@earendil-works/pi-durable 0.87.0 → 0.99.0

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.
Files changed (177) hide show
  1. package/README.md +72 -1
  2. package/dist/documents.d.ts +66 -0
  3. package/dist/documents.d.ts.map +1 -0
  4. package/dist/documents.js +98 -0
  5. package/dist/documents.js.map +1 -0
  6. package/dist/entries.d.ts +13 -0
  7. package/dist/entries.d.ts.map +1 -0
  8. package/dist/entries.js +18 -0
  9. package/dist/entries.js.map +1 -0
  10. package/dist/env/index.d.ts +131 -0
  11. package/dist/env/index.d.ts.map +1 -0
  12. package/dist/env/index.js +45 -0
  13. package/dist/env/index.js.map +1 -0
  14. package/dist/env/node.d.ts +45 -0
  15. package/dist/env/node.d.ts.map +1 -0
  16. package/dist/env/node.js +908 -0
  17. package/dist/env/node.js.map +1 -0
  18. package/dist/env/utils/adaptive-publisher.d.ts +24 -0
  19. package/dist/env/utils/adaptive-publisher.d.ts.map +1 -0
  20. package/dist/env/utils/adaptive-publisher.js +79 -0
  21. package/dist/env/utils/adaptive-publisher.js.map +1 -0
  22. package/dist/env/utils/output-capture.d.ts +31 -0
  23. package/dist/env/utils/output-capture.d.ts.map +1 -0
  24. package/dist/env/utils/output-capture.js +238 -0
  25. package/dist/env/utils/output-capture.js.map +1 -0
  26. package/dist/env/utils/truncate.d.ts +71 -0
  27. package/dist/env/utils/truncate.d.ts.map +1 -0
  28. package/dist/env/utils/truncate.js +294 -0
  29. package/dist/env/utils/truncate.js.map +1 -0
  30. package/dist/errors.d.ts +15 -0
  31. package/dist/errors.d.ts.map +1 -0
  32. package/dist/errors.js +24 -0
  33. package/dist/errors.js.map +1 -0
  34. package/dist/harness/config.d.ts +20 -0
  35. package/dist/harness/config.d.ts.map +1 -0
  36. package/dist/harness/config.js +18 -0
  37. package/dist/harness/config.js.map +1 -0
  38. package/dist/harness/context.d.ts +27 -0
  39. package/dist/harness/context.d.ts.map +1 -0
  40. package/dist/harness/context.js +109 -0
  41. package/dist/harness/context.js.map +1 -0
  42. package/dist/harness/generation.d.ts +36 -0
  43. package/dist/harness/generation.d.ts.map +1 -0
  44. package/dist/harness/generation.js +266 -0
  45. package/dist/harness/generation.js.map +1 -0
  46. package/dist/harness/harness.d.ts +10 -0
  47. package/dist/harness/harness.d.ts.map +1 -0
  48. package/dist/harness/harness.js +266 -0
  49. package/dist/harness/harness.js.map +1 -0
  50. package/dist/harness/live.d.ts +40 -0
  51. package/dist/harness/live.d.ts.map +1 -0
  52. package/dist/harness/live.js +41 -0
  53. package/dist/harness/live.js.map +1 -0
  54. package/dist/harness/prompt.d.ts +24 -0
  55. package/dist/harness/prompt.d.ts.map +1 -0
  56. package/dist/harness/prompt.js +88 -0
  57. package/dist/harness/prompt.js.map +1 -0
  58. package/dist/harness/registry.d.ts +7 -0
  59. package/dist/harness/registry.d.ts.map +1 -0
  60. package/dist/harness/registry.js +309 -0
  61. package/dist/harness/registry.js.map +1 -0
  62. package/dist/harness/scheduler.d.ts +63 -0
  63. package/dist/harness/scheduler.d.ts.map +1 -0
  64. package/dist/harness/scheduler.js +605 -0
  65. package/dist/harness/scheduler.js.map +1 -0
  66. package/dist/harness/submissions.d.ts +24 -0
  67. package/dist/harness/submissions.d.ts.map +1 -0
  68. package/dist/harness/submissions.js +133 -0
  69. package/dist/harness/submissions.js.map +1 -0
  70. package/dist/harness/types.d.ts +358 -0
  71. package/dist/harness/types.d.ts.map +1 -0
  72. package/dist/harness/types.js +2 -0
  73. package/dist/harness/types.js.map +1 -0
  74. package/dist/harness/util.d.ts +14 -0
  75. package/dist/harness/util.d.ts.map +1 -0
  76. package/dist/harness/util.js +55 -0
  77. package/dist/harness/util.js.map +1 -0
  78. package/dist/ids.d.ts +6 -0
  79. package/dist/ids.d.ts.map +1 -0
  80. package/dist/ids.js +9 -0
  81. package/dist/ids.js.map +1 -0
  82. package/dist/index.d.ts +13 -2
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +11 -1
  85. package/dist/index.js.map +1 -1
  86. package/dist/session/forks.d.ts +10 -0
  87. package/dist/session/forks.d.ts.map +1 -0
  88. package/dist/session/forks.js +42 -0
  89. package/dist/session/forks.js.map +1 -0
  90. package/dist/session/observation.d.ts +28 -0
  91. package/dist/session/observation.d.ts.map +1 -0
  92. package/dist/session/observation.js +280 -0
  93. package/dist/session/observation.js.map +1 -0
  94. package/dist/session/session.d.ts +59 -0
  95. package/dist/session/session.d.ts.map +1 -0
  96. package/dist/session/session.js +380 -0
  97. package/dist/session/session.js.map +1 -0
  98. package/dist/session/transaction.d.ts +105 -0
  99. package/dist/session/transaction.d.ts.map +1 -0
  100. package/dist/session/transaction.js +718 -0
  101. package/dist/session/transaction.js.map +1 -0
  102. package/dist/storage/jsonl/index.d.ts +2 -0
  103. package/dist/storage/jsonl/index.d.ts.map +1 -0
  104. package/dist/storage/jsonl/index.js +2 -0
  105. package/dist/storage/jsonl/index.js.map +1 -0
  106. package/dist/storage/jsonl/node.d.ts +6 -0
  107. package/dist/storage/jsonl/node.d.ts.map +1 -0
  108. package/dist/storage/jsonl/node.js +8 -0
  109. package/dist/storage/jsonl/node.js.map +1 -0
  110. package/dist/storage/jsonl/storage.d.ts +115 -0
  111. package/dist/storage/jsonl/storage.d.ts.map +1 -0
  112. package/dist/storage/jsonl/storage.js +681 -0
  113. package/dist/storage/jsonl/storage.js.map +1 -0
  114. package/dist/storage/memory.d.ts +60 -0
  115. package/dist/storage/memory.d.ts.map +1 -0
  116. package/dist/storage/memory.js +681 -0
  117. package/dist/storage/memory.js.map +1 -0
  118. package/dist/storage/sqlite/database.d.ts +30 -0
  119. package/dist/storage/sqlite/database.d.ts.map +1 -0
  120. package/dist/storage/sqlite/database.js +2 -0
  121. package/dist/storage/sqlite/database.js.map +1 -0
  122. package/dist/storage/sqlite/index.d.ts +4 -0
  123. package/dist/storage/sqlite/index.d.ts.map +1 -0
  124. package/dist/storage/sqlite/index.js +3 -0
  125. package/dist/storage/sqlite/index.js.map +1 -0
  126. package/dist/storage/sqlite/migrations.d.ts +11 -0
  127. package/dist/storage/sqlite/migrations.d.ts.map +1 -0
  128. package/dist/storage/sqlite/migrations.js +111 -0
  129. package/dist/storage/sqlite/migrations.js.map +1 -0
  130. package/dist/storage/sqlite/node.d.ts +25 -0
  131. package/dist/storage/sqlite/node.d.ts.map +1 -0
  132. package/dist/storage/sqlite/node.js +97 -0
  133. package/dist/storage/sqlite/node.js.map +1 -0
  134. package/dist/storage/sqlite/storage.d.ts +51 -0
  135. package/dist/storage/sqlite/storage.d.ts.map +1 -0
  136. package/dist/storage/sqlite/storage.js +628 -0
  137. package/dist/storage/sqlite/storage.js.map +1 -0
  138. package/dist/tasks.d.ts +6 -0
  139. package/dist/tasks.d.ts.map +1 -0
  140. package/dist/tasks.js +5 -0
  141. package/dist/tasks.js.map +1 -0
  142. package/dist/testing/assertions.d.ts +5 -0
  143. package/dist/testing/assertions.d.ts.map +1 -0
  144. package/dist/testing/assertions.js +25 -0
  145. package/dist/testing/assertions.js.map +1 -0
  146. package/dist/testing/index.d.ts +6 -0
  147. package/dist/testing/index.d.ts.map +1 -0
  148. package/dist/testing/index.js +5 -0
  149. package/dist/testing/index.js.map +1 -0
  150. package/dist/testing/runner.d.ts +10 -0
  151. package/dist/testing/runner.d.ts.map +1 -0
  152. package/dist/testing/runner.js +14 -0
  153. package/dist/testing/runner.js.map +1 -0
  154. package/dist/testing/storage-benchmark.d.ts +41 -0
  155. package/dist/testing/storage-benchmark.d.ts.map +1 -0
  156. package/dist/testing/storage-benchmark.js +351 -0
  157. package/dist/testing/storage-benchmark.js.map +1 -0
  158. package/dist/testing/storage-conformance.d.ts +4 -0
  159. package/dist/testing/storage-conformance.d.ts.map +1 -0
  160. package/dist/testing/storage-conformance.js +1122 -0
  161. package/dist/testing/storage-conformance.js.map +1 -0
  162. package/dist/testing/types.d.ts +19 -0
  163. package/dist/testing/types.d.ts.map +1 -0
  164. package/dist/testing/types.js +2 -0
  165. package/dist/testing/types.js.map +1 -0
  166. package/dist/types.d.ts +525 -78
  167. package/dist/types.d.ts.map +1 -1
  168. package/dist/types.js.map +1 -1
  169. package/docs/chord-delta-findings.md +1 -1
  170. package/docs/pico-v5-chord-usage.md +90 -102
  171. package/docs/pico-v5-handoff.md +493 -253
  172. package/docs/pico-v5.md +1901 -848
  173. package/package.json +47 -5
  174. package/dist/memory-storage.d.ts +0 -37
  175. package/dist/memory-storage.d.ts.map +0 -1
  176. package/dist/memory-storage.js +0 -322
  177. package/dist/memory-storage.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/env/node.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ChildProcess, spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { constants, createWriteStream, type WriteStream } from \"node:fs\";\nimport {\n\taccess,\n\tappendFile,\n\tlstat,\n\tmkdir,\n\tmkdtemp,\n\topen as openFile,\n\treaddir,\n\treadFile,\n\trealpath,\n\trename,\n\trm,\n\twriteFile,\n} from \"node:fs/promises\";\nimport { homedir, constants as osConstants, tmpdir } from \"node:os\";\nimport { basename, isAbsolute, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { Context } from \"@earendil-works/chord\";\nimport {\n\ttype ExecutionEnv,\n\tExecutionError,\n\terr,\n\tFileError,\n\ttype FileInfo,\n\ttype FileKind,\n\tok,\n\ttype Result,\n\ttype ShellExecOptions,\n\ttype ShellExecResult,\n\ttype TextLine,\n\ttype TextLineReader,\n\ttoError,\n} from \"./index.ts\";\nimport { OutputCapture } from \"./utils/output-capture.ts\";\n\nconst MAX_TIMEOUT_MS = 2_147_483_647;\nconst MAX_TIMEOUT_SECONDS = MAX_TIMEOUT_MS / 1000;\nconst EXIT_STDIO_GRACE_MS = 100;\nconst SPILL_HIGH_WATER_MARK = 8 * 1024 * 1024;\n\ntype SpillChunk = string | Uint8Array;\n\nfunction resolveTimeoutMs(timeout: number | undefined): Result<number | undefined, ExecutionError> {\n\tif (timeout === undefined) return ok(undefined);\n\tif (!Number.isFinite(timeout) || timeout <= 0) {\n\t\treturn err(new ExecutionError(\"timeout\", \"Invalid timeout: must be a finite number of seconds\"));\n\t}\n\n\tconst timeoutMs = timeout * 1000;\n\tif (timeoutMs > MAX_TIMEOUT_MS) {\n\t\treturn err(new ExecutionError(\"timeout\", `Invalid timeout: maximum is ${MAX_TIMEOUT_SECONDS} seconds`));\n\t}\n\treturn ok(timeoutMs);\n}\n\nfunction resolvePath(cwd: string, path: string): string {\n\tlet normalized = path;\n\tif (normalized === \"~\") {\n\t\tnormalized = homedir();\n\t} else if (normalized.startsWith(\"~/\") || (process.platform === \"win32\" && normalized.startsWith(\"~\\\\\"))) {\n\t\tnormalized = join(homedir(), normalized.slice(2));\n\t} else if (normalized.startsWith(\"file://\")) {\n\t\ttry {\n\t\t\tnormalized = fileURLToPath(normalized);\n\t\t} catch {\n\t\t\t// Keep malformed URLs as ordinary paths so filesystem methods preserve their non-throwing contract.\n\t\t}\n\t}\n\treturn isAbsolute(normalized) ? resolve(normalized) : resolve(cwd, normalized);\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: basename(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, fallbackPath?: string): FileError {\n\tif (error instanceof FileError) return error;\n\tconst cause = toError(error);\n\tconst nodeError = isNodeError(error) ? error : undefined;\n\tconst path = typeof nodeError?.path === \"string\" ? nodeError.path : fallbackPath;\n\tif (nodeError) {\n\t\tconst message = nodeError.message;\n\t\tswitch (nodeError.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(\n\t\t\tnew ExecutionError(\n\t\t\t\t\"shell_unavailable\",\n\t\t\t\t`No bash shell found. Options:\\n` +\n\t\t\t\t\t` 1. Install Git for Windows: https://git-scm.com/download/win\\n` +\n\t\t\t\t\t` 2. Add your bash to PATH (Cygwin, MSYS2, etc.)\\n` +\n\t\t\t\t\t\" 3. Configure an explicit shellPath\\n\\n\" +\n\t\t\t\t\t`Searched Git Bash in:\\n${candidates.map((path) => ` ${path}`).join(\"\\n\")}`,\n\t\t\t),\n\t\t);\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(\n\tbaseEnv?: NodeJS.ProcessEnv,\n\textraEnv?: Record<string, string>,\n\tinheritEnv = true,\n): NodeJS.ProcessEnv {\n\tif (!inheritEnv) return { ...extraEnv };\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\tconst child = spawn(\n\t\t\t\tjoin(process.env.SystemRoot ?? \"C:\\\\Windows\", \"System32\", \"taskkill.exe\"),\n\t\t\t\t[\"/F\", \"/T\", \"/PID\", String(pid)],\n\t\t\t\t{\n\t\t\t\t\tstdio: \"ignore\",\n\t\t\t\t\tdetached: true,\n\t\t\t\t\twindowsHide: true,\n\t\t\t\t},\n\t\t\t);\n\t\t\t// A failed spawn emits \"error\" asynchronously; consume it to avoid crashing Node.\n\t\t\tchild.once(\"error\", () => {});\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\nfunction waitForChildProcess(\n\tchild: ChildProcess,\n\tspillIsDraining: () => boolean,\n): Promise<{ code: number | null; signal: NodeJS.Signals | null }> {\n\treturn new Promise((resolvePromise, reject) => {\n\t\tlet settled = false;\n\t\tlet exited = false;\n\t\tlet exitCode: number | null = null;\n\t\tlet exitSignal: NodeJS.Signals | null = null;\n\t\tlet postExitTimer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet stdoutEnded = child.stdout === null;\n\t\tlet stderrEnded = child.stderr === null;\n\n\t\tconst cleanup = (): void => {\n\t\t\tif (postExitTimer) clearTimeout(postExitTimer);\n\t\t\tchild.removeListener(\"error\", onError);\n\t\t\tchild.removeListener(\"exit\", onExit);\n\t\t\tchild.removeListener(\"close\", onClose);\n\t\t\tchild.stdout?.removeListener(\"end\", onStdoutEnd);\n\t\t\tchild.stderr?.removeListener(\"end\", onStderrEnd);\n\t\t\tchild.stdout?.removeListener(\"data\", onData);\n\t\t\tchild.stderr?.removeListener(\"data\", onData);\n\t\t};\n\t\tconst finalize = (): void => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tcleanup();\n\t\t\tchild.stdout?.destroy();\n\t\t\tchild.stderr?.destroy();\n\t\t\tresolvePromise({ code: exitCode, signal: exitSignal });\n\t\t};\n\t\tconst maybeFinalizeAfterExit = (): void => {\n\t\t\tif (exited && stdoutEnded && stderrEnded) finalize();\n\t\t};\n\t\tconst armIdleTimer = (): void => {\n\t\t\tif (postExitTimer) clearTimeout(postExitTimer);\n\t\t\tpostExitTimer = setTimeout(() => {\n\t\t\t\tif (spillIsDraining()) armIdleTimer();\n\t\t\t\telse finalize();\n\t\t\t}, EXIT_STDIO_GRACE_MS);\n\t\t};\n\t\tconst onData = (): void => {\n\t\t\tif (exited && !settled) armIdleTimer();\n\t\t};\n\t\tconst onStdoutEnd = (): void => {\n\t\t\tstdoutEnded = true;\n\t\t\tmaybeFinalizeAfterExit();\n\t\t};\n\t\tconst onStderrEnd = (): void => {\n\t\t\tstderrEnded = true;\n\t\t\tmaybeFinalizeAfterExit();\n\t\t};\n\t\tconst onError = (error: Error): void => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tcleanup();\n\t\t\treject(error);\n\t\t};\n\t\tconst onExit = (code: number | null, signal: NodeJS.Signals | null): void => {\n\t\t\texited = true;\n\t\t\texitCode = code;\n\t\t\texitSignal = signal;\n\t\t\tmaybeFinalizeAfterExit();\n\t\t\tif (!settled) armIdleTimer();\n\t\t};\n\t\tconst onClose = (code: number | null, signal: NodeJS.Signals | null): void => {\n\t\t\texitCode = code;\n\t\t\texitSignal = signal;\n\t\t\tfinalize();\n\t\t};\n\n\t\tchild.stdout?.once(\"end\", onStdoutEnd);\n\t\tchild.stderr?.once(\"end\", onStderrEnd);\n\t\tchild.stdout?.on(\"data\", onData);\n\t\tchild.stderr?.on(\"data\", onData);\n\t\tchild.once(\"error\", onError);\n\t\tchild.once(\"exit\", onExit);\n\t\tchild.once(\"close\", onClose);\n\t});\n}\n\n/** Strict LF reader; Node readline does not report whether its final line was newline-terminated. */\nclass NodeTextLineReader implements TextLineReader {\n\tprivate readonly file: Awaited<ReturnType<typeof openFile>>;\n\tprivate readonly path: string;\n\tprivate readonly decoder = new TextDecoder();\n\tprivate readonly chunk = new Uint8Array(64 * 1024);\n\tprivate byteOffset = 0;\n\tprivate buffered = \"\";\n\tprivate ended = false;\n\tprivate closed = false;\n\n\tconstructor(file: Awaited<ReturnType<typeof openFile>>, path: string) {\n\t\tthis.file = file;\n\t\tthis.path = path;\n\t}\n\n\tasync readLine(context: Context): Promise<Result<TextLine | undefined, FileError>> {\n\t\tconst aborted = abortResult<TextLine | undefined>(context.abortSignal, this.path);\n\t\tif (aborted) return aborted;\n\t\tif (this.closed) return err(new FileError(\"invalid\", \"Text line reader is closed\", this.path));\n\n\t\ttry {\n\t\t\twhile (true) {\n\t\t\t\tconst newline = this.buffered.indexOf(\"\\n\");\n\t\t\t\tif (newline !== -1) {\n\t\t\t\t\tconst text = this.buffered.slice(0, newline);\n\t\t\t\t\tthis.buffered = this.buffered.slice(newline + 1);\n\t\t\t\t\treturn ok({ text, terminated: true });\n\t\t\t\t}\n\t\t\t\tif (this.ended) {\n\t\t\t\t\tif (this.buffered.length === 0) return ok(undefined);\n\t\t\t\t\tconst text = this.buffered;\n\t\t\t\t\tthis.buffered = \"\";\n\t\t\t\t\treturn ok({ text, terminated: false });\n\t\t\t\t}\n\n\t\t\t\t// Explicit positions allow an aborted read to be retried without skipping bytes.\n\t\t\t\tconst { bytesRead } = await this.file.read(this.chunk, 0, this.chunk.length, this.byteOffset);\n\t\t\t\tconst afterReadAbort = abortResult<TextLine | undefined>(context.abortSignal, this.path);\n\t\t\t\tif (afterReadAbort) return afterReadAbort;\n\t\t\t\tthis.byteOffset += bytesRead;\n\t\t\t\tif (bytesRead === 0) {\n\t\t\t\t\tthis.buffered += this.decoder.decode();\n\t\t\t\t\tthis.ended = true;\n\t\t\t\t} else {\n\t\t\t\t\tthis.buffered += this.decoder.decode(this.chunk.subarray(0, bytesRead), { stream: true });\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, this.path));\n\t\t}\n\t}\n\n\tasync close(_context: Context): Promise<void> {\n\t\tif (this.closed) return;\n\t\tthis.closed = true;\n\t\tthis.buffered = \"\";\n\t\ttry {\n\t\t\tawait this.file.close();\n\t\t} catch {\n\t\t\t// Closing is best-effort, including after cancellation or an earlier I/O failure.\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\tprivate activeChildPids = new Set<number>();\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, _context: Context): Promise<Result<string, FileError>> {\n\t\treturn ok(resolvePath(this.cwd, path));\n\t}\n\n\tasync joinPath(parts: string[], _context: Context): Promise<Result<string, FileError>> {\n\t\treturn ok(join(...parts));\n\t}\n\n\tasync exec(\n\t\tcommand: string,\n\t\toptions: ShellExecOptions | undefined,\n\t\tcontext: Context,\n\t): Promise<Result<ShellExecResult, ExecutionError>> {\n\t\tconst signal = context.abortSignal;\n\t\tif (signal?.aborted) return err(new ExecutionError(\"aborted\", \"aborted\"));\n\t\tconst timeoutMsResult = resolveTimeoutMs(options?.timeout);\n\t\tif (!timeoutMsResult.ok) return err(timeoutMsResult.error);\n\t\tconst timeoutMs = timeoutMsResult.value;\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\t\ttry {\n\t\t\tawait access(cwd, constants.F_OK);\n\t\t} catch (error) {\n\t\t\tconst cause = toError(error);\n\t\t\treturn err(\n\t\t\t\tnew ExecutionError(\n\t\t\t\t\t\"spawn_error\",\n\t\t\t\t\t`Working directory does not exist: ${cwd}\\nCannot execute bash commands.`,\n\t\t\t\t\tcause,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\treturn await new Promise((resolvePromise) => {\n\t\t\tlet settled = false;\n\t\t\tlet timedOut = false;\n\t\t\tlet callbackError: ExecutionError | undefined;\n\t\t\tlet spillError: ExecutionError | undefined;\n\t\t\tlet child: ReturnType<typeof spawn> | undefined;\n\t\t\tlet timeoutId: ReturnType<typeof setTimeout> | undefined;\n\t\t\tconst spillPrefix: SpillChunk[] = [];\n\t\t\tlet spillPath: string | undefined;\n\t\t\tconst spillQueue: SpillChunk[] = [];\n\t\t\tlet spillStart: Promise<void> | undefined;\n\t\t\tlet spillStream: WriteStream | undefined;\n\t\t\tlet spillBackpressured = false;\n\n\t\t\tconst onAbort = () => {\n\t\t\t\tif (child?.pid) killProcessTree(child.pid);\n\t\t\t};\n\t\t\tconst failCallback = (error: unknown) => {\n\t\t\t\tif (callbackError !== undefined) return;\n\t\t\t\tconst cause = toError(error);\n\t\t\t\tcallbackError = new ExecutionError(\"callback_error\", cause.message, cause);\n\t\t\t\tonAbort();\n\t\t\t};\n\t\t\tlet capture: OutputCapture;\n\t\t\ttry {\n\t\t\t\tcapture = new OutputCapture(options?.capture, context, {\n\t\t\t\t\tonUpdate: options?.onUpdate,\n\t\t\t\t\tonError: failCallback,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconst cause = toError(error);\n\t\t\t\tresolvePromise(err(new ExecutionError(\"unknown\", cause.message, cause)));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst settle = (result: Result<ShellExecResult, ExecutionError>) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tif (timeoutId) clearTimeout(timeoutId);\n\t\t\t\tif (signal) signal.removeEventListener(\"abort\", onAbort);\n\t\t\t\tif (child?.pid) this.activeChildPids.delete(child.pid);\n\t\t\t\tcapture.dispose();\n\t\t\t\tresolvePromise(result);\n\t\t\t};\n\t\t\tconst pauseOutput = () => {\n\t\t\t\tchild?.stdout?.pause();\n\t\t\t\tchild?.stderr?.pause();\n\t\t\t};\n\t\t\tconst resumeOutput = () => {\n\t\t\t\tif (callbackError || spillError || timedOut || signal?.aborted || spillBackpressured) return;\n\t\t\t\tchild?.stdout?.resume();\n\t\t\t\tchild?.stderr?.resume();\n\t\t\t};\n\t\t\tconst failSpill = (error: unknown) => {\n\t\t\t\tif (spillError !== undefined) return;\n\t\t\t\tconst cause = toError(error);\n\t\t\t\tspillError = new ExecutionError(\n\t\t\t\t\t\"unknown\",\n\t\t\t\t\t`Failed to preserve complete shell output: ${cause.message}`,\n\t\t\t\t\tcause,\n\t\t\t\t);\n\t\t\t\tspillBackpressured = false;\n\t\t\t\tonAbort();\n\t\t\t};\n\t\t\tconst writeSpill = (chunk: SpillChunk): void => {\n\t\t\t\tif (spillStream === undefined || chunk.length === 0) return;\n\t\t\t\tif (spillStream.write(chunk) || spillBackpressured) return;\n\t\t\t\tspillBackpressured = true;\n\t\t\t\tpauseOutput();\n\t\t\t\tspillStream.once(\"drain\", () => {\n\t\t\t\t\tspillBackpressured = false;\n\t\t\t\t\tresumeOutput();\n\t\t\t\t});\n\t\t\t};\n\t\t\tconst startSpill = (chunk: SpillChunk): void => {\n\t\t\t\tif (spillStream !== undefined) {\n\t\t\t\t\twriteSpill(chunk);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tspillQueue.push(chunk);\n\t\t\t\tif (spillStart !== undefined) return;\n\t\t\t\tpauseOutput();\n\t\t\t\tspillStart = (async () => {\n\t\t\t\t\tconst created = await this.createTempFile({ prefix: \"pi-output-\", suffix: \".log\" }, context);\n\t\t\t\t\tif (!created.ok) throw created.error;\n\t\t\t\t\tspillPath = created.value;\n\t\t\t\t\tcapture.setSpillPath(spillPath);\n\t\t\t\t\tspillStream = createWriteStream(spillPath, { flags: \"a\", highWaterMark: SPILL_HIGH_WATER_MARK });\n\t\t\t\t\tspillStream.on(\"error\", failSpill);\n\t\t\t\t\tfor (const queued of spillQueue) writeSpill(queued);\n\t\t\t\t\tspillQueue.length = 0;\n\t\t\t\t})()\n\t\t\t\t\t.catch(failSpill)\n\t\t\t\t\t.finally(resumeOutput);\n\t\t\t};\n\t\t\tconst finishSpill = async (): Promise<void> => {\n\t\t\t\tawait spillStart;\n\t\t\t\tconst stream = spillStream;\n\t\t\t\tif (stream === undefined || spillError !== undefined || stream.destroyed) return;\n\t\t\t\tawait new Promise<void>((resolveFinish) => {\n\t\t\t\t\tstream.once(\"error\", () => resolveFinish());\n\t\t\t\t\tstream.once(\"finish\", resolveFinish);\n\t\t\t\t\tstream.end();\n\t\t\t\t});\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, options?.inheritEnv),\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 (child.pid) this.activeChildPids.add(child.pid);\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\ttimeoutMs === undefined\n\t\t\t\t\t? undefined\n\t\t\t\t\t: setTimeout(() => {\n\t\t\t\t\t\t\ttimedOut = true;\n\t\t\t\t\t\t\tonAbort();\n\t\t\t\t\t\t}, timeoutMs);\n\n\t\t\tif (signal) {\n\t\t\t\tif (signal.aborted) onAbort();\n\t\t\t\telse signal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t}\n\n\t\t\tconst feed = (chunk: Uint8Array) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst wasTruncated = capture.truncated;\n\t\t\t\t\tcapture.push(chunk);\n\t\t\t\t\tif (!options?.capture?.spill || chunk.length === 0) return;\n\t\t\t\t\tif (spillPath !== undefined || wasTruncated) {\n\t\t\t\t\t\tstartSpill(chunk);\n\t\t\t\t\t} else if (capture.truncated) {\n\t\t\t\t\t\tfor (const prefix of spillPrefix) startSpill(prefix);\n\t\t\t\t\t\tspillPrefix.length = 0;\n\t\t\t\t\t\tstartSpill(chunk);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tspillPrefix.push(chunk);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tfailCallback(error);\n\t\t\t\t}\n\t\t\t};\n\t\t\tchild.stdout?.on(\"data\", feed);\n\t\t\tchild.stderr?.on(\"data\", feed);\n\n\t\t\tvoid waitForChildProcess(\n\t\t\t\tchild,\n\t\t\t\t() =>\n\t\t\t\t\tspillError === undefined &&\n\t\t\t\t\tspillStart !== undefined &&\n\t\t\t\t\t(spillStream === undefined || spillBackpressured),\n\t\t\t).then(\n\t\t\t\tasync ({ code, signal: exitSignal }) => {\n\t\t\t\t\tawait finishSpill();\n\t\t\t\t\ttry {\n\t\t\t\t\t\tcapture.finish();\n\t\t\t\t\t\tcapture.flush();\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tfailCallback(error);\n\t\t\t\t\t}\n\t\t\t\t\tif (callbackError) {\n\t\t\t\t\t\tsettle(err(callbackError));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (timedOut) {\n\t\t\t\t\t\tsettle(err(new ExecutionError(\"timeout\", `timeout:${options?.timeout}`)));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\tsettle(err(new ExecutionError(\"aborted\", \"aborted\")));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (spillError) {\n\t\t\t\t\t\tsettle(err(spillError));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst output = capture.snapshot();\n\t\t\t\t\t// A process killed by a signal (e.g. OOM killer) has no exit code; map it\n\t\t\t\t\t// to the conventional 128 + signal number so callers do not mistake it\n\t\t\t\t\t// for a successful exit.\n\t\t\t\t\tconst exitCode = code ?? (exitSignal ? 128 + (osConstants.signals[exitSignal] ?? 0) : 1);\n\t\t\t\t\tsettle(\n\t\t\t\t\t\tok({\n\t\t\t\t\t\t\texitCode,\n\t\t\t\t\t\t\ttruncation: output.truncation,\n\t\t\t\t\t\t\t...(output.spillPath === undefined ? {} : { spillPath: output.spillPath }),\n\t\t\t\t\t\t\t...(output.lastLineBytes === undefined ? {} : { lastLineBytes: output.lastLineBytes }),\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t(error: Error) => settle(err(new ExecutionError(\"spawn_error\", error.message, error))),\n\t\t\t);\n\t\t});\n\t}\n\n\tasync openTextLineReader(path: string, context: Context): Promise<Result<TextLineReader, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<TextLineReader>(context.abortSignal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\tconst file = await openFile(resolved, \"r\");\n\t\t\tconst afterOpenAbort = abortResult<TextLineReader>(context.abortSignal, resolved);\n\t\t\tif (afterOpenAbort) {\n\t\t\t\tawait file.close().catch(() => undefined);\n\t\t\t\treturn afterOpenAbort;\n\t\t\t}\n\t\t\treturn ok(new NodeTextLineReader(file, resolved));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync readTextFile(path: string, context: Context): Promise<Result<string, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst signal = context.abortSignal;\n\t\tconst aborted = abortResult<string>(signal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\treturn ok(await readFile(resolved, { encoding: \"utf8\", signal }));\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 } | undefined,\n\t\tcontext: Context,\n\t): Promise<Result<string[], FileError>> {\n\t\tif (options?.maxLines !== undefined && options.maxLines <= 0) return ok([]);\n\t\tconst opened = await this.openTextLineReader(path, context);\n\t\tif (!opened.ok) return opened;\n\t\tconst lines: string[] = [];\n\t\ttry {\n\t\t\twhile (options?.maxLines === undefined || lines.length < options.maxLines) {\n\t\t\t\tconst line = await opened.value.readLine(context);\n\t\t\t\tif (!line.ok) return line;\n\t\t\t\tif (line.value === undefined) break;\n\t\t\t\tlines.push(line.value.text);\n\t\t\t}\n\t\t\treturn ok(lines);\n\t\t} finally {\n\t\t\tawait opened.value.close(context);\n\t\t}\n\t}\n\n\tasync readBinaryFile(path: string, context: Context): Promise<Result<Uint8Array, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst signal = context.abortSignal;\n\t\tconst aborted = abortResult<Uint8Array>(signal, resolved);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\treturn ok(await readFile(resolved, { signal }));\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync writeFile(path: string, content: string | Uint8Array, context: Context): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst signal = context.abortSignal;\n\t\tconst aborted = abortResult<void>(signal, 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>(signal, resolved);\n\t\t\tif (afterMkdirAbort) return afterMkdirAbort;\n\t\t\tawait writeFile(resolved, content, { signal });\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, context: Context): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst signal = context.abortSignal;\n\t\tconst aborted = abortResult<void>(signal, 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>(signal, resolved);\n\t\t\tif (afterMkdirAbort) return afterMkdirAbort;\n\t\t\tawait appendFile(resolved, content);\n\t\t\tconst afterAppendAbort = abortResult<void>(signal, resolved);\n\t\t\treturn afterAppendAbort ?? ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t}\n\t}\n\n\tasync truncateFile(path: string, size: number, context: Context): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst signal = context.abortSignal;\n\t\tconst aborted = abortResult<void>(signal, resolved);\n\t\tif (aborted) return aborted;\n\t\tif (!Number.isSafeInteger(size) || size < 0) {\n\t\t\treturn err(new FileError(\"invalid\", \"File size must be a non-negative safe integer\", resolved));\n\t\t}\n\t\tlet file: Awaited<ReturnType<typeof openFile>> | undefined;\n\t\ttry {\n\t\t\tfile = await openFile(resolved, \"r+\");\n\t\t\tawait file.truncate(size);\n\t\t\tconst afterTruncateAbort = abortResult<void>(signal, resolved);\n\t\t\treturn afterTruncateAbort ?? ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t} finally {\n\t\t\tawait file?.close().catch(() => undefined);\n\t\t}\n\t}\n\n\tasync flushFile(path: string, context: Context): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst signal = context.abortSignal;\n\t\tconst aborted = abortResult<void>(signal, resolved);\n\t\tif (aborted) return aborted;\n\t\tlet file: Awaited<ReturnType<typeof openFile>> | undefined;\n\t\ttry {\n\t\t\tfile = await openFile(resolved, \"r+\");\n\t\t\tawait file.sync();\n\t\t\tconst afterSyncAbort = abortResult<void>(signal, resolved);\n\t\t\treturn afterSyncAbort ?? ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, resolved));\n\t\t} finally {\n\t\t\tawait file?.close().catch(() => undefined);\n\t\t}\n\t}\n\n\tasync renameFile(sourcePath: string, destinationPath: string, context: Context): Promise<Result<void, FileError>> {\n\t\tconst source = resolvePath(this.cwd, sourcePath);\n\t\tconst destination = resolvePath(this.cwd, destinationPath);\n\t\tconst aborted = abortResult<void>(context.abortSignal, destination);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\tawait rename(source, destination);\n\t\t\treturn ok(undefined);\n\t\t} catch (error) {\n\t\t\treturn err(toFileError(error, source));\n\t\t}\n\t}\n\n\tasync fileInfo(path: string, context: Context): Promise<Result<FileInfo, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<FileInfo>(context.abortSignal, resolved);\n\t\tif (aborted) return aborted;\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, context: Context): Promise<Result<FileInfo[], FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst signal = context.abortSignal;\n\t\tconst aborted = abortResult<FileInfo[]>(signal, 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[]>(signal, 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, context: Context): Promise<Result<string, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<string>(context.abortSignal, resolved);\n\t\tif (aborted) return aborted;\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, context: Context): Promise<Result<boolean, FileError>> {\n\t\tconst result = await this.fileInfo(path, context);\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(\n\t\tpath: string,\n\t\toptions: { recursive?: boolean } | undefined,\n\t\tcontext: Context,\n\t): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<void>(context.abortSignal, resolved);\n\t\tif (aborted) return aborted;\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(\n\t\tpath: string,\n\t\toptions: { recursive?: boolean; force?: boolean } | undefined,\n\t\tcontext: Context,\n\t): Promise<Result<void, FileError>> {\n\t\tconst resolved = resolvePath(this.cwd, path);\n\t\tconst aborted = abortResult<void>(context.abortSignal, resolved);\n\t\tif (aborted) return aborted;\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 | undefined, context: Context): Promise<Result<string, FileError>> {\n\t\tconst aborted = abortResult<string>(context.abortSignal);\n\t\tif (aborted) return aborted;\n\t\ttry {\n\t\t\tprefix ??= \"tmp-\";\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(\n\t\toptions: { prefix?: string; suffix?: string } | undefined,\n\t\tcontext: Context,\n\t): Promise<Result<string, FileError>> {\n\t\tconst dir = await this.createTempDir(\"tmp-\", context);\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(_context: Context): Promise<void> {\n\t\tfor (const pid of this.activeChildPids) killProcessTree(pid);\n\t\tthis.activeChildPids.clear();\n\t}\n}\n"]}
