github vshulcz/deja-vu v0.23.2

2 hours ago

Recall is twice as fast and the index a third smaller, with the same answers.
On a 19k-session store against 0.23.1, MCP recall p50 goes from 170 to 85 ms
and the index from 277 to 185 MB, and LongMemEval-S hit@1 is 88.9 against
88.1. Agents get less noise: the per-prompt block is injected for 51 unrelated
prompts in 240 instead of 171, and pages with nothing to find are a third of
their size. A recall that misses the deadline still reaches the agent, and
recall answers during an upgrade's rebuild. Cold builds cost 31% more CPU than
0.23.1 because the index now records the commands and edits behind each
conclusion. The index rebuilds once on upgrade.

Added

  • deja mcp --context-search serves Qwen Code's External Context MCP
    Profile v1: one context_search({query}) tool that answers from the local
    index with at most five items in the profile's untrusted envelope, checked
    against the profile's published schemas and test vectors. deja mcp itself
    is unchanged. Register it with qwen mcp add deja-context deja mcp --context-search --timeout 8000 --include-tools context_search (#5662).
  • DEJA_RECALL_GLOBAL=1 makes MCP recall, deja recall and deja mcp --context-search rank every project the same instead of putting the current
    one first. Unset, nothing changes, and the hooks and the TUI keep their
    scope. From @Terminator637 (#5674).

Changed

  • Recall labels who wrote each line (Model said (no record backs it),
    Prompt written by a parent agent, Output with an instruction to agents …)
    and shows the command or edit a model's conclusion rests on above the
    conclusion, from receipts written when the index is built or updated. A check or build
    rule a person typed in an interactive Claude Code session of the current
    project is shown as User said (this project), and the frame header and MCP
    instructions say to follow those lines and nothing else. An instruction to
    run something that no person in the project typed (tool output, a paste, a
    parent agent's prompt, a claude -p run, another project) is cut to
    [instruction to agents left out]; a rule the person took back is not
    shown. The index version is now 109, so the store rebuilds once on the
    first run.
  • Recall no longer heads a page "No session is about this" when a session on
    it holds most of a long query. The page says which session holds how many of
    the query's words and which it lacks. A page that shares only filler words
    with the query, or lacks the path or identifier it names, keeps the old line.
    A word-form match that had to drop query words no longer outranks the
    sessions that hold them.
  • The instructions, skills and extensions ask for 1-3 exact terms on recall (a
    file path, an error string, a flag or identifier) instead of the task's key
    nouns. Queries of six or more words almost never matched.
  • The instructions, skills and extensions no longer tell the agent that a
    recalled rule outranks its defaults. Recall is untrusted reference data from
    past transcripts: the agent names the rule in one line and asks before it
    changes a command, a file write or a config. The standing-decisions block
    says the same (#5676).
  • The per-prompt line names the agent the memory came from and how long ago:
    deja-vu — from Codex CLI, 4 months ago: "<quote>" (via <terms>), where it
    used to say only "you have been here" and a date. The gates are unchanged:
    a confident match only, at most once in twenty minutes per session. The dsh
    card and the OpenClaw chat line read both shapes (#5660).
  • A spawned subagent's instructions are no longer extended with recall, except
    in Grok, whose main-thread hooks print to nobody. Over 60 days on one
    machine, 1339 Claude Code subagents were handed a block and none used it,
    and those blocks were 55% of all per-prompt recall. opencode task sessions
    are not searched on their turns either, since the agent that wrote them had
    the recall already (#5660).
  • The per-prompt block is injected only when the prompt names something the
    history holds: two of its lead words said in one message, or one word that
    names a thing (a path, a symbol, a rare Latin-letter word). The block is also
    dropped when none of its quoted lines holds two of the question's words.
    Replayed over 240 real prompts: unrelated blocks 171 to 51, relevant 9 to 11,
    mean block about 1750 to 600 bytes. On a store under 109 sessions the
    rareness floor follows the store, so a new user's one-word question is still
    answered (#5717, #5718).
  • A recall page headed "No session is about this" lists each lead on one line
    (where, when, which query words it holds, id), and only the first keeps an
    excerpt. Agents followed one of those leads 6 times in 212. Replayed over 88
    real recall calls: these pages are 0.37x the bytes, with no found answer lost
    (#5722, #5723).
  • The index is about a third smaller. Records are compressed from 256 bytes
    instead of 8 KB, at the fastest level: a 19k-session store goes from 277 to
    185 MB, a 38k one from 548 to 365 MB. Old and new binaries read each other's
    index, so there is no rebuild (#5727, #5729).
  • Recall is about twice as fast and uses a third of the memory. Session views
    and bucket directories are kept between queries, ranking runs on slices
    instead of maps of maps, and deja mcp checks the index for freshness on a
    15 s timer instead of walking every transcript inside each call. On a
    19k-session store against 0.23.1: MCP recall p50 170 to 85 ms, p95 293 to
    158 ms, CPU per call 368 to 139 ms, allocation 245 to 91 MB; the per-prompt
    hook p50 148 to 107 ms; deja search p50 203 to 161 ms. Output is
    unchanged. A session another agent writes becomes searchable within about
    15 s under deja mcp; the CLI and hooks still check on every call (#5728,
    #5730, #5732, #5733, #5734, #5736).
  • Receipt extraction scans tokens by hand instead of with three regexps. A cold
    build of 19k sessions takes 59 s of CPU instead of 87 s with byte-identical
    output. That is still 31% more than 0.23.1, which had no receipts (#5735,
    #5737).

Fixed

  • A two-word recall query where one word is in no session falls back to the
    other word when it is rare enough to mean something. The page says which word
    was dropped and shows at most three sessions. It used to come back empty
    while the same word in a three-word query was dropped (#5711, #5712).

  • Recall keeps the machine-wide best answer second on a project-first page, and
    gives the first conclusion only part of the page. On 48 real recall calls the
    answer that exists was found 10 times in 22 instead of 7 (#5708, #5709). The
    added session no longer sets the page's first line, so a question with no
    answer still opens with "No session is about this" (#5713, #5714).

  • A recall that finishes after its wait note, and found sessions, rides once on
    the next tool reply on the same connection. Agents repeated the exact call 2
    times in 47 and the answer was lost (#5715, #5716).

  • While an upgrade rebuilds the index, recall, recall_context and blame answer
    from the previous index instead of "ask again". On a 40k-session stand 139 of
    139 recalls during the rebuild returned hits, against 0 of 260. A build older
    than 10 minutes no longer starts a second one (#5720, #5721).

  • A warmup claim names the process that owns it. A live worker that goes quiet
    under I/O contention, or waits on the index lock, is no longer replaced by a
    second and third worker, and a finishing worker removes only its own claim.
    Reported by @j2h4u (#5719, #5726).

  • deja sources names a location for copilot-chat, roo, kilocode and
    cherrystudio on a machine where they are not installed yet. Those rows
    printed an empty column; each now names the directory deja reads once the
    editor or app creates it: VS Code's User directory, the extension's
    globalStorage directory, and Cherry Studio's default store (#5638).

  • Three hook regressions found by replaying 333 real events against v0.23.1.
    A failure that matches another session's only on a shell parse error no
    longer gets that session's next command as a hint (unrelated hints 3 of 60
    to 0). Ran/Output lines give up their room before the line that answers in
    the per-prompt block. A program's own remedy in tool output is kept; only
    text addressed to AI agents is cut. The frame names the user-rule
    exception only when the block carries one (#5704).

  • deja doctor reports MiniMax Code guidance as installed after deja install mcode-auto wrote the skill, instead of "unsupported" (#5700).

  • Tab completion offers deja friction --settle and --unsettle in bash, zsh,
    fish and PowerShell, and completes nothing for the wall id after them.
    friction shared one case with fix and tests, which offered only --limit
    and --json (#5640).

  • deja how and deja restore run without an argument print the usage line
    deja help prints. Each kept its own copy, and both had drifted: how
    left out --all-projects and restore spelled -o file for
    -o|--out file. deja files, a third copy, now reads the same entry
    (#5641).

  • opencode and Kilo keep one per-prompt recall block on a user message. The
    plugins appended on every model call and only checked for their own block at
    the end, so two copies of the plugin, or a host that keeps the message
    between calls, stacked a block per call, alternating between two pointers.
    The block is now put in place of any already there, and a block already on
    the message is reused rather than asked for again. Run
    deja install opencode-auto again to rewrite the plugin (#5682).

  • deja show --offset -1 says --offset wants a number from 0 up and quotes
    the value, as deja recall does. It shared one message with --limit,
    "needs a positive integer", which is wrong for --offset: 0 is the first
    message (#5650).

  • deja help delete names the agents it takes instead of describing them: the
    page closes with the list built from the two maps the command reads, so an
    agent added to either is named there without a second edit. The refusal for an
    agent whose sessions deja cannot check yet opens with the agent —
    Continue sessions can't be deleted yet: deja has not checked how Continue lists them — where the CLI's own prefix made it read deja: deja can't delete Continue sessions yet. From @tnalbant (#5654, #5675).

  • Ten agent guides say how to delete a session with deja delete, including
    the Cline and Antigravity cases it refuses or cleans up. From @gezerui888
    (#5738).

  • deja stats --year says "1 session", "1 turn" and "1 record" on every
    line, not only the first, and the verbs agree. From @dannyward630 (#5655,
    #5658).

  • Amp threads the plugin writes are filed under the workspace Amp has open,
    not amp/plugins. The plugin took process.cwd() for the thread's
    directory, and Amp runs a plugin from ~/.config/amp/plugins, so every
    thread and every hook it sent named that directory. It now reads
    amp.system.workspaceRoot. Run deja install amp-auto again to rewrite the
    plugin; threads already written are corrected the next time they end a
    turn (#5672).

  • opencode shows the per-prompt line. The plugins kept only the model's half
    of the reply, so the line reached nobody while deja counted it shown and
    held the next one back twenty minutes. opencode 1.x and Kilo now toast it.
    The 2.x plugin has no channel to the TUI and asks deja --strict, so the
    line and the session-start receipt stay unspent there (#5660).

  • A resumed Gemini CLI session no longer shows and indexes each tool result
    twice. Gemini writes the earlier function responses again under new message
    ids, and those are now dropped by call id. The index is rebuilt once on
    upgrade. From @adity982 (#5318, #5618).

  • Per-prompt recall no longer replaces the answer on small models. The block
    ended with If it helped, say: "déjà vu: ...", and qwen3:8b in dsh with
    reasoning off replied with only that line in 10 of 10 runs. It now asks for
    the answer first and the line last: 10 of 10 answered, 10 still credited
    the recall (#5664).

  • deja fix finds the failures and fixes that happened in subagents. The
    subagent cut dropped every command a child ran, so most of them were never
    mined. It now keeps the commands with their exit status, and of their output
    only the lines that read as a failure or carry a test runner's verdict. On a
    rebuild of one machine's Claude history, subagent sessions with commands
    went from 754 to 2097 of 2273 and served fix pairs from 320 to 588, for 4.6%
    more index (224 to 234 MB) and about 4% slower search. The index is rebuilt
    once on upgrade (#5678).

  • opencode run "<question>" gets per-prompt recall again. opencode quotes
    each argument holding a space, and the prompt in quotes read as one clause,
    so an instruction in front of the question used up the terms and the block
    was empty. A prompt wrapped whole in one pair of quotes is now read without
    them (#5679).

  • The compaction freshness check stops reading git output at its deadline. A
    child process left holding the pipe kept it reading until that child exited,
    which on a worktree with millions of untracked files can take minutes. From
    @miztizm (#5620, #5621).

  • On Windows, plugins no longer flash a console window each time they run
    deja from a GUI host such as the DSH desktop app. Every spawn in the shipped
    and generated JavaScript plugins and the npm launcher now passes
    windowsHide, and the Hermes plugins pass CREATE_NO_WINDOW. Reported by @Deadsoul-114514 (#5635).

Changelog

Features

  • feat(mcp): serve Qwen's External Context profile with deja mcp --context-search (#5663)
  • feat(recall): follow the user's own check rules, cut instructions nobody in the project typed (#5696)
  • feat: add a Cursor marketplace plugin (#5667)

Fixes

  • fix(amp): file plugin-written threads under the workspace, not amp/plugins (#5673) (@anupamchugh)
  • fix(compaction): bound the untracked listing so a huge worktree cannot stall the hook (#5621) (@miztizm)
  • fix(completion): offer friction --settle and --unsettle in every shell (#5685) (@notsubash)
  • fix(delete): name the agents delete takes in help, and start the refusal with the agent (#5675) (@tnalbant)
  • fix(gemini): dedupe resumed tool responses (#5618) (@adity982)
  • fix(hook): ask for the answer before the recall credit line (#5665)
  • fix(hook): only inject recall when the prompt names something the history holds (#5718)
  • fix(hook): three regressions vs 0.23.1 found on a real-store replay (#5705)
  • fix(ingest): index a repository's own scripts run by relative path (#5691)
  • fix(mcp): hand a late recall answer on with the next tool call (#5716)
  • fix(opencode): keep one per-prompt recall block per user message (#5683)
  • fix(plugins): spawn deja with windowsHide so Windows GUI hosts stop flashing a console (#5681)
  • fix(recall): answer from the previous index while a version rebuild runs (#5721)
  • fix(recall): ask for 1-3 exact terms and stop calling partial matches nothing (#5693)
  • fix(recall): keep exact-tier and directory-lead order stable across calls (#5689)
  • fix(recall): keep the machine's added answer out of the page lead (#5714)
  • fix(recall): keep the machine's best answer on a project-first page (#5709)
  • fix(recall): let a two-word query fall back to the word the store holds (#5712)
  • fix(recall): list leads one line each on a page no session is about (#5723)
  • fix(sources): name a default location for copilot-chat, roo, kilocode and cherrystudio (#5694) (@ColumbusLabs)
  • fix(warmup): keep a claim while its owner runs, clear only your own (#5719) (#5726)
  • fix: allow explicit global recall across projects (#5674) (@Terminator637)
  • fix: deja how and deja restore print the usage line deja help prints (#5686) (@notsubash)
  • fix: deja show --offset says it wants a number from 0 up, and quotes the value (#5684) (@notsubash)
  • fix: name the source agent in the recall line, show it in opencode, stop recall into subagents (#5661)
  • fix: report MiniMax Code guidance in doctor (#5700) (@rajshadow)
  • fix: singularize year stats counts (#5658) (@dannyward630)
  • fix: subagent commands reach fix, quoted opencode prompts get recall (#5680)
  • fix: treat recalled rules as reference data, ask before acting on them (#5677)

Performance

  • perf(index): deflate records from 256 bytes at the fastest level (#5729)
  • perf(index): scan receipt tokens by hand instead of three regexps (#5737)
  • perf(mcp): check index freshness on a timer, not inside every recall (#5733)
  • perf(recall): cache bucket directories and rank on slices, not maps of maps (#5736)
  • perf(recall): keep per-manifest session views between queries (#5730)

Documentation

  • docs(guide): add guide page for deleting Goose session history (#4968) (#5659) (@liziye627-design)
  • docs(guide): add memory guide for TRAE CLI (#5089) (#5668) (@Sombolm)
  • docs: bring README, site, help and skills up to 0.23.2 (#5742)
  • docs: changelog and a why-comment for the mcode guidance fix (#5700) (#5703)
  • docs: changelog and site version for 0.23.2 (#5740)
  • docs: document the MCP tools/call deadline and DEJA_MCP_DEADLINE (#5706) (@Oscar-Williams)
  • docs: explain session deletion in history guides (#5738) (@gezerui888)
  • docs: link registry pages from home, fix zh orphans, keep counts out of lastmod (#5671)
  • docs: say what deja-vu is in one sentence and answer the comparison questions on compare.html (#5725)

Other

  • chore: pin the manifests to 0.23.1 (#5633)
  • refactor: delete index.FrictionHash, which nothing calls (#5656) (#5699) (@notsubash)
  • test(gitread): pin the literal env values, not the package variable (#5701)
  • test(sources): give the SQLite progress test a 1s window (#5710)

Install

curl -fsSL https://raw.githubusercontent.com/vshulcz/deja-vu/main/install.sh | sh
go install github.com/vshulcz/deja-vu/cmd/deja@v0.23.2
brew install deja-vu

Don't miss a new deja-vu release

NewReleases is sending notifications on new releases.