@repo-os/repoos 0.5.60 → 0.5.62

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 (215) hide show
  1. package/dist/.build-info.json +2 -2
  2. package/dist/.build-stamp.json +1 -1
  3. package/dist/commands/certify.d.ts +2 -0
  4. package/dist/commands/certify.js +6 -3
  5. package/dist/commands/doctor.d.ts +3 -1
  6. package/dist/commands/doctor.js +10 -7
  7. package/dist/commands/init.js +34 -0
  8. package/dist/commands/shot.d.ts +43 -0
  9. package/dist/commands/shot.js +98 -25
  10. package/dist/commands/tasks.d.ts +7 -2
  11. package/dist/commands/tasks.js +175 -16
  12. package/dist/commands/ui-contrast-audit.d.ts +43 -0
  13. package/dist/commands/ui-contrast-audit.js +196 -16
  14. package/dist/core/agent-compatibility.json +25 -3
  15. package/dist/core/agent-contract.d.ts +3 -0
  16. package/dist/core/agent-contract.js +108 -5
  17. package/dist/core/agent-updates.d.ts +1 -3
  18. package/dist/core/agent-updates.js +2 -22
  19. package/dist/core/check-store.d.ts +2 -1
  20. package/dist/core/check-store.js +15 -5
  21. package/dist/core/config.d.ts +1 -1
  22. package/dist/core/config.js +12 -2
  23. package/dist/core/detect.d.ts +0 -6
  24. package/dist/core/detect.js +4 -25
  25. package/dist/core/doctor.js +3 -1
  26. package/dist/core/git.d.ts +17 -1
  27. package/dist/core/git.js +58 -4
  28. package/dist/core/models.d.ts +7 -0
  29. package/dist/core/models.js +63 -1
  30. package/dist/core/providers/spend.d.ts +127 -1
  31. package/dist/core/providers/spend.js +347 -17
  32. package/dist/core/repoos.d.ts +2 -0
  33. package/dist/core/repoos.js +9 -0
  34. package/dist/core/shot-page.d.ts +9 -1
  35. package/dist/core/shot-page.js +112 -10
  36. package/dist/core/shot-plan.d.ts +87 -6
  37. package/dist/core/shot-plan.js +125 -18
  38. package/dist/core/shot-targets.d.ts +50 -0
  39. package/dist/core/shot-targets.js +77 -21
  40. package/dist/core/support-bundle.js +2 -0
  41. package/dist/core/task-dependencies.d.ts +15 -0
  42. package/dist/core/task-dependencies.js +112 -0
  43. package/dist/core/task-dependencies.test.d.ts +1 -0
  44. package/dist/core/task-dependencies.test.js +211 -0
  45. package/dist/core/task.d.ts +17 -0
  46. package/dist/core/task.js +50 -0
  47. package/dist/core/types.d.ts +29 -3
  48. package/dist/server/agents.d.ts +94 -11
  49. package/dist/server/agents.js +602 -72
  50. package/dist/server/auto-engineering.d.ts +1 -1
  51. package/dist/server/auto-engineering.js +4 -1
  52. package/dist/server/handoff.js +33 -0
  53. package/dist/server/integration-job.d.ts +2 -0
  54. package/dist/server/integration-job.js +5 -0
  55. package/dist/server/integration-orchestrator.js +29 -12
  56. package/dist/server/live-index.d.ts +12 -0
  57. package/dist/server/live-index.js +11 -2
  58. package/dist/server/merge-conflict.d.ts +39 -0
  59. package/dist/server/merge-conflict.js +128 -0
  60. package/dist/server/release-notes-cache.d.ts +7 -2
  61. package/dist/server/release-notes-cache.js +30 -17
  62. package/dist/server/release.d.ts +25 -8
  63. package/dist/server/release.js +48 -8
  64. package/dist/server/review.js +8 -3
  65. package/dist/server/routes/info.js +5 -1
  66. package/dist/server/routes/model-providers.d.ts +6 -0
  67. package/dist/server/routes/model-providers.js +55 -5
  68. package/dist/server/routes/release.d.ts +37 -7
  69. package/dist/server/routes/release.js +120 -44
  70. package/dist/server/routes/repo-log.d.ts +12 -0
  71. package/dist/server/routes/repo-log.js +68 -2
  72. package/dist/server/routes/tasks.d.ts +12 -0
  73. package/dist/server/routes/tasks.js +270 -33
  74. package/dist/server/server.js +32 -3
  75. package/dist/server/shot-capture.d.ts +2 -0
  76. package/dist/server/shot-capture.js +104 -14
  77. package/dist/server/shots.d.ts +14 -0
  78. package/dist/server/shots.js +16 -1
  79. package/dist/server/task-underspecified-flag.d.ts +2 -0
  80. package/dist/server/task-underspecified-flag.js +10 -0
  81. package/dist/server/watcher.d.ts +1 -0
  82. package/dist/server/watcher.js +16 -4
  83. package/dist/server/worktree-handoff-guard.js +121 -3
  84. package/dist/server/write.d.ts +19 -1
  85. package/dist/server/write.js +57 -4
  86. package/dist/ui/assets/{AgentModelModal-CFdPv_af.js → AgentModelModal-C-X9UXUK.js} +1 -1
  87. package/dist/ui/assets/{AgentsView-Cp-2uoJK.css → AgentsView-DPFAB5vF.css} +1 -1
  88. package/dist/ui/assets/AgentsView-FHNRZWLG.js +1 -0
  89. package/dist/ui/assets/ChecksView-DdI629ss.css +1 -0
  90. package/dist/ui/assets/ChecksView-DueoaSQy.js +0 -0
  91. package/dist/ui/assets/ContextView-CE6PlM7S.js +4 -0
  92. package/dist/ui/assets/DashboardView-D6GeYs6o.js +1 -0
  93. package/dist/ui/assets/DashboardView-MjXlMIuk.css +1 -0
  94. package/dist/ui/assets/{DeploymentsView-CrveYuba.js → DeploymentsView-BJZ6z_Gd.js} +1 -1
  95. package/dist/ui/assets/{DiffView-CwcQsIy6.js → DiffView-D8pgjtSQ.js} +2 -2
  96. package/dist/ui/assets/InputsView-C1MEfngw.js +1 -0
  97. package/dist/ui/assets/{LoginView-CZyIyLbb.js → LoginView-DYvBzW5u.js} +1 -1
  98. package/dist/ui/assets/ReleasesView-B94OPqL-.css +1 -0
  99. package/dist/ui/assets/ReleasesView-CGzIvtxF.js +3 -0
  100. package/dist/ui/assets/SettingsView-DsoMIVuc.js +4 -0
  101. package/dist/ui/assets/StoriesView-BVQNDIfP.js +1 -0
  102. package/dist/ui/assets/{VoiceDictate-C0-jNbo1.js → VoiceDictate-DkW8pCow.js} +1 -1
  103. package/dist/ui/assets/WorkView-iBEEgB6t.js +2 -0
  104. package/dist/ui/assets/{abnfDiagram-VCTEODGH-CR-dgaI5.js → abnfDiagram-VCTEODGH-MSv6Drat.js} +1 -1
  105. package/dist/ui/assets/architecture-7GRP2DOG-DsFV151p.js +1 -0
  106. package/dist/ui/assets/{architectureDiagram-5GKGNRK7-DZ96SWkx.js → architectureDiagram-5GKGNRK7-BZ_-qdv7.js} +1 -1
  107. package/dist/ui/assets/{blockDiagram-I7D4REHJ-DGqfLA3z.js → blockDiagram-I7D4REHJ-B5rJFlWv.js} +1 -1
  108. package/dist/ui/assets/{button-BsLUWnfn.js → button-Y6WlSBKj.js} +1 -1
  109. package/dist/ui/assets/{c4Diagram-7LVT6UL2-Cowa_bSL.js → c4Diagram-7LVT6UL2-27feyEIL.js} +1 -1
  110. package/dist/ui/assets/channel-Cz6IiS37.js +1 -0
  111. package/dist/ui/assets/{checkbox-Bu0fOTRa.js → checkbox-D_jqCYo8.js} +1 -1
  112. package/dist/ui/assets/{chunk-4HAMMTFA-BcVHsIg0.js → chunk-4HAMMTFA-eEnsDUUm.js} +1 -1
  113. package/dist/ui/assets/{chunk-75Z2AOVW-CCrPEBxq.js → chunk-75Z2AOVW-CZJr44uW.js} +1 -1
  114. package/dist/ui/assets/{chunk-DU6HZSFF-BlxKgrXx.js → chunk-DU6HZSFF-CjmVMWOj.js} +1 -1
  115. package/dist/ui/assets/{chunk-F27PBJKO-CoHtdaN7.js → chunk-F27PBJKO-4bUPHWpG.js} +1 -1
  116. package/dist/ui/assets/{chunk-GMAD6QVW-BcsnrHyI.js → chunk-GMAD6QVW-C0bqKg0k.js} +1 -1
  117. package/dist/ui/assets/{chunk-GVQU2GXP-DsWHJ94f.js → chunk-GVQU2GXP-CNduQ5rz.js} +1 -1
  118. package/dist/ui/assets/{chunk-IMKFNOWR-DR9nP96a.js → chunk-IMKFNOWR-Myux_1tI.js} +1 -1
  119. package/dist/ui/assets/{chunk-L3NEJ4N5-CB-GwFZo.js → chunk-L3NEJ4N5-NuKwzg2U.js} +1 -1
  120. package/dist/ui/assets/{chunk-OSK3NFVY-iY9KK7zg.js → chunk-OSK3NFVY-CEqMHLr2.js} +1 -1
  121. package/dist/ui/assets/{chunk-P2QGCYS3-CqI6JQdG.js → chunk-P2QGCYS3-CR-84Lk5.js} +1 -1
  122. package/dist/ui/assets/{chunk-POPQ4Y6H-DV25Tql2.js → chunk-POPQ4Y6H-Br-XXvax.js} +1 -1
  123. package/dist/ui/assets/{chunk-PWAF6VOD-DSYNRc8Y.js → chunk-PWAF6VOD-BG70h8rU.js} +1 -1
  124. package/dist/ui/assets/{chunk-SHT3W25Y-Bo50rAC0.js → chunk-SHT3W25Y-BuA1JMD2.js} +1 -1
  125. package/dist/ui/assets/{chunk-SVP7TREG-BXeqvMHD.js → chunk-SVP7TREG-pngt2L1r.js} +1 -1
  126. package/dist/ui/assets/{chunk-TICWLB2K-mRRCAZVT.js → chunk-TICWLB2K-Cjy3Fajf.js} +1 -1
  127. package/dist/ui/assets/classDiagram-ZZMXUADV-BSdAza91.js +1 -0
  128. package/dist/ui/assets/classDiagram-v2-VYDZK3BY-BSdAza91.js +1 -0
  129. package/dist/ui/assets/config-Brg64iOP.js +1 -0
  130. package/dist/ui/assets/{cynefin-OW5HDTMX-j8AhdAmH.js → cynefin-OW5HDTMX-BPprbkdm.js} +1 -1
  131. package/dist/ui/assets/{cynefinDiagram-5FMLGOSQ-T9YMbC5-.js → cynefinDiagram-5FMLGOSQ-DDhXMGfJ.js} +1 -1
  132. package/dist/ui/assets/{dagre-GXQ25YYZ-Db7gL2It.js → dagre-GXQ25YYZ-Dif9VtAE.js} +1 -1
  133. package/dist/ui/assets/{diagram-S7CK7UJ4-u2nvAKJY.js → diagram-S7CK7UJ4-RboRw0Qp.js} +1 -1
  134. package/dist/ui/assets/{diagram-UQ7AKVKN-DTDLg2RD.js → diagram-UQ7AKVKN-BALbR1VK.js} +1 -1
  135. package/dist/ui/assets/{diagram-VSXAHHWV-Bg1yw3NM.js → diagram-VSXAHHWV-DikETeUn.js} +1 -1
  136. package/dist/ui/assets/{diagram-VX7I27RA-C-2r-Zwc.js → diagram-VX7I27RA-BhzF4vum.js} +1 -1
  137. package/dist/ui/assets/{diagram-Z3DM3KII-mhTivOeP.js → diagram-Z3DM3KII-DfElw-8p.js} +1 -1
  138. package/dist/ui/assets/{ebnfDiagram-PWID7BFC-BomtsdPH.js → ebnfDiagram-PWID7BFC-DWBcjdxW.js} +1 -1
  139. package/dist/ui/assets/{erDiagram-RLTQ6QDP-ByyLYlKt.js → erDiagram-RLTQ6QDP-9t0j2-5C.js} +1 -1
  140. package/dist/ui/assets/eventmodeling-NTZA5JFV-CkM-IpK3.js +1 -0
  141. package/dist/ui/assets/flowDiagram-HODETNUW-Cjc88Y5V.js +1 -0
  142. package/dist/ui/assets/{ganttDiagram-EL5Y4UJY-vwT9SFzy.js → ganttDiagram-EL5Y4UJY-BV4wbDOf.js} +1 -1
  143. package/dist/ui/assets/{gitGraph-4MIJSDKK-D4MR7EUd.js → gitGraph-4MIJSDKK-CHLeBDuC.js} +1 -1
  144. package/dist/ui/assets/{gitGraphDiagram-WWUBYQGX-CAs6Oicn.js → gitGraphDiagram-WWUBYQGX-D1coFQQr.js} +1 -1
  145. package/dist/ui/assets/index-CCwW1Tv4.css +1 -0
  146. package/dist/ui/assets/index-CvnEg0cY.js +55 -0
  147. package/dist/ui/assets/{info-A6RAGUB7-D-SDm8bt.js → info-A6RAGUB7-BA6DRUi0.js} +1 -1
  148. package/dist/ui/assets/{infoDiagram-27XIBGKW-I3RynMEK.js → infoDiagram-27XIBGKW-DelTcISi.js} +1 -1
  149. package/dist/ui/assets/{ishikawaDiagram-5VMMS53U-DViQsOVU.js → ishikawaDiagram-5VMMS53U-D6SYXrWV.js} +1 -1
  150. package/dist/ui/assets/{journeyDiagram-3NMN7TZE-CoJkCrsA.js → journeyDiagram-3NMN7TZE-iul5gKFN.js} +1 -1
  151. package/dist/ui/assets/{kanban-definition-UXKFOSKX-De32ZjHj.js → kanban-definition-UXKFOSKX-DmsdCDnD.js} +1 -1
  152. package/dist/ui/assets/{line-RJPM2c8D.js → line-6qxsfuaD.js} +1 -1
  153. package/dist/ui/assets/{mermaid-parser.core-bWpp6huV.js → mermaid-parser.core-DwVo-Y2S.js} +3 -3
  154. package/dist/ui/assets/{mermaid.core-CG0WgtUh.js → mermaid.core-DMfVb5bs.js} +4 -4
  155. package/dist/ui/assets/{mindmap-definition-YA3MSWOX-C56ZodSM.js → mindmap-definition-YA3MSWOX-CD5cXQfB.js} +1 -1
  156. package/dist/ui/assets/{packet-AYTQ26CC-CndaUGZ1.js → packet-AYTQ26CC-DVdCUknr.js} +1 -1
  157. package/dist/ui/assets/{pegDiagram-XKGWAZYB-DCC4hvTA.js → pegDiagram-XKGWAZYB-DGmIIA1Q.js} +1 -1
  158. package/dist/ui/assets/{pie-WAS4IAKB-Cfm-_dkl.js → pie-WAS4IAKB-UGTX1jKx.js} +1 -1
  159. package/dist/ui/assets/{pieDiagram-E7YTZNPT-Di3aGaMm.js → pieDiagram-E7YTZNPT-DLbLermT.js} +1 -1
  160. package/dist/ui/assets/{quadrantDiagram-AXDQQJYC-q_I_jD91.js → quadrantDiagram-AXDQQJYC-DrKEGcJP.js} +1 -1
  161. package/dist/ui/assets/{radar-RG4KPBEZ-DtiqcHoq.js → radar-RG4KPBEZ-Bts8VyZT.js} +1 -1
  162. package/dist/ui/assets/{railroad-74A4TZTK-DnepJqEX.js → railroad-74A4TZTK-DEWurv57.js} +1 -1
  163. package/dist/ui/assets/railroad-abnf-HS5TGJTU-DKtrJ5pg.js +1 -0
  164. package/dist/ui/assets/railroad-ebnf-LZEXJU2U-8eArMXZA.js +1 -0
  165. package/dist/ui/assets/railroad-peg-WCYAUIDC-SfWjNEkF.js +1 -0
  166. package/dist/ui/assets/{railroadDiagram-O6MQD6OU-I8cQO0Ff.js → railroadDiagram-O6MQD6OU-Bc2KS9ny.js} +1 -1
  167. package/dist/ui/assets/repo-BWyge_2n.js +1 -0
  168. package/dist/ui/assets/{requirementDiagram-BXWQKSXE-CJJ0Hb8G.js → requirementDiagram-BXWQKSXE-DJYx_Rdm.js} +1 -1
  169. package/dist/ui/assets/{sankeyDiagram-P5KCCOFB-sV__k-lq.js → sankeyDiagram-P5KCCOFB-BcEvC1QT.js} +1 -1
  170. package/dist/ui/assets/{sequenceDiagram-WJ2MYXX4-ouV9lTvQ.js → sequenceDiagram-WJ2MYXX4-ERKmG0r-.js} +1 -1
  171. package/dist/ui/assets/{stateDiagram-D77RDMKH-hb_F14o9.js → stateDiagram-D77RDMKH-ChqxZBTP.js} +1 -1
  172. package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-Crkx2xne.js +1 -0
  173. package/dist/ui/assets/{swimlanes-42K2YHIH-zLlllJjz.js → swimlanes-42K2YHIH-DVgFWSH5.js} +1 -1
  174. package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-BVnIaNys.js +8 -0
  175. package/dist/ui/assets/{timeline-definition-24CTP7MA-sH1isqOu.js → timeline-definition-24CTP7MA-Bs376mCS.js} +1 -1
  176. package/dist/ui/assets/{title-CmTcwJQC.js → title-CIBxYjzz.js} +1 -1
  177. package/dist/ui/assets/{treeView-Q6P3EWNA-BCmHIy3a.js → treeView-Q6P3EWNA-B8wx19JO.js} +1 -1
  178. package/dist/ui/assets/{treemap-WGGIJYW6-Dt0_pLds.js → treemap-WGGIJYW6-By-sUWWT.js} +1 -1
  179. package/dist/ui/assets/ui-DFhclAYe.js +1 -0
  180. package/dist/ui/assets/vendor-ui-BInmYDPf.js +3 -0
  181. package/dist/ui/assets/{vennDiagram-4TSXK5OY-VyFD_IW6.js → vennDiagram-4TSXK5OY-DT2AgAWU.js} +1 -1
  182. package/dist/ui/assets/{wardley-WFR3VGLG-Bbzy3wiO.js → wardley-WFR3VGLG-CRXTnxDX.js} +1 -1
  183. package/dist/ui/assets/{wardleyDiagram-VM6X3IG4-ywLURBFW.js → wardleyDiagram-VM6X3IG4-CuRK6dGX.js} +1 -1
  184. package/dist/ui/assets/{xychartDiagram-S5SC5T6Z-B5J_sFHA.js → xychartDiagram-S5SC5T6Z-BPgu4rsi.js} +1 -1
  185. package/dist/ui/index.html +11 -10
  186. package/dist/ui/sw.js +2 -2
  187. package/package.json +1 -1
  188. package/dist/ui/assets/AgentsView-D0-0eTHc.js +0 -1
  189. package/dist/ui/assets/ChecksView-B1i8XJKX.js +0 -0
  190. package/dist/ui/assets/ChecksView-CuSoxLqv.css +0 -1
  191. package/dist/ui/assets/ContextView-BZtBkBvL.js +0 -4
  192. package/dist/ui/assets/DashboardView-GqiLEeJW.css +0 -1
  193. package/dist/ui/assets/DashboardView-L3LxrCcG.js +0 -1
  194. package/dist/ui/assets/InputsView-DV--xXFD.js +0 -1
  195. package/dist/ui/assets/ReleasesView-BgGNVM_E.css +0 -1
  196. package/dist/ui/assets/ReleasesView-DR9hFdJP.js +0 -3
  197. package/dist/ui/assets/SettingsView-DcAJ_7I0.js +0 -4
  198. package/dist/ui/assets/StoriesView-7Y-m9ze_.js +0 -1
  199. package/dist/ui/assets/WorkView-D3wRNx9w.js +0 -2
  200. package/dist/ui/assets/architecture-7GRP2DOG-Ck8_HLSt.js +0 -1
  201. package/dist/ui/assets/channel-f69_ZBo8.js +0 -1
  202. package/dist/ui/assets/classDiagram-ZZMXUADV-Bep317uI.js +0 -1
  203. package/dist/ui/assets/classDiagram-v2-VYDZK3BY-Bep317uI.js +0 -1
  204. package/dist/ui/assets/config-BpusGwRJ.js +0 -1
  205. package/dist/ui/assets/eventmodeling-NTZA5JFV-KeldQ82t.js +0 -1
  206. package/dist/ui/assets/flowDiagram-HODETNUW-BGCbuMAO.js +0 -1
  207. package/dist/ui/assets/index-B_NqhhGa.css +0 -1
  208. package/dist/ui/assets/index-DGwt0YaQ.js +0 -48
  209. package/dist/ui/assets/railroad-abnf-HS5TGJTU-BURH3L8i.js +0 -1
  210. package/dist/ui/assets/railroad-ebnf-LZEXJU2U-BBeSEJsW.js +0 -1
  211. package/dist/ui/assets/railroad-peg-WCYAUIDC-BbMPu8ur.js +0 -1
  212. package/dist/ui/assets/repo-CrA_4-Ii.js +0 -1
  213. package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-B8tCq2OW.js +0 -1
  214. package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-CXzbsdys.js +0 -8
  215. package/dist/ui/assets/vendor-ui-BbK4TVl8.js +0 -3
