{"_id":"@dreamor/dsh-memvault","_rev":"2-a304b8b3615438535664d02979266739","name":"@dreamor/dsh-memvault","dist-tags":{"latest":"0.4.0"},"versions":{"0.3.0":{"name":"@dreamor/dsh-memvault","version":"0.3.0","license":"MIT","_id":"@dreamor/dsh-memvault@0.3.0","maintainers":[{"name":"dreamor","email":"dreamor@msn.com"}],"homepage":"https://github.com/dreamor/memvault#readme","bugs":{"url":"https://github.com/dreamor/memvault/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"8515628d27771c95cba1f21d5d2b8bb162bfd0cd","tarball":"https://registry.npmjs.org/@dreamor/dsh-memvault/-/dsh-memvault-0.3.0.tgz","fileCount":23,"integrity":"sha512-U0vNT74VRKCYfpd/+Jn8n2RlTextCwqhyr8w1/1pYc6jfMqWeKSBHZnPcSJ83EiGxxoqVgd+YL+nqc4b0ku9sg==","signatures":[{"sig":"MEUCIQC9T7dn+V3OCTlmVhaMVXiV4Pk51yo+5wiSCiZCh7EbfgIgHL57K2MIQZ4qPhtkuE71BLRpslRlfmCv3cfxx98VSCo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":43668},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"6aed1381ea37974cc905e5092182338ac6725105","scripts":{"test":"vitest run","build":"tsc -p ./","watch":"tsc -w -p ./"},"_npmUser":{"name":"dreamor","email":"dreamor@msn.com"},"repository":{"url":"git+https://github.com/dreamor/memvault.git","type":"git","directory":"dsh-plugin"},"_npmVersion":"11.19.1","description":"DeepSeek Harness (dsh) Cordis plugin: auto-injects MemVault memories into the system prompt and auto-extracts memories at turn end.","directories":{},"_nodeVersion":"26.8.2","dependencies":{"@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.11","typescript":"^5.5.0","@types/node":"^22.0.0","@deepseek-ai/cordis":"4.0.1","@deepseek-ai/dsh-llm":"0.1.1-rc.2","@deepseek-ai/dsh-scope":"0.1.1-rc.2","@deepseek-ai/dsh-session":"0.1.1-rc.2","@deepseek-ai/schemastery":"3.18.1","@deepseek-ai/dsh-system-prompt":"0.1.1-rc.2"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.0","@deepseek-ai/dsh-llm":"*","@deepseek-ai/dsh-session":"*","@deepseek-ai/schemastery":"*","@deepseek-ai/dsh-system-prompt":"*"},"_npmOperationalInternal":{"tmp":"tmp/dsh-memvault_0.3.0_1789104501707_0.1884671959666968","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@dreamor/dsh-memvault","version":"0.4.0","description":"DeepSeek Harness (dsh) Cordis plugin: auto-injects MemVault memories into the system prompt and auto-extracts memories at turn end.","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"repository":{"type":"git","url":"git+https://github.com/dreamor/MemVault.git","directory":"dsh-plugin"},"license":"MIT","scripts":{"build":"tsc -p ./","watch":"tsc -w -p ./","test":"vitest run"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.0","@deepseek-ai/dsh-llm":"*","@deepseek-ai/dsh-session":"*","@deepseek-ai/dsh-system-prompt":"*","@deepseek-ai/schemastery":"*"},"dependencies":{"@modelcontextprotocol/sdk":"^1.0.0"},"devDependencies":{"@deepseek-ai/cordis":"4.0.1","@deepseek-ai/dsh-llm":"0.1.1-rc.2","@deepseek-ai/dsh-scope":"0.1.1-rc.2","@deepseek-ai/dsh-session":"0.1.1-rc.2","@deepseek-ai/dsh-system-prompt":"0.1.1-rc.2","@deepseek-ai/schemastery":"3.18.1","@types/node":"^22.0.0","typescript":"^5.5.0","vitest":"^4.1.11"},"gitHead":"47117001e04d609f7d3a004b2b9c740d97c757c1","_id":"@dreamor/dsh-memvault@0.4.0","bugs":{"url":"https://github.com/dreamor/MemVault/issues"},"homepage":"https://github.com/dreamor/MemVault#readme","_nodeVersion":"24.20.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-UFHhG9x5YjxSd6RXzeW1yWocV6VrzQylxj2ye9DohGhlwvlPiSkFSq5hM7IOqigjiBDMH0iY1x856lQdX0BsZw==","shasum":"f3b0c2cb74a5c0ac6d1690d4b86d726565b2e558","tarball":"https://registry.npmjs.org/@dreamor/dsh-memvault/-/dsh-memvault-0.4.0.tgz","fileCount":23,"unpackedSize":43668,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dreamor%2fdsh-memvault@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC5YuLgVl6e052CFcp1ORgNuEssPRNeqVybbsdzzLGu0QIhAN2jYaqAj/AnVcSArhU/YczcxLCzq5tjg2KIEu64Exf1"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:04a43246-1ff5-4e4e-b6ad-6fbf4eb73d4b"}},"directories":{},"maintainers":[{"name":"dreamor","email":"dreamor@msn.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-memvault_0.4.0_1789185677000_0.8918332718415802"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-11T05:28:21.531Z","modified":"2026-09-12T04:01:17.491Z","0.3.0":"2026-09-11T05:28:21.845Z","0.4.0":"2026-09-12T04:01:17.144Z"},"bugs":{"url":"https://github.com/dreamor/MemVault/issues"},"license":"MIT","homepage":"https://github.com/dreamor/MemVault#readme","repository":{"type":"git","url":"git+https://github.com/dreamor/MemVault.git","directory":"dsh-plugin"},"description":"DeepSeek Harness (dsh) Cordis plugin: auto-injects MemVault memories into the system prompt and auto-extracts memories at turn end.","maintainers":[{"name":"dreamor","email":"dreamor@msn.com"}],"readme":"# @dreamor/dsh-memvault\n\nCordis plugin bridging [MemVault](../README.md) into [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (`dsh`).\n\nThe `dsh`/Cordis API surface it relies on (`ctx.systemPrompt.section()`,\n`session/event` payloads, `Plugin.Object` resolution) was verified against\nthe actual `deepseek-harness` source, not secondhand docs.\n\n## What it does\n\n- **Auto-injection**: keeps `memory://session-inject` cached and registers it\n  as a system prompt section (`ctx.systemPrompt.section()`), refreshed\n  eagerly at load and again on every `turn/end`. No agent tool call required.\n- **Auto-extraction**: on `turn/end` with `reason.kind === 'completed'`, calls\n  MemVault's `notify_response` with **both** that turn's assistant text and\n  the user's own turn text (`user/message` events with `source.kind === 'user'`)\n  automatically. Passing the user's own words matters — MemVault's extractor\n  signal words are first-person (\"我偏好\"/\"我喜欢\"), which match a user's own\n  statement far more reliably than an assistant's restatement of it.\n\nIf you only want the raw 16 MemVault tools exposed to the model (no\nauto-injection/auto-extraction), you don't need this package — dsh's own\n`@deepseek-ai/dsh-mcp-client` does the same with zero code: each upstream\nserver gets its own Cordis plugin instance via `cordis.patch.yml`\n(`transport: stdio`, `serverName: memvault`, `command: <path to\nmemvault-proxy>`).\n\n## Install\n\nPrerequisites: a working `dsh` install (e.g. `npx @deepseek-ai/dsh web`) and the\n`memvault-proxy` binary reachable from `PATH` (or point `binaryPath` at one —\nsee the override section below).\n\nBuild, then install into a dsh profile from the repo's `dsh-plugin/` directory:\n\n```bash\ncd dsh-plugin\nnpm install        # peer deps on 0.0.1-rc.1 packages need npm i --legacy-peer-deps\nnpm run build      # tsc --strict\nnpx @deepseek-ai/dsh plugin --profile <profile> add \"$PWD\"\n```\n\n`dsh plugin add` runs the equivalent of `pnpm add` and appends the package to\nthat profile's `dsh.profile.bundles` automatically — no manual edit of the\nprofile's `cordis.patch.yml` is needed for a default install. The plugin ships a\n`cordis.patch.yml` that registers one `memvault` entry with the default config\n(`mode: spawn`, `embeddingProvider: native`, …).\n\nVerify the composed config, then start:\n\n```bash\nnpx @deepseek-ai/dsh --profile <profile> --dump-config   # 组合后应只有一条 id: memvault 且字段正确\nnpx @deepseek-ai/dsh <profile> --port 0                  # 实际启动方式以你的 dsh 用法为准\n```\n\nAt startup the plugin spawns `memvault-proxy` on port 3778 and probes\n`http://127.0.0.1:3778/health` until the server is ready. To confirm the\ninjection actually lands: start a real conversation turn, then decompress\nthe session log (`zstd -d ~/.dsh/sessions/.../session.jsonl.zstd`) and check\nthat `request/header.data.header.system` contains the injected\n`[MUST]`/`[REF]` blocks.\n\n### Overriding config (local development)\n\nTo override a single field (e.g. point `binaryPath` at a locally built\n`memvault-proxy`), add a **bare-id override patch** to the profile's\n`cordis.patch.yml` and rewrite the whole `config` block — an override replaces\nthe entire `config`, it does not merge per-field:\n\n```yaml\n- id: memvault\n  name: '@dreamor/dsh-memvault'\n  config:\n    mode: spawn\n    db: '~/.memvault/data.db'\n    port: 3778\n    binaryPath: /absolute/path/to/memvault-proxy\n    embeddingProvider: native\n    agentId: dsh\n    injectOnAssemble: true\n    extractOnTurnEnd: true\n```\n\nThe `cordis.patch.yml` this plugin ships wraps its entry in `insert:` because\nthe entry doesn't exist in any earlier layer. A bare `- id:` patch is an\n*override* that requires the id to already exist and errors with\n`patch: entry \"memvault\" not found` otherwise — an override patch must\nrewrite the whole `config` block, it never merges per-field.\n\n## Config\n\n| Field | Default | Meaning |\n|---|---|---|\n| `mode` | `spawn` | `spawn` manages a `memvault-proxy` child process; `attach` connects to `url`. |\n| `db` | `~/.memvault/data.db` | Used when `mode: spawn`. |\n| `port` | `3778` | Used when `mode: spawn`. |\n| `url` | `''` | Used when `mode: attach`, e.g. `http://127.0.0.1:3778/mcp`. |\n| `binaryPath` | `''` (resolved from `PATH`) | Used when `mode: spawn`. |\n| `embeddingProvider` | `native` | Used when `mode: spawn` — forced as `MEMVAULT_EMBEDDING_PROVIDER` in the child's env, so it can't accidentally inherit dsh's own `OPENAI_API_KEY`. |\n| `agentId` | `dsh` | Reported to MemVault on every call. |\n| `injectOnAssemble` | `true` | Toggle auto-injection. |\n| `extractOnTurnEnd` | `true` | Toggle auto-extraction. |\n\n## Build\n\n```bash\nnpm install\nnpm run build\nnpm test\n```\n\n## Status\n\nBuilds clean (`tsc --strict`) against the real, npm-published\n`@deepseek-ai/cordis@4.0.1`, `@deepseek-ai/dsh-system-prompt`,\n`@deepseek-ai/dsh-session`, and `@deepseek-ai/dsh-llm` packages (not mocks —\nsee `src/index.smoke.test.ts`, which mounts the plugin on a real `Context`\nalongside the real `SystemPrompt` service and asserts `ctx.systemPrompt.assemble()`\nactually contains the injected section).\n\n**Fully verified end to end against a real `dsh` install** (`npx\n@deepseek-ai/dsh web`, v0.1.0-rc.6). Four real bugs were found and fixed in\nthe course of the verification:\n\n1. `cordis.patch.yml` insert vs. override patch semantics (a bare `id` patch\n   requires the id to already exist).\n2. `memvault-proxy` inheriting a stray `OPENAI_API_KEY` from dsh's own\n   process env, plus a stale (pre-`native`-embedding) local binary.\n3. The eager injection-cache refresh at `apply()` time racing\n   `memvault-proxy`'s own startup (`fetch failed`).\n4. `mcp-client.ts` permanently caching a *failed* connection attempt —\n   `connected ??= (...)` memoized on the first (raced, failing) call, so\n   every later call kept re-rejecting forever, never retrying even after the\n   proxy came up.\n\nWith all four fixed, a real conversation turn's session log\n(`~/.dsh/sessions/.../session.jsonl.zstd`, decompressed with `zstd -d`) shows\nthe actual `request/header.data.header.system` text containing MemVault's\ninjected `[MUST]`/`[REF]` memories, and a direct `notify_response` call\nagainst the running `memvault-proxy` moved MemVault's memory count from 8 to\n10 (new preference/fact memories actually saved to Inbox).\n\nA follow-up round extended `notify_response` to also extract from the user's\nown turn text — MemVault's extractor\nsignal words are first-person, so a user's own statement (\"我偏好用 tabs\")\nmatches far more reliably than an assistant's restatement of it (\"你偏好用\ntabs\" used to be silently rejected; the signal-word list was also extended\nwith second/third-person mirrors). Verified against the real running\n`memvault-proxy`: memory count went from 10 to 13 across three scenarios,\nwith `source:user`/`source:assistant` tags on the results.\n\nNote for anyone installing dsh-internal packages directly: several of them\n(`@deepseek-ai/dsh-session`, `@deepseek-ai/dsh-system-prompt`) have peer deps\non other `0.0.1-rc.1` packages that aren't all published yet\n(`@deepseek-ai/dsh-type-meta` 404s as of this writing) — `npm install\n--legacy-peer-deps` gets you the ones that matter for this package.\n","readmeFilename":"README.md"}