v1.0.125
Closes 3 community-reported issues (Codex broken on every load, Node 26 V8 ABI break on macOS, verbose flag carve-out leak) and merges 2 contributed PRs (C# runtime, Windows space-in-path quote fix) with security follow-ups. All 5 fixes verified against refs/ upstream sources — no LLM hallucinations.
What broke
#547 — Codex regex parser rejects bundled hooks/hooks.json with lookaround
@ivkiwi reported: mcp__(?!plugin_context-mode_) in ~/.codex/plugins/cache/context-mode/context-mode/1.0.124/hooks/hooks.json triggers Codex error "look-around, including look-ahead and look-behind, is not supported". Verified against refs/platforms/codex/codex-rs/hooks/Cargo.toml — Codex uses the Rust regex crate, which deliberately omits lookaround. Every Codex user on v1.0.124 was broken at boot.
The deeper insight (from refs/platforms/codex/codex-rs/hooks/src/events/common.rs:152): Codex has an is_exact_matcher short-circuit — when a matcher contains ONLY [A-Za-z0-9_|], regex compilation is skipped entirely. This subset works on every engine (Codex Rust, Claude Code JS, Cursor JS, Kiro JS, Gemini, qwen, copilot) — pipe-separated literal names are universal.
Fix:
hooks/hooks.json(universal bundled file Codex loads from plugin cache):mcp__(?!plugin_context-mode_)→mcp__simple prefix. Claude Code treats it as substring match, fires for every external MCP tool. Hook body'sisExternalMcpTool()filter (PR #532) does the actual "skip our own" decision — semantics preserved, no lookaround.configs/codex/hooks.json+src/adapters/codex/{hooks,index}.ts: same rewrite. Matcher passesis_exact_matcher, zero engine variance.- Drift-guard test in
tests/adapters/codex.test.tsasserts Codex matchers stay in the[A-Za-z0-9_|]charset forever.
#551 — Node 26 V8 ABI break crashes better-sqlite3 compile on macOS
@debop reported staff-grade: Node 26.0.0 (NODE_MODULE_VERSION 147) removed v8::PropertyCallbackInfo::This(). better-sqlite3@12.9.0 uses it → compile fails on macOS arm64. They cited the exact bundle code: src/db-base.ts gates node:sqlite selection on process.platform === "linux" only, even though node:sqlite (DatabaseSync) has been stable since Node 22.5 on every platform.
Fix: extend the gate from Linux-only to hasModernSqlite() (Bun OR Node ≥22.5 on any OS). The helper existed in hooks/ensure-deps.mjs; now exported from src/db-base.ts too. macOS + Node 26 users get the built-in node:sqlite adapter — no native compile, no V8 ABI exposure. Windows + Node ≥22.5 users get the same improvement. Pre-Node-22.5 environments continue to use better-sqlite3 if compile succeeds, then WASM if not.
This is the architectural direction the v1.0.124 #544 review surfaced — making SQLite a graceful-degradation problem instead of a hard install gate. v1.0.125 is the first step.
#517 — cp/mv/rm/ln verbose carve-out leaks on flag bundles where v isn't last
@rpickmans found that (?!\s+-[a-zA-Z]*v\b) requires v to be the LAST alpha char in the bundle. Flag combos like cp -rvi, mv -vfr, rm -rvf, ln -vs, ln -vfs, ln -sfvr slip past the carve-out and silently run, flooding the user's context with verbose output.
Verified the systemic defect lives in all four lines (hooks/core/routing.mjs:188-193) — not just ln. Fix: replace \b anchor with [a-zA-Z]* so v is caught anywhere in the flag group. Test cases for cp/mv/rm/ln added to tests/core/routing.test.ts.
PR #546 — C# (csharp) runtime via dotnet-script (by @jordancarney1)
Adds the 12th polyglot runtime. ctx_execute(language: "csharp") and ctx_execute_file(..., language: "csharp") now run .csx scripts via dotnet-script. Mirrors the existing Ruby/Perl/Elixir wiring exactly. PR contained 6 DOTNET_* env strips already.
Security follow-up landed in v1.0.125: the security review (cited against learn.microsoft.com/en-us/dotnet/core/runtime-config/debugging-profiling) identified DLL/IPC injection vectors the PR missed. v1.0.125 extends the denylist with:
CORECLR_PROFILER+CORECLR_PROFILER_PATH(+_32,_64,_ARM32,_ARM64variants) — load arbitrary native DLL into the dotnet host (stronger thanDOTNET_STARTUP_HOOKS)DOTNET_PROFILER_PATH(+ same arch variants) — cross-plat aliasCORECLR_ENABLE_PROFILING— gates profiler loadDOTNET_DiagnosticPorts— peer process can attach debugger / dump memory / inject IL via diagnostic IPCDOTNET_BUNDLE_EXTRACT_BASE_DIR— single-file extraction directory hijack^COMPlus_/iprefix regex sweep — everyDOTNET_*knob has aCOMPlus_*back-compat synonym (per Microsoft docs: ".NET Framework runtime configuration uses theCOMPlus_prefix"). Stripping onlyDOTNET_*left the aliases live.
Docs across README.md, CONTRIBUTING.md, BENCHMARK.md, docs/llms-full.txt, llms-full.txt bumped from "11 languages" to "12".
PR #549 — claude-code adapter quotes pluginRoot in generated hook commands (by @jstan2525)
Windows users with spaces in %USERPROFILE% (e.g. C:\Users\High Ground Services) saw ctx_doctor report all 5 hook scripts as FAIL at a doubled path. Diagnosis verified empirically: extractHookScriptPath in src/util/hook-config.ts:24 falls through to \S+\.mjs when commands aren't quoted, grabbing only the tail-after-last-space. PR wraps each ${pluginRoot}/hooks/<name>.mjs in double quotes — surgical fix, includes regression test in tests/adapters/claude-code.test.ts.
15-adapter audit (per MUST-3): only claude-code had this defect. The other 14 hook-emitting adapters already route through buildNodeCommand (src/adapters/types.ts:332) which double-quotes both nodePath and scriptPath. Future architectural cleanup: migrate claude-code/index.ts to buildNodeCommand to prevent drift (tracked separately, not blocking).
Tests
- 3183 pass · 8 pre-existing baseline failures (OpenCodeAdapter config-paths — verified present on
origin/nextat v1.0.124, unrelated) - 6 new tests for Codex
is_exact_matcherdrift-guard - 1 new test file (
tests/util/db-base-platform-gate.test.ts) for #551 cross-platform gate - 138 new test lines in
tests/executor.test.tsfor C# runtime + DOTNET env strips - 71 new test lines for cp/mv/rm/ln carve-out edge cases
Compatibility
15 adapters / 3 OS. No interface changes. Per-adapter migration:
| Adapter | Effect |
|---|---|
| codex | #547 fixed — bundled hook matchers now pass is_exact_matcher; Codex loads cleanly
|
| claude-code | #549 fixed for Windows space-in-path; mcp__ literal matcher = same routing via hook body filter
|
| All other 13 adapters | Zero change |
csharp is opt-in: if dotnet-script isn't installed, ctx_execute(language: "csharp") returns the install hint (dotnet tool install -g dotnet-script).
Upgrade
npm install -g context-mode@latest
# inside Claude Code / Codex / etc:
/ctx-upgrade
# restart your sessionCodex users on v1.0.124: the upgrade fixes the regex matcher in both ~/.codex/hooks.json (regenerated by upgrade) AND the bundled plugin-cache hooks/hooks.json (replaced by new tarball). No manual cleanup needed.
macOS users on Node 26 hitting better-sqlite3 compile errors: the upgrade switches you to node:sqlite automatically. /ctx-doctor should report FTS5 / SQLite: PASS — native module works (it's actually the built-in node:sqlite, but the message is shared).
Thanks
@ivkiwi for the staff-grade #547 diagnosis (cited the exact Codex regex error, the bundled file path, the local fix, the architectural insight that the plugin-cache file is ALSO loaded by Codex). @debop for the #551 root-cause report with the exact V8 API line, the diff workaround, and the suggested fix already implemented in hasModernSqlite(). @rpickmans for the #517 regex follow-up that exposed a systemic defect across cp/mv/rm/ln, not just ln. @jordancarney1 for PR #546 (C# runtime) — security review extended the env strip, not because the PR was wrong, but because Microsoft's runtime-hijack surface is wider than commonly documented. @jstan2525 for PR #549 (Windows quote fix) — precise regex diagnosis with empirical reproduction.
Every report this cycle came with file:line citations, refs/-grade upstream evidence, or shell-ready repro commands. That's the contributor energy that turns a brittle install path into an architectural improvement.