@agimon-ai/po-runner 0.0.0-alpha.2 → 0.0.0-alpha.21

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 (238) hide show
  1. package/LICENSE +149 -21
  2. package/README.md +17 -17
  3. package/dist/ansiScrub.mjs +1 -2
  4. package/dist/apiContracts.cjs +1 -1
  5. package/dist/apiContracts.cjs.map +1 -1
  6. package/dist/apiContracts.mjs +1 -1
  7. package/dist/apiContracts.mjs.map +1 -1
  8. package/dist/{bashResult-bIVSzoj-.mjs → bashResult-BqDa7sbC.mjs} +10 -9
  9. package/dist/bashResult-BqDa7sbC.mjs.map +1 -0
  10. package/dist/{bashResult-DNgtahGR.cjs → bashResult-C2iKhHpD.cjs} +10 -9
  11. package/dist/bashResult-C2iKhHpD.cjs.map +1 -0
  12. package/dist/{bashRunService-CJ02XaAq.mjs → bashRunService-Cl3pYccr.mjs} +2 -2
  13. package/dist/bashRunService-Cl3pYccr.mjs.map +1 -0
  14. package/dist/{bashRunService-DyqxOSlx.cjs → bashRunService-DjOH5kye.cjs} +2 -2
  15. package/dist/bashRunService-DjOH5kye.cjs.map +1 -0
  16. package/dist/bashRunService.cjs +1 -1
  17. package/dist/bashRunService.d.mts +3 -3
  18. package/dist/bashRunService.mjs +1 -2
  19. package/dist/bashSchema.cjs +1 -1
  20. package/dist/bashSchema.mjs +1 -2
  21. package/dist/{bashTool-C-k7fmyh.mjs → bashTool-BvC3YOgG.mjs} +2 -2
  22. package/dist/{bashTool-C-k7fmyh.mjs.map → bashTool-BvC3YOgG.mjs.map} +1 -1
  23. package/dist/{bashTool-CdgtqVFD.cjs → bashTool-euL6zMDl.cjs} +2 -2
  24. package/dist/{bashTool-CdgtqVFD.cjs.map → bashTool-euL6zMDl.cjs.map} +1 -1
  25. package/dist/bashTool.cjs +3 -3
  26. package/dist/bashTool.d.mts +1 -1
  27. package/dist/bashTool.mjs +3 -3
  28. package/dist/bin/cli.cjs +6 -6
  29. package/dist/bin/cli.cjs.map +1 -1
  30. package/dist/bin/cli.mjs +7 -7
  31. package/dist/bin/cli.mjs.map +1 -1
  32. package/dist/bin/logSink.cjs +6 -6
  33. package/dist/bin/logSink.cjs.map +1 -1
  34. package/dist/bin/logSink.mjs +7 -7
  35. package/dist/bin/logSink.mjs.map +1 -1
  36. package/dist/bin/runnerHost.cjs +4 -4
  37. package/dist/bin/runnerHost.cjs.map +1 -1
  38. package/dist/bin/runnerHost.mjs +5 -5
  39. package/dist/bin/runnerHost.mjs.map +1 -1
  40. package/dist/{cliApp-Dj9nwaOv.cjs → cliApp-T8Fx_-1j.cjs} +6 -6
  41. package/dist/cliApp-T8Fx_-1j.cjs.map +1 -0
  42. package/dist/{cliApp-v8Z3rMCi.mjs → cliApp-q97eVh4E.mjs} +6 -6
  43. package/dist/cliApp-q97eVh4E.mjs.map +1 -0
  44. package/dist/cliApp.cjs +1 -1
  45. package/dist/cliApp.d.mts +1 -1
  46. package/dist/cliApp.mjs +1 -2
  47. package/dist/clock.mjs +1 -2
  48. package/dist/{compaction-4QSUsBxq.cjs → compaction-Cduebib_.cjs} +3 -3
  49. package/dist/compaction-Cduebib_.cjs.map +1 -0
  50. package/dist/{compaction-DCw80VZj.mjs → compaction-nNlE6e5I.mjs} +3 -3
  51. package/dist/compaction-nNlE6e5I.mjs.map +1 -0
  52. package/dist/compaction.cjs +1 -1
  53. package/dist/compaction.d.mts +1 -1
  54. package/dist/compaction.mjs +1 -2
  55. package/dist/config.cjs +1 -1
  56. package/dist/config.d.mts +1 -1
  57. package/dist/config.mjs +1 -2
  58. package/dist/extensions/mcp-ui.mjs.map +1 -1
  59. package/dist/extensions/mcp.cjs +8 -7
  60. package/dist/extensions/mcp.cjs.map +1 -1
  61. package/dist/extensions/mcp.d.mts +1 -1
  62. package/dist/extensions/mcp.mjs +7 -6
  63. package/dist/extensions/mcp.mjs.map +1 -1
  64. package/dist/extensions/native.mjs +1 -1
  65. package/dist/extensions/native.mjs.map +1 -1
  66. package/dist/extensions/server.cjs +233 -119
  67. package/dist/extensions/server.cjs.map +1 -1
  68. package/dist/extensions/server.d.mts +2 -2
  69. package/dist/extensions/server.d.mts.map +1 -1
  70. package/dist/extensions/server.mjs +233 -119
  71. package/dist/extensions/server.mjs.map +1 -1
  72. package/dist/extensions/web.mjs +88 -62
  73. package/dist/extensions/web.mjs.map +1 -1
  74. package/dist/{headless-BGYfIlNk.mjs → headless-DOlCixyf.mjs} +5 -5
  75. package/dist/headless-DOlCixyf.mjs.map +1 -0
  76. package/dist/{headless-CHUsBGhg.cjs → headless-Dko_yBiy.cjs} +5 -5
  77. package/dist/headless-Dko_yBiy.cjs.map +1 -0
  78. package/dist/{index-Dhi8asLH.d.mts → index--xF7DvsE.d.mts} +4 -4
  79. package/dist/{index-Dhi8asLH.d.mts.map → index--xF7DvsE.d.mts.map} +1 -1
  80. package/dist/{index-BZL7keVW.d.mts → index-BCCF1sGD.d.mts} +2 -2
  81. package/dist/{index-BZL7keVW.d.mts.map → index-BCCF1sGD.d.mts.map} +1 -1
  82. package/dist/{index-BwB_jTI9.d.mts → index-BzeXJk6V.d.mts} +5 -5
  83. package/dist/index-BzeXJk6V.d.mts.map +1 -0
  84. package/dist/{index-D9-IXax4.d.mts → index-C-IC35d9.d.mts} +2 -2
  85. package/dist/{index-D9-IXax4.d.mts.map → index-C-IC35d9.d.mts.map} +1 -1
  86. package/dist/{index-DBz0DxnL.d.mts → index-CzCF_OP9.d.mts} +3 -4
  87. package/dist/index-CzCF_OP9.d.mts.map +1 -0
  88. package/dist/index.cjs +5 -5
  89. package/dist/index.d.mts +5 -5
  90. package/dist/index.mjs +5 -5
  91. package/dist/{launcher-BDm6-DiQ.mjs → launcher-CCYsFBM9.mjs} +3 -3
  92. package/dist/{launcher-BDm6-DiQ.mjs.map → launcher-CCYsFBM9.mjs.map} +1 -1
  93. package/dist/{launcher-SlyE8R3b.cjs → launcher-ZgDdyXpq.cjs} +8 -2
  94. package/dist/{launcher-SlyE8R3b.cjs.map → launcher-ZgDdyXpq.cjs.map} +1 -1
  95. package/dist/launcher.cjs +1 -1
  96. package/dist/launcher.d.mts +1 -1
  97. package/dist/launcher.mjs +1 -2
  98. package/dist/{lifeline-BZaQA0rm.mjs → lifeline-Bm-bHIjS.mjs} +6 -6
  99. package/dist/lifeline-Bm-bHIjS.mjs.map +1 -0
  100. package/dist/{lifeline-BuV_erib.cjs → lifeline-m7laIzIP.cjs} +6 -6
  101. package/dist/lifeline-m7laIzIP.cjs.map +1 -0
  102. package/dist/lifeline.cjs +1 -1
  103. package/dist/lifeline.d.mts +1 -1
  104. package/dist/lifeline.mjs +1 -1
  105. package/dist/{logFile-CNvepZh0.cjs → logFile-CnPKtxPy.cjs} +2 -2
  106. package/dist/{logFile-CNvepZh0.cjs.map → logFile-CnPKtxPy.cjs.map} +1 -1
  107. package/dist/{logFile-KKPbkC-a.mjs → logFile-XcDHBwu1.mjs} +2 -2
  108. package/dist/{logFile-KKPbkC-a.mjs.map → logFile-XcDHBwu1.mjs.map} +1 -1
  109. package/dist/logFile.cjs +1 -1
  110. package/dist/logFile.d.mts +1 -1
  111. package/dist/logFile.mjs +1 -2
  112. package/dist/{logReader-B6J7L7Ua.cjs → logReader-DHCK2BEr.cjs} +4 -4
  113. package/dist/{logReader-B6J7L7Ua.cjs.map → logReader-DHCK2BEr.cjs.map} +1 -1
  114. package/dist/{logReader-UfbDbwQl.mjs → logReader-mq9uVurh.mjs} +4 -4
  115. package/dist/{logReader-UfbDbwQl.mjs.map → logReader-mq9uVurh.mjs.map} +1 -1
  116. package/dist/logReader.cjs +1 -1
  117. package/dist/logReader.mjs +1 -2
  118. package/dist/processControl.mjs +1 -2
  119. package/dist/{ptyHost-DlQtTB8F.mjs → ptyHost-CwbLLr90.mjs} +2 -2
  120. package/dist/{ptyHost-DlQtTB8F.mjs.map → ptyHost-CwbLLr90.mjs.map} +1 -1
  121. package/dist/{ptyHost-MI2Z6WTG.cjs → ptyHost-D35hNmtd.cjs} +2 -2
  122. package/dist/{ptyHost-MI2Z6WTG.cjs.map → ptyHost-D35hNmtd.cjs.map} +1 -1
  123. package/dist/ptyHost.cjs +1 -1
  124. package/dist/ptyHost.mjs +1 -2
  125. package/dist/{ptySpawner-DEi1KOnd.mjs → ptySpawner-C375NJnj.mjs} +2 -2
  126. package/dist/ptySpawner-C375NJnj.mjs.map +1 -0
  127. package/dist/{ptySpawner-ijw0g5_T.cjs → ptySpawner-C39IzbRo.cjs} +2 -2
  128. package/dist/ptySpawner-C39IzbRo.cjs.map +1 -0
  129. package/dist/ptySpawner.cjs +1 -1
  130. package/dist/ptySpawner.d.mts +1 -1
  131. package/dist/ptySpawner.mjs +1 -2
  132. package/dist/{reconcile-DMeNSxwn.mjs → reconcile-5cZ11jSD.cjs} +12 -42
  133. package/dist/reconcile-5cZ11jSD.cjs.map +1 -0
  134. package/dist/{reconcile-BugwYFbV.cjs → reconcile-wNYQJZF-.mjs} +2 -62
  135. package/dist/reconcile-wNYQJZF-.mjs.map +1 -0
  136. package/dist/reconcile.cjs +1 -2
  137. package/dist/reconcile.d.mts +2 -9
  138. package/dist/reconcile.d.mts.map +1 -1
  139. package/dist/reconcile.mjs +1 -2
  140. package/dist/responseEnvelope.cjs +2 -2
  141. package/dist/responseEnvelope.d.mts +3 -3
  142. package/dist/responseEnvelope.mjs +2 -2
  143. package/dist/{rmuxBackend-DlxgqRZ1.cjs → rmuxBackend-Dh0CYVAL.cjs} +5 -5
  144. package/dist/rmuxBackend-Dh0CYVAL.cjs.map +1 -0
  145. package/dist/{rmuxBackend-DfyQwJrc.mjs → rmuxBackend-rjrVTG6K.mjs} +4 -4
  146. package/dist/rmuxBackend-rjrVTG6K.mjs.map +1 -0
  147. package/dist/rmuxBackend.cjs +1 -1
  148. package/dist/rmuxBackend.d.mts +1 -1
  149. package/dist/rmuxBackend.mjs +1 -2
  150. package/dist/{rtkProcessor-Bc4L4o_8.cjs → rtkProcessor-DSGbM-Cm.cjs} +4 -4
  151. package/dist/rtkProcessor-DSGbM-Cm.cjs.map +1 -0
  152. package/dist/{rtkProcessor-B9KPdyzr.mjs → rtkProcessor-Iw9gP5Xp.mjs} +3 -3
  153. package/dist/rtkProcessor-Iw9gP5Xp.mjs.map +1 -0
  154. package/dist/rtkProcessor.cjs +1 -1
  155. package/dist/rtkProcessor.d.mts +1 -1
  156. package/dist/rtkProcessor.mjs +1 -1
  157. package/dist/{runnerConfig-D2tGq5ZM.cjs → runnerConfig-BoLMinlx.cjs} +11 -11
  158. package/dist/runnerConfig-BoLMinlx.cjs.map +1 -0
  159. package/dist/{runnerConfig-BjtulXBI.d.mts → runnerConfig-DuWL6TJx.d.mts} +10 -10
  160. package/dist/{runnerConfig-BjtulXBI.d.mts.map → runnerConfig-DuWL6TJx.d.mts.map} +1 -1
  161. package/dist/{runnerConfig-BQBlVAXn.mjs → runnerConfig-XXMq4VQA.mjs} +11 -11
  162. package/dist/runnerConfig-XXMq4VQA.mjs.map +1 -0
  163. package/dist/{runnerDependencies-DruByBGS.mjs → runnerDependencies-7h_cxOva.mjs} +17 -17
  164. package/dist/runnerDependencies-7h_cxOva.mjs.map +1 -0
  165. package/dist/{runnerDependencies-KMZigIxB.cjs → runnerDependencies-DSun3xO-.cjs} +17 -17
  166. package/dist/runnerDependencies-DSun3xO-.cjs.map +1 -0
  167. package/dist/runnerDependencies.cjs +1 -1
  168. package/dist/runnerDependencies.d.mts +1 -1
  169. package/dist/runnerDependencies.mjs +1 -2
  170. package/dist/runnerNamer.d.mts +1 -1
  171. package/dist/runnerNamer.mjs +1 -2
  172. package/dist/{runnerPaths-BTEuzxw0.cjs → runnerPaths-B41rMOY6.cjs} +20 -38
  173. package/dist/runnerPaths-B41rMOY6.cjs.map +1 -0
  174. package/dist/{runnerPaths-B_dAAeco.mjs → runnerPaths-Dibbvyx_.mjs} +20 -38
  175. package/dist/runnerPaths-Dibbvyx_.mjs.map +1 -0
  176. package/dist/runnerPaths.cjs +1 -1
  177. package/dist/runnerPaths.d.mts +5 -7
  178. package/dist/runnerPaths.d.mts.map +1 -1
  179. package/dist/runnerPaths.mjs +1 -2
  180. package/dist/{runnerRegistry-CeOHEjBv.mjs → runnerRegistry-BgaR5O86.mjs} +12 -11
  181. package/dist/runnerRegistry-BgaR5O86.mjs.map +1 -0
  182. package/dist/{runnerRegistry-CtJiD02R.d.mts → runnerRegistry-V-Ocaf4N.d.mts} +1 -3
  183. package/dist/{runnerRegistry-CtJiD02R.d.mts.map → runnerRegistry-V-Ocaf4N.d.mts.map} +1 -1
  184. package/dist/{runnerRegistry-BmkZTJHi.cjs → runnerRegistry-dQYlMSpQ.cjs} +23 -10
  185. package/dist/runnerRegistry-dQYlMSpQ.cjs.map +1 -0
  186. package/dist/runnerRegistry.cjs +1 -1
  187. package/dist/runnerRegistry.d.mts +2 -2
  188. package/dist/runnerRegistry.mjs +1 -2
  189. package/dist/services/lifeline/client.cjs +2 -2
  190. package/dist/services/lifeline/client.cjs.map +1 -1
  191. package/dist/services/lifeline/client.d.mts +1 -1
  192. package/dist/services/lifeline/client.mjs +2 -2
  193. package/dist/services/lifeline/client.mjs.map +1 -1
  194. package/dist/{session-Chsb_Nh2.mjs → session-BKYnH4R6.mjs} +2 -2
  195. package/dist/{session-Chsb_Nh2.mjs.map → session-BKYnH4R6.mjs.map} +1 -1
  196. package/dist/{session-BC43uEyG.cjs → session-BvqzhXZY.cjs} +2 -2
  197. package/dist/{session-BC43uEyG.cjs.map → session-BvqzhXZY.cjs.map} +1 -1
  198. package/dist/session.cjs +1 -1
  199. package/dist/session.mjs +1 -1
  200. package/dist/spawner.mjs +1 -2
  201. package/dist/{type-C31e1gla.d.mts → type-Do0YxwVQ.d.mts} +4 -4
  202. package/dist/{type-C31e1gla.d.mts.map → type-Do0YxwVQ.d.mts.map} +1 -1
  203. package/dist/{type-BXM03qSw.d.mts → type-DwMZoINK.d.mts} +8 -8
  204. package/dist/{type-BXM03qSw.d.mts.map → type-DwMZoINK.d.mts.map} +1 -1
  205. package/dist/types.d.mts +1 -1
  206. package/package.json +31 -34
  207. package/skills/{doom-runner → po-runner}/SKILL.md +15 -15
  208. package/src/prompts/po-use-runner/SKILL.md +11 -11
  209. package/dist/bashResult-DNgtahGR.cjs.map +0 -1
  210. package/dist/bashResult-bIVSzoj-.mjs.map +0 -1
  211. package/dist/bashRunService-CJ02XaAq.mjs.map +0 -1
  212. package/dist/bashRunService-DyqxOSlx.cjs.map +0 -1
  213. package/dist/cliApp-Dj9nwaOv.cjs.map +0 -1
  214. package/dist/cliApp-v8Z3rMCi.mjs.map +0 -1
  215. package/dist/compaction-4QSUsBxq.cjs.map +0 -1
  216. package/dist/compaction-DCw80VZj.mjs.map +0 -1
  217. package/dist/headless-BGYfIlNk.mjs.map +0 -1
  218. package/dist/headless-CHUsBGhg.cjs.map +0 -1
  219. package/dist/index-BwB_jTI9.d.mts.map +0 -1
  220. package/dist/index-DBz0DxnL.d.mts.map +0 -1
  221. package/dist/lifeline-BZaQA0rm.mjs.map +0 -1
  222. package/dist/lifeline-BuV_erib.cjs.map +0 -1
  223. package/dist/ptySpawner-DEi1KOnd.mjs.map +0 -1
  224. package/dist/ptySpawner-ijw0g5_T.cjs.map +0 -1
  225. package/dist/reconcile-BugwYFbV.cjs.map +0 -1
  226. package/dist/reconcile-DMeNSxwn.mjs.map +0 -1
  227. package/dist/rmuxBackend-DfyQwJrc.mjs.map +0 -1
  228. package/dist/rmuxBackend-DlxgqRZ1.cjs.map +0 -1
  229. package/dist/rtkProcessor-B9KPdyzr.mjs.map +0 -1
  230. package/dist/rtkProcessor-Bc4L4o_8.cjs.map +0 -1
  231. package/dist/runnerConfig-BQBlVAXn.mjs.map +0 -1
  232. package/dist/runnerConfig-D2tGq5ZM.cjs.map +0 -1
  233. package/dist/runnerDependencies-DruByBGS.mjs.map +0 -1
  234. package/dist/runnerDependencies-KMZigIxB.cjs.map +0 -1
  235. package/dist/runnerPaths-BTEuzxw0.cjs.map +0 -1
  236. package/dist/runnerPaths-B_dAAeco.mjs.map +0 -1
  237. package/dist/runnerRegistry-BmkZTJHi.cjs.map +0 -1
  238. package/dist/runnerRegistry-CeOHEjBv.mjs.map +0 -1
