- Codex: decouple active_agent_count decrement from close_agent target
parsing and reset counter on turn_context to prevent main assistant
messages from being swallowed when close_agent events are malformed
- Codex: use exact filename match with separator-aware fallback and
sorted candidates for deterministic subagent session file resolution
- Codex/OpenCode: truncate subagent tool call previews to 500 chars
- OpenCode: batch-load all subagent tool calls in a single SQL query
instead of per-task N+1 queries to avoid slow detail page loads
- Streaming: restrict positional child grouping fallback to in-progress
agents only, preventing top-level tool calls from being incorrectly
folded into completed Agent cards
- Tests: update Claude context window assertions to match 1M default
Refactor cleanAgentOutput to a sequential non-recursive pipeline: unwrap
JSON containers first, then strip task_id session lines, then extract
<task_result> content. Also apply cleaning to in-progress agent output
during streaming, not just completed results.
Forward the previously-dropped `locations` and `meta` fields from ACP
SDK ToolCall/ToolCallUpdate events through to the frontend. The meta
field carries `claudeCode.parentToolUseId` which enables precise
parent-child matching for concurrent Agent tool calls during streaming.
- Forward locations/meta in Rust AcpEvent types and connection handlers
- Use parentToolUseId for exact agent→child mapping, with position-based
fallback for agents that don't provide it (Codex, OpenCode)
- Replace `any` types with proper ToolCallMeta / unknown types
- Add runtime guards for meta field parsing (defensive against
unexpected shapes from different agents)
- Cache inferLiveToolName results per tool_call_id to avoid redundant
computation across Phase 1 and Phase 2
- Lazy-construct agentStats only when children exist
Support Agent card rendering during live streaming responses for Claude
Code, Codex CLI, and OpenCode. Previously Agent cards only rendered for
loaded/historical messages parsed from the DB.
- Fix tool name inference: subagent_type in input now returns "agent"
instead of "task"; add spawn_agent/wait_agent/close_agent aliases
- Group sub-agent tool calls inside parent Agent cards during streaming
using position-based heuristic (ACP SDK lacks parent_id tracking)
- Clean raw Agent output (JSON content blocks, XML task_result wrappers)
- Emit agent_stats with nested tool calls so AgentToolCallPart renders
child execution inline, matching the loaded message appearance
Live tool calls that produce output while running (e.g. streaming bash
stdout from Codex) now render their partial output in real time instead
of appearing blank until the tool completes. The tool card keeps its
running visual state — spinner and 24KB tail truncation — while chunks
arrive, and transitions to the completed state once the final status
lands. A WeakMap keyed on the ACP reducer's chunks-array identity
memoizes the joined output so repeated renders don't re-run O(n) string
concatenation.
Prevent left and right sidebars from auto-opening on small screens during folder page initialization, regardless of persisted open state.
Gate mobile sidebar sheets behind restored panel state to avoid initial sidebar pop-in.
Enable raw Claude SDK forwarding for ACP sessions and emit only system/api_retry events to the frontend.
Show a localized single-line retry banner with loading under the conversation input, including error details and retry progress.
Replace raw_output single-string accumulation with a chunks array to
eliminate O(n^2) string concatenation on every 200ms terminal poll event.
Batch tool_call_update dispatches via requestAnimationFrame so multiple
agents no longer trigger 25+ React re-renders per second.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Session-page connect never triggers download/install; returns
SdkNotInstalled immediately and prompts the user to install from
Agent Settings instead
- Binary agents now accept any cached version via
find_best_cached_binary_for_agent so stale caches still connect
- Bound Initialize handshake with a 60s timeout and convert it to
AcpError::InitializeTimeout via a sentinel in run_connection
- Spawn background task owns ConnectionManager map insertion and
removes the entry on exit through an RAII guard that survives
panics, preventing leaked stale entries
- AcpError gains SdkNotInstalled and InitializeTimeout variants plus
a stable code() identifier; AcpEvent::Error carries code so the
frontend can render localized messages by key
- Frontend preflight now runs for all connect sources; error event
handler switches on code to show translated text for
initialize_timeout, sdk_not_installed, platform_not_supported,
process_exited, spawn_failed and download_failed
- Remove ConnectionStatus::Downloading enum variant, all frontend
branches, and i18n strings; drop obsolete autoLinkFailedTitle,
autoLinkPreflightFailed, preflightCheckFailedDefault and
preflightFailedTitle keys across 10 locales
- Add backendErrors.* translations in 10 languages
- Diagnostic logging: always log agent stderr plus binary
path/size/args/env keys and Initialize timing; gate stdin/stdout
JSON-RPC tracing behind CODEG_ACP_DEBUG to avoid persisting user
content into OS log files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace crypto.randomUUID() with the existing randomUUID() utility
that falls back to crypto.getRandomValues() over plain HTTP.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Centralize terminal process lifecycle in terminal-context as single
source of truth. TerminalView reports exit/failure via callback,
context maintains exitedTerminals set, command-dropdown reacts to it.
Removes redundant polling and per-component exit event subscriptions
that raced with deferred spawn introduced in b2d10fa.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move PTY spawn from context layer to view layer so event subscription
happens before spawn, preventing loss of initial terminal output.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>