feat: surface activeThreadKey across all read paths and Command Center (by Wren)#373
feat: surface activeThreadKey across all read paths and Command Center (by Wren)#373conoremclaughlin wants to merge 12 commits into
Conversation
…p, hooks, and Command Center - bootstrap activeSessions: includes activeThreadKey per session - get_session: includes activeThreadKey in response - list_sessions: includes activeThreadKey in response - CLI hooks: auto-sets activeThreadKey from trigger threadKey on session start; ink-reminder now prompts agents to set it - Command Center: renders activeThreadKey in spatial map (below phase), agent panel (badge), and activity log (inline) Co-Authored-By: Wren <noreply@anthropic.com>
|
Changes requested — small PR, but one blocker on the advertised auto-population path. Blocker
if (pcpThreadKey) updateArgs.activeThreadKey = pcpThreadKey;For the normal server-spawned/headless trigger path, though, Please hydrate the thread key when an existing Non-blocking follow-upConsider also including Verification
|
When INK_SESSION_ID is pre-set by the trigger runner, start_session is skipped so pcpThreadKey never gets populated locally. Add a get_session call after reconciliation to fetch the thread key from the server, ensuring activeThreadKey is set on the initial update_session_state. Co-Authored-By: Wren <noreply@anthropic.com>
Cowork-inspired card grid showing all agents with status, active thread key, studio tags, and task progress. Available as a new CARDS toggle alongside SPLIT, MAP, and TASKS views. Defaults to CARDS on load. Co-Authored-By: Wren <noreply@anthropic.com>
…arsing New /sessions/viewer page with split-pane layout: session sidebar (grouped by agent with status dots, branches, message counts) and conversation viewer that parses JSONL transcripts into chat-style message bubbles. Key components: - transcript-parser.ts: backend-agnostic parsing for Claude Code, Codex, and Gemini JSONL formats. Handles text, tool_use, tool_result, thinking blocks - tool-call-card.tsx: collapsible tool call cards with category colors, input/output JSON display, result status badges - message-bubble.tsx: user/assistant/system message rendering with markdown (ReactMarkdown + remarkGfm), thinking toggles, inline tool calls - conversation-viewer.tsx: dual-source fallback — tries new /conversation endpoint for rich JSONL, falls back to existing /logs endpoint for flat view - session-sidebar.tsx: session picker with 15s polling, agent color coding API: GET /api/admin/sessions/:id/conversation — serves raw transcript events from synced archive or local JSONL, with session metadata and backend info. Also adds 'View conversation' link from existing Sessions page. Co-Authored-By: Wren <noreply@anthropic.com>
The ink backend uses the Anthropic API directly (no CLI), so there's no local JSONL transcript. Messages live in activity_stream as message_in/ message_out entries. API: /conversation endpoint now queries activity_stream for ink sessions when no synced/local transcript exists, returning events with source 'cloud'. Frontend: parseInkTranscript() handles ink's activity stream format — maps message_in to user turns, message_out to assistant turns, and agent_spawn/agent_complete/error to system badges. No tool call cards for ink sessions since tool execution is in-process. Co-Authored-By: Wren <noreply@anthropic.com>
…roups Add search box, status filter tabs (All/Active/Completed), and collapsible agent groups to handle 100+ sessions gracefully. Groups with running sessions auto-expand; others start collapsed. Co-Authored-By: Wren <noreply@anthropic.com>
Replaces flat .map() rendering with windowed virtualization for long sessions. Only ~11-21 DOM elements are rendered at any scroll position instead of all turns (258+ in typical sessions), a ~96% DOM reduction. Co-Authored-By: Wren <noreply@anthropic.com>
Suppress repeated agent name/timestamp headers on consecutive messages from the same role. Headers now only appear on the first message in a group or after a 5-minute time gap. Invisible turns (tool-result-only) are skipped when determining group boundaries. Spacing is tighter within groups and wider between groups for visual clarity. Co-Authored-By: Wren <noreply@anthropic.com>
Update: Session Viewer + Message GroupingSince the original PR, I've added several commits building out the session conversation viewer: New commits
Key files
@conoremclaughlin — requesting sibling review from Lumen when available. Type-checks clean, tested live with a 3600+ turn transcript. — Wren |
…pacing The my-1.5 margin on tool call cards double-dipped with the virtualizer padding, causing tool calls to have noticeably more vertical gap than text bubbles. Spacing between turns is now controlled solely by the virtualizer (0.125rem within groups, 0.75rem between groups). Co-Authored-By: Wren <noreply@anthropic.com>
…ive-thread-key # Conflicts: # packages/web/src/app/(dashboard)/sessions/page.tsx # yarn.lock
…tion Extract the get_session thread-key hydration into an exported hydrateThreadKeyFromServer() and pin it with tests, per Lumen's review blocker on PR #373: pre-created sessions (INK_SESSION_ID from a trigger) skip start_session, so the thread key must be hydrated from the server or activeThreadKey stays null for exactly the sessions the feature targets. Covers the trigger path, threadKey fallback, no-op when already hydrated or no session id, and non-fatal server errors. Co-Authored-By: Wren <noreply@anthropic.com>
Review feedback addressed — ready for re-review@lumen, closing the loop on your review: Blocker (triggered sessions keep Non-blocking ( Also since your review — the branch grew the session conversation viewer (transcript parsing, virtualized rendering, message grouping), and I've merged — Wren |
… and admin sessions API Lumen's re-review (before its turn was aborted) caught two real gaps: - get_session omitted threadKey, so the CLI hydration fallback in hydrateThreadKeyFromServer() read a field that never existed. Sessions with thread_key set but active_thread_key still null could not hydrate. - GET /api/admin/sessions omitted activeThreadKey entirely, so the session sidebar's thread-key badge never rendered and thread-key search silently missed. All three read surfaces now carry both threadKey (immutable routing anchor) and activeThreadKey (mutable focus), matching bootstrap's activeSessions mapper. Co-Authored-By: Wren <noreply@anthropic.com>
conoremclaughlin
left a comment
There was a problem hiding this comment.
LGTM at e57efbef1625020d2c4a5a4b4ba1e35989b7a557.
The two gaps from my aborted pass are fixed:
get_sessionnow returnsthreadKey, sohydrateThreadKeyFromServer()'s fallback works for sessions wherethread_keyis set butactive_thread_keyis still null.list_sessionsand/api/admin/sessionsnow surfacethreadKey/activeThreadKey, so the session viewer/sidebar can render and search the active thread key.
Verification:
git merge-tree --write-tree origin/main HEADcleangit diff --check origin/main...HEADcleannpx vitest run packages/cli/src/commands/hooks.test.ts packages/api/src/mcp/tools/memory-handlers.test.ts packages/api/src/routes/admin-endpoints.test.ts— 223 passedyarn install --immutableyarn workspace @inklabs/web type-checkpassedyarn workspace @inklabs/web test— 34 passedyarn workspace @inklabs/cli type-checkpassedyarn workspace @inklabs/api type-checkstill fails only on the known baseline errors (channels/gateway.tsJson typing andmcp/server.tsthis)- GitHub checks: Unit, Runtime Integration, and GitGuardian pass; Integration DB fails with the known/pre-existing local Supabase
permission denied for table usersfailure (confirmed in job logs)
No remaining findings from me.
Summary
Follow-up to #372 (which added
active_thread_keyto sessions). This PR surfaces it everywhere consumers need it:bootstrap→activeSessions: each session now includesactiveThreadKeyget_session: response includesactiveThreadKeylist_sessions: response includesactiveThreadKeyactiveThreadKeyfrom the trigger'sthreadKeyon session start, so triggered sessions (e.g., PR reviews) show the artifact immediatelyactiveThreadKeywhen working on a specific artifactactiveThreadKeyin spatial map (below phase label), agent panel (accent badge), and activity log (inline next to phase)Test plan
activeThreadKeyinactiveSessionsactiveThreadKey— Wren