@jentrix/runner 0.5.13 → 0.5.15

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/README.md CHANGED
@@ -132,10 +132,10 @@ Setup:
132
132
 
133
133
  | Context loaded up front | Bytes | ≈ Tokens |
134
134
  | --- | --- | --- |
135
- | MCP agent — all 242 tool definitions | 387 KB | ~105k |
135
+ | MCP agent — all 242 tool definitions | 374 KB | ~101k |
136
136
  | CLI agent — `CLI_STANDUP_SYSTEM_PROMPT` only | 2 KB | ~510 |
137
137
 
138
- That is a **~205× smaller** Jentrix-specific up-front context.
138
+ That is a **~198× smaller** Jentrix-specific up-front context.
139
139
  <!-- END GENERATED: mcp-tool-count:agent-token-cost -->
140
140
 
141
141
  Reproduce the two numbers directly:
@@ -0,0 +1,7 @@
1
+ // lib/version.ts
2
+ var RUNNER_VERSION = "0.5.15";
3
+
4
+ export {
5
+ RUNNER_VERSION
6
+ };
7
+ //# sourceMappingURL=chunk-PTARP62V.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../lib/version.ts"],
4
- "sourcesContent": ["export const RUNNER_VERSION = \"0.5.13\";\n"],
4
+ "sourcesContent": ["export const RUNNER_VERSION = \"0.5.15\";\n"],
5
5
  "mappings": ";AAAO,IAAM,iBAAiB;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  RUNNER_VERSION
4
- } from "./chunk-QBB7WO4L.js";
4
+ } from "./chunk-PTARP62V.js";
5
5
 
6
6
  // runner-cli.ts
7
7
  import { fileURLToPath } from "node:url";
@@ -219,7 +219,7 @@ async function main(args = process.argv.slice(2)) {
219
219
  return runConfiguredRunner(args.includes("--once"));
220
220
  }
