@repo-os/repoos 0.5.64 → 0.5.65

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 (158) hide show
  1. package/dist/.build-info.json +2 -2
  2. package/dist/.build-stamp.json +1 -1
  3. package/dist/cli/help.js +14 -2
  4. package/dist/cli/index.js +7 -0
  5. package/dist/commands/certify.d.ts +2 -0
  6. package/dist/commands/certify.js +69 -6
  7. package/dist/commands/check.d.ts +50 -0
  8. package/dist/commands/check.js +267 -8
  9. package/dist/commands/init.js +3 -1
  10. package/dist/commands/outline.d.ts +1 -0
  11. package/dist/commands/outline.js +51 -0
  12. package/dist/core/agent-compatibility.json +22 -22
  13. package/dist/core/agent-contract.d.ts +10 -0
  14. package/dist/core/agent-contract.js +36 -2
  15. package/dist/core/check-format.d.ts +23 -0
  16. package/dist/core/check-format.js +84 -0
  17. package/dist/core/check-plan.d.ts +13 -1
  18. package/dist/core/check-plan.js +15 -0
  19. package/dist/core/check-runner.d.ts +6 -0
  20. package/dist/core/check-store.d.ts +10 -0
  21. package/dist/core/check-store.js +16 -6
  22. package/dist/core/config.d.ts +1 -1
  23. package/dist/core/config.js +41 -0
  24. package/dist/core/context-pack.d.ts +28 -3
  25. package/dist/core/context-pack.js +43 -10
  26. package/dist/core/db.d.ts +11 -0
  27. package/dist/core/db.js +27 -3
  28. package/dist/core/keyword-rank.d.ts +118 -0
  29. package/dist/core/keyword-rank.js +231 -0
  30. package/dist/core/outline.d.ts +37 -0
  31. package/dist/core/outline.js +618 -0
  32. package/dist/core/repo-log.d.ts +16 -8
  33. package/dist/core/repo-log.js +39 -0
  34. package/dist/core/types.d.ts +22 -0
  35. package/dist/server/agents.d.ts +12 -0
  36. package/dist/server/agents.js +32 -2
  37. package/dist/server/cto-monitor.d.ts +21 -5
  38. package/dist/server/cto-monitor.js +88 -28
  39. package/dist/server/cto.d.ts +1 -1
  40. package/dist/server/cto.js +43 -8
  41. package/dist/server/handoff.js +21 -0
  42. package/dist/server/review.js +6 -0
  43. package/dist/server/routes/config.js +9 -0
  44. package/dist/server/routes/repo-log.d.ts +2 -0
  45. package/dist/server/routes/repo-log.js +14 -1
  46. package/dist/server/server.js +4 -1
  47. package/dist/ui/assets/{AgentsView-CLLCJ6AW.js → AgentsView-DC2kfIH_.js} +1 -1
  48. package/dist/ui/assets/ChecksView-BmdCOghF.css +1 -0
  49. package/dist/ui/assets/ChecksView-DwfZfOc9.js +0 -0
  50. package/dist/ui/assets/{ContextView-BRKEH19F.js → ContextView-2tUPHg0-.js} +2 -2
  51. package/dist/ui/assets/{DashboardView-MjXlMIuk.css → DashboardView-AGzNLRGm.css} +1 -1
  52. package/dist/ui/assets/{DashboardView-DCXBFRQz.js → DashboardView-BHv_FI1_.js} +1 -1
  53. package/dist/ui/assets/DiffView-DphAy_We.js +4 -0
  54. package/dist/ui/assets/DiffView-gEzzmiij.css +1 -0
  55. package/dist/ui/assets/{InputsView-36_PZvpn.js → InputsView-YBZYQo72.js} +1 -1
  56. package/dist/ui/assets/{LoginView-BjflJl_6.js → LoginView-BrQXEW51.js} +1 -1
  57. package/dist/ui/assets/ReleasesView-BQYf9YdH.js +5 -0
  58. package/dist/ui/assets/ReleasesView-CDa4RD79.css +1 -0
  59. package/dist/ui/assets/SettingsView-CwgTYYnZ.js +4 -0
  60. package/dist/ui/assets/{StoriesView-CifxEAYl.js → StoriesView-DHA8hQcu.js} +1 -1
  61. package/dist/ui/assets/{WorkView-bH-ScFce.js → WorkView-DYpJLDv-.js} +1 -1
  62. package/dist/ui/assets/{abnfDiagram-VCTEODGH-CVHYF-2B.js → abnfDiagram-VCTEODGH-D7K5xY21.js} +1 -1
  63. package/dist/ui/assets/architecture-7GRP2DOG-BILS7kzQ.js +1 -0
  64. package/dist/ui/assets/{architectureDiagram-5GKGNRK7-DNci99O0.js → architectureDiagram-5GKGNRK7-B_BA-0Uq.js} +1 -1
  65. package/dist/ui/assets/{blockDiagram-I7D4REHJ-_uKj9BoB.js → blockDiagram-I7D4REHJ-Cpb81UDE.js} +1 -1
  66. package/dist/ui/assets/{c4Diagram-7LVT6UL2-BCm84NDK.js → c4Diagram-7LVT6UL2-V3L4erkN.js} +1 -1
  67. package/dist/ui/assets/channel-C2fJCoOG.js +1 -0
  68. package/dist/ui/assets/{chunk-4HAMMTFA-B0SvItaq.js → chunk-4HAMMTFA-DEg9Tw-P.js} +1 -1
  69. package/dist/ui/assets/{chunk-75Z2AOVW-ByhyhHkE.js → chunk-75Z2AOVW-B3NLZ27i.js} +1 -1
  70. package/dist/ui/assets/{chunk-DU6HZSFF-DGHJT_EX.js → chunk-DU6HZSFF-DL1X-Drb.js} +1 -1
  71. package/dist/ui/assets/{chunk-F27PBJKO-DphXoQ_c.js → chunk-F27PBJKO-CtsVl7e2.js} +1 -1
  72. package/dist/ui/assets/{chunk-GMAD6QVW-CeOdTf1_.js → chunk-GMAD6QVW-DVbfeU88.js} +1 -1
  73. package/dist/ui/assets/{chunk-GVQU2GXP-DA6NZTDx.js → chunk-GVQU2GXP-DrRVvPhy.js} +1 -1
  74. package/dist/ui/assets/{chunk-IMKFNOWR-CWQzBfxw.js → chunk-IMKFNOWR-D9x4VaSZ.js} +1 -1
  75. package/dist/ui/assets/{chunk-L3NEJ4N5-Jjp-lf7l.js → chunk-L3NEJ4N5-CQ838V5P.js} +1 -1
  76. package/dist/ui/assets/{chunk-OSK3NFVY-CanEM2w7.js → chunk-OSK3NFVY-CscJ3Ugl.js} +1 -1
  77. package/dist/ui/assets/{chunk-P2QGCYS3-DcuoNMI1.js → chunk-P2QGCYS3-Dn_74uGA.js} +1 -1
  78. package/dist/ui/assets/{chunk-POPQ4Y6H-DLIgw2CT.js → chunk-POPQ4Y6H-BWQVTVVG.js} +1 -1
  79. package/dist/ui/assets/{chunk-PWAF6VOD-XuleFtHn.js → chunk-PWAF6VOD-BEip3UPe.js} +1 -1
  80. package/dist/ui/assets/{chunk-SHT3W25Y-CMO_67hc.js → chunk-SHT3W25Y-BBhLU2Ko.js} +1 -1
  81. package/dist/ui/assets/{chunk-SVP7TREG-DLelKGBr.js → chunk-SVP7TREG-BAIckYL1.js} +1 -1
  82. package/dist/ui/assets/{chunk-TICWLB2K-sACguoCN.js → chunk-TICWLB2K-DL38vvUq.js} +1 -1
  83. package/dist/ui/assets/classDiagram-ZZMXUADV-D2HbZ8pG.js +1 -0
  84. package/dist/ui/assets/classDiagram-v2-VYDZK3BY-D2HbZ8pG.js +1 -0
  85. package/dist/ui/assets/{cynefin-OW5HDTMX-DAkUUvXu.js → cynefin-OW5HDTMX-BtNk2QXI.js} +1 -1
  86. package/dist/ui/assets/{cynefinDiagram-5FMLGOSQ-Chsc32sw.js → cynefinDiagram-5FMLGOSQ-C1RB8hg-.js} +1 -1
  87. package/dist/ui/assets/{dagre-GXQ25YYZ-DiAMScnY.js → dagre-GXQ25YYZ-BK1Ciodj.js} +1 -1
  88. package/dist/ui/assets/{diagram-S7CK7UJ4-CR8P8aO5.js → diagram-S7CK7UJ4-C0Kgo7tc.js} +1 -1
  89. package/dist/ui/assets/{diagram-UQ7AKVKN-Ct84CouM.js → diagram-UQ7AKVKN-B64zLMX6.js} +1 -1
  90. package/dist/ui/assets/{diagram-VSXAHHWV-CoUoPKsA.js → diagram-VSXAHHWV-CzrxcSQH.js} +1 -1
  91. package/dist/ui/assets/{diagram-VX7I27RA-CCXAjAgW.js → diagram-VX7I27RA-yjdIqP0q.js} +1 -1
  92. package/dist/ui/assets/{diagram-Z3DM3KII-BHQBkQE-.js → diagram-Z3DM3KII-DOyxmmRK.js} +1 -1
  93. package/dist/ui/assets/{ebnfDiagram-PWID7BFC-Cvs4zLE6.js → ebnfDiagram-PWID7BFC-igftIl5p.js} +1 -1
  94. package/dist/ui/assets/{erDiagram-RLTQ6QDP-BNZr7oA5.js → erDiagram-RLTQ6QDP-D1YF1lZ2.js} +1 -1
  95. package/dist/ui/assets/eventmodeling-NTZA5JFV-Cq__3onz.js +1 -0
  96. package/dist/ui/assets/flowDiagram-HODETNUW-oqazLecl.js +1 -0
  97. package/dist/ui/assets/{ganttDiagram-EL5Y4UJY-D4y1dvLK.js → ganttDiagram-EL5Y4UJY-7cJOmpvL.js} +1 -1
  98. package/dist/ui/assets/{gitGraph-4MIJSDKK-DvGOpoGX.js → gitGraph-4MIJSDKK-vTrxvPkn.js} +1 -1
  99. package/dist/ui/assets/{gitGraphDiagram-WWUBYQGX-D3fKN22e.js → gitGraphDiagram-WWUBYQGX-BzFDa_ja.js} +1 -1
  100. package/dist/ui/assets/index-BzQofiD_.js +54 -0
  101. package/dist/ui/assets/index-CjufFN0L.css +1 -0
  102. package/dist/ui/assets/{info-A6RAGUB7-CG6_1t4v.js → info-A6RAGUB7-DZ5p-DTt.js} +1 -1
  103. package/dist/ui/assets/{infoDiagram-27XIBGKW-BZGXzyAi.js → infoDiagram-27XIBGKW-Dt9fTB-K.js} +1 -1
  104. package/dist/ui/assets/{ishikawaDiagram-5VMMS53U-28Q-yzl6.js → ishikawaDiagram-5VMMS53U-DzWqCZwA.js} +1 -1
  105. package/dist/ui/assets/{journeyDiagram-3NMN7TZE-NDtxuR9G.js → journeyDiagram-3NMN7TZE-DPqO0nTE.js} +1 -1
  106. package/dist/ui/assets/{kanban-definition-UXKFOSKX-BGoqQ8sU.js → kanban-definition-UXKFOSKX-Csmtd8-e.js} +1 -1
  107. package/dist/ui/assets/{line-BXWQsF8z.js → line-BhE0sIdC.js} +1 -1
  108. package/dist/ui/assets/{mermaid-parser.core-DGAd_8KH.js → mermaid-parser.core-DXuNQalk.js} +3 -3
  109. package/dist/ui/assets/{mermaid.core-BD0MSzMW.js → mermaid.core-CBbbhK6t.js} +4 -4
  110. package/dist/ui/assets/{mindmap-definition-YA3MSWOX-CDZKgZhH.js → mindmap-definition-YA3MSWOX-DVfGFieO.js} +1 -1
  111. package/dist/ui/assets/{packet-AYTQ26CC-Dni6tyV_.js → packet-AYTQ26CC-B1T01rik.js} +1 -1
  112. package/dist/ui/assets/{pegDiagram-XKGWAZYB-C5fozvsn.js → pegDiagram-XKGWAZYB-DX3MmX7k.js} +1 -1
  113. package/dist/ui/assets/{pie-WAS4IAKB-ff6I2ES-.js → pie-WAS4IAKB-CYWT14Ey.js} +1 -1
  114. package/dist/ui/assets/{pieDiagram-E7YTZNPT-CeLG9FfB.js → pieDiagram-E7YTZNPT-CnZwSuIL.js} +1 -1
  115. package/dist/ui/assets/{quadrantDiagram-AXDQQJYC-CkmW8Tj0.js → quadrantDiagram-AXDQQJYC-TlCorrVm.js} +1 -1
  116. package/dist/ui/assets/{radar-RG4KPBEZ-BDj-Xizd.js → radar-RG4KPBEZ-zD8NcNrm.js} +1 -1
  117. package/dist/ui/assets/{railroad-74A4TZTK-BzMG8WRw.js → railroad-74A4TZTK-CZZJ_fBU.js} +1 -1
  118. package/dist/ui/assets/railroad-abnf-HS5TGJTU-CfWwDqoE.js +1 -0
  119. package/dist/ui/assets/railroad-ebnf-LZEXJU2U-BHW-SzuB.js +1 -0
  120. package/dist/ui/assets/railroad-peg-WCYAUIDC-DqepkVj5.js +1 -0
  121. package/dist/ui/assets/{railroadDiagram-O6MQD6OU-DGgj7juY.js → railroadDiagram-O6MQD6OU-CcUsh2xT.js} +1 -1
  122. package/dist/ui/assets/{requirementDiagram-BXWQKSXE-Hosv7UOI.js → requirementDiagram-BXWQKSXE-BRs-m-IN.js} +1 -1
  123. package/dist/ui/assets/{sankeyDiagram-P5KCCOFB-DMJjO5XD.js → sankeyDiagram-P5KCCOFB-DZr6ULrz.js} +1 -1
  124. package/dist/ui/assets/{sequenceDiagram-WJ2MYXX4-Djna7B24.js → sequenceDiagram-WJ2MYXX4-DG3jgNAD.js} +1 -1
  125. package/dist/ui/assets/{stateDiagram-D77RDMKH-BFnhpU0l.js → stateDiagram-D77RDMKH-BdOc9c8v.js} +1 -1
  126. package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-C-B8vQtJ.js +1 -0
  127. package/dist/ui/assets/{swimlanes-42K2YHIH-PNlguaia.js → swimlanes-42K2YHIH-CNGoL8K1.js} +1 -1
  128. package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-l739H5Fp.js +8 -0
  129. package/dist/ui/assets/{timeline-definition-24CTP7MA-uORclcIS.js → timeline-definition-24CTP7MA-22MZfL5_.js} +1 -1
  130. package/dist/ui/assets/{treeView-Q6P3EWNA-BP_ISed5.js → treeView-Q6P3EWNA-BD4hTxfi.js} +1 -1
  131. package/dist/ui/assets/{treemap-WGGIJYW6--V-EhCEf.js → treemap-WGGIJYW6-Cemii_iW.js} +1 -1
  132. package/dist/ui/assets/{vennDiagram-4TSXK5OY-B96mS7FE.js → vennDiagram-4TSXK5OY-NxbwfKSB.js} +1 -1
  133. package/dist/ui/assets/{wardley-WFR3VGLG-CYGfXDZf.js → wardley-WFR3VGLG-CAkXWtRC.js} +1 -1
  134. package/dist/ui/assets/{wardleyDiagram-VM6X3IG4-C_qHUJEK.js → wardleyDiagram-VM6X3IG4-Ukj6iPYI.js} +1 -1
  135. package/dist/ui/assets/{xychartDiagram-S5SC5T6Z-D-iwVqdz.js → xychartDiagram-S5SC5T6Z-ESpPlWUQ.js} +1 -1
  136. package/dist/ui/index.html +2 -2
  137. package/dist/ui/sw.js +2 -2
  138. package/package.json +1 -1
  139. package/dist/ui/assets/ChecksView-DOMuC-Du.js +0 -0
  140. package/dist/ui/assets/ChecksView-MRswedqR.css +0 -1
  141. package/dist/ui/assets/DiffView-B9-i6C6C.css +0 -1
  142. package/dist/ui/assets/DiffView-By7Or-tt.js +0 -4
  143. package/dist/ui/assets/ReleasesView-B9reiAba.css +0 -1
  144. package/dist/ui/assets/ReleasesView-C367f6Z-.js +0 -3
  145. package/dist/ui/assets/SettingsView-MvAmqgCS.js +0 -4
  146. package/dist/ui/assets/architecture-7GRP2DOG-B7mPOijT.js +0 -1
  147. package/dist/ui/assets/channel-DC785MeQ.js +0 -1
  148. package/dist/ui/assets/classDiagram-ZZMXUADV-kAdq9jdR.js +0 -1
  149. package/dist/ui/assets/classDiagram-v2-VYDZK3BY-kAdq9jdR.js +0 -1
  150. package/dist/ui/assets/eventmodeling-NTZA5JFV-DL8OHcU1.js +0 -1
  151. package/dist/ui/assets/flowDiagram-HODETNUW-hqiZmPvO.js +0 -1
  152. package/dist/ui/assets/index-DRsQaKB6.css +0 -1
  153. package/dist/ui/assets/index-Rfjq1wMn.js +0 -54
  154. package/dist/ui/assets/railroad-abnf-HS5TGJTU-D6ImUE6q.js +0 -1
  155. package/dist/ui/assets/railroad-ebnf-LZEXJU2U-xmNsKCvd.js +0 -1
  156. package/dist/ui/assets/railroad-peg-WCYAUIDC-B1-OWQhz.js +0 -1
  157. package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-Dj2QV7iE.js +0 -1
  158. package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-D63RNwQp.js +0 -8
