@@ -387,7 +387,7 @@ describe("slash/palette accept holds the host until dispatch settles", () => {
387387 closeInsetOverlay ( shell ) ;
388388 await Promise . resolve ( ) ;
389389 expect ( shell . overlayKind ) . toBe ( "help" ) ;
390- expect ( resolved ) . not . toBeUndefined ( ) ;
390+ expect ( resolved ) . toEqual ( { allow : false } ) ;
391391 } finally {
392392 dispose ( ) ;
393393 }
@@ -428,7 +428,7 @@ describe("slash/palette accept holds the host until dispatch settles", () => {
428428 acceptOverlaySelection ( shell ) ;
429429 await Promise . resolve ( ) ;
430430 expect ( shell . overlayKind ) . toBe ( "help" ) ;
431- expect ( liveResolved ) . not . toBeUndefined ( ) ;
431+ expect ( liveResolved ) . toEqual ( { allow : false } ) ;
432432 expect ( queuedResolved ) . toBeUndefined ( ) ;
433433
434434 await Bun . sleep ( 20 ) ;
@@ -588,7 +588,7 @@ describe("slash/palette accept holds the host until dispatch settles", () => {
588588 closeInsetOverlay ( shell ) ;
589589 await Promise . resolve ( ) ;
590590 expect ( shell . overlayKind ) . toBe ( "settings" ) ;
591- expect ( resolved ) . not . toBeUndefined ( ) ;
591+ expect ( resolved ) . toEqual ( { allow : false } ) ;
592592 } finally {
593593 dispose ( ) ;
594594 }
@@ -649,7 +649,7 @@ describe("slash/palette accept holds the host until dispatch settles", () => {
649649 closeInsetOverlay ( shell ) ;
650650 await Promise . resolve ( ) ;
651651 expect ( shell . overlayKind ) . toBe ( "mcp" ) ;
652- expect ( resolved ) . not . toBeUndefined ( ) ;
652+ expect ( resolved ) . toEqual ( { allow : false } ) ;
653653 } finally {
654654 dispose ( ) ;
655655 }
@@ -1061,7 +1061,7 @@ describe("overlay host occupancy and opt-in deferral", () => {
10611061 closeInsetOverlay ( shell ) ;
10621062 await Promise . resolve ( ) ;
10631063 expect ( shell . overlayKind ) . toBe ( "add_provider" ) ;
1064- expect ( resolved ) . not . toBeUndefined ( ) ;
1064+ expect ( resolved ) . toEqual ( { allow : false } ) ;
10651065 } finally {
10661066 dispose ( ) ;
10671067 }
@@ -1083,4 +1083,49 @@ describe("overlay host occupancy and opt-in deferral", () => {
10831083 expect ( isOverlayHostIdle ( shell ) ) . toBe ( true ) ;
10841084 } ) ;
10851085 } ) ;
1086+
1087+ test ( "Esc during a reservation drains a queued gate without denying it" , async ( ) => {
1088+ await withShell ( async ( { shell, press, render } ) => {
1089+ const emitter = new EventEmitter ( ) ;
1090+ const dispose = wireGates ( emitter , shell ) ;
1091+ try {
1092+ reserveOverlayHost ( shell ) ;
1093+ let resolved : unknown ;
1094+ emitPermissionGate ( emitter , ( outcome ) => {
1095+ resolved = outcome ;
1096+ } ) ;
1097+ expect ( shell . overlayKind ) . not . toBe ( "permissions" ) ;
1098+ expect ( resolved ) . toBeUndefined ( ) ;
1099+
1100+ press ( "Escape" ) ;
1101+ await render ( ) ;
1102+ await Bun . sleep ( 60 ) ;
1103+ expect ( shell . overlayKind ) . toBe ( "permissions" ) ;
1104+ expect ( resolved ) . toBeUndefined ( ) ;
1105+ } finally {
1106+ dispose ( ) ;
1107+ }
1108+ } ) ;
1109+ } ) ;
1110+
1111+ test ( "stale reservation release does not drop a later hold" , async ( ) => {
1112+ await withShell ( async ( { shell, press, render } ) => {
1113+ const first = reserveOverlayHost ( shell ) ;
1114+ expect ( isOverlayHostIdle ( shell ) ) . toBe ( false ) ;
1115+
1116+ press ( "Escape" ) ;
1117+ await render ( ) ;
1118+ await Bun . sleep ( 60 ) ;
1119+ expect ( isOverlayHostIdle ( shell ) ) . toBe ( true ) ;
1120+
1121+ const second = reserveOverlayHost ( shell ) ;
1122+ expect ( isOverlayHostIdle ( shell ) ) . toBe ( false ) ;
1123+
1124+ first ( ) ;
1125+ expect ( isOverlayHostIdle ( shell ) ) . toBe ( false ) ;
1126+
1127+ second ( ) ;
1128+ expect ( isOverlayHostIdle ( shell ) ) . toBe ( true ) ;
1129+ } ) ;
1130+ } ) ;
10861131} ) ;
0 commit comments