dev-harness-cli 1.1.0 β†’ 2.1.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 (41) hide show
  1. package/README.md +515 -135
  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/constants.mjs +19 -2
  19. package/cli/lib/contract.mjs +3 -3
  20. package/cli/lib/gates.mjs +1 -1
  21. package/cli/lib/help.mjs +28 -28
  22. package/cli/lib/ralph-inner.mjs +2 -2
  23. package/cli/lib/ralph-outer.mjs +3 -3
  24. package/cli/lib/ralph-output.mjs +1 -1
  25. package/cli/lib/scaffold.mjs +1 -1
  26. package/cli/lib/state.mjs +1 -1
  27. package/package.json +13 -4
  28. package/templates/AGENTS.md +5 -5
  29. package/templates/ci/github-actions.yml +1 -1
  30. package/templates/ci/gitlab-ci.yml +1 -1
  31. package/templates/docs/agents/generator.md +1 -1
  32. package/templates/docs/agents/simplifier.md +1 -1
  33. package/templates/docs/phases/build.md +3 -3
  34. package/templates/docs/phases/define.md +3 -3
  35. package/templates/docs/phases/plan.md +3 -3
  36. package/templates/docs/phases/review.md +2 -2
  37. package/templates/docs/phases/ship.md +3 -3
  38. package/templates/docs/phases/simplify.md +3 -3
  39. package/templates/docs/phases/verify.md +2 -2
  40. package/templates/init.ps1 +1 -1
  41. package/templates/progress.md +1 -1
package/README.md CHANGED
@@ -1,101 +1,467 @@
1
1
  <div align="center">
2
2
 
3
- # Dev Harness
3
+ # 🎯 Dev Harness
4
4
 
5
- ### Agent-agnostic development pipeline CLI
5
+ ### *Agent-Agnostic Development Pipeline CLI*
6
6
 
7
- Scaffold Β· Phase orchestration Β· Gate validation Β· Iteration
7
+ **Scaffold Β· Phase Orchestration Β· Gate Validation Β· Iterative Refinement**
8
8
 
