github mksglu/context-mode v1.0.129

latest release: v1.0.130
one hour ago

v1.0.129

Hotfix bundling 2 critical fixes — ship together as single release.

What broke

CI breakage from v1.0.128 — EXCLUSIVE pragma scope

v1.0.128 shipped db.pragma("locking_mode = EXCLUSIVE") inside applyWALPragmas(), which is called by EVERY DB type — both single-writer SessionDB (per-project) AND multi-writer ContentStore (FTS5 shared knowledge base across sessions). ContentStore is multi-writer by design (multiple Claude Code sessions concurrently search/index the same content store). Applying EXCLUSIVE there deadlocked the second instance — broke 4 ContentStore concurrency tests with 90s timeouts:

  • two ContentStore instances can write to the same DB file
  • indexPlainText is protected by withRetry
  • indexJSON is protected by withRetry
  • search and searchTrigram work under concurrent writes

CI on next + main both failed.

Fix architecture (commits f6c6153 + 77b6c15 + 24ab4fa):

  • Removed locking_mode = EXCLUSIVE from applyWALPragmas — base function now applies only WAL + synchronous + mmap_size (multi-writer-safe)
  • Added EXCLUSIVE in SQLiteBase ctor only — both single-writer (lockfile + EXCLUSIVE) layers gated by tmpdir skip
  • Critical: tmpdir skip-gate matches lockfile's gate. Tests open SessionDB twice on same tmpdir path to exercise multi-writer recovery; if EXCLUSIVE fires when lockfile didn't, the second open hits SQLITE_BUSY on its FIRST pragma call. Single source of truth: skipExclusive = dbPath.startsWith(tmpdir()) matches acquireDbLock helper's check.
  • Architectural separation now correct:
    • SessionDB (per-project, single-writer) → lockfile + EXCLUSIVE
    • ContentStore (shared, multi-writer by design) → no lockfile, no EXCLUSIVE, withRetry handles SQLITE_BUSY

#561 — Pi bridge identification env leakage (algorithmic 15-adapter fix)

@ishabana on Windows 11, v1.0.127. Pi runs npm:context-mode as package extension; mcp-bridge.ts spawns server.bundle.mjs as child process. v1.0.124 #545 fix scrubbed WORKSPACE-role env vars but PRESERVED IDENTIFICATION-role vars (CLAUDE_CODE_ENTRYPOINT, CLAUDE_PLUGIN_ROOT). When Pi runs alongside Claude Code, child inherits these → detectPlatform() returns claude-code (FIRST in PLATFORM_ENV_VARS registry, identification vars hijack detection) → Pi data lands in ~/.claude/context-mode/ instead of ~/.pi/context-mode/.

This was the ROOT cause of #560 (WAL contention) — Pi server + Claude Code MCP server BOTH writing to ~/.claude/context-mode/content/*.db simultaneously, WAL grows unbounded, queries hang. Reporter's verification: ~/.pi/context-mode/sessions/ exists but ~/.pi/context-mode/content/ does NOT — confirming content lands in wrong dir.

Fix architecture (commits 8172c29 + 4ef1c78 + 554ef81):

  • New algorithmic helper foreignIdentificationEnv(platform) in src/adapters/detect.ts — mirrors existing foreignWorkspaceEnv pattern. Returns Set<string> of identification-role var names from all OTHER platforms in PLATFORM_ENV_VARS. Algorithmic — registry-driven, MUST-3 compliant.
  • Pi bridge scrub extended in src/adapters/pi/mcp-bridge.ts — added second loop iterating foreignIdentificationEnv("pi") alongside existing workspace scrub. Comment cites #561 + JSDoc updated to clarify identification vars are foreign-noise when spawning under different host.
  • 15-adapter leak matrix extended in tests/util/project-dir-matrix.test.ts — for each (host, foreign) pair, asserts foreign IDENTIFICATION vars are scrubbed when host = pi. Adapter #16 inherits both filters automatically.
  • 3-OS uniformprocess.env semantics same on macOS/Linux/Windows once vars are materialized. No platform-conditional code.

Architectural lesson — past mistake caught

Test 7951357 in v1.0.124 era already KNEW identification vars leak into JetBrains projectRoot test. We patched the SYMPTOM in test setup (manual scrub) instead of the PRODUCTION ROOT (mcp-bridge scrub). v1.0.129 fixes the production root. Future contributors won't repeat this — the matrix test now enforces the invariant.

Composes with v1.0.128 #559 + #560 fixes

Once #561 is fixed:

  • Pi writes to ~/.pi/context-mode/ (correct partition)
  • No multi-writer WAL contention with Claude Code's MCP server (different DB path)
  • v1.0.128 lockfile still protects against same-DB multi-instance (e.g. user double-registers)
  • v1.0.128 sibling kill on /ctx-upgrade still cleans accumulated zombies

Three issues (#559 + #560 + #561) all closed by v1.0.128 → v1.0.129 progression.

Tests

3242 pass · 8 pre-existing OpenCode baseline failures (unchanged from v1.0.122 baseline).

Full test suite run BEFORE push (per Mert's CI breakage prevention directive). Total 3280 tests / 28 skipped / 10 failed (8 OpenCode + 2 timing-sensitive — within baseline noise tolerance for repeated runs).

New tests added in EXISTING files (CONTRIBUTING L275 — zero new test files):

  • tests/store.test.ts: 4 ContentStore concurrent tests now PASS (regression confirmed fixed)
  • tests/util/db-base-platform-gate.test.ts: regression guard for SQLiteBase EXCLUSIVE locking
  • tests/adapters/detect.test.ts: foreignIdentificationEnv helper assertions
  • tests/adapters/pi-mcp-bridge-env-scrub.test.ts: identification env scrub at spawn site
  • tests/util/project-dir-matrix.test.ts: 15-adapter leak matrix extended with identification ban invariant

Compatibility

15 adapters / 3 OS. Zero observable behavior change for healthy installs. Pi bridge fix is single-file (only Pi spawns context-mode child via in-repo bridge — other 14 adapters use host MCP runtime). EXCLUSIVE scope correction restores ContentStore multi-writer behavior that v1.0.128 broke.

Adapter Effect of v1.0.129
Pi #561 fixed — Pi data now correctly partitioned to ~/.pi/context-mode/
Claude Code No change — already host-spawned with correct env
All 15 (universal) ContentStore multi-writer restored. SessionDB single-writer enforcement preserved (lockfile + EXCLUSIVE on production paths only).

Upgrade

npm install -g context-mode@latest
# inside Claude Code:
/ctx-upgrade
# fully restart Claude Code (Cmd+Q + reopen)

If you were on v1.0.128 and saw concurrency tests timing out, v1.0.129 is the fix.

If you run Pi alongside Claude Code, verify after upgrade: ~/.pi/context-mode/content/ should now be created on first Pi ctx_* invocation. Pi sessions and content land in ~/.pi/, Claude Code's land in ~/.claude/ — no cross-pollution, no WAL contention.

Thanks

@ishabana for #561 — staff-grade diagnosis traced through bridge env handling to detection cascade, with two concrete fix proposals (Option A scrub + Option B Pi-marker). We shipped Option A as algorithmic generalization (foreignIdentificationEnv helper). Your data on Pi+Claude coexistence broke open the architectural class — without it, this would have stayed silent until next user hit it harder.

Don't miss a new context-mode release

NewReleases is sending notifications on new releases.