fix(claude_code): handle bypass permissions prompt on startup (#119)#120
Merged
Conversation
Claude Code v2.1.41+ shows a "Bypass Permissions mode" confirmation dialog on every launch with --dangerously-skip-permissions unless skipDangerousModePermissionPrompt is persisted in ~/.claude/settings.json. This blocks CAO initialization with a 30-second timeout. Two-layer fix: - Preventive: write skipDangerousModePermissionPrompt: true to ~/.claude/settings.json before launching Claude Code - Defensive: detect "Yes, I accept" in tmux buffer and send Down+Enter as a fallback if the settings-based fix doesn't take effect Also: - Rename _handle_trust_prompt → _handle_startup_prompts to reflect it now handles both bypass permissions and workspace trust prompts - Use continue (not return) after accepting bypass prompt so a subsequent trust prompt is still handled - Exclude bypass prompt from WAITING_USER_ANSWER status detection Closes #119 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…s-permissions-prompt
Add startswith("/") guard after realpath() to satisfy CodeQL's
py/path-injection two-state taint model. CodeQL recognizes
str.startswith() as a SafeAccessCheck that clears NormalizedUnchecked
taint. The guard is always true after realpath() but explicitly
rejects relative paths and satisfies the static analysis requirement.
Regression was introduced in d22ebde (#110) which relaxed the home
directory containment check to allow paths outside ~/. This removed
the startswith(home_dir) guard that CodeQL relied on.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
_handle_trust_prompt→_handle_startup_promptsto handle both bypass and trust promptsCloses #119
Problem
Claude Code v2.1.41+ shows a "Bypass Permissions mode" confirmation dialog on every launch with
--dangerously-skip-permissionsunlessskipDangerousModePermissionPrompt: trueis persisted in~/.claude/settings.json(ref: anthropics/claude-code#25503). The default selection is "No, exit" (option 1), so pressing Enter exits Claude Code. This causes CAO to timeout after 30 seconds during initialization.WARNING: Claude Code running in Bypass Permissions mode
...
❯ 1. No, exit
2. Yes, I accept
Enter to confirm · Esc to cancel
What this adds on top of
mainmainalready handles the bypass prompt viasubprocess.run(raw escape sequence). This PR adds:_ensure_skip_bypass_prompt_setting()skipDangerousModePermissionPrompt: trueto~/.claude/settings.jsonbefore launch — prevents the prompt entirely instead of relying on the UI fallbackbypass_acceptedflag +continueinstead ofreturnmainreturns after handling bypass, so if the trust prompt follows, it gets missed and causes a hangBYPASS_PROMPT_PATTERN+get_status()exclusionWAITING_USER_ANSWERFix
skipDangerousModePermissionPrompt: trueto~/.claude/settings.jsonbefore launchDownescape sequence +Entervia subprocessget_status()fixWAITING_USER_ANSWERdetectionDesign decisions
Settings-based fix is the primary layer — deterministic, no timing dependency. The UI fallback is kept as defense-in-depth.
continuenotreturnafter accepting bypass prompt — the workspace trust prompt may followbypass_acceptedflag prevents re-sending keystrokes when stale text remains in the tmux buffer\x1b[B) for Down arrow —tmux send-keys "Down"doesn't work with Claude's Ink TUI~/.claude/settings.json, merges the key, writes back (same pattern as Gemini CLI's~/.gemini/settings.jsonMCP registration)Files Changed
src/cli_agent_orchestrator/providers/claude_code.pyBYPASS_PROMPT_PATTERN,_ensure_skip_bypass_prompt_setting(), renamed_handle_trust_prompt→_handle_startup_promptswith bypass prompt handling, updatedget_status()exclusiontest/providers/test_claude_code_unit.pyget_status()exclusionTesting