@fanchao8609/agent_brain_sync 1.2.3 → 1.3.1

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
@@ -62,10 +62,10 @@ abs init # 建 .brain/ 图谱,只需一次
62
62
  abs load # 开机读状态(路线 + 看板 + 最近流水)
63
63
  abs todo # 看板 Today / In Progress / Blocked / Done
64
64
 
65
- abs task start TASK-1 --note "要做什么"
66
- abs task note TASK-1 --note "改到 X 文件 L40" # 实时断点
67
- abs task blocked TASK-1 --note "卡在哪"
68
- abs task done TASK-1
65
+ abs todo add TASK-1 --note "要做什么"
66
+ abs todo note TASK-1 --note "改到 X 文件 L40" # 实时断点
67
+ abs todo blocked TASK-1 --note "卡在哪"
68
+ abs todo done TASK-1
69
69
 
70
70
  abs note "一句话经验" --tags 坑,docker # 经验暂存 → sources/
71
71
  abs log "完成 X" # 记一行流水;abs log 无参 = 查看
@@ -74,10 +74,13 @@ abs status # 当前项目 + 图谱概要
74
74
  abs lint # 体检:死链/孤岛/超尺寸/堆积
75
75
  ```
76
76
 
77
+ > `abs todo start` 与 `abs todo add` 等价(都登记任务)。
78
+ > 旧版 `abs task ...` / `abs board` 已改名,会报错并提示新写法。
79
+
77
80
  ### 工作流
78
81
 
79
82
  - **hook 自动**:宿主生命周期事件写技术流水到 `~/.abs/log/`
80
- - **实时层(你/AI 手动)**:任务和经验在边界处立刻用 `abs task` / `abs note` 落盘
83
+ - **实时层(你/AI 手动)**:任务和经验在边界处立刻用 `abs todo` / `abs note` 落盘
81
84
  - **收尾层**:`abs wrapup` 在 Stop 时快照未完成任务;下个会话开头对账 todo、沉淀经验、修 index
82
85
 
83
86
  ---
package/bin/abs.js CHANGED
@@ -82,43 +82,83 @@ function parseArgv(args) {
82
82
 
83
83
  const usage = `abs — agent-brain-sync 记忆工具
84
84
 
85
- 用法:
86
- abs init [--repair] 建 .brain/ 图谱;结构不完整时报明细,--repair 只补缺不覆盖
85
+ 读:
87
86
  abs load 开机读状态 (index/todo/log)
88
- abs todo 查看任务看板 (board 的正名)
89
- abs index 查看图谱索引 index.md
90
- abs log 无参查看流水 log.md;带参追加一行: abs log "标题" (仅用户/AI 主动记, hook 事件走 ~/.abs/log/hooks.log)
91
- abs status 显示当前项目 + 图谱概要
92
- abs task start <id> [--note ..] [--section Today / In Progress] 登记任务
93
- abs task note <id> --note "断点/进度" 实时落 ↳ 断点 行
94
- abs task blocked <id> --note "卡点原因" 移入 Blocked 区
95
- abs task done <id> 完成并归位 Done
87
+ abs todo 任务看板 Today / In Progress / Blocked / Done
88
+ abs index 图谱索引 index.md
89
+ abs log 流水 log.md
90
+ abs status 当前项目 + 图谱概要
91
+
92
+ 写:
93
+ abs todo add <id> [--note ..] [--section ..] 登记任务 (start 同义)
94
+ abs todo note <id> --note "断点/进度" 实时落 ↳ 断点 行
95
+ abs todo blocked <id> --note "卡点原因" 移入 Blocked 区
96
+ abs todo done <id> 完成并归位 Done
97
+ abs log "完成 X:…" 记一行工作成果 (无参=查看)
96
98
  abs note "经验一句话" [--tags 坑,docker] 经验实时暂存 → sources/
99
+
100
+ 维护:
97
101
  abs query <词1> [词2 …] 检索 .brain/ 知识页 (多词 OR)
98
102
  abs lint 图谱体检 (死链/孤岛/超尺寸/堆积)
