Skip to content

Give tuiPromptRunner the same startup-dialog dismissals as the CoS agent path #4180

Description

@atomantic

Problem

executeTuiRun (server/lib/tuiPromptRunner.js) still gates its paste on the old idle heuristic — "saw output, then went quiet for READY_IDLE_THRESHOLD_MS", with a blind sendPrompt('fallback') at PASTE_DEADLINE_MS. It has no equivalent of the CoS agent path's positive input-ready gate or its startup-dialog dismissals.

That means any first-run/opt-in modal the provider CLI paints will be treated as "the banner finished repainting", and the prompt gets pasted into the dialog, which ignores it. The run then burns its full timeout and finalizes on whatever the screen happened to say.

The agent path (server/services/agentTuiSpawning.js) has already had to learn this lesson twice:

  • Claude Code's folder-trust gate (TUI_TRUST_PROMPT_PATTERN)
  • Claude Code v2.1.233's auto-mode offer (TUI_AUTO_MODE_PROMPT_PATTERN) — four agents died paste-not-rendered on 2026-08-14 before it was handled

tuiPromptRunner handles neither, so a one-shot TUI run in a folder claude has not seen, or on a CLI version showing a new opt-in, fails the same way with no dismissal.

Why it was left out of the fix

The auto-mode fix scoped itself to the CoS agent spawner, which is where the incident happened and the only consumer of createInputReadyTracker. Extending tuiPromptRunner is a real behavior change to a separate execution path (it would newly suppress the blind-paste fallback), so it wants its own change and its own test pass rather than riding along.

Proposed work

  1. Build the shared tracker in tuiPromptRunner too: createInputReadyTracker(...) from server/lib/tuiHandshake.js, fed from the existing onData handler with both the raw and ANSI-stripped chunk.
  2. Add the two dismissal branches to the readyTimer interval, mirroring agentTuiSpawning.jsneedsTrust\r (accept "Yes, I trust"); needsAutoModeChoice\x1b[B\r (decline, then ackAutoModeChoice()), each behind a one-shot latch.
  3. Decide the fallback posture explicitly. The agent path refuses to blind-paste and fails tui-not-ready at the deadline. tuiPromptRunner currently always blind-pastes. Recommendation: keep the blind-paste fallback for non-claude providers, but suppress it while needsTrust/needsAutoModeChoice is armed — pasting into a known-live modal is never right, and the hard timeout is still the backstop.
  4. Tests in server/lib/tuiPromptRunner.test.js: a run that paints the trust gate and one that paints the auto-mode offer both dismiss it and then paste. Verify each test bites by reverting the branch.

Acceptance

  • A one-shot TUI run started in an untrusted folder dismisses the trust gate and submits its prompt.
  • A run that hits the auto-mode offer declines it (option 2 — never rewrite the user's global permission default) and submits its prompt.
  • No blind paste is sent while a known dialog is on screen.

Refs #4181 (the CoS-agent-side fix for the same class).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

in-progressClaimed and being workedplanTracked by /do:replan

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions