examples/dsh-memory-plugin
volcengine/OpenViking面向 DeepSeek Harness 的 OpenViking 记忆与上下文插件:pre-step 自动召回与画像注入、会话捕获、`viking://` URI 防护,以及对接 OpenViking 服务端的 recall/write 记忆工具。
Long-term project memory for coding agents, backed by Hindsight. One package, several agents: a shared reflect-and-inject core with a thin entry point per agent (Claude Code, Codex CLI, DeepAgents Dcode, opencode, opencode 2, Kilo CLI, Cursor CLI, GitHub Copilot CLI, Grok Build, Qwen Code, Kimi Code, Factory Droid, ZCode, TraeCode, Antigravity CLI, Devin CLI, Cline CLI, pi, Prime Agent, DeepSeek Harness, WorkBuddy, CodeBuddy). Ingestion is fully automatic — there is no setup command: a repo's git history and conversations flow into its memory bank in the background as you work.
The premise: most of a real fix is derivable from the code, but the _last mile_ often hinges on a project-specific decision that isn't in the code at all — a rounding rule, a retry allowlist, a tie-break policy. Those decisions live in git history and past conversations. This package puts them in front of the agent at the moment it starts working, and keeps a curated set of knowledge pages (architecture, conventions, in-flight initiatives) that future sessions start from.
AMB's sdebench is the measurement: a coding agent over 61 real repository tasks, three runs each, with and without memory.
Accuracy is not what moves — every run solves 60–61 of the 61 either way. These are tasks a good agent can already do. What memory changes is how much it costs you to get there: how often you have to stop and correct the agent, and what the tokens cost.
Agent · Corrections / task · Cost / task Claude Code · 0.85 → 0.36 · $0.445 → $0.338 Codex CLI · 1.34 → 0.47 · $0.577 → $0.276 opencode · 1.20 → 0.80 · $0.634 → $0.553
No memory → with Hindsight, mean of 3 runs. Corrections reproduce the labels AMB prints on its own chart; cost is derived from the same per-run table.
Both numbers move together, and that is the mechanism rather than a coincidence. A correction is a round trip: the agent guesses a project-specific decision wrong, you stop it, you explain, it redoes the work. Every one of those costs a turn of tokens and a turn of your attention. Handing the agent the decision _before_ it starts — the rounding rule, the retry allowlist, the tie-break policy that was settled in a commit message or a conversation months ago — removes the guess, and the round trip with it.
npx @vectorize-io/hindsight-coding-agents install all # every detected agent, wired natively
npx @vectorize-io/hindsight-coding-agents install claude-code # or just one
npx @vectorize-io/hindsight-coding-agents uninstall all # removes exactly what install added
npx @vectorize-io/hindsight-coding-agents update # refresh the runtime only, no rewiring
npx @vectorize-io/hindsight-coding-agents stats # how often each agent uses Hindsightinstall takes an explicit target — all, or one or more harness names. A bare npx @vectorize-io/hindsight-coding-agents install changes nothing and prints the choice, so wiring every agent on the machine is never something that happens by accident. Updating is the same `install` command again — it re-copies the runtime in place.
Day to day you should not have to: once a day, a session start checks npm and re-stages a newer runtime in the background (autoUpdate, on by default — set it to false to pin the version you have). That is the update command above, which refreshes the copy every wired agent already points at and deliberately touches no host config; re-run install yourself after a release that adds a new hook, or to wire another agent.
On a terminal it also asks where memory should live — Hindsight Cloud, a server you run, or a local daemon on this machine (see Where memory lives). Scripted installs pass --server cloud|self-hosted|daemon instead; it is asked only once, and never again on re-install.
Same command, only the harness name changes. Run after installing the package globally.
npx @vectorize-io/hindsight-coding-agents install claude-code3 hooks in ~/.claude/settings.json, MCP via claude mcp add (user scope), and the companion skill.
npx @vectorize-io/hindsight-coding-agents install codex3 hooks in ~/.codex/hooks.json plus [mcp_servers] in config.toml (needs codex_hooks = true).
npx @vectorize-io/hindsight-coding-agents install dcodeThe installer registers this package as a local marketplace with Dcode, then invokes Dcode's own plugin install command. The package is a native Agent Plugin: its root plugin.json contributes the shared skill, the Hooks V2 SessionStart, UserPromptSubmit, and Stop lifecycle, and the namespaced hindsight_* MCP server. Enable the plugin through Dcode's normal plugin manager; no Dcode config patcher or compatibility bridge is required.
Dcode namespaces a plugin's MCP tools, so they appear as plugin__hindsight-coding-…__hindsight_… rather than under their bare names — the agent resolves them from the tool guide either way. In headless runs (dcode -n) Dcode allows the read-only Hindsight tools and gates the two that write (hindsight_ingest_document, hindsight_capture_initiative) behind an approval it has no UI for; use the interactive TUI to capture an initiative or ingest a document. For the same reason the one-time codebase survey runs under another installed agent's CLI when there is one, exactly as it does for Cursor, Copilot, Devin, Grok Build, Cline, Kilo and Prime Agent.
npx @vectorize-io/hindsight-coding-agents install opencodeA plugin entry in ~/.config/opencode/opencode.json — native tools, no MCP needed.
npx @vectorize-io/hindsight-coding-agents install opencode2opencode v2 (npm @opencode/cli) exposes an opencode2 binary alias alongside opencode and rewrote the plugin API, so it is a harness of its own. It writes the same plugin entry to the same ~/.config/opencode/opencode.json — the two CLIs share that file, and v1 rejects the whole config if it sees v2's plugins key — and each CLI then loads its own entry point from the one registered path. So installing either harness wires both, and uninstalling either removes the shared entry.
Two differences from v1, both because of the host: the one-time codebase survey runs under another installed agent's CLI (v2 plugins cannot define the read-only agent the survey needs), and the seed banner is written to the plugin log instead of a TUI toast (v2 plugins cannot raise one). Recall, injection, the native hindsight_* tools and session write-back are identical. The companion skill is identical too, but it is registered in memory through v2's skill API rather than copied into a skills directory — opencode2 has none of its own, and the two it reads belong to other agents.
npx @vectorize-io/hindsight-coding-agents install kiloA plugin entry in ~/.config/kilo/kilo.json[c].
npx @vectorize-io/hindsight-coding-agents install cursor-cliHooks in ~/.cursor/hooks.json, ~/.cursor/mcp.json, and the companion skill.
npx @vectorize-io/hindsight-coding-agents install copilot-cli~/.copilot/hooks/, mcp-config.json, and the companion skill.
npx @vectorize-io/hindsight-coding-agents install grok-buildNative hooks in ~/.grok/hooks/hindsight.json, MCP in ~/.grok/config.toml, plus the companion skill. Grok also runs Claude Code's hooks from ~/.claude/settings.json; those stay silent inside Grok, so a machine wired for both hosts records each Grok session once. Grok passes hook context to the model only from tool hooks, so the session and prompt context arrive with the result of the agent's first tool call after each prompt (a PostToolUse hook).
npx @vectorize-io/hindsight-coding-agents install qwen-codeNative hooks in ~/.qwen/settings.json, plus MCP and the companion skill.
Qwen's hook timeout is in milliseconds (its own docs: "Timeout in milliseconds, default60000"), unlike every other supported agent, so the installed values are 30000/30000/60000.Recall fires on genuine submissions only — UserPromptSubmit also fires on tool-resultcontinuations, so interactive sessions recall once per prompt while headless (qwen -p),serve, SDK and ACP sessions seed and retain but do not recall.npx @vectorize-io/hindsight-coding-agents install kimi-codeNative hooks in ~/.kimi-code/config.toml, plus MCP in ~/.kimi-code/mcp.json and the companion skill. (Hooks and MCP go under $KIMI_CODE_HOME instead when it is set.)
Kimi's SessionStart hook cannot reach the model, so the session briefing is silent there;
recalled memory arrives on the first prompt instead, as a `` block. Sessions are
retained from every agent's wire.jsonl under the session directory, subagents included.npx @vectorize-io/hindsight-coding-agents install factory-droid4 hook registrations in ~/.factory/hooks.json (user scope), including a cancellation-safe Notification write-back, plus a stdio MCP registration under mcpServers.hindsight in ~/.factory/mcp.json, and the companion skill in ~/.factory/skills. The installer touches only JSON files - no Droid CLI round-trip - and refuses to overwrite a user-managed MCP server already named hindsight. Droid's hook protocol matches Claude Code's (session_id/transcript_path/cwd in, hookSpecificOutput.additionalContext out). Recall and injection use the same protocol; write-back also handles Droid's cancellation notification because Droid does not emit Stop after a cancelled turn.
npx @vectorize-io/hindsight-coding-agents install zcodeThree hook registrations plus a stdio MCP server under mcp.servers.hindsight, both in ZCode's own CLI config ~/.zcode/cli/config.json - never your real Claude Code settings, even though ZCode embeds the Claude Code agent runtime and speaks its hook protocol. The companion skill goes to ~/.zcode/skills. Config hooks ship disabled, so the installer also sets hooks.enabled to true; uninstall removes the whole block again when nothing else is registered there, and refuses to touch an MCP server named hindsight that it did not write.
ZCode's hooktimeoutMsis in milliseconds (installed values30000/30000/60000), and
hooks.maxOutputBytes caps what a hook may print - anything larger is dropped, injection andall. The installer seeds it at 32768 only when your config does not already set one.ZCode keeps no durable session transcript: Stop carries the reply plus a temp, assistant-onlyfile it deletes as soon as the hook returns, and no user prompt at all. So this is the one agent
whose conversation the plugin journals itself - the prompt hook records what you asked, the
Stop hook records the reply - and the write-back then behaves like every other agent's,appending each new turn to the same session document. --import-conversations is therefore notavailable for ZCode: there is no past history on disk to backfill from.
npx @vectorize-io/hindsight-coding-agents install traecodeThree hook registrations in TraeCode's user-level hooks.json, the companion skill under the same dot-dir's skills/, and two filesystem.readWrite rules in sandbox.json — one for ~/.hindsight, without which the hooks fail silently (exit 0, no effect) because the sandbox blocks those writes, and one for Trae's per-window storage DBs (/User/workspaceStorage), which the SessionStart hook seeds with the workspace's MCP enable switch. Network is allowed by default. TRAE ships two editions with different brand roots — the CN build uses ~/.trae-cn and "Trae CN", the international build ~/.trae and "Trae" — so every path resolves by probing for the edition dir that exists and defaulting to the CN names. Plain JSON files, no CLI round-trip. TraeCode speaks Claude Code's hook protocol, so recall and injection work exactly as they do there; the event map lives under the top-level hooks key and the version field the host writes is preserved.
MCP is registered per repo, never at the user level: Trae launches user-level servers with the Electron process's cwd (your home directory), where a hindsight entry either self-disables under optInOnly (zero tools) or resolves the home bank instead of the repo's. So the installer pre-seeds the per-repo registration for every repo opted in via mapPathToBank — a mcpServers.hindsight stdio server in /.trae/mcp.json, pinned to that repo via HINDSIGHT_MCP_PROJECT_CWD — migrates any stale user-level entry back out of /User/mcp.json, and seeds the per-workspace enable switch directly. The SessionStart hook re-checks both on every session and writes them only when missing or stale (idempotent fallback) — Trae's hook sandbox cannot be relied on to perform those writes itself. The per-repo file is merged not clobbered, and gitignored when the repo has a .gitignore (the path is machine-specific). A foreign hindsight entry — in either file — is the user's own server and is never touched.
Trae only reads that per-repo file once the global trae.mcp.enableWorkspaceMcp setting is on (default off), so the installer handles the gate: an interactive run asks, a non-interactive run takes --enable-workspace-mcp, and either way the setting is written and Trae windows must be restarted to pick it up (declining, or a settings file with comments, prints the manual step). Registrations and enable switches take effect on the NEXT window, so the MCP tools appear when you reload after the first session; repos opted into mapPathToBank after install need one more install traecode run, and if a repo's server still shows disabled in the MCP panel, flip it on once there.
One manual step remains after install (UI state the installer cannot write): enable the hooks