night-orch 0.1.0

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 (911) hide show
  1. package/README.md +138 -0
  2. package/dist/cli/commands/cleanup.d.ts +14 -0
  3. package/dist/cli/commands/cleanup.d.ts.map +1 -0
  4. package/dist/cli/commands/cleanup.js +62 -0
  5. package/dist/cli/commands/cleanup.js.map +1 -0
  6. package/dist/cli/commands/continue.d.ts +9 -0
  7. package/dist/cli/commands/continue.d.ts.map +1 -0
  8. package/dist/cli/commands/continue.js +70 -0
  9. package/dist/cli/commands/continue.js.map +1 -0
  10. package/dist/cli/commands/cost-override.d.ts +11 -0
  11. package/dist/cli/commands/cost-override.d.ts.map +1 -0
  12. package/dist/cli/commands/cost-override.js +76 -0
  13. package/dist/cli/commands/cost-override.js.map +1 -0
  14. package/dist/cli/commands/daily-cost-override.d.ts +11 -0
  15. package/dist/cli/commands/daily-cost-override.d.ts.map +1 -0
  16. package/dist/cli/commands/daily-cost-override.js +71 -0
  17. package/dist/cli/commands/daily-cost-override.js.map +1 -0
  18. package/dist/cli/commands/delete-entry.d.ts +12 -0
  19. package/dist/cli/commands/delete-entry.d.ts.map +1 -0
  20. package/dist/cli/commands/delete-entry.js +68 -0
  21. package/dist/cli/commands/delete-entry.js.map +1 -0
  22. package/dist/cli/commands/doctor.d.ts +9 -0
  23. package/dist/cli/commands/doctor.d.ts.map +1 -0
  24. package/dist/cli/commands/doctor.js +227 -0
  25. package/dist/cli/commands/doctor.js.map +1 -0
  26. package/dist/cli/commands/init.d.ts +2 -0
  27. package/dist/cli/commands/init.d.ts.map +1 -0
  28. package/dist/cli/commands/init.js +73 -0
  29. package/dist/cli/commands/init.js.map +1 -0
  30. package/dist/cli/commands/labels-init.d.ts +9 -0
  31. package/dist/cli/commands/labels-init.d.ts.map +1 -0
  32. package/dist/cli/commands/labels-init.js +52 -0
  33. package/dist/cli/commands/labels-init.js.map +1 -0
  34. package/dist/cli/commands/mcp.d.ts +9 -0
  35. package/dist/cli/commands/mcp.d.ts.map +1 -0
  36. package/dist/cli/commands/mcp.js +52 -0
  37. package/dist/cli/commands/mcp.js.map +1 -0
  38. package/dist/cli/commands/monitoring-init.d.ts +2 -0
  39. package/dist/cli/commands/monitoring-init.d.ts.map +1 -0
  40. package/dist/cli/commands/monitoring-init.js +43 -0
  41. package/dist/cli/commands/monitoring-init.js.map +1 -0
  42. package/dist/cli/commands/notify-test.d.ts +9 -0
  43. package/dist/cli/commands/notify-test.d.ts.map +1 -0
  44. package/dist/cli/commands/notify-test.js +41 -0
  45. package/dist/cli/commands/notify-test.js.map +1 -0
  46. package/dist/cli/commands/rebase.d.ts +9 -0
  47. package/dist/cli/commands/rebase.d.ts.map +1 -0
  48. package/dist/cli/commands/rebase.js +63 -0
  49. package/dist/cli/commands/rebase.js.map +1 -0
  50. package/dist/cli/commands/retry.d.ts +14 -0
  51. package/dist/cli/commands/retry.d.ts.map +1 -0
  52. package/dist/cli/commands/retry.js +52 -0
  53. package/dist/cli/commands/retry.js.map +1 -0
  54. package/dist/cli/commands/run-once.d.ts +9 -0
  55. package/dist/cli/commands/run-once.d.ts.map +1 -0
  56. package/dist/cli/commands/run-once.js +62 -0
  57. package/dist/cli/commands/run-once.js.map +1 -0
  58. package/dist/cli/commands/run.d.ts +9 -0
  59. package/dist/cli/commands/run.d.ts.map +1 -0
  60. package/dist/cli/commands/run.js +142 -0
  61. package/dist/cli/commands/run.js.map +1 -0
  62. package/dist/cli/commands/serve.d.ts +14 -0
  63. package/dist/cli/commands/serve.d.ts.map +1 -0
  64. package/dist/cli/commands/serve.js +51 -0
  65. package/dist/cli/commands/serve.js.map +1 -0
  66. package/dist/cli/commands/settings.d.ts +10 -0
  67. package/dist/cli/commands/settings.d.ts.map +1 -0
  68. package/dist/cli/commands/settings.js +100 -0
  69. package/dist/cli/commands/settings.js.map +1 -0
  70. package/dist/cli/commands/status.d.ts +8 -0
  71. package/dist/cli/commands/status.d.ts.map +1 -0
  72. package/dist/cli/commands/status.js +153 -0
  73. package/dist/cli/commands/status.js.map +1 -0
  74. package/dist/cli/commands/sync.d.ts +9 -0
  75. package/dist/cli/commands/sync.d.ts.map +1 -0
  76. package/dist/cli/commands/sync.js +60 -0
  77. package/dist/cli/commands/sync.js.map +1 -0
  78. package/dist/cli/commands/update.d.ts +4 -0
  79. package/dist/cli/commands/update.d.ts.map +1 -0
  80. package/dist/cli/commands/update.js +29 -0
  81. package/dist/cli/commands/update.js.map +1 -0
  82. package/dist/cli/commands/watch.d.ts +9 -0
  83. package/dist/cli/commands/watch.d.ts.map +1 -0
  84. package/dist/cli/commands/watch.js +56 -0
  85. package/dist/cli/commands/watch.js.map +1 -0
  86. package/dist/cli/commands/web.d.ts +16 -0
  87. package/dist/cli/commands/web.d.ts.map +1 -0
  88. package/dist/cli/commands/web.js +206 -0
  89. package/dist/cli/commands/web.js.map +1 -0
  90. package/dist/cli/index.d.ts +3 -0
  91. package/dist/cli/index.d.ts.map +1 -0
  92. package/dist/cli/index.js +213 -0
  93. package/dist/cli/index.js.map +1 -0
  94. package/dist/cli/init/detector.d.ts +7 -0
  95. package/dist/cli/init/detector.d.ts.map +1 -0
  96. package/dist/cli/init/detector.js +40 -0
  97. package/dist/cli/init/detector.js.map +1 -0
  98. package/dist/cli/init/templates.d.ts +10 -0
  99. package/dist/cli/init/templates.d.ts.map +1 -0
  100. package/dist/cli/init/templates.js +30 -0
  101. package/dist/cli/init/templates.js.map +1 -0
  102. package/dist/cli/tui/actions-bar.d.ts +21 -0
  103. package/dist/cli/tui/actions-bar.d.ts.map +1 -0
  104. package/dist/cli/tui/actions-bar.js +91 -0
  105. package/dist/cli/tui/actions-bar.js.map +1 -0
  106. package/dist/cli/tui/active-runs.d.ts +9 -0
  107. package/dist/cli/tui/active-runs.d.ts.map +1 -0
  108. package/dist/cli/tui/active-runs.js +23 -0
  109. package/dist/cli/tui/active-runs.js.map +1 -0
  110. package/dist/cli/tui/agent-stream.d.ts +10 -0
  111. package/dist/cli/tui/agent-stream.d.ts.map +1 -0
  112. package/dist/cli/tui/agent-stream.js +83 -0
  113. package/dist/cli/tui/agent-stream.js.map +1 -0
  114. package/dist/cli/tui/app.d.ts +40 -0
  115. package/dist/cli/tui/app.d.ts.map +1 -0
  116. package/dist/cli/tui/app.js +995 -0
  117. package/dist/cli/tui/app.js.map +1 -0
  118. package/dist/cli/tui/constants.d.ts +15 -0
  119. package/dist/cli/tui/constants.d.ts.map +1 -0
  120. package/dist/cli/tui/constants.js +102 -0
  121. package/dist/cli/tui/constants.js.map +1 -0
  122. package/dist/cli/tui/cost-bar.d.ts +10 -0
  123. package/dist/cli/tui/cost-bar.d.ts.map +1 -0
  124. package/dist/cli/tui/cost-bar.js +17 -0
  125. package/dist/cli/tui/cost-bar.js.map +1 -0
  126. package/dist/cli/tui/data.d.ts +56 -0
  127. package/dist/cli/tui/data.d.ts.map +1 -0
  128. package/dist/cli/tui/data.js +296 -0
  129. package/dist/cli/tui/data.js.map +1 -0
  130. package/dist/cli/tui/format.d.ts +11 -0
  131. package/dist/cli/tui/format.d.ts.map +1 -0
  132. package/dist/cli/tui/format.js +83 -0
  133. package/dist/cli/tui/format.js.map +1 -0
  134. package/dist/cli/tui/header.d.ts +16 -0
  135. package/dist/cli/tui/header.d.ts.map +1 -0
  136. package/dist/cli/tui/header.js +22 -0
  137. package/dist/cli/tui/header.js.map +1 -0
  138. package/dist/cli/tui/logs-view.d.ts +19 -0
  139. package/dist/cli/tui/logs-view.d.ts.map +1 -0
  140. package/dist/cli/tui/logs-view.js +63 -0
  141. package/dist/cli/tui/logs-view.js.map +1 -0
  142. package/dist/cli/tui/merge-queue-panel.d.ts +9 -0
  143. package/dist/cli/tui/merge-queue-panel.d.ts.map +1 -0
  144. package/dist/cli/tui/merge-queue-panel.js +14 -0
  145. package/dist/cli/tui/merge-queue-panel.js.map +1 -0
  146. package/dist/cli/tui/projects-view.d.ts +25 -0
  147. package/dist/cli/tui/projects-view.d.ts.map +1 -0
  148. package/dist/cli/tui/projects-view.js +145 -0
  149. package/dist/cli/tui/projects-view.js.map +1 -0
  150. package/dist/cli/tui/recent-runs.d.ts +9 -0
  151. package/dist/cli/tui/recent-runs.d.ts.map +1 -0
  152. package/dist/cli/tui/recent-runs.js +20 -0
  153. package/dist/cli/tui/recent-runs.js.map +1 -0
  154. package/dist/cli/tui/runs-view.d.ts +22 -0
  155. package/dist/cli/tui/runs-view.d.ts.map +1 -0
  156. package/dist/cli/tui/runs-view.js +48 -0
  157. package/dist/cli/tui/runs-view.js.map +1 -0
  158. package/dist/cli/tui/settings-view.d.ts +9 -0
  159. package/dist/cli/tui/settings-view.d.ts.map +1 -0
  160. package/dist/cli/tui/settings-view.js +21 -0
  161. package/dist/cli/tui/settings-view.js.map +1 -0
  162. package/dist/cli/tui/stats-view.d.ts +11 -0
  163. package/dist/cli/tui/stats-view.d.ts.map +1 -0
  164. package/dist/cli/tui/stats-view.js +48 -0
  165. package/dist/cli/tui/stats-view.js.map +1 -0
  166. package/dist/cli/tui/titles.d.ts +36 -0
  167. package/dist/cli/tui/titles.d.ts.map +1 -0
  168. package/dist/cli/tui/titles.js +50 -0
  169. package/dist/cli/tui/titles.js.map +1 -0
  170. package/dist/cli/tui/types.d.ts +10 -0
  171. package/dist/cli/tui/types.d.ts.map +1 -0
  172. package/dist/cli/tui/types.js +2 -0
  173. package/dist/cli/tui/types.js.map +1 -0
  174. package/dist/cli/tui/view-model.d.ts +20 -0
  175. package/dist/cli/tui/view-model.d.ts.map +1 -0
  176. package/dist/cli/tui/view-model.js +80 -0
  177. package/dist/cli/tui/view-model.js.map +1 -0
  178. package/dist/components/button/button.tui.d.ts +4 -0
  179. package/dist/components/button/button.tui.d.ts.map +1 -0
  180. package/dist/components/button/button.tui.js +16 -0
  181. package/dist/components/button/button.tui.js.map +1 -0
  182. package/dist/components/button/button.web.d.ts +4 -0
  183. package/dist/components/button/button.web.d.ts.map +1 -0
  184. package/dist/components/button/button.web.js +7 -0
  185. package/dist/components/button/button.web.js.map +1 -0
  186. package/dist/components/button/index.d.ts +5 -0
  187. package/dist/components/button/index.d.ts.map +1 -0
  188. package/dist/components/button/index.js +4 -0
  189. package/dist/components/button/index.js.map +1 -0
  190. package/dist/components/button/types.d.ts +28 -0
  191. package/dist/components/button/types.d.ts.map +1 -0
  192. package/dist/components/button/types.js +2 -0
  193. package/dist/components/button/types.js.map +1 -0
  194. package/dist/components/button/view-model.d.ts +3 -0
  195. package/dist/components/button/view-model.d.ts.map +1 -0
  196. package/dist/components/button/view-model.js +53 -0
  197. package/dist/components/button/view-model.js.map +1 -0
  198. package/dist/components/card/card.tui.d.ts +4 -0
  199. package/dist/components/card/card.tui.d.ts.map +1 -0
  200. package/dist/components/card/card.tui.js +41 -0
  201. package/dist/components/card/card.tui.js.map +1 -0
  202. package/dist/components/card/card.web.d.ts +4 -0
  203. package/dist/components/card/card.web.d.ts.map +1 -0
  204. package/dist/components/card/card.web.js +12 -0
  205. package/dist/components/card/card.web.js.map +1 -0
  206. package/dist/components/card/index.d.ts +5 -0
  207. package/dist/components/card/index.d.ts.map +1 -0
  208. package/dist/components/card/index.js +4 -0
  209. package/dist/components/card/index.js.map +1 -0
  210. package/dist/components/card/types.d.ts +22 -0
  211. package/dist/components/card/types.d.ts.map +1 -0
  212. package/dist/components/card/types.js +2 -0
  213. package/dist/components/card/types.js.map +1 -0
  214. package/dist/components/card/view-model.d.ts +3 -0
  215. package/dist/components/card/view-model.d.ts.map +1 -0
  216. package/dist/components/card/view-model.js +35 -0
  217. package/dist/components/card/view-model.js.map +1 -0
  218. package/dist/components/index.d.ts +5 -0
  219. package/dist/components/index.d.ts.map +1 -0
  220. package/dist/components/index.js +5 -0
  221. package/dist/components/index.js.map +1 -0
  222. package/dist/components/issue-row/index.d.ts +5 -0
  223. package/dist/components/issue-row/index.d.ts.map +1 -0
  224. package/dist/components/issue-row/index.js +4 -0
  225. package/dist/components/issue-row/index.js.map +1 -0
  226. package/dist/components/issue-row/issue-row.tui.d.ts +4 -0
  227. package/dist/components/issue-row/issue-row.tui.d.ts.map +1 -0
  228. package/dist/components/issue-row/issue-row.tui.js +15 -0
  229. package/dist/components/issue-row/issue-row.tui.js.map +1 -0
  230. package/dist/components/issue-row/issue-row.web.d.ts +4 -0
  231. package/dist/components/issue-row/issue-row.web.d.ts.map +1 -0
  232. package/dist/components/issue-row/issue-row.web.js +14 -0
  233. package/dist/components/issue-row/issue-row.web.js.map +1 -0
  234. package/dist/components/issue-row/types.d.ts +18 -0
  235. package/dist/components/issue-row/types.d.ts.map +1 -0
  236. package/dist/components/issue-row/types.js +2 -0
  237. package/dist/components/issue-row/types.js.map +1 -0
  238. package/dist/components/issue-row/view-model.d.ts +3 -0
  239. package/dist/components/issue-row/view-model.d.ts.map +1 -0
  240. package/dist/components/issue-row/view-model.js +31 -0
  241. package/dist/components/issue-row/view-model.js.map +1 -0
  242. package/dist/components/modal/index.d.ts +3 -0
  243. package/dist/components/modal/index.d.ts.map +1 -0
  244. package/dist/components/modal/index.js +2 -0
  245. package/dist/components/modal/index.js.map +1 -0
  246. package/dist/components/modal/modal.web.d.ts +16 -0
  247. package/dist/components/modal/modal.web.d.ts.map +1 -0
  248. package/dist/components/modal/modal.web.js +92 -0
  249. package/dist/components/modal/modal.web.js.map +1 -0
  250. package/dist/components/modal/types.d.ts +15 -0
  251. package/dist/components/modal/types.d.ts.map +1 -0
  252. package/dist/components/modal/types.js +2 -0
  253. package/dist/components/modal/types.js.map +1 -0
  254. package/dist/config/loader.d.ts +23 -0
  255. package/dist/config/loader.d.ts.map +1 -0
  256. package/dist/config/loader.js +136 -0
  257. package/dist/config/loader.js.map +1 -0
  258. package/dist/config/paths.d.ts +6 -0
  259. package/dist/config/paths.d.ts.map +1 -0
  260. package/dist/config/paths.js +24 -0
  261. package/dist/config/paths.js.map +1 -0
  262. package/dist/config/schema.d.ts +3088 -0
  263. package/dist/config/schema.d.ts.map +1 -0
  264. package/dist/config/schema.js +328 -0
  265. package/dist/config/schema.js.map +1 -0
  266. package/dist/discovery/commands.d.ts +33 -0
  267. package/dist/discovery/commands.d.ts.map +1 -0
  268. package/dist/discovery/commands.js +82 -0
  269. package/dist/discovery/commands.js.map +1 -0
  270. package/dist/discovery/decomposer.d.ts +6 -0
  271. package/dist/discovery/decomposer.d.ts.map +1 -0
  272. package/dist/discovery/decomposer.js +102 -0
  273. package/dist/discovery/decomposer.js.map +1 -0
  274. package/dist/discovery/discover.d.ts +21 -0
  275. package/dist/discovery/discover.d.ts.map +1 -0
  276. package/dist/discovery/discover.js +98 -0
  277. package/dist/discovery/discover.js.map +1 -0
  278. package/dist/discovery/followup.d.ts +14 -0
  279. package/dist/discovery/followup.d.ts.map +1 -0
  280. package/dist/discovery/followup.js +27 -0
  281. package/dist/discovery/followup.js.map +1 -0
  282. package/dist/discovery/roles.d.ts +15 -0
  283. package/dist/discovery/roles.d.ts.map +1 -0
  284. package/dist/discovery/roles.js +36 -0
  285. package/dist/discovery/roles.js.map +1 -0
  286. package/dist/discovery/selector.d.ts +13 -0
  287. package/dist/discovery/selector.d.ts.map +1 -0
  288. package/dist/discovery/selector.js +27 -0
  289. package/dist/discovery/selector.js.map +1 -0
  290. package/dist/discovery/triage.d.ts +29 -0
  291. package/dist/discovery/triage.d.ts.map +1 -0
  292. package/dist/discovery/triage.js +61 -0
  293. package/dist/discovery/triage.js.map +1 -0
  294. package/dist/environment/bootstrap.d.ts +19 -0
  295. package/dist/environment/bootstrap.d.ts.map +1 -0
  296. package/dist/environment/bootstrap.js +89 -0
  297. package/dist/environment/bootstrap.js.map +1 -0
  298. package/dist/environment/dedicated.d.ts +17 -0
  299. package/dist/environment/dedicated.d.ts.map +1 -0
  300. package/dist/environment/dedicated.js +68 -0
  301. package/dist/environment/dedicated.js.map +1 -0
  302. package/dist/environment/env-file.d.ts +16 -0
  303. package/dist/environment/env-file.d.ts.map +1 -0
  304. package/dist/environment/env-file.js +74 -0
  305. package/dist/environment/env-file.js.map +1 -0
  306. package/dist/environment/manager.d.ts +33 -0
  307. package/dist/environment/manager.d.ts.map +1 -0
  308. package/dist/environment/manager.js +113 -0
  309. package/dist/environment/manager.js.map +1 -0
  310. package/dist/environment/port.d.ts +15 -0
  311. package/dist/environment/port.d.ts.map +1 -0
  312. package/dist/environment/port.js +21 -0
  313. package/dist/environment/port.js.map +1 -0
  314. package/dist/environment/shared.d.ts +6 -0
  315. package/dist/environment/shared.d.ts.map +1 -0
  316. package/dist/environment/shared.js +30 -0
  317. package/dist/environment/shared.js.map +1 -0
  318. package/dist/events/bus.d.ts +18 -0
  319. package/dist/events/bus.d.ts.map +1 -0
  320. package/dist/events/bus.js +70 -0
  321. package/dist/events/bus.js.map +1 -0
  322. package/dist/events/observability.d.ts +32 -0
  323. package/dist/events/observability.d.ts.map +1 -0
  324. package/dist/events/observability.js +155 -0
  325. package/dist/events/observability.js.map +1 -0
  326. package/dist/events/types.d.ts +18 -0
  327. package/dist/events/types.d.ts.map +1 -0
  328. package/dist/events/types.js +2 -0
  329. package/dist/events/types.js.map +1 -0
  330. package/dist/forge/bot-comment.d.ts +17 -0
  331. package/dist/forge/bot-comment.d.ts.map +1 -0
  332. package/dist/forge/bot-comment.js +30 -0
  333. package/dist/forge/bot-comment.js.map +1 -0
  334. package/dist/forge/factory.d.ts +4 -0
  335. package/dist/forge/factory.d.ts.map +1 -0
  336. package/dist/forge/factory.js +31 -0
  337. package/dist/forge/factory.js.map +1 -0
  338. package/dist/forge/forgejo-client.d.ts +20 -0
  339. package/dist/forge/forgejo-client.d.ts.map +1 -0
  340. package/dist/forge/forgejo-client.js +114 -0
  341. package/dist/forge/forgejo-client.js.map +1 -0
  342. package/dist/forge/forgejo-labels.d.ts +13 -0
  343. package/dist/forge/forgejo-labels.d.ts.map +1 -0
  344. package/dist/forge/forgejo-labels.js +51 -0
  345. package/dist/forge/forgejo-labels.js.map +1 -0
  346. package/dist/forge/forgejo.d.ts +31 -0
  347. package/dist/forge/forgejo.d.ts.map +1 -0
  348. package/dist/forge/forgejo.js +264 -0
  349. package/dist/forge/forgejo.js.map +1 -0
  350. package/dist/forge/github.d.ts +31 -0
  351. package/dist/forge/github.d.ts.map +1 -0
  352. package/dist/forge/github.js +438 -0
  353. package/dist/forge/github.js.map +1 -0
  354. package/dist/forge/status-comment.d.ts +19 -0
  355. package/dist/forge/status-comment.d.ts.map +1 -0
  356. package/dist/forge/status-comment.js +44 -0
  357. package/dist/forge/status-comment.js.map +1 -0
  358. package/dist/forge/types.d.ts +118 -0
  359. package/dist/forge/types.d.ts.map +1 -0
  360. package/dist/forge/types.js +2 -0
  361. package/dist/forge/types.js.map +1 -0
  362. package/dist/git/process.d.ts +15 -0
  363. package/dist/git/process.d.ts.map +1 -0
  364. package/dist/git/process.js +38 -0
  365. package/dist/git/process.js.map +1 -0
  366. package/dist/git/repo.d.ts +64 -0
  367. package/dist/git/repo.d.ts.map +1 -0
  368. package/dist/git/repo.js +158 -0
  369. package/dist/git/repo.js.map +1 -0
  370. package/dist/git/slug.d.ts +13 -0
  371. package/dist/git/slug.d.ts.map +1 -0
  372. package/dist/git/slug.js +28 -0
  373. package/dist/git/slug.js.map +1 -0
  374. package/dist/git/worktree.d.ts +23 -0
  375. package/dist/git/worktree.d.ts.map +1 -0
  376. package/dist/git/worktree.js +200 -0
  377. package/dist/git/worktree.js.map +1 -0
  378. package/dist/labels/bootstrap.d.ts +12 -0
  379. package/dist/labels/bootstrap.d.ts.map +1 -0
  380. package/dist/labels/bootstrap.js +101 -0
  381. package/dist/labels/bootstrap.js.map +1 -0
  382. package/dist/labels/config.d.ts +6 -0
  383. package/dist/labels/config.d.ts.map +1 -0
  384. package/dist/labels/config.js +56 -0
  385. package/dist/labels/config.js.map +1 -0
  386. package/dist/labels/manager.d.ts +10 -0
  387. package/dist/labels/manager.d.ts.map +1 -0
  388. package/dist/labels/manager.js +30 -0
  389. package/dist/labels/manager.js.map +1 -0
  390. package/dist/labels/transitions.d.ts +33 -0
  391. package/dist/labels/transitions.d.ts.map +1 -0
  392. package/dist/labels/transitions.js +81 -0
  393. package/dist/labels/transitions.js.map +1 -0
  394. package/dist/loop/checkpoint.d.ts +60 -0
  395. package/dist/loop/checkpoint.d.ts.map +1 -0
  396. package/dist/loop/checkpoint.js +226 -0
  397. package/dist/loop/checkpoint.js.map +1 -0
  398. package/dist/loop/commit.d.ts +17 -0
  399. package/dist/loop/commit.d.ts.map +1 -0
  400. package/dist/loop/commit.js +65 -0
  401. package/dist/loop/commit.js.map +1 -0
  402. package/dist/loop/context.d.ts +11 -0
  403. package/dist/loop/context.d.ts.map +1 -0
  404. package/dist/loop/context.js +26 -0
  405. package/dist/loop/context.js.map +1 -0
  406. package/dist/loop/cost.d.ts +79 -0
  407. package/dist/loop/cost.d.ts.map +1 -0
  408. package/dist/loop/cost.js +223 -0
  409. package/dist/loop/cost.js.map +1 -0
  410. package/dist/loop/decision.d.ts +22 -0
  411. package/dist/loop/decision.d.ts.map +1 -0
  412. package/dist/loop/decision.js +118 -0
  413. package/dist/loop/decision.js.map +1 -0
  414. package/dist/loop/diff-guard.d.ts +21 -0
  415. package/dist/loop/diff-guard.d.ts.map +1 -0
  416. package/dist/loop/diff-guard.js +52 -0
  417. package/dist/loop/diff-guard.js.map +1 -0
  418. package/dist/loop/engine.d.ts +32 -0
  419. package/dist/loop/engine.d.ts.map +1 -0
  420. package/dist/loop/engine.js +376 -0
  421. package/dist/loop/engine.js.map +1 -0
  422. package/dist/loop/parallel.d.ts +20 -0
  423. package/dist/loop/parallel.d.ts.map +1 -0
  424. package/dist/loop/parallel.js +144 -0
  425. package/dist/loop/parallel.js.map +1 -0
  426. package/dist/loop/plan-summary-comment.d.ts +5 -0
  427. package/dist/loop/plan-summary-comment.d.ts.map +1 -0
  428. package/dist/loop/plan-summary-comment.js +89 -0
  429. package/dist/loop/plan-summary-comment.js.map +1 -0
  430. package/dist/loop/pricing.d.ts +23 -0
  431. package/dist/loop/pricing.d.ts.map +1 -0
  432. package/dist/loop/pricing.js +64 -0
  433. package/dist/loop/pricing.js.map +1 -0
  434. package/dist/loop/review-feedback.d.ts +12 -0
  435. package/dist/loop/review-feedback.d.ts.map +1 -0
  436. package/dist/loop/review-feedback.js +55 -0
  437. package/dist/loop/review-feedback.js.map +1 -0
  438. package/dist/loop/step-executor.d.ts +70 -0
  439. package/dist/loop/step-executor.d.ts.map +1 -0
  440. package/dist/loop/step-executor.js +328 -0
  441. package/dist/loop/step-executor.js.map +1 -0
  442. package/dist/loop/supervisor.d.ts +9 -0
  443. package/dist/loop/supervisor.d.ts.map +1 -0
  444. package/dist/loop/supervisor.js +22 -0
  445. package/dist/loop/supervisor.js.map +1 -0
  446. package/dist/loop/types.d.ts +66 -0
  447. package/dist/loop/types.d.ts.map +1 -0
  448. package/dist/loop/types.js +2 -0
  449. package/dist/loop/types.js.map +1 -0
  450. package/dist/loop/verifier.d.ts +9 -0
  451. package/dist/loop/verifier.d.ts.map +1 -0
  452. package/dist/loop/verifier.js +59 -0
  453. package/dist/loop/verifier.js.map +1 -0
  454. package/dist/loop/workflow.d.ts +38 -0
  455. package/dist/loop/workflow.d.ts.map +1 -0
  456. package/dist/loop/workflow.js +64 -0
  457. package/dist/loop/workflow.js.map +1 -0
  458. package/dist/mcp/http.d.ts +8 -0
  459. package/dist/mcp/http.d.ts.map +1 -0
  460. package/dist/mcp/http.js +76 -0
  461. package/dist/mcp/http.js.map +1 -0
  462. package/dist/mcp/resources/index.d.ts +11 -0
  463. package/dist/mcp/resources/index.d.ts.map +1 -0
  464. package/dist/mcp/resources/index.js +137 -0
  465. package/dist/mcp/resources/index.js.map +1 -0
  466. package/dist/mcp/server.d.ts +16 -0
  467. package/dist/mcp/server.d.ts.map +1 -0
  468. package/dist/mcp/server.js +54 -0
  469. package/dist/mcp/server.js.map +1 -0
  470. package/dist/mcp/tools/index.d.ts +19 -0
  471. package/dist/mcp/tools/index.d.ts.map +1 -0
  472. package/dist/mcp/tools/index.js +847 -0
  473. package/dist/mcp/tools/index.js.map +1 -0
  474. package/dist/mentions/manager.d.ts +12 -0
  475. package/dist/mentions/manager.d.ts.map +1 -0
  476. package/dist/mentions/manager.js +50 -0
  477. package/dist/mentions/manager.js.map +1 -0
  478. package/dist/mentions/resolver.d.ts +12 -0
  479. package/dist/mentions/resolver.d.ts.map +1 -0
  480. package/dist/mentions/resolver.js +26 -0
  481. package/dist/mentions/resolver.js.map +1 -0
  482. package/dist/mentions/tracker.d.ts +8 -0
  483. package/dist/mentions/tracker.d.ts.map +1 -0
  484. package/dist/mentions/tracker.js +18 -0
  485. package/dist/mentions/tracker.js.map +1 -0
  486. package/dist/merge-queue/batch.d.ts +19 -0
  487. package/dist/merge-queue/batch.d.ts.map +1 -0
  488. package/dist/merge-queue/batch.js +100 -0
  489. package/dist/merge-queue/batch.js.map +1 -0
  490. package/dist/merge-queue/bisect.d.ts +10 -0
  491. package/dist/merge-queue/bisect.d.ts.map +1 -0
  492. package/dist/merge-queue/bisect.js +18 -0
  493. package/dist/merge-queue/bisect.js.map +1 -0
  494. package/dist/merge-queue/eligibility.d.ts +25 -0
  495. package/dist/merge-queue/eligibility.d.ts.map +1 -0
  496. package/dist/merge-queue/eligibility.js +125 -0
  497. package/dist/merge-queue/eligibility.js.map +1 -0
  498. package/dist/merge-queue/finalize.d.ts +7 -0
  499. package/dist/merge-queue/finalize.d.ts.map +1 -0
  500. package/dist/merge-queue/finalize.js +36 -0
  501. package/dist/merge-queue/finalize.js.map +1 -0
  502. package/dist/merge-queue/runner.d.ts +13 -0
  503. package/dist/merge-queue/runner.d.ts.map +1 -0
  504. package/dist/merge-queue/runner.js +246 -0
  505. package/dist/merge-queue/runner.js.map +1 -0
  506. package/dist/merge-queue/staging.d.ts +13 -0
  507. package/dist/merge-queue/staging.d.ts.map +1 -0
  508. package/dist/merge-queue/staging.js +88 -0
  509. package/dist/merge-queue/staging.js.map +1 -0
  510. package/dist/merge-queue/types.d.ts +23 -0
  511. package/dist/merge-queue/types.d.ts.map +1 -0
  512. package/dist/merge-queue/types.js +2 -0
  513. package/dist/merge-queue/types.js.map +1 -0
  514. package/dist/metrics/collectors.d.ts +24 -0
  515. package/dist/metrics/collectors.d.ts.map +1 -0
  516. package/dist/metrics/collectors.js +132 -0
  517. package/dist/metrics/collectors.js.map +1 -0
  518. package/dist/metrics/server.d.ts +8 -0
  519. package/dist/metrics/server.d.ts.map +1 -0
  520. package/dist/metrics/server.js +41 -0
  521. package/dist/metrics/server.js.map +1 -0
  522. package/dist/metrics/service.d.ts +26 -0
  523. package/dist/metrics/service.d.ts.map +1 -0
  524. package/dist/metrics/service.js +161 -0
  525. package/dist/metrics/service.js.map +1 -0
  526. package/dist/notify/channels/console.d.ts +10 -0
  527. package/dist/notify/channels/console.d.ts.map +1 -0
  528. package/dist/notify/channels/console.js +17 -0
  529. package/dist/notify/channels/console.js.map +1 -0
  530. package/dist/notify/channels/discord.d.ts +13 -0
  531. package/dist/notify/channels/discord.d.ts.map +1 -0
  532. package/dist/notify/channels/discord.js +183 -0
  533. package/dist/notify/channels/discord.js.map +1 -0
  534. package/dist/notify/channels/github-comment.d.ts +13 -0
  535. package/dist/notify/channels/github-comment.d.ts.map +1 -0
  536. package/dist/notify/channels/github-comment.js +52 -0
  537. package/dist/notify/channels/github-comment.js.map +1 -0
  538. package/dist/notify/channels/smtp.d.ts +17 -0
  539. package/dist/notify/channels/smtp.d.ts.map +1 -0
  540. package/dist/notify/channels/smtp.js +65 -0
  541. package/dist/notify/channels/smtp.js.map +1 -0
  542. package/dist/notify/channels/webhook-common.d.ts +19 -0
  543. package/dist/notify/channels/webhook-common.d.ts.map +1 -0
  544. package/dist/notify/channels/webhook-common.js +111 -0
  545. package/dist/notify/channels/webhook-common.js.map +1 -0
  546. package/dist/notify/channels/webhook.d.ts +13 -0
  547. package/dist/notify/channels/webhook.d.ts.map +1 -0
  548. package/dist/notify/channels/webhook.js +72 -0
  549. package/dist/notify/channels/webhook.js.map +1 -0
  550. package/dist/notify/dispatcher.d.ts +11 -0
  551. package/dist/notify/dispatcher.d.ts.map +1 -0
  552. package/dist/notify/dispatcher.js +66 -0
  553. package/dist/notify/dispatcher.js.map +1 -0
  554. package/dist/notify/factory.d.ts +5 -0
  555. package/dist/notify/factory.d.ts.map +1 -0
  556. package/dist/notify/factory.js +46 -0
  557. package/dist/notify/factory.js.map +1 -0
  558. package/dist/notify/payload.d.ts +8 -0
  559. package/dist/notify/payload.d.ts.map +1 -0
  560. package/dist/notify/payload.js +37 -0
  561. package/dist/notify/payload.js.map +1 -0
  562. package/dist/notify/types.d.ts +34 -0
  563. package/dist/notify/types.d.ts.map +1 -0
  564. package/dist/notify/types.js +2 -0
  565. package/dist/notify/types.js.map +1 -0
  566. package/dist/ops/auto-cleanup.d.ts +14 -0
  567. package/dist/ops/auto-cleanup.d.ts.map +1 -0
  568. package/dist/ops/auto-cleanup.js +58 -0
  569. package/dist/ops/auto-cleanup.js.map +1 -0
  570. package/dist/ops/cleanup.d.ts +32 -0
  571. package/dist/ops/cleanup.d.ts.map +1 -0
  572. package/dist/ops/cleanup.js +208 -0
  573. package/dist/ops/cleanup.js.map +1 -0
  574. package/dist/ops/continue.d.ts +12 -0
  575. package/dist/ops/continue.d.ts.map +1 -0
  576. package/dist/ops/continue.js +240 -0
  577. package/dist/ops/continue.js.map +1 -0
  578. package/dist/ops/cost-override.d.ts +16 -0
  579. package/dist/ops/cost-override.d.ts.map +1 -0
  580. package/dist/ops/cost-override.js +28 -0
  581. package/dist/ops/cost-override.js.map +1 -0
  582. package/dist/ops/daily-cost-override.d.ts +15 -0
  583. package/dist/ops/daily-cost-override.d.ts.map +1 -0
  584. package/dist/ops/daily-cost-override.js +23 -0
  585. package/dist/ops/daily-cost-override.js.map +1 -0
  586. package/dist/ops/delete-entry.d.ts +44 -0
  587. package/dist/ops/delete-entry.d.ts.map +1 -0
  588. package/dist/ops/delete-entry.js +381 -0
  589. package/dist/ops/delete-entry.js.map +1 -0
  590. package/dist/ops/labels-init.d.ts +43 -0
  591. package/dist/ops/labels-init.d.ts.map +1 -0
  592. package/dist/ops/labels-init.js +149 -0
  593. package/dist/ops/labels-init.js.map +1 -0
  594. package/dist/ops/rebase-and-check.d.ts +34 -0
  595. package/dist/ops/rebase-and-check.d.ts.map +1 -0
  596. package/dist/ops/rebase-and-check.js +110 -0
  597. package/dist/ops/rebase-and-check.js.map +1 -0
  598. package/dist/ops/rebase.d.ts +18 -0
  599. package/dist/ops/rebase.d.ts.map +1 -0
  600. package/dist/ops/rebase.js +67 -0
  601. package/dist/ops/rebase.js.map +1 -0
  602. package/dist/ops/retention.d.ts +29 -0
  603. package/dist/ops/retention.d.ts.map +1 -0
  604. package/dist/ops/retention.js +120 -0
  605. package/dist/ops/retention.js.map +1 -0
  606. package/dist/ops/retry.d.ts +19 -0
  607. package/dist/ops/retry.d.ts.map +1 -0
  608. package/dist/ops/retry.js +106 -0
  609. package/dist/ops/retry.js.map +1 -0
  610. package/dist/ops/summary.d.ts +42 -0
  611. package/dist/ops/summary.d.ts.map +1 -0
  612. package/dist/ops/summary.js +86 -0
  613. package/dist/ops/summary.js.map +1 -0
  614. package/dist/ops/sync.d.ts +47 -0
  615. package/dist/ops/sync.d.ts.map +1 -0
  616. package/dist/ops/sync.js +445 -0
  617. package/dist/ops/sync.js.map +1 -0
  618. package/dist/planning/mode.d.ts +14 -0
  619. package/dist/planning/mode.d.ts.map +1 -0
  620. package/dist/planning/mode.js +33 -0
  621. package/dist/planning/mode.js.map +1 -0
  622. package/dist/poller/control.d.ts +21 -0
  623. package/dist/poller/control.d.ts.map +1 -0
  624. package/dist/poller/control.js +42 -0
  625. package/dist/poller/control.js.map +1 -0
  626. package/dist/poller/shutdown.d.ts +20 -0
  627. package/dist/poller/shutdown.d.ts.map +1 -0
  628. package/dist/poller/shutdown.js +94 -0
  629. package/dist/poller/shutdown.js.map +1 -0
  630. package/dist/publishing/pr-body.d.ts +25 -0
  631. package/dist/publishing/pr-body.d.ts.map +1 -0
  632. package/dist/publishing/pr-body.js +119 -0
  633. package/dist/publishing/pr-body.js.map +1 -0
  634. package/dist/publishing/publisher.d.ts +19 -0
  635. package/dist/publishing/publisher.d.ts.map +1 -0
  636. package/dist/publishing/publisher.js +116 -0
  637. package/dist/publishing/publisher.js.map +1 -0
  638. package/dist/publishing/push.d.ts +13 -0
  639. package/dist/publishing/push.d.ts.map +1 -0
  640. package/dist/publishing/push.js +56 -0
  641. package/dist/publishing/push.js.map +1 -0
  642. package/dist/reactions/handler.d.ts +20 -0
  643. package/dist/reactions/handler.d.ts.map +1 -0
  644. package/dist/reactions/handler.js +50 -0
  645. package/dist/reactions/handler.js.map +1 -0
  646. package/dist/reactions/scanner.d.ts +13 -0
  647. package/dist/reactions/scanner.d.ts.map +1 -0
  648. package/dist/reactions/scanner.js +141 -0
  649. package/dist/reactions/scanner.js.map +1 -0
  650. package/dist/reactions/types.d.ts +41 -0
  651. package/dist/reactions/types.d.ts.map +1 -0
  652. package/dist/reactions/types.js +2 -0
  653. package/dist/reactions/types.js.map +1 -0
  654. package/dist/runner/poller.d.ts +19 -0
  655. package/dist/runner/poller.d.ts.map +1 -0
  656. package/dist/runner/poller.js +1358 -0
  657. package/dist/runner/poller.js.map +1 -0
  658. package/dist/settings/registry.d.ts +37 -0
  659. package/dist/settings/registry.d.ts.map +1 -0
  660. package/dist/settings/registry.js +299 -0
  661. package/dist/settings/registry.js.map +1 -0
  662. package/dist/settings/runtime.d.ts +33 -0
  663. package/dist/settings/runtime.d.ts.map +1 -0
  664. package/dist/settings/runtime.js +148 -0
  665. package/dist/settings/runtime.js.map +1 -0
  666. package/dist/state/db.d.ts +3 -0
  667. package/dist/state/db.d.ts.map +1 -0
  668. package/dist/state/db.js +80 -0
  669. package/dist/state/db.js.map +1 -0
  670. package/dist/state/issues.d.ts +47 -0
  671. package/dist/state/issues.d.ts.map +1 -0
  672. package/dist/state/issues.js +188 -0
  673. package/dist/state/issues.js.map +1 -0
  674. package/dist/state/leases.d.ts +27 -0
  675. package/dist/state/leases.d.ts.map +1 -0
  676. package/dist/state/leases.js +75 -0
  677. package/dist/state/leases.js.map +1 -0
  678. package/dist/state/migrations/001-initial.d.ts +3 -0
  679. package/dist/state/migrations/001-initial.d.ts.map +1 -0
  680. package/dist/state/migrations/001-initial.js +70 -0
  681. package/dist/state/migrations/001-initial.js.map +1 -0
  682. package/dist/state/migrations/002-placeholder.d.ts +7 -0
  683. package/dist/state/migrations/002-placeholder.d.ts.map +1 -0
  684. package/dist/state/migrations/002-placeholder.js +8 -0
  685. package/dist/state/migrations/002-placeholder.js.map +1 -0
  686. package/dist/state/migrations/003-mention-tracking.d.ts +3 -0
  687. package/dist/state/migrations/003-mention-tracking.d.ts.map +1 -0
  688. package/dist/state/migrations/003-mention-tracking.js +13 -0
  689. package/dist/state/migrations/003-mention-tracking.js.map +1 -0
  690. package/dist/state/migrations/004-command-tracking.d.ts +3 -0
  691. package/dist/state/migrations/004-command-tracking.d.ts.map +1 -0
  692. package/dist/state/migrations/004-command-tracking.js +13 -0
  693. package/dist/state/migrations/004-command-tracking.js.map +1 -0
  694. package/dist/state/migrations/005-block-reason.d.ts +3 -0
  695. package/dist/state/migrations/005-block-reason.d.ts.map +1 -0
  696. package/dist/state/migrations/005-block-reason.js +4 -0
  697. package/dist/state/migrations/005-block-reason.js.map +1 -0
  698. package/dist/state/migrations/006-parent-run.d.ts +3 -0
  699. package/dist/state/migrations/006-parent-run.d.ts.map +1 -0
  700. package/dist/state/migrations/006-parent-run.js +4 -0
  701. package/dist/state/migrations/006-parent-run.js.map +1 -0
  702. package/dist/state/migrations/007-merge-queue.d.ts +3 -0
  703. package/dist/state/migrations/007-merge-queue.d.ts.map +1 -0
  704. package/dist/state/migrations/007-merge-queue.js +21 -0
  705. package/dist/state/migrations/007-merge-queue.js.map +1 -0
  706. package/dist/state/migrations/008-agent-events.d.ts +3 -0
  707. package/dist/state/migrations/008-agent-events.d.ts.map +1 -0
  708. package/dist/state/migrations/008-agent-events.js +15 -0
  709. package/dist/state/migrations/008-agent-events.js.map +1 -0
  710. package/dist/state/migrations/009-run-titles.d.ts +3 -0
  711. package/dist/state/migrations/009-run-titles.d.ts.map +1 -0
  712. package/dist/state/migrations/009-run-titles.js +11 -0
  713. package/dist/state/migrations/009-run-titles.js.map +1 -0
  714. package/dist/state/migrations/010-issues.d.ts +9 -0
  715. package/dist/state/migrations/010-issues.d.ts.map +1 -0
  716. package/dist/state/migrations/010-issues.js +193 -0
  717. package/dist/state/migrations/010-issues.js.map +1 -0
  718. package/dist/state/migrations/011-rebuild-issues-from-latest-run.d.ts +8 -0
  719. package/dist/state/migrations/011-rebuild-issues-from-latest-run.d.ts.map +1 -0
  720. package/dist/state/migrations/011-rebuild-issues-from-latest-run.js +125 -0
  721. package/dist/state/migrations/011-rebuild-issues-from-latest-run.js.map +1 -0
  722. package/dist/state/migrations/012-settings-overrides.d.ts +3 -0
  723. package/dist/state/migrations/012-settings-overrides.d.ts.map +1 -0
  724. package/dist/state/migrations/012-settings-overrides.js +14 -0
  725. package/dist/state/migrations/012-settings-overrides.js.map +1 -0
  726. package/dist/state/migrations/013-token-usage.d.ts +3 -0
  727. package/dist/state/migrations/013-token-usage.d.ts.map +1 -0
  728. package/dist/state/migrations/013-token-usage.js +21 -0
  729. package/dist/state/migrations/013-token-usage.js.map +1 -0
  730. package/dist/state/migrations/014-daily-run-usage.d.ts +3 -0
  731. package/dist/state/migrations/014-daily-run-usage.d.ts.map +1 -0
  732. package/dist/state/migrations/014-daily-run-usage.js +14 -0
  733. package/dist/state/migrations/014-daily-run-usage.js.map +1 -0
  734. package/dist/state/migrations/015-run-cost-override.d.ts +11 -0
  735. package/dist/state/migrations/015-run-cost-override.d.ts.map +1 -0
  736. package/dist/state/migrations/015-run-cost-override.js +20 -0
  737. package/dist/state/migrations/015-run-cost-override.js.map +1 -0
  738. package/dist/state/migrations/016-daily-cost-cap-override.d.ts +15 -0
  739. package/dist/state/migrations/016-daily-cost-cap-override.d.ts.map +1 -0
  740. package/dist/state/migrations/016-daily-cost-cap-override.js +24 -0
  741. package/dist/state/migrations/016-daily-cost-cap-override.js.map +1 -0
  742. package/dist/state/migrations/017-merge-batch-merged-prs.d.ts +13 -0
  743. package/dist/state/migrations/017-merge-batch-merged-prs.d.ts.map +1 -0
  744. package/dist/state/migrations/017-merge-batch-merged-prs.js +22 -0
  745. package/dist/state/migrations/017-merge-batch-merged-prs.js.map +1 -0
  746. package/dist/state/migrations/018-run-retry-count.d.ts +13 -0
  747. package/dist/state/migrations/018-run-retry-count.d.ts.map +1 -0
  748. package/dist/state/migrations/018-run-retry-count.js +22 -0
  749. package/dist/state/migrations/018-run-retry-count.js.map +1 -0
  750. package/dist/state/migrations/019-runs-active-index-top-level.d.ts +16 -0
  751. package/dist/state/migrations/019-runs-active-index-top-level.d.ts.map +1 -0
  752. package/dist/state/migrations/019-runs-active-index-top-level.js +23 -0
  753. package/dist/state/migrations/019-runs-active-index-top-level.js.map +1 -0
  754. package/dist/state/runs.d.ts +100 -0
  755. package/dist/state/runs.d.ts.map +1 -0
  756. package/dist/state/runs.js +321 -0
  757. package/dist/state/runs.js.map +1 -0
  758. package/dist/state/settings.d.ts +16 -0
  759. package/dist/state/settings.d.ts.map +1 -0
  760. package/dist/state/settings.js +55 -0
  761. package/dist/state/settings.js.map +1 -0
  762. package/dist/state/stats.d.ts +133 -0
  763. package/dist/state/stats.d.ts.map +1 -0
  764. package/dist/state/stats.js +419 -0
  765. package/dist/state/stats.js.map +1 -0
  766. package/dist/supervisor/health.d.ts +24 -0
  767. package/dist/supervisor/health.d.ts.map +1 -0
  768. package/dist/supervisor/health.js +186 -0
  769. package/dist/supervisor/health.js.map +1 -0
  770. package/dist/supervisor/index.d.ts +31 -0
  771. package/dist/supervisor/index.d.ts.map +1 -0
  772. package/dist/supervisor/index.js +387 -0
  773. package/dist/supervisor/index.js.map +1 -0
  774. package/dist/supervisor/status.d.ts +18 -0
  775. package/dist/supervisor/status.d.ts.map +1 -0
  776. package/dist/supervisor/status.js +30 -0
  777. package/dist/supervisor/status.js.map +1 -0
  778. package/dist/supervisor/updater.d.ts +18 -0
  779. package/dist/supervisor/updater.d.ts.map +1 -0
  780. package/dist/supervisor/updater.js +108 -0
  781. package/dist/supervisor/updater.js.map +1 -0
  782. package/dist/utils/build-info.d.ts +6 -0
  783. package/dist/utils/build-info.d.ts.map +1 -0
  784. package/dist/utils/build-info.js +56 -0
  785. package/dist/utils/build-info.js.map +1 -0
  786. package/dist/utils/command.d.ts +8 -0
  787. package/dist/utils/command.d.ts.map +1 -0
  788. package/dist/utils/command.js +71 -0
  789. package/dist/utils/command.js.map +1 -0
  790. package/dist/utils/ids.d.ts +4 -0
  791. package/dist/utils/ids.d.ts.map +1 -0
  792. package/dist/utils/ids.js +17 -0
  793. package/dist/utils/ids.js.map +1 -0
  794. package/dist/utils/install-method.d.ts +4 -0
  795. package/dist/utils/install-method.d.ts.map +1 -0
  796. package/dist/utils/install-method.js +13 -0
  797. package/dist/utils/install-method.js.map +1 -0
  798. package/dist/utils/issue-repo.d.ts +2 -0
  799. package/dist/utils/issue-repo.d.ts.map +1 -0
  800. package/dist/utils/issue-repo.js +7 -0
  801. package/dist/utils/issue-repo.js.map +1 -0
  802. package/dist/utils/logger.d.ts +7 -0
  803. package/dist/utils/logger.d.ts.map +1 -0
  804. package/dist/utils/logger.js +63 -0
  805. package/dist/utils/logger.js.map +1 -0
  806. package/dist/utils/project-root.d.ts +8 -0
  807. package/dist/utils/project-root.d.ts.map +1 -0
  808. package/dist/utils/project-root.js +22 -0
  809. package/dist/utils/project-root.js.map +1 -0
  810. package/dist/utils/sanitize-error.d.ts +36 -0
  811. package/dist/utils/sanitize-error.d.ts.map +1 -0
  812. package/dist/utils/sanitize-error.js +89 -0
  813. package/dist/utils/sanitize-error.js.map +1 -0
  814. package/dist/utils/time.d.ts +7 -0
  815. package/dist/utils/time.d.ts.map +1 -0
  816. package/dist/utils/time.js +47 -0
  817. package/dist/utils/time.js.map +1 -0
  818. package/dist/web/server.d.ts +14 -0
  819. package/dist/web/server.d.ts.map +1 -0
  820. package/dist/web/server.js +1185 -0
  821. package/dist/web/server.js.map +1 -0
  822. package/dist/workers/acp.d.ts +9 -0
  823. package/dist/workers/acp.d.ts.map +1 -0
  824. package/dist/workers/acp.js +190 -0
  825. package/dist/workers/acp.js.map +1 -0
  826. package/dist/workers/acpx-imports.d.ts +18 -0
  827. package/dist/workers/acpx-imports.d.ts.map +1 -0
  828. package/dist/workers/acpx-imports.js +43 -0
  829. package/dist/workers/acpx-imports.js.map +1 -0
  830. package/dist/workers/claude.d.ts +9 -0
  831. package/dist/workers/claude.d.ts.map +1 -0
  832. package/dist/workers/claude.js +341 -0
  833. package/dist/workers/claude.js.map +1 -0
  834. package/dist/workers/codex.d.ts +21 -0
  835. package/dist/workers/codex.d.ts.map +1 -0
  836. package/dist/workers/codex.js +337 -0
  837. package/dist/workers/codex.js.map +1 -0
  838. package/dist/workers/command.d.ts +6 -0
  839. package/dist/workers/command.d.ts.map +1 -0
  840. package/dist/workers/command.js +15 -0
  841. package/dist/workers/command.js.map +1 -0
  842. package/dist/workers/env.d.ts +18 -0
  843. package/dist/workers/env.d.ts.map +1 -0
  844. package/dist/workers/env.js +172 -0
  845. package/dist/workers/env.js.map +1 -0
  846. package/dist/workers/events.d.ts +7 -0
  847. package/dist/workers/events.d.ts.map +1 -0
  848. package/dist/workers/events.js +30 -0
  849. package/dist/workers/events.js.map +1 -0
  850. package/dist/workers/factory.d.ts +6 -0
  851. package/dist/workers/factory.d.ts.map +1 -0
  852. package/dist/workers/factory.js +13 -0
  853. package/dist/workers/factory.js.map +1 -0
  854. package/dist/workers/parsers/coder.d.ts +6 -0
  855. package/dist/workers/parsers/coder.d.ts.map +1 -0
  856. package/dist/workers/parsers/coder.js +59 -0
  857. package/dist/workers/parsers/coder.js.map +1 -0
  858. package/dist/workers/parsers/decomposer.d.ts +16 -0
  859. package/dist/workers/parsers/decomposer.d.ts.map +1 -0
  860. package/dist/workers/parsers/decomposer.js +35 -0
  861. package/dist/workers/parsers/decomposer.js.map +1 -0
  862. package/dist/workers/parsers/extract.d.ts +41 -0
  863. package/dist/workers/parsers/extract.d.ts.map +1 -0
  864. package/dist/workers/parsers/extract.js +231 -0
  865. package/dist/workers/parsers/extract.js.map +1 -0
  866. package/dist/workers/parsers/planner.d.ts +6 -0
  867. package/dist/workers/parsers/planner.d.ts.map +1 -0
  868. package/dist/workers/parsers/planner.js +77 -0
  869. package/dist/workers/parsers/planner.js.map +1 -0
  870. package/dist/workers/parsers/reviewer.d.ts +6 -0
  871. package/dist/workers/parsers/reviewer.d.ts.map +1 -0
  872. package/dist/workers/parsers/reviewer.js +105 -0
  873. package/dist/workers/parsers/reviewer.js.map +1 -0
  874. package/dist/workers/prompt/compiler.d.ts +11 -0
  875. package/dist/workers/prompt/compiler.d.ts.map +1 -0
  876. package/dist/workers/prompt/compiler.js +199 -0
  877. package/dist/workers/prompt/compiler.js.map +1 -0
  878. package/dist/workers/prompt/templates.d.ts +13 -0
  879. package/dist/workers/prompt/templates.d.ts.map +1 -0
  880. package/dist/workers/prompt/templates.js +110 -0
  881. package/dist/workers/prompt/templates.js.map +1 -0
  882. package/dist/workers/registry.d.ts +9 -0
  883. package/dist/workers/registry.d.ts.map +1 -0
  884. package/dist/workers/registry.js +21 -0
  885. package/dist/workers/registry.js.map +1 -0
  886. package/dist/workers/streaming-exec.d.ts +26 -0
  887. package/dist/workers/streaming-exec.d.ts.map +1 -0
  888. package/dist/workers/streaming-exec.js +166 -0
  889. package/dist/workers/streaming-exec.js.map +1 -0
  890. package/dist/workers/timeout.d.ts +17 -0
  891. package/dist/workers/timeout.d.ts.map +1 -0
  892. package/dist/workers/timeout.js +37 -0
  893. package/dist/workers/timeout.js.map +1 -0
  894. package/dist/workers/types.d.ts +120 -0
  895. package/dist/workers/types.d.ts.map +1 -0
  896. package/dist/workers/types.js +2 -0
  897. package/dist/workers/types.js.map +1 -0
  898. package/docker-compose.example.yaml +29 -0
  899. package/examples/config.example.yaml +256 -0
  900. package/examples/night-orch.service +40 -0
  901. package/monitoring/grafana/dashboards/night-orch.json +140 -0
  902. package/monitoring/grafana/provisioning/dashboards/dashboards.yml +10 -0
  903. package/monitoring/grafana/provisioning/datasources/prometheus.yml +9 -0
  904. package/monitoring/prometheus.yml +8 -0
  905. package/package.json +104 -0
  906. package/web/dist/assets/index-CBFNqVuV.js +9 -0
  907. package/web/dist/assets/index-RCNGmuI2.css +1 -0
  908. package/web/dist/icon.svg +10 -0
  909. package/web/dist/index.html +22 -0
  910. package/web/dist/manifest.webmanifest +16 -0
  911. package/web/dist/sw.js +58 -0
