fix: a new account's first Claude session no longer opens on the bypass warning
--allow-dangerously-skip-permissions (bypass in the pane's shift+tab cycle) made Claude Code show its Bypass Permissions warning on any account that had not accepted it yet — every new member's first session, which the Chat UI cannot answer, though nobody asked for bypass. Now passed only when the run starts in bypassPermissions (asking is consent to see it) or the account's user settings already hold skipDangerousModePermissionPrompt (pty-run bypassAccepted; a member's read owner-checked from their home). The host, which accepted long ago, keeps the flag. Test: pty-run.
This commit is contained in:
+29
-1
@@ -165,6 +165,24 @@ function promptFileArgv(id, argv) {
|
||||
return ["sh", "-c", READ_PROMPT, "sh", file, ...argv.slice(0, -1)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the account a pane runs as has accepted Claude Code's bypass
|
||||
* warning — Claude writes `skipDangerousModePermissionPrompt: true` to its
|
||||
* user settings once it is. A member's (S3) is read from their home, owner-
|
||||
* checked; the host's from CLAUDE_HOME. Unreadable reads as "not yet".
|
||||
*/
|
||||
function bypassAccepted(member) {
|
||||
const file = member
|
||||
? path.join(member.home, ".claude", "settings.json")
|
||||
: path.join(require("./claude-home").getClaudeHome(), "settings.json");
|
||||
try {
|
||||
const text = require("./run-as").readFileSafe(file, "utf8", { max: 1 << 20 });
|
||||
return JSON.parse(text).skipDangerousModePermissionPrompt === true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function buildClaudeArgv({
|
||||
model,
|
||||
permissionMode,
|
||||
@@ -177,6 +195,7 @@ function buildClaudeArgv({
|
||||
addDirs = [],
|
||||
systemPromptFile = null,
|
||||
proxyArgv = [],
|
||||
offerBypass = true,
|
||||
platform = process.platform,
|
||||
}) {
|
||||
const argv = ["claude"];
|
||||
@@ -210,7 +229,11 @@ function buildClaudeArgv({
|
||||
// plan/auto/manual/acceptEdits, so a run started in any non-bypass mode could
|
||||
// never reach bypass from inside the pane, while a real terminal could.
|
||||
// The starting mode is still whatever --permission-mode says above.
|
||||
argv.push("--allow-dangerously-skip-permissions");
|
||||
// Only once the account has accepted Claude Code's bypass warning
|
||||
// (`offerBypass`, see bypassAccepted): before that the flag alone puts the
|
||||
// warning in front of a brand-new account's first session — one the Chat UI
|
||||
// cannot answer — although nobody asked for bypass.
|
||||
if (offerBypass) argv.push("--allow-dangerously-skip-permissions");
|
||||
if (model) argv.push("--model", model);
|
||||
if (effort && EFFORT_LEVELS.has(effort)) argv.push("--effort", effort);
|
||||
if (resumeSessionId) argv.push("--resume", resumeSessionId);
|
||||
@@ -512,6 +535,11 @@ function spawnRun(args) {
|
||||
resumeSessionId,
|
||||
forkSession: forkSession === true,
|
||||
newSessionId,
|
||||
// Asking for bypass is consent to see its warning; otherwise only an
|
||||
// account that already accepted it gets bypass in its shift+tab cycle.
|
||||
offerBypass:
|
||||
permissionMode === "bypassPermissions" ||
|
||||
(entry.launcher === "claude" && bypassAccepted(require("./run-as").accountForLane(laneId))),
|
||||
worktreeName: worktree === true ? `ah-${laneId}-${Date.now().toString(36)}` : null,
|
||||
resumeLast,
|
||||
bypass: bypass === true,
|
||||
|
||||
Reference in New Issue
Block a user