@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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile-5cZ11jSD.cjs","names":[],"sources":["../src/constants/reconcile.ts","../src/services/reconcile/index.ts"],"sourcesContent":["export const COMPLETED_STATE = 'completed';\n","import { COMPLETED_STATE } from '../../constants/reconcile';\nimport type { ILauncher } from '../../types/launcher';\nimport type { IProcessControl } from '../../types/processControl';\nimport type { IRmuxBackend } from '../../types/rmuxBackend';\nimport type { IRunnerRegistry, RunnerRecord, RunnerTerminationIntent } from '../../types/runnerRegistry';\n\nconst MULTIPLEXER_BACKENDS = new Set(['rmux', 'tmux']);\n\ninterface ReconcileDependencies {\n registry: IRunnerRegistry;\n launcher: ILauncher;\n rmuxBackend: IRmuxBackend;\n processControl: IProcessControl;\n currentHostPid: number;\n startup: boolean;\n /** Same-host restart cleanup belongs only to this session. */\n startupSessionId?: string;\n active?: readonly RunnerRecord[];\n}\n\nexport interface RunnerReconcileResult {\n reclaimed: string[];\n errors: string[];\n}\n\nexport async function stopRunnerProcess(\n record: RunnerRecord,\n launcher: ILauncher,\n rmuxBackend: IRmuxBackend,\n termination?: { registry: IRunnerRegistry; intent: RunnerTerminationIntent },\n): Promise<boolean> {\n if (termination) await termination.registry.requestTermination(record.id, termination.intent, record.sessionId);\n const stopped =\n (MULTIPLEXER_BACKENDS.has(record.backend) && record.backendTarget\n ? await rmuxBackend.stop(record.backendTarget, record.pid)\n : false) || (await launcher.stop(record.pid));\n if (!stopped && termination) await termination.registry.requestTermination(record.id, undefined, record.sessionId);\n return stopped;\n}\n\n/** Repairs active registry entries that lost their original completion observer. */\nexport async function reconcileActiveRunners(dependencies: ReconcileDependencies): Promise<RunnerReconcileResult> {\n const result: RunnerReconcileResult = { reclaimed: [], errors: [] };\n const active = dependencies.active ?? (await dependencies.registry.list());\n for (const record of active) {\n try {\n const persisted = await dependencies.registry.get(record.id, record.sessionId);\n if (persisted?.state === COMPLETED_STATE) {\n await dependencies.registry.release(record.id, record.sessionId);\n result.reclaimed.push(record.id);\n continue;\n }\n\n const rmuxOutcome = MULTIPLEXER_BACKENDS.has(record.backend)\n ? dependencies.rmuxBackend.readOutcome(record.id, record.sessionId)\n : undefined;\n if (rmuxOutcome) {\n await dependencies.registry.complete(\n record.id,\n {\n reason:\n rmuxOutcome.reason ??\n (rmuxOutcome.signal ? 'signaled' : rmuxOutcome.code === 0 ? COMPLETED_STATE : 'failed'),\n code: rmuxOutcome.code,\n signal: rmuxOutcome.signal,\n ...(rmuxOutcome.terminationReason ? { terminationReason: rmuxOutcome.terminationReason } : {}),\n ...(rmuxOutcome.stopReason ? { stopReason: rmuxOutcome.stopReason } : {}),\n },\n record.sessionId,\n );\n result.reclaimed.push(record.id);\n continue;\n }\n\n if (!dependencies.processControl.isAlive(record.pid)) {\n await dependencies.registry.complete(\n record.id,\n { reason: 'backend_lost', code: null, signal: null },\n record.sessionId,\n );\n result.reclaimed.push(record.id);\n continue;\n }\n\n const previousRuntime =\n dependencies.startup &&\n record.hostPid === dependencies.currentHostPid &&\n record.sessionId === dependencies.startupSessionId;\n const ownerLost = !dependencies.processControl.isAlive(record.hostPid);\n if (!previousRuntime && !ownerLost) continue;\n\n const stopped = await stopRunnerProcess(record, dependencies.launcher, dependencies.rmuxBackend, {\n registry: dependencies.registry,\n intent: {\n reason: 'stopped',\n terminationReason: ownerLost ? 'owner_lost' : 'parent_session_cleanup',\n stopReason: 'owner session ended',\n },\n });\n if (!stopped && dependencies.processControl.isAlive(record.pid)) {\n result.errors.push(`Could not stop orphaned runner ${record.id}`);\n continue;\n }\n await dependencies.registry.complete(\n record.id,\n {\n reason: 'stopped',\n code: null,\n signal: 'SIGTERM',\n stopReason: 'owner session ended',\n },\n record.sessionId,\n );\n result.reclaimed.push(record.id);\n } catch (error) {\n result.errors.push(`Could not reconcile runner ${record.id}: ${String(error)}`);\n }\n }\n return result;\n}\n"],"mappings":";;ACMA,MAAM,uCAAuB,IAAI,IAAI,CAAC,QAAQ,MAAM,CAAC;AAmBrD,eAAsB,kBACpB,QACA,UACA,aACA,aACkB;CAClB,IAAI,aAAa,MAAM,YAAY,SAAS,mBAAmB,OAAO,IAAI,YAAY,QAAQ,OAAO,SAAS;CAC9G,MAAM,WACH,qBAAqB,IAAI,OAAO,OAAO,KAAK,OAAO,gBAChD,MAAM,YAAY,KAAK,OAAO,eAAe,OAAO,GAAG,IACvD,UAAW,MAAM,SAAS,KAAK,OAAO,GAAG;CAC/C,IAAI,CAAC,WAAW,aAAa,MAAM,YAAY,SAAS,mBAAmB,OAAO,IAAI,KAAA,GAAW,OAAO,SAAS;CACjH,OAAO;AACT;;AAGA,eAAsB,uBAAuB,cAAqE;CAChH,MAAM,SAAgC;EAAE,WAAW,CAAC;EAAG,QAAQ,CAAC;CAAE;CAClE,MAAM,SAAS,aAAa,UAAW,MAAM,aAAa,SAAS,KAAK;CACxE,KAAK,MAAM,UAAU,QACnB,IAAI;EAEF,KAAI,MADoB,aAAa,SAAS,IAAI,OAAO,IAAI,OAAO,SAAS,EAAA,EAC9D,UAAA,aAA2B;GACxC,MAAM,aAAa,SAAS,QAAQ,OAAO,IAAI,OAAO,SAAS;GAC/D,OAAO,UAAU,KAAK,OAAO,EAAE;GAC/B;EACF;EAEA,MAAM,cAAc,qBAAqB,IAAI,OAAO,OAAO,IACvD,aAAa,YAAY,YAAY,OAAO,IAAI,OAAO,SAAS,IAChE,KAAA;EACJ,IAAI,aAAa;GACf,MAAM,aAAa,SAAS,SAC1B,OAAO,IACP;IACE,QACE,YAAY,WACX,YAAY,SAAS,aAAa,YAAY,SAAS,IAAA,cAAsB;IAChF,MAAM,YAAY;IAClB,QAAQ,YAAY;IACpB,GAAI,YAAY,oBAAoB,EAAE,mBAAmB,YAAY,kBAAkB,IAAI,CAAC;IAC5F,GAAI,YAAY,aAAa,EAAE,YAAY,YAAY,WAAW,IAAI,CAAC;GACzE,GACA,OAAO,SACT;GACA,OAAO,UAAU,KAAK,OAAO,EAAE;GAC/B;EACF;EAEA,IAAI,CAAC,aAAa,eAAe,QAAQ,OAAO,GAAG,GAAG;GACpD,MAAM,aAAa,SAAS,SAC1B,OAAO,IACP;IAAE,QAAQ;IAAgB,MAAM;IAAM,QAAQ;GAAK,GACnD,OAAO,SACT;GACA,OAAO,UAAU,KAAK,OAAO,EAAE;GAC/B;EACF;EAEA,MAAM,kBACJ,aAAa,WACb,OAAO,YAAY,aAAa,kBAChC,OAAO,cAAc,aAAa;EACpC,MAAM,YAAY,CAAC,aAAa,eAAe,QAAQ,OAAO,OAAO;EACrE,IAAI,CAAC,mBAAmB,CAAC,WAAW;EAUpC,IAAI,CAAC,MARiB,kBAAkB,QAAQ,aAAa,UAAU,aAAa,aAAa;GAC/F,UAAU,aAAa;GACvB,QAAQ;IACN,QAAQ;IACR,mBAAmB,YAAY,eAAe;IAC9C,YAAY;GACd;EACF,CAAC,KACe,aAAa,eAAe,QAAQ,OAAO,GAAG,GAAG;GAC/D,OAAO,OAAO,KAAK,kCAAkC,OAAO,IAAI;GAChE;EACF;EACA,MAAM,aAAa,SAAS,SAC1B,OAAO,IACP;GACE,QAAQ;GACR,MAAM;GACN,QAAQ;GACR,YAAY;EACd,GACA,OAAO,SACT;EACA,OAAO,UAAU,KAAK,OAAO,EAAE;CACjC,SAAS,OAAO;EACd,OAAO,OAAO,KAAK,8BAA8B,OAAO,GAAG,IAAI,OAAO,KAAK,GAAG;CAChF;CAEF,OAAO;AACT"}
@@ -1,6 +1,3 @@
1
- const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
2
- let node_path = require("node:path");
3
- node_path = require_rolldown_runtime.__toESM(node_path, 1);
4
1
  //#endregion
5
2
  //#region src/services/reconcile/index.ts
6
3
  const MULTIPLEXER_BACKENDS = /* @__PURE__ */ new Set(["rmux", "tmux"]);
@@ -70,64 +67,7 @@ async function reconcileActiveRunners(dependencies) {
70
67
  }
71
68
  return result;
72
69
  }
73
- function isWithin(root, candidate) {
74
- const relative = node_path.default.relative(node_path.default.resolve(root), node_path.default.resolve(candidate));
75
- return relative === "" || !relative.startsWith("..") && !node_path.default.isAbsolute(relative);
76
- }
77
- /** Deletes the legacy Git store only after no live foreign runner uses it. */
78
- async function cleanupLegacyRunnerStore(dependencies) {
79
- const result = {
80
- reclaimed: [],
81
- errors: []
82
- };
83
- const legacyDirectory = dependencies.paths.legacyDirectory();
84
- if (!legacyDirectory) return result;
85
- const legacyRecords = (await dependencies.registry.list()).filter((record) => isWithin(legacyDirectory, record.logPath));
86
- for (const record of legacyRecords) {
87
- const childAlive = dependencies.processControl.isAlive(record.pid);
88
- const ownerAlive = dependencies.processControl.isAlive(record.hostPid);
89
- if (childAlive && ownerAlive) continue;
90
- try {
91
- if (childAlive) {
92
- if (!await stopRunnerProcess(record, dependencies.launcher, dependencies.rmuxBackend) && dependencies.processControl.isAlive(record.pid)) {
93
- result.errors.push(`Could not stop legacy runner ${record.id}`);
94
- continue;
95
- }
96
- }
97
- await dependencies.registry.release(record.id, record.sessionId);
98
- result.reclaimed.push(record.id);
99
- } catch (error) {
100
- result.errors.push(`Could not reclaim legacy runner ${record.id}: ${String(error)}`);
101
- }
102
- }
103
- let liveDependencies;
104
- try {
105
- liveDependencies = (await dependencies.registry.listAcrossRepositories()).filter((record) => isWithin(legacyDirectory, record.logPath) && dependencies.processControl.isAlive(record.pid));
106
- } catch (error) {
107
- result.errors.push(`Could not verify legacy runner dependencies: ${String(error)}`);
108
- return result;
109
- }
110
- if (result.errors.length === 0 && liveDependencies.length === 0) result.removed = dependencies.paths.removeLegacyStore();
111
- return result;
112
- }
113
70
  //#endregion
114
- Object.defineProperty(exports, "cleanupLegacyRunnerStore", {
115
- enumerable: true,
116
- get: function() {
117
- return cleanupLegacyRunnerStore;
118
- }
119
- });
120
- Object.defineProperty(exports, "reconcileActiveRunners", {
121
- enumerable: true,
122
- get: function() {
123
- return reconcileActiveRunners;
124
- }
125
- });
126
- Object.defineProperty(exports, "stopRunnerProcess", {
127
- enumerable: true,
128
- get: function() {
129
- return stopRunnerProcess;
130
- }
131
- });
71
+ export { stopRunnerProcess as n, reconcileActiveRunners as t };
132
72
 
133
- //# sourceMappingURL=reconcile-BugwYFbV.cjs.map
73
+ //# sourceMappingURL=reconcile-wNYQJZF-.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile-wNYQJZF-.mjs","names":[],"sources":["../src/constants/reconcile.ts","../src/services/reconcile/index.ts"],"sourcesContent":["export const COMPLETED_STATE = 'completed';\n","import { COMPLETED_STATE } from '../../constants/reconcile';\nimport type { ILauncher } from '../../types/launcher';\nimport type { IProcessControl } from '../../types/processControl';\nimport type { IRmuxBackend } from '../../types/rmuxBackend';\nimport type { IRunnerRegistry, RunnerRecord, RunnerTerminationIntent } from '../../types/runnerRegistry';\n\nconst MULTIPLEXER_BACKENDS = new Set(['rmux', 'tmux']);\n\ninterface ReconcileDependencies {\n registry: IRunnerRegistry;\n launcher: ILauncher;\n rmuxBackend: IRmuxBackend;\n processControl: IProcessControl;\n currentHostPid: number;\n startup: boolean;\n /** Same-host restart cleanup belongs only to this session. */\n startupSessionId?: string;\n active?: readonly RunnerRecord[];\n}\n\nexport interface RunnerReconcileResult {\n reclaimed: string[];\n errors: string[];\n}\n\nexport async function stopRunnerProcess(\n record: RunnerRecord,\n launcher: ILauncher,\n rmuxBackend: IRmuxBackend,\n termination?: { registry: IRunnerRegistry; intent: RunnerTerminationIntent },\n): Promise<boolean> {\n if (termination) await termination.registry.requestTermination(record.id, termination.intent, record.sessionId);\n const stopped =\n (MULTIPLEXER_BACKENDS.has(record.backend) && record.backendTarget\n ? await rmuxBackend.stop(record.backendTarget, record.pid)\n : false) || (await launcher.stop(record.pid));\n if (!stopped && termination) await termination.registry.requestTermination(record.id, undefined, record.sessionId);\n return stopped;\n}\n\n/** Repairs active registry entries that lost their original completion observer. */\nexport async function reconcileActiveRunners(dependencies: ReconcileDependencies): Promise<RunnerReconcileResult> {\n const result: RunnerReconcileResult = { reclaimed: [], errors: [] };\n const active = dependencies.active ?? (await dependencies.registry.list());\n for (const record of active) {\n try {\n const persisted = await dependencies.registry.get(record.id, record.sessionId);\n if (persisted?.state === COMPLETED_STATE) {\n await dependencies.registry.release(record.id, record.sessionId);\n result.reclaimed.push(record.id);\n continue;\n }\n\n const rmuxOutcome = MULTIPLEXER_BACKENDS.has(record.backend)\n ? dependencies.rmuxBackend.readOutcome(record.id, record.sessionId)\n : undefined;\n if (rmuxOutcome) {\n await dependencies.registry.complete(\n record.id,\n {\n reason:\n rmuxOutcome.reason ??\n (rmuxOutcome.signal ? 'signaled' : rmuxOutcome.code === 0 ? COMPLETED_STATE : 'failed'),\n code: rmuxOutcome.code,\n signal: rmuxOutcome.signal,\n ...(rmuxOutcome.terminationReason ? { terminationReason: rmuxOutcome.terminationReason } : {}),\n ...(rmuxOutcome.stopReason ? { stopReason: rmuxOutcome.stopReason } : {}),\n },\n record.sessionId,\n );\n result.reclaimed.push(record.id);\n continue;\n }\n\n if (!dependencies.processControl.isAlive(record.pid)) {\n await dependencies.registry.complete(\n record.id,\n { reason: 'backend_lost', code: null, signal: null },\n record.sessionId,\n );\n result.reclaimed.push(record.id);\n continue;\n }\n\n const previousRuntime =\n dependencies.startup &&\n record.hostPid === dependencies.currentHostPid &&\n record.sessionId === dependencies.startupSessionId;\n const ownerLost = !dependencies.processControl.isAlive(record.hostPid);\n if (!previousRuntime && !ownerLost) continue;\n\n const stopped = await stopRunnerProcess(record, dependencies.launcher, dependencies.rmuxBackend, {\n registry: dependencies.registry,\n intent: {\n reason: 'stopped',\n terminationReason: ownerLost ? 'owner_lost' : 'parent_session_cleanup',\n stopReason: 'owner session ended',\n },\n });\n if (!stopped && dependencies.processControl.isAlive(record.pid)) {\n result.errors.push(`Could not stop orphaned runner ${record.id}`);\n continue;\n }\n await dependencies.registry.complete(\n record.id,\n {\n reason: 'stopped',\n code: null,\n signal: 'SIGTERM',\n stopReason: 'owner session ended',\n },\n record.sessionId,\n );\n result.reclaimed.push(record.id);\n } catch (error) {\n result.errors.push(`Could not reconcile runner ${record.id}: ${String(error)}`);\n }\n }\n return result;\n}\n"],"mappings":";;ACMA,MAAM,uCAAuB,IAAI,IAAI,CAAC,QAAQ,MAAM,CAAC;AAmBrD,eAAsB,kBACpB,QACA,UACA,aACA,aACkB;CAClB,IAAI,aAAa,MAAM,YAAY,SAAS,mBAAmB,OAAO,IAAI,YAAY,QAAQ,OAAO,SAAS;CAC9G,MAAM,WACH,qBAAqB,IAAI,OAAO,OAAO,KAAK,OAAO,gBAChD,MAAM,YAAY,KAAK,OAAO,eAAe,OAAO,GAAG,IACvD,UAAW,MAAM,SAAS,KAAK,OAAO,GAAG;CAC/C,IAAI,CAAC,WAAW,aAAa,MAAM,YAAY,SAAS,mBAAmB,OAAO,IAAI,KAAA,GAAW,OAAO,SAAS;CACjH,OAAO;AACT;;AAGA,eAAsB,uBAAuB,cAAqE;CAChH,MAAM,SAAgC;EAAE,WAAW,CAAC;EAAG,QAAQ,CAAC;CAAE;CAClE,MAAM,SAAS,aAAa,UAAW,MAAM,aAAa,SAAS,KAAK;CACxE,KAAK,MAAM,UAAU,QACnB,IAAI;EAEF,KAAI,MADoB,aAAa,SAAS,IAAI,OAAO,IAAI,OAAO,SAAS,EAAA,EAC9D,UAAA,aAA2B;GACxC,MAAM,aAAa,SAAS,QAAQ,OAAO,IAAI,OAAO,SAAS;GAC/D,OAAO,UAAU,KAAK,OAAO,EAAE;GAC/B;EACF;EAEA,MAAM,cAAc,qBAAqB,IAAI,OAAO,OAAO,IACvD,aAAa,YAAY,YAAY,OAAO,IAAI,OAAO,SAAS,IAChE,KAAA;EACJ,IAAI,aAAa;GACf,MAAM,aAAa,SAAS,SAC1B,OAAO,IACP;IACE,QACE,YAAY,WACX,YAAY,SAAS,aAAa,YAAY,SAAS,IAAA,cAAsB;IAChF,MAAM,YAAY;IAClB,QAAQ,YAAY;IACpB,GAAI,YAAY,oBAAoB,EAAE,mBAAmB,YAAY,kBAAkB,IAAI,CAAC;IAC5F,GAAI,YAAY,aAAa,EAAE,YAAY,YAAY,WAAW,IAAI,CAAC;GACzE,GACA,OAAO,SACT;GACA,OAAO,UAAU,KAAK,OAAO,EAAE;GAC/B;EACF;EAEA,IAAI,CAAC,aAAa,eAAe,QAAQ,OAAO,GAAG,GAAG;GACpD,MAAM,aAAa,SAAS,SAC1B,OAAO,IACP;IAAE,QAAQ;IAAgB,MAAM;IAAM,QAAQ;GAAK,GACnD,OAAO,SACT;GACA,OAAO,UAAU,KAAK,OAAO,EAAE;GAC/B;EACF;EAEA,MAAM,kBACJ,aAAa,WACb,OAAO,YAAY,aAAa,kBAChC,OAAO,cAAc,aAAa;EACpC,MAAM,YAAY,CAAC,aAAa,eAAe,QAAQ,OAAO,OAAO;EACrE,IAAI,CAAC,mBAAmB,CAAC,WAAW;EAUpC,IAAI,CAAC,MARiB,kBAAkB,QAAQ,aAAa,UAAU,aAAa,aAAa;GAC/F,UAAU,aAAa;GACvB,QAAQ;IACN,QAAQ;IACR,mBAAmB,YAAY,eAAe;IAC9C,YAAY;GACd;EACF,CAAC,KACe,aAAa,eAAe,QAAQ,OAAO,GAAG,GAAG;GAC/D,OAAO,OAAO,KAAK,kCAAkC,OAAO,IAAI;GAChE;EACF;EACA,MAAM,aAAa,SAAS,SAC1B,OAAO,IACP;GACE,QAAQ;GACR,MAAM;GACN,QAAQ;GACR,YAAY;EACd,GACA,OAAO,SACT;EACA,OAAO,UAAU,KAAK,OAAO,EAAE;CACjC,SAAS,OAAO;EACd,OAAO,OAAO,KAAK,8BAA8B,OAAO,GAAG,IAAI,OAAO,KAAK,GAAG;CAChF;CAEF,OAAO;AACT"}
@@ -1,5 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_reconcile = require("./reconcile-BugwYFbV.cjs");
3
- exports.cleanupLegacyRunnerStore = require_reconcile.cleanupLegacyRunnerStore;
2
+ const require_reconcile = require("./reconcile-5cZ11jSD.cjs");
4
3
  exports.reconcileActiveRunners = require_reconcile.reconcileActiveRunners;
