dsh-claude-memory 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 GodCC6
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,209 @@
1
+ # dsh-claude-memory
2
+
3
+ A read-only [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin that
4
+ surfaces **Claude Code's existing project memory** inside DSH — so a task can continue in
5
+ DSH after a Claude Code quota runs out.
6
+
7
+ 中文文档:[README.zh.md](README.zh.md)
8
+
9
+ ```
10
+ ~/.claude/CLAUDE.md ─┐
11
+ @imports inlined │
12
+ ~/.claude/projects/<key>/ ├─► confine ─► redact ─► byte-budget ─► DSH system prompt
13
+ memory/MEMORY.md (index) │ + claude_memory tool
14
+ memory/<topic>.md (bodies) ─┘
15
+ ```
16
+
17
+ ## What it does
18
+
19
+ - Injects the resolved project's `MEMORY.md` index into the system prompt, plus the
20
+ user-global `~/.claude/CLAUDE.md` with its `@path` imports inlined.
21
+ - Registers one `claude_memory` tool so the model can open any memory, list projects, or
22
+ search across a project's notes — full bodies never enter the prompt by default.
23
+ - Masks credential-shaped text **before** anything reaches the model provider.
24
+ - Never writes, moves, or deletes anything under the Claude home.
25
+
26
+ ## Install
27
+
28
+ ```bash
29
+ dsh plugin --profile web add dsh-claude-memory
30
+ ```
31
+
32
+ Restart the profile — a new bundle in `dsh.profile.bundles` is read at boot, not live.
33
+
34
+ From a checkout instead of npm:
35
+
36
+ ```bash
37
+ dsh plugin --profile web add /path/to/dsh-claude-memory
38
+ ```
39
+
40
+ Verify the row composed:
41
+
42
+ ```bash
43
+ dsh --profile web --dump-config | grep -A 10 claude-memory
44
+ ```
45
+
46
+ ## Configuration
47
+
48
+ Defaults live in this package's `cordis.patch.yml`; override them in your profile's patch
49
+ layer or a `--patch` overlay.
50
+
51
+ | Field | Default | Meaning |
52
+ |---|---|---|
53
+ | `claudeHome` | `~/.claude` | Claude Code home. Every read is confined to this root. |
54
+ | `cwd` | `process.cwd()` | **Fallback only.** A live session's `agent.session.header.cwd` always wins. |
55
+ | `includeDescendants` | `true` | List sibling/child projects that have memory. |
56
+ | `descendantLimit` | `12` | How many other projects to list. |
57
+ | `maxIndexBytes` | `24000` | Byte budget for the injected memory block. |
58
+ | `maxGlobalBytes` | `6000` | Byte budget for `CLAUDE.md` plus inlined imports. |
59
+ | `enableMemory` | `true` | Inject the memory block. |
60
+ | `enableGlobalInstructions` | `true` | Inject the user-global instructions. |
61
+ | `enableTool` | `true` | Register the `claude_memory` tool. |
62
+ | `redactMode` | `on` | `on` masks secrets, `report` counts only, `off` disables. |
63
+ | `refreshMs` | `20000` | Re-read the store when a prompt is assembled and the cache is older. |
64
+
65
+ ## What reaches the model
66
+
67
+ Two system-prompt sections (orders 10 and 11, just after the deployment persona):
68
+
69
+ 1. **`claude-memory:global`** — `~/.claude/CLAUDE.md` with `@path` lines inlined. DSH's own
70
+ instruction loader deliberately does not expand imports, and it reads
71
+ `$DSH_HOME/AGENTS.md` rather than `~/.claude/CLAUDE.md`, so this is the only path that
72
+ carries the user-global Claude Code memory.
73
+ 2. **`claude-memory:memory`** — the resolved project's `MEMORY.md` index, plus a
74
+ newest-first list of the other projects that have memory.
75
+
76
+ Full memory bodies arrive only through the tool, one file at a time, under a 20 KB cap.
77
+
78
+ ## Project resolution
79
+
80
+ The directory that decides which memory is relevant is the **session's** working directory,
81
+ not the directory the `dsh` server was launched from. Those differ whenever the server is
82
+ started from one checkout while sessions run in another.
83
+
84
+ Resolution order:
85
+
86
+ 1. **exact** — `<home>/projects/<encoded-cwd>/memory/` exists;
87
+ 2. **git-root** — the encoded key for the enclosing git repository root has memory;
88
+ 3. **freshest** — otherwise, the most recently updated memory set among the ancestors and
89
+ children of the working directory (reported to the model as a guess).
90
+
91
+ Rule 2 exists because **Claude Code files memory under the git repository root, not the raw
92
+ working directory** — see the case study below. In rules 2 and 3 the other projects are
93
+ listed newest-first, so the freshest child is one tool call away.
94
+
95
+ `agent.session.header.cwd` is the same source the first-party `dsh-agent-instructions`
96
+ loader reads. Sections are registered globally as a fallback and then **shadowed per agent**
97
+ from `agent/created`, and the tool resolves per call from `exec.agent`, so a subagent or a
98
+ session started elsewhere sees its own project.
99
+
100
+ ## The `claude_memory` tool
101
+
102
+ | Action | Arguments | Returns |
103
+ |---|---|---|
104
+ | `projects` | `limit?` | Every project with memory, entry counts, current marker |
105
+ | `index` | `project?` | One project's `MEMORY.md` |
106
+ | `read` | `project?`, `file?` | One topic file; without `file`, the topic listing |
107
+ | `search` | `query`, `project?`, `limit?` | Matching lines as `file:line: text` |
108
+
109
+ `project` accepts a full key, a key suffix, or a unique substring. Every response passes the
110
+ same redactor and a 20 KB cap.
111
+
112
+ ## Security model
113
+
114
+ The threat model is concrete: notes written for one vendor's model provider are about to be
115
+ sent to a different one.
116
+
117
+ - **Read-only.** No code path writes, moves, or deletes anything under `claudeHome`.
118
+ - **Confined.** Every path is `realpath`-resolved and must stay inside `claudeHome`; a
119
+ symlinked file pointing outside is rejected. Topic names containing a path separator are
120
+ rejected.
121
+ - **Redacted before injection.** 13 rules cover provider key shapes, bearer tokens, PEM
122
+ blocks, JWTs, `password`/`token`/`secret` assignments with an entropy floor, connection
123
+ strings with inline credentials, and long hex blobs. A false positive costs one masked
124
+ line; a false negative ships a credential, so the policy leans conservative.
125
+ - **Untrusted framing.** The injected block tells the model the notes are background, never
126
+ instructions — memory text must not be able to steer the agent.
127
+ - **No dependencies.** The plugin imports only `node:*`, so there is no third-party code in
128
+ the trust path and it resolves in a profile whose `node_modules` lacks the harness
129
+ packages.
130
+ - **Prompt text is a string.** Providers read a synchronously refreshed cache; they never
131
+ return a promise.
132
+
133
+ Redaction is pattern-based, not a classifier. It cannot catch a secret that does not look
134
+ like one. Use `redactMode: report` to audit what *would* be masked, and
135
+ `enableMemory: false` as the kill switch.
136
+
137
+ ## Tests
138
+
139
+ ```bash
140
+ npm test # smoke + plugin + schema + live
141
+ npm run test:unit # fixture-only, no real ~/.claude needed
142
+ ```
143
+
144
+ | File | What it covers |
145
+ |---|---|
146
+ | `test/smoke.mjs` | Paths, redaction, store, budgeting, tool — against a synthetic fixture in the OS temp dir |
147
+ | `test/plugin.mjs` | Loader contract against a fake Cordis context, including agent-scoped shadowing |
148
+ | `test/schema.mjs` | The hand-written tool schema against the real `@deepseek-ai/dsh-tools` validators; skips when DSH is absent |
149
+ | `test/live.mjs` | Optional check against a real `~/.claude`; asserts no credential-shaped text reaches the prompt, skips when absent |
150
+
151
+ 76 assertions, no network, no model calls.
152
+
153
+ ## Case study: two things that are easy to get wrong
154
+
155
+ Both findings come from reading the ecosystem's existing plugins and a real memory store.
156
+ They apply to any DSH plugin that bridges another agent's files.
157
+
158
+ ### 1. Prompt providers are synchronous — an `async` provider renders as a `Promise`
159
+
160
+ `dsh-system-prompt` resolves section and context text **without awaiting it**
161
+ (`lib/index.js:330,337`), and the interpolator then calls `text.indexOf`
162
+ (`lib/index.js:152`). A provider declared as `async () => string` therefore yields a
163
+ `Promise`, not a string.
164
+
165
+ The most prominent Claude Code bridge in the ecosystem
166
+ ([`YYTbit/dsh-plugin-claude-bridge`](https://github.com/YYTbit/dsh-plugin-claude-bridge),
167
+ `src/index.ts:75,92,107`) registers async providers. Loading is not the same as rendering:
168
+ the plugin mounts cleanly and then fails at assembly. This plugin keeps a synchronously
169
+ refreshed cache and returns plain strings.
170
+
171
+ ### 2. Claude Code files memory under the git repository root
172
+
173
+ Memory lives at `~/.claude/projects/<encoded-project-path>/memory/`, where the path is the
174
+ project directory with `/` replaced by `-`. The question is *which* directory counts as the
175
+ project. Measured on the author's machine, on a docs hub that sits inside a larger repo and
176
+ has no `.git` of its own:
177
+
178
+ | Observation | Value |
179
+ |---|---|
180
+ | The hub session's recorded `cwd` | the hub directory |
181
+ | Its `Write`/`Edit` calls into a `memory/` path | 12, **all** under the enclosing repo's key |
182
+ | References to the enclosing repo's `memory/MEMORY.md` in that session | 235 |
183
+ | References to its own directory's `memory/` path | **0** |
184
+ | `.git` at hub / parent / grandparent | no / no / **yes** |
185
+
186
+ Session *transcripts* are stored under the cwd slug; **memory is stored under the git
187
+ repository root**. A bridge that resolves by `process.cwd()` — or that stops at the exact
188
+ cwd — silently reads the wrong project's notes for any hub directory. Memory directories are
189
+ also created on demand: across 50 project directories on that machine, only 20 had a
190
+ non-empty index and 21 had an empty `memory/`, so "no memory directory" is normal and does
191
+ not mean the directory was unused.
192
+
193
+ ## Known limits
194
+
195
+ - **Not a session-history reader.** It reads memory files, not transcripts. "What was I doing
196
+ an hour ago" needs the `*.jsonl` transcripts — out of scope here.
197
+ - **Claude Code's own index cap is not enforced.** Claude Code loads the first 200 lines or
198
+ 25 KB of `MEMORY.md`; an over-cap index silently drops entries there. This plugin injects
199
+ up to `maxIndexBytes` and does not warn about the cap.
200
+ - **Lossy project keys.** `-` is both the separator and a legal character in a directory
201
+ name, so display paths are recovered by walking the filesystem and fall back to the raw
202
+ key tail.
203
+ - **No watcher.** Freshness comes from `refreshMs` checked at prompt assembly, so an edit
204
+ made mid-turn lands on the next assembly.
205
+ - **Index only for the resolved project.** Other projects need a tool call.
206
+
207
+ ## License
208
+
209
+ MIT
package/README.zh.md ADDED
@@ -0,0 +1,187 @@
1
+ # dsh-claude-memory
2
+
3
+ 一个只读的 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 插件,把
4
+ **Claude Code 已有的项目记忆**接进 DSH —— 让 Claude Code 额度耗尽后,任务能在 DSH 里接着做。
5
+
6
+ English: [README.md](README.md)
7
+
8
+ ```
9
+ ~/.claude/CLAUDE.md ─┐
10
+ @import 已内联 │
11
+ ~/.claude/projects/<key>/ ├─► 收敛 ─► 脱敏 ─► 字节预算 ─► DSH system prompt
12
+ memory/MEMORY.md (索引) │ + claude_memory 工具
13
+ memory/<topic>.md (正文) ─┘
14
+ ```
15
+
16
+ ## 它做什么
17
+
18
+ - 把解析到的项目 `MEMORY.md` 索引注入 system prompt,同时注入用户级
19
+ `~/.claude/CLAUDE.md`(其 `@path` import 会被内联展开)。
20
+ - 注册一个 `claude_memory` 工具,让模型按需打开某条记忆、列项目、或跨主题搜索 ——
21
+ 完整正文默认不进 prompt。
22
+ - 在内容到达模型服务商**之前**就把凭据形状的文本打码。
23
+ - 绝不写入、移动或删除 Claude home 下的任何文件。
24
+
25
+ ## 安装
26
+
27
+ ```bash
28
+ dsh plugin --profile web add dsh-claude-memory
29
+ ```
30
+
31
+ 需要重启 profile —— `dsh.profile.bundles` 里的新 bundle 是启动时读取的,不热加载。
32
+
33
+ 从本地目录安装:
34
+
35
+ ```bash
36
+ dsh plugin --profile web add /path/to/dsh-claude-memory
37
+ ```
38
+
39
+ 验证配置树:
40
+
41
+ ```bash
42
+ dsh --profile web --dump-config | grep -A 10 claude-memory
43
+ ```
44
+
45
+ ## 配置
46
+
47
+ 默认值在包内的 `cordis.patch.yml`;可在 profile 的 patch 层或 `--patch` 覆盖层里改。
48
+
49
+ | 字段 | 默认 | 含义 |
50
+ |---|---|---|
51
+ | `claudeHome` | `~/.claude` | Claude Code home,所有读取都收敛在这个根下 |
52
+ | `cwd` | `process.cwd()` | **仅兜底**。会话的 `agent.session.header.cwd` 永远优先 |
53
+ | `includeDescendants` | `true` | 是否列出有记忆的兄弟/子项目 |
54
+ | `descendantLimit` | `12` | 最多列出几个其他项目 |
55
+ | `maxIndexBytes` | `24000` | 注入记忆块的字节预算 |
56
+ | `maxGlobalBytes` | `6000` | `CLAUDE.md` 加内联 import 的字节预算 |
57
+ | `enableMemory` | `true` | 是否注入记忆块 |
58
+ | `enableGlobalInstructions` | `true` | 是否注入用户级指令 |
59
+ | `enableTool` | `true` | 是否注册 `claude_memory` 工具 |
60
+ | `redactMode` | `on` | `on` 打码、`report` 只统计、`off` 关闭 |
61
+ | `refreshMs` | `20000` | prompt 组装时若缓存超过此值就重读 |
62
+
63
+ ## 实际进入模型的内容
64
+
65
+ 两个 system prompt 段落(order 10 / 11,紧随部署 persona 之后):
66
+
67
+ 1. **`claude-memory:global`** —— `~/.claude/CLAUDE.md`,`@path` 已内联。DSH 自带的指令
68
+ 加载器**不解析 import**,且读的是 `$DSH_HOME/AGENTS.md` 而非 `~/.claude/CLAUDE.md`,
69
+ 所以这里是用户级 Claude Code 记忆唯一的通路。
70
+ 2. **`claude-memory:memory`** —— 解析到的项目 `MEMORY.md` 索引,外加按新鲜度排序的其他
71
+ 项目列表。
72
+
73
+ 完整正文只通过工具按需返回,一次一个文件,单次 20 KB 上限。
74
+
75
+ ## 项目解析
76
+
77
+ 决定"该读哪份记忆"的是**会话的工作目录**,不是 `dsh` 服务启动的目录 —— 服务从某个
78
+ checkout 启动、会话在另一个目录跑的时候,两者必然不同。
79
+
80
+ 解析顺序:
81
+
82
+ 1. **exact** —— `<home>/projects/<cwd 编码>/memory/` 存在;
83
+ 2. **git-root** —— 外层 git 仓库根对应的键有记忆;
84
+ 3. **freshest** —— 都没有时,在祖先与子项目里选索引更新时间最新的(并明确告知模型这是猜测)。
85
+
86
+ 规则 2 的存在是因为 **Claude Code 把记忆归档在 git 仓库根下,而不是原始工作目录** ——
87
+ 见下方案例研究。规则 2、3 下其他项目按新鲜度倒序列出,最新那个一次工具调用就能取。
88
+
89
+ `agent.session.header.cwd` 与第一方 `dsh-agent-instructions` 读的是同一个来源。段落先以
90
+ 全局注册作兜底,再在 `agent/created` 时**按 agent 作用域 shadow**;工具则按调用方
91
+ `exec.agent` 逐次解析,因此子 agent 或在别处启动的会话看到的是自己的项目。
92
+
93
+ ## `claude_memory` 工具
94
+
95
+ | action | 参数 | 返回 |
96
+ |---|---|---|
97
+ | `projects` | `limit?` | 所有有记忆的项目、条数、当前标记 |
98
+ | `index` | `project?` | 某个项目的 `MEMORY.md` |
99
+ | `read` | `project?`、`file?` | 某个主题文件;不给 `file` 则列出主题 |
100
+ | `search` | `query`、`project?`、`limit?` | 匹配行,格式 `file:line: text` |
101
+
102
+ `project` 可传完整键、键后缀或唯一子串。所有返回都过同一个脱敏器并受 20 KB 上限约束。
103
+
104
+ ## 安全模型
105
+
106
+ 威胁模型很具体:为 A 厂商模型写的笔记,即将发给 B 厂商。
107
+
108
+ - **只读**:没有任何代码路径写入、移动或删除 `claudeHome` 下的文件。
109
+ - **收敛**:每个路径都经 `realpath` 解析且必须落在 `claudeHome` 内;指向外部的符号链接
110
+ 会被拒绝;含路径分隔符的主题名会被拒绝。
111
+ - **注入前脱敏**:13 条规则覆盖厂商 key 形状、Bearer token、PEM 块、JWT、带熵阈值的
112
+ `password`/`token`/`secret` 赋值、内联凭据的连接串、长 hex 串。误报代价是一行被打码,
113
+ 漏报代价是把凭据发出去 —— 所以策略偏保守。
114
+ - **不可信框定**:注入块明确告诉模型这些是背景笔记而非指令,记忆文本不能操纵 agent。
115
+ - **零依赖**:只 import `node:*`,信任链里没有第三方代码,且在 `node_modules` 为空
116
+ (不含 harness 包)的 profile 里也能解析。
117
+ - **prompt 文本是字符串**:provider 读同步刷新的缓存,永不返回 Promise。
118
+
119
+ 脱敏是基于模式的,不是分类器,抓不住"不像凭据的凭据"。用 `redactMode: report` 审计
120
+ "哪些会被打码",用 `enableMemory: false` 作为总开关。
121
+
122
+ ## 测试
123
+
124
+ ```bash
125
+ npm test # smoke + plugin + schema + live
126
+ npm run test:unit # 仅 fixture,不需要真实 ~/.claude
127
+ ```
128
+
129
+ | 文件 | 覆盖范围 |
130
+ |---|---|
131
+ | `test/smoke.mjs` | 路径、脱敏、存储、预算、工具 —— 全部跑在系统临时目录里的合成 fixture 上 |
132
+ | `test/plugin.mjs` | 假 Cordis ctx 下的 loader 契约,含 agent 作用域 shadow |
133
+ | `test/schema.mjs` | 手写工具 schema 过真实 `@deepseek-ai/dsh-tools` 校验器;无 DSH 时跳过 |
134
+ | `test/live.mjs` | 可选:对真实 `~/.claude` 检查"没有凭据形状文本进入 prompt";无 store 时跳过 |
135
+
136
+ 共 76 项断言,无网络、无模型调用。
137
+
138
+ ## 案例研究:两件容易做错的事
139
+
140
+ 两个发现都来自阅读生态里已有的插件与一份真实记忆库。对任何"桥接另一个 agent 文件"的
141
+ DSH 插件都适用。
142
+
143
+ ### 1. prompt provider 是同步的 —— `async` provider 会渲染成 `Promise`
144
+
145
+ `dsh-system-prompt` 解析段落与上下文文本时**不做 await**(`lib/index.js:330,337`),随后
146
+ 插值器调用 `text.indexOf`(`lib/index.js:152`)。所以声明成 `async () => string` 的 provider
147
+ 返回的是 `Promise` 而不是字符串。
148
+
149
+ 生态里最知名的 Claude Code 桥接插件
150
+ ([`YYTbit/dsh-plugin-claude-bridge`](https://github.com/YYTbit/dsh-plugin-claude-bridge),
151
+ `src/index.ts:75,92,107`)注册的正是 async provider。**能加载不等于能渲染** —— 插件挂载
152
+ 正常,组装时才失败。本插件用同步刷新的缓存,返回普通字符串。
153
+
154
+ ### 2. Claude Code 把记忆归档在 git 仓库根下
155
+
156
+ 记忆位于 `~/.claude/projects/<项目路径编码>/memory/`,路径编码是项目目录把 `/` 换成 `-`。
157
+ 问题在于**哪个目录算项目**。在作者机器上,对一个位于更大仓库内、自身没有 `.git` 的文档
158
+ hub 实测:
159
+
160
+ | 观察项 | 值 |
161
+ |---|---|
162
+ | 该 hub 会话记录的 `cwd` | hub 目录 |
163
+ | 它写入 `memory/` 的 `Write`/`Edit` 调用 | 12 次,**全部**落在外层仓库的键下 |
164
+ | 该会话引用外层仓库 `memory/MEMORY.md` 的次数 | 235 |
165
+ | 引用它自己目录 `memory/` 路径的次数 | **0** |
166
+ | hub / 父目录 / 祖父目录是否有 `.git` | 无 / 无 / **有** |
167
+
168
+ **会话记录**按 cwd 编码存放,**记忆按 git 仓库根存放**。按 `process.cwd()` 解析、或只认
169
+ 精确 cwd 的桥接插件,在任何 hub 目录下都会静默读错项目的笔记。另外记忆目录是**按需创建**
170
+ 的:那台机器 50 个项目目录里只有 20 个有非空索引,21 个是空 `memory/` —— 所以"没有记忆
171
+ 目录"很正常,不代表那个目录没被用过。
172
+
173
+ ## 已知边界
174
+
175
+ - **不读会话流水**。它读记忆文件,不读 transcript。"我一小时前在做什么"需要 `*.jsonl`,
176
+ 不在本插件范围内。
177
+ - **不强制 Claude Code 自己的索引上限**。Claude Code 只加载 `MEMORY.md` 的前 200 行或
178
+ 25 KB,超限的条目在那边会被静默丢弃;本插件按 `maxIndexBytes` 注入,不对该上限告警。
179
+ - **项目键有损**。`-` 既是分隔符也是目录名的合法字符,所以展示路径靠遍历文件系统反查,
180
+ 失败时退回键尾。
181
+ - **没有文件监听**。新鲜度靠 prompt 组装时检查 `refreshMs`,所以一轮对话中途的改动会在
182
+ 下一次组装生效。
183
+ - **只注入解析到的那一个项目的索引**。其他项目需要工具调用。
184
+
185
+ ## 许可证
186
+
187
+ MIT
@@ -0,0 +1,21 @@
1
+ # dsh-claude-memory — profile patch layer.
2
+ #
3
+ # Inserted by `dsh plugin --profile <name> add <path-to-this-package>`.
4
+ # The row is deliberately minimal: the plugin's own module export declares
5
+ # `inject: ['systemPrompt', 'tools']`, so no `inject` key is set here (setting
6
+ # an empty one would shadow the declaration).
7
+ - insert:
8
+ - id: claude-memory
9
+ name: dsh-claude-memory
10
+ config:
11
+ # System-prompt budget for the current project's MEMORY.md index.
12
+ maxIndexBytes: 24000
13
+ # Budget for the user-global ~/.claude/CLAUDE.md (with @imports inlined).
14
+ maxGlobalBytes: 6000
15
+ # List child projects that have memory (e.g. sub-repos of a hub dir).
16
+ includeDescendants: true
17
+ descendantLimit: 12
18
+ # 'on' masks credential-shaped text; 'report' counts only; 'off' disables.
19
+ redactMode: on
20
+ # Re-read the store when a prompt is assembled and the cache is older.
21
+ refreshMs: 20000
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "dsh-claude-memory",
3
+ "version": "0.1.0",
4
+ "description": "Read-only DeepSeek Harness plugin that surfaces Claude Code's project memory, redacted and byte-budgeted",
5
+ "type": "module",
6
+ "main": "src/index.js",
7
+ "exports": {
8
+ ".": "./src/index.js"
9
+ },
10
+ "files": [
11
+ "src",
12
+ "cordis.patch.yml",
13
+ "README.md",
14
+ "README.zh.md",
15
+ "LICENSE"
16
+ ],
17
+ "engines": {
18
+ "node": "^22.19.0 || >=24.0.0"
19
+ },
20
+ "scripts": {
21
+ "test": "node test/smoke.mjs && node test/plugin.mjs && node test/schema.mjs && node test/live.mjs",
22
+ "test:unit": "node test/smoke.mjs && node test/plugin.mjs",
23
+ "test:live": "node test/live.mjs",
24
+ "prepublishOnly": "npm run test:unit"
25
+ },
26
+ "dsh": {
27
+ "bundle": {
28
+ "patch": "./cordis.patch.yml"
29
+ }
30
+ },
31
+ "keywords": [
32
+ "dsh-plugin",
33
+ "deepseek-harness",
34
+ "claude-code",
35
+ "memory",
36
+ "agent-memory",
37
+ "context"
38
+ ],
39
+ "author": "GodCC6",
40
+ "license": "MIT",
41
+ "publishConfig": {
42
+ "registry": "https://registry.npmjs.org/",
43
+ "access": "public"
44
+ },
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "git+https://github.com/GodCC6/dsh-claude-memory.git"
48
+ },
49
+ "homepage": "https://github.com/GodCC6/dsh-claude-memory#readme",
50
+ "bugs": {
51
+ "url": "https://github.com/GodCC6/dsh-claude-memory/issues"
52
+ }
53
+ }