@repo-os/repoos 0.5.56 → 0.5.57

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 (322) hide show
  1. package/dist/.build-info.json +3 -2
  2. package/dist/.build-stamp.json +1 -1
  3. package/dist/cli/index.js +4 -1
  4. package/dist/commands/check.d.ts +8 -7
  5. package/dist/commands/check.js +257 -49
  6. package/dist/commands/init.js +39 -33
  7. package/dist/core/auth-store.d.ts +89 -0
  8. package/dist/core/auth-store.js +603 -0
  9. package/dist/core/board-columns.test.js +18 -0
  10. package/dist/core/build.d.ts +2 -0
  11. package/dist/core/build.js +5 -3
  12. package/dist/core/check-plan.d.ts +28 -0
  13. package/dist/core/check-plan.js +44 -0
  14. package/dist/core/check-store.d.ts +88 -0
  15. package/dist/core/check-store.js +264 -0
  16. package/dist/core/config.js +270 -31
  17. package/dist/core/copy-inspector.d.ts +25 -0
  18. package/dist/core/copy-inspector.js +112 -0
  19. package/dist/core/db.js +32 -0
  20. package/dist/core/git.d.ts +78 -7
  21. package/dist/core/git.js +115 -10
  22. package/dist/core/needs-input.d.ts +2 -0
  23. package/dist/core/needs-input.js +6 -0
  24. package/dist/core/pm-question-context.d.ts +6 -0
  25. package/dist/core/pm-question-context.js +20 -0
  26. package/dist/core/remote-hosts.d.ts +52 -0
  27. package/dist/core/remote-hosts.js +137 -0
  28. package/dist/core/repo-log.d.ts +4 -0
  29. package/dist/core/repo-log.js +6 -1
  30. package/dist/core/runtime.d.ts +2 -0
  31. package/dist/core/runtime.js +62 -0
  32. package/dist/core/secret-store.d.ts +20 -0
  33. package/dist/core/secret-store.js +73 -0
  34. package/dist/core/secret-store.test.d.ts +1 -0
  35. package/dist/core/secret-store.test.js +38 -0
  36. package/dist/core/stories.d.ts +19 -0
  37. package/dist/core/stories.js +117 -0
  38. package/dist/core/story-definition-files.d.ts +39 -2
  39. package/dist/core/story-definition-files.js +197 -11
  40. package/dist/core/story-display.d.ts +9 -1
  41. package/dist/core/story-display.js +2 -0
  42. package/dist/core/support-bundle.js +4 -0
  43. package/dist/core/task-underspecified.d.ts +12 -0
  44. package/dist/core/task-underspecified.js +99 -0
  45. package/dist/core/task.js +17 -0
  46. package/dist/core/telegram-chat.d.ts +77 -0
  47. package/dist/core/telegram-chat.js +220 -0
  48. package/dist/core/telegram-disconnect.d.ts +19 -0
  49. package/dist/core/telegram-disconnect.js +40 -0
  50. package/dist/core/telegram-identity.d.ts +102 -0
  51. package/dist/core/telegram-identity.js +262 -0
  52. package/dist/core/types.d.ts +162 -5
  53. package/dist/core/types.js +3 -1
  54. package/dist/core/worktree-gc.js +10 -4
  55. package/dist/server/agents.d.ts +51 -9
  56. package/dist/server/agents.js +135 -46
  57. package/dist/server/branchless-release.js +8 -5
  58. package/dist/server/debug-tldr.d.ts +101 -0
  59. package/dist/server/debug-tldr.js +311 -0
  60. package/dist/server/done.d.ts +16 -0
  61. package/dist/server/done.js +45 -3
  62. package/dist/server/freeform-runs.js +4 -1
  63. package/dist/server/handoff.d.ts +19 -2
  64. package/dist/server/handoff.js +216 -36
  65. package/dist/server/integration-job.d.ts +20 -0
  66. package/dist/server/integration-job.js +27 -0
  67. package/dist/server/integration-orchestrator.d.ts +91 -1
  68. package/dist/server/integration-orchestrator.js +287 -59
  69. package/dist/server/live-index.d.ts +31 -1
  70. package/dist/server/live-index.js +25 -1
  71. package/dist/server/needs-input-dismiss.d.ts +14 -0
  72. package/dist/server/needs-input-dismiss.js +51 -1
  73. package/dist/server/notifications/dispatch.d.ts +32 -0
  74. package/dist/server/notifications/dispatch.js +238 -0
  75. package/dist/server/notifications/format.d.ts +14 -0
  76. package/dist/server/notifications/format.js +23 -0
  77. package/dist/server/notifications/index.d.ts +9 -0
  78. package/dist/server/notifications/index.js +8 -0
  79. package/dist/server/notifications/link.d.ts +14 -0
  80. package/dist/server/notifications/link.js +45 -0
  81. package/dist/server/notifications/ntfy-provider.d.ts +10 -0
  82. package/dist/server/notifications/ntfy-provider.js +81 -0
  83. package/dist/server/notifications/progress.d.ts +14 -0
  84. package/dist/server/notifications/progress.js +26 -0
  85. package/dist/server/notifications/reasons.d.ts +6 -0
  86. package/dist/server/notifications/reasons.js +14 -0
  87. package/dist/server/notifications/spec.d.ts +27 -0
  88. package/dist/server/notifications/spec.js +79 -0
  89. package/dist/server/notifications/telegram-provider.d.ts +6 -0
  90. package/dist/server/notifications/telegram-provider.js +74 -0
  91. package/dist/server/notifications/types.d.ts +41 -0
  92. package/dist/server/notifications/types.js +1 -0
  93. package/dist/server/ntfy.d.ts +7 -48
  94. package/dist/server/ntfy.js +16 -102
  95. package/dist/server/pre-review-remote-gate.d.ts +101 -0
  96. package/dist/server/pre-review-remote-gate.js +163 -0
  97. package/dist/server/release.js +21 -28
  98. package/dist/server/reload.js +15 -10
  99. package/dist/server/remote-validation.d.ts +504 -11
  100. package/dist/server/remote-validation.js +1493 -57
  101. package/dist/server/review.d.ts +3 -1
  102. package/dist/server/review.js +87 -8
  103. package/dist/server/routes/auth.d.ts +11 -1
  104. package/dist/server/routes/auth.js +7 -1
  105. package/dist/server/routes/check-runs.d.ts +14 -0
  106. package/dist/server/routes/check-runs.js +29 -0
  107. package/dist/server/routes/config.d.ts +9 -0
  108. package/dist/server/routes/config.js +149 -2
  109. package/dist/server/routes/copy-inspector.d.ts +11 -0
  110. package/dist/server/routes/copy-inspector.js +73 -0
  111. package/dist/server/routes/debugger.d.ts +10 -0
  112. package/dist/server/routes/debugger.js +4 -1
  113. package/dist/server/routes/helpers.d.ts +1 -0
  114. package/dist/server/routes/helpers.js +3 -1
  115. package/dist/server/routes/index.d.ts +5 -0
  116. package/dist/server/routes/index.js +5 -0
  117. package/dist/server/routes/info.js +2 -0
  118. package/dist/server/routes/repo-log.js +2 -1
  119. package/dist/server/routes/stories.d.ts +19 -1
  120. package/dist/server/routes/stories.js +179 -3
  121. package/dist/server/routes/tasks.d.ts +1 -0
  122. package/dist/server/routes/tasks.js +188 -9
  123. package/dist/server/routes/telegram-identity.d.ts +27 -0
  124. package/dist/server/routes/telegram-identity.js +290 -0
  125. package/dist/server/routes/telegram-webhook.d.ts +8 -0
  126. package/dist/server/routes/telegram-webhook.js +98 -0
  127. package/dist/server/routes/telegram.d.ts +36 -0
  128. package/dist/server/routes/telegram.js +411 -0
  129. package/dist/server/server.d.ts +19 -11
  130. package/dist/server/server.js +262 -55
  131. package/dist/server/story-pm.d.ts +1 -0
  132. package/dist/server/story-pm.js +5 -0
  133. package/dist/server/task-check.d.ts +24 -2
  134. package/dist/server/task-check.js +48 -2
  135. package/dist/server/task-underspecified-flag.d.ts +8 -0
  136. package/dist/server/task-underspecified-flag.js +35 -0
  137. package/dist/server/task-watchdog.d.ts +8 -0
  138. package/dist/server/task-watchdog.js +14 -8
  139. package/dist/server/telegram/actor.d.ts +16 -0
  140. package/dist/server/telegram/actor.js +4 -0
  141. package/dist/server/telegram/agent-chat.d.ts +87 -0
  142. package/dist/server/telegram/agent-chat.js +211 -0
  143. package/dist/server/telegram/api.d.ts +136 -0
  144. package/dist/server/telegram/api.js +217 -0
  145. package/dist/server/telegram/commands.d.ts +72 -0
  146. package/dist/server/telegram/commands.js +285 -0
  147. package/dist/server/telegram/disconnect.d.ts +65 -0
  148. package/dist/server/telegram/disconnect.js +147 -0
  149. package/dist/server/telegram/group-addressing.d.ts +15 -0
  150. package/dist/server/telegram/group-addressing.js +53 -0
  151. package/dist/server/telegram/guide-chat.d.ts +147 -0
  152. package/dist/server/telegram/guide-chat.js +296 -0
  153. package/dist/server/telegram/index.d.ts +116 -0
  154. package/dist/server/telegram/index.js +163 -0
  155. package/dist/server/telegram/intake.d.ts +46 -0
  156. package/dist/server/telegram/intake.js +200 -0
  157. package/dist/server/telegram/normalize.d.ts +32 -0
  158. package/dist/server/telegram/normalize.js +125 -0
  159. package/dist/server/telegram/polling.d.ts +81 -0
  160. package/dist/server/telegram/polling.js +214 -0
  161. package/dist/server/telegram/provider.d.ts +137 -0
  162. package/dist/server/telegram/provider.js +805 -0
  163. package/dist/server/telegram/provisioning.d.ts +68 -0
  164. package/dist/server/telegram/provisioning.js +234 -0
  165. package/dist/server/telegram/rate-limits.d.ts +4 -0
  166. package/dist/server/telegram/rate-limits.js +47 -0
  167. package/dist/server/telegram/redact.d.ts +18 -0
  168. package/dist/server/telegram/redact.js +59 -0
  169. package/dist/server/telegram/render.d.ts +51 -0
  170. package/dist/server/telegram/render.js +74 -0
  171. package/dist/server/telegram/store.d.ts +78 -0
  172. package/dist/server/telegram/store.js +226 -0
  173. package/dist/server/telegram/types.d.ts +322 -0
  174. package/dist/server/telegram/types.js +31 -0
  175. package/dist/server/write.js +6 -0
  176. package/dist/ui/assets/ActivityIndicator-BNDj8i9m.js +1 -0
  177. package/dist/ui/assets/AgentModelModal-Ced4h4sp.js +1 -0
  178. package/dist/ui/assets/AgentsView-fJc8ZQRN.js +1 -0
  179. package/dist/ui/assets/ChecksView-CpGuGL1P.js +0 -0
  180. package/dist/ui/assets/ChecksView-DK2wcClf.css +1 -0
  181. package/dist/ui/assets/ContextView-C2ElRI0s.js +4 -0
  182. package/dist/ui/assets/ContextView-CTGAeIvz.css +1 -0
  183. package/dist/ui/assets/DashboardView-BlSDOM4G.js +1 -0
  184. package/dist/ui/assets/DeploymentsView-BEhIaXyw.css +1 -0
  185. package/dist/ui/assets/DeploymentsView-C8mGOGjE.js +1 -0
  186. package/dist/ui/assets/{DiffView-g587DbeS.js → DiffView-nH7u0JwJ.js} +3 -3
  187. package/dist/ui/assets/InputsView-BZ3T5jsY.js +1 -0
  188. package/dist/ui/assets/InputsView-CD5Ajhdh.css +1 -0
  189. package/dist/ui/assets/LoginView-CX6blOC4.js +1 -0
  190. package/dist/ui/assets/ReleasesView-C5PaQX6n.js +3 -0
  191. package/dist/ui/assets/SettingsView-C1xiIbbq.js +4 -0
  192. package/dist/ui/assets/SettingsView-C7KstbuH.css +1 -0
  193. package/dist/ui/assets/StoriesView-BCJnrDOc.js +1 -0
  194. package/dist/ui/assets/StoriesView-C3GxoeML.css +1 -0
  195. package/dist/ui/assets/VoiceDictate-CEyIL7fp.css +1 -0
  196. package/dist/ui/assets/VoiceDictate-CifZUkzt.js +16 -0
  197. package/dist/ui/assets/WorkView-C4lr2ckC.css +1 -0
  198. package/dist/ui/assets/WorkView-CrQ8R4xr.js +2 -0
  199. package/dist/ui/assets/_plugin-vue_export-helper-BDNMzG2s.js +1 -0
  200. package/dist/ui/assets/{abnfDiagram-VCTEODGH-C6WykvNa.js → abnfDiagram-VCTEODGH-CxKkcu03.js} +1 -1
  201. package/dist/ui/assets/api-0vqymbHB.js +1 -0
  202. package/dist/ui/assets/architecture-7GRP2DOG-BKXNQ9fY.js +1 -0
  203. package/dist/ui/assets/{architectureDiagram-5GKGNRK7-roEGL8m0.js → architectureDiagram-5GKGNRK7-B7yFyWIW.js} +1 -1
  204. package/dist/ui/assets/{blockDiagram-I7D4REHJ-DJuucocN.js → blockDiagram-I7D4REHJ-Dqn5piZv.js} +1 -1
  205. package/dist/ui/assets/{button-DQcC_aLE.js → button-BsLUWnfn.js} +1 -1
  206. package/dist/ui/assets/{c4Diagram-7LVT6UL2-6sUrKoSN.js → c4Diagram-7LVT6UL2-BDourwGX.js} +1 -1
  207. package/dist/ui/assets/catppuccin-latte-CtsyrtPq.js +1 -0
  208. package/dist/ui/assets/catppuccin-mocha-DjuaAJKi.js +1 -0
  209. package/dist/ui/assets/channel-DXJt6aEW.js +1 -0
  210. package/dist/ui/assets/checkbox-Bu0fOTRa.js +1 -0
  211. package/dist/ui/assets/{chunk-4HAMMTFA-J0_pcEVf.js → chunk-4HAMMTFA-BGxQ0vmo.js} +1 -1
  212. package/dist/ui/assets/{chunk-75Z2AOVW-BxJ2TNvr.js → chunk-75Z2AOVW-CoD1HiQQ.js} +1 -1
  213. package/dist/ui/assets/{chunk-DU6HZSFF-BX0XMIVw.js → chunk-DU6HZSFF-WQx_PGDE.js} +1 -1
  214. package/dist/ui/assets/{chunk-F27PBJKO-atSjCf8v.js → chunk-F27PBJKO-BmtJFWYx.js} +1 -1
  215. package/dist/ui/assets/{chunk-GMAD6QVW-Bos7znjM.js → chunk-GMAD6QVW-kRmn1tqd.js} +1 -1
  216. package/dist/ui/assets/{chunk-GVQU2GXP-Co0d8Tfs.js → chunk-GVQU2GXP-C2SMD4HM.js} +1 -1
  217. package/dist/ui/assets/{chunk-IMKFNOWR-DkOJUS_A.js → chunk-IMKFNOWR-DRm68yqu.js} +1 -1
  218. package/dist/ui/assets/{chunk-L3NEJ4N5-GBmbBw5A.js → chunk-L3NEJ4N5-Bdd0UO7i.js} +1 -1
  219. package/dist/ui/assets/{chunk-OSK3NFVY-Pao3zNLe.js → chunk-OSK3NFVY-DzFP_5D1.js} +1 -1
  220. package/dist/ui/assets/{chunk-P2QGCYS3-NVMl_E1J.js → chunk-P2QGCYS3-CxTbTe1z.js} +1 -1
  221. package/dist/ui/assets/{chunk-POPQ4Y6H-tzZL78RS.js → chunk-POPQ4Y6H-1sMFzZlT.js} +1 -1
  222. package/dist/ui/assets/{chunk-PWAF6VOD-DwrkqNeH.js → chunk-PWAF6VOD-qwo7mGDG.js} +1 -1
  223. package/dist/ui/assets/{chunk-SHT3W25Y-8I7NMlT4.js → chunk-SHT3W25Y-t7arLGqg.js} +1 -1
  224. package/dist/ui/assets/{chunk-SVP7TREG-BpweZcGw.js → chunk-SVP7TREG-CDGoMrDa.js} +1 -1
  225. package/dist/ui/assets/{chunk-TICWLB2K-B8ZvCXdY.js → chunk-TICWLB2K-DdCRvOgF.js} +1 -1
  226. package/dist/ui/assets/classDiagram-ZZMXUADV-CuXQhOCc.js +1 -0
  227. package/dist/ui/assets/classDiagram-v2-VYDZK3BY-CuXQhOCc.js +1 -0
  228. package/dist/ui/assets/config-CxRkBtUj.js +1 -0
  229. package/dist/ui/assets/{cynefin-OW5HDTMX-BHvKo-Aq.js → cynefin-OW5HDTMX-Dphr1hkJ.js} +1 -1
  230. package/dist/ui/assets/{cynefinDiagram-5FMLGOSQ-3kuG-1VM.js → cynefinDiagram-5FMLGOSQ-BmNfqRyY.js} +1 -1
  231. package/dist/ui/assets/{dagre-GXQ25YYZ-2P8Yk_4G.js → dagre-GXQ25YYZ-0__5BzkZ.js} +1 -1
  232. package/dist/ui/assets/{diagram-S7CK7UJ4-DRs3pJcK.js → diagram-S7CK7UJ4-BCSWodGD.js} +1 -1
  233. package/dist/ui/assets/{diagram-UQ7AKVKN-B3pbA6Zl.js → diagram-UQ7AKVKN-DNY_hqmH.js} +1 -1
  234. package/dist/ui/assets/{diagram-VSXAHHWV-BmFgGjHb.js → diagram-VSXAHHWV-DgEipWnL.js} +1 -1
  235. package/dist/ui/assets/{diagram-VX7I27RA-D5jJPu_a.js → diagram-VX7I27RA-CXqwFFDY.js} +1 -1
  236. package/dist/ui/assets/{diagram-Z3DM3KII-cCr1BFg7.js → diagram-Z3DM3KII-DqGMJic1.js} +1 -1
  237. package/dist/ui/assets/{ebnfDiagram-PWID7BFC-Dg1VhPuY.js → ebnfDiagram-PWID7BFC-O7OLADLR.js} +1 -1
  238. package/dist/ui/assets/{erDiagram-RLTQ6QDP-CT4xW2dC.js → erDiagram-RLTQ6QDP-BLybCuiJ.js} +1 -1
  239. package/dist/ui/assets/eventmodeling-NTZA5JFV-BXXaF1fS.js +1 -0
  240. package/dist/ui/assets/flowDiagram-HODETNUW-HB2tiq05.js +1 -0
  241. package/dist/ui/assets/{ganttDiagram-EL5Y4UJY-Hc1my0Jy.js → ganttDiagram-EL5Y4UJY-PP7LUoJk.js} +1 -1
  242. package/dist/ui/assets/{gitGraph-4MIJSDKK-ClQZHGcg.js → gitGraph-4MIJSDKK-jLh6GWq3.js} +1 -1
  243. package/dist/ui/assets/{gitGraphDiagram-WWUBYQGX-BwlfrDKb.js → gitGraphDiagram-WWUBYQGX-BpQqVPAf.js} +1 -1
  244. package/dist/ui/assets/index-C9k_vHM5.js +46 -0
  245. package/dist/ui/assets/index-DKDq8ZAh.css +1 -0
  246. package/dist/ui/assets/{info-A6RAGUB7-GHiNutT4.js → info-A6RAGUB7-MKojffEb.js} +1 -1
  247. package/dist/ui/assets/{infoDiagram-27XIBGKW-B5tfXwvj.js → infoDiagram-27XIBGKW-CDsY5bPn.js} +1 -1
  248. package/dist/ui/assets/{ishikawaDiagram-5VMMS53U-B8G11EdJ.js → ishikawaDiagram-5VMMS53U-DlkSFpW_.js} +1 -1
  249. package/dist/ui/assets/{journeyDiagram-3NMN7TZE-ubCuNa3S.js → journeyDiagram-3NMN7TZE-BQerIcFQ.js} +1 -1
  250. package/dist/ui/assets/{kanban-definition-UXKFOSKX-RHlFG4is.js → kanban-definition-UXKFOSKX-DcOUAWHk.js} +1 -1
  251. package/dist/ui/assets/{line-DMrn1eUc.js → line-CWe6TPQq.js} +1 -1
  252. package/dist/ui/assets/{mermaid-parser.core-D_ycqYZL.js → mermaid-parser.core-B6lGkbHf.js} +3 -3
  253. package/dist/ui/assets/{mermaid.core-CaXJ86pu.js → mermaid.core-usGEYfph.js} +4 -4
  254. package/dist/ui/assets/{mindmap-definition-YA3MSWOX-kx1nN_cJ.js → mindmap-definition-YA3MSWOX-CRr1hJ6k.js} +1 -1
  255. package/dist/ui/assets/{packet-AYTQ26CC-L5erT19p.js → packet-AYTQ26CC-Vrb5eklN.js} +1 -1
  256. package/dist/ui/assets/{pegDiagram-XKGWAZYB-C_KTXpQM.js → pegDiagram-XKGWAZYB-DWgbaT0F.js} +1 -1
  257. package/dist/ui/assets/{pie-WAS4IAKB-q2S3rGf9.js → pie-WAS4IAKB-EBSi28Ou.js} +1 -1
  258. package/dist/ui/assets/{pieDiagram-E7YTZNPT-BLHxbu3z.js → pieDiagram-E7YTZNPT-CY7kTdf6.js} +1 -1
  259. package/dist/ui/assets/{quadrantDiagram-AXDQQJYC-DNxwy4on.js → quadrantDiagram-AXDQQJYC-DapXMfW1.js} +1 -1
  260. package/dist/ui/assets/{radar-RG4KPBEZ-5paFbTrA.js → radar-RG4KPBEZ-B4g4t9_Y.js} +1 -1
  261. package/dist/ui/assets/{railroad-74A4TZTK-C4zNgPiH.js → railroad-74A4TZTK-DbL2DZlM.js} +1 -1
  262. package/dist/ui/assets/railroad-abnf-HS5TGJTU-SDQCarTw.js +1 -0
  263. package/dist/ui/assets/railroad-ebnf-LZEXJU2U-D9NI_tLh.js +1 -0
  264. package/dist/ui/assets/railroad-peg-WCYAUIDC-kSMa3Mxd.js +1 -0
  265. package/dist/ui/assets/{railroadDiagram-O6MQD6OU-VmXZ6m0T.js → railroadDiagram-O6MQD6OU-Bq4-JY0m.js} +1 -1
  266. package/dist/ui/assets/repo-OUIxzvAy.js +1 -0
  267. package/dist/ui/assets/{requirementDiagram-BXWQKSXE-BHuX0BwK.js → requirementDiagram-BXWQKSXE-CVI43xef.js} +1 -1
  268. package/dist/ui/assets/{sankeyDiagram-P5KCCOFB-5kDwMhVC.js → sankeyDiagram-P5KCCOFB-6igeb8Iu.js} +1 -1
  269. package/dist/ui/assets/{sequenceDiagram-WJ2MYXX4-KSqKjCpq.js → sequenceDiagram-WJ2MYXX4-LYhNaHRI.js} +1 -1
  270. package/dist/ui/assets/{stateDiagram-D77RDMKH-A_P_Un-0.js → stateDiagram-D77RDMKH-VQcHODiY.js} +1 -1
  271. package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-L8aM9etd.js +1 -0
  272. package/dist/ui/assets/{swimlanes-42K2YHIH-BMAnXKSs.js → swimlanes-42K2YHIH-C5U1l1mo.js} +1 -1
  273. package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-Dj94QI7O.js +8 -0
  274. package/dist/ui/assets/time-CwKjNEcq.js +1 -0
  275. package/dist/ui/assets/{timeline-definition-24CTP7MA-BWweJQmR.js → timeline-definition-24CTP7MA-C8YMVaeD.js} +1 -1
  276. package/dist/ui/assets/title-CmTcwJQC.js +1 -0
  277. package/dist/ui/assets/{treeView-Q6P3EWNA-DusMk7Rp.js → treeView-Q6P3EWNA-B4Opgu8L.js} +1 -1
  278. package/dist/ui/assets/{treemap-WGGIJYW6-BoIcxm2V.js → treemap-WGGIJYW6-BWpYq891.js} +1 -1
  279. package/dist/ui/assets/useChatScroll-BD10j3cq.js +1 -0
  280. package/dist/ui/assets/vendor-ui-BbK4TVl8.js +3 -0
  281. package/dist/ui/assets/{vennDiagram-4TSXK5OY-DENh7Izt.js → vennDiagram-4TSXK5OY-BZ7_jhEK.js} +1 -1
  282. package/dist/ui/assets/{wardley-WFR3VGLG-D-IbkF5y.js → wardley-WFR3VGLG-DSF6DKt8.js} +1 -1
  283. package/dist/ui/assets/{wardleyDiagram-VM6X3IG4-Cwsu4-ww.js → wardleyDiagram-VM6X3IG4-ChfzNSSI.js} +1 -1
  284. package/dist/ui/assets/{xychartDiagram-S5SC5T6Z-wZXsbj8s.js → xychartDiagram-S5SC5T6Z-CwDvFw4R.js} +1 -1
  285. package/dist/ui/index.html +15 -7
  286. package/dist/ui/sw.js +2 -2
  287. package/package.json +4 -2
  288. package/dist/ui/assets/AgentsView-CqkgzCze.js +0 -1
  289. package/dist/ui/assets/ChecksView-C0TtYC-4.css +0 -1
  290. package/dist/ui/assets/ChecksView-Doy8ZRcs.js +0 -0
  291. package/dist/ui/assets/ContextView-BKPMIh5Q.css +0 -1
  292. package/dist/ui/assets/ContextView-HTKy3bOH.js +0 -4
  293. package/dist/ui/assets/DashboardView-DP7D-o1S.js +0 -1
  294. package/dist/ui/assets/DeploymentsView-BRgF6h-S.js +0 -1
  295. package/dist/ui/assets/DeploymentsView-DI5Y69BM.css +0 -1
  296. package/dist/ui/assets/InputsView-BLhcZaQg.js +0 -1
  297. package/dist/ui/assets/InputsView-CAOnQPzO.css +0 -1
  298. package/dist/ui/assets/LoginView-BKLriI-b.js +0 -1
  299. package/dist/ui/assets/ReleasesView-BpUqzAYv.js +0 -3
  300. package/dist/ui/assets/SettingsView-DkZ64CDa.js +0 -4
  301. package/dist/ui/assets/SettingsView-tL4SoVW8.css +0 -1
  302. package/dist/ui/assets/StoriesView-BLX17KW4.css +0 -1
  303. package/dist/ui/assets/StoriesView-BqHkUyKa.js +0 -1
  304. package/dist/ui/assets/WorkView-BGW29rZ6.css +0 -1
  305. package/dist/ui/assets/WorkView-Dpkonfs7.js +0 -2
  306. package/dist/ui/assets/api-Dic4Uw1D.js +0 -1
  307. package/dist/ui/assets/architecture-7GRP2DOG-BobXoPbG.js +0 -1
  308. package/dist/ui/assets/channel-Cy_U0xgO.js +0 -1
  309. package/dist/ui/assets/classDiagram-ZZMXUADV-DentwTwE.js +0 -1
  310. package/dist/ui/assets/classDiagram-v2-VYDZK3BY-DentwTwE.js +0 -1
  311. package/dist/ui/assets/config-Cl3iDM_B.js +0 -1
  312. package/dist/ui/assets/eventmodeling-NTZA5JFV-C-x4iElw.js +0 -1
  313. package/dist/ui/assets/flowDiagram-HODETNUW-BSzze3T9.js +0 -1
  314. package/dist/ui/assets/index-CWATVnBi.css +0 -1
  315. package/dist/ui/assets/index-ChI6cY4t.js +0 -35
  316. package/dist/ui/assets/railroad-abnf-HS5TGJTU-BXfjNyx0.js +0 -1
  317. package/dist/ui/assets/railroad-ebnf-LZEXJU2U-jn0Yk9uc.js +0 -1
  318. package/dist/ui/assets/railroad-peg-WCYAUIDC-Cv8anGyJ.js +0 -1
  319. package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-BuGnvM9I.js +0 -1
  320. package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-DK-DtsW-.js +0 -8
  321. package/dist/ui/assets/title-ComEuLCp.js +0 -1
  322. package/dist/ui/assets/vendor-ui-DFGj-ZXN.js +0 -3
