Skip to main content

DaemonEvent

Enum DaemonEvent 

Source
pub enum DaemonEvent {
    PalaceCreated {
        id: String,
        name: String,
        source: ActivitySource,
    },
    DrawerAdded {
        palace_id: String,
        palace_name: String,
        drawer_count: usize,
        timestamp: DateTime<Utc>,
        content_preview: String,
        source: ActivitySource,
    },
    DrawerDeleted {
        palace_id: String,
        drawer_count: usize,
        source: ActivitySource,
    },
    DreamCompleted {
        palace_id: Option<String>,
        merged: usize,
        pruned: usize,
        compacted: usize,
        closets_updated: usize,
        duration_ms: u64,
        source: ActivitySource,
    },
    StatusChanged {
        total_drawers: usize,
        total_vectors: usize,
        total_kg_triples: usize,
    },
    HookFired {
        palace_id: Option<String>,
        palace_name: Option<String>,
        hook_type: HookType,
        injection_kind: InjectionKind,
        injection_length: u64,
        trigger_prompt_excerpt: String,
        timestamp: DateTime<Utc>,
        duration_ms: u64,
        source: ActivitySource,
    },
}
Expand description

Live daemon events broadcast to connected SSE subscribers.

Why: The dashboard needs push-driven updates so palace creation, drawer add/delete, dream cycles, and aggregate status changes are visible without polling. A single broadcast channel fans out to every connected browser. What: Tagged enum serialized as {"type": "...", ...fields} over SSE. Test: web::tests::sse_stream_emits_events subscribes, triggers a mutation, and asserts the frame arrives.

Variants§

§

PalaceCreated

Fields

§name: String
§source: ActivitySource

Originating subsystem (HTTP, MCP, Hook). Why (issue #96): the UI badges each row with its source so operators can tell at a glance whether a write came from the dashboard form, an MCP tool call, or a hook-driven path. The wire-format key is source (lower-case strings via serde rename_all on ActivitySource).

§

DrawerAdded

Fields

§palace_id: String
§palace_name: String

Friendly palace name (Palace.name) at write time. Why: lets SSE consumers (the dashboard activity feed) render the human-readable label without a separate id→name lookup. Empty string if the emitter could not resolve the name.

§drawer_count: usize
§timestamp: DateTime<Utc>

Wall-clock timestamp when the drawer was added. Why: SSE receivers want to render “just now / 2m ago” relative to the daemon’s clock, not the time the SSE frame happens to arrive.

§content_preview: String

Short preview of the drawer’s content (whitespace-collapsed, truncated to ~80 chars with an ellipsis when cut). Why: the TUI activity feed and dashboard ticker want to show what was stored, not just the running drawer count. Empty when the emitter could not resolve the content (legacy clients tolerate the missing field via #[serde(default)]).

§source: ActivitySource

Originating subsystem (issue #96).

§

DrawerDeleted

Fields

§palace_id: String
§drawer_count: usize
§source: ActivitySource

Originating subsystem (issue #96).

§

DreamCompleted

Fields

§palace_id: Option<String>
§merged: usize
§pruned: usize
§compacted: usize
§closets_updated: usize
§duration_ms: u64
§source: ActivitySource

Originating subsystem (issue #96).

§

StatusChanged

Fields

§total_drawers: usize
§total_vectors: usize
§total_kg_triples: usize
§

HookFired

A Claude Code hook completed and rendered (or attempted to render) an injection block.

Why: pre-#XXX the activity feed only fired on drawer / palace / dream writes, which meant a normal Claude Code session — whose only daemon traffic is hook invocations — left the feed empty. Surfacing every hook firing answers the user complaint “no activity in the TUI” and gives operators a way to see how often each project palace is actually picking up prompt-context / inbox-check work. What: carries the resolved palace (or None if cwd resolution failed), the HookType label, the InjectionKind label, the rendered injection byte length, a short excerpt of the triggering prompt (capped at ~80 chars; the full content stays in the JSONL prompt log only), the timestamp, the hook’s wall-clock duration, and the ActivitySource tag (always Hook for this variant). Backwards-compatible: SSE clients that do not recognise the hook_fired type tag can safely ignore the frame.

Fields

§palace_id: Option<String>

Resolved palace id (slug) — None if cwd resolution failed.

§palace_name: Option<String>

Friendly palace name at hook time — None if the registry could not be consulted (HTTP path uses palace_id here when no separate name is known).

§hook_type: HookType
§injection_kind: InjectionKind
§injection_length: u64

Rendered injection size in bytes (0 when no injection was emitted, e.g. SessionStart with an empty inbox).

§trigger_prompt_excerpt: String

Short excerpt of the triggering prompt for the activity feed display. Capped at ~80 chars with a trailing when cut. Why: the activity feed renders this directly; full prompt content (which may be sensitive) stays in the JSONL log.

§timestamp: DateTime<Utc>
§duration_ms: u64

Hook wall-clock duration in milliseconds.

§source: ActivitySource

Always ActivitySource::Hook for this variant; encoded explicitly so the same dispatch path (emit) can persist + broadcast it.

Implementations§

Source§

impl DaemonEvent

Source

pub fn type_str(&self) -> &'static str

Short discriminant label matching the SSE type field.

Why: the persisted activity log stores event_type as a string so the UI can render the row without re-parsing the payload. Sharing the same labels the SSE serializer uses keeps the wire and the stored history consistent. What: returns one of palace_created, drawer_added, drawer_deleted, dream_completed, status_changed. Test: daemon_event_type_str_matches_sse_tag in the lib tests.

Source

pub fn palace_id(&self) -> Option<&str>

palace_id if the event is scoped to a single palace.

Why: the activity log indexes entries by palace id so the UI can filter by palace; daemon-wide events (status_changed, dream-across-all-palaces) return None. What: returns a borrowed string when the variant carries a palace id, otherwise None. Test: daemon_event_palace_id_extraction.

Source

pub fn source(&self) -> Option<ActivitySource>

Originating subsystem if the event carries one.

Why: only mutation events carry a source; the aggregate StatusChanged is recomputed by the daemon and has no caller, so it returns None. What: returns the variant’s source field where present. Test: daemon_event_source_extraction.

Trait Implementations§

Source§

impl Clone for DaemonEvent

Source§

fn clone(&self) -> DaemonEvent

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for DaemonEvent

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Serialize for DaemonEvent

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more