MCPcopy Create free account
hub / github.com/AnukarOP/claude-code-leaked / executeInBackground

Function executeInBackground

source code/utils/hooks.ts:186–267  ·  view source on GitHub ↗
({
  processId,
  hookId,
  shellCommand,
  asyncResponse,
  hookEvent,
  hookName,
  command,
  asyncRewake,
  pluginId,
}: {
  processId: string
  hookId: string
  shellCommand: ShellCommand
  asyncResponse: AsyncHookJSONOutput
  hookEvent: HookEvent | 'StatusLine' | 'FileSuggestion'
  hookName: string
  command: string
  asyncRewake?: boolean
  pluginId?: string
})

Source from the content-addressed store, hash-verified

184}
185
186function executeInBackground({
187 processId,
188 hookId,
189 shellCommand,
190 asyncResponse,
191 hookEvent,
192 hookName,
193 command,
194 asyncRewake,
195 pluginId,
196}: {
197 processId: string
198 hookId: string
199 shellCommand: ShellCommand
200 asyncResponse: AsyncHookJSONOutput
201 hookEvent: HookEvent | 'StatusLine' | 'FileSuggestion'
202 hookName: string
203 command: string
204 asyncRewake?: boolean
205 pluginId?: string
206}): boolean {
207 if (asyncRewake) {
208 // asyncRewake hooks bypass the registry entirely. On completion, if exit
209 // code 2 (blocking error), enqueue as a task-notification so it wakes the
210 // model via useQueueProcessor (idle) or gets injected mid-query via
211 // queued_command attachments (busy).
212 //
213 // NOTE: We deliberately do NOT call shellCommand.background() here, because
214 // it calls taskOutput.spillToDisk() which breaks in-memory stdout/stderr
215 // capture (getStderr() returns '' in disk mode). The StreamWrappers stay
216 // attached and pipe data into the in-memory TaskOutput buffers. The abort
217 // handler already no-ops on 'interrupt' reason (user submitted a new
218 // message), so the hook survives new prompts. A hard cancel (Escape) WILL
219 // kill the hook via the abort handler, which is the desired behavior.
220 void shellCommand.result.then(async result => {
221 // result resolves on 'exit', but stdio 'data' events may still be
222 // pending. Yield to I/O so the StreamWrapper data handlers drain into
223 // TaskOutput before we read it.
224 await new Promise(resolve => setImmediate(resolve))
225 const stdout = await shellCommand.taskOutput.getStdout()
226 const stderr = shellCommand.taskOutput.getStderr()
227 shellCommand.cleanup()
228 emitHookResponse({
229 hookId,
230 hookName,
231 hookEvent,
232 output: stdout + stderr,
233 stdout,
234 stderr,
235 exitCode: result.code,
236 outcome: result.code === 0 ? 'success' : 'error',
237 })
238 if (result.code === 2) {
239 enqueuePendingNotification({
240 value: wrapInSystemReminder(
241 `Stop hook blocking error from command "${hookName}": ${stderr || stdout}`,
242 ),
243 mode: 'task-notification',

Callers 1

execCommandHookFunction · 0.85

Calls 8

emitHookResponseFunction · 0.85
wrapInSystemReminderFunction · 0.85
registerPendingAsyncHookFunction · 0.85
getStdoutMethod · 0.80
getStderrMethod · 0.80
cleanupMethod · 0.45
backgroundMethod · 0.45

Tested by

no test coverage detected