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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/LICENSE +149 -21
  2. package/README.md +17 -17
  3. package/dist/ansiScrub.mjs +1 -2
  4. package/dist/apiContracts.cjs +1 -1
  5. package/dist/apiContracts.cjs.map +1 -1
  6. package/dist/apiContracts.mjs +1 -1
  7. package/dist/apiContracts.mjs.map +1 -1
  8. package/dist/{bashResult-bIVSzoj-.mjs → bashResult-BqDa7sbC.mjs} +10 -9
  9. package/dist/bashResult-BqDa7sbC.mjs.map +1 -0
  10. package/dist/{bashResult-DNgtahGR.cjs → bashResult-C2iKhHpD.cjs} +10 -9
  11. package/dist/bashResult-C2iKhHpD.cjs.map +1 -0
  12. package/dist/{bashRunService-CJ02XaAq.mjs → bashRunService-Cl3pYccr.mjs} +2 -2
  13. package/dist/bashRunService-Cl3pYccr.mjs.map +1 -0
  14. package/dist/{bashRunService-DyqxOSlx.cjs → bashRunService-DjOH5kye.cjs} +2 -2
  15. package/dist/bashRunService-DjOH5kye.cjs.map +1 -0
  16. package/dist/bashRunService.cjs +1 -1
  17. package/dist/bashRunService.d.mts +3 -3
  18. package/dist/bashRunService.mjs +1 -2
  19. package/dist/bashSchema.cjs +1 -1
  20. package/dist/bashSchema.mjs +1 -2
  21. package/dist/{bashTool-C-k7fmyh.mjs → bashTool-BvC3YOgG.mjs} +2 -2
  22. package/dist/{bashTool-C-k7fmyh.mjs.map → bashTool-BvC3YOgG.mjs.map} +1 -1
  23. package/dist/{bashTool-CdgtqVFD.cjs → bashTool-euL6zMDl.cjs} +2 -2
  24. package/dist/{bashTool-CdgtqVFD.cjs.map → bashTool-euL6zMDl.cjs.map} +1 -1
  25. package/dist/bashTool.cjs +3 -3
  26. package/dist/bashTool.d.mts +1 -1
  27. package/dist/bashTool.mjs +3 -3
  28. package/dist/bin/cli.cjs +6 -6
  29. package/dist/bin/cli.cjs.map +1 -1
  30. package/dist/bin/cli.mjs +7 -7
  31. package/dist/bin/cli.mjs.map +1 -1
  32. package/dist/bin/logSink.cjs +6 -6
  33. package/dist/bin/logSink.cjs.map +1 -1
  34. package/dist/bin/logSink.mjs +7 -7
  35. package/dist/bin/logSink.mjs.map +1 -1
  36. package/dist/bin/runnerHost.cjs +4 -4
  37. package/dist/bin/runnerHost.cjs.map +1 -1
  38. package/dist/bin/runnerHost.mjs +5 -5
  39. package/dist/bin/runnerHost.mjs.map +1 -1
  40. package/dist/{cliApp-Dj9nwaOv.cjs → cliApp-T8Fx_-1j.cjs} +6 -6
  41. package/dist/cliApp-T8Fx_-1j.cjs.map +1 -0
  42. package/dist/{cliApp-v8Z3rMCi.mjs → cliApp-q97eVh4E.mjs} +6 -6
  43. package/dist/cliApp-q97eVh4E.mjs.map +1 -0
  44. package/dist/cliApp.cjs +1 -1
  45. package/dist/cliApp.d.mts +1 -1
  46. package/dist/cliApp.mjs +1 -2
  47. package/dist/clock.mjs +1 -2
  48. package/dist/{compaction-4QSUsBxq.cjs → compaction-Cduebib_.cjs} +3 -3
  49. package/dist/compaction-Cduebib_.cjs.map +1 -0
  50. package/dist/{compaction-DCw80VZj.mjs → compaction-nNlE6e5I.mjs} +3 -3
  51. package/dist/compaction-nNlE6e5I.mjs.map +1 -0
  52. package/dist/compaction.cjs +1 -1
  53. package/dist/compaction.d.mts +1 -1
  54. package/dist/compaction.mjs +1 -2
  55. package/dist/config.cjs +1 -1
  56. package/dist/config.d.mts +1 -1
  57. package/dist/config.mjs +1 -2
  58. package/dist/extensions/mcp-ui.mjs.map +1 -1
  59. package/dist/extensions/mcp.cjs +8 -7
  60. package/dist/extensions/mcp.cjs.map +1 -1
  61. package/dist/extensions/mcp.d.mts +1 -1
  62. package/dist/extensions/mcp.mjs +7 -6
  63. package/dist/extensions/mcp.mjs.map +1 -1
  64. package/dist/extensions/native.mjs +1 -1
  65. package/dist/extensions/native.mjs.map +1 -1
  66. package/dist/extensions/server.cjs +233 -119
  67. package/dist/extensions/server.cjs.map +1 -1
  68. package/dist/extensions/server.d.mts +2 -2
  69. package/dist/extensions/server.d.mts.map +1 -1
  70. package/dist/extensions/server.mjs +233 -119
  71. package/dist/extensions/server.mjs.map +1 -1
  72. package/dist/extensions/web.mjs +88 -62
  73. package/dist/extensions/web.mjs.map +1 -1
  74. package/dist/{headless-BGYfIlNk.mjs → headless-DOlCixyf.mjs} +5 -5
  75. package/dist/headless-DOlCixyf.mjs.map +1 -0
  76. package/dist/{headless-CHUsBGhg.cjs → headless-Dko_yBiy.cjs} +5 -5
  77. package/dist/headless-Dko_yBiy.cjs.map +1 -0
  78. package/dist/{index-Dhi8asLH.d.mts → index--xF7DvsE.d.mts} +4 -4
  79. package/dist/{index-Dhi8asLH.d.mts.map → index--xF7DvsE.d.mts.map} +1 -1
  80. package/dist/{index-BZL7keVW.d.mts → index-BCCF1sGD.d.mts} +2 -2
  81. package/dist/{index-BZL7keVW.d.mts.map → index-BCCF1sGD.d.mts.map} +1 -1
  82. package/dist/{index-BwB_jTI9.d.mts → index-BzeXJk6V.d.mts} +5 -5
  83. package/dist/index-BzeXJk6V.d.mts.map +1 -0
  84. package/dist/{index-D9-IXax4.d.mts → index-C-IC35d9.d.mts} +2 -2
  85. package/dist/{index-D9-IXax4.d.mts.map → index-C-IC35d9.d.mts.map} +1 -1
  86. package/dist/{index-DBz0DxnL.d.mts → index-CzCF_OP9.d.mts} +3 -4
  87. package/dist/index-CzCF_OP9.d.mts.map +1 -0
  88. package/dist/index.cjs +5 -5
  89. package/dist/index.d.mts +5 -5
  90. package/dist/index.mjs +5 -5
  91. package/dist/{launcher-BDm6-DiQ.mjs → launcher-CCYsFBM9.mjs} +3 -3
  92. package/dist/{launcher-BDm6-DiQ.mjs.map → launcher-CCYsFBM9.mjs.map} +1 -1
  93. package/dist/{launcher-SlyE8R3b.cjs → launcher-ZgDdyXpq.cjs} +8 -2
  94. package/dist/{launcher-SlyE8R3b.cjs.map → launcher-ZgDdyXpq.cjs.map} +1 -1
  95. package/dist/launcher.cjs +1 -1
  96. package/dist/launcher.d.mts +1 -1
  97. package/dist/launcher.mjs +1 -2
  98. package/dist/{lifeline-BZaQA0rm.mjs → lifeline-Bm-bHIjS.mjs} +6 -6
  99. package/dist/lifeline-Bm-bHIjS.mjs.map +1 -0
  100. package/dist/{lifeline-BuV_erib.cjs → lifeline-m7laIzIP.cjs} +6 -6
  101. package/dist/lifeline-m7laIzIP.cjs.map +1 -0
  102. package/dist/lifeline.cjs +1 -1
  103. package/dist/lifeline.d.mts +1 -1
  104. package/dist/lifeline.mjs +1 -1
  105. package/dist/{logFile-CNvepZh0.cjs → logFile-CnPKtxPy.cjs} +2 -2
  106. package/dist/{logFile-CNvepZh0.cjs.map → logFile-CnPKtxPy.cjs.map} +1 -1
  107. package/dist/{logFile-KKPbkC-a.mjs → logFile-XcDHBwu1.mjs} +2 -2
  108. package/dist/{logFile-KKPbkC-a.mjs.map → logFile-XcDHBwu1.mjs.map} +1 -1
  109. package/dist/logFile.cjs +1 -1
  110. package/dist/logFile.d.mts +1 -1
  111. package/dist/logFile.mjs +1 -2
  112. package/dist/{logReader-B6J7L7Ua.cjs → logReader-DHCK2BEr.cjs} +4 -4
  113. package/dist/{logReader-B6J7L7Ua.cjs.map → logReader-DHCK2BEr.cjs.map} +1 -1
  114. package/dist/{logReader-UfbDbwQl.mjs → logReader-mq9uVurh.mjs} +4 -4
  115. package/dist/{logReader-UfbDbwQl.mjs.map → logReader-mq9uVurh.mjs.map} +1 -1
  116. package/dist/logReader.cjs +1 -1
  117. package/dist/logReader.mjs +1 -2
  118. package/dist/processControl.mjs +1 -2
  119. package/dist/{ptyHost-DlQtTB8F.mjs → ptyHost-CwbLLr90.mjs} +2 -2
  120. package/dist/{ptyHost-DlQtTB8F.mjs.map → ptyHost-CwbLLr90.mjs.map} +1 -1
  121. package/dist/{ptyHost-MI2Z6WTG.cjs → ptyHost-D35hNmtd.cjs} +2 -2
  122. package/dist/{ptyHost-MI2Z6WTG.cjs.map → ptyHost-D35hNmtd.cjs.map} +1 -1
  123. package/dist/ptyHost.cjs +1 -1
  124. package/dist/ptyHost.mjs +1 -2
  125. package/dist/{ptySpawner-DEi1KOnd.mjs → ptySpawner-C375NJnj.mjs} +2 -2
  126. package/dist/ptySpawner-C375NJnj.mjs.map +1 -0
  127. package/dist/{ptySpawner-ijw0g5_T.cjs → ptySpawner-C39IzbRo.cjs} +2 -2
  128. package/dist/ptySpawner-C39IzbRo.cjs.map +1 -0
  129. package/dist/ptySpawner.cjs +1 -1
  130. package/dist/ptySpawner.d.mts +1 -1
  131. package/dist/ptySpawner.mjs +1 -2
  132. package/dist/{reconcile-DMeNSxwn.mjs → reconcile-5cZ11jSD.cjs} +12 -42
  133. package/dist/reconcile-5cZ11jSD.cjs.map +1 -0
  134. package/dist/{reconcile-BugwYFbV.cjs → reconcile-wNYQJZF-.mjs} +2 -62
  135. package/dist/reconcile-wNYQJZF-.mjs.map +1 -0
  136. package/dist/reconcile.cjs +1 -2
  137. package/dist/reconcile.d.mts +2 -9
  138. package/dist/reconcile.d.mts.map +1 -1
  139. package/dist/reconcile.mjs +1 -2
  140. package/dist/responseEnvelope.cjs +2 -2
  141. package/dist/responseEnvelope.d.mts +3 -3
  142. package/dist/responseEnvelope.mjs +2 -2
  143. package/dist/{rmuxBackend-DlxgqRZ1.cjs → rmuxBackend-Dh0CYVAL.cjs} +5 -5
  144. package/dist/rmuxBackend-Dh0CYVAL.cjs.map +1 -0
  145. package/dist/{rmuxBackend-DfyQwJrc.mjs → rmuxBackend-rjrVTG6K.mjs} +4 -4
  146. package/dist/rmuxBackend-rjrVTG6K.mjs.map +1 -0
  147. package/dist/rmuxBackend.cjs +1 -1
  148. package/dist/rmuxBackend.d.mts +1 -1
  149. package/dist/rmuxBackend.mjs +1 -2
  150. package/dist/{rtkProcessor-Bc4L4o_8.cjs → rtkProcessor-DSGbM-Cm.cjs} +4 -4
  151. package/dist/rtkProcessor-DSGbM-Cm.cjs.map +1 -0
  152. package/dist/{rtkProcessor-B9KPdyzr.mjs → rtkProcessor-Iw9gP5Xp.mjs} +3 -3
  153. package/dist/rtkProcessor-Iw9gP5Xp.mjs.map +1 -0
  154. package/dist/rtkProcessor.cjs +1 -1
  155. package/dist/rtkProcessor.d.mts +1 -1
  156. package/dist/rtkProcessor.mjs +1 -1
  157. package/dist/{runnerConfig-D2tGq5ZM.cjs → runnerConfig-BoLMinlx.cjs} +11 -11
  158. package/dist/runnerConfig-BoLMinlx.cjs.map +1 -0
  159. package/dist/{runnerConfig-BjtulXBI.d.mts → runnerConfig-DuWL6TJx.d.mts} +10 -10
  160. package/dist/{runnerConfig-BjtulXBI.d.mts.map → runnerConfig-DuWL6TJx.d.mts.map} +1 -1
  161. package/dist/{runnerConfig-BQBlVAXn.mjs → runnerConfig-XXMq4VQA.mjs} +11 -11
  162. package/dist/runnerConfig-XXMq4VQA.mjs.map +1 -0
  163. package/dist/{runnerDependencies-DruByBGS.mjs → runnerDependencies-7h_cxOva.mjs} +17 -17
  164. package/dist/runnerDependencies-7h_cxOva.mjs.map +1 -0
  165. package/dist/{runnerDependencies-KMZigIxB.cjs → runnerDependencies-DSun3xO-.cjs} +17 -17
  166. package/dist/runnerDependencies-DSun3xO-.cjs.map +1 -0
  167. package/dist/runnerDependencies.cjs +1 -1
  168. package/dist/runnerDependencies.d.mts +1 -1
  169. package/dist/runnerDependencies.mjs +1 -2
  170. package/dist/runnerNamer.d.mts +1 -1
  171. package/dist/runnerNamer.mjs +1 -2
  172. package/dist/{runnerPaths-BTEuzxw0.cjs → runnerPaths-B41rMOY6.cjs} +20 -38
  173. package/dist/runnerPaths-B41rMOY6.cjs.map +1 -0
  174. package/dist/{runnerPaths-B_dAAeco.mjs → runnerPaths-Dibbvyx_.mjs} +20 -38
  175. package/dist/runnerPaths-Dibbvyx_.mjs.map +1 -0
  176. package/dist/runnerPaths.cjs +1 -1
  177. package/dist/runnerPaths.d.mts +5 -7
  178. package/dist/runnerPaths.d.mts.map +1 -1
  179. package/dist/runnerPaths.mjs +1 -2
  180. package/dist/{runnerRegistry-CeOHEjBv.mjs → runnerRegistry-BgaR5O86.mjs} +12 -11
  181. package/dist/runnerRegistry-BgaR5O86.mjs.map +1 -0
  182. package/dist/{runnerRegistry-CtJiD02R.d.mts → runnerRegistry-V-Ocaf4N.d.mts} +1 -3
  183. package/dist/{runnerRegistry-CtJiD02R.d.mts.map → runnerRegistry-V-Ocaf4N.d.mts.map} +1 -1
  184. package/dist/{runnerRegistry-BmkZTJHi.cjs → runnerRegistry-dQYlMSpQ.cjs} +23 -10
  185. package/dist/runnerRegistry-dQYlMSpQ.cjs.map +1 -0
  186. package/dist/runnerRegistry.cjs +1 -1
  187. package/dist/runnerRegistry.d.mts +2 -2
  188. package/dist/runnerRegistry.mjs +1 -2
  189. package/dist/services/lifeline/client.cjs +2 -2
  190. package/dist/services/lifeline/client.cjs.map +1 -1
  191. package/dist/services/lifeline/client.d.mts +1 -1
  192. package/dist/services/lifeline/client.mjs +2 -2
  193. package/dist/services/lifeline/client.mjs.map +1 -1
  194. package/dist/{session-Chsb_Nh2.mjs → session-BKYnH4R6.mjs} +2 -2
  195. package/dist/{session-Chsb_Nh2.mjs.map → session-BKYnH4R6.mjs.map} +1 -1
  196. package/dist/{session-BC43uEyG.cjs → session-BvqzhXZY.cjs} +2 -2
  197. package/dist/{session-BC43uEyG.cjs.map → session-BvqzhXZY.cjs.map} +1 -1
  198. package/dist/session.cjs +1 -1
  199. package/dist/session.mjs +1 -1
  200. package/dist/spawner.mjs +1 -2
  201. package/dist/{type-C31e1gla.d.mts → type-Do0YxwVQ.d.mts} +4 -4
  202. package/dist/{type-C31e1gla.d.mts.map → type-Do0YxwVQ.d.mts.map} +1 -1
  203. package/dist/{type-BXM03qSw.d.mts → type-DwMZoINK.d.mts} +8 -8
  204. package/dist/{type-BXM03qSw.d.mts.map → type-DwMZoINK.d.mts.map} +1 -1
  205. package/dist/types.d.mts +1 -1
  206. package/package.json +31 -34
  207. package/skills/{doom-runner → po-runner}/SKILL.md +15 -15
  208. package/src/prompts/po-use-runner/SKILL.md +11 -11
  209. package/dist/bashResult-DNgtahGR.cjs.map +0 -1
  210. package/dist/bashResult-bIVSzoj-.mjs.map +0 -1
  211. package/dist/bashRunService-CJ02XaAq.mjs.map +0 -1
  212. package/dist/bashRunService-DyqxOSlx.cjs.map +0 -1
  213. package/dist/cliApp-Dj9nwaOv.cjs.map +0 -1
  214. package/dist/cliApp-v8Z3rMCi.mjs.map +0 -1
  215. package/dist/compaction-4QSUsBxq.cjs.map +0 -1
  216. package/dist/compaction-DCw80VZj.mjs.map +0 -1
  217. package/dist/headless-BGYfIlNk.mjs.map +0 -1
  218. package/dist/headless-CHUsBGhg.cjs.map +0 -1
  219. package/dist/index-BwB_jTI9.d.mts.map +0 -1
  220. package/dist/index-DBz0DxnL.d.mts.map +0 -1
  221. package/dist/lifeline-BZaQA0rm.mjs.map +0 -1
  222. package/dist/lifeline-BuV_erib.cjs.map +0 -1
  223. package/dist/ptySpawner-DEi1KOnd.mjs.map +0 -1
  224. package/dist/ptySpawner-ijw0g5_T.cjs.map +0 -1
  225. package/dist/reconcile-BugwYFbV.cjs.map +0 -1
  226. package/dist/reconcile-DMeNSxwn.mjs.map +0 -1
  227. package/dist/rmuxBackend-DfyQwJrc.mjs.map +0 -1
  228. package/dist/rmuxBackend-DlxgqRZ1.cjs.map +0 -1
  229. package/dist/rtkProcessor-B9KPdyzr.mjs.map +0 -1
  230. package/dist/rtkProcessor-Bc4L4o_8.cjs.map +0 -1
  231. package/dist/runnerConfig-BQBlVAXn.mjs.map +0 -1
  232. package/dist/runnerConfig-D2tGq5ZM.cjs.map +0 -1
  233. package/dist/runnerDependencies-DruByBGS.mjs.map +0 -1
  234. package/dist/runnerDependencies-KMZigIxB.cjs.map +0 -1
  235. package/dist/runnerPaths-BTEuzxw0.cjs.map +0 -1
  236. package/dist/runnerPaths-B_dAAeco.mjs.map +0 -1
  237. package/dist/runnerRegistry-BmkZTJHi.cjs.map +0 -1
  238. package/dist/runnerRegistry-CeOHEjBv.mjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
