github mksglu/context-mode v1.0.105

latest release: v1.0.106
4 hours ago

v1.0.105

A focused stability release: every reported bug from the OpenCode community is fixed, the timeout policy in ctx_execute* no longer murders long-running builds, and the renderer-safe doctor output unblocks Z.ai users.

What's new

OpenCode SessionStart actually works now (PR #376 follow-up — @mikij)

Mickey reported three concrete bugs against the OpenCode plugin path. All three landed in this release.

  • db.getResume() always returned null/undefined. Root cause: we hooked experimental.chat.messages.transform, whose SDK contract is input: {} (no sessionID) and output: { messages: { info, parts }[] }. Our prior output.messages.unshift({ role, content }) was the wrong shape and got silently dropped. Verified against OpenCode source (packages/plugin/src/index.ts:281-295). Fix: pivot to experimental.chat.system.transform (input: { sessionID?, model }, output: { system: string[] }). Snapshots now actually reach the model.
  • sessionStartInjected = true survived only the first session per process. A closure-scope boolean plus a process-global randomUUID() binding meant any plugin process that handled more than one session (i.e. all of them) tripped the flag once and never reset it. Fix: drop randomUUID() entirely; plumb input.sessionID from each hook; gate injection with a Set<string> keyed by sessionID.
  • Snapshot insertion preserves OpenCode's prompt-cache header. OpenCode (packages/opencode/src/session/llm.ts:117-128) saves header = system[0] before the hook fires, then folds [header, body] only when system[0] === header afterwards. We now splice(1, 0, snapshot) instead of unshift, so cache fold survives every resume injection. Without this, every ctx_execute invocation on a resumed OpenCode session would have invalidated the provider prompt cache and 3-5×'d input token cost.

Cross-session resume claim is now race-safe: SessionDB.claimLatestUnconsumedResume() runs a single atomic UPDATE … WHERE id = (SELECT id … LIMIT 1) RETURNING so two concurrent processes for the same project can never both inject the same snapshot.

Z.ai GLM 4.7 → "client is not defined" on ctx_doctor is gone (PR #376 follow-up — @mikij)

Z.ai's MCP renderer mounts a custom React component for GFM task-list syntax (- [x], - [ ], - [-]) that depends on a missing client context, throwing ReferenceError. We refactored ctx_doctor output to plain-text [OK]/[FAIL]/[WARN] prefixes and dropped the ## h2 header. Renderer-safe across every MCP client we've checked.

Long Gradle/Maven/SBT builds no longer get murdered at 30s (Issue #406@wax911)

Maxwell hit a real pain point: the implicit .default(30000) Zod timeout on ctx_execute / ctx_execute_file (and 60_000 on ctx_batch_execute) was killing legitimate Gradle test runs whenever the LLM forgot to pass an explicit value.

We rejected the "add env var defaults + 30-min build floor" approach — server-side timeout policy is the wrong layer when every MCP host already enforces its own RPC timeout. Stacking another policy creates dead config that drifts.

Fix: drop the implicit Zod defaults entirely. When the caller omits timeout, the server fires no kill timer at all — the host's RPC timeout governs (which is the right layer). When the caller passes an explicit value, behaviour is unchanged. Tool descriptions now spell this out so the LLM picks an appropriate timeout for long builds without relying on a magic default.

Bonus: sbt is now redirected alongside gradle/mvn in hooks/core/routing.mjs (it was missing from the regex). Word-boundary guards prevent false positives on substrings like gradle-wrapper-config.

Other changes (came in via #404 / #405)

  • fix(insight): keep directory overrides in source (#404)@mksglu
  • fix: add ps1 extension for Windows PowerShell -File scripts (#405) — community contribution

Tests added

All in existing files per CONTRIBUTING.md L275:

  • tests/session/session-db.test.ts — 4 atomic-claim slices
  • tests/opencode-plugin.test.ts — 5 system.transform behaviour tests (including the cache-fold header preservation regression)
  • tests/core/server.test.ts — Z.ai renderer regression + 2 batch undefined-timeout tests
  • tests/executor.test.ts — 2 no-timeout tests (JS + shell)
  • tests/hooks/core-routing.test.ts — 3 sbt + word-boundary tests

tests/opencode-session-start.test.ts was removed — orphan file that asserted the now-deleted messages.transform hook; coverage moved into tests/opencode-plugin.test.ts.

Validation

Reviewed across 8 parallel sub-agent passes (3 diagnose + 3 grill + 2 architect/14×3-OS validation). All converged on SHIP after the cache-fold splice fix landed.

  • 14 adapter × 3 OS coverage verified
  • 10 hook-paradigm adapters unaffected (chat.system.transform is OpenCode-SDK-only)
  • SQLite 3.53 bundled with better-sqlite3UPDATE … RETURNING works on Windows
  • openclaw + pi paths unchanged — they receive a real session_start event, so the Mickey #2 closure-flag pattern doesn't apply

Contributors

Big thanks to the community catching this round:

  • @mikij — three excellent bug reports against PR #376 with concrete repros, all landed
  • @wax911 — Issue #406 with a fully sketched proposal; we went a different direction but the use case was 100% real
  • #404 / #405 reporters — Windows PowerShell extension fix + insight directory override fix

Upgrade

npm update -g context-mode

Or use the in-product ctx_upgrade MCP tool.

If you hit anything weird, please open an issue with the platform name (Claude Code / Cursor / Codex / OpenCode / etc.), OS, and ctx_doctor output — that triplet covers ~95% of the variance.

Don't miss a new context-mode release

NewReleases is sending notifications on new releases.