@fanchao8609/agent_brain_sync 1.17.2 → 1.19.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 +21 -0
- package/README.md +16 -7
- package/bin/abs.js +19 -4
- package/bin/mcp.js +8 -6
- package/hooks/abs.omp.ts +852 -0
- package/hooks/abs.pi.ts +55 -18
- package/package.json +2 -1
- package/src/hosts.js +10 -0
- package/src/install.js +53 -0
- package/src/lint.js +5 -3
- package/src/store.js +31 -5
- package/src/todo/archive.js +18 -8
- package/src/todo/common.js +61 -6
- package/src/todo/spec.js +2 -2
- package/src/todo/structure.js +16 -8
- package/src/todo/tasks.js +73 -17
- package/src/todo/validate.js +28 -4
- package/src/todo.js +3 -3
- package/src/wrapup.js +18 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 fanchao
|
|
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
CHANGED
|
@@ -21,7 +21,7 @@ abs install
|
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
23
|
abs install --agent pi # 只装 pi
|
|
24
|
-
abs install # 全部: claude-code / codex / opencode / pi
|
|
24
|
+
abs install # 全部: claude-code / codex / opencode / pi / omp
|
|
25
25
|
abs install --agent pi --no-mcp # 只装 hook + skill,不要 MCP
|
|
26
26
|
```
|
|
27
27
|
|
|
@@ -33,6 +33,7 @@ abs install --agent pi --no-mcp # 只装 hook + skill,不要 MCP
|
|
|
33
33
|
| codex | `~/.codex/hooks.json` | config.toml `[mcp_servers.abs]` | `~/.codex/skills/` |
|
|
34
34
|
| opencode | `~/.config/opencode/plugins/abs.ts` | opencode.json mcp.abs | skills/ |
|
|
35
35
|
| pi | `~/.pi/agent/extensions/abs.ts` | `~/.pi/agent/mcp-adapter.json` `mcpServers.abs` | `~/.pi/agent/skills/` |
|
|
36
|
+
| omp | `~/.omp/agent/extensions/abs.ts` | `~/.omp/agent/mcp.json` `mcpServers.abs` | `~/.omp/agent/skills/` |
|
|
36
37
|
|
|
37
38
|
> **skill 规则**:`skill/` 下每个含 `SKILL.md` 的子目录 = 一个 skill,
|
|
38
39
|
> **目录名即安装名**(须与 frontmatter `name` 一致,否则 pi 会告警)。
|
|
@@ -53,9 +54,9 @@ npm install && npm link # 之后全局就有 abs
|
|
|
53
54
|
|
|
54
55
|
## 怎么用
|
|
55
56
|
|
|
56
|
-
### pi:编辑器上的 todo 面板
|
|
57
|
+
### pi / omp:编辑器上的 todo 面板
|
|
57
58
|
|
|
58
|
-
pi 宿主额外多一层 UI(其它宿主没有):**编辑器上方常驻一块 todo 面板**,直接读当前项目 `.brain/todo.md`。
|
|
59
|
+
pi 与 omp 宿主额外多一层 UI(其它宿主没有):**编辑器上方常驻一块 todo 面板**,直接读当前项目 `.brain/todo.md`。
|
|
59
60
|
|
|
60
61
|
```
|
|
61
62
|
─────────────────────────────────────────────────
|
|
@@ -69,6 +70,8 @@ pi 宿主额外多一层 UI(其它宿主没有):**编辑器上方常驻一
|
|
|
69
70
|
- **只显示未完成**,Done 归计数不占位(数量在标题里)
|
|
70
71
|
- **按当前使用者过滤**:显示 `[[我]]` 的 + 没标作者的(老任务/手写),别人的不显示
|
|
71
72
|
- **断点行 `↳` 挂在父任务下**;`├─` / `└─` 表结构
|
|
73
|
+
- **断点也可以是任务**:` ↳ [ ] <id> — 说明` 与普通任务同等对待(上看板、可 `done` / `note` / `state`);
|
|
74
|
+
单独的 `↳ 断点: 一句话` 仍是纯附属行、不算任务
|
|
72
75
|
- **「进行中」带三点动画**`○○○ → ●●○ → ●●●`(250ms/帧)—— 一眼看出哪条在跑
|
|
73
76
|
- **实时刷新**:我调 `abs_task` / `abs_board` 后立即重画,不用等我讲完话
|
|
74
77
|
- **上描边与输入框同色满宽**(主题色 `thinkingOff`,跟 pi 输入框的边框一致)
|
|
@@ -105,7 +108,9 @@ abs load # 开机读状态(Rules + 图谱计数 + 看板
|
|
|
105
108
|
abs todo # 看板 Todo / Done(行首带状态标记)
|
|
106
109
|
|
|
107
110
|
abs todo add TASK-1 --note "要做什么"
|
|
108
|
-
abs todo note TASK-1 --note "改到 X 文件 L40" #
|
|
111
|
+
abs todo note TASK-1 --note "改到 X 文件 L40" # 追加一条子项(标准 md 嵌套列表,可多条)
|
|
112
|
+
abs todo bp-done TASK-1 [--n 2] # 勾子项(n=第几条,缺省最后一条)
|
|
113
|
+
abs todo bp-undone TASK-1 [--n 2] # 取消勾(勾错了退回)
|
|
109
114
|
abs todo memo TASK-1 "随手记一段(可多句,不上看板)" # 任务笔记 → sessions/;无参=查看
|
|
110
115
|
abs todo state TASK-1 --note "进行中|讨论中|滞留中" # 改行首状态标记
|
|
111
116
|
abs todo done TASK-1
|
|
@@ -126,6 +131,9 @@ abs update # 升级到最新版并刷新四宿主
|
|
|
126
131
|
```
|
|
127
132
|
|
|
128
133
|
> `abs todo start` 与 `abs todo add` 等价(都登记任务)。
|
|
134
|
+
> **子项就是标准 Markdown 嵌套列表**:任务下缩进 2 空格的 `- [ ] …`,可多条、可各自勾选;
|
|
135
|
+
> 面板按缩进画树线,归档时原样保留缩进。旧格式 `↳ 断点:` 仍能读(存量不坏)。
|
|
136
|
+
> 任务 id 不能含空格(用连字符),含空格会被明确拒掉。
|
|
129
137
|
> 旧版 `abs task ...` / `abs board` 已废,打它们会报「未知命令」并退出码 1。
|
|
130
138
|
> `abs wrapup` / `abs teardown-check` 是 hook 内部命令,无需手动调用。
|
|
131
139
|
> **作者名要填真的**:`tester` / `foo` / `aaa` 这类占位名会被拒 —— 因为 `{user}` 是全局单值,
|
|
@@ -147,7 +155,7 @@ abs update # 升级到最新版并刷新四宿主
|
|
|
147
155
|
abs update
|
|
148
156
|
```
|
|
149
157
|
|
|
150
|
-
查 npm 最新版 → 升级 →
|
|
158
|
+
查 npm 最新版 → 升级 → 自动重刷五个宿主的 hook/skill(hook 里烧的是绝对路径,升级后必须重装,`abs update` 帮你做了)。完事重启宿主。
|
|
151
159
|
|
|
152
160
|
手动方式:
|
|
153
161
|
|
|
@@ -164,7 +172,7 @@ abs install # 重新刷 hook/skill
|
|
|
164
172
|
|
|
165
173
|
```bash
|
|
166
174
|
abs uninstall # 全部宿主
|
|
167
|
-
abs uninstall --agent pi # 只卸 pi
|
|
175
|
+
abs uninstall --agent pi # 只卸 pi(omp 同理:--agent omp)
|
|
168
176
|
npm uninstall -g @fanchao8609/agent_brain_sync
|
|
169
177
|
```
|
|
170
178
|
|
|
@@ -196,12 +204,13 @@ agent_brain_sync/
|
|
|
196
204
|
├── src/query.js 检索知识页(多词 OR)
|
|
197
205
|
├── src/relevant.js 相关页推荐(按"当前在干什么"挑该读的页)
|
|
198
206
|
├── src/codegraph.js 借本机 CodeGraph 取"代码影响面",写回图谱
|
|
199
|
-
├── src/hosts.js
|
|
207
|
+
├── src/hosts.js 五宿主接入定义
|
|
200
208
|
├── src/install.js 安装/卸载(分区共存合并)
|
|
201
209
|
├── src/userconfig.js 使用者姓名配置(作者标记;占位名如 tester/foo 会被拒)
|
|
202
210
|
├── src/wrapup.js Stop 收尾快照/归档
|
|
203
211
|
├── hooks/event.sh hook 模板
|
|
204
212
|
├── hooks/abs.pi.ts pi 扩展模板(含 todo 面板 / 随机昵称 / 常驻指引)
|
|
213
|
+
├── hooks/abs.omp.ts omp 扩展模板(同上;omp 的 before_agent_start 是 systemPrompt 整体替换)
|
|
205
214
|
├── skill/<名称>/SKILL.md 技能(每个子目录 = 一个 skill,装到各智能体)
|
|
206
215
|
├── scripts/ 构建期脚本(语法检查等,不进 npm 包)
|
|
207
216
|
├── docs/plans/ 方案文件(YYYYMMDD-<名>.md,不进 npm 包)
|
package/bin/abs.js
CHANGED
|
@@ -82,7 +82,7 @@ async function cmdUpdate({ yes }) {
|
|
|
82
82
|
console.log(r);
|
|
83
83
|
console.log('\n刷新四宿主 hook/skill(hook 脚本烧的是绝对路径 + 模板快照,升级后必须重装)…');
|
|
84
84
|
await runInstall({ agent: undefined, mcp: true, skill: true, yes: yes !== false });
|
|
85
|
-
console.log(`\n完成。重启宿主(pi / opencode / claude-code / codex)后新 hook 生效。`);
|
|
85
|
+
console.log(`\n完成。重启宿主(pi / omp / opencode / claude-code / codex)后新 hook 生效。`);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
const [,, cmd, ...rest] = process.argv;
|
|
@@ -116,6 +116,8 @@ const FLAG_SPEC = {
|
|
|
116
116
|
'title': { type: 'string' },
|
|
117
117
|
'desc': { type: 'string' },
|
|
118
118
|
'state': { type: 'string' },
|
|
119
|
+
// 勾子项用:第几条(1-based,缺省=最后一条)
|
|
120
|
+
'n': { type: 'string' },
|
|
119
121
|
// log 流水类型:note|dev|concept|ingest(cmdLog 会校枚举,非枚举直接报错)。
|
|
120
122
|
// ★ 漏声明就是真 bug(2026-10-05 本机实测):不在 FLAG_SPEC 的选项会被静默丢掉,
|
|
121
123
|
// 于是 `abs log "x" --kind note` 全写成默认的 dev,而 cmdLog 的枚举校验看不见它。
|
|
@@ -272,7 +274,7 @@ const subUsage = {
|
|
|
272
274
|
' abs install [--agent <宿主>] [--yes] [--no-mcp] [--no-skill]',
|
|
273
275
|
'',
|
|
274
276
|
'参数:',
|
|
275
|
-
' --agent <宿主> 只装一个宿主: claude-code | codex | opencode | pi',
|
|
277
|
+
' --agent <宿主> 只装一个宿主: claude-code | codex | opencode | pi | omp',
|
|
276
278
|
' (不传则在 TTY 下交互多选; 非 TTY / --yes 时为全部)',
|
|
277
279
|
' --yes 不交互,直接装全部宿主(自动化用)',
|
|
278
280
|
' --no-mcp 不注册 MCP server',
|
|
@@ -295,7 +297,7 @@ const subUsage = {
|
|
|
295
297
|
' abs uninstall [--agent <宿主>] [--yes]',
|
|
296
298
|
'',
|
|
297
299
|
'参数:',
|
|
298
|
-
' --agent <宿主> 只卸一个宿主: claude-code | codex | opencode | pi(不传=全部)',
|
|
300
|
+
' --agent <宿主> 只卸一个宿主: claude-code | codex | opencode | pi | omp(不传=全部)',
|
|
299
301
|
' --yes 不交互',
|
|
300
302
|
'',
|
|
301
303
|
'说明:',
|
|
@@ -310,6 +312,8 @@ const subUsage = {
|
|
|
310
312
|
' abs todo add <id> [--note "做什么"] [--section 讨论中|滞留中|搁置]',
|
|
311
313
|
' abs todo rename <旧id> --note "<新id>" 改任务 id(起错名/不可读时)',
|
|
312
314
|
' abs todo note <id> --note "断点/进度"',
|
|
315
|
+
' abs todo bp-done <id> 勾断点 → `↳ [x] 断点:`(做完落一句)',
|
|
316
|
+
' abs todo bp-undone <id> 取消勾(勾错了退回)',
|
|
313
317
|
' abs todo memo <id> "随手记(可多句)" 任务笔记 → sessions/,不上看板;无文字=查看',
|
|
314
318
|
' abs todo state <id> --note 进行中|讨论中|滞留中|搁置',
|
|
315
319
|
' abs todo done <id> [--as 落地|否决|仅方案] [结语文字]',
|
|
@@ -374,6 +378,8 @@ const TODO_ACTIONS = {
|
|
|
374
378
|
add: 'start',
|
|
375
379
|
start: 'start', // add 的别名(老习惯保留)
|
|
376
380
|
note: 'note',
|
|
381
|
+
'bp-done': 'bp-done', // 勾断点:`↳ [ ] 断点:` → `↳ [x] 断点:`
|
|
382
|
+
'bp-undone': 'bp-undone', // 取消勾断点(勾错了退回)
|
|
377
383
|
memo: 'memo', // 任务随手记:多句/追加/不占看板(无文字时=查看)
|
|
378
384
|
state: 'state', // 改行首状态标记:进行中|讨论中|滞留中|搁置(原地,不搬区)
|
|
379
385
|
rename: 'rename', // 改任务 id:人工起错名、或旧 id 不可读时用
|
|
@@ -469,7 +475,7 @@ async function main() {
|
|
|
469
475
|
if (!action) {
|
|
470
476
|
throw new Error(
|
|
471
477
|
`✗ 未知子命令 "${sub}"\n` +
|
|
472
|
-
` 可用: add / start / note / memo / state / done / archive\n` +
|
|
478
|
+
` 可用: add / start / note / bp-done / bp-undone / memo / state / done / archive\n` +
|
|
473
479
|
` 看板: abs todo(不带参数)\n` +
|
|
474
480
|
` 登记任务: abs todo add <id> --note "做什么"`,
|
|
475
481
|
);
|
|
@@ -492,6 +498,15 @@ async function main() {
|
|
|
492
498
|
console.log(await cmdTask({ dir: opts.dir, action, id, note, session: opts.session }));
|
|
493
499
|
break;
|
|
494
500
|
}
|
|
501
|
+
// 勾/取消勾子项:只收 <id>(子项位置 = 「某任务的第 N 条」,没有自己的 id)
|
|
502
|
+
if (action === 'bp-done' || action === 'bp-undone') {
|
|
503
|
+
rejectExtra(rest2, `abs todo ${sub} <id> [--n N]`);
|
|
504
|
+
if (!id) throw new Error(`✗ 缺 <id>\n 用法: abs todo ${sub} <id> [--n N]`);
|
|
505
|
+
const n = opts.n ? Number(opts.n) : undefined;
|
|
506
|
+
if (opts.n && (!Number.isInteger(n) || n < 1)) throw new Error(`✗ --n 要是正整数(收到 "${opts.n}")`);
|
|
507
|
+
console.log(await cmdTask({ dir: opts.dir, action, id, n }));
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
495
510
|
rejectExtra(rest2, usage);
|
|
496
511
|
if (!id) throw new Error(`✗ 缺 <id>\n 用法: ${usage}`);
|
|
497
512
|
console.log(await cmdTask({ dir: opts.dir, action, id, section: opts.section, note: opts.note, as: opts.as, session: opts.session }));
|
package/bin/mcp.js
CHANGED
|
@@ -112,12 +112,12 @@ tool(
|
|
|
112
112
|
|
|
113
113
|
tool(
|
|
114
114
|
'abs_task',
|
|
115
|
-
'任务实时落盘(幂等键 = id)。start 登记进 Todo / note
|
|
115
|
+
'任务实时落盘(幂等键 = id)。start 登记进 Todo / note 补子项(**追加**,标准 md 嵌套列表,`abs todo note`)/ bp_done、bp_undone 勾/取消勾子项(n=第几条,缺省最后一条)/ memo 任务随手记(多句/追加/不上看板)/ state 改状态 / done 完成归位 Done(done 时 note=结语文字,as=结语类型:落地|否决|仅方案)。必填: cwd, action, id。多会话并行时,start/add 带上 session(值见 system prompt 的 [会话] 段)以标记「这条任务谁在做」。',
|
|
116
116
|
{
|
|
117
|
-
action: z.enum(['add', 'start', 'done', 'note', 'memo', 'state']),
|
|
117
|
+
action: z.enum(['add', 'start', 'done', 'note', 'bp_done', 'bp_undone', 'memo', 'state']),
|
|
118
118
|
id: z.string().describe('任务幂等键,如 TASK-xxx 或子任务名'),
|
|
119
|
-
|
|
120
|
-
note: z.string().optional().describe('add/start=做什么; note=断点(文件/到哪步,一句话); memo=随手记(可多句、不定长,追加式;不传=查看已有笔记); state=进行中|讨论中|滞留中|搁置(搁置=用户改方向/不做了;滞留中=还要做只是卡住); done=结语文字'),
|
|
119
|
+
n: z.number().int().positive().optional().describe('bp_done/bp_undone 用:第几条子项(1-based,缺省=最后一条)'),
|
|
120
|
+
cwd: z.string().describe('项目根目录(.brain/ 所在处)'), note: z.string().optional().describe('add/start=做什么; note=断点(文件/到哪步,一句话); memo=随手记(可多句、不定长,追加式;不传=查看已有笔记); state=进行中|讨论中|滞留中|搁置(搁置=用户改方向/不做了;滞留中=还要做只是卡住); done=结语文字'),
|
|
121
121
|
as: z.enum(['落地', '否决', '仅方案']).optional().describe('仅 done:结语类型。默认 落地。做了又撤/评估后不做用 否决,只设计过用 仅方案 —— 别让假【落地】污染看板'),
|
|
122
122
|
// 会话 id:多会话并行时标记「这条任务是谁在做」。
|
|
123
123
|
// 值取自 system prompt 里的 `[会话] 本会话 id = xxx`(hook 注入),由模型原样回传。
|
|
@@ -125,12 +125,14 @@ tool(
|
|
|
125
125
|
// (协议没有,PI_* 环境变量也没有);模型本来就知道自己的 sid,直接收下最省。
|
|
126
126
|
session: z.string().optional().describe('仅 start/add:本会话 id(取自 system prompt 的 [会话] 段)。多会话并行时用来标记「这条任务谁在做」'),
|
|
127
127
|
},
|
|
128
|
-
async ({ action, id, cwd, note, as, session }) => {
|
|
128
|
+
async ({ action, id, cwd, note, as, session, n }) => {
|
|
129
129
|
const root = await findBrainRoot(cwd || process.cwd());
|
|
130
130
|
if (!root) return errNoBrain(cwd || process.cwd());
|
|
131
131
|
// add 是 start 的别名(与 CLI `abs todo add` 对齐)
|
|
132
132
|
const act = action === 'add' ? 'start' : action;
|
|
133
|
-
|
|
133
|
+
// bp_done → bp-done(MCP 参数名不用连字符,内部 action 用)
|
|
134
|
+
const act2 = act === 'bp_done' ? 'bp-done' : act === 'bp_undone' ? 'bp-undone' : act;
|
|
135
|
+
return { content: [{ type: 'text', text: await cmdTask({ dir: root, action: act2, id, note, as, session, n }) }] };
|
|
134
136
|
}
|
|
135
137
|
);
|
|
136
138
|
|