Work deferred from Phases 2–3, plus items discovered while mining pingdotgg/t3code's
ClaudeAdapter.ts. Read alongside NOTES.md (which captures spike-era limits) and
the design handoff under design_handoff_conclave/.
These were carry-overs from Phase 3 that have since been implemented. Listed here so the original scoping is still discoverable.
messagestable is written to on every append (SessionManager.PersistMessage).- Schema:
(id, session_id, role, content, tools_json, created_at, seq, claude_uuid)(migration v3, extended in v9). - Loaded lazily on session activate via
LoadTranscriptIfNeeded.
WorktreeService.ComputeDiffparses--numstat+--name-status.SessionManager.RefreshDiffis invoked after eachResultEvent.- Cached in DB columns (
diff_files/add/del) so the sidebar still has numbers when the worktree is unreachable.
SessionVm.CancellationSourceset byClaudeServicefor the duration of a turn.ShellVm.CancelActiveTurncancels the linked CTS, which kills the child process.
messages.claude_uuidcolumn (migration v9), populated from theAssistantEvent'suuidfield. Used by fork-at-message to map our row back to claude's JSONL chain.
Session.TotalCostUsdaccumulated from eachResultEvent.TotalCostUsd. Surfaced onSessionVm.TotalCostFormattedin the right panel.- Per-event
usagebreakdown is not surfaced (input vs cache_read vs cache_create); could still be added if the difference becomes interesting.
--include-partial-messagesis passed unconditionally;ClaudeService.HandleStreamDeltaappendstext_deltas to the liveTranscriptMessageVm.- Tool-use input deltas are still ignored; we wait for the final
assistantevent for those.
- READ: line count, GLOB/GREP: match count, EDIT/WRITE: collapses success preamble to "ok". BASH: still falls back to first-line trim — exit-code + duration parsing is still TODO.
SessionVm.Planis anObservableCollection<PlanItemVm>.TodoWriteinvocations are parsed bySessionManager.ParsePlanJsonand pushed viaSessionVm.ReplacePlan.- Persisted via
sessions.plan_json(migration v4). - Header / progress bar / row states render per
PlanView.axaml.
SessionVm.Logsis a 500-entry ring buffer ofLogLineVm((ts, level, message)).- Lifecycle, informational stream events, and errors are routed through
ClaudeService.Log. Not persisted (intentional).
- Per-session
permission_mode(migration v5) passed to claude via--permission-mode. UI selector: Prompt / Auto-accept edits / Full access. - Still open: structured
AskUserQuestionandExitPlanModeflows. They render as ordinary tool calls today and the model will wait indefinitely for a response we can't give. Either (a) implement an MCP-basedcanUseToolcallback, or (b) embed Node + Agent SDK. Both deferred. Sessions show a warning log line when these tools fire so the user knows why claude is hanging.
GhService.TryGetPullRequestrunsgh pr view; refreshed on session load and after each turn. Hidden whenghisn't installed/authenticated.Session.PrNumber/PrState/PrMergedAtcached (migrations v2 + v7) so the card paints immediately on load.
EmptyState.axamlrenders when!HasActiveSession. Right panel auto-collapses viaMainWindow.ApplyResponsiveLayout.
- Filter pills filter (
ShellVm.ApplyFilter). - Project rename (
SessionManager.RenameProject+ sidebar context menu). - Auto-expand project on filter/search match.
- Claude version gate (
ClaudeCapabilities.Detect+AtLeast). - Auto-cleanup of merged sessions (
AutoCleanupService, settings v8).
- ⌘⏎ submit in the new-session modal — visual hint exists, key handler doesn't.
- Auto-expand project on new session — currently the sidebar shows the new session under its project but the chevron stays collapsed if the user had it collapsed.
- Capability probe — t3code's trick of starting a query, reading init, and aborting. Useful for an About dialog and to disable unavailable models in the selector.
Subprocess spawn vs Agent SDK. t3code gets a lot for free from the Node SDK:
multi-turn streaming via a single long-lived query() fed by an async iterable,
permission callbacks, per-message lifecycle events. Our per-turn CLI-spawn approach
works but costs a process-start per turn and gives us less granular control.
Three paths:
- Stay with CLI (current). Replicate features manually. Simplest packaging; no Node runtime dependency. What we're doing now.
- MCP-based augmentation: CLI base + local MCP server for permission prompts
and structured I/O. Medium lift. Would unblock the
AskUserQuestion/ExitPlanModeflows above. - Embed Node + use Agent SDK: heaviest; introduces a second runtime in the bundle. Cleanest feature parity.
Revisit this choice when either (a) we hit a CLI limitation we can't work around (e.g. need true per-tool permission callbacks and MCP doesn't cut it), or (b) platform bundling via a Node sidecar proves cheap on all three target OSes.