@zhuan-ai/zhuanspec 2.15.7 → 2.16.2
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/dist/cli/hooks.d.ts +13 -1
- package/dist/cli/hooks.js +75 -2
- package/dist/cli/index.js +111 -4
- package/dist/commands/accuracy.js +5 -1
- package/dist/commands/knowledge.d.ts +21 -0
- package/dist/commands/knowledge.js +80 -0
- package/dist/commands/progress.d.ts +78 -0
- package/dist/commands/progress.js +349 -3
- package/dist/core/archive.js +28 -0
- package/dist/core/configurators/codex.d.ts +55 -1
- package/dist/core/configurators/codex.js +234 -2
- package/dist/core/corrections/select-candidates.d.ts +58 -0
- package/dist/core/corrections/select-candidates.js +357 -0
- package/dist/core/hooks/collect-knowledge.js +80 -5
- package/dist/core/hooks/deviation-check.d.ts +26 -1
- package/dist/core/hooks/deviation-check.js +32 -184
- package/dist/core/hooks/knowledge-index.d.ts +84 -0
- package/dist/core/hooks/knowledge-index.js +270 -0
- package/dist/core/hooks/post-archive.js +25 -13
- package/dist/core/hooks/record-progress.d.ts +64 -1
- package/dist/core/hooks/record-progress.js +224 -54
- package/dist/core/hooks/summarize.js +107 -20
- package/dist/core/hooks/user-input-hook.d.ts +38 -2
- package/dist/core/hooks/user-input-hook.js +346 -21
- package/dist/core/init.d.ts +16 -0
- package/dist/core/init.js +208 -11
- package/dist/core/metrics/code-accuracy.d.ts +152 -3
- package/dist/core/metrics/code-accuracy.js +323 -19
- package/dist/core/templates/agents-root-stub.d.ts +1 -1
- package/dist/core/templates/agents-root-stub.js +1 -0
- package/dist/core/templates/agents-template.d.ts +1 -1
- package/dist/core/templates/agents-template.js +27 -25
- package/dist/core/templates/codex-hooks-template.d.ts +37 -0
- package/dist/core/templates/codex-hooks-template.js +33 -2
- package/dist/core/templates/slash-command-templates.js +208 -66
- package/dist/core/templates/tasks-template.js +66 -14
- package/dist/core/update.js +17 -0
- package/dist/core/validation/strict-rules.d.ts +28 -0
- package/dist/core/validation/strict-rules.js +284 -0
- package/dist/utils/hook-merge.d.ts +6 -0
- package/dist/utils/hook-merge.js +33 -2
- package/dist/utils/phase-utils.js +5 -0
- package/package.json +22 -20
|
@@ -55,9 +55,9 @@ export const agentsTemplate = `# ZhuanSpec 使用说明
|
|
|
55
55
|
|
|
56
56
|
## 知识库检查
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
**工作区边界(强制)**:查找文档、检索工程代码、执行 grep/glob/ls 时,范围必须限定在当前 ZhuanSpec 工作区内。禁止使用跨上级目录的 glob(如 \`../**\`)、上级目录绝对路径或手动拼接到工作区外路径。Glob 返回相对路径时,必须以本次工具调用的 \`path\` 参数作为基准拼接绝对路径,不得误解为当前目录或上级目录。
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
**在任何阶段开始前,必须先检查知识库并加载项目知识:**
|
|
61
61
|
|
|
62
62
|
| 操作 | 命令 | 目的 |
|
|
63
63
|
|------|------|------|
|
|
@@ -65,16 +65,13 @@ export const agentsTemplate = `# ZhuanSpec 使用说明
|
|
|
65
65
|
| 搜索最佳实践 | \`rg "[关键词]" zhuanspec/knowledge/best-practices/\` | 学习成功经验 |
|
|
66
66
|
| 搜索隐式约定 | \`rg "[关键词]" zhuanspec/knowledge/implicit-conventions/\` | 理解团队约定 |
|
|
67
67
|
| 阅读知识索引 | \`cat zhuanspec/knowledge/index.md\` | 了解项目级知识摘要 |
|
|
68
|
-
|
|
|
69
|
-
| 语义检索功能 | \`llmwiki query -e --token <token> "[关键词]"\` | 优先做功能/实现位置的向量检索,token 来自 \`[service]/.llm-wiki/index.md\` |
|
|
70
|
-
| 结果匹配记录 | \`append [service]/.llm-wiki/result.log\` | 每次 llmwiki query 后判断结果是否匹配当前请求诉求,并记录判断结论 |
|
|
71
|
-
| 知识点定位 | \`llmwiki knowledge points "[关键词]"\` | 优先定位配置类、数据模型类、关键知识点 |
|
|
68
|
+
| 加载项目知识 | \`@skill:load-project-knowledge\` | 渐进式加载项目架构、服务定位、检索优先路径和架构约束 |
|
|
72
69
|
|
|
73
70
|
**知识库作用**:
|
|
74
71
|
- 减少重复踩坑,积累项目经验
|
|
75
72
|
- 提供团队隐式约定的书面记录
|
|
76
73
|
- 加速新成员融入和知识传承
|
|
77
|
-
-
|
|
74
|
+
- 通过 \`@skill:load-project-knowledge\` 渐进式加载项目知识,获取 matched_services、search_priority、architecture_constraints,按优先路径缩小代码定位范围
|
|
78
75
|
|
|
79
76
|
---
|
|
80
77
|
|
|
@@ -158,13 +155,7 @@ Wave: W/N | Phase: Apply
|
|
|
158
155
|
* 获取:matched_services(涉及的服务列表)、search_priority(检索优先路径)、architecture_constraints(架构约束)
|
|
159
156
|
* 使用:后续代码定位使用 search_priority 限定范围,方案设计检查 architecture_constraints
|
|
160
157
|
* 兼容策略:若未找到 project.md 或关键词无匹配,输出警告并使用全局检索
|
|
161
|
-
-
|
|
162
|
-
* 若已定位到涉及服务,优先阅读各工程服务目录下的 \`[service]/.llm-wiki/index.md\`,严格按照其中的引导执行检索
|
|
163
|
-
* \`llmwiki query -e --token <token> "[关键词]"\` 中的 \`<token>\` 必须来自对应服务的 \`[service]/.llm-wiki/index.md\`
|
|
164
|
-
* 功能/实现定位优先使用 \`llmwiki query -e --token <token> "[关键词]"\` 做语义检索
|
|
165
|
-
* 每次执行 \`llmwiki query\` 后,必须判断查询结果是否与当前请求诉求匹配,并将关键词、服务、匹配/不匹配结论、简要原因记录到对应服务的 \`[service]/.llm-wiki/result.log\`
|
|
166
|
-
* 查找配置类、数据模型类、配置项归属时,优先使用 \`llmwiki knowledge points "[关键词]"\`
|
|
167
|
-
* 仅当对应服务的 \`.llm-wiki/\` 不存在、llmwiki 无结果、结果与当前请求诉求不匹配、或结果明显偏差时,才回退到 \`grep/glob\` 或全局检索
|
|
158
|
+
- **工程代码检索**:使用 \`@skill:load-project-knowledge\` 返回的 search_priority 限定检索范围,按优先路径定位代码;仅当 Skill 无匹配结果时,才回退到 \`grep/glob\` 或全局检索
|
|
168
159
|
- 阅读 \`zhuanspec/project.md\` 了解项目约定(提示:"✓ Loaded project.md")
|
|
169
160
|
- 审查 \`zhuanspec/project.md\`,\`zhuanspec list\` 和 \`zhuanspec list --specs\` 以了解当前上下文。
|
|
170
161
|
1. **测试 case 来源确认(最先执行,禁止跳过)**:
|
|
@@ -207,6 +198,16 @@ Wave: W/N | Phase: Apply
|
|
|
207
198
|
3. 选择一个唯一的动词开头的 \`change-id\`,并在 \`zhuanspec/changes/<id>/\` 下搭建 \`proposal.md\`、\`tasks.md\`、\`design.md\` 和规范增量。
|
|
208
199
|
4. 将变更映射为具体的功能或要求,将多范围的工作分解为具有明确关系和顺序的不同规范增量。
|
|
209
200
|
5. 当解决方案跨越多个系统、引入新模式或在提交规范之前需要权衡讨论时,在 \`design.md\` 中捕获架构推理。
|
|
201
|
+
|
|
202
|
+
⚠️ **CHECKPOINT [DESIGN-EXTERNAL-DEPENDENCY-GATE]**(提案阶段前置闭环,必须在 design.md 新建/更新后立即执行):
|
|
203
|
+
1. **依赖识别**:全量罗列 ES / MQ / Redis / SCF-RPC / HTTP / OSS / Config(Apollo) / Job 八类外部依赖,按类型分桶;依赖清单优先从 techDesign 阶段产出提取,缺失时从用户提供的技术方案 / specs 中补齐
|
|
204
|
+
2. **硬规则使用 AskQuestion**:只要某项依赖的状态 / 版本 / 负责方 / 兜底策略任一字段不明确,**必须** 调用 \`AskQuestion\` 一次性展示选项;严禁默认写 ✅ 或 “待确认”跳过
|
|
205
|
+
3. **矩阵落地**:根据用户回答将结果写入 design.md 的「外部依赖可用性矩阵」段,表头必须为 **6 列**:
|
|
206
|
+
\`| 依赖名称 | 类型 | 状态 | 版本/环境 | 兜底/阻塞策略 | 负责方 |\`
|
|
207
|
+
4. **闭环完结**:本步骤结束前所有 techDesign 阶段标记为 ⚠️ / ❓ 的条目必须沉淀为 ✅ / ❌ / ✅+兜底,**不允许留白**;该矩阵是 propose / apply / 集成验证阶段的唯一事实源
|
|
208
|
+
|
|
209
|
+
⚠️ **CHECKPOINT [DATA-STORAGE-STRATEGY]**(仅当技术方案包含新增表 / CREATE TABLE / t_* 时强制执行):必须用 \`AskQuestion\` 批量澄清 **预估数量级 / 查询场景 / 读写 QPS / 时效性 / 一致性(含跨表事务)** 5 字段,并在 design.md 写入 **8 列** 「## 数据存储策略」表:\`| 表名 | 预估数量级 | 查询场景 | 读/写 QPS | 时效性 | 一致性(含跨表事务) | 存储策略 | 备注 |\`。任一列出现 \`TBD\` / 空 / 待评估 → 未通过,禁止进入规范增量编写。
|
|
210
|
+
|
|
210
211
|
6. 在 \`changes/<id>/specs/<capability>/spec.md\` 中起草规范增量(每个功能一个文件夹),使用 \`## ADDED|MODIFIED|REMOVED Requirements\`,每个要求至少包含一个 \`#### Scenario:\`,并在相关时交叉引用相关功能。
|
|
211
212
|
|
|
212
213
|
⚠️ **CHECKPOINT [SPEC-REQUIREMENT-FORMAT]**:
|
|
@@ -364,13 +365,7 @@ Wave: W/N | Phase: Apply
|
|
|
364
365
|
* 输入:domain(当前项目)、keywords(从 tasks.md 提取)
|
|
365
366
|
* 获取:matched_services、search_priority、architecture_constraints
|
|
366
367
|
* 使用:代码定位使用 search_priority 限定范围,避免全局检索偏差
|
|
367
|
-
-
|
|
368
|
-
* 若已定位到涉及服务,先阅读对应服务目录下的 \`[service]/.llm-wiki/index.md\`
|
|
369
|
-
* \`llmwiki query -e --token <token> "[关键词]"\` 中的 \`<token>\` 必须来自对应服务的 \`[service]/.llm-wiki/index.md\`
|
|
370
|
-
* 功能/实现定位优先使用 \`llmwiki query -e --token <token> "[关键词]"\`
|
|
371
|
-
* 每次执行 \`llmwiki query\` 后,必须判断查询结果是否与当前请求诉求匹配,并将关键词、服务、匹配/不匹配结论、简要原因记录到对应服务的 \`[service]/.llm-wiki/result.log\`
|
|
372
|
-
* 配置类、数据模型类、配置项归属优先使用 \`llmwiki knowledge points "[关键词]"\`
|
|
373
|
-
* 仅当对应服务的 \`.llm-wiki/\` 不存在、llmwiki 无结果、结果与当前请求诉求不匹配、或结果明显偏差时,才回退到 \`grep/glob\`
|
|
368
|
+
- **实施前定位代码**:使用 \`@skill:load-project-knowledge\` 返回的 search_priority 限定检索范围,按优先路径定位代码;仅当 Skill 无匹配结果时,才回退到 \`grep/glob\`
|
|
374
369
|
- 阅读 \`zhuanspec/project.md\` 了解项目约定(提示:"✓ Loaded project.md")
|
|
375
370
|
- 阅读 proposal.md - 了解要构建的内容
|
|
376
371
|
1. **阅读 design.md**(如果存在) - 审查技术决策
|
|
@@ -1193,10 +1188,17 @@ Apply 阶段使用两种专用 Agent 类型执行代码实施任务,由编排
|
|
|
1193
1188
|
- 扫描本 Wave 所有任务报告(reports/task-*.md)
|
|
1194
1189
|
- 提取状态为 DONE_WITH_CONCERNS 或 BLOCKED 的任务
|
|
1195
1190
|
- 将其 concerns/blocker 原因记录到集成测试报告的 Concerns 追踪章节
|
|
1196
|
-
|
|
1197
|
-
-
|
|
1198
|
-
-
|
|
1199
|
-
-
|
|
1191
|
+
4.1. **外部依赖全量扫描与兜底闭环(MANDATORY,不允许遗漏)**:
|
|
1192
|
+
提案阶段 DESIGN-EXTERNAL-DEPENDENCY-GATE 的集成验证兑现验收点,必须完整依序执行:
|
|
1193
|
+
- **三类来源全量采集**:同时要汇总《1》从 design.md 「外部依赖可用性矩阵」6 列表提取原始条目、2 从本 Wave 任务报告的 concern/blocker 文本中抓取外部依赖关键词、3 对 Wave 新增/修改源码做静态扫描(\`@MessageConsumer\`/\`RedisTemplate\`/\`@ApolloJsonValue\`/\`@XxlJob\`/\`@ServiceContract\` 等)
|
|
1194
|
+
- **8 桶分类,每桶都必须给结论**:ES / MQ / Redis / SCF-RPC / HTTP / OSS / Config / Job;没有项则写 \`—\` 并注明“已确认无依赖”,禁止跳过桶
|
|
1195
|
+
- **状态不明确的桶强制 \`AskQuestion\`**:当 design.md 矩阵有 ⚠️/❌ 仍被 Wave 涉及、代码扫描出新依赖、concern 明确说“占位/默认兜底/待核实”、或桶空但代码涉及该类型关键词(依赖声明遗漏)时,**必须** 一次性批量 AskQuestion,不允许仅凭“任务状态为 DONE_WITH_CONCERNS + 有报告”就算闭环
|
|
1196
|
+
- **写回对账表**:将结果记录到集成测试报告的 **外部依赖兜底对账表**(5 列:桶 / 依赖条目 / 来源 / 解决状态 / 后续动作);✅+兜底 条目必须同步回写 design.md 矩阵;桶结论缺失 → 集成报告整体状态强制 FAIL,阻断下一 Wave
|
|
1197
|
+
- **列出待重跑清单**(MANDATORY):澄清 ≠ 闭环。扫描本 Wave NEEDS_CONTEXT / BLOCKED 任务,识别阻断原因已澄清的任务,在集成报告中新增 \`## 🔁 待重试任务清单\` 段(5 列:任务ID / 原状态 / 阻断原因 / 已澄清依赖 / 重跑执行方);空列也须显式写 \`— 无需重跑\`
|
|
1198
|
+
5. **阻塞任务重试(BLOCKED ∪ NEEDS_CONTEXT 合并处理)**:
|
|
1199
|
+
- 重试对象:(1)编译/测试失败被标 BLOCKED 的任务;(2)待重跑清单中因外部依赖已澄清而解锁的 NEEDS_CONTEXT / BLOCKED 任务
|
|
1200
|
+
- 重跑前确认 design.md 矩阵已写回澄清结果;重新启动 subagent 时在 prompt 中显式标注 \`Execution Mode = RETRY\`,并附带上次 concerns 摘要 + 本次已澄清依赖条目 + 最新矩阵片段
|
|
1201
|
+
- 重试后仍失败 → 保留 BLOCKED 记录到集成测试报告,整体状态强制 FAIL
|
|
1200
1202
|
5. **生成集成测试报告**(MANDATORY,不得跳过):
|
|
1201
1203
|
- 报告路径:\`changes/<change-id>/reports/wave-{N}-integration-report.md\`
|
|
1202
1204
|
- 记录所有任务执行结果、编译检查结果、阻塞任务重试结果
|
|
@@ -48,5 +48,42 @@ export declare function getCodexHooksTomlBlock(): string;
|
|
|
48
48
|
* hook entries without serialising to TOML.
|
|
49
49
|
*/
|
|
50
50
|
export declare function getCodexDefaultHooks(): readonly CodexHookEntry[];
|
|
51
|
+
/**
|
|
52
|
+
* Identity of a Codex hook handler used by the CLI's per-hook content-trust
|
|
53
|
+
* mechanism (Codex PR #20321). Codex keys every trusted hash entry by:
|
|
54
|
+
*
|
|
55
|
+
* "<absolute-config-toml-path>:<event_snake>:<group_idx>:<handler_idx>"
|
|
56
|
+
*
|
|
57
|
+
* where:
|
|
58
|
+
* - event_snake: lowercase snake_case of the event name
|
|
59
|
+
* (SessionStart → session_start, PreToolUse → pre_tool_use, ...)
|
|
60
|
+
* - group_idx: 0-based index of the `[[hooks.<Event>]]` array entry
|
|
61
|
+
* (i.e. the Nth occurrence of that event)
|
|
62
|
+
* - handler_idx: 0-based index of the handler within that group
|
|
63
|
+
* (i.e. the Nth `[[hooks.<Event>.hooks]]` under the same group)
|
|
64
|
+
*
|
|
65
|
+
* ZhuanSpec emits exactly one handler per group, so handler_idx is always 0.
|
|
66
|
+
* Callers use these slots to seed `[hooks.state."<key>"] trusted_hash` entries
|
|
67
|
+
* in `~/.codex/config.toml` from a previously approved project, so users do
|
|
68
|
+
* not have to re-approve hooks in every new project.
|
|
69
|
+
*/
|
|
70
|
+
export interface CodexHookSlot {
|
|
71
|
+
/** Original PascalCase event name (matches the TOML `[[hooks.<Event>]]` header). */
|
|
72
|
+
event: CodexHookEntry['event'];
|
|
73
|
+
/** Event name in snake_case (e.g. `session_start`, `pre_tool_use`). */
|
|
74
|
+
eventSnake: 'session_start' | 'user_prompt_submit' | 'pre_tool_use' | 'post_tool_use' | 'stop';
|
|
75
|
+
/** 0-based index among `[[hooks.<Event>]]` arrays sharing the same event. */
|
|
76
|
+
groupIndex: number;
|
|
77
|
+
/** 0-based index of the handler within the group; always 0 for ZhuanSpec defaults. */
|
|
78
|
+
handlerIndex: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Derive the {event, group, handler} triple for every default hook.
|
|
82
|
+
*
|
|
83
|
+
* The returned slots are in declaration order; per-event `groupIndex` starts at
|
|
84
|
+
* 0 and increments each time a new `[[hooks.<Event>]]` block is emitted for
|
|
85
|
+
* the same event (matching Codex's array-of-tables semantics).
|
|
86
|
+
*/
|
|
87
|
+
export declare function getCodexDefaultHookSlots(): readonly CodexHookSlot[];
|
|
51
88
|
export {};
|
|
52
89
|
//# sourceMappingURL=codex-hooks-template.d.ts.map
|
|
@@ -38,8 +38,8 @@ const CODEX_DEFAULT_HOOKS = [
|
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
event: 'UserPromptSubmit',
|
|
41
|
-
command: 'ZHUANSPEC_HOST=codex zhuanspec-hook
|
|
42
|
-
statusMessage: '
|
|
41
|
+
command: 'ZHUANSPEC_HOST=codex zhuanspec-hook user-input --json',
|
|
42
|
+
statusMessage: 'Recording user input & correction context...',
|
|
43
43
|
},
|
|
44
44
|
{
|
|
45
45
|
event: 'PreToolUse',
|
|
@@ -111,4 +111,35 @@ export function getCodexHooksTomlBlock() {
|
|
|
111
111
|
export function getCodexDefaultHooks() {
|
|
112
112
|
return CODEX_DEFAULT_HOOKS;
|
|
113
113
|
}
|
|
114
|
+
/** Convert a Codex event name (PascalCase) to the snake_case form used in hook keys. */
|
|
115
|
+
function toEventSnake(event) {
|
|
116
|
+
switch (event) {
|
|
117
|
+
case 'SessionStart':
|
|
118
|
+
return 'session_start';
|
|
119
|
+
case 'UserPromptSubmit':
|
|
120
|
+
return 'user_prompt_submit';
|
|
121
|
+
case 'PreToolUse':
|
|
122
|
+
return 'pre_tool_use';
|
|
123
|
+
case 'PostToolUse':
|
|
124
|
+
return 'post_tool_use';
|
|
125
|
+
case 'Stop':
|
|
126
|
+
return 'stop';
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Derive the {event, group, handler} triple for every default hook.
|
|
131
|
+
*
|
|
132
|
+
* The returned slots are in declaration order; per-event `groupIndex` starts at
|
|
133
|
+
* 0 and increments each time a new `[[hooks.<Event>]]` block is emitted for
|
|
134
|
+
* the same event (matching Codex's array-of-tables semantics).
|
|
135
|
+
*/
|
|
136
|
+
export function getCodexDefaultHookSlots() {
|
|
137
|
+
const groupCounters = new Map();
|
|
138
|
+
return CODEX_DEFAULT_HOOKS.map((entry) => {
|
|
139
|
+
const eventSnake = toEventSnake(entry.event);
|
|
140
|
+
const groupIndex = groupCounters.get(eventSnake) ?? 0;
|
|
141
|
+
groupCounters.set(eventSnake, groupIndex + 1);
|
|
142
|
+
return { event: entry.event, eventSnake, groupIndex, handlerIndex: 0 };
|
|
143
|
+
});
|
|
144
|
+
}
|
|
114
145
|
//# sourceMappingURL=codex-hooks-template.js.map
|