@agimon-ai/po-runner 0.0.0-alpha.21 → 0.0.0-alpha.23
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.
- package/dist/apiContracts.cjs +8 -1
- package/dist/apiContracts.cjs.map +1 -1
- package/dist/apiContracts.d.mts.map +1 -1
- package/dist/apiContracts.mjs +8 -1
- package/dist/apiContracts.mjs.map +1 -1
- package/dist/{bashRunService-Ci0cGdYO.d.mts → bashRunService-BL4JIUi2.d.mts} +6 -1
- package/dist/bashRunService-BL4JIUi2.d.mts.map +1 -0
- package/dist/{bashRunService-DjOH5kye.cjs → bashRunService-CJhMNrPz.cjs} +8 -4
- package/dist/bashRunService-CJhMNrPz.cjs.map +1 -0
- package/dist/{bashRunService-Cl3pYccr.mjs → bashRunService-DbYsj1zc.mjs} +8 -4
- package/dist/bashRunService-DbYsj1zc.mjs.map +1 -0
- package/dist/bashRunService.cjs +1 -1
- package/dist/bashRunService.d.mts +1 -1
- package/dist/bashRunService.d.mts.map +1 -1
- package/dist/bashRunService.mjs +1 -1
- package/dist/bashTool.cjs +1 -1
- package/dist/bashTool.d.mts +2 -2
- package/dist/bashTool.mjs +1 -1
- package/dist/bin/cli.cjs +1 -1
- package/dist/bin/cli.mjs +1 -1
- package/dist/extensions/mcp.cjs +1 -0
- package/dist/extensions/mcp.cjs.map +1 -1
- package/dist/extensions/mcp.mjs +1 -0
- package/dist/extensions/mcp.mjs.map +1 -1
- package/dist/extensions/native.mjs +533 -256
- package/dist/extensions/native.mjs.map +1 -1
- package/dist/extensions/server.cjs +24 -6
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.mjs +23 -5
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +459 -517
- package/dist/extensions/web.mjs.map +1 -1
- package/dist/{headless-Dko_yBiy.cjs → headless-BqYKFHwy.cjs} +31 -6
- package/dist/headless-BqYKFHwy.cjs.map +1 -0
- package/dist/{headless-DOlCixyf.mjs → headless-CV-eb5rz.mjs} +31 -6
- package/dist/headless-CV-eb5rz.mjs.map +1 -0
- package/dist/{index-BzeXJk6V.d.mts → index-BciAgV5f.d.mts} +11 -4
- package/dist/index-BciAgV5f.d.mts.map +1 -0
- package/dist/{index--xF7DvsE.d.mts → index-CXbcmf-G.d.mts} +2 -2
- package/dist/{index--xF7DvsE.d.mts.map → index-CXbcmf-G.d.mts.map} +1 -1
- package/dist/index.cjs +4 -4
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/responseEnvelope.d.mts +1 -1
- package/dist/{rmuxBackend-Dh0CYVAL.cjs → rmuxBackend-Cod2H85V.cjs} +2 -2
- package/dist/{rmuxBackend-Dh0CYVAL.cjs.map → rmuxBackend-Cod2H85V.cjs.map} +1 -1
- package/dist/rmuxBackend.cjs +1 -1
- package/dist/{rtkProcessor-DSGbM-Cm.cjs → rtkProcessor-xwARIxhe.cjs} +2 -2
- package/dist/{rtkProcessor-DSGbM-Cm.cjs.map → rtkProcessor-xwARIxhe.cjs.map} +1 -1
- package/dist/rtkProcessor.cjs +1 -1
- package/dist/{runnerDependencies-7h_cxOva.mjs → runnerDependencies-CamKwphq.mjs} +2 -2
- package/dist/{runnerDependencies-7h_cxOva.mjs.map → runnerDependencies-CamKwphq.mjs.map} +1 -1
- package/dist/{runnerDependencies-DSun3xO-.cjs → runnerDependencies-HIqMQp9b.cjs} +4 -4
- package/dist/{runnerDependencies-DSun3xO-.cjs.map → runnerDependencies-HIqMQp9b.cjs.map} +1 -1
- package/dist/runnerDependencies.cjs +1 -1
- package/dist/runnerDependencies.d.mts +1 -1
- package/dist/runnerDependencies.mjs +1 -1
- package/dist/{type-Do0YxwVQ.d.mts → type-BQ2shEB5.d.mts} +2 -2
- package/dist/{type-Do0YxwVQ.d.mts.map → type-BQ2shEB5.d.mts.map} +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +17 -17
- package/dist/bashRunService-Ci0cGdYO.d.mts.map +0 -1
- package/dist/bashRunService-Cl3pYccr.mjs.map +0 -1
- package/dist/bashRunService-DjOH5kye.cjs.map +0 -1
- package/dist/headless-DOlCixyf.mjs.map +0 -1
- package/dist/headless-Dko_yBiy.cjs.map +0 -1
- package/dist/index-BzeXJk6V.d.mts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rtkProcessor-DSGbM-Cm.cjs","names":["fs","RTK_FAILED_WARNING","RTK_OVERSIZED_WARNING","RTK_UNAVAILABLE_WARNING","spawn","getResultMaxBytes","RTK_TIMEOUT_WARNING","createRequire","path"],"sources":["../src/constants/rtkProcessor.ts","../src/services/rtkProcessor/index.ts"],"sourcesContent":["export const BYTES_PER_MIB = 1_048_576;\nexport const RTK_STDIN_MAX_BYTES = 10_485_760;\nexport const DEFAULT_RTK_TIMEOUT_MS = 10_000;\nexport const RTK_KILL_WAIT_MS = 1_000;\nexport const OUTPUT_BUFFER_FACTOR = 2;\nexport const EXECUTABLE_MODE = 0o755;\nexport const SIMPLE_TOKEN_PATTERN = /^[A-Za-z0-9_./:@%+=,-]+$/u;\nexport const SHELL_CONTROL_PATTERN = /[\\r\\n;&|<>`$\\\\'\"(){}*?!]/u;\nexport const RTK_BINARY_ENV = 'PO_RTK_BINARY';\n","import { type ChildProcessWithoutNullStreams, spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport {\n DEFAULT_RTK_TIMEOUT_MS,\n EXECUTABLE_MODE,\n OUTPUT_BUFFER_FACTOR,\n RTK_BINARY_ENV,\n RTK_KILL_WAIT_MS,\n RTK_STDIN_MAX_BYTES,\n SHELL_CONTROL_PATTERN,\n SIMPLE_TOKEN_PATTERN,\n} from '../../constants/rtkProcessor';\nimport {\n type IRtkProcessor,\n RTK_FAILED_WARNING,\n RTK_OVERSIZED_WARNING,\n RTK_TIMEOUT_WARNING,\n RTK_UNAVAILABLE_WARNING,\n type RtkFilter,\n type RtkProcessRequest,\n type RtkProcessResult,\n} from '../../types/rtkProcessor';\nimport type { RunnerSettings } from '../../types/runnerSettings';\nimport { getResultMaxBytes } from '../runnerConfig';\n\nconst GIT_DIFF_INCOMPATIBLE_OPTIONS = [\n '-s',\n '-z',\n '--raw',\n '--numstat',\n '--shortstat',\n '--stat',\n '--dirstat',\n '--dirstat-by-file',\n '--summary',\n '--compact-summary',\n '--name-only',\n '--name-status',\n '--check',\n '--binary',\n '--word-diff',\n '--word-diff-regex',\n '--color',\n '--color-words',\n '--color-moved',\n '--color-moved-ws',\n '--line-prefix',\n '--no-patch',\n '--patch-with-raw',\n '--patch-with-stat',\n '--ext-diff',\n '--textconv',\n '--quiet',\n '--submodule',\n] as const;\nconst STRUCTURED_SEARCH_INCOMPATIBLE_OPTIONS = [\n '--json',\n '--null',\n '--null-data',\n '--color',\n '--colour',\n '--after-context',\n '--before-context',\n '--context',\n '--no-filename',\n '--no-line-number',\n '--heading',\n] as const;\nconst PACKAGE_BY_PLATFORM: Readonly<Record<string, string>> = {\n 'darwin-arm64': '@agimon-ai/po-runner-rtk-darwin-arm64',\n 'darwin-x64': '@agimon-ai/po-runner-rtk-darwin-x64',\n 'linux-arm64': '@agimon-ai/po-runner-rtk-linux-arm64',\n 'linux-x64': '@agimon-ai/po-runner-rtk-linux-x64',\n};\n\ntype BinaryResolver = () => string | undefined;\n\nexport class RtkProcessor implements IRtkProcessor {\n /**\n * Latched once a binary proves unrunnable on this host.\n *\n * A glibc build installed on a musl host satisfies os and cpu, so it\n * resolves and then fails to exec. Without this the same poed spawn is\n * paid on every command, and each one is reported as a processing failure\n * rather than the absence it actually is.\n */\n private unrunnable = false;\n\n constructor(\n private readonly resolveBinary: BinaryResolver = bundledBinary,\n private readonly timeoutMs = DEFAULT_RTK_TIMEOUT_MS,\n private readonly env: Readonly<Record<string, string | undefined>> = process.env,\n private readonly settings?: RunnerSettings,\n ) {}\n\n async process(request: RtkProcessRequest): Promise<RtkProcessResult> {\n const filter = classifyRtkFilter(request.command);\n if (!filter) return { kind: 'skipped' };\n\n let inputBytes: number;\n try {\n inputBytes = fs.statSync(request.logPath).size;\n } catch {\n return { kind: 'fallback', warning: RTK_FAILED_WARNING };\n }\n if (inputBytes > RTK_STDIN_MAX_BYTES) return { kind: 'fallback', warning: RTK_OVERSIZED_WARNING };\n\n if (this.unrunnable) return { kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING };\n\n let binary: string | undefined;\n try {\n binary = this.resolveBinary === bundledBinary ? bundledBinary(this.env) : this.resolveBinary();\n if (!binary) return { kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING };\n if ((fs.statSync(binary).mode & 0o111) === 0) fs.chmodSync(binary, EXECUTABLE_MODE);\n } catch {\n return { kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING };\n }\n\n return this.pipe(binary, filter, request.logPath, inputBytes);\n }\n\n private pipe(binary: string, filter: RtkFilter, logPath: string, inputBytes: number): Promise<RtkProcessResult> {\n return new Promise((resolve) => {\n let child: ChildProcessWithoutNullStreams;\n try {\n child = spawn(binary, ['pipe', '-f', filter], { stdio: 'pipe' });\n } catch {\n this.unrunnable = true;\n resolve({ kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING });\n return;\n }\n\n const input = fs.createReadStream(logPath);\n const outputLimit = getResultMaxBytes(this.env, this.settings) * OUTPUT_BUFFER_FACTOR;\n let head: Buffer<ArrayBufferLike> = Buffer.alloc(0);\n let output: Buffer<ArrayBufferLike> = Buffer.alloc(0);\n let outputBytes = 0;\n let newlineCount = 0;\n let lastByte: number | undefined;\n let settled = false;\n let fallbackWarning: string | undefined;\n let killWaitTimer: ReturnType<typeof setTimeout> | undefined;\n\n const finish = (result: RtkProcessResult): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n if (killWaitTimer) clearTimeout(killWaitTimer);\n input.destroy();\n resolve(result);\n };\n const stop = (warning: string): void => {\n if (settled) return;\n fallbackWarning = warning;\n let killed = false;\n try {\n killed = child.kill('SIGKILL');\n } catch {\n finish({ kind: 'fallback', warning });\n return;\n }\n if (!killed) {\n finish({ kind: 'fallback', warning });\n return;\n }\n killWaitTimer ??= setTimeout(() => finish({ kind: 'fallback', warning }), RTK_KILL_WAIT_MS);\n };\n const timer = setTimeout(() => stop(RTK_TIMEOUT_WARNING), this.timeoutMs);\n\n child.stdout.on('data', (chunk: Buffer) => {\n outputBytes += chunk.byteLength;\n for (const byte of chunk) if (byte === 0x0a) newlineCount += 1;\n lastByte = chunk.at(-1);\n if (head.byteLength < outputLimit) {\n head = Buffer.concat([head, chunk.subarray(0, outputLimit - head.byteLength)]);\n }\n output = appendTail(output, chunk, outputLimit);\n });\n child.stderr.resume();\n child.once('error', (error: NodeJS.ErrnoException) => {\n // Reaching the process is a precondition, not part of processing, so a\n // failure to start reports absence and is not attempted again.\n if (error.code === 'ENOENT' || error.code === 'EACCES' || error.code === 'ENOEXEC') {\n this.unrunnable = true;\n stop(RTK_UNAVAILABLE_WARNING);\n return;\n }\n stop(RTK_FAILED_WARNING);\n });\n child.stdin.once('error', () => stop(RTK_FAILED_WARNING));\n input.once('error', () => stop(RTK_FAILED_WARNING));\n child.once('close', (code) => {\n if (fallbackWarning) {\n finish({ kind: 'fallback', warning: fallbackWarning });\n return;\n }\n const processedOutput = decodeUtf8Tail(output);\n if (code !== 0 || (inputBytes > 0 && processedOutput.trim().length === 0)) {\n finish({ kind: 'fallback', warning: RTK_FAILED_WARNING });\n return;\n }\n const lines = newlineCount + (outputBytes > 0 && lastByte !== 0x0a ? 1 : 0);\n finish({\n kind: 'processed',\n result: {\n filter,\n // Only meaningful once the stream outgrew the buffer; below that\n // `output` already starts at byte zero.\n head: outputBytes > output.byteLength ? head.toString('utf8') : '',\n output: processedOutput,\n bytes: outputBytes,\n lines,\n },\n });\n });\n\n input.pipe(child.stdin);\n });\n }\n}\n\n/**\n * Classifies only whitespace-delimited single commands. Shell syntax, expansion,\n * quoting, and globbing are rejected instead of being partially interpreted.\n */\nexport function classifyRtkFilter(command: string): RtkFilter | undefined {\n if (SHELL_CONTROL_PATTERN.test(command)) return undefined;\n const trimmed = command.trim();\n if (!trimmed) return undefined;\n const tokens = trimmed.split(/[ \\t]+/u);\n if (tokens.some((token) => !SIMPLE_TOKEN_PATTERN.test(token))) return undefined;\n\n if (tokens[0] === 'cargo' && tokens[1] === 'test') {\n if (tokens.includes('--') || tokens.some((token) => token.startsWith('--message-format') || token === '--json')) {\n return undefined;\n }\n return 'cargo-test';\n }\n if (tokens[0] === 'pytest') {\n if (tokens.some((token) => token.startsWith('--json-report'))) return undefined;\n return 'pytest';\n }\n if (tokens[0] === 'git' && tokens[1] === 'diff') {\n if (\n tokens.some((token) =>\n GIT_DIFF_INCOMPATIBLE_OPTIONS.some((option) => token === option || token.startsWith(`${option}=`)),\n )\n ) {\n return undefined;\n }\n return 'git-diff';\n }\n if (tokens[0] === 'grep') {\n if (tokens.length < 4 || incompatibleStructuredSearch(tokens)) return undefined;\n return hasShortOrLongOption(tokens, 'n', '--line-number') && hasShortOrLongOption(tokens, 'H', '--with-filename')\n ? 'grep'\n : undefined;\n }\n if (tokens[0] === 'rg') {\n if (tokens.length < 4 || incompatibleStructuredSearch(tokens) || !tokens.includes('--no-heading')) return undefined;\n return hasShortOrLongOption(tokens, 'n', '--line-number') && hasShortOrLongOption(tokens, 'H', '--with-filename')\n ? 'grep'\n : undefined;\n }\n if (tokens[0] === 'go' && tokens[1] === 'test') {\n let jsonOutput = false;\n for (const token of tokens.slice(2)) {\n if (token === '-json' || token === '-json=true') jsonOutput = true;\n if (token === '-json=false') jsonOutput = false;\n }\n return jsonOutput ? 'go-test' : undefined;\n }\n if (tokens[0] === 'ruff' && tokens[1] === 'check') {\n const jsonOutput = tokens.some(\n (token, index) =>\n token === '--output-format=json' || (token === '--output-format' && tokens[index + 1] === 'json'),\n );\n return jsonOutput ? 'ruff-check' : undefined;\n }\n return undefined;\n}\n\nexport function rtkPackageForTarget(platform: string, architecture: string): string | undefined {\n const target = `${platform}-${architecture}`;\n const packageName = PACKAGE_BY_PLATFORM[target];\n if (!packageName) process.emitWarning(`Bundled RTK binary is unavailable for unsupported target ${target}`);\n return packageName;\n}\n\nfunction bundledBinary(env: Readonly<Record<string, string | undefined>> = process.env): string | undefined {\n const configured = env[RTK_BINARY_ENV];\n if (configured !== undefined && configured !== '') return configured;\n const packageName = rtkPackageForTarget(process.platform, process.arch);\n if (!packageName) return undefined;\n try {\n const require = createRequire(import.meta.url);\n const manifest = require.resolve(`${packageName}/package.json`);\n return path.join(path.dirname(manifest), 'vendor', 'bin', 'rtk');\n } catch {\n return undefined;\n }\n}\n\nfunction appendTail(\n current: Buffer<ArrayBufferLike>,\n chunk: Buffer<ArrayBufferLike>,\n limit: number,\n): Buffer<ArrayBufferLike> {\n if (chunk.byteLength >= limit) return Buffer.from(chunk.subarray(chunk.byteLength - limit));\n const combined = Buffer.concat([current, chunk]);\n return combined.byteLength > limit ? Buffer.from(combined.subarray(combined.byteLength - limit)) : combined;\n}\n\nfunction decodeUtf8Tail(output: Buffer<ArrayBufferLike>): string {\n let start = 0;\n while (start < output.byteLength && (output[start]! & 0xc0) === 0x80) start += 1;\n return output.subarray(start).toString('utf8');\n}\nfunction hasShortOrLongOption(tokens: readonly string[], short: string, long: string): boolean {\n return tokens.some(\n (token) => token === long || (token.startsWith('-') && !token.startsWith('--') && token.slice(1).includes(short)),\n );\n}\n\nfunction incompatibleStructuredSearch(tokens: readonly string[]): boolean {\n return tokens.some(\n (token) =>\n (token.startsWith('-') && !token.startsWith('--') && /[0ABCILNchzZ]/u.test(token.slice(1))) ||\n STRUCTURED_SEARCH_INCOMPATIBLE_OPTIONS.some((option) => token === option || token.startsWith(`${option}=`)),\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rtkProcessor-xwARIxhe.cjs","names":["fs","RTK_FAILED_WARNING","RTK_OVERSIZED_WARNING","RTK_UNAVAILABLE_WARNING","spawn","getResultMaxBytes","RTK_TIMEOUT_WARNING","createRequire","path"],"sources":["../src/constants/rtkProcessor.ts","../src/services/rtkProcessor/index.ts"],"sourcesContent":["export const BYTES_PER_MIB = 1_048_576;\nexport const RTK_STDIN_MAX_BYTES = 10_485_760;\nexport const DEFAULT_RTK_TIMEOUT_MS = 10_000;\nexport const RTK_KILL_WAIT_MS = 1_000;\nexport const OUTPUT_BUFFER_FACTOR = 2;\nexport const EXECUTABLE_MODE = 0o755;\nexport const SIMPLE_TOKEN_PATTERN = /^[A-Za-z0-9_./:@%+=,-]+$/u;\nexport const SHELL_CONTROL_PATTERN = /[\\r\\n;&|<>`$\\\\'\"(){}*?!]/u;\nexport const RTK_BINARY_ENV = 'PO_RTK_BINARY';\n","import { type ChildProcessWithoutNullStreams, spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport {\n DEFAULT_RTK_TIMEOUT_MS,\n EXECUTABLE_MODE,\n OUTPUT_BUFFER_FACTOR,\n RTK_BINARY_ENV,\n RTK_KILL_WAIT_MS,\n RTK_STDIN_MAX_BYTES,\n SHELL_CONTROL_PATTERN,\n SIMPLE_TOKEN_PATTERN,\n} from '../../constants/rtkProcessor';\nimport {\n type IRtkProcessor,\n RTK_FAILED_WARNING,\n RTK_OVERSIZED_WARNING,\n RTK_TIMEOUT_WARNING,\n RTK_UNAVAILABLE_WARNING,\n type RtkFilter,\n type RtkProcessRequest,\n type RtkProcessResult,\n} from '../../types/rtkProcessor';\nimport type { RunnerSettings } from '../../types/runnerSettings';\nimport { getResultMaxBytes } from '../runnerConfig';\n\nconst GIT_DIFF_INCOMPATIBLE_OPTIONS = [\n '-s',\n '-z',\n '--raw',\n '--numstat',\n '--shortstat',\n '--stat',\n '--dirstat',\n '--dirstat-by-file',\n '--summary',\n '--compact-summary',\n '--name-only',\n '--name-status',\n '--check',\n '--binary',\n '--word-diff',\n '--word-diff-regex',\n '--color',\n '--color-words',\n '--color-moved',\n '--color-moved-ws',\n '--line-prefix',\n '--no-patch',\n '--patch-with-raw',\n '--patch-with-stat',\n '--ext-diff',\n '--textconv',\n '--quiet',\n '--submodule',\n] as const;\nconst STRUCTURED_SEARCH_INCOMPATIBLE_OPTIONS = [\n '--json',\n '--null',\n '--null-data',\n '--color',\n '--colour',\n '--after-context',\n '--before-context',\n '--context',\n '--no-filename',\n '--no-line-number',\n '--heading',\n] as const;\nconst PACKAGE_BY_PLATFORM: Readonly<Record<string, string>> = {\n 'darwin-arm64': '@agimon-ai/po-runner-rtk-darwin-arm64',\n 'darwin-x64': '@agimon-ai/po-runner-rtk-darwin-x64',\n 'linux-arm64': '@agimon-ai/po-runner-rtk-linux-arm64',\n 'linux-x64': '@agimon-ai/po-runner-rtk-linux-x64',\n};\n\ntype BinaryResolver = () => string | undefined;\n\nexport class RtkProcessor implements IRtkProcessor {\n /**\n * Latched once a binary proves unrunnable on this host.\n *\n * A glibc build installed on a musl host satisfies os and cpu, so it\n * resolves and then fails to exec. Without this the same poed spawn is\n * paid on every command, and each one is reported as a processing failure\n * rather than the absence it actually is.\n */\n private unrunnable = false;\n\n constructor(\n private readonly resolveBinary: BinaryResolver = bundledBinary,\n private readonly timeoutMs = DEFAULT_RTK_TIMEOUT_MS,\n private readonly env: Readonly<Record<string, string | undefined>> = process.env,\n private readonly settings?: RunnerSettings,\n ) {}\n\n async process(request: RtkProcessRequest): Promise<RtkProcessResult> {\n const filter = classifyRtkFilter(request.command);\n if (!filter) return { kind: 'skipped' };\n\n let inputBytes: number;\n try {\n inputBytes = fs.statSync(request.logPath).size;\n } catch {\n return { kind: 'fallback', warning: RTK_FAILED_WARNING };\n }\n if (inputBytes > RTK_STDIN_MAX_BYTES) return { kind: 'fallback', warning: RTK_OVERSIZED_WARNING };\n\n if (this.unrunnable) return { kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING };\n\n let binary: string | undefined;\n try {\n binary = this.resolveBinary === bundledBinary ? bundledBinary(this.env) : this.resolveBinary();\n if (!binary) return { kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING };\n if ((fs.statSync(binary).mode & 0o111) === 0) fs.chmodSync(binary, EXECUTABLE_MODE);\n } catch {\n return { kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING };\n }\n\n return this.pipe(binary, filter, request.logPath, inputBytes);\n }\n\n private pipe(binary: string, filter: RtkFilter, logPath: string, inputBytes: number): Promise<RtkProcessResult> {\n return new Promise((resolve) => {\n let child: ChildProcessWithoutNullStreams;\n try {\n child = spawn(binary, ['pipe', '-f', filter], { stdio: 'pipe' });\n } catch {\n this.unrunnable = true;\n resolve({ kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING });\n return;\n }\n\n const input = fs.createReadStream(logPath);\n const outputLimit = getResultMaxBytes(this.env, this.settings) * OUTPUT_BUFFER_FACTOR;\n let head: Buffer<ArrayBufferLike> = Buffer.alloc(0);\n let output: Buffer<ArrayBufferLike> = Buffer.alloc(0);\n let outputBytes = 0;\n let newlineCount = 0;\n let lastByte: number | undefined;\n let settled = false;\n let fallbackWarning: string | undefined;\n let killWaitTimer: ReturnType<typeof setTimeout> | undefined;\n\n const finish = (result: RtkProcessResult): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n if (killWaitTimer) clearTimeout(killWaitTimer);\n input.destroy();\n resolve(result);\n };\n const stop = (warning: string): void => {\n if (settled) return;\n fallbackWarning = warning;\n let killed = false;\n try {\n killed = child.kill('SIGKILL');\n } catch {\n finish({ kind: 'fallback', warning });\n return;\n }\n if (!killed) {\n finish({ kind: 'fallback', warning });\n return;\n }\n killWaitTimer ??= setTimeout(() => finish({ kind: 'fallback', warning }), RTK_KILL_WAIT_MS);\n };\n const timer = setTimeout(() => stop(RTK_TIMEOUT_WARNING), this.timeoutMs);\n\n child.stdout.on('data', (chunk: Buffer) => {\n outputBytes += chunk.byteLength;\n for (const byte of chunk) if (byte === 0x0a) newlineCount += 1;\n lastByte = chunk.at(-1);\n if (head.byteLength < outputLimit) {\n head = Buffer.concat([head, chunk.subarray(0, outputLimit - head.byteLength)]);\n }\n output = appendTail(output, chunk, outputLimit);\n });\n child.stderr.resume();\n child.once('error', (error: NodeJS.ErrnoException) => {\n // Reaching the process is a precondition, not part of processing, so a\n // failure to start reports absence and is not attempted again.\n if (error.code === 'ENOENT' || error.code === 'EACCES' || error.code === 'ENOEXEC') {\n this.unrunnable = true;\n stop(RTK_UNAVAILABLE_WARNING);\n return;\n }\n stop(RTK_FAILED_WARNING);\n });\n child.stdin.once('error', () => stop(RTK_FAILED_WARNING));\n input.once('error', () => stop(RTK_FAILED_WARNING));\n child.once('close', (code) => {\n if (fallbackWarning) {\n finish({ kind: 'fallback', warning: fallbackWarning });\n return;\n }\n const processedOutput = decodeUtf8Tail(output);\n if (code !== 0 || (inputBytes > 0 && processedOutput.trim().length === 0)) {\n finish({ kind: 'fallback', warning: RTK_FAILED_WARNING });\n return;\n }\n const lines = newlineCount + (outputBytes > 0 && lastByte !== 0x0a ? 1 : 0);\n finish({\n kind: 'processed',\n result: {\n filter,\n // Only meaningful once the stream outgrew the buffer; below that\n // `output` already starts at byte zero.\n head: outputBytes > output.byteLength ? head.toString('utf8') : '',\n output: processedOutput,\n bytes: outputBytes,\n lines,\n },\n });\n });\n\n input.pipe(child.stdin);\n });\n }\n}\n\n/**\n * Classifies only whitespace-delimited single commands. Shell syntax, expansion,\n * quoting, and globbing are rejected instead of being partially interpreted.\n */\nexport function classifyRtkFilter(command: string): RtkFilter | undefined {\n if (SHELL_CONTROL_PATTERN.test(command)) return undefined;\n const trimmed = command.trim();\n if (!trimmed) return undefined;\n const tokens = trimmed.split(/[ \\t]+/u);\n if (tokens.some((token) => !SIMPLE_TOKEN_PATTERN.test(token))) return undefined;\n\n if (tokens[0] === 'cargo' && tokens[1] === 'test') {\n if (tokens.includes('--') || tokens.some((token) => token.startsWith('--message-format') || token === '--json')) {\n return undefined;\n }\n return 'cargo-test';\n }\n if (tokens[0] === 'pytest') {\n if (tokens.some((token) => token.startsWith('--json-report'))) return undefined;\n return 'pytest';\n }\n if (tokens[0] === 'git' && tokens[1] === 'diff') {\n if (\n tokens.some((token) =>\n GIT_DIFF_INCOMPATIBLE_OPTIONS.some((option) => token === option || token.startsWith(`${option}=`)),\n )\n ) {\n return undefined;\n }\n return 'git-diff';\n }\n if (tokens[0] === 'grep') {\n if (tokens.length < 4 || incompatibleStructuredSearch(tokens)) return undefined;\n return hasShortOrLongOption(tokens, 'n', '--line-number') && hasShortOrLongOption(tokens, 'H', '--with-filename')\n ? 'grep'\n : undefined;\n }\n if (tokens[0] === 'rg') {\n if (tokens.length < 4 || incompatibleStructuredSearch(tokens) || !tokens.includes('--no-heading')) return undefined;\n return hasShortOrLongOption(tokens, 'n', '--line-number') && hasShortOrLongOption(tokens, 'H', '--with-filename')\n ? 'grep'\n : undefined;\n }\n if (tokens[0] === 'go' && tokens[1] === 'test') {\n let jsonOutput = false;\n for (const token of tokens.slice(2)) {\n if (token === '-json' || token === '-json=true') jsonOutput = true;\n if (token === '-json=false') jsonOutput = false;\n }\n return jsonOutput ? 'go-test' : undefined;\n }\n if (tokens[0] === 'ruff' && tokens[1] === 'check') {\n const jsonOutput = tokens.some(\n (token, index) =>\n token === '--output-format=json' || (token === '--output-format' && tokens[index + 1] === 'json'),\n );\n return jsonOutput ? 'ruff-check' : undefined;\n }\n return undefined;\n}\n\nexport function rtkPackageForTarget(platform: string, architecture: string): string | undefined {\n const target = `${platform}-${architecture}`;\n const packageName = PACKAGE_BY_PLATFORM[target];\n if (!packageName) process.emitWarning(`Bundled RTK binary is unavailable for unsupported target ${target}`);\n return packageName;\n}\n\nfunction bundledBinary(env: Readonly<Record<string, string | undefined>> = process.env): string | undefined {\n const configured = env[RTK_BINARY_ENV];\n if (configured !== undefined && configured !== '') return configured;\n const packageName = rtkPackageForTarget(process.platform, process.arch);\n if (!packageName) return undefined;\n try {\n const require = createRequire(import.meta.url);\n const manifest = require.resolve(`${packageName}/package.json`);\n return path.join(path.dirname(manifest), 'vendor', 'bin', 'rtk');\n } catch {\n return undefined;\n }\n}\n\nfunction appendTail(\n current: Buffer<ArrayBufferLike>,\n chunk: Buffer<ArrayBufferLike>,\n limit: number,\n): Buffer<ArrayBufferLike> {\n if (chunk.byteLength >= limit) return Buffer.from(chunk.subarray(chunk.byteLength - limit));\n const combined = Buffer.concat([current, chunk]);\n return combined.byteLength > limit ? Buffer.from(combined.subarray(combined.byteLength - limit)) : combined;\n}\n\nfunction decodeUtf8Tail(output: Buffer<ArrayBufferLike>): string {\n let start = 0;\n while (start < output.byteLength && (output[start]! & 0xc0) === 0x80) start += 1;\n return output.subarray(start).toString('utf8');\n}\nfunction hasShortOrLongOption(tokens: readonly string[], short: string, long: string): boolean {\n return tokens.some(\n (token) => token === long || (token.startsWith('-') && !token.startsWith('--') && token.slice(1).includes(short)),\n );\n}\n\nfunction incompatibleStructuredSearch(tokens: readonly string[]): boolean {\n return tokens.some(\n (token) =>\n (token.startsWith('-') && !token.startsWith('--') && /[0ABCILNchzZ]/u.test(token.slice(1))) ||\n STRUCTURED_SEARCH_INCOMPATIBLE_OPTIONS.some((option) => token === option || token.startsWith(`${option}=`)),\n );\n}\n"],"mappings":";;;;;;;;;;AACA,MAAa,sBAAsB;AACnC,MAAa,yBAAyB;AACtC,MAAa,mBAAmB;AAGhC,MAAa,uBAAuB;AACpC,MAAa,wBAAwB;AACrC,MAAa,iBAAiB;;;ACoB9B,MAAM,gCAAgC;CACpC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AACA,MAAM,yCAAyC;CAC7C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AACA,MAAM,sBAAwD;CAC5D,gBAAgB;CAChB,cAAc;CACd,eAAe;CACf,aAAa;AACf;AAIA,IAAa,eAAb,MAAmD;CAY9B;CACA;CACA;CACA;;;;;;;;;CANnB,aAAqB;CAErB,YACE,gBAAiD,eACjD,YAA6B,wBAC7B,MAAqE,QAAQ,KAC7E,UACA;EAJiB,KAAA,gBAAA;EACA,KAAA,YAAA;EACA,KAAA,MAAA;EACA,KAAA,WAAA;CAChB;CAEH,MAAM,QAAQ,SAAuD;EACnE,MAAM,SAAS,kBAAkB,QAAQ,OAAO;EAChD,IAAI,CAAC,QAAQ,OAAO,EAAE,MAAM,UAAU;EAEtC,IAAI;EACJ,IAAI;GACF,aAAaA,QAAAA,QAAG,SAAS,QAAQ,OAAO,CAAC,CAAC;EAC5C,QAAQ;GACN,OAAO;IAAE,MAAM;IAAY,SAASC,qBAAAA;GAAmB;EACzD;EACA,IAAI,aAAA,UAAkC,OAAO;GAAE,MAAM;GAAY,SAASC,qBAAAA;EAAsB;EAEhG,IAAI,KAAK,YAAY,OAAO;GAAE,MAAM;GAAY,SAASC,qBAAAA;EAAwB;EAEjF,IAAI;EACJ,IAAI;GACF,SAAS,KAAK,kBAAkB,gBAAgB,cAAc,KAAK,GAAG,IAAI,KAAK,cAAc;GAC7F,IAAI,CAAC,QAAQ,OAAO;IAAE,MAAM;IAAY,SAASA,qBAAAA;GAAwB;GACzE,KAAKH,QAAAA,QAAG,SAAS,MAAM,CAAC,CAAC,OAAO,QAAW,GAAG,QAAA,QAAG,UAAU,QAAA,GAAuB;EACpF,QAAQ;GACN,OAAO;IAAE,MAAM;IAAY,SAASG,qBAAAA;GAAwB;EAC9D;EAEA,OAAO,KAAK,KAAK,QAAQ,QAAQ,QAAQ,SAAS,UAAU;CAC9D;CAEA,KAAa,QAAgB,QAAmB,SAAiB,YAA+C;EAC9G,OAAO,IAAI,SAAS,YAAY;GAC9B,IAAI;GACJ,IAAI;IACF,SAAA,GAAQC,mBAAAA,MAAAA,CAAM,QAAQ;KAAC;KAAQ;KAAM;IAAM,GAAG,EAAE,OAAO,OAAO,CAAC;GACjE,QAAQ;IACN,KAAK,aAAa;IAClB,QAAQ;KAAE,MAAM;KAAY,SAASD,qBAAAA;IAAwB,CAAC;IAC9D;GACF;GAEA,MAAM,QAAQH,QAAAA,QAAG,iBAAiB,OAAO;GACzC,MAAM,cAAcK,qBAAAA,kBAAkB,KAAK,KAAK,KAAK,QAAQ,IAAA;GAC7D,IAAI,OAAgC,OAAO,MAAM,CAAC;GAClD,IAAI,SAAkC,OAAO,MAAM,CAAC;GACpD,IAAI,cAAc;GAClB,IAAI,eAAe;GACnB,IAAI;GACJ,IAAI,UAAU;GACd,IAAI;GACJ,IAAI;GAEJ,MAAM,UAAU,WAAmC;IACjD,IAAI,SAAS;IACb,UAAU;IACV,aAAa,KAAK;IAClB,IAAI,eAAe,aAAa,aAAa;IAC7C,MAAM,QAAQ;IACd,QAAQ,MAAM;GAChB;GACA,MAAM,QAAQ,YAA0B;IACtC,IAAI,SAAS;IACb,kBAAkB;IAClB,IAAI,SAAS;IACb,IAAI;KACF,SAAS,MAAM,KAAK,SAAS;IAC/B,QAAQ;KACN,OAAO;MAAE,MAAM;MAAY;KAAQ,CAAC;KACpC;IACF;IACA,IAAI,CAAC,QAAQ;KACX,OAAO;MAAE,MAAM;MAAY;KAAQ,CAAC;KACpC;IACF;IACA,kBAAkB,iBAAiB,OAAO;KAAE,MAAM;KAAY;IAAQ,CAAC,GAAG,gBAAgB;GAC5F;GACA,MAAM,QAAQ,iBAAiB,KAAKC,qBAAAA,mBAAmB,GAAG,KAAK,SAAS;GAExE,MAAM,OAAO,GAAG,SAAS,UAAkB;IACzC,eAAe,MAAM;IACrB,KAAK,MAAM,QAAQ,OAAO,IAAI,SAAS,IAAM,gBAAgB;IAC7D,WAAW,MAAM,GAAG,EAAE;IACtB,IAAI,KAAK,aAAa,aACpB,OAAO,OAAO,OAAO,CAAC,MAAM,MAAM,SAAS,GAAG,cAAc,KAAK,UAAU,CAAC,CAAC;IAE/E,SAAS,WAAW,QAAQ,OAAO,WAAW;GAChD,CAAC;GACD,MAAM,OAAO,OAAO;GACpB,MAAM,KAAK,UAAU,UAAiC;IAGpD,IAAI,MAAM,SAAS,YAAY,MAAM,SAAS,YAAY,MAAM,SAAS,WAAW;KAClF,KAAK,aAAa;KAClB,KAAKH,qBAAAA,uBAAuB;KAC5B;IACF;IACA,KAAKF,qBAAAA,kBAAkB;GACzB,CAAC;GACD,MAAM,MAAM,KAAK,eAAe,KAAKA,qBAAAA,kBAAkB,CAAC;GACxD,MAAM,KAAK,eAAe,KAAKA,qBAAAA,kBAAkB,CAAC;GAClD,MAAM,KAAK,UAAU,SAAS;IAC5B,IAAI,iBAAiB;KACnB,OAAO;MAAE,MAAM;MAAY,SAAS;KAAgB,CAAC;KACrD;IACF;IACA,MAAM,kBAAkB,eAAe,MAAM;IAC7C,IAAI,SAAS,KAAM,aAAa,KAAK,gBAAgB,KAAK,CAAC,CAAC,WAAW,GAAI;KACzE,OAAO;MAAE,MAAM;MAAY,SAASA,qBAAAA;KAAmB,CAAC;KACxD;IACF;IACA,MAAM,QAAQ,gBAAgB,cAAc,KAAK,aAAa,KAAO,IAAI;IACzE,OAAO;KACL,MAAM;KACN,QAAQ;MACN;MAGA,MAAM,cAAc,OAAO,aAAa,KAAK,SAAS,MAAM,IAAI;MAChE,QAAQ;MACR,OAAO;MACP;KACF;IACF,CAAC;GACH,CAAC;GAED,MAAM,KAAK,MAAM,KAAK;EACxB,CAAC;CACH;AACF;;;;;AAMA,SAAgB,kBAAkB,SAAwC;CACxE,IAAI,sBAAsB,KAAK,OAAO,GAAG,OAAO,KAAA;CAChD,MAAM,UAAU,QAAQ,KAAK;CAC7B,IAAI,CAAC,SAAS,OAAO,KAAA;CACrB,MAAM,SAAS,QAAQ,MAAM,SAAS;CACtC,IAAI,OAAO,MAAM,UAAU,CAAC,qBAAqB,KAAK,KAAK,CAAC,GAAG,OAAO,KAAA;CAEtE,IAAI,OAAO,OAAO,WAAW,OAAO,OAAO,QAAQ;EACjD,IAAI,OAAO,SAAS,IAAI,KAAK,OAAO,MAAM,UAAU,MAAM,WAAW,kBAAkB,KAAK,UAAU,QAAQ,GAC5G;EAEF,OAAO;CACT;CACA,IAAI,OAAO,OAAO,UAAU;EAC1B,IAAI,OAAO,MAAM,UAAU,MAAM,WAAW,eAAe,CAAC,GAAG,OAAO,KAAA;EACtE,OAAO;CACT;CACA,IAAI,OAAO,OAAO,SAAS,OAAO,OAAO,QAAQ;EAC/C,IACE,OAAO,MAAM,UACX,8BAA8B,MAAM,WAAW,UAAU,UAAU,MAAM,WAAW,GAAG,OAAO,EAAE,CAAC,CACnG,GAEA;EAEF,OAAO;CACT;CACA,IAAI,OAAO,OAAO,QAAQ;EACxB,IAAI,OAAO,SAAS,KAAK,6BAA6B,MAAM,GAAG,OAAO,KAAA;EACtE,OAAO,qBAAqB,QAAQ,KAAK,eAAe,KAAK,qBAAqB,QAAQ,KAAK,iBAAiB,IAC5G,SACA,KAAA;CACN;CACA,IAAI,OAAO,OAAO,MAAM;EACtB,IAAI,OAAO,SAAS,KAAK,6BAA6B,MAAM,KAAK,CAAC,OAAO,SAAS,cAAc,GAAG,OAAO,KAAA;EAC1G,OAAO,qBAAqB,QAAQ,KAAK,eAAe,KAAK,qBAAqB,QAAQ,KAAK,iBAAiB,IAC5G,SACA,KAAA;CACN;CACA,IAAI,OAAO,OAAO,QAAQ,OAAO,OAAO,QAAQ;EAC9C,IAAI,aAAa;EACjB,KAAK,MAAM,SAAS,OAAO,MAAM,CAAC,GAAG;GACnC,IAAI,UAAU,WAAW,UAAU,cAAc,aAAa;GAC9D,IAAI,UAAU,eAAe,aAAa;EAC5C;EACA,OAAO,aAAa,YAAY,KAAA;CAClC;CACA,IAAI,OAAO,OAAO,UAAU,OAAO,OAAO,SAKxC,OAJmB,OAAO,MACvB,OAAO,UACN,UAAU,0BAA2B,UAAU,qBAAqB,OAAO,QAAQ,OAAO,MAE9E,IAAI,eAAe,KAAA;AAGvC;AAEA,SAAgB,oBAAoB,UAAkB,cAA0C;CAC9F,MAAM,SAAS,GAAG,SAAS,GAAG;CAC9B,MAAM,cAAc,oBAAoB;CACxC,IAAI,CAAC,aAAa,QAAQ,YAAY,4DAA4D,QAAQ;CAC1G,OAAO;AACT;AAEA,SAAS,cAAc,MAAoD,QAAQ,KAAyB;CAC1G,MAAM,aAAa,IAAI;CACvB,IAAI,eAAe,KAAA,KAAa,eAAe,IAAI,OAAO;CAC1D,MAAM,cAAc,oBAAoB,QAAQ,UAAU,QAAQ,IAAI;CACtE,IAAI,CAAC,aAAa,OAAO,KAAA;CACzB,IAAI;EAEF,MAAM,YAAA,GADUM,YAAAA,cAAAA,CAAAA,QAAAA,KAAAA,CAAAA,CAAAA,cAAAA,UAAAA,CAAAA,CAAAA,IACO,CAAC,CAAC,QAAQ,GAAG,YAAY,cAAc;EAC9D,OAAOC,UAAAA,QAAK,KAAKA,UAAAA,QAAK,QAAQ,QAAQ,GAAG,UAAU,OAAO,KAAK;CACjE,QAAQ;EACN;CACF;AACF;AAEA,SAAS,WACP,SACA,OACA,OACyB;CACzB,IAAI,MAAM,cAAc,OAAO,OAAO,OAAO,KAAK,MAAM,SAAS,MAAM,aAAa,KAAK,CAAC;CAC1F,MAAM,WAAW,OAAO,OAAO,CAAC,SAAS,KAAK,CAAC;CAC/C,OAAO,SAAS,aAAa,QAAQ,OAAO,KAAK,SAAS,SAAS,SAAS,aAAa,KAAK,CAAC,IAAI;AACrG;AAEA,SAAS,eAAe,QAAyC;CAC/D,IAAI,QAAQ;CACZ,OAAO,QAAQ,OAAO,eAAe,OAAO,SAAU,SAAU,KAAM,SAAS;CAC/E,OAAO,OAAO,SAAS,KAAK,CAAC,CAAC,SAAS,MAAM;AAC/C;AACA,SAAS,qBAAqB,QAA2B,OAAe,MAAuB;CAC7F,OAAO,OAAO,MACX,UAAU,UAAU,QAAS,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,WAAW,IAAI,KAAK,MAAM,MAAM,CAAC,CAAC,CAAC,SAAS,KAAK,CACjH;AACF;AAEA,SAAS,6BAA6B,QAAoC;CACxE,OAAO,OAAO,MACX,UACE,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,WAAW,IAAI,KAAK,iBAAiB,KAAK,MAAM,MAAM,CAAC,CAAC,KACzF,uCAAuC,MAAM,WAAW,UAAU,UAAU,MAAM,WAAW,GAAG,OAAO,EAAE,CAAC,CAC9G;AACF"}
|
package/dist/rtkProcessor.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_rtkProcessor = require("./rtkProcessor-CsrCPyTQ.cjs");
|
|
3
|
-
const require_rtkProcessor$1 = require("./rtkProcessor-
|
|
3
|
+
const require_rtkProcessor$1 = require("./rtkProcessor-xwARIxhe.cjs");
|
|
4
4
|
exports.RTK_FAILED_WARNING = require_rtkProcessor.RTK_FAILED_WARNING;
|
|
5
5
|
exports.RTK_OVERSIZED_WARNING = require_rtkProcessor.RTK_OVERSIZED_WARNING;
|
|
6
6
|
exports.RTK_STDIN_MAX_BYTES = require_rtkProcessor$1.RTK_STDIN_MAX_BYTES;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as BashRunService } from "./bashRunService-
|
|
1
|
+
import { t as BashRunService } from "./bashRunService-DbYsj1zc.mjs";
|
|
2
2
|
import { g as noninteractiveEnvironment, s as getLogMaxBytes, u as getResultMaxBytes } from "./runnerConfig-XXMq4VQA.mjs";
|
|
3
3
|
import { t as LogReader } from "./logReader-mq9uVurh.mjs";
|
|
4
4
|
import { t as SystemClock } from "./clock-Cv2pddgo.mjs";
|
|
@@ -644,4 +644,4 @@ function createRunnerDependencies(overrides) {
|
|
|
644
644
|
//#endregion
|
|
645
645
|
export { TmuxBackend as n, PtyBackendChain as r, createRunnerDependencies as t };
|
|
646
646
|
|
|
647
|
-
//# sourceMappingURL=runnerDependencies-
|
|
647
|
+
//# sourceMappingURL=runnerDependencies-CamKwphq.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runnerDependencies-7h_cxOva.mjs","names":[],"sources":["../src/constants/tmuxBackend.ts","../src/services/ptyBackendChain/index.ts","../src/services/tmuxBackend/TmuxClient.ts","../src/services/tmuxBackend/index.ts","../src/services/runnerDependencies/index.ts"],"sourcesContent":["export const POLL_MS = 100;\nexport const LOG_DRAIN_TIMEOUT_MS = 2_000;\nexport const LOG_DRAIN_POLL_MS = 25;\nexport const PANE_STATE_FORMAT = '#{pane_dead}:#{pane_dead_status}:#{session_name}';\nexport const STOP_GRACE_MS = 3_000;\nexport const SESSION_PREFIX = 'po-tmux-';\nexport const OWNED_TARGET_PATTERN = /^po-tmux-[A-Za-z0-9_-]+$/;\nexport const TMUX_TARGET_PREFIX = SESSION_PREFIX;\nexport const SOCKET_HASH_LENGTH = 12;\nexport const SOCKET_PREFIX = 'po-tmux-';\nexport const NON_INTERACTIVE_ENV = { NO_COLOR: '1', CI: '1' };\n","import { TMUX_TARGET_PREFIX } from '../../constants/tmuxBackend';\nimport type { RunHandle } from '../../types/launcher';\nimport type { PtyRun } from '../../types/ptyHost';\nimport type { IRmuxBackend, RmuxLaunchRequest } from '../../types/rmuxBackend';\nimport type { ExitResult } from '../../types/spawner';\n\n/**\n * Presents the available PTY backends as one, preferring RMUX.\n *\n * A launch takes the first backend that accepts it, so a host without a\n * compatible RMUX binary still gets panes rather than falling through to the\n * plain subprocess launcher. Every later call routes on the target's prefix\n * instead of asking each backend in turn: a backend cannot tell \"this session\n * is gone\" from \"this session was never mine\", and guessing would let one\n * report success for the other's run.\n */\nexport class PtyBackendChain implements IRmuxBackend {\n constructor(\n private readonly rmux: IRmuxBackend,\n private readonly tmux: IRmuxBackend,\n ) {}\n\n async launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined> {\n return (await this.rmux.launch(request)) ?? (await this.tmux.launch(request));\n }\n\n watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined> {\n return this.owner(target).watch(id, target, sessionId);\n }\n\n stop(target: string, expectedPid: number): Promise<boolean> {\n return this.owner(target).stop(target, expectedPid);\n }\n\n input(target: string, text: string): Promise<boolean> {\n return this.owner(target).input(target, text);\n }\n\n capture(target: string): Promise<string | undefined> {\n return this.owner(target).capture(target);\n }\n\n /** Both backends persist terminal evidence at the same path, so either answers. */\n readOutcome(id: string, sessionId: string): ExitResult | undefined {\n return this.rmux.readOutcome(id, sessionId) ?? this.tmux.readOutcome(id, sessionId);\n }\n\n get(name: string): PtyRun | undefined {\n return this.rmux.get(name) ?? this.tmux.get(name);\n }\n\n private owner(target: string): IRmuxBackend {\n return target.startsWith(TMUX_TARGET_PREFIX) ? this.tmux : this.rmux;\n }\n}\n","import { execFile } from 'node:child_process';\n\nimport type { ITmuxClient, TmuxResult } from '../../types/tmuxClient';\n\nconst TMUX_BINARY = 'tmux';\nconst SOCKET_OPTION = '-L';\n/** Long enough for a loaded server, short enough that a hung tmux is not fatal. */\nconst COMMAND_TIMEOUT_MS = 10_000;\nconst MAX_OUTPUT_BYTES = 4 * 1024 * 1024;\n\nexport class TmuxClient implements ITmuxClient {\n constructor(\n private readonly socket: string,\n private readonly binary = TMUX_BINARY,\n ) {}\n\n run(args: readonly string[]): Promise<TmuxResult> {\n return new Promise((resolve, reject) => {\n execFile(\n this.binary,\n [SOCKET_OPTION, this.socket, ...args],\n { timeout: COMMAND_TIMEOUT_MS, maxBuffer: MAX_OUTPUT_BYTES, encoding: 'utf8' },\n (error, stdout, stderr) => {\n // A non-zero tmux exit is an answer, not a fault: `has-session`\n // reports absence that way. Only a missing or hung binary rejects.\n const code = (error as (Error & { code?: number | string }) | null)?.code;\n if (error && typeof code !== 'number') {\n reject(error);\n return;\n }\n resolve({ returnCode: typeof code === 'number' ? code : 0, stdout, stderr });\n },\n );\n });\n }\n\n async format(target: string, format: string): Promise<string | undefined> {\n const result = await this.run(['display-message', '-p', '-t', target, '-F', format]).catch(() => undefined);\n if (!result || result.returnCode !== 0) return undefined;\n return result.stdout.replace(/\\n$/, '');\n }\n\n async sessionMissing(target: string): Promise<boolean> {\n const result = await this.run(['has-session', '-t', target]).catch(() => undefined);\n return !result || result.returnCode !== 0;\n }\n}\n","import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport {\n LOG_DRAIN_POLL_MS,\n LOG_DRAIN_TIMEOUT_MS,\n NON_INTERACTIVE_ENV,\n OWNED_TARGET_PATTERN,\n PANE_STATE_FORMAT,\n POLL_MS,\n SESSION_PREFIX,\n SOCKET_HASH_LENGTH,\n SOCKET_PREFIX,\n STOP_GRACE_MS,\n} from '../../constants/tmuxBackend';\nimport type { RunHandle } from '../../types/launcher';\nimport type { PtyRun } from '../../types/ptyHost';\nimport type { IRmuxBackend, RmuxLaunchRequest } from '../../types/rmuxBackend';\nimport type { RunnerSettings } from '../../types/runnerSettings';\nimport type { ExitResult } from '../../types/spawner';\nimport type { ITmuxClient } from '../../types/tmuxClient';\nimport { getLogMaxBytes, getResultMaxBytes, noninteractiveEnvironment } from '../runnerConfig';\nimport type { IRunnerPaths } from '../runnerPaths/type';\nimport {\n type CommandSpec,\n type SupervisorPaths,\n cleanupSupervisorFiles,\n NO_TERMINAL_INPUT_ENV,\n readExitMetadata,\n runtimeEntry,\n shellJoin,\n supervisorPaths,\n writeCommandSpec,\n} from '../runnerSupervisor';\nimport { TmuxClient } from './TmuxClient';\n\n/** Pane liveness, its exit status, and whether the session still exists, in one read. */\n/** Distinct from the RMUX prefix so a target names the backend that owns it. */\n\n/**\n * Supervises runs in tmux panes, for hosts with no compatible RMUX binary.\n *\n * The pane runs the same runnerHost supervisor as the RMUX backend, so exit\n * metadata, log rotation, and lifeline handling are shared rather than\n * reimplemented: only the multiplexer differs. Kept beside the RMUX backend\n * rather than folded into it because that path has no unit coverage to\n * refactor against.\n */\nexport class TmuxBackend implements IRmuxBackend {\n private clientPromise: Promise<ITmuxClient | undefined> | undefined;\n private readonly runs = new Map<string, PtyRun>();\n private readonly completions = new Map<string, Promise<ExitResult>>();\n\n constructor(\n private readonly paths: IRunnerPaths,\n private readonly createClient: (socket: string) => ITmuxClient = (socket) => new TmuxClient(socket),\n private readonly env: Readonly<Record<string, string | undefined>> = process.env,\n private readonly settings?: RunnerSettings,\n ) {}\n\n async launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined> {\n const tmux = await this.client();\n if (!tmux) return undefined;\n\n this.paths.ensureDirectories();\n const target = `${SESSION_PREFIX}${request.id}`;\n const logPath = this.paths.logPathFor(request.id);\n const aux = this.auxPaths(request.id, request.sessionId);\n let created = false;\n let released = false;\n\n try {\n this.prepareFiles(request, logPath, aux);\n // One quoted command rather than an argv: tmux takes shell-command as a\n // single word, and quoting here is what keeps a path with spaces intact.\n const supervisor = shellJoin([process.execPath, runtimeEntry('runnerHost'), aux.spec, aux.gate, aux.exit]);\n await this.checked(tmux, ['new-session', '-d', '-s', target, '-c', request.cwd, supervisor]);\n created = true;\n // Set before the gate opens, so it is in force by the time the command\n // can exit. A pane that vanishes on exit takes the log sink down with it\n // before Node has finished starting, losing the output of fast commands,\n // and leaves #{pane_dead} with nothing to report.\n await this.checked(tmux, ['set-option', '-t', target, 'remain-on-exit', 'on']);\n await this.checked(tmux, ['pipe-pane', '-t', target, this.logPipeCommand(logPath, aux.logDone, request)]);\n\n const pid = await panePid(tmux, target);\n fs.writeFileSync(aux.gate, '', { mode: 0o600 });\n released = true;\n\n let buffering = true;\n const completion = this.monitor(tmux, target, aux);\n this.trackCompletion(target, completion);\n const handle: RunHandle = {\n id: request.id,\n name: request.name,\n pid,\n logPath,\n backend: 'tmux',\n backendTarget: target,\n output: () => (buffering ? readTail(logPath, getResultMaxBytes(this.env, this.settings) * 2) : ''),\n completion: () => completion,\n detach: () => {\n buffering = false;\n },\n stop: () => this.stop(target, pid),\n };\n\n if (request.interactive) this.runs.set(request.name, this.interactiveRun(handle, tmux, target, completion));\n void completion\n .finally(() => this.runs.delete(request.name))\n .catch((error: unknown) => process.emitWarning(`tmux completion failed for ${target}: ${errorMessage(error)}`));\n return handle;\n } catch (error) {\n if (released) throw error;\n if (created) await killSession(tmux, target);\n cleanupSupervisorFiles(aux);\n process.emitWarning(\n request.interactive\n ? `tmux launch unavailable for interactive runner: ${errorMessage(error)}`\n : `tmux launch unavailable, using supervised subprocess: ${errorMessage(error)}`,\n );\n return undefined;\n }\n }\n\n async stop(target: string, expectedPid: number): Promise<boolean> {\n if (!OWNED_TARGET_PATTERN.test(target) || !Number.isInteger(expectedPid) || expectedPid <= 0) return false;\n\n const tmux = await this.client();\n if (!tmux) return false;\n try {\n if (await tmux.sessionMissing(target)) return true;\n\n const pid = await panePid(tmux, target);\n if (pid !== expectedPid) return false;\n const signalled = signalPane(pid, target);\n if (signalled === 'gone') return true;\n if (signalled === 'failed') return false;\n\n if (await waitForPaneStop(tmux, target, STOP_GRACE_MS)) return true;\n if (await tmux.sessionMissing(target)) return true;\n\n // Revalidate after the grace period so a replacement pane is never closed.\n const currentPid = await panePid(tmux, target).catch(() => undefined);\n if (currentPid !== expectedPid) return false;\n\n return killSession(tmux, target);\n } catch (error) {\n process.emitWarning(`Could not stop tmux target ${target}: ${errorMessage(error)}`);\n return false;\n }\n }\n\n async watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined> {\n const tmux = await this.client();\n if (!tmux) return undefined;\n if (await tmux.sessionMissing(target)) return undefined;\n const completion = this.monitor(tmux, target, this.auxPaths(id, sessionId));\n this.trackCompletion(target, completion);\n return completion;\n }\n\n async input(target: string, text: string): Promise<boolean> {\n const tmux = await this.client();\n if (!tmux) return false;\n const result = await tmux.run(['send-keys', '-t', target, '-l', text]).catch((error: unknown) => {\n process.emitWarning(`Could not send input to tmux target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result?.returnCode === 0;\n }\n\n async capture(target: string): Promise<string | undefined> {\n const tmux = await this.client();\n if (!tmux) return undefined;\n const result = await tmux.run(['capture-pane', '-p', '-t', target]).catch((error: unknown) => {\n process.emitWarning(`Could not capture tmux target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result?.returnCode === 0 ? result.stdout : undefined;\n }\n\n get(name: string): PtyRun | undefined {\n return this.runs.get(name);\n }\n\n readOutcome(id: string, sessionId: string): ExitResult | undefined {\n return readExitMetadata(this.auxPaths(id, sessionId).exit);\n }\n\n private trackCompletion(target: string, completion: Promise<ExitResult>): void {\n this.completions.set(target, completion);\n void completion\n .finally(() => this.completions.delete(target))\n .catch((error: unknown) => process.emitWarning(`tmux monitor failed for ${target}: ${errorMessage(error)}`));\n }\n\n private client(): Promise<ITmuxClient | undefined> {\n this.clientPromise ??= this.resolveClient();\n return this.clientPromise;\n }\n\n private async resolveClient(): Promise<ITmuxClient | undefined> {\n const client = this.createClient(socketName(this.paths.repositoryPath()));\n try {\n const version = await client.run(['-V']);\n if (version.returnCode !== 0) throw new Error(version.stderr.trim() || 'tmux reported no version');\n return client;\n } catch (error) {\n process.emitWarning(`tmux is unavailable: ${errorMessage(error)}`);\n return undefined;\n }\n }\n\n private async checked(tmux: ITmuxClient, args: readonly string[]): Promise<void> {\n const result = await tmux.run(args);\n if (result.returnCode !== 0) {\n throw new Error(`tmux ${args[0] ?? ''} failed: ${result.stderr.trim() || `exit ${result.returnCode}`}`);\n }\n }\n\n private prepareFiles(request: RmuxLaunchRequest, logPath: string, aux: SupervisorPaths): void {\n cleanupSupervisorFiles(aux);\n fs.writeFileSync(logPath, '', { mode: 0o600 });\n const env = environment(request.sessionId, request.interactive, this.env);\n const spec: CommandSpec = { command: request.command, cwd: request.cwd, env };\n writeCommandSpec(aux.spec, spec);\n }\n\n private auxPaths(id: string, sessionId?: string): SupervisorPaths {\n return supervisorPaths(this.paths.stateDirectory(sessionId), id);\n }\n\n /**\n * The sink the pane pipes into.\n *\n * An interactive run also asks for a raw copy: the scrubbed log it writes\n * beside it has had cursor movement taken out, which is what a terminal\n * needs most. Only interactive runs pay for it, because only they can be\n * attached to.\n */\n private logPipeCommand(logPath: string, donePath: string, request: RmuxLaunchRequest): string {\n const id = path.basename(logPath, '.log');\n return shellJoin([\n process.execPath,\n runtimeEntry('logSink'),\n logPath,\n this.paths.rotatedLogPathFor(id),\n String(getLogMaxBytes(this.env)),\n donePath,\n ...(request.interactive ? [this.paths.rawLogPathFor(id)] : []),\n ]);\n }\n\n private async monitor(tmux: ITmuxClient, target: string, aux: SupervisorPaths): Promise<ExitResult> {\n try {\n const paneCode = await waitForRunEnd(tmux, target, aux.exit);\n await waitForLogDrain(tmux, target, aux.logDone);\n return readExitMetadata(aux.exit) ?? { code: paneCode, signal: null };\n } finally {\n if (!(await tmux.sessionMissing(target).catch(() => false))) await killSession(tmux, target);\n cleanupSupervisorFiles(aux);\n }\n }\n\n private interactiveRun(\n handle: RunHandle,\n tmux: ITmuxClient,\n target: string,\n completion: Promise<ExitResult>,\n ): PtyRun {\n let screen = '';\n let active = true;\n const handlers = new Set<(data: string) => void>();\n const refresh = async (): Promise<void> => {\n while (active) {\n const captured = await tmux.run(['capture-pane', '-p', '-t', target]).catch((error: unknown) => {\n process.emitWarning(`Could not capture tmux screen for ${handle.name}: ${errorMessage(error)}`);\n return undefined;\n });\n const next = captured?.returnCode === 0 ? captured.stdout : screen;\n if (next !== screen) {\n screen = next;\n for (const handler of handlers) handler(next);\n }\n await delay(POLL_MS);\n }\n };\n void refresh();\n void completion\n .finally(() => {\n active = false;\n })\n .catch((error: unknown) =>\n process.emitWarning(`tmux interactive completion failed for ${handle.name}: ${errorMessage(error)}`),\n );\n return {\n ...handle,\n write: (text) => {\n void tmux\n .run(['send-keys', '-t', target, '-l', text])\n .catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n screen: () => screen,\n onData: (handler) => {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n resize: (cols, rows) => {\n void tmux\n .run(['resize-window', '-t', target, '-x', String(cols), '-y', String(rows)])\n .catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n };\n }\n}\n\nfunction socketName(repositoryPath: string): string {\n const hash = createHash('sha256').update(repositoryPath).digest('hex').slice(0, SOCKET_HASH_LENGTH);\n return `${SOCKET_PREFIX}${hash}`;\n}\n\nfunction environment(\n sessionId: string,\n interactive: boolean,\n env: Readonly<Record<string, string | undefined>>,\n): Record<string, string> {\n const values: NodeJS.ProcessEnv = {\n ...env,\n ...(interactive ? {} : { ...NON_INTERACTIVE_ENV, ...noninteractiveEnvironment(env) }),\n ...NO_TERMINAL_INPUT_ENV,\n PI_SESSION_ID: sessionId,\n };\n if (!interactive) delete values['FORCE_COLOR'];\n return Object.fromEntries(\n Object.entries(values).filter((entry): entry is [string, string] => entry[1] !== undefined),\n );\n}\n\nasync function killSession(tmux: ITmuxClient, target: string): Promise<boolean> {\n const result = await tmux.run(['kill-session', '-t', target]).catch((error: unknown) => {\n process.emitWarning(`Could not close tmux target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result?.returnCode === 0;\n}\n\nasync function panePid(tmux: ITmuxClient, target: string): Promise<number> {\n const message = await tmux.format(target, '#{pane_pid}');\n const pid = Number(message);\n if (!Number.isInteger(pid) || pid <= 0) throw new Error(`tmux did not report a pane pid for ${target}`);\n return pid;\n}\n\n/**\n * Waits for the run to end, preferring the supervisor's own record of it.\n *\n * The sidecar is written before the pane can end and outlives the server the\n * pane's exit takes down, so asking tmux is the fallback for a supervisor that\n * died without recording anything.\n */\nasync function waitForRunEnd(tmux: ITmuxClient, target: string, exitPath: string): Promise<number | null> {\n for (;;) {\n if (fs.existsSync(exitPath)) return null;\n const state = await readPaneExit(tmux, target);\n if (state.exited) return state.code;\n await delay(POLL_MS);\n }\n}\n\nasync function waitForLogDrain(tmux: ITmuxClient, target: string, donePath: string): Promise<void> {\n const deadline = Date.now() + LOG_DRAIN_TIMEOUT_MS;\n while (Date.now() < deadline) {\n if (fs.existsSync(donePath)) return;\n if (await tmux.sessionMissing(target)) return;\n await delay(LOG_DRAIN_POLL_MS);\n }\n}\n\nasync function waitForPaneStop(tmux: ITmuxClient, target: string, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if ((await readPaneExit(tmux, target)).exited) return true;\n await delay(POLL_MS);\n }\n return false;\n}\n\n/** One formatted read answers both questions this poll asks. */\nasync function readPaneExit(tmux: ITmuxClient, target: string): Promise<{ exited: boolean; code: number | null }> {\n const message = await tmux.format(target, PANE_STATE_FORMAT);\n // An unreachable server is the ordinary end of the last run: the pane exiting\n // ends its session, and the last session ending stops the server.\n if (message === undefined) return { exited: true, code: null };\n const [dead, status, ...rest] = message.trim().split(':');\n if (rest.join(':') === '') return { exited: true, code: null };\n if (dead === '1' || dead === 'true') {\n const code = Number(status);\n return { exited: true, code: Number.isInteger(code) ? code : null };\n }\n return { exited: false, code: null };\n}\n\nfunction signalPane(pid: number, target: string): 'signalled' | 'gone' | 'failed' {\n try {\n process.kill(pid, 'SIGTERM');\n return 'signalled';\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ESRCH') return 'gone';\n process.emitWarning(`Could not signal tmux target ${target}: ${errorMessage(error)}`);\n return 'failed';\n }\n}\n\nfunction readTail(target: string, maxBytes: number): string {\n let handle: number | undefined;\n try {\n const size = fs.statSync(target).size;\n const bytes = Math.min(size, maxBytes);\n const buffer = Buffer.alloc(bytes);\n handle = fs.openSync(target, 'r');\n fs.readSync(handle, buffer, 0, bytes, size - bytes);\n return buffer.toString('utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n process.emitWarning(`Could not read tmux log ${target}: ${errorMessage(error)}`);\n }\n return '';\n } finally {\n if (handle !== undefined) fs.closeSync(handle);\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n timer.unref?.();\n });\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import { sharedExecutionBudget, type PoHostExecutionBudget } from '@agimon-ai/po-core/packageApi';\n\nimport { BashRunService } from '../bashRunService';\nimport { SystemClock } from '../clock';\nimport { Launcher } from '../launcher';\nimport { NodeLifeline } from '../lifeline';\nimport { LogFile } from '../logFile';\nimport { LogReader } from '../logReader';\nimport { NodeProcessControl } from '../processControl';\nimport { PtyBackendChain } from '../ptyBackendChain';\nimport { PtyHost } from '../ptyHost';\nimport { NodePtySpawner } from '../ptySpawner';\nimport { RmuxBackend } from '../rmuxBackend';\nimport { RtkProcessor } from '../rtkProcessor';\nimport { RunnerNamer } from '../runnerNamer';\nimport { RunnerPaths } from '../runnerPaths';\nimport { RunnerRegistry, createDefaultProcessRegistry } from '../runnerRegistry';\nimport { NodeSpawner } from '../spawner';\nimport { TmuxBackend } from '../tmuxBackend';\nimport type { RunnerDependencies } from './type';\n/** Build once on first access, then hand back the same instance. */\nfunction memoize<T>(build: () => T): () => T {\n let value: T | undefined;\n let built = false;\n return () => {\n if (!built) {\n value = build();\n built = true;\n }\n return value as T;\n };\n}\n\n/**\n * Builds the extension's service graph.\n *\n * A factory rather than a module-level singleton: the extension owns one graph\n * per session, and tests get a fresh one they can substitute ports on through\n * `overrides` without leaking state between cases.\n *\n * Every slot resolves lazily and memoizes, which keeps the previous container's\n * behaviour: nothing is constructed until it is asked for, so opening the SQLite\n * process registry stays deferred until something actually needs a runner.\n */\nexport function createRunnerDependencies(\n overrides: Partial<RunnerDependencies> & {\n environment: Readonly<Record<string, string | undefined>>;\n cwd?: string;\n executionBudget?: PoHostExecutionBudget;\n },\n): RunnerDependencies {\n const settings =\n overrides.settings === undefined\n ? undefined\n : Object.freeze({\n ...overrides.settings,\n ...(overrides.settings?.errorPatterns\n ? { errorPatterns: Object.freeze([...overrides.settings.errorPatterns]) }\n : {}),\n });\n const environment = { ...overrides.environment };\n const cwd = overrides.cwd ?? process.cwd();\n const clock = memoize(() => overrides.clock ?? new SystemClock());\n const spawner = memoize(() => overrides.spawner ?? new NodeSpawner());\n const processControl = memoize(() => overrides.processControl ?? new NodeProcessControl());\n const ptySpawner = memoize(() => overrides.ptySpawner ?? new NodePtySpawner());\n const paths = memoize(() => overrides.paths ?? new RunnerPaths(cwd, environment));\n const lifeline = memoize(() => overrides.lifeline ?? new NodeLifeline(paths()));\n const processRegistry = memoize(() => overrides.processRegistry ?? createDefaultProcessRegistry(environment));\n const runnerRegistry = memoize(\n () => overrides.runnerRegistry ?? new RunnerRegistry(paths(), processControl(), processRegistry(), environment),\n );\n const namer = memoize(() => overrides.namer ?? new RunnerNamer(runnerRegistry()));\n const logFile = memoize(() => overrides.logFile ?? new LogFile(paths()));\n const logReader = memoize(() => overrides.logReader ?? new LogReader());\n const launcher = memoize(\n () =>\n overrides.launcher ??\n new Launcher(spawner(), processControl(), logFile(), clock(), paths(), lifeline(), environment, settings),\n );\n const rmuxBackend = memoize(\n () =>\n overrides.rmuxBackend ??\n new PtyBackendChain(\n new RmuxBackend(paths(), environment, settings),\n new TmuxBackend(paths(), undefined, environment, settings),\n ),\n );\n const rtkProcessor = memoize(\n () => overrides.rtkProcessor ?? new RtkProcessor(undefined, undefined, environment, settings),\n );\n const ptyHost = memoize(\n () => overrides.ptyHost ?? new PtyHost(ptySpawner(), logFile(), processControl(), clock(), environment, settings),\n );\n const bashRunService = memoize(\n () =>\n overrides.bashRunService ??\n new BashRunService(\n launcher(),\n rmuxBackend(),\n namer(),\n runnerRegistry(),\n clock(),\n rtkProcessor(),\n cwd,\n environment,\n overrides.executionBudget ?? sharedExecutionBudget(environment),\n ),\n );\n\n return {\n settings,\n environment,\n get clock() {\n return clock();\n },\n get spawner() {\n return spawner();\n },\n get processControl() {\n return processControl();\n },\n get ptySpawner() {\n return ptySpawner();\n },\n get paths() {\n return paths();\n },\n get lifeline() {\n return lifeline();\n },\n get processRegistry() {\n return processRegistry();\n },\n get runnerRegistry() {\n return runnerRegistry();\n },\n get namer() {\n return namer();\n },\n get logFile() {\n return logFile();\n },\n get logReader() {\n return logReader();\n },\n get launcher() {\n return launcher();\n },\n get rmuxBackend() {\n return rmuxBackend();\n },\n get rtkProcessor() {\n return rtkProcessor();\n },\n get ptyHost() {\n return ptyHost();\n },\n get bashRunService() {\n return bashRunService();\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runnerDependencies-CamKwphq.mjs","names":[],"sources":["../src/constants/tmuxBackend.ts","../src/services/ptyBackendChain/index.ts","../src/services/tmuxBackend/TmuxClient.ts","../src/services/tmuxBackend/index.ts","../src/services/runnerDependencies/index.ts"],"sourcesContent":["export const POLL_MS = 100;\nexport const LOG_DRAIN_TIMEOUT_MS = 2_000;\nexport const LOG_DRAIN_POLL_MS = 25;\nexport const PANE_STATE_FORMAT = '#{pane_dead}:#{pane_dead_status}:#{session_name}';\nexport const STOP_GRACE_MS = 3_000;\nexport const SESSION_PREFIX = 'po-tmux-';\nexport const OWNED_TARGET_PATTERN = /^po-tmux-[A-Za-z0-9_-]+$/;\nexport const TMUX_TARGET_PREFIX = SESSION_PREFIX;\nexport const SOCKET_HASH_LENGTH = 12;\nexport const SOCKET_PREFIX = 'po-tmux-';\nexport const NON_INTERACTIVE_ENV = { NO_COLOR: '1', CI: '1' };\n","import { TMUX_TARGET_PREFIX } from '../../constants/tmuxBackend';\nimport type { RunHandle } from '../../types/launcher';\nimport type { PtyRun } from '../../types/ptyHost';\nimport type { IRmuxBackend, RmuxLaunchRequest } from '../../types/rmuxBackend';\nimport type { ExitResult } from '../../types/spawner';\n\n/**\n * Presents the available PTY backends as one, preferring RMUX.\n *\n * A launch takes the first backend that accepts it, so a host without a\n * compatible RMUX binary still gets panes rather than falling through to the\n * plain subprocess launcher. Every later call routes on the target's prefix\n * instead of asking each backend in turn: a backend cannot tell \"this session\n * is gone\" from \"this session was never mine\", and guessing would let one\n * report success for the other's run.\n */\nexport class PtyBackendChain implements IRmuxBackend {\n constructor(\n private readonly rmux: IRmuxBackend,\n private readonly tmux: IRmuxBackend,\n ) {}\n\n async launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined> {\n return (await this.rmux.launch(request)) ?? (await this.tmux.launch(request));\n }\n\n watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined> {\n return this.owner(target).watch(id, target, sessionId);\n }\n\n stop(target: string, expectedPid: number): Promise<boolean> {\n return this.owner(target).stop(target, expectedPid);\n }\n\n input(target: string, text: string): Promise<boolean> {\n return this.owner(target).input(target, text);\n }\n\n capture(target: string): Promise<string | undefined> {\n return this.owner(target).capture(target);\n }\n\n /** Both backends persist terminal evidence at the same path, so either answers. */\n readOutcome(id: string, sessionId: string): ExitResult | undefined {\n return this.rmux.readOutcome(id, sessionId) ?? this.tmux.readOutcome(id, sessionId);\n }\n\n get(name: string): PtyRun | undefined {\n return this.rmux.get(name) ?? this.tmux.get(name);\n }\n\n private owner(target: string): IRmuxBackend {\n return target.startsWith(TMUX_TARGET_PREFIX) ? this.tmux : this.rmux;\n }\n}\n","import { execFile } from 'node:child_process';\n\nimport type { ITmuxClient, TmuxResult } from '../../types/tmuxClient';\n\nconst TMUX_BINARY = 'tmux';\nconst SOCKET_OPTION = '-L';\n/** Long enough for a loaded server, short enough that a hung tmux is not fatal. */\nconst COMMAND_TIMEOUT_MS = 10_000;\nconst MAX_OUTPUT_BYTES = 4 * 1024 * 1024;\n\nexport class TmuxClient implements ITmuxClient {\n constructor(\n private readonly socket: string,\n private readonly binary = TMUX_BINARY,\n ) {}\n\n run(args: readonly string[]): Promise<TmuxResult> {\n return new Promise((resolve, reject) => {\n execFile(\n this.binary,\n [SOCKET_OPTION, this.socket, ...args],\n { timeout: COMMAND_TIMEOUT_MS, maxBuffer: MAX_OUTPUT_BYTES, encoding: 'utf8' },\n (error, stdout, stderr) => {\n // A non-zero tmux exit is an answer, not a fault: `has-session`\n // reports absence that way. Only a missing or hung binary rejects.\n const code = (error as (Error & { code?: number | string }) | null)?.code;\n if (error && typeof code !== 'number') {\n reject(error);\n return;\n }\n resolve({ returnCode: typeof code === 'number' ? code : 0, stdout, stderr });\n },\n );\n });\n }\n\n async format(target: string, format: string): Promise<string | undefined> {\n const result = await this.run(['display-message', '-p', '-t', target, '-F', format]).catch(() => undefined);\n if (!result || result.returnCode !== 0) return undefined;\n return result.stdout.replace(/\\n$/, '');\n }\n\n async sessionMissing(target: string): Promise<boolean> {\n const result = await this.run(['has-session', '-t', target]).catch(() => undefined);\n return !result || result.returnCode !== 0;\n }\n}\n","import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport {\n LOG_DRAIN_POLL_MS,\n LOG_DRAIN_TIMEOUT_MS,\n NON_INTERACTIVE_ENV,\n OWNED_TARGET_PATTERN,\n PANE_STATE_FORMAT,\n POLL_MS,\n SESSION_PREFIX,\n SOCKET_HASH_LENGTH,\n SOCKET_PREFIX,\n STOP_GRACE_MS,\n} from '../../constants/tmuxBackend';\nimport type { RunHandle } from '../../types/launcher';\nimport type { PtyRun } from '../../types/ptyHost';\nimport type { IRmuxBackend, RmuxLaunchRequest } from '../../types/rmuxBackend';\nimport type { RunnerSettings } from '../../types/runnerSettings';\nimport type { ExitResult } from '../../types/spawner';\nimport type { ITmuxClient } from '../../types/tmuxClient';\nimport { getLogMaxBytes, getResultMaxBytes, noninteractiveEnvironment } from '../runnerConfig';\nimport type { IRunnerPaths } from '../runnerPaths/type';\nimport {\n type CommandSpec,\n type SupervisorPaths,\n cleanupSupervisorFiles,\n NO_TERMINAL_INPUT_ENV,\n readExitMetadata,\n runtimeEntry,\n shellJoin,\n supervisorPaths,\n writeCommandSpec,\n} from '../runnerSupervisor';\nimport { TmuxClient } from './TmuxClient';\n\n/** Pane liveness, its exit status, and whether the session still exists, in one read. */\n/** Distinct from the RMUX prefix so a target names the backend that owns it. */\n\n/**\n * Supervises runs in tmux panes, for hosts with no compatible RMUX binary.\n *\n * The pane runs the same runnerHost supervisor as the RMUX backend, so exit\n * metadata, log rotation, and lifeline handling are shared rather than\n * reimplemented: only the multiplexer differs. Kept beside the RMUX backend\n * rather than folded into it because that path has no unit coverage to\n * refactor against.\n */\nexport class TmuxBackend implements IRmuxBackend {\n private clientPromise: Promise<ITmuxClient | undefined> | undefined;\n private readonly runs = new Map<string, PtyRun>();\n private readonly completions = new Map<string, Promise<ExitResult>>();\n\n constructor(\n private readonly paths: IRunnerPaths,\n private readonly createClient: (socket: string) => ITmuxClient = (socket) => new TmuxClient(socket),\n private readonly env: Readonly<Record<string, string | undefined>> = process.env,\n private readonly settings?: RunnerSettings,\n ) {}\n\n async launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined> {\n const tmux = await this.client();\n if (!tmux) return undefined;\n\n this.paths.ensureDirectories();\n const target = `${SESSION_PREFIX}${request.id}`;\n const logPath = this.paths.logPathFor(request.id);\n const aux = this.auxPaths(request.id, request.sessionId);\n let created = false;\n let released = false;\n\n try {\n this.prepareFiles(request, logPath, aux);\n // One quoted command rather than an argv: tmux takes shell-command as a\n // single word, and quoting here is what keeps a path with spaces intact.\n const supervisor = shellJoin([process.execPath, runtimeEntry('runnerHost'), aux.spec, aux.gate, aux.exit]);\n await this.checked(tmux, ['new-session', '-d', '-s', target, '-c', request.cwd, supervisor]);\n created = true;\n // Set before the gate opens, so it is in force by the time the command\n // can exit. A pane that vanishes on exit takes the log sink down with it\n // before Node has finished starting, losing the output of fast commands,\n // and leaves #{pane_dead} with nothing to report.\n await this.checked(tmux, ['set-option', '-t', target, 'remain-on-exit', 'on']);\n await this.checked(tmux, ['pipe-pane', '-t', target, this.logPipeCommand(logPath, aux.logDone, request)]);\n\n const pid = await panePid(tmux, target);\n fs.writeFileSync(aux.gate, '', { mode: 0o600 });\n released = true;\n\n let buffering = true;\n const completion = this.monitor(tmux, target, aux);\n this.trackCompletion(target, completion);\n const handle: RunHandle = {\n id: request.id,\n name: request.name,\n pid,\n logPath,\n backend: 'tmux',\n backendTarget: target,\n output: () => (buffering ? readTail(logPath, getResultMaxBytes(this.env, this.settings) * 2) : ''),\n completion: () => completion,\n detach: () => {\n buffering = false;\n },\n stop: () => this.stop(target, pid),\n };\n\n if (request.interactive) this.runs.set(request.name, this.interactiveRun(handle, tmux, target, completion));\n void completion\n .finally(() => this.runs.delete(request.name))\n .catch((error: unknown) => process.emitWarning(`tmux completion failed for ${target}: ${errorMessage(error)}`));\n return handle;\n } catch (error) {\n if (released) throw error;\n if (created) await killSession(tmux, target);\n cleanupSupervisorFiles(aux);\n process.emitWarning(\n request.interactive\n ? `tmux launch unavailable for interactive runner: ${errorMessage(error)}`\n : `tmux launch unavailable, using supervised subprocess: ${errorMessage(error)}`,\n );\n return undefined;\n }\n }\n\n async stop(target: string, expectedPid: number): Promise<boolean> {\n if (!OWNED_TARGET_PATTERN.test(target) || !Number.isInteger(expectedPid) || expectedPid <= 0) return false;\n\n const tmux = await this.client();\n if (!tmux) return false;\n try {\n if (await tmux.sessionMissing(target)) return true;\n\n const pid = await panePid(tmux, target);\n if (pid !== expectedPid) return false;\n const signalled = signalPane(pid, target);\n if (signalled === 'gone') return true;\n if (signalled === 'failed') return false;\n\n if (await waitForPaneStop(tmux, target, STOP_GRACE_MS)) return true;\n if (await tmux.sessionMissing(target)) return true;\n\n // Revalidate after the grace period so a replacement pane is never closed.\n const currentPid = await panePid(tmux, target).catch(() => undefined);\n if (currentPid !== expectedPid) return false;\n\n return killSession(tmux, target);\n } catch (error) {\n process.emitWarning(`Could not stop tmux target ${target}: ${errorMessage(error)}`);\n return false;\n }\n }\n\n async watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined> {\n const tmux = await this.client();\n if (!tmux) return undefined;\n if (await tmux.sessionMissing(target)) return undefined;\n const completion = this.monitor(tmux, target, this.auxPaths(id, sessionId));\n this.trackCompletion(target, completion);\n return completion;\n }\n\n async input(target: string, text: string): Promise<boolean> {\n const tmux = await this.client();\n if (!tmux) return false;\n const result = await tmux.run(['send-keys', '-t', target, '-l', text]).catch((error: unknown) => {\n process.emitWarning(`Could not send input to tmux target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result?.returnCode === 0;\n }\n\n async capture(target: string): Promise<string | undefined> {\n const tmux = await this.client();\n if (!tmux) return undefined;\n const result = await tmux.run(['capture-pane', '-p', '-t', target]).catch((error: unknown) => {\n process.emitWarning(`Could not capture tmux target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result?.returnCode === 0 ? result.stdout : undefined;\n }\n\n get(name: string): PtyRun | undefined {\n return this.runs.get(name);\n }\n\n readOutcome(id: string, sessionId: string): ExitResult | undefined {\n return readExitMetadata(this.auxPaths(id, sessionId).exit);\n }\n\n private trackCompletion(target: string, completion: Promise<ExitResult>): void {\n this.completions.set(target, completion);\n void completion\n .finally(() => this.completions.delete(target))\n .catch((error: unknown) => process.emitWarning(`tmux monitor failed for ${target}: ${errorMessage(error)}`));\n }\n\n private client(): Promise<ITmuxClient | undefined> {\n this.clientPromise ??= this.resolveClient();\n return this.clientPromise;\n }\n\n private async resolveClient(): Promise<ITmuxClient | undefined> {\n const client = this.createClient(socketName(this.paths.repositoryPath()));\n try {\n const version = await client.run(['-V']);\n if (version.returnCode !== 0) throw new Error(version.stderr.trim() || 'tmux reported no version');\n return client;\n } catch (error) {\n process.emitWarning(`tmux is unavailable: ${errorMessage(error)}`);\n return undefined;\n }\n }\n\n private async checked(tmux: ITmuxClient, args: readonly string[]): Promise<void> {\n const result = await tmux.run(args);\n if (result.returnCode !== 0) {\n throw new Error(`tmux ${args[0] ?? ''} failed: ${result.stderr.trim() || `exit ${result.returnCode}`}`);\n }\n }\n\n private prepareFiles(request: RmuxLaunchRequest, logPath: string, aux: SupervisorPaths): void {\n cleanupSupervisorFiles(aux);\n fs.writeFileSync(logPath, '', { mode: 0o600 });\n const env = environment(request.sessionId, request.interactive, this.env);\n const spec: CommandSpec = { command: request.command, cwd: request.cwd, env };\n writeCommandSpec(aux.spec, spec);\n }\n\n private auxPaths(id: string, sessionId?: string): SupervisorPaths {\n return supervisorPaths(this.paths.stateDirectory(sessionId), id);\n }\n\n /**\n * The sink the pane pipes into.\n *\n * An interactive run also asks for a raw copy: the scrubbed log it writes\n * beside it has had cursor movement taken out, which is what a terminal\n * needs most. Only interactive runs pay for it, because only they can be\n * attached to.\n */\n private logPipeCommand(logPath: string, donePath: string, request: RmuxLaunchRequest): string {\n const id = path.basename(logPath, '.log');\n return shellJoin([\n process.execPath,\n runtimeEntry('logSink'),\n logPath,\n this.paths.rotatedLogPathFor(id),\n String(getLogMaxBytes(this.env)),\n donePath,\n ...(request.interactive ? [this.paths.rawLogPathFor(id)] : []),\n ]);\n }\n\n private async monitor(tmux: ITmuxClient, target: string, aux: SupervisorPaths): Promise<ExitResult> {\n try {\n const paneCode = await waitForRunEnd(tmux, target, aux.exit);\n await waitForLogDrain(tmux, target, aux.logDone);\n return readExitMetadata(aux.exit) ?? { code: paneCode, signal: null };\n } finally {\n if (!(await tmux.sessionMissing(target).catch(() => false))) await killSession(tmux, target);\n cleanupSupervisorFiles(aux);\n }\n }\n\n private interactiveRun(\n handle: RunHandle,\n tmux: ITmuxClient,\n target: string,\n completion: Promise<ExitResult>,\n ): PtyRun {\n let screen = '';\n let active = true;\n const handlers = new Set<(data: string) => void>();\n const refresh = async (): Promise<void> => {\n while (active) {\n const captured = await tmux.run(['capture-pane', '-p', '-t', target]).catch((error: unknown) => {\n process.emitWarning(`Could not capture tmux screen for ${handle.name}: ${errorMessage(error)}`);\n return undefined;\n });\n const next = captured?.returnCode === 0 ? captured.stdout : screen;\n if (next !== screen) {\n screen = next;\n for (const handler of handlers) handler(next);\n }\n await delay(POLL_MS);\n }\n };\n void refresh();\n void completion\n .finally(() => {\n active = false;\n })\n .catch((error: unknown) =>\n process.emitWarning(`tmux interactive completion failed for ${handle.name}: ${errorMessage(error)}`),\n );\n return {\n ...handle,\n write: (text) => {\n void tmux\n .run(['send-keys', '-t', target, '-l', text])\n .catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n screen: () => screen,\n onData: (handler) => {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n resize: (cols, rows) => {\n void tmux\n .run(['resize-window', '-t', target, '-x', String(cols), '-y', String(rows)])\n .catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n };\n }\n}\n\nfunction socketName(repositoryPath: string): string {\n const hash = createHash('sha256').update(repositoryPath).digest('hex').slice(0, SOCKET_HASH_LENGTH);\n return `${SOCKET_PREFIX}${hash}`;\n}\n\nfunction environment(\n sessionId: string,\n interactive: boolean,\n env: Readonly<Record<string, string | undefined>>,\n): Record<string, string> {\n const values: NodeJS.ProcessEnv = {\n ...env,\n ...(interactive ? {} : { ...NON_INTERACTIVE_ENV, ...noninteractiveEnvironment(env) }),\n ...NO_TERMINAL_INPUT_ENV,\n PI_SESSION_ID: sessionId,\n };\n if (!interactive) delete values['FORCE_COLOR'];\n return Object.fromEntries(\n Object.entries(values).filter((entry): entry is [string, string] => entry[1] !== undefined),\n );\n}\n\nasync function killSession(tmux: ITmuxClient, target: string): Promise<boolean> {\n const result = await tmux.run(['kill-session', '-t', target]).catch((error: unknown) => {\n process.emitWarning(`Could not close tmux target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result?.returnCode === 0;\n}\n\nasync function panePid(tmux: ITmuxClient, target: string): Promise<number> {\n const message = await tmux.format(target, '#{pane_pid}');\n const pid = Number(message);\n if (!Number.isInteger(pid) || pid <= 0) throw new Error(`tmux did not report a pane pid for ${target}`);\n return pid;\n}\n\n/**\n * Waits for the run to end, preferring the supervisor's own record of it.\n *\n * The sidecar is written before the pane can end and outlives the server the\n * pane's exit takes down, so asking tmux is the fallback for a supervisor that\n * died without recording anything.\n */\nasync function waitForRunEnd(tmux: ITmuxClient, target: string, exitPath: string): Promise<number | null> {\n for (;;) {\n if (fs.existsSync(exitPath)) return null;\n const state = await readPaneExit(tmux, target);\n if (state.exited) return state.code;\n await delay(POLL_MS);\n }\n}\n\nasync function waitForLogDrain(tmux: ITmuxClient, target: string, donePath: string): Promise<void> {\n const deadline = Date.now() + LOG_DRAIN_TIMEOUT_MS;\n while (Date.now() < deadline) {\n if (fs.existsSync(donePath)) return;\n if (await tmux.sessionMissing(target)) return;\n await delay(LOG_DRAIN_POLL_MS);\n }\n}\n\nasync function waitForPaneStop(tmux: ITmuxClient, target: string, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if ((await readPaneExit(tmux, target)).exited) return true;\n await delay(POLL_MS);\n }\n return false;\n}\n\n/** One formatted read answers both questions this poll asks. */\nasync function readPaneExit(tmux: ITmuxClient, target: string): Promise<{ exited: boolean; code: number | null }> {\n const message = await tmux.format(target, PANE_STATE_FORMAT);\n // An unreachable server is the ordinary end of the last run: the pane exiting\n // ends its session, and the last session ending stops the server.\n if (message === undefined) return { exited: true, code: null };\n const [dead, status, ...rest] = message.trim().split(':');\n if (rest.join(':') === '') return { exited: true, code: null };\n if (dead === '1' || dead === 'true') {\n const code = Number(status);\n return { exited: true, code: Number.isInteger(code) ? code : null };\n }\n return { exited: false, code: null };\n}\n\nfunction signalPane(pid: number, target: string): 'signalled' | 'gone' | 'failed' {\n try {\n process.kill(pid, 'SIGTERM');\n return 'signalled';\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ESRCH') return 'gone';\n process.emitWarning(`Could not signal tmux target ${target}: ${errorMessage(error)}`);\n return 'failed';\n }\n}\n\nfunction readTail(target: string, maxBytes: number): string {\n let handle: number | undefined;\n try {\n const size = fs.statSync(target).size;\n const bytes = Math.min(size, maxBytes);\n const buffer = Buffer.alloc(bytes);\n handle = fs.openSync(target, 'r');\n fs.readSync(handle, buffer, 0, bytes, size - bytes);\n return buffer.toString('utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n process.emitWarning(`Could not read tmux log ${target}: ${errorMessage(error)}`);\n }\n return '';\n } finally {\n if (handle !== undefined) fs.closeSync(handle);\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n timer.unref?.();\n });\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import { sharedExecutionBudget, type PoHostExecutionBudget } from '@agimon-ai/po-core/packageApi';\n\nimport { BashRunService } from '../bashRunService';\nimport { SystemClock } from '../clock';\nimport { Launcher } from '../launcher';\nimport { NodeLifeline } from '../lifeline';\nimport { LogFile } from '../logFile';\nimport { LogReader } from '../logReader';\nimport { NodeProcessControl } from '../processControl';\nimport { PtyBackendChain } from '../ptyBackendChain';\nimport { PtyHost } from '../ptyHost';\nimport { NodePtySpawner } from '../ptySpawner';\nimport { RmuxBackend } from '../rmuxBackend';\nimport { RtkProcessor } from '../rtkProcessor';\nimport { RunnerNamer } from '../runnerNamer';\nimport { RunnerPaths } from '../runnerPaths';\nimport { RunnerRegistry, createDefaultProcessRegistry } from '../runnerRegistry';\nimport { NodeSpawner } from '../spawner';\nimport { TmuxBackend } from '../tmuxBackend';\nimport type { RunnerDependencies } from './type';\n/** Build once on first access, then hand back the same instance. */\nfunction memoize<T>(build: () => T): () => T {\n let value: T | undefined;\n let built = false;\n return () => {\n if (!built) {\n value = build();\n built = true;\n }\n return value as T;\n };\n}\n\n/**\n * Builds the extension's service graph.\n *\n * A factory rather than a module-level singleton: the extension owns one graph\n * per session, and tests get a fresh one they can substitute ports on through\n * `overrides` without leaking state between cases.\n *\n * Every slot resolves lazily and memoizes, which keeps the previous container's\n * behaviour: nothing is constructed until it is asked for, so opening the SQLite\n * process registry stays deferred until something actually needs a runner.\n */\nexport function createRunnerDependencies(\n overrides: Partial<RunnerDependencies> & {\n environment: Readonly<Record<string, string | undefined>>;\n cwd?: string;\n executionBudget?: PoHostExecutionBudget;\n },\n): RunnerDependencies {\n const settings =\n overrides.settings === undefined\n ? undefined\n : Object.freeze({\n ...overrides.settings,\n ...(overrides.settings?.errorPatterns\n ? { errorPatterns: Object.freeze([...overrides.settings.errorPatterns]) }\n : {}),\n });\n const environment = { ...overrides.environment };\n const cwd = overrides.cwd ?? process.cwd();\n const clock = memoize(() => overrides.clock ?? new SystemClock());\n const spawner = memoize(() => overrides.spawner ?? new NodeSpawner());\n const processControl = memoize(() => overrides.processControl ?? new NodeProcessControl());\n const ptySpawner = memoize(() => overrides.ptySpawner ?? new NodePtySpawner());\n const paths = memoize(() => overrides.paths ?? new RunnerPaths(cwd, environment));\n const lifeline = memoize(() => overrides.lifeline ?? new NodeLifeline(paths()));\n const processRegistry = memoize(() => overrides.processRegistry ?? createDefaultProcessRegistry(environment));\n const runnerRegistry = memoize(\n () => overrides.runnerRegistry ?? new RunnerRegistry(paths(), processControl(), processRegistry(), environment),\n );\n const namer = memoize(() => overrides.namer ?? new RunnerNamer(runnerRegistry()));\n const logFile = memoize(() => overrides.logFile ?? new LogFile(paths()));\n const logReader = memoize(() => overrides.logReader ?? new LogReader());\n const launcher = memoize(\n () =>\n overrides.launcher ??\n new Launcher(spawner(), processControl(), logFile(), clock(), paths(), lifeline(), environment, settings),\n );\n const rmuxBackend = memoize(\n () =>\n overrides.rmuxBackend ??\n new PtyBackendChain(\n new RmuxBackend(paths(), environment, settings),\n new TmuxBackend(paths(), undefined, environment, settings),\n ),\n );\n const rtkProcessor = memoize(\n () => overrides.rtkProcessor ?? new RtkProcessor(undefined, undefined, environment, settings),\n );\n const ptyHost = memoize(\n () => overrides.ptyHost ?? new PtyHost(ptySpawner(), logFile(), processControl(), clock(), environment, settings),\n );\n const bashRunService = memoize(\n () =>\n overrides.bashRunService ??\n new BashRunService(\n launcher(),\n rmuxBackend(),\n namer(),\n runnerRegistry(),\n clock(),\n rtkProcessor(),\n cwd,\n environment,\n overrides.executionBudget ?? sharedExecutionBudget(environment),\n ),\n );\n\n return {\n settings,\n environment,\n get clock() {\n return clock();\n },\n get spawner() {\n return spawner();\n },\n get processControl() {\n return processControl();\n },\n get ptySpawner() {\n return ptySpawner();\n },\n get paths() {\n return paths();\n },\n get lifeline() {\n return lifeline();\n },\n get processRegistry() {\n return processRegistry();\n },\n get runnerRegistry() {\n return runnerRegistry();\n },\n get namer() {\n return namer();\n },\n get logFile() {\n return logFile();\n },\n get logReader() {\n return logReader();\n },\n get launcher() {\n return launcher();\n },\n get rmuxBackend() {\n return rmuxBackend();\n },\n get rtkProcessor() {\n return rtkProcessor();\n },\n get ptyHost() {\n return ptyHost();\n },\n get bashRunService() {\n return bashRunService();\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AACA,MAAa,uBAAuB;AAEpC,MAAa,oBAAoB;AAEjC,MAAa,iBAAiB;AAC9B,MAAa,uBAAuB;AAGpC,MAAa,gBAAgB;AAC7B,MAAa,sBAAsB;CAAE,UAAU;CAAK,IAAI;AAAI;;;;;;;;;;;;;ACM5D,IAAa,kBAAb,MAAqD;CAEhC;CACA;CAFnB,YACE,MACA,MACA;EAFiB,KAAA,OAAA;EACA,KAAA,OAAA;CAChB;CAEH,MAAM,OAAO,SAA4D;EACvE,OAAQ,MAAM,KAAK,KAAK,OAAO,OAAO,KAAO,MAAM,KAAK,KAAK,OAAO,OAAO;CAC7E;CAEA,MAAM,IAAY,QAAgB,WAAqD;EACrF,OAAO,KAAK,MAAM,MAAM,CAAC,CAAC,MAAM,IAAI,QAAQ,SAAS;CACvD;CAEA,KAAK,QAAgB,aAAuC;EAC1D,OAAO,KAAK,MAAM,MAAM,CAAC,CAAC,KAAK,QAAQ,WAAW;CACpD;CAEA,MAAM,QAAgB,MAAgC;EACpD,OAAO,KAAK,MAAM,MAAM,CAAC,CAAC,MAAM,QAAQ,IAAI;CAC9C;CAEA,QAAQ,QAA6C;EACnD,OAAO,KAAK,MAAM,MAAM,CAAC,CAAC,QAAQ,MAAM;CAC1C;;CAGA,YAAY,IAAY,WAA2C;EACjE,OAAO,KAAK,KAAK,YAAY,IAAI,SAAS,KAAK,KAAK,KAAK,YAAY,IAAI,SAAS;CACpF;CAEA,IAAI,MAAkC;EACpC,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,IAAI,IAAI;CAClD;CAEA,MAAc,QAA8B;EAC1C,OAAO,OAAO,WAAA,UAA6B,IAAI,KAAK,OAAO,KAAK;CAClE;AACF;;;AClDA,MAAM,cAAc;AACpB,MAAM,gBAAgB;;AAEtB,MAAM,qBAAqB;AAC3B,MAAM,mBAAmB;AAEzB,IAAa,aAAb,MAA+C;CAE1B;CACA;CAFnB,YACE,QACA,SAA0B,aAC1B;EAFiB,KAAA,SAAA;EACA,KAAA,SAAA;CAChB;CAEH,IAAI,MAA8C;EAChD,OAAO,IAAI,SAAS,SAAS,WAAW;GACtC,SACE,KAAK,QACL;IAAC;IAAe,KAAK;IAAQ,GAAG;GAAI,GACpC;IAAE,SAAS;IAAoB,WAAW;IAAkB,UAAU;GAAO,IAC5E,OAAO,QAAQ,WAAW;IAGzB,MAAM,OAAQ,OAAuD;IACrE,IAAI,SAAS,OAAO,SAAS,UAAU;KACrC,OAAO,KAAK;KACZ;IACF;IACA,QAAQ;KAAE,YAAY,OAAO,SAAS,WAAW,OAAO;KAAG;KAAQ;IAAO,CAAC;GAC7E,CACF;EACF,CAAC;CACH;CAEA,MAAM,OAAO,QAAgB,QAA6C;EACxE,MAAM,SAAS,MAAM,KAAK,IAAI;GAAC;GAAmB;GAAM;GAAM;GAAQ;GAAM;EAAM,CAAC,CAAC,CAAC,YAAY,KAAA,CAAS;EAC1G,IAAI,CAAC,UAAU,OAAO,eAAe,GAAG,OAAO,KAAA;EAC/C,OAAO,OAAO,OAAO,QAAQ,OAAO,EAAE;CACxC;CAEA,MAAM,eAAe,QAAkC;EACrD,MAAM,SAAS,MAAM,KAAK,IAAI;GAAC;GAAe;GAAM;EAAM,CAAC,CAAC,CAAC,YAAY,KAAA,CAAS;EAClF,OAAO,CAAC,UAAU,OAAO,eAAe;CAC1C;AACF;;;;;;;;;;;;;;ACGA,IAAa,cAAb,MAAiD;CAM5B;CACA;CACA;CACA;CARnB;CACA,uBAAwB,IAAI,IAAoB;CAChD,8BAA+B,IAAI,IAAiC;CAEpE,YACE,OACA,gBAAkE,WAAW,IAAI,WAAW,MAAM,GAClG,MAAqE,QAAQ,KAC7E,UACA;EAJiB,KAAA,QAAA;EACA,KAAA,eAAA;EACA,KAAA,MAAA;EACA,KAAA,WAAA;CAChB;CAEH,MAAM,OAAO,SAA4D;EACvE,MAAM,OAAO,MAAM,KAAK,OAAO;EAC/B,IAAI,CAAC,MAAM,OAAO,KAAA;EAElB,KAAK,MAAM,kBAAkB;EAC7B,MAAM,SAAS,GAAG,iBAAiB,QAAQ;EAC3C,MAAM,UAAU,KAAK,MAAM,WAAW,QAAQ,EAAE;EAChD,MAAM,MAAM,KAAK,SAAS,QAAQ,IAAI,QAAQ,SAAS;EACvD,IAAI,UAAU;EACd,IAAI,WAAW;EAEf,IAAI;GACF,KAAK,aAAa,SAAS,SAAS,GAAG;GAGvC,MAAM,aAAa,UAAU;IAAC,QAAQ;IAAU,aAAa,YAAY;IAAG,IAAI;IAAM,IAAI;IAAM,IAAI;GAAI,CAAC;GACzG,MAAM,KAAK,QAAQ,MAAM;IAAC;IAAe;IAAM;IAAM;IAAQ;IAAM,QAAQ;IAAK;GAAU,CAAC;GAC3F,UAAU;GAKV,MAAM,KAAK,QAAQ,MAAM;IAAC;IAAc;IAAM;IAAQ;IAAkB;GAAI,CAAC;GAC7E,MAAM,KAAK,QAAQ,MAAM;IAAC;IAAa;IAAM;IAAQ,KAAK,eAAe,SAAS,IAAI,SAAS,OAAO;GAAC,CAAC;GAExG,MAAM,MAAM,MAAM,QAAQ,MAAM,MAAM;GACtC,GAAG,cAAc,IAAI,MAAM,IAAI,EAAE,MAAM,IAAM,CAAC;GAC9C,WAAW;GAEX,IAAI,YAAY;GAChB,MAAM,aAAa,KAAK,QAAQ,MAAM,QAAQ,GAAG;GACjD,KAAK,gBAAgB,QAAQ,UAAU;GACvC,MAAM,SAAoB;IACxB,IAAI,QAAQ;IACZ,MAAM,QAAQ;IACd;IACA;IACA,SAAS;IACT,eAAe;IACf,cAAe,YAAY,SAAS,SAAS,kBAAkB,KAAK,KAAK,KAAK,QAAQ,IAAI,CAAC,IAAI;IAC/F,kBAAkB;IAClB,cAAc;KACZ,YAAY;IACd;IACA,YAAY,KAAK,KAAK,QAAQ,GAAG;GACnC;GAEA,IAAI,QAAQ,aAAa,KAAK,KAAK,IAAI,QAAQ,MAAM,KAAK,eAAe,QAAQ,MAAM,QAAQ,UAAU,CAAC;GAC1G,WACG,cAAc,KAAK,KAAK,OAAO,QAAQ,IAAI,CAAC,CAAC,CAC7C,OAAO,UAAmB,QAAQ,YAAY,8BAA8B,OAAO,IAAI,aAAa,KAAK,GAAG,CAAC;GAChH,OAAO;EACT,SAAS,OAAO;GACd,IAAI,UAAU,MAAM;GACpB,IAAI,SAAS,MAAM,YAAY,MAAM,MAAM;GAC3C,uBAAuB,GAAG;GAC1B,QAAQ,YACN,QAAQ,cACJ,mDAAmD,aAAa,KAAK,MACrE,yDAAyD,aAAa,KAAK,GACjF;GACA;EACF;CACF;CAEA,MAAM,KAAK,QAAgB,aAAuC;EAChE,IAAI,CAAC,qBAAqB,KAAK,MAAM,KAAK,CAAC,OAAO,UAAU,WAAW,KAAK,eAAe,GAAG,OAAO;EAErG,MAAM,OAAO,MAAM,KAAK,OAAO;EAC/B,IAAI,CAAC,MAAM,OAAO;EAClB,IAAI;GACF,IAAI,MAAM,KAAK,eAAe,MAAM,GAAG,OAAO;GAE9C,MAAM,MAAM,MAAM,QAAQ,MAAM,MAAM;GACtC,IAAI,QAAQ,aAAa,OAAO;GAChC,MAAM,YAAY,WAAW,KAAK,MAAM;GACxC,IAAI,cAAc,QAAQ,OAAO;GACjC,IAAI,cAAc,UAAU,OAAO;GAEnC,IAAI,MAAM,gBAAgB,MAAM,QAAA,GAAqB,GAAG,OAAO;GAC/D,IAAI,MAAM,KAAK,eAAe,MAAM,GAAG,OAAO;GAI9C,IAAI,MADqB,QAAQ,MAAM,MAAM,CAAC,CAAC,YAAY,KAAA,CAAS,MACjD,aAAa,OAAO;GAEvC,OAAO,YAAY,MAAM,MAAM;EACjC,SAAS,OAAO;GACd,QAAQ,YAAY,8BAA8B,OAAO,IAAI,aAAa,KAAK,GAAG;GAClF,OAAO;EACT;CACF;CAEA,MAAM,MAAM,IAAY,QAAgB,WAAqD;EAC3F,MAAM,OAAO,MAAM,KAAK,OAAO;EAC/B,IAAI,CAAC,MAAM,OAAO,KAAA;EAClB,IAAI,MAAM,KAAK,eAAe,MAAM,GAAG,OAAO,KAAA;EAC9C,MAAM,aAAa,KAAK,QAAQ,MAAM,QAAQ,KAAK,SAAS,IAAI,SAAS,CAAC;EAC1E,KAAK,gBAAgB,QAAQ,UAAU;EACvC,OAAO;CACT;CAEA,MAAM,MAAM,QAAgB,MAAgC;EAC1D,MAAM,OAAO,MAAM,KAAK,OAAO;EAC/B,IAAI,CAAC,MAAM,OAAO;EAKlB,QAAO,MAJc,KAAK,IAAI;GAAC;GAAa;GAAM;GAAQ;GAAM;EAAI,CAAC,CAAC,CAAC,OAAO,UAAmB;GAC/F,QAAQ,YAAY,uCAAuC,OAAO,IAAI,aAAa,KAAK,GAAG;EAE7F,CAAC,EAAA,EACc,eAAe;CAChC;CAEA,MAAM,QAAQ,QAA6C;EACzD,MAAM,OAAO,MAAM,KAAK,OAAO;EAC/B,IAAI,CAAC,MAAM,OAAO,KAAA;EAClB,MAAM,SAAS,MAAM,KAAK,IAAI;GAAC;GAAgB;GAAM;GAAM;EAAM,CAAC,CAAC,CAAC,OAAO,UAAmB;GAC5F,QAAQ,YAAY,iCAAiC,OAAO,IAAI,aAAa,KAAK,GAAG;EAEvF,CAAC;EACD,OAAO,QAAQ,eAAe,IAAI,OAAO,SAAS,KAAA;CACpD;CAEA,IAAI,MAAkC;EACpC,OAAO,KAAK,KAAK,IAAI,IAAI;CAC3B;CAEA,YAAY,IAAY,WAA2C;EACjE,OAAO,iBAAiB,KAAK,SAAS,IAAI,SAAS,CAAC,CAAC,IAAI;CAC3D;CAEA,gBAAwB,QAAgB,YAAuC;EAC7E,KAAK,YAAY,IAAI,QAAQ,UAAU;EACvC,WACG,cAAc,KAAK,YAAY,OAAO,MAAM,CAAC,CAAC,CAC9C,OAAO,UAAmB,QAAQ,YAAY,2BAA2B,OAAO,IAAI,aAAa,KAAK,GAAG,CAAC;CAC/G;CAEA,SAAmD;EACjD,KAAK,kBAAkB,KAAK,cAAc;EAC1C,OAAO,KAAK;CACd;CAEA,MAAc,gBAAkD;EAC9D,MAAM,SAAS,KAAK,aAAa,WAAW,KAAK,MAAM,eAAe,CAAC,CAAC;EACxE,IAAI;GACF,MAAM,UAAU,MAAM,OAAO,IAAI,CAAC,IAAI,CAAC;GACvC,IAAI,QAAQ,eAAe,GAAG,MAAM,IAAI,MAAM,QAAQ,OAAO,KAAK,KAAK,0BAA0B;GACjG,OAAO;EACT,SAAS,OAAO;GACd,QAAQ,YAAY,wBAAwB,aAAa,KAAK,GAAG;GACjE;EACF;CACF;CAEA,MAAc,QAAQ,MAAmB,MAAwC;EAC/E,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI;EAClC,IAAI,OAAO,eAAe,GACxB,MAAM,IAAI,MAAM,QAAQ,KAAK,MAAM,GAAG,WAAW,OAAO,OAAO,KAAK,KAAK,QAAQ,OAAO,cAAc;CAE1G;CAEA,aAAqB,SAA4B,SAAiB,KAA4B;EAC5F,uBAAuB,GAAG;EAC1B,GAAG,cAAc,SAAS,IAAI,EAAE,MAAM,IAAM,CAAC;EAC7C,MAAM,MAAM,YAAY,QAAQ,WAAW,QAAQ,aAAa,KAAK,GAAG;EACxE,MAAM,OAAoB;GAAE,SAAS,QAAQ;GAAS,KAAK,QAAQ;GAAK;EAAI;EAC5E,iBAAiB,IAAI,MAAM,IAAI;CACjC;CAEA,SAAiB,IAAY,WAAqC;EAChE,OAAO,gBAAgB,KAAK,MAAM,eAAe,SAAS,GAAG,EAAE;CACjE;;;;;;;;;CAUA,eAAuB,SAAiB,UAAkB,SAAoC;EAC5F,MAAM,KAAK,KAAK,SAAS,SAAS,MAAM;EACxC,OAAO,UAAU;GACf,QAAQ;GACR,aAAa,SAAS;GACtB;GACA,KAAK,MAAM,kBAAkB,EAAE;GAC/B,OAAO,eAAe,KAAK,GAAG,CAAC;GAC/B;GACA,GAAI,QAAQ,cAAc,CAAC,KAAK,MAAM,cAAc,EAAE,CAAC,IAAI,CAAC;EAC9D,CAAC;CACH;CAEA,MAAc,QAAQ,MAAmB,QAAgB,KAA2C;EAClG,IAAI;GACF,MAAM,WAAW,MAAM,cAAc,MAAM,QAAQ,IAAI,IAAI;GAC3D,MAAM,gBAAgB,MAAM,QAAQ,IAAI,OAAO;GAC/C,OAAO,iBAAiB,IAAI,IAAI,KAAK;IAAE,MAAM;IAAU,QAAQ;GAAK;EACtE,UAAU;GACR,IAAI,CAAE,MAAM,KAAK,eAAe,MAAM,CAAC,CAAC,YAAY,KAAK,GAAI,MAAM,YAAY,MAAM,MAAM;GAC3F,uBAAuB,GAAG;EAC5B;CACF;CAEA,eACE,QACA,MACA,QACA,YACQ;EACR,IAAI,SAAS;EACb,IAAI,SAAS;EACb,MAAM,2BAAW,IAAI,IAA4B;EACjD,MAAM,UAAU,YAA2B;GACzC,OAAO,QAAQ;IACb,MAAM,WAAW,MAAM,KAAK,IAAI;KAAC;KAAgB;KAAM;KAAM;IAAM,CAAC,CAAC,CAAC,OAAO,UAAmB;KAC9F,QAAQ,YAAY,qCAAqC,OAAO,KAAK,IAAI,aAAa,KAAK,GAAG;IAEhG,CAAC;IACD,MAAM,OAAO,UAAU,eAAe,IAAI,SAAS,SAAS;IAC5D,IAAI,SAAS,QAAQ;KACnB,SAAS;KACT,KAAK,MAAM,WAAW,UAAU,QAAQ,IAAI;IAC9C;IACA,MAAM,MAAA,GAAa;GACrB;EACF;EACA,QAAa;EACb,WACG,cAAc;GACb,SAAS;EACX,CAAC,CAAC,CACD,OAAO,UACN,QAAQ,YAAY,0CAA0C,OAAO,KAAK,IAAI,aAAa,KAAK,GAAG,CACrG;EACF,OAAO;GACL,GAAG;GACH,QAAQ,SAAS;IACf,KACG,IAAI;KAAC;KAAa;KAAM;KAAQ;KAAM;IAAI,CAAC,CAAC,CAC5C,OAAO,UAAmB,QAAQ,YAAY,aAAa,KAAK,CAAC,CAAC;GACvE;GACA,cAAc;GACd,SAAS,YAAY;IACnB,SAAS,IAAI,OAAO;IACpB,aAAa,SAAS,OAAO,OAAO;GACtC;GACA,SAAS,MAAM,SAAS;IACtB,KACG,IAAI;KAAC;KAAiB;KAAM;KAAQ;KAAM,OAAO,IAAI;KAAG;KAAM,OAAO,IAAI;IAAC,CAAC,CAAC,CAC5E,OAAO,UAAmB,QAAQ,YAAY,aAAa,KAAK,CAAC,CAAC;GACvE;EACF;CACF;AACF;AAEA,SAAS,WAAW,gBAAgC;CAClD,MAAM,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,cAAc,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAA,EAAqB;CAClG,OAAO,GAAG,gBAAgB;AAC5B;AAEA,SAAS,YACP,WACA,aACA,KACwB;CACxB,MAAM,SAA4B;EAChC,GAAG;EACH,GAAI,cAAc,CAAC,IAAI;GAAE,GAAG;GAAqB,GAAG,0BAA0B,GAAG;EAAE;EACnF,GAAG;EACH,eAAe;CACjB;CACA,IAAI,CAAC,aAAa,OAAO,OAAO;CAChC,OAAO,OAAO,YACZ,OAAO,QAAQ,MAAM,CAAC,CAAC,QAAQ,UAAqC,MAAM,OAAO,KAAA,CAAS,CAC5F;AACF;AAEA,eAAe,YAAY,MAAmB,QAAkC;CAK9E,QAAO,MAJc,KAAK,IAAI;EAAC;EAAgB;EAAM;CAAM,CAAC,CAAC,CAAC,OAAO,UAAmB;EACtF,QAAQ,YAAY,+BAA+B,OAAO,IAAI,aAAa,KAAK,GAAG;CAErF,CAAC,EAAA,EACc,eAAe;AAChC;AAEA,eAAe,QAAQ,MAAmB,QAAiC;CACzE,MAAM,UAAU,MAAM,KAAK,OAAO,QAAQ,aAAa;CACvD,MAAM,MAAM,OAAO,OAAO;CAC1B,IAAI,CAAC,OAAO,UAAU,GAAG,KAAK,OAAO,GAAG,MAAM,IAAI,MAAM,sCAAsC,QAAQ;CACtG,OAAO;AACT;;;;;;;;AASA,eAAe,cAAc,MAAmB,QAAgB,UAA0C;CACxG,SAAS;EACP,IAAI,GAAG,WAAW,QAAQ,GAAG,OAAO;EACpC,MAAM,QAAQ,MAAM,aAAa,MAAM,MAAM;EAC7C,IAAI,MAAM,QAAQ,OAAO,MAAM;EAC/B,MAAM,MAAA,GAAa;CACrB;AACF;AAEA,eAAe,gBAAgB,MAAmB,QAAgB,UAAiC;CACjG,MAAM,WAAW,KAAK,IAAI,IAAI;CAC9B,OAAO,KAAK,IAAI,IAAI,UAAU;EAC5B,IAAI,GAAG,WAAW,QAAQ,GAAG;EAC7B,IAAI,MAAM,KAAK,eAAe,MAAM,GAAG;EACvC,MAAM,MAAA,EAAuB;CAC/B;AACF;AAEA,eAAe,gBAAgB,MAAmB,QAAgB,WAAqC;CACrG,MAAM,WAAW,KAAK,IAAI,IAAI;CAC9B,OAAO,KAAK,IAAI,IAAI,UAAU;EAC5B,KAAK,MAAM,aAAa,MAAM,MAAM,EAAA,CAAG,QAAQ,OAAO;EACtD,MAAM,MAAA,GAAa;CACrB;CACA,OAAO;AACT;;AAGA,eAAe,aAAa,MAAmB,QAAmE;CAChH,MAAM,UAAU,MAAM,KAAK,OAAO,QAAQ,iBAAiB;CAG3D,IAAI,YAAY,KAAA,GAAW,OAAO;EAAE,QAAQ;EAAM,MAAM;CAAK;CAC7D,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,QAAQ,KAAK,CAAC,CAAC,MAAM,GAAG;CACxD,IAAI,KAAK,KAAK,GAAG,MAAM,IAAI,OAAO;EAAE,QAAQ;EAAM,MAAM;CAAK;CAC7D,IAAI,SAAS,OAAO,SAAS,QAAQ;EACnC,MAAM,OAAO,OAAO,MAAM;EAC1B,OAAO;GAAE,QAAQ;GAAM,MAAM,OAAO,UAAU,IAAI,IAAI,OAAO;EAAK;CACpE;CACA,OAAO;EAAE,QAAQ;EAAO,MAAM;CAAK;AACrC;AAEA,SAAS,WAAW,KAAa,QAAiD;CAChF,IAAI;EACF,QAAQ,KAAK,KAAK,SAAS;EAC3B,OAAO;CACT,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,SAAS,OAAO;EAC9D,QAAQ,YAAY,gCAAgC,OAAO,IAAI,aAAa,KAAK,GAAG;EACpF,OAAO;CACT;AACF;AAEA,SAAS,SAAS,QAAgB,UAA0B;CAC1D,IAAI;CACJ,IAAI;EACF,MAAM,OAAO,GAAG,SAAS,MAAM,CAAC,CAAC;EACjC,MAAM,QAAQ,KAAK,IAAI,MAAM,QAAQ;EACrC,MAAM,SAAS,OAAO,MAAM,KAAK;EACjC,SAAS,GAAG,SAAS,QAAQ,GAAG;EAChC,GAAG,SAAS,QAAQ,QAAQ,GAAG,OAAO,OAAO,KAAK;EAClD,OAAO,OAAO,SAAS,MAAM;CAC/B,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,UAC5C,QAAQ,YAAY,2BAA2B,OAAO,IAAI,aAAa,KAAK,GAAG;EAEjF,OAAO;CACT,UAAU;EACR,IAAI,WAAW,KAAA,GAAW,GAAG,UAAU,MAAM;CAC/C;AACF;AAEA,SAAS,MAAM,IAA2B;CACxC,OAAO,IAAI,SAAS,YAAY;EAE9B,WADyB,SAAS,EAC9B,CAAC,CAAC,QAAQ;CAChB,CAAC;AACH;AAEA,SAAS,aAAa,OAAwB;CAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;;;;ACtaA,SAAS,QAAW,OAAyB;CAC3C,IAAI;CACJ,IAAI,QAAQ;CACZ,aAAa;EACX,IAAI,CAAC,OAAO;GACV,QAAQ,MAAM;GACd,QAAQ;EACV;EACA,OAAO;CACT;AACF;;;;;;;;;;;;AAaA,SAAgB,yBACd,WAKoB;CACpB,MAAM,WACJ,UAAU,aAAa,KAAA,IACnB,KAAA,IACA,OAAO,OAAO;EACZ,GAAG,UAAU;EACb,GAAI,UAAU,UAAU,gBACpB,EAAE,eAAe,OAAO,OAAO,CAAC,GAAG,UAAU,SAAS,aAAa,CAAC,EAAE,IACtE,CAAC;CACP,CAAC;CACP,MAAM,cAAc,EAAE,GAAG,UAAU,YAAY;CAC/C,MAAM,MAAM,UAAU,OAAO,QAAQ,IAAI;CACzC,MAAM,QAAQ,cAAc,UAAU,SAAS,IAAI,YAAY,CAAC;CAChE,MAAM,UAAU,cAAc,UAAU,WAAW,IAAI,YAAY,CAAC;CACpE,MAAM,iBAAiB,cAAc,UAAU,kBAAkB,IAAI,mBAAmB,CAAC;CACzF,MAAM,aAAa,cAAc,UAAU,cAAc,IAAI,eAAe,CAAC;CAC7E,MAAM,QAAQ,cAAc,UAAU,SAAS,IAAI,YAAY,KAAK,WAAW,CAAC;CAChF,MAAM,WAAW,cAAc,UAAU,YAAY,IAAI,aAAa,MAAM,CAAC,CAAC;CAC9E,MAAM,kBAAkB,cAAc,UAAU,mBAAmB,6BAA6B,WAAW,CAAC;CAC5G,MAAM,iBAAiB,cACf,UAAU,kBAAkB,IAAI,eAAe,MAAM,GAAG,eAAe,GAAG,gBAAgB,GAAG,WAAW,CAChH;CACA,MAAM,QAAQ,cAAc,UAAU,SAAS,IAAI,YAAY,eAAe,CAAC,CAAC;CAChF,MAAM,UAAU,cAAc,UAAU,WAAW,IAAI,QAAQ,MAAM,CAAC,CAAC;CACvE,MAAM,YAAY,cAAc,UAAU,aAAa,IAAI,UAAU,CAAC;CACtE,MAAM,WAAW,cAEb,UAAU,YACV,IAAI,SAAS,QAAQ,GAAG,eAAe,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,QAAQ,CAC5G;CACA,MAAM,cAAc,cAEhB,UAAU,eACV,IAAI,gBACF,IAAI,YAAY,MAAM,GAAG,aAAa,QAAQ,GAC9C,IAAI,YAAY,MAAM,GAAG,KAAA,GAAW,aAAa,QAAQ,CAC3D,CACJ;CACA,MAAM,eAAe,cACb,UAAU,gBAAgB,IAAI,aAAa,KAAA,GAAW,KAAA,GAAW,aAAa,QAAQ,CAC9F;CACA,MAAM,UAAU,cACR,UAAU,WAAW,IAAI,QAAQ,WAAW,GAAG,QAAQ,GAAG,eAAe,GAAG,MAAM,GAAG,aAAa,QAAQ,CAClH;CACA,MAAM,iBAAiB,cAEnB,UAAU,kBACV,IAAI,eACF,SAAS,GACT,YAAY,GACZ,MAAM,GACN,eAAe,GACf,MAAM,GACN,aAAa,GACb,KACA,aACA,UAAU,mBAAmB,sBAAsB,WAAW,CAChE,CACJ;CAEA,OAAO;EACL;EACA;EACA,IAAI,QAAQ;GACV,OAAO,MAAM;EACf;EACA,IAAI,UAAU;GACZ,OAAO,QAAQ;EACjB;EACA,IAAI,iBAAiB;GACnB,OAAO,eAAe;EACxB;EACA,IAAI,aAAa;GACf,OAAO,WAAW;EACpB;EACA,IAAI,QAAQ;GACV,OAAO,MAAM;EACf;EACA,IAAI,WAAW;GACb,OAAO,SAAS;EAClB;EACA,IAAI,kBAAkB;GACpB,OAAO,gBAAgB;EACzB;EACA,IAAI,iBAAiB;GACnB,OAAO,eAAe;EACxB;EACA,IAAI,QAAQ;GACV,OAAO,MAAM;EACf;EACA,IAAI,UAAU;GACZ,OAAO,QAAQ;EACjB;EACA,IAAI,YAAY;GACd,OAAO,UAAU;EACnB;EACA,IAAI,WAAW;GACb,OAAO,SAAS;EAClB;EACA,IAAI,cAAc;GAChB,OAAO,YAAY;EACrB;EACA,IAAI,eAAe;GACjB,OAAO,aAAa;EACtB;EACA,IAAI,UAAU;GACZ,OAAO,QAAQ;EACjB;EACA,IAAI,iBAAiB;GACnB,OAAO,eAAe;EACxB;CACF;AACF"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
|
|
2
|
-
const require_bashRunService = require("./bashRunService-
|
|
2
|
+
const require_bashRunService = require("./bashRunService-CJhMNrPz.cjs");
|
|
3
3
|
const require_runnerConfig = require("./runnerConfig-BoLMinlx.cjs");
|
|
4
4
|
const require_logReader = require("./logReader-DHCK2BEr.cjs");
|
|
5
5
|
const require_clock = require("./clock-jqnLWziT.cjs");
|
|
6
|
-
const require_rmuxBackend = require("./rmuxBackend-
|
|
6
|
+
const require_rmuxBackend = require("./rmuxBackend-Cod2H85V.cjs");
|
|
7
7
|
const require_services_runnerSupervisor_index = require("./services/runnerSupervisor/index.cjs");
|
|
8
|
-
const require_rtkProcessor = require("./rtkProcessor-
|
|
8
|
+
const require_rtkProcessor = require("./rtkProcessor-xwARIxhe.cjs");
|
|
9
9
|
const require_launcher = require("./launcher-ZgDdyXpq.cjs");
|
|
10
10
|
const require_lifeline = require("./lifeline-m7laIzIP.cjs");
|
|
11
11
|
const require_logFile = require("./logFile-CnPKtxPy.cjs");
|
|
@@ -664,4 +664,4 @@ Object.defineProperty(exports, "createRunnerDependencies", {
|
|
|
664
664
|
}
|
|
665
665
|
});
|
|
666
666
|
|
|
667
|
-
//# sourceMappingURL=runnerDependencies-
|
|
667
|
+
//# sourceMappingURL=runnerDependencies-HIqMQp9b.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runnerDependencies-DSun3xO-.cjs","names":["shellJoin","runtimeEntry","getResultMaxBytes","readExitMetadata","supervisorPaths","path","getLogMaxBytes","createHash","noninteractiveEnvironment","NO_TERMINAL_INPUT_ENV","fs","SystemClock","NodeSpawner","NodeProcessControl","NodePtySpawner","RunnerPaths","NodeLifeline","createDefaultProcessRegistry","RunnerRegistry","RunnerNamer","LogFile","LogReader","Launcher","RmuxBackend","RtkProcessor","PtyHost","BashRunService","sharedExecutionBudget"],"sources":["../src/constants/tmuxBackend.ts","../src/services/ptyBackendChain/index.ts","../src/services/tmuxBackend/TmuxClient.ts","../src/services/tmuxBackend/index.ts","../src/services/runnerDependencies/index.ts"],"sourcesContent":["export const POLL_MS = 100;\nexport const LOG_DRAIN_TIMEOUT_MS = 2_000;\nexport const LOG_DRAIN_POLL_MS = 25;\nexport const PANE_STATE_FORMAT = '#{pane_dead}:#{pane_dead_status}:#{session_name}';\nexport const STOP_GRACE_MS = 3_000;\nexport const SESSION_PREFIX = 'po-tmux-';\nexport const OWNED_TARGET_PATTERN = /^po-tmux-[A-Za-z0-9_-]+$/;\nexport const TMUX_TARGET_PREFIX = SESSION_PREFIX;\nexport const SOCKET_HASH_LENGTH = 12;\nexport const SOCKET_PREFIX = 'po-tmux-';\nexport const NON_INTERACTIVE_ENV = { NO_COLOR: '1', CI: '1' };\n","import { TMUX_TARGET_PREFIX } from '../../constants/tmuxBackend';\nimport type { RunHandle } from '../../types/launcher';\nimport type { PtyRun } from '../../types/ptyHost';\nimport type { IRmuxBackend, RmuxLaunchRequest } from '../../types/rmuxBackend';\nimport type { ExitResult } from '../../types/spawner';\n\n/**\n * Presents the available PTY backends as one, preferring RMUX.\n *\n * A launch takes the first backend that accepts it, so a host without a\n * compatible RMUX binary still gets panes rather than falling through to the\n * plain subprocess launcher. Every later call routes on the target's prefix\n * instead of asking each backend in turn: a backend cannot tell \"this session\n * is gone\" from \"this session was never mine\", and guessing would let one\n * report success for the other's run.\n */\nexport class PtyBackendChain implements IRmuxBackend {\n constructor(\n private readonly rmux: IRmuxBackend,\n private readonly tmux: IRmuxBackend,\n ) {}\n\n async launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined> {\n return (await this.rmux.launch(request)) ?? (await this.tmux.launch(request));\n }\n\n watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined> {\n return this.owner(target).watch(id, target, sessionId);\n }\n\n stop(target: string, expectedPid: number): Promise<boolean> {\n return this.owner(target).stop(target, expectedPid);\n }\n\n input(target: string, text: string): Promise<boolean> {\n return this.owner(target).input(target, text);\n }\n\n capture(target: string): Promise<string | undefined> {\n return this.owner(target).capture(target);\n }\n\n /** Both backends persist terminal evidence at the same path, so either answers. */\n readOutcome(id: string, sessionId: string): ExitResult | undefined {\n return this.rmux.readOutcome(id, sessionId) ?? this.tmux.readOutcome(id, sessionId);\n }\n\n get(name: string): PtyRun | undefined {\n return this.rmux.get(name) ?? this.tmux.get(name);\n }\n\n private owner(target: string): IRmuxBackend {\n return target.startsWith(TMUX_TARGET_PREFIX) ? this.tmux : this.rmux;\n }\n}\n","import { execFile } from 'node:child_process';\n\nimport type { ITmuxClient, TmuxResult } from '../../types/tmuxClient';\n\nconst TMUX_BINARY = 'tmux';\nconst SOCKET_OPTION = '-L';\n/** Long enough for a loaded server, short enough that a hung tmux is not fatal. */\nconst COMMAND_TIMEOUT_MS = 10_000;\nconst MAX_OUTPUT_BYTES = 4 * 1024 * 1024;\n\nexport class TmuxClient implements ITmuxClient {\n constructor(\n private readonly socket: string,\n private readonly binary = TMUX_BINARY,\n ) {}\n\n run(args: readonly string[]): Promise<TmuxResult> {\n return new Promise((resolve, reject) => {\n execFile(\n this.binary,\n [SOCKET_OPTION, this.socket, ...args],\n { timeout: COMMAND_TIMEOUT_MS, maxBuffer: MAX_OUTPUT_BYTES, encoding: 'utf8' },\n (error, stdout, stderr) => {\n // A non-zero tmux exit is an answer, not a fault: `has-session`\n // reports absence that way. Only a missing or hung binary rejects.\n const code = (error as (Error & { code?: number | string }) | null)?.code;\n if (error && typeof code !== 'number') {\n reject(error);\n return;\n }\n resolve({ returnCode: typeof code === 'number' ? code : 0, stdout, stderr });\n },\n );\n });\n }\n\n async format(target: string, format: string): Promise<string | undefined> {\n const result = await this.run(['display-message', '-p', '-t', target, '-F', format]).catch(() => undefined);\n if (!result || result.returnCode !== 0) return undefined;\n return result.stdout.replace(/\\n$/, '');\n }\n\n async sessionMissing(target: string): Promise<boolean> {\n const result = await this.run(['has-session', '-t', target]).catch(() => undefined);\n return !result || result.returnCode !== 0;\n }\n}\n","import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport {\n LOG_DRAIN_POLL_MS,\n LOG_DRAIN_TIMEOUT_MS,\n NON_INTERACTIVE_ENV,\n OWNED_TARGET_PATTERN,\n PANE_STATE_FORMAT,\n POLL_MS,\n SESSION_PREFIX,\n SOCKET_HASH_LENGTH,\n SOCKET_PREFIX,\n STOP_GRACE_MS,\n} from '../../constants/tmuxBackend';\nimport type { RunHandle } from '../../types/launcher';\nimport type { PtyRun } from '../../types/ptyHost';\nimport type { IRmuxBackend, RmuxLaunchRequest } from '../../types/rmuxBackend';\nimport type { RunnerSettings } from '../../types/runnerSettings';\nimport type { ExitResult } from '../../types/spawner';\nimport type { ITmuxClient } from '../../types/tmuxClient';\nimport { getLogMaxBytes, getResultMaxBytes, noninteractiveEnvironment } from '../runnerConfig';\nimport type { IRunnerPaths } from '../runnerPaths/type';\nimport {\n type CommandSpec,\n type SupervisorPaths,\n cleanupSupervisorFiles,\n NO_TERMINAL_INPUT_ENV,\n readExitMetadata,\n runtimeEntry,\n shellJoin,\n supervisorPaths,\n writeCommandSpec,\n} from '../runnerSupervisor';\nimport { TmuxClient } from './TmuxClient';\n\n/** Pane liveness, its exit status, and whether the session still exists, in one read. */\n/** Distinct from the RMUX prefix so a target names the backend that owns it. */\n\n/**\n * Supervises runs in tmux panes, for hosts with no compatible RMUX binary.\n *\n * The pane runs the same runnerHost supervisor as the RMUX backend, so exit\n * metadata, log rotation, and lifeline handling are shared rather than\n * reimplemented: only the multiplexer differs. Kept beside the RMUX backend\n * rather than folded into it because that path has no unit coverage to\n * refactor against.\n */\nexport class TmuxBackend implements IRmuxBackend {\n private clientPromise: Promise<ITmuxClient | undefined> | undefined;\n private readonly runs = new Map<string, PtyRun>();\n private readonly completions = new Map<string, Promise<ExitResult>>();\n\n constructor(\n private readonly paths: IRunnerPaths,\n private readonly createClient: (socket: string) => ITmuxClient = (socket) => new TmuxClient(socket),\n private readonly env: Readonly<Record<string, string | undefined>> = process.env,\n private readonly settings?: RunnerSettings,\n ) {}\n\n async launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined> {\n const tmux = await this.client();\n if (!tmux) return undefined;\n\n this.paths.ensureDirectories();\n const target = `${SESSION_PREFIX}${request.id}`;\n const logPath = this.paths.logPathFor(request.id);\n const aux = this.auxPaths(request.id, request.sessionId);\n let created = false;\n let released = false;\n\n try {\n this.prepareFiles(request, logPath, aux);\n // One quoted command rather than an argv: tmux takes shell-command as a\n // single word, and quoting here is what keeps a path with spaces intact.\n const supervisor = shellJoin([process.execPath, runtimeEntry('runnerHost'), aux.spec, aux.gate, aux.exit]);\n await this.checked(tmux, ['new-session', '-d', '-s', target, '-c', request.cwd, supervisor]);\n created = true;\n // Set before the gate opens, so it is in force by the time the command\n // can exit. A pane that vanishes on exit takes the log sink down with it\n // before Node has finished starting, losing the output of fast commands,\n // and leaves #{pane_dead} with nothing to report.\n await this.checked(tmux, ['set-option', '-t', target, 'remain-on-exit', 'on']);\n await this.checked(tmux, ['pipe-pane', '-t', target, this.logPipeCommand(logPath, aux.logDone, request)]);\n\n const pid = await panePid(tmux, target);\n fs.writeFileSync(aux.gate, '', { mode: 0o600 });\n released = true;\n\n let buffering = true;\n const completion = this.monitor(tmux, target, aux);\n this.trackCompletion(target, completion);\n const handle: RunHandle = {\n id: request.id,\n name: request.name,\n pid,\n logPath,\n backend: 'tmux',\n backendTarget: target,\n output: () => (buffering ? readTail(logPath, getResultMaxBytes(this.env, this.settings) * 2) : ''),\n completion: () => completion,\n detach: () => {\n buffering = false;\n },\n stop: () => this.stop(target, pid),\n };\n\n if (request.interactive) this.runs.set(request.name, this.interactiveRun(handle, tmux, target, completion));\n void completion\n .finally(() => this.runs.delete(request.name))\n .catch((error: unknown) => process.emitWarning(`tmux completion failed for ${target}: ${errorMessage(error)}`));\n return handle;\n } catch (error) {\n if (released) throw error;\n if (created) await killSession(tmux, target);\n cleanupSupervisorFiles(aux);\n process.emitWarning(\n request.interactive\n ? `tmux launch unavailable for interactive runner: ${errorMessage(error)}`\n : `tmux launch unavailable, using supervised subprocess: ${errorMessage(error)}`,\n );\n return undefined;\n }\n }\n\n async stop(target: string, expectedPid: number): Promise<boolean> {\n if (!OWNED_TARGET_PATTERN.test(target) || !Number.isInteger(expectedPid) || expectedPid <= 0) return false;\n\n const tmux = await this.client();\n if (!tmux) return false;\n try {\n if (await tmux.sessionMissing(target)) return true;\n\n const pid = await panePid(tmux, target);\n if (pid !== expectedPid) return false;\n const signalled = signalPane(pid, target);\n if (signalled === 'gone') return true;\n if (signalled === 'failed') return false;\n\n if (await waitForPaneStop(tmux, target, STOP_GRACE_MS)) return true;\n if (await tmux.sessionMissing(target)) return true;\n\n // Revalidate after the grace period so a replacement pane is never closed.\n const currentPid = await panePid(tmux, target).catch(() => undefined);\n if (currentPid !== expectedPid) return false;\n\n return killSession(tmux, target);\n } catch (error) {\n process.emitWarning(`Could not stop tmux target ${target}: ${errorMessage(error)}`);\n return false;\n }\n }\n\n async watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined> {\n const tmux = await this.client();\n if (!tmux) return undefined;\n if (await tmux.sessionMissing(target)) return undefined;\n const completion = this.monitor(tmux, target, this.auxPaths(id, sessionId));\n this.trackCompletion(target, completion);\n return completion;\n }\n\n async input(target: string, text: string): Promise<boolean> {\n const tmux = await this.client();\n if (!tmux) return false;\n const result = await tmux.run(['send-keys', '-t', target, '-l', text]).catch((error: unknown) => {\n process.emitWarning(`Could not send input to tmux target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result?.returnCode === 0;\n }\n\n async capture(target: string): Promise<string | undefined> {\n const tmux = await this.client();\n if (!tmux) return undefined;\n const result = await tmux.run(['capture-pane', '-p', '-t', target]).catch((error: unknown) => {\n process.emitWarning(`Could not capture tmux target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result?.returnCode === 0 ? result.stdout : undefined;\n }\n\n get(name: string): PtyRun | undefined {\n return this.runs.get(name);\n }\n\n readOutcome(id: string, sessionId: string): ExitResult | undefined {\n return readExitMetadata(this.auxPaths(id, sessionId).exit);\n }\n\n private trackCompletion(target: string, completion: Promise<ExitResult>): void {\n this.completions.set(target, completion);\n void completion\n .finally(() => this.completions.delete(target))\n .catch((error: unknown) => process.emitWarning(`tmux monitor failed for ${target}: ${errorMessage(error)}`));\n }\n\n private client(): Promise<ITmuxClient | undefined> {\n this.clientPromise ??= this.resolveClient();\n return this.clientPromise;\n }\n\n private async resolveClient(): Promise<ITmuxClient | undefined> {\n const client = this.createClient(socketName(this.paths.repositoryPath()));\n try {\n const version = await client.run(['-V']);\n if (version.returnCode !== 0) throw new Error(version.stderr.trim() || 'tmux reported no version');\n return client;\n } catch (error) {\n process.emitWarning(`tmux is unavailable: ${errorMessage(error)}`);\n return undefined;\n }\n }\n\n private async checked(tmux: ITmuxClient, args: readonly string[]): Promise<void> {\n const result = await tmux.run(args);\n if (result.returnCode !== 0) {\n throw new Error(`tmux ${args[0] ?? ''} failed: ${result.stderr.trim() || `exit ${result.returnCode}`}`);\n }\n }\n\n private prepareFiles(request: RmuxLaunchRequest, logPath: string, aux: SupervisorPaths): void {\n cleanupSupervisorFiles(aux);\n fs.writeFileSync(logPath, '', { mode: 0o600 });\n const env = environment(request.sessionId, request.interactive, this.env);\n const spec: CommandSpec = { command: request.command, cwd: request.cwd, env };\n writeCommandSpec(aux.spec, spec);\n }\n\n private auxPaths(id: string, sessionId?: string): SupervisorPaths {\n return supervisorPaths(this.paths.stateDirectory(sessionId), id);\n }\n\n /**\n * The sink the pane pipes into.\n *\n * An interactive run also asks for a raw copy: the scrubbed log it writes\n * beside it has had cursor movement taken out, which is what a terminal\n * needs most. Only interactive runs pay for it, because only they can be\n * attached to.\n */\n private logPipeCommand(logPath: string, donePath: string, request: RmuxLaunchRequest): string {\n const id = path.basename(logPath, '.log');\n return shellJoin([\n process.execPath,\n runtimeEntry('logSink'),\n logPath,\n this.paths.rotatedLogPathFor(id),\n String(getLogMaxBytes(this.env)),\n donePath,\n ...(request.interactive ? [this.paths.rawLogPathFor(id)] : []),\n ]);\n }\n\n private async monitor(tmux: ITmuxClient, target: string, aux: SupervisorPaths): Promise<ExitResult> {\n try {\n const paneCode = await waitForRunEnd(tmux, target, aux.exit);\n await waitForLogDrain(tmux, target, aux.logDone);\n return readExitMetadata(aux.exit) ?? { code: paneCode, signal: null };\n } finally {\n if (!(await tmux.sessionMissing(target).catch(() => false))) await killSession(tmux, target);\n cleanupSupervisorFiles(aux);\n }\n }\n\n private interactiveRun(\n handle: RunHandle,\n tmux: ITmuxClient,\n target: string,\n completion: Promise<ExitResult>,\n ): PtyRun {\n let screen = '';\n let active = true;\n const handlers = new Set<(data: string) => void>();\n const refresh = async (): Promise<void> => {\n while (active) {\n const captured = await tmux.run(['capture-pane', '-p', '-t', target]).catch((error: unknown) => {\n process.emitWarning(`Could not capture tmux screen for ${handle.name}: ${errorMessage(error)}`);\n return undefined;\n });\n const next = captured?.returnCode === 0 ? captured.stdout : screen;\n if (next !== screen) {\n screen = next;\n for (const handler of handlers) handler(next);\n }\n await delay(POLL_MS);\n }\n };\n void refresh();\n void completion\n .finally(() => {\n active = false;\n })\n .catch((error: unknown) =>\n process.emitWarning(`tmux interactive completion failed for ${handle.name}: ${errorMessage(error)}`),\n );\n return {\n ...handle,\n write: (text) => {\n void tmux\n .run(['send-keys', '-t', target, '-l', text])\n .catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n screen: () => screen,\n onData: (handler) => {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n resize: (cols, rows) => {\n void tmux\n .run(['resize-window', '-t', target, '-x', String(cols), '-y', String(rows)])\n .catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n };\n }\n}\n\nfunction socketName(repositoryPath: string): string {\n const hash = createHash('sha256').update(repositoryPath).digest('hex').slice(0, SOCKET_HASH_LENGTH);\n return `${SOCKET_PREFIX}${hash}`;\n}\n\nfunction environment(\n sessionId: string,\n interactive: boolean,\n env: Readonly<Record<string, string | undefined>>,\n): Record<string, string> {\n const values: NodeJS.ProcessEnv = {\n ...env,\n ...(interactive ? {} : { ...NON_INTERACTIVE_ENV, ...noninteractiveEnvironment(env) }),\n ...NO_TERMINAL_INPUT_ENV,\n PI_SESSION_ID: sessionId,\n };\n if (!interactive) delete values['FORCE_COLOR'];\n return Object.fromEntries(\n Object.entries(values).filter((entry): entry is [string, string] => entry[1] !== undefined),\n );\n}\n\nasync function killSession(tmux: ITmuxClient, target: string): Promise<boolean> {\n const result = await tmux.run(['kill-session', '-t', target]).catch((error: unknown) => {\n process.emitWarning(`Could not close tmux target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result?.returnCode === 0;\n}\n\nasync function panePid(tmux: ITmuxClient, target: string): Promise<number> {\n const message = await tmux.format(target, '#{pane_pid}');\n const pid = Number(message);\n if (!Number.isInteger(pid) || pid <= 0) throw new Error(`tmux did not report a pane pid for ${target}`);\n return pid;\n}\n\n/**\n * Waits for the run to end, preferring the supervisor's own record of it.\n *\n * The sidecar is written before the pane can end and outlives the server the\n * pane's exit takes down, so asking tmux is the fallback for a supervisor that\n * died without recording anything.\n */\nasync function waitForRunEnd(tmux: ITmuxClient, target: string, exitPath: string): Promise<number | null> {\n for (;;) {\n if (fs.existsSync(exitPath)) return null;\n const state = await readPaneExit(tmux, target);\n if (state.exited) return state.code;\n await delay(POLL_MS);\n }\n}\n\nasync function waitForLogDrain(tmux: ITmuxClient, target: string, donePath: string): Promise<void> {\n const deadline = Date.now() + LOG_DRAIN_TIMEOUT_MS;\n while (Date.now() < deadline) {\n if (fs.existsSync(donePath)) return;\n if (await tmux.sessionMissing(target)) return;\n await delay(LOG_DRAIN_POLL_MS);\n }\n}\n\nasync function waitForPaneStop(tmux: ITmuxClient, target: string, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if ((await readPaneExit(tmux, target)).exited) return true;\n await delay(POLL_MS);\n }\n return false;\n}\n\n/** One formatted read answers both questions this poll asks. */\nasync function readPaneExit(tmux: ITmuxClient, target: string): Promise<{ exited: boolean; code: number | null }> {\n const message = await tmux.format(target, PANE_STATE_FORMAT);\n // An unreachable server is the ordinary end of the last run: the pane exiting\n // ends its session, and the last session ending stops the server.\n if (message === undefined) return { exited: true, code: null };\n const [dead, status, ...rest] = message.trim().split(':');\n if (rest.join(':') === '') return { exited: true, code: null };\n if (dead === '1' || dead === 'true') {\n const code = Number(status);\n return { exited: true, code: Number.isInteger(code) ? code : null };\n }\n return { exited: false, code: null };\n}\n\nfunction signalPane(pid: number, target: string): 'signalled' | 'gone' | 'failed' {\n try {\n process.kill(pid, 'SIGTERM');\n return 'signalled';\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ESRCH') return 'gone';\n process.emitWarning(`Could not signal tmux target ${target}: ${errorMessage(error)}`);\n return 'failed';\n }\n}\n\nfunction readTail(target: string, maxBytes: number): string {\n let handle: number | undefined;\n try {\n const size = fs.statSync(target).size;\n const bytes = Math.min(size, maxBytes);\n const buffer = Buffer.alloc(bytes);\n handle = fs.openSync(target, 'r');\n fs.readSync(handle, buffer, 0, bytes, size - bytes);\n return buffer.toString('utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n process.emitWarning(`Could not read tmux log ${target}: ${errorMessage(error)}`);\n }\n return '';\n } finally {\n if (handle !== undefined) fs.closeSync(handle);\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n timer.unref?.();\n });\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import { sharedExecutionBudget, type PoHostExecutionBudget } from '@agimon-ai/po-core/packageApi';\n\nimport { BashRunService } from '../bashRunService';\nimport { SystemClock } from '../clock';\nimport { Launcher } from '../launcher';\nimport { NodeLifeline } from '../lifeline';\nimport { LogFile } from '../logFile';\nimport { LogReader } from '../logReader';\nimport { NodeProcessControl } from '../processControl';\nimport { PtyBackendChain } from '../ptyBackendChain';\nimport { PtyHost } from '../ptyHost';\nimport { NodePtySpawner } from '../ptySpawner';\nimport { RmuxBackend } from '../rmuxBackend';\nimport { RtkProcessor } from '../rtkProcessor';\nimport { RunnerNamer } from '../runnerNamer';\nimport { RunnerPaths } from '../runnerPaths';\nimport { RunnerRegistry, createDefaultProcessRegistry } from '../runnerRegistry';\nimport { NodeSpawner } from '../spawner';\nimport { TmuxBackend } from '../tmuxBackend';\nimport type { RunnerDependencies } from './type';\n/** Build once on first access, then hand back the same instance. */\nfunction memoize<T>(build: () => T): () => T {\n let value: T | undefined;\n let built = false;\n return () => {\n if (!built) {\n value = build();\n built = true;\n }\n return value as T;\n };\n}\n\n/**\n * Builds the extension's service graph.\n *\n * A factory rather than a module-level singleton: the extension owns one graph\n * per session, and tests get a fresh one they can substitute ports on through\n * `overrides` without leaking state between cases.\n *\n * Every slot resolves lazily and memoizes, which keeps the previous container's\n * behaviour: nothing is constructed until it is asked for, so opening the SQLite\n * process registry stays deferred until something actually needs a runner.\n */\nexport function createRunnerDependencies(\n overrides: Partial<RunnerDependencies> & {\n environment: Readonly<Record<string, string | undefined>>;\n cwd?: string;\n executionBudget?: PoHostExecutionBudget;\n },\n): RunnerDependencies {\n const settings =\n overrides.settings === undefined\n ? undefined\n : Object.freeze({\n ...overrides.settings,\n ...(overrides.settings?.errorPatterns\n ? { errorPatterns: Object.freeze([...overrides.settings.errorPatterns]) }\n : {}),\n });\n const environment = { ...overrides.environment };\n const cwd = overrides.cwd ?? process.cwd();\n const clock = memoize(() => overrides.clock ?? new SystemClock());\n const spawner = memoize(() => overrides.spawner ?? new NodeSpawner());\n const processControl = memoize(() => overrides.processControl ?? new NodeProcessControl());\n const ptySpawner = memoize(() => overrides.ptySpawner ?? new NodePtySpawner());\n const paths = memoize(() => overrides.paths ?? new RunnerPaths(cwd, environment));\n const lifeline = memoize(() => overrides.lifeline ?? new NodeLifeline(paths()));\n const processRegistry = memoize(() => overrides.processRegistry ?? createDefaultProcessRegistry(environment));\n const runnerRegistry = memoize(\n () => overrides.runnerRegistry ?? new RunnerRegistry(paths(), processControl(), processRegistry(), environment),\n );\n const namer = memoize(() => overrides.namer ?? new RunnerNamer(runnerRegistry()));\n const logFile = memoize(() => overrides.logFile ?? new LogFile(paths()));\n const logReader = memoize(() => overrides.logReader ?? new LogReader());\n const launcher = memoize(\n () =>\n overrides.launcher ??\n new Launcher(spawner(), processControl(), logFile(), clock(), paths(), lifeline(), environment, settings),\n );\n const rmuxBackend = memoize(\n () =>\n overrides.rmuxBackend ??\n new PtyBackendChain(\n new RmuxBackend(paths(), environment, settings),\n new TmuxBackend(paths(), undefined, environment, settings),\n ),\n );\n const rtkProcessor = memoize(\n () => overrides.rtkProcessor ?? new RtkProcessor(undefined, undefined, environment, settings),\n );\n const ptyHost = memoize(\n () => overrides.ptyHost ?? new PtyHost(ptySpawner(), logFile(), processControl(), clock(), environment, settings),\n );\n const bashRunService = memoize(\n () =>\n overrides.bashRunService ??\n new BashRunService(\n launcher(),\n rmuxBackend(),\n namer(),\n runnerRegistry(),\n clock(),\n rtkProcessor(),\n cwd,\n environment,\n overrides.executionBudget ?? sharedExecutionBudget(environment),\n ),\n );\n\n return {\n settings,\n environment,\n get clock() {\n return clock();\n },\n get spawner() {\n return spawner();\n },\n get processControl() {\n return processControl();\n },\n get ptySpawner() {\n return ptySpawner();\n },\n get paths() {\n return paths();\n },\n get lifeline() {\n return lifeline();\n },\n get processRegistry() {\n return processRegistry();\n },\n get runnerRegistry() {\n return runnerRegistry();\n },\n get namer() {\n return namer();\n },\n get logFile() {\n return logFile();\n },\n get logReader() {\n return logReader();\n },\n get launcher() {\n return launcher();\n },\n get rmuxBackend() {\n return rmuxBackend();\n },\n get rtkProcessor() {\n return rtkProcessor();\n },\n get ptyHost() {\n return ptyHost();\n },\n get bashRunService() {\n return bashRunService();\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runnerDependencies-HIqMQp9b.cjs","names":["shellJoin","runtimeEntry","getResultMaxBytes","readExitMetadata","supervisorPaths","path","getLogMaxBytes","createHash","noninteractiveEnvironment","NO_TERMINAL_INPUT_ENV","fs","SystemClock","NodeSpawner","NodeProcessControl","NodePtySpawner","RunnerPaths","NodeLifeline","createDefaultProcessRegistry","RunnerRegistry","RunnerNamer","LogFile","LogReader","Launcher","RmuxBackend","RtkProcessor","PtyHost","BashRunService","sharedExecutionBudget"],"sources":["../src/constants/tmuxBackend.ts","../src/services/ptyBackendChain/index.ts","../src/services/tmuxBackend/TmuxClient.ts","../src/services/tmuxBackend/index.ts","../src/services/runnerDependencies/index.ts"],"sourcesContent":["export const POLL_MS = 100;\nexport const LOG_DRAIN_TIMEOUT_MS = 2_000;\nexport const LOG_DRAIN_POLL_MS = 25;\nexport const PANE_STATE_FORMAT = '#{pane_dead}:#{pane_dead_status}:#{session_name}';\nexport const STOP_GRACE_MS = 3_000;\nexport const SESSION_PREFIX = 'po-tmux-';\nexport const OWNED_TARGET_PATTERN = /^po-tmux-[A-Za-z0-9_-]+$/;\nexport const TMUX_TARGET_PREFIX = SESSION_PREFIX;\nexport const SOCKET_HASH_LENGTH = 12;\nexport const SOCKET_PREFIX = 'po-tmux-';\nexport const NON_INTERACTIVE_ENV = { NO_COLOR: '1', CI: '1' };\n","import { TMUX_TARGET_PREFIX } from '../../constants/tmuxBackend';\nimport type { RunHandle } from '../../types/launcher';\nimport type { PtyRun } from '../../types/ptyHost';\nimport type { IRmuxBackend, RmuxLaunchRequest } from '../../types/rmuxBackend';\nimport type { ExitResult } from '../../types/spawner';\n\n/**\n * Presents the available PTY backends as one, preferring RMUX.\n *\n * A launch takes the first backend that accepts it, so a host without a\n * compatible RMUX binary still gets panes rather than falling through to the\n * plain subprocess launcher. Every later call routes on the target's prefix\n * instead of asking each backend in turn: a backend cannot tell \"this session\n * is gone\" from \"this session was never mine\", and guessing would let one\n * report success for the other's run.\n */\nexport class PtyBackendChain implements IRmuxBackend {\n constructor(\n private readonly rmux: IRmuxBackend,\n private readonly tmux: IRmuxBackend,\n ) {}\n\n async launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined> {\n return (await this.rmux.launch(request)) ?? (await this.tmux.launch(request));\n }\n\n watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined> {\n return this.owner(target).watch(id, target, sessionId);\n }\n\n stop(target: string, expectedPid: number): Promise<boolean> {\n return this.owner(target).stop(target, expectedPid);\n }\n\n input(target: string, text: string): Promise<boolean> {\n return this.owner(target).input(target, text);\n }\n\n capture(target: string): Promise<string | undefined> {\n return this.owner(target).capture(target);\n }\n\n /** Both backends persist terminal evidence at the same path, so either answers. */\n readOutcome(id: string, sessionId: string): ExitResult | undefined {\n return this.rmux.readOutcome(id, sessionId) ?? this.tmux.readOutcome(id, sessionId);\n }\n\n get(name: string): PtyRun | undefined {\n return this.rmux.get(name) ?? this.tmux.get(name);\n }\n\n private owner(target: string): IRmuxBackend {\n return target.startsWith(TMUX_TARGET_PREFIX) ? this.tmux : this.rmux;\n }\n}\n","import { execFile } from 'node:child_process';\n\nimport type { ITmuxClient, TmuxResult } from '../../types/tmuxClient';\n\nconst TMUX_BINARY = 'tmux';\nconst SOCKET_OPTION = '-L';\n/** Long enough for a loaded server, short enough that a hung tmux is not fatal. */\nconst COMMAND_TIMEOUT_MS = 10_000;\nconst MAX_OUTPUT_BYTES = 4 * 1024 * 1024;\n\nexport class TmuxClient implements ITmuxClient {\n constructor(\n private readonly socket: string,\n private readonly binary = TMUX_BINARY,\n ) {}\n\n run(args: readonly string[]): Promise<TmuxResult> {\n return new Promise((resolve, reject) => {\n execFile(\n this.binary,\n [SOCKET_OPTION, this.socket, ...args],\n { timeout: COMMAND_TIMEOUT_MS, maxBuffer: MAX_OUTPUT_BYTES, encoding: 'utf8' },\n (error, stdout, stderr) => {\n // A non-zero tmux exit is an answer, not a fault: `has-session`\n // reports absence that way. Only a missing or hung binary rejects.\n const code = (error as (Error & { code?: number | string }) | null)?.code;\n if (error && typeof code !== 'number') {\n reject(error);\n return;\n }\n resolve({ returnCode: typeof code === 'number' ? code : 0, stdout, stderr });\n },\n );\n });\n }\n\n async format(target: string, format: string): Promise<string | undefined> {\n const result = await this.run(['display-message', '-p', '-t', target, '-F', format]).catch(() => undefined);\n if (!result || result.returnCode !== 0) return undefined;\n return result.stdout.replace(/\\n$/, '');\n }\n\n async sessionMissing(target: string): Promise<boolean> {\n const result = await this.run(['has-session', '-t', target]).catch(() => undefined);\n return !result || result.returnCode !== 0;\n }\n}\n","import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport {\n LOG_DRAIN_POLL_MS,\n LOG_DRAIN_TIMEOUT_MS,\n NON_INTERACTIVE_ENV,\n OWNED_TARGET_PATTERN,\n PANE_STATE_FORMAT,\n POLL_MS,\n SESSION_PREFIX,\n SOCKET_HASH_LENGTH,\n SOCKET_PREFIX,\n STOP_GRACE_MS,\n} from '../../constants/tmuxBackend';\nimport type { RunHandle } from '../../types/launcher';\nimport type { PtyRun } from '../../types/ptyHost';\nimport type { IRmuxBackend, RmuxLaunchRequest } from '../../types/rmuxBackend';\nimport type { RunnerSettings } from '../../types/runnerSettings';\nimport type { ExitResult } from '../../types/spawner';\nimport type { ITmuxClient } from '../../types/tmuxClient';\nimport { getLogMaxBytes, getResultMaxBytes, noninteractiveEnvironment } from '../runnerConfig';\nimport type { IRunnerPaths } from '../runnerPaths/type';\nimport {\n type CommandSpec,\n type SupervisorPaths,\n cleanupSupervisorFiles,\n NO_TERMINAL_INPUT_ENV,\n readExitMetadata,\n runtimeEntry,\n shellJoin,\n supervisorPaths,\n writeCommandSpec,\n} from '../runnerSupervisor';\nimport { TmuxClient } from './TmuxClient';\n\n/** Pane liveness, its exit status, and whether the session still exists, in one read. */\n/** Distinct from the RMUX prefix so a target names the backend that owns it. */\n\n/**\n * Supervises runs in tmux panes, for hosts with no compatible RMUX binary.\n *\n * The pane runs the same runnerHost supervisor as the RMUX backend, so exit\n * metadata, log rotation, and lifeline handling are shared rather than\n * reimplemented: only the multiplexer differs. Kept beside the RMUX backend\n * rather than folded into it because that path has no unit coverage to\n * refactor against.\n */\nexport class TmuxBackend implements IRmuxBackend {\n private clientPromise: Promise<ITmuxClient | undefined> | undefined;\n private readonly runs = new Map<string, PtyRun>();\n private readonly completions = new Map<string, Promise<ExitResult>>();\n\n constructor(\n private readonly paths: IRunnerPaths,\n private readonly createClient: (socket: string) => ITmuxClient = (socket) => new TmuxClient(socket),\n private readonly env: Readonly<Record<string, string | undefined>> = process.env,\n private readonly settings?: RunnerSettings,\n ) {}\n\n async launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined> {\n const tmux = await this.client();\n if (!tmux) return undefined;\n\n this.paths.ensureDirectories();\n const target = `${SESSION_PREFIX}${request.id}`;\n const logPath = this.paths.logPathFor(request.id);\n const aux = this.auxPaths(request.id, request.sessionId);\n let created = false;\n let released = false;\n\n try {\n this.prepareFiles(request, logPath, aux);\n // One quoted command rather than an argv: tmux takes shell-command as a\n // single word, and quoting here is what keeps a path with spaces intact.\n const supervisor = shellJoin([process.execPath, runtimeEntry('runnerHost'), aux.spec, aux.gate, aux.exit]);\n await this.checked(tmux, ['new-session', '-d', '-s', target, '-c', request.cwd, supervisor]);\n created = true;\n // Set before the gate opens, so it is in force by the time the command\n // can exit. A pane that vanishes on exit takes the log sink down with it\n // before Node has finished starting, losing the output of fast commands,\n // and leaves #{pane_dead} with nothing to report.\n await this.checked(tmux, ['set-option', '-t', target, 'remain-on-exit', 'on']);\n await this.checked(tmux, ['pipe-pane', '-t', target, this.logPipeCommand(logPath, aux.logDone, request)]);\n\n const pid = await panePid(tmux, target);\n fs.writeFileSync(aux.gate, '', { mode: 0o600 });\n released = true;\n\n let buffering = true;\n const completion = this.monitor(tmux, target, aux);\n this.trackCompletion(target, completion);\n const handle: RunHandle = {\n id: request.id,\n name: request.name,\n pid,\n logPath,\n backend: 'tmux',\n backendTarget: target,\n output: () => (buffering ? readTail(logPath, getResultMaxBytes(this.env, this.settings) * 2) : ''),\n completion: () => completion,\n detach: () => {\n buffering = false;\n },\n stop: () => this.stop(target, pid),\n };\n\n if (request.interactive) this.runs.set(request.name, this.interactiveRun(handle, tmux, target, completion));\n void completion\n .finally(() => this.runs.delete(request.name))\n .catch((error: unknown) => process.emitWarning(`tmux completion failed for ${target}: ${errorMessage(error)}`));\n return handle;\n } catch (error) {\n if (released) throw error;\n if (created) await killSession(tmux, target);\n cleanupSupervisorFiles(aux);\n process.emitWarning(\n request.interactive\n ? `tmux launch unavailable for interactive runner: ${errorMessage(error)}`\n : `tmux launch unavailable, using supervised subprocess: ${errorMessage(error)}`,\n );\n return undefined;\n }\n }\n\n async stop(target: string, expectedPid: number): Promise<boolean> {\n if (!OWNED_TARGET_PATTERN.test(target) || !Number.isInteger(expectedPid) || expectedPid <= 0) return false;\n\n const tmux = await this.client();\n if (!tmux) return false;\n try {\n if (await tmux.sessionMissing(target)) return true;\n\n const pid = await panePid(tmux, target);\n if (pid !== expectedPid) return false;\n const signalled = signalPane(pid, target);\n if (signalled === 'gone') return true;\n if (signalled === 'failed') return false;\n\n if (await waitForPaneStop(tmux, target, STOP_GRACE_MS)) return true;\n if (await tmux.sessionMissing(target)) return true;\n\n // Revalidate after the grace period so a replacement pane is never closed.\n const currentPid = await panePid(tmux, target).catch(() => undefined);\n if (currentPid !== expectedPid) return false;\n\n return killSession(tmux, target);\n } catch (error) {\n process.emitWarning(`Could not stop tmux target ${target}: ${errorMessage(error)}`);\n return false;\n }\n }\n\n async watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined> {\n const tmux = await this.client();\n if (!tmux) return undefined;\n if (await tmux.sessionMissing(target)) return undefined;\n const completion = this.monitor(tmux, target, this.auxPaths(id, sessionId));\n this.trackCompletion(target, completion);\n return completion;\n }\n\n async input(target: string, text: string): Promise<boolean> {\n const tmux = await this.client();\n if (!tmux) return false;\n const result = await tmux.run(['send-keys', '-t', target, '-l', text]).catch((error: unknown) => {\n process.emitWarning(`Could not send input to tmux target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result?.returnCode === 0;\n }\n\n async capture(target: string): Promise<string | undefined> {\n const tmux = await this.client();\n if (!tmux) return undefined;\n const result = await tmux.run(['capture-pane', '-p', '-t', target]).catch((error: unknown) => {\n process.emitWarning(`Could not capture tmux target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result?.returnCode === 0 ? result.stdout : undefined;\n }\n\n get(name: string): PtyRun | undefined {\n return this.runs.get(name);\n }\n\n readOutcome(id: string, sessionId: string): ExitResult | undefined {\n return readExitMetadata(this.auxPaths(id, sessionId).exit);\n }\n\n private trackCompletion(target: string, completion: Promise<ExitResult>): void {\n this.completions.set(target, completion);\n void completion\n .finally(() => this.completions.delete(target))\n .catch((error: unknown) => process.emitWarning(`tmux monitor failed for ${target}: ${errorMessage(error)}`));\n }\n\n private client(): Promise<ITmuxClient | undefined> {\n this.clientPromise ??= this.resolveClient();\n return this.clientPromise;\n }\n\n private async resolveClient(): Promise<ITmuxClient | undefined> {\n const client = this.createClient(socketName(this.paths.repositoryPath()));\n try {\n const version = await client.run(['-V']);\n if (version.returnCode !== 0) throw new Error(version.stderr.trim() || 'tmux reported no version');\n return client;\n } catch (error) {\n process.emitWarning(`tmux is unavailable: ${errorMessage(error)}`);\n return undefined;\n }\n }\n\n private async checked(tmux: ITmuxClient, args: readonly string[]): Promise<void> {\n const result = await tmux.run(args);\n if (result.returnCode !== 0) {\n throw new Error(`tmux ${args[0] ?? ''} failed: ${result.stderr.trim() || `exit ${result.returnCode}`}`);\n }\n }\n\n private prepareFiles(request: RmuxLaunchRequest, logPath: string, aux: SupervisorPaths): void {\n cleanupSupervisorFiles(aux);\n fs.writeFileSync(logPath, '', { mode: 0o600 });\n const env = environment(request.sessionId, request.interactive, this.env);\n const spec: CommandSpec = { command: request.command, cwd: request.cwd, env };\n writeCommandSpec(aux.spec, spec);\n }\n\n private auxPaths(id: string, sessionId?: string): SupervisorPaths {\n return supervisorPaths(this.paths.stateDirectory(sessionId), id);\n }\n\n /**\n * The sink the pane pipes into.\n *\n * An interactive run also asks for a raw copy: the scrubbed log it writes\n * beside it has had cursor movement taken out, which is what a terminal\n * needs most. Only interactive runs pay for it, because only they can be\n * attached to.\n */\n private logPipeCommand(logPath: string, donePath: string, request: RmuxLaunchRequest): string {\n const id = path.basename(logPath, '.log');\n return shellJoin([\n process.execPath,\n runtimeEntry('logSink'),\n logPath,\n this.paths.rotatedLogPathFor(id),\n String(getLogMaxBytes(this.env)),\n donePath,\n ...(request.interactive ? [this.paths.rawLogPathFor(id)] : []),\n ]);\n }\n\n private async monitor(tmux: ITmuxClient, target: string, aux: SupervisorPaths): Promise<ExitResult> {\n try {\n const paneCode = await waitForRunEnd(tmux, target, aux.exit);\n await waitForLogDrain(tmux, target, aux.logDone);\n return readExitMetadata(aux.exit) ?? { code: paneCode, signal: null };\n } finally {\n if (!(await tmux.sessionMissing(target).catch(() => false))) await killSession(tmux, target);\n cleanupSupervisorFiles(aux);\n }\n }\n\n private interactiveRun(\n handle: RunHandle,\n tmux: ITmuxClient,\n target: string,\n completion: Promise<ExitResult>,\n ): PtyRun {\n let screen = '';\n let active = true;\n const handlers = new Set<(data: string) => void>();\n const refresh = async (): Promise<void> => {\n while (active) {\n const captured = await tmux.run(['capture-pane', '-p', '-t', target]).catch((error: unknown) => {\n process.emitWarning(`Could not capture tmux screen for ${handle.name}: ${errorMessage(error)}`);\n return undefined;\n });\n const next = captured?.returnCode === 0 ? captured.stdout : screen;\n if (next !== screen) {\n screen = next;\n for (const handler of handlers) handler(next);\n }\n await delay(POLL_MS);\n }\n };\n void refresh();\n void completion\n .finally(() => {\n active = false;\n })\n .catch((error: unknown) =>\n process.emitWarning(`tmux interactive completion failed for ${handle.name}: ${errorMessage(error)}`),\n );\n return {\n ...handle,\n write: (text) => {\n void tmux\n .run(['send-keys', '-t', target, '-l', text])\n .catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n screen: () => screen,\n onData: (handler) => {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n resize: (cols, rows) => {\n void tmux\n .run(['resize-window', '-t', target, '-x', String(cols), '-y', String(rows)])\n .catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n };\n }\n}\n\nfunction socketName(repositoryPath: string): string {\n const hash = createHash('sha256').update(repositoryPath).digest('hex').slice(0, SOCKET_HASH_LENGTH);\n return `${SOCKET_PREFIX}${hash}`;\n}\n\nfunction environment(\n sessionId: string,\n interactive: boolean,\n env: Readonly<Record<string, string | undefined>>,\n): Record<string, string> {\n const values: NodeJS.ProcessEnv = {\n ...env,\n ...(interactive ? {} : { ...NON_INTERACTIVE_ENV, ...noninteractiveEnvironment(env) }),\n ...NO_TERMINAL_INPUT_ENV,\n PI_SESSION_ID: sessionId,\n };\n if (!interactive) delete values['FORCE_COLOR'];\n return Object.fromEntries(\n Object.entries(values).filter((entry): entry is [string, string] => entry[1] !== undefined),\n );\n}\n\nasync function killSession(tmux: ITmuxClient, target: string): Promise<boolean> {\n const result = await tmux.run(['kill-session', '-t', target]).catch((error: unknown) => {\n process.emitWarning(`Could not close tmux target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result?.returnCode === 0;\n}\n\nasync function panePid(tmux: ITmuxClient, target: string): Promise<number> {\n const message = await tmux.format(target, '#{pane_pid}');\n const pid = Number(message);\n if (!Number.isInteger(pid) || pid <= 0) throw new Error(`tmux did not report a pane pid for ${target}`);\n return pid;\n}\n\n/**\n * Waits for the run to end, preferring the supervisor's own record of it.\n *\n * The sidecar is written before the pane can end and outlives the server the\n * pane's exit takes down, so asking tmux is the fallback for a supervisor that\n * died without recording anything.\n */\nasync function waitForRunEnd(tmux: ITmuxClient, target: string, exitPath: string): Promise<number | null> {\n for (;;) {\n if (fs.existsSync(exitPath)) return null;\n const state = await readPaneExit(tmux, target);\n if (state.exited) return state.code;\n await delay(POLL_MS);\n }\n}\n\nasync function waitForLogDrain(tmux: ITmuxClient, target: string, donePath: string): Promise<void> {\n const deadline = Date.now() + LOG_DRAIN_TIMEOUT_MS;\n while (Date.now() < deadline) {\n if (fs.existsSync(donePath)) return;\n if (await tmux.sessionMissing(target)) return;\n await delay(LOG_DRAIN_POLL_MS);\n }\n}\n\nasync function waitForPaneStop(tmux: ITmuxClient, target: string, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if ((await readPaneExit(tmux, target)).exited) return true;\n await delay(POLL_MS);\n }\n return false;\n}\n\n/** One formatted read answers both questions this poll asks. */\nasync function readPaneExit(tmux: ITmuxClient, target: string): Promise<{ exited: boolean; code: number | null }> {\n const message = await tmux.format(target, PANE_STATE_FORMAT);\n // An unreachable server is the ordinary end of the last run: the pane exiting\n // ends its session, and the last session ending stops the server.\n if (message === undefined) return { exited: true, code: null };\n const [dead, status, ...rest] = message.trim().split(':');\n if (rest.join(':') === '') return { exited: true, code: null };\n if (dead === '1' || dead === 'true') {\n const code = Number(status);\n return { exited: true, code: Number.isInteger(code) ? code : null };\n }\n return { exited: false, code: null };\n}\n\nfunction signalPane(pid: number, target: string): 'signalled' | 'gone' | 'failed' {\n try {\n process.kill(pid, 'SIGTERM');\n return 'signalled';\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ESRCH') return 'gone';\n process.emitWarning(`Could not signal tmux target ${target}: ${errorMessage(error)}`);\n return 'failed';\n }\n}\n\nfunction readTail(target: string, maxBytes: number): string {\n let handle: number | undefined;\n try {\n const size = fs.statSync(target).size;\n const bytes = Math.min(size, maxBytes);\n const buffer = Buffer.alloc(bytes);\n handle = fs.openSync(target, 'r');\n fs.readSync(handle, buffer, 0, bytes, size - bytes);\n return buffer.toString('utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n process.emitWarning(`Could not read tmux log ${target}: ${errorMessage(error)}`);\n }\n return '';\n } finally {\n if (handle !== undefined) fs.closeSync(handle);\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n timer.unref?.();\n });\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import { sharedExecutionBudget, type PoHostExecutionBudget } from '@agimon-ai/po-core/packageApi';\n\nimport { BashRunService } from '../bashRunService';\nimport { SystemClock } from '../clock';\nimport { Launcher } from '../launcher';\nimport { NodeLifeline } from '../lifeline';\nimport { LogFile } from '../logFile';\nimport { LogReader } from '../logReader';\nimport { NodeProcessControl } from '../processControl';\nimport { PtyBackendChain } from '../ptyBackendChain';\nimport { PtyHost } from '../ptyHost';\nimport { NodePtySpawner } from '../ptySpawner';\nimport { RmuxBackend } from '../rmuxBackend';\nimport { RtkProcessor } from '../rtkProcessor';\nimport { RunnerNamer } from '../runnerNamer';\nimport { RunnerPaths } from '../runnerPaths';\nimport { RunnerRegistry, createDefaultProcessRegistry } from '../runnerRegistry';\nimport { NodeSpawner } from '../spawner';\nimport { TmuxBackend } from '../tmuxBackend';\nimport type { RunnerDependencies } from './type';\n/** Build once on first access, then hand back the same instance. */\nfunction memoize<T>(build: () => T): () => T {\n let value: T | undefined;\n let built = false;\n return () => {\n if (!built) {\n value = build();\n built = true;\n }\n return value as T;\n };\n}\n\n/**\n * Builds the extension's service graph.\n *\n * A factory rather than a module-level singleton: the extension owns one graph\n * per session, and tests get a fresh one they can substitute ports on through\n * `overrides` without leaking state between cases.\n *\n * Every slot resolves lazily and memoizes, which keeps the previous container's\n * behaviour: nothing is constructed until it is asked for, so opening the SQLite\n * process registry stays deferred until something actually needs a runner.\n */\nexport function createRunnerDependencies(\n overrides: Partial<RunnerDependencies> & {\n environment: Readonly<Record<string, string | undefined>>;\n cwd?: string;\n executionBudget?: PoHostExecutionBudget;\n },\n): RunnerDependencies {\n const settings =\n overrides.settings === undefined\n ? undefined\n : Object.freeze({\n ...overrides.settings,\n ...(overrides.settings?.errorPatterns\n ? { errorPatterns: Object.freeze([...overrides.settings.errorPatterns]) }\n : {}),\n });\n const environment = { ...overrides.environment };\n const cwd = overrides.cwd ?? process.cwd();\n const clock = memoize(() => overrides.clock ?? new SystemClock());\n const spawner = memoize(() => overrides.spawner ?? new NodeSpawner());\n const processControl = memoize(() => overrides.processControl ?? new NodeProcessControl());\n const ptySpawner = memoize(() => overrides.ptySpawner ?? new NodePtySpawner());\n const paths = memoize(() => overrides.paths ?? new RunnerPaths(cwd, environment));\n const lifeline = memoize(() => overrides.lifeline ?? new NodeLifeline(paths()));\n const processRegistry = memoize(() => overrides.processRegistry ?? createDefaultProcessRegistry(environment));\n const runnerRegistry = memoize(\n () => overrides.runnerRegistry ?? new RunnerRegistry(paths(), processControl(), processRegistry(), environment),\n );\n const namer = memoize(() => overrides.namer ?? new RunnerNamer(runnerRegistry()));\n const logFile = memoize(() => overrides.logFile ?? new LogFile(paths()));\n const logReader = memoize(() => overrides.logReader ?? new LogReader());\n const launcher = memoize(\n () =>\n overrides.launcher ??\n new Launcher(spawner(), processControl(), logFile(), clock(), paths(), lifeline(), environment, settings),\n );\n const rmuxBackend = memoize(\n () =>\n overrides.rmuxBackend ??\n new PtyBackendChain(\n new RmuxBackend(paths(), environment, settings),\n new TmuxBackend(paths(), undefined, environment, settings),\n ),\n );\n const rtkProcessor = memoize(\n () => overrides.rtkProcessor ?? new RtkProcessor(undefined, undefined, environment, settings),\n );\n const ptyHost = memoize(\n () => overrides.ptyHost ?? new PtyHost(ptySpawner(), logFile(), processControl(), clock(), environment, settings),\n );\n const bashRunService = memoize(\n () =>\n overrides.bashRunService ??\n new BashRunService(\n launcher(),\n rmuxBackend(),\n namer(),\n runnerRegistry(),\n clock(),\n rtkProcessor(),\n cwd,\n environment,\n overrides.executionBudget ?? sharedExecutionBudget(environment),\n ),\n );\n\n return {\n settings,\n environment,\n get clock() {\n return clock();\n },\n get spawner() {\n return spawner();\n },\n get processControl() {\n return processControl();\n },\n get ptySpawner() {\n return ptySpawner();\n },\n get paths() {\n return paths();\n },\n get lifeline() {\n return lifeline();\n },\n get processRegistry() {\n return processRegistry();\n },\n get runnerRegistry() {\n return runnerRegistry();\n },\n get namer() {\n return namer();\n },\n get logFile() {\n return logFile();\n },\n get logReader() {\n return logReader();\n },\n get launcher() {\n return launcher();\n },\n get rmuxBackend() {\n return rmuxBackend();\n },\n get rtkProcessor() {\n return rtkProcessor();\n },\n get ptyHost() {\n return ptyHost();\n },\n get bashRunService() {\n return bashRunService();\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_runnerDependencies = require("./runnerDependencies-
|
|
2
|
+
const require_runnerDependencies = require("./runnerDependencies-HIqMQp9b.cjs");
|
|
3
3
|
exports.createRunnerDependencies = require_runnerDependencies.createRunnerDependencies;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createRunnerDependencies } from "./index
|
|
1
|
+
import { t as createRunnerDependencies } from "./index-CXbcmf-G.mjs";
|
|
2
2
|
export { createRunnerDependencies };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as createRunnerDependencies } from "./runnerDependencies-
|
|
1
|
+
export { t as createRunnerDependencies } from "./runnerDependencies-CamKwphq.mjs";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as IRtkProcessor } from "./rtkProcessor-CVZvNhkJ.mjs";
|
|
2
|
-
import { a as IBashRunService } from "./bashRunService-
|
|
2
|
+
import { a as IBashRunService } from "./bashRunService-BL4JIUi2.mjs";
|
|
3
3
|
import { t as IClock } from "./clock-euJkweLq.mjs";
|
|
4
4
|
import { n as ISpawner } from "./spawner-CdrN_HNk.mjs";
|
|
5
5
|
import { t as ILauncher } from "./launcher-BG5t9nvG.mjs";
|
|
@@ -40,4 +40,4 @@ interface RunnerDependencies {
|
|
|
40
40
|
}
|
|
41
41
|
//#endregion
|
|
42
42
|
export { RunnerDependencies as t };
|
|
43
|
-
//# sourceMappingURL=type-
|
|
43
|
+
//# sourceMappingURL=type-BQ2shEB5.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-
|
|
1
|
+
{"version":3,"file":"type-BQ2shEB5.d.mts","names":[],"sources":["../src/services/runnerDependencies/type.ts"],"mappings":";;;;;;;;;;;;;;;;;;;UAmBiB;WACN,WAAW;WACX,aAAa,SAAS;WACtB,OAAO;WACP,SAAS;WACT,gBAAgB;WAChB,YAAY;WACZ,OAAO;WACP,UAAU;WACV,gBAAgB;WAChB,OAAO;WACP,SAAS;WACT,WAAW;WACX,UAAU;WACV,aAAa;WACb,cAAc;WACd,SAAS;WACT,gBAAgB;;WAEhB,iBAAiB"}
|
package/dist/types.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { c as RtkProcessResult, l as RtkProcessedOutput, o as RtkFilter, s as RtkProcessRequest, t as IRtkProcessor } from "./rtkProcessor-CVZvNhkJ.mjs";
|
|
2
|
-
import { t as RunnerDependencies } from "./type-
|
|
2
|
+
import { t as RunnerDependencies } from "./type-BQ2shEB5.mjs";
|
|
3
3
|
export type { IRtkProcessor, RtkFilter, RtkProcessRequest, RtkProcessResult, RtkProcessedOutput, RunnerDependencies };
|