From ea0091a49f2c7f833bc65351aa18f4b25f925880 Mon Sep 17 00:00:00 2001 From: sec-check Date: Sun, 11 Oct 2026 22:52:24 -0400 Subject: [PATCH] fix(attach): word-split multi-token --dangerous flags so omp gets --approval-mode yolo as two args Fixes #227 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: sec-check --- README.md | 2 +- changelog.d/fixed-omp-dangerous-flag.md | 1 + src/attach.ts | 4 +++- test/cli.test.js | 11 +++++++++++ 4 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 changelog.d/fixed-omp-dangerous-flag.md 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/changelog.d/fixed-omp-dangerous-flag.md b/changelog.d/fixed-omp-dangerous-flag.md new file mode 100644 index 0000000..f9fdaae --- /dev/null +++ b/changelog.d/fixed-omp-dangerous-flag.md @@ -0,0 +1 @@ +- `pluk attach --cli=omp --dangerous` now passes `--approval-mode yolo` as two arguments; previously omp received a single `--approval-mode yolo` token and the flag had no effect. diff --git a/src/attach.ts b/src/attach.ts index 99da4be..58a89be 100644 --- a/src/attach.ts +++ b/src/attach.ts @@ -295,7 +295,9 @@ export function attach(opts: AttachOptions): void { if (opts.dangerouslySkipPermissions) { const dangerFlag = resolveDangerousFlag(cli); if (dangerFlag) { - fullCmd += ` ${shellQuote(dangerFlag)}`; + // Word-split: some flags are two tokens (omp's `--approval-mode yolo`), + // and a single shellQuote() would hand the CLI one argv entry. + fullCmd += ` ${splitShellWords(dangerFlag).map(shellQuote).join(' ')}`; } else { log(`no dangerous/auto flag known for cli=${cli}, skipping`); } diff --git a/test/cli.test.js b/test/cli.test.js index 38f7917..424487e 100644 --- a/test/cli.test.js +++ b/test/cli.test.js @@ -255,6 +255,17 @@ test('attach --dangerous appends the per-CLI danger flag to the start command', assert.match(calls, /^send-keys -t =agent-y: -- 'claude' '--dangerously-skip-permissions' Enter$/m); }); +test('attach --dangerous word-splits a multi-token danger flag (omp)', () => { + rmSync(tmuxLog, { force: true }); + const runDir = makeRunDir(); + const { code } = runCli([ + 'attach', 'agent-omp', '--cli=omp', `--run-dir=${runDir}`, '--no-open', '--dangerous', + ]); + assert.equal(code, 0); + const calls = readFileSync(tmuxLog, 'utf-8'); + assert.match(calls, /^send-keys -t =agent-omp: -- 'omp' '--approval-mode' 'yolo' Enter$/m); +}); + // --- watch over stdin ------------------------------------------------------------- test('watch classifies stdin lines and emits JSONL events', () => {