Add expandable command and file-change activity boxes#3173
Add expandable command and file-change activity boxes#3173Quicksaver wants to merge 304 commits into
Conversation
- Query peers sequentially until one returns a result - Avoid sending owner-sensitive commands to later peers - Cover the interrupt dispatch path with a regression test
- Align VS Code extension deps with the upstream Effect catalog - Switch local peer HTTP calls and server tests to Effect HTTP - Tighten orchestration test decoding for thread.turn.start
- Resolve catalog dependencies from the root workspace catalog - Keep packaged VS Code manifests installable outside the monorepo
- Add forceDesktopLayout to sidebar provider - Keep thread sidebar open in desktop shells - Add regression coverage for desktop rendering
- Preserve provider lock in all hosts - Remove VS Code-only composer unlock path - Update unit coverage for shared lock behavior
- Buffer and coalesce subagent activity output - Preserve local behavior for future upstream merges - Document branch-specific changes in CUSTOMIZED.md
- Let chat surfaces use full available width by default - Keep the VS Code setting as an explicit opt-in override - Cover the new default with a focused web test - Update extension docs to describe empty as no max width
- Label desktop-bootstrap bearer sessions as VS Code - Shorten their bearer TTL and revoke stale ones - Add authenticated session revocation on backend stop - Route thread archive stop commands through peer context - Update tests for auth, federation, and backend cleanup
- Remove the 12-hour TTL override for backend bearer sessions - Keep stale desktop-bootstrap cleanup separate from live tokens
- Restrict self-revoke route to bearer sessions - Make backend revocation timeout portable and resilient - Preserve peer archive-stop routing fallback
- Stop provider sessions when archive routing lookup fails - Add regression coverage for lookup failure fallback
- Add bearer-only HTTP authentication for revocation - Cover revocation when cookie and bearer auth coexist
- Add shared desktop backend advertisement files\n- Issue and refresh bootstrap tickets for desktop backends\n- Let the web UI read VS Code workspace bootstrap data
- Revoke stale VS Code bearer sessions on cancelled startup - Gate desktop ready state on control advertisement setup - Replace connected webview disposables on reconnect
- Delete expired desktop bootstrap ticket rows during issuance - Remove advertisements after closing backend run scope
- Restrict desktop ticket minting to control sessions - Harden VS Code workspace bootstrap selection and retries - Tighten host bridge typing and cleanup behavior
- Thread startup abort signals through backend readiness and bootstrap - Update cancellation coverage to honor abort signals
- Remove stopped desktop backend advertisements after close - Keep workspace bootstrap tied to active cancellation only
- Document current desktop-control ticket flow - Note workspace bootstrap fallback and abort behavior - Keep README unchanged because it still matches shipped UX
- Note the extension work is local customization - Point implementation detail to apps/vscode-extension/IMPLEMENTATION.md
# Conflicts: # .github/workflows/release.yml # apps/server/src/auth/Layers/ServerAuth.test.ts # apps/server/src/auth/Layers/ServerAuth.ts # apps/server/src/auth/PairingGrantStore.test.ts # apps/server/src/auth/PairingGrantStore.ts # apps/server/src/auth/Services/ServerAuth.ts # apps/server/src/auth/SessionStore.ts # apps/server/src/auth/http.ts # apps/server/src/orchestration/http.ts # apps/server/src/server.test.ts # apps/server/src/server.ts # apps/server/src/ws.ts # apps/web/src/authBootstrap.test.ts # apps/web/src/environments/primary/auth.ts # apps/web/src/environments/primary/bootstrap.test.ts # apps/web/src/environments/primary/context.ts # apps/web/vite.config.ts # bun.lock # packages/contracts/src/ipc.ts
- keep the workspace test command on the merged toolchain
- replace stale bun package commands - refresh verified toolchain and auth wording
- keep mobile builds on the local Expo project - remove the stale mobile package override - invoke vsce through pnpm exec
# Conflicts: # .gitignore # apps/server/src/bin.ts # apps/web/src/components/settings/SettingsSidebarNav.tsx # apps/web/src/environments/runtime/service.ts # apps/web/src/main.tsx # apps/web/src/routes/_chat.index.tsx # packages/shared/package.json # pnpm-lock.yaml # pnpm-workspace.yaml
- Switch extension tests to the Effect Vitest package - Update the extension dev dependency and lockfile - Refresh customized branch test commands in CUSTOMIZED.md
- Remove desktop-issued VS Code ticket advertising - Store and reuse the exchanged bearer token in VS Code - Keep the desktop backend advertisement credential-free
- Preserve latest running child activity rows in parent timelines - Add per-generation sidebar indentation for visible subagents - Update subagent dedupe and visibility tests
…tivity-boxes # Conflicts: # apps/web/src/components/chat/MessagesTimeline.test.tsx # apps/web/src/components/chat/MessagesTimeline.tsx # apps/web/src/session-logic.test.ts # apps/web/src/session-logic.ts
- Escape embedded script end tags in bridge data - Dispose webview resources when rendering fails - Clean up MCP sockets after listen failures - Surface malformed desktop readiness responses - Keep timeline hooks after the early subagent return
- Keep subagent row hooks stable before grouped rendering - Retry stalled VS Code readiness bodies under abort timeout
- Preserve retries for transient readiness body read failures - Escape inline webview bootstrap payload parser breakouts - Share render cleanup for connected VS Code webviews
There was a problem hiding this comment.
Effect service conventions: one error class deviates from the module's pattern and the service error conventions.
Posted via Macroscope — Effect Service Conventions
- Switch the error to a Schema tagged error\n- Keep the message stable for backend advertisement failures
- Include advertisement failure causes in warning messages
Keep the desktop backend advertisement error message stable while logging the underlying cause as structured metadata.
- Preserve nested advertisement failure causes safely - Add coverage for malformed advertisement cause values
- Redact fallback advertisement diagnostics for malformed URLs - Cover invalid-port URL sanitizer behavior
…activity-boxes # Conflicts: # apps/server/src/provider/Layers/CursorProvider.test.ts # apps/web/src/components/AppSidebarLayout.tsx # apps/web/src/components/NoActiveThreadState.tsx # apps/web/src/components/Sidebar.tsx # apps/web/src/components/chat/ChatHeader.tsx # apps/web/src/components/ui/sidebar.tsx # apps/web/src/routes/_chat.index.tsx # apps/web/src/routes/settings.tsx
- Check updateThreadMetadata failure in server thread updates - Set thread error when the source control update does not succeed
- Clear stale thread errors after metadata updates - Preserve string failure messages from squashed causes
- Track source control metadata update errors separately - Clear only metadata update errors after successful ref changes
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a02327a. Configure here.
- Add shared helpers for thread error clearing - Ignore out-of-order metadata responses per thread - Reuse the dismiss handler for server-thread errors
- Use the active thread key for metadata error state - Prune stale metadata errors and update sequences - Cover thread-key record pruning in ChatView tests
There was a problem hiding this comment.
Effect service conventions: one issue found in the newly added SourceControlPanelService. See inline comment.
Posted via Macroscope — Effect Service Conventions
| export interface SourceControlPanelServiceShape { | ||
| readonly snapshot: ( | ||
| input: VcsPanelSnapshotInput, | ||
| ) => Effect.Effect<VcsPanelSnapshotResult, GitCommandError>; | ||
| readonly branchDetails: ( | ||
| input: VcsPanelBranchDetailsInput, | ||
| ) => Effect.Effect<VcsPanelBranchDetails, GitCommandError>; | ||
| readonly branchCommits: ( | ||
| input: VcsPanelBranchCommitsInput, | ||
| ) => Effect.Effect<VcsPanelBranchCommitsResult, GitCommandError>; | ||
| readonly stashDetails: ( | ||
| input: VcsPanelStashDetailsInput, | ||
| ) => Effect.Effect<VcsPanelStashDetails, GitCommandError>; | ||
| readonly stageFiles: (input: VcsPanelFileActionInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly unstageFiles: (input: VcsPanelFileActionInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly discardFiles: (input: VcsPanelFileActionInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly enrichWorkingTreeFiles: ( | ||
| input: VcsPanelWorkingTreeFileEnrichmentInput, | ||
| ) => Effect.Effect<VcsPanelWorkingTreeFileEnrichmentResult, GitCommandError>; | ||
| readonly readFileDiff: ( | ||
| input: VcsPanelFileDiffInput, | ||
| ) => Effect.Effect<VcsPanelFileDiffResult, GitCommandError>; | ||
| readonly commitStaged: (input: VcsPanelCommitInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly pullBranch: ( | ||
| input: VcsPanelBranchActionInput, | ||
| ) => Effect.Effect<VcsPullResult, GitCommandError>; | ||
| readonly pushBranch: (input: VcsPanelBranchActionInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly deleteBranch: (input: VcsPanelDeleteBranchInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly undoLatestCommit: ( | ||
| input: VcsPanelUndoCommitInput, | ||
| ) => Effect.Effect<void, GitCommandError>; | ||
| readonly revertCommit: (input: VcsPanelCommitActionInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly checkoutCommit: ( | ||
| input: VcsPanelCommitActionInput, | ||
| ) => Effect.Effect<{ readonly refName: string }, GitCommandError>; | ||
| readonly createBranchFromCommit: ( | ||
| input: VcsPanelCommitActionInput, | ||
| ) => Effect.Effect<{ readonly refName: string }, GitCommandError>; | ||
| readonly mergeBranchIntoCurrent: ( | ||
| input: VcsPanelRefActionInput, | ||
| ) => Effect.Effect<void, GitCommandError>; | ||
| readonly rebaseCurrentOnto: ( | ||
| input: VcsPanelRefActionInput, | ||
| ) => Effect.Effect<void, GitCommandError>; | ||
| readonly fetchBranch: (input: VcsPanelBranchActionInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly fetchRemote: (input: VcsPanelRemoteInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly fetchAllRemotes: (input: VcsPanelSnapshotInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly addRemote: (input: VcsPanelAddRemoteInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly removeRemote: (input: VcsPanelRemoteInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly createStash: (input: VcsPanelStashInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly applyStash: (input: VcsPanelStashInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly popStash: (input: VcsPanelStashInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly dropStash: (input: VcsPanelStashInput) => Effect.Effect<void, GitCommandError>; | ||
| readonly compare: ( | ||
| input: VcsPanelCompareInput, | ||
| ) => Effect.Effect<VcsPanelCompareResult, GitCommandError>; | ||
| } | ||
|
|
||
| export class SourceControlPanelService extends Context.Service< | ||
| SourceControlPanelService, | ||
| SourceControlPanelServiceShape | ||
| >()("t3/sourceControl/SourceControlPanelService") {} |
There was a problem hiding this comment.
This newly added service declares a standalone SourceControlPanelServiceShape interface and passes it into Context.Service, but the convention is to define the service interface inline in the Context.Service declaration and refer to it as SourceControlPanelService["Service"] (no standalone FooShape type).
Suggested change: move the interface body inline into the tag and drop the separate interface:
export class SourceControlPanelService extends Context.Service<
SourceControlPanelService,
{
readonly snapshot: (
input: VcsPanelSnapshotInput,
) => Effect.Effect<VcsPanelSnapshotResult, GitCommandError>;
// ...rest of the members...
readonly compare: (
input: VcsPanelCompareInput,
) => Effect.Effect<VcsPanelCompareResult, GitCommandError>;
}
>()("t3/sourceControl/SourceControlPanelService") {}Then update the implementation references from SourceControlPanelServiceShape["..."] to SourceControlPanelService["Service"]["..."].
Posted via Macroscope — Effect Service Conventions

Summary
This adds richer expandable activity boxes for command and file-change work-log rows in the chat timeline. Command rows can now show the command, raw command, exit code, duration, stdout/stderr or fallback output, and file-change rows can show changed paths plus inline unified diffs when patch data is available.
The implementation keeps this data in the derived work-log model, extracts command result and patch metadata from provider payloads, and renders the richer details without losing the existing compact row behavior.
What Changed
WorkLogEntry, including stdout, stderr, fallback output, exit code, and duration.MessagesTimelinewith command/raw-command sections, status chips, tail-truncated output, and full-output expansion.MessagesTimelinewith changed-file chips and inline diff rendering through the existing diff rendering utilities.Why
Individual command and diff events are mostly opaque currently. We can somewhat see what the agent is doing, but we don't have a clear picture of what each command actually outputs, or what each file change actually produced.
Usually that's fine, most times we inspect the end result and trust the agent. Sometimes it's good to inspect a little deeper. For commands we can help steer by debugging their output, or just compare the results with manual runs. For diffs we can see better follow along the multiple changes an agent makes, or even inspect changes to git-ignored files (which don't appear on the main diff panel).
Validation
(cd apps/web && pnpm exec vp test run --passWithNoTests --project unit src/session-logic.test.ts)passed: 1 file, 79 tests.(cd apps/web && pnpm exec vp test run --passWithNoTests --project unit src/components/chat/MessagesTimeline.test.tsx)passed: 1 file, 13 tests.pnpm exec vp run --filter @t3tools/web test -- src/components/chat/MessagesTimeline.test.tsxpassed on the final branch state: 145 files, 1318 tests.pnpm exec vp run --filter t3code-vscode test -- src/backendManager.test.ts src/webview.test.ts src/mcpBridge.test.ts src/extension.test.tspassed on the final branch state: 6 files, 55 tests.pnpm exec vp run --filter @t3tools/desktop test -- src/backend/DesktopBackendManager.test.tspassed on the final branch state: 43 files, 241 tests.pnpm exec vp run --filter @t3tools/web test -- src/components/source-control/SourceControlPanel.logic.test.ts src/state/sourceControlPanel.test.tspassed after the source-control metadata error handling fix: 146 files, 1330 tests.pnpm exec vp run --filter @t3tools/web test -- src/components/ChatView.logic.test.tspassed after the source-control metadata error dismissal/race fixes: 146 files, 1335 tests.pnpm exec vp checkpassed. It reported 20 existing lint warnings outside this branch's changed files.pnpm exec vp run typecheckpassed across all packages.$assess-workcompleted after the review fixes. Earlier CodeRabbit first/final passes reported 0 issues; Codex and blast review follow-ups were addressed in1558dd029,26c447183, and the desktop advertisement diagnostic commits throughbac9d4907. The Macroscope source-control metadata thread was addressed byaa0adfd93,1bb7681c, anda02327a7. The latest Cursor source-control metadata dismissal/race threads were addressed by4ca7cf953,f15d7e34c,ef437d295,cface2863, and documented in2565d1d90; CodeRabbit/Codex/blast assessment follow-ups were addressed and the final CodeRabbit pass reported 0 issues.Proof
before:

after:

expanded command output with tail truncation:

expanded inline file-change diffs:

Note
High Risk
Touches orchestration persistence and auth bootstrap paths plus broad Git/VCS and desktop lifecycle behavior; scope and cross-client impact make regressions costly.
Overview
Chat work-log rows now expose richer expandable detail: command sections (stdout/stderr, exit code, duration, tail truncation), file-change chips with inline unified diffs when patch data exists, and dedicated subagent summary rows that link into child threads instead of treating collab items like generic expandable tools.
session-logiccarries structured command output, patch extraction, stable ordering for streamed chunks, and safer incremental output merging.Codex subagent orchestration is wired end-to-end: threads gain persisted
parentRelation(projection ingest/query, lifecycle commands), child shells and launch prompts from collab metadata, title generation from the title seed, resume/re-run status updates, and child turn interrupts routed through the root provider session without falling back to the parent’s active turn.The fork also adds substantial platform surface: Git Version Control right-panel behavior and server RPCs (documented in
SOURCE_CONTROL.md), desktop backend advertisements with sanitized failure diagnostics and cleanup on stop, VS Code–style host bootstrap (workspace folders, MCP servers,stdio-to-udsrelay), legacy/api/auth/bootstrap/bearercompatibility routes, Electron context-menu separator normalization, and agent skills for multi-worktree update/port/comment flows. Docs and investigation logs (SUBAGENTS.md,POWER_CONSUMPTION.md, fork pointer inAGENTS.md) accompany these behaviors.Reviewed by Cursor Bugbot for commit 91c1d67. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add expandable command and file-change activity boxes to the chat timeline
aria-expandedandaria-labelattributes; commands, file changes, and subagent items each show structured detail panels when expanded.session-logic.tsis significantly extended to extractstdout,stderr,exitCode,durationMs, andpatchfrom tool payloads; merging across streaming updates now prefers cumulative content and avoids regressing to shorter snapshots.projection_threadsand two new indexes; migration 034 backfillsroot_thread_idfor existing rows, which could be slow on large databases.Macroscope summarized 91c1d67.