@agimon-ai/doompi-runner 0.0.1-alpha.2 → 0.0.1-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 (293) hide show
  1. package/README.md +25 -16
  2. package/dist/adapters/RunnerPaths.cjs +2 -0
  3. package/dist/adapters/RunnerPaths.cjs.map +1 -0
  4. package/dist/adapters/RunnerPaths.d.cts +35 -0
  5. package/dist/adapters/RunnerPaths.d.cts.map +1 -0
  6. package/dist/adapters/RunnerPaths.d.mts +35 -0
  7. package/dist/adapters/RunnerPaths.d.mts.map +1 -0
  8. package/dist/adapters/RunnerPaths.mjs +2 -0
  9. package/dist/adapters/RunnerPaths.mjs.map +1 -0
  10. package/dist/adapters/pi/extension.cjs +3 -0
  11. package/dist/adapters/pi/extension.cjs.map +1 -0
  12. package/dist/adapters/pi/extension.d.cts +10 -0
  13. package/dist/adapters/pi/extension.d.cts.map +1 -0
  14. package/dist/adapters/pi/extension.d.mts +10 -0
  15. package/dist/adapters/pi/extension.d.mts.map +1 -0
  16. package/dist/adapters/pi/extension.mjs +3 -0
  17. package/dist/adapters/pi/extension.mjs.map +1 -0
  18. package/dist/adapters/pty/ptyProvider.cjs +2 -0
  19. package/dist/adapters/pty/ptyProvider.cjs.map +1 -0
  20. package/dist/adapters/pty/ptyProvider.d.cts +13 -0
  21. package/dist/adapters/pty/ptyProvider.d.cts.map +1 -0
  22. package/dist/adapters/pty/ptyProvider.d.mts +13 -0
  23. package/dist/adapters/pty/ptyProvider.d.mts.map +1 -0
  24. package/dist/adapters/pty/ptyProvider.mjs +2 -0
  25. package/dist/adapters/pty/ptyProvider.mjs.map +1 -0
  26. package/dist/bin/cli.cjs +1 -1
  27. package/dist/bin/cli.cjs.map +1 -1
  28. package/dist/bin/cli.mjs +1 -1
  29. package/dist/bin/cli.mjs.map +1 -1
  30. package/dist/bin/logSink.cjs.map +1 -1
  31. package/dist/bin/logSink.mjs.map +1 -1
  32. package/dist/bin/runnerHost.cjs.map +1 -1
  33. package/dist/bin/runnerHost.mjs.map +1 -1
  34. package/dist/cli/cliApp.cjs +1 -6
  35. package/dist/cli/cliApp.d.cts +2 -23
  36. package/dist/cli/cliApp.d.mts +2 -23
  37. package/dist/cli/cliApp.mjs +1 -6
  38. package/dist/commands/bash/bashTool.cjs +7 -0
  39. package/dist/commands/bash/bashTool.cjs.map +1 -0
  40. package/dist/commands/bash/bashTool.d.cts +25 -0
  41. package/dist/commands/bash/bashTool.d.cts.map +1 -0
  42. package/dist/commands/bash/bashTool.d.mts +25 -0
  43. package/dist/commands/bash/bashTool.d.mts.map +1 -0
  44. package/dist/commands/bash/bashTool.mjs +7 -0
  45. package/dist/commands/bash/bashTool.mjs.map +1 -0
  46. package/dist/commands/bash/responseEnvelope.cjs +10 -0
  47. package/dist/commands/bash/responseEnvelope.cjs.map +1 -0
  48. package/dist/commands/bash/responseEnvelope.d.cts +45 -0
  49. package/dist/commands/bash/responseEnvelope.d.cts.map +1 -0
  50. package/dist/commands/bash/responseEnvelope.d.mts +45 -0
  51. package/dist/commands/bash/responseEnvelope.d.mts.map +1 -0
  52. package/dist/commands/bash/responseEnvelope.mjs +10 -0
  53. package/dist/{tool/responseEnvelope.cjs.map → commands/bash/responseEnvelope.mjs.map} +1 -1
  54. package/dist/commands/cli/cliApp.cjs +6 -0
  55. package/dist/commands/cli/cliApp.cjs.map +1 -0
  56. package/dist/commands/cli/cliApp.d.cts +23 -0
  57. package/dist/commands/cli/cliApp.d.cts.map +1 -0
  58. package/dist/commands/cli/cliApp.d.mts +23 -0
  59. package/dist/commands/cli/cliApp.d.mts.map +1 -0
  60. package/dist/commands/cli/cliApp.mjs +6 -0
  61. package/dist/commands/cli/cliApp.mjs.map +1 -0
  62. package/dist/compaction.cjs +1 -4
  63. package/dist/compaction.d.cts +2 -14
  64. package/dist/compaction.d.mts +2 -14
  65. package/dist/compaction.mjs +1 -4
  66. package/dist/config.cjs +1 -2
  67. package/dist/config.d.cts +2 -32
  68. package/dist/config.d.mts +2 -32
  69. package/dist/config.mjs +1 -2
  70. package/dist/container/index.cjs +1 -1
  71. package/dist/container/index.cjs.map +1 -1
  72. package/dist/container/index.mjs +1 -1
  73. package/dist/container/index.mjs.map +1 -1
  74. package/dist/extension.cjs +1 -3
  75. package/dist/extension.d.cts +2 -10
  76. package/dist/extension.d.mts +2 -10
  77. package/dist/extension.mjs +1 -3
  78. package/dist/extensions/pi.cjs +1 -1
  79. package/dist/extensions/pi.cjs.map +1 -1
  80. package/dist/extensions/pi.d.cts +1 -1
  81. package/dist/extensions/pi.d.mts +1 -1
  82. package/dist/extensions/pi.mjs +1 -1
  83. package/dist/extensions/pi.mjs.map +1 -1
  84. package/dist/index.cjs +1 -1
  85. package/dist/index.d.cts +2 -2
  86. package/dist/index.d.mts +2 -2
  87. package/dist/index.mjs +1 -1
  88. package/dist/ptyProvider.cjs +1 -2
  89. package/dist/ptyProvider.d.cts +2 -13
  90. package/dist/ptyProvider.d.mts +2 -13
  91. package/dist/ptyProvider.mjs +1 -2
  92. package/dist/reconcile.cjs +1 -2
  93. package/dist/reconcile.d.cts +2 -37
  94. package/dist/reconcile.d.mts +2 -37
  95. package/dist/reconcile.mjs +1 -2
  96. package/dist/runnerSpec.cjs +1 -2
  97. package/dist/runnerSpec.d.cts +2 -50
  98. package/dist/runnerSpec.d.mts +2 -50
  99. package/dist/runnerSpec.mjs +1 -2
  100. package/dist/schemas/bashTool.cjs +2 -0
  101. package/dist/schemas/bashTool.cjs.map +1 -0
  102. package/dist/schemas/bashTool.d.cts +25 -0
  103. package/dist/schemas/bashTool.d.cts.map +1 -0
  104. package/dist/schemas/bashTool.d.mts +25 -0
  105. package/dist/schemas/bashTool.d.mts.map +1 -0
  106. package/dist/schemas/bashTool.mjs +2 -0
  107. package/dist/schemas/bashTool.mjs.map +1 -0
  108. package/dist/schemas/runnerSpec.cjs +2 -0
  109. package/dist/schemas/runnerSpec.cjs.map +1 -0
  110. package/dist/schemas/runnerSpec.d.cts +50 -0
  111. package/dist/schemas/runnerSpec.d.cts.map +1 -0
  112. package/dist/schemas/runnerSpec.d.mts +50 -0
  113. package/dist/schemas/runnerSpec.d.mts.map +1 -0
  114. package/dist/schemas/runnerSpec.mjs +2 -0
  115. package/dist/schemas/runnerSpec.mjs.map +1 -0
  116. package/dist/services/AnsiScrub/ansiScrub.cjs +1 -1
  117. package/dist/services/AnsiScrub/ansiScrub.cjs.map +1 -1
  118. package/dist/services/AnsiScrub/ansiScrub.mjs +1 -1
  119. package/dist/services/AnsiScrub/ansiScrub.mjs.map +1 -1
  120. package/dist/services/BashRunService/BashRunService.cjs +1 -1
  121. package/dist/services/BashRunService/BashRunService.cjs.map +1 -1
  122. package/dist/services/BashRunService/BashRunService.mjs +1 -1
  123. package/dist/services/BashRunService/BashRunService.mjs.map +1 -1
  124. package/dist/services/Launcher/Launcher.cjs +1 -1
  125. package/dist/services/Launcher/Launcher.cjs.map +1 -1
  126. package/dist/services/Launcher/Launcher.mjs +1 -1
  127. package/dist/services/Launcher/Launcher.mjs.map +1 -1
  128. package/dist/services/Lifeline/NodeLifeline.cjs +1 -1
  129. package/dist/services/Lifeline/NodeLifeline.cjs.map +1 -1
  130. package/dist/services/Lifeline/NodeLifeline.mjs +1 -1
  131. package/dist/services/Lifeline/NodeLifeline.mjs.map +1 -1
  132. package/dist/services/LogFile/LogFile.cjs +1 -1
  133. package/dist/services/LogFile/LogFile.cjs.map +1 -1
  134. package/dist/services/LogFile/LogFile.mjs +1 -1
  135. package/dist/services/LogFile/LogFile.mjs.map +1 -1
  136. package/dist/services/PtyHost/PtyHost.cjs +1 -1
  137. package/dist/services/PtyHost/PtyHost.cjs.map +1 -1
  138. package/dist/services/PtyHost/PtyHost.mjs +1 -1
  139. package/dist/services/PtyHost/PtyHost.mjs.map +1 -1
  140. package/dist/services/RmuxBackend/RmuxBackend.cjs +1 -1
  141. package/dist/services/RmuxBackend/RmuxBackend.cjs.map +1 -1
  142. package/dist/services/RmuxBackend/RmuxBackend.mjs +1 -1
  143. package/dist/services/RmuxBackend/RmuxBackend.mjs.map +1 -1
  144. package/dist/services/RunnerNamer/RunnerNamer.cjs +1 -1
  145. package/dist/services/RunnerNamer/RunnerNamer.cjs.map +1 -1
  146. package/dist/services/RunnerNamer/RunnerNamer.mjs +1 -1
  147. package/dist/services/RunnerNamer/RunnerNamer.mjs.map +1 -1
  148. package/dist/services/RunnerPaths/RunnerPaths.cjs +1 -2
  149. package/dist/services/RunnerPaths/RunnerPaths.d.cts +2 -31
  150. package/dist/services/RunnerPaths/RunnerPaths.d.mts +2 -31
  151. package/dist/services/RunnerPaths/RunnerPaths.mjs +1 -2
  152. package/dist/services/RunnerPaths/index.cjs +1 -1
  153. package/dist/services/RunnerPaths/index.d.cts +2 -1
  154. package/dist/services/RunnerPaths/index.d.mts +2 -1
  155. package/dist/services/RunnerPaths/index.mjs +1 -1
  156. package/dist/services/RunnerPaths/types.d.cts +2 -0
  157. package/dist/services/RunnerPaths/types.d.cts.map +1 -1
  158. package/dist/services/RunnerPaths/types.d.mts +2 -0
  159. package/dist/services/RunnerPaths/types.d.mts.map +1 -1
  160. package/dist/services/RunnerRegistry/RunnerRegistry.cjs +1 -1
  161. package/dist/services/RunnerRegistry/RunnerRegistry.cjs.map +1 -1
  162. package/dist/services/RunnerRegistry/RunnerRegistry.mjs +1 -1
  163. package/dist/services/RunnerRegistry/RunnerRegistry.mjs.map +1 -1
  164. package/dist/services/runs/compaction.cjs +4 -0
  165. package/dist/services/runs/compaction.cjs.map +1 -0
  166. package/dist/services/runs/compaction.d.cts +14 -0
  167. package/dist/services/runs/compaction.d.cts.map +1 -0
  168. package/dist/services/runs/compaction.d.mts +14 -0
  169. package/dist/services/runs/compaction.d.mts.map +1 -0
  170. package/dist/services/runs/compaction.mjs +4 -0
  171. package/dist/services/runs/compaction.mjs.map +1 -0
  172. package/dist/services/runs/reconcile.cjs +2 -0
  173. package/dist/services/runs/reconcile.cjs.map +1 -0
  174. package/dist/services/runs/reconcile.d.cts +37 -0
  175. package/dist/services/runs/reconcile.d.cts.map +1 -0
  176. package/dist/services/runs/reconcile.d.mts +37 -0
  177. package/dist/services/runs/reconcile.d.mts.map +1 -0
  178. package/dist/services/runs/reconcile.mjs +2 -0
  179. package/dist/services/runs/reconcile.mjs.map +1 -0
  180. package/dist/services/runs/session.cjs +2 -0
  181. package/dist/services/runs/session.cjs.map +1 -0
  182. package/dist/services/runs/session.d.cts +10 -0
  183. package/dist/services/runs/session.d.cts.map +1 -0
  184. package/dist/services/runs/session.d.mts +10 -0
  185. package/dist/services/runs/session.d.mts.map +1 -0
  186. package/dist/services/runs/session.mjs +2 -0
  187. package/dist/services/runs/session.mjs.map +1 -0
  188. package/dist/session.cjs +1 -2
  189. package/dist/session.d.cts +2 -10
  190. package/dist/session.d.mts +2 -10
  191. package/dist/session.mjs +1 -2
  192. package/dist/tool/bashTool.cjs +1 -7
  193. package/dist/tool/bashTool.d.cts +2 -25
  194. package/dist/tool/bashTool.d.mts +2 -25
  195. package/dist/tool/bashTool.mjs +1 -7
  196. package/dist/tool/responseEnvelope.cjs +1 -10
  197. package/dist/tool/responseEnvelope.d.cts +2 -45
  198. package/dist/tool/responseEnvelope.d.mts +2 -45
  199. package/dist/tool/responseEnvelope.mjs +1 -10
  200. package/dist/tool/schema.cjs +1 -2
  201. package/dist/tool/schema.d.cts +2 -25
  202. package/dist/tool/schema.d.mts +2 -25
  203. package/dist/tool/schema.mjs +1 -2
  204. package/dist/tui/bashRender.cjs +4 -7
  205. package/dist/tui/bashRender.cjs.map +1 -1
  206. package/dist/tui/bashRender.d.cts +5 -5
  207. package/dist/tui/bashRender.d.cts.map +1 -1
  208. package/dist/tui/bashRender.d.mts +5 -5
  209. package/dist/tui/bashRender.d.mts.map +1 -1
  210. package/dist/tui/bashRender.mjs +4 -7
  211. package/dist/tui/bashRender.mjs.map +1 -1
  212. package/dist/tui/format.cjs +1 -1
  213. package/dist/tui/format.cjs.map +1 -1
  214. package/dist/tui/format.mjs +1 -1
  215. package/dist/tui/format.mjs.map +1 -1
  216. package/dist/tui/runnerSpace.cjs +4 -4
  217. package/dist/tui/runnerSpace.cjs.map +1 -1
  218. package/dist/tui/runnerSpace.d.cts.map +1 -1
  219. package/dist/tui/runnerSpace.d.mts.map +1 -1
  220. package/dist/tui/runnerSpace.mjs +4 -4
  221. package/dist/tui/runnerSpace.mjs.map +1 -1
  222. package/dist/types/config.cjs +2 -0
  223. package/dist/types/config.cjs.map +1 -0
  224. package/dist/types/config.d.cts +32 -0
  225. package/dist/types/config.d.cts.map +1 -0
  226. package/dist/types/config.d.mts +32 -0
  227. package/dist/types/config.d.mts.map +1 -0
  228. package/dist/types/config.mjs +2 -0
  229. package/dist/types/config.mjs.map +1 -0
  230. package/dist/types/index.cjs +2 -0
  231. package/dist/types/index.cjs.map +1 -0
  232. package/dist/types/index.d.cts +28 -0
  233. package/dist/types/index.d.cts.map +1 -0
  234. package/dist/types/index.d.mts +28 -0
  235. package/dist/types/index.d.mts.map +1 -0
  236. package/dist/types/index.mjs +2 -0
  237. package/dist/types/index.mjs.map +1 -0
  238. package/dist/types.cjs +1 -2
  239. package/dist/types.d.cts +2 -28
  240. package/dist/types.d.mts +2 -28
  241. package/dist/types.mjs +1 -2
  242. package/package.json +20 -13
  243. package/dist/cli/cliApp.cjs.map +0 -1
  244. package/dist/cli/cliApp.d.cts.map +0 -1
  245. package/dist/cli/cliApp.d.mts.map +0 -1
  246. package/dist/cli/cliApp.mjs.map +0 -1
  247. package/dist/compaction.cjs.map +0 -1
  248. package/dist/compaction.d.cts.map +0 -1
  249. package/dist/compaction.d.mts.map +0 -1
  250. package/dist/compaction.mjs.map +0 -1
  251. package/dist/config.cjs.map +0 -1
  252. package/dist/config.d.cts.map +0 -1
  253. package/dist/config.d.mts.map +0 -1
  254. package/dist/config.mjs.map +0 -1
  255. package/dist/extension.cjs.map +0 -1
  256. package/dist/extension.d.cts.map +0 -1
  257. package/dist/extension.d.mts.map +0 -1
  258. package/dist/extension.mjs.map +0 -1
  259. package/dist/ptyProvider.cjs.map +0 -1
  260. package/dist/ptyProvider.d.cts.map +0 -1
  261. package/dist/ptyProvider.d.mts.map +0 -1
  262. package/dist/ptyProvider.mjs.map +0 -1
  263. package/dist/reconcile.cjs.map +0 -1
  264. package/dist/reconcile.d.cts.map +0 -1
  265. package/dist/reconcile.d.mts.map +0 -1
  266. package/dist/reconcile.mjs.map +0 -1
  267. package/dist/runnerSpec.cjs.map +0 -1
  268. package/dist/runnerSpec.d.cts.map +0 -1
  269. package/dist/runnerSpec.d.mts.map +0 -1
  270. package/dist/runnerSpec.mjs.map +0 -1
  271. package/dist/services/RunnerPaths/RunnerPaths.cjs.map +0 -1
  272. package/dist/services/RunnerPaths/RunnerPaths.d.cts.map +0 -1
  273. package/dist/services/RunnerPaths/RunnerPaths.d.mts.map +0 -1
  274. package/dist/services/RunnerPaths/RunnerPaths.mjs.map +0 -1
  275. package/dist/session.cjs.map +0 -1
  276. package/dist/session.d.cts.map +0 -1
  277. package/dist/session.d.mts.map +0 -1
  278. package/dist/session.mjs.map +0 -1
  279. package/dist/tool/bashTool.cjs.map +0 -1
  280. package/dist/tool/bashTool.d.cts.map +0 -1
  281. package/dist/tool/bashTool.d.mts.map +0 -1
  282. package/dist/tool/bashTool.mjs.map +0 -1
  283. package/dist/tool/responseEnvelope.d.cts.map +0 -1
  284. package/dist/tool/responseEnvelope.d.mts.map +0 -1
  285. package/dist/tool/responseEnvelope.mjs.map +0 -1
  286. package/dist/tool/schema.cjs.map +0 -1
  287. package/dist/tool/schema.d.cts.map +0 -1
  288. package/dist/tool/schema.d.mts.map +0 -1
  289. package/dist/tool/schema.mjs.map +0 -1
  290. package/dist/types.cjs.map +0 -1
  291. package/dist/types.d.cts.map +0 -1
  292. package/dist/types.d.mts.map +0 -1
  293. package/dist/types.mjs.map +0 -1
