@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
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../tool/responseEnvelope.cjs"),t=`Runners`;function n(e){return e>0?`Runners ${e} ●`:void 0}function r(e){return e>0?{fullText:`Runner ${e}`,compactText:`R${e}`}:void 0}function i(t,n){let r=t.interactive?` · tty`:``;return`${t.name} · ${e.formatUptime(t.startedAt,n)}${r} · ${t.command}`}function a(t,n){return t.map(t=>({name:t.name,detail:`pid ${t.pid} · up ${e.formatUptime(t.startedAt,n)} · ${t.command}`,interactive:t.interactive}))}function o(e){return`${t} (${e})`}exports.OVERLAY_HEADING=t,exports.WIDGET_KEY=`doom-runners`,exports.formatRunnerFooterContribution=r,exports.formatRunnerStatus=n,exports.formatWidgetHeading=o,exports.formatWidgetLine=i,exports.toRunnerRows=a;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../commands/bash/responseEnvelope.cjs"),t=`Runners`;function n(e){return e>0?`Runners ${e} ●`:void 0}function r(e){return e>0?{fullText:`Runner ${e}`,compactText:`R${e}`}:void 0}function i(t,n){let r=t.interactive?` · tty`:``;return`${t.name} · ${e.formatUptime(t.startedAt,n)}${r} · ${t.command}`}function a(t,n){return t.map(t=>({name:t.name,detail:`pid ${t.pid} · up ${e.formatUptime(t.startedAt,n)} · ${t.command}`,interactive:t.interactive}))}function o(e){return`${t} (${e})`}exports.OVERLAY_HEADING=t,exports.WIDGET_KEY=`doom-runners`,exports.formatRunnerFooterContribution=r,exports.formatRunnerStatus=n,exports.formatWidgetHeading=o,exports.formatWidgetLine=i,exports.toRunnerRows=a;
2
2
  //# sourceMappingURL=format.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"format.cjs","names":["formatUptime"],"sources":["../../src/tui/format.ts"],"sourcesContent":["import type { RunnerRecord } from '../services/RunnerRegistry/index.ts';\nimport { formatUptime } from '../tool/responseEnvelope.ts';\n\nexport const WIDGET_KEY = 'doom-runners';\nexport const OVERLAY_HEADING = 'Runners';\n\n/** Compact footer text. An absent value removes the group entirely. */\nexport function formatRunnerStatus(count: number): string | undefined {\n return count > 0 ? `Runners ${count} ●` : undefined;\n}\n\nexport function formatRunnerFooterContribution(count: number): { fullText: string; compactText: string } | undefined {\n return count > 0 ? { fullText: `Runner ${count}`, compactText: `R${count}` } : undefined;\n}\n\n/** `api · 3m · nx dev-start api` — the widget's per-runner line. */\nexport function formatWidgetLine(record: RunnerRecord, now: number): string {\n const mode = record.interactive ? ' · tty' : '';\n return `${record.name} · ${formatUptime(record.startedAt, now)}${mode} · ${record.command}`;\n}\n\nexport interface RunnerRow {\n name: string;\n detail: string;\n interactive: boolean;\n}\n\n/** Rows for the Runner Space list, as plain values so they can be asserted as text. */\nexport function toRunnerRows(records: readonly RunnerRecord[], now: number): RunnerRow[] {\n return records.map((record) => ({\n name: record.name,\n detail: `pid ${record.pid} · up ${formatUptime(record.startedAt, now)} · ${record.command}`,\n interactive: record.interactive,\n }));\n}\n\n/** Heading text for the widget, hidden entirely when there is nothing running. */\nexport function formatWidgetHeading(count: number): string {\n return `${OVERLAY_HEADING} (${count})`;\n}\n"],"mappings":"mHAIa,EAAkB,UAG/B,SAAgB,EAAmB,EAAmC,CACpE,OAAO,EAAQ,EAAI,WAAW,EAAM,IAAM,IAAA,EAC5C,CAEA,SAAgB,EAA+B,EAAsE,CACnH,OAAO,EAAQ,EAAI,CAAE,SAAU,UAAU,IAAS,YAAa,IAAI,GAAQ,EAAI,IAAA,EACjF,CAGA,SAAgB,EAAiB,EAAsB,EAAqB,CAC1E,IAAM,EAAO,EAAO,YAAc,SAAW,GAC7C,MAAO,GAAG,EAAO,KAAK,KAAKA,EAAAA,aAAa,EAAO,UAAW,CAAG,IAAI,EAAK,KAAK,EAAO,SACpF,CASA,SAAgB,EAAa,EAAkC,EAA0B,CACvF,OAAO,EAAQ,IAAK,IAAY,CAC9B,KAAM,EAAO,KACb,OAAQ,OAAO,EAAO,IAAI,QAAQA,EAAAA,aAAa,EAAO,UAAW,CAAG,EAAE,KAAK,EAAO,UAClF,YAAa,EAAO,WACtB,EAAE,CACJ,CAGA,SAAgB,EAAoB,EAAuB,CACzD,MAAO,GAAG,EAAgB,IAAI,EAAM,EACtC"}
1
+ {"version":3,"file":"format.cjs","names":["formatUptime"],"sources":["../../src/tui/format.ts"],"sourcesContent":["import { formatUptime } from '../commands/bash/responseEnvelope.ts';\nimport type { RunnerRecord } from '../services/RunnerRegistry/index.ts';\n\nexport const WIDGET_KEY = 'doom-runners';\nexport const OVERLAY_HEADING = 'Runners';\n\n/** Compact footer text. An absent value removes the group entirely. */\nexport function formatRunnerStatus(count: number): string | undefined {\n return count > 0 ? `Runners ${count} ●` : undefined;\n}\n\nexport function formatRunnerFooterContribution(count: number): { fullText: string; compactText: string } | undefined {\n return count > 0 ? { fullText: `Runner ${count}`, compactText: `R${count}` } : undefined;\n}\n\n/** `api · 3m · nx dev-start api` — the widget's per-runner line. */\nexport function formatWidgetLine(record: RunnerRecord, now: number): string {\n const mode = record.interactive ? ' · tty' : '';\n return `${record.name} · ${formatUptime(record.startedAt, now)}${mode} · ${record.command}`;\n}\n\nexport interface RunnerRow {\n name: string;\n detail: string;\n interactive: boolean;\n}\n\n/** Rows for the Runner Space list, as plain values so they can be asserted as text. */\nexport function toRunnerRows(records: readonly RunnerRecord[], now: number): RunnerRow[] {\n return records.map((record) => ({\n name: record.name,\n detail: `pid ${record.pid} · up ${formatUptime(record.startedAt, now)} · ${record.command}`,\n interactive: record.interactive,\n }));\n}\n\n/** Heading text for the widget, hidden entirely when there is nothing running. */\nexport function formatWidgetHeading(count: number): string {\n return `${OVERLAY_HEADING} (${count})`;\n}\n"],"mappings":"4HAIa,EAAkB,UAG/B,SAAgB,EAAmB,EAAmC,CACpE,OAAO,EAAQ,EAAI,WAAW,EAAM,IAAM,IAAA,EAC5C,CAEA,SAAgB,EAA+B,EAAsE,CACnH,OAAO,EAAQ,EAAI,CAAE,SAAU,UAAU,IAAS,YAAa,IAAI,GAAQ,EAAI,IAAA,EACjF,CAGA,SAAgB,EAAiB,EAAsB,EAAqB,CAC1E,IAAM,EAAO,EAAO,YAAc,SAAW,GAC7C,MAAO,GAAG,EAAO,KAAK,KAAKA,EAAAA,aAAa,EAAO,UAAW,CAAG,IAAI,EAAK,KAAK,EAAO,SACpF,CASA,SAAgB,EAAa,EAAkC,EAA0B,CACvF,OAAO,EAAQ,IAAK,IAAY,CAC9B,KAAM,EAAO,KACb,OAAQ,OAAO,EAAO,IAAI,QAAQA,EAAAA,aAAa,EAAO,UAAW,CAAG,EAAE,KAAK,EAAO,UAClF,YAAa,EAAO,WACtB,EAAE,CACJ,CAGA,SAAgB,EAAoB,EAAuB,CACzD,MAAO,GAAG,EAAgB,IAAI,EAAM,EACtC"}
@@ -1,2 +1,2 @@
1
- import{formatUptime as e}from"../tool/responseEnvelope.mjs";const t=`doom-runners`,n=`Runners`;function r(e){return e>0?`Runners ${e} ●`:void 0}function i(e){return e>0?{fullText:`Runner ${e}`,compactText:`R${e}`}:void 0}function a(t,n){let r=t.interactive?` · tty`:``;return`${t.name} · ${e(t.startedAt,n)}${r} · ${t.command}`}function o(t,n){return t.map(t=>({name:t.name,detail:`pid ${t.pid} · up ${e(t.startedAt,n)} · ${t.command}`,interactive:t.interactive}))}function s(e){return`${n} (${e})`}export{n as OVERLAY_HEADING,t as WIDGET_KEY,i as formatRunnerFooterContribution,r as formatRunnerStatus,s as formatWidgetHeading,a as formatWidgetLine,o as toRunnerRows};
1
+ import{formatUptime as e}from"../commands/bash/responseEnvelope.mjs";const t=`doom-runners`,n=`Runners`;function r(e){return e>0?`Runners ${e} ●`:void 0}function i(e){return e>0?{fullText:`Runner ${e}`,compactText:`R${e}`}:void 0}function a(t,n){let r=t.interactive?` · tty`:``;return`${t.name} · ${e(t.startedAt,n)}${r} · ${t.command}`}function o(t,n){return t.map(t=>({name:t.name,detail:`pid ${t.pid} · up ${e(t.startedAt,n)} · ${t.command}`,interactive:t.interactive}))}function s(e){return`${n} (${e})`}export{n as OVERLAY_HEADING,t as WIDGET_KEY,i as formatRunnerFooterContribution,r as formatRunnerStatus,s as formatWidgetHeading,a as formatWidgetLine,o as toRunnerRows};
2
2
  //# sourceMappingURL=format.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"format.mjs","names":[],"sources":["../../src/tui/format.ts"],"sourcesContent":["import type { RunnerRecord } from '../services/RunnerRegistry/index.ts';\nimport { formatUptime } from '../tool/responseEnvelope.ts';\n\nexport const WIDGET_KEY = 'doom-runners';\nexport const OVERLAY_HEADING = 'Runners';\n\n/** Compact footer text. An absent value removes the group entirely. */\nexport function formatRunnerStatus(count: number): string | undefined {\n return count > 0 ? `Runners ${count} ●` : undefined;\n}\n\nexport function formatRunnerFooterContribution(count: number): { fullText: string; compactText: string } | undefined {\n return count > 0 ? { fullText: `Runner ${count}`, compactText: `R${count}` } : undefined;\n}\n\n/** `api · 3m · nx dev-start api` — the widget's per-runner line. */\nexport function formatWidgetLine(record: RunnerRecord, now: number): string {\n const mode = record.interactive ? ' · tty' : '';\n return `${record.name} · ${formatUptime(record.startedAt, now)}${mode} · ${record.command}`;\n}\n\nexport interface RunnerRow {\n name: string;\n detail: string;\n interactive: boolean;\n}\n\n/** Rows for the Runner Space list, as plain values so they can be asserted as text. */\nexport function toRunnerRows(records: readonly RunnerRecord[], now: number): RunnerRow[] {\n return records.map((record) => ({\n name: record.name,\n detail: `pid ${record.pid} · up ${formatUptime(record.startedAt, now)} · ${record.command}`,\n interactive: record.interactive,\n }));\n}\n\n/** Heading text for the widget, hidden entirely when there is nothing running. */\nexport function formatWidgetHeading(count: number): string {\n return `${OVERLAY_HEADING} (${count})`;\n}\n"],"mappings":"4DAGA,MAAa,EAAa,eACb,EAAkB,UAG/B,SAAgB,EAAmB,EAAmC,CACpE,OAAO,EAAQ,EAAI,WAAW,EAAM,IAAM,IAAA,EAC5C,CAEA,SAAgB,EAA+B,EAAsE,CACnH,OAAO,EAAQ,EAAI,CAAE,SAAU,UAAU,IAAS,YAAa,IAAI,GAAQ,EAAI,IAAA,EACjF,CAGA,SAAgB,EAAiB,EAAsB,EAAqB,CAC1E,IAAM,EAAO,EAAO,YAAc,SAAW,GAC7C,MAAO,GAAG,EAAO,KAAK,KAAK,EAAa,EAAO,UAAW,CAAG,IAAI,EAAK,KAAK,EAAO,SACpF,CASA,SAAgB,EAAa,EAAkC,EAA0B,CACvF,OAAO,EAAQ,IAAK,IAAY,CAC9B,KAAM,EAAO,KACb,OAAQ,OAAO,EAAO,IAAI,QAAQ,EAAa,EAAO,UAAW,CAAG,EAAE,KAAK,EAAO,UAClF,YAAa,EAAO,WACtB,EAAE,CACJ,CAGA,SAAgB,EAAoB,EAAuB,CACzD,MAAO,GAAG,EAAgB,IAAI,EAAM,EACtC"}
1
+ {"version":3,"file":"format.mjs","names":[],"sources":["../../src/tui/format.ts"],"sourcesContent":["import { formatUptime } from '../commands/bash/responseEnvelope.ts';\nimport type { RunnerRecord } from '../services/RunnerRegistry/index.ts';\n\nexport const WIDGET_KEY = 'doom-runners';\nexport const OVERLAY_HEADING = 'Runners';\n\n/** Compact footer text. An absent value removes the group entirely. */\nexport function formatRunnerStatus(count: number): string | undefined {\n return count > 0 ? `Runners ${count} ●` : undefined;\n}\n\nexport function formatRunnerFooterContribution(count: number): { fullText: string; compactText: string } | undefined {\n return count > 0 ? { fullText: `Runner ${count}`, compactText: `R${count}` } : undefined;\n}\n\n/** `api · 3m · nx dev-start api` — the widget's per-runner line. */\nexport function formatWidgetLine(record: RunnerRecord, now: number): string {\n const mode = record.interactive ? ' · tty' : '';\n return `${record.name} · ${formatUptime(record.startedAt, now)}${mode} · ${record.command}`;\n}\n\nexport interface RunnerRow {\n name: string;\n detail: string;\n interactive: boolean;\n}\n\n/** Rows for the Runner Space list, as plain values so they can be asserted as text. */\nexport function toRunnerRows(records: readonly RunnerRecord[], now: number): RunnerRow[] {\n return records.map((record) => ({\n name: record.name,\n detail: `pid ${record.pid} · up ${formatUptime(record.startedAt, now)} · ${record.command}`,\n interactive: record.interactive,\n }));\n}\n\n/** Heading text for the widget, hidden entirely when there is nothing running. */\nexport function formatWidgetHeading(count: number): string {\n return `${OVERLAY_HEADING} (${count})`;\n}\n"],"mappings":"qEAGA,MAAa,EAAa,eACb,EAAkB,UAG/B,SAAgB,EAAmB,EAAmC,CACpE,OAAO,EAAQ,EAAI,WAAW,EAAM,IAAM,IAAA,EAC5C,CAEA,SAAgB,EAA+B,EAAsE,CACnH,OAAO,EAAQ,EAAI,CAAE,SAAU,UAAU,IAAS,YAAa,IAAI,GAAQ,EAAI,IAAA,EACjF,CAGA,SAAgB,EAAiB,EAAsB,EAAqB,CAC1E,IAAM,EAAO,EAAO,YAAc,SAAW,GAC7C,MAAO,GAAG,EAAO,KAAK,KAAK,EAAa,EAAO,UAAW,CAAG,IAAI,EAAK,KAAK,EAAO,SACpF,CASA,SAAgB,EAAa,EAAkC,EAA0B,CACvF,OAAO,EAAQ,IAAK,IAAY,CAC9B,KAAM,EAAO,KACb,OAAQ,OAAO,EAAO,IAAI,QAAQ,EAAa,EAAO,UAAW,CAAG,EAAE,KAAK,EAAO,UAClF,YAAa,EAAO,WACtB,EAAE,CACJ,CAGA,SAAgB,EAAoB,EAAuB,CACzD,MAAO,GAAG,EAAgB,IAAI,EAAM,EACtC"}
@@ -1,6 +1,6 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./format.cjs");let t=require("@earendil-works/pi-tui"),n=require("@agimon-ai/doompi-ui/components/doomOverlay");const r=n.DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions;var i=class extends n.DoomOverlay{options;done;selected=0;attached;viewedLog;unsubscribe;logRefresh;notice;stopReason;constructor(e,t,n,r){super(e,t),this.options=n,this.done=r}handleInput(e){if(this.stopReason){this.handleStopReasonInput(e);return}if(this.attached){this.handleAttachedInput(e);return}if(this.viewedLog){(0,t.matchesKey)(e,`escape`)&&this.detach();return}this.handleListInput(e)}getChrome(){let e=this.options.getRunners();return{title:`RUNNER SPACE`,accent:n.DOOM_OVERLAY_ACCENT,breadcrumb:`SPC › r / runners › r / runner space`,headerRight:this.attached?`attached · ${this.attached.name}`:this.viewedLog?`logs · ${this.viewedLog.name}`:`${e.length} runners · this worktree`,footer:this.attached?`esc back · everything else goes to the runner`:this.viewedLog?`esc back · live stdout/stderr`:`↑↓/jk select · enter open · s stop · r reason · esc close`,footerHints:this.attached||this.viewedLog?void 0:[[`↑↓/jk`,`select`],[`enter`,`open`],[`s`,`stop`],[`r`,`reason`],[`esc`,`close`]],footerRight:this.attached?`live tty`:this.viewedLog?`live log`:e.length>0?`${Math.min(this.selected,e.length-1)+1}/${e.length}`:`empty`}}renderBody(e,n){let r=n=>(0,t.truncateToWidth)(n,e,`…`);return this.attached?this.renderAttached(r,n):this.viewedLog?this.renderLog(r,n):this.renderList(r,n)}handleAttachedInput(e){if((0,t.matchesKey)(e,`escape`)){this.detach();return}this.attached?.write(e)}handleListInput(e){let n=this.options.getRunners();if((0,t.matchesKey)(e,`escape`)||(0,t.matchesKey)(e,`ctrl+c`)){this.close();return}(0,t.matchesKey)(e,`up`)||e===`k`?this.move(-1,n.length):(0,t.matchesKey)(e,`down`)||e===`j`?this.move(1,n.length):e===`\r`||e===`
2
- `?this.attach(n):e===`s`?this.stop(n):e===`r`&&this.promptStopReason(n)}move(e,t){t!==0&&(this.selected=Math.max(0,Math.min(t-1,this.selected+e)),this.notice=void 0,this.tui.requestRender())}current(e){if(e.length!==0)return e[Math.min(this.selected,e.length-1)]}attach(e){let t=this.current(e);if(!t)return;let n=t.interactive?this.options.getPtyRun(t.name):void 0;this.notice=void 0,n?(this.attached=n,this.unsubscribe=n.onData(()=>this.tui.requestRender())):(this.viewedLog=t,this.logRefresh=setInterval(()=>this.tui.requestRender(!0),250),this.logRefresh.unref?.()),this.tui.requestRender(!0)}detach(){this.unsubscribe?.(),this.unsubscribe=void 0,this.logRefresh&&clearInterval(this.logRefresh),this.logRefresh=void 0,this.attached=void 0,this.viewedLog=void 0,this.tui.requestRender(!0)}stop(e){let t=this.current(e);t&&this.options.stopRunner(t.id).then(()=>{this.notice=`Stopped ${t.name}`,this.tui.requestRender(!0)}).catch(e=>{this.notice=e instanceof Error?e.message:String(e),this.tui.requestRender()})}promptStopReason(e){let t=this.current(e);t&&(this.stopReason={runner:t,text:``},this.tui.requestRender())}handleStopReasonInput(e){let n=this.stopReason;if(n){if((0,t.matchesKey)(e,`escape`)||(0,t.matchesKey)(e,`ctrl+c`)){this.stopReason=void 0,this.tui.requestRender();return}if(e===`\r`||e===`
3
- `){this.stopReason=void 0,this.options.stopRunner(n.runner.id,n.text.trim()||void 0).then(()=>{this.notice=`Stopped ${n.runner.name}`,this.tui.requestRender(!0)}).catch(e=>{this.notice=e instanceof Error?e.message:String(e),this.tui.requestRender()});return}(0,t.matchesKey)(e,`backspace`)?n.text=n.text.slice(0,-1):e.includes(`\x1B`)||(n.text+=e),this.tui.requestRender()}}close(){this.detach(),this.done(void 0)}renderList(t,n){let r=this.options.getRunners(),i=e.toRunnerRows(r,Date.now()),a=[];if(this.stopReason)return[t(`Stop reason for ${this.stopReason.runner.name}: ${this.stopReason.text}`)];if(i.length===0)a.push(t(this.theme.fg(`dim`,`No background runners. bash backgrounds anything that outlives the threshold.`)));else{let e=this.notice?2:0,r=Math.max(1,n-e),o=Math.max(0,i.length-r),s=Math.min(o,Math.max(0,this.selected-r+1));i.slice(s,s+r).forEach((e,n)=>{let r=s+n===Math.min(this.selected,i.length-1)?`›`:` `,o=e.interactive?` [tty]`:``;a.push(t(`${r} ${e.name}${o} ${this.theme.fg(`dim`,e.detail)}`))})}return this.notice&&a.push(``,t(this.theme.fg(`warning`,this.notice))),a.slice(0,n)}renderAttached(e,t){let n=this.attached;return n?n.screen().split(`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./format.cjs");let t=require("@earendil-works/pi-tui"),n=require("@agimon-ai/doompi-ui/components/doomOverlay");const r=n.DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions,i=`${n.DOOM_NAVIGATION_KEYS.list} select · enter open · s stop · r reason · esc close`;var a=class extends n.DoomOverlay{options;done;selected=0;attached;viewedLog;unsubscribe;logRefresh;notice;stopReason;constructor(e,t,n,r){super(e,t),this.options=n,this.done=r}handleInput(e){if(this.stopReason){this.handleStopReasonInput(e);return}if(this.attached){this.handleAttachedInput(e);return}if(this.viewedLog){(0,t.matchesKey)(e,`escape`)&&this.detach();return}this.handleListInput(e)}getChrome(){let e=this.options.getRunners();return{title:`RUNNER SPACE`,accent:n.DOOM_OVERLAY_ACCENT,breadcrumb:`SPC › r / runners › r / runner space`,headerRight:this.attached?`attached · ${this.attached.name}`:this.viewedLog?`logs · ${this.viewedLog.name}`:`${e.length} runners · this worktree`,footer:this.attached?`esc back · everything else goes to the runner`:this.viewedLog?`esc back · live stdout/stderr`:i,footerHints:this.attached||this.viewedLog?void 0:[[n.DOOM_NAVIGATION_KEYS.list,`select`],[`enter`,`open`],[`s`,`stop`],[`r`,`reason`],[`esc`,`close`]],footerRight:this.attached?`live tty`:this.viewedLog?`live log`:e.length>0?`${Math.min(this.selected,e.length-1)+1}/${e.length}`:`empty`}}renderBody(e,n){let r=n=>(0,t.truncateToWidth)(n,e,`…`);return this.attached?this.renderAttached(r,n):this.viewedLog?this.renderLog(r,n):this.renderList(r,n)}handleAttachedInput(e){if((0,t.matchesKey)(e,`escape`)){this.detach();return}this.attached?.write(e)}handleListInput(e){let n=this.options.getRunners();if((0,t.matchesKey)(e,`escape`)||(0,t.matchesKey)(e,`ctrl+c`)){this.close();return}(0,t.matchesKey)(e,`up`)||e===`k`?this.move(-1,n.length):(0,t.matchesKey)(e,`down`)||e===`j`?this.move(1,n.length):e===`\r`||e===`
2
+ `?this.attach(n):e===`s`?this.stop(n):e===`r`&&this.promptStopReason(n)}move(e,t){t!==0&&(this.selected=Math.max(0,Math.min(t-1,this.selected+e)),this.notice=void 0,this.tui.requestRender())}current(e){if(e.length!==0)return e[Math.min(this.selected,e.length-1)]}attach(e){let t=this.current(e);if(!t)return;let n=t.interactive?this.options.getPtyRun(t.name):void 0;this.notice=void 0,n?(this.attached=n,this.unsubscribe=n.onData(()=>this.tui.requestRender())):(this.viewedLog=t,this.logRefresh=setInterval(()=>this.tui.requestRender(!0),250),this.logRefresh.unref?.()),this.tui.requestRender(!0)}detach(){this.unsubscribe?.(),this.unsubscribe=void 0,this.logRefresh&&clearInterval(this.logRefresh),this.logRefresh=void 0,this.attached=void 0,this.viewedLog=void 0,this.tui.requestRender(!0)}stop(e){let t=this.current(e);t&&this.options.stopRunner(t.id).then(()=>{this.notice={text:`Stopped ${t.name}`,color:`success`},this.tui.requestRender(!0)}).catch(e=>{this.notice={text:e instanceof Error?e.message:String(e),color:`error`},this.tui.requestRender()})}promptStopReason(e){let t=this.current(e);t&&(this.stopReason={runner:t,text:``},this.tui.requestRender())}handleStopReasonInput(e){let n=this.stopReason;if(n){if((0,t.matchesKey)(e,`escape`)||(0,t.matchesKey)(e,`ctrl+c`)){this.stopReason=void 0,this.tui.requestRender();return}if(e===`\r`||e===`
3
+ `){this.stopReason=void 0,this.options.stopRunner(n.runner.id,n.text.trim()||void 0).then(()=>{this.notice={text:`Stopped ${n.runner.name}`,color:`success`},this.tui.requestRender(!0)}).catch(e=>{this.notice={text:e instanceof Error?e.message:String(e),color:`error`},this.tui.requestRender()});return}(0,t.matchesKey)(e,`backspace`)?n.text=n.text.slice(0,-1):e.includes(`\x1B`)||(n.text+=e),this.tui.requestRender()}}close(){this.detach(),this.done(void 0)}renderList(t,n){let r=this.options.getRunners(),i=e.toRunnerRows(r,Date.now()),a=[];if(this.stopReason)return[t(`Stop reason for ${this.stopReason.runner.name}: ${this.stopReason.text}`)];if(i.length===0)a.push(t(this.theme.fg(`dim`,`No background runners. bash backgrounds anything that outlives the threshold.`)));else{let e=this.notice?2:0,r=Math.max(1,n-e),o=Math.max(0,i.length-r),s=Math.min(o,Math.max(0,this.selected-r+1));i.slice(s,s+r).forEach((e,n)=>{let r=s+n===Math.min(this.selected,i.length-1)?`›`:` `,o=e.interactive?` [tty]`:``;a.push(t(`${r} ${e.name}${o} ${this.theme.fg(`dim`,e.detail)}`))})}return this.notice&&a.push(``,t(this.theme.fg(this.notice.color,this.notice.text))),a.slice(0,n)}renderAttached(e,t){let n=this.attached;return n?n.screen().split(`
4
4
  `).slice(-t).map(e):[]}renderLog(e,t){let n=this.viewedLog;if(!n)return[];let r=this.options.readLog(n.logPath);return r?r.split(`