@@ -1,5 +1,5 @@
1
1
  {
2
- "hash": "cf6db5df542f115cccfac9cdfcfbd0703be0f1fa5628e248d1aa85ff48bf2c09",
3
- "version": "0.5.60",
2
+ "hash": "0264ffb217828c3c1e53be5b58abbe310ff9b749bb8bd2c916d4d22e6dd164ac",
3
+ "version": "0.5.62",
4
4
  "devUi": false
5
5
  }
@@ -1,3 +1,3 @@
1
1
  {
2
- "generatedAt": "2026-09-30T14:26:04.444Z"
2
+ "generatedAt": "2026-10-02T12:12:44.891Z"
3
3
  }
@@ -5,6 +5,8 @@ export interface CertifyCliArgs {
5
5
  missingCli: boolean;
6
6
  /** Explicit binary path — skips PATH resolution and probes this binary directly. */
7
7
  binary: string | null;
8
+ /** Model for the probe's runs (`--model <id>`), or null for the harness default. */
9
+ model: string | null;
8
10
  }
9
11
  export declare function parseCertifyArgs(argv: string[]): CertifyCliArgs;
10
12
  export declare function cmdCertify(argv: string[]): Promise<void>;
@@ -22,9 +22,11 @@ export function parseCertifyArgs(argv) {
22
22
  const json = argv.includes("--json");
23
23
  const binaryIdx = argv.indexOf("--binary");
24
24
  const binary = binaryIdx !== -1 ? (argv[binaryIdx + 1] ?? null) : null;
25
- const positional = argv.filter((a, i) => !a.startsWith("--") && argv[i - 1] !== "--binary");
25
+ const modelIdx = argv.indexOf("--model");
26
+ const model = modelIdx !== -1 ? (argv[modelIdx + 1] ?? null) : null;
27
+ const positional = argv.filter((a, i) => !a.startsWith("--") && argv[i - 1] !== "--binary" && argv[i - 1] !== "--model");
26
28
  const cli = positional[0] ?? null;
27
- return { cli, yes, json, missingCli: !cli, binary };
29
+ return { cli, yes, json, missingCli: !cli, binary, model };
28
30
  }
