@repo-os/repoos 0.5.45

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 (362) hide show
  1. package/LICENSE.md +110 -0
  2. package/README.md +272 -0
  3. package/dist/.build-info.json +4 -0
  4. package/dist/.build-stamp.json +3 -0
  5. package/dist/cli/colors.d.ts +13 -0
  6. package/dist/cli/colors.js +37 -0
  7. package/dist/cli/index.d.ts +2 -0
  8. package/dist/cli/index.js +221 -0
  9. package/dist/commands/check.d.ts +170 -0
  10. package/dist/commands/check.js +1227 -0
  11. package/dist/commands/docs.d.ts +2 -0
  12. package/dist/commands/docs.js +70 -0
  13. package/dist/commands/gc.d.ts +1 -0
  14. package/dist/commands/gc.js +57 -0
  15. package/dist/commands/init.d.ts +9 -0
  16. package/dist/commands/init.js +699 -0
  17. package/dist/commands/screenshots.d.ts +7 -0
  18. package/dist/commands/screenshots.js +77 -0
  19. package/dist/commands/serve.d.ts +55 -0
  20. package/dist/commands/serve.js +204 -0
  21. package/dist/commands/status.d.ts +140 -0
  22. package/dist/commands/status.js +569 -0
  23. package/dist/commands/stop.d.ts +1 -0
  24. package/dist/commands/stop.js +59 -0
  25. package/dist/commands/tasks.d.ts +47 -0
  26. package/dist/commands/tasks.js +334 -0
  27. package/dist/commands/tunnel.d.ts +1 -0
  28. package/dist/commands/tunnel.js +1271 -0
  29. package/dist/commands/ui-harness.d.ts +53 -0
  30. package/dist/commands/ui-harness.js +62 -0
  31. package/dist/commands/ui-smoke.d.ts +6 -0
  32. package/dist/commands/ui-smoke.js +220 -0
  33. package/dist/commands/upgrade.d.ts +15 -0
  34. package/dist/commands/upgrade.js +188 -0
  35. package/dist/core/auth-store.d.ts +81 -0
  36. package/dist/core/auth-store.js +530 -0
  37. package/dist/core/auth.d.ts +75 -0
  38. package/dist/core/auth.js +124 -0
  39. package/dist/core/bootstrap.d.ts +41 -0
  40. package/dist/core/bootstrap.js +236 -0
  41. package/dist/core/build.d.ts +92 -0
  42. package/dist/core/build.js +249 -0
  43. package/dist/core/canary.d.ts +10 -0
  44. package/dist/core/canary.js +14 -0
  45. package/dist/core/check-failure-summary.d.ts +10 -0
  46. package/dist/core/check-failure-summary.js +34 -0
  47. package/dist/core/config.d.ts +160 -0
  48. package/dist/core/config.js +1288 -0
  49. package/dist/core/context-pack.d.ts +74 -0
  50. package/dist/core/context-pack.js +778 -0
  51. package/dist/core/db.d.ts +236 -0
  52. package/dist/core/db.js +747 -0
  53. package/dist/core/detect.d.ts +69 -0
  54. package/dist/core/detect.js +251 -0
  55. package/dist/core/docs.d.ts +76 -0
  56. package/dist/core/docs.js +225 -0
  57. package/dist/core/frontmatter.d.ts +29 -0
  58. package/dist/core/frontmatter.js +215 -0
  59. package/dist/core/git.d.ts +505 -0
  60. package/dist/core/git.js +1453 -0
  61. package/dist/core/indexer.d.ts +33 -0
  62. package/dist/core/indexer.js +282 -0
  63. package/dist/core/input.d.ts +66 -0
  64. package/dist/core/input.js +222 -0
  65. package/dist/core/logger.d.ts +70 -0
  66. package/dist/core/logger.js +138 -0
  67. package/dist/core/models.d.ts +45 -0
  68. package/dist/core/models.js +291 -0
  69. package/dist/core/net-probe.d.ts +4 -0
  70. package/dist/core/net-probe.js +20 -0
  71. package/dist/core/providers/deepinfra.d.ts +23 -0
  72. package/dist/core/providers/deepinfra.js +44 -0
  73. package/dist/core/providers/index.d.ts +24 -0
  74. package/dist/core/providers/index.js +59 -0
  75. package/dist/core/providers/openrouter.d.ts +28 -0
  76. package/dist/core/providers/openrouter.js +82 -0
  77. package/dist/core/providers/spend.d.ts +86 -0
  78. package/dist/core/providers/spend.js +286 -0
  79. package/dist/core/providers/types.d.ts +56 -0
  80. package/dist/core/providers/types.js +39 -0
  81. package/dist/core/repoos.d.ts +59 -0
  82. package/dist/core/repoos.js +221 -0
  83. package/dist/core/runtime.d.ts +35 -0
  84. package/dist/core/runtime.js +167 -0
  85. package/dist/core/skills-registry.d.ts +39 -0
  86. package/dist/core/skills-registry.js +148 -0
  87. package/dist/core/skills-registry.test.d.ts +1 -0
  88. package/dist/core/skills-registry.test.js +52 -0
  89. package/dist/core/sysmem.d.ts +7 -0
  90. package/dist/core/sysmem.js +55 -0
  91. package/dist/core/tailscale.d.ts +2 -0
  92. package/dist/core/tailscale.js +19 -0
  93. package/dist/core/task.d.ts +53 -0
  94. package/dist/core/task.js +310 -0
  95. package/dist/core/toml-line.d.ts +20 -0
  96. package/dist/core/toml-line.js +52 -0
  97. package/dist/core/toml-validate.d.ts +44 -0
  98. package/dist/core/toml-validate.js +335 -0
  99. package/dist/core/tunnel-assistant.d.ts +30 -0
  100. package/dist/core/tunnel-assistant.js +65 -0
  101. package/dist/core/tunnel-registry.d.ts +96 -0
  102. package/dist/core/tunnel-registry.js +267 -0
  103. package/dist/core/tunnel-registry.test.d.ts +1 -0
  104. package/dist/core/tunnel-registry.test.js +309 -0
  105. package/dist/core/tunnel.d.ts +103 -0
  106. package/dist/core/tunnel.js +320 -0
  107. package/dist/core/types.d.ts +811 -0
  108. package/dist/core/types.js +27 -0
  109. package/dist/core/worktree-gc.d.ts +57 -0
  110. package/dist/core/worktree-gc.js +194 -0
  111. package/dist/server/__tests__/integration-job.test.d.ts +1 -0
  112. package/dist/server/__tests__/integration-job.test.js +129 -0
  113. package/dist/server/agents.d.ts +1020 -0
  114. package/dist/server/agents.js +4070 -0
  115. package/dist/server/attachments.d.ts +51 -0
  116. package/dist/server/attachments.js +130 -0
  117. package/dist/server/auto-engineering.d.ts +45 -0
  118. package/dist/server/auto-engineering.js +275 -0
  119. package/dist/server/branchless-release.d.ts +22 -0
  120. package/dist/server/branchless-release.js +67 -0
  121. package/dist/server/built-in-agents.d.ts +305 -0
  122. package/dist/server/built-in-agents.js +1838 -0
  123. package/dist/server/cto-monitor.d.ts +35 -0
  124. package/dist/server/cto-monitor.js +281 -0
  125. package/dist/server/cto.d.ts +125 -0
  126. package/dist/server/cto.js +590 -0
  127. package/dist/server/deployments.d.ts +119 -0
  128. package/dist/server/deployments.js +325 -0
  129. package/dist/server/diff-snapshot.d.ts +20 -0
  130. package/dist/server/diff-snapshot.js +73 -0
  131. package/dist/server/done.d.ts +160 -0
  132. package/dist/server/done.js +488 -0
  133. package/dist/server/freeform.d.ts +55 -0
  134. package/dist/server/freeform.js +179 -0
  135. package/dist/server/handoff.d.ts +99 -0
  136. package/dist/server/handoff.js +575 -0
  137. package/dist/server/hetzner.d.ts +45 -0
  138. package/dist/server/hetzner.js +117 -0
  139. package/dist/server/icons.d.ts +8 -0
  140. package/dist/server/icons.js +195 -0
  141. package/dist/server/integration-job.d.ts +75 -0
  142. package/dist/server/integration-job.js +144 -0
  143. package/dist/server/integration-orchestrator.d.ts +211 -0
  144. package/dist/server/integration-orchestrator.js +1299 -0
  145. package/dist/server/integration-status.d.ts +48 -0
  146. package/dist/server/integration-status.js +71 -0
  147. package/dist/server/live-index.d.ts +295 -0
  148. package/dist/server/live-index.js +452 -0
  149. package/dist/server/model-test.d.ts +20 -0
  150. package/dist/server/model-test.js +100 -0
  151. package/dist/server/ntfy.d.ts +57 -0
  152. package/dist/server/ntfy.js +112 -0
  153. package/dist/server/pm-attachments.d.ts +35 -0
  154. package/dist/server/pm-attachments.js +181 -0
  155. package/dist/server/pm-runs.d.ts +58 -0
  156. package/dist/server/pm-runs.js +80 -0
  157. package/dist/server/preview.d.ts +174 -0
  158. package/dist/server/preview.js +641 -0
  159. package/dist/server/release.d.ts +88 -0
  160. package/dist/server/release.js +449 -0
  161. package/dist/server/reload.d.ts +194 -0
  162. package/dist/server/reload.js +586 -0
  163. package/dist/server/remote-validation.d.ts +132 -0
  164. package/dist/server/remote-validation.js +478 -0
  165. package/dist/server/repo-lock.d.ts +36 -0
  166. package/dist/server/repo-lock.js +141 -0
  167. package/dist/server/review-guard.d.ts +14 -0
  168. package/dist/server/review-guard.js +159 -0
  169. package/dist/server/review.d.ts +243 -0
  170. package/dist/server/review.js +1211 -0
  171. package/dist/server/routes/agents.d.ts +6 -0
  172. package/dist/server/routes/agents.js +28 -0
  173. package/dist/server/routes/auth.d.ts +60 -0
  174. package/dist/server/routes/auth.js +755 -0
  175. package/dist/server/routes/config.d.ts +20 -0
  176. package/dist/server/routes/config.js +347 -0
  177. package/dist/server/routes/debugger.d.ts +33 -0
  178. package/dist/server/routes/debugger.js +360 -0
  179. package/dist/server/routes/deployments.d.ts +3 -0
  180. package/dist/server/routes/deployments.js +16 -0
  181. package/dist/server/routes/docs.d.ts +8 -0
  182. package/dist/server/routes/docs.js +135 -0
  183. package/dist/server/routes/helpers.d.ts +21 -0
  184. package/dist/server/routes/helpers.js +171 -0
  185. package/dist/server/routes/index.d.ts +19 -0
  186. package/dist/server/routes/index.js +18 -0
  187. package/dist/server/routes/info.d.ts +17 -0
  188. package/dist/server/routes/info.js +177 -0
  189. package/dist/server/routes/inputs.d.ts +7 -0
  190. package/dist/server/routes/inputs.js +125 -0
  191. package/dist/server/routes/model-providers.d.ts +27 -0
  192. package/dist/server/routes/model-providers.js +94 -0
  193. package/dist/server/routes/models.d.ts +3 -0
  194. package/dist/server/routes/models.js +36 -0
  195. package/dist/server/routes/notify.d.ts +2 -0
  196. package/dist/server/routes/notify.js +17 -0
  197. package/dist/server/routes/playground.d.ts +29 -0
  198. package/dist/server/routes/playground.js +81 -0
  199. package/dist/server/routes/release.d.ts +20 -0
  200. package/dist/server/routes/release.js +86 -0
  201. package/dist/server/routes/router.d.ts +12 -0
  202. package/dist/server/routes/router.js +32 -0
  203. package/dist/server/routes/skill-registry.d.ts +5 -0
  204. package/dist/server/routes/skill-registry.js +51 -0
  205. package/dist/server/routes/tasks.d.ts +58 -0
  206. package/dist/server/routes/tasks.js +1442 -0
  207. package/dist/server/routes/transcribe.d.ts +2 -0
  208. package/dist/server/routes/transcribe.js +124 -0
  209. package/dist/server/routes/types.d.ts +68 -0
  210. package/dist/server/routes/types.js +1 -0
  211. package/dist/server/routes/ui.d.ts +5 -0
  212. package/dist/server/routes/ui.js +81 -0
  213. package/dist/server/routes/utils.d.ts +3 -0
  214. package/dist/server/routes/utils.js +23 -0
  215. package/dist/server/serve-reaper.d.ts +135 -0
  216. package/dist/server/serve-reaper.js +491 -0
  217. package/dist/server/server.d.ts +49 -0
  218. package/dist/server/server.js +2171 -0
  219. package/dist/server/supervisor.d.ts +89 -0
  220. package/dist/server/supervisor.js +231 -0
  221. package/dist/server/system.d.ts +198 -0
  222. package/dist/server/system.js +480 -0
  223. package/dist/server/task-check.d.ts +45 -0
  224. package/dist/server/task-check.js +71 -0
  225. package/dist/server/task-transitions.d.ts +51 -0
  226. package/dist/server/task-transitions.js +78 -0
  227. package/dist/server/task-watchdog.d.ts +158 -0
  228. package/dist/server/task-watchdog.js +681 -0
  229. package/dist/server/test-run.d.ts +28 -0
  230. package/dist/server/test-run.js +81 -0
  231. package/dist/server/watcher.d.ts +21 -0
  232. package/dist/server/watcher.js +194 -0
  233. package/dist/server/write.d.ts +94 -0
  234. package/dist/server/write.js +345 -0
  235. package/dist/ui/assets/AgentsView-CF4wRvHh.css +1 -0
  236. package/dist/ui/assets/AgentsView-D-myL-kA.js +1 -0
  237. package/dist/ui/assets/ContextView-D3TC-RSp.css +1 -0
  238. package/dist/ui/assets/ContextView-DsOqAdyE.js +4 -0
  239. package/dist/ui/assets/DashboardView-BOhsIJqO.js +1 -0
  240. package/dist/ui/assets/DashboardView-Ck9o0RP2.css +1 -0
  241. package/dist/ui/assets/DeploymentsView--iIUVfEH.css +1 -0
  242. package/dist/ui/assets/DeploymentsView-DXu_FYR2.js +1 -0
  243. package/dist/ui/assets/InputsView-24HVbVPk.js +1 -0
  244. package/dist/ui/assets/InputsView-BLb7GHtx.css +1 -0
  245. package/dist/ui/assets/LoginView-6QlGg6cx.css +1 -0
  246. package/dist/ui/assets/LoginView-BqupI0Lt.js +1 -0
  247. package/dist/ui/assets/ReleasesView-BEG1A0YH.css +1 -0
  248. package/dist/ui/assets/ReleasesView-CAgMuxpe.js +3 -0
  249. package/dist/ui/assets/SettingsView-CA-NYSMK.css +1 -0
  250. package/dist/ui/assets/SettingsView-O3iZSnjg.js +3 -0
  251. package/dist/ui/assets/WorkView-D8Tl6qwy.js +1 -0
  252. package/dist/ui/assets/WorkView-DMYL2s3W.css +1 -0
  253. package/dist/ui/assets/abnfDiagram-VCTEODGH-J5lkSnEE.js +1 -0
  254. package/dist/ui/assets/arc-BHZnmhhM.js +1 -0
  255. package/dist/ui/assets/architecture-7GRP2DOG-pLdFt-xS.js +1 -0
  256. package/dist/ui/assets/architectureDiagram-5GKGNRK7-C3k89uKX.js +36 -0
  257. package/dist/ui/assets/array-BifhSqXX.js +1 -0
  258. package/dist/ui/assets/blockDiagram-I7D4REHJ-AWNoBzop.js +129 -0
  259. package/dist/ui/assets/button-lbikqSph.js +1 -0
  260. package/dist/ui/assets/c4Diagram-7LVT6UL2-DKG1D5gd.js +38 -0
  261. package/dist/ui/assets/channel-gA4qBv3A.js +1 -0
  262. package/dist/ui/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  263. package/dist/ui/assets/chunk-4HAMMTFA-D1YR8lF_.js +62 -0
  264. package/dist/ui/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  265. package/dist/ui/assets/chunk-75Z2AOVW-5GuBxfsL.js +2 -0
  266. package/dist/ui/assets/chunk-DU6HZSFF-DfdNNqwa.js +127 -0
  267. package/dist/ui/assets/chunk-F27PBJKO-BPZzinQ4.js +1 -0
  268. package/dist/ui/assets/chunk-FOHPRMQF-l2z4K2jD.js +161 -0
  269. package/dist/ui/assets/chunk-GMAD6QVW-DGWvSKj5.js +72 -0
  270. package/dist/ui/assets/chunk-GVQU2GXP-D6Aw75wJ.js +1 -0
  271. package/dist/ui/assets/chunk-IMKFNOWR-B8mMBKCW.js +231 -0
  272. package/dist/ui/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  273. package/dist/ui/assets/chunk-L3NEJ4N5-D5OJuXYE.js +1 -0
  274. package/dist/ui/assets/chunk-OSK3NFVY-B7r9w2UW.js +10 -0
  275. package/dist/ui/assets/chunk-P2QGCYS3-C74X4AQX.js +1 -0
  276. package/dist/ui/assets/chunk-POPQ4Y6H-C5_u1gUS.js +1 -0
  277. package/dist/ui/assets/chunk-PWAF6VOD-DfoTLtxn.js +1 -0
  278. package/dist/ui/assets/chunk-SHT3W25Y-D40m2eqz.js +168 -0
  279. package/dist/ui/assets/chunk-SVP7TREG-euxi0Kap.js +88 -0
  280. package/dist/ui/assets/chunk-TICWLB2K-fkdxngzN.js +206 -0
  281. package/dist/ui/assets/chunk-XXDRQBXY-DFBUG-OT.js +1 -0
  282. package/dist/ui/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  283. package/dist/ui/assets/classDiagram-ZZMXUADV-BzW8bq2P.js +1 -0
  284. package/dist/ui/assets/classDiagram-v2-VYDZK3BY-BzW8bq2P.js +1 -0
  285. package/dist/ui/assets/cose-bilkent-JH36ORCC-BTcgMon1.js +1 -0
  286. package/dist/ui/assets/cynefin-OW5HDTMX-B5m_COsS.js +1 -0
  287. package/dist/ui/assets/cynefinDiagram-5FMLGOSQ-C-AG6CGe.js +62 -0
  288. package/dist/ui/assets/cytoscape.esm-FBntH-9t.js +321 -0
  289. package/dist/ui/assets/dagre-GXQ25YYZ-DDfDnp8L.js +4 -0
  290. package/dist/ui/assets/dagre-PrKaheQc.js +1 -0
  291. package/dist/ui/assets/defaultLocale-BFoDCU3G.js +1 -0
  292. package/dist/ui/assets/diagram-S7CK7UJ4-DjQZAlEY.js +30 -0
  293. package/dist/ui/assets/diagram-UQ7AKVKN-DAZ9yp1B.js +41 -0
  294. package/dist/ui/assets/diagram-VSXAHHWV-BWepUKJD.js +3 -0
  295. package/dist/ui/assets/diagram-VX7I27RA-EcV1J81b.js +24 -0
  296. package/dist/ui/assets/diagram-Z3DM3KII-Dbz7XU_K.js +24 -0
  297. package/dist/ui/assets/dist-DTg6UBE_.js +1 -0
  298. package/dist/ui/assets/ebnfDiagram-PWID7BFC-BUyQw8Mm.js +1 -0
  299. package/dist/ui/assets/erDiagram-RLTQ6QDP-WVf8ukKt.js +99 -0
  300. package/dist/ui/assets/eventmodeling-NTZA5JFV-DHqyLOAn.js +1 -0
  301. package/dist/ui/assets/flowDiagram-HODETNUW-CYk_ze5K.js +1 -0
  302. package/dist/ui/assets/ganttDiagram-EL5Y4UJY-rB4MZuB-.js +292 -0
  303. package/dist/ui/assets/gitGraph-4MIJSDKK-BOTWM8dY.js +1 -0
  304. package/dist/ui/assets/gitGraphDiagram-WWUBYQGX-eYscuhtP.js +106 -0
  305. package/dist/ui/assets/graphlib-DS17s2tU.js +1 -0
  306. package/dist/ui/assets/index-BACBfnga.css +1 -0
  307. package/dist/ui/assets/index-BOQ-ust6.js +26 -0
  308. package/dist/ui/assets/info-A6RAGUB7-_67wOORe.js +1 -0
  309. package/dist/ui/assets/infoDiagram-27XIBGKW-XVXbddTA.js +2 -0
  310. package/dist/ui/assets/init-C-OQMol4.js +1 -0
  311. package/dist/ui/assets/ishikawaDiagram-5VMMS53U-ClLNiEru.js +70 -0
  312. package/dist/ui/assets/journeyDiagram-3NMN7TZE-NRawjR6i.js +139 -0
  313. package/dist/ui/assets/kanban-definition-UXKFOSKX-BgSzBfIx.js +89 -0
  314. package/dist/ui/assets/katex-DolUETbr.js +257 -0
  315. package/dist/ui/assets/line-KAyfuul4.js +1 -0
  316. package/dist/ui/assets/linear-cCCPOpu7.js +1 -0
  317. package/dist/ui/assets/mermaid-parser.core-CgXZk1iN.js +7 -0
  318. package/dist/ui/assets/mermaid.core-BUUkChHW.js +44 -0
  319. package/dist/ui/assets/mindmap-definition-YA3MSWOX-Cpn7vW4r.js +96 -0
  320. package/dist/ui/assets/ordinal-BDEzSJ7C.js +1 -0
  321. package/dist/ui/assets/packet-AYTQ26CC-0lZwM-d6.js +1 -0
  322. package/dist/ui/assets/path-COt_16Va.js +1 -0
  323. package/dist/ui/assets/pegDiagram-XKGWAZYB-impy0inn.js +1 -0
  324. package/dist/ui/assets/pie-WAS4IAKB-CqfdGHYg.js +1 -0
  325. package/dist/ui/assets/pieDiagram-E7YTZNPT-CxjL4I1h.js +39 -0
  326. package/dist/ui/assets/quadrantDiagram-AXDQQJYC-Cjd1QMIe.js +7 -0
  327. package/dist/ui/assets/radar-RG4KPBEZ-CRkQIwiv.js +1 -0
  328. package/dist/ui/assets/railroad-74A4TZTK-i67XSWTB.js +1 -0
  329. package/dist/ui/assets/railroad-abnf-HS5TGJTU-Cv9m5aS3.js +1 -0
  330. package/dist/ui/assets/railroad-ebnf-LZEXJU2U-C5ZIn-Jh.js +1 -0
  331. package/dist/ui/assets/railroad-peg-WCYAUIDC-CGra9Oq-.js +1 -0
  332. package/dist/ui/assets/railroadDiagram-O6MQD6OU-_pK0qyaY.js +1 -0
  333. package/dist/ui/assets/releases-B0WNV-SY.js +1 -0
  334. package/dist/ui/assets/repoos-cto-square.webp +0 -0
  335. package/dist/ui/assets/repoos-helpful-pm-square.webp +0 -0
  336. package/dist/ui/assets/repoos-orchestrator-square.webp +0 -0
  337. package/dist/ui/assets/repoos-performance-agent-square.webp +0 -0
  338. package/dist/ui/assets/repoos-ross-from-friends-square.webp +0 -0
  339. package/dist/ui/assets/repoos-tech-debt-agent-square.webp +0 -0
  340. package/dist/ui/assets/requirementDiagram-BXWQKSXE-CRrFX-yw.js +84 -0
  341. package/dist/ui/assets/rough.esm-By172zw-.js +1 -0
  342. package/dist/ui/assets/sankeyDiagram-P5KCCOFB-X_xFRj9E.js +40 -0
  343. package/dist/ui/assets/sequenceDiagram-WJ2MYXX4-Byb49lKf.js +162 -0
  344. package/dist/ui/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  345. package/dist/ui/assets/src-BH-TyZbA.js +1 -0
  346. package/dist/ui/assets/stateDiagram-D77RDMKH-CzaPrqYF.js +1 -0
  347. package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-BCXckz7K.js +1 -0
  348. package/dist/ui/assets/swimlanes-42K2YHIH-Cx_1lnqr.js +1 -0
  349. package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-54qsKi6A.js +8 -0
  350. package/dist/ui/assets/timeline-definition-24CTP7MA-B1IbZPQ-.js +120 -0
  351. package/dist/ui/assets/treeView-Q6P3EWNA-DFWhVE3d.js +1 -0
  352. package/dist/ui/assets/treemap-WGGIJYW6-BmbYPThn.js +1 -0
  353. package/dist/ui/assets/vendor-ui-DPm7zLxi.js +3 -0
  354. package/dist/ui/assets/vendor-vue-CobgyEJp.js +1 -0
  355. package/dist/ui/assets/vennDiagram-4TSXK5OY-Ae2AtRpt.js +34 -0
  356. package/dist/ui/assets/wardley-WFR3VGLG-BtD4X4tL.js +1 -0
  357. package/dist/ui/assets/wardleyDiagram-VM6X3IG4-B3YN2fTd.js +78 -0
  358. package/dist/ui/assets/xychartDiagram-S5SC5T6Z-CIzJfMKA.js +7 -0
  359. package/dist/ui/favicon.svg +11 -0
  360. package/dist/ui/index.html +49 -0
  361. package/dist/ui/sw.js +48 -0
  362. package/package.json +91 -0
