@repo-os/repoos 0.5.73 → 0.5.75

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 (295) hide show
  1. package/dist/.build-info.json +2 -2
  2. package/dist/.build-stamp.json +1 -1
  3. package/dist/cli/api-route-parity.js +7 -0
  4. package/dist/cli/help.js +4 -3
  5. package/dist/cli/repoos-api.d.ts +1 -0
  6. package/dist/cli/repoos-api.js +1 -0
  7. package/dist/commands/check.d.ts +2 -0
  8. package/dist/commands/check.js +50 -5
  9. package/dist/commands/checks.js +101 -24
  10. package/dist/commands/control-api.js +3 -3
  11. package/dist/commands/docs.js +2 -0
  12. package/dist/commands/gc.js +24 -26
  13. package/dist/commands/init.js +2 -2
  14. package/dist/commands/status.d.ts +32 -3
  15. package/dist/commands/status.js +59 -14
  16. package/dist/commands/tasks.d.ts +1 -1
  17. package/dist/commands/tasks.js +3 -3
  18. package/dist/commands/ui-smoke.js +8 -7
  19. package/dist/commands/upgrade.d.ts +1 -7
  20. package/dist/commands/upgrade.js +2 -19
  21. package/dist/core/active-task-card.d.ts +79 -0
  22. package/dist/core/active-task-card.js +172 -0
  23. package/dist/core/active-without-engineer-recovery.d.ts +34 -0
  24. package/dist/core/active-without-engineer-recovery.js +40 -0
  25. package/dist/core/agent-contract.js +2 -4
  26. package/dist/core/agent-run-tmpdir.d.ts +43 -0
  27. package/dist/core/agent-run-tmpdir.js +97 -0
  28. package/dist/core/attention.d.ts +2 -2
  29. package/dist/core/attention.js +2 -0
  30. package/dist/core/budget-runtime-state.d.ts +41 -0
  31. package/dist/core/budget-runtime-state.js +198 -0
  32. package/dist/core/check-results-store.d.ts +1 -0
  33. package/dist/core/check-results-store.js +1 -0
  34. package/dist/core/check-runner.d.ts +1 -0
  35. package/dist/core/check-runner.js +44 -37
  36. package/dist/core/check-store.d.ts +29 -1
  37. package/dist/core/check-store.js +167 -1
  38. package/dist/core/check-wait.d.ts +7 -4
  39. package/dist/core/check-wait.js +11 -8
  40. package/dist/core/config.js +82 -34
  41. package/dist/core/context-pack.js +2 -0
  42. package/dist/core/cross-process-slots.d.ts +3 -0
  43. package/dist/core/cross-process-slots.js +26 -5
  44. package/dist/core/done-task-cleanup.d.ts +6 -0
  45. package/dist/core/done-task-cleanup.js +53 -0
  46. package/dist/core/driver-brief.js +2 -0
  47. package/dist/core/engineer-crash-recovery.js +36 -2
  48. package/dist/core/engineer-slot.d.ts +15 -0
  49. package/dist/core/engineer-slot.js +21 -0
  50. package/dist/core/git-maintenance.d.ts +16 -1
  51. package/dist/core/git-maintenance.js +82 -1
  52. package/dist/core/git.d.ts +44 -2
  53. package/dist/core/git.js +334 -51
  54. package/dist/core/landable.d.ts +13 -5
  55. package/dist/core/landable.js +38 -5
  56. package/dist/core/launcher-runtime.d.ts +14 -0
  57. package/dist/core/launcher-runtime.js +129 -0
  58. package/dist/core/local-gates.js +5 -2
  59. package/dist/core/local-queue-marker.d.ts +4 -0
  60. package/dist/core/local-queue-marker.js +7 -0
  61. package/dist/core/needs-input.js +4 -2
  62. package/dist/core/process-group.d.ts +11 -0
  63. package/dist/core/process-group.js +39 -0
  64. package/dist/core/queued-message-recovery.d.ts +65 -0
  65. package/dist/core/queued-message-recovery.js +62 -0
  66. package/dist/core/repoos-toml-runtime-diff.d.ts +1 -0
  67. package/dist/core/repoos-toml-runtime-diff.js +70 -0
  68. package/dist/core/report-paths.d.ts +29 -0
  69. package/dist/core/report-paths.js +60 -0
  70. package/dist/core/review-findings.js +14 -2
  71. package/dist/core/review-passes.d.ts +24 -5
  72. package/dist/core/review-passes.js +74 -29
  73. package/dist/core/shot-fixtures.d.ts +1 -1
  74. package/dist/core/shot-fixtures.js +15 -0
  75. package/dist/core/task.d.ts +7 -0
  76. package/dist/core/task.js +18 -0
  77. package/dist/core/test-case-timings.d.ts +36 -0
  78. package/dist/core/test-case-timings.js +85 -0
  79. package/dist/core/types.d.ts +11 -0
  80. package/dist/core/watchdog-task-diff.d.ts +2 -0
  81. package/dist/core/watchdog-task-diff.js +113 -0
  82. package/dist/core/worktree-gc.d.ts +55 -13
  83. package/dist/core/worktree-gc.js +726 -94
  84. package/dist/server/__tests__/shot-capture-lock.test.d.ts +1 -0
  85. package/dist/server/__tests__/shot-capture-lock.test.js +18 -0
  86. package/dist/server/active-task-card.d.ts +24 -0
  87. package/dist/server/active-task-card.js +73 -0
  88. package/dist/server/active-without-engineer-recovery.d.ts +15 -0
  89. package/dist/server/active-without-engineer-recovery.js +148 -0
  90. package/dist/server/agents.d.ts +42 -1
  91. package/dist/server/agents.js +203 -27
  92. package/dist/server/attention-events.d.ts +1 -0
  93. package/dist/server/attention-events.js +9 -1
  94. package/dist/server/attention-notify.d.ts +2 -0
  95. package/dist/server/attention-notify.js +15 -0
  96. package/dist/server/auto-engineering.d.ts +2 -1
  97. package/dist/server/auto-engineering.js +13 -8
  98. package/dist/server/branchless-release.d.ts +14 -0
  99. package/dist/server/branchless-release.js +96 -24
  100. package/dist/server/built-in-agent-runner.js +2 -0
  101. package/dist/server/cto-monitor.js +4 -0
  102. package/dist/server/cto.d.ts +4 -3
  103. package/dist/server/cto.js +4 -3
  104. package/dist/server/debug-tldr.js +5 -2
  105. package/dist/server/done-hold-migration.d.ts +8 -0
  106. package/dist/server/done-hold-migration.js +69 -0
  107. package/dist/server/done.d.ts +1 -0
  108. package/dist/server/done.js +24 -3
  109. package/dist/server/engineer-crash-recovery.js +2 -11
  110. package/dist/server/engineer-launch.js +22 -0
  111. package/dist/server/engineering-reports.d.ts +70 -0
  112. package/dist/server/engineering-reports.js +239 -0
  113. package/dist/server/freeform-runs.d.ts +2 -1
  114. package/dist/server/freeform-runs.js +16 -2
  115. package/dist/server/git-worker.d.ts +2 -0
  116. package/dist/server/git-worker.js +14 -2
  117. package/dist/server/handoff.d.ts +10 -0
  118. package/dist/server/handoff.js +196 -8
  119. package/dist/server/integration-orchestrator.d.ts +18 -0
  120. package/dist/server/integration-orchestrator.js +139 -43
  121. package/dist/server/model-test.d.ts +3 -0
  122. package/dist/server/model-test.js +16 -1
  123. package/dist/server/provider-usage-limit-probe.js +6 -8
  124. package/dist/server/remote-validation.d.ts +17 -4
  125. package/dist/server/remote-validation.js +119 -27
  126. package/dist/server/report-layout-migration.d.ts +31 -0
  127. package/dist/server/report-layout-migration.js +182 -0
  128. package/dist/server/request-close-out.js +6 -3
  129. package/dist/server/review-automation.d.ts +1 -0
  130. package/dist/server/review-automation.js +3 -0
  131. package/dist/server/review-guard.js +4 -2
  132. package/dist/server/review-report-store.d.ts +23 -0
  133. package/dist/server/review-report-store.js +56 -0
  134. package/dist/server/review-tree-identity.js +49 -2
  135. package/dist/server/review.d.ts +63 -1
  136. package/dist/server/review.js +345 -104
  137. package/dist/server/routes/check-runs.d.ts +2 -0
  138. package/dist/server/routes/check-runs.js +40 -0
  139. package/dist/server/routes/config.js +16 -5
  140. package/dist/server/routes/dev.js +2 -0
  141. package/dist/server/routes/docs.js +3 -0
  142. package/dist/server/routes/inputs.js +5 -1
  143. package/dist/server/routes/models.js +5 -1
  144. package/dist/server/routes/playground.js +5 -1
  145. package/dist/server/routes/release.js +3 -0
  146. package/dist/server/routes/stories.d.ts +3 -0
  147. package/dist/server/routes/stories.js +40 -1
  148. package/dist/server/routes/support.js +6 -1
  149. package/dist/server/routes/tasks.d.ts +4 -0
  150. package/dist/server/routes/tasks.js +98 -8
  151. package/dist/server/server.js +222 -23
  152. package/dist/server/shot-capture.d.ts +2 -0
  153. package/dist/server/shot-capture.js +34 -1
  154. package/dist/server/skill-suggestions.js +2 -1
  155. package/dist/server/story-pm.js +15 -2
  156. package/dist/server/system.d.ts +79 -0
  157. package/dist/server/system.js +243 -1
  158. package/dist/server/task-check.d.ts +9 -0
  159. package/dist/server/task-check.js +24 -1
  160. package/dist/server/task-watchdog.d.ts +15 -9
  161. package/dist/server/task-watchdog.js +98 -35
  162. package/dist/server/ui-handoff-gate.js +10 -5
  163. package/dist/server/worktree-handoff-guard.js +7 -2
  164. package/dist/server/write.js +3 -13
  165. package/dist/ui/assets/ActivityIndicator-DsxETMHH.js +1 -0
  166. package/dist/ui/assets/AgentModelControl-BLHKdXCK.js +1 -0
  167. package/dist/ui/assets/AgentModelModal-DEAULUdA.js +1 -0
  168. package/dist/ui/assets/AgentsView-BWKykKEA.js +2 -0
  169. package/dist/ui/assets/AgentsView-DEIyf0uD.css +1 -0
  170. package/dist/ui/assets/{ChatAgentModelChip-DPHWICS-.js → ChatAgentModelChip-C1B23ArJ.js} +1 -1
  171. package/dist/ui/assets/ChecksView-CfIhwy6Z.css +1 -0
  172. package/dist/ui/assets/ChecksView-DaRwduJB.js +0 -0
  173. package/dist/ui/assets/ContextView-DQ6RW6w0.js +4 -0
  174. package/dist/ui/assets/DashboardView-B-7-dQLU.js +1 -0
  175. package/dist/ui/assets/{DashboardView-DJdeWV8s.css → DashboardView-jENeCIEX.css} +1 -1
  176. package/dist/ui/assets/DeleteConfirmDialog-CHkMTvmt.js +1 -0
  177. package/dist/ui/assets/DeploymentsView-DiB0gR1F.js +1 -0
  178. package/dist/ui/assets/{DevView-CwWIgB5t.js → DevView-B-32GGYO.js} +2 -2
  179. package/dist/ui/assets/{DiffView-DPlMpZwl.js → DiffView-DOftUGZx.js} +1 -1
  180. package/dist/ui/assets/FailedTestsList-C_9Floyr.js +1 -0
  181. package/dist/ui/assets/InputsView-D4WtnYSg.js +1 -0
  182. package/dist/ui/assets/LoginView-CcDGWaF3.js +1 -0
  183. package/dist/ui/assets/PageSkeleton-CsTdMpw3.css +1 -0
  184. package/dist/ui/assets/PageSkeleton-DRgDMfth.js +1 -0
  185. package/dist/ui/assets/{ReleasesView-B9Ao5H9s.js → ReleasesView-Sxyylk3a.js} +1 -1
  186. package/dist/ui/assets/SecretsView-C99csAEO.js +1 -0
  187. package/dist/ui/assets/SettingsView-T6midXQa.js +4 -0
  188. package/dist/ui/assets/StoriesView-CpLqmKTx.js +1 -0
  189. package/dist/ui/assets/{VoiceDictate-BIXyHCYF.js → VoiceDictate-D97LIVNB.js} +1 -1
  190. package/dist/ui/assets/WorkView-C9Fd-nys.js +2 -0
  191. package/dist/ui/assets/WorkView-couHda3J.css +1 -0
  192. package/dist/ui/assets/{abnfDiagram-VCTEODGH-D6t2YdDd.js → abnfDiagram-VCTEODGH-B0BRuj2x.js} +1 -1
  193. package/dist/ui/assets/{architectureDiagram-5GKGNRK7-DfvZY3qH.js → architectureDiagram-5GKGNRK7-ZfY0-Gdw.js} +1 -1
  194. package/dist/ui/assets/{blockDiagram-I7D4REHJ-p9SaIkVm.js → blockDiagram-I7D4REHJ-C-J_DWun.js} +1 -1
  195. package/dist/ui/assets/{c4Diagram-7LVT6UL2-BL-ftUgy.js → c4Diagram-7LVT6UL2-bQf4xDX5.js} +1 -1
  196. package/dist/ui/assets/channel-6uQ09cde.js +1 -0
  197. package/dist/ui/assets/check-progress-p3dLHxxW.js +2 -0
  198. package/dist/ui/assets/{chunk-2E4U76K2-V3UlY0fF.js → chunk-2E4U76K2-DLFOie7L.js} +1 -1
  199. package/dist/ui/assets/{chunk-4HAMMTFA-CMXUfdBr.js → chunk-4HAMMTFA-BPDy0z56.js} +1 -1
  200. package/dist/ui/assets/{chunk-75Z2AOVW-BVgiO27L.js → chunk-75Z2AOVW-CGe3rSHt.js} +1 -1
  201. package/dist/ui/assets/{chunk-CLGD4ZFX-CRaWjb_k.js → chunk-CLGD4ZFX-Cc3Z-MGq.js} +1 -1
  202. package/dist/ui/assets/{chunk-DU6HZSFF-DoybIPWm.js → chunk-DU6HZSFF-DoNdcPzn.js} +1 -1
  203. package/dist/ui/assets/{chunk-F27PBJKO-N6cLLABx.js → chunk-F27PBJKO-0W-eFq3z.js} +1 -1
  204. package/dist/ui/assets/{chunk-GMAD6QVW-iqG0Mryo.js → chunk-GMAD6QVW-DIa91igC.js} +1 -1
  205. package/dist/ui/assets/{chunk-GVQU2GXP-f8esshKW.js → chunk-GVQU2GXP-B9kO2TNG.js} +1 -1
  206. package/dist/ui/assets/{chunk-IMKFNOWR-DRyUVZ8K.js → chunk-IMKFNOWR-BVh_kn6v.js} +1 -1
  207. package/dist/ui/assets/{chunk-L3NEJ4N5-MIVQTWm1.js → chunk-L3NEJ4N5-BIAmP_VV.js} +1 -1
  208. package/dist/ui/assets/{chunk-OSK3NFVY-BCHyxVoP.js → chunk-OSK3NFVY-JwMwYbXa.js} +1 -1
  209. package/dist/ui/assets/{chunk-P2QGCYS3-ChYZkZI_.js → chunk-P2QGCYS3-jcoeuQEp.js} +1 -1
  210. package/dist/ui/assets/{chunk-POPQ4Y6H-TgXMUskQ.js → chunk-POPQ4Y6H-DIWunY1p.js} +1 -1
  211. package/dist/ui/assets/{chunk-PWAF6VOD-qsH24WJM.js → chunk-PWAF6VOD-DK7-N58B.js} +1 -1
  212. package/dist/ui/assets/{chunk-SHT3W25Y-BQu5f8tz.js → chunk-SHT3W25Y-CcbXenLZ.js} +1 -1
  213. package/dist/ui/assets/{chunk-SVP7TREG-CvmZPDcQ.js → chunk-SVP7TREG-CU8QcmKz.js} +1 -1
  214. package/dist/ui/assets/{chunk-TICWLB2K-DPOtzVuP.js → chunk-TICWLB2K-C2dfqOZm.js} +1 -1
  215. package/dist/ui/assets/chunk-TLUHSLCS-D-41MDHJ.js +2 -0
  216. package/dist/ui/assets/classDiagram-ZZMXUADV-CG7r0YBU.js +1 -0
  217. package/dist/ui/assets/classDiagram-v2-VYDZK3BY-CG7r0YBU.js +1 -0
  218. package/dist/ui/assets/{cynefinDiagram-5FMLGOSQ-BMMxTCVH.js → cynefinDiagram-5FMLGOSQ-OgOMfJ2M.js} +1 -1
  219. package/dist/ui/assets/{dagre-GXQ25YYZ-mdcBXgnq.js → dagre-GXQ25YYZ-DbmwwCwb.js} +1 -1
  220. package/dist/ui/assets/{diagram-S7CK7UJ4-BYHQN-__.js → diagram-S7CK7UJ4-fSJUV0Sv.js} +1 -1
  221. package/dist/ui/assets/{diagram-UQ7AKVKN-du5xkY-t.js → diagram-UQ7AKVKN-CPLv2elu.js} +1 -1
  222. package/dist/ui/assets/{diagram-VSXAHHWV-CDljZt2c.js → diagram-VSXAHHWV-CsOV5L3Y.js} +1 -1
  223. package/dist/ui/assets/{diagram-VX7I27RA-66z56eI2.js → diagram-VX7I27RA-C6eTl1uM.js} +1 -1
  224. package/dist/ui/assets/{diagram-Z3DM3KII-DDSrtck7.js → diagram-Z3DM3KII-B4UZmomc.js} +1 -1
  225. package/dist/ui/assets/docs-ZCGAA3kV.js +1 -0
  226. package/dist/ui/assets/{ebnfDiagram-PWID7BFC-DQDNc_-9.js → ebnfDiagram-PWID7BFC-CSTTfh_S.js} +1 -1
  227. package/dist/ui/assets/{erDiagram-RLTQ6QDP-CAWU1WaF.js → erDiagram-RLTQ6QDP-BYT61Y7Q.js} +1 -1
  228. package/dist/ui/assets/flowDiagram-HODETNUW-DzLUu-VJ.js +1 -0
  229. package/dist/ui/assets/{ganttDiagram-EL5Y4UJY-C6V1kaYI.js → ganttDiagram-EL5Y4UJY-DKTisdub.js} +1 -1
  230. package/dist/ui/assets/{gitGraphDiagram-WWUBYQGX-BGygR4v-.js → gitGraphDiagram-WWUBYQGX-ZkPvOAfk.js} +1 -1
  231. package/dist/ui/assets/index-BUmR8syJ.css +1 -0
  232. package/dist/ui/assets/index-hshjr8FP.js +68 -0
  233. package/dist/ui/assets/{infoDiagram-27XIBGKW-DZILjOjA.js → infoDiagram-27XIBGKW-Ck98QGBN.js} +1 -1
  234. package/dist/ui/assets/{ishikawaDiagram-5VMMS53U-B2cFxmGF.js → ishikawaDiagram-5VMMS53U-CqwQ5qZ8.js} +1 -1
  235. package/dist/ui/assets/{journeyDiagram-3NMN7TZE-C5Sb8YTl.js → journeyDiagram-3NMN7TZE-C1UQN2RN.js} +1 -1
  236. package/dist/ui/assets/{kanban-definition-UXKFOSKX-CV3Osxtb.js → kanban-definition-UXKFOSKX-9zw0uM6N.js} +1 -1
  237. package/dist/ui/assets/{line-BxE-EqfN.js → line-CeMjuG_7.js} +1 -1
  238. package/dist/ui/assets/{mermaid-parser.core-CQ4lbIXW.js → mermaid-parser.core-Bosog0P9.js} +1 -1
  239. package/dist/ui/assets/mermaid.core-CJqh-dHb.js +11 -0
  240. package/dist/ui/assets/{mindmap-definition-YA3MSWOX-Cpi-IHX6.js → mindmap-definition-YA3MSWOX-Da8qCo0o.js} +1 -1
  241. package/dist/ui/assets/{pegDiagram-XKGWAZYB-DMcJVhJW.js → pegDiagram-XKGWAZYB-DELDftZr.js} +1 -1
  242. package/dist/ui/assets/{pieDiagram-E7YTZNPT-CdXUU05z.js → pieDiagram-E7YTZNPT-Da3NN6-R.js} +1 -1
  243. package/dist/ui/assets/{quadrantDiagram-AXDQQJYC-B2_Z5M8E.js → quadrantDiagram-AXDQQJYC-B51kliky.js} +1 -1
  244. package/dist/ui/assets/{railroadDiagram-O6MQD6OU-u4uj57HH.js → railroadDiagram-O6MQD6OU-BgsVU5EU.js} +1 -1
  245. package/dist/ui/assets/repo-PZFVwA66.js +54 -0
  246. package/dist/ui/assets/{requirementDiagram-BXWQKSXE-B4keHdJD.js → requirementDiagram-BXWQKSXE-D1AT3iV0.js} +1 -1
  247. package/dist/ui/assets/{sankeyDiagram-P5KCCOFB-dZdIPYfI.js → sankeyDiagram-P5KCCOFB-BDK2LYvj.js} +1 -1
  248. package/dist/ui/assets/{sequenceDiagram-WJ2MYXX4-kBAuNmyS.js → sequenceDiagram-WJ2MYXX4-CNiCcLn-.js} +1 -1
  249. package/dist/ui/assets/{stateDiagram-D77RDMKH-D83tShBX.js → stateDiagram-D77RDMKH-Cf-064cv.js} +1 -1
  250. package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-CrFLdWWs.js +1 -0
  251. package/dist/ui/assets/{swimlanes-42K2YHIH-DRDo7aP4.js → swimlanes-42K2YHIH-D-tbu4wq.js} +1 -1
  252. package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-D6iLKbDv.js +8 -0
  253. package/dist/ui/assets/{timeline-definition-24CTP7MA-mnm_omtS.js → timeline-definition-24CTP7MA-DRufowda.js} +1 -1
  254. package/dist/ui/assets/{vennDiagram-4TSXK5OY-Djq6ULjF.js → vennDiagram-4TSXK5OY-D1vf8POQ.js} +1 -1
  255. package/dist/ui/assets/{wardleyDiagram-VM6X3IG4-GfB-sti2.js → wardleyDiagram-VM6X3IG4-B4fB0w_8.js} +1 -1
  256. package/dist/ui/assets/{xychartDiagram-S5SC5T6Z-DRh9G9Zb.js → xychartDiagram-S5SC5T6Z-CpSh2ftP.js} +1 -1
  257. package/dist/ui/index.html +12 -14
  258. package/dist/ui/sw.js +2 -2
  259. package/package.json +1 -1
  260. package/dist/ui/assets/ActivityIndicator-CFysp8fx.js +0 -1
  261. package/dist/ui/assets/AgentModelControl-iHOGbgue.js +0 -1
  262. package/dist/ui/assets/AgentModelModal-Cifx9MEF.js +0 -1
  263. package/dist/ui/assets/AgentsView-DoAgVcFi.js +0 -2
  264. package/dist/ui/assets/AgentsView-SbjUmYp0.css +0 -1
  265. package/dist/ui/assets/ChecksView-DVFC0J4t.css +0 -1
  266. package/dist/ui/assets/ChecksView-DaLrQ8xf.js +0 -0
  267. package/dist/ui/assets/ContextView-Btiqouai.js +0 -4
  268. package/dist/ui/assets/DashboardView-BzKRZk7c.js +0 -1
  269. package/dist/ui/assets/DeleteConfirmDialog-Cy8bXm1R.js +0 -1
  270. package/dist/ui/assets/DependencyChip-BZQN-6jN.js +0 -1
  271. package/dist/ui/assets/DeploymentsView-CyiTsye9.js +0 -1
  272. package/dist/ui/assets/FailedTestsList-DKSLDbG6.js +0 -1
  273. package/dist/ui/assets/InputsView-BZzEXRPF.js +0 -1
  274. package/dist/ui/assets/LoginView-Bww-iSWH.js +0 -1
  275. package/dist/ui/assets/PageSkeleton-2lGeBsoi.css +0 -1
  276. package/dist/ui/assets/PageSkeleton-D7fVi3NJ.js +0 -1
  277. package/dist/ui/assets/SecretsView-BSEb1LP0.js +0 -1
  278. package/dist/ui/assets/SettingsView-DE5rdOwQ.js +0 -4
  279. package/dist/ui/assets/StoriesView-CzcU-EES.js +0 -1
  280. package/dist/ui/assets/WorkView-B1JytTp3.css +0 -1
  281. package/dist/ui/assets/WorkView-DxNhKHZ0.js +0 -2
  282. package/dist/ui/assets/channel-BV21EJtW.js +0 -1
  283. package/dist/ui/assets/check-setup-DQZqfS14.js +0 -2
  284. package/dist/ui/assets/chunk-TLUHSLCS-D30OEKwA.js +0 -2
  285. package/dist/ui/assets/classDiagram-ZZMXUADV-DqgLJsDt.js +0 -1
  286. package/dist/ui/assets/classDiagram-v2-VYDZK3BY-DqgLJsDt.js +0 -1
  287. package/dist/ui/assets/docs-8_CFug_V.js +0 -1
  288. package/dist/ui/assets/flowDiagram-HODETNUW-tMrL1QbJ.js +0 -1
  289. package/dist/ui/assets/index-BEQoXI01.css +0 -1
  290. package/dist/ui/assets/index-ib5yOjK6.js +0 -68
  291. package/dist/ui/assets/mermaid.core-Do6AR5iD.js +0 -11
  292. package/dist/ui/assets/repo-CPSBfMRE.js +0 -40
  293. package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-CNtNh1Ls.js +0 -1
  294. package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-CGtDYnNu.js +0 -8
  295. package/dist/ui/assets/ui-ClI5E21n.js +0 -7