@@ -1,5 +1,5 @@
1
1
  {
2
- "hash": "fe42b7d3c5e92f40a7421aa079b19143152aaa5475d60de61c7098723741384f",
3
- "version": "0.5.64",
2
+ "hash": "5139d67402c747817a7237d45bbdf3dc259350732a389c4dc4f1037533e74fc0",
3
+ "version": "0.5.65",
4
4
  "devUi": false
5
5
  }
@@ -1,3 +1,3 @@
1
1
  {
2
- "generatedAt": "2026-10-04T11:13:13.008Z"
2
+ "generatedAt": "2026-10-05T04:53:51.934Z"
3
3
  }
package/dist/cli/help.js CHANGED
@@ -86,6 +86,17 @@ const GROUPS = [
86
86
  },
87
87
  ],
88
88
  },
89
+ {
90
+ name: "Code",
91
+ commands: [
92
+ {
93
+ name: "outline",
94
+ usage: "outline <file> [--json]",
95
+ desc: "Print a file's symbols and line ranges (read ranges, not whole files)",
96
+ flags: "--json",
97
+ },
98
+ ],
99
+ },
89
100
  {
90
101
  name: "Health",
91
102
  commands: [
@@ -109,9 +120,9 @@ const GROUPS = [
109
120
  },
110
121
  {
111
122
  name: "certify",
112
- usage: "certify <cli> [--yes] [--json] [--binary <path>]",
123
+ usage: "certify <cli> [--yes] [--json] [--force] [--binary <path>]",
113
124
  desc: "Run the adapter contract suite and record certification evidence",
114
- flags: "--yes · --json · --binary <path>",
125
+ flags: "--yes · --json · --force · --binary <path>",
115
126
  },
116
127
  {
117
128
  name: "support",
@@ -169,6 +180,7 @@ const EXAMPLES = [
169
180
  { cmd: 'repoos note 0012 "Handle the reviewer\'s suggestions before the next review"' },
170
181
  { cmd: 'repoos update 0012 --title "New title" --area web,core' },
171
182
  { cmd: "repoos list ready" },
183
+ { cmd: "repoos outline src/server/agents.ts", comment: "then read only the range you need" },
172
184
  { cmd: "repoos doctor", comment: "passing checks are hidden; --verbose shows all" },
173
185
  { cmd: "repoos shot", comment: "screenshot the task preview for the current worktree" },
174
186
  { cmd: "repoos shot /repo/commits/abc123", comment: "capture one route" },
package/dist/cli/index.js CHANGED
@@ -7,6 +7,7 @@ import { cmdInit } from "../commands/init.js";
7
7
  import { cmdList, cmdShow, cmdMv, cmdUpdate, cmdNew, cmdIndex, cmdNote, } from "../commands/tasks.js";
8
8
  import { cmdNewDoc } from "../commands/docs.js";
9
9
  import { cmdGc } from "../commands/gc.js";
10
+ import { cmdOutline } from "../commands/outline.js";
10
11
  import { cmdCheck } from "../commands/check.js";
11
12
  import { cmdShot } from "../commands/shot.js";
12
13
  import { cmdServe, serveProcessTitle, setServeProcessTitle } from "../commands/serve.js";
@@ -89,6 +90,9 @@ function main() {
89
90
  "-h",
90
91
  "upgrade",
91
92
  "uninstall",
93
+ // Read-only inspection of one file: the build-staleness hash is pure
94
+ // overhead here, and `outline` is meant to stay well under 200ms.
95
+ "outline",
92
96
  ]);
93
97
  if (!skipCheck.has(cmd)) {
94
98
  const result = checkBuild();
@@ -165,6 +169,9 @@ function main() {
165
169
  case "gc":
166
170
  cmdGc(rest);
167
171
  break;
172
+ case "outline":
173
+ cmdOutline(rest);
174
+ break;
168
175
  case "serve":
169
176
  case "server":
170
177
  void cmdServe(rest);
@@ -2,6 +2,8 @@ export interface CertifyCliArgs {
2
2
  cli: string | null;
3
3
  yes: boolean;
4
4
  json: boolean;
5
+ /** `--force`: run the probe even when this version is already certified. */
6
+ force: boolean;
5
7
  missingCli: boolean;
6
8
  /** Explicit binary path — skips PATH resolution and probes this binary directly. */
7
9
  binary: string | null;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `repoos certify <cli> [--yes] [--json]` — run the adapter contract suite and,
2
+ * `repoos certify <cli> [--yes] [--json] [--force]` — run the adapter contract suite and,
3
3
  * when every seam passes, write the certification evidence back into
4
4
  * `src/core/agent-compatibility.json` automatically.
5
5
  *
@@ -11,33 +11,40 @@
11
11
  * does — src/core/ in a dev checkout, dist/core/ in a built install — and
12
12
  * writes back to whichever file it loaded from.
13
13
  */
14
+ import { spawnSync } from "node:child_process";
14
15
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
15
16
  import { fileURLToPath } from "node:url";
16
17
  import { join } from "node:path";
17
- import { runAdapterContract } from "../core/agent-contract.js";
18
+ import { resolveProbeModel, runAdapterContract } from "../core/agent-contract.js";
18
19
  import { parseAgentVersion } from "../core/agent-compatibility.js";
20
+ import { KNOWN_AGENTS, resolveBinary } from "../core/detect.js";
19
21
  import { c } from "../cli/colors.js";
20
22
  export function parseCertifyArgs(argv) {
21
23
  const yes = argv.includes("--yes");
22
24
  const json = argv.includes("--json");
25
+ const force = argv.includes("--force");
23
26
  const binaryIdx = argv.indexOf("--binary");
24
27
  const binary = binaryIdx !== -1 ? (argv[binaryIdx + 1] ?? null) : null;
25
28
  const modelIdx = argv.indexOf("--model");
26
29
  const model = modelIdx !== -1 ? (argv[modelIdx + 1] ?? null) : null;
27
30
  const positional = argv.filter((a, i) => !a.startsWith("--") && argv[i - 1] !== "--binary" && argv[i - 1] !== "--model");
28
31
  const cli = positional[0] ?? null;
29
- return { cli, yes, json, missingCli: !cli, binary, model };
32
+ return { cli, yes, json, force, missingCli: !cli, binary, model };
30
33
  }
31
34
  /** Locate the live manifest file on disk (src or dist). */
32
35
  function findManifestPath() {
33
36
  const manifestUrl = new URL("../core/agent-compatibility.json", import.meta.url);
34
37
  const candidates = [];
38
+ // The committed manifest is src/'s copy; dist/ is gitignored build output, so
39
+ // a run from a built checkout must still write src/ or the evidence is lost.
40
+ candidates.push(join(process.cwd(), "src/core/agent-compatibility.json"));
35
41
  if (manifestUrl.protocol === "file:") {
36
42
  candidates.push(fileURLToPath(manifestUrl));
37
43
  }
38
- candidates.push(join(process.cwd(), "src/core/agent-compatibility.json"), join(process.cwd(), "dist/core/agent-compatibility.json"));
44
+ candidates.push(join(process.cwd(), "dist/core/agent-compatibility.json"));
39
45
  const root = process.env.REPOOS_ROOT;
40
46
  if (root) {
47
+ candidates.unshift(join(root, "src/core/agent-compatibility.json"));
41
48
  candidates.push(join(root, "src/core/agent-compatibility.json"), join(root, "dist/core/agent-compatibility.json"));
42
49
  }
43
50
  for (const p of candidates) {
@@ -57,14 +64,69 @@ function loadManifest(path) {
57
64
  function saveManifest(path, manifest) {
58
65
  writeFileSync(path, JSON.stringify(manifest, null, 2) + "\n", "utf8");
59
66
  }
67
+ /**
68
+ * The installed version when it is already covered by the manifest (equal to or
69
+ * older than `newestCertifiedVersion`), else null. Reads only `--version` — no
70
+ * tokens. Any doubt (missing binary, unparsable version, no entry) returns
71
+ * null so the probe runs.
72
+ */
73
+ function alreadyCertified(cli, binaryOverride) {
74
+ try {
75
+ const known = KNOWN_AGENTS.find((a) => a.cli === cli)?.binary;
76
+ const bin = binaryOverride ?? (known ? resolveBinary(known) : null);
77
+ if (!bin || !existsSync(bin))
78
+ return null;
79
+ const out = spawnSync(bin, ["--version"], { encoding: "utf8", timeout: 10_000 });
80
+ const installed = parseAgentVersion(`${out.stdout ?? ""}\n${out.stderr ?? ""}`);
81
+ const path = findManifestPath();
82
+ if (!installed || !path)
83
+ return null;
84
+ const entry = loadManifest(path).contracts.find((e) => e.cli === cli);
85
+ const newest = entry?.newestCertifiedVersion ?? null;
86
+ const newestParsed = newest ? parseAgentVersion(newest) : null;
87
+ if (!newest || !newestParsed)
88
+ return null;
89
+ for (let i = 0; i < 3; i++) {
90
+ if (installed[i] > newestParsed[i])
91
+ return null;
92
+ if (installed[i] < newestParsed[i])
93
+ break;
94
+ }
95
+ return { version: installed.join("."), newest };
96
+ }
97
+ catch {
98
+ return null;
99
+ }
100
+ }
60
101
  export async function cmdCertify(argv) {
61
- const { cli, yes, json: asJson, missingCli, binary, model } = parseCertifyArgs(argv);
102
+ const { cli, yes, json: asJson, force, missingCli, binary, model } = parseCertifyArgs(argv);
62
103
  if (missingCli || !cli) {
63
104
  console.error(c.red(" repoos certify needs a harness id, e.g. `repoos certify opencode`."));
64
105
  console.error(c.dim(" Use --binary <path> to probe a specific binary instead of PATH resolution."));
65
106
  process.exitCode = 1;
66
107
  return;
67
108
  }
109
+ // Skip by default when the installed version is already certified: the live
110
+ // probe spends provider tokens, and re-running it on a covered version only
111
+ // rewrites the date. `--force` re-probes anyway.
112
+ if (!force) {
113
+ const covered = alreadyCertified(cli, binary);
114
+ if (covered) {
115
+ if (asJson) {
116
+ console.log(JSON.stringify({ cli, skipped: true, version: covered.version }, null, 2));
117
+ }
118
+ else {
119
+ console.log("");
120
+ console.log(" " +
121
+ c.green("✔ Skipped") +
122
+ ` — ${cli} ${covered.version} is already certified` +
123
+ c.dim(` (newest certified: ${covered.newest}).`));
124
+ console.log(c.dim(" Use --force to re-run the live probe anyway."));
125
+ console.log("");
126
+ }
127
+ return;
128
+ }
129
+ }
68
130
  const WARNING = [
69
131
  "",
70
132
  c.yellow(c.bold("⚠ Live compatibility probe + manifest write")),
@@ -144,7 +206,8 @@ export async function cmdCertify(argv) {
144
206
  const manifest = loadManifest(manifestPath);
145
207
  const versionStr = result.detectedVersion ? result.detectedVersion.join(".") : null;
146
208
  const now = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
147
- const source = `repoos certify ${cli} live probe — ${result.capabilities.length}/${result.capabilities.length} seams passed on ${result.startedAt} against binary ${result.binary}`;
209
+ const probeModelUsed = resolveProbeModel(cli, "live", model);
210
+ const source = `repoos certify ${cli} live probe — ${result.capabilities.length}/${result.capabilities.length} seams passed on ${result.startedAt} against binary ${result.binary}${probeModelUsed ? ` on model ${probeModelUsed}` : ""}`;
148
211
  let contract = manifest.contracts.find((c) => c.cli === cli);
149
212
  if (!contract) {
150
213
  // Bootstrap a minimal contract for a harness that has no entry yet.
@@ -1,6 +1,7 @@
1
1
  import type { CheckContrastPair, CheckThemeScope, RepoOSConfig } from "../core/types.js";
2
2
  import { type CheckPlan, type CheckStep } from "../core/check-plan.js";
3
3
  import { type StepRunResult } from "../core/check-runner.js";
4
+ import { type CheckRunPhase } from "../core/check-store.js";
4
5
  /**
5
6
  * Bare `require(...)` calls guard (#0271 follow-up): this package is
6
7
  * `"type": "module"` (ESM) — a bare, un-shadowed `require` is undefined at
@@ -213,9 +214,36 @@ export interface CheckOptions {
213
214
  printPlan?: boolean;
214
215
  /** Skip the remote runner even when `remoteValidation.enabled` (#0520). */
215
216
  localTestsOnly?: boolean;
217
+ /**
218
+ * Run each `format` step's fixer before its check (#0651). Off by default,
219
+ * so the close-out gate still fails an unformatted committed tree; handoff
220
+ * opts in. `kind = "format"` fixes via the `fmt` script, or a step's `fix`.
221
+ */
222
+ fix?: boolean;
223
+ /** Only run these step names — backs `repoos check --step <name>` (#0651). */
224
+ steps?: string[];
216
225
  }
217
226
  /** Parse `repoos check` flags. Unknown flags are ignored, never fatal. */
218
227
  export declare function parseCheckArgs(argv?: string[]): CheckOptions;
228
+ /** Hard cap on failing files that get an isolation re-run (#0655). Above it,
229
+ * the failure is broad enough that per-file triage says nothing useful. */
230
+ export declare const MAX_ISOLATION_TRIAGE_FILES = 3;
231
+ /** The test file from a `file > suite > test` failed-test name. */
232
+ export declare function failedTestFile(name: string): string;
233
+ /**
234
+ * Unique, still-present test files from recorded failure names, in order.
235
+ * A filter naming a deleted file makes vitest exit 1 on "no test files found",
236
+ * which would be a false failed-first failure — so drop paths that don't exist.
237
+ */
238
+ export declare function failedTestFiles(names: string[], repoRoot: string): string[];
239
+ /**
240
+ * Args appended after `--` that scope a project's test script to `files`, or
241
+ * null when the script can't be scoped that way (#0655). RepoOS's own two-pass
242
+ * runner gets its dedicated `--failed-first` single-pass mode (so the
243
+ * latency-sensitive isolated pass is skipped); a plain vitest/jest script
244
+ * accepts positional file filters.
245
+ */
246
+ export declare function testFileFilterArgs(testScript: string | undefined, files: string[]): string[] | null;
219
247
  /**
220
248
  * Repo-relative paths that differ from `ref`, plus anything uncommitted or
221
249
  * untracked — the working tree an agent actually hands over, not just what is
@@ -236,6 +264,14 @@ export interface RunPlanOptions {
236
264
  changedPaths?: string[];
237
265
  /** Git ref the changed paths came from — the Tests step scopes itself to it. */
238
266
  changedRef?: string;
267
+ /** Run each `format` step's fixer before its check (#0651). */
268
+ fix?: boolean;
269
+ /** Only run these step names (`repoos check --step`). Empty means all. */
270
+ stepNames?: string[];
271
+ /** Failing test names from the previous run, for failed-first ordering (#0655). */
272
+ previousFailedTests?: string[];
273
+ /** Isolation re-runs per failing file for the flake-triage label (#0655). */
274
+ isolationRuns?: number;
239
275
  onStart?: (step: CheckStep) => void;
240
276
  onResult?: (result: StepRunResult) => void;
241
277
  }
@@ -251,3 +287,17 @@ export interface RunPlanOptions {
251
287
  */
252
288
  export declare function runCheckPlan(plan: CheckPlan, opts: RunPlanOptions): Promise<StepRunResult[]>;
253
289
  export declare function cmdCheck(argv?: string[]): Promise<void>;
290
+ /**
291
+ * Failing test names from this task's most recent run (#0655), or none. Only
292
+ * when that most recent run actually failed — once a run is green, the next
293
+ * `repoos check` starts from a clean slate. Interactive/CLI and pre-review
294
+ * only: close-out and release always run the full suite. Fail-soft.
295
+ */
296
+ export declare function previousFailedTestsForRun(opts: {
297
+ root: string;
298
+ cacheDir: string;
299
+ /** Absolute worktree path the new run will execute in, when known. */
300
+ worktree?: string;
301
+ taskId: string | null;
302
+ phase: CheckRunPhase;
303
+ }): string[];