@tea-agent/loop-agent 0.26.0 → 0.26.1

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.
Files changed (170) hide show
  1. package/CHANGELOG.md +1032 -1020
  2. package/README.md +8 -3
  3. package/bin/loop-agent.js +21 -21
  4. package/dist/cli/command-definitions.js +25 -10
  5. package/dist/cli/help.js +4 -3
  6. package/dist/cli/program.js +43 -17
  7. package/dist/commands/cursor-prompt.js +6 -6
  8. package/dist/commands/import-prd.js +7 -2
  9. package/dist/commands/init.js +7 -5
  10. package/dist/commands/loop-benchmark.js +11 -11
  11. package/dist/commands/pi-reuse-benchmark.js +16 -16
  12. package/dist/commands/task-source-prepare.js +468 -0
  13. package/dist/executors/dag-pi-executor.js +40 -5
  14. package/dist/executors/shell-write-guard.js +161 -25
  15. package/dist/sidecars/cursor-prompt/executor.js +1 -1
  16. package/dist/task/source-prepare/build-draft.js +215 -0
  17. package/dist/task/source-prepare/completeness.js +195 -0
  18. package/dist/task/source-prepare/index.js +7 -0
  19. package/dist/task/source-prepare/parse-intent.js +373 -0
  20. package/dist/task/source-prepare/path-policy.js +197 -0
  21. package/dist/task/source-prepare/prepare.js +506 -0
  22. package/dist/task/source-prepare/reference-integrity.js +274 -0
  23. package/dist/task/source-prepare/types.js +7 -0
  24. package/dist/worker/observe/static/copy.js +67 -67
  25. package/dist/worker/observe/static/dag-layout.d.ts +31 -31
  26. package/dist/worker/observe/static/dag-layout.js +83 -83
  27. package/dist/worker/observe/static/dom.js +220 -220
  28. package/dist/worker/observe/static/relations.js +133 -133
  29. package/dist/worker/observe/static/router.js +93 -93
  30. package/dist/worker/observe/static/run-processing.js +148 -148
  31. package/dist/worker/observe/static/views/batch.js +227 -227
  32. package/dist/worker/observe/static/views/dag-graph.js +172 -172
  33. package/dist/worker/observe/static/views/failures.js +143 -143
  34. package/dist/worker/observe/static/views/feature.js +492 -492
  35. package/dist/worker/observe/static/views/run.js +453 -453
  36. package/dist/worker/observe/static/views/shell.js +7 -7
  37. package/dist/worker/observe/static/views/timeline.js +163 -163
  38. package/dist/workflows/dag/canvas-observer.js +275 -275
  39. package/docs/skills/README.md +7 -7
  40. package/docs/templates/adr.md +60 -60
  41. package/docs/templates/agent-dag-authority-surface-audit.prompt.md +94 -94
  42. package/docs/templates/agent-dag-decision-envelope.schema.json +213 -213
  43. package/docs/templates/agent-dag-decision-gate.prompt.md +246 -246
  44. package/docs/templates/agent-dag-process-supervisor.prompt.md +98 -98
  45. package/docs/templates/agent-dag-report.schema.json +473 -473
  46. package/docs/templates/agent-dag-review-verdict.prompt.md +68 -68
  47. package/docs/templates/backend-test-result.schema.json +99 -99
  48. package/docs/templates/feature-spec.md +53 -53
  49. package/docs/templates/frontend-design-contract.md +42 -42
  50. package/docs/templates/frontend-eval/fixtures/failures/01-type-build-error.md +17 -17
  51. package/docs/templates/frontend-eval/fixtures/failures/02-unit-component-test-fail.md +16 -16
  52. package/docs/templates/frontend-eval/fixtures/failures/03-fixture-schema-drift.md +16 -16
  53. package/docs/templates/frontend-eval/fixtures/failures/04-missing-loading-empty-error-state.md +16 -16
  54. package/docs/templates/frontend-eval/fixtures/failures/05-forbidden-write-writeset-expansion.md +16 -16
  55. package/docs/templates/frontend-eval/fixtures/failures/06-unapproved-dependency-add.md +16 -16
  56. package/docs/templates/frontend-eval/fixtures/failures/07-mock-production-on.md +21 -21
  57. package/docs/templates/frontend-eval/fixtures/functional/01-simple-component-style.md +29 -29
  58. package/docs/templates/frontend-eval/fixtures/functional/02-form-validation.md +28 -28
  59. package/docs/templates/frontend-eval/fixtures/functional/03-list-detail-page.md +28 -28
  60. package/docs/templates/frontend-eval/fixtures/functional/04-api-mock.md +29 -29
  61. package/docs/templates/frontend-eval/fixtures/functional/05-permission-auth-gated-ui.md +27 -27
  62. package/docs/templates/frontend-eval/fixtures/functional/06-ssr-server-client-boundary.md +28 -28
  63. package/docs/templates/frontend-eval/fixtures/functional/07-shared-public-component-api.md +28 -28
  64. package/docs/templates/frontend-eval/fixtures/functional/08-pure-local-no-remote.md +27 -27
  65. package/docs/templates/frontend-eval/metrics.md +138 -138
  66. package/docs/templates/frontend-eval/smoke-targets.md +53 -53
  67. package/docs/templates/frontend-task-constraints.md +35 -35
  68. package/docs/templates/frontend-task-requirement.md +70 -70
  69. package/docs/templates/init-evolution-review.md +35 -35
  70. package/docs/templates/init-managed-agents.md +10 -5
  71. package/docs/templates/interactive-ui-round2-experiment.md +66 -66
  72. package/docs/templates/knowledge-graph-bootstrap-dag.json +118 -118
  73. package/docs/templates/knowledge-sync-dag.json +178 -178
  74. package/docs/templates/knowledge-sync-draft.schema.json +71 -71
  75. package/docs/templates/product-line/closeout.yaml +9 -9
  76. package/docs/templates/product-line/design.md +13 -13
  77. package/docs/templates/product-line/links.md +10 -10
  78. package/docs/templates/product-line/requirement.md +17 -17
  79. package/docs/templates/product-line/test-plan.md +7 -7
  80. package/docs/templates/production-readiness-checklist.md +57 -57
  81. package/docs/templates/project-start-checklist.md +9 -9
  82. package/docs/templates/qa-report.md +48 -48
  83. package/docs/templates/sprint-contract.md +29 -29
  84. package/docs/templates/worker-dogfood-evidence.md +80 -80
  85. package/docs/templates/worker-dogfood-setup.md +68 -68
  86. package/package.json +1 -1
  87. package/scripts/kb-bootstrap-init-skeleton.sh +0 -0
  88. package/scripts/kb-graph-incremental-prepare.mjs +386 -386
  89. package/scripts/kb-graph-materialize.mjs +105 -105
  90. package/scripts/kb-graph-promote.mjs +164 -164
  91. package/scripts/kb-query.mjs +554 -554
  92. package/skills/ai-engineering-context/SKILL.md +48 -48
  93. package/skills/analyze-product-dependencies/SKILL.md +67 -67
  94. package/skills/analyze-product-dependencies/agents/openai.yaml +4 -4
  95. package/skills/analyze-product-dependencies/references/api-documentation-schema.md +30 -30
  96. package/skills/analyze-product-dependencies/references/dependency-analysis-schema.md +28 -28
  97. package/skills/analyze-product-dependencies/references/example.md +76 -76
  98. package/skills/analyze-product-dependencies/references/forward-test-cases.md +35 -35
  99. package/skills/analyze-product-dependencies/references/input-contract.md +11 -11
  100. package/skills/analyze-product-dependencies/references/scouting-rules.md +61 -61
  101. package/skills/analyze-product-dependencies/scripts/test-validators.mjs +267 -267
  102. package/skills/analyze-product-dependencies/scripts/validate-api-documentation.mjs +101 -101
  103. package/skills/analyze-product-dependencies/scripts/validate-dependency-analysis.mjs +142 -142
  104. package/skills/analyze-product-dependencies/scripts/validate-product-requirement-input.mjs +76 -76
  105. package/skills/analyze-product-dependencies/scripts/validation-helpers.mjs +146 -146
  106. package/skills/analyze-product-requirements/SKILL.md +90 -90
  107. package/skills/analyze-product-requirements/agents/openai.yaml +4 -4
  108. package/skills/analyze-product-requirements/references/acceptance-criteria.md +91 -91
  109. package/skills/analyze-product-requirements/references/clarification-and-knowledge.md +56 -56
  110. package/skills/analyze-product-requirements/references/example.md +86 -86
  111. package/skills/analyze-product-requirements/references/forward-test-cases.md +66 -66
  112. package/skills/analyze-product-requirements/references/product-analysis-schema.md +32 -32
  113. package/skills/analyze-product-requirements/references/product-requirement-schema.md +33 -33
  114. package/skills/analyze-product-requirements/references/requirement-clarification-schema.md +35 -35
  115. package/skills/analyze-product-requirements/scripts/test-validators.mjs +193 -193
  116. package/skills/analyze-product-requirements/scripts/validate-product-analysis.mjs +69 -69
  117. package/skills/analyze-product-requirements/scripts/validate-product-requirement.mjs +97 -97
  118. package/skills/analyze-product-requirements/scripts/validate-requirement-clarification.mjs +98 -98
  119. package/skills/analyze-product-requirements/scripts/validation-helpers.mjs +156 -156
  120. package/skills/browser-tools/browser-content.js +103 -103
  121. package/skills/browser-tools/browser-cookies.js +35 -35
  122. package/skills/browser-tools/browser-eval.js +53 -53
  123. package/skills/browser-tools/browser-hn-scraper.js +108 -108
  124. package/skills/browser-tools/browser-nav.js +44 -44
  125. package/skills/browser-tools/browser-pick.js +162 -162
  126. package/skills/browser-tools/browser-screenshot.js +34 -34
  127. package/skills/browser-tools/browser-start.js +86 -86
  128. package/skills/browser-tools/package-lock.json +2556 -2556
  129. package/skills/browser-tools/package.json +19 -19
  130. package/skills/code-review-core/SKILL.md +20 -20
  131. package/skills/codebase-scout/SKILL.md +19 -19
  132. package/skills/grill-me/SKILL.md +10 -10
  133. package/skills/loop-agent/SKILL.md +5 -2
  134. package/skills/loop-agent/references/README.md +67 -67
  135. package/skills/loop-agent/references/command-reference.md +17 -15
  136. package/skills/loop-agent/references/docs-converge.md +126 -126
  137. package/skills/loop-agent/references/harness-policy.md +3 -4
  138. package/skills/loop-agent/references/learned/README.md +21 -21
  139. package/skills/loop-agent/references/long-running-loop.md +57 -57
  140. package/skills/loop-agent/references/one-shot-runs.md +85 -85
  141. package/skills/loop-agent/references/pi-prompt.md +23 -23
  142. package/skills/loop-agent/references/pi-subagent-assisted-mode.md +84 -84
  143. package/skills/loop-agent/references/post-implementation-and-patterns.md +1 -1
  144. package/skills/loop-agent/references/source-and-plan-practice.md +3 -2
  145. package/skills/loop-agent/references/task-workflow.md +7 -5
  146. package/skills/playwright-cli/SKILL.md +420 -420
  147. package/skills/playwright-cli/references/element-attributes.md +23 -23
  148. package/skills/playwright-cli/references/playwright-tests.md +39 -39
  149. package/skills/playwright-cli/references/request-mocking.md +87 -87
  150. package/skills/playwright-cli/references/running-code.md +241 -241
  151. package/skills/playwright-cli/references/session-management.md +225 -225
  152. package/skills/playwright-cli/references/storage-state.md +275 -275
  153. package/skills/playwright-cli/references/test-generation.md +433 -433
  154. package/skills/playwright-cli/references/tracing.md +139 -139
  155. package/skills/playwright-cli/references/video-recording.md +143 -143
  156. package/skills/requesting-code-review/SKILL.md +101 -101
  157. package/skills/requesting-code-review/code-reviewer.md +168 -168
  158. package/skills/systematic-debugging/CREATION-LOG.md +119 -119
  159. package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -158
  160. package/skills/systematic-debugging/condition-based-waiting.md +115 -115
  161. package/skills/systematic-debugging/defense-in-depth.md +122 -122
  162. package/skills/systematic-debugging/find-polluter.sh +63 -63
  163. package/skills/systematic-debugging/root-cause-tracing.md +169 -169
  164. package/skills/systematic-debugging/test-academic.md +14 -14
  165. package/skills/systematic-debugging/test-pressure-1.md +58 -58
  166. package/skills/systematic-debugging/test-pressure-2.md +68 -68
  167. package/skills/systematic-debugging/test-pressure-3.md +69 -69
  168. package/skills/using-git-worktrees/SKILL.md +215 -215
  169. package/skills/verification-before-completion/SKILL.md +154 -154
  170. package/skills/webapp-testing/SKILL.md +19 -19
package/README.md CHANGED
@@ -56,11 +56,16 @@ loop-agent init reconcile --repo-root .
56
56
 
57
57
  ```bash
58
58
  loop-agent new-task example-task "实现一个有明确验收标准的小功能"
59
- ```
60
59
 
61
- 完善 `.harness/tasks/example-task/source/需求.md` `task.json` 中的结构化写入边界,然后执行:
60
+ # 推荐:先有详细 PRD,再归档并确定性派生执行契约(无需手写两个 source 文件)
61
+ # loop-agent import-prd example-task --file path/to/prd.md --json
62
+ loop-agent task source prepare example-task \
63
+ --use-imported-prd \
64
+ --allowed-path "src/**" \
65
+ --forbidden-path ".harness/**" \
66
+ --verify "typecheck:npm run typecheck" \
67
+ --apply --json
62
68
 
63
- ```bash
64
69
  loop-agent dag run-task example-task \
65
70
  --profile auto \
66
71
  --strict-models \
package/bin/loop-agent.js CHANGED
@@ -1,21 +1,21 @@
1
- #!/usr/bin/env node
2
- import { existsSync } from "node:fs";
3
- import { dirname, join } from "node:path";
4
- import { fileURLToPath, pathToFileURL } from "node:url";
5
-
6
- const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
7
- const cliEntry = join(packageRoot, "dist", "cli.js");
8
-
9
- if (!existsSync(cliEntry)) {
10
- console.error(
11
- `loop-agent: cannot find built CLI at ${cliEntry}. Run \`npm run build\` before using the package bin.`,
12
- );
13
- process.exit(1);
14
- }
15
-
16
- try {
17
- await import(pathToFileURL(cliEntry).href);
18
- } catch (error) {
19
- console.error(error instanceof Error ? error.message : String(error));
20
- process.exit(1);
21
- }
1
+ #!/usr/bin/env node
2
+ import { existsSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
+
6
+ const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
7
+ const cliEntry = join(packageRoot, "dist", "cli.js");
8
+
9
+ if (!existsSync(cliEntry)) {
10
+ console.error(
11
+ `loop-agent: cannot find built CLI at ${cliEntry}. Run \`npm run build\` before using the package bin.`,
12
+ );
13
+ process.exit(1);
14
+ }
15
+
16
+ try {
17
+ await import(pathToFileURL(cliEntry).href);
18
+ } catch (error) {
19
+ console.error(error instanceof Error ? error.message : String(error));
20
+ process.exit(1);
21
+ }
@@ -12,6 +12,7 @@ import { runInstructions } from "../commands/instructions.js";
12
12
  import { runNewTask } from "../commands/new-task.js";
13
13
  import { runImportPrd } from "../commands/import-prd.js";
14
14
  import { runTaskContract } from "../commands/task-contract.js";
15
+ import { runTaskSourcePrepare } from "../commands/task-source-prepare.js";
15
16
  import { runOperator } from "../commands/operator.js";
16
17
  import { runPlanList } from "../commands/plan-list.js";
17
18
  import { runPlanCheck, runPlanComplete, runPlanCreate, } from "../commands/plan.js";
@@ -139,7 +140,7 @@ const DAG_SUBCOMMANDS = [
139
140
  "final-verification",
140
141
  "decision",
141
142
  ];
142
- const TASK_SUBCOMMANDS = ["contract"];
143
+ const TASK_SUBCOMMANDS = ["contract", "source"];
143
144
  const TASK_CONTRACT_SUBCOMMANDS = [
144
145
  "show",
145
146
  "validate",
@@ -149,6 +150,7 @@ const TASK_CONTRACT_SUBCOMMANDS = [
149
150
  "doctor",
150
151
  "recover",
151
152
  ];
153
+ const TASK_SOURCE_SUBCOMMANDS = ["prepare"];
152
154
  const OPERATOR_SUBCOMMANDS = ["capabilities"];
153
155
  const WORKFLOW_SUBCOMMANDS = [
154
156
  "list",
@@ -271,19 +273,32 @@ export const COMMAND_DEFINITIONS = [
271
273
  name: "task",
272
274
  adapter: "required",
273
275
  tier: "primary",
274
- intent: "Task Contract application boundary: show/validate/diff/apply/adopt/doctor/recover managed contract facts.",
275
- usage: "task contract <show|validate|diff|apply|adopt|doctor|recover> ...",
276
+ intent: "Task Contract and source intake: contract show/validate/diff/apply/adopt/doctor/recover; source prepare (PRD-first Draft projection).",
277
+ usage: "task <contract|source> ... (contract <show|validate|diff|apply|adopt|doctor|recover>; source prepare ...)",
276
278
  subcommands: [...TASK_SUBCOMMANDS],
277
279
  handler: async ({ repoRoot, subcommand, rest }) => {
278
- if (subcommand !== "contract") {
279
- throw new Error(formatSubcommandUsageError("task", TASK_SUBCOMMANDS));
280
+ if (subcommand === "contract") {
281
+ const [contractSub, ...contractRest] = rest;
282
+ if (!contractSub ||
283
+ !TASK_CONTRACT_SUBCOMMANDS.includes(contractSub)) {
284
+ throw new Error(`usage: task contract <${TASK_CONTRACT_SUBCOMMANDS.join("|")}> ...`);
285
+ }
286
+ await runTaskContract(repoRoot, [contractSub, ...contractRest]);
287
+ return;
280
288
  }
281
- const [contractSub, ...contractRest] = rest;
282
- if (!contractSub ||
283
- !TASK_CONTRACT_SUBCOMMANDS.includes(contractSub)) {
284
- throw new Error(`usage: task contract <${TASK_CONTRACT_SUBCOMMANDS.join("|")}> ...`);
289
+ if (subcommand === "source") {
290
+ const [sourceSub, ...sourceRest] = rest;
291
+ if (!sourceSub ||
292
+ !TASK_SOURCE_SUBCOMMANDS.includes(sourceSub)) {
293
+ throw new Error(`usage: task source <${TASK_SOURCE_SUBCOMMANDS.join("|")}> ...`);
294
+ }
295
+ if (sourceSub === "prepare") {
296
+ await runTaskSourcePrepare(repoRoot, sourceRest);
297
+ return;
298
+ }
299
+ throw new Error(`usage: task source <${TASK_SOURCE_SUBCOMMANDS.join("|")}> ...`);
285
300
  }
286
- await runTaskContract(repoRoot, [contractSub, ...contractRest]);
301
+ throw new Error(formatSubcommandUsageError("task", TASK_SUBCOMMANDS));
287
302
  },
288
303
  },
289
304
  {
package/dist/cli/help.js CHANGED
@@ -24,9 +24,10 @@ export function formatCommandTierSummary(manifest = CODE_AGENT_COMMAND_MANIFEST)
24
24
  return [
25
25
  "Recommended DAG path:",
26
26
  " 1. new-task <task-id> [title]",
27
- " 2. import-prd <task-id> --file <original-prd> # optional but recommended",
28
- " 3. dag run-task <task-id> --profile auto --strict-models",
29
- " 4. run-dag --dag <path> --cwd <repo-root>",
27
+ " 2. import-prd <task-id> --file <detailed-prd> # PRD-first recommended",
28
+ " 3. task source prepare <task-id> --use-imported-prd --allowed-path <glob> --apply",
29
+ " 4. dag run-task <task-id> --profile auto --strict-models",
30
+ " 5. run-dag --dag <path> --cwd <repo-root>",
30
31
  "Operator recovery/closeout: dag status/report/doctor/closeout-draft",
31
32
  `Primary commands: ${primary}`,
32
33
  `Operator commands: ${operator}`,
@@ -41,6 +41,7 @@ import { runLoopBenchmark } from "../commands/loop-benchmark.js";
41
41
  import { runNewTask } from "../commands/new-task.js";
42
42
  import { runImportPrd } from "../commands/import-prd.js";
43
43
  import { runTaskContract } from "../commands/task-contract.js";
44
+ import { runTaskSourcePrepare } from "../commands/task-source-prepare.js";
44
45
  import { runOperator } from "../commands/operator.js";
45
46
  import { runPiReuseBenchmark } from "../commands/pi-reuse-benchmark.js";
46
47
  import { parsePiPromptArgs, printPiPromptUsage, runPiPrompt, } from "../commands/pi-prompt.js";
@@ -137,25 +138,33 @@ async function runCommanderAction(ctx, command, subcommand, rest) {
137
138
  await runImportPrd(ctx.repoRoot, compactArgs([subcommand, ...rest]));
138
139
  return;
139
140
  case "task": {
140
- if (subcommand !== "contract") {
141
- throw new Error("usage: task <contract> ...");
141
+ if (subcommand === "contract") {
142
+ const [contractSub, ...contractRest] = rest;
143
+ const allowed = [
144
+ "show",
145
+ "validate",
146
+ "diff",
147
+ "apply",
148
+ "adopt",
149
+ "doctor",
150
+ "recover",
151
+ ];
152
+ if (!contractSub ||
153
+ !allowed.includes(contractSub)) {
154
+ throw new Error(`usage: task contract <${allowed.join("|")}> ...`);
155
+ }
156
+ await runTaskContract(ctx.repoRoot, [contractSub, ...contractRest]);
157
+ return;
142
158
  }
143
- const [contractSub, ...contractRest] = rest;
144
- const allowed = [
145
- "show",
146
- "validate",
147
- "diff",
148
- "apply",
149
- "adopt",
150
- "doctor",
151
- "recover",
152
- ];
153
- if (!contractSub ||
154
- !allowed.includes(contractSub)) {
155
- throw new Error(`usage: task contract <${allowed.join("|")}> ...`);
159
+ if (subcommand === "source") {
160
+ const [sourceSub, ...sourceRest] = rest;
161
+ if (sourceSub !== "prepare") {
162
+ throw new Error("usage: task source <prepare> ...");
163
+ }
164
+ await runTaskSourcePrepare(ctx.repoRoot, sourceRest);
165
+ return;
156
166
  }
157
- await runTaskContract(ctx.repoRoot, [contractSub, ...contractRest]);
158
- return;
167
+ throw new Error("usage: task <contract|source> ...");
159
168
  }
160
169
  case "operator":
161
170
  await runOperator(ctx.repoRoot, compactArgs([subcommand, ...rest]));
@@ -437,6 +446,14 @@ function addStandaloneSubcommands(parent, subcommands, handler) {
437
446
  });
438
447
  }
439
448
  }
449
+ function configureTaskSourcePrepare(command) {
450
+ command
451
+ .description("Prepare deterministic task source files from a PRD or draft")
452
+ .usage("<task-id> [options]")
453
+ .option("--from-draft <path>", "TaskContractDraftV1 JSON path")
454
+ .option("--use-imported-prd", "use the task's imported PRD reference")
455
+ .option("--force-overwrite-source", "replace existing managed source files");
456
+ }
440
457
  function configureDagValidate(command) {
441
458
  command
442
459
  .description("Validate an Agent DAG spec")
@@ -662,6 +679,15 @@ export function buildLoopAgentProgram(options) {
662
679
  }
663
680
  if (entry.subcommands)
664
681
  addRawSubcommands(command, entry.subcommands, options.defaultRepoRoot);
682
+ if (entry.name === "task") {
683
+ const source = command.commands.find((child) => child.name() === "source");
684
+ if (source) {
685
+ const prepare = createRawArgsCommand("prepare", "Prepare deterministic task source files", options.defaultRepoRoot);
686
+ configureTaskSourcePrepare(prepare);
687
+ replaceActionWithOptionAwareDispatch(prepare, options.defaultRepoRoot);
688
+ source.addCommand(prepare);
689
+ }
690
+ }
665
691
  program.addCommand(command);
666
692
  }
667
693
  return program;
@@ -141,7 +141,7 @@ async function runCursorPromptBatch(task, cwd, model, timeoutMs) {
141
141
  }
142
142
  async function runCursorPromptStreaming(task, cwd, model, timeoutMs) {
143
143
  const startedAt = Date.now();
144
- process.stderr.write(`[cursor-prompt] streaming (model=${model}, cwd=${cwd})
144
+ process.stderr.write(`[cursor-prompt] streaming (model=${model}, cwd=${cwd})
145
145
  `);
146
146
  const runDir = (await computeRunDir(cwd, task)) ?? undefined;
147
147
  const result = await executeCursorPromptStream({
@@ -164,15 +164,15 @@ async function runCursorPromptStreaming(task, cwd, model, timeoutMs) {
164
164
  });
165
165
  const elapsed = ((Date.now() - startedAt) / 1000).toFixed(1);
166
166
  if (result.ok) {
167
- process.stderr.write(`
168
- [cursor-prompt] done in ${elapsed}s, status=${result.status}
167
+ process.stderr.write(`
168
+ [cursor-prompt] done in ${elapsed}s, status=${result.status}
169
169
  `);
170
170
  }
171
171
  else {
172
172
  const stderr = result.stderr || "(no output)";
173
- process.stderr.write(`
174
- [cursor-prompt] FAILED in ${elapsed}s (${result.failureCategory}):
175
- ${stderr}
173
+ process.stderr.write(`
174
+ [cursor-prompt] FAILED in ${elapsed}s (${result.failureCategory}):
175
+ ${stderr}
176
176
  `);
177
177
  process.exit(1);
178
178
  }
@@ -61,7 +61,11 @@ export async function runImportPrd(repoRoot, args) {
61
61
  .split(path.sep)
62
62
  .join("/"),
63
63
  referenceDocs: result.referenceDocs,
64
- message: "Imported PRD as an immutable source reference. Derive source/需求.md from it; do not rewrite the reference copy.",
64
+ message: "Imported PRD as an immutable source reference. Next: task source prepare --use-imported-prd (plus engineering --allowed-path/--verify) then --apply. Do not rewrite source/references/*.",
65
+ next: [
66
+ `loop-agent task source prepare ${result.taskId} --use-imported-prd --allowed-path <glob> --verify "typecheck:npm run typecheck" --json`,
67
+ `loop-agent task source prepare ${result.taskId} --use-imported-prd --allowed-path <glob> --apply --json`,
68
+ ],
65
69
  }, null, 2));
66
70
  return;
67
71
  }
@@ -71,6 +75,7 @@ export async function runImportPrd(repoRoot, args) {
71
75
  ` materialized: ${result.materializedRelativePath}`,
72
76
  ` sha256: ${result.sha256}`,
73
77
  ` manifest: ${path.relative(repoRoot, result.manifestPath).split(path.sep).join("/")}`,
74
- "Next: write source/需求.md as a derived execution contract with REQ/AC ids that map back to the original PRD. Do not edit source/references/*.",
78
+ "Next: loop-agent task source prepare <task-id> --use-imported-prd --allowed-path <glob> [--verify label:cmd] --apply --json",
79
+ "Do not hand-write source/需求.md or source/执行约束.md on the default path; do not edit source/references/*.",
75
80
  ].join("\n"));
76
81
  }
@@ -1811,14 +1811,15 @@ function buildManagedReadmeBlock(input) {
1811
1811
  "",
1812
1812
  "```bash",
1813
1813
  'loop-agent new-task <task-id> "任务标题"',
1814
- "# write .harness/tasks/<task-id>/source/需求.md",
1815
- "# write .harness/tasks/<task-id>/source/执行约束.md",
1814
+ "# 推荐:详细 PRD → import-prd → task source prepare --apply(无需手写两 source)",
1815
+ "# loop-agent import-prd <task-id> --file <prd.md>",
1816
+ 'loop-agent task source prepare <task-id> --use-imported-prd --allowed-path "<glob>" --apply --json',
1816
1817
  "loop-agent dag run-task <task-id> --profile auto --strict-models",
1817
1818
  "loop-agent dag validate --dag .harness/tasks/<task-id>/dag.json --strict-models --strict-governance",
1818
1819
  "loop-agent run-dag --dag .harness/tasks/<task-id>/dag.json --cwd .",
1819
1820
  "```",
1820
1821
  "",
1821
- `详细工作流见 \`${input.governanceRoot}/feature-workflow.md\`;验证矩阵见 \`${input.governanceRoot}/verification-matrix.md\`。任务 source 是必需项:\`source/需求.md\` 写目标、范围、非目标、验收标准和相关链接,\`source/执行约束.md\` 写允许路径、禁止路径、受保护变更、不变量、预期验证和失败条件。`,
1822
+ `详细工作流见 \`${input.governanceRoot}/feature-workflow.md\`;验证矩阵见 \`${input.governanceRoot}/verification-matrix.md\`。任务 source 仍必需(\`source/需求.md\` / \`source/执行约束.md\`),默认由 \`task source prepare --apply\` 从详细 PRD 确定性派生,而不是主会话手写或 LLM 写 md。`,
1822
1823
  "",
1823
1824
  "执行后使用 `loop-agent dag report --run-id <run-id> --markdown` 和 `loop-agent dag doctor --run-id <run-id> --markdown` 读取事实与诊断失败。失败 run 不做成功式 closeout;使用 `loop-agent dag closeout-draft --run-id <run-id>` 生成 failure handoff。",
1824
1825
  "",
@@ -2043,8 +2044,9 @@ function buildTargetFeatureWorkflow(input) {
2043
2044
  "",
2044
2045
  "```bash",
2045
2046
  'loop-agent new-task <task-id> "Task title"',
2046
- "# write .harness/tasks/<task-id>/source/需求.md",
2047
- "# write .harness/tasks/<task-id>/source/执行约束.md",
2047
+ "# Preferred: detailed PRD → import-prd → task source prepare --apply",
2048
+ "# loop-agent import-prd <task-id> --file <prd.md>",
2049
+ 'loop-agent task source prepare <task-id> --use-imported-prd --allowed-path "<glob>" --apply --json',
2048
2050
  "loop-agent dag run-task <task-id> --profile auto --strict-models",
2049
2051
  "loop-agent dag validate --dag .harness/tasks/<task-id>/dag.json --strict-models --strict-governance",
2050
2052
  "loop-agent run-dag --dag .harness/tasks/<task-id>/dag.json --cwd .",
@@ -37,17 +37,17 @@ export function parseLoopBenchmarkArgs(args) {
37
37
  return { json, markdown, outputPath };
38
38
  }
39
39
  export function printLoopBenchmarkUsage() {
40
- console.log(`usage: loop-benchmark [options]
41
-
42
- Deterministic loop-agent loop benchmark baseline (no live Pi/Cursor calls).
43
-
44
- Options:
45
- --json Emit JSON (default when no format flag is set)
46
- --markdown Emit Markdown report
47
- --output <path> Write Markdown report to a repo-relative or absolute path
48
- -h, --help Show this help
49
-
50
- Control groups: single-repair, 3-pass-convergence, 3-pass-convergence+quota.
40
+ console.log(`usage: loop-benchmark [options]
41
+
42
+ Deterministic loop-agent loop benchmark baseline (no live Pi/Cursor calls).
43
+
44
+ Options:
45
+ --json Emit JSON (default when no format flag is set)
46
+ --markdown Emit Markdown report
47
+ --output <path> Write Markdown report to a repo-relative or absolute path
48
+ -h, --help Show this help
49
+
50
+ Control groups: single-repair, 3-pass-convergence, 3-pass-convergence+quota.
51
51
  Recommendation never changes convergence.enabled default.`);
52
52
  }
53
53
  export async function runLoopBenchmark(repoRoot, rawArgs) {
@@ -106,22 +106,22 @@ export function parsePiReuseBenchmarkArgs(args) {
106
106
  };
107
107
  }
108
108
  export function printPiReuseBenchmarkUsage() {
109
- console.log(`usage: pi-reuse-benchmark [options]
110
-
111
- Deterministic Pi runtime reuse benchmark/decision summary (no live Pi calls).
112
-
113
- Options:
114
- --report <path> Benchmark report markdown (approval status)
115
- --approval <path> Explicit approval JSON artifact
116
- --off-executor <path> Baseline executor.jsonl (reuse off)
117
- --on-executor <path> Treatment executor.jsonl (reuse on)
118
- --off-task <task-id> Resolve baseline from .harness/tasks/<id>/logs/executor.jsonl
119
- --on-task <task-id> Resolve treatment from .harness/tasks/<id>/logs/executor.jsonl
120
- --json Emit JSON (default when no format flag is set)
121
- --markdown Emit Markdown summary
122
- -h, --help Show this help
123
-
124
- Recommendations: defer | maintain-opt-in | eligible-for-human-review
109
+ console.log(`usage: pi-reuse-benchmark [options]
110
+
111
+ Deterministic Pi runtime reuse benchmark/decision summary (no live Pi calls).
112
+
113
+ Options:
114
+ --report <path> Benchmark report markdown (approval status)
115
+ --approval <path> Explicit approval JSON artifact
116
+ --off-executor <path> Baseline executor.jsonl (reuse off)
117
+ --on-executor <path> Treatment executor.jsonl (reuse on)
118
+ --off-task <task-id> Resolve baseline from .harness/tasks/<id>/logs/executor.jsonl
119
+ --on-task <task-id> Resolve treatment from .harness/tasks/<id>/logs/executor.jsonl
120
+ --json Emit JSON (default when no format flag is set)
121
+ --markdown Emit Markdown summary
122
+ -h, --help Show this help
123
+
124
+ Recommendations: defer | maintain-opt-in | eligible-for-human-review
125
125
  Never changes CODE_AGENT_PI_REUSE_RUNTIME default (off).`);
126
126
  }
127
127
  function resolveRepoRelative(repoRoot, filePath) {