@wnlen/agent-execution-template 0.8.16 → 0.8.18
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 +40 -0
- package/README.zh-CN.md +35 -0
- package/bin/agent-execution-template.js +54 -4
- package/docs/SPEC.md +9 -4
- package/package.json +3 -2
- package/template/en/ai/README.md +3 -19
- package/template/en/ai/project/task.md +26 -3
- package/template/en/ai/template/VERSION +1 -1
- package/template/en/ai/template/execution-policy.md +109 -0
- package/template/en/ai/template/prompt.md +19 -12
- package/template/en/ai/template/protocol.md +9 -64
- package/template/en/ai/template/rules/core.md +10 -27
- package/template/zh/ai/README.md +3 -19
- package/template/zh/ai/project/task.md +20 -2
- package/template/zh/ai/template/VERSION +1 -1
- package/template/zh/ai/template/execution-policy.md +95 -0
- package/template/zh/ai/template/prompt.md +13 -8
- package/template/zh/ai/template/protocol.md +7 -50
- package/template/zh/ai/template/rules/core.md +9 -20
- package/test/check-release.js +94 -0
- package/test/selftest.js +54 -10
package/test/selftest.js
CHANGED
|
@@ -51,6 +51,7 @@ function testInitUpdateDoctor() {
|
|
|
51
51
|
assert(read(cwd, "ai/template/LANG") === "zh\n", "init should default to zh template");
|
|
52
52
|
assert(exists(cwd, "ai/template/VERSION"), "init should create template VERSION");
|
|
53
53
|
assert(exists(cwd, "ai/template/bootstrap.md"), "init should create template bootstrap prompt");
|
|
54
|
+
assert(exists(cwd, "ai/template/execution-policy.md"), "init should create execution policy prompt");
|
|
54
55
|
assert(exists(cwd, "ai/template/prompt.md"), "init should create template prompt");
|
|
55
56
|
assert(exists(cwd, "ai/template/reconcile.md"), "init should create template reconcile prompt");
|
|
56
57
|
assert(exists(cwd, "ai/project/inbox/.gitkeep"), "init should create inbox directory");
|
|
@@ -77,16 +78,21 @@ function testInitUpdateDoctor() {
|
|
|
77
78
|
assert(read(cwd, "ai/template/bootstrap.md").includes("未吸收资料"), "bootstrap handoff should audit unabsorbed material");
|
|
78
79
|
assert(read(cwd, "ai/template/bootstrap.md").includes("冲突处理"), "bootstrap handoff should audit conflict handling");
|
|
79
80
|
assert(read(cwd, "ai/template/prompt.md").includes("任务草稿交接"), "execution prompt should include task handoff");
|
|
81
|
+
assert(read(cwd, "ai/template/prompt.md").includes("ai/template/execution-policy.md"), "execution prompt should read execution policy");
|
|
82
|
+
assert(read(cwd, "ai/template/execution-policy.md").includes("风险分级"), "execution policy should include risk rubric");
|
|
83
|
+
assert(read(cwd, "ai/template/execution-policy.md").includes("execution_policy.task_tree"), "execution policy should require task tree persistence");
|
|
80
84
|
assert(read(cwd, "ai/template/prompt.md").includes("默认也只处理 `ai/project/inbox/*.md`"), "execution prompt should narrow inbox reconciliation");
|
|
81
|
-
assert(read(cwd, "ai/template/protocol.md").includes("
|
|
82
|
-
assert(read(cwd, "ai/template/
|
|
83
|
-
assert(read(cwd, "ai/template/
|
|
84
|
-
assert(read(cwd, "ai/template/
|
|
85
|
+
assert(read(cwd, "ai/template/protocol.md").includes("`bounded_continuous`"), "protocol should include bounded continuous execution");
|
|
86
|
+
assert(read(cwd, "ai/template/execution-policy.md").includes("垂直切片"), "protocol should require vertical-slice progress for continuous execution");
|
|
87
|
+
assert(read(cwd, "ai/template/execution-policy.md").includes("L1 为 2 个或更多,自动启用"), "protocol should auto-enable continuous execution from L1 count");
|
|
88
|
+
assert(read(cwd, "ai/template/execution-policy.md").includes("每个 Checkpoint 必须包含"), "protocol should require evidence-backed checkpoints");
|
|
85
89
|
assert(read(cwd, "ai/template/rules/core.md").includes("边界内连续执行门"), "core rules should include bounded continuous execution gate");
|
|
86
90
|
assert(read(cwd, "ai/template/rules/core.md").includes("需要扩大范围、权限、命令、网络或验收时"), "core rules should stop continuous execution before boundary expansion");
|
|
87
91
|
assert(read(cwd, "ai/project/task.md").includes("execution_policy:"), "task template should include execution policy");
|
|
92
|
+
assert(read(cwd, "ai/project/task.md").includes("readiness:"), "task template should include readiness state");
|
|
88
93
|
assert(read(cwd, "ai/project/task.md").includes("activation_rule: \"auto_enable_when_l1_count_gte_2\""), "task template should define automatic activation rule");
|
|
89
94
|
assert(read(cwd, "ai/project/task.md").includes("risk_gate:"), "task template should define risk gate");
|
|
95
|
+
assert(read(cwd, "ai/project/task.md").includes("status: \"pending | running | done | blocked\""), "task template should define task tree node status");
|
|
90
96
|
assert(read(cwd, "ai/project/task.md").includes("progress_unit: \"vertical_slice\""), "task template should define continuous progress unit");
|
|
91
97
|
assert(read(cwd, "ai/template/prompt.md").includes("开始初始化这个项目"), "execution prompt should route natural bootstrap entry");
|
|
92
98
|
assert(read(cwd, "ai/template/prompt.md").includes("开始初始化这个项目,并吸收 ai/project/inbox/ 里的资料"), "execution prompt should route bootstrap with inbox material");
|
|
@@ -116,6 +122,7 @@ function testInitUpdateDoctor() {
|
|
|
116
122
|
assert(initOutput.includes("把 ai/project/inbox/ideas/ 里的新灵感生成方向修订提案"), "init output should provide natural strategy prompt");
|
|
117
123
|
assert(initOutput.includes("agent-execution-template next"), "init output should tell users how to recover the next step");
|
|
118
124
|
assert(initOutput.includes("文件:"), "init output should summarize file changes");
|
|
125
|
+
assert(!initOutput.includes("维护者提示"), "init output should not show source checkout guidance in user projects");
|
|
119
126
|
assert(!initOutput.includes("[已更新]"), "init output should hide detailed file changes by default");
|
|
120
127
|
assert(!initOutput.includes("Read ai/template/bootstrap.md"), "init output should not use weak Read bootstrap command");
|
|
121
128
|
assert(run(["init", "--verbose"], cwd).includes("[已更新] ai/template/VERSION"), "init --verbose should show detailed file changes");
|
|
@@ -142,6 +149,7 @@ function testEnglishInitUpdateDoctor() {
|
|
|
142
149
|
|
|
143
150
|
const initOutput = run(["init", "--lang", "en"], cwd);
|
|
144
151
|
assert(read(cwd, "ai/template/LANG") === "en\n", "init --lang en should install English template");
|
|
152
|
+
assert(exists(cwd, "ai/template/execution-policy.md"), "English init should create execution policy prompt");
|
|
145
153
|
assert(read(cwd, "ai/template/bootstrap.md").includes("Confirmation Dimensions"), "English init should install English bootstrap prompt");
|
|
146
154
|
assert(read(cwd, "ai/template/bootstrap.md").includes("Do not summarize this file"), "English bootstrap prompt should prevent summary-only behavior");
|
|
147
155
|
assert(read(cwd, "ai/template/bootstrap.md").includes("ai/project/refs/final-shape.md"), "English bootstrap prompt should initialize the North Star");
|
|
@@ -154,16 +162,21 @@ function testEnglishInitUpdateDoctor() {
|
|
|
154
162
|
assert(read(cwd, "ai/template/bootstrap.md").includes("Unabsorbed material"), "English bootstrap handoff should audit unabsorbed material");
|
|
155
163
|
assert(read(cwd, "ai/template/bootstrap.md").includes("Conflict handling"), "English bootstrap handoff should audit conflict handling");
|
|
156
164
|
assert(read(cwd, "ai/template/prompt.md").includes("Start initializing this project"), "English execution prompt should route natural bootstrap entry");
|
|
165
|
+
assert(read(cwd, "ai/template/prompt.md").includes("ai/template/execution-policy.md"), "English execution prompt should read execution policy");
|
|
166
|
+
assert(read(cwd, "ai/template/execution-policy.md").includes("Risk Rubric"), "English execution policy should include risk rubric");
|
|
167
|
+
assert(read(cwd, "ai/template/execution-policy.md").includes("execution_policy.task_tree"), "English execution policy should require task tree persistence");
|
|
157
168
|
assert(read(cwd, "ai/template/prompt.md").includes("default to only `ai/project/inbox/*.md`"), "English execution prompt should narrow inbox reconciliation");
|
|
158
169
|
assert(read(cwd, "ai/template/protocol.md").includes("`bounded_continuous`"), "English protocol should include bounded continuous execution");
|
|
159
|
-
assert(read(cwd, "ai/template/
|
|
160
|
-
assert(read(cwd, "ai/template/
|
|
161
|
-
assert(read(cwd, "ai/template/
|
|
170
|
+
assert(read(cwd, "ai/template/execution-policy.md").includes("vertical"), "English protocol should require vertical-slice progress for continuous execution");
|
|
171
|
+
assert(read(cwd, "ai/template/execution-policy.md").includes("Automatically use `bounded_continuous`"), "English protocol should auto-enable continuous execution from L1 count");
|
|
172
|
+
assert(read(cwd, "ai/template/execution-policy.md").includes("Every checkpoint must include"), "English protocol should require evidence-backed checkpoints");
|
|
162
173
|
assert(read(cwd, "ai/template/rules/core.md").includes("Bounded Continuous Execution Gate"), "English core rules should include bounded continuous execution gate");
|
|
163
174
|
assert(read(cwd, "ai/template/rules/core.md").includes("expand scope, permission, commands, network access, or acceptance"), "English core rules should stop continuous execution before boundary expansion");
|
|
164
175
|
assert(read(cwd, "ai/project/task.md").includes("execution_policy:"), "English task template should include execution policy");
|
|
176
|
+
assert(read(cwd, "ai/project/task.md").includes("readiness:"), "English task template should include readiness state");
|
|
165
177
|
assert(read(cwd, "ai/project/task.md").includes("activation_rule: \"auto_enable_when_l1_count_gte_2\""), "English task template should define automatic activation rule");
|
|
166
178
|
assert(read(cwd, "ai/project/task.md").includes("risk_gate:"), "English task template should define risk gate");
|
|
179
|
+
assert(read(cwd, "ai/project/task.md").includes("status: \"pending | running | done | blocked\""), "English task template should define task tree node status");
|
|
167
180
|
assert(read(cwd, "ai/project/task.md").includes("progress_unit: \"vertical_slice\""), "English task template should define continuous progress unit");
|
|
168
181
|
assert(read(cwd, "ai/template/prompt.md").includes("Start initializing this project and absorb the material in ai/project/inbox/"), "English execution prompt should route bootstrap with inbox material");
|
|
169
182
|
assert(read(cwd, "ai/template/prompt.md").includes("instead of bootstrapping again"), "English execution prompt should reconcile inbox material when project context already exists");
|
|
@@ -190,6 +203,7 @@ function testEnglishInitUpdateDoctor() {
|
|
|
190
203
|
assert(initOutput.includes("Generate a direction amendment proposal from ai/project/inbox/ideas/"), "English init output should provide natural strategy prompt");
|
|
191
204
|
assert(initOutput.includes("agent-execution-template next"), "English init output should tell users how to recover the next step");
|
|
192
205
|
assert(initOutput.includes("Files:"), "English init output should summarize file changes");
|
|
206
|
+
assert(!initOutput.includes("Maintainer note"), "English init output should not show source checkout guidance in user projects");
|
|
193
207
|
assert(!initOutput.includes("[UPDATED]"), "English init output should hide detailed file changes by default");
|
|
194
208
|
assert(run(["init", "--lang=en", "--verbose"], cwd).includes("[UPDATED] ai/template/VERSION"), "English init --verbose should show detailed file changes");
|
|
195
209
|
|
|
@@ -236,6 +250,25 @@ function testDoctorFailureAndWarning() {
|
|
|
236
250
|
write(taskWarnCwd, "ai/project/task.md", "# Task only\n");
|
|
237
251
|
const taskWarnOutput = run(["doctor"], taskWarnCwd);
|
|
238
252
|
assert(taskWarnOutput.includes("任务 front matter 缺少关键字段"), "doctor should warn incomplete task front matter");
|
|
253
|
+
|
|
254
|
+
const taskPolicyWarnCwd = createTempProject("agent-execution-template-task-policy");
|
|
255
|
+
run(["init"], taskPolicyWarnCwd);
|
|
256
|
+
write(taskPolicyWarnCwd, "ai/project/task.md", `---
|
|
257
|
+
task_id: ""
|
|
258
|
+
type: "feature"
|
|
259
|
+
priority: "P2"
|
|
260
|
+
risk_level: "low"
|
|
261
|
+
readiness: "ready_to_execute"
|
|
262
|
+
execution_policy:
|
|
263
|
+
mode: "auto"
|
|
264
|
+
model_policy: {}
|
|
265
|
+
refs: {}
|
|
266
|
+
permission: {}
|
|
267
|
+
---
|
|
268
|
+
# Task
|
|
269
|
+
`);
|
|
270
|
+
const taskPolicyWarnOutput = run(["doctor"], taskPolicyWarnCwd);
|
|
271
|
+
assert(taskPolicyWarnOutput.includes("任务 front matter 缺少关键字段"), "doctor should warn when execution policy fields are incomplete");
|
|
239
272
|
}
|
|
240
273
|
|
|
241
274
|
function testRefreshBacksUpAndImportsOldProject() {
|
|
@@ -271,14 +304,14 @@ function testNextCommandRoutesByProjectState() {
|
|
|
271
304
|
assert(run(["next"], cwd).includes("开始初始化这个项目"), "next should bootstrap a freshly installed project");
|
|
272
305
|
|
|
273
306
|
write(cwd, "ai/project/project.md", "USER PROJECT MARKER\n");
|
|
274
|
-
assert(run(["next"], cwd).includes("
|
|
307
|
+
assert(run(["next"], cwd).includes("执行前先拆 L1 任务"), "next should continue with automatic execution guidance when no intake is waiting");
|
|
275
308
|
|
|
276
309
|
write(cwd, "ai/project/inbox/product.md", "# Product material\n");
|
|
277
310
|
assert(run(["next"], cwd).includes("整合 ai/project/inbox/ 里的新资料"), "next should route material inbox to reconcile");
|
|
278
311
|
fs.unlinkSync(path.join(cwd, "ai/project/inbox/product.md"));
|
|
279
312
|
|
|
280
313
|
write(cwd, "ai/project/inbox/processed/product.md", "# Processed material\n");
|
|
281
|
-
assert(run(["next"], cwd).includes("
|
|
314
|
+
assert(run(["next"], cwd).includes("执行前先拆 L1 任务"), "next should ignore processed inbox material");
|
|
282
315
|
fs.unlinkSync(path.join(cwd, "ai/project/inbox/processed/product.md"));
|
|
283
316
|
|
|
284
317
|
write(cwd, "ai/project/inbox/ideas/new-direction.md", "# Direction idea\n");
|
|
@@ -286,7 +319,7 @@ function testNextCommandRoutesByProjectState() {
|
|
|
286
319
|
fs.unlinkSync(path.join(cwd, "ai/project/inbox/ideas/new-direction.md"));
|
|
287
320
|
|
|
288
321
|
write(cwd, "ai/project/proposals/final-shape-updates/proposal.md", "---\nstatus: \"applied\"\n---\n");
|
|
289
|
-
assert(run(["next"], cwd).includes("
|
|
322
|
+
assert(run(["next"], cwd).includes("执行前先拆 L1 任务"), "next should ignore already applied proposals");
|
|
290
323
|
|
|
291
324
|
write(cwd, "ai/project/proposals/final-shape-updates/proposal.md", "---\nstatus: \"proposed\"\n---\n");
|
|
292
325
|
assert(run(["next"], cwd).includes("已有方向修订提案"), "next should route existing proposals to human review");
|
|
@@ -307,6 +340,16 @@ function testPermissionErrorIsActionable() {
|
|
|
307
340
|
}
|
|
308
341
|
}
|
|
309
342
|
|
|
343
|
+
function testSourceCheckoutNotice() {
|
|
344
|
+
const doctorOutput = run(["doctor"], repoRoot);
|
|
345
|
+
assert(doctorOutput.includes("维护者提示"), "doctor should warn when run in the package source checkout");
|
|
346
|
+
assert(doctorOutput.includes("node bin/agent-execution-template.js <command>"), "source checkout notice should show local node command");
|
|
347
|
+
assert(doctorOutput.includes("不要把维护者本地初始化产生的 ai/project/** 当成产品改动提交"), "source checkout notice should warn against committing local bootstrap context");
|
|
348
|
+
|
|
349
|
+
const nextOutput = run(["next"], repoRoot);
|
|
350
|
+
assert(nextOutput.includes("维护者提示"), "next should warn when run in the package source checkout");
|
|
351
|
+
}
|
|
352
|
+
|
|
310
353
|
function main() {
|
|
311
354
|
testInitUpdateDoctor();
|
|
312
355
|
testEnglishInitUpdateDoctor();
|
|
@@ -314,6 +357,7 @@ function main() {
|
|
|
314
357
|
testRefreshBacksUpAndImportsOldProject();
|
|
315
358
|
testNextCommandRoutesByProjectState();
|
|
316
359
|
testPermissionErrorIsActionable();
|
|
360
|
+
testSourceCheckoutNotice();
|
|
317
361
|
console.log("selftest ok");
|
|
318
362
|
}
|
|
319
363
|
|