@@ -5,6 +5,30 @@ import { MaxBudgetUsdExceededError } from '#core/errors/maxBudgetUsd'
55import { MaxTurnsExceededError } from '#core/errors/maxTurns'
66import { randomUUID } from 'crypto'
77
8+ const PRINT_MODE_ABORT_SIGNALS : NodeJS . Signals [ ] = [
9+ 'SIGINT' ,
10+ 'SIGTERM' ,
11+ 'SIGBREAK' ,
12+ ]
13+
14+ function installPrintModeSignalAbort (
15+ abortController : AbortController ,
16+ ) : ( ) => void {
17+ const abort = ( ) => {
18+ abortController . abort ( )
19+ }
20+
21+ for ( const signal of PRINT_MODE_ABORT_SIGNALS ) {
22+ process . prependListener ( signal , abort )
23+ }
24+
25+ return ( ) => {
26+ for ( const signal of PRINT_MODE_ABORT_SIGNALS ) {
27+ process . removeListener ( signal , abort )
28+ }
29+ }
30+ }
31+
832type RunTurnFn = ( args : {
933 messages : Message [ ]
1034 canUseTool : CanUseToolFn
@@ -54,6 +78,9 @@ export async function runSingleTurnPrint(args: {
5478} ) : Promise < void > {
5579 let lastAssistant : Message | null = null
5680 let queryError : unknown = null
81+ const cleanupSignalAbort = installPrintModeSignalAbort (
82+ args . toolUseContext . abortController ,
83+ )
5784
5885 try {
5986 for await ( const m of args . runTurn ( {
@@ -75,6 +102,8 @@ export async function runSingleTurnPrint(args: {
75102 args . toolUseContext . abortController . abort ( )
76103 } catch { }
77104 queryError = e
105+ } finally {
106+ cleanupSignalAbort ( )
78107 }
79108
80109 const totalCostUsd = args . getTotalCostUsd ( )
@@ -219,3 +248,5 @@ export async function runSingleTurnPrint(args: {
219248 }
220249 process . exit ( ( resultMsg as any ) ?. is_error ? 1 : 0 )
221250}
251+
252+ export const __installPrintModeSignalAbortForTests = installPrintModeSignalAbort
0 commit comments