* Helper to run .mux/init hook if it exists and is executable. * Shared between WorktreeRuntime and LocalRuntime. * @param workspacePath - Path to the workspace directory * @param muxEnv - MUX_ environment variables (from getMuxEnv) * @param initLogger - Logger for streaming output *
(
workspacePath: string,
muxEnv: Record<string, string>,
initLogger: InitLogger,
abortSignal?: AbortSignal
)
| 422 | * @param abortSignal - Optional abort signal |
| 423 | */ |
| 424 | protected async runInitHook( |
| 425 | workspacePath: string, |
| 426 | muxEnv: Record<string, string>, |
| 427 | initLogger: InitLogger, |
| 428 | abortSignal?: AbortSignal |
| 429 | ): Promise<void> { |
| 430 | // Hook path is derived from MUX_PROJECT_PATH in muxEnv |
| 431 | const projectPath = muxEnv.MUX_PROJECT_PATH; |
| 432 | const hookPath = getInitHookPath(projectPath); |
| 433 | initLogger.logStep(`Running init hook: ${hookPath}`); |
| 434 | |
| 435 | if (abortSignal?.aborted) { |
| 436 | initLogger.logComplete(EXIT_CODE_ABORTED); |
| 437 | return; |
| 438 | } |
| 439 | |
| 440 | // Create line-buffered loggers |
| 441 | const loggers = createLineBufferedLoggers(initLogger); |
| 442 | |
| 443 | return new Promise<void>((resolve) => { |
| 444 | const bashPath = getBashPath(); |
| 445 | const proc = spawn(bashPath, ["-c", shellQuote(hookPath)], { |
| 446 | cwd: workspacePath, |
| 447 | stdio: ["ignore", "pipe", "pipe"], |
| 448 | env: { |
| 449 | ...process.env, |
| 450 | ...muxEnv, |
| 451 | }, |
| 452 | // Prevent console window from appearing on Windows |
| 453 | windowsHide: true, |
| 454 | // Spawn as a detached process group leader so we can reliably cancel the hook. |
| 455 | detached: true, |
| 456 | }); |
| 457 | |
| 458 | let aborted = false; |
| 459 | |
| 460 | const onAbort = () => { |
| 461 | aborted = true; |
| 462 | |
| 463 | if (proc.pid !== undefined) { |
| 464 | killProcessTree(proc.pid); |
| 465 | return; |
| 466 | } |
| 467 | |
| 468 | try { |
| 469 | proc.kill("SIGKILL"); |
| 470 | } catch { |
| 471 | // ignore |
| 472 | } |
| 473 | }; |
| 474 | |
| 475 | abortSignal?.addEventListener("abort", onAbort, { once: true }); |
| 476 | if (abortSignal?.aborted) { |
| 477 | onAbort(); |
| 478 | } |
| 479 | |
| 480 | proc.stdout.on("data", (data: Buffer) => { |
| 481 | loggers.stdout.append(data.toString()); |
nothing calls this directly
no test coverage detected