Skip to content

feat: make esc interrupt/skip instead of exit #715

Description

@avoidwork

Summary

Change the ESC key behavior in the TUI to interrupt or skip the current operation instead of exiting the application entirely.

Motivation

Currently, pressing ESC exits the application, which can be destructive when the user intends to cancel or interrupt a specific operation (e.g., a long-running command, a search, or a prompt). Users need a non-destructive way to back out of operations without losing their session or having to restart the application.

Proposed Solution

Modify the ESC key handler in the TUI input system to:

  • Interrupt or skip the current operation when ESC is pressed
  • Keep the application running and return to the main prompt
  • Preserve the current session state
  • Optionally provide visual feedback that the operation was interrupted

Alternatives Considered

  • Adding a separate keybinding for interrupt (e.g., Ctrl+C) — but ESC is a more intuitive "back out" key for many users
  • Making the behavior configurable — could be added later if needed, but the default should be interrupt/skip

OpenSpec Note

This project uses OpenSpec for feature development. If this request is approved, I will:

  1. Run /opsx:propose to generate a full proposal with specs and tasks
  2. Iterate on the design before any code is written
  3. Follow the task-driven implementation workflow

Additional Context

This affects the TUI input handling, likely in src/tui/inputPanel.js or src/tui/commandParser.js. The change should be tested to ensure it works correctly with all current TUI operations.

Audit Findings (for Issue #715)

  • src/tui/app.js:841-848 — The ESC key handler in the main useInput callback: when isStreamingRef.current is true, it calls handleInterrupt(), but when false it calls handleQuit() which exits the app. This is the primary location to change.
  • src/tui/app.js:819-821 — Onboarding phase also calls handleQuit() on ESC. Consider whether ESC should interrupt/skip during onboarding too.
  • src/tui/app.js:827-829 — Banner dismissal calls handleQuit() on ESC. This may be intentional (close banner) but worth reviewing.
  • src/tui/settingsPanel.js:26 — Settings panel uses key.escape to exit the panel (not the app). This is likely correct behavior.
  • src/tui/memoryPanel.js:26 — Memory panel uses key.escape to exit the panel. Same as above, likely correct.
  • src/tui/banner.js:46 — Banner component uses key.escape to dismiss. Likely correct.

The core change is in app.js:841-848: replace the handleQuit() call in the non-streaming branch with an interrupt/skip action that clears the current input or returns to the main prompt without exiting.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions