Skip to content

fix: unblock fresh-agent onboarding on Claude Code 2.1.x (bypass prompt + numeric ALLOWED_USER) - #28

Closed
HubKey76 wants to merge 2 commits into
noogalabs:mainfrom
HubKey76:fix/claude-code-bypass-permissions-prompt
Closed

HubKey76 wants to merge 2 commits into
noogalabs:mainfrom
HubKey76:fix/claude-code-bypass-permissions-prompt

Conversation

@HubKey76

@HubKey76 HubKey76 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Two bugs that prevent a fresh agent from onboarding on Claude Code 2.1.x. Each is an independent commit.


1. fix(pty) — auto-accept the "Bypass Permissions mode" prompt

Every agent crash-loops on first boot. Claude Code 2.1.x shows a "Bypass Permissions mode" acceptance screen when launched with --dangerously-skip-permissions (which the Anthropic PTY adapter does). Its cursor defaults to 1. No, exit:

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

The trust-prompt auto-accept in AgentPTY.spawn() dismisses prompts with a bare Enter — which here selects "No, exit" and quits Claude. The watchdog marks the agent crashed and restarts it into the same wall forever. (bypassPermissionsModeAccepted=true in ~/.claude.json does not suppress it.) Worsened because 2. Yes, I accept contains Yes, so the existing recent.includes('Yes') check also fired the fatal Enter.

Fix: detect the screen and arrow-down to "2. Yes, I accept" before confirming, once per session (guarded so redundant timers don't inject stray keys into the live REPL). Match on single tokens ('Bypass', 'responsibility') — Claude's TUI positions each word with ANSI cursor-move codes, so there are no literal spaces in the PTY buffer and a multi-word substring like 'Bypass Permissions mode' never matches (same reason the existing single-token 'trust'/'Yes' checks work).

2. fix(detect-chat-id) — write the numeric user id to ALLOWED_USER

detect-chat-id derived ALLOWED_USER as user.username || String(user.fromId), so any operator who has a Telegram @username got a non-numeric value written to the agent .env. The daemon then rejects it — "ALLOWED_USER must be a comma-separated list of numeric Telegram user IDs" — and silently refuses to enable Telegram. The agent can send messages but never receives them, with no obvious cause.

Fix: always write the numeric fromId; keep @username only for the human-readable display label.


Testing

Both reproduced and fixed live on Claude Code 2.1.176 (macOS, Node v24):

🤖 Generated with Claude Code

HubKey76 and others added 2 commits July 6, 2026 15:40
Claude Code 2.1.x shows a "Bypass Permissions mode" acceptance screen on
launch with --dangerously-skip-permissions. Its cursor DEFAULTS to
"1. No, exit", so the trust-prompt auto-accept handler's bare Enter selected
"No, exit" and quit Claude — crash-looping every agent on first boot. The
option text "2. Yes, I accept" also made the existing recent.includes('Yes')
check fire that same fatal Enter.

Detect the screen and arrow-down to "2. Yes, I accept" before confirming,
exactly once per session (guarded so later redundant timers don't inject
stray keys into the live REPL).

Match on single tokens ('Bypass', 'responsibility'): Claude's TUI positions
each word with ANSI cursor-move codes, so there are no literal spaces in the
PTY buffer and a multi-word substring like 'Bypass Permissions mode' never
matches.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ername

detect-chat-id derived ALLOWED_USER as `user.username || String(user.fromId)`,
so any operator who has a Telegram @username got a non-numeric value written
to the agent's .env. The daemon then rejects it ("ALLOWED_USER must be a
comma-separated list of numeric Telegram user IDs") and SILENTLY refuses to
enable Telegram — the agent can send but never receives, with no obvious cause.

Always write the numeric fromId; keep @username only for the display label.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@HubKey76 HubKey76 changed the title fix(pty): auto-accept Claude Code 2.1.x "Bypass Permissions mode" prompt fix: unblock fresh-agent onboarding on Claude Code 2.1.x (bypass prompt + numeric ALLOWED_USER) Jul 6, 2026
noogalabs added a commit that referenced this pull request Jul 17, 2026
* fix(pty): harden bypass-permissions startup recovery

Port the member-reported fix from #11 using the canonical bounded, stateful handler. Retry only while the gate remains in the final 4KB, cap navigation at three answers, strip ANSI, and keep bare Enter unreachable while an exit-default marker is visible.

* fix(detect-chat-id): persist numeric Telegram user IDs

Port the diagnosis from #28 and verify the real command JSON path. ALLOWED_USER now always uses the numeric sender ID even when Telegram supplies an @username.

---------

Co-authored-by: NancyBraun <nancy@carolinaspropertymanagement.com>
Co-authored-by: HubKey76 <mike@hubkey.co>
@noogalabs

Copy link
Copy Markdown
Owner

@codex review\n\nPlease review exact head 6affad916da011bd97bc0b26c9925886a4199e93.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: 6affad916d

ℹ️ 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".

@noogalabs

Copy link
Copy Markdown
Owner

Closing this one as superseded - but with credit where it's due: you diagnosed this 11 days before the fix that landed, and the shape that shipped matches your diagnosis (default-to-"No, exit" handling, single-token matching, numeric user IDs).

Where it landed on main: afba07747d (#45, Jul 17) covers both halves - the bypass-gate handling in agent-pty.ts (since hardened further in #46 with a capped answer guard and a preflight suppression check) and the numeric-ID detect-chat-id - with the Aug 18 catch-up (#61) folding in the rest. Current main's version is more hardened than either of our earlier takes, so there's nothing left for this branch to add.

Thanks for being first to the diagnosis - that's what got it fixed. Hope to see more from you.

@noogalabs noogalabs closed this Aug 18, 2026
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.

2 participants