221
221
  if (command === "session-run" && (args.includes("--plan-stdin") || args.includes("--plan-file"))) {
222
- const { runSessionHost } = await import("./session-host-X4B43PJJ.js");
222
+ const { runSessionHost } = await import("./session-host-DMDLRICG.js");
223
223
  let raw;
224
224
  const planFile = valueAfter(args, "--plan-file");
225
225
  if (planFile) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../runner-cli.ts"],
4
- "sourcesContent": ["#!/usr/bin/env node\nimport { fileURLToPath } from \"node:url\";\nimport { spawn } from \"node:child_process\";\nimport { realpathSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport type { RunnerConfig } from \"./lib/runner-config.js\";\nimport type { RunnerSetupApply } from \"./lib/runner-setup.js\";\nimport { RUNNER_VERSION } from \"./lib/version.js\";\n\n// ---------------------------------------------------------------------------\n// TYPE-ONLY above, and that is load-bearing (MVP separation P5).\n//\n// `probe`, `setup-apply` and `run` are the PLATFORM half of this binary: they\n// enroll a worker and poll for agent jobs, both of which are planes. The MVP\n// deployment uses only the session half (`session-run`, `session-hook`), and\n// `session-hook` in particular is invoked by a Claude Code lifecycle hook \u2014\n// several times per conversation, on the operator's critical path.\n//\n// Statically importing `local-probes` put `@anthropic-ai/claude-agent-sdk` at\n// the top of the built bundle, so EVERY invocation paid to load 4.5 MB of a\n// provider SDK the session half never touches: ~90ms per hook against a ~10ms\n// bare-node baseline. The three `await import(\u2026)` calls below move that cost\n// into the branches that actually need it.\n//\n// The dependency itself stays REQUIRED rather than optional. Making it\n// optional is the packaging half of this question and it breaks a platform\n// operator's `npm i -g` in a way this refactor should not decide silently \u2014\n// see `plans/mvp-separation-strategy.md` \u00A7 P5.\n// ---------------------------------------------------------------------------\n\nexport const RUNNER_PROTOCOL_VERSION = 1;\nexport { RUNNER_VERSION };\n\n/**\n * STA-131 \u2014 the default hook-context dir per provider, resolved in code. A\n * `$HOME` literal on hook argv never expands on Windows (no POSIX shell), so\n * the plugins pass `--provider` and the path is built here, cross-platform.\n */\nexport function sessionHookDir(\n provider: string | null,\n home: string = homedir(),\n): string | null {\n return provider === \"claude\" || provider === \"codex\"\n ? join(home, \".config\", \"stacks\", `${provider}-sessions`)\n : null;\n}\n\nexport function runnerVersionEnvelope() {\n return {\n protocolVersion: RUNNER_PROTOCOL_VERSION,\n runnerVersion: RUNNER_VERSION,\n };\n}\n\nexport function runnerEnvironment(\n config: RunnerConfig,\n configPath: string,\n once: boolean,\n base: NodeJS.ProcessEnv = process.env,\n): NodeJS.ProcessEnv {\n return {\n ...base,\n STACKS_BASE_URL: config.jentrixBaseUrl,\n STACKS_MCP_URL: config.mcpUrl,\n STACKS_RUNNER_MODE: \"self-hosted\",\n STACKS_BOOTSTRAP_TOKEN: config.bootstrapToken,\n STACKS_CLAIM_URL: config.claimUrl,\n STACKS_RUNNER_AUTH_STATE: `${configPath}.auth.json`,\n STACKS_WORKER_HEARTBEAT_TOKEN: config.heartbeatToken,\n STACKS_RUNNER_ROLE_BINDINGS: JSON.stringify(config.roleBindings),\n STACKS_RUNNER_HOST: \"127.0.0.1\",\n STACKS_CLAUDE_EXECUTABLE: config.executables.claude,\n STACKS_CODEX_EXECUTABLE: config.executables.codex,\n STACKS_POLL_MS: base.STACKS_POLL_MS ?? \"30000\",\n ...(once ? { STACKS_RUNNER_ONCE: \"1\" } : {}),\n };\n}\n\nexport function terminationHandlers(kill: (signal: NodeJS.Signals) => unknown) {\n return {\n interrupt: () => kill(\"SIGINT\"),\n terminate: () => kill(\"SIGTERM\"),\n };\n}\n\nexport function assertRunnerConfigCompatibility(config: RunnerConfig): void {\n if (config.protocolVersion !== RUNNER_PROTOCOL_VERSION) {\n throw new Error(\n `RUNNER_VERSION_MISMATCH: run: npm install --global @jentrix/cli@${RUNNER_VERSION} @jentrix/runner@${RUNNER_VERSION}`,\n );\n }\n}\n\nasync function runConfiguredRunner(once: boolean): Promise<number> {\n const { probeLocalRuntimes } = await import(\"./lib/local-probes.js\");\n const { readRunnerConfig, runnerConfigPath } = await import(\n \"./lib/runner-config.js\"\n );\n const { applyRunnerSetup } = await import(\"./lib/runner-setup.js\");\n const configPath = runnerConfigPath();\n let config: RunnerConfig;\n try {\n config = await readRunnerConfig(configPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException)?.code === \"ENOENT\") {\n throw new Error(\"BOOTSTRAP_REQUIRED: run jentrix runner setup.\");\n }\n throw error;\n }\n assertRunnerConfigCompatibility(config);\n const runtimes = await probeLocalRuntimes({\n claudePath: config.executables.claude,\n codexPath: config.executables.codex,\n });\n const probes = new Map(\n runtimes.map((runtime) => [runtime.adapterKey, runtime]),\n );\n for (const binding of Object.values(config.roleBindings)) {\n const probe = probes.get(binding.runtimeAdapterKey);\n if (!probe || probe.status !== \"ready\") {\n throw new Error(\n `ROLE_PLAN_UNSATISFIED: ${binding.runtimeAdapterKey} is not ready for a configured role.`,\n );\n }\n if (\n probe.availableModels.length > 0 &&\n !probe.availableModels.some((model) => model.id === binding.model)\n ) {\n throw new Error(\n `ROLE_PLAN_UNSATISFIED: ${binding.runtimeAdapterKey} cannot run configured model ${binding.model}.`,\n );\n }\n }\n await applyRunnerSetup(\n {\n protocolVersion: config.protocolVersion,\n runnerVersion: config.runnerVersion,\n configPath,\n jentrixBaseUrl: config.jentrixBaseUrl,\n mcpUrl: config.mcpUrl,\n workspaceId: config.workspaceId,\n enrollment: null,\n bootstrap: { token: config.bootstrapToken, claimUrl: config.claimUrl },\n runtimes,\n roleBindings: config.roleBindings,\n attestationConnections: [\n ...new Map(\n Object.values(config.roleBindings)\n .filter((binding) => binding.requiresClaimCredential)\n .map((binding) => [\n binding.providerConnectionId,\n {\n connectionId: binding.providerConnectionId,\n runtimeAdapterKey: binding.runtimeAdapterKey,\n },\n ]),\n ).values(),\n ],\n },\n {\n postJson: (path, body) =>\n postSetupJson(config.jentrixBaseUrl, path, body),\n },\n );\n const workflowRunner = fileURLToPath(\n new URL(\"./workflow-runner.js\", import.meta.url),\n );\n const child = spawn(process.execPath, [workflowRunner], {\n env: runnerEnvironment(config, configPath, once),\n stdio: \"inherit\",\n });\n const { interrupt, terminate } = terminationHandlers((signal) =>\n child.kill(signal),\n );\n process.once(\"SIGINT\", interrupt);\n process.once(\"SIGTERM\", terminate);\n try {\n return await new Promise<number>((resolve, reject) => {\n child.once(\"error\", reject);\n child.once(\"exit\", (code, signal) => resolve(code ?? (signal ? 1 : 0)));\n });\n } finally {\n process.off(\"SIGINT\", interrupt);\n process.off(\"SIGTERM\", terminate);\n }\n}\n\nfunction valueAfter(args: string[], flag: string): string | undefined {\n const at = args.indexOf(flag);\n return at >= 0 ? args[at + 1] : undefined;\n}\n\nasync function readStdinCapped(cap = 2 * 1024 * 1024): Promise<string> {\n const chunks: Buffer[] = [];\n let bytes = 0;\n for await (const chunk of process.stdin) {\n const buffer = Buffer.from(chunk);\n bytes += buffer.byteLength;\n if (bytes > cap)\n throw new Error(\"runner setup input exceeded its size limit\");\n chunks.push(buffer);\n }\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n\nasync function postSetupJson(\n baseUrl: string,\n path: string,\n body: Record<string, unknown>,\n): Promise<Record<string, unknown>> {\n const response = await fetch(new URL(path, baseUrl), {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(30_000),\n });\n if (!response.ok) {\n throw new Error(\n `${path} refused the runner request (HTTP ${response.status}).`,\n );\n }\n const value = await response.json();\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(`${path} returned malformed JSON.`);\n }\n return value as Record<string, unknown>;\n}\n\nexport async function main(\n args: string[] = process.argv.slice(2),\n): Promise<number> {\n const command = args[0];\n // F-2/AGE-933: the conventional spellings must work too \u2014 every other CLI\n // on the machine answers `--version`, so rejecting it reads as breakage.\n if (command === \"--version\" || command === \"-v\") {\n process.stdout.write(`${RUNNER_VERSION}\\n`);\n return 0;\n }\n if (command === \"version\") {\n if (args.includes(\"--json\")) {\n process.stdout.write(`${JSON.stringify(runnerVersionEnvelope())}\\n`);\n } else {\n process.stdout.write(`${RUNNER_VERSION}\\n`);\n }\n return 0;\n }\n if (command === \"probe\" && args.includes(\"--json\")) {\n const { probeLocalRuntimes } = await import(\"./lib/local-probes.js\");\n const { runnerConfigPath, runnerConfigSummary } = await import(\n \"./lib/runner-config.js\"\n );\n const [runtimes, config] = await Promise.all([\n probeLocalRuntimes({\n claudePath: valueAfter(args, \"--claude-path\"),\n codexPath: valueAfter(args, \"--codex-path\"),\n }),\n runnerConfigSummary(runnerConfigPath()),\n ]);\n process.stdout.write(\n `${JSON.stringify({ ...runnerVersionEnvelope(), runtimes, config })}\\n`,\n );\n return runtimes.some((runtime) => runtime.status === \"ready\") ? 0 : 1;\n }\n if (command === \"setup-apply\" && args.includes(\"--plan-stdin\")) {\n const { applyRunnerSetup } = await import(\"./lib/runner-setup.js\");\n const parsed = JSON.parse(await readStdinCapped()) as RunnerSetupApply;\n if (parsed.protocolVersion !== RUNNER_PROTOCOL_VERSION) {\n throw new Error(\"runner setup protocol version mismatch\");\n }\n const result = await applyRunnerSetup(parsed, {\n postJson: (path, body) =>\n postSetupJson(parsed.jentrixBaseUrl, path, body),\n });\n process.stdout.write(`${JSON.stringify(result)}\\n`);\n return 0;\n }\n if (command === \"run\") {\n return runConfiguredRunner(args.includes(\"--once\"));\n }\n // M20.1: connected-session host. The plan (including the TRANSIENT human\n // bearer) arrives over stdin or a 0600 plan file that is unlinked on read \u2014\n // never argv, never persisted (AC4). The file form exists because a LAUNCH\n // keeps the TTY's stdin for the interactive provider.\n if (\n command === \"session-run\" &&\n (args.includes(\"--plan-stdin\") || args.includes(\"--plan-file\"))\n ) {\n const { runSessionHost } = await import(\"./lib/session-host.js\");\n let raw: string;\n const planFile = valueAfter(args, \"--plan-file\");\n if (planFile) {\n const { readFileSync, unlinkSync } = await import(\"node:fs\");\n raw = readFileSync(planFile, \"utf8\");\n try {\n unlinkSync(planFile);\n } catch {\n // best-effort \u2014 the file is 0600 and holds a short-lived bearer\n }\n } else {\n raw = await readStdinCapped();\n }\n const plan = JSON.parse(raw) as {\n protocolVersion?: number;\n provider?: string;\n };\n if (plan.protocolVersion !== RUNNER_PROTOCOL_VERSION) {\n throw new Error(\n \"RUNNER_VERSION_MISMATCH: session plan protocol mismatch\",\n );\n }\n if (plan.provider !== \"claude\" && plan.provider !== \"codex\") {\n throw new Error(\"RUNNER_CONFIG_INVALID: unknown session provider\");\n }\n return runSessionHost(\n plan as import(\"./lib/session-host.js\").SessionRunPlan,\n );\n }\n // M20.1 \u00A715.1: the hook forwarder Claude lifecycle hooks invoke. Argv holds\n // only the session DIRECTORY and event name; the payload rides stdin.\n if (command === \"session-hook\") {\n // The hook-log module, NOT `session-host` \u2014 appending a line must not load\n // the MCP client and both transcript mappers (P5).\n const { appendHookEvent } = await import(\"./lib/session-hook-log.js\");\n // --dir stays as the explicit override (and keeps pre-0.5.13 plugin\n // copies working on unix); see sessionHookDir for why --provider exists.\n const dir =\n valueAfter(args, \"--dir\") ??\n sessionHookDir(valueAfter(args, \"--provider\") ?? null);\n const event = valueAfter(args, \"--event\") ?? \"unknown\";\n if (!dir)\n throw new Error(\n \"RUNNER_CONFIG_INVALID: session-hook needs --provider claude|codex or --dir\",\n );\n appendHookEvent(dir, event, await readStdinCapped());\n return 0;\n }\n process.stderr.write(\n \"usage: stacks-runner version --json | probe --json [--claude-path PATH] [--codex-path PATH] | setup-apply --plan-stdin | run [--once] | session-run --plan-stdin | session-hook (--provider claude|codex | --dir DIR) --event NAME\\n\",\n );\n return 2;\n}\n\nfunction isEntrypoint(): boolean {\n try {\n return (\n realpathSync(process.argv[1] ?? \"\") ===\n realpathSync(fileURLToPath(import.meta.url))\n );\n } catch {\n return false;\n }\n}\n\nif (isEntrypoint()) {\n main().then(\n (code) => {\n process.exitCode = code;\n },\n (error) => {\n const message = error instanceof Error ? error.message : \"\";\n process.stderr.write(\n /^[A-Z][A-Z_]+: /.test(message)\n ? `${message}\\n`\n : \"RUNNER_CONFIG_INVALID: runner protocol failure\\n\",\n );\n process.exitCode = 2;\n },\n );\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["#!/usr/bin/env node\nimport { fileURLToPath } from \"node:url\";\nimport { spawn } from \"node:child_process\";\nimport { realpathSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport type { RunnerConfig } from \"./lib/runner-config.js\";\nimport type { RunnerSetupApply } from \"./lib/runner-setup.js\";\nimport { RUNNER_VERSION } from \"./lib/version.js\";\n\n// ---------------------------------------------------------------------------\n// TYPE-ONLY above, and that is load-bearing (MVP separation P5).\n//\n// `probe`, `setup-apply` and `run` are the PLATFORM half of this binary: they\n// enroll a worker and poll for agent jobs, both of which are planes. The MVP\n// deployment uses only the session half (`session-run`, `session-hook`), and\n// `session-hook` in particular is invoked by a Claude Code lifecycle hook \u2014\n// several times per conversation, on the operator's critical path.\n//\n// Statically importing `local-probes` put `@anthropic-ai/claude-agent-sdk` at\n// the top of the built bundle, so EVERY invocation paid to load 4.5 MB of a\n// provider SDK the session half never touches: ~90ms per hook against a ~10ms\n// bare-node baseline. The three `await import(\u2026)` calls below move that cost\n// into the branches that actually need it.\n//\n// The dependency itself stays REQUIRED rather than optional. Making it\n// optional is the packaging half of this question and it breaks a platform\n// operator's `npm i -g` in a way this refactor should not decide silently \u2014\n// see `plans/mvp-separation-strategy.md` \u00A7 P5.\n// ---------------------------------------------------------------------------\n\nexport const RUNNER_PROTOCOL_VERSION = 1;\nexport { RUNNER_VERSION };\n\n/**\n * STA-131 \u2014 the default hook-context dir per provider, resolved in code. A\n * `$HOME` literal on hook argv never expands on Windows (no POSIX shell), so\n * the plugins pass `--provider` and the path is built here, cross-platform.\n */\nexport function sessionHookDir(\n provider: string | null,\n home: string = homedir(),\n): string | null {\n return provider === \"claude\" || provider === \"codex\"\n ? join(home, \".config\", \"stacks\", `${provider}-sessions`)\n : null;\n}\n\nexport function runnerVersionEnvelope() {\n return {\n protocolVersion: RUNNER_PROTOCOL_VERSION,\n runnerVersion: RUNNER_VERSION,\n };\n}\n\nexport function runnerEnvironment(\n config: RunnerConfig,\n configPath: string,\n once: boolean,\n base: NodeJS.ProcessEnv = process.env,\n): NodeJS.ProcessEnv {\n return {\n ...base,\n STACKS_BASE_URL: config.jentrixBaseUrl,\n STACKS_MCP_URL: config.mcpUrl,\n STACKS_RUNNER_MODE: \"self-hosted\",\n STACKS_BOOTSTRAP_TOKEN: config.bootstrapToken,\n STACKS_CLAIM_URL: config.claimUrl,\n STACKS_RUNNER_AUTH_STATE: `${configPath}.auth.json`,\n STACKS_WORKER_HEARTBEAT_TOKEN: config.heartbeatToken,\n STACKS_RUNNER_ROLE_BINDINGS: JSON.stringify(config.roleBindings),\n STACKS_RUNNER_HOST: \"127.0.0.1\",\n STACKS_CLAUDE_EXECUTABLE: config.executables.claude,\n STACKS_CODEX_EXECUTABLE: config.executables.codex,\n STACKS_POLL_MS: base.STACKS_POLL_MS ?? \"30000\",\n ...(once ? { STACKS_RUNNER_ONCE: \"1\" } : {}),\n };\n}\n\nexport function terminationHandlers(kill: (signal: NodeJS.Signals) => unknown) {\n return {\n interrupt: () => kill(\"SIGINT\"),\n terminate: () => kill(\"SIGTERM\"),\n };\n}\n\nexport function assertRunnerConfigCompatibility(config: RunnerConfig): void {\n if (config.protocolVersion !== RUNNER_PROTOCOL_VERSION) {\n throw new Error(\n `RUNNER_VERSION_MISMATCH: run: npm install --global @jentrix/cli@${RUNNER_VERSION} @jentrix/runner@${RUNNER_VERSION}`,\n );\n }\n}\n\nasync function runConfiguredRunner(once: boolean): Promise<number> {\n const { probeLocalRuntimes } = await import(\"./lib/local-probes.js\");\n const { readRunnerConfig, runnerConfigPath } =\n await import(\"./lib/runner-config.js\");\n const { applyRunnerSetup } = await import(\"./lib/runner-setup.js\");\n const configPath = runnerConfigPath();\n let config: RunnerConfig;\n try {\n config = await readRunnerConfig(configPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException)?.code === \"ENOENT\") {\n throw new Error(\"BOOTSTRAP_REQUIRED: run jentrix runner setup.\");\n }\n throw error;\n }\n assertRunnerConfigCompatibility(config);\n const runtimes = await probeLocalRuntimes({\n claudePath: config.executables.claude,\n codexPath: config.executables.codex,\n });\n const probes = new Map(\n runtimes.map((runtime) => [runtime.adapterKey, runtime]),\n );\n for (const binding of Object.values(config.roleBindings)) {\n const probe = probes.get(binding.runtimeAdapterKey);\n if (!probe || probe.status !== \"ready\") {\n throw new Error(\n `ROLE_PLAN_UNSATISFIED: ${binding.runtimeAdapterKey} is not ready for a configured role.`,\n );\n }\n if (\n probe.availableModels.length > 0 &&\n !probe.availableModels.some((model) => model.id === binding.model)\n ) {\n throw new Error(\n `ROLE_PLAN_UNSATISFIED: ${binding.runtimeAdapterKey} cannot run configured model ${binding.model}.`,\n );\n }\n }\n await applyRunnerSetup(\n {\n protocolVersion: config.protocolVersion,\n runnerVersion: config.runnerVersion,\n configPath,\n jentrixBaseUrl: config.jentrixBaseUrl,\n mcpUrl: config.mcpUrl,\n workspaceId: config.workspaceId,\n enrollment: null,\n bootstrap: { token: config.bootstrapToken, claimUrl: config.claimUrl },\n runtimes,\n roleBindings: config.roleBindings,\n attestationConnections: [\n ...new Map(\n Object.values(config.roleBindings)\n .filter((binding) => binding.requiresClaimCredential)\n .map((binding) => [\n binding.providerConnectionId,\n {\n connectionId: binding.providerConnectionId,\n runtimeAdapterKey: binding.runtimeAdapterKey,\n },\n ]),\n ).values(),\n ],\n },\n {\n postJson: (path, body) =>\n postSetupJson(config.jentrixBaseUrl, path, body),\n },\n );\n const workflowRunner = fileURLToPath(\n new URL(\"./workflow-runner.js\", import.meta.url),\n );\n const child = spawn(process.execPath, [workflowRunner], {\n env: runnerEnvironment(config, configPath, once),\n stdio: \"inherit\",\n });\n const { interrupt, terminate } = terminationHandlers((signal) =>\n child.kill(signal),\n );\n process.once(\"SIGINT\", interrupt);\n process.once(\"SIGTERM\", terminate);\n try {\n return await new Promise<number>((resolve, reject) => {\n child.once(\"error\", reject);\n child.once(\"exit\", (code, signal) => resolve(code ?? (signal ? 1 : 0)));\n });\n } finally {\n process.off(\"SIGINT\", interrupt);\n process.off(\"SIGTERM\", terminate);\n }\n}\n\nfunction valueAfter(args: string[], flag: string): string | undefined {\n const at = args.indexOf(flag);\n return at >= 0 ? args[at + 1] : undefined;\n}\n\nasync function readStdinCapped(cap = 2 * 1024 * 1024): Promise<string> {\n const chunks: Buffer[] = [];\n let bytes = 0;\n for await (const chunk of process.stdin) {\n const buffer = Buffer.from(chunk);\n bytes += buffer.byteLength;\n if (bytes > cap)\n throw new Error(\"runner setup input exceeded its size limit\");\n chunks.push(buffer);\n }\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n\nasync function postSetupJson(\n baseUrl: string,\n path: string,\n body: Record<string, unknown>,\n): Promise<Record<string, unknown>> {\n const response = await fetch(new URL(path, baseUrl), {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(30_000),\n });\n if (!response.ok) {\n throw new Error(\n `${path} refused the runner request (HTTP ${response.status}).`,\n );\n }\n const value = await response.json();\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(`${path} returned malformed JSON.`);\n }\n return value as Record<string, unknown>;\n}\n\nexport async function main(\n args: string[] = process.argv.slice(2),\n): Promise<number> {\n const command = args[0];\n // F-2/AGE-933: the conventional spellings must work too \u2014 every other CLI\n // on the machine answers `--version`, so rejecting it reads as breakage.\n if (command === \"--version\" || command === \"-v\") {\n process.stdout.write(`${RUNNER_VERSION}\\n`);\n return 0;\n }\n if (command === \"version\") {\n if (args.includes(\"--json\")) {\n process.stdout.write(`${JSON.stringify(runnerVersionEnvelope())}\\n`);\n } else {\n process.stdout.write(`${RUNNER_VERSION}\\n`);\n }\n return 0;\n }\n if (command === \"probe\" && args.includes(\"--json\")) {\n const { probeLocalRuntimes } = await import(\"./lib/local-probes.js\");\n const { runnerConfigPath, runnerConfigSummary } =\n await import(\"./lib/runner-config.js\");\n const [runtimes, config] = await Promise.all([\n probeLocalRuntimes({\n claudePath: valueAfter(args, \"--claude-path\"),\n codexPath: valueAfter(args, \"--codex-path\"),\n }),\n runnerConfigSummary(runnerConfigPath()),\n ]);\n process.stdout.write(\n `${JSON.stringify({ ...runnerVersionEnvelope(), runtimes, config })}\\n`,\n );\n return runtimes.some((runtime) => runtime.status === \"ready\") ? 0 : 1;\n }\n if (command === \"setup-apply\" && args.includes(\"--plan-stdin\")) {\n const { applyRunnerSetup } = await import(\"./lib/runner-setup.js\");\n const parsed = JSON.parse(await readStdinCapped()) as RunnerSetupApply;\n if (parsed.protocolVersion !== RUNNER_PROTOCOL_VERSION) {\n throw new Error(\"runner setup protocol version mismatch\");\n }\n const result = await applyRunnerSetup(parsed, {\n postJson: (path, body) =>\n postSetupJson(parsed.jentrixBaseUrl, path, body),\n });\n process.stdout.write(`${JSON.stringify(result)}\\n`);\n return 0;\n }\n if (command === \"run\") {\n return runConfiguredRunner(args.includes(\"--once\"));\n }\n // M20.1: connected-session host. The plan (including the TRANSIENT human\n // bearer) arrives over stdin or a 0600 plan file that is unlinked on read \u2014\n // never argv, never persisted (AC4). The file form exists because a LAUNCH\n // keeps the TTY's stdin for the interactive provider.\n if (\n command === \"session-run\" &&\n (args.includes(\"--plan-stdin\") || args.includes(\"--plan-file\"))\n ) {\n const { runSessionHost } = await import(\"./lib/session-host.js\");\n let raw: string;\n const planFile = valueAfter(args, \"--plan-file\");\n if (planFile) {\n const { readFileSync, unlinkSync } = await import(\"node:fs\");\n raw = readFileSync(planFile, \"utf8\");\n try {\n unlinkSync(planFile);\n } catch {\n // best-effort \u2014 the file is 0600 and holds a short-lived bearer\n }\n } else {\n raw = await readStdinCapped();\n }\n const plan = JSON.parse(raw) as {\n protocolVersion?: number;\n provider?: string;\n };\n if (plan.protocolVersion !== RUNNER_PROTOCOL_VERSION) {\n throw new Error(\n \"RUNNER_VERSION_MISMATCH: session plan protocol mismatch\",\n );\n }\n if (plan.provider !== \"claude\" && plan.provider !== \"codex\") {\n throw new Error(\"RUNNER_CONFIG_INVALID: unknown session provider\");\n }\n return runSessionHost(\n plan as import(\"./lib/session-host.js\").SessionRunPlan,\n );\n }\n // M20.1 \u00A715.1: the hook forwarder Claude lifecycle hooks invoke. Argv holds\n // only the session DIRECTORY and event name; the payload rides stdin.\n if (command === \"session-hook\") {\n // The hook-log module, NOT `session-host` \u2014 appending a line must not load\n // the MCP client and both transcript mappers (P5).\n const { appendHookEvent } = await import(\"./lib/session-hook-log.js\");\n // --dir stays as the explicit override (and keeps pre-0.5.13 plugin\n // copies working on unix); see sessionHookDir for why --provider exists.\n const dir =\n valueAfter(args, \"--dir\") ??\n sessionHookDir(valueAfter(args, \"--provider\") ?? null);\n const event = valueAfter(args, \"--event\") ?? \"unknown\";\n if (!dir)\n throw new Error(\n \"RUNNER_CONFIG_INVALID: session-hook needs --provider claude|codex or --dir\",\n );\n appendHookEvent(dir, event, await readStdinCapped());\n return 0;\n }\n process.stderr.write(\n \"usage: stacks-runner version --json | probe --json [--claude-path PATH] [--codex-path PATH] | setup-apply --plan-stdin | run [--once] | session-run --plan-stdin | session-hook (--provider claude|codex | --dir DIR) --event NAME\\n\",\n );\n return 2;\n}\n\nfunction isEntrypoint(): boolean {\n try {\n return (\n realpathSync(process.argv[1] ?? \"\") ===\n realpathSync(fileURLToPath(import.meta.url))\n );\n } catch {\n return false;\n }\n}\n\nif (isEntrypoint()) {\n main().then(\n (code) => {\n process.exitCode = code;\n },\n (error) => {\n const message = error instanceof Error ? error.message : \"\";\n process.stderr.write(\n /^[A-Z][A-Z_]+: /.test(message)\n ? `${message}\\n`\n : \"RUNNER_CONFIG_INVALID: runner protocol failure\\n\",\n );\n process.exitCode = 2;\n },\n );\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  RUNNER_VERSION
3
- } from "./chunk-QBB7WO4L.js";
3
+ } from "./chunk-PTARP62V.js";
4
4
  import {
5
5
  appendHookEvent,
6
6
  readHookLines,
@@ -305,7 +305,9 @@ function aggregateSessionUsage(input) {
305
305
  let closed = 0;
306
306
  for (const interval of intervals) {
307
307
  if (interval.endedAt == null) {
308
- missing.push(`${label} interval ${interval.id} never observed its terminal event`);
308
+ missing.push(
309
+ `${label} interval ${interval.id} never observed its terminal event`
310
+ );
309
311
  continue;
310
312
  }
311
313
  total += Math.max(0, interval.endedAt - interval.startedAt);
@@ -913,7 +915,11 @@ function mapClaudeTranscriptLine(line) {
913
915
  baseEvent(
914
916
  entry,
915
917
  "tool_call",
916
- { toolUseId: block.id ?? null, name: block.name ?? null, input: block.input ?? null },
918
+ {
919
+ toolUseId: block.id ?? null,
920
+ name: block.name ?? null,
921
+ input: block.input ?? null
922
+ },
917
923
  `:tool:${block.id ?? ""}`
918
924
  )
919
925
  );
@@ -2001,4 +2007,4 @@ export {
2001
2007
  safeParse,
2002
2008
  sessionCallTool
2003
2009
  };
2004
- //# sourceMappingURL=session-host-X4B43PJJ.js.map
2010
+ //# sourceMappingURL=session-host-DMDLRICG.js.map