99
- abs wrapup 快照当前未完成任务到 ~/.abs/log/wrapup.log (收尾保险)
100
- abs install [--agent <claude-code|opencode|codex|pi>] 安装 MCP+hook+skill
101
- abs uninstall [--agent <...>] 卸载
103
+ abs init [--repair] 建 .brain/ 图谱; 结构不完整时报明细, --repair 只补缺不覆盖
104
+ abs install [--agent <宿主>] 安装 MCP+hook+skill (宿主: claude-code/codex/opencode/pi)
105
+ abs uninstall [--agent <...>] 卸载
102
106
  abs update 升级到最新版并刷新四宿主 hook/skill
103
107
  abs --version 显示当前版本
104
108
  abs help 本帮助
109
+
110
+ 注: abs wrapup / abs teardown-check 是 hook 内部命令, 不需手动调用。
105
111
  `;
106
112
 
113
+ /**
114
+ * 拒绝多余的未知位置参数。
115
+ * 坑: 以前只读命令(如 abs todo)会静默忽略多余词 —— `abs todo add x` 照样打印看板、
116
+ * exit 0、不报错, 用户以为登记成功实际什么都没写。现在一律报错并给正确用法。
117
+ * @param {string[]} extra 收到的位置参数
118
+ * @param {string} fix 正确用法的提示行
119
+ */
120
+ function rejectExtra(extra, fix) {
121
+ if (!extra.length) return;
122
+ const q = extra.map((s) => `"${s}"`).join('、');
123
+ throw new Error(`✗ 不认识多余参数 ${q}\n 正确用法: ${fix}`);
124
+ }
125
+
126
+ // 已改名/已废弃命令 → 新写法(报错而非静默,避免用户白跑一趟)
127
+ const RENAMED = {
128
+ task: () => '命令已改名: abs task → abs todo\n 例: abs todo add <id> --note "…" / abs todo done <id>',
129
+ board: () => '命令已改名: abs board → abs todo',
130
+ };
131
+
132
+ // task/todo 共用的子命令 → 归一化后的 action
133
+ const TODO_ACTIONS = {
134
+ add: 'start',
135
+ start: 'start', // add 的别名(老习惯保留)
136
+ note: 'note',
137
+ blocked: 'blocked',
138
+ done: 'done',
139
+ };
140
+
107
141
  async function main() {
108
142
  const opts = parseArgv(rest);
109
143
  try {
144
+ if (RENAMED[cmd]) throw new Error(RENAMED[cmd]());
110
145
  switch (cmd) {
111
146
  case 'init': {
147
+ rejectExtra(opts._, 'abs init [--repair]');
112
148
  const msg = opts.repair
113
149
  ? await cmdRepair({ dir: opts.dir })
114
150
  : await cmdInit({ dir: opts.dir });
115
151
  console.log(msg);
116
152
  break;
117
153
  }
118
- case 'load': console.log(await cmdLoad({ dir: opts.dir })); break;
119
- case 'board': console.log(await cmdShow({ dir: opts.dir, view: 'todo' })); break;
120
- case 'todo': console.log(await cmdShow({ dir: opts.dir, view: 'todo' })); break;
121
- case 'index': console.log(await cmdShow({ dir: opts.dir, view: 'index' })); break;
154
+ case 'load':
155
+ rejectExtra(opts._, 'abs load');
156
+ console.log(await cmdLoad({ dir: opts.dir }));
157
+ break;
158
+ case 'index':
159
+ rejectExtra(opts._, 'abs index');
160
+ console.log(await cmdShow({ dir: opts.dir, view: 'index' }));
161
+ break;
122
162
  case 'log': {
123
163
  // 无参=查看 log.md;带参=追加一行 (用户/AI 主动记; hook 生命周期事件走技术日志 hooks.log, 不经这里)
124
164
  if (opts._.length) {
@@ -128,12 +168,29 @@ async function main() {
128
168
  }
129
169
  break;
130
170
  }
131
- case 'status': console.log(await cmdStatus({ dir: opts.dir })); break;
132
- case 'task': {
133
- const [action, id] = opts._;
134
- if (!action || !['start', 'done', 'blocked', 'note'].includes(action)) {
135
- throw new Error('abs task <start|done|blocked|note> <id>');
171
+ case 'status':
172
+ rejectExtra(opts._, 'abs status');
173
+ console.log(await cmdStatus({ dir: opts.dir }));
174
+ break;
175
+ // abs todo —— 无子命令=看板;带子命令=任务写操作
176
+ case 'todo': {
177
+ const [sub, id, ...rest2] = opts._;
178
+ if (!sub) {
179
+ rejectExtra([id, ...rest2].filter(Boolean), 'abs todo');
180
+ console.log(await cmdShow({ dir: opts.dir, view: 'todo' }));
181
+ break;
182
+ }
183
+ const action = TODO_ACTIONS[sub];
184
+ if (!action) {
185
+ throw new Error(
186
+ `✗ 未知子命令 "${sub}"\n` +
187
+ ` 可用: add / start / note / blocked / done\n` +
188
+ ` 看板: abs todo(不带参数)\n` +
189
+ ` 登记任务: abs todo add <id> --note "做什么"`,
190
+ );
136
191
  }
192
+ rejectExtra(rest2, `abs todo ${sub} <id>${action === 'done' ? '' : ' --note "…"'}`);
193
+ if (!id) throw new Error(`✗ 缺 <id>\n 用法: abs todo ${sub} <id>${action === 'done' ? '' : ' --note "…"'}`);
137
194
  console.log(await cmdTask({ dir: opts.dir, action, id, section: opts.section, note: opts.note }));
138
195
  break;
139
196
  }
@@ -149,10 +206,13 @@ async function main() {
149
206
  break;
150
207
  }
151
208
  case 'lint': {
209
+ rejectExtra(opts._, 'abs lint');
152
210
  console.log(await cmdLint({ dir: opts.dir }));
153
211
  break;
154
212
  }
213
+ // 内部命令(hook 专用,不出现在 help):Stop 时机械快照未完成任务
155
214
  case 'wrapup': {
215
+ rejectExtra(opts._, 'abs wrapup(内部命令, 供 hook 调用)');
156
216
  console.log(await cmdWrapup({ dir: opts.dir }));
157
217
  break;
158
218
  }
package/bin/mcp.js CHANGED
@@ -8,8 +8,10 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
8
8
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
9
9
  import { z } from 'zod';
10
10
  import { appendFile, mkdir } from 'node:fs/promises';
11
+ import { readFileSync } from 'node:fs';
11
12
  import { homedir } from 'node:os';
12
- import { join } from 'node:path';
13
+ import { join, dirname } from 'node:path';
14
+ import { fileURLToPath } from 'node:url';
13
15
  import { findBrainRoot } from '../src/index.js';
14
16
  import { cmdBoard, cmdLoad, cmdStatus, cmdTask, cmdQuery, cmdLint, cmdNote, cmdWrapup } from '../src/store.js';
15
17
 
@@ -44,13 +46,29 @@ function withTrace(name, handler) {
44
46
  };
45
47
  }
46
48
 
49
+ // 版本号从本包 package.json 读(曾硬编码 '0.1.0',与包版本脱节,宿主里看着困惑)
50
+ function pkgVersion() {
51
+ try {
52
+ const root = join(dirname(fileURLToPath(import.meta.url)), '..');
53
+ return JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')).version || 'unknown';
54
+ } catch { return 'unknown'; }
55
+ }
56
+
47
57
  const server = new McpServer({
48
58
  name: 'abs',
49
- version: '0.1.0',
59
+ version: pkgVersion(),
50
60
  });
51
61
 
62
+ // 统一注册入口(总是经 withTrace)。
63
+ // 坑: 以前 9 处工具各自直接调 server.tool(...) 而不包 withTrace, 导致 withTrace 定义了
64
+ // 但从未被调用 → mcp.log 永远不生成。可观测性静默缺失(无任何症状), 藏了很久。
65
+ // 现在工具只经本函数注册, 包 trace 这件事无法再被遗漏。
66
+ function tool(name, description, schema, handler) {
67
+ server.tool(name, description, schema, withTrace(name, handler));
68
+ }
69
+
52
70
  // 工具面(narrow on purpose — 只暴露读/查/记状态,不做深提炼)
53
- server.tool(
71
+ tool(
54
72
  'abs_resolve_project',
55
73
  '定位当前项目的 .brain 图谱根(从给定目录向上找最近 .brain/)。多项目隔离的唯一入口。',
56
74
  { cwd: z.string().describe('当前工作目录,默认进程 cwd') },
@@ -63,7 +81,7 @@ server.tool(
63
81
  }
64
82
  );
65
83
 
66
- server.tool(
84
+ tool(
67
85
  'abs_board',
68
86
  '读取当前项目 todo 看板(含断点/Next-Step)。先 resolve 得到项目,再传其根目录。',
69
87
  { cwd: z.string().describe('项目内任意目录') },
@@ -74,7 +92,7 @@ server.tool(
74
92
  }
75
93
  );
76
94
 
77
- server.tool(
95
+ tool(
78
96
  'abs_load',
79
97
  '开机读状态:index 路线 + todo 看板 + 最近 log。跨会话续接的入口。',
80
98
  { cwd: z.string().describe('项目内任意目录') },
@@ -85,23 +103,25 @@ server.tool(
85
103
  }
86
104
  );
87
105
 
88
- server.tool(
106
+ tool(
89
107
  'abs_task',
90
- '任务实时落盘(幂等键 = id)。start 登记 / note 补断点(改到哪个文件哪行) / blocked 碰壁 / done 完成归位。',
108
+ '任务实时落盘(幂等键 = id)。add/start 登记 / note 补断点(改到哪个文件哪行) / blocked 碰壁 / done 完成归位。',
91
109
  {
92
- action: z.enum(['start', 'done', 'note', 'blocked']),
110
+ action: z.enum(['add', 'start', 'done', 'note', 'blocked']),
93
111
  id: z.string().describe('任务幂等键,如 TASK-xxx 或子任务名'),
94
112
  cwd: z.string().describe('项目内任意目录'),
95
- note: z.string().optional().describe('start=做什么; note=断点(文件/到哪步); blocked=卡点原因'),
113
+ note: z.string().optional().describe('add/start=做什么; note=断点(文件/到哪步); blocked=卡点原因'),
96
114
  },
97
115
  async ({ action, id, cwd, note }) => {
98
116
  const root = await findBrainRoot(cwd || process.cwd());
99
117
  if (!root) return err('未找到 .brain/,先 abs init');
100
- return { content: [{ type: 'text', text: await cmdTask({ dir: root, action, id, note }) }] };
118
+ // add 是 start 的别名(与 CLI `abs todo add` 对齐)
119
+ const act = action === 'add' ? 'start' : action;
120
+ return { content: [{ type: 'text', text: await cmdTask({ dir: root, action: act, id, note }) }] };
101
121
  }
102
122
  );
103
123
 
104
- server.tool(
124
+ tool(
105
125
  'abs_status',
106
126
  '当前项目 + 图谱概要(各类页数)。',
107
127
  { cwd: z.string().describe('项目内任意目录') },
@@ -112,7 +132,7 @@ server.tool(
112
132
  }
113
133
  );
114
134
 
115
- server.tool(
135
+ tool(
116
136
  'abs_query',
117
137
  '检索当前项目 .brain/ 知识页(多词 OR):以前踩过什么坑、哪页记了 X。',
118
138
  { cwd: z.string().describe('项目内任意目录'), terms: z.array(z.string()).min(1).describe('检索词') },
@@ -123,7 +143,7 @@ server.tool(
123
143
  }
124
144
  );
125
145
 
126
- server.tool(
146
+ tool(
127
147
  'abs_lint',
128
148
  '图谱体检:死链/孤岛/缺 frontmatter/超尺寸/sources 堆积/index 漏列。',
129
149
  { cwd: z.string().describe('项目内任意目录') },
@@ -134,7 +154,7 @@ server.tool(
134
154
  }
135
155
  );
136
156
 
137
- server.tool(
157
+ tool(
138
158
  'abs_note',
139
159
  '经验实时暂存:把刚踩的坑/技巧/结论一句话落进 sources/(防 context 断了流失)。Teardown 时再提炼进 concepts/。',
140
160
  {
@@ -149,7 +169,7 @@ server.tool(
149
169
  }
150
170
  );
151
171
 
152
- server.tool(
172
+ tool(
153
173
  'abs_wrapup',
154
174
  '收尾保险:把当前 todo 未完成任务快照到 ~/.abs/log/wrapup.log(下会话 load 时展示滞留对账)。',
155
175
  { cwd: z.string().describe('项目内任意目录') },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fanchao8609/agent_brain_sync",
3
- "version": "1.2.3",
3
+ "version": "1.3.1",
4
4
  "description": "agent-brain-sync: 跨会话 AI 编码记忆 — hook 纯触发 + CLI/MCP 读写 .brain markdown 图谱, 防并发写保护。",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/skill/SKILL.md CHANGED
@@ -90,18 +90,18 @@ monorepo 若多个子包各自独立交付,可各建一份 `.brain/`;横向
90
90
 
91
91
  1. **读状态**:`abs load`(或 MCP `abs_load`)读 index 路线 + todo 看板 + 最近 log。
92
92
  2. **对账滞留(强制,别跳过)**:若 `abs load` 顶部出现 `⏳ 上会话滞留`,说明上会话有任务做完/做到一半就断了。**先收尾再开工**:
93
- - 快照里的任务现在真做完了 → `abs task done <id>`(done 后下次 load 滞留自动消失);
94
- - 还没做完 → `abs task note <id> --note "接到哪/改到哪个文件"` 补断点(别空手续接)。
93
+ - 快照里的任务现在真做完了 → `abs todo done <id>`(done 后下次 load 滞留自动消失);
94
+ - 还没做完 → `abs todo note <id> --note "接到哪/改到哪个文件"` 补断点(别空手续接)。
95
95
  滞留没清完就不算接上了状态——这是「任务做完没进 Done」的根治动作。
96
96
  3. **读命中页**:按关键词在 index 定位 → 读对应 concepts/entities 全文。
97
97
  4. **续 todo**:默认续 todo 分支 → 把顶部未完成项当当前任务开做。
98
- 5. **登记新任务**:有明确新任务而 todo 没有 → `abs task start <id> --note 做什么` 登记
98
+ 5. **登记新任务**:有明确新任务而 todo 没有 → `abs todo add <id> --note 做什么` 登记
99
99
  再动工。不登记,会话一切断就丢。
100
100
 
101
101
  ## 进行中:todo 是活看板 + 经验实时落(最重要的纪律)
102
102
 
103
103
  **todo 不是收尾仪式,是干活中随改随写的活看板。** 每个任务边界立即更新,和 git commit
104
- 同一个反射,别等收尾。用工具(MCP `abs_task` / CLI `abs task`):
104
+ 同一个反射,别等收尾。用工具(MCP `abs_task` / CLI `abs todo`):
105
105
 
106
106
  > **写操作优先 MCP,不要用 `bash` 跑 `abs`。** 实测:MCP 单次 ~2ms(server 常驻),
107
107
  > CLI 单次 27ms(其中 20ms 是每次起 node 进程的固定开销,读写本身仅 3ms)。
@@ -110,15 +110,19 @@ monorepo 若多个子包各自独立交付,可各建一份 `.brain/`;横向
110
110
 
111
111
  | 时机 | 动作 |
112
112
  |---|---|
113
- | 认领新任务 | `abs task start <id> --note "做什么"` |
114
- | 子任务做完 | `abs task done <id>`(自动归位 Done 对应 `### YYYY-MM-DD` 分组顶部,新完成在前;断点随迁) |
115
- | 碰壁/阻塞 | `abs task blocked <id> --note "卡点原因"`(移 Blocked) |
116
- | 被打断/改向/干到一半停 | `abs task note <id> --note "改到哪个文件/到哪步"`(补 ↳ 断点 行) |
113
+ | 认领新任务 | `abs todo add <id> --note "做什么"` |
114
+ | 子任务做完 | `abs todo done <id>`(自动归位 Done 对应 `### YYYY-MM-DD` 分组顶部,新完成在前;断点随迁) |
115
+ | 碰壁/阻塞 | `abs todo blocked <id> --note "卡点原因"`(移 Blocked) |
116
+ | 被打断/改向/干到一半停 | `abs todo note <id> --note "改到哪个文件/到哪步"`(补 ↳ 断点 行) |
117
117
 
