feat(web): Serve realtime runs canvas in the browser - #63
Merged
Conversation
Add a localhost-only codedeck web command that serves a self-contained canvas page: session nodes grouped by run with the orchestrator at the center, live status, and per-session event streams translated into motion (particles, pulses, activity feed). Includes port parsing, SSE framing, and route helpers with unit tests.
A non-loopback dummy base trips the S5332 cleartext-protocol rule even though only the path and query are read. 127.0.0.1 keeps the parse identical and stays inside the rule's loopback exception.
The motion button toggled the class on the inner SVG instead of the button, so its pressed state never followed the click. Recenter forced zoom 1, which lands in the void between runs on a spread fleet; it now refits the most active run like the initial framing. Also adds a hide toggle for finished sessions with a hidden count in the summary.
4ndreello
marked this pull request as ready for review
September 8, 2026 01:08
…yout Clicking a node opens a drawer with model, repo, pid, event counts and a humanized history tail fetched from session.get. Hide/motion state lives in the query string so F5 keeps the filters. Offscreen active sessions get clickable edge pills that jump the camera to them. Ring spacing tightened (verified numerically) and tool activity shows a snippet of the real input instead of a generic label.
Draw a subtle dashed container with the repo name around each run so the project is visible without opening the detail drawer. Recompute the layout over the visible set when hiding completed, center cards on their true outer width, fit small sets entirely, pin dragged nodes, and show model effort plus a dead label in the detail view.
Share the ps liveness rule with the session.list and session.get read boundary so the web canvas and the terminal agree: an active session whose recorded process is gone serves as dead instead of stale working. The stored row is never mutated, only the served view.
|
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.



Serve the runs canvas over HTTP with live daemon data instead of mock files.
codedeck web starts a localhost-only bridge (default :3100, --open launches the browser) that serves a single self-contained page: sessions grouped by runId with the orchestrator at the center, status in plain language, and one event stream per active session translated into motion on the canvas (text deltas travel as particles, tool starts pulse, permission requests raise the amber alert).
The page makes zero external requests and the server binds 127.0.0.1 with no host flag on purpose; realtime send stays out of scope for V2 since session.send only admits idle sessions and open sessions refuse it.
Careful-review notes: the canvas page is a large template string in src/web/canvas-page.ts promoted byte-identical from the validated spike (asserted in tests: no backticks, no interpolation, no external URLs); the stream route pre-flights session.get before the 200 so a dead daemon yields JSON 404 instead of a hanging EventSource.