@@ -1,7 +1,7 @@
1
- import { t as getBackgroundThresholdMs } from "./runnerConfig-BQBlVAXn.mjs";
2
- import { n as BASH_TOOL_NAME, r as BashParamsSchema, t as BASH_TOOL_LABEL } from "./bashTool-C-k7fmyh.mjs";
3
- import { c as formatRunResult, f as parseResultPragma, m as textResult } from "./bashResult-bIVSzoj-.mjs";
4
- import { r as stopRunnerProcess } from "./reconcile-DMeNSxwn.mjs";
1
+ import { t as getBackgroundThresholdMs } from "./runnerConfig-XXMq4VQA.mjs";
2
+ import { n as BASH_TOOL_NAME, r as BashParamsSchema, t as BASH_TOOL_LABEL } from "./bashTool-BvC3YOgG.mjs";
3
+ import { c as formatRunResult, f as parseResultPragma, m as textResult } from "./bashResult-BqDa7sbC.mjs";
4
+ import { n as stopRunnerProcess } from "./reconcile-wNYQJZF-.mjs";
5
5
  //#region src/constants/headless.ts
6
6
  const MS_PER_SECOND = 1e3;
7
7
  //#endregion
@@ -166,4 +166,4 @@ function createHeadlessRunnersCommand(dependencies) {
166
166
  //#endregion
167
167
  export { createHeadlessRunnersCommand as n, createHeadlessBashTool as t };
168
168
 
169
- //# sourceMappingURL=headless-BGYfIlNk.mjs.map
169
+ //# sourceMappingURL=headless-DOlCixyf.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headless-DOlCixyf.mjs","names":[],"sources":["../src/constants/headless.ts","../src/constants/runners.ts","../src/constants/runnersCommand.ts","../src/services/runnersCommand/index.ts","../src/services/headless/index.ts"],"sourcesContent":["export const MS_PER_SECOND = 1000;\n","export const COMMAND_NAME = 'runners';\nexport const COMMAND_DESCRIPTION =\n 'Open Runner Space: background processes started by bash. `/runners stop <id> [reason]` stops one, `/runners start [name=x] [cwd=y] [interactive=true] -- <command>` starts one.';\nexport const SERVER_COMMAND_DESCRIPTION = 'Start and stop supervised background runners without a terminal UI.';\n","export const RUNNERS_STOP_VERB = 'stop';\nexport const RUNNERS_START_VERB = 'start';\nexport const RUNNERS_COMMAND_SEPARATOR = '--';\nexport const NAME_KEY = 'name';\nexport const CWD_KEY = 'cwd';\nexport const INTERACTIVE_KEY = 'interactive';\n","import {\n CWD_KEY,\n INTERACTIVE_KEY,\n NAME_KEY,\n RUNNERS_COMMAND_SEPARATOR,\n RUNNERS_START_VERB,\n RUNNERS_STOP_VERB,\n} from '../../constants/runnersCommand';\n/** The `/runners` verb that stops one runner without opening Runner Space. */\n/** The `/runners` verb that starts one, for a client that cannot call the bash tool. */\n/**\n * Ends the options and begins the command.\n *\n * A command is arbitrary shell: it may hold `=`, and it may hold flags of its\n * own (`pnpm test -- --watch`). Only the first of these is the separator, so\n * everything the reader typed survives intact after it.\n */\n\nexport interface RunnersStartRequest {\n kind: 'start';\n /** The shell command to run; empty when the reader gave none. */\n command: string;\n cwd?: string;\n name?: string;\n interactive: boolean;\n}\n\nexport type RunnersCommandRequest =\n /** No arguments: open Runner Space. */\n | { kind: 'space' }\n /** `stop <id> [reason]`: stop one runner headlessly; id is empty when it was left out. */\n | { kind: 'stop'; id: string; reason?: string }\n /** `start [key=value ...] -- <command>`: start one headlessly. */\n | RunnersStartRequest;\n\n/** Splits on whitespace but keeps a double-quoted run together, so a path with spaces survives. */\nfunction tokenize(text: string): string[] {\n return text.match(/(?:\"[^\"]*\"|\\S)+/gu) ?? [];\n}\n\nfunction unquote(value: string): string {\n return value.length >= 2 && value.startsWith('\"') && value.endsWith('\"') ? value.slice(1, -1) : value;\n}\n\n/**\n * Parses `start`'s tail: `key=value` pairs up to the separator, then the\n * command verbatim.\n *\n * Without a separator the whole tail is the command, so typing\n * `/runners start pnpm build` does what it looks like. Options are read only\n * when a separator says where they end, which is what keeps a command such as\n * `FOO=bar pnpm test` from being mistaken for one.\n */\nfunction parseStart(tail: string): RunnersStartRequest {\n const tokens = tokenize(tail);\n const separator = tokens.indexOf(RUNNERS_COMMAND_SEPARATOR);\n if (separator === -1) return { kind: 'start', command: tail.trim(), interactive: false };\n\n const request: RunnersStartRequest = {\n kind: 'start',\n // Sliced from the raw text rather than rejoined from tokens: rejoining\n // would collapse the spacing the reader wrote.\n command: tail.slice(tail.indexOf(RUNNERS_COMMAND_SEPARATOR) + RUNNERS_COMMAND_SEPARATOR.length).trim(),\n interactive: false,\n };\n for (const token of tokens.slice(0, separator)) {\n const split = token.indexOf('=');\n if (split <= 0) continue;\n const value = unquote(token.slice(split + 1));\n const key = token.slice(0, split);\n if (key === NAME_KEY && value !== '') request.name = value;\n if (key === CWD_KEY && value !== '') request.cwd = value;\n if (key === INTERACTIVE_KEY) request.interactive = value === 'true';\n }\n return request;\n}\n\n/**\n * Parses `/runners` arguments. Anything other than a known verb opens Runner\n * Space, which is what the bare command has always done.\n */\nexport function parseRunnersCommand(args: string): RunnersCommandRequest {\n const trimmed = args.trim();\n const [verb = '', id = '', ...rest] = trimmed.split(/\\s+/u).filter(Boolean);\n if (verb === RUNNERS_START_VERB) return parseStart(trimmed.slice(verb.length).trim());\n if (verb !== RUNNERS_STOP_VERB) return { kind: 'space' };\n const reason = rest.join(' ').trim();\n return { kind: 'stop', id, ...(reason ? { reason } : {}) };\n}\n","import type {\n PoHeadlessCommand,\n PoHeadlessExecutionContext,\n PoHeadlessTool,\n PoHeadlessToolResult,\n} from '@agimon-ai/po-core/headless';\n\nimport { BASH_TOOL_LABEL, BASH_TOOL_NAME } from '../../constants/bashTool';\nimport { MS_PER_SECOND } from '../../constants/headless';\nimport { COMMAND_NAME, SERVER_COMMAND_DESCRIPTION } from '../../constants/runners';\nimport { type BashParams, BashParamsSchema } from '../../schemas/bashTool';\nimport { formatRunResult, parseResultPragma, textResult } from '../../services/bashResult';\nimport { stopRunnerProcess } from '../../services/reconcile';\nimport { getBackgroundThresholdMs } from '../../services/runnerConfig';\nimport type { RunnerDependencies } from '../../services/runnerDependencies/type';\nimport { parseRunnersCommand } from '../../services/runnersCommand';\nimport { type LogSummarizer } from '../../types/bashResult';\nimport type { IBashRunService } from '../../types/bashRunService';\nimport type { RunnerSettings } from '../../types/runnerSettings';\n\nexport function createHeadlessBashTool(\n bashRunService: IBashRunService,\n summarizeLog?: LogSummarizer,\n settings?: RunnerSettings,\n environment: NodeJS.ProcessEnv = process.env,\n): PoHeadlessTool<typeof BashParamsSchema> {\n return {\n name: BASH_TOOL_NAME,\n label: BASH_TOOL_LABEL,\n description:\n 'Execute one Bash command in the current working directory. Foreground commands return bounded output; commands that outlive the threshold return a supervised runner id and streaming log path.',\n promptSnippet: 'Execute shell commands with bounded foreground output and supervised background runners',\n promptGuidelines: [\n `A command still running after ${Math.round(getBackgroundThresholdMs() / MS_PER_SECOND)} seconds remains active as a background runner with an id and streaming log path.`,\n 'Pass background: true for commands that should remain active, such as dev servers, watchers, and tails.',\n 'Stop background runners when they are no longer needed.',\n ],\n parameters: BashParamsSchema,\n executionMode: 'serial',\n execute: async (\n _toolCallId: string,\n params: BashParams,\n signal: AbortSignal | undefined,\n onUpdate: ((result: PoHeadlessToolResult) => void) | undefined,\n context: PoHeadlessExecutionContext,\n ) => {\n const { command, timeout, background, interactive, name } = params;\n if (signal?.aborted) throw new Error('Operation aborted');\n if (onUpdate)\n onUpdate(\n textResult(\n `Starting ${interactive === true ? 'interactive runner' : background === true ? 'background runner' : 'command'}...`,\n ),\n );\n let onOutput: ((output: string) => void) | undefined;\n if (background !== true && interactive !== true && onUpdate) onOutput = (output) => onUpdate(textResult(output));\n const result = await bashRunService.run({\n command,\n timeoutMs: timeout === undefined ? undefined : timeout * MS_PER_SECOND,\n background,\n interactive,\n name,\n ...(onOutput ? { onOutput } : {}),\n ...(signal ? { signal } : {}),\n cwd: context.cwd,\n sessionId: context.sessionId,\n });\n if (signal?.aborted) throw new Error('Operation aborted');\n return formatRunResult(result, parseResultPragma(command), summarizeLog, settings, environment);\n },\n };\n}\n\nexport function createHeadlessRunnersCommand(dependencies: RunnerDependencies): PoHeadlessCommand {\n return {\n name: COMMAND_NAME,\n description: SERVER_COMMAND_DESCRIPTION,\n async execute(args: string, context: PoHeadlessExecutionContext) {\n const request = parseRunnersCommand(args);\n if (request.kind === 'space') {\n const active = await dependencies.runnerRegistry.listBySession(context.sessionId);\n await context.client.notify({\n body: `${active.length} active runner${active.length === 1 ? '' : 's'}.`,\n level: 'info',\n });\n return;\n }\n if (request.kind === 'start') {\n if (!request.command) throw new Error('Usage: /runners start [name=x] [cwd=y] [interactive=true] -- <command>');\n const result = await dependencies.bashRunService.run({\n command: request.command,\n background: true,\n sessionId: context.sessionId,\n cwd: request.cwd === undefined ? context.cwd : request.cwd,\n ...(request.name ? { name: request.name } : {}),\n ...(request.interactive ? { interactive: true } : {}),\n });\n await context.client.notify({\n body:\n formatRunResult(result, {}, undefined, dependencies.settings, dependencies.environment).content[0]?.text ??\n 'Runner started.',\n level: 'info',\n });\n return;\n }\n if (!request.id) throw new Error('Usage: /runners stop <runner-id> [reason]');\n const record = await dependencies.runnerRegistry.get(request.id, context.sessionId);\n if (!record) {\n await context.client.notify({ body: `No active runner ${request.id} in this session.`, level: 'warning' });\n return;\n }\n const stopped = await stopRunnerProcess(record, dependencies.launcher, dependencies.rmuxBackend, {\n registry: dependencies.runnerRegistry,\n intent: {\n reason: 'stopped',\n terminationReason: 'user_stop',\n ...(request.reason ? { stopReason: request.reason } : {}),\n },\n });\n if (stopped) {\n await dependencies.runnerRegistry.complete(\n request.id,\n {\n reason: 'stopped',\n code: null,\n signal: null,\n ...(request.reason ? { stopReason: request.reason } : {}),\n },\n context.sessionId,\n );\n }\n await context.client.notify({\n body: stopped ? `Stopped runner ${request.id}.` : `Could not stop runner ${request.id}.`,\n level: stopped ? 'info' : 'error',\n });\n },\n };\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- const require_runnerConfig = require("./runnerConfig-D2tGq5ZM.cjs");
2
- const require_bashTool = require("./bashTool-CdgtqVFD.cjs");
3
- const require_bashResult = require("./bashResult-DNgtahGR.cjs");
4
- const require_reconcile = require("./reconcile-BugwYFbV.cjs");
1
+ const require_runnerConfig = require("./runnerConfig-BoLMinlx.cjs");
2
+ const require_bashTool = require("./bashTool-euL6zMDl.cjs");
3
+ const require_bashResult = require("./bashResult-C2iKhHpD.cjs");
4
+ const require_reconcile = require("./reconcile-5cZ11jSD.cjs");
5
5
  //#region src/constants/headless.ts
6
6
  const MS_PER_SECOND = 1e3;
7
7
  //#endregion
@@ -177,4 +177,4 @@ Object.defineProperty(exports, "createHeadlessRunnersCommand", {
177
177
  }
178
178
  });
