Skip to content

feat(ui): announce blocking actions in the header and add a timing page with Buckaroo's spans - #318

Open
paddymul wants to merge 5 commits into
mainfrom
feat/blocking-action-strip
Open

paddymul wants to merge 5 commits into
mainfrom
feat/blocking-action-strip

Conversation

@paddymul

@paddymul paddymul commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Problem

When a page waits, nothing says what it is waiting on. On 2026-10-08 loading cars took 3.27 s: the companion's POST to Buckaroo sat for 3.2 s behind a 4.5 s summary-stats run for camera_violations (Buckaroo runs everything on one IOLoop thread), then Buckaroo's own handler took 39 ms. The activity log has the 3.27 s, and telemetry.jsonl has both the stats run and the 39 ms, but nothing puts them side by side.

Fix

  • tallyman_core/activity.py: a process-wide tracker. track(name, detail) tells listeners the action is about to start (action_start) and again when it ends (action_end, with the duration); an exception is recorded as the action's error and re-raised. The companion forwards both over the existing SSE channel (from worker threads, through the loop).
  • Announced: prepare entry and the buckaroo load_expr POST in BuckarooManager.load_session, and the diff data, promote diff, save code, reset, staleness and recalc routes.
  • Header: now: <action> <detail> · <elapsed> while one runs (the longest, +N more for the rest), last: <action> <detail> · <time> after, linking to the timing page. SSE action events do not bump version, so they do not refetch the catalog.
  • GET /{project}/api/timing?window_s=: the companion's actions and the spans Buckaroo posted back to telemetry.jsonl, on one clock (epoch ms).
  • Timing page: both on a shared axis, split into bursts (rows within 2 s of the latest end) so each burst is readable. A load_expr POST says how long after it started Buckaroo began handling it. That gap is queueing plus the request's transfer and parsing; the page does not separate them.

Not in this PR: Buckaroo announcing the start of its own work (it posts a span only when it ends, so the header cannot say a stats run is about to start; that needs a change in the buckaroo repo), and actions that run in the MCP process. The log is in memory, so a restart empties it.

Checked in a browser against a running companion: the pill showed now: buckaroo load_expr 71d4f4fc7932 · 3 ms and then last: … · 543 ms, and the timing page showed the companion's POST, Buckaroo's load_expr, ws_first_payload and stats.complete for it.

🤖 Generated with Claude Code

paddymul and others added 5 commits October 8, 2026 11:06
…iming page

The companion announces each blocking action before it runs and again when it ends, the header shows the running action and the last one, and GET /api/timing returns the companion's actions beside the spans Buckaroo posted back.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…eue and for trace labels

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…a timing page

activity.ts holds the pure state: a reducer for action_start and action_end, the now and last labels, the wait a load_expr POST spent in Buckaroo's queue, and the timeline layout. SSEContext keeps it without bumping version; ActivityStrip shows it in the header; TimingPage lays the companion's actions and Buckaroo's spans on one axis.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…burst of activity

The rows lacked the flex layout the shared waterfall classes give, and one axis for the whole window made a half-second action a sliver next to another half a minute later. Rows within 2 s of the latest end share an axis. The note on a slow load_expr now says when Buckaroo began handling it, since the gap also holds the request's transfer and parsing, not only queueing.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…em over SSE, and serve /api/timing

tallyman_core/activity.py tracks running and finished actions and tells listeners at each start and end. load_session announces preparing the entry and the load_expr POST; the diff, promote, save-code, reset, staleness and recalc routes announce themselves. The companion forwards the events over SSE and GET /{project}/api/timing returns the actions beside the spans Buckaroo posted back.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
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