dev-harness-cli 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +19 -19
  2. package/cli/commands/checkpoint.mjs +2 -2
  3. package/cli/commands/config.mjs +12 -12
  4. package/cli/commands/contract.mjs +10 -10
  5. package/cli/commands/detect-tool.mjs +3 -3
  6. package/cli/commands/init.mjs +1 -1
  7. package/cli/commands/learn.mjs +3 -3
  8. package/cli/commands/pause.mjs +1 -1
  9. package/cli/commands/phase.mjs +6 -6
  10. package/cli/commands/resume.mjs +3 -3
  11. package/cli/commands/rollback.mjs +6 -6
  12. package/cli/commands/set-mode.mjs +5 -5
  13. package/cli/commands/status.mjs +7 -7
  14. package/cli/commands/validate.mjs +7 -7
  15. package/cli/commands/worktree.mjs +6 -6
  16. package/cli/{harness-dev.mjs → dev-harness.mjs} +2 -2
  17. package/cli/lib/config-registry.mjs +2 -2
  18. package/cli/lib/contract.mjs +3 -3
  19. package/cli/lib/gates.mjs +1 -1
  20. package/cli/lib/help.mjs +28 -28
  21. package/cli/lib/ralph-inner.mjs +2 -2
  22. package/cli/lib/ralph-outer.mjs +3 -3
  23. package/cli/lib/ralph-output.mjs +1 -1
  24. package/cli/lib/scaffold.mjs +1 -1
  25. package/cli/lib/state.mjs +1 -1
  26. package/package.json +4 -4
  27. package/templates/AGENTS.md +5 -5
  28. package/templates/ci/github-actions.yml +1 -1
  29. package/templates/ci/gitlab-ci.yml +1 -1
  30. package/templates/docs/agents/generator.md +1 -1
  31. package/templates/docs/agents/simplifier.md +1 -1
  32. package/templates/docs/phases/build.md +3 -3
  33. package/templates/docs/phases/define.md +3 -3
  34. package/templates/docs/phases/plan.md +3 -3
  35. package/templates/docs/phases/review.md +2 -2
  36. package/templates/docs/phases/ship.md +3 -3
  37. package/templates/docs/phases/simplify.md +3 -3
  38. package/templates/docs/phases/verify.md +2 -2
  39. package/templates/init.ps1 +1 -1
  40. package/templates/progress.md +1 -1
package/README.md CHANGED
@@ -35,7 +35,7 @@ npx dev-harness-cli init --stack python --target my-project
35
35
 
36
36
  # Global install
37
37
  npm install -g dev-harness-cli
38
- harness-dev --help
38
+ dev-harness --help
39
39
  ```
40
40
 
41
41
  Requires **Node.js >= 18**. Zero runtime dependencies.
@@ -44,29 +44,29 @@ Requires **Node.js >= 18**. Zero runtime dependencies.
44
44
 
45
45
  ```bash
46
46
  # 1. Scaffold a new project
47
- harness-dev init --stack node --target my-app
47
+ dev-harness init --stack node --target my-app
48
48
  cd my-app
49
49
 
50
50
  # 2. Check status
51
- harness-dev status
51
+ dev-harness status
52
52
 
53
53
  # 3. Run the DEFINE phase (agent writes specs)
54
- harness-dev phase define
54
+ dev-harness phase define
55
55
 
56
56
  # 4. Validate (run gate checks)
57
- harness-dev validate
57
+ dev-harness validate
58
58
 
59
59
  # 5. Continue through pipeline
60
- harness-dev phase plan
61
- harness-dev phase build
62
- harness-dev phase verify
63
- harness-dev phase review
64
- harness-dev phase ship
60
+ dev-harness phase plan
61
+ dev-harness phase build
62
+ dev-harness phase verify
63
+ dev-harness phase review
64
+ dev-harness phase ship
65
65
  ```
66
66
 
67
67
  ## Project Structure
68
68
 
69
- When you run `harness-dev init`, all harness-managed files go into a `harness/` subfolder — keeping your project root clean:
69
+ When you run `dev-harness init`, all harness-managed files go into a `harness/` subfolder — keeping your project root clean:
70
70
 
71
71
  ```
72
72
  my-project/
@@ -157,13 +157,13 @@ Harness works with any coding agent. Use `--agent-tool` during init to generate
157
157
 
158
158
  ```bash
159
159
  # Claude Code → generates CLAUDE.md
160
- harness-dev init --stack node --agent-tool claude-code --target my-app
160
+ dev-harness init --stack node --agent-tool claude-code --target my-app
161
161
 
162
162
  # Cursor → generates .cursorrules
163
- harness-dev init --stack node --agent-tool cursor --target my-app
163
+ dev-harness init --stack node --agent-tool cursor --target my-app
164
164
 
165
165
  # GitHub Copilot → generates .github/copilot-instructions.md
166
- harness-dev init --stack node --agent-tool copilot --target my-app
166
+ dev-harness init --stack node --agent-tool copilot --target my-app
167
167
  ```
168
168
 
169
169
  **18 supported tools:** claude-code, cursor, windsurf, gemini, copilot, cline, roo, kilo-code, amazon-q, codex, opencode, continue, aider, antigravity, openclaw, pi, hermes, generic.
@@ -175,7 +175,7 @@ See [docs/TOOL_INTEGRATION.md](docs/TOOL_INTEGRATION.md) for per-tool setup guid
175
175
  Gates are deterministic checks that must pass before advancing to the next phase. Enable with:
176
176
 
177
177
  ```bash
178
- harness-dev config set gates.enabled true
178
+ dev-harness config set gates.enabled true
179
179
  ```
180
180
 
181
181
  | Phase | Gates |
@@ -193,7 +193,7 @@ harness-dev config set gates.enabled true
193
193
  All configuration lives in `harness/config.json`. View with:
194
194
 
195
195
  ```bash
196
- harness-dev config list
196
+ dev-harness config list
197
197
  ```
198
198
 
199
199
  29 parameters across 8 groups: Execution, Stack, Agent Tool, Gates, Git, Phases, Agent Tones, Runtime State.
@@ -205,9 +205,9 @@ See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for full reference.
205
205
  All commands support `--json` for machine-parseable output:
206
206
 
207
207
  ```bash
208
- harness-dev status --json
209
- harness-dev phase define --json
210
- harness-dev validate --json
208
+ dev-harness status --json
209
+ dev-harness phase define --json
210
+ dev-harness validate --json
211
211
  ```
212
212
 
