@agimon-ai/po-runner 0.0.0-alpha.64 → 0.0.0-alpha.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/README.md +6 -0
  2. package/dist/bin/cli.cjs +3 -3
  3. package/dist/bin/cli.mjs +3 -3
  4. package/dist/bin/runnerHost.cjs +3 -3
  5. package/dist/bin/runnerHost.mjs +3 -3
  6. package/dist/{cliApp-GKcqD6CT.cjs → cliApp-BYfgP44s.cjs} +3 -3
  7. package/dist/{cliApp-GKcqD6CT.cjs.map → cliApp-BYfgP44s.cjs.map} +1 -1
  8. package/dist/{cliApp-g7APOwcU.mjs → cliApp-DPbA8LkI.mjs} +3 -3
  9. package/dist/{cliApp-g7APOwcU.mjs.map → cliApp-DPbA8LkI.mjs.map} +1 -1
  10. package/dist/cliApp.cjs +1 -1
  11. package/dist/cliApp.mjs +1 -1
  12. package/dist/extensions/mcp.cjs +1 -0
  13. package/dist/extensions/mcp.cjs.map +1 -1
  14. package/dist/extensions/mcp.mjs +1 -0
  15. package/dist/extensions/mcp.mjs.map +1 -1
  16. package/dist/extensions/server.cjs +21 -9
  17. package/dist/extensions/server.cjs.map +1 -1
  18. package/dist/extensions/server.mjs +21 -9
  19. package/dist/extensions/server.mjs.map +1 -1
  20. package/dist/index.cjs +2 -2
  21. package/dist/index.mjs +2 -2
  22. package/dist/launch.cjs +1 -1
  23. package/dist/launch.d.mts +14 -3
  24. package/dist/launch.d.mts.map +1 -1
  25. package/dist/launch.mjs +1 -1
  26. package/dist/{launcher-D3Cl0fGC.mjs → launcher-CwVJ55MC.mjs} +3 -3
  27. package/dist/{launcher-D3Cl0fGC.mjs.map → launcher-CwVJ55MC.mjs.map} +1 -1
  28. package/dist/{launcher-rqlG32NT.cjs → launcher-ksyHY-iG.cjs} +3 -3
  29. package/dist/{launcher-rqlG32NT.cjs.map → launcher-ksyHY-iG.cjs.map} +1 -1
  30. package/dist/launcher.cjs +1 -1
  31. package/dist/launcher.mjs +1 -1
  32. package/dist/{ptyHost-DfXM9RCJ.cjs → ptyHost-C-oWV455.cjs} +3 -3
  33. package/dist/{ptyHost-DfXM9RCJ.cjs.map → ptyHost-C-oWV455.cjs.map} +1 -1
  34. package/dist/{ptyHost-D8zJaYg3.mjs → ptyHost-C2zu-ZfO.mjs} +3 -3
  35. package/dist/{ptyHost-D8zJaYg3.mjs.map → ptyHost-C2zu-ZfO.mjs.map} +1 -1
  36. package/dist/ptyHost.cjs +1 -1
  37. package/dist/ptyHost.mjs +1 -1
  38. package/dist/{rmuxBackend-B-7aY8Kc.mjs → rmuxBackend-BCfO297l.mjs} +2 -2
  39. package/dist/{rmuxBackend-B-7aY8Kc.mjs.map → rmuxBackend-BCfO297l.mjs.map} +1 -1
  40. package/dist/{rmuxBackend-CPVm0YUN.cjs → rmuxBackend-BooQvfXt.cjs} +2 -2
  41. package/dist/{rmuxBackend-CPVm0YUN.cjs.map → rmuxBackend-BooQvfXt.cjs.map} +1 -1
  42. package/dist/rmuxBackend.cjs +1 -1
  43. package/dist/rmuxBackend.mjs +1 -1
  44. package/dist/{runnerDependencies-C1TO2nk_.mjs → runnerDependencies-0SbEl19h.mjs} +7 -7
  45. package/dist/{runnerDependencies-C1TO2nk_.mjs.map → runnerDependencies-0SbEl19h.mjs.map} +1 -1
  46. package/dist/{runnerDependencies-CqxPZasw.cjs → runnerDependencies-DNxVf_Sg.cjs} +7 -7
  47. package/dist/{runnerDependencies-CqxPZasw.cjs.map → runnerDependencies-DNxVf_Sg.cjs.map} +1 -1
  48. package/dist/runnerDependencies.cjs +1 -1
  49. package/dist/runnerDependencies.mjs +1 -1
  50. package/dist/{runnerHost-B2Jiba1U.mjs → runnerHost-BvNYPMeh.mjs} +12 -1
  51. package/dist/runnerHost-BvNYPMeh.mjs.map +1 -0
  52. package/dist/{runnerHost-BXk4sPBP.cjs → runnerHost-C2F5oxzn.cjs} +12 -1
  53. package/dist/runnerHost-C2F5oxzn.cjs.map +1 -0
  54. package/dist/{runnerLaunch-C2Cp6EaL.cjs → runnerLaunch-BAf7hXMr.cjs} +69 -15
  55. package/dist/runnerLaunch-BAf7hXMr.cjs.map +1 -0
  56. package/dist/{runnerLaunch-DN5H79t8.mjs → runnerLaunch-Bimgdh4h.mjs} +69 -15
  57. package/dist/runnerLaunch-Bimgdh4h.mjs.map +1 -0
  58. package/dist/{runnerPaths-sdEEgdM8.cjs → runnerPaths-CSkswyjR.cjs} +4 -4
  59. package/dist/{runnerPaths-sdEEgdM8.cjs.map → runnerPaths-CSkswyjR.cjs.map} +1 -1
  60. package/dist/{runnerPaths-DtT9RJxQ.mjs → runnerPaths-D3P7_EhW.mjs} +4 -4
  61. package/dist/{runnerPaths-DtT9RJxQ.mjs.map → runnerPaths-D3P7_EhW.mjs.map} +1 -1
  62. package/dist/runnerPaths.cjs +1 -1
  63. package/dist/runnerPaths.mjs +1 -1
  64. package/dist/{runnerRegistry-BucrRJsG.cjs → runnerRegistry-B8K1L3lq.cjs} +2 -2
  65. package/dist/{runnerRegistry-BucrRJsG.cjs.map → runnerRegistry-B8K1L3lq.cjs.map} +1 -1
  66. package/dist/{runnerRegistry-_B6LXMhS.mjs → runnerRegistry-Dqca6SD3.mjs} +2 -2
  67. package/dist/{runnerRegistry-_B6LXMhS.mjs.map → runnerRegistry-Dqca6SD3.mjs.map} +1 -1
  68. package/dist/runnerRegistry.cjs +1 -1
  69. package/dist/runnerRegistry.mjs +1 -1
  70. package/dist/{session-IgtrocZP.mjs → session-CdVeSD7F.mjs} +3 -3
  71. package/dist/{session-CRql5E2T.cjs.map → session-CdVeSD7F.mjs.map} +1 -1
  72. package/dist/{session-CRql5E2T.cjs → session-DnUj8Q71.cjs} +4 -4
  73. package/dist/{session-IgtrocZP.mjs.map → session-DnUj8Q71.cjs.map} +1 -1
  74. package/dist/{session-3oSU3QjI.mjs → session-ISEGK4z9.mjs} +4 -4
  75. package/dist/{session-3oSU3QjI.mjs.map → session-ISEGK4z9.mjs.map} +1 -1
  76. package/dist/{session-D_nH4XhL.cjs → session-PQd3azWf.cjs} +4 -4
  77. package/dist/{session-D_nH4XhL.cjs.map → session-PQd3azWf.cjs.map} +1 -1
  78. package/dist/session.cjs +3 -3
  79. package/dist/session.d.mts +1 -1
  80. package/dist/session.mjs +3 -3
  81. package/package.json +16 -16
  82. package/skills/po-runner/SKILL.md +1 -1
  83. package/dist/runnerHost-B2Jiba1U.mjs.map +0 -1
  84. package/dist/runnerHost-BXk4sPBP.cjs.map +0 -1
  85. package/dist/runnerLaunch-C2Cp6EaL.cjs.map +0 -1
  86. package/dist/runnerLaunch-DN5H79t8.mjs.map +0 -1
package/README.md CHANGED
@@ -290,3 +290,9 @@ Public capabilities use flat kebab-case subpaths such as `runner-dependencies`,
290
290
  ### Native session ownership
291
291
 
292
292
  The Po server plugin owns runner startup, history retention, background completion notifications, and successful-compaction recovery. The standalone `po-runner` command remains available. Runner project settings retain the existing headless bridge's trusted-project assumption, validation, and environment-over-project precedence. Optional runner activity toggles do not restart the retained supervisor.
293
+
294
+ ### Package launches and trusted owner routing
295
+
296
+ `readPoRunnerLaunch(context)` from `@agimon-ai/po-runner/launch` returns the `po/runner-launch` service, whose `start`, `get`, `list`, `stop`, `logs` and `onChange` always act on the calling session. Its optional `forOwner()` takes no argument and returns the same six operations against the session's trusted owner: the workflow run's `ownerSessionId` when the session was bootstrapped as a workflow step, otherwise the session itself. Callers cannot name an owner. Check `typeof launch.forOwner === 'function'` before use, because builds that predate it lack it.
297
+
298
+ Routed starts never wake the owner's agent (`wakeOnExit` is forced off) and register with the owner's supervision, so a runner survives its workflow child and stops with the owner. Releasing the child cancels only its own pending starts before handoff and its own subscriptions. A missing or other-build owner fails with `owner unavailable` before anything spawns. Closing owners also refuse launches, with a disposed or aborted error if still registered. There is no fallback to the calling session. The `bash` tool, the `runner` namespace and the top-level launch methods stay session-local.
package/dist/bin/cli.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const require_runnerSequenceStore = require("../runnerSequenceStore-Ck6M-8r_.cjs");
4
- const require_cliApp = require("../cliApp-GKcqD6CT.cjs");
5
- const require_session = require("../session-D_nH4XhL.cjs");
6
- const require_runnerDependencies = require("../runnerDependencies-CqxPZasw.cjs");
4
+ const require_cliApp = require("../cliApp-BYfgP44s.cjs");
5
+ const require_session = require("../session-PQd3azWf.cjs");
6
+ const require_runnerDependencies = require("../runnerDependencies-DNxVf_Sg.cjs");
7
7
  let node_fs_promises = require("node:fs/promises");
8
8
  let node_url = require("node:url");
9
9
  let _agimon_ai_po_core_telemetry = require("@agimon-ai/po-core/telemetry");
package/dist/bin/cli.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as createRunnerSequenceStore } from "../runnerSequenceStore-CaY7S_Sd.mjs";
3
- import { n as runnerCliHelp, t as runCli } from "../cliApp-g7APOwcU.mjs";
4
- import { t as inheritedSessionId } from "../session-3oSU3QjI.mjs";
5
- import { t as createRunnerDependencies } from "../runnerDependencies-C1TO2nk_.mjs";
3
+ import { n as runnerCliHelp, t as runCli } from "../cliApp-DPbA8LkI.mjs";
4
+ import { t as inheritedSessionId } from "../session-ISEGK4z9.mjs";
5
+ import { t as createRunnerDependencies } from "../runnerDependencies-0SbEl19h.mjs";
6
6
  import { realpath } from "node:fs/promises";
7
7
  import { fileURLToPath } from "node:url";
8
8
  import { createPoTelemetry } from "@agimon-ai/po-core/telemetry";