118
- > **跨会话任务只用 abs task,别用宿主原生 todo。** Cl​aude TodoWrite/Task、co​dex todo-list、
118
+ > `abs todo start` 与 `abs todo add` 等价(老写法仍可用)。
119
+ > 旧版 `abs task ...` / `abs board` 已改名,会报错并提示新写法。
120
+ > 只读命令(`todo`/`status`/`lint`/`load`/`index`)遇多余参数会报错 —— 不再静默吞掉。
121
+
122
+ > **跨会话任务只用 abs todo,别用宿主原生 todo。** Cl​aude TodoWrite/Task、co​dex todo-list、
119
123
  > Op​enCode todowrite、pi `/list`/goal 各有各的原生任务——但**多是会话内临时**,不会写进
120
124
  > `.brain/todo.md`。若用原生 todo 建了跨会话任务,它就会「只在界面 0/N 里、abs 看不到」,
121
- > 下会话接不上、收尾没影。**分工**:跨会话/会被打断的任务 → `abs task start`(唯一真源);
125
+ > 下会话接不上、收尾没影。**分工**:跨会话/会被打断的任务 → `abs todo add`(唯一真源);
122
126
  > 原生 todo 顶多记「本会话内不跨断点的临时拆解草稿」。
123
127
 
124
128
  **经验/坑刚冒出来就落**:`abs note "一句话经验" --tags 坑,docker`(MCP `abs_note`)——