5
4
  exports.stopRunnerProcess = require_reconcile.stopRunnerProcess;
@@ -1,8 +1,7 @@
1
1
  import { t as ILauncher } from "./launcher-BG5t9nvG.mjs";
2
2
  import { t as IRmuxBackend } from "./rmuxBackend-CaEWooWn.mjs";
3
- import { a as RunnerTerminationIntent, i as RunnerRecord, n as IRunnerRegistry } from "./runnerRegistry-CtJiD02R.mjs";
3
+ import { a as RunnerTerminationIntent, i as RunnerRecord, n as IRunnerRegistry } from "./runnerRegistry-V-Ocaf4N.mjs";
4
4
  import { t as IProcessControl } from "./processControl-BAOa3oo_.mjs";
5
- import { t as IRunnerPaths } from "./type-BXM03qSw.mjs";
6
5
  //#region src/services/reconcile/index.d.ts
7
6
  interface ReconcileDependencies {
8
7
  registry: IRunnerRegistry;
@@ -25,12 +24,6 @@ export declare function stopRunnerProcess(record: RunnerRecord, launcher: ILaunc
25
24
  }): Promise<boolean>;
26
25
  /** Repairs active registry entries that lost their original completion observer. */
27
26
  export declare function reconcileActiveRunners(dependencies: ReconcileDependencies): Promise<RunnerReconcileResult>;
28
- interface LegacyCleanupDependencies extends Omit<ReconcileDependencies, 'startup'> {
29
- paths: IRunnerPaths;
30
- }
31
- /** Deletes the legacy Git store only after no live foreign runner uses it. */
32
- export declare function cleanupLegacyRunnerStore(dependencies: LegacyCleanupDependencies): Promise<RunnerReconcileResult & {
33
- removed?: string;
34
- }>;
35
27
  //#endregion
28
+ export {};
36
29
  //# sourceMappingURL=reconcile.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reconcile.d.mts","names":[],"sources":["../src/services/reconcile/index.ts"],"mappings":";;;;;;UAWU;EACR,UAAU;EACV,UAAU;EACV,aAAa;EACb,gBAAgB;EAChB;EACA;;EAEA;EACA,kBAAkB;;iBAGH;EACf;EACA;;wBAGoB,kBACpB,QAAQ,cACR,UAAU,WACV,aAAa,cACb;EAAgB,UAAU;EAAiB,QAAQ;IAClD;;wBAWmB,uBAAuB,cAAc,wBAAwB,QAAQ;UAqFjF,kCAAkC,KAAK;EAC/C,OAAO;;;wBAIa,yBACpB,cAAc,4BACb,QAAQ;EAA0B"}
1
+ {"version":3,"file":"reconcile.d.mts","names":[],"sources":["../src/services/reconcile/index.ts"],"mappings":";;;;;UAQU;EACR,UAAU;EACV,UAAU;EACV,aAAa;EACb,gBAAgB;EAChB;EACA;;EAEA;EACA,kBAAkB;;iBAGH;EACf;EACA;;wBAGoB,kBACpB,QAAQ,cACR,UAAU,WACV,aAAa,cACb;EAAgB,UAAU;EAAiB,QAAQ;IAClD;;wBAWmB,uBAAuB,cAAc,wBAAwB,QAAQ"}
@@ -1,2 +1 @@
1
- import { n as reconcileActiveRunners, r as stopRunnerProcess, t as cleanupLegacyRunnerStore } from "./reconcile-DMeNSxwn.mjs";
2
- export { cleanupLegacyRunnerStore, reconcileActiveRunners, stopRunnerProcess };
1
+ export { t as reconcileActiveRunners, n as stopRunnerProcess } from "./reconcile-wNYQJZF-.mjs";
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_bashResult = require("./bashResult-DNgtahGR.cjs");
3
- const require_logReader = require("./logReader-B6J7L7Ua.cjs");
2
+ const require_bashResult = require("./bashResult-C2iKhHpD.cjs");
3
+ const require_logReader = require("./logReader-DHCK2BEr.cjs");
4
4
  exports.boundExcerpt = require_bashResult.boundExcerpt;
5
5
  exports.boundResultText = require_bashResult.boundResultText;
6
6
  exports.collectErrorLines = require_bashResult.collectErrorLines;
@@ -1,5 +1,5 @@
1
1
  import { n as BashRunResult } from "./bashRunService-Ci0cGdYO.mjs";
2
- import { i as RunnerRecord } from "./runnerRegistry-CtJiD02R.mjs";
2
+ import { i as RunnerRecord } from "./runnerRegistry-V-Ocaf4N.mjs";
3
3
  import { a as ResultBudget, c as TruncatedOutput, i as LogSummary, n as Excerpt, o as SalvagedError, r as LogSummarizer, s as ToolResult, t as ErrorLineScanner } from "./bashResult-DcrRaBLv.mjs";
4
4
  import { t as RunnerSettings } from "./runnerSettings-DiV1lvzx.mjs";
5
5
  import { i as truncateForResult, r as summarizeLog } from "./index-DM7yJpMs.mjs";
@@ -11,7 +11,7 @@ export declare function formatSize(bytes: number): string;
11
11
  export declare function countLines(text: string): number;
12
12
  export declare function createErrorScanner(maxEntries?: number, settings?: RunnerSettings): ErrorLineScanner;
13
13
  /**
14
- * Reads `# @doom: {"maxResultBytes": 32768}` from the command's first line.
14
+ * Reads `# @po: {"maxResultBytes": 32768}` from the command's first line.
15
15
  *
16
16
  * The pragma is a shell comment, so it stays harmless if this parse is ever
17
17
  * skipped, and it survives verbatim into the log where a wider result can be
@@ -37,7 +37,7 @@ export declare function boundExcerpt(text: string, maxLines?: number, maxBytes?:
37
37
  * so the marker states what was dropped rather than what was captured.
38
38
  */
39
39
  export declare function composeExcerpt(headSource: string, tailSource: string, totalLines: number, maxLines?: number, maxBytes?: number, errors?: readonly SalvagedError[], maxTokens?: number, settings?: RunnerSettings): Excerpt;
40
- /** Applies Doom's line and byte ceilings to text already held in memory. */
40
+ /** Applies Po's line and byte ceilings to text already held in memory. */
41
41
  export declare function summarizeText(text: string, maxLines?: number, maxBytes?: number): Pick<LogSummary, 'tail' | 'tailLines'>;
42
42
  /** Bounds the complete model-facing result after status and recovery text are attached. */
43
43
  export declare function boundResultText(text: string, maxBytes?: number, settings?: RunnerSettings, maxTokens?: number): string;
@@ -1,3 +1,3 @@
1
- import { a as countLines, c as formatRunResult, d as formatUptime, f as parseResultPragma, i as composeExcerpt, l as formatRunnerLine, m as textResult, n as boundResultText, o as createErrorScanner, p as summarizeText, r as collectErrorLines, s as errorResult, t as boundExcerpt, u as formatSize } from "./bashResult-bIVSzoj-.mjs";
2
- import { i as truncateForResult, r as summarizeLog } from "./logReader-UfbDbwQl.mjs";
1
+ import { a as countLines, c as formatRunResult, d as formatUptime, f as parseResultPragma, i as composeExcerpt, l as formatRunnerLine, m as textResult, n as boundResultText, o as createErrorScanner, p as summarizeText, r as collectErrorLines, s as errorResult, t as boundExcerpt, u as formatSize } from "./bashResult-BqDa7sbC.mjs";
2
+ import { i as truncateForResult, r as summarizeLog } from "./logReader-mq9uVurh.mjs";
3
3
  export { boundExcerpt, boundResultText, collectErrorLines, composeExcerpt, countLines, createErrorScanner, errorResult, formatRunResult, formatRunnerLine, formatSize, formatUptime, parseResultPragma, summarizeLog, summarizeText, textResult, truncateForResult };
@@ -1,12 +1,12 @@
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_services_runnerSupervisor_index = require("./services/runnerSupervisor/index.cjs");
4
4
  let node_crypto = require("node:crypto");
5
5
  let node_fs = require("node:fs");
6
6
  node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
7
+ let node_module = require("node:module");
7
8
  let node_path = require("node:path");
8
9
  node_path = require_rolldown_runtime.__toESM(node_path, 1);
9
- let node_module = require("node:module");
10
10
  let _rmux_sdk = require("@rmux/sdk");
11
11
  //#region src/constants/rmuxBackend.ts
12
12
  const RMUX_BINARY_ENV = "PO_RMUX_BINARY";
@@ -15,8 +15,8 @@ const PANE_STATE_FORMAT = "#{pane_dead}:#{pane_dead_status}:#{session_name}";
15
15
  const PANE_PID_FORMAT = "#{pane_pid}";
16
16
  const STOP_CLOSE_TIMEOUT_MS = 1e3;
17
17
  const VENDOR_DIRECTORY = "vendor";
18
- const SESSION_PREFIX = "doom-runner-";
19
- const OWNED_TARGET_PATTERN = /^doom-runner-[A-Za-z0-9_-]+$/;
18
+ const SESSION_PREFIX = "po-runner-";
19
+ const OWNED_TARGET_PATTERN = /^po-runner-[A-Za-z0-9_-]+$/;
20
20
  const NON_INTERACTIVE_ENV = {
21
21
  NO_COLOR: "1",
22
22
  CI: "1"
@@ -520,4 +520,4 @@ Object.defineProperty(exports, "rmuxPackageForTarget", {
520
520
  }
521
521
  });
522
522
 