5
- `).slice(-t).map(e):[e(this.theme.fg(`dim`,`Waiting for output…`))]}};async function a(e,t){await e.ui.custom((e,n,r,a)=>new i(e,n,t,a),n.DOOM_FULLSCREEN_UI_OPTIONS)}exports.RUNNER_SPACE_OVERLAY_OPTIONS=r,exports.RunnerSpaceComponent=i,exports.openRunnerSpace=a;
5
+ `).slice(-t).map(e):[e(this.theme.fg(`dim`,`Waiting for output…`))]}};async function o(e,t){await e.ui.custom((e,n,r,i)=>new a(e,n,t,i),n.DOOM_FULLSCREEN_UI_OPTIONS)}exports.RUNNER_SPACE_OVERLAY_OPTIONS=r,exports.RunnerSpaceComponent=a,exports.openRunnerSpace=o;
6
6
  //# sourceMappingURL=runnerSpace.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"runnerSpace.cjs","names":["DOOM_FULLSCREEN_UI_OPTIONS","DoomOverlay","matchesKey","DOOM_OVERLAY_ACCENT","truncateToWidth","toRunnerRows"],"sources":["../../src/tui/runnerSpace.ts"],"sourcesContent":["/**\n * Runner Space: the `SPC r r` overlay.\n *\n * Two modes behind one component. The list shows every runner in this worktree\n * and can stop them; attaching to an interactive runner renders its live\n * terminal and forwards keystrokes to it, which is the whole reason PTY runs\n * exist. Rendering is pure, so the surface can be asserted as text.\n */\n\nimport type { ExtensionContext, Theme } from '@earendil-works/pi-coding-agent';\nimport {\n DOOM_OVERLAY_ACCENT,\n DoomOverlay,\n type DoomOverlayChrome,\n type DoomOverlayTui,\n DOOM_FULLSCREEN_UI_OPTIONS,\n} from '@agimon-ai/doompi-ui/components/doomOverlay';\nimport { matchesKey, truncateToWidth } from '@earendil-works/pi-tui';\nimport type { PtyRun } from '../services/PtyHost/index.ts';\nimport type { RunnerRecord } from '../services/RunnerRegistry/index.ts';\nimport { toRunnerRows } from './format.ts';\n\nexport const RUNNER_SPACE_OVERLAY_OPTIONS = DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions;\n\nconst KEY_ENTER = '\\r';\nconst KEY_NEWLINE = '\\n';\nconst TITLE = 'RUNNER SPACE';\nconst EMPTY_MESSAGE = 'No background runners. bash backgrounds anything that outlives the threshold.';\nconst LIST_FOOTER = '↑↓/jk select · enter open · s stop · r reason · esc close';\nconst ATTACH_FOOTER = 'esc back · everything else goes to the runner';\nconst LOG_FOOTER = 'esc back · live stdout/stderr';\nconst LOG_REFRESH_MS = 250;\nconst ELLIPSIS = '…';\n\nexport interface RunnerSpaceOptions {\n getRunners: () => readonly RunnerRecord[];\n /** The hosted terminal for a runner, when this session owns one. */\n getPtyRun: (name: string) => PtyRun | undefined;\n readLog: (logPath: string) => string;\n stopRunner: (id: string, reason?: string) => Promise<void>;\n}\n\nexport class RunnerSpaceComponent extends DoomOverlay {\n private selected = 0;\n private attached: PtyRun | undefined;\n private viewedLog: RunnerRecord | undefined;\n private unsubscribe: (() => void) | undefined;\n private logRefresh: ReturnType<typeof setInterval> | undefined;\n private notice: string | undefined;\n private stopReason: { runner: RunnerRecord; text: string } | undefined;\n\n constructor(\n tui: DoomOverlayTui,\n theme: Theme,\n private readonly options: RunnerSpaceOptions,\n private readonly done: (result: undefined) => void,\n ) {\n super(tui, theme);\n }\n\n handleInput(data: string): void {\n if (this.stopReason) {\n this.handleStopReasonInput(data);\n return;\n }\n if (this.attached) {\n this.handleAttachedInput(data);\n return;\n }\n if (this.viewedLog) {\n if (matchesKey(data, 'escape')) this.detach();\n return;\n }\n this.handleListInput(data);\n }\n\n protected getChrome(): DoomOverlayChrome {\n const runners = this.options.getRunners();\n return {\n title: TITLE,\n accent: DOOM_OVERLAY_ACCENT,\n breadcrumb: 'SPC › r / runners › r / runner space',\n headerRight: this.attached\n ? `attached · ${this.attached.name}`\n : this.viewedLog\n ? `logs · ${this.viewedLog.name}`\n : `${runners.length} runners · this worktree`,\n footer: this.attached ? ATTACH_FOOTER : this.viewedLog ? LOG_FOOTER : LIST_FOOTER,\n footerHints:\n this.attached || this.viewedLog\n ? undefined\n : [\n ['↑↓/jk', 'select'],\n ['enter', 'open'],\n ['s', 'stop'],\n ['r', 'reason'],\n ['esc', 'close'],\n ],\n footerRight: this.attached\n ? 'live tty'\n : this.viewedLog\n ? 'live log'\n : runners.length > 0\n ? `${Math.min(this.selected, runners.length - 1) + 1}/${runners.length}`\n : 'empty',\n };\n }\n\n protected renderBody(width: number, height: number): string[] {\n const truncate = (line: string): string => truncateToWidth(line, width, ELLIPSIS);\n if (this.attached) return this.renderAttached(truncate, height);\n if (this.viewedLog) return this.renderLog(truncate, height);\n return this.renderList(truncate, height);\n }\n\n private handleAttachedInput(data: string): void {\n if (matchesKey(data, 'escape')) {\n this.detach();\n return;\n }\n this.attached?.write(data);\n }\n\n private handleListInput(data: string): void {\n const runners = this.options.getRunners();\n\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c')) {\n this.close();\n return;\n }\n if (matchesKey(data, 'up') || data === 'k') this.move(-1, runners.length);\n else if (matchesKey(data, 'down') || data === 'j') this.move(1, runners.length);\n else if (data === KEY_ENTER || data === KEY_NEWLINE) this.attach(runners);\n else if (data === 's') this.stop(runners);\n else if (data === 'r') this.promptStopReason(runners);\n }\n\n private move(delta: number, count: number): void {\n if (count === 0) return;\n this.selected = Math.max(0, Math.min(count - 1, this.selected + delta));\n this.notice = undefined;\n this.tui.requestRender();\n }\n\n private current(runners: readonly RunnerRecord[]): RunnerRecord | undefined {\n if (runners.length === 0) return undefined;\n return runners[Math.min(this.selected, runners.length - 1)];\n }\n\n private attach(runners: readonly RunnerRecord[]): void {\n const record = this.current(runners);\n if (!record) return;\n\n const run = record.interactive ? this.options.getPtyRun(record.name) : undefined;\n this.notice = undefined;\n if (run) {\n this.attached = run;\n this.unsubscribe = run.onData(() => this.tui.requestRender());\n } else {\n this.viewedLog = record;\n this.logRefresh = setInterval(() => this.tui.requestRender(true), LOG_REFRESH_MS);\n this.logRefresh.unref?.();\n }\n this.tui.requestRender(true);\n }\n\n private detach(): void {\n this.unsubscribe?.();\n this.unsubscribe = undefined;\n if (this.logRefresh) clearInterval(this.logRefresh);\n this.logRefresh = undefined;\n this.attached = undefined;\n this.viewedLog = undefined;\n this.tui.requestRender(true);\n }\n\n private stop(runners: readonly RunnerRecord[]): void {\n const record = this.current(runners);\n if (!record) return;\n\n this.options\n .stopRunner(record.id)\n .then(() => {\n this.notice = `Stopped ${record.name}`;\n this.tui.requestRender(true);\n })\n .catch((error: unknown) => {\n // Shown rather than swallowed: a failed stop means the process is still\n // running and the operator needs to know.\n this.notice = error instanceof Error ? error.message : String(error);\n this.tui.requestRender();\n });\n }\n\n private promptStopReason(runners: readonly RunnerRecord[]): void {\n const runner = this.current(runners);\n if (!runner) return;\n this.stopReason = { runner, text: '' };\n this.tui.requestRender();\n }\n\n private handleStopReasonInput(data: string): void {\n const prompt = this.stopReason;\n if (!prompt) return;\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c')) {\n this.stopReason = undefined;\n this.tui.requestRender();\n return;\n }\n if (data === KEY_ENTER || data === KEY_NEWLINE) {\n this.stopReason = undefined;\n this.options\n .stopRunner(prompt.runner.id, prompt.text.trim() || undefined)\n .then(() => {\n this.notice = `Stopped ${prompt.runner.name}`;\n this.tui.requestRender(true);\n })\n .catch((error: unknown) => {\n this.notice = error instanceof Error ? error.message : String(error);\n this.tui.requestRender();\n });\n return;\n }\n if (matchesKey(data, 'backspace')) prompt.text = prompt.text.slice(0, -1);\n else if (!data.includes('\\u001b')) prompt.text += data;\n this.tui.requestRender();\n }\n\n private close(): void {\n this.detach();\n this.done(undefined);\n }\n\n private renderList(truncate: (line: string) => string, height: number): string[] {\n const runners = this.options.getRunners();\n const rows = toRunnerRows(runners, Date.now());\n const lines: string[] = [];\n\n if (this.stopReason) {\n return [truncate(`Stop reason for ${this.stopReason.runner.name}: ${this.stopReason.text}`)];\n }\n\n if (rows.length === 0) lines.push(truncate(this.theme.fg('dim', EMPTY_MESSAGE)));\n else {\n const noticeRows = this.notice ? 2 : 0;\n const capacity = Math.max(1, height - noticeRows);\n const maxStart = Math.max(0, rows.length - capacity);\n const start = Math.min(maxStart, Math.max(0, this.selected - capacity + 1));\n rows.slice(start, start + capacity).forEach((row, offset) => {\n const index = start + offset;\n const marker = index === Math.min(this.selected, rows.length - 1) ? '›' : ' ';\n const tty = row.interactive ? ' [tty]' : '';\n lines.push(truncate(`${marker} ${row.name}${tty} ${this.theme.fg('dim', row.detail)}`));\n });\n }\n\n if (this.notice) lines.push('', truncate(this.theme.fg('warning', this.notice)));\n return lines.slice(0, height);\n }\n\n private renderAttached(truncate: (line: string) => string, height: number): string[] {\n const run = this.attached;\n if (!run) return [];\n\n return run.screen().split('\\n').slice(-height).map(truncate);\n }\n\n private renderLog(truncate: (line: string) => string, height: number): string[] {\n const record = this.viewedLog;\n if (!record) return [];\n\n const text = this.options.readLog(record.logPath);\n if (!text) return [truncate(this.theme.fg('dim', 'Waiting for output…'))];\n return text.split('\\n').slice(-height).map(truncate);\n }\n}\n\nexport async function openRunnerSpace(ctx: ExtensionContext, options: RunnerSpaceOptions): Promise<void> {\n await ctx.ui.custom<undefined>(\n (tui, theme, _keybindings, done) => new RunnerSpaceComponent(tui, theme, options, done),\n DOOM_FULLSCREEN_UI_OPTIONS,\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"runnerSpace.cjs","names":["DOOM_FULLSCREEN_UI_OPTIONS","DOOM_NAVIGATION_KEYS","DoomOverlay","matchesKey","DOOM_OVERLAY_ACCENT","truncateToWidth","toRunnerRows"],"sources":["../../src/tui/runnerSpace.ts"],"sourcesContent":["/**\n * Runner Space: the `SPC r r` overlay.\n *\n * Two modes behind one component. The list shows every runner in this worktree\n * and can stop them; attaching to an interactive runner renders its live\n * terminal and forwards keystrokes to it, which is the whole reason PTY runs\n * exist. Rendering is pure, so the surface can be asserted as text.\n */\n\nimport {\n DOOM_FULLSCREEN_UI_OPTIONS,\n DOOM_NAVIGATION_KEYS,\n DOOM_OVERLAY_ACCENT,\n DoomOverlay,\n type DoomOverlayChrome,\n type DoomOverlayTui,\n} from '@agimon-ai/doompi-ui/components/doomOverlay';\nimport type { ExtensionContext, Theme } from '@earendil-works/pi-coding-agent';\nimport { matchesKey, truncateToWidth } from '@earendil-works/pi-tui';\nimport type { PtyRun } from '../services/PtyHost/index.ts';\nimport type { RunnerRecord } from '../services/RunnerRegistry/index.ts';\nimport { toRunnerRows } from './format.ts';\n\nexport const RUNNER_SPACE_OVERLAY_OPTIONS = DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions;\n\nconst KEY_ENTER = '\\r';\nconst KEY_NEWLINE = '\\n';\nconst TITLE = 'RUNNER SPACE';\nconst EMPTY_MESSAGE = 'No background runners. bash backgrounds anything that outlives the threshold.';\nconst LIST_FOOTER = `${DOOM_NAVIGATION_KEYS.list} select · enter open · s stop · r reason · esc close`;\nconst ATTACH_FOOTER = 'esc back · everything else goes to the runner';\nconst LOG_FOOTER = 'esc back · live stdout/stderr';\nconst LOG_REFRESH_MS = 250;\nconst ELLIPSIS = '…';\n\nexport interface RunnerSpaceOptions {\n getRunners: () => readonly RunnerRecord[];\n /** The hosted terminal for a runner, when this session owns one. */\n getPtyRun: (name: string) => PtyRun | undefined;\n readLog: (logPath: string) => string;\n stopRunner: (id: string, reason?: string) => Promise<void>;\n}\n\nexport class RunnerSpaceComponent extends DoomOverlay {\n private selected = 0;\n private attached: PtyRun | undefined;\n private viewedLog: RunnerRecord | undefined;\n private unsubscribe: (() => void) | undefined;\n private logRefresh: ReturnType<typeof setInterval> | undefined;\n private notice: { text: string; color: 'success' | 'error' } | undefined;\n private stopReason: { runner: RunnerRecord; text: string } | undefined;\n\n constructor(\n tui: DoomOverlayTui,\n theme: Theme,\n private readonly options: RunnerSpaceOptions,\n private readonly done: (result: undefined) => void,\n ) {\n super(tui, theme);\n }\n\n handleInput(data: string): void {\n if (this.stopReason) {\n this.handleStopReasonInput(data);\n return;\n }\n if (this.attached) {\n this.handleAttachedInput(data);\n return;\n }\n if (this.viewedLog) {\n if (matchesKey(data, 'escape')) this.detach();\n return;\n }\n this.handleListInput(data);\n }\n\n protected getChrome(): DoomOverlayChrome {\n const runners = this.options.getRunners();\n return {\n title: TITLE,\n accent: DOOM_OVERLAY_ACCENT,\n breadcrumb: 'SPC › r / runners › r / runner space',\n headerRight: this.attached\n ? `attached · ${this.attached.name}`\n : this.viewedLog\n ? `logs · ${this.viewedLog.name}`\n : `${runners.length} runners · this worktree`,\n footer: this.attached ? ATTACH_FOOTER : this.viewedLog ? LOG_FOOTER : LIST_FOOTER,\n footerHints:\n this.attached || this.viewedLog\n ? undefined\n : [\n [DOOM_NAVIGATION_KEYS.list, 'select'],\n ['enter', 'open'],\n ['s', 'stop'],\n ['r', 'reason'],\n ['esc', 'close'],\n ],\n footerRight: this.attached\n ? 'live tty'\n : this.viewedLog\n ? 'live log'\n : runners.length > 0\n ? `${Math.min(this.selected, runners.length - 1) + 1}/${runners.length}`\n : 'empty',\n };\n }\n\n protected renderBody(width: number, height: number): string[] {\n const truncate = (line: string): string => truncateToWidth(line, width, ELLIPSIS);\n if (this.attached) return this.renderAttached(truncate, height);\n if (this.viewedLog) return this.renderLog(truncate, height);\n return this.renderList(truncate, height);\n }\n\n private handleAttachedInput(data: string): void {\n if (matchesKey(data, 'escape')) {\n this.detach();\n return;\n }\n this.attached?.write(data);\n }\n\n private handleListInput(data: string): void {\n const runners = this.options.getRunners();\n\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c')) {\n this.close();\n return;\n }\n if (matchesKey(data, 'up') || data === 'k') this.move(-1, runners.length);\n else if (matchesKey(data, 'down') || data === 'j') this.move(1, runners.length);\n else if (data === KEY_ENTER || data === KEY_NEWLINE) this.attach(runners);\n else if (data === 's') this.stop(runners);\n else if (data === 'r') this.promptStopReason(runners);\n }\n\n private move(delta: number, count: number): void {\n if (count === 0) return;\n this.selected = Math.max(0, Math.min(count - 1, this.selected + delta));\n this.notice = undefined;\n this.tui.requestRender();\n }\n\n private current(runners: readonly RunnerRecord[]): RunnerRecord | undefined {\n if (runners.length === 0) return undefined;\n return runners[Math.min(this.selected, runners.length - 1)];\n }\n\n private attach(runners: readonly RunnerRecord[]): void {\n const record = this.current(runners);\n if (!record) return;\n\n const run = record.interactive ? this.options.getPtyRun(record.name) : undefined;\n this.notice = undefined;\n if (run) {\n this.attached = run;\n this.unsubscribe = run.onData(() => this.tui.requestRender());\n } else {\n this.viewedLog = record;\n this.logRefresh = setInterval(() => this.tui.requestRender(true), LOG_REFRESH_MS);\n this.logRefresh.unref?.();\n }\n this.tui.requestRender(true);\n }\n\n private detach(): void {\n this.unsubscribe?.();\n this.unsubscribe = undefined;\n if (this.logRefresh) clearInterval(this.logRefresh);\n this.logRefresh = undefined;\n this.attached = undefined;\n this.viewedLog = undefined;\n this.tui.requestRender(true);\n }\n\n private stop(runners: readonly RunnerRecord[]): void {\n const record = this.current(runners);\n if (!record) return;\n\n this.options\n .stopRunner(record.id)\n .then(() => {\n this.notice = { text: `Stopped ${record.name}`, color: 'success' };\n this.tui.requestRender(true);\n })\n .catch((error: unknown) => {\n // Shown rather than swallowed: a failed stop means the process is still\n // running and the operator needs to know.\n this.notice = { text: error instanceof Error ? error.message : String(error), color: 'error' };\n this.tui.requestRender();\n });\n }\n\n private promptStopReason(runners: readonly RunnerRecord[]): void {\n const runner = this.current(runners);\n if (!runner) return;\n this.stopReason = { runner, text: '' };\n this.tui.requestRender();\n }\n\n private handleStopReasonInput(data: string): void {\n const prompt = this.stopReason;\n if (!prompt) return;\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c')) {\n this.stopReason = undefined;\n this.tui.requestRender();\n return;\n }\n if (data === KEY_ENTER || data === KEY_NEWLINE) {\n this.stopReason = undefined;\n this.options\n .stopRunner(prompt.runner.id, prompt.text.trim() || undefined)\n .then(() => {\n this.notice = { text: `Stopped ${prompt.runner.name}`, color: 'success' };\n this.tui.requestRender(true);\n })\n .catch((error: unknown) => {\n this.notice = { text: error instanceof Error ? error.message : String(error), color: 'error' };\n this.tui.requestRender();\n });\n return;\n }\n if (matchesKey(data, 'backspace')) prompt.text = prompt.text.slice(0, -1);\n else if (!data.includes('\\u001b')) prompt.text += data;\n this.tui.requestRender();\n }\n\n private close(): void {\n this.detach();\n this.done(undefined);\n }\n\n private renderList(truncate: (line: string) => string, height: number): string[] {\n const runners = this.options.getRunners();\n const rows = toRunnerRows(runners, Date.now());\n const lines: string[] = [];\n\n if (this.stopReason) {\n return [truncate(`Stop reason for ${this.stopReason.runner.name}: ${this.stopReason.text}`)];\n }\n\n if (rows.length === 0) lines.push(truncate(this.theme.fg('dim', EMPTY_MESSAGE)));\n else {\n const noticeRows = this.notice ? 2 : 0;\n const capacity = Math.max(1, height - noticeRows);\n const maxStart = Math.max(0, rows.length - capacity);\n const start = Math.min(maxStart, Math.max(0, this.selected - capacity + 1));\n rows.slice(start, start + capacity).forEach((row, offset) => {\n const index = start + offset;\n const marker = index === Math.min(this.selected, rows.length - 1) ? '›' : ' ';\n const tty = row.interactive ? ' [tty]' : '';\n lines.push(truncate(`${marker} ${row.name}${tty} ${this.theme.fg('dim', row.detail)}`));\n });\n }\n\n if (this.notice) lines.push('', truncate(this.theme.fg(this.notice.color, this.notice.text)));\n return lines.slice(0, height);\n }\n\n private renderAttached(truncate: (line: string) => string, height: number): string[] {\n const run = this.attached;\n if (!run) return [];\n\n return run.screen().split('\\n').slice(-height).map(truncate);\n }\n\n private renderLog(truncate: (line: string) => string, height: number): string[] {\n const record = this.viewedLog;\n if (!record) return [];\n\n const text = this.options.readLog(record.logPath);\n if (!text) return [truncate(this.theme.fg('dim', 'Waiting for output…'))];\n return text.split('\\n').slice(-height).map(truncate);\n }\n}\n\nexport async function openRunnerSpace(ctx: ExtensionContext, options: RunnerSpaceOptions): Promise<void> {\n await ctx.ui.custom<undefined>(\n (tui, theme, _keybindings, done) => new RunnerSpaceComponent(tui, theme, options, done),\n DOOM_FULLSCREEN_UI_OPTIONS,\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"runnerSpace.d.cts","names":[],"sources":["../../src/tui/runnerSpace.ts"],"mappings":";;;;;;;cAsBa;;;;;;UAYI;EACf,2BAA2B;;EAE3B,YAAY,iBAAiB;EAC7B,UAAU;EACV,aAAa,YAAY,oBAAoB;;cAGlC,6BAA6B;mBAYrB;mBACA;UAZX;UACA;UACA;UACA;UACA;UACA;UACA;EAGN,YAAA,KAAK,gBACL,OAAO,OACU,SAAS,oBACT,OAAO;EAK1B,YAAY;YAgBF,aAAa;YAgCb,WAAW,eAAe;UAO5B;UAQA;UAcA;UAOA;UAKA;UAiBA;UAUA;UAkBA;UAOA;UA2BA;UAKA;UA2BA;UAOA;;iBAUY,gBAAgB,KAAK,kBAAkB,SAAS,qBAAqB"}
