import { randomUUID } from "node:crypto"; import { constants } from "node:fs"; import { access, realpath } from "node:fs/promises"; import { isAbsolute } from "node:path"; import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisOutputError, } from "../../domain/analysisErrorCore.js"; import { ProviderAdapterError } from "../../domain/providerAdapterError.js"; import { ProviderCleanupError } from "../../domain/providerCleanupError.js"; import { cleanupOwnedProcessGroup } from "../../process/ProcessOwnership.js"; import { ProviderProcessSupervisor, spawnOwnedProviderProcess, type OwnedProviderProcessSpawnOptions, type SpawnedOwnedProviderProcess, } from "../../process/ProviderProcess.js"; import { checkRecoveryDeadline, inventoryRecoveryFiles, fingerprintRecoveryFile, recoveryFailureMessage, } from "./RecoveryFiles.js"; import { RECOVERY_LIMITS } from "./WakaruRelease.js"; const OPERATION = "recover_javascript_sources"; /** Inject the owned process launcher while retaining production protocol parsing. */ export type WakaruLauncher = ( options: OwnedProviderProcessSpawnOptions, ) => Promise; /** Resolve and fingerprint explicitly configured tools; acquire nothing at startup. */ export const resolveWakaruCommand = async ( environment: Readonly>, ) => { const configured = environment.REA_WAKARU_COMMAND; if ( process.platform !== "linux" || process.arch !== "x64" || configured === undefined || !isAbsolute(configured) ) throw new AnalysisCapabilityUnavailableError( "wakaru", OPERATION, "Provide an absolute REA_WAKARU_COMMAND pointing to Wakaru 1.13.0 on Linux x64; no tool is installed by REA", ); try { const command = await realpath(configured); await access(command, constants.R_OK | constants.X_OK); const fingerprint = await fingerprintRecoveryFile( command, RECOVERY_LIMITS.outputBytes, ); const limiter = environment.REA_JAVASCRIPT_PRLIMIT_COMMAND ?? "/usr/bin/prlimit"; if (!isAbsolute(limiter)) throw new TypeError("REA_JAVASCRIPT_PRLIMIT_COMMAND must be absolute"); await access(limiter, constants.X_OK); return { command, limiter, ...fingerprint }; } catch (cause: unknown) { throw new AnalysisCapabilityUnavailableError( "wakaru", OPERATION, `Configured Wakaru or util-linux prlimit is unavailable: ${recoveryFailureMessage(cause)}`, { cause }, ); } }; type WakaruCommandContext = { command: string; limiter: string; arguments: readonly string[]; cwd: string; deadline: number; environment: Readonly>; signal?: AbortSignal; launcher?: WakaruLauncher; staging?: string; }; /** Run one bounded command and verify cleanup before consuming its output. */ export const runWakaruCommand = async (context: WakaruCommandContext) => { checkRecoveryDeadline(context.deadline, context.signal); const runId = `rea-wakaru-${randomUUID()}`; const spawned = await (context.launcher ?? spawnOwnedProviderProcess)({ command: context.limiter, arguments: [ `--as=${String(RECOVERY_LIMITS.addressSpaceBytes)}`, `--fsize=${String(RECOVERY_LIMITS.outputBytes)}`, "--core=0", "--cpu=120", "--", context.command, ...context.arguments, ], expectedCommand: null, runId, cwd: context.cwd, hostEnvironment: context.environment, ...(context.signal === undefined ? {} : { signal: context.signal }), env: { TMPDIR: context.cwd, RAYON_NUM_THREADS: "1", NO_COLOR: "1" }, }).catch((cause: unknown) => { if (context.signal?.aborted === true) throw new AnalysisCancelledError(OPERATION); throw new ProviderAdapterError("wakaru", OPERATION, { cause, diagnostics: { reason: "Failed to launch configured Wakaru through util-linux prlimit", command: context.command, detail: recoveryFailureMessage(cause), }, }); }); let oversized = false; const supervisor = new ProviderProcessSupervisor( { ...spawned, ownsProcessLifetime: true, cleanup: spawned.cleanup ?? (() => cleanupOwnedProcessGroup(spawned.ownership)), }, { onDiagnostic: (event) => { if ( event.type === "output" && event.totalBytes > RECOVERY_LIMITS.reportBytes ) oversized = true; }, }, ); let failure: unknown; try { while (!(await supervisor.waitForOutputClose(100))) { checkRecoveryDeadline(context.deadline, context.signal); if (oversized) throw new AnalysisOutputError( OPERATION, "Wakaru diagnostic stream exceeds 8 MiB", ); if (context.staging !== undefined) await inventoryRecoveryFiles(context.staging, context.signal); } checkRecoveryDeadline(context.deadline, context.signal); if (oversized) throw new AnalysisOutputError( OPERATION, "Wakaru diagnostic stream exceeds 8 MiB", ); } catch (cause: unknown) { failure = cause; } const stopped = await supervisor.stop(); const snapshot = supervisor.snapshot(); supervisor.dispose(); if (stopped.status === "incomplete") throw new ProviderCleanupError("wakaru", [runId, context.cwd], { reason: stopped.reason, previous_error: failure instanceof Error ? failure.message : null, exit_code: snapshot.exitCode ?? null, signal: snapshot.signal ?? null, }); if (failure !== undefined) throw failure; if (context.signal?.aborted === true) throw new AnalysisCancelledError(OPERATION); return { exit_code: snapshot.exitCode ?? null, signal: snapshot.signal ?? null, stdout: snapshot.stdout.text, stderr: snapshot.stderr.text, command: context.command, arguments: [...context.arguments], resource_limiter: context.limiter, }; };