From d72f74503dcc1573fe88184b943248d9ed38aa3a Mon Sep 17 00:00:00 2001 From: quality Date: Sun, 11 Oct 2026 22:53:57 -0400 Subject: [PATCH] test: pin README --dangerous row to attach.ts DANGEROUS_FLAGS The README --dangerous row names the flag each CLI gets, but #225 added omp: '--approval-mode yolo' to DANGEROUS_FLAGS without updating it, so the docs advertised three CLIs while attach knew four. Add a support-matrix guard that parses both and requires them to agree on CLI set and exact flag text, and add the missing omp entry to the row. Refs #229 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: quality --- README.md | 2 +- test/cli-support-matrix.test.js | 47 +++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b632218..c4e0698 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ tmux attach -t my-agent | `--rationguard` | Start rationguard watcher alongside pluk (requires `rationguard` on `PATH` — `npm install -g @hivecommons/rationguard` — or `--rationguard-bin`; pluk never fetches it from the registry implicitly) | | `--rationguard-bin=` | Explicit rationguard command to run instead of the one on `PATH`, e.g. `--rationguard-bin='npx --yes @hivecommons/rationguard@0.11.0'` (also `PLUK_RATIONGUARD_BIN`) | | `--rebuttal=send` | Auto-send rebuttals when rationguard detects excuses | -| `--dangerous` | Skip CLI permission prompts (`--dangerously-skip-permissions` for claude, `--full-auto` for codex, `--non-interactive` for goose) | +| `--dangerous` | Skip CLI permission prompts (`--dangerously-skip-permissions` for claude, `--full-auto` for codex, `--non-interactive` for goose, `--approval-mode yolo` for omp) | | `--dir=/path` | Working directory for the agent | | `--cli-args="..."` | Extra arguments to pass to the CLI | | `--no-open` | Don't open a terminal window | diff --git a/test/cli-support-matrix.test.js b/test/cli-support-matrix.test.js index 02b2bcb..3154192 100644 --- a/test/cli-support-matrix.test.js +++ b/test/cli-support-matrix.test.js @@ -83,3 +83,50 @@ test('README --cli row, CLI_COMMANDS, and bundled patterns agree on the supporte assert.deepEqual(bundled, launchable, 'patterns/ should bundle exactly the CLIs attach can launch'); assert.deepEqual(Object.keys(BUILTIN_PATTERNS).sort(), launchable, 'BUILTIN_PATTERNS should cover exactly the CLIs attach can launch'); }); + +// --- --dangerous flag documentation ------------------------------------------------ +// +// The README `--dangerous` row names the exact flag each CLI gets. #225 added +// `omp: '--approval-mode yolo'` to DANGEROUS_FLAGS without touching that row, +// so the docs advertised three CLIs while attach knew four. Pin the row to the +// source the same way the `--cli` row is pinned to CLI_COMMANDS above. + +// Entries of a `const NAME: Record = { key: 'value', ... }` +// literal in attach.ts as a { key: value } object. +function recordEntries(source, name) { + const re = new RegExp(`const ${name}: Record = \\{([\\s\\S]*?)\\};`); + const m = source.match(re); + assert.ok(m, `src/attach.ts should still declare ${name} as a Record literal`); + const entries = {}; + for (const e of m[1].matchAll(/^\s*([A-Za-z0-9_-]+)\s*:\s*'([^']*)'/gm)) entries[e[1]] = e[2]; + assert.ok(Object.keys(entries).length > 0, `${name} should declare at least one CLI`); + return entries; +} + +// { cli: flag } pairs from the README row `| \`--dangerous\` | ... (\`flag\` for cli, ...) |`. +function readmeDangerousFlags(text) { + const row = text.split('\n').find((l) => l.startsWith('| `--dangerous`')); + assert.ok(row, 'README.md should document the --dangerous option in the attach flags table'); + const pairs = {}; + for (const m of row.matchAll(/`([^`]+)` for ([a-z0-9-]+)/g)) pairs[m[2]] = m[1]; + assert.ok(Object.keys(pairs).length > 0, 'README --dangerous row should list at least one `flag` for cli pair'); + return pairs; +} + +test('README --dangerous row lists every DANGEROUS_FLAGS entry with its exact flag', () => { + const flags = recordEntries(attachSource, 'DANGEROUS_FLAGS'); + const documented = readmeDangerousFlags(readme); + for (const [cli, flag] of Object.entries(flags)) { + assert.equal( + documented[cli], + flag, + `README --dangerous row should say \`${flag}\` for ${cli} (attach.ts DANGEROUS_FLAGS); ` + + `got ${documented[cli] === undefined ? 'no entry' : `\`${documented[cli]}\``}`, + ); + } + assert.deepEqual( + Object.keys(documented).sort(), + Object.keys(flags).sort(), + 'README --dangerous row should list exactly the CLIs DANGEROUS_FLAGS knows', + ); +});