@tea-agent/loop-agent 0.26.5-beta.2 → 0.27.1-beta.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.
Files changed (79) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +33 -0
  3. package/README.md +13 -23
  4. package/dist/application/dag/args.js +7 -7
  5. package/dist/application/dag/generate-task-dag.js +2 -2
  6. package/dist/application/dag/run-dag.js +3 -4
  7. package/dist/application/dag/validate-dag.js +1 -1
  8. package/dist/application/task-lifecycle/advance.js +845 -0
  9. package/dist/application/task-lifecycle/gates.js +80 -0
  10. package/dist/application/task-lifecycle/index.js +7 -0
  11. package/dist/application/task-lifecycle/observe.js +395 -0
  12. package/dist/application/task-lifecycle/plan-transitions.js +224 -0
  13. package/dist/application/task-lifecycle/recommendations.js +180 -0
  14. package/dist/application/task-lifecycle/record.js +73 -0
  15. package/dist/application/task-lifecycle/types.js +1 -0
  16. package/dist/cli/command-definitions.js +14 -111
  17. package/dist/cli/help.js +6 -7
  18. package/dist/cli/program.js +26 -90
  19. package/dist/cli/update/policy.js +0 -1
  20. package/dist/commands/dag-final-verification.js +1 -1
  21. package/dist/commands/dag-init-hybrid.js +1 -1
  22. package/dist/commands/delegate.js +2 -2
  23. package/dist/commands/init.js +21 -19
  24. package/dist/commands/run-dag-progress.js +1 -1
  25. package/dist/commands/status.js +18 -17
  26. package/dist/commands/study-init.js +2 -2
  27. package/dist/commands/task-advance.js +335 -0
  28. package/dist/commands/task-contract.js +3 -5
  29. package/dist/commands/task-source-prepare.js +9 -4
  30. package/dist/commands/task-status.js +133 -0
  31. package/dist/executors/dag-pi-executor.js +18 -22
  32. package/dist/executors/shell-executor.js +41 -25
  33. package/dist/governance/manifest-types.js +2 -2
  34. package/dist/shared/operator/capabilities.js +1358 -243
  35. package/dist/task/contract/adopt.js +1 -1
  36. package/dist/task/contract/apply.js +1 -1
  37. package/dist/task/contract/import-revision.js +1 -1
  38. package/dist/task/contract/recover.js +2 -2
  39. package/dist/task/read-model.js +18 -23
  40. package/dist/task/runtime.js +1 -1
  41. package/dist/task/source-prepare/completeness.js +1 -1
  42. package/dist/task/source-prepare/parse-intent.js +6 -1
  43. package/dist/task/source-prepare/prepare.js +23 -20
  44. package/dist/worker/console/operator-actions.js +288 -95
  45. package/dist/worker/console/recovery-cta.js +4 -4
  46. package/dist/worker/console/static/assets/{index-CSRIhuzh.js → index-CNO7n6qB.js} +1 -1
  47. package/dist/worker/console/static/index.html +1 -1
  48. package/dist/worker/materialize/harness-task-materializer.js +6 -5
  49. package/dist/worker/run-task/run-task.js +204 -112
  50. package/dist/worker/runner/run-ready.js +1 -1
  51. package/dist/workflows/dag/backend-test-markdown-workflow.js +49 -23
  52. package/dist/workflows/dag/backend-test-pytest-collection.js +57 -9
  53. package/dist/workflows/dag/frontend-implementation-contract.js +3 -3
  54. package/dist/workflows/dag/frontend-prewrite-gate.js +18 -1
  55. package/dist/workflows/dag/frontend-test-l5-report.js +46 -7
  56. package/dist/workflows/dag/init-hybrid.js +6 -35
  57. package/dist/workflows/dag/output-protocol.js +23 -0
  58. package/docs/templates/backend-test-dag.json +2 -2
  59. package/docs/templates/evaluation/agents-map-slim-v1.md +1 -1
  60. package/docs/templates/evaluation/agents-map-verbose-v0.md +3 -3
  61. package/docs/templates/frontend-implementation-contract.schema.json +2 -2
  62. package/docs/templates/harness.schema.json +2 -2
  63. package/docs/templates/init-managed-agents.md +13 -16
  64. package/docs/templates/production-readiness-checklist.md +3 -3
  65. package/harness.json +1 -1
  66. package/package.json +1 -1
  67. package/scripts/kb-bootstrap-init-skeleton.sh +2 -1
  68. package/scripts/kb-graph-incremental-prepare.mjs +2 -2
  69. package/skills/loop-agent/SKILL.md +18 -13
  70. package/skills/loop-agent/references/README.md +1 -1
  71. package/skills/loop-agent/references/command-reference.md +55 -84
  72. package/skills/loop-agent/references/harness-policy.md +19 -23
  73. package/skills/loop-agent/references/hybrid-dag.md +32 -34
  74. package/skills/loop-agent/references/long-running-loop.md +2 -2
  75. package/skills/loop-agent/references/one-shot-runs.md +4 -5
  76. package/skills/loop-agent/references/orchestrator-and-interventions.md +3 -3
  77. package/skills/loop-agent/references/post-implementation-and-patterns.md +4 -4
  78. package/skills/loop-agent/references/source-and-plan-practice.md +45 -51
  79. package/skills/loop-agent/references/task-workflow.md +14 -15
