@earendil-works/pi-agent-core 0.79.8 → 0.79.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"nodejs.d.ts","sourceRoot":"","sources":["../../../src/harness/env/nodejs.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { constants, createReadStream } from \"node:fs\";\nimport {\n\taccess,\n\tappendFile,\n\tlstat,\n\tmkdir,\n\tmkdtemp,\n\treaddir,\n\treadFile,\n\trealpath,\n\trm,\n\twriteFile,\n} from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport { createInterface } from \"node:readline\";\nimport {\n\ttype ExecutionEnv,\n\tExecutionError,\n\terr,\n\tFileError,\n\ttype FileInfo,\n\ttype FileKind,\n\tok,\n\ttype Result,\n\ttoError,\n} from \"../types.ts\";\n\nfunction resolvePath(cwd: string, path: string): string {\n\treturn isAbsolute(path) ? path : resolve(cwd, path);\n}\n\nfunction fileKindFromStats(stats: {\n\tisFile(): boolean;\n\tisDirectory(): boolean;\n\tisSymbolicLink(): boolean;\n}): FileKind | undefined {\n\tif (stats.isFile()) return \"file\";\n\tif (stats.isDirectory()) return \"directory\";\n\tif (stats.isSymbolicLink()) return \"symlink\";\n\treturn undefined;\n}\n\nfunction fileInfoFromStats(\n\tpath: string,\n\tstats: { isFile(): boolean; isDirectory(): boolean; isSymbolicLink(): boolean; size: number; mtimeMs: number },\n): Result<FileInfo, FileError> {\n\tconst kind = fileKindFromStats(stats);\n\tif (!kind) return err(new FileError(\"invalid\", \"Unsupported file type\", path));\n\treturn ok({\n\t\tname: path.replace(/\\/+$/, \"\").split(\"/\").pop() ?? path,\n\t\tpath,\n\t\tkind,\n\t\tsize: stats.size,\n\t\tmtimeMs: stats.mtimeMs,\n\t});\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n\nfunction toFileError(error: unknown, path?: string): FileError {\n\tif (error instanceof FileError) return error;\n\tconst cause = toError(error);\n\tif (isNodeError(error)) {\n\t\tconst message = error.message;\n\t\tswitch (error.code) {\n\t\t\tcase \"ABORT_ERR\":\n\t\t\t\treturn new FileError(\"aborted\", message, path, cause);\n\t\t\tcase \"ENOENT\":\n\t\t\t\treturn new FileError(\"not_found\", message, path, cause);\n\t\t\tcase \"EACCES\":\n\t\t\tcase \"EPERM\":\n\t\t\t\treturn new FileError(\"permission_denied\", message, path, cause);\n\t\t\tcase \"ENOTDIR\":\n\t\t\t\treturn new FileError(\"not_directory\", message, path, cause);\n\t\t\tcase \"EISDIR\":\n\t\t\t\treturn new FileError(\"is_directory\", message, path, cause);\n\t\t\tcase \"EINVAL\":\n\t\t\t\treturn new FileError(\"invalid\", message, path, cause);\n\t\t}\n\t}\n\treturn new FileError(\"unknown\", cause.message, path, cause);\n}\n\nfunction abortResult<TValue>(signal: AbortSignal | undefined, path?: string): Result<TValue, FileError> | undefined {\n\treturn signal?.aborted ? err(new FileError(\"aborted\", \"aborted\", path)) : undefined;\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path, constants.F_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function runCommand(\n\tcommand: string,\n\targs: string[],\n\ttimeoutMs: number,\n): Promise<{ stdout: string; status: number | null }> {\n\treturn await new Promise((resolve) => {\n\t\tlet stdout = \"\";\n\t\tlet child: ReturnType<typeof spawn>;\n\t\ttry {\n\t\t\tchild = spawn(command, args, {\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t} catch {\n\t\t\tresolve({ stdout: \"\", status: null });\n\t\t\treturn;\n\t\t}\n\t\tconst timeout = setTimeout(() => {\n\t\t\tif (child.pid) killProcessTree(child.pid);\n\t\t}, timeoutMs);\n\t\tchild.stdout?.setEncoding(\"utf8\");\n\t\tchild.stdout?.on(\"data\", (chunk: string) => {\n\t\t\tstdout += chunk;\n\t\t});\n\t\tchild.on(\"error\", () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tresolve({ stdout: \"\", status: null });\n\t\t});\n\t\tchild.on(\"close\", (status) => {\n\t\t\tclearTimeout(timeout);\n\t\t\tresolve({ stdout, status });\n\t\t});\n\t});\n}\n\nasync function findBashOnPath(): Promise<string | null> {\n\tconst result =\n\t\tprocess.platform === \"win32\"\n\t\t\t? await runCommand(\"where\", [\"bash.exe\"], 5000)\n\t\t\t: await runCommand(\"which\", [\"bash\"], 5000);\n\tif (result.status !== 0 || !result.stdout) return null;\n\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\treturn firstMatch && (await pathExists(firstMatch)) ? firstMatch : null;\n}\n\nasync function getShellConfig(\n\tcustomShellPath?: string,\n): Promise<Result<{ shell: string; args: string[] }, ExecutionError>> {\n\tif (customShellPath) {\n\t\tif (await pathExists(customShellPath)) {\n\t\t\treturn ok({ shell: customShellPath, args: [\"-c\"] });\n\t\t}\n\t\treturn err(new ExecutionError(\"shell_unavailable\", `Custom shell path not found: ${customShellPath}`));\n\t}\n\tif (process.platform === \"win32\") {\n\t\tconst candidates: string[] = [];\n\t\tconst programFiles = process.env.ProgramFiles;\n\t\tif (programFiles) candidates.push(`${programFiles}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tconst programFilesX86 = process.env[\"ProgramFiles(x86)\"];\n\t\tif (programFilesX86) candidates.push(`${programFilesX86}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tfor (const candidate of candidates) {\n\t\t\tif (await pathExists(candidate)) {\n\t\t\t\treturn ok({ shell: candidate, args: [\"-c\"] });\n\t\t\t}\n\t\t}\n\t\tconst bashOnPath = await findBashOnPath();\n\t\tif (bashOnPath) {\n\t\t\treturn ok({ shell: bashOnPath, args: [\"-c\"] });\n\t\t}\n\t\treturn err(new ExecutionError(\"shell_unavailable\", \"No bash shell found\"));\n\t}\n\n\tif (await pathExists(\"/bin/bash\")) {\n\t\treturn ok({ shell: \"/bin/bash\", args: [\"-c\"] });\n\t}\n\tconst bashOnPath = await findBashOnPath();\n\tif (bashOnPath) {\n\t\treturn ok({ shell: bashOnPath, args: [\"-c\"] });\n\t}\n\treturn ok({ shell: \"sh\", args: [\"-c\"] });\n}\n\nfunction getShellEnv(baseEnv?: NodeJS.ProcessEnv, extraEnv?: Record<string, string>): NodeJS.ProcessEnv {\n\treturn {\n\t\t...process.env,\n\t\t...baseEnv,\n\t\t...extraEnv,\n\t};\n}\n\nfunction killProcessTree(pid: number): void {\n\tif (process.platform === \"win32\") {\n\t\ttry {\n\t\t\tspawn(\"taskkill\", [\"/F\", \"/T\", \"/PID\", String(pid)], {\n\t\t\t\tstdio: \"ignore\",\n\t\t\t\tdetached: true,\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Ignore errors.\n\t\t}\n\t\treturn;\n\t}\n\n\ttry {\n\t\tprocess.kill(-pid, \"SIGKILL\");\n\t} catch {\n\t\ttry {\n\t\t\tprocess.kill(pid, \"SIGKILL\");\n\t\t} catch {\n\t\t\t// Process already dead.\n\t\t}\n\t}\n}\n\nexport class NodeExecutionEnv implements ExecutionEnv {\n\tcwd: string;\n\tprivate shellPath?: string;\n\tprivate shellEnv?: NodeJS.ProcessEnv;\n\n\tconstructor(options: { cwd: string; shellPath?: string; shellEnv?: NodeJS.ProcessEnv }) {\n\t\tthis.cwd = options.cwd;\n\t\tthis.shellPath = options.shellPath;\n\t\tthis.shellEnv = options.shellEnv;\n\t}\n\n\tasync absolutePath(path: string): Promise<Result<string, FileError>> {\n\t\treturn ok(resolvePath(this.cwd, path));\n\t}\n\n\tasync joinPath(parts: string[]): Promise<Result<string, FileError>> {\n\t\treturn ok(join(...parts));\n\t}\n\n\tasync exec(\n\t\tcommand: string,\n\t\toptions?: {\n\t\t\tcwd?: string;\n\t\t\tenv?: Record<string, string>;\n\t\t\ttimeout?: number;\n\t\t\tabortSignal?: AbortSignal;\n\t\t\tonStdout?: (chunk: string) => void;\n\t\t\tonStderr?: (chunk: string) => void;\n\t\t},\n\t): Promise<Result<{ stdout: string; stderr: string; exitCode: number }, ExecutionError>> {\n\t\tif (options?.abortSignal?.aborted) return err(new ExecutionError(\"aborted\", \"aborted\"));\n\n\t\tconst cwd = options?.cwd ? resolvePath(this.cwd, options.cwd) : this.cwd;\n\t\tconst shellConfig = await getShellConfig(this.shellPath);\n\t\tif (!shellConfig.ok) return shellConfig;\n\n\t\treturn await new Promise((resolvePromise) => {\n\t\t\tlet stdout = \"\";\n\t\t\tlet stderr = \"\";\n\t\t\tlet settled = false;\n\t\t\tlet timedOut = false;\n\t\t\tlet callbackError: ExecutionError | undefined;\n\t\t\tlet child: ReturnType<typeof spawn> | undefined;\n\t\t\tlet timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n\t\t\tconst onAbort = () => {\n\t\t\t\tif (child?.pid) {\n\t\t\t\t\tkillProcessTree(child.pid);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst settle = (result: Result<{ stdout: string; stderr: string; exitCode: number }, ExecutionError>) => {\n\t\t\t\tif (timeoutId) clearTimeout(timeoutId);\n\t\t\t\tif (options?.abortSignal) options.abortSignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tresolvePromise(result);\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\tchild = spawn(shellConfig.value.shell, [...shellConfig.value.args, command], {\n\t\t\t\t\tcwd,\n\t\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\t\tenv: getShellEnv(this.shellEnv, options?.env),\n\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\t\twindowsHide: true,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconst cause = toError(error);\n\t\t\t\tsettle(err(new ExecutionError(\"spawn_error\", cause.message, cause)));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttimeoutId =\n\t\t\t\ttypeof options?.timeout === \"number\"\n\t\t\t\t\t? setTimeout(() => {\n\t\t\t\t\t\t\ttimedOut = true;\n\t\t\t\t\t\t\tif (child?.pid) {\n\t\t\t\t\t\t\t\tkillProcessTree(child.pid);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, options.timeout * 1000)\n\t\t\t\t\t: undefined;\n\n\t\t\tif (options?.abortSignal) {\n\t\t\t\tif (options.abortSignal.aborted) {\n\t\t\t\t\tonAbort();\n\t\t\t\t} else {\n\t\t\t\t\toptions.abortSignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tchild.stdout?.setEncoding(\"utf8\");\n\t\t\tchild.stderr?.setEncoding(\"utf8\");\n\t\t\tchild.stdout?.on(\"data\", (chunk: string) => {\n\t\t\t\tstdout += chunk;\n\t\t\t\ttry {\n\t\t\t\t\toptions?.onStdout?.(chunk);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst cause = toError(error);\n\t\t\t\t\tcallbackError = new ExecutionError(\"callback_error\", cause.message, cause);\n\t\t\t\t\tonAbort();\n\t\t\t\t}\n\t\t\t});\n\t\t\tchild.stderr?.on(\"data\", (chunk: string) => {\n\t\t\t\tstderr += chunk;\n\t\t\t\ttry {\n\t\t\t\t\toptions?.onStderr?.(chunk);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst cause = toError(error);\n\t\t\t\t\tcallbackError = new ExecutionError(\"callback_error\", cause.message, cause);\n\t\t\t\t\tonAbort();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\tsettle(err(new ExecutionError(\"spawn_error\", error.message, error)));\n\t\t\t});\n\n\t\t\tchild.on(\"close\", (code) => {\n\t\t\t\tif (callbackError) {\n\t\t\t\t\tsettle(err(callbackError));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (timedOut) {\n\t\t\t\t\tsettle(err(new ExecutionError(\"timeout\", `timeout:${options?.timeout}`)));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (options?.abortSignal?.aborted) {\n\t\t\t\t\tsettle(err(new ExecutionError(\"aborted\", \"aborted\")));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettle(ok({ stdout, stderr, exitCode: code ?? 0 }));\n\t\t\t});\n\t\t});\n\t}\n\n\tasync readTextFile(path: string, abortSignal?: AbortSignal): Promise<Result<string, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<string>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\treturn ok(await readFile(resolved, { encoding: \"utf8\", signal: abortSignal }));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync readTextLines(\n\t\tpath: string,\n\t\toptions?: { maxLines?: number; abortSignal?: AbortSignal },\n\t): Promise<Result<string[], FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<string[]>(options?.abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\tif (options?.maxLines !== undefined && options.maxLines <= 0) return ok([]);\n\t\tlet stream: ReturnType<typeof createReadStream> | undefined;\n\t\tlet lineReader: ReturnType<typeof createInterface> | undefined;\n\t\ttry {\n\t\t\tstream = createReadStream(resolved, { encoding: \"utf8\", signal: options?.abortSignal });\n\t\t\tlineReader = createInterface({ input: stream, crlfDelay: Infinity });\n\t\t\tconst lines: string[] = [];\n\t\t\tfor await (const line of lineReader) {\n\t\t\t\tconst loopAbort = abortResult<string[]>(options?.abortSignal, resolved);\n\t\t\t\tif (loopAbort) return loopAbort;\n\t\t\t\tlines.push(line);\n\t\t\t\tif (options?.maxLines !== undefined && lines.length >= options.maxLines) break;\n\t\t\t}\n\t\t\tconst afterReadAbort = abortResult<string[]>(options?.abortSignal, resolved);\n\t\t\tif (afterReadAbort) return afterReadAbort;\n\t\t\treturn ok(lines);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t} finally {\n\t\t\tlineReader?.close();\n\t\t\tstream?.destroy();\n\t\t}\n\t}\n\n\tasync readBinaryFile(path: string, abortSignal?: AbortSignal): Promise<Result<Uint8Array, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<Uint8Array>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\treturn ok(await readFile(resolved, { signal: abortSignal }));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync writeFile(\n\t\tpath: string,\n\t\tcontent: string | Uint8Array,\n\t\tabortSignal?: AbortSignal,\n\t): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<void>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\tawait mkdir(resolve(resolved, \"..\"), { recursive: true });\n\t\t\tconst afterMkdirAbort = abortResult<void>(abortSignal, resolved);\n\t\t\tif (afterMkdirAbort) return afterMkdirAbort;\n\t\t\tawait writeFile(resolved, content, { signal: abortSignal });\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync appendFile(path: string, content: string | Uint8Array): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\tawait mkdir(resolve(resolved, \"..\"), { recursive: true });\n\t\t\tawait appendFile(resolved, content);\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync fileInfo(path: string): Promise<Result<FileInfo, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\treturn fileInfoFromStats(resolved, await lstat(resolved));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync listDir(path: string, abortSignal?: AbortSignal): Promise<Result<FileInfo[], FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<FileInfo[]>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\tconst entries = await readdir(resolved, { withFileTypes: true });\n\t\t\tconst infos: FileInfo[] = [];\n\t\t\tfor (const entry of entries) {\n\t\t\t\tconst loopAbort = abortResult<FileInfo[]>(abortSignal, resolved);\n\t\t\t\tif (loopAbort) return loopAbort;\n\t\t\t\tconst entryPath = resolve(resolved, entry.name);\n\t\t\t\ttry {\n\t\t\t\t\tconst info = fileInfoFromStats(entryPath, await lstat(entryPath));\n\t\t\t\t\tif (info.ok) infos.push(info.value);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn err(toFileError(error, entryPath));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ok(infos);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync canonicalPath(path: string): Promise<Result<string, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\treturn ok(await realpath(resolved));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync exists(path: string): Promise<Result<boolean, FileError>> {\n\t\tconst result = await this.fileInfo(path);\n\t\tif (result.ok) return ok(true);\n\t\tif (result.error.code === \"not_found\") return ok(false);\n\t\treturn err(result.error);\n\t}\n\n\tasync createDir(path: string, options?: { recursive?: boolean }): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\tawait mkdir(resolved, { recursive: options?.recursive ?? true });\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync remove(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\tawait rm(resolved, { recursive: options?.recursive ?? false, force: options?.force ?? false });\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync createTempDir(prefix: string = \"tmp-\"): Promise<Result<string, FileError>> {\n\t\ttry {\n\t\t\treturn ok(await mkdtemp(join(tmpdir(), prefix)));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error));\n\t\t}\n\t}\n\n\tasync createTempFile(options?: { prefix?: string; suffix?: string }): Promise<Result<string, FileError>> {\n\t\tconst dir = await this.createTempDir(\"tmp-\");\n\t\tif (!dir.ok) return dir;\n\t\tconst filePath = join(dir.value, `${options?.prefix ?? \"\"}${randomUUID()}${options?.suffix ?? \"\"}`);\n\t\ttry {\n\t\t\tawait writeFile(filePath, \"\");\n\t\t\treturn ok(filePath);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, filePath));\n\t\t}\n\t}\n\n\tasync cleanup(): Promise<void> {\n\t\t// nothing to clean up for the local node implementation\n\t}\n}\n"]}
1
+ {"version":3,"file":"nodejs.d.ts","sourceRoot":"","sources":["../../../src/harness/env/nodejs.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { constants, createReadStream } from \"node:fs\";\nimport {\n\taccess,\n\tappendFile,\n\tlstat,\n\tmkdir,\n\tmkdtemp,\n\treaddir,\n\treadFile,\n\trealpath,\n\trm,\n\twriteFile,\n} from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport { createInterface } from \"node:readline\";\nimport {\n\ttype ExecutionEnv,\n\tExecutionError,\n\terr,\n\tFileError,\n\ttype FileInfo,\n\ttype FileKind,\n\tok,\n\ttype Result,\n\ttoError,\n} from \"../types.ts\";\n\nfunction resolvePath(cwd: string, path: string): string {\n\treturn isAbsolute(path) ? path : resolve(cwd, path);\n}\n\nfunction fileKindFromStats(stats: {\n\tisFile(): boolean;\n\tisDirectory(): boolean;\n\tisSymbolicLink(): boolean;\n}): FileKind | undefined {\n\tif (stats.isFile()) return \"file\";\n\tif (stats.isDirectory()) return \"directory\";\n\tif (stats.isSymbolicLink()) return \"symlink\";\n\treturn undefined;\n}\n\nfunction fileInfoFromStats(\n\tpath: string,\n\tstats: { isFile(): boolean; isDirectory(): boolean; isSymbolicLink(): boolean; size: number; mtimeMs: number },\n): Result<FileInfo, FileError> {\n\tconst kind = fileKindFromStats(stats);\n\tif (!kind) return err(new FileError(\"invalid\", \"Unsupported file type\", path));\n\treturn ok({\n\t\tname: path.replace(/\\/+$/, \"\").split(\"/\").pop() ?? path,\n\t\tpath,\n\t\tkind,\n\t\tsize: stats.size,\n\t\tmtimeMs: stats.mtimeMs,\n\t});\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n\nfunction toFileError(error: unknown, path?: string): FileError {\n\tif (error instanceof FileError) return error;\n\tconst cause = toError(error);\n\tif (isNodeError(error)) {\n\t\tconst message = error.message;\n\t\tswitch (error.code) {\n\t\t\tcase \"ABORT_ERR\":\n\t\t\t\treturn new FileError(\"aborted\", message, path, cause);\n\t\t\tcase \"ENOENT\":\n\t\t\t\treturn new FileError(\"not_found\", message, path, cause);\n\t\t\tcase \"EACCES\":\n\t\t\tcase \"EPERM\":\n\t\t\t\treturn new FileError(\"permission_denied\", message, path, cause);\n\t\t\tcase \"ENOTDIR\":\n\t\t\t\treturn new FileError(\"not_directory\", message, path, cause);\n\t\t\tcase \"EISDIR\":\n\t\t\t\treturn new FileError(\"is_directory\", message, path, cause);\n\t\t\tcase \"EINVAL\":\n\t\t\t\treturn new FileError(\"invalid\", message, path, cause);\n\t\t}\n\t}\n\treturn new FileError(\"unknown\", cause.message, path, cause);\n}\n\nfunction abortResult<TValue>(signal: AbortSignal | undefined, path?: string): Result<TValue, FileError> | undefined {\n\treturn signal?.aborted ? err(new FileError(\"aborted\", \"aborted\", path)) : undefined;\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path, constants.F_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function runCommand(\n\tcommand: string,\n\targs: string[],\n\ttimeoutMs: number,\n): Promise<{ stdout: string; status: number | null }> {\n\treturn await new Promise((resolve) => {\n\t\tlet stdout = \"\";\n\t\tlet child: ReturnType<typeof spawn>;\n\t\ttry {\n\t\t\tchild = spawn(command, args, {\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t} catch {\n\t\t\tresolve({ stdout: \"\", status: null });\n\t\t\treturn;\n\t\t}\n\t\tconst timeout = setTimeout(() => {\n\t\t\tif (child.pid) killProcessTree(child.pid);\n\t\t}, timeoutMs);\n\t\tchild.stdout?.setEncoding(\"utf8\");\n\t\tchild.stdout?.on(\"data\", (chunk: string) => {\n\t\t\tstdout += chunk;\n\t\t});\n\t\tchild.on(\"error\", () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tresolve({ stdout: \"\", status: null });\n\t\t});\n\t\tchild.on(\"close\", (status) => {\n\t\t\tclearTimeout(timeout);\n\t\t\tresolve({ stdout, status });\n\t\t});\n\t});\n}\n\nasync function findBashOnPath(): Promise<string | null> {\n\tconst result =\n\t\tprocess.platform === \"win32\"\n\t\t\t? await runCommand(\"where\", [\"bash.exe\"], 5000)\n\t\t\t: await runCommand(\"which\", [\"bash\"], 5000);\n\tif (result.status !== 0 || !result.stdout) return null;\n\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\treturn firstMatch && (await pathExists(firstMatch)) ? firstMatch : null;\n}\n\ninterface ShellConfig {\n\tshell: string;\n\targs: string[];\n\tcommandTransport?: \"argv\" | \"stdin\";\n}\n\nfunction isLegacyWslBashPath(path: string): boolean {\n\tconst normalized = path.replace(/\\//g, \"\\\\\").toLowerCase();\n\treturn /^[a-z]:\\\\windows\\\\(?:system32|sysnative)\\\\bash\\.exe$/.test(normalized);\n}\n\nfunction getBashShellConfig(shell: string): ShellConfig {\n\treturn isLegacyWslBashPath(shell) ? { shell, args: [\"-s\"], commandTransport: \"stdin\" } : { shell, args: [\"-c\"] };\n}\n\nasync function getShellConfig(customShellPath?: string): Promise<Result<ShellConfig, ExecutionError>> {\n\tif (customShellPath) {\n\t\tif (await pathExists(customShellPath)) {\n\t\t\treturn ok(getBashShellConfig(customShellPath));\n\t\t}\n\t\treturn err(new ExecutionError(\"shell_unavailable\", `Custom shell path not found: ${customShellPath}`));\n\t}\n\tif (process.platform === \"win32\") {\n\t\tconst candidates: string[] = [];\n\t\tconst programFiles = process.env.ProgramFiles;\n\t\tif (programFiles) candidates.push(`${programFiles}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tconst programFilesX86 = process.env[\"ProgramFiles(x86)\"];\n\t\tif (programFilesX86) candidates.push(`${programFilesX86}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tfor (const candidate of candidates) {\n\t\t\tif (await pathExists(candidate)) {\n\t\t\t\treturn ok(getBashShellConfig(candidate));\n\t\t\t}\n\t\t}\n\t\tconst bashOnPath = await findBashOnPath();\n\t\tif (bashOnPath) {\n\t\t\treturn ok(getBashShellConfig(bashOnPath));\n\t\t}\n\t\treturn err(new ExecutionError(\"shell_unavailable\", \"No bash shell found\"));\n\t}\n\n\tif (await pathExists(\"/bin/bash\")) {\n\t\treturn ok(getBashShellConfig(\"/bin/bash\"));\n\t}\n\tconst bashOnPath = await findBashOnPath();\n\tif (bashOnPath) {\n\t\treturn ok(getBashShellConfig(bashOnPath));\n\t}\n\treturn ok({ shell: \"sh\", args: [\"-c\"] });\n}\n\nfunction getShellEnv(baseEnv?: NodeJS.ProcessEnv, extraEnv?: Record<string, string>): NodeJS.ProcessEnv {\n\treturn {\n\t\t...process.env,\n\t\t...baseEnv,\n\t\t...extraEnv,\n\t};\n}\n\nfunction killProcessTree(pid: number): void {\n\tif (process.platform === \"win32\") {\n\t\ttry {\n\t\t\tspawn(\"taskkill\", [\"/F\", \"/T\", \"/PID\", String(pid)], {\n\t\t\t\tstdio: \"ignore\",\n\t\t\t\tdetached: true,\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Ignore errors.\n\t\t}\n\t\treturn;\n\t}\n\n\ttry {\n\t\tprocess.kill(-pid, \"SIGKILL\");\n\t} catch {\n\t\ttry {\n\t\t\tprocess.kill(pid, \"SIGKILL\");\n\t\t} catch {\n\t\t\t// Process already dead.\n\t\t}\n\t}\n}\n\nexport class NodeExecutionEnv implements ExecutionEnv {\n\tcwd: string;\n\tprivate shellPath?: string;\n\tprivate shellEnv?: NodeJS.ProcessEnv;\n\n\tconstructor(options: { cwd: string; shellPath?: string; shellEnv?: NodeJS.ProcessEnv }) {\n\t\tthis.cwd = options.cwd;\n\t\tthis.shellPath = options.shellPath;\n\t\tthis.shellEnv = options.shellEnv;\n\t}\n\n\tasync absolutePath(path: string): Promise<Result<string, FileError>> {\n\t\treturn ok(resolvePath(this.cwd, path));\n\t}\n\n\tasync joinPath(parts: string[]): Promise<Result<string, FileError>> {\n\t\treturn ok(join(...parts));\n\t}\n\n\tasync exec(\n\t\tcommand: string,\n\t\toptions?: {\n\t\t\tcwd?: string;\n\t\t\tenv?: Record<string, string>;\n\t\t\ttimeout?: number;\n\t\t\tabortSignal?: AbortSignal;\n\t\t\tonStdout?: (chunk: string) => void;\n\t\t\tonStderr?: (chunk: string) => void;\n\t\t},\n\t): Promise<Result<{ stdout: string; stderr: string; exitCode: number }, ExecutionError>> {\n\t\tif (options?.abortSignal?.aborted) return err(new ExecutionError(\"aborted\", \"aborted\"));\n\n\t\tconst cwd = options?.cwd ? resolvePath(this.cwd, options.cwd) : this.cwd;\n\t\tconst shellConfig = await getShellConfig(this.shellPath);\n\t\tif (!shellConfig.ok) return shellConfig;\n\n\t\treturn await new Promise((resolvePromise) => {\n\t\t\tlet stdout = \"\";\n\t\t\tlet stderr = \"\";\n\t\t\tlet settled = false;\n\t\t\tlet timedOut = false;\n\t\t\tlet callbackError: ExecutionError | undefined;\n\t\t\tlet child: ReturnType<typeof spawn> | undefined;\n\t\t\tlet timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n\t\t\tconst onAbort = () => {\n\t\t\t\tif (child?.pid) {\n\t\t\t\t\tkillProcessTree(child.pid);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst settle = (result: Result<{ stdout: string; stderr: string; exitCode: number }, ExecutionError>) => {\n\t\t\t\tif (timeoutId) clearTimeout(timeoutId);\n\t\t\t\tif (options?.abortSignal) options.abortSignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tresolvePromise(result);\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\tconst commandFromStdin = shellConfig.value.commandTransport === \"stdin\";\n\t\t\t\tchild = spawn(\n\t\t\t\t\tshellConfig.value.shell,\n\t\t\t\t\tcommandFromStdin ? shellConfig.value.args : [...shellConfig.value.args, command],\n\t\t\t\t\t{\n\t\t\t\t\t\tcwd,\n\t\t\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\t\t\tenv: getShellEnv(this.shellEnv, options?.env),\n\t\t\t\t\t\tstdio: [commandFromStdin ? \"pipe\" : \"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\t\t\twindowsHide: true,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tif (commandFromStdin) {\n\t\t\t\t\tchild.stdin?.on(\"error\", () => {});\n\t\t\t\t\tchild.stdin?.end(command);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconst cause = toError(error);\n\t\t\t\tsettle(err(new ExecutionError(\"spawn_error\", cause.message, cause)));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttimeoutId =\n\t\t\t\ttypeof options?.timeout === \"number\"\n\t\t\t\t\t? setTimeout(() => {\n\t\t\t\t\t\t\ttimedOut = true;\n\t\t\t\t\t\t\tif (child?.pid) {\n\t\t\t\t\t\t\t\tkillProcessTree(child.pid);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, options.timeout * 1000)\n\t\t\t\t\t: undefined;\n\n\t\t\tif (options?.abortSignal) {\n\t\t\t\tif (options.abortSignal.aborted) {\n\t\t\t\t\tonAbort();\n\t\t\t\t} else {\n\t\t\t\t\toptions.abortSignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tchild.stdout?.setEncoding(\"utf8\");\n\t\t\tchild.stderr?.setEncoding(\"utf8\");\n\t\t\tchild.stdout?.on(\"data\", (chunk: string) => {\n\t\t\t\tstdout += chunk;\n\t\t\t\ttry {\n\t\t\t\t\toptions?.onStdout?.(chunk);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst cause = toError(error);\n\t\t\t\t\tcallbackError = new ExecutionError(\"callback_error\", cause.message, cause);\n\t\t\t\t\tonAbort();\n\t\t\t\t}\n\t\t\t});\n\t\t\tchild.stderr?.on(\"data\", (chunk: string) => {\n\t\t\t\tstderr += chunk;\n\t\t\t\ttry {\n\t\t\t\t\toptions?.onStderr?.(chunk);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst cause = toError(error);\n\t\t\t\t\tcallbackError = new ExecutionError(\"callback_error\", cause.message, cause);\n\t\t\t\t\tonAbort();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\tsettle(err(new ExecutionError(\"spawn_error\", error.message, error)));\n\t\t\t});\n\n\t\t\tchild.on(\"close\", (code) => {\n\t\t\t\tif (callbackError) {\n\t\t\t\t\tsettle(err(callbackError));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (timedOut) {\n\t\t\t\t\tsettle(err(new ExecutionError(\"timeout\", `timeout:${options?.timeout}`)));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (options?.abortSignal?.aborted) {\n\t\t\t\t\tsettle(err(new ExecutionError(\"aborted\", \"aborted\")));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettle(ok({ stdout, stderr, exitCode: code ?? 0 }));\n\t\t\t});\n\t\t});\n\t}\n\n\tasync readTextFile(path: string, abortSignal?: AbortSignal): Promise<Result<string, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<string>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\treturn ok(await readFile(resolved, { encoding: \"utf8\", signal: abortSignal }));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync readTextLines(\n\t\tpath: string,\n\t\toptions?: { maxLines?: number; abortSignal?: AbortSignal },\n\t): Promise<Result<string[], FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<string[]>(options?.abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\tif (options?.maxLines !== undefined && options.maxLines <= 0) return ok([]);\n\t\tlet stream: ReturnType<typeof createReadStream> | undefined;\n\t\tlet lineReader: ReturnType<typeof createInterface> | undefined;\n\t\ttry {\n\t\t\tstream = createReadStream(resolved, { encoding: \"utf8\", signal: options?.abortSignal });\n\t\t\tlineReader = createInterface({ input: stream, crlfDelay: Infinity });\n\t\t\tconst lines: string[] = [];\n\t\t\tfor await (const line of lineReader) {\n\t\t\t\tconst loopAbort = abortResult<string[]>(options?.abortSignal, resolved);\n\t\t\t\tif (loopAbort) return loopAbort;\n\t\t\t\tlines.push(line);\n\t\t\t\tif (options?.maxLines !== undefined && lines.length >= options.maxLines) break;\n\t\t\t}\n\t\t\tconst afterReadAbort = abortResult<string[]>(options?.abortSignal, resolved);\n\t\t\tif (afterReadAbort) return afterReadAbort;\n\t\t\treturn ok(lines);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t} finally {\n\t\t\tlineReader?.close();\n\t\t\tstream?.destroy();\n\t\t}\n\t}\n\n\tasync readBinaryFile(path: string, abortSignal?: AbortSignal): Promise<Result<Uint8Array, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<Uint8Array>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\treturn ok(await readFile(resolved, { signal: abortSignal }));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync writeFile(\n\t\tpath: string,\n\t\tcontent: string | Uint8Array,\n\t\tabortSignal?: AbortSignal,\n\t): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<void>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\tawait mkdir(resolve(resolved, \"..\"), { recursive: true });\n\t\t\tconst afterMkdirAbort = abortResult<void>(abortSignal, resolved);\n\t\t\tif (afterMkdirAbort) return afterMkdirAbort;\n\t\t\tawait writeFile(resolved, content, { signal: abortSignal });\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync appendFile(path: string, content: string | Uint8Array): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\tawait mkdir(resolve(resolved, \"..\"), { recursive: true });\n\t\t\tawait appendFile(resolved, content);\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync fileInfo(path: string): Promise<Result<FileInfo, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\treturn fileInfoFromStats(resolved, await lstat(resolved));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync listDir(path: string, abortSignal?: AbortSignal): Promise<Result<FileInfo[], FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<FileInfo[]>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\tconst entries = await readdir(resolved, { withFileTypes: true });\n\t\t\tconst infos: FileInfo[] = [];\n\t\t\tfor (const entry of entries) {\n\t\t\t\tconst loopAbort = abortResult<FileInfo[]>(abortSignal, resolved);\n\t\t\t\tif (loopAbort) return loopAbort;\n\t\t\t\tconst entryPath = resolve(resolved, entry.name);\n\t\t\t\ttry {\n\t\t\t\t\tconst info = fileInfoFromStats(entryPath, await lstat(entryPath));\n\t\t\t\t\tif (info.ok) infos.push(info.value);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn err(toFileError(error, entryPath));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ok(infos);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync canonicalPath(path: string): Promise<Result<string, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\treturn ok(await realpath(resolved));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync exists(path: string): Promise<Result<boolean, FileError>> {\n\t\tconst result = await this.fileInfo(path);\n\t\tif (result.ok) return ok(true);\n\t\tif (result.error.code === \"not_found\") return ok(false);\n\t\treturn err(result.error);\n\t}\n\n\tasync createDir(path: string, options?: { recursive?: boolean }): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\tawait mkdir(resolved, { recursive: options?.recursive ?? true });\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync remove(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\tawait rm(resolved, { recursive: options?.recursive ?? false, force: options?.force ?? false });\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync createTempDir(prefix: string = \"tmp-\"): Promise<Result<string, FileError>> {\n\t\ttry {\n\t\t\treturn ok(await mkdtemp(join(tmpdir(), prefix)));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error));\n\t\t}\n\t}\n\n\tasync createTempFile(options?: { prefix?: string; suffix?: string }): Promise<Result<string, FileError>> {\n\t\tconst dir = await this.createTempDir(\"tmp-\");\n\t\tif (!dir.ok) return dir;\n\t\tconst filePath = join(dir.value, `${options?.prefix ?? \"\"}${randomUUID()}${options?.suffix ?? \"\"}`);\n\t\ttry {\n\t\t\tawait writeFile(filePath, \"\");\n\t\t\treturn ok(filePath);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, filePath));\n\t\t}\n\t}\n\n\tasync cleanup(): Promise<void> {\n\t\t// nothing to clean up for the local node implementation\n\t}\n}\n"]}
@@ -110,10 +110,17 @@ async function findBashOnPath() {
110
110
  const firstMatch = result.stdout.trim().split(/\r?\n/)[0];
111
111
  return firstMatch && (await pathExists(firstMatch)) ? firstMatch : null;
112
112
  }