@@ -161,9 +161,9 @@ async function readMarker(marker) {
161
161
  /** One registry per registry path, held until the observer runs out of work. */
162
162
  async function loadCleaner() {
163
163
  const [{ cleanupRunnerSession }, { RunnerPaths }, { createDefaultProcessRegistry }] = await Promise.all([
164
- Promise.resolve().then(() => require("../runnerHost-BXk4sPBP.cjs")).then((n) => n.runnerHost_exports),
165
- Promise.resolve().then(() => require("../runnerPaths-sdEEgdM8.cjs")).then((n) => n.runnerPaths_exports),
166
- Promise.resolve().then(() => require("../runnerRegistry-BucrRJsG.cjs")).then((n) => n.runnerRegistry_exports)
164
+ Promise.resolve().then(() => require("../runnerHost-C2F5oxzn.cjs")).then((n) => n.runnerHost_exports),
165
+ Promise.resolve().then(() => require("../runnerPaths-CSkswyjR.cjs")).then((n) => n.runnerPaths_exports),
166
+ Promise.resolve().then(() => require("../runnerRegistry-B8K1L3lq.cjs")).then((n) => n.runnerRegistry_exports)
167
167
  ]);
168
168
  const registries = /* @__PURE__ */ new Map();
169
169
  process.once("beforeExit", () => {
@@ -157,9 +157,9 @@ async function readMarker(marker) {
157
157
  /** One registry per registry path, held until the observer runs out of work. */
158
158
  async function loadCleaner() {
159
159
  const [{ cleanupRunnerSession }, { RunnerPaths }, { createDefaultProcessRegistry }] = await Promise.all([
160
- import("../runnerHost-B2Jiba1U.mjs").then((n) => n.r),
161
- import("../runnerPaths-DtT9RJxQ.mjs").then((n) => n.r),
162
- import("../runnerRegistry-_B6LXMhS.mjs").then((n) => n.r)
160
+ import("../runnerHost-BvNYPMeh.mjs").then((n) => n.r),
161
+ import("../runnerPaths-D3P7_EhW.mjs").then((n) => n.r),
162
+ import("../runnerRegistry-Dqca6SD3.mjs").then((n) => n.r)
163
163
  ]);
164
164
  const registries = /* @__PURE__ */ new Map();
165
165
  process.once("beforeExit", () => {
@@ -2,7 +2,7 @@ const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
2
2
  const require_bashResult = require("./bashResult-B1w7qkQW.cjs");
3
3
  const require_reconcile = require("./reconcile-DjF9T1hN.cjs");
4
4
  const require_runnerSequenceStore = require("./runnerSequenceStore-Ck6M-8r_.cjs");
5
- const require_session = require("./session-D_nH4XhL.cjs");
5
+ const require_session = require("./session-PQd3azWf.cjs");
6
6
  let node_fs_promises = require("node:fs/promises");
7
7
  let node_fs = require("node:fs");
8
8
  node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
@@ -14,7 +14,7 @@ const MULTIPLEXER_BACKENDS = /* @__PURE__ */ new Set(["rmux", "tmux"]);
14
14
  async function runCli(argv, dependencies) {
15
15
  const [command, ...args] = argv;
16
16
  if (command !== void 0 && command !== "--help" && command !== "-h" && !require_session.inheritedSessionId(dependencies.env)) {
17
- dependencies.stderr("PI_SESSION_ID is required for po-runner commands");
17
+ dependencies.stderr("PO_SESSION_ID is required for po-runner commands");
18
18
  return 1;
19
19
  }
20
20
  if (command && args[0] && require_runnerSequenceStore.isSequenceId(args[0])) return sequenceCommand(command, args, dependencies);
@@ -304,4 +304,4 @@ Object.defineProperty(exports, "runnerCliHelp", {
304
304
  }
305
305
  });
306
306
 
307
- //# sourceMappingURL=cliApp-GKcqD6CT.cjs.map
307
+ //# sourceMappingURL=cliApp-BYfgP44s.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cliApp-GKcqD6CT.cjs","names":["inheritedSessionId","isSequenceId","requiredSessionId","formatRunnerLine","open","stat","stopRunnerProcess"],"sources":["../src/constants/cliApp.ts","../src/services/cliApp/index.ts"],"sourcesContent":["export const DEFAULT_LOG_LINES = 200;\nexport const FOLLOW_INTERVAL_MS = 250;\nexport const COMPLETED_STATE = 'completed';\nexport const STOPPED_REASON = 'stopped';\nexport const TERMINATION_SIGNAL = 'SIGTERM';\n","import fs from 'node:fs';\nimport { open, stat } from 'node:fs/promises';\n\nimport {\n COMPLETED_STATE,\n DEFAULT_LOG_LINES,\n FOLLOW_INTERVAL_MS,\n STOPPED_REASON,\n TERMINATION_SIGNAL,\n} from '../../constants/cliApp';\nimport { formatRunnerLine } from '../../services/bashResult';\nimport { inheritedSessionId, requiredSessionId } from '../../services/session';\nimport type { ILauncher } from '../../types/launcher';\nimport type { ILogReader } from '../../types/logReader';\nimport type { IRmuxBackend } from '../../types/rmuxBackend';\nimport type { IRunnerRegistry, RunnerRecord } from '../../types/runnerRegistry';\nimport { stopRunnerProcess } from '../reconcile';\nimport { isSequenceId, type RunnerSequenceStore } from '../runnerSequenceStore';\n\nconst MULTIPLEXER_BACKENDS = new Set(['rmux', 'tmux']);\n\nexport interface CliDependencies {\n registry: IRunnerRegistry;\n launcher: ILauncher;\n rmuxBackend: IRmuxBackend;\n logReader: ILogReader;\n env?: NodeJS.ProcessEnv;\n sequences?: RunnerSequenceStore;\n stdout(text: string): void;\n stderr(text: string): void;\n readStdin(): Promise<string>;\n}\n\nexport async function runCli(argv: readonly string[], dependencies: CliDependencies): Promise<number> {\n const [command, ...args] = argv;\n if (command !== undefined && command !== '--help' && command !== '-h' && !inheritedSessionId(dependencies.env)) {\n dependencies.stderr('PI_SESSION_ID is required for po-runner commands');\n return 1;\n }\n if (command && args[0] && isSequenceId(args[0])) return sequenceCommand(command, args, dependencies);\n switch (command) {\n case 'list':\n return list(args, dependencies);\n case 'status':\n return status(args, dependencies);\n case 'logs':\n return logs(args, dependencies);\n case 'stop':\n return stop(args, dependencies);\n case 'stop-all':\n return stopAll(args, dependencies);\n case 'input':\n return input(args, dependencies);\n case '--help':\n case '-h':\n case undefined:\n dependencies.stdout(runnerCliHelp());\n return 0;\n default:\n dependencies.stderr(`Unknown command: ${command}\\n\\n${runnerCliHelp()}`);\n return 1;\n }\n}\n\nasync function sequenceCommand(\n command: string,\n args: readonly string[],\n dependencies: CliDependencies,\n): Promise<number> {\n const store = dependencies.sequences;\n if (!store) {\n dependencies.stderr('Sequence controls are unavailable.');\n return 1;\n }\n const record = await store.get(args[0]!);\n if (!record) {\n dependencies.stderr(`No sequence with id ${args[0]}`);\n return 1;\n }\n if (command === 'stop') {\n if (record.state !== 'running') {\n dependencies.stderr(`Sequence ${record.id} is already completed`);\n return 1;\n }\n await store.requestStop(record.id, option(args, '--reason'));\n dependencies.stdout(`Stop requested for sequence ${record.id}`);\n return 0;\n }\n if (command === 'status') {\n dependencies.stdout(\n [\n `ID: ${record.id}`,\n `Name: ${record.name}`,\n `State: ${record.state}`,\n `Session: ${record.sessionId}`,\n ...(record.outcome ? [`Outcome: ${record.outcome}`] : []),\n ...record.stages.map((stage) => `Stage ${stage.index + 1}: ${stage.state}${stage.id ? ` (${stage.id})` : ''}`),\n ].join('\\n'),\n );\n return 0;\n }\n if (command === 'logs') {\n if (args.includes('--follow')) {\n dependencies.stderr('Sequence logs are finite snapshots; inspect status before reading again.');\n return 1;\n }\n if (record.result)\n dependencies.stdout(\n record.result.content.flatMap((part) => (part.type === 'text' ? [part.text] : [])).join('\\n'),\n );\n else\n dependencies.stdout(\n [\n `Sequence ${record.id} is running.`,\n ...record.stages.filter((stage) => stage.logPath).map((stage) => `${stage.index + 1}. ${stage.logPath}`),\n ].join('\\n'),\n );\n return 0;\n }\n dependencies.stderr(\n command === 'input' ? 'Command sequences are noninteractive.' : `Unknown sequence command: ${command}`,\n );\n return 1;\n}\n\nasync function list(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = args.includes('--all')\n ? await dependencies.registry.listAll(sessionId)\n : await dependencies.registry.listBySession(sessionId);\n const sequences = (await dependencies.sequences?.list(args.includes('--all'))) ?? [];\n const rows = [\n ...records.map(formatRecord),\n ...sequences.map((record) => `${record.id} ${record.state} sequence ${record.name}`),\n ];\n dependencies.stdout(rows.length > 0 ? rows.join('\\n') : 'No runners');\n return 0;\n}\n\nasync function status(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n dependencies.stdout(\n [\n `ID: ${record.id}`,\n `Name: ${record.name}`,\n `State: ${record.state}`,\n `Backend: ${record.backend}`,\n ...(record.backendTarget ? [`Backend target: ${record.backendTarget}`] : []),\n `PID: ${record.pid}`,\n `Command: ${record.command}`,\n `CWD: ${record.cwd}`,\n `Session: ${record.sessionId}`,\n `Log: ${record.logPath}`,\n ...(record.exit ? [`Exit: ${formatExit(record)}`] : []),\n ].join('\\n'),\n );\n return 0;\n}\n\nasync function logs(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n const lines = positiveInteger(option(args, '--lines')) ?? DEFAULT_LOG_LINES;\n const result = await dependencies.logReader.read(record.logPath, { lines });\n if (!result.exists) {\n dependencies.stderr(`Runner ${record.id} has not written a log yet`);\n return 1;\n }\n if (result.text) dependencies.stdout(result.text);\n if (!args.includes('--follow')) return 0;\n return follow(record, result.fileSize, dependencies);\n}\n\nasync function stop(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state !== 'running') {\n dependencies.stderr(`Runner ${record.id} is already ${record.state}`);\n return 1;\n }\n const reason = option(args, '--reason');\n if (!(await stopRecord(record, dependencies, reason))) {\n dependencies.stderr(`Could not stop runner ${record.id}`);\n return 1;\n }\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n dependencies.stdout(`Stopped ${record.id}\\nLog: ${record.logPath}`);\n return 0;\n}\n\nasync function stopAll(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = await dependencies.registry.listBySession(sessionId);\n const reason = option(args, '--reason');\n for (const sequence of (await dependencies.sequences?.list()) ?? []) {\n await dependencies.sequences!.requestStop(sequence.id, reason);\n dependencies.stdout(`Stop requested for sequence ${sequence.id}`);\n }\n const stopped: RunnerRecord[] = [];\n for (const record of records) {\n if (!(await stopRecord(record, dependencies, reason))) continue;\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n stopped.push(record);\n }\n dependencies.stdout(\n records.length === 0\n ? `No active runners for session ${sessionId}`\n : `Stopped ${stopped.length} runner(s) for session ${sessionId}: ${stopped.map((record) => record.id).join(', ')}`,\n );\n if (stopped.length !== records.length) {\n dependencies.stderr(`Could not stop ${records.length - stopped.length} runner(s) for session ${sessionId}`);\n return 1;\n }\n return 0;\n}\n\nasync function input(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state === COMPLETED_STATE) {\n dependencies.stderr(`Runner ${record.id} is already completed; use po-runner logs ${record.id}`);\n return 1;\n }\n if (!record.interactive) {\n dependencies.stderr(`Runner ${record.id} was not started with interactive: true`);\n return 1;\n }\n const supplied = option(args, '--text');\n const text = supplied ?? (await dependencies.readStdin());\n const payload = args.includes('--enter') && !text.endsWith('\\n') ? `${text}\\n` : text;\n if (!MULTIPLEXER_BACKENDS.has(record.backend) || !record.backendTarget) {\n dependencies.stderr(`Runner ${record.id} uses the ${record.backend} backend, which does not expose CLI input`);\n return 1;\n }\n if (!(await dependencies.rmuxBackend.input(record.backendTarget, payload))) {\n dependencies.stderr(`Runner ${record.id} is no longer accepting RMUX input`);\n return 1;\n }\n dependencies.stdout(`Sent input to ${record.id}`);\n return 0;\n}\n\nasync function requiredRecord(\n id: string | undefined,\n dependencies: CliDependencies,\n): Promise<RunnerRecord | undefined> {\n if (!id) {\n dependencies.stderr('A runner ID is required');\n return undefined;\n }\n const sessionId = requiredSessionId(dependencies.env);\n const scopedRecord = await dependencies.registry.get(id, sessionId);\n if (!scopedRecord) {\n dependencies.stderr(`No runner with id ${id}`);\n return undefined;\n }\n return scopedRecord;\n}\n\nfunction formatRecord(record: RunnerRecord): string {\n const active = formatRunnerLine(record, Date.now());\n return `${record.id} ${record.state} ${record.backend} ${active}`;\n}\n\nfunction formatExit(record: RunnerRecord): string {\n const exit = record.exit;\n if (!exit) return 'unknown';\n const detail = exit.code !== null ? ` code ${exit.code}` : exit.signal ? ` ${exit.signal}` : '';\n const attribution = exit.terminationReason ? ` [${exit.terminationReason}]` : '';\n const note = exit.stopReason ? ` (${exit.stopReason})` : '';\n return `${exit.reason}${detail}${attribution}${note}`;\n}\n\nfunction option(args: readonly string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nfunction positiveInteger(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nasync function follow(record: RunnerRecord, initialSize: number, dependencies: CliDependencies): Promise<number> {\n let offset = initialSize;\n return new Promise<number>((resolve) => {\n let stopped = false;\n let stateTimer: NodeJS.Timeout;\n let reads = Promise.resolve();\n const drain = async (current: fs.Stats): Promise<void> => {\n if (current.size < offset) offset = 0;\n if (current.size === offset) return;\n const length = current.size - offset;\n const buffer = Buffer.alloc(length);\n const descriptor = await open(record.logPath, 'r');\n try {\n const { bytesRead } = await descriptor.read(buffer, 0, length, offset);\n if (bytesRead > 0) dependencies.stdout(buffer.subarray(0, bytesRead).toString('utf8'));\n offset += bytesRead;\n } finally {\n await descriptor.close();\n }\n };\n const report = (error: unknown): void => {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n dependencies.stderr(`Runner ${record.id} failed to flush its final log output: ${String(error)}`);\n }\n };\n const listener = (current: fs.Stats): void => {\n if (stopped) return;\n reads = reads.then(() => drain(current)).catch(report);\n };\n const stopFollowing = (): void => {\n if (stopped) return;\n stopped = true;\n fs.unwatchFile(record.logPath, listener);\n clearInterval(stateTimer);\n process.off('SIGINT', stopFollowing);\n reads = reads.then(async () => drain(await stat(record.logPath))).catch(report);\n void reads.then(() => resolve(0));\n };\n process.once('SIGINT', stopFollowing);\n fs.watchFile(record.logPath, { interval: FOLLOW_INTERVAL_MS }, listener);\n stateTimer = setInterval(() => {\n void dependencies.registry.get(record.id).then((current) => {\n if (current?.state === COMPLETED_STATE) stopFollowing();\n });\n }, FOLLOW_INTERVAL_MS);\n });\n}\n\nasync function stopRecord(record: RunnerRecord, dependencies: CliDependencies, reason?: string): Promise<boolean> {\n return stopRunnerProcess(record, dependencies.launcher, dependencies.rmuxBackend, {\n registry: dependencies.registry,\n intent: { reason: STOPPED_REASON, terminationReason: 'user_stop', ...(reason ? { stopReason: reason } : {}) },\n });\n}\n\nexport function runnerCliHelp(): string {\n return [\n 'Usage: po-runner <command>',\n '',\n 'Commands:',\n ' list [--all]',\n ' status <id>',\n ' logs <id> [--lines N] [--follow]',\n ' stop <id> [--reason <text>]',\n ' stop-all [--reason <text>]',\n ' input <id> [--text <text>] [--enter]',\n ].join('\\n');\n}\n"],"mappings":";;;;;;;;AAGA,MAAa,iBAAiB;AAC9B,MAAa,qBAAqB;;;ACelC,MAAM,uCAAuB,IAAI,IAAI,CAAC,QAAQ,MAAM,CAAC;AAcrD,eAAsB,OAAO,MAAyB,cAAgD;CACpG,MAAM,CAAC,SAAS,GAAG,QAAQ;CAC3B,IAAI,YAAY,KAAA,KAAa,YAAY,YAAY,YAAY,QAAQ,CAACA,gBAAAA,mBAAmB,aAAa,GAAG,GAAG;EAC9G,aAAa,OAAO,kDAAkD;EACtE,OAAO;CACT;CACA,IAAI,WAAW,KAAK,MAAMC,4BAAAA,aAAa,KAAK,EAAE,GAAG,OAAO,gBAAgB,SAAS,MAAM,YAAY;CACnG,QAAQ,SAAR;EACE,KAAK,QACH,OAAO,KAAK,MAAM,YAAY;EAChC,KAAK,UACH,OAAO,OAAO,MAAM,YAAY;EAClC,KAAK,QACH,OAAO,KAAK,MAAM,YAAY;EAChC,KAAK,QACH,OAAO,KAAK,MAAM,YAAY;EAChC,KAAK,YACH,OAAO,QAAQ,MAAM,YAAY;EACnC,KAAK,SACH,OAAO,MAAM,MAAM,YAAY;EACjC,KAAK;EACL,KAAK;EACL,KAAK,KAAA;GACH,aAAa,OAAO,cAAc,CAAC;GACnC,OAAO;EACT;GACE,aAAa,OAAO,oBAAoB,QAAQ,MAAM,cAAc,GAAG;GACvE,OAAO;CACX;AACF;AAEA,eAAe,gBACb,SACA,MACA,cACiB;CACjB,MAAM,QAAQ,aAAa;CAC3B,IAAI,CAAC,OAAO;EACV,aAAa,OAAO,oCAAoC;EACxD,OAAO;CACT;CACA,MAAM,SAAS,MAAM,MAAM,IAAI,KAAK,EAAG;CACvC,IAAI,CAAC,QAAQ;EACX,aAAa,OAAO,uBAAuB,KAAK,IAAI;EACpD,OAAO;CACT;CACA,IAAI,YAAY,QAAQ;EACtB,IAAI,OAAO,UAAU,WAAW;GAC9B,aAAa,OAAO,YAAY,OAAO,GAAG,sBAAsB;GAChE,OAAO;EACT;EACA,MAAM,MAAM,YAAY,OAAO,IAAI,OAAO,MAAM,UAAU,CAAC;EAC3D,aAAa,OAAO,+BAA+B,OAAO,IAAI;EAC9D,OAAO;CACT;CACA,IAAI,YAAY,UAAU;EACxB,aAAa,OACX;GACE,OAAO,OAAO;GACd,SAAS,OAAO;GAChB,UAAU,OAAO;GACjB,YAAY,OAAO;GACnB,GAAI,OAAO,UAAU,CAAC,YAAY,OAAO,SAAS,IAAI,CAAC;GACvD,GAAG,OAAO,OAAO,KAAK,UAAU,SAAS,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,GAAG,KAAK,IAAI;EAC/G,CAAC,CAAC,KAAK,IAAI,CACb;EACA,OAAO;CACT;CACA,IAAI,YAAY,QAAQ;EACtB,IAAI,KAAK,SAAS,UAAU,GAAG;GAC7B,aAAa,OAAO,0EAA0E;GAC9F,OAAO;EACT;EACA,IAAI,OAAO,QACT,aAAa,OACX,OAAO,OAAO,QAAQ,SAAS,SAAU,KAAK,SAAS,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAE,CAAC,CAAC,KAAK,IAAI,CAC9F;OAEA,aAAa,OACX,CACE,YAAY,OAAO,GAAG,eACtB,GAAG,OAAO,OAAO,QAAQ,UAAU,MAAM,OAAO,CAAC,CAAC,KAAK,UAAU,GAAG,MAAM,QAAQ,EAAE,IAAI,MAAM,SAAS,CACzG,CAAC,CAAC,KAAK,IAAI,CACb;EACF,OAAO;CACT;CACA,aAAa,OACX,YAAY,UAAU,0CAA0C,6BAA6B,SAC/F;CACA,OAAO;AACT;AAEA,eAAe,KAAK,MAAyB,cAAgD;CAC3F,MAAM,YAAYC,gBAAAA,kBAAkB,aAAa,GAAG;CACpD,MAAM,UAAU,KAAK,SAAS,OAAO,IACjC,MAAM,aAAa,SAAS,QAAQ,SAAS,IAC7C,MAAM,aAAa,SAAS,cAAc,SAAS;CACvD,MAAM,YAAa,MAAM,aAAa,WAAW,KAAK,KAAK,SAAS,OAAO,CAAC,KAAM,CAAC;CACnF,MAAM,OAAO,CACX,GAAG,QAAQ,IAAI,YAAY,GAC3B,GAAG,UAAU,KAAK,WAAW,GAAG,OAAO,GAAG,IAAI,OAAO,MAAM,cAAc,OAAO,MAAM,CACxF;CACA,aAAa,OAAO,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,YAAY;CACpE,OAAO;AACT;AAEA,eAAe,OAAO,MAAyB,cAAgD;CAC7F,MAAM,SAAS,MAAM,eAAe,KAAK,IAAI,YAAY;CACzD,IAAI,CAAC,QAAQ,OAAO;CACpB,aAAa,OACX;EACE,OAAO,OAAO;EACd,SAAS,OAAO;EAChB,UAAU,OAAO;EACjB,YAAY,OAAO;EACnB,GAAI,OAAO,gBAAgB,CAAC,mBAAmB,OAAO,eAAe,IAAI,CAAC;EAC1E,QAAQ,OAAO;EACf,YAAY,OAAO;EACnB,QAAQ,OAAO;EACf,YAAY,OAAO;EACnB,QAAQ,OAAO;EACf,GAAI,OAAO,OAAO,CAAC,SAAS,WAAW,MAAM,GAAG,IAAI,CAAC;CACvD,CAAC,CAAC,KAAK,IAAI,CACb;CACA,OAAO;AACT;AAEA,eAAe,KAAK,MAAyB,cAAgD;CAC3F,MAAM,SAAS,MAAM,eAAe,KAAK,IAAI,YAAY;CACzD,IAAI,CAAC,QAAQ,OAAO;CACpB,MAAM,QAAQ,gBAAgB,OAAO,MAAM,SAAS,CAAC,KAAA;CACrD,MAAM,SAAS,MAAM,aAAa,UAAU,KAAK,OAAO,SAAS,EAAE,MAAM,CAAC;CAC1E,IAAI,CAAC,OAAO,QAAQ;EAClB,aAAa,OAAO,UAAU,OAAO,GAAG,2BAA2B;EACnE,OAAO;CACT;CACA,IAAI,OAAO,MAAM,aAAa,OAAO,OAAO,IAAI;CAChD,IAAI,CAAC,KAAK,SAAS,UAAU,GAAG,OAAO;CACvC,OAAO,OAAO,QAAQ,OAAO,UAAU,YAAY;AACrD;AAEA,eAAe,KAAK,MAAyB,cAAgD;CAC3F,MAAM,SAAS,MAAM,eAAe,KAAK,IAAI,YAAY;CACzD,IAAI,CAAC,QAAQ,OAAO;CACpB,IAAI,OAAO,UAAU,WAAW;EAC9B,aAAa,OAAO,UAAU,OAAO,GAAG,cAAc,OAAO,OAAO;EACpE,OAAO;CACT;CACA,MAAM,SAAS,OAAO,MAAM,UAAU;CACtC,IAAI,CAAE,MAAM,WAAW,QAAQ,cAAc,MAAM,GAAI;EACrD,aAAa,OAAO,yBAAyB,OAAO,IAAI;EACxD,OAAO;CACT;CACA,MAAM,aAAa,SAAS,SAC1B,OAAO,IACP;EACE,QAAQ;EACR,MAAM;EACN,QAAQ;EACR,GAAI,SAAS,EAAE,YAAY,OAAO,IAAI,CAAC;CACzC,GACA,OAAO,SACT;CACA,aAAa,OAAO,WAAW,OAAO,GAAG,SAAS,OAAO,SAAS;CAClE,OAAO;AACT;AAEA,eAAe,QAAQ,MAAyB,cAAgD;CAC9F,MAAM,YAAYA,gBAAAA,kBAAkB,aAAa,GAAG;CACpD,MAAM,UAAU,MAAM,aAAa,SAAS,cAAc,SAAS;CACnE,MAAM,SAAS,OAAO,MAAM,UAAU;CACtC,KAAK,MAAM,YAAa,MAAM,aAAa,WAAW,KAAK,KAAM,CAAC,GAAG;EACnE,MAAM,aAAa,UAAW,YAAY,SAAS,IAAI,MAAM;EAC7D,aAAa,OAAO,+BAA+B,SAAS,IAAI;CAClE;CACA,MAAM,UAA0B,CAAC;CACjC,KAAK,MAAM,UAAU,SAAS;EAC5B,IAAI,CAAE,MAAM,WAAW,QAAQ,cAAc,MAAM,GAAI;EACvD,MAAM,aAAa,SAAS,SAC1B,OAAO,IACP;GACE,QAAQ;GACR,MAAM;GACN,QAAQ;GACR,GAAI,SAAS,EAAE,YAAY,OAAO,IAAI,CAAC;EACzC,GACA,OAAO,SACT;EACA,QAAQ,KAAK,MAAM;CACrB;CACA,aAAa,OACX,QAAQ,WAAW,IACf,iCAAiC,cACjC,WAAW,QAAQ,OAAO,yBAAyB,UAAU,IAAI,QAAQ,KAAK,WAAW,OAAO,EAAE,CAAC,CAAC,KAAK,IAAI,GACnH;CACA,IAAI,QAAQ,WAAW,QAAQ,QAAQ;EACrC,aAAa,OAAO,kBAAkB,QAAQ,SAAS,QAAQ,OAAO,yBAAyB,WAAW;EAC1G,OAAO;CACT;CACA,OAAO;AACT;AAEA,eAAe,MAAM,MAAyB,cAAgD;CAC5F,MAAM,SAAS,MAAM,eAAe,KAAK,IAAI,YAAY;CACzD,IAAI,CAAC,QAAQ,OAAO;CACpB,IAAI,OAAO,UAAA,aAA2B;EACpC,aAAa,OAAO,UAAU,OAAO,GAAG,4CAA4C,OAAO,IAAI;EAC/F,OAAO;CACT;CACA,IAAI,CAAC,OAAO,aAAa;EACvB,aAAa,OAAO,UAAU,OAAO,GAAG,wCAAwC;EAChF,OAAO;CACT;CAEA,MAAM,OADW,OAAO,MAAM,QACV,KAAM,MAAM,aAAa,UAAU;CACvD,MAAM,UAAU,KAAK,SAAS,SAAS,KAAK,CAAC,KAAK,SAAS,IAAI,IAAI,GAAG,KAAK,MAAM;CACjF,IAAI,CAAC,qBAAqB,IAAI,OAAO,OAAO,KAAK,CAAC,OAAO,eAAe;EACtE,aAAa,OAAO,UAAU,OAAO,GAAG,YAAY,OAAO,QAAQ,0CAA0C;EAC7G,OAAO;CACT;CACA,IAAI,CAAE,MAAM,aAAa,YAAY,MAAM,OAAO,eAAe,OAAO,GAAI;EAC1E,aAAa,OAAO,UAAU,OAAO,GAAG,mCAAmC;EAC3E,OAAO;CACT;CACA,aAAa,OAAO,iBAAiB,OAAO,IAAI;CAChD,OAAO;AACT;AAEA,eAAe,eACb,IACA,cACmC;CACnC,IAAI,CAAC,IAAI;EACP,aAAa,OAAO,yBAAyB;EAC7C;CACF;CACA,MAAM,YAAYA,gBAAAA,kBAAkB,aAAa,GAAG;CACpD,MAAM,eAAe,MAAM,aAAa,SAAS,IAAI,IAAI,SAAS;CAClE,IAAI,CAAC,cAAc;EACjB,aAAa,OAAO,qBAAqB,IAAI;EAC7C;CACF;CACA,OAAO;AACT;AAEA,SAAS,aAAa,QAA8B;CAClD,MAAM,SAASC,mBAAAA,iBAAiB,QAAQ,KAAK,IAAI,CAAC;CAClD,OAAO,GAAG,OAAO,GAAG,IAAI,OAAO,MAAM,IAAI,OAAO,QAAQ,IAAI;AAC9D;AAEA,SAAS,WAAW,QAA8B;CAChD,MAAM,OAAO,OAAO;CACpB,IAAI,CAAC,MAAM,OAAO;CAClB,MAAM,SAAS,KAAK,SAAS,OAAO,SAAS,KAAK,SAAS,KAAK,SAAS,IAAI,KAAK,WAAW;CAC7F,MAAM,cAAc,KAAK,oBAAoB,KAAK,KAAK,kBAAkB,KAAK;CAC9E,MAAM,OAAO,KAAK,aAAa,KAAK,KAAK,WAAW,KAAK;CACzD,OAAO,GAAG,KAAK,SAAS,SAAS,cAAc;AACjD;AAEA,SAAS,OAAO,MAAyB,MAAkC;CACzE,MAAM,QAAQ,KAAK,QAAQ,IAAI;CAC/B,OAAO,SAAS,IAAI,KAAK,QAAQ,KAAK,KAAA;AACxC;AAEA,SAAS,gBAAgB,OAA+C;CACtE,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,MAAM,SAAS,OAAO,KAAK;CAC3B,OAAO,OAAO,UAAU,MAAM,KAAK,SAAS,IAAI,SAAS,KAAA;AAC3D;AAEA,eAAe,OAAO,QAAsB,aAAqB,cAAgD;CAC/G,IAAI,SAAS;CACb,OAAO,IAAI,SAAiB,YAAY;EACtC,IAAI,UAAU;EACd,IAAI;EACJ,IAAI,QAAQ,QAAQ,QAAQ;EAC5B,MAAM,QAAQ,OAAO,YAAqC;GACxD,IAAI,QAAQ,OAAO,QAAQ,SAAS;GACpC,IAAI,QAAQ,SAAS,QAAQ;GAC7B,MAAM,SAAS,QAAQ,OAAO;GAC9B,MAAM,SAAS,OAAO,MAAM,MAAM;GAClC,MAAM,aAAa,OAAA,GAAMC,iBAAAA,KAAAA,CAAK,OAAO,SAAS,GAAG;GACjD,IAAI;IACF,MAAM,EAAE,cAAc,MAAM,WAAW,KAAK,QAAQ,GAAG,QAAQ,MAAM;IACrE,IAAI,YAAY,GAAG,aAAa,OAAO,OAAO,SAAS,GAAG,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC;IACrF,UAAU;GACZ,UAAU;IACR,MAAM,WAAW,MAAM;GACzB;EACF;EACA,MAAM,UAAU,UAAyB;GACvC,IAAK,MAAgC,SAAS,UAC5C,aAAa,OAAO,UAAU,OAAO,GAAG,yCAAyC,OAAO,KAAK,GAAG;EAEpG;EACA,MAAM,YAAY,YAA4B;GAC5C,IAAI,SAAS;GACb,QAAQ,MAAM,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,MAAM,MAAM;EACvD;EACA,MAAM,sBAA4B;GAChC,IAAI,SAAS;GACb,UAAU;GACV,QAAA,QAAG,YAAY,OAAO,SAAS,QAAQ;GACvC,cAAc,UAAU;GACxB,QAAQ,IAAI,UAAU,aAAa;GACnC,QAAQ,MAAM,KAAK,YAAY,MAAM,OAAA,GAAMC,iBAAAA,KAAAA,CAAK,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM;GAC9E,MAAW,WAAW,QAAQ,CAAC,CAAC;EAClC;EACA,QAAQ,KAAK,UAAU,aAAa;EACpC,QAAA,QAAG,UAAU,OAAO,SAAS,EAAE,UAAA,IAA6B,GAAG,QAAQ;EACvE,aAAa,kBAAkB;GAC7B,aAAkB,SAAS,IAAI,OAAO,EAAE,CAAC,CAAC,MAAM,YAAY;IAC1D,IAAI,SAAS,UAAA,aAA2B,cAAc;GACxD,CAAC;EACH,GAAA,GAAqB;CACvB,CAAC;AACH;AAEA,eAAe,WAAW,QAAsB,cAA+B,QAAmC;CAChH,OAAOC,kBAAAA,kBAAkB,QAAQ,aAAa,UAAU,aAAa,aAAa;EAChF,UAAU,aAAa;EACvB,QAAQ;GAAE,QAAQ;GAAgB,mBAAmB;GAAa,GAAI,SAAS,EAAE,YAAY,OAAO,IAAI,CAAC;EAAG;CAC9G,CAAC;AACH;AAEA,SAAgB,gBAAwB;CACtC,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;AACb"}
1
+ {"version":3,"file":"cliApp-BYfgP44s.cjs","names":["inheritedSessionId","isSequenceId","requiredSessionId","formatRunnerLine","open","stat","stopRunnerProcess"],"sources":["../src/constants/cliApp.ts","../src/services/cliApp/index.ts"],"sourcesContent":["export const DEFAULT_LOG_LINES = 200;\nexport const FOLLOW_INTERVAL_MS = 250;\nexport const COMPLETED_STATE = 'completed';\nexport const STOPPED_REASON = 'stopped';\nexport const TERMINATION_SIGNAL = 'SIGTERM';\n","import fs from 'node:fs';\nimport { open, stat } from 'node:fs/promises';\n\nimport {\n COMPLETED_STATE,\n DEFAULT_LOG_LINES,\n FOLLOW_INTERVAL_MS,\n STOPPED_REASON,\n TERMINATION_SIGNAL,\n} from '../../constants/cliApp';\nimport { formatRunnerLine } from '../../services/bashResult';\nimport { inheritedSessionId, requiredSessionId } from '../../services/session';\nimport type { ILauncher } from '../../types/launcher';\nimport type { ILogReader } from '../../types/logReader';\nimport type { IRmuxBackend } from '../../types/rmuxBackend';\nimport type { IRunnerRegistry, RunnerRecord } from '../../types/runnerRegistry';\nimport { stopRunnerProcess } from '../reconcile';\nimport { isSequenceId, type RunnerSequenceStore } from '../runnerSequenceStore';\n\nconst MULTIPLEXER_BACKENDS = new Set(['rmux', 'tmux']);\n\nexport interface CliDependencies {\n registry: IRunnerRegistry;\n launcher: ILauncher;\n rmuxBackend: IRmuxBackend;\n logReader: ILogReader;\n env?: NodeJS.ProcessEnv;\n sequences?: RunnerSequenceStore;\n stdout(text: string): void;\n stderr(text: string): void;\n readStdin(): Promise<string>;\n}\n\nexport async function runCli(argv: readonly string[], dependencies: CliDependencies): Promise<number> {\n const [command, ...args] = argv;\n if (command !== undefined && command !== '--help' && command !== '-h' && !inheritedSessionId(dependencies.env)) {\n dependencies.stderr('PO_SESSION_ID is required for po-runner commands');\n return 1;\n }\n if (command && args[0] && isSequenceId(args[0])) return sequenceCommand(command, args, dependencies);\n switch (command) {\n case 'list':\n return list(args, dependencies);\n case 'status':\n return status(args, dependencies);\n case 'logs':\n return logs(args, dependencies);\n case 'stop':\n return stop(args, dependencies);\n case 'stop-all':\n return stopAll(args, dependencies);\n case 'input':\n return input(args, dependencies);\n case '--help':\n case '-h':\n case undefined:\n dependencies.stdout(runnerCliHelp());\n return 0;\n default:\n dependencies.stderr(`Unknown command: ${command}\\n\\n${runnerCliHelp()}`);\n return 1;\n }\n}\n\nasync function sequenceCommand(\n command: string,\n args: readonly string[],\n dependencies: CliDependencies,\n): Promise<number> {\n const store = dependencies.sequences;\n if (!store) {\n dependencies.stderr('Sequence controls are unavailable.');\n return 1;\n }\n const record = await store.get(args[0]!);\n if (!record) {\n dependencies.stderr(`No sequence with id ${args[0]}`);\n return 1;\n }\n if (command === 'stop') {\n if (record.state !== 'running') {\n dependencies.stderr(`Sequence ${record.id} is already completed`);\n return 1;\n }\n await store.requestStop(record.id, option(args, '--reason'));\n dependencies.stdout(`Stop requested for sequence ${record.id}`);\n return 0;\n }\n if (command === 'status') {\n dependencies.stdout(\n [\n `ID: ${record.id}`,\n `Name: ${record.name}`,\n `State: ${record.state}`,\n `Session: ${record.sessionId}`,\n ...(record.outcome ? [`Outcome: ${record.outcome}`] : []),\n ...record.stages.map((stage) => `Stage ${stage.index + 1}: ${stage.state}${stage.id ? ` (${stage.id})` : ''}`),\n ].join('\\n'),\n );\n return 0;\n }\n if (command === 'logs') {\n if (args.includes('--follow')) {\n dependencies.stderr('Sequence logs are finite snapshots; inspect status before reading again.');\n return 1;\n }\n if (record.result)\n dependencies.stdout(\n record.result.content.flatMap((part) => (part.type === 'text' ? [part.text] : [])).join('\\n'),\n );\n else\n dependencies.stdout(\n [\n `Sequence ${record.id} is running.`,\n ...record.stages.filter((stage) => stage.logPath).map((stage) => `${stage.index + 1}. ${stage.logPath}`),\n ].join('\\n'),\n );\n return 0;\n }\n dependencies.stderr(\n command === 'input' ? 'Command sequences are noninteractive.' : `Unknown sequence command: ${command}`,\n );\n return 1;\n}\n\nasync function list(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = args.includes('--all')\n ? await dependencies.registry.listAll(sessionId)\n : await dependencies.registry.listBySession(sessionId);\n const sequences = (await dependencies.sequences?.list(args.includes('--all'))) ?? [];\n const rows = [\n ...records.map(formatRecord),\n ...sequences.map((record) => `${record.id} ${record.state} sequence ${record.name}`),\n ];\n dependencies.stdout(rows.length > 0 ? rows.join('\\n') : 'No runners');\n return 0;\n}\n\nasync function status(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n dependencies.stdout(\n [\n `ID: ${record.id}`,\n `Name: ${record.name}`,\n `State: ${record.state}`,\n `Backend: ${record.backend}`,\n ...(record.backendTarget ? [`Backend target: ${record.backendTarget}`] : []),\n `PID: ${record.pid}`,\n `Command: ${record.command}`,\n `CWD: ${record.cwd}`,\n `Session: ${record.sessionId}`,\n `Log: ${record.logPath}`,\n ...(record.exit ? [`Exit: ${formatExit(record)}`] : []),\n ].join('\\n'),\n );\n return 0;\n}\n\nasync function logs(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n const lines = positiveInteger(option(args, '--lines')) ?? DEFAULT_LOG_LINES;\n const result = await dependencies.logReader.read(record.logPath, { lines });\n if (!result.exists) {\n dependencies.stderr(`Runner ${record.id} has not written a log yet`);\n return 1;\n }\n if (result.text) dependencies.stdout(result.text);\n if (!args.includes('--follow')) return 0;\n return follow(record, result.fileSize, dependencies);\n}\n\nasync function stop(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state !== 'running') {\n dependencies.stderr(`Runner ${record.id} is already ${record.state}`);\n return 1;\n }\n const reason = option(args, '--reason');\n if (!(await stopRecord(record, dependencies, reason))) {\n dependencies.stderr(`Could not stop runner ${record.id}`);\n return 1;\n }\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n dependencies.stdout(`Stopped ${record.id}\\nLog: ${record.logPath}`);\n return 0;\n}\n\nasync function stopAll(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = await dependencies.registry.listBySession(sessionId);\n const reason = option(args, '--reason');\n for (const sequence of (await dependencies.sequences?.list()) ?? []) {\n await dependencies.sequences!.requestStop(sequence.id, reason);\n dependencies.stdout(`Stop requested for sequence ${sequence.id}`);\n }\n const stopped: RunnerRecord[] = [];\n for (const record of records) {\n if (!(await stopRecord(record, dependencies, reason))) continue;\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n stopped.push(record);\n }\n dependencies.stdout(\n records.length === 0\n ? `No active runners for session ${sessionId}`\n : `Stopped ${stopped.length} runner(s) for session ${sessionId}: ${stopped.map((record) => record.id).join(', ')}`,\n );\n if (stopped.length !== records.length) {\n dependencies.stderr(`Could not stop ${records.length - stopped.length} runner(s) for session ${sessionId}`);\n return 1;\n }\n return 0;\n}\n\nasync function input(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state === COMPLETED_STATE) {\n dependencies.stderr(`Runner ${record.id} is already completed; use po-runner logs ${record.id}`);\n return 1;\n }\n if (!record.interactive) {\n dependencies.stderr(`Runner ${record.id} was not started with interactive: true`);\n return 1;\n }\n const supplied = option(args, '--text');\n const text = supplied ?? (await dependencies.readStdin());\n const payload = args.includes('--enter') && !text.endsWith('\\n') ? `${text}\\n` : text;\n if (!MULTIPLEXER_BACKENDS.has(record.backend) || !record.backendTarget) {\n dependencies.stderr(`Runner ${record.id} uses the ${record.backend} backend, which does not expose CLI input`);\n return 1;\n }\n if (!(await dependencies.rmuxBackend.input(record.backendTarget, payload))) {\n dependencies.stderr(`Runner ${record.id} is no longer accepting RMUX input`);\n return 1;\n }\n dependencies.stdout(`Sent input to ${record.id}`);\n return 0;\n}\n\nasync function requiredRecord(\n id: string | undefined,\n dependencies: CliDependencies,\n): Promise<RunnerRecord | undefined> {\n if (!id) {\n dependencies.stderr('A runner ID is required');\n return undefined;\n }\n const sessionId = requiredSessionId(dependencies.env);\n const scopedRecord = await dependencies.registry.get(id, sessionId);\n if (!scopedRecord) {\n dependencies.stderr(`No runner with id ${id}`);\n return undefined;\n }\n return scopedRecord;\n}\n\nfunction formatRecord(record: RunnerRecord): string {\n const active = formatRunnerLine(record, Date.now());\n return `${record.id} ${record.state} ${record.backend} ${active}`;\n}\n\nfunction formatExit(record: RunnerRecord): string {\n const exit = record.exit;\n if (!exit) return 'unknown';\n const detail = exit.code !== null ? ` code ${exit.code}` : exit.signal ? ` ${exit.signal}` : '';\n const attribution = exit.terminationReason ? ` [${exit.terminationReason}]` : '';\n const note = exit.stopReason ? ` (${exit.stopReason})` : '';\n return `${exit.reason}${detail}${attribution}${note}`;\n}\n\nfunction option(args: readonly string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nfunction positiveInteger(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nasync function follow(record: RunnerRecord, initialSize: number, dependencies: CliDependencies): Promise<number> {\n let offset = initialSize;\n return new Promise<number>((resolve) => {\n let stopped = false;\n let stateTimer: NodeJS.Timeout;\n let reads = Promise.resolve();\n const drain = async (current: fs.Stats): Promise<void> => {\n if (current.size < offset) offset = 0;\n if (current.size === offset) return;\n const length = current.size - offset;\n const buffer = Buffer.alloc(length);\n const descriptor = await open(record.logPath, 'r');\n try {\n const { bytesRead } = await descriptor.read(buffer, 0, length, offset);\n if (bytesRead > 0) dependencies.stdout(buffer.subarray(0, bytesRead).toString('utf8'));\n offset += bytesRead;\n } finally {\n await descriptor.close();\n }\n };\n const report = (error: unknown): void => {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n dependencies.stderr(`Runner ${record.id} failed to flush its final log output: ${String(error)}`);\n }\n };\n const listener = (current: fs.Stats): void => {\n if (stopped) return;\n reads = reads.then(() => drain(current)).catch(report);\n };\n const stopFollowing = (): void => {\n if (stopped) return;\n stopped = true;\n fs.unwatchFile(record.logPath, listener);\n clearInterval(stateTimer);\n process.off('SIGINT', stopFollowing);\n reads = reads.then(async () => drain(await stat(record.logPath))).catch(report);\n void reads.then(() => resolve(0));\n };\n process.once('SIGINT', stopFollowing);\n fs.watchFile(record.logPath, { interval: FOLLOW_INTERVAL_MS }, listener);\n stateTimer = setInterval(() => {\n void dependencies.registry.get(record.id).then((current) => {\n if (current?.state === COMPLETED_STATE) stopFollowing();\n });\n }, FOLLOW_INTERVAL_MS);\n });\n}\n\nasync function stopRecord(record: RunnerRecord, dependencies: CliDependencies, reason?: string): Promise<boolean> {\n return stopRunnerProcess(record, dependencies.launcher, dependencies.rmuxBackend, {\n registry: dependencies.registry,\n intent: { reason: STOPPED_REASON, terminationReason: 'user_stop', ...(reason ? { stopReason: reason } : {}) },\n });\n}\n\nexport function runnerCliHelp(): string {\n return [\n 'Usage: po-runner <command>',\n '',\n 'Commands:',\n ' list [--all]',\n ' status <id>',\n ' logs <id> [--lines N] [--follow]',\n ' stop <id> [--reason <text>]',\n ' stop-all [--reason <text>]',\n ' input <id> [--text <text>] [--enter]',\n ].join('\\n');\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { l as formatRunnerLine } from "./bashResult-ntL4Umz3.mjs";
2
2
  import { n as stopRunnerProcess } from "./reconcile-DUaX_vKZ.mjs";
3
3
  import { n as isSequenceId } from "./runnerSequenceStore-CaY7S_Sd.mjs";
4
- import { n as requiredSessionId, t as inheritedSessionId } from "./session-3oSU3QjI.mjs";
4
+ import { n as requiredSessionId, t as inheritedSessionId } from "./session-ISEGK4z9.mjs";
5
5
  import { open, stat } from "node:fs/promises";
6
6
  import fs$1 from "node:fs";
7
7
  const STOPPED_REASON = "stopped";
@@ -12,7 +12,7 @@ const MULTIPLEXER_BACKENDS = /* @__PURE__ */ new Set(["rmux", "tmux"]);
12
12
  async function runCli(argv, dependencies) {
13
13
  const [command, ...args] = argv;
14
14
  if (command !== void 0 && command !== "--help" && command !== "-h" && !inheritedSessionId(dependencies.env)) {
15
- dependencies.stderr("PI_SESSION_ID is required for po-runner commands");
15
+ dependencies.stderr("PO_SESSION_ID is required for po-runner commands");
16
16
  return 1;
17
17
  }
18
18
  if (command && args[0] && isSequenceId(args[0])) return sequenceCommand(command, args, dependencies);
@@ -291,4 +291,4 @@ function runnerCliHelp() {
291
291
  //#endregion
292
292
  export { runnerCliHelp as n, runCli as t };
293
293
 
294
- //# sourceMappingURL=cliApp-g7APOwcU.mjs.map
294
+ //# sourceMappingURL=cliApp-DPbA8LkI.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cliApp-g7APOwcU.mjs","names":[],"sources":["../src/constants/cliApp.ts","../src/services/cliApp/index.ts"],"sourcesContent":["export const DEFAULT_LOG_LINES = 200;\nexport const FOLLOW_INTERVAL_MS = 250;\nexport const COMPLETED_STATE = 'completed';\nexport const STOPPED_REASON = 'stopped';\nexport const TERMINATION_SIGNAL = 'SIGTERM';\n","import fs from 'node:fs';\nimport { open, stat } from 'node:fs/promises';\n\nimport {\n COMPLETED_STATE,\n DEFAULT_LOG_LINES,\n FOLLOW_INTERVAL_MS,\n STOPPED_REASON,\n TERMINATION_SIGNAL,\n} from '../../constants/cliApp';\nimport { formatRunnerLine } from '../../services/bashResult';\nimport { inheritedSessionId, requiredSessionId } from '../../services/session';\nimport type { ILauncher } from '../../types/launcher';\nimport type { ILogReader } from '../../types/logReader';\nimport type { IRmuxBackend } from '../../types/rmuxBackend';\nimport type { IRunnerRegistry, RunnerRecord } from '../../types/runnerRegistry';\nimport { stopRunnerProcess } from '../reconcile';\nimport { isSequenceId, type RunnerSequenceStore } from '../runnerSequenceStore';\n\nconst MULTIPLEXER_BACKENDS = new Set(['rmux', 'tmux']);\n\nexport interface CliDependencies {\n registry: IRunnerRegistry;\n launcher: ILauncher;\n rmuxBackend: IRmuxBackend;\n logReader: ILogReader;\n env?: NodeJS.ProcessEnv;\n sequences?: RunnerSequenceStore;\n stdout(text: string): void;\n stderr(text: string): void;\n readStdin(): Promise<string>;\n}\n\nexport async function runCli(argv: readonly string[], dependencies: CliDependencies): Promise<number> {\n const [command, ...args] = argv;\n if (command !== undefined && command !== '--help' && command !== '-h' && !inheritedSessionId(dependencies.env)) {\n dependencies.stderr('PI_SESSION_ID is required for po-runner commands');\n return 1;\n }\n if (command && args[0] && isSequenceId(args[0])) return sequenceCommand(command, args, dependencies);\n switch (command) {\n case 'list':\n return list(args, dependencies);\n case 'status':\n return status(args, dependencies);\n case 'logs':\n return logs(args, dependencies);\n case 'stop':\n return stop(args, dependencies);\n case 'stop-all':\n return stopAll(args, dependencies);\n case 'input':\n return input(args, dependencies);\n case '--help':\n case '-h':\n case undefined:\n dependencies.stdout(runnerCliHelp());\n return 0;\n default:\n dependencies.stderr(`Unknown command: ${command}\\n\\n${runnerCliHelp()}`);\n return 1;\n }\n}\n\nasync function sequenceCommand(\n command: string,\n args: readonly string[],\n dependencies: CliDependencies,\n): Promise<number> {\n const store = dependencies.sequences;\n if (!store) {\n dependencies.stderr('Sequence controls are unavailable.');\n return 1;\n }\n const record = await store.get(args[0]!);\n if (!record) {\n dependencies.stderr(`No sequence with id ${args[0]}`);\n return 1;\n }\n if (command === 'stop') {\n if (record.state !== 'running') {\n dependencies.stderr(`Sequence ${record.id} is already completed`);\n return 1;\n }\n await store.requestStop(record.id, option(args, '--reason'));\n dependencies.stdout(`Stop requested for sequence ${record.id}`);\n return 0;\n }\n if (command === 'status') {\n dependencies.stdout(\n [\n `ID: ${record.id}`,\n `Name: ${record.name}`,\n `State: ${record.state}`,\n `Session: ${record.sessionId}`,\n ...(record.outcome ? [`Outcome: ${record.outcome}`] : []),\n ...record.stages.map((stage) => `Stage ${stage.index + 1}: ${stage.state}${stage.id ? ` (${stage.id})` : ''}`),\n ].join('\\n'),\n );\n return 0;\n }\n if (command === 'logs') {\n if (args.includes('--follow')) {\n dependencies.stderr('Sequence logs are finite snapshots; inspect status before reading again.');\n return 1;\n }\n if (record.result)\n dependencies.stdout(\n record.result.content.flatMap((part) => (part.type === 'text' ? [part.text] : [])).join('\\n'),\n );\n else\n dependencies.stdout(\n [\n `Sequence ${record.id} is running.`,\n ...record.stages.filter((stage) => stage.logPath).map((stage) => `${stage.index + 1}. ${stage.logPath}`),\n ].join('\\n'),\n );\n return 0;\n }\n dependencies.stderr(\n command === 'input' ? 'Command sequences are noninteractive.' : `Unknown sequence command: ${command}`,\n );\n return 1;\n}\n\nasync function list(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = args.includes('--all')\n ? await dependencies.registry.listAll(sessionId)\n : await dependencies.registry.listBySession(sessionId);\n const sequences = (await dependencies.sequences?.list(args.includes('--all'))) ?? [];\n const rows = [\n ...records.map(formatRecord),\n ...sequences.map((record) => `${record.id} ${record.state} sequence ${record.name}`),\n ];\n dependencies.stdout(rows.length > 0 ? rows.join('\\n') : 'No runners');\n return 0;\n}\n\nasync function status(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n dependencies.stdout(\n [\n `ID: ${record.id}`,\n `Name: ${record.name}`,\n `State: ${record.state}`,\n `Backend: ${record.backend}`,\n ...(record.backendTarget ? [`Backend target: ${record.backendTarget}`] : []),\n `PID: ${record.pid}`,\n `Command: ${record.command}`,\n `CWD: ${record.cwd}`,\n `Session: ${record.sessionId}`,\n `Log: ${record.logPath}`,\n ...(record.exit ? [`Exit: ${formatExit(record)}`] : []),\n ].join('\\n'),\n );\n return 0;\n}\n\nasync function logs(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n const lines = positiveInteger(option(args, '--lines')) ?? DEFAULT_LOG_LINES;\n const result = await dependencies.logReader.read(record.logPath, { lines });\n if (!result.exists) {\n dependencies.stderr(`Runner ${record.id} has not written a log yet`);\n return 1;\n }\n if (result.text) dependencies.stdout(result.text);\n if (!args.includes('--follow')) return 0;\n return follow(record, result.fileSize, dependencies);\n}\n\nasync function stop(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state !== 'running') {\n dependencies.stderr(`Runner ${record.id} is already ${record.state}`);\n return 1;\n }\n const reason = option(args, '--reason');\n if (!(await stopRecord(record, dependencies, reason))) {\n dependencies.stderr(`Could not stop runner ${record.id}`);\n return 1;\n }\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n dependencies.stdout(`Stopped ${record.id}\\nLog: ${record.logPath}`);\n return 0;\n}\n\nasync function stopAll(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = await dependencies.registry.listBySession(sessionId);\n const reason = option(args, '--reason');\n for (const sequence of (await dependencies.sequences?.list()) ?? []) {\n await dependencies.sequences!.requestStop(sequence.id, reason);\n dependencies.stdout(`Stop requested for sequence ${sequence.id}`);\n }\n const stopped: RunnerRecord[] = [];\n for (const record of records) {\n if (!(await stopRecord(record, dependencies, reason))) continue;\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n stopped.push(record);\n }\n dependencies.stdout(\n records.length === 0\n ? `No active runners for session ${sessionId}`\n : `Stopped ${stopped.length} runner(s) for session ${sessionId}: ${stopped.map((record) => record.id).join(', ')}`,\n );\n if (stopped.length !== records.length) {\n dependencies.stderr(`Could not stop ${records.length - stopped.length} runner(s) for session ${sessionId}`);\n return 1;\n }\n return 0;\n}\n\nasync function input(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state === COMPLETED_STATE) {\n dependencies.stderr(`Runner ${record.id} is already completed; use po-runner logs ${record.id}`);\n return 1;\n }\n if (!record.interactive) {\n dependencies.stderr(`Runner ${record.id} was not started with interactive: true`);\n return 1;\n }\n const supplied = option(args, '--text');\n const text = supplied ?? (await dependencies.readStdin());\n const payload = args.includes('--enter') && !text.endsWith('\\n') ? `${text}\\n` : text;\n if (!MULTIPLEXER_BACKENDS.has(record.backend) || !record.backendTarget) {\n dependencies.stderr(`Runner ${record.id} uses the ${record.backend} backend, which does not expose CLI input`);\n return 1;\n }\n if (!(await dependencies.rmuxBackend.input(record.backendTarget, payload))) {\n dependencies.stderr(`Runner ${record.id} is no longer accepting RMUX input`);\n return 1;\n }\n dependencies.stdout(`Sent input to ${record.id}`);\n return 0;\n}\n\nasync function requiredRecord(\n id: string | undefined,\n dependencies: CliDependencies,\n): Promise<RunnerRecord | undefined> {\n if (!id) {\n dependencies.stderr('A runner ID is required');\n return undefined;\n }\n const sessionId = requiredSessionId(dependencies.env);\n const scopedRecord = await dependencies.registry.get(id, sessionId);\n if (!scopedRecord) {\n dependencies.stderr(`No runner with id ${id}`);\n return undefined;\n }\n return scopedRecord;\n}\n\nfunction formatRecord(record: RunnerRecord): string {\n const active = formatRunnerLine(record, Date.now());\n return `${record.id} ${record.state} ${record.backend} ${active}`;\n}\n\nfunction formatExit(record: RunnerRecord): string {\n const exit = record.exit;\n if (!exit) return 'unknown';\n const detail = exit.code !== null ? ` code ${exit.code}` : exit.signal ? ` ${exit.signal}` : '';\n const attribution = exit.terminationReason ? ` [${exit.terminationReason}]` : '';\n const note = exit.stopReason ? ` (${exit.stopReason})` : '';\n return `${exit.reason}${detail}${attribution}${note}`;\n}\n\nfunction option(args: readonly string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nfunction positiveInteger(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nasync function follow(record: RunnerRecord, initialSize: number, dependencies: CliDependencies): Promise<number> {\n let offset = initialSize;\n return new Promise<number>((resolve) => {\n let stopped = false;\n let stateTimer: NodeJS.Timeout;\n let reads = Promise.resolve();\n const drain = async (current: fs.Stats): Promise<void> => {\n if (current.size < offset) offset = 0;\n if (current.size === offset) return;\n const length = current.size - offset;\n const buffer = Buffer.alloc(length);\n const descriptor = await open(record.logPath, 'r');\n try {\n const { bytesRead } = await descriptor.read(buffer, 0, length, offset);\n if (bytesRead > 0) dependencies.stdout(buffer.subarray(0, bytesRead).toString('utf8'));\n offset += bytesRead;\n } finally {\n await descriptor.close();\n }\n };\n const report = (error: unknown): void => {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n dependencies.stderr(`Runner ${record.id} failed to flush its final log output: ${String(error)}`);\n }\n };\n const listener = (current: fs.Stats): void => {\n if (stopped) return;\n reads = reads.then(() => drain(current)).catch(report);\n };\n const stopFollowing = (): void => {\n if (stopped) return;\n stopped = true;\n fs.unwatchFile(record.logPath, listener);\n clearInterval(stateTimer);\n process.off('SIGINT', stopFollowing);\n reads = reads.then(async () => drain(await stat(record.logPath))).catch(report);\n void reads.then(() => resolve(0));\n };\n process.once('SIGINT', stopFollowing);\n fs.watchFile(record.logPath, { interval: FOLLOW_INTERVAL_MS }, listener);\n stateTimer = setInterval(() => {\n void dependencies.registry.get(record.id).then((current) => {\n if (current?.state === COMPLETED_STATE) stopFollowing();\n });\n }, FOLLOW_INTERVAL_MS);\n });\n}\n\nasync function stopRecord(record: RunnerRecord, dependencies: CliDependencies, reason?: string): Promise<boolean> {\n return stopRunnerProcess(record, dependencies.launcher, dependencies.rmuxBackend, {\n registry: dependencies.registry,\n intent: { reason: STOPPED_REASON, terminationReason: 'user_stop', ...(reason ? { stopReason: reason } : {}) },\n });\n}\n\nexport function runnerCliHelp(): string {\n return [\n 'Usage: po-runner <command>',\n '',\n 'Commands:',\n ' list [--all]',\n ' status <id>',\n ' logs <id> [--lines N] [--follow]',\n ' stop <id> [--reason <text>]',\n ' stop-all [--reason <text>]',\n ' input <id> [--text <text>] [--enter]',\n ].join('\\n');\n}\n"],"mappings":";;;;;;AAGA,MAAa,iBAAiB;AAC9B,MAAa,qBAAqB;;;ACelC,MAAM,uCAAuB,IAAI,IAAI,CAAC,QAAQ,MAAM,CAAC;AAcrD,eAAsB,OAAO,MAAyB,cAAgD;CACpG,MAAM,CAAC,SAAS,GAAG,QAAQ;CAC3B,IAAI,YAAY,KAAA,KAAa,YAAY,YAAY,YAAY,QAAQ,CAAC,mBAAmB,aAAa,GAAG,GAAG;EAC9G,aAAa,OAAO,kDAAkD;EACtE,OAAO;CACT;CACA,IAAI,WAAW,KAAK,MAAM,aAAa,KAAK,EAAE,GAAG,OAAO,gBAAgB,SAAS,MAAM,YAAY;CACnG,QAAQ,SAAR;EACE,KAAK,QACH,OAAO,KAAK,MAAM,YAAY;EAChC,KAAK,UACH,OAAO,OAAO,MAAM,YAAY;EAClC,KAAK,QACH,OAAO,KAAK,MAAM,YAAY;EAChC,KAAK,QACH,OAAO,KAAK,MAAM,YAAY;EAChC,KAAK,YACH,OAAO,QAAQ,MAAM,YAAY;EACnC,KAAK,SACH,OAAO,MAAM,MAAM,YAAY;EACjC,KAAK;EACL,KAAK;EACL,KAAK,KAAA;GACH,aAAa,OAAO,cAAc,CAAC;GACnC,OAAO;EACT;GACE,aAAa,OAAO,oBAAoB,QAAQ,MAAM,cAAc,GAAG;GACvE,OAAO;CACX;AACF;AAEA,eAAe,gBACb,SACA,MACA,cACiB;CACjB,MAAM,QAAQ,aAAa;CAC3B,IAAI,CAAC,OAAO;EACV,aAAa,OAAO,oCAAoC;EACxD,OAAO;CACT;CACA,MAAM,SAAS,MAAM,MAAM,IAAI,KAAK,EAAG;CACvC,IAAI,CAAC,QAAQ;EACX,aAAa,OAAO,uBAAuB,KAAK,IAAI;EACpD,OAAO;CACT;CACA,IAAI,YAAY,QAAQ;EACtB,IAAI,OAAO,UAAU,WAAW;GAC9B,aAAa,OAAO,YAAY,OAAO,GAAG,sBAAsB;GAChE,OAAO;EACT;EACA,MAAM,MAAM,YAAY,OAAO,IAAI,OAAO,MAAM,UAAU,CAAC;EAC3D,aAAa,OAAO,+BAA+B,OAAO,IAAI;EAC9D,OAAO;CACT;CACA,IAAI,YAAY,UAAU;EACxB,aAAa,OACX;GACE,OAAO,OAAO;GACd,SAAS,OAAO;GAChB,UAAU,OAAO;GACjB,YAAY,OAAO;GACnB,GAAI,OAAO,UAAU,CAAC,YAAY,OAAO,SAAS,IAAI,CAAC;GACvD,GAAG,OAAO,OAAO,KAAK,UAAU,SAAS,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,GAAG,KAAK,IAAI;EAC/G,CAAC,CAAC,KAAK,IAAI,CACb;EACA,OAAO;CACT;CACA,IAAI,YAAY,QAAQ;EACtB,IAAI,KAAK,SAAS,UAAU,GAAG;GAC7B,aAAa,OAAO,0EAA0E;GAC9F,OAAO;EACT;EACA,IAAI,OAAO,QACT,aAAa,OACX,OAAO,OAAO,QAAQ,SAAS,SAAU,KAAK,SAAS,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAE,CAAC,CAAC,KAAK,IAAI,CAC9F;OAEA,aAAa,OACX,CACE,YAAY,OAAO,GAAG,eACtB,GAAG,OAAO,OAAO,QAAQ,UAAU,MAAM,OAAO,CAAC,CAAC,KAAK,UAAU,GAAG,MAAM,QAAQ,EAAE,IAAI,MAAM,SAAS,CACzG,CAAC,CAAC,KAAK,IAAI,CACb;EACF,OAAO;CACT;CACA,aAAa,OACX,YAAY,UAAU,0CAA0C,6BAA6B,SAC/F;CACA,OAAO;AACT;AAEA,eAAe,KAAK,MAAyB,cAAgD;CAC3F,MAAM,YAAY,kBAAkB,aAAa,GAAG;CACpD,MAAM,UAAU,KAAK,SAAS,OAAO,IACjC,MAAM,aAAa,SAAS,QAAQ,SAAS,IAC7C,MAAM,aAAa,SAAS,cAAc,SAAS;CACvD,MAAM,YAAa,MAAM,aAAa,WAAW,KAAK,KAAK,SAAS,OAAO,CAAC,KAAM,CAAC;CACnF,MAAM,OAAO,CACX,GAAG,QAAQ,IAAI,YAAY,GAC3B,GAAG,UAAU,KAAK,WAAW,GAAG,OAAO,GAAG,IAAI,OAAO,MAAM,cAAc,OAAO,MAAM,CACxF;CACA,aAAa,OAAO,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,YAAY;CACpE,OAAO;AACT;AAEA,eAAe,OAAO,MAAyB,cAAgD;CAC7F,MAAM,SAAS,MAAM,eAAe,KAAK,IAAI,YAAY;CACzD,IAAI,CAAC,QAAQ,OAAO;CACpB,aAAa,OACX;EACE,OAAO,OAAO;EACd,SAAS,OAAO;EAChB,UAAU,OAAO;EACjB,YAAY,OAAO;EACnB,GAAI,OAAO,gBAAgB,CAAC,mBAAmB,OAAO,eAAe,IAAI,CAAC;EAC1E,QAAQ,OAAO;EACf,YAAY,OAAO;EACnB,QAAQ,OAAO;EACf,YAAY,OAAO;EACnB,QAAQ,OAAO;EACf,GAAI,OAAO,OAAO,CAAC,SAAS,WAAW,MAAM,GAAG,IAAI,CAAC;CACvD,CAAC,CAAC,KAAK,IAAI,CACb;CACA,OAAO;AACT;AAEA,eAAe,KAAK,MAAyB,cAAgD;CAC3F,MAAM,SAAS,MAAM,eAAe,KAAK,IAAI,YAAY;CACzD,IAAI,CAAC,QAAQ,OAAO;CACpB,MAAM,QAAQ,gBAAgB,OAAO,MAAM,SAAS,CAAC,KAAA;CACrD,MAAM,SAAS,MAAM,aAAa,UAAU,KAAK,OAAO,SAAS,EAAE,MAAM,CAAC;CAC1E,IAAI,CAAC,OAAO,QAAQ;EAClB,aAAa,OAAO,UAAU,OAAO,GAAG,2BAA2B;EACnE,OAAO;CACT;CACA,IAAI,OAAO,MAAM,aAAa,OAAO,OAAO,IAAI;CAChD,IAAI,CAAC,KAAK,SAAS,UAAU,GAAG,OAAO;CACvC,OAAO,OAAO,QAAQ,OAAO,UAAU,YAAY;AACrD;AAEA,eAAe,KAAK,MAAyB,cAAgD;CAC3F,MAAM,SAAS,MAAM,eAAe,KAAK,IAAI,YAAY;CACzD,IAAI,CAAC,QAAQ,OAAO;CACpB,IAAI,OAAO,UAAU,WAAW;EAC9B,aAAa,OAAO,UAAU,OAAO,GAAG,cAAc,OAAO,OAAO;EACpE,OAAO;CACT;CACA,MAAM,SAAS,OAAO,MAAM,UAAU;CACtC,IAAI,CAAE,MAAM,WAAW,QAAQ,cAAc,MAAM,GAAI;EACrD,aAAa,OAAO,yBAAyB,OAAO,IAAI;EACxD,OAAO;CACT;CACA,MAAM,aAAa,SAAS,SAC1B,OAAO,IACP;EACE,QAAQ;EACR,MAAM;EACN,QAAQ;EACR,GAAI,SAAS,EAAE,YAAY,OAAO,IAAI,CAAC;CACzC,GACA,OAAO,SACT;CACA,aAAa,OAAO,WAAW,OAAO,GAAG,SAAS,OAAO,SAAS;CAClE,OAAO;AACT;AAEA,eAAe,QAAQ,MAAyB,cAAgD;CAC9F,MAAM,YAAY,kBAAkB,aAAa,GAAG;CACpD,MAAM,UAAU,MAAM,aAAa,SAAS,cAAc,SAAS;CACnE,MAAM,SAAS,OAAO,MAAM,UAAU;CACtC,KAAK,MAAM,YAAa,MAAM,aAAa,WAAW,KAAK,KAAM,CAAC,GAAG;EACnE,MAAM,aAAa,UAAW,YAAY,SAAS,IAAI,MAAM;EAC7D,aAAa,OAAO,+BAA+B,SAAS,IAAI;CAClE;CACA,MAAM,UAA0B,CAAC;CACjC,KAAK,MAAM,UAAU,SAAS;EAC5B,IAAI,CAAE,MAAM,WAAW,QAAQ,cAAc,MAAM,GAAI;EACvD,MAAM,aAAa,SAAS,SAC1B,OAAO,IACP;GACE,QAAQ;GACR,MAAM;GACN,QAAQ;GACR,GAAI,SAAS,EAAE,YAAY,OAAO,IAAI,CAAC;EACzC,GACA,OAAO,SACT;EACA,QAAQ,KAAK,MAAM;CACrB;CACA,aAAa,OACX,QAAQ,WAAW,IACf,iCAAiC,cACjC,WAAW,QAAQ,OAAO,yBAAyB,UAAU,IAAI,QAAQ,KAAK,WAAW,OAAO,EAAE,CAAC,CAAC,KAAK,IAAI,GACnH;CACA,IAAI,QAAQ,WAAW,QAAQ,QAAQ;EACrC,aAAa,OAAO,kBAAkB,QAAQ,SAAS,QAAQ,OAAO,yBAAyB,WAAW;EAC1G,OAAO;CACT;CACA,OAAO;AACT;AAEA,eAAe,MAAM,MAAyB,cAAgD;CAC5F,MAAM,SAAS,MAAM,eAAe,KAAK,IAAI,YAAY;CACzD,IAAI,CAAC,QAAQ,OAAO;CACpB,IAAI,OAAO,UAAA,aAA2B;EACpC,aAAa,OAAO,UAAU,OAAO,GAAG,4CAA4C,OAAO,IAAI;EAC/F,OAAO;CACT;CACA,IAAI,CAAC,OAAO,aAAa;EACvB,aAAa,OAAO,UAAU,OAAO,GAAG,wCAAwC;EAChF,OAAO;CACT;CAEA,MAAM,OADW,OAAO,MAAM,QACV,KAAM,MAAM,aAAa,UAAU;CACvD,MAAM,UAAU,KAAK,SAAS,SAAS,KAAK,CAAC,KAAK,SAAS,IAAI,IAAI,GAAG,KAAK,MAAM;CACjF,IAAI,CAAC,qBAAqB,IAAI,OAAO,OAAO,KAAK,CAAC,OAAO,eAAe;EACtE,aAAa,OAAO,UAAU,OAAO,GAAG,YAAY,OAAO,QAAQ,0CAA0C;EAC7G,OAAO;CACT;CACA,IAAI,CAAE,MAAM,aAAa,YAAY,MAAM,OAAO,eAAe,OAAO,GAAI;EAC1E,aAAa,OAAO,UAAU,OAAO,GAAG,mCAAmC;EAC3E,OAAO;CACT;CACA,aAAa,OAAO,iBAAiB,OAAO,IAAI;CAChD,OAAO;AACT;AAEA,eAAe,eACb,IACA,cACmC;CACnC,IAAI,CAAC,IAAI;EACP,aAAa,OAAO,yBAAyB;EAC7C;CACF;CACA,MAAM,YAAY,kBAAkB,aAAa,GAAG;CACpD,MAAM,eAAe,MAAM,aAAa,SAAS,IAAI,IAAI,SAAS;CAClE,IAAI,CAAC,cAAc;EACjB,aAAa,OAAO,qBAAqB,IAAI;EAC7C;CACF;CACA,OAAO;AACT;AAEA,SAAS,aAAa,QAA8B;CAClD,MAAM,SAAS,iBAAiB,QAAQ,KAAK,IAAI,CAAC;CAClD,OAAO,GAAG,OAAO,GAAG,IAAI,OAAO,MAAM,IAAI,OAAO,QAAQ,IAAI;AAC9D;AAEA,SAAS,WAAW,QAA8B;CAChD,MAAM,OAAO,OAAO;CACpB,IAAI,CAAC,MAAM,OAAO;CAClB,MAAM,SAAS,KAAK,SAAS,OAAO,SAAS,KAAK,SAAS,KAAK,SAAS,IAAI,KAAK,WAAW;CAC7F,MAAM,cAAc,KAAK,oBAAoB,KAAK,KAAK,kBAAkB,KAAK;CAC9E,MAAM,OAAO,KAAK,aAAa,KAAK,KAAK,WAAW,KAAK;CACzD,OAAO,GAAG,KAAK,SAAS,SAAS,cAAc;AACjD;AAEA,SAAS,OAAO,MAAyB,MAAkC;CACzE,MAAM,QAAQ,KAAK,QAAQ,IAAI;CAC/B,OAAO,SAAS,IAAI,KAAK,QAAQ,KAAK,KAAA;AACxC;AAEA,SAAS,gBAAgB,OAA+C;CACtE,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,MAAM,SAAS,OAAO,KAAK;CAC3B,OAAO,OAAO,UAAU,MAAM,KAAK,SAAS,IAAI,SAAS,KAAA;AAC3D;AAEA,eAAe,OAAO,QAAsB,aAAqB,cAAgD;CAC/G,IAAI,SAAS;CACb,OAAO,IAAI,SAAiB,YAAY;EACtC,IAAI,UAAU;EACd,IAAI;EACJ,IAAI,QAAQ,QAAQ,QAAQ;EAC5B,MAAM,QAAQ,OAAO,YAAqC;GACxD,IAAI,QAAQ,OAAO,QAAQ,SAAS;GACpC,IAAI,QAAQ,SAAS,QAAQ;GAC7B,MAAM,SAAS,QAAQ,OAAO;GAC9B,MAAM,SAAS,OAAO,MAAM,MAAM;GAClC,MAAM,aAAa,MAAM,KAAK,OAAO,SAAS,GAAG;GACjD,IAAI;IACF,MAAM,EAAE,cAAc,MAAM,WAAW,KAAK,QAAQ,GAAG,QAAQ,MAAM;IACrE,IAAI,YAAY,GAAG,aAAa,OAAO,OAAO,SAAS,GAAG,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC;IACrF,UAAU;GACZ,UAAU;IACR,MAAM,WAAW,MAAM;GACzB;EACF;EACA,MAAM,UAAU,UAAyB;GACvC,IAAK,MAAgC,SAAS,UAC5C,aAAa,OAAO,UAAU,OAAO,GAAG,yCAAyC,OAAO,KAAK,GAAG;EAEpG;EACA,MAAM,YAAY,YAA4B;GAC5C,IAAI,SAAS;GACb,QAAQ,MAAM,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,MAAM,MAAM;EACvD;EACA,MAAM,sBAA4B;GAChC,IAAI,SAAS;GACb,UAAU;GACV,KAAG,YAAY,OAAO,SAAS,QAAQ;GACvC,cAAc,UAAU;GACxB,QAAQ,IAAI,UAAU,aAAa;GACnC,QAAQ,MAAM,KAAK,YAAY,MAAM,MAAM,KAAK,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM;GAC9E,MAAW,WAAW,QAAQ,CAAC,CAAC;EAClC;EACA,QAAQ,KAAK,UAAU,aAAa;EACpC,KAAG,UAAU,OAAO,SAAS,EAAE,UAAA,IAA6B,GAAG,QAAQ;EACvE,aAAa,kBAAkB;GAC7B,aAAkB,SAAS,IAAI,OAAO,EAAE,CAAC,CAAC,MAAM,YAAY;IAC1D,IAAI,SAAS,UAAA,aAA2B,cAAc;GACxD,CAAC;EACH,GAAA,GAAqB;CACvB,CAAC;AACH;AAEA,eAAe,WAAW,QAAsB,cAA+B,QAAmC;CAChH,OAAO,kBAAkB,QAAQ,aAAa,UAAU,aAAa,aAAa;EAChF,UAAU,aAAa;EACvB,QAAQ;GAAE,QAAQ;GAAgB,mBAAmB;GAAa,GAAI,SAAS,EAAE,YAAY,OAAO,IAAI,CAAC;EAAG;CAC9G,CAAC;AACH;AAEA,SAAgB,gBAAwB;CACtC,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;AACb"}
1
+ {"version":3,"file":"cliApp-DPbA8LkI.mjs","names":[],"sources":["../src/constants/cliApp.ts","../src/services/cliApp/index.ts"],"sourcesContent":["export const DEFAULT_LOG_LINES = 200;\nexport const FOLLOW_INTERVAL_MS = 250;\nexport const COMPLETED_STATE = 'completed';\nexport const STOPPED_REASON = 'stopped';\nexport const TERMINATION_SIGNAL = 'SIGTERM';\n","import fs from 'node:fs';\nimport { open, stat } from 'node:fs/promises';\n\nimport {\n COMPLETED_STATE,\n DEFAULT_LOG_LINES,\n FOLLOW_INTERVAL_MS,\n STOPPED_REASON,\n TERMINATION_SIGNAL,\n} from '../../constants/cliApp';\nimport { formatRunnerLine } from '../../services/bashResult';\nimport { inheritedSessionId, requiredSessionId } from '../../services/session';\nimport type { ILauncher } from '../../types/launcher';\nimport type { ILogReader } from '../../types/logReader';\nimport type { IRmuxBackend } from '../../types/rmuxBackend';\nimport type { IRunnerRegistry, RunnerRecord } from '../../types/runnerRegistry';\nimport { stopRunnerProcess } from '../reconcile';\nimport { isSequenceId, type RunnerSequenceStore } from '../runnerSequenceStore';\n\nconst MULTIPLEXER_BACKENDS = new Set(['rmux', 'tmux']);\n\nexport interface CliDependencies {\n registry: IRunnerRegistry;\n launcher: ILauncher;\n rmuxBackend: IRmuxBackend;\n logReader: ILogReader;\n env?: NodeJS.ProcessEnv;\n sequences?: RunnerSequenceStore;\n stdout(text: string): void;\n stderr(text: string): void;\n readStdin(): Promise<string>;\n}\n\nexport async function runCli(argv: readonly string[], dependencies: CliDependencies): Promise<number> {\n const [command, ...args] = argv;\n if (command !== undefined && command !== '--help' && command !== '-h' && !inheritedSessionId(dependencies.env)) {\n dependencies.stderr('PO_SESSION_ID is required for po-runner commands');\n return 1;\n }\n if (command && args[0] && isSequenceId(args[0])) return sequenceCommand(command, args, dependencies);\n switch (command) {\n case 'list':\n return list(args, dependencies);\n case 'status':\n return status(args, dependencies);\n case 'logs':\n return logs(args, dependencies);\n case 'stop':\n return stop(args, dependencies);\n case 'stop-all':\n return stopAll(args, dependencies);\n case 'input':\n return input(args, dependencies);\n case '--help':\n case '-h':\n case undefined:\n dependencies.stdout(runnerCliHelp());\n return 0;\n default:\n dependencies.stderr(`Unknown command: ${command}\\n\\n${runnerCliHelp()}`);\n return 1;\n }\n}\n\nasync function sequenceCommand(\n command: string,\n args: readonly string[],\n dependencies: CliDependencies,\n): Promise<number> {\n const store = dependencies.sequences;\n if (!store) {\n dependencies.stderr('Sequence controls are unavailable.');\n return 1;\n }\n const record = await store.get(args[0]!);\n if (!record) {\n dependencies.stderr(`No sequence with id ${args[0]}`);\n return 1;\n }\n if (command === 'stop') {\n if (record.state !== 'running') {\n dependencies.stderr(`Sequence ${record.id} is already completed`);\n return 1;\n }\n await store.requestStop(record.id, option(args, '--reason'));\n dependencies.stdout(`Stop requested for sequence ${record.id}`);\n return 0;\n }\n if (command === 'status') {\n dependencies.stdout(\n [\n `ID: ${record.id}`,\n `Name: ${record.name}`,\n `State: ${record.state}`,\n `Session: ${record.sessionId}`,\n ...(record.outcome ? [`Outcome: ${record.outcome}`] : []),\n ...record.stages.map((stage) => `Stage ${stage.index + 1}: ${stage.state}${stage.id ? ` (${stage.id})` : ''}`),\n ].join('\\n'),\n );\n return 0;\n }\n if (command === 'logs') {\n if (args.includes('--follow')) {\n dependencies.stderr('Sequence logs are finite snapshots; inspect status before reading again.');\n return 1;\n }\n if (record.result)\n dependencies.stdout(\n record.result.content.flatMap((part) => (part.type === 'text' ? [part.text] : [])).join('\\n'),\n );\n else\n dependencies.stdout(\n [\n `Sequence ${record.id} is running.`,\n ...record.stages.filter((stage) => stage.logPath).map((stage) => `${stage.index + 1}. ${stage.logPath}`),\n ].join('\\n'),\n );\n return 0;\n }\n dependencies.stderr(\n command === 'input' ? 'Command sequences are noninteractive.' : `Unknown sequence command: ${command}`,\n );\n return 1;\n}\n\nasync function list(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = args.includes('--all')\n ? await dependencies.registry.listAll(sessionId)\n : await dependencies.registry.listBySession(sessionId);\n const sequences = (await dependencies.sequences?.list(args.includes('--all'))) ?? [];\n const rows = [\n ...records.map(formatRecord),\n ...sequences.map((record) => `${record.id} ${record.state} sequence ${record.name}`),\n ];\n dependencies.stdout(rows.length > 0 ? rows.join('\\n') : 'No runners');\n return 0;\n}\n\nasync function status(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n dependencies.stdout(\n [\n `ID: ${record.id}`,\n `Name: ${record.name}`,\n `State: ${record.state}`,\n `Backend: ${record.backend}`,\n ...(record.backendTarget ? [`Backend target: ${record.backendTarget}`] : []),\n `PID: ${record.pid}`,\n `Command: ${record.command}`,\n `CWD: ${record.cwd}`,\n `Session: ${record.sessionId}`,\n `Log: ${record.logPath}`,\n ...(record.exit ? [`Exit: ${formatExit(record)}`] : []),\n ].join('\\n'),\n );\n return 0;\n}\n\nasync function logs(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n const lines = positiveInteger(option(args, '--lines')) ?? DEFAULT_LOG_LINES;\n const result = await dependencies.logReader.read(record.logPath, { lines });\n if (!result.exists) {\n dependencies.stderr(`Runner ${record.id} has not written a log yet`);\n return 1;\n }\n if (result.text) dependencies.stdout(result.text);\n if (!args.includes('--follow')) return 0;\n return follow(record, result.fileSize, dependencies);\n}\n\nasync function stop(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state !== 'running') {\n dependencies.stderr(`Runner ${record.id} is already ${record.state}`);\n return 1;\n }\n const reason = option(args, '--reason');\n if (!(await stopRecord(record, dependencies, reason))) {\n dependencies.stderr(`Could not stop runner ${record.id}`);\n return 1;\n }\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n dependencies.stdout(`Stopped ${record.id}\\nLog: ${record.logPath}`);\n return 0;\n}\n\nasync function stopAll(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = await dependencies.registry.listBySession(sessionId);\n const reason = option(args, '--reason');\n for (const sequence of (await dependencies.sequences?.list()) ?? []) {\n await dependencies.sequences!.requestStop(sequence.id, reason);\n dependencies.stdout(`Stop requested for sequence ${sequence.id}`);\n }\n const stopped: RunnerRecord[] = [];\n for (const record of records) {\n if (!(await stopRecord(record, dependencies, reason))) continue;\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n stopped.push(record);\n }\n dependencies.stdout(\n records.length === 0\n ? `No active runners for session ${sessionId}`\n : `Stopped ${stopped.length} runner(s) for session ${sessionId}: ${stopped.map((record) => record.id).join(', ')}`,\n );\n if (stopped.length !== records.length) {\n dependencies.stderr(`Could not stop ${records.length - stopped.length} runner(s) for session ${sessionId}`);\n return 1;\n }\n return 0;\n}\n\nasync function input(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state === COMPLETED_STATE) {\n dependencies.stderr(`Runner ${record.id} is already completed; use po-runner logs ${record.id}`);\n return 1;\n }\n if (!record.interactive) {\n dependencies.stderr(`Runner ${record.id} was not started with interactive: true`);\n return 1;\n }\n const supplied = option(args, '--text');\n const text = supplied ?? (await dependencies.readStdin());\n const payload = args.includes('--enter') && !text.endsWith('\\n') ? `${text}\\n` : text;\n if (!MULTIPLEXER_BACKENDS.has(record.backend) || !record.backendTarget) {\n dependencies.stderr(`Runner ${record.id} uses the ${record.backend} backend, which does not expose CLI input`);\n return 1;\n }\n if (!(await dependencies.rmuxBackend.input(record.backendTarget, payload))) {\n dependencies.stderr(`Runner ${record.id} is no longer accepting RMUX input`);\n return 1;\n }\n dependencies.stdout(`Sent input to ${record.id}`);\n return 0;\n}\n\nasync function requiredRecord(\n id: string | undefined,\n dependencies: CliDependencies,\n): Promise<RunnerRecord | undefined> {\n if (!id) {\n dependencies.stderr('A runner ID is required');\n return undefined;\n }\n const sessionId = requiredSessionId(dependencies.env);\n const scopedRecord = await dependencies.registry.get(id, sessionId);\n if (!scopedRecord) {\n dependencies.stderr(`No runner with id ${id}`);\n return undefined;\n }\n return scopedRecord;\n}\n\nfunction formatRecord(record: RunnerRecord): string {\n const active = formatRunnerLine(record, Date.now());\n return `${record.id} ${record.state} ${record.backend} ${active}`;\n}\n\nfunction formatExit(record: RunnerRecord): string {\n const exit = record.exit;\n if (!exit) return 'unknown';\n const detail = exit.code !== null ? ` code ${exit.code}` : exit.signal ? ` ${exit.signal}` : '';\n const attribution = exit.terminationReason ? ` [${exit.terminationReason}]` : '';\n const note = exit.stopReason ? ` (${exit.stopReason})` : '';\n return `${exit.reason}${detail}${attribution}${note}`;\n}\n\nfunction option(args: readonly string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nfunction positiveInteger(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nasync function follow(record: RunnerRecord, initialSize: number, dependencies: CliDependencies): Promise<number> {\n let offset = initialSize;\n return new Promise<number>((resolve) => {\n let stopped = false;\n let stateTimer: NodeJS.Timeout;\n let reads = Promise.resolve();\n const drain = async (current: fs.Stats): Promise<void> => {\n if (current.size < offset) offset = 0;\n if (current.size === offset) return;\n const length = current.size - offset;\n const buffer = Buffer.alloc(length);\n const descriptor = await open(record.logPath, 'r');\n try {\n const { bytesRead } = await descriptor.read(buffer, 0, length, offset);\n if (bytesRead > 0) dependencies.stdout(buffer.subarray(0, bytesRead).toString('utf8'));\n offset += bytesRead;\n } finally {\n await descriptor.close();\n }\n };\n const report = (error: unknown): void => {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n dependencies.stderr(`Runner ${record.id} failed to flush its final log output: ${String(error)}`);\n }\n };\n const listener = (current: fs.Stats): void => {\n if (stopped) return;\n reads = reads.then(() => drain(current)).catch(report);\n };\n const stopFollowing = (): void => {\n if (stopped) return;\n stopped = true;\n fs.unwatchFile(record.logPath, listener);\n clearInterval(stateTimer);\n process.off('SIGINT', stopFollowing);\n reads = reads.then(async () => drain(await stat(record.logPath))).catch(report);\n void reads.then(() => resolve(0));\n };\n process.once('SIGINT', stopFollowing);\n fs.watchFile(record.logPath, { interval: FOLLOW_INTERVAL_MS }, listener);\n stateTimer = setInterval(() => {\n void dependencies.registry.get(record.id).then((current) => {\n if (current?.state === COMPLETED_STATE) stopFollowing();\n });\n }, FOLLOW_INTERVAL_MS);\n });\n}\n\nasync function stopRecord(record: RunnerRecord, dependencies: CliDependencies, reason?: string): Promise<boolean> {\n return stopRunnerProcess(record, dependencies.launcher, dependencies.rmuxBackend, {\n registry: dependencies.registry,\n intent: { reason: STOPPED_REASON, terminationReason: 'user_stop', ...(reason ? { stopReason: reason } : {}) },\n });\n}\n\nexport function runnerCliHelp(): string {\n return [\n 'Usage: po-runner <command>',\n '',\n 'Commands:',\n ' list [--all]',\n ' status <id>',\n ' logs <id> [--lines N] [--follow]',\n ' stop <id> [--reason <text>]',\n ' stop-all [--reason <text>]',\n ' input <id> [--text <text>] [--enter]',\n ].join('\\n');\n}\n"],"mappings":"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"}
package/dist/cliApp.cjs CHANGED
@@ -1,4 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_cliApp = require("./cliApp-GKcqD6CT.cjs");
2
+ const require_cliApp = require("./cliApp-BYfgP44s.cjs");
3
3
  exports.runCli = require_cliApp.runCli;
4
4
  exports.runnerCliHelp = require_cliApp.runnerCliHelp;
package/dist/cliApp.mjs CHANGED
@@ -1 +1 @@
1
- export { t as runCli, n as runnerCliHelp } from "./cliApp-g7APOwcU.mjs";
1
+ export { t as runCli, n as runnerCliHelp } from "./cliApp-DPbA8LkI.mjs";
@@ -29,6 +29,7 @@ let _agimon_ai_po_core_serverPlugin = require("@agimon-ai/po-core/serverPlugin")
29
29
  require("@agimon-ai/po-core/codemode");
30
30
  require("@agimon-ai/po-core/platform");
31
31
  require("@agimon-ai/po-core/telemetry");
32
+ require("@agimon-ai/po-core/workflow");
32
33
  let typebox = require("typebox");
33
34
  let node_child_process = require("node:child_process");
34
35
  require("@agimon-ai/po-core/packageApi");