@@ -142,8 +146,8 @@ monorepo 若多个子包各自独立交付,可各建一份 `.brain/`;横向
142
146
  收到 Stop / "结束/先这样/切别的事" / 长任务告一段落,立即执行(快、准、不啰嗦):
143
147
 
144
148
  1. **读 todo** → `abs load`,看 Today 还有哪些没完成。
145
- 2. **判有没有做完没登记** → 实际完成了漏登记的 `abs task done <id>`;做到一半补
146
- `abs task note <id> --note 断点`;碰壁 `abs task blocked`。别让干完的事还停 Today。
149
+ 2. **判有没有做完没登记** → 实际完成了漏登记的 `abs todo done <id>`;做到一半补
150
+ `abs todo note <id> --note 断点`;碰壁 `abs todo blocked`。别让干完的事还停 Today。
147
151
  3. **沉淀经验(该沉淀才沉淀)** → 踩了值得记的坑/有可复用技巧/跨会话判断 → `abs note`
148
152
  暂存;值得深提炼的(规律/坑/决策)按 Teardown 走完整流程。
149
153
  4. **更新 index/log/todo** → 新页同步进 index;`log.md` 倒序记一行**工作成果**摘要
@@ -196,7 +200,7 @@ status: draft # 或 reviewed(仅指知识冲突裁决结案)
196
200
  | 层 | 干什么 | 靠什么 |