2
- const require_runnerConfig = require("./runnerConfig-D2tGq5ZM.cjs");
3
- const require_session = require("./session-BC43uEyG.cjs");
2
+ const require_runnerConfig = require("./runnerConfig-BoLMinlx.cjs");
3
+ const require_session = require("./session-BvqzhXZY.cjs");
4
4
  let node_fs = require("node:fs");
5
5
  node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
6
6
  let node_path = require("node:path");
@@ -8,7 +8,7 @@ node_path = require_rolldown_runtime.__toESM(node_path, 1);
8
8
  let node_child_process = require("node:child_process");
9
9
  let _agimon_ai_po_core_piSettings = require("@agimon-ai/po-core/piSettings");
10
10
  //#region src/constants/runnerPaths.ts
11
- const STORE_DIR_NAME = "doom-runner";
11
+ const STORE_DIR_NAME = "po-runner";
12
12
  const LOG_DIR_NAME = "logs";
13
13
  const STATE_DIR_NAME = "runs";
14
14
  const LOG_EXTENSION = ".log";
@@ -156,7 +156,7 @@ async function isEmptySessionAsync(directory) {
156
156
  }
157
157
  /**
158
158
  * The root every session's runner state lives under, before any log-directory
159
- * override: `<agent dir>/doom-runner/<session id>/{runs,logs}`. A reader in
159
+ * override: `<agent dir>/po-runner/<session id>/{runs,logs}`. A reader in
160
160
  * another process, such as the cockpit hub, resolves the same root from its
161
161
  * own environment. A relative agent directory resolves against home, not the cwd.
162
162
  */
@@ -183,7 +183,7 @@ var RunnerPaths = class {
183
183
  }
184
184
  setSessionId(sessionId) {
185
185
  const trimmed = sessionId.trim();
186
- if (!trimmed) throw new Error("doom-runner session id cannot be blank");
186
+ if (!trimmed) throw new Error("po-runner session id cannot be blank");
187
187
  this.adoptedSessionId = trimmed;
188
188
  }
