feat(run): make bypass permissions selectable in a lane pane's shift+tab cycle

`claude` only offers bypass in its shift+tab permission cycle when started
with `--allow-dangerously-skip-permissions`, which the pane argv never passed.
A dashboard-started run was therefore stuck cycling plan/auto/manual/
accept-edits, while the same session attached from a real terminal could
reach bypass.

The flag makes bypass SELECTABLE, not enabled — `claude --help`: "Enable
bypassing all permission checks as an option, without it being enabled by
default." The starting mode is still whatever `--permission-mode` says
(`acceptEdits` by default) and `--dangerously-skip-permissions`, which would
actually turn it on, is still never passed. Entering bypass remains an
explicit human shift+tab in the pane, or an explicit
`permissionMode: "bypassPermissions"` on POST /api/run.
This commit is contained in:
2026-08-20 08:32:43 +07:00
parent 77ca6e0188
commit ce2797b01f
4 changed files with 31 additions and 0 deletions
+20
View File
@@ -116,6 +116,26 @@ describe("pty-run", () => {
assert.ok(newSessionArgv.includes("abc12345"));
});
it("spawnRun offers bypass in the pane's shift+tab cycle without starting in it", () => {
let newSessionArgv = null;
tmux.__setExecImpl((args) => {
if (args[0] === "has-session") {
const e = new Error("gone");
e.status = 1;
throw e;
}
if (args[0] === "new-session") newSessionArgv = args;
return "";
});
pty.spawnRun({ laneId: 4, cwd: "/tmp/repo" });
assert.ok(newSessionArgv.includes("--allow-dangerously-skip-permissions"));
// ...as an OPTION only: the starting mode stays the requested one, and
// `--dangerously-skip-permissions` (which would enable it) is never passed.
assert.ok(!newSessionArgv.includes("--dangerously-skip-permissions"));
const modeAt = newSessionArgv.indexOf("--permission-mode");
assert.equal(newSessionArgv[modeAt + 1], "acceptEdits");
});
it("spawnRun appends a positional initial prompt after argv flags", () => {
let newSessionArgv = null;
tmux.__setExecImpl((args) => {