523
- //# sourceMappingURL=rmuxBackend-DlxgqRZ1.cjs.map
523
+ //# sourceMappingURL=rmuxBackend-Dh0CYVAL.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rmuxBackend-Dh0CYVAL.cjs","names":["runtimeEntry","getResultMaxBytes","readExitMetadata","RMUX","supervisorPaths","path","shellJoin","getLogMaxBytes","createRequire","fs","createHash","noninteractiveEnvironment","NO_TERMINAL_INPUT_ENV","watchForFile"],"sources":["../src/constants/rmuxBackend.ts","../src/services/rmuxBackend/index.ts"],"sourcesContent":["export const RMUX_BINARY_ENV = 'PO_RMUX_BINARY';\nexport const POLL_MS = 100;\nexport const LOG_DRAIN_TIMEOUT_MS = 2_000;\n/**\n * Fallback interval for a missed log-completion event or a lost session.\n * The retained pane lets the sink write its marker before session cleanup.\n */\nexport const LOG_DRAIN_POLL_MS = 25;\nexport const PANE_STATE_FORMAT = '#{pane_dead}:#{pane_dead_status}:#{session_name}';\nexport const PANE_PID_FORMAT = '#{pane_pid}';\nexport const STOP_GRACE_MS = 3_000;\nexport const STOP_CLOSE_TIMEOUT_MS = 1_000;\nexport const EXECUTABLE_MODE = 0o755;\n/** The owner, group, and other execute bits, so an already runnable file is left alone. */\nexport const EXECUTABLE_BITS = 0o111;\nexport const VENDOR_DIRECTORY = 'vendor';\nexport const SESSION_PREFIX = 'po-runner-';\nexport const OWNED_TARGET_PATTERN = /^po-runner-[A-Za-z0-9_-]+$/;\nexport const SOCKET_HASH_LENGTH = 12;\nexport const NON_INTERACTIVE_ENV = { NO_COLOR: '1', CI: '1' };\n","import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport { type Pane, RMUX, type Rmux } from '@rmux/sdk';\n\nimport {\n EXECUTABLE_BITS,\n EXECUTABLE_MODE,\n LOG_DRAIN_POLL_MS,\n LOG_DRAIN_TIMEOUT_MS,\n NON_INTERACTIVE_ENV,\n OWNED_TARGET_PATTERN,\n PANE_PID_FORMAT,\n PANE_STATE_FORMAT,\n POLL_MS,\n RMUX_BINARY_ENV,\n SESSION_PREFIX,\n SOCKET_HASH_LENGTH,\n STOP_CLOSE_TIMEOUT_MS,\n STOP_GRACE_MS,\n VENDOR_DIRECTORY,\n} from '../../constants/rmuxBackend';\nimport type { RunHandle } from '../../types/launcher';\nimport type { PtyRun } from '../../types/ptyHost';\nimport type { IRmuxBackend, RmuxLaunchRequest } from '../../types/rmuxBackend';\nimport type { RunnerSettings } from '../../types/runnerSettings';\nimport type { ExitResult } from '../../types/spawner';\nimport { getLogMaxBytes, getResultMaxBytes, noninteractiveEnvironment } from '../runnerConfig';\nimport type { IRunnerPaths } from '../runnerPaths/type';\nimport {\n cleanupSupervisorFiles,\n type CommandSpec,\n NO_TERMINAL_INPUT_ENV,\n readExitMetadata,\n runtimeEntry,\n shellJoin,\n type SupervisorPaths,\n supervisorPaths,\n watchForFile,\n writeCommandSpec,\n} from '../runnerSupervisor';\n\n/** Pane liveness, its exit status, and whether the session still exists, in one read. */\nconst PACKAGE_BY_PLATFORM: Readonly<Record<string, string>> = {\n 'darwin-arm64': '@agimon-ai/po-runner-rmux-darwin-arm64',\n 'darwin-x64': '@agimon-ai/po-runner-rmux-darwin-x64',\n 'linux-arm64': '@agimon-ai/po-runner-rmux-linux-arm64',\n 'linux-x64': '@agimon-ai/po-runner-rmux-linux-x64',\n};\n\nexport class RmuxBackend implements IRmuxBackend {\n private clientPromise: Promise<Rmux | undefined> | undefined;\n private readonly runs = new Map<string, PtyRun>();\n private readonly completions = new Map<string, Promise<ExitResult>>();\n\n constructor(\n private readonly paths: IRunnerPaths,\n private readonly env: Readonly<Record<string, string | undefined>> = process.env,\n private readonly settings?: RunnerSettings,\n ) {}\n\n async launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined> {\n const rmux = await this.client();\n if (!rmux) return undefined;\n\n this.paths.ensureDirectories();\n const target = `${SESSION_PREFIX}${request.id}`;\n const logPath = this.paths.logPathFor(request.id);\n const aux = this.auxPaths(request.id, request.sessionId);\n let created = false;\n let released = false;\n\n try {\n this.prepareFiles(request, logPath, aux);\n // `-P -F` reports the pane pid from the call that creates the pane, so the\n // launch does not spend a second round trip asking for it.\n const opened = await rmux.cmd(\n 'new-session',\n '-d',\n '-P',\n '-F',\n PANE_PID_FORMAT,\n '-s',\n target,\n '-c',\n request.cwd,\n process.execPath,\n runtimeEntry('runnerHost'),\n aux.spec,\n aux.gate,\n aux.exit,\n { check: true },\n );\n created = true;\n // Keep the pane until the log reader drains. Otherwise a fast shell can\n // end the session before the reader starts, losing its final output.\n await rmux.cmd('set-option', '-t', target, 'remain-on-exit', 'on', { check: true });\n await rmux.cmd('pipe-pane', '-t', target, this.logPipeCommand(logPath, aux.logDone, request), { check: true });\n\n const pane = rmux.session(target).pane(0, 0);\n const pid = reportedPid(String(opened.stdout ?? '')) ?? (await panePid(rmux, target));\n fs.writeFileSync(aux.gate, '', { mode: 0o600 });\n released = true;\n\n let buffering = true;\n const completion = this.monitor(rmux, pane, target, aux);\n this.trackCompletion(target, completion);\n const stop = (): Promise<boolean> => this.stop(target, pid);\n const handle: RunHandle = {\n id: request.id,\n name: request.name,\n pid,\n logPath,\n backend: 'rmux',\n backendTarget: target,\n output: () => (buffering ? readTail(logPath, getResultMaxBytes(this.env, this.settings) * 2) : ''),\n completion: () => completion,\n detach: () => {\n buffering = false;\n },\n stop,\n };\n\n if (request.interactive) this.runs.set(request.name, this.interactiveRun(handle, pane, completion));\n void completion\n .finally(() => this.runs.delete(request.name))\n .catch((error: unknown) => process.emitWarning(`RMUX completion failed for ${target}: ${errorMessage(error)}`));\n return handle;\n } catch (error) {\n if (released) throw error;\n if (created) {\n await rmux\n .session(target)\n .kill()\n .catch((cleanupError: unknown) =>\n process.emitWarning(`Could not clean up failed RMUX launch ${target}: ${errorMessage(cleanupError)}`),\n );\n }\n cleanupSupervisorFiles(aux);\n process.emitWarning(\n request.interactive\n ? `RMUX launch unavailable for interactive runner: ${errorMessage(error)}`\n : `RMUX launch unavailable, using supervised subprocess: ${errorMessage(error)}`,\n );\n return undefined;\n }\n }\n\n async stop(target: string, expectedPid: number): Promise<boolean> {\n if (!OWNED_TARGET_PATTERN.test(target) || !Number.isInteger(expectedPid) || expectedPid <= 0) return false;\n\n const rmux = await this.client();\n if (!rmux) return false;\n try {\n // A session that already ended took its process group with it.\n if (await sessionMissing(rmux, target)) return true;\n\n const pid = await panePid(rmux, target);\n if (pid !== expectedPid) return false;\n const signalled = signalPane(pid, target);\n if (signalled === 'gone') return true;\n if (signalled === 'failed') return false;\n\n if (await waitForPaneStop(rmux, target, STOP_GRACE_MS)) return true;\n if (await sessionMissing(rmux, target)) return true;\n\n // Revalidate after the grace period so a replacement pane is never closed.\n const currentPid = await panePid(rmux, target);\n if (currentPid !== expectedPid) return false;\n\n return closeOwnedSession(rmux, target);\n } catch (error) {\n process.emitWarning(`Could not stop RMUX target ${target}: ${errorMessage(error)}`);\n return false;\n }\n }\n\n async watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined> {\n const rmux = await this.client();\n if (!rmux) return undefined;\n const pane = rmux.session(target).pane(0, 0);\n try {\n await rmux.displayMessage('#{pane_id}', { target });\n } catch (error) {\n process.emitWarning(`Could not watch RMUX target ${target}: ${errorMessage(error)}`);\n return undefined;\n }\n const completion = this.monitor(rmux, pane, target, this.auxPaths(id, sessionId));\n this.trackCompletion(target, completion);\n return completion;\n }\n\n async input(target: string, text: string): Promise<boolean> {\n const rmux = await this.client();\n if (!rmux) return false;\n const result = await rmux\n .session(target)\n .pane(0, 0)\n .sendText(text)\n .catch((error: unknown) => {\n process.emitWarning(`Could not send input to RMUX target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result !== undefined;\n }\n\n async capture(target: string): Promise<string | undefined> {\n const rmux = await this.client();\n if (!rmux) return undefined;\n return rmux\n .session(target)\n .pane(0, 0)\n .captureText()\n .catch((error: unknown) => {\n process.emitWarning(`Could not capture RMUX target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n }\n\n get(name: string): PtyRun | undefined {\n return this.runs.get(name);\n }\n\n readOutcome(id: string, sessionId: string): ExitResult | undefined {\n return readExitMetadata(this.auxPaths(id, sessionId).exit);\n }\n\n private trackCompletion(target: string, completion: Promise<ExitResult>): void {\n this.completions.set(target, completion);\n void completion\n .finally(() => this.completions.delete(target))\n .catch((error: unknown) => process.emitWarning(`RMUX monitor failed for ${target}: ${errorMessage(error)}`));\n }\n\n private client(): Promise<Rmux | undefined> {\n this.clientPromise ??= this.resolveClient();\n return this.clientPromise;\n }\n\n private async resolveClient(): Promise<Rmux | undefined> {\n const binaries = [resolveBundledRmuxBinary(import.meta.url, this.env), 'rmux'].filter(\n (value): value is string => value !== undefined,\n );\n for (const binary of binaries) {\n try {\n if (binary !== 'rmux') ensureExecutablePayload(binary);\n const client = new RMUX({ binary, socketName: socketName(this.paths.repositoryPath()) });\n await client.capabilities();\n return client;\n } catch (error) {\n process.emitWarning(`RMUX candidate ${binary} is unavailable: ${errorMessage(error)}`);\n // Try the next compatible candidate. Non-interactive calls can use the subprocess launcher.\n }\n }\n return undefined;\n }\n\n private prepareFiles(request: RmuxLaunchRequest, logPath: string, aux: SupervisorPaths): void {\n cleanupSupervisorFiles(aux);\n fs.writeFileSync(logPath, '', { mode: 0o600 });\n const env = environment(request.sessionId, request.interactive, this.env);\n // runnerHost supervises the command and watches the lifeline itself, so an\n // owner that dies mid-run is handled inside the pane rather than around it.\n const spec: CommandSpec = { command: request.command, cwd: request.cwd, env };\n writeCommandSpec(aux.spec, spec);\n }\n\n private auxPaths(id: string, sessionId?: string): SupervisorPaths {\n return supervisorPaths(this.paths.stateDirectory(sessionId), id);\n }\n\n /**\n * The sink the pane pipes into.\n *\n * An interactive run also asks for a raw copy: the scrubbed log it writes\n * beside it has had cursor movement taken out, which is what a terminal\n * needs most. Only interactive runs pay for it, because only they can be\n * attached to.\n */\n private logPipeCommand(logPath: string, donePath: string, request: RmuxLaunchRequest): string {\n const id = path.basename(logPath, '.log');\n return shellJoin([\n process.execPath,\n runtimeEntry('logSink'),\n logPath,\n this.paths.rotatedLogPathFor(id),\n String(getLogMaxBytes(this.env)),\n donePath,\n ...(request.interactive ? [this.paths.rawLogPathFor(id)] : []),\n ]);\n }\n\n private async monitor(rmux: Rmux, pane: Pane, target: string, aux: SupervisorPaths): Promise<ExitResult> {\n try {\n const paneCode = await waitForRunEnd(rmux, target, aux.exit);\n await waitForLogDrain(rmux, target, aux.logDone);\n return readExitMetadata(aux.exit) ?? { code: paneCode, signal: null };\n } finally {\n // The pane stays alive for log capture. Remove its session after draining,\n // allowing the last completed run to shut down the mux server too.\n let timer: ReturnType<typeof setTimeout> | undefined;\n const cleanup = async (): Promise<void> => {\n if (!(await sessionMissing(rmux, target))) await pane.server.session(target).kill();\n };\n try {\n await Promise.race([\n cleanup().catch((error: unknown) =>\n process.emitWarning(`Could not clean up completed RMUX target ${target}: ${errorMessage(error)}`),\n ),\n new Promise<void>((resolve) => {\n timer = setTimeout(() => {\n process.emitWarning(`Timed out cleaning up RMUX target ${target} after ${STOP_CLOSE_TIMEOUT_MS}ms`);\n resolve();\n }, STOP_CLOSE_TIMEOUT_MS);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n cleanupSupervisorFiles(aux);\n }\n }\n }\n\n private interactiveRun(handle: RunHandle, pane: Pane, completion: Promise<ExitResult>): PtyRun {\n let screen = '';\n let active = true;\n const handlers = new Set<(data: string) => void>();\n const refresh = async (): Promise<void> => {\n while (active) {\n const next = await pane.captureText().catch((error: unknown) => {\n process.emitWarning(`Could not capture RMUX screen for ${handle.name}: ${errorMessage(error)}`);\n return screen;\n });\n if (next !== screen) {\n screen = next;\n for (const handler of handlers) handler(next);\n }\n await delay(POLL_MS);\n }\n };\n void refresh();\n void completion\n .finally(() => {\n active = false;\n })\n .catch((error: unknown) =>\n process.emitWarning(`RMUX interactive completion failed for ${handle.name}: ${errorMessage(error)}`),\n );\n return {\n ...handle,\n write: (text) => {\n void pane.sendText(text).catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n screen: () => screen,\n onData: (handler) => {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n resize: (cols, rows) => {\n void pane\n .resize({ width: cols, height: rows })\n .catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n };\n }\n}\n\nexport function rmuxPackageForTarget(platform: string, architecture: string): string | undefined {\n const target = `${platform}-${architecture}`;\n const packageName = PACKAGE_BY_PLATFORM[target];\n if (!packageName) process.emitWarning(`Bundled RMUX binary is unavailable for unsupported target ${target}`);\n return packageName;\n}\n\nexport function resolveBundledRmuxBinary(\n moduleUrl = import.meta.url,\n env: Readonly<Record<string, string | undefined>> = process.env,\n): string | undefined {\n const configured = env[RMUX_BINARY_ENV];\n if (configured !== undefined && configured !== '') return configured;\n const packageName = rmuxPackageForTarget(process.platform, process.arch);\n if (!packageName) return undefined;\n try {\n const require = createRequire(moduleUrl);\n const manifest = require.resolve(`${packageName}/package.json`);\n return path.join(path.dirname(manifest), VENDOR_DIRECTORY, 'bin', 'rmux');\n } catch (error) {\n process.emitWarning(`Bundled RMUX binary is unavailable for ${packageName}: ${errorMessage(error)}`);\n return undefined;\n }\n}\n\n/**\n * Make the bundled payload runnable before the launcher is spawned.\n *\n * The prebuilt packages reach npm with plain 0644 files, so the executable bit\n * the build set is not what lands on a user machine. Restoring it on the one\n * binary we spawn is not enough: rmux execs two files of its own,\n * `bin/rmux-daemon` and `libexec/rmux/rmux`, and the launcher fails on that\n * first exec with a permission error. Every file the payload ships is restored\n * here instead, which also covers a helper a later rmux release adds.\n *\n * A configured override (PO_RMUX_BINARY) usually points at a stand-alone\n * binary, so only paths that really sit inside a package vendor tree get the\n * walk. Files that are already executable are left untouched, since chmod on a\n * binary owned by someone else would throw and drop an otherwise usable\n * candidate.\n */\nexport function ensureExecutablePayload(binary: string): void {\n const vendor = path.resolve(path.dirname(binary), '..');\n const payload =\n path.basename(vendor) === VENDOR_DIRECTORY\n ? fs\n .readdirSync(vendor, { recursive: true, withFileTypes: true })\n .filter((entry) => entry.isFile())\n .map((entry) => path.join(entry.parentPath, entry.name))\n : [binary];\n for (const file of payload) {\n if ((fs.statSync(file).mode & EXECUTABLE_BITS) === 0) fs.chmodSync(file, EXECUTABLE_MODE);\n }\n}\n\nfunction socketName(repositoryPath: string): string {\n const hash = createHash('sha256').update(repositoryPath).digest('hex').slice(0, SOCKET_HASH_LENGTH);\n return `${SESSION_PREFIX}${hash}`;\n}\n\nfunction environment(\n sessionId: string,\n interactive: boolean,\n env: Readonly<Record<string, string | undefined>>,\n): Record<string, string> {\n const values: NodeJS.ProcessEnv = {\n ...env,\n ...(interactive ? {} : { ...NON_INTERACTIVE_ENV, ...noninteractiveEnvironment(env) }),\n // Applied to interactive runs as well: a pane is a tty either way, and an\n // agent sending input to a prompt still has no way past a pager.\n ...NO_TERMINAL_INPUT_ENV,\n PI_SESSION_ID: sessionId,\n };\n if (!interactive) delete values['FORCE_COLOR'];\n return Object.fromEntries(\n Object.entries(values).filter((entry): entry is [string, string] => entry[1] !== undefined),\n );\n}\n\nasync function panePid(rmux: Rmux, target: string): Promise<number> {\n const response = await rmux.displayMessage(PANE_PID_FORMAT, { target });\n const message = typeof response['message'] === 'string' ? response['message'] : '';\n const pid = reportedPid(message);\n if (pid === undefined) throw new Error(`RMUX did not report a pane pid for ${target}`);\n return pid;\n}\n\n/** A pane pid as rmux prints it, or nothing when the output holds no usable pid. */\nfunction reportedPid(output: string): number | undefined {\n const pid = Number(output.trim());\n return Number.isInteger(pid) && pid > 0 ? pid : undefined;\n}\n\n/**\n * Waits for the run to end, preferring the supervisor's own record of it.\n *\n * The sidecar is written before the command's pane can end, and it outlives the\n * server that the pane's exit takes down with it. Watching for it means a run\n * that finishes inside a poll interval is observed when it finishes rather than\n * on the next tick. Asking the server stays the fallback for a supervisor that\n * died without recording anything.\n */\nasync function waitForRunEnd(rmux: Rmux, target: string, exitPath: string): Promise<number | null> {\n const landed = watchForFile(exitPath);\n let active = true;\n const readEvidence = async (): Promise<null> => {\n while (active) {\n if (await landed.appeared(POLL_MS)) return null;\n }\n return null;\n };\n const probePane = async (): Promise<number | null> => {\n while (active) {\n await delay(POLL_MS);\n if (!active) return null;\n const state = await readPaneExit(rmux, target);\n if (state.exited) return state.code;\n }\n return null;\n };\n try {\n // A stalled SDK request must not block the supervisor's durable evidence.\n // Keep only one pane request in flight, even when it never answers.\n return await Promise.race([readEvidence(), probePane()]);\n } finally {\n active = false;\n landed.close();\n }\n}\n\n/**\n * Gives the log sink a moment to mark the log complete.\n *\n * Normal completion retains the session until the sink records its final\n * writes. A lost session cannot guarantee a later marker, so it ends the wait.\n */\nasync function waitForLogDrain(rmux: Rmux, target: string, donePath: string): Promise<void> {\n const deadline = Date.now() + LOG_DRAIN_TIMEOUT_MS;\n const landed = watchForFile(donePath);\n let active = true;\n const readEvidence = async (): Promise<void> => {\n while (active && Date.now() < deadline) {\n if (await landed.appeared(LOG_DRAIN_POLL_MS)) return;\n }\n };\n const probeSession = async (): Promise<void> => {\n while (active && Date.now() < deadline) {\n await delay(LOG_DRAIN_POLL_MS);\n if (!active) return;\n if (await sessionMissing(rmux, target)) return;\n }\n };\n try {\n // The file loop enforces the deadline while a session query is outstanding.\n await Promise.race([readEvidence(), probeSession()]);\n } finally {\n active = false;\n landed.close();\n }\n}\n\nasync function closeOwnedSession(rmux: Rmux, target: string): Promise<boolean> {\n return new Promise((resolve) => {\n let settled = false;\n const finish = (result: boolean): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(result);\n };\n const timer = setTimeout(() => {\n process.emitWarning(`Timed out closing RMUX target ${target} after ${STOP_CLOSE_TIMEOUT_MS}ms`);\n finish(false);\n }, STOP_CLOSE_TIMEOUT_MS);\n void rmux\n .session(target)\n .kill()\n .then(\n () => finish(true),\n (error: unknown) => {\n process.emitWarning(`Could not close RMUX target ${target}: ${errorMessage(error)}`);\n finish(false);\n },\n );\n });\n}\n\nasync function waitForPaneStop(rmux: Rmux, target: string, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n try {\n if ((await readPaneExit(rmux, target)).exited) return true;\n } catch (error) {\n process.emitWarning(`Could not verify RMUX target ${target} stopped: ${errorMessage(error)}`);\n return false;\n }\n await delay(POLL_MS);\n }\n return false;\n}\n\n/**\n * One formatted read answers both questions this poll asks, so watching a run\n * costs the same single rmux call it always did.\n */\nasync function readPaneExit(rmux: Rmux, target: string): Promise<{ exited: boolean; code: number | null }> {\n let message: string;\n try {\n const response = await rmux.displayMessage(PANE_STATE_FORMAT, { target });\n message = typeof response['message'] === 'string' ? response['message'] : '';\n } catch {\n // The last session ending stops the server, so a server that cannot be\n // reached is the ordinary end of the last run rather than a fault.\n return { exited: true, code: null };\n }\n const [dead, status, ...rest] = message.trim().split(':');\n // A missing session formats as a live pane with no name rather than failing,\n // so the name is what says whether there is still anything to watch.\n if (rest.join(':') === '') return { exited: true, code: null };\n if (dead === '1' || dead === 'true') {\n const code = Number(status);\n return { exited: true, code: Number.isInteger(code) ? code : null };\n }\n return { exited: false, code: null };\n}\n\n/** A session that cannot be found, on a server that may itself be gone. */\nasync function sessionMissing(rmux: Rmux, target: string): Promise<boolean> {\n try {\n const probe = await rmux.cmd('has-session', '-t', target);\n return probe.returnCode !== 0;\n } catch {\n // No server to ask means no session to find.\n return true;\n }\n}\n\n/**\n * A pane that was already gone and a signal that could not be delivered are\n * opposite answers to \"is it stopped\", so they are reported apart.\n */\nfunction signalPane(pid: number, target: string): 'signalled' | 'gone' | 'failed' {\n try {\n process.kill(pid, 'SIGTERM');\n return 'signalled';\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ESRCH') return 'gone';\n process.emitWarning(`Could not signal RMUX target ${target}: ${errorMessage(error)}`);\n return 'failed';\n }\n}\n\nfunction readTail(target: string, maxBytes: number): string {\n let handle: number | undefined;\n try {\n const size = fs.statSync(target).size;\n const bytes = Math.min(size, maxBytes);\n const buffer = Buffer.alloc(bytes);\n handle = fs.openSync(target, 'r');\n fs.readSync(handle, buffer, 0, bytes, size - bytes);\n return buffer.toString('utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n process.emitWarning(`Could not read RMUX log ${target}: ${errorMessage(error)}`);\n }\n return '';\n } finally {\n if (handle !== undefined) fs.closeSync(handle);\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n timer.unref?.();\n });\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":";;;;;;;;;;;AAAA,MAAa,kBAAkB;AAE/B,MAAa,uBAAuB;AAMpC,MAAa,oBAAoB;AACjC,MAAa,kBAAkB;AAE/B,MAAa,wBAAwB;AAIrC,MAAa,mBAAmB;AAChC,MAAa,iBAAiB;AAC9B,MAAa,uBAAuB;AAEpC,MAAa,sBAAsB;CAAE,UAAU;CAAK,IAAI;AAAI;;;;AC0B5D,MAAM,sBAAwD;CAC5D,gBAAgB;CAChB,cAAc;CACd,eAAe;CACf,aAAa;AACf;AAEA,IAAa,cAAb,MAAiD;CAM5B;CACA;CACA;CAPnB;CACA,uBAAwB,IAAI,IAAoB;CAChD,8BAA+B,IAAI,IAAiC;CAEpE,YACE,OACA,MAAqE,QAAQ,KAC7E,UACA;EAHiB,KAAA,QAAA;EACA,KAAA,MAAA;EACA,KAAA,WAAA;CAChB;CAEH,MAAM,OAAO,SAA4D;EACvE,MAAM,OAAO,MAAM,KAAK,OAAO;EAC/B,IAAI,CAAC,MAAM,OAAO,KAAA;EAElB,KAAK,MAAM,kBAAkB;EAC7B,MAAM,SAAS,GAAG,iBAAiB,QAAQ;EAC3C,MAAM,UAAU,KAAK,MAAM,WAAW,QAAQ,EAAE;EAChD,MAAM,MAAM,KAAK,SAAS,QAAQ,IAAI,QAAQ,SAAS;EACvD,IAAI,UAAU;EACd,IAAI,WAAW;EAEf,IAAI;GACF,KAAK,aAAa,SAAS,SAAS,GAAG;GAGvC,MAAM,SAAS,MAAM,KAAK,IACxB,eACA,MACA,MACA,MACA,iBACA,MACA,QACA,MACA,QAAQ,KACR,QAAQ,UACRA,wCAAAA,aAAa,YAAY,GACzB,IAAI,MACJ,IAAI,MACJ,IAAI,MACJ,EAAE,OAAO,KAAK,CAChB;GACA,UAAU;GAGV,MAAM,KAAK,IAAI,cAAc,MAAM,QAAQ,kBAAkB,MAAM,EAAE,OAAO,KAAK,CAAC;GAClF,MAAM,KAAK,IAAI,aAAa,MAAM,QAAQ,KAAK,eAAe,SAAS,IAAI,SAAS,OAAO,GAAG,EAAE,OAAO,KAAK,CAAC;GAE7G,MAAM,OAAO,KAAK,QAAQ,MAAM,CAAC,CAAC,KAAK,GAAG,CAAC;GAC3C,MAAM,MAAM,YAAY,OAAO,OAAO,UAAU,EAAE,CAAC,KAAM,MAAM,QAAQ,MAAM,MAAM;GACnF,QAAA,QAAG,cAAc,IAAI,MAAM,IAAI,EAAE,MAAM,IAAM,CAAC;GAC9C,WAAW;GAEX,IAAI,YAAY;GAChB,MAAM,aAAa,KAAK,QAAQ,MAAM,MAAM,QAAQ,GAAG;GACvD,KAAK,gBAAgB,QAAQ,UAAU;GACvC,MAAM,aAA+B,KAAK,KAAK,QAAQ,GAAG;GAC1D,MAAM,SAAoB;IACxB,IAAI,QAAQ;IACZ,MAAM,QAAQ;IACd;IACA;IACA,SAAS;IACT,eAAe;IACf,cAAe,YAAY,SAAS,SAASC,qBAAAA,kBAAkB,KAAK,KAAK,KAAK,QAAQ,IAAI,CAAC,IAAI;IAC/F,kBAAkB;IAClB,cAAc;KACZ,YAAY;IACd;IACA;GACF;GAEA,IAAI,QAAQ,aAAa,KAAK,KAAK,IAAI,QAAQ,MAAM,KAAK,eAAe,QAAQ,MAAM,UAAU,CAAC;GAClG,WACG,cAAc,KAAK,KAAK,OAAO,QAAQ,IAAI,CAAC,CAAC,CAC7C,OAAO,UAAmB,QAAQ,YAAY,8BAA8B,OAAO,IAAI,aAAa,KAAK,GAAG,CAAC;GAChH,OAAO;EACT,SAAS,OAAO;GACd,IAAI,UAAU,MAAM;GACpB,IAAI,SACF,MAAM,KACH,QAAQ,MAAM,CAAC,CACf,KAAK,CAAC,CACN,OAAO,iBACN,QAAQ,YAAY,yCAAyC,OAAO,IAAI,aAAa,YAAY,GAAG,CACtG;GAEJ,wCAAA,uBAAuB,GAAG;GAC1B,QAAQ,YACN,QAAQ,cACJ,mDAAmD,aAAa,KAAK,MACrE,yDAAyD,aAAa,KAAK,GACjF;GACA;EACF;CACF;CAEA,MAAM,KAAK,QAAgB,aAAuC;EAChE,IAAI,CAAC,qBAAqB,KAAK,MAAM,KAAK,CAAC,OAAO,UAAU,WAAW,KAAK,eAAe,GAAG,OAAO;EAErG,MAAM,OAAO,MAAM,KAAK,OAAO;EAC/B,IAAI,CAAC,MAAM,OAAO;EAClB,IAAI;GAEF,IAAI,MAAM,eAAe,MAAM,MAAM,GAAG,OAAO;GAE/C,MAAM,MAAM,MAAM,QAAQ,MAAM,MAAM;GACtC,IAAI,QAAQ,aAAa,OAAO;GAChC,MAAM,YAAY,WAAW,KAAK,MAAM;GACxC,IAAI,cAAc,QAAQ,OAAO;GACjC,IAAI,cAAc,UAAU,OAAO;GAEnC,IAAI,MAAM,gBAAgB,MAAM,QAAA,GAAqB,GAAG,OAAO;GAC/D,IAAI,MAAM,eAAe,MAAM,MAAM,GAAG,OAAO;GAI/C,IAAI,MADqB,QAAQ,MAAM,MAAM,MAC1B,aAAa,OAAO;GAEvC,OAAO,kBAAkB,MAAM,MAAM;EACvC,SAAS,OAAO;GACd,QAAQ,YAAY,8BAA8B,OAAO,IAAI,aAAa,KAAK,GAAG;GAClF,OAAO;EACT;CACF;CAEA,MAAM,MAAM,IAAY,QAAgB,WAAqD;EAC3F,MAAM,OAAO,MAAM,KAAK,OAAO;EAC/B,IAAI,CAAC,MAAM,OAAO,KAAA;EAClB,MAAM,OAAO,KAAK,QAAQ,MAAM,CAAC,CAAC,KAAK,GAAG,CAAC;EAC3C,IAAI;GACF,MAAM,KAAK,eAAe,cAAc,EAAE,OAAO,CAAC;EACpD,SAAS,OAAO;GACd,QAAQ,YAAY,+BAA+B,OAAO,IAAI,aAAa,KAAK,GAAG;GACnF;EACF;EACA,MAAM,aAAa,KAAK,QAAQ,MAAM,MAAM,QAAQ,KAAK,SAAS,IAAI,SAAS,CAAC;EAChF,KAAK,gBAAgB,QAAQ,UAAU;EACvC,OAAO;CACT;CAEA,MAAM,MAAM,QAAgB,MAAgC;EAC1D,MAAM,OAAO,MAAM,KAAK,OAAO;EAC/B,IAAI,CAAC,MAAM,OAAO;EASlB,OAAO,MARc,KAClB,QAAQ,MAAM,CAAC,CACf,KAAK,GAAG,CAAC,CAAC,CACV,SAAS,IAAI,CAAC,CACd,OAAO,UAAmB;GACzB,QAAQ,YAAY,uCAAuC,OAAO,IAAI,aAAa,KAAK,GAAG;EAE7F,CAAC,MACe,KAAA;CACpB;CAEA,MAAM,QAAQ,QAA6C;EACzD,MAAM,OAAO,MAAM,KAAK,OAAO;EAC/B,IAAI,CAAC,MAAM,OAAO,KAAA;EAClB,OAAO,KACJ,QAAQ,MAAM,CAAC,CACf,KAAK,GAAG,CAAC,CAAC,CACV,YAAY,CAAC,CACb,OAAO,UAAmB;GACzB,QAAQ,YAAY,iCAAiC,OAAO,IAAI,aAAa,KAAK,GAAG;EAEvF,CAAC;CACL;CAEA,IAAI,MAAkC;EACpC,OAAO,KAAK,KAAK,IAAI,IAAI;CAC3B;CAEA,YAAY,IAAY,WAA2C;EACjE,OAAOC,wCAAAA,iBAAiB,KAAK,SAAS,IAAI,SAAS,CAAC,CAAC,IAAI;CAC3D;CAEA,gBAAwB,QAAgB,YAAuC;EAC7E,KAAK,YAAY,IAAI,QAAQ,UAAU;EACvC,WACG,cAAc,KAAK,YAAY,OAAO,MAAM,CAAC,CAAC,CAC9C,OAAO,UAAmB,QAAQ,YAAY,2BAA2B,OAAO,IAAI,aAAa,KAAK,GAAG,CAAC;CAC/G;CAEA,SAA4C;EAC1C,KAAK,kBAAkB,KAAK,cAAc;EAC1C,OAAO,KAAK;CACd;CAEA,MAAc,gBAA2C;EACvD,MAAM,WAAW,CAAC,yBAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,MAA0C,KAAK,GAAG,GAAG,MAAM,CAAC,CAAC,QAC5E,UAA2B,UAAU,KAAA,CACxC;EACA,KAAK,MAAM,UAAU,UACnB,IAAI;GACF,IAAI,WAAW,QAAQ,wBAAwB,MAAM;GACrD,MAAM,SAAS,IAAIC,UAAAA,KAAK;IAAE;IAAQ,YAAY,WAAW,KAAK,MAAM,eAAe,CAAC;GAAE,CAAC;GACvF,MAAM,OAAO,aAAa;GAC1B,OAAO;EACT,SAAS,OAAO;GACd,QAAQ,YAAY,kBAAkB,OAAO,mBAAmB,aAAa,KAAK,GAAG;EAEvF;CAGJ;CAEA,aAAqB,SAA4B,SAAiB,KAA4B;EAC5F,wCAAA,uBAAuB,GAAG;EAC1B,QAAA,QAAG,cAAc,SAAS,IAAI,EAAE,MAAM,IAAM,CAAC;EAC7C,MAAM,MAAM,YAAY,QAAQ,WAAW,QAAQ,aAAa,KAAK,GAAG;EAGxE,MAAM,OAAoB;GAAE,SAAS,QAAQ;GAAS,KAAK,QAAQ;GAAK;EAAI;EAC5E,wCAAA,iBAAiB,IAAI,MAAM,IAAI;CACjC;CAEA,SAAiB,IAAY,WAAqC;EAChE,OAAOC,wCAAAA,gBAAgB,KAAK,MAAM,eAAe,SAAS,GAAG,EAAE;CACjE;;;;;;;;;CAUA,eAAuB,SAAiB,UAAkB,SAAoC;EAC5F,MAAM,KAAKC,UAAAA,QAAK,SAAS,SAAS,MAAM;EACxC,OAAOC,wCAAAA,UAAU;GACf,QAAQ;GACRN,wCAAAA,aAAa,SAAS;GACtB;GACA,KAAK,MAAM,kBAAkB,EAAE;GAC/B,OAAOO,qBAAAA,eAAe,KAAK,GAAG,CAAC;GAC/B;GACA,GAAI,QAAQ,cAAc,CAAC,KAAK,MAAM,cAAc,EAAE,CAAC,IAAI,CAAC;EAC9D,CAAC;CACH;CAEA,MAAc,QAAQ,MAAY,MAAY,QAAgB,KAA2C;EACvG,IAAI;GACF,MAAM,WAAW,MAAM,cAAc,MAAM,QAAQ,IAAI,IAAI;GAC3D,MAAM,gBAAgB,MAAM,QAAQ,IAAI,OAAO;GAC/C,OAAOL,wCAAAA,iBAAiB,IAAI,IAAI,KAAK;IAAE,MAAM;IAAU,QAAQ;GAAK;EACtE,UAAU;GAGR,IAAI;GACJ,MAAM,UAAU,YAA2B;IACzC,IAAI,CAAE,MAAM,eAAe,MAAM,MAAM,GAAI,MAAM,KAAK,OAAO,QAAQ,MAAM,CAAC,CAAC,KAAK;GACpF;GACA,IAAI;IACF,MAAM,QAAQ,KAAK,CACjB,QAAQ,CAAC,CAAC,OAAO,UACf,QAAQ,YAAY,4CAA4C,OAAO,IAAI,aAAa,KAAK,GAAG,CAClG,GACA,IAAI,SAAe,YAAY;KAC7B,QAAQ,iBAAiB;MACvB,QAAQ,YAAY,qCAAqC,OAAO,SAAS,sBAAsB,GAAG;MAClG,QAAQ;KACV,GAAG,qBAAqB;IAC1B,CAAC,CACH,CAAC;GACH,UAAU;IACR,IAAI,OAAO,aAAa,KAAK;IAC7B,wCAAA,uBAAuB,GAAG;GAC5B;EACF;CACF;CAEA,eAAuB,QAAmB,MAAY,YAAyC;EAC7F,IAAI,SAAS;EACb,IAAI,SAAS;EACb,MAAM,2BAAW,IAAI,IAA4B;EACjD,MAAM,UAAU,YAA2B;GACzC,OAAO,QAAQ;IACb,MAAM,OAAO,MAAM,KAAK,YAAY,CAAC,CAAC,OAAO,UAAmB;KAC9D,QAAQ,YAAY,qCAAqC,OAAO,KAAK,IAAI,aAAa,KAAK,GAAG;KAC9F,OAAO;IACT,CAAC;IACD,IAAI,SAAS,QAAQ;KACnB,SAAS;KACT,KAAK,MAAM,WAAW,UAAU,QAAQ,IAAI;IAC9C;IACA,MAAM,MAAA,GAAa;GACrB;EACF;EACA,QAAa;EACb,WACG,cAAc;GACb,SAAS;EACX,CAAC,CAAC,CACD,OAAO,UACN,QAAQ,YAAY,0CAA0C,OAAO,KAAK,IAAI,aAAa,KAAK,GAAG,CACrG;EACF,OAAO;GACL,GAAG;GACH,QAAQ,SAAS;IACf,KAAU,SAAS,IAAI,CAAC,CAAC,OAAO,UAAmB,QAAQ,YAAY,aAAa,KAAK,CAAC,CAAC;GAC7F;GACA,cAAc;GACd,SAAS,YAAY;IACnB,SAAS,IAAI,OAAO;IACpB,aAAa,SAAS,OAAO,OAAO;GACtC;GACA,SAAS,MAAM,SAAS;IACtB,KACG,OAAO;KAAE,OAAO;KAAM,QAAQ;IAAK,CAAC,CAAC,CACrC,OAAO,UAAmB,QAAQ,YAAY,aAAa,KAAK,CAAC,CAAC;GACvE;EACF;CACF;AACF;AAEA,SAAgB,qBAAqB,UAAkB,cAA0C;CAC/F,MAAM,SAAS,GAAG,SAAS,GAAG;CAC9B,MAAM,cAAc,oBAAoB;CACxC,IAAI,CAAC,aAAa,QAAQ,YAAY,6DAA6D,QAAQ;CAC3G,OAAO;AACT;AAEA,SAAgB,yBACd,YAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,MACA,MAAoD,QAAQ,KACxC;CACpB,MAAM,aAAa,IAAI;CACvB,IAAI,eAAe,KAAA,KAAa,eAAe,IAAI,OAAO;CAC1D,MAAM,cAAc,qBAAqB,QAAQ,UAAU,QAAQ,IAAI;CACvE,IAAI,CAAC,aAAa,OAAO,KAAA;CACzB,IAAI;EAEF,MAAM,YAAA,GADUM,YAAAA,cAAAA,CAAc,SACP,CAAC,CAAC,QAAQ,GAAG,YAAY,cAAc;EAC9D,OAAOH,UAAAA,QAAK,KAAKA,UAAAA,QAAK,QAAQ,QAAQ,GAAG,kBAAkB,OAAO,MAAM;CAC1E,SAAS,OAAO;EACd,QAAQ,YAAY,0CAA0C,YAAY,IAAI,aAAa,KAAK,GAAG;EACnG;CACF;AACF;;;;;;;;;;;;;;;;;AAkBA,SAAgB,wBAAwB,QAAsB;CAC5D,MAAM,SAASA,UAAAA,QAAK,QAAQA,UAAAA,QAAK,QAAQ,MAAM,GAAG,IAAI;CACtD,MAAM,UACJA,UAAAA,QAAK,SAAS,MAAM,MAAA,WAChBI,QAAAA,QACG,YAAY,QAAQ;EAAE,WAAW;EAAM,eAAe;CAAK,CAAC,CAAC,CAC7D,QAAQ,UAAU,MAAM,OAAO,CAAC,CAAC,CACjC,KAAK,UAAUJ,UAAAA,QAAK,KAAK,MAAM,YAAY,MAAM,IAAI,CAAC,IACzD,CAAC,MAAM;CACb,KAAK,MAAM,QAAQ,SACjB,KAAKI,QAAAA,QAAG,SAAS,IAAI,CAAC,CAAC,OAAA,QAA4B,GAAG,QAAA,QAAG,UAAU,MAAA,GAAqB;AAE5F;AAEA,SAAS,WAAW,gBAAgC;CAClD,MAAM,QAAA,GAAOC,YAAAA,WAAAA,CAAW,QAAQ,CAAC,CAAC,OAAO,cAAc,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAA,EAAqB;CAClG,OAAO,GAAG,iBAAiB;AAC7B;AAEA,SAAS,YACP,WACA,aACA,KACwB;CACxB,MAAM,SAA4B;EAChC,GAAG;EACH,GAAI,cAAc,CAAC,IAAI;GAAE,GAAG;GAAqB,GAAGC,qBAAAA,0BAA0B,GAAG;EAAE;EAGnF,GAAGC,wCAAAA;EACH,eAAe;CACjB;CACA,IAAI,CAAC,aAAa,OAAO,OAAO;CAChC,OAAO,OAAO,YACZ,OAAO,QAAQ,MAAM,CAAC,CAAC,QAAQ,UAAqC,MAAM,OAAO,KAAA,CAAS,CAC5F;AACF;AAEA,eAAe,QAAQ,MAAY,QAAiC;CAClE,MAAM,WAAW,MAAM,KAAK,eAAe,iBAAiB,EAAE,OAAO,CAAC;CAEtE,MAAM,MAAM,YADI,OAAO,SAAS,eAAe,WAAW,SAAS,aAAa,EACjD;CAC/B,IAAI,QAAQ,KAAA,GAAW,MAAM,IAAI,MAAM,sCAAsC,QAAQ;CACrF,OAAO;AACT;;AAGA,SAAS,YAAY,QAAoC;CACvD,MAAM,MAAM,OAAO,OAAO,KAAK,CAAC;CAChC,OAAO,OAAO,UAAU,GAAG,KAAK,MAAM,IAAI,MAAM,KAAA;AAClD;;;;;;;;;;AAWA,eAAe,cAAc,MAAY,QAAgB,UAA0C;CACjG,MAAM,SAASC,wCAAAA,aAAa,QAAQ;CACpC,IAAI,SAAS;CACb,MAAM,eAAe,YAA2B;EAC9C,OAAO,QACL,IAAI,MAAM,OAAO,SAAA,GAAgB,GAAG,OAAO;EAE7C,OAAO;CACT;CACA,MAAM,YAAY,YAAoC;EACpD,OAAO,QAAQ;GACb,MAAM,MAAA,GAAa;GACnB,IAAI,CAAC,QAAQ,OAAO;GACpB,MAAM,QAAQ,MAAM,aAAa,MAAM,MAAM;GAC7C,IAAI,MAAM,QAAQ,OAAO,MAAM;EACjC;EACA,OAAO;CACT;CACA,IAAI;EAGF,OAAO,MAAM,QAAQ,KAAK,CAAC,aAAa,GAAG,UAAU,CAAC,CAAC;CACzD,UAAU;EACR,SAAS;EACT,OAAO,MAAM;CACf;AACF;;;;;;;AAQA,eAAe,gBAAgB,MAAY,QAAgB,UAAiC;CAC1F,MAAM,WAAW,KAAK,IAAI,IAAI;CAC9B,MAAM,SAASA,wCAAAA,aAAa,QAAQ;CACpC,IAAI,SAAS;CACb,MAAM,eAAe,YAA2B;EAC9C,OAAO,UAAU,KAAK,IAAI,IAAI,UAC5B,IAAI,MAAM,OAAO,SAAA,EAA0B,GAAG;CAElD;CACA,MAAM,eAAe,YAA2B;EAC9C,OAAO,UAAU,KAAK,IAAI,IAAI,UAAU;GACtC,MAAM,MAAA,EAAuB;GAC7B,IAAI,CAAC,QAAQ;GACb,IAAI,MAAM,eAAe,MAAM,MAAM,GAAG;EAC1C;CACF;CACA,IAAI;EAEF,MAAM,QAAQ,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC,CAAC;CACrD,UAAU;EACR,SAAS;EACT,OAAO,MAAM;CACf;AACF;AAEA,eAAe,kBAAkB,MAAY,QAAkC;CAC7E,OAAO,IAAI,SAAS,YAAY;EAC9B,IAAI,UAAU;EACd,MAAM,UAAU,WAA0B;GACxC,IAAI,SAAS;GACb,UAAU;GACV,aAAa,KAAK;GAClB,QAAQ,MAAM;EAChB;EACA,MAAM,QAAQ,iBAAiB;GAC7B,QAAQ,YAAY,iCAAiC,OAAO,SAAS,sBAAsB,GAAG;GAC9F,OAAO,KAAK;EACd,GAAG,qBAAqB;EACxB,KACG,QAAQ,MAAM,CAAC,CACf,KAAK,CAAC,CACN,WACO,OAAO,IAAI,IAChB,UAAmB;GAClB,QAAQ,YAAY,+BAA+B,OAAO,IAAI,aAAa,KAAK,GAAG;GACnF,OAAO,KAAK;EACd,CACF;CACJ,CAAC;AACH;AAEA,eAAe,gBAAgB,MAAY,QAAgB,WAAqC;CAC9F,MAAM,WAAW,KAAK,IAAI,IAAI;CAC9B,OAAO,KAAK,IAAI,IAAI,UAAU;EAC5B,IAAI;GACF,KAAK,MAAM,aAAa,MAAM,MAAM,EAAA,CAAG,QAAQ,OAAO;EACxD,SAAS,OAAO;GACd,QAAQ,YAAY,gCAAgC,OAAO,YAAY,aAAa,KAAK,GAAG;GAC5F,OAAO;EACT;EACA,MAAM,MAAA,GAAa;CACrB;CACA,OAAO;AACT;;;;;AAMA,eAAe,aAAa,MAAY,QAAmE;CACzG,IAAI;CACJ,IAAI;EACF,MAAM,WAAW,MAAM,KAAK,eAAe,mBAAmB,EAAE,OAAO,CAAC;EACxE,UAAU,OAAO,SAAS,eAAe,WAAW,SAAS,aAAa;CAC5E,QAAQ;EAGN,OAAO;GAAE,QAAQ;GAAM,MAAM;EAAK;CACpC;CACA,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,QAAQ,KAAK,CAAC,CAAC,MAAM,GAAG;CAGxD,IAAI,KAAK,KAAK,GAAG,MAAM,IAAI,OAAO;EAAE,QAAQ;EAAM,MAAM;CAAK;CAC7D,IAAI,SAAS,OAAO,SAAS,QAAQ;EACnC,MAAM,OAAO,OAAO,MAAM;EAC1B,OAAO;GAAE,QAAQ;GAAM,MAAM,OAAO,UAAU,IAAI,IAAI,OAAO;EAAK;CACpE;CACA,OAAO;EAAE,QAAQ;EAAO,MAAM;CAAK;AACrC;;AAGA,eAAe,eAAe,MAAY,QAAkC;CAC1E,IAAI;EAEF,QAAO,MADa,KAAK,IAAI,eAAe,MAAM,MAAM,EAAA,CAC3C,eAAe;CAC9B,QAAQ;EAEN,OAAO;CACT;AACF;;;;;AAMA,SAAS,WAAW,KAAa,QAAiD;CAChF,IAAI;EACF,QAAQ,KAAK,KAAK,SAAS;EAC3B,OAAO;CACT,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,SAAS,OAAO;EAC9D,QAAQ,YAAY,gCAAgC,OAAO,IAAI,aAAa,KAAK,GAAG;EACpF,OAAO;CACT;AACF;AAEA,SAAS,SAAS,QAAgB,UAA0B;CAC1D,IAAI;CACJ,IAAI;EACF,MAAM,OAAOJ,QAAAA,QAAG,SAAS,MAAM,CAAC,CAAC;EACjC,MAAM,QAAQ,KAAK,IAAI,MAAM,QAAQ;EACrC,MAAM,SAAS,OAAO,MAAM,KAAK;EACjC,SAASA,QAAAA,QAAG,SAAS,QAAQ,GAAG;EAChC,QAAA,QAAG,SAAS,QAAQ,QAAQ,GAAG,OAAO,OAAO,KAAK;EAClD,OAAO,OAAO,SAAS,MAAM;CAC/B,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,UAC5C,QAAQ,YAAY,2BAA2B,OAAO,IAAI,aAAa,KAAK,GAAG;EAEjF,OAAO;CACT,UAAU;EACR,IAAI,WAAW,KAAA,GAAW,QAAA,QAAG,UAAU,MAAM;CAC/C;AACF;AAEA,SAAS,MAAM,IAA2B;CACxC,OAAO,IAAI,SAAS,YAAY;EAE9B,WADyB,SAAS,EAC9B,CAAC,CAAC,QAAQ;CAChB,CAAC;AACH;AAEA,SAAS,aAAa,OAAwB;CAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D"}
@@ -1,4 +1,4 @@
1
- import { g as noninteractiveEnvironment, s as getLogMaxBytes, u as getResultMaxBytes } from "./runnerConfig-BQBlVAXn.mjs";
1
+ import { g as noninteractiveEnvironment, s as getLogMaxBytes, u as getResultMaxBytes } from "./runnerConfig-XXMq4VQA.mjs";
2
2
  import { NO_TERMINAL_INPUT_ENV, cleanupSupervisorFiles, readExitMetadata, runtimeEntry, shellJoin, supervisorPaths, watchForFile, writeCommandSpec } from "./services/runnerSupervisor/index.mjs";
