harnessed 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -123
- package/dist/cli.mjs +50 -23
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# harnessed
|
|
2
2
|
|
|
3
3
|
> AI coding harness 包管理器 + composition orchestrator
|
|
4
|
-
>
|
|
4
|
+
> 把三层栈协作方法论 (gstack 决策 + GSD 项目经理 + superpowers 资深工程师 + karpathy 心法 + mattpocock 招式) 机器化为可执行 engine
|
|
5
5
|
|
|
6
6
|
[](https://npmjs.com/package/harnessed)
|
|
7
7
|
[](./LICENSE)
|
|
@@ -17,46 +17,72 @@
|
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
## 🎯 关键差异化
|
|
20
|
+
## 🎯 关键差异化
|
|
21
21
|
|
|
22
22
|
- **三层栈机器化** — `gstack 决策` + `GSD 项目经理` + `superpowers 资深工程师` + `karpathy 4 心法` + `mattpocock 23 招式`,5 支柱 100% capture
|
|
23
23
|
- **不 vendor 上游** — manifest describe install/check;上游升级用户 re-install 即获最新版
|
|
24
|
-
- **Composition Skill
|
|
25
|
-
- **L0 Discipline Substrate
|
|
24
|
+
- **Composition Skill** — 自家 workflow skill 当指挥棒,调度多个上游协同。**4 master orchestrator + 18 sub-workflow + 2 standalone = 24 namespace-layered workflow**,完整 4-stage 机器化 (`/discuss /plan /task /verify` 4 master + 三层栈 18 sub + `/research /retro` 2 standalone)
|
|
25
|
+
- **L0 Discipline Substrate** — 全局 cross-stage 行为基准 (karpathy 心法 + output-style + language + operational + priority + protocols),applied universally
|
|
26
26
|
- **包管理器思维** — install dependency graph 自动解析, doctor 健康检查, install-base 一键装齐
|
|
27
27
|
- **统一入口** — 用户面对 `/discuss /plan /task /verify` 等 master slash command,不需学每家上游术语;sub command 显式调用单 stage (例如 `/discuss-strategic` 只跑战略层澄清)
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
31
|
-
##
|
|
31
|
+
## 📦 快速安装
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
```bash
|
|
34
|
+
npm install -g harnessed && harnessed setup
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
## 📐 4-stage 流程图
|
|
36
40
|
|
|
37
41
|
```mermaid
|
|
38
|
-
graph
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
graph TD
|
|
43
|
+
RS([⓪ /research — 前置多源调研 可选]):::optional
|
|
44
|
+
subgraph Discuss[① Discuss 战略澄清]
|
|
41
45
|
DM[/discuss master/]
|
|
46
|
+
DS[discuss-strategic]
|
|
47
|
+
DP[discuss-phase]
|
|
48
|
+
DT[discuss-subtask]
|
|
49
|
+
DM --> DS & DP & DT
|
|
42
50
|
end
|
|
43
|
-
subgraph Plan[Plan 任务规划]
|
|
44
|
-
PA[plan-architecture] & PP[plan-phase]
|
|
51
|
+
subgraph Plan[② Plan 任务规划]
|
|
45
52
|
PM[/plan master/]
|
|
53
|
+
PA[plan-architecture]
|
|
54
|
+
PP[plan-phase]
|
|
55
|
+
PM --> PA & PP
|
|
46
56
|
end
|
|
47
|
-
subgraph Task[Task 执行]
|
|
48
|
-
TC[task-clarify] & TCo[task-code] & TT[task-test] & TD[task-deliver]
|
|
57
|
+
subgraph Task[③ Task 执行]
|
|
49
58
|
TM[/task master/]
|
|
59
|
+
TC[task-clarify]
|
|
60
|
+
TCo[task-code]
|
|
61
|
+
TT[task-test]
|
|
62
|
+
TD[task-deliver]
|
|
63
|
+
TM --> TC --> TCo --> TT --> TD
|
|
50
64
|
end
|
|
51
|
-
subgraph Verify[Verify 验证]
|
|
52
|
-
VP[verify-progress] & VC[verify-code-review] & VPa[verify-paranoid]
|
|
53
|
-
VQ[verify-qa] & VS[verify-security] & VD[verify-design]
|
|
54
|
-
VSi[verify-simplify] & VM[verify-multispec]
|
|
65
|
+
subgraph Verify[④ Verify 验证]
|
|
55
66
|
VMs[/verify master/]
|
|
67
|
+
VP[verify-progress]
|
|
68
|
+
VC[verify-code-review]
|
|
69
|
+
VPa[verify-paranoid]
|
|
70
|
+
VQ[verify-qa]
|
|
71
|
+
VS[verify-security]
|
|
72
|
+
VD[verify-design]
|
|
73
|
+
VSi[verify-simplify]
|
|
74
|
+
VM[verify-multispec]
|
|
75
|
+
VMs --> VP & VC & VPa & VQ & VS & VD & VSi & VM
|
|
56
76
|
end
|
|
77
|
+
RT([⑤ /retro — 里程碑总结 可选]):::optional
|
|
78
|
+
RS --> Discuss
|
|
57
79
|
Discuss --> Plan --> Task --> Verify
|
|
80
|
+
Verify --> RT
|
|
81
|
+
classDef optional stroke-dasharray:5 5,fill:#f5f5f5,color:#666
|
|
58
82
|
```
|
|
59
83
|
|
|
84
|
+
> 虚框 = 可选 standalone (`/research` 战略前调研 / `/retro` 里程碑后总结);实框 = 主流程 4-stage cadence。
|
|
85
|
+
|
|
60
86
|
### 24 workflow 总览表
|
|
61
87
|
|
|
62
88
|
| Slash cmd | Stage | Type | Capability / Upstream | Brief |
|
|
@@ -73,7 +99,7 @@ graph LR
|
|
|
73
99
|
| `/task-code` | ③ Task | Sub | karpathy 4 心法 + `/zoom-out` / `/improve-codebase-architecture` / `/diagnose` conditional | 子任务编码 + 跨 session progress.md 同步 |
|
|
74
100
|
| `/task-test` | ③ Task | Sub | superpowers TDD red-green-refactor + `/diagnose` conditional | 核心逻辑 TDD 强制 (alias mattpocock `/tdd`) |
|
|
75
101
|
| `/task-deliver` | ③ Task | Sub | `ralph-loop` SDK wrapper + Agent Teams conditional | 至 verbatim `COMPLETE` + R20.10 max_iter fallback |
|
|
76
|
-
| `/verify` | ④ Verify | Master | masterOrchestrator | 7 sub
|
|
102
|
+
| `/verify` | ④ Verify | Master | masterOrchestrator | 7 sub 按场景 conditional dispatch |
|
|
77
103
|
| `/verify-progress` | ④ Verify | Sub | GSD `/gsd-verify-work` + `/gsd-progress` | 必跑串行起点 — UAT 验收 + 状态同步 |
|
|
78
104
|
| `/verify-code-review` | ④ Verify | Sub | `code-review` 多 subagent fan-out | 高置信度 finding 并行 |
|
|
79
105
|
| `/verify-paranoid` | ④ Verify | Sub | gstack `/review` (Paranoid Staff Engineer) | 关键模块 PR 前强制 |
|
|
@@ -90,49 +116,6 @@ graph LR
|
|
|
90
116
|
|
|
91
117
|
---
|
|
92
118
|
|
|
93
|
-
## 🔄 Migrating from v2.0 to v3.0
|
|
94
|
-
|
|
95
|
-
v3.0 是 **breaking refactor**。v2.0 的 3 个 monolithic slash cmd 全部 DROP,改用 v3 namespace-layered 等价物:
|
|
96
|
-
|
|
97
|
-
| v2.0 (DROPPED) | v3.0 (NEW) |
|
|
98
|
-
|----------------|------------|
|
|
99
|
-
| `/plan-feature` | `/plan` (master, 自动 gate-route) OR `/plan-phase` (直接 sub) |
|
|
100
|
-
| `/execute-task` | `/task` (master, 串行 4 sub) OR `/task-{clarify,code,test,deliver}` (单 stage) |
|
|
101
|
-
| `/verify-work` | `/verify` (master, 7 sub conditional) OR `/verify-{progress,code-review,paranoid,qa,security,design,simplify,multispec}` (单维度) |
|
|
102
|
-
|
|
103
|
-
`/research` (v2.0 NEW) 不变,schema bump v2 → v3 但 phases verbatim 保留。
|
|
104
|
-
|
|
105
|
-
### 升级步骤
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
# 1. 升级 npm package
|
|
109
|
-
npm install -g harnessed@3
|
|
110
|
-
|
|
111
|
-
# 2. 重新 setup — v3 把 24 个 workflow skill 装到 ~/.claude/skills/
|
|
112
|
-
harnessed setup --apply
|
|
113
|
-
|
|
114
|
-
# 3. (可选) 手动清理 v2 残留 skill dir (per K12 mitigation)
|
|
115
|
-
rm -rf ~/.claude/skills/plan-feature ~/.claude/skills/execute-task ~/.claude/skills/verify-work
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
> v2.0 SHIPPED & ARCHIVED 2026-05-19 (17/20 phases 85%);v3.0 v1.0-RC2 minor STARTING;v1.0 GA target 2026-05-22~23 — 详 [.planning/STATE.md](./.planning/STATE.md)。
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## 📦 快速安装
|
|
123
|
-
|
|
124
|
-
```bash
|
|
125
|
-
npm install -g harnessed
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
或不全局安装 (ephemeral 模式):
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
npx harnessed@latest <command>
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
---
|
|
135
|
-
|
|
136
119
|
## 🚩 命令一览
|
|
137
120
|
|
|
138
121
|
### 主命令
|
|
@@ -152,21 +135,24 @@ npx harnessed@latest <command>
|
|
|
152
135
|
|
|
153
136
|
### 参数 (Flags)
|
|
154
137
|
|
|
138
|
+
> 所有命令默认 **apply (immediate write)**,无需加 flag。高级用户可加 `--dry-run` 预览。
|
|
139
|
+
|
|
155
140
|
| Flag | 说明 |
|
|
156
141
|
| ---- | ---- |
|
|
157
|
-
| `--
|
|
158
|
-
| `--
|
|
159
|
-
| `--non-interactive` | CI / 脚本场景;必须配合 `--apply` 或 `--dry-run` |
|
|
142
|
+
| `--dry-run` | 预览不写盘 (高级用户 opt-in) |
|
|
143
|
+
| `--non-interactive` | CI / 脚本场景 |
|
|
160
144
|
| `--system` | L4 全局装允许 (否则降级 L1 npx ephemeral) |
|
|
161
145
|
| `--yes` | uninstall 跳过交互 confirm |
|
|
162
146
|
| `--full-diff` | 展开 > 200 行的 diff 折叠 |
|
|
163
147
|
| `--no-color` | 强制 nocolor (即使 TTY) |
|
|
164
148
|
|
|
149
|
+
> `--apply` flag 仍保留为向后兼容 alias (no-op, 旧脚本不破)。
|
|
150
|
+
|
|
165
151
|
---
|
|
166
152
|
|
|
167
153
|
## ⚡ 使用流程
|
|
168
154
|
|
|
169
|
-
|
|
155
|
+
4-stage 三层栈方法论 — 推荐 4 个 master orchestrator 串行驱动:
|
|
170
156
|
|
|
171
157
|
```
|
|
172
158
|
/discuss → /plan → /task → /verify
|
|
@@ -184,7 +170,7 @@ v3.0 4-stage 三层栈方法论 — 推荐 4 个 master orchestrator 串行驱
|
|
|
184
170
|
|
|
185
171
|
```bash
|
|
186
172
|
# 1. 装 workflow 上游 (一行装齐 gstack + GSD + superpowers + planning-with-files)
|
|
187
|
-
harnessed setup
|
|
173
|
+
harnessed setup
|
|
188
174
|
|
|
189
175
|
# 2. 在 Claude Code 内跑 4-stage cadence
|
|
190
176
|
/discuss "新功能 X" # 战略 + Phase + 子任务 3 层澄清
|
|
@@ -202,7 +188,7 @@ harnessed resume
|
|
|
202
188
|
|
|
203
189
|
---
|
|
204
190
|
|
|
205
|
-
## 🗂️ 架构 (
|
|
191
|
+
## 🗂️ 架构 (4-stage namespace-layered)
|
|
206
192
|
|
|
207
193
|
### 1. 目录结构
|
|
208
194
|
|
|
@@ -229,11 +215,11 @@ harnessed/
|
|
|
229
215
|
│ │ ├── parallelism-gate.yaml # L5b execution mechanism routing
|
|
230
216
|
│ │ ├── tdd-gate.yaml
|
|
231
217
|
│ │ ├── fallback.yaml # 3 铁律: skip_with_transparency + override + chain_isolation
|
|
232
|
-
│ │ ├── web-design-routing.yaml #
|
|
233
|
-
│ │ ├── web-testing-routing.yaml #
|
|
234
|
-
│ │ ├── web-search-routing.yaml #
|
|
218
|
+
│ │ ├── web-design-routing.yaml # UI 设计工具路由
|
|
219
|
+
│ │ ├── web-testing-routing.yaml # E2E / 浏览器测试工具路由
|
|
220
|
+
│ │ ├── web-search-routing.yaml # 网页搜索 / 文档抓取路由
|
|
235
221
|
│ │ └── stage-routing.yaml # master orchestrator sub-stage 路由
|
|
236
|
-
│ └── disciplines/ # L0:
|
|
222
|
+
│ └── disciplines/ # L0: 全局 cross-stage 行为基准
|
|
237
223
|
│ ├── karpathy.yaml # 4 心法 + ≤200L
|
|
238
224
|
│ ├── output-style.yaml # BLUF + no-emoji + no-em-dash
|
|
239
225
|
│ ├── language.yaml # zh-Hans default + English preserve
|
|
@@ -246,7 +232,7 @@ harnessed/
|
|
|
246
232
|
├── tests/ # vitest unit + integration + dogfood (R8.1 dogfood-first)
|
|
247
233
|
├── scripts/ # CI gate (check-workflow-schema, transparency-verdict, state-archive)
|
|
248
234
|
├── .planning/ # project memory (STATE + ROADMAP + REQUIREMENTS + per-phase + milestones)
|
|
249
|
-
└── docs/adr/ # 架构决策记录
|
|
235
|
+
└── docs/adr/ # 架构决策记录
|
|
250
236
|
```
|
|
251
237
|
|
|
252
238
|
### 2. 逻辑分层 (8 层)
|
|
@@ -276,21 +262,21 @@ harnessed/
|
|
|
276
262
|
├────────────────────────────────────────────────────────────┤
|
|
277
263
|
│ L1 Upstream components (NOT vendored) │
|
|
278
264
|
├────────────────────────────────────────────────────────────┤
|
|
279
|
-
│ L0 Discipline Substrate (
|
|
265
|
+
│ L0 Discipline Substrate (全局生效) │
|
|
280
266
|
│ karpathy 心法 + output-style + language + operational + │
|
|
281
267
|
│ priority + protocols (applied universally to L1-L7) │
|
|
282
268
|
└────────────────────────────────────────────────────────────┘
|
|
283
269
|
```
|
|
284
270
|
|
|
285
|
-
### 3. Cross-cutting Capabilities (capabilities.yaml 7 category, ~
|
|
271
|
+
### 3. Cross-cutting Capabilities (capabilities.yaml 7 category, ~83 entry)
|
|
286
272
|
|
|
287
273
|
```
|
|
288
|
-
behavioral (
|
|
289
|
-
tool-slash-cmd (
|
|
290
|
-
tool-mcp (
|
|
291
|
-
tool-cli (
|
|
274
|
+
behavioral (6): karpathy-guidelines + output-style + language + operational + priority + protocols
|
|
275
|
+
tool-slash-cmd (~60): gstack 30+ optional + gsd 10+ + mattpocock 12 高频 + 等
|
|
276
|
+
tool-mcp (3): chrome-devtools-mcp / tavily-mcp / exa-mcp
|
|
277
|
+
tool-cli (2): ctx7 / gws
|
|
292
278
|
tool-plugin (2): planning-with-files / @playwright/test
|
|
293
|
-
tool-bundled (
|
|
279
|
+
tool-bundled (3): ralph-loop / webapp-testing / playwright-cli
|
|
294
280
|
agent-platform (3): agent-teams-create / send-message / shutdown
|
|
295
281
|
```
|
|
296
282
|
|
|
@@ -324,35 +310,25 @@ planning-with-files /plan (cross-cutting tool) → write artifacts to .planning/
|
|
|
324
310
|
|
|
325
311
|
### 5. 抉择路由矩阵 (rules-based, codified in judgments + capabilities)
|
|
326
312
|
|
|
327
|
-
| 场景 |
|
|
328
|
-
|
|
329
|
-
| 并行机制 |
|
|
330
|
-
| UI 设计主方案 |
|
|
331
|
-
| E2E 浏览器探查 |
|
|
332
|
-
| E2E commit-able TS |
|
|
333
|
-
| E2E Python 后端联动 |
|
|
334
|
-
|
|
|
335
|
-
| Web 搜索 (关键词) |
|
|
336
|
-
| Web 搜索 (
|
|
337
|
-
| 库 API 文档 |
|
|
338
|
-
| GitHub URL |
|
|
339
|
-
| 单 URL 抓取 |
|
|
340
|
-
| Gmail/Drive/Calendar |
|
|
341
|
-
| 架构审查 (复杂) |
|
|
342
|
-
| TDD 强制 (核心算法) |
|
|
343
|
-
| 关键模块 PR |
|
|
344
|
-
| 大重构 PR
|
|
345
|
-
| 跨
|
|
346
|
-
|
|
347
|
-
### v3.0 superset commitment
|
|
348
|
-
|
|
349
|
-
harnessed v3.0 是 user 个人 `~/.claude/CLAUDE.md` + Obsidian doc + `~/.claude/rules/` 的 **machine-codified superset**:
|
|
350
|
-
- ✅ 4-stage cadence verbatim 机器化 (20 workflows)
|
|
351
|
-
- ✅ 三层栈判据 + fallback 3 铁律 (judgments/ 10 file)
|
|
352
|
-
- ✅ Pattern A/B/C Agent Teams routing (L5b mechanism)
|
|
353
|
-
- ✅ Rules-based tool routing (4 NEW judgments + capabilities)
|
|
354
|
-
- ✅ Global discipline (L0 substrate, 6 yaml)
|
|
355
|
-
- ✅ harnessed > user manual via: auto gate-route + Pure bundled + cross-session memory + ADR audit + Token cost estimation + real-time discipline enforcement
|
|
313
|
+
| 场景 | Default → Escalate |
|
|
314
|
+
|------|---------------------|
|
|
315
|
+
| 并行机制 | subagent → Agent Teams Pattern A/B/C (5 触发) |
|
|
316
|
+
| UI 设计主方案 | ui-ux-pro-max → frontend-design (用户明示风格) |
|
|
317
|
+
| E2E 浏览器探查 | playwright-cli (Bash 一行 token 省) |
|
|
318
|
+
| E2E commit-able TS | @playwright/test 默认 |
|
|
319
|
+
| E2E Python 后端联动 | webapp-testing |
|
|
320
|
+
| 性能 / a11y / 内存诊断 | chrome-devtools-mcp |
|
|
321
|
+
| Web 搜索 (关键词) | Tavily MCP 默认 |
|
|
322
|
+
| Web 搜索 (描述式 / 学术) | Exa MCP |
|
|
323
|
+
| 库 API 文档 | ctx7 CLI |
|
|
324
|
+
| GitHub URL | gh CLI |
|
|
325
|
+
| 单 URL 抓取 | WebFetch 内置 |
|
|
326
|
+
| Gmail / Drive / Calendar | gws CLI |
|
|
327
|
+
| 架构审查 (复杂) | gstack /plan-eng-review |
|
|
328
|
+
| TDD 强制 (核心算法) | superpowers TDD OR mattpocock /tdd |
|
|
329
|
+
| 关键模块 PR | gstack /review |
|
|
330
|
+
| 大重构 PR 多维度审查 | 4-specialist Agent Team Pattern C |
|
|
331
|
+
| 跨 session hand-off | discipline.protocols self-contained design doc |
|
|
356
332
|
|
|
357
333
|
---
|
|
358
334
|
|
|
@@ -401,7 +377,7 @@ harnessed setup --apply # 自动装齐 gstack + GSD + superpowers + planning-wi
|
|
|
401
377
|
| Orchestration | GSD | 高层 phase 任务图 + 依赖分析 |
|
|
402
378
|
| Persistence | planning-with-files | 持久化 `task_plan.md` / `progress.md` / `findings.md` |
|
|
403
379
|
|
|
404
|
-
|
|
380
|
+
`/discuss /plan /task /verify` 4 个 master 把 4 阶段串起来,每个 master 内部再 delegate 到对应 sub。每个阶段做不同事,输出喂给下一阶段。**没有合并**。
|
|
405
381
|
|
|
406
382
|
</details>
|
|
407
383
|
|
|
@@ -428,25 +404,13 @@ v3.0 `/discuss /plan /task /verify` 4 个 master 把 4 阶段串起来,每个 ma
|
|
|
428
404
|
|
|
429
405
|
- `npx harnessed@latest setup` 跑的是 **Node.js CLI** (`bin/harnessed`)
|
|
430
406
|
- setup 装的 **workflow skills** (markdown) 进 `~/.claude/skills/`,由 Claude Code 运行时加载
|
|
431
|
-
- `/discuss` / `/plan` / `/task` / `/verify`
|
|
407
|
+
- `/discuss` / `/plan` / `/task` / `/verify` 等是 CC 内的 slash command,触发 skill 执行
|
|
432
408
|
- CLI 和 CC skill 共享 `.harnessed/checkpoints/` 状态目录
|
|
433
409
|
|
|
434
410
|
</details>
|
|
435
411
|
|
|
436
412
|
---
|
|
437
413
|
|
|
438
|
-
## 📚 文档导航
|
|
439
|
-
|
|
440
|
-
- [docs/WORKFLOW.md](./docs/WORKFLOW.md) — 4-stage workflow mermaid + 各 stage 详解
|
|
441
|
-
- [docs/INSTALLER-CONTRACT.md](./docs/INSTALLER-CONTRACT.md) — installer 6 条用户视角硬契约
|
|
442
|
-
- [docs/MAINTAINER-ONBOARDING.md](./docs/MAINTAINER-ONBOARDING.md) — 30 分钟跑通 dev 环境
|
|
443
|
-
- [docs/adr/](./docs/adr/) — 架构决策记录 (ADR 0001-0023)
|
|
444
|
-
- [CHANGELOG.md](./CHANGELOG.md) — 完整版本历史
|
|
445
|
-
- [CONTRIBUTING.md](./CONTRIBUTING.md) — 贡献指南
|
|
446
|
-
- [SECURITY.md](./SECURITY.md) — 漏洞披露通道
|
|
447
|
-
|
|
448
|
-
---
|
|
449
|
-
|
|
450
414
|
## License
|
|
451
415
|
|
|
452
416
|
[Apache-2.0](./LICENSE) — 见 [NOTICE](./NOTICE) (含 Harness Inc. 商标 disclaimer)
|
package/dist/cli.mjs
CHANGED
|
@@ -793,7 +793,7 @@ var init_resume = __esm({
|
|
|
793
793
|
|
|
794
794
|
// package.json
|
|
795
795
|
var package_default = {
|
|
796
|
-
version: "3.0.
|
|
796
|
+
version: "3.0.1"};
|
|
797
797
|
|
|
798
798
|
// src/manifest/errors.ts
|
|
799
799
|
function instancePathToKeyPath(instancePath) {
|
|
@@ -2940,7 +2940,12 @@ function validateNonInteractiveFlags(raw, cmdName) {
|
|
|
2940
2940
|
|
|
2941
2941
|
// src/cli/execute-task.ts
|
|
2942
2942
|
function registerExecuteTask(program2) {
|
|
2943
|
-
program2.command("execute-task").description(
|
|
2943
|
+
program2.command("execute-task").description(
|
|
2944
|
+
"Run execute-task workflow (4-phase chain \u2192 ralph-loop COMPLETE; immediate by default \u2014 use --dry-run for preview)"
|
|
2945
|
+
).requiredOption("--task <text>", "task description (required)").option("--workflow <name>", "workflow name", "execute-task").option(
|
|
2946
|
+
"--apply",
|
|
2947
|
+
"(deprecated; kept for backward compat \u2014 execute-task spawns immediately by default)"
|
|
2948
|
+
).option("--dry-run", "preview only \u2014 do not spawn subagent (opt-in for advanced users)").option("--non-interactive", "CI / scripts \u2014 requires --apply or --dry-run").option("--model <model>", "subagent model: 'haiku' | 'sonnet' | 'opus'").option("--model-tier <tier>", "override: 'inherit' bypasses per-phase phase.model (B-10)").option("--max-iterations <n>", "ralph-loop max iter (default 20)", (v) => parseInt(v, 10)).action(async (raw) => {
|
|
2944
2949
|
validateNonInteractiveFlags(raw, "execute-task --task <text>");
|
|
2945
2950
|
if (!raw.task) {
|
|
2946
2951
|
console.error("error: --task <text> is required");
|
|
@@ -2963,7 +2968,7 @@ function registerExecuteTask(program2) {
|
|
|
2963
2968
|
};
|
|
2964
2969
|
}
|
|
2965
2970
|
const taskCtx = { task: raw.task, task_type: "execute-task" };
|
|
2966
|
-
const isDryRun = raw.dryRun === true
|
|
2971
|
+
const isDryRun = raw.dryRun === true;
|
|
2967
2972
|
if (isDryRun) {
|
|
2968
2973
|
console.log(
|
|
2969
2974
|
JSON.stringify({ workflow: phases.workflow, phases: phases.phases, taskCtx }, null, 2)
|
|
@@ -3041,8 +3046,10 @@ async function dirSizeKb(dir) {
|
|
|
3041
3046
|
return Math.round(total / 1024);
|
|
3042
3047
|
}
|
|
3043
3048
|
function registerGc(program2) {
|
|
3044
|
-
program2.command("gc").description(
|
|
3045
|
-
|
|
3049
|
+
program2.command("gc").description(
|
|
3050
|
+
"Garbage-collect old backup snapshots (immediate by default \u2014 use --dry-run for preview)"
|
|
3051
|
+
).option("--older-than <duration>", "delete snapshots older than (e.g. 30d / 24h / 4w)", "30d").option("--keep-last <N>", "always keep the most recent N snapshots", "0").option("--apply", "(deprecated; kept for backward compat \u2014 gc deletes immediately by default)").option("--dry-run", "preview only \u2014 do not delete (opt-in for advanced users)").action(async (opts) => {
|
|
3052
|
+
const dryRun = opts.dryRun === true;
|
|
3046
3053
|
const olderMs = parseDuration(opts.olderThan ?? "30d");
|
|
3047
3054
|
if (olderMs == null) {
|
|
3048
3055
|
console.error(
|
|
@@ -3092,7 +3099,7 @@ function registerGc(program2) {
|
|
|
3092
3099
|
console.log(` ${c.ts} ${c.manifest} (${c.sizeKb} KB)`);
|
|
3093
3100
|
if (!dryRun) await rm(c.path, { recursive: true, force: true });
|
|
3094
3101
|
}
|
|
3095
|
-
if (dryRun) console.log("\n(dry-run \u2014 re-run
|
|
3102
|
+
if (dryRun) console.log("\n(dry-run \u2014 re-run without --dry-run to actually delete)");
|
|
3096
3103
|
});
|
|
3097
3104
|
}
|
|
3098
3105
|
async function confirmAt(level, ctx) {
|
|
@@ -4465,7 +4472,7 @@ function formatError(e) {
|
|
|
4465
4472
|
return `${head}${where}${tip}`;
|
|
4466
4473
|
}
|
|
4467
4474
|
function registerInstall(program2) {
|
|
4468
|
-
program2.command("install <name>").description("Install an upstream (
|
|
4475
|
+
program2.command("install <name>").description("Install an upstream (immediate by default \u2014 use --dry-run for preview)").option("--apply", "(deprecated; kept for backward compat \u2014 install is immediate by default)").option("--dry-run", "preview only \u2014 do not write to disk (opt-in for advanced users)").option("--system", "allow L4 system-wide install (e.g. global npm install)").option("--non-interactive", "skip all prompts (CI / scripts) \u2014 requires --apply or --dry-run").option("--full-diff", "expand diffs longer than 200 lines").option("--no-color", "disable ANSI colors (auto-detected when piped)").option(
|
|
4469
4476
|
"--known-good",
|
|
4470
4477
|
"use known-good version lock from versions/<harnessed-ver>-known-good.yaml"
|
|
4471
4478
|
).action(async (name, raw) => {
|
|
@@ -4497,9 +4504,10 @@ function registerInstall(program2) {
|
|
|
4497
4504
|
console.error(` fix: run 'harnessed audit' to inspect manifest issues`);
|
|
4498
4505
|
process.exit(1);
|
|
4499
4506
|
}
|
|
4507
|
+
const dryRun = raw.dryRun === true;
|
|
4500
4508
|
const opts = {
|
|
4501
|
-
apply:
|
|
4502
|
-
dryRun
|
|
4509
|
+
apply: !dryRun,
|
|
4510
|
+
dryRun,
|
|
4503
4511
|
system: raw.system === true,
|
|
4504
4512
|
nonInteractive: raw.nonInteractive === true,
|
|
4505
4513
|
fullDiff: raw.fullDiff === true,
|
|
@@ -4545,11 +4553,17 @@ async function listBaseManifests(cwd) {
|
|
|
4545
4553
|
return out;
|
|
4546
4554
|
}
|
|
4547
4555
|
function registerInstallBase(program2) {
|
|
4548
|
-
program2.command("install-base").description(
|
|
4556
|
+
program2.command("install-base").description(
|
|
4557
|
+
"Install the phase 1.3 base profile (immediate by default \u2014 use --dry-run for preview)"
|
|
4558
|
+
).option(
|
|
4559
|
+
"--apply",
|
|
4560
|
+
"(deprecated; kept for backward compat \u2014 install-base is immediate by default)"
|
|
4561
|
+
).option("--dry-run", "preview only \u2014 do not write to disk (opt-in for advanced users)").option("--non-interactive", "skip all prompts (CI / scripts) \u2014 requires --apply or --dry-run").action(async (raw) => {
|
|
4549
4562
|
validateNonInteractiveFlags(raw, "install-base");
|
|
4563
|
+
const dryRun = raw.dryRun === true;
|
|
4550
4564
|
const opts = {
|
|
4551
|
-
apply:
|
|
4552
|
-
dryRun
|
|
4565
|
+
apply: !dryRun,
|
|
4566
|
+
dryRun,
|
|
4553
4567
|
system: false,
|
|
4554
4568
|
nonInteractive: raw.nonInteractive === true,
|
|
4555
4569
|
fullDiff: false,
|
|
@@ -4609,7 +4623,12 @@ function basename(upstream) {
|
|
|
4609
4623
|
return (upstream.split("/").pop() ?? upstream).replace(/\.git$/, "");
|
|
4610
4624
|
}
|
|
4611
4625
|
function registerManifestAdd(program2) {
|
|
4612
|
-
program2.command("manifest-add <upstream>").description(
|
|
4626
|
+
program2.command("manifest-add <upstream>").description(
|
|
4627
|
+
"Add a new upstream adapter (EE-5 5-question merge gate; immediate by default \u2014 use --dry-run for preview)"
|
|
4628
|
+
).option("--category <cat>", "manifest category (skill-packs | tools)", "skill-packs").option("--name <name>", "short adapter name (defaults to <upstream> basename)").option(
|
|
4629
|
+
"--apply",
|
|
4630
|
+
"(deprecated; kept for backward compat \u2014 manifest-add persists immediately by default)"
|
|
4631
|
+
).option("--dry-run", "preview only \u2014 do not write JSON (opt-in for advanced users)").option("--non-interactive", "CI/scripts \u2014 requires --apply or --dry-run; WARN-only dry-run").action(async (upstream, raw) => {
|
|
4613
4632
|
validateNonInteractiveFlags(raw, "manifest-add <upstream>");
|
|
4614
4633
|
const name = raw.name ?? basename(upstream);
|
|
4615
4634
|
const category = raw.category ?? "skill-packs";
|
|
@@ -4638,7 +4657,8 @@ function registerManifestAdd(program2) {
|
|
|
4638
4657
|
payload[f] = a;
|
|
4639
4658
|
}
|
|
4640
4659
|
rl.close();
|
|
4641
|
-
|
|
4660
|
+
const dryRun = raw.dryRun === true;
|
|
4661
|
+
if (!dryRun) {
|
|
4642
4662
|
writeFileSync(outPath, `${JSON.stringify(payload, null, 2)}
|
|
4643
4663
|
`, "utf8");
|
|
4644
4664
|
console.log(`[manifest-add] EE-5 gate passed; wrote ${outPath}`);
|
|
@@ -4652,14 +4672,19 @@ function registerManifestAdd(program2) {
|
|
|
4652
4672
|
|
|
4653
4673
|
// src/cli/research.ts
|
|
4654
4674
|
function registerResearch(program2) {
|
|
4655
|
-
program2.command("research").description(
|
|
4675
|
+
program2.command("research").description(
|
|
4676
|
+
"Run research workflow (search category sub-routing \u2192 spawn \u2192 verbatim COMPLETE; immediate by default \u2014 use --dry-run for preview)"
|
|
4677
|
+
).requiredOption("--query <text>", "research prompt (required)").option(
|
|
4678
|
+
"--apply",
|
|
4679
|
+
"(deprecated; kept for backward compat \u2014 research spawns immediately by default)"
|
|
4680
|
+
).option("--dry-run", "preview only \u2014 do not spawn subagent (opt-in for advanced users)").option("--non-interactive", "skip all prompts (CI / scripts) \u2014 requires --apply or --dry-run").option("--model <model>", "subagent model: 'haiku' | 'sonnet' | 'opus'").action(async (raw) => {
|
|
4656
4681
|
validateNonInteractiveFlags(raw, "research --query <text>");
|
|
4657
4682
|
if (!raw.query) {
|
|
4658
4683
|
console.error("error: --query <text> is required");
|
|
4659
4684
|
process.exit(2);
|
|
4660
4685
|
}
|
|
4661
4686
|
const taskCtx = { task: raw.query, task_type: "search" };
|
|
4662
|
-
if (raw.dryRun === true
|
|
4687
|
+
if (raw.dryRun === true) {
|
|
4663
4688
|
const preview = await runRouting(taskCtx, {
|
|
4664
4689
|
skillsRoot: void 0,
|
|
4665
4690
|
// Stub spawn — dry-run never reaches it; explicit COMPLETE keeps shape happy.
|
|
@@ -4677,7 +4702,9 @@ function registerResearch(program2) {
|
|
|
4677
4702
|
}
|
|
4678
4703
|
console.log(`[dry-run] matched_rule: ${preview.matchedRule?.id ?? "(fallback supervisor)"}`);
|
|
4679
4704
|
console.log(`[dry-run] query: ${raw.query}`);
|
|
4680
|
-
console.log(
|
|
4705
|
+
console.log(
|
|
4706
|
+
" (run without --dry-run to spawn the subagent and emit verbatim COMPLETE round-trip)"
|
|
4707
|
+
);
|
|
4681
4708
|
process.exit(0);
|
|
4682
4709
|
}
|
|
4683
4710
|
const result = await runRouting(taskCtx, {
|
|
@@ -5320,12 +5347,12 @@ async function runUninstall(manifest, opts) {
|
|
|
5320
5347
|
|
|
5321
5348
|
// src/cli/uninstall.ts
|
|
5322
5349
|
function registerUninstall(program2) {
|
|
5323
|
-
program2.command("uninstall <name>").description("Uninstall an upstream (
|
|
5350
|
+
program2.command("uninstall <name>").description("Uninstall an upstream (immediate by default \u2014 use --dry-run for preview)").option("--apply", "(deprecated; kept for backward compat \u2014 uninstall is immediate by default)").option("--dry-run", "preview only \u2014 do not delete files (opt-in for advanced users)").option("--yes", "skip interactive confirm (CI / scripts) \u2014 fatal with --dry-run").option("--non-interactive", "alias for --yes (CI compat)").action(async (name, raw) => {
|
|
5324
5351
|
const yes = raw.yes === true || raw.nonInteractive === true;
|
|
5325
|
-
if (yes &&
|
|
5352
|
+
if (yes && raw.dryRun) {
|
|
5326
5353
|
console.error(
|
|
5327
|
-
`error: --yes
|
|
5328
|
-
fix: harnessed uninstall ${name} --yes --
|
|
5354
|
+
`error: --yes is incompatible with --dry-run (dry-run does not mutate)
|
|
5355
|
+
fix: harnessed uninstall ${name} --yes (immediate) OR harnessed uninstall ${name} --dry-run (preview)`
|
|
5329
5356
|
);
|
|
5330
5357
|
process.exit(2);
|
|
5331
5358
|
}
|
|
@@ -5356,10 +5383,10 @@ function registerUninstall(program2) {
|
|
|
5356
5383
|
process.exit(1);
|
|
5357
5384
|
}
|
|
5358
5385
|
const method = v.manifest.spec.install.method;
|
|
5359
|
-
const dryRun = raw.dryRun === true
|
|
5386
|
+
const dryRun = raw.dryRun === true;
|
|
5360
5387
|
if (dryRun) {
|
|
5361
5388
|
console.log(`[dry-run] would uninstall '${resolvedName}' via method '${method}'`);
|
|
5362
|
-
console.log(` run
|
|
5389
|
+
console.log(` run without --dry-run to execute`);
|
|
5363
5390
|
process.exit(2);
|
|
5364
5391
|
}
|
|
5365
5392
|
if (!yes) {
|