@fanchao8609/agent_brain_sync 1.7.6 → 1.7.7
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 +11 -0
- package/package.json +1 -1
- package/skill/SKILL.md +5 -3
- package/src/store.js +29 -0
package/README.md
CHANGED
|
@@ -72,11 +72,18 @@ abs log "完成 X" # 记一行流水;abs log 无参 =
|
|
|
72
72
|
abs query <词> # 检索图谱(多词 OR)
|
|
73
73
|
abs status # 当前项目 + 图谱概要
|
|
74
74
|
abs lint # 体检:死链/孤岛/超尺寸/堆积
|
|
75
|
+
abs rule # 列出 index.md 的 ## Rules 硬规则
|
|
76
|
+
abs rule add "一句话" # 追加一条硬规则(违反会丢数据/静默失效级的)
|
|
77
|
+
abs config show # 查看使用者姓名(标记作者用)
|
|
78
|
+
abs config set user <名字> # 设置作者名 → ~/.abs/config.json
|
|
75
79
|
abs todo archive # 归档 Done 区旧日期组(默认留近 3 天)
|
|
80
|
+
abs update # 升级到最新版并刷新四宿主 hook/skill
|
|
76
81
|
```
|
|
77
82
|
|
|
78
83
|
> `abs todo start` 与 `abs todo add` 等价(都登记任务)。
|
|
79
84
|
> 旧版 `abs task ...` / `abs board` 已改名,会报错并提示新写法。
|
|
85
|
+
> `abs wrapup` / `abs teardown-check` 是 hook 内部命令,无需手动调用。
|
|
86
|
+
> **升级后分区名自动归一**:`abs load` 每次都会顺手核对 `index/log/todo` 三文件结构,旧的英文/中文分区名(如 `## 当前路线 (Roadmap)` → `## Roadmap`、`# 🗂 图谱索引` → `# 🗂 Graph Index`)会被自动改回标准;缺分区自动补建,无头文件只提醒不自动改。
|
|
80
87
|
|
|
81
88
|
### 工作流
|
|
82
89
|
|
|
@@ -101,6 +108,8 @@ npm i -g @fanchao8609/agent_brain_sync@latest
|
|
|
101
108
|
abs install # 重新刷 hook/skill
|
|
102
109
|
```
|
|
103
110
|
|
|
111
|
+
> ⚠️ 改完源码(尤其 `skill/SKILL.md`、`src/`)后**必须 `abs install --yes` 重扇出**,否则宿主还在跑旧副本 —— 版本号与代码会脱节。发布用 `npm version patch`(自动打 tag),别手改 `package.json` 的 version;发布后 `npm view` 有缓存延迟,必要时 `npm cache clean --force` 再验。
|
|
112
|
+
|
|
104
113
|
---
|
|
105
114
|
|
|
106
115
|
## 卸载
|
|
@@ -136,6 +145,8 @@ agent_brain_sync/
|
|
|
136
145
|
├── src/store.js CLI 命令实现
|
|
137
146
|
├── src/hosts.js 四宿主接入定义
|
|
138
147
|
├── src/install.js 安装/卸载(分区共存合并)
|
|
148
|
+
├── src/userconfig.js 使用者姓名配置(作者标记)
|
|
149
|
+
├── src/wrapup.js Stop 收尾快照/归档
|
|
139
150
|
├── hooks/event.sh hook 模板
|
|
140
151
|
├── skill/SKILL.md 技能(装到各智能体)
|
|
141
152
|
└── test/ 单测
|
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -20,7 +20,7 @@ abs todo # 看板(Done 折成计数;明细 abs todo --fu
|
|
|
20
20
|
abs index / abs log # 完整 index.md / log.md
|
|
21
21
|
abs status # 当前项目 + 图谱概要
|
|
22
22
|
abs query <词1> [词2 …] # 检索 .brain/ 知识页(多词 OR)
|
|
23
|
-
abs lint #
|
|
23
|
+
abs lint # 图谱体检(死链/悬挂/超限/堆积/未提炼/Rules 超限)
|
|
24
24
|
|
|
25
25
|
# 写
|
|
26
26
|
abs todo add <id> --note "做什么" # 登记任务(start 同义)
|
|
@@ -148,7 +148,7 @@ Done 区由 `abs wrapup` 在会话结束时自动把「超 3 天且整天都已
|
|
|
148
148
|
3. **sources 是暂存**:提炼成规律后删/归档,并清掉指向它的引用(防死链)。
|
|
149
149
|
4. **能不能用一行链接代替新增整页**?
|
|
150
150
|
|
|
151
|
-
`abs lint`
|
|
151
|
+
`abs lint` 兜底:死链/孤岛/**悬挂页(NO-INBOUND)**/缺 frontmatter/超限/sources 堆积/**超龄未提炼(SOURCE-UNDISTILLED)**/index 漏列/Rules 超限。
|
|
152
152
|
## 开场:Init Sync(开工 / 默认续 todo)
|
|
153
153
|
|
|
154
154
|
图谱已存在;收到第一个核心开发指令**之前**走这条链载入上下文:
|
|
@@ -252,7 +252,9 @@ Done 区由 `abs wrapup` 在会话结束时自动把「超 3 天且整天都已
|
|
|
252
252
|
|
|
253
253
|
- `abs query <词>` 检索(多词 OR)→ 读命中页 → 答用 `[[页面名]]` 标来源。
|
|
254
254
|
**代码问题(符号在哪/谁调用)不在 .brain,直接读源码**;.brain 只答"踩过什么坑/上次做到哪"。
|
|
255
|
-
- `abs lint`
|
|
255
|
+
- `abs lint` 体检:死链/孤岛/**悬挂页**/缺 frontmatter/模板残留/超尺寸/sources 堆积/**超龄未提炼**/index 漏列/Rules 超限。
|
|
256
|
+
- `NO-INBOUND`:有出边但无人 `[[链接]]` 到你 = 挂在图上没人接(孤岛检查只抓"零出零入")。
|
|
257
|
+
- `SOURCE-UNDISTILLED`:source 超 7 天仍未链到任何 concept = 暂存了没归位。
|
|
256
258
|
|
|
257
259
|
## 三层分工
|
|
258
260
|
|
package/src/store.js
CHANGED
|
@@ -944,6 +944,10 @@ export async function cmdLint({ dir }) {
|
|
|
944
944
|
if (f.endsWith('.md')) names.add(f.replace(/\.md$/, ''));
|
|
945
945
|
}
|
|
946
946
|
const linkedNames = new Set(pages.flatMap((p) => p.links));
|
|
947
|
+
// 入度统计(不含 index.md):图上"有人引用它"才算被接上。
|
|
948
|
+
// index 是入口清单(每页都会被登记),算进去就永远不会有 NO-INBOUND —— 失去意义。
|
|
949
|
+
const inbound = new Map();
|
|
950
|
+
for (const p of pages) for (const ln of p.links) inbound.set(ln, (inbound.get(ln) || 0) + 1);
|
|
947
951
|
// index.md 里列的 [[x]] —— 用于反向查死引用(列了但页不存在)
|
|
948
952
|
let indexLinks = [];
|
|
949
953
|
try {
|
|
@@ -972,6 +976,12 @@ export async function cmdLint({ dir }) {
|
|
|
972
976
|
if (!isTerminal && !pg.links.length && !linkedNames.has(pg.slug)) {
|
|
973
977
|
issues.push(`ORPHAN-PAGE: ${pg.rel} (no links out, no links in)`);
|
|
974
978
|
}
|
|
979
|
+
// NO-INBOUND: 有出边但无人指向 = 挂在图上没人接。ORPHAN-PAGE 只抓"零出零入",
|
|
980
|
+
// 抓不到"连了 5 条出去却没人连它"的悬挂页(实测 concepts/file-shape-check-on-load 即是)。
|
|
981
|
+
// 只查知识页(concepts/entities/syntheses)——sources/sessions 的孤立是设计使然。
|
|
982
|
+
if (['concepts', 'entities', 'syntheses'].includes(pg.dir) && !(inbound.get(pg.slug) || 0)) {
|
|
983
|
+
issues.push(`NO-INBOUND: ${pg.rel} (无人链接到本页;在相关页的 ## 关联连接 挂一条 [[${pg.slug}]])`);
|
|
984
|
+
}
|
|
975
985
|
if (/知识冲突/.test(pg.body) && /status: draft/.test(pg.frontmatter)) {
|
|
976
986
|
issues.push(`UNRESOLVED-CONFLICT: ${pg.rel}`);
|
|
977
987
|
}
|
|
@@ -995,6 +1005,21 @@ export async function cmdLint({ dir }) {
|
|
|
995
1005
|
const nsrc = pages.filter((p) => p.dir === 'sources').length;
|
|
996
1006
|
if (nsrc > 10) issues.push(`SOURCES-PILED-UP: sources/ has ${nsrc} files > 10; 提炼归档旧 source`);
|
|
997
1007
|
|
|
1008
|
+
// SOURCE-UNDISTILLED: source 页超过 SOURCE_STALE_DAYS 天仍没链到任何 concept 页 = 暂存了没归位。
|
|
1009
|
+
// 只数总量(SOURCES-PILED-UP)抓不到"4 个 source 里 3 个没提炼"——实测本仓即如此。
|
|
1010
|
+
// 判据机械可判:出边里有没有 concepts/ 的页 + mtime 超龄,不猜语义。
|
|
1011
|
+
const conceptSlugs = new Set(pages.filter((p) => p.dir === 'concepts').map((p) => p.slug));
|
|
1012
|
+
const staleMs = SOURCE_STALE_DAYS * 86400 * 1000;
|
|
1013
|
+
for (const pg of pages) {
|
|
1014
|
+
if (pg.dir !== 'sources') continue;
|
|
1015
|
+
if (pg.links.some((ln) => conceptSlugs.has(ln))) continue;
|
|
1016
|
+
let ageMs = 0;
|
|
1017
|
+
try { ageMs = Date.now() - (await fs.stat(join(root, pg.rel))).mtimeMs; } catch { continue; }
|
|
1018
|
+
if (ageMs > staleMs) {
|
|
1019
|
+
issues.push(`SOURCE-UNDISTILLED: ${pg.rel}(${SOURCE_STALE_DAYS} 天未提炼成 concept;提炼后删 source 并清引用)`);
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
|
|
998
1023
|
// Rules 区:它的价值在“少而重”,且不被折叠(load 每次都全量读)。
|
|
999
1024
|
// 无上限增长 = 把 load 又撑回去(同 Done / index 清单的膨胀根因)。
|
|
1000
1025
|
{
|
|
@@ -1072,6 +1097,10 @@ const PAGE_DIRS = ['entities', 'concepts', 'sources', 'syntheses', 'sessions'];
|
|
|
1072
1097
|
const PAGE_MAX_LINES = 150;
|
|
1073
1098
|
const PAGE_MAX_BYTES = 8 * 1024;
|
|
1074
1099
|
|
|
1100
|
+
// source 页超龄未提炼的天数阈值(SOURCE-UNDISTILLED)。
|
|
1101
|
+
// 7 天 = 跨过至少一个完整工作周还没人提炼,基本等于被遗忘。
|
|
1102
|
+
const SOURCE_STALE_DAYS = 7;
|
|
1103
|
+
|
|
1075
1104
|
async function listPages(vault) {
|
|
1076
1105
|
let indexText = '';
|
|
1077
1106
|
try {
|