3
3
  import { createRequire } from "node:module";
4
4
  import { createHash } from "node:crypto";
@@ -12,8 +12,8 @@ const PANE_STATE_FORMAT = "#{pane_dead}:#{pane_dead_status}:#{session_name}";
12
12
  const PANE_PID_FORMAT = "#{pane_pid}";
13
13
  const STOP_CLOSE_TIMEOUT_MS = 1e3;
14
14
  const VENDOR_DIRECTORY = "vendor";
15
- const SESSION_PREFIX = "doom-runner-";
16
- const OWNED_TARGET_PATTERN = /^doom-runner-[A-Za-z0-9_-]+$/;
15
+ const SESSION_PREFIX = "po-runner-";
16
+ const OWNED_TARGET_PATTERN = /^po-runner-[A-Za-z0-9_-]+$/;
17
17
  const NON_INTERACTIVE_ENV = {
18
18
  NO_COLOR: "1",
19
19
  CI: "1"
@@ -506,4 +506,4 @@ function errorMessage(error) {
506
506
  //#endregion
507
507
  export { rmuxPackageForTarget as n, RmuxBackend as t };
508
508
 
509
- //# sourceMappingURL=rmuxBackend-DfyQwJrc.mjs.map
509
+ //# sourceMappingURL=rmuxBackend-rjrVTG6K.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rmuxBackend-rjrVTG6K.mjs","names":[],"sources":["../src/constants/rmuxBackend.ts","../src/services/rmuxBackend/index.ts"],"sourcesContent":["export const RMUX_BINARY_ENV = 'PO_RMUX_BINARY';\nexport const POLL_MS = 100;\nexport const LOG_DRAIN_TIMEOUT_MS = 2_000;\n/**\n * Fallback interval for a missed log-completion event or a lost session.\n * The retained pane lets the sink write its marker before session cleanup.\n */\nexport const LOG_DRAIN_POLL_MS = 25;\nexport const PANE_STATE_FORMAT = '#{pane_dead}:#{pane_dead_status}:#{session_name}';\nexport const PANE_PID_FORMAT = '#{pane_pid}';\nexport const STOP_GRACE_MS = 3_000;\nexport const STOP_CLOSE_TIMEOUT_MS = 1_000;\nexport const EXECUTABLE_MODE = 0o755;\n/** The owner, group, and other execute bits, so an already runnable file is left alone. */\nexport const EXECUTABLE_BITS = 0o111;\nexport const VENDOR_DIRECTORY = 'vendor';\nexport const SESSION_PREFIX = 'po-runner-';\nexport const OWNED_TARGET_PATTERN = /^po-runner-[A-Za-z0-9_-]+$/;\nexport const SOCKET_HASH_LENGTH = 12;\nexport const NON_INTERACTIVE_ENV = { NO_COLOR: '1', CI: '1' };\n","import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport { type Pane, RMUX, type Rmux } from '@rmux/sdk';\n\nimport {\n EXECUTABLE_BITS,\n EXECUTABLE_MODE,\n LOG_DRAIN_POLL_MS,\n LOG_DRAIN_TIMEOUT_MS,\n NON_INTERACTIVE_ENV,\n OWNED_TARGET_PATTERN,\n PANE_PID_FORMAT,\n PANE_STATE_FORMAT,\n POLL_MS,\n RMUX_BINARY_ENV,\n SESSION_PREFIX,\n SOCKET_HASH_LENGTH,\n STOP_CLOSE_TIMEOUT_MS,\n STOP_GRACE_MS,\n VENDOR_DIRECTORY,\n} from '../../constants/rmuxBackend';\nimport type { RunHandle } from '../../types/launcher';\nimport type { PtyRun } from '../../types/ptyHost';\nimport type { IRmuxBackend, RmuxLaunchRequest } from '../../types/rmuxBackend';\nimport type { RunnerSettings } from '../../types/runnerSettings';\nimport type { ExitResult } from '../../types/spawner';\nimport { getLogMaxBytes, getResultMaxBytes, noninteractiveEnvironment } from '../runnerConfig';\nimport type { IRunnerPaths } from '../runnerPaths/type';\nimport {\n cleanupSupervisorFiles,\n type CommandSpec,\n NO_TERMINAL_INPUT_ENV,\n readExitMetadata,\n runtimeEntry,\n shellJoin,\n type SupervisorPaths,\n supervisorPaths,\n watchForFile,\n writeCommandSpec,\n} from '../runnerSupervisor';\n\n/** Pane liveness, its exit status, and whether the session still exists, in one read. */\nconst PACKAGE_BY_PLATFORM: Readonly<Record<string, string>> = {\n 'darwin-arm64': '@agimon-ai/po-runner-rmux-darwin-arm64',\n 'darwin-x64': '@agimon-ai/po-runner-rmux-darwin-x64',\n 'linux-arm64': '@agimon-ai/po-runner-rmux-linux-arm64',\n 'linux-x64': '@agimon-ai/po-runner-rmux-linux-x64',\n};\n\nexport class RmuxBackend implements IRmuxBackend {\n private clientPromise: Promise<Rmux | undefined> | undefined;\n private readonly runs = new Map<string, PtyRun>();\n private readonly completions = new Map<string, Promise<ExitResult>>();\n\n constructor(\n private readonly paths: IRunnerPaths,\n private readonly env: Readonly<Record<string, string | undefined>> = process.env,\n private readonly settings?: RunnerSettings,\n ) {}\n\n async launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined> {\n const rmux = await this.client();\n if (!rmux) return undefined;\n\n this.paths.ensureDirectories();\n const target = `${SESSION_PREFIX}${request.id}`;\n const logPath = this.paths.logPathFor(request.id);\n const aux = this.auxPaths(request.id, request.sessionId);\n let created = false;\n let released = false;\n\n try {\n this.prepareFiles(request, logPath, aux);\n // `-P -F` reports the pane pid from the call that creates the pane, so the\n // launch does not spend a second round trip asking for it.\n const opened = await rmux.cmd(\n 'new-session',\n '-d',\n '-P',\n '-F',\n PANE_PID_FORMAT,\n '-s',\n target,\n '-c',\n request.cwd,\n process.execPath,\n runtimeEntry('runnerHost'),\n aux.spec,\n aux.gate,\n aux.exit,\n { check: true },\n );\n created = true;\n // Keep the pane until the log reader drains. Otherwise a fast shell can\n // end the session before the reader starts, losing its final output.\n await rmux.cmd('set-option', '-t', target, 'remain-on-exit', 'on', { check: true });\n await rmux.cmd('pipe-pane', '-t', target, this.logPipeCommand(logPath, aux.logDone, request), { check: true });\n\n const pane = rmux.session(target).pane(0, 0);\n const pid = reportedPid(String(opened.stdout ?? '')) ?? (await panePid(rmux, target));\n fs.writeFileSync(aux.gate, '', { mode: 0o600 });\n released = true;\n\n let buffering = true;\n const completion = this.monitor(rmux, pane, target, aux);\n this.trackCompletion(target, completion);\n const stop = (): Promise<boolean> => this.stop(target, pid);\n const handle: RunHandle = {\n id: request.id,\n name: request.name,\n pid,\n logPath,\n backend: 'rmux',\n backendTarget: target,\n output: () => (buffering ? readTail(logPath, getResultMaxBytes(this.env, this.settings) * 2) : ''),\n completion: () => completion,\n detach: () => {\n buffering = false;\n },\n stop,\n };\n\n if (request.interactive) this.runs.set(request.name, this.interactiveRun(handle, pane, completion));\n void completion\n .finally(() => this.runs.delete(request.name))\n .catch((error: unknown) => process.emitWarning(`RMUX completion failed for ${target}: ${errorMessage(error)}`));\n return handle;\n } catch (error) {\n if (released) throw error;\n if (created) {\n await rmux\n .session(target)\n .kill()\n .catch((cleanupError: unknown) =>\n process.emitWarning(`Could not clean up failed RMUX launch ${target}: ${errorMessage(cleanupError)}`),\n );\n }\n cleanupSupervisorFiles(aux);\n process.emitWarning(\n request.interactive\n ? `RMUX launch unavailable for interactive runner: ${errorMessage(error)}`\n : `RMUX launch unavailable, using supervised subprocess: ${errorMessage(error)}`,\n );\n return undefined;\n }\n }\n\n async stop(target: string, expectedPid: number): Promise<boolean> {\n if (!OWNED_TARGET_PATTERN.test(target) || !Number.isInteger(expectedPid) || expectedPid <= 0) return false;\n\n const rmux = await this.client();\n if (!rmux) return false;\n try {\n // A session that already ended took its process group with it.\n if (await sessionMissing(rmux, target)) return true;\n\n const pid = await panePid(rmux, target);\n if (pid !== expectedPid) return false;\n const signalled = signalPane(pid, target);\n if (signalled === 'gone') return true;\n if (signalled === 'failed') return false;\n\n if (await waitForPaneStop(rmux, target, STOP_GRACE_MS)) return true;\n if (await sessionMissing(rmux, target)) return true;\n\n // Revalidate after the grace period so a replacement pane is never closed.\n const currentPid = await panePid(rmux, target);\n if (currentPid !== expectedPid) return false;\n\n return closeOwnedSession(rmux, target);\n } catch (error) {\n process.emitWarning(`Could not stop RMUX target ${target}: ${errorMessage(error)}`);\n return false;\n }\n }\n\n async watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined> {\n const rmux = await this.client();\n if (!rmux) return undefined;\n const pane = rmux.session(target).pane(0, 0);\n try {\n await rmux.displayMessage('#{pane_id}', { target });\n } catch (error) {\n process.emitWarning(`Could not watch RMUX target ${target}: ${errorMessage(error)}`);\n return undefined;\n }\n const completion = this.monitor(rmux, pane, target, this.auxPaths(id, sessionId));\n this.trackCompletion(target, completion);\n return completion;\n }\n\n async input(target: string, text: string): Promise<boolean> {\n const rmux = await this.client();\n if (!rmux) return false;\n const result = await rmux\n .session(target)\n .pane(0, 0)\n .sendText(text)\n .catch((error: unknown) => {\n process.emitWarning(`Could not send input to RMUX target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result !== undefined;\n }\n\n async capture(target: string): Promise<string | undefined> {\n const rmux = await this.client();\n if (!rmux) return undefined;\n return rmux\n .session(target)\n .pane(0, 0)\n .captureText()\n .catch((error: unknown) => {\n process.emitWarning(`Could not capture RMUX target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n }\n\n get(name: string): PtyRun | undefined {\n return this.runs.get(name);\n }\n\n readOutcome(id: string, sessionId: string): ExitResult | undefined {\n return readExitMetadata(this.auxPaths(id, sessionId).exit);\n }\n\n private trackCompletion(target: string, completion: Promise<ExitResult>): void {\n this.completions.set(target, completion);\n void completion\n .finally(() => this.completions.delete(target))\n .catch((error: unknown) => process.emitWarning(`RMUX monitor failed for ${target}: ${errorMessage(error)}`));\n }\n\n private client(): Promise<Rmux | undefined> {\n this.clientPromise ??= this.resolveClient();\n return this.clientPromise;\n }\n\n private async resolveClient(): Promise<Rmux | undefined> {\n const binaries = [resolveBundledRmuxBinary(import.meta.url, this.env), 'rmux'].filter(\n (value): value is string => value !== undefined,\n );\n for (const binary of binaries) {\n try {\n if (binary !== 'rmux') ensureExecutablePayload(binary);\n const client = new RMUX({ binary, socketName: socketName(this.paths.repositoryPath()) });\n await client.capabilities();\n return client;\n } catch (error) {\n process.emitWarning(`RMUX candidate ${binary} is unavailable: ${errorMessage(error)}`);\n // Try the next compatible candidate. Non-interactive calls can use the subprocess launcher.\n }\n }\n return undefined;\n }\n\n private prepareFiles(request: RmuxLaunchRequest, logPath: string, aux: SupervisorPaths): void {\n cleanupSupervisorFiles(aux);\n fs.writeFileSync(logPath, '', { mode: 0o600 });\n const env = environment(request.sessionId, request.interactive, this.env);\n // runnerHost supervises the command and watches the lifeline itself, so an\n // owner that dies mid-run is handled inside the pane rather than around it.\n const spec: CommandSpec = { command: request.command, cwd: request.cwd, env };\n writeCommandSpec(aux.spec, spec);\n }\n\n private auxPaths(id: string, sessionId?: string): SupervisorPaths {\n return supervisorPaths(this.paths.stateDirectory(sessionId), id);\n }\n\n /**\n * The sink the pane pipes into.\n *\n * An interactive run also asks for a raw copy: the scrubbed log it writes\n * beside it has had cursor movement taken out, which is what a terminal\n * needs most. Only interactive runs pay for it, because only they can be\n * attached to.\n */\n private logPipeCommand(logPath: string, donePath: string, request: RmuxLaunchRequest): string {\n const id = path.basename(logPath, '.log');\n return shellJoin([\n process.execPath,\n runtimeEntry('logSink'),\n logPath,\n this.paths.rotatedLogPathFor(id),\n String(getLogMaxBytes(this.env)),\n donePath,\n ...(request.interactive ? [this.paths.rawLogPathFor(id)] : []),\n ]);\n }\n\n private async monitor(rmux: Rmux, pane: Pane, target: string, aux: SupervisorPaths): Promise<ExitResult> {\n try {\n const paneCode = await waitForRunEnd(rmux, target, aux.exit);\n await waitForLogDrain(rmux, target, aux.logDone);\n return readExitMetadata(aux.exit) ?? { code: paneCode, signal: null };\n } finally {\n // The pane stays alive for log capture. Remove its session after draining,\n // allowing the last completed run to shut down the mux server too.\n let timer: ReturnType<typeof setTimeout> | undefined;\n const cleanup = async (): Promise<void> => {\n if (!(await sessionMissing(rmux, target))) await pane.server.session(target).kill();\n };\n try {\n await Promise.race([\n cleanup().catch((error: unknown) =>\n process.emitWarning(`Could not clean up completed RMUX target ${target}: ${errorMessage(error)}`),\n ),\n new Promise<void>((resolve) => {\n timer = setTimeout(() => {\n process.emitWarning(`Timed out cleaning up RMUX target ${target} after ${STOP_CLOSE_TIMEOUT_MS}ms`);\n resolve();\n }, STOP_CLOSE_TIMEOUT_MS);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n cleanupSupervisorFiles(aux);\n }\n }\n }\n\n private interactiveRun(handle: RunHandle, pane: Pane, completion: Promise<ExitResult>): PtyRun {\n let screen = '';\n let active = true;\n const handlers = new Set<(data: string) => void>();\n const refresh = async (): Promise<void> => {\n while (active) {\n const next = await pane.captureText().catch((error: unknown) => {\n process.emitWarning(`Could not capture RMUX screen for ${handle.name}: ${errorMessage(error)}`);\n return screen;\n });\n if (next !== screen) {\n screen = next;\n for (const handler of handlers) handler(next);\n }\n await delay(POLL_MS);\n }\n };\n void refresh();\n void completion\n .finally(() => {\n active = false;\n })\n .catch((error: unknown) =>\n process.emitWarning(`RMUX interactive completion failed for ${handle.name}: ${errorMessage(error)}`),\n );\n return {\n ...handle,\n write: (text) => {\n void pane.sendText(text).catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n screen: () => screen,\n onData: (handler) => {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n resize: (cols, rows) => {\n void pane\n .resize({ width: cols, height: rows })\n .catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n };\n }\n}\n\nexport function rmuxPackageForTarget(platform: string, architecture: string): string | undefined {\n const target = `${platform}-${architecture}`;\n const packageName = PACKAGE_BY_PLATFORM[target];\n if (!packageName) process.emitWarning(`Bundled RMUX binary is unavailable for unsupported target ${target}`);\n return packageName;\n}\n\nexport function resolveBundledRmuxBinary(\n moduleUrl = import.meta.url,\n env: Readonly<Record<string, string | undefined>> = process.env,\n): string | undefined {\n const configured = env[RMUX_BINARY_ENV];\n if (configured !== undefined && configured !== '') return configured;\n const packageName = rmuxPackageForTarget(process.platform, process.arch);\n if (!packageName) return undefined;\n try {\n const require = createRequire(moduleUrl);\n const manifest = require.resolve(`${packageName}/package.json`);\n return path.join(path.dirname(manifest), VENDOR_DIRECTORY, 'bin', 'rmux');\n } catch (error) {\n process.emitWarning(`Bundled RMUX binary is unavailable for ${packageName}: ${errorMessage(error)}`);\n return undefined;\n }\n}\n\n/**\n * Make the bundled payload runnable before the launcher is spawned.\n *\n * The prebuilt packages reach npm with plain 0644 files, so the executable bit\n * the build set is not what lands on a user machine. Restoring it on the one\n * binary we spawn is not enough: rmux execs two files of its own,\n * `bin/rmux-daemon` and `libexec/rmux/rmux`, and the launcher fails on that\n * first exec with a permission error. Every file the payload ships is restored\n * here instead, which also covers a helper a later rmux release adds.\n *\n * A configured override (PO_RMUX_BINARY) usually points at a stand-alone\n * binary, so only paths that really sit inside a package vendor tree get the\n * walk. Files that are already executable are left untouched, since chmod on a\n * binary owned by someone else would throw and drop an otherwise usable\n * candidate.\n */\nexport function ensureExecutablePayload(binary: string): void {\n const vendor = path.resolve(path.dirname(binary), '..');\n const payload =\n path.basename(vendor) === VENDOR_DIRECTORY\n ? fs\n .readdirSync(vendor, { recursive: true, withFileTypes: true })\n .filter((entry) => entry.isFile())\n .map((entry) => path.join(entry.parentPath, entry.name))\n : [binary];\n for (const file of payload) {\n if ((fs.statSync(file).mode & EXECUTABLE_BITS) === 0) fs.chmodSync(file, EXECUTABLE_MODE);\n }\n}\n\nfunction socketName(repositoryPath: string): string {\n const hash = createHash('sha256').update(repositoryPath).digest('hex').slice(0, SOCKET_HASH_LENGTH);\n return `${SESSION_PREFIX}${hash}`;\n}\n\nfunction environment(\n sessionId: string,\n interactive: boolean,\n env: Readonly<Record<string, string | undefined>>,\n): Record<string, string> {\n const values: NodeJS.ProcessEnv = {\n ...env,\n ...(interactive ? {} : { ...NON_INTERACTIVE_ENV, ...noninteractiveEnvironment(env) }),\n // Applied to interactive runs as well: a pane is a tty either way, and an\n // agent sending input to a prompt still has no way past a pager.\n ...NO_TERMINAL_INPUT_ENV,\n PI_SESSION_ID: sessionId,\n };\n if (!interactive) delete values['FORCE_COLOR'];\n return Object.fromEntries(\n Object.entries(values).filter((entry): entry is [string, string] => entry[1] !== undefined),\n );\n}\n\nasync function panePid(rmux: Rmux, target: string): Promise<number> {\n const response = await rmux.displayMessage(PANE_PID_FORMAT, { target });\n const message = typeof response['message'] === 'string' ? response['message'] : '';\n const pid = reportedPid(message);\n if (pid === undefined) throw new Error(`RMUX did not report a pane pid for ${target}`);\n return pid;\n}\n\n/** A pane pid as rmux prints it, or nothing when the output holds no usable pid. */\nfunction reportedPid(output: string): number | undefined {\n const pid = Number(output.trim());\n return Number.isInteger(pid) && pid > 0 ? pid : undefined;\n}\n\n/**\n * Waits for the run to end, preferring the supervisor's own record of it.\n *\n * The sidecar is written before the command's pane can end, and it outlives the\n * server that the pane's exit takes down with it. Watching for it means a run\n * that finishes inside a poll interval is observed when it finishes rather than\n * on the next tick. Asking the server stays the fallback for a supervisor that\n * died without recording anything.\n */\nasync function waitForRunEnd(rmux: Rmux, target: string, exitPath: string): Promise<number | null> {\n const landed = watchForFile(exitPath);\n let active = true;\n const readEvidence = async (): Promise<null> => {\n while (active) {\n if (await landed.appeared(POLL_MS)) return null;\n }\n return null;\n };\n const probePane = async (): Promise<number | null> => {\n while (active) {\n await delay(POLL_MS);\n if (!active) return null;\n const state = await readPaneExit(rmux, target);\n if (state.exited) return state.code;\n }\n return null;\n };\n try {\n // A stalled SDK request must not block the supervisor's durable evidence.\n // Keep only one pane request in flight, even when it never answers.\n return await Promise.race([readEvidence(), probePane()]);\n } finally {\n active = false;\n landed.close();\n }\n}\n\n/**\n * Gives the log sink a moment to mark the log complete.\n *\n * Normal completion retains the session until the sink records its final\n * writes. A lost session cannot guarantee a later marker, so it ends the wait.\n */\nasync function waitForLogDrain(rmux: Rmux, target: string, donePath: string): Promise<void> {\n const deadline = Date.now() + LOG_DRAIN_TIMEOUT_MS;\n const landed = watchForFile(donePath);\n let active = true;\n const readEvidence = async (): Promise<void> => {\n while (active && Date.now() < deadline) {\n if (await landed.appeared(LOG_DRAIN_POLL_MS)) return;\n }\n };\n const probeSession = async (): Promise<void> => {\n while (active && Date.now() < deadline) {\n await delay(LOG_DRAIN_POLL_MS);\n if (!active) return;\n if (await sessionMissing(rmux, target)) return;\n }\n };\n try {\n // The file loop enforces the deadline while a session query is outstanding.\n await Promise.race([readEvidence(), probeSession()]);\n } finally {\n active = false;\n landed.close();\n }\n}\n\nasync function closeOwnedSession(rmux: Rmux, target: string): Promise<boolean> {\n return new Promise((resolve) => {\n let settled = false;\n const finish = (result: boolean): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(result);\n };\n const timer = setTimeout(() => {\n process.emitWarning(`Timed out closing RMUX target ${target} after ${STOP_CLOSE_TIMEOUT_MS}ms`);\n finish(false);\n }, STOP_CLOSE_TIMEOUT_MS);\n void rmux\n .session(target)\n .kill()\n .then(\n () => finish(true),\n (error: unknown) => {\n process.emitWarning(`Could not close RMUX target ${target}: ${errorMessage(error)}`);\n finish(false);\n },\n );\n });\n}\n\nasync function waitForPaneStop(rmux: Rmux, target: string, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n try {\n if ((await readPaneExit(rmux, target)).exited) return true;\n } catch (error) {\n process.emitWarning(`Could not verify RMUX target ${target} stopped: ${errorMessage(error)}`);\n return false;\n }\n await delay(POLL_MS);\n }\n return false;\n}\n\n/**\n * One formatted read answers both questions this poll asks, so watching a run\n * costs the same single rmux call it always did.\n */\nasync function readPaneExit(rmux: Rmux, target: string): Promise<{ exited: boolean; code: number | null }> {\n let message: string;\n try {\n const response = await rmux.displayMessage(PANE_STATE_FORMAT, { target });\n message = typeof response['message'] === 'string' ? response['message'] : '';\n } catch {\n // The last session ending stops the server, so a server that cannot be\n // reached is the ordinary end of the last run rather than a fault.\n return { exited: true, code: null };\n }\n const [dead, status, ...rest] = message.trim().split(':');\n // A missing session formats as a live pane with no name rather than failing,\n // so the name is what says whether there is still anything to watch.\n if (rest.join(':') === '') return { exited: true, code: null };\n if (dead === '1' || dead === 'true') {\n const code = Number(status);\n return { exited: true, code: Number.isInteger(code) ? code : null };\n }\n return { exited: false, code: null };\n}\n\n/** A session that cannot be found, on a server that may itself be gone. */\nasync function sessionMissing(rmux: Rmux, target: string): Promise<boolean> {\n try {\n const probe = await rmux.cmd('has-session', '-t', target);\n return probe.returnCode !== 0;\n } catch {\n // No server to ask means no session to find.\n return true;\n }\n}\n\n/**\n * A pane that was already gone and a signal that could not be delivered are\n * opposite answers to \"is it stopped\", so they are reported apart.\n */\nfunction signalPane(pid: number, target: string): 'signalled' | 'gone' | 'failed' {\n try {\n process.kill(pid, 'SIGTERM');\n return 'signalled';\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ESRCH') return 'gone';\n process.emitWarning(`Could not signal RMUX target ${target}: ${errorMessage(error)}`);\n return 'failed';\n }\n}\n\nfunction readTail(target: string, maxBytes: number): string {\n let handle: number | undefined;\n try {\n const size = fs.statSync(target).size;\n const bytes = Math.min(size, maxBytes);\n const buffer = Buffer.alloc(bytes);\n handle = fs.openSync(target, 'r');\n fs.readSync(handle, buffer, 0, bytes, size - bytes);\n return buffer.toString('utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n process.emitWarning(`Could not read RMUX log ${target}: ${errorMessage(error)}`);\n }\n return '';\n } finally {\n if (handle !== undefined) fs.closeSync(handle);\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n timer.unref?.();\n });\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_rmuxBackend = require("./rmuxBackend-DlxgqRZ1.cjs");
2
+ const require_rmuxBackend = require("./rmuxBackend-Dh0CYVAL.cjs");
3
3
  exports.RmuxBackend = require_rmuxBackend.RmuxBackend;
4
4
  exports.rmuxPackageForTarget = require_rmuxBackend.rmuxPackageForTarget;
@@ -1,3 +1,3 @@
1
1
  import { n as RmuxLaunchRequest, t as IRmuxBackend } from "./rmuxBackend-CaEWooWn.mjs";
2
- import { n as rmuxPackageForTarget, t as RmuxBackend } from "./index-D9-IXax4.mjs";
2
+ import { n as rmuxPackageForTarget, t as RmuxBackend } from "./index-C-IC35d9.mjs";
3
3
  export { type IRmuxBackend, RmuxBackend, type RmuxLaunchRequest, rmuxPackageForTarget };
@@ -1,2 +1 @@
1
- import { n as rmuxPackageForTarget, t as RmuxBackend } from "./rmuxBackend-DfyQwJrc.mjs";
2
- export { RmuxBackend, rmuxPackageForTarget };
1
+ export { t as RmuxBackend, n as rmuxPackageForTarget } from "./rmuxBackend-rjrVTG6K.mjs";
@@ -1,11 +1,11 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
2
2
  const require_rtkProcessor = require("./rtkProcessor-CsrCPyTQ.cjs");
3
- const require_runnerConfig = require("./runnerConfig-D2tGq5ZM.cjs");
3
+ const require_runnerConfig = require("./runnerConfig-BoLMinlx.cjs");
4
4
  let node_fs = require("node:fs");
5
5
  node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
6
+ let node_module = require("node:module");
6
7
  let node_path = require("node:path");
7
8
  node_path = require_rolldown_runtime.__toESM(node_path, 1);
8
- let node_module = require("node:module");
9
9
  let node_child_process = require("node:child_process");
10
10
  //#region src/constants/rtkProcessor.ts
11
11
  const RTK_STDIN_MAX_BYTES = 10485760;
@@ -74,7 +74,7 @@ var RtkProcessor = class {
74
74
  * Latched once a binary proves unrunnable on this host.
75
75
  *
76
76
  * A glibc build installed on a musl host satisfies os and cpu, so it
77
- * resolves and then fails to exec. Without this the same doomed spawn is
77
+ * resolves and then fails to exec. Without this the same poed spawn is
78
78
  * paid on every command, and each one is reported as a processing failure
79
79
  * rather than the absence it actually is.
80
80
  */
@@ -332,4 +332,4 @@ Object.defineProperty(exports, "rtkPackageForTarget", {
332
332
  }
333
333
  });
334
334
 
335
- //# sourceMappingURL=rtkProcessor-Bc4L4o_8.cjs.map
335
+ //# sourceMappingURL=rtkProcessor-DSGbM-Cm.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rtkProcessor-DSGbM-Cm.cjs","names":["fs","RTK_FAILED_WARNING","RTK_OVERSIZED_WARNING","RTK_UNAVAILABLE_WARNING","spawn","getResultMaxBytes","RTK_TIMEOUT_WARNING","createRequire","path"],"sources":["../src/constants/rtkProcessor.ts","../src/services/rtkProcessor/index.ts"],"sourcesContent":["export const BYTES_PER_MIB = 1_048_576;\nexport const RTK_STDIN_MAX_BYTES = 10_485_760;\nexport const DEFAULT_RTK_TIMEOUT_MS = 10_000;\nexport const RTK_KILL_WAIT_MS = 1_000;\nexport const OUTPUT_BUFFER_FACTOR = 2;\nexport const EXECUTABLE_MODE = 0o755;\nexport const SIMPLE_TOKEN_PATTERN = /^[A-Za-z0-9_./:@%+=,-]+$/u;\nexport const SHELL_CONTROL_PATTERN = /[\\r\\n;&|<>`$\\\\'\"(){}*?!]/u;\nexport const RTK_BINARY_ENV = 'PO_RTK_BINARY';\n","import { type ChildProcessWithoutNullStreams, spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport {\n DEFAULT_RTK_TIMEOUT_MS,\n EXECUTABLE_MODE,\n OUTPUT_BUFFER_FACTOR,\n RTK_BINARY_ENV,\n RTK_KILL_WAIT_MS,\n RTK_STDIN_MAX_BYTES,\n SHELL_CONTROL_PATTERN,\n SIMPLE_TOKEN_PATTERN,\n} from '../../constants/rtkProcessor';\nimport {\n type IRtkProcessor,\n RTK_FAILED_WARNING,\n RTK_OVERSIZED_WARNING,\n RTK_TIMEOUT_WARNING,\n RTK_UNAVAILABLE_WARNING,\n type RtkFilter,\n type RtkProcessRequest,\n type RtkProcessResult,\n} from '../../types/rtkProcessor';\nimport type { RunnerSettings } from '../../types/runnerSettings';\nimport { getResultMaxBytes } from '../runnerConfig';\n\nconst GIT_DIFF_INCOMPATIBLE_OPTIONS = [\n '-s',\n '-z',\n '--raw',\n '--numstat',\n '--shortstat',\n '--stat',\n '--dirstat',\n '--dirstat-by-file',\n '--summary',\n '--compact-summary',\n '--name-only',\n '--name-status',\n '--check',\n '--binary',\n '--word-diff',\n '--word-diff-regex',\n '--color',\n '--color-words',\n '--color-moved',\n '--color-moved-ws',\n '--line-prefix',\n '--no-patch',\n '--patch-with-raw',\n '--patch-with-stat',\n '--ext-diff',\n '--textconv',\n '--quiet',\n '--submodule',\n] as const;\nconst STRUCTURED_SEARCH_INCOMPATIBLE_OPTIONS = [\n '--json',\n '--null',\n '--null-data',\n '--color',\n '--colour',\n '--after-context',\n '--before-context',\n '--context',\n '--no-filename',\n '--no-line-number',\n '--heading',\n] as const;\nconst PACKAGE_BY_PLATFORM: Readonly<Record<string, string>> = {\n 'darwin-arm64': '@agimon-ai/po-runner-rtk-darwin-arm64',\n 'darwin-x64': '@agimon-ai/po-runner-rtk-darwin-x64',\n 'linux-arm64': '@agimon-ai/po-runner-rtk-linux-arm64',\n 'linux-x64': '@agimon-ai/po-runner-rtk-linux-x64',\n};\n\ntype BinaryResolver = () => string | undefined;\n\nexport class RtkProcessor implements IRtkProcessor {\n /**\n * Latched once a binary proves unrunnable on this host.\n *\n * A glibc build installed on a musl host satisfies os and cpu, so it\n * resolves and then fails to exec. Without this the same poed spawn is\n * paid on every command, and each one is reported as a processing failure\n * rather than the absence it actually is.\n */\n private unrunnable = false;\n\n constructor(\n private readonly resolveBinary: BinaryResolver = bundledBinary,\n private readonly timeoutMs = DEFAULT_RTK_TIMEOUT_MS,\n private readonly env: Readonly<Record<string, string | undefined>> = process.env,\n private readonly settings?: RunnerSettings,\n ) {}\n\n async process(request: RtkProcessRequest): Promise<RtkProcessResult> {\n const filter = classifyRtkFilter(request.command);\n if (!filter) return { kind: 'skipped' };\n\n let inputBytes: number;\n try {\n inputBytes = fs.statSync(request.logPath).size;\n } catch {\n return { kind: 'fallback', warning: RTK_FAILED_WARNING };\n }\n if (inputBytes > RTK_STDIN_MAX_BYTES) return { kind: 'fallback', warning: RTK_OVERSIZED_WARNING };\n\n if (this.unrunnable) return { kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING };\n\n let binary: string | undefined;\n try {\n binary = this.resolveBinary === bundledBinary ? bundledBinary(this.env) : this.resolveBinary();\n if (!binary) return { kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING };\n if ((fs.statSync(binary).mode & 0o111) === 0) fs.chmodSync(binary, EXECUTABLE_MODE);\n } catch {\n return { kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING };\n }\n\n return this.pipe(binary, filter, request.logPath, inputBytes);\n }\n\n private pipe(binary: string, filter: RtkFilter, logPath: string, inputBytes: number): Promise<RtkProcessResult> {\n return new Promise((resolve) => {\n let child: ChildProcessWithoutNullStreams;\n try {\n child = spawn(binary, ['pipe', '-f', filter], { stdio: 'pipe' });\n } catch {\n this.unrunnable = true;\n resolve({ kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING });\n return;\n }\n\n const input = fs.createReadStream(logPath);\n const outputLimit = getResultMaxBytes(this.env, this.settings) * OUTPUT_BUFFER_FACTOR;\n let head: Buffer<ArrayBufferLike> = Buffer.alloc(0);\n let output: Buffer<ArrayBufferLike> = Buffer.alloc(0);\n let outputBytes = 0;\n let newlineCount = 0;\n let lastByte: number | undefined;\n let settled = false;\n let fallbackWarning: string | undefined;\n let killWaitTimer: ReturnType<typeof setTimeout> | undefined;\n\n const finish = (result: RtkProcessResult): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n if (killWaitTimer) clearTimeout(killWaitTimer);\n input.destroy();\n resolve(result);\n };\n const stop = (warning: string): void => {\n if (settled) return;\n fallbackWarning = warning;\n let killed = false;\n try {\n killed = child.kill('SIGKILL');\n } catch {\n finish({ kind: 'fallback', warning });\n return;\n }\n if (!killed) {\n finish({ kind: 'fallback', warning });\n return;\n }\n killWaitTimer ??= setTimeout(() => finish({ kind: 'fallback', warning }), RTK_KILL_WAIT_MS);\n };\n const timer = setTimeout(() => stop(RTK_TIMEOUT_WARNING), this.timeoutMs);\n\n child.stdout.on('data', (chunk: Buffer) => {\n outputBytes += chunk.byteLength;\n for (const byte of chunk) if (byte === 0x0a) newlineCount += 1;\n lastByte = chunk.at(-1);\n if (head.byteLength < outputLimit) {\n head = Buffer.concat([head, chunk.subarray(0, outputLimit - head.byteLength)]);\n }\n output = appendTail(output, chunk, outputLimit);\n });\n child.stderr.resume();\n child.once('error', (error: NodeJS.ErrnoException) => {\n // Reaching the process is a precondition, not part of processing, so a\n // failure to start reports absence and is not attempted again.\n if (error.code === 'ENOENT' || error.code === 'EACCES' || error.code === 'ENOEXEC') {\n this.unrunnable = true;\n stop(RTK_UNAVAILABLE_WARNING);\n return;\n }\n stop(RTK_FAILED_WARNING);\n });\n child.stdin.once('error', () => stop(RTK_FAILED_WARNING));\n input.once('error', () => stop(RTK_FAILED_WARNING));\n child.once('close', (code) => {\n if (fallbackWarning) {\n finish({ kind: 'fallback', warning: fallbackWarning });\n return;\n }\n const processedOutput = decodeUtf8Tail(output);\n if (code !== 0 || (inputBytes > 0 && processedOutput.trim().length === 0)) {\n finish({ kind: 'fallback', warning: RTK_FAILED_WARNING });\n return;\n }\n const lines = newlineCount + (outputBytes > 0 && lastByte !== 0x0a ? 1 : 0);\n finish({\n kind: 'processed',\n result: {\n filter,\n // Only meaningful once the stream outgrew the buffer; below that\n // `output` already starts at byte zero.\n head: outputBytes > output.byteLength ? head.toString('utf8') : '',\n output: processedOutput,\n bytes: outputBytes,\n lines,\n },\n });\n });\n\n input.pipe(child.stdin);\n });\n }\n}\n\n/**\n * Classifies only whitespace-delimited single commands. Shell syntax, expansion,\n * quoting, and globbing are rejected instead of being partially interpreted.\n */\nexport function classifyRtkFilter(command: string): RtkFilter | undefined {\n if (SHELL_CONTROL_PATTERN.test(command)) return undefined;\n const trimmed = command.trim();\n if (!trimmed) return undefined;\n const tokens = trimmed.split(/[ \\t]+/u);\n if (tokens.some((token) => !SIMPLE_TOKEN_PATTERN.test(token))) return undefined;\n\n if (tokens[0] === 'cargo' && tokens[1] === 'test') {\n if (tokens.includes('--') || tokens.some((token) => token.startsWith('--message-format') || token === '--json')) {\n return undefined;\n }\n return 'cargo-test';\n }\n if (tokens[0] === 'pytest') {\n if (tokens.some((token) => token.startsWith('--json-report'))) return undefined;\n return 'pytest';\n }\n if (tokens[0] === 'git' && tokens[1] === 'diff') {\n if (\n tokens.some((token) =>\n GIT_DIFF_INCOMPATIBLE_OPTIONS.some((option) => token === option || token.startsWith(`${option}=`)),\n )\n ) {\n return undefined;\n }\n return 'git-diff';\n }\n if (tokens[0] === 'grep') {\n if (tokens.length < 4 || incompatibleStructuredSearch(tokens)) return undefined;\n return hasShortOrLongOption(tokens, 'n', '--line-number') && hasShortOrLongOption(tokens, 'H', '--with-filename')\n ? 'grep'\n : undefined;\n }\n if (tokens[0] === 'rg') {\n if (tokens.length < 4 || incompatibleStructuredSearch(tokens) || !tokens.includes('--no-heading')) return undefined;\n return hasShortOrLongOption(tokens, 'n', '--line-number') && hasShortOrLongOption(tokens, 'H', '--with-filename')\n ? 'grep'\n : undefined;\n }\n if (tokens[0] === 'go' && tokens[1] === 'test') {\n let jsonOutput = false;\n for (const token of tokens.slice(2)) {\n if (token === '-json' || token === '-json=true') jsonOutput = true;\n if (token === '-json=false') jsonOutput = false;\n }\n return jsonOutput ? 'go-test' : undefined;\n }\n if (tokens[0] === 'ruff' && tokens[1] === 'check') {\n const jsonOutput = tokens.some(\n (token, index) =>\n token === '--output-format=json' || (token === '--output-format' && tokens[index + 1] === 'json'),\n );\n return jsonOutput ? 'ruff-check' : undefined;\n }\n return undefined;\n}\n\nexport function rtkPackageForTarget(platform: string, architecture: string): string | undefined {\n const target = `${platform}-${architecture}`;\n const packageName = PACKAGE_BY_PLATFORM[target];\n if (!packageName) process.emitWarning(`Bundled RTK binary is unavailable for unsupported target ${target}`);\n return packageName;\n}\n\nfunction bundledBinary(env: Readonly<Record<string, string | undefined>> = process.env): string | undefined {\n const configured = env[RTK_BINARY_ENV];\n if (configured !== undefined && configured !== '') return configured;\n const packageName = rtkPackageForTarget(process.platform, process.arch);\n if (!packageName) return undefined;\n try {\n const require = createRequire(import.meta.url);\n const manifest = require.resolve(`${packageName}/package.json`);\n return path.join(path.dirname(manifest), 'vendor', 'bin', 'rtk');\n } catch {\n return undefined;\n }\n}\n\nfunction appendTail(\n current: Buffer<ArrayBufferLike>,\n chunk: Buffer<ArrayBufferLike>,\n limit: number,\n): Buffer<ArrayBufferLike> {\n if (chunk.byteLength >= limit) return Buffer.from(chunk.subarray(chunk.byteLength - limit));\n const combined = Buffer.concat([current, chunk]);\n return combined.byteLength > limit ? Buffer.from(combined.subarray(combined.byteLength - limit)) : combined;\n}\n\nfunction decodeUtf8Tail(output: Buffer<ArrayBufferLike>): string {\n let start = 0;\n while (start < output.byteLength && (output[start]! & 0xc0) === 0x80) start += 1;\n return output.subarray(start).toString('utf8');\n}\nfunction hasShortOrLongOption(tokens: readonly string[], short: string, long: string): boolean {\n return tokens.some(\n (token) => token === long || (token.startsWith('-') && !token.startsWith('--') && token.slice(1).includes(short)),\n );\n}\n\nfunction incompatibleStructuredSearch(tokens: readonly string[]): boolean {\n return tokens.some(\n (token) =>\n (token.startsWith('-') && !token.startsWith('--') && /[0ABCILNchzZ]/u.test(token.slice(1))) ||\n STRUCTURED_SEARCH_INCOMPATIBLE_OPTIONS.some((option) => token === option || token.startsWith(`${option}=`)),\n );\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { i as RTK_UNAVAILABLE_WARNING, n as RTK_OVERSIZED_WARNING, r as RTK_TIMEOUT_WARNING, t as RTK_FAILED_WARNING } from "./rtkProcessor-B4_urXQr.mjs";
2
- import { u as getResultMaxBytes } from "./runnerConfig-BQBlVAXn.mjs";
2
+ import { u as getResultMaxBytes } from "./runnerConfig-XXMq4VQA.mjs";
3
3
  import { createRequire } from "node:module";
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
@@ -71,7 +71,7 @@ var RtkProcessor = class {
71
71
  * Latched once a binary proves unrunnable on this host.
72
72
  *
73
73
  * A glibc build installed on a musl host satisfies os and cpu, so it
74
- * resolves and then fails to exec. Without this the same doomed spawn is
74
+ * resolves and then fails to exec. Without this the same poed spawn is
75
75
  * paid on every command, and each one is reported as a processing failure
76
76
  * rather than the absence it actually is.
77
77
  */
@@ -306,4 +306,4 @@ function incompatibleStructuredSearch(tokens) {
306
306
  //#endregion
307
307
  export { RTK_STDIN_MAX_BYTES as i, classifyRtkFilter as n, rtkPackageForTarget as r, RtkProcessor as t };
308
308
 
309
- //# sourceMappingURL=rtkProcessor-B9KPdyzr.mjs.map
309
+ //# sourceMappingURL=rtkProcessor-Iw9gP5Xp.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rtkProcessor-Iw9gP5Xp.mjs","names":[],"sources":["../src/constants/rtkProcessor.ts","../src/services/rtkProcessor/index.ts"],"sourcesContent":["export const BYTES_PER_MIB = 1_048_576;\nexport const RTK_STDIN_MAX_BYTES = 10_485_760;\nexport const DEFAULT_RTK_TIMEOUT_MS = 10_000;\nexport const RTK_KILL_WAIT_MS = 1_000;\nexport const OUTPUT_BUFFER_FACTOR = 2;\nexport const EXECUTABLE_MODE = 0o755;\nexport const SIMPLE_TOKEN_PATTERN = /^[A-Za-z0-9_./:@%+=,-]+$/u;\nexport const SHELL_CONTROL_PATTERN = /[\\r\\n;&|<>`$\\\\'\"(){}*?!]/u;\nexport const RTK_BINARY_ENV = 'PO_RTK_BINARY';\n","import { type ChildProcessWithoutNullStreams, spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport {\n DEFAULT_RTK_TIMEOUT_MS,\n EXECUTABLE_MODE,\n OUTPUT_BUFFER_FACTOR,\n RTK_BINARY_ENV,\n RTK_KILL_WAIT_MS,\n RTK_STDIN_MAX_BYTES,\n SHELL_CONTROL_PATTERN,\n SIMPLE_TOKEN_PATTERN,\n} from '../../constants/rtkProcessor';\nimport {\n type IRtkProcessor,\n RTK_FAILED_WARNING,\n RTK_OVERSIZED_WARNING,\n RTK_TIMEOUT_WARNING,\n RTK_UNAVAILABLE_WARNING,\n type RtkFilter,\n type RtkProcessRequest,\n type RtkProcessResult,\n} from '../../types/rtkProcessor';\nimport type { RunnerSettings } from '../../types/runnerSettings';\nimport { getResultMaxBytes } from '../runnerConfig';\n\nconst GIT_DIFF_INCOMPATIBLE_OPTIONS = [\n '-s',\n '-z',\n '--raw',\n '--numstat',\n '--shortstat',\n '--stat',\n '--dirstat',\n '--dirstat-by-file',\n '--summary',\n '--compact-summary',\n '--name-only',\n '--name-status',\n '--check',\n '--binary',\n '--word-diff',\n '--word-diff-regex',\n '--color',\n '--color-words',\n '--color-moved',\n '--color-moved-ws',\n '--line-prefix',\n '--no-patch',\n '--patch-with-raw',\n '--patch-with-stat',\n '--ext-diff',\n '--textconv',\n '--quiet',\n '--submodule',\n] as const;\nconst STRUCTURED_SEARCH_INCOMPATIBLE_OPTIONS = [\n '--json',\n '--null',\n '--null-data',\n '--color',\n '--colour',\n '--after-context',\n '--before-context',\n '--context',\n '--no-filename',\n '--no-line-number',\n '--heading',\n] as const;\nconst PACKAGE_BY_PLATFORM: Readonly<Record<string, string>> = {\n 'darwin-arm64': '@agimon-ai/po-runner-rtk-darwin-arm64',\n 'darwin-x64': '@agimon-ai/po-runner-rtk-darwin-x64',\n 'linux-arm64': '@agimon-ai/po-runner-rtk-linux-arm64',\n 'linux-x64': '@agimon-ai/po-runner-rtk-linux-x64',\n};\n\ntype BinaryResolver = () => string | undefined;\n\nexport class RtkProcessor implements IRtkProcessor {\n /**\n * Latched once a binary proves unrunnable on this host.\n *\n * A glibc build installed on a musl host satisfies os and cpu, so it\n * resolves and then fails to exec. Without this the same poed spawn is\n * paid on every command, and each one is reported as a processing failure\n * rather than the absence it actually is.\n */\n private unrunnable = false;\n\n constructor(\n private readonly resolveBinary: BinaryResolver = bundledBinary,\n private readonly timeoutMs = DEFAULT_RTK_TIMEOUT_MS,\n private readonly env: Readonly<Record<string, string | undefined>> = process.env,\n private readonly settings?: RunnerSettings,\n ) {}\n\n async process(request: RtkProcessRequest): Promise<RtkProcessResult> {\n const filter = classifyRtkFilter(request.command);\n if (!filter) return { kind: 'skipped' };\n\n let inputBytes: number;\n try {\n inputBytes = fs.statSync(request.logPath).size;\n } catch {\n return { kind: 'fallback', warning: RTK_FAILED_WARNING };\n }\n if (inputBytes > RTK_STDIN_MAX_BYTES) return { kind: 'fallback', warning: RTK_OVERSIZED_WARNING };\n\n if (this.unrunnable) return { kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING };\n\n let binary: string | undefined;\n try {\n binary = this.resolveBinary === bundledBinary ? bundledBinary(this.env) : this.resolveBinary();\n if (!binary) return { kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING };\n if ((fs.statSync(binary).mode & 0o111) === 0) fs.chmodSync(binary, EXECUTABLE_MODE);\n } catch {\n return { kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING };\n }\n\n return this.pipe(binary, filter, request.logPath, inputBytes);\n }\n\n private pipe(binary: string, filter: RtkFilter, logPath: string, inputBytes: number): Promise<RtkProcessResult> {\n return new Promise((resolve) => {\n let child: ChildProcessWithoutNullStreams;\n try {\n child = spawn(binary, ['pipe', '-f', filter], { stdio: 'pipe' });\n } catch {\n this.unrunnable = true;\n resolve({ kind: 'fallback', warning: RTK_UNAVAILABLE_WARNING });\n return;\n }\n\n const input = fs.createReadStream(logPath);\n const outputLimit = getResultMaxBytes(this.env, this.settings) * OUTPUT_BUFFER_FACTOR;\n let head: Buffer<ArrayBufferLike> = Buffer.alloc(0);\n let output: Buffer<ArrayBufferLike> = Buffer.alloc(0);\n let outputBytes = 0;\n let newlineCount = 0;\n let lastByte: number | undefined;\n let settled = false;\n let fallbackWarning: string | undefined;\n let killWaitTimer: ReturnType<typeof setTimeout> | undefined;\n\n const finish = (result: RtkProcessResult): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n if (killWaitTimer) clearTimeout(killWaitTimer);\n input.destroy();\n resolve(result);\n };\n const stop = (warning: string): void => {\n if (settled) return;\n fallbackWarning = warning;\n let killed = false;\n try {\n killed = child.kill('SIGKILL');\n } catch {\n finish({ kind: 'fallback', warning });\n return;\n }\n if (!killed) {\n finish({ kind: 'fallback', warning });\n return;\n }\n killWaitTimer ??= setTimeout(() => finish({ kind: 'fallback', warning }), RTK_KILL_WAIT_MS);\n };\n const timer = setTimeout(() => stop(RTK_TIMEOUT_WARNING), this.timeoutMs);\n\n child.stdout.on('data', (chunk: Buffer) => {\n outputBytes += chunk.byteLength;\n for (const byte of chunk) if (byte === 0x0a) newlineCount += 1;\n lastByte = chunk.at(-1);\n if (head.byteLength < outputLimit) {\n head = Buffer.concat([head, chunk.subarray(0, outputLimit - head.byteLength)]);\n }\n output = appendTail(output, chunk, outputLimit);\n });\n child.stderr.resume();\n child.once('error', (error: NodeJS.ErrnoException) => {\n // Reaching the process is a precondition, not part of processing, so a\n // failure to start reports absence and is not attempted again.\n if (error.code === 'ENOENT' || error.code === 'EACCES' || error.code === 'ENOEXEC') {\n this.unrunnable = true;\n stop(RTK_UNAVAILABLE_WARNING);\n return;\n }\n stop(RTK_FAILED_WARNING);\n });\n child.stdin.once('error', () => stop(RTK_FAILED_WARNING));\n input.once('error', () => stop(RTK_FAILED_WARNING));\n child.once('close', (code) => {\n if (fallbackWarning) {\n finish({ kind: 'fallback', warning: fallbackWarning });\n return;\n }\n const processedOutput = decodeUtf8Tail(output);\n if (code !== 0 || (inputBytes > 0 && processedOutput.trim().length === 0)) {\n finish({ kind: 'fallback', warning: RTK_FAILED_WARNING });\n return;\n }\n const lines = newlineCount + (outputBytes > 0 && lastByte !== 0x0a ? 1 : 0);\n finish({\n kind: 'processed',\n result: {\n filter,\n // Only meaningful once the stream outgrew the buffer; below that\n // `output` already starts at byte zero.\n head: outputBytes > output.byteLength ? head.toString('utf8') : '',\n output: processedOutput,\n bytes: outputBytes,\n lines,\n },\n });\n });\n\n input.pipe(child.stdin);\n });\n }\n}\n\n/**\n * Classifies only whitespace-delimited single commands. Shell syntax, expansion,\n * quoting, and globbing are rejected instead of being partially interpreted.\n */\nexport function classifyRtkFilter(command: string): RtkFilter | undefined {\n if (SHELL_CONTROL_PATTERN.test(command)) return undefined;\n const trimmed = command.trim();\n if (!trimmed) return undefined;\n const tokens = trimmed.split(/[ \\t]+/u);\n if (tokens.some((token) => !SIMPLE_TOKEN_PATTERN.test(token))) return undefined;\n\n if (tokens[0] === 'cargo' && tokens[1] === 'test') {\n if (tokens.includes('--') || tokens.some((token) => token.startsWith('--message-format') || token === '--json')) {\n return undefined;\n }\n return 'cargo-test';\n }\n if (tokens[0] === 'pytest') {\n if (tokens.some((token) => token.startsWith('--json-report'))) return undefined;\n return 'pytest';\n }\n if (tokens[0] === 'git' && tokens[1] === 'diff') {\n if (\n tokens.some((token) =>\n GIT_DIFF_INCOMPATIBLE_OPTIONS.some((option) => token === option || token.startsWith(`${option}=`)),\n )\n ) {\n return undefined;\n }\n return 'git-diff';\n }\n if (tokens[0] === 'grep') {\n if (tokens.length < 4 || incompatibleStructuredSearch(tokens)) return undefined;\n return hasShortOrLongOption(tokens, 'n', '--line-number') && hasShortOrLongOption(tokens, 'H', '--with-filename')\n ? 'grep'\n : undefined;\n }\n if (tokens[0] === 'rg') {\n if (tokens.length < 4 || incompatibleStructuredSearch(tokens) || !tokens.includes('--no-heading')) return undefined;\n return hasShortOrLongOption(tokens, 'n', '--line-number') && hasShortOrLongOption(tokens, 'H', '--with-filename')\n ? 'grep'\n : undefined;\n }\n if (tokens[0] === 'go' && tokens[1] === 'test') {\n let jsonOutput = false;\n for (const token of tokens.slice(2)) {\n if (token === '-json' || token === '-json=true') jsonOutput = true;\n if (token === '-json=false') jsonOutput = false;\n }\n return jsonOutput ? 'go-test' : undefined;\n }\n if (tokens[0] === 'ruff' && tokens[1] === 'check') {\n const jsonOutput = tokens.some(\n (token, index) =>\n token === '--output-format=json' || (token === '--output-format' && tokens[index + 1] === 'json'),\n );\n return jsonOutput ? 'ruff-check' : undefined;\n }\n return undefined;\n}\n\nexport function rtkPackageForTarget(platform: string, architecture: string): string | undefined {\n const target = `${platform}-${architecture}`;\n const packageName = PACKAGE_BY_PLATFORM[target];\n if (!packageName) process.emitWarning(`Bundled RTK binary is unavailable for unsupported target ${target}`);\n return packageName;\n}\n\nfunction bundledBinary(env: Readonly<Record<string, string | undefined>> = process.env): string | undefined {\n const configured = env[RTK_BINARY_ENV];\n if (configured !== undefined && configured !== '') return configured;\n const packageName = rtkPackageForTarget(process.platform, process.arch);\n if (!packageName) return undefined;\n try {\n const require = createRequire(import.meta.url);\n const manifest = require.resolve(`${packageName}/package.json`);\n return path.join(path.dirname(manifest), 'vendor', 'bin', 'rtk');\n } catch {\n return undefined;\n }\n}\n\nfunction appendTail(\n current: Buffer<ArrayBufferLike>,\n chunk: Buffer<ArrayBufferLike>,\n limit: number,\n): Buffer<ArrayBufferLike> {\n if (chunk.byteLength >= limit) return Buffer.from(chunk.subarray(chunk.byteLength - limit));\n const combined = Buffer.concat([current, chunk]);\n return combined.byteLength > limit ? Buffer.from(combined.subarray(combined.byteLength - limit)) : combined;\n}\n\nfunction decodeUtf8Tail(output: Buffer<ArrayBufferLike>): string {\n let start = 0;\n while (start < output.byteLength && (output[start]! & 0xc0) === 0x80) start += 1;\n return output.subarray(start).toString('utf8');\n}\nfunction hasShortOrLongOption(tokens: readonly string[], short: string, long: string): boolean {\n return tokens.some(\n (token) => token === long || (token.startsWith('-') && !token.startsWith('--') && token.slice(1).includes(short)),\n );\n}\n\nfunction incompatibleStructuredSearch(tokens: readonly string[]): boolean {\n return tokens.some(\n (token) =>\n (token.startsWith('-') && !token.startsWith('--') && /[0ABCILNchzZ]/u.test(token.slice(1))) ||\n STRUCTURED_SEARCH_INCOMPATIBLE_OPTIONS.some((option) => token === option || token.startsWith(`${option}=`)),\n );\n}\n"],"mappings":"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"}