dev-memory-cli 0.24.0 → 0.25.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Dev Memory Skill Suite
2
2
 
3
- Dev Memory Skill Suite 为 Codex、Claude 等 coding agent 提供跨会话开发记忆能力。
3
+ Dev Memory Skill Suite 为 Codex、Claude Code、Trae / Trae CN 等 coding agent 提供跨会话开发记忆能力。
4
4
 
5
5
  开发知识存储在用户目录,并按 **仓库身份 + Git 分支** 隔离。分支层保存当前工作的目标、约束和上下文,repo 层保存跨分支长期有效的规则与资料入口。Git 负责提交与代码历史,dev-memory 负责对后续开发仍有价值的语义信息。
6
6
 
@@ -57,8 +57,10 @@ npm install -g dev-memory-cli
57
57
  # 在当前仓库安装生命周期 hook
58
58
  dev-memory-cli install-hooks codex
59
59
  dev-memory-cli install-hooks claude
60
+ dev-memory-cli install-hooks trae
61
+ dev-memory-cli install-hooks trae-cn
60
62
 
61
- # 或一次安装两套
63
+ # 或一次安装全部支持的客户端
62
64
  dev-memory-cli install-hooks --all
63
65
  ```
64
66
 
@@ -70,6 +72,8 @@ dev-memory-cli install-hooks --all --global
70
72
 
71
73
  CLI 也可通过 `npx -y dev-memory-cli ...` 按需执行。Skill 与 hook 相互独立,安装 skill 不会修改本地 hook 配置。
72
74
 
75
+ Trae 的 Hook 配置按客户端隔离:国际版写入 `.trae/hooks.json`,国内版写入 `.trae-cn/hooks.json`;加 `--global` 时分别写入用户目录下的同名路径。已有 Hook 会保留,重复安装只更新 dev-memory 自己的条目。
76
+
73
77
  Codex Desktop 没有本仓库依赖的项目生命周期 hook。安装每日扫描任务可覆盖 Codex CLI 和 Desktop 共同写入的本机会话文件:
74
78
 
75
79
  ```bash
@@ -178,18 +182,18 @@ git config --local dev-memory.worktreeWriteback true
178
182
 
179
183
  ## 生命周期 Hook
180
184
 
181
- | 事件 | Codex CLI | Claude Code CLI | 行为 |
182
- | --- | :-: | :-: | --- |
183
- | `SessionStart` | ✓ | ✓ | 刷新 Git 派生索引,注入浓缩记忆和完整文件路径;同一 session 幂等 |
184
- | `Stop` | ✓ | ✓ | 记录轻量 HEAD marker;Codex 同时登记待扫描会话,不启动模型 |
185
- | `PreCompact` | | ✓ | 兼容占位,当前不执行额外刷新 |
186
- | `SessionEnd` | | ✓ | 记录最终 HEAD,并把 transcript 总结任务放入后台队列 |
185
+ | 事件 | Codex CLI | Claude Code CLI | Trae | Trae CN | 行为 |
186
+ | --- | :-: | :-: | :-: | :-: | --- |
187
+ | `SessionStart` | ✓ | ✓ | ✓ | ✓ | 刷新 Git 派生索引,注入浓缩记忆和完整文件路径;同一 session 幂等 |
188
+ | `Stop` | ✓ | ✓ | ✓ | ✓ | 记录轻量 HEAD marker;有可识别会话信息时登记扫描候选,不启动模型 |
189
+ | `PreCompact` | | ✓ | | | 兼容占位,当前不执行额外刷新 |
190
+ | `SessionEnd` | | ✓ | | | 记录最终 HEAD,并把 transcript 总结任务放入后台队列 |
187
191
 
188
192
  ### 会话总结
189
193
 
190
- Claude Code CLI 通过 `SessionEnd` 创建后台总结任务。Codex CLI 没有 `SessionEnd`,其 `Stop` hook 只登记候选;Codex Desktop 不依赖 hook。Codex 两种入口统一由每日扫描器读取 `~/.codex/sessions` 和 `~/.codex/archived_sessions`。
194
+ Claude Code CLI 通过 `SessionEnd` 创建后台总结任务。Codex、Trae Trae CN 当前没有该事件:它们的 `Stop` hook 只做轻量记录,并在 payload 带有可识别会话信息时登记扫描候选,不会在每轮回复后启动总结模型。现有定时扫描器只解析 Codex CLI / Desktop 写入的 `~/.codex/sessions` 和 `~/.codex/archived_sessions`;Trae Hook 支持当前覆盖 SessionStart 恢复与轻量 HEAD 刷新,不宣称扫描其私有会话存储。
191
195
 
