Restore permission-gate auto-deny and fix Esc leaving gate promises unresolved - #340
Merged
TheGreatAxios merged 2 commits intoAug 7, 2026
Merged
Conversation
TheGreatAxios
force-pushed
the
cl-5568-5569-gate-dismiss-and-timeout
branch
from
August 7, 2026 04:48
47f94b8 to
d61373a
Compare
A local redeclaration of the gate event type omitted timeoutMs, timeoutMessage, and signal, so goal-mode timeouts and watchdog aborts were silently dropped. An unattended run could park on the permission modal forever with nobody able to answer it. Import the shared type instead, so the compiler catches a missing field, and wire a timer plus an abort listener into the permission handler that auto-deny and close the overlay. All three exit paths (accept, timeout, abort) guard on a settled flag so none can double-resolve, and a queued gate resolves on its own timeout without disturbing whichever gate is currently on screen.
Esc on a permission or operator overlay called closeInsetOverlay, which dropped the accept callback without ever invoking the caller's awaited resolve. The run deadlocked until the process was killed. Add an onCancel hook to the overlay opts and thread it through the open/close paths for the promise-backed overlay kinds only, so the gate wiring can resolve deny/cancel from it. Deliberate accept and answer-submit paths null the hook first so closing there does not also fire it. The operator gate also gains its own settled flag mirroring the permission gate, so double-resolve is prevented by construction rather than by callers remembering to null the hook. Update the operator "no way to answer" copy now that Esc actually settles the question.
TheGreatAxios
force-pushed
the
cl-5568-5569-gate-dismiss-and-timeout
branch
from
August 7, 2026 05:11
d61373a to
dbf21e4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PermissionGateEventtype ingate-wire.tsinstead of a narrower local redeclaration that silently droppedtimeoutMs,timeoutMessage, andsignalonPermissionso goal-mode timeouts and watchdog aborts auto-deny the gate and close the overlay, cleaning up after themselves on normal resolutiononCancelhook toOpenPermissionsOpts/OpenOperatorOptsand thread it throughopenListOverlay/closeInsetOverlayso Esc on a permission or operator overlay resolves the awaited promise (deny/cancel) instead of abandoning it; update the operator "no way to answer" copy to matchVerification
bun run typecheck,bun run build, andbun testall run clean except three pre-existing flaky failures unrelated to this change (markdown transcript rowsfence tests, ripgrep timing tests) — confirmed by rerunning and seeing a different flaky subset fail each timesrc/tui-opentui/gate-wire.test.ts(36 tests, up from 31) covers: timeout auto-deny with the given message and overlay close, abort auto-deny while the overlay is open, no leaked timer after a normal accept, and Esc resolving both the permission gate (deny) and the operator gate (cancel)onOperator: its local type already matched the sharedOperatorGateEventfield-for-field (no timeout/signal there), so only the type redeclaration needed fixing there, not new wiringoverlays.tsrendering logic (owned by a sibling fix for CL-5560) beyond adding theonCanceloption plumbingCloses CL-5568
Closes CL-5569