v1.0.106
A focused follow-up to v1.0.105 — Mickey @mikij retested the OpenCode resume injection and surfaced two real defects plus one UX dead end. All addressed here, plus a stale-version-check fix that bit us during the v1.0.105 rollout itself.
What's new
OpenCode cross-session resume — actually works AND you can see it
v1.0.105 fixed the wrong hook (messages.transform → system.transform) but Mickey reported the snapshot was still doing nothing observable. After auditing OpenCode source (packages/opencode/src/session/llm.ts:103-122) and running 3 parallel sub-agent verifications:
-
resumeInjected.add(sessionId)ordering bug. v1.0.105 marked a session as "tried" BEFORE checking whether the DB had a snapshot. A new session that polled too early — before any prior session had compacted — was permanently locked out of retroactive injection within the same plugin process. Fix: move the.addto AFTER a successful splice. No row → no mark → next chat turn retries. -
Self-injection bug. Without further care, fix #1 would have shipped a worse bug: a session that compacts mid-flight (Session B turn 5 produces B's own snapshot row) would claim its OWN snapshot back into its OWN system prompt on turn 6 — wasted tokens AND consumed the snapshot meant for the next fresh session. Fix:
claimLatestUnconsumedResume()now takes acurrentSessionIdparameter; the SQL addsAND session_id != ?to the innerSELECTso a session can never claim its own row. Architect grill confirmed without this guard the feature is anti-correct: it steals from itself. -
Visible signal — Mickey's "I can't find use case for it". The injection was working but invisible. No log line, no UI surface, nothing the user could grep. We now prepend a plain XML comment to the snapshot:
<!-- context-mode v1.0.106: resumed prior session abc12345 (N events, M chars) --> <session_resume>...</session_resume>Harmless to the model, shows up in
OPENCODE_DEBUG=1logs as proof the snapshot landed.
Mickey's repro after this lands
cd ~/proj && opencode— do enough work to trigger auto-compact (or run/compact)- Exit (
Ctrl+D//exit), restartopencodein the same directory - Send your first message —
grep '<!-- context-mode v1.0.106:' ~/.cache/opencode/log/*.logwill show the marker
Other changes
_latestVersion now refreshes hourly (long-running session bug)
The "context-mode outdated, upgrade available" warning relied on a single npm registry fetch at server startup. Long-running MCP sessions (some folks keep one alive 24h+) cached a stale value forever — when v1.0.105 went live, a 14h-old session never knew. Fix: setInterval(60 * 60 * 1000).unref() re-fetches every hour. .unref() ensures graceful shutdown isn't blocked.
Tests
All in EXISTING files per CONTRIBUTING.md L275:
tests/session/session-db.test.ts— 2 new self-exclusion slices (claim excludes current session, returns another session's row when both have one)tests/opencode-plugin.test.ts— 4 new behavior tests (self-injection guard, retry on next turn, B→C handoff, visible marker emitted)
276/276 tests pass across session-db + opencode-plugin + server.
Validation
3 parallel sub-agent passes (diagnose / grill-with-docs / architect) all converged on RESHAPE before this change, SHIP after the self-exclusion + visible marker landed. Verified against agentisd/refs/opencode source — chat.system.transform fires per-turn from LLM.process, system enters as 1-entry joined string, our splice(1, 0, marker+snapshot) preserves the [header, body] cache fold.
Docs
docs/platform-support.md OpenCode entry now lists the 4th hook (experimental.chat.system.transform), explains the cross-session resume workflow, and tells users how to verify via OPENCODE_DEBUG=1.
Contributors
- @mikij — for retesting v1.0.105 and surfacing both the gate-ordering bug and the silent-no-feedback UX dead end. Without this report, the feature would have shipped working-but-invisible and we'd have caught the self-injection regression in production.
Upgrade
npm update -g context-modeOr use the in-product ctx_upgrade MCP tool. If your MCP session is older than ~1 hour, the server may take up to an hour to notice this release — that's the bug we just fixed (so it'll never happen again after this update).