done-done-axi 0.6.5 → 0.6.7

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 CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  A command-line check of real screenshots, recordings and output.
13
13
 
14
- For developers using coding agents. Tests can pass while the app is still broken.
14
+ For developers using coding agents, alone or in a [Firstmate](#use-with-firstmate-or-another-agent-fleet) fleet. Tests can pass while the app is still broken.
15
15
 
16
16
  <img src="docs/media/demo.png" width="320" alt="Real sample app: Release checklist shows Capture the real app checked and Done. The actual claude-haiku-5-5 judge passes that captured screenshot at sample commit 08d635e46a98.">
17
17
 
@@ -20,9 +20,13 @@ For developers using coding agents. Tests can pass while the app is still broken
20
20
  ```sh
21
21
  npm install -g done-done-axi
22
22
  cd your-app && done-done init
23
- done-done doctor
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.
27
+
28
+ **With or without Firstmate.** On its own, you or your agent run these three lines. In a [Firstmate](https://github.com/kunchenguid/firstmate) fleet, two files make every worker prove its task, plus an optional merge gate that checks that proof ([how](#use-with-firstmate-or-another-agent-fleet)).
29
+
26
30
  [Website](https://umeranjum17.github.io/done-done-axi/) · [Setup](#install-in-3-steps) · [Agent skill](#use-it-from-your-agent) · [Reference](docs/reference.md) · [npm](https://www.npmjs.com/package/done-done-axi)
27
31
 
28
32
  ## Install in 3 steps
@@ -30,16 +34,16 @@ done-done doctor
30
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).
31
35
 
32
36
  1. **Install.** The first line above puts `done-done` (and the long name `done-done-axi`) on your PATH. No `sudo`? Add `--prefix ~/.local` and put `~/.local/bin` on your `PATH`.
33
- 2. **Set up your repo.** `init` writes a minimal `.done-done.yaml` and asks you, in a terminal, which coding agent and which judge to use. done-done never picks either for you. Outside a terminal, pass `--agent <agent> --model <model> --judge <agent> --judge-model <model>` instead.
34
- 3. **Check the setup.** `doctor` changes nothing and names each missing piece with the exact command that fixes it. It checks setup, not whether your app works.
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.
35
39
 
36
- Review and commit the capture recipe and verify skill, then ask for proof:
40
+ Optional setup check: `done-done doctor --probe` requires a real answer from your chosen agent; it checks setup, not whether your app works.
37
41
 
38
- ```sh
39
- done-done verify --outcome "<what a user can now do>"
40
- ```
42
+ 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/drive steps keep your normal Codex config. Codex is not a judge route.
43
+
44
+ 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.
41
45
 
42
- Your agent drives the real product and saves screenshots or output. A fresh judge checks whether each capture shows your claim. No judge pass, no receipt. You choose the agents and models; captures go to your chosen judge's provider, on your own plan or key. [Manual CLI](#manual-cli) walks through recording a journey, checking it and saving a receipt.
46
+ No result? `done-done doctor` changes nothing and names each missing piece, such as a verify skill `init` could not write, with the exact command that fixes it. Commit `.done-done.yaml` and the verify skill so later runs and your teammates use the same recipe. You choose the agents and models; captures go to your chosen judge's provider, on your own plan or key. [Manual CLI](#manual-cli) walks through recording a journey, checking it and saving a receipt.
43
47
 
44
48
  ## Why
45
49
 
@@ -153,7 +157,7 @@ Another fleet works the same way: add the include text to whatever your workers
153
157
 
154
158
  ## Learn more
155
159
 
156
- - [Vision](VISION.md): the three-tool family, the rules they share, and where done-done goes next.
160
+ - [Vision](VISION.md): who done-done is for, the problem, where it is going, what it is not, and the next milestones.
157
161
  - [Worked example: a CLI project](docs/example-cli.md): set up, one journey, check and receipt on a command-line tool.
158
162
  - [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.
159
163
  - [Full reference](docs/reference.md): every command and option, the Checks block rules, each file check, and both config files.
@@ -161,7 +165,7 @@ Another fleet works the same way: add the include text to whatever your workers
161
165
 
162
166
  ## What's next
163
167
 
164
- So far: `init`, `doctor`, `run` (including `--open` and `--close`), `check`, `receipt`, `affected` (the journeys a diff needs), `lint` (a no-model gate on a Checks block), `gate` (a no-model CI check of a committed 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.
168
+ So far: `init`, `doctor`, `run` (including `--open` and `--close`), `check`, `receipt`, `affected` (the journeys a diff needs), `lint` (a no-model gate on a Checks block), `gate` (a no-model CI check of a committed 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: the [milestones in the vision](VISION.md#next-milestones).
165
169
 
166
170
  ## Develop
167
171
 
package/dist/agents.js CHANGED
@@ -255,16 +255,34 @@ const ADAPTERS = {
255
255
  // answer, and --ephemeral keeps no session. An edit step runs in codex's workspace-write sandbox, which writes only the
256
256
  // repo, the run's folders (--add-dir) and $TMPDIR; it may use the network, since the drive launches the app and talks
257
257
  // to it, and it keeps the user's config.toml. Without a model, codex runs its own default.
258
- // A tool-less call is refused: codex with the user's config.toml kept its MCP server, which read a
259
- // canary file outside the folder, and --disable does not turn off its multi-agent tools.
258
+ // Readers keep normal authentication but not user config (MCP), instructions or tools. Feature flags alone
259
+ // are insufficient: the bundled model catalog can force code-mode, collaboration and apply_patch back on.
260
+ // Copy only that public catalog into this call's scratch folder and remove its tool capabilities too.
260
261
  codex: {
261
262
  streams: true,
262
- editOnly: 'codex cannot run tool-less: with your config.toml it keeps its MCP tools, which read files outside the folder',
263
+ files: (c) => {
264
+ if (c.tools === 'edit')
265
+ return {};
266
+ const r = spawnSync(c.path, ['debug', 'models', '--bundled'], { encoding: 'utf8', timeout: 10_000, maxBuffer: 16 << 20 });
267
+ if (r.status !== 0)
268
+ throw new Error(`codex tool-less setup: ${r.error?.message || r.stderr || `debug models --bundled exited ${r.status}`}; update Codex CLI`);
269
+ const catalog = JSON.parse(r.stdout);
270
+ if (!Array.isArray(catalog.models) || !catalog.models.length || (c.model && !catalog.models.some((m) => m.slug === c.model)))
271
+ throw new Error(`codex tool-less setup: bundled catalog does not list ${c.model || 'any model'}; choose a model from codex debug models --bundled`);
272
+ for (const m of catalog.models)
273
+ Object.assign(m, { shell_type: 'disabled', apply_patch_tool_type: null, tool_mode: 'direct', multi_agent_version: null, experimental_supported_tools: [], supports_search_tool: false });
274
+ return { 'models.json': JSON.stringify(catalog) };
275
+ },
263
276
  // Each sandboxed command runs in its own process namespace, so a server or browser bridge started in the
264
277
  // background by one command was gone by the next one, and a drive that launched the app and then browsed it captured nothing.
265
278
  editNote: 'Your shell sandbox ends every process a command started, background ones too, when that command ends. So start what a task needs (an app, a server, a browser bridge), use it, save what it produces and stop it within one shell command (a script in $TMPDIR is fine).',
266
- argv: (c) => ['exec', '--json', '--ephemeral', ...(c.model ? ['-m', c.model] : []),
267
- '--sandbox', 'workspace-write', '-c', 'sandbox_workspace_write.network_access=true', ...(c.dirs ?? []).flatMap((d) => ['--add-dir', d])],
279
+ argv: (c, dir) => [...(c.tools === 'edit' ? [] : ['--no-daemon']), 'exec', '--json', '--ephemeral', ...(c.model ? ['-m', c.model] : []),
280
+ ...(c.tools === 'edit' ? ['--sandbox', 'workspace-write', '-c', 'sandbox_workspace_write.network_access=true', ...(c.dirs ?? []).flatMap((d) => ['--add-dir', d])] : [
281
+ '--ignore-user-config', '--ignore-rules', '--skip-git-repo-check', '--sandbox', 'read-only',
282
+ '-c', 'project_doc_max_bytes=0', '-c', `model_catalog_json=${JSON.stringify(join(dir, 'models.json'))}`,
283
+ '-c', 'web_search="disabled"', '-c', 'tools.update_plan.enabled=false', '-c', 'tools.experimental_request_user_input.enabled=false',
284
+ ...['shell_tool', 'multi_agent', 'apps', 'plugins', 'skill_search', 'tool_suggest', 'image_generation', 'view_image', 'sleep_tool', 'goals'].flatMap((f) => ['--disable', f]),
285
+ ])],
268
286
  answer: (out, c) => {
269
287
  let text = '';
270
288
  let failed = '';
@@ -335,11 +353,9 @@ export function knownAgentOf(agent) {
335
353
  return AGENTS.find((a) => target === a || (target.startsWith(a) && !/[A-Za-z0-9]/.test(target[a.length]))) ?? agent;
336
354
  }
337
355
  const adapterFor = (agent) => (agent.startsWith('acp:') ? ACP : Object.hasOwn(ADAPTERS, agent) ? ADAPTERS[agent] : undefined);
338
- // Why an agent cannot run a tool-less call, '' when it can.
339
- export const editOnlyReason = (agent) => adapterFor(agent)?.editOnly ?? '';
340
356
  // Why an agent cannot read a repo tool-less from text plain code gathers, '' when it can: gemini's none mode is a
341
357
  // read-only plan mode, not tool-free.
342
- 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));
358
+ export const toollessReason = (agent) => (agent === 'gemini' ? 'gemini cannot read tool-less yet, since its none mode is read-only plan mode, not tool-free' : '');
343
359
  // A binary from config: a bare name is looked up on PATH, an absolute path is used when it is an executable file.
344
360
  export const findBin = (bin) => (isAbsolute(bin) ? (isExecutable(bin) ? bin : '') : onPath(bin));
345
361
  // The binary that starts an agent: agent_path_override.<agent>, else its name on PATH. An acp:<target> agent starts
@@ -508,16 +524,14 @@ export async function askAgent(c) {
508
524
  cwd = c.tools === 'none' ? dir : c.cwd;
509
525
  if (!adapter)
510
526
  throw new Error(`no adapter for ${c.agent} yet`);
511
- if (adapter.editOnly && c.tools !== 'edit')
512
- throw new Error(adapter.editOnly);
527
+ const bin = c.path;
528
+ if (!bin)
529
+ throw new Error(c.agent.startsWith('acp:') ? `${c.agent} needs acpx, and acpx is not startable; ${ACPX_INSTALL}` : notStartable(c.agent, c.override));
513
530
  if (adapter.readsImages)
514
531
  for (const i of c.images ?? [])
515
532
  writeFileSync(join(dir, i.name), i.bytes, { mode: 0o600 });
516
533
  for (const [name, text] of Object.entries(adapter.files?.(c) ?? {}))
517
534
  writeFileSync(join(dir, name), text, { mode: 0o600 });
518
- const bin = c.path;
519
- if (!bin)
520
- throw new Error(c.agent.startsWith('acp:') ? `${c.agent} needs acpx, and acpx is not startable; ${ACPX_INSTALL}` : notStartable(c.agent, c.override));
521
535
  let lastError = '';
522
536
  for (;;) {
523
537
  attempts++;