@@ -0,0 +1,24 @@
1
+ export interface AdaptivePublisherOptions<TValue, TUpdate> {
2
+ snapshot(): TValue;
3
+ update(previous: TValue | undefined, current: TValue): TUpdate | undefined;
4
+ measure(update: TUpdate): number;
5
+ publish(update: TUpdate): void;
6
+ onError(error: unknown): void;
7
+ minIntervalMs?: number;
8
+ targetBytesPerSecond?: number;
9
+ }
10
+ /**
11
+ * Publishes the latest state without queuing intermediate mutations.
12
+ *
13
+ * The first dirty state after idle is immediate. Each publication then buys a
14
+ * delay proportional to its encoded size, with a minimum interval that also
15
+ * bounds event count. A single trailing timer guarantees eventual publication.
16
+ */
17
+ export declare class AdaptivePublisher<TValue, TUpdate> {
18
+ #private;
19
+ constructor(options: AdaptivePublisherOptions<TValue, TUpdate>);
20
+ markDirty(): void;
21
+ flush(force?: boolean): void;
22
+ dispose(): void;
23
+ }
24
+ //# sourceMappingURL=adaptive-publisher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adaptive-publisher.d.ts","sourceRoot":"","sources":["../../../src/env/utils/adaptive-publisher.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB,CAAC,MAAM,EAAE,OAAO;IACxD,QAAQ,IAAI,MAAM,CAAC;IACnB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC3E,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IACjC,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,qBAAa,iBAAiB,CAAC,MAAM,EAAE,OAAO;;IAU7C,YAAY,OAAO,EAAE,wBAAwB,CAAC,MAAM,EAAE,OAAO,CAAC,EAI7D;IAED,SAAS,IAAI,IAAI,CAShB;IAED,KAAK,CAAC,KAAK,UAAQ,GAAG,IAAI,CAuBzB;IAED,OAAO,IAAI,IAAI,CAId;CAaD"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Publishes the latest state without queuing intermediate mutations.
3
+ *
4
+ * The first dirty state after idle is immediate. Each publication then buys a
5
+ * delay proportional to its encoded size, with a minimum interval that also
6
+ * bounds event count. A single trailing timer guarantees eventual publication.
7
+ */
8
+ export class AdaptivePublisher {
9
+ #options;
10
+ #minIntervalMs;
11
+ #targetBytesPerSecond;
12
+ #published;
13
+ #dirty = false;
14
+ #nextEmitAt = 0;
15
+ #timer;
16
+ #disposed = false;
17
+ constructor(options) {
18
+ this.#options = options;
19
+ this.#minIntervalMs = options.minIntervalMs ?? 100;
20
+ this.#targetBytesPerSecond = options.targetBytesPerSecond ?? 100 * 1024;
21
+ }
22
+ markDirty() {
23
+ if (this.#disposed)
24
+ return;
25
+ this.#dirty = true;
26
+ const wait = this.#nextEmitAt - Date.now();
27
+ if (wait <= 0) {
28
+ this.flush();
29
+ return;
30
+ }
31
+ this.#armTimer(wait);
32
+ }
33
+ flush(force = false) {
34
+ if (this.#disposed || !this.#dirty)
35
+ return;
36
+ const now = Date.now();
37
+ if (!force && now < this.#nextEmitAt) {
38
+ this.#armTimer(this.#nextEmitAt - now);
39
+ return;
40
+ }
41
+ if (this.#timer !== undefined)
42
+ clearTimeout(this.#timer);
43
+ this.#timer = undefined;
44
+ const current = this.#options.snapshot();
45
+ const update = this.#options.update(this.#published, current);
46
+ if (update === undefined) {
47
+ this.#published = current;
48
+ this.#dirty = false;
49
+ return;
50
+ }
51
+ const encodedBytes = this.#options.measure(update);
52
+ this.#published = current;
53
+ this.#dirty = false;
54
+ this.#nextEmitAt = now + Math.max(this.#minIntervalMs, (encodedBytes * 1000) / this.#targetBytesPerSecond);
55
+ // Commit before delivery. A consumer may apply the update and then throw or
56
+ // reenter the producer; retaining the old baseline would duplicate that delta.
57
+ this.#options.publish(update);
58
+ }
59
+ dispose() {
60
+ if (this.#timer !== undefined)
61
+ clearTimeout(this.#timer);
62
+ this.#timer = undefined;
63
+ this.#disposed = true;
64
+ }
65
+ #armTimer(wait) {
66
+ if (this.#timer !== undefined)
67
+ return;
68
+ this.#timer = setTimeout(() => {
69
+ this.#timer = undefined;
70
+ try {
71
+ this.flush();
72
+ }
73
+ catch (error) {
74
+ this.#options.onError(error);
75
+ }
76
+ }, wait);
77
+ }
78
+ }
79
+ //# sourceMappingURL=adaptive-publisher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adaptive-publisher.js","sourceRoot":"","sources":["../../../src/env/utils/adaptive-publisher.ts"],"names":[],"mappings":"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","sourcesContent":["export interface AdaptivePublisherOptions<TValue, TUpdate> {\n\tsnapshot(): TValue;\n\tupdate(previous: TValue | undefined, current: TValue): TUpdate | undefined;\n\tmeasure(update: TUpdate): number;\n\tpublish(update: TUpdate): void;\n\tonError(error: unknown): void;\n\tminIntervalMs?: number;\n\ttargetBytesPerSecond?: number;\n}\n\n/**\n * Publishes the latest state without queuing intermediate mutations.\n *\n * The first dirty state after idle is immediate. Each publication then buys a\n * delay proportional to its encoded size, with a minimum interval that also\n * bounds event count. A single trailing timer guarantees eventual publication.\n */\nexport class AdaptivePublisher<TValue, TUpdate> {\n\treadonly #options: AdaptivePublisherOptions<TValue, TUpdate>;\n\treadonly #minIntervalMs: number;\n\treadonly #targetBytesPerSecond: number;\n\t#published: TValue | undefined;\n\t#dirty = false;\n\t#nextEmitAt = 0;\n\t#timer: ReturnType<typeof setTimeout> | undefined;\n\t#disposed = false;\n\n\tconstructor(options: AdaptivePublisherOptions<TValue, TUpdate>) {\n\t\tthis.#options = options;\n\t\tthis.#minIntervalMs = options.minIntervalMs ?? 100;\n\t\tthis.#targetBytesPerSecond = options.targetBytesPerSecond ?? 100 * 1024;\n\t}\n\n\tmarkDirty(): void {\n\t\tif (this.#disposed) return;\n\t\tthis.#dirty = true;\n\t\tconst wait = this.#nextEmitAt - Date.now();\n\t\tif (wait <= 0) {\n\t\t\tthis.flush();\n\t\t\treturn;\n\t\t}\n\t\tthis.#armTimer(wait);\n\t}\n\n\tflush(force = false): void {\n\t\tif (this.#disposed || !this.#dirty) return;\n\t\tconst now = Date.now();\n\t\tif (!force && now < this.#nextEmitAt) {\n\t\t\tthis.#armTimer(this.#nextEmitAt - now);\n\t\t\treturn;\n\t\t}\n\t\tif (this.#timer !== undefined) clearTimeout(this.#timer);\n\t\tthis.#timer = undefined;\n\t\tconst current = this.#options.snapshot();\n\t\tconst update = this.#options.update(this.#published, current);\n\t\tif (update === undefined) {\n\t\t\tthis.#published = current;\n\t\t\tthis.#dirty = false;\n\t\t\treturn;\n\t\t}\n\t\tconst encodedBytes = this.#options.measure(update);\n\t\tthis.#published = current;\n\t\tthis.#dirty = false;\n\t\tthis.#nextEmitAt = now + Math.max(this.#minIntervalMs, (encodedBytes * 1000) / this.#targetBytesPerSecond);\n\t\t// Commit before delivery. A consumer may apply the update and then throw or\n\t\t// reenter the producer; retaining the old baseline would duplicate that delta.\n\t\tthis.#options.publish(update);\n\t}\n\n\tdispose(): void {\n\t\tif (this.#timer !== undefined) clearTimeout(this.#timer);\n\t\tthis.#timer = undefined;\n\t\tthis.#disposed = true;\n\t}\n\n\t#armTimer(wait: number): void {\n\t\tif (this.#timer !== undefined) return;\n\t\tthis.#timer = setTimeout(() => {\n\t\t\tthis.#timer = undefined;\n\t\t\ttry {\n\t\t\t\tthis.flush();\n\t\t\t} catch (error) {\n\t\t\t\tthis.#options.onError(error);\n\t\t\t}\n\t\t}, wait);\n\t}\n}\n"]}
@@ -0,0 +1,31 @@
1
+ import type { Context } from "@earendil-works/chord";
2
+ import type { ShellOutputCaptureOptions, ShellOutputUpdate, ShellOutputView } from "../index.ts";
3
+ export declare const OUTPUT_MIN_EMIT_INTERVAL_MS = 100;
4
+ export declare const OUTPUT_TARGET_BYTES_PER_SECOND: number;
5
+ interface OutputCaptureHandlers {
6
+ onUpdate?: (update: ShellOutputUpdate, context: Context) => void;
7
+ onError(error: unknown): void;
8
+ }
9
+ /**
10
+ * Maintains and publishes one bounded shell-output view.
11
+ *
12
+ * Writes received while publication is rate-limited collapse into the latest
13
+ * view. Small changes remain responsive; complete window turnovers purchase a
14
+ * proportionally longer delay. The first update after idle and an explicit
15
+ * final flush are immediate.
16
+ */
17
+ export declare class OutputCapture {
18
+ #private;
19
+ constructor(options: ShellOutputCaptureOptions | undefined, context: Context, handlers: OutputCaptureHandlers);
20
+ get truncated(): boolean;
21
+ push(chunk: string | Uint8Array): void;
22
+ finish(): void;
23
+ setSpillPath(path: string): void;
24
+ snapshot(): ShellOutputView;
25
+ flush(): void;
26
+ dispose(): void;
27
+ }
28
+ export declare function applyShellOutputUpdate(current: ShellOutputView | undefined, update: ShellOutputUpdate): ShellOutputView;
29
+ export declare function sanitizeShellOutput(text: string): string;
30
+ export {};
31
+ //# sourceMappingURL=output-capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-capture.d.ts","sourceRoot":"","sources":["../../../src/env/utils/output-capture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,yBAAyB,EAAuB,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAItH,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAC/C,eAAO,MAAM,8BAA8B,QAAa,CAAC;AAMzD,UAAU,qBAAqB;IAC9B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACjE,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,qBAAa,aAAa;;IAmBzB,YAAY,OAAO,EAAE,yBAAyB,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAqB5G;IAED,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQrC;IAED,MAAM,IAAI,IAAI,CAGb;IAED,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAK/B;IAED,QAAQ,IAAI,eAAe,CA6B1B;IAED,KAAK,IAAI,IAAI,CAGZ;IAED,OAAO,IAAI,IAAI,CAGd;CAsCD;AAED,wBAAgB,sBAAsB,CACrC,OAAO,EAAE,eAAe,GAAG,SAAS,EACpC,MAAM,EAAE,iBAAiB,GACvB,eAAe,CAWjB;AA+CD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD"}
@@ -0,0 +1,238 @@
1
+ import { AdaptivePublisher } from "./adaptive-publisher.js";
2
+ import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateHead, truncateTail, utf8ByteLength } from "./truncate.js";
3
+ export const OUTPUT_MIN_EMIT_INTERVAL_MS = 100;
4
+ export const OUTPUT_TARGET_BYTES_PER_SECOND = 100 * 1024;
5
+ const INVALID_SHELL_OUTPUT = /[\x00-\x08\x0b-\x1f\ufff9-\ufffb]/g;
6
+ const textEncoder = new TextEncoder();
7
+ const textDecoder = new TextDecoder();
8
+ /**
9
+ * Maintains and publishes one bounded shell-output view.
10
+ *
11
+ * Writes received while publication is rate-limited collapse into the latest
12
+ * view. Small changes remain responsive; complete window turnovers purchase a
13
+ * proportionally longer delay. The first update after idle and an explicit
14
+ * final flush are immediate.
15
+ */
16
+ export class OutputCapture {
17
+ #maxBytes;
18
+ #maxLines;
19
+ #retain;
20
+ #context;
21
+ #onUpdate;
22
+ #decoder = new TextDecoder();
23
+ #buffer = "";
24
+ #bufferBytes = 0;
25
+ #totalBytes = 0;
26
+ #newlines = 0;
27
+ #endsWithNewline = true;
28
+ #currentLineBytes = 0;
29
+ #lastTerminatedLineBytes = 0;
30
+ #spillPath;
31
+ #disposed = false;
32
+ #publisher;
33
+ constructor(options, context, handlers) {
34
+ this.#maxBytes = options?.limits.maxBytes ?? DEFAULT_MAX_BYTES;
35
+ this.#maxLines = options?.limits.maxLines ?? DEFAULT_MAX_LINES;
36
+ this.#retain = options?.limits.retain ?? "tail";
37
+ this.#context = context;
38
+ this.#onUpdate = handlers.onUpdate;
39
+ if (!Number.isFinite(this.#maxBytes) || this.#maxBytes <= 0) {
40
+ throw new TypeError("Output maxBytes must be a positive finite number");
41
+ }
42
+ if (!Number.isInteger(this.#maxLines) || this.#maxLines <= 0) {
43
+ throw new TypeError("Output maxLines must be a positive integer");
44
+ }
45
+ this.#publisher = new AdaptivePublisher({
46
+ snapshot: () => this.snapshot(),
47
+ update: updateFrom,
48
+ measure: (update) => utf8ByteLength(JSON.stringify(update)),
49
+ publish: (update) => this.#onUpdate?.(update, this.#context),
50
+ onError: handlers.onError,
51
+ minIntervalMs: OUTPUT_MIN_EMIT_INTERVAL_MS,
52
+ targetBytesPerSecond: OUTPUT_TARGET_BYTES_PER_SECOND,
53
+ });
54
+ }
55
+ get truncated() {
56
+ return this.#totalBytes > this.#maxBytes || this.#totalLines() > this.#maxLines;
57
+ }
58
+ push(chunk) {
59
+ if (this.#disposed)
60
+ return;
61
+ if (typeof chunk === "string") {
62
+ this.#appendText(this.#decoder.decode());
63
+ this.#appendText(chunk);
64
+ return;
65
+ }
66
+ this.#appendText(this.#decoder.decode(chunk, { stream: true }));
67
+ }
68
+ finish() {
69
+ if (this.#disposed)
70
+ return;
71
+ this.#appendText(this.#decoder.decode());
72
+ }
73
+ setSpillPath(path) {
74
+ if (this.#disposed || this.#spillPath === path)
75
+ return;
76
+ this.#spillPath = path;
77
+ this.#publisher.markDirty();
78
+ this.flush();
79
+ }
80
+ snapshot() {
81
+ const retained = this.#retain === "head"
82
+ ? truncateHead(this.#buffer, { maxBytes: this.#maxBytes, maxLines: this.#maxLines })
83
+ : truncateTail(this.#buffer, { maxBytes: this.#maxBytes, maxLines: this.#maxLines });
84
+ const totalLines = this.#totalLines();
85
+ const truncated = this.truncated;
86
+ const { content, ...truncation } = retained;
87
+ // The working buffer preserves the retained edge, so its truncation decision reports the first limit reached.
88
+ const truncatedBy = !truncated
89
+ ? null
90
+ : retained.truncated
91
+ ? retained.truncatedBy
92
+ : totalLines > this.#maxLines
93
+ ? "lines"
94
+ : "bytes";
95
+ const lastLineBytes = this.#endsWithNewline ? this.#lastTerminatedLineBytes : this.#currentLineBytes;
96
+ return {
97
+ text: sanitizeShellOutput(content),
98
+ truncation: {
99
+ ...truncation,
100
+ truncated,
101
+ truncatedBy,
102
+ totalBytes: this.#totalBytes,
103
+ totalLines,
104
+ },
105
+ ...(this.#spillPath === undefined ? {} : { spillPath: this.#spillPath }),
106
+ ...(retained.lastLinePartial ? { lastLineBytes } : {}),
107
+ };
108
+ }
109
+ flush() {
110
+ if (this.#disposed)
111
+ return;
112
+ this.#publisher.flush(true);
113
+ }
114
+ dispose() {
115
+ this.#publisher.dispose();
116
+ this.#disposed = true;
117
+ }
118
+ #appendText(text) {
119
+ if (text === "")
120
+ return;
121
+ const textBytes = utf8ByteLength(text);
122
+ this.#totalBytes += textBytes;
123
+ this.#newlines += countNewlines(text);
124
+ this.#endsWithNewline = text.endsWith("\n");
125
+ const lastNewline = text.lastIndexOf("\n");
126
+ if (lastNewline === -1) {
127
+ this.#currentLineBytes += textBytes;
128
+ }
129
+ else {
130
+ const previousNewline = lastNewline === 0 ? -1 : text.lastIndexOf("\n", lastNewline - 1);
131
+ this.#lastTerminatedLineBytes =
132
+ previousNewline === -1
133
+ ? this.#currentLineBytes + utf8ByteLength(text.slice(0, lastNewline))
134
+ : utf8ByteLength(text.slice(previousNewline + 1, lastNewline));
135
+ this.#currentLineBytes = utf8ByteLength(text.slice(lastNewline + 1));
136
+ }
137
+ this.#buffer += text;
138
+ this.#bufferBytes += textBytes;
139
+ // Trimming stops at a UTF-8 character boundary. The four-byte allowance keeps at least twice the byte limit,
140
+ // preserving the evidence for limits and partial lines even when an edge character is multi-byte.
141
+ const guard = this.#maxBytes * 2 + 4;
142
+ if (this.#bufferBytes > guard * 2) {
143
+ this.#buffer =
144
+ this.#retain === "tail"
145
+ ? trimToLastUtf8Bytes(this.#buffer, guard)
146
+ : trimToFirstUtf8Bytes(this.#buffer, guard);
147
+ this.#bufferBytes = utf8ByteLength(this.#buffer);
148
+ }
149
+ this.#publisher.markDirty();
150
+ }
151
+ #totalLines() {
152
+ return this.#newlines + (this.#endsWithNewline || this.#totalBytes === 0 ? 0 : 1);
153
+ }
154
+ }
155
+ export function applyShellOutputUpdate(current, update) {
156
+ switch (update.kind) {
157
+ case "replace":
158
+ return update.output;
159
+ case "append":
160
+ return { text: `${current?.text ?? ""}${update.text}`, ...update.metadata };
161
+ case "slide":
162
+ return { text: `${current?.text.slice(update.drop) ?? ""}${update.text}`, ...update.metadata };
163
+ case "metadata":
164
+ return { text: current?.text ?? "", ...update.metadata };
165
+ }
166
+ }
167
+ function updateFrom(previous, current) {
168
+ if (previous === undefined)
169
+ return { kind: "replace", output: current };
170
+ const metadata = {
171
+ truncation: current.truncation,
172
+ ...(current.spillPath === undefined ? {} : { spillPath: current.spillPath }),
173
+ ...(current.lastLineBytes === undefined ? {} : { lastLineBytes: current.lastLineBytes }),
174
+ };
175
+ if (current.text === previous.text)
176
+ return { kind: "metadata", metadata };
177
+ if (current.text.length > previous.text.length && current.text.slice(0, previous.text.length) === previous.text) {
178
+ return { kind: "append", text: current.text.slice(previous.text.length), metadata };
179
+ }
180
+ const shared = suffixPrefixOverlap(previous.text, current.text, Math.min(previous.text.length, current.text.length, current.truncation.maxBytes * 2));
181
+ if (shared > 0) {
182
+ return {
183
+ kind: "slide",
184
+ drop: previous.text.length - shared,
185
+ text: current.text.slice(shared),
186
+ metadata,
187
+ };
188
+ }
189
+ return { kind: "replace", output: current };
190
+ }
191
+ function suffixPrefixOverlap(before, after, scan) {
192
+ if (before.length === 0 || after.length === 0 || scan === 0)
193
+ return 0;
194
+ const tail = before.length > scan ? before.slice(before.length - scan) : before;
195
+ for (const probeLength of [Math.min(64, after.length), 1]) {
196
+ const probe = after.slice(0, probeLength);
197
+ let candidates = 0;
198
+ for (let index = tail.indexOf(probe); index !== -1; index = tail.indexOf(probe, index + 1)) {
199
+ if (++candidates > 8)
200
+ break;
201
+ const overlapLength = tail.length - index;
202
+ if (overlapLength <= after.length && tail.slice(index) === after.slice(0, overlapLength)) {
203
+ return overlapLength;
204
+ }
205
+ }
206
+ if (probeLength === 1)
207
+ break;
208
+ }
209
+ return 0;
210
+ }
211
+ export function sanitizeShellOutput(text) {
212
+ return text.replace(INVALID_SHELL_OUTPUT, "");
213
+ }
214
+ function countNewlines(text) {
215
+ let count = 0;
216
+ for (let index = text.indexOf("\n"); index !== -1; index = text.indexOf("\n", index + 1))
217
+ count++;
218
+ return count;
219
+ }
220
+ function trimToLastUtf8Bytes(text, maxBytes) {
221
+ const bytes = textEncoder.encode(text);
222
+ if (bytes.length <= maxBytes)
223
+ return text;
224
+ let start = bytes.length - maxBytes;
225
+ while (start < bytes.length && ((bytes[start] ?? 0) & 0xc0) === 0x80)
226
+ start++;
227
+ return textDecoder.decode(bytes.subarray(start));
228
+ }
229
+ function trimToFirstUtf8Bytes(text, maxBytes) {
230
+ const bytes = textEncoder.encode(text);
231
+ if (bytes.length <= maxBytes)
232
+ return text;
233
+ let end = maxBytes;
234
+ while (end > 0 && ((bytes[end] ?? 0) & 0xc0) === 0x80)
235
+ end--;
236
+ return textDecoder.decode(bytes.subarray(0, end));
237
+ }
238
+ //# sourceMappingURL=output-capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-capture.js","sourceRoot":"","sources":["../../../src/env/utils/output-capture.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport type { ShellOutputCaptureOptions, ShellOutputMetadata, ShellOutputUpdate, ShellOutputView } from \"../index.ts\";\nimport { AdaptivePublisher } from \"./adaptive-publisher.ts\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateHead, truncateTail, utf8ByteLength } from \"./truncate.ts\";\n\nexport const OUTPUT_MIN_EMIT_INTERVAL_MS = 100;\nexport const OUTPUT_TARGET_BYTES_PER_SECOND = 100 * 1024;\n\nconst INVALID_SHELL_OUTPUT = /[\\x00-\\x08\\x0b-\\x1f\\ufff9-\\ufffb]/g;\nconst textEncoder = new TextEncoder();\nconst textDecoder = new TextDecoder();\n\ninterface OutputCaptureHandlers {\n\tonUpdate?: (update: ShellOutputUpdate, context: Context) => void;\n\tonError(error: unknown): void;\n}\n\n/**\n * Maintains and publishes one bounded shell-output view.\n *\n * Writes received while publication is rate-limited collapse into the latest\n * view. Small changes remain responsive; complete window turnovers purchase a\n * proportionally longer delay. The first update after idle and an explicit\n * final flush are immediate.\n */\nexport class OutputCapture {\n\treadonly #maxBytes: number;\n\treadonly #maxLines: number;\n\treadonly #retain: \"head\" | \"tail\";\n\treadonly #context: Context;\n\treadonly #onUpdate: OutputCaptureHandlers[\"onUpdate\"];\n\n\treadonly #decoder = new TextDecoder();\n\t#buffer = \"\";\n\t#bufferBytes = 0;\n\t#totalBytes = 0;\n\t#newlines = 0;\n\t#endsWithNewline = true;\n\t#currentLineBytes = 0;\n\t#lastTerminatedLineBytes = 0;\n\t#spillPath: string | undefined;\n\t#disposed = false;\n\treadonly #publisher: AdaptivePublisher<ShellOutputView, ShellOutputUpdate>;\n\n\tconstructor(options: ShellOutputCaptureOptions | undefined, context: Context, handlers: OutputCaptureHandlers) {\n\t\tthis.#maxBytes = options?.limits.maxBytes ?? DEFAULT_MAX_BYTES;\n\t\tthis.#maxLines = options?.limits.maxLines ?? DEFAULT_MAX_LINES;\n\t\tthis.#retain = options?.limits.retain ?? \"tail\";\n\t\tthis.#context = context;\n\t\tthis.#onUpdate = handlers.onUpdate;\n\t\tif (!Number.isFinite(this.#maxBytes) || this.#maxBytes <= 0) {\n\t\t\tthrow new TypeError(\"Output maxBytes must be a positive finite number\");\n\t\t}\n\t\tif (!Number.isInteger(this.#maxLines) || this.#maxLines <= 0) {\n\t\t\tthrow new TypeError(\"Output maxLines must be a positive integer\");\n\t\t}\n\t\tthis.#publisher = new AdaptivePublisher({\n\t\t\tsnapshot: () => this.snapshot(),\n\t\t\tupdate: updateFrom,\n\t\t\tmeasure: (update) => utf8ByteLength(JSON.stringify(update)),\n\t\t\tpublish: (update) => this.#onUpdate?.(update, this.#context),\n\t\t\tonError: handlers.onError,\n\t\t\tminIntervalMs: OUTPUT_MIN_EMIT_INTERVAL_MS,\n\t\t\ttargetBytesPerSecond: OUTPUT_TARGET_BYTES_PER_SECOND,\n\t\t});\n\t}\n\n\tget truncated(): boolean {\n\t\treturn this.#totalBytes > this.#maxBytes || this.#totalLines() > this.#maxLines;\n\t}\n\n\tpush(chunk: string | Uint8Array): void {\n\t\tif (this.#disposed) return;\n\t\tif (typeof chunk === \"string\") {\n\t\t\tthis.#appendText(this.#decoder.decode());\n\t\t\tthis.#appendText(chunk);\n\t\t\treturn;\n\t\t}\n\t\tthis.#appendText(this.#decoder.decode(chunk, { stream: true }));\n\t}\n\n\tfinish(): void {\n\t\tif (this.#disposed) return;\n\t\tthis.#appendText(this.#decoder.decode());\n\t}\n\n\tsetSpillPath(path: string): void {\n\t\tif (this.#disposed || this.#spillPath === path) return;\n\t\tthis.#spillPath = path;\n\t\tthis.#publisher.markDirty();\n\t\tthis.flush();\n\t}\n\n\tsnapshot(): ShellOutputView {\n\t\tconst retained =\n\t\t\tthis.#retain === \"head\"\n\t\t\t\t? truncateHead(this.#buffer, { maxBytes: this.#maxBytes, maxLines: this.#maxLines })\n\t\t\t\t: truncateTail(this.#buffer, { maxBytes: this.#maxBytes, maxLines: this.#maxLines });\n\t\tconst totalLines = this.#totalLines();\n\t\tconst truncated = this.truncated;\n\t\tconst { content, ...truncation } = retained;\n\t\t// The working buffer preserves the retained edge, so its truncation decision reports the first limit reached.\n\t\tconst truncatedBy = !truncated\n\t\t\t? null\n\t\t\t: retained.truncated\n\t\t\t\t? retained.truncatedBy\n\t\t\t\t: totalLines > this.#maxLines\n\t\t\t\t\t? \"lines\"\n\t\t\t\t\t: \"bytes\";\n\t\tconst lastLineBytes = this.#endsWithNewline ? this.#lastTerminatedLineBytes : this.#currentLineBytes;\n\t\treturn {\n\t\t\ttext: sanitizeShellOutput(content),\n\t\t\ttruncation: {\n\t\t\t\t...truncation,\n\t\t\t\ttruncated,\n\t\t\t\ttruncatedBy,\n\t\t\t\ttotalBytes: this.#totalBytes,\n\t\t\t\ttotalLines,\n\t\t\t},\n\t\t\t...(this.#spillPath === undefined ? {} : { spillPath: this.#spillPath }),\n\t\t\t...(retained.lastLinePartial ? { lastLineBytes } : {}),\n\t\t};\n\t}\n\n\tflush(): void {\n\t\tif (this.#disposed) return;\n\t\tthis.#publisher.flush(true);\n\t}\n\n\tdispose(): void {\n\t\tthis.#publisher.dispose();\n\t\tthis.#disposed = true;\n\t}\n\n\t#appendText(text: string): void {\n\t\tif (text === \"\") return;\n\t\tconst textBytes = utf8ByteLength(text);\n\t\tthis.#totalBytes += textBytes;\n\t\tthis.#newlines += countNewlines(text);\n\t\tthis.#endsWithNewline = text.endsWith(\"\\n\");\n\t\tconst lastNewline = text.lastIndexOf(\"\\n\");\n\t\tif (lastNewline === -1) {\n\t\t\tthis.#currentLineBytes += textBytes;\n\t\t} else {\n\t\t\tconst previousNewline = lastNewline === 0 ? -1 : text.lastIndexOf(\"\\n\", lastNewline - 1);\n\t\t\tthis.#lastTerminatedLineBytes =\n\t\t\t\tpreviousNewline === -1\n\t\t\t\t\t? this.#currentLineBytes + utf8ByteLength(text.slice(0, lastNewline))\n\t\t\t\t\t: utf8ByteLength(text.slice(previousNewline + 1, lastNewline));\n\t\t\tthis.#currentLineBytes = utf8ByteLength(text.slice(lastNewline + 1));\n\t\t}\n\t\tthis.#buffer += text;\n\t\tthis.#bufferBytes += textBytes;\n\n\t\t// Trimming stops at a UTF-8 character boundary. The four-byte allowance keeps at least twice the byte limit,\n\t\t// preserving the evidence for limits and partial lines even when an edge character is multi-byte.\n\t\tconst guard = this.#maxBytes * 2 + 4;\n\t\tif (this.#bufferBytes > guard * 2) {\n\t\t\tthis.#buffer =\n\t\t\t\tthis.#retain === \"tail\"\n\t\t\t\t\t? trimToLastUtf8Bytes(this.#buffer, guard)\n\t\t\t\t\t: trimToFirstUtf8Bytes(this.#buffer, guard);\n\t\t\tthis.#bufferBytes = utf8ByteLength(this.#buffer);\n\t\t}\n\t\tthis.#publisher.markDirty();\n\t}\n\n\t#totalLines(): number {\n\t\treturn this.#newlines + (this.#endsWithNewline || this.#totalBytes === 0 ? 0 : 1);\n\t}\n}\n\nexport function applyShellOutputUpdate(\n\tcurrent: ShellOutputView | undefined,\n\tupdate: ShellOutputUpdate,\n): ShellOutputView {\n\tswitch (update.kind) {\n\t\tcase \"replace\":\n\t\t\treturn update.output;\n\t\tcase \"append\":\n\t\t\treturn { text: `${current?.text ?? \"\"}${update.text}`, ...update.metadata };\n\t\tcase \"slide\":\n\t\t\treturn { text: `${current?.text.slice(update.drop) ?? \"\"}${update.text}`, ...update.metadata };\n\t\tcase \"metadata\":\n\t\t\treturn { text: current?.text ?? \"\", ...update.metadata };\n\t}\n}\n\nfunction updateFrom(previous: ShellOutputView | undefined, current: ShellOutputView): ShellOutputUpdate {\n\tif (previous === undefined) return { kind: \"replace\", output: current };\n\tconst metadata: ShellOutputMetadata = {\n\t\ttruncation: current.truncation,\n\t\t...(current.spillPath === undefined ? {} : { spillPath: current.spillPath }),\n\t\t...(current.lastLineBytes === undefined ? {} : { lastLineBytes: current.lastLineBytes }),\n\t};\n\tif (current.text === previous.text) return { kind: \"metadata\", metadata };\n\tif (current.text.length > previous.text.length && current.text.slice(0, previous.text.length) === previous.text) {\n\t\treturn { kind: \"append\", text: current.text.slice(previous.text.length), metadata };\n\t}\n\tconst shared = suffixPrefixOverlap(\n\t\tprevious.text,\n\t\tcurrent.text,\n\t\tMath.min(previous.text.length, current.text.length, current.truncation.maxBytes * 2),\n\t);\n\tif (shared > 0) {\n\t\treturn {\n\t\t\tkind: \"slide\",\n\t\t\tdrop: previous.text.length - shared,\n\t\t\ttext: current.text.slice(shared),\n\t\t\tmetadata,\n\t\t};\n\t}\n\treturn { kind: \"replace\", output: current };\n}\n\nfunction suffixPrefixOverlap(before: string, after: string, scan: number): number {\n\tif (before.length === 0 || after.length === 0 || scan === 0) return 0;\n\tconst tail = before.length > scan ? before.slice(before.length - scan) : before;\n\tfor (const probeLength of [Math.min(64, after.length), 1]) {\n\t\tconst probe = after.slice(0, probeLength);\n\t\tlet candidates = 0;\n\t\tfor (let index = tail.indexOf(probe); index !== -1; index = tail.indexOf(probe, index + 1)) {\n\t\t\tif (++candidates > 8) break;\n\t\t\tconst overlapLength = tail.length - index;\n\t\t\tif (overlapLength <= after.length && tail.slice(index) === after.slice(0, overlapLength)) {\n\t\t\t\treturn overlapLength;\n\t\t\t}\n\t\t}\n\t\tif (probeLength === 1) break;\n\t}\n\treturn 0;\n}\n\nexport function sanitizeShellOutput(text: string): string {\n\treturn text.replace(INVALID_SHELL_OUTPUT, \"\");\n}\n\nfunction countNewlines(text: string): number {\n\tlet count = 0;\n\tfor (let index = text.indexOf(\"\\n\"); index !== -1; index = text.indexOf(\"\\n\", index + 1)) count++;\n\treturn count;\n}\n\nfunction trimToLastUtf8Bytes(text: string, maxBytes: number): string {\n\tconst bytes = textEncoder.encode(text);\n\tif (bytes.length <= maxBytes) return text;\n\tlet start = bytes.length - maxBytes;\n\twhile (start < bytes.length && ((bytes[start] ?? 0) & 0xc0) === 0x80) start++;\n\treturn textDecoder.decode(bytes.subarray(start));\n}\n\nfunction trimToFirstUtf8Bytes(text: string, maxBytes: number): string {\n\tconst bytes = textEncoder.encode(text);\n\tif (bytes.length <= maxBytes) return text;\n\tlet end = maxBytes;\n\twhile (end > 0 && ((bytes[end] ?? 0) & 0xc0) === 0x80) end--;\n\treturn textDecoder.decode(bytes.subarray(0, end));\n}\n"]}