113
+ function isLegacyWslBashPath(path) {
114
+ const normalized = path.replace(/\//g, "\\").toLowerCase();
115
+ return /^[a-z]:\\windows\\(?:system32|sysnative)\\bash\.exe$/.test(normalized);
116
+ }
117
+ function getBashShellConfig(shell) {
118
+ return isLegacyWslBashPath(shell) ? { shell, args: ["-s"], commandTransport: "stdin" } : { shell, args: ["-c"] };
119
+ }
113
120
  async function getShellConfig(customShellPath) {
114
121
  if (customShellPath) {
115
122
  if (await pathExists(customShellPath)) {
116
- return ok({ shell: customShellPath, args: ["-c"] });
123
+ return ok(getBashShellConfig(customShellPath));
117
124
  }
118
125
  return err(new ExecutionError("shell_unavailable", `Custom shell path not found: ${customShellPath}`));
119
126
  }
@@ -127,21 +134,21 @@ async function getShellConfig(customShellPath) {
127
134
  candidates.push(`${programFilesX86}\\Git\\bin\\bash.exe`);
128
135
  for (const candidate of candidates) {
129
136
  if (await pathExists(candidate)) {
130
- return ok({ shell: candidate, args: ["-c"] });
137
+ return ok(getBashShellConfig(candidate));
131
138
  }
132
139
  }
133
140
  const bashOnPath = await findBashOnPath();
134
141
  if (bashOnPath) {
135
- return ok({ shell: bashOnPath, args: ["-c"] });
142
+ return ok(getBashShellConfig(bashOnPath));
136
143
  }
137
144
  return err(new ExecutionError("shell_unavailable", "No bash shell found"));
138
145
  }
139
146
  if (await pathExists("/bin/bash")) {
140
- return ok({ shell: "/bin/bash", args: ["-c"] });
147
+ return ok(getBashShellConfig("/bin/bash"));
141
148
  }
142
149
  const bashOnPath = await findBashOnPath();
143
150
  if (bashOnPath) {
144
- return ok({ shell: bashOnPath, args: ["-c"] });
151
+ return ok(getBashShellConfig(bashOnPath));
145
152
  }
146
153
  return ok({ shell: "sh", args: ["-c"] });
147
154
  }
@@ -224,13 +231,18 @@ export class NodeExecutionEnv {
224
231
  resolvePromise(result);
225
232
  };
226
233
  try {
227
- child = spawn(shellConfig.value.shell, [...shellConfig.value.args, command], {
234
+ const commandFromStdin = shellConfig.value.commandTransport === "stdin";
235
+ child = spawn(shellConfig.value.shell, commandFromStdin ? shellConfig.value.args : [...shellConfig.value.args, command], {
228
236
  cwd,
229
237
  detached: process.platform !== "win32",
230
238
  env: getShellEnv(this.shellEnv, options?.env),
231
- stdio: ["ignore", "pipe", "pipe"],
239
+ stdio: [commandFromStdin ? "pipe" : "ignore", "pipe", "pipe"],
232
240
  windowsHide: true,
233
241
  });
242
+ if (commandFromStdin) {
243
+ child.stdin?.on("error", () => { });
244
+ child.stdin?.end(command);
245
+ }
234
246
  }
235
247
  catch (error) {
236
248
  const cause = toError(error);
@@ -1 +1 @@
1
- {"version":3,"file":"nodejs.js","sourceRoot":"","sources":["../../../src/harness/env/nodejs.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { constants, createReadStream } from \"node:fs\";\nimport {\n\taccess,\n\tappendFile,\n\tlstat,\n\tmkdir,\n\tmkdtemp,\n\treaddir,\n\treadFile,\n\trealpath,\n\trm,\n\twriteFile,\n} from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport { createInterface } from \"node:readline\";\nimport {\n\ttype ExecutionEnv,\n\tExecutionError,\n\terr,\n\tFileError,\n\ttype FileInfo,\n\ttype FileKind,\n\tok,\n\ttype Result,\n\ttoError,\n} from \"../types.ts\";\n\nfunction resolvePath(cwd: string, path: string): string {\n\treturn isAbsolute(path) ? path : resolve(cwd, path);\n}\n\nfunction fileKindFromStats(stats: {\n\tisFile(): boolean;\n\tisDirectory(): boolean;\n\tisSymbolicLink(): boolean;\n}): FileKind | undefined {\n\tif (stats.isFile()) return \"file\";\n\tif (stats.isDirectory()) return \"directory\";\n\tif (stats.isSymbolicLink()) return \"symlink\";\n\treturn undefined;\n}\n\nfunction fileInfoFromStats(\n\tpath: string,\n\tstats: { isFile(): boolean; isDirectory(): boolean; isSymbolicLink(): boolean; size: number; mtimeMs: number },\n): Result<FileInfo, FileError> {\n\tconst kind = fileKindFromStats(stats);\n\tif (!kind) return err(new FileError(\"invalid\", \"Unsupported file type\", path));\n\treturn ok({\n\t\tname: path.replace(/\\/+$/, \"\").split(\"/\").pop() ?? path,\n\t\tpath,\n\t\tkind,\n\t\tsize: stats.size,\n\t\tmtimeMs: stats.mtimeMs,\n\t});\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n\nfunction toFileError(error: unknown, path?: string): FileError {\n\tif (error instanceof FileError) return error;\n\tconst cause = toError(error);\n\tif (isNodeError(error)) {\n\t\tconst message = error.message;\n\t\tswitch (error.code) {\n\t\t\tcase \"ABORT_ERR\":\n\t\t\t\treturn new FileError(\"aborted\", message, path, cause);\n\t\t\tcase \"ENOENT\":\n\t\t\t\treturn new FileError(\"not_found\", message, path, cause);\n\t\t\tcase \"EACCES\":\n\t\t\tcase \"EPERM\":\n\t\t\t\treturn new FileError(\"permission_denied\", message, path, cause);\n\t\t\tcase \"ENOTDIR\":\n\t\t\t\treturn new FileError(\"not_directory\", message, path, cause);\n\t\t\tcase \"EISDIR\":\n\t\t\t\treturn new FileError(\"is_directory\", message, path, cause);\n\t\t\tcase \"EINVAL\":\n\t\t\t\treturn new FileError(\"invalid\", message, path, cause);\n\t\t}\n\t}\n\treturn new FileError(\"unknown\", cause.message, path, cause);\n}\n\nfunction abortResult<TValue>(signal: AbortSignal | undefined, path?: string): Result<TValue, FileError> | undefined {\n\treturn signal?.aborted ? err(new FileError(\"aborted\", \"aborted\", path)) : undefined;\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path, constants.F_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function runCommand(\n\tcommand: string,\n\targs: string[],\n\ttimeoutMs: number,\n): Promise<{ stdout: string; status: number | null }> {\n\treturn await new Promise((resolve) => {\n\t\tlet stdout = \"\";\n\t\tlet child: ReturnType<typeof spawn>;\n\t\ttry {\n\t\t\tchild = spawn(command, args, {\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t} catch {\n\t\t\tresolve({ stdout: \"\", status: null });\n\t\t\treturn;\n\t\t}\n\t\tconst timeout = setTimeout(() => {\n\t\t\tif (child.pid) killProcessTree(child.pid);\n\t\t}, timeoutMs);\n\t\tchild.stdout?.setEncoding(\"utf8\");\n\t\tchild.stdout?.on(\"data\", (chunk: string) => {\n\t\t\tstdout += chunk;\n\t\t});\n\t\tchild.on(\"error\", () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tresolve({ stdout: \"\", status: null });\n\t\t});\n\t\tchild.on(\"close\", (status) => {\n\t\t\tclearTimeout(timeout);\n\t\t\tresolve({ stdout, status });\n\t\t});\n\t});\n}\n\nasync function findBashOnPath(): Promise<string | null> {\n\tconst result =\n\t\tprocess.platform === \"win32\"\n\t\t\t? await runCommand(\"where\", [\"bash.exe\"], 5000)\n\t\t\t: await runCommand(\"which\", [\"bash\"], 5000);\n\tif (result.status !== 0 || !result.stdout) return null;\n\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\treturn firstMatch && (await pathExists(firstMatch)) ? firstMatch : null;\n}\n\nasync function getShellConfig(\n\tcustomShellPath?: string,\n): Promise<Result<{ shell: string; args: string[] }, ExecutionError>> {\n\tif (customShellPath) {\n\t\tif (await pathExists(customShellPath)) {\n\t\t\treturn ok({ shell: customShellPath, args: [\"-c\"] });\n\t\t}\n\t\treturn err(new ExecutionError(\"shell_unavailable\", `Custom shell path not found: ${customShellPath}`));\n\t}\n\tif (process.platform === \"win32\") {\n\t\tconst candidates: string[] = [];\n\t\tconst programFiles = process.env.ProgramFiles;\n\t\tif (programFiles) candidates.push(`${programFiles}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tconst programFilesX86 = process.env[\"ProgramFiles(x86)\"];\n\t\tif (programFilesX86) candidates.push(`${programFilesX86}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tfor (const candidate of candidates) {\n\t\t\tif (await pathExists(candidate)) {\n\t\t\t\treturn ok({ shell: candidate, args: [\"-c\"] });\n\t\t\t}\n\t\t}\n\t\tconst bashOnPath = await findBashOnPath();\n\t\tif (bashOnPath) {\n\t\t\treturn ok({ shell: bashOnPath, args: [\"-c\"] });\n\t\t}\n\t\treturn err(new ExecutionError(\"shell_unavailable\", \"No bash shell found\"));\n\t}\n\n\tif (await pathExists(\"/bin/bash\")) {\n\t\treturn ok({ shell: \"/bin/bash\", args: [\"-c\"] });\n\t}\n\tconst bashOnPath = await findBashOnPath();\n\tif (bashOnPath) {\n\t\treturn ok({ shell: bashOnPath, args: [\"-c\"] });\n\t}\n\treturn ok({ shell: \"sh\", args: [\"-c\"] });\n}\n\nfunction getShellEnv(baseEnv?: NodeJS.ProcessEnv, extraEnv?: Record<string, string>): NodeJS.ProcessEnv {\n\treturn {\n\t\t...process.env,\n\t\t...baseEnv,\n\t\t...extraEnv,\n\t};\n}\n\nfunction killProcessTree(pid: number): void {\n\tif (process.platform === \"win32\") {\n\t\ttry {\n\t\t\tspawn(\"taskkill\", [\"/F\", \"/T\", \"/PID\", String(pid)], {\n\t\t\t\tstdio: \"ignore\",\n\t\t\t\tdetached: true,\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Ignore errors.\n\t\t}\n\t\treturn;\n\t}\n\n\ttry {\n\t\tprocess.kill(-pid, \"SIGKILL\");\n\t} catch {\n\t\ttry {\n\t\t\tprocess.kill(pid, \"SIGKILL\");\n\t\t} catch {\n\t\t\t// Process already dead.\n\t\t}\n\t}\n}\n\nexport class NodeExecutionEnv implements ExecutionEnv {\n\tcwd: string;\n\tprivate shellPath?: string;\n\tprivate shellEnv?: NodeJS.ProcessEnv;\n\n\tconstructor(options: { cwd: string; shellPath?: string; shellEnv?: NodeJS.ProcessEnv }) {\n\t\tthis.cwd = options.cwd;\n\t\tthis.shellPath = options.shellPath;\n\t\tthis.shellEnv = options.shellEnv;\n\t}\n\n\tasync absolutePath(path: string): Promise<Result<string, FileError>> {\n\t\treturn ok(resolvePath(this.cwd, path));\n\t}\n\n\tasync joinPath(parts: string[]): Promise<Result<string, FileError>> {\n\t\treturn ok(join(...parts));\n\t}\n\n\tasync exec(\n\t\tcommand: string,\n\t\toptions?: {\n\t\t\tcwd?: string;\n\t\t\tenv?: Record<string, string>;\n\t\t\ttimeout?: number;\n\t\t\tabortSignal?: AbortSignal;\n\t\t\tonStdout?: (chunk: string) => void;\n\t\t\tonStderr?: (chunk: string) => void;\n\t\t},\n\t): Promise<Result<{ stdout: string; stderr: string; exitCode: number }, ExecutionError>> {\n\t\tif (options?.abortSignal?.aborted) return err(new ExecutionError(\"aborted\", \"aborted\"));\n\n\t\tconst cwd = options?.cwd ? resolvePath(this.cwd, options.cwd) : this.cwd;\n\t\tconst shellConfig = await getShellConfig(this.shellPath);\n\t\tif (!shellConfig.ok) return shellConfig;\n\n\t\treturn await new Promise((resolvePromise) => {\n\t\t\tlet stdout = \"\";\n\t\t\tlet stderr = \"\";\n\t\t\tlet settled = false;\n\t\t\tlet timedOut = false;\n\t\t\tlet callbackError: ExecutionError | undefined;\n\t\t\tlet child: ReturnType<typeof spawn> | undefined;\n\t\t\tlet timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n\t\t\tconst onAbort = () => {\n\t\t\t\tif (child?.pid) {\n\t\t\t\t\tkillProcessTree(child.pid);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst settle = (result: Result<{ stdout: string; stderr: string; exitCode: number }, ExecutionError>) => {\n\t\t\t\tif (timeoutId) clearTimeout(timeoutId);\n\t\t\t\tif (options?.abortSignal) options.abortSignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tresolvePromise(result);\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\tchild = spawn(shellConfig.value.shell, [...shellConfig.value.args, command], {\n\t\t\t\t\tcwd,\n\t\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\t\tenv: getShellEnv(this.shellEnv, options?.env),\n\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\t\twindowsHide: true,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconst cause = toError(error);\n\t\t\t\tsettle(err(new ExecutionError(\"spawn_error\", cause.message, cause)));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttimeoutId =\n\t\t\t\ttypeof options?.timeout === \"number\"\n\t\t\t\t\t? setTimeout(() => {\n\t\t\t\t\t\t\ttimedOut = true;\n\t\t\t\t\t\t\tif (child?.pid) {\n\t\t\t\t\t\t\t\tkillProcessTree(child.pid);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, options.timeout * 1000)\n\t\t\t\t\t: undefined;\n\n\t\t\tif (options?.abortSignal) {\n\t\t\t\tif (options.abortSignal.aborted) {\n\t\t\t\t\tonAbort();\n\t\t\t\t} else {\n\t\t\t\t\toptions.abortSignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tchild.stdout?.setEncoding(\"utf8\");\n\t\t\tchild.stderr?.setEncoding(\"utf8\");\n\t\t\tchild.stdout?.on(\"data\", (chunk: string) => {\n\t\t\t\tstdout += chunk;\n\t\t\t\ttry {\n\t\t\t\t\toptions?.onStdout?.(chunk);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst cause = toError(error);\n\t\t\t\t\tcallbackError = new ExecutionError(\"callback_error\", cause.message, cause);\n\t\t\t\t\tonAbort();\n\t\t\t\t}\n\t\t\t});\n\t\t\tchild.stderr?.on(\"data\", (chunk: string) => {\n\t\t\t\tstderr += chunk;\n\t\t\t\ttry {\n\t\t\t\t\toptions?.onStderr?.(chunk);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst cause = toError(error);\n\t\t\t\t\tcallbackError = new ExecutionError(\"callback_error\", cause.message, cause);\n\t\t\t\t\tonAbort();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\tsettle(err(new ExecutionError(\"spawn_error\", error.message, error)));\n\t\t\t});\n\n\t\t\tchild.on(\"close\", (code) => {\n\t\t\t\tif (callbackError) {\n\t\t\t\t\tsettle(err(callbackError));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (timedOut) {\n\t\t\t\t\tsettle(err(new ExecutionError(\"timeout\", `timeout:${options?.timeout}`)));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (options?.abortSignal?.aborted) {\n\t\t\t\t\tsettle(err(new ExecutionError(\"aborted\", \"aborted\")));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettle(ok({ stdout, stderr, exitCode: code ?? 0 }));\n\t\t\t});\n\t\t});\n\t}\n\n\tasync readTextFile(path: string, abortSignal?: AbortSignal): Promise<Result<string, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<string>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\treturn ok(await readFile(resolved, { encoding: \"utf8\", signal: abortSignal }));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync readTextLines(\n\t\tpath: string,\n\t\toptions?: { maxLines?: number; abortSignal?: AbortSignal },\n\t): Promise<Result<string[], FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<string[]>(options?.abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\tif (options?.maxLines !== undefined && options.maxLines <= 0) return ok([]);\n\t\tlet stream: ReturnType<typeof createReadStream> | undefined;\n\t\tlet lineReader: ReturnType<typeof createInterface> | undefined;\n\t\ttry {\n\t\t\tstream = createReadStream(resolved, { encoding: \"utf8\", signal: options?.abortSignal });\n\t\t\tlineReader = createInterface({ input: stream, crlfDelay: Infinity });\n\t\t\tconst lines: string[] = [];\n\t\t\tfor await (const line of lineReader) {\n\t\t\t\tconst loopAbort = abortResult<string[]>(options?.abortSignal, resolved);\n\t\t\t\tif (loopAbort) return loopAbort;\n\t\t\t\tlines.push(line);\n\t\t\t\tif (options?.maxLines !== undefined && lines.length >= options.maxLines) break;\n\t\t\t}\n\t\t\tconst afterReadAbort = abortResult<string[]>(options?.abortSignal, resolved);\n\t\t\tif (afterReadAbort) return afterReadAbort;\n\t\t\treturn ok(lines);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t} finally {\n\t\t\tlineReader?.close();\n\t\t\tstream?.destroy();\n\t\t}\n\t}\n\n\tasync readBinaryFile(path: string, abortSignal?: AbortSignal): Promise<Result<Uint8Array, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<Uint8Array>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\treturn ok(await readFile(resolved, { signal: abortSignal }));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync writeFile(\n\t\tpath: string,\n\t\tcontent: string | Uint8Array,\n\t\tabortSignal?: AbortSignal,\n\t): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<void>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\tawait mkdir(resolve(resolved, \"..\"), { recursive: true });\n\t\t\tconst afterMkdirAbort = abortResult<void>(abortSignal, resolved);\n\t\t\tif (afterMkdirAbort) return afterMkdirAbort;\n\t\t\tawait writeFile(resolved, content, { signal: abortSignal });\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync appendFile(path: string, content: string | Uint8Array): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\tawait mkdir(resolve(resolved, \"..\"), { recursive: true });\n\t\t\tawait appendFile(resolved, content);\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync fileInfo(path: string): Promise<Result<FileInfo, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\treturn fileInfoFromStats(resolved, await lstat(resolved));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync listDir(path: string, abortSignal?: AbortSignal): Promise<Result<FileInfo[], FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<FileInfo[]>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\tconst entries = await readdir(resolved, { withFileTypes: true });\n\t\t\tconst infos: FileInfo[] = [];\n\t\t\tfor (const entry of entries) {\n\t\t\t\tconst loopAbort = abortResult<FileInfo[]>(abortSignal, resolved);\n\t\t\t\tif (loopAbort) return loopAbort;\n\t\t\t\tconst entryPath = resolve(resolved, entry.name);\n\t\t\t\ttry {\n\t\t\t\t\tconst info = fileInfoFromStats(entryPath, await lstat(entryPath));\n\t\t\t\t\tif (info.ok) infos.push(info.value);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn err(toFileError(error, entryPath));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ok(infos);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync canonicalPath(path: string): Promise<Result<string, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\treturn ok(await realpath(resolved));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync exists(path: string): Promise<Result<boolean, FileError>> {\n\t\tconst result = await this.fileInfo(path);\n\t\tif (result.ok) return ok(true);\n\t\tif (result.error.code === \"not_found\") return ok(false);\n\t\treturn err(result.error);\n\t}\n\n\tasync createDir(path: string, options?: { recursive?: boolean }): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\tawait mkdir(resolved, { recursive: options?.recursive ?? true });\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync remove(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\tawait rm(resolved, { recursive: options?.recursive ?? false, force: options?.force ?? false });\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync createTempDir(prefix: string = \"tmp-\"): Promise<Result<string, FileError>> {\n\t\ttry {\n\t\t\treturn ok(await mkdtemp(join(tmpdir(), prefix)));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error));\n\t\t}\n\t}\n\n\tasync createTempFile(options?: { prefix?: string; suffix?: string }): Promise<Result<string, FileError>> {\n\t\tconst dir = await this.createTempDir(\"tmp-\");\n\t\tif (!dir.ok) return dir;\n\t\tconst filePath = join(dir.value, `${options?.prefix ?? \"\"}${randomUUID()}${options?.suffix ?? \"\"}`);\n\t\ttry {\n\t\t\tawait writeFile(filePath, \"\");\n\t\t\treturn ok(filePath);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, filePath));\n\t\t}\n\t}\n\n\tasync cleanup(): Promise<void> {\n\t\t// nothing to clean up for the local node implementation\n\t}\n}\n"]}
1
+ {"version":3,"file":"nodejs.js","sourceRoot":"","sources":["../../../src/harness/env/nodejs.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { constants, createReadStream } from \"node:fs\";\nimport {\n\taccess,\n\tappendFile,\n\tlstat,\n\tmkdir,\n\tmkdtemp,\n\treaddir,\n\treadFile,\n\trealpath,\n\trm,\n\twriteFile,\n} from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport { createInterface } from \"node:readline\";\nimport {\n\ttype ExecutionEnv,\n\tExecutionError,\n\terr,\n\tFileError,\n\ttype FileInfo,\n\ttype FileKind,\n\tok,\n\ttype Result,\n\ttoError,\n} from \"../types.ts\";\n\nfunction resolvePath(cwd: string, path: string): string {\n\treturn isAbsolute(path) ? path : resolve(cwd, path);\n}\n\nfunction fileKindFromStats(stats: {\n\tisFile(): boolean;\n\tisDirectory(): boolean;\n\tisSymbolicLink(): boolean;\n}): FileKind | undefined {\n\tif (stats.isFile()) return \"file\";\n\tif (stats.isDirectory()) return \"directory\";\n\tif (stats.isSymbolicLink()) return \"symlink\";\n\treturn undefined;\n}\n\nfunction fileInfoFromStats(\n\tpath: string,\n\tstats: { isFile(): boolean; isDirectory(): boolean; isSymbolicLink(): boolean; size: number; mtimeMs: number },\n): Result<FileInfo, FileError> {\n\tconst kind = fileKindFromStats(stats);\n\tif (!kind) return err(new FileError(\"invalid\", \"Unsupported file type\", path));\n\treturn ok({\n\t\tname: path.replace(/\\/+$/, \"\").split(\"/\").pop() ?? path,\n\t\tpath,\n\t\tkind,\n\t\tsize: stats.size,\n\t\tmtimeMs: stats.mtimeMs,\n\t});\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n\nfunction toFileError(error: unknown, path?: string): FileError {\n\tif (error instanceof FileError) return error;\n\tconst cause = toError(error);\n\tif (isNodeError(error)) {\n\t\tconst message = error.message;\n\t\tswitch (error.code) {\n\t\t\tcase \"ABORT_ERR\":\n\t\t\t\treturn new FileError(\"aborted\", message, path, cause);\n\t\t\tcase \"ENOENT\":\n\t\t\t\treturn new FileError(\"not_found\", message, path, cause);\n\t\t\tcase \"EACCES\":\n\t\t\tcase \"EPERM\":\n\t\t\t\treturn new FileError(\"permission_denied\", message, path, cause);\n\t\t\tcase \"ENOTDIR\":\n\t\t\t\treturn new FileError(\"not_directory\", message, path, cause);\n\t\t\tcase \"EISDIR\":\n\t\t\t\treturn new FileError(\"is_directory\", message, path, cause);\n\t\t\tcase \"EINVAL\":\n\t\t\t\treturn new FileError(\"invalid\", message, path, cause);\n\t\t}\n\t}\n\treturn new FileError(\"unknown\", cause.message, path, cause);\n}\n\nfunction abortResult<TValue>(signal: AbortSignal | undefined, path?: string): Result<TValue, FileError> | undefined {\n\treturn signal?.aborted ? err(new FileError(\"aborted\", \"aborted\", path)) : undefined;\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path, constants.F_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function runCommand(\n\tcommand: string,\n\targs: string[],\n\ttimeoutMs: number,\n): Promise<{ stdout: string; status: number | null }> {\n\treturn await new Promise((resolve) => {\n\t\tlet stdout = \"\";\n\t\tlet child: ReturnType<typeof spawn>;\n\t\ttry {\n\t\t\tchild = spawn(command, args, {\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t} catch {\n\t\t\tresolve({ stdout: \"\", status: null });\n\t\t\treturn;\n\t\t}\n\t\tconst timeout = setTimeout(() => {\n\t\t\tif (child.pid) killProcessTree(child.pid);\n\t\t}, timeoutMs);\n\t\tchild.stdout?.setEncoding(\"utf8\");\n\t\tchild.stdout?.on(\"data\", (chunk: string) => {\n\t\t\tstdout += chunk;\n\t\t});\n\t\tchild.on(\"error\", () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tresolve({ stdout: \"\", status: null });\n\t\t});\n\t\tchild.on(\"close\", (status) => {\n\t\t\tclearTimeout(timeout);\n\t\t\tresolve({ stdout, status });\n\t\t});\n\t});\n}\n\nasync function findBashOnPath(): Promise<string | null> {\n\tconst result =\n\t\tprocess.platform === \"win32\"\n\t\t\t? await runCommand(\"where\", [\"bash.exe\"], 5000)\n\t\t\t: await runCommand(\"which\", [\"bash\"], 5000);\n\tif (result.status !== 0 || !result.stdout) return null;\n\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\treturn firstMatch && (await pathExists(firstMatch)) ? firstMatch : null;\n}\n\ninterface ShellConfig {\n\tshell: string;\n\targs: string[];\n\tcommandTransport?: \"argv\" | \"stdin\";\n}\n\nfunction isLegacyWslBashPath(path: string): boolean {\n\tconst normalized = path.replace(/\\//g, \"\\\\\").toLowerCase();\n\treturn /^[a-z]:\\\\windows\\\\(?:system32|sysnative)\\\\bash\\.exe$/.test(normalized);\n}\n\nfunction getBashShellConfig(shell: string): ShellConfig {\n\treturn isLegacyWslBashPath(shell) ? { shell, args: [\"-s\"], commandTransport: \"stdin\" } : { shell, args: [\"-c\"] };\n}\n\nasync function getShellConfig(customShellPath?: string): Promise<Result<ShellConfig, ExecutionError>> {\n\tif (customShellPath) {\n\t\tif (await pathExists(customShellPath)) {\n\t\t\treturn ok(getBashShellConfig(customShellPath));\n\t\t}\n\t\treturn err(new ExecutionError(\"shell_unavailable\", `Custom shell path not found: ${customShellPath}`));\n\t}\n\tif (process.platform === \"win32\") {\n\t\tconst candidates: string[] = [];\n\t\tconst programFiles = process.env.ProgramFiles;\n\t\tif (programFiles) candidates.push(`${programFiles}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tconst programFilesX86 = process.env[\"ProgramFiles(x86)\"];\n\t\tif (programFilesX86) candidates.push(`${programFilesX86}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tfor (const candidate of candidates) {\n\t\t\tif (await pathExists(candidate)) {\n\t\t\t\treturn ok(getBashShellConfig(candidate));\n\t\t\t}\n\t\t}\n\t\tconst bashOnPath = await findBashOnPath();\n\t\tif (bashOnPath) {\n\t\t\treturn ok(getBashShellConfig(bashOnPath));\n\t\t}\n\t\treturn err(new ExecutionError(\"shell_unavailable\", \"No bash shell found\"));\n\t}\n\n\tif (await pathExists(\"/bin/bash\")) {\n\t\treturn ok(getBashShellConfig(\"/bin/bash\"));\n\t}\n\tconst bashOnPath = await findBashOnPath();\n\tif (bashOnPath) {\n\t\treturn ok(getBashShellConfig(bashOnPath));\n\t}\n\treturn ok({ shell: \"sh\", args: [\"-c\"] });\n}\n\nfunction getShellEnv(baseEnv?: NodeJS.ProcessEnv, extraEnv?: Record<string, string>): NodeJS.ProcessEnv {\n\treturn {\n\t\t...process.env,\n\t\t...baseEnv,\n\t\t...extraEnv,\n\t};\n}\n\nfunction killProcessTree(pid: number): void {\n\tif (process.platform === \"win32\") {\n\t\ttry {\n\t\t\tspawn(\"taskkill\", [\"/F\", \"/T\", \"/PID\", String(pid)], {\n\t\t\t\tstdio: \"ignore\",\n\t\t\t\tdetached: true,\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Ignore errors.\n\t\t}\n\t\treturn;\n\t}\n\n\ttry {\n\t\tprocess.kill(-pid, \"SIGKILL\");\n\t} catch {\n\t\ttry {\n\t\t\tprocess.kill(pid, \"SIGKILL\");\n\t\t} catch {\n\t\t\t// Process already dead.\n\t\t}\n\t}\n}\n\nexport class NodeExecutionEnv implements ExecutionEnv {\n\tcwd: string;\n\tprivate shellPath?: string;\n\tprivate shellEnv?: NodeJS.ProcessEnv;\n\n\tconstructor(options: { cwd: string; shellPath?: string; shellEnv?: NodeJS.ProcessEnv }) {\n\t\tthis.cwd = options.cwd;\n\t\tthis.shellPath = options.shellPath;\n\t\tthis.shellEnv = options.shellEnv;\n\t}\n\n\tasync absolutePath(path: string): Promise<Result<string, FileError>> {\n\t\treturn ok(resolvePath(this.cwd, path));\n\t}\n\n\tasync joinPath(parts: string[]): Promise<Result<string, FileError>> {\n\t\treturn ok(join(...parts));\n\t}\n\n\tasync exec(\n\t\tcommand: string,\n\t\toptions?: {\n\t\t\tcwd?: string;\n\t\t\tenv?: Record<string, string>;\n\t\t\ttimeout?: number;\n\t\t\tabortSignal?: AbortSignal;\n\t\t\tonStdout?: (chunk: string) => void;\n\t\t\tonStderr?: (chunk: string) => void;\n\t\t},\n\t): Promise<Result<{ stdout: string; stderr: string; exitCode: number }, ExecutionError>> {\n\t\tif (options?.abortSignal?.aborted) return err(new ExecutionError(\"aborted\", \"aborted\"));\n\n\t\tconst cwd = options?.cwd ? resolvePath(this.cwd, options.cwd) : this.cwd;\n\t\tconst shellConfig = await getShellConfig(this.shellPath);\n\t\tif (!shellConfig.ok) return shellConfig;\n\n\t\treturn await new Promise((resolvePromise) => {\n\t\t\tlet stdout = \"\";\n\t\t\tlet stderr = \"\";\n\t\t\tlet settled = false;\n\t\t\tlet timedOut = false;\n\t\t\tlet callbackError: ExecutionError | undefined;\n\t\t\tlet child: ReturnType<typeof spawn> | undefined;\n\t\t\tlet timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n\t\t\tconst onAbort = () => {\n\t\t\t\tif (child?.pid) {\n\t\t\t\t\tkillProcessTree(child.pid);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst settle = (result: Result<{ stdout: string; stderr: string; exitCode: number }, ExecutionError>) => {\n\t\t\t\tif (timeoutId) clearTimeout(timeoutId);\n\t\t\t\tif (options?.abortSignal) options.abortSignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tresolvePromise(result);\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\tconst commandFromStdin = shellConfig.value.commandTransport === \"stdin\";\n\t\t\t\tchild = spawn(\n\t\t\t\t\tshellConfig.value.shell,\n\t\t\t\t\tcommandFromStdin ? shellConfig.value.args : [...shellConfig.value.args, command],\n\t\t\t\t\t{\n\t\t\t\t\t\tcwd,\n\t\t\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\t\t\tenv: getShellEnv(this.shellEnv, options?.env),\n\t\t\t\t\t\tstdio: [commandFromStdin ? \"pipe\" : \"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\t\t\twindowsHide: true,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tif (commandFromStdin) {\n\t\t\t\t\tchild.stdin?.on(\"error\", () => {});\n\t\t\t\t\tchild.stdin?.end(command);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconst cause = toError(error);\n\t\t\t\tsettle(err(new ExecutionError(\"spawn_error\", cause.message, cause)));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttimeoutId =\n\t\t\t\ttypeof options?.timeout === \"number\"\n\t\t\t\t\t? setTimeout(() => {\n\t\t\t\t\t\t\ttimedOut = true;\n\t\t\t\t\t\t\tif (child?.pid) {\n\t\t\t\t\t\t\t\tkillProcessTree(child.pid);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, options.timeout * 1000)\n\t\t\t\t\t: undefined;\n\n\t\t\tif (options?.abortSignal) {\n\t\t\t\tif (options.abortSignal.aborted) {\n\t\t\t\t\tonAbort();\n\t\t\t\t} else {\n\t\t\t\t\toptions.abortSignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tchild.stdout?.setEncoding(\"utf8\");\n\t\t\tchild.stderr?.setEncoding(\"utf8\");\n\t\t\tchild.stdout?.on(\"data\", (chunk: string) => {\n\t\t\t\tstdout += chunk;\n\t\t\t\ttry {\n\t\t\t\t\toptions?.onStdout?.(chunk);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst cause = toError(error);\n\t\t\t\t\tcallbackError = new ExecutionError(\"callback_error\", cause.message, cause);\n\t\t\t\t\tonAbort();\n\t\t\t\t}\n\t\t\t});\n\t\t\tchild.stderr?.on(\"data\", (chunk: string) => {\n\t\t\t\tstderr += chunk;\n\t\t\t\ttry {\n\t\t\t\t\toptions?.onStderr?.(chunk);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst cause = toError(error);\n\t\t\t\t\tcallbackError = new ExecutionError(\"callback_error\", cause.message, cause);\n\t\t\t\t\tonAbort();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\tsettle(err(new ExecutionError(\"spawn_error\", error.message, error)));\n\t\t\t});\n\n\t\t\tchild.on(\"close\", (code) => {\n\t\t\t\tif (callbackError) {\n\t\t\t\t\tsettle(err(callbackError));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (timedOut) {\n\t\t\t\t\tsettle(err(new ExecutionError(\"timeout\", `timeout:${options?.timeout}`)));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (options?.abortSignal?.aborted) {\n\t\t\t\t\tsettle(err(new ExecutionError(\"aborted\", \"aborted\")));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettle(ok({ stdout, stderr, exitCode: code ?? 0 }));\n\t\t\t});\n\t\t});\n\t}\n\n\tasync readTextFile(path: string, abortSignal?: AbortSignal): Promise<Result<string, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<string>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\treturn ok(await readFile(resolved, { encoding: \"utf8\", signal: abortSignal }));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync readTextLines(\n\t\tpath: string,\n\t\toptions?: { maxLines?: number; abortSignal?: AbortSignal },\n\t): Promise<Result<string[], FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<string[]>(options?.abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\tif (options?.maxLines !== undefined && options.maxLines <= 0) return ok([]);\n\t\tlet stream: ReturnType<typeof createReadStream> | undefined;\n\t\tlet lineReader: ReturnType<typeof createInterface> | undefined;\n\t\ttry {\n\t\t\tstream = createReadStream(resolved, { encoding: \"utf8\", signal: options?.abortSignal });\n\t\t\tlineReader = createInterface({ input: stream, crlfDelay: Infinity });\n\t\t\tconst lines: string[] = [];\n\t\t\tfor await (const line of lineReader) {\n\t\t\t\tconst loopAbort = abortResult<string[]>(options?.abortSignal, resolved);\n\t\t\t\tif (loopAbort) return loopAbort;\n\t\t\t\tlines.push(line);\n\t\t\t\tif (options?.maxLines !== undefined && lines.length >= options.maxLines) break;\n\t\t\t}\n\t\t\tconst afterReadAbort = abortResult<string[]>(options?.abortSignal, resolved);\n\t\t\tif (afterReadAbort) return afterReadAbort;\n\t\t\treturn ok(lines);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t} finally {\n\t\t\tlineReader?.close();\n\t\t\tstream?.destroy();\n\t\t}\n\t}\n\n\tasync readBinaryFile(path: string, abortSignal?: AbortSignal): Promise<Result<Uint8Array, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<Uint8Array>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\treturn ok(await readFile(resolved, { signal: abortSignal }));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync writeFile(\n\t\tpath: string,\n\t\tcontent: string | Uint8Array,\n\t\tabortSignal?: AbortSignal,\n\t): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<void>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\tawait mkdir(resolve(resolved, \"..\"), { recursive: true });\n\t\t\tconst afterMkdirAbort = abortResult<void>(abortSignal, resolved);\n\t\t\tif (afterMkdirAbort) return afterMkdirAbort;\n\t\t\tawait writeFile(resolved, content, { signal: abortSignal });\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync appendFile(path: string, content: string | Uint8Array): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\tawait mkdir(resolve(resolved, \"..\"), { recursive: true });\n\t\t\tawait appendFile(resolved, content);\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync fileInfo(path: string): Promise<Result<FileInfo, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\treturn fileInfoFromStats(resolved, await lstat(resolved));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync listDir(path: string, abortSignal?: AbortSignal): Promise<Result<FileInfo[], FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<FileInfo[]>(abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\tconst entries = await readdir(resolved, { withFileTypes: true });\n\t\t\tconst infos: FileInfo[] = [];\n\t\t\tfor (const entry of entries) {\n\t\t\t\tconst loopAbort = abortResult<FileInfo[]>(abortSignal, resolved);\n\t\t\t\tif (loopAbort) return loopAbort;\n\t\t\t\tconst entryPath = resolve(resolved, entry.name);\n\t\t\t\ttry {\n\t\t\t\t\tconst info = fileInfoFromStats(entryPath, await lstat(entryPath));\n\t\t\t\t\tif (info.ok) infos.push(info.value);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn err(toFileError(error, entryPath));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ok(infos);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync canonicalPath(path: string): Promise<Result<string, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\treturn ok(await realpath(resolved));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync exists(path: string): Promise<Result<boolean, FileError>> {\n\t\tconst result = await this.fileInfo(path);\n\t\tif (result.ok) return ok(true);\n\t\tif (result.error.code === \"not_found\") return ok(false);\n\t\treturn err(result.error);\n\t}\n\n\tasync createDir(path: string, options?: { recursive?: boolean }): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\tawait mkdir(resolved, { recursive: options?.recursive ?? true });\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync remove(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\ttry {\n\t\t\tawait rm(resolved, { recursive: options?.recursive ?? false, force: options?.force ?? false });\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync createTempDir(prefix: string = \"tmp-\"): Promise<Result<string, FileError>> {\n\t\ttry {\n\t\t\treturn ok(await mkdtemp(join(tmpdir(), prefix)));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error));\n\t\t}\n\t}\n\n\tasync createTempFile(options?: { prefix?: string; suffix?: string }): Promise<Result<string, FileError>> {\n\t\tconst dir = await this.createTempDir(\"tmp-\");\n\t\tif (!dir.ok) return dir;\n\t\tconst filePath = join(dir.value, `${options?.prefix ?? \"\"}${randomUUID()}${options?.suffix ?? \"\"}`);\n\t\ttry {\n\t\t\tawait writeFile(filePath, \"\");\n\t\t\treturn ok(filePath);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, filePath));\n\t\t}\n\t}\n\n\tasync cleanup(): Promise<void> {\n\t\t// nothing to clean up for the local node implementation\n\t}\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-agent-core",
3
- "version": "0.79.8",
3
+ "version": "0.79.10",
4
4
  "description": "General-purpose agent with transport abstraction, state management, and attachment support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -33,7 +33,7 @@
33
33
  "prepublishOnly": "npm run clean && npm run build"
34
34
  },
35
35
  "dependencies": {
36
- "@earendil-works/pi-ai": "^0.79.8",
36
+ "@earendil-works/pi-ai": "^0.79.10",
37
37
  "ignore": "7.0.5",
38
38
  "typebox": "1.1.38",
39
39
  "yaml": "2.9.0"