Problem
The double Ctrl+C to exit functionality from sst/opencode#4900 was broken during a recent upstream merge. This feature prevents accidental exits by requiring users to press Ctrl+C twice within 2 seconds.
Currently, pressing Ctrl+C when the prompt is empty immediately exits the application, which is frustrating when users accidentally clear their prompt or hit Ctrl+C by mistake.
Expected Behavior
- First Ctrl+C press (with empty prompt): Show a warning toast "Press again to exit"
- Second Ctrl+C press within 2 seconds: Exit the application
- After 2 seconds: Reset the exit attempt counter
Current Behavior
Ctrl+C immediately exits when the prompt is empty, with no warning or confirmation.
Root Cause
During upstream merge, the tryExit function and lastExitAttempt tracking variable were lost from packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx. The code at line ~848-855 now directly calls exit() instead of the protective tryExit() wrapper.
Interestingly, the search.tsx component still has the tryExit implementation (lines 42-59), showing this pattern was preserved in some places but lost in the main prompt.
Acceptance Criteria
Implementation Details
Reference Implementation (from PR anomalyco#4900)
The original implementation adds these changes to prompt/index.tsx:
// After: const exit = useExit()
let lastExitAttempt = 0
async function tryExit() {
const now = Date.now()
if (now - lastExitAttempt < 2000) {
await exit()
return
}
lastExitAttempt = now
toast.show({
variant: "warning",
message: "Press again to exit",
duration: 2000,
})
}
Then change the exit handler from:
if (keybind.match("app_exit", e)) {
if (store.prompt.input === "") {
await exit() // <-- Currently this
To:
if (keybind.match("app_exit", e)) {
if (store.prompt.input === "") {
await tryExit() // <-- Should be this
Files to Modify
| File |
Change |
packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx:669 |
Add lastExitAttempt variable and tryExit() function after const exit = useExit() |
packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx:848-855 |
Replace exit() with tryExit() in app_exit keybind handler |
Reference: search.tsx Working Implementation
See packages/opencode/src/cli/cmd/tui/component/prompt/search.tsx:42-59 for the working pattern already in the codebase:
let lastExitAttempt = 0
async function tryExit() {
const now = Date.now()
if (now - lastExitAttempt < 2000) {
await exit()
return
}
lastExitAttempt = now
toast.show({
variant: "warning",
message: "Press again to exit",
duration: 2000,
})
}
External References
Tasks
Problem
The double Ctrl+C to exit functionality from sst/opencode#4900 was broken during a recent upstream merge. This feature prevents accidental exits by requiring users to press Ctrl+C twice within 2 seconds.
Currently, pressing Ctrl+C when the prompt is empty immediately exits the application, which is frustrating when users accidentally clear their prompt or hit Ctrl+C by mistake.
Expected Behavior
Current Behavior
Ctrl+C immediately exits when the prompt is empty, with no warning or confirmation.
Root Cause
During upstream merge, the
tryExitfunction andlastExitAttempttracking variable were lost frompackages/opencode/src/cli/cmd/tui/component/prompt/index.tsx. The code at line ~848-855 now directly callsexit()instead of the protectivetryExit()wrapper.Interestingly, the
search.tsxcomponent still has thetryExitimplementation (lines 42-59), showing this pattern was preserved in some places but lost in the main prompt.Acceptance Criteria
tryExit()function restored inpackages/opencode/src/cli/cmd/tui/component/prompt/index.tsxlastExitAttemptvariable tracks last exit attempt timestampscript/sync/fork-features.json(already present)Implementation Details
Reference Implementation (from PR anomalyco#4900)
The original implementation adds these changes to
prompt/index.tsx:Then change the exit handler from:
To:
Files to Modify
packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx:669lastExitAttemptvariable andtryExit()function afterconst exit = useExit()packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx:848-855exit()withtryExit()inapp_exitkeybind handlerReference: search.tsx Working Implementation
See
packages/opencode/src/cli/cmd/tui/component/prompt/search.tsx:42-59for the working pattern already in the codebase:External References
9a8b8b019af0d18de5a6edeb1ae43a16689b5e77Tasks
lastExitAttemptvariable after line 669tryExit()function afterlastExitAttempttryExit()instead ofexit()useToasthook is imported (already present at line 31)bun testin packages/opencode