192
- 任务触发端与总结执行端相互独立。Claude 的即时 worker 和 Codex 定时扫描器都可以使用 `coco`、`codex` 或 `claude` CLI。扫描器在 `~/.dev-memory/config.json` 的 `session_scan` 中内置三个可配置 preset,默认按 `coco → codex → claude` 选择第一个可用命令;每个 preset 可指定模型、profile、额外参数和环境变量。
196
+ 任务触发端与总结执行端相互独立。Claude 的即时 worker 和 Codex 定时扫描器都可以使用 `coco`、`codex` 或 `claude` CLI。扫描器在 `~/.dev-memory/config.json` 的 `session_scan` 中内置三个可配置 preset,默认按 `claude → codex` 选择第一个可用命令;`coco` preset 继续保留,可显式启用或加入顺序。每个 preset 可指定模型、profile、额外参数和环境变量。
193
197
 
194
198
  总结输入包含全部尚未处理的 user/assistant 语义消息和现有 dev-memory,不按“最近几条”截尾,也不截断单条消息。长会话按顺序分块并最终归并;工具调用流水账、system 消息和 reasoning 不参与语义总结。输出限定为结构化 JSON,用于新增或修正 decisions、risks、glossary、file map 和 repo 共享记忆;时效性的“当前进展”“下一步”“当前阶段”不会写入。
195
199
 
@@ -332,7 +336,7 @@ dev-memory-cli summary <extract-core>
332
336
  dev-memory-cli session-scan <run|replay|install|status|stats|history|show|uninstall|config>
333
337
  dev-memory-cli hook <session-start|pre-compact|stop|session-end>
334
338
  dev-memory-cli ui
335
- dev-memory-cli install-hooks <codex|claude|--all>
339
+ dev-memory-cli install-hooks <codex|claude|trae|trae-cn|--all>
336
340
  ```
337
341
 
338
342
  具体参数以各子命令的 `--help` 为准。
@@ -358,7 +362,7 @@ lib/maintenance/ # 按需注入独立维护 Agent 的 prompt
358
362
  lib/ui-server.js # 本地管理面板服务
359
363
  lib/ui-app.html # 管理面板前端
360
364
  scripts/hooks/ # 生命周期 hook 实现
361
- hooks/ # Codex / Claude hook 模板
365
+ hooks/ # Codex / Claude Code / Trae hook 模板
362
366
  skills/dev-memory-read/ # 唯一常驻 Skill
363
367
  tests/ # Python 测试
364
368
  docs/diagrams/ # README 图表及源文件
package/bin/dev-memory.js CHANGED
@@ -9,6 +9,7 @@ const PACKAGE_ROOT = path.resolve(__dirname, "..");
9
9
  const DEFAULT_STORAGE_ROOT = path.join(os.homedir(), ".dev-memory", "repos");
10
10
  const DEFAULT_CONFIG_PATH = process.env.DEV_MEMORY_CONFIG_PATH || path.join(os.homedir(), ".dev-memory", "config.json");
11
11
  const WORKSPACE_CONFIG_NAME = ".dev-memory-workspace.json";
12
+ const SUPPORTED_HOOK_AGENTS = ["codex", "claude", "trae", "trae-cn"];
12
13
 
13
14
  function fail(message) {
14
15
  process.stderr.write(`ERROR: ${message}\n`);
@@ -191,32 +192,54 @@ function ensureSessionSummaryConfig() {
191
192
  function templatePathForAgent(agent) {
192
193
  if (agent === "codex") return packageScript("hooks", "codex-hooks.json");
193
194
  if (agent === "claude") return packageScript("hooks", "hooks.json");
195
+ if (agent === "trae" || agent === "trae-cn") return packageScript("hooks", "trae-hooks.json");
194
196
  fail(`unsupported agent: ${agent}`);
195
197
  }
196
198
 
197
199
  function targetPathForAgent(agent, repoRoot) {
198
200
  if (agent === "codex") return path.join(repoRoot, ".codex", "hooks.json");
199
201
  if (agent === "claude") return path.join(repoRoot, ".claude", "settings.local.json");
202
+ if (agent === "trae") return path.join(repoRoot, ".trae", "hooks.json");
203
+ if (agent === "trae-cn") return path.join(repoRoot, ".trae-cn", "hooks.json");
200
204
  fail(`unsupported agent: ${agent}`);
201
205
  }
202
206
 
203
207
  function globalTargetPathForAgent(agent) {
204
208
  if (agent === "codex") return path.join(os.homedir(), ".codex", "hooks.json");
205
209
  if (agent === "claude") return path.join(os.homedir(), ".claude", "settings.json");
210
+ if (agent === "trae") return path.join(os.homedir(), ".trae", "hooks.json");
211
+ if (agent === "trae-cn") return path.join(os.homedir(), ".trae-cn", "hooks.json");
206
212
  fail(`unsupported agent: ${agent}`);
207
213
  }
208
214
 
215
+ function hookListIdentity(item) {
216
+ if (!item || typeof item !== "object") return null;
217
+ if (typeof item.id === "string" && item.id) {
218
+ return `id:${item.id}\u0000${item.matcher || ""}`;
219
+ }
220
+ const nestedHooks = Array.isArray(item.hooks) ? item.hooks : [];
221
+ for (const hook of nestedHooks) {
222
+ const command = hook && typeof hook.command === "string" ? hook.command.trim() : "";
223
+ const match = command.match(/(?:^|\s)dev-memory-cli\s+hook\s+(session-start|pre-compact|stop|session-end)(?:\s|$)/);
224
+ if (match) return `dev-memory-command:${match[1]}`;
225
+ }
226
+ return null;
227
+ }
228
+
209
229
  function mergeHookLists(existingItems, incomingItems) {
210
230
  const merged = existingItems.map((item) => ({ ...item }));
211
231
  const index = new Map();
212
- merged.forEach((item, i) => index.set(`${item.id || ""}\u0000${item.matcher || ""}`, i));
232
+ merged.forEach((item, i) => {
233
+ const key = hookListIdentity(item);
234
+ if (key) index.set(key, i);
235
+ });
213
236
  for (const item of incomingItems) {
214
237
  const copied = { ...item };
215
- const key = `${copied.id || ""}\u0000${copied.matcher || ""}`;
216
- if (index.has(key)) {
238
+ const key = hookListIdentity(copied);
239
+ if (key && index.has(key)) {
217
240
  merged[index.get(key)] = copied;
218
241
  } else {
219
- index.set(key, merged.length);
242
+ if (key) index.set(key, merged.length);
220
243
  merged.push(copied);
221
244
  }
222
245
  }
@@ -224,7 +247,7 @@ function mergeHookLists(existingItems, incomingItems) {
224
247
  }
225
248
 
226
249
  function mergeConfig(existingConfig, templateConfig) {
227
- const result = { ...existingConfig };
250
+ const result = { ...templateConfig, ...existingConfig };
228
251
  const existingHooks = existingConfig.hooks || {};
229
252
  const templateHooks = templateConfig.hooks || {};
230
253
  const mergedHooks = {};
@@ -272,7 +295,7 @@ function installHooksForAgent(agent, options) {
272
295
 
273
296
  function commandInstallHooks(positional, options) {
274
297
  const isAll = Boolean(options.all);
275
- const agents = isAll ? ["codex", "claude"] : [positional[0] || options.agent || "codex"];
298
+ const agents = isAll ? SUPPORTED_HOOK_AGENTS : [positional[0] || options.agent || "codex"];
276
299
  const reports = agents.map((agent) => installHooksForAgent(agent, options));
277
300
  process.stdout.write(`${JSON.stringify(isAll ? reports : reports[0], null, 2)}\n`);
278
301
  }
@@ -794,7 +817,7 @@ function commandBranch(rawArgs) {
794
817
  function printHelp() {
795
818
  process.stdout.write(`Usage:
796
819
  dev-memory-cli hook <session-start|pre-compact|stop|session-end> [--repo PATH]
797
- dev-memory-cli install-hooks <codex|claude> [--repo PATH] [--global]
820
+ dev-memory-cli install-hooks <codex|claude|trae|trae-cn> [--repo PATH] [--global]
798
821
  dev-memory-cli install-hooks --all [--repo PATH] [--global]
799
822
  dev-memory-cli ui [--port N] [--host HOST] [--no-open] [--read-only]
800
823
  dev-memory-cli workspace <show|primary> [...]
package/hooks/README.md CHANGED
@@ -1,16 +1,24 @@
1
1
  # Lifecycle Hooks
2
2
 
3
- 本项目使用 agent 生命周期 hook,不使用 Git hook。Claude Code 与 Codex 的可用事件不同,模板分别维护。
3
+ 本项目使用 agent 生命周期 hook,不使用 Git hook。Claude Code、Codex、TraeTrae CN 的可用事件和配置目录不同,模板分别维护。
4
4
 
5
5
  ## 当前仓库里的接入方式
6
6
 
7
7
  - repo-local 配置位置:
8
8
  - Claude: `.claude/settings.local.json`
9
9
  - Codex: `.codex/hooks.json`
10
+ - Trae: `.trae/hooks.json`
11
+ - Trae CN: `.trae-cn/hooks.json`
12
+ - user-level 配置位置:
13
+ - Claude: `~/.claude/settings.json`
14
+ - Codex: `~/.codex/hooks.json`
15
+ - Trae: `~/.trae/hooks.json`
16
+ - Trae CN: `~/.trae-cn/hooks.json`
10
17
  - 可复用模板:
11
18
  - Claude: [hooks/hooks.json](hooks.json)
12
19
  - Codex: [hooks/codex-hooks.json](codex-hooks.json)
13
- - `dev-memory-cli` 是这两套配置共用的稳定执行入口
20
+ - Trae / Trae CN: [hooks/trae-hooks.json](trae-hooks.json)
21
+ - `dev-memory-cli` 是所有配置共用的稳定执行入口
14
22
  - hook 仅在模板内容合并到对应 agent 配置后生效
15
23
 
16
24
  ### Codex 快速安装
@@ -34,18 +42,21 @@ sh -c "$(curl -fsSL https://raw.githubusercontent.com/xluos/dev-memory-skill-sui
34
42
  ```bash
35
43
  dev-memory-cli install-hooks codex
36
44
  dev-memory-cli install-hooks claude
45
+ dev-memory-cli install-hooks trae
46
+ dev-memory-cli install-hooks trae-cn
47
+ dev-memory-cli install-hooks --all
37
48
  ```
38
49
 
39
50
  已有旧配置如果还写着 `dev-memory hook ...` 或 `npx dev-memory hook ...`,重新执行安装命令会按 hook id 覆盖为 `dev-memory-cli hook ...`。
40
51
 
41
52
  ## Hook 行为
42
53
 
43
- | 事件 | Codex CLI | Claude Code CLI | 行为 |
44
- | --- | :-: | :-: | --- |
45
- | `SessionStart` | ✓ | ✓ | 读取当前 repo+branch 记忆并注入会话;同一 session 的重复触发幂等跳过 |
46
- | `Stop` | ✓ | ✓ | 每次回复后记录轻量 HEAD marker;Codex 同时登记定时扫描候选 |
47
- | `PreCompact` | | ✓ | 兼容占位;当前不执行额外刷新 |
48
- | `SessionEnd` | | ✓ | 记录最终 HEAD,创建 transcript 总结任务并启动后台 worker |
54
+ | 事件 | Codex CLI | Claude Code CLI | Trae | Trae CN | 行为 |
55
+ | --- | :-: | :-: | :-: | :-: | --- |
56
+ | `SessionStart` | ✓ | ✓ | ✓ | ✓ | 读取当前 repo+branch 记忆并注入会话;同一 session 的重复触发幂等跳过 |
57
+ | `Stop` | ✓ | ✓ | ✓ | ✓ | 每次回复后记录轻量 HEAD marker;payload 有会话信息时登记扫描候选 |
58
+ | `PreCompact` | | ✓ | | | 兼容占位;当前不执行额外刷新 |
59
+ | `SessionEnd` | | ✓ | | | 记录最终 HEAD,创建 transcript 总结任务并启动后台 worker |
49
60
 
50
61
  `SessionStart` 的幂等记录位于 `<repo-memory>/jobs/session-start/injected/*.json`。重复触发只记录 skip 日志,不重复注入上下文。
51
62
 
@@ -53,7 +64,7 @@ dev-memory-cli install-hooks claude
53
64
 
54
65
  ### 生效范围
55
66
 
56
- `SessionEnd` 自动总结仅由 **Claude Code CLI** 的生命周期事件触发。Codex CLI hook 模板没有 `SessionEnd`;它的 `Stop` 只登记候选,不在每轮回答后启动模型。Codex Desktop 不使用这组项目 hook。
67
+ `SessionEnd` 自动总结仅由 **Claude Code CLI** 的生命周期事件触发。Codex、Trae Trae CN 模板都不注册 `SessionEnd`;它们的 `Stop` 只做轻量记录,不在每轮回答后启动模型。Codex Desktop 不使用这组项目 hook。
57
68
 
58
69
  总结任务的触发端与执行端是两个独立概念:
59
70
 
@@ -138,13 +149,13 @@ dev-memory-cli session-scan status
138
149
 
139
150
  ### 执行器配置
140
151
 
141
- `~/.dev-memory/config.json` 中的 `session_scan` 独立配置扫描执行器。默认提供 `coco`、`codex`、`claude` 三个 preset,并按顺序选择第一个已安装且启用的命令:
152
+ `~/.dev-memory/config.json` 中的 `session_scan` 独立配置扫描执行器。默认提供 `coco`、`codex`、`claude` 三个 preset,并按 `claude → codex` 选择第一个已安装且启用的命令;`coco` preset 为兼容保留,可显式加入 `order`:
142
153
 
143
154
  ```json
144
155
  {
145
156
  "session_scan": {
146
157
  "executor": "auto",
147
- "order": ["coco", "codex", "claude"],
158
+ "order": ["claude", "codex"],
148
159
  "schedule_times": ["03:00", "13:00"],
149
160
  "skip_when_computer_active": true,
150
161
  "active_within_minutes": 10,
@@ -214,6 +225,8 @@ dev-memory-cli session-scan uninstall
214
225
 
215
226
  - Claude 把 [hooks/hooks.json](hooks.json) 合并到 `.claude/settings.local.json`。
216
227
  - Codex CLI 把 [hooks/codex-hooks.json](codex-hooks.json) 合并到 `.codex/hooks.json`。
228
+ - Trae 把 [hooks/trae-hooks.json](trae-hooks.json) 合并到 `.trae/hooks.json`。
229
+ - Trae CN 把同一模板合并到 `.trae-cn/hooks.json`;模板声明 Trae 要求的 `version: 1`。
217
230
  - Codex Desktop 通过本地 rollout 定时扫描覆盖,不依赖项目 hook。
218
231
  - 其他仓库需要先安装 CLI,再安装对应 hook;hook 运行时统一调用 `dev-memory-cli hook ...`。
219
232
 
@@ -0,0 +1,29 @@
1
+ {
2
+ "version": 1,
3
+ "hooks": {
4
+ "SessionStart": [
5
+ {
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "dev-memory-cli hook session-start",
10
+ "timeout": 20,
11
+ "statusMessage": "Loading dev-memory context"
12
+ }
13
+ ]
14
+ }
15
+ ],
16
+ "Stop": [
17
+ {
18
+ "hooks": [
19
+ {
20
+ "type": "command",
21
+ "command": "dev-memory-cli hook stop",
22
+ "timeout": 15,
23
+ "statusMessage": "Updating dev-memory session marker"
24
+ }
25
+ ]
26
+ }
27
+ ]
28
+ }
29
+ }
@@ -126,7 +126,7 @@ def _deep_merge(base, override):
126
126
  def default_scan_config():
127
127
  return {
128
128
  "executor": "auto",
129
- "order": ["coco", "codex", "claude"],
129
+ "order": ["claude", "codex"],
130
130
  "executors": json.loads(json.dumps(DEFAULT_EXECUTORS)),
131
131
  "schedule_times": ["03:00", "13:00"],
132
132
  "skip_when_computer_active": True,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dev-memory-cli",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "description": "CLI for dev-memory hooks and repo-local setup (formerly @xluos/dev-assets-cli)",
5
5
  "license": "MIT",
6
6
  "repository": {