179
179
 
180
- //# sourceMappingURL=headless-CHUsBGhg.cjs.map
180
+ //# sourceMappingURL=headless-Dko_yBiy.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headless-Dko_yBiy.cjs","names":["BASH_TOOL_NAME","BASH_TOOL_LABEL","getBackgroundThresholdMs","BashParamsSchema","textResult","formatRunResult","parseResultPragma","stopRunnerProcess"],"sources":["../src/constants/headless.ts","../src/constants/runners.ts","../src/constants/runnersCommand.ts","../src/services/runnersCommand/index.ts","../src/services/headless/index.ts"],"sourcesContent":["export const MS_PER_SECOND = 1000;\n","export const COMMAND_NAME = 'runners';\nexport const COMMAND_DESCRIPTION =\n 'Open Runner Space: background processes started by bash. `/runners stop <id> [reason]` stops one, `/runners start [name=x] [cwd=y] [interactive=true] -- <command>` starts one.';\nexport const SERVER_COMMAND_DESCRIPTION = 'Start and stop supervised background runners without a terminal UI.';\n","export const RUNNERS_STOP_VERB = 'stop';\nexport const RUNNERS_START_VERB = 'start';\nexport const RUNNERS_COMMAND_SEPARATOR = '--';\nexport const NAME_KEY = 'name';\nexport const CWD_KEY = 'cwd';\nexport const INTERACTIVE_KEY = 'interactive';\n","import {\n CWD_KEY,\n INTERACTIVE_KEY,\n NAME_KEY,\n RUNNERS_COMMAND_SEPARATOR,\n RUNNERS_START_VERB,\n RUNNERS_STOP_VERB,\n} from '../../constants/runnersCommand';\n/** The `/runners` verb that stops one runner without opening Runner Space. */\n/** The `/runners` verb that starts one, for a client that cannot call the bash tool. */\n/**\n * Ends the options and begins the command.\n *\n * A command is arbitrary shell: it may hold `=`, and it may hold flags of its\n * own (`pnpm test -- --watch`). Only the first of these is the separator, so\n * everything the reader typed survives intact after it.\n */\n\nexport interface RunnersStartRequest {\n kind: 'start';\n /** The shell command to run; empty when the reader gave none. */\n command: string;\n cwd?: string;\n name?: string;\n interactive: boolean;\n}\n\nexport type RunnersCommandRequest =\n /** No arguments: open Runner Space. */\n | { kind: 'space' }\n /** `stop <id> [reason]`: stop one runner headlessly; id is empty when it was left out. */\n | { kind: 'stop'; id: string; reason?: string }\n /** `start [key=value ...] -- <command>`: start one headlessly. */\n | RunnersStartRequest;\n\n/** Splits on whitespace but keeps a double-quoted run together, so a path with spaces survives. */\nfunction tokenize(text: string): string[] {\n return text.match(/(?:\"[^\"]*\"|\\S)+/gu) ?? [];\n}\n\nfunction unquote(value: string): string {\n return value.length >= 2 && value.startsWith('\"') && value.endsWith('\"') ? value.slice(1, -1) : value;\n}\n\n/**\n * Parses `start`'s tail: `key=value` pairs up to the separator, then the\n * command verbatim.\n *\n * Without a separator the whole tail is the command, so typing\n * `/runners start pnpm build` does what it looks like. Options are read only\n * when a separator says where they end, which is what keeps a command such as\n * `FOO=bar pnpm test` from being mistaken for one.\n */\nfunction parseStart(tail: string): RunnersStartRequest {\n const tokens = tokenize(tail);\n const separator = tokens.indexOf(RUNNERS_COMMAND_SEPARATOR);\n if (separator === -1) return { kind: 'start', command: tail.trim(), interactive: false };\n\n const request: RunnersStartRequest = {\n kind: 'start',\n // Sliced from the raw text rather than rejoined from tokens: rejoining\n // would collapse the spacing the reader wrote.\n command: tail.slice(tail.indexOf(RUNNERS_COMMAND_SEPARATOR) + RUNNERS_COMMAND_SEPARATOR.length).trim(),\n interactive: false,\n };\n for (const token of tokens.slice(0, separator)) {\n const split = token.indexOf('=');\n if (split <= 0) continue;\n const value = unquote(token.slice(split + 1));\n const key = token.slice(0, split);\n if (key === NAME_KEY && value !== '') request.name = value;\n if (key === CWD_KEY && value !== '') request.cwd = value;\n if (key === INTERACTIVE_KEY) request.interactive = value === 'true';\n }\n return request;\n}\n\n/**\n * Parses `/runners` arguments. Anything other than a known verb opens Runner\n * Space, which is what the bare command has always done.\n */\nexport function parseRunnersCommand(args: string): RunnersCommandRequest {\n const trimmed = args.trim();\n const [verb = '', id = '', ...rest] = trimmed.split(/\\s+/u).filter(Boolean);\n if (verb === RUNNERS_START_VERB) return parseStart(trimmed.slice(verb.length).trim());\n if (verb !== RUNNERS_STOP_VERB) return { kind: 'space' };\n const reason = rest.join(' ').trim();\n return { kind: 'stop', id, ...(reason ? { reason } : {}) };\n}\n","import type {\n PoHeadlessCommand,\n PoHeadlessExecutionContext,\n PoHeadlessTool,\n PoHeadlessToolResult,\n} from '@agimon-ai/po-core/headless';\n\nimport { BASH_TOOL_LABEL, BASH_TOOL_NAME } from '../../constants/bashTool';\nimport { MS_PER_SECOND } from '../../constants/headless';\nimport { COMMAND_NAME, SERVER_COMMAND_DESCRIPTION } from '../../constants/runners';\nimport { type BashParams, BashParamsSchema } from '../../schemas/bashTool';\nimport { formatRunResult, parseResultPragma, textResult } from '../../services/bashResult';\nimport { stopRunnerProcess } from '../../services/reconcile';\nimport { getBackgroundThresholdMs } from '../../services/runnerConfig';\nimport type { RunnerDependencies } from '../../services/runnerDependencies/type';\nimport { parseRunnersCommand } from '../../services/runnersCommand';\nimport { type LogSummarizer } from '../../types/bashResult';\nimport type { IBashRunService } from '../../types/bashRunService';\nimport type { RunnerSettings } from '../../types/runnerSettings';\n\nexport function createHeadlessBashTool(\n bashRunService: IBashRunService,\n summarizeLog?: LogSummarizer,\n settings?: RunnerSettings,\n environment: NodeJS.ProcessEnv = process.env,\n): PoHeadlessTool<typeof BashParamsSchema> {\n return {\n name: BASH_TOOL_NAME,\n label: BASH_TOOL_LABEL,\n description:\n 'Execute one Bash command in the current working directory. Foreground commands return bounded output; commands that outlive the threshold return a supervised runner id and streaming log path.',\n promptSnippet: 'Execute shell commands with bounded foreground output and supervised background runners',\n promptGuidelines: [\n `A command still running after ${Math.round(getBackgroundThresholdMs() / MS_PER_SECOND)} seconds remains active as a background runner with an id and streaming log path.`,\n 'Pass background: true for commands that should remain active, such as dev servers, watchers, and tails.',\n 'Stop background runners when they are no longer needed.',\n ],\n parameters: BashParamsSchema,\n executionMode: 'serial',\n execute: async (\n _toolCallId: string,\n params: BashParams,\n signal: AbortSignal | undefined,\n onUpdate: ((result: PoHeadlessToolResult) => void) | undefined,\n context: PoHeadlessExecutionContext,\n ) => {\n const { command, timeout, background, interactive, name } = params;\n if (signal?.aborted) throw new Error('Operation aborted');\n if (onUpdate)\n onUpdate(\n textResult(\n `Starting ${interactive === true ? 'interactive runner' : background === true ? 'background runner' : 'command'}...`,\n ),\n );\n let onOutput: ((output: string) => void) | undefined;\n if (background !== true && interactive !== true && onUpdate) onOutput = (output) => onUpdate(textResult(output));\n const result = await bashRunService.run({\n command,\n timeoutMs: timeout === undefined ? undefined : timeout * MS_PER_SECOND,\n background,\n interactive,\n name,\n ...(onOutput ? { onOutput } : {}),\n ...(signal ? { signal } : {}),\n cwd: context.cwd,\n sessionId: context.sessionId,\n });\n if (signal?.aborted) throw new Error('Operation aborted');\n return formatRunResult(result, parseResultPragma(command), summarizeLog, settings, environment);\n },\n };\n}\n\nexport function createHeadlessRunnersCommand(dependencies: RunnerDependencies): PoHeadlessCommand {\n return {\n name: COMMAND_NAME,\n description: SERVER_COMMAND_DESCRIPTION,\n async execute(args: string, context: PoHeadlessExecutionContext) {\n const request = parseRunnersCommand(args);\n if (request.kind === 'space') {\n const active = await dependencies.runnerRegistry.listBySession(context.sessionId);\n await context.client.notify({\n body: `${active.length} active runner${active.length === 1 ? '' : 's'}.`,\n level: 'info',\n });\n return;\n }\n if (request.kind === 'start') {\n if (!request.command) throw new Error('Usage: /runners start [name=x] [cwd=y] [interactive=true] -- <command>');\n const result = await dependencies.bashRunService.run({\n command: request.command,\n background: true,\n sessionId: context.sessionId,\n cwd: request.cwd === undefined ? context.cwd : request.cwd,\n ...(request.name ? { name: request.name } : {}),\n ...(request.interactive ? { interactive: true } : {}),\n });\n await context.client.notify({\n body:\n formatRunResult(result, {}, undefined, dependencies.settings, dependencies.environment).content[0]?.text ??\n 'Runner started.',\n level: 'info',\n });\n return;\n }\n if (!request.id) throw new Error('Usage: /runners stop <runner-id> [reason]');\n const record = await dependencies.runnerRegistry.get(request.id, context.sessionId);\n if (!record) {\n await context.client.notify({ body: `No active runner ${request.id} in this session.`, level: 'warning' });\n return;\n }\n const stopped = await stopRunnerProcess(record, dependencies.launcher, dependencies.rmuxBackend, {\n registry: dependencies.runnerRegistry,\n intent: {\n reason: 'stopped',\n terminationReason: 'user_stop',\n ...(request.reason ? { stopReason: request.reason } : {}),\n },\n });\n if (stopped) {\n await dependencies.runnerRegistry.complete(\n request.id,\n {\n reason: 'stopped',\n code: null,\n signal: null,\n ...(request.reason ? { stopReason: request.reason } : {}),\n },\n context.sessionId,\n );\n }\n await context.client.notify({\n body: stopped ? `Stopped runner ${request.id}.` : `Could not stop runner ${request.id}.`,\n level: stopped ? 'info' : 'error',\n });\n },\n };\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { t as RunnerDependencies } from "./type-C31e1gla.mjs";
2
- import { DoomHostExecutionBudget } from "@agimon-ai/po-core/packageApi";
1
+ import { t as RunnerDependencies } from "./type-Do0YxwVQ.mjs";
2
+ import { PoHostExecutionBudget } from "@agimon-ai/po-core/packageApi";
3
3
  //#region src/services/runnerDependencies/index.d.ts
4
4
  /**
5
5
  * Builds the extension's service graph.
@@ -15,8 +15,8 @@ import { DoomHostExecutionBudget } from "@agimon-ai/po-core/packageApi";
15
15
  declare function createRunnerDependencies(overrides: Partial<RunnerDependencies> & {
16
16
  environment: Readonly<Record<string, string | undefined>>;
17
17
  cwd?: string;
18
- executionBudget?: DoomHostExecutionBudget;
18
+ executionBudget?: PoHostExecutionBudget;
19
19
  }): RunnerDependencies;
20
20
  //#endregion
21
21
  export { createRunnerDependencies as t };
22
- //# sourceMappingURL=index-Dhi8asLH.d.mts.map
22
+ //# sourceMappingURL=index--xF7DvsE.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-Dhi8asLH.d.mts","names":[],"sources":["../src/services/runnerDependencies/index.ts"],"mappings":";;;;;;;;;;;;;;iBA4CgB,yBACd,WAAW,QAAQ;EACjB,aAAa,SAAS;EACtB;EACA,kBAAkB;IAEnB"}
1
+ {"version":3,"file":"index--xF7DvsE.d.mts","names":[],"sources":["../src/services/runnerDependencies/index.ts"],"mappings":";;;;;;;;;;;;;;iBA4CgB,yBACd,WAAW,QAAQ;EACjB,aAAa,SAAS;EACtB;EACA,kBAAkB;IAEnB"}
@@ -11,7 +11,7 @@ declare class RtkProcessor implements IRtkProcessor {
11
11
  * Latched once a binary proves unrunnable on this host.
12
12
  *
13
13
  * A glibc build installed on a musl host satisfies os and cpu, so it
14
- * resolves and then fails to exec. Without this the same doomed spawn is
14
+ * resolves and then fails to exec. Without this the same poed spawn is
15
15
  * paid on every command, and each one is reported as a processing failure
16
16
  * rather than the absence it actually is.
17
17
  */
@@ -28,4 +28,4 @@ declare function classifyRtkFilter(command: string): RtkFilter | undefined;
28
28
  declare function rtkPackageForTarget(platform: string, architecture: string): string | undefined;
29
29
  //#endregion
30
30
  export { classifyRtkFilter as n, rtkPackageForTarget as r, RtkProcessor as t };
31
- //# sourceMappingURL=index-BZL7keVW.d.mts.map
31
+ //# sourceMappingURL=index-BCCF1sGD.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-BZL7keVW.d.mts","names":[],"sources":["../src/services/rtkProcessor/index.ts"],"mappings":";;;KA8EK;cAEQ,wBAAwB;mBAYhB;mBACA;mBACA;mBACA;;;;;;;;;UANX;EAER,YACmB,gBAAe,gBACf,oBACA,MAAK,SAAS,qCACd,WAAW;EAGxB,QAAQ,SAAS,oBAAoB,QAAQ;UA0B3C;;;;;;iBAwGM,kBAAkB,kBAAkB;iBAyDpC,oBAAoB,kBAAkB"}
1
+ {"version":3,"file":"index-BCCF1sGD.d.mts","names":[],"sources":["../src/services/rtkProcessor/index.ts"],"mappings":";;;KA8EK;cAEQ,wBAAwB;mBAYhB;mBACA;mBACA;mBACA;;;;;;;;;UANX;EAER,YACmB,gBAAe,gBACf,oBACA,MAAK,SAAS,qCACd,WAAW;EAGxB,QAAQ,SAAS,oBAAoB,QAAQ;UA0B3C;;;;;;iBAwGM,kBAAkB,kBAAkB;iBAyDpC,oBAAoB,kBAAkB"}
@@ -2,11 +2,11 @@ import { a as IBashRunService } from "./bashRunService-Ci0cGdYO.mjs";
2
2
  import { n as BashParamsSchema } from "./bashTool-B1EwZLo_.mjs";
3
3
  import { r as LogSummarizer } from "./bashResult-DcrRaBLv.mjs";
4
4
  import { t as RunnerSettings } from "./runnerSettings-DiV1lvzx.mjs";
5
- import { t as RunnerDependencies } from "./type-C31e1gla.mjs";
6
- import { DoomHeadlessCommand, DoomHeadlessTool } from "@agimon-ai/po-core/headless";
5
+ import { t as RunnerDependencies } from "./type-Do0YxwVQ.mjs";
6
+ import { PoHeadlessCommand, PoHeadlessTool } from "@agimon-ai/po-core/headless";
7
7
  //#region src/services/headless/index.d.ts
8
- declare function createHeadlessBashTool(bashRunService: IBashRunService, summarizeLog?: LogSummarizer, settings?: RunnerSettings, environment?: NodeJS.ProcessEnv): DoomHeadlessTool<typeof BashParamsSchema>;
9
- declare function createHeadlessRunnersCommand(dependencies: RunnerDependencies): DoomHeadlessCommand;
8
+ declare function createHeadlessBashTool(bashRunService: IBashRunService, summarizeLog?: LogSummarizer, settings?: RunnerSettings, environment?: NodeJS.ProcessEnv): PoHeadlessTool<typeof BashParamsSchema>;
9
+ declare function createHeadlessRunnersCommand(dependencies: RunnerDependencies): PoHeadlessCommand;
10
10
  //#endregion
11
11
  export { createHeadlessRunnersCommand as n, createHeadlessBashTool as t };
12
- //# sourceMappingURL=index-BwB_jTI9.d.mts.map
12
+ //# sourceMappingURL=index-BzeXJk6V.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BzeXJk6V.d.mts","names":[],"sources":["../src/services/headless/index.ts"],"mappings":";;;;;;;iBAoBgB,uBACd,gBAAgB,iBAChB,eAAe,eACf,WAAW,gBACX,cAAa,OAAO,aACnB,sBAAsB;iBAgDT,6BAA6B,cAAc,qBAAqB"}
@@ -3,7 +3,7 @@ import { r as RunHandle } from "./launcher-BG5t9nvG.mjs";
3
3
  import { r as PtyRun } from "./ptyHost-DWWtRrGn.mjs";
4
4
  import { n as RmuxLaunchRequest, t as IRmuxBackend } from "./rmuxBackend-CaEWooWn.mjs";
5
5
  import { t as RunnerSettings } from "./runnerSettings-DiV1lvzx.mjs";
6
- import { t as IRunnerPaths } from "./type-BXM03qSw.mjs";
6
+ import { t as IRunnerPaths } from "./type-DwMZoINK.mjs";
7
7
  //#region src/services/rmuxBackend/index.d.ts
8
8
  declare class RmuxBackend implements IRmuxBackend {
9
9
  private readonly paths;
@@ -40,4 +40,4 @@ declare class RmuxBackend implements IRmuxBackend {
40
40
  declare function rmuxPackageForTarget(platform: string, architecture: string): string | undefined;
41
41
  //#endregion
42
42
  export { rmuxPackageForTarget as n, RmuxBackend as t };
43
- //# sourceMappingURL=index-D9-IXax4.d.mts.map
43
+ //# sourceMappingURL=index-C-IC35d9.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-D9-IXax4.d.mts","names":[],"sources":["../src/services/rmuxBackend/index.ts"],"mappings":";;;;;;;cAoDa,uBAAuB;mBAMf;mBACA;mBACA;UAPX;mBACS;mBACA;EAEjB,YACmB,OAAO,cACP,MAAK,SAAS,qCACd,WAAW;EAGxB,OAAO,SAAS,oBAAoB,QAAQ;EAuF5C,KAAK,gBAAgB,sBAAsB;EA6B3C,MAAM,YAAY,gBAAgB,qBAAqB,QAAQ;EAe/D,MAAM,gBAAgB,eAAe;EAcrC,QAAQ,iBAAiB;EAa/B,IAAI,eAAe;EAInB,YAAY,YAAY,oBAAoB;UAIpC;UAOA;UAKM;UAkBN;UAUA;;;;;;;;;UAYA;UAaM;UA+BN;;iBA4CM,qBAAqB,kBAAkB"}
1
+ {"version":3,"file":"index-C-IC35d9.d.mts","names":[],"sources":["../src/services/rmuxBackend/index.ts"],"mappings":";;;;;;;cAoDa,uBAAuB;mBAMf;mBACA;mBACA;UAPX;mBACS;mBACA;EAEjB,YACmB,OAAO,cACP,MAAK,SAAS,qCACd,WAAW;EAGxB,OAAO,SAAS,oBAAoB,QAAQ;EAuF5C,KAAK,gBAAgB,sBAAsB;EA6B3C,MAAM,YAAY,gBAAgB,qBAAqB,QAAQ;EAe/D,MAAM,gBAAgB,eAAe;EAcrC,QAAQ,iBAAiB;EAa/B,IAAI,eAAe;EAInB,YAAY,YAAY,oBAAoB;UAIpC;UAOA;UAKM;UAkBN;UAUA;;;;;;;;;UAYA;UAaM;UA+BN;;iBA4CM,qBAAqB,kBAAkB"}
@@ -1,6 +1,6 @@
1
- import { a as RunnerTerminationIntent, i as RunnerRecord, n as IRunnerRegistry, r as RegisterRunnerInput, t as CompleteRunnerInput } from "./runnerRegistry-CtJiD02R.mjs";
1
+ import { a as RunnerTerminationIntent, i as RunnerRecord, n as IRunnerRegistry, r as RegisterRunnerInput, t as CompleteRunnerInput } from "./runnerRegistry-V-Ocaf4N.mjs";
2
2
  import { t as IProcessControl } from "./processControl-BAOa3oo_.mjs";
3
- import { t as IRunnerPaths } from "./type-BXM03qSw.mjs";
3
+ import { t as IRunnerPaths } from "./type-DwMZoINK.mjs";
4
4
  import { ProcessRegistryService } from "@agimon-ai/foundation-process-registry";
5
5
  //#region src/services/runnerRegistry/index.d.ts
6
6
  /** The slice of the shared registry service this wrapper depends on. */
@@ -16,7 +16,6 @@ declare class RunnerRegistry implements IRunnerRegistry {
16
16
  constructor(paths: IRunnerPaths, processControl: IProcessControl, registry: ProcessRegistryPort, environment: Readonly<Record<string, string | undefined>>);
17
17
  register(input: RegisterRunnerInput): Promise<RunnerRecord>;
18
18
  list(): Promise<RunnerRecord[]>;
19
- listAcrossRepositories(): Promise<RunnerRecord[]>;
20
19
  listBySession(sessionId: string): Promise<RunnerRecord[]>;
21
20
  listByRootSession(rootSessionId: string): Promise<RunnerRecord[]>;
22
21
  listAll(sessionId?: string): Promise<RunnerRecord[]>;
@@ -36,4 +35,4 @@ declare class RunnerRegistry implements IRunnerRegistry {
36
35
  }
37
36
  //#endregion
38
37
  export { RunnerRegistry as n, createDefaultProcessRegistry as r, ProcessRegistryPort as t };
39
- //# sourceMappingURL=index-DBz0DxnL.d.mts.map
38
+ //# sourceMappingURL=index-CzCF_OP9.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-CzCF_OP9.d.mts","names":[],"sources":["../src/services/runnerRegistry/index.ts"],"mappings":";;;;;;KAoCY,sBAAsB,KAChC;;iBAKc,6BACd,MAAK,SAAS,sCACb;cA+CU,0BAA0B;mBAIlB;mBACA;mBACA;mBACA;mBANF;EAEjB,YACmB,OAAO,cACP,gBAAgB,iBAChB,UAAU,qBACV,aAAa,SAAS;EAGnC,SAAS,OAAO,sBAAsB,QAAQ;EAqD9C,QAAQ,QAAQ;EAShB,cAAc,oBAAoB,QAAQ;EAK1C,kBAAkB,wBAAwB,QAAQ;EAKlD,QAAQ,qBAAqB,QAAQ;EAgBrC,IAAI,YAAY,qBAAqB,QAAQ;EAgB7C,aAAa,aAAa,QAAQ;EASlC,mBACJ,YACA,QAAQ,qCACR,qBACC,QAAQ;EAWL,SAAS,YAAY,SAAS,qBAAqB,qBAAqB,QAAQ;EAiChF,QAAQ,YAAY,qBAAqB;EAiBzC,aAAa;EAQnB,UAAU,sBAAsB;EAUhC;UAKQ;UAUA;UAOA;UAIA;UAIA"}
package/dist/index.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_runnerConfig = require("./runnerConfig-D2tGq5ZM.cjs");
3
- const require_headless = require("./headless-CHUsBGhg.cjs");
4
- const require_rmuxBackend = require("./rmuxBackend-DlxgqRZ1.cjs");
5
- const require_rtkProcessor = require("./rtkProcessor-Bc4L4o_8.cjs");
6
- const require_runnerDependencies = require("./runnerDependencies-KMZigIxB.cjs");
2
+ const require_runnerConfig = require("./runnerConfig-BoLMinlx.cjs");
3
+ const require_headless = require("./headless-Dko_yBiy.cjs");
4
+ const require_rmuxBackend = require("./rmuxBackend-Dh0CYVAL.cjs");
5
+ const require_rtkProcessor = require("./rtkProcessor-DSGbM-Cm.cjs");
6
+ const require_runnerDependencies = require("./runnerDependencies-DSun3xO-.cjs");
7
7
  exports.DEFAULT_BG_THRESHOLD_MS = require_runnerConfig.DEFAULT_BG_THRESHOLD_MS;
8
8
  exports.DEFAULT_LOG_MAX_BYTES = require_runnerConfig.DEFAULT_LOG_MAX_BYTES;
9
9
  exports.DEFAULT_LOG_TTL_MS = require_runnerConfig.DEFAULT_LOG_TTL_MS;
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { n as RmuxLaunchRequest, t as IRmuxBackend } from "./rmuxBackend-CaEWooWn.mjs";
2
- import { n as createHeadlessRunnersCommand, t as createHeadlessBashTool } from "./index-BwB_jTI9.mjs";
3
- import { A as getLogTtlMs, C as getBackgroundThresholdMs, M as getResultMaxBytes, c as DEFAULT_LOG_TTL_MS, k as getLogMaxBytes, n as DEFAULT_BG_THRESHOLD_MS, s as DEFAULT_LOG_MAX_BYTES, u as DEFAULT_RESULT_MAX_BYTES } from "./runnerConfig-BjtulXBI.mjs";
4
- import { t as RmuxBackend } from "./index-D9-IXax4.mjs";
5
- import { r as rtkPackageForTarget } from "./index-BZL7keVW.mjs";
6
- import { t as createRunnerDependencies } from "./index-Dhi8asLH.mjs";
2
+ import { n as createHeadlessRunnersCommand, t as createHeadlessBashTool } from "./index-BzeXJk6V.mjs";
3
+ import { A as getLogTtlMs, C as getBackgroundThresholdMs, M as getResultMaxBytes, c as DEFAULT_LOG_TTL_MS, k as getLogMaxBytes, n as DEFAULT_BG_THRESHOLD_MS, s as DEFAULT_LOG_MAX_BYTES, u as DEFAULT_RESULT_MAX_BYTES } from "./runnerConfig-DuWL6TJx.mjs";
4
+ import { t as RmuxBackend } from "./index-C-IC35d9.mjs";
5
+ import { r as rtkPackageForTarget } from "./index-BCCF1sGD.mjs";
6
+ import { t as createRunnerDependencies } from "./index--xF7DvsE.mjs";
7
7
  export { DEFAULT_BG_THRESHOLD_MS, DEFAULT_LOG_MAX_BYTES, DEFAULT_LOG_TTL_MS, DEFAULT_RESULT_MAX_BYTES, type IRmuxBackend, RmuxBackend, type RmuxLaunchRequest, createHeadlessBashTool, createHeadlessRunnersCommand, createRunnerDependencies, getBackgroundThresholdMs, getLogMaxBytes, getLogTtlMs, getResultMaxBytes, rtkPackageForTarget };
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { D as DEFAULT_RESULT_MAX_BYTES, T as DEFAULT_LOG_TTL_MS, c as getLogTtlMs, s as getLogMaxBytes, t as getBackgroundThresholdMs, u as getResultMaxBytes, w as DEFAULT_LOG_MAX_BYTES, y as DEFAULT_BG_THRESHOLD_MS } from "./runnerConfig-BQBlVAXn.mjs";
2
- import { n as createHeadlessRunnersCommand, t as createHeadlessBashTool } from "./headless-BGYfIlNk.mjs";
3
- import { t as RmuxBackend } from "./rmuxBackend-DfyQwJrc.mjs";
4
- import { r as rtkPackageForTarget } from "./rtkProcessor-B9KPdyzr.mjs";
5
- import { t as createRunnerDependencies } from "./runnerDependencies-DruByBGS.mjs";
1
+ import { D as DEFAULT_RESULT_MAX_BYTES, T as DEFAULT_LOG_TTL_MS, c as getLogTtlMs, s as getLogMaxBytes, t as getBackgroundThresholdMs, u as getResultMaxBytes, w as DEFAULT_LOG_MAX_BYTES, y as DEFAULT_BG_THRESHOLD_MS } from "./runnerConfig-XXMq4VQA.mjs";
2
+ import { n as createHeadlessRunnersCommand, t as createHeadlessBashTool } from "./headless-DOlCixyf.mjs";
3
+ import { t as RmuxBackend } from "./rmuxBackend-rjrVTG6K.mjs";
4
+ import { r as rtkPackageForTarget } from "./rtkProcessor-Iw9gP5Xp.mjs";
5
+ import { t as createRunnerDependencies } from "./runnerDependencies-7h_cxOva.mjs";
6
6
  export { DEFAULT_BG_THRESHOLD_MS, DEFAULT_LOG_MAX_BYTES, DEFAULT_LOG_TTL_MS, DEFAULT_RESULT_MAX_BYTES, RmuxBackend, createHeadlessBashTool, createHeadlessRunnersCommand, createRunnerDependencies, getBackgroundThresholdMs, getLogMaxBytes, getLogTtlMs, getResultMaxBytes, rtkPackageForTarget };
@@ -1,4 +1,4 @@
1
- import { g as noninteractiveEnvironment, u as getResultMaxBytes } from "./runnerConfig-BQBlVAXn.mjs";
1
+ import { g as noninteractiveEnvironment, u as getResultMaxBytes } from "./runnerConfig-XXMq4VQA.mjs";
2
2
  import { t as PI_SESSION_ID_ENV } from "./session-DE2Acesp.mjs";
3
3
  import { NO_TERMINAL_INPUT_ENV, cleanupSupervisorFiles, readExitMetadata, supervisorCommand, supervisorPaths, writeCommandSpec } from "./services/runnerSupervisor/index.mjs";
4
4
  import { LIFELINE_ENV } from "./services/lifeline/client.mjs";
@@ -145,6 +145,6 @@ function defined(env) {
145
145
  return Object.fromEntries(Object.entries(env).filter((entry) => entry[1] !== void 0));
146
146
  }
147
147
  //#endregion
148
- export { Launcher as t };
148
+ export { TERM_GRACE_MS as n, Launcher as t };
149
149
 
150
- //# sourceMappingURL=launcher-BDm6-DiQ.mjs.map
150
+ //# sourceMappingURL=launcher-CCYsFBM9.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"launcher-BDm6-DiQ.mjs","names":[],"sources":["../src/constants/launcher.ts","../src/services/launcher/index.ts"],"sourcesContent":["export const NON_INTERACTIVE_ENV = { FORCE_COLOR: '1', CI: '1' };\nexport const TERM_GRACE_MS = 2_000;\nexport const LIVENESS_POLL_MS = 100;\nexport const MEMORY_BUFFER_FACTOR = 2;\nexport const GATE_MODE = 0o600;\n","import fs from 'node:fs';\n\nimport {\n GATE_MODE,\n LIVENESS_POLL_MS,\n MEMORY_BUFFER_FACTOR,\n NON_INTERACTIVE_ENV,\n TERM_GRACE_MS,\n} from '../../constants/launcher';\nimport { PI_SESSION_ID_ENV } from '../../constants/session';\nimport type { IClock } from '../../types/clock';\nimport type { ILauncher, LaunchRequest, RunHandle } from '../../types/launcher';\nimport type { ILifeline } from '../../types/lifeline';\nimport type { ILogFile } from '../../types/logFile';\nimport type { IProcessControl } from '../../types/processControl';\nimport type { RunnerSettings } from '../../types/runnerSettings';\nimport type { ExitResult, ISpawner } from '../../types/spawner';\nimport { LIFELINE_ENV } from '../lifeline/client';\nimport { getResultMaxBytes, noninteractiveEnvironment } from '../runnerConfig';\nimport type { IRunnerPaths } from '../runnerPaths/type';\nimport {\n cleanupSupervisorFiles,\n NO_TERMINAL_INPUT_ENV,\n readExitMetadata,\n supervisorCommand,\n supervisorPaths,\n writeCommandSpec,\n} from '../runnerSupervisor';\n\n/**\n * Prompts belong on a screen, not in a log file, so `CI` stays set.\n *\n * Colour is kept: the log is replayed into the transcript, and the scrub keeps\n * SGR while still removing the cursor moves that made raw output unreadable.\n */\n/** In-memory output is a multiple of the result ceiling; the log holds the rest. */\n\nexport class Launcher implements ILauncher {\n constructor(\n private readonly spawner: ISpawner,\n private readonly processControl: IProcessControl,\n private readonly logFile: ILogFile,\n private readonly clock: IClock,\n private readonly paths: IRunnerPaths,\n private readonly lifeline?: ILifeline,\n private readonly environment: Readonly<Record<string, string | undefined>> = process.env,\n private readonly settings?: RunnerSettings,\n ) {}\n\n launch(request: LaunchRequest): RunHandle {\n const writer = this.logFile.open(request.id);\n const memoryLimit = getResultMaxBytes(this.environment, this.settings) * MEMORY_BUFFER_FACTOR;\n\n let buffer = '';\n let buffering = true;\n let settled = false;\n let resolveCompletion: (result: ExitResult) => void = () => undefined;\n let rejectCompletion: (error: Error) => void = () => undefined;\n const completion = new Promise<ExitResult>((resolve, reject) => {\n resolveCompletion = resolve;\n rejectCompletion = reject;\n });\n\n this.paths.ensureDirectories(request.sessionId);\n const supervisor = supervisorPaths(this.paths.stateDirectory(request.sessionId), request.id);\n const { [LIFELINE_ENV]: _inheritedLifeline, ...environment } = this.environment;\n const env = {\n ...environment,\n ...NON_INTERACTIVE_ENV,\n ...noninteractiveEnvironment(environment),\n ...NO_TERMINAL_INPUT_ENV,\n [PI_SESSION_ID_ENV]: request.sessionId,\n [LIFELINE_ENV]: this.lifeline?.path(),\n };\n cleanupSupervisorFiles(supervisor);\n writeCommandSpec(supervisor.spec, { command: request.command, cwd: request.cwd, env: defined(env) });\n // Nothing has to be attached before this runner starts, so its gate opens at once.\n fs.writeFileSync(supervisor.gate, '', { mode: GATE_MODE });\n\n const child = this.spawner.spawn({\n // runnerHost supervises the command: it forwards signals and, if the owning\n // pi dies without running its shutdown handler, kills the group itself.\n command: supervisorCommand(supervisor),\n cwd: request.cwd,\n env,\n // Its own process group, so stopping a runner takes the whole tree with it.\n detached: true,\n });\n\n const failLaunch = (error: unknown): void => {\n if (settled) return;\n settled = true;\n writer.close();\n cleanupSupervisorFiles(supervisor);\n try {\n child.kill('SIGTERM');\n } catch (killError) {\n process.emitWarning(`Could not stop runner after log failure: ${String(killError)}`);\n }\n rejectCompletion(error instanceof Error ? error : new Error(String(error)));\n };\n child.onOutput((chunk) => {\n if (settled) return;\n try {\n writer.append(chunk);\n } catch (error) {\n failLaunch(error);\n return;\n }\n if (!buffering) return;\n buffer += chunk;\n if (buffer.length > memoryLimit) buffer = buffer.slice(-memoryLimit);\n });\n\n child.onError(failLaunch);\n\n child.onExit((result) => {\n if (settled) return;\n settled = true;\n writer.close();\n // The supervisor collapses a signalled command into an exit code, so its\n // own sidecar is the only place the original signal survives.\n const outcome = readExitMetadata(supervisor.exit) ?? result;\n cleanupSupervisorFiles(supervisor);\n resolveCompletion(outcome);\n });\n\n // The launcher must never hold the pi process open on a runner's behalf.\n child.unref();\n\n const stop = async (): Promise<boolean> => (child.pid === undefined ? false : this.stop(child.pid));\n\n return {\n id: request.id,\n name: request.name,\n pid: child.pid,\n logPath: writer.path,\n backend: 'native',\n output: () => buffer,\n completion: () => completion,\n detach: () => {\n buffering = false;\n buffer = '';\n },\n stop,\n };\n }\n\n async stop(pid: number): Promise<boolean> {\n if (!this.processControl.isAlive(pid)) return false;\n\n this.processControl.signalGroup(pid, 'SIGTERM');\n const deadline = this.clock.now() + TERM_GRACE_MS;\n while (this.clock.now() < deadline) {\n if (!this.processControl.isAlive(pid)) return true;\n await this.sleep(LIVENESS_POLL_MS);\n }\n\n this.processControl.signalGroup(pid, 'SIGKILL');\n return true;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n this.clock.after(ms, resolve);\n });\n }\n}\n\n/** The spec is JSON, which has no way to carry an unset variable. */\nfunction defined(env: Readonly<Record<string, string | undefined>>): Record<string, string> {\n return Object.fromEntries(Object.entries(env).filter((entry): entry is [string, string] => entry[1] !== undefined));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"launcher-CCYsFBM9.mjs","names":[],"sources":["../src/constants/launcher.ts","../src/services/launcher/index.ts"],"sourcesContent":["export const NON_INTERACTIVE_ENV = { FORCE_COLOR: '1', CI: '1' };\nexport const TERM_GRACE_MS = 2_000;\nexport const LIVENESS_POLL_MS = 100;\nexport const MEMORY_BUFFER_FACTOR = 2;\nexport const GATE_MODE = 0o600;\n","import fs from 'node:fs';\n\nimport {\n GATE_MODE,\n LIVENESS_POLL_MS,\n MEMORY_BUFFER_FACTOR,\n NON_INTERACTIVE_ENV,\n TERM_GRACE_MS,\n} from '../../constants/launcher';\nimport { PI_SESSION_ID_ENV } from '../../constants/session';\nimport type { IClock } from '../../types/clock';\nimport type { ILauncher, LaunchRequest, RunHandle } from '../../types/launcher';\nimport type { ILifeline } from '../../types/lifeline';\nimport type { ILogFile } from '../../types/logFile';\nimport type { IProcessControl } from '../../types/processControl';\nimport type { RunnerSettings } from '../../types/runnerSettings';\nimport type { ExitResult, ISpawner } from '../../types/spawner';\nimport { LIFELINE_ENV } from '../lifeline/client';\nimport { getResultMaxBytes, noninteractiveEnvironment } from '../runnerConfig';\nimport type { IRunnerPaths } from '../runnerPaths/type';\nimport {\n cleanupSupervisorFiles,\n NO_TERMINAL_INPUT_ENV,\n readExitMetadata,\n supervisorCommand,\n supervisorPaths,\n writeCommandSpec,\n} from '../runnerSupervisor';\n\n/**\n * Prompts belong on a screen, not in a log file, so `CI` stays set.\n *\n * Colour is kept: the log is replayed into the transcript, and the scrub keeps\n * SGR while still removing the cursor moves that made raw output unreadable.\n */\n/** In-memory output is a multiple of the result ceiling; the log holds the rest. */\n\nexport class Launcher implements ILauncher {\n constructor(\n private readonly spawner: ISpawner,\n private readonly processControl: IProcessControl,\n private readonly logFile: ILogFile,\n private readonly clock: IClock,\n private readonly paths: IRunnerPaths,\n private readonly lifeline?: ILifeline,\n private readonly environment: Readonly<Record<string, string | undefined>> = process.env,\n private readonly settings?: RunnerSettings,\n ) {}\n\n launch(request: LaunchRequest): RunHandle {\n const writer = this.logFile.open(request.id);\n const memoryLimit = getResultMaxBytes(this.environment, this.settings) * MEMORY_BUFFER_FACTOR;\n\n let buffer = '';\n let buffering = true;\n let settled = false;\n let resolveCompletion: (result: ExitResult) => void = () => undefined;\n let rejectCompletion: (error: Error) => void = () => undefined;\n const completion = new Promise<ExitResult>((resolve, reject) => {\n resolveCompletion = resolve;\n rejectCompletion = reject;\n });\n\n this.paths.ensureDirectories(request.sessionId);\n const supervisor = supervisorPaths(this.paths.stateDirectory(request.sessionId), request.id);\n const { [LIFELINE_ENV]: _inheritedLifeline, ...environment } = this.environment;\n const env = {\n ...environment,\n ...NON_INTERACTIVE_ENV,\n ...noninteractiveEnvironment(environment),\n ...NO_TERMINAL_INPUT_ENV,\n [PI_SESSION_ID_ENV]: request.sessionId,\n [LIFELINE_ENV]: this.lifeline?.path(),\n };\n cleanupSupervisorFiles(supervisor);\n writeCommandSpec(supervisor.spec, { command: request.command, cwd: request.cwd, env: defined(env) });\n // Nothing has to be attached before this runner starts, so its gate opens at once.\n fs.writeFileSync(supervisor.gate, '', { mode: GATE_MODE });\n\n const child = this.spawner.spawn({\n // runnerHost supervises the command: it forwards signals and, if the owning\n // pi dies without running its shutdown handler, kills the group itself.\n command: supervisorCommand(supervisor),\n cwd: request.cwd,\n env,\n // Its own process group, so stopping a runner takes the whole tree with it.\n detached: true,\n });\n\n const failLaunch = (error: unknown): void => {\n if (settled) return;\n settled = true;\n writer.close();\n cleanupSupervisorFiles(supervisor);\n try {\n child.kill('SIGTERM');\n } catch (killError) {\n process.emitWarning(`Could not stop runner after log failure: ${String(killError)}`);\n }\n rejectCompletion(error instanceof Error ? error : new Error(String(error)));\n };\n child.onOutput((chunk) => {\n if (settled) return;\n try {\n writer.append(chunk);\n } catch (error) {\n failLaunch(error);\n return;\n }\n if (!buffering) return;\n buffer += chunk;\n if (buffer.length > memoryLimit) buffer = buffer.slice(-memoryLimit);\n });\n\n child.onError(failLaunch);\n\n child.onExit((result) => {\n if (settled) return;\n settled = true;\n writer.close();\n // The supervisor collapses a signalled command into an exit code, so its\n // own sidecar is the only place the original signal survives.\n const outcome = readExitMetadata(supervisor.exit) ?? result;\n cleanupSupervisorFiles(supervisor);\n resolveCompletion(outcome);\n });\n\n // The launcher must never hold the pi process open on a runner's behalf.\n child.unref();\n\n const stop = async (): Promise<boolean> => (child.pid === undefined ? false : this.stop(child.pid));\n\n return {\n id: request.id,\n name: request.name,\n pid: child.pid,\n logPath: writer.path,\n backend: 'native',\n output: () => buffer,\n completion: () => completion,\n detach: () => {\n buffering = false;\n buffer = '';\n },\n stop,\n };\n }\n\n async stop(pid: number): Promise<boolean> {\n if (!this.processControl.isAlive(pid)) return false;\n\n this.processControl.signalGroup(pid, 'SIGTERM');\n const deadline = this.clock.now() + TERM_GRACE_MS;\n while (this.clock.now() < deadline) {\n if (!this.processControl.isAlive(pid)) return true;\n await this.sleep(LIVENESS_POLL_MS);\n }\n\n this.processControl.signalGroup(pid, 'SIGKILL');\n return true;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n this.clock.after(ms, resolve);\n });\n }\n}\n\n/** The spec is JSON, which has no way to carry an unset variable. */\nfunction defined(env: Readonly<Record<string, string | undefined>>): Record<string, string> {\n return Object.fromEntries(Object.entries(env).filter((entry): entry is [string, string] => entry[1] !== undefined));\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
2
- const require_runnerConfig = require("./runnerConfig-D2tGq5ZM.cjs");
2
+ const require_runnerConfig = require("./runnerConfig-BoLMinlx.cjs");
3
3
  const require_session = require("./session-SfIPtdZO.cjs");
4
4
  const require_services_runnerSupervisor_index = require("./services/runnerSupervisor/index.cjs");
5
5
  const require_services_lifeline_client = require("./services/lifeline/client.cjs");
@@ -153,5 +153,11 @@ Object.defineProperty(exports, "Launcher", {
153
153
  return Launcher;
154
154
  }
155
155
  });
156
+ Object.defineProperty(exports, "TERM_GRACE_MS", {
157
+ enumerable: true,
158
+ get: function() {
159
+ return TERM_GRACE_MS;
160
+ }
161
+ });
156
162
 
157
- //# sourceMappingURL=launcher-SlyE8R3b.cjs.map
163
+ //# sourceMappingURL=launcher-ZgDdyXpq.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"launcher-SlyE8R3b.cjs","names":["getResultMaxBytes","supervisorPaths","LIFELINE_ENV","noninteractiveEnvironment","NO_TERMINAL_INPUT_ENV","PI_SESSION_ID_ENV","supervisorCommand","readExitMetadata"],"sources":["../src/constants/launcher.ts","../src/services/launcher/index.ts"],"sourcesContent":["export const NON_INTERACTIVE_ENV = { FORCE_COLOR: '1', CI: '1' };\nexport const TERM_GRACE_MS = 2_000;\nexport const LIVENESS_POLL_MS = 100;\nexport const MEMORY_BUFFER_FACTOR = 2;\nexport const GATE_MODE = 0o600;\n","import fs from 'node:fs';\n\nimport {\n GATE_MODE,\n LIVENESS_POLL_MS,\n MEMORY_BUFFER_FACTOR,\n NON_INTERACTIVE_ENV,\n TERM_GRACE_MS,\n} from '../../constants/launcher';\nimport { PI_SESSION_ID_ENV } from '../../constants/session';\nimport type { IClock } from '../../types/clock';\nimport type { ILauncher, LaunchRequest, RunHandle } from '../../types/launcher';\nimport type { ILifeline } from '../../types/lifeline';\nimport type { ILogFile } from '../../types/logFile';\nimport type { IProcessControl } from '../../types/processControl';\nimport type { RunnerSettings } from '../../types/runnerSettings';\nimport type { ExitResult, ISpawner } from '../../types/spawner';\nimport { LIFELINE_ENV } from '../lifeline/client';\nimport { getResultMaxBytes, noninteractiveEnvironment } from '../runnerConfig';\nimport type { IRunnerPaths } from '../runnerPaths/type';\nimport {\n cleanupSupervisorFiles,\n NO_TERMINAL_INPUT_ENV,\n readExitMetadata,\n supervisorCommand,\n supervisorPaths,\n writeCommandSpec,\n} from '../runnerSupervisor';\n\n/**\n * Prompts belong on a screen, not in a log file, so `CI` stays set.\n *\n * Colour is kept: the log is replayed into the transcript, and the scrub keeps\n * SGR while still removing the cursor moves that made raw output unreadable.\n */\n/** In-memory output is a multiple of the result ceiling; the log holds the rest. */\n\nexport class Launcher implements ILauncher {\n constructor(\n private readonly spawner: ISpawner,\n private readonly processControl: IProcessControl,\n private readonly logFile: ILogFile,\n private readonly clock: IClock,\n private readonly paths: IRunnerPaths,\n private readonly lifeline?: ILifeline,\n private readonly environment: Readonly<Record<string, string | undefined>> = process.env,\n private readonly settings?: RunnerSettings,\n ) {}\n\n launch(request: LaunchRequest): RunHandle {\n const writer = this.logFile.open(request.id);\n const memoryLimit = getResultMaxBytes(this.environment, this.settings) * MEMORY_BUFFER_FACTOR;\n\n let buffer = '';\n let buffering = true;\n let settled = false;\n let resolveCompletion: (result: ExitResult) => void = () => undefined;\n let rejectCompletion: (error: Error) => void = () => undefined;\n const completion = new Promise<ExitResult>((resolve, reject) => {\n resolveCompletion = resolve;\n rejectCompletion = reject;\n });\n\n this.paths.ensureDirectories(request.sessionId);\n const supervisor = supervisorPaths(this.paths.stateDirectory(request.sessionId), request.id);\n const { [LIFELINE_ENV]: _inheritedLifeline, ...environment } = this.environment;\n const env = {\n ...environment,\n ...NON_INTERACTIVE_ENV,\n ...noninteractiveEnvironment(environment),\n ...NO_TERMINAL_INPUT_ENV,\n [PI_SESSION_ID_ENV]: request.sessionId,\n [LIFELINE_ENV]: this.lifeline?.path(),\n };\n cleanupSupervisorFiles(supervisor);\n writeCommandSpec(supervisor.spec, { command: request.command, cwd: request.cwd, env: defined(env) });\n // Nothing has to be attached before this runner starts, so its gate opens at once.\n fs.writeFileSync(supervisor.gate, '', { mode: GATE_MODE });\n\n const child = this.spawner.spawn({\n // runnerHost supervises the command: it forwards signals and, if the owning\n // pi dies without running its shutdown handler, kills the group itself.\n command: supervisorCommand(supervisor),\n cwd: request.cwd,\n env,\n // Its own process group, so stopping a runner takes the whole tree with it.\n detached: true,\n });\n\n const failLaunch = (error: unknown): void => {\n if (settled) return;\n settled = true;\n writer.close();\n cleanupSupervisorFiles(supervisor);\n try {\n child.kill('SIGTERM');\n } catch (killError) {\n process.emitWarning(`Could not stop runner after log failure: ${String(killError)}`);\n }\n rejectCompletion(error instanceof Error ? error : new Error(String(error)));\n };\n child.onOutput((chunk) => {\n if (settled) return;\n try {\n writer.append(chunk);\n } catch (error) {\n failLaunch(error);\n return;\n }\n if (!buffering) return;\n buffer += chunk;\n if (buffer.length > memoryLimit) buffer = buffer.slice(-memoryLimit);\n });\n\n child.onError(failLaunch);\n\n child.onExit((result) => {\n if (settled) return;\n settled = true;\n writer.close();\n // The supervisor collapses a signalled command into an exit code, so its\n // own sidecar is the only place the original signal survives.\n const outcome = readExitMetadata(supervisor.exit) ?? result;\n cleanupSupervisorFiles(supervisor);\n resolveCompletion(outcome);\n });\n\n // The launcher must never hold the pi process open on a runner's behalf.\n child.unref();\n\n const stop = async (): Promise<boolean> => (child.pid === undefined ? false : this.stop(child.pid));\n\n return {\n id: request.id,\n name: request.name,\n pid: child.pid,\n logPath: writer.path,\n backend: 'native',\n output: () => buffer,\n completion: () => completion,\n detach: () => {\n buffering = false;\n buffer = '';\n },\n stop,\n };\n }\n\n async stop(pid: number): Promise<boolean> {\n if (!this.processControl.isAlive(pid)) return false;\n\n this.processControl.signalGroup(pid, 'SIGTERM');\n const deadline = this.clock.now() + TERM_GRACE_MS;\n while (this.clock.now() < deadline) {\n if (!this.processControl.isAlive(pid)) return true;\n await this.sleep(LIVENESS_POLL_MS);\n }\n\n this.processControl.signalGroup(pid, 'SIGKILL');\n return true;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n this.clock.after(ms, resolve);\n });\n }\n}\n\n/** The spec is JSON, which has no way to carry an unset variable. */\nfunction defined(env: Readonly<Record<string, string | undefined>>): Record<string, string> {\n return Object.fromEntries(Object.entries(env).filter((entry): entry is [string, string] => entry[1] !== undefined));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"launcher-ZgDdyXpq.cjs","names":["getResultMaxBytes","supervisorPaths","LIFELINE_ENV","noninteractiveEnvironment","NO_TERMINAL_INPUT_ENV","PI_SESSION_ID_ENV","supervisorCommand","readExitMetadata"],"sources":["../src/constants/launcher.ts","../src/services/launcher/index.ts"],"sourcesContent":["export const NON_INTERACTIVE_ENV = { FORCE_COLOR: '1', CI: '1' };\nexport const TERM_GRACE_MS = 2_000;\nexport const LIVENESS_POLL_MS = 100;\nexport const MEMORY_BUFFER_FACTOR = 2;\nexport const GATE_MODE = 0o600;\n","import fs from 'node:fs';\n\nimport {\n GATE_MODE,\n LIVENESS_POLL_MS,\n MEMORY_BUFFER_FACTOR,\n NON_INTERACTIVE_ENV,\n TERM_GRACE_MS,\n} from '../../constants/launcher';\nimport { PI_SESSION_ID_ENV } from '../../constants/session';\nimport type { IClock } from '../../types/clock';\nimport type { ILauncher, LaunchRequest, RunHandle } from '../../types/launcher';\nimport type { ILifeline } from '../../types/lifeline';\nimport type { ILogFile } from '../../types/logFile';\nimport type { IProcessControl } from '../../types/processControl';\nimport type { RunnerSettings } from '../../types/runnerSettings';\nimport type { ExitResult, ISpawner } from '../../types/spawner';\nimport { LIFELINE_ENV } from '../lifeline/client';\nimport { getResultMaxBytes, noninteractiveEnvironment } from '../runnerConfig';\nimport type { IRunnerPaths } from '../runnerPaths/type';\nimport {\n cleanupSupervisorFiles,\n NO_TERMINAL_INPUT_ENV,\n readExitMetadata,\n supervisorCommand,\n supervisorPaths,\n writeCommandSpec,\n} from '../runnerSupervisor';\n\n/**\n * Prompts belong on a screen, not in a log file, so `CI` stays set.\n *\n * Colour is kept: the log is replayed into the transcript, and the scrub keeps\n * SGR while still removing the cursor moves that made raw output unreadable.\n */\n/** In-memory output is a multiple of the result ceiling; the log holds the rest. */\n\nexport class Launcher implements ILauncher {\n constructor(\n private readonly spawner: ISpawner,\n private readonly processControl: IProcessControl,\n private readonly logFile: ILogFile,\n private readonly clock: IClock,\n private readonly paths: IRunnerPaths,\n private readonly lifeline?: ILifeline,\n private readonly environment: Readonly<Record<string, string | undefined>> = process.env,\n private readonly settings?: RunnerSettings,\n ) {}\n\n launch(request: LaunchRequest): RunHandle {\n const writer = this.logFile.open(request.id);\n const memoryLimit = getResultMaxBytes(this.environment, this.settings) * MEMORY_BUFFER_FACTOR;\n\n let buffer = '';\n let buffering = true;\n let settled = false;\n let resolveCompletion: (result: ExitResult) => void = () => undefined;\n let rejectCompletion: (error: Error) => void = () => undefined;\n const completion = new Promise<ExitResult>((resolve, reject) => {\n resolveCompletion = resolve;\n rejectCompletion = reject;\n });\n\n this.paths.ensureDirectories(request.sessionId);\n const supervisor = supervisorPaths(this.paths.stateDirectory(request.sessionId), request.id);\n const { [LIFELINE_ENV]: _inheritedLifeline, ...environment } = this.environment;\n const env = {\n ...environment,\n ...NON_INTERACTIVE_ENV,\n ...noninteractiveEnvironment(environment),\n ...NO_TERMINAL_INPUT_ENV,\n [PI_SESSION_ID_ENV]: request.sessionId,\n [LIFELINE_ENV]: this.lifeline?.path(),\n };\n cleanupSupervisorFiles(supervisor);\n writeCommandSpec(supervisor.spec, { command: request.command, cwd: request.cwd, env: defined(env) });\n // Nothing has to be attached before this runner starts, so its gate opens at once.\n fs.writeFileSync(supervisor.gate, '', { mode: GATE_MODE });\n\n const child = this.spawner.spawn({\n // runnerHost supervises the command: it forwards signals and, if the owning\n // pi dies without running its shutdown handler, kills the group itself.\n command: supervisorCommand(supervisor),\n cwd: request.cwd,\n env,\n // Its own process group, so stopping a runner takes the whole tree with it.\n detached: true,\n });\n\n const failLaunch = (error: unknown): void => {\n if (settled) return;\n settled = true;\n writer.close();\n cleanupSupervisorFiles(supervisor);\n try {\n child.kill('SIGTERM');\n } catch (killError) {\n process.emitWarning(`Could not stop runner after log failure: ${String(killError)}`);\n }\n rejectCompletion(error instanceof Error ? error : new Error(String(error)));\n };\n child.onOutput((chunk) => {\n if (settled) return;\n try {\n writer.append(chunk);\n } catch (error) {\n failLaunch(error);\n return;\n }\n if (!buffering) return;\n buffer += chunk;\n if (buffer.length > memoryLimit) buffer = buffer.slice(-memoryLimit);\n });\n\n child.onError(failLaunch);\n\n child.onExit((result) => {\n if (settled) return;\n settled = true;\n writer.close();\n // The supervisor collapses a signalled command into an exit code, so its\n // own sidecar is the only place the original signal survives.\n const outcome = readExitMetadata(supervisor.exit) ?? result;\n cleanupSupervisorFiles(supervisor);\n resolveCompletion(outcome);\n });\n\n // The launcher must never hold the pi process open on a runner's behalf.\n child.unref();\n\n const stop = async (): Promise<boolean> => (child.pid === undefined ? false : this.stop(child.pid));\n\n return {\n id: request.id,\n name: request.name,\n pid: child.pid,\n logPath: writer.path,\n backend: 'native',\n output: () => buffer,\n completion: () => completion,\n detach: () => {\n buffering = false;\n buffer = '';\n },\n stop,\n };\n }\n\n async stop(pid: number): Promise<boolean> {\n if (!this.processControl.isAlive(pid)) return false;\n\n this.processControl.signalGroup(pid, 'SIGTERM');\n const deadline = this.clock.now() + TERM_GRACE_MS;\n while (this.clock.now() < deadline) {\n if (!this.processControl.isAlive(pid)) return true;\n await this.sleep(LIVENESS_POLL_MS);\n }\n\n this.processControl.signalGroup(pid, 'SIGKILL');\n return true;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n this.clock.after(ms, resolve);\n });\n }\n}\n\n/** The spec is JSON, which has no way to carry an unset variable. */\nfunction defined(env: Readonly<Record<string, string | undefined>>): Record<string, string> {\n return Object.fromEntries(Object.entries(env).filter((entry): entry is [string, string] => entry[1] !== undefined));\n}\n"],"mappings":"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"}
package/dist/launcher.cjs CHANGED
@@ -1,3 +1,3 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_launcher = require("./launcher-SlyE8R3b.cjs");
2
+ const require_launcher = require("./launcher-ZgDdyXpq.cjs");
3
3
  exports.Launcher = require_launcher.Launcher;
@@ -5,7 +5,7 @@ import { t as ILifeline } from "./lifeline-eJdZV0nN.mjs";
5
5
  import { t as ILogFile } from "./logFile-C7oQ_v-g.mjs";
6
6
  import { t as IProcessControl } from "./processControl-BAOa3oo_.mjs";
7
7
  import { t as RunnerSettings } from "./runnerSettings-DiV1lvzx.mjs";
8
- import { t as IRunnerPaths } from "./type-BXM03qSw.mjs";
8
+ import { t as IRunnerPaths } from "./type-DwMZoINK.mjs";
9
9
  //#region src/services/launcher/index.d.ts
10
10
  /**
11
11
  * Prompts belong on a screen, not in a log file, so `CI` stays set.
package/dist/launcher.mjs CHANGED
@@ -1,2 +1 @@
1
- import { t as Launcher } from "./launcher-BDm6-DiQ.mjs";
2
- export { Launcher };
1
+ export { t as Launcher } from "./launcher-CCYsFBM9.mjs";
@@ -36,7 +36,7 @@ var NodeLifeline = class {
36
36
  this.target = target;
37
37
  return target;
38
38
  } catch (error) {
39
- process.emitWarning(`Could not arm the doom-runner lifeline: ${String(error)}`);
39
+ process.emitWarning(`Could not arm the po-runner lifeline: ${String(error)}`);
40
40
  return;
41
41
  }
42
42
  }
@@ -50,7 +50,7 @@ var NodeLifeline = class {
50
50
  try {
51
51
  this.server.close();
52
52
  } catch (error) {
53
- process.emitWarning(`Could not close the doom-runner lifeline: ${String(error)}`);
53
+ process.emitWarning(`Could not close the po-runner lifeline: ${String(error)}`);
54
54
  }
55
55
  this.server = void 0;
56
56
  }
@@ -58,7 +58,7 @@ var NodeLifeline = class {
58
58
  try {
59
59
  fs.rmSync(this.target, { force: true });
60
60
  } catch (error) {
61
- process.emitWarning(`Could not remove the doom-runner lifeline: ${String(error)}`);
61
+ process.emitWarning(`Could not remove the po-runner lifeline: ${String(error)}`);
62
62
  }
63
63
  this.target = void 0;
64
64
  }
@@ -68,7 +68,7 @@ var NodeLifeline = class {
68
68
  const preferred = path.join(this.paths.stateDirectory(sessionId), SOCKET_NAME);
69
69
  if (Buffer.byteLength(preferred) <= 100) return preferred;
70
70
  const hash = createHash("sha256").update(preferred).digest("hex").slice(0, 12);
71
- return path.join(os.tmpdir(), `doom-runner-${hash}.sock`);
71
+ return path.join(os.tmpdir(), `po-runner-${hash}.sock`);
72
72
  }
73
73
  };
74
74
  /** Binding must complete before the first runner launches, so arming waits for it. */
@@ -77,7 +77,7 @@ function listen(server, target) {
77
77
  server.once("error", reject);
78
78
  server.listen(target, () => {
79
79
  server.removeListener("error", reject);
80
- server.on("error", (error) => process.emitWarning(`doom-runner lifeline failed: ${error.message}`));
80
+ server.on("error", (error) => process.emitWarning(`po-runner lifeline failed: ${error.message}`));
81
81
  resolve();
82
82
  });
83
83
  });
@@ -85,4 +85,4 @@ function listen(server, target) {
85
85
  //#endregion
86
86
  export { NodeLifeline as t };
87
87
 
88
- //# sourceMappingURL=lifeline-BZaQA0rm.mjs.map
88
+ //# sourceMappingURL=lifeline-Bm-bHIjS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifeline-Bm-bHIjS.mjs","names":[],"sources":["../src/constants/lifeline.ts","../src/services/lifeline/index.ts"],"sourcesContent":["export const SOCKET_NAME = 'lifeline.sock';\nexport const SOCKET_PATH_LIMIT = 100;\nexport const SOCKET_HASH_LENGTH = 12;\nexport const SOCKET_MODE = 0o600;\n","import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport net from 'node:net';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { SOCKET_HASH_LENGTH, SOCKET_MODE, SOCKET_NAME, SOCKET_PATH_LIMIT } from '../../constants/lifeline';\nimport type { ILifeline } from '../../types/lifeline';\nimport type { IRunnerPaths } from '../runnerPaths/type';\n\n/** Unix socket paths are capped at 104 bytes, so a long agent directory falls back to the temp dir. */\n\nexport class NodeLifeline implements ILifeline {\n private server: net.Server | undefined;\n private target: string | undefined;\n /** Closing a server stops it accepting; only the connections carry the death signal. */\n private readonly connections = new Set<net.Socket>();\n\n constructor(private readonly paths: IRunnerPaths) {}\n\n async arm(sessionId: string): Promise<string | undefined> {\n if (this.target) return this.target;\n try {\n this.paths.ensureDirectories(sessionId);\n const target = this.socketPath(sessionId);\n // A socket left behind by a SIGKILLed predecessor refuses connections, never accepts them.\n fs.rmSync(target, { force: true });\n const server = net.createServer((connection) => {\n // Runners need only the close edge, so their liveness and their data are equally irrelevant.\n connection.unref();\n connection.resume();\n this.connections.add(connection);\n connection.on('close', () => this.connections.delete(connection));\n });\n await listen(server, target);\n fs.chmodSync(target, SOCKET_MODE);\n // The lifeline must never be the reason pi stays alive.\n server.unref();\n this.server = server;\n this.target = target;\n return target;\n } catch (error) {\n // Runners stay unwatched rather than unlaunchable, so a session without a\n // lifeline degrades to running them unsupervised instead of failing.\n process.emitWarning(`Could not arm the po-runner lifeline: ${String(error)}`);\n return undefined;\n }\n }\n\n path(): string | undefined {\n return this.target;\n }\n\n dispose(): void {\n // Dropping the connections is what a runner sees, and it is the whole point\n // of disposing: closing the server alone would leave every runner waiting.\n for (const connection of this.connections) connection.destroy();\n this.connections.clear();\n if (this.server) {\n try {\n this.server.close();\n } catch (error) {\n process.emitWarning(`Could not close the po-runner lifeline: ${String(error)}`);\n }\n this.server = undefined;\n }\n if (this.target) {\n try {\n fs.rmSync(this.target, { force: true });\n } catch (error) {\n process.emitWarning(`Could not remove the po-runner lifeline: ${String(error)}`);\n }\n this.target = undefined;\n }\n }\n\n /** Keeps the socket beside the session it belongs to unless that path is too long to bind. */\n private socketPath(sessionId: string): string {\n const preferred = path.join(this.paths.stateDirectory(sessionId), SOCKET_NAME);\n if (Buffer.byteLength(preferred) <= SOCKET_PATH_LIMIT) return preferred;\n const hash = createHash('sha256').update(preferred).digest('hex').slice(0, SOCKET_HASH_LENGTH);\n return path.join(os.tmpdir(), `po-runner-${hash}.sock`);\n }\n}\n\n/** Binding must complete before the first runner launches, so arming waits for it. */\nfunction listen(server: net.Server, target: string): Promise<void> {\n return new Promise((resolve, reject) => {\n server.once('error', reject);\n server.listen(target, () => {\n server.removeListener('error', reject);\n // Later errors would otherwise reach the process as unhandled.\n server.on('error', (error: Error) => process.emitWarning(`po-runner lifeline failed: ${error.message}`));\n resolve();\n });\n });\n}\n"],"mappings":";;;;;;AAAA,MAAa,cAAc;;;;ACY3B,IAAa,eAAb,MAA+C;CAMhB;CAL7B;CACA;;CAEA,8BAA+B,IAAI,IAAgB;CAEnD,YAAY,OAAsC;EAArB,KAAA,QAAA;CAAsB;CAEnD,MAAM,IAAI,WAAgD;EACxD,IAAI,KAAK,QAAQ,OAAO,KAAK;EAC7B,IAAI;GACF,KAAK,MAAM,kBAAkB,SAAS;GACtC,MAAM,SAAS,KAAK,WAAW,SAAS;GAExC,GAAG,OAAO,QAAQ,EAAE,OAAO,KAAK,CAAC;GACjC,MAAM,SAAS,IAAI,cAAc,eAAe;IAE9C,WAAW,MAAM;IACjB,WAAW,OAAO;IAClB,KAAK,YAAY,IAAI,UAAU;IAC/B,WAAW,GAAG,eAAe,KAAK,YAAY,OAAO,UAAU,CAAC;GAClE,CAAC;GACD,MAAM,OAAO,QAAQ,MAAM;GAC3B,GAAG,UAAU,QAAA,GAAmB;GAEhC,OAAO,MAAM;GACb,KAAK,SAAS;GACd,KAAK,SAAS;GACd,OAAO;EACT,SAAS,OAAO;GAGd,QAAQ,YAAY,yCAAyC,OAAO,KAAK,GAAG;GAC5E;EACF;CACF;CAEA,OAA2B;EACzB,OAAO,KAAK;CACd;CAEA,UAAgB;EAGd,KAAK,MAAM,cAAc,KAAK,aAAa,WAAW,QAAQ;EAC9D,KAAK,YAAY,MAAM;EACvB,IAAI,KAAK,QAAQ;GACf,IAAI;IACF,KAAK,OAAO,MAAM;GACpB,SAAS,OAAO;IACd,QAAQ,YAAY,2CAA2C,OAAO,KAAK,GAAG;GAChF;GACA,KAAK,SAAS,KAAA;EAChB;EACA,IAAI,KAAK,QAAQ;GACf,IAAI;IACF,GAAG,OAAO,KAAK,QAAQ,EAAE,OAAO,KAAK,CAAC;GACxC,SAAS,OAAO;IACd,QAAQ,YAAY,4CAA4C,OAAO,KAAK,GAAG;GACjF;GACA,KAAK,SAAS,KAAA;EAChB;CACF;;CAGA,WAAmB,WAA2B;EAC5C,MAAM,YAAY,KAAK,KAAK,KAAK,MAAM,eAAe,SAAS,GAAG,WAAW;EAC7E,IAAI,OAAO,WAAW,SAAS,KAAA,KAAwB,OAAO;EAC9D,MAAM,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAA,EAAqB;EAC7F,OAAO,KAAK,KAAK,GAAG,OAAO,GAAG,aAAa,KAAK,MAAM;CACxD;AACF;;AAGA,SAAS,OAAO,QAAoB,QAA+B;CACjE,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,OAAO,KAAK,SAAS,MAAM;EAC3B,OAAO,OAAO,cAAc;GAC1B,OAAO,eAAe,SAAS,MAAM;GAErC,OAAO,GAAG,UAAU,UAAiB,QAAQ,YAAY,8BAA8B,MAAM,SAAS,CAAC;GACvG,QAAQ;EACV,CAAC;CACH,CAAC;AACH"}
@@ -41,7 +41,7 @@ var NodeLifeline = class {
41
41
  this.target = target;
42
42
  return target;
43
43
  } catch (error) {
44
- process.emitWarning(`Could not arm the doom-runner lifeline: ${String(error)}`);
44
+ process.emitWarning(`Could not arm the po-runner lifeline: ${String(error)}`);
45
45
  return;
46
46
  }
47
47
  }
@@ -55,7 +55,7 @@ var NodeLifeline = class {
55
55
  try {
56
56
  this.server.close();
57
57
  } catch (error) {
58
- process.emitWarning(`Could not close the doom-runner lifeline: ${String(error)}`);
58
+ process.emitWarning(`Could not close the po-runner lifeline: ${String(error)}`);
59
59
  }
60
60
  this.server = void 0;
61
61
  }
@@ -63,7 +63,7 @@ var NodeLifeline = class {
63
63
  try {
64
64
  node_fs.default.rmSync(this.target, { force: true });
65
65
  } catch (error) {
66
- process.emitWarning(`Could not remove the doom-runner lifeline: ${String(error)}`);
66
+ process.emitWarning(`Could not remove the po-runner lifeline: ${String(error)}`);
67
67
  }
68
68
  this.target = void 0;
69
69
  }
@@ -73,7 +73,7 @@ var NodeLifeline = class {
73
73
  const preferred = node_path.default.join(this.paths.stateDirectory(sessionId), SOCKET_NAME);
74
74
  if (Buffer.byteLength(preferred) <= 100) return preferred;
75
75
  const hash = (0, node_crypto.createHash)("sha256").update(preferred).digest("hex").slice(0, 12);
76
- return node_path.default.join(node_os.default.tmpdir(), `doom-runner-${hash}.sock`);
76
+ return node_path.default.join(node_os.default.tmpdir(), `po-runner-${hash}.sock`);
77
77
  }
78
78
  };