@@ -0,0 +1,699 @@
1
+ /**
2
+ * `repoos init` — make any repo RepoOS-ready, idempotently. Safe to re-run: it
3
+ * never overwrites existing files, only creates what's missing.
4
+ *
5
+ * In a directory that is NOT inside a git repo, `repoos init` switches to a
6
+ * guided, interactive flow that creates a brand-new RepoOS project from
7
+ * scratch: optionally in a subdirectory, with a choice of layout (repo root
8
+ * vs. a `repoos/` subfolder, config file at root either way), an optional
9
+ * one-line project description (seeded into the sample task) and an optional
10
+ * initial commit.
11
+ */
12
+ import { spawn } from "node:child_process";
13
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync, } from "node:fs";
14
+ import { createServer } from "node:net";
15
+ import { join, resolve } from "node:path";
16
+ import { createInterface } from "node:readline/promises";
17
+ import { stdin as input, stdout as output } from "node:process";
18
+ import { deriveServePort, findRepoRoot, loadConfig } from "../core/config.js";
19
+ import { gitAvailable, gitCommitAll, gitConfig, gitInit, isGitRepo } from "../core/git.js";
20
+ import { c } from "../cli/colors.js";
21
+ import { cmdServe } from "./serve.js";
22
+ const SAMPLE_TASK = (description) => `---
23
+ id: "0001"
24
+ title: Set up RepoOS
25
+ type: chore
26
+ status: done
27
+ priority: p2
28
+ area: infra
29
+ assigned_to: unassigned
30
+ created_by: human
31
+ branch: ""
32
+ ---
33
+ ${description ? `\n## Overview\n\n${description}\n` : ""}
34
+ ## Problem
35
+
36
+ The repo needed a lightweight, repo-native way to track work that AI agents
37
+ and humans share. Tasks live as markdown files, versioned in git.
38
+
39
+ ## Desired UX
40
+
41
+ Run \`repoos list\` to see the board. Run \`repoos show 0001\` to read a task
42
+ (this one). Agents read these files directly for full context.
43
+
44
+ ## Acceptance criteria
45
+
46
+ - [x] \`repoos init\` scaffolded work/, repoos.toml, AGENTS.md
47
+ - [x] \`repoos list\` shows this task
48
+ - [x] Editing the \`status:\` field moves it across the board
49
+
50
+ This task exists to show you the shape of a task file — it's done because
51
+ running \`repoos init\` already satisfies everything above. There's nothing to
52
+ "work" here; move on to your next task.
53
+
54
+ ## Notes for AI
55
+
56
+ Status is a frontmatter field — never move files between folders. Keep diffs
57
+ small. Read AGENTS.md before starting any task.
58
+ `;
59
+ /**
60
+ * The first *workable* task a guided new-project init leaves on the board.
61
+ * 0001 is deliberately `done` (scaffolding is the whole of it), so this is what
62
+ * a new user — or their first agent — actually picks up. `repoos init` runs
63
+ * before any server or agent exists, so the body itself is the prompt: it
64
+ * embeds the one-line description collected at init and carries the questions
65
+ * that turn that description into docs and real tasks later.
66
+ */
67
+ const NEW_PROJECT_STARTER_TASK = (id, description) => `---
68
+ id: "${id}"
69
+ title: Flesh out the product vision and initial architecture
70
+ type: spec
71
+ status: ready
72
+ priority: p2
73
+ area: product
74
+ assigned_to: unassigned
75
+ created_by: human
76
+ branch: ""
77
+ ---
78
+ ## Overview
79
+
80
+ This project started from a one-line description. This task turns it into
81
+ something a team can actually build from — a shared vision, an initial
82
+ architecture, and a first batch of concrete work.
83
+
84
+ ## Project description
85
+
86
+ ${description
87
+ ? `> ${description}`
88
+ : "_No description was given at init time. Start by writing one line that says what this project is and who it's for._"}
89
+
90
+ ## What to do
91
+
92
+ 1. Read the description above and the rest of this repo.
93
+ 2. Work through the questions that block design — on your own, or with the
94
+ project's owner:
95
+ - Who is this for, and what is the smallest useful first release?
96
+ - What stack and hosting, and why those over the alternatives?
97
+ - What is explicitly **out of scope** for now?
98
+ 3. Write the answers into \`docs/\` — at minimum a short vision note and an
99
+ architecture note. Keep them specific to this project.
100
+ 4. Break the result into a handful of concrete tasks with
101
+ \`repoos new "<title>"\`, and move the ones that are ready into \`ready\`.
102
+ 5. Record the docs you wrote here, then move this task to \`review\` (or
103
+ \`done\` if there is genuinely nothing left to capture).
104
+
105
+ ## Notes for AI
106
+
107
+ This task is self-contained: the description above and the questions in step 2
108
+ are the prompt. Ask the human before inventing answers about stack, scope or
109
+ priorities — a short back-and-forth here saves a lot of rework later.
110
+ `;
111
+ /**
112
+ * The first workable task for `repoos init` inside an existing codebase. There
113
+ * is already a repo to read, so unlike the new-project starter this one is
114
+ * about documenting what exists and turning the gaps into a real backlog.
115
+ */
116
+ const EXISTING_REPO_STARTER_TASK = (id) => `---
117
+ id: "${id}"
118
+ title: Read this codebase and propose docs/ + an initial task backlog
119
+ type: spec
120
+ status: ready
121
+ priority: p2
122
+ area: docs
123
+ assigned_to: unassigned
124
+ created_by: human
125
+ branch: ""
126
+ ---
127
+ ## Overview
128
+
129
+ RepoOS was just added to an existing codebase. The first useful move is to read
130
+ what's already here, write down what a newcomer — human or agent — would need,
131
+ then turn what's missing into work.
132
+
133
+ ## What to do
134
+
135
+ 1. Scan the repo: top-level structure, languages and frameworks, build and
136
+ test commands, and any existing conventions or docs.
137
+ 2. Write the durable findings into \`docs/\` — architecture notes and the
138
+ conventions anyone working here must follow.
139
+ 3. Draft a small starter backlog of real tasks with \`repoos new "<title>"\`,
140
+ each concrete enough to work on its own.
141
+ 4. Record what you wrote here, then move this task to \`review\` (or \`done\` if
142
+ there is nothing left to capture).
143
+
144
+ ## Notes for AI
145
+
146
+ Read \`AGENTS.md\` first — it's the operating loop for this repo. Base the docs
147
+ on what the code actually does rather than what you'd expect it to; where the
148
+ repo is silent, write down the open question instead of guessing.
149
+ `;
150
+ const AGENTS_MD = `# AGENTS.md
151
+
152
+ This repo uses **RepoOS**: tasks are markdown files under \`work/\`, and the
153
+ repo itself is the source of truth. This file tells AI agents how to operate.
154
+
155
+ ## Operating loop
156
+
157
+ 1. Read this file and any relevant docs under \`docs/\`.
158
+ 2. Pick a task from \`work/\` whose \`status: ready\`.
159
+ 3. Set its \`status: active\` (edit the frontmatter; do not move the file).
160
+ 4. Create a worktree on the branch named in the task's \`branch:\` field, or set one.
161
+ 5. Implement → test → if the repo has a git remote, open an MR/PR against main.
162
+ 6. Set \`status: review\` when ready for human sign-off. **Leave the worktree open; do NOT merge its branch.**
163
+
164
+ ## Review and sign-off
165
+
166
+ A \`review\` task stays in its open worktree until a human (or another AI) signs
167
+ off; the implementer never merges to \`main\` at \`review\` time.
168
+
169
+ - No git remote: on approval, the reviewer says **"move task <id> to done"**. The
170
+ implementer then sets \`status: done\` (commit \`docs(<id>): set status done\`),
171
+ fast-forward merges the branch to \`main\`, removes the worktree, and deletes
172
+ the branch.
173
+ - With a git remote: an MR/PR is opened against \`main\` at \`review\` time. On
174
+ approval it is merged by the reviewer (or by the implementer only on "move task
175
+ <id> to done"), then remote + local branches are deleted and \`status\` is set
176
+ to \`done\`.
177
+ - Requested changes are fixed on the same worktree, tests re-run, and the task
178
+ re-set to \`review\`.
179
+ - If the \`reviewer\` agent is enabled on the Agents page, RepoOS reviews the
180
+ task automatically when it lands in \`review\` and shows a short report (bugs,
181
+ edge cases, suggestions) in the task drawer. It is advisory: the human still
182
+ reviews and is the only one who moves a task to \`done\`.
183
+
184
+ ## Rules
185
+
186
+ - **Never** move task files between folders. Status lives in frontmatter.
187
+ - **Never write directly to \`work/*.md\` files.** All task creation and
188
+ manipulation goes through \`repoos\` commands or HTTP API endpoints
189
+ (\`POST /api/tasks\`, \`PATCH /api/tasks/:id\`, etc.). If the RepoOS server
190
+ is unreachable, stop and report the issue — do not hand-write task files.
191
+ - **The Product Manager agent is authorized to create and update tasks.** It
192
+ must use those same RepoOS CLI commands or HTTP API endpoints for task body,
193
+ metadata, and status changes; it must never edit task Markdown directly.
194
+ - **Never** deploy to production without human sign-off.
195
+ - Keep frontmatter tidy; \`repoos\` will normalize key order on write.
196
+ - One task = one focused worktree.
197
+
198
+ ## Conventions
199
+
200
+ Document stack-specific conventions here (framework, lint, test commands).
201
+
202
+ ## UI previews are server-owned
203
+
204
+ Never run \`repoos serve\` yourself and never pick a port — RepoOS owns the
205
+ control-plane port and every preview port, and direct serve attempts from agent
206
+ processes are rejected. Preview requests are the human's to make — do NOT
207
+ automatically request a preview before handoff or as a routine part of finishing
208
+ a task. If the human explicitly asks you to verify a change the way a browser
209
+ would see it, request this task's managed preview by emitting the exact signal
210
+ line (idempotent, and no localhost or curl is required — your sandbox may have
211
+ no network access to the control plane):
212
+
213
+ ::repoos-preview-request::
214
+
215
+ RepoOS validates the request against your live run, starts the preview from
216
+ your worktree, probes it server-side, and records the preview URL and probe
217
+ result in your task transcript. The preview is reaped when the task leaves
218
+ active/review.
219
+ `;
220
+ function repoosToml(layout) {
221
+ const ns = layout === "repoos"
222
+ ? `workDir = "repoos/work"\ndocsDir = "repoos/docs"\ncacheDir = "repoos/.repoos"\n`
223
+ : "";
224
+ return `# RepoOS configuration. All fields optional — these are the defaults.
225
+
226
+ ${ns}defaultStatus = "inbox"
227
+ defaultAssignee = "unassigned"
228
+
229
+ # Optional features, off by default — uncomment to turn them on. Real
230
+ # secrets (API keys, client secrets) go in .env, never here (this file is
231
+ # git-tracked); see .env.example for the matching variables.
232
+
233
+ # [auth] # require login (email OTP / Google) — docs/native-auth.md
234
+ # enabled = true
235
+ # bootstrapAdmin = "you@example.com" # only this email can claim the first admin account
236
+ #
237
+ # [auth.emailProvider]
238
+ # type = "resend"
239
+ # fromAddress = "noreply@yourdomain.com"
240
+ #
241
+ # [auth.google] # optional — adds a "Sign in with Google" button
242
+ # clientId = "..." # clientSecret goes in .env, not here
243
+
244
+ # [whisper] # voice-to-text in text areas
245
+ # provider = "groq" # or "openai"
246
+
247
+ # ntfyEnabled = true # push notifications on task lifecycle events
248
+ # ntfyTopic = "repoos_myproject"
249
+ # ntfyBaseUrl = "https://ntfy.sh" # or your self-hosted ntfy server
250
+ `;
251
+ }
252
+ const ENV_EXAMPLE = `# Copy to .env and fill in what you need — .env is gitignored, this file is
253
+ # tracked so the repo documents which secrets a full setup expects.
254
+ # repoos serve auto-loads .env at startup; real shell/process-supervisor env
255
+ # vars still take precedence over it.
256
+
257
+ # --- Auth (docs/native-auth.md) — only used when [auth].enabled = true ---
258
+ # REPOOS_RESEND_API_KEY=re_...
259
+ # REPOOS_GOOGLE_CLIENT_SECRET=...
260
+ # REPOOS_AUTH_SESSION_SECRET=... # auto-generated on first boot if omitted
261
+
262
+ # --- Voice-to-text transcription (only used when [whisper] is configured) ---
263
+ # REPOOS_WHISPER_KEY=... # or GROQ_API_KEY / OPENAI_API_KEY directly
264
+
265
+ # --- repoos tunnel (Cloudflare Tunnel + Access) ---
266
+ # CLOUDFLARE_API_TOKEN=...
267
+
268
+ # --- ntfy.sh push notifications ---
269
+ # NTFY_BASE_URL=https://ntfy.sh # or your self-hosted ntfy server
270
+ `;
271
+ const INITIAL_COMMIT_MSG = "chore: initialize RepoOS project";
272
+ const STARTER_TASK = {
273
+ new: { slug: "flesh-out-the-vision", build: NEW_PROJECT_STARTER_TASK },
274
+ existing: { slug: "read-the-codebase", build: (id) => EXISTING_REPO_STARTER_TASK(id) },
275
+ };
276
+ /**
277
+ * Next free 4-digit task id for a scaffolded file, derived from the ids that
278
+ * already exist under `workDir` (matching the numbering scheme used by
279
+ * `createTask`). 0001 is written just before this runs, so a fresh scaffold
280
+ * gets 0002; a repo that already has tasks gets the next id past the highest.
281
+ */
282
+ function nextScaffoldId(root, workDir) {
283
+ let max = 0;
284
+ try {
285
+ for (const name of readdirSync(join(root, workDir))) {
286
+ const m = name.match(/^(\d+)/);
287
+ if (m)
288
+ max = Math.max(max, parseInt(m[1], 10));
289
+ }
290
+ }
291
+ catch {
292
+ /* workDir doesn't exist yet — start from zero */
293
+ }
294
+ return String(max + 1).padStart(4, "0");
295
+ }
296
+ /**
297
+ * Locate an already-seeded starter task by its slug suffix. Init is
298
+ * idempotent, so once the starter exists a re-run must not write another one —
299
+ * and crucially, must not compute a *new* id every time (which would append a
300
+ * fresh 0002, 0003, … starter on each run).
301
+ */
302
+ function findStarter(root, workDir, slug) {
303
+ try {
304
+ const match = readdirSync(join(root, workDir)).find((n) => n.endsWith(`-${slug}.md`));
305
+ return match ? join(workDir, match).split("\\").join("/") : null;
306
+ }
307
+ catch {
308
+ return null;
309
+ }
310
+ }
311
+ export function scaffoldInto(root, description, layout = "root", kind = "new") {
312
+ const created = [];
313
+ const skipped = [];
314
+ const ensureDir = (rel) => {
315
+ const p = join(root, rel);
316
+ if (!existsSync(p)) {
317
+ mkdirSync(p, { recursive: true });
318
+ created.push(rel + "/");
319
+ }
320
+ else {
321
+ skipped.push(rel + "/");
322
+ }
323
+ };
324
+ const ensureFile = (rel, content) => {
325
+ const p = join(root, rel);
326
+ if (!existsSync(p)) {
327
+ writeFileSync(p, content);
328
+ created.push(rel);
329
+ }
330
+ else {
331
+ skipped.push(rel);
332
+ }
333
+ };
334
+ // Write config first so workDir/docsDir/cacheDir overrides are in effect
335
+ // before the dirs are created (namespace layout) — or so an existing
336
+ // config is respected untouched (existing-repo path).
337
+ ensureFile("repoos.toml", repoosToml(layout));
338
+ const config = loadConfig(root);
339
+ ensureDir(config.workDir);
340
+ ensureDir(config.docsDir);
341
+ ensureFile("AGENTS.md", AGENTS_MD);
342
+ ensureFile(join(config.workDir, "0001-set-up-repoos.md"), SAMPLE_TASK(description));
343
+ // 0001 is `done` (scaffolding is all of it), so without this the ready
344
+ // column is empty right after init. Seed one genuinely workable task; its
345
+ // id follows whatever is already on the board.
346
+ const starter = STARTER_TASK[kind];
347
+ const existingStarter = findStarter(root, config.workDir, starter.slug);
348
+ if (existingStarter) {
349
+ skipped.push(existingStarter);
350
+ }
351
+ else {
352
+ const starterId = nextScaffoldId(root, config.workDir);
353
+ ensureFile(join(config.workDir, `${starterId}-${starter.slug}.md`), starter.build(starterId, description));
354
+ }
355
+ ensureFile(".env.example", ENV_EXAMPLE);
356
+ // gitignore the derived cache and local secrets
357
+ const giPath = join(root, ".gitignore");
358
+ const ignoreLines = [
359
+ { comment: "# RepoOS derived index cache", line: `${config.cacheDir}/` },
360
+ { comment: "# Local secrets — see .env.example", line: ".env" },
361
+ ];
362
+ const existingLines = existsSync(giPath) ? readFileSync(giPath, "utf8").split(/\r?\n/) : [];
363
+ const toAdd = ignoreLines.filter((l) => !existingLines.some((e) => e.trim() === l.line));
364
+ if (toAdd.length === 0) {
365
+ skipped.push(".gitignore");
366
+ }
367
+ else if (existsSync(giPath)) {
368
+ appendFileSync(giPath, "\n" + toAdd.map((l) => `${l.comment}\n${l.line}`).join("\n\n") + "\n");
369
+ created.push(".gitignore (+entry)");
370
+ }
371
+ else {
372
+ writeFileSync(giPath, toAdd.map((l) => `${l.comment}\n${l.line}`).join("\n\n") + "\n");
373
+ created.push(".gitignore");
374
+ }
375
+ return { created, skipped };
376
+ }
377
+ function reportInit(root, created, skipped) {
378
+ console.log(c.bold(c.cyan("\n RepoOS initialized")) + c.dim(` · ${root}\n`));
379
+ for (const f of created)
380
+ console.log(" " + c.green("created ") + f);
381
+ for (const f of skipped)
382
+ console.log(" " + c.dim("exists " + f));
383
+ }
384
+ /**
385
+ * The marker that identifies a RepoOS project root: repoos.toml. It lives at
386
+ * the root in BOTH layouts (root and repoos/ namespace), so this alone is a
387
+ * reliable, unambiguous signal. We deliberately do NOT scan for work/ dirs —
388
+ * a `repoos/work/` folder could just be the actual repoos repo clone (or any
389
+ * unrelated `work/`), which would make sibling directories false-positive as
390
+ * "already a RepoOS project".
391
+ */
392
+ function repoOSMarker(dir) {
393
+ const p = join(dir, "repoos.toml");
394
+ return existsSync(p) ? p : null;
395
+ }
396
+ /** Nearest ancestor (or the dir itself) that already has a RepoOS layout. */
397
+ function findRepoOSDir(start) {
398
+ let dir = resolve(start);
399
+ while (true) {
400
+ if (repoOSMarker(dir))
401
+ return dir;
402
+ const parent = resolve(dir, "..");
403
+ if (parent === dir)
404
+ return null;
405
+ dir = parent;
406
+ }
407
+ }
408
+ function warnAlreadySetUp(dir, hint) {
409
+ console.log(c.yellow("\n RepoOS is already set up in ") + c.cyan(dir) + c.yellow("."));
410
+ if (hint)
411
+ console.log(c.dim(` ${hint}`));
412
+ const marker = repoOSMarker(dir);
413
+ if (marker) {
414
+ console.log(c.dim(" Detected because ") + c.cyan(marker) + c.dim(" exists."));
415
+ }
416
+ console.log(c.dim(" To initialize a brand-new project, run repoos init in a different (empty) directory."));
417
+ }
418
+ async function ask(question) {
419
+ const rl = createInterface({ input, output });
420
+ try {
421
+ const answer = await rl.question(question);
422
+ return answer.trim();
423
+ }
424
+ finally {
425
+ rl.close();
426
+ }
427
+ }
428
+ async function confirm(question, dflt) {
429
+ const hint = dflt ? " [Y/n]" : " [y/N]";
430
+ const answer = (await ask(question + c.dim(hint) + " ")).toLowerCase();
431
+ if (answer === "")
432
+ return dflt;
433
+ return answer === "y" || answer === "yes";
434
+ }
435
+ /** Ask where the scaffold should live: repo root (default) or a repoos/ subfolder. */
436
+ async function askLayout() {
437
+ for (let attempt = 0; attempt < 3; attempt++) {
438
+ const answer = (await ask(" Where should RepoOS live?" +
439
+ c.dim(" r = repo root (default), n = repoos/ subfolder — avoids clashing with existing dirs") +
440
+ ": ")).toLowerCase();
441
+ if (answer === "" || answer === "r" || answer === "root")
442
+ return "root";
443
+ if (answer === "n" || answer === "namespace" || answer === "repoos")
444
+ return "repoos";
445
+ console.log(c.yellow(` "${answer}" — type r (root) or n (repoos/ subfolder).`));
446
+ }
447
+ return "root";
448
+ }
449
+ /** Open a URL in the default browser. Fail-soft (best effort, never blocks). */
450
+ function openBrowser(url) {
451
+ const cmd = process.platform === "darwin"
452
+ ? ["open", url]
453
+ : process.platform === "win32"
454
+ ? ["cmd", "/c", "start", "", url]
455
+ : ["xdg-open", url];
456
+ try {
457
+ const child = spawn(cmd[0], cmd.slice(1), {
458
+ detached: true,
459
+ stdio: "ignore",
460
+ });
461
+ child.on("error", () => { });
462
+ child.unref();
463
+ }
464
+ catch {
465
+ /* fail-soft */
466
+ }
467
+ }
468
+ function probePort(port) {
469
+ return new Promise((resolve) => {
470
+ const srv = createServer();
471
+ srv.once("error", () => resolve(false));
472
+ srv.listen(port, "127.0.0.1", () => srv.close(() => resolve(true)));
473
+ });
474
+ }
475
+ /** First free port at or above `start` (bounded). Falls back to `start`. */
476
+ async function nextFreePort(start) {
477
+ for (let p = start; p < start + 50; p++) {
478
+ if (await probePort(p))
479
+ return p;
480
+ }
481
+ return start;
482
+ }
483
+ /**
484
+ * Ask for a serve port, defaulting to this repo's stable derived port (the same
485
+ * one `repoos serve` would pick). `explicit` is true only when the user typed a
486
+ * concrete port — the caller then pins it in repoos.toml so future `serve`s
487
+ * reuse it.
488
+ */
489
+ async function askPort(derived) {
490
+ for (let attempt = 0; attempt < 3; attempt++) {
491
+ const raw = await ask(" Preferred port" +
492
+ c.dim(` [${derived}] — Enter for this repo's default, 0 = let the OS pick a free port`) +
493
+ ": ");
494
+ if (raw === "")
495
+ return { port: derived, explicit: false };
496
+ const n = Number(raw);
497
+ if (Number.isInteger(n) && n >= 0 && n <= 65535) {
498
+ return { port: n, explicit: n > 0 };
499
+ }
500
+ console.log(c.yellow(` "${raw}" isn't a valid port.`));
501
+ }
502
+ return { port: derived, explicit: false };
503
+ }
504
+ /** Pin `servePort` in repoos.toml so future `repoos serve` runs reuse it. */
505
+ function persistServePort(root, port) {
506
+ const tomlPath = join(root, "repoos.toml");
507
+ try {
508
+ const text = readFileSync(tomlPath, "utf8");
509
+ if (/^\s*servePort\s*=/m.test(text))
510
+ return;
511
+ const line = `servePort = ${port}\n`;
512
+ const anchor = /^defaultAssignee\s*=.*$/m;
513
+ const next = anchor.test(text)
514
+ ? text.replace(anchor, (m) => `${m}\nservePort = ${port}`)
515
+ : text + (text.endsWith("\n") ? "" : "\n") + line;
516
+ writeFileSync(tomlPath, next);
517
+ console.log(" " + c.green("saved") + c.dim(` servePort = ${port} to repoos.toml`));
518
+ }
519
+ catch {
520
+ /* fail-soft — the server still starts on the chosen port this run */
521
+ }
522
+ }
523
+ async function guidedNewRepo(args) {
524
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
525
+ console.error(c.red("\n This directory isn't a git repo, so repoos init needs interactive prompts."));
526
+ console.error(c.dim(" Run it in a terminal, or run `git init` first and then `repoos init` again."));
527
+ process.exitCode = 1;
528
+ return;
529
+ }
530
+ const cwd = process.cwd();
531
+ let projectName = (args[0] ?? "").trim();
532
+ if (projectName && !/^[A-Za-z0-9._-]+$/.test(projectName)) {
533
+ console.error(c.red(` Invalid project name "${projectName}" — use letters, digits, . _ -`));
534
+ process.exitCode = 1;
535
+ return;
536
+ }
537
+ console.log(c.dim("\n Not inside a git repository."));
538
+ console.log(c.cyan(" repoos init will create a new RepoOS project here."));
539
+ console.log(c.dim(" Default: the CURRENT directory. Enter a project name to use a subdirectory instead."));
540
+ if (!projectName) {
541
+ projectName = await ask(" Project name" + c.dim(" (Enter = current directory)") + ": ");
542
+ }
543
+ let target = cwd;
544
+ if (projectName) {
545
+ target = join(cwd, projectName);
546
+ if (repoOSMarker(target)) {
547
+ warnAlreadySetUp(target, "Nothing to create — that project already exists.");
548
+ process.exitCode = 1;
549
+ return;
550
+ }
551
+ console.log();
552
+ const ok = await confirm(" Create the project in a new subdirectory " +
553
+ c.cyan(`./${projectName}`) +
554
+ c.dim(` → ${target}`), true);
555
+ if (!ok) {
556
+ console.log(c.yellow("\n Cancelled — nothing was created."));
557
+ return;
558
+ }
559
+ }
560
+ else {
561
+ console.log(c.dim(` → Using the current directory: ${cwd}`));
562
+ }
563
+ const layout = await askLayout();
564
+ console.log();
565
+ const scaffoldFiles = layout === "repoos"
566
+ ? "repoos/work/, repoos/docs/, AGENTS.md, repoos.toml, .gitignore"
567
+ : "work/, docs/, AGENTS.md, repoos.toml, .gitignore";
568
+ const proceed = await confirm(" Ready to " +
569
+ c.cyan("git init") +
570
+ c.dim(" and scaffold " + scaffoldFiles) +
571
+ " in " +
572
+ c.cyan(target), true);
573
+ if (!proceed) {
574
+ console.log(c.yellow("\n Cancelled — nothing was created."));
575
+ return;
576
+ }
577
+ const description = await ask(" Project description" +
578
+ c.dim(" — one line, gives the AI context to suggest next steps (optional, Enter to skip)") +
579
+ ": ");
580
+ if (!existsSync(target))
581
+ mkdirSync(target, { recursive: true });
582
+ // git health warnings — fail-soft, scaffold regardless
583
+ const gitOk = gitAvailable(target);
584
+ if (!gitOk) {
585
+ console.log(c.yellow("\n Warning: git doesn't appear to be installed — scaffolding without git."));
586
+ }
587
+ else if (!gitConfig(target, "user.name") && !gitConfig(target, "user.email")) {
588
+ console.log(c.yellow("\n Warning: no git identity is configured."));
589
+ console.log(c.dim(" git may auto-detect it, or the initial commit may fail. Set it with:"));
590
+ console.log(c.dim(' git config --global user.name "You" && git config --global user.email you@example.com'));
591
+ }
592
+ const { created, skipped } = scaffoldInto(target, description, layout);
593
+ reportInit(target, created, skipped);
594
+ if (!gitOk) {
595
+ console.log(c.dim(" To add git later: git init && git add -A && git commit"));
596
+ }
597
+ else if (gitInit(target)) {
598
+ console.log(" " + c.green("git init") + c.dim(" ok"));
599
+ }
600
+ else {
601
+ console.log(c.yellow(" Warning: git init failed — files left uncommitted."));
602
+ }
603
+ if (gitOk && (await confirm("\n Make an initial commit of the scaffold?", true))) {
604
+ const hash = gitCommitAll(target, INITIAL_COMMIT_MSG);
605
+ if (hash) {
606
+ console.log(" " + c.green("committed ") + c.dim(hash));
607
+ }
608
+ else {
609
+ console.log(c.yellow(" Warning: initial commit failed (unconfigured identity or a hook) — files left uncommitted."));
610
+ }
611
+ }
612
+ if (await confirm("\n Launch the RepoOS web console now to start building?", true)) {
613
+ const { port: preferred, explicit } = await askPort(deriveServePort(target));
614
+ let port = preferred;
615
+ if (preferred > 0) {
616
+ const free = await nextFreePort(preferred);
617
+ if (free !== preferred) {
618
+ console.log(c.yellow(` Port ${preferred} is in use — using ${free} instead.`));
619
+ port = free;
620
+ }
621
+ }
622
+ // Only pin an explicitly chosen port. The derived default is already stable
623
+ // per checkout, so writing it would just add noise to repoos.toml.
624
+ if (explicit)
625
+ persistServePort(target, preferred);
626
+ const dirHint = target === cwd ? null : `cd ${target}`;
627
+ if (target !== cwd)
628
+ process.chdir(target);
629
+ // A child process can change ITS OWN cwd (above) but never the parent
630
+ // shell's — the user's terminal is still sitting in `cwd`. Print the
631
+ // exact commands to run rather than just noting the mismatch, so there's
632
+ // nothing to figure out once this server is stopped.
633
+ if (dirHint) {
634
+ console.log(c.dim("\n Your shell is still in ") +
635
+ c.cyan(cwd) +
636
+ c.dim(". When you come back to this project, run:\n\n") +
637
+ " " +
638
+ c.cyan(dirHint) +
639
+ "\n " +
640
+ c.cyan("repoos serve") +
641
+ "\n");
642
+ }
643
+ console.log(c.dim(" Starting the RepoOS web console…"));
644
+ // Opening the browser is deferred to onReady — the server isn't actually
645
+ // listening until cmdServe's startServer() resolves, and opening a tab
646
+ // any earlier races that startup, showing connection errors until a
647
+ // manual reload.
648
+ await cmdServe(["--port", String(port)], {
649
+ onReady: (url) => openBrowser(url),
650
+ onShutdown: dirHint
651
+ ? () => console.log(c.dim(" Start it again with:\n\n ") +
652
+ c.cyan(dirHint) +
653
+ "\n " +
654
+ c.cyan("repoos serve") +
655
+ "\n")
656
+ : undefined,
657
+ });
658
+ return;
659
+ }
660
+ const dirHint = target === cwd ? "" : `cd ${target} · `;
661
+ console.log("\n Next: " +
662
+ c.cyan(dirHint + "repoos list") +
663
+ c.dim(" · ") +
664
+ c.cyan("repoos show 0001") +
665
+ c.dim(" · ") +
666
+ c.cyan('repoos new "My task"') +
667
+ c.dim(" · ") +
668
+ c.cyan("repoos serve") +
669
+ c.dim(" to open the web console") +
670
+ "\n");
671
+ }
672
+ export async function cmdInit(args) {
673
+ const cwd = process.cwd();
674
+ if (isGitRepo(cwd)) {
675
+ // existing-repo path — unchanged, idempotent, no prompts
676
+ const root = findRepoRoot(cwd);
677
+ const { created, skipped } = scaffoldInto(root, "", "root", "existing");
678
+ if (created.length === 0) {
679
+ warnAlreadySetUp(root, "Nothing to initialize here.");
680
+ for (const f of skipped)
681
+ console.log(" " + c.dim("exists " + f));
682
+ return;
683
+ }
684
+ reportInit(root, created, skipped);
685
+ return;
686
+ }
687
+ const alreadyHere = findRepoOSDir(cwd);
688
+ if (alreadyHere) {
689
+ warnAlreadySetUp(alreadyHere, "This directory isn't a git repo, but it sits inside an existing RepoOS setup.");
690
+ process.exitCode = 1;
691
+ return;
692
+ }
693
+ try {
694
+ await guidedNewRepo(args);
695
+ }
696
+ catch {
697
+ console.log(c.yellow("\n Cancelled."));
698
+ }
699
+ }