Skip to content

fix(launch): wait for idle before tmux attach on non-headless launch …#221

Merged
haofeif merged 2 commits into
mainfrom
fix/kiro-cli-attach-before-idle
Apr 30, 2026
Merged

fix(launch): wait for idle before tmux attach on non-headless launch …#221
haofeif merged 2 commits into
mainfrom
fix/kiro-cli-attach-before-idle

Conversation

@haofeif

@haofeif haofeif commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Fixes #220.

Problem

cao launch (non-headless) attached to the tmux session the moment the API returned, before the provider's TUI had finished wiring its input handler. The attach-time pty resize would race with init and the TUI silently dropped keystrokes — most visible on agents with many MCP servers where init takes longer.

Root cause

cli/commands/launch.py had asymmetric wait semantics:

if not headless:
    subprocess.run(["tmux", "attach-session", "-t", terminal["session_name"]])  # no wait
elif message:
    wait_until_terminal_status(terminal["id"], {IDLE, COMPLETED}, timeout=120)   # proper wait

The headless-with-message path already had the wait. The non-headless path needed the same guard.

Fix

Add wait_until_terminal_status before tmux attach-session:

if not headless:
    ready = wait_until_terminal_status(terminal["id"], {IDLE, COMPLETED}, timeout=120)
    if not ready:
        click.echo(click.style("  Warning: ... attaching anyway; input may be unreliable ...", fg="yellow"))
    subprocess.run(["tmux", "attach-session", "-t", terminal["session_name"]])

The wait is advisory — on timeout we warn and still attach, because orphaning a slow-initializing session in tmux is worse than letting the user watch it come alive.

Why this is reliable now

PR #215 (false-IDLE during Initializing...) already landed, which means wait_until_terminal_status actually blocks through init instead of returning early on the idle-prompt placeholder that kiro-cli's TUI v2 paints before init completes.

Relationship to recent fixes

All three address the same symptom (input dropped after launch) from different angles. They compose cleanly.

Changes

src/cli_agent_orchestrator/cli/commands/launch.py

  • Insert wait_until_terminal_status before subprocess.run(["tmux", "attach-session", ...]) with a warn-and-proceed fallback on timeout.

test/cli/commands/test_launch.py

  • New: test_launch_non_headless_waits_for_idle_before_attach — asserts the wait is called with the terminal id and runs before the attach.
  • New: test_launch_non_headless_attaches_even_if_wait_times_out — asserts warn-and-proceed on timeout.
  • Updated 4 existing non-headless tests to patch wait_until_terminal_status and include the terminal id in their mocked API response (previously the mock dict omitted id, which would now KeyError on the real code path).

Provider-agnostic

Although #220 was filed for kiro-cli, the wait applies to every provider. opencode_cli and others with slow TUI init also benefit.

Verification

  • uv run pytest test/cli/commands/test_launch.py -q21/21 pass
  • Full CI-filtered suite (--ignore=test/providers/test_q_cli_integration.py --ignore=test/providers/test_kiro_cli_integration.py --ignore=test/e2e -m "not e2e") — 1523 passed, 1 skipped
  • black --check src/.../launch.py test/.../test_launch.py — clean
  • isort --check-only src/.../launch.py test/.../test_launch.py — clean

Test plan

  • Unit suite passes
  • Lint + formatters clean
  • Non-headless cao launch waits for IDLE before attach
  • Non-headless launch still attaches if wait times out (with warning)
  • Live: cao launch --agents developer --yolo on a profile with multiple MCP servers — keystrokes land reliably after attach

…220)

Addresses issue #220. cao launch (non-headless) attached to the tmux
session the moment the API returned, before the provider's TUI had
finished wiring its input handler. The attach-time pty resize would then
race with init and the TUI would silently drop keystrokes — most visible
on profiles with many MCP servers where init takes longer.

The headless-with-message path already waits via
wait_until_terminal_status(IDLE/COMPLETED, timeout=120). This change
mirrors that wait on the non-headless path. When the wait times out we
still attach so the user can inspect a slow-initializing session rather
than orphan it in tmux; a yellow warning is printed.

With PR #215 (false-IDLE during Initializing...) already landed, this
wait reliably blocks through init instead of returning early on the
idle-prompt placeholder.

Changes
- src/cli_agent_orchestrator/cli/commands/launch.py: insert
  wait_until_terminal_status before subprocess.run(["tmux",
  "attach-session", ...]) with a warn-and-proceed fallback on timeout.
- test/cli/commands/test_launch.py: add regression guards
  (test_launch_non_headless_waits_for_idle_before_attach,
  test_launch_non_headless_attaches_even_if_wait_times_out); update the
  four existing non-headless tests to patch wait_until_terminal_status
  and include the terminal id in their mocked API response.

Verification
- 21/21 test/cli/commands/test_launch.py
- 1523 passed, 1 skipped under CI's ignore set
- black --check and isort --check-only clean on touched files
@haofeif

haofeif commented Apr 30, 2026

Copy link
Copy Markdown
Contributor Author

@carlosiduarte can you pls help to check this fix ?

@haofeif haofeif added the bug Something isn't working label Apr 30, 2026

@carlosiduarte carlosiduarte 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.

Thanks @haofeif! This is exactly the fix we've been running locally — confirmed it resolves the input-drop race on non-headless launch. LGTM ✅

@haofeif haofeif merged commit f650aa2 into main Apr 30, 2026
12 checks passed
@haofeif haofeif deleted the fix/kiro-cli-attach-before-idle branch April 30, 2026 11:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

kiro_cli TUI: input unresponsive when tmux attach runs before kiro finishes initializing

2 participants