Commit graph

539 commits

Author SHA1 Message Date
Claude
1be15758ec fix(mcp): thread abort signals, restore tool fidelity, and fix subpath imports
Audit-driven fixes across the two MCP server surfaces and the Claude Code
streaming adapter:

- src/mcp-server.ts: propagate `extra.signal` into `tool.execute` so MCP
  clients can actually cancel long-running Bash/WebFetch/grep calls, and
  route the remaining `/server` subpath import through `createRequire`
  for #3603 consistency.
- src/tests/mcp-createRequire.test.ts: extend regression coverage to the
  `/server` subpath.
- claude-code-cli/stream-adapter.ts: (a) classify aborts as `aborted`
  instead of the retry-eligible `stream_exhausted_without_result`,
  (b) merge final-turn toolCall blocks from the builder into the
  AssistantMessage via the new `mergePendingToolCalls` helper so a turn
  ending in `tool_use` stop_reason no longer drops its tool calls, and
  (c) resolve the SDK permission mode via `resolveClaudePermissionMode`
  (auto-mode → bypass, interactive → acceptEdits, env override).
- packages/mcp-server/src/server.ts: make `gsd_query` actually respect
  its `query` argument with known categories + forward-compatible
  fallback, and thread `extra.signal` into `gsd_execute` so an aborted
  RPC request cancels the newly-created session instead of leaking a
  background RpcClient process.
- stream-adapter test suite: add regression tests for abort
  classification, final-turn tool-call merging, and permission mode
  resolution.

Verified via: mcp-createRequire, stream-adapter (27), partial-builder,
mcp-server package (31), workflow-tools (13) — 83 tests green.

https://claude.ai/code/session_0174sYny3VvdwYTdCNTmY4Do
2026-04-12 20:04:47 -05:00
Claude
701ab18d81 fix(models): block unconfigured models from selection surfaces
Filter models whose provider has no working API key or OAuth out of
every user-facing selection path. Previously, stale defaults and scoped
sets could leak unconfigured models into /model, /gsd model, and auto
run — the user could "pick" a model that immediately threw on use.

- model-selector: filter scopedModels via isProviderRequestReady;
  default to "all" scope when no scoped model is ready.
- model-controller: same filter for getModelCandidates, so exact-match
  resolution from /model <term> can't return an unauth'd scoped model.
- model-resolver: gate findInitialModel step 3 on provider readiness so
  a stale saved default falls through to the available-models path.
- startup-model-validation: check configuredExists against getAvailable
  instead of getAll, so a configured-but-unauth default triggers the
  fallback picker and thinking-level reset.
- auto-start: validate resolveDefaultSessionModel against the live
  registry + auth before snapshotting, and warn when PREFERENCES.md
  names an unconfigured model.

https://claude.ai/code/session_015q6b23ap9Pyqdogzz2FXGh
2026-04-12 17:25:06 -05:00
Jeremy McSpadden
c3aa3a3bf0 Merge pull request #4067 from jeremymcs/fix/gsd-model-session-override 2026-04-12 12:50:12 -05:00
Jeremy McSpadden
17e3ef6a28 Merge pull request #4064 from mastertyko/fix/3402-full-oauth-login-url
fix(pi-coding-agent): show full OAuth login URLs
2026-04-12 12:26:25 -05:00
Jeremy
c96d01acb7 fix(model): require provider readiness for saved default selection 2026-04-12 12:24:49 -05:00
mastertyko
f15938ea4c fix(pi-coding-agent): show full OAuth login URLs 2026-04-12 18:45:28 +02:00
Jeremy McSpadden
564a71da37 Merge pull request #4053 from jeremymcs/fix/auto-session-credential-cooldown
fix(auto): survive transient 429 credential cooldown
2026-04-12 09:42:37 -05:00
Jeremy
4f2e90e1e8 test(auto): add tests for credential cooldown fix
- auth-storage.test.ts: 8 tests for getEarliestBackoffExpiry()
- sdk.test.ts: 12 tests for CredentialCooldownError class
- infra-errors-cooldown.test.ts: 35 tests for isTransientCooldownError(),
  getCooldownRetryAfterMs(), and exported constants

Required by CI lint (require-tests.sh) per CONTRIBUTING.md.

Closes #4052
2026-04-12 09:30:52 -05:00
Jeremy
d0afe018eb fix(auto): add structured cooldown error and bounded retry budget
Address Codex adversarial review findings:

- Replace string-matched cooldown detection with typed
  CredentialCooldownError (code: AUTH_COOLDOWN, retryAfterMs)
- Add MAX_COOLDOWN_RETRIES (5) cap so cooldown retries can't spin for
  hours on persistent quota exhaustion
- Auto-loop uses retryAfterMs from structured error when available,
  falls back to 35s default
- Export CredentialCooldownError from pi-coding-agent package
- Retain regex fallback for cross-process error propagation

