@thincoder/core 0.10.7 → 0.10.9
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/CHANGELOG.md +21 -0
- package/advisor/compaction.mjs +1 -1
- package/advisor/run.mjs +1 -1
- package/agent/chat-call.mjs +40 -27
- package/agent/child-marks.mjs +1 -1
- package/agent/dispatch-gates.mjs +7 -4
- package/agent/dispatch-run.mjs +1 -0
- package/agent/family-tools.mjs +13 -8
- package/agent/helpers.mjs +12 -10
- package/agent/image-heal.mjs +65 -0
- package/agent/light-round.mjs +4 -4
- package/agent/live-beat.mjs +4 -4
- package/agent/post-turn.mjs +34 -0
- package/agent/record-results.mjs +9 -1
- package/agent/run-stages.mjs +45 -10
- package/agent/setup-reminders.mjs +14 -13
- package/agent/setup.mjs +72 -48
- package/agent/spawn-child.mjs +1 -1
- package/agent/subagent-event.mjs +1 -1
- package/agent/suspension.mjs +2 -1
- package/agent/timers.mjs +8 -8
- package/agent/turn-loop.mjs +7 -1
- package/agent-tools/advisor.mjs +1 -1
- package/agent-tools/async-discard.mjs +40 -5
- package/agent-tools/async-settle.mjs +3 -1
- package/agent-tools/audit-block.mjs +5 -3
- package/agent-tools/batch-gate.mjs +198 -0
- package/agent-tools/batch-lifecycle.mjs +216 -36
- package/agent-tools/batch-paths.mjs +20 -20
- package/agent-tools/batch-skeleton.mjs +87 -0
- package/agent-tools/batch.mjs +11 -3
- package/agent-tools/checkpoint.mjs +1 -1
- package/agent-tools/context.mjs +28 -5
- package/agent-tools/design-slots.mjs +20 -7
- package/agent-tools/doc-check.mjs +75 -0
- package/agent-tools/eng.mjs +5 -3
- package/agent-tools/manifest.mjs +18 -18
- package/agent-tools/parent-channel.mjs +3 -3
- package/agent-tools/review-facts.mjs +2 -2
- package/agent-tools/settings.mjs +1 -1
- package/agent-tools/spawn-gates.mjs +108 -47
- package/agent-tools/ssh-session.mjs +486 -0
- package/agent-tools/ssh-transport.mjs +324 -0
- package/agent-tools/ssh-vault.mjs +291 -0
- package/agent-tools/subagent-scheduler.mjs +6 -5
- package/agent-tools/subagent-spawn.mjs +18 -11
- package/agent-tools/subagent.mjs +17 -9
- package/agent-tools/task.mjs +1 -1
- package/agent-tools/timer.mjs +8 -2
- package/agent-tools/zero-write-watch.mjs +2 -2
- package/agent-tools.mjs +3 -2
- package/attachments.mjs +4 -4
- package/browser/cdp.mjs +2 -2
- package/browser/launch.mjs +50 -4
- package/browser/snapshot.mjs +1 -1
- package/config-defaults.mjs +92 -0
- package/config-io.mjs +7 -2
- package/config-normalize.mjs +109 -0
- package/config-watch.mjs +2 -2
- package/config.mjs +88 -190
- package/declaration.mjs +5 -1
- package/doc-check/anchors.mjs +142 -0
- package/doc-check/index.mjs +210 -0
- package/doc-check/version.mjs +84 -0
- package/doc-check/width.mjs +132 -0
- package/file-refs.mjs +6 -6
- package/generate-title.mjs +1 -1
- package/hooks.mjs +1 -1
- package/i18n.mjs +13 -1
- package/ledger-cmd.mjs +314 -62
- package/ledger-db.mjs +122 -31
- package/ledger-migrate.mjs +18 -12
- package/ledger-read.mjs +6 -7
- package/ledger-tools.mjs +138 -77
- package/ledger.mjs +34 -62
- package/log.mjs +17 -3
- package/manifest-discovery.mjs +21 -18
- package/manifest-schema.mjs +17 -14
- package/manifest.mjs +37 -22
- package/mcp/transport-stdio.mjs +1 -1
- package/mcp.mjs +2 -2
- package/memory/core.mjs +1 -1
- package/memory/scan.mjs +1 -1
- package/memory/sweep.mjs +1 -1
- package/model-specs.mjs +7 -7
- package/notify-policy.mjs +6 -6
- package/package.json +2 -1
- package/permission.mjs +21 -1
- package/prompts/advisor-design.md +53 -23
- package/prompts/advisor-round1.md +34 -14
- package/prompts/advisor-round2.md +32 -19
- package/prompts/advisor-round3.md +34 -21
- package/prompts/common.md +148 -79
- package/prompts/consult-base.md +14 -8
- package/prompts/discipline-engineering.md +70 -66
- package/prompts/discipline-normal.md +86 -77
- package/prompts/persona-coder.md +6 -6
- package/prompts/persona-eng-coder.md +19 -18
- package/prompts/persona-eng-designer.md +40 -31
- package/prompts/persona-engineering.md +124 -92
- package/prompts/persona-explore.md +2 -2
- package/prompts/persona-normal.md +20 -17
- package/prompts/persona-plan.md +7 -7
- package/prompts/subagent-base.md +4 -4
- package/provider/anthropic.mjs +4 -2
- package/provider/core.mjs +4 -2
- package/provider/errors.mjs +8 -0
- package/provider/google.mjs +8 -1
- package/provider/normalize.mjs +42 -12
- package/provider/responses-request.mjs +4 -3
- package/provider/responses.mjs +2 -2
- package/provider/wait-status.mjs +1 -1
- package/provider-flows.mjs +1 -1
- package/queued.mjs +2 -2
- package/rules.mjs +4 -4
- package/session-gc.mjs +1 -1
- package/session-lifecycle.mjs +7 -7
- package/session-slot-write.mjs +2 -2
- package/session-slots-manifest.mjs +1 -1
- package/session.mjs +1 -1
- package/shell-candidates.mjs +2 -2
- package/shell-identity.mjs +1 -1
- package/team.mjs +63 -5
- package/think-off.mjs +3 -3
- package/token-ttl.mjs +1 -1
- package/token-window.mjs +1 -1
- package/tool-docs/bash.md +1 -1
- package/tool-docs/batch.md +1 -1
- package/tool-docs/browser.md +1 -1
- package/tool-docs/doc_check.md +54 -0
- package/tool-docs/fetch.md +3 -2
- package/tool-docs/ledger.md +7 -5
- package/tool-docs/manifest.md +14 -2
- package/tool-docs/ssh.md +51 -0
- package/tool-docs/subagent.md +6 -9
- package/tool-docs/timer.md +2 -1
- package/tool-docs/websearch.md +3 -1
- package/tools/browser.mjs +1 -1
- package/tools/execute.mjs +1 -1
- package/tools/git-run.mjs +2 -2
- package/tools/git.mjs +8 -8
- package/tools/index.mjs +3 -0
- package/tools/ops.mjs +1 -1
- package/tools/process-tree.mjs +2 -2
- package/tools/ssh-askpass.mjs +35 -0
- package/tools/ssh.mjs +105 -0
- package/tools/web-deepseek.mjs +172 -0
- package/tools/web.mjs +29 -4
- package/vision-reader.mjs +4 -4
|
@@ -1,52 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* spawn-gates.mjs — M5 委派与 spawn 门新门禁统一落点(ENGINEERING-MODE-V2-MODULE-DELEGATION §2.3):
|
|
3
3
|
* 全部新增门禁逻辑集中于此——装配点(buildSpawnChild / normalizeFileList)只加 import 调用。
|
|
4
|
-
* 已实现:F2(round
|
|
4
|
+
* 已实现:F2(round 枚举 + 任务书参数校验/拼装——四项核心 + 第五项按角色)· F6(files 声明面拦截谓词)。
|
|
5
5
|
* 裁撤(2026-09-17 主 agent 裁定——不落代码):
|
|
6
|
-
* - F4 修复轮窄带:全量勘察散文 marker 不可机判(误拒风险不可接受)→ 由 F2
|
|
6
|
+
* - F4 修复轮窄带:全量勘察散文 marker 不可机判(误拒风险不可接受)→ 由 F2 的 round 参数承载轮次语义;
|
|
7
7
|
* - F5 advisor 角色:advisor 不入 spawn 通道(评审走 advisor 工具)——enum 收正为
|
|
8
8
|
* explore/eng-designer/eng-coder。
|
|
9
9
|
* 零依赖:本模块零 import(叶子——纯谓词层,无环、无反向依赖)。
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
/**
|
|
13
|
-
* F2 任务书五段文本字段(六强制字段中 round 之外的五段——ENGINEERING-MODE-V2-MODULE-DELEGATION §1.2 F2)。
|
|
14
|
-
* 判据 = 段标题在场(标题行或行内 marker——summaryEngTaskBook 同款手法:marker 正则命中
|
|
15
|
-
* task ∪ context 文本即可);内容够不够由执行者拒收兜底(需求 §1.14 #9 行为面——不做内容校验)。
|
|
16
|
-
* 双语 marker:中文标题(主 agent 派单形)与英文标题(交付报告格式模板形)同收。
|
|
17
|
-
*/
|
|
18
|
-
const TASK_BOOK_FIELDS = [
|
|
19
|
-
{ label: "目标与理由 (goal & why)", markers: [/目标与理由/, /goal\s*&\s*why/i, /goal\s+and\s+why/i] },
|
|
20
|
-
{ label: "已知事实 (known facts)", markers: [/已知事实/, /known\s+facts/i] },
|
|
21
|
-
{ label: "设计要点与禁止范围 (design points & forbidden scope)", markers: [/设计要点/, /design\s+points/i] },
|
|
22
|
-
{ label: "验收标准 (acceptance criteria)", markers: [/验收标准/, /acceptance\s+criteria/i] },
|
|
23
|
-
{ label: "交付报告格式 (delivery-report format)", markers: [/交付报告格式/, /交付报告/, /delivery[- ]report\s+format/i] },
|
|
24
|
-
]
|
|
25
|
-
|
|
26
12
|
/** F2 round 合法值(初始轮 / 修正轮——「派单必带」= 无默认值)。
|
|
27
13
|
* 单源:本档为唯一字面量处——schema 面(`agent-tools/subagent.mjs`)与谓词面(本档)同引用(D2)。
|
|
28
14
|
*/
|
|
29
15
|
export const ROUND_VALUES = ["initial", "fix"]
|
|
30
16
|
|
|
31
|
-
/**
|
|
32
|
-
*
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
17
|
+
/** 任务书样例内容(供人照抄;不是门的判据——门只判存在 / 类型 / 非空):核心四项一份,
|
|
18
|
+
* 第五项按角色各一份(工程角色 = `designPoints` ∥ explore / plan / coder = `scope`)。 */
|
|
19
|
+
const TASK_BOOK_CORE_MIN = {
|
|
20
|
+
goal: "实现批准设计(样例任务书——四项核心 + 角色第五项齐备)。",
|
|
21
|
+
knownFacts: "设计已评审通过、token 已签发、批次档在册。",
|
|
22
|
+
acceptance: "设计档的验收口径逐条可机验、项目验证链全绿。",
|
|
23
|
+
reportFormat: "交付表 + 文件路径 + 验证命令与结果。",
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** 工程角色样例(核心四项 + `designPoints`)。 */
|
|
27
|
+
export const ENG_TASK_BOOK_MIN = { ...TASK_BOOK_CORE_MIN, designPoints: "仅落设计档受影响文件清单;禁夹带新语义。" }
|
|
28
|
+
|
|
29
|
+
/** 非工程角色样例(核心四项 + `scope`)——explore / plan / coder。 */
|
|
30
|
+
export const PLAIN_TASK_BOOK_MIN = { ...TASK_BOOK_CORE_MIN, scope: "只读:相关源 / 设计档;不写任何文件、不碰 bench/。" }
|
|
42
31
|
|
|
43
32
|
/**
|
|
44
|
-
* F2
|
|
45
|
-
* round 枚举(initial|fix,必带集合 = eng-coder/eng-designer
|
|
46
|
-
*
|
|
47
|
-
* (context 是任务书背景段的携带参数——字段落在任一面均算在场)。
|
|
33
|
+
* F2 round 结构化参数校验(ENGINEERING-MODE-V2-MODULE-DELEGATION §2.2):
|
|
34
|
+
* round 枚举(initial|fix,必带集合 = eng-coder/eng-designer)。
|
|
35
|
+
* 缺 / 非法 → 抛错(派单缺陷——spawn 机械拒)。
|
|
48
36
|
*/
|
|
49
|
-
export function
|
|
37
|
+
export function validateRoundParam(args) {
|
|
50
38
|
const a = args ?? {}
|
|
51
39
|
const missing = []
|
|
52
40
|
if (!ROUND_VALUES.includes(a.round)) {
|
|
@@ -54,17 +42,88 @@ export function validateTaskBookFields(args) {
|
|
|
54
42
|
? `round (${ROUND_VALUES.join("|")}) — the structured round parameter`
|
|
55
43
|
: `round ∈ {${ROUND_VALUES.join(", ")}} (got ${JSON.stringify(a.round)})`)
|
|
56
44
|
}
|
|
57
|
-
const text = [a.context, a.task].filter((s) => typeof s === "string").join("\n")
|
|
58
|
-
for (const f of TASK_BOOK_FIELDS) {
|
|
59
|
-
if (!f.markers.some((m) => m.test(text))) missing.push(f.label)
|
|
60
|
-
}
|
|
61
45
|
if (missing.length === 0) return
|
|
62
46
|
throw new Error(
|
|
63
|
-
`Engineering spawn
|
|
64
|
-
`The
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
47
|
+
`Engineering spawn round gate: ${missing.join(" · ")}. ` +
|
|
48
|
+
`The spawn contract requires the structured round parameter (initial|fix); ` +
|
|
49
|
+
`the five task-book parameters are enforced by a separate gate (validateTaskBookParams) — ` +
|
|
50
|
+
`a missing or invalid round is a dispatch defect and the spawn is refused.`)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* F2 任务书名集(**所有 spawn 角色**):core = 四项核心(全员必带);fifth = 第五项两名
|
|
55
|
+
* ——工程角色 = `designPoints` ∥ explore / plan / coder = `scope`。
|
|
56
|
+
* 单源:本档为唯一名集处——校验 / 拼装 / 探针夹具校验一律经 `taskBookParamsFor(role)` 派生(D2)。
|
|
57
|
+
* 样例对象 = `ENG_TASK_BOOK_MIN` / `PLAIN_TASK_BOOK_MIN`(供人照抄)。
|
|
58
|
+
*/
|
|
59
|
+
export const TASK_BOOK_PARAMS = {
|
|
60
|
+
core: ["goal", "knownFacts", "acceptance", "reportFormat"],
|
|
61
|
+
fifth: { engineering: "designPoints", plain: "scope" },
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** 角色 → 第五项类别(唯一判据;**与模式无关**——工程模式里的 explore 也取 plain)。
|
|
65
|
+
* 未知角色取 plain:spawn 路径上角色 enum 门先拒收(`agent-tools/subagent.mjs` 的 `ROLES`),到不了本门。 */
|
|
66
|
+
function fifthClassOf(role) {
|
|
67
|
+
return role === "eng-coder" || role === "eng-designer" ? "engineering" : "plain"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** 角色 → 该角色的任务书名集(四项核心 + 第五项;序 = 拼装序:第五项插在 `knownFacts` 之后,
|
|
71
|
+
* 与 C 之前 eng 角色的拼装序逐字相同——审计摘要 marker `/^Design points/i` 不受影响)。 */
|
|
72
|
+
export function taskBookParamsFor(role) {
|
|
73
|
+
const core = TASK_BOOK_PARAMS.core
|
|
74
|
+
return [...core.slice(0, 2), TASK_BOOK_PARAMS.fifth[fifthClassOf(role)], ...core.slice(2)]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** 拼装标签(不导出;仅词面,不是判据——无任何匹配读它)。 */
|
|
78
|
+
const TASK_BOOK_LABELS = {
|
|
79
|
+
goal: "Goal & why",
|
|
80
|
+
knownFacts: "Known facts",
|
|
81
|
+
designPoints: "Design points & forbidden scope",
|
|
82
|
+
scope: "Scope (what to read / what not to touch)",
|
|
83
|
+
acceptance: "Acceptance criteria",
|
|
84
|
+
reportFormat: "Delivery report format",
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* F2 任务书参数校验(ENGINEERING-MODE-V2-MODULE-DELEGATION §2.2)· **所有 spawn 角色**:
|
|
89
|
+
* 名集按角色取(`taskBookParamsFor(role)`)。判据只有三条——参数存在 ∧ typeof string ∧
|
|
90
|
+
* trim() 非空。不读内容:无正则、无标题匹配、无双语 marker。缺 / 空白 / 非字符串 → 合并抛,
|
|
91
|
+
* 文案逐项点名该参数;第五项缺失而另一名在场时,文案附一句指路(只作文案,不加判据)。
|
|
92
|
+
*/
|
|
93
|
+
export function validateTaskBookParams(args, role) {
|
|
94
|
+
const a = args ?? {}
|
|
95
|
+
const names = taskBookParamsFor(role)
|
|
96
|
+
const fifth = TASK_BOOK_PARAMS.fifth[fifthClassOf(role)]
|
|
97
|
+
const otherFifth = fifth === "designPoints" ? "scope" : "designPoints"
|
|
98
|
+
const failed = []
|
|
99
|
+
for (const name of names) {
|
|
100
|
+
const v = a[name]
|
|
101
|
+
if (v === undefined || v === null) {
|
|
102
|
+
const hint = name === fifth && a[otherFifth] !== undefined && a[otherFifth] !== null
|
|
103
|
+
? ` (got ${otherFifth} instead — that name belongs to the ${fifthClassOf(role) === "engineering" ? "explore/plan/coder" : "eng-coder/eng-designer"} spawns)`
|
|
104
|
+
: ""
|
|
105
|
+
failed.push(`${name} — missing (the task book is four core parameters + the role's fifth)${hint}`)
|
|
106
|
+
}
|
|
107
|
+
else if (typeof v !== "string") failed.push(`${name} — must be a string (got ${typeof v})`)
|
|
108
|
+
else if (v.trim() === "") failed.push(`${name} — blank (trim() is empty)`)
|
|
109
|
+
}
|
|
110
|
+
if (failed.length === 0) return
|
|
111
|
+
throw new Error(
|
|
112
|
+
`Spawn task-book gate (role='${role}'): ${failed.join(" · ")}. ` +
|
|
113
|
+
`The task book is four core parameters (${TASK_BOOK_PARAMS.core.join(" / ")}) plus ${fifth} ` +
|
|
114
|
+
`(the fifth parameter for role='${role}'); a missing, blank or non-string value is a dispatch defect and the spawn is refused.`)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** 五参 → 子代理任务书文本(**非门禁**,纯拼装):按 `taskBookParamsFor(role)` 固定序 + 标签,
|
|
118
|
+
* 空值跳过,`\n\n` 分隔。拼装单源 = 本函数——子代理 input 与探针判官的「任务书全文」同源。 */
|
|
119
|
+
export function composeTaskBookBrief(args, role) {
|
|
120
|
+
const a = args ?? {}
|
|
121
|
+
const parts = []
|
|
122
|
+
for (const name of taskBookParamsFor(role)) {
|
|
123
|
+
const v = a[name]
|
|
124
|
+
if (typeof v === "string" && v.trim() !== "") parts.push(`${TASK_BOOK_LABELS[name]}: ${v.trim()}`)
|
|
125
|
+
}
|
|
126
|
+
return parts.join("\n\n")
|
|
68
127
|
}
|
|
69
128
|
|
|
70
129
|
/**
|
|
@@ -87,18 +146,20 @@ const MANIFEST_BASENAME = "project-manifest.json"
|
|
|
87
146
|
|
|
88
147
|
/**
|
|
89
148
|
* F6 files 声明面拦截谓词(ENGINEERING-MODE-V2-MODULE-DELEGATION §2.2):
|
|
90
|
-
* scripts
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
149
|
+
* scripts/*(工程工具面不入域——**层级锚定:仅仓根与直接子层**——目录名在深层不携带
|
|
150
|
+
* face 信息(2026-10-14 收正:#1449——`deployment/<x>/scripts/*` 类交付物放行)——内容
|
|
151
|
+
* 产物 only)与过程档(父侧职责)→ 收集全部违规后抛合并错误(fail-closed——错误即工具
|
|
152
|
+
* 结果 JSON——无排队残留)。目录声明不在本谓词(normalizeFileList 循环内先行拒——错误
|
|
153
|
+
* 序不变)。调用点 = normalizeFileList(subagent-scheduler.mjs——本谓词在循环后跑——
|
|
154
|
+
* 目录错误先于过程档错误)。
|
|
94
155
|
*/
|
|
95
156
|
export function rejectEngineeringFilePaths(files) {
|
|
96
157
|
const violations = []
|
|
97
158
|
for (const f of Array.isArray(files) ? files : []) {
|
|
98
159
|
const segs = String(f).replace(/\\/g, "/").split("/").filter((s) => s)
|
|
99
160
|
const base = (segs[segs.length - 1] ?? "").toLowerCase()
|
|
100
|
-
if (segs.some((s) => s.toLowerCase() === "scripts")) {
|
|
101
|
-
violations.push(`engineering-tools face path ${f} must not be listed in files — scripts
|
|
161
|
+
if (segs.slice(0, 2).some((s) => s.toLowerCase() === "scripts")) {
|
|
162
|
+
violations.push(`engineering-tools face path ${f} must not be listed in files — scripts/* at the repo root or a direct child package is the engineering-tools face, not a content product (applies to every session, not engineering-mode-scoped; files carries source/test/design-doc paths only)`)
|
|
102
163
|
} else if (PROCESS_BASENAMES.has(base)) {
|
|
103
164
|
violations.push(`Parent-side maintained file ${f} must not be listed in files — reconciliation is the parent's duty; use the design-doc path if you need to edit a design doc`)
|
|
104
165
|
} else if (base === MANIFEST_BASENAME) {
|