create-harness-vibe-coding 0.8.4 → 0.8.6
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 +20 -4
- package/package.json +1 -1
- package/templates/common/.claude/skills/wf-remove/SKILL.md +26 -13
- package/templates/common/.harness-version +8 -8
- package/templates/common/Harness/README.md +2 -2
- package/templates/common/SETUP.md +28 -21
- package/templates/common/scripts/validate-harness.mjs +3 -0
- package/templates/common/scripts/wf-remove.mjs +117 -54
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ npx create-harness-vibe-coding@latest my-project
|
|
|
18
18
|
|
|
19
19
|
## Your Agent Knows What to Do
|
|
20
20
|
|
|
21
|
-
Already have a project?
|
|
21
|
+
Already have a project? Paste this sentence. Your agent should use the script-first fast path: dry-run JSON first, read only files named in `agent.aiMergeRequired`, then run the structural validator.
|
|
22
22
|
|
|
23
23
|
```text
|
|
24
24
|
Read and follow https://github.com/zingspark/create-harness-vibe-coding exactly to configure this project with create-harness-vibe-coding.
|
|
@@ -41,7 +41,7 @@ Chinese README: [README-CN.md](README-CN.md)
|
|
|
41
41
|
| `subagent-orchestrator` | Runs parallel agents without collision |
|
|
42
42
|
| `memory-master` + `context-master` | Learns from failures, compresses when full |
|
|
43
43
|
| PRD + Research templates | Asks "what" and "why" before coding |
|
|
44
|
-
|
|
|
44
|
+
| 16 built-in agents | Research, plan, architecture, TDD, build, review, debug, verify, memory/context, WF-MAX managers |
|
|
45
45
|
| Architecture docs | Knows where boundaries live |
|
|
46
46
|
| Context-loading protocol | Loads only the docs each agent needs |
|
|
47
47
|
| `.claude/` + `.agents/skills/` | Claude Code and Codex skill adapters over the same Harness docs |
|
|
@@ -125,10 +125,15 @@ npx create-harness-vibe-coding@latest my-app . -y --dry-run --json
|
|
|
125
125
|
|
|
126
126
|
# Add only what's missing. Never overwrite.
|
|
127
127
|
npx create-harness-vibe-coding@latest my-app . -y --on-conflict skip --json
|
|
128
|
+
|
|
129
|
+
# Install-complete structural gate.
|
|
130
|
+
node Harness/scripts/validate-harness.mjs
|
|
128
131
|
```
|
|
129
132
|
|
|
130
133
|
The JSON output is the agent's install report: `scan` replaces hand-written root probes, `plan.create` is script-owned, and `agent.aiMergeRequired` is the only list that needs semantic AI review. Do not read package source or templates unless `agent.aiMergeRequired` names a conflicting file.
|
|
131
134
|
|
|
135
|
+
For existing projects, a passing non-strict validator is the install-complete gate. `--strict` is the bootstrap/release gate and may fail until PRD, research, and architecture placeholders have been resolved from real project facts.
|
|
136
|
+
|
|
132
137
|
`npx` is an install and safe-merge entry, not an update engine for an already installed Harness. Once `Harness/` exists, use `/wf-update` in Claude Code, `$wf-update` in Codex, or `node Harness/scripts/wf-update-check.mjs`; root entry conflicts such as `CLAUDE.md`, `AGENTS.md`, `.claude/`, `.agents/`, `.codex/`, and local Harness docs need agent-mediated merge decisions.
|
|
133
138
|
|
|
134
139
|
| Flag | Does |
|
|
@@ -182,6 +187,14 @@ npx create-harness-vibe-coding@latest my-app . -y --dry-run --json
|
|
|
182
187
|
|
|
183
188
|
Use `scan.markers` instead of manual top-level probes. Ask **at most 3 blocking questions** before touching files. Files in `plan.create` are handled by the script; only files in `agent.aiMergeRequired` need AI comparison and user-supervised merge decisions.
|
|
184
189
|
|
|
190
|
+
Fast path for an existing project with no installed `Harness/`:
|
|
191
|
+
|
|
192
|
+
1. Run the dry-run JSON command.
|
|
193
|
+
2. Run the JSON `agent.safeMergeCommand` to create only missing files.
|
|
194
|
+
3. Patch only files listed in `agent.aiMergeRequired`; preserve project-owned content.
|
|
195
|
+
4. Run `node Harness/scripts/validate-harness.mjs`.
|
|
196
|
+
5. Stop and report install status. Defer `--strict` until bootstrap fills project-fact placeholders.
|
|
197
|
+
|
|
185
198
|
Ask these only when they affect writes:
|
|
186
199
|
|
|
187
200
|
- If `CLAUDE.md` or `AGENTS.md` already exists, should missing Harness guidance be merged, kept separate, or skipped?
|
|
@@ -205,7 +218,10 @@ Harness docs always live in root `Harness/`; do not route Harness files through
|
|
|
205
218
|
# In this package repo
|
|
206
219
|
npm test
|
|
207
220
|
|
|
208
|
-
# In
|
|
221
|
+
# In an existing project immediately after safe-merge install
|
|
222
|
+
node Harness/scripts/validate-harness.mjs
|
|
223
|
+
|
|
224
|
+
# In a generated project after bootstrap, or before release
|
|
209
225
|
node Harness/scripts/validate-harness.mjs --strict
|
|
210
226
|
```
|
|
211
227
|
|
|
@@ -229,7 +245,7 @@ my-project/
|
|
|
229
245
|
│ ├── memory/ ← Durable self-learning
|
|
230
246
|
│ └── scripts/ ← Validator
|
|
231
247
|
├── .claude/
|
|
232
|
-
│ ├── agents/ ←
|
|
248
|
+
│ ├── agents/ ← 16 built-in agents
|
|
233
249
|
│ ├── skills/ ← Claude Code skill commands
|
|
234
250
|
│ └── rules/ ← Universal coding rules
|
|
235
251
|
├── .agents/
|
package/package.json
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: wf-remove
|
|
3
|
-
description: Use for /wf-remove in Claude Code, $wf-remove or /skills wf-remove in Codex, or any request to uninstall Harness safely.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# WF Remove Adapter
|
|
7
|
-
|
|
1
|
+
---
|
|
2
|
+
name: wf-remove
|
|
3
|
+
description: Use for /wf-remove in Claude Code, $wf-remove or /skills wf-remove in Codex, or any request to uninstall Harness safely.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# WF Remove Adapter
|
|
7
|
+
|
|
8
8
|
## Invocation
|
|
9
9
|
|
|
10
10
|
- Claude Code: use `/wf-remove` or select the `wf-remove` skill.
|
|
11
11
|
- Codex CLI or IDE: use `$wf-remove` or `/skills` then choose `wf-remove`.
|
|
12
|
+
- User-facing removal is the slash/skill command. The Node commands below are
|
|
13
|
+
agent-internal execution steps; do not ask the user to copy/paste them unless
|
|
14
|
+
the agent has no shell/tool access.
|
|
12
15
|
|
|
13
16
|
## Load
|
|
14
17
|
|
|
@@ -17,21 +20,31 @@ description: Use for /wf-remove in Claude Code, $wf-remove or /skills wf-remove
|
|
|
17
20
|
|
|
18
21
|
## Flow
|
|
19
22
|
|
|
20
|
-
1.
|
|
21
|
-
plan.
|
|
22
|
-
2. Auto-remove only SAFE files that still match stored checksums
|
|
23
|
+
1. On plain `/wf-remove`, run `node Harness/scripts/wf-remove.mjs --json` for
|
|
24
|
+
the machine-readable plan, then run the safe default apply command yourself.
|
|
25
|
+
2. Auto-remove only SAFE files that still match stored checksums or exact
|
|
26
|
+
built-in Harness discovery files recognized by the script.
|
|
23
27
|
3. Ask the user before every MODIFIED or uncertain file.
|
|
24
28
|
4. Preserve USER DATA by default. For an explicit thorough uninstall, use
|
|
25
29
|
`--purge-user-data` (alias `--purge`); add `--keep-tasks` when the user wants task records
|
|
26
30
|
retained while project-fact Harness docs are removed.
|
|
27
|
-
5. Run the script, not manual deletes:
|
|
31
|
+
5. Run the script yourself, not manual deletes and not user-side command copy:
|
|
28
32
|
- safe default: `node Harness/scripts/wf-remove.mjs --apply --yes`
|
|
29
33
|
- thorough but keep tasks: `node Harness/scripts/wf-remove.mjs --apply --yes --purge-user-data --keep-tasks`
|
|
30
34
|
- exact modified decisions: add `--delete-modified <path>` for each
|
|
31
35
|
user-approved MODIFIED file.
|
|
36
|
+
6. After apply, verify residual discovery folders:
|
|
37
|
+
- `.claude/agents`
|
|
38
|
+
- `.claude/skills`
|
|
39
|
+
- `.claude/commands`
|
|
40
|
+
- `.claude/rules`
|
|
41
|
+
- `.agents/skills`
|
|
42
|
+
- `.codex`
|
|
43
|
+
Built-in Harness files in these locations should be gone. Custom user skills
|
|
44
|
+
or user-owned files may remain and must be reported, not blindly deleted.
|
|
32
45
|
|
|
33
46
|
## Return
|
|
34
47
|
|
|
35
48
|
Report SAFE removals, MODIFIED keep/delete decisions, preserved USER DATA,
|
|
36
|
-
PURGE removals, directory cleanup,
|
|
37
|
-
status, and `git status` guidance.
|
|
49
|
+
PURGE removals, directory cleanup, `.claude` / `.agents` / `.codex` residual
|
|
50
|
+
status, `.harness-version` status, and `git status` guidance.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generator": "0.8.
|
|
3
|
-
"generated": "2026-07-
|
|
2
|
+
"generator": "0.8.6",
|
|
3
|
+
"generated": "2026-07-02T10:59:32.891Z",
|
|
4
4
|
"options": [],
|
|
5
5
|
"autoCheck": true,
|
|
6
6
|
"source": "https://raw.githubusercontent.com/zingspark/create-harness-vibe-coding/main/templates/common/",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
".agents/skills/wf-learn/SKILL.md": "sha256-7f3e1ee0aa83cbb76707698d0c26b703ad5c74b2df95a7dc4d751939a4ba05b2",
|
|
13
13
|
".agents/skills/wf-max/SKILL.md": "sha256-9b37cc3385f6d1a285b617169e91fbf71ffec76135b7b46ec1de2fe94ca220da",
|
|
14
14
|
".agents/skills/wf-readme/SKILL.md": "sha256-4d34ee3b6b305fa2581f5d8cb31e9152759f3df8bf8fa08efbb43782f128bdcd",
|
|
15
|
-
".agents/skills/wf-remove/SKILL.md": "sha256-
|
|
15
|
+
".agents/skills/wf-remove/SKILL.md": "sha256-21ebef1a1fa8645d094c8ceeca78b33f036b6c42cda6db8be425d38d9e91af75",
|
|
16
16
|
".agents/skills/wf-review/SKILL.md": "sha256-cc6d536ec6de25546a0ba96e686f195da50ed11bc03763a76ef46d77243d3537",
|
|
17
17
|
".agents/skills/wf-update/SKILL.md": "sha256-d57cd89e271b2af63b6a1264af552a30f8d44959cf4782b42f0ab082a90be9cf",
|
|
18
18
|
".agents/skills/wf/SKILL.md": "sha256-70766bd2cb02bc489b5cc021797af62596a005d444a026abb511054a1a820a67",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
".claude/skills/wf-learn/SKILL.md": "sha256-7f3e1ee0aa83cbb76707698d0c26b703ad5c74b2df95a7dc4d751939a4ba05b2",
|
|
43
43
|
".claude/skills/wf-max/SKILL.md": "sha256-9b37cc3385f6d1a285b617169e91fbf71ffec76135b7b46ec1de2fe94ca220da",
|
|
44
44
|
".claude/skills/wf-readme/SKILL.md": "sha256-4d34ee3b6b305fa2581f5d8cb31e9152759f3df8bf8fa08efbb43782f128bdcd",
|
|
45
|
-
".claude/skills/wf-remove/SKILL.md": "sha256-
|
|
45
|
+
".claude/skills/wf-remove/SKILL.md": "sha256-21ebef1a1fa8645d094c8ceeca78b33f036b6c42cda6db8be425d38d9e91af75",
|
|
46
46
|
".claude/skills/wf-review/SKILL.md": "sha256-cc6d536ec6de25546a0ba96e686f195da50ed11bc03763a76ef46d77243d3537",
|
|
47
47
|
".claude/skills/wf-update/SKILL.md": "sha256-d57cd89e271b2af63b6a1264af552a30f8d44959cf4782b42f0ab082a90be9cf",
|
|
48
48
|
".claude/skills/wf/SKILL.md": "sha256-70766bd2cb02bc489b5cc021797af62596a005d444a026abb511054a1a820a67",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"Harness/HARNESS_BRIDGE.md": "sha256-681dbeca9a590bbeb3a0c01b044e40e642e6d640632d8611064eb897ada8a48d",
|
|
57
57
|
"Harness/MEMORY.md": "sha256-038217c5407a526dca3bd186ec4880f266fa6a8a31d52ebcd27d55aa11f32bb0",
|
|
58
58
|
"Harness/MEMORY_PROTOCOL.md": "sha256-c24c232442a50f1dc7183480fc3b51c6171e32d3ba6648c056797ccd69fea717",
|
|
59
|
-
"Harness/README.md": "sha256-
|
|
60
|
-
"Harness/SETUP.md": "sha256-
|
|
59
|
+
"Harness/README.md": "sha256-95f5d0bd9e250669845c9c5e0724fdb474b1d84ec90d97588501b15f5ef183e9",
|
|
60
|
+
"Harness/SETUP.md": "sha256-490fdac08d5cff4e3b3de4c2155aac18a67f305aa659187923d8a54a4a759873",
|
|
61
61
|
"Harness/TDD-GUIDE.md": "sha256-602084530fd0dea7499a023ce75738351e5d97a0c222b64d405f36da6b59a162",
|
|
62
62
|
"Harness/WF-AUTO-SPARK.md": "sha256-48cc08e1a78cd4abb2ae9c2807ef1ac9a09544eb954220b9087b2032fabbd690",
|
|
63
63
|
"Harness/WF-AUTO.md": "sha256-d31b545249588a69c73e5e0ad8b1286ece1a53d9cd0e93b8ba0ae6dac6fdd119",
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
"Harness/lifecycle.md": "sha256-a2d025e52f3b4412d8439083aca0d2cf7a4458ad0e30de4fc6465f990379190f",
|
|
71
71
|
"Harness/research/README.md": "sha256-956c154df01cb9376972eb8b88bb3be0fe4e2dda802a72457c0126e3476fa755",
|
|
72
72
|
"Harness/scripts/scan-clean.mjs": "sha256-7f693faf762c9c8e7657143d651f7c8369ed4823f18babe21daec58a55025593",
|
|
73
|
-
"Harness/scripts/validate-harness.mjs": "sha256-
|
|
74
|
-
"Harness/scripts/wf-remove.mjs": "sha256-
|
|
73
|
+
"Harness/scripts/validate-harness.mjs": "sha256-31dc33729034656d24ec163ff310164e2fc77289212b2278ab4a2f3d4b9294dc",
|
|
74
|
+
"Harness/scripts/wf-remove.mjs": "sha256-944e5da9dc1abcfb8f410bca743c3f5fbee2bc74d09b97e04ceaaf53da0cb9f1",
|
|
75
75
|
"Harness/scripts/wf-update-check.mjs": "sha256-d14ce08f4c05ba118362a56a4b7d5965b114bc2b15a023c08e21d57f32b2cf93",
|
|
76
76
|
"Harness/subagents.md": "sha256-16255092bab9011bb67359b4399d27ab292c14a717e67123e8a76e40e8669661",
|
|
77
77
|
"Harness/templates/ACCEPTANCE.template.md": "sha256-394a6c08b155b1d121f1d51da774f7988bdb891224c6d5f2ca2c131e8c95ffb3",
|
|
@@ -77,7 +77,7 @@ Routing priority: if a request explicitly says `/wf <task>`, `$wf`, `wf mode`, `
|
|
|
77
77
|
| Need subagents | subagent, role pack, context, inject, return format, orchestrator, isolation | [subagents.md](subagents.md), [context-loading.md](context-loading.md), [dispatch.md](dispatch.md), [AGENT_ISOLATION.md](AGENT_ISOLATION.md) | controller plan, role-specific context pack, isolation-aware dispatch pack |
|
|
78
78
|
| Need feature work | feature, implementation, TDD, test, review, closeout | [tasks/_template/PLAN.md](tasks/_template/PLAN.md), [agent-workflow.md](agent-workflow.md), [TDD-GUIDE.md](TDD-GUIDE.md), [ACCEPTANCE_PROTOCOL.md](ACCEPTANCE_PROTOCOL.md) | task plan, AC-linked RED tests, implementation loop |
|
|
79
79
|
| Review or release check | review, release, finding, risk, evidence, verification | [agent-workflow.md](agent-workflow.md), current feature doc | findings, verification evidence |
|
|
80
|
-
| Harness readiness check | validate, readiness, placeholder, missing file, release gate | `Harness/scripts/validate-harness.mjs`, `Harness/scripts/validate-harness.mjs --strict` |
|
|
80
|
+
| Harness readiness check | validate, readiness, placeholder, missing file, release gate | `Harness/scripts/validate-harness.mjs`, `Harness/scripts/validate-harness.mjs --strict` | structural install check; strict bootstrap/release placeholder check |
|
|
81
81
|
| Need harness update | /wf-update, $wf-update, update, check for updates, harness version | `.claude/skills/wf-update/SKILL.md`, `.agents/skills/wf-update/SKILL.md`, `Harness/.harness-version`, `Harness/scripts/wf-update-check.mjs` | script-driven comparison, SAFE/CONFLICT/PRESERVE classification, user decides conflicts |
|
|
82
82
|
| Need harness removal | /wf-remove, $wf-remove, wf remove, remove harness, uninstall harness | `.claude/skills/wf-remove/SKILL.md`, `.agents/skills/wf-remove/SKILL.md`, `Harness/scripts/wf-remove.mjs` | safe removal plan: auto-remove SAFE, confirm MODIFIED, never touch USER DATA |
|
|
83
83
|
|
|
@@ -103,7 +103,7 @@ Routing priority: if a request explicitly says `/wf <task>`, `$wf`, `wf mode`, `
|
|
|
103
103
|
- Do not add stack-specific agents or skills without following `extension.md`.
|
|
104
104
|
- Do not close work without tests or recorded manual verification.
|
|
105
105
|
- Do not mark work `Verified` until evidence is recorded in the current task's `tasks/<id>/PROGRESS.md` and `tasks/<id>/PLAN.md` or the feature doc.
|
|
106
|
-
- Run `node Harness/scripts/validate-harness.mjs` for scaffold structure; run `node Harness/scripts/validate-harness.mjs --strict` after bootstrap and before release.
|
|
106
|
+
- Run `node Harness/scripts/validate-harness.mjs` for install-complete scaffold structure; run `node Harness/scripts/validate-harness.mjs --strict` only after bootstrap resolves project-fact placeholders and before release.
|
|
107
107
|
- If a doc still has `{{...}}`, treat that section as a template, not project fact.
|
|
108
108
|
|
|
109
109
|
## Doc Map
|
|
@@ -31,7 +31,7 @@ First clarify the idea, then create Mini PRD, acceptance criteria, UI/API contra
|
|
|
31
31
|
|
|
32
32
|
## Required Bootstrap Sequence
|
|
33
33
|
|
|
34
|
-
Claude must follow this order
|
|
34
|
+
Claude or Codex must follow this order during bootstrap. This sequence is broader than installation; if the user only asked to install/configure the harness in an existing project, follow the "Existing Project Fast Path" below and stop after the non-strict validator passes.
|
|
35
35
|
|
|
36
36
|
0. **ECC Stack Configuration** — Detect the project's tech stack. If the repo is empty or has no stack markers (`package.json`, `go.mod`, `pyproject.toml`, `Cargo.toml`, `Gemfile`, `composer.json`, `build.gradle`, etc.), ask the user: "What's your tech stack? (language/framework)" Then install the matching ECC rule sets from `~/.claude/rules/ecc/`. See `Harness/ECC-GUIDE.md` for the stack→rules mapping. Minimum: always install `common/`. Verify with `ls .claude/rules/ecc/`.
|
|
37
37
|
1. Read `CLAUDE.md`, `Harness/MEMORY.md`, `Harness/README.md`, `Harness/lifecycle.md`, and `Harness/ACCEPTANCE_PROTOCOL.md`. Load `Harness/memory/*` only when the router or memory trigger applies.
|
|
@@ -45,8 +45,8 @@ Claude must follow this order:
|
|
|
45
45
|
9. Implement only after PRD-GATE, AC-GATE, CONTRACT-GATE, and TEST-GATE pass.
|
|
46
46
|
10. Independently validate with an AC-by-AC result matrix; use `Harness/HARNESS_BRIDGE.md` for browser/API/CDP flows.
|
|
47
47
|
11. For `/wf-auto` or memory scenario hints, read `Harness/WF-AUTO.md` and `Harness/MEMORY_PROTOCOL.md`; do not enable a background runner by default. The only allowed runtime hook is the optional `/wf-auto` bounded tick hook.
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
12. Run `node Harness/scripts/validate-harness.mjs --strict` after project-fact placeholders are resolved.
|
|
49
|
+
13. Record final verification and next feedback step in `Harness/tasks/<task-id>/PROGRESS.md`. If repeated tool failures, repeated user corrections, or reusable review/debug lessons appeared, record the concise reflection in the relevant `Harness/memory/` file.
|
|
50
50
|
|
|
51
51
|
## Install or Upgrade Path
|
|
52
52
|
|
|
@@ -59,20 +59,25 @@ Before writing, identify the project state:
|
|
|
59
59
|
| Legacy architecture or older project docs | Treat existing code/docs as source of truth, dry-run first, then fill PRD, research, architecture, and task plans from observed facts |
|
|
60
60
|
| Existing `Harness/` | Do not use `npx` as an updater; ask whether to run `/wf-update`, `$wf-update`, `node Harness/scripts/wf-update-check.mjs`, keep untouched, or remove/reinstall after approval |
|
|
61
61
|
|
|
62
|
-
When adding this harness to a project that already has source code, docs, CI, or tool configuration, treat the existing project as the source of truth before filling harness docs.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
When adding this harness to a project that already has source code, docs, CI, or tool configuration, treat the existing project as the source of truth before filling harness docs.
|
|
63
|
+
|
|
64
|
+
### Existing Project Fast Path
|
|
65
|
+
|
|
66
|
+
Use this path when the user asks only to install or configure the harness in an existing project. Do not bootstrap PRD, research, architecture, or task capsules unless the user explicitly asks for bootstrap.
|
|
67
|
+
|
|
68
|
+
1. Get the machine-readable install report first with `npx create-harness-vibe-coding@latest <project-name> <target-dir> -y --dry-run --on-conflict skip --json`. Use `scan.markers` and `agent.aiMergeRequired` instead of hand-written root probes for install decisions. Do manual project-fact reading only after the script has created missing Harness files.
|
|
69
|
+
2. Run the JSON `agent.safeMergeCommand` to create only missing files.
|
|
70
|
+
3. Record discovered facts in the final install summary. Create or update task capsules only when bootstrap or multi-step implementation work begins.
|
|
67
71
|
4. Existing configuration is project fact. Do not overwrite `CLAUDE.md`, `AGENTS.md`, `.claude/`, `.agents/`, `.codex/`, `.gitignore`, settings, package files, CI, docs routers, workflow docs, or installed skills/plugins/rules unless the user explicitly approves that exact overwrite.
|
|
68
|
-
5. When a harness file conflicts with an existing file, preserve the existing file and register any missing harness guidance manually using `Harness/extension.md`.
|
|
69
|
-
6. Run `node Harness/scripts/validate-harness.mjs
|
|
72
|
+
5. When a harness file conflicts with an existing file, preserve the existing file and register any missing harness guidance manually using `Harness/extension.md`.
|
|
73
|
+
6. Run `node Harness/scripts/validate-harness.mjs` as the install-complete gate.
|
|
74
|
+
7. Defer `node Harness/scripts/validate-harness.mjs --strict` until bootstrap removes project-fact placeholders. If placeholders intentionally remain, report strict validation as deferred rather than treating install as failed.
|
|
70
75
|
|
|
71
76
|
`npx create-harness-vibe-coding` is an install/safe-merge entry, not an update engine for a project that already has an installed Harness. If `Harness/` already exists, use `/wf-update`, `$wf-update`, or `node Harness/scripts/wf-update-check.mjs`; root entry files and user-modified Harness docs require agent-mediated merge decisions.
|
|
72
77
|
|
|
73
78
|
### Agent-Link Install Intake
|
|
74
79
|
|
|
75
|
-
When the user installs by pasting the GitHub link into an agent, get the JSON install report before editing or asking generic questions. Summarize `scan.markers`, then ask only questions that affect writes, architecture, security, or workflow. Ask at most three blocking questions up front, record safe defaults for the rest, and ask follow-ups only when that choice becomes active.
|
|
80
|
+
When the user installs by pasting the GitHub link into an agent, get the JSON install report before editing or asking generic questions. Do not fetch full template files or read package source until `agent.aiMergeRequired` names a file that needs semantic comparison. Summarize `scan.markers`, then ask only questions that affect writes, architecture, security, or workflow. Ask at most three blocking questions up front, record safe defaults for the rest, and ask follow-ups only when that choice becomes active.
|
|
76
81
|
|
|
77
82
|
| Topic | Ask When | Default If Unanswered |
|
|
78
83
|
| --- | --- | --- |
|
|
@@ -117,9 +122,9 @@ When `--on-conflict skip` leaves existing files untouched, the script still owns
|
|
|
117
122
|
- **[Overwrite]** — Replace with the template version. Optionally backup the original first (`--on-conflict backup`).
|
|
118
123
|
- **[Keep]** — Leave the existing file as-is. Skip this file.
|
|
119
124
|
|
|
120
|
-
4. For Merge: use
|
|
121
|
-
|
|
122
|
-
5. After all merges, run `node Harness/scripts/validate-harness.mjs --strict`
|
|
125
|
+
4. For Merge: use targeted edits, not a full-file rewrite. In Codex, use `apply_patch` or an equivalent patch operation. Only insert sections, headings, and text that are structurally required. Do not reorder or modify existing content. Do not remove custom project-specific registrations. After merging `CLAUDE.md` or `AGENTS.md`, inspect the heading outline and remove duplicate headings or repeated bullets introduced by the merge.
|
|
126
|
+
|
|
127
|
+
5. After all install merges, run `node Harness/scripts/validate-harness.mjs`. Run `node Harness/scripts/validate-harness.mjs --strict` only after project-fact placeholders are resolved during bootstrap or release preparation.
|
|
123
128
|
|
|
124
129
|
**File-specific gap checklists:**
|
|
125
130
|
|
|
@@ -131,12 +136,12 @@ The harness validator checks for specific structural invariants. When comparing
|
|
|
131
136
|
| `AGENTS.md` | Root agent entry points to `CLAUDE.md` and `Harness/README.md`; for existing projects, merge only after explicit user consent |
|
|
132
137
|
| `README.md` | Existing README is project-owned. Preserve by default; ask whether to append only Development notes or run `wf-readme` for a structure pass with tables/diagrams before broad edits |
|
|
133
138
|
| `Harness/MEMORY.md` | All common agents registered under `## Agents`; all common harness skills registered under `## Skills`; all 3 `Harness/memory/` files registered under `## Memory Folder`; `Harness/memory/` folder usage guidance; `Project Resource Index` in title |
|
|
134
|
-
| `.claude/rules/ecc/common.md` | `## Context`
|
|
139
|
+
| `.claude/rules/ecc/common.md` | Required project-local universal rules. Keep it even when global `~/.claude/rules/ecc/common/` exists; that directory and this file have different scopes. Required sections: `## Context` with the durable communication invariant (`project files are the only durable communication channel`); `## Memory` with three reflection file entries; `## Security` |
|
|
135
140
|
| `Harness/README.md` | `## Keyword Routing` heading; `## Load By Task` table with at minimum the rows: "Need WF mode", "Adding harness to existing project", "Need implementation plan", "Need parallel agents", "Need subagents", "Need durable memory or reflection"; WF routing keywords include `/wf`, `wf mode`, `workflow mode`, and `wk mode`; explicit WF/WK output says subagent docs load immediately; `## Doc Map` with `memory/` and `subagents.md` entries; the durable communication invariant text; `Harness/README.md is the primary router` |
|
|
136
141
|
| `Harness/WF.md` | `WF mode requires multi-subagent orchestration by default`; explicit `/wf`, `$wf`, `wf mode`, `workflow mode`, or `wk mode` requires at least 3 distinct role passes before second planning; `collaboration decision tree`; `Heartbeat Protocol` |
|
|
137
142
|
| `Harness/extension.md` | `## Non-Invasive Extension Rules` section with the "Preserve existing" rule; `## Agent Contract` section; `## Registration` section |
|
|
138
|
-
| `Harness/dispatch.md` | The durable communication invariant; common agent entries
|
|
139
|
-
| `Harness/context-loading.md` | The durable communication invariant; `Harness/README.md is the primary router`; all
|
|
143
|
+
| `Harness/dispatch.md` | The durable communication invariant; registered common agent entries; `## Handoff Format` heading |
|
|
144
|
+
| `Harness/context-loading.md` | The durable communication invariant; `Harness/README.md is the primary router`; all 12 subagent context packs (Explorer Pass, Planner, Researcher, Docs Researcher, Architect, Test Writer, Implementer, Reviewer, Debugger, Verifier, Memory Master, Context Master) |
|
|
140
145
|
| `Harness/subagents.md` | `## Source Attribution`; `## Built-in Agent Roster`; `## WF Default Fan-Out`; `Controller Role`; `Efficiency Ladder`; `Review Gates`; `collaboration decision tree`; source markers for `npx skills find`, `dispatching-parallel-agents`, and `subagent-driven-development` |
|
|
141
146
|
| `Harness/architecture.md` | `## 2. Interface Decoupling`; `## 3. State Design`; `Avoid speculative abstraction`; layer constraints derived from actual project facts |
|
|
142
147
|
| `Harness/PROGRESS.md` | global task index with Active Task and task history; cross-task decisions |
|
|
@@ -146,12 +151,14 @@ The harness validator checks for specific structural invariants. When comparing
|
|
|
146
151
|
| `Harness/workflows/browser-e2e.md` (if installed as optional) | `data-testid`, `accessible labels/roles`, and `inputs, buttons, filters, rows, empty/error/loading states` requirement |
|
|
147
152
|
| `Harness/workflows/ts-react-frontend.md` (if installed as optional) | Same UI selector contract as above |
|
|
148
153
|
|
|
149
|
-
**Files that do NOT need manual merge when the path does not already exist (auto-created by harness):**
|
|
154
|
+
**Files that do NOT need manual merge when the path does not already exist (auto-created by harness):**
|
|
155
|
+
|
|
156
|
+
The generated file list is authoritative by path, not by stale count labels. Current common scaffolds include WF-MAX manager agents and `tdd-guide`; keep every file created by the scaffold unless a removal workflow explicitly classifies it as safe to remove.
|
|
150
157
|
|
|
151
158
|
- `Harness/memory/tool-usage-reflections.md`, `Harness/memory/user-corrections-preferences.md`, `Harness/memory/agent-lessons-patterns.md` — these are new empty files
|
|
152
|
-
- `.claude/agents/*.md`
|
|
159
|
+
- `.claude/agents/*.md` - all built-in common agent files, including WF-MAX managers and `tdd-guide`
|
|
153
160
|
- `.claude/skills/*.md` and mirrored `.agents/skills/*.md` — Claude Code and Codex skill adapters over the same Harness docs
|
|
154
|
-
- `.claude/rules/ecc/common.md`
|
|
161
|
+
- `.claude/rules/ecc/common.md` - required project-local universal rules. Do not delete this file as a duplicate of a global `~/.claude/rules/ecc/common/` directory; they are different scopes.
|
|
155
162
|
- `.claude/settings.json` — harness settings
|
|
156
163
|
- `Harness/WF.md`, `Harness/lifecycle.md`, `Harness/subagents.md`, `Harness/agent-workflow.md`, `Harness/architecture.md` — harness runtime docs
|
|
157
164
|
- `Harness/research/*.md` — research protocol and templates
|
|
@@ -314,5 +321,5 @@ After scaffolding, use the JSON output first. Files in `plan.create[]` were hand
|
|
|
314
321
|
|
|
315
322
|
1. Read `CLAUDE.md`, `Harness/MEMORY.md`, and `Harness/README.md`.
|
|
316
323
|
2. Follow the Required Bootstrap Sequence above.
|
|
317
|
-
3. Run `node Harness/scripts/validate-harness.mjs --strict`
|
|
324
|
+
3. Run `node Harness/scripts/validate-harness.mjs` after install. Run `node Harness/scripts/validate-harness.mjs --strict` after bootstrap resolves project-fact placeholders.
|
|
318
325
|
4. Delete `Harness/SETUP.md`.
|
|
@@ -541,6 +541,9 @@ requireText('Harness/templates/TEST_PLAN.template.md', 'syntax-only checks', 'te
|
|
|
541
541
|
requireText('.claude/skills/tdd/SKILL.md', 'Harness/ACCEPTANCE_PROTOCOL.md', 'tdd skill loads acceptance protocol');
|
|
542
542
|
requireText('.claude/skills/tdd/SKILL.md', 'Harness/HARNESS_BRIDGE.md', 'tdd skill loads harness bridge');
|
|
543
543
|
requireText('.claude/skills/tdd/SKILL.md', 'No syntax-only acceptance', 'tdd skill forbids syntax-only acceptance');
|
|
544
|
+
requireText('.claude/skills/wf-remove/SKILL.md', 'User-facing removal is the slash/skill command', 'wf-remove slash command is user-facing');
|
|
545
|
+
requireText('.claude/skills/wf-remove/SKILL.md', 'agent-internal execution steps', 'wf-remove script commands are agent-internal');
|
|
546
|
+
requireText('.claude/skills/wf-remove/SKILL.md', 'verify residual discovery folders', 'wf-remove residual discovery verification');
|
|
544
547
|
requireText('.claude/agents/tdd-guide.md', 'Browser Acceptance Rules', 'tdd-guide browser acceptance rules');
|
|
545
548
|
requireText('.claude/agents/tdd-guide.md', 'real user actions', 'tdd-guide real user action requirement');
|
|
546
549
|
requireText('.claude/agents/test-writer.md', 'Harness/ACCEPTANCE_PROTOCOL.md', 'test-writer loads acceptance protocol');
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* wf-remove.mjs
|
|
3
|
+
* wf-remove.mjs �?Safely remove Harness framework files.
|
|
4
4
|
*
|
|
5
5
|
* Classifies all Harness-owned files into:
|
|
6
|
-
* SAFE
|
|
7
|
-
* MODIFIED
|
|
8
|
-
* USER
|
|
6
|
+
* SAFE �?framework files matching stored checksums �?auto-remove
|
|
7
|
+
* MODIFIED �?framework files edited by user �?MUST confirm
|
|
8
|
+
* USER �?user data files �?NEVER remove
|
|
9
9
|
*
|
|
10
10
|
* Usage:
|
|
11
11
|
* node Harness/scripts/wf-remove.mjs # dry-run: show plan
|
|
@@ -23,12 +23,12 @@ import { resolve, dirname, join, sep } from 'path';
|
|
|
23
23
|
import { fileURLToPath } from 'url';
|
|
24
24
|
import { createInterface } from 'readline';
|
|
25
25
|
|
|
26
|
-
const
|
|
26
|
+
const SCRIPT_FILE = fileURLToPath(import.meta.url);
|
|
27
|
+
const __dirname = dirname(SCRIPT_FILE);
|
|
28
|
+
const SCRIPT_ROOT = resolve(__dirname, '..', '..');
|
|
27
29
|
const ROOT = process.env.WF_ROOT
|
|
28
30
|
? resolve(process.env.WF_ROOT)
|
|
29
|
-
:
|
|
30
|
-
? process.cwd()
|
|
31
|
-
: resolve(__dirname, '..', '..'));
|
|
31
|
+
: SCRIPT_ROOT;
|
|
32
32
|
const VERSION_FILE = resolve(ROOT, 'Harness', '.harness-version');
|
|
33
33
|
|
|
34
34
|
// ── Classification ─────────────────────────────────────────────────
|
|
@@ -45,7 +45,7 @@ const HARNESS_PREFIXES = [
|
|
|
45
45
|
'tests/.gitkeep',
|
|
46
46
|
];
|
|
47
47
|
|
|
48
|
-
/** Files the user owns
|
|
48
|
+
/** Files the user owns �?NEVER remove. Consistent with wf-update-check PRESERVE_PATTERNS. */
|
|
49
49
|
const USER_DATA_PATTERNS = [
|
|
50
50
|
/^Harness\/PROGRESS\.md$/,
|
|
51
51
|
/^Harness\/tasks\//,
|
|
@@ -97,14 +97,67 @@ function isPurgeableHarnessData(file, { keepTasks }) {
|
|
|
97
97
|
if (keepTasks && /^Harness\/tasks\//.test(file) && !isFrameworkTaskFile(file)) return false;
|
|
98
98
|
return PURGEABLE_HARNESS_DATA_PATTERNS.some(p => p.test(file));
|
|
99
99
|
}
|
|
100
|
-
|
|
101
|
-
/** Framework files that should always exist (not part of removal). */
|
|
102
|
-
const KEEP_FRAMEWORK = new Set([
|
|
103
|
-
'Harness/.harness-version',
|
|
104
|
-
]);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
100
|
+
|
|
101
|
+
/** Framework files that should always exist (not part of removal). */
|
|
102
|
+
const KEEP_FRAMEWORK = new Set([
|
|
103
|
+
'Harness/.harness-version',
|
|
104
|
+
]);
|
|
105
|
+
|
|
106
|
+
const BUILT_IN_AGENT_NAMES = [
|
|
107
|
+
'architect-manager',
|
|
108
|
+
'architect',
|
|
109
|
+
'context-master',
|
|
110
|
+
'debugger',
|
|
111
|
+
'docs-researcher',
|
|
112
|
+
'explore-manager',
|
|
113
|
+
'implement-manager',
|
|
114
|
+
'implementer',
|
|
115
|
+
'memory-master',
|
|
116
|
+
'planner',
|
|
117
|
+
'researcher',
|
|
118
|
+
'review-manager',
|
|
119
|
+
'reviewer',
|
|
120
|
+
'tdd-guide',
|
|
121
|
+
'test-writer',
|
|
122
|
+
'verifier',
|
|
123
|
+
];
|
|
124
|
+
|
|
125
|
+
const BUILT_IN_SKILL_NAMES = [
|
|
126
|
+
'browser-e2e',
|
|
127
|
+
'github-pr-review',
|
|
128
|
+
'python-backend',
|
|
129
|
+
'subagent-orchestrator',
|
|
130
|
+
'tdd',
|
|
131
|
+
'ts-react-frontend',
|
|
132
|
+
'ui-ux-review',
|
|
133
|
+
'wf',
|
|
134
|
+
'wf-auto',
|
|
135
|
+
'wf-auto-spark',
|
|
136
|
+
'wf-browser',
|
|
137
|
+
'wf-learn',
|
|
138
|
+
'wf-max',
|
|
139
|
+
'wf-readme',
|
|
140
|
+
'wf-remove',
|
|
141
|
+
'wf-review',
|
|
142
|
+
'wf-update',
|
|
143
|
+
];
|
|
144
|
+
|
|
145
|
+
const KNOWN_FRAMEWORK_FILES = new Set([
|
|
146
|
+
...BUILT_IN_AGENT_NAMES.map(name => `.claude/agents/${name}.md`),
|
|
147
|
+
...BUILT_IN_SKILL_NAMES.flatMap(name => [
|
|
148
|
+
`.claude/skills/${name}/SKILL.md`,
|
|
149
|
+
`.agents/skills/${name}/SKILL.md`,
|
|
150
|
+
]),
|
|
151
|
+
'.claude/commands/wf-help.md',
|
|
152
|
+
'.claude/rules/ecc/common.md',
|
|
153
|
+
]);
|
|
154
|
+
|
|
155
|
+
function isKnownFrameworkFile(file) {
|
|
156
|
+
return KNOWN_FRAMEWORK_FILES.has(file);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Directories to clean up if empty after file removal. */
|
|
160
|
+
const CLEANUP_DIRS = [
|
|
108
161
|
'.claude/agents',
|
|
109
162
|
'.claude/skills/wf-auto',
|
|
110
163
|
'.claude/skills/wf-browser',
|
|
@@ -251,7 +304,7 @@ function removeEmptyDirs(startDir) {
|
|
|
251
304
|
|
|
252
305
|
async function askUser(question) {
|
|
253
306
|
if (!process.stdin.isTTY) {
|
|
254
|
-
console.log(' (non-interactive
|
|
307
|
+
console.log(' (non-interactive �?defaulting to KEEP)');
|
|
255
308
|
return 'k';
|
|
256
309
|
}
|
|
257
310
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -300,8 +353,9 @@ async function main() {
|
|
|
300
353
|
addFilesUnder(allFiles, dir, scanIssues);
|
|
301
354
|
}
|
|
302
355
|
|
|
303
|
-
// Add framework files that might not be in checksums (newer additions)
|
|
356
|
+
// Add framework files that might not be in checksums (newer additions)
|
|
304
357
|
const extraPatterns = [
|
|
358
|
+
...KNOWN_FRAMEWORK_FILES,
|
|
305
359
|
'.claude/skills/wf/SKILL.md',
|
|
306
360
|
'.agents/skills/wf/SKILL.md',
|
|
307
361
|
'.claude/skills/tdd/SKILL.md',
|
|
@@ -323,9 +377,9 @@ async function main() {
|
|
|
323
377
|
}
|
|
324
378
|
|
|
325
379
|
// 2. Classify every file
|
|
326
|
-
const safe = []; // SAFE
|
|
327
|
-
const modified = []; // MODIFIED
|
|
328
|
-
const user = []; // USER
|
|
380
|
+
const safe = []; // SAFE �?matches checksum, auto-remove
|
|
381
|
+
const modified = []; // MODIFIED �?user edited, must confirm
|
|
382
|
+
const user = []; // USER �?never remove
|
|
329
383
|
const skipped = []; // File not on disk, traversal rejected, or framework-keep
|
|
330
384
|
const purge = []; // Explicitly requested Harness user-data removal
|
|
331
385
|
skipped.push(...scanIssues);
|
|
@@ -347,13 +401,13 @@ async function main() {
|
|
|
347
401
|
});
|
|
348
402
|
continue;
|
|
349
403
|
}
|
|
350
|
-
user.push({ file, reason: 'user data
|
|
404
|
+
user.push({ file, reason: 'user data �?NEVER removed' });
|
|
351
405
|
continue;
|
|
352
406
|
}
|
|
353
407
|
|
|
354
408
|
// Only allow deletion of files under harness-owned prefixes
|
|
355
409
|
if (!isHarnessOwned(canonical)) {
|
|
356
|
-
user.push({ file, reason: 'outside harness prefix
|
|
410
|
+
user.push({ file, reason: 'outside harness prefix �?NEVER removed' });
|
|
357
411
|
continue;
|
|
358
412
|
}
|
|
359
413
|
|
|
@@ -366,15 +420,24 @@ async function main() {
|
|
|
366
420
|
skipped.push({ file, reason: 'not on disk' });
|
|
367
421
|
continue;
|
|
368
422
|
}
|
|
369
|
-
|
|
370
|
-
const currentHash = sha256File(diskPath);
|
|
371
|
-
const storedHash = storedChecksums[file];
|
|
372
|
-
|
|
373
|
-
if (!storedHash) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
423
|
+
|
|
424
|
+
const currentHash = sha256File(diskPath);
|
|
425
|
+
const storedHash = storedChecksums[file];
|
|
426
|
+
|
|
427
|
+
if (!storedHash) {
|
|
428
|
+
if (isKnownFrameworkFile(canonical)) {
|
|
429
|
+
safe.push({
|
|
430
|
+
file,
|
|
431
|
+
currentHash,
|
|
432
|
+
storedHash: currentHash,
|
|
433
|
+
reason: 'known framework file missing from legacy checksums',
|
|
434
|
+
});
|
|
435
|
+
} else {
|
|
436
|
+
modified.push({ file, currentHash, storedHash: 'none', reason: 'not in checksums' });
|
|
437
|
+
}
|
|
438
|
+
} else if (currentHash === storedHash) {
|
|
439
|
+
safe.push({ file, currentHash, storedHash });
|
|
440
|
+
} else {
|
|
378
441
|
modified.push({ file, currentHash, storedHash, reason: 'user modified' });
|
|
379
442
|
}
|
|
380
443
|
}
|
|
@@ -385,7 +448,7 @@ async function main() {
|
|
|
385
448
|
const settingsHash = sha256File(settingsFile);
|
|
386
449
|
const storedSettingsHash = storedChecksums['.claude/settings.json'];
|
|
387
450
|
if (storedSettingsHash && settingsHash !== storedSettingsHash) {
|
|
388
|
-
// User modified settings
|
|
451
|
+
// User modified settings �?move to modified
|
|
389
452
|
// Remove from safe if it was there
|
|
390
453
|
const idx = safe.findIndex(s => s.file === '.claude/settings.json');
|
|
391
454
|
if (idx >= 0) {
|
|
@@ -429,16 +492,16 @@ async function main() {
|
|
|
429
492
|
return;
|
|
430
493
|
}
|
|
431
494
|
|
|
432
|
-
console.log('\n🧹 WF-REMOVE
|
|
495
|
+
console.log('\n🧹 WF-REMOVE �?Harness framework removal plan\n');
|
|
433
496
|
|
|
434
497
|
if (safe.length > 0) {
|
|
435
|
-
console.log(
|
|
436
|
-
for (const s of safe) console.log(`
|
|
498
|
+
console.log(`�?SAFE (${safe.length} files �?auto-remove, unmodified framework):`);
|
|
499
|
+
for (const s of safe) console.log(` �?${s.file}`);
|
|
437
500
|
console.log('');
|
|
438
501
|
}
|
|
439
502
|
|
|
440
503
|
if (modified.length > 0) {
|
|
441
|
-
console.log(
|
|
504
|
+
console.log(`�?MODIFIED (${modified.length} files �?REQUIRE CONFIRMATION):`);
|
|
442
505
|
for (const m of modified) {
|
|
443
506
|
console.log(` ? ${m.file} [${m.reason}]`);
|
|
444
507
|
}
|
|
@@ -446,8 +509,8 @@ async function main() {
|
|
|
446
509
|
}
|
|
447
510
|
|
|
448
511
|
if (user.length > 0) {
|
|
449
|
-
console.log(`🔒 USER DATA (${user.length} files
|
|
450
|
-
for (const u of user) console.log(`
|
|
512
|
+
console.log(`🔒 USER DATA (${user.length} files �?NEVER removed):`);
|
|
513
|
+
for (const u of user) console.log(` �?${u.file} [${u.reason}]`);
|
|
451
514
|
console.log('');
|
|
452
515
|
}
|
|
453
516
|
|
|
@@ -464,17 +527,17 @@ async function main() {
|
|
|
464
527
|
return;
|
|
465
528
|
}
|
|
466
529
|
|
|
467
|
-
// 4. Apply
|
|
530
|
+
// 4. Apply �?remove SAFE files automatically (rehash before unlink)
|
|
468
531
|
let safeRemoved = 0;
|
|
469
532
|
let safeFailed = 0;
|
|
470
533
|
for (const s of safe) {
|
|
471
534
|
const diskPath = safePath(s.file);
|
|
472
|
-
if (!diskPath) { console.error(`
|
|
535
|
+
if (!diskPath) { console.error(` �?Traversal rejected: ${s.file}`); safeFailed++; continue; }
|
|
473
536
|
if (!existsSync(diskPath)) continue;
|
|
474
537
|
// Re-verify hash hasn't changed since classification
|
|
475
538
|
const currentHash = sha256File(diskPath);
|
|
476
539
|
if (currentHash !== s.storedHash) {
|
|
477
|
-
console.log(`
|
|
540
|
+
console.log(` �?Skipped (modified since classification): ${s.file}`);
|
|
478
541
|
safeFailed++;
|
|
479
542
|
continue;
|
|
480
543
|
}
|
|
@@ -482,13 +545,13 @@ async function main() {
|
|
|
482
545
|
unlinkSync(diskPath);
|
|
483
546
|
safeRemoved++;
|
|
484
547
|
} catch (e) {
|
|
485
|
-
console.error(`
|
|
548
|
+
console.error(` �?Failed to remove: ${s.file} �?${e.message}`);
|
|
486
549
|
safeFailed++;
|
|
487
550
|
}
|
|
488
551
|
}
|
|
489
|
-
console.log(
|
|
552
|
+
console.log(`�?Removed ${safeRemoved} safe files.`);
|
|
490
553
|
|
|
491
|
-
// 5. Handle MODIFIED files
|
|
554
|
+
// 5. Handle MODIFIED files �?prompt user
|
|
492
555
|
let modifiedRemoved = 0;
|
|
493
556
|
let modifiedKept = 0;
|
|
494
557
|
let modifiedFailed = 0;
|
|
@@ -508,7 +571,7 @@ async function main() {
|
|
|
508
571
|
}
|
|
509
572
|
if (yes) {
|
|
510
573
|
// Non-interactive mode: skip all modified
|
|
511
|
-
console.log(`
|
|
574
|
+
console.log(` �?Skipped (modified): ${m.file}`);
|
|
512
575
|
modifiedKept++;
|
|
513
576
|
continue;
|
|
514
577
|
}
|
|
@@ -520,17 +583,17 @@ async function main() {
|
|
|
520
583
|
const answer = await askUser(' Choose [d/k]: ');
|
|
521
584
|
if (answer === 'd' || answer === 'delete') {
|
|
522
585
|
const diskPath = safePath(m.file);
|
|
523
|
-
if (!diskPath) { console.error(`
|
|
586
|
+
if (!diskPath) { console.error(` �?Traversal rejected: ${m.file}`); modifiedFailed++; continue; }
|
|
524
587
|
try {
|
|
525
588
|
unlinkSync(diskPath);
|
|
526
|
-
console.log(`
|
|
589
|
+
console.log(` �?Deleted: ${m.file}`);
|
|
527
590
|
modifiedRemoved++;
|
|
528
591
|
} catch (e) {
|
|
529
|
-
console.error(`
|
|
592
|
+
console.error(` �?Failed: ${m.file} �?${e.message}`);
|
|
530
593
|
modifiedFailed++;
|
|
531
594
|
}
|
|
532
595
|
} else {
|
|
533
|
-
console.log(`
|
|
596
|
+
console.log(` �?Kept: ${m.file}`);
|
|
534
597
|
modifiedKept++;
|
|
535
598
|
}
|
|
536
599
|
}
|
|
@@ -591,7 +654,7 @@ async function main() {
|
|
|
591
654
|
}
|
|
592
655
|
} else if (!existsSync(harPath) || (existsSync(harPath) && readdirSync(harPath).filter(f => f !== '.harness-version').length === 0)) {
|
|
593
656
|
unlinkSync(VERSION_FILE);
|
|
594
|
-
console.log('
|
|
657
|
+
console.log('�?Removed .harness-version (Harness directory empty).');
|
|
595
658
|
}
|
|
596
659
|
}
|
|
597
660
|
|
|
@@ -610,7 +673,7 @@ async function main() {
|
|
|
610
673
|
if (pruned > 0) {
|
|
611
674
|
versionData.checksums = checksums;
|
|
612
675
|
writeFileSync(VERSION_FILE, JSON.stringify(versionData, null, 2) + '\n', 'utf-8');
|
|
613
|
-
console.log(
|
|
676
|
+
console.log(`�?Pruned ${pruned} stale checksum(s) from .harness-version.`);
|
|
614
677
|
}
|
|
615
678
|
}
|
|
616
679
|
|
|
@@ -624,7 +687,7 @@ async function main() {
|
|
|
624
687
|
// Strip the harness section: everything from "## 1. Harness Binding" to the next "## "
|
|
625
688
|
const cleaned = content.replace(/## 1\. Harness Binding[\s\S]*?(?=## 2\.)/, '');
|
|
626
689
|
writeFileSync(claudePath, cleaned, 'utf-8');
|
|
627
|
-
console.log('
|
|
690
|
+
console.log('�?Stripped Harness binding section from CLAUDE.md.');
|
|
628
691
|
}
|
|
629
692
|
}
|
|
630
693
|
}
|