Skip to content

feat(tmux): auto-accept the bypass-permissions prompt on fresh installs#12

Merged
smixs merged 1 commit into
mainfrom
feat/bypass-permissions-prompt
Jun 17, 2026
Merged

feat(tmux): auto-accept the bypass-permissions prompt on fresh installs#12
smixs merged 1 commit into
mainfrom
feat/bypass-permissions-prompt

Conversation

@smixs

@smixs smixs commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Problem (reported by a downstream fork)

On a fresh machine / config dir, the bot launches claude --dangerously-skip-permissions, which shows a one-time full-screen modal:

WARNING: Claude Code running in Bypass Permissions mode
…
❯ 1. No, exit
  2. Yes, I accept

classify_state didn't know this screen → UNKNOWNRuntimeError: session not ready in 90s. The bot couldn't start until a human accepted the modal by hand. Hidden in production only because the modal was already accepted there once.

Fix

  • New PaneState.BYPASS_PROMPT, auto-selecting "2. Yes, I accept" in _ensure_locked — debounced to the state transition like the existing TRUST handling. Unlike TRUST, the safe default sits on "1. No, exit", so we actively send 2 (consistent with the survey-dismiss send-keys "0" pattern).
  • Double anchor for detection: the verbatim warning title AND the numbered accept line must both be present. "Yes, I accept" alone is reply-natural (a model could emit a numbered consent list), so requiring the unique title keeps detection as safe as TRUST's single un-reproducible line — hardened after blind review flagged the weaker single anchor.
  • On-screen text taken verbatim from the Claude Code binary v2.1.179 (not guessed).

Tests

  • test_classify_bypass_prompt — the real screen classifies.
  • test_classify_bypass_not_triggered_by_prose and …_by_numbered_list_reply — a reply mentioning bypass, or one whose line 2 reads "2. Yes, I accept the terms", stays READY (no false 2-injection by the watchdog's current_state()).
  • test_ensure_session_accepts_bypass_prompt / …_does_not_spam_bypass — sends 2 once and reaches READY; debounced across repeated captures.
  • 238 passed; ruff clean; no-claude-p guard clean.

Closes feedback item #1 (bypass-permissions modal blocks first run).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ee54f5a6a7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/d_brain/services/tmux_parse.py Outdated
Comment on lines +233 to +234
if _BYPASS_TITLE_RE.search(text) and _BYPASS_MENU_RE.search(text):
return PaneState.BYPASS_PROMPT

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Scope bypass prompt matching to the live modal

Because _capture() includes tmux scrollback (capture-pane ... -S -200), this whole-pane check also sees normal transcript text. If a completed reply quotes the bypass warning title and the 2. Yes, I accept menu line while the pane is otherwise idle, classify_state returns BYPASS_PROMPT instead of READY; the watchdog does not include this new state in _SERVICEABLE, so after the stall threshold it can force-recover a healthy session. Please constrain this detection to the actual modal region or otherwise prefer the live idle/footer state when the anchors only appear in scrollback.

Useful? React with 👍 / 👎.

First run with --dangerously-skip-permissions on a fresh CLAUDE_CONFIG_DIR
shows a full-screen "WARNING: Claude Code running in Bypass Permissions mode"
with a numbered menu (1. No, exit / 2. Yes, I accept). classify_state knew
nothing of it → UNKNOWN → "session not ready in 90s" RuntimeError on every
fresh install (the bot recovered only after a human accepted it by hand).

Add PaneState.BYPASS_PROMPT and auto-select "2. Yes, I accept" in
_ensure_locked (debounced to the transition, like TRUST). Unlike TRUST the
safe default sits on "1. No, exit", so we must actively send "2".

Detection uses a TRIPLE guard so a model reply can't be mistaken for the
modal: the verbatim warning title AND the numbered accept line must both be
present, AND the idle "bypass permissions on" footer must be ABSENT. The real
modal precedes the normal TUI (no footer yet); a working/idle session always
shows the footer. Without the footer guard a reply quoting the warning from
scrollback (capture spans -S -200) would classify as BYPASS_PROMPT, which the
watchdog does not list as serviceable → it would force-recover a healthy
session. Screen text taken verbatim from the Claude Code binary v2.1.179.

Tests: classify positive; three negatives (prose mention; a numbered-list
reply; the warning quoted in scrollback while the idle footer is present —
all stay READY); session accepts via "2" and reaches READY; "2" debounced
across repeated captures. Reported by a downstream fork; footer guard added
after Codex review.
@smixs smixs force-pushed the feat/bypass-permissions-prompt branch from ee54f5a to 484f474 Compare June 17, 2026 01:59
@smixs smixs merged commit f85e11f into main Jun 17, 2026
1 check passed
@smixs smixs deleted the feat/bypass-permissions-prompt branch June 17, 2026 02:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant