@repo-os/repoos 0.5.49 → 0.5.51

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 (250) hide show
  1. package/README.md +17 -0
  2. package/dist/.build-info.json +2 -2
  3. package/dist/.build-stamp.json +1 -1
  4. package/dist/cli/index.js +8 -2
  5. package/dist/commands/certify.d.ts +10 -0
  6. package/dist/commands/certify.js +198 -0
  7. package/dist/commands/doctor.d.ts +17 -1
  8. package/dist/commands/doctor.js +121 -4
  9. package/dist/commands/serve.d.ts +11 -0
  10. package/dist/commands/serve.js +33 -0
  11. package/dist/commands/service.js +2 -2
  12. package/dist/commands/tasks.d.ts +2 -2
  13. package/dist/commands/tasks.js +16 -5
  14. package/dist/commands/ui-harness.js +11 -1
  15. package/dist/core/agent-compatibility.d.ts +46 -0
  16. package/dist/core/agent-compatibility.js +329 -0
  17. package/dist/core/agent-compatibility.json +179 -0
  18. package/dist/core/agent-contract.d.ts +34 -0
  19. package/dist/core/agent-contract.js +895 -0
  20. package/dist/core/auth-store.d.ts +10 -0
  21. package/dist/core/auth-store.js +120 -0
  22. package/dist/core/canary.d.ts +1 -1
  23. package/dist/core/canary.js +1 -1
  24. package/dist/core/config.d.ts +32 -1
  25. package/dist/core/config.js +166 -3
  26. package/dist/core/detect-cache.d.ts +8 -0
  27. package/dist/core/detect-cache.js +30 -0
  28. package/dist/core/detect.d.ts +57 -6
  29. package/dist/core/detect.js +136 -28
  30. package/dist/core/doctor.d.ts +15 -0
  31. package/dist/core/doctor.js +79 -3
  32. package/dist/core/hub-capabilities.d.ts +38 -0
  33. package/dist/core/hub-capabilities.js +66 -0
  34. package/dist/core/hub-task-search.d.ts +22 -0
  35. package/dist/core/hub-task-search.js +62 -0
  36. package/dist/core/repoos.d.ts +15 -1
  37. package/dist/core/repoos.js +7 -5
  38. package/dist/core/stories.d.ts +73 -0
  39. package/dist/core/stories.js +129 -0
  40. package/dist/core/task.js +7 -0
  41. package/dist/core/types.d.ts +56 -2
  42. package/dist/server/agents.d.ts +5 -4
  43. package/dist/server/agents.js +47 -65
  44. package/dist/server/freeform.d.ts +2 -0
  45. package/dist/server/freeform.js +1 -0
  46. package/dist/server/integration-orchestrator.d.ts +11 -0
  47. package/dist/server/integration-orchestrator.js +260 -139
  48. package/dist/server/live-index.js +2 -0
  49. package/dist/server/preview.d.ts +9 -0
  50. package/dist/server/preview.js +12 -1
  51. package/dist/server/remote-validation.d.ts +47 -10
  52. package/dist/server/remote-validation.js +202 -11
  53. package/dist/server/routes/agents.d.ts +18 -0
  54. package/dist/server/routes/agents.js +53 -10
  55. package/dist/server/routes/hub.d.ts +12 -0
  56. package/dist/server/routes/hub.js +234 -0
  57. package/dist/server/routes/index.d.ts +1 -0
  58. package/dist/server/routes/index.js +1 -0
  59. package/dist/server/routes/service.js +2 -2
  60. package/dist/server/routes/support.d.ts +12 -0
  61. package/dist/server/routes/support.js +160 -4
  62. package/dist/server/routes/tasks.js +37 -18
  63. package/dist/server/serve-reaper.d.ts +1 -1
  64. package/dist/server/serve-reaper.js +16 -2
  65. package/dist/server/server.d.ts +28 -0
  66. package/dist/server/server.js +123 -14
  67. package/dist/server/write.d.ts +2 -0
  68. package/dist/server/write.js +9 -0
  69. package/dist/ui/assets/AgentsView-VpkTvsSg.js +1 -0
  70. package/dist/ui/assets/ChecksView-CDE2cfWk.js +1 -0
  71. package/dist/ui/assets/ChecksView-D79umAfM.css +1 -0
  72. package/dist/ui/assets/ContextView-B61GEm1Z.js +4 -0
  73. package/dist/ui/assets/DashboardView-C5anCBko.js +1 -0
  74. package/dist/ui/assets/DeploymentsView-BfRAdizb.js +1 -0
  75. package/dist/ui/assets/DeploymentsView-DI5Y69BM.css +1 -0
  76. package/dist/ui/assets/DiffView-BpW0Agf3.css +1 -0
  77. package/dist/ui/assets/DiffView-DixEbWbX.js +4 -0
  78. package/dist/ui/assets/InputsView-CgH2DwWm.css +1 -0
  79. package/dist/ui/assets/InputsView-DZJ_-QCu.js +1 -0
  80. package/dist/ui/assets/{LoginView-Bgv90FPK.js → LoginView-BhkLJwz2.js} +1 -1
  81. package/dist/ui/assets/ReleasesView-Bc4mWRi1.js +3 -0
  82. package/dist/ui/assets/ReleasesView-DaX_TFoT.css +1 -0
  83. package/dist/ui/assets/SettingsView-CaJPb-O7.js +4 -0
  84. package/dist/ui/assets/StoriesView-BdwyVyBi.css +1 -0
  85. package/dist/ui/assets/StoriesView-s-GXglwO.js +1 -0
  86. package/dist/ui/assets/TaskCard-CiDqR0-o.js +1 -0
  87. package/dist/ui/assets/WorkView-BGW29rZ6.css +1 -0
  88. package/dist/ui/assets/WorkView-VjIRIAu3.js +2 -0
  89. package/dist/ui/assets/abnfDiagram-VCTEODGH-CsyiRZfO.js +1 -0
  90. package/dist/ui/assets/{arc-BHZnmhhM.js → arc-DMqT1Ve5.js} +1 -1
  91. package/dist/ui/assets/architecture-7GRP2DOG-xBNBIq5T.js +1 -0
  92. package/dist/ui/assets/architectureDiagram-5GKGNRK7-B08h5dWI.js +36 -0
  93. package/dist/ui/assets/{blockDiagram-I7D4REHJ-BsnD-5PV.js → blockDiagram-I7D4REHJ-BPPeB-eQ.js} +6 -6
  94. package/dist/ui/assets/{c4Diagram-7LVT6UL2-CqpUjbtK.js → c4Diagram-7LVT6UL2-BfADPuem.js} +7 -7
  95. package/dist/ui/assets/channel-BoRSmxIz.js +1 -0
  96. package/dist/ui/assets/{chunk-4HAMMTFA-Cp59m-71.js → chunk-4HAMMTFA-DOmKNumZ.js} +7 -7
  97. package/dist/ui/assets/chunk-75Z2AOVW-fvtO31Ky.js +2 -0
  98. package/dist/ui/assets/{chunk-DU6HZSFF-Becd7Cgr.js → chunk-DU6HZSFF-egapwqdZ.js} +32 -32
  99. package/dist/ui/assets/{chunk-F27PBJKO-Blb2qqJ4.js → chunk-F27PBJKO-B4F_scL_.js} +1 -1
  100. package/dist/ui/assets/{chunk-GMAD6QVW-5Qh43abc.js → chunk-GMAD6QVW-B0g7hXXo.js} +6 -6
  101. package/dist/ui/assets/{chunk-GVQU2GXP-Bb0Ur8QB.js → chunk-GVQU2GXP-ByHTqLhx.js} +1 -1
  102. package/dist/ui/assets/{chunk-IMKFNOWR-OYY7Z4BW.js → chunk-IMKFNOWR-BiX2WjGm.js} +5 -5
  103. package/dist/ui/assets/chunk-L3NEJ4N5-Dtn3Nz1E.js +1 -0
  104. package/dist/ui/assets/{chunk-OSK3NFVY-DeC-74ju.js → chunk-OSK3NFVY-D2FVEKbm.js} +4 -4
  105. package/dist/ui/assets/{chunk-P2QGCYS3-D9AFqJkh.js → chunk-P2QGCYS3-DbpxXwpl.js} +1 -1
  106. package/dist/ui/assets/chunk-POPQ4Y6H-wc9BY3N-.js +1 -0
  107. package/dist/ui/assets/{chunk-PWAF6VOD-DO8Mg8r-.js → chunk-PWAF6VOD-CKBLutxN.js} +1 -1
  108. package/dist/ui/assets/{chunk-SHT3W25Y-CoPZM9XW.js → chunk-SHT3W25Y-CtTrYLC0.js} +9 -9
  109. package/dist/ui/assets/{chunk-SVP7TREG-Bawvkywu.js → chunk-SVP7TREG-QwFEiE2U.js} +4 -4
  110. package/dist/ui/assets/{chunk-TICWLB2K-D-QDMLtT.js → chunk-TICWLB2K-DM5hYl74.js} +6 -6
  111. package/dist/ui/assets/chunk-XXDRQBXY-DqAYeljN.js +1 -0
  112. package/dist/ui/assets/classDiagram-ZZMXUADV-C0YZV-id.js +1 -0
  113. package/dist/ui/assets/classDiagram-v2-VYDZK3BY-C0YZV-id.js +1 -0
  114. package/dist/ui/assets/cose-bilkent-JH36ORCC-Cju1UDLh.js +1 -0
  115. package/dist/ui/assets/css-BsVw1vtW.js +1 -0
  116. package/dist/ui/assets/{cynefin-OW5HDTMX-BArHh8-d.js → cynefin-OW5HDTMX-DKbiErci.js} +1 -1
  117. package/dist/ui/assets/cynefinDiagram-5FMLGOSQ-C_RVv0hh.js +62 -0
  118. package/dist/ui/assets/{dagre-GXQ25YYZ-9nuP3Mhz.js → dagre-GXQ25YYZ-BYlBs_VY.js} +3 -3
  119. package/dist/ui/assets/{diagram-S7CK7UJ4-CcjB4ae6.js → diagram-S7CK7UJ4-BvYISuK2.js} +3 -3
  120. package/dist/ui/assets/diagram-UQ7AKVKN-Bf4NWZw-.js +41 -0
  121. package/dist/ui/assets/diagram-VSXAHHWV-DeBDsA1S.js +3 -0
  122. package/dist/ui/assets/diagram-VX7I27RA-COq97Bh2.js +24 -0
  123. package/dist/ui/assets/diagram-Z3DM3KII-DipozH1R.js +24 -0
  124. package/dist/ui/assets/dist-CMahQVbr.js +141 -0
  125. package/dist/ui/assets/dist-DoRUjfaQ.js +12 -0
  126. package/dist/ui/assets/dist-v5Q1xZ2K.js +1 -0
  127. package/dist/ui/assets/ebnfDiagram-PWID7BFC-C7bjWaVV.js +1 -0
  128. package/dist/ui/assets/{erDiagram-RLTQ6QDP-eWb4VjRB.js → erDiagram-RLTQ6QDP-CkdV1U7x.js} +6 -6
  129. package/dist/ui/assets/eventmodeling-NTZA5JFV-C7NKZ2E3.js +1 -0
  130. package/dist/ui/assets/flowDiagram-HODETNUW-BsiwhEl2.js +1 -0
  131. package/dist/ui/assets/ganttDiagram-EL5Y4UJY-CpLssEGJ.js +292 -0
  132. package/dist/ui/assets/{gitGraph-4MIJSDKK-BKTHQFNQ.js → gitGraph-4MIJSDKK-ZNvMSPlV.js} +1 -1
  133. package/dist/ui/assets/gitGraphDiagram-WWUBYQGX-BLzUTHIQ.js +106 -0
  134. package/dist/ui/assets/github-dark-default-DXG-b-1a.js +1 -0
  135. package/dist/ui/assets/github-light-default-BXViO-2h.js +1 -0
  136. package/dist/ui/assets/go-rLFTqkRN.js +1 -0
  137. package/dist/ui/assets/groovy-CacY0gHj.js +1 -0
  138. package/dist/ui/assets/html-BY76lXLH.js +1 -0
  139. package/dist/ui/assets/index-B0otXprn.css +1 -0
  140. package/dist/ui/assets/index-nZg6iOq8.js +35 -0
  141. package/dist/ui/assets/{info-A6RAGUB7-CB_w7eMD.js → info-A6RAGUB7-CIyWcXp1.js} +1 -1
  142. package/dist/ui/assets/infoDiagram-27XIBGKW-8e2Woehk.js +2 -0
  143. package/dist/ui/assets/{ishikawaDiagram-5VMMS53U-Dd1RLJJm.js → ishikawaDiagram-5VMMS53U-C7lXCzD0.js} +1 -1
  144. package/dist/ui/assets/java-BXcb2rRD.js +1 -0
  145. package/dist/ui/assets/javascript-BgS3c2Ky.js +1 -0
  146. package/dist/ui/assets/{journeyDiagram-3NMN7TZE-CD4al8cv.js → journeyDiagram-3NMN7TZE-Cw7e6vEa.js} +6 -6
  147. package/dist/ui/assets/json-qhed-kSA.js +1 -0
  148. package/dist/ui/assets/jsonc-CYpm1nAK.js +1 -0
  149. package/dist/ui/assets/jsx-Bz0zcwM4.js +1 -0
  150. package/dist/ui/assets/{kanban-definition-UXKFOSKX-CicP51YB.js → kanban-definition-UXKFOSKX-40gNKOtZ.js} +24 -24
  151. package/dist/ui/assets/kotlin-DhhofPvG.js +1 -0
  152. package/dist/ui/assets/{line-Cd1yQwS1.js → line-Dx_6SLjf.js} +1 -1
  153. package/dist/ui/assets/{linear-cCCPOpu7.js → linear-C7gIVo4m.js} +1 -1
  154. package/dist/ui/assets/markdown-BYOwaDjH.js +1 -0
  155. package/dist/ui/assets/{mermaid-parser.core-B65nU8-J.js → mermaid-parser.core-Cx9IgWvp.js} +3 -3
  156. package/dist/ui/assets/mermaid.core-CE4Rcwvp.js +44 -0
  157. package/dist/ui/assets/{mindmap-definition-YA3MSWOX-B6X7miC7.js → mindmap-definition-YA3MSWOX-Bpjh59WU.js} +8 -8
  158. package/dist/ui/assets/{packet-AYTQ26CC-BGs-wvw2.js → packet-AYTQ26CC-TzUU1fUR.js} +1 -1
  159. package/dist/ui/assets/pegDiagram-XKGWAZYB-xfGkTiyU.js +1 -0
  160. package/dist/ui/assets/{pie-WAS4IAKB-Dk_1-q02.js → pie-WAS4IAKB-Cy0RJX4e.js} +1 -1
  161. package/dist/ui/assets/{pieDiagram-E7YTZNPT-g_h8F1NG.js → pieDiagram-E7YTZNPT-C_wFzDa5.js} +3 -3
  162. package/dist/ui/assets/python-gzcpVVnB.js +1 -0
  163. package/dist/ui/assets/{quadrantDiagram-AXDQQJYC-BZnaapW7.js → quadrantDiagram-AXDQQJYC-D8nlig_S.js} +6 -6
  164. package/dist/ui/assets/{radar-RG4KPBEZ-DDgd9Igt.js → radar-RG4KPBEZ-DpEbf4Sa.js} +1 -1
  165. package/dist/ui/assets/{railroad-74A4TZTK-DhAP39G6.js → railroad-74A4TZTK-CSOahYzS.js} +1 -1
  166. package/dist/ui/assets/railroad-abnf-HS5TGJTU-8vJ8IZcu.js +1 -0
  167. package/dist/ui/assets/railroad-ebnf-LZEXJU2U-p9du8TJr.js +1 -0
  168. package/dist/ui/assets/railroad-peg-WCYAUIDC-BweyuB5K.js +1 -0
  169. package/dist/ui/assets/railroadDiagram-O6MQD6OU-CgaqmbL8.js +1 -0
  170. package/dist/ui/assets/{requirementDiagram-BXWQKSXE-DgmeoXsi.js → requirementDiagram-BXWQKSXE-b5SPb0kK.js} +7 -7
  171. package/dist/ui/assets/rolldown-runtime-hePW80VL.js +1 -0
  172. package/dist/ui/assets/rust-Cfkwpbl8.js +1 -0
  173. package/dist/ui/assets/{sankeyDiagram-P5KCCOFB-DjzQt3qt.js → sankeyDiagram-P5KCCOFB-DORlq3KF.js} +7 -7
  174. package/dist/ui/assets/{sequenceDiagram-WJ2MYXX4-CbbbJQEL.js → sequenceDiagram-WJ2MYXX4-BwS_-jk2.js} +9 -9
  175. package/dist/ui/assets/shellscript-CLZ0U2zV.js +1 -0
  176. package/dist/ui/assets/sql-BsFa4tDR.js +1 -0
  177. package/dist/ui/assets/src-B6xuSHsQ.js +1 -0
  178. package/dist/ui/assets/stateDiagram-D77RDMKH-DfgJqXRY.js +1 -0
  179. package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-D7zefEr8.js +1 -0
  180. package/dist/ui/assets/{swimlanes-42K2YHIH-BsVty5RJ.js → swimlanes-42K2YHIH-aT_bNbqM.js} +1 -1
  181. package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-BqH3ZHk1.js +8 -0
  182. package/dist/ui/assets/{timeline-definition-24CTP7MA-jG7c5_Cs.js → timeline-definition-24CTP7MA-V7APg65Z.js} +7 -7
  183. package/dist/ui/assets/toml-CcmNWLt0.js +1 -0
  184. package/dist/ui/assets/{treeView-Q6P3EWNA-DLCAW9b3.js → treeView-Q6P3EWNA-CkX4_NCQ.js} +1 -1
  185. package/dist/ui/assets/{treemap-WGGIJYW6-uUXNdPOX.js → treemap-WGGIJYW6-CNj80LcR.js} +1 -1
  186. package/dist/ui/assets/tsx-udAQXfEw.js +1 -0
  187. package/dist/ui/assets/typescript-bsJCZSQ-.js +1 -0
  188. package/dist/ui/assets/vendor-ui-Cke7Wpgg.js +3 -0
  189. package/dist/ui/assets/{vennDiagram-4TSXK5OY-CHK_fGs0.js → vennDiagram-4TSXK5OY-Cp2p3H8R.js} +7 -7
  190. package/dist/ui/assets/vue-BaXc62bQ.js +1 -0
  191. package/dist/ui/assets/{wardley-WFR3VGLG-DJG6hnMr.js → wardley-WFR3VGLG-DZlFTJK6.js} +1 -1
  192. package/dist/ui/assets/{wardleyDiagram-VM6X3IG4-C82KklcY.js → wardleyDiagram-VM6X3IG4-Lnl-KAaI.js} +3 -3
  193. package/dist/ui/assets/{xychartDiagram-S5SC5T6Z-q9hGmKYE.js → xychartDiagram-S5SC5T6Z-BJxTLbnv.js} +6 -6
  194. package/dist/ui/assets/yaml-rwi0_p6S.js +1 -0
  195. package/dist/ui/index.html +3 -4
  196. package/dist/ui/sw.js +2 -2
  197. package/package.json +3 -2
  198. package/dist/ui/assets/AgentsView-B-w3_cUA.js +0 -1
  199. package/dist/ui/assets/ChecksView-CBObmY95.js +0 -1
  200. package/dist/ui/assets/ChecksView-Dquk2SnE.css +0 -1
  201. package/dist/ui/assets/ContextView-5BIYLq1t.js +0 -4
  202. package/dist/ui/assets/DashboardView-C7HwIylJ.js +0 -1
  203. package/dist/ui/assets/DeploymentsView--iIUVfEH.css +0 -1
  204. package/dist/ui/assets/DeploymentsView-AYs3M5WP.js +0 -1
  205. package/dist/ui/assets/DiffView-COhR1P-a.css +0 -1
  206. package/dist/ui/assets/DiffView-elhz-H8B.js +0 -2
  207. package/dist/ui/assets/InputsView-D4XmIvgc.js +0 -1
  208. package/dist/ui/assets/InputsView-oTB_RUkL.css +0 -1
  209. package/dist/ui/assets/ReleasesView-6NUvSu9N.css +0 -1
  210. package/dist/ui/assets/ReleasesView-DPt6F5YS.js +0 -3
  211. package/dist/ui/assets/SettingsView-5eZ1Py0Q.js +0 -3
  212. package/dist/ui/assets/WorkView-C3h32p3k.js +0 -2
  213. package/dist/ui/assets/WorkView-CFnddFhr.css +0 -1
  214. package/dist/ui/assets/abnfDiagram-VCTEODGH-pHc-qg0W.js +0 -1
  215. package/dist/ui/assets/architecture-7GRP2DOG-BExW7N2X.js +0 -1
  216. package/dist/ui/assets/architectureDiagram-5GKGNRK7-DQV0ZlG2.js +0 -36
  217. package/dist/ui/assets/button-ywbZCzIW.js +0 -1
  218. package/dist/ui/assets/channel-ZvHJgbXo.js +0 -1
  219. package/dist/ui/assets/chunk-75Z2AOVW-ChHwnZLM.js +0 -2
  220. package/dist/ui/assets/chunk-L3NEJ4N5-aNCeLfta.js +0 -1
  221. package/dist/ui/assets/chunk-POPQ4Y6H-Ba34aN-g.js +0 -1
  222. package/dist/ui/assets/chunk-XXDRQBXY-DFBUG-OT.js +0 -1
  223. package/dist/ui/assets/classDiagram-ZZMXUADV-CmFaEw-m.js +0 -1
  224. package/dist/ui/assets/classDiagram-v2-VYDZK3BY-CmFaEw-m.js +0 -1
  225. package/dist/ui/assets/cose-bilkent-JH36ORCC-BTcgMon1.js +0 -1
  226. package/dist/ui/assets/cynefinDiagram-5FMLGOSQ-DhS-kLot.js +0 -62
  227. package/dist/ui/assets/diagram-UQ7AKVKN-gEbDZ2wA.js +0 -41
  228. package/dist/ui/assets/diagram-VSXAHHWV-B2I7HJ_I.js +0 -3
  229. package/dist/ui/assets/diagram-VX7I27RA-BjZiKmur.js +0 -24
  230. package/dist/ui/assets/diagram-Z3DM3KII-uHuWeWJS.js +0 -24
  231. package/dist/ui/assets/dist-DTg6UBE_.js +0 -1
  232. package/dist/ui/assets/ebnfDiagram-PWID7BFC-Dt6YEtM2.js +0 -1
  233. package/dist/ui/assets/eventmodeling-NTZA5JFV-BGINq340.js +0 -1
  234. package/dist/ui/assets/flowDiagram-HODETNUW-CslflvVm.js +0 -1
  235. package/dist/ui/assets/ganttDiagram-EL5Y4UJY-Dc1YagBo.js +0 -292
  236. package/dist/ui/assets/gitGraphDiagram-WWUBYQGX-5MXnQYI9.js +0 -106
  237. package/dist/ui/assets/index-DWedw2UO.css +0 -1
  238. package/dist/ui/assets/index-DXotWZmz.js +0 -27
  239. package/dist/ui/assets/infoDiagram-27XIBGKW-C-9Kuflq.js +0 -2
  240. package/dist/ui/assets/mermaid.core-m8HIJWVk.js +0 -44
  241. package/dist/ui/assets/pegDiagram-XKGWAZYB-C-lyH7_H.js +0 -1
  242. package/dist/ui/assets/railroad-abnf-HS5TGJTU-BqsR_EwF.js +0 -1
  243. package/dist/ui/assets/railroad-ebnf-LZEXJU2U-Duonsle8.js +0 -1
  244. package/dist/ui/assets/railroad-peg-WCYAUIDC-LVUZVuDx.js +0 -1
  245. package/dist/ui/assets/railroadDiagram-O6MQD6OU-CB0apIqD.js +0 -1
  246. package/dist/ui/assets/src-BH-TyZbA.js +0 -1
  247. package/dist/ui/assets/stateDiagram-D77RDMKH-4wOmoi5j.js +0 -1
  248. package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-BJWDIO8n.js +0 -1
  249. package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-DibiQlL8.js +0 -8
  250. package/dist/ui/assets/vendor-ui-C4DmZ9GE.js +0 -3
