Releases: cortexkit/magic-context
Release list
v0.32.0
v0.32.0
The Pi release: a transform-performance overhaul measured on real long sessions, /clone state inheritance, and a batch of cache-stability and correctness fixes from two blind audit rounds. Plus a compact memory format that trims the token cost of injected project memory for everyone, and Claude Code / Codex session support on the dashboard's cache page.
Pi
Transform performance overhaul (#224)
Three optimization rounds, verified byte-identical against 62 real session files at every step:
- The historian trigger no longer resolves the full session boundary before its cheap gate — the most expensive per-pass cost on long historian-enabled sessions.
- Already-compacted history is trimmed before conversion and tagging instead of after, and tag loading is scoped to the live tail.
- Stable messages reuse their tag identities and token counts across passes instead of re-deriving them; branch entries parse incrementally (only new entries per pass) instead of re-parsing the whole session file.
On the largest real-world test session (27k entries, ~1,100 live messages), a steady-state pass dropped from ~1s to under 100ms warm. Sessions at the scale reported in #224 (5,700+ messages) see the reported multi-second transforms fall to a few hundred milliseconds.
/clone inherits Magic Context state (#225)
/clone previously produced a session where Magic Context's summaries, tags, and compaction state didn't exist — the clone lost its compacted history and could overflow on the first message where the original fit. Clones now inherit the full state at fork time (Pi preserves entry ids across clones, so the migration is exact): a cloned session continues with the same summarized history, tag numbers, and reduction state as the original. As a stopgap on older versions, /ctx-wrapup in a clone re-summarizes the full history — that path was also verified to recover everything behind the compaction boundary and to resume cleanly if interrupted.
Correctness batch from a blind audit round
An adversarial audit of the Pi lane surfaced failure-path bugs where an error mid-pass could ship bytes whose replay state never persisted — each one a potential cache bust on the next pass. All fixed with fault-injection tests:
- Reasoning clearing rolls back if its watermark write fails (previously: cleared bytes shipped, next pass restored them).
- Placeholder stripping persists before splicing (previously: a failed write meant a message vanished for one pass and returned the next).
- The stable-id scheme cutover only commits after the pass completes (previously: a failed pass could strand previously-stripped messages back into the prompt).
- A cross-process race in fallback-tag adoption could renumber a tag; collisions now preserve the number already on the wire.
- The mid-turn release valve only unlocks on genuine user messages (synthetic user-shaped messages no longer let mutations land mid-turn).
- Pi now strips processed images the same way OpenCode does: pasted screenshots the assistant has already handled are replaced with a placeholder once aged, instead of riding every subsequent request as base64. Frozen-id replay keeps it cache-stable, and clones inherit the stripped set.
Status lines no longer reach the model
Progress notices (/ctx-embed drains, wrapup progress, config warnings) were delivered through a path that made them model-visible — the model would occasionally reply "Noted." to a background embedding notice mid-turn, costing tokens and transcript noise. Status entries now use Pi's display-only entry mechanism and structurally cannot enter model context. On Pi 0.80.2 (which lacks the entry renderer API) statuses are persisted but invisible; 0.80.3+ renders them normally.
Everyone
A cache-stability fix for pressure folds
A fold pass could serialize one assistant message near the compaction boundary differently than the surrounding passes — reasoning strips ran before tool reclamation changed the message topology, while the next pass ran them after. The result was a second, unnecessary cache bust (~half the prompt re-cached) one pass after a designed fold. Representation strips now run once, after all mutations, on every pass — a fold and the pass after it serialize byte-identical prefixes.
Leaner history compartments
Compartments in <session-history> now render as markdown headings (## 62704-62776 · 2026-06-08→09 · Title) instead of XML tags with attributes. On a large session's history this saves ~15% of the whole block (15k tokens on our biggest real session), applies retroactively to all stored compartments, and reads better. ctx_expand guidance and tool descriptions updated to match.
Compact project memory format
The injected <project-memory> block now renders memories as #id: fact lines grouped under one category tag, instead of one XML element with attributes per memory — roughly 20 tokens saved per memory, which adds up on mature projects with large memory pools. Memory ids remain visible so ctx_memory actions keep working unchanged, and importance scoring moved off the wire entirely (it still orders what survives the budget) — which also makes background memory re-classification cache-neutral.
Compartment dates restored
The history compartments in <session-history> carry their start-date/end-date attributes again when temporal awareness is on (lost in the v2 decay renderer) — so the model can reason about when past work actually happened.
Smart drops actually enabled
A config-mapping bug meant the smart_drops flag (superseded-edit compression, spent control-plane drops) was silently ignored on OpenCode since its release — the transform never saw the setting. If you enabled it and wondered why nothing happened: it works now.
Dashboard
(Ships as dashboard v0.10.0 alongside this release.)
- Claude Code and Codex sessions on the cache page: sessions from both harnesses appear in Cache Diagnostics with full cache hit/write timelines. Sessions managed by CortexKit context management are shown by default with a "Managed" badge; a toggle reveals unmanaged ones.
- Pi models in the shared config editor (#226): the model pickers now merge OpenCode and Pi model lists (with provider prefixes normalized), and you can always type a model id directly even when a discovered list is present — discovery is never exhaustive. Thanks @mkurt for the precise diagnosis.
- Bug-report form now includes Pi and Dashboard as client options.
Also fixed
- A
Bun is not definedboot error on OpenCode Desktop from the RPC server's WebSocket path. - Project-identity resolution no longer stalls passes on slow/dead git under load (last-known-good caching + realpath walks for symlinked
.git). ctx_searchresult anchors (@msg N) only render for the current session, so stale anchors can't point at the wrong conversation.- Doctor's ONNX runtime probe runs in a subprocess so a broken native binding can't crash the host process.
Dashboard dashboard-v0.10.0
Dashboard Release dashboard-v0.10.0
v0.31.5
v0.31.5
Patch release: two user-reported fixes.
Fixed
Pi historian failing on every run with some extension setups (#222, #221)
Hidden Pi subagent children (historian, dreamer, recomp) load your Pi extensions so extension-provided models keep working. In Pi's print mode, extensions load before the child's prompt is read — an extension that starts an agent turn during startup made the child fail with Agent is already processing on every model in the chain, wedging the historian entirely. The runner now detects this exact collision and retries the run once with user extensions disabled (Magic Context's own tooling stays loaded). Well-behaved extension setups are unaffected and keep extension-provided models; colliding setups get a working historian using built-in or provider-configured models, with a clear log line distinguishing extension interference from model failures.
Doctor warned about a removed setting (#220)
The doctor's user-memories check read the v1 dreamer.user_memories.enabled key, which the v2 config migration removes — so the warning fired on every run when dreamer.disable=true and pointed at a setting that no longer exists. The check now reads the v2 task schedule (dreamer.tasks["review-user-memories"].schedule), matching the runtime gate. Thanks @tobwen for the diagnosis and the fix (#219).
v0.31.4
v0.31.4
Maintenance release: 14 fix batches from two internal audit waves plus one user-reported bug.
Fixed
Compaction not triggering after threshold (#218)
A session whose previous turn ended with an interrupted or partially-aborted tool call could get stuck: every subsequent pass was classified as mid-turn, so the compaction threshold never fired and queued context reductions never applied. A newer real user message now ends the stale turn on both OpenCode and Pi. Additionally, doctor --issue reports no longer redact plain numeric settings like execute_threshold_tokens (redaction now applies only to string values under secret-like keys).
Workspace memory sharing
Two security fixes: malformed workspace share_categories now fails closed to sharing nothing (instead of sharing everything), and primary agents can no longer update, archive, or merge another project's memories through shared categories — shared visibility is read-only; mutations require ownership.
Project config trust boundaries
Project-level (.cortexkit/magic-context.jsonc) configs can no longer override historian.model / historian.fallback_models (a cloned repository could otherwise route background LLM work to a repo-chosen model on your credentials), and project-level execute thresholds now only apply when they delay compaction relative to your user config, never advance it. Dreamer task tuning and memory.enabled remain project-configurable.
Dreamer reliability
Dreamer task manifests (verify / map-memories / classify) are now fail-closed: a truncated or malformed model response is rejected and retried instead of partially applied. Lease-guarded writes use immediate transactions so concurrent OpenCode and Pi processes cannot double-commit. Retrospective scanning no longer permanently skips older sessions on large backlogs, and file-change verification catches same-second commits.
Historian and wrapup coordination
/ctx-recomp can no longer race a live /ctx-wrapup into concurrent compartment mutation. The boundary staleness fingerprint now hashes content (same-length edits are detected). Wrapup correctly treats a final chunk followed only by filtered noise as final, and waits at most 10 minutes for a busy compartment lease instead of indefinitely.
Cache stability
Two-pass tool reclaim and smart-drops now ride a hard m[0] fold on defer passes (previously spilled to a second cache bust). Image stripping replays its frozen set on every pass, including sessions that never had a compaction watermark. Channel-2 nudge delivery uses per-claim tokens so concurrent processes cannot double-deliver, and synthetic todo state never anchors to an errored/aborted assistant message (which some providers drop from the wire, orphaning the tool pair).
Storage integrity
Memory embeddings are skipped when content changed while the embedding request was in flight (stale-vector guard). The message search index recovers failed incremental writes even after later successes advanced its watermark. Cross-process duplicate memory writes are now idempotent.
Other fixes
- TUI/RPC: WebSocket re-hello no longer leaks notification sinks (lost TUI actions), reconnects detect a restarted server, upgrades require token auth before accepting the socket, and per-session cursors stop cross-session notification pruning.
- Pi todowrite: foreign-extension tool outputs are validated fail-closed before capture; overlay output capped.
- Smart notes: network check lifecycle hardened (tarpit responses can no longer hold the sandbox lock past budget; terminal rejections no longer retry).
- CLI doctor: honors
PI_CODING_AGENT_DIReverywhere, atomic JSONL migration writes, issue-report body-limit postcondition. - Pi E2E parity: 8 cache-invariant scenarios and a Pi-native subagent isolation test ported from the OpenCode suite.
v0.31.3
v0.31.3
Patch release: completes the TUI fix started in v0.31.2 and ships a batch of Pi parity fixes.
TUI sidebar now updates when installed from npm
v0.31.2 restored the OpenTUI runtime dependencies so the sidebar loads again, but a second issue remained: on OpenCode 1.17.14, plugins installed from npm are excluded from OpenTUI's Solid compile step, so the sidebar rendered once and never updated (token counts, compartments, and memories stuck at zero). Development checkouts were unaffected, which is why the problem only appeared in published installs.
The TUI is now precompiled at publish time and binds directly to the host's OpenTUI runtime, so the sidebar is fully live from npm installs. Older OpenCode versions and development checkouts keep working through an automatic fallback. The release pipeline now installs the packed artifact and verifies the compiled output before publishing, so this failure class is gated structurally.
Pi: todowrite gets real UX and a disable switch
Magic Context registers a todowrite tool on Pi (Pi has no built-in task list). It previously rendered raw JSON and could not be turned off, which clashed with community todo extensions. Now:
- A persistent todo overlay above the editor shows active tasks with status glyphs and counts while work is in flight, and hides itself when the list empties. It survives restarts.
- Tool calls render as compact status lines instead of JSON dumps, and a
/todoscommand lists tasks grouped by status. - New
todowrite.enabledconfig (defaulttrue): set tofalseif you use your own todo extension, and Magic Context registers neither the tool, the command, nor the overlay.todowrite.overlaycontrols just the widget.
Pi fixes
- Commands and tools now follow
/cd:/ctx-status,/ctx-dream,/ctx-wrapup,/ctx-embed, smart notes, and the rest resolve the active project's configuration at invocation time instead of using the project Pi was launched in. - Historian resilience now matches OpenCode: transient provider errors (rate limits, timeouts, 5xx) retry on the same model before moving down the fallback chain, and the live session model serves as a last-resort fallback after configured
fallback_models. - Historian failures now surface a notice in the session (previously they were only recorded internally), with the same wording and throttling as OpenCode.
/ctx-embed startreports progress during long embedding runs instead of appearing hung.- Fixed several cache-stability gaps: pending drops no longer land mid-historian-run, session switch-back no longer forces an immediate rebuild, and a stuck emergency-recovery flag now clears only after context usage genuinely drops.
/ctx-recomp --upgradenow points to/ctx-session-upgradeinstead of failing as invalid usage./ctx-statusshows the work metrics (new work tokens / total input) that OpenCode's sidebar already displays.
Other
ctx_searchnote anchors and smart-note attribution fixes on Pi.
v0.31.2
v0.31.2
Urgent fix: v0.31.1 broke the TUI sidebar for standard installs. Update immediately if you are on 0.31.1.
Fixes
TUI sidebar failed to load on v0.31.1
v0.31.1 stopped shipping OpenTUI and Solid as runtime dependencies, on the expectation that OpenCode supplies its own copies to TUI plugins. That holds for plugins loaded from a plain directory, but not for npm-installed plugins: OpenCode's import rewriting skips sources inside node_modules, so the standard install could not resolve @opentui/solid and the sidebar silently failed to load. The dependencies are restored.
The underlying goal — surviving OpenCode's OpenTUI version changes without a plugin release — needs a host-side change and will be revisited with the OpenCode team.
v0.31.1
v0.31.1
Patch release: the TUI sidebar no longer breaks when OpenCode changes its embedded OpenTUI version.
Fixes
TUI sidebar survives OpenCode's OpenTUI version changes
The plugin previously shipped its own copies of @opentui/core, @opentui/solid, and solid-js, pinned to match a specific OpenCode release. Every time OpenCode upgraded or reverted its embedded OpenTUI, that pin went stale and the sidebar could fail to load until we shipped a matching release.
OpenCode's TUI loader actually supplies its own OpenTUI and Solid instances to raw-TSX plugins, so the local copies were unnecessary. They are no longer installed as runtime dependencies; the host's versions are used directly. The sidebar now works across OpenCode's OpenTUI upgrades (0.3.x through 0.4.x) without a plugin update, and installs get slightly smaller.
Smart-note background checks no longer spill errors to stderr
A smart-note network check that hit the response size limit (or timed out) printed an uncaught SmartNoteNetworkError stack trace to OpenCode's stderr on every occurrence. The error is now handled on the response stream and reported through the normal check-failure path.
Smart-note state writes no longer fail with "database is locked"
Smart-note scheduling updates used a transaction shape that could not wait for a concurrent writer, producing spurious database is locked errors when several OpenCode instances shared the database. They now take the write lock up front and wait like every other writer.
v0.31.0
v0.31.0
Feature release: a new /ctx-wrapup command for compacting history on demand, notes in ctx_search, sturdier project identity on flaky git setups, and a simplified reduction configuration.
New
/ctx-wrapup: compact older history on demand
/ctx-wrapup [messages_to_keep] runs the historian forward over your live history right away, keeping only the newest N raw messages (default 20, counting every message: yours, the assistant's, and tool results). Everything older is summarized into compartments. The cut never splits an in-flight tool exchange and prefers to land on one of your messages.
Use it before switching from a large-context model to a smaller one: the compacted history is queued and materializes on your next message, and a model switch applies it at no extra cost. If you want it applied immediately instead, run /ctx-flush first.
While it runs, OpenCode's TUI shows a live Wrapup progress bar in the sidebar; OpenCode Desktop posts a start notice and the result in the chat; Pi reports per-chunk status messages. /ctx-recomp and /ctx-session-upgrade wait their turn while a wrapup is active (and the other way around), including across multiple processes sharing the same database.
ctx_search now covers your notes
Notes taken with ctx_note (including smart notes) are now a search source alongside memories, message history, git commits, and compartments. Results show the note's status and age; notes from the current session carry a @msg N anchor the agent can expand for surrounding context.
Improved
Project identity survives flaky git
Project-scoped memory is keyed by a git-derived project identity. Several failure modes could previously split or flip that identity:
- A git timeout on a slow disk, or a
dubious ownershiprefusal, disabled Magic Context for the session or split memory under a directory-based fallback identity. Both now fall back gracefully, and once a session has resolved its real git identity, transient git failures keep using it instead of flipping. - Working in a subdirectory during a transient failure now reuses the repository's identity rather than minting a separate one.
- Symlinked checkouts are now detected as git repositories.
dubious ownershipproduces a one-time warning with the exactgit config --global --add safe.directoryfix.
Doctor checks the local embedding runtime more safely
The CLI doctor now probes whether onnxruntime-node actually loads (not just whether its files exist), and runs that probe in a separate process so a broken native binding cannot crash the doctor itself.
Changed
ctx_reduce_enabled removed
Agent-controlled reduction is now always on; the ctx_reduce_enabled setting is gone. If your config still contains it, the key is ignored harmlessly. Caveman text compression, which was previously tied to that flag, is now controlled solely by caveman_text_compression.enabled (still off by default, and never applied to subagents).
Fixes
- The TUI sidebar no longer shows a Facts row (facts were folded into project memories in v2; the row was always 0).
- Pi: disabling
caveman_text_compressionnow also stops replaying compression persisted by earlier passes. - Pi: a transient search timeout no longer suppresses automatic search hints for the rest of the turn.
- A number of internal hardening fixes around the new wrapup command's concurrency (durable run marker with self-expiry, crash recovery on restart, and safe interleaving with the automatic historian), prompt-cache stability under multi-process contention, and the compaction-marker advance on Pi.
Dashboard dashboard-v0.9.3
Dashboard v0.9.3
Config editor alignment with plugin v0.31.0.
Changed
- Removed the retired
ctx_reduce_enabledtoggle from the General section. Agent-controlled reduction is always on as of plugin v0.31.0. - Caveman Text Compression no longer shows the "has no effect while Agent Controlled Reduction is enabled" warning; the setting is independent now and the description reflects that (active for primary sessions when enabled, never for subagents).
- The bundled configuration schema matches plugin v0.31.0.
v0.30.7
v0.30.7
Patch release fixing a false recomp failure on Pi-only installs and laying the plugin-side groundwork for a much faster dashboard Projects page.
Fixes
Pi: /ctx-recomp reported failure after succeeding on installs without OpenCode
On machines where Pi runs without OpenCode installed (for example Pi inside a Linux container), /ctx-recomp and /ctx-session-upgrade completed their rebuild and then reported Recomp failed unexpectedly: unable to open database file. The rebuild had actually published; the error came from a post-publish step that tried to open OpenCode's database, which does not exist on Pi-only installs. That step is now skipped on Pi, and a missing OpenCode database can no longer be created as an empty stray file. If you saw this failure, your recomp results were saved — no re-run needed.
Pi: boot log printed executeThreshold=[object Object]% for per-model thresholds
When execute_threshold_percentage is configured as a per-model map, the startup log now prints the resolved values (for example 65% (provider/model=50%)) instead of [object Object]%.
Improvements
Session-to-project index for the dashboard
Reported dashboard Projects page load times of two minutes or more came from the dashboard re-deriving each session's project by running git across every session directory on every load, including directories that no longer exist or live on slow network paths. The plugin now records a durable session-to-project index (a one-time background backfill on first start after upgrading, then kept current automatically), and the upcoming dashboard release reads that index directly instead of running git at all. Sessions whose directories have been deleted are left unindexed rather than guessed. Update both the plugin and the dashboard to get the fast path end to end.