Skip to content

feat(ui): live-capture streaming model + update_fx adoption (#59 pt1)#67

Merged
sepehr-safari merged 1 commit into
mainfrom
feat/live-capture-view
Jul 12, 2026
Merged

feat(ui): live-capture streaming model + update_fx adoption (#59 pt1)#67
sepehr-safari merged 1 commit into
mainfrom
feat/live-capture-view

Conversation

@sepehr-safari

Copy link
Copy Markdown
Member

Part 1 of #59 (live-capture view): the effects-channel adoption and the streaming state machine from ADR-0009. Interactive view controls + a config form are part 2.

What's here

  • update_fx adoption (main.zig). The app switches from the pure update to the effects-capable update_fx: it runs workspace.update for the model change, then issues fx.spawn on start_capture — self-spawning studio capture … --ndjson, whose stdout NDJSON lines stream back as capture_line Msgs — and fx.cancel on stop_capture. main captures argv[0] as the self-exe for the spawn argv.
  • LiveCapture state machine (workspace.zig). New Msgs (start_capture / stop_capture / capture_line: EffectLine / capture_exit: EffectExit); the captured NDJSON stream accumulates (bounded to max_live_bytes — oldest whole lines drop), and the live trace is re-derived from it via loadTrace — reusing the whole engine, so it correlates + detects exactly like an opened trace and the inspector renders it viewport-bounded. Kept off the traces array so tab compaction never disturbs it.

Why re-derive (not incremental append)

It reuses the entire parse → correlate → detect → render pipeline for free (the live trace is a LoadedTrace), so a live session behaves identically to an opened one. Re-parse is O(n) per line — fine at human event rates within the cap; an incremental-append optimization is a later refinement.

Tests (154/154, +2)

Streamed lines append into a growing, correlated trace; status transitions across start / stop / exit reasons (.cancelled/.exited → stopped, .rejected/.spawn_failed/.signaled → failed); lines gate when not capturing; a fresh start bumps the cancel key and clears the recording. All leak-tested (std.testing.allocator).

Verification

  • native test -Dplatform=null154/154.
  • native build (ReleaseFast) → clean — the CLI dispatch already pulled run() into the app build, and now updateFx/fx.spawn/Effects.lineMsg compile there too.
  • zig fmt --check clean; studio ci still exits 0 (no regression from the update_fx switch).

Part 2 (next)

The interactive view: a start/stop control + status, a config input (listen / upstream), and presenting the live trace (the model + render path are ready; this wires the buttons and the config). Then #60 (notifications).

Part 1 of the live-capture view (#59): the effects-channel adoption and the
streaming state machine (ADR-0009). Interactive view controls + a config form
are part 2.

- The app adopts update_fx (main.zig): the effects-capable update runs the pure
  workspace.update, then issues fx.spawn on start_capture (self-spawning
  `studio capture … --ndjson`, whose stdout NDJSON lines stream back as
  capture_line Msgs) and fx.cancel on stop_capture. main captures argv[0] as the
  self-exe for the spawn argv.
- workspace gains a LiveCapture state machine: start/stop/line/exit Msgs; the
  captured NDJSON stream accumulates (bounded to max_live_bytes — oldest whole
  lines drop) and the live trace is re-derived from it via loadTrace, reusing the
  whole engine, so it correlates + detects exactly like an opened trace and the
  inspector renders it viewport-bounded. Kept off the traces array so tab
  compaction never disturbs it.
- Headless tests: streamed lines append into a growing, correlated trace; status
  transitions (start/stop/exit reasons); lines gate when not capturing; a fresh
  start bumps the cancel key and clears the recording.

Verified: native test 154/154, native build (ReleaseFast) compiles the fx.spawn
app path, zig fmt clean.
@sepehr-safari sepehr-safari merged commit 354dca8 into main Jul 12, 2026
3 checks passed
@sepehr-safari sepehr-safari deleted the feat/live-capture-view branch July 12, 2026 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant