@tea-agent/loop-agent 0.26.5-beta.1 → 0.27.0
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/AGENTS.md +2 -2
- package/CHANGELOG.md +29 -0
- package/README.md +13 -23
- package/dist/application/dag/args.js +7 -7
- package/dist/application/dag/generate-task-dag.js +2 -2
- package/dist/application/dag/run-dag.js +3 -4
- package/dist/application/dag/validate-dag.js +1 -1
- package/dist/application/task-lifecycle/advance.js +845 -0
- package/dist/application/task-lifecycle/gates.js +80 -0
- package/dist/application/task-lifecycle/index.js +7 -0
- package/dist/application/task-lifecycle/observe.js +395 -0
- package/dist/application/task-lifecycle/plan-transitions.js +224 -0
- package/dist/application/task-lifecycle/recommendations.js +180 -0
- package/dist/application/task-lifecycle/record.js +73 -0
- package/dist/application/task-lifecycle/types.js +1 -0
- package/dist/cli/command-definitions.js +14 -111
- package/dist/cli/help.js +6 -7
- package/dist/cli/program.js +26 -90
- package/dist/cli/update/policy.js +0 -1
- package/dist/commands/dag-final-verification.js +1 -1
- package/dist/commands/dag-init-hybrid.js +1 -1
- package/dist/commands/delegate.js +2 -2
- package/dist/commands/init.js +21 -19
- package/dist/commands/run-dag-progress.js +1 -1
- package/dist/commands/status.js +18 -17
- package/dist/commands/study-init.js +2 -2
- package/dist/commands/task-advance.js +335 -0
- package/dist/commands/task-contract.js +3 -5
- package/dist/commands/task-source-prepare.js +9 -4
- package/dist/commands/task-status.js +133 -0
- package/dist/governance/manifest-types.js +2 -2
- package/dist/shared/operator/capabilities.js +1358 -243
- package/dist/task/contract/adopt.js +1 -1
- package/dist/task/contract/apply.js +1 -1
- package/dist/task/contract/import-revision.js +1 -1
- package/dist/task/contract/recover.js +2 -2
- package/dist/task/read-model.js +18 -23
- package/dist/task/runtime.js +1 -1
- package/dist/task/source-prepare/completeness.js +1 -1
- package/dist/task/source-prepare/parse-intent.js +6 -1
- package/dist/task/source-prepare/prepare.js +23 -20
- package/dist/worker/console/operator-actions.js +288 -95
- package/dist/worker/console/recovery-cta.js +4 -4
- package/dist/worker/console/static/assets/{index-CSRIhuzh.js → index-CNO7n6qB.js} +1 -1
- package/dist/worker/console/static/index.html +1 -1
- package/dist/worker/materialize/harness-task-materializer.js +6 -5
- package/dist/worker/run-task/run-task.js +204 -112
- package/dist/worker/runner/run-ready.js +1 -1
- package/dist/workflows/dag/frontend-implementation-contract.js +5 -57
- package/dist/workflows/dag/frontend-prewrite-gate.js +1 -6
- package/dist/workflows/dag/init-hybrid.js +11 -42
- package/docs/templates/evaluation/agents-map-slim-v1.md +1 -1
- package/docs/templates/evaluation/agents-map-verbose-v0.md +3 -3
- package/docs/templates/harness.schema.json +2 -2
- package/docs/templates/init-managed-agents.md +13 -16
- package/docs/templates/production-readiness-checklist.md +3 -3
- package/harness.json +4 -4
- package/package.json +1 -1
- package/scripts/kb-bootstrap-init-skeleton.sh +2 -1
- package/scripts/kb-graph-incremental-prepare.mjs +2 -2
- package/skills/loop-agent/SKILL.md +18 -13
- package/skills/loop-agent/references/README.md +1 -1
- package/skills/loop-agent/references/command-reference.md +55 -84
- package/skills/loop-agent/references/harness-policy.md +19 -23
- package/skills/loop-agent/references/hybrid-dag.md +31 -33
- package/skills/loop-agent/references/long-running-loop.md +2 -2
- package/skills/loop-agent/references/one-shot-runs.md +4 -5
- package/skills/loop-agent/references/orchestrator-and-interventions.md +3 -3
- package/skills/loop-agent/references/post-implementation-and-patterns.md +4 -4
- package/skills/loop-agent/references/source-and-plan-practice.md +45 -51
- package/skills/loop-agent/references/task-workflow.md +14 -15
package/dist/cli/help.js
CHANGED
|
@@ -22,13 +22,12 @@ export function formatCommandTierSummary(manifest = CODE_AGENT_COMMAND_MANIFEST)
|
|
|
22
22
|
.map((entry) => entry.name)
|
|
23
23
|
.join(", ");
|
|
24
24
|
return [
|
|
25
|
-
"Recommended
|
|
26
|
-
" 1.
|
|
27
|
-
" 2.
|
|
28
|
-
" 3. task
|
|
29
|
-
" 4.
|
|
30
|
-
"
|
|
31
|
-
"Operator recovery/closeout: dag status/report/doctor/closeout-draft",
|
|
25
|
+
"Recommended task lifecycle (single mutation + single read):",
|
|
26
|
+
" 1. task advance <task-id> [title] --prd <prd.md> --allowed-path <glob> --verify <label:command> --json",
|
|
27
|
+
" 2. review writeSet gate digest from JSON",
|
|
28
|
+
" 3. task advance <task-id> --approve-gate write-set-review:<digest> --json",
|
|
29
|
+
" 4. task status <task-id> --json # optional read-only",
|
|
30
|
+
"Advanced DAG authoring/forensics: dag validate|execute|report|workflow-* (not the standard happy path)",
|
|
32
31
|
`Primary commands: ${primary}`,
|
|
33
32
|
`Operator commands: ${operator}`,
|
|
34
33
|
compatibility ? `Legacy compatibility commands: ${compatibility}` : "",
|
package/dist/cli/program.js
CHANGED
|
@@ -3,7 +3,6 @@ import { fileURLToPath } from "node:url";
|
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import { readPackageVersion } from "../shared/package-metadata.js";
|
|
5
5
|
import { resolveAdapter } from "../adapters/index.js";
|
|
6
|
-
import { runCloseout } from "../commands/closeout.js";
|
|
7
6
|
import { runCoverageAudit } from "../commands/coverage-audit.js";
|
|
8
7
|
import { runCoverageReport } from "../commands/coverage-report.js";
|
|
9
8
|
import { parseCursorPromptArgs, printCursorPromptUsage, runCursorPrompt, } from "../commands/cursor-prompt.js";
|
|
@@ -17,7 +16,6 @@ import { runDagRerun } from "../commands/dag-rerun.js";
|
|
|
17
16
|
import { runDagReject } from "../commands/dag-reject.js";
|
|
18
17
|
import { runDagCloseoutDraft, runDagReport } from "../commands/dag-report.js";
|
|
19
18
|
import { runDagResume } from "../commands/dag-resume.js";
|
|
20
|
-
import { runDagRunTask } from "../commands/dag-run-task.js";
|
|
21
19
|
import { runDagValidate } from "../commands/dag-validate.js";
|
|
22
20
|
import { runDagWorkflowCompile } from "../commands/dag-workflow-compile.js";
|
|
23
21
|
import { runDagWorkflowPlan } from "../commands/dag-workflow-plan.js";
|
|
@@ -38,21 +36,17 @@ import { runInstructions } from "../commands/instructions.js";
|
|
|
38
36
|
import { runKnowledge } from "../commands/knowledge.js";
|
|
39
37
|
import { runLoop } from "../commands/loop.js";
|
|
40
38
|
import { runLoopBenchmark } from "../commands/loop-benchmark.js";
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import { runTaskContract } from "../commands/task-contract.js";
|
|
44
|
-
import { runTaskSourcePrepare } from "../commands/task-source-prepare.js";
|
|
39
|
+
import { runTaskAdvance } from "../commands/task-advance.js";
|
|
40
|
+
import { runTaskStatus } from "../commands/task-status.js";
|
|
45
41
|
import { runOperator } from "../commands/operator.js";
|
|
46
42
|
import { runPiReuseBenchmark } from "../commands/pi-reuse-benchmark.js";
|
|
47
43
|
import { parsePiPromptArgs, printPiPromptUsage, runPiPrompt, } from "../commands/pi-prompt.js";
|
|
48
44
|
import { runPlanList } from "../commands/plan-list.js";
|
|
49
45
|
import { runPlanCheck, runPlanComplete, runPlanCreate, } from "../commands/plan.js";
|
|
50
|
-
import { runPromoteRun } from "../commands/promote-run.js";
|
|
51
46
|
import { runReferenceIndex } from "../commands/reference-index.js";
|
|
52
47
|
import { runRunDag } from "../commands/run-dag.js";
|
|
53
48
|
import { runSpine } from "../commands/spine.js";
|
|
54
49
|
import { runStats } from "../commands/stats.js";
|
|
55
|
-
import { runStatus } from "../commands/status.js";
|
|
56
50
|
import { runStudyInit } from "../commands/study-init.js";
|
|
57
51
|
import { runWorkflowCommand } from "../commands/workflow.js";
|
|
58
52
|
import { runWorktreeCreate } from "../commands/worktree-create.js";
|
|
@@ -116,6 +110,17 @@ async function dispatchRegisteredCommand(commandObject, defaultRepoRoot, rawArgs
|
|
|
116
110
|
};
|
|
117
111
|
await runCommanderAction(ctx, command, subcommand, rest);
|
|
118
112
|
}
|
|
113
|
+
async function runTaskCommand(repoRoot, subcommand, rest) {
|
|
114
|
+
if (subcommand === "advance") {
|
|
115
|
+
await runTaskAdvance(repoRoot, rest);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (subcommand === "status") {
|
|
119
|
+
await runTaskStatus(repoRoot, rest);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
throw new Error("usage: task <advance|status> ...");
|
|
123
|
+
}
|
|
119
124
|
async function runCommanderAction(ctx, command, subcommand, rest) {
|
|
120
125
|
switch (command) {
|
|
121
126
|
case "inspect":
|
|
@@ -127,63 +132,16 @@ async function runCommanderAction(ctx, command, subcommand, rest) {
|
|
|
127
132
|
case "docs":
|
|
128
133
|
await runDocsCommand(ctx.repoRoot, subcommand, rest);
|
|
129
134
|
return;
|
|
130
|
-
case "new-task": {
|
|
131
|
-
const [taskId, ...titleParts] = [subcommand, ...rest];
|
|
132
|
-
if (!taskId)
|
|
133
|
-
throw new Error("taskId required");
|
|
134
|
-
await runNewTask(ctx.repoRoot, taskId, titleParts.join(" ") || undefined);
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
case "import-prd":
|
|
138
|
-
await runImportPrd(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
139
|
-
return;
|
|
140
135
|
case "task": {
|
|
141
|
-
|
|
142
|
-
|
|
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;
|
|
158
|
-
}
|
|
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;
|
|
166
|
-
}
|
|
167
|
-
throw new Error("usage: task <contract|source> ...");
|
|
136
|
+
await runTaskCommand(ctx.repoRoot, subcommand, rest);
|
|
137
|
+
return;
|
|
168
138
|
}
|
|
169
139
|
case "operator":
|
|
170
140
|
await runOperator(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
171
141
|
return;
|
|
172
|
-
case "status": {
|
|
173
|
-
if (!subcommand)
|
|
174
|
-
throw new Error("taskId required");
|
|
175
|
-
await runStatus(ctx.repoRoot, subcommand);
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
142
|
case "instructions":
|
|
179
143
|
await runInstructions(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
180
144
|
return;
|
|
181
|
-
case "promote-run":
|
|
182
|
-
await runPromoteRun(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
183
|
-
return;
|
|
184
|
-
case "closeout":
|
|
185
|
-
await runCloseout(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
186
|
-
return;
|
|
187
145
|
case "stats":
|
|
188
146
|
await runStats(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
189
147
|
return;
|
|
@@ -240,9 +198,6 @@ async function runCommanderAction(ctx, command, subcommand, rest) {
|
|
|
240
198
|
case "dag":
|
|
241
199
|
await runDagAction(ctx.repoRoot, subcommand, rest);
|
|
242
200
|
return;
|
|
243
|
-
case "run-dag":
|
|
244
|
-
await runRunDag(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
245
|
-
return;
|
|
246
201
|
case "workflow":
|
|
247
202
|
await runWorkflowCommand(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
248
203
|
return;
|
|
@@ -364,8 +319,8 @@ async function runDagAction(repoRoot, subcommand, rest) {
|
|
|
364
319
|
case "doctor":
|
|
365
320
|
await runDagDoctor(repoRoot, args);
|
|
366
321
|
return;
|
|
367
|
-
case "
|
|
368
|
-
await
|
|
322
|
+
case "execute":
|
|
323
|
+
await runRunDag(repoRoot, args);
|
|
369
324
|
return;
|
|
370
325
|
case "report":
|
|
371
326
|
await runDagReport(repoRoot, args);
|
|
@@ -401,7 +356,7 @@ async function runDagAction(repoRoot, subcommand, rest) {
|
|
|
401
356
|
throw new Error("usage: dag decision <inspect|validate> --run-id <id> [--node-id <node-id>]");
|
|
402
357
|
}
|
|
403
358
|
default:
|
|
404
|
-
throw new Error("usage: dag <init-hybrid|
|
|
359
|
+
throw new Error("usage: dag <init-hybrid|execute|validate|workflow-plan|workflow-validate|workflow-compile|approve|reject|resume|status|doctor|report|closeout-draft|reconcile-run|rerun|rerun-task|reconcile-tasks|final-verification|decision> ...");
|
|
405
360
|
}
|
|
406
361
|
}
|
|
407
362
|
function compactArgs(args) {
|
|
@@ -431,7 +386,8 @@ function createRawArgsCommand(name, description, defaultRepoRoot) {
|
|
|
431
386
|
}
|
|
432
387
|
function addRawSubcommands(parent, subcommands, defaultRepoRoot) {
|
|
433
388
|
for (const subcommand of subcommands) {
|
|
434
|
-
|
|
389
|
+
const command = createRawArgsCommand(subcommand, `${parent.name()} ${subcommand}`, defaultRepoRoot);
|
|
390
|
+
parent.addCommand(command);
|
|
435
391
|
}
|
|
436
392
|
}
|
|
437
393
|
function addStandaloneSubcommands(parent, subcommands, handler) {
|
|
@@ -464,9 +420,9 @@ function configureDagValidate(command) {
|
|
|
464
420
|
.option("--forbid-executor <executor>", "forbid executor", (value, previous = []) => [...previous, value])
|
|
465
421
|
.option("--spine-task <task-id>", "run spine audit for task id");
|
|
466
422
|
}
|
|
467
|
-
function
|
|
423
|
+
function configureDagExecute(command) {
|
|
468
424
|
command
|
|
469
|
-
.description("
|
|
425
|
+
.description("Advanced: execute an arbitrary DagSpec JSON (standard task path uses task advance)")
|
|
470
426
|
.option("--dag <path>", "DAG spec path")
|
|
471
427
|
.option("-C, --cwd <dir>", "working directory")
|
|
472
428
|
.option("--init-only", "initialize run artifacts without executing")
|
|
@@ -480,22 +436,6 @@ function configureRunDag(command) {
|
|
|
480
436
|
.option("--canvases-dir <dir>", "canvas output directory")
|
|
481
437
|
.option("--events-jsonl <path>", "append DAG node events to a JSONL file");
|
|
482
438
|
}
|
|
483
|
-
function configureDagRunTask(command) {
|
|
484
|
-
command
|
|
485
|
-
.description("Create and optionally execute a DAG for a task")
|
|
486
|
-
.option("-o, --output <path>", "output DAG path")
|
|
487
|
-
.option("--profile <profile>", "auto|minimal|standard|reviewed|supervised")
|
|
488
|
-
.option("--strict-models", "fail on model routing warnings")
|
|
489
|
-
.option("--execute", "execute after creating the DAG")
|
|
490
|
-
.option("--init-only", "initialize run artifacts without executing")
|
|
491
|
-
.option("--dry-run", "validate and plan without executing")
|
|
492
|
-
.option("--cwd <dir>", "working directory")
|
|
493
|
-
.option("--max-concurrent <n>", "maximum concurrent nodes")
|
|
494
|
-
.option("--run-id <id>", "run id")
|
|
495
|
-
.option("--canvas-path <path>", "absolute canvas output path")
|
|
496
|
-
.option("--canvas <name>", "canvas name")
|
|
497
|
-
.option("--canvases-dir <dir>", "canvas output directory");
|
|
498
|
-
}
|
|
499
439
|
function optionTokens(command) {
|
|
500
440
|
const tokens = [];
|
|
501
441
|
const options = command.opts();
|
|
@@ -562,10 +502,10 @@ function addDagCommand(program, defaultRepoRoot) {
|
|
|
562
502
|
configureDagValidate(validate);
|
|
563
503
|
replaceActionWithOptionAwareDispatch(validate, defaultRepoRoot);
|
|
564
504
|
dag.addCommand(validate);
|
|
565
|
-
const
|
|
566
|
-
|
|
567
|
-
replaceActionWithOptionAwareDispatch(
|
|
568
|
-
dag.addCommand(
|
|
505
|
+
const execute = createRawArgsCommand("execute", "Advanced: execute an arbitrary DagSpec JSON", defaultRepoRoot);
|
|
506
|
+
configureDagExecute(execute);
|
|
507
|
+
replaceActionWithOptionAwareDispatch(execute, defaultRepoRoot);
|
|
508
|
+
dag.addCommand(execute);
|
|
569
509
|
const decision = new Command("decision").description("DAG decision envelope commands");
|
|
570
510
|
addRawSubcommands(decision, ["inspect", "validate"], defaultRepoRoot);
|
|
571
511
|
dag.addCommand(decision);
|
|
@@ -673,10 +613,6 @@ export function buildLoopAgentProgram(options) {
|
|
|
673
613
|
continue;
|
|
674
614
|
}
|
|
675
615
|
const command = createRawArgsCommand(entry.name, entry.intent, options.defaultRepoRoot);
|
|
676
|
-
if (entry.name === "run-dag") {
|
|
677
|
-
configureRunDag(command);
|
|
678
|
-
replaceActionWithOptionAwareDispatch(command, options.defaultRepoRoot);
|
|
679
|
-
}
|
|
680
616
|
if (entry.subcommands)
|
|
681
617
|
addRawSubcommands(command, entry.subcommands, options.defaultRepoRoot);
|
|
682
618
|
if (entry.name === "task") {
|
|
@@ -65,7 +65,7 @@ export async function runDagFinalVerification(repoRoot, rawArgs) {
|
|
|
65
65
|
next: [
|
|
66
66
|
`Review ${result.outputPath}`,
|
|
67
67
|
`npm run dev -- dag validate --dag ${result.outputPath} --strict-models --strict-governance`,
|
|
68
|
-
`npm run dev --
|
|
68
|
+
`npm run dev -- dag execute --dag ${result.outputPath} --cwd ${repoRoot}`,
|
|
69
69
|
],
|
|
70
70
|
}, null, 2));
|
|
71
71
|
}
|
|
@@ -51,7 +51,7 @@ export async function runDagInitHybrid(repoRoot, rawArgs) {
|
|
|
51
51
|
next: [
|
|
52
52
|
`Review ${result.outputPath}`,
|
|
53
53
|
`npm run dev -- dag validate --dag ${result.outputPath}`,
|
|
54
|
-
"Use
|
|
54
|
+
"Use dag execute --dry-run only when you intentionally need an active run snapshot.",
|
|
55
55
|
],
|
|
56
56
|
}, null, 2));
|
|
57
57
|
}
|
|
@@ -64,9 +64,9 @@ export function printDelegateNextSteps(taskId, result) {
|
|
|
64
64
|
` worktree: ${result.worktreePath}`,
|
|
65
65
|
` Next — generate, validate, and run DAG in the worktree:`,
|
|
66
66
|
` cd ${JSON.stringify(result.worktreePath)}`,
|
|
67
|
-
` loop-agent --repo-root ${JSON.stringify(result.worktreePath)}
|
|
67
|
+
` loop-agent --repo-root ${JSON.stringify(result.worktreePath)} task advance ${taskId} --profile auto --json`,
|
|
68
68
|
` loop-agent dag validate --dag ${JSON.stringify(dagPath)} --strict-models --strict-governance`,
|
|
69
|
-
` loop-agent
|
|
69
|
+
` loop-agent dag execute --dag ${JSON.stringify(dagPath)} --cwd ${JSON.stringify(result.worktreePath)}`,
|
|
70
70
|
` Or: loop-agent delegate ${taskId} --auto-run`,
|
|
71
71
|
` After work completes:`,
|
|
72
72
|
` loop-agent harvest ${taskId}`,
|
package/dist/commands/init.js
CHANGED
|
@@ -446,7 +446,7 @@ check_skill "agent-worker" "references/agent-worker-operator.md"
|
|
|
446
446
|
# against the whole skill file so host auto-discovery phrasing cannot drift.
|
|
447
447
|
loop_agent_skill=".agents/skills/loop-agent/SKILL.md"
|
|
448
448
|
loop_agent_text="$(tr '[:upper:]' '[:lower:]' < "\${loop_agent_skill}")"
|
|
449
|
-
for term in "loop-agent 帮我完成" "帮我实现" "帮我修复" "帮我开发" "agent dag" "
|
|
449
|
+
for term in "loop-agent 帮我完成" "帮我实现" "帮我修复" "帮我开发" "agent dag" "task advance" "task status" "dag validate" "dag execute"; do
|
|
450
450
|
if [[ "\${loop_agent_text}" != *"\${term}"* ]]; then
|
|
451
451
|
echo "skill entry 检查失败(loop-agent):description 缺少触发/路由词 \${term}" >&2
|
|
452
452
|
exit 1
|
|
@@ -1810,16 +1810,17 @@ function buildManagedReadmeBlock(input) {
|
|
|
1810
1810
|
"默认使用 Agent DAG 作为实现工作流:",
|
|
1811
1811
|
"",
|
|
1812
1812
|
"```bash",
|
|
1813
|
-
'loop-agent
|
|
1814
|
-
"
|
|
1815
|
-
|
|
1816
|
-
'
|
|
1817
|
-
"
|
|
1818
|
-
"
|
|
1819
|
-
|
|
1813
|
+
'loop-agent task advance <task-id> "任务标题" \\',
|
|
1814
|
+
" --prd <prd.md> \\",
|
|
1815
|
+
' --allowed-path "<glob>" \\',
|
|
1816
|
+
' --verify "typecheck:npm run typecheck" \\',
|
|
1817
|
+
" --json",
|
|
1818
|
+
"# 审查 writeSet gate digest 后:",
|
|
1819
|
+
'loop-agent task advance <task-id> --approve-gate "write-set-review:<digest>" --json',
|
|
1820
|
+
"loop-agent task status <task-id> --json",
|
|
1820
1821
|
"```",
|
|
1821
1822
|
"",
|
|
1822
|
-
`详细工作流见 \`${input.governanceRoot}/feature-workflow.md\`;验证矩阵见 \`${input.governanceRoot}/verification-matrix.md\`。任务 source 仍必需(\`source/需求.md\` / \`source/执行约束.md\`),默认由 \`task
|
|
1823
|
+
`详细工作流见 \`${input.governanceRoot}/feature-workflow.md\`;验证矩阵见 \`${input.governanceRoot}/verification-matrix.md\`。任务 source 仍必需(\`source/需求.md\` / \`source/执行约束.md\`),默认由 \`task advance --prd\` 从详细 PRD 确定性派生,而不是主会话手写或 LLM 写 md。高级任意 DagSpec 才用 \`dag validate|execute|report\`,不进入标准 happy path。`,
|
|
1823
1824
|
"",
|
|
1824
1825
|
"执行后使用 `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。",
|
|
1825
1826
|
"",
|
|
@@ -2043,13 +2044,14 @@ function buildTargetFeatureWorkflow(input) {
|
|
|
2043
2044
|
"## Agent DAG Path",
|
|
2044
2045
|
"",
|
|
2045
2046
|
"```bash",
|
|
2046
|
-
'loop-agent
|
|
2047
|
-
"
|
|
2048
|
-
|
|
2049
|
-
'
|
|
2050
|
-
"
|
|
2051
|
-
"
|
|
2052
|
-
|
|
2047
|
+
'loop-agent task advance <task-id> "Task title" \\',
|
|
2048
|
+
" --prd <prd.md> \\",
|
|
2049
|
+
' --allowed-path "<glob>" \\',
|
|
2050
|
+
' --verify "typecheck:npm run typecheck" \\',
|
|
2051
|
+
" --json",
|
|
2052
|
+
"# Review writeSet gate digest, then:",
|
|
2053
|
+
'loop-agent task advance <task-id> --approve-gate "write-set-review:<digest>" --json',
|
|
2054
|
+
"loop-agent task status <task-id> --json",
|
|
2053
2055
|
"```",
|
|
2054
2056
|
"",
|
|
2055
2057
|
DAG_HARD_GATE_TRIGGER,
|
|
@@ -2082,7 +2084,7 @@ function buildTargetFeatureWorkflow(input) {
|
|
|
2082
2084
|
"```bash",
|
|
2083
2085
|
"loop-agent knowledge graph-init --product-name <name>",
|
|
2084
2086
|
"# edit knowledge/bootstrap/scope.yaml, then:",
|
|
2085
|
-
"loop-agent
|
|
2087
|
+
"loop-agent task advance <task-id> --task-kind knowledge-graph-bootstrap --json",
|
|
2086
2088
|
"loop-agent knowledge query --mode by_feature --feature F-2026-004 --json",
|
|
2087
2089
|
"loop-agent knowledge query --mode by_id --id SVC-order --json",
|
|
2088
2090
|
'loop-agent knowledge query --mode search --text "keyword" --json',
|
|
@@ -2156,14 +2158,14 @@ function buildTargetLoopAgentHarness(input) {
|
|
|
2156
2158
|
"",
|
|
2157
2159
|
"## Default Workflow",
|
|
2158
2160
|
"",
|
|
2159
|
-
"Use `loop-agent
|
|
2161
|
+
"Use `loop-agent task advance` / `loop-agent task status` for non-trivial implementation work; advanced arbitrary DagSpec uses `loop-agent dag execute`.",
|
|
2160
2162
|
"",
|
|
2161
2163
|
"## Adaptive Liveness",
|
|
2162
2164
|
"",
|
|
2163
2165
|
"- Healthy Pi nodes are no longer stopped by a fixed 30-minute deadline. The default 4h absolute max is a final safety bound and cannot be extended by synthetic heartbeats.",
|
|
2164
2166
|
"- Runner heartbeat proves only the runner lease. Provider, tool, or output activity records meaningful progress; prolonged inactivity can surface as `quiet`, `suspected-stall`, `probing`, or `needs-attention` in `dag status`, `dag doctor`, and Observe.",
|
|
2165
2167
|
"- A silent transport is aborted in a controlled way. `termination-unconfirmed` means the old attempt may still exist, so loop-agent fails closed and does not start an automatic retry; inspect the run before any operator recovery.",
|
|
2166
|
-
"- `agent-worker` does not set an outer `
|
|
2168
|
+
"- `agent-worker` does not set an outer `task advance` / `dag execute` wall-clock by default. An explicit `worker.timeout_ms` remains a hard timeout.",
|
|
2167
2169
|
"",
|
|
2168
2170
|
"## Operator Recovery",
|
|
2169
2171
|
"",
|
|
@@ -59,7 +59,7 @@ export function createRunDagProgressObserver(options = {}) {
|
|
|
59
59
|
let timer;
|
|
60
60
|
const emit = (message) => {
|
|
61
61
|
try {
|
|
62
|
-
write(`[
|
|
62
|
+
write(`[dag execute] ${message}\n`);
|
|
63
63
|
}
|
|
64
64
|
catch {
|
|
65
65
|
// Progress is a derived CLI view and must never decide DAG execution.
|
package/dist/commands/status.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { getTaskDir, getTaskPaths, getTaskStatus, loadTaskConfig,
|
|
2
|
-
import { getArtifactPath } from
|
|
3
|
-
import { buildTaskReadModel } from
|
|
1
|
+
import { getTaskDir, getTaskPaths, getTaskStatus, loadTaskConfig, } from "../task/runtime.js";
|
|
2
|
+
import { getArtifactPath } from "../shared/artifacts-core.js";
|
|
3
|
+
import { buildTaskReadModel } from "../task/read-model.js";
|
|
4
4
|
export async function runStatus(repoRoot, taskId) {
|
|
5
|
-
|
|
5
|
+
// Read-only: do not refresh/repair/migrate. Mutations belong to task advance.
|
|
6
6
|
const state = await getTaskStatus(repoRoot, taskId);
|
|
7
7
|
const taskConfig = await loadTaskConfig(repoRoot, taskId);
|
|
8
8
|
const taskDir = getTaskDir(repoRoot, taskId);
|
|
@@ -12,17 +12,17 @@ export async function runStatus(repoRoot, taskId) {
|
|
|
12
12
|
taskId,
|
|
13
13
|
taskDir,
|
|
14
14
|
taskRoot: taskDir,
|
|
15
|
-
sourceOfTruth:
|
|
15
|
+
sourceOfTruth: "task",
|
|
16
16
|
artifactPaths: {
|
|
17
17
|
taskConfig: taskPaths.taskConfigPath,
|
|
18
18
|
workflowState: taskPaths.statePath,
|
|
19
19
|
sourceDir: taskPaths.sourceDir,
|
|
20
20
|
artifactsDir: `${taskDir}/artifacts`,
|
|
21
|
-
analysis: getArtifactPath(taskDir,
|
|
22
|
-
plan: getArtifactPath(taskDir,
|
|
23
|
-
modifyLog: getArtifactPath(taskDir,
|
|
24
|
-
verifyResult: getArtifactPath(taskDir,
|
|
25
|
-
retrospective: getArtifactPath(taskDir,
|
|
21
|
+
analysis: getArtifactPath(taskDir, "analyze"),
|
|
22
|
+
plan: getArtifactPath(taskDir, "plan"),
|
|
23
|
+
modifyLog: getArtifactPath(taskDir, "implement"),
|
|
24
|
+
verifyResult: getArtifactPath(taskDir, "verify"),
|
|
25
|
+
retrospective: getArtifactPath(taskDir, "retrospective"),
|
|
26
26
|
},
|
|
27
27
|
runRefs: {
|
|
28
28
|
oneShotRuns: readModel.runRefs.oneShotRuns,
|
|
@@ -30,7 +30,7 @@ export async function runStatus(repoRoot, taskId) {
|
|
|
30
30
|
},
|
|
31
31
|
readModel,
|
|
32
32
|
actionContext: {
|
|
33
|
-
mode:
|
|
33
|
+
mode: "dag",
|
|
34
34
|
allowedEditRoots: taskConfig.allowedPaths,
|
|
35
35
|
forbiddenPaths: taskConfig.forbiddenPaths,
|
|
36
36
|
constraints: taskConfig.hardConstraints,
|
|
@@ -40,17 +40,18 @@ export async function runStatus(repoRoot, taskId) {
|
|
|
40
40
|
status: state.status,
|
|
41
41
|
complexity: taskConfig.complexity,
|
|
42
42
|
maxFixLoops: taskConfig.maxFixLoops,
|
|
43
|
-
verifyEnv: taskConfig.verifyEnv ??
|
|
43
|
+
verifyEnv: taskConfig.verifyEnv ?? "clean",
|
|
44
44
|
maxGoalContinuationsPerRun: taskConfig.maxGoalContinuationsPerRun ?? 5,
|
|
45
45
|
goal: state.goal,
|
|
46
46
|
sourceState: state.sourceState,
|
|
47
47
|
completedSteps: state.completedSteps,
|
|
48
48
|
decisionLogSize: state.decisionLog.length,
|
|
49
49
|
artifacts: state.artifacts,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
// Prefer task advance/status; keep single next action (no parallel command arrays).
|
|
51
|
+
next: {
|
|
52
|
+
kind: "advance-or-status",
|
|
53
|
+
command: readModel.nextAction.command,
|
|
54
|
+
reason: readModel.nextAction.reason,
|
|
55
|
+
},
|
|
55
56
|
}, null, 2));
|
|
56
57
|
}
|
|
@@ -120,8 +120,8 @@ export async function runStudyInit(repoRoot, args) {
|
|
|
120
120
|
next: [
|
|
121
121
|
'edit source/需求.md and source/执行约束.md',
|
|
122
122
|
indexed
|
|
123
|
-
? `npm run dev --
|
|
124
|
-
: `npm run dev -- reference index ${options.taskId}; npm run dev --
|
|
123
|
+
? `npm run dev -- task advance ${options.taskId} --profile auto --json`
|
|
124
|
+
: `npm run dev -- reference index ${options.taskId}; npm run dev -- task advance ${options.taskId} --profile auto --json`,
|
|
125
125
|
],
|
|
126
126
|
}, null, 2));
|
|
127
127
|
}
|