29
31
  /** Locate the live manifest file on disk (src or dist). */
30
32
  function findManifestPath() {
@@ -56,7 +58,7 @@ function saveManifest(path, manifest) {
56
58
  writeFileSync(path, JSON.stringify(manifest, null, 2) + "\n", "utf8");
57
59
  }
58
60
  export async function cmdCertify(argv) {
59
- const { cli, yes, json: asJson, missingCli, binary } = parseCertifyArgs(argv);
61
+ const { cli, yes, json: asJson, missingCli, binary, model } = parseCertifyArgs(argv);
60
62
  if (missingCli || !cli) {
61
63
  console.error(c.red(" repoos certify needs a harness id, e.g. `repoos certify opencode`."));
62
64
  console.error(c.dim(" Use --binary <path> to probe a specific binary instead of PATH resolution."));
@@ -99,6 +101,7 @@ export async function cmdCertify(argv) {
99
101
  cli,
100
102
  mode: "live",
101
103
  ...(binary ? { bin: binary } : {}),
104
+ ...(model ? { model } : {}),
102
105
  });
103
106
  if (asJson) {
104
107
  console.log(JSON.stringify(result, null, 2));
@@ -8,6 +8,8 @@ export interface DoctorCliArgs {
8
8
  probe: string | null;
9
9
  /** True when `--probe` was given without a value (or before another flag). */
10
10
  probeMissingValue: boolean;
11
+ /** Model for the probe's runs (`--model <id>`), or null for the harness default. */
12
+ model: string | null;
11
13
  /** Explicit binary path for the probe — bypasses PATH resolution. */
12
14
  binary: string | null;
13
15
  }
@@ -38,5 +40,5 @@ export interface DoctorRenderOptions {
38
40
  */
39
41
  export declare function formatDoctor(report: DoctorReport, opts?: DoctorRenderOptions): string;
40
42
  export declare function renderDoctor(report: DoctorReport, opts?: DoctorRenderOptions): void;
41
- /** `repoos doctor [--json] [--verbose] [--probe <cli>] [--yes]` */
43
+ /** `repoos doctor [--json] [--verbose] [--probe <cli> [--model <id>]] [--yes]` */
42
44
  export declare function cmdDoctor(argv: string[]): Promise<void>;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `repoos doctor [--json] [--verbose] [--probe <cli>] [--yes]` — human and
2
+ * `repoos doctor [--json] [--verbose] [--probe <cli> [--model <id>]] [--yes]` — human and
3
3
  * machine rendering of the readiness preflight built in `src/core/doctor.ts`.
4
4
  *
5
5
  * The command adds no diagnostic logic of its own: it runs the engine, prints
@@ -31,15 +31,17 @@ export function parseDoctorArgs(argv) {
31
31
  const yes = argv.includes("--yes");
32
32
  const binaryIdx = argv.indexOf("--binary");
33
33
  const binary = binaryIdx !== -1 ? (argv[binaryIdx + 1] ?? null) : null;
34
+ const modelIdx = argv.indexOf("--model");
35
+ const model = modelIdx !== -1 ? (argv[modelIdx + 1] ?? null) : null;
34
36
  const probeArg = argv.indexOf("--probe");
35
37
  if (probeArg === -1) {
36
- return { json, verbose, yes, probe: null, probeMissingValue: false, binary };
38
+ return { json, verbose, yes, probe: null, probeMissingValue: false, model, binary };
37
39
  }
38
40
  const value = argv[probeArg + 1];
39
41
  if (!value || value.startsWith("--")) {
40
- return { json, verbose, yes, probe: null, probeMissingValue: true, binary };
42
+ return { json, verbose, yes, probe: null, probeMissingValue: true, model, binary };
41
43
  }
42
- return { json, verbose, yes, probe: value, probeMissingValue: false, binary };
44
+ return { json, verbose, yes, probe: value, probeMissingValue: false, model, binary };
43
45
  }
44
46
  function severityColor(severity, text) {
45
47
  if (severity === "pass")
@@ -153,16 +155,16 @@ export function formatDoctor(report, opts = {}) {
153
155
  export function renderDoctor(report, opts = {}) {
154
156
  console.log(formatDoctor(report, opts));
155
157
  }
156
- /** `repoos doctor [--json] [--verbose] [--probe <cli>] [--yes]` */
158
+ /** `repoos doctor [--json] [--verbose] [--probe <cli> [--model <id>]] [--yes]` */
157
159
  export async function cmdDoctor(argv) {
158
- const { json: asJson, yes, probe: probeCli, probeMissingValue, binary, verbose, } = parseDoctorArgs(argv);
160
+ const { json: asJson, yes, probe: probeCli, probeMissingValue, binary, model, verbose, } = parseDoctorArgs(argv);
159
161
  if (probeMissingValue) {
160
162
  console.error(c.red(" repoos doctor --probe needs a harness id, e.g. `--probe opencode`."));
161
163
  process.exitCode = 1;
162
164
  return;
163
165
  }
164
166
  if (probeCli) {
165
- await cmdProbe(probeCli, { asJson, yes, binary });
167
+ await cmdProbe(probeCli, { asJson, yes, binary, model });
166
168
  return;
167
169
  }
168
170
  try {
@@ -228,6 +230,7 @@ async function cmdProbe(cli, opts) {
228
230
  cli,
229
231
  mode: "live",
230
232
  ...(opts.binary ? { bin: opts.binary } : {}),
233
+ ...(opts.model ? { model: opts.model } : {}),
231
234
  });
232
235
  if (opts.asJson) {
233
236
  console.log(JSON.stringify(result, null, 2));
@@ -255,6 +255,37 @@ RepoOS validates the request against your live run, starts the preview from
255
255
  your worktree, probes it server-side, and records the preview URL and probe
256
256
  result in your task transcript. The preview is reaped when the task leaves
257
257
  active/review.
258
+
259
+ ## Declaring evidence shots (## Shots)
260
+
261
+ A task body may carry a \`## Shots\` section with a fenced JSON list of capture
262
+ entries (see \`src/core/shot-plan.ts\`). Each entry has \`target\`, \`route\`, an
263
+ optional \`selector\` (element crop — the exception), an optional \`highlight\`
264
+ CSS selector (outlines changed elements), a \`label\`, and optional ordered
265
+ \`steps\` (click/fill/wait, plain CSS selectors). Use \`repoos update <id>
266
+ --shots '<JSON list>'\` to declare it (the CLI validates the JSON and writes the
267
+ fenced section) without touching the rest of the body — a full \`--body\` replace that drops
268
+ Problem / Desired UX / Acceptance criteria / Notes for AI is refused unless
269
+ \`--force\` is passed.
270
+
271
+ For tabbed views (e.g. Agents), prefer \`?tab=<id>\` routes
272
+ (\`/agents?tab=detected\`) over click steps to reach the right tab, and always
273
+ set \`highlight\` to the changed elements. A declared \`highlight\` or \`selector\`
274
+ that matches nothing at capture time records a visible warning — capture still
275
+ succeeds. Declared shots default to the whole visible window (\`fullPage:
276
+ false\`) with changed elements outlined via \`highlight\`; \`selector\` (element
277
+ crop) is the exception and \`fullPage\` stays off.
278
+
279
+ ## Section body edits
280
+
281
+ To replace a single \`## Section\` without touching the rest of the body (the
282
+ Activity log is always preserved), use:
283
+
284
+ repoos update <id> --section "Section Name" --section-body "new content"
285
+
286
+ A full \`--body\` replace that would drop Problem / Desired UX / Acceptance
287
+ criteria / Notes for AI is refused unless \`--force\` is passed; the error
288
+ message points at this section form.
258
289
  `;
259
290
  /** Marker makes the optional existing-repo addition safe to offer repeatedly. */
260
291
  export const REPOOS_AGENTS_SECTION_MARKER = "<!-- repoos:managed-instructions -->";
@@ -400,6 +431,9 @@ const ENV_EXAMPLE = `# Copy to .env and fill in what you need — .env is gitign
400
431
  # --- Model providers / voice-to-text transcription ---
401
432
  # REPOOS_OPENROUTER_API_KEY=...
402
433
  # REPOOS_OPENCODE_GO_API_KEY=...
434
+ # REPOOS_DEEPINFRA_API_KEY=...
435
+ # REPOOS_GITHUB_COPILOT_TOKEN=... # classic PAT — billing endpoints reject fine-grained tokens
436
+ # REPOOS_GITHUB_COPILOT_SCOPE= # empty = personal plan; org:<name> / enterprise:<name> for centrally billed
403
437
  # REPOOS_WHISPER_KEY=... # or GROQ_API_KEY / OPENAI_API_KEY directly
404
438
 
405
439
  # --- Infrastructure ---
@@ -1,3 +1,4 @@
1
+ import { type CaptureEntry } from "../core/shot-plan.js";
1
2
  interface CmdShotOptions {
2
3
  route?: string;
3
4
  target?: string;
@@ -23,6 +24,48 @@ interface CmdShotOptions {
23
24
  export declare function isShotCaptureUnavailable(err: unknown): boolean;
24
25
  /** Parse `repoos shot [<route|url>] [flags]`; unknown/malformed args set `error`. */
25
26
  export declare function parseShotArgs(args: string[]): CmdShotOptions;
27
+ /** Everything the capture plan for one `repoos shot` invocation depends on. */
28
+ export interface CliShotPlanInput {
29
+ /** The task body, read for its `## Shots` declaration. */
30
+ body: string;
31
+ /** The positional route, when the caller typed one (not an absolute URL). */
32
+ route?: string;
33
+ /** `--selector`, when given. */
34
+ selector?: string;
35
+ /** Target names resolved from changed paths / the task's area / `--target`. */
36
+ targets: string[];
37
+ /** Per-target matched globs, for the fallback caption (#0603). */
38
+ matchedGlobs: ReadonlyMap<string, string[]>;
39
+ /** Targets whose matched files are docs content only (#0603). */
40
+ docsContentOnly: ReadonlySet<string>;
41
+ }
42
+ /** The plan plus the visible notes `cmdShot` prints alongside it. */
43
+ export interface CliShotPlan {
44
+ entries: CaptureEntry[];
45
+ /** Problems with the task's declared `## Shots` list itself. */
46
+ declaredErrors: string[];
47
+ /** Per-entry problems the plan builder reported. */
48
+ errors: string[];
49
+ /** Visible skip notes (docs-content-only targets, …). */
50
+ skips: string[];
51
+ }
52
+ /**
53
+ * The capture plan for one `repoos shot` run, as a pure function of the task
54
+ * body, the CLI flags and the resolved targets (#0610). Pulled out of
55
+ * `cmdShot` so the wiring is testable without a server, git or a browser: the
56
+ * bug it fixes — a typed route losing to the `/` fallback — lived in the single
57
+ * line that picked between two candidate plans, so no plan-level test could
58
+ * reach it.
59
+ *
60
+ * Precedence, documented in `user-docs/cli.md` and `repoos shot --help`: an
61
+ * explicit route/selector replaces the WHOLE declared list. A declared entry
62
+ * carries steps, a highlight and a label authored for its own route, so
63
+ * re-pointing entry #2 at a route the engineer typed would click selectors that
64
+ * may not exist there. The flag says "shoot this", not "shoot this instead of
65
+ * that entry" — and the fallback then carries the requested route to every
66
+ * resolved target, which is what it always meant.
67
+ */
68
+ export declare function buildCliShotPlan(input: CliShotPlanInput): CliShotPlan;
26
69
  /**
27
70
  * `repoos shot` entrypoint. Returns the process exit code: 0 on success (or a
28
71
  * clean skip has already been reported), 1 on a real failure.
@@ -21,8 +21,8 @@ import { findRepoRoot, loadConfig, mainCheckoutRoot, resolveServePort } from "..
21
21
  import { changedPathsVsBase, currentBranch } from "../core/git.js";
22
22
  import { createRepoOS } from "../core/repoos.js";
23
23
  import { captureShotPage } from "../core/shot-page.js";
24
- import { buildCapturePlan, parseShotPlan } from "../core/shot-plan.js";
25
- import { formatTargetList, resolveShotTargets, } from "../core/shot-targets.js";
24
+ import { buildCapturePlan, parseShotPlan, provenanceCaption, } from "../core/shot-plan.js";
25
+ import { describeTargetPathMatches, formatTargetList, resolveShotTargets, } from "../core/shot-targets.js";
26
26
  import { readServeLocks } from "./status.js";
27
27
  import { readLocalCliToken } from "../server/local-token.js";
28
28
  import { launchWebkit } from "./ui-harness.js";
@@ -137,6 +137,38 @@ function normalizedRoute(route) {
137
137
  return "/";
138
138
  return route.startsWith("/") ? route : `/${route}`;
139
139
  }
140
+ /**
141
+ * The capture plan for one `repoos shot` run, as a pure function of the task
142
+ * body, the CLI flags and the resolved targets (#0610). Pulled out of
143
+ * `cmdShot` so the wiring is testable without a server, git or a browser: the
144
+ * bug it fixes — a typed route losing to the `/` fallback — lived in the single
145
+ * line that picked between two candidate plans, so no plan-level test could
146
+ * reach it.
147
+ *
148
+ * Precedence, documented in `user-docs/cli.md` and `repoos shot --help`: an
149
+ * explicit route/selector replaces the WHOLE declared list. A declared entry
150
+ * carries steps, a highlight and a label authored for its own route, so
151
+ * re-pointing entry #2 at a route the engineer typed would click selectors that
152
+ * may not exist there. The flag says "shoot this", not "shoot this instead of
153
+ * that entry" — and the fallback then carries the requested route to every
154
+ * resolved target, which is what it always meant.
155
+ */
156
+ export function buildCliShotPlan(input) {
157
+ const pinned = Boolean(input.route || input.selector);
158
+ const declared = pinned ? { shots: [], errors: [] } : parseShotPlan(input.body);
159
+ const built = buildCapturePlan(input.targets, declared.shots, {
160
+ matchedGlobs: input.matchedGlobs,
161
+ docsContentOnly: input.docsContentOnly,
162
+ route: input.route,
163
+ selector: input.selector,
164
+ });
165
+ return {
166
+ entries: built.entries,
167
+ declaredErrors: declared.errors,
168
+ errors: built.errors,
169
+ skips: built.autoSkips,
170
+ };
171
+ }
140
172
  /** The task on the main checkout's board whose branch is `branch`, or by id. */
141
173
  function findTask(mainRoot, branch, taskId) {
142
174
  const index = createRepoOS(mainRoot).reindex();
@@ -208,9 +240,11 @@ async function uploadShot(port, taskId, token, input) {
208
240
  target: input.target,
209
241
  route: input.route,
210
242
  ...(input.label ? { label: input.label } : {}),
243
+ ...(input.provenance ? { provenance: input.provenance } : {}),
211
244
  name: input.target,
212
245
  mime: "image/png",
213
246
  data: input.data,
247
+ ...(input.warnings?.length ? { warnings: input.warnings } : {}),
214
248
  }),
215
249
  });
216
250
  }
@@ -239,13 +273,24 @@ export async function cmdShot(args) {
239
273
  Which page or state to capture can be declared in the task body: a
240
274
  "## Shots" section holding a fenced JSON list, one entry per shot:
241
275
 
242
- {"target": "default", "route": "/board", "label": "Board",
276
+ {"target": "default", "route": "/repository", "label": "Task drawer",
277
+ "highlight": ".drawer .task-title",
243
278
  "steps": [{"click": "button.new-task"}, {"waitMs": 300}]}
244
279
 
245
- (target/route/selector/label/steps; steps are click, fill + text,
246
- waitFor, or waitMs, using plain CSS selectors). The same list drives
247
- the server's automatic capture at handoff. Without it, "/" is captured
248
- per resolved target.
280
+ (target/route/selector/label/highlight/steps; steps are click, fill + text,
281
+ waitFor, or waitMs, using plain CSS selectors; highlight is an optional
282
+ selector outlined around the changed element before capture — say what
283
+ changed). The same list drives the server's automatic capture at handoff.
284
+ Without it, "/" is captured per resolved target — by this command when you
285
+ run it, and by the automatic capture only when the diff touches a UI
286
+ target's paths; diffs touching just tests or task notes stand down with a
287
+ visible "shots: skipped — no UI change to capture" note instead.
288
+
289
+ An explicit <route> or --selector replaces the declared list outright, and
290
+ applies to every resolved target: declared entries carry steps, a highlight
291
+ and a label written for their own route, so they are never re-pointed at a
292
+ route you typed. A named route also counts as the justification a
293
+ docs-content-only target needs, so it is captured instead of skipped.
249
294
 
250
295
  Arguments:
251
296
  <route|url> Route to capture on the preview (default "/"), or an
@@ -297,6 +342,8 @@ export async function cmdShot(args) {
297
342
  target: targets[0],
298
343
  route: opts.route,
299
344
  ...(opts.selector ? { selector: opts.selector } : {}),
345
+ // An absolute URL is the subject by construction; nothing to attribute.
346
+ provenance: { kind: "auto" },
300
347
  },
301
348
  ];
302
349
  }
@@ -325,25 +372,43 @@ export async function cmdShot(args) {
325
372
  }
326
373
  // The task's own `## Shots` declaration wins when the CLI flags did not
327
374
  // pin a route/selector — the engineer knows which page/state is visible.
328
- const declared = opts.route || opts.selector
329
- ? { shots: [], errors: [] }
330
- : parseShotPlan(task.body);
331
- for (const error of declared.errors) {
375
+ // Provenance + docs gate need the same match detail the server uses (#0603):
376
+ // which globs matched per target, and which targets matched docs content
377
+ // only (for those, a route-less declared shot or the blind `/` fallback is
378
+ // skipped — a docs home page shows the site, not the change; a route the
379
+ // caller typed by hand is the justification that skip asks for, so it is
380
+ // captured).
381
+ const matchedGlobs = new Map();
382
+ const docsContentOnly = new Set();
383
+ for (const match of describeTargetPathMatches(worktreeConfig.preview, changed)) {
384
+ matchedGlobs.set(match.target, match.globs);
385
+ if (match.contentOnly)
386
+ docsContentOnly.add(match.target);
387
+ }
388
+ // #0610: the requested route/selector is part of the plan, not a separate
389
+ // candidate that lost to the fallback's `/`.
390
+ const built = buildCliShotPlan({
391
+ body: task.body,
392
+ route: opts.route,
393
+ selector: opts.selector,
394
+ targets,
395
+ matchedGlobs,
396
+ docsContentOnly,
397
+ });
398
+ for (const error of built.declaredErrors) {
332
399
  console.error(c.yellow(" · ") + `declared shot list: ${error}`);
333
400
  }
334
- const built = buildCapturePlan(targets, declared.shots);
335
401
  for (const error of built.errors) {
336
402
  console.error(c.yellow(" · ") + error);
337
403
  }
338
- plan = built.entries.length
339
- ? built.entries
340
- : targets.map((target) => ({
341
- target,
342
- route: normalizedRoute(opts.route),
343
- ...(opts.selector ? { selector: opts.selector } : {}),
344
- }));
345
- if (built.entries.length) {
346
- console.log(c.dim(` plan: ${built.entries.map((e) => `${e.target}${e.label ? ` – ${e.label}` : ""}`).join(", ")}`));
404
+ for (const skip of built.skips) {
405
+ console.error(c.yellow(" · ") + `skipped: ${skip}`);
406
+ }
407
+ plan = built.entries;
408
+ if (plan.length > 0) {
409
+ console.log(c.dim(` plan: ${plan
410
+ .map((e) => `${e.target}${e.route === "/" ? "" : ` ${e.route}`}${e.label ? ` – ${e.label}` : ""}`)
411
+ .join(", ")}`));
347
412
  }
348
413
  }
349
414
  // Preview lifecycle is server-owned; the CLI only reaches it over HTTP. Prefer
@@ -406,11 +471,17 @@ export async function cmdShot(args) {
406
471
  : `${currentPreviewUrl}${normalizedRoute(entry.route)}`;
407
472
  const page = (await context.newPage());
408
473
  let png;
474
+ const warnings = [];
409
475
  try {
410
476
  await page.setViewportSize(opts.viewport);
411
- png = await captureShotPage(page, pageUrl, entry, {
412
- waitMs: opts.waitMs,
413
- fullPage: opts.fullPage,
477
+ png = await captureShotPage(page, pageUrl, entry, { waitMs: opts.waitMs, fullPage: opts.fullPage }, (selector, route) => {
478
+ warnings.push(`highlight ${selector} matched nothing on ${route}`);
479
+ console.error(c.yellow(" · ") +
480
+ `highlight "${selector}" matched nothing on ${route} — capture went ahead unhighlighted`);
481
+ }, (selector, route) => {
482
+ warnings.push(`selector ${selector} matched nothing on ${route}`);
483
+ console.error(c.yellow(" · ") +
484
+ `selector "${selector}" matched nothing on ${route} — capture used the whole window`);
414
485
  });
415
486
  }
416
487
  catch (err) {
@@ -424,7 +495,9 @@ export async function cmdShot(args) {
424
495
  target: entry.target,
425
496
  route: entry.route.startsWith("/") ? normalizedRoute(entry.route) : entry.route,
426
497
  ...(entry.label ? { label: entry.label } : {}),
498
+ provenance: provenanceCaption(entry.provenance),
427
499
  data: png.toString("base64"),
500
+ ...(warnings.length ? { warnings } : {}),
428
501
  });
429
502
  if (!uploaded.ok) {
430
503
  console.error(c.red(" ✗ ") + `storing the shot failed: ${uploaded.error}`);
@@ -438,7 +511,7 @@ export async function cmdShot(args) {
438
511
  url: uploaded.shot.url,
439
512
  });
440
513
  console.log(c.green(" ✔ ") +
441
- `${entry.target}${entry.label ? ` – ${entry.label}` : ""} → ${c.cyan(uploaded.shot.path)} ${c.dim(`(${Math.round(png.length / 1024)} KB)`)}`);
514
+ `${entry.target}${entry.highlight ? " · highlighted" : ""}${entry.label ? ` – ${entry.label}` : ""} → ${c.cyan(uploaded.shot.path)} ${c.dim(`(${Math.round(png.length / 1024)} KB)`)}`);
442
515
  }
443
516
  if (saved.length === 0) {
444
517
  console.error(c.yellow(" · ") + "No shots captured.");
@@ -72,15 +72,20 @@ export declare function cmdNote(args: string[]): void;
72
72
  /**
73
73
  * `repoos update <id> [--title ...] [--area ...] [--story ...] [--priority ...]
74
74
  * [--type ...] [--body ... | --body -] [--branch ...] [--assigned-to ai|human]
75
- * [--needs-input true|false] [--questions "Question one\nQuestion two"]`
75
+ * [--needs-input true|false] [--questions "Question one\nQuestion two"] [--depends-on ids]
76
+ * [--shots '<JSON list>' | --section "<heading>" --section-body ... | --force]`
76
77
  *
77
78
  * Writes directly via patchTaskFile (same path the server's PATCH route uses),
78
79
  * so it works with no HTTP round-trip and no session auth — this is the path
79
80
  * agents/scripts should use to edit task metadata instead of hitting the API.
80
81
  * `--body -` reads the new body from stdin, for large/multiline bodies.
82
+ * `--shots '<JSON list>'` validates and formats `## Shots` without clobbering
83
+ * the rest of the body. A full `--body` that drops spec headings (Problem /
84
+ * Desired UX / Acceptance criteria / Notes for AI) is refused unless `--force`
85
+ * is passed.
81
86
  */
82
87
  export declare function cmdUpdate(args: string[]): void;
83
- /** `repoos new <title> [--ai] [--needs-input true] [--questions "..."]` */
88
+ /** `repoos new <title> [--ai] [--needs-input true] [--questions "..."] [--depends-on ids]` */
84
89
  export declare function cmdNew(args: string[]): void;
85
90
  /** `repoos index [--json]` — rebuild cache; optionally print machine-readable JSON. */
86
91
  export declare function cmdIndex(args: string[]): void;