@@ -0,0 +1,10 @@
1
+ import{getResultMaxBytes as e}from"../../types/config.mjs";import t from"node:fs";const n=1024,r=n*n;function i(e,t={}){return{content:[{type:`text`,text:e}],details:t}}function a(e){return i(`Error: ${e}`,{error:e})}function o(e){return e<n?`${e} B`:e<r?`${(e/n).toFixed(1)} KB`:`${(e/r).toFixed(1)} MB`}function s(e){return e.toLocaleString(`en-US`)}function c(e){return e.length===0?0:e.endsWith(`
2
+ `)?e.split(`
3
+ `).length-1:e.split(`
4
+ `).length}function l(n,r=200,i=e()){try{let e=t.readFileSync(n,`utf8`),a=c(e),o=e.split(`
5
+ `).slice(-Math.max(1,r)-+!!e.endsWith(`
6
+ `)).join(`
7
+ `),s=Buffer.byteLength(o,`utf8`),l=s>i?Buffer.from(o,`utf8`).subarray(s-i).toString(`utf8`):o,u=s>i?l.indexOf(`
8
+ `):-1,d=u>=0?l.slice(u+1):l;return{tail:d,bytes:t.statSync(n).size,lines:a,tailLines:c(d)}}catch{return{tail:``,bytes:0,lines:0,tailLines:0}}}function u(t,n,r=e()){let i=Buffer.byteLength(t,`utf8`);if(i<=r)return{text:t,truncated:!1,outputLines:c(t)};let a=Buffer.from(t,`utf8`).subarray(i-r).toString(`utf8`),o=a.indexOf(`
9
+ `),s=o===-1?a:a.slice(o+1);return{text:`${s}\n${d(s,n,t,i)}`,truncated:!0,outputLines:c(s)}}function d(e,t,n,r){let i=c(e),a=f(t),l=a?.lines??c(n),u=a?.bytes??r;return[`[output truncated: showing the last ${s(i)} lines.`,`Full output is at ${t} (${o(u)}, ${s(l)} lines).`,`Inspect it with doom-runner logs, or read the file with an offset near line ${s(l)}.]`].join(` `)}function f(e){try{let n=t.readFileSync(e,`utf8`);return{bytes:t.statSync(e).size,lines:c(n)}}catch{return}}function p(e,t=Date.now()){let n=e.interactive?` interactive`:``;return`${e.name} pid ${e.pid} up ${m(e.startedAt,t)}${n} ${e.command}`}function m(e,t){let n=Date.parse(e);if(Number.isNaN(n))return`unknown`;let r=Math.max(0,Math.floor((t-n)/1e3));if(r<60)return`${r}s`;let i=Math.floor(r/60);if(i<60)return`${i}m`;let a=Math.floor(i/60);return a<24?`${a}h`:`${Math.floor(a/24)}d`}export{c as countLines,a as errorResult,p as formatRunnerLine,o as formatSize,m as formatUptime,l as summarizeLog,i as textResult,u as truncateForResult};
10
+ //# sourceMappingURL=responseEnvelope.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"responseEnvelope.cjs","names":["getResultMaxBytes","fs"],"sources":["../../src/tool/responseEnvelope.ts"],"sourcesContent":["import fs from 'node:fs';\nimport { getResultMaxBytes } from '../config.ts';\nimport type { RunnerRecord } from '../services/RunnerRegistry/index.ts';\n\nconst BYTES_PER_KB = 1024;\nconst BYTES_PER_MB = BYTES_PER_KB * BYTES_PER_KB;\n\nexport interface ToolResult {\n content: Array<{ type: 'text'; text: string }>;\n details: Record<string, unknown>;\n /** Tools this result makes available from here on in the transcript. */\n addedToolNames?: string[];\n}\n\nexport function textResult(text: string, details: Record<string, unknown> = {}): ToolResult {\n return { content: [{ type: 'text', text }], details };\n}\n\nexport function errorResult(message: string): ToolResult {\n return textResult(`Error: ${message}`, { error: message });\n}\n\n/** Human-readable byte count, matching how pi reports output sizes. */\nexport function formatSize(bytes: number): string {\n if (bytes < BYTES_PER_KB) return `${bytes} B`;\n if (bytes < BYTES_PER_MB) return `${(bytes / BYTES_PER_KB).toFixed(1)} KB`;\n return `${(bytes / BYTES_PER_MB).toFixed(1)} MB`;\n}\n\nfunction formatCount(value: number): string {\n return value.toLocaleString('en-US');\n}\n\nexport function countLines(text: string): number {\n if (text.length === 0) return 0;\n return text.endsWith('\\n') ? text.split('\\n').length - 1 : text.split('\\n').length;\n}\n\nexport interface TruncatedOutput {\n text: string;\n truncated: boolean;\n /** Lines returned, which is what the model actually received. */\n outputLines: number;\n}\n\nexport interface LogSummary {\n tail: string;\n bytes: number;\n lines: number;\n tailLines: number;\n}\n\n/** Reads a bounded tail plus exact metadata after the writer has flushed. */\nexport function summarizeLog(path: string, maxLines = 200, maxBytes = getResultMaxBytes()): LogSummary {\n try {\n const contents = fs.readFileSync(path, 'utf8');\n const lines = countLines(contents);\n const lineTail = contents\n .split('\\n')\n .slice(-Math.max(1, maxLines) - (contents.endsWith('\\n') ? 1 : 0))\n .join('\\n');\n const bytes = Buffer.byteLength(lineTail, 'utf8');\n const byteTail =\n bytes > maxBytes\n ? Buffer.from(lineTail, 'utf8')\n .subarray(bytes - maxBytes)\n .toString('utf8')\n : lineTail;\n const firstNewline = bytes > maxBytes ? byteTail.indexOf('\\n') : -1;\n const tail = firstNewline >= 0 ? byteTail.slice(firstNewline + 1) : byteTail;\n return { tail, bytes: fs.statSync(path).size, lines, tailLines: countLines(tail) };\n } catch {\n return { tail: '', bytes: 0, lines: 0, tailLines: 0 };\n }\n}\n\n/**\n * Keeps the tail of an oversized result and points at the file holding the rest.\n *\n * The notice states the file's real size and line count so the model does not\n * guess at offsets when it goes on to read the file, which is the failure this\n * whole policy exists to prevent.\n */\nexport function truncateForResult(\n text: string,\n fullOutputPath: string,\n maxBytes = getResultMaxBytes(),\n): TruncatedOutput {\n const totalBytes = Buffer.byteLength(text, 'utf8');\n if (totalBytes <= maxBytes) return { text, truncated: false, outputLines: countLines(text) };\n\n const kept = Buffer.from(text, 'utf8')\n .subarray(totalBytes - maxBytes)\n .toString('utf8');\n // Drop the leading partial line rather than hand back a fragment.\n const newline = kept.indexOf('\\n');\n const tail = newline === -1 ? kept : kept.slice(newline + 1);\n\n return {\n text: `${tail}\\n${truncationNotice(tail, fullOutputPath, text, totalBytes)}`,\n truncated: true,\n outputLines: countLines(tail),\n };\n}\n\nfunction truncationNotice(tail: string, fullOutputPath: string, text: string, totalBytes: number): string {\n const shown = countLines(tail);\n // Counted from the file, never from `text`. What the caller holds in memory\n // is itself capped, so using it here would understate the file by orders of\n // magnitude and send the reader looking past the end of a much longer file.\n const file = measureFile(fullOutputPath);\n const totalLines = file?.lines ?? countLines(text);\n const fileSize = file?.bytes ?? totalBytes;\n\n return [\n `[output truncated: showing the last ${formatCount(shown)} lines.`,\n `Full output is at ${fullOutputPath} (${formatSize(fileSize)}, ${formatCount(totalLines)} lines).`,\n `Inspect it with doom-runner logs, or read the file with an offset near line ${formatCount(totalLines)}.]`,\n ].join(' ');\n}\n\n/** Real size and line count of the file the notice points at. */\nfunction measureFile(path: string): { bytes: number; lines: number } | undefined {\n try {\n const contents = fs.readFileSync(path, 'utf8');\n return { bytes: fs.statSync(path).size, lines: countLines(contents) };\n } catch {\n return undefined;\n }\n}\n\n/** `name pid 1234 up 3m sleep 60` — one runner per line. */\nexport function formatRunnerLine(record: RunnerRecord, now = Date.now()): string {\n const mode = record.interactive ? ' interactive' : '';\n return `${record.name} pid ${record.pid} up ${formatUptime(record.startedAt, now)}${mode} ${record.command}`;\n}\n\nexport function formatUptime(startedAt: string, now: number): string {\n const started = Date.parse(startedAt);\n if (Number.isNaN(started)) return 'unknown';\n const seconds = Math.max(0, Math.floor((now - started) / 1000));\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n return hours < 24 ? `${hours}h` : `${Math.floor(hours / 24)}d`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"responseEnvelope.mjs","names":[],"sources":["../../../src/commands/bash/responseEnvelope.ts"],"sourcesContent":["import fs from 'node:fs';\nimport type { RunnerRecord } from '../../services/RunnerRegistry/index.ts';\nimport { getResultMaxBytes } from '../../types/config.ts';\n\nconst BYTES_PER_KB = 1024;\nconst BYTES_PER_MB = BYTES_PER_KB * BYTES_PER_KB;\n\nexport interface ToolResult {\n content: Array<{ type: 'text'; text: string }>;\n details: Record<string, unknown>;\n /** Tools this result makes available from here on in the transcript. */\n addedToolNames?: string[];\n}\n\nexport function textResult(text: string, details: Record<string, unknown> = {}): ToolResult {\n return { content: [{ type: 'text', text }], details };\n}\n\nexport function errorResult(message: string): ToolResult {\n return textResult(`Error: ${message}`, { error: message });\n}\n\n/** Human-readable byte count, matching how pi reports output sizes. */\nexport function formatSize(bytes: number): string {\n if (bytes < BYTES_PER_KB) return `${bytes} B`;\n if (bytes < BYTES_PER_MB) return `${(bytes / BYTES_PER_KB).toFixed(1)} KB`;\n return `${(bytes / BYTES_PER_MB).toFixed(1)} MB`;\n}\n\nfunction formatCount(value: number): string {\n return value.toLocaleString('en-US');\n}\n\nexport function countLines(text: string): number {\n if (text.length === 0) return 0;\n return text.endsWith('\\n') ? text.split('\\n').length - 1 : text.split('\\n').length;\n}\n\nexport interface TruncatedOutput {\n text: string;\n truncated: boolean;\n /** Lines returned, which is what the model actually received. */\n outputLines: number;\n}\n\nexport interface LogSummary {\n tail: string;\n bytes: number;\n lines: number;\n tailLines: number;\n}\n\n/** Reads a bounded tail plus exact metadata after the writer has flushed. */\nexport function summarizeLog(path: string, maxLines = 200, maxBytes = getResultMaxBytes()): LogSummary {\n try {\n const contents = fs.readFileSync(path, 'utf8');\n const lines = countLines(contents);\n const lineTail = contents\n .split('\\n')\n .slice(-Math.max(1, maxLines) - (contents.endsWith('\\n') ? 1 : 0))\n .join('\\n');\n const bytes = Buffer.byteLength(lineTail, 'utf8');\n const byteTail =\n bytes > maxBytes\n ? Buffer.from(lineTail, 'utf8')\n .subarray(bytes - maxBytes)\n .toString('utf8')\n : lineTail;\n const firstNewline = bytes > maxBytes ? byteTail.indexOf('\\n') : -1;\n const tail = firstNewline >= 0 ? byteTail.slice(firstNewline + 1) : byteTail;\n return { tail, bytes: fs.statSync(path).size, lines, tailLines: countLines(tail) };\n } catch {\n return { tail: '', bytes: 0, lines: 0, tailLines: 0 };\n }\n}\n\n/**\n * Keeps the tail of an oversized result and points at the file holding the rest.\n *\n * The notice states the file's real size and line count so the model does not\n * guess at offsets when it goes on to read the file, which is the failure this\n * whole policy exists to prevent.\n */\nexport function truncateForResult(\n text: string,\n fullOutputPath: string,\n maxBytes = getResultMaxBytes(),\n): TruncatedOutput {\n const totalBytes = Buffer.byteLength(text, 'utf8');\n if (totalBytes <= maxBytes) return { text, truncated: false, outputLines: countLines(text) };\n\n const kept = Buffer.from(text, 'utf8')\n .subarray(totalBytes - maxBytes)\n .toString('utf8');\n // Drop the leading partial line rather than hand back a fragment.\n const newline = kept.indexOf('\\n');\n const tail = newline === -1 ? kept : kept.slice(newline + 1);\n\n return {\n text: `${tail}\\n${truncationNotice(tail, fullOutputPath, text, totalBytes)}`,\n truncated: true,\n outputLines: countLines(tail),\n };\n}\n\nfunction truncationNotice(tail: string, fullOutputPath: string, text: string, totalBytes: number): string {\n const shown = countLines(tail);\n // Counted from the file, never from `text`. What the caller holds in memory\n // is itself capped, so using it here would understate the file by orders of\n // magnitude and send the reader looking past the end of a much longer file.\n const file = measureFile(fullOutputPath);\n const totalLines = file?.lines ?? countLines(text);\n const fileSize = file?.bytes ?? totalBytes;\n\n return [\n `[output truncated: showing the last ${formatCount(shown)} lines.`,\n `Full output is at ${fullOutputPath} (${formatSize(fileSize)}, ${formatCount(totalLines)} lines).`,\n `Inspect it with doom-runner logs, or read the file with an offset near line ${formatCount(totalLines)}.]`,\n ].join(' ');\n}\n\n/** Real size and line count of the file the notice points at. */\nfunction measureFile(path: string): { bytes: number; lines: number } | undefined {\n try {\n const contents = fs.readFileSync(path, 'utf8');\n return { bytes: fs.statSync(path).size, lines: countLines(contents) };\n } catch {\n return undefined;\n }\n}\n\n/** `name pid 1234 up 3m sleep 60` — one runner per line. */\nexport function formatRunnerLine(record: RunnerRecord, now = Date.now()): string {\n const mode = record.interactive ? ' interactive' : '';\n return `${record.name} pid ${record.pid} up ${formatUptime(record.startedAt, now)}${mode} ${record.command}`;\n}\n\nexport function formatUptime(startedAt: string, now: number): string {\n const started = Date.parse(startedAt);\n if (Number.isNaN(started)) return 'unknown';\n const seconds = Math.max(0, Math.floor((now - started) / 1000));\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n return hours < 24 ? `${hours}h` : `${Math.floor(hours / 24)}d`;\n}\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../services/runs/session.cjs"),n=require("../bash/responseEnvelope.cjs");let r=require("node:fs");r=e.__toESM(r,1);const i=`completed`,a=`rmux`,o=`stopped`,s=`SIGTERM`;async function c(e,n){let[r,...i]=e;if(r!==void 0&&r!==`--help`&&r!==`-h`&&!t.inheritedSessionId(n.env))return n.stderr(`PI_SESSION_ID is required for doom-runner commands`),1;switch(r){case`list`:return l(i,n);case`status`:return u(i,n);case`logs`:return d(i,n);case`stop`:return f(i,n);case`stop-all`:return p(i,n);case`input`:return m(i,n);case`--help`:case`-h`:case void 0:return n.stdout(S()),0;default:return n.stderr(`Unknown command: ${r}\n\n${S()}`),1}}async function l(e,n){let r=t.requiredSessionId(n.env),i=e.includes(`--all`)?await n.registry.listAll(r):await n.registry.listBySession(r);return n.stdout(i.length>0?i.map(g).join(`
2
+ `):`No runners`),0}async function u(e,t){let n=await h(e[0],t);return n?(t.stdout([`ID: ${n.id}`,`Name: ${n.name}`,`State: ${n.state}`,`Backend: ${n.backend}`,...n.backendTarget?[`Backend target: ${n.backendTarget}`]:[],`PID: ${n.pid}`,`Command: ${n.command}`,`CWD: ${n.cwd}`,`Session: ${n.sessionId}`,`Log: ${n.logPath}`,...n.exit?[`Exit: ${_(n)}`]:[]].join(`
3
+ `)),0):1}async function d(e,t){let n=await h(e[0],t);if(!n)return 1;let r=y(v(e,`--lines`))??200,i=t.logReader.read(n.logPath,{lines:r});return i.exists?(i.text&&t.stdout(i.text),e.includes(`--follow`)?b(n,i.fileSize,t):0):(t.stderr(`Runner ${n.id} has not written a log yet`),1)}async function f(e,t){let n=await h(e[0],t);if(!n)return 1;if(n.state!==`running`)return t.stderr(`Runner ${n.id} is already ${n.state}`),1;await x(n,t);let r=v(e,`--reason`);return await t.registry.complete(n.id,{reason:o,code:null,signal:s,...r?{stopReason:r}:{}},n.sessionId),t.stdout(`Stopped ${n.id}\nLog: ${n.logPath}`),0}async function p(e,n){let r=t.requiredSessionId(n.env),i=await n.registry.listBySession(r),a=v(e,`--reason`);for(let e of i)await x(e,n),await n.registry.complete(e.id,{reason:o,code:null,signal:s,...a?{stopReason:a}:{}},e.sessionId);return n.stdout(i.length>0?`Stopped ${i.length} runner(s) for session ${r}: ${i.map(e=>e.id).join(`, `)}`:`No active runners for session ${r}`),0}async function m(e,t){let n=await h(e[0],t);if(!n)return 1;if(n.state===i)return t.stderr(`Runner ${n.id} is already completed; use doom-runner logs ${n.id}`),1;if(!n.interactive)return t.stderr(`Runner ${n.id} was not started with interactive: true`),1;let r=v(e,`--text`)??await t.readStdin(),o=e.includes(`--enter`)&&!r.endsWith(`
4
+ `)?`${r}\n`:r;return n.backend!==a||!n.backendTarget?(t.stderr(`Runner ${n.id} uses the ${n.backend} backend, which does not expose CLI input`),1):await t.rmuxBackend.input(n.backendTarget,o)?(t.stdout(`Sent input to ${n.id}`),0):(t.stderr(`Runner ${n.id} is no longer accepting RMUX input`),1)}async function h(e,n){if(!e){n.stderr(`A runner ID is required`);return}let r=t.requiredSessionId(n.env),i=await n.registry.get(e,r);if(!i){n.stderr(`No runner with id ${e}`);return}return i}function g(e){let t=n.formatRunnerLine(e);return`${e.id} ${e.state} ${e.backend} ${t}`}function _(e){let t=e.exit;if(!t)return`unknown`;let n=t.code===null?t.signal?` ${t.signal}`:``:` code ${t.code}`,r=t.stopReason?` (${t.stopReason})`:``;return`${t.reason}${n}${r}`}function v(e,t){let n=e.indexOf(t);return n>=0?e[n+1]:void 0}function y(e){if(e===void 0)return;let t=Number(e);return Number.isInteger(t)&&t>0?t:void 0}async function b(e,t,n){let a=t;return new Promise(t=>{let o=!1,s,c=t=>{if(t.size<a&&(a=0),t.size===a)return;let i=t.size-a,o=Buffer.alloc(i),s=r.default.openSync(e.logPath,`r`);try{let e=r.default.readSync(s,o,0,i,a);e>0&&n.stdout(o.subarray(0,e).toString(`utf8`))}finally{r.default.closeSync(s)}a=t.size},l=()=>{if(!o){o=!0;try{c(r.default.statSync(e.logPath))}catch(t){t.code!==`ENOENT`&&n.stderr(`Runner ${e.id} failed to flush its final log output: ${t.message}`)}r.default.unwatchFile(e.logPath,c),clearInterval(s),process.off(`SIGINT`,l),t(0)}};process.once(`SIGINT`,l),r.default.watchFile(e.logPath,{interval:250},c),s=setInterval(()=>{n.registry.get(e.id).then(e=>{e?.state===i&&l()})},250)})}async function x(e,t){return e.backend===a&&e.backendTarget?t.rmuxBackend.stop(e.backendTarget,e.pid):t.launcher.stop(e.pid)}function S(){return[`Usage: doom-runner <command>`,``,`Commands:`,` list [--all]`,` status <id>`,` logs <id> [--lines N] [--follow]`,` stop <id> [--reason <text>]`,` stop-all [--reason <text>]`,` input <id> [--text <text>] [--enter]`].join(`
5
+ `)}exports.runCli=c;
6
+ //# sourceMappingURL=cliApp.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cliApp.cjs","names":["inheritedSessionId","requiredSessionId","formatRunnerLine","fs"],"sources":["../../../src/commands/cli/cliApp.ts"],"sourcesContent":["import fs from 'node:fs';\nimport type { ILauncher } from '../../services/Launcher/index.ts';\nimport type { ILogReader } from '../../services/LogReader/index.ts';\nimport type { IRmuxBackend } from '../../services/RmuxBackend/index.ts';\nimport type { IRunnerRegistry, RunnerRecord } from '../../services/RunnerRegistry/index.ts';\nimport { inheritedSessionId, requiredSessionId } from '../../services/runs/session.ts';\nimport { formatRunnerLine } from '../bash/responseEnvelope.ts';\n\nconst DEFAULT_LOG_LINES = 200;\nconst FOLLOW_INTERVAL_MS = 250;\nconst COMPLETED_STATE = 'completed';\nconst RMUX_BACKEND = 'rmux';\nconst STOPPED_REASON = 'stopped';\nconst TERMINATION_SIGNAL = 'SIGTERM';\n\nexport interface CliDependencies {\n registry: IRunnerRegistry;\n launcher: ILauncher;\n rmuxBackend: IRmuxBackend;\n logReader: ILogReader;\n env?: NodeJS.ProcessEnv;\n stdout(text: string): void;\n stderr(text: string): void;\n readStdin(): Promise<string>;\n}\n\nexport async function runCli(argv: readonly string[], dependencies: CliDependencies): Promise<number> {\n const [command, ...args] = argv;\n if (command !== undefined && command !== '--help' && command !== '-h' && !inheritedSessionId(dependencies.env)) {\n dependencies.stderr('PI_SESSION_ID is required for doom-runner commands');\n return 1;\n }\n switch (command) {\n case 'list':\n return list(args, dependencies);\n case 'status':\n return status(args, dependencies);\n case 'logs':\n return logs(args, dependencies);\n case 'stop':\n return stop(args, dependencies);\n case 'stop-all':\n return stopAll(args, dependencies);\n case 'input':\n return input(args, dependencies);\n case '--help':\n case '-h':\n case undefined:\n dependencies.stdout(help());\n return 0;\n default:\n dependencies.stderr(`Unknown command: ${command}\\n\\n${help()}`);\n return 1;\n }\n}\n\nasync function list(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = args.includes('--all')\n ? await dependencies.registry.listAll(sessionId)\n : await dependencies.registry.listBySession(sessionId);\n dependencies.stdout(records.length > 0 ? records.map(formatRecord).join('\\n') : 'No runners');\n return 0;\n}\n\nasync function status(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n dependencies.stdout(\n [\n `ID: ${record.id}`,\n `Name: ${record.name}`,\n `State: ${record.state}`,\n `Backend: ${record.backend}`,\n ...(record.backendTarget ? [`Backend target: ${record.backendTarget}`] : []),\n `PID: ${record.pid}`,\n `Command: ${record.command}`,\n `CWD: ${record.cwd}`,\n `Session: ${record.sessionId}`,\n `Log: ${record.logPath}`,\n ...(record.exit ? [`Exit: ${formatExit(record)}`] : []),\n ].join('\\n'),\n );\n return 0;\n}\n\nasync function logs(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n const lines = positiveInteger(option(args, '--lines')) ?? DEFAULT_LOG_LINES;\n const result = dependencies.logReader.read(record.logPath, { lines });\n if (!result.exists) {\n dependencies.stderr(`Runner ${record.id} has not written a log yet`);\n return 1;\n }\n if (result.text) dependencies.stdout(result.text);\n if (!args.includes('--follow')) return 0;\n return follow(record, result.fileSize, dependencies);\n}\n\nasync function stop(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state !== 'running') {\n dependencies.stderr(`Runner ${record.id} is already ${record.state}`);\n return 1;\n }\n await stopRecord(record, dependencies);\n const reason = option(args, '--reason');\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n dependencies.stdout(`Stopped ${record.id}\\nLog: ${record.logPath}`);\n return 0;\n}\n\nasync function stopAll(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = await dependencies.registry.listBySession(sessionId);\n const reason = option(args, '--reason');\n for (const record of records) {\n await stopRecord(record, dependencies);\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n }\n dependencies.stdout(\n records.length > 0\n ? `Stopped ${records.length} runner(s) for session ${sessionId}: ${records.map((record) => record.id).join(', ')}`\n : `No active runners for session ${sessionId}`,\n );\n return 0;\n}\n\nasync function input(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state === COMPLETED_STATE) {\n dependencies.stderr(`Runner ${record.id} is already completed; use doom-runner logs ${record.id}`);\n return 1;\n }\n if (!record.interactive) {\n dependencies.stderr(`Runner ${record.id} was not started with interactive: true`);\n return 1;\n }\n const supplied = option(args, '--text');\n const text = supplied ?? (await dependencies.readStdin());\n const payload = args.includes('--enter') && !text.endsWith('\\n') ? `${text}\\n` : text;\n if (record.backend !== RMUX_BACKEND || !record.backendTarget) {\n dependencies.stderr(`Runner ${record.id} uses the ${record.backend} backend, which does not expose CLI input`);\n return 1;\n }\n if (!(await dependencies.rmuxBackend.input(record.backendTarget, payload))) {\n dependencies.stderr(`Runner ${record.id} is no longer accepting RMUX input`);\n return 1;\n }\n dependencies.stdout(`Sent input to ${record.id}`);\n return 0;\n}\n\nasync function requiredRecord(\n id: string | undefined,\n dependencies: CliDependencies,\n): Promise<RunnerRecord | undefined> {\n if (!id) {\n dependencies.stderr('A runner ID is required');\n return undefined;\n }\n const sessionId = requiredSessionId(dependencies.env);\n const scopedRecord = await dependencies.registry.get(id, sessionId);\n if (!scopedRecord) {\n dependencies.stderr(`No runner with id ${id}`);\n return undefined;\n }\n return scopedRecord;\n}\n\nfunction formatRecord(record: RunnerRecord): string {\n const active = formatRunnerLine(record);\n return `${record.id} ${record.state} ${record.backend} ${active}`;\n}\n\nfunction formatExit(record: RunnerRecord): string {\n const exit = record.exit;\n if (!exit) return 'unknown';\n const detail = exit.code !== null ? ` code ${exit.code}` : exit.signal ? ` ${exit.signal}` : '';\n const note = exit.stopReason ? ` (${exit.stopReason})` : '';\n return `${exit.reason}${detail}${note}`;\n}\n\nfunction option(args: readonly string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nfunction positiveInteger(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nasync function follow(record: RunnerRecord, initialSize: number, dependencies: CliDependencies): Promise<number> {\n let offset = initialSize;\n return new Promise<number>((resolve) => {\n let stopped = false;\n let stateTimer: NodeJS.Timeout;\n const listener = (current: fs.Stats): void => {\n if (current.size < offset) offset = 0;\n if (current.size === offset) return;\n const length = current.size - offset;\n const buffer = Buffer.alloc(length);\n const descriptor = fs.openSync(record.logPath, 'r');\n try {\n const bytesRead = fs.readSync(descriptor, buffer, 0, length, offset);\n if (bytesRead > 0) dependencies.stdout(buffer.subarray(0, bytesRead).toString('utf8'));\n } finally {\n fs.closeSync(descriptor);\n }\n offset = current.size;\n };\n const stopFollowing = (): void => {\n if (stopped) return;\n stopped = true;\n try {\n listener(fs.statSync(record.logPath));\n } catch (error) {\n // A missing log file was already reported by the initial read.\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n dependencies.stderr(`Runner ${record.id} failed to flush its final log output: ${(error as Error).message}`);\n }\n }\n fs.unwatchFile(record.logPath, listener);\n clearInterval(stateTimer);\n process.off('SIGINT', stopFollowing);\n resolve(0);\n };\n process.once('SIGINT', stopFollowing);\n fs.watchFile(record.logPath, { interval: FOLLOW_INTERVAL_MS }, listener);\n stateTimer = setInterval(() => {\n void dependencies.registry.get(record.id).then((current) => {\n if (current?.state === COMPLETED_STATE) stopFollowing();\n });\n }, FOLLOW_INTERVAL_MS);\n });\n}\n\nasync function stopRecord(record: RunnerRecord, dependencies: CliDependencies): Promise<boolean> {\n if (record.backend === RMUX_BACKEND && record.backendTarget) {\n return dependencies.rmuxBackend.stop(record.backendTarget, record.pid);\n }\n return dependencies.launcher.stop(record.pid);\n}\n\nfunction help(): string {\n return [\n 'Usage: doom-runner <command>',\n '',\n 'Commands:',\n ' list [--all]',\n ' status <id>',\n ' logs <id> [--lines N] [--follow]',\n ' stop <id> [--reason <text>]',\n ' stop-all [--reason <text>]',\n ' input <id> [--text <text>] [--enter]',\n ].join('\\n');\n}\n"],"mappings":"yLAQA,MAEM,EAAkB,YAClB,EAAe,OACf,EAAiB,UACjB,EAAqB,UAa3B,eAAsB,EAAO,EAAyB,EAAgD,CACpG,GAAM,CAAC,EAAS,GAAG,GAAQ,EAC3B,GAAI,IAAY,IAAA,IAAa,IAAY,UAAY,IAAY,MAAQ,CAACA,EAAAA,mBAAmB,EAAa,GAAG,EAE3G,OADA,EAAa,OAAO,oDAAoD,EACjE,EAET,OAAQ,EAAR,CACE,IAAK,OACH,OAAO,EAAK,EAAM,CAAY,EAChC,IAAK,SACH,OAAO,EAAO,EAAM,CAAY,EAClC,IAAK,OACH,OAAO,EAAK,EAAM,CAAY,EAChC,IAAK,OACH,OAAO,EAAK,EAAM,CAAY,EAChC,IAAK,WACH,OAAO,EAAQ,EAAM,CAAY,EACnC,IAAK,QACH,OAAO,EAAM,EAAM,CAAY,EACjC,IAAK,SACL,IAAK,KACL,KAAK,IAAA,GAEH,OADA,EAAa,OAAO,EAAK,CAAC,EACnB,EACT,QAEE,OADA,EAAa,OAAO,oBAAoB,EAAQ,MAAM,EAAK,GAAG,EACvD,CACX,CACF,CAEA,eAAe,EAAK,EAAyB,EAAgD,CAC3F,IAAM,EAAYC,EAAAA,kBAAkB,EAAa,GAAG,EAC9C,EAAU,EAAK,SAAS,OAAO,EACjC,MAAM,EAAa,SAAS,QAAQ,CAAS,EAC7C,MAAM,EAAa,SAAS,cAAc,CAAS,EAEvD,OADA,EAAa,OAAO,EAAQ,OAAS,EAAI,EAAQ,IAAI,CAAY,CAAC,CAAC,KAAK;CAAI,EAAI,YAAY,EACrF,CACT,CAEA,eAAe,EAAO,EAAyB,EAAgD,CAC7F,IAAM,EAAS,MAAM,EAAe,EAAK,GAAI,CAAY,EAiBzD,OAhBK,GACL,EAAa,OACX,CACE,OAAO,EAAO,KACd,SAAS,EAAO,OAChB,UAAU,EAAO,QACjB,YAAY,EAAO,UACnB,GAAI,EAAO,cAAgB,CAAC,mBAAmB,EAAO,eAAe,EAAI,CAAC,EAC1E,QAAQ,EAAO,MACf,YAAY,EAAO,UACnB,QAAQ,EAAO,MACf,YAAY,EAAO,YACnB,QAAQ,EAAO,UACf,GAAI,EAAO,KAAO,CAAC,SAAS,EAAW,CAAM,GAAG,EAAI,CAAC,CACvD,CAAC,CAAC,KAAK;CAAI,CACb,EACO,GAhBa,CAiBtB,CAEA,eAAe,EAAK,EAAyB,EAAgD,CAC3F,IAAM,EAAS,MAAM,EAAe,EAAK,GAAI,CAAY,EACzD,GAAI,CAAC,EAAQ,MAAO,GACpB,IAAM,EAAQ,EAAgB,EAAO,EAAM,SAAS,CAAC,GAAK,IACpD,EAAS,EAAa,UAAU,KAAK,EAAO,QAAS,CAAE,OAAM,CAAC,EAOpE,OANK,EAAO,QAIR,EAAO,MAAM,EAAa,OAAO,EAAO,IAAI,EAC3C,EAAK,SAAS,UAAU,EACtB,EAAO,EAAQ,EAAO,SAAU,CAAY,EADZ,IAJrC,EAAa,OAAO,UAAU,EAAO,GAAG,2BAA2B,EAC5D,EAKX,CAEA,eAAe,EAAK,EAAyB,EAAgD,CAC3F,IAAM,EAAS,MAAM,EAAe,EAAK,GAAI,CAAY,EACzD,GAAI,CAAC,EAAQ,MAAO,GACpB,GAAI,EAAO,QAAU,UAEnB,OADA,EAAa,OAAO,UAAU,EAAO,GAAG,cAAc,EAAO,OAAO,EAC7D,EAET,MAAM,EAAW,EAAQ,CAAY,EACrC,IAAM,EAAS,EAAO,EAAM,UAAU,EAYtC,OAXA,MAAM,EAAa,SAAS,SAC1B,EAAO,GACP,CACE,OAAQ,EACR,KAAM,KACN,OAAQ,EACR,GAAI,EAAS,CAAE,WAAY,CAAO,EAAI,CAAC,CACzC,EACA,EAAO,SACT,EACA,EAAa,OAAO,WAAW,EAAO,GAAG,SAAS,EAAO,SAAS,EAC3D,CACT,CAEA,eAAe,EAAQ,EAAyB,EAAgD,CAC9F,IAAM,EAAYA,EAAAA,kBAAkB,EAAa,GAAG,EAC9C,EAAU,MAAM,EAAa,SAAS,cAAc,CAAS,EAC7D,EAAS,EAAO,EAAM,UAAU,EACtC,IAAK,IAAM,KAAU,EACnB,MAAM,EAAW,EAAQ,CAAY,EACrC,MAAM,EAAa,SAAS,SAC1B,EAAO,GACP,CACE,OAAQ,EACR,KAAM,KACN,OAAQ,EACR,GAAI,EAAS,CAAE,WAAY,CAAO,EAAI,CAAC,CACzC,EACA,EAAO,SACT,EAOF,OALA,EAAa,OACX,EAAQ,OAAS,EACb,WAAW,EAAQ,OAAO,yBAAyB,EAAU,IAAI,EAAQ,IAAK,GAAW,EAAO,EAAE,CAAC,CAAC,KAAK,IAAI,IAC7G,iCAAiC,GACvC,EACO,CACT,CAEA,eAAe,EAAM,EAAyB,EAAgD,CAC5F,IAAM,EAAS,MAAM,EAAe,EAAK,GAAI,CAAY,EACzD,GAAI,CAAC,EAAQ,MAAO,GACpB,GAAI,EAAO,QAAU,EAEnB,OADA,EAAa,OAAO,UAAU,EAAO,GAAG,8CAA8C,EAAO,IAAI,EAC1F,EAET,GAAI,CAAC,EAAO,YAEV,OADA,EAAa,OAAO,UAAU,EAAO,GAAG,wCAAwC,EACzE,EAGT,IAAM,EADW,EAAO,EAAM,QACV,GAAM,MAAM,EAAa,UAAU,EACjD,EAAU,EAAK,SAAS,SAAS,GAAK,CAAC,EAAK,SAAS;CAAI,EAAI,GAAG,EAAK,IAAM,EAUjF,OATI,EAAO,UAAY,GAAgB,CAAC,EAAO,eAC7C,EAAa,OAAO,UAAU,EAAO,GAAG,YAAY,EAAO,QAAQ,0CAA0C,EACtG,GAEH,MAAM,EAAa,YAAY,MAAM,EAAO,cAAe,CAAO,GAIxE,EAAa,OAAO,iBAAiB,EAAO,IAAI,EACzC,IAJL,EAAa,OAAO,UAAU,EAAO,GAAG,mCAAmC,EACpE,EAIX,CAEA,eAAe,EACb,EACA,EACmC,CACnC,GAAI,CAAC,EAAI,CACP,EAAa,OAAO,yBAAyB,EAC7C,MACF,CACA,IAAM,EAAYA,EAAAA,kBAAkB,EAAa,GAAG,EAC9C,EAAe,MAAM,EAAa,SAAS,IAAI,EAAI,CAAS,EAClE,GAAI,CAAC,EAAc,CACjB,EAAa,OAAO,qBAAqB,GAAI,EAC7C,MACF,CACA,OAAO,CACT,CAEA,SAAS,EAAa,EAA8B,CAClD,IAAM,EAASC,EAAAA,iBAAiB,CAAM,EACtC,MAAO,GAAG,EAAO,GAAG,IAAI,EAAO,MAAM,IAAI,EAAO,QAAQ,IAAI,GAC9D,CAEA,SAAS,EAAW,EAA8B,CAChD,IAAM,EAAO,EAAO,KACpB,GAAI,CAAC,EAAM,MAAO,UAClB,IAAM,EAAS,EAAK,OAAS,KAA8B,EAAK,OAAS,IAAI,EAAK,SAAW,GAAzD,SAAS,EAAK,OAC5C,EAAO,EAAK,WAAa,KAAK,EAAK,WAAW,GAAK,GACzD,MAAO,GAAG,EAAK,SAAS,IAAS,GACnC,CAEA,SAAS,EAAO,EAAyB,EAAkC,CACzE,IAAM,EAAQ,EAAK,QAAQ,CAAI,EAC/B,OAAO,GAAS,EAAI,EAAK,EAAQ,GAAK,IAAA,EACxC,CAEA,SAAS,EAAgB,EAA+C,CACtE,GAAI,IAAU,IAAA,GAAW,OACzB,IAAM,EAAS,OAAO,CAAK,EAC3B,OAAO,OAAO,UAAU,CAAM,GAAK,EAAS,EAAI,EAAS,IAAA,EAC3D,CAEA,eAAe,EAAO,EAAsB,EAAqB,EAAgD,CAC/G,IAAI,EAAS,EACb,OAAO,IAAI,QAAiB,GAAY,CACtC,IAAI,EAAU,GACV,EACE,EAAY,GAA4B,CAE5C,GADI,EAAQ,KAAO,IAAQ,EAAS,GAChC,EAAQ,OAAS,EAAQ,OAC7B,IAAM,EAAS,EAAQ,KAAO,EACxB,EAAS,OAAO,MAAM,CAAM,EAC5B,EAAaC,EAAAA,QAAG,SAAS,EAAO,QAAS,GAAG,EAClD,GAAI,CACF,IAAM,EAAYA,EAAAA,QAAG,SAAS,EAAY,EAAQ,EAAG,EAAQ,CAAM,EAC/D,EAAY,GAAG,EAAa,OAAO,EAAO,SAAS,EAAG,CAAS,CAAC,CAAC,SAAS,MAAM,CAAC,CACvF,QAAU,CACR,EAAA,QAAG,UAAU,CAAU,CACzB,CACA,EAAS,EAAQ,IACnB,EACM,MAA4B,CAC5B,MACJ,GAAU,GACV,GAAI,CACF,EAASA,EAAAA,QAAG,SAAS,EAAO,OAAO,CAAC,CACtC,OAAS,EAAO,CAET,EAAgC,OAAS,UAC5C,EAAa,OAAO,UAAU,EAAO,GAAG,yCAA0C,EAAgB,SAAS,CAE/G,CACA,EAAA,QAAG,YAAY,EAAO,QAAS,CAAQ,EACvC,cAAc,CAAU,EACxB,QAAQ,IAAI,SAAU,CAAa,EACnC,EAAQ,CAAC,CAZC,CAaZ,EACA,QAAQ,KAAK,SAAU,CAAa,EACpC,EAAA,QAAG,UAAU,EAAO,QAAS,CAAE,SAAU,GAAmB,EAAG,CAAQ,EACvE,EAAa,gBAAkB,CAC7B,EAAkB,SAAS,IAAI,EAAO,EAAE,CAAC,CAAC,KAAM,GAAY,CACtD,GAAS,QAAU,GAAiB,EAAc,CACxD,CAAC,CACH,EAAG,GAAkB,CACvB,CAAC,CACH,CAEA,eAAe,EAAW,EAAsB,EAAiD,CAI/F,OAHI,EAAO,UAAY,GAAgB,EAAO,cACrC,EAAa,YAAY,KAAK,EAAO,cAAe,EAAO,GAAG,EAEhE,EAAa,SAAS,KAAK,EAAO,GAAG,CAC9C,CAEA,SAAS,GAAe,CACtB,MAAO,CACL,+BACA,GACA,YACA,iBACA,gBACA,qCACA,gCACA,+BACA,wCACF,CAAC,CAAC,KAAK;CAAI,CACb"}
@@ -0,0 +1,23 @@
1
+ import { ILauncher } from "../../services/Launcher/types.cjs";
2
+ import "../../services/Launcher/index.cjs";
3
+ import { ILogReader } from "../../services/LogReader/types.cjs";
4
+ import "../../services/LogReader/index.cjs";
5
+ import { IRmuxBackend } from "../../services/RmuxBackend/types.cjs";
6
+ import "../../services/RmuxBackend/index.cjs";
7
+ import { IRunnerRegistry } from "../../services/RunnerRegistry/types.cjs";
8
+ import "../../services/RunnerRegistry/index.cjs";
9
+ //#region src/commands/cli/cliApp.d.ts
10
+ interface CliDependencies {
11
+ registry: IRunnerRegistry;
12
+ launcher: ILauncher;
13
+ rmuxBackend: IRmuxBackend;
14
+ logReader: ILogReader;
15
+ env?: NodeJS.ProcessEnv;
16
+ stdout(text: string): void;
17
+ stderr(text: string): void;
18
+ readStdin(): Promise<string>;
19
+ }
20
+ declare function runCli(argv: readonly string[], dependencies: CliDependencies): Promise<number>;
21
+ //#endregion
22
+ export { CliDependencies, runCli };
23
+ //# sourceMappingURL=cliApp.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cliApp.d.cts","names":[],"sources":["../../../src/commands/cli/cliApp.ts"],"mappings":";;;;;;;;;UAeiB;EACf,UAAU;EACV,UAAU;EACV,aAAa;EACb,WAAW;EACX,MAAM,OAAO;EACb,OAAO;EACP,OAAO;EACP,aAAa;;iBAGO,OAAO,yBAAyB,cAAc,kBAAkB"}
@@ -0,0 +1,23 @@
1
+ import { ILauncher } from "../../services/Launcher/types.mjs";
2
+ import "../../services/Launcher/index.mjs";
3
+ import { ILogReader } from "../../services/LogReader/types.mjs";
4
+ import "../../services/LogReader/index.mjs";
5
+ import { IRmuxBackend } from "../../services/RmuxBackend/types.mjs";
6
+ import "../../services/RmuxBackend/index.mjs";
7
+ import { IRunnerRegistry } from "../../services/RunnerRegistry/types.mjs";
8
+ import "../../services/RunnerRegistry/index.mjs";
9
+ //#region src/commands/cli/cliApp.d.ts
10
+ interface CliDependencies {
11
+ registry: IRunnerRegistry;
12
+ launcher: ILauncher;
13
+ rmuxBackend: IRmuxBackend;
14
+ logReader: ILogReader;
15
+ env?: NodeJS.ProcessEnv;
16
+ stdout(text: string): void;
17
+ stderr(text: string): void;
18
+ readStdin(): Promise<string>;
19
+ }
20
+ declare function runCli(argv: readonly string[], dependencies: CliDependencies): Promise<number>;
21
+ //#endregion
22
+ export { CliDependencies, runCli };
23
+ //# sourceMappingURL=cliApp.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cliApp.d.mts","names":[],"sources":["../../../src/commands/cli/cliApp.ts"],"mappings":";;;;;;;;;UAeiB;EACf,UAAU;EACV,UAAU;EACV,aAAa;EACb,WAAW;EACX,MAAM,OAAO;EACb,OAAO;EACP,OAAO;EACP,aAAa;;iBAGO,OAAO,yBAAyB,cAAc,kBAAkB"}
@@ -0,0 +1,6 @@
1
+ import{inheritedSessionId as e,requiredSessionId as t}from"../../services/runs/session.mjs";import{formatRunnerLine as n}from"../bash/responseEnvelope.mjs";import r from"node:fs";const i=`completed`,a=`rmux`,o=`stopped`,s=`SIGTERM`;async function c(t,n){let[r,...i]=t;if(r!==void 0&&r!==`--help`&&r!==`-h`&&!e(n.env))return n.stderr(`PI_SESSION_ID is required for doom-runner commands`),1;switch(r){case`list`:return l(i,n);case`status`:return u(i,n);case`logs`:return d(i,n);case`stop`:return f(i,n);case`stop-all`:return p(i,n);case`input`:return m(i,n);case`--help`:case`-h`:case void 0:return n.stdout(S()),0;default:return n.stderr(`Unknown command: ${r}\n\n${S()}`),1}}async function l(e,n){let r=t(n.env),i=e.includes(`--all`)?await n.registry.listAll(r):await n.registry.listBySession(r);return n.stdout(i.length>0?i.map(g).join(`
2
+ `):`No runners`),0}async function u(e,t){let n=await h(e[0],t);return n?(t.stdout([`ID: ${n.id}`,`Name: ${n.name}`,`State: ${n.state}`,`Backend: ${n.backend}`,...n.backendTarget?[`Backend target: ${n.backendTarget}`]:[],`PID: ${n.pid}`,`Command: ${n.command}`,`CWD: ${n.cwd}`,`Session: ${n.sessionId}`,`Log: ${n.logPath}`,...n.exit?[`Exit: ${_(n)}`]:[]].join(`
3
+ `)),0):1}async function d(e,t){let n=await h(e[0],t);if(!n)return 1;let r=y(v(e,`--lines`))??200,i=t.logReader.read(n.logPath,{lines:r});return i.exists?(i.text&&t.stdout(i.text),e.includes(`--follow`)?b(n,i.fileSize,t):0):(t.stderr(`Runner ${n.id} has not written a log yet`),1)}async function f(e,t){let n=await h(e[0],t);if(!n)return 1;if(n.state!==`running`)return t.stderr(`Runner ${n.id} is already ${n.state}`),1;await x(n,t);let r=v(e,`--reason`);return await t.registry.complete(n.id,{reason:o,code:null,signal:s,...r?{stopReason:r}:{}},n.sessionId),t.stdout(`Stopped ${n.id}\nLog: ${n.logPath}`),0}async function p(e,n){let r=t(n.env),i=await n.registry.listBySession(r),a=v(e,`--reason`);for(let e of i)await x(e,n),await n.registry.complete(e.id,{reason:o,code:null,signal:s,...a?{stopReason:a}:{}},e.sessionId);return n.stdout(i.length>0?`Stopped ${i.length} runner(s) for session ${r}: ${i.map(e=>e.id).join(`, `)}`:`No active runners for session ${r}`),0}async function m(e,t){let n=await h(e[0],t);if(!n)return 1;if(n.state===i)return t.stderr(`Runner ${n.id} is already completed; use doom-runner logs ${n.id}`),1;if(!n.interactive)return t.stderr(`Runner ${n.id} was not started with interactive: true`),1;let r=v(e,`--text`)??await t.readStdin(),o=e.includes(`--enter`)&&!r.endsWith(`
4
+ `)?`${r}\n`:r;return n.backend!==a||!n.backendTarget?(t.stderr(`Runner ${n.id} uses the ${n.backend} backend, which does not expose CLI input`),1):await t.rmuxBackend.input(n.backendTarget,o)?(t.stdout(`Sent input to ${n.id}`),0):(t.stderr(`Runner ${n.id} is no longer accepting RMUX input`),1)}async function h(e,n){if(!e){n.stderr(`A runner ID is required`);return}let r=t(n.env),i=await n.registry.get(e,r);if(!i){n.stderr(`No runner with id ${e}`);return}return i}function g(e){let t=n(e);return`${e.id} ${e.state} ${e.backend} ${t}`}function _(e){let t=e.exit;if(!t)return`unknown`;let n=t.code===null?t.signal?` ${t.signal}`:``:` code ${t.code}`,r=t.stopReason?` (${t.stopReason})`:``;return`${t.reason}${n}${r}`}function v(e,t){let n=e.indexOf(t);return n>=0?e[n+1]:void 0}function y(e){if(e===void 0)return;let t=Number(e);return Number.isInteger(t)&&t>0?t:void 0}async function b(e,t,n){let a=t;return new Promise(t=>{let o=!1,s,c=t=>{if(t.size<a&&(a=0),t.size===a)return;let i=t.size-a,o=Buffer.alloc(i),s=r.openSync(e.logPath,`r`);try{let e=r.readSync(s,o,0,i,a);e>0&&n.stdout(o.subarray(0,e).toString(`utf8`))}finally{r.closeSync(s)}a=t.size},l=()=>{if(!o){o=!0;try{c(r.statSync(e.logPath))}catch(t){t.code!==`ENOENT`&&n.stderr(`Runner ${e.id} failed to flush its final log output: ${t.message}`)}r.unwatchFile(e.logPath,c),clearInterval(s),process.off(`SIGINT`,l),t(0)}};process.once(`SIGINT`,l),r.watchFile(e.logPath,{interval:250},c),s=setInterval(()=>{n.registry.get(e.id).then(e=>{e?.state===i&&l()})},250)})}async function x(e,t){return e.backend===a&&e.backendTarget?t.rmuxBackend.stop(e.backendTarget,e.pid):t.launcher.stop(e.pid)}function S(){return[`Usage: doom-runner <command>`,``,`Commands:`,` list [--all]`,` status <id>`,` logs <id> [--lines N] [--follow]`,` stop <id> [--reason <text>]`,` stop-all [--reason <text>]`,` input <id> [--text <text>] [--enter]`].join(`
5
+ `)}export{c as runCli};
6
+ //# sourceMappingURL=cliApp.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cliApp.mjs","names":[],"sources":["../../../src/commands/cli/cliApp.ts"],"sourcesContent":["import fs from 'node:fs';\nimport type { ILauncher } from '../../services/Launcher/index.ts';\nimport type { ILogReader } from '../../services/LogReader/index.ts';\nimport type { IRmuxBackend } from '../../services/RmuxBackend/index.ts';\nimport type { IRunnerRegistry, RunnerRecord } from '../../services/RunnerRegistry/index.ts';\nimport { inheritedSessionId, requiredSessionId } from '../../services/runs/session.ts';\nimport { formatRunnerLine } from '../bash/responseEnvelope.ts';\n\nconst DEFAULT_LOG_LINES = 200;\nconst FOLLOW_INTERVAL_MS = 250;\nconst COMPLETED_STATE = 'completed';\nconst RMUX_BACKEND = 'rmux';\nconst STOPPED_REASON = 'stopped';\nconst TERMINATION_SIGNAL = 'SIGTERM';\n\nexport interface CliDependencies {\n registry: IRunnerRegistry;\n launcher: ILauncher;\n rmuxBackend: IRmuxBackend;\n logReader: ILogReader;\n env?: NodeJS.ProcessEnv;\n stdout(text: string): void;\n stderr(text: string): void;\n readStdin(): Promise<string>;\n}\n\nexport async function runCli(argv: readonly string[], dependencies: CliDependencies): Promise<number> {\n const [command, ...args] = argv;\n if (command !== undefined && command !== '--help' && command !== '-h' && !inheritedSessionId(dependencies.env)) {\n dependencies.stderr('PI_SESSION_ID is required for doom-runner commands');\n return 1;\n }\n switch (command) {\n case 'list':\n return list(args, dependencies);\n case 'status':\n return status(args, dependencies);\n case 'logs':\n return logs(args, dependencies);\n case 'stop':\n return stop(args, dependencies);\n case 'stop-all':\n return stopAll(args, dependencies);\n case 'input':\n return input(args, dependencies);\n case '--help':\n case '-h':\n case undefined:\n dependencies.stdout(help());\n return 0;\n default:\n dependencies.stderr(`Unknown command: ${command}\\n\\n${help()}`);\n return 1;\n }\n}\n\nasync function list(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = args.includes('--all')\n ? await dependencies.registry.listAll(sessionId)\n : await dependencies.registry.listBySession(sessionId);\n dependencies.stdout(records.length > 0 ? records.map(formatRecord).join('\\n') : 'No runners');\n return 0;\n}\n\nasync function status(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n dependencies.stdout(\n [\n `ID: ${record.id}`,\n `Name: ${record.name}`,\n `State: ${record.state}`,\n `Backend: ${record.backend}`,\n ...(record.backendTarget ? [`Backend target: ${record.backendTarget}`] : []),\n `PID: ${record.pid}`,\n `Command: ${record.command}`,\n `CWD: ${record.cwd}`,\n `Session: ${record.sessionId}`,\n `Log: ${record.logPath}`,\n ...(record.exit ? [`Exit: ${formatExit(record)}`] : []),\n ].join('\\n'),\n );\n return 0;\n}\n\nasync function logs(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n const lines = positiveInteger(option(args, '--lines')) ?? DEFAULT_LOG_LINES;\n const result = dependencies.logReader.read(record.logPath, { lines });\n if (!result.exists) {\n dependencies.stderr(`Runner ${record.id} has not written a log yet`);\n return 1;\n }\n if (result.text) dependencies.stdout(result.text);\n if (!args.includes('--follow')) return 0;\n return follow(record, result.fileSize, dependencies);\n}\n\nasync function stop(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state !== 'running') {\n dependencies.stderr(`Runner ${record.id} is already ${record.state}`);\n return 1;\n }\n await stopRecord(record, dependencies);\n const reason = option(args, '--reason');\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n dependencies.stdout(`Stopped ${record.id}\\nLog: ${record.logPath}`);\n return 0;\n}\n\nasync function stopAll(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = await dependencies.registry.listBySession(sessionId);\n const reason = option(args, '--reason');\n for (const record of records) {\n await stopRecord(record, dependencies);\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n }\n dependencies.stdout(\n records.length > 0\n ? `Stopped ${records.length} runner(s) for session ${sessionId}: ${records.map((record) => record.id).join(', ')}`\n : `No active runners for session ${sessionId}`,\n );\n return 0;\n}\n\nasync function input(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state === COMPLETED_STATE) {\n dependencies.stderr(`Runner ${record.id} is already completed; use doom-runner logs ${record.id}`);\n return 1;\n }\n if (!record.interactive) {\n dependencies.stderr(`Runner ${record.id} was not started with interactive: true`);\n return 1;\n }\n const supplied = option(args, '--text');\n const text = supplied ?? (await dependencies.readStdin());\n const payload = args.includes('--enter') && !text.endsWith('\\n') ? `${text}\\n` : text;\n if (record.backend !== RMUX_BACKEND || !record.backendTarget) {\n dependencies.stderr(`Runner ${record.id} uses the ${record.backend} backend, which does not expose CLI input`);\n return 1;\n }\n if (!(await dependencies.rmuxBackend.input(record.backendTarget, payload))) {\n dependencies.stderr(`Runner ${record.id} is no longer accepting RMUX input`);\n return 1;\n }\n dependencies.stdout(`Sent input to ${record.id}`);\n return 0;\n}\n\nasync function requiredRecord(\n id: string | undefined,\n dependencies: CliDependencies,\n): Promise<RunnerRecord | undefined> {\n if (!id) {\n dependencies.stderr('A runner ID is required');\n return undefined;\n }\n const sessionId = requiredSessionId(dependencies.env);\n const scopedRecord = await dependencies.registry.get(id, sessionId);\n if (!scopedRecord) {\n dependencies.stderr(`No runner with id ${id}`);\n return undefined;\n }\n return scopedRecord;\n}\n\nfunction formatRecord(record: RunnerRecord): string {\n const active = formatRunnerLine(record);\n return `${record.id} ${record.state} ${record.backend} ${active}`;\n}\n\nfunction formatExit(record: RunnerRecord): string {\n const exit = record.exit;\n if (!exit) return 'unknown';\n const detail = exit.code !== null ? ` code ${exit.code}` : exit.signal ? ` ${exit.signal}` : '';\n const note = exit.stopReason ? ` (${exit.stopReason})` : '';\n return `${exit.reason}${detail}${note}`;\n}\n\nfunction option(args: readonly string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nfunction positiveInteger(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nasync function follow(record: RunnerRecord, initialSize: number, dependencies: CliDependencies): Promise<number> {\n let offset = initialSize;\n return new Promise<number>((resolve) => {\n let stopped = false;\n let stateTimer: NodeJS.Timeout;\n const listener = (current: fs.Stats): void => {\n if (current.size < offset) offset = 0;\n if (current.size === offset) return;\n const length = current.size - offset;\n const buffer = Buffer.alloc(length);\n const descriptor = fs.openSync(record.logPath, 'r');\n try {\n const bytesRead = fs.readSync(descriptor, buffer, 0, length, offset);\n if (bytesRead > 0) dependencies.stdout(buffer.subarray(0, bytesRead).toString('utf8'));\n } finally {\n fs.closeSync(descriptor);\n }\n offset = current.size;\n };\n const stopFollowing = (): void => {\n if (stopped) return;\n stopped = true;\n try {\n listener(fs.statSync(record.logPath));\n } catch (error) {\n // A missing log file was already reported by the initial read.\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n dependencies.stderr(`Runner ${record.id} failed to flush its final log output: ${(error as Error).message}`);\n }\n }\n fs.unwatchFile(record.logPath, listener);\n clearInterval(stateTimer);\n process.off('SIGINT', stopFollowing);\n resolve(0);\n };\n process.once('SIGINT', stopFollowing);\n fs.watchFile(record.logPath, { interval: FOLLOW_INTERVAL_MS }, listener);\n stateTimer = setInterval(() => {\n void dependencies.registry.get(record.id).then((current) => {\n if (current?.state === COMPLETED_STATE) stopFollowing();\n });\n }, FOLLOW_INTERVAL_MS);\n });\n}\n\nasync function stopRecord(record: RunnerRecord, dependencies: CliDependencies): Promise<boolean> {\n if (record.backend === RMUX_BACKEND && record.backendTarget) {\n return dependencies.rmuxBackend.stop(record.backendTarget, record.pid);\n }\n return dependencies.launcher.stop(record.pid);\n}\n\nfunction help(): string {\n return [\n 'Usage: doom-runner <command>',\n '',\n 'Commands:',\n ' list [--all]',\n ' status <id>',\n ' logs <id> [--lines N] [--follow]',\n ' stop <id> [--reason <text>]',\n ' stop-all [--reason <text>]',\n ' input <id> [--text <text>] [--enter]',\n ].join('\\n');\n}\n"],"mappings":"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"}
@@ -1,4 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=`Active background runners survived compaction:`;function t(t){if(t.length===0)return``;let n=t.flatMap(e=>[`- ${e.name} (${e.id}), log: ${e.logPath}`,` Check: doom-runner status ${e.id}`,` Stream: doom-runner logs ${e.id} --follow`]);return[e,...n,`Use these CLI commands to inspect existing runners before launching another command.`].join(`
2
- `)}function n(n,r){return r.length===0||n.includes(e)?n:[n,``,t(r)].join(`
3
- `)}function r(e,n){e.on(`session_compact`,async()=>{let r=n.getSessionId();if(!r)return;let i;try{i=await n.listBySession(r)}catch{return}let a=t(i);a&&e.sendMessage({customType:`doom-runner-compaction`,content:a,display:!1,details:{sessionId:r,runnerIds:i.map(e=>e.id)}},{triggerTurn:!1,deliverAs:`steer`})})}exports.activeRunnerRecovery=t,exports.appendActiveRunnersToSummary=n,exports.registerRunnerCompactionRecovery=r;
4
- //# sourceMappingURL=compaction.cjs.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./services/runs/compaction.cjs");exports.activeRunnerRecovery=e.activeRunnerRecovery,exports.appendActiveRunnersToSummary=e.appendActiveRunnersToSummary,exports.registerRunnerCompactionRecovery=e.registerRunnerCompactionRecovery;
@@ -1,14 +1,2 @@
1
- import { RunnerRecord } from "./services/RunnerRegistry/types.cjs";
2
- import "./services/RunnerRegistry/index.cjs";
3
- import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
4
- //#region src/compaction.d.ts
5
- interface RunnerCompactionDependencies {
6
- getSessionId(): string | undefined;
7
- listBySession(sessionId: string): Promise<RunnerRecord[]>;
8
- }
9
- declare function activeRunnerRecovery(active: readonly RunnerRecord[]): string;
10
- declare function appendActiveRunnersToSummary(summary: string, active: readonly RunnerRecord[]): string;
11
- declare function registerRunnerCompactionRecovery(pi: ExtensionAPI, dependencies: RunnerCompactionDependencies): void;
12
- //#endregion
13
- export { RunnerCompactionDependencies, activeRunnerRecovery, appendActiveRunnersToSummary, registerRunnerCompactionRecovery };
14
- //# sourceMappingURL=compaction.d.cts.map
1
+ import { RunnerCompactionDependencies, activeRunnerRecovery, appendActiveRunnersToSummary, registerRunnerCompactionRecovery } from "./services/runs/compaction.cjs";
2
+ export { RunnerCompactionDependencies, activeRunnerRecovery, appendActiveRunnersToSummary, registerRunnerCompactionRecovery };
@@ -1,14 +1,2 @@
1
- import { RunnerRecord } from "./services/RunnerRegistry/types.mjs";
2
- import "./services/RunnerRegistry/index.mjs";
3
- import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
4
- //#region src/compaction.d.ts
5
- interface RunnerCompactionDependencies {
6
- getSessionId(): string | undefined;
7
- listBySession(sessionId: string): Promise<RunnerRecord[]>;
8
- }
9
- declare function activeRunnerRecovery(active: readonly RunnerRecord[]): string;
10
- declare function appendActiveRunnersToSummary(summary: string, active: readonly RunnerRecord[]): string;
11
- declare function registerRunnerCompactionRecovery(pi: ExtensionAPI, dependencies: RunnerCompactionDependencies): void;
12
- //#endregion
13
- export { RunnerCompactionDependencies, activeRunnerRecovery, appendActiveRunnersToSummary, registerRunnerCompactionRecovery };
14
- //# sourceMappingURL=compaction.d.mts.map
1
+ import { RunnerCompactionDependencies, activeRunnerRecovery, appendActiveRunnersToSummary, registerRunnerCompactionRecovery } from "./services/runs/compaction.mjs";
2
+ export { RunnerCompactionDependencies, activeRunnerRecovery, appendActiveRunnersToSummary, registerRunnerCompactionRecovery };
@@ -1,4 +1 @@
1
- const e=`Active background runners survived compaction:`;function t(t){if(t.length===0)return``;let n=t.flatMap(e=>[`- ${e.name} (${e.id}), log: ${e.logPath}`,` Check: doom-runner status ${e.id}`,` Stream: doom-runner logs ${e.id} --follow`]);return[e,...n,`Use these CLI commands to inspect existing runners before launching another command.`].join(`
2
- `)}function n(n,r){return r.length===0||n.includes(e)?n:[n,``,t(r)].join(`
3
- `)}function r(e,n){e.on(`session_compact`,async()=>{let r=n.getSessionId();if(!r)return;let i;try{i=await n.listBySession(r)}catch{return}let a=t(i);a&&e.sendMessage({customType:`doom-runner-compaction`,content:a,display:!1,details:{sessionId:r,runnerIds:i.map(e=>e.id)}},{triggerTurn:!1,deliverAs:`steer`})})}export{t as activeRunnerRecovery,n as appendActiveRunnersToSummary,r as registerRunnerCompactionRecovery};
4
- //# sourceMappingURL=compaction.mjs.map
1
+ import{activeRunnerRecovery as e,appendActiveRunnersToSummary as t,registerRunnerCompactionRecovery as n}from"./services/runs/compaction.mjs";export{e as activeRunnerRecovery,t as appendActiveRunnersToSummary,n as registerRunnerCompactionRecovery};
package/dist/config.cjs CHANGED
@@ -1,2 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=`DOOM_RUNNER_BG_THRESHOLD_MS`,t=`DOOM_RUNNER_RESULT_MAX_BYTES`,n=`DOOM_RUNNER_LOG_MAX_BYTES`,r=`DOOM_RUNNER_LOG_TTL_MS`,i=6e4,a=51200,o=5242880,s=6048e5;function c(e,t){let n=Number(e);return Number.isFinite(n)&&n>0?n:t}function l(t=process.env){return c(t[e],i)}function u(e=process.env){return c(e[t],a)}function d(e=process.env){return c(e[n],o)}function f(e=process.env){return c(e[r],s)}exports.BG_THRESHOLD_MS_ENV=e,exports.DEFAULT_BG_THRESHOLD_MS=i,exports.DEFAULT_LOG_MAX_BYTES=o,exports.DEFAULT_LOG_TTL_MS=s,exports.DEFAULT_RESULT_MAX_BYTES=a,exports.LOG_DIR_ENV=`DOOM_RUNNER_LOG_DIR`,exports.LOG_MAX_BYTES_ENV=n,exports.LOG_TTL_MS_ENV=r,exports.RESULT_MAX_BYTES_ENV=t,exports.getBackgroundThresholdMs=l,exports.getLogMaxBytes=d,exports.getLogTtlMs=f,exports.getResultMaxBytes=u;
2
- //# sourceMappingURL=config.cjs.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./types/config.cjs");exports.BG_THRESHOLD_MS_ENV=e.BG_THRESHOLD_MS_ENV,exports.DEFAULT_BG_THRESHOLD_MS=e.DEFAULT_BG_THRESHOLD_MS,exports.DEFAULT_LOG_MAX_BYTES=e.DEFAULT_LOG_MAX_BYTES,exports.DEFAULT_LOG_TTL_MS=e.DEFAULT_LOG_TTL_MS,exports.DEFAULT_RESULT_MAX_BYTES=e.DEFAULT_RESULT_MAX_BYTES,exports.LOG_DIR_ENV=e.LOG_DIR_ENV,exports.LOG_MAX_BYTES_ENV=e.LOG_MAX_BYTES_ENV,exports.LOG_TTL_MS_ENV=e.LOG_TTL_MS_ENV,exports.RESULT_MAX_BYTES_ENV=e.RESULT_MAX_BYTES_ENV,exports.getBackgroundThresholdMs=e.getBackgroundThresholdMs,exports.getLogMaxBytes=e.getLogMaxBytes,exports.getLogTtlMs=e.getLogTtlMs,exports.getResultMaxBytes=e.getResultMaxBytes;
package/dist/config.d.cts CHANGED
@@ -1,32 +1,2 @@
1
- //#region src/config.d.ts
2
- /**
3
- * Extension configuration, read from the environment.
4
- *
5
- * Env rather than a config file, matching doom-task: doom-pi already carries
6
- * per-launch state to Pi through env vars.
7
- */
8
- declare const BG_THRESHOLD_MS_ENV = "DOOM_RUNNER_BG_THRESHOLD_MS";
9
- declare const RESULT_MAX_BYTES_ENV = "DOOM_RUNNER_RESULT_MAX_BYTES";
10
- declare const LOG_MAX_BYTES_ENV = "DOOM_RUNNER_LOG_MAX_BYTES";
11
- declare const LOG_TTL_MS_ENV = "DOOM_RUNNER_LOG_TTL_MS";
12
- /** Unscoped override for the runner log directory. */
13
- declare const LOG_DIR_ENV = "DOOM_RUNNER_LOG_DIR";
14
- /** A bash call still running at this point is promoted to a named runner. */
15
- declare const DEFAULT_BG_THRESHOLD_MS = 60000;
16
- /** Tool results past this size are tail-truncated and spilled to the log file. */
17
- declare const DEFAULT_RESULT_MAX_BYTES = 51200;
18
- /** A runner log rotates once to `.log.1` at this size. */
19
- declare const DEFAULT_LOG_MAX_BYTES: number;
20
- /** Retention window for logs with no live registry record. */
21
- declare const DEFAULT_LOG_TTL_MS: number;
22
- /** Age at which a bash call becomes a background runner. */
23
- declare function getBackgroundThresholdMs(env?: NodeJS.ProcessEnv): number;
24
- /** Byte ceiling for a single tool result before tail truncation kicks in. */
25
- declare function getResultMaxBytes(env?: NodeJS.ProcessEnv): number;
26
- /** Byte ceiling for a runner log before it rotates. */
27
- declare function getLogMaxBytes(env?: NodeJS.ProcessEnv): number;
28
- /** Retention window for orphaned runner logs. */
29
- declare function getLogTtlMs(env?: NodeJS.ProcessEnv): number;
30
- //#endregion
31
- export { BG_THRESHOLD_MS_ENV, DEFAULT_BG_THRESHOLD_MS, DEFAULT_LOG_MAX_BYTES, DEFAULT_LOG_TTL_MS, DEFAULT_RESULT_MAX_BYTES, LOG_DIR_ENV, LOG_MAX_BYTES_ENV, LOG_TTL_MS_ENV, RESULT_MAX_BYTES_ENV, getBackgroundThresholdMs, getLogMaxBytes, getLogTtlMs, getResultMaxBytes };
32
- //# sourceMappingURL=config.d.cts.map
1
+ import { BG_THRESHOLD_MS_ENV, DEFAULT_BG_THRESHOLD_MS, DEFAULT_LOG_MAX_BYTES, DEFAULT_LOG_TTL_MS, DEFAULT_RESULT_MAX_BYTES, LOG_DIR_ENV, LOG_MAX_BYTES_ENV, LOG_TTL_MS_ENV, RESULT_MAX_BYTES_ENV, getBackgroundThresholdMs, getLogMaxBytes, getLogTtlMs, getResultMaxBytes } from "./types/config.cjs";
2
+ export { BG_THRESHOLD_MS_ENV, DEFAULT_BG_THRESHOLD_MS, DEFAULT_LOG_MAX_BYTES, DEFAULT_LOG_TTL_MS, DEFAULT_RESULT_MAX_BYTES, LOG_DIR_ENV, LOG_MAX_BYTES_ENV, LOG_TTL_MS_ENV, RESULT_MAX_BYTES_ENV, getBackgroundThresholdMs, getLogMaxBytes, getLogTtlMs, getResultMaxBytes };
package/dist/config.d.mts CHANGED
@@ -1,32 +1,2 @@
1
- //#region src/config.d.ts
2
- /**
3
- * Extension configuration, read from the environment.
4
- *
5
- * Env rather than a config file, matching doom-task: doom-pi already carries
6
- * per-launch state to Pi through env vars.
7
- */
8
- declare const BG_THRESHOLD_MS_ENV = "DOOM_RUNNER_BG_THRESHOLD_MS";
9
- declare const RESULT_MAX_BYTES_ENV = "DOOM_RUNNER_RESULT_MAX_BYTES";
10
- declare const LOG_MAX_BYTES_ENV = "DOOM_RUNNER_LOG_MAX_BYTES";
11
- declare const LOG_TTL_MS_ENV = "DOOM_RUNNER_LOG_TTL_MS";
12
- /** Unscoped override for the runner log directory. */
13
- declare const LOG_DIR_ENV = "DOOM_RUNNER_LOG_DIR";
14
- /** A bash call still running at this point is promoted to a named runner. */
15
- declare const DEFAULT_BG_THRESHOLD_MS = 60000;
16
- /** Tool results past this size are tail-truncated and spilled to the log file. */
17
- declare const DEFAULT_RESULT_MAX_BYTES = 51200;
18
- /** A runner log rotates once to `.log.1` at this size. */
19
- declare const DEFAULT_LOG_MAX_BYTES: number;
20
- /** Retention window for logs with no live registry record. */
21
- declare const DEFAULT_LOG_TTL_MS: number;
22
- /** Age at which a bash call becomes a background runner. */
23
- declare function getBackgroundThresholdMs(env?: NodeJS.ProcessEnv): number;
24
- /** Byte ceiling for a single tool result before tail truncation kicks in. */
25
- declare function getResultMaxBytes(env?: NodeJS.ProcessEnv): number;
26
- /** Byte ceiling for a runner log before it rotates. */
27
- declare function getLogMaxBytes(env?: NodeJS.ProcessEnv): number;
28
- /** Retention window for orphaned runner logs. */
29
- declare function getLogTtlMs(env?: NodeJS.ProcessEnv): number;
30
- //#endregion
31
- export { BG_THRESHOLD_MS_ENV, DEFAULT_BG_THRESHOLD_MS, DEFAULT_LOG_MAX_BYTES, DEFAULT_LOG_TTL_MS, DEFAULT_RESULT_MAX_BYTES, LOG_DIR_ENV, LOG_MAX_BYTES_ENV, LOG_TTL_MS_ENV, RESULT_MAX_BYTES_ENV, getBackgroundThresholdMs, getLogMaxBytes, getLogTtlMs, getResultMaxBytes };
32
- //# sourceMappingURL=config.d.mts.map
1
+ import { BG_THRESHOLD_MS_ENV, DEFAULT_BG_THRESHOLD_MS, DEFAULT_LOG_MAX_BYTES, DEFAULT_LOG_TTL_MS, DEFAULT_RESULT_MAX_BYTES, LOG_DIR_ENV, LOG_MAX_BYTES_ENV, LOG_TTL_MS_ENV, RESULT_MAX_BYTES_ENV, getBackgroundThresholdMs, getLogMaxBytes, getLogTtlMs, getResultMaxBytes } from "./types/config.mjs";
2
+ export { BG_THRESHOLD_MS_ENV, DEFAULT_BG_THRESHOLD_MS, DEFAULT_LOG_MAX_BYTES, DEFAULT_LOG_TTL_MS, DEFAULT_RESULT_MAX_BYTES, LOG_DIR_ENV, LOG_MAX_BYTES_ENV, LOG_TTL_MS_ENV, RESULT_MAX_BYTES_ENV, getBackgroundThresholdMs, getLogMaxBytes, getLogTtlMs, getResultMaxBytes };
package/dist/config.mjs CHANGED
@@ -1,2 +1 @@
1
- const e=`DOOM_RUNNER_BG_THRESHOLD_MS`,t=`DOOM_RUNNER_RESULT_MAX_BYTES`,n=`DOOM_RUNNER_LOG_MAX_BYTES`,r=`DOOM_RUNNER_LOG_TTL_MS`,i=`DOOM_RUNNER_LOG_DIR`,a=6e4,o=51200,s=5242880,c=6048e5;function l(e,t){let n=Number(e);return Number.isFinite(n)&&n>0?n:t}function u(t=process.env){return l(t[e],a)}function d(e=process.env){return l(e[t],o)}function f(e=process.env){return l(e[n],s)}function p(e=process.env){return l(e[r],c)}export{e as BG_THRESHOLD_MS_ENV,a as DEFAULT_BG_THRESHOLD_MS,s as DEFAULT_LOG_MAX_BYTES,c as DEFAULT_LOG_TTL_MS,o as DEFAULT_RESULT_MAX_BYTES,i as LOG_DIR_ENV,n as LOG_MAX_BYTES_ENV,r as LOG_TTL_MS_ENV,t as RESULT_MAX_BYTES_ENV,u as getBackgroundThresholdMs,f as getLogMaxBytes,p as getLogTtlMs,d as getResultMaxBytes};
2
- //# sourceMappingURL=config.mjs.map
1
+ import{BG_THRESHOLD_MS_ENV as e,DEFAULT_BG_THRESHOLD_MS as t,DEFAULT_LOG_MAX_BYTES as n,DEFAULT_LOG_TTL_MS as r,DEFAULT_RESULT_MAX_BYTES as i,LOG_DIR_ENV as a,LOG_MAX_BYTES_ENV as o,LOG_TTL_MS_ENV as s,RESULT_MAX_BYTES_ENV as c,getBackgroundThresholdMs as l,getLogMaxBytes as u,getLogTtlMs as d,getResultMaxBytes as f}from"./types/config.mjs";export{e as BG_THRESHOLD_MS_ENV,t as DEFAULT_BG_THRESHOLD_MS,n as DEFAULT_LOG_MAX_BYTES,r as DEFAULT_LOG_TTL_MS,i as DEFAULT_RESULT_MAX_BYTES,a as LOG_DIR_ENV,o as LOG_MAX_BYTES_ENV,s as LOG_TTL_MS_ENV,c as RESULT_MAX_BYTES_ENV,l as getBackgroundThresholdMs,u as getLogMaxBytes,d as getLogTtlMs,f as getResultMaxBytes};
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../types.cjs"),t=require("../services/BashRunService/BashRunService.cjs");require("../services/BashRunService/index.cjs");const n=require("../services/Clock/SystemClock.cjs");require("../services/Clock/index.cjs");const r=require("../services/Launcher/Launcher.cjs");require("../services/Launcher/index.cjs");const i=require("../services/Lifeline/NodeLifeline.cjs");require("../services/Lifeline/index.cjs");const a=require("../services/PtyHost/PtyHost.cjs");require("../services/PtyHost/index.cjs");const o=require("../services/LogFile/LogFile.cjs");require("../services/LogFile/index.cjs");const s=require("../services/LogReader/LogReader.cjs");require("../services/LogReader/index.cjs");const c=require("../services/ProcessControl/NodeProcessControl.cjs");require("../services/ProcessControl/index.cjs");const l=require("../services/PtySpawner/NodePtySpawner.cjs");require("../services/PtySpawner/index.cjs");const u=require("../services/RunnerNamer/RunnerNamer.cjs");require("../services/RunnerNamer/index.cjs");const d=require("../services/RunnerPaths/RunnerPaths.cjs");require("../services/RunnerPaths/index.cjs");const f=require("../services/RmuxBackend/RmuxBackend.cjs");require("../services/RmuxBackend/index.cjs");const p=require("../services/RunnerRegistry/RunnerRegistry.cjs");require("../services/RunnerRegistry/index.cjs");const m=require("../services/Spawner/NodeSpawner.cjs");require("../services/Spawner/index.cjs");let h=require("inversify");require("reflect-metadata/lite");function g(){let g=new h.Container;return g.bind(e.TYPES.Clock).to(n.SystemClock).inSingletonScope(),g.bind(e.TYPES.Spawner).to(m.NodeSpawner).inSingletonScope(),g.bind(e.TYPES.ProcessControl).to(c.NodeProcessControl).inSingletonScope(),g.bind(e.TYPES.PtySpawner).to(l.NodePtySpawner).inSingletonScope(),g.bind(e.TYPES.RunnerPaths).to(d.RunnerPaths).inSingletonScope(),g.bind(e.TYPES.Lifeline).to(i.NodeLifeline).inSingletonScope(),g.bind(e.TYPES.ProcessRegistry).toDynamicValue(()=>p.createDefaultProcessRegistry()).inSingletonScope(),g.bind(e.TYPES.RunnerRegistry).to(p.RunnerRegistry).inSingletonScope(),g.bind(e.TYPES.RunnerNamer).to(u.RunnerNamer).inSingletonScope(),g.bind(e.TYPES.LogFile).to(o.LogFile).inSingletonScope(),g.bind(e.TYPES.LogReader).to(s.LogReader).inSingletonScope(),g.bind(e.TYPES.Launcher).to(r.Launcher).inSingletonScope(),g.bind(e.TYPES.RmuxBackend).to(f.RmuxBackend).inSingletonScope(),g.bind(e.TYPES.PtyHost).to(a.PtyHost).inSingletonScope(),g.bind(e.TYPES.BashRunService).to(t.BashRunService).inSingletonScope(),g}exports.createRunnerContainer=g;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../types/index.cjs"),t=require("../services/BashRunService/BashRunService.cjs");require("../services/BashRunService/index.cjs");const n=require("../services/Clock/SystemClock.cjs");require("../services/Clock/index.cjs");const r=require("../services/Launcher/Launcher.cjs");require("../services/Launcher/index.cjs");const i=require("../services/Lifeline/NodeLifeline.cjs");require("../services/Lifeline/index.cjs");const a=require("../services/LogFile/LogFile.cjs");require("../services/LogFile/index.cjs");const o=require("../services/LogReader/LogReader.cjs");require("../services/LogReader/index.cjs");const s=require("../services/ProcessControl/NodeProcessControl.cjs");require("../services/ProcessControl/index.cjs");const c=require("../services/PtyHost/PtyHost.cjs");require("../services/PtyHost/index.cjs");const l=require("../services/PtySpawner/NodePtySpawner.cjs");require("../services/PtySpawner/index.cjs");const u=require("../services/RmuxBackend/RmuxBackend.cjs");require("../services/RmuxBackend/index.cjs");const d=require("../services/RunnerNamer/RunnerNamer.cjs");require("../services/RunnerNamer/index.cjs");const f=require("../adapters/RunnerPaths.cjs");require("../services/RunnerPaths/index.cjs");const p=require("../services/RunnerRegistry/RunnerRegistry.cjs");require("../services/RunnerRegistry/index.cjs");const m=require("../services/Spawner/NodeSpawner.cjs");require("../services/Spawner/index.cjs");let h=require("inversify");require("reflect-metadata/lite");function g(){let g=new h.Container;return g.bind(e.TYPES.Clock).to(n.SystemClock).inSingletonScope(),g.bind(e.TYPES.Spawner).to(m.NodeSpawner).inSingletonScope(),g.bind(e.TYPES.ProcessControl).to(s.NodeProcessControl).inSingletonScope(),g.bind(e.TYPES.PtySpawner).to(l.NodePtySpawner).inSingletonScope(),g.bind(e.TYPES.RunnerPaths).to(f.RunnerPaths).inSingletonScope(),g.bind(e.TYPES.Lifeline).to(i.NodeLifeline).inSingletonScope(),g.bind(e.TYPES.ProcessRegistry).toDynamicValue(()=>p.createDefaultProcessRegistry()).inSingletonScope(),g.bind(e.TYPES.RunnerRegistry).to(p.RunnerRegistry).inSingletonScope(),g.bind(e.TYPES.RunnerNamer).to(d.RunnerNamer).inSingletonScope(),g.bind(e.TYPES.LogFile).to(a.LogFile).inSingletonScope(),g.bind(e.TYPES.LogReader).to(o.LogReader).inSingletonScope(),g.bind(e.TYPES.Launcher).to(r.Launcher).inSingletonScope(),g.bind(e.TYPES.RmuxBackend).to(u.RmuxBackend).inSingletonScope(),g.bind(e.TYPES.PtyHost).to(c.PtyHost).inSingletonScope(),g.bind(e.TYPES.BashRunService).to(t.BashRunService).inSingletonScope(),g}exports.createRunnerContainer=g;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["Container","TYPES","SystemClock","NodeSpawner","NodeProcessControl","NodePtySpawner","RunnerPaths","NodeLifeline","createDefaultProcessRegistry","RunnerRegistry","RunnerNamer","LogFile","LogReader","Launcher","RmuxBackend","PtyHost","BashRunService"],"sources":["../../src/container/index.ts"],"sourcesContent":["import { Container } from 'inversify';\nimport 'reflect-metadata/lite';\nimport { BashRunService, type IBashRunService } from '../services/BashRunService/index.ts';\nimport { type IClock, SystemClock } from '../services/Clock/index.ts';\nimport { type ILauncher, Launcher } from '../services/Launcher/index.ts';\nimport { type ILifeline, NodeLifeline } from '../services/Lifeline/index.ts';\nimport { type IPtyHost, PtyHost } from '../services/PtyHost/index.ts';\nimport { type ILogFile, LogFile } from '../services/LogFile/index.ts';\nimport { type ILogReader, LogReader } from '../services/LogReader/index.ts';\nimport { type IProcessControl, NodeProcessControl } from '../services/ProcessControl/index.ts';\nimport { type IPtySpawner, NodePtySpawner } from '../services/PtySpawner/index.ts';\nimport { type IRunnerNamer, RunnerNamer } from '../services/RunnerNamer/index.ts';\nimport { type IRunnerPaths, RunnerPaths } from '../services/RunnerPaths/index.ts';\nimport { type IRmuxBackend, RmuxBackend } from '../services/RmuxBackend/index.ts';\nimport {\n createDefaultProcessRegistry,\n type IRunnerRegistry,\n type ProcessRegistryPort,\n RunnerRegistry,\n} from '../services/RunnerRegistry/index.ts';\nimport { type ISpawner, NodeSpawner } from '../services/Spawner/index.ts';\nimport { TYPES } from '../types.ts';\n\n/**\n * Builds the extension's service graph.\n *\n * A factory rather than a module-level singleton: the extension owns one\n * container per session, and tests get a fresh graph they can rebind ports on\n * without leaking state between cases.\n */\nexport function createRunnerContainer(): Container {\n const container = new Container();\n\n container.bind<IClock>(TYPES.Clock).to(SystemClock).inSingletonScope();\n container.bind<ISpawner>(TYPES.Spawner).to(NodeSpawner).inSingletonScope();\n container.bind<IProcessControl>(TYPES.ProcessControl).to(NodeProcessControl).inSingletonScope();\n container.bind<IPtySpawner>(TYPES.PtySpawner).to(NodePtySpawner).inSingletonScope();\n\n container.bind<IRunnerPaths>(TYPES.RunnerPaths).to(RunnerPaths).inSingletonScope();\n container.bind<ILifeline>(TYPES.Lifeline).to(NodeLifeline).inSingletonScope();\n // Dynamic value rather than a class binding: opening the SQLite registry is\n // deferred until something actually needs a runner.\n container\n .bind<ProcessRegistryPort>(TYPES.ProcessRegistry)\n .toDynamicValue(() => createDefaultProcessRegistry())\n .inSingletonScope();\n container.bind<IRunnerRegistry>(TYPES.RunnerRegistry).to(RunnerRegistry).inSingletonScope();\n container.bind<IRunnerNamer>(TYPES.RunnerNamer).to(RunnerNamer).inSingletonScope();\n container.bind<ILogFile>(TYPES.LogFile).to(LogFile).inSingletonScope();\n container.bind<ILogReader>(TYPES.LogReader).to(LogReader).inSingletonScope();\n container.bind<ILauncher>(TYPES.Launcher).to(Launcher).inSingletonScope();\n container.bind<IRmuxBackend>(TYPES.RmuxBackend).to(RmuxBackend).inSingletonScope();\n container.bind<IPtyHost>(TYPES.PtyHost).to(PtyHost).inSingletonScope();\n container.bind<IBashRunService>(TYPES.BashRunService).to(BashRunService).inSingletonScope();\n\n return container;\n}\n"],"mappings":"yiDA8BA,SAAgB,GAAmC,CACjD,IAAM,EAAY,IAAIA,EAAAA,UAwBtB,OAtBA,EAAU,KAAaC,EAAAA,MAAM,KAAK,CAAC,CAAC,GAAGC,EAAAA,WAAW,CAAC,CAAC,iBAAiB,EACrE,EAAU,KAAeD,EAAAA,MAAM,OAAO,CAAC,CAAC,GAAGE,EAAAA,WAAW,CAAC,CAAC,iBAAiB,EACzE,EAAU,KAAsBF,EAAAA,MAAM,cAAc,CAAC,CAAC,GAAGG,EAAAA,kBAAkB,CAAC,CAAC,iBAAiB,EAC9F,EAAU,KAAkBH,EAAAA,MAAM,UAAU,CAAC,CAAC,GAAGI,EAAAA,cAAc,CAAC,CAAC,iBAAiB,EAElF,EAAU,KAAmBJ,EAAAA,MAAM,WAAW,CAAC,CAAC,GAAGK,EAAAA,WAAW,CAAC,CAAC,iBAAiB,EACjF,EAAU,KAAgBL,EAAAA,MAAM,QAAQ,CAAC,CAAC,GAAGM,EAAAA,YAAY,CAAC,CAAC,iBAAiB,EAG5E,EACG,KAA0BN,EAAAA,MAAM,eAAe,CAAC,CAChD,mBAAqBO,EAAAA,6BAA6B,CAAC,CAAC,CACpD,iBAAiB,EACpB,EAAU,KAAsBP,EAAAA,MAAM,cAAc,CAAC,CAAC,GAAGQ,EAAAA,cAAc,CAAC,CAAC,iBAAiB,EAC1F,EAAU,KAAmBR,EAAAA,MAAM,WAAW,CAAC,CAAC,GAAGS,EAAAA,WAAW,CAAC,CAAC,iBAAiB,EACjF,EAAU,KAAeT,EAAAA,MAAM,OAAO,CAAC,CAAC,GAAGU,EAAAA,OAAO,CAAC,CAAC,iBAAiB,EACrE,EAAU,KAAiBV,EAAAA,MAAM,SAAS,CAAC,CAAC,GAAGW,EAAAA,SAAS,CAAC,CAAC,iBAAiB,EAC3E,EAAU,KAAgBX,EAAAA,MAAM,QAAQ,CAAC,CAAC,GAAGY,EAAAA,QAAQ,CAAC,CAAC,iBAAiB,EACxE,EAAU,KAAmBZ,EAAAA,MAAM,WAAW,CAAC,CAAC,GAAGa,EAAAA,WAAW,CAAC,CAAC,iBAAiB,EACjF,EAAU,KAAeb,EAAAA,MAAM,OAAO,CAAC,CAAC,GAAGc,EAAAA,OAAO,CAAC,CAAC,iBAAiB,EACrE,EAAU,KAAsBd,EAAAA,MAAM,cAAc,CAAC,CAAC,GAAGe,EAAAA,cAAc,CAAC,CAAC,iBAAiB,EAEnF,CACT"}
1
+ {"version":3,"file":"index.cjs","names":["Container","TYPES","SystemClock","NodeSpawner","NodeProcessControl","NodePtySpawner","RunnerPaths","NodeLifeline","createDefaultProcessRegistry","RunnerRegistry","RunnerNamer","LogFile","LogReader","Launcher","RmuxBackend","PtyHost","BashRunService"],"sources":["../../src/container/index.ts"],"sourcesContent":["import { Container } from 'inversify';\nimport 'reflect-metadata/lite';\nimport { BashRunService, type IBashRunService } from '../services/BashRunService/index.ts';\nimport { type IClock, SystemClock } from '../services/Clock/index.ts';\nimport { type ILauncher, Launcher } from '../services/Launcher/index.ts';\nimport { type ILifeline, NodeLifeline } from '../services/Lifeline/index.ts';\nimport { type ILogFile, LogFile } from '../services/LogFile/index.ts';\nimport { type ILogReader, LogReader } from '../services/LogReader/index.ts';\nimport { type IProcessControl, NodeProcessControl } from '../services/ProcessControl/index.ts';\nimport { type IPtyHost, PtyHost } from '../services/PtyHost/index.ts';\nimport { type IPtySpawner, NodePtySpawner } from '../services/PtySpawner/index.ts';\nimport { type IRmuxBackend, RmuxBackend } from '../services/RmuxBackend/index.ts';\nimport { type IRunnerNamer, RunnerNamer } from '../services/RunnerNamer/index.ts';\nimport { type IRunnerPaths, RunnerPaths } from '../services/RunnerPaths/index.ts';\nimport {\n createDefaultProcessRegistry,\n type IRunnerRegistry,\n type ProcessRegistryPort,\n RunnerRegistry,\n} from '../services/RunnerRegistry/index.ts';\nimport { type ISpawner, NodeSpawner } from '../services/Spawner/index.ts';\nimport { TYPES } from '../types/index.ts';\n\n/**\n * Builds the extension's service graph.\n *\n * A factory rather than a module-level singleton: the extension owns one\n * container per session, and tests get a fresh graph they can rebind ports on\n * without leaking state between cases.\n */\nexport function createRunnerContainer(): Container {\n const container = new Container();\n\n container.bind<IClock>(TYPES.Clock).to(SystemClock).inSingletonScope();\n container.bind<ISpawner>(TYPES.Spawner).to(NodeSpawner).inSingletonScope();\n container.bind<IProcessControl>(TYPES.ProcessControl).to(NodeProcessControl).inSingletonScope();\n container.bind<IPtySpawner>(TYPES.PtySpawner).to(NodePtySpawner).inSingletonScope();\n\n container.bind<IRunnerPaths>(TYPES.RunnerPaths).to(RunnerPaths).inSingletonScope();\n container.bind<ILifeline>(TYPES.Lifeline).to(NodeLifeline).inSingletonScope();\n // Dynamic value rather than a class binding: opening the SQLite registry is\n // deferred until something actually needs a runner.\n container\n .bind<ProcessRegistryPort>(TYPES.ProcessRegistry)\n .toDynamicValue(() => createDefaultProcessRegistry())\n .inSingletonScope();\n container.bind<IRunnerRegistry>(TYPES.RunnerRegistry).to(RunnerRegistry).inSingletonScope();\n container.bind<IRunnerNamer>(TYPES.RunnerNamer).to(RunnerNamer).inSingletonScope();\n container.bind<ILogFile>(TYPES.LogFile).to(LogFile).inSingletonScope();\n container.bind<ILogReader>(TYPES.LogReader).to(LogReader).inSingletonScope();\n container.bind<ILauncher>(TYPES.Launcher).to(Launcher).inSingletonScope();\n container.bind<IRmuxBackend>(TYPES.RmuxBackend).to(RmuxBackend).inSingletonScope();\n container.bind<IPtyHost>(TYPES.PtyHost).to(PtyHost).inSingletonScope();\n container.bind<IBashRunService>(TYPES.BashRunService).to(BashRunService).inSingletonScope();\n\n return container;\n}\n"],"mappings":"miDA8BA,SAAgB,GAAmC,CACjD,IAAM,EAAY,IAAIA,EAAAA,UAwBtB,OAtBA,EAAU,KAAaC,EAAAA,MAAM,KAAK,CAAC,CAAC,GAAGC,EAAAA,WAAW,CAAC,CAAC,iBAAiB,EACrE,EAAU,KAAeD,EAAAA,MAAM,OAAO,CAAC,CAAC,GAAGE,EAAAA,WAAW,CAAC,CAAC,iBAAiB,EACzE,EAAU,KAAsBF,EAAAA,MAAM,cAAc,CAAC,CAAC,GAAGG,EAAAA,kBAAkB,CAAC,CAAC,iBAAiB,EAC9F,EAAU,KAAkBH,EAAAA,MAAM,UAAU,CAAC,CAAC,GAAGI,EAAAA,cAAc,CAAC,CAAC,iBAAiB,EAElF,EAAU,KAAmBJ,EAAAA,MAAM,WAAW,CAAC,CAAC,GAAGK,EAAAA,WAAW,CAAC,CAAC,iBAAiB,EACjF,EAAU,KAAgBL,EAAAA,MAAM,QAAQ,CAAC,CAAC,GAAGM,EAAAA,YAAY,CAAC,CAAC,iBAAiB,EAG5E,EACG,KAA0BN,EAAAA,MAAM,eAAe,CAAC,CAChD,mBAAqBO,EAAAA,6BAA6B,CAAC,CAAC,CACpD,iBAAiB,EACpB,EAAU,KAAsBP,EAAAA,MAAM,cAAc,CAAC,CAAC,GAAGQ,EAAAA,cAAc,CAAC,CAAC,iBAAiB,EAC1F,EAAU,KAAmBR,EAAAA,MAAM,WAAW,CAAC,CAAC,GAAGS,EAAAA,WAAW,CAAC,CAAC,iBAAiB,EACjF,EAAU,KAAeT,EAAAA,MAAM,OAAO,CAAC,CAAC,GAAGU,EAAAA,OAAO,CAAC,CAAC,iBAAiB,EACrE,EAAU,KAAiBV,EAAAA,MAAM,SAAS,CAAC,CAAC,GAAGW,EAAAA,SAAS,CAAC,CAAC,iBAAiB,EAC3E,EAAU,KAAgBX,EAAAA,MAAM,QAAQ,CAAC,CAAC,GAAGY,EAAAA,QAAQ,CAAC,CAAC,iBAAiB,EACxE,EAAU,KAAmBZ,EAAAA,MAAM,WAAW,CAAC,CAAC,GAAGa,EAAAA,WAAW,CAAC,CAAC,iBAAiB,EACjF,EAAU,KAAeb,EAAAA,MAAM,OAAO,CAAC,CAAC,GAAGc,EAAAA,OAAO,CAAC,CAAC,iBAAiB,EACrE,EAAU,KAAsBd,EAAAA,MAAM,cAAc,CAAC,CAAC,GAAGe,EAAAA,cAAc,CAAC,CAAC,iBAAiB,EAEnF,CACT"}
@@ -1,2 +1,2 @@
1
- import{TYPES as e}from"../types.mjs";import{BashRunService as t}from"../services/BashRunService/BashRunService.mjs";import"../services/BashRunService/index.mjs";import{SystemClock as n}from"../services/Clock/SystemClock.mjs";import"../services/Clock/index.mjs";import{Launcher as r}from"../services/Launcher/Launcher.mjs";import"../services/Launcher/index.mjs";import{NodeLifeline as i}from"../services/Lifeline/NodeLifeline.mjs";import"../services/Lifeline/index.mjs";import{PtyHost as a}from"../services/PtyHost/PtyHost.mjs";import"../services/PtyHost/index.mjs";import{LogFile as o}from"../services/LogFile/LogFile.mjs";import"../services/LogFile/index.mjs";import{LogReader as s}from"../services/LogReader/LogReader.mjs";import"../services/LogReader/index.mjs";import{NodeProcessControl as c}from"../services/ProcessControl/NodeProcessControl.mjs";import"../services/ProcessControl/index.mjs";import{NodePtySpawner as l}from"../services/PtySpawner/NodePtySpawner.mjs";import"../services/PtySpawner/index.mjs";import{RunnerNamer as u}from"../services/RunnerNamer/RunnerNamer.mjs";import"../services/RunnerNamer/index.mjs";import{RunnerPaths as d}from"../services/RunnerPaths/RunnerPaths.mjs";import"../services/RunnerPaths/index.mjs";import{RmuxBackend as f}from"../services/RmuxBackend/RmuxBackend.mjs";import"../services/RmuxBackend/index.mjs";import{RunnerRegistry as p,createDefaultProcessRegistry as m}from"../services/RunnerRegistry/RunnerRegistry.mjs";import"../services/RunnerRegistry/index.mjs";import{NodeSpawner as h}from"../services/Spawner/NodeSpawner.mjs";import"../services/Spawner/index.mjs";import{Container as g}from"inversify";import"reflect-metadata/lite";function _(){let _=new g;return _.bind(e.Clock).to(n).inSingletonScope(),_.bind(e.Spawner).to(h).inSingletonScope(),_.bind(e.ProcessControl).to(c).inSingletonScope(),_.bind(e.PtySpawner).to(l).inSingletonScope(),_.bind(e.RunnerPaths).to(d).inSingletonScope(),_.bind(e.Lifeline).to(i).inSingletonScope(),_.bind(e.ProcessRegistry).toDynamicValue(()=>m()).inSingletonScope(),_.bind(e.RunnerRegistry).to(p).inSingletonScope(),_.bind(e.RunnerNamer).to(u).inSingletonScope(),_.bind(e.LogFile).to(o).inSingletonScope(),_.bind(e.LogReader).to(s).inSingletonScope(),_.bind(e.Launcher).to(r).inSingletonScope(),_.bind(e.RmuxBackend).to(f).inSingletonScope(),_.bind(e.PtyHost).to(a).inSingletonScope(),_.bind(e.BashRunService).to(t).inSingletonScope(),_}export{_ as createRunnerContainer};
1
+ import{TYPES as e}from"../types/index.mjs";import{BashRunService as t}from"../services/BashRunService/BashRunService.mjs";import"../services/BashRunService/index.mjs";import{SystemClock as n}from"../services/Clock/SystemClock.mjs";import"../services/Clock/index.mjs";import{Launcher as r}from"../services/Launcher/Launcher.mjs";import"../services/Launcher/index.mjs";import{NodeLifeline as i}from"../services/Lifeline/NodeLifeline.mjs";import"../services/Lifeline/index.mjs";import{LogFile as a}from"../services/LogFile/LogFile.mjs";import"../services/LogFile/index.mjs";import{LogReader as o}from"../services/LogReader/LogReader.mjs";import"../services/LogReader/index.mjs";import{NodeProcessControl as s}from"../services/ProcessControl/NodeProcessControl.mjs";import"../services/ProcessControl/index.mjs";import{PtyHost as c}from"../services/PtyHost/PtyHost.mjs";import"../services/PtyHost/index.mjs";import{NodePtySpawner as l}from"../services/PtySpawner/NodePtySpawner.mjs";import"../services/PtySpawner/index.mjs";import{RmuxBackend as u}from"../services/RmuxBackend/RmuxBackend.mjs";import"../services/RmuxBackend/index.mjs";import{RunnerNamer as d}from"../services/RunnerNamer/RunnerNamer.mjs";import"../services/RunnerNamer/index.mjs";import{RunnerPaths as f}from"../adapters/RunnerPaths.mjs";import"../services/RunnerPaths/index.mjs";import{RunnerRegistry as p,createDefaultProcessRegistry as m}from"../services/RunnerRegistry/RunnerRegistry.mjs";import"../services/RunnerRegistry/index.mjs";import{NodeSpawner as h}from"../services/Spawner/NodeSpawner.mjs";import"../services/Spawner/index.mjs";import{Container as g}from"inversify";import"reflect-metadata/lite";function _(){let _=new g;return _.bind(e.Clock).to(n).inSingletonScope(),_.bind(e.Spawner).to(h).inSingletonScope(),_.bind(e.ProcessControl).to(s).inSingletonScope(),_.bind(e.PtySpawner).to(l).inSingletonScope(),_.bind(e.RunnerPaths).to(f).inSingletonScope(),_.bind(e.Lifeline).to(i).inSingletonScope(),_.bind(e.ProcessRegistry).toDynamicValue(()=>m()).inSingletonScope(),_.bind(e.RunnerRegistry).to(p).inSingletonScope(),_.bind(e.RunnerNamer).to(d).inSingletonScope(),_.bind(e.LogFile).to(a).inSingletonScope(),_.bind(e.LogReader).to(o).inSingletonScope(),_.bind(e.Launcher).to(r).inSingletonScope(),_.bind(e.RmuxBackend).to(u).inSingletonScope(),_.bind(e.PtyHost).to(c).inSingletonScope(),_.bind(e.BashRunService).to(t).inSingletonScope(),_}export{_ as createRunnerContainer};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/container/index.ts"],"sourcesContent":["import { Container } from 'inversify';\nimport 'reflect-metadata/lite';\nimport { BashRunService, type IBashRunService } from '../services/BashRunService/index.ts';\nimport { type IClock, SystemClock } from '../services/Clock/index.ts';\nimport { type ILauncher, Launcher } from '../services/Launcher/index.ts';\nimport { type ILifeline, NodeLifeline } from '../services/Lifeline/index.ts';\nimport { type IPtyHost, PtyHost } from '../services/PtyHost/index.ts';\nimport { type ILogFile, LogFile } from '../services/LogFile/index.ts';\nimport { type ILogReader, LogReader } from '../services/LogReader/index.ts';\nimport { type IProcessControl, NodeProcessControl } from '../services/ProcessControl/index.ts';\nimport { type IPtySpawner, NodePtySpawner } from '../services/PtySpawner/index.ts';\nimport { type IRunnerNamer, RunnerNamer } from '../services/RunnerNamer/index.ts';\nimport { type IRunnerPaths, RunnerPaths } from '../services/RunnerPaths/index.ts';\nimport { type IRmuxBackend, RmuxBackend } from '../services/RmuxBackend/index.ts';\nimport {\n createDefaultProcessRegistry,\n type IRunnerRegistry,\n type ProcessRegistryPort,\n RunnerRegistry,\n} from '../services/RunnerRegistry/index.ts';\nimport { type ISpawner, NodeSpawner } from '../services/Spawner/index.ts';\nimport { TYPES } from '../types.ts';\n\n/**\n * Builds the extension's service graph.\n *\n * A factory rather than a module-level singleton: the extension owns one\n * container per session, and tests get a fresh graph they can rebind ports on\n * without leaking state between cases.\n */\nexport function createRunnerContainer(): Container {\n const container = new Container();\n\n container.bind<IClock>(TYPES.Clock).to(SystemClock).inSingletonScope();\n container.bind<ISpawner>(TYPES.Spawner).to(NodeSpawner).inSingletonScope();\n container.bind<IProcessControl>(TYPES.ProcessControl).to(NodeProcessControl).inSingletonScope();\n container.bind<IPtySpawner>(TYPES.PtySpawner).to(NodePtySpawner).inSingletonScope();\n\n container.bind<IRunnerPaths>(TYPES.RunnerPaths).to(RunnerPaths).inSingletonScope();\n container.bind<ILifeline>(TYPES.Lifeline).to(NodeLifeline).inSingletonScope();\n // Dynamic value rather than a class binding: opening the SQLite registry is\n // deferred until something actually needs a runner.\n container\n .bind<ProcessRegistryPort>(TYPES.ProcessRegistry)\n .toDynamicValue(() => createDefaultProcessRegistry())\n .inSingletonScope();\n container.bind<IRunnerRegistry>(TYPES.RunnerRegistry).to(RunnerRegistry).inSingletonScope();\n container.bind<IRunnerNamer>(TYPES.RunnerNamer).to(RunnerNamer).inSingletonScope();\n container.bind<ILogFile>(TYPES.LogFile).to(LogFile).inSingletonScope();\n container.bind<ILogReader>(TYPES.LogReader).to(LogReader).inSingletonScope();\n container.bind<ILauncher>(TYPES.Launcher).to(Launcher).inSingletonScope();\n container.bind<IRmuxBackend>(TYPES.RmuxBackend).to(RmuxBackend).inSingletonScope();\n container.bind<IPtyHost>(TYPES.PtyHost).to(PtyHost).inSingletonScope();\n container.bind<IBashRunService>(TYPES.BashRunService).to(BashRunService).inSingletonScope();\n\n return container;\n}\n"],"mappings":"+oDA8BA,SAAgB,GAAmC,CACjD,IAAM,EAAY,IAAI,EAwBtB,OAtBA,EAAU,KAAa,EAAM,KAAK,CAAC,CAAC,GAAG,CAAW,CAAC,CAAC,iBAAiB,EACrE,EAAU,KAAe,EAAM,OAAO,CAAC,CAAC,GAAG,CAAW,CAAC,CAAC,iBAAiB,EACzE,EAAU,KAAsB,EAAM,cAAc,CAAC,CAAC,GAAG,CAAkB,CAAC,CAAC,iBAAiB,EAC9F,EAAU,KAAkB,EAAM,UAAU,CAAC,CAAC,GAAG,CAAc,CAAC,CAAC,iBAAiB,EAElF,EAAU,KAAmB,EAAM,WAAW,CAAC,CAAC,GAAG,CAAW,CAAC,CAAC,iBAAiB,EACjF,EAAU,KAAgB,EAAM,QAAQ,CAAC,CAAC,GAAG,CAAY,CAAC,CAAC,iBAAiB,EAG5E,EACG,KAA0B,EAAM,eAAe,CAAC,CAChD,mBAAqB,EAA6B,CAAC,CAAC,CACpD,iBAAiB,EACpB,EAAU,KAAsB,EAAM,cAAc,CAAC,CAAC,GAAG,CAAc,CAAC,CAAC,iBAAiB,EAC1F,EAAU,KAAmB,EAAM,WAAW,CAAC,CAAC,GAAG,CAAW,CAAC,CAAC,iBAAiB,EACjF,EAAU,KAAe,EAAM,OAAO,CAAC,CAAC,GAAG,CAAO,CAAC,CAAC,iBAAiB,EACrE,EAAU,KAAiB,EAAM,SAAS,CAAC,CAAC,GAAG,CAAS,CAAC,CAAC,iBAAiB,EAC3E,EAAU,KAAgB,EAAM,QAAQ,CAAC,CAAC,GAAG,CAAQ,CAAC,CAAC,iBAAiB,EACxE,EAAU,KAAmB,EAAM,WAAW,CAAC,CAAC,GAAG,CAAW,CAAC,CAAC,iBAAiB,EACjF,EAAU,KAAe,EAAM,OAAO,CAAC,CAAC,GAAG,CAAO,CAAC,CAAC,iBAAiB,EACrE,EAAU,KAAsB,EAAM,cAAc,CAAC,CAAC,GAAG,CAAc,CAAC,CAAC,iBAAiB,EAEnF,CACT"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/container/index.ts"],"sourcesContent":["import { Container } from 'inversify';\nimport 'reflect-metadata/lite';\nimport { BashRunService, type IBashRunService } from '../services/BashRunService/index.ts';\nimport { type IClock, SystemClock } from '../services/Clock/index.ts';\nimport { type ILauncher, Launcher } from '../services/Launcher/index.ts';\nimport { type ILifeline, NodeLifeline } from '../services/Lifeline/index.ts';\nimport { type ILogFile, LogFile } from '../services/LogFile/index.ts';\nimport { type ILogReader, LogReader } from '../services/LogReader/index.ts';\nimport { type IProcessControl, NodeProcessControl } from '../services/ProcessControl/index.ts';\nimport { type IPtyHost, PtyHost } from '../services/PtyHost/index.ts';\nimport { type IPtySpawner, NodePtySpawner } from '../services/PtySpawner/index.ts';\nimport { type IRmuxBackend, RmuxBackend } from '../services/RmuxBackend/index.ts';\nimport { type IRunnerNamer, RunnerNamer } from '../services/RunnerNamer/index.ts';\nimport { type IRunnerPaths, RunnerPaths } from '../services/RunnerPaths/index.ts';\nimport {\n createDefaultProcessRegistry,\n type IRunnerRegistry,\n type ProcessRegistryPort,\n RunnerRegistry,\n} from '../services/RunnerRegistry/index.ts';\nimport { type ISpawner, NodeSpawner } from '../services/Spawner/index.ts';\nimport { TYPES } from '../types/index.ts';\n\n/**\n * Builds the extension's service graph.\n *\n * A factory rather than a module-level singleton: the extension owns one\n * container per session, and tests get a fresh graph they can rebind ports on\n * without leaking state between cases.\n */\nexport function createRunnerContainer(): Container {\n const container = new Container();\n\n container.bind<IClock>(TYPES.Clock).to(SystemClock).inSingletonScope();\n container.bind<ISpawner>(TYPES.Spawner).to(NodeSpawner).inSingletonScope();\n container.bind<IProcessControl>(TYPES.ProcessControl).to(NodeProcessControl).inSingletonScope();\n container.bind<IPtySpawner>(TYPES.PtySpawner).to(NodePtySpawner).inSingletonScope();\n\n container.bind<IRunnerPaths>(TYPES.RunnerPaths).to(RunnerPaths).inSingletonScope();\n container.bind<ILifeline>(TYPES.Lifeline).to(NodeLifeline).inSingletonScope();\n // Dynamic value rather than a class binding: opening the SQLite registry is\n // deferred until something actually needs a runner.\n container\n .bind<ProcessRegistryPort>(TYPES.ProcessRegistry)\n .toDynamicValue(() => createDefaultProcessRegistry())\n .inSingletonScope();\n container.bind<IRunnerRegistry>(TYPES.RunnerRegistry).to(RunnerRegistry).inSingletonScope();\n container.bind<IRunnerNamer>(TYPES.RunnerNamer).to(RunnerNamer).inSingletonScope();\n container.bind<ILogFile>(TYPES.LogFile).to(LogFile).inSingletonScope();\n container.bind<ILogReader>(TYPES.LogReader).to(LogReader).inSingletonScope();\n container.bind<ILauncher>(TYPES.Launcher).to(Launcher).inSingletonScope();\n container.bind<IRmuxBackend>(TYPES.RmuxBackend).to(RmuxBackend).inSingletonScope();\n container.bind<IPtyHost>(TYPES.PtyHost).to(PtyHost).inSingletonScope();\n container.bind<IBashRunService>(TYPES.BashRunService).to(BashRunService).inSingletonScope();\n\n return container;\n}\n"],"mappings":"yoDA8BA,SAAgB,GAAmC,CACjD,IAAM,EAAY,IAAI,EAwBtB,OAtBA,EAAU,KAAa,EAAM,KAAK,CAAC,CAAC,GAAG,CAAW,CAAC,CAAC,iBAAiB,EACrE,EAAU,KAAe,EAAM,OAAO,CAAC,CAAC,GAAG,CAAW,CAAC,CAAC,iBAAiB,EACzE,EAAU,KAAsB,EAAM,cAAc,CAAC,CAAC,GAAG,CAAkB,CAAC,CAAC,iBAAiB,EAC9F,EAAU,KAAkB,EAAM,UAAU,CAAC,CAAC,GAAG,CAAc,CAAC,CAAC,iBAAiB,EAElF,EAAU,KAAmB,EAAM,WAAW,CAAC,CAAC,GAAG,CAAW,CAAC,CAAC,iBAAiB,EACjF,EAAU,KAAgB,EAAM,QAAQ,CAAC,CAAC,GAAG,CAAY,CAAC,CAAC,iBAAiB,EAG5E,EACG,KAA0B,EAAM,eAAe,CAAC,CAChD,mBAAqB,EAA6B,CAAC,CAAC,CACpD,iBAAiB,EACpB,EAAU,KAAsB,EAAM,cAAc,CAAC,CAAC,GAAG,CAAc,CAAC,CAAC,iBAAiB,EAC1F,EAAU,KAAmB,EAAM,WAAW,CAAC,CAAC,GAAG,CAAW,CAAC,CAAC,iBAAiB,EACjF,EAAU,KAAe,EAAM,OAAO,CAAC,CAAC,GAAG,CAAO,CAAC,CAAC,iBAAiB,EACrE,EAAU,KAAiB,EAAM,SAAS,CAAC,CAAC,GAAG,CAAS,CAAC,CAAC,iBAAiB,EAC3E,EAAU,KAAgB,EAAM,QAAQ,CAAC,CAAC,GAAG,CAAQ,CAAC,CAAC,iBAAiB,EACxE,EAAU,KAAmB,EAAM,WAAW,CAAC,CAAC,GAAG,CAAW,CAAC,CAAC,iBAAiB,EACjF,EAAU,KAAe,EAAM,OAAO,CAAC,CAAC,GAAG,CAAO,CAAC,CAAC,iBAAiB,EACrE,EAAU,KAAsB,EAAM,cAAc,CAAC,CAAC,GAAG,CAAc,CAAC,CAAC,iBAAiB,EAEnF,CACT"}
@@ -1,3 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./config.cjs"),t=require("./types.cjs"),n=require("./container/index.cjs"),r=require("./compaction.cjs"),i=require("./ptyProvider.cjs"),a=require("./reconcile.cjs"),o=require("./tool/bashTool.cjs"),s=require("./tui/format.cjs"),c=require("./tui/runnerSpace.cjs");let l=require("@agimon-ai/doompi-extension-contracts/child-process"),u=require("@agimon-ai/doompi-telemetry"),d=require("@agimon-ai/doompi-extension-contracts/protocol"),f=require("@agimon-ai/doompi-ui/footer"),p=require("@agimon-ai/doompi-ui/leader");const m=`@agimon-ai/doompi-runner`,h=`runners`,g=`completed`,_=`stopped`,v=`doom-runner-runners`;function y(y){let b=n.createRunnerContainer(),x=b.get(t.TYPES.RunnerRegistry),S=b.get(t.TYPES.Launcher),C=b.get(t.TYPES.RmuxBackend),w=b.get(t.TYPES.LogReader),T=b.get(t.TYPES.PtyHost),E=b.get(t.TYPES.BashRunService),D=b.get(t.TYPES.RunnerPaths),O=b.get(t.TYPES.ProcessControl),k=b.get(t.TYPES.Lifeline),A,j,M=[],N,P,F,I=!1,L=!1,R=!1,z,B=!1,V=!1,H,U=new Set,W=new Set,G=e=>(F??=(0,u.createDoomTelemetry)({serviceName:`doom-runner`,packageName:`@agimon-ai/doompi-runner`,cwd:e.cwd,env:process.env,enableLogs:!0,enableTraces:!0}),F),K=(0,f.registerDoomFooterContribution)(y,{source:m,id:`runner-count`,order:10}),q=async e=>{let t=A;if(!t||L)return;let n=await x.list();if(L)return;let r=n;if(e){let e=await a.reconcileActiveRunners({registry:x,launcher:S,rmuxBackend:C,processControl:O,currentHostPid:process.pid,startup:!1,active:n});for(let t of e.errors)process.emitWarning(t);if(e.reclaimed.length>0){let t=new Set(e.reclaimed);r=n.filter(e=>!t.has(e.id))}}if(L)return;M=r.filter(e=>e.sessionId===t);let i=(j?r.filter(e=>(e.rootSessionId??e.sessionId)===j):[]).length;H!==i&&(H=i,K.update(s.formatRunnerFooterContribution(i)),N?.hasUI&&N.ui.setStatus(v,s.formatRunnerStatus(i)));let o=[...W],c=await Promise.all(o.map(e=>x.get(e,t)));if(!L)for(let[e,n]of c.entries()){let r=o[e];if(!r)continue;if(!n||n.sessionId!==t){W.delete(r);continue}if(n.state!==g||(W.delete(n.id),U.has(n.id)))continue;U.add(n.id);let i=n.exit?.reason??g,a=n.exit?.code===null||n.exit?.code===void 0?``:`, exit code ${n.exit.code}`,s=[`Background runner ${n.name} exited: ${i}${a}.`,`Runner ID: ${n.id}`,`Log: ${n.logPath}`,`Inspect: doom-runner logs ${n.id}`].join(`
2
- `);y.sendMessage({customType:`doom-runner-finished`,content:s,display:!0},{triggerTurn:!0,deliverAs:`steer`}),N&&G(N).recordEvent(`doom_runner.process_finished`,{outcome:`completed`,"runner.exit_code":n.exit?.code??0,"runner.backend":n.backend,...Number.isFinite(Date.parse(n.startedAt))?{duration_ms:Math.max(0,Date.now()-Date.parse(n.startedAt))}:{}})}},J=(e=!0)=>{if(!A||!I||L)return Promise.resolve();if(z)return B=!0,V||=e,z;let t=(async()=>{let t=e;do B=!1,V=!1,await q(t),t=V;while(B&&!L)})().finally(()=>{z===t&&(z=void 0)});return z=t,t},Y=e=>{L||(N&&G(N).recordError(`doom_runner.refresh_failed`,e),process.emitWarning(`Could not refresh doom-runner: ${String(e)}`))},X=e=>{J(e).catch(Y)},Z=x.subscribe(()=>X(!1)),Q=setInterval(()=>X(!0),500);Q.unref?.(),o.registerBashTool(y,{bashRunService:E,getSessionId:()=>{if(!A)throw Error(`doom-runner requires an active Pi session`);return A},onRunnerStarted:e=>{W.add(e),X(!1)}}),r.registerRunnerCompactionRecovery(y,{getSessionId:()=>A,listBySession:e=>x.listBySession(e)}),y.registerCommand(h,{description:`Open Runner Space: background processes started by bash`,handler:async(e,t)=>{if(!t.hasUI){t.ui.notify(`/runners requires interactive mode`,`error`);return}await J(),await c.openRunnerSpace(t,{getRunners:()=>M,getPtyRun:e=>C.get(e)??T.get(e),readLog:e=>w.read(e,{lines:1e3}).text,stopRunner:async(e,t)=>{let n=M.find(t=>t.id===e);n&&(n.backend===`rmux`&&n.backendTarget?await C.stop(n.backendTarget,n.pid):await S.stop(n.pid),await x.complete(n.id,{reason:_,code:null,signal:null,stopReason:t},n.sessionId),await J())}})}}),(0,p.registerDoomLeaderContribution)(y,{source:m,bindings:[{id:`runners.open`,path:[{key:`r`,label:`runners`,order:67},{key:`r`,label:`open`,detail:`background processes`}],command:{name:h}}]}),y.on(`session_start`,async(t,n)=>{let r=n,o=G(r);o.recordEvent(`doom_runner.session_started`,{outcome:`started`}),A=r.sessionManager.getSessionId(),D.setSessionId(A),j=(0,l.resolveRootSessionId)(A),N=r,I=!1,H=void 0,U.clear(),W.clear(),await k.arm(A),P?.(),P=i.provideRunnerPty((0,d.createProtocolRuntime)({bus:y.events,source:m,sessionId:A}),{ptyHost:T,sessionId:()=>A,onError:(e,t)=>void o.recordError(`doom_runner.pty_launch_failed`,e,{"run.id":t})});let s=await x.listAll(A);for(let e of s)e.state===g?U.add(e.id):e.promoted&&W.add(e.id);let c=await a.cleanupLegacyRunnerStore({registry:x,launcher:S,rmuxBackend:C,processControl:O,currentHostPid:process.pid,paths:D}),u=await a.reconcileActiveRunners({registry:x,launcher:S,rmuxBackend:C,processControl:O,currentHostPid:process.pid,startup:!0});I=!0,await J(!1);let f=D.sweepHistory(e.getLogTtlMs()),p=[...c.errors,...u.errors,...f.errors];for(let e of p)process.emitWarning(e);let h=c.reclaimed.length+u.reclaimed.length;h>0&&r.hasUI&&r.ui.notify(`Reclaimed ${h} stale runner record(s)`,`warning`),o.recordEvent(`doom_runner.reconciled`,{"runner.reclaimed_count":h,"runner.error_count":p.length,outcome:p.length===0?`completed`:`degraded`})}),y.on(`session_shutdown`,async()=>{if(R)return;R=!0,I=!1,L=!0,clearInterval(Q),Z();let e=z;if(e)try{await e}catch(e){process.emitWarning(`Could not settle doom-runner refresh during shutdown: ${String(e)}`)}try{try{P?.(),P=void 0,await T.disposeAll()}catch(e){process.emitWarning(`Could not dispose doom-runner PTYs: ${String(e)}`)}let e=A?await x.listBySession(A):[];for(let t of e)try{let e=await a.stopRunnerProcess(t,S,C);if(!e&&O.isAlive(t.pid)){process.emitWarning(`Could not stop runner ${t.id} during session shutdown`);continue}await x.complete(t.id,{reason:_,code:null,signal:e?`SIGTERM`:null,stopReason:`session ended`},t.sessionId)}catch(e){process.emitWarning(`Could not clean up runner ${t.id}: ${String(e)}`)}}finally{k.dispose(),K.dispose(),N?.hasUI&&N.ui.setStatus(v,void 0),x.close(),await F?.recordEvent(`doom_runner.session_finished`,{outcome:`stopped`}),await F?.shutdown(),F=void 0}})}exports.runnerExtension=y;
3
- //# sourceMappingURL=extension.cjs.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./adapters/pi/extension.cjs");exports.runnerExtension=e.runnerExtension;
@@ -1,10 +1,2 @@
1
- import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- //#region src/extension.d.ts
3
- /**
4
- * doom-runner: replaces pi's `bash` tool with a supervised one and provides a
5
- * CLI for anything it leaves running.
6
- */
7
- declare function runnerExtension(pi: ExtensionAPI): void;
8
- //#endregion
9
- export { runnerExtension };
10
- //# sourceMappingURL=extension.d.cts.map
1
+ import { runnerExtension } from "./adapters/pi/extension.cjs";
2
+ export { runnerExtension };
@@ -1,10 +1,2 @@
1
- import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- //#region src/extension.d.ts
3
- /**
4
- * doom-runner: replaces pi's `bash` tool with a supervised one and provides a
5
- * CLI for anything it leaves running.
6
- */
7
- declare function runnerExtension(pi: ExtensionAPI): void;
8
- //#endregion
9
- export { runnerExtension };
10
- //# sourceMappingURL=extension.d.mts.map
1
+ import { runnerExtension } from "./adapters/pi/extension.mjs";
2
+ export { runnerExtension };
@@ -1,3 +1 @@
1
- import{getLogTtlMs as e}from"./config.mjs";import{TYPES as t}from"./types.mjs";import{createRunnerContainer as n}from"./container/index.mjs";import{registerRunnerCompactionRecovery as r}from"./compaction.mjs";import{provideRunnerPty as i}from"./ptyProvider.mjs";import{cleanupLegacyRunnerStore as a,reconcileActiveRunners as o,stopRunnerProcess as s}from"./reconcile.mjs";import{registerBashTool as c}from"./tool/bashTool.mjs";import{formatRunnerFooterContribution as l,formatRunnerStatus as u}from"./tui/format.mjs";import{openRunnerSpace as d}from"./tui/runnerSpace.mjs";import{resolveRootSessionId as f}from"@agimon-ai/doompi-extension-contracts/child-process";import{createDoomTelemetry as p}from"@agimon-ai/doompi-telemetry";import{createProtocolRuntime as m}from"@agimon-ai/doompi-extension-contracts/protocol";import{registerDoomFooterContribution as h}from"@agimon-ai/doompi-ui/footer";import{registerDoomLeaderContribution as g}from"@agimon-ai/doompi-ui/leader";const _=`@agimon-ai/doompi-runner`,v=`runners`,y=`completed`,b=`stopped`,x=`doom-runner-runners`;function S(S){let C=n(),w=C.get(t.RunnerRegistry),T=C.get(t.Launcher),E=C.get(t.RmuxBackend),D=C.get(t.LogReader),O=C.get(t.PtyHost),k=C.get(t.BashRunService),A=C.get(t.RunnerPaths),j=C.get(t.ProcessControl),M=C.get(t.Lifeline),N,P,F=[],I,L,R,z=!1,B=!1,V=!1,H,U=!1,W=!1,G,K=new Set,q=new Set,J=e=>(R??=p({serviceName:`doom-runner`,packageName:`@agimon-ai/doompi-runner`,cwd:e.cwd,env:process.env,enableLogs:!0,enableTraces:!0}),R),Y=h(S,{source:_,id:`runner-count`,order:10}),X=async e=>{let t=N;if(!t||B)return;let n=await w.list();if(B)return;let r=n;if(e){let e=await o({registry:w,launcher:T,rmuxBackend:E,processControl:j,currentHostPid:process.pid,startup:!1,active:n});for(let t of e.errors)process.emitWarning(t);if(e.reclaimed.length>0){let t=new Set(e.reclaimed);r=n.filter(e=>!t.has(e.id))}}if(B)return;F=r.filter(e=>e.sessionId===t);let i=(P?r.filter(e=>(e.rootSessionId??e.sessionId)===P):[]).length;G!==i&&(G=i,Y.update(l(i)),I?.hasUI&&I.ui.setStatus(x,u(i)));let a=[...q],s=await Promise.all(a.map(e=>w.get(e,t)));if(!B)for(let[e,n]of s.entries()){let r=a[e];if(!r)continue;if(!n||n.sessionId!==t){q.delete(r);continue}if(n.state!==y||(q.delete(n.id),K.has(n.id)))continue;K.add(n.id);let i=n.exit?.reason??y,o=n.exit?.code===null||n.exit?.code===void 0?``:`, exit code ${n.exit.code}`,s=[`Background runner ${n.name} exited: ${i}${o}.`,`Runner ID: ${n.id}`,`Log: ${n.logPath}`,`Inspect: doom-runner logs ${n.id}`].join(`
2
- `);S.sendMessage({customType:`doom-runner-finished`,content:s,display:!0},{triggerTurn:!0,deliverAs:`steer`}),I&&J(I).recordEvent(`doom_runner.process_finished`,{outcome:`completed`,"runner.exit_code":n.exit?.code??0,"runner.backend":n.backend,...Number.isFinite(Date.parse(n.startedAt))?{duration_ms:Math.max(0,Date.now()-Date.parse(n.startedAt))}:{}})}},Z=(e=!0)=>{if(!N||!z||B)return Promise.resolve();if(H)return U=!0,W||=e,H;let t=(async()=>{let t=e;do U=!1,W=!1,await X(t),t=W;while(U&&!B)})().finally(()=>{H===t&&(H=void 0)});return H=t,t},ee=e=>{B||(I&&J(I).recordError(`doom_runner.refresh_failed`,e),process.emitWarning(`Could not refresh doom-runner: ${String(e)}`))},Q=e=>{Z(e).catch(ee)},te=w.subscribe(()=>Q(!1)),$=setInterval(()=>Q(!0),500);$.unref?.(),c(S,{bashRunService:k,getSessionId:()=>{if(!N)throw Error(`doom-runner requires an active Pi session`);return N},onRunnerStarted:e=>{q.add(e),Q(!1)}}),r(S,{getSessionId:()=>N,listBySession:e=>w.listBySession(e)}),S.registerCommand(v,{description:`Open Runner Space: background processes started by bash`,handler:async(e,t)=>{if(!t.hasUI){t.ui.notify(`/runners requires interactive mode`,`error`);return}await Z(),await d(t,{getRunners:()=>F,getPtyRun:e=>E.get(e)??O.get(e),readLog:e=>D.read(e,{lines:1e3}).text,stopRunner:async(e,t)=>{let n=F.find(t=>t.id===e);n&&(n.backend===`rmux`&&n.backendTarget?await E.stop(n.backendTarget,n.pid):await T.stop(n.pid),await w.complete(n.id,{reason:b,code:null,signal:null,stopReason:t},n.sessionId),await Z())}})}}),g(S,{source:_,bindings:[{id:`runners.open`,path:[{key:`r`,label:`runners`,order:67},{key:`r`,label:`open`,detail:`background processes`}],command:{name:v}}]}),S.on(`session_start`,async(t,n)=>{let r=n,s=J(r);s.recordEvent(`doom_runner.session_started`,{outcome:`started`}),N=r.sessionManager.getSessionId(),A.setSessionId(N),P=f(N),I=r,z=!1,G=void 0,K.clear(),q.clear(),await M.arm(N),L?.(),L=i(m({bus:S.events,source:_,sessionId:N}),{ptyHost:O,sessionId:()=>N,onError:(e,t)=>void s.recordError(`doom_runner.pty_launch_failed`,e,{"run.id":t})});let c=await w.listAll(N);for(let e of c)e.state===y?K.add(e.id):e.promoted&&q.add(e.id);let l=await a({registry:w,launcher:T,rmuxBackend:E,processControl:j,currentHostPid:process.pid,paths:A}),u=await o({registry:w,launcher:T,rmuxBackend:E,processControl:j,currentHostPid:process.pid,startup:!0});z=!0,await Z(!1);let d=A.sweepHistory(e()),p=[...l.errors,...u.errors,...d.errors];for(let e of p)process.emitWarning(e);let h=l.reclaimed.length+u.reclaimed.length;h>0&&r.hasUI&&r.ui.notify(`Reclaimed ${h} stale runner record(s)`,`warning`),s.recordEvent(`doom_runner.reconciled`,{"runner.reclaimed_count":h,"runner.error_count":p.length,outcome:p.length===0?`completed`:`degraded`})}),S.on(`session_shutdown`,async()=>{if(V)return;V=!0,z=!1,B=!0,clearInterval($),te();let e=H;if(e)try{await e}catch(e){process.emitWarning(`Could not settle doom-runner refresh during shutdown: ${String(e)}`)}try{try{L?.(),L=void 0,await O.disposeAll()}catch(e){process.emitWarning(`Could not dispose doom-runner PTYs: ${String(e)}`)}let e=N?await w.listBySession(N):[];for(let t of e)try{let e=await s(t,T,E);if(!e&&j.isAlive(t.pid)){process.emitWarning(`Could not stop runner ${t.id} during session shutdown`);continue}await w.complete(t.id,{reason:b,code:null,signal:e?`SIGTERM`:null,stopReason:`session ended`},t.sessionId)}catch(e){process.emitWarning(`Could not clean up runner ${t.id}: ${String(e)}`)}}finally{M.dispose(),Y.dispose(),I?.hasUI&&I.ui.setStatus(x,void 0),w.close(),await R?.recordEvent(`doom_runner.session_finished`,{outcome:`stopped`}),await R?.shutdown(),R=void 0}})}export{S as runnerExtension};
3
- //# sourceMappingURL=extension.mjs.map
1
+ import{runnerExtension as e}from"./adapters/pi/extension.mjs";export{e as runnerExtension};
@@ -1,2 +1,2 @@
1
- var e=require("../extension.cjs").runnerExtension;module.exports=e;
1
+ var e=require("../adapters/pi/extension.cjs").runnerExtension;module.exports=e;
2
2
  //# sourceMappingURL=pi.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pi.cjs","names":["runnerExtension"],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { runnerExtension } from '../extension.ts';\n\nexport default runnerExtension;\n"],"mappings":"AAEA,IAAA,4BAAeA,CAAAA,CAAAA"}
1
+ {"version":3,"file":"pi.cjs","names":["runnerExtension"],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { runnerExtension } from '../adapters/pi/extension.ts';\n\nexport default runnerExtension;\n"],"mappings":"AAEA,IAAA,wCAAeA,CAAAA,CAAAA"}
@@ -1,2 +1,2 @@
1
- import { runnerExtension } from "../extension.cjs";
1
+ import { runnerExtension } from "../adapters/pi/extension.cjs";
2
2
  export = runnerExtension;
@@ -1,2 +1,2 @@
1
- import { runnerExtension } from "../extension.mjs";
1
+ import { runnerExtension } from "../adapters/pi/extension.mjs";
2
2
  export { runnerExtension as default };
@@ -1,2 +1,2 @@
1
- import{runnerExtension as e}from"../extension.mjs";var t=e;export{t as default};
1
+ import{runnerExtension as e}from"../adapters/pi/extension.mjs";var t=e;export{t as default};
2
2
  //# sourceMappingURL=pi.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pi.mjs","names":[],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { runnerExtension } from '../extension.ts';\n\nexport default runnerExtension;\n"],"mappings":"mDAEA,IAAA,EAAe"}
1
+ {"version":3,"file":"pi.mjs","names":[],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { runnerExtension } from '../adapters/pi/extension.ts';\n\nexport default runnerExtension;\n"],"mappings":"+DAEA,IAAA,EAAe"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./config.cjs"),t=require("./types.cjs"),n=require("./services/RmuxBackend/RmuxBackend.cjs");require("./services/RmuxBackend/index.cjs");const r=require("./container/index.cjs");exports.DEFAULT_BG_THRESHOLD_MS=e.DEFAULT_BG_THRESHOLD_MS,exports.DEFAULT_LOG_MAX_BYTES=e.DEFAULT_LOG_MAX_BYTES,exports.DEFAULT_LOG_TTL_MS=e.DEFAULT_LOG_TTL_MS,exports.DEFAULT_RESULT_MAX_BYTES=e.DEFAULT_RESULT_MAX_BYTES,Object.defineProperty(exports,"RmuxBackend",{enumerable:!0,get:function(){return n.RmuxBackend}}),exports.TYPES=t.TYPES,exports.createRunnerContainer=r.createRunnerContainer,exports.getBackgroundThresholdMs=e.getBackgroundThresholdMs,exports.getLogMaxBytes=e.getLogMaxBytes,exports.getLogTtlMs=e.getLogTtlMs,exports.getResultMaxBytes=e.getResultMaxBytes;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./types/config.cjs"),t=require("./types/index.cjs"),n=require("./services/RmuxBackend/RmuxBackend.cjs");require("./services/RmuxBackend/index.cjs");const r=require("./container/index.cjs");exports.DEFAULT_BG_THRESHOLD_MS=e.DEFAULT_BG_THRESHOLD_MS,exports.DEFAULT_LOG_MAX_BYTES=e.DEFAULT_LOG_MAX_BYTES,exports.DEFAULT_LOG_TTL_MS=e.DEFAULT_LOG_TTL_MS,exports.DEFAULT_RESULT_MAX_BYTES=e.DEFAULT_RESULT_MAX_BYTES,Object.defineProperty(exports,"RmuxBackend",{enumerable:!0,get:function(){return n.RmuxBackend}}),exports.TYPES=t.TYPES,exports.createRunnerContainer=r.createRunnerContainer,exports.getBackgroundThresholdMs=e.getBackgroundThresholdMs,exports.getLogMaxBytes=e.getLogMaxBytes,exports.getLogTtlMs=e.getLogTtlMs,exports.getResultMaxBytes=e.getResultMaxBytes;