197
201
  |---|---|---|
198
202
  | **hook(机械)** | SessionStart/UserPromptSubmit/Stop/SessionEnd 自动记**技术日志**(~/.abs/log/) | 宿主 hook 配置。你不写技术日志。 |
199
- | **CLI/MCP(实时)** | 任务/经验**实时落盘**:`abs task start/note/blocked/done`、`abs note` | 每个任务边界立即调;经验随时 abs note。 |
203
+ | **CLI/MCP(实时)** | 任务/经验**实时落盘**:`abs todo add/note/blocked/done`、`abs note` | 每个任务边界立即调;经验随时 abs note。 |
200
204
  | **skill(自觉)** | **深提炼**(sources→concepts)+ 收尾循环 + 修 index | 判断什么值得沉淀,工具不替你判断。 |
201
205
 
202
206
  实时层解决"断了就丢";自觉层解决"噪音污染"。分工明确:骨架/任务/暂存/检索/体检走 abs 工具
package/src/install.js CHANGED
@@ -302,7 +302,7 @@ const server = async ({ client, directory }) => {
302
302
  const TEARDOWN_MSG =
303
303
  "[abs 收尾提醒] 本会话改过文件但 .brain/ 今天还没有记录。请立即走收尾循环:\\n" +
304
304
  "1) 跑 abs load 看 Today 还有哪些未完成;\\n" +
305
- "2) 实际做完漏登记的 abs task done <id>,做到一半的 abs task note <id> --note \\"断点\\";\\n" +
305
+ "2) 实际做完漏登记的 abs todo done <id>,做到一半的 abs todo note <id> --note \\"断点\\";\\n" +
306
306
  "3) 值得留的经验 abs note \\"...\\"(宁少勿滥,能从代码 grep 到的不记);\\n" +
307
307
  "4) abs log \\"完成 X:...\\" 记一行工作成果,新页同步进 index。\\n" +
308
308
  "简洁执行,不要复述本条提醒。若本次确实没有可沉淀产出,直接回一句\\"无可沉淀\\"即可。"
@@ -487,7 +487,7 @@ export default function absPiHook(pi: ExtensionAPI): void {
487
487
  pi.sendUserMessage(
488
488
  "[abs 收尾提醒] 本会话改过文件但 .brain/ 今天还没有记录。请立即走收尾循环:\\n" +
489
489
  "1) 跑 abs load 看 Today 还有哪些未完成;\\n" +
490
- "2) 实际做完漏登记的 abs task done <id>,做到一半的 abs task note <id> --note \\"断点\\";\\n" +
490
+ "2) 实际做完漏登记的 abs todo done <id>,做到一半的 abs todo note <id> --note \\"断点\\";\\n" +
491
491
  "3) 值得留的经验 abs note \\"...\\"(宁少勿滥,能从代码 grep 到的不记);\\n" +
492
492
  "4) abs log \\"完成 X:...\\" 记一行工作成果,新页同步进 index。\\n" +
493
493
  "简洁执行,不要复述本条提醒。若本次确实没有可沉淀产出,直接回一句\\"无可沉淀\\"即可。",
package/src/store.js CHANGED
@@ -180,7 +180,7 @@ export async function cmdLoad({ dir }) {
180
180
  `📂 abs → 项目: ${root}`,
181
181
  '⏳ 上会话滞留(未 done,先对账)',
182
182
  rows.join('\n'),
183
- '→ 完成: abs task done <id>;未完: abs task note <id> --note 断点',
183
+ '→ 完成: abs todo done <id>;未完: abs todo note <id> --note 断点',
184
184
  ''
185
185
  );
186
186
  }
@@ -244,7 +244,7 @@ export async function cmdTeardownCheck({ dir, payload }) {
244
244
  const msg = [
245
245
  '[abs 收尾提醒] 本会话改过文件但 .brain/ 今天还没有记录。请立即走收尾循环:',
246
246
  '1) 跑 abs load 看 Today 还有哪些未完成;',
247
- '2) 实际做完漏登记的 abs task done <id>,做到一半的 abs task note <id> --note "断点";',
247
+ '2) 实际做完漏登记的 abs todo done <id>,做到一半的 abs todo note <id> --note "断点";',
248
248
  '3) 值得留的经验 abs note "..."(宁少勿滥,能从代码 grep 到的不记);',
249
249
  '4) abs log "完成 X:..." 记一行工作成果,新页同步进 index。',
250
250
  '简洁执行,不要复述本条提醒。若本次确实没有可沉淀产出,直接回一句"无可沉淀"即可。',
@@ -302,7 +302,7 @@ export async function cmdTask({ dir, action, id, section, note }) {
302
302
  return r.msg;
303
303
  }
304
304
  if (action === 'note') {
305
- if (!note) return '用法: abs task note <id> --note "断点/进度"(实时落 ↳ 断点 行)';
305
+ if (!note) return '用法: abs todo note <id> --note "断点/进度"(实时落 ↳ 断点 行)';
306
306
  const r = await setBreakpoint(root, { id, text: note });
307
307
  return r.msg;
308
308
  }
package/src/todo.js CHANGED
@@ -318,6 +318,6 @@ export async function moveBlocked(brainRoot, { id, reason }) {
318
318
  export async function boardText(brainRoot, textOverride) {
319
319
  const text = textOverride !== undefined ? textOverride : await readTodo(brainRoot);
320
320
  const head = `📂 abs → 项目: ${brainRoot}`;
321
- if (!text.trim()) return `${head}\n\n(todo.md 为空,先 abs task start 登记任务)`;
321
+ if (!text.trim()) return `${head}\n\n(todo.md 为空,先 abs todo add 登记任务)`;
322
322
  return `${head}\n\n${text.trim()}`;
323
323
  }