done-done-axi 0.6.12 → 0.6.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -178
- package/docs/index.html +1 -1
- package/docs/manual-cli.md +66 -0
- package/docs/media/hero-dark.png +0 -0
- package/docs/media/hero-light.png +0 -0
- package/docs/media/hero-phone-dark.png +0 -0
- package/docs/media/hero-phone-light.png +0 -0
- package/docs/media/hero-refuse.txt +4 -0
- package/docs/media/hero-run.txt +41 -0
- package/docs/media/hero.gif +0 -0
- package/docs/media/hero.mjs +84 -0
- package/docs/reference.md +31 -1
- package/docs/releasing.md +3 -3
- package/docs/social-preview.png +0 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
|
|
4
4
|
<img src="docs/logo.svg" width="64" height="64" alt="done-done">
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
</div>
|
|
9
|
-
|
|
10
|
-
# Prove your app really works.
|
|
6
|
+
<h1>Prove your app really works.</h1>
|
|
11
7
|
|
|
12
|
-
A command-line check
|
|
8
|
+
A command-line check that drives your app the way a user does, then has a separate agent judge what it captured.
|
|
13
9
|
|
|
14
|
-
For developers using coding agents
|
|
10
|
+
For developers using coding agents: the tests pass, the agent says "done", and the app is still broken.
|
|
15
11
|
|
|
16
|
-
<
|
|
12
|
+
<picture>
|
|
13
|
+
<source media="(max-width: 600px) and (prefers-color-scheme: dark)" srcset="docs/media/hero-phone-dark.png">
|
|
14
|
+
<source media="(max-width: 600px)" srcset="docs/media/hero-phone-light.png">
|
|
15
|
+
<img src="docs/media/hero.gif" width="880" alt="A real run: done-done run records a capture for commit ca78363, done-done check passes with the judge's reason, done-done receipt writes the receipt, and done-done init refuses a journey that only runs npm test.">
|
|
16
|
+
</picture>
|
|
17
17
|
|
|
18
|
-
<sub>
|
|
18
|
+
<sub>A real 0.6.12 run on a small sample app: a capture, the judge's pass and its reason, the receipt, and a test-only journey refused. Long paths shortened; [still, light](docs/media/hero-light.png) · [dark](docs/media/hero-dark.png).</sub>
|
|
19
19
|
|
|
20
20
|
```sh
|
|
21
21
|
npm install -g done-done-axi
|
|
@@ -23,41 +23,50 @@ cd your-app && done-done init
|
|
|
23
23
|
done-done verify --outcome "<what works now>"
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
The last line is your first result: your agent drives the real app, a judge checks each capture, and you get a pass with a receipt, or the judge's reason it did not pass.
|
|
26
|
+
The last line is your first result: your agent drives the real app, a fresh judge checks each capture, and you get a pass with a receipt, or the judge's reason it did not pass.
|
|
27
27
|
|
|
28
|
-
**With or without Firstmate.**
|
|
28
|
+
**With or without Firstmate.** Alone, you or your agent run these three lines; nothing else is needed. Inside a [Firstmate](https://github.com/kunchenguid/firstmate) fleet, two small files make every worker prove its task and let the merge check that proof ([how](#inside-firstmate-or-another-agent-fleet)).
|
|
29
29
|
|
|
30
|
-
[Website](https://umeranjum17.github.io/done-done-axi/) · [
|
|
30
|
+
[Website](https://umeranjum17.github.io/done-done-axi/) · [Quick start](#quick-start) · [Why](#why-not-just-green-tests) · [Reference](docs/reference.md) · [npm](https://www.npmjs.com/package/done-done-axi)
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
You need **[Node 22.18+](https://nodejs.org) and git**, plus your own signed-in coding agent or API key for the judge. Early preview; see [what's next](#whats-next).
|
|
32
|
+
[](https://www.npmjs.com/package/done-done-axi) [](https://nodejs.org) [](#whats-next)
|
|
35
33
|
|
|
36
|
-
|
|
37
|
-
2. **Set up your repo.** `init` asks you, in a terminal, which coding agent drives your app and which judge checks it. done-done never picks either for you. It then writes a minimal `.done-done.yaml` and a verify skill: how to launch and drive your app. Outside a terminal, pass `--agent <agent> --model <model> --judge <agent> --judge-model <model>` instead.
|
|
38
|
-
3. **Get your first result.** Say what works now, in plain words. `verify` has your agent drive the real product the way a user does and save screenshots or output. A fresh judge checks whether each capture shows your claim. A pass names the capture and writes a receipt for this commit. Anything else stops at a gate with the judge's reason, and `done-done respond` answers it. No judge pass, no receipt.
|
|
34
|
+
</div>
|
|
39
35
|
|
|
40
|
-
|
|
36
|
+
## Quick start
|
|
41
37
|
|
|
42
|
-
|
|
38
|
+
You need **[Node 22.18+](https://nodejs.org) and git**, plus your own signed-in coding agent or API key for the judge.
|
|
43
39
|
|
|
44
|
-
|
|
40
|
+
1. **Install.** The first line above puts `done-done` and `done-done-axi` on your PATH. No `sudo`? Add `--prefix ~/.local` and put `~/.local/bin` on your `PATH`.
|
|
41
|
+
2. **Set up your repo.** `init` asks which coding agent drives your app and which judge checks it, and never picks either for you. It writes a minimal `.done-done.yaml` and a verify skill that says how to launch and drive your app. Outside a terminal, pass `--agent <agent> --model <model> --judge <agent> --judge-model <model>`.
|
|
42
|
+
3. **Get your first result.** Say what works now, in plain words. Your agent drives the real product as a user would and saves screenshots, a recording or output; a fresh judge checks whether each capture shows your claim. A pass names the capture and writes a receipt for this commit; anything else stops at a gate with the judge's reason, which `done-done respond` answers.
|
|
45
43
|
|
|
46
|
-
|
|
44
|
+
Commit `.done-done.yaml` and the verify skill so later runs and your teammates use the same recipe. Captures go to your judge's provider, on your plan or key.
|
|
47
45
|
|
|
48
|
-
|
|
46
|
+
## Why: not just green tests
|
|
49
47
|
|
|
50
|
-
|
|
48
|
+
| | Green tests, or an agent's word | done-done |
|
|
49
|
+
| --- | --- | --- |
|
|
50
|
+
| What is checked | Code paths, types, lint, builds | The app, CLI or site, driven the way a user drives it |
|
|
51
|
+
| Who looks | You, or nobody | A fresh judge agent you chose, tools off, on your plan |
|
|
52
|
+
| Tied to a commit | No | A receipt names the commit and the sha256 of every capture |
|
|
53
|
+
| Stale or reused proof | Passes | Fails: proof from an older commit, or a file used for another claim, is refused |
|
|
54
|
+
| When it goes wrong | "Done" was wrong, later | The judge's reason, a gate to answer, and no receipt |
|
|
51
55
|
|
|
52
|
-
|
|
56
|
+
## What it checks
|
|
53
57
|
|
|
54
|
-
**
|
|
58
|
+
- 🧪 **The real product, not code checks.** A journey that only runs tests, typecheck, lint or a build is refused, and so is proof whose captures all come from such a run ([rule](docs/reference.md#real-product-evidence)).
|
|
59
|
+
- 🔗 **Tied to a commit, fresh, not reused.** Every run records the commit and whether the tree was dirty; older-commit proof fails, and a file used for another claim is reuse ([how](docs/reference.md#where-proof-lives)).
|
|
60
|
+
- 👀 **A judge always answers.** A fresh, tools-off judge on your plan looks at every `check`, `receipt` and `verify`. It cannot be turned off, and a judge that fails to answer stops the command instead of passing ([how](docs/reference.md#judge-relevance)).
|
|
61
|
+
- 🧾 **Honest claims, no model.** `done-done lint <PR URL | file> <evidence folder>` gates a worker's `## Checks` block: four filled lines, and evidence that exists, differs, is newer than the folder and was never used by another PR ([how](docs/reference.md#lint-check)).
|
|
62
|
+
- 🚦 **CI gate, no key.** `done-done gate` passes when a committed receipt covers the head; CI never runs `check`, `run` or `verify` and never gets a model key ([how](docs/reference.md#ci-gate)).
|
|
63
|
+
- 🎨 **Looks right, fits the screen.** `done-done design` has the judge compare a screen with its approved mock; `done-done look <url>` fails a 390 px page that overflows, with no model ([design](docs/reference.md#design-check), [look](docs/reference.md#look-check)).
|
|
55
64
|
|
|
56
|
-
|
|
65
|
+
Every answer is an exit code: **0** pass, **1** fail, **2** usage or config error, **3** can't tell either way, **4** a run is still going or waits at its gate ([all codes](docs/reference.md#exit-codes)).
|
|
57
66
|
|
|
58
67
|
## See it work
|
|
59
68
|
|
|
60
|
-
Four moments from a demo notes app
|
|
69
|
+
Four more moments from a demo notes app: a capture for the current commit, a judged pass, a check that refuses an older commit and two bad files, and a config error that stops the run. Real output from the current build; these four use a stub judge that says the screen shows the outcome, so no model runs.
|
|
61
70
|
|
|
62
71
|
<picture><source media="(prefers-color-scheme: dark)" srcset="docs/media/run-dark.svg"><img src="docs/media/run-light.svg" alt="done-done run sync records one screenshot for the current commit." width="400" align="top"></picture>
|
|
63
72
|
<picture><source media="(prefers-color-scheme: dark)" srcset="docs/media/pass-dark.svg"><img src="docs/media/pass-light.svg" alt="A Checks block cites the new screenshot, the judge passes it, and done-done check passes." width="400" align="top"></picture>
|
|
@@ -65,52 +74,21 @@ Four moments from a demo notes app. Every picture is real output from the curren
|
|
|
65
74
|
<picture><source media="(prefers-color-scheme: dark)" srcset="docs/media/reasons-dark.svg"><img src="docs/media/reasons-light.svg" alt="done-done check fails: one screenshot is from an older commit, one file is empty, one is a blank frame." width="400" align="top"></picture>
|
|
66
75
|
<picture><source media="(prefers-color-scheme: dark)" srcset="docs/media/config-dark.svg"><img src="docs/media/config-light.svg" alt="done-done run stops with exit 2 because the config has an unknown key." width="400" align="top"></picture>
|
|
67
76
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
- It's just a CLI any capable agent can run without setup.
|
|
71
|
-
- It's built for agents: [TOON](https://github.com/toon-format/spec) output by default (`--json` and `--full` when needed), and every result names the next command in its `help` lines.
|
|
72
|
-
- The skill below only handles discovery; agents learn done-done by using it.
|
|
77
|
+
The hero above is a real run of the published CLI on a fresh sample repo, replayed line by line: `run` recorded the capture at commit `ca78363`, the Pi judge on `commandcode/deepseek/deepseek-v4.1-flash` read it and passed it with that reason, `receipt` wrote the receipt, and `init` refused a journey whose only command was `npm test`. [The manual walkthrough](docs/manual-cli.md) does the same by hand.
|
|
73
78
|
|
|
74
|
-
## Use
|
|
79
|
+
## Use it from your agent
|
|
75
80
|
|
|
76
|
-
|
|
81
|
+
Give your agent the done-done skill in the [Agent Skills](https://agentskills.io) format, naming your agent with `-a`:
|
|
77
82
|
|
|
78
83
|
```sh
|
|
79
84
|
npx skills add umeranjum17/done-done-axi --skill done-done -a <agent> -y
|
|
80
85
|
```
|
|
81
86
|
|
|
82
|
-
`<agent>` is `claude-code`, `codex`, `opencode`, `pi` or `gemini-cli`.
|
|
87
|
+
`<agent>` is `claude-code`, `codex`, `opencode`, `pi` or `gemini-cli`. The skill lands in this project (`.claude/skills/done-done/` for Claude Code, `.agents/skills/done-done/` for the rest) next to a `skills-lock.json`: commit both so your teammates get it, or add `-g` to install it once for all projects. No npm install is needed: the skill runs `done-done` from your PATH, else the npm package through `npx`. Then ask in plain words ("prove the app in this repo works") or use your agent's slash command.
|
|
83
88
|
|
|
84
|
-
|
|
89
|
+
## Journeys in plain words
|
|
85
90
|
|
|
86
|
-
|
|
87
|
-
The skill tells your agent to use `done-done` if it is on PATH and otherwise run the npm package through `npx`, so the CLI comes along on demand:
|
|
88
|
-
|
|
89
|
-
```sh
|
|
90
|
-
npx -y done-done-axi --help
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
The skill is a short stub and sends the agent to `--help` and the bare command for current instructions, so an installed copy cannot go stale against a newer CLI.
|
|
94
|
-
|
|
95
|
-
Then, in agents that expose skills as slash commands (Claude Code, for example), invoke it directly:
|
|
96
|
-
|
|
97
|
-
```
|
|
98
|
-
/done-done prove the app in this repo works
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
Or just ask in plain words - "prove the app in this repo works", "is this really done?", "gate this PR on proof" - and the agent loads the skill on its own.
|
|
102
|
-
|
|
103
|
-
## Other Ways to Use done-done
|
|
104
|
-
|
|
105
|
-
The skill is the recommended path, but it is not the only one.
|
|
106
|
-
|
|
107
|
-
### Manual CLI
|
|
108
|
-
|
|
109
|
-
Prefer a terminal to an agent skill? The [manual walkthrough](docs/manual-cli.md) covers installation without sudo, choosing agents, capture recipes, core and upgrade journeys, hooks, `doctor`, checks, receipts and the verify/fix loop. All behavior details live there or in the [reference](docs/reference.md).
|
|
110
|
-
|
|
111
|
-
## Write journeys in plain words
|
|
112
|
-
|
|
113
|
-
A journey is the saved script that drives your app and captures what a user sees. You do not have to write it yourself. Describe it, and the agent you chose at `init` writes it:
|
|
91
|
+
A journey is the saved script that drives your app and captures what a user sees. Describe it and your agent writes it:
|
|
114
92
|
|
|
115
93
|
```sh
|
|
116
94
|
done-done journey add "greet Umer and check that Hello Umer is printed"
|
|
@@ -118,127 +96,50 @@ done-done journey enhance greet-umer-prints-hello "add checks for an empty name
|
|
|
118
96
|
done-done journey improve greet-umer-prints-hello "also check that greeting Zoë prints exactly Hello Zoë"
|
|
119
97
|
```
|
|
120
98
|
|
|
121
|
-
|
|
122
|
-
- **`enhance <name> ["<focus>"]`** deepens one journey you already have with more steps, edge cases and checks, and keeps the checks it has. Leave out the focus for a general pass.
|
|
123
|
-
- **`improve <name> "<instruction>"`** makes one specific change to one journey and nothing else.
|
|
99
|
+
`add` writes the script, its config entry and its feature in the verify skill; `enhance` deepens one journey; `improve` makes one change to one journey. Each exercise runs once on uncommitted files, which is a trial, not proof: read the script, commit it, then `done-done run <name>`. The saved script needs no agent or model, so CI can replay it; generation runs only on your machine ([worked transcript](docs/manual-cli.md)).
|
|
124
100
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
```
|
|
128
|
-
$ done-done journey add "greet Umer and check that Hello Umer is printed"
|
|
129
|
-
Added journey greet-umer-prints-hello through claude. Review these repo changes:
|
|
130
|
-
.agents/skills/done-done-verify-hello-umer/features/README.md | 1 +
|
|
131
|
-
.done-done.yaml | 3 +++
|
|
132
|
-
2 files changed, 4 insertions(+)
|
|
133
|
-
journeys/greet-umer-prints-hello.mjs | 29 new lines
|
|
134
|
-
.agents/skills/done-done-verify-hello-umer/features/greet-umer-prints-hello.md | 13 new lines
|
|
135
|
-
The first run is a dirty-tree trial, not clean proof. Review and commit, then: done-done run greet-umer-prints-hello
|
|
136
|
-
ok greet-umer-prints-hello
|
|
137
|
-
command: run
|
|
138
|
-
result: recorded
|
|
139
|
-
dirty: true
|
|
140
|
-
files: 1
|
|
141
|
-
evidence[1]: …/terminal.txt
|
|
142
|
-
|
|
143
|
-
$ done-done journey enhance greet-umer-prints-hello "add checks for an empty name and an unknown command"
|
|
144
|
-
Enhanced journey greet-umer-prints-hello through claude. Review these repo changes:
|
|
145
|
-
.../features/greet-umer-prints-hello.md | 8 +++++++
|
|
146
|
-
.done-done.yaml | 4 +++-
|
|
147
|
-
journeys/greet-umer-prints-hello.mjs | 27 +++++++++++++++++++---
|
|
148
|
-
3 files changed, 35 insertions(+), 4 deletions(-)
|
|
149
|
-
…
|
|
150
|
-
files: 3
|
|
151
|
-
evidence[3]: …/terminal-empty-name.txt,…/terminal-unknown-command.txt,…/terminal.txt
|
|
152
|
-
|
|
153
|
-
$ done-done journey improve greet-umer-prints-hello "also check that greeting Zoë prints exactly Hello Zoë"
|
|
154
|
-
Improved journey greet-umer-prints-hello through claude. Review these repo changes:
|
|
155
|
-
.../features/greet-umer-prints-hello.md | 8 ++++++++
|
|
156
|
-
.done-done.yaml | 1 +
|
|
157
|
-
journeys/greet-umer-prints-hello.mjs | 11 ++++++++++-
|
|
158
|
-
3 files changed, 19 insertions(+), 1 deletion(-)
|
|
159
|
-
…
|
|
160
|
-
files: 4
|
|
161
|
-
evidence[4]: …/terminal-empty-name.txt,…/terminal-unknown-command.txt,…/terminal-zoe.txt,…/terminal.txt
|
|
162
|
-
```
|
|
101
|
+
## Inside Firstmate, or another agent fleet
|
|
163
102
|
|
|
164
|
-
|
|
103
|
+
done-done works the same with or without Firstmate: the skill and CLI behave identically inside or outside a Firstmate home. [Firstmate](https://github.com/kunchenguid/firstmate) hands tasks to agent workers and merges their work, and [`integrations/firstmate/`](integrations/firstmate/) ships the two files those workers need:
|
|
165
104
|
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
# Improved instruction: "also check that greeting Zoë prints exactly Hello Zoë"
|
|
172
|
-
node journeys/greet-umer-prints-hello.mjs
|
|
105
|
+
```sh
|
|
106
|
+
npx skills add umeranjum17/done-done-axi --skill done-done -g -a <agent> -y
|
|
107
|
+
npm install -g done-done-axi
|
|
108
|
+
cat "$(npm root -g)/done-done-axi/integrations/firstmate/brief-include.md" >> "$FM_HOME/config/brief-include.md"
|
|
109
|
+
cp "$(npm root -g)/done-done-axi/integrations/firstmate/merge-gate" "$FM_HOME/config/merge-gate"
|
|
173
110
|
```
|
|
174
111
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
## What it checks
|
|
178
|
-
|
|
179
|
-
- 🧪 **The real product, not code checks**: Proof must come from driving the app, CLI or site the way a user does. A config whose journeys only run tests, typecheck, lint or a build, or proof whose captures all come from such runs, is refused by `check`, `receipt` and `gate`, and `doctor` flags it ([rule](docs/reference.md#real-product-evidence)).
|
|
180
|
-
- 🎯 **The core journey and the upgrade users take**: Each app names the one flow a user cannot live without, driven end to end on the real target, and an app that ships an installable artifact also names the upgrade over its previous release. `doctor` and the verify skill `init` writes require both ([rule](docs/reference.md#core-journey-and-release-path)).
|
|
181
|
-
- 🧭 **The journeys your change needs**: `done-done affected [<base>]` reads the diff since the last receipt (or the default branch), maps each changed file to the journeys whose command runs it and the verify skill features whose file cites it, adds the core journey when a file is in no feature or journey, and exits 1 until a receipt for HEAD has a run of each. It flags the files no feature covers, so the feature map grows with the code ([how](docs/reference.md#affected-journeys)).
|
|
182
|
-
- 🔗 **Tied to a commit**: Every run records the commit, and whether there were uncommitted changes.
|
|
183
|
-
- 🖼️ **Real media**: Empty, cut-off, blank or tiny screenshots fail. Videos must hold real frames (needs `ffprobe`).
|
|
184
|
-
- ⏱️ **Fresh**: Proof from an older commit fails. Commits that only touch docs can be set to keep it fresh.
|
|
185
|
-
- ♻️ **Not reused**: Proof made only of files already used for a different claim fails, and so does citing the same file twice. A claim is named by `--claim-id <id>`, which defaults to your branch, so rewording it keeps its proof. Several claims on one branch each need their own `--claim-id`.
|
|
186
|
-
- 🧾 **Honest claims**: Reads a pull request's `## Checks` block — from a file, a URL, or stdin — and makes sure every line is filled in.
|
|
187
|
-
- 📌 **Verifiable later**: `receipt` records a passing check against the exact commit and the sha256 of every file it cited; `receipt --verify` re-checks it from any checkout of that commit on the same machine (a merge gate or a fresh clone) ([how](docs/reference.md#where-proof-lives)).
|
|
188
|
-
- 👀 **Shows the outcome** (always): `check`, `receipt` and `verify` start done-done's own judge, a fresh, tools-off agent on your own plan or key (Claude Code, opencode, pi or Gemini CLI, or your own OpenAI API key), to say whether each capture is the right screen for the claim (and each text capture, such as a log, JSON or CLI output, the right output), and a wrong one fails. There is no way to turn it off: done-done gives no result without it. The checks above never pass on their own, and a check that cites only files the judge cannot read (a video) stops before the judge, with exit 2. You choose the judge route (`done-done init --judge <agent> --judge-model <model>`, or pick it from the list done-done shows in a terminal; `done-done check --judge <route>` overrides it for one call); for a Pi judge with no explicit model, done-done defaults to `openai-codex/gpt-6-luna` unless `agent_config.pi.model` is set. Any agent and model you choose runs, your coding agent's own too. A judge that fails or times out stops the command with its cause (exit 2; a `verify` run stops with exit 2 and its cause in the run record), and no receipt is written.
|
|
189
|
-
- 🎨 **Looks right**: `done-done design <screens...> [--mock <screen>=<mock>]` has the same judge look at each captured screen, alone or next to its approved mock, and fails it on stretched or squashed images, clipped or squashed text, overlap, elements off-screen, blank or black strips and broken layout, naming each defect and where it is ([how](docs/reference.md#design-check)).
|
|
190
|
-
- 📐 **Fits the screen**: `done-done look <url>` opens a web page in headless Chrome at a 390x844 phone viewport, captures it, and fails the journey that calls it on squashed text, clipped text, elements cut off by an edge or a page wider than the screen, naming each element, with no model ([how](docs/reference.md#look-check)).
|
|
191
|
-
- 🧮 **Honest, cheap claim gate**: `done-done lint <PR URL | report file> <evidence folder>` is a no-model gate on a worker's `## Checks` block, on whenever you call it. It prints `PASS` or `FAIL: <reason>` and exits 1 on a fail: the four lines present, proof naming a command or path, a real repro on a fix PR, evidence files that exist, are non-empty, are newer than the evidence folder and differ from each other, at least one never used by another PR (hashes kept in `~/.done-done/lint.hashes`, every run logged to `lint.log` there), under 1,000 added non-generated lines, and a `WARN` when a PR changes `src/` with no `journeys/` file ([how](docs/reference.md#lint-check)). `evidence: not proven: <cause>` passes.
|
|
192
|
-
- 🚦 **CI gate, no model**: `done-done gate [<head>]` passes when a receipt committed under `.done-done-receipts/` covers the head and its captures come from real-product runs, with no judge, config, key or evidence files. CI never runs `check`, `run` or `verify` and never gets a model key; proof runs on your desktop ([how](docs/reference.md#ci-gate)).
|
|
193
|
-
- 🧩 **Page is clean** (with a `dom` block): each captured screen also needs its page-check record. A page that overflows the viewport, logs a console error, has a failed request or shows squashed, clipped or cut-off UI fails, unless an allow list names it ([how](docs/reference.md#dom-assertions)).
|
|
194
|
-
|
|
195
|
-
Every answer is an exit code: **0** pass, **1** fail, **2** usage or config error (including no agent or judge set, a check that fails before its judge, a capture the judge cannot be sent, or a judge that did not answer: never a result), **3** can't tell either way, **4** a `verify`, `maintain` or `rerun` run is still running, or a `verify` run waits at its gate.
|
|
196
|
-
|
|
197
|
-
### Interaction polish needs proof too
|
|
198
|
-
|
|
199
|
-
Opt in with `interaction_checklist` in `.done-done.yaml`: detail next/previous plus swipe, instant send/answer state, destructive undo, scroll position on back, long-list search/filter, and useful empty states. Each item needs judged real-product frames or an explicit not-applicable reason; missing proof is flagged, never silently passed. The [shipped checklist and wiring](docs/reference.md#interaction-checklist-opt-in) extend `check`, `receipt` and `verify`; existing approved-design checks stay unchanged without opt-in.
|
|
200
|
-
|
|
201
|
-
## Alone, and with the other tools
|
|
202
|
-
|
|
203
|
-
done-done works on its own: the CLI and the skill need nothing else. It is one of three tools that each do one job and connect through small written contracts ([Vision](VISION.md)):
|
|
112
|
+
- **`brief-include.md`**: Firstmate adds `config/brief-include.md` to every worker brief. It tells the worker to set up done-done, run the journeys `done-done affected` lists for its committed change, write a `## Checks` block, pass `check`, record a `receipt`, and see `affected` exit 0.
|
|
113
|
+
- **`merge-gate`** (optional): refuses a PR whose head is not the one asked for, then runs `done-done check --from <PR URL>` and `done-done receipt --verify <head>` against your default branch's rules. Upstream Firstmate does not call a merge gate yet, so run it by hand until it does ([details](docs/reference.md#merge-gate-on-the-desktop)).
|
|
204
114
|
|
|
205
|
-
|
|
206
|
-
- [`learn-from-mistakes-axi`](https://www.npmjs.com/package/learn-from-mistakes-axi): the retro tool that finds mistakes your agents keep repeating, with evidence. Neither tool needs the other.
|
|
207
|
-
- [`first-draft-axi`](https://www.npmjs.com/package/first-draft-axi): turns a prompt into design mocks. Pass a mock to `done-done design <screen> --mock <screen>=<mock>` to judge a captured screen next to it.
|
|
115
|
+
Another fleet works the same way: add the include text to whatever your workers read first, and run `merge-gate` before each merge, with `FM_HOME` set to the folder that holds `data/<task-id>/checks.md` for local-only tasks. Evidence and receipts stay in `~/.done-done/evidence/<app>` after teardown.
|
|
208
116
|
|
|
209
|
-
##
|
|
117
|
+
## The other two tools
|
|
210
118
|
|
|
211
|
-
done-done works the
|
|
119
|
+
done-done works on its own: the CLI and the skill need nothing else. It is one of three tools that each do one job and connect through small written contracts ([Vision](VISION.md)): [sign-off-axi](https://www.npmjs.com/package/sign-off-axi) is the board where agents ask you questions (`done-done signoff` prepares a run's card, `--wait` brings the answer back, and the opt-in posts it); [learn-from-mistakes-axi](https://www.npmjs.com/package/learn-from-mistakes-axi) finds the mistakes your agents keep repeating; [first-draft-axi](https://www.npmjs.com/package/first-draft-axi) turns a prompt into design mocks you can judge a capture against.
|
|
212
120
|
|
|
121
|
+
## Known limits
|
|
213
122
|
|
|
214
|
-
|
|
123
|
+
- **Claude Code and Codex are proven live. OpenCode is not yet proven live** on our test machine ([why, and what to try](docs/reference.md#agent-and-judge-support-today)).
|
|
124
|
+
- Codex readers and probes need a CLI with `exec --ignore-user-config` and `debug models --bundled`. Codex is not a judge route; a Pi judge on `openai-codex/gpt-6.1-sol` judges through your existing Codex login.
|
|
125
|
+
- done-done keeps no login of its own: every agent and judge call runs your installed, signed-in CLI on your plan or key.
|
|
126
|
+
- Early preview: behaviour and config keys can change between minor versions.
|
|
215
127
|
|
|
216
|
-
|
|
128
|
+
## Manual CLI
|
|
217
129
|
|
|
218
|
-
|
|
219
|
-
npx skills add umeranjum17/done-done-axi --skill done-done -g -a <agent> -y
|
|
220
|
-
npm install -g done-done-axi
|
|
221
|
-
cat "$(npm root -g)/done-done-axi/integrations/firstmate/brief-include.md" >> "$FM_HOME/config/brief-include.md"
|
|
222
|
-
cp "$(npm root -g)/done-done-axi/integrations/firstmate/merge-gate" "$FM_HOME/config/merge-gate"
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
- **`brief-include.md`**: Firstmate adds `config/brief-include.md` to every worker brief. It tells the worker to set up done-done, run the journeys `done-done affected` lists for its committed change, write a `## Checks` block, pass `check`, record a `receipt`, and see `affected` exit 0. The evidence and receipt stay in `~/.done-done/evidence/<app>` after teardown deletes the worktree.
|
|
226
|
-
- **`merge-gate`** (optional): `merge-gate <task-id> <worktree|-> <head> <pr-url|->`. In the worktree, it refuses a PR whose head is not `<head>`, then runs `done-done check --from <PR URL or $FM_HOME/data/<task-id>/checks.md> --trusted-ref <default branch>` (`origin/HEAD`, else `origin/main` or `origin/master`, else the local `main` or `master` in a repo with no remote), then `done-done receipt --verify <head>`. Both paths read done-done's rules from your default branch, never from the task's own branch, so merge `.done-done.yaml` there before you rely on it. The gate does not fetch: it reads the local `origin` refs, so run `git fetch origin` before you run it. It needs `done-done` on PATH (the `npm install` line above). A nonzero exit refuses the merge, and done-done's output says why. A worktree of `-` means the task recorded none, so there is no repo to check: the gate refuses (exit 2) rather than check whatever folder it was called from. Its `check` always starts the judge the user set, which must pass each capture; with none set, the gate refuses (exit 2). Upstream Firstmate does not call a merge gate yet, so this file has no effect until it does; you can run it by hand before a merge.
|
|
227
|
-
|
|
228
|
-
Another fleet works the same way: add the include text to whatever your workers read first, and run `merge-gate` before each merge, with `FM_HOME` set to the folder that holds `data/<task-id>/checks.md` for local-only tasks.
|
|
130
|
+
Prefer a terminal to an agent skill? The [manual walkthrough](docs/manual-cli.md) covers installation without sudo, choosing agents, capture recipes, core and upgrade journeys, hooks, `doctor`, checks, receipts and the verify/fix loop. Every behaviour detail is there or in the [full reference](docs/reference.md).
|
|
229
131
|
|
|
230
132
|
## Learn more
|
|
231
133
|
|
|
232
134
|
- [Vision](VISION.md): who done-done is for, the problem, where it is going, what it is not, and the next milestones.
|
|
233
|
-
- [Worked example: a CLI project](docs/example-cli.md)
|
|
234
|
-
- [Worked example: create and maintain a verify skill](docs/example-create-maintain.md): init writes the skill, a source change makes it drift, maintain fixes it, then a real browser journey is judged.
|
|
135
|
+
- [Worked example: a CLI project](docs/example-cli.md) and [create and maintain a verify skill](docs/example-create-maintain.md).
|
|
235
136
|
- [Full reference](docs/reference.md): every command and option, the Checks block rules, each file check, and both config files.
|
|
236
|
-
- [Config reference](docs/reference.md#config):
|
|
137
|
+
- [Config reference](docs/reference.md#config): pooled Claude accounts for judge and agent calls, and the Codex fallback route.
|
|
237
138
|
- [Report a problem or ask a question](https://github.com/umeranjum17/done-done-axi/issues)
|
|
238
139
|
|
|
239
140
|
## What's next
|
|
240
141
|
|
|
241
|
-
|
|
142
|
+
Early preview: behaviour and config keys can change between minor versions. Shipped so far: `init`, `doctor`, `run`, `check`, `receipt`, `verify`, `journey add|enhance|improve`, `maintain`, `affected`, `lint`, `gate`, `design`, `look`, and the run tools (`status`, `attach`, `logs`, `rerun`, `abort`, `signoff`, `history`). Next: the [milestones in the vision](VISION.md#next-milestones).
|
|
242
143
|
|
|
243
144
|
## Develop
|
|
244
145
|
|
|
@@ -246,20 +147,9 @@ So far: `init`, `doctor`, `run` (including `--open` and `--close`), `check`, `re
|
|
|
246
147
|
git clone https://github.com/umeranjum17/done-done-axi
|
|
247
148
|
cd done-done-axi
|
|
248
149
|
npm install
|
|
249
|
-
npm
|
|
250
|
-
npm test # builds, then runs the end-to-end tests against throwaway git repos
|
|
251
|
-
npm run build:skill # regenerate skills/done-done/SKILL.md from src/skill.ts
|
|
252
|
-
npm run build:skill -- --check # fail if the committed skill is out of date
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
To try an unreleased commit without cloning, run it straight from GitHub (npm 12 needs `--allow-git=all`):
|
|
256
|
-
|
|
257
|
-
```sh
|
|
258
|
-
npx -y --allow-git=all github:umeranjum17/done-done-axi --help
|
|
150
|
+
npm test
|
|
259
151
|
```
|
|
260
152
|
|
|
261
|
-
`dist/` is committed, so installing from GitHub needs no build step
|
|
262
|
-
|
|
263
|
-
The first-screen PNG pairs an actual sample-app screenshot with its real configured-judge pass and captured commit. Start a fresh sample with `node docs/media/demo.mjs <fresh-scratch-directory> 0` (the server prints its owned port), open a native run in its `app/` repo, drive the checklist in the browser, save `app.png` at 400×140 DPR 2 into the run's evidence folder, seal it and run `check` with your configured judge. Save the open result as `<scratch>/open.json` and the check result as `<scratch>/check.json`; `/proof` displays that screenshot and verdict. Capture `/proof` at 400×230 DPR 2 with `chrome-devtools-axi`. It refuses to show a pass without a real passing result. Keep scratch outside the repo and stop the server afterwards. The lower terminal illustrations (hero, run, pass, reasons, config) use a stub judge (no model); redraw them with `npx tsc && node docs/media/make.mjs`. The logo (`docs/logo.svg`) and the flow picture are hand-made SVGs.
|
|
153
|
+
`npm test` builds, then runs the end-to-end tests against throwaway git repos. `dist/` is committed, so installing from GitHub needs no build step; `npm test` fails while the rebuilt `dist/` differs from the commit, so `git add` the new files with your change. [Working on done-done](docs/reference.md#working-on-done-done) covers the skill build, the sample app and the screenshots.
|
|
264
154
|
|
|
265
155
|
The landing page ([`docs/index.html`](docs/index.html), served by GitHub Pages from `main` `/docs`) is static: change it in the same PR as any README change it repeats (install steps, what it checks, the other tools).
|
package/docs/index.html
CHANGED
|
@@ -159,7 +159,7 @@ done-done verify --outcome "<what works now>"</code></pre>
|
|
|
159
159
|
<section id="firstmate">
|
|
160
160
|
<h2>Inside Firstmate, or outside</h2>
|
|
161
161
|
<p class="lead">done-done behaves the same with or without <a href="https://github.com/kunchenguid/firstmate">Firstmate</a>. Nothing here is needed to use it.</p>
|
|
162
|
-
<p class="lead">Inside a Firstmate home, <code>integrations/firstmate/</code> ships a brief include that tells each worker to run a journey, write a <code>## Checks</code> block, pass <code>check</code> and record a <code>receipt</code>, and an optional merge gate that refuses a merge without it. A lone agent in a terminal skips all of that. Upstream Firstmate does not call the merge gate yet; run it by hand if you want it to enforce the check. <a href="https://github.com/umeranjum17/done-done-axi#
|
|
162
|
+
<p class="lead">Inside a Firstmate home, <code>integrations/firstmate/</code> ships a brief include that tells each worker to run a journey, write a <code>## Checks</code> block, pass <code>check</code> and record a <code>receipt</code>, and an optional merge gate that refuses a merge without it. A lone agent in a terminal skips all of that. Upstream Firstmate does not call the merge gate yet; run it by hand if you want it to enforce the check. <a href="https://github.com/umeranjum17/done-done-axi#inside-firstmate-or-another-agent-fleet">Integration instructions</a>.</p>
|
|
163
163
|
</section>
|
|
164
164
|
|
|
165
165
|
</main>
|
package/docs/manual-cli.md
CHANGED
|
@@ -73,4 +73,70 @@ With `auto_fix: { verify: <n> }` (0, the default, reports only), a failed verify
|
|
|
73
73
|
|
|
74
74
|
While a `verify` or `maintain` run goes, `done-done status` shows its steps and next move, `done-done attach` streams its events, and `done-done logs --step <name>` shows one step's log. `done-done rerun` runs a failed verify run again from the failed step, `done-done abort` stops a live run, `done-done signoff` writes a verify run's sign-off message, and `done-done history` lists past runs.
|
|
75
75
|
|
|
76
|
+
**4. Write a journey from plain words**
|
|
77
|
+
|
|
78
|
+
A journey is the saved script that drives your app and captures what a user sees. You do not have to write it yourself; describe it and the agent you chose at `init` writes it:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
done-done journey add "greet Umer and check that Hello Umer is printed"
|
|
82
|
+
done-done journey enhance greet-umer-prints-hello "add checks for an empty name and an unknown command"
|
|
83
|
+
done-done journey improve greet-umer-prints-hello "also check that greeting Zoë prints exactly Hello Zoë"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
- **`add "<description>"`** writes a new journey: a capture script in `journeys/`, its entry in `.done-done.yaml` and a feature in your verify skill. It names the journey from your words and prints that name.
|
|
87
|
+
- **`enhance <name> ["<focus>"]`** deepens one journey you already have with more steps, edge cases and checks, and keeps the checks it has. Leave out the focus for a general pass.
|
|
88
|
+
- **`improve <name> "<instruction>"`** makes one specific change to one journey and nothing else.
|
|
89
|
+
|
|
90
|
+
Each command prints the files it changed, then runs the journey once. This is the real output of the three lines above, from a clean install on a small greeting CLI with Claude Code as the agent (run paths cut short with `…`):
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
$ done-done journey add "greet Umer and check that Hello Umer is printed"
|
|
94
|
+
Added journey greet-umer-prints-hello through claude. Review these repo changes:
|
|
95
|
+
.agents/skills/done-done-verify-hello-umer/features/README.md | 1 +
|
|
96
|
+
.done-done.yaml | 3 +++
|
|
97
|
+
2 files changed, 4 insertions(+)
|
|
98
|
+
journeys/greet-umer-prints-hello.mjs | 29 new lines
|
|
99
|
+
.agents/skills/done-done-verify-hello-umer/features/greet-umer-prints-hello.md | 13 new lines
|
|
100
|
+
The first run is a dirty-tree trial, not clean proof. Review and commit, then: done-done run greet-umer-prints-hello
|
|
101
|
+
ok greet-umer-prints-hello
|
|
102
|
+
command: run
|
|
103
|
+
result: recorded
|
|
104
|
+
dirty: true
|
|
105
|
+
files: 1
|
|
106
|
+
evidence[1]: …/terminal.txt
|
|
107
|
+
|
|
108
|
+
$ done-done journey enhance greet-umer-prints-hello "add checks for an empty name and an unknown command"
|
|
109
|
+
Enhanced journey greet-umer-prints-hello through claude. Review these repo changes:
|
|
110
|
+
.../features/greet-umer-prints-hello.md | 8 +++++++
|
|
111
|
+
.done-done.yaml | 4 +++-
|
|
112
|
+
journeys/greet-umer-prints-hello.mjs | 27 +++++++++++++++++++---
|
|
113
|
+
3 files changed, 35 insertions(+), 4 deletions(-)
|
|
114
|
+
…
|
|
115
|
+
files: 3
|
|
116
|
+
evidence[3]: …/terminal-empty-name.txt,…/terminal-unknown-command.txt,…/terminal.txt
|
|
117
|
+
|
|
118
|
+
$ done-done journey improve greet-umer-prints-hello "also check that greeting Zoë prints exactly Hello Zoë"
|
|
119
|
+
Improved journey greet-umer-prints-hello through claude. Review these repo changes:
|
|
120
|
+
.../features/greet-umer-prints-hello.md | 8 ++++++++
|
|
121
|
+
.done-done.yaml | 1 +
|
|
122
|
+
journeys/greet-umer-prints-hello.mjs | 11 ++++++++++-
|
|
123
|
+
3 files changed, 19 insertions(+), 1 deletion(-)
|
|
124
|
+
…
|
|
125
|
+
files: 4
|
|
126
|
+
evidence[4]: …/terminal-empty-name.txt,…/terminal-unknown-command.txt,…/terminal-zoe.txt,…/terminal.txt
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`.done-done.yaml` keeps what you asked for next to the journey:
|
|
130
|
+
|
|
131
|
+
```yaml
|
|
132
|
+
journeys:
|
|
133
|
+
greet-umer-prints-hello:
|
|
134
|
+
command:
|
|
135
|
+
# Enhanced focus: "add checks for an empty name and an unknown command"
|
|
136
|
+
# Improved instruction: "also check that greeting Zoë prints exactly Hello Zoë"
|
|
137
|
+
node journeys/greet-umer-prints-hello.mjs
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
That first run is a trial on uncommitted files, not proof. Read the generated script as you would any code an agent wrote, commit it, then `done-done run greet-umer-prints-hello` records clean proof (`dirty: false`). The saved script needs no agent or model, so CI can replay it. Generation itself runs only on your machine, never in CI, and uses only the agent you configured. `done-done journey --help` shows these examples; the [reference](reference.md#add-a-journey-from-a-description) has every rule.
|
|
141
|
+
|
|
76
142
|
Run `done-done` with no arguments to see the current config and the next step.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
$ done-done init --journey tests -- 'npm test'
|
|
2
|
+
command: init
|
|
3
|
+
error: "init --journey tests: npm test is code-only: a test, typecheck, lint or build run proves the code checks pass, not that the product works, so check and gate never count its run as proof; nothing was written"
|
|
4
|
+
exit: 2
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
$ done-done run greet
|
|
2
|
+
command: run
|
|
3
|
+
result: recorded
|
|
4
|
+
run_id: 20261025T033042Z-ca783630-43267e
|
|
5
|
+
commit: ca783630026370864950bce53bc5efab802d29d6
|
|
6
|
+
dirty: false
|
|
7
|
+
files: 1
|
|
8
|
+
record: ~/.done-done/evidence/sample/.done-done/runs/20261025T033042Z-ca783630-43267e.json
|
|
9
|
+
evidence[1]: 20261025T033042Z-ca783630-43267e.terminal.txt
|
|
10
|
+
|
|
11
|
+
$ done-done check --outcome "running greet.mjs with Umer prints Hello Umer" "$evidence"
|
|
12
|
+
command: check
|
|
13
|
+
result: pass
|
|
14
|
+
claim: running greet.mjs with Umer prints Hello Umer
|
|
15
|
+
files: 1
|
|
16
|
+
evidence[1]: 20261025T033042Z-ca783630-43267e.terminal.txt
|
|
17
|
+
judge:
|
|
18
|
+
route: "answerer:pi"
|
|
19
|
+
model: commandcode/deepseek/deepseek-v4.1-flash
|
|
20
|
+
independence: agent
|
|
21
|
+
author: claude (model claude-haiku-5-5)
|
|
22
|
+
judged[1]{path,verdict,reason,seen,cached}:
|
|
23
|
+
20261025T033042Z-ca783630-43267e.terminal.txt,pass,The output shows running greet.mjs with Umer and printing Hello Umer.,"I read the single capture entry. The command line \"$ node greet.mjs Umer\" runs greet.mjs with Umer, and the following output line \"Hello Umer\" matches the outcome exactly, with no error or contradiction.",false
|
|
24
|
+
note: "PNG and JPEG screens and text captures (logs, JSON, CLI output) are judged; video and other files are not"
|
|
25
|
+
|
|
26
|
+
$ done-done receipt --outcome "running greet.mjs with Umer prints Hello Umer" "$evidence"
|
|
27
|
+
command: receipt
|
|
28
|
+
result: pass
|
|
29
|
+
head: ca783630026370864950bce53bc5efab802d29d6
|
|
30
|
+
tree: 3dff6448314deb0fe0325786bc9a7c2369366be6
|
|
31
|
+
claim: running greet.mjs with Umer prints Hello Umer
|
|
32
|
+
files: 1
|
|
33
|
+
receipt: ~/.done-done/evidence/sample/.done-done/receipts/ca783630026370864950bce53bc5efab802d29d6.json
|
|
34
|
+
judge:
|
|
35
|
+
route: "answerer:pi"
|
|
36
|
+
model: commandcode/deepseek/deepseek-v4.1-flash
|
|
37
|
+
independence: agent
|
|
38
|
+
author: claude (model claude-haiku-5-5)
|
|
39
|
+
judged[1]{path,verdict,reason,seen,cached}:
|
|
40
|
+
20261025T033042Z-ca783630-43267e.terminal.txt,pass,The output shows running greet.mjs with Umer and printing Hello Umer.,"I read the single capture entry. The command line \"$ node greet.mjs Umer\" runs greet.mjs with Umer, and the following output line \"Hello Umer\" matches the outcome exactly, with no error or contradiction.",true
|
|
41
|
+
note: "PNG and JPEG screens and text captures (logs, JSON, CLI output) are judged; video and other files are not"
|
|
Binary file
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Build the README hero pages from the captured CLI transcripts in this folder.
|
|
2
|
+
// Every value shown is asserted to exist in a transcript; only field order and long paths change.
|
|
3
|
+
// Usage: node docs/media/hero.mjs, then screenshot .hero/hero-desktop.html (828x596) and
|
|
4
|
+
// .hero/hero-phone.html (418x792) at device scale factor 2, in light and dark:
|
|
5
|
+
// hero-light.png, hero-dark.png (1600 px wide source shown at width 100%), hero-phone-*.png.
|
|
6
|
+
// The animated hero.gif replays the same lines one by one (1200 px wide, 16 frames, ~9 s),
|
|
7
|
+
// ending on the judge's pass and the receipt; it is captured from the same page with the
|
|
8
|
+
// lines revealed a step at a time, one row's worth of pixels cropped off each earlier frame.
|
|
9
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
10
|
+
import { dirname, join } from 'node:path';
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
|
|
13
|
+
const dir = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const pass = readFileSync(join(dir, 'hero-run.txt'), 'utf8');
|
|
15
|
+
const refuse = readFileSync(join(dir, 'hero-refuse.txt'), 'utf8');
|
|
16
|
+
const need = (hay, s) => {
|
|
17
|
+
if (!hay.includes(s)) throw new Error(`not in the captured transcript: ${s}`);
|
|
18
|
+
return s;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const commit = need(pass, 'ca783630026370864950bce53bc5efab802d29d6');
|
|
22
|
+
const reason = need(pass, 'The output shows running greet.mjs with Umer and printing Hello Umer.');
|
|
23
|
+
const model = need(pass, 'commandcode/deepseek/deepseek-v4.1-flash');
|
|
24
|
+
const err = need(refuse, 'init --journey tests: npm test is code-only: a test, typecheck, lint or build run proves the code checks pass, not that the product works, so check and gate never count its run as proof; nothing was written');
|
|
25
|
+
|
|
26
|
+
const esc = (s) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
27
|
+
const L = (cls, s) => `<div class="${cls}">${esc(s)}</div>`;
|
|
28
|
+
|
|
29
|
+
const body = ({ phone }) => [
|
|
30
|
+
L('cmd', '$ done-done run greet'),
|
|
31
|
+
L('out', 'result: recorded'),
|
|
32
|
+
L('out', `commit: ${commit}`),
|
|
33
|
+
L('out', 'dirty: false'),
|
|
34
|
+
L('out', 'files: 1'),
|
|
35
|
+
'',
|
|
36
|
+
L('cmd', `$ done-done check --outcome "greeting Umer prints Hello Umer" ${phone ? '…' : '…terminal.txt'}`),
|
|
37
|
+
L('ok', 'result: pass'),
|
|
38
|
+
L('out', 'judge: answerer:pi'),
|
|
39
|
+
L('out', `model: ${model}`),
|
|
40
|
+
L('ok', `reason: "${reason}"`),
|
|
41
|
+
'',
|
|
42
|
+
L('cmd', '$ done-done receipt --outcome "greeting Umer prints Hello Umer"'),
|
|
43
|
+
L('ok', 'result: pass'),
|
|
44
|
+
L('out', `receipt: receipts/${commit}.json`),
|
|
45
|
+
'<div class="rule"></div>',
|
|
46
|
+
L('cmd', "$ done-done init --journey tests -- 'npm test'"),
|
|
47
|
+
L('bad', 'result: fail'),
|
|
48
|
+
L('bad', `error: ${err}`),
|
|
49
|
+
].join('\n');
|
|
50
|
+
|
|
51
|
+
const page = ({ width, font, phone, title }) => `<!doctype html><meta charset="utf-8"><title>${title}</title>
|
|
52
|
+
<style>
|
|
53
|
+
:root { color-scheme: light dark; }
|
|
54
|
+
html, body { margin: 0; background: #f6f8fa; }
|
|
55
|
+
body { font: ${font}px/1.62 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
|
|
56
|
+
.card { width: ${width}px; box-sizing: border-box; margin: 14px; padding: 16px 18px; border-radius: 10px;
|
|
57
|
+
background: #fff; border: 1px solid #d8dee4; color: #1f2328; }
|
|
58
|
+
.meta { font: 600 12px/1.4 ui-sans-serif, system-ui, sans-serif; letter-spacing: .01em; color: #57606a; margin-bottom: 10px; }
|
|
59
|
+
.cmd { color: #6639ba; font-weight: 600; margin-top: 10px; white-space: pre-wrap; word-break: break-word; }
|
|
60
|
+
.out { color: #1f2328; white-space: pre-wrap; word-break: break-word; }
|
|
61
|
+
.ok { color: #1a7f37; white-space: pre-wrap; word-break: break-word; }
|
|
62
|
+
.bad { color: #b42318; white-space: pre-wrap; word-break: break-word; }
|
|
63
|
+
.rule { border-top: 1px dashed #d8dee4; margin: 14px 0 2px; }
|
|
64
|
+
@media (prefers-color-scheme: dark) {
|
|
65
|
+
html, body { background: #0d1117; }
|
|
66
|
+
.card { background: #161b22; border-color: #30363d; color: #e6edf3; }
|
|
67
|
+
.meta { color: #8b949e; }
|
|
68
|
+
.cmd { color: #d2a8ff; }
|
|
69
|
+
.out { color: #e6edf3; }
|
|
70
|
+
.ok { color: #3fb950; }
|
|
71
|
+
.bad { color: #ff7b72; }
|
|
72
|
+
.rule { border-color: #30363d; }
|
|
73
|
+
}
|
|
74
|
+
</style>
|
|
75
|
+
<div class="card">
|
|
76
|
+
<div class="meta">done-done 0.6.12 · real run on a small sample app</div>
|
|
77
|
+
${body({ phone })}
|
|
78
|
+
</div>`;
|
|
79
|
+
|
|
80
|
+
const out = join(dir, '.hero');
|
|
81
|
+
mkdirSync(out, { recursive: true });
|
|
82
|
+
writeFileSync(join(out, 'hero-desktop.html'), page({ width: 800, font: 15, phone: false, title: 'done-done hero, desktop' }));
|
|
83
|
+
writeFileSync(join(out, 'hero-phone.html'), page({ width: 390, font: 14, phone: true, title: 'done-done hero, phone' }));
|
|
84
|
+
console.log(`wrote ${out}/hero-desktop.html and ${out}/hero-phone.html`);
|
package/docs/reference.md
CHANGED
|
@@ -100,6 +100,16 @@ done-done starts the coding agent you choose, and never picks one. `agent:` name
|
|
|
100
100
|
|
|
101
101
|
Each call is a fresh, single-shot session that must answer one JSON object matching a schema. The prompt goes on stdin (claude, codex, pi, gemini, acp) or into a 0600 prompt file (opencode), never in argv. done-done can start claude (`claude -p --output-format json --json-schema <schema> --model <model> --no-session-persistence`, all tools off with `--tools ''`; tool-less calls also pass `--setting-sources ''` and run from a scratch folder, so no project settings or hooks load; read-only calls allow only `--tools Read,Grep,Glob` and pass `--setting-sources ''` and `--strict-mcp-config`, so no user settings or MCP servers load), opencode (`opencode run "Follow the attached instructions." --format json -m <provider/model> -f <prompt file>`, with the schema in the 0600 prompt file and every tool denied through `OPENCODE_PERMISSION` except on an edit step ([Drive by agent](#drive-by-agent), Scope)), pi (`pi -p --mode json --no-session --no-tools`, tools off for every read or probe call, since pi has no read-only mode that refuses outside reads, and `--model <model>` only when one is set) and gemini (`gemini -p "Follow the instructions on stdin." -o json -m <model> --approval-mode plan|auto_edit`, where `plan` is read-only for the probe and read steps and `auto_edit` is used for edit steps; `--skip-trust` is added only to the tool-less probe in its scratch folder, so repo calls keep Gemini's workspace trust gate) and codex (`codex exec --json --ephemeral [-m <model>]`, the answer being the last agent message of its JSONL events; an edit step runs in codex's `--sandbox workspace-write` with the run's evidence and scratch folders added by `--add-dir` and network on, so the drive can launch the app and talk to it, while it keeps your own codex config). Codex readers and probes run a separate `--no-daemon exec --ignore-user-config --ignore-rules --skip-git-repo-check --sandbox read-only` call, with project instructions disabled and your normal authentication untouched. Feature flags alone do not remove all tools: model metadata can force code-mode, collaboration and patch tools back on. done-done reads the CLI's public bundled catalog (`codex debug models --bundled`), writes a scratch-only copy with those capabilities removed, disables the remaining tool features and web search, and supplies it through `model_catalog_json`. A missing catalog, unsupported CLI or model not in that catalog fails with its cause; no unsafe fallback or copied login is used. `doctor --probe` now requires a real Codex answer, and `init` and maintain use the same clean reader. Native Codex image judging is not implemented; Codex image judging is available through `answerer:pi` with `openai-codex/gpt-6.1-sol` on your existing Codex login. `acp:<target>` runs `acpx --cwd <dir> --format json --json-strict --deny-all --non-interactive-permissions deny [--model <model>] <target> exec --file -`, with the prompt and schema on stdin; every tool is denied. pi has no permission gate for edit steps, so doctor adds a `tool_gate` warning row whenever pi is the agent: every pi tool runs without approval. codex's sandbox covers its shell too, so doctor adds a `tool_gate` warning row whenever codex is the agent: a drive's recipe tool can write only where the drive may (see [Drive by agent](#drive-by-agent), Scope).
|
|
102
102
|
|
|
103
|
+
### Agent and judge support today
|
|
104
|
+
|
|
105
|
+
Claude Code and Codex are proven live. **OpenCode is not yet proven live:** its free tier rejects done-done's tools-off calls with HTTP 403 (`opencode/deepseek-v4.1-flash-free`), so `init`, `doctor --probe` and a judged run are not proven there, and `opencode/muse-spark-1.3-contributor-free` may be absent from the installed catalog. To try OpenCode, choose a model your plan already covers from `opencode models` with `--agent opencode --model <provider/model>`; done-done never needs a new account or API spend.
|
|
106
|
+
|
|
107
|
+
For a signed-in Claude Code setup, pass `--agent claude --model claude-haiku-5-5 --judge claude --judge-model claude-haiku-5-5` to `init`. For Codex, use `--agent codex --model gpt-6.1-sol` with that same judge. Codex readers and probes require a CLI with `exec --ignore-user-config` and `debug models --bundled`: they keep your login, but disable MCP, project instructions and model-provided tools; edit and drive steps keep your normal Codex config. Codex is not a judge route; a Pi judge on `openai-codex/gpt-6.1-sol` judges through your existing Codex login.
|
|
108
|
+
|
|
109
|
+
`done-done --version` prints the bare version first; help headers show it too, and suffixed versions are labelled `pre-release`.
|
|
110
|
+
|
|
111
|
+
Optional setup check: `done-done doctor --probe` requires a real answer from your chosen agent; it checks setup, not whether your app works.
|
|
112
|
+
|
|
103
113
|
### Add a journey from a description
|
|
104
114
|
|
|
105
115
|
```sh
|
|
@@ -388,7 +398,7 @@ done-done affected origin/main
|
|
|
388
398
|
|
|
389
399
|
`affected [<base>]` says which journeys a change needs and whether HEAD's proof covers them. It is model-free and reads git, `.done-done.yaml` and the verify skill only.
|
|
390
400
|
|
|
391
|
-
- **The change.** The files that differ from `<base>`, else from the newest receipt whose head is before HEAD (the commits since the last proof), else from the merge base with the default branch (`origin/HEAD`, `origin/main`, `origin/master`, then the local `main` or `master`, the order the [Firstmate merge gate](../README.md#
|
|
401
|
+
- **The change.** The files that differ from `<base>`, else from the newest receipt whose head is before HEAD (the commits since the last proof), else from the merge base with the default branch (`origin/HEAD`, `origin/main`, `origin/master`, then the local `main` or `master`, the order the [Firstmate merge gate](../README.md#inside-firstmate-or-another-agent-fleet) uses), plus uncommitted changes to tracked files. Untracked files are not part of the change until added. A file that matches `evidence.ignore_paths`, or a committed receipt under `.done-done-receipts/` ([CI gate](#ci-gate)), needs nothing.
|
|
392
402
|
- **The mapping.** A journey is needed when its command runs the changed file (`node journeys/e2e.mjs` runs `journeys/e2e.mjs`). A feature of the verify skill (`features/<name>.md`) is needed when its file cites the changed file: a repo path, a markdown link (read from the feature's folder), a folder written with a slash (`src/` covers every file under it) or a bare file name, which matches each tracked file of that name as `maintain` reads one; or when the feature file itself changed. The skill's `SKILL.md` and `features/README.md` are what every feature follows, so a change to them needs every feature. A needed feature brings each journey it names (`run <journey>` or `verify <journey>` in its text, or a file the journey's command runs that it cites too); a feature that names no journey is driven by your agent: `done-done verify --feature <name>`. A code-only journey ([Real-product evidence](#real-product-evidence)) is never needed.
|
|
393
403
|
- **Uncertain means more, never less.** A changed file that no feature or journey covers, or no base to diff against, makes the mapping uncertain: the core journey ([Core journey and release path](#core-journey-and-release-path)) is needed too, or the feature the feature map marks `(core journey)`, or every journey when none is named. Each such file is listed under `unmapped` and flagged in `help`: add it to the feature file that drives it (`done-done maintain` reports recent files no feature covers), or record a journey for it.
|
|
394
404
|
- **The proof.** `fresh` (exit 0) when the receipt for HEAD verifies ([Record a receipt](#record-a-receipt)), its `runs` include a run of every needed journey (by name, or by the journey's command) and every needed feature (a `verify --feature` drive, which the receipt records as the run's `feature`), and no tracked file has an uncommitted change. Otherwise exit 1: `stale` when the newest receipt is for an earlier commit (it names that commit and the journeys the new commits need), when the receipt for HEAD misses a needed journey or feature, or when there are uncommitted changes; `missing` when there is no receipt at all. `help` gives the commands that capture the missing proof (`done-done run <journey>`, `done-done verify --feature <name>`), then the receipt step.
|
|
@@ -829,3 +839,23 @@ An `agent_config` entry merges with the defaults field by field, so `claude: { m
|
|
|
829
839
|
|
|
830
840
|
Global-only keys describe the machine. Project-only keys describe the project. Setting a global-only or project-only key in the wrong file is an error (exit 2), not something silently ignored.
|
|
831
841
|
|
|
842
|
+
|
|
843
|
+
## Working on done-done
|
|
844
|
+
|
|
845
|
+
```sh
|
|
846
|
+
npm install -g --prefix ~/.local . # optional: links this checkout as done-done on your PATH
|
|
847
|
+
npm run build:skill # regenerate skills/done-done/SKILL.md from src/skill.ts
|
|
848
|
+
npm run build:skill -- --check # fail if the committed skill is out of date
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
To try an unreleased commit without cloning (npm 12 needs `--allow-git=all`):
|
|
852
|
+
|
|
853
|
+
```sh
|
|
854
|
+
npx -y --allow-git=all github:umeranjum17/done-done-axi --help
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
`dist/` is committed, so installing from GitHub needs no build step. `npm test` rebuilds it and fails while the rebuilt `dist/` differs from the commit or has files git does not track, so `git add` the new `dist/` files with your change.
|
|
858
|
+
|
|
859
|
+
The first-screen terminal images (`docs/media/hero-*.png`, and the animated `hero.gif`) are real output from the published CLI, captured in a sample repo. `node docs/media/hero.mjs` rebuilds their pages from the captured transcripts beside it (`hero-run.txt`, `hero-refuse.txt`) and fails when a shown value is not in them; screenshot `.hero/hero-desktop.html` (828x596) and `.hero/hero-phone.html` (418x792) at device scale factor 2, in light and dark. The GIF replays the same lines a step at a time on that page, ending on the judge's pass and the receipt. The four lower terminal illustrations (`hero`, `run`, `pass`, `reasons`, `config`) use a stub judge, so no model runs; redraw them with `npx tsc && node docs/media/make.mjs`. The logo (`docs/logo.svg`) and the flow picture are hand-made SVGs.
|
|
860
|
+
|
|
861
|
+
The demo notes app behind those pictures: start one with `node docs/media/demo.mjs <fresh-scratch-directory> 0` (the server prints its owned port), open a native run in its `app/` repo, drive the checklist in the browser, save `app.png` at 400×140 DPR 2 into the run's evidence folder, seal it and run `check` with your configured judge. Save the open result as `<scratch>/open.json` and the check result as `<scratch>/check.json`; `/proof` displays that screenshot and verdict and refuses to show a pass without a real passing result. Capture `/proof` at 400×230 DPR 2 with `chrome-devtools-axi`, keep the scratch outside the repo and stop the server afterwards.
|
package/docs/releasing.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
# 0.6.
|
|
1
|
+
# 0.6.13 patch release
|
|
2
2
|
|
|
3
|
-
This release
|
|
3
|
+
This release carries the rewritten README to the npm page: a real judged run on the first screen, the hero images rendered from captured CLI transcripts, and reference detail moved into the docs.
|
|
4
4
|
|
|
5
|
-
Do not publish an unmerged candidate. The existing `release` workflow on main tests and publishes an unpublished package version using npm trusted publishing. After merge, confirm `npm view done-done-axi@0.6.
|
|
5
|
+
Do not publish an unmerged candidate. The existing `release` workflow on main tests and publishes an unpublished package version using npm trusted publishing. After merge, confirm `npm view done-done-axi@0.6.13 version dist.integrity` and smoke-test a clean `npx` install with `done-done --version`. Do not run `npm publish` manually unless the workflow fails and the release is blocked; if so, stop and report.
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "done-done-axi",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.13",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "Prove your app really works: done-done drives your app the way a user does, a fresh judge checks every capture, and the proof is tied to a commit.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"repository": { "type": "git", "url": "git+https://github.com/umeranjum17/done-done-axi.git" },
|
|
8
|
-
"homepage": "https://github.
|
|
8
|
+
"homepage": "https://umeranjum17.github.io/done-done-axi/",
|
|
9
9
|
"bugs": { "url": "https://github.com/umeranjum17/done-done-axi/issues" },
|
|
10
|
-
"keywords": ["axi", "done", "proof", "evidence", "screenshot", "verification", "cli", "agent"],
|
|
10
|
+
"keywords": ["axi", "done", "proof", "evidence", "screenshot", "verification", "cli", "agent", "ai-agents", "coding-agents"],
|
|
11
11
|
"bin": { "done-done-axi": "dist/cli.js", "done-done": "dist/cli.js" },
|
|
12
12
|
"files": ["dist", "!dist/skill.js", "skills", "docs", "integrations"],
|
|
13
13
|
"engines": { "node": ">=22.18" },
|