anomalyco / anomalyco/opencode

[FEATURE]: Require confirmation (debounced double Ctrl+C) before exiting the TUI

Open
#50,088 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Feature hasn't been suggested before.
  • I have verified this feature I'm about to request hasn't been suggested before.

Closely related requests exist, but they were either auto-closed without a change or track a different aspect (Windows copy conflict, remapping/disabling Ctrl+C). None currently tracks the rapid-repeat / debounce behavior described here. See Related issues at the bottom.

Describe the enhancement you want to request
Problem

Ctrl+C is deeply ingrained muscle memory for "stop / abort". When users want to end the current task they tend to tap Ctrl+C several times in quick succession. In the TUI, app.exit is bound to ctrl+c (default ctrl+c,ctrl+d,<leader>q), and with an empty prompt it fires immediately. A rapid burst therefore terminates the TUI before the user can react — often losing the session view or context.

Reconfiguring keybinds.app.exit works around it, but it is easy to be bitten by the default, and remapping doesn't solve the underlying behavior: repeated, near-simultaneous presses are each treated as a fresh confirm/exit signal.

Desired behavior (Claude Code-style)

Make Ctrl+C a debounced exit confirmation instead of an immediate exit:

  1. First Ctrl+C while idle → do not exit. Show a non-blocking hint such as Press Ctrl+C again to exit (a confirmation prompt is also fine).
  2. Rapid Ctrl+C presses within a short cooldown window (e.g. ~1–2s) → ignored / debounced. They must not count as the confirming press. So a spam burst ends with "hint shown, still running" rather than exiting.
  3. A Ctrl+C pressed after the cooldown has elapsed while the hint is visible → actually exit.
  4. While a task/generation is active, the first Ctrl+C should interrupt the current task (as session.interrupt does) and keep the TUI open. The exit-confirmation flow above only applies when idle.

In short: ignore the trailing presses of a rapid burst, ask for confirmation, and only exit if the user presses again after a short interval.

Why the current keybind options are insufficient
  • Setting app.exit to none/remapping is a manual workaround, not a safe default, and doesn't help users who intentionally keep ctrl+c as exit.
  • There is no way to express "require a second, non-rapid press to confirm" via the current string/none/preventDefault keybind forms.
Suggested configuration (optional)
{
  "keybinds": {
    // confirm exit; rapid repeat presses are debounced/ignored
    "app.exit": { "key": "ctrl+c", "confirm": true, "confirmTimeout": 2000 }
  }
}

Or a dedicated setting (default on):

{
  "app": { "exit": { "confirm": true, "confirmTimeout": 2000 } }
}
Environment
  • opencode 1.18.31
  • macOS, default keybinds (app.exit: ctrl+c,ctrl+d,<leader>q, prompt.clear: ctrl+c)
Related issues
  • #7957 — Ctrl+C should not exit OpenCode (Windows copy conflict)
  • #2999 — Provide means to disable Ctrl+C
  • #47290 — Allow remapping or disabling Ctrl+C to prevent accidental thread loss
  • #26371 / #15932 / #10975 / #41510 — earlier double-Ctrl+C requests (closed)
  • #4997 — Keybinds tracking issue

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the TUI's app.exit and prompt.clear keybind handling, then compare it with session.interrupt while a task is active. Define how idle Ctrl+C confirmation, rapid-repeat debouncing, cooldown expiry, and the existing keybind configuration should interact. Done means rapid bursts leave the TUI open, a later confirmation exits, and active tasks are interrupted without exiting.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.