@@ -1,4 +1,5 @@
1
1
  {
2
- "hash": "f30fcce6f5c1d53000699830d693eabb1921532ae40f9462a44af88519527c92",
3
- "version": "0.5.56"
2
+ "hash": "69cefc15aead79d33e1a4fcf9b4d8d1358152d8f214530f3af45226fbe121036",
3
+ "version": "0.5.57",
4
+ "devUi": false
4
5
  }
@@ -1,3 +1,3 @@
1
1
  {
2
- "generatedAt": "2026-09-26T09:59:53.699Z"
2
+ "generatedAt": "2026-09-29T11:51:40.533Z"
3
3
  }
package/dist/cli/index.js CHANGED
@@ -20,7 +20,7 @@ import { cmdSupport } from "../commands/support.js";
20
20
  import { cmdService } from "../commands/service.js";
21
21
  import { checkBuild } from "../core/build.js";
22
22
  import { loadConfig } from "../core/config.js";
23
- import { reexecUnderBunIfRequested } from "../core/runtime.js";
23
+ import { reexecAfterStaleBuild, reexecUnderBunIfRequested } from "../core/runtime.js";
24
24
  import { c } from "./colors.js";
25
25
  import { readFileSync } from "node:fs";
26
26
  import { dirname, join } from "node:path";
@@ -147,6 +147,9 @@ function main() {
147
147
  if (reexecUnderBunIfRequested()) {
148
148
  return;
149
149
  }
150
+ if (reexecAfterStaleBuild()) {
151
+ return;
152
+ }
150
153
  // Name the managed project in `ps`/Activity Monitor for the long-lived serve
151
154
  // process (#0347). Done here — before the staleness check — so the one-time
152
155
  // Bun re-exec inside setServeProcessTitle can't re-print that warning, and
@@ -124,13 +124,12 @@ export declare function themeContrastOffenders(css: string, config: ThemeContras
124
124
  * actually be affected). Unset for a standalone `repoos check` — that path
125
125
  * is the full definition-of-done gate and must never narrow coverage.
126
126
  *
127
- * Only the two per-branch pre-merge checks set this: the engineer's own
128
- * self-check before requesting handoff, and the server's handoff-finalize
129
- * re-verification (both re-checking the SAME isolated branch, just diffed
130
- * against its own base). The close-out gate that validates the actual merge
131
- * onto main (integration-orchestrator.ts's validateCandidate) deliberately
132
- * never sets it — that check is about interaction with whatever else has
133
- * landed on main since, which a per-branch diff can't see.
127
+ * Set after a remote validation pass (close-out, pre-review handoff, or
128
+ * `repoos check` when `remoteValidation.enabled`) so the local gate skips only
129
+ * the Tests step. Per-branch pre-merge checks also set `REPOOS_CHECK_CHANGED`
130
+ * (engineer self-check and handoff re-verification). Close-out's merge-gate
131
+ * check deliberately never sets `REPOOS_CHECK_CHANGED` — that gate validates
132
+ * interaction with whatever else has landed on main since.
134
133
  */
135
134
  export declare function changedTestRef(env: NodeJS.ProcessEnv): string | undefined;
136
135
  /**
@@ -177,6 +176,8 @@ export interface CheckOptions {
177
176
  changed?: string;
178
177
  /** Print the resolved plan as `[[check.steps]]` TOML and exit 0. */
179
178
  printPlan?: boolean;
179
+ /** Skip the remote runner even when `remoteValidation.enabled` (#0520). */
180
+ localTestsOnly?: boolean;
180
181
  }
181
182
  /** Parse `repoos check` flags. Unknown flags are ignored, never fatal. */
182
183
  export declare function parseCheckArgs(argv?: string[]): CheckOptions;
@@ -31,6 +31,11 @@ import { preferBunForDevTasks } from "../core/runtime.js";
31
31
  import { blockingFailures, DEFAULT_PROFILE, describeStep, formatPlanToml, resolveCheckPlan, selectSteps, } from "../core/check-plan.js";
32
32
  import { detectRepoMarkers, missingBinaries, prereqDetail, runCommand, stepCwd, } from "../core/check-runner.js";
33
33
  import { writeCheckRun } from "../core/check-results-store.js";
34
+ import { envToRunContext, getCheckStore, localMachineName } from "../core/check-store.js";
35
+ import { mainCheckoutRoot } from "../core/git.js";
36
+ import { Logger } from "../core/logger.js";
37
+ import { createRemoteValidator } from "../server/remote-validation.js";
38
+ import { runRemotePreReviewGate, standaloneCliCanUseRemote, remoteValidationAlreadyAttempted, uncommittedFilesBlockingRemoteGate, shouldRunCliRemotePreReviewGate, } from "../server/pre-review-remote-gate.js";
34
39
  /**
35
40
  * Split a CSS selector list on top-level commas (respecting parentheses,
36
41
  * so `:not(.a,.b)` stays one group).
@@ -499,22 +504,12 @@ function resolveVar(value, map, depth = 0) {
499
504
  const next = map[`--${m[1]}`];
500
505
  return next !== undefined ? resolveVar(next, map, depth + 1) : value;
501
506
  }
502
- // KNOWN LIMITATION (fix tracked in #0504, found while registering the gruvbox
503
- // theme in #0503): the rgb()/rgba() branches below tolerate no whitespace between
504
- // components, but oxfmt writes `rgba(110, 157, 106, 0.22)` with spaces, so every
505
- // spaced literal fails to parse and returns null. A pair whose fg or bg yields no
506
- // candidates is SKIPPED rather than failed, so a `[check] contrastPairs` bg token
507
- // written as a spaced `rgba()` is silently never checked — as are the spaced
508
- // `rgba()` stops inside a gradient, which drop out of `colorCandidates`. Measured
509
- // on this repo's own stylesheet: 425 spaced literals, leaving 4-6 of the 9
510
- // configured pairs unchecked in every theme. A whitespace-tolerant regex (`\s*`
511
- // after each separator) was measured to produce ZERO new offenders across all five
512
- // themes, so the fix is a one-liner that only strengthens the gate. It is its own
513
- // task rather than folded into a theme change because it alters the guard's
514
- // behaviour repo-wide and for every project that configures
515
- // `[check] contrastPairs`. Until it lands, do not rely on this guard to catch a
516
- // contrast problem in a token written as `rgba(r, g, b, a)`; gruvbox deliberately
517
- // uses 8-digit hex for its checked alpha tokens to stay verifiable.
507
+ // Both rgb()/rgba() forms are whitespace-tolerant (`\s*` after each separator),
508
+ // so a formatter's `rgba(110, 157, 106, 0.22)` parses (#0504). Before that fix
509
+ // these branches tolerated no whitespace, which silently skipped any
510
+ // contrastPairs whose colour could not be read; if you ever loosen them again,
511
+ // a pair that fails to parse is SKIPPED rather than failed, so re-run the real
512
+ // guard against the real stylesheet rather than reasoning about it.
518
513
  function parseColor(v) {
519
514
  const s = v.trim().toLowerCase();
520
515
  if (!s || s === "none")
@@ -688,13 +683,12 @@ export function themeContrastOffenders(css, config) {
688
683
  * actually be affected). Unset for a standalone `repoos check` — that path
689
684
  * is the full definition-of-done gate and must never narrow coverage.
690
685
  *
691
- * Only the two per-branch pre-merge checks set this: the engineer's own
692
- * self-check before requesting handoff, and the server's handoff-finalize
693
- * re-verification (both re-checking the SAME isolated branch, just diffed
694
- * against its own base). The close-out gate that validates the actual merge
695
- * onto main (integration-orchestrator.ts's validateCandidate) deliberately
696
- * never sets it — that check is about interaction with whatever else has
697
- * landed on main since, which a per-branch diff can't see.
686
+ * Set after a remote validation pass (close-out, pre-review handoff, or
687
+ * `repoos check` when `remoteValidation.enabled`) so the local gate skips only
688
+ * the Tests step. Per-branch pre-merge checks also set `REPOOS_CHECK_CHANGED`
689
+ * (engineer self-check and handoff re-verification). Close-out's merge-gate
690
+ * check deliberately never sets `REPOOS_CHECK_CHANGED` — that gate validates
691
+ * interaction with whatever else has landed on main since.
698
692
  */
699
693
  export function changedTestRef(env) {
700
694
  const ref = env.REPOOS_CHECK_CHANGED;
@@ -763,6 +757,8 @@ export function parseCheckArgs(argv = []) {
763
757
  opts.changed = argv[++i];
764
758
  else if (a === "--print-plan")
765
759
  opts.printPlan = true;
760
+ else if (a === "--local-tests")
761
+ opts.localTestsOnly = true;
766
762
  }
767
763
  return opts;
768
764
  }
@@ -1338,6 +1334,16 @@ export async function runCheckPlan(plan, opts) {
1338
1334
  export async function cmdCheck(argv = []) {
1339
1335
  const opts = parseCheckArgs(argv);
1340
1336
  const repoRoot = findRepoRoot();
1337
+ // Where this run's history row(s) go (#0564 review): the MAIN checkout's
1338
+ // `.repoos/checks.db`, the one store the running server reads. A standalone
1339
+ // `repoos check` inside a task worktree used to write to the worktree's own
1340
+ // file, so an agent's self-check never appeared in Checks → Runs. An
1341
+ // explicit REPOOS_CHECK_STORE_ROOT (server-spawned paths) already points at
1342
+ // the main root and wins. Deliberately a local value, NOT a process.env
1343
+ // write: an exported env var reaches every child this command spawns —
1344
+ // including the test suite, whose own check-store fixtures would then
1345
+ // record into this repo's live store instead of their own tmp ones.
1346
+ const checkStoreRoot = resolveCheckStoreRoot(repoRoot);
1341
1347
  const cfg = loadConfig(repoRoot);
1342
1348
  const markers = detectRepoMarkers(repoRoot);
1343
1349
  const plan = resolveCheckPlan({
@@ -1390,35 +1396,186 @@ export async function cmdCheck(argv = []) {
1390
1396
  console.log(c.dim(` · Changed-path mode: ${changedPaths?.length ?? 0} path(s) differ from ${changedRef} ` +
1391
1397
  "(fast pre-review pass — close-out still runs the full plan)"));
1392
1398
  }
1393
- const runStartedAt = new Date();
1394
- const results = await runCheckPlan(plan, {
1395
- repoRoot,
1396
- cfg,
1397
- profile,
1398
- // Narrowed above after the null check; `?? undefined` keeps the types
1399
- // honest without a cast.
1400
- changedPaths: changedPaths ?? undefined,
1401
- changedRef,
1402
- onStart: (step) => {
1403
- heading(step.name);
1404
- console.log(c.dim(` · ${describeStep(step)}`));
1405
- },
1406
- onResult: (r) => {
1407
- const secs = r.durationMs >= 1000 ? ` (${(r.durationMs / 1000).toFixed(1)}s)` : "";
1408
- if (r.status === "passed") {
1409
- console.log(c.green(` ✔ ${r.name}${secs}${r.detail ? ` — ${r.detail}` : ""}`));
1410
- }
1411
- else if (r.status === "skipped") {
1412
- console.log(c.dim(` ⏭ ${r.name} — ${statusDetail(r)}`));
1399
+ if (cfg.remoteValidation?.enabled &&
1400
+ !standaloneCliCanUseRemote(cfg) &&
1401
+ !changedRef &&
1402
+ !opts.localTestsOnly &&
1403
+ !remoteValidationAlreadyAttempted(process.env)) {
1404
+ console.log(c.dim(" · remote validation: the Hetzner runner is owned by the server, so a standalone " +
1405
+ "`repoos check` runs the full local gate (handoff and close-out still use the runner)"));
1406
+ }
1407
+ let runRemoteGate = shouldRunCliRemotePreReviewGate(cfg, { ...opts, changedRef }, process.env);
1408
+ if (runRemoteGate) {
1409
+ // The runner tests a bundle of HEAD. Uncommitted work would be skipped by it
1410
+ // and then unverified locally (tests are skipped after a remote pass), so
1411
+ // test the working tree locally instead and say why.
1412
+ const uncommitted = await uncommittedFilesBlockingRemoteGate(repoRoot, cfg);
1413
+ if (uncommitted.length > 0) {
1414
+ runRemoteGate = false;
1415
+ const shown = uncommitted.slice(0, 5).join(", ");
1416
+ console.log(c.yellow(` ⚠ uncommitted changes (${shown}${uncommitted.length > 5 ? ", …" : ""}) — the remote ` +
1417
+ "gate tests committed HEAD only, so running the full local gate on the working tree instead\n"));
1418
+ }
1419
+ }
1420
+ // The plan never runs when the remote gate fails, so the normal end-of-run
1421
+ // record is never written: persist the failure for the Checks surface too,
1422
+ // like a local failure and like the handoff path (fail-soft).
1423
+ const persistRemoteFailure = (detail, output, startedAt) => {
1424
+ const finishedAt = new Date();
1425
+ const durationMs = finishedAt.getTime() - startedAt.getTime();
1426
+ writeCheckRun(repoRoot, {
1427
+ profile,
1428
+ source: plan.source,
1429
+ changedRef,
1430
+ startedAt: startedAt.toISOString(),
1431
+ finishedAt: finishedAt.toISOString(),
1432
+ durationMs,
1433
+ passed: false,
1434
+ results: [
1435
+ {
1436
+ name: "remote-validation",
1437
+ status: "failed",
1438
+ durationMs,
1439
+ output: output || undefined,
1440
+ detail,
1441
+ required: true,
1442
+ },
1443
+ ],
1444
+ }, cfg.cacheDir);
1445
+ };
1446
+ if (runRemoteGate) {
1447
+ heading("Remote validation");
1448
+ const logger = new Logger({ root: repoRoot });
1449
+ let remoteValidator;
1450
+ try {
1451
+ remoteValidator = createRemoteValidator(cfg, logger);
1452
+ }
1453
+ catch (e) {
1454
+ const msg = `remote validation init failed: ${e.message}`;
1455
+ if (!cfg.remoteValidation?.fallbackToLocal) {
1456
+ console.log(c.red(`\n ✗ ${msg}\n`));
1457
+ persistRemoteFailure(msg, "", new Date());
1458
+ // The runner never dispatched, so nothing else will record this
1459
+ // failed remote attempt in the history (#0564). Record it here —
1460
+ // machine unknown (no host was ever chosen), remote half only.
1461
+ recordRunHistoryRow({
1462
+ root: checkStoreRoot,
1463
+ cacheDir: cfg.cacheDir,
1464
+ scope: "full",
1465
+ startedAt: new Date().toISOString(),
1466
+ durationMs: 0,
1467
+ outcome: "fail",
1468
+ failedStep: "remote-validation",
1469
+ skippedSteps: [],
1470
+ detail: msg,
1471
+ });
1472
+ process.exit(1);
1413
1473
  }
1414
- else if (!r.required) {
1415
- console.log(c.yellow(` ⚠ ${r.name} failed (optional) — ${statusDetail(r)}`));
1474
+ console.log(c.yellow(` ⚠ ${msg} — running the full local gate\n`));
1475
+ }
1476
+ if (remoteValidator) {
1477
+ // Route the runner's own history rows (recordRemoteRunHistory reads
1478
+ // this env) to the resolved store root for THIS dispatch only, then
1479
+ // restore — a process-wide export here would leak into the check
1480
+ // plan's child processes (the test suite's own check-store fixtures
1481
+ // record via the same env and would land in the live store).
1482
+ const prevStoreRoot = process.env.REPOOS_CHECK_STORE_ROOT;
1483
+ process.env.REPOOS_CHECK_STORE_ROOT = checkStoreRoot;
1484
+ try {
1485
+ const taskId = process.env.REPOOS_TASK_ID?.trim() || "pre-review";
1486
+ const remoteStartedAt = new Date();
1487
+ let remoteOutput = "";
1488
+ // Which gate is calling (#0564): a caller-supplied task id means this is
1489
+ // a pre-review pass for that task; otherwise a bare CLI run.
1490
+ const { phase: runPhase } = envToRunContext(process.env);
1491
+ const gate = await runRemotePreReviewGate({
1492
+ config: cfg,
1493
+ remoteValidator,
1494
+ worktreePath: repoRoot,
1495
+ taskId,
1496
+ phase: runPhase,
1497
+ onChunk: (chunk) => {
1498
+ remoteOutput += chunk;
1499
+ process.stdout.write(chunk);
1500
+ },
1501
+ });
1502
+ // Await the teardown: the failure path below exits the process, and an
1503
+ // un-awaited async runner delete would be cut off mid-request, leaking a
1504
+ // warm VM that no idle timer survives the exit to reap.
1505
+ await remoteValidator.dispose().catch(() => { });
1506
+ if (gate.kind === "fail") {
1507
+ console.log(c.red(`\n ✗ ${gate.detail}\n`));
1508
+ persistRemoteFailure(gate.detail, remoteOutput, remoteStartedAt);
1509
+ process.exit(1);
1510
+ }
1511
+ if (gate.kind === "local-only" && gate.skipTests) {
1512
+ process.env.REPOOS_SKIP_TESTS = "1";
1513
+ console.log(c.green(" ✔ remote gate passed — running local guards only\n"));
1514
+ }
1515
+ else if (gate.kind === "local-only") {
1516
+ console.log(c.yellow(" ⚠ remote unavailable — running the full local gate\n"));
1517
+ }
1416
1518
  }
1417
- else {
1418
- console.log(c.red(` ✗ ${r.name}${secs}`));
1519
+ finally {
1520
+ if (prevStoreRoot === undefined)
1521
+ delete process.env.REPOOS_CHECK_STORE_ROOT;
1522
+ else
1523
+ process.env.REPOOS_CHECK_STORE_ROOT = prevStoreRoot;
1419
1524
  }
1420
- },
1421
- });
1525
+ }
1526
+ }
1527
+ const runStartedAt = new Date();
1528
+ let results;
1529
+ try {
1530
+ results = await runCheckPlan(plan, {
1531
+ repoRoot,
1532
+ cfg,
1533
+ profile,
1534
+ // Narrowed above after the null check; `?? undefined` keeps the types
1535
+ // honest without a cast.
1536
+ changedPaths: changedPaths ?? undefined,
1537
+ changedRef,
1538
+ onStart: (step) => {
1539
+ heading(step.name);
1540
+ console.log(c.dim(` · ${describeStep(step)}`));
1541
+ },
1542
+ onResult: (r) => {
1543
+ const secs = r.durationMs >= 1000 ? ` (${(r.durationMs / 1000).toFixed(1)}s)` : "";
1544
+ if (r.status === "passed") {
1545
+ console.log(c.green(` ✔ ${r.name}${secs}${r.detail ? ` — ${r.detail}` : ""}`));
1546
+ }
1547
+ else if (r.status === "skipped") {
1548
+ console.log(c.dim(` ⏭ ${r.name} — ${statusDetail(r)}`));
1549
+ }
1550
+ else if (!r.required) {
1551
+ console.log(c.yellow(` ⚠ ${r.name} failed (optional) — ${statusDetail(r)}`));
1552
+ }
1553
+ else {
1554
+ console.log(c.red(` ✗ ${r.name}${secs}`));
1555
+ }
1556
+ },
1557
+ });
1558
+ }
1559
+ catch (e) {
1560
+ // The plan runner is not expected to throw, but if it does the normal
1561
+ // end-of-run record below never runs — and the server-side check manager
1562
+ // records only `code === null`, so a child that dies on an unhandled
1563
+ // error would leave NO row at all (#0564 review). Record the crash, then
1564
+ // re-throw for the usual CLI error path.
1565
+ const finishedAt = new Date();
1566
+ recordRunHistoryRow({
1567
+ root: checkStoreRoot,
1568
+ cacheDir: cfg.cacheDir,
1569
+ scope: changedRef ? `changed:${changedRef}` : "full",
1570
+ startedAt: runStartedAt.toISOString(),
1571
+ durationMs: finishedAt.getTime() - runStartedAt.getTime(),
1572
+ outcome: "fail",
1573
+ failedStep: "check",
1574
+ skippedSteps: [],
1575
+ detail: `check crashed before completing: ${e.message}`,
1576
+ });
1577
+ throw e;
1578
+ }
1422
1579
  // ── Summary ─────────────────────────────────────────────────────────
1423
1580
  const gatingFailures = results.filter((r) => r.required && r.status !== "passed" && r.status !== "skipped");
1424
1581
  const optionalFailures = results.filter((r) => !r.required && r.status !== "passed" && r.status !== "skipped");
@@ -1468,8 +1625,59 @@ export async function cmdCheck(argv = []) {
1468
1625
  required: r.required,
1469
1626
  })),
1470
1627
  }, cfg.cacheDir);
1628
+ // Record the run in the durable history (#0564). The caller (handoff,
1629
+ // close-out, release) identifies itself via env; a bare `repoos check`
1630
+ // records as phase "cli" with a null task id. The store lives in the MAIN
1631
+ // checkout (resolved at the top of this command, #0564 review) so worktree
1632
+ // runs land in the history the server reads.
1633
+ recordRunHistoryRow({
1634
+ root: checkStoreRoot,
1635
+ cacheDir: cfg.cacheDir,
1636
+ scope: changedRef ? `changed:${changedRef}` : "full",
1637
+ startedAt: runStartedAt.toISOString(),
1638
+ durationMs: finishedAt.getTime() - runStartedAt.getTime(),
1639
+ outcome: gatingFailures.length === 0 ? "pass" : "fail",
1640
+ failedStep: gatingFailures[0]?.name ?? null,
1641
+ skippedSteps: results.filter((r) => r.status === "skipped").map((r) => r.name),
1642
+ detail: gatingFailures[0]?.detail ?? null,
1643
+ });
1471
1644
  process.exit(gatingFailures.length > 0 ? 1 : 0);
1472
1645
  }
1646
+ /**
1647
+ * Where a standalone run's check-run history rows belong (#0564 review): an
1648
+ * explicit `REPOOS_CHECK_STORE_ROOT` (server-spawned paths) wins; otherwise
1649
+ * the MAIN checkout, resolved through any linked worktree. Fail-soft.
1650
+ */
1651
+ function resolveCheckStoreRoot(repoRoot) {
1652
+ const envRoot = process.env.REPOOS_CHECK_STORE_ROOT?.trim();
1653
+ return envRoot || mainCheckoutRoot(repoRoot);
1654
+ }
1655
+ /**
1656
+ * Write one local check-run row into the durable history (#0564), attributing
1657
+ * the caller/phase from the environment. Fail-soft: history is observability,
1658
+ * never a gate input.
1659
+ */
1660
+ function recordRunHistoryRow(row) {
1661
+ try {
1662
+ const { taskId, phase } = envToRunContext(process.env);
1663
+ getCheckStore(row.root, row.cacheDir).record({
1664
+ taskId,
1665
+ phase,
1666
+ machine: localMachineName(),
1667
+ remote: false,
1668
+ scope: row.scope,
1669
+ startedAt: row.startedAt,
1670
+ durationMs: row.durationMs,
1671
+ outcome: row.outcome,
1672
+ failedStep: row.failedStep,
1673
+ skippedSteps: row.skippedSteps,
1674
+ detail: row.detail,
1675
+ });
1676
+ }
1677
+ catch {
1678
+ /* never fail the gate on a history write */
1679
+ }
1680
+ }
1473
1681
  /**
1474
1682
  * Names of steps that already failed and therefore block their dependents.
1475
1683
  * A timeout or a missing prerequisite counts; an OPTIONAL step never does —
@@ -158,42 +158,47 @@ repo itself is the source of truth. This file tells AI agents how to operate.
158
158
 
159
159
  ## Operating loop
160
160
 
161
- 1. Read this file and any relevant docs under \`${docsDir}/\`.
162
- 2. Pick a task from \`${workDir}/\` whose \`status: ready\`.
163
- 3. Set its \`status: active\` (edit the frontmatter; do not move the file).
164
- 4. Create a worktree on the branch named in the task's \`branch:\` field, or set one.
165
- 5. Run \`repoos check\` and confirm it passes, then implement → test → if the repo
166
- has a git remote, open an MR/PR against main.
167
- 6. When ready for human sign-off, run \`repoos mv <id> review\` and stop. **That
168
- records a handoff request; it does not set the status.** RepoOS re-runs the
169
- check, commits the branch and moves the task to \`review\`. The task stays
170
- \`active\` until then, and stays \`active\` with the failure shown if the check
171
- fails. **Leave the worktree open; do NOT merge its branch.**
161
+ For a RepoOS-managed task runner:
162
+
163
+ 1. Read this file, your assigned task under \`${workDir}/\`, and relevant
164
+ project docs under \`${docsDir}/\`.
165
+ 2. Work in the task branch and dedicated worktree RepoOS assigned. The server
166
+ owns activation and worktree setup; do not claim another task or edit its
167
+ frontmatter directly.
168
+ 3. Implement the task, update directly affected docs, and run
169
+ \`repoos check --changed main\`. It must pass before handoff.
170
+ 4. Request handoff with \`repoos mv <id> review\` or finish your reply with
171
+ \`::repoos-handoff-ready::\`, then end your turn. In your own runner session,
172
+ both record a request without changing status. RepoOS commits the branch,
173
+ runs checks, verifies the tested tree stayed unchanged, and then moves the
174
+ task to \`review\`. Failure leaves it \`active\` with the reason shown.
175
+ 5. Leave the worktree open and stop. Do not merge the branch or mark it done.
176
+ Requested fixes continue on the same worktree with another checked handoff.
177
+
178
+ Interactive agents helping on a task use its same branch/worktree and the
179
+ same review/close-out workflow. Coordinate with any live engineer/reviewer
180
+ before editing. Outside a managed runner, \`repoos mv <id> review\` writes
181
+ metadata that the server intercepts asynchronously; wait for finalization,
182
+ not just the CLI command's return. Runner-only signals do not apply there.
172
183
 
173
184
  ## Review and sign-off
174
185
 
175
- A \`review\` task stays in its open worktree until a human (or another AI) signs
176
- off; the implementer never merges to \`main\` at \`review\` time.
186
+ RepoOS owns review and close-out whether or not this repo has a Git remote.
187
+ Do not open a PR, push a task branch, or substitute GitHub approval/merge
188
+ unless the human explicitly requests that separate workflow.
177
189
 
178
- Every route into \`review\` — the Review button, a board drag, a
179
- \`PATCH status: review\`, \`repoos mv\`, or an agent's handoff signal — runs the
180
- same finalization: scoped \`repoos check\`, then the commit guard, then
181
- \`review\`. Nothing reaches \`review\` on the commit guard alone.
190
+ The reviewer agent, when enabled, writes an advisory report in the task drawer.
191
+ It does not edit code or replace human approval. After the human approves,
192
+ use **Move to done** in RepoOS or \`POST /api/tasks/:id/done\`. The server
193
+ merges the task into a separate candidate worktree, validates the combined
194
+ result, rechecks the primary branch under a publication lock, publishes,
195
+ cleans up, and records completion. \`repoos mv <id> done\` only changes metadata;
196
+ it does not run close-out or merge code.
182
197
 
183
- - No git remote: on approval, the reviewer says **"move task <id> to done"**. The
184
- implementer then sets \`status: done\` (commit \`docs(<id>): set status done\`),
185
- fast-forward merges the branch to \`main\`, removes the worktree, and deletes
186
- the branch.
187
- - With a git remote: an MR/PR is opened against \`main\` at \`review\` time. On
188
- approval it is merged by the reviewer (or by the implementer only on "move task
189
- <id> to done"), then remote + local branches are deleted and \`status\` is set
190
- to \`done\`.
191
- - Requested changes are fixed on the same worktree, tests re-run, and the task
192
- handed off again.
193
- - If the \`reviewer\` agent is enabled on the Agents page, RepoOS reviews the
194
- task automatically when it lands in \`review\` and shows a short report (bugs,
195
- edge cases, suggestions) in the task drawer. It is advisory: the human still
196
- reviews and is the only one who moves a task to \`done\`.
198
+ A direct commit on the primary branch is an exception requiring explicit
199
+ human authorization. If that already-landed work has a branchless task record,
200
+ the \`/done\` endpoint can check the primary checkout and record release without
201
+ a candidate merge. Do not erase a task's branch metadata to force this path.
197
202
 
198
203
  ## Rules
199
204
 
@@ -246,8 +251,9 @@ export const REPOOS_AGENTS_SECTION = (workDir) => `${REPOOS_AGENTS_SECTION_MARKE
246
251
  RepoOS keeps tasks as Markdown under \`${workDir}/\` and runs task work in dedicated
247
252
  Git worktrees. Use the RepoOS UI or \`repoos\` commands to create and update
248
253
  tasks; do not hand-edit task files. Read the relevant project docs before
249
- starting work, run \`repoos check\` before handoff, and let the reviewer decide
250
- what merges.
254
+ starting work, run \`repoos check\` before handoff, and await human approval
255
+ through RepoOS's **Move to done**. The reviewer is advisory. A Git remote does
256
+ not require a PR; close-out validates and merges through RepoOS.
251
257
  `;
252
258
  /**
253
259
  * Return the exact addition that `repoos init` may offer for an existing
@@ -42,11 +42,57 @@ export interface AuditLogEntry {
42
42
  details: string | null;
43
43
  createdAt: string;
44
44
  }
45
+ export interface TelegramUserLink {
46
+ instanceIdentity?: string;
47
+ telegramUserId: number;
48
+ email: string;
49
+ telegramUsername: string | null;
50
+ boundAt: string;
51
+ boundBy: string | null;
52
+ lastSeenAt: string | null;
53
+ revokedAt: string | null;
54
+ }
55
+ export interface TelegramChatLink {
56
+ instanceIdentity?: string;
57
+ telegramChatId: number;
58
+ chatType: string;
59
+ title: string | null;
60
+ boundAt: string;
61
+ boundBy: string;
62
+ revokedAt: string | null;
63
+ /** When false, this chat is bound but opted out of push notifications (#0537). */
64
+ notificationsEnabled: boolean;
65
+ }
66
+ export interface TelegramChatBindInvite {
67
+ nonceHash: string;
68
+ repoIdentity: string;
69
+ instanceIdentity: string;
70
+ mac: string;
71
+ createdBy: string;
72
+ createdAt: string;
73
+ expiresAt: string;
74
+ redeemedAt: string | null;
75
+ redeemedChatId: number | null;
76
+ }
77
+ export interface TelegramLinkInvite {
78
+ nonceHash: string;
79
+ email: string;
80
+ repoIdentity: string;
81
+ instanceIdentity: string;
82
+ mac: string;
83
+ createdBy: string;
84
+ createdAt: string;
85
+ expiresAt: string;
86
+ redeemedAt: string | null;
87
+ }
45
88
  export declare class AuthStore {
46
89
  private db;
47
90
  private available;
91
+ private instanceIdentityValue;
92
+ get instanceIdentity(): string;
48
93
  constructor(repoRoot: string);
49
94
  isAvailable(): boolean;
95
+ private migrateTelegramBindingTables;
50
96
  getUser(email: string): AuthUser | null;
51
97
  listUsers(): AuthUser[];
52
98
  upsertUser(email: string, role: AuthRole, addedBy: string | null, displayName?: string): void;
@@ -71,6 +117,8 @@ export declare class AuthStore {
71
117
  countFailedVerifyAttempts(email: string, windowSeconds: number): number;
72
118
  cleanupExpiredOtps(): number;
73
119
  logAudit(action: string, targetEmail: string | null, actorEmail: string | null, details?: string): void;
120
+ /** Like logAudit, but required for lifecycle events that must not report success without a row. */
121
+ logAuditRequired(action: string, targetEmail: string | null, actorEmail: string | null, details?: string): void;
74
122
  getAuditLog(limit?: number): AuditLogEntry[];
75
123
  createHubCapability(input: Omit<HubCapability, "tokenHash" | "revokedAt" | "lastUsedAt"> & {
76
124
  tokenHash: string;
@@ -80,11 +128,52 @@ export declare class AuthStore {
80
128
  getHubCapability(id: string): HubCapability | null;
81
129
  revokeHubCapability(id: string): boolean;
82
130
  markHubCapabilityUsed(id: string): void;
131
+ getTelegramLink(telegramUserId: number): TelegramUserLink | null;
132
+ listTelegramLinks(): TelegramUserLink[];
133
+ upsertTelegramLink(link: TelegramUserLink): boolean;
134
+ touchTelegramLinkSeen(telegramUserId: number, seenAt: string): void;
135
+ revokeTelegramLink(telegramUserId: number, revokedAt: string): boolean;
136
+ /**
137
+ * Revoke active user links for this instance only.
138
+ */
139
+ revokeAllActiveTelegramUserLinks(revokedAt: string): number;
140
+ insertTelegramInvite(invite: TelegramLinkInvite): boolean;
141
+ getTelegramInviteByNonceHash(nonceHash: string): TelegramLinkInvite | null;
142
+ /**
143
+ * Mark an unused invite redeemed. Returns false if the row is missing,
144
+ * already redeemed, or the write fails — callers treat all as replay.
145
+ */
146
+ markTelegramInviteRedeemed(nonceHash: string, redeemedAt: string): boolean;
147
+ cleanupExpiredTelegramInvites(): number;
148
+ getTelegramChatLink(telegramChatId: number): TelegramChatLink | null;
149
+ listTelegramChatLinks(): TelegramChatLink[];
150
+ upsertTelegramChatLink(link: TelegramChatLink): boolean;
151
+ setTelegramChatNotificationsEnabled(telegramChatId: number, enabled: boolean): boolean;
152
+ revokeTelegramChatLink(telegramChatId: number, revokedAt: string): boolean;
153
+ /** Revoke active chat links for this instance only. */
154
+ revokeAllActiveTelegramChatLinks(revokedAt: string): number;
155
+ deleteTelegramUserInvitesForInstance(instanceIdentity: string): number;
156
+ deleteTelegramChatBindInvitesForInstance(instanceIdentity: string): number;
157
+ insertTelegramChatBindInvite(invite: TelegramChatBindInvite): boolean;
158
+ getTelegramChatBindInviteByNonceHash(nonceHash: string): TelegramChatBindInvite | null;
159
+ markTelegramChatBindInviteRedeemed(nonceHash: string, redeemedAt: string, redeemedChatId: number): boolean;
160
+ cleanupExpiredTelegramChatBindInvites(): number;
161
+ /**
162
+ * Run `fn` inside BEGIN IMMEDIATE so invite redeem cannot race a second
163
+ * /start into a double bind. Nested calls are not supported — later
164
+ * Telegram intake (#0532/#0534) must not wrap redeemTelegramInvite in
165
+ * another transaction.
166
+ */
167
+ withImmediateTransaction<T>(fn: () => T): T;
83
168
  private toHubCapability;
84
169
  private toUser;
85
170
  private toSession;
86
171
  private toOtp;
87
172
  private toAuditEntry;
173
+ private toTelegramLink;
174
+ private toTelegramInvite;
175
+ private toTelegramChatLink;
176
+ private toTelegramChatBindInvite;
88
177
  close(): void;
89
178
  }
90
179
  export declare function getAuthStore(repoRoot: string): AuthStore | null;