Change /^[a-z]+:/i to /^[a-z]{2,}:/i in getWriteGateModuleCandidates()
and getWorkflowExecutorModuleCandidates() so single-letter drive prefixes
(C:, D:) are not rejected as URL schemes. All IANA-registered schemes are
2+ characters, so this is a safe narrowing.
Adds regression tests for the regex fix.
Fixes#3942
Addresses Codex adversarial review findings — the ADR-005 registries
and filters were built but not connected to the actual model selection
and provider adapter paths.
Fix 1+2: Tool filtering applied after model selection
- selectAndApplyModel() now calls adjustToolSet() after pi.setModel()
- Incompatible tools are removed via pi.setActiveTools()
- adjust_tool_set hook fires to allow extension overrides
- Verbose output reports filtered tools with provider context
Fix 3: ProviderSwitchReport wired through all 6 provider adapters
- New transformMessagesWithReport() convenience wrapper creates report,
passes it to transformMessages(), and logs non-empty reports to stderr
when GSD_VERBOSE=1 or PI_VERBOSE=1
- All adapters updated: anthropic, google, openai-responses,
openai-completions, mistral, bedrock
- 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
Helps users understand that 'anthropic-api' makes direct API calls (requires
API key / extra usage) while 'claude-code' routes through the local CLI
(uses subscription).
Two bugs prevented subscription users from routing through Claude Code CLI:
1. Retry handler regex only matched "third-party" errors but actual error is
"You're out of extra usage" — fallback never triggered
2. auto-model-selection actively rerouted bare model IDs back to anthropic
even after startup migration set claude-code as the session provider
Verify claude-code fallback only fires for anthropic provider and
does not reroute non-anthropic providers on similar error text.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Prevent _tryClaudeCodeFallback from firing for non-Anthropic providers
that may produce similar error text, avoiding unintended provider drift.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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
PR #3744 and #3765 introduced contentCursorRow which diverges from the
actual terminal cursor position after IME repositioning. computeLineDiff
computes ANSI escape movements which are relative to where the cursor
physically is — that must be hardwareCursorRow, not a phantom position.
Remove contentCursorRow entirely and revert computeLineDiff baseline to
hardwareCursorRow. The ghost-line test was asserting wrong movement
direction (UP from phantom position vs DOWN from actual cursor).
Closes#3764
PR #3744 fixed autocomplete ghost lines by introducing a local
contentCursorRow initialized from this.cursorRow, but this.cursorRow
tracks the content end (last line), not where the cursor actually
ended up after rendering. This caused computeLineDiff to compute
wrong movement deltas, making content clear and jump on every keystroke.
Fix: add an instance field contentCursorRow that stores finalCursorRow
after content rendering but before positionHardwareCursor moves the
cursor for IME. This correctly separates three cursor concepts:
- cursorRow: logical content end (viewport calculation)
- contentCursorRow: post-render cursor position (movement baseline)
- hardwareCursorRow: actual terminal cursor (may differ due to IME)
Closes#3764
Use the rendered content row as the shrink diff baseline instead of\nreusing the IME hardware cursor row. Add a focused TUI regression test\nthat reproduces the ghost-line cleanup path when autocomplete shrinks.\n\nCloses #3721