9
- [![npm version](https://img.shields.io/npm/v/dev-harness-cli.svg)](https://www.npmjs.com/package/dev-harness-cli)
10
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
11
- [![Node.js >=18](https://img.shields.io/badge/node-%3E%3D18-green.svg)](https://nodejs.org)
12
- [![Zero Dependencies](https://img.shields.io/badge/dependencies-zero-blue.svg)](#)
9
+ [![npm version](https://img.shields.io/npm/v/dev-harness-cli.svg?style=flat-square&logo=npm&color=CB3837)](https://www.npmjs.com/package/dev-harness-cli)
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
11
+ [![Node.js >=18](https://img.shields.io/badge/node-%3E%3D18-339933.svg?style=flat-square&logo=node.js&logoColor=white)](https://nodejs.org)
12
+ [![Minimal Dependencies](https://img.shields.io/badge/dependencies-minimal-4FC08D.svg?style=flat-square)](#-dependencies)
13
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-FF6B6B.svg?style=flat-square)](#)
14
+ [![Maintained](https://img.shields.io/badge/maintained-yes-1E90FF.svg?style=flat-square)](#)
13
15
 
14
- **Works with any coding agent:** Claude Code Β· Codex Β· Cursor Β· Aider Β· Continue Β· OpenCode Β· Windsurf Β· Gemini Β· GitHub Copilot Β· Cline Β· Roo Β· Kilo Code Β· Amazon Q Β· and more
16
+ 🧰 **Works with any coding agent β€” IDE or TUI**
17
+
18
+ `Claude Code` Β· `Cursor` Β· `Windsurf` Β· `GitHub Copilot` Β· `Gemini CLI` Β· `Codex CLI` Β· `Cline` Β· `Roo Code` Β· `Kilo Code` Β· `Amazon Q Developer` Β· `OpenCode` Β· `Continue` Β· `Aider` Β· `Hermes` Β· `OpenClaw` Β· `Antigravity` Β· `Pi` Β· and more
15
19
 
16
20
  </div>
17
21
 
18
22
  ---
19
23
 
20
- ## What is this?
24
+ ## πŸ“‹ Table of Contents
25
+
26
+ - [πŸ€” What Is This?](#-what-is-this)
27
+ - [πŸš€ Quick Start](#-quick-start)
28
+ - [πŸ“– User Guide](#-user-guide)
29
+ - [πŸ–₯️ IDE-Based Agentic Tools](#️-ide-based-agentic-tools)
30
+ - [πŸ’» TUI-Based Agentic Tools](#-tui-based-agentic-tools)
31
+ - [🧠 How It Works](#-how-it-works)
32
+ - [Pipeline Phases](#pipeline-phases)
33
+ - [Gate Validation](#gate-validation)
34
+ - [Ralph Inner / Outer Loops](#ralph-inner--outer-loops)
35
+ - [Multi-Agent Committee Review](#multi-agent-committee-review)
36
+ - [πŸ“ Project Structure](#-project-structure)
37
+ - [βš™οΈ CLI Reference](#️-cli-reference)
38
+ - [πŸ”§ Configuration](#-configuration)
39
+ - [πŸ“€ JSON Output](#-json-output)
40
+ - [πŸ™ Acknowledgements & Influences](#-acknowledgements--influences)
41
+ - [πŸ“„ License](#-license)
21
42
 
22
- **Dev Harness** is a CLI tool that brings structure to AI-assisted software development. Instead of ad-hoc prompting, it enforces a **phase pipeline** with **gate validation** β€” ensuring specs are written before code, code is reviewed before shipping, and nothing gets skipped.
43
+ ---
23
44
 
45
+ ## πŸ€” What Is This?
46
+
47
+ **Dev Harness** is a CLI tool that brings **deterministic structure** to AI-assisted software development. Instead of ad-hoc prompting β€” where agents hallucinate scope, skip steps, or rubber-stamp their own work β€” Dev Harness enforces a **phase pipeline** with **gate validation**.
48
+
49
+ > 🎯 **Specs before code. Review before shipping. Nothing skipped.**
50
+
51
+ ```mermaid
52
+ flowchart LR
53
+ DEFINE[πŸ“ DEFINE] --> PLAN[πŸ“‹ PLAN]
54
+ PLAN --> BUILD[πŸ› οΈ BUILD]
55
+ BUILD --> VERIFY[βœ… VERIFY]
56
+ VERIFY -.-> SIMPLIFY[🧹 SIMPLIFY]
57
+ VERIFY --> REVIEW[πŸ” REVIEW]
58
+ SIMPLIFY --> REVIEW
59
+ REVIEW --> SHIP[πŸš€ SHIP]
60
+
61
+ style DEFINE fill:#4A90D9,color:#fff,stroke:none
62
+ style PLAN fill:#50C878,color:#fff,stroke:none
63
+ style BUILD fill:#FF8C42,color:#fff,stroke:none
64
+ style VERIFY fill:#9B59B6,color:#fff,stroke:none
65
+ style SIMPLIFY fill:#F1C40F,color:#333,stroke:none
66
+ style REVIEW fill:#E74C3C,color:#fff,stroke:none
67
+ style SHIP fill:#2ECC71,color:#fff,stroke:none
24
68
  ```
25
- define β†’ plan β†’ build β†’ verify β†’ [simplify] β†’ review β†’ ship
69
+
70
+ Each phase has **deterministic gates** β€” automated checks that must pass before the pipeline can advance. The agent does the work; the harness validates the result. No more wondering if the agent actually finished what it said it did.
71
+
72
+ ### ✨ Key Features
73
+
74
+ | | Feature | Description |
75
+ |---|---------|-------------|
76
+ | 🧩 | **Agent-Agnostic** | Works with 18+ agentic coding tools β€” IDE extensions and TUI agents alike |
77
+ | 🚦 | **Phase Pipeline** | 7-phase workflow: Define β†’ Plan β†’ Build β†’ Verify β†’ Simplify β†’ Review β†’ Ship |
78
+ | 🚧 | **Gate Validation** | Every phase has deterministic pass/fail checks β€” no skipping steps |
79
+ | πŸ”„ | **Ralph Loops** | Inner/outer iterative loops with fresh-context retry (inspired by [ghuntley.com/ralph](https://ghuntley.com/ralph)) |
80
+ | πŸ§‘β€βš–οΈ | **Multi-Agent Review** | Committee of agent personas (Planner, Generator, Evaluator, Simplifier) prevents self-evaluation leniency |
81
+ | πŸ“ | **Sprint Contracts** | Pre-build negotiation between agent personas for spec/code agreement |
82
+ | πŸ—οΈ | **31+ Stack Templates** | Python, Node.js, Go, Rust, C, C++, Java, Kotlin, .NET, Ruby, PHP, Swift, Elixir, and many more |
83
+ | 🏭 | **Custom Stacks** | Unlimited custom language/platform support via `config.stackMeta` |
84
+ | πŸ“¦ | **Minimal Dependencies** | Curated runtime deps (ajv, simple-git, ink, p-retry, picocolors, string-width) β€” each chosen for a concrete robustness win |
85
+
86
+ ---
87
+
88
+ ## πŸ—οΈ Architecture
89
+
90
+ Dev Harness is a layered CLI: argument parsing β†’ command routing β†’ library modules β†’ file/state I/O. The diagrams below show how the pieces fit together.
91
+
92
+ ### System Architecture
93
+
94
+ ```mermaid
95
+ flowchart TD
96
+ User([User / Agent]) -->|dev-harness &lt;cmd&gt;| CLI[cli/dev-harness.mjs<br/>Entry + routing]
97
+ CLI -->|parse| Args[lib/args.mjs<br/>Argument parser]
98
+ CLI -->|dispatch| Cmds[cli/commands/*.mjs<br/>17 command handlers]
99
+ Cmds -->|use| Lib[cli/lib/*.mjs<br/>30+ library modules]
100
+ Lib -->|read/write| State[(harness/config.json<br/>+ feature-list.json<br/>+ progress.md)]
101
+ Lib -->|git ops| Git[lib/git.mjs<br/>simple-git async]
102
+ Lib -->|validate| Gates[lib/gates.mjs<br/>Phase gate checks]
103
+ Lib -->|iterate| Ralph[lib/ralph-inner.mjs<br/>lib/ralph-outer.mjs]
104
+ Lib -->|spawn| Supervisor[lib/supervisor.mjs<br/>Orchestrator + p-retry]
105
+ Supervisor -->|render| TUI[tui/dashboard.mjs<br/>Ink live dashboard]
106
+ Cmds -->|scaffold| Templates[templates/<br/>31 stack templates]
107
+ Cmds -->|detect| Stacks[lib/detect-stack.mjs<br/>Stack detection]
26
108
  ```
27
109
 
28
- Each phase has **deterministic gates** (checks) that must pass before advancing. The agent does the work; harness validates the result.
110
+ ### 7-Phase Pipeline
111
+
112
+ ```mermaid
113
+ flowchart LR
114
+ INIT[INIT<br/>Scaffold] --> DEFINE[DEFINE<br/>Specs + contract]
115
+ DEFINE --> PLAN[PLAN<br/>Architecture]
116
+ PLAN --> BUILD[BUILD<br/>Implement features]
117
+ BUILD --> VERIFY[VERIFY<br/>Tests + coverage]
118
+ VERIFY --> SIMPLIFY[SIMPLIFY<br/>Refactor]
119
+ SIMPLIFY --> REVIEW[REVIEW<br/>Multi-agent committee]
120
+ REVIEW --> SHIP[SHIP<br/>Tag + release]
121
+ style SIMPLIFY fill:#fef3c7,stroke:#d97706,stroke-dasharray: 5 5
122
+ ```
123
+
124
+ > `SIMPLIFY` is opt-in (excluded from default phase order). Each phase has deterministic gate checks β€” no skipping.
125
+
126
+ ### Ralph Inner/Outer Loop
127
+
128
+ The Ralph pattern drives iterative refinement. The **outer loop** advances phases; the **inner loop** iterates features/tasks within a phase, retrying with fresh git context on failure.
129
+
130
+ ```mermaid
131
+ stateDiagram-v2
132
+ [*] --> Idle
133
+ Idle --> Running: phase &lt;name&gt;
134
+ state Running {
135
+ [*] --> LoadConfig
136
+ LoadConfig --> CheckRetries
137
+ CheckRetries --> Escalated: retries &gt;= max
138
+ CheckRetries --> GitReset: retry &amp; --git-ops
139
+ GitReset --> PickTask
140
+ CheckRetries --> PickTask: fresh run
141
+ PickTask --> FeatureIterate: build/verify/simplify
142
+ PickTask --> DeliverableRetry: init/define/plan/review/ship
143
+ FeatureIterate --> Instruction: next task
144
+ DeliverableRetry --> Instruction: produce deliverable
145
+ Instruction --> [*]: agent validates
146
+ }
147
+ Running --> Complete: all features pass
148
+ Running --> Escalated: retries exhausted
149
+ Complete --> [*]
150
+ Escalated --> [*]
151
+ ```
152
+
153
+ ### Orchestrator (Supervisor) Data Flow
154
+
155
+ `dev-harness run` spawns an agent per task, monitors it, retries on API downtime, and renders a live dashboard.
156
+
157
+ ```mermaid
158
+ flowchart TD
159
+ Start([dev-harness run]) --> Loop{Pipeline<br/>complete?}
160
+ Loop -->|no| Heartbeat[Record heartbeat]
161
+ Heartbeat --> BuildPrompt[Build task prompt]
162
+ BuildPrompt --> HasTask{Task<br/>available?}
163
+ HasTask -->|no| Advance[continuePipeline]
164
+ Advance --> Loop
165
+ HasTask -->|yes| Spawn[spawnAgent<br/>fresh session]
166
+ Spawn --> Wait[waitForCompletion]
167
+ Wait --> ExitCode{exit code}
168
+ ExitCode -->|0| Validate[runChecks]
169
+ Validate --> Pass{gates pass?}
170
+ Pass -->|yes| MarkDone[Mark task complete]
171
+ MarkDone --> Loop
172
+ Pass -->|no| RetryTask[Increment taskRetry]
173
+ RetryTask --> Loop
174
+ ExitCode -->|non-zero| ApiError{API error?}
175
+ ApiError -->|yes| Backoff[p-retry<br/>exponential backoff]
176
+ Backoff -->|recovered| Validate
177
+ Backoff -->|exhausted| Pause[Pause pipeline]
178
+ ApiError -->|no| RetryTask
179
+ Pause --> End([Paused β€” resume on recovery])
180
+ Loop -->|yes| End2([Pipeline complete])
181
+ ```
182
+
183
+ ### Tier-1 vs Tier-2 Agent Integration
184
+
185
+ ```mermaid
186
+ flowchart TB
187
+ subgraph Tier1[Tier 1 β€” Orchestrator Mode]
188
+ direction LR
189
+ CLI1[dev-harness run] --> Spawn1[spawnAgent per task]
190
+ Spawn1 --> Hermes[Hermes]
191
+ Spawn1 --> OpenClaw[OpenClaw]
192
+ Spawn1 --> ClaudeCode[Claude Code]
193
+ end
194
+ subgraph Tier2[Tier 2 β€” Instruction Mode]
195
+ direction LR
196
+ CLI2[dev-harness phase &lt;name&gt;] --> Write[Write AGENTS.md<br/>+ task instructions]
197
+ Write --> Cursor[Cursor]
198
+ Write --> Copilot[Copilot]
199
+ Write --> Windsurf[Windsurf]
200
+ Write --> Gemini[Gemini]
201
+ Write --> OtherIDE[...14 more IDE tools]
202
+ end
203
+ ```
29
204
 
30
- ## Install
205
+ > **Tier 1** tools are spawnable TUI agents β€” dev-harness runs them per task with fresh sessions and API retry. **Tier 2** tools are IDE extensions β€” dev-harness writes instructions and the agent reads them natively.
206
+
207
+ ---
208
+
209
+ ## πŸš€ Quick Start
31
210
 
32
211
  ```bash
33
- # Quick start (no install)
212
+ # 🏁 One-liner β€” no install needed
34
213
  npx dev-harness-cli init --stack python --target my-project
35
214
 
36
- # Global install
215
+ # πŸ“¦ Global install
37
216
  npm install -g dev-harness-cli
38
- harness-dev --help
217
+ dev-harness --help
39
218
  ```
40
219
 
41
- Requires **Node.js >= 18**. Zero runtime dependencies.
220
+ > **Requires Node.js >= 18.** Minimal, audited runtime dependencies.
42
221
 
43
- ## Quick Start
222
+ ### Your First Pipeline
44
223
 
45
224
  ```bash
46
- # 1. Scaffold a new project
47
- harness-dev init --stack node --target my-app
225
+ # 1️⃣ Scaffold a new project
226
+ dev-harness init --stack node --target my-app
48
227
  cd my-app
49
228
 
50
- # 2. Check status
51
- harness-dev status
229
+ # 2️⃣ Check your status
230
+ dev-harness status
52
231
 
53
- # 3. Run the DEFINE phase (agent writes specs)
54
- harness-dev phase define
232
+ # 3️⃣ Run the DEFINE phase (agent writes specs)
233
+ dev-harness phase define
55
234
 
56
- # 4. Validate (run gate checks)
57
- harness-dev validate
235
+ # 4️⃣ Validate β€” run gate checks
236
+ dev-harness validate
58
237
 
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
238
+ # 5️⃣ Advance through the pipeline
239
+ dev-harness phase plan
240
+ dev-harness phase build
241
+ dev-harness phase verify
242
+ dev-harness phase review
243
+ dev-harness phase ship
65
244
  ```
66
245
 
67
- ## Project Structure
246
+ ---
247
+
248
+ ## πŸ“– User Guide
249
+
250
+ Dev Harness works with two families of agentic coding tools. Which one are you using?
251
+
252
+ ---
253
+
254
+ ### πŸ–₯️ IDE-Based Agentic Tools
255
+
256
+ These tools run as **extensions or built-in features inside an editor/IDE** (VS Code, JetBrains, etc.). They read a project-level config file to understand how to behave.
257
+
258
+ #### How It Works
259
+
260
+ 1. **Scaffold** with the `--agent-tool` flag for your tool
261
+ 2. Dev Harness generates the **tool-specific config file** that the agent reads automatically
262
+ 3. The agent follows the **phase instructions** emitted by `dev-harness phase <name>`
263
+ 4. After each phase, run `dev-harness validate` to **check gates** before advancing
264
+
265
+ #### Supported IDE Tools
266
+
267
+ | Tool | Config File | Init Command |
268
+ |------|-------------|-------------|
269
+ | **Claude Code** | `CLAUDE.md` | `dev-harness init --agent-tool claude-code` |
270
+ | **Cursor** | `.cursorrules` | `dev-harness init --agent-tool cursor` |
271
+ | **Windsurf** | `.windsurfrules` | `dev-harness init --agent-tool windsurf` |
272
+ | **GitHub Copilot** | `.github/copilot-instructions.md` | `dev-harness init --agent-tool copilot` |
273
+ | **Gemini CLI** | `GEMINI.md` | `dev-harness init --agent-tool gemini` |
274
+ | **Codex CLI** | `AGENTS.md` | `dev-harness init --agent-tool codex` |
275
+ | **Cline** | `.clinerules` | `dev-harness init --agent-tool cline` |
276
+ | **Roo Code** | `.roorules` | `dev-harness init --agent-tool roo` |
277
+ | **Kilo Code** | `.kilocoderules` | `dev-harness init --agent-tool kilo-code` |
278
+ | **Amazon Q Developer** | `.amazonq/rules.md` | `dev-harness init --agent-tool amazon-q` |
279
+ | **OpenCode** | `AGENTS.md` | `dev-harness init --agent-tool opencode` |
280
+ | **Continue** | `AGENTS.md` | `dev-harness init --agent-tool continue` |
281
+ | **Aider** | `AGENTS.md` | `dev-harness init --agent-tool aider` |
68
282
 
69
- When you run `harness-dev init`, all harness-managed files go into a `harness/` subfolder β€” keeping your project root clean:
283
+ #### IDE Setup Example β€” Claude Code
284
+
285
+ ```bash
286
+ # Scaffold with Claude Code adapter
287
+ dev-harness init --stack python --agent-tool claude-code --target my-project
288
+ cd my-project
289
+
290
+ # CLAUDE.md is now in the project root β€” Claude reads it automatically
291
+ claude
292
+
293
+ # Inside Claude: follow the phase instructions
294
+ # "Run: dev-harness phase define"
295
+ # "Run: dev-harness validate"
296
+ # "Run: dev-harness phase plan"
297
+ # ...and so on through the pipeline
298
+ ```
299
+
300
+ > **Pattern:** All IDE tools follow the same workflow β€” scaffold with the tool flag, then let the agent read its config and follow phase instructions. The only difference is which filename the agent expects.
301
+
302
+ ---
303
+
304
+ ### πŸ’» TUI-Based Agentic Tools
305
+
306
+ These tools run as **standalone terminal applications** (TUI = Terminal User Interface). They typically read `AGENTS.md` from the project root natively, or use a custom manifest format.
307
+
308
+ #### How It Works
309
+
310
+ 1. **Scaffold** with `--agent-tool` for your TUI tool (or use `generic`)
311
+ 2. The harness generates `AGENTS.md` β€” the canonical conventions file
312
+ 3. The TUI agent reads `AGENTS.md` on startup and follows the pipeline
313
+ 4. Full adapter directories may include **wrapper scripts** that delegate to the CLI
314
+
315
+ #### Supported TUI Tools
316
+
317
+ | Tool | Entry Point | Init Command | Notes |
318
+ |------|------------|-------------|-------|
319
+ | **Hermes** | `adapters/hermes/SKILL.md` | `dev-harness init --agent-tool hermes` | Full adapter with SKILL.md manifest + wrapper scripts |
320
+ | **OpenClaw** | `AGENTS.md` | `dev-harness init --agent-tool openclaw` | Reads AGENTS.md natively |
321
+ | **Antigravity** | `AGENTS.md` | `dev-harness init --agent-tool antigravity` | Reads AGENTS.md natively |
322
+ | **Pi** | `AGENTS.md` | `dev-harness init --agent-tool pi` | Reads AGENTS.md natively |
323
+ | **Generic** | `AGENTS.md` | `dev-harness init --agent-tool generic` | Fallback β€” works with any tool |
324
+
325
+ #### TUI Setup Example β€” Hermes
326
+
327
+ ```bash
328
+ # Scaffold with Hermes adapter
329
+ dev-harness init --stack go --agent-tool hermes --target my-service
330
+ cd my-service
331
+
332
+ # Hermes loads the skill via adapters/hermes/SKILL.md
333
+ # The SKILL.md references wrapper scripts that call the CLI
334
+ # adapters/hermes/
335
+ # β”œβ”€β”€ SKILL.md ← Hermes skill manifest
336
+ # β”œβ”€β”€ scripts/
337
+ # β”‚ β”œβ”€β”€ init.mjs ← Wraps dev-harness init
338
+ # β”‚ β”œβ”€β”€ phase.mjs ← Wraps dev-harness phase
339
+ # β”‚ └── validate.mjs ← Wraps dev-harness validate
340
+ # └── templates/ ← Shared templates
341
+
342
+ # Follow the phase pipeline inside Hermes
343
+ ```
344
+
345
+ > **Pattern:** TUI tools that natively read `AGENTS.md` need no extra config β€” just scaffold and go. Tools with custom manifest formats (like Hermes with `SKILL.md`) get a full adapter directory with wrapper scripts.
346
+
347
+ ---
348
+
349
+ ## 🧠 How It Works
350
+
351
+ ### Pipeline Phases
352
+
353
+ | Phase | 🎯 Goal | πŸ“¦ Key Artifact | 🚧 Gate(s) |
354
+ |-------|---------|-----------------|------------|
355
+ | πŸ”΅ **DEFINE** | Write specs before any code | `SPEC.md`, `PROJECT_PLAN.md` | `feature-branch`, `contract-agreed` |
356
+ | 🟒 **PLAN** | Break specs into actionable tasks | Task breakdown | `git-clean` |
357
+ | 🟠 **BUILD** | Implement features one at a time | Working code | `coverage` _(if enabled)_ |
358
+ | 🟣 **VERIFY** | Validate and test everything | Passing test suite | `coverage` _(if enabled)_ |
359
+ | 🟑 **SIMPLIFY** | Refactor, reduce complexity | Cleaner codebase | `git-clean`, `no-empty-dirs` |
360
+ | πŸ”΄ **REVIEW** | Multi-agent committee review | Review report | `branch-up-to-date`, `rubric-exists`, `readme-exists`, `architecture-doc`, `decisions-logged` |
361
+ | 🟒 **SHIP** | Tag, changelog, publish | Release | `git-clean`, `tagged`, `changelog`, `readme-exists`, `license-exists`, `changelog-content`, `contributing-exists`, `no-empty-dirs` |
362
+
363
+ > 🧹 **SIMPLIFY** is optional β€” it runs after VERIFY only if `simplify` is in your phase list.
364
+
365
+ ### Gate Validation
366
+
367
+ Every phase has **deterministic gates** β€” automated checks that return a clear **pass/fail**. Gates prevent the most common failure modes in AI-assisted development:
368
+
369
+ - 🚫 **No skipping** β€” can't ship without reviewing
370
+ - πŸ“ **No coding without specs** β€” DEFINE gates must pass before BUILD
371
+ - πŸ” **No self-review leniency** β€” REVIEW uses multi-agent committee
372
+ - 🧹 **No dead code or empty dirs** β€” SIMPLIFY gates keep the codebase clean
373
+
374
+ Enable gates:
375
+
376
+ ```bash
377
+ dev-harness config set gates.enabled true
378
+ ```
379
+
380
+ ### Ralph Inner / Outer Loops
381
+
382
+ The architecture is built on the **Ralph pattern** β€” an iterative loop architecture that gives the agent fresh context on each retry.
383
+
384
+ ```
385
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
386
+ β”‚ 🌐 OUTER LOOP β”‚
387
+ β”‚ define β†’ plan β†’ build β†’ verify β†’ review β†’ ship β”‚
388
+ β”‚ (phase transitions, gate validation, human escalation) β”‚
389
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
390
+ β”‚
391
+ β–Ό
392
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
393
+ β”‚ πŸ”„ INNER LOOP β”‚
394
+ β”‚ β”‚
395
+ β”‚ feature-iterate mode: β”‚
396
+ β”‚ pick next feature β†’ agent works β†’ validate β†’ pass? β”‚
397
+ β”‚ βœ… β†’ next feature β”‚
398
+ β”‚ ❌ β†’ git reset --hard β†’ retry (fresh context) β”‚
399
+ β”‚ β”‚
400
+ β”‚ deliverable-retry mode: β”‚
401
+ β”‚ agent works on deliverable β†’ validate β†’ pass? β”‚
402
+ β”‚ βœ… β†’ advance phase β”‚
403
+ β”‚ ❌ β†’ rewrite + retry (up to N attempts) β”‚
404
+ β”‚ β”‚
405
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
406
+ ```
407
+
408
+ #### 🌐 Outer Loop
409
+
410
+ The CLI **emits structured instructions** for the current phase. The agent executes the phase, then runs `dev-harness validate` β€” which checks phase-specific gates. If gates pass, the agent advances to the next phase.
411
+
412
+ #### πŸ”„ Inner Loop (Ralph)
413
+
414
+ When building or verifying, the harness enters an **inner loop** that iterates over individual features (`feature-iterate`) or retries failed deliverables (`deliverable-retry`). The critical insight: **on retry, the harness resets to a clean git state** (`git reset --hard` + clean). This forces the agent to re-approach the problem with fresh context β€” avoiding the common failure mode of compounding its own mistakes.
415
+
416
+ > πŸ’‘ *"The single most important implementation detail is the hard reset on retry β€” it forces the agent to re-approach the problem rather than patch around its own bugs."*
417
+
418
+ ### Multi-Agent Committee Review
419
+
420
+ During REVIEW, Dev Harness can orchestrate a **committee of agent personas** β€” each reviewing from a different perspective:
421
+
422
+ | Persona | Role |
423
+ |---------|------|
424
+ | 🧭 **Planner** | Does this meet the spec? Is the architecture sound? |
425
+ | βš™οΈ **Generator** | Does the code work? Is it idiomatic? |
426
+ | πŸ” **Evaluator** | What's wrong? Where are the gaps? _(tuned to be skeptical)_ |
427
+ | 🧹 **Simplifier** | Is this over-engineered? Can it be simpler? |
428
+
429
+ This directly addresses the **self-evaluation leniency problem** β€” an agent asked to review its own work will almost always rubber-stamp it. A separate Evaluator persona, tuned to be skeptical, catches what the Generator misses.
430
+
431
+ ---
432
+
433
+ ## πŸ“ Project Structure
434
+
435
+ When you run `dev-harness init`, all harness-managed files go into a `harness/` subfolder β€” keeping your project root clean:
70
436
 
71
437
  ```
72
438
  my-project/
73
- β”œβ”€β”€ AGENTS.md # Agent instructions (root β€” tools expect it here)
74
- β”œβ”€β”€ .gitignore # Git ignore rules
75
- β”œβ”€β”€ package.json # Your project's package file
76
- β”œβ”€β”€ src/ # Your source code
77
- β”œβ”€β”€ tests/ # Your tests
78
- └── harness/ # All harness-managed files
79
- β”œβ”€β”€ config.json # Harness configuration + state
80
- β”œβ”€β”€ progress.md # Session state + lessons learned
81
- β”œβ”€β”€ sprint-contract.md # Pre-build agreement
82
- β”œβ”€β”€ evaluator-rubric.md # Quality scorecard
83
- β”œβ”€β”€ session-handoff.md # Context for session transitions
84
- β”œβ”€β”€ clean-state-checklist.md
439
+ β”œβ”€β”€ AGENTS.md # Agent conventions (root β€” tools expect it here)
440
+ β”œβ”€β”€ .gitignore # Git ignore rules
441
+ β”œβ”€β”€ package.json # Your project's package file
442
+ β”œβ”€β”€ src/ # Your source code
443
+ β”œβ”€β”€ tests/ # Your tests
444
+ └── harness/ # All harness-managed files
445
+ β”œβ”€β”€ config.json # Harness configuration + state
446
+ β”œβ”€β”€ progress.md # Session state + lessons learned
447
+ β”œβ”€β”€ sprint-contract.md # Pre-build agreement
448
+ β”œβ”€β”€ evaluator-rubric.md # Quality scorecard
449
+ β”œβ”€β”€ session-handoff.md # Context for session transitions
450
+ β”œβ”€β”€ clean-state-checklist.md # Clean state checklist
85
451
  β”œβ”€β”€ features/
86
- β”‚ β”œβ”€β”€ feature-list.json # Feature tracking
87
- β”‚ └── feature-list.schema.json
452
+ β”‚ β”œβ”€β”€ feature-list.json # Feature tracking
453
+ β”‚ └── feature-list.schema.json # Feature list schema
88
454
  β”œβ”€β”€ docs/
89
- β”‚ β”œβ”€β”€ ARCHITECTURE.md # Architecture decisions
90
- β”‚ β”œβ”€β”€ CONSTRAINTS.md # Technical constraints
91
- β”‚ β”œβ”€β”€ DECISIONS.md # Decision log
92
- β”‚ β”œβ”€β”€ api-patterns.md # API conventions
93
- β”‚ β”œβ”€β”€ agents/ # Agent role guides
455
+ β”‚ β”œβ”€β”€ ARCHITECTURE.md # Architecture decisions
456
+ β”‚ β”œβ”€β”€ CONSTRAINTS.md # Technical constraints
457
+ β”‚ β”œβ”€β”€ DECISIONS.md # Decision log
458
+ β”‚ β”œβ”€β”€ api-patterns.md # API conventions
459
+ β”‚ β”œβ”€β”€ agents/ # Agent role guides
94
460
  β”‚ β”‚ β”œβ”€β”€ planner.md
95
461
  β”‚ β”‚ β”œβ”€β”€ generator.md
96
462
  β”‚ β”‚ β”œβ”€β”€ evaluator.md
97
463
  β”‚ β”‚ └── simplifier.md
98
- β”‚ └── phases/ # Phase instructions
464
+ β”‚ └── phases/ # Phase instructions
99
465
  β”‚ β”œβ”€β”€ define.md
100
466
  β”‚ β”œβ”€β”€ plan.md
101
467
  β”‚ β”œβ”€β”€ build.md
@@ -111,103 +477,68 @@ my-project/
111
477
  └── init.ps1
112
478
  ```
113
479
 
114
- ## Supported Stacks
115
-
116
- 31 built-in stacks + custom stack support:
117
-
118
- | Stack | Detection Files | Config File |
119
- |-------|----------------|-------------|
120
- | Node.js | `package.json`, `*.js`, `*.ts` | `package.json` |
121
- | Python | `pyproject.toml`, `setup.py`, `*.py` | `pyproject.toml` |
122
- | Rust | `Cargo.toml`, `*.rs` | `Cargo.toml` |
123
- | Go | `go.mod`, `*.go` | `go.mod` |
124
- | Java | `pom.xml`, `build.gradle`, `*.java` | `pom.xml` |
125
- | C/C++ | `*.c`, `*.cpp`, `*.hpp` | `CMakeLists.txt` |
126
- | .NET | `*.cs`, `*.fs` | `global.json` |
127
- | Ruby | `Gemfile`, `*.rb` | `Gemfile` |
128
- | PHP | `composer.json`, `*.php` | `composer.json` |
129
- | Swift | `Package.swift`, `*.swift` | `Package.swift` |
130
- | + 21 more | | |
131
-
132
- **Custom stacks:** Pass any name to `--stack` and fill `stackMeta` in `harness/config.json` during DEFINE phase.
480
+ ---
133
481
 
134
- ## Commands
482
+ ## βš™οΈ CLI Reference
135
483
 
136
484
  | Command | Description |
137
485
  |---------|-------------|
138
- | `init` | Scaffold a new project with harness structure |
139
- | `status` | Show current phase, stack, features, gates |
140
- | `phase <name>` | Invoke a pipeline phase |
141
- | `validate` | Run gate checks for current phase |
142
- | `config list` | List all 29 configurable parameters |
143
- | `config get <key>` | Get a config value |
144
- | `config set <key> <value>` | Set a config value |
145
- | `set-mode <copilot\|autopilot>` | Switch execution mode |
146
- | `pause` / `resume` | Pause/resume autopilot |
147
- | `contract propose/review/status/escalate` | Sprint contract negotiation |
148
- | `learn <message>` | Save a lesson to progress.md |
149
- | `checkpoint create <label>` | Create a manual checkpoint |
150
- | `rollback list/to/branch` | Restore to checkpoint |
151
- | `worktree create/list/remove` | Git worktree management |
152
- | `detect-tool` | Detect available agent tools |
153
-
154
- ## Agent Tool Integration
155
-
156
- Harness works with any coding agent. Use `--agent-tool` during init to generate tool-specific files:
157
-
158
- ```bash
159
- # Claude Code β†’ generates CLAUDE.md
160
- harness-dev init --stack node --agent-tool claude-code --target my-app
161
-
162
- # Cursor β†’ generates .cursorrules
163
- harness-dev init --stack node --agent-tool cursor --target my-app
164
-
165
- # GitHub Copilot β†’ generates .github/copilot-instructions.md
166
- harness-dev init --stack node --agent-tool copilot --target my-app
167
- ```
168
-
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.
486
+ | `dev-harness init` | πŸ—οΈ Scaffold a new harness project (stack + agent tool + target) |
487
+ | `dev-harness status` | πŸ“Š Show current phase, stack, mode, and pipeline state |
488
+ | `dev-harness phase <name>` | 🚦 Run a pipeline phase (define, plan, build, verify, simplify, review, ship) |
489
+ | `dev-harness validate` | βœ… Run gate checks for the current phase |
490
+ | `dev-harness run` | πŸš€ Start orchestrator β€” spawn agent per task, API retry, live dashboard |
491
+ | `dev-harness select-tool` | 🧰 Choose backend agentic tool (interactive wizard) |
492
+ | `dev-harness config [get|set|list]` | βš™οΈ View or update configuration parameters |
493
+ | `dev-harness contract` | πŸ“ Negotiate a sprint contract between agent personas |
494
+ | `dev-harness checkpoint` | πŸ’Ύ Create a manual git checkpoint |
495
+ | `dev-harness rollback` | βͺ Roll back to a previous checkpoint |
496
+ | `dev-harness worktree` | 🌿 Manage git worktrees for parallel feature work |
497
+ | `dev-harness pause` | ⏸️ Pause the pipeline (save state) |
498
+ | `dev-harness resume` | ▢️ Resume a paused pipeline |
499
+ | `dev-harness set-mode <mode>` | πŸ”€ Switch between `copilot` (instruction) and `autopilot` (auto-advance) |
500
+ | `dev-harness learn` | πŸ“š Mark a phase as learned (skip in future runs) |
501
+ | `dev-harness detect-tool` | πŸ”Ž Auto-detect which agent tool is in use |
502
+ | `dev-harness --help` | ❓ Show full help |
170
503
 
171
- See [docs/TOOL_INTEGRATION.md](docs/TOOL_INTEGRATION.md) for per-tool setup guides.
504
+ ---
172
505
 
173
- ## Gates
506
+ ## πŸ”§ Configuration
174
507
 
175
- Gates are deterministic checks that must pass before advancing to the next phase. Enable with:
508
+ All configuration lives in `harness/config.json`. View with:
176
509
 
177
510
  ```bash
178
- harness-dev config set gates.enabled true
511
+ dev-harness config list
179
512
  ```
180
513
 
181
- | Phase | Gates |
182
- |-------|-------|
183
- | DEFINE | feature-branch, contract-agreed |
184
- | PLAN | git-clean |
185
- | BUILD | (coverage if enabled) |
186
- | VERIFY | (coverage if enabled) |
187
- | SIMPLIFY | git-clean, no-empty-dirs |
188
- | REVIEW | branch-up-to-date, rubric-exists, readme-exists, architecture-doc, decisions-logged |
189
- | SHIP | git-clean, tagged, changelog, readme-exists, license-exists, changelog-content, contributing-exists, no-empty-dirs |
514
+ <details>
515
+ <summary>πŸ“‹ Click to see configuration groups</summary>
190
516
 
191
- ## Configuration
517
+ | Group | Parameters | Description |
518
+ |-------|-----------|-------------|
519
+ | ⚑ **Execution** | `maxRetries`, `commandTimeout`, `coverageTimeout`, `maxNegotiationRounds`, `escalationTimeout` | Runtime behavior tuning |
520
+ | πŸ—οΈ **Stack** | `stack`, `stackMeta` | Language/platform configuration |
521
+ | 🧰 **Agent Tool** | `agentTool` | Current agent tool selection |
522
+ | 🚧 **Gates** | `gates.enabled`, `gates.required`, `gates.coverageThreshold` | Gate validation settings |
523
+ | 🌿 **Git** | `git.autoCommit`, `git.autoPush`, `git.mainBranch`, `git.tagPrefix` | Git integration behavior |
524
+ | 🚦 **Phases** | `phases.order`, `phases.skip`, `phases.simplifyAfter` | Pipeline phase configuration |
525
+ | 🎭 **Agent Tones** | `tones.planner`, `tones.generator`, `tones.evaluator`, `tones.simplifier` | Persona instruction customization |
526
+ | πŸ’Ύ **Runtime State** | `currentPhase`, `retryCount`, `mode`, `paused` | Live pipeline state |
192
527
 
193
- All configuration lives in `harness/config.json`. View with:
194
-
195
- ```bash
196
- harness-dev config list
197
- ```
528
+ </details>
198
529
 
199
- 29 parameters across 8 groups: Execution, Stack, Agent Tool, Gates, Git, Phases, Agent Tones, Runtime State.
530
+ **29 parameters** across 8 groups. See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for the full reference.
200
531
 
201
- See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for full reference.
532
+ ---
202
533
 
203
- ## JSON Output
534
+ ## πŸ“€ JSON Output
204
535
 
205
- All commands support `--json` for machine-parseable output:
536
+ All commands support `--json` for machine-parseable output β€” perfect for CI/CD pipelines, wrapper scripts, and tool integration.
206
537
 
207
538
  ```bash
208
- harness-dev status --json
209
- harness-dev phase define --json
210
- harness-dev validate --json
539
+ dev-harness status --json
540
+ dev-harness phase define --json
541
+ dev-harness validate --json
211
542
  ```
212
543
 
213
544
  ```json
@@ -220,8 +551,57 @@ harness-dev validate --json
220
551
  }
221
552
  ```
222
553
 
223
- Errors go to stderr. Exit codes: `0` success, `1` validation, `2` usage, `3` internal.
554
+ | Convention | Rule |
555
+ |------------|------|
556
+ | βœ… **stdout** | Always valid JSON β€” machine-parseable, no exceptions |
557
+ | ❌ **stderr** | All errors, warnings, human-readable messages |
558
+ | **Exit codes** | `0` success, `1` validation failure, `2` usage error, `3` internal error |
559
+ | **JSON contract** | Every response includes `command`, `status`, `message` |
560
+
561
+ ---
562
+
563
+ ## οΏ½ Dependencies
564
+
565
+ Dev Harness v2.1.0 moved from zero-runtime-deps to a **minimal, audited** dependency set. Each dependency was chosen for a concrete robustness, performance, or correctness win that the hand-rolled equivalent could not match. All dependencies are ubiquitous, well-maintained, and support Node 18+.
566
+
567
+ | Dependency | Version | Replaces | Why |
568
+ |------------|---------|----------|-----|
569
+ | [`ajv`](https://github.com/ajv-validator/ajv) | ^8 | hand-rolled `validate-schema.mjs` | Full JSON Schema draft-07 support (`$ref`, `format`, `oneOf`, `if/then/else`, `pattern`) β€” the previous validator silently passed configs using unsupported keywords |
570
+ | [`simple-git`](https://github.com/steveukx/git-js) | ^3 | `execSync`-based `git.mjs` | **Async** git ops β€” unblocks the orchestrator event loop during `dev-harness run`; typed results; eliminates string-concat command injection risk |
571
+ | [`ink`](https://github.com/vadimdemedes/ink) + [`react`](https://react.dev) | ^5 / ^18 | manual ANSI `tui/dashboard.mjs` | Real layout engine, proper Unicode width, focus management, scrollable regions that work across terminals |
572
+ | [`p-retry`](https://github.com/sindresorhus/p-retry) | ^6 | hand-rolled backoff in `supervisor.mjs` | Battle-tested exponential backoff with `shouldRetry` predicate |
573
+ | [`picocolors`](https://github.com/alexeyraspopov/picocolors) | ^1 | hand-rolled ANSI color codes | TTY detection, `NO_COLOR`/`FORCE_COLOR` conformance, Windows support, 256/truecolor downgrading |
574
+ | [`string-width`](https://github.com/sindresorhus/string-width) | ^7 | emoji-width heuristic in `ansi.mjs` | Correctly measures emoji, combining marks, ZWJ sequences, and East Asian wide chars β€” the previous heuristic mis-measured many code points |
224
575
 
225
- ## License
576
+ > **Supply-chain posture:** 6 direct deps, all from established maintainers (Sindre Sorhus, Ajv org, Vadim Demedes, Steve King). `npm audit` reports 0 vulnerabilities. Versions pinned with caret ranges for patch updates.
226
577
 
227
- MIT
578
+ ---
579
+
580
+ ## οΏ½πŸ™ Acknowledgements & Influences
581
+
582
+ Dev Harness was built on the shoulders of foundational work in the **harness engineering** space. We are deeply grateful to these projects, papers, and people whose ideas shaped this tool:
583
+
584
+ | Influence | Links | Impact on Dev Harness |
585
+ |-----------|-------|----------------------|
586
+ | **Ralph Pattern**<br>by Dean Huntley | [`ghuntley.com/ralph`](https://ghuntley.com/ralph) · [`snarktank/ralph`](https://github.com/snarktank/ralph) | 🧠 **Core architecture.** The entire inner/outer loop design, fresh-context retry via `git reset --hard`, and `progress.md` session tracking are direct implementations of the Ralph pattern. The `ralph-inner.mjs`, `ralph-outer.mjs`, and `ralph-output.mjs` modules are named in its honor. |
587
+ | **Agent Skills**<br>by Addy Osmani | [`github.com/addyosmani/agent-skills`](https://github.com/addyosmani/agent-skills) | 🚦 **Pipeline & review design.** The 6-phase pipeline structure, committee-based multi-agent review with 4 personas (Planner, Generator, Evaluator, Simplifier), and anti-rationalization patterns come directly from this work. |
588
+ | **Anthropic**<br>Harness Research | ["Effective Harnesses" (Nov 2025)](https://anthropic.com/engineering/effective-harnesses) Β· ["Harness Design" (Mar 2026)](https://anthropic.com/engineering/harness-design) | πŸ“ **Generator/Evaluator split, sprint contracts, and rollback.** The finding that *"tuning a standalone evaluator to be skeptical is far more tractable than making a generator critical of its own work"* directly motivated our multi-agent committee. Sprint contract negotiation, feature lists, and middle-iteration recovery are all Anthropic-inspired. |
589
+ | **OpenAI**<br>Harness Engineering | ["Harness Engineering" (Feb 2026)](https://openai.com/index/harness-engineering/) | 🌿 **Worktree isolation & progressive disclosure.** The worktree CLI commands for isolated parallel feature development, and the progressive disclosure pattern in `AGENTS.md` (a concise map to detailed docs/) are direct applications of OpenAI's principles. |
590
+
591
+ > πŸ’‘ *These works collectively define the **harness engineering** discipline β€” the practice of building structured execution environments that make AI coding agents reliable at scale. Dev Harness is our synthesis and implementation of these ideas in a single, tool-agnostic CLI.*
592
+
593
+ ---
594
+
595
+ ## πŸ“„ License
596
+
597
+ [MIT](LICENSE) Β© 2026 Bakr Bagaber
598
+
599
+ ---
600
+
601
+ <div align="center">
602
+ <sub>Built with β˜• and πŸ€– Β· Questions? Open an issue Β· Contributions welcome!</sub>
603
+ <br>
604
+ <sub>
605
+ <a href="#-dev-harness">↑ Back to top</a>
606
+ </sub>
607
+ </div>