github mksglu/context-mode v1.0.144

2 hours ago

v1.0.144

Three independent fixes, each surgical, each preserving the rest of the system.

Fixes

Pi MCP bridge no longer kills slow tools/call at 120s (#643). The bridge's hardcoded DEFAULT_CALL_TIMEOUT_MS = 120_000 was firing on legitimate long-running ctx_execute calls — test suites (2-5 min), npm run build, cargo test, go test ./.... The 120s value was arbitrary (commit #472), never pinned by tests, and the bridge had nothing useful to do with the bound: a hung subprocess is detected via stdio close, a crashed subprocess via exit code, and a fetch-bound hang owns its own HTTP timeout one layer down. The bound was bridge-layer overreach into execution-layer concerns.

Reporter proposed CTX_BRIDGE_CALL_TIMEOUT_MS env var; we removed the timeout entirely instead. Rationale: env vars are operational noise (every flag = user complexity), and the bug class is owned by the executor where timeout is already a per-call knob. DEFAULT_REQUEST_TIMEOUT_MS = 60_000 for initialize / tools/list is preserved — those are bootstrap, hang means real failure. Implementation gates setTimeout on Number.isFinite(timeoutMs) (Node coerces undefined and Infinity to 1ms timer, so we explicitly skip the timer). Closes #643.

OpenCode plugin no longer surfaces -32601 Method not found when suppression is active (#637). v1.0.140 added emitSuppressionDiagnostic to suppress duplicate MCP tools when both plugin: ["context-mode"] AND legacy mcp.context-mode are present in opencode.json — correct architectural call. But the SDK only installs its tools/list handler when at least one registerTool() reaches setToolRequestHandlers() — the suppression shim short-circuits every registration, so the handler was never installed. Result: the suppressed legacy MCP child responded to tools/list with -32601 instead of {tools: []}. Users saw the error, concluded "broken plugin", filed #637.

Fix: new registerEmptyToolsListHandler(server) registers a spec-compliant {tools: []} response for ListToolsRequestSchema when suppression is active. The existing #623 stderr diagnostic still fires alongside. Users now get correct JSON-RPC behavior + clear ownership message. Closes #637.

PreToolUse hook handles paths with spaces (#636). hooks/pretooluse.mjs:130 was building hook commands via string concatenation ("node " + resolve(targetDir, ...)) — unquoted. When targetDir lives under Dropbox/iCloud-style spaced paths ("Lucas Werneck", "My Projects"), /bin/sh -c word-split at hook-spawn time, producing the reporter's "Failed with non-blocking status code" spam.

Fix: one-line JSON.stringify(scriptPath) for proper quoting. POSIX affected (macOS, Linux, WSL); Windows already immune via separate hooks/normalize-hooks.mjs path. The legacy branch only fires when hooks/hooks.json is absent in the plugin cache (pre-v1.0.108 upgrade path). Closes #636.

Tests

  • 2 new tests in existing tests/adapters/pi-mcp-bridge.test.ts (#643): tools/call no-timeout + initialize-still-bounded regression guard
  • 1 new test in existing tests/core/server.test.ts (#637): InMemoryTransport probes tools/list returns {tools: []} under suppression
  • 2 new tests in existing tests/hooks/integration.test.ts (#636): spaced-path word-split assertion + RED-baseline doc

All slotted per CONTRIBUTING L275 — no new test files. Full suite preserves baseline.

Compatibility

15 adapters, 3 OS. No schema migration. engines.node >= 22.5.0 preserved.

Upgrade

npm install -g context-mode@latest
# Restart Claude Code / OpenCode / Pi (Cmd+Q + reopen)

Credits

  • Reporter who flagged #643 with concrete pain points (test suites, builds) — your env-var proposal was the right framing of the wrong fix; we took the bridge-layering insight from your alternatives section
  • Reporter who flagged #637 — the perception bug was real even though the headline claim was wrong; your timing nudged us to wire the spec-compliant fallback
  • Reporter who flagged #636 with reproducer environment matching Dropbox/iCloud spaced-path patterns

Don't miss a new context-mode release

NewReleases is sending notifications on new releases.