(eventName: string, backgroundFn?: (shellId: string) => void)
| 922 | |
| 923 | // Helper to start backgrounding with optional logging |
| 924 | function startBackgrounding(eventName: string, backgroundFn?: (shellId: string) => void): void { |
| 925 | // If a foreground task is already registered (via registerForeground in the |
| 926 | // progress loop), background it in-place instead of re-spawning. Re-spawning |
| 927 | // would overwrite tasks[taskId], emit a duplicate task_started SDK event, |
| 928 | // and leak the first cleanup callback. |
| 929 | if (foregroundTaskId) { |
| 930 | if (!backgroundExistingForegroundTask(foregroundTaskId, shellCommand, description || command, setAppState, toolUseId)) { |
| 931 | return; |
| 932 | } |
| 933 | backgroundShellId = foregroundTaskId; |
| 934 | logEvent(eventName, { |
| 935 | command_type: getCommandTypeForLogging(command) |
| 936 | }); |
| 937 | backgroundFn?.(foregroundTaskId); |
| 938 | return; |
| 939 | } |
| 940 | |
| 941 | // No foreground task registered — spawn a new background task |
| 942 | // Note: spawn is essentially synchronous despite being async |
| 943 | void spawnBackgroundTask().then(shellId => { |
| 944 | backgroundShellId = shellId; |
| 945 | |
| 946 | // Wake the generator's Promise.race so it sees backgroundShellId. |
| 947 | // Without this, if the poller has stopped ticking for this task |
| 948 | // (no output + shared-poller race with sibling stopPolling calls) |
| 949 | // and the process is hung on I/O, the race at line ~1357 never |
| 950 | // resolves and the generator deadlocks despite being backgrounded. |
| 951 | const resolve = resolveProgress; |
| 952 | if (resolve) { |
| 953 | resolveProgress = null; |
| 954 | resolve(); |
| 955 | } |
| 956 | logEvent(eventName, { |
| 957 | command_type: getCommandTypeForLogging(command) |
| 958 | }); |
| 959 | if (backgroundFn) { |
| 960 | backgroundFn(shellId); |
| 961 | } |
| 962 | }); |
| 963 | } |
| 964 | |
| 965 | // Set up auto-backgrounding on timeout if enabled |
| 966 | // Only background commands that are allowed to be auto-backgrounded (not sleep, etc.) |
no test coverage detected