213
213
  ```json
@@ -9,7 +9,7 @@
9
9
  * save named recovery points (e.g. "before-refactor") that appear
10
10
  * in `rollback list` and can be used with `rollback to/branch`.
11
11
  *
12
- * Usage: harness-dev checkpoint create <label>
12
+ * Usage: dev-harness checkpoint create <label>
13
13
  */
14
14
  import { die, CliError, EXIT } from '../lib/errors.mjs';
15
15
  import { execGit, getGitRoot, gitTagExists, createGitTag } from '../lib/git.mjs';
@@ -21,7 +21,7 @@ export default async function checkpointCommand(args) {
21
21
  const label = args.positionals[0];
22
22
 
23
23
  if (sub !== 'create' || !label) {
24
- die(new CliError('Usage: harness-dev checkpoint create <label> [--force]', EXIT.USAGE_ERROR), json);
24
+ die(new CliError('Usage: dev-harness checkpoint create <label> [--force]', EXIT.USAGE_ERROR), json);
25
25
  return;
26
26
  }
27
27
 
@@ -4,16 +4,16 @@
4
4
  * Uses state.mjs for dot-notation read/write with persistence.
5
5
  *
6
6
  * Usage:
7
- * harness-dev config list — list all parameters with descriptions
8
- * harness-dev config get [key] — get a value or all config
9
- * harness-dev config set <key> <value> — set a value
7
+ * dev-harness config list — list all parameters with descriptions
8
+ * dev-harness config get [key] — get a value or all config
9
+ * dev-harness config set <key> <value> — set a value
10
10
  *
11
11
  * Examples:
12
- * harness-dev config list
13
- * harness-dev config list --json
14
- * harness-dev config get gates.enabled
15
- * harness-dev config set gates.enabled true
16
- * harness-dev config set maxRetries 5
12
+ * dev-harness config list
13
+ * dev-harness config list --json
14
+ * dev-harness config get gates.enabled
15
+ * dev-harness config set gates.enabled true
16
+ * dev-harness config set maxRetries 5
17
17
  */
18
18
  import { resolve } from 'node:path';
19
19
  import { die, CliError, EXIT } from '../lib/errors.mjs';
@@ -29,7 +29,7 @@ export default async function configCommand(args) {
29
29
 
30
30
  if (!sub || (sub !== 'get' && sub !== 'set' && sub !== 'list')) {
31
31
  die(new CliError(
32
- 'Usage: harness-dev config list | config get [key] | config set <key> <value>',
32
+ 'Usage: dev-harness config list | config get [key] | config set <key> <value>',
33
33
  EXIT.USAGE_ERROR,
34
34
  ), json);
35
35
  return;
@@ -75,7 +75,7 @@ export default async function configCommand(args) {
75
75
  // Human output — grouped table
76
76
  process.stdout.write('═══ Harness Configuration ═══\n\n');
77
77
  if (!ok) {
78
- process.stdout.write(' No harness/config.json found. Run: harness-dev init\n\n');
78
+ process.stdout.write(' No harness/config.json found. Run: dev-harness init\n\n');
79
79
  return;
80
80
  }
81
81
 
@@ -102,7 +102,7 @@ export default async function configCommand(args) {
102
102
  process.stdout.write('\n');
103
103
  }
104
104
 
105
- process.stdout.write('Edit with: harness-dev config set <key> <value>\n');
105
+ process.stdout.write('Edit with: dev-harness config set <key> <value>\n');
106
106
  process.stdout.write('Full docs: docs/CONFIGURATION.md\n');
107
107
  return;
108
108
  }
@@ -141,7 +141,7 @@ export default async function configCommand(args) {
141
141
  if (sub === 'set') {
142
142
  if (pos.length < 2) {
143
143
  die(new CliError(
144
- 'Usage: harness-dev config set <key> <value>\n' +
144
+ 'Usage: dev-harness config set <key> <value>\n' +
145
145
  ' String values: config set mode copilot\n' +
146
146
  ' Boolean values: config set gates.enabled true\n' +
147
147
  ' Numeric values: config set maxRetries 5',
@@ -4,10 +4,10 @@
4
4
  * Manages the generator-evaluator agreement loop.
5
5
  *
6
6
  * Usage:
7
- * harness-dev contract propose [--scope "msg"] [--exclusions "msg"]
8
- * harness-dev contract review [--agreed|--needs-revision]
9
- * harness-dev contract status
10
- * harness-dev contract escalate [--reason "msg"]
7
+ * dev-harness contract propose [--scope "msg"] [--exclusions "msg"]
8
+ * dev-harness contract review [--agreed|--needs-revision]
9
+ * dev-harness contract status
10
+ * dev-harness contract escalate [--reason "msg"]
11
11
  */
12
12
  import { resolve } from 'node:path';
13
13
  import { die, CliError, EXIT } from '../lib/errors.mjs';
@@ -22,7 +22,7 @@ export default async function contractCommand(args) {
22
22
  const sub = args.subcommand;
23
23
 
24
24
  if (!sub || !SUBCOMMANDS.includes(sub)) {
25
- die(new CliError(`Usage: harness-dev contract ${SUBCOMMANDS.join('|')}`, EXIT.USAGE_ERROR), json);
25
+ die(new CliError(`Usage: dev-harness contract ${SUBCOMMANDS.join('|')}`, EXIT.USAGE_ERROR), json);
26
26
  return;
27
27
  }
28
28
 
@@ -34,7 +34,7 @@ export default async function contractCommand(args) {
34
34
 
35
35
  if (!scope) {
36
36
  die(new CliError(
37
- 'Usage: harness-dev contract propose --scope "I will build X" [--exclusions "W"] [--criteria "test1|test2"]',
37
+ 'Usage: dev-harness contract propose --scope "I will build X" [--exclusions "W"] [--criteria "test1|test2"]',
38
38
  EXIT.USAGE_ERROR,
39
39
  ), json);
40
40
  return;
@@ -53,7 +53,7 @@ export default async function contractCommand(args) {
53
53
  }
54
54
 
55
55
  if (result.ok) {
56
- process.stdout.write('✓ Contract proposed. Run: harness-dev contract review\n');
56
+ process.stdout.write('✓ Contract proposed. Run: dev-harness contract review\n');
57
57
  } else {
58
58
  process.stderr.write(`✗ ${result.error}\n`);
59
59
  }
@@ -68,7 +68,7 @@ export default async function contractCommand(args) {
68
68
 
69
69
  if (!agreed && !needsRevision) {
70
70
  die(new CliError(
71
- 'Usage: harness-dev contract review --agreed [--notes "msg"] OR --needs-revision [--notes "msg"]',
71
+ 'Usage: dev-harness contract review --agreed [--notes "msg"] OR --needs-revision [--notes "msg"]',
72
72
  EXIT.USAGE_ERROR,
73
73
  ), json);
74
74
  return;
@@ -116,7 +116,7 @@ export default async function contractCommand(args) {
116
116
  rounds,
117
117
  message: status
118
118
  ? `Contract ${status} (round ${rounds}/5)`
119
- : 'No sprint-contract.md found. Run: harness-dev contract propose',
119
+ : 'No sprint-contract.md found. Run: dev-harness contract propose',
120
120
  }) + '\n');
121
121
  return;
122
122
  }
@@ -124,7 +124,7 @@ export default async function contractCommand(args) {
124
124
  if (status) {
125
125
  process.stdout.write(`Contract status: ${status} (round ${rounds}/5)\n`);
126
126
  } else {
127
- process.stdout.write('No sprint-contract.md found. Run: harness-dev contract propose\n');
127
+ process.stdout.write('No sprint-contract.md found. Run: dev-harness contract propose\n');
128
128
  }
129
129
  return;
130
130
  }
@@ -12,7 +12,7 @@
12
12
  * Also reads harness-config.json agentTool field if present.
13
13
  *
14
14
  * Usage:
15
- * harness-dev detect-tool [--target <dir>] [--json]
15
+ * dev-harness detect-tool [--target <dir>] [--json]
16
16
  */
17
17
  import { existsSync } from 'node:fs';
18
18
  import { resolve } from 'node:path';
@@ -80,7 +80,7 @@ export default async function detectToolCommand(args) {
80
80
  status: 'ok',
81
81
  message: detected.length > 0
82
82
  ? `Detected ${detected.length} agent tool(s): ${detected.join(', ')}`
83
- : 'No agent tools detected. Run: harness-dev init',
83
+ : 'No agent tools detected. Run: dev-harness init',
84
84
  available: detected,
85
85
  configured: configuredTool,
86
86
  recommended,
@@ -104,7 +104,7 @@ export default async function detectToolCommand(args) {
104
104
  }
105
105
  } else {
106
106
  emitHuman(` No agent tools detected.\n`);
107
- emitHuman(` Run: harness-dev init to scaffold a project.\n`);
107
+ emitHuman(` Run: dev-harness init to scaffold a project.\n`);
108
108
  }
109
109
  if (hasAgentsMd) {
110
110
  emitHuman(`\n AGENTS.md present — tools that read it natively are available.\n`);
@@ -6,7 +6,7 @@
6
6
  * init.sh, progress.md, sprint-contract.md) plus project files (feature_list.json,
7
7
  * feature-list.schema.json, session-handoff.md, etc.), git init, .gitignore.
8
8
  *
9
- * Usage: harness-dev init [--stack <name>] [--target <dir>] [--agent-tool <name>] [--force] [--no-git] [--json]
9
+ * Usage: dev-harness init [--stack <name>] [--target <dir>] [--agent-tool <name>] [--force] [--no-git] [--json]
10
10
  */
11
11
  import { resolve, join } from 'node:path';
12
12
  import {
@@ -2,8 +2,8 @@
2
2
  * learn — Append a lesson to progress.md.
3
3
  *
4
4
  * Usage:
5
- * harness-dev learn "Lesson text here"
6
- * harness-dev learn "Lesson text" --json
5
+ * dev-harness learn "Lesson text here"
6
+ * dev-harness learn "Lesson text" --json
7
7
  */
8
8
  import { CliError, EXIT, die } from '../lib/errors.mjs';
9
9
  import { appendLesson } from '../lib/progress.mjs';
@@ -17,7 +17,7 @@ export default async function learnCommand(args) {
17
17
  if (!message) {
18
18
  die(
19
19
  new CliError(
20
- 'Lesson message required.\n Example: harness-dev learn "Token refresh gotcha — accepts access_token in body"',
20
+ 'Lesson message required.\n Example: dev-harness learn "Token refresh gotcha — accepts access_token in body"',
21
21
  EXIT.USAGE_ERROR,
22
22
  ),
23
23
  json,
@@ -4,7 +4,7 @@
4
4
  * Sets config.paused = true. The outer loop checks this
5
5
  * before starting a new phase in autopilot mode.
6
6
  *
7
- * Usage: harness-dev pause [--json]
7
+ * Usage: dev-harness pause [--json]
8
8
  */
9
9
  import { set } from '../lib/state.mjs';
10
10
  import { parseCommandArgs } from '../lib/command-helpers.mjs';
@@ -5,8 +5,8 @@
5
5
  * then triggers the outer loop for autopilot advancement.
6
6
  *
7
7
  * Usage:
8
- * harness-dev phase <name>
9
- * harness-dev phase <name> --json
8
+ * dev-harness phase <name>
9
+ * dev-harness phase <name> --json
10
10
  */
11
11
  import { CliError, EXIT, die } from '../lib/errors.mjs';
12
12
  import { transitionPhase, getPhaseOrder, loadConfig } from '../lib/state.mjs';
@@ -51,7 +51,7 @@ export default async function phaseCommand(args) {
51
51
  const { config: preConfig, ok: preOk } = loadConfig(targetDir);
52
52
  const preMode = preOk ? (preConfig.mode ?? 'copilot') : 'copilot';
53
53
  if (preOk && preConfig.paused && preMode === 'autopilot') {
54
- const msg = 'Pipeline is paused. Run: harness-dev resume';
54
+ const msg = 'Pipeline is paused. Run: dev-harness resume';
55
55
  if (json) {
56
56
  process.stdout.write(JSON.stringify({
57
57
  command: 'phase',
@@ -140,11 +140,11 @@ export default async function phaseCommand(args) {
140
140
  if (pipelineResult.status === 'complete') {
141
141
  process.stdout.write(`\n✓ Pipeline complete. All phases done.\n`);
142
142
  } else if (pipelineResult.status === 'instruction') {
143
- process.stdout.write(`\nNext: harness-dev phase ${pipelineResult.nextPhase}\n`);
143
+ process.stdout.write(`\nNext: dev-harness phase ${pipelineResult.nextPhase}\n`);
144
144
  }
145
145
  } else if (nextPhase) {
146
146
  // Copilot: print next step
147
- process.stdout.write(`Next: harness-dev phase ${nextPhase}\n`);
147
+ process.stdout.write(`Next: dev-harness phase ${nextPhase}\n`);
148
148
  // Auto-prompt: controlled by two independent flags:
149
149
  // autoPrompt=true → show the prompt
150
150
  // confirmGates=true → require y/n answer before continuing
@@ -158,7 +158,7 @@ export default async function phaseCommand(args) {
158
158
  process.stdout.write(`\n✓ Pipeline complete. All phases done.\n`);
159
159
  }
160
160
  } else if (answer === false) {
161
- process.stdout.write(` Staying in ${phase.toUpperCase()}. Run: harness-dev phase ${nextPhase} when ready.\n`);
161
+ process.stdout.write(` Staying in ${phase.toUpperCase()}. Run: dev-harness phase ${nextPhase} when ready.\n`);
162
162
  }
163
163
  // null = no TTY, skipped
164
164
  } else {
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Sets config.paused = false. Allows autopilot to continue.
5
5
  *
6
- * Usage: harness-dev resume [--json]
6
+ * Usage: dev-harness resume [--json]
7
7
  */
8
8
  import { set } from '../lib/state.mjs';
9
9
  import { parseCommandArgs } from '../lib/command-helpers.mjs';
@@ -19,14 +19,14 @@ export default async function resumeCommand(args) {
19
19
  command: 'resume',
20
20
  status: result.ok ? 'ok' : 'error',
21
21
  message: result.ok
22
- ? 'Pipeline resumed. Run: harness-dev phase <name> to continue.'
22
+ ? 'Pipeline resumed. Run: dev-harness phase <name> to continue.'
23
23
  : (result.error || 'Failed to resume'),
24
24
  });
25
25
  return;
26
26
  }
27
27
 
28
28
  if (result.ok) {
29
- emitHuman('✓ Pipeline resumed. Run: harness-dev phase <name> to continue.\n');
29
+ emitHuman('✓ Pipeline resumed. Run: dev-harness phase <name> to continue.\n');
30
30
  } else {
31
31
  emitHumanError(`✗ ${result.error}\n`);
32
32
  }
@@ -13,7 +13,7 @@
13
13
  * manual/<label> — User-created manual checkpoints
14
14
  * recovery/* — Recovery branches (for informational display)
15
15
  *
16
- * Usage: harness-dev rollback <subcommand> [checkpoint]
16
+ * Usage: dev-harness rollback <subcommand> [checkpoint]
17
17
  */
18
18
  import { die, CliError, EXIT } from '../lib/errors.mjs';
19
19
  import { execGit, getGitRoot } from '../lib/git.mjs';
@@ -67,12 +67,12 @@ export default async function rollbackCommand(args) {
67
67
  const sub = args.subcommand;
68
68
 
69
69
  if (!sub || !SUBCOMMANDS.includes(sub)) {
70
- die(new CliError(`Usage: harness-dev rollback ${SUBCOMMANDS.join('|')}`, EXIT.USAGE_ERROR), json);
70
+ die(new CliError(`Usage: dev-harness rollback ${SUBCOMMANDS.join('|')}`, EXIT.USAGE_ERROR), json);
71
71
  return;
72
72
  }
73
73
 
74
74
  if (sub !== 'list' && args.positionals.length < 1) {
75
- die(new CliError(`Usage: harness-dev rollback ${sub} <checkpoint>`, EXIT.USAGE_ERROR), json);
75
+ die(new CliError(`Usage: dev-harness rollback ${sub} <checkpoint>`, EXIT.USAGE_ERROR), json);
76
76
  return;
77
77
  }
78
78
 
@@ -118,7 +118,7 @@ export default async function rollbackCommand(args) {
118
118
  } else {
119
119
  if (checkpoints.length === 0 && recoveryBranches.length === 0) {
120
120
  process.stdout.write('No checkpoints found. Phase tags (phase/*) and iteration tags (iter/*) are created automatically when auto-tagging is enabled.\n');
121
- process.stdout.write('Manual checkpoints: harness-dev checkpoint create <label>\n');
121
+ process.stdout.write('Manual checkpoints: dev-harness checkpoint create <label>\n');
122
122
  } else {
123
123
  if (checkpoints.length > 0) {
124
124
  process.stdout.write('Checkpoints:\n');
@@ -146,7 +146,7 @@ export default async function rollbackCommand(args) {
146
146
  // Verify the tag exists
147
147
  const tagCheck = execGit(`git rev-parse --verify "${checkpoint}^{commit}"`, gitRoot);
148
148
  if (!tagCheck.ok) {
149
- const msg = `Checkpoint "${checkpoint}" not found. Run: harness-dev rollback list`;
149
+ const msg = `Checkpoint "${checkpoint}" not found. Run: dev-harness rollback list`;
150
150
  if (json) {
151
151
  process.stdout.write(JSON.stringify({ command: 'rollback', subcommand: 'to', checkpoint, status: 'error', message: msg }) + '\n');
152
152
  } else {
@@ -205,7 +205,7 @@ export default async function rollbackCommand(args) {
205
205
  // Verify the tag exists
206
206
  const tagCheck = execGit(`git rev-parse --verify "${checkpoint}^{commit}"`, gitRoot);
207
207
  if (!tagCheck.ok) {
208
- const msg = `Checkpoint "${checkpoint}" not found. Run: harness-dev rollback list`;
208
+ const msg = `Checkpoint "${checkpoint}" not found. Run: dev-harness rollback list`;
209
209
  if (json) {
210
210
  process.stdout.write(JSON.stringify({ command: 'rollback', subcommand: 'branch', checkpoint, status: 'error', message: msg }) + '\n');
211
211
  } else {
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * set-mode — Switch between copilot and autopilot.
3
3
  *
4
- * Usage: harness-dev set-mode <mode>
5
- * harness-dev set-mode autopilot
6
- * harness-dev set-mode copilot
7
- * harness-dev set-mode autopilot --json
4
+ * Usage: dev-harness set-mode <mode>
5
+ * dev-harness set-mode autopilot
6
+ * dev-harness set-mode copilot
7
+ * dev-harness set-mode autopilot --json
8
8
  */
9
9
  import { die, CliError, EXIT } from '../lib/errors.mjs';
10
10
  import { set, loadConfig, getPhaseOrder } from '../lib/state.mjs';
@@ -19,7 +19,7 @@ export default async function setModeCommand(args) {
19
19
  if (!mode || !valid.includes(mode)) {
20
20
  die(
21
21
  new CliError(
22
- `Mode required. Valid: ${valid.join(', ')}.\n Example: harness-dev set-mode autopilot`,
22
+ `Mode required. Valid: ${valid.join(', ')}.\n Example: dev-harness set-mode autopilot`,
23
23
  EXIT.USAGE_ERROR,
24
24
  ),
25
25
  json,
@@ -4,7 +4,7 @@
4
4
  * Reads harness-config.json via state.mjs for live project state,
5
5
  * plus runs stack detection and gate checks for current status.
6
6
  *
7
- * Usage: harness-dev status [--json] [--target <dir>]
7
+ * Usage: dev-harness status [--json] [--target <dir>]
8
8
  */
9
9
  import { resolve, basename } from 'node:path';
10
10
  import { detectStack } from '../lib/detect-stack.mjs';
@@ -61,7 +61,7 @@ export default async function statusCommand(args) {
61
61
  status: 'ok',
62
62
  message: configOk
63
63
  ? `Phase: ${phase || 'not started'}, Stack: ${stack.label}`
64
- : 'No harness/config.json found — run harness-dev init',
64
+ : 'No harness/config.json found — run dev-harness init',
65
65
  project: basename(targetDir),
66
66
  stack: stack.name,
67
67
  stackLabel: stack.label,
@@ -150,19 +150,19 @@ function gateStatusLabel(status, passing, total) {
150
150
 
151
151
  function determineNextAction(targetDir, configOk, config, phase, gateStatus) {
152
152
  if (!configOk) {
153
- return 'Run: harness-dev init';
153
+ return 'Run: dev-harness init';
154
154
  }
155
155
  if (!phase) {
156
- return 'Run: harness-dev phase define to start';
156
+ return 'Run: dev-harness phase define to start';
157
157
  }
158
158
  if (gateStatus === 'fail') {
159
- return 'Run: harness-dev validate to re-check';
159
+ return 'Run: dev-harness validate to re-check';
160
160
  }
161
161
  // Determine next phase
162
162
  const order = ['define', 'plan', 'build', 'verify', 'review', 'ship'];
163
163
  const idx = order.indexOf(phase);
164
164
  if (idx >= 0 && idx < order.length - 1) {
165
- return `Run: harness-dev phase ${order[idx + 1]}`;
165
+ return `Run: dev-harness phase ${order[idx + 1]}`;
166
166
  }
167
- return `Run: harness-dev validate`;
167
+ return `Run: dev-harness validate`;
168
168
  }
@@ -5,15 +5,15 @@
5
5
  * Otherwise runs phase-specific checks and reports results.
6
6
  *
7
7
  * Usage:
8
- * harness-dev validate — check current phase
9
- * harness-dev validate --json — machine-readable output
10
- * harness-dev validate --phase X — check specific phase
8
+ * dev-harness validate — check current phase
9
+ * dev-harness validate --json — machine-readable output
10
+ * dev-harness validate --phase X — check specific phase
11
11
  *
12
12
  * Examples:
13
- * harness-dev validate
13
+ * dev-harness validate
14
14
  * # → BUILD Gate: PASS — 3/3 checks pass
15
15
  *
16
- * harness-dev validate --json
16
+ * dev-harness validate --json
17
17
  * # → {"phase":"build","checks":[...],"overall":false,"failures":["lint"]}
18
18
  */
19
19
  import { resolve } from 'node:path';
@@ -53,7 +53,7 @@ export default async function validateCommand(args) {
53
53
  if (task) { out.task = task; }
54
54
  process.stdout.write(JSON.stringify(out) + '\n');
55
55
  } else {
56
- process.stdout.write('Gates disabled. Enable with: harness-dev config set gates.enabled true\n');
56
+ process.stdout.write('Gates disabled. Enable with: dev-harness config set gates.enabled true\n');
57
57
  }
58
58
  return;
59
59
  }
@@ -62,7 +62,7 @@ export default async function validateCommand(args) {
62
62
  if (!phase) {
63
63
  die(
64
64
  new CliError(
65
- 'No phase found in config. Run: harness-dev init or harness-dev phase <name>',
65
+ 'No phase found in config. Run: dev-harness init or dev-harness phase <name>',
66
66
  EXIT.VALIDATION_FAILURE,
67
67
  ),
68
68
  json,
@@ -8,7 +8,7 @@
8
8
  * prune — git worktree prune (remove orphaned metadata)
9
9
  * remove <name> — git worktree remove + optionally delete branch
10
10
  *
11
- * Usage: harness-dev worktree <subcommand> [name] [options]
11
+ * Usage: dev-harness worktree <subcommand> [name] [options]
12
12
  */
13
13
  import { existsSync } from 'node:fs';
14
14
  import { resolve, dirname } from 'node:path';
@@ -25,13 +25,13 @@ export default async function worktreeCommand(args) {
25
25
  const sub = args.subcommand;
26
26
 
27
27
  if (!sub || !SUBCOMMANDS.includes(sub)) {
28
- die(new CliError(`Usage: harness-dev worktree ${SUBCOMMANDS.join('|')}`, EXIT.USAGE_ERROR), json);
28
+ die(new CliError(`Usage: dev-harness worktree ${SUBCOMMANDS.join('|')}`, EXIT.USAGE_ERROR), json);
29
29
  return;
30
30
  }
31
31
 
32
32
  const gitRoot = getGitRoot(targetDir);
33
33
  if (!gitRoot) {
34
- const msg = 'Not inside a git repository. Run: git init first or harness-dev init';
34
+ const msg = 'Not inside a git repository. Run: git init first or dev-harness init';
35
35
  if (json) {
36
36
  process.stdout.write(JSON.stringify({ command: 'worktree', subcommand: sub, status: 'error', message: msg }) + '\n');
37
37
  } else {
@@ -44,7 +44,7 @@ export default async function worktreeCommand(args) {
44
44
  if (sub === 'create') {
45
45
  const name = args.positionals[0];
46
46
  if (!name) {
47
- die(new CliError('Usage: harness-dev worktree create <name>', EXIT.USAGE_ERROR), json);
47
+ die(new CliError('Usage: dev-harness worktree create <name>', EXIT.USAGE_ERROR), json);
48
48
  return;
49
49
  }
50
50
 
@@ -88,7 +88,7 @@ export default async function worktreeCommand(args) {
88
88
 
89
89
  // Scaffold harness in the new worktree — run full init with parent's detected stack
90
90
  const stack = detectStack(worktreePath).name;
91
- const harnessDevPath = new URL('../harness-dev.mjs', import.meta.url).pathname;
91
+ const harnessDevPath = new URL('../dev-harness.mjs', import.meta.url).pathname;
92
92
  const initResult = execGit(
93
93
  `node "${harnessDevPath}" init --stack "${stack}" --force --no-git --json`,
94
94
  worktreePath,
@@ -232,7 +232,7 @@ export default async function worktreeCommand(args) {
232
232
  if (sub === 'remove') {
233
233
  const name = args.positionals[0];
234
234
  if (!name) {
235
- die(new CliError('Usage: harness-dev worktree remove <name>', EXIT.USAGE_ERROR), json);
235
+ die(new CliError('Usage: dev-harness worktree remove <name>', EXIT.USAGE_ERROR), json);
236
236
  return;
237
237
  }
238
238
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * harness-dev — Agent-agnostic development harness CLI.
3
+ * dev-harness — Agent-agnostic development harness CLI.
4
4
  *
5
5
  * Entry point. Parses args, routes to command handler,
6
6
  * formats output (human or JSON), handles errors.
@@ -68,7 +68,7 @@ async function main() {
68
68
  const loader = COMMANDS[args.command];
69
69
  if (!loader) {
70
70
  throw new CliError(
71
- `Unknown command "${args.command}". See harness-dev --help`,
71
+ `Unknown command "${args.command}". See dev-harness --help`,
72
72
  EXIT.USAGE_ERROR
73
73
  );
74
74
  }
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Single source of truth for parameter descriptions, types, allowed values,
5
5
  * and defaults. Used by:
6
- * - `harness-dev config list` — interactive parameter listing
6
+ * - `dev-harness config list` — interactive parameter listing
7
7
  * - docs/CONFIGURATION.md — generated documentation
8
8
  * - config command — validation of set values
9
9
  *
@@ -198,7 +198,7 @@ export const CONFIG_PARAMS = [
198
198
  group: 'Runtime State',
199
199
  label: 'Current Phase',
200
200
  type: 'string',
201
- description: 'Current pipeline phase. Managed by harness-dev phase — do not edit.',
201
+ description: 'Current pipeline phase. Managed by dev-harness phase — do not edit.',
202
202
  default: null,
203
203
  editable: false,
204
204
  },
@@ -168,7 +168,7 @@ ${existingStatus || `## Agreement Status
168
168
  export function reviewContract(targetDir, decision, notes) {
169
169
  const path = CONTRACT_PATH(targetDir);
170
170
  if (!existsSync(path)) {
171
- return { ok: false, error: 'No sprint-contract.md found. Run: harness-dev contract propose first', escalated: false };
171
+ return { ok: false, error: 'No sprint-contract.md found. Run: dev-harness contract propose first', escalated: false };
172
172
  }
173
173
 
174
174
  try {
@@ -276,7 +276,7 @@ export function validateContract(targetDir) {
276
276
  return {
277
277
  name: 'contract-agreed',
278
278
  pass: false,
279
- detail: 'Sprint contract not yet proposed. Run: harness-dev contract propose',
279
+ detail: 'Sprint contract not yet proposed. Run: dev-harness contract propose',
280
280
  };
281
281
  }
282
282
 
@@ -301,6 +301,6 @@ export function validateContract(targetDir) {
301
301
  return {
302
302
  name: 'contract-agreed',
303
303
  pass: false,
304
- detail: `Sprint contract ${noun} (round ${rounds}/${MAX_NEGOTIATION_ROUNDS}). Run: harness-dev contract review`,
304
+ detail: `Sprint contract ${noun} (round ${rounds}/${MAX_NEGOTIATION_ROUNDS}). Run: dev-harness contract review`,
305
305
  };
306
306
  }
package/cli/lib/gates.mjs CHANGED
@@ -5,7 +5,7 @@
5
5
  * that return { name, pass, detail }.
6
6
  *
7
7
  * Phase gates are disabled by default (gates.enabled: false).
8
- * Run via: harness-dev validate
8
+ * Run via: dev-harness validate
9
9
  *
10
10
  * Usage:
11
11
  * import { runChecks, getPhase } from './gates.mjs';
package/cli/lib/help.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  * Help text builder — centralized to keep all formatting in one place.
3
3
  */
4
4
 
5
- const USAGE = `Usage: harness-dev <command> [options]
5
+ const USAGE = `Usage: dev-harness <command> [options]
6
6
 
7
7
  Pipeline commands:
8
8
  init Scaffold full harness in current directory
@@ -53,14 +53,14 @@ Exit codes:
53
53
  2 Usage error (bad arguments)
54
54
  3 Internal error`;
55
55
 
56
- const VERSION = '1.1.0';
56
+ const VERSION = '1.2.0';
57
57
 
58
58
  // Help text for JSON output
59
59
  function buildJsonHelp() {
60
60
  return {
61
61
  help: true,
62
62
  version: VERSION,
63
- usage: 'harness-dev <command> [options]',
63
+ usage: 'dev-harness <command> [options]',
64
64
  commands: {
65
65
  init: 'Scaffold full harness in current directory',
66
66
  status: 'Show current phase + gate state + detected stack',
@@ -111,12 +111,12 @@ export function versionText(json = false) {
111
111
  if (json) {
112
112
  return JSON.stringify({ version: VERSION });
113
113
  }
114
- return `harness-dev v${VERSION}`;
114
+ return `dev-harness v${VERSION}`;
115
115
  }
116
116
 
117
- // Per-command help text (for `harness-dev <command> --help`).
117
+ // Per-command help text (for `dev-harness <command> --help`).
118
118
  const COMMAND_HELP = {
119
- init: `Usage: harness-dev init [--stack <name>] [--target <dir>] [--force] [--no-git] [--json]
119
+ init: `Usage: dev-harness init [--stack <name>] [--target <dir>] [--force] [--no-git] [--json]
120
120
 
121
121
  Scaffold a full harness in the target directory:
122
122
  - Detects stack (or use --stack)
@@ -131,7 +131,7 @@ Flags:
131
131
  --no-git Skip git init
132
132
  --json JSON output`,
133
133
 
134
- status: `Usage: harness-dev status [--target <dir>] [--json]
134
+ status: `Usage: dev-harness status [--target <dir>] [--json]
135
135
 
136
136
  Show current phase, gate state, detected stack, recent lessons, and next action.
137
137
 
@@ -139,7 +139,7 @@ Flags:
139
139
  --target <dir> Project directory (default: cwd)
140
140
  --json JSON output`,
141
141
 
142
- phase: `Usage: harness-dev phase <name> [--target <dir>] [--git-ops] [--json]
142
+ phase: `Usage: dev-harness phase <name> [--target <dir>] [--git-ops] [--json]
143
143
 
144
144
  Invoke a phase. Valid phases: define, plan, build, verify, simplify, review, ship.
145
145
 
@@ -148,7 +148,7 @@ Flags:
148
148
  --git-ops Execute git reset --hard + clean on retry (fresh context)
149
149
  --json JSON output`,
150
150
 
151
- validate: `Usage: harness-dev validate [--phase <name>] [--feature <id> --task <id>] [--target <dir>] [--json]
151
+ validate: `Usage: dev-harness validate [--phase <name>] [--feature <id> --task <id>] [--target <dir>] [--json]
152
152
 
153
153
  Run gate checks for the current (or specified) phase.
154
154
 
@@ -159,39 +159,39 @@ Flags:
159
159
  --target <dir> Project directory (default: cwd)
160
160
  --json JSON output`,
161
161
 
162
- 'set-mode': `Usage: harness-dev set-mode <copilot|autopilot> [--target <dir>] [--json]
162
+ 'set-mode': `Usage: dev-harness set-mode <copilot|autopilot> [--target <dir>] [--json]
163
163
 
164
164
  Switch execution mode. Autopilot requires DEFINE phase or later.`,
165
165
 
166
- config: `Usage: harness-dev config list [--target <dir>] [--json]
167
- harness-dev config get [key] [--target <dir>] [--json]
168
- harness-dev config set <key> <value> [--target <dir>] [--json]
166
+ config: `Usage: dev-harness config list [--target <dir>] [--json]
167
+ dev-harness config get [key] [--target <dir>] [--json]
168
+ dev-harness config set <key> <value> [--target <dir>] [--json]
169
169
 
170
170
  List all parameters with descriptions, or get/set values via dot-notation.
171
171
  Use 'config list' to see all configurable parameters, their current values,
172
172
  types, allowed options, and descriptions.
173
173
 
174
174
  Examples:
175
- harness-dev config list
176
- harness-dev config list --json
177
- harness-dev config get gates.enabled
178
- harness-dev config set gates.enabled true
179
- harness-dev config set mode autopilot
180
- harness-dev config set maxRetries 5`,
175
+ dev-harness config list
176
+ dev-harness config list --json
177
+ dev-harness config get gates.enabled
178
+ dev-harness config set gates.enabled true
179
+ dev-harness config set mode autopilot
180
+ dev-harness config set maxRetries 5`,
181
181
 
182
- pause: `Usage: harness-dev pause [--target <dir>] [--json]
182
+ pause: `Usage: dev-harness pause [--target <dir>] [--json]
183
183
 
184
184
  Pause autopilot execution. Autopilot stops after the current phase gate.`,
185
185
 
186
- resume: `Usage: harness-dev resume [--target <dir>] [--json]
186
+ resume: `Usage: dev-harness resume [--target <dir>] [--json]
187
187
 
188
188
  Resume autopilot execution.`,
189
189
 
190
- learn: `Usage: harness-dev learn "<message>" [--target <dir>] [--json]
190
+ learn: `Usage: dev-harness learn "<message>" [--target <dir>] [--json]
191
191
 
192
192
  Append a lesson to the Lessons section of progress.md.`,
193
193
 
194
- contract: `Usage: harness-dev contract <subcommand> [options] [--target <dir>] [--json]
194
+ contract: `Usage: dev-harness contract <subcommand> [options] [--target <dir>] [--json]
195
195
 
196
196
  Subcommands:
197
197
  propose --scope "..." [--exclusions "..."] [--criteria "..."] Generator proposes
@@ -199,7 +199,7 @@ Subcommands:
199
199
  status Show contract state
200
200
  escalate [--reason "..."] Human adjudication`,
201
201
 
202
- worktree: `Usage: harness-dev worktree <subcommand> [options] [--target <dir>] [--json]
202
+ worktree: `Usage: dev-harness worktree <subcommand> [options] [--target <dir>] [--json]
203
203
 
204
204
  Subcommands:
205
205
  create <name> Create isolated worktree for a feature
@@ -207,25 +207,25 @@ Subcommands:
207
207
  prune Remove orphaned worktrees
208
208
  remove <name> Clean up worktree (optionally merge branch)`,
209
209
 
210
- rollback: `Usage: harness-dev rollback <subcommand> [checkpoint] [--target <dir>] [--json]
210
+ rollback: `Usage: dev-harness rollback <subcommand> [checkpoint] [--target <dir>] [--json]
211
211
 
212
212
  Subcommands:
213
213
  list Show available checkpoints
214
214
  to <tag> Restore state to a checkpoint
215
215
  branch <tag> Branch off a good iteration`,
216
216
 
217
- checkpoint: `Usage: harness-dev checkpoint create <label> [--force] [--target <dir>] [--json]
217
+ checkpoint: `Usage: dev-harness checkpoint create <label> [--force] [--target <dir>] [--json]
218
218
 
219
219
  Create a manual checkpoint tag (manual/<label>). Requires clean working tree
220
220
  unless --force is given.`,
221
221
 
222
- 'detect-tool': `Usage: harness-dev detect-tool [--target <dir>] [--json]
222
+ 'detect-tool': `Usage: dev-harness detect-tool [--target <dir>] [--json]
223
223
 
224
224
  Scan the project for agent-tool files (CLAUDE.md, .cursorrules, AGENTS.md, etc.)
225
225
  and report which coding agents are available. Recommends a tool based on config
226
226
  and detected files.`,
227
227
 
228
- help: `Usage: harness-dev help
228
+ help: `Usage: dev-harness help
229
229
 
230
230
  Show the global help message. Alias for --help.`,
231
231
  };
@@ -259,7 +259,7 @@ export function runPhase(targetDir, phase, options = {}) {
259
259
  // Human output
260
260
  process.stdout.write(output);
261
261
  process.stdout.write(`\n═══════════════════════════════════════\n`);
262
- process.stdout.write(`Run: harness-dev validate --feature ${feature.id} --task ${task.id}\n`);
262
+ process.stdout.write(`Run: dev-harness validate --feature ${feature.id} --task ${task.id}\n`);
263
263
  process.stdout.write(`═══════════════════════════════════════\n`);
264
264
 
265
265
  return {
@@ -298,7 +298,7 @@ export function runPhase(targetDir, phase, options = {}) {
298
298
  // Human output
299
299
  process.stdout.write(output);
300
300
  process.stdout.write(`\n═══════════════════════════════════════\n`);
301
- process.stdout.write(`Run: harness-dev validate\n`);
301
+ process.stdout.write(`Run: dev-harness validate\n`);
302
302
  process.stdout.write(`═══════════════════════════════════════\n`);
303
303
 
304
304
  return {
@@ -98,7 +98,7 @@ export function continuePipeline(targetDir, completedPhase, options = {}) {
98
98
 
99
99
  if (mode === 'copilot') {
100
100
  // Copilot: print instructions for next phase
101
- const msg = `${completedPhase.toUpperCase()} complete. Next: harness-dev phase ${nextPhase}`;
101
+ const msg = `${completedPhase.toUpperCase()} complete. Next: dev-harness phase ${nextPhase}`;
102
102
  if (json) {
103
103
  return {
104
104
  ok: true,
@@ -128,7 +128,7 @@ export function continuePipeline(targetDir, completedPhase, options = {}) {
128
128
 
129
129
  // Re-check pause before auto-advancing (user may have paused during phase execution)
130
130
  if (config.paused) {
131
- const msg = `Autopilot paused after "${completedPhase}". Run: harness-dev resume`;
131
+ const msg = `Autopilot paused after "${completedPhase}". Run: dev-harness resume`;
132
132
  if (verbose && !json) {
133
133
  process.stdout.write(`\n ⏸ ${msg}\n`);
134
134
  }
@@ -205,7 +205,7 @@ export function continuePipeline(targetDir, completedPhase, options = {}) {
205
205
  * Run the full autopilot pipeline from current state through SHIP.
206
206
  *
207
207
  * This is a convenience wrapper — normally autopilot is triggered
208
- * by calling `harness-dev phase <name>` while in autopilot mode.
208
+ * by calling `dev-harness phase <name>` while in autopilot mode.
209
209
  *
210
210
  * @param {string} targetDir
211
211
  * @param {object} [options]
@@ -171,7 +171,7 @@ export function buildDeliverableRetryOutput(phase, mode, maxRetries, resetOnRetr
171
171
  }
172
172
 
173
173
  out += `\n`;
174
- out += `When done, run: harness-dev validate\n`;
174
+ out += `When done, run: dev-harness validate\n`;
175
175
  if (resetOnRetry) {out += `Git reset on retry: enabled\n`;}
176
176
  if (autoCommit) {out += `Auto-commit: enabled\n`;}
177
177
  return out;
@@ -418,7 +418,7 @@ export function getVersionFileContent(stack) {
418
418
  * Return .gitignore content for the given stack.
419
419
  */
420
420
  export function getGitignoreContent(stack) {
421
- return `# Harness runtime state (regenerated by harness-dev)
421
+ return `# Harness runtime state (regenerated by dev-harness)
422
422
  harness/config.json
423
423
  harness/features/feature-list.json
424
424
  harness/progress.md
package/cli/lib/state.mjs CHANGED
@@ -124,7 +124,7 @@ export function loadConfig(targetDir) {
124
124
  config: defaults,
125
125
  path: cfgPath,
126
126
  ok: false,
127
- error: `Not found: ${cfgPath}. Run: harness-dev init`,
127
+ error: `Not found: ${cfgPath}. Run: dev-harness init`,
128
128
  };
129
129
  }
130
130
 
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "dev-harness-cli",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Agent-agnostic software development harness CLI — scaffold, phase orchestration, gate validation for any coding agent",
5
5
  "type": "module",
6
6
  "bin": {
7
- "harness-dev": "cli/harness-dev.mjs"
7
+ "dev-harness": "cli/dev-harness.mjs"
8
8
  },
9
9
  "files": [
10
10
  "cli/",
@@ -39,10 +39,10 @@
39
39
  "scripts": {
40
40
  "lint": "eslint cli/",
41
41
  "lint:fix": "eslint cli/ --fix",
42
- "check": "node --check cli/harness-dev.mjs && echo 'Syntax OK'",
42
+ "check": "node --check cli/dev-harness.mjs && echo 'Syntax OK'",
43
43
  "test": "node test/run-all.mjs",
44
44
  "test:verbose": "node test/run-all.mjs --verbose",
45
- "postinstall": "node -e \"try{process.stdout.write('harness-dev installed. Run: npx harness-dev --help\\n')}catch(e){}\""
45
+ "postinstall": "node -e \"try{process.stdout.write('dev-harness installed. Run: npx dev-harness --help\\n')}catch(e){}\""
46
46
  },
47
47
  "devDependencies": {
48
48
  "@eslint/js": "^10.0.1",
@@ -3,9 +3,9 @@
3
3
  ## Quick Start
4
4
 
5
5
  ```bash
6
- harness-dev status # Where are we?
7
- harness-dev phase <name> # Invoke a phase
8
- harness-dev validate # Check gate criteria
6
+ dev-harness status # Where are we?
7
+ dev-harness phase <name> # Invoke a phase
8
+ dev-harness validate # Check gate criteria
9
9
  ```
10
10
 
11
11
  ## Project
@@ -50,8 +50,8 @@ All harness-managed files live under `harness/` (except `AGENTS.md` which stays
50
50
  2. Read `harness/progress.md` + this file before each operation
51
51
  3. Commit frequently — each iteration is a checkpoint
52
52
  4. If unsure → read the role guide in `harness/docs/agents/`
53
- 5. Never skip gates — run `harness-dev validate` after each phase
54
- 6. Fresh context per retry — pass `--git-ops` to `harness-dev phase <name>` to auto-reset the working tree on retry (off by default; agent-agnostic)
53
+ 5. Never skip gates — run `dev-harness validate` after each phase
54
+ 6. Fresh context per retry — pass `--git-ops` to `dev-harness phase <name>` to auto-reset the working tree on retry (off by default; agent-agnostic)
55
55
  7. **No files in project root** unless they are harness-managed files (listed in Key Files above) or standard project files (README.md, LICENSE, CHANGELOG.md, CONTRIBUTING.md, .gitignore, and the stack config file like package.json/pyproject.toml/Cargo.toml). All source code, tests, scripts, and docs go in subdirectories.
56
56
  8. **Structure from the start** — create folders for your work on day one and stick to them. Suggested layout: `src/` (source), `tests/` (tests), `docs/` (documentation), `scripts/` (automation). Do not dump files at root "temporarily" — there is no temporary.
57
57
  9. **No orphaned files** — every file you create must have a clear purpose and be referenced by imports, configs, docs, or the build system. If you create a file, wire it in immediately. Delete files you stop using.
@@ -75,4 +75,4 @@ jobs:
75
75
  steps:
76
76
  - uses: actions/checkout@v4
77
77
  - run: npm install -g dev-harness-cli
78
- - run: harness-dev validate --json
78
+ - run: dev-harness validate --json
@@ -55,5 +55,5 @@ gate:
55
55
  image: node:lts
56
56
  script:
57
57
  - npm install -g dev-harness-cli
58
- - harness-dev validate --json
58
+ - dev-harness validate --json
59
59
  needs: [coverage]
@@ -10,4 +10,4 @@ You implement. You produce artifacts. You self-check.
10
10
  - In BUILD: implement ONE task at a time, then validate
11
11
  - In VERIFY: run the full test suite
12
12
  - In SIMPLIFY: adopt the Simplifier persona (see simplifier.md)
13
- - When done: call `harness-dev validate`
13
+ - When done: call `dev-harness validate`
@@ -10,4 +10,4 @@ You refactor. You clean. You never change behavior.
10
10
  - Break long functions (~40 line threshold)
11
11
  - Rename unclear variables
12
12
  - ⚠ All tests must still pass after your changes
13
- - Run `harness-dev validate` after each feature to confirm gate
13
+ - Run `dev-harness validate` after each feature to confirm gate
@@ -21,14 +21,14 @@ fresh context. Only when all features pass does the phase gate run.
21
21
  1. Read `progress.md`, `AGENTS.md`, `sprint-contract.md`.
22
22
  2. Pick next feature where `passes === false`.
23
23
  3. Implement the feature's tasks.
24
- 4. Run `harness-dev validate --feature <name> --task <id>` per task.
24
+ 4. Run `dev-harness validate --feature <name> --task <id>` per task.
25
25
  5. On pass: mark feature `passes: true`, commit, append lesson to `progress.md`.
26
26
  6. On fail (≤ `maxRetries`): retry with fresh context (git reset if `--git-ops`).
27
27
  7. On fail (> `maxRetries`): escalate to human.
28
28
 
29
29
  ## Exit Gate
30
30
 
31
- Run `harness-dev validate` — checks:
31
+ Run `dev-harness validate` — checks:
32
32
 
33
33
  - `config-exists`
34
34
  - `git-repo`
@@ -38,4 +38,4 @@ Run `harness-dev validate` — checks:
38
38
 
39
39
  ## Handoff
40
40
 
41
- On gate pass: `harness-dev phase verify` (Generator → Evaluator).
41
+ On gate pass: `dev-harness phase verify` (Generator → Evaluator).
@@ -12,7 +12,7 @@ feature list.
12
12
 
13
13
  ## Entry
14
14
 
15
- - `harness-config.json` exists (created by `harness-dev init`)
15
+ - `harness-config.json` exists (created by `dev-harness init`)
16
16
  - `AGENTS.md` present in project root
17
17
 
18
18
  ## Work
@@ -40,7 +40,7 @@ feature list.
40
40
 
41
41
  ## Exit Gate
42
42
 
43
- Run `harness-dev validate` — checks:
43
+ Run `dev-harness validate` — checks:
44
44
 
45
45
  - `config-exists`
46
46
  - `git-repo`
@@ -48,4 +48,4 @@ Run `harness-dev validate` — checks:
48
48
 
49
49
  ## Handoff
50
50
 
51
- On gate pass: `harness-dev phase plan` (Planner → continues as Planner for decomposition).
51
+ On gate pass: `dev-harness phase plan` (Planner → continues as Planner for decomposition).
@@ -20,11 +20,11 @@ verifiable acceptance criteria. The Sprint Contract is negotiated here.
20
20
  2. Decompose into features → tasks in `feature_list.json`.
21
21
  3. Planner proposes `sprint-contract.md` (scope, criteria, exclusions).
22
22
  4. Evaluator reviews; iterate until `**Status:** Agreed`.
23
- 5. Use `harness-dev contract propose` / `contract review --decision <agreed|needs-revision>`.
23
+ 5. Use `dev-harness contract propose` / `contract review --decision <agreed|needs-revision>`.
24
24
 
25
25
  ## Exit Gate
26
26
 
27
- Run `harness-dev validate` — checks:
27
+ Run `dev-harness validate` — checks:
28
28
 
29
29
  - `config-exists`
30
30
  - `git-repo`
@@ -33,4 +33,4 @@ Run `harness-dev validate` — checks:
33
33
 
34
34
  ## Handoff
35
35
 
36
- On gate pass: `harness-dev phase build` (Planner → Generator).
36
+ On gate pass: `dev-harness phase build` (Planner → Generator).
@@ -27,7 +27,7 @@ overall verdict: Accept / Revise / Block.
27
27
 
28
28
  ## Exit Gate
29
29
 
30
- Run `harness-dev validate` — checks:
30
+ Run `dev-harness validate` — checks:
31
31
 
32
32
  - `config-exists`
33
33
  - `git-repo`
@@ -39,4 +39,4 @@ Run `harness-dev validate` — checks:
39
39
 
40
40
  ## Handoff
41
41
 
42
- On gate pass: `harness-dev phase ship` (committee → release).
42
+ On gate pass: `dev-harness phase ship` (committee → release).
@@ -17,13 +17,13 @@ The release must be reproducible from a clean checkout.
17
17
 
18
18
  1. Update `CHANGELOG.md` with version, date, summary.
19
19
  2. Bump version in `package.json` / equivalent manifest.
20
- 3. Run full `harness-dev validate` — all gates must pass.
20
+ 3. Run full `dev-harness validate` — all gates must pass.
21
21
  4. Tag the release: `git tag -a v<x.y.z> -m "Release x.y.z"`.
22
22
  5. Open or merge the PR per project workflow.
23
23
 
24
24
  ## Exit Gate
25
25
 
26
- Run `harness-dev validate` — checks:
26
+ Run `dev-harness validate` — checks:
27
27
 
28
28
  - `config-exists`
29
29
  - `git-repo`
@@ -38,6 +38,6 @@ Run `harness-dev validate` — checks:
38
38
 
39
39
  ## Handoff
40
40
 
41
- On gate pass: pipeline complete. `harness-dev status` reports
41
+ On gate pass: pipeline complete. `dev-harness status` reports
42
42
  `Pipeline complete after "ship"`. Increment `pipelineIteration` and loop back
43
43
  to DEFINE for the next sprint, or stop if the project is done.
@@ -20,14 +20,14 @@ must not break the feature's acceptance criteria.
20
20
  1. Read `progress.md` and `AGENTS.md`.
21
21
  2. For each feature: review the implementation, propose deletions/renames.
22
22
  3. Apply simplifications.
23
- 4. Re-run `harness-dev validate --feature <name>` — criteria must still pass.
23
+ 4. Re-run `dev-harness validate --feature <name>` — criteria must still pass.
24
24
  5. On pass: commit, append lesson.
25
25
  6. On fail (≤ `maxRetries`): revert and retry.
26
26
  7. On fail (> `maxRetries`): escalate.
27
27
 
28
28
  ## Exit Gate
29
29
 
30
- Run `harness-dev validate` — checks:
30
+ Run `dev-harness validate` — checks:
31
31
 
32
32
  - `config-exists`
33
33
  - `git-repo`
@@ -37,4 +37,4 @@ Run `harness-dev validate` — checks:
37
37
 
38
38
  ## Handoff
39
39
 
40
- On gate pass: `harness-dev phase review` (Simplifier → multi-agent committee).
40
+ On gate pass: `dev-harness phase review` (Simplifier → multi-agent committee).
@@ -26,7 +26,7 @@ feature's acceptance criteria from the sprint contract and scores it against
26
26
 
27
27
  ## Exit Gate
28
28
 
29
- Run `harness-dev validate` — checks:
29
+ Run `dev-harness validate` — checks:
30
30
 
31
31
  - `config-exists`
32
32
  - `git-repo`
@@ -35,4 +35,4 @@ Run `harness-dev validate` — checks:
35
35
 
36
36
  ## Handoff
37
37
 
38
- On gate pass: `harness-dev phase simplify` (Evaluator → Simplifier).
38
+ On gate pass: `dev-harness phase simplify` (Evaluator → Simplifier).
@@ -94,4 +94,4 @@ switch ($Stack) {
94
94
  Write-Host " ✓ Setup verified" -ForegroundColor Green
95
95
 
96
96
  # ── Start ────────────────────────────────────────────────────────────────────
97
- Write-Host "`nSetup complete. Run: harness-dev phase define" -ForegroundColor Cyan
97
+ Write-Host "`nSetup complete. Run: dev-harness phase define" -ForegroundColor Cyan
@@ -10,7 +10,7 @@ Retry Count: 0/{{maxRetries}}
10
10
 
11
11
  ## Lessons
12
12
 
13
- <!-- Use \`harness-dev learn "lesson here"\` to add lessons. -->
13
+ <!-- Use \`dev-harness learn "lesson here"\` to add lessons. -->
14
14
 
15
15
  ## Checkpoints
16
16