done-done-axi 0.3.2 → 0.4.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.
- package/README.md +15 -15
- package/dist/agents.js +19 -12
- package/dist/cli.js +449 -431
- package/dist/config.js +30 -27
- package/dist/design.js +27 -44
- package/dist/judge.js +110 -57
- package/dist/maintain.js +16 -14
- package/docs/media/hero-dark.svg +186 -154
- package/docs/media/hero-light.svg +186 -154
- package/docs/media/make.mjs +7 -2
- package/docs/media/pass-dark.svg +22 -8
- package/docs/media/pass-light.svg +22 -8
- package/docs/media/reasons-dark.svg +15 -23
- package/docs/media/reasons-light.svg +15 -23
- package/docs/media/run-dark.svg +6 -6
- package/docs/media/run-light.svg +6 -6
- package/docs/reference.md +52 -64
- package/integrations/firstmate/brief-include.md +5 -3
- package/integrations/firstmate/merge-gate +2 -2
- package/package.json +4 -6
- package/skills/done-done/SKILL.md +7 -6
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
done-done won't accept "done" without real, fresh proof from your product, captured at the exact commit being called done.
|
|
11
11
|
|
|
12
|
-
[](https://nodejs.org) [](#whats-next) [](https://www.npmjs.com/package/done-done-axi)
|
|
13
13
|
|
|
14
14
|
<br>
|
|
15
15
|
|
|
@@ -35,10 +35,10 @@ done-done runs your capture and ties every screenshot, recording and log it save
|
|
|
35
35
|
|
|
36
36
|
## See it work
|
|
37
37
|
|
|
38
|
-
Four moments from a demo notes app. Every picture is real output from the current build.
|
|
38
|
+
Four moments from a demo notes app. Every picture is real output from the current build; the demo's judge is a stub that says the screen shows the outcome, so no model runs.
|
|
39
39
|
|
|
40
|
-
<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
|
|
41
|
-
<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, and done-done check passes." width="400" align="top"></picture>
|
|
40
|
+
<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>
|
|
41
|
+
<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>
|
|
42
42
|
|
|
43
43
|
<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>
|
|
44
44
|
<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>
|
|
@@ -51,7 +51,7 @@ done-done is an [AXI](https://axi.md), which means -
|
|
|
51
51
|
|
|
52
52
|
## Use It From Your Agent
|
|
53
53
|
|
|
54
|
-
You need Node 22.
|
|
54
|
+
You need Node 22.18 or later and git. Give your agent the done-done skill in the [Agent Skills](https://agentskills.io) format with [`npx skills`](https://github.com/vercel-labs/skills), naming your agent with `-a`:
|
|
55
55
|
|
|
56
56
|
```sh
|
|
57
57
|
npx skills add umeranjum17/done-done-axi --skill done-done -a <agent> -y
|
|
@@ -101,7 +101,7 @@ cd your-app
|
|
|
101
101
|
done-done init
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
`init` writes a minimal `.done-done.yaml` (only if you don't already have one) that names your app, and a commented global `~/.done-done/config.yaml` (only if there is none). done-done never picks the coding agent it starts: `init` asks you in a terminal, or takes `--agent <agent> --model <model>`. It never picks the judge either, the agent of its own that `verify`
|
|
104
|
+
`init` writes a minimal `.done-done.yaml` (only if you don't already have one) that names your app, and a commented global `~/.done-done/config.yaml` (only if there is none). done-done never picks the coding agent it starts: `init` asks you in a terminal, or takes `--agent <agent> --model <model>`. It never picks the judge either, the agent of its own that `check`, `receipt`, `verify` and `design` always start to look at each capture: `init` asks in a terminal, or takes `--judge <agent> --judge-model <model>`. Any agent and model you choose runs, your coding agent's own too (the judge is a fresh session of its own). The config keys are in the [reference](docs/reference.md#config). A plain `init` never overwrites an existing config. It writes no verify skill: write `.agents/skills/verify-<app>/SKILL.md` by hand, with a launch that never touches real accounts or your own state. Evidence lives outside the repo, in `~/.done-done/evidence/<app>`, so it outlives the checkout that captured it. For an `answerer:pi` judge with no explicit model, done-done uses `openai-codex/gpt-6-luna`; `judge.model` or `agent_config.pi.model` overrides it. Then describe how to capture proof — swap the command for whatever drives your real app and saves screenshots, recordings or logs:
|
|
105
105
|
|
|
106
106
|
```yaml
|
|
107
107
|
journeys:
|
|
@@ -123,9 +123,9 @@ git commit -m "Add done-done"
|
|
|
123
123
|
|
|
124
124
|
A `run -- <command>` whose command matches no recorded journey still runs, but its result hints that the recipe is not in the repo. For a proof you drive by hand or by your agent instead of a journey, `done-done run --open` prints a run id and a folder to capture into, and `done-done run --close <run-id>` seals it ([how](docs/reference.md#run-a-journey)).
|
|
125
125
|
|
|
126
|
-
At any point, `done-done doctor` checks the setup and changes nothing except the `--probe` call record. Each item reports `ok`, `warning` or `missing` with the exact fix command; an agent you have not set yet is `missing`, with the command that saves your choice. `done-done doctor --probe` also asks the agent one question to prove it answers; on a new machine that probe fails until the agent is signed in (for pi, run `pi` and then `/login`). The quick start above never calls the agent, so `run` and `check` work before it
|
|
126
|
+
At any point, `done-done doctor` checks the setup and changes nothing except the `--probe` call record. Each item reports `ok`, `warning` or `missing` with the exact fix command; an agent you have not set yet is `missing`, with the command that saves your choice. `done-done doctor --probe` also asks the agent one question to prove it answers; on a new machine that probe fails until the agent is signed in (for pi, run `pi` and then `/login`). The quick start above never calls the coding agent, so `run` and `check` work before it is signed in; `check` does call the judge, so set one first. The items are listed in the [reference](docs/reference.md#check-the-setup).
|
|
127
127
|
|
|
128
|
-
`done-done maintain` keeps the verify skill true: it checks the skill's links and feature index, checks that every `file:line` it cites exists, and has your coding agent read the source for each feature, read-only, to report drift. It ends `clean`, `drift` with the findings to fix, or `blocked`. With `auto_fix: { maintain: <n> }` (as in no-mistakes; 0, the default, reports only), your judge first sorts each drift finding (a skill out of date, or a product that may be wrong, which stops and asks you), then your agent fixes the skill folder only, in a done-done worktree, and maintain runs again, up to n times. A clean end is `changed`: one commit on a `done-done/maintain-<run-id>` branch, your branch untouched ([reference](docs/reference.md#keep-the-verify-skill-true)).
|
|
128
|
+
`done-done maintain` keeps the verify skill true: it checks the skill's links and feature index, checks that every `file:line` it cites exists, and has your coding agent read the source for each feature, read-only, to report drift. It ends `clean`, `drift` with the findings to fix, or `blocked`. It never runs without that reader: an agent that is not set asks, and one that cannot start or cannot read without tools stops it before the run (exit 2). With `auto_fix: { maintain: <n> }` (as in no-mistakes; 0, the default, reports only), your judge first sorts each drift finding (a skill out of date, or a product that may be wrong, which stops and asks you), then your agent fixes the skill folder only, in a done-done worktree, and maintain runs again, up to n times. A clean end is `changed`: one commit on a `done-done/maintain-<run-id>` branch, your branch untouched ([reference](docs/reference.md#keep-the-verify-skill-true)).
|
|
129
129
|
|
|
130
130
|
**3. Run it, then check it**
|
|
131
131
|
|
|
@@ -134,7 +134,7 @@ done-done run smoke
|
|
|
134
134
|
done-done check --outcome "it starts" ~/.done-done/evidence/your-app/*/*.log
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
Each command prints one machine-readable result. By default it is [TOON](https://github.com/toon-format/spec) (the compact AXI convention), and
|
|
137
|
+
Each command prints one machine-readable result. By default it is [TOON](https://github.com/toon-format/spec) (the compact AXI convention). `run` shows `result: recorded`: it captured evidence, and says nothing about whether it proves the claim. `check` starts your judge on each capture, and only a check the judge passes shows `result: pass`; with no judge set it asks for one, and a judge that fails stops with the cause (exit 2), never a result. Add `--json` for JSON, or `--full` to list every evidence file or finding instead of the first few. After later runs, use the `run_id` the result prints in place of the first `*`.
|
|
138
138
|
|
|
139
139
|
When a check passes, save a receipt and re-verify it later:
|
|
140
140
|
|
|
@@ -143,7 +143,7 @@ done-done receipt --outcome "it starts" ~/.done-done/evidence/your-app/*/*.log
|
|
|
143
143
|
done-done receipt --verify "$(git rev-parse HEAD)"
|
|
144
144
|
```
|
|
145
145
|
|
|
146
|
-
No journey yet? `done-done verify --outcome "<what a user can now do>"` has your coding agent drive one feature of the verify skill the way a user does (`--feature <name>` picks it).
|
|
146
|
+
No journey yet? `done-done verify --outcome "<what a user can now do>"` has your coding agent drive one feature of the verify skill the way a user does (`--feature <name>` picks it). Your judge then checks the captures. When it says a capture is wrong or unclear, or a capture it cannot read (a video or other file) is not judged, the run waits at its gate (exit 4) until you answer with `done-done respond --action fix`, which ends it `fail` so you fix the product or the recipe and run again: nothing moves a run past its judge, and no receipt is written without a judge pass. Until then, a new `verify` or `rerun` of the same claim in that checkout is refused, so nothing goes around the gate ([details](docs/reference.md#drive-by-agent)).
|
|
147
147
|
|
|
148
148
|
With `auto_fix: { verify: <n> }` (0, the default, reports only), a failed verify is fixed with your own agent: your judge first sorts each wrong screen (a product bug to fix, or a question that waits at the gate for you), then your agent fixes the product in a done-done worktree with your ignored files copied in, and verify runs again there, up to n times. A pass ends `changed`, with the fix on a `done-done/verify-<run-id>` branch and your branch untouched ([details](docs/reference.md#fix-the-product)).
|
|
149
149
|
|
|
@@ -159,13 +159,13 @@ Run `done-done` with no arguments to see the current config and the next step.
|
|
|
159
159
|
- ♻️ **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`.
|
|
160
160
|
- 🧾 **Honest claims**: Reads a pull request's `## Checks` block — from a file, a URL, or stdin — and makes sure every line is filled in.
|
|
161
161
|
- 📌 **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), or in CI once the evidence folder is copied there ([how](docs/reference.md#where-proof-lives)).
|
|
162
|
-
- 👀 **Shows the outcome** (
|
|
162
|
+
- 👀 **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); 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.
|
|
163
163
|
- 🎨 **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)).
|
|
164
164
|
- 📐 **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)).
|
|
165
165
|
- 🧩 **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)).
|
|
166
166
|
- 🔒 **Safe in CI**: `--trusted-ref origin/main` reads the rules from your main branch, so a pull request can't loosen them.
|
|
167
167
|
|
|
168
|
-
Every answer is an exit code: **0** pass, **1** fail (or
|
|
168
|
+
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.
|
|
169
169
|
|
|
170
170
|
## Use with Firstmate or another agent fleet
|
|
171
171
|
|
|
@@ -181,7 +181,7 @@ cp "$(npm root -g)/done-done-axi/integrations/firstmate/merge-gate" "$FM_HOME/co
|
|
|
181
181
|
```
|
|
182
182
|
|
|
183
183
|
- **`brief-include.md`**: Firstmate adds `config/brief-include.md` to every worker brief. It tells the worker to set up done-done, run a journey on its committed change, write a `## Checks` block, pass `check`, and record a `receipt`. The evidence and receipt stay in `~/.done-done/evidence/<app>` after teardown deletes the worktree.
|
|
184
|
-
- **`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`
|
|
184
|
+
- **`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.
|
|
185
185
|
|
|
186
186
|
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.
|
|
187
187
|
|
|
@@ -193,7 +193,7 @@ Another fleet works the same way: add the include text to whatever your workers
|
|
|
193
193
|
|
|
194
194
|
## What's next
|
|
195
195
|
|
|
196
|
-
So far: `init`, `doctor`, `run` (including `--open` and `--close`), `check`, `receipt`, `verify` (by journey or by your coding agent, with a gate you answer with `respond`), `maintain`, the capture judge (on
|
|
196
|
+
So far: `init`, `doctor`, `run` (including `--open` and `--close`), `check`, `receipt`, `verify` (by journey or by your coding agent, with a gate you answer with `respond`), `maintain`, the capture judge (always on), the `design` visual check, the `look` step, the run tools (`status`, `attach`, `logs`, `rerun`, `abort`, `signoff`, `history`) and the opt-in session hooks for Claude Code, Codex, opencode, Gemini CLI and pi. Coming next: help writing the proof steps for your app.
|
|
197
197
|
|
|
198
198
|
## Develop
|
|
199
199
|
|
|
@@ -215,4 +215,4 @@ npx -y --allow-git=all github:umeranjum17/done-done-axi --help
|
|
|
215
215
|
|
|
216
216
|
`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.
|
|
217
217
|
|
|
218
|
-
The terminal pictures (hero, run, pass, reasons, config) are real output from the current build; redraw them with `npx tsc && node docs/media/make.mjs`. The wordmark and the flow picture are hand-made SVGs.
|
|
218
|
+
The terminal pictures (hero, run, pass, reasons, config) are real output from the current build, with a stub judge (no model); redraw them with `npx tsc && node docs/media/make.mjs`. The wordmark and the flow picture are hand-made SVGs.
|
package/dist/agents.js
CHANGED
|
@@ -3,7 +3,7 @@ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
|
3
3
|
import { homedir, tmpdir } from 'node:os';
|
|
4
4
|
import { dirname, extname, isAbsolute, join } from 'node:path';
|
|
5
5
|
import { stripVTControlCharacters } from 'node:util';
|
|
6
|
-
import { AGENTS, ANSWERER_JUDGES, CHEAP, EFFORT_FLAGS, KEY_ROUTES, parseDuration, UsageError } from './config.js';
|
|
6
|
+
import { AGENTS, ANSWERER_JUDGES, CHEAP, JUDGE_DEFAULT, EFFORT_FLAGS, KEY_ROUTES, parseDuration, UsageError } from './config.js';
|
|
7
7
|
import { isExecutable, onPath } from './judge.js';
|
|
8
8
|
// argv never carries the prompt: it goes on stdin, or (file: true) into a 0600 prompt file the argv points at.
|
|
9
9
|
// done-done parses the answer, validates it against the schema, and asks a tool-less call again, at most ASK_ATTEMPTS calls.
|
|
@@ -118,6 +118,13 @@ const ACP = {
|
|
|
118
118
|
};
|
|
119
119
|
export const ACPX_INSTALL = 'Install the acpx ACP bridge (npm install -g acpx, https://github.com/openclaw/acpx), then re-run: done-done doctor';
|
|
120
120
|
const PI_TOOL_LESS = ['--no-tools', '--no-extensions', '--no-skills', '--no-prompt-templates', '--no-context-files'];
|
|
121
|
+
// --no-extensions also hides the extension that supplies a model's provider: claude-bridge models were 0 with it, 13 with
|
|
122
|
+
// -e npm:pi-claude-bridge. A tool-less call loads that one extension and no other: the rest add tools or prompt text.
|
|
123
|
+
const PI_PROVIDER_EXTENSIONS = { 'claude-bridge': 'npm:pi-claude-bridge' };
|
|
124
|
+
const piProviderExtension = (model) => {
|
|
125
|
+
const provider = model?.split('/')[0] ?? '';
|
|
126
|
+
return Object.hasOwn(PI_PROVIDER_EXTENSIONS, provider) ? ['-e', PI_PROVIDER_EXTENSIONS[provider]] : [];
|
|
127
|
+
};
|
|
121
128
|
const ADAPTERS = {
|
|
122
129
|
// claude -p: --json-schema puts the validated object in structured_output; --tools '' turns every tool off.
|
|
123
130
|
// An edit step accepts edits only in cwd and --add-dir folders, and may run commands (the drive launches the app).
|
|
@@ -187,13 +194,14 @@ const ADAPTERS = {
|
|
|
187
194
|
// message); --mode json streams JSONL events whose assistant message_end holds the answer text,
|
|
188
195
|
// --no-session keeps the probe ephemeral. An @<file> argument attaches an image to that message.
|
|
189
196
|
// --no-tools turns every built-in and extension tool off (probed: a canary file outside the cwd went unread).
|
|
190
|
-
// A tool-less call also loads no
|
|
191
|
-
//
|
|
197
|
+
// A tool-less call also loads no skills, prompt templates or context files, and only the chosen model's provider
|
|
198
|
+
// extension (piProviderExtension): the others would add the user's own context to a fresh judge, and loading all of
|
|
199
|
+
// them took 2 minutes on a real setup (probed), past the judge's timeout.
|
|
192
200
|
// Pi has no permission gate for edit steps, so doctor warns about it. Without a model, pi runs its own default.
|
|
193
201
|
pi: {
|
|
194
202
|
streams: true,
|
|
195
203
|
readsImages: true,
|
|
196
|
-
argv: (c, dir) => ['-p', '--mode', 'json', '--no-session', ...(c.tools === 'edit' ? [] : PI_TOOL_LESS), ...(c.model ? ['--model', c.model] : []), ...(c.images ?? []).map((i) => `@${join(dir, i.name)}`)],
|
|
204
|
+
argv: (c, dir) => ['-p', '--mode', 'json', '--no-session', ...(c.tools === 'edit' ? [] : [...PI_TOOL_LESS, ...piProviderExtension(c.model)]), ...(c.model ? ['--model', c.model] : []), ...(c.images ?? []).map((i) => `@${join(dir, i.name)}`)],
|
|
197
205
|
answer: (out, c) => {
|
|
198
206
|
let text = '';
|
|
199
207
|
let failure = '';
|
|
@@ -303,6 +311,9 @@ export function knownAgentOf(agent) {
|
|
|
303
311
|
const adapterFor = (agent) => (agent.startsWith('acp:') ? ACP : Object.hasOwn(ADAPTERS, agent) ? ADAPTERS[agent] : undefined);
|
|
304
312
|
// Why an agent cannot run a tool-less call, '' when it can.
|
|
305
313
|
export const editOnlyReason = (agent) => adapterFor(agent)?.editOnly ?? '';
|
|
314
|
+
// Why an agent cannot read a repo tool-less from text plain code gathers, '' when it can: gemini's none mode is a
|
|
315
|
+
// read-only plan mode, not tool-free.
|
|
316
|
+
export const toollessReason = (agent) => (agent === 'gemini' ? 'gemini cannot read tool-less yet, since its none mode is read-only plan mode, not tool-free' : editOnlyReason(agent));
|
|
306
317
|
// A binary from config: a bare name is looked up on PATH, an absolute path is used when it is an executable file.
|
|
307
318
|
export const findBin = (bin) => (isAbsolute(bin) ? (isExecutable(bin) ? bin : '') : onPath(bin));
|
|
308
319
|
// The binary that starts an agent: agent_path_override.<agent>, else its name on PATH. An acp:<target> agent starts
|
|
@@ -323,9 +334,9 @@ export const routeOf = (agent) => (agent === 'claude' ? 'claude-code' : `answere
|
|
|
323
334
|
export const JUDGES = AGENTS.filter((a) => a === 'claude' || ANSWERER_JUDGES.includes(a));
|
|
324
335
|
// Like the agent, the judge is exactly the one the user set; with none, done-done asks the user (in a terminal) or
|
|
325
336
|
// stops with this error, so a calling agent asks its user rather than picking one.
|
|
326
|
-
export const noJudge = () => askError('judge', JUDGES.join(', '), 'never pick one for them
|
|
327
|
-
//
|
|
328
|
-
export function selectJudge(cfg, found
|
|
337
|
+
export const noJudge = () => askError('judge', JUDGES.join(', '), 'never pick one for them', `done-done init --judge <agent> --judge-model <model>, e.g. done-done init --judge opencode --judge-model ${CHEAP.opencode.model}`);
|
|
338
|
+
// The user's judge may be any agent and model they choose, the author's own too: it judges in a fresh session.
|
|
339
|
+
export function selectJudge(cfg, found) {
|
|
329
340
|
const route = cfg.judge.route;
|
|
330
341
|
if (!route)
|
|
331
342
|
throw noJudge();
|
|
@@ -334,17 +345,13 @@ export function selectJudge(cfg, found, fix = false) {
|
|
|
334
345
|
if (keyed && !cfg.judge.model)
|
|
335
346
|
throw new UsageError(`judge: judge.route ${route} needs judge.model, a model your key can use that reads images`, 'Set judge.model in ~/.done-done/config.yaml');
|
|
336
347
|
const agent = keyed ? route : route === 'claude-code' ? 'claude' : route.slice('answerer:'.length);
|
|
337
|
-
const model = cfg.judge.model || modelFor(cfg, agent);
|
|
348
|
+
const model = cfg.judge.model || (agent === 'pi' ? cfg.agent_config.pi?.model || JUDGE_DEFAULT : modelFor(cfg, agent));
|
|
338
349
|
if (!model)
|
|
339
350
|
throw new UsageError(`judge: no model for ${route}`, `Set judge.model in ~/.done-done/config.yaml`);
|
|
340
351
|
// acp:claude-code is claude for independence; an author with no known model is never apart by model.
|
|
341
352
|
const independence = keyed
|
|
342
353
|
? found.model && model === found.model ? 'session-only' : 'agent'
|
|
343
354
|
: agent !== knownAgentOf(found.agent) ? 'agent' : found.model && model !== found.model ? 'model' : 'session-only';
|
|
344
|
-
if (fix && independence !== 'agent')
|
|
345
|
-
throw new UsageError(`judge: the judge ${agent} (model ${model}) is the fixer's own agent (${found.agent}) at any model, and the judge is never the agent that did the work; judge.allow_same does not apply to auto_fix`, 'Ask the user for another judge agent and save it: done-done init --judge <agent> --judge-model <model>');
|
|
346
|
-
if (independence === 'session-only' && !cfg.judge.allow_same)
|
|
347
|
-
throw new UsageError(`judge: the judge ${agent} (model ${model}) is the author's own agent and model (${found.agent}), and the judge must differ from the author by agent or by model`, `done-done init --judge <agent> --judge-model <model>, with another agent or the same agent at another model; judge.allow_same: true in ~/.done-done/config.yaml is an opt-out only, for a fresh session of the same agent and model`);
|
|
348
355
|
return { route, agent, model, independence, author: { agent: found.agent, model: found.model } };
|
|
349
356
|
}
|
|
350
357
|
const DRAIN_MS = 500;
|