ai-dev-harness 0.1.0 → 0.1.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/COLLEAGUE_TRIAL_GUIDE.md +175 -0
- package/ONLINE_INSTALL_GUIDE.md +458 -0
- package/README.md +253 -54
- package/dist/agent.js +74 -49
- package/dist/approval.js +64 -0
- package/dist/audit.js +1 -0
- package/dist/checkpoint.js +83 -0
- package/dist/cli.js +326 -99
- package/dist/config.js +118 -9
- package/dist/context.js +62 -21
- package/dist/contextScore.js +44 -0
- package/dist/diagnostics.js +58 -0
- package/dist/doctor.js +100 -0
- package/dist/feedback.js +5 -0
- package/dist/init.js +8 -20
- package/dist/integration.js +84 -93
- package/dist/loop.js +116 -0
- package/dist/mcp.js +29 -112
- package/dist/metrics.js +91 -0
- package/dist/replay.js +27 -0
- package/dist/runPaths.js +31 -0
- package/dist/summarize.js +170 -39
- package/dist/templates.js +39 -215
- package/package.json +5 -2
- package/scripts/read-evidence.ps1 +45 -3
- package/scripts/run-harness.ps1 +9 -6
- package/templates/default-project/AGENTS.md +9 -0
- package/templates/default-project/SKILLS.md +13 -0
- package/templates/default-project/TOOLS.md +11 -0
- package/templates/default-project/skills/add_feature/SKILL.md +34 -0
- package/templates/default-project/skills/add_feature/context.yaml +33 -0
- package/templates/default-project/skills/add_feature/verify.yaml +2 -0
- package/templates/default-project/skills/fix_bug/SKILL.md +45 -0
- package/templates/default-project/skills/fix_bug/context.yaml +33 -0
- package/templates/default-project/skills/fix_bug/verify.yaml +2 -0
- package/templates/default-project/skills/update_docs/SKILL.md +28 -0
- package/templates/default-project/skills/update_docs/context.yaml +30 -0
- package/templates/default-project/skills/update_docs/verify.yaml +2 -0
- package/templates/default-project/skills/write_tests/SKILL.md +30 -0
- package/templates/default-project/skills/write_tests/context.yaml +32 -0
- package/templates/default-project/skills/write_tests/verify.yaml +2 -0
- package/templates/integrations/claude/SKILL.md +115 -0
- package/templates/integrations/codex/AGENTS_BLOCK.md +82 -0
- package/templates/integrations/cursor/ai-dev-harness.mdc +55 -0
- package/templates/integrations/gemini/GEMINI_BLOCK.md +46 -0
package/dist/runPaths.js
CHANGED
|
@@ -12,10 +12,41 @@ export function makeRunPaths(cwd, config, task) {
|
|
|
12
12
|
agentPrompt: path.join(runDir, "agent_prompt.md"),
|
|
13
13
|
plan: path.join(runDir, "plan.md"),
|
|
14
14
|
executionLog: path.join(runDir, "execution.log"),
|
|
15
|
+
agentContract: path.join(runDir, "agent_contract.json"),
|
|
15
16
|
gitDiff: path.join(runDir, "git_diff.patch"),
|
|
16
17
|
verify: path.join(runDir, "verify.json"),
|
|
18
|
+
verifyDiagnostics: path.join(runDir, "verify_diagnostics.json"),
|
|
19
|
+
contextScore: path.join(runDir, "context_score.json"),
|
|
20
|
+
approvalRequired: path.join(runDir, "approval_required.json"),
|
|
21
|
+
feedback: path.join(runDir, "feedback.jsonl"),
|
|
22
|
+
checkpoint: path.join(runDir, "checkpoint.json"),
|
|
23
|
+
preIterationDiff: path.join(runDir, "pre_iteration_diff.patch"),
|
|
24
|
+
postIterationDiff: path.join(runDir, "post_iteration_diff.patch"),
|
|
17
25
|
summary: path.join(runDir, "summary.md"),
|
|
18
26
|
persistSuggestions: path.join(runDir, "persist_suggestions.md"),
|
|
27
|
+
loopReview: path.join(runDir, "loop_review.json"),
|
|
28
|
+
loopReport: path.join(runDir, "loop_report.md"),
|
|
19
29
|
audit: path.join(runDir, "audit.jsonl")
|
|
20
30
|
};
|
|
21
31
|
}
|
|
32
|
+
export function makeIterationPaths(paths, iteration) {
|
|
33
|
+
const iterationDir = path.join(paths.runDir, `iteration-${iteration}`);
|
|
34
|
+
return {
|
|
35
|
+
iteration,
|
|
36
|
+
iterationDir,
|
|
37
|
+
contextPack: path.join(iterationDir, "context_pack.md"),
|
|
38
|
+
agentPrompt: path.join(iterationDir, "agent_prompt.md"),
|
|
39
|
+
plan: path.join(iterationDir, "plan.md"),
|
|
40
|
+
executionLog: path.join(iterationDir, "execution.log"),
|
|
41
|
+
agentContract: path.join(iterationDir, "agent_contract.json"),
|
|
42
|
+
gitDiff: path.join(iterationDir, "git_diff.patch"),
|
|
43
|
+
verify: path.join(iterationDir, "verify.json"),
|
|
44
|
+
verifyDiagnostics: path.join(iterationDir, "verify_diagnostics.json"),
|
|
45
|
+
contextScore: path.join(iterationDir, "context_score.json"),
|
|
46
|
+
approvalRequired: path.join(iterationDir, "approval_required.json"),
|
|
47
|
+
feedback: path.join(iterationDir, "feedback.jsonl"),
|
|
48
|
+
checkpoint: path.join(iterationDir, "checkpoint.json"),
|
|
49
|
+
preIterationDiff: path.join(iterationDir, "pre_iteration_diff.patch"),
|
|
50
|
+
postIterationDiff: path.join(iterationDir, "post_iteration_diff.patch")
|
|
51
|
+
};
|
|
52
|
+
}
|
package/dist/summarize.js
CHANGED
|
@@ -2,14 +2,14 @@ import { readFile, writeFile } from "node:fs/promises";
|
|
|
2
2
|
import { truncate } from "./utils.js";
|
|
3
3
|
export async function writeSummary(options) {
|
|
4
4
|
const diff = await readFile(options.gitDiffPath, "utf8").catch(() => "");
|
|
5
|
-
const summary = `#
|
|
5
|
+
const summary = `# 运行总结
|
|
6
6
|
|
|
7
|
-
##
|
|
8
|
-
-
|
|
9
|
-
- Agent
|
|
10
|
-
-
|
|
7
|
+
## 执行状态
|
|
8
|
+
- 任务状态: ${options.agentResult?.status === "success" && options.verifyResult?.status === "passed" ? "可进入评审" : "需要关注"}
|
|
9
|
+
- Agent 状态: ${options.agentResult?.status ?? "未运行"}
|
|
10
|
+
- 验证状态: ${options.verifyResult?.status ?? "未运行"}
|
|
11
11
|
|
|
12
|
-
##
|
|
12
|
+
## 任务
|
|
13
13
|
${options.task}
|
|
14
14
|
|
|
15
15
|
## Skill
|
|
@@ -18,54 +18,185 @@ ${options.skillName}
|
|
|
18
18
|
## Agent
|
|
19
19
|
${options.agentName}
|
|
20
20
|
|
|
21
|
-
##
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
21
|
+
## 执行结果
|
|
22
|
+
- 状态: ${options.agentResult?.status ?? "未运行"}
|
|
23
|
+
- 退出码: ${options.agentResult?.exitCode ?? "n/a"}
|
|
24
|
+
- 修改文件: ${options.agentResult?.changedFiles.join(", ") || "无"}
|
|
25
25
|
|
|
26
|
-
##
|
|
27
|
-
-
|
|
26
|
+
## 验证结果
|
|
27
|
+
- 状态: ${options.verifyResult?.status ?? "未运行"}
|
|
28
28
|
|
|
29
|
-
##
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
29
|
+
## 评审检查清单
|
|
30
|
+
- 确认变更限定在任务范围内。
|
|
31
|
+
- 确认公共接口和向后兼容性没有被意外破坏。
|
|
32
|
+
- 确认失败或跳过的验证项已被理解。
|
|
33
|
+
- 确认知识沉淀建议符合 OKF v0.1 + 团队扩展规范,并经过人工评审后再写入 Knowledge Graph。
|
|
34
34
|
|
|
35
|
-
## PR
|
|
36
|
-
###
|
|
37
|
-
${options.agentResult?.changedFiles.length ?
|
|
35
|
+
## PR 描述草稿
|
|
36
|
+
### 变更内容
|
|
37
|
+
${options.agentResult?.changedFiles.length ? `更新 ${options.agentResult.changedFiles.length} 个文件。` : "未检测到文件变更。"}
|
|
38
38
|
|
|
39
|
-
###
|
|
40
|
-
-
|
|
39
|
+
### 变更原因
|
|
40
|
+
- 见 execution.log 中的 Agent 影响分析、计划和最终报告。
|
|
41
41
|
|
|
42
|
-
###
|
|
43
|
-
${options.verifyResult?.commands.map((cmd) => `- ${cmd.name}: ${cmd.exitCode === 0 ? "
|
|
42
|
+
### 验证
|
|
43
|
+
${options.verifyResult?.commands.map((cmd) => `- ${cmd.name}: ${cmd.exitCode === 0 ? "通过" : "失败"} (${cmd.command})`).join("\n") || "- 未运行"}
|
|
44
44
|
|
|
45
|
-
###
|
|
46
|
-
-
|
|
45
|
+
### 风险
|
|
46
|
+
- 合并前需要评审正确性、安全性、兼容性和知识沉淀建议。
|
|
47
47
|
|
|
48
|
-
###
|
|
49
|
-
-
|
|
48
|
+
### 知识沉淀跟进
|
|
49
|
+
- 写入 Knowledge Graph 前先评审 persist_suggestions.md,确认目标项目目录、frontmatter、相关链接、index.md 和 log.md 更新项。
|
|
50
50
|
|
|
51
|
-
## Diff
|
|
51
|
+
## Diff 快照
|
|
52
52
|
\`\`\`diff
|
|
53
53
|
${truncate(diff, 12000)}
|
|
54
54
|
\`\`\`
|
|
55
55
|
`;
|
|
56
|
-
const persist = `#
|
|
56
|
+
const persist = `# 知识沉淀建议
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
写入 Knowledge Graph 前,请先人工评审这些建议。本文只生成 OKF 候选内容,不自动写入知识库。
|
|
59
59
|
|
|
60
|
-
-
|
|
60
|
+
- 任务: ${options.task}
|
|
61
61
|
- Skill: ${options.skillName}
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
- 修改文件: ${options.agentResult?.changedFiles.join(", ") || "无"}
|
|
63
|
+
- 沉淀策略: 写入 Knowledge Graph 前必须人工评审。
|
|
64
|
+
- 知识库规范: OKF v0.1 + PC 浏览器团队扩展。
|
|
65
|
+
|
|
66
|
+
## OKF 写作规则
|
|
67
|
+
|
|
68
|
+
- 每个知识文档是一个 concept,concept_id 等于文件路径去掉 \`.md\` 后缀。
|
|
69
|
+
- 新文档放入具体项目目录,例如 \`/zero/\`、\`/se/\`、\`/yuntun/\`。
|
|
70
|
+
- 子域优先选择 \`overview\`、\`features\`、\`metrics\`、\`api\`、\`playbooks\`、\`references\`。
|
|
71
|
+
- 普通知识文档必须包含 YAML frontmatter: \`type\`、\`title\`、\`description\`、\`tags\`、\`timestamp\`;API/数据类建议补充 \`resource\`。
|
|
72
|
+
- \`## 相关\` 必须使用有效 Markdown 链接,推荐 bundle 根相对路径,例如 \`/zero/features/fast-launch.md\`。
|
|
73
|
+
- API Reference 必须补充 \`## 关键实现锚点\` 和 \`### Agent 使用建议\`。
|
|
74
|
+
- 不写入密钥、Token、明文密码、未脱敏用户数据、未公开内网 IP;内网链接使用占位符域名。
|
|
75
|
+
- 合入知识库时同步更新对应目录的 \`index.md\` 和 \`log.md\`。
|
|
76
|
+
|
|
77
|
+
## 建议候选文档
|
|
78
|
+
|
|
79
|
+
### Candidate 1: Feature / Module Note
|
|
80
|
+
|
|
81
|
+
- 适用条件: 本次变更澄清了功能行为、模块职责、边界条件或实现约束。
|
|
82
|
+
- 建议路径: \`/<project>/features/<feature-or-module>.md\`
|
|
83
|
+
- 建议 type: \`Feature\`
|
|
84
|
+
|
|
85
|
+
\`\`\`\`markdown
|
|
86
|
+
---
|
|
87
|
+
type: Feature
|
|
88
|
+
title: <功能或模块名称>
|
|
89
|
+
description: <一句话说明这个功能/模块解决什么问题,以及本次变更沉淀了什么>
|
|
90
|
+
tags: [<project>, <feature-or-module>]
|
|
91
|
+
timestamp: ${new Date().toISOString()}
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 背景 / 设计目标
|
|
95
|
+
|
|
96
|
+
- <为什么需要这个功能或这次变更>
|
|
97
|
+
|
|
98
|
+
## 方案 / 实现
|
|
99
|
+
|
|
100
|
+
- <关键实现路径、主要流程、重要约束>
|
|
101
|
+
- 相关代码: \`${options.agentResult?.changedFiles[0] ?? "<path/to/code>"}\`
|
|
102
|
+
|
|
103
|
+
## 注意事项 / 已知限制
|
|
104
|
+
|
|
105
|
+
- <边界条件、兼容性、风险点>
|
|
106
|
+
|
|
107
|
+
## 相关
|
|
108
|
+
|
|
109
|
+
- [相关文档](/<project>/<domain>/<doc>.md)
|
|
110
|
+
\`\`\`\`
|
|
111
|
+
|
|
112
|
+
### Candidate 2: API Reference
|
|
113
|
+
|
|
114
|
+
- 适用条件: 本次变更涉及接口语义、入参、返回值、兼容性或调用链。
|
|
115
|
+
- 建议路径: \`/<project>/api/<api-name>.md\`
|
|
116
|
+
- 建议 type: \`API Reference\`
|
|
117
|
+
|
|
118
|
+
\`\`\`\`markdown
|
|
119
|
+
---
|
|
120
|
+
type: API Reference
|
|
121
|
+
title: <接口名称>
|
|
122
|
+
description: <一句话说明接口职责和主要调用场景>
|
|
123
|
+
resource: <endpoint-or-openapi-placeholder>
|
|
124
|
+
tags: [<project>, api]
|
|
125
|
+
timestamp: ${new Date().toISOString()}
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 关键实现锚点
|
|
129
|
+
- 模块: \`<代码仓库中的模块路径>\`
|
|
130
|
+
- 类/组件: \`<核心类、Handler 或入口函数>\`
|
|
131
|
+
- 补充入口: \`<配置、部署脚本或 Playbook 路径>\`
|
|
132
|
+
|
|
133
|
+
### Agent 使用建议
|
|
134
|
+
|
|
135
|
+
需要实现细节时,继续用 CodeGraph 查询真实调用链和影响面。
|
|
136
|
+
|
|
137
|
+
# Schema
|
|
138
|
+
|
|
139
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
140
|
+
|------|------|------|------|
|
|
141
|
+
| <field> | <type> | <yes/no> | <description> |
|
|
142
|
+
|
|
143
|
+
# Examples
|
|
144
|
+
|
|
145
|
+
\`\`\`json
|
|
146
|
+
{
|
|
147
|
+
"example": true
|
|
148
|
+
}
|
|
149
|
+
\`\`\`
|
|
150
|
+
|
|
151
|
+
## 相关
|
|
152
|
+
|
|
153
|
+
- [相关功能](/<project>/features/<feature>.md)
|
|
154
|
+
\`\`\`\`
|
|
155
|
+
|
|
156
|
+
### Candidate 3: Playbook / Test Knowledge
|
|
157
|
+
|
|
158
|
+
- 适用条件: 本次修复、验证、回滚或排障步骤可复用。
|
|
159
|
+
- 建议路径: \`/<project>/playbooks/<scenario>.md\`
|
|
160
|
+
- 建议 type: \`Playbook\`
|
|
161
|
+
|
|
162
|
+
\`\`\`\`markdown
|
|
163
|
+
---
|
|
164
|
+
type: Playbook
|
|
165
|
+
title: <场景处理手册>
|
|
166
|
+
description: <一句话说明该手册解决什么操作/排障场景>
|
|
167
|
+
tags: [<project>, playbook]
|
|
168
|
+
timestamp: ${new Date().toISOString()}
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 适用场景
|
|
172
|
+
|
|
173
|
+
- <什么情况下使用>
|
|
174
|
+
|
|
175
|
+
## 操作步骤
|
|
176
|
+
|
|
177
|
+
1. <步骤一>
|
|
178
|
+
2. <步骤二>
|
|
179
|
+
3. <验证结果>
|
|
180
|
+
|
|
181
|
+
## 风险与回滚
|
|
182
|
+
|
|
183
|
+
- <风险>
|
|
184
|
+
- <回滚方式>
|
|
185
|
+
|
|
186
|
+
## 相关
|
|
187
|
+
|
|
188
|
+
- [相关功能](/<project>/features/<feature>.md)
|
|
189
|
+
\`\`\`\`
|
|
190
|
+
|
|
191
|
+
## index.md / log.md 更新建议
|
|
192
|
+
|
|
193
|
+
- \`index.md\`: 添加新文档链接和一句话 description。
|
|
194
|
+
- \`log.md\`: 最新日期在前,使用 \`**Creation**\`、\`**Update**\`、\`**Deprecation**\` 或 \`**Deletion**\`。
|
|
195
|
+
|
|
196
|
+
## 缺失上下文记录
|
|
197
|
+
|
|
198
|
+
- Missing Context Candidate: 如果缺少 CodeGraph 或 Knowledge Graph 证据影响判断,请记录缺失的工具、query、concept_id 或代码路径。
|
|
199
|
+
- Skill Improvement Candidate: 如果本次任务暴露 Skill 输入、验证命令或 MCP 使用规则缺口,请记录到 Skill 改进建议。
|
|
69
200
|
`;
|
|
70
201
|
await writeFile(options.summaryPath, summary, "utf8");
|
|
71
202
|
await writeFile(options.persistPath, persist, "utf8");
|
package/dist/templates.js
CHANGED
|
@@ -1,217 +1,41 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
1
4
|
import { defaultConfigYaml } from "./config.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
`,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
Every skill follows the same execution contract:
|
|
31
|
-
|
|
32
|
-
1. Analysis Contract: identify assumptions, affected files/modules, likely risks, and the smallest viable plan.
|
|
33
|
-
2. Execution Contract: make only task-relevant changes and avoid opportunistic refactors.
|
|
34
|
-
3. Verification Contract: run or defer verification with explicit reasons.
|
|
35
|
-
4. Report Contract: explain root cause or intent, changed files, verification, residual risk, and knowledge suggestions.
|
|
36
|
-
`
|
|
37
|
-
};
|
|
38
|
-
const baseContext = `queries:
|
|
39
|
-
- related files
|
|
40
|
-
- symbols
|
|
41
|
-
- call graph
|
|
42
|
-
- dependencies
|
|
43
|
-
- impact analysis
|
|
44
|
-
fallbackInclude:
|
|
45
|
-
- README.md
|
|
46
|
-
- src
|
|
47
|
-
`;
|
|
48
|
-
const defaultVerify = `- name: git status
|
|
49
|
-
command: git status --short
|
|
50
|
-
`;
|
|
51
|
-
export const skillTemplates = {
|
|
52
|
-
fix_bug: {
|
|
53
|
-
"SKILL.md": `# fix_bug
|
|
54
|
-
|
|
55
|
-
## Goal
|
|
56
|
-
Diagnose and fix a defect with the smallest safe code change.
|
|
57
|
-
|
|
58
|
-
## Inputs
|
|
59
|
-
- Task text or issue description.
|
|
60
|
-
- CodeGraph impact context.
|
|
61
|
-
- Knowledge Graph related decisions, module notes, APIs, and runbooks.
|
|
62
|
-
|
|
63
|
-
## Outputs
|
|
64
|
-
- Code change.
|
|
65
|
-
- Test or verification result.
|
|
66
|
-
- Summary with root cause, impact, risk, and follow-up suggestions.
|
|
67
|
-
|
|
68
|
-
## Analysis Contract
|
|
69
|
-
- Restate the observed defect and expected behavior.
|
|
70
|
-
- Identify the likely root cause and the code path involved.
|
|
71
|
-
- List assumptions and confidence level before editing.
|
|
72
|
-
- Use CodeGraph impact context to avoid missing callers or dependent modules.
|
|
73
|
-
- Use Knowledge Graph decisions and runbooks to avoid violating historical constraints.
|
|
74
|
-
|
|
75
|
-
## Execution Contract
|
|
76
|
-
- Make the smallest task-relevant change.
|
|
77
|
-
- Prefer adding or updating a regression test when feasible.
|
|
78
|
-
- Do not rewrite unrelated code, rename public APIs, change formatting broadly, or upgrade dependencies.
|
|
79
|
-
- If root cause is unclear after inspection, stop and report missing evidence instead of guessing.
|
|
80
|
-
|
|
81
|
-
## Verification Contract
|
|
82
|
-
- Run the configured verification commands through Harness.
|
|
83
|
-
- If manual or targeted verification is needed, describe the exact command or scenario.
|
|
84
|
-
- Record any verification that could not be run and why.
|
|
85
|
-
|
|
86
|
-
## Report Contract
|
|
87
|
-
- Root cause.
|
|
88
|
-
- Files changed.
|
|
89
|
-
- Why the fix is safe.
|
|
90
|
-
- Verification result.
|
|
91
|
-
- Residual risk.
|
|
92
|
-
- Knowledge or runbook update suggestions.
|
|
93
|
-
|
|
94
|
-
## Acceptance
|
|
95
|
-
- The defect is explained.
|
|
96
|
-
- The change is limited to the affected area.
|
|
97
|
-
- Relevant verification commands pass or failures are recorded.
|
|
98
|
-
`,
|
|
99
|
-
"verify.yaml": defaultVerify,
|
|
100
|
-
"context.yaml": baseContext
|
|
101
|
-
},
|
|
102
|
-
add_feature: {
|
|
103
|
-
"SKILL.md": `# add_feature
|
|
104
|
-
|
|
105
|
-
## Goal
|
|
106
|
-
Implement a scoped feature using existing project patterns.
|
|
107
|
-
|
|
108
|
-
## Analysis Contract
|
|
109
|
-
- Restate the feature intent and non-goals.
|
|
110
|
-
- Identify affected modules, public interfaces, data flows, and compatibility risks.
|
|
111
|
-
- Check CodeGraph context for callers, dependencies, and likely integration points.
|
|
112
|
-
- Check Knowledge Graph context for ADRs, API contracts, and previous decisions.
|
|
113
|
-
|
|
114
|
-
## Execution Contract
|
|
115
|
-
- Implement the smallest coherent slice that satisfies the task.
|
|
116
|
-
- Follow existing patterns before introducing new abstractions.
|
|
117
|
-
- Do not change unrelated behavior or broaden scope.
|
|
118
|
-
- Preserve backward compatibility unless the task explicitly allows breaking changes.
|
|
119
|
-
|
|
120
|
-
## Verification Contract
|
|
121
|
-
- Add or update tests when behavior changes.
|
|
122
|
-
- Run configured verification commands through Harness.
|
|
123
|
-
- Record unverified scenarios and reasons.
|
|
124
|
-
|
|
125
|
-
## Report Contract
|
|
126
|
-
- Feature behavior implemented.
|
|
127
|
-
- Files changed.
|
|
128
|
-
- Compatibility notes.
|
|
129
|
-
- Verification result.
|
|
130
|
-
- Residual risk.
|
|
131
|
-
- Documentation or knowledge suggestions.
|
|
132
|
-
|
|
133
|
-
## Outputs
|
|
134
|
-
- Code change.
|
|
135
|
-
- Tests or verification.
|
|
136
|
-
- Documentation and knowledge suggestions when behavior changes.
|
|
137
|
-
`,
|
|
138
|
-
"verify.yaml": defaultVerify,
|
|
139
|
-
"context.yaml": baseContext
|
|
140
|
-
},
|
|
141
|
-
write_tests: {
|
|
142
|
-
"SKILL.md": `# write_tests
|
|
143
|
-
|
|
144
|
-
## Goal
|
|
145
|
-
Add or improve tests for existing behavior without changing production behavior unless required.
|
|
146
|
-
|
|
147
|
-
## Analysis Contract
|
|
148
|
-
- Identify the behavior under test and the risk it protects.
|
|
149
|
-
- Locate existing test patterns, fixtures, and helper APIs.
|
|
150
|
-
- Check CodeGraph context for affected code paths.
|
|
151
|
-
- Avoid inventing behavior not supported by source code or knowledge context.
|
|
152
|
-
|
|
153
|
-
## Execution Contract
|
|
154
|
-
- Prefer focused tests over broad snapshot or brittle integration tests.
|
|
155
|
-
- Do not change production code unless the existing code is untestable and the change is minimal.
|
|
156
|
-
- Keep fixtures deterministic and local to the test where possible.
|
|
157
|
-
|
|
158
|
-
## Verification Contract
|
|
159
|
-
- Run the relevant test command or configured Harness verification.
|
|
160
|
-
- If the full suite is too expensive, document the targeted command and why.
|
|
161
|
-
|
|
162
|
-
## Report Contract
|
|
163
|
-
- Scenarios covered.
|
|
164
|
-
- Files changed.
|
|
165
|
-
- Verification result.
|
|
166
|
-
- Remaining uncovered risks.
|
|
167
|
-
|
|
168
|
-
## Outputs
|
|
169
|
-
- Test files or fixture updates.
|
|
170
|
-
- Verification result.
|
|
171
|
-
- Summary of covered scenarios.
|
|
172
|
-
`,
|
|
173
|
-
"verify.yaml": defaultVerify,
|
|
174
|
-
"context.yaml": baseContext
|
|
175
|
-
},
|
|
176
|
-
update_docs: {
|
|
177
|
-
"SKILL.md": `# update_docs
|
|
178
|
-
|
|
179
|
-
## Goal
|
|
180
|
-
Update project documentation and propose knowledge graph additions.
|
|
181
|
-
|
|
182
|
-
## Analysis Contract
|
|
183
|
-
- Identify the audience and purpose of the documentation update.
|
|
184
|
-
- Cross-check docs against code, CodeGraph context, and Knowledge Graph records.
|
|
185
|
-
- Distinguish confirmed facts from inferred guidance.
|
|
186
|
-
|
|
187
|
-
## Execution Contract
|
|
188
|
-
- Update only documentation or knowledge suggestion artifacts unless explicitly asked to change code.
|
|
189
|
-
- Keep docs concise, operational, and linked to actual project behavior.
|
|
190
|
-
- Do not write directly to Knowledge Graph in v1.
|
|
191
|
-
|
|
192
|
-
## Verification Contract
|
|
193
|
-
- Check links, commands, paths, and filenames mentioned in the docs.
|
|
194
|
-
- Run configured verification when docs affect generated artifacts or examples.
|
|
195
|
-
|
|
196
|
-
## Report Contract
|
|
197
|
-
- Docs changed.
|
|
198
|
-
- Source of truth used.
|
|
199
|
-
- Verification result.
|
|
200
|
-
- Knowledge Graph suggestions.
|
|
201
|
-
|
|
202
|
-
## Outputs
|
|
203
|
-
- Documentation changes.
|
|
204
|
-
- Persist suggestions for ADR, module notes, runbooks, or decisions.
|
|
205
|
-
`,
|
|
206
|
-
"verify.yaml": defaultVerify,
|
|
207
|
-
"context.yaml": `queries:
|
|
208
|
-
- related docs
|
|
209
|
-
- ADR
|
|
210
|
-
- module notes
|
|
211
|
-
- API docs
|
|
212
|
-
fallbackInclude:
|
|
213
|
-
- README.md
|
|
214
|
-
- docs
|
|
215
|
-
`
|
|
5
|
+
import { pathExists } from "./utils.js";
|
|
6
|
+
export function packageRootFromHere() {
|
|
7
|
+
return path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
8
|
+
}
|
|
9
|
+
export function templateRoot(packageRoot = packageRootFromHere()) {
|
|
10
|
+
return path.join(packageRoot, "templates");
|
|
11
|
+
}
|
|
12
|
+
export async function readTemplateFile(relPath, packageRoot = packageRootFromHere()) {
|
|
13
|
+
return readFile(path.join(templateRoot(packageRoot), relPath), "utf8");
|
|
14
|
+
}
|
|
15
|
+
export function renderTemplate(content, vars) {
|
|
16
|
+
return Object.entries(vars).reduce((next, [key, value]) => next.replaceAll(`{{${key}}}`, value), content);
|
|
17
|
+
}
|
|
18
|
+
export async function readTemplateTree(relDir, packageRoot = packageRootFromHere()) {
|
|
19
|
+
const root = path.join(templateRoot(packageRoot), relDir);
|
|
20
|
+
const files = [];
|
|
21
|
+
async function walk(absDir, relBase) {
|
|
22
|
+
const entries = await readdir(absDir, { withFileTypes: true });
|
|
23
|
+
for (const entry of entries) {
|
|
24
|
+
const abs = path.join(absDir, entry.name);
|
|
25
|
+
const rel = path.join(relBase, entry.name);
|
|
26
|
+
if (entry.isDirectory()) {
|
|
27
|
+
await walk(abs, rel);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
files.push({ relPath: rel, content: await readFile(abs, "utf8") });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
216
33
|
}
|
|
217
|
-
|
|
34
|
+
if (await pathExists(root))
|
|
35
|
+
await walk(root, "");
|
|
36
|
+
return files;
|
|
37
|
+
}
|
|
38
|
+
export async function defaultProjectTemplates(packageRoot = packageRootFromHere()) {
|
|
39
|
+
const files = await readTemplateTree("default-project", packageRoot);
|
|
40
|
+
return [{ relPath: "harness.yaml", content: defaultConfigYaml() }, ...files];
|
|
41
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-dev-harness",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Auditable AI development harness for Codex and
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Auditable AI development harness for Codex, Claude Code, Cursor Agent, and Gemini CLI.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"ai",
|
|
@@ -21,7 +21,10 @@
|
|
|
21
21
|
"!dist/**/*.test.js",
|
|
22
22
|
"!dist/testSupport.js",
|
|
23
23
|
"scripts/",
|
|
24
|
+
"templates/",
|
|
24
25
|
"README.md",
|
|
26
|
+
"ONLINE_INSTALL_GUIDE.md",
|
|
27
|
+
"COLLEAGUE_TRIAL_GUIDE.md",
|
|
25
28
|
"package.json"
|
|
26
29
|
],
|
|
27
30
|
"scripts": {
|
|
@@ -14,10 +14,17 @@ $runPath = if (Test-Path -LiteralPath $Run) {
|
|
|
14
14
|
Resolve-Path -LiteralPath (Join-Path $repoPath "runs\$Run")
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
Write-Host "[harness-skill]
|
|
17
|
+
Write-Host "[harness-skill] 证据目录: $runPath"
|
|
18
18
|
|
|
19
19
|
$summary = Join-Path $runPath "summary.md"
|
|
20
20
|
$verify = Join-Path $runPath "verify.json"
|
|
21
|
+
$verifyDiagnostics = Join-Path $runPath "verify_diagnostics.json"
|
|
22
|
+
$contract = Join-Path $runPath "agent_contract.json"
|
|
23
|
+
$contextScore = Join-Path $runPath "context_score.json"
|
|
24
|
+
$approval = Join-Path $runPath "approval_required.json"
|
|
25
|
+
$checkpoint = Join-Path $runPath "checkpoint.json"
|
|
26
|
+
$loopReview = Join-Path $runPath "loop_review.json"
|
|
27
|
+
$loopReport = Join-Path $runPath "loop_report.md"
|
|
21
28
|
$audit = Join-Path $runPath "audit.jsonl"
|
|
22
29
|
|
|
23
30
|
if (Test-Path -LiteralPath $summary) {
|
|
@@ -30,7 +37,42 @@ if (Test-Path -LiteralPath $verify) {
|
|
|
30
37
|
Get-Content -LiteralPath $verify
|
|
31
38
|
}
|
|
32
39
|
|
|
40
|
+
if (Test-Path -LiteralPath $verifyDiagnostics) {
|
|
41
|
+
Write-Host "`n--- verify_diagnostics.json ---"
|
|
42
|
+
Get-Content -LiteralPath $verifyDiagnostics
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (Test-Path -LiteralPath $contract) {
|
|
46
|
+
Write-Host "`n--- agent_contract.json ---"
|
|
47
|
+
Get-Content -LiteralPath $contract
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (Test-Path -LiteralPath $contextScore) {
|
|
51
|
+
Write-Host "`n--- context_score.json ---"
|
|
52
|
+
Get-Content -LiteralPath $contextScore
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (Test-Path -LiteralPath $approval) {
|
|
56
|
+
Write-Host "`n--- approval_required.json ---"
|
|
57
|
+
Get-Content -LiteralPath $approval
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (Test-Path -LiteralPath $checkpoint) {
|
|
61
|
+
Write-Host "`n--- checkpoint.json ---"
|
|
62
|
+
Get-Content -LiteralPath $checkpoint
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (Test-Path -LiteralPath $loopReview) {
|
|
66
|
+
Write-Host "`n--- loop_review.json ---"
|
|
67
|
+
Get-Content -LiteralPath $loopReview
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (Test-Path -LiteralPath $loopReport) {
|
|
71
|
+
Write-Host "`n--- loop_report.md ---"
|
|
72
|
+
Get-Content -LiteralPath $loopReport
|
|
73
|
+
}
|
|
74
|
+
|
|
33
75
|
if (Test-Path -LiteralPath $audit) {
|
|
34
|
-
Write-Host "`n---
|
|
35
|
-
Select-String -LiteralPath $audit -Pattern "
|
|
76
|
+
Write-Host "`n--- 审计失败/错误 ---"
|
|
77
|
+
Select-String -LiteralPath $audit -Pattern "failed|error|evaluate|rework|approval|restore|run_finished" | ForEach-Object { $_.Line }
|
|
36
78
|
}
|
package/scripts/run-harness.ps1
CHANGED
|
@@ -7,7 +7,7 @@ param(
|
|
|
7
7
|
[string]$Skill,
|
|
8
8
|
|
|
9
9
|
[Parameter(Mandatory = $true)]
|
|
10
|
-
[ValidateSet("claude", "codex")]
|
|
10
|
+
[ValidateSet("claude", "codex", "cursor", "gemini")]
|
|
11
11
|
[string]$Agent,
|
|
12
12
|
|
|
13
13
|
[string]$Repo = (Get-Location).Path,
|
|
@@ -19,7 +19,11 @@ $ErrorActionPreference = "Stop"
|
|
|
19
19
|
|
|
20
20
|
$repoPath = Resolve-Path -LiteralPath $Repo
|
|
21
21
|
$harnessYaml = Join-Path $repoPath "harness.yaml"
|
|
22
|
-
$cliPath =
|
|
22
|
+
$cliPath = '{{HARNESS_CLI_PATH}}'
|
|
23
|
+
|
|
24
|
+
if ($cliPath -like '{{*}}') {
|
|
25
|
+
$cliPath = Resolve-Path -LiteralPath (Join-Path $PSScriptRoot "..\dist\cli.js")
|
|
26
|
+
}
|
|
23
27
|
|
|
24
28
|
Write-Host "[harness-skill] repo: $repoPath"
|
|
25
29
|
Write-Host "[harness-skill] checking config: $harnessYaml"
|
|
@@ -33,8 +37,7 @@ if ($LASTEXITCODE -ne 0) {
|
|
|
33
37
|
Write-Error "$repoPath is not a Git repository. AI Dev Harness run requires a business Git repository."
|
|
34
38
|
}
|
|
35
39
|
|
|
36
|
-
$
|
|
37
|
-
$cliPath,
|
|
40
|
+
$argList = @(
|
|
38
41
|
"run",
|
|
39
42
|
"--task",
|
|
40
43
|
$Task,
|
|
@@ -45,9 +48,9 @@ $argsList = @(
|
|
|
45
48
|
)
|
|
46
49
|
|
|
47
50
|
if ($Live) {
|
|
48
|
-
$
|
|
51
|
+
$argList += "--live"
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
Write-Host "[harness-skill] starting harness: $Skill via $Agent"
|
|
52
|
-
node @
|
|
55
|
+
node $cliPath @argList
|
|
53
56
|
exit $LASTEXITCODE
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Project Agent Rules
|
|
2
|
+
|
|
3
|
+
- Work inside this Git repository only.
|
|
4
|
+
- Prefer small, reviewable changes.
|
|
5
|
+
- Do not modify generated or dependency directories.
|
|
6
|
+
- Always explain impact, risk, verification, and follow-up knowledge updates.
|
|
7
|
+
- Before changing code, state assumptions, affected areas, and a minimal plan.
|
|
8
|
+
- If required context is missing or confidence is low, stop and report what is missing instead of guessing.
|
|
9
|
+
- Do not perform broad refactors, formatting-only sweeps, dependency upgrades, or unrelated cleanup unless the task explicitly asks for them.
|