Dispatch a command into the srv reducer and return the emitted
events. Locks the reducer mutex briefly; the lock is released
before any I/O (caller is responsible for publishing the events
to the broadcast bus).
Per-agent_id debounce generation for zoom mirroring. Each term:zoom
change bumps the agentโs generation; the spawned trailing-write task only
commits if its captured generation is still current 300ms later, so a
Ctrl+Wheel burst collapses into a single durable write (+ one global
def-registry re-mirror). See SPEC_AGENT_ZOOM_PERSISTENCE ยง4.3.
Read-only snapshot of the window โ workspace โ tab โ pane tree, for agent
introspection (GET /api/v1/layout). Pure wstore reads โ no reducer, so
itโs hermetic and safe. Lookups use linear scans (a handful of objects).
Compensation helper: dispatch a command into the reducer and
apply its emitted events to wstore best-effort. Used when an
earlier sync apply partially wrote SQLite and we need to undo
the leaked rows. SQLite errors during compensation are logged
but ignored โ the caller is already returning an error to the
client; throwing on the cleanup just hides the original cause.
(codex P1 + reagent P2 #616 โ partial-write cleanup.)
Phase E.4 (Option A) โ reverse lookup: given a LayoutState.oid,
find the Tab.oid that owns it (i.e., the tab whose layoutstate
field matches). Returns None when the layout is unowned (legacy
or partially-migrated row) or the wstore read fails โ caller treats
either as โskip the reducer dispatch and fall through to the wcore
write.โ Linear scan over all tabs; acceptable here because the
layout-update path is low-frequency relative to drag-resize and
the reducer mutex itself is held for sub-millisecond intervals.
Phase E.5.5 โ append a layout-delete action to the source tabโs
LayoutState.pendingbackendactions so the source windowโs
frontend tears the moved block out of its layout tree on next
poll. Mirrors the action-queueing portion of
wcore::tear_off_block. Layout migration is E.4.
Floating-pane re-dock โ enqueue an โinsertโ action on the TARGET
tabโs LayoutState.pendingbackendactions so the target windowโs
frontend adds a new leaf for the redocked block through its
LayoutTreeActionType.InsertNode reducer pathway.
Dispatch a service call and broadcast any resulting WaveObjUpdates to the
event bus โ the shared core of handle_service. Factored out so the typed
first-class agent-API verbs (e.g. /api/v1/window/name) get byte-identical
persistence + broadcast to a raw /agentmux/service call without
re-implementing it. See SPEC_AGENT_API_FIRST_CLASS_SURFACE_2026_06_17.md.
Debounced trailing mirror of an agent blockโs term:zoom into the per-agent
ui:zoom content blob. zoom = Some(z) upserts; zoom = None (term:zoom
reset to null / 1.0) deletes the row so a default agent persists nothing.
Phase E.5.5 โ set up the layout tree for a tab that just received
its first block via the TearOffBlock saga. Called from the
TearOffBlock RPC handler after the sagaโs reducer-state portion
(CreateTab + MoveBlock) completes. Mirrors the layout-rootnode
Update a wave object by replacing it wholesale in the store.
The incoming value must have otype and oid fields.
Matches Goโs ObjectService.UpdateObject behavior.
Returns (otype, oid, updated_value_with_new_version) on success.
Existence check used by DeleteWorkspace to decide whether to
run the wcore delete path. Propagates StoreError so the caller
can surface real I/O / corruption failures instead of
misclassifying them as โnot foundโ (codex P2 #615 carryover โ
the prior bool return collapsed Err(_) into false, which
led to silent successes when SQLite was unhealthy: reducer would
delete its own copy and report success while the disk row was
never touched).