189
189
  logDirectory(sessionId) {
@@ -212,13 +212,14 @@ var RunnerPaths = class {
212
212
  node_fs.default.mkdirSync(this.logDirectory(sessionId), { recursive: true });
213
213
  node_fs.default.mkdirSync(this.stateDirectory(sessionId), { recursive: true });
214
214
  }
215
- sweepHistory(ttlMs, now = Date.now()) {
215
+ sweepHistory(ttlMs, now = Date.now(), live = this.liveSessions()) {
216
216
  const result = {
217
217
  removed: [],
218
218
  errors: []
219
219
  };
220
- if (this.env["DOOM_RUNNER_LOG_DIR"]?.trim()) {
221
- this.sweepStateDirectory(this.stateDirectory(), this.sessionId(), ttlMs, now, result);
220
+ if (this.env["PO_RUNNER_LOG_DIR"]?.trim()) {
221
+ const owner = [...live][0] ?? this.sessionId();
222
+ this.sweepStateDirectory(this.stateDirectory(owner), owner, ttlMs, now, result);
222
223
  return result;
223
224
  }
224
225
  const root = this.storeDirectory();
@@ -230,9 +231,8 @@ var RunnerPaths = class {
230
231
  result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);
231
232
  return result;
232
233
  }
233
- const active = this.currentSessionId();
234
234
  for (const sessionId of sessions) {
235
- if (sessionId === active) {
235
+ if (live.has(sessionId)) {
236
236
  this.sweepActiveSession(sessionId, ttlMs, now, result);
237
237
  continue;
238
238
  }
@@ -240,13 +240,14 @@ var RunnerPaths = class {
240
240
  }
241
241
  return result;
242
242
  }
243
- async sweepHistoryAsync(ttlMs, now = Date.now()) {
243
+ async sweepHistoryAsync(ttlMs, now = Date.now(), live = this.liveSessions()) {
244
244
  const result = {
245
245
  removed: [],
246
246
  errors: []
247
247
  };
248
- if (this.env["DOOM_RUNNER_LOG_DIR"]?.trim()) {
249
- await this.sweepStateDirectoryAsync(this.stateDirectory(), this.sessionId(), ttlMs, now, result);
248
+ if (this.env["PO_RUNNER_LOG_DIR"]?.trim()) {
249
+ const owner = [...live][0] ?? this.sessionId();
250
+ await this.sweepStateDirectoryAsync(this.stateDirectory(owner), owner, ttlMs, now, result);
250
251
  return result;
251
252
  }
252
253
  const root = this.storeDirectory();
@@ -258,9 +259,8 @@ var RunnerPaths = class {
258
259
  result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);
259
260
  return result;
260
261
  }
261
- const active = this.currentSessionId();
262
262
  for (const sessionId of sessions) {
263
- if (sessionId === active) {
263
+ if (live.has(sessionId)) {
264
264
  await this.sweepActiveSessionAsync(sessionId, ttlMs, now, result);
265
265
  continue;
266
266
  }
@@ -268,30 +268,12 @@ var RunnerPaths = class {
268
268
  }
269
269
  return result;
270
270
  }
271
- legacyDirectory() {
272
- const commonDirectory = git([
273
- "rev-parse",
274
- "--path-format=absolute",
275
- "--git-common-dir"
276
- ], this.cwd);
277
- if (!commonDirectory || !git(["rev-parse", "--show-toplevel"], this.cwd)) return void 0;
278
- return node_path.default.join(realPath(commonDirectory), STORE_DIR_NAME);
279
- }
280
- removeLegacyStore() {
281
- const target = this.legacyDirectory();
282
- if (!target || node_path.default.basename(target) !== "doom-runner" || !node_fs.default.existsSync(target)) return void 0;
283
- node_fs.default.rmSync(target, {
284
- recursive: true,
285
- force: true
286
- });
287
- return target;
288
- }
289
271
  /** The live session, if one is known, so a sweep never deletes underneath itself. */
290
- currentSessionId() {
272
+ liveSessions() {
291
273
  try {
292
- return this.sessionId();
274
+ return /* @__PURE__ */ new Set([this.sessionId()]);
293
275
  } catch {
294
- return;
276
+ return /* @__PURE__ */ new Set();
295
277
  }
296
278
  }
297
279
  /**
@@ -357,7 +339,7 @@ var RunnerPaths = class {
357
339
  }
358
340
  sessionId(explicit) {
359
341
  const sessionId = explicit?.trim() || this.adoptedSessionId || require_session.inheritedSessionId(this.env);
360
- if (!sessionId) throw new Error("PI_SESSION_ID is required for doom-runner storage");
342
+ if (!sessionId) throw new Error("PI_SESSION_ID is required for po-runner storage");
361
343
  return sessionId;
362
344
  }
363
345
  storeDirectory() {
@@ -468,4 +450,4 @@ Object.defineProperty(exports, "runnerStateDirFor", {
468
450
  }
469
451
  });
470
452
 
471
- //# sourceMappingURL=runnerPaths-BTEuzxw0.cjs.map
453
+ //# sourceMappingURL=runnerPaths-B41rMOY6.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runnerPaths-B41rMOY6.cjs","names":["execFileSync","fs","path","piAgentDirectory","LOG_DIR_ENV","inheritedSessionId","getMaxCompletedRunners"],"sources":["../src/constants/runnerPaths.ts","../src/services/runnerPaths/index.ts"],"sourcesContent":["export const STORE_DIR_NAME = 'po-runner';\nexport const LOG_DIR_NAME = 'logs';\nexport const STATE_DIR_NAME = 'runs';\nexport const LOG_EXTENSION = '.log';\nexport const STATE_EXTENSION = '.json';\nexport const ROTATED_SUFFIX = '.1';\nexport const RAW_SUFFIX = '.raw';\nexport const PI_CODING_AGENT_DIR_ENV = 'PI_CODING_AGENT_DIR';\nexport const FILE_ENCODING = 'utf8';\nexport const NOT_FOUND_ERROR_CODE = 'ENOENT';\nexport const EMPTY_SESSION_GRACE_MS = 300_000;\n","import { execFileSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { piAgentDirectory } from '@agimon-ai/po-core/piSettings';\n\nimport { LOG_DIR_ENV } from '../../constants/runnerConfig';\nimport {\n EMPTY_SESSION_GRACE_MS,\n FILE_ENCODING,\n LOG_DIR_NAME,\n LOG_EXTENSION,\n NOT_FOUND_ERROR_CODE,\n RAW_SUFFIX,\n ROTATED_SUFFIX,\n STATE_DIR_NAME,\n STATE_EXTENSION,\n STORE_DIR_NAME,\n} from '../../constants/runnerPaths';\nimport { getMaxCompletedRunners } from '../runnerConfig';\nimport { inheritedSessionId } from '../session';\nimport type { IRunnerPaths, LogSweepResult } from './type';\n\n/** Unscrubbed pane bytes, kept beside the log so an attached terminal can replay them. */\n/**\n * How long an entirely empty session directory is left alone before it counts\n * as an orphan. A session that has started but not yet run anything owns such a\n * directory for a moment, and reclaiming it out from under that session would\n * be churn for no gain.\n */\n\nfunction git(args: string[], cwd: string): string | undefined {\n try {\n const output = execFileSync('git', args, { cwd, encoding: FILE_ENCODING, stdio: ['ignore', 'pipe', 'ignore'] });\n const trimmed = output.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction realPath(target: string): string {\n try {\n return fs.realpathSync(target);\n } catch {\n return target;\n }\n}\n\n/**\n * Newest mtime anywhere one level inside the session, falling back to the\n * directory itself. A session still being written to therefore always looks\n * recent, whatever state its individual records are in.\n */\nfunction newestEntryTime(directory: string): number {\n let newest = fs.statSync(directory).mtimeMs;\n for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {\n const target = path.join(directory, entry.name);\n newest = Math.max(newest, fs.statSync(target).mtimeMs);\n if (!entry.isDirectory()) continue;\n for (const child of fs.readdirSync(target)) {\n newest = Math.max(newest, fs.statSync(path.join(target, child)).mtimeMs);\n }\n }\n return newest;\n}\n\nasync function newestEntryTimeAsync(directory: string): Promise<number> {\n let newest = (await fs.promises.stat(directory)).mtimeMs;\n for (const entry of await fs.promises.readdir(directory, { withFileTypes: true })) {\n const target = path.join(directory, entry.name);\n newest = Math.max(newest, (await fs.promises.stat(target)).mtimeMs);\n if (!entry.isDirectory()) continue;\n for (const child of await fs.promises.readdir(target)) {\n newest = Math.max(newest, (await fs.promises.stat(path.join(target, child))).mtimeMs);\n }\n }\n return newest;\n}\n\n/**\n * Whether any run in this session names a pi process that is still running.\n *\n * One live record is enough: records are only ever written by their owner, so a\n * live host pid means the session is still in use however old its files look.\n */\nfunction ownerAlive(stateDirectory: string): boolean {\n let entries: string[];\n try {\n entries = fs.readdirSync(stateDirectory);\n } catch {\n // No records left to consult, so nothing claims the directory.\n return false;\n }\n\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n try {\n const value: unknown = JSON.parse(fs.readFileSync(path.join(stateDirectory, entry), FILE_ENCODING));\n const hostPid = (value as { hostPid?: unknown }).hostPid;\n if (typeof hostPid !== 'number') continue;\n process.kill(hostPid, 0);\n return true;\n } catch {\n // An unreadable record and a dead pid mean the same thing here: no claim.\n }\n }\n return false;\n}\n\nasync function ownerAliveAsync(stateDirectory: string): Promise<boolean> {\n let entries: string[];\n try {\n entries = await fs.promises.readdir(stateDirectory);\n } catch {\n return false;\n }\n\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n try {\n const value: unknown = JSON.parse(await fs.promises.readFile(path.join(stateDirectory, entry), FILE_ENCODING));\n const hostPid = (value as { hostPid?: unknown }).hostPid;\n if (typeof hostPid !== 'number') continue;\n process.kill(hostPid, 0);\n return true;\n } catch {\n // An unreadable record and a dead pid mean the same thing here: no claim.\n }\n }\n return false;\n}\n\nfunction completedAt(value: unknown): number | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const record = value as { state?: unknown; exit?: { finishedAt?: unknown } };\n if (record.state !== 'completed' || typeof record.exit?.finishedAt !== 'string') return undefined;\n const timestamp = Date.parse(record.exit.finishedAt);\n return Number.isFinite(timestamp) ? timestamp : undefined;\n}\n\ninterface CompletedRecord {\n readonly id: string;\n readonly statePath: string;\n readonly finishedAt: number;\n}\n\n/**\n * Completed records a sweep may delete: everything past the TTL, and everything\n * beyond the newest `keep`.\n *\n * The count bound is what keeps a live session from growing without limit. Its\n * records only reach a multi-day TTL long after the session that is still\n * writing them would have filled its directory, so age alone bounds nothing\n * while the session lasts.\n */\nfunction expiredCompletedRecords(\n records: readonly CompletedRecord[],\n ttlMs: number,\n now: number,\n keep: number,\n): CompletedRecord[] {\n return [...records]\n .sort((left, right) => right.finishedAt - left.finishedAt)\n .filter((record, index) => index >= keep || now - record.finishedAt > ttlMs);\n}\n\n/**\n * Whether the directory holds no files at all, only empty subdirectories.\n *\n * A session that ran something leaves metadata behind, and a live session keeps\n * its lifeline socket in the state directory, so an entirely empty tree names\n * no owner and no history.\n */\nfunction isEmptySession(directory: string): boolean {\n for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {\n if (!entry.isDirectory()) return false;\n if (fs.readdirSync(path.join(directory, entry.name)).length > 0) return false;\n }\n return true;\n}\n\nasync function isEmptySessionAsync(directory: string): Promise<boolean> {\n for (const entry of await fs.promises.readdir(directory, { withFileTypes: true })) {\n if (!entry.isDirectory()) return false;\n if ((await fs.promises.readdir(path.join(directory, entry.name))).length > 0) return false;\n }\n return true;\n}\n\n/**\n * The root every session's runner state lives under, before any log-directory\n * override: `<agent dir>/po-runner/<session id>/{runs,logs}`. A reader in\n * another process, such as the cockpit hub, resolves the same root from its\n * own environment. A relative agent directory resolves against home, not the cwd.\n */\nexport function resolveRunnerStoreDirectory(env: Readonly<Record<string, string | undefined>>): string {\n return path.join(piAgentDirectory(env), STORE_DIR_NAME);\n}\n\n/** Durable metadata directory for one session. Used by APIs and history reads, not live transport. */\nexport function runnerStateDirFor(storeDir: string, sessionId: string): string {\n return path.join(storeDir, sessionId, STATE_DIR_NAME);\n}\n\n/** Session-scoped runner storage under the Pi agent directory. */\nexport class RunnerPaths implements IRunnerPaths {\n private adoptedSessionId: string | undefined;\n private repository: string | undefined;\n\n constructor(\n private readonly cwd: string = process.cwd(),\n private readonly env: Readonly<Record<string, string | undefined>> = { ...process.env },\n ) {}\n\n repositoryPath(): string {\n this.repository ??= realPath(git(['rev-parse', '--show-toplevel'], this.cwd) ?? this.cwd);\n return this.repository;\n }\n\n setSessionId(sessionId: string): void {\n const trimmed = sessionId.trim();\n if (!trimmed) throw new Error('po-runner session id cannot be blank');\n this.adoptedSessionId = trimmed;\n }\n\n logDirectory(sessionId?: string): string {\n const override = this.env[LOG_DIR_ENV]?.trim();\n if (override) return path.resolve(this.cwd, override);\n return path.join(this.sessionDirectory(sessionId), LOG_DIR_NAME);\n }\n\n stateDirectory(sessionId?: string): string {\n const override = this.env[LOG_DIR_ENV]?.trim();\n if (override) return path.join(path.resolve(this.cwd, override), '..', STATE_DIR_NAME);\n return path.join(this.sessionDirectory(sessionId), STATE_DIR_NAME);\n }\n\n logPathFor(id: string, sessionId?: string): string {\n return path.join(this.logDirectory(sessionId), `${id}${LOG_EXTENSION}`);\n }\n\n rotatedLogPathFor(id: string, sessionId?: string): string {\n return `${this.logPathFor(id, sessionId)}${ROTATED_SUFFIX}`;\n }\n\n rawLogPathFor(id: string, sessionId?: string): string {\n return `${this.logPathFor(id, sessionId)}${RAW_SUFFIX}`;\n }\n\n statePathFor(id: string, sessionId?: string): string {\n return path.join(this.stateDirectory(sessionId), `${id}${STATE_EXTENSION}`);\n }\n\n ensureDirectories(sessionId?: string): void {\n fs.mkdirSync(this.logDirectory(sessionId), { recursive: true });\n fs.mkdirSync(this.stateDirectory(sessionId), { recursive: true });\n }\n\n sweepHistory(\n ttlMs: number,\n now: number = Date.now(),\n live: ReadonlySet<string> = this.liveSessions(),\n ): LogSweepResult {\n const result: LogSweepResult = { removed: [], errors: [] };\n // A pinned log directory belongs to whoever pinned it, so that branch only\n // ever removes the files this package put there.\n if (this.env[LOG_DIR_ENV]?.trim()) {\n // Without a live session there is no owner to sweep for, as before.\n const owner = [...live][0] ?? this.sessionId();\n this.sweepStateDirectory(this.stateDirectory(owner), owner, ttlMs, now, result);\n return result;\n }\n const root = this.storeDirectory();\n let sessions: string[];\n try {\n sessions = fs.readdirSync(root);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === NOT_FOUND_ERROR_CODE) return result;\n result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);\n return result;\n }\n\n // Sweeping whole session directories rather than the three files a completed\n // record names is what keeps sockets, sidecars, runs that never reached a\n // terminal state, and the emptied directories themselves from accumulating.\n for (const sessionId of sessions) {\n if (live.has(sessionId)) {\n this.sweepActiveSession(sessionId, ttlMs, now, result);\n continue;\n }\n this.sweepSessionDirectory(path.join(root, sessionId), ttlMs, now, result);\n }\n return result;\n }\n\n async sweepHistoryAsync(\n ttlMs: number,\n now: number = Date.now(),\n live: ReadonlySet<string> = this.liveSessions(),\n ): Promise<LogSweepResult> {\n const result: LogSweepResult = { removed: [], errors: [] };\n if (this.env[LOG_DIR_ENV]?.trim()) {\n const owner = [...live][0] ?? this.sessionId();\n await this.sweepStateDirectoryAsync(this.stateDirectory(owner), owner, ttlMs, now, result);\n return result;\n }\n\n const root = this.storeDirectory();\n let sessions: string[];\n try {\n sessions = await fs.promises.readdir(root);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === NOT_FOUND_ERROR_CODE) return result;\n result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);\n return result;\n }\n\n for (const sessionId of sessions) {\n if (live.has(sessionId)) {\n await this.sweepActiveSessionAsync(sessionId, ttlMs, now, result);\n continue;\n }\n await this.sweepSessionDirectoryAsync(path.join(root, sessionId), ttlMs, now, result);\n }\n return result;\n }\n\n /** The live session, if one is known, so a sweep never deletes underneath itself. */\n private liveSessions(): ReadonlySet<string> {\n try {\n return new Set([this.sessionId()]);\n } catch {\n // A CLI invocation outside a session still sweeps; it just has nothing to spare.\n return new Set();\n }\n }\n\n /**\n * Retention inside the session that is still running.\n *\n * The whole-directory sweep cannot be pointed at the live session: it would\n * take the lifeline socket, the supervisor sidecars and the running runners'\n * own metadata with it. Per-record retention is safe there because it only\n * ever removes a record whose state is `completed` together with the two log\n * files that record names, and never the directory itself. A running record\n * has no `exit.finishedAt`, so it is not a candidate at any age.\n */\n private sweepActiveSession(sessionId: string, ttlMs: number, now: number, result: LogSweepResult): void {\n this.sweepStateDirectory(this.stateDirectory(sessionId), sessionId, ttlMs, now, result);\n }\n\n private async sweepActiveSessionAsync(\n sessionId: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): Promise<void> {\n await this.sweepStateDirectoryAsync(this.stateDirectory(sessionId), sessionId, ttlMs, now, result);\n }\n\n /** Removes a session's whole directory once its newest entry is past the TTL. */\n private sweepSessionDirectory(directory: string, ttlMs: number, now: number, result: LogSweepResult): void {\n try {\n const newest = newestEntryTime(directory);\n // An orphan left by a session that never ran anything holds nothing worth\n // a retention window, so it goes as soon as it is clearly not in use.\n if (now - newest > EMPTY_SESSION_GRACE_MS && isEmptySession(directory)) {\n fs.rmSync(directory, { recursive: true, force: true });\n result.removed.push(directory);\n return;\n }\n if (now - newest <= ttlMs) return;\n // An idle session can go quiet for longer than the TTL, and deleting one\n // takes its lifeline socket with it, which would read to its own runners\n // as an owner that had died. Its records name the owner, so ask.\n if (ownerAlive(path.join(directory, STATE_DIR_NAME))) return;\n fs.rmSync(directory, { recursive: true, force: true });\n result.removed.push(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not sweep runner session ${directory}: ${String(error)}`);\n }\n }\n }\n\n private async sweepSessionDirectoryAsync(\n directory: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): Promise<void> {\n try {\n const newest = await newestEntryTimeAsync(directory);\n if (now - newest > EMPTY_SESSION_GRACE_MS && (await isEmptySessionAsync(directory))) {\n await fs.promises.rm(directory, { recursive: true, force: true });\n result.removed.push(directory);\n return;\n }\n if (now - newest <= ttlMs) return;\n if (await ownerAliveAsync(path.join(directory, STATE_DIR_NAME))) return;\n await fs.promises.rm(directory, { recursive: true, force: true });\n result.removed.push(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not sweep runner session ${directory}: ${String(error)}`);\n }\n }\n }\n\n private sessionId(explicit?: string): string {\n const sessionId = explicit?.trim() || this.adoptedSessionId || inheritedSessionId(this.env);\n if (!sessionId) throw new Error('PI_SESSION_ID is required for po-runner storage');\n return sessionId;\n }\n\n storeDirectory(): string {\n const override = this.env[LOG_DIR_ENV]?.trim();\n if (override) return path.dirname(path.resolve(this.cwd, override));\n return resolveRunnerStoreDirectory(this.env);\n }\n\n private sessionDirectory(sessionId?: string): string {\n return path.join(this.storeDirectory(), this.sessionId(sessionId));\n }\n\n private sweepStateDirectory(\n directory: string,\n sessionId: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): void {\n let entries: string[];\n try {\n entries = fs.readdirSync(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not read runner state directory ${directory}: ${String(error)}`);\n }\n return;\n }\n\n const completed: CompletedRecord[] = [];\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n const statePath = path.join(directory, entry);\n try {\n const value: unknown = JSON.parse(fs.readFileSync(statePath, FILE_ENCODING));\n const finishedAt = completedAt(value);\n if (finishedAt === undefined) continue;\n completed.push({ id: entry.slice(0, -STATE_EXTENSION.length), statePath, finishedAt });\n } catch (error) {\n result.errors.push(`Could not sweep runner metadata ${statePath}: ${String(error)}`);\n }\n }\n\n for (const record of expiredCompletedRecords(completed, ttlMs, now, getMaxCompletedRunners(this.env))) {\n this.removeHistoryFiles(sessionId, record.id, record.statePath, result);\n }\n }\n\n private async sweepStateDirectoryAsync(\n directory: string,\n sessionId: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): Promise<void> {\n let entries: string[];\n try {\n entries = await fs.promises.readdir(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not read runner state directory ${directory}: ${String(error)}`);\n }\n return;\n }\n\n const completed: CompletedRecord[] = [];\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n const statePath = path.join(directory, entry);\n try {\n const value: unknown = JSON.parse(await fs.promises.readFile(statePath, FILE_ENCODING));\n const finishedAt = completedAt(value);\n if (finishedAt === undefined) continue;\n completed.push({ id: entry.slice(0, -STATE_EXTENSION.length), statePath, finishedAt });\n } catch (error) {\n result.errors.push(`Could not sweep runner metadata ${statePath}: ${String(error)}`);\n }\n }\n\n for (const record of expiredCompletedRecords(completed, ttlMs, now, getMaxCompletedRunners(this.env))) {\n await this.removeHistoryFilesAsync(sessionId, record.id, record.statePath, result);\n }\n }\n\n private removeHistoryFiles(sessionId: string, id: string, statePath: string, result: LogSweepResult): void {\n const candidates = [\n statePath,\n this.logPathFor(id, sessionId),\n this.rotatedLogPathFor(id, sessionId),\n this.rawLogPathFor(id, sessionId),\n ];\n for (const candidate of candidates) {\n try {\n fs.unlinkSync(candidate);\n result.removed.push(candidate);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not remove runner history ${candidate}: ${String(error)}`);\n }\n }\n }\n }\n\n private async removeHistoryFilesAsync(\n sessionId: string,\n id: string,\n statePath: string,\n result: LogSweepResult,\n ): Promise<void> {\n const candidates = [statePath, this.logPathFor(id, sessionId), this.rotatedLogPathFor(id, sessionId)];\n for (const candidate of candidates) {\n try {\n await fs.promises.unlink(candidate);\n result.removed.push(candidate);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not remove runner history ${candidate}: ${String(error)}`);\n }\n }\n }\n }\n}\n"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
- import { M as LOG_DIR_ENV, l as getMaxCompletedRunners } from "./runnerConfig-BQBlVAXn.mjs";
2
- import { t as inheritedSessionId } from "./session-Chsb_Nh2.mjs";
1
+ import { M as LOG_DIR_ENV, l as getMaxCompletedRunners } from "./runnerConfig-XXMq4VQA.mjs";
2
+ import { t as inheritedSessionId } from "./session-BKYnH4R6.mjs";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import { execFileSync } from "node:child_process";
6
6
  import { piAgentDirectory } from "@agimon-ai/po-core/piSettings";
7
7
  //#region src/constants/runnerPaths.ts
8
- const STORE_DIR_NAME = "doom-runner";
8
+ const STORE_DIR_NAME = "po-runner";
9
9
  const LOG_DIR_NAME = "logs";
10
10
  const STATE_DIR_NAME = "runs";
11
11
  const LOG_EXTENSION = ".log";
@@ -153,7 +153,7 @@ async function isEmptySessionAsync(directory) {
153
153
  }
154
154
  /**
155
155
  * The root every session's runner state lives under, before any log-directory
156
- * override: `<agent dir>/doom-runner/<session id>/{runs,logs}`. A reader in
156
+ * override: `<agent dir>/po-runner/<session id>/{runs,logs}`. A reader in
157
157
  * another process, such as the cockpit hub, resolves the same root from its
158
158
  * own environment. A relative agent directory resolves against home, not the cwd.
159
159
  */
@@ -180,7 +180,7 @@ var RunnerPaths = class {
180
180
  }
181
181
  setSessionId(sessionId) {
182
182
  const trimmed = sessionId.trim();
183
- if (!trimmed) throw new Error("doom-runner session id cannot be blank");
183
+ if (!trimmed) throw new Error("po-runner session id cannot be blank");
184
184
  this.adoptedSessionId = trimmed;
185
185
  }
186
186
  logDirectory(sessionId) {
@@ -209,13 +209,14 @@ var RunnerPaths = class {
209
209
  fs.mkdirSync(this.logDirectory(sessionId), { recursive: true });
210
210
  fs.mkdirSync(this.stateDirectory(sessionId), { recursive: true });
211
211
  }
212
- sweepHistory(ttlMs, now = Date.now()) {
212
+ sweepHistory(ttlMs, now = Date.now(), live = this.liveSessions()) {
213
213
  const result = {
214
214
  removed: [],
215
215
  errors: []
216
216
  };
217
- if (this.env["DOOM_RUNNER_LOG_DIR"]?.trim()) {
218
- this.sweepStateDirectory(this.stateDirectory(), this.sessionId(), ttlMs, now, result);
217
+ if (this.env["PO_RUNNER_LOG_DIR"]?.trim()) {
218
+ const owner = [...live][0] ?? this.sessionId();
219
+ this.sweepStateDirectory(this.stateDirectory(owner), owner, ttlMs, now, result);
219
220
  return result;
220
221
  }
221
222
  const root = this.storeDirectory();
@@ -227,9 +228,8 @@ var RunnerPaths = class {
227
228
  result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);
228
229
  return result;
229
230
  }
230
- const active = this.currentSessionId();
231
231
  for (const sessionId of sessions) {
232
- if (sessionId === active) {
232
+ if (live.has(sessionId)) {
233
233
  this.sweepActiveSession(sessionId, ttlMs, now, result);
234
234
  continue;
235
235
  }
@@ -237,13 +237,14 @@ var RunnerPaths = class {
237
237
  }
238
238
  return result;
239
239
  }
240
- async sweepHistoryAsync(ttlMs, now = Date.now()) {
240
+ async sweepHistoryAsync(ttlMs, now = Date.now(), live = this.liveSessions()) {
241
241
  const result = {
242
242
  removed: [],
243
243
  errors: []
244
244
  };
245
- if (this.env["DOOM_RUNNER_LOG_DIR"]?.trim()) {
246
- await this.sweepStateDirectoryAsync(this.stateDirectory(), this.sessionId(), ttlMs, now, result);
245
+ if (this.env["PO_RUNNER_LOG_DIR"]?.trim()) {
246
+ const owner = [...live][0] ?? this.sessionId();
247
+ await this.sweepStateDirectoryAsync(this.stateDirectory(owner), owner, ttlMs, now, result);
247
248
  return result;
248
249
  }
249
250
  const root = this.storeDirectory();
@@ -255,9 +256,8 @@ var RunnerPaths = class {
255
256
  result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);
256
257
  return result;
257
258
  }
258
- const active = this.currentSessionId();
259
259
  for (const sessionId of sessions) {
260
- if (sessionId === active) {
260
+ if (live.has(sessionId)) {
261
261
  await this.sweepActiveSessionAsync(sessionId, ttlMs, now, result);
262
262
  continue;
263
263
  }
@@ -265,30 +265,12 @@ var RunnerPaths = class {
265
265
  }
266
266
  return result;
267
267
  }
268
- legacyDirectory() {
269
- const commonDirectory = git([
270
- "rev-parse",
271
- "--path-format=absolute",
272
- "--git-common-dir"
273
- ], this.cwd);
274
- if (!commonDirectory || !git(["rev-parse", "--show-toplevel"], this.cwd)) return void 0;
275
- return path.join(realPath(commonDirectory), STORE_DIR_NAME);
276
- }
277
- removeLegacyStore() {
278
- const target = this.legacyDirectory();
279
- if (!target || path.basename(target) !== "doom-runner" || !fs.existsSync(target)) return void 0;
280
- fs.rmSync(target, {
281
- recursive: true,
282
- force: true
283
- });
284
- return target;
285
- }
286
268
  /** The live session, if one is known, so a sweep never deletes underneath itself. */
287
- currentSessionId() {
269
+ liveSessions() {
288
270
  try {
289
- return this.sessionId();
271
+ return /* @__PURE__ */ new Set([this.sessionId()]);
290
272
  } catch {
291
- return;
273
+ return /* @__PURE__ */ new Set();
292
274
  }
293
275
  }
294
276
  /**
@@ -354,7 +336,7 @@ var RunnerPaths = class {
354
336
  }
355
337
  sessionId(explicit) {
356
338
  const sessionId = explicit?.trim() || this.adoptedSessionId || inheritedSessionId(this.env);
357
- if (!sessionId) throw new Error("PI_SESSION_ID is required for doom-runner storage");
339
+ if (!sessionId) throw new Error("PI_SESSION_ID is required for po-runner storage");
358
340
  return sessionId;
359
341
  }
360
342
  storeDirectory() {
@@ -448,4 +430,4 @@ var RunnerPaths = class {
448
430
  //#endregion
449
431
  export { resolveRunnerStoreDirectory as n, runnerStateDirFor as r, RunnerPaths as t };
450
432
 
451
- //# sourceMappingURL=runnerPaths-B_dAAeco.mjs.map
433
+ //# sourceMappingURL=runnerPaths-Dibbvyx_.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runnerPaths-Dibbvyx_.mjs","names":[],"sources":["../src/constants/runnerPaths.ts","../src/services/runnerPaths/index.ts"],"sourcesContent":["export const STORE_DIR_NAME = 'po-runner';\nexport const LOG_DIR_NAME = 'logs';\nexport const STATE_DIR_NAME = 'runs';\nexport const LOG_EXTENSION = '.log';\nexport const STATE_EXTENSION = '.json';\nexport const ROTATED_SUFFIX = '.1';\nexport const RAW_SUFFIX = '.raw';\nexport const PI_CODING_AGENT_DIR_ENV = 'PI_CODING_AGENT_DIR';\nexport const FILE_ENCODING = 'utf8';\nexport const NOT_FOUND_ERROR_CODE = 'ENOENT';\nexport const EMPTY_SESSION_GRACE_MS = 300_000;\n","import { execFileSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { piAgentDirectory } from '@agimon-ai/po-core/piSettings';\n\nimport { LOG_DIR_ENV } from '../../constants/runnerConfig';\nimport {\n EMPTY_SESSION_GRACE_MS,\n FILE_ENCODING,\n LOG_DIR_NAME,\n LOG_EXTENSION,\n NOT_FOUND_ERROR_CODE,\n RAW_SUFFIX,\n ROTATED_SUFFIX,\n STATE_DIR_NAME,\n STATE_EXTENSION,\n STORE_DIR_NAME,\n} from '../../constants/runnerPaths';\nimport { getMaxCompletedRunners } from '../runnerConfig';\nimport { inheritedSessionId } from '../session';\nimport type { IRunnerPaths, LogSweepResult } from './type';\n\n/** Unscrubbed pane bytes, kept beside the log so an attached terminal can replay them. */\n/**\n * How long an entirely empty session directory is left alone before it counts\n * as an orphan. A session that has started but not yet run anything owns such a\n * directory for a moment, and reclaiming it out from under that session would\n * be churn for no gain.\n */\n\nfunction git(args: string[], cwd: string): string | undefined {\n try {\n const output = execFileSync('git', args, { cwd, encoding: FILE_ENCODING, stdio: ['ignore', 'pipe', 'ignore'] });\n const trimmed = output.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction realPath(target: string): string {\n try {\n return fs.realpathSync(target);\n } catch {\n return target;\n }\n}\n\n/**\n * Newest mtime anywhere one level inside the session, falling back to the\n * directory itself. A session still being written to therefore always looks\n * recent, whatever state its individual records are in.\n */\nfunction newestEntryTime(directory: string): number {\n let newest = fs.statSync(directory).mtimeMs;\n for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {\n const target = path.join(directory, entry.name);\n newest = Math.max(newest, fs.statSync(target).mtimeMs);\n if (!entry.isDirectory()) continue;\n for (const child of fs.readdirSync(target)) {\n newest = Math.max(newest, fs.statSync(path.join(target, child)).mtimeMs);\n }\n }\n return newest;\n}\n\nasync function newestEntryTimeAsync(directory: string): Promise<number> {\n let newest = (await fs.promises.stat(directory)).mtimeMs;\n for (const entry of await fs.promises.readdir(directory, { withFileTypes: true })) {\n const target = path.join(directory, entry.name);\n newest = Math.max(newest, (await fs.promises.stat(target)).mtimeMs);\n if (!entry.isDirectory()) continue;\n for (const child of await fs.promises.readdir(target)) {\n newest = Math.max(newest, (await fs.promises.stat(path.join(target, child))).mtimeMs);\n }\n }\n return newest;\n}\n\n/**\n * Whether any run in this session names a pi process that is still running.\n *\n * One live record is enough: records are only ever written by their owner, so a\n * live host pid means the session is still in use however old its files look.\n */\nfunction ownerAlive(stateDirectory: string): boolean {\n let entries: string[];\n try {\n entries = fs.readdirSync(stateDirectory);\n } catch {\n // No records left to consult, so nothing claims the directory.\n return false;\n }\n\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n try {\n const value: unknown = JSON.parse(fs.readFileSync(path.join(stateDirectory, entry), FILE_ENCODING));\n const hostPid = (value as { hostPid?: unknown }).hostPid;\n if (typeof hostPid !== 'number') continue;\n process.kill(hostPid, 0);\n return true;\n } catch {\n // An unreadable record and a dead pid mean the same thing here: no claim.\n }\n }\n return false;\n}\n\nasync function ownerAliveAsync(stateDirectory: string): Promise<boolean> {\n let entries: string[];\n try {\n entries = await fs.promises.readdir(stateDirectory);\n } catch {\n return false;\n }\n\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n try {\n const value: unknown = JSON.parse(await fs.promises.readFile(path.join(stateDirectory, entry), FILE_ENCODING));\n const hostPid = (value as { hostPid?: unknown }).hostPid;\n if (typeof hostPid !== 'number') continue;\n process.kill(hostPid, 0);\n return true;\n } catch {\n // An unreadable record and a dead pid mean the same thing here: no claim.\n }\n }\n return false;\n}\n\nfunction completedAt(value: unknown): number | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const record = value as { state?: unknown; exit?: { finishedAt?: unknown } };\n if (record.state !== 'completed' || typeof record.exit?.finishedAt !== 'string') return undefined;\n const timestamp = Date.parse(record.exit.finishedAt);\n return Number.isFinite(timestamp) ? timestamp : undefined;\n}\n\ninterface CompletedRecord {\n readonly id: string;\n readonly statePath: string;\n readonly finishedAt: number;\n}\n\n/**\n * Completed records a sweep may delete: everything past the TTL, and everything\n * beyond the newest `keep`.\n *\n * The count bound is what keeps a live session from growing without limit. Its\n * records only reach a multi-day TTL long after the session that is still\n * writing them would have filled its directory, so age alone bounds nothing\n * while the session lasts.\n */\nfunction expiredCompletedRecords(\n records: readonly CompletedRecord[],\n ttlMs: number,\n now: number,\n keep: number,\n): CompletedRecord[] {\n return [...records]\n .sort((left, right) => right.finishedAt - left.finishedAt)\n .filter((record, index) => index >= keep || now - record.finishedAt > ttlMs);\n}\n\n/**\n * Whether the directory holds no files at all, only empty subdirectories.\n *\n * A session that ran something leaves metadata behind, and a live session keeps\n * its lifeline socket in the state directory, so an entirely empty tree names\n * no owner and no history.\n */\nfunction isEmptySession(directory: string): boolean {\n for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {\n if (!entry.isDirectory()) return false;\n if (fs.readdirSync(path.join(directory, entry.name)).length > 0) return false;\n }\n return true;\n}\n\nasync function isEmptySessionAsync(directory: string): Promise<boolean> {\n for (const entry of await fs.promises.readdir(directory, { withFileTypes: true })) {\n if (!entry.isDirectory()) return false;\n if ((await fs.promises.readdir(path.join(directory, entry.name))).length > 0) return false;\n }\n return true;\n}\n\n/**\n * The root every session's runner state lives under, before any log-directory\n * override: `<agent dir>/po-runner/<session id>/{runs,logs}`. A reader in\n * another process, such as the cockpit hub, resolves the same root from its\n * own environment. A relative agent directory resolves against home, not the cwd.\n */\nexport function resolveRunnerStoreDirectory(env: Readonly<Record<string, string | undefined>>): string {\n return path.join(piAgentDirectory(env), STORE_DIR_NAME);\n}\n\n/** Durable metadata directory for one session. Used by APIs and history reads, not live transport. */\nexport function runnerStateDirFor(storeDir: string, sessionId: string): string {\n return path.join(storeDir, sessionId, STATE_DIR_NAME);\n}\n\n/** Session-scoped runner storage under the Pi agent directory. */\nexport class RunnerPaths implements IRunnerPaths {\n private adoptedSessionId: string | undefined;\n private repository: string | undefined;\n\n constructor(\n private readonly cwd: string = process.cwd(),\n private readonly env: Readonly<Record<string, string | undefined>> = { ...process.env },\n ) {}\n\n repositoryPath(): string {\n this.repository ??= realPath(git(['rev-parse', '--show-toplevel'], this.cwd) ?? this.cwd);\n return this.repository;\n }\n\n setSessionId(sessionId: string): void {\n const trimmed = sessionId.trim();\n if (!trimmed) throw new Error('po-runner session id cannot be blank');\n this.adoptedSessionId = trimmed;\n }\n\n logDirectory(sessionId?: string): string {\n const override = this.env[LOG_DIR_ENV]?.trim();\n if (override) return path.resolve(this.cwd, override);\n return path.join(this.sessionDirectory(sessionId), LOG_DIR_NAME);\n }\n\n stateDirectory(sessionId?: string): string {\n const override = this.env[LOG_DIR_ENV]?.trim();\n if (override) return path.join(path.resolve(this.cwd, override), '..', STATE_DIR_NAME);\n return path.join(this.sessionDirectory(sessionId), STATE_DIR_NAME);\n }\n\n logPathFor(id: string, sessionId?: string): string {\n return path.join(this.logDirectory(sessionId), `${id}${LOG_EXTENSION}`);\n }\n\n rotatedLogPathFor(id: string, sessionId?: string): string {\n return `${this.logPathFor(id, sessionId)}${ROTATED_SUFFIX}`;\n }\n\n rawLogPathFor(id: string, sessionId?: string): string {\n return `${this.logPathFor(id, sessionId)}${RAW_SUFFIX}`;\n }\n\n statePathFor(id: string, sessionId?: string): string {\n return path.join(this.stateDirectory(sessionId), `${id}${STATE_EXTENSION}`);\n }\n\n ensureDirectories(sessionId?: string): void {\n fs.mkdirSync(this.logDirectory(sessionId), { recursive: true });\n fs.mkdirSync(this.stateDirectory(sessionId), { recursive: true });\n }\n\n sweepHistory(\n ttlMs: number,\n now: number = Date.now(),\n live: ReadonlySet<string> = this.liveSessions(),\n ): LogSweepResult {\n const result: LogSweepResult = { removed: [], errors: [] };\n // A pinned log directory belongs to whoever pinned it, so that branch only\n // ever removes the files this package put there.\n if (this.env[LOG_DIR_ENV]?.trim()) {\n // Without a live session there is no owner to sweep for, as before.\n const owner = [...live][0] ?? this.sessionId();\n this.sweepStateDirectory(this.stateDirectory(owner), owner, ttlMs, now, result);\n return result;\n }\n const root = this.storeDirectory();\n let sessions: string[];\n try {\n sessions = fs.readdirSync(root);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === NOT_FOUND_ERROR_CODE) return result;\n result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);\n return result;\n }\n\n // Sweeping whole session directories rather than the three files a completed\n // record names is what keeps sockets, sidecars, runs that never reached a\n // terminal state, and the emptied directories themselves from accumulating.\n for (const sessionId of sessions) {\n if (live.has(sessionId)) {\n this.sweepActiveSession(sessionId, ttlMs, now, result);\n continue;\n }\n this.sweepSessionDirectory(path.join(root, sessionId), ttlMs, now, result);\n }\n return result;\n }\n\n async sweepHistoryAsync(\n ttlMs: number,\n now: number = Date.now(),\n live: ReadonlySet<string> = this.liveSessions(),\n ): Promise<LogSweepResult> {\n const result: LogSweepResult = { removed: [], errors: [] };\n if (this.env[LOG_DIR_ENV]?.trim()) {\n const owner = [...live][0] ?? this.sessionId();\n await this.sweepStateDirectoryAsync(this.stateDirectory(owner), owner, ttlMs, now, result);\n return result;\n }\n\n const root = this.storeDirectory();\n let sessions: string[];\n try {\n sessions = await fs.promises.readdir(root);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === NOT_FOUND_ERROR_CODE) return result;\n result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);\n return result;\n }\n\n for (const sessionId of sessions) {\n if (live.has(sessionId)) {\n await this.sweepActiveSessionAsync(sessionId, ttlMs, now, result);\n continue;\n }\n await this.sweepSessionDirectoryAsync(path.join(root, sessionId), ttlMs, now, result);\n }\n return result;\n }\n\n /** The live session, if one is known, so a sweep never deletes underneath itself. */\n private liveSessions(): ReadonlySet<string> {\n try {\n return new Set([this.sessionId()]);\n } catch {\n // A CLI invocation outside a session still sweeps; it just has nothing to spare.\n return new Set();\n }\n }\n\n /**\n * Retention inside the session that is still running.\n *\n * The whole-directory sweep cannot be pointed at the live session: it would\n * take the lifeline socket, the supervisor sidecars and the running runners'\n * own metadata with it. Per-record retention is safe there because it only\n * ever removes a record whose state is `completed` together with the two log\n * files that record names, and never the directory itself. A running record\n * has no `exit.finishedAt`, so it is not a candidate at any age.\n */\n private sweepActiveSession(sessionId: string, ttlMs: number, now: number, result: LogSweepResult): void {\n this.sweepStateDirectory(this.stateDirectory(sessionId), sessionId, ttlMs, now, result);\n }\n\n private async sweepActiveSessionAsync(\n sessionId: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): Promise<void> {\n await this.sweepStateDirectoryAsync(this.stateDirectory(sessionId), sessionId, ttlMs, now, result);\n }\n\n /** Removes a session's whole directory once its newest entry is past the TTL. */\n private sweepSessionDirectory(directory: string, ttlMs: number, now: number, result: LogSweepResult): void {\n try {\n const newest = newestEntryTime(directory);\n // An orphan left by a session that never ran anything holds nothing worth\n // a retention window, so it goes as soon as it is clearly not in use.\n if (now - newest > EMPTY_SESSION_GRACE_MS && isEmptySession(directory)) {\n fs.rmSync(directory, { recursive: true, force: true });\n result.removed.push(directory);\n return;\n }\n if (now - newest <= ttlMs) return;\n // An idle session can go quiet for longer than the TTL, and deleting one\n // takes its lifeline socket with it, which would read to its own runners\n // as an owner that had died. Its records name the owner, so ask.\n if (ownerAlive(path.join(directory, STATE_DIR_NAME))) return;\n fs.rmSync(directory, { recursive: true, force: true });\n result.removed.push(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not sweep runner session ${directory}: ${String(error)}`);\n }\n }\n }\n\n private async sweepSessionDirectoryAsync(\n directory: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): Promise<void> {\n try {\n const newest = await newestEntryTimeAsync(directory);\n if (now - newest > EMPTY_SESSION_GRACE_MS && (await isEmptySessionAsync(directory))) {\n await fs.promises.rm(directory, { recursive: true, force: true });\n result.removed.push(directory);\n return;\n }\n if (now - newest <= ttlMs) return;\n if (await ownerAliveAsync(path.join(directory, STATE_DIR_NAME))) return;\n await fs.promises.rm(directory, { recursive: true, force: true });\n result.removed.push(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not sweep runner session ${directory}: ${String(error)}`);\n }\n }\n }\n\n private sessionId(explicit?: string): string {\n const sessionId = explicit?.trim() || this.adoptedSessionId || inheritedSessionId(this.env);\n if (!sessionId) throw new Error('PI_SESSION_ID is required for po-runner storage');\n return sessionId;\n }\n\n storeDirectory(): string {\n const override = this.env[LOG_DIR_ENV]?.trim();\n if (override) return path.dirname(path.resolve(this.cwd, override));\n return resolveRunnerStoreDirectory(this.env);\n }\n\n private sessionDirectory(sessionId?: string): string {\n return path.join(this.storeDirectory(), this.sessionId(sessionId));\n }\n\n private sweepStateDirectory(\n directory: string,\n sessionId: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): void {\n let entries: string[];\n try {\n entries = fs.readdirSync(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not read runner state directory ${directory}: ${String(error)}`);\n }\n return;\n }\n\n const completed: CompletedRecord[] = [];\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n const statePath = path.join(directory, entry);\n try {\n const value: unknown = JSON.parse(fs.readFileSync(statePath, FILE_ENCODING));\n const finishedAt = completedAt(value);\n if (finishedAt === undefined) continue;\n completed.push({ id: entry.slice(0, -STATE_EXTENSION.length), statePath, finishedAt });\n } catch (error) {\n result.errors.push(`Could not sweep runner metadata ${statePath}: ${String(error)}`);\n }\n }\n\n for (const record of expiredCompletedRecords(completed, ttlMs, now, getMaxCompletedRunners(this.env))) {\n this.removeHistoryFiles(sessionId, record.id, record.statePath, result);\n }\n }\n\n private async sweepStateDirectoryAsync(\n directory: string,\n sessionId: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): Promise<void> {\n let entries: string[];\n try {\n entries = await fs.promises.readdir(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not read runner state directory ${directory}: ${String(error)}`);\n }\n return;\n }\n\n const completed: CompletedRecord[] = [];\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n const statePath = path.join(directory, entry);\n try {\n const value: unknown = JSON.parse(await fs.promises.readFile(statePath, FILE_ENCODING));\n const finishedAt = completedAt(value);\n if (finishedAt === undefined) continue;\n completed.push({ id: entry.slice(0, -STATE_EXTENSION.length), statePath, finishedAt });\n } catch (error) {\n result.errors.push(`Could not sweep runner metadata ${statePath}: ${String(error)}`);\n }\n }\n\n for (const record of expiredCompletedRecords(completed, ttlMs, now, getMaxCompletedRunners(this.env))) {\n await this.removeHistoryFilesAsync(sessionId, record.id, record.statePath, result);\n }\n }\n\n private removeHistoryFiles(sessionId: string, id: string, statePath: string, result: LogSweepResult): void {\n const candidates = [\n statePath,\n this.logPathFor(id, sessionId),\n this.rotatedLogPathFor(id, sessionId),\n this.rawLogPathFor(id, sessionId),\n ];\n for (const candidate of candidates) {\n try {\n fs.unlinkSync(candidate);\n result.removed.push(candidate);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not remove runner history ${candidate}: ${String(error)}`);\n }\n }\n }\n }\n\n private async removeHistoryFilesAsync(\n sessionId: string,\n id: string,\n statePath: string,\n result: LogSweepResult,\n ): Promise<void> {\n const candidates = [statePath, this.logPathFor(id, sessionId), this.rotatedLogPathFor(id, sessionId)];\n for (const candidate of candidates) {\n try {\n await fs.promises.unlink(candidate);\n result.removed.push(candidate);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not remove runner history ${candidate}: ${String(error)}`);\n }\n }\n }\n }\n}\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_runnerPaths = require("./runnerPaths-BTEuzxw0.cjs");
2
+ const require_runnerPaths = require("./runnerPaths-B41rMOY6.cjs");
3
3
  exports.RunnerPaths = require_runnerPaths.RunnerPaths;
@@ -1,4 +1,4 @@
1
- import { n as LogSweepResult, t as IRunnerPaths } from "./type-BXM03qSw.mjs";
1
+ import { n as LogSweepResult, t as IRunnerPaths } from "./type-DwMZoINK.mjs";
2
2
  //#region src/services/runnerPaths/index.d.ts
3
3
  /** Session-scoped runner storage under the Pi agent directory. */
4
4
  export declare class RunnerPaths implements IRunnerPaths {
@@ -16,12 +16,10 @@ export declare class RunnerPaths implements IRunnerPaths {
16
16
  rawLogPathFor(id: string, sessionId?: string): string;
17
17
  statePathFor(id: string, sessionId?: string): string;
18
18
  ensureDirectories(sessionId?: string): void;
19
- sweepHistory(ttlMs: number, now?: number): LogSweepResult;
20
- sweepHistoryAsync(ttlMs: number, now?: number): Promise<LogSweepResult>;
21
- legacyDirectory(): string | undefined;
22
- removeLegacyStore(): string | undefined;
19
+ sweepHistory(ttlMs: number, now?: number, live?: ReadonlySet<string>): LogSweepResult;
20
+ sweepHistoryAsync(ttlMs: number, now?: number, live?: ReadonlySet<string>): Promise<LogSweepResult>;
23
21
  /** The live session, if one is known, so a sweep never deletes underneath itself. */
24
- private currentSessionId;
22
+ private liveSessions;
25
23
  /**
26
24
  * Retention inside the session that is still running.
27
25
  *
@@ -38,7 +36,7 @@ export declare class RunnerPaths implements IRunnerPaths {
38
36
  private sweepSessionDirectory;
39
37
  private sweepSessionDirectoryAsync;
40
38
  private sessionId;
41
- private storeDirectory;
39
+ storeDirectory(): string;
42
40
  private sessionDirectory;
43
41
  private sweepStateDirectory;
44
42
  private sweepStateDirectoryAsync;
@@ -1 +1 @@
1
- {"version":3,"file":"runnerPaths.d.mts","names":[],"sources":["../src/services/runnerPaths/index.ts"],"mappings":";;;qBA8Ma,uBAAuB;mBAKf;mBACA;UALX;UACA;EAER,YACmB,cACA,MAAK,SAAS;EAGjC;EAKA,aAAa;EAMb,aAAa;EAMb,eAAe;EAMf,WAAW,YAAY;EAIvB,kBAAkB,YAAY;EAI9B,cAAc,YAAY;EAI1B,aAAa,YAAY;EAIzB,kBAAkB;EAKlB,aAAa,eAAe,eAA2B;EAgCjD,kBAAkB,eAAe,eAA2B,QAAQ;EA4B1E;EAMA;;UAQQ;;;;;;;;;;;UAmBA;UAIM;;UAUN;UAwBM;UAwBN;UAMA;UAMA;UAIA;UAoCM;UAoCN;UAmBM"}
1
+ {"version":3,"file":"runnerPaths.d.mts","names":[],"sources":["../src/services/runnerPaths/index.ts"],"mappings":";;;qBA8Ma,uBAAuB;mBAKf;mBACA;UALX;UACA;EAER,YACmB,cACA,MAAK,SAAS;EAGjC;EAKA,aAAa;EAMb,aAAa;EAMb,eAAe;EAMf,WAAW,YAAY;EAIvB,kBAAkB,YAAY;EAI9B,cAAc,YAAY;EAI1B,aAAa,YAAY;EAIzB,kBAAkB;EAKlB,aACE,eACA,cACA,OAAM,sBACL;EAiCG,kBACJ,eACA,cACA,OAAM,sBACL,QAAQ;;UA6BH;;;;;;;;;;;UAmBA;UAIM;;UAUN;UAwBM;UAwBN;EAMR;UAMQ;UAIA;UAoCM;UAoCN;UAmBM"}
@@ -1,2 +1 @@
1
- import { t as RunnerPaths } from "./runnerPaths-B_dAAeco.mjs";
2
- export { RunnerPaths };
1
+ export { t as RunnerPaths } from "./runnerPaths-Dibbvyx_.mjs";
@@ -6,8 +6,8 @@ import { createProcessRegistryService, normalizeRepositoryPath, resolveProcessTa
6
6
  import { resolveRootSessionId } from "@agimon-ai/po-core/childProcess";
7
7
  //#region src/constants/runnerRegistry.ts
8
8
  const SERVICE_TYPE = "tool";
9
- const SERVICE_PREFIX = "doom-runner:";
10
- const RUNNER_TAG = "doom-runner";
9
+ const SERVICE_PREFIX = "po-runner:";
10
+ const RUNNER_TAG = "po-runner";
11
11
  const REGISTRY_PATH_ENV = "PROCESS_REGISTRY_PATH";
12
12
  //#endregion
13
13
  //#region src/services/runnerRecord/index.ts
@@ -25,9 +25,16 @@ function formatRunnerFinished(record) {
25
25
  `Background runner ${record.name} exited: ${outcome}${code}.`,
26
26
  `Runner ID: ${record.id}`,
27
27
  `Log: ${record.logPath}`,
28
- `Inspect: doom-runner logs ${record.id}`
28
+ `Inspect: po-runner logs ${record.id}`
29
29
  ].join("\n");
30
30
  }
31
+ /** The one line the person sees in the transcript for the same exit. */
32
+ function formatRunnerFinishedNotice(record) {
33
+ const reason = record.exit?.reason ?? record.state;
34
+ const code = record.exit?.code === null || record.exit?.code === void 0 ? "" : `exit ${record.exit.code}`;
35
+ const outcome = reason === "completed" ? code : [reason, code].filter(Boolean).join(", ");
36
+ return `Background runner ${record.name} finished${outcome ? ` · ${outcome}` : ""}`;
37
+ }
31
38
  /** Compact footer text. An absent value removes the group entirely. */
32
39
  function formatRunnerStatus(count) {
33
40
  return count > 0 ? `Runners ${count} ●` : void 0;
@@ -150,12 +157,6 @@ var RunnerRegistry = class {
150
157
  tags: resolveProcessTags([RUNNER_TAG])
151
158
  })).map(toRunnerRecord);
152
159
  }
153
- async listAcrossRepositories() {
154
- return (await this.registry.listProcesses({
155
- serviceType: SERVICE_TYPE,
156
- tags: resolveProcessTags([RUNNER_TAG])
157
- })).map(toRunnerRecord);
158
- }
159
160
  async listBySession(sessionId) {
160
161
  return (await this.list()).filter((record) => record.sessionId === sessionId);
161
162
  }
@@ -334,6 +335,6 @@ function isPrimaryMetadataEntry(entry) {
334
335
  return entry.endsWith(".json") && !entry.endsWith(".command.json") && !entry.endsWith(".exit.json");
335
336
  }
336
337
  //#endregion
337
- export { isRunnerRecord as a, formatRunnerStatus as i, createDefaultProcessRegistry as n, formatRunnerFinished as r, RunnerRegistry as t };
338
+ export { formatRunnerStatus as a, formatRunnerFinishedNotice as i, createDefaultProcessRegistry as n, isRunnerRecord as o, formatRunnerFinished as r, REGISTRY_PATH_ENV as s, RunnerRegistry as t };
338
339
 
339
- //# sourceMappingURL=runnerRegistry-CeOHEjBv.mjs.map
340
+ //# sourceMappingURL=runnerRegistry-BgaR5O86.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runnerRegistry-BgaR5O86.mjs","names":[],"sources":["../src/constants/runnerRegistry.ts","../src/services/runnerRecord/index.ts","../src/services/runnerRegistry/index.ts"],"sourcesContent":["export const SERVICE_TYPE = 'tool';\nexport const SERVICE_PREFIX = 'po-runner:';\nexport const RUNNER_TAG = 'po-runner';\nexport const REGISTRY_PATH_ENV = 'PROCESS_REGISTRY_PATH';\nexport const JSON_EXTENSION = '.json';\nexport const COMMAND_SIDECAR_SUFFIX = '.command.json';\nexport const EXIT_SIDECAR_SUFFIX = '.exit.json';\nexport const NOT_FOUND_ERROR_CODE = 'ENOENT';\n","import type { RunnerRecord } from '../../types/runnerRegistry';\n\n/** The disk record's shape guard, shared by the registry and every reader of its files. */\nexport function isRunnerRecord(value: unknown): value is RunnerRecord {\n if (typeof value !== 'object' || value === null) return false;\n const record = value as Partial<RunnerRecord>;\n return (\n typeof record.id === 'string' &&\n typeof record.name === 'string' &&\n typeof record.pid === 'number' &&\n typeof record.command === 'string' &&\n typeof record.cwd === 'string' &&\n typeof record.logPath === 'string' &&\n typeof record.sessionId === 'string' &&\n typeof record.startedAt === 'string' &&\n (record.state === 'running' || record.state === 'completed') &&\n typeof record.promoted === 'boolean' &&\n (record.backend === 'rmux' || record.backend === 'tmux' || record.backend === 'native')\n );\n}\n\n/** What the agent reads when a runner it sent to the background exits. Shared by the Pi and server hosts. */\nexport function formatRunnerFinished(record: RunnerRecord): string {\n const outcome = record.exit?.reason ?? record.state;\n const code = record.exit?.code === null || record.exit?.code === undefined ? '' : `, exit code ${record.exit.code}`;\n return [\n `Background runner ${record.name} exited: ${outcome}${code}.`,\n `Runner ID: ${record.id}`,\n `Log: ${record.logPath}`,\n `Inspect: po-runner logs ${record.id}`,\n ].join('\\n');\n}\n\n/** The one line the person sees in the transcript for the same exit. */\nexport function formatRunnerFinishedNotice(record: RunnerRecord): string {\n const reason = record.exit?.reason ?? record.state;\n const code = record.exit?.code === null || record.exit?.code === undefined ? '' : `exit ${record.exit.code}`;\n const outcome = reason === 'completed' ? code : [reason, code].filter(Boolean).join(', ');\n return `Background runner ${record.name} finished${outcome ? ` · ${outcome}` : ''}`;\n}\n/** Compact footer text. An absent value removes the group entirely. */\nexport function formatRunnerStatus(count: number): string | undefined {\n return count > 0 ? `Runners ${count} ●` : undefined;\n}\n\nexport function formatRunnerFooterContribution(count: number): { fullText: string; compactText: string } | undefined {\n return count > 0 ? { fullText: `Runner ${count}`, compactText: `R${count}` } : undefined;\n}\n","import { execFile } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport {\n createProcessRegistryService,\n normalizeRepositoryPath,\n type ProcessRegistryRecord,\n type ProcessRegistryService,\n resolveProcessTags,\n} from '@agimon-ai/foundation-process-registry';\nimport { resolveRootSessionId } from '@agimon-ai/po-core/childProcess';\n\nimport {\n COMMAND_SIDECAR_SUFFIX,\n EXIT_SIDECAR_SUFFIX,\n JSON_EXTENSION,\n NOT_FOUND_ERROR_CODE,\n REGISTRY_PATH_ENV,\n RUNNER_TAG,\n SERVICE_PREFIX,\n SERVICE_TYPE,\n} from '../../constants/runnerRegistry';\nimport type { IProcessControl } from '../../types/processControl';\nimport type {\n CompleteRunnerInput,\n IRunnerRegistry,\n RegisterRunnerInput,\n RunnerRecord,\n RunnerTerminationIntent,\n} from '../../types/runnerRegistry';\nimport type { IRunnerPaths } from '../runnerPaths/type';\nimport { isRunnerRecord } from '../runnerRecord';\n\n/** The slice of the shared registry service this wrapper depends on. */\nexport type ProcessRegistryPort = Pick<\n ProcessRegistryService,\n 'registerProcess' | 'releaseProcess' | 'listProcesses' | 'close'\n>;\n\n/** Opens the SQLite-backed registry the rest of the monorepo already shares. */\nexport function createDefaultProcessRegistry(\n env: Readonly<Record<string, string | undefined>> = process.env,\n): ProcessRegistryPort {\n return createProcessRegistryService(env[REGISTRY_PATH_ENV]);\n}\n\nfunction sessionTag(sessionId: string): string {\n return `session:${sessionId}`;\n}\n\nfunction readString(record: ProcessRegistryRecord, key: string): string {\n const value = record.metadata?.[key];\n return typeof value === 'string' ? value : '';\n}\n\nfunction readNumber(record: ProcessRegistryRecord, key: string): number {\n const value = record.metadata?.[key];\n return typeof value === 'number' ? value : 0;\n}\n\nconst runCommand = promisify(execFile);\n\n/**\n * The process start time the registry stores to prove a pid is still the\n * process it registered.\n *\n * The registry resolves it itself when the caller omits it, and it does so with\n * `execFileSync`, which stops this process for the length of a `ps` on every\n * runner that starts. Reading it here costs the same subprocess and blocks\n * nothing: the command is already running by the time a runner is registered.\n *\n * The value has to match what the registry would have read, so the command and\n * the trimming are deliberately identical to its own.\n */\nasync function processStartedAt(pid: number): Promise<string | undefined> {\n if (process.platform === 'win32') return undefined;\n try {\n const { stdout } = await runCommand('ps', ['-o', 'lstart=', '-p', String(pid)], { encoding: 'utf8' });\n return stdout.trim() || undefined;\n } catch {\n return undefined;\n }\n}\n\ntype ListenerRegistration = Readonly<{ key: string; listener: () => void }>;\n\n// Server plugin replacement can leave an in-flight tool and its publisher on different registry instances.\nconst listenersBySession = new Map<string, Set<() => void>>();\n\nexport class RunnerRegistry implements IRunnerRegistry {\n private readonly subscriptions = new Set<ListenerRegistration>();\n\n constructor(\n private readonly paths: IRunnerPaths,\n private readonly processControl: IProcessControl,\n private readonly registry: ProcessRegistryPort,\n private readonly environment: Readonly<Record<string, string | undefined>>,\n ) {}\n\n async register(input: RegisterRunnerInput): Promise<RunnerRecord> {\n const startedAt = new Date().toISOString();\n const rootSessionId = resolveRootSessionId(input.sessionId, this.environment);\n const identity = await processStartedAt(input.pid);\n const response = await this.registry.registerProcess({\n repositoryPath: this.repositoryPath(),\n serviceName: `${SERVICE_PREFIX}${input.id}`,\n serviceType: SERVICE_TYPE,\n pid: input.pid,\n command: input.command,\n ...(identity === undefined ? {} : { processStartedAt: identity }),\n tags: resolveProcessTags([RUNNER_TAG, `runner:${input.id}`, sessionTag(input.sessionId)]),\n metadata: {\n id: input.id,\n name: input.name,\n command: input.command,\n cwd: input.cwd,\n logPath: input.logPath,\n interactive: input.interactive,\n sessionId: input.sessionId,\n rootSessionId,\n backend: input.backend,\n ...(input.backendTarget ? { backendTarget: input.backendTarget } : {}),\n startedAt,\n hostPid: process.pid,\n },\n // The caller has already resolved name collisions against live records,\n // so anything still holding this name is stale.\n force: true,\n });\n if (!response.success) throw new Error(response.error ?? `Failed to register runner ${input.name}`);\n const record: RunnerRecord = {\n id: input.id,\n name: input.name,\n pid: input.pid,\n command: input.command,\n cwd: input.cwd,\n logPath: input.logPath,\n interactive: input.interactive,\n sessionId: input.sessionId,\n rootSessionId,\n startedAt,\n state: 'running',\n promoted: false,\n backend: input.backend,\n ...(input.backendTarget ? { backendTarget: input.backendTarget } : {}),\n hostPid: process.pid,\n };\n this.writeRecord(record);\n this.notify(record.sessionId);\n return record;\n }\n\n async list(): Promise<RunnerRecord[]> {\n const records = await this.registry.listProcesses({\n repositoryPath: this.repositoryPath(),\n serviceType: SERVICE_TYPE,\n tags: resolveProcessTags([RUNNER_TAG]),\n });\n return records.map(toRunnerRecord);\n }\n\n async listBySession(sessionId: string): Promise<RunnerRecord[]> {\n const records = await this.list();\n return records.filter((record) => record.sessionId === sessionId);\n }\n\n async listByRootSession(rootSessionId: string): Promise<RunnerRecord[]> {\n const records = await this.list();\n return records.filter((record) => (record.rootSessionId ?? record.sessionId) === rootSessionId);\n }\n\n async listAll(sessionId?: string): Promise<RunnerRecord[]> {\n this.paths.ensureDirectories(sessionId);\n const records: RunnerRecord[] = [];\n const directory = this.paths.stateDirectory(sessionId);\n for (const entry of fs.readdirSync(directory)) {\n if (!isPrimaryMetadataEntry(entry)) continue;\n try {\n const parsed: unknown = JSON.parse(fs.readFileSync(`${directory}/${entry}`, 'utf8'));\n if (isRunnerRecord(parsed)) records.push(parsed);\n } catch (error) {\n process.emitWarning(`Could not read runner metadata ${entry}: ${String(error)}`);\n }\n }\n return records.sort((left, right) => right.startedAt.localeCompare(left.startedAt));\n }\n\n async get(id: string, sessionId?: string): Promise<RunnerRecord | undefined> {\n const target = this.paths.statePathFor(id, sessionId);\n try {\n const parsed: unknown = JSON.parse(fs.readFileSync(target, 'utf8'));\n if (!isRunnerRecord(parsed) || parsed.id !== id) {\n process.emitWarning(`Could not read runner metadata ${path.basename(target)}: invalid runner record`);\n return undefined;\n }\n return parsed;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === NOT_FOUND_ERROR_CODE) return undefined;\n process.emitWarning(`Could not read runner metadata ${path.basename(target)}: ${String(error)}`);\n return undefined;\n }\n }\n\n async markPromoted(id: string): Promise<RunnerRecord | undefined> {\n const record = await this.get(id);\n if (!record) return undefined;\n const promoted = { ...record, promoted: true };\n this.writeRecord(promoted);\n this.notify(promoted.sessionId);\n return promoted;\n }\n\n async requestTermination(\n id: string,\n intent: RunnerTerminationIntent | undefined,\n sessionId?: string,\n ): Promise<RunnerRecord | undefined> {\n const record = await this.get(id, sessionId);\n if (!record) return undefined;\n if (record.state === 'completed') return record;\n if (intent !== undefined && record.terminationIntent !== undefined) return record;\n const { terminationIntent: _previous, ...rest } = record;\n const updated: RunnerRecord = { ...rest, ...(intent ? { terminationIntent: intent } : {}) };\n this.writeRecord(updated);\n return updated;\n }\n\n async complete(id: string, outcome: CompleteRunnerInput, sessionId?: string): Promise<RunnerRecord | undefined> {\n const persisted = await this.get(id, sessionId);\n if (persisted?.state === 'completed') {\n await this.release(id, persisted.sessionId);\n return persisted;\n }\n const active = await this.list();\n const record =\n persisted ??\n active.find((candidate) => candidate.id === id && (sessionId === undefined || candidate.sessionId === sessionId));\n if (!record) {\n const belongsToAnotherSession =\n sessionId !== undefined && active.some((candidate) => candidate.id === id && candidate.sessionId !== sessionId);\n if (!belongsToAnotherSession) await this.release(id, sessionId);\n return undefined;\n }\n const completed: RunnerRecord = {\n ...record,\n state: 'completed',\n exit: {\n ...outcome,\n ...(outcome.signal !== null && outcome.terminationReason === undefined && record.terminationIntent === undefined\n ? { terminationReason: 'external_signal' as const }\n : {}),\n ...record.terminationIntent,\n finishedAt: new Date().toISOString(),\n },\n };\n this.writeRecord(completed);\n await this.release(id, completed.sessionId);\n return completed;\n }\n\n async release(id: string, sessionId?: string): Promise<void> {\n const activeSessionId = sessionId ?? (await this.list()).find((record) => record.id === id)?.sessionId;\n const ownedSessionId = activeSessionId ?? (await this.get(id))?.sessionId;\n const response = await this.registry.releaseProcess({\n repositoryPath: this.repositoryPath(),\n serviceName: `${SERVICE_PREFIX}${id}`,\n serviceType: SERVICE_TYPE,\n kill: false,\n releasePort: false,\n force: true,\n });\n if (!response.success && !response.error?.includes('No matching process entry')) {\n throw new Error(response.error ?? `Failed to release runner ${id}`);\n }\n if (ownedSessionId !== undefined) this.notify(ownedSessionId);\n }\n\n async pruneDead(): Promise<string[]> {\n const dead = (await this.list()).filter((record) => !this.processControl.isAlive(record.pid));\n for (const record of dead) {\n await this.complete(record.id, { reason: 'backend_lost', code: null, signal: null }, record.sessionId);\n }\n return dead.map((record) => record.id);\n }\n\n subscribe(listener: () => void, sessionId: string): () => void {\n const subscribed = (): void => listener();\n const registration = { key: this.subscriptionKey(sessionId), listener: subscribed };\n const listeners = listenersBySession.get(registration.key) ?? new Set<() => void>();\n listeners.add(subscribed);\n listenersBySession.set(registration.key, listeners);\n this.subscriptions.add(registration);\n return () => this.removeSubscription(registration);\n }\n\n close(): void {\n for (const registration of this.subscriptions) this.removeSubscription(registration);\n this.registry.close();\n }\n\n private notify(sessionId: string): void {\n for (const listener of listenersBySession.get(this.subscriptionKey(sessionId)) ?? []) {\n try {\n listener();\n } catch (error) {\n process.emitWarning(`Runner registry listener failed: ${String(error)}`);\n }\n }\n }\n\n private removeSubscription(registration: ListenerRegistration): void {\n const listeners = listenersBySession.get(registration.key);\n listeners?.delete(registration.listener);\n if (listeners?.size === 0) listenersBySession.delete(registration.key);\n this.subscriptions.delete(registration);\n }\n\n private subscriptionKey(sessionId: string): string {\n return JSON.stringify([path.resolve(this.paths.stateDirectory(sessionId)), sessionId]);\n }\n\n private repositoryPath(): string {\n return normalizeRepositoryPath(this.paths.repositoryPath());\n }\n\n private writeRecord(record: RunnerRecord): void {\n this.paths.ensureDirectories(record.sessionId);\n const target = this.paths.statePathFor(record.id, record.sessionId);\n const temporary = `${target}.${process.pid}.tmp`;\n fs.writeFileSync(temporary, `${JSON.stringify(record, null, 2)}\\n`, 'utf8');\n fs.renameSync(temporary, target);\n }\n}\n\n/** Every field is read back from metadata this class wrote on registration. */\nfunction toRunnerRecord(record: ProcessRegistryRecord): RunnerRecord {\n return {\n id: readString(record, 'id'),\n name: readString(record, 'name'),\n pid: record.pid,\n command: readString(record, 'command'),\n cwd: readString(record, 'cwd'),\n logPath: readString(record, 'logPath'),\n interactive: record.metadata?.interactive === true,\n sessionId: readString(record, 'sessionId'),\n ...(readString(record, 'rootSessionId') ? { rootSessionId: readString(record, 'rootSessionId') } : {}),\n startedAt: readString(record, 'startedAt'),\n state: 'running',\n promoted: false,\n backend: readBackend(record.metadata?.backend),\n ...(readString(record, 'backendTarget') ? { backendTarget: readString(record, 'backendTarget') } : {}),\n hostPid: readNumber(record, 'hostPid'),\n };\n}\n\nfunction readBackend(value: unknown): RunnerRecord['backend'] {\n return value === 'rmux' || value === 'tmux' ? value : 'native';\n}\n\nfunction isPrimaryMetadataEntry(entry: string): boolean {\n return (\n entry.endsWith(JSON_EXTENSION) && !entry.endsWith(COMMAND_SIDECAR_SUFFIX) && !entry.endsWith(EXIT_SIDECAR_SUFFIX)\n );\n}\n"],"mappings":"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"}
@@ -63,8 +63,6 @@ interface CompleteRunnerInput {
63
63
  interface IRunnerRegistry {
64
64
  register(input: RegisterRunnerInput): Promise<RunnerRecord>;
65
65
  list(): Promise<RunnerRecord[]>;
66
- /** Active doom-runner records across repository scopes, used only for safe legacy-store cleanup. */
67
- listAcrossRepositories(): Promise<RunnerRecord[]>;
68
66
  /** Active records started by one session, used for scoped bulk stop and shutdown. */
69
67
  listBySession(sessionId: string): Promise<RunnerRecord[]>;
70
68
  /** Active records visible to every descendant of one root Pi session. */
@@ -85,4 +83,4 @@ interface IRunnerRegistry {
85
83
  }
86
84
  //#endregion
87
85
  export { RunnerTerminationIntent as a, RunnerRecord as i, IRunnerRegistry as n, RegisterRunnerInput as r, CompleteRunnerInput as t };
88
- //# sourceMappingURL=runnerRegistry-CtJiD02R.d.mts.map
86
+ //# sourceMappingURL=runnerRegistry-V-Ocaf4N.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runnerRegistry-CtJiD02R.d.mts","names":[],"sources":["../src/types/runnerRegistry.ts"],"mappings":";KAAY;KACA;KACA;KASA;KAOA;EACV;EACA,mBAAmB,QAAQ;EAC3B;;UAGe;EACf,QAAQ;EACR;EACA,QAAQ,OAAO;EACf,oBAAoB;EACpB;EACA;;;UAIe;EACf;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA,OAAO;EACP;EACA,SAAS;EACT;EACA,OAAO;;EAEP,oBAAoB;;EAEpB;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS;EACT;;UAGe;EACf,QAAQ;EACR;EACA,QAAQ,OAAO;EACf,oBAAoB;EACpB;;;UAIe;EACf,SAAS,OAAO,sBAAsB,QAAQ;EAC9C,QAAQ,QAAQ;;EAEhB,0BAA0B,QAAQ;;EAElC,cAAc,oBAAoB,QAAQ;;EAE1C,kBAAkB,wBAAwB,QAAQ;;EAElD,QAAQ,qBAAqB,QAAQ;EACrC,IAAI,YAAY,qBAAqB,QAAQ;EAC7C,aAAa,aAAa,QAAQ;EAClC,mBACE,YACA,QAAQ,qCACR,qBACC,QAAQ;EACX,SAAS,YAAY,SAAS,qBAAqB,qBAAqB,QAAQ;;EAEhF,QAAQ,YAAY,qBAAqB;;EAEzC,aAAa;;EAEb,UAAU,sBAAsB;EAChC"}
1
+ {"version":3,"file":"runnerRegistry-V-Ocaf4N.d.mts","names":[],"sources":["../src/types/runnerRegistry.ts"],"mappings":";KAAY;KACA;KACA;KASA;KAOA;EACV;EACA,mBAAmB,QAAQ;EAC3B;;UAGe;EACf,QAAQ;EACR;EACA,QAAQ,OAAO;EACf,oBAAoB;EACpB;EACA;;;UAIe;EACf;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA,OAAO;EACP;EACA,SAAS;EACT;EACA,OAAO;;EAEP,oBAAoB;;EAEpB;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS;EACT;;UAGe;EACf,QAAQ;EACR;EACA,QAAQ,OAAO;EACf,oBAAoB;EACpB;;;UAIe;EACf,SAAS,OAAO,sBAAsB,QAAQ;EAC9C,QAAQ,QAAQ;;EAEhB,cAAc,oBAAoB,QAAQ;;EAE1C,kBAAkB,wBAAwB,QAAQ;;EAElD,QAAQ,qBAAqB,QAAQ;EACrC,IAAI,YAAY,qBAAqB,QAAQ;EAC7C,aAAa,aAAa,QAAQ;EAClC,mBACE,YACA,QAAQ,qCACR,qBACC,QAAQ;EACX,SAAS,YAAY,SAAS,qBAAqB,qBAAqB,QAAQ;;EAEhF,QAAQ,YAAY,qBAAqB;;EAEzC,aAAa;;EAEb,UAAU,sBAAsB;EAChC"}