* fix: align @gsd/native module type with compiled output (#2861)
The package declared "type": "module" and used "import"-only export
conditions, but the addon loader used import.meta.url which is
incompatible when the parent package enforces ESM resolution on
Node.js v24. Switch to "type": "commonjs" with "default" export
conditions and remove the import.meta.url/__dirname shim (CJS
provides both natively).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: restore dual CJS/ESM compat for native addon loader
The ESM-to-CJS conversion removed import.meta.url polyfills, but the CI
test loader (dist-redirect.mjs) transpiles this file to ESM via
ts.transpileModule — making __dirname and require unavailable at test time.
Add runtime typeof guards that use the CJS globals when available (compiled
output) and fall back to import.meta.url in ESM (test runner). Use
@ts-expect-error to suppress TS1470 for the import.meta branches that are
unreachable in the compiled CJS output.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use indirect eval for import.meta.url to avoid CJS parse-time error
import.meta is a parse-time syntax error in CJS — typeof guards don't
help because Node.js rejects the syntax before executing any code.
Wrapping in new Function("return import.meta.url") hides the syntax
from the CJS parser while still working when executed as ESM (test runner).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: replace new Function(import.meta.url) with loader-injected CJS globals
import.meta is static syntax unavailable in new Function() and eval()
scopes, causing rtk-portability CI failures across all platforms.
Instead of trying to access import.meta.url indirectly, the test loader
(dist-redirect.mjs) now injects __dirname, __filename, and require as a
preamble when transpiling workspace packages to ESM. This lets native.ts
use __dirname/require directly in both CJS (production) and ESM (CI test)
contexts without any import.meta.url fallback.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Map pause_turn to "pauseTurn" instead of "stop" so the agent loop
continues when Anthropic's server pauses a long-running turn (e.g.
native web search hitting its iteration limit). Previously the
incomplete server_tool_use block was saved to history, causing a
400 invalid_request_error on the next API call.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The "Extra usage is required for long context requests" error from
Anthropic is a billing gate, not a transient rate limit. Classify it as
quota_exhausted so the handler enters the fallback path instead of an
infinite backoff loop. When no cross-provider fallback exists, attempt a
[1m] to base model downgrade before stopping cleanly.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
When gsd is spawned as an RPC bridge child process, stdout is a pipe
(process.stdout.isTTY === undefined). The TUI render loop would run at
~4,600 renders/sec writing ANSI escape codes to the pipe, consuming
500%+ CPU per process while idle.
Add isTTY guard to Terminal interface, ProcessTerminal.start(), TUI.start(),
and requestRender() so the entire render pipeline is skipped on non-TTY stdout.
RemoteTerminal (browser-backed) correctly reports isTTY=true.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Saves in-progress daemon work from M005-m138xe that was sitting uncommitted.
Includes orchestrator expansion, event bridge/formatter enhancements,
message batcher tweaks, and discord bot additions.
Tests cover: provider registration, base URL + API type, reasoning +
context window specs, and non-collision with generated zai models.
Required by CI lint gate (require-tests.sh).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
GLM-5.1 is the latest Zhipu AI model with 204K context window and
131K max output tokens. It uses the Z.AI Coding Plan endpoint
(OpenAI-compatible) and supports reasoning via enable_thinking.
Not yet tracked by models.dev, so added to models.custom.ts alongside
existing alibaba-coding-plan entries. Merges additively with the
generated Z.AI provider (glm-5, glm-5-turbo, etc.).
Specs from https://docs.z.ai/devpack/using5.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: Migrated headless orchestrator to use execution_complete events,…
- "src/headless.ts"
- "src/headless-ui.ts"
- "src/tests/headless-v2-migration.test.ts"
GSD-Task: S06/T02
* test: Wired pi-coding-agent to re-export JSONL utils from @gsd/rpc-clie…
- "packages/pi-coding-agent/src/modes/rpc/jsonl.ts"
- "packages/pi-coding-agent/package.json"
- "packages/rpc-client/src/index.ts"
- "packages/rpc-client/src/jsonl.ts"
- "packages/rpc-client/src/rpc-client.ts"
- "packages/rpc-client/src/rpc-types.ts"
- "packages/rpc-client/src/rpc-client.test.ts"
- "packages/rpc-client/package.json"
GSD-Task: S06/T03
* feat: Wire --resume flag to resolve session IDs via prefix matching and…
- "src/headless.ts"
- "dist/headless.js"
GSD-Task: S01/T01
* test: Added 5 e2e integration tests proving headless JSON batch, SIGINT…
- "src/tests/integration/e2e-headless.test.ts"
GSD-Task: S01/T02
* test: Updated @gsd/rpc-client and @gsd/mcp-server to 2.52.0 with publis…
- "packages/rpc-client/package.json"
- "packages/mcp-server/package.json"
- "packages/rpc-client/.npmignore"
- "packages/mcp-server/.npmignore"
GSD-Task: S02/T01
* chore: auto-commit after complete-milestone
GSD-Unit: M002-gzq23a
* fix: revert jsonl.ts to inline implementation — @gsd-build/rpc-client not available at source-level test time in CI
The re-export from @gsd-build/rpc-client fails in CI because tests run against
TypeScript source (--experimental-strip-types) before any build step. The npm
dependency resolves to node_modules/ which requires dist/ to exist. Reverting
to the original inline implementation eliminates the cross-package dependency
for source-level imports.
The re-export from @gsd-build/rpc-client fails in CI because tests run against
TypeScript source (--experimental-strip-types) before any build step. The npm
dependency resolves to node_modules/ which requires dist/ to exist. Reverting
to the original inline implementation eliminates the cross-package dependency
for source-level imports.
* refactor(pi-ai): replace model-ID pattern matching with capability metadata
Add ModelCapabilities to Model<TApi> and a CAPABILITY_PATCHES mechanism
so call sites read model.capabilities fields instead of parsing model IDs
or hardcoding provider names.
- types.ts: add ModelCapabilities interface (supportsXhigh, requiresToolCallId,
supportsServiceTier, charsPerToken) and capabilities?: ModelCapabilities to
Model<TApi>
- models.ts: add CAPABILITY_PATCHES table applied at registry init; patches
declare GPT-5.x and Opus 4.6 capabilities once instead of repeating ID
checks at every call site; supportsXhigh() now reads capabilities only
- service-tier.ts: extract SERVICE_TIER_MODEL_PREFIXES constant so the gating
list has a single named home; add path comment pointing to issue #2546 for
the full capability-driven follow-up
No behaviour change. New models and providers can declare capabilities in
their model definitions without touching function logic.
Closes#2546
* fix(pi-ai): apply capability patches to custom/discovered/extension models
Models constructed outside the static pi-ai registry (custom models
from models.json, extension-registered models, discovered models)
bypassed CAPABILITY_PATCHES — causing supportsXhigh() to silently
return false for GPT-5.x or Opus 4.6 variants registered through
those paths.
Export applyCapabilityPatches() from pi-ai and call it in ModelRegistry
after model assembly in all three construction paths: loadModels(),
applyProviderConfig(), and discoverModels().
Add regression tests covering patching, precedence, idempotency,
and synthetic models that mimic the custom/extension path.
Closes#2546
On Windows, `spawn()` with `detached: true` sets the
CREATE_NEW_PROCESS_GROUP flag in CreateProcess. In certain terminal
contexts — notably VSCode's integrated terminal (ConPTY), Windows
Terminal, and some MSYS2/Git Bash configurations — this flag conflicts
with the parent process group hierarchy and causes a synchronous EINVAL
from libuv, making *every* bash/async_bash/bg_shell command fail
immediately with `spawn EINVAL`.
The bg-shell extension already guards against this with
`detached: process.platform !== "win32"` (process-manager.ts:109),
but three other spawn sites were missed:
- `packages/pi-coding-agent/src/core/tools/bash.ts` (bash tool)
- `packages/pi-coding-agent/src/core/bash-executor.ts` (RPC executor)
- `src/resources/extensions/async-jobs/async-bash-tool.ts` (async_bash)
This commit aligns all spawn sites with the bg-shell pattern.
Additionally fixes two related issues:
1. `killProcessTree()` in shell.ts used `detached: true` on its own
`taskkill` spawn call — unnecessary and potentially problematic
in the same terminal contexts. Removed.
2. `killTree()` in async-bash-tool.ts used Unix-only
`process.kill(-pid)` with no Windows fallback. On Windows, negative
PIDs (process group kill) are not supported, so orphaned child
processes could survive timeout kills. Now uses `taskkill /F /T`
on Windows, matching the bg-shell and shell.ts implementations.
Includes a regression test that statically verifies no spawn site
uses unconditional `detached: true`, plus a smoke test confirming
the platform-guarded pattern works on all platforms.
Reproduction: Run GSD v2.42-v2.51 inside VSCode on Windows 11 with
Git Bash as the shell. Any bash tool call fails with `spawn EINVAL`.
The error is 100% reproducible and affects all shell operations
(bash, async_bash, bg_shell start).
Co-authored-by: Matt Haynes <matt@auroraventures.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The webSearchResult branch deleted entries from pendingTools after rendering,
which removed the duplicate-prevention guard. Subsequent streaming tokens
re-iterated content blocks, re-created the serverToolUse component, and
re-rendered the search result — producing 18+ duplicate blocks.
The message_end handler already calls pendingTools.clear(), so the explicit
deletes were unnecessary and harmful.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>