feat(desktop): rebuild agent activity feed around a classifier registry and twelve render classes#1381
Conversation
wesbillman
left a comment
There was a problem hiding this comment.
Poit — I found one merge-blocking issue before this should leave draft.
CHANGE: remove or hard-gate the activity render-class debug fixture before merge. The PR statically imports debugAgentActivityFixture / debugAgentActivityRawFixture into AgentSessionThreadPanel, exposes Debug: show all render classes in the live activity settings menu, adds the debug specs to the smoke project, and even adds a file-size override that says “Remove this with debugAgentActivityFixture.ts before the PR merges.” As written, a production user can replace a real agent activity panel with synthetic fixture data, and the main app bundle ships the 1k-line fixture. If the fixture is only for design review, it should be removed before undrafting; if it must stay available, it needs to be dev/test gated so it cannot appear in production or affect the production bundle/CI smoke set.
Everything else I reviewed looked directionally coherent: reducer upserts, permission/raw/status surfacing, channel scoping, sent-message linking, same-kind grouping, and the presenter split all matched the stated model.
Validation I ran locally:
PATH="$PWD/bin:$PATH" just desktop-check✅ (Biome info-only template-literal suggestions in the temporary debug specs)pnpm --dir desktop exec tsc --noEmit --pretty false✅ after refreshing pnpm install in the new worktreePATH="$PWD/bin:$PATH" just desktop-test✅ (1350 tests)PATH="$PWD/bin:$PATH" just desktop-build✅ (existing chunk/dynamic-import warnings)- focused Playwright debug specs:
pnpm --dir desktop exec playwright test tests/e2e/activity-debug-fixture.spec.ts tests/e2e/activity-debug-expanded.spec.ts --project=smoke✅ (4 passed) git diff --check origin/main...HEAD✅
69614f1 to
05c010c
Compare
|
Poit — copying my review feedback here so it is visible as a PR comment too. CHANGE: remove or hard-gate the activity render-class debug fixture before merge. The PR currently:
As written, a production user can swap a real agent activity panel to synthetic fixture data, and the production bundle ships the 1k-line fixture. If it is only for design review, it should be removed before undrafting; if it must stay available, it needs a dev/test gate so it cannot appear in production or affect the production bundle/CI smoke set. Everything else I checked looked coherent: reducer upserts, permission/raw/status surfacing, channel scoping, sent-message linking, same-kind grouping, and the presenter split. Validation I ran locally:
|
…ship model Replay of PR #1061 (tho/activity-ui-polish) onto fresh main: lands the 20 UI-polish commits as one net diff, reconciled with #1229's merged declared-ownership model (viewerIsOwner = isCurrentUserOwner || isOwner) and #1089's content-visibility-auto virtualization. Notable reconciles: - markdown.tsx: ported the compact/tight variant system into main's newer lightbox/spoiler markdown component (rather than overwriting it), layering variant density/leading overrides after the base owl-spacing so tailwind-merge wins. Dropped the branch's hardcoded text-[15px] in favor of main's rem-token text-sm base (post-#1052 zoom-safe scale). - agentSessionTranscript.ts: pass TranscriptItemContext (not channelId). - managed_agents: thread avatar_url through ManagedAgentSummary so the transcript renders the assistant-bubble avatar from the pinned record snapshot; bumped runtime.rs size override 2001 -> 2002 for the +1 line. Observer-seed screenshots intentionally excluded (separate follow-up). Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Add reusable debug fixture helpers for MCP-style tool items, shell command outputs, file edits, and todo updates.
- Expand the activity fixture with repeated file edits, command bursts, todo updates, a push report, and final message-send activity to better exercise collapsed and inline transcript states.
- Align fixture arguments and results with buzz-dev-mcp and ACP wire shapes, including qualified tool names, shell JSON result payloads, str_replace unified diffs, todo {text, done} state, _Stop hook output, and session/update raw payload structure.
Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Move transcript item presentation for the 12 activity render classes into sibling components under activityRenderClasses. - Add a typed render-class presenter registry so every AgentActivityRenderClass maps to a presentational component. - Keep AgentSessionTranscriptList focused on transcript display blocks, turn grouping, setup rows, and prompt context rendering. - Share timestamp, identity props, lifecycle, and tool row delegates across the extracted presenters without changing transcript behavior. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Parse file edit tool results from unified diff output, Shiki diff markers, and shell JSON stdout/stderr payloads. - Add compact file edit summaries that show a muted Edited verb, filename, and green/red +N/-N counts. - Keep expanded tool details unchanged so raw Parameters and Result output remain available. - Cover diff stat parsing for direct str_replace output, Shiki markers, and shell-wrapped JSON output. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Add path-specific file edit scenarios so the debug fixture exercises different old/new snippets and unified diff shapes across transcript files. - Thread variable tool durations through generated file-edit and shell rows so compact activity summaries show realistic elapsed times instead of repeated defaults. - Preserve the existing MCP-style fixture payload structure while making command bursts, push rows, and generated edits visually distinct for review. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Extract reusable file edit diff parsing for compact summaries and expanded tool details. - Render successful parsed file edit results as a focused diff view with the file path, code/context lines, and tinted add/remove rows. - Hide noisy Parameters for parsed file edits while preserving raw Result fallback for errors and unparsed tool output. - Trim only trailing blank diff rows so terminal newlines do not add empty padding while intentional internal blank lines remain visible. - Extend tool summary tests to cover parsed diff lines, Shiki diff markers, shell JSON stdout, and trailing blank trimming. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Remove the shared left padding from expanded tool accordion details so content aligns with the trigger. - Move the file path into the file edit diff card footer and let the code region flex/scroll within the max-height container. - Render the footer path in normal UI text with ellipsis and a full-path title tooltip instead of monospace code styling. - Use regular weight for the file edit filename in the accordion trigger while preserving the muted Edited verb and diff stat emphasis. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Group consecutive same-kind tool runs in the transcript and lower the file-edit grouping threshold to two edits. - Render grouped tool runs by expanding into the full existing tool-call accordion rows instead of simple preview text. - Restyle grouped summaries to match normal tool-call rows with split muted verb/object labels and no surrounding box treatment. - Remove row-level padding/margins from grouped tool call rendering so vertical rhythm is controlled by flex gaps. - Add coverage for consecutive file edit grouping and preserve existing read/command grouping behavior. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Capture the principles and tenets of the activity feed — the reader-frame (comprehension/confidence/control), the Verb-Object-Outcome lens, the twelve render classes, and the cross-cutting design principles — alongside the other VISION_*.md docs. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Add ActivityRow, ActivityRowLabel, and ActivityRowContent as named primitives for native details/summary activity rows. - Migrate grouped tool summaries and compact tool labels to shared verb/object/outcome styling. - Align Thinking, Plan, Raw rail, and non-error lifecycle rows with the same quiet ActivityRow disclosure treatment. - Preserve specialized expanded states such as file-edit diffs, raw payload sections, and destructive error rows. - Keep label splitting as a graceful fallback for curated activity labels while unknown labels render honestly as-is. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Add structured action metadata to agent activity descriptors so rows can render verb/object semantics without parsing display labels. - Populate actions for developer harness tools, generic fallback tools, native Buzz MCP tools, and Buzz CLI commands. - Make compact tool rows prefer descriptor action metadata before falling back to curated label splitting. - Normalize Buzz operation actions across MCP-style names and CLI-style group/verb names so transport-specific labels converge. - Cover structured action output for shell, read-file, Buzz CLI, and native Buzz MCP tool summaries. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Add isolated one-file edit samples for the activity vision doc and ActivityRow label handling so the debug fixture exercises standalone file-edit rows outside the larger edit burst. - Keep the fixture narrative on the common agent cadence of assistant text, shell stdout, user feedback, and then another tool pass. - Preserve deterministic placeholder agent/user avatars and neutral fixture-agent copy in the debug transcript data while keeping the fixture under the desktop file-size gate. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Increase the assistant activity author label from text-xs to text-sm so it matches compact tool-call labels. - Keep transcript timestamps on the smaller text-xs scale to preserve visual hierarchy. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Merge deterministic debug profile entries into the activity transcript only when the render-class fixture is enabled. - Override the debug agent name and avatar while the fixture is active so assistant messages use the neutral placeholder identity. - Keep the live agent identity and profile lookup unchanged outside the temporary debug render-class mode. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Move transcript item spacing onto the transcript log and turn group containers with flex gaps. - Remove row-level y-margins and helper logic from transcript item wrappers. - Drop vertical padding from assistant/user message wrappers and compact activity summaries so container gaps control rhythm. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Add Tailwind min-h-6 to simple ActivityRow containers so collapsed activity rows have a consistent 24px floor. - Apply the same min-h-6 to expandable ActivityRow summaries to align tool and grouped activity rows. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Update compact tool summaries so expanded accordions promote from muted text to foreground text - Align shared ActivityRow labels, objects, and chevrons with the same muted passive and foreground active state treatment - Normalize nested prompt context and raw rail accordions to use matching passive/active colors - Standardize transcript accordion chevrons on the smaller h-3.5 w-3.5 size for visual consistency Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Add a shared FileEditDiffView helper so individual tool rows and transcript grouping logic use the same edit-diff rendering and line-diff detection. - Calculate aggregate additions and deletions for grouped file-edit summaries while preserving the independent expandable edit rows inside the expanded group. - Remove ActivityRow default-open support and the plan-row opt-in so activity rows render closed by default. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Add UserMessageBubble to centralize user-authored transcript alignment, avatar/profile lookup, markdown rendering, and bubble styling. - Reuse the shared bubble for the turn prompt path while keeping prompt context and setup controls owned by AgentSessionTranscriptList. - Reuse the shared bubble for regular user message chunks and render their timestamp through the same footer slot for consistent layout. - Preserve assistant message rendering while removing duplicated user-bubble logic from MessageActivity. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Switch assistant transcript markdown from the compact variant to the tight variant so rendered paragraphs use leading-5 instead of leading-6. - Remove the wrapper-level leading override because Markdown owns the effective paragraph line-height. - Keep the change scoped to assistant transcript output without changing user bubbles or tool detail blocks. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Add sent-message link extraction for completed activity tool rows using channel identity plus returned message event ids. - Route clickable sent-message footer timestamps through the existing in-app channel navigation instead of adding a separate action. - Replace custom transcript timestamp tooltips with native title attributes and update debug fixture message ids to exercise the openable state. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Remove prompt setup hover tooltips from the activity footer so the setup text only appears inside the context modal. - Collapse the footer context affordance to the checks icon while preserving the accessible toggle label. - Add the checks icon to the context modal subtitle row to keep the setup signal visible with the turn summary. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Move sent-message activity deep links from the runtime duration label onto the visible transcript timestamp. - Extend transcript message items with optional Buzz event ids so user prompt bubbles can navigate back to their source message when the observer payload provides one. - Parse Event ID fields from framed Buzz event prompt sections and retain a single triggering event id fallback for older observer frames. - Keep linked timestamps visually aligned with the previous muted timestamp styling while preserving keyboard focus affordances. - Simplify visible transcript timestamps to short 12-hour labels without seconds, with full date/time retained in the tooltip. - Update the debug activity fixtures to include a real 64-hex prompt event id and add focused tests for parsing, linking, and timestamp formatting. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Add native title support to ActivityRow so non-message transcript rows can expose full timestamp details without rendering visible time text. - Remove visible timestamps from lifecycle/status/error, plan, thought, raw metadata, setup-only, grouped summary, and non-message tool rows. - Keep visible timestamps on actual message surfaces, including user/assistant transcript messages and sent-message activity bubbles. - Centralize full timestamp tooltip formatting in agentSessionUtils and reuse it from TranscriptTimestamp and row title call sites. - Preserve runtime duration labels on tool rows while moving wall-clock time into the row title. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Update AgentSessionToolItem so sent message activity renders as a left-side message bubble with the agent avatar, mirroring user prompt bubbles instead of using the generic tool accordion. - Replace inline sent-message expansion with a checkmark-triggered context dialog that uses rounded collapsible sections for message content, parameters, and results. - Keep sent-message timestamps linked to the underlying message while moving duration into the dialog subtitle and removing redundant footer text. - Pass agent identity through ToolActivity so message tool rows can resolve the correct avatar and display name. - Update the debug activity fixture to use realistic 64-character event IDs for sent-message link coverage. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Replace the monolithic AgentSessionToolItem implementation with a barrel export and focused render modules for the main tool item, compact rows, sent-message context, shell output, todo summaries, image previews, detail blocks, and message-link helpers. - Render shell command activity details as a muted terminal-style block below the existing accordion label, with inline accent-colored terminal icon, muted command text, and foreground stdout output. - Parse shell tool result envelopes so stdout displays without exposing the raw JSON result payload, and add focused parser coverage for envelope and raw text cases. - Keep plan update progress summaries, such as 5/5 complete, in foreground while preserving muted surrounding label text. - Render todo tool summaries as static checkbox snapshots in a dedicated component, keeping the desktop file-size guard green. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Render activity row diff stats in a single inline-flex group so additions and deletions share the same baseline, line height, and font size. - Switch compact diff stat colors from hardcoded green/red Tailwind utilities to theme-backed status tokens. - Preserve the existing compact +N/-N summary behavior while improving light and dark theme consistency. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Update the agent lifecycle error row to render the alert icon, title, separator, and detail text in a single inline flow. - Remove the flex-row layout so long turn error messages can wrap naturally within the error card instead of forcing the detail text across one row. - Preserve the existing destructive tone, border, background, and timestamp tooltip behavior for lifecycle errors. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Replace the suppressed tool passthrough with a dedicated ActivityRow presenter - Preserve action labels, timestamps, and duration text without mounting generic tool details - Avoid extra expanded detail padding for stop-hook items like Checked todos Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Temporary Playwright specs that mount the activity panel via the mock bridge, enable the debug render-class fixture, and capture the full taxonomy (feed walk, cog menu, raw rail, expanded states) into __shots__. Travels with the temporary debug harness and is stripped alongside it. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Permission lifecycle items rendered through the generic 'Status' branch of LifecycleActivity, so a 'Permission requested' interrupt looked identical to ordinary status rows. Add a dedicated permission branch (amber pill + ShieldCheck icon) mirroring the existing error-pill treatment, and a distinct transcript-permission-item testid so it can be targeted in tests and screenshots. Keeps the shared row vocabulary; no live-renderer or grouping changes. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
62606eb to
618f550
Compare
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
| # Vision: The Agent Activity Feed | ||
|
|
||
| ## The Problem | ||
|
|
||
| When you delegate work to an agent, you are trusting a process you cannot see. The activity feed is the window into that process — but a window is only useful if you can read it at a glance. A raw input/output dump is not a window; it is a transcript you have to decode. It forces you to *parse* before you can *judge*. |
There was a problem hiding this comment.
Do you want this file in here at the project root?
There was a problem hiding this comment.
I think so! followed convention of other VISION_*.md docs
Three regressions introduced by #1381's activity-feed rebuild: 1. Per-turn prompt context sections are now visible inline in the feed body. Previously they were hidden behind a modal accessible only via a small CheckCheck toggle inside the user-message bubble footer. Now the sections render directly below the user bubble with each section title visible and body expandable on click. A "View full" button opens the scrollable modal for focused reading. 2. Metadata items (system prompt, prompt context) now display their semantic title instead of the anonymous "Captured N raw sections" label. RawRailActivity now uses item.title as the verb, so "System prompt" and "Prompt context" render with their real names. 3. Permission rows now show the decided outcome. The permission response arrives as an acp_write event with result.outcome and the same JSON-RPC id as the request. A pendingPermissions map on TranscriptState indexes request id → lifecycle item id + option kind map. On the response the outcome is appended: Approved (allow_once) / Denied (reject_once) / Cancelled. Also restores metadata participation in isMeaningfulItem() for the Now summary bar. Raw JSON-RPC frames remain excluded (acpSource=raw_json_rpc); all semantic metadata (system prompt, prompt context) now contribute again, matching pre-#1381 behavior. System-prompt key (system-prompt:${ch}) is intentionally unchanged — the frame predates session creation and correctly reflects current channel setup by replacing on each session/new. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
…sions Adds a Playwright smoke spec that seeds observer relay events directly into the production appendAgentEvent → processTranscriptEvent ingestion path via a new __BUZZ_E2E_SEED_OBSERVER_EVENTS__ e2e bridge hook, then screenshots four surfaces restored by PR #1412: - 01-prompt-context-inline: collapsed inline prompt-context block - 02-system-prompt-title: system prompt with title visible in feed - 03-permission-approved: permission row with Approved (allow_once) outcome - 04-permission-cancelled: permission row with Cancelled outcome Supporting changes: - injectObserverEventsForE2E exported from observerRelayStore.ts - __BUZZ_E2E_SEED_OBSERVER_EVENTS__ Window hook wired in e2eBridge.ts - spec added to smoke project in playwright.config.ts Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Vision
This whole push starts from
VISION_ACTIVITY.md, added in this branch. The feed exists to earn delegation — to let a developer supervise an agent the way they'd supervise a capable teammate: skim for progress, trust the routine, catch the one thing that needs them. Every item earns its pixels by answering one of three questions — Comprehension (what is it doing, and why?), Confidence (is it going well, or stuck?), Control (do I need to step in, and where?).The governing frame is Verb · Object · Outcome: every meaningful item reads as a sentence — "Sent a message to #design," "Edited
runtime.rs(+12/−3)," "Ran tests → 1248 passed" — with the supporting detail pushed into progressive disclosure. The design principles that fall out of that (semantics over transport, outcome-first, mutate-in-place, never-go-dark, failures-rise-reads-recede, resolve-references, honesty-over-guessing, polished-by-default-raw-on-demand) are the rubric this code should be held to. Please keep the implementation honest to that doc.Overview
Category: improvement
User Impact: The agent activity feed reads like a supervisable transcript — a sentence per action with grouped tool work, semantic relay/file-edit/shell cards, modeled permission and lifecycle states, and a raw rail on demand — instead of a low-level event dump.
Problem: The old feed exposed event shapes too directly and spread classification across catalog + summary files via string-matching. Render classes were shoe-horned —
planrode insidethought, file-edits weren't distinct diff items, and lifecycle/permission weren't modeled at all (a permission interrupt looked identical to an ordinary status line). That forced the reader to parse before they could judge.Solution: A rebuild of the present/classify layers atop the existing reduce→group→render foundation: a pluggable classifier registry (
(toolName, args, result) → render-class + semantic descriptor, providers tried in order, generic fallback last) and twelve first-class render classes, so every event the agent can emit lands in exactly one class with an honest generic floor. The buzz catalog becomes one registered provider; harness tools another; non-buzz agents fall through to a clean generic row.Changes
This branch is the cumulative activity-feed stack (PR-1 transcript polish → PR-2 reducer hardening → PR-3 classify/present rebuild); stacking here is non-normative, so the diff is presented as a whole. The heart of PR-3 is the classifier + render-class taxonomy below.
File changes
VISION_ACTIVITY.md
The origin document — the reader-frame, the Verb·Object·Outcome lens, the twelve render classes, and the cross-cutting design principles. The rubric the rest of the diff is held to.
desktop/src/features/agents/ui/agentSessionToolClassifier.ts
The classifier registry seam —
(toolName, args, result) → render-class + semantic descriptor, providers tried in order with a generic fallback. Includes the buzz-CLI-in-shell parser (tokenizeShellCommand,parseBuzzCliCommand,extractSimpleEchoPipeContent) that promotes a shellbuzz …command to a proper relay-op descriptor.desktop/src/features/agents/ui/agentSessionTranscript.ts
The id-keyed reducer (coalesce + in-place upsert), now with branches that surface
session/request_permission→ permission items,raw_json_rpc→ in-feed raw-rail, and free-form title/text status; terminal-first tool inserts setcompletedAtimmediately so duration isn't lost. Unknown status-ish frames are intentionally ignored (commented).desktop/src/features/agents/ui/agentSessionTranscriptGrouping.ts
The grouping-layer pass — same-kind run-collapse within a turn (e.g. 5 reads → "Read 5 files"), summary labels, and turn bucketing.
desktop/src/features/agents/ui/activityRenderClasses/
The twelve render-class presenters promoted to first-class item types (message, relay-op, file-edit, shell, status/lifecycle, thought, plan/todo, permission, error, generic, raw-rail, suppressed), over a shared
ActivityRowprimitive.LifecycleActivitygives permission its own amber pill + ShieldCheck treatment, distinct from the red error pill.desktop/src/features/agents/ui/AgentSessionToolItem/
Tool-call rendering split into focused presenters (compact summary rows, todo/shell/diff blocks, sent-message context dialog, view-image preview, message-link resolution) instead of one payload-first monolith.
desktop/src/features/agents/ui/agentSessionTranscriptPresentation.ts + agentSessionTranscriptHelpers.ts
Presentation helpers, including
isMeaningfulItemnow wired into the BotActivityBar headline scan so lifecycle/metadata noise can't rotate into the compact working label.desktop/src/features/agents/ui/*.test.mjs
Unit coverage for the classifier (shell tokenizer, buzz-CLI parser, echo-pipe extraction), grouping (run-collapse, summary, bucketing), reducer (permission/raw/status flow), helpers, and presentation — the pure-function surfaces that previously had none.
desktop/tests/e2e/activity-debug-*.spec.ts + fixtures
Debug-fixture screenshot specs exercising every render class, plus the raw activity debug fixture used to prove permission/raw-rail/status reach the feed.
Reproduction Steps
buzz …shell command parsed into a relay-op card), plan/todo, error/recovered, suppressed, generic, raw-rail, and the permission row (amber pill + ShieldCheck) sitting distinctly above a red error pill.buildTranscript(DEBUG_AGENT_ACTIVITY_RAW_EVENTS)yields 53 items withpermission: 1,raw-rail: 2,status: 3— the formerly-dropped classes now flow.Render-class coverage
Every event the agent emits resolves to exactly one of the twelve render classes, organized by how often they're read and how much consequence they carry (per
VISION_ACTIVITY.md). The table below is the exhaustive set, each with a live example captured from the debug fixture during review.Coverage note (depth vs. breadth): the taxonomy is exhaustive —
... satisfies Record<AgentActivityRenderClass, Presenter>makes adding a class a compile error, and the last three classes (generic, raw-rail, suppressed) guarantee an honest floor for anything unrecognized. The semantic richness is intentionally Buzz-deep: Buzz relay ops, the buzz-CLI-in-shell parser, and file-edit diffs get bespoke cards, while non-Buzz MCP/ACP tools deliberately fall through to the clean generic row rather than fabricated semantics. Non-Buzz agents get a correct, legible feed; Buzz agents get a native one.The spine — read constantly
buzz messages sendpromoted to a message cardHigh-value context — consulted to judge correctness
Ambient safety net — rarely read, but must exist
raw_json_rpcas a collapsible in-feed sectionIn-feed contrast
All three formerly-dropped classes (permission, raw-rail, status) rendering together, with the amber Permission requested pill sitting distinctly above the red Turn error pill — exactly the high-signal interrupt the vision calls for:
Notes for the reviewer
main(a release bump + provider-agnostic model selection), touchingbuzz-agent/src-tauri/ persona pickers — disjoint from the activity-feed files, low conflict risk. Deliberately not rebased — holding any history rewrite until eyeballed. Safety refsafety/pr-3-pre-pr-4f5276acparked locally.buzz-acpstop_reasonenrichment;view_imageremote-thumbnail + per-kind tool icons.Closes #1344