@@ -8233,6 +8233,46 @@ describe("runCodexAppServerAttempt", () => {
82338233 expect ( nativeHookRelayTesting . getNativeHookRelayRegistrationForTests ( relayId ) ) . toBeUndefined ( ) ;
82348234 } ) ;
82358235
8236+ it ( "cleans up native hook relay state when Codex completes the turn as interrupted" , async ( ) => {
8237+ const harness = createStartedThreadHarness ( ) ;
8238+ const run = runCodexAppServerAttempt (
8239+ createParams ( path . join ( tempDir , "session.jsonl" ) , path . join ( tempDir , "workspace" ) ) ,
8240+ { nativeHookRelay : { enabled : true } , turnTerminalIdleTimeoutMs : 60_000 } ,
8241+ ) ;
8242+
8243+ await harness . waitForMethod ( "turn/start" ) ;
8244+ const startRequest = harness . requests . find ( ( request ) => request . method === "thread/start" ) ;
8245+ const relayId = extractRelayIdFromThreadRequest ( startRequest ?. params ) ;
8246+ await harness . notify ( {
8247+ method : "turn/completed" ,
8248+ params : {
8249+ threadId : "thread-1" ,
8250+ turnId : "turn-1" ,
8251+ turn : { id : "turn-1" , status : "interrupted" , items : [ ] } ,
8252+ } ,
8253+ } ) ;
8254+
8255+ const result = await run ;
8256+ expect ( result . aborted ) . toBe ( false ) ;
8257+ expect ( result . timedOut ) . toBe ( false ) ;
8258+ expect ( result . promptError ) . toBeNull ( ) ;
8259+ expect ( nativeHookRelayTesting . getNativeHookRelayRegistrationForTests ( relayId ) ) . toBeUndefined ( ) ;
8260+ await expect (
8261+ invokeNativeHookRelay ( {
8262+ provider : "codex" ,
8263+ relayId,
8264+ event : "pre_tool_use" ,
8265+ rawPayload : {
8266+ hook_event_name : "PreToolUse" ,
8267+ tool_name : "Bash" ,
8268+ tool_input : { command : "pnpm test" } ,
8269+ } ,
8270+ } ) ,
8271+ ) . rejects . toThrow ( "native hook relay not found" ) ;
8272+ testing . flushPendingCodexNativeHookRelayUnregistersForTests ( ) ;
8273+ expect ( nativeHookRelayTesting . getNativeHookRelayRegistrationForTests ( relayId ) ) . toBeUndefined ( ) ;
8274+ } ) ;
8275+
82368276 it ( "keeps upstream cancellation aborted when Codex completes the turn as interrupted" , async ( ) => {
82378277 const harness = createStartedThreadHarness ( ) ;
82388278 const abortController = new AbortController ( ) ;
0 commit comments