Closes #4052
2026-04-12 09:16:05 -05:00
Jeremy
cd86e8a7d0 feat(tui): improve gsd overlays, shortcuts, and notification flows 2026-04-12 09:13:46 -05:00
Jeremy
1ae93e9822 fix(auto): survive transient 429 credential cooldown in auto sessions
getApiKey() retry loop (3 attempts, ~12s) couldn't outlast the 30s
rate-limit backoff window, causing cooldown errors to cascade through
the auto-loop and trigger a hard stop after 3 consecutive failures.

- Add AuthStorage.getEarliestBackoffExpiry() to expose when the next
  credential becomes available
- Update getApiKey() to sleep until backoff expiry (up to 60s) instead
  of fixed 2s/4s/6s delays
- Add isTransientCooldownError() detector in infra-errors.ts
- Auto-loop now waits 35s on cooldown errors without incrementing the
  consecutive error counter

Closes #4052
2026-04-12 09:04:41 -05:00
Jeremy McSpadden
b22f7baafb Merge pull request #4043 from mastertyko/fix/3783-minimax-bearer-auth
fix(pi-ai): use bearer auth for MiniMax Anthropic API
2026-04-12 09:03:11 -05:00
mastertyko
d2ed5a91a6 fix(pi-coding-agent): match renderable tools case-insensitively 2026-04-12 14:05:30 +02:00
mastertyko
739f6ca51c fix(pi-ai): use bearer auth for MiniMax Anthropic API 2026-04-12 14:02:07 +02:00
Jeremy
4b69e44a42 merge: resolve upstream/main conflicts for PR #3177 2026-04-11 22:59:58 -05:00
Jeremy McSpadden
56ee5616a5 Merge pull request #3984 from mastertyko/fix/3973-mcp-inline-db-open
fix(mcp-server): open the DB for inline workflow tools
2026-04-11 22:52:52 -05:00
github-actions[bot]
cf6f0613dd release: v2.71.0 2026-04-11 23:19:57 +00:00
Jeremy
b488961609 fix(tui): clear pinned output on message_end to prevent duplicate display
The pinned "Latest Output" zone was only cleared at agent_end, but during
flows with form elicitation (e.g. discuss-phase), there is a gap between
message_end and agent_end where the agent waits for user input. During this
gap, the same content was visible in both the chat history and the pinned
zone. Clear the pinned zone at message_end when the assistant message is
finalized in the chat container.
2026-04-11 17:41:50 -05:00
Jeremy
5531538e0d fix(tui): clear pinned latest output on turn completion 2026-04-11 16:58:48 -05:00
Git-Scram
1d1e47e78b fix(tui): restore pinned output above editor during tool execution
Restores the pinned assistant output zone that shows the latest narration
during tool execution. Adds markdown rendering, animated spinner, height
capping to prevent render flashing, and session rebuild support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 15:53:29 -04:00
Jeremy
2d531720f7 fix(tui): mask secure extension input values in interactive mode 2026-04-11 13:28:17 -05:00
Jeremy
bf4bcfadde fix(claude-code): harden MCP elicitation schema handling 2026-04-11 13:26:24 -05:00
Jeremy
1495e711e1 fix(claude-code): accept secure_env_collect MCP elicitation forms 2026-04-11 13:18:27 -05:00
Jeremy
74fee9ed48 fix(interactive): keep MCP tool output ordered and restore secure prompt fallback 2026-04-11 12:47:41 -05:00
Jeremy
ea506f66c8 feat(mcp-server): add secure_env_collect tool via MCP form elicitation
Exposes secure_env_collect as an MCP tool so any MCP client (Claude Code,
Cursor, etc.) can collect secrets through form-based input. Values are
written directly to .env/Vercel/Convex and never appear in LLM context —
only key names and applied/skipped status are returned.

- New env-writer.ts with writeEnvKey, detectDestination, checkExistingEnvKeys, applySecrets
- Uses server.server.elicitInput() to present form fields to the MCP client
- Pre-checks existing keys to skip already-set env vars
- Auto-detects destination from project files (vercel.json, convex/ dir)
- 27 tests covering utilities and tool integration

Closes #3975
2026-04-11 11:51:43 -05:00
Jeremy McSpadden
5d48038816 Merge pull request #3992 from jeremymcs/fix/mcp-output-stream-order
fix(interactive): preserve MCP tool output stream ordering
2026-04-11 11:46:23 -05:00
Jeremy
ba6c1f5d7e test(interactive): cover MCP tool output ordering in chat controller 2026-04-11 11:32:28 -05:00
Jeremy
58d729894e fix(interactive): preserve MCP tool output stream ordering 2026-04-11 11:26:08 -05:00
mastertyko
4ad2379dc5 fix(mcp-server): open the DB for inline workflow tools 2026-04-11 17:44:17 +02:00
github-actions[bot]
26696be2fa release: v2.70.1 2026-04-11 04:22:31 +00:00
Jeremy McSpadden
19cbb17683 Merge pull request #3961 from jeremymcs/fix/windows-portability-sweep
fix: harden Windows portability across runtime and tooling
2026-04-10 21:53:10 -05:00
Jeremy
61204ce771 fix(windows): harden portability across runtime and tooling 2026-04-10 20:33:18 -05:00
Jeremy McSpadden
9a7453fae8 Merge pull request #3957 from jeremymcs/fix/mcp-importLocalModule-paths
fix(mcp-server): importLocalModule resolves src/ paths from dist/ context
2026-04-10 19:54:00 -05:00
Jeremy McSpadden
37fa5168a9 Merge pull request #3956 from jeremymcs/fix/claude-code-structured-questions-fallback
[codex] fix Claude Code discuss structured-question fallback
2026-04-10 19:44:45 -05:00
Jeremy
67767c2527 test(mcp-server): add regression tests for importLocalModule candidate resolution
Extracts _buildImportCandidates() as a testable export and adds 5 tests
verifying src/<->dist/ path swapping and .ts extension fallback logic.

Refs #3954
2026-04-10 19:33:00 -05:00
Jeremy
d64056f833 fix claude code mcp elicitation bridge 2026-04-10 19:24:51 -05:00
Jeremy
ad8405c372 fix(mcp-server): importLocalModule resolves src/ paths from dist/ context
importLocalModule() resolved paths relative to import.meta.url. When
running from dist/, paths like ../../../src/.../foo.js pointed to source
where no .js files exist. Now tries src/<->dist/ swap and .ts fallback
so the same code works in both dev (tsx) and prod (compiled) contexts.

Also adds dist/ candidates to write-gate and workflow-executor lookups.

Fixes #3954
2026-04-10 19:22:52 -05:00
github-actions[bot]
4b671fba0f release: v2.70.0 2026-04-10 23:12:12 +00:00
Jeremy McSpadden
afe0574a23 Merge pull request #3953 from jeremymcs/fix/remove-anthropic-oauth 2026-04-10 17:52:59 -05:00
Jeremy
7ee1fa0c46 fix(pi-ai): remove Anthropic OAuth flow for TOS compliance
Delete the Anthropic OAuth module, remove it from the built-in provider
registry, strip the OAuth client branch from the Anthropic streaming
provider, and replace the daemon orchestrator's token refresh with a
simple ANTHROPIC_API_KEY requirement.

Anthropic access is now API key or local Claude Code CLI only.

Closes #3952
2026-04-10 17:33:34 -05:00
Jeremy
f350647863 fix(mcp-server): hydrate model credentials into env 2026-04-10 17:31:07 -05:00
Jeremy
f886cf01c2 fix(mcp-server): hydrate stored tool credentials on startup 2026-04-10 17:24:50 -05:00
Jeremy McSpadden
0575d2cb58 Merge pull request #3946 from jeremymcs/feat/mcp-ask-user-questions-elicitation
feat(mcp-server): expose ask_user_questions via elicitation
2026-04-10 16:58:34 -05:00
Jeremy
b3275a182d feat(mcp-server): expose ask_user_questions via elicitation 2026-04-10 15:44:08 -05:00
Jeremy McSpadden
c0f101a217 Merge pull request #3943 from Git-Scram/fix/mcp-windows-drive-letter-regex
fix(mcp-server): URL scheme regex matches Windows drive letters
2026-04-10 15:17:59 -05:00
github-actions[bot]
00107d2775 release: v2.69.0 2026-04-10 20:00:49 +00:00
jeremymcs
9b853ce960 fix(mcp-server): URL scheme regex no longer matches Windows drive letters
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
2026-04-10 15:20:39 -04:00
Jeremy
2ad315b9fb fix(gsd): wire ADR-005 infrastructure into live paths
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
2026-04-10 12:49:49 -05:00
Jeremy
b1c0dafc70 feat(gsd): implement ADR-005 multi-model provider and tool strategy
Implements all 4 phases of ADR-005 (issue #2790):

Phase 1: Provider Capabilities Registry
- Declarative ProviderCapabilities interface and PROVIDER_CAPABILITIES
  registry covering all 12 API providers
- Consolidates scattered *-shared.ts knowledge into queryable registry
- Unknown providers get permissive defaults (backward compatible)

Phase 2: Tool Compatibility Metadata
- ToolCompatibility interface (producesImages, schemaFeatures, minCapabilityTier)
- compatibility field on ToolDefinition
- Tool compatibility registry with pre-populated built-in tools
- Auto-registration from registerTool() and MCP tool defaults

Phase 3: Tool-Compat Filter + ProviderSwitchReport
- ProviderSwitchReport tracks thinking blocks dropped/downgraded,
  tool call IDs remapped, synthetic results inserted, thought
  signatures dropped during cross-provider message transformation
- isToolCompatibleWithProvider(), filterToolsForProvider(), adjustToolSet()
  functions in model router
- filteredTools field on RoutingDecision
- Verbose output for filtered tools in auto-model-selection

Phase 4: adjustToolSet Extension Hook
- AdjustToolSetEvent and AdjustToolSetResult interfaces
- emitAdjustToolSet() on ExtensionAPI and ExtensionRuntime
- Default no-op handler in register-hooks.ts

Includes 47 new tests (20 provider caps + 10 switch report + 17 tool compat)

Closes #2790
2026-04-10 12:33:40 -05:00
github-actions[bot]
61ea410e33 release: v2.68.1 2026-04-10 15:59:03 +00:00