Releases: cortexkit/magic-context
v0.27.3
v0.27.3
Patch release: prevents a hard context-overflow when switching from a large-context model to a smaller one mid-session, stops the dashboard from spawning a background indexer daemon, and includes sidebar polish plus the badge/schema-fence fixes queued from the v0.27.2 window.
Fixes
-
Switching to a smaller-context model mid-session no longer overflows the first request (#188). If you switched from a large-context model (say 512k) to a smaller one (say 272k) while the session already held more history than the new model's window, the first request was sent oversized and rejected by the provider, and recovery only kicked in one turn later. Root cause was a model-resolution bug: on the switching turn the transform read the model off the last assistant message (still the old model) instead of the new model you actually selected, so the whole pass sized history against the old, larger limit. Magic Context now resolves the outgoing model correctly, clears the previous model's stale limit/pressure state, and proactively compacts before the first request when the carried history would not fit, so the switch is seamless instead of erroring once.
-
Opening the dashboard no longer spawns a background indexer daemon. The dashboard runs
opencode modelsto populate its model pickers, which booted the full OpenCode runtime including external plugins and could leave a high-CPU indexer process orphaned after the short-lived discovery call exited. It now runsopencode --pure models, which skips external plugins while keeping built-in auth. -
Sidebar header badge stays readable and no longer renders heavy black text. The transparent-theme fix from the v0.27.2 window (#186) derived the badge label color from the accent, but its threshold flipped ordinary mid-tone accents (a typical orange/amber) to black, which looked heavy and clashed with neighboring badges. The label now stays white across the normal range of accent colors and only switches to black on genuinely light/pale accents, while remaining safe on transparent themes.
-
Sidebar slot now sits higher by default. The Magic Context sidebar slot's default sort order moved up so it renders above the AFT slot out of the box. You can still set your own
order(orforceToTop) intui-preferences.jsonc. -
Clearer schema-fence guidance (#185). When a database written by a newer plugin version is opened by an older one, the message now points you at
doctor --forceas the remedy.
Docs
- Corrected the README's "existing project" section and rewrote the dashboard reference page to match the current project-centric dashboard layout (Projects with Sessions/Memories/Dreamer/Primers, Workspaces, Cache, User Directives, Config, Logs).
v0.27.2
v0.27.2
Patch release: fixes a TUI sidebar that fails to load on OpenCode 1.17.10, a config-migration edge case that could leave you running on defaults, and a context-limit misreport on OpenAI OAuth models. Also includes the two fixes already queued from v0.27.1's window (#176, #177).
Fixes
-
TUI sidebar loads again on OpenCode 1.17.10. OpenCode 1.17.10 bumped its TUI runtime (OpenTUI) to 0.4.2. The Magic Context sidebar ships as raw TSX that compiles against OpenTUI's JSX runtime, but the plugin didn't declare
@opentui/solid/solid-jsas dependencies, so on 1.17.10 the sidebar failed to load withCannot find module '@opentui/solid/jsx-dev-runtime'. Those runtime dependencies are now declared (pinned to the versions the host ships), and a CI smoke test imports the TUI entry the way OpenCode loads it so this can't silently regress again. -
Config migration no longer moves your user config when you open OpenCode inside the config directory. The v0.27.0 config-location migration moves a legacy config into the shared CortexKit location. If you happened to open OpenCode with its working directory set to the config home itself (
~/.config/cortexkit), the project-scope migration treated your user config as a project config, moved it into a.cortexkit/subfolder, and renamed the original aside, leaving Magic Context running on default settings until you noticed. The migration now never treats a user-scope config as a project source. No data was lost by the original behavior (the file's contents were preserved), but the active config path could go empty. -
Context limit no longer misreported for OpenAI OAuth models (e.g. gpt-5.5). Magic Context reads each model's prompt limit from OpenCode's resolved provider config. That limit is auth-dependent: on OpenAI OAuth, gpt-5.5's input cap is 272k, not the catalog's 922k. If the limit cache warmed up before your provider auth finished loading, it could cache and persist the raw 922k, and because the existing recovery only corrects a limit that's too low, a too-high value never self-corrected, so the sidebar showed plenty of headroom while the backend rejected the request. The limit cache now re-warms once, after a successful response proves auth is live, replacing any stale pre-auth value with the real one.
-
Pi spawns correctly on Windows (#177). Pi subagents now spawn through the running Node executable instead of a bare
picommand, which failed on Windows. The spawn path is also shell-free, so prompt text is never passed throughcmd.exe. -
Fresh installs default to
.jsoncconfig (#176). New installs now writemagic-context.jsoncinstead oftui.json.
v0.27.1
v0.27.1
Patch release: fixes a first-run setup crash introduced in v0.27.0, and stops the diagnostic log from masking token counts.
Fixes
-
Setup no longer crashes on a fresh machine. v0.27.0 moved configuration to the shared CortexKit location (
~/.config/cortexkit/magic-context.jsonc), but on a brand-new install that directory does not exist yet, and the setup wizard tried to write the config without creating it first, so the run ended inENOENT: ... magic-context.jsonc.tmp. The atomic-write helper now creates the parent directory before writing, so the very firstsetupcompletes cleanly. If you hit this on v0.27.0, update and re-runnpx @cortexkit/magic-context@latest setup. -
Token counts stay readable in the log. Diagnostic log lines like
tokens.input=45000andhasUsageTokens=truewere being rewritten to<REDACTED>because the secret redactor matched on the word "token" in the key name. A real key, token, or password is always a high-entropy string, never a bare number or boolean, so numeric and boolean values are now left as-is. Actual secrets (bearer tokens, JWTs, API keys) are still redacted by their value shape regardless of the key name, so nothing sensitive leaks. This also applies to the log tail indoctor --issuereports.
v0.27.0
v0.27.0: Dreamer V2, Primers, and the CortexKit config move
The biggest release since the V2 historian. The background dreamer is rebuilt into independently-scheduled tasks, two new memory capabilities ship (Primers and friction-learning), embedding storage stops throwing away your vectors on a config change, and configuration moves to a shared CortexKit location. Plus a deep correctness, security, and cross-harness hardening pass.
Dreamer V2: per-task scheduling
The dreamer is no longer one monolithic nightly run. Each maintenance task has its own cron schedule and its own model, configurable in the setup wizard, the dashboard, or magic-context.jsonc:
"dreamer": {
"tasks": {
"verify": { "schedule": "0 3 * * *" },
"curate": { "schedule": "0 4 * * 0" },
"classify-memories": { "schedule": "0 6 * * *" },
"retrospective": { "schedule": "0 5 * * *" },
"maintain-docs": { "schedule": "" }
}
}Point a lightweight model at the routine tasks and a stronger one at just the task that needs it. Set a schedule to "" to turn a task off. Every dreamer task is cache-safe by design: it never busts your prompt cache, no matter when it runs.
Each task now also runs with a dedicated prompt and a least-privilege toolset, so a memory-classification pass can't read files and a docs pass can't touch memory.
New: memory importance scoring (classify-memories)
Scores each memory's importance by blending how durable the fact is with what your project is actively working on, plus its scope and whether it is safe to share with teammates. When the injected memory block is over budget, the most relevant memories stay in context and the least relevant drop first (they remain fully searchable via ctx_search). Runs in the background, completely cache-neutral.
New: learning from friction (retrospective)
Learns from the moments you had to correct or re-explain something and records the durable lesson as a project memory, so the same friction does not recur. It is cheap by default: it only does real work when a cheap pass detects a genuine correction pattern, and it reads only your own typed messages (never tool output or other content), with the learning distilled into a third-person rule rather than your raw words. On by default; turn it off anytime.
New: Primers
Primers are durable, standing answers to the questions that keep coming up about how your project works ("how does the transform pipeline stay cache-stable?", "where does session state live?"). The historian notices when the same question recurs across days and promotes it to a Primer; the dreamer then keeps the answer current by investigating the actual code (an open-book read of the relevant files), not by re-summarizing what is already in context. Stale Primers sink out of the render budget over time but stay in the database.
Smart notes that check their own condition, cheaply
A smart note (ctx_note with a surface_condition) resurfaces when its condition becomes true. Until now the dreamer re-checked that condition by asking an LLM every single time it ran, all the way up until the condition was finally met. For something like "resurface when PR #42 is merged," that meant paying for a full model call on every check, possibly for days.
Now, for a deterministic condition like a GitHub PR being merged, a release tag being published, or a file appearing on disk, the dreamer writes a small reusable check once and then simply runs that script on each cycle. The repeated, open-ended LLM evaluation becomes a cheap, deterministic run that verifies the real-world signal (PR state, release tag, file contents) and surfaces the note at the right moment. The script runs in a locked-down WASM sandbox with a read-only, SSRF-guarded capability API, so a note's condition can safely reach out to check the world without ever touching anything it should not.
Memory maintenance, split so neither task starves
The old combined memory task is now focused tasks:
- verify checks memories against their backing files and fixes or removes stale ones, but only when those files actually changed (a one-time map-memories backfill records which files back which memory).
- verify-broad periodically re-checks the whole pool to catch drift.
- curate deduplicates, tightens, and prunes. Cross-category merges are now structurally rejected: a memory has exactly one category.
Beyond the split, every dreamer task was re-tooled to do more with less. Each task now gets a focused prompt and only the tools it needs, and the heaviest passes (classify, verify) were reworked to emit a single structured result instead of grinding through many small tool calls. The result is noticeably fewer tokens per run for better, more consistent output, which matters most if you point the dreamer at a paid model.
Embedding storage no longer wipes your vectors on a config change
Previously, changing your embedding model or endpoint could trigger a full, destructive re-embed of every memory, commit, and history chunk. Now vectors for different models coexist in storage, keyed per model. Switching providers (or testing one) keeps your existing vectors intact; the old set is garbage-collected lazily and only once a trusted new config has registered. A degraded or mid-migration config never drives deletion. Also adds a guard that refuses vectors when an endpoint silently serves a different model than requested (wrong-dimension corruption), and supports asymmetric query/passage input_type.
Configuration moves to a shared CortexKit location
Magic Context configuration now lives in one shared place per machine instead of per-harness:
- User config:
~/.config/cortexkit/magic-context.jsonc - Project config:
<project>/.cortexkit/magic-context.jsonc
This is automatic. On first run after upgrading, your existing magic-context.jsonc (from the OpenCode or Pi location) is moved to the new path, and the old file is renamed to *.MOVED_READPLEASE with a short note inside so nothing is silently left behind. If the migrator finds two legacy files that disagree, it refuses to merge them and asks you to consolidate (it never clobbers your settings). Project-local runtime artifacts (historian error dumps) move under <project>/.cortexkit/magic-context/, and a scoped .gitignore keeps them out of your repo.
Workspaces: selective memory sharing
Workspace members can now share memory by category rather than all-or-nothing. Toggle which of the five categories cross into sibling projects (defaults to sharing only CONSTRAINTS), so global truths travel while project-local controls stay private.
Reliability and hardening
- Plugin-load resilience. The plugin entry is hardened against an OpenCode Desktop multi-instance boot-order issue that could leave the transform disabled and balloon a session's context. A failure registering hidden agents can no longer take down the whole plugin.
/ctx-*commands no longer leak an error into the TUI or log on OpenCode 1.17.x. The handled-command signal is now a clean 204 response.- Resilient dreamer leases. Transient database contention during a long task no longer aborts it as a permanent failure, and a genuine multi-minute stall is detected correctly instead of risking a split-brain run.
- A multi-wave correctness and security review across storage permissions, config recovery, the embedding pipeline, the dashboard backend, SSRF guards, and migration safety. Storage directories are tightened to
0700/0600. toast_duration_ms: 0now disables Magic Context toasts entirely.
Thanks to our contributors
This release includes community contributions from:
- @kecsap: a configurable toast duration, including
toast_duration_ms: 0to turn Magic Context toasts off entirely (#92). - @tracycam: security hardening, including tighter storage-directory permissions, SQLite
ATTACHpath escaping, and project-config privilege fixes (#143).
Thanks also to everyone who filed detailed bug reports, and to Dependabot for the dependency bumps (#170, #171).
Upgrading
Upgrading is automatic. Your dreamer config is migrated to the new per-task schema in place, your configuration file is moved to the CortexKit location, and the database migrates to schema v49 on first load. No manual steps.
Dashboard dashboard-v0.8.0
Dashboard v0.8.0
A major dashboard release that reorganizes everything around your projects, ships the full Dreamer V2 control surface, adds Primers, and brings the config and embedding changes from plugin v0.27.0 to the desktop app.
Project-centric navigation
The dashboard is now organized around projects instead of scattered global lists. The sidebar is Projects, Workspaces, Cache, User Directives, Config, Logs.
- Projects is a searchable card grid sorted by recent activity. Each card shows session and memory counts, the workspace it belongs to (if any), active harness badges (OpenCode / Pi), and when it was last active.
- Open a project to get Sessions, Memories, Dreamer, and Primers as tabs scoped to that project. The old global Memories, Sessions, Dreamer, and Primers pages are gone; you reach each through its project, so you are always looking at one project's data with no cross-project noise.
Dreamer V2 control surface
The Dreamer page is rebuilt for the new per-task model (plugin v0.27.0):
- A project-card grid with a collapsible task list per project, each task showing its schedule and a last-run traffic light (hover for detail).
- Per-project configuration via a gear button: edit a project's dreamer tasks in a focused modal that writes a per-project override, with a clear "inherited from global" indicator and a one-click revert.
- A redesigned task list as cards with inline icons and on/off toggles, an error panel when a run fails, and a flat run-history table (started, task, status, duration, tokens, memory changes).
- A cron picker that actually works: presets (nightly, weekly, hourly), a custom-cron escape hatch with validation, and a human-readable explanation ("Every day at 3am").
New: Primers
A Primers tab surfaces each project's durable standing answers (the recurring "how does X work?" questions the dreamer keeps current by reading the code), with their freshness.
Memory classification
The Memory browser now shows each memory's importance (as a band-colored pill) plus scope and shareability when they differ from the defaults, so you can see at a glance what the dreamer considers load-bearing.
Workspaces: selective memory sharing
The Workspaces panel lets you share memory by category across member projects (toggle which of the five categories cross over, defaulting to CONSTRAINTS only), with a staged Save / Discard so a batch of changes commits as one.
Cache Diagnostics improvements
- The Cache Hit Timeline scales each bar to the model's context window and segments by context-window changes, so a 1M-token model and a 256k model are never measured against the same axis.
- A redesigned, provider-agnostic cache health metric (no longer relying on cache-write data only some providers report), with an explicit UNKNOWN state for providers that report no cache accounting.
- The per-session view colors the compartment strip by importance instead of an arbitrary rainbow.
- Fixes a case where the timeline fragmented into one segment per step for sessions without a recorded context limit (e.g. background subagents); these now render on one stable scale.
Configuration moves to the CortexKit location
Matching plugin v0.27.0, the dashboard reads configuration from the shared CortexKit location (~/.config/cortexkit/ and <project>/.cortexkit/). The OpenCode and Pi config tabs are collapsed into a single User Config tab. Edits preserve your comments and untouched keys (the editor aborts a save rather than dropping them on a parse error), and config writes are hardened against symlink and path-escape attacks.
Reliability and correctness
- Archived OpenCode sessions no longer appear in session lists or inflate project session counts.
- Deleted worktree projects (leftover
bg_<hash>directories from background tasks) no longer show up as their own project cards. dir:<hash>projects now resolve to their real directory name instead of an opaque hash.- The dashboard degrades gracefully on older databases: it opens read-only, never creates or migrates tables, and falls back to sensible defaults when a column or table is missing rather than erroring.
- Robust memory-embedding queries for the new per-model embedding coexistence (plugin v0.27.0), and a fix for UTF-8 paths and string values in config parsing.
- Windows and version-manager (mise / asdf / volta) model-dropdown discovery via a login-shell PATH fallback.
Upgrading
Download the build for your platform below. The dashboard is read-only against your Magic Context database, so it is safe to run alongside any plugin version; it degrades gracefully if your database predates plugin v0.27.0.
v0.26.0
v0.26.0
A performance release for large, long-running sessions: per-message transform overhead is at least 2× lower on typical passes, and up to ~10× lower on the heavy ones (when history summarization fires). Also removes a source of confusing "model not found" errors by dropping the built-in model fallback chain, fixes prompt-cache and Anthropic thinking-block issues, and folds in three community fixes.
Faster on large sessions
Every message you send runs Magic Context's transform, and on very large sessions (hundreds of thousands to millions of tokens) several steps in that path were scaling with the whole session instead of just the live tail. They've been scoped to read only the part that can actually change. Measured on a real ~2M-token session, the typical per-pass transform cost roughly halved (median ~220 ms → ~95 ms), and the worst passes improved far more.
- The summarization trigger and message-tagging now read only the live conversation tail, not the entire tag history. On that session this cut the trigger's per-pass cost from ~70 ms to low single digits and tagging from ~38 ms to well under a millisecond.
- When history summarization actually fires, it no longer blocks the turn while it gathers and prepares its input — that preparation read raw history straight off disk on the main path and could stall a large session for several seconds before the model even started responding. It now reads only the tail it needs (~9.6 s → ~150 ms on that session).
Net effect: noticeably less lag per message on big sessions, and no multi-second pause when summarization kicks in.
No more surprise models: the built-in fallback chain is gone
The historian and dreamer agents had a built-in fallback chain — a hardcoded list of models across several providers, tried automatically when the configured model failed. If you only have one provider, every entry in that chain was a "model not found", producing a burst of confusing errors (e.g. Model not found: opencode/gemini-3.1-pro for someone who never configured Gemini).
Fallbacks are now only what you configure. If a hidden agent's model fails, Magic Context tries the fallback_models you set for it (if any) — never a model you don't have. The historian additionally falls back to your active session model as a last resort; with nothing configured, a failing model just retries cleanly instead of cascading through providers you've never used.
To make a genuinely failing model visible, doctor now has a Historian runs section that records every summarization run (success / failure / no-op) and is never reset — so a "fails several times, then succeeds" pattern is no longer hidden by a counter that clears on every success.
Anthropic thinking-block & prompt-cache fixes
- Stale "[cleared]" thinking blocks. When Magic Context clears the text of an old reasoning/thinking block to save space, it could leave a
[cleared]placeholder paired with the block's original cryptographic signature — a content/signature mismatch that some Anthropic-family routes (direct Claude, Bedrock-Claude, proxied Claude) can reject. Clearing is now safe on every provider: on canonical Anthropic the block is dropped before the wire, on other OpenCode providers the reasoning is left untouched, and on Pi the block is emptied so the serializer drops it. The latest turn's reasoning is never touched on either harness. (#162) - Fewer prompt-cache busts. A hard cache rebuild (model switch, idle timeout, memory change) now also drains any pending content drops in the same pass, instead of forcing a second rebuild a turn later. And a compartment with no embeddable raw text (e.g. a tool-only span) no longer loops the background embedder forever on Desktop.
Community fixes
- TUI crash on the recompile/upgrade progress panel (#168). A reactive race could dereference a momentarily-null progress value and crash the TUI. Fixed. (Thanks @jiuxingwang.)
historian.disallowed_toolsfor weak models (#166). Some weak instruction-following models get stuck in tool-calling loops when tool definitions are present. You can now strip tools from the historian's request (["*"]removes all); the historian gets its full prompt inline and doesn't need them. (Thanks @tobwen.)- Pi-only
thinking_levelleaking into OpenCode agent config (#167). It's now stripped from all three hidden agents. (Thanks @tobwen.)
Also in this release
doctor migrate-session— re-home a session to another project. A new interactive command to move a session (and, optionally, the memories it created) from one project to another, with a dry-run preview.npx @cortexkit/magic-context doctor migrate-session --session <id> --to <dir>.- Asymmetric embedding models (#155). Embedding providers that distinguish query vs. document input types are now driven correctly per call (
query_input_type), without invalidating your stored vectors. - Release tooling fails fast. The dashboard release script now surfaces a failed build leg immediately instead of waiting out the slow legs first, and the build is hardened against transient crates.io network drops.
Dashboard dashboard-v0.7.0
Magic Context Dashboard v0.7.0
Cache Diagnostics, rebuilt
The Cache page now tracks each session in its own bounded window instead of a
shared global event pool, so the Recent Sessions cards show per-session
hit-ratio, event count, and bust count that no longer drift with how busy other
sessions are.
- Per-session windows. Pick how many recent events to keep per session
(200 / 400 / 600 / 800 / 1000); cards and the timeline both reflect exactly
that window. - Live, reliable refresh. A 1-second loop re-lists sessions and fetches only
new events per session, so the Recent Sessions strip stays current without
the manual pause/unpause it sometimes needed before. - One-line strip. Recent Sessions render as a single row of equal-width
cards; how many show adapts to the window width.
Cache timeline
- Context-scaled bars. Bar height is the prompt size relative to the model's
context window, with an inner cached segment — so you can see the prompt grow
and drop across a session at a glance. - Accurate severity. Cache health is judged by comparing each step's cached
read against what the previous step predicted, instead of a raw ratio that
false-warned on large file reads. Providers that don't report cache data show
as "unknown" rather than a misleading bust. - Magic-Context-attributed drops. Drop markers correlate to the actual
scheduler decision recorded by the plugin (execute / materialize / emergency),
shown in a tooltip. The blue drop line is now clickable and jumps to the step. - Importance heat-map. The compartment strip in the session view colors each
segment by its importance band (critical / high / medium / low) instead of a
meaningless rainbow.
Memories & projects
- Edit a memory's category directly from the dashboard (#158).
- Non-git projects now appear in the project picker and filter their memories
correctly (#160). - Real project names. Sessions that ran in a git repo with no remote/commit
no longer display as "/"; they show their actual directory. - Windows model dropdown is populated for version-manager installs
(mise / nvm / fnm / volta / asdf) and via a PATH fallback (#149).
v0.25.0
v0.25.0
Makes context reduction more automatic and fully reversible: old tool output is now reclaimed without you asking, anything that gets dropped can be recovered in full, and the agent is better at trimming spent output on its own. Also fixes a case where history summarization could silently stall, a broken Pi command, missing embeddings on Windows/Desktop, runaway background agents, and several prompt-cache busts.
New: automatic reclaim of old tool output
The execute threshold summarizes older conversation, but until now it never touched tool output (file reads, search results, command output) on its own — that was left to the agent calling ctx_reduce or the 85% emergency drop. In long, tool-heavy sessions that left a lot of stale output sitting in context: agents reliably drop recent outputs as they finish with them, but rarely go back for old ones, so the oldest tool results just accumulated.
Magic Context now reclaims them automatically. Once a tool output has survived a full execute cycle without being used, it's dropped on the next one — so a tool result gets one round of grace (in case you're still working with it), then goes if it's still untouched. Outputs you're actively using and the current turn's work are never affected, and this rides the cache rebuild that was already happening, so it adds no extra prompt-cache busts.
New: recover anything that was dropped (ctx_expand)
Dropping a tool output (with ctx_reduce or the automatic reclaim above) replaces it with a [dropped] placeholder on the wire — but the original is still kept in storage. ctx_expand can now bring it back:
ctx_expand({ message: 138 })— the full, untruncated content of the message at that ordinal: every text part and every tool call's complete input and output. This is the cheap way to get back a tool output you dropped — and it works even when re-running the tool would now give a different answer (the file changed, the command isn't deterministic). If the message was genuinely deleted (session revert/prune), it says so.ctx_expand({ start, end, verbose: true })— lists each message in a range separately with its ordinal, so you can find the exact message or tool call you want, then recover it by ordinal.
Both use the same [N] ordinals you already see in compartments and ctx_search results.
Improved: ctx_reduce guidance models actually follow
The ctx_reduce description framed dropping as immediate and irreversible (drop entirely, gone forever), which made models — GPT-family especially — hoard the tool and only reduce at the very end of a turn. It's now described accurately: marking content discardable is deferred (it stays visible until space is actually needed) and recoverable (via ctx_expand). The guidance is anchored on "are you done with this?" rather than "is it safe to delete?", so the agent trims spent output earlier and more freely while still protecting unprocessed evidence.
Fixes
- History summarization could silently stall. If a tool call was interrupted (an aborted run, a crash) and left dangling without a result, the summarizer's boundary logic could refuse to advance past it — so a session would stop compacting and just grow, with no error, until it ran out of room. The only recovery was rebuilding the session. The boundary now skips a stale, never-completing tool call instead of getting stuck behind it. This affected sessions on 0.23.0–0.24.1.
- Pi:
/ctx-dreamwas broken (#151). It failed withUnknown named parameter '0'on Pi and Desktop. A single database call used an array-bind form that works under one SQLite engine but not the other; it's fixed, and the engine layer now normalizes this so the whole class can't recur. - Pi / Desktop: local embeddings could fail to load (#128). When the local embedding runtime is missing or broken (a common Windows case), Magic Context now degrades cleanly with one clear message instead of repeated cryptic errors, and
doctordetects and reports it. - Runaway background agents (#154, #152). A weak or local model could get a background agent (history summarizer, dreamer) stuck in an endless tool-call loop that survived even cancelling — only a full restart stopped it. Background agents now have a hard step cap and are force-stopped on timeout.
- Fewer prompt-cache busts. Several cases that were re-billing large prompt prefixes:
- Dropped content now always renders with one identical placeholder, so a drop can never change already-sent bytes on a later pass.
- Removed an errored-tool-output trimming step whose timing could mutate an already-cached message to save a handful of bytes at the cost of a full prefix re-bill.
- When a model cargo-cults Magic Context's internal
§N§markers with an improvised closer, the stray characters are now cleaned up as a unit instead of leaving residue on the wire.
Also in this release
/ctx-embed— see and control history embedding. Run/ctx-embedfor a breakdown of what's embedded for the session (model, and how many compartments / memories / commits are covered), and/ctx-embed start/pauseto control the backfill. A session's missing history now also backfills automatically in the background, so older discussion becomes semantically searchable viactx_searchwithout a manual step. (Replaces/ctx-embed-history.)- Background agents can now manage their own context.
ctx_reduceand the context-pressure nudges are available to subagents, so long-running background work stays lean (paired with the automatic reclaim above). - Pasted noise in your messages can be dropped. A large pasted block (logs, data dumps) inside one of your messages can now be reduced once it's been processed — your instructions are always preserved, and the content stays searchable via
ctx_search. - Internal hardening: added cross-engine SQLite test coverage to CI and brought the Pi
doctorembedding check to parity with OpenCode.
v0.24.1
v0.24.1
Patch release: a fix for session titles never generating, fewer cache busts, embedding-endpoint safety, calmer reduction reminders, and a persistent TUI sidebar.
Fixes
-
Session titles generate again. With the plugin enabled, a new session could keep the default
New session - <timestamp>title forever (most visibly in non-git directories). Magic Context injects its compacted history as synthetic context messages, and those weren't flagged correctly, so OpenCode's auto-title step counted them as real user turns and skipped titling. The injected history is now marked synthetic — it still reaches the model, but no longer blocks the title. (#129) -
No embedding under the wrong model. When a local OpenAI-compatible endpoint (LM Studio, Ollama) serves a different embedding model than the one you configured — e.g. a shared endpoint where another tool keeps a smaller model loaded — the returned vectors have a different dimensionality and don't belong in your index. Magic Context now checks the model the endpoint reports and refuses mismatched vectors instead of silently corrupting the store. A clear log line names what was requested vs. served.
-
Embedded history chunks no longer get truncated. Chunks are now sized with a safety margin below the endpoint's input limit, so cross-tokenizer rounding can't push a chunk slightly over the limit and clip its tail.
-
Two more prompt-cache busts removed. (1) A stuck overflow-recovery flag could keep forcing a session to behave as if it were at the emergency ceiling — re-running cleanup every turn — after a
/ctx-recomphad already relieved the pressure; the flag now clears when there's nothing left to compact and on a successful recomp. (2) A dropped older message could flip between two equivalent placeholder forms across passes, changing one block of the prompt prefix and re-billing the tail; the two placeholder paths now agree byte-for-byte.
Improvements
-
Quieter, better-calibrated reduction reminders. The reminder that nudges the agent to drop spent tool output was over-firing — it measured against the wrong budget, so a modest pile triggered "urgent" on a large-context model. It now scales against the agent's actual working window, ignores output that can't be dropped yet (the protected recent window), and is worded as advisory rather than a directive. If the agent has already reduced enough, approaching the threshold no longer nags it.
-
Persistent TUI sidebar preferences. The Magic Context sidebar can now remember its collapsed/expanded state across restarts, and you can reorder it, rename its header, or hide individual sections — via a shared
~/.config/opencode/tui-preferences.jsoncfile (onemagic-contextkey). See the TUI sidebar reference.
Also in this release
- New documentation: why your token count can stay high after the execute threshold — the execute threshold compresses older conversation; tool outputs are reclaimed by
ctx_reduceor the 85% safety net, not by the threshold itself.
Dashboard dashboard-v0.6.0
Dashboard v0.6.0
Adds the Workspaces panel and fixes model dropdowns for version-manager installs.
New: Workspaces panel
Manage cross-project workspaces directly from the dashboard. Create a workspace, add member projects, and choose which memory categories members share with each other (Constraints only, by default). Edits are staged per card — add and remove members, toggle categories, then Save once, so the change applies as a single update instead of one per click.
Memories from other workspace members appear in each member session labelled by their source project. (Requires the v0.23.2 plugin, which owns the workspace schema; the panel degrades gracefully on older plugin versions.)
Fixes
- Model dropdowns were empty for version-manager installs. If your
pioropencodebinary is installed by a version manager (mise, nvm, fnm, volta, asdf), the dashboard couldn't find it — the desktop app doesn't inherit your shellPATH— so the model comboboxes came up empty. The dashboard now resolves the binary through your login shell (and known version-manager directories), bounded by a short timeout. - Workspaces panel layout — corrected double padding on the panel and tidied the shared-categories checkboxes to match the dark theme; Save/Discard now appear only when there are unsaved edits.