fix(webui): make the keyless file-backed monitor report live progress#31
Merged
ignorejjj merged 4 commits intoJun 25, 2026
Merged
Conversation
The keyless WebUI (open_dashboard / `arbor web`) renders a session from disk with no live RunState or EventBus. build_session_snapshot only filled the tree, counters and scores, so the page showed a frozen run: runtime stuck at 0s, token/cache counters at zero, a dead pipeline, an empty activity feed, and a blank improvement chart. Node modals also rendered a black (invisible) title and showed the full multi-line hypothesis instead of a headline, and sessions created from a linked git worktree disappeared when the dashboard was opened from the main checkout. - Add a timing sidecar (mcp/session_timing.py -> .coordinator/activity.json): the Node model intentionally stores no timestamps, so session_ops now records a run clock, per-node started/finished, and a capped event log on add/update/ prune/worktree_create/merge. The tree JSON stays byte-compatible. - session_source: derive elapsed_seconds, per-node runtime_seconds/ finished_elapsed, the pipeline phase, running-node "agents", and best_score_history (fixes the empty/flat improvement chart) from the sidecar. - Hide the Tokens and Cache cards in keyless mode (flagged via snapshot.keyless) rather than show misleading zeros - those counters belong to the host harness, not Arbor - and reflow the stat grid. - Anchor .arbor/sessions at the main working tree when driven from a linked git worktree (session_ops._stable_arbor_base, mirrored in export.resolve_session_dir) so session state survives branch/worktree switches. - Fix the black modal title (set color on the #overlay host, which sits outside the themed shell wrapper) and show a one-line headline (oneLine) for node titles, keeping the full hypothesis in the modal Details. Add tests for the sidecar-backed snapshot, the activity recording, and the stable-base behaviour. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Inside a git submodule, `git rev-parse --git-common-dir` points at the parent repo's `.git/modules/<name>`, so anchoring `.arbor` at its parent would land in `.git/modules` rather than a working tree. Require the resolved main root to actually hold a `.git` entry before redirecting there — normal linked worktrees still redirect (their root has a `.git` dir), submodules no longer misfire. Adds a linked-worktree redirect test (env-guarded like the other worktree tests).
Use a per-writer temp filename (pid + thread id) so two concurrent `_save` calls can't clobber a shared `.tmp` mid-write — the rename onto the final path stays atomic. Clean up the temp file on failure, and document that the read-modify-write in record_event still assumes a single writer per session.
- flag the live snapshot `keyless: False` explicitly, so its shape matches empty_state_dict() and the keyless path (the browser hides token/cache cards only when keyless is true) - debug-log the stable-base session-lookup fallback in export instead of swallowing the exception silently - tiebreak the improvement-chart ordering on score, so legacy sessions with no sidecar timing (all keyed at +inf) still draw in a deterministic order
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.
Summary
Fixes the keyless, file-backed WebUI monitor (
open_dashboardMCP tool /arbor web) that a host coding agent drives via thearbor mcptools. That monitor renders a session from disk with no liveRunStateorEventBus, butbuild_session_snapshotonly populated the tree, counters and scores — so the page presented a frozen run.Symptoms addressed:
0sand a blank improvement chart — no clock or score history was ever derived..arbor/).Changes
Nodemodel intentionally stores no timestamps (and must stay byte-compatible), so a newmcp/session_timing.pymaintains.coordinator/activity.json: a run clock, per-nodestarted/finished, and a capped event log.session_opsrecords an event on add / update / prune /worktree_create/ merge.session_sourcenow deriveselapsed_seconds, per-noderuntime_seconds/finished_elapsed, the pipeline phase, running-node "agents", andbest_score_history(which fixes the empty/flat improvement chart) from the sidecar.keyless) instead of showing misleading zeros, and the stat grid reflows..arbor/sessionsis anchored at the main working tree when driven from a linked worktree (session_ops._stable_arbor_base, mirrored inexport.resolve_session_dir); normal checkouts and non-git directories are unchanged.#overlayliving outside the themed shell wrapper, so the bare<h2>inherited the browser-default color; color is now set on the overlay. Node titles render a one-line headline (oneLine), with the full hypothesis preserved in the modal's Details.Testing
345 passed, 2 skipped. The remaining failures (test_exportpath separators,test_worktree/test_zoogit-worktree & subprocess) reproduce on an untouched checkout and are pre-existing Windows-environment issues, not regressions.🤖 Generated with Claude Code