1
+ {"version":3,"file":"runnerSpace.d.cts","names":[],"sources":["../../src/tui/runnerSpace.ts"],"mappings":";;;;;;;cAuBa;;;;;;UAYI;EACf,2BAA2B;;EAE3B,YAAY,iBAAiB;EAC7B,UAAU;EACV,aAAa,YAAY,oBAAoB;;cAGlC,6BAA6B;mBAYrB;mBACA;UAZX;UACA;UACA;UACA;UACA;UACA;UACA;EAGN,YAAA,KAAK,gBACL,OAAO,OACU,SAAS,oBACT,OAAO;EAK1B,YAAY;YAgBF,aAAa;YAgCb,WAAW,eAAe;UAO5B;UAQA;UAcA;UAOA;UAKA;UAiBA;UAUA;UAkBA;UAOA;UA2BA;UAKA;UA2BA;UAOA;;iBAUY,gBAAgB,KAAK,kBAAkB,SAAS,qBAAqB"}
@@ -1 +1 @@
1
- {"version":3,"file":"runnerSpace.d.mts","names":[],"sources":["../../src/tui/runnerSpace.ts"],"mappings":";;;;;;;cAsBa;;;;;;UAYI;EACf,2BAA2B;;EAE3B,YAAY,iBAAiB;EAC7B,UAAU;EACV,aAAa,YAAY,oBAAoB;;cAGlC,6BAA6B;mBAYrB;mBACA;UAZX;UACA;UACA;UACA;UACA;UACA;UACA;EAGN,YAAA,KAAK,gBACL,OAAO,OACU,SAAS,oBACT,OAAO;EAK1B,YAAY;YAgBF,aAAa;YAgCb,WAAW,eAAe;UAO5B;UAQA;UAcA;UAOA;UAKA;UAiBA;UAUA;UAkBA;UAOA;UA2BA;UAKA;UA2BA;UAOA;;iBAUY,gBAAgB,KAAK,kBAAkB,SAAS,qBAAqB"}
1
+ {"version":3,"file":"runnerSpace.d.mts","names":[],"sources":["../../src/tui/runnerSpace.ts"],"mappings":";;;;;;;cAuBa;;;;;;UAYI;EACf,2BAA2B;;EAE3B,YAAY,iBAAiB;EAC7B,UAAU;EACV,aAAa,YAAY,oBAAoB;;cAGlC,6BAA6B;mBAYrB;mBACA;UAZX;UACA;UACA;UACA;UACA;UACA;UACA;EAGN,YAAA,KAAK,gBACL,OAAO,OACU,SAAS,oBACT,OAAO;EAK1B,YAAY;YAgBF,aAAa;YAgCb,WAAW,eAAe;UAO5B;UAQA;UAcA;UAOA;UAKA;UAiBA;UAUA;UAkBA;UAOA;UA2BA;UAKA;UA2BA;UAOA;;iBAUY,gBAAgB,KAAK,kBAAkB,SAAS,qBAAqB"}
@@ -1,6 +1,6 @@
1
- import{toRunnerRows as e}from"./format.mjs";import{matchesKey as t,truncateToWidth as n}from"@earendil-works/pi-tui";import{DOOM_FULLSCREEN_UI_OPTIONS as r,DOOM_OVERLAY_ACCENT as i,DoomOverlay as a}from"@agimon-ai/doompi-ui/components/doomOverlay";const o=r.overlayOptions;var s=class extends a{options;done;selected=0;attached;viewedLog;unsubscribe;logRefresh;notice;stopReason;constructor(e,t,n,r){super(e,t),this.options=n,this.done=r}handleInput(e){if(this.stopReason){this.handleStopReasonInput(e);return}if(this.attached){this.handleAttachedInput(e);return}if(this.viewedLog){t(e,`escape`)&&this.detach();return}this.handleListInput(e)}getChrome(){let e=this.options.getRunners();return{title:`RUNNER SPACE`,accent:i,breadcrumb:`SPC › r / runners › r / runner space`,headerRight:this.attached?`attached · ${this.attached.name}`:this.viewedLog?`logs · ${this.viewedLog.name}`:`${e.length} runners · this worktree`,footer:this.attached?`esc back · everything else goes to the runner`:this.viewedLog?`esc back · live stdout/stderr`:`↑↓/jk select · enter open · s stop · r reason · esc close`,footerHints:this.attached||this.viewedLog?void 0:[[`↑↓/jk`,`select`],[`enter`,`open`],[`s`,`stop`],[`r`,`reason`],[`esc`,`close`]],footerRight:this.attached?`live tty`:this.viewedLog?`live log`:e.length>0?`${Math.min(this.selected,e.length-1)+1}/${e.length}`:`empty`}}renderBody(e,t){let r=t=>n(t,e,`…`);return this.attached?this.renderAttached(r,t):this.viewedLog?this.renderLog(r,t):this.renderList(r,t)}handleAttachedInput(e){if(t(e,`escape`)){this.detach();return}this.attached?.write(e)}handleListInput(e){let n=this.options.getRunners();if(t(e,`escape`)||t(e,`ctrl+c`)){this.close();return}t(e,`up`)||e===`k`?this.move(-1,n.length):t(e,`down`)||e===`j`?this.move(1,n.length):e===`\r`||e===`
2
- `?this.attach(n):e===`s`?this.stop(n):e===`r`&&this.promptStopReason(n)}move(e,t){t!==0&&(this.selected=Math.max(0,Math.min(t-1,this.selected+e)),this.notice=void 0,this.tui.requestRender())}current(e){if(e.length!==0)return e[Math.min(this.selected,e.length-1)]}attach(e){let t=this.current(e);if(!t)return;let n=t.interactive?this.options.getPtyRun(t.name):void 0;this.notice=void 0,n?(this.attached=n,this.unsubscribe=n.onData(()=>this.tui.requestRender())):(this.viewedLog=t,this.logRefresh=setInterval(()=>this.tui.requestRender(!0),250),this.logRefresh.unref?.()),this.tui.requestRender(!0)}detach(){this.unsubscribe?.(),this.unsubscribe=void 0,this.logRefresh&&clearInterval(this.logRefresh),this.logRefresh=void 0,this.attached=void 0,this.viewedLog=void 0,this.tui.requestRender(!0)}stop(e){let t=this.current(e);t&&this.options.stopRunner(t.id).then(()=>{this.notice=`Stopped ${t.name}`,this.tui.requestRender(!0)}).catch(e=>{this.notice=e instanceof Error?e.message:String(e),this.tui.requestRender()})}promptStopReason(e){let t=this.current(e);t&&(this.stopReason={runner:t,text:``},this.tui.requestRender())}handleStopReasonInput(e){let n=this.stopReason;if(n){if(t(e,`escape`)||t(e,`ctrl+c`)){this.stopReason=void 0,this.tui.requestRender();return}if(e===`\r`||e===`
3
- `){this.stopReason=void 0,this.options.stopRunner(n.runner.id,n.text.trim()||void 0).then(()=>{this.notice=`Stopped ${n.runner.name}`,this.tui.requestRender(!0)}).catch(e=>{this.notice=e instanceof Error?e.message:String(e),this.tui.requestRender()});return}t(e,`backspace`)?n.text=n.text.slice(0,-1):e.includes(`\x1B`)||(n.text+=e),this.tui.requestRender()}}close(){this.detach(),this.done(void 0)}renderList(t,n){let r=this.options.getRunners(),i=e(r,Date.now()),a=[];if(this.stopReason)return[t(`Stop reason for ${this.stopReason.runner.name}: ${this.stopReason.text}`)];if(i.length===0)a.push(t(this.theme.fg(`dim`,`No background runners. bash backgrounds anything that outlives the threshold.`)));else{let e=this.notice?2:0,r=Math.max(1,n-e),o=Math.max(0,i.length-r),s=Math.min(o,Math.max(0,this.selected-r+1));i.slice(s,s+r).forEach((e,n)=>{let r=s+n===Math.min(this.selected,i.length-1)?`›`:` `,o=e.interactive?` [tty]`:``;a.push(t(`${r} ${e.name}${o} ${this.theme.fg(`dim`,e.detail)}`))})}return this.notice&&a.push(``,t(this.theme.fg(`warning`,this.notice))),a.slice(0,n)}renderAttached(e,t){let n=this.attached;return n?n.screen().split(`
1
+ import{toRunnerRows as e}from"./format.mjs";import{matchesKey as t,truncateToWidth as n}from"@earendil-works/pi-tui";import{DOOM_FULLSCREEN_UI_OPTIONS as r,DOOM_NAVIGATION_KEYS as i,DOOM_OVERLAY_ACCENT as a,DoomOverlay as o}from"@agimon-ai/doompi-ui/components/doomOverlay";const s=r.overlayOptions,c=`${i.list} select · enter open · s stop · r reason · esc close`;var l=class extends o{options;done;selected=0;attached;viewedLog;unsubscribe;logRefresh;notice;stopReason;constructor(e,t,n,r){super(e,t),this.options=n,this.done=r}handleInput(e){if(this.stopReason){this.handleStopReasonInput(e);return}if(this.attached){this.handleAttachedInput(e);return}if(this.viewedLog){t(e,`escape`)&&this.detach();return}this.handleListInput(e)}getChrome(){let e=this.options.getRunners();return{title:`RUNNER SPACE`,accent:a,breadcrumb:`SPC › r / runners › r / runner space`,headerRight:this.attached?`attached · ${this.attached.name}`:this.viewedLog?`logs · ${this.viewedLog.name}`:`${e.length} runners · this worktree`,footer:this.attached?`esc back · everything else goes to the runner`:this.viewedLog?`esc back · live stdout/stderr`:c,footerHints:this.attached||this.viewedLog?void 0:[[i.list,`select`],[`enter`,`open`],[`s`,`stop`],[`r`,`reason`],[`esc`,`close`]],footerRight:this.attached?`live tty`:this.viewedLog?`live log`:e.length>0?`${Math.min(this.selected,e.length-1)+1}/${e.length}`:`empty`}}renderBody(e,t){let r=t=>n(t,e,`…`);return this.attached?this.renderAttached(r,t):this.viewedLog?this.renderLog(r,t):this.renderList(r,t)}handleAttachedInput(e){if(t(e,`escape`)){this.detach();return}this.attached?.write(e)}handleListInput(e){let n=this.options.getRunners();if(t(e,`escape`)||t(e,`ctrl+c`)){this.close();return}t(e,`up`)||e===`k`?this.move(-1,n.length):t(e,`down`)||e===`j`?this.move(1,n.length):e===`\r`||e===`
2
+ `?this.attach(n):e===`s`?this.stop(n):e===`r`&&this.promptStopReason(n)}move(e,t){t!==0&&(this.selected=Math.max(0,Math.min(t-1,this.selected+e)),this.notice=void 0,this.tui.requestRender())}current(e){if(e.length!==0)return e[Math.min(this.selected,e.length-1)]}attach(e){let t=this.current(e);if(!t)return;let n=t.interactive?this.options.getPtyRun(t.name):void 0;this.notice=void 0,n?(this.attached=n,this.unsubscribe=n.onData(()=>this.tui.requestRender())):(this.viewedLog=t,this.logRefresh=setInterval(()=>this.tui.requestRender(!0),250),this.logRefresh.unref?.()),this.tui.requestRender(!0)}detach(){this.unsubscribe?.(),this.unsubscribe=void 0,this.logRefresh&&clearInterval(this.logRefresh),this.logRefresh=void 0,this.attached=void 0,this.viewedLog=void 0,this.tui.requestRender(!0)}stop(e){let t=this.current(e);t&&this.options.stopRunner(t.id).then(()=>{this.notice={text:`Stopped ${t.name}`,color:`success`},this.tui.requestRender(!0)}).catch(e=>{this.notice={text:e instanceof Error?e.message:String(e),color:`error`},this.tui.requestRender()})}promptStopReason(e){let t=this.current(e);t&&(this.stopReason={runner:t,text:``},this.tui.requestRender())}handleStopReasonInput(e){let n=this.stopReason;if(n){if(t(e,`escape`)||t(e,`ctrl+c`)){this.stopReason=void 0,this.tui.requestRender();return}if(e===`\r`||e===`
3
+ `){this.stopReason=void 0,this.options.stopRunner(n.runner.id,n.text.trim()||void 0).then(()=>{this.notice={text:`Stopped ${n.runner.name}`,color:`success`},this.tui.requestRender(!0)}).catch(e=>{this.notice={text:e instanceof Error?e.message:String(e),color:`error`},this.tui.requestRender()});return}t(e,`backspace`)?n.text=n.text.slice(0,-1):e.includes(`\x1B`)||(n.text+=e),this.tui.requestRender()}}close(){this.detach(),this.done(void 0)}renderList(t,n){let r=this.options.getRunners(),i=e(r,Date.now()),a=[];if(this.stopReason)return[t(`Stop reason for ${this.stopReason.runner.name}: ${this.stopReason.text}`)];if(i.length===0)a.push(t(this.theme.fg(`dim`,`No background runners. bash backgrounds anything that outlives the threshold.`)));else{let e=this.notice?2:0,r=Math.max(1,n-e),o=Math.max(0,i.length-r),s=Math.min(o,Math.max(0,this.selected-r+1));i.slice(s,s+r).forEach((e,n)=>{let r=s+n===Math.min(this.selected,i.length-1)?`›`:` `,o=e.interactive?` [tty]`:``;a.push(t(`${r} ${e.name}${o} ${this.theme.fg(`dim`,e.detail)}`))})}return this.notice&&a.push(``,t(this.theme.fg(this.notice.color,this.notice.text))),a.slice(0,n)}renderAttached(e,t){let n=this.attached;return n?n.screen().split(`
4
4
  `).slice(-t).map(e):[]}renderLog(e,t){let n=this.viewedLog;if(!n)return[];let r=this.options.readLog(n.logPath);return r?r.split(`
5
- `).slice(-t).map(e):[e(this.theme.fg(`dim`,`Waiting for output…`))]}};async function c(e,t){await e.ui.custom((e,n,r,i)=>new s(e,n,t,i),r)}export{o as RUNNER_SPACE_OVERLAY_OPTIONS,s as RunnerSpaceComponent,c as openRunnerSpace};
5
+ `).slice(-t).map(e):[e(this.theme.fg(`dim`,`Waiting for output…`))]}};async function u(e,t){await e.ui.custom((e,n,r,i)=>new l(e,n,t,i),r)}export{s as RUNNER_SPACE_OVERLAY_OPTIONS,l as RunnerSpaceComponent,u as openRunnerSpace};
6
6
  //# sourceMappingURL=runnerSpace.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"runnerSpace.mjs","names":[],"sources":["../../src/tui/runnerSpace.ts"],"sourcesContent":["/**\n * Runner Space: the `SPC r r` overlay.\n *\n * Two modes behind one component. The list shows every runner in this worktree\n * and can stop them; attaching to an interactive runner renders its live\n * terminal and forwards keystrokes to it, which is the whole reason PTY runs\n * exist. Rendering is pure, so the surface can be asserted as text.\n */\n\nimport type { ExtensionContext, Theme } from '@earendil-works/pi-coding-agent';\nimport {\n DOOM_OVERLAY_ACCENT,\n DoomOverlay,\n type DoomOverlayChrome,\n type DoomOverlayTui,\n DOOM_FULLSCREEN_UI_OPTIONS,\n} from '@agimon-ai/doompi-ui/components/doomOverlay';\nimport { matchesKey, truncateToWidth } from '@earendil-works/pi-tui';\nimport type { PtyRun } from '../services/PtyHost/index.ts';\nimport type { RunnerRecord } from '../services/RunnerRegistry/index.ts';\nimport { toRunnerRows } from './format.ts';\n\nexport const RUNNER_SPACE_OVERLAY_OPTIONS = DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions;\n\nconst KEY_ENTER = '\\r';\nconst KEY_NEWLINE = '\\n';\nconst TITLE = 'RUNNER SPACE';\nconst EMPTY_MESSAGE = 'No background runners. bash backgrounds anything that outlives the threshold.';\nconst LIST_FOOTER = '↑↓/jk select · enter open · s stop · r reason · esc close';\nconst ATTACH_FOOTER = 'esc back · everything else goes to the runner';\nconst LOG_FOOTER = 'esc back · live stdout/stderr';\nconst LOG_REFRESH_MS = 250;\nconst ELLIPSIS = '…';\n\nexport interface RunnerSpaceOptions {\n getRunners: () => readonly RunnerRecord[];\n /** The hosted terminal for a runner, when this session owns one. */\n getPtyRun: (name: string) => PtyRun | undefined;\n readLog: (logPath: string) => string;\n stopRunner: (id: string, reason?: string) => Promise<void>;\n}\n\nexport class RunnerSpaceComponent extends DoomOverlay {\n private selected = 0;\n private attached: PtyRun | undefined;\n private viewedLog: RunnerRecord | undefined;\n private unsubscribe: (() => void) | undefined;\n private logRefresh: ReturnType<typeof setInterval> | undefined;\n private notice: string | undefined;\n private stopReason: { runner: RunnerRecord; text: string } | undefined;\n\n constructor(\n tui: DoomOverlayTui,\n theme: Theme,\n private readonly options: RunnerSpaceOptions,\n private readonly done: (result: undefined) => void,\n ) {\n super(tui, theme);\n }\n\n handleInput(data: string): void {\n if (this.stopReason) {\n this.handleStopReasonInput(data);\n return;\n }\n if (this.attached) {\n this.handleAttachedInput(data);\n return;\n }\n if (this.viewedLog) {\n if (matchesKey(data, 'escape')) this.detach();\n return;\n }\n this.handleListInput(data);\n }\n\n protected getChrome(): DoomOverlayChrome {\n const runners = this.options.getRunners();\n return {\n title: TITLE,\n accent: DOOM_OVERLAY_ACCENT,\n breadcrumb: 'SPC › r / runners › r / runner space',\n headerRight: this.attached\n ? `attached · ${this.attached.name}`\n : this.viewedLog\n ? `logs · ${this.viewedLog.name}`\n : `${runners.length} runners · this worktree`,\n footer: this.attached ? ATTACH_FOOTER : this.viewedLog ? LOG_FOOTER : LIST_FOOTER,\n footerHints:\n this.attached || this.viewedLog\n ? undefined\n : [\n ['↑↓/jk', 'select'],\n ['enter', 'open'],\n ['s', 'stop'],\n ['r', 'reason'],\n ['esc', 'close'],\n ],\n footerRight: this.attached\n ? 'live tty'\n : this.viewedLog\n ? 'live log'\n : runners.length > 0\n ? `${Math.min(this.selected, runners.length - 1) + 1}/${runners.length}`\n : 'empty',\n };\n }\n\n protected renderBody(width: number, height: number): string[] {\n const truncate = (line: string): string => truncateToWidth(line, width, ELLIPSIS);\n if (this.attached) return this.renderAttached(truncate, height);\n if (this.viewedLog) return this.renderLog(truncate, height);\n return this.renderList(truncate, height);\n }\n\n private handleAttachedInput(data: string): void {\n if (matchesKey(data, 'escape')) {\n this.detach();\n return;\n }\n this.attached?.write(data);\n }\n\n private handleListInput(data: string): void {\n const runners = this.options.getRunners();\n\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c')) {\n this.close();\n return;\n }\n if (matchesKey(data, 'up') || data === 'k') this.move(-1, runners.length);\n else if (matchesKey(data, 'down') || data === 'j') this.move(1, runners.length);\n else if (data === KEY_ENTER || data === KEY_NEWLINE) this.attach(runners);\n else if (data === 's') this.stop(runners);\n else if (data === 'r') this.promptStopReason(runners);\n }\n\n private move(delta: number, count: number): void {\n if (count === 0) return;\n this.selected = Math.max(0, Math.min(count - 1, this.selected + delta));\n this.notice = undefined;\n this.tui.requestRender();\n }\n\n private current(runners: readonly RunnerRecord[]): RunnerRecord | undefined {\n if (runners.length === 0) return undefined;\n return runners[Math.min(this.selected, runners.length - 1)];\n }\n\n private attach(runners: readonly RunnerRecord[]): void {\n const record = this.current(runners);\n if (!record) return;\n\n const run = record.interactive ? this.options.getPtyRun(record.name) : undefined;\n this.notice = undefined;\n if (run) {\n this.attached = run;\n this.unsubscribe = run.onData(() => this.tui.requestRender());\n } else {\n this.viewedLog = record;\n this.logRefresh = setInterval(() => this.tui.requestRender(true), LOG_REFRESH_MS);\n this.logRefresh.unref?.();\n }\n this.tui.requestRender(true);\n }\n\n private detach(): void {\n this.unsubscribe?.();\n this.unsubscribe = undefined;\n if (this.logRefresh) clearInterval(this.logRefresh);\n this.logRefresh = undefined;\n this.attached = undefined;\n this.viewedLog = undefined;\n this.tui.requestRender(true);\n }\n\n private stop(runners: readonly RunnerRecord[]): void {\n const record = this.current(runners);\n if (!record) return;\n\n this.options\n .stopRunner(record.id)\n .then(() => {\n this.notice = `Stopped ${record.name}`;\n this.tui.requestRender(true);\n })\n .catch((error: unknown) => {\n // Shown rather than swallowed: a failed stop means the process is still\n // running and the operator needs to know.\n this.notice = error instanceof Error ? error.message : String(error);\n this.tui.requestRender();\n });\n }\n\n private promptStopReason(runners: readonly RunnerRecord[]): void {\n const runner = this.current(runners);\n if (!runner) return;\n this.stopReason = { runner, text: '' };\n this.tui.requestRender();\n }\n\n private handleStopReasonInput(data: string): void {\n const prompt = this.stopReason;\n if (!prompt) return;\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c')) {\n this.stopReason = undefined;\n this.tui.requestRender();\n return;\n }\n if (data === KEY_ENTER || data === KEY_NEWLINE) {\n this.stopReason = undefined;\n this.options\n .stopRunner(prompt.runner.id, prompt.text.trim() || undefined)\n .then(() => {\n this.notice = `Stopped ${prompt.runner.name}`;\n this.tui.requestRender(true);\n })\n .catch((error: unknown) => {\n this.notice = error instanceof Error ? error.message : String(error);\n this.tui.requestRender();\n });\n return;\n }\n if (matchesKey(data, 'backspace')) prompt.text = prompt.text.slice(0, -1);\n else if (!data.includes('\\u001b')) prompt.text += data;\n this.tui.requestRender();\n }\n\n private close(): void {\n this.detach();\n this.done(undefined);\n }\n\n private renderList(truncate: (line: string) => string, height: number): string[] {\n const runners = this.options.getRunners();\n const rows = toRunnerRows(runners, Date.now());\n const lines: string[] = [];\n\n if (this.stopReason) {\n return [truncate(`Stop reason for ${this.stopReason.runner.name}: ${this.stopReason.text}`)];\n }\n\n if (rows.length === 0) lines.push(truncate(this.theme.fg('dim', EMPTY_MESSAGE)));\n else {\n const noticeRows = this.notice ? 2 : 0;\n const capacity = Math.max(1, height - noticeRows);\n const maxStart = Math.max(0, rows.length - capacity);\n const start = Math.min(maxStart, Math.max(0, this.selected - capacity + 1));\n rows.slice(start, start + capacity).forEach((row, offset) => {\n const index = start + offset;\n const marker = index === Math.min(this.selected, rows.length - 1) ? '›' : ' ';\n const tty = row.interactive ? ' [tty]' : '';\n lines.push(truncate(`${marker} ${row.name}${tty} ${this.theme.fg('dim', row.detail)}`));\n });\n }\n\n if (this.notice) lines.push('', truncate(this.theme.fg('warning', this.notice)));\n return lines.slice(0, height);\n }\n\n private renderAttached(truncate: (line: string) => string, height: number): string[] {\n const run = this.attached;\n if (!run) return [];\n\n return run.screen().split('\\n').slice(-height).map(truncate);\n }\n\n private renderLog(truncate: (line: string) => string, height: number): string[] {\n const record = this.viewedLog;\n if (!record) return [];\n\n const text = this.options.readLog(record.logPath);\n if (!text) return [truncate(this.theme.fg('dim', 'Waiting for output…'))];\n return text.split('\\n').slice(-height).map(truncate);\n }\n}\n\nexport async function openRunnerSpace(ctx: ExtensionContext, options: RunnerSpaceOptions): Promise<void> {\n await ctx.ui.custom<undefined>(\n (tui, theme, _keybindings, done) => new RunnerSpaceComponent(tui, theme, options, done),\n DOOM_FULLSCREEN_UI_OPTIONS,\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"runnerSpace.mjs","names":[],"sources":["../../src/tui/runnerSpace.ts"],"sourcesContent":["/**\n * Runner Space: the `SPC r r` overlay.\n *\n * Two modes behind one component. The list shows every runner in this worktree\n * and can stop them; attaching to an interactive runner renders its live\n * terminal and forwards keystrokes to it, which is the whole reason PTY runs\n * exist. Rendering is pure, so the surface can be asserted as text.\n */\n\nimport {\n DOOM_FULLSCREEN_UI_OPTIONS,\n DOOM_NAVIGATION_KEYS,\n DOOM_OVERLAY_ACCENT,\n DoomOverlay,\n type DoomOverlayChrome,\n type DoomOverlayTui,\n} from '@agimon-ai/doompi-ui/components/doomOverlay';\nimport type { ExtensionContext, Theme } from '@earendil-works/pi-coding-agent';\nimport { matchesKey, truncateToWidth } from '@earendil-works/pi-tui';\nimport type { PtyRun } from '../services/PtyHost/index.ts';\nimport type { RunnerRecord } from '../services/RunnerRegistry/index.ts';\nimport { toRunnerRows } from './format.ts';\n\nexport const RUNNER_SPACE_OVERLAY_OPTIONS = DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions;\n\nconst KEY_ENTER = '\\r';\nconst KEY_NEWLINE = '\\n';\nconst TITLE = 'RUNNER SPACE';\nconst EMPTY_MESSAGE = 'No background runners. bash backgrounds anything that outlives the threshold.';\nconst LIST_FOOTER = `${DOOM_NAVIGATION_KEYS.list} select · enter open · s stop · r reason · esc close`;\nconst ATTACH_FOOTER = 'esc back · everything else goes to the runner';\nconst LOG_FOOTER = 'esc back · live stdout/stderr';\nconst LOG_REFRESH_MS = 250;\nconst ELLIPSIS = '…';\n\nexport interface RunnerSpaceOptions {\n getRunners: () => readonly RunnerRecord[];\n /** The hosted terminal for a runner, when this session owns one. */\n getPtyRun: (name: string) => PtyRun | undefined;\n readLog: (logPath: string) => string;\n stopRunner: (id: string, reason?: string) => Promise<void>;\n}\n\nexport class RunnerSpaceComponent extends DoomOverlay {\n private selected = 0;\n private attached: PtyRun | undefined;\n private viewedLog: RunnerRecord | undefined;\n private unsubscribe: (() => void) | undefined;\n private logRefresh: ReturnType<typeof setInterval> | undefined;\n private notice: { text: string; color: 'success' | 'error' } | undefined;\n private stopReason: { runner: RunnerRecord; text: string } | undefined;\n\n constructor(\n tui: DoomOverlayTui,\n theme: Theme,\n private readonly options: RunnerSpaceOptions,\n private readonly done: (result: undefined) => void,\n ) {\n super(tui, theme);\n }\n\n handleInput(data: string): void {\n if (this.stopReason) {\n this.handleStopReasonInput(data);\n return;\n }\n if (this.attached) {\n this.handleAttachedInput(data);\n return;\n }\n if (this.viewedLog) {\n if (matchesKey(data, 'escape')) this.detach();\n return;\n }\n this.handleListInput(data);\n }\n\n protected getChrome(): DoomOverlayChrome {\n const runners = this.options.getRunners();\n return {\n title: TITLE,\n accent: DOOM_OVERLAY_ACCENT,\n breadcrumb: 'SPC › r / runners › r / runner space',\n headerRight: this.attached\n ? `attached · ${this.attached.name}`\n : this.viewedLog\n ? `logs · ${this.viewedLog.name}`\n : `${runners.length} runners · this worktree`,\n footer: this.attached ? ATTACH_FOOTER : this.viewedLog ? LOG_FOOTER : LIST_FOOTER,\n footerHints:\n this.attached || this.viewedLog\n ? undefined\n : [\n [DOOM_NAVIGATION_KEYS.list, 'select'],\n ['enter', 'open'],\n ['s', 'stop'],\n ['r', 'reason'],\n ['esc', 'close'],\n ],\n footerRight: this.attached\n ? 'live tty'\n : this.viewedLog\n ? 'live log'\n : runners.length > 0\n ? `${Math.min(this.selected, runners.length - 1) + 1}/${runners.length}`\n : 'empty',\n };\n }\n\n protected renderBody(width: number, height: number): string[] {\n const truncate = (line: string): string => truncateToWidth(line, width, ELLIPSIS);\n if (this.attached) return this.renderAttached(truncate, height);\n if (this.viewedLog) return this.renderLog(truncate, height);\n return this.renderList(truncate, height);\n }\n\n private handleAttachedInput(data: string): void {\n if (matchesKey(data, 'escape')) {\n this.detach();\n return;\n }\n this.attached?.write(data);\n }\n\n private handleListInput(data: string): void {\n const runners = this.options.getRunners();\n\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c')) {\n this.close();\n return;\n }\n if (matchesKey(data, 'up') || data === 'k') this.move(-1, runners.length);\n else if (matchesKey(data, 'down') || data === 'j') this.move(1, runners.length);\n else if (data === KEY_ENTER || data === KEY_NEWLINE) this.attach(runners);\n else if (data === 's') this.stop(runners);\n else if (data === 'r') this.promptStopReason(runners);\n }\n\n private move(delta: number, count: number): void {\n if (count === 0) return;\n this.selected = Math.max(0, Math.min(count - 1, this.selected + delta));\n this.notice = undefined;\n this.tui.requestRender();\n }\n\n private current(runners: readonly RunnerRecord[]): RunnerRecord | undefined {\n if (runners.length === 0) return undefined;\n return runners[Math.min(this.selected, runners.length - 1)];\n }\n\n private attach(runners: readonly RunnerRecord[]): void {\n const record = this.current(runners);\n if (!record) return;\n\n const run = record.interactive ? this.options.getPtyRun(record.name) : undefined;\n this.notice = undefined;\n if (run) {\n this.attached = run;\n this.unsubscribe = run.onData(() => this.tui.requestRender());\n } else {\n this.viewedLog = record;\n this.logRefresh = setInterval(() => this.tui.requestRender(true), LOG_REFRESH_MS);\n this.logRefresh.unref?.();\n }\n this.tui.requestRender(true);\n }\n\n private detach(): void {\n this.unsubscribe?.();\n this.unsubscribe = undefined;\n if (this.logRefresh) clearInterval(this.logRefresh);\n this.logRefresh = undefined;\n this.attached = undefined;\n this.viewedLog = undefined;\n this.tui.requestRender(true);\n }\n\n private stop(runners: readonly RunnerRecord[]): void {\n const record = this.current(runners);\n if (!record) return;\n\n this.options\n .stopRunner(record.id)\n .then(() => {\n this.notice = { text: `Stopped ${record.name}`, color: 'success' };\n this.tui.requestRender(true);\n })\n .catch((error: unknown) => {\n // Shown rather than swallowed: a failed stop means the process is still\n // running and the operator needs to know.\n this.notice = { text: error instanceof Error ? error.message : String(error), color: 'error' };\n this.tui.requestRender();\n });\n }\n\n private promptStopReason(runners: readonly RunnerRecord[]): void {\n const runner = this.current(runners);\n if (!runner) return;\n this.stopReason = { runner, text: '' };\n this.tui.requestRender();\n }\n\n private handleStopReasonInput(data: string): void {\n const prompt = this.stopReason;\n if (!prompt) return;\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c')) {\n this.stopReason = undefined;\n this.tui.requestRender();\n return;\n }\n if (data === KEY_ENTER || data === KEY_NEWLINE) {\n this.stopReason = undefined;\n this.options\n .stopRunner(prompt.runner.id, prompt.text.trim() || undefined)\n .then(() => {\n this.notice = { text: `Stopped ${prompt.runner.name}`, color: 'success' };\n this.tui.requestRender(true);\n })\n .catch((error: unknown) => {\n this.notice = { text: error instanceof Error ? error.message : String(error), color: 'error' };\n this.tui.requestRender();\n });\n return;\n }\n if (matchesKey(data, 'backspace')) prompt.text = prompt.text.slice(0, -1);\n else if (!data.includes('\\u001b')) prompt.text += data;\n this.tui.requestRender();\n }\n\n private close(): void {\n this.detach();\n this.done(undefined);\n }\n\n private renderList(truncate: (line: string) => string, height: number): string[] {\n const runners = this.options.getRunners();\n const rows = toRunnerRows(runners, Date.now());\n const lines: string[] = [];\n\n if (this.stopReason) {\n return [truncate(`Stop reason for ${this.stopReason.runner.name}: ${this.stopReason.text}`)];\n }\n\n if (rows.length === 0) lines.push(truncate(this.theme.fg('dim', EMPTY_MESSAGE)));\n else {\n const noticeRows = this.notice ? 2 : 0;\n const capacity = Math.max(1, height - noticeRows);\n const maxStart = Math.max(0, rows.length - capacity);\n const start = Math.min(maxStart, Math.max(0, this.selected - capacity + 1));\n rows.slice(start, start + capacity).forEach((row, offset) => {\n const index = start + offset;\n const marker = index === Math.min(this.selected, rows.length - 1) ? '›' : ' ';\n const tty = row.interactive ? ' [tty]' : '';\n lines.push(truncate(`${marker} ${row.name}${tty} ${this.theme.fg('dim', row.detail)}`));\n });\n }\n\n if (this.notice) lines.push('', truncate(this.theme.fg(this.notice.color, this.notice.text)));\n return lines.slice(0, height);\n }\n\n private renderAttached(truncate: (line: string) => string, height: number): string[] {\n const run = this.attached;\n if (!run) return [];\n\n return run.screen().split('\\n').slice(-height).map(truncate);\n }\n\n private renderLog(truncate: (line: string) => string, height: number): string[] {\n const record = this.viewedLog;\n if (!record) return [];\n\n const text = this.options.readLog(record.logPath);\n if (!text) return [truncate(this.theme.fg('dim', 'Waiting for output…'))];\n return text.split('\\n').slice(-height).map(truncate);\n }\n}\n\nexport async function openRunnerSpace(ctx: ExtensionContext, options: RunnerSpaceOptions): Promise<void> {\n await ctx.ui.custom<undefined>(\n (tui, theme, _keybindings, done) => new RunnerSpaceComponent(tui, theme, options, done),\n DOOM_FULLSCREEN_UI_OPTIONS,\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
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=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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.cjs","names":[],"sources":["../../src/types/config.ts"],"sourcesContent":["/**\n * Extension configuration, read from the environment.\n *\n * Env rather than a config file, matching doom-task: doom-pi already carries\n * per-launch state to Pi through env vars.\n */\n\nexport const BG_THRESHOLD_MS_ENV = 'DOOM_RUNNER_BG_THRESHOLD_MS';\nexport const RESULT_MAX_BYTES_ENV = 'DOOM_RUNNER_RESULT_MAX_BYTES';\nexport const LOG_MAX_BYTES_ENV = 'DOOM_RUNNER_LOG_MAX_BYTES';\nexport const LOG_TTL_MS_ENV = 'DOOM_RUNNER_LOG_TTL_MS';\n/** Unscoped override for the runner log directory. */\nexport const LOG_DIR_ENV = 'DOOM_RUNNER_LOG_DIR';\n\n/** A bash call still running at this point is promoted to a named runner. */\nexport const DEFAULT_BG_THRESHOLD_MS = 60_000;\n/** Tool results past this size are tail-truncated and spilled to the log file. */\nexport const DEFAULT_RESULT_MAX_BYTES = 51_200;\n/** A runner log rotates once to `.log.1` at this size. */\nexport const DEFAULT_LOG_MAX_BYTES = 5 * 1024 * 1024;\n/** Retention window for logs with no live registry record. */\nexport const DEFAULT_LOG_TTL_MS = 7 * 24 * 60 * 60 * 1000;\n\nfunction positiveNumber(raw: string | undefined, fallback: number): number {\n const value = Number(raw);\n return Number.isFinite(value) && value > 0 ? value : fallback;\n}\n\n/** Age at which a bash call becomes a background runner. */\nexport function getBackgroundThresholdMs(env: NodeJS.ProcessEnv = process.env): number {\n return positiveNumber(env[BG_THRESHOLD_MS_ENV], DEFAULT_BG_THRESHOLD_MS);\n}\n\n/** Byte ceiling for a single tool result before tail truncation kicks in. */\nexport function getResultMaxBytes(env: NodeJS.ProcessEnv = process.env): number {\n return positiveNumber(env[RESULT_MAX_BYTES_ENV], DEFAULT_RESULT_MAX_BYTES);\n}\n\n/** Byte ceiling for a runner log before it rotates. */\nexport function getLogMaxBytes(env: NodeJS.ProcessEnv = process.env): number {\n return positiveNumber(env[LOG_MAX_BYTES_ENV], DEFAULT_LOG_MAX_BYTES);\n}\n\n/** Retention window for orphaned runner logs. */\nexport function getLogTtlMs(env: NodeJS.ProcessEnv = process.env): number {\n return positiveNumber(env[LOG_TTL_MS_ENV], DEFAULT_LOG_TTL_MS);\n}\n"],"mappings":"AAOA,MAAa,EAAsB,8BACtB,EAAuB,+BACvB,EAAoB,4BACpB,EAAiB,yBAKjB,EAA0B,IAE1B,EAA2B,MAE3B,EAAwB,QAExB,EAAqB,OAElC,SAAS,EAAe,EAAyB,EAA0B,CACzE,IAAM,EAAQ,OAAO,CAAG,EACxB,OAAO,OAAO,SAAS,CAAK,GAAK,EAAQ,EAAI,EAAQ,CACvD,CAGA,SAAgB,EAAyB,EAAyB,QAAQ,IAAa,CACrF,OAAO,EAAe,EAAI,GAAsB,CAAuB,CACzE,CAGA,SAAgB,EAAkB,EAAyB,QAAQ,IAAa,CAC9E,OAAO,EAAe,EAAI,GAAuB,CAAwB,CAC3E,CAGA,SAAgB,EAAe,EAAyB,QAAQ,IAAa,CAC3E,OAAO,EAAe,EAAI,GAAoB,CAAqB,CACrE,CAGA,SAAgB,EAAY,EAAyB,QAAQ,IAAa,CACxE,OAAO,EAAe,EAAI,GAAiB,CAAkB,CAC/D"}
@@ -0,0 +1,32 @@
1
+ //#region src/types/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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.cts","names":[],"sources":["../../src/types/config.ts"],"mappings":";;;;;;;cAOa;cACA;cACA;cACA;;cAEA;;cAGA;;cAEA;;cAEA;;cAEA;;iBAQG,yBAAyB,MAAK,OAAO;;iBAKrC,kBAAkB,MAAK,OAAO;;iBAK9B,eAAe,MAAK,OAAO;;iBAK3B,YAAY,MAAK,OAAO"}
@@ -0,0 +1,32 @@
1
+ //#region src/types/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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.mts","names":[],"sources":["../../src/types/config.ts"],"mappings":";;;;;;;cAOa;cACA;cACA;cACA;;cAEA;;cAGA;;cAEA;;cAEA;;cAEA;;iBAQG,yBAAyB,MAAK,OAAO;;iBAKrC,kBAAkB,MAAK,OAAO;;iBAK9B,eAAe,MAAK,OAAO;;iBAK3B,YAAY,MAAK,OAAO"}
@@ -0,0 +1,2 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.mjs","names":[],"sources":["../../src/types/config.ts"],"sourcesContent":["/**\n * Extension configuration, read from the environment.\n *\n * Env rather than a config file, matching doom-task: doom-pi already carries\n * per-launch state to Pi through env vars.\n */\n\nexport const BG_THRESHOLD_MS_ENV = 'DOOM_RUNNER_BG_THRESHOLD_MS';\nexport const RESULT_MAX_BYTES_ENV = 'DOOM_RUNNER_RESULT_MAX_BYTES';\nexport const LOG_MAX_BYTES_ENV = 'DOOM_RUNNER_LOG_MAX_BYTES';\nexport const LOG_TTL_MS_ENV = 'DOOM_RUNNER_LOG_TTL_MS';\n/** Unscoped override for the runner log directory. */\nexport const LOG_DIR_ENV = 'DOOM_RUNNER_LOG_DIR';\n\n/** A bash call still running at this point is promoted to a named runner. */\nexport const DEFAULT_BG_THRESHOLD_MS = 60_000;\n/** Tool results past this size are tail-truncated and spilled to the log file. */\nexport const DEFAULT_RESULT_MAX_BYTES = 51_200;\n/** A runner log rotates once to `.log.1` at this size. */\nexport const DEFAULT_LOG_MAX_BYTES = 5 * 1024 * 1024;\n/** Retention window for logs with no live registry record. */\nexport const DEFAULT_LOG_TTL_MS = 7 * 24 * 60 * 60 * 1000;\n\nfunction positiveNumber(raw: string | undefined, fallback: number): number {\n const value = Number(raw);\n return Number.isFinite(value) && value > 0 ? value : fallback;\n}\n\n/** Age at which a bash call becomes a background runner. */\nexport function getBackgroundThresholdMs(env: NodeJS.ProcessEnv = process.env): number {\n return positiveNumber(env[BG_THRESHOLD_MS_ENV], DEFAULT_BG_THRESHOLD_MS);\n}\n\n/** Byte ceiling for a single tool result before tail truncation kicks in. */\nexport function getResultMaxBytes(env: NodeJS.ProcessEnv = process.env): number {\n return positiveNumber(env[RESULT_MAX_BYTES_ENV], DEFAULT_RESULT_MAX_BYTES);\n}\n\n/** Byte ceiling for a runner log before it rotates. */\nexport function getLogMaxBytes(env: NodeJS.ProcessEnv = process.env): number {\n return positiveNumber(env[LOG_MAX_BYTES_ENV], DEFAULT_LOG_MAX_BYTES);\n}\n\n/** Retention window for orphaned runner logs. */\nexport function getLogTtlMs(env: NodeJS.ProcessEnv = process.env): number {\n return positiveNumber(env[LOG_TTL_MS_ENV], DEFAULT_LOG_TTL_MS);\n}\n"],"mappings":"AAOA,MAAa,EAAsB,8BACtB,EAAuB,+BACvB,EAAoB,4BACpB,EAAiB,yBAEjB,EAAc,sBAGd,EAA0B,IAE1B,EAA2B,MAE3B,EAAwB,QAExB,EAAqB,OAElC,SAAS,EAAe,EAAyB,EAA0B,CACzE,IAAM,EAAQ,OAAO,CAAG,EACxB,OAAO,OAAO,SAAS,CAAK,GAAK,EAAQ,EAAI,EAAQ,CACvD,CAGA,SAAgB,EAAyB,EAAyB,QAAQ,IAAa,CACrF,OAAO,EAAe,EAAI,GAAsB,CAAuB,CACzE,CAGA,SAAgB,EAAkB,EAAyB,QAAQ,IAAa,CAC9E,OAAO,EAAe,EAAI,GAAuB,CAAwB,CAC3E,CAGA,SAAgB,EAAe,EAAyB,QAAQ,IAAa,CAC3E,OAAO,EAAe,EAAI,GAAoB,CAAqB,CACrE,CAGA,SAAgB,EAAY,EAAyB,QAAQ,IAAa,CACxE,OAAO,EAAe,EAAI,GAAiB,CAAkB,CAC/D"}
@@ -0,0 +1,2 @@
1
+ const e={Clock:Symbol.for(`doom-runner:Clock`),Spawner:Symbol.for(`doom-runner:Spawner`),ProcessControl:Symbol.for(`doom-runner:ProcessControl`),PtySpawner:Symbol.for(`doom-runner:PtySpawner`),ProcessRegistry:Symbol.for(`doom-runner:ProcessRegistry`),RunnerPaths:Symbol.for(`doom-runner:RunnerPaths`),Lifeline:Symbol.for(`doom-runner:Lifeline`),RunnerRegistry:Symbol.for(`doom-runner:RunnerRegistry`),RunnerNamer:Symbol.for(`doom-runner:RunnerNamer`),LogFile:Symbol.for(`doom-runner:LogFile`),LogReader:Symbol.for(`doom-runner:LogReader`),Launcher:Symbol.for(`doom-runner:Launcher`),RmuxBackend:Symbol.for(`doom-runner:RmuxBackend`),PtyHost:Symbol.for(`doom-runner:PtyHost`),BashRunService:Symbol.for(`doom-runner:BashRunService`)};exports.TYPES=e;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../src/types/index.ts"],"sourcesContent":["/**\n * Inversify binding keys.\n *\n * `Symbol.for` is a process-global registry, so every key is namespaced to\n * avoid colliding with the containers of other extensions loaded into the same\n * pi process.\n */\nexport const TYPES = {\n Clock: Symbol.for('doom-runner:Clock'),\n Spawner: Symbol.for('doom-runner:Spawner'),\n ProcessControl: Symbol.for('doom-runner:ProcessControl'),\n PtySpawner: Symbol.for('doom-runner:PtySpawner'),\n ProcessRegistry: Symbol.for('doom-runner:ProcessRegistry'),\n RunnerPaths: Symbol.for('doom-runner:RunnerPaths'),\n Lifeline: Symbol.for('doom-runner:Lifeline'),\n RunnerRegistry: Symbol.for('doom-runner:RunnerRegistry'),\n RunnerNamer: Symbol.for('doom-runner:RunnerNamer'),\n LogFile: Symbol.for('doom-runner:LogFile'),\n LogReader: Symbol.for('doom-runner:LogReader'),\n Launcher: Symbol.for('doom-runner:Launcher'),\n RmuxBackend: Symbol.for('doom-runner:RmuxBackend'),\n PtyHost: Symbol.for('doom-runner:PtyHost'),\n BashRunService: Symbol.for('doom-runner:BashRunService'),\n} as const;\n"],"mappings":"AAOA,MAAa,EAAQ,CACnB,MAAO,OAAO,IAAI,mBAAmB,EACrC,QAAS,OAAO,IAAI,qBAAqB,EACzC,eAAgB,OAAO,IAAI,4BAA4B,EACvD,WAAY,OAAO,IAAI,wBAAwB,EAC/C,gBAAiB,OAAO,IAAI,6BAA6B,EACzD,YAAa,OAAO,IAAI,yBAAyB,EACjD,SAAU,OAAO,IAAI,sBAAsB,EAC3C,eAAgB,OAAO,IAAI,4BAA4B,EACvD,YAAa,OAAO,IAAI,yBAAyB,EACjD,QAAS,OAAO,IAAI,qBAAqB,EACzC,UAAW,OAAO,IAAI,uBAAuB,EAC7C,SAAU,OAAO,IAAI,sBAAsB,EAC3C,YAAa,OAAO,IAAI,yBAAyB,EACjD,QAAS,OAAO,IAAI,qBAAqB,EACzC,eAAgB,OAAO,IAAI,4BAA4B,CACzD"}
@@ -0,0 +1,28 @@
1
+ //#region src/types/index.d.ts
2
+ /**
3
+ * Inversify binding keys.
4
+ *
5
+ * `Symbol.for` is a process-global registry, so every key is namespaced to
6
+ * avoid colliding with the containers of other extensions loaded into the same
7
+ * pi process.
8
+ */
9
+ declare const TYPES: {
10
+ readonly Clock: symbol;
11
+ readonly Spawner: symbol;
12
+ readonly ProcessControl: symbol;
13
+ readonly PtySpawner: symbol;
14
+ readonly ProcessRegistry: symbol;
15
+ readonly RunnerPaths: symbol;
16
+ readonly Lifeline: symbol;
17
+ readonly RunnerRegistry: symbol;
18
+ readonly RunnerNamer: symbol;
19
+ readonly LogFile: symbol;
20
+ readonly LogReader: symbol;
21
+ readonly Launcher: symbol;
22
+ readonly RmuxBackend: symbol;
23
+ readonly PtyHost: symbol;
24
+ readonly BashRunService: symbol;
25
+ };
26
+ //#endregion
27
+ export { TYPES };
28
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/types/index.ts"],"mappings":";;;;;;;;cAOa"}
@@ -0,0 +1,28 @@
1
+ //#region src/types/index.d.ts
2
+ /**
3
+ * Inversify binding keys.
4
+ *
5
+ * `Symbol.for` is a process-global registry, so every key is namespaced to
6
+ * avoid colliding with the containers of other extensions loaded into the same
7
+ * pi process.
8
+ */
9
+ declare const TYPES: {
10
+ readonly Clock: symbol;
11
+ readonly Spawner: symbol;
12
+ readonly ProcessControl: symbol;
13
+ readonly PtySpawner: symbol;
14
+ readonly ProcessRegistry: symbol;
15
+ readonly RunnerPaths: symbol;
16
+ readonly Lifeline: symbol;
17
+ readonly RunnerRegistry: symbol;
18
+ readonly RunnerNamer: symbol;
19
+ readonly LogFile: symbol;
20
+ readonly LogReader: symbol;
21
+ readonly Launcher: symbol;
22
+ readonly RmuxBackend: symbol;
23
+ readonly PtyHost: symbol;
24
+ readonly BashRunService: symbol;
25
+ };
26
+ //#endregion
27
+ export { TYPES };
28
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/types/index.ts"],"mappings":";;;;;;;;cAOa"}
@@ -0,0 +1,2 @@
1
+ const e={Clock:Symbol.for(`doom-runner:Clock`),Spawner:Symbol.for(`doom-runner:Spawner`),ProcessControl:Symbol.for(`doom-runner:ProcessControl`),PtySpawner:Symbol.for(`doom-runner:PtySpawner`),ProcessRegistry:Symbol.for(`doom-runner:ProcessRegistry`),RunnerPaths:Symbol.for(`doom-runner:RunnerPaths`),Lifeline:Symbol.for(`doom-runner:Lifeline`),RunnerRegistry:Symbol.for(`doom-runner:RunnerRegistry`),RunnerNamer:Symbol.for(`doom-runner:RunnerNamer`),LogFile:Symbol.for(`doom-runner:LogFile`),LogReader:Symbol.for(`doom-runner:LogReader`),Launcher:Symbol.for(`doom-runner:Launcher`),RmuxBackend:Symbol.for(`doom-runner:RmuxBackend`),PtyHost:Symbol.for(`doom-runner:PtyHost`),BashRunService:Symbol.for(`doom-runner:BashRunService`)};export{e as TYPES};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/types/index.ts"],"sourcesContent":["/**\n * Inversify binding keys.\n *\n * `Symbol.for` is a process-global registry, so every key is namespaced to\n * avoid colliding with the containers of other extensions loaded into the same\n * pi process.\n */\nexport const TYPES = {\n Clock: Symbol.for('doom-runner:Clock'),\n Spawner: Symbol.for('doom-runner:Spawner'),\n ProcessControl: Symbol.for('doom-runner:ProcessControl'),\n PtySpawner: Symbol.for('doom-runner:PtySpawner'),\n ProcessRegistry: Symbol.for('doom-runner:ProcessRegistry'),\n RunnerPaths: Symbol.for('doom-runner:RunnerPaths'),\n Lifeline: Symbol.for('doom-runner:Lifeline'),\n RunnerRegistry: Symbol.for('doom-runner:RunnerRegistry'),\n RunnerNamer: Symbol.for('doom-runner:RunnerNamer'),\n LogFile: Symbol.for('doom-runner:LogFile'),\n LogReader: Symbol.for('doom-runner:LogReader'),\n Launcher: Symbol.for('doom-runner:Launcher'),\n RmuxBackend: Symbol.for('doom-runner:RmuxBackend'),\n PtyHost: Symbol.for('doom-runner:PtyHost'),\n BashRunService: Symbol.for('doom-runner:BashRunService'),\n} as const;\n"],"mappings":"AAOA,MAAa,EAAQ,CACnB,MAAO,OAAO,IAAI,mBAAmB,EACrC,QAAS,OAAO,IAAI,qBAAqB,EACzC,eAAgB,OAAO,IAAI,4BAA4B,EACvD,WAAY,OAAO,IAAI,wBAAwB,EAC/C,gBAAiB,OAAO,IAAI,6BAA6B,EACzD,YAAa,OAAO,IAAI,yBAAyB,EACjD,SAAU,OAAO,IAAI,sBAAsB,EAC3C,eAAgB,OAAO,IAAI,4BAA4B,EACvD,YAAa,OAAO,IAAI,yBAAyB,EACjD,QAAS,OAAO,IAAI,qBAAqB,EACzC,UAAW,OAAO,IAAI,uBAAuB,EAC7C,SAAU,OAAO,IAAI,sBAAsB,EAC3C,YAAa,OAAO,IAAI,yBAAyB,EACjD,QAAS,OAAO,IAAI,qBAAqB,EACzC,eAAgB,OAAO,IAAI,4BAA4B,CACzD"}
package/dist/types.cjs CHANGED
@@ -1,2 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e={Clock:Symbol.for(`doom-runner:Clock`),Spawner:Symbol.for(`doom-runner:Spawner`),ProcessControl:Symbol.for(`doom-runner:ProcessControl`),PtySpawner:Symbol.for(`doom-runner:PtySpawner`),ProcessRegistry:Symbol.for(`doom-runner:ProcessRegistry`),RunnerPaths:Symbol.for(`doom-runner:RunnerPaths`),Lifeline:Symbol.for(`doom-runner:Lifeline`),RunnerRegistry:Symbol.for(`doom-runner:RunnerRegistry`),RunnerNamer:Symbol.for(`doom-runner:RunnerNamer`),LogFile:Symbol.for(`doom-runner:LogFile`),LogReader:Symbol.for(`doom-runner:LogReader`),Launcher:Symbol.for(`doom-runner:Launcher`),RmuxBackend:Symbol.for(`doom-runner:RmuxBackend`),PtyHost:Symbol.for(`doom-runner:PtyHost`),BashRunService:Symbol.for(`doom-runner:BashRunService`)};exports.TYPES=e;
2
- //# sourceMappingURL=types.cjs.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./types/index.cjs");exports.TYPES=e.TYPES;
package/dist/types.d.cts CHANGED
@@ -1,28 +1,2 @@
1
- //#region src/types.d.ts
2
- /**
3
- * Inversify binding keys.
4
- *
5
- * `Symbol.for` is a process-global registry, so every key is namespaced to
6
- * avoid colliding with the containers of other extensions loaded into the same
7
- * pi process.
8
- */
9
- declare const TYPES: {
10
- readonly Clock: symbol;
11
- readonly Spawner: symbol;
12
- readonly ProcessControl: symbol;
13
- readonly PtySpawner: symbol;
14
- readonly ProcessRegistry: symbol;
15
- readonly RunnerPaths: symbol;
16
- readonly Lifeline: symbol;
17
- readonly RunnerRegistry: symbol;
18
- readonly RunnerNamer: symbol;
19
- readonly LogFile: symbol;
20
- readonly LogReader: symbol;
21
- readonly Launcher: symbol;
22
- readonly RmuxBackend: symbol;
23
- readonly PtyHost: symbol;
24
- readonly BashRunService: symbol;
25
- };
26
- //#endregion
27
- export { TYPES };
28
- //# sourceMappingURL=types.d.cts.map
1
+ import { TYPES } from "./types/index.cjs";
2
+ export { TYPES };
package/dist/types.d.mts CHANGED
@@ -1,28 +1,2 @@
1
- //#region src/types.d.ts
2
- /**
3
- * Inversify binding keys.
4
- *
5
- * `Symbol.for` is a process-global registry, so every key is namespaced to
6
- * avoid colliding with the containers of other extensions loaded into the same
7
- * pi process.
8
- */
9
- declare const TYPES: {
10
- readonly Clock: symbol;
11
- readonly Spawner: symbol;
12
- readonly ProcessControl: symbol;
13
- readonly PtySpawner: symbol;
14
- readonly ProcessRegistry: symbol;
15
- readonly RunnerPaths: symbol;
16
- readonly Lifeline: symbol;
17
- readonly RunnerRegistry: symbol;
18
- readonly RunnerNamer: symbol;
19
- readonly LogFile: symbol;
20
- readonly LogReader: symbol;
21
- readonly Launcher: symbol;
22
- readonly RmuxBackend: symbol;
23
- readonly PtyHost: symbol;
24
- readonly BashRunService: symbol;
25
- };
26
- //#endregion
27
- export { TYPES };
28
- //# sourceMappingURL=types.d.mts.map
1
+ import { TYPES } from "./types/index.mjs";
2
+ export { TYPES };
package/dist/types.mjs CHANGED
@@ -1,2 +1 @@
1
- const e={Clock:Symbol.for(`doom-runner:Clock`),Spawner:Symbol.for(`doom-runner:Spawner`),ProcessControl:Symbol.for(`doom-runner:ProcessControl`),PtySpawner:Symbol.for(`doom-runner:PtySpawner`),ProcessRegistry:Symbol.for(`doom-runner:ProcessRegistry`),RunnerPaths:Symbol.for(`doom-runner:RunnerPaths`),Lifeline:Symbol.for(`doom-runner:Lifeline`),RunnerRegistry:Symbol.for(`doom-runner:RunnerRegistry`),RunnerNamer:Symbol.for(`doom-runner:RunnerNamer`),LogFile:Symbol.for(`doom-runner:LogFile`),LogReader:Symbol.for(`doom-runner:LogReader`),Launcher:Symbol.for(`doom-runner:Launcher`),RmuxBackend:Symbol.for(`doom-runner:RmuxBackend`),PtyHost:Symbol.for(`doom-runner:PtyHost`),BashRunService:Symbol.for(`doom-runner:BashRunService`)};export{e as TYPES};
2
- //# sourceMappingURL=types.mjs.map
1
+ import{TYPES as e}from"./types/index.mjs";export{e as TYPES};