package/AGENTS.md CHANGED
@@ -24,7 +24,7 @@
24
24
  - Shell 搜索优先 `rg`,按名找文件优先 `fd`;脚本用 Git Bash / 兼容 Bash。
25
25
  - 用 loop-agent 迭代本仓库时,控制器必须来自已发布 npm 包(记录实际版本);启动后不要中途升级;不要用工作区 `npm link` / `npm run dev` 控制可能改 CLI/runtime/package 的任务。
26
26
  - 反复出现的约束固化为文档、脚本、检查、测试或模板;禁止占位实现(除非 contract 标明脚手架)。
27
- - 非微小实现:`exec-plan` 不能替代 Agent DAG;除非用户要求 one-shot 或计划记录 escape hatch,否则改实现前完成 `new-task`、结构化路径、`dag run-task`、`dag validate` writeSet 审查。
27
+ - 非微小实现:`exec-plan` 不能替代 Agent DAG;除非用户要求 one-shot 或计划记录 escape hatch,否则改实现前完成 `task advance`(PRD + 结构化路径边界)、writeSet gate 审查与 `task advance --approve-gate`。
28
28
  - **实现默认 DAG,主会话不直接改代码**:只要是实现/修复/行为或展示语义变更(含 observe 文案映射、runtime status、schema、executor、CLI 等),主会话只做 Orient / 建 task / dry-run / validate / writeSet 审查 / 执行与监视 DAG,**不得**自己改 `src/**`、`test/**` 等交付面。仅当用户**明确授权**主会话直接处理(例如「直接改」「主会话改」「one-shot」「不用 DAG」)时,才允许主会话写入;授权后仍须记录边界、allowedPaths 与验证证据。纯答疑、读代码、查状态、提交/推送已有 diff、或用户点名的文档微调(如本文件规则)不在此限。
29
29
  - 不要自行引入外部 SDD/spec-first 等强制平行治理树;以本文件与 `docs/` 为准(ADR 0006)。
30
30
 
@@ -51,7 +51,7 @@
51
51
 
52
52
  DAG 执行期间主 agent 必须持续轮询监视直到 run 结束(FINISHED / FAILED / 需要 approve),不能轮询一次就停下等用户;轮询间隔应合理(避免频繁唤醒浪费 token,也不得住一个节点上赌一次就走)。判活必须用可靠方式:看 `state.json` 的 `runner.heartbeatAt` 是否持续刷新 + `session-events.jsonl` 是否在增长 + `dag doctor` 的 `liveness` 字段,不要只用 `tasklist /FI "PID eq X"` 这类过滤语法在 Git Bash 下会误报 DEAD,从而错判一个正常工作的 run 为 orphaned。遇到疑似 stall 先按 `docs/runtime/agent-dag-runner.md` 查 `lastMeaningfulProgressAt` / provider 活动,有真实进展就继续等,绝不盲目 supersede。
53
53
 
54
- DAG 执行期间,主 agent 不得修改 writeSet 外的任何工作区文件(包括 AGENTS.md、docs、根配置等)。bounded writer 节点的 write guard 用「节点运行期间的工作区 diff」作为越界证据,不区分改动来自 pi 还是主会话——主会话在 pi 节点跑的时候改了 writeSet 外文件,会让 write guard 把账算到 pi 头上、判节点 ERROR、下游 cascade skip。需要改文档/约束时,要么在 DAG 启动前改完,要么等 run 结束后改;务必与 DAG 写入节点在时间上互斥。排查任务路由问题时优先用 `resolveTaskDagTemplateSelection` / `classifyTaskDemand` 等纯函数探针或 `--output` 指定临时路径,不要反复 `dag run-task`——每次调用(含 `--dry-run`)都会在 `.harness/dag-runs/active/` 新建一个 run 目录,dry-run 不执行节点但目录残留,堆积成「一堆 active run」的假象。
54
+ DAG 执行期间,主 agent 不得修改 writeSet 外的任何工作区文件(包括 AGENTS.md、docs、根配置等)。bounded writer 节点的 write guard 用「节点运行期间的工作区 diff」作为越界证据,不区分改动来自 pi 还是主会话——主会话在 pi 节点跑的时候改了 writeSet 外文件,会让 write guard 把账算到 pi 头上、判节点 ERROR、下游 cascade skip。需要改文档/约束时,要么在 DAG 启动前改完,要么等 run 结束后改;务必与 DAG 写入节点在时间上互斥。排查任务路由问题时优先用 `resolveTaskDagTemplateSelection` / `classifyTaskDemand` 等纯函数探针或 `--output` 指定临时路径,不要反复 `dag execute --dry-run` / 无必要的 lifecycle 探测——每次可能在 `.harness/dag-runs/active/` 新建 run 目录,dry-run 不执行节点但目录残留,堆积成「一堆 active run」的假象。优先用纯函数探针或 `task status`。
55
55
 
56
56
  ## 项目地图
57
57
 
package/CHANGELOG.md CHANGED
@@ -2,6 +2,39 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ### 修复
6
+
7
+ - 修复 backend-test collection assess 在 Markdown 已声明安全 mapped `test_*.py`、但 pytest writer 漏生成文件时直接以 `invalid-output` 阻断 repair 的问题:initial facts 升级为 `backend-test-pytest-collection-v2`,可记录 expected/existing/missing scripts、`collectionAttempted=false` 与 `missing-mapped-pytest-script`,复用既有单次 bounded repair 创建精确缺失脚本,并由 final collection、scope、安全和 hash freshness 门禁重新授权业务执行
8
+
9
+ ## [0.27.0] - 2026-08-03
10
+
11
+ ### 重点更新
12
+
13
+ - 标准操作生命周期统一为 task advance(推进任务)与 task status(查看状态)两个入口
14
+ - 移除十余个旧版公开命令别名,简化操作心智模型
15
+ - task advance 首次执行可自动完成 PRD 导入、契约派生、DAG 生成与校验,停在 writeSet 摘要门禁等待确认
16
+ - Worker 与 Console 全面迁移至新的机器契约,统一通过 task advance 驱动
17
+
18
+ ### 新增
19
+
20
+ - 新增 task advance 作为标准任务生命周期的唯一推荐变更入口
21
+ - 新增 task status 作为只读任务状态查询入口
22
+ - task advance 支持 --accept-recommendations 参数,通过摘要确认确定性采纳工程边界推荐
23
+ - task advance 新增 Worker 机器契约参数:--profile、--max-concurrent、--run-id、--events-jsonl、--worker-association、--dag-output、--skip-finalize、--no-strict-models
24
+ - ADR 0008 将 run 级 dag recovery/forensic/decision 冻结为永久 advanced 专用,标准 task 面保持简洁
25
+
26
+ ### 改进
27
+
28
+ - Worker run-task 主路径改为 task advance prepare 到 writeSet 门禁后经 --approve-gate 执行,不再 spawn dag run-task / run-dag / dag validate
29
+ - Console 的 status 调用迁移至 task status,dagRunTask/prepareDagConfirmation 生成路径迁移至 task advance --dag-output
30
+ - 顶层 status 去掉 refreshSourceState 副作用,read-model next 指向 advance/status
31
+ - 标准主路径文档、skills、help、capabilities 全面收敛为 task advance + task status
32
+
33
+ ### 修复
34
+
35
+ - 完成 task-advance 迁移后对齐残余断言:skill 触发词、workflow defaultEntry、Ring1/Ring2 CLI smoke 及 help-summary 与新生命周期一致
36
+ - 更新 dag/run-task/final-verification/reference-context 预期,pre-push 不再断言已删除的 dag run-task / task contract 公开命令
37
+
5
38
  ## [0.26.4] - 2026-08-03