@@ -0,0 +1,1185 @@
1
+ import { createServer } from 'node:http';
2
+ import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';
3
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
4
+ import { homedir } from 'node:os';
5
+ import { readFile, stat } from 'node:fs/promises';
6
+ import { extname, resolve, dirname, sep } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { WebSocket, WebSocketServer } from 'ws';
9
+ import { handleToolCall } from '../mcp/tools/index.js';
10
+ import { handleResourceRead } from '../mcp/resources/index.js';
11
+ import { loadTuiStats } from '../state/stats.js';
12
+ import { getBuildInfo } from '../utils/build-info.js';
13
+ import { logger } from '../utils/logger.js';
14
+ import { sanitizeError } from '../utils/sanitize-error.js';
15
+ import { nowUtcIso } from '../utils/time.js';
16
+ import { listRuntimeSettings, resolveConfigWithRuntimeSettings, RuntimeSettingInputError, } from '../settings/runtime.js';
17
+ import { getSettingDefinition, resolveSettingYamlValue } from '../settings/registry.js';
18
+ const ONE_MEGABYTE = 1024 * 1024;
19
+ const DEFAULT_SNAPSHOT_INTERVAL_MS = 3000;
20
+ const MUTATION_INTENT_HEADER = 'x-night-orch-intent';
21
+ const MUTATION_INTENT_VALUE = 'mutate';
22
+ const WEB_AUTH_TOKEN_HEADER = 'x-night-orch-web-token';
23
+ const BUILD_INFO = getBuildInfo();
24
+ const CONTENT_TYPES = {
25
+ '.css': 'text/css; charset=utf-8',
26
+ '.html': 'text/html; charset=utf-8',
27
+ '.ico': 'image/x-icon',
28
+ '.jpeg': 'image/jpeg',
29
+ '.jpg': 'image/jpeg',
30
+ '.js': 'text/javascript; charset=utf-8',
31
+ '.json': 'application/json; charset=utf-8',
32
+ '.map': 'application/json; charset=utf-8',
33
+ '.png': 'image/png',
34
+ '.svg': 'image/svg+xml; charset=utf-8',
35
+ '.txt': 'text/plain; charset=utf-8',
36
+ '.webmanifest': 'application/manifest+json; charset=utf-8',
37
+ };
38
+ export function resolveWebFrontendDistPath(explicitPath) {
39
+ if (explicitPath) {
40
+ return resolve(explicitPath);
41
+ }
42
+ const moduleDir = dirname(fileURLToPath(import.meta.url));
43
+ return resolve(moduleDir, '../../web/dist');
44
+ }
45
+ export async function startWebServer(deps, options) {
46
+ // Hard gate on non-loopback binds: the web server hands out a mutation
47
+ // token via `/api/session` to any same-origin caller and offers
48
+ // destructive endpoints (retry/cleanup/sync/etc) under that token. When
49
+ // bound to a non-loopback address, require an operator-supplied auth
50
+ // token env (`NIGHT_ORCH_WEB_AUTH_TOKEN`) so any single-origin XSS or
51
+ // local process cannot trivially escalate to full write access.
52
+ const bindHostName = normalizeHostname(options.host) ?? options.host;
53
+ const isLoopbackBind = bindHostName === '127.0.0.1'
54
+ || bindHostName === '::1'
55
+ || bindHostName === 'localhost'
56
+ || bindHostName === '';
57
+ if (!isLoopbackBind && !process.env['NIGHT_ORCH_WEB_AUTH_TOKEN']) {
58
+ throw new Error(`night-orch web refuses to bind to non-loopback host "${options.host}" without NIGHT_ORCH_WEB_AUTH_TOKEN set. `
59
+ + 'Either bind to 127.0.0.1 / ::1 or provide an out-of-band auth token via that env var.');
60
+ }
61
+ const security = createWebSecurityContext(deps, options);
62
+ const operationsEnabled = options.operationsEnabled ?? true;
63
+ const frontendDistPath = resolveWebFrontendDistPath(options.frontendDistPath);
64
+ const hasFrontendAssets = existsSync(resolve(frontendDistPath, 'index.html'));
65
+ if (!hasFrontendAssets) {
66
+ logger.warn({ frontendDistPath }, 'Web frontend assets not found. Build with `pnpm web:build` before starting `night-orch web`.');
67
+ }
68
+ const wsServer = new WebSocketServer({ noServer: true });
69
+ const clients = new Map();
70
+ const httpServer = createServer(async (req, res) => {
71
+ try {
72
+ const requestUrl = getRequestUrl(req);
73
+ if (requestUrl.pathname.startsWith('/api/')) {
74
+ if (!isAllowedRequestHost(req, security)) {
75
+ writeJson(res, 403, { error: 'Forbidden host' });
76
+ return;
77
+ }
78
+ await handleApiRequest(req, res, requestUrl, deps, security, operationsEnabled, options.rawConfig);
79
+ return;
80
+ }
81
+ if (requestUrl.pathname === '/ws') {
82
+ writeJson(res, 426, { error: 'Upgrade Required' });
83
+ return;
84
+ }
85
+ await serveFrontend(req, res, requestUrl.pathname, frontendDistPath, hasFrontendAssets);
86
+ }
87
+ catch (err) {
88
+ if (res.headersSent) {
89
+ return;
90
+ }
91
+ const sanitized = sanitizeError(err);
92
+ const status = isClientRequestError(sanitized.message)
93
+ ? 400
94
+ : isAuthorizationError(sanitized.message)
95
+ ? 403
96
+ : 500;
97
+ if (status >= 500) {
98
+ logger.warn({ err: sanitized }, 'Web request failed');
99
+ }
100
+ writeJson(res, status, { error: sanitized.message });
101
+ }
102
+ });
103
+ httpServer.on('upgrade', (req, socket, head) => {
104
+ let requestUrl;
105
+ try {
106
+ requestUrl = getRequestUrl(req);
107
+ }
108
+ catch {
109
+ rejectUpgrade(socket, 400, 'Bad Request');
110
+ return;
111
+ }
112
+ if (requestUrl.pathname !== '/ws') {
113
+ socket.destroy();
114
+ return;
115
+ }
116
+ if (!isAllowedRequestHost(req, security)) {
117
+ rejectUpgrade(socket, 403, 'Forbidden');
118
+ return;
119
+ }
120
+ if (!hasAllowedOrigin(req, security, false)) {
121
+ rejectUpgrade(socket, 403, 'Forbidden');
122
+ return;
123
+ }
124
+ wsServer.handleUpgrade(req, socket, head, (ws) => {
125
+ wsServer.emit('connection', ws);
126
+ });
127
+ });
128
+ wsServer.on('connection', (ws) => {
129
+ const state = { runSubscriptions: new Map() };
130
+ clients.set(ws, state);
131
+ sendWebsocket(ws, {
132
+ type: 'connected',
133
+ payload: { timestamp: nowUtcIso() },
134
+ });
135
+ ws.on('message', (raw) => {
136
+ const decoded = decodeWsMessage(raw);
137
+ if (decoded === null) {
138
+ sendWebsocket(ws, { type: 'error', error: 'Unsupported websocket payload type' });
139
+ return;
140
+ }
141
+ void handleWsMessage(ws, state, decoded, deps);
142
+ });
143
+ ws.on('close', () => {
144
+ clients.delete(ws);
145
+ });
146
+ });
147
+ const snapshotIntervalMs = Math.max(1000, Math.floor(options.snapshotIntervalMs ?? DEFAULT_SNAPSHOT_INTERVAL_MS));
148
+ let tickInFlight = false;
149
+ const publishTick = async () => {
150
+ if (tickInFlight)
151
+ return;
152
+ tickInFlight = true;
153
+ try {
154
+ const snapshot = await buildDashboardSnapshot(deps);
155
+ const snapshotMessage = JSON.stringify({ type: 'snapshot', payload: snapshot });
156
+ for (const ws of clients.keys()) {
157
+ if (ws.readyState !== WebSocket.OPEN)
158
+ continue;
159
+ ws.send(snapshotMessage);
160
+ }
161
+ for (const [ws, state] of clients.entries()) {
162
+ if (ws.readyState !== WebSocket.OPEN)
163
+ continue;
164
+ await publishRunSubscriptions(ws, state, deps);
165
+ }
166
+ }
167
+ catch (err) {
168
+ logger.warn({ err }, 'Failed to publish websocket snapshot tick');
169
+ }
170
+ finally {
171
+ tickInFlight = false;
172
+ }
173
+ };
174
+ const interval = setInterval(() => {
175
+ void publishTick();
176
+ }, snapshotIntervalMs);
177
+ interval.unref();
178
+ httpServer.on('close', () => {
179
+ clearInterval(interval);
180
+ for (const ws of wsServer.clients) {
181
+ ws.close();
182
+ }
183
+ wsServer.close();
184
+ });
185
+ await new Promise((resolveStart, rejectStart) => {
186
+ httpServer.once('error', rejectStart);
187
+ httpServer.listen(options.port, options.host, () => {
188
+ httpServer.off('error', rejectStart);
189
+ logger.info({ host: options.host, port: options.port }, 'Web server started');
190
+ resolveStart();
191
+ });
192
+ });
193
+ await publishTick();
194
+ return httpServer;
195
+ }
196
+ async function handleApiRequest(req, res, requestUrl, deps, security, operationsEnabled, rawConfig) {
197
+ const method = req.method ?? 'GET';
198
+ const { pathname, searchParams } = requestUrl;
199
+ const runtimeDeps = {
200
+ ...deps,
201
+ config: resolveConfigWithRuntimeSettings(deps.config, deps.db),
202
+ };
203
+ if (method === 'POST' && pathname.startsWith('/api/operations/')) {
204
+ // Update is a supervisor operation — always allowed regardless of attach/standalone mode
205
+ if (!operationsEnabled && pathname !== '/api/operations/update') {
206
+ writeJson(res, 409, { error: 'Web operations are disabled by server policy.' });
207
+ return;
208
+ }
209
+ const guardFailure = validateMutationRequest(req, security);
210
+ if (guardFailure) {
211
+ writeJson(res, guardFailure.statusCode, { error: guardFailure.error });
212
+ return;
213
+ }
214
+ }
215
+ if (method === 'GET' && pathname === '/api/health') {
216
+ writeJson(res, 200, { status: 'ok', now: nowUtcIso() });
217
+ return;
218
+ }
219
+ if (method === 'GET' && pathname === '/api/dashboard') {
220
+ const snapshot = await buildDashboardSnapshot(runtimeDeps);
221
+ writeJson(res, 200, snapshot);
222
+ return;
223
+ }
224
+ if (method === 'GET' && pathname === '/api/projects') {
225
+ const snapshot = buildProjectsSnapshot(runtimeDeps);
226
+ writeJson(res, 200, snapshot);
227
+ return;
228
+ }
229
+ if (method === 'GET' && pathname === '/api/settings') {
230
+ const snapshot = buildSettingsSnapshot(deps, rawConfig);
231
+ writeJson(res, 200, snapshot);
232
+ return;
233
+ }
234
+ if (method === 'GET' && pathname === '/api/session') {
235
+ // When the server is bound to a non-loopback address with an operator-
236
+ // supplied auth token, we must NOT hand it out via HTTP — the client
237
+ // must provide it out-of-band. For loopback, disclosure is low-risk.
238
+ writeJson(res, 200, {
239
+ mutationToken: security.operatorAuthMode ? null : security.webMutationToken,
240
+ operationsEnabled,
241
+ requiresExternalAuth: security.operatorAuthMode,
242
+ });
243
+ return;
244
+ }
245
+ if (method === 'GET' && pathname === '/api/status') {
246
+ const repo = searchParams.get('repo') ?? undefined;
247
+ const result = await handleToolCall('night-orch-status', { repo }, runtimeDeps);
248
+ writeJson(res, 200, result);
249
+ return;
250
+ }
251
+ if (method === 'GET' && pathname === '/api/runs') {
252
+ const repo = searchParams.get('repo') ?? undefined;
253
+ const status = searchParams.get('status') ?? undefined;
254
+ const limit = toBoundedInt(searchParams.get('limit'), 50, 1, 500);
255
+ const result = await handleToolCall('night-orch-list-runs', { repo, status, limit }, runtimeDeps);
256
+ writeJson(res, 200, result);
257
+ return;
258
+ }
259
+ if (method === 'GET' && pathname === '/api/cost') {
260
+ const days = toBoundedInt(searchParams.get('days'), 7, 1, 30);
261
+ const result = await handleToolCall('night-orch-cost-report', { days }, runtimeDeps);
262
+ writeJson(res, 200, result);
263
+ return;
264
+ }
265
+ if (method === 'GET' && pathname === '/api/stats') {
266
+ writeJson(res, 200, loadTuiStats(runtimeDeps.db, { costModel: runtimeDeps.config.cost.model }));
267
+ return;
268
+ }
269
+ if (method === 'GET' && pathname === '/api/config') {
270
+ const result = await handleResourceRead('night-orch://config', runtimeDeps);
271
+ writeJson(res, 200, result);
272
+ return;
273
+ }
274
+ if (method === 'GET') {
275
+ const runDetailMatch = pathname.match(/^\/api\/runs\/([^/]+)$/);
276
+ if (runDetailMatch) {
277
+ const runId = decodeURIComponent(runDetailMatch[1] ?? '');
278
+ const result = await handleToolCall('night-orch-run-detail', { runId }, runtimeDeps);
279
+ writeJson(res, 200, result);
280
+ return;
281
+ }
282
+ const runEventsMatch = pathname.match(/^\/api\/runs\/([^/]+)\/events$/);
283
+ if (runEventsMatch) {
284
+ const runId = decodeURIComponent(runEventsMatch[1] ?? '');
285
+ const since = toBoundedInt(searchParams.get('since'), 0, 0, Number.MAX_SAFE_INTEGER);
286
+ const limit = toBoundedInt(searchParams.get('limit'), 100, 1, 200);
287
+ const result = await handleToolCall('night-orch-stream-events', { runId, since, limit }, runtimeDeps);
288
+ writeJson(res, 200, result);
289
+ return;
290
+ }
291
+ const repoIssuesMatch = pathname.match(/^\/api\/repos\/([^/]+)\/issues$/);
292
+ if (repoIssuesMatch) {
293
+ const repo = decodeURIComponent(repoIssuesMatch[1] ?? '');
294
+ const filter = searchParams.get('filter') ?? 'all';
295
+ const result = await handleToolCall('night-orch-list-issues', { repo, filter }, runtimeDeps);
296
+ writeJson(res, 200, result);
297
+ return;
298
+ }
299
+ }
300
+ if (method === 'POST' && pathname === '/api/operations/poll') {
301
+ const body = await readJsonBody(req);
302
+ const result = await handleToolCall('night-orch-poll', withMcpMutationAuth({ dryRun: Boolean(body['dryRun']) }, security), runtimeDeps);
303
+ writeJson(res, 200, result);
304
+ return;
305
+ }
306
+ if (method === 'POST' && pathname === '/api/operations/sync') {
307
+ const body = await readJsonBody(req);
308
+ const result = await handleToolCall('night-orch-sync', withMcpMutationAuth({ dryRun: Boolean(body['dryRun']) }, security), runtimeDeps);
309
+ writeJson(res, 200, result);
310
+ return;
311
+ }
312
+ if (method === 'POST' && pathname === '/api/operations/cleanup') {
313
+ const body = await readJsonBody(req);
314
+ const result = await handleToolCall('night-orch-cleanup', withMcpMutationAuth({ dryRun: Boolean(body['dryRun']) }, security), runtimeDeps);
315
+ writeJson(res, 200, result);
316
+ return;
317
+ }
318
+ if (method === 'POST' && pathname === '/api/operations/labels-init') {
319
+ const body = await readJsonBody(req);
320
+ const repo = toNonEmptyString(body['repo']);
321
+ if (!repo) {
322
+ writeJson(res, 400, { error: 'repo is required' });
323
+ return;
324
+ }
325
+ const result = await handleToolCall('night-orch-labels-init', withMcpMutationAuth({
326
+ repo,
327
+ dryRun: Boolean(body['dryRun']),
328
+ }, security), runtimeDeps);
329
+ writeJson(res, 200, result);
330
+ return;
331
+ }
332
+ if (method === 'POST' && pathname === '/api/operations/retry') {
333
+ const body = await readJsonBody(req);
334
+ const repo = toNonEmptyString(body['repo']);
335
+ const issueNumber = toBoundedInt(body['issueNumber'], NaN, 1, Number.MAX_SAFE_INTEGER);
336
+ if (!repo || Number.isNaN(issueNumber)) {
337
+ writeJson(res, 400, { error: 'repo and issueNumber are required' });
338
+ return;
339
+ }
340
+ const result = await handleToolCall('night-orch-retry', withMcpMutationAuth({
341
+ repo,
342
+ issueNumber,
343
+ resetPlan: Boolean(body['resetPlan']),
344
+ fresh: Boolean(body['fresh']),
345
+ }, security), runtimeDeps);
346
+ writeJson(res, 200, result);
347
+ return;
348
+ }
349
+ if (method === 'POST' && pathname === '/api/operations/rebase') {
350
+ const body = await readJsonBody(req);
351
+ const repo = toNonEmptyString(body['repo']);
352
+ const issueNumber = toBoundedInt(body['issueNumber'], NaN, 1, Number.MAX_SAFE_INTEGER);
353
+ if (!repo || Number.isNaN(issueNumber)) {
354
+ writeJson(res, 400, { error: 'repo and issueNumber are required' });
355
+ return;
356
+ }
357
+ const result = await handleToolCall('night-orch-rebase', withMcpMutationAuth({
358
+ repo,
359
+ issueNumber,
360
+ check: body['check'] === undefined ? true : Boolean(body['check']),
361
+ }, security), runtimeDeps);
362
+ writeJson(res, 200, result);
363
+ return;
364
+ }
365
+ if (method === 'POST' && pathname === '/api/operations/continue') {
366
+ const body = await readJsonBody(req);
367
+ const repo = toNonEmptyString(body['repo']);
368
+ const issueNumber = toBoundedInt(body['issueNumber'], NaN, 1, Number.MAX_SAFE_INTEGER);
369
+ if (!repo || Number.isNaN(issueNumber)) {
370
+ writeJson(res, 400, { error: 'repo and issueNumber are required' });
371
+ return;
372
+ }
373
+ const result = await handleToolCall('night-orch-continue', withMcpMutationAuth({
374
+ repo,
375
+ issueNumber,
376
+ }, security), runtimeDeps);
377
+ writeJson(res, 200, result);
378
+ return;
379
+ }
380
+ if (method === 'POST' && pathname === '/api/operations/delete-entry') {
381
+ const body = await readJsonBody(req);
382
+ const repo = toNonEmptyString(body['repo']);
383
+ const issueNumber = toBoundedInt(body['issueNumber'], NaN, 1, Number.MAX_SAFE_INTEGER);
384
+ if (!repo || Number.isNaN(issueNumber)) {
385
+ writeJson(res, 400, { error: 'repo and issueNumber are required' });
386
+ return;
387
+ }
388
+ const result = await handleToolCall('night-orch-delete-entry', withMcpMutationAuth({
389
+ repo,
390
+ issueNumber,
391
+ force: Boolean(body['force']),
392
+ dryRun: Boolean(body['dryRun']),
393
+ }, security), runtimeDeps);
394
+ writeJson(res, 200, result);
395
+ return;
396
+ }
397
+ if (method === 'POST' && pathname === '/api/operations/daily-cost-override/set') {
398
+ const body = await readJsonBody(req);
399
+ const amountUsd = toFiniteNumber(body['amountUsd']);
400
+ if (amountUsd === null || amountUsd <= 0) {
401
+ writeJson(res, 400, { error: 'amountUsd must be a positive finite number' });
402
+ return;
403
+ }
404
+ try {
405
+ const result = await handleToolCall('night-orch-daily-cost-override', withMcpMutationAuth({ amountUsd }, security), runtimeDeps);
406
+ writeJson(res, 200, result);
407
+ }
408
+ catch (err) {
409
+ writeJson(res, 400, { error: err.message });
410
+ }
411
+ return;
412
+ }
413
+ if (method === 'POST' && pathname === '/api/operations/daily-cost-override/clear') {
414
+ try {
415
+ const result = await handleToolCall('night-orch-daily-cost-override', withMcpMutationAuth({ clear: true }, security), runtimeDeps);
416
+ writeJson(res, 200, result);
417
+ }
418
+ catch (err) {
419
+ writeJson(res, 400, { error: err.message });
420
+ }
421
+ return;
422
+ }
423
+ if (method === 'POST' && pathname === '/api/operations/cost-override/set') {
424
+ const body = await readJsonBody(req);
425
+ const repo = toNonEmptyString(body['repo']);
426
+ const issueNumber = toBoundedInt(body['issueNumber'], NaN, 1, Number.MAX_SAFE_INTEGER);
427
+ const amountUsd = toFiniteNumber(body['amountUsd']);
428
+ if (!repo || Number.isNaN(issueNumber)) {
429
+ writeJson(res, 400, { error: 'repo and issueNumber are required' });
430
+ return;
431
+ }
432
+ if (amountUsd === null || amountUsd <= 0) {
433
+ writeJson(res, 400, { error: 'amountUsd must be a positive finite number' });
434
+ return;
435
+ }
436
+ try {
437
+ const result = await handleToolCall('night-orch-cost-override', withMcpMutationAuth({ repo, issueNumber, amountUsd }, security), runtimeDeps);
438
+ writeJson(res, 200, result);
439
+ }
440
+ catch (err) {
441
+ writeJson(res, 400, { error: err.message });
442
+ }
443
+ return;
444
+ }
445
+ if (method === 'POST' && pathname === '/api/operations/cost-override/clear') {
446
+ const body = await readJsonBody(req);
447
+ const repo = toNonEmptyString(body['repo']);
448
+ const issueNumber = toBoundedInt(body['issueNumber'], NaN, 1, Number.MAX_SAFE_INTEGER);
449
+ if (!repo || Number.isNaN(issueNumber)) {
450
+ writeJson(res, 400, { error: 'repo and issueNumber are required' });
451
+ return;
452
+ }
453
+ try {
454
+ const result = await handleToolCall('night-orch-cost-override', withMcpMutationAuth({ repo, issueNumber, clear: true }, security), runtimeDeps);
455
+ writeJson(res, 200, result);
456
+ }
457
+ catch (err) {
458
+ writeJson(res, 400, { error: err.message });
459
+ }
460
+ return;
461
+ }
462
+ if (method === 'POST' && pathname === '/api/operations/settings/set') {
463
+ const body = await readJsonBody(req);
464
+ const key = toNonEmptyString(body['key']);
465
+ const value = body['value'];
466
+ if (!key || value === undefined) {
467
+ writeJson(res, 400, { error: 'key and value are required' });
468
+ return;
469
+ }
470
+ try {
471
+ const result = await handleToolCall('night-orch-set-setting', withMcpMutationAuth({ key, value }, security), deps);
472
+ writeJson(res, 200, result);
473
+ }
474
+ catch (err) {
475
+ if (isRuntimeSettingInputError(err)) {
476
+ writeJson(res, 400, { error: err.message });
477
+ return;
478
+ }
479
+ throw err;
480
+ }
481
+ return;
482
+ }
483
+ if (method === 'POST' && pathname === '/api/operations/settings/clear') {
484
+ const body = await readJsonBody(req);
485
+ const key = toNonEmptyString(body['key']);
486
+ if (!key) {
487
+ writeJson(res, 400, { error: 'key is required' });
488
+ return;
489
+ }
490
+ try {
491
+ const result = await handleToolCall('night-orch-clear-setting', withMcpMutationAuth({ key }, security), deps);
492
+ writeJson(res, 200, result);
493
+ }
494
+ catch (err) {
495
+ if (isRuntimeSettingInputError(err)) {
496
+ writeJson(res, 400, { error: err.message });
497
+ return;
498
+ }
499
+ throw err;
500
+ }
501
+ return;
502
+ }
503
+ if (method === 'GET' && pathname === '/api/update-status') {
504
+ const statusPath = resolve(homedir(), '.config', 'night-orch', 'update-status.json');
505
+ try {
506
+ const parsed = JSON.parse(readFileSync(statusPath, 'utf-8'));
507
+ const status = {
508
+ state: typeof parsed['state'] === 'string' ? parsed['state'] : 'idle',
509
+ ...(typeof parsed['error'] === 'string' ? { error: parsed['error'] } : {}),
510
+ };
511
+ writeJson(res, 200, status);
512
+ }
513
+ catch {
514
+ writeJson(res, 200, { state: 'idle' });
515
+ }
516
+ return;
517
+ }
518
+ if (method === 'POST' && pathname === '/api/operations/update') {
519
+ // Try IPC first (running under supervisor)
520
+ if (typeof process.send === 'function') {
521
+ process.send({ type: 'update-requested' });
522
+ writeJson(res, 200, { accepted: true, method: 'ipc' });
523
+ return;
524
+ }
525
+ // Fallback: trigger file
526
+ const dataDir = resolve(homedir(), '.config', 'night-orch');
527
+ const triggerPath = resolve(dataDir, 'update-requested');
528
+ mkdirSync(dataDir, { recursive: true });
529
+ writeFileSync(triggerPath, nowUtcIso());
530
+ writeJson(res, 200, { accepted: true, method: 'trigger-file' });
531
+ return;
532
+ }
533
+ writeJson(res, 404, { error: `Unknown API route: ${method} ${pathname}` });
534
+ }
535
+ async function serveFrontend(req, res, pathname, frontendDistPath, hasFrontendAssets) {
536
+ const method = req.method ?? 'GET';
537
+ if (method !== 'GET' && method !== 'HEAD') {
538
+ writeJson(res, 405, { error: 'Method not allowed' });
539
+ return;
540
+ }
541
+ if (!hasFrontendAssets) {
542
+ writeJson(res, 503, {
543
+ error: 'Frontend assets not available',
544
+ hint: 'Run `pnpm web:build` to build the frontend assets.',
545
+ });
546
+ return;
547
+ }
548
+ const relativePath = pathname === '/' ? '/index.html' : pathname;
549
+ const targetPath = resolve(frontendDistPath, `.${relativePath}`);
550
+ // Path-traversal guard: `targetPath.startsWith(frontendDistPath)` alone
551
+ // is insufficient — a sibling directory such as `frontendDistPath` +
552
+ // "-stash" would pass. Require exact match or a true subdirectory path.
553
+ if (targetPath !== frontendDistPath && !targetPath.startsWith(frontendDistPath + sep)) {
554
+ writeJson(res, 403, { error: 'Forbidden path' });
555
+ return;
556
+ }
557
+ const candidatePath = await pickExistingFile(targetPath);
558
+ if (!candidatePath && extname(relativePath) !== '') {
559
+ writeJson(res, 404, { error: 'Not found' });
560
+ return;
561
+ }
562
+ const filePath = candidatePath ?? resolve(frontendDistPath, 'index.html');
563
+ try {
564
+ const body = await readFile(filePath);
565
+ const contentType = CONTENT_TYPES[extname(filePath)] ?? 'application/octet-stream';
566
+ const isIndex = filePath.endsWith('/index.html');
567
+ const cacheControl = isIndex ? 'no-cache' : 'public, max-age=31536000, immutable';
568
+ res.writeHead(200, {
569
+ 'Content-Type': contentType,
570
+ 'Cache-Control': cacheControl,
571
+ });
572
+ if (method === 'HEAD') {
573
+ res.end();
574
+ return;
575
+ }
576
+ res.end(body);
577
+ }
578
+ catch (err) {
579
+ logger.warn({ err, filePath }, 'Failed to serve frontend asset');
580
+ writeJson(res, 500, { error: 'Failed to read frontend asset' });
581
+ }
582
+ }
583
+ async function pickExistingFile(path) {
584
+ try {
585
+ const metadata = await stat(path);
586
+ if (metadata.isFile()) {
587
+ return path;
588
+ }
589
+ }
590
+ catch {
591
+ // not found
592
+ }
593
+ return null;
594
+ }
595
+ async function readJsonBody(req) {
596
+ const chunks = [];
597
+ let size = 0;
598
+ for await (const chunk of req) {
599
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
600
+ size += buffer.length;
601
+ if (size > ONE_MEGABYTE) {
602
+ throw new Error('Request body too large');
603
+ }
604
+ chunks.push(buffer);
605
+ }
606
+ if (chunks.length === 0) {
607
+ return {};
608
+ }
609
+ const body = Buffer.concat(chunks).toString('utf-8').trim();
610
+ if (!body) {
611
+ return {};
612
+ }
613
+ try {
614
+ const parsed = JSON.parse(body);
615
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
616
+ throw new Error('JSON body must be an object');
617
+ }
618
+ return parsed;
619
+ }
620
+ catch (err) {
621
+ throw new Error(`Invalid JSON body: ${err.message}`);
622
+ }
623
+ }
624
+ function getRequestUrl(req) {
625
+ return new URL(req.url ?? '/', 'http://localhost');
626
+ }
627
+ function validateMutationRequest(req, security) {
628
+ if (!isAllowedRequestHost(req, security)) {
629
+ return { statusCode: 403, error: 'Forbidden host' };
630
+ }
631
+ if (!hasAllowedOrigin(req, security, true)) {
632
+ return { statusCode: 403, error: 'Forbidden origin' };
633
+ }
634
+ const intent = getSingleHeaderValue(req.headers[MUTATION_INTENT_HEADER]);
635
+ if (intent !== MUTATION_INTENT_VALUE) {
636
+ return { statusCode: 403, error: `Missing required header: ${MUTATION_INTENT_HEADER}` };
637
+ }
638
+ const contentType = getSingleHeaderValue(req.headers['content-type']);
639
+ if (!contentType || !isJsonContentType(contentType)) {
640
+ return { statusCode: 415, error: 'Content-Type must be application/json' };
641
+ }
642
+ const webToken = getSingleHeaderValue(req.headers[WEB_AUTH_TOKEN_HEADER]);
643
+ if (!webToken) {
644
+ return { statusCode: 401, error: `Missing required header: ${WEB_AUTH_TOKEN_HEADER}` };
645
+ }
646
+ if (!isMatchingToken(webToken, security.webMutationToken)) {
647
+ return { statusCode: 403, error: 'Invalid web auth token' };
648
+ }
649
+ return null;
650
+ }
651
+ function hasAllowedOrigin(req, security, allowMissingOrigin) {
652
+ const originHeader = getSingleHeaderValue(req.headers.origin);
653
+ if (!originHeader) {
654
+ return allowMissingOrigin;
655
+ }
656
+ let originUrl;
657
+ try {
658
+ originUrl = new URL(originHeader);
659
+ }
660
+ catch {
661
+ return false;
662
+ }
663
+ if (originUrl.protocol !== 'http:' && originUrl.protocol !== 'https:') {
664
+ return false;
665
+ }
666
+ return security.allowedHostnames.has(originUrl.hostname.toLowerCase());
667
+ }
668
+ function isJsonContentType(contentType) {
669
+ const normalized = contentType.split(';')[0]?.trim().toLowerCase();
670
+ return normalized === 'application/json';
671
+ }
672
+ function getSingleHeaderValue(value) {
673
+ if (Array.isArray(value)) {
674
+ return value[0]?.trim() || null;
675
+ }
676
+ if (typeof value === 'string') {
677
+ const trimmed = value.trim();
678
+ return trimmed.length > 0 ? trimmed : null;
679
+ }
680
+ return null;
681
+ }
682
+ function withMcpMutationAuth(args, security) {
683
+ if (!security.mcpMutationAuthToken) {
684
+ return args;
685
+ }
686
+ return {
687
+ ...args,
688
+ authToken: security.mcpMutationAuthToken,
689
+ };
690
+ }
691
+ function createWebSecurityContext(deps, options) {
692
+ // When bound to a non-loopback address, the operator-supplied env var
693
+ // IS the mutation token. The startup guard in startWebServer() ensures
694
+ // the env var is set before we get here. Using it directly means the
695
+ // /api/session endpoint can refuse to disclose it — the operator gives
696
+ // the token to trusted clients out-of-band (browser extension, curl
697
+ // header, etc).
698
+ //
699
+ // For loopback binds, keep the random-per-process token and disclose it
700
+ // via /api/session as before — the risk is low when only local processes
701
+ // can reach the server.
702
+ const operatorToken = process.env['NIGHT_ORCH_WEB_AUTH_TOKEN'];
703
+ const bindHostName = normalizeHostname(options.host) ?? options.host;
704
+ const isLoopback = bindHostName === '127.0.0.1'
705
+ || bindHostName === '::1'
706
+ || bindHostName === 'localhost'
707
+ || bindHostName === '';
708
+ const operatorAuthMode = !isLoopback && !!operatorToken;
709
+ return {
710
+ allowedHostnames: resolveAllowedHostnames(options.host, options.allowedHosts ?? []),
711
+ webMutationToken: operatorAuthMode ? operatorToken : randomBytes(24).toString('base64url'),
712
+ mcpMutationAuthToken: resolveMcpMutationAuthToken(deps),
713
+ operatorAuthMode,
714
+ };
715
+ }
716
+ function resolveAllowedHostnames(bindHost, configuredAllowedHosts) {
717
+ const hostnames = new Set();
718
+ const bindHostName = normalizeHostname(bindHost);
719
+ if (bindHostName && bindHostName !== '0.0.0.0' && bindHostName !== '::') {
720
+ addAllowedHostname(hostnames, bindHostName);
721
+ }
722
+ for (const rawHost of configuredAllowedHosts) {
723
+ const normalized = normalizeHostname(rawHost);
724
+ if (!normalized)
725
+ continue;
726
+ addAllowedHostname(hostnames, normalized);
727
+ }
728
+ if (hostnames.size === 0) {
729
+ throw new Error('No allowed web hosts configured. Use a concrete --host or provide one or more --allowed-host values.');
730
+ }
731
+ return hostnames;
732
+ }
733
+ function addAllowedHostname(allowedHostnames, hostname) {
734
+ if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1') {
735
+ allowedHostnames.add('localhost');
736
+ allowedHostnames.add('127.0.0.1');
737
+ allowedHostnames.add('::1');
738
+ return;
739
+ }
740
+ allowedHostnames.add(hostname);
741
+ }
742
+ function normalizeHostname(value) {
743
+ const trimmed = value.trim();
744
+ if (trimmed.length === 0) {
745
+ return null;
746
+ }
747
+ const candidates = trimmed.includes('://')
748
+ ? [trimmed]
749
+ : [
750
+ `http://${trimmed}`,
751
+ ...(trimmed.includes(':') && !trimmed.startsWith('[') ? [`http://[${trimmed}]`] : []),
752
+ ];
753
+ for (const candidate of candidates) {
754
+ try {
755
+ const parsed = new URL(candidate);
756
+ const hostname = parsed.hostname.toLowerCase();
757
+ if (hostname.length > 0) {
758
+ return hostname;
759
+ }
760
+ }
761
+ catch {
762
+ // try next parse candidate
763
+ }
764
+ }
765
+ return null;
766
+ }
767
+ function isAllowedRequestHost(req, security) {
768
+ const hostHeader = getSingleHeaderValue(req.headers.host);
769
+ if (!hostHeader) {
770
+ return false;
771
+ }
772
+ const hostname = normalizeHostname(hostHeader);
773
+ if (!hostname) {
774
+ return false;
775
+ }
776
+ return security.allowedHostnames.has(hostname);
777
+ }
778
+ function resolveMcpMutationAuthToken(deps) {
779
+ const tokenEnv = deps.config.mcp.authTokenEnv;
780
+ if (!tokenEnv) {
781
+ return undefined;
782
+ }
783
+ const token = process.env[tokenEnv];
784
+ if (!token) {
785
+ throw new Error(`MCP auth token env var ${tokenEnv} is configured but not set`);
786
+ }
787
+ return token;
788
+ }
789
+ function isMatchingToken(providedToken, expectedToken) {
790
+ const providedHash = createHash('sha256').update(providedToken).digest();
791
+ const expectedHash = createHash('sha256').update(expectedToken).digest();
792
+ return timingSafeEqual(providedHash, expectedHash);
793
+ }
794
+ function rejectUpgrade(socket, statusCode, message) {
795
+ const payload = `${message}\n`;
796
+ socket.write(`HTTP/1.1 ${statusCode} ${message}\r\n` +
797
+ 'Connection: close\r\n' +
798
+ 'Content-Type: text/plain; charset=utf-8\r\n' +
799
+ `Content-Length: ${Buffer.byteLength(payload)}\r\n` +
800
+ '\r\n' +
801
+ payload);
802
+ socket.destroy();
803
+ }
804
+ function writeJson(res, status, payload) {
805
+ res.writeHead(status, { 'Content-Type': 'application/json; charset=utf-8' });
806
+ res.end(JSON.stringify(payload));
807
+ }
808
+ function toBoundedInt(value, fallback, min, max) {
809
+ const parsed = typeof value === 'number'
810
+ ? value
811
+ : typeof value === 'string'
812
+ ? Number.parseInt(value, 10)
813
+ : NaN;
814
+ if (!Number.isFinite(parsed)) {
815
+ return fallback;
816
+ }
817
+ return Math.max(min, Math.min(max, Math.floor(parsed)));
818
+ }
819
+ function toNonEmptyString(value) {
820
+ if (typeof value !== 'string') {
821
+ return null;
822
+ }
823
+ const trimmed = value.trim();
824
+ return trimmed.length > 0 ? trimmed : null;
825
+ }
826
+ function toFiniteNumber(value) {
827
+ const parsed = typeof value === 'number'
828
+ ? value
829
+ : typeof value === 'string'
830
+ ? Number.parseFloat(value)
831
+ : NaN;
832
+ return Number.isFinite(parsed) ? parsed : null;
833
+ }
834
+ async function buildDashboardSnapshot(deps) {
835
+ const runtimeConfig = resolveConfigWithRuntimeSettings(deps.config, deps.db);
836
+ const runtimeDeps = {
837
+ ...deps,
838
+ config: runtimeConfig,
839
+ };
840
+ const [status, runs, cost] = await Promise.all([
841
+ handleToolCall('night-orch-status', {}, runtimeDeps),
842
+ handleToolCall('night-orch-list-runs', { limit: 100 }, runtimeDeps),
843
+ handleToolCall('night-orch-cost-report', { days: 7 }, runtimeDeps),
844
+ ]);
845
+ return {
846
+ generatedAt: nowUtcIso(),
847
+ status,
848
+ runs,
849
+ cost,
850
+ build: BUILD_INFO,
851
+ config: {
852
+ repos: runtimeConfig.repos.map((repo) => repo.repo),
853
+ pollIntervalSeconds: runtimeConfig.github.pollIntervalSeconds,
854
+ },
855
+ stats: loadTuiStats(runtimeDeps.db, { costModel: runtimeConfig.cost.model }),
856
+ };
857
+ }
858
+ function buildProjectsSnapshot(deps) {
859
+ return {
860
+ generatedAt: nowUtcIso(),
861
+ githubDefaults: {
862
+ tokenEnv: deps.config.github.tokenEnv,
863
+ apiBaseUrl: deps.config.github.apiBaseUrl,
864
+ },
865
+ workerProfiles: Object.fromEntries(Object.entries(deps.config.workerProfiles).map(([name, profile]) => [
866
+ name,
867
+ sanitizeWorkerProfile(profile),
868
+ ])),
869
+ repos: deps.config.repos.map((repo) => sanitizeProjectRepo(repo)),
870
+ };
871
+ }
872
+ function buildSettingsSnapshot(deps, rawConfig) {
873
+ const runtimeSettings = listRuntimeSettings(deps.config, deps.db);
874
+ return {
875
+ generatedAt: nowUtcIso(),
876
+ settings: runtimeSettings.map((setting) => {
877
+ const definition = getSettingDefinition(setting.key);
878
+ if (!definition) {
879
+ return {
880
+ ...setting,
881
+ hasYamlValue: false,
882
+ yamlValue: null,
883
+ };
884
+ }
885
+ const { hasYamlValue, yamlValue } = resolveSettingYamlValue(definition, rawConfig, deps.config);
886
+ return {
887
+ ...setting,
888
+ hasYamlValue,
889
+ yamlValue,
890
+ };
891
+ }),
892
+ };
893
+ }
894
+ function sanitizeWorkerProfile(profile) {
895
+ return {
896
+ type: profile.type,
897
+ command: profile.command,
898
+ args: [...profile.args],
899
+ workerTimeoutSeconds: profile.workerTimeoutSeconds,
900
+ minimalEnv: profile.minimalEnv,
901
+ runtimeWrapper: profile.runtimeWrapper,
902
+ envKeys: Object.keys(profile.env),
903
+ };
904
+ }
905
+ function sanitizeProjectRepo(repo) {
906
+ return {
907
+ repo: repo.repo,
908
+ forge: repo.forge,
909
+ linkedProjects: [...repo.linkedProjects],
910
+ apiBaseUrl: repo.apiBaseUrl,
911
+ tokenEnv: repo.tokenEnv,
912
+ maxConcurrentRuns: repo.maxConcurrentRuns,
913
+ localPath: repo.localPath,
914
+ baseBranch: repo.baseBranch,
915
+ branchPrefix: repo.branchPrefix,
916
+ labels: sanitizeLabels(repo.labels),
917
+ ...(repo.kanban
918
+ ? {
919
+ kanban: {
920
+ triggerLabel: repo.kanban.triggerLabel,
921
+ labels: sanitizeLabels(repo.kanban.labels),
922
+ },
923
+ }
924
+ : {}),
925
+ labelConfig: Object.fromEntries(Object.entries(repo.labelConfig).map(([label, config]) => [
926
+ label,
927
+ {
928
+ ...(config.color ? { color: config.color } : {}),
929
+ ...(config.description ? { description: config.description } : {}),
930
+ },
931
+ ])),
932
+ defaults: {
933
+ planner: repo.defaults.planner,
934
+ coder: repo.defaults.coder,
935
+ reviewer: repo.defaults.reviewer,
936
+ doneMode: repo.defaults.doneMode,
937
+ notifyPriority: repo.defaults.notifyPriority,
938
+ prMentions: [...repo.defaults.prMentions],
939
+ },
940
+ ...(repo.environment ? { environment: sanitizeEnvironment(repo.environment) } : {}),
941
+ verify: repo.verify.map((command) => copyCommandSpec(command)),
942
+ prompts: {
943
+ plannerSystem: Boolean(repo.prompts?.plannerSystem),
944
+ coderSystem: Boolean(repo.prompts?.coderSystem),
945
+ reviewerSystem: Boolean(repo.prompts?.reviewerSystem),
946
+ },
947
+ planning: {
948
+ prdDirectory: repo.planning.prdDirectory,
949
+ },
950
+ selectors: {
951
+ includeLabelsAny: [...repo.selectors.includeLabelsAny],
952
+ excludeLabelsAny: [...repo.selectors.excludeLabelsAny],
953
+ },
954
+ agents: { ...repo.agents },
955
+ ...(repo.workflow ? { workflow: repo.workflow } : {}),
956
+ ...(repo.workflowByTriage ? { workflowByTriage: { ...repo.workflowByTriage } } : {}),
957
+ mergeQueue: {
958
+ enabled: repo.mergeQueue.enabled,
959
+ batchSize: repo.mergeQueue.batchSize,
960
+ mergeMethod: repo.mergeQueue.mergeMethod,
961
+ retryFlakyOnce: repo.mergeQueue.retryFlakyOnce,
962
+ requireApproval: repo.mergeQueue.requireApproval,
963
+ stagingBranchPrefix: repo.mergeQueue.stagingBranchPrefix,
964
+ },
965
+ };
966
+ }
967
+ function sanitizeEnvironment(environment) {
968
+ return {
969
+ defaultMode: environment.defaultMode,
970
+ ...(environment.dedicated
971
+ ? {
972
+ dedicated: {
973
+ compose: {
974
+ file: environment.dedicated.compose.file,
975
+ services: [...environment.dedicated.compose.services],
976
+ projectName: environment.dedicated.compose.projectName,
977
+ },
978
+ env: {
979
+ copyFrom: environment.dedicated.env.copyFrom,
980
+ overrideKeys: Object.keys(environment.dedicated.env.overrides),
981
+ overrideFiles: [...environment.dedicated.env.overrideFiles],
982
+ },
983
+ ...(environment.dedicated.healthcheck
984
+ ? { healthcheck: copyCommandSpec(environment.dedicated.healthcheck) }
985
+ : {}),
986
+ teardownOnComplete: environment.dedicated.teardownOnComplete,
987
+ },
988
+ }
989
+ : {}),
990
+ ...(environment.shared
991
+ ? {
992
+ shared: {
993
+ requireRunning: environment.shared.requireRunning,
994
+ ...(environment.shared.healthcheck
995
+ ? { healthcheck: copyCommandSpec(environment.shared.healthcheck) }
996
+ : {}),
997
+ },
998
+ }
999
+ : {}),
1000
+ bootstrap: environment.bootstrap.map((step) => ({
1001
+ when: step.when,
1002
+ command: copyCommandSpec(step.command),
1003
+ ...(step.failureHints && step.failureHints.length > 0
1004
+ ? {
1005
+ failureHints: step.failureHints.map((hint) => ({
1006
+ contains: hint.contains,
1007
+ message: hint.message,
1008
+ output: hint.output,
1009
+ })),
1010
+ }
1011
+ : {}),
1012
+ })),
1013
+ cleanup: environment.cleanup.map((step) => ({
1014
+ when: step.when,
1015
+ command: copyCommandSpec(step.command),
1016
+ ...(step.failureHints && step.failureHints.length > 0
1017
+ ? {
1018
+ failureHints: step.failureHints.map((hint) => ({
1019
+ contains: hint.contains,
1020
+ message: hint.message,
1021
+ output: hint.output,
1022
+ })),
1023
+ }
1024
+ : {}),
1025
+ })),
1026
+ };
1027
+ }
1028
+ function sanitizeLabels(labels) {
1029
+ return {
1030
+ ready: [...labels.ready],
1031
+ running: labels.running,
1032
+ blocked: normalizeLabelValue(labels.blocked),
1033
+ needsHuman: labels.needsHuman,
1034
+ reviewReady: labels.reviewReady,
1035
+ error: labels.error,
1036
+ retry: labels.retry,
1037
+ planning: labels.planning,
1038
+ mergeQueued: labels.mergeQueued,
1039
+ merging: labels.merging,
1040
+ mergeFailed: labels.mergeFailed,
1041
+ };
1042
+ }
1043
+ function normalizeLabelValue(value) {
1044
+ if (typeof value === 'string')
1045
+ return value;
1046
+ if (Array.isArray(value)) {
1047
+ return value.find((entry) => typeof entry === 'string') ?? '';
1048
+ }
1049
+ return '';
1050
+ }
1051
+ function copyCommandSpec(command) {
1052
+ if (Array.isArray(command)) {
1053
+ return [...command];
1054
+ }
1055
+ return command;
1056
+ }
1057
+ async function handleWsMessage(ws, state, rawMessage, deps) {
1058
+ let command;
1059
+ try {
1060
+ command = JSON.parse(rawMessage);
1061
+ }
1062
+ catch {
1063
+ sendWebsocket(ws, { type: 'error', error: 'Invalid JSON message' });
1064
+ return;
1065
+ }
1066
+ if (command.type === 'subscribe-run-events') {
1067
+ const runId = typeof command.runId === 'string' ? command.runId : '';
1068
+ if (!runId) {
1069
+ sendWebsocket(ws, { type: 'error', error: 'runId is required for subscribe-run-events' });
1070
+ return;
1071
+ }
1072
+ const cursor = Number.isFinite(command.since) ? Math.max(0, Math.floor(command.since ?? 0)) : 0;
1073
+ state.runSubscriptions.set(runId, cursor);
1074
+ sendWebsocket(ws, { type: 'subscribed', payload: { runId, since: cursor } });
1075
+ return;
1076
+ }
1077
+ if (command.type === 'unsubscribe-run-events') {
1078
+ const runId = typeof command.runId === 'string' ? command.runId : '';
1079
+ if (!runId) {
1080
+ sendWebsocket(ws, { type: 'error', error: 'runId is required for unsubscribe-run-events' });
1081
+ return;
1082
+ }
1083
+ state.runSubscriptions.delete(runId);
1084
+ sendWebsocket(ws, { type: 'unsubscribed', payload: { runId } });
1085
+ return;
1086
+ }
1087
+ if (command.type === 'refresh') {
1088
+ const snapshot = await buildDashboardSnapshot(deps);
1089
+ sendWebsocket(ws, { type: 'snapshot', payload: snapshot });
1090
+ return;
1091
+ }
1092
+ sendWebsocket(ws, { type: 'error', error: 'Unknown command type' });
1093
+ }
1094
+ async function publishRunSubscriptions(ws, state, deps) {
1095
+ for (const [runId, since] of state.runSubscriptions.entries()) {
1096
+ try {
1097
+ const result = await handleToolCall('night-orch-stream-events', { runId, since, limit: 200 }, deps);
1098
+ const eventPayload = toRunEventPayload(result);
1099
+ if (!eventPayload) {
1100
+ continue;
1101
+ }
1102
+ state.runSubscriptions.set(runId, eventPayload.lastEventId);
1103
+ if (eventPayload.events.length === 0) {
1104
+ continue;
1105
+ }
1106
+ sendWebsocket(ws, {
1107
+ type: 'run-events',
1108
+ payload: {
1109
+ runId,
1110
+ events: eventPayload.events,
1111
+ lastEventId: eventPayload.lastEventId,
1112
+ },
1113
+ });
1114
+ }
1115
+ catch (err) {
1116
+ sendWebsocket(ws, {
1117
+ type: 'error',
1118
+ error: `Failed to stream events for ${runId}: ${err.message}`,
1119
+ });
1120
+ }
1121
+ }
1122
+ }
1123
+ function toRunEventPayload(input) {
1124
+ if (!input || typeof input !== 'object')
1125
+ return null;
1126
+ const maybeEvents = input.events;
1127
+ const maybeLastEventId = input.lastEventId;
1128
+ if (!Array.isArray(maybeEvents))
1129
+ return null;
1130
+ if (typeof maybeLastEventId !== 'number' || !Number.isFinite(maybeLastEventId))
1131
+ return null;
1132
+ return {
1133
+ events: maybeEvents,
1134
+ lastEventId: Math.max(0, Math.floor(maybeLastEventId)),
1135
+ };
1136
+ }
1137
+ function sendWebsocket(ws, payload) {
1138
+ if (ws.readyState !== WebSocket.OPEN)
1139
+ return;
1140
+ ws.send(JSON.stringify(payload));
1141
+ }
1142
+ function isClientRequestError(message) {
1143
+ return message.startsWith('Invalid JSON body') || message === 'Request body too large';
1144
+ }
1145
+ function isAuthorizationError(message) {
1146
+ return message.startsWith('Unauthorized:');
1147
+ }
1148
+ function isRuntimeSettingInputError(err) {
1149
+ if (err instanceof RuntimeSettingInputError) {
1150
+ return true;
1151
+ }
1152
+ return err instanceof Error && err.name === 'RuntimeSettingInputError';
1153
+ }
1154
+ function decodeWsMessage(raw) {
1155
+ if (typeof raw === 'string') {
1156
+ return raw;
1157
+ }
1158
+ if (raw instanceof Buffer) {
1159
+ return raw.toString('utf-8');
1160
+ }
1161
+ if (raw instanceof ArrayBuffer) {
1162
+ return Buffer.from(raw).toString('utf-8');
1163
+ }
1164
+ if (ArrayBuffer.isView(raw)) {
1165
+ return Buffer.from(raw.buffer, raw.byteOffset, raw.byteLength).toString('utf-8');
1166
+ }
1167
+ if (Array.isArray(raw)) {
1168
+ const buffers = raw
1169
+ .map((item) => {
1170
+ if (item instanceof Buffer)
1171
+ return item;
1172
+ if (item instanceof ArrayBuffer)
1173
+ return Buffer.from(item);
1174
+ if (ArrayBuffer.isView(item))
1175
+ return Buffer.from(item.buffer, item.byteOffset, item.byteLength);
1176
+ return null;
1177
+ })
1178
+ .filter((item) => item !== null);
1179
+ if (buffers.length === 0)
1180
+ return null;
1181
+ return Buffer.concat(buffers).toString('utf-8');
1182
+ }
1183
+ return null;
1184
+ }
1185
+ //# sourceMappingURL=server.js.map