feat(ui): live-capture streaming model + update_fx adoption (#59 pt1)#67
Merged
Conversation
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.
This was referenced Jul 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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_fxadoption (main.zig). The app switches from the pureupdateto the effects-capableupdate_fx: it runsworkspace.updatefor the model change, then issuesfx.spawnonstart_capture— self-spawningstudio capture … --ndjson, whose stdout NDJSON lines stream back ascapture_lineMsgs — andfx.cancelonstop_capture.maincapturesargv[0]as the self-exe for the spawn argv.LiveCapturestate machine (workspace.zig). New Msgs (start_capture/stop_capture/capture_line: EffectLine/capture_exit: EffectExit); the captured NDJSON stream accumulates (bounded tomax_live_bytes— oldest whole lines drop), and the live trace is re-derived from it vialoadTrace— reusing the whole engine, so it correlates + detects exactly like an opened trace and the inspector renders it viewport-bounded. Kept off thetracesarray 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=null→ 154/154.native build(ReleaseFast) → clean — the CLI dispatch already pulledrun()into the app build, and nowupdateFx/fx.spawn/Effects.lineMsgcompile there too.zig fmt --checkclean;studio cistill exits 0 (no regression from theupdate_fxswitch).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).