79
79
  /** Binding must complete before the first runner launches, so arming waits for it. */
@@ -82,7 +82,7 @@ function listen(server, target) {
82
82
  server.once("error", reject);
83
83
  server.listen(target, () => {
84
84
  server.removeListener("error", reject);
85
- server.on("error", (error) => process.emitWarning(`doom-runner lifeline failed: ${error.message}`));
85
+ server.on("error", (error) => process.emitWarning(`po-runner lifeline failed: ${error.message}`));
86
86
  resolve();
87
87
  });
88
88
  });
@@ -95,4 +95,4 @@ Object.defineProperty(exports, "NodeLifeline", {
95
95
  }
96
96
  });
97
97
 
98
- //# sourceMappingURL=lifeline-BuV_erib.cjs.map
98
+ //# sourceMappingURL=lifeline-m7laIzIP.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifeline-m7laIzIP.cjs","names":["net","path","createHash","os"],"sources":["../src/constants/lifeline.ts","../src/services/lifeline/index.ts"],"sourcesContent":["export const SOCKET_NAME = 'lifeline.sock';\nexport const SOCKET_PATH_LIMIT = 100;\nexport const SOCKET_HASH_LENGTH = 12;\nexport const SOCKET_MODE = 0o600;\n","import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport net from 'node:net';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { SOCKET_HASH_LENGTH, SOCKET_MODE, SOCKET_NAME, SOCKET_PATH_LIMIT } from '../../constants/lifeline';\nimport type { ILifeline } from '../../types/lifeline';\nimport type { IRunnerPaths } from '../runnerPaths/type';\n\n/** Unix socket paths are capped at 104 bytes, so a long agent directory falls back to the temp dir. */\n\nexport class NodeLifeline implements ILifeline {\n private server: net.Server | undefined;\n private target: string | undefined;\n /** Closing a server stops it accepting; only the connections carry the death signal. */\n private readonly connections = new Set<net.Socket>();\n\n constructor(private readonly paths: IRunnerPaths) {}\n\n async arm(sessionId: string): Promise<string | undefined> {\n if (this.target) return this.target;\n try {\n this.paths.ensureDirectories(sessionId);\n const target = this.socketPath(sessionId);\n // A socket left behind by a SIGKILLed predecessor refuses connections, never accepts them.\n fs.rmSync(target, { force: true });\n const server = net.createServer((connection) => {\n // Runners need only the close edge, so their liveness and their data are equally irrelevant.\n connection.unref();\n connection.resume();\n this.connections.add(connection);\n connection.on('close', () => this.connections.delete(connection));\n });\n await listen(server, target);\n fs.chmodSync(target, SOCKET_MODE);\n // The lifeline must never be the reason pi stays alive.\n server.unref();\n this.server = server;\n this.target = target;\n return target;\n } catch (error) {\n // Runners stay unwatched rather than unlaunchable, so a session without a\n // lifeline degrades to running them unsupervised instead of failing.\n process.emitWarning(`Could not arm the po-runner lifeline: ${String(error)}`);\n return undefined;\n }\n }\n\n path(): string | undefined {\n return this.target;\n }\n\n dispose(): void {\n // Dropping the connections is what a runner sees, and it is the whole point\n // of disposing: closing the server alone would leave every runner waiting.\n for (const connection of this.connections) connection.destroy();\n this.connections.clear();\n if (this.server) {\n try {\n this.server.close();\n } catch (error) {\n process.emitWarning(`Could not close the po-runner lifeline: ${String(error)}`);\n }\n this.server = undefined;\n }\n if (this.target) {\n try {\n fs.rmSync(this.target, { force: true });\n } catch (error) {\n process.emitWarning(`Could not remove the po-runner lifeline: ${String(error)}`);\n }\n this.target = undefined;\n }\n }\n\n /** Keeps the socket beside the session it belongs to unless that path is too long to bind. */\n private socketPath(sessionId: string): string {\n const preferred = path.join(this.paths.stateDirectory(sessionId), SOCKET_NAME);\n if (Buffer.byteLength(preferred) <= SOCKET_PATH_LIMIT) return preferred;\n const hash = createHash('sha256').update(preferred).digest('hex').slice(0, SOCKET_HASH_LENGTH);\n return path.join(os.tmpdir(), `po-runner-${hash}.sock`);\n }\n}\n\n/** Binding must complete before the first runner launches, so arming waits for it. */\nfunction listen(server: net.Server, target: string): Promise<void> {\n return new Promise((resolve, reject) => {\n server.once('error', reject);\n server.listen(target, () => {\n server.removeListener('error', reject);\n // Later errors would otherwise reach the process as unhandled.\n server.on('error', (error: Error) => process.emitWarning(`po-runner lifeline failed: ${error.message}`));\n resolve();\n });\n });\n}\n"],"mappings":";;;;;;;;;;;AAAA,MAAa,cAAc;;;;ACY3B,IAAa,eAAb,MAA+C;CAMhB;CAL7B;CACA;;CAEA,8BAA+B,IAAI,IAAgB;CAEnD,YAAY,OAAsC;EAArB,KAAA,QAAA;CAAsB;CAEnD,MAAM,IAAI,WAAgD;EACxD,IAAI,KAAK,QAAQ,OAAO,KAAK;EAC7B,IAAI;GACF,KAAK,MAAM,kBAAkB,SAAS;GACtC,MAAM,SAAS,KAAK,WAAW,SAAS;GAExC,QAAA,QAAG,OAAO,QAAQ,EAAE,OAAO,KAAK,CAAC;GACjC,MAAM,SAASA,SAAAA,QAAI,cAAc,eAAe;IAE9C,WAAW,MAAM;IACjB,WAAW,OAAO;IAClB,KAAK,YAAY,IAAI,UAAU;IAC/B,WAAW,GAAG,eAAe,KAAK,YAAY,OAAO,UAAU,CAAC;GAClE,CAAC;GACD,MAAM,OAAO,QAAQ,MAAM;GAC3B,QAAA,QAAG,UAAU,QAAA,GAAmB;GAEhC,OAAO,MAAM;GACb,KAAK,SAAS;GACd,KAAK,SAAS;GACd,OAAO;EACT,SAAS,OAAO;GAGd,QAAQ,YAAY,yCAAyC,OAAO,KAAK,GAAG;GAC5E;EACF;CACF;CAEA,OAA2B;EACzB,OAAO,KAAK;CACd;CAEA,UAAgB;EAGd,KAAK,MAAM,cAAc,KAAK,aAAa,WAAW,QAAQ;EAC9D,KAAK,YAAY,MAAM;EACvB,IAAI,KAAK,QAAQ;GACf,IAAI;IACF,KAAK,OAAO,MAAM;GACpB,SAAS,OAAO;IACd,QAAQ,YAAY,2CAA2C,OAAO,KAAK,GAAG;GAChF;GACA,KAAK,SAAS,KAAA;EAChB;EACA,IAAI,KAAK,QAAQ;GACf,IAAI;IACF,QAAA,QAAG,OAAO,KAAK,QAAQ,EAAE,OAAO,KAAK,CAAC;GACxC,SAAS,OAAO;IACd,QAAQ,YAAY,4CAA4C,OAAO,KAAK,GAAG;GACjF;GACA,KAAK,SAAS,KAAA;EAChB;CACF;;CAGA,WAAmB,WAA2B;EAC5C,MAAM,YAAYC,UAAAA,QAAK,KAAK,KAAK,MAAM,eAAe,SAAS,GAAG,WAAW;EAC7E,IAAI,OAAO,WAAW,SAAS,KAAA,KAAwB,OAAO;EAC9D,MAAM,QAAA,GAAOC,YAAAA,WAAAA,CAAW,QAAQ,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAA,EAAqB;EAC7F,OAAOD,UAAAA,QAAK,KAAKE,QAAAA,QAAG,OAAO,GAAG,aAAa,KAAK,MAAM;CACxD;AACF;;AAGA,SAAS,OAAO,QAAoB,QAA+B;CACjE,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,OAAO,KAAK,SAAS,MAAM;EAC3B,OAAO,OAAO,cAAc;GAC1B,OAAO,eAAe,SAAS,MAAM;GAErC,OAAO,GAAG,UAAU,UAAiB,QAAQ,YAAY,8BAA8B,MAAM,SAAS,CAAC;GACvG,QAAQ;EACV,CAAC;CACH,CAAC;AACH"}
package/dist/lifeline.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_services_lifeline_client = require("./services/lifeline/client.cjs");
3
- const require_lifeline = require("./lifeline-BuV_erib.cjs");
3
+ const require_lifeline = require("./lifeline-m7laIzIP.cjs");
4
4
  exports.LIFELINE_ENV = require_services_lifeline_client.LIFELINE_ENV;
5
5
  exports.NodeLifeline = require_lifeline.NodeLifeline;
6
6
  exports.watchOwner = require_services_lifeline_client.watchOwner;
@@ -1,5 +1,5 @@
1
1
  import { t as ILifeline } from "./lifeline-eJdZV0nN.mjs";
2
- import { t as IRunnerPaths } from "./type-BXM03qSw.mjs";
2
+ import { t as IRunnerPaths } from "./type-DwMZoINK.mjs";
3
3
  import { LIFELINE_ENV, watchOwner } from "./services/lifeline/client.mjs";
4
4
  //#region src/services/lifeline/index.d.ts
5
5
  /** Unix socket paths are capped at 104 bytes, so a long agent directory falls back to the temp dir. */
package/dist/lifeline.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  import { LIFELINE_ENV, watchOwner } from "./services/lifeline/client.mjs";
2
- import { t as NodeLifeline } from "./lifeline-BZaQA0rm.mjs";
2
+ import { t as NodeLifeline } from "./lifeline-Bm-bHIjS.mjs";
3
3
  export { LIFELINE_ENV, NodeLifeline, watchOwner };