@@ -1,5 +1,5 @@
1
1
  {
2
- "hash": "54182298d418b9bcc12c138af5d99c0470fb3a54a8a573775e600c2e37ab1669",
3
- "version": "0.5.73",
2
+ "hash": "bd7090b8a9f41e6d39058987c990b663fd2d8e51ec58782d6dafbb41fd7e540a",
3
+ "version": "0.5.75",
4
4
  "devUi": false
5
5
  }
@@ -1,3 +1,3 @@
1
1
  {
2
- "generatedAt": "2026-10-29T21:23:55.474Z"
2
+ "generatedAt": "2026-11-04T03:49:23.103Z"
3
3
  }
@@ -73,6 +73,11 @@ const FILE_CLI_MATCHERS = [
73
73
  ];
74
74
  /** UI-only, SSE/hub, auth, or internal routes — no CLI required. */
75
75
  const UI_ONLY_MATCHERS = [
76
+ // Task-card-only explicit cancellation of a stalled, registered local check.
77
+ re("POST", /^\/api\/tasks\/([^/]+)\/cancel-check$/.source),
78
+ // Read-only task engineering-report history used by the Dev tab.
79
+ re("GET", /^\/api\/tasks\/([^/]+)\/engineering-reports$/.source),
80
+ re("GET", /^\/api\/tasks\/([^/]+)\/engineering-reports\/([^/]+)$/.source),
76
81
  under("/api/auth/"),
77
82
  under("/api/hub/"),
78
83
  under("/api/telegram/"),
@@ -111,6 +116,7 @@ const UI_ONLY_MATCHERS = [
111
116
  exact("GET", "/api/attention"),
112
117
  exact("GET", "/api/decisions"),
113
118
  exact("GET", "/api/check-runs"),
119
+ exact("GET", "/api/check-run-test-cases"),
114
120
  exact("GET", "/api/local-check-slots"),
115
121
  re("POST", /^\/api\/local-check-slots\/(\d+)\/release\/(\d+)$/.source),
116
122
  exact("GET", "/api/resource-queues"),
@@ -118,6 +124,7 @@ const UI_ONLY_MATCHERS = [
118
124
  re("GET", /^\/api\/tasks\/([^/]+)\/integration-job$/.source),
119
125
  re("POST", /^\/api\/tasks\/([^/]+)\/worktree-handoff\/discard$/.source),
120
126
  re("GET", /^\/api\/tasks\/([^/]+)\/review$/.source),
127
+ re("GET", /^\/api\/tasks\/([^/]+)\/review\/passes\/([^/]+)$/.source),
121
128
  re("POST", /^\/api\/tasks\/([^/]+)\/review\/message$/.source),
122
129
  re("POST", /^\/api\/tasks\/([^/]+)\/pm\/message$/.source),
123
130
  re("POST", /^\/api\/tasks\/([^/]+)\/pm\/interrupt$/.source),
package/dist/cli/help.js CHANGED
@@ -157,7 +157,7 @@ const GROUPS = [
157
157
  {
158
158
  name: "landable",
159
159
  usage: "landable <id> [--json] [--port N]",
160
- desc: "Read-only landing pre-checks (verdict, lock, worktree, merge, scope, main) — exits non-zero when not landable (GET /api/tasks/:id/landable)",
160
+ desc: "Read-only checks before merging (verdict, lock, worktree, merge, scope, main) — exits non-zero when the task is not ready to merge (GET /api/tasks/:id/landable)",
161
161
  flags: "--json · --port",
162
162
  },
163
163
  {
@@ -304,8 +304,9 @@ const GROUPS = [
304
304
  },
305
305
  {
306
306
  name: "checks timings",
307
- usage: "checks timings",
308
- desc: "Show recent check durations and the slowest test files",
307
+ usage: "checks timings [--tests] [--run-id ID] [--recent-runs N] [--limit N] [--offset N] [--json]",
308
+ desc: "Recent check durations, slowest test files, and slow individual test cases",
309
+ flags: "--tests · --run-id ID · --recent-runs N · --limit N · --offset N · --json",
309
310
  },
310
311
  {
311
312
  name: "checks slots",
@@ -43,6 +43,7 @@ export declare class RepoOsApi {
43
43
  fetchEventStream(): Promise<Response>;
44
44
  request(method: string, path: string, body?: unknown, opts?: {
45
45
  retryAuth?: boolean;
46
+ timeoutMs?: number;
46
47
  }): Promise<{
47
48
  status: number;
48
49
  body: ApiJson;
@@ -127,6 +127,7 @@ export class RepoOsApi {
127
127
  method,
128
128
  headers: this.buildHeaders(jsonBody),
129
129
  body: jsonBody ? JSON.stringify(body) : undefined,
130
+ signal: opts.timeoutMs && opts.timeoutMs > 0 ? AbortSignal.timeout(opts.timeoutMs) : undefined,
130
131
  });
131
132
  }
132
133
  catch (err) {
@@ -1,4 +1,5 @@
1
1
  import { type TestFileTiming } from "../core/test-file-timings.js";
2
+ import { type TestCaseTiming } from "../core/test-case-timings.js";
2
3
  import type { CheckContrastPair, CheckThemeScope, RepoOSConfig } from "../core/types.js";
3
4
  import { type CheckPlan, type CheckStep } from "../core/check-plan.js";
4
5
  import { type StepRunResult, type StepStatus } from "../core/check-runner.js";
@@ -275,6 +276,7 @@ interface StepContext {
275
276
  /** What a built-in `kind` handler returns. */
276
277
  interface BuiltinOutcome {
277
278
  testFileTimings?: TestFileTiming[];
279
+ testCaseTimings?: TestCaseTiming[];
278
280
  status: StepStatus;
279
281
  /** The command it resolved to (so the results block can name it). */
280
282
  command?: string;
@@ -33,6 +33,7 @@ import { cpus, totalmem } from "node:os";
33
33
  import { isAbsolute, join, relative, sep } from "node:path";
34
34
  import { c } from "../cli/colors.js";
35
35
  import { TestFileTimingCollector, testFileTimings, formatSlowestTestFiles, } from "../core/test-file-timings.js";
36
+ import { TestCaseTimingCollector, formatSlowestTestCases, mergeTestCaseTimings, pushTimingOutputChunk, } from "../core/test-case-timings.js";
36
37
  import { checkBuildForRoot } from "../core/build.js";
37
38
  import { findRepoRoot, loadConfig } from "../core/config.js";
38
39
  import { availableMemBytes } from "../core/sysmem.js";
@@ -1403,6 +1404,10 @@ async function stepTests(ctx) {
1403
1404
  : "skipped — test suite ran on the remote validation runner (REPOOS_SKIP_TESTS=1)");
1404
1405
  }
1405
1406
  const fileTimingCollector = new TestFileTimingCollector();
1407
+ const caseTimingCollector = new TestCaseTimingCollector();
1408
+ const onTimingChunk = (chunk) => {
1409
+ pushTimingOutputChunk(chunk, fileTimingCollector, caseTimingCollector);
1410
+ };
1406
1411
  const hasTestScript = Boolean(ctx.scriptPkg.scripts?.test);
1407
1412
  const hasTestFiles = ["test", "__tests__", "tests"].some((d) => existsSync(join(ctx.cwd, d)));
1408
1413
  if (!hasTestScript && !hasTestFiles)
@@ -1441,7 +1446,7 @@ async function stepTests(ctx) {
1441
1446
  console.log(c.dim(` · previously-failed test file(s) first · ${priorFiles.join(", ")}`));
1442
1447
  const pre = await runCommand({
1443
1448
  command: preflight,
1444
- onChunk: (chunk) => fileTimingCollector.push(chunk),
1449
+ onChunk: onTimingChunk,
1445
1450
  cwd: ctx.cwd,
1446
1451
  timeoutMs: 300_000,
1447
1452
  env,
@@ -1455,6 +1460,7 @@ async function stepTests(ctx) {
1455
1460
  status: pre.status === "timeout" ? "timeout" : "failed",
1456
1461
  command: preflight,
1457
1462
  testFileTimings: fileTimingCollector.values(),
1463
+ testCaseTimings: caseTimingCollector.values(),
1458
1464
  detail: `previously-failed test file(s) still fail — ${why}`,
1459
1465
  output: pre.output,
1460
1466
  };
@@ -1478,13 +1484,14 @@ async function stepTests(ctx) {
1478
1484
  timeoutMs,
1479
1485
  env,
1480
1486
  echo: ctx.echo,
1481
- onChunk: (chunk) => fileTimingCollector.push(chunk),
1487
+ onChunk: onTimingChunk,
1482
1488
  });
1483
1489
  if (res.status === "passed") {
1484
1490
  return {
1485
1491
  status: "passed",
1486
1492
  command,
1487
1493
  testFileTimings: fileTimingCollector.values(),
1494
+ testCaseTimings: caseTimingCollector.values(),
1488
1495
  detail: changedRef ? `scoped to changed vs ${changedRef} plus always-run suites` : undefined,
1489
1496
  output: res.output,
1490
1497
  };
@@ -1493,6 +1500,7 @@ async function stepTests(ctx) {
1493
1500
  return {
1494
1501
  status: "timeout",
1495
1502
  testFileTimings: fileTimingCollector.values(),
1503
+ testCaseTimings: caseTimingCollector.values(),
1496
1504
  command,
1497
1505
  detail: `timed out after ${timeoutLabel(timeoutMs)}`,
1498
1506
  output: res.output,
@@ -1504,6 +1512,7 @@ async function stepTests(ctx) {
1504
1512
  return {
1505
1513
  status: "failed",
1506
1514
  testFileTimings: fileTimingCollector.values(),
1515
+ testCaseTimings: caseTimingCollector.values(),
1507
1516
  command,
1508
1517
  detail: outputTail(res.output) ?? `Tests failed (exit ${res.exitCode})`,
1509
1518
  output: res.output,
@@ -1822,6 +1831,7 @@ export async function runCheckPlan(plan, opts) {
1822
1831
  required: step.required,
1823
1832
  isolationNote: outcome.isolationNote,
1824
1833
  testFileTimings: outcome.testFileTimings,
1834
+ testCaseTimings: outcome.testCaseTimings,
1825
1835
  });
1826
1836
  }
1827
1837
  return results;
@@ -2142,12 +2152,27 @@ export async function cmdCheck(argv = []) {
2142
2152
  console.log(c.red(`\n ✗ ${msg}\n`));
2143
2153
  const holders = inspectCrossProcessSlots(localCheckLockRoot(repoRoot, cfg.cacheDir ?? ".repoos"));
2144
2154
  for (const holder of holders) {
2145
- console.log(c.dim(` slot ${holder.slot}: pid ${holder.pid ?? "unknown"}, ${Math.round(holder.ageMs / 1000)}s${holder.dead ? " (dead; reclaiming)" : holder.wedged ? " (possibly wedged)" : ""}`));
2155
+ console.log(c.dim(` slot ${holder.slot}: pid ${holder.pid ?? "unknown"}, ${Math.round(holder.ageMs / 1000)}s${holder.dead ? " (process exited; reclaiming)" : holder.wedged ? ` (no recent heartbeat; last seen ${Math.round(holder.heartbeatAgeMs / 1000)}s ago)` : ""}`));
2146
2156
  }
2147
2157
  process.exit(1);
2148
2158
  }
2149
2159
  waitRecord = waits.finish();
2150
2160
  const runStartedAt = new Date();
2161
+ // Persist a provisional row before running steps. If this process is killed,
2162
+ // the durable history still shows an interrupted run instead of no run.
2163
+ const historyRunId = recordRunHistoryRow({
2164
+ root: checkStoreRoot,
2165
+ cacheDir: cfg.cacheDir,
2166
+ attribution: runContext,
2167
+ scope: changedRef ? `changed:${changedRef}` : "full",
2168
+ worktree: repoRoot,
2169
+ startedAt: runStartedAt.toISOString(),
2170
+ durationMs: 0,
2171
+ outcome: "cancelled",
2172
+ failedStep: "check",
2173
+ skippedSteps: [],
2174
+ detail: "Check was interrupted before completion.",
2175
+ });
2151
2176
  // Failed-first ordering (#0655): only interactive/CLI and pre-review runs
2152
2177
  // reorder. Close-out and release run their selected suite from a clean
2153
2178
  // slate, and the remote close-out gate never reaches this point. Attribution
@@ -2231,6 +2256,7 @@ export async function cmdCheck(argv = []) {
2231
2256
  skippedSteps: [],
2232
2257
  steps: completedSteps,
2233
2258
  detail: `check crashed before completing: ${e.message}`,
2259
+ updateId: historyRunId,
2234
2260
  });
2235
2261
  throw e;
2236
2262
  }
@@ -2290,9 +2316,17 @@ export async function cmdCheck(argv = []) {
2290
2316
  }
2291
2317
  }
2292
2318
  const fileTimings = results.flatMap((r) => r.testFileTimings ?? testFileTimings(r.output ?? ""));
2319
+ // Individual case history comes only from Vitest's structured reporter
2320
+ // events. Step output is intentionally bounded and must never be its source.
2321
+ const caseTimings = mergeTestCaseTimings(results.flatMap((r) => r.testCaseTimings ?? []));
2293
2322
  if (fileTimings.length) {
2294
2323
  heading("Slowest test files");
2295
2324
  console.log(formatSlowestTestFiles(fileTimings));
2325
+ console.log(c.dim(" File totals include hook time in that file; they are not the sum of individual cases below."));
2326
+ }
2327
+ if (caseTimings.length) {
2328
+ heading("Slowest test cases");
2329
+ console.log(formatSlowestTestCases(caseTimings));
2296
2330
  }
2297
2331
  // Persist the run for the Checks surface (#0447) before exiting. Fail-soft:
2298
2332
  // visibility only, never a reason to fail an otherwise-green gate.
@@ -2352,6 +2386,7 @@ export async function cmdCheck(argv = []) {
2352
2386
  durationMs: r.durationMs,
2353
2387
  output: r.output,
2354
2388
  testFileTimings: r.testFileTimings,
2389
+ testCaseTimings: r.testCaseTimings,
2355
2390
  detail: r.detail,
2356
2391
  required: r.required,
2357
2392
  })),
@@ -2377,6 +2412,7 @@ export async function cmdCheck(argv = []) {
2377
2412
  stepsDone: finalProgress?.stepsDone ?? null,
2378
2413
  stepsTotal: finalProgress?.stepsTotal ?? null,
2379
2414
  testFileTimings: fileTimings,
2415
+ testCaseTimings: caseTimings,
2380
2416
  testsDone: testProgress?.testsDone ?? null,
2381
2417
  testsTotal: testProgress?.testsTotal ?? null,
2382
2418
  detail: (() => {
@@ -2403,6 +2439,7 @@ export async function cmdCheck(argv = []) {
2403
2439
  failedTests: gatingFailures.flatMap((r) => extractFailedTests(r.output ?? "")),
2404
2440
  // Informational isolation label (#0655) — never part of the outcome.
2405
2441
  isolationNote: results.find((r) => r.isolationNote)?.isolationNote ?? null,
2442
+ updateId: historyRunId,
2406
2443
  });
2407
2444
  process.exit(gatingFailures.length > 0 ? 1 : 0);
2408
2445
  }
@@ -2438,7 +2475,8 @@ export function previousFailedTestsForRun(opts) {
2438
2475
  function recordRunHistoryRow(row) {
2439
2476
  try {
2440
2477
  const { taskId, phase } = row.attribution;
2441
- getCheckStore(row.root, row.cacheDir).record({
2478
+ const store = getCheckStore(row.root, row.cacheDir);
2479
+ const input = {
2442
2480
  taskId,
2443
2481
  phase,
2444
2482
  worktree: row.worktree,
@@ -2463,10 +2501,17 @@ function recordRunHistoryRow(row) {
2463
2501
  testsTotal: row.testsTotal,
2464
2502
  steps: row.steps,
2465
2503
  testFileTimings: row.testFileTimings,
2466
- });
2504
+ testCaseTimings: row.testCaseTimings,
2505
+ };
2506
+ if (row.updateId != null) {
2507
+ store.update(row.updateId, input);
2508
+ return row.updateId;
2509
+ }
2510
+ return store.record(input);
2467
2511
  }
2468
2512
  catch {
2469
2513
  /* never fail the gate on a history write */
2514
+ return null;
2470
2515
  }
2471
2516
  }
2472
2517
  /**
@@ -1,32 +1,110 @@
1
- import { getCheckStore } from "../core/check-store.js";
1
+ import { DEFAULT_TEST_CASE_LIST_LIMIT, getCheckStore, MAX_TEST_CASE_LIST_LIMIT, } from "../core/check-store.js";
2
2
  import { formatSlowestTestFiles } from "../core/test-file-timings.js";
3
+ import { formatSlowestTestCases } from "../core/test-case-timings.js";
3
4
  import { c } from "../cli/colors.js";
4
5
  import { loadConfig } from "../core/config.js";
5
- import { inspectCrossProcessSlots, localCheckLockRoot, releaseLocalCheckSlot, } from "../core/cross-process-slots.js";
6
- import { readQueueMarkers } from "../core/local-queue-marker.js";
6
+ import { inspectCrossProcessSlots, listSlotWaiterPids, localCheckLockRoot, releaseLocalCheckSlot, } from "../core/cross-process-slots.js";
7
+ import { currentQueueMarkers, readQueueMarkers } from "../core/local-queue-marker.js";
7
8
  import { mainCheckoutRoot } from "../core/git.js";
8
9
  import { heavySlotLimit } from "../core/resource-limits.js";
9
- export function cmdChecks(args) {
10
- if (args[0] === "timings") {
11
- const config = loadConfig();
12
- let root = config.root;
13
- try {
14
- root = mainCheckoutRoot(root);
10
+ function resolveChecksRoot() {
11
+ const config = loadConfig();
12
+ try {
13
+ return mainCheckoutRoot(config.root);
14
+ }
15
+ catch {
16
+ return config.root;
17
+ }
18
+ }
19
+ function parseTimingsFlags(args) {
20
+ let json = false;
21
+ let tests = false;
22
+ let runId;
23
+ let recentRuns = 10;
24
+ let limit = DEFAULT_TEST_CASE_LIST_LIMIT;
25
+ let offset = 0;
26
+ for (let i = 0; i < args.length; i++) {
27
+ const a = args[i];
28
+ if (a === "--json")
29
+ json = true;
30
+ else if (a === "--tests" || a === "tests")
31
+ tests = true;
32
+ else if (a === "--run-id" || a === "--run") {
33
+ const n = Number(args[++i]);
34
+ if (Number.isFinite(n) && n > 0)
35
+ runId = Math.floor(n);
36
+ }
37
+ else if (a === "--recent-runs" || a === "--recent") {
38
+ const n = Number(args[++i]);
39
+ if (Number.isFinite(n) && n > 0)
40
+ recentRuns = Math.min(100, Math.floor(n));
41
+ }
42
+ else if (a === "--limit") {
43
+ const n = Number(args[++i]);
44
+ if (Number.isFinite(n) && n > 0)
45
+ limit = Math.min(MAX_TEST_CASE_LIST_LIMIT, Math.floor(n));
46
+ }
47
+ else if (a === "--offset") {
48
+ const n = Number(args[++i]);
49
+ if (Number.isFinite(n) && n >= 0)
50
+ offset = Math.floor(n);
51
+ }
52
+ }
53
+ return { json, tests, runId, recentRuns, limit, offset };
54
+ }
55
+ function cmdChecksTimings(args) {
56
+ const config = loadConfig();
57
+ const root = resolveChecksRoot();
58
+ const flags = parseTimingsFlags(args);
59
+ const store = getCheckStore(root, config.cacheDir);
60
+ if (flags.tests) {
61
+ const result = store.listSlowTestCases({
62
+ runId: flags.runId,
63
+ recentRuns: flags.recentRuns,
64
+ limit: flags.limit,
65
+ offset: flags.offset,
66
+ });
67
+ if (flags.json) {
68
+ console.log(JSON.stringify({ ok: true, ...result }, null, 0));
69
+ return;
15
70
  }
16
- catch {
17
- /* standalone */
71
+ const scope = flags.runId != null
72
+ ? `run #${flags.runId}`
73
+ : `last ${result.recentRuns ?? flags.recentRuns} run(s)`;
74
+ console.log(`Slowest test cases (including beforeEach/afterEach hooks) · ${scope} · limit ${result.limit} offset ${result.offset}`);
75
+ if (!result.cases.length) {
76
+ console.log(" (no recorded cases — run repoos check after upgrading)");
77
+ return;
18
78
  }
19
- for (const run of getCheckStore(root, config.cacheDir).list({ limit: 10 })) {
20
- console.log(`${run.startedAt} · ${run.phase} · ${run.machine ?? "local"} · ${run.scope} · ${((run.durationMs ?? 0) / 1000).toFixed(1)}s`);
21
- if (run.testFileTimings?.length) {
22
- console.log("Slowest test files (test + hook time):");
23
- console.log(formatSlowestTestFiles(run.testFileTimings));
24
- }
79
+ console.log(formatSlowestTestCases(result.cases.map(({ file, name, durationMs, result: outcome, retry, caseId }) => ({
80
+ file,
81
+ name,
82
+ caseId,
83
+ retry,
84
+ durationMs,
85
+ result: outcome,
86
+ })), result.limit));
87
+ if (result.hasMore) {
88
+ console.log(c.dim(` … more rows available (hasMore)`));
25
89
  }
26
90
  return;
27
91
  }
92
+ for (const run of store.list({ limit: 10 })) {
93
+ console.log(`${run.startedAt} · ${run.phase} · ${run.machine ?? "local"} · ${run.scope} · ${((run.durationMs ?? 0) / 1000).toFixed(1)}s · run #${run.id}`);
94
+ if (run.testFileTimings?.length) {
95
+ console.log("Slowest test files (test + hook time in file):");
96
+ console.log(formatSlowestTestFiles(run.testFileTimings));
97
+ }
98
+ }
99
+ console.log(c.dim("\nIndividual cases: repoos checks timings --tests [--run-id ID] [--recent-runs N] [--limit N] [--offset N] [--json]"));
100
+ }
101
+ export function cmdChecks(args) {
102
+ if (args[0] === "timings") {
103
+ cmdChecksTimings(args.slice(1));
104
+ return;
105
+ }
28
106
  if (args[0] !== "slots") {
29
- console.error("Usage: repoos checks timings | slots [--release SLOT --confirm PID]");
107
+ console.error("Usage: repoos checks timings [--tests] [--run-id ID] [--recent-runs N] [--limit N] [--offset N] [--json] | slots [--release SLOT --confirm PID]");
30
108
  process.exitCode = 2;
31
109
  return;
32
110
  }
@@ -54,7 +132,7 @@ export function cmdChecks(args) {
54
132
  const holder = inspectCrossProcessSlots(root, heavySlotLimit(config), config.localChecks?.staleAfterMs).find((item) => item.slot === slot);
55
133
  if (!holder?.pid)
56
134
  throw new Error(`slot ${slot} is free`);
57
- console.log(`Releasing slot ${slot}, held by task #${String(holder.meta?.taskId ?? "unknown")} check, PID ${holder.pid}${holder.dead ? ", dead" : holder.wedged ? ", wedged" : ", alive"}.`);
135
+ console.log(`Releasing slot ${slot}, held by task #${String(holder.meta?.taskId ?? "unknown")} check, PID ${holder.pid}${holder.dead ? ", process exited" : holder.wedged ? `, no recent heartbeat (last seen ${Math.round(holder.heartbeatAgeMs / 1000)}s ago)` : ", alive"}.`);
58
136
  releaseLocalCheckSlot(root, slot, pid, config.localChecks?.staleAfterMs);
59
137
  console.log(c.green(" ✔ Slot released."));
60
138
  }
@@ -70,13 +148,12 @@ export function cmdChecks(args) {
70
148
  ? `#${String(holder.meta.taskId)} check`
71
149
  : "unattributed check";
72
150
  console.log(holder.pid
73
- ? `slot ${holder.slot}: ${task}, pid ${holder.pid}, ${holder.dead ? "dead, reclaiming" : holder.wedged ? "wedged" : "alive"}, held ${Math.round(holder.ageMs / 1000)}s, heartbeat ${Math.round(holder.heartbeatAgeMs / 1000)}s ago`
151
+ ? `slot ${holder.slot}: ${task}, pid ${holder.pid}, ${holder.dead ? "process exited, reclaiming" : holder.wedged ? `no recent heartbeat (last seen ${Math.round(holder.heartbeatAgeMs / 1000)}s ago)` : "alive"}, held ${Math.round(holder.ageMs / 1000)}s, heartbeat ${Math.round(holder.heartbeatAgeMs / 1000)}s ago`
74
152
  : `slot ${holder.slot}: free`);
75
153
  }
76
- for (const marker of readQueueMarkers(boardRoot, cacheDir)
77
- .filter((entry) => entry.kind === "local-check")
78
- .sort((a, b) => a.position - b.position)) {
154
+ const queue = currentQueueMarkers(readQueueMarkers(boardRoot, cacheDir).filter((entry) => entry.kind === "local-check"), listSlotWaiterPids(root));
155
+ queue.forEach((marker) => {
79
156
  const waitingMs = Math.max(0, Date.now() - Date.parse(marker.since));
80
157
  console.log(`queue position ${marker.position}: #${marker.taskId}, waiting ${Math.round(waitingMs / 1000)}s`);
81
- }
158
+ });
82
159
  }
@@ -738,7 +738,7 @@ export async function cmdDone(args) {
738
738
  console.log(`${result.status >= 200 && result.status < 300 ? c.green(" ✓ ") : c.yellow(" · ")}${message} (HTTP ${result.status})`);
739
739
  return (result.status >= 200 && result.status < 300) || result.status === 409 ? 0 : 1;
740
740
  }
741
- const started = await api.request("POST", `/api/tasks/${id}/done`, { commitDirty });
741
+ const started = await api.request("POST", `/api/tasks/${id}/done`, { commitDirty }, { timeoutMs: 0 });
742
742
  if (started.status === 409 && started.body.needsCommit) {
743
743
  throw new RepoOsApiError(started.body.error ?? "close-out blocked on dirty tree", 409, started.body);
744
744
  }
@@ -1529,8 +1529,8 @@ export async function cmdLandable(args) {
1529
1529
  printJson(result);
1530
1530
  else {
1531
1531
  const verdict = result.landable
1532
- ? c.green(`#${id} is landable`)
1533
- : c.red(`#${id} is not landable yet`);
1532
+ ? c.green(`#${id} is ready to merge`)
1533
+ : c.red(`#${id} is not ready to merge yet`);
1534
1534
  console.log(` ${verdict}`);
1535
1535
  for (const check of result.checks) {
1536
1536
  console.log(` ${landableIcon(check.status)} ${c.bold(check.label)} — ${check.detail}`);
@@ -5,6 +5,7 @@ import { readFileSync } from "node:fs";
5
5
  import { createDocument, createFreeformDocument, docFreeformPrompt, parseGeneratedDocument, } from "../core/docs.js";
6
6
  import { loadConfig } from "../core/config.js";
7
7
  import { c } from "../cli/colors.js";
8
+ import { repoAgentRunTmpOpts } from "../core/agent-run-tmpdir.js";
8
9
  import { resolvePmAgent, runPrompt, recordOneShotSession } from "../server/agents.js";
9
10
  import { currentDocsDir, importDocsInto, scaffoldDocsInto } from "./docs-io.js";
10
11
  /** `repoos new-doc "<description>"` or `repoos new-doc --path docs/foo.md --content-file x.md` */
@@ -34,6 +35,7 @@ export async function cmdNewDoc(args) {
34
35
  const docResult = await createFreeformDocument(config, description, async (desc) => {
35
36
  const result = await runPrompt(pm, docFreeformPrompt(desc), {
36
37
  cwd: config.root,
38
+ ...repoAgentRunTmpOpts(config),
37
39
  });
38
40
  // Freeform doc authoring is real PM spend that belongs to no task (0311).
39
41
  recordOneShotSession(config.root, pm, result, { sessionType: "pm", taskId: null });
@@ -3,29 +3,37 @@
3
3
  *
4
4
  * Runs against the MAIN checkout (via `boardRoot()`), never a linked worktree.
5
5
  *
6
- * repoos gc prune `repoos/integrate/*` candidates + stale metadata
7
- * now, and PREVIEW the feature worktrees `--yes` would take
8
- * repoos gc --yes also remove feature worktrees/branches for done/absent
9
- * tasks (skips any with uncommitted or unmerged work)
10
- * repoos gc --dry-run show everything that would be collected, touch nothing
6
+ * Cleanup is automatic and safe by construction (#1004): the same sweep runs at
7
+ * boot and after every close-out. An operator can still inspect or force a run:
8
+ *
9
+ * repoos gc run the safe sweep now (candidates + resolved,
10
+ * provably-redundant feature worktrees)
11
+ * repoos gc --yes accepted for compatibility; identical to the above
12
+ * repoos gc --dry-run show candidates, retained reasons, and external
13
+ * worktrees, touching nothing
11
14
  */
12
15
  import { createRepoOS } from "../core/repoos.js";
13
16
  import { boardRoot } from "../core/config.js";
14
17
  import { c } from "../cli/colors.js";
15
- import { sweepStaleWorktrees } from "../core/worktree-gc.js";
18
+ import { formatGcEntryDetails, sweepStaleWorktrees } from "../core/worktree-gc.js";
16
19
  function printReport(report, title) {
17
20
  console.log(c.bold(` ${title}`));
18
- if (report.removedWorktrees.length === 0 &&
19
- report.keptDirty.length === 0 &&
20
- report.errors.length === 0) {
21
- console.log(c.dim(" nothing to collect"));
22
- }
21
+ const counts = report.summary;
22
+ console.log(c.dim(` ${counts.candidates} safe candidate${counts.candidates === 1 ? "" : "s"} · ` +
23
+ `${counts.retained} retained · ${counts.external} outside RepoOS`));
23
24
  for (const w of report.removedWorktrees) {
24
25
  const verb = report.dryRun ? "would remove" : "removed";
25
- console.log(` ${c.green(verb)} ${w.branch || c.dim("(detached)")} ${c.dim(w.path)}`);
26
+ console.log(` ${c.green(verb)} ${w.branch || c.dim("(detached)")} ${c.dim(w.path)}` +
27
+ c.dim(` — ${w.reason}`));
26
28
  }
27
- for (const k of report.keptDirty) {
29
+ for (const k of report.retained) {
28
30
  console.log(` ${c.yellow("kept")} ${k.branch || c.dim("(detached)")} ${c.dim(`— ${k.reason}`)}`);
31
+ const detail = formatGcEntryDetails(k);
32
+ if (detail)
33
+ console.log(c.dim(` ${detail}`));
34
+ }
35
+ for (const e of report.external) {
36
+ console.log(` ${c.dim("external")} ${e.branch || c.dim("(detached)")} ${c.dim(e.path)}`);
29
37
  }
30
38
  for (const e of report.errors) {
31
39
  console.log(` ${c.red("error")} ${e}`);
@@ -35,23 +43,13 @@ function printReport(report, title) {
35
43
  }
36
44
  export function cmdGc(argv) {
37
45
  const dryRun = argv.includes("--dry-run") || argv.includes("-n");
38
- const yes = argv.includes("--yes") || argv.includes("-y");
46
+ // `--yes` is accepted as a no-op compatibility alias: the default sweep is
47
+ // already the same safe policy, with the same fail-closed guards.
39
48
  const { root } = boardRoot();
40
49
  const { config } = createRepoOS(root);
41
50
  if (dryRun) {
42
51
  printReport(sweepStaleWorktrees(config, { mode: "full", dryRun: true }), "gc — dry run");
43
52
  return;
44
53
  }
45
- if (yes) {
46
- printReport(sweepStaleWorktrees(config, { mode: "full" }), "gc");
47
- return;
48
- }
49
- // Default: do the safe part for real, preview the rest.
50
- printReport(sweepStaleWorktrees(config, { mode: "integrate-only" }), "gc — candidates + stale metadata");
51
- const preview = sweepStaleWorktrees(config, { mode: "full", dryRun: true });
52
- const pendingFeature = preview.removedWorktrees.filter((w) => !w.branch.startsWith("repoos/integrate/"));
53
- if (pendingFeature.length || preview.keptDirty.length) {
54
- console.log();
55
- printReport({ ...preview, removedWorktrees: pendingFeature }, "feature worktrees — run `repoos gc --yes` to apply");
56
- }
54
+ printReport(sweepStaleWorktrees(config, { mode: "full" }), "gc");
57
55
  }
@@ -1249,7 +1249,7 @@ async function offerAreaVocabulary(root) {
1249
1249
  if (areas.length === 0)
1250
1250
  return;
1251
1251
  console.log(c.dim(" Preview targets route a task preview by its area — the picker and"));
1252
- console.log(c.dim(" the PM prompt offer target areas automatically; see user-docs/configuration.md's Previews section."));
1252
+ console.log(c.dim(" the PM prompt offer target areas automatically; see https://docs.repoos.org/configuration (Previews)."));
1253
1253
  const previewStub = await confirm(" Scaffold commented preview-target stubs for these areas?", false);
1254
1254
  // Do not clobber a config changed while the prompt was open.
1255
1255
  if (readFileSync(tomlPath, "utf8") !== original) {
@@ -1706,7 +1706,7 @@ async function guidedNewRepo(opts) {
1706
1706
  }
1707
1707
  if (areas.length) {
1708
1708
  console.log(c.dim(" Preview targets route a task preview by its area — the picker and"));
1709
- console.log(c.dim(" the PM prompt offer target areas automatically; see user-docs/configuration.md's Previews section."));
1709
+ console.log(c.dim(" the PM prompt offer target areas automatically; see https://docs.repoos.org/configuration (Previews)."));
1710
1710
  }
1711
1711
  // Preview targets reinforce areas ("define them together"): when an area
1712
1712
  // vocabulary was given, offer to scaffold the commented `[[preview.targets]]`
@@ -99,20 +99,49 @@ export interface StatusSnapshot {
99
99
  active: StatusActiveTask[];
100
100
  };
101
101
  worktrees: {
102
- /** Registered worktrees including the main checkout. */
102
+ /** Registered worktrees including the main checkout and external ones. */
103
103
  count: number;
104
+ /** Registered worktrees RepoOS manages (excludes external ones). */
105
+ managedCount: number;
104
106
  warnThreshold: number;
105
107
  /** What `repoos gc --dry-run` would collect (same sweep, same inputs). */
106
- leaked: Array<{
108
+ candidates: Array<{
107
109
  branch: string;
108
110
  path: string;
111
+ reason: string;
112
+ taskId?: string;
113
+ taskStatus?: string;
114
+ commitsAhead?: number;
115
+ dirtyPaths?: string[];
116
+ ignoredPaths?: string[];
117
+ changedSourcePaths?: string[];
109
118
  }>;
110
119
  /** What gc would keep, with the reason it is kept. */
111
- kept: Array<{
120
+ retained: Array<{
121
+ branch: string;
122
+ path: string;
123
+ reason: string;
124
+ taskId?: string;
125
+ taskStatus?: string;
126
+ commitsAhead?: number;
127
+ dirtyPaths?: string[];
128
+ ignoredPaths?: string[];
129
+ changedSourcePaths?: string[];
130
+ }>;
131
+ /** Registered worktrees outside RepoOS's managed directory (never touched). */
132
+ external: Array<{
112
133
  branch: string;
113
134
  path: string;
114
135
  reason: string;
115
136
  }>;
137
+ /** Why a sweep could not proceed, e.g. unreadable lifecycle state. */
138
+ errors: string[];
139
+ /** Counts mirror `gc --dry-run`, so the two views agree by construction. */
140
+ counts: {
141
+ candidates: number;
142
+ retained: number;
143
+ external: number;
144
+ };
116
145
  };
117
146
  tunnel: {
118
147
  configured: boolean;