6
39
 
7
40
  ### 重点更新
package/README.md CHANGED
@@ -55,40 +55,30 @@ loop-agent init reconcile --repo-root .
55
55
  初始化后,在已初始化的目标项目中你可以直接对宿主 agent 说「**loop-agent 帮我完成 XXX 需求**」(或「帮我实现 / 帮我修复 / 帮我开发 XXX」「使用 loop-agent 完成 XXX」「按 loop-agent 流程处理 XXX」),初始化写入的 `AGENTS.md` 与 `.agents/skills/loop-agent/` 会把这类通用需求表达确定性地路由进 Agent DAG,**无需**追加额外的 `cli` 关键词。主会话只负责编排与验证,业务实现由受治理 DAG writer 完成。
56
56
 
57
57
  ```bash
58
- loop-agent new-task example-task "实现一个有明确验收标准的小功能"
59
-
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 \
58
+ # 标准单任务路径:唯一 mutation 入口 task advance + 可选只读 task status
59
+ loop-agent task advance example-task "实现一个有明确验收标准的小功能" \
60
+ --prd path/to/prd.md \
64
61
  --allowed-path "src/**" \
65
62
  --forbidden-path ".harness/**" \
66
63
  --verify "typecheck:npm run typecheck" \
67
- --apply --json
68
-
69
- loop-agent dag run-task example-task \
70
- --profile auto \
71
- --strict-models \
72
- --output .harness/tasks/example-task/dag.json
64
+ --json
73
65
 
74
- loop-agent dag validate \
75
- --dag .harness/tasks/example-task/dag.json \
76
- --strict-models \
77
- --strict-governance
66
+ # 审查返回的 writeSet / gate.digest 后,同一命令批准并长跑到稳定终态
67
+ loop-agent task advance example-task \
68
+ --approve-gate "write-set-review:<digest>" \
69
+ --json
78
70
 
79
- loop-agent run-dag \
80
- --dag .harness/tasks/example-task/dag.json \
81
- --cwd .
71
+ # 可选只读查询(不 refresh、不 mutation)
72
+ loop-agent task status example-task --json
82
73
  ```
83
74
 
84
- 省略 `--output` 时默认写入 `.harness/tasks/<task-id>/dag.json`。详细步骤见[第一次运行](website/docs/quick-start/first-run.md)和 [Agent DAG 工作流](website/docs/guides/agent-dag.md)。
75
+ 首次 `task advance` 会 create/import PRD/派生 managed contract/生成并 strict validate DAG,然后停在 writeSet gate;未批准不会启动业务 writer。详细步骤见[第一次运行](website/docs/quick-start/first-run.md)和 [Agent DAG 工作流](website/docs/guides/agent-dag.md)。
85
76
 
86
77
  ## 查看执行状态
87
78
 
88
79
  ```bash
89
- loop-agent status example-task
90
- loop-agent dag status
91
- loop-agent dag doctor --run-id <run-id> --markdown
80
+ loop-agent task status example-task --json
81
+ # advanced forensic(非标准主路径)
92
82
  loop-agent dag report --run-id <run-id>
93
83
  ```
94
84
 
@@ -247,7 +247,7 @@ export function parseDagValidateArgs(args) {
247
247
  }
248
248
  export function parseRunDagArgs(args, defaultCwd) {
249
249
  if (args.length === 0) {
250
- throw new Error("usage: run-dag --dag <path> [--cwd <dir>] [--init-only] [--dry-run] [--max-concurrent N] [--run-id id] [--quiet] [--progress-interval-ms N] [--canvas-path <abs-path> | --canvas <name> [--canvases-dir <dir>]] [--events-jsonl <path>] [--json]");
250
+ throw new Error("usage: dag execute --dag <path> [--cwd <dir>] [--init-only] [--dry-run] [--max-concurrent N] [--run-id id] [--quiet] [--progress-interval-ms N] [--canvas-path <abs-path> | --canvas <name> [--canvases-dir <dir>]] [--events-jsonl <path>] [--json]");
251
251
  }
252
252
  let dagPath;
253
253
  let cwd;
@@ -328,7 +328,7 @@ export function parseRunDagArgs(args, defaultCwd) {
328
328
  workerAssociation = parseWorkerAssociation(arg.slice("--worker-association=".length));
329
329
  }
330
330
  else if (arg === "--json") {
331
- // Accepted for operator/console callers; run-dag always emits JSON stdout.
331
+ // Accepted for operator/console callers; dag execute always emits JSON stdout.
332
332
  }
333
333
  else if (!arg.startsWith("-")) {
334
334
  if (!dagPath)
@@ -337,11 +337,11 @@ export function parseRunDagArgs(args, defaultCwd) {
337
337
  throw new Error(`unexpected positional argument: ${arg}`);
338
338
  }
339
339
  else {
340
- throw new Error(`unknown run-dag flag: ${arg}`);
340
+ throw new Error(`unknown dag execute flag: ${arg}`);
341
341
  }
342
342
  }
343
343
  if (!dagPath) {
344
- throw new Error("run-dag requires --dag <path>");
344
+ throw new Error("dag execute requires --dag <path>");
345
345
  }
346
346
  return {
347
347
  dagPath: path.resolve(dagPath),
@@ -368,14 +368,14 @@ function parseProgressIntervalMs(value) {
368
368
  }
369
369
  function parseWorkerAssociation(raw) {
370
370
  if (!raw?.trim()) {
371
- throw new Error("run-dag --worker-association requires JSON");
371
+ throw new Error("dag execute --worker-association requires JSON");
372
372
  }
373
373
  let parsed;
374
374
  try {
375
375
  parsed = JSON.parse(raw);
376
376
  }
377
377
  catch {
378
- throw new Error("run-dag --worker-association must be valid JSON");
378
+ throw new Error("dag execute --worker-association must be valid JSON");
379
379
  }
380
380
  if (!parsed ||
381
381
  typeof parsed !== "object" ||
@@ -383,7 +383,7 @@ function parseWorkerAssociation(raw) {
383
383
  typeof parsed.workerRunId !== "string" ||
384
384
  typeof parsed.featureId !== "string" ||
385
385
  typeof parsed.taskId !== "string") {
386
- throw new Error("run-dag --worker-association requires {schemaVersion:1,workerRunId,featureId,taskId}");
386
+ throw new Error("dag execute --worker-association requires {schemaVersion:1,workerRunId,featureId,taskId}");
387
387
  }
388
388
  return parsed;
389
389
  }
@@ -75,8 +75,8 @@ function buildNextSteps(taskId, outputPath, cwd) {
75
75
  return [
76
76
  `Review ${outputPath}`,
77
77
  `loop-agent dag validate --dag ${outputPath} --strict-models --strict-governance`,
78
- `loop-agent run-dag --dag ${outputPath} --cwd ${cwd}`,
79
- `loop-agent dag run-task ${taskId} --execute --cwd ${cwd}`,
78
+ `loop-agent dag execute --dag ${outputPath} --cwd ${cwd}`,
79
+ `loop-agent task advance ${taskId} --approve-gate write-set-review:<digest> --json`,
80
80
  ];
81
81
  }
82
82
  function buildBasicValidationLevel(outputPath) {
@@ -23,10 +23,9 @@ async function flushCanvasSafely(canvas) {
23
23
  }
24
24
  function buildRunDagNextSteps(runId) {
25
25
  return [
26
- `loop-agent dag report --run-id ${runId} --markdown`,
27
- `loop-agent dag doctor --run-id ${runId} --markdown`,
28
- `loop-agent promote-run <task-id> --run-id ${runId}`,
29
- `loop-agent dag closeout-draft --run-id ${runId}`,
26
+ `loop-agent task advance <task-id> --json # promote/closeout/recovery via lifecycle entry`,
27
+ `loop-agent task status <task-id> --json`,
28
+ `loop-agent dag report --run-id ${runId} --markdown # advanced forensic`,
30
29
  ];
31
30
  }
32
31
  export async function runDagUseCase(input) {
@@ -161,6 +161,6 @@ export async function validateDagUseCase(input) {
161
161
  ...formatModelMatrixWarnings(warnings),
162
162
  ...formatGovernanceWarnings(governanceWarnings),
163
163
  ],
164
- next: [`loop-agent run-dag --dag ${input.dagPath} --cwd ${input.repoRoot}`],
164
+ next: [`loop-agent dag execute --dag ${input.dagPath} --cwd ${input.repoRoot}`],
165
165
  };
166
166
  }