package/README.md CHANGED
@@ -296,6 +296,23 @@ roles alongside the engineer agent. Freeform task creation sends a description
296
296
  through the PM agent for structured drafting. All agent capability is local —
297
297
  no API tokens leave your machine unless you configure them.
298
298
 
299
+ ## RepoOS Hub for macOS
300
+
301
+ A native Mac app (macOS 13+; sessions persist across relaunches on macOS 14+)
302
+ that keeps tabs on all your RepoOS servers from
303
+ one window: pin tasks across servers, see live attention counts in the sidebar
304
+ and Dock badge, and jump between servers and tasks with Cmd-K. Each server
305
+ loads in its own isolated WebKit session — sessions are never shared between
306
+ servers, and server pages get no bridge into your files or Keychain. Local
307
+ loopback servers need zero setup; remote servers use short-lived, revocable
308
+ capability tokens (created over HTTPS on the server, stored in the Keychain)
309
+ for their attention and search endpoints.
310
+
311
+ The Hub's DMG is published on
312
+ [GitHub Releases](https://github.com/repo-os/repoos/releases) with each tag
313
+ release (the first Hub DMG is pending). Setup, pairing, and limitation details
314
+ are in the [Hub guide](https://github.com/repo-os/repoos/blob/main/user-docs/macos-hub.md).
315
+
299
316
  ## Roadmap
300
317
 
301
318
  - **Stage 1 — parser + index + CLI** ✅
@@ -1,4 +1,4 @@
1
1
  {
2
- "hash": "f5bc7080896e6462e45fb88aeecb10c9c2f675395207b58c11bc29b2b5524aa7",
3
- "version": "0.5.49"
2
+ "hash": "9978dc66ddd3de60d301a374cf6cf80f0e7f6fa67545d1dcab764e930f29b35a",
3
+ "version": "0.5.51"
4
4
  }
@@ -1,3 +1,3 @@
1
1
  {
2
- "generatedAt": "2026-09-20T04:12:23.987Z"
2
+ "generatedAt": "2026-09-23T02:28:26.540Z"
3
3
  }
package/dist/cli/index.js CHANGED
@@ -15,6 +15,7 @@ import { cmdUpgrade } from "../commands/upgrade.js";
15
15
  import { cmdUninstall } from "../commands/uninstall.js";
16
16
  import { cmdStatus } from "../commands/status.js";
17
17
  import { cmdDoctor } from "../commands/doctor.js";
18
+ import { cmdCertify } from "../commands/certify.js";
18
19
  import { cmdSupport } from "../commands/support.js";
19
20
  import { cmdService } from "../commands/service.js";
20
21
  import { checkBuild } from "../core/build.js";
@@ -91,7 +92,8 @@ function help() {
91
92
  cmdRow("init [name]", "Scaffold work/, repoos.toml, AGENTS.md; outside a git repo runs a guided flow that can launch the web console"),
92
93
  cmdRow("list [status]", `Show the board (or one column: ${c.dim("inbox|ready|active|review|done")})`),
93
94
  cmdRow("status [--json]", "One-screen health snapshot: server, build freshness, board, worktrees, tunnel, git"),
94
- cmdRow("doctor [--json]", "Read-only readiness preflight: identity, config, layout, tools, check plan, server, secrets"),
95
+ cmdRow("doctor [--json] [--probe <cli>] [--binary <path>]", "Readiness preflight: identity, config, layout, tools, check plan, server, secrets (--probe runs a live contract check; --binary overrides PATH resolution)"),
96
+ cmdRow("certify <cli> [--yes] [--binary <path>]", "Run the adapter contract suite and write certification evidence into agent-compatibility.json (--binary probes a specific binary)"),
95
97
  cmdRow("support bundle", "Write a redacted, inspectable diagnostic bundle for failed setups"),
96
98
  cmdRow("show <id>", "Show a task's full spec"),
97
99
  cmdRow("mv <id> <status>", `Move a task to a new status — never merges code ${c.dim('flags: --note "...", --force-not-merged')}`),
@@ -101,7 +103,7 @@ function help() {
101
103
  cmdRow('new-doc "<desc>"', "Create a document from a description via PM agent"),
102
104
  cmdRow("index [--json]", "Rebuild the derived index cache"),
103
105
  cmdRow("gc [--yes|--dry-run]", "Collect leaked task worktrees/branches (done/absent tasks, integrate candidates)"),
104
- cmdRow("serve [--port N]", "Start the local server (live API + SSE stream)"),
106
+ cmdRow("serve [--port N]", `Start the local server (live API + SSE stream) ${c.dim("flags: --host, --preview-overrides, --no-preview-overrides")}`),
105
107
  cmdRow("stop [--port N]", "Stop this repo's serve process (by its own lockfile)"),
106
108
  cmdRow("service [sub]", `Manage background services ${c.dim("list|status|install|start|stop|restart|enable|disable|remove")}`),
107
109
  cmdRow("tunnel <sub>", `Publish local apps via Cloudflare Tunnel + Zero Trust ${c.dim("(setup|create|allow|deny|rename|destroy|start|install|stop|list|status)")}`),
@@ -163,6 +165,7 @@ function main() {
163
165
  "check",
164
166
  "status",
165
167
  "doctor",
168
+ "certify",
166
169
  "support",
167
170
  "help",
168
171
  "--help",
@@ -201,6 +204,9 @@ function main() {
201
204
  case "doctor":
202
205
  void cmdDoctor(rest);
203
206
  break;
207
+ case "certify":
208
+ void cmdCertify(rest);
209
+ break;
204
210
  case "support":
205
211
  void cmdSupport(rest);
206
212
  break;
@@ -0,0 +1,10 @@
1
+ export interface CertifyCliArgs {
2
+ cli: string | null;
3
+ yes: boolean;
4
+ json: boolean;
5
+ missingCli: boolean;
6
+ /** Explicit binary path — skips PATH resolution and probes this binary directly. */
7
+ binary: string | null;
8
+ }
9
+ export declare function parseCertifyArgs(argv: string[]): CertifyCliArgs;
10
+ export declare function cmdCertify(argv: string[]): Promise<void>;
@@ -0,0 +1,198 @@
1
+ /**
2
+ * `repoos certify <cli> [--yes] [--json]` — run the adapter contract suite and,
3
+ * when every seam passes, write the certification evidence back into
4
+ * `src/core/agent-compatibility.json` automatically.
5
+ *
6
+ * This is the maintainer-facing counterpart to `repoos doctor --probe`: doctor
7
+ * shows you the result; certify also commits it to the manifest so the next
8
+ * RepoOS release ships the updated compatibility status to all users.
9
+ *
10
+ * The command resolves the manifest path the same way `agent-compatibility.ts`
11
+ * does — src/core/ in a dev checkout, dist/core/ in a built install — and
12
+ * writes back to whichever file it loaded from.
13
+ */
14
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
15
+ import { fileURLToPath } from "node:url";
16
+ import { join } from "node:path";
17
+ import { runAdapterContract } from "../core/agent-contract.js";
18
+ import { parseAgentVersion } from "../core/agent-compatibility.js";
19
+ import { c } from "../cli/colors.js";
20
+ export function parseCertifyArgs(argv) {
21
+ const yes = argv.includes("--yes");
22
+ const json = argv.includes("--json");
23
+ const binaryIdx = argv.indexOf("--binary");
24
+ const binary = binaryIdx !== -1 ? (argv[binaryIdx + 1] ?? null) : null;
25
+ const positional = argv.filter((a, i) => !a.startsWith("--") && argv[i - 1] !== "--binary");
26
+ const cli = positional[0] ?? null;
27
+ return { cli, yes, json, missingCli: !cli, binary };
28
+ }
29
+ /** Locate the live manifest file on disk (src or dist). */
30
+ function findManifestPath() {
31
+ const manifestUrl = new URL("../core/agent-compatibility.json", import.meta.url);
32
+ const candidates = [];
33
+ if (manifestUrl.protocol === "file:") {
34
+ candidates.push(fileURLToPath(manifestUrl));
35
+ }
36
+ candidates.push(join(process.cwd(), "src/core/agent-compatibility.json"), join(process.cwd(), "dist/core/agent-compatibility.json"));
37
+ const root = process.env.REPOOS_ROOT;
38
+ if (root) {
39
+ candidates.push(join(root, "src/core/agent-compatibility.json"), join(root, "dist/core/agent-compatibility.json"));
40
+ }
41
+ for (const p of candidates) {
42
+ try {
43
+ if (existsSync(p))
44
+ return p;
45
+ }
46
+ catch {
47
+ /* skip */
48
+ }
49
+ }
50
+ return null;
51
+ }
52
+ function loadManifest(path) {
53
+ return JSON.parse(readFileSync(path, "utf8"));
54
+ }
55
+ function saveManifest(path, manifest) {
56
+ writeFileSync(path, JSON.stringify(manifest, null, 2) + "\n", "utf8");
57
+ }
58
+ export async function cmdCertify(argv) {
59
+ const { cli, yes, json: asJson, missingCli, binary } = parseCertifyArgs(argv);
60
+ if (missingCli || !cli) {
61
+ console.error(c.red(" repoos certify needs a harness id, e.g. `repoos certify opencode`."));
62
+ console.error(c.dim(" Use --binary <path> to probe a specific binary instead of PATH resolution."));
63
+ process.exitCode = 1;
64
+ return;
65
+ }
66
+ const WARNING = [
67
+ "",
68
+ c.yellow(c.bold("⚠ Live compatibility probe + manifest write")),
69
+ " This runs the adapter contract suite against the installed harness and,",
70
+ " if every seam passes, writes the certification evidence into",
71
+ " src/core/agent-compatibility.json. It may use your provider credentials",
72
+ " and spend tokens. It never reads task files or project content.",
73
+ "",
74
+ ].join("\n");
75
+ if (!yes) {
76
+ if (!process.stdin.isTTY) {
77
+ console.error(c.red(" repoos certify requires --yes when stdin is not a terminal."));
78
+ console.error(c.dim(" repoos certify " + cli + " --yes"));
79
+ process.exitCode = 1;
80
+ return;
81
+ }
82
+ const { createInterface } = await import("node:readline");
83
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
84
+ console.log(WARNING);
85
+ const answer = await new Promise((resolve) => {
86
+ rl.question(c.bold(` Run the ${cli} probe and write results to the manifest? [y/N] `), resolve);
87
+ });
88
+ rl.close();
89
+ if (!/^y(es)?$/i.test(answer.trim())) {
90
+ console.log(c.dim(" Cancelled."));
91
+ return;
92
+ }
93
+ }
94
+ else if (!asJson) {
95
+ console.log(WARNING);
96
+ }
97
+ // Run the probe.
98
+ const result = await runAdapterContract({
99
+ cli,
100
+ mode: "live",
101
+ ...(binary ? { bin: binary } : {}),
102
+ });
103
+ if (asJson) {
104
+ console.log(JSON.stringify(result, null, 2));
105
+ if (!result.passed)
106
+ process.exitCode = 1;
107
+ return;
108
+ }
109
+ // Print probe output (same as doctor --probe).
110
+ console.log("");
111
+ console.log(" " +
112
+ c.bold(c.cyan("Adapter contract probe")) +
113
+ c.dim(" — " + result.cli) +
114
+ c.dim(" (" + result.binary + ")"));
115
+ for (const cap of result.capabilities) {
116
+ const icon = cap.ok ? c.green("✔") : c.red("✗");
117
+ console.log(" " + icon + " " + cap.label + c.dim(" (" + cap.id + ")"));
118
+ console.log(" " + c.dim(cap.detail));
119
+ }
120
+ const passCount = result.capabilities.filter((cap) => cap.ok).length;
121
+ const verdict = result.passed
122
+ ? c.green(`PASSED — ${result.capabilities.length}/${result.capabilities.length} seams`)
123
+ : c.red(`FAILED — ${passCount}/${result.capabilities.length} seams`);
124
+ console.log("");
125
+ console.log(" " + verdict + c.dim(` (${Math.round(result.durationMs / 1000)}s)`));
126
+ if (!result.passed) {
127
+ console.log("");
128
+ console.log(c.dim(" Manifest not updated — probe must pass all seams to certify."));
129
+ console.log("");
130
+ process.exitCode = 1;
131
+ return;
132
+ }
133
+ // Locate the manifest and update it.
134
+ const manifestPath = findManifestPath();
135
+ if (!manifestPath) {
136
+ console.error(c.red(" Cannot find agent-compatibility.json to write certification."));
137
+ console.error(c.dim(" Run from the repoos source checkout, or set REPOOS_ROOT."));
138
+ process.exitCode = 1;
139
+ return;
140
+ }
141
+ const manifest = loadManifest(manifestPath);
142
+ const versionStr = result.detectedVersion ? result.detectedVersion.join(".") : null;
143
+ const now = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
144
+ const source = `repoos certify ${cli} live probe — ${result.capabilities.length}/${result.capabilities.length} seams passed on ${result.startedAt} against binary ${result.binary}`;
145
+ let contract = manifest.contracts.find((c) => c.cli === cli);
146
+ if (!contract) {
147
+ // Bootstrap a minimal contract for a harness that has no entry yet.
148
+ const major = result.detectedVersion?.[0] ?? 0;
149
+ contract = {
150
+ cli,
151
+ name: cli,
152
+ supportedMajor: major,
153
+ supportedRange: `>=${major}.0.0 <${major + 1}.0.0`,
154
+ newestCertifiedVersion: versionStr,
155
+ knownIncompatibleRanges: [],
156
+ requiredCapabilities: result.capabilities.filter((c) => c.ok).map((c) => c.id),
157
+ verifiedAt: now,
158
+ verificationSource: source,
159
+ upgradeGuidance: `Install the current ${cli} release and re-run \`repoos certify ${cli}\`.`,
160
+ officialUrl: "",
161
+ };
162
+ manifest.contracts.push(contract);
163
+ console.log("");
164
+ console.log(" " + c.yellow("⚠ No existing contract — bootstrapped a new entry."));
165
+ console.log(c.dim(" Review src/core/agent-compatibility.json before committing:"));
166
+ console.log(c.dim(` officialUrl, upgradeGuidance, and supportedRange may need editing.`));
167
+ }
168
+ else {
169
+ // Update the three certification fields.
170
+ const prev = contract.newestCertifiedVersion;
171
+ const prevParsed = prev ? parseAgentVersion(prev) : null;
172
+ const thisParsed = result.detectedVersion;
173
+ // Only advance newestCertifiedVersion — never roll it back.
174
+ if (!prevParsed ||
175
+ !thisParsed ||
176
+ thisParsed[0] > prevParsed[0] ||
177
+ (thisParsed[0] === prevParsed[0] && thisParsed[1] > prevParsed[1]) ||
178
+ (thisParsed[0] === prevParsed[0] &&
179
+ thisParsed[1] === prevParsed[1] &&
180
+ thisParsed[2] >= prevParsed[2])) {
181
+ contract.newestCertifiedVersion = versionStr;
182
+ }
183
+ contract.verifiedAt = now;
184
+ contract.verificationSource = source;
185
+ }
186
+ saveManifest(manifestPath, manifest);
187
+ console.log("");
188
+ console.log(" " + c.green("✔ Manifest updated") + c.dim(" — " + manifestPath));
189
+ if (versionStr) {
190
+ console.log(c.dim(` newestCertifiedVersion: ${versionStr}`));
191
+ }
192
+ console.log(c.dim(` verifiedAt: ${now}`));
193
+ console.log("");
194
+ console.log(c.dim(" Next: review the diff, then commit:"));
195
+ console.log(c.dim(` git diff src/core/agent-compatibility.json`));
196
+ console.log(c.dim(` git add src/core/agent-compatibility.json && git commit -m "cert(${cli}): certify ${versionStr ?? "unknown"}"`));
197
+ console.log("");
198
+ }
@@ -1,4 +1,20 @@
1
1
  import { type DoctorReport } from "../core/doctor.js";
2
+ export interface DoctorCliArgs {
3
+ json: boolean;
4
+ yes: boolean;
5
+ /** Value passed to `--probe`, or null when the flag is absent. */
6
+ probe: string | null;
7
+ /** True when `--probe` was given without a value (or before another flag). */
8
+ probeMissingValue: boolean;
9
+ /** Explicit binary path for the probe — bypasses PATH resolution. */
10
+ binary: string | null;
11
+ }
12
+ /**
13
+ * Parse `repoos doctor`'s argument list. Kept pure and exported so the probe
14
+ * arming rules (`--probe` needs a value; `--probe --yes` is a usage error) are
15
+ * unit-tested rather than only exercised through a live run.
16
+ */
17
+ export declare function parseDoctorArgs(argv: string[]): DoctorCliArgs;
2
18
  export declare function renderDoctor(report: DoctorReport): void;
3
- /** `repoos doctor [--json]` */
19
+ /** `repoos doctor [--json] [--probe <cli>] [--yes]` */
4
20
  export declare function cmdDoctor(argv: string[]): Promise<void>;
@@ -1,16 +1,42 @@
1
1
  /**
2
- * `repoos doctor [--json]` — human and machine rendering of the readiness
3
- * preflight built in `src/core/doctor.ts`.
2
+ * `repoos doctor [--json] [--probe <cli>] [--yes]` — human and machine
3
+ * rendering of the readiness preflight built in `src/core/doctor.ts`.
4
4
  *
5
5
  * The command adds no diagnostic logic of its own: it runs the engine, prints
6
6
  * it, and sets the exit code (non-zero when any finding is a `fail`, so it is
7
7
  * usable in scripts). `--json` emits the same `DoctorReport` the UI and the
8
8
  * support bundle (#0453) consume.
9
+ *
10
+ * `--probe <cli>` runs the live adapter contract suite for that harness
11
+ * (`src/core/agent-contract.ts`) instead of the static report. It is opt-in
12
+ * and may use provider credentials/tokens, so it warns, asks for confirmation
13
+ * on a TTY (or requires `--yes` headless), runs in an isolated temp fixture,
14
+ * and cleans up.
9
15
  */
10
16
  import { readBuildMeta } from "../core/build.js";
17
+ import { runAdapterContract } from "../core/agent-contract.js";
11
18
  import { doctorRemediations, DOCTOR_CATEGORIES, runDoctor, } from "../core/doctor.js";
12
19
  import { c } from "../cli/colors.js";
13
20
  const ICON = { pass: "✔", warn: "⚠", fail: "✗" };
21
+ /**
22
+ * Parse `repoos doctor`'s argument list. Kept pure and exported so the probe
23
+ * arming rules (`--probe` needs a value; `--probe --yes` is a usage error) are
24
+ * unit-tested rather than only exercised through a live run.
25
+ */
26
+ export function parseDoctorArgs(argv) {
27
+ const json = argv.includes("--json");
28
+ const yes = argv.includes("--yes");
29
+ const binaryIdx = argv.indexOf("--binary");
30
+ const binary = binaryIdx !== -1 ? (argv[binaryIdx + 1] ?? null) : null;
31
+ const probeArg = argv.indexOf("--probe");
32
+ if (probeArg === -1)
33
+ return { json, yes, probe: null, probeMissingValue: false, binary };
34
+ const value = argv[probeArg + 1];
35
+ if (!value || value.startsWith("--")) {
36
+ return { json, yes, probe: null, probeMissingValue: true, binary };
37
+ }
38
+ return { json, yes, probe: value, probeMissingValue: false, binary };
39
+ }
14
40
  function severityColor(severity, text) {
15
41
  if (severity === "pass")
16
42
  return c.green(text);
@@ -57,9 +83,18 @@ export function renderDoctor(report) {
57
83
  }
58
84
  console.log("");
59
85
  }
60
- /** `repoos doctor [--json]` */
86
+ /** `repoos doctor [--json] [--probe <cli>] [--yes]` */
61
87
  export async function cmdDoctor(argv) {
62
- const asJson = argv.includes("--json");
88
+ const { json: asJson, yes, probe: probeCli, probeMissingValue, binary } = parseDoctorArgs(argv);
89
+ if (probeMissingValue) {
90
+ console.error(c.red(" repoos doctor --probe needs a harness id, e.g. `--probe opencode`."));
91
+ process.exitCode = 1;
92
+ return;
93
+ }
94
+ if (probeCli) {
95
+ await cmdProbe(probeCli, { asJson, yes, binary });
96
+ return;
97
+ }
63
98
  try {
64
99
  const report = await runDoctor({ version: readBuildMeta().version });
65
100
  if (asJson) {
@@ -76,3 +111,85 @@ export async function cmdDoctor(argv) {
76
111
  process.exitCode = 1;
77
112
  }
78
113
  }
114
+ /**
115
+ * Live adapter-contract probe (`repoos doctor --probe <cli>`). Opt-in: warns
116
+ * that provider credentials/tokens may be spent, confirms on a TTY (or demands
117
+ * `--yes` headless), runs every seam in an isolated temp fixture, and reports
118
+ * the honest result. A passed probe is the evidence a maintainer records in
119
+ * `src/core/agent-compatibility.json` (verifiedAt + verificationSource).
120
+ */
121
+ async function cmdProbe(cli, opts) {
122
+ const WARNING = [
123
+ "",
124
+ c.yellow(c.bold("⚠ Live compatibility probe")),
125
+ " This runs the installed harness in an isolated temporary directory,",
126
+ " exercising version, help, model listing, a headless one-shot, event",
127
+ " parsing, permission/auto mode, session continuation, and cancellation.",
128
+ " It may use your provider credentials and spend tokens: the one-shot,",
129
+ " resume, and cancellation seams each start a real harness run. It never",
130
+ " reads task files, prompts, or project content, and the temporary fixture",
131
+ " is removed when done.",
132
+ "",
133
+ ].join("\n");
134
+ if (!opts.yes) {
135
+ if (!process.stdin.isTTY) {
136
+ console.error(c.red(" repoos doctor --probe requires --yes when stdin is not a terminal."));
137
+ console.error(c.dim(" repoos doctor --probe " + cli + " --yes"));
138
+ process.exitCode = 1;
139
+ return;
140
+ }
141
+ const { createInterface } = await import("node:readline");
142
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
143
+ console.log(WARNING);
144
+ const answer = await new Promise((resolve) => {
145
+ rl.question(c.bold(` Run the live ${cli} compatibility probe? [y/N] `), resolve);
146
+ });
147
+ rl.close();
148
+ if (!/^y(es)?$/i.test(answer.trim())) {
149
+ console.log(c.dim(" Probe cancelled."));
150
+ return;
151
+ }
152
+ }
153
+ else if (!opts.asJson) {
154
+ console.log(WARNING);
155
+ }
156
+ try {
157
+ const result = await runAdapterContract({
158
+ cli,
159
+ mode: "live",
160
+ ...(opts.binary ? { bin: opts.binary } : {}),
161
+ });
162
+ if (opts.asJson) {
163
+ console.log(JSON.stringify(result, null, 2));
164
+ }
165
+ else {
166
+ console.log("");
167
+ console.log(" " +
168
+ c.bold(c.cyan("Adapter contract probe")) +
169
+ c.dim(" — " + result.cli) +
170
+ c.dim(" (" + result.binary + ")"));
171
+ for (const cap of result.capabilities) {
172
+ const icon = cap.ok ? c.green("✔") : c.red("✗");
173
+ console.log(" " + icon + " " + cap.label + c.dim(" (" + cap.id + ")"));
174
+ console.log(" " + c.dim(cap.detail));
175
+ }
176
+ const verdict = result.passed
177
+ ? c.green(`PASSED — ${result.capabilities.length}/${result.capabilities.length} seams`)
178
+ : c.red(`FAILED — ${result.capabilities.filter((cap) => cap.ok).length}/${result.capabilities.length} seams`);
179
+ console.log("");
180
+ console.log(" " + verdict + c.dim(` (${Math.round(result.durationMs / 1000)}s)`));
181
+ if (result.passed && result.evidence) {
182
+ console.log("");
183
+ console.log(" " + c.bold("Record evidence in the manifest"));
184
+ console.log(" " + c.dim(result.evidence));
185
+ }
186
+ console.log("");
187
+ }
188
+ if (!result.passed)
189
+ process.exitCode = 1;
190
+ }
191
+ catch (e) {
192
+ console.error(c.red(" repoos doctor --probe failed: ") + e.message);
193
+ process.exitCode = 1;
194
+ }
195
+ }
@@ -40,6 +40,17 @@ export declare function resolveServeHost(explicitHost?: string): {
40
40
  tailscaleDetected: boolean;
41
41
  tailscaleIP?: string;
42
42
  };
43
+ /**
44
+ * Whether this `repoos serve` should apply the repo's preview-only
45
+ * `[preview.*]` config overlay (#0464).
46
+ *
47
+ * Precedence, lowest to highest: the REPOOS_PREVIEW_CHILD=1 marker (set by
48
+ * PreviewManager on every managed preview child) turns it on; an explicit
49
+ * `--no-preview-overrides`/`--preview-overrides` flag always wins. An ordinary
50
+ * `repoos serve` has neither, so it resolves the base configuration unchanged.
51
+ * Exported for tests.
52
+ */
53
+ export declare function resolvePreviewOverrides(args: readonly string[], env?: NodeJS.ProcessEnv): boolean;
43
54
  /**
44
55
  * True when this process is a managed agent (REPOOS_AGENT=1) attempting to
45
56
  * launch `repoos serve` directly, as opposed to a preview child or a reload
@@ -79,6 +79,26 @@ export function resolveServeHost(explicitHost) {
79
79
  return { host: "0.0.0.0", tailscaleDetected: true, tailscaleIP };
80
80
  return { host: "127.0.0.1", tailscaleDetected: false };
81
81
  }
82
+ /**
83
+ * Whether this `repoos serve` should apply the repo's preview-only
84
+ * `[preview.*]` config overlay (#0464).
85
+ *
86
+ * Precedence, lowest to highest: the REPOOS_PREVIEW_CHILD=1 marker (set by
87
+ * PreviewManager on every managed preview child) turns it on; an explicit
88
+ * `--no-preview-overrides`/`--preview-overrides` flag always wins. An ordinary
89
+ * `repoos serve` has neither, so it resolves the base configuration unchanged.
90
+ * Exported for tests.
91
+ */
92
+ export function resolvePreviewOverrides(args, env = process.env) {
93
+ let explicit;
94
+ for (const arg of args) {
95
+ if (arg === "--preview-overrides")
96
+ explicit = true;
97
+ else if (arg === "--no-preview-overrides")
98
+ explicit = false;
99
+ }
100
+ return explicit ?? env.REPOOS_PREVIEW_CHILD === "1";
101
+ }
82
102
  /**
83
103
  * True when this process is a managed agent (REPOOS_AGENT=1) attempting to
84
104
  * launch `repoos serve` directly, as opposed to a preview child or a reload
@@ -116,6 +136,12 @@ export async function cmdServe(args, opts = {}) {
116
136
  else if (args[i] === "--quiet" || args[i] === "-q")
117
137
  quiet = true;
118
138
  }
139
+ // Preview-only config overlay (#0464). A managed preview child
140
+ // (REPOOS_PREVIEW_CHILD=1, set by PreviewManager) applies the repo's
141
+ // `[preview.*]` overlay by default; every ordinary `repoos serve` resolves
142
+ // the base configuration. `--preview-overrides` forces it on (UI-test
143
+ // previews); `--no-preview-overrides` is the escape hatch back to base.
144
+ const applyPreviewOverrides = resolvePreviewOverrides(args);
119
145
  const { host, tailscaleDetected, tailscaleIP } = resolveServeHost(explicitHost);
120
146
  let handle;
121
147
  try {
@@ -124,6 +150,8 @@ export async function cmdServe(args, opts = {}) {
124
150
  handle = await startServer({
125
151
  port,
126
152
  host,
153
+ hostExplicit: explicitHost !== undefined,
154
+ previewOverrides: applyPreviewOverrides,
127
155
  reloadReplacement: process.env.REPOOS_RELOAD === "1",
128
156
  });
129
157
  }
@@ -149,6 +177,11 @@ export async function cmdServe(args, opts = {}) {
149
177
  snap.taskCount +
150
178
  c.dim(" tasks · SSE stream at ") +
151
179
  c.cyan(handle.url + "/api/events"));
180
+ // Report an active preview-only overlay and its effective keys (#0464), so a
181
+ // preview that deliberately differs from the base config is never silent.
182
+ if (handle.previewOverrides?.length) {
183
+ console.log(c.yellow(" preview overrides active: ") + c.dim(handle.previewOverrides.join(", ")));
184
+ }
152
185
  const rt = isBun()
153
186
  ? `Bun ${process.versions.bun ?? ""}`.trim()
154
187
  : `Node ${process.versions.node}`;
@@ -15,7 +15,7 @@
15
15
  * Commands operate on the current repo by default.
16
16
  */
17
17
  import { listServices, getServiceStatus, installService, removeService, startService, stopService, restartService, enableAutoStart, disableAutoStart, checkHealth, } from "../core/service-manager.js";
18
- import { boardRoot, deriveServePort, loadConfig } from "../core/config.js";
18
+ import { boardRoot, loadConfig, resolveServePort } from "../core/config.js";
19
19
  import { c } from "../cli/colors.js";
20
20
  function statusLabel(s) {
21
21
  if (s === "running")
@@ -78,7 +78,7 @@ export async function cmdService(argv) {
78
78
  case "install": {
79
79
  const { root } = boardRoot();
80
80
  const config = loadConfig(root);
81
- const port = deriveServePort(root);
81
+ const port = resolveServePort(root, config);
82
82
  const result = await installService(root, port, { autoStart: false });
83
83
  if (!result.ok) {
84
84
  console.error(c.red(" ✗ " + result.error));
@@ -50,8 +50,8 @@ export declare function cmdMv(id?: string, status?: string, note?: string, opts?
50
50
  */
51
51
  export declare function cmdNote(args: string[]): void;
52
52
  /**
53
- * `repoos update <id> [--title ...] [--area ...] [--priority ...] [--type ...]
54
- * [--body ... | --body -] [--branch ...] [--assigned-to ai|human]
53
+ * `repoos update <id> [--title ...] [--area ...] [--story ...] [--priority ...]
54
+ * [--type ...] [--body ... | --body -] [--branch ...] [--assigned-to ai|human]
55
55
  * [--needs-input true|false] [--questions "Question one\nQuestion two"]`
56
56
  *
57
57
  * Writes directly via patchTaskFile (same path the server's PATCH route uses),
@@ -248,6 +248,7 @@ export function cmdNote(args) {
248
248
  const UPDATE_FLAGS = {
249
249
  title: "title",
250
250
  area: "area",
251
+ story: "story",
251
252
  priority: "priority",
252
253
  type: "type",
253
254
  body: "body",
@@ -257,8 +258,8 @@ const UPDATE_FLAGS = {
257
258
  questions: "questions",
258
259
  };
259
260
  /**
260
- * `repoos update <id> [--title ...] [--area ...] [--priority ...] [--type ...]
261
- * [--body ... | --body -] [--branch ...] [--assigned-to ai|human]
261
+ * `repoos update <id> [--title ...] [--area ...] [--story ...] [--priority ...]
262
+ * [--type ...] [--body ... | --body -] [--branch ...] [--assigned-to ai|human]
262
263
  * [--needs-input true|false] [--questions "Question one\nQuestion two"]`
263
264
  *
264
265
  * Writes directly via patchTaskFile (same path the server's PATCH route uses),
@@ -268,7 +269,7 @@ const UPDATE_FLAGS = {
268
269
  */
269
270
  export function cmdUpdate(args) {
270
271
  const [id, ...rest] = args;
271
- const usage = ' Usage: repoos update <id> [--title "..."] [--area a] [--priority p] [--type t] [--body "..."|-] [--branch b] [--assigned-to ai|human] [--needs-input true|false] [--questions "Question one\\nQuestion two"] [--clear-questions]';
272
+ const usage = ' Usage: repoos update <id> [--title "..."] [--area a] [--story "Delivery slice"] [--priority p] [--type t] [--body "..."|-] [--branch b] [--assigned-to ai|human] [--needs-input true|false] [--questions "Question one\\nQuestion two"] [--clear-questions]';
272
273
  if (!id) {
273
274
  console.error(c.red(usage));
274
275
  process.exitCode = 1;
@@ -337,7 +338,16 @@ export function cmdUpdate(args) {
337
338
  process.exitCode = 1;
338
339
  }
339
340
  }
340
- const NEW_FLAGS = new Set(["ai", "type", "area", "priority", "body", "needs-input", "questions"]);
341
+ const NEW_FLAGS = new Set([
342
+ "ai",
343
+ "type",
344
+ "area",
345
+ "story",
346
+ "priority",
347
+ "body",
348
+ "needs-input",
349
+ "questions",
350
+ ]);
341
351
  function parseQuestions(raw) {
342
352
  try {
343
353
  const parsed = JSON.parse(raw);
@@ -355,7 +365,7 @@ function parseQuestions(raw) {
355
365
  }
356
366
  /** `repoos new <title> [--ai] [--needs-input true] [--questions "..."]` */
357
367
  export function cmdNew(args) {
358
- const usage = ' Usage: repoos new "Task title" [--ai] [--type bug] [--area web] [--priority p1] [--body "..."|-] [--needs-input true|false] [--questions "Question one\\nQuestion two"]';
368
+ const usage = ' Usage: repoos new "Task title" [--ai] [--type bug] [--area web] [--story "Delivery slice"] [--priority p1] [--body "..."|-] [--needs-input true|false] [--questions "Question one\\nQuestion two"]';
359
369
  const flags = {};
360
370
  const positional = [];
361
371
  for (let i = 0; i < args.length; i++) {
@@ -396,6 +406,7 @@ export function cmdNew(args) {
396
406
  title,
397
407
  type: flags.type || undefined,
398
408
  area: flags.area || undefined,
409
+ story: flags.story || undefined,
399
410
  priority: flags.priority || undefined,
400
411
  assignedTo: flags.ai ? "ai" : undefined,
401
412
  body: flags.body || undefined,
@@ -18,7 +18,17 @@ export async function startPreviewServer(root) {
18
18
  // disableAuth: the smoke gate tests generic rendering (title, board,
19
19
  // buttons), not auth flows — a project with [auth] enabled must not make
20
20
  // `repoos check` itself unable to reach the dashboard.
21
- const opts = { host: "127.0.0.1", port: 0, disableAuth: true };
21
+ //
22
+ // previewOverrides: this is the UI-test preview path, so it resolves the same
23
+ // preview-only `[preview.*]` overlay a managed preview applies (#0464). The
24
+ // smoke test's throwaway fixture declares no overlay, so this is normally a
25
+ // no-op; it matters when the harness serves a real root.
26
+ const opts = {
27
+ host: "127.0.0.1",
28
+ port: 0,
29
+ disableAuth: true,
30
+ previewOverrides: true,
31
+ };
22
32
  if (root !== undefined)
23
33
  opts.root = root;
24
34
  return startServer(opts);