@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 +8 -5
- package/bin/abs.js +82 -22
- package/bin/mcp.js +35 -15
- package/package.json +1 -1
- package/skill/SKILL.md +17 -13
- package/src/install.js +2 -2
- package/src/store.js +3 -3
- package/src/todo.js +1 -1
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
|
|
66
|
-
abs
|
|
67
|
-
abs
|
|
68
|
-
abs
|
|
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
|
|
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
|
|
89
|
-
abs index
|
|
90
|
-
abs log
|
|
91
|
-
abs status
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
abs
|
|
95
|
-
abs
|
|
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
|
|
100
|
-
abs install [--agent
|
|
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':
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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':
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
172
|
+
tool(
|
|
153
173
|
'abs_wrapup',
|
|
154
174
|
'收尾保险:把当前 todo 未完成任务快照到 ~/.abs/log/wrapup.log(下会话 load 时展示滞留对账)。',
|
|
155
175
|
{ cwd: z.string().describe('项目内任意目录') },
|
package/package.json
CHANGED
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
|
|
94
|
-
- 还没做完 → `abs
|
|
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
|
|
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
|
|
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
|
|
114
|
-
| 子任务做完 | `abs
|
|
115
|
-
| 碰壁/阻塞 | `abs
|
|
116
|
-
| 被打断/改向/干到一半停 | `abs
|
|
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
|
-
>
|
|
118
|
+
> `abs todo start` 与 `abs todo add` 等价(老写法仍可用)。
|
|
119
|
+
> 旧版 `abs task ...` / `abs board` 已改名,会报错并提示新写法。
|
|
120
|
+
> 只读命令(`todo`/`status`/`lint`/`load`/`index`)遇多余参数会报错 —— 不再静默吞掉。
|
|
121
|
+
|
|
122
|
+
> **跨会话任务只用 abs todo,别用宿主原生 todo。** Claude TodoWrite/Task、codex todo-list、
|
|
119
123
|
> OpenCode todowrite、pi `/list`/goal 各有各的原生任务——但**多是会话内临时**,不会写进
|
|
120
124
|
> `.brain/todo.md`。若用原生 todo 建了跨会话任务,它就会「只在界面 0/N 里、abs 看不到」,
|
|
121
|
-
> 下会话接不上、收尾没影。**分工**:跨会话/会被打断的任务 → `abs
|
|
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
|
|
146
|
-
`abs
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
321
|
+
if (!text.trim()) return `${head}\n\n(todo.md 为空,先 abs todo add 登记任务)`;
|
|
322
322
|
return `${head}\n\n${text.trim()}`;
|
|
323
323
|
}
|