@fanchao8609/agent_brain_sync 1.19.2 → 1.19.4
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/package.json +1 -1
- package/src/todo/structure.js +10 -2
- package/src/todo/validate.js +30 -0
package/package.json
CHANGED
package/src/todo/structure.js
CHANGED
|
@@ -185,13 +185,21 @@ export function enforceBrainFormat(text, spec, prev) {
|
|
|
185
185
|
const tLines = t.split('\n');
|
|
186
186
|
const bad = checkFileShape(fname, t).filter(
|
|
187
187
|
(it) => it.code !== 'STRAY-BLANK-LINE' &&
|
|
188
|
-
|
|
188
|
+
// ★ 孤儿缩进行**不吃存量豁免**(2026-10-18 用户要求)。
|
|
189
|
+
// 超长断点/奇怪条目放行存量是因为「没有安全的自动修法」;
|
|
190
|
+
// 而孤儿行是**确定性的坏数据**(子项没有父项,语义已丢),放行 = 让损坏持续。
|
|
191
|
+
// 宁可写不进去让人看见,也不要静默接受。
|
|
192
|
+
(it.code === 'TODO-ORPHAN-CHILD' ||
|
|
193
|
+
!(prevSig !== null && prevSig.has(sigOfLine(tLines[it.line - 1] || '')))),
|
|
189
194
|
);
|
|
190
195
|
if (bad.length) {
|
|
196
|
+
const onlyOrphan = bad.every((it) => it.code === 'TODO-ORPHAN-CHILD');
|
|
191
197
|
throw new Error(
|
|
192
198
|
`✗ ${fname} 格式不合规(写入被拒):\n` +
|
|
193
199
|
bad.map((it) => ` · ${it.msg}`).join('\n') +
|
|
194
|
-
|
|
200
|
+
(onlyOrphan
|
|
201
|
+
? `\n 出路:子任务必须挂在主任务下。给删掉的父任务行恢复一行任务行,或把那几条子项一起删掉。`
|
|
202
|
+
: `\n 出路:内容归入现有标签,或走对应入口(页 → concepts/ 等子目录 + index 登记;流水 → abs log;经验 → abs note)。`),
|
|
195
203
|
);
|
|
196
204
|
}
|
|
197
205
|
};
|
package/src/todo/validate.js
CHANGED
|
@@ -77,6 +77,36 @@ export function checkFileShape(file, text, { lintMode = false } = {}) {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
+
// 孤儿缩进行:缩进的任务行(子任务)上方必须紧跟着一条任务行。
|
|
81
|
+
//
|
|
82
|
+
// 为何要这个(2026-10-18 实测):我手动清理 Done 区时只删了父任务行、
|
|
83
|
+
// 留下了它的 ` - [x] 测试子项`,于是看板上出现一条“没有主项的子项”
|
|
84
|
+
// —— 而当时 checkFileShape 报 0 违规,lint 也说健康,没人拦得住。
|
|
85
|
+
// 现实中它会来自:手改文件、父任务行被删、分区重建时父任务被搬走。
|
|
86
|
+
// 子任务离开父任务就没有意义(它靠缩进表达归属),所以这是硬错。
|
|
87
|
+
if (file === 'todo.md') {
|
|
88
|
+
for (let i = 0; i < lines.length; i++) {
|
|
89
|
+
if (!/^\s+- \[[ x]\]/.test(lines[i])) continue;
|
|
90
|
+
// 往上找最近的非空行
|
|
91
|
+
let p = i - 1;
|
|
92
|
+
while (p >= 0 && !lines[p].trim()) p--;
|
|
93
|
+
const prev = p >= 0 ? lines[p] : null;
|
|
94
|
+
// 父行可以是:顶层任务 `- [x]`、子任务 ` - [x]`、或旧格式一等任务 ` ↳ [ ] …`
|
|
95
|
+
// (后者缩进是历史形态,它本身是任务不是子项 —— 实测漏认会把合法数据误判成孤儿)。
|
|
96
|
+
const ok = prev !== null && (
|
|
97
|
+
/^- \[[ x]\]/.test(prev) ||
|
|
98
|
+
/^\s+- \[[ x]\]/.test(prev) ||
|
|
99
|
+
/^\s*↳\s*\[[ x]\]/.test(prev)
|
|
100
|
+
);
|
|
101
|
+
if (!ok) {
|
|
102
|
+
issues.push({
|
|
103
|
+
code: 'TODO-ORPHAN-CHILD',
|
|
104
|
+
line: i + 1,
|
|
105
|
+
msg: `todo.md:${i + 1} 孤儿子任务(「${lines[i].trim().slice(0, 40)}」上方没有主任务)—— 子任务靠缩进表达归属,删父任务时要连子项一起删`,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
80
110
|
// 条目之间的空行(与写入闸门 assertNoStrayBlank 同判据)。
|
|
81
111
|
// lint 只能「报」,不能抛 —— 体检不能因格式坏而挂。
|
|
82
112
|
const isEntryLine = (l) => /^-\s/.test(l) || /^#{1,3}\s+\[/.test(l);
|