Files
oh-my-claudecode/scripts/lib
snowlaxcandClaude Opus 4.7 34c6d7ca17 fix(team): handle Claude Code v2.1.x banner and Enter swallow stalls
Claude Code v2.1.x ships two TUI changes that hang OMC team workflows:

1. A persistent "⏵⏵ bypass permissions on (shift+tab to cycle)" mode
   indicator that renders below the prompt on idle panes — previously
   used as a startup signal.
2. The TUI swallows a single Enter sent during state transitions while
   input handlers are still binding, so a freshly-typed message lands
   in the input buffer but is never submitted.

Reported symptoms:
- omc team N:claude workers hang in "[OMC] Starting..." forever.
- Dispatched messages appear in the worker input but never submit.
- New Claude Code sessions show "[OMC] Starting..." stuck on the
  statusLine until the user types a key, because v2.1.x does not
  re-poll the statusLine until input.

Detection + mitigation across three runtime paths and the HUD wrapper:
- paneHasClaudeStartupBanner: if a prompt is visible anywhere in the
  tail, treat the banner as the idle mode indicator, not bootstrap.
- runtime-v2 spawn: extend the bounded Enter-resubmit retry from 3 to
  4 attempts and evidence wait from 6 to 12 seconds, riding through a
  longer TUI bind window.
- defaultInjector: always send 2 Enters (was claude:1 / codex:2) so
  the dispatch path mirrors runtime-v2 swallow mitigation. Drop the
  now-unused resolveWorkerCliForRequest helper.
- hud-cache-wrapper.sh: when no cached HUD exists but stdin is
  available, refresh synchronously and emit the rendered line on the
  first frame; keep the "[OMC] Starting..." placeholder only for the
  no-stdin path.

Tests:
- src/team/__tests__/tmux-session.test.ts: v2.1.142 capture fixtures
  for idle pane (banner below prompt), mid-task pane (spinner +
  paneHasActiveTask), and banner-only pre-prompt.
- src/installer/__tests__/hud-cache-wrapper.test.ts: first-render
  returns the real HUD when stdin is present; placeholder path
  remains for the no-stdin case.

Constraint: Claude Code v2.1.x rendering and input-handler binding are
external behavior we cannot influence; fixes are detection and timing
accommodations.

Rejected: Bumping the dispatch timeout | timeout was never the
bottleneck — the wrapper and injector were producing the wrong output
deterministically. Raising it would mask the issue and worsen the
first-frame statusLine UX.

Confidence: high

Scope-risk: moderate

Directive: Future edits to paneHasClaudeStartupBanner must keep the
prompt-presence short-circuit; v2.1.x idle panes rely on it to avoid
the same false-positive recurring under a different banner string.

Tested: npm run test:run -- src/team/__tests__/tmux-session.test.ts
(34/34); npm run test:run -- src/installer/__tests__/hud-cache-wrapper.test.ts
(8/8); manual omc team N:claude dispatch on Claude Code v2.1.142;
manual new-session statusLine first-frame check.

Not-tested: Behavior on Claude Code <2.1 (no permanent mode
indicator) — the banner-without-prompt branch remains, so the previous
detection is preserved by construction.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 16:09:26 +00:00
..