@tea-agent/loop-agent 0.5.0 → 0.6.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 +142 -142
- package/CHANGELOG.md +116 -98
- package/README.md +195 -195
- package/bin/agent-worker.js +22 -22
- package/bin/loop-agent.js +21 -21
- package/dist/application/dag/args.js +9 -1
- package/dist/application/dag/run-dag.js +16 -2
- package/dist/cli/command-definitions.js +22 -4
- package/dist/cli/help.js +3 -2
- package/dist/cli/program.js +7 -5
- package/dist/commands/import-prd.js +76 -0
- package/dist/commands/init.js +467 -457
- package/dist/commands/instructions.js +90 -58
- package/dist/commands/loop-benchmark.js +11 -11
- package/dist/commands/pi-reuse-benchmark.js +16 -16
- package/dist/executors/cursor-executor.js +1 -1
- package/dist/executors/dag-pi-executor.js +1 -0
- package/dist/executors/pi-sdk-executor.js +63 -1
- package/dist/shared/preview.js +39 -0
- package/dist/task/runtime.js +27 -27
- package/dist/task/source-references.js +221 -0
- package/dist/worker/cli.js +62 -1
- package/dist/worker/loop-agent/loop-agent-client.js +97 -5
- package/dist/worker/materialize/harness-task-materializer.js +162 -5
- package/dist/worker/observability/event-store.js +82 -0
- package/dist/worker/observability/events.js +79 -0
- package/dist/worker/observability/progress-composite.js +33 -0
- package/dist/worker/observability/read-model.js +1013 -0
- package/dist/worker/observability/snapshot-store.js +43 -0
- package/dist/worker/observability/types.js +1 -0
- package/dist/worker/observe/paths.js +64 -0
- package/dist/worker/observe/routes.js +423 -0
- package/dist/worker/observe/server.js +61 -0
- package/dist/worker/observe/static/app.js +1419 -0
- package/dist/worker/observe/static/index.html +63 -0
- package/dist/worker/observe/static/styles.css +613 -0
- package/dist/worker/pool/failure-routing.js +41 -6
- package/dist/worker/pool/run-store.js +50 -0
- package/dist/worker/progress-reporter.js +0 -18
- package/dist/worker/run-task/run-task.js +327 -92
- package/dist/worker/runner/run-ready.js +112 -4
- package/dist/workflows/dag/canvas-observer.js +275 -275
- package/dist/workflows/dag/event-observer.js +132 -0
- package/dist/workflows/dag/init-hybrid.js +146 -13
- package/dist/workflows/dag/observer-compose.js +52 -0
- package/docs/README.md +74 -72
- package/docs/agent-dag-recovery-playbook.md +184 -184
- package/docs/agent-dag-runner.md +42 -42
- package/docs/architecture/runtime-boundaries.md +162 -147
- package/docs/cursor-executor-usage.md +25 -25
- package/docs/decisions/README.md +3 -3
- package/docs/design/README.md +49 -36
- package/docs/development-principles.md +73 -73
- package/docs/dynamic-workflow-dag-engine-roadmap.md +1749 -1749
- package/docs/exec-plans/README.md +6 -6
- package/docs/exec-plans/active/README.md +12 -7
- package/docs/exec-plans/completed/README.md +31 -19
- package/docs/feature-workflow.md +186 -186
- package/docs/harness-methodology-debugging.md +153 -153
- package/docs/harness-methodology-tdd.md +130 -130
- package/docs/harness-methodology-verification.md +27 -27
- package/docs/init-surface.manifest.json +205 -199
- package/docs/loop-agent-harness.md +55 -42
- package/docs/production-readiness.md +96 -96
- package/docs/progress/README.md +3 -3
- package/docs/reports/README.md +9 -5
- package/docs/skills/README.md +6 -6
- package/docs/skills/vetted-skill-registry.md +26 -26
- package/docs/templates/adr.md +60 -60
- package/docs/templates/agent-dag-authority-surface-audit.prompt.md +94 -94
- package/docs/templates/agent-dag-decision-envelope.schema.json +213 -213
- package/docs/templates/agent-dag-decision-gate-dogfood-report.md +117 -117
- package/docs/templates/agent-dag-decision-gate.prompt.md +246 -246
- package/docs/templates/agent-dag-process-supervisor.prompt.md +98 -98
- package/docs/templates/agent-dag-report.schema.json +454 -454
- package/docs/templates/agent-dag-review-verdict.prompt.md +68 -68
- package/docs/templates/agent-dag.base.json +195 -195
- package/docs/templates/agent-dag.final-verification.json +190 -190
- package/docs/templates/agent-dag.schema.json +316 -316
- package/docs/templates/agent-dag.supervised-implementation.json +500 -500
- package/docs/templates/exec-plan.md +64 -64
- package/docs/templates/feature-spec.md +53 -53
- package/docs/templates/hybrid-dag.json +193 -193
- package/docs/templates/init-evolution-review.md +33 -33
- package/docs/templates/production-readiness-checklist.md +57 -57
- package/docs/templates/progress-log.md +17 -17
- package/docs/templates/project-start-checklist.md +9 -9
- package/docs/templates/qa-report.md +48 -48
- package/docs/templates/sprint-contract.md +29 -29
- package/docs/templates/worker-dogfood-evidence.md +52 -0
- package/docs/templates/worker-dogfood-setup.md +48 -0
- package/docs/verification-matrix.md +41 -41
- package/examples/decision-gate-agent-dag.json +123 -123
- package/examples/example-dag.json +51 -51
- package/examples/hybrid-loop-agent-dag.json +194 -194
- package/harness.json +70 -69
- package/package.json +66 -66
- package/skills/ai-engineering-context/SKILL.md +48 -48
- package/skills/code-review-core/SKILL.md +20 -20
- package/skills/codebase-scout/SKILL.md +19 -19
- package/skills/init-capability-evolution/SKILL.md +69 -69
- package/skills/loop-agent/SKILL.md +149 -147
- package/skills/loop-agent/references/README.md +67 -67
- package/skills/loop-agent/references/command-reference.md +412 -403
- package/skills/loop-agent/references/harness-policy.md +263 -259
- package/skills/loop-agent/references/hybrid-dag.md +216 -216
- package/skills/loop-agent/references/learned/README.md +21 -21
- package/skills/loop-agent/references/long-running-loop.md +59 -59
- package/skills/loop-agent/references/model-routing.md +36 -36
- package/skills/loop-agent/references/multi-worktree.md +54 -54
- package/skills/loop-agent/references/one-shot-runs.md +85 -85
- package/skills/loop-agent/references/orchestrator-and-interventions.md +169 -169
- package/skills/loop-agent/references/pi-prompt.md +23 -23
- package/skills/loop-agent/references/pi-subagent-assisted-mode.md +81 -81
- package/skills/loop-agent/references/post-implementation-and-patterns.md +44 -44
- package/skills/loop-agent/references/task-workflow.md +89 -84
- package/skills/loop-agent/references/verification-and-failure-handling.md +128 -128
- package/skills/requesting-code-review/SKILL.md +101 -101
- package/skills/requesting-code-review/code-reviewer.md +168 -168
- package/skills/systematic-debugging/CREATION-LOG.md +119 -119
- package/skills/systematic-debugging/SKILL.md +296 -296
- package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -158
- package/skills/systematic-debugging/condition-based-waiting.md +115 -115
- package/skills/systematic-debugging/defense-in-depth.md +122 -122
- package/skills/systematic-debugging/find-polluter.sh +63 -63
- package/skills/systematic-debugging/root-cause-tracing.md +169 -169
- package/skills/systematic-debugging/test-academic.md +14 -14
- package/skills/systematic-debugging/test-pressure-1.md +58 -58
- package/skills/systematic-debugging/test-pressure-2.md +68 -68
- package/skills/systematic-debugging/test-pressure-3.md +69 -69
- package/skills/test-driven-development/SKILL.md +20 -20
- package/skills/verification-before-completion/SKILL.md +154 -154
- package/skills/webapp-testing/SKILL.md +19 -19
package/README.md
CHANGED
|
@@ -1,195 +1,195 @@
|
|
|
1
|
-
# loop-agent
|
|
2
|
-
|
|
3
|
-
`loop-agent` 是面向 AI coding agent 的仓库级任务运行时和治理工具。它把一次研发任务组织成可生成、可校验、可执行、可恢复、可交接的 Agent DAG,并用 `.harness/`、`docs/` 和 shell verification 记录执行事实、长期治理资料和完成依据。
|
|
4
|
-
|
|
5
|
-
它可以作为任意目标项目的稳定控制器:初始化目标项目后,项目会获得 repo-local skills、治理文档、验证脚本、任务运行态目录和模型执行指引,使 agent 在目标项目里的工作体验尽量与本仓库对齐。
|
|
6
|
-
|
|
7
|
-
## 快速开始
|
|
8
|
-
|
|
9
|
-
到一个新项目时,可以直接对当前 agent 说:
|
|
10
|
-
|
|
11
|
-
```text
|
|
12
|
-
请用 loop-agent 完整初始化当前项目;如果本机没有 loop-agent,请先安装 @tea-agent/loop-agent@latest。按 init instructions 使用 full + merge 初始化,探索项目后补全 README 和验证命令,最后运行 doctor、inspect、docs audit 和 check-repo 并汇报结果。
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
作为 CLI 使用时,安装已发布包:
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm install -g @tea-agent/loop-agent@latest
|
|
19
|
-
loop-agent --version
|
|
20
|
-
loop-agent --help
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
检查当前项目的 loop-agent 配置:
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
loop-agent doctor
|
|
27
|
-
loop-agent inspect
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## 初始化目标项目
|
|
31
|
-
|
|
32
|
-
在新项目中,最简单的用法是让当前 agent 执行初始化。需要更稳的执行约束时,可以使用下面这段完整提示词:
|
|
33
|
-
|
|
34
|
-
```text
|
|
35
|
-
请用 loop-agent 完整初始化当前项目。
|
|
36
|
-
|
|
37
|
-
如果本机还没有 `loop-agent` 命令,请先运行 `npm install -g @tea-agent/loop-agent@latest`,再记录 `npm list -g @tea-agent/loop-agent --depth=0` 的实际版本。
|
|
38
|
-
|
|
39
|
-
然后运行 `loop-agent init instructions --repo-root .`,按指引使用 full + merge 初始化。需要选择 provider/model,或涉及凭据、成本、部署副作用时先问我;其他能安全默认的选项直接继续。
|
|
40
|
-
|
|
41
|
-
初始化后请立刻探索当前项目的 README、manifest/build/config 文件和源码目录,补全根 README 的项目概览、技术栈/目录结构、开发与验证命令,并同步更新 `docs/verification-matrix.md` 和必要的 `scripts/ci-tests.sh`。
|
|
42
|
-
|
|
43
|
-
最后运行 `loop-agent init doctor --repo-root .`、`loop-agent inspect --repo-root .`、`loop-agent docs audit --repo-root .`、`bash scripts/check-repo.sh`,如项目测试入口可识别也运行 `bash scripts/ci-tests.sh` 或 `bash scripts/ci.sh`,并汇报结果、假设和剩余风险。
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
如果手动运行 CLI,可以使用:
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
loop-agent init instructions --repo-root <target-repo>
|
|
50
|
-
loop-agent init --repo-root <target-repo> --profile full --merge
|
|
51
|
-
loop-agent init doctor --repo-root <target-repo>
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
`init instructions` 会输出给模型/Agent 执行完整初始化的指引包,不要求目标项目已有 `harness.json`。默认初始化会 merge 已有 `AGENTS.md`、`harness.json` 和 `docs/`,复制 repo-local `skills/` 并同步镜像到 `.agents/skills/`(agent 兼容路径,如 OpenCode 自动发现),生成语言无关的治理脚本矩阵、中文根 README 入口、目标项目版治理文档和 `.harness/` 骨架;已有 README 会保留用户正文并插入/更新 loop-agent managed block。初始化还会向 `.gitignore` 合并一个 loop-agent managed block(`# LOOP_AGENT_INIT_START/END`),把 `.harness/tasks/*`、`.harness/dag-runs/*`、`.harness/runs/*`、`.harness/live/`、`.harness/cache/`、`.harness/init-surface.json`、`.task-pool/`、`.worktrees/` 等个人/会话运行态事实忽略掉,同时保留 `.harness/prompts/` 和目录占位可共享,不会整目录忽略 `.harness/`,也不会覆盖用户已有的 ignore 规则。
|
|
55
|
-
|
|
56
|
-
新初始化会写入 `.harness/init-surface.json`,记录当前 controller 版本、初始化投影文件 hash 和 manifest hash。已用旧版本初始化的目标项目,可以用下面的维护入口对齐新版本初始化能力:
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
loop-agent init check-update --repo-root <target-repo> --json
|
|
60
|
-
loop-agent init check-update --repo-root <target-repo> --markdown
|
|
61
|
-
loop-agent init update --repo-root <target-repo> --bootstrap-surface
|
|
62
|
-
loop-agent init update --repo-root <target-repo> --apply-safe
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
`check-update` 只读报告 deterministic actions、model merge tasks、human decisions 和 recommended next。`update --bootstrap-surface` 为旧项目补 inferred baseline;`update --apply-safe` 只补缺失文件、目录和 managed block(包括过期的 `.gitignore` managed block),不覆盖已有但无法确认来源的本地文件。
|
|
66
|
-
|
|
67
|
-
当初始化由模型/Agent 执行时,它应把初始化当成一个自动化闭环:确认真正不能安全默认的 provider/model、治理根目录或凭据/成本问题后,运行 deterministic init,随后立刻读取目标项目真实文件,补全根 README 的项目概览、技术栈/目录结构、开发与验证命令,并同步适配 `docs/verification-matrix.md` 和必要的 `scripts/ci-tests.sh`。
|
|
68
|
-
|
|
69
|
-
初始化生成的 `scripts/ci-tests.sh` 不假定目标项目是 TypeScript、Node、前端或后端项目。它会保守探测 `package.json`、`Makefile`、`go.mod`、`Cargo.toml`、Python 测试配置、Maven、Gradle、.NET 等常见入口,只运行实际存在且工具可用的命令;探测不到时会清楚提示需要由初始化模型或用户按目标项目实际技术栈补充。
|
|
70
|
-
|
|
71
|
-
## 运行任务
|
|
72
|
-
|
|
73
|
-
创建并运行一个标准 Agent DAG:
|
|
74
|
-
|
|
75
|
-
```bash
|
|
76
|
-
loop-agent new-task <task-id> "任务标题"
|
|
77
|
-
loop-agent dag run-task <task-id> --profile auto --strict-models --output <temp-dir>/<task-id>-dag.json
|
|
78
|
-
loop-agent dag validate --dag <temp-dir>/<task-id>-dag.json --strict-models --strict-governance
|
|
79
|
-
loop-agent run-dag --dag <temp-dir>/<task-id>-dag.json --cwd .
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
`<temp-dir>` 表示平台原生临时目录;也可以省略 `--output`,再使用命令 JSON 输出里的 `outputPath`。
|
|
83
|
-
|
|
84
|
-
一次性只读评审或有边界写入:
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
loop-agent pi-prompt --cwd . --tools read,grep,find,ls "只读评审这个任务,不要编辑文件。"
|
|
88
|
-
loop-agent pi-prompt --cwd . --tools read,bash,edit,write,grep,find,ls "<包含 allowedPaths 和 forbiddenPaths 的有边界任务说明>"
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
## 核心概念
|
|
92
|
-
|
|
93
|
-
- **Agent DAG**:把一次任务拆成 contract、scout、plan、implement、verify、closeout 等可审查节点。
|
|
94
|
-
- **`.harness/`**:记录 task、DAG run、one-shot run、cache 和 live state 等运行态事实。
|
|
95
|
-
- **`harness.json`**:描述项目名、治理根目录、模型路由、executor 和验证脚本。
|
|
96
|
-
- **repo-local skills**:目标项目本地的 `skills/`(loop-agent 主路径)优先于发布包内置 skills,便于项目定制 agent 行为;`init --profile full` 还会把同一份 skills 镜像到 `.agents/skills/`,让外部 agent(如 OpenCode)也能自动发现。DAG skill 解析顺序为:用户配置目录 → `skills/` → `.agents/skills/` → 发布包内置。
|
|
97
|
-
- **治理文档**:`docs/` 保存原则、工作流、验证矩阵、runtime 边界、计划和报告。
|
|
98
|
-
- **shell verification**:完成声明必须有可复现命令作为依据,而不是只靠聊天结论。
|
|
99
|
-
|
|
100
|
-
这些治理原则的设计思想吸收了 Anthropic 长时运行 agent harness、OpenAI Codex harness engineering、腾讯端到端 Harness Engineering 和社区 agent harness 实践:人类掌舵,智能体执行;仓库作为记录系统;任务小步推进;用结构化 handoff 与可复现验证跨 session 保持连续性。背景资料收录在 `website/docs/practices/`。
|
|
101
|
-
|
|
102
|
-
## 能力概览
|
|
103
|
-
|
|
104
|
-
- 生成、校验、执行和汇总 Agent DAG。
|
|
105
|
-
- 从任务说明生成标准 DAG,并按依赖顺序运行规划、实现、验证和收口节点。
|
|
106
|
-
- 维护 `loop` 长程任务状态,包括目标、轮次、信号、验证事实和收口草稿。
|
|
107
|
-
- 通过 Pi executor 执行只读规划、评审、诊断和有边界写入。
|
|
108
|
-
- 保留 Cursor executor 作为显式启用的可选后端。
|
|
109
|
-
- 通过 shell executor 运行确定性的验证命令。
|
|
110
|
-
- 检查任务状态、运行态工件、文档链接、skill entry 和 runtime boundary 等治理规则。
|
|
111
|
-
|
|
112
|
-
## 内置示例
|
|
113
|
-
|
|
114
|
-
`examples/` 默认不复制到目标项目。可以通过工具内置命令查看或按需复制:
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
loop-agent examples list
|
|
118
|
-
loop-agent examples show example-dag.json
|
|
119
|
-
loop-agent examples copy example-dag.json --repo-root <target-repo>
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## 迭代本仓库
|
|
123
|
-
|
|
124
|
-
如果要用 loop-agent 迭代 loop-agent 本仓库,控制器必须来自已发布的 npm 安装包。不要使用当前工作区的 `npm link` 或 `npm run dev` 作为控制器;首次安装或有意升级可用 `@latest`,但一次自举任务启动后不要在任务中途升级控制器。
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
npm install -g @tea-agent/loop-agent@latest
|
|
128
|
-
npm list -g @tea-agent/loop-agent --depth=0
|
|
129
|
-
loop-agent doctor
|
|
130
|
-
loop-agent run-dag --dag <temp-dir>/<task-id>-dag.json --cwd <repo-root>
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
`@latest` 只用于安装或升级,不要在 DAG 节点里反复用 `npx @latest` 拉取。自举任务应记录 `npm list -g` 显示的实际版本号。
|
|
134
|
-
|
|
135
|
-
## 文档导航
|
|
136
|
-
|
|
137
|
-
| 路径 | 用途 |
|
|
138
|
-
|---|---|
|
|
139
|
-
| `AGENTS.md` | 本仓库的 agent 开工协议、会话协议和长期工作规则 |
|
|
140
|
-
| `harness.json` | loop-agent 在本仓库的模型、executor、治理根目录和脚本配置 |
|
|
141
|
-
| `docs/README.md` | 治理文档索引 |
|
|
142
|
-
| `docs/verification-matrix.md` | 不同变更类型对应的验证命令 |
|
|
143
|
-
| `docs/production-readiness.md` | Production Readiness v0.1 支持范围、证据和验收标准 |
|
|
144
|
-
| `docs/architecture/runtime-boundaries.md` | runtime 层边界和依赖方向 |
|
|
145
|
-
| `skills/loop-agent/` | loop-agent skill 入口和 references |
|
|
146
|
-
| `examples/` | 可复用 DAG 示例 |
|
|
147
|
-
| `website/docs/` | 面向使用者的 Docusaurus 文档站内容 |
|
|
148
|
-
| `website/docs/practices/` | Anthropic、OpenAI Codex、腾讯端到端工程与社区 harness 实践资料 |
|
|
149
|
-
|
|
150
|
-
## 本仓库开发
|
|
151
|
-
|
|
152
|
-
本地源码开发:
|
|
153
|
-
|
|
154
|
-
```bash
|
|
155
|
-
npm install
|
|
156
|
-
npm run build
|
|
157
|
-
node bin/loop-agent.js --help
|
|
158
|
-
npm run dev -- --help
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
常用验证命令:
|
|
162
|
-
|
|
163
|
-
```bash
|
|
164
|
-
npm run typecheck
|
|
165
|
-
npm test
|
|
166
|
-
bash scripts/check-repo.sh
|
|
167
|
-
bash scripts/ci.sh
|
|
168
|
-
npm run docs:build
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
当前 CLI 使用 `commander` 组织 command tree。顶层 help、子命令 help、参数解析和未知命令错误都由 commander 驱动。
|
|
172
|
-
|
|
173
|
-
Windows 上运行 `scripts/*.sh` 时使用 Git Bash 或已配置的兼容 Bash,不要求使用 WSL 或 POSIX 路径。实际文件操作和 `--output` / `--dag` / `--cwd` 参数使用当前平台原生路径;仓库内引用、JSON/Markdown 证据引用和 glob 约定可继续用 `/` 作为稳定分隔符。
|
|
174
|
-
|
|
175
|
-
## 发布包内容
|
|
176
|
-
|
|
177
|
-
发布包包含静态运行和指导资料:`bin/`、`dist/`、`skills/`、`docs/*.md`、`docs/architecture/runtime-boundaries.md`、`docs/skills/`、`docs/templates/`、`docs/init-surface.manifest.json`、`examples/`、`harness.json`、`AGENTS.md`、`README.md` 和 `CHANGELOG.md`。
|
|
178
|
-
|
|
179
|
-
`docs/progress/`、`docs/reports/`、`docs/exec-plans/`、`docs/decisions/` 等目录下的任务正文是目标仓库实时生成或历史事实;npm 包只携带这些目录的 README,不携带本仓库已有历史记录。
|
|
180
|
-
|
|
181
|
-
DAG skill 指令优先从目标项目或用户配置目录解析;目标项目未提供本地 `skills/` 时,CLI 会回退到 npm 包内置的 `skills/`。因此普通项目不需要复制 loop-agent 仓库历史文档或内置 skills 才能获得默认 DAG 能力。
|
|
182
|
-
|
|
183
|
-
## 发布前检查
|
|
184
|
-
|
|
185
|
-
发布 npm 包前至少运行:
|
|
186
|
-
|
|
187
|
-
```bash
|
|
188
|
-
npm run typecheck
|
|
189
|
-
npm test
|
|
190
|
-
npm run build
|
|
191
|
-
node bin/loop-agent.js --help
|
|
192
|
-
npm pack --dry-run
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
发布入口 `bin/loop-agent.js` 只加载 `dist/cli.js`;`npm run dev -- <args>` 只用于源码开发和定位问题。
|
|
1
|
+
# loop-agent
|
|
2
|
+
|
|
3
|
+
`loop-agent` 是面向 AI coding agent 的仓库级任务运行时和治理工具。它把一次研发任务组织成可生成、可校验、可执行、可恢复、可交接的 Agent DAG,并用 `.harness/`、`docs/` 和 shell verification 记录执行事实、长期治理资料和完成依据。
|
|
4
|
+
|
|
5
|
+
它可以作为任意目标项目的稳定控制器:初始化目标项目后,项目会获得 repo-local skills、治理文档、验证脚本、任务运行态目录和模型执行指引,使 agent 在目标项目里的工作体验尽量与本仓库对齐。
|
|
6
|
+
|
|
7
|
+
## 快速开始
|
|
8
|
+
|
|
9
|
+
到一个新项目时,可以直接对当前 agent 说:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
请用 loop-agent 完整初始化当前项目;如果本机没有 loop-agent,请先安装 @tea-agent/loop-agent@latest。按 init instructions 使用 full + merge 初始化,探索项目后补全 README 和验证命令,最后运行 doctor、inspect、docs audit 和 check-repo 并汇报结果。
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
作为 CLI 使用时,安装已发布包:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g @tea-agent/loop-agent@latest
|
|
19
|
+
loop-agent --version
|
|
20
|
+
loop-agent --help
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
检查当前项目的 loop-agent 配置:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
loop-agent doctor
|
|
27
|
+
loop-agent inspect
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 初始化目标项目
|
|
31
|
+
|
|
32
|
+
在新项目中,最简单的用法是让当前 agent 执行初始化。需要更稳的执行约束时,可以使用下面这段完整提示词:
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
请用 loop-agent 完整初始化当前项目。
|
|
36
|
+
|
|
37
|
+
如果本机还没有 `loop-agent` 命令,请先运行 `npm install -g @tea-agent/loop-agent@latest`,再记录 `npm list -g @tea-agent/loop-agent --depth=0` 的实际版本。
|
|
38
|
+
|
|
39
|
+
然后运行 `loop-agent init instructions --repo-root .`,按指引使用 full + merge 初始化。需要选择 provider/model,或涉及凭据、成本、部署副作用时先问我;其他能安全默认的选项直接继续。
|
|
40
|
+
|
|
41
|
+
初始化后请立刻探索当前项目的 README、manifest/build/config 文件和源码目录,补全根 README 的项目概览、技术栈/目录结构、开发与验证命令,并同步更新 `docs/verification-matrix.md` 和必要的 `scripts/ci-tests.sh`。
|
|
42
|
+
|
|
43
|
+
最后运行 `loop-agent init doctor --repo-root .`、`loop-agent inspect --repo-root .`、`loop-agent docs audit --repo-root .`、`bash scripts/check-repo.sh`,如项目测试入口可识别也运行 `bash scripts/ci-tests.sh` 或 `bash scripts/ci.sh`,并汇报结果、假设和剩余风险。
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
如果手动运行 CLI,可以使用:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
loop-agent init instructions --repo-root <target-repo>
|
|
50
|
+
loop-agent init --repo-root <target-repo> --profile full --merge
|
|
51
|
+
loop-agent init doctor --repo-root <target-repo>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`init instructions` 会输出给模型/Agent 执行完整初始化的指引包,不要求目标项目已有 `harness.json`。默认初始化会 merge 已有 `AGENTS.md`、`harness.json` 和 `docs/`,复制 repo-local `skills/` 并同步镜像到 `.agents/skills/`(agent 兼容路径,如 OpenCode 自动发现),生成语言无关的治理脚本矩阵、中文根 README 入口、目标项目版治理文档和 `.harness/` 骨架;已有 README 会保留用户正文并插入/更新 loop-agent managed block。初始化还会向 `.gitignore` 合并一个 loop-agent managed block(`# LOOP_AGENT_INIT_START/END`),把 `.harness/tasks/*`、`.harness/dag-runs/*`、`.harness/runs/*`、`.harness/live/`、`.harness/cache/`、`.harness/init-surface.json`、`.task-pool/`、`.worktrees/` 等个人/会话运行态事实忽略掉,同时保留 `.harness/prompts/` 和目录占位可共享,不会整目录忽略 `.harness/`,也不会覆盖用户已有的 ignore 规则。
|
|
55
|
+
|
|
56
|
+
新初始化会写入 `.harness/init-surface.json`,记录当前 controller 版本、初始化投影文件 hash 和 manifest hash。已用旧版本初始化的目标项目,可以用下面的维护入口对齐新版本初始化能力:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
loop-agent init check-update --repo-root <target-repo> --json
|
|
60
|
+
loop-agent init check-update --repo-root <target-repo> --markdown
|
|
61
|
+
loop-agent init update --repo-root <target-repo> --bootstrap-surface
|
|
62
|
+
loop-agent init update --repo-root <target-repo> --apply-safe
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`check-update` 只读报告 deterministic actions、model merge tasks、human decisions 和 recommended next。`update --bootstrap-surface` 为旧项目补 inferred baseline;`update --apply-safe` 只补缺失文件、目录和 managed block(包括过期的 `.gitignore` managed block),不覆盖已有但无法确认来源的本地文件。
|
|
66
|
+
|
|
67
|
+
当初始化由模型/Agent 执行时,它应把初始化当成一个自动化闭环:确认真正不能安全默认的 provider/model、治理根目录或凭据/成本问题后,运行 deterministic init,随后立刻读取目标项目真实文件,补全根 README 的项目概览、技术栈/目录结构、开发与验证命令,并同步适配 `docs/verification-matrix.md` 和必要的 `scripts/ci-tests.sh`。
|
|
68
|
+
|
|
69
|
+
初始化生成的 `scripts/ci-tests.sh` 不假定目标项目是 TypeScript、Node、前端或后端项目。它会保守探测 `package.json`、`Makefile`、`go.mod`、`Cargo.toml`、Python 测试配置、Maven、Gradle、.NET 等常见入口,只运行实际存在且工具可用的命令;探测不到时会清楚提示需要由初始化模型或用户按目标项目实际技术栈补充。
|
|
70
|
+
|
|
71
|
+
## 运行任务
|
|
72
|
+
|
|
73
|
+
创建并运行一个标准 Agent DAG:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
loop-agent new-task <task-id> "任务标题"
|
|
77
|
+
loop-agent dag run-task <task-id> --profile auto --strict-models --output <temp-dir>/<task-id>-dag.json
|
|
78
|
+
loop-agent dag validate --dag <temp-dir>/<task-id>-dag.json --strict-models --strict-governance
|
|
79
|
+
loop-agent run-dag --dag <temp-dir>/<task-id>-dag.json --cwd .
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`<temp-dir>` 表示平台原生临时目录;也可以省略 `--output`,再使用命令 JSON 输出里的 `outputPath`。
|
|
83
|
+
|
|
84
|
+
一次性只读评审或有边界写入:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
loop-agent pi-prompt --cwd . --tools read,grep,find,ls "只读评审这个任务,不要编辑文件。"
|
|
88
|
+
loop-agent pi-prompt --cwd . --tools read,bash,edit,write,grep,find,ls "<包含 allowedPaths 和 forbiddenPaths 的有边界任务说明>"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## 核心概念
|
|
92
|
+
|
|
93
|
+
- **Agent DAG**:把一次任务拆成 contract、scout、plan、implement、verify、closeout 等可审查节点。
|
|
94
|
+
- **`.harness/`**:记录 task、DAG run、one-shot run、cache 和 live state 等运行态事实。
|
|
95
|
+
- **`harness.json`**:描述项目名、治理根目录、模型路由、executor 和验证脚本。
|
|
96
|
+
- **repo-local skills**:目标项目本地的 `skills/`(loop-agent 主路径)优先于发布包内置 skills,便于项目定制 agent 行为;`init --profile full` 还会把同一份 skills 镜像到 `.agents/skills/`,让外部 agent(如 OpenCode)也能自动发现。DAG skill 解析顺序为:用户配置目录 → `skills/` → `.agents/skills/` → 发布包内置。
|
|
97
|
+
- **治理文档**:`docs/` 保存原则、工作流、验证矩阵、runtime 边界、计划和报告。
|
|
98
|
+
- **shell verification**:完成声明必须有可复现命令作为依据,而不是只靠聊天结论。
|
|
99
|
+
|
|
100
|
+
这些治理原则的设计思想吸收了 Anthropic 长时运行 agent harness、OpenAI Codex harness engineering、腾讯端到端 Harness Engineering 和社区 agent harness 实践:人类掌舵,智能体执行;仓库作为记录系统;任务小步推进;用结构化 handoff 与可复现验证跨 session 保持连续性。背景资料收录在 `website/docs/practices/`。
|
|
101
|
+
|
|
102
|
+
## 能力概览
|
|
103
|
+
|
|
104
|
+
- 生成、校验、执行和汇总 Agent DAG。
|
|
105
|
+
- 从任务说明生成标准 DAG,并按依赖顺序运行规划、实现、验证和收口节点。
|
|
106
|
+
- 维护 `loop` 长程任务状态,包括目标、轮次、信号、验证事实和收口草稿。
|
|
107
|
+
- 通过 Pi executor 执行只读规划、评审、诊断和有边界写入。
|
|
108
|
+
- 保留 Cursor executor 作为显式启用的可选后端。
|
|
109
|
+
- 通过 shell executor 运行确定性的验证命令。
|
|
110
|
+
- 检查任务状态、运行态工件、文档链接、skill entry 和 runtime boundary 等治理规则。
|
|
111
|
+
|
|
112
|
+
## 内置示例
|
|
113
|
+
|
|
114
|
+
`examples/` 默认不复制到目标项目。可以通过工具内置命令查看或按需复制:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
loop-agent examples list
|
|
118
|
+
loop-agent examples show example-dag.json
|
|
119
|
+
loop-agent examples copy example-dag.json --repo-root <target-repo>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## 迭代本仓库
|
|
123
|
+
|
|
124
|
+
如果要用 loop-agent 迭代 loop-agent 本仓库,控制器必须来自已发布的 npm 安装包。不要使用当前工作区的 `npm link` 或 `npm run dev` 作为控制器;首次安装或有意升级可用 `@latest`,但一次自举任务启动后不要在任务中途升级控制器。
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
npm install -g @tea-agent/loop-agent@latest
|
|
128
|
+
npm list -g @tea-agent/loop-agent --depth=0
|
|
129
|
+
loop-agent doctor
|
|
130
|
+
loop-agent run-dag --dag <temp-dir>/<task-id>-dag.json --cwd <repo-root>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`@latest` 只用于安装或升级,不要在 DAG 节点里反复用 `npx @latest` 拉取。自举任务应记录 `npm list -g` 显示的实际版本号。
|
|
134
|
+
|
|
135
|
+
## 文档导航
|
|
136
|
+
|
|
137
|
+
| 路径 | 用途 |
|
|
138
|
+
|---|---|
|
|
139
|
+
| `AGENTS.md` | 本仓库的 agent 开工协议、会话协议和长期工作规则 |
|
|
140
|
+
| `harness.json` | loop-agent 在本仓库的模型、executor、治理根目录和脚本配置 |
|
|
141
|
+
| `docs/README.md` | 治理文档索引 |
|
|
142
|
+
| `docs/verification-matrix.md` | 不同变更类型对应的验证命令 |
|
|
143
|
+
| `docs/production-readiness.md` | Production Readiness v0.1 支持范围、证据和验收标准 |
|
|
144
|
+
| `docs/architecture/runtime-boundaries.md` | runtime 层边界和依赖方向 |
|
|
145
|
+
| `skills/loop-agent/` | loop-agent skill 入口和 references |
|
|
146
|
+
| `examples/` | 可复用 DAG 示例 |
|
|
147
|
+
| `website/docs/` | 面向使用者的 Docusaurus 文档站内容 |
|
|
148
|
+
| `website/docs/practices/` | Anthropic、OpenAI Codex、腾讯端到端工程与社区 harness 实践资料 |
|
|
149
|
+
|
|
150
|
+
## 本仓库开发
|
|
151
|
+
|
|
152
|
+
本地源码开发:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
npm install
|
|
156
|
+
npm run build
|
|
157
|
+
node bin/loop-agent.js --help
|
|
158
|
+
npm run dev -- --help
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
常用验证命令:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
npm run typecheck
|
|
165
|
+
npm test
|
|
166
|
+
bash scripts/check-repo.sh
|
|
167
|
+
bash scripts/ci.sh
|
|
168
|
+
npm run docs:build
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
当前 CLI 使用 `commander` 组织 command tree。顶层 help、子命令 help、参数解析和未知命令错误都由 commander 驱动。
|
|
172
|
+
|
|
173
|
+
Windows 上运行 `scripts/*.sh` 时使用 Git Bash 或已配置的兼容 Bash,不要求使用 WSL 或 POSIX 路径。实际文件操作和 `--output` / `--dag` / `--cwd` 参数使用当前平台原生路径;仓库内引用、JSON/Markdown 证据引用和 glob 约定可继续用 `/` 作为稳定分隔符。
|
|
174
|
+
|
|
175
|
+
## 发布包内容
|
|
176
|
+
|
|
177
|
+
发布包包含静态运行和指导资料:`bin/`、`dist/`、`skills/`、`docs/*.md`、`docs/architecture/runtime-boundaries.md`、`docs/skills/`、`docs/templates/`、`docs/init-surface.manifest.json`、`examples/`、`harness.json`、`AGENTS.md`、`README.md` 和 `CHANGELOG.md`。
|
|
178
|
+
|
|
179
|
+
`docs/progress/`、`docs/reports/`、`docs/exec-plans/`、`docs/decisions/` 等目录下的任务正文是目标仓库实时生成或历史事实;npm 包只携带这些目录的 README,不携带本仓库已有历史记录。
|
|
180
|
+
|
|
181
|
+
DAG skill 指令优先从目标项目或用户配置目录解析;目标项目未提供本地 `skills/` 时,CLI 会回退到 npm 包内置的 `skills/`。因此普通项目不需要复制 loop-agent 仓库历史文档或内置 skills 才能获得默认 DAG 能力。
|
|
182
|
+
|
|
183
|
+
## 发布前检查
|
|
184
|
+
|
|
185
|
+
发布 npm 包前至少运行:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
npm run typecheck
|
|
189
|
+
npm test
|
|
190
|
+
npm run build
|
|
191
|
+
node bin/loop-agent.js --help
|
|
192
|
+
npm pack --dry-run
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
发布入口 `bin/loop-agent.js` 只加载 `dist/cli.js`;`npm run dev -- <args>` 只用于源码开发和定位问题。
|
package/bin/agent-worker.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
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", "worker", "cli.js");
|
|
8
|
-
|
|
9
|
-
if (!existsSync(cliEntry)) {
|
|
10
|
-
console.error(
|
|
11
|
-
`agent-worker: 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
|
-
const cli = await import(pathToFileURL(cliEntry).href);
|
|
18
|
-
await cli.main(process.argv);
|
|
19
|
-
} catch (error) {
|
|
20
|
-
console.error(error instanceof Error ? error.message : String(error));
|
|
21
|
-
process.exit(1);
|
|
22
|
-
}
|
|
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", "worker", "cli.js");
|
|
8
|
+
|
|
9
|
+
if (!existsSync(cliEntry)) {
|
|
10
|
+
console.error(
|
|
11
|
+
`agent-worker: 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
|
+
const cli = await import(pathToFileURL(cliEntry).href);
|
|
18
|
+
await cli.main(process.argv);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
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
|
+
}
|
|
@@ -242,7 +242,7 @@ export function parseDagValidateArgs(args) {
|
|
|
242
242
|
}
|
|
243
243
|
export function parseRunDagArgs(args, defaultCwd) {
|
|
244
244
|
if (args.length === 0) {
|
|
245
|
-
throw new Error("usage: run-dag --dag <path> [--cwd <dir>] [--init-only] [--dry-run] [--max-concurrent N] [--run-id id] [--canvas-path <abs-path> | --canvas <name> [--canvases-dir <dir>]]");
|
|
245
|
+
throw new Error("usage: run-dag --dag <path> [--cwd <dir>] [--init-only] [--dry-run] [--max-concurrent N] [--run-id id] [--canvas-path <abs-path> | --canvas <name> [--canvases-dir <dir>]] [--events-jsonl <path>]");
|
|
246
246
|
}
|
|
247
247
|
let dagPath;
|
|
248
248
|
let cwd;
|
|
@@ -254,6 +254,7 @@ export function parseRunDagArgs(args, defaultCwd) {
|
|
|
254
254
|
let canvasPath;
|
|
255
255
|
let canvasName;
|
|
256
256
|
let canvasesDir;
|
|
257
|
+
let eventsJsonlPath;
|
|
257
258
|
for (let i = 0; i < args.length; i += 1) {
|
|
258
259
|
const arg = args[i];
|
|
259
260
|
if (arg === "--dag") {
|
|
@@ -301,6 +302,12 @@ export function parseRunDagArgs(args, defaultCwd) {
|
|
|
301
302
|
else if (arg.startsWith("--canvases-dir=")) {
|
|
302
303
|
canvasesDir = arg.slice(15);
|
|
303
304
|
}
|
|
305
|
+
else if (arg === "--events-jsonl") {
|
|
306
|
+
eventsJsonlPath = args[++i];
|
|
307
|
+
}
|
|
308
|
+
else if (arg.startsWith("--events-jsonl=")) {
|
|
309
|
+
eventsJsonlPath = arg.slice("--events-jsonl=".length);
|
|
310
|
+
}
|
|
304
311
|
else if (!arg.startsWith("-")) {
|
|
305
312
|
if (!dagPath)
|
|
306
313
|
dagPath = arg;
|
|
@@ -325,6 +332,7 @@ export function parseRunDagArgs(args, defaultCwd) {
|
|
|
325
332
|
canvasPath,
|
|
326
333
|
canvasName,
|
|
327
334
|
canvasesDir,
|
|
335
|
+
eventsJsonlPath,
|
|
328
336
|
};
|
|
329
337
|
}
|
|
330
338
|
export function parseDagReportArgs(args) {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { createDagEventObserver } from "../../workflows/dag/event-observer.js";
|
|
3
|
+
import { composeDagRunObservers } from "../../workflows/dag/observer-compose.js";
|
|
2
4
|
import { createDagCanvasObserver, resolveCanvasPath, } from "../../workflows/dag/canvas-observer.js";
|
|
3
5
|
import { loadDagSpecFromFile, runDag } from "../../workflows/dag/runner.js";
|
|
4
6
|
import { assertValidDagSpec, collectForbiddenExecutorIssues, } from "../../workflows/dag/validate.js";
|
|
@@ -62,13 +64,24 @@ export async function runDagUseCase(input) {
|
|
|
62
64
|
const canvas = resolvedCanvasPath
|
|
63
65
|
? createDagCanvasObserver({ canvasPath: resolvedCanvasPath, spec })
|
|
64
66
|
: undefined;
|
|
67
|
+
const eventObserver = input.eventsJsonlPath
|
|
68
|
+
? createDagEventObserver({
|
|
69
|
+
eventsJsonlPath: input.eventsJsonlPath,
|
|
70
|
+
spec,
|
|
71
|
+
})
|
|
72
|
+
: undefined;
|
|
73
|
+
const observer = composeDagRunObservers([
|
|
74
|
+
canvas?.observer,
|
|
75
|
+
eventObserver?.observer,
|
|
76
|
+
]);
|
|
65
77
|
if (input.dryRun) {
|
|
66
78
|
const summary = await runDag(spec, {
|
|
67
79
|
cwd: input.cwd,
|
|
68
80
|
dryRun: true,
|
|
69
81
|
runId: input.runId,
|
|
70
|
-
observer
|
|
82
|
+
observer,
|
|
71
83
|
});
|
|
84
|
+
await eventObserver?.flush();
|
|
72
85
|
const canvasError = await flushCanvasSafely(canvas);
|
|
73
86
|
return {
|
|
74
87
|
mode: "dry-run",
|
|
@@ -89,8 +102,9 @@ export async function runDagUseCase(input) {
|
|
|
89
102
|
dryRun: false,
|
|
90
103
|
maxConcurrent: input.maxConcurrent,
|
|
91
104
|
runId: input.runId,
|
|
92
|
-
observer
|
|
105
|
+
observer,
|
|
93
106
|
});
|
|
107
|
+
await eventObserver?.flush();
|
|
94
108
|
const canvasError = await flushCanvasSafely(canvas);
|
|
95
109
|
if (resolvedCanvasPath) {
|
|
96
110
|
return {
|
|
@@ -8,6 +8,7 @@ import { runHandoffCheck } from "../commands/handoff-check.js";
|
|
|
8
8
|
import { runInspect } from "../commands/inspect.js";
|
|
9
9
|
import { runInstructions } from "../commands/instructions.js";
|
|
10
10
|
import { runNewTask } from "../commands/new-task.js";
|
|
11
|
+
import { runImportPrd } from "../commands/import-prd.js";
|
|
11
12
|
import { runPlanList } from "../commands/plan-list.js";
|
|
12
13
|
import { runPromoteRun } from "../commands/promote-run.js";
|
|
13
14
|
import { runSpine } from "../commands/spine.js";
|
|
@@ -30,7 +31,7 @@ import { runDagReject } from "../commands/dag-reject.js";
|
|
|
30
31
|
import { runDagReconcileTasks } from "../commands/dag-reconcile-tasks.js";
|
|
31
32
|
import { runDagResume } from "../commands/dag-resume.js";
|
|
32
33
|
import { runDagDecisionInspect, runDagDecisionValidate, } from "../workflows/dag/decision-envelope.js";
|
|
33
|
-
import { runDagDoctor, runDagStatus
|
|
34
|
+
import { runDagDoctor, runDagStatus } from "../workflows/dag/lifecycle.js";
|
|
34
35
|
import { runDagRunTask } from "../commands/dag-run-task.js";
|
|
35
36
|
import { runDagCloseoutDraft, runDagReport } from "../commands/dag-report.js";
|
|
36
37
|
import { runDagFinalVerification } from "../commands/dag-final-verification.js";
|
|
@@ -50,7 +51,12 @@ export function formatSubcommandUsageError(name, subcommands) {
|
|
|
50
51
|
return `usage: ${formatSubcommandUsage(name, subcommands)}`;
|
|
51
52
|
}
|
|
52
53
|
const DOCS_SUBCOMMANDS = ["audit", "archive"];
|
|
53
|
-
const INIT_SUBCOMMANDS = [
|
|
54
|
+
const INIT_SUBCOMMANDS = [
|
|
55
|
+
"instructions",
|
|
56
|
+
"doctor",
|
|
57
|
+
"check-update",
|
|
58
|
+
"update",
|
|
59
|
+
];
|
|
54
60
|
const EXAMPLES_SUBCOMMANDS = ["list", "show", "copy"];
|
|
55
61
|
const CLOSEOUT_SUBCOMMANDS = ["task"];
|
|
56
62
|
const PLAN_SUBCOMMANDS = ["list"];
|
|
@@ -175,6 +181,16 @@ export const COMMAND_DEFINITIONS = [
|
|
|
175
181
|
await runNewTask(repoRoot, taskId, titleParts.join(" ") || undefined);
|
|
176
182
|
},
|
|
177
183
|
},
|
|
184
|
+
{
|
|
185
|
+
name: "import-prd",
|
|
186
|
+
adapter: "required",
|
|
187
|
+
tier: "primary",
|
|
188
|
+
intent: "Copy a user PRD into source/references as an immutable fact source before deriving source/需求.md.",
|
|
189
|
+
usage: "import-prd <task-id> --file <path> [--name requirement] [--role requirement] [--json]",
|
|
190
|
+
handler: async ({ repoRoot, subcommand, rest }) => {
|
|
191
|
+
await runImportPrd(repoRoot, [subcommand, ...rest].filter(Boolean));
|
|
192
|
+
},
|
|
193
|
+
},
|
|
178
194
|
{
|
|
179
195
|
name: "status",
|
|
180
196
|
adapter: "required",
|
|
@@ -481,7 +497,9 @@ export const COMMAND_DEFINITIONS = [
|
|
|
481
497
|
}
|
|
482
498
|
if (subcommand === "decision") {
|
|
483
499
|
const decisionSubcommand = rest[0];
|
|
484
|
-
const decisionArgs = rest
|
|
500
|
+
const decisionArgs = rest
|
|
501
|
+
.slice(1)
|
|
502
|
+
.filter((arg) => Boolean(arg));
|
|
485
503
|
if (decisionSubcommand === "inspect") {
|
|
486
504
|
await runDagDecisionInspect(repoRoot, decisionArgs);
|
|
487
505
|
return;
|
|
@@ -500,7 +518,7 @@ export const COMMAND_DEFINITIONS = [
|
|
|
500
518
|
adapter: "required",
|
|
501
519
|
tier: "primary",
|
|
502
520
|
intent: "Execute a reviewed Agent DAG spec.",
|
|
503
|
-
usage: "run-dag --dag <path> [
|
|
521
|
+
usage: "run-dag --dag <path> [--cwd <dir>] [--init-only] [--dry-run] [--max-concurrent N] [--run-id id] [--canvas-path <abs-path> | --canvas <name> [--canvases-dir <dir>]] [--events-jsonl <path>]",
|
|
504
522
|
handler: async ({ repoRoot, subcommand, rest }) => {
|
|
505
523
|
const runDagArgs = [subcommand, ...rest].filter((arg) => Boolean(arg));
|
|
506
524
|
await runRunDag(repoRoot, runDagArgs);
|
package/dist/cli/help.js
CHANGED
|
@@ -24,8 +24,9 @@ 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.
|
|
28
|
-
" 3. run-
|
|
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>",
|
|
29
30
|
"Operator recovery/closeout: dag status/report/doctor/closeout-draft",
|
|
30
31
|
`Primary commands: ${primary}`,
|
|
31
32
|
`Operator commands: ${operator}`,
|