- Stream tool results in real-time during Claude Code SDK sessions
instead of deferring until session end. Tool calls (read, bash, write,
etc.) now show their output as they complete, not collapsed as "..."
- Stop suppressing toolcall_start/delta/end events from stream adapter
so the TUI can render tool call progress during streaming
- On SDK turn boundary (user message with tool results), push synthetic
toolcall_end events with externalResult attached for immediate rendering
- Chat controller checks for externalResult on toolcall_end message
updates and calls updateResult on pending ToolExecutionComponents
- Fix case-sensitive tool name matching (Read vs read, Bash vs bash)
in TUI ToolExecutionComponent rendering
- Auto-discover and pass GSD_WORKFLOW_EXECUTORS_MODULE and
GSD_WORKFLOW_WRITE_GATE_MODULE env vars in MCP server launch config
- Add /gsd mcp init command and auto-bootstrap .mcp.json for Claude
Code provider during auto-start
- Add tool_execution_update event type for web UI streaming updates
- Add setStderrLoggingEnabled toggle for workflow logger
Anthropic now blocks third-party apps from using Pro/Max subscription
quotas via direct API calls. This change makes the claude-code provider
(which delegates to the local claude CLI binary) the default path for
Anthropic subscription users — TOS-compliant because requests flow
through Anthropic's own infrastructure.
Changes:
- Enhanced readiness check to verify CLI auth status (not just binary)
- Startup migration: auto-switch anthropic → claude-code when CLI ready
- Error recovery: auto-switch on third-party 400 block error
- Onboarding: removed Anthropic from OAuth, added Claude CLI option
- Added claude-code to flat-rate providers (no dynamic routing benefit)
Closes#3772
* fix: repair YAML bullet lists in malformed tool-call JSON (#2660)
When LLMs copy YAML template formatting into tool-call arguments, they
produce `"key": - item` instead of `"key": ["item"]`, causing JSON parse
errors that block milestone completion. Add a repairToolJson() utility
that detects and converts YAML-style bullet lists into JSON arrays before
parsing. Integrated into both the PartialMessageBuilder (claude-code-cli)
and the anthropic-shared streaming provider, with fallback in
parseStreamingJson for all other providers.
Closes#2660
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use .js import extension in repair-tool-json test
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The claude-code provider in gsd-pi was effectively stateless: it sent
only the last user message, disabled session persistence, and filtered
out all sidechain/subagent events. This made multi-turn conversations
feel isolated and caused incomplete responses.
- Replace extractLastUserPrompt with buildPromptFromContext that
serialises the full conversation history (system prompt + all turns)
- Change persistSession from false to true for session continuity
- Remove parent_tool_use_id filtering so delegated/sidechain outputs
are included in the final response
- Extract buildSdkOptions for testability
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Treat Claude SDK generator exhaustion without a terminal result as a
stream interruption instead of a successful completion.
This prevents phantom-success auto-mode advances, keeps the failure
classifiable as transient provider recovery, and adds regression tests
for the fallback message plus provider classification.
Closes#2575
When the API stream is truncated mid-tool-call, PartialMessageBuilder
emits a toolcall_end event with { _raw: "<broken json>" } in the
arguments — but the event looks identical to a healthy tool completion.
Downstream consumers (error classifiers, tool handlers, activity log)
have no way to distinguish a truncated call from a completed one.
Add a malformedArguments: boolean flag to the toolcall_end event variant
in AssistantMessageEvent. The flag is set to true only in the JSON parse
catch path, so existing consumers (which do not check for it) are
unaffected. New consumers like classifyProviderError can use it to
handle truncated tool calls appropriately.
Closes#2574
- Filter toolcall_start/delta/end events from streaming to prevent
out-of-order rendering in the TUI's accumulated message content
- Collect tool calls from intermediate SDK turns and include them
BEFORE text content in the final AssistantMessage
- The agent loop's externalToolExecution path emits proper
tool_execution_start/end events for each intermediate tool call
- Result: tool activity renders above the text response, not below
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds `externalToolExecution` flag to AgentLoopConfig. When true, the
agent loop emits tool_execution_start/end events for TUI rendering but
skips local tool dispatch. Used by providers that handle tool execution
internally (e.g., Claude Code CLI via Agent SDK).
The flag is dynamically evaluated per-loop via a callback on
AgentOptions, so model switches mid-session are handled correctly.
Providers with authMode "externalCli" automatically use this mode.
Also updates the Claude Code CLI stream adapter to preserve tool call
blocks in the final message instead of stripping them.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add pathToClaudeCodeExecutable to SDK query options, resolving the
system `claude` binary via `which claude`. Without this, the SDK
looks for a bundled cli.js that doesn't exist when installed as a
library dependency.
- Remove env option that was replacing the subprocess environment and
stripping auth credentials, causing "Not logged in" errors.
- Update model IDs to current versions: claude-opus-4-6 (1M ctx),
claude-sonnet-4-6 (1M ctx), claude-haiku-4-5 (200K ctx).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implements Phase 1 of the Claude Code subscription-as-provider integration
(issue #2509). Users with a Claude Code subscription (Pro/Max/Team) can
use subsidized inference through GSD's UI via the official Agent SDK.
The extension registers a provider with authMode: "externalCli" that
delegates to the user's locally-installed claude CLI. The SDK runs the
full agentic loop (multi-turn, tool execution) in one streamSimple call.
Tool calls stream in real-time for TUI visibility but are stripped from
the final AssistantMessage so the agent loop ends cleanly without local
tool dispatch.
Zero core changes — pure extension-based implementation.
Closes#2509
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>