coding-agent-harness 1.0.4 → 1.0.5
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/CHANGELOG.md +7 -0
- package/LICENSE +661 -21
- package/LICENSE-EXCEPTION.md +37 -0
- package/README.md +33 -1
- package/README.zh-CN.md +23 -1
- package/SKILL.md +9 -8
- package/docs-release/architecture/overview.md +1 -1
- package/docs-release/architecture/overview.zh-CN.md +1 -1
- package/docs-release/architecture/system-explainer/01-system-overview.md +217 -0
- package/docs-release/architecture/system-explainer/02-module-dependency.md +257 -0
- package/docs-release/architecture/system-explainer/03-task-lifecycle.md +304 -0
- package/docs-release/architecture/system-explainer/04-check-and-governance.md +239 -0
- package/docs-release/architecture/system-explainer/05-data-flow.md +276 -0
- package/docs-release/architecture/system-explainer/06-preset-and-migration.md +303 -0
- package/docs-release/architecture/system-explainer/README.md +67 -0
- package/docs-release/architecture/system-explainer/en-US/01-system-overview.md +226 -0
- package/docs-release/architecture/system-explainer/en-US/02-module-dependency.md +263 -0
- package/docs-release/architecture/system-explainer/en-US/03-task-lifecycle.md +319 -0
- package/docs-release/architecture/system-explainer/en-US/04-check-and-governance.md +250 -0
- package/docs-release/architecture/system-explainer/en-US/05-data-flow.md +290 -0
- package/docs-release/architecture/system-explainer/en-US/06-preset-and-migration.md +323 -0
- package/docs-release/architecture/system-explainer/en-US/README.md +70 -0
- package/docs-release/guides/agent-installation.en-US.md +8 -7
- package/docs-release/guides/agent-installation.md +9 -7
- package/docs-release/guides/preset-development.md +26 -2
- package/docs-release/guides/task-state-machine.en-US.md +30 -13
- package/docs-release/guides/task-state-machine.md +30 -13
- package/examples/minimal-project/docs/09-PLANNING/TASKS/demo-task/INDEX.md +60 -0
- package/package.json +3 -2
- package/references/harness-ledger.md +1 -1
- package/scripts/commands/migration-command.mjs +30 -0
- package/scripts/commands/task-command.mjs +26 -25
- package/scripts/harness.mjs +7 -3
- package/scripts/lib/capability-registry.mjs +17 -21
- package/scripts/lib/check-module-parallel.mjs +9 -16
- package/scripts/lib/check-profiles.mjs +35 -81
- package/scripts/lib/check-task-contracts.mjs +13 -5
- package/scripts/lib/core-shared.mjs +55 -2
- package/scripts/lib/dashboard-data.mjs +126 -18
- package/scripts/lib/dashboard-workbench.mjs +80 -1
- package/scripts/lib/dashboard-writer.mjs +6 -2
- package/scripts/lib/git-status-summary.mjs +1 -1
- package/scripts/lib/governance-sync.mjs +180 -83
- package/scripts/lib/harness-core.mjs +1 -0
- package/scripts/lib/markdown-utils.mjs +33 -0
- package/scripts/lib/migration-planner.mjs +4 -6
- package/scripts/lib/phase-kind.mjs +50 -0
- package/scripts/lib/preset-engine.mjs +5 -8
- package/scripts/lib/preset-registry.mjs +188 -39
- package/scripts/lib/review-confirm-git-gate.mjs +1 -1
- package/scripts/lib/status-builder.mjs +88 -0
- package/scripts/lib/status-dashboard-renderer.mjs +7 -4
- package/scripts/lib/task-audit-metadata.mjs +385 -0
- package/scripts/lib/task-audit-migration.mjs +350 -0
- package/scripts/lib/task-completion-consistency.mjs +11 -1
- package/scripts/lib/task-lifecycle/create-task-helpers.mjs +67 -0
- package/scripts/lib/task-lifecycle/phase-sync.mjs +88 -0
- package/scripts/lib/task-lifecycle/review-confirm.mjs +40 -29
- package/scripts/lib/task-lifecycle/review-gates.mjs +13 -10
- package/scripts/lib/task-lifecycle/review-submission.mjs +63 -0
- package/scripts/lib/task-lifecycle/scaffold-provenance.mjs +49 -0
- package/scripts/lib/task-lifecycle/template-files.mjs +53 -0
- package/scripts/lib/task-lifecycle.mjs +114 -147
- package/scripts/lib/task-metadata.mjs +118 -0
- package/scripts/lib/task-review-model.mjs +54 -68
- package/scripts/lib/task-scanner.mjs +70 -143
- package/skills/preset-creator/references/complex-task-skeleton/brief.md +11 -0
- package/templates/AGENTS.md.template +7 -5
- package/templates/dashboard/assets/app-src/00-state.js +12 -0
- package/templates/dashboard/assets/app-src/10-router.js +3 -0
- package/templates/dashboard/assets/app-src/20-overview.js +7 -3
- package/templates/dashboard/assets/app-src/35-task-detail.js +46 -6
- package/templates/dashboard/assets/app-src/55-presets.js +375 -0
- package/templates/dashboard/assets/app-src/60-shared.js +3 -1
- package/templates/dashboard/assets/app-src/90-bindings.js +131 -0
- package/templates/dashboard/assets/app.css +583 -0
- package/templates/dashboard/assets/app.css.manifest.json +1 -0
- package/templates/dashboard/assets/app.js +578 -10
- package/templates/dashboard/assets/app.manifest.json +1 -0
- package/templates/dashboard/assets/css-src/00-foundation.css +4 -0
- package/templates/dashboard/assets/css-src/40-detail-modules-migration.css +62 -0
- package/templates/dashboard/assets/css-src/45-presets.css +516 -0
- package/templates/dashboard/assets/i18n.js +140 -2
- package/templates/planning/INDEX.md +87 -0
- package/templates/planning/brief.md +1 -1
- package/templates/planning/module_session_prompt.md +1 -0
- package/templates/planning/review.md +0 -18
- package/templates/planning/task_plan.md +4 -43
- package/templates/planning/visual_map.md +13 -9
- package/templates/planning/visual_map.simple.md +52 -0
- package/templates/reference/execution-workflow-standard.md +29 -2
- package/templates-zh-CN/AGENTS.md.template +7 -5
- package/templates-zh-CN/planning/INDEX.md +87 -0
- package/templates-zh-CN/planning/brief.md +1 -1
- package/templates-zh-CN/planning/module_session_prompt.md +1 -0
- package/templates-zh-CN/planning/review.md +0 -18
- package/templates-zh-CN/planning/task_plan.md +3 -63
- package/templates-zh-CN/planning/visual_map.md +14 -7
- package/templates-zh-CN/planning/visual_map.simple.md +48 -0
- package/templates-zh-CN/reference/execution-workflow-standard.md +31 -6
|
@@ -185,26 +185,26 @@ The agent must read `session.json` and `migrate-plan.json`, then migrate active
|
|
|
185
185
|
After initialization or migration, agents should not manually copy task folders. Use lifecycle commands:
|
|
186
186
|
|
|
187
187
|
```bash
|
|
188
|
-
harness new-task
|
|
188
|
+
harness new-task \
|
|
189
189
|
--title "Phase 2 task lifecycle" \
|
|
190
190
|
--locale en-US \
|
|
191
191
|
/path/to/project
|
|
192
192
|
|
|
193
|
-
harness task-start
|
|
193
|
+
harness task-start <task-id-from-new-task-output> \
|
|
194
194
|
--message "Start lifecycle slice implementation" \
|
|
195
195
|
/path/to/project
|
|
196
196
|
|
|
197
|
-
harness task-log
|
|
197
|
+
harness task-log <task-id-from-new-task-output> \
|
|
198
198
|
--message "Completed CLI and template updates" \
|
|
199
199
|
--evidence "command:TARGET:npm-test:passed" \
|
|
200
200
|
/path/to/project
|
|
201
201
|
|
|
202
|
-
harness review-confirm
|
|
202
|
+
harness review-confirm <task-id-from-new-task-output> \
|
|
203
203
|
--reviewer "Human Reviewer" \
|
|
204
|
-
--confirm
|
|
204
|
+
--confirm <task-id-from-new-task-output> \
|
|
205
205
|
/path/to/project
|
|
206
206
|
|
|
207
|
-
harness task-complete
|
|
207
|
+
harness task-complete <task-id-from-new-task-output> \
|
|
208
208
|
--message "Verification loop completed" \
|
|
209
209
|
/path/to/project
|
|
210
210
|
```
|
|
@@ -212,13 +212,14 @@ harness task-complete phase-2-lifecycle \
|
|
|
212
212
|
Rules:
|
|
213
213
|
|
|
214
214
|
- Do not manually copy task templates or create partial task folders. `harness check` enforces the file set created by `new-task`.
|
|
215
|
+
- `new-task --title "..."` generates a default ID like `YYYY-MM-DD-phase-2-task-lifecycle-a1b2c3d4` to reduce collisions when multiple people or agents create tasks in the same repository. Pass an explicit `<task-id>` only when a coordinator needs a stable compatibility ID.
|
|
215
216
|
- `new-task --budget simple` creates `brief.md`, `task_plan.md`, `visual_map.md`, and `progress.md`.
|
|
216
217
|
- `new-task` defaults to `standard` and creates the simple files plus `execution_strategy.md`, `findings.md`, `lesson_candidates.md`, and `review.md`.
|
|
217
218
|
- `new-task --budget complex` creates the standard files plus `references/INDEX.md` and `artifacts/INDEX.md`.
|
|
218
219
|
- Existing task directories are not overwritten. Renaming or continuing old tasks is a coordinator decision.
|
|
219
220
|
- `task-start`, `task-block`, and `task-complete` only update lifecycle status and logs in `progress.md`.
|
|
220
221
|
- `task-log` only appends execution records. Evidence uses `type:PATH:summary`, for example `command:TARGET:npm-test:passed`.
|
|
221
|
-
- `review-confirm`
|
|
222
|
+
- `review-confirm` writes human review confirmation audit fields to the task `INDEX.md` through gated commits. It must reject open P0/P1/P2 findings marked `Open: yes` or `Blocks Release: yes`.
|
|
222
223
|
- CLI-owned lifecycle and lesson commands auto-commit allowlisted writes in a clean Git root. Dirty state appears in `status` / dashboard warnings and blocks those mechanical commits. Agent-owned manual edits still need proactive commits; deferred commits must record the no-commit reason, owner, and next step.
|
|
223
224
|
- `status --json` keeps old `task.state` for compatibility and adds `lifecycleState`, `reviewStatus`, `closeoutStatus`, and `stateConflicts`. `done` means implementation finished; it does not mean `closed`.
|
|
224
225
|
- For human operation, start the local HTML workbench with `harness dev /path/to/project`. It binds to `127.0.0.1`, chooses a port automatically, opens the browser, and refreshes when docs change. In headless or CI contexts, use `harness dev --no-open /path/to/project`.
|
|
@@ -204,26 +204,26 @@ harness migrate-verify \
|
|
|
204
204
|
初始化或迁移完成后,agent 不应手工复制任务目录。使用生命周期命令创建和推进任务:
|
|
205
205
|
|
|
206
206
|
```bash
|
|
207
|
-
harness new-task
|
|
207
|
+
harness new-task \
|
|
208
208
|
--title "阶段二任务生命周期" \
|
|
209
209
|
--locale zh-CN \
|
|
210
210
|
/path/to/project
|
|
211
211
|
|
|
212
|
-
harness task-start
|
|
212
|
+
harness task-start <new-task 输出的 task-id> \
|
|
213
213
|
--message "开始实现生命周期切片" \
|
|
214
214
|
/path/to/project
|
|
215
215
|
|
|
216
|
-
harness task-log
|
|
216
|
+
harness task-log <new-task 输出的 task-id> \
|
|
217
217
|
--message "完成 CLI 与模板更新" \
|
|
218
218
|
--evidence "command:TARGET:npm-test:passed" \
|
|
219
219
|
/path/to/project
|
|
220
220
|
|
|
221
|
-
harness review-confirm
|
|
221
|
+
harness review-confirm <new-task 输出的 task-id> \
|
|
222
222
|
--reviewer "Human Reviewer" \
|
|
223
|
-
--confirm
|
|
223
|
+
--confirm <new-task 输出的 task-id> \
|
|
224
224
|
/path/to/project
|
|
225
225
|
|
|
226
|
-
harness task-complete
|
|
226
|
+
harness task-complete <new-task 输出的 task-id> \
|
|
227
227
|
--message "验证闭环完成" \
|
|
228
228
|
/path/to/project
|
|
229
229
|
```
|
|
@@ -232,6 +232,8 @@ harness task-complete phase-2-lifecycle \
|
|
|
232
232
|
|
|
233
233
|
- 不要手工复制任务模板,也不要创建不完整任务目录。`harness check` 会按
|
|
234
234
|
`new-task` 创建的预算文件集校验。
|
|
235
|
+
- `new-task --title "..."` 默认生成类似 `YYYY-MM-DD-phase-2-task-lifecycle-a1b2c3d4`
|
|
236
|
+
的任务 ID,避免多人或多 agent 同仓协作时重名;只有需要固定兼容 ID 时才传显式 `<task-id>`。
|
|
235
237
|
- `new-task --budget simple` 创建 `brief.md`、`task_plan.md`、`visual_map.md`
|
|
236
238
|
和 `progress.md`。
|
|
237
239
|
- `new-task` 默认 `standard`,创建 simple 文件,并额外创建
|
|
@@ -242,7 +244,7 @@ harness task-complete phase-2-lifecycle \
|
|
|
242
244
|
- `task-start`、`task-block`、`task-complete` 只更新 `progress.md` 的生命周期状态和日志。
|
|
243
245
|
- `task-log` 只追加执行记录;证据使用 `type:PATH:summary`,例如
|
|
244
246
|
`command:TARGET:npm-test:passed`。
|
|
245
|
-
- `review-confirm`
|
|
247
|
+
- `review-confirm` 会通过受控提交把人工确认审计字段写入任务 `INDEX.md`;如果存在 `Open: yes` 或 `Blocks Release: yes` 的开放 P0/P1/P2 finding,必须拒绝确认。
|
|
246
248
|
- CLI-owned lifecycle 和 lesson 命令会在干净 Git root 中自动提交 allowlisted 写入;dirty 状态会出现在 `status` / dashboard 的警告里,并阻塞这些机械化提交。Agent 手工改动仍要主动提交,不能提交时记录 no-commit reason、owner 和下一步。
|
|
247
249
|
- `status --json` 保留旧 `task.state` 用于兼容,并新增 `lifecycleState`、`reviewStatus`、`closeoutStatus` 和 `stateConflicts`。`done` 只表示实现完成,不等于 `closed`。
|
|
248
250
|
- 人工操作入口使用本地 HTML workbench:`harness dev /path/to/project`。它会启动只绑定 `127.0.0.1` 的动态页面、自动选择端口、打开浏览器并随 docs 变更刷新。无 GUI 或 CI 场景使用 `harness dev --no-open /path/to/project`。
|
|
@@ -28,6 +28,29 @@ and `harness install-user` seed them into the user preset root, while
|
|
|
28
28
|
`harness preset seed` for the user root or `harness preset seed --project <target>`
|
|
29
29
|
for the project root when a preset root is missing or incomplete.
|
|
30
30
|
|
|
31
|
+
## Dashboard Management
|
|
32
|
+
|
|
33
|
+
The Dashboard exposes a Presets view for the target project. Static dashboards
|
|
34
|
+
show a read-only catalog of discovered project, user, and bundled presets,
|
|
35
|
+
including source, purpose, compatible budgets, task kind, manifest path, and
|
|
36
|
+
resource counts.
|
|
37
|
+
|
|
38
|
+
Use the local dynamic Workbench when you want to manage presets from the web UI:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
harness dev /path/to/project
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
In Workbench mode, the Presets view can check presets, install a local preset
|
|
45
|
+
directory, `.zip` archive, or bundled preset id into the project or user scope,
|
|
46
|
+
seed bundled presets into either scope, and uninstall project/user presets.
|
|
47
|
+
Bundled package presets are immutable from the Dashboard: they can be inspected,
|
|
48
|
+
checked, and used as install or seed sources, but not edited or deleted.
|
|
49
|
+
|
|
50
|
+
The CLI and filesystem remain canonical. The Dashboard calls the same preset
|
|
51
|
+
registry operations as `harness preset ...`; it does not store independent preset
|
|
52
|
+
state.
|
|
53
|
+
|
|
31
54
|
## Package Layout
|
|
32
55
|
|
|
33
56
|
```text
|
|
@@ -184,13 +207,14 @@ Supported evidence types:
|
|
|
184
207
|
```bash
|
|
185
208
|
harness preset check ./my-preset
|
|
186
209
|
harness preset install ./my-preset
|
|
210
|
+
harness preset install ./my-preset.zip
|
|
187
211
|
harness preset install ./my-preset --project /path/to/project
|
|
188
212
|
harness preset install legacy-migration --force
|
|
189
213
|
harness preset seed
|
|
190
214
|
harness preset seed --project /path/to/project
|
|
191
215
|
harness preset list --json /path/to/project
|
|
192
216
|
harness preset inspect custom-review --json /path/to/project
|
|
193
|
-
harness new-task
|
|
217
|
+
harness new-task --title "Custom review task" --preset custom-review --subject "API contracts" /path/to/project
|
|
194
218
|
harness preset uninstall custom-review
|
|
195
219
|
```
|
|
196
220
|
|
|
@@ -199,7 +223,7 @@ harness preset uninstall custom-review
|
|
|
199
223
|
For every preset, prove both the manifest and downstream task behavior:
|
|
200
224
|
|
|
201
225
|
1. Run `harness preset check ./my-preset`.
|
|
202
|
-
2. Install into an isolated HOME or disposable environment.
|
|
226
|
+
2. Install the folder and, if distributing an archive, install the `.zip` into an isolated HOME or disposable environment.
|
|
203
227
|
3. Create at least one task with `harness new-task --preset`.
|
|
204
228
|
4. For reference bundles, create two different tasks from the same preset and verify both contain the same shared `references/` files and independent audit/evidence bundles.
|
|
205
229
|
5. Run `harness status --json`, `harness task-index --json`, and `harness check --profile target-project <target>`.
|
|
@@ -5,7 +5,8 @@ Chinese mirror: `docs-release/guides/task-state-machine.md`
|
|
|
5
5
|
Coding Agent Harness does not model task state as a single field. The Dashboard derives the visible lifecycle from multiple files:
|
|
6
6
|
|
|
7
7
|
- `progress.md` stores raw `task.state` and execution evidence.
|
|
8
|
-
- `review.md` stores Agent Review Submission, material findings, and
|
|
8
|
+
- `review.md` stores Agent Review Submission, material findings, and review evidence.
|
|
9
|
+
- `INDEX.md` stores Task Audit Metadata, including task creation and human review confirmation audit fields.
|
|
9
10
|
- `lesson_candidates.md` records lesson candidate decisions and sedimentation routing.
|
|
10
11
|
- `10-WALKTHROUGH/Closeout-SSoT.md` records closeout status and links walkthrough evidence.
|
|
11
12
|
- Tombstone / supersede metadata records whether a task was soft-deleted, merged, archived, or replaced.
|
|
@@ -32,20 +33,37 @@ stateDiagram-v2
|
|
|
32
33
|
finalized --> [*]
|
|
33
34
|
```
|
|
34
35
|
|
|
35
|
-
`task-review` means the agent submitted a review packet. It does not mean human approval. `review-confirm` is the
|
|
36
|
+
`task-review` means the agent submitted a review packet. It does not mean human approval. `review-confirm` is the human confirmation gate and writes its audit fields to `INDEX.md`. `task-complete` / closeout is not a substitute for review confirmation.
|
|
37
|
+
|
|
38
|
+
## Phase Kind Map
|
|
39
|
+
|
|
40
|
+
`visual_map.md` is the machine-readable phase timeline. New phase tables may include `Kind`, `Exit Command`, and `Actor` columns:
|
|
41
|
+
|
|
42
|
+
| Kind | Purpose | Counts Toward Implementation Completion | Typical Exit |
|
|
43
|
+
| --- | --- | --- | --- |
|
|
44
|
+
| `init` | Scope, context, budget, and execution strategy. | no | `harness task-start <task-id>` |
|
|
45
|
+
| `execution` | Implementation, documentation, and verification slices. | yes | `harness task-phase <task-id> <phase-id> --state done --completion 100 --evidence present` |
|
|
46
|
+
| `gate` | Agent review submission, human confirmation, lesson routing, walkthrough, and closeout. | no | `harness task-review`, `harness review-confirm`, or `harness task-complete` |
|
|
47
|
+
|
|
48
|
+
Older phase tables without `Kind` remain valid and are treated as `execution`.
|
|
49
|
+
The Dashboard implementation score uses non-skipped `execution` phases only.
|
|
50
|
+
Gate phases explain the next lifecycle action and owner; they do not make a finished implementation look incomplete.
|
|
51
|
+
Agents may run `Exit Command` values with `Actor: agent`. `Actor: human` gates, especially `review-confirm`, require explicit human action.
|
|
36
52
|
|
|
37
53
|
## Derived State
|
|
38
54
|
|
|
39
55
|
```mermaid
|
|
40
56
|
flowchart TB
|
|
41
57
|
Progress["progress.md<br/>task.state + evidence"]
|
|
42
|
-
|
|
58
|
+
Index["INDEX.md<br/>Task Audit Metadata"]
|
|
59
|
+
Review["review.md<br/>Agent Review Submission + findings + evidence"]
|
|
43
60
|
Lessons["lesson_candidates.md<br/>decision + sedimentation route"]
|
|
44
61
|
Closeout["Closeout-SSoT.md<br/>closeout row + walkthrough"]
|
|
45
62
|
Tombstone["tombstone / supersede metadata"]
|
|
46
63
|
Scanner["scanner"]
|
|
47
64
|
|
|
48
65
|
Progress --> Scanner
|
|
66
|
+
Index --> Scanner
|
|
49
67
|
Review --> Scanner
|
|
50
68
|
Lessons --> Scanner
|
|
51
69
|
Closeout --> Scanner
|
|
@@ -62,7 +80,7 @@ flowchart TB
|
|
|
62
80
|
| Field | Source | Purpose |
|
|
63
81
|
| --- | --- | --- |
|
|
64
82
|
| `task.state` | `progress.md` | Raw execution stage. |
|
|
65
|
-
| `reviewStatus` | `
|
|
83
|
+
| `reviewStatus` | `INDEX.md` Task Audit Metadata + `review.md` findings/submission | Separates missing review, agent-submitted review, blockers, and human confirmation. |
|
|
66
84
|
| `closeoutStatus` | `Closeout-SSoT.md` | Separates missing, pending, and closed closeout. |
|
|
67
85
|
| `lifecycleState` | scanner-derived | Main Dashboard lifecycle meaning. |
|
|
68
86
|
| `taskQueues[]` | scanner-derived | Which lifecycle queues include the task. A task can be visible in more than one governance queue. |
|
|
@@ -76,9 +94,9 @@ flowchart TB
|
|
|
76
94
|
| Tombstone, superseded-by, archive, or abandoned marker exists | `soft-deleted-superseded` | Hidden by default, but preserved for audit and replacement tracing. |
|
|
77
95
|
| Open P0-P2 finding, invalid transition, audit failure, or failed human-review gate | `blocked` | Cannot enter human confirmation until the blocker is fixed or waived. |
|
|
78
96
|
| Standard / complex task is missing required files, sections, evidence, lesson decision, or review submission | `missing-materials` | Needs agent repair; not part of the human review queue. |
|
|
79
|
-
| `task-review` was submitted, materials are ready, and
|
|
80
|
-
|
|
|
81
|
-
|
|
|
97
|
+
| `task-review` was submitted, materials are ready, and `INDEX.md` does not show human confirmation | `review-submitted` | Truly waiting for human review. |
|
|
98
|
+
| `INDEX.md` shows human confirmation, but closeout / ledger / lessons are not fully closed | `confirmed-finalization-pending` | Accountability moved to the reviewer, but governance closeout remains. |
|
|
99
|
+
| `INDEX.md` shows human confirmation, and closeout / ledger / lesson routing are complete | `finalized` | Truly complete and traceable. |
|
|
82
100
|
| `task.state = blocked` without a review blocker | `active-blocked` | Execution is blocked. |
|
|
83
101
|
| `task.state = in_progress` | `active` | Work is active. |
|
|
84
102
|
| `task.state = planned/not_started` | `ready` | Work has not started; not in human review by default. |
|
|
@@ -91,9 +109,9 @@ flowchart TB
|
|
|
91
109
|
| `required` | Review document exists, but the packet is not ready for human review. |
|
|
92
110
|
| `submitted` | An agent submitted a review packet. This is not human confirmation. |
|
|
93
111
|
| `blocked-open-findings` | There is an open P0-P2 finding or a finding that blocks release / confirmation. |
|
|
94
|
-
| `confirmed` | `Human Review
|
|
112
|
+
| `confirmed` | `INDEX.md` Task Audit Metadata has `Human Review Status: confirmed` and committed audit fields. |
|
|
95
113
|
|
|
96
|
-
Agent self-review, subagent review, and coordinator review can only move a task toward `submitted`. Only `review-confirm` or an explicit Dashboard Workbench human confirmation writes
|
|
114
|
+
Agent self-review, subagent review, and coordinator review can only move a task toward `submitted`. Only `review-confirm` or an explicit Dashboard Workbench human confirmation writes the confirmation audit fields in `INDEX.md`.
|
|
97
115
|
|
|
98
116
|
## Lifecycle Queues
|
|
99
117
|
|
|
@@ -167,16 +185,15 @@ sequenceDiagram
|
|
|
167
185
|
else accepted
|
|
168
186
|
API->>Lifecycle: confirmTaskReview()
|
|
169
187
|
Lifecycle->>Lifecycle: verify clean Git state, identity, hooks, allowlist
|
|
170
|
-
Lifecycle->>Docs: write
|
|
171
|
-
Lifecycle->>
|
|
172
|
-
Lifecycle->>Lifecycle: commit allowlisted review/progress files
|
|
188
|
+
Lifecycle->>Docs: write confirmation fields to INDEX.md
|
|
189
|
+
Lifecycle->>Lifecycle: commit allowlisted INDEX.md
|
|
173
190
|
Lifecycle->>Docs: record confirmation commit SHA + committed audit status
|
|
174
191
|
API->>Scanner: regenerate dashboard snapshot
|
|
175
192
|
API-->>UI: confirmed task
|
|
176
193
|
end
|
|
177
194
|
```
|
|
178
195
|
|
|
179
|
-
Strict rule: an agent can prepare review evidence and submit the task for review, but the task is not human-confirmed until the
|
|
196
|
+
Strict rule: an agent can prepare review evidence and submit the task for review, but the task is not human-confirmed until the task `INDEX.md` contains committed confirmation audit fields. Confirmation must use gated auto-commit: the CLI and Workbench reject dirty Git state, missing commit identity, hook/preflight failure, or writes outside the current task `INDEX.md` allowlist, and return recovery guidance.
|
|
180
197
|
|
|
181
198
|
CLI-owned mechanical writes and agent-owned manual slices have different boundaries. `new-task`, `task-*`, `task-phase`, `module-step`, `review-confirm`, `lesson-sediment`, and `lesson-promote --apply` acquire a lock, restrict writes to an allowlist, and auto-commit in a clean Git root. When an agent manually edits code, templates, or task docs, it still needs to proactively commit after verification; if it cannot commit, it must record the no-commit reason, owner, and next step, and must not mix unrelated dirty changes into the task commit.
|
|
182
199
|
|
|
@@ -5,7 +5,8 @@ English mirror: `docs-release/guides/task-state-machine.en-US.md`
|
|
|
5
5
|
Coding Agent Harness 的任务状态不是一个单字段。Dashboard 里看到的生命周期由多个文件共同推导:
|
|
6
6
|
|
|
7
7
|
- `progress.md` 记录原始 `task.state` 和执行证据。
|
|
8
|
-
- `review.md` 记录 Agent Review Submission、material findings
|
|
8
|
+
- `review.md` 记录 Agent Review Submission、material findings 和审查证据。
|
|
9
|
+
- `INDEX.md` 记录任务审计元数据,包括任务创建和人工确认审计字段。
|
|
9
10
|
- `lesson_candidates.md` 记录 lesson candidate 的人工判定和后续沉淀路由。
|
|
10
11
|
- `10-WALKTHROUGH/Closeout-SSoT.md` 记录任务是否完成收口,并链接 walkthrough。
|
|
11
12
|
- Tombstone / supersede 信息记录任务是否被软删除、合并、归档或替代。
|
|
@@ -32,20 +33,37 @@ stateDiagram-v2
|
|
|
32
33
|
finalized --> [*]
|
|
33
34
|
```
|
|
34
35
|
|
|
35
|
-
`task-review` 表示 Agent 提交审查材料包,不表示人工批准。`review-confirm`
|
|
36
|
+
`task-review` 表示 Agent 提交审查材料包,不表示人工批准。`review-confirm` 才表示人工确认门禁,并把审计字段写入 `INDEX.md`。`task-complete` / closeout 也不是 review confirmation 的替代品。
|
|
37
|
+
|
|
38
|
+
## 阶段类型地图
|
|
39
|
+
|
|
40
|
+
`visual_map.md` 是机器可读的阶段时间线。新的阶段表可以包含 `Kind`、`Exit Command` 和 `Actor` 三列:
|
|
41
|
+
|
|
42
|
+
| Kind | 作用 | 是否计入实现完成度 | 典型出口 |
|
|
43
|
+
| --- | --- | --- | --- |
|
|
44
|
+
| `init` | 范围、上下文、预算和执行策略。 | 否 | `harness task-start <task-id>` |
|
|
45
|
+
| `execution` | 实现、文档和验证切片。 | 是 | `harness task-phase <task-id> <phase-id> --state done --completion 100 --evidence present` |
|
|
46
|
+
| `gate` | Agent 提交审查、人工确认、lesson routing、walkthrough 和 closeout。 | 否 | `harness task-review`、`harness review-confirm` 或 `harness task-complete` |
|
|
47
|
+
|
|
48
|
+
旧阶段表没有 `Kind` 也继续有效,默认按 `execution` 处理。
|
|
49
|
+
Dashboard 实现完成度只计算非 skipped 的 `execution` 阶段。
|
|
50
|
+
Gate 阶段用于解释下一步生命周期动作和责任人,不会让已完成的实现看起来未完成。
|
|
51
|
+
Agent 只能执行 `Actor: agent` 的 `Exit Command`。`Actor: human` 的 gate,尤其是 `review-confirm`,必须由人工明确执行。
|
|
36
52
|
|
|
37
53
|
## 派生状态
|
|
38
54
|
|
|
39
55
|
```mermaid
|
|
40
56
|
flowchart TB
|
|
41
57
|
Progress["progress.md<br/>task.state + evidence"]
|
|
42
|
-
|
|
58
|
+
Index["INDEX.md<br/>Task Audit Metadata"]
|
|
59
|
+
Review["review.md<br/>Agent Review Submission + findings + evidence"]
|
|
43
60
|
Lessons["lesson_candidates.md<br/>decision + sedimentation route"]
|
|
44
61
|
Closeout["Closeout-SSoT.md<br/>closeout row + walkthrough"]
|
|
45
62
|
Tombstone["tombstone / supersede metadata"]
|
|
46
63
|
Scanner["scanner"]
|
|
47
64
|
|
|
48
65
|
Progress --> Scanner
|
|
66
|
+
Index --> Scanner
|
|
49
67
|
Review --> Scanner
|
|
50
68
|
Lessons --> Scanner
|
|
51
69
|
Closeout --> Scanner
|
|
@@ -62,7 +80,7 @@ flowchart TB
|
|
|
62
80
|
| 字段 | 来源 | 作用 |
|
|
63
81
|
| --- | --- | --- |
|
|
64
82
|
| `task.state` | `progress.md` | 原始执行阶段。 |
|
|
65
|
-
| `reviewStatus` | `
|
|
83
|
+
| `reviewStatus` | `INDEX.md` Task Audit Metadata + `review.md` findings/submission | 区分缺审查、Agent 已提交审查、阻塞、人工确认。 |
|
|
66
84
|
| `closeoutStatus` | `Closeout-SSoT.md` | 区分收口缺失、待处理、已关闭。 |
|
|
67
85
|
| `lifecycleState` | scanner 派生 | Dashboard 的主生命周期语义。 |
|
|
68
86
|
| `taskQueues[]` | scanner 派生 | 任务属于哪些生命周期队列。一个任务可同时在多个治理队列中可见。 |
|
|
@@ -76,9 +94,9 @@ flowchart TB
|
|
|
76
94
|
| 有 tombstone、superseded-by、archive 或 abandoned 标记 | `soft-deleted-superseded` | 默认隐藏,但保留审计和替代链。 |
|
|
77
95
|
| 有 open P0-P2 finding、非法状态转换、审计失败或人审门禁失败 | `blocked` | 不能进入人工确认,必须先修 blocker 或记录 waiver。 |
|
|
78
96
|
| 标准/复杂任务缺必需文件、章节、证据、lesson decision 或 review submission | `missing-materials` | 需要 Agent 补材料,不属于人审队列。 |
|
|
79
|
-
| 已执行 `task-review
|
|
80
|
-
|
|
|
81
|
-
|
|
|
97
|
+
| 已执行 `task-review`,材料齐全,且 `INDEX.md` 尚未显示人工确认 | `review-submitted` | 真正等待人审。 |
|
|
98
|
+
| `INDEX.md` 已显示人工确认,但 closeout / ledger / lessons 仍未全部收口 | `confirmed-finalization-pending` | 责任已转移给确认人,但治理收口仍待完成。 |
|
|
99
|
+
| `INDEX.md` 已显示人工确认,且 closeout / ledger / lesson routing 完成 | `finalized` | 真正完成,可只读追溯。 |
|
|
82
100
|
| `task.state = blocked` 但没有 review blocker | `active-blocked` | 执行阻塞。 |
|
|
83
101
|
| `task.state = in_progress` | `active` | 执行中。 |
|
|
84
102
|
| `task.state = planned/not_started` | `ready` | 准备中,默认不进入人审队列。 |
|
|
@@ -91,9 +109,9 @@ flowchart TB
|
|
|
91
109
|
| `required` | 有 review 文档,但还没有足够材料可提交人审。 |
|
|
92
110
|
| `submitted` | Agent 已提交审查材料包;这不是人工确认。 |
|
|
93
111
|
| `blocked-open-findings` | 有 open P0-P2 finding,或 finding 阻塞发布 / 确认。 |
|
|
94
|
-
| `confirmed` |
|
|
112
|
+
| `confirmed` | `INDEX.md` Task Audit Metadata 包含 `Human Review Status: confirmed` 和已提交审计字段。 |
|
|
95
113
|
|
|
96
|
-
Agent 自查、subagent 审查和 coordinator 审查都只能让任务接近 `submitted`。只有 `review-confirm` 或 Workbench
|
|
114
|
+
Agent 自查、subagent 审查和 coordinator 审查都只能让任务接近 `submitted`。只有 `review-confirm` 或 Workbench 的明确人工确认动作会把确认审计字段写入 `INDEX.md`。
|
|
97
115
|
|
|
98
116
|
## 生命周期队列
|
|
99
117
|
|
|
@@ -174,16 +192,15 @@ sequenceDiagram
|
|
|
174
192
|
else accepted
|
|
175
193
|
API->>Lifecycle: confirmTaskReview()
|
|
176
194
|
Lifecycle->>Lifecycle: verify Git clean, identity, hooks, allowlist
|
|
177
|
-
Lifecycle->>Docs: write
|
|
178
|
-
Lifecycle->>
|
|
179
|
-
Lifecycle->>Lifecycle: commit allowlisted review/progress files
|
|
195
|
+
Lifecycle->>Docs: write confirmation fields to INDEX.md
|
|
196
|
+
Lifecycle->>Lifecycle: commit allowlisted INDEX.md
|
|
180
197
|
Lifecycle->>Docs: record confirmation commit SHA + committed audit status
|
|
181
198
|
API->>Scanner: regenerate dashboard snapshot
|
|
182
199
|
API-->>UI: confirmed task
|
|
183
200
|
end
|
|
184
201
|
```
|
|
185
202
|
|
|
186
|
-
严格规则:Agent 可以准备 review evidence
|
|
203
|
+
严格规则:Agent 可以准备 review evidence,也可以提交审查;但任务只有在任务 `INDEX.md` 包含已提交的确认审计字段后,才算人工确认。确认动作必须通过 gated auto-commit:Git 状态不干净、提交身份缺失、hook/preflight 失败,或待写文件超出当前任务 `INDEX.md` 白名单时,CLI 和 Workbench 都会拒绝并返回恢复建议。
|
|
187
204
|
|
|
188
205
|
CLI-owned 机械写入和 agent-owned 手工切片是两条边界。`new-task`、`task-*`、`task-phase`、`module-step`、`review-confirm`、`lesson-sediment` 和 `lesson-promote --apply` 会在干净 Git root 中加锁、限制写入范围并自动提交。Agent 手工编辑代码、模板或任务文档时仍要在验证后主动提交;无法提交时必须记录 no-commit reason、owner 和下一步,不能把 unrelated dirty changes 混入任务提交。
|
|
189
206
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Demo task - Task Package Index
|
|
2
|
+
|
|
3
|
+
Task Contract: harness-task/v1
|
|
4
|
+
|
|
5
|
+
## Task Identity
|
|
6
|
+
|
|
7
|
+
| Field | Value |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| Task ID | `demo-task` |
|
|
10
|
+
| Budget | `standard` |
|
|
11
|
+
| Preset | `none` |
|
|
12
|
+
| Module | `n/a` |
|
|
13
|
+
| Long-running | `no` |
|
|
14
|
+
| Created | 2026-05-25 |
|
|
15
|
+
|
|
16
|
+
## Task Audit Metadata
|
|
17
|
+
|
|
18
|
+
| Field | Value |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| Created By | historical-backfill |
|
|
21
|
+
| Created At | 2026-05-25 |
|
|
22
|
+
| Command Shape | n/a |
|
|
23
|
+
| Budget | standard |
|
|
24
|
+
| Template Source | examples/minimal-project historical fixture |
|
|
25
|
+
| Task Creator | n/a |
|
|
26
|
+
| Task Creator Source | legacy-unavailable |
|
|
27
|
+
| Human Review Status | not-confirmed |
|
|
28
|
+
| Confirmation ID | n/a |
|
|
29
|
+
| Confirmed At | n/a |
|
|
30
|
+
| Reviewer | n/a |
|
|
31
|
+
| Reviewer Email | n/a |
|
|
32
|
+
| Confirm Text | n/a |
|
|
33
|
+
| Evidence Checked | n/a |
|
|
34
|
+
| Review Commit SHA | n/a |
|
|
35
|
+
| Audit Source | migrated-legacy-scaffold |
|
|
36
|
+
| Audit Status | migrated |
|
|
37
|
+
| Exception Reason | Existing demo task predates scaffold provenance enforcement. |
|
|
38
|
+
| Message | n/a |
|
|
39
|
+
| Migration Status | migrated |
|
|
40
|
+
| Migrated From | brief.md#Scaffold Provenance |
|
|
41
|
+
| Legacy Extra Fields | {} |
|
|
42
|
+
| Migration Notes | example fixture backfilled to INDEX audit metadata |
|
|
43
|
+
|
|
44
|
+
## Core Contract Files
|
|
45
|
+
|
|
46
|
+
| File | Purpose |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| `brief.md` | Human-readable task summary and context entry. |
|
|
49
|
+
| `task_plan.md` | Current task goal, scope, selected budget, acceptance, and operating decisions. |
|
|
50
|
+
| `visual_map.md` | Phase map, evidence status, next lifecycle commands, and supporting diagrams. |
|
|
51
|
+
| `progress.md` | Execution log, verification evidence, decisions, and handoff notes. |
|
|
52
|
+
|
|
53
|
+
## Standard Task Files
|
|
54
|
+
|
|
55
|
+
| File | Purpose |
|
|
56
|
+
| --- | --- |
|
|
57
|
+
| `execution_strategy.md` | Execution mode, ownership, conflict control, and evidence strategy. |
|
|
58
|
+
| `findings.md` | Findings, research notes, accepted risks, and unresolved questions. |
|
|
59
|
+
| `lesson_candidates.md` | Task-local lesson candidate decisions before closeout. |
|
|
60
|
+
| `review.md` | Agent review submission, adversarial review, findings, evidence, and routing. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coding-agent-harness",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Document governance kernel for long-running coding agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"CHANGELOG.md",
|
|
45
45
|
"SKILL.md",
|
|
46
46
|
"LICENSE",
|
|
47
|
+
"LICENSE-EXCEPTION.md",
|
|
47
48
|
"references/",
|
|
48
49
|
"skills/",
|
|
49
50
|
"presets/",
|
|
@@ -56,5 +57,5 @@
|
|
|
56
57
|
"engines": {
|
|
57
58
|
"node": ">=18"
|
|
58
59
|
},
|
|
59
|
-
"license": "
|
|
60
|
+
"license": "AGPL-3.0-or-later"
|
|
60
61
|
}
|
|
@@ -3,8 +3,38 @@ import {
|
|
|
3
3
|
runMigration,
|
|
4
4
|
verifyMigrationSession,
|
|
5
5
|
} from "../lib/harness-core.mjs";
|
|
6
|
+
import {
|
|
7
|
+
applyTaskAuditIndexMigration,
|
|
8
|
+
planTaskAuditIndexMigration,
|
|
9
|
+
} from "../lib/task-audit-migration.mjs";
|
|
6
10
|
|
|
7
11
|
export function runMigrationCommand(command, { args, takeFlag, takeOption, targetArg }) {
|
|
12
|
+
if (command === "migrate-task-audit-index") {
|
|
13
|
+
const json = takeFlag("--json");
|
|
14
|
+
const apply = takeFlag("--apply");
|
|
15
|
+
const planOnly = takeFlag("--plan");
|
|
16
|
+
try {
|
|
17
|
+
const result = apply && !planOnly
|
|
18
|
+
? applyTaskAuditIndexMigration(targetArg())
|
|
19
|
+
: planTaskAuditIndexMigration(targetArg());
|
|
20
|
+
if (json) {
|
|
21
|
+
console.log(JSON.stringify(result, null, 2));
|
|
22
|
+
} else {
|
|
23
|
+
console.log(`Task audit INDEX migration ${result.result}: ${result.target}`);
|
|
24
|
+
console.log(`actions: ${result.summary.actions}`);
|
|
25
|
+
console.log(`legacy audit blocks: ${result.summary.legacyAuditBlocks}`);
|
|
26
|
+
console.log(`failures: ${result.summary.failures}`);
|
|
27
|
+
for (const action of result.actions || []) console.log(`- ${action.taskId}: ${action.legacyBlocks.join(", ")}`);
|
|
28
|
+
for (const failure of result.failures || []) console.error(`Failure: ${failure.taskId}: ${failure.failure}`);
|
|
29
|
+
}
|
|
30
|
+
process.exit(result.failures?.length ? 1 : 0);
|
|
31
|
+
} catch (error) {
|
|
32
|
+
if (json && error.plan) console.error(JSON.stringify(error.plan, null, 2));
|
|
33
|
+
else console.error(error.message);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
8
38
|
if (command === "migrate-plan") {
|
|
9
39
|
const json = takeFlag("--json");
|
|
10
40
|
const limit = Number.parseInt(takeOption("--limit", "20"), 10) || 20;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
1
|
import {
|
|
3
2
|
confirmTaskReview,
|
|
4
3
|
createTask,
|
|
@@ -28,12 +27,7 @@ export function runTaskCommand(command, { args, takeFlag, takeOption, targetArg
|
|
|
28
27
|
const longRunning = takeFlag("--long-running");
|
|
29
28
|
try {
|
|
30
29
|
const parsed = parseNewTaskArgs(args, { preset, fromSession });
|
|
31
|
-
|
|
32
|
-
if (!taskId) {
|
|
33
|
-
console.error("Missing task id");
|
|
34
|
-
process.exit(2);
|
|
35
|
-
}
|
|
36
|
-
console.log(JSON.stringify(createTask(parsed.target, taskId, { title, locale, dryRun, moduleKey, budget, longRunning, preset, fromSession, presetArgs: parsed.presetArgs }), null, 2));
|
|
30
|
+
console.log(JSON.stringify(createTask(parsed.target, parsed.taskId, { title, locale, dryRun, moduleKey, budget, longRunning, preset, fromSession, presetArgs: parsed.presetArgs, automaticTaskId: parsed.automaticTaskId }), null, 2));
|
|
37
31
|
} catch (error) {
|
|
38
32
|
console.error(error.message);
|
|
39
33
|
process.exit(1);
|
|
@@ -229,20 +223,15 @@ export function runTaskCommand(command, { args, takeFlag, takeOption, targetArg
|
|
|
229
223
|
throw new Error(`Unsupported task command: ${command}`);
|
|
230
224
|
}
|
|
231
225
|
|
|
232
|
-
function parseNewTaskArgs(args, { preset = ""
|
|
226
|
+
function parseNewTaskArgs(args, { preset = "" } = {}) {
|
|
233
227
|
const values = [...args];
|
|
234
|
-
let taskId = "";
|
|
235
|
-
if (!fromSession) {
|
|
236
|
-
taskId = values.shift() || "";
|
|
237
|
-
} else if (values.length > 0 && !values[0].startsWith("-") && !(values.length === 1 && fs.existsSync(values[0]))) {
|
|
238
|
-
taskId = values.shift();
|
|
239
|
-
}
|
|
240
228
|
const presetPackage = preset ? readPresetPackageForNewTask(preset, values) : null;
|
|
241
|
-
|
|
242
|
-
const
|
|
229
|
+
const parsed = splitPresetArgsAndPositionals(values, presetPackage);
|
|
230
|
+
const resolved = resolveNewTaskPositionals(parsed.positionals);
|
|
243
231
|
return {
|
|
244
|
-
taskId,
|
|
245
|
-
target:
|
|
232
|
+
taskId: resolved.taskId,
|
|
233
|
+
target: resolved.target || ".",
|
|
234
|
+
automaticTaskId: !resolved.taskId,
|
|
246
235
|
presetArgs: parsed.presetArgs,
|
|
247
236
|
};
|
|
248
237
|
}
|
|
@@ -275,9 +264,9 @@ function presetDiscoveryTargetCandidates(values) {
|
|
|
275
264
|
return candidates;
|
|
276
265
|
}
|
|
277
266
|
|
|
278
|
-
function
|
|
267
|
+
function splitPresetArgsAndPositionals(values, presetPackage) {
|
|
279
268
|
const presetArgs = [];
|
|
280
|
-
const
|
|
269
|
+
const positionals = [];
|
|
281
270
|
const declaredFlags = new Map(Object.values(presetPackage?.inputs || {}).filter((input) => input.flag).map((input) => [input.flag, input]));
|
|
282
271
|
for (let index = 0; index < values.length; index += 1) {
|
|
283
272
|
const value = values[index];
|
|
@@ -295,18 +284,30 @@ function splitPresetArgsAndTarget(values, presetPackage) {
|
|
|
295
284
|
index += 1;
|
|
296
285
|
}
|
|
297
286
|
} else {
|
|
298
|
-
|
|
287
|
+
positionals.push(value);
|
|
299
288
|
}
|
|
300
289
|
}
|
|
301
|
-
if (targetCandidates.length > 1) {
|
|
302
|
-
throw new Error(`Too many positional arguments for new-task: ${targetCandidates.join(", ")}`);
|
|
303
|
-
}
|
|
304
290
|
return {
|
|
305
|
-
|
|
291
|
+
positionals,
|
|
306
292
|
presetArgs,
|
|
307
293
|
};
|
|
308
294
|
}
|
|
309
295
|
|
|
296
|
+
function isPathLikePositional(value) {
|
|
297
|
+
return value === "." || value === ".." || value.startsWith("/") || value.startsWith("~/") || value.includes("/") || value.includes("\\");
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function resolveNewTaskPositionals(positionals) {
|
|
301
|
+
if (positionals.length === 0) return { taskId: "", target: "" };
|
|
302
|
+
if (positionals.length === 1) {
|
|
303
|
+
const [value] = positionals;
|
|
304
|
+
if (isPathLikePositional(value)) return { taskId: "", target: value };
|
|
305
|
+
return { taskId: value, target: "" };
|
|
306
|
+
}
|
|
307
|
+
if (positionals.length === 2) return { taskId: positionals[0], target: positionals[1] };
|
|
308
|
+
throw new Error(`Too many positional arguments for new-task: ${positionals.join(", ")}`);
|
|
309
|
+
}
|
|
310
|
+
|
|
310
311
|
function formatTaskCommandError(error) {
|
|
311
312
|
const lines = [error.message];
|
|
312
313
|
if (Array.isArray(error.recovery) && error.recovery.length > 0) {
|
package/scripts/harness.mjs
CHANGED
|
@@ -87,16 +87,17 @@ Usage:
|
|
|
87
87
|
harness init [--dry-run] [--locale zh-CN|en-US] [--capabilities core,dashboard] [--add-npm-scripts] [target]
|
|
88
88
|
harness add-capability <name> [--dry-run] [--locale zh-CN|en-US] [target]
|
|
89
89
|
harness migrate-plan [--json] [--limit n] [target]
|
|
90
|
+
harness migrate-task-audit-index [--plan] [--apply] [--json] [target]
|
|
90
91
|
harness migrate-run [--locale zh-CN|en-US] [--assume-locale] [--allow-dirty] [--plan-only] [--out-dir folder] [--session-dir folder] [target]
|
|
91
92
|
harness migrate-verify [--json] [--full-cutover] <session.json>
|
|
92
93
|
harness governance rebuild [--dry-run] [--archive] [--apply] [target]
|
|
93
94
|
harness preset list [--json] [target]
|
|
94
95
|
harness preset inspect <id> [--json] [target]
|
|
95
96
|
harness preset check <id> [--json] [target]
|
|
96
|
-
harness preset install <
|
|
97
|
+
harness preset install <folder|zip|builtin-id> [--project] [--force] [--json] [target]
|
|
97
98
|
harness preset seed [--project] [--force] [--dry-run] [--json] [target]
|
|
98
99
|
harness preset uninstall <id> [--project] [--json] [target]
|
|
99
|
-
harness new-task
|
|
100
|
+
harness new-task [task-id] [--module key] [--budget simple|standard|complex] [--preset id] [--from-session session.json] [--long-running] [--title title] [--locale zh-CN|en-US] [--dry-run] [target]
|
|
100
101
|
harness task-start <task-id> [--message text] [target]
|
|
101
102
|
harness task-phase <task-id> <phase-id> [--state done] [--completion 100] [--evidence present] [target]
|
|
102
103
|
harness task-log <task-id> --message text [--evidence type:PATH:summary] [target]
|
|
@@ -127,6 +128,9 @@ Preset discovery:
|
|
|
127
128
|
"harness init" seeds bundled presets into the target project. "harness
|
|
128
129
|
install-user" and npm postinstall seed bundled presets into the user root.
|
|
129
130
|
Use "harness preset seed" to repair or re-run preset seeding.
|
|
131
|
+
Use "harness preset install" with a local preset folder, .zip archive, or
|
|
132
|
+
bundled preset id. Preset archives must contain preset.yaml at the archive
|
|
133
|
+
root or inside one top-level folder.
|
|
130
134
|
Use "harness preset list --json" to see available presets, their source,
|
|
131
135
|
purpose, compatible budgets, and manifest path. Use "harness preset inspect
|
|
132
136
|
<id> --json" for the full preset manifest summary.
|
|
@@ -224,7 +228,7 @@ if (command === "help" || command === "--help" || command === "-h") {
|
|
|
224
228
|
console.error(error.message);
|
|
225
229
|
process.exit(1);
|
|
226
230
|
}
|
|
227
|
-
} else if (["migrate-plan", "migrate-run", "migrate-verify"].includes(command)) {
|
|
231
|
+
} else if (["migrate-plan", "migrate-run", "migrate-verify", "migrate-task-audit-index"].includes(command)) {
|
|
228
232
|
runMigrationCommand(command, { args, takeFlag, takeOption, targetArg });
|
|
229
233
|
} else if (command === "governance") {
|
|
230
234
|
const subcommand = args.shift() || "";
|