@vibe-agent-toolkit/cli 0.2.0-rc.1 → 0.2.0-rc.11

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 (504) hide show
  1. package/README.md +4 -5
  2. package/dist/bin/vat +97 -28
  3. package/dist/bin/vat.js +97 -28
  4. package/dist/bin/vat.js.map +1 -1
  5. package/dist/bin.js +115 -76
  6. package/dist/bin.js.map +1 -1
  7. package/dist/command-loaders.d.ts +44 -0
  8. package/dist/command-loaders.d.ts.map +1 -0
  9. package/dist/command-loaders.js +60 -0
  10. package/dist/command-loaders.js.map +1 -0
  11. package/dist/commands/agent/build.d.ts.map +1 -1
  12. package/dist/commands/agent/build.js +2 -1
  13. package/dist/commands/agent/build.js.map +1 -1
  14. package/dist/commands/agent/import.d.ts.map +1 -1
  15. package/dist/commands/agent/import.js +3 -2
  16. package/dist/commands/agent/import.js.map +1 -1
  17. package/dist/commands/agent/index.js +1 -1
  18. package/dist/commands/agent/install-path.d.ts +36 -0
  19. package/dist/commands/agent/install-path.d.ts.map +1 -0
  20. package/dist/commands/agent/install-path.js +44 -0
  21. package/dist/commands/agent/install-path.js.map +1 -0
  22. package/dist/commands/agent/install.d.ts.map +1 -1
  23. package/dist/commands/agent/install.js +66 -13
  24. package/dist/commands/agent/install.js.map +1 -1
  25. package/dist/commands/agent/installed.d.ts.map +1 -1
  26. package/dist/commands/agent/installed.js +22 -12
  27. package/dist/commands/agent/installed.js.map +1 -1
  28. package/dist/commands/agent/list.d.ts.map +1 -1
  29. package/dist/commands/agent/list.js +2 -1
  30. package/dist/commands/agent/list.js.map +1 -1
  31. package/dist/commands/agent/run.d.ts.map +1 -1
  32. package/dist/commands/agent/run.js +2 -1
  33. package/dist/commands/agent/run.js.map +1 -1
  34. package/dist/commands/agent/uninstall.d.ts.map +1 -1
  35. package/dist/commands/agent/uninstall.js +13 -6
  36. package/dist/commands/agent/uninstall.js.map +1 -1
  37. package/dist/commands/agent/validate.d.ts.map +1 -1
  38. package/dist/commands/agent/validate.js +3 -2
  39. package/dist/commands/agent/validate.js.map +1 -1
  40. package/dist/commands/ard/emit.d.ts +165 -0
  41. package/dist/commands/ard/emit.d.ts.map +1 -0
  42. package/dist/commands/ard/emit.js +338 -0
  43. package/dist/commands/ard/emit.js.map +1 -0
  44. package/dist/commands/ard/index.d.ts +12 -0
  45. package/dist/commands/ard/index.d.ts.map +1 -0
  46. package/dist/commands/ard/index.js +84 -0
  47. package/dist/commands/ard/index.js.map +1 -0
  48. package/dist/commands/ard/surfaces.d.ts +56 -0
  49. package/dist/commands/ard/surfaces.d.ts.map +1 -0
  50. package/dist/commands/ard/surfaces.js +150 -0
  51. package/dist/commands/ard/surfaces.js.map +1 -0
  52. package/dist/commands/audit/distributed-tree.d.ts +2 -2
  53. package/dist/commands/audit/distributed-tree.d.ts.map +1 -1
  54. package/dist/commands/audit/distributed-tree.js +11 -7
  55. package/dist/commands/audit/distributed-tree.js.map +1 -1
  56. package/dist/commands/audit/git-url-clone.d.ts +1 -1
  57. package/dist/commands/audit/git-url-clone.d.ts.map +1 -1
  58. package/dist/commands/audit/git-url-clone.js.map +1 -1
  59. package/dist/commands/audit/hierarchical-output.d.ts +1 -1
  60. package/dist/commands/audit/hierarchical-output.d.ts.map +1 -1
  61. package/dist/commands/audit/hierarchical-output.js +1 -1
  62. package/dist/commands/audit/hierarchical-output.js.map +1 -1
  63. package/dist/commands/audit/provenance.d.ts.map +1 -1
  64. package/dist/commands/audit/provenance.js +4 -3
  65. package/dist/commands/audit/provenance.js.map +1 -1
  66. package/dist/commands/audit/scan-population.d.ts +158 -0
  67. package/dist/commands/audit/scan-population.d.ts.map +1 -0
  68. package/dist/commands/audit/scan-population.js +292 -0
  69. package/dist/commands/audit/scan-population.js.map +1 -0
  70. package/dist/commands/audit-settings.d.ts.map +1 -1
  71. package/dist/commands/audit-settings.js +6 -5
  72. package/dist/commands/audit-settings.js.map +1 -1
  73. package/dist/commands/audit.d.ts +98 -8
  74. package/dist/commands/audit.d.ts.map +1 -1
  75. package/dist/commands/audit.js +1150 -394
  76. package/dist/commands/audit.js.map +1 -1
  77. package/dist/commands/build.d.ts +1 -1
  78. package/dist/commands/build.d.ts.map +1 -1
  79. package/dist/commands/build.js +40 -36
  80. package/dist/commands/build.js.map +1 -1
  81. package/dist/commands/cache/cache-control.d.ts +82 -0
  82. package/dist/commands/cache/cache-control.d.ts.map +1 -0
  83. package/dist/commands/cache/cache-control.js +86 -0
  84. package/dist/commands/cache/cache-control.js.map +1 -0
  85. package/dist/commands/cache/clear.d.ts +34 -6
  86. package/dist/commands/cache/clear.d.ts.map +1 -1
  87. package/dist/commands/cache/clear.js +101 -15
  88. package/dist/commands/cache/clear.js.map +1 -1
  89. package/dist/commands/cache/index.d.ts +13 -63
  90. package/dist/commands/cache/index.d.ts.map +1 -1
  91. package/dist/commands/cache/index.js +47 -79
  92. package/dist/commands/cache/index.js.map +1 -1
  93. package/dist/commands/claude/claude-config.d.ts.map +1 -1
  94. package/dist/commands/claude/claude-config.js +6 -0
  95. package/dist/commands/claude/claude-config.js.map +1 -1
  96. package/dist/commands/claude/context.d.ts +372 -0
  97. package/dist/commands/claude/context.d.ts.map +1 -0
  98. package/dist/commands/claude/context.js +1115 -0
  99. package/dist/commands/claude/context.js.map +1 -0
  100. package/dist/commands/claude/index.d.ts +14 -0
  101. package/dist/commands/claude/index.d.ts.map +1 -1
  102. package/dist/commands/claude/index.js +22 -2
  103. package/dist/commands/claude/index.js.map +1 -1
  104. package/dist/commands/claude/marketplace/changelog-utils.d.ts +1 -1
  105. package/dist/commands/claude/marketplace/changelog-utils.d.ts.map +1 -1
  106. package/dist/commands/claude/marketplace/changelog-utils.js +1 -2
  107. package/dist/commands/claude/marketplace/changelog-utils.js.map +1 -1
  108. package/dist/commands/claude/marketplace/git-publish.d.ts.map +1 -1
  109. package/dist/commands/claude/marketplace/git-publish.js +40 -31
  110. package/dist/commands/claude/marketplace/git-publish.js.map +1 -1
  111. package/dist/commands/claude/marketplace/license-utils.d.ts.map +1 -1
  112. package/dist/commands/claude/marketplace/license-utils.js +0 -1
  113. package/dist/commands/claude/marketplace/license-utils.js.map +1 -1
  114. package/dist/commands/claude/marketplace/publish-tree.d.ts.map +1 -1
  115. package/dist/commands/claude/marketplace/publish-tree.js +0 -6
  116. package/dist/commands/claude/marketplace/publish-tree.js.map +1 -1
  117. package/dist/commands/claude/marketplace/publish.d.ts.map +1 -1
  118. package/dist/commands/claude/marketplace/publish.js +2 -1
  119. package/dist/commands/claude/marketplace/publish.js.map +1 -1
  120. package/dist/commands/claude/marketplace/validate.d.ts +73 -22
  121. package/dist/commands/claude/marketplace/validate.d.ts.map +1 -1
  122. package/dist/commands/claude/marketplace/validate.js +407 -72
  123. package/dist/commands/claude/marketplace/validate.js.map +1 -1
  124. package/dist/commands/claude/org/api-keys.d.ts +0 -3
  125. package/dist/commands/claude/org/api-keys.d.ts.map +1 -1
  126. package/dist/commands/claude/org/api-keys.js +2 -1
  127. package/dist/commands/claude/org/api-keys.js.map +1 -1
  128. package/dist/commands/claude/org/helpers.d.ts +54 -1
  129. package/dist/commands/claude/org/helpers.d.ts.map +1 -1
  130. package/dist/commands/claude/org/helpers.js +42 -7
  131. package/dist/commands/claude/org/helpers.js.map +1 -1
  132. package/dist/commands/claude/org/index.d.ts.map +1 -1
  133. package/dist/commands/claude/org/index.js +24 -16
  134. package/dist/commands/claude/org/index.js.map +1 -1
  135. package/dist/commands/claude/org/invites.d.ts +0 -3
  136. package/dist/commands/claude/org/invites.d.ts.map +1 -1
  137. package/dist/commands/claude/org/invites.js +3 -2
  138. package/dist/commands/claude/org/invites.js.map +1 -1
  139. package/dist/commands/claude/org/skills.d.ts +527 -0
  140. package/dist/commands/claude/org/skills.d.ts.map +1 -1
  141. package/dist/commands/claude/org/skills.js +1414 -108
  142. package/dist/commands/claude/org/skills.js.map +1 -1
  143. package/dist/commands/claude/org/users.d.ts +0 -3
  144. package/dist/commands/claude/org/users.d.ts.map +1 -1
  145. package/dist/commands/claude/org/users.js +6 -3
  146. package/dist/commands/claude/org/users.js.map +1 -1
  147. package/dist/commands/claude/org/workspaces.d.ts +0 -3
  148. package/dist/commands/claude/org/workspaces.d.ts.map +1 -1
  149. package/dist/commands/claude/org/workspaces.js +11 -7
  150. package/dist/commands/claude/org/workspaces.js.map +1 -1
  151. package/dist/commands/claude/plugin/build.d.ts +41 -3
  152. package/dist/commands/claude/plugin/build.d.ts.map +1 -1
  153. package/dist/commands/claude/plugin/build.js +147 -80
  154. package/dist/commands/claude/plugin/build.js.map +1 -1
  155. package/dist/commands/claude/plugin/helpers.d.ts.map +1 -1
  156. package/dist/commands/claude/plugin/helpers.js +2 -7
  157. package/dist/commands/claude/plugin/helpers.js.map +1 -1
  158. package/dist/commands/claude/plugin/install.d.ts +12 -0
  159. package/dist/commands/claude/plugin/install.d.ts.map +1 -1
  160. package/dist/commands/claude/plugin/install.js +93 -62
  161. package/dist/commands/claude/plugin/install.js.map +1 -1
  162. package/dist/commands/claude/plugin/list.d.ts.map +1 -1
  163. package/dist/commands/claude/plugin/list.js +3 -2
  164. package/dist/commands/claude/plugin/list.js.map +1 -1
  165. package/dist/commands/claude/plugin/marketplace-json.d.ts +24 -9
  166. package/dist/commands/claude/plugin/marketplace-json.d.ts.map +1 -1
  167. package/dist/commands/claude/plugin/marketplace-json.js +10 -9
  168. package/dist/commands/claude/plugin/marketplace-json.js.map +1 -1
  169. package/dist/commands/claude/plugin/plugin-changelog.d.ts.map +1 -1
  170. package/dist/commands/claude/plugin/plugin-changelog.js +0 -2
  171. package/dist/commands/claude/plugin/plugin-changelog.js.map +1 -1
  172. package/dist/commands/claude/plugin/plugin-files.d.ts.map +1 -1
  173. package/dist/commands/claude/plugin/plugin-files.js +3 -6
  174. package/dist/commands/claude/plugin/plugin-files.js.map +1 -1
  175. package/dist/commands/claude/plugin/plugin-validators.d.ts.map +1 -1
  176. package/dist/commands/claude/plugin/plugin-validators.js +3 -6
  177. package/dist/commands/claude/plugin/plugin-validators.js.map +1 -1
  178. package/dist/commands/claude/plugin/tree-copy.d.ts +73 -0
  179. package/dist/commands/claude/plugin/tree-copy.d.ts.map +1 -1
  180. package/dist/commands/claude/plugin/tree-copy.js +221 -14
  181. package/dist/commands/claude/plugin/tree-copy.js.map +1 -1
  182. package/dist/commands/claude/plugin/uninstall.d.ts.map +1 -1
  183. package/dist/commands/claude/plugin/uninstall.js +4 -4
  184. package/dist/commands/claude/plugin/uninstall.js.map +1 -1
  185. package/dist/commands/consistency-check.d.ts +17 -15
  186. package/dist/commands/consistency-check.d.ts.map +1 -1
  187. package/dist/commands/consistency-check.js +152 -106
  188. package/dist/commands/consistency-check.js.map +1 -1
  189. package/dist/commands/corpus/index.d.ts.map +1 -1
  190. package/dist/commands/corpus/index.js +3 -0
  191. package/dist/commands/corpus/index.js.map +1 -1
  192. package/dist/commands/corpus/report.d.ts +1 -2
  193. package/dist/commands/corpus/report.d.ts.map +1 -1
  194. package/dist/commands/corpus/report.js +1 -3
  195. package/dist/commands/corpus/report.js.map +1 -1
  196. package/dist/commands/corpus/runner.d.ts +58 -1
  197. package/dist/commands/corpus/runner.d.ts.map +1 -1
  198. package/dist/commands/corpus/runner.js +95 -41
  199. package/dist/commands/corpus/runner.js.map +1 -1
  200. package/dist/commands/corpus/scan.d.ts.map +1 -1
  201. package/dist/commands/corpus/scan.js +20 -12
  202. package/dist/commands/corpus/scan.js.map +1 -1
  203. package/dist/commands/corpus/seed.d.ts +4 -4
  204. package/dist/commands/corpus/seed.d.ts.map +1 -1
  205. package/dist/commands/corpus/seed.js +1 -3
  206. package/dist/commands/corpus/seed.js.map +1 -1
  207. package/dist/commands/doctor.d.ts +50 -0
  208. package/dist/commands/doctor.d.ts.map +1 -1
  209. package/dist/commands/doctor.js +245 -52
  210. package/dist/commands/doctor.js.map +1 -1
  211. package/dist/commands/inventory.d.ts +13 -1
  212. package/dist/commands/inventory.d.ts.map +1 -1
  213. package/dist/commands/inventory.js +121 -17
  214. package/dist/commands/inventory.js.map +1 -1
  215. package/dist/commands/mcp/collections.d.ts +1 -1
  216. package/dist/commands/mcp/collections.d.ts.map +1 -1
  217. package/dist/commands/mcp/list-collections.d.ts.map +1 -1
  218. package/dist/commands/mcp/list-collections.js +2 -1
  219. package/dist/commands/mcp/list-collections.js.map +1 -1
  220. package/dist/commands/mcp/serve.d.ts.map +1 -1
  221. package/dist/commands/mcp/serve.js +3 -2
  222. package/dist/commands/mcp/serve.js.map +1 -1
  223. package/dist/commands/okf/index.d.ts +11 -0
  224. package/dist/commands/okf/index.d.ts.map +1 -0
  225. package/dist/commands/okf/index.js +116 -0
  226. package/dist/commands/okf/index.js.map +1 -0
  227. package/dist/commands/okf/validate.d.ts +195 -0
  228. package/dist/commands/okf/validate.d.ts.map +1 -0
  229. package/dist/commands/okf/validate.js +199 -0
  230. package/dist/commands/okf/validate.js.map +1 -0
  231. package/dist/commands/phase-utils.d.ts +182 -114
  232. package/dist/commands/phase-utils.d.ts.map +1 -1
  233. package/dist/commands/phase-utils.js +154 -163
  234. package/dist/commands/phase-utils.js.map +1 -1
  235. package/dist/commands/positional-args.d.ts.map +1 -1
  236. package/dist/commands/positional-args.js +3 -2
  237. package/dist/commands/positional-args.js.map +1 -1
  238. package/dist/commands/rag/clear-command.d.ts.map +1 -1
  239. package/dist/commands/rag/clear-command.js +2 -1
  240. package/dist/commands/rag/clear-command.js.map +1 -1
  241. package/dist/commands/rag/index-command.d.ts +64 -0
  242. package/dist/commands/rag/index-command.d.ts.map +1 -1
  243. package/dist/commands/rag/index-command.js +72 -6
  244. package/dist/commands/rag/index-command.js.map +1 -1
  245. package/dist/commands/rag/index.d.ts.map +1 -1
  246. package/dist/commands/rag/index.js +23 -10
  247. package/dist/commands/rag/index.js.map +1 -1
  248. package/dist/commands/rag/query-command.d.ts.map +1 -1
  249. package/dist/commands/rag/query-command.js +2 -1
  250. package/dist/commands/rag/query-command.js.map +1 -1
  251. package/dist/commands/rag/stats-command.d.ts.map +1 -1
  252. package/dist/commands/rag/stats-command.js +2 -1
  253. package/dist/commands/rag/stats-command.js.map +1 -1
  254. package/dist/commands/resources/builtin-help.d.ts +27 -0
  255. package/dist/commands/resources/builtin-help.d.ts.map +1 -0
  256. package/dist/commands/resources/builtin-help.js +46 -0
  257. package/dist/commands/resources/builtin-help.js.map +1 -0
  258. package/dist/commands/resources/check-progress.d.ts +167 -0
  259. package/dist/commands/resources/check-progress.d.ts.map +1 -0
  260. package/dist/commands/resources/check-progress.js +250 -0
  261. package/dist/commands/resources/check-progress.js.map +1 -0
  262. package/dist/commands/resources/check-supervisor.d.ts +479 -0
  263. package/dist/commands/resources/check-supervisor.d.ts.map +1 -0
  264. package/dist/commands/resources/check-supervisor.js +587 -0
  265. package/dist/commands/resources/check-supervisor.js.map +1 -0
  266. package/dist/commands/resources/check.d.ts +620 -0
  267. package/dist/commands/resources/check.d.ts.map +1 -0
  268. package/dist/commands/resources/check.js +1452 -0
  269. package/dist/commands/resources/check.js.map +1 -0
  270. package/dist/commands/resources/index.d.ts.map +1 -1
  271. package/dist/commands/resources/index.js +430 -4
  272. package/dist/commands/resources/index.js.map +1 -1
  273. package/dist/commands/resources/query.d.ts +106 -0
  274. package/dist/commands/resources/query.d.ts.map +1 -0
  275. package/dist/commands/resources/query.js +177 -0
  276. package/dist/commands/resources/query.js.map +1 -0
  277. package/dist/commands/resources/scan.d.ts +24 -0
  278. package/dist/commands/resources/scan.d.ts.map +1 -1
  279. package/dist/commands/resources/scan.js +17 -8
  280. package/dist/commands/resources/scan.js.map +1 -1
  281. package/dist/commands/resources/validate.d.ts +42 -2
  282. package/dist/commands/resources/validate.d.ts.map +1 -1
  283. package/dist/commands/resources/validate.js +208 -55
  284. package/dist/commands/resources/validate.js.map +1 -1
  285. package/dist/commands/skill/review-checklist.d.ts +3 -2
  286. package/dist/commands/skill/review-checklist.d.ts.map +1 -1
  287. package/dist/commands/skill/review-checklist.js +40 -2
  288. package/dist/commands/skill/review-checklist.js.map +1 -1
  289. package/dist/commands/skill/review.d.ts +247 -0
  290. package/dist/commands/skill/review.d.ts.map +1 -1
  291. package/dist/commands/skill/review.js +100 -62
  292. package/dist/commands/skill/review.js.map +1 -1
  293. package/dist/commands/skill/test/configure.d.ts +56 -0
  294. package/dist/commands/skill/test/configure.d.ts.map +1 -1
  295. package/dist/commands/skill/test/configure.js +75 -16
  296. package/dist/commands/skill/test/configure.js.map +1 -1
  297. package/dist/commands/skill/test/run.d.ts +63 -10
  298. package/dist/commands/skill/test/run.d.ts.map +1 -1
  299. package/dist/commands/skill/test/run.js +258 -77
  300. package/dist/commands/skill/test/run.js.map +1 -1
  301. package/dist/commands/skills/build.d.ts +94 -4
  302. package/dist/commands/skills/build.d.ts.map +1 -1
  303. package/dist/commands/skills/build.js +325 -97
  304. package/dist/commands/skills/build.js.map +1 -1
  305. package/dist/commands/skills/install.d.ts +2 -1
  306. package/dist/commands/skills/install.d.ts.map +1 -1
  307. package/dist/commands/skills/install.js +20 -31
  308. package/dist/commands/skills/install.js.map +1 -1
  309. package/dist/commands/skills/list.d.ts +2 -1
  310. package/dist/commands/skills/list.d.ts.map +1 -1
  311. package/dist/commands/skills/list.js +44 -26
  312. package/dist/commands/skills/list.js.map +1 -1
  313. package/dist/commands/skills/package.d.ts +1 -1
  314. package/dist/commands/skills/package.d.ts.map +1 -1
  315. package/dist/commands/skills/package.js +6 -8
  316. package/dist/commands/skills/package.js.map +1 -1
  317. package/dist/commands/skills/scope-guard.d.ts.map +1 -1
  318. package/dist/commands/skills/scope-guard.js +8 -6
  319. package/dist/commands/skills/scope-guard.js.map +1 -1
  320. package/dist/commands/skills/shared.d.ts.map +1 -1
  321. package/dist/commands/skills/shared.js +2 -4
  322. package/dist/commands/skills/shared.js.map +1 -1
  323. package/dist/commands/skills/skill-discovery.d.ts +47 -6
  324. package/dist/commands/skills/skill-discovery.d.ts.map +1 -1
  325. package/dist/commands/skills/skill-discovery.js +61 -11
  326. package/dist/commands/skills/skill-discovery.js.map +1 -1
  327. package/dist/commands/skills/source-resolvers.d.ts +15 -0
  328. package/dist/commands/skills/source-resolvers.d.ts.map +1 -1
  329. package/dist/commands/skills/source-resolvers.js +25 -4
  330. package/dist/commands/skills/source-resolvers.js.map +1 -1
  331. package/dist/commands/skills/validate-command.d.ts.map +1 -1
  332. package/dist/commands/skills/validate-command.js +11 -3
  333. package/dist/commands/skills/validate-command.js.map +1 -1
  334. package/dist/commands/skills/validate.d.ts +140 -4
  335. package/dist/commands/skills/validate.d.ts.map +1 -1
  336. package/dist/commands/skills/validate.js +224 -67
  337. package/dist/commands/skills/validate.js.map +1 -1
  338. package/dist/commands/validate.d.ts +1 -1
  339. package/dist/commands/validate.d.ts.map +1 -1
  340. package/dist/commands/validate.js +63 -27
  341. package/dist/commands/validate.js.map +1 -1
  342. package/dist/commands/verify.d.ts +119 -15
  343. package/dist/commands/verify.d.ts.map +1 -1
  344. package/dist/commands/verify.js +357 -142
  345. package/dist/commands/verify.js.map +1 -1
  346. package/dist/index.d.ts +0 -1
  347. package/dist/index.d.ts.map +1 -1
  348. package/dist/index.js +5 -1
  349. package/dist/index.js.map +1 -1
  350. package/dist/report-schemas.d.ts +45 -0
  351. package/dist/report-schemas.d.ts.map +1 -0
  352. package/dist/report-schemas.js +100 -0
  353. package/dist/report-schemas.js.map +1 -0
  354. package/dist/skill-resolution/classify.js +2 -2
  355. package/dist/skill-resolution/classify.js.map +1 -1
  356. package/dist/skill-resolution/packaging-config.d.ts +49 -5
  357. package/dist/skill-resolution/packaging-config.d.ts.map +1 -1
  358. package/dist/skill-resolution/packaging-config.js +59 -19
  359. package/dist/skill-resolution/packaging-config.js.map +1 -1
  360. package/dist/skill-resolution/resolve-skill-reference.d.ts.map +1 -1
  361. package/dist/skill-resolution/resolve-skill-reference.js +55 -57
  362. package/dist/skill-resolution/resolve-skill-reference.js.map +1 -1
  363. package/dist/utils/agent-discovery.d.ts.map +1 -1
  364. package/dist/utils/agent-discovery.js +22 -11
  365. package/dist/utils/agent-discovery.js.map +1 -1
  366. package/dist/utils/agent-runner.d.ts.map +1 -1
  367. package/dist/utils/agent-runner.js +7 -4
  368. package/dist/utils/agent-runner.js.map +1 -1
  369. package/dist/utils/claude-context-lens.d.ts +34 -0
  370. package/dist/utils/claude-context-lens.d.ts.map +1 -0
  371. package/dist/utils/claude-context-lens.js +39 -0
  372. package/dist/utils/claude-context-lens.js.map +1 -0
  373. package/dist/utils/command-error.d.ts +143 -20
  374. package/dist/utils/command-error.d.ts.map +1 -1
  375. package/dist/utils/command-error.js +179 -36
  376. package/dist/utils/command-error.js.map +1 -1
  377. package/dist/utils/config-loader.d.ts +2 -1
  378. package/dist/utils/config-loader.d.ts.map +1 -1
  379. package/dist/utils/config-loader.js +40 -14
  380. package/dist/utils/config-loader.js.map +1 -1
  381. package/dist/utils/corpus-target.d.ts +26 -0
  382. package/dist/utils/corpus-target.d.ts.map +1 -0
  383. package/dist/utils/corpus-target.js +72 -0
  384. package/dist/utils/corpus-target.js.map +1 -0
  385. package/dist/utils/edge-lens-evaluation.d.ts +83 -0
  386. package/dist/utils/edge-lens-evaluation.d.ts.map +1 -0
  387. package/dist/utils/edge-lens-evaluation.js +110 -0
  388. package/dist/utils/edge-lens-evaluation.js.map +1 -0
  389. package/dist/utils/help-loader.d.ts.map +1 -1
  390. package/dist/utils/help-loader.js +0 -1
  391. package/dist/utils/help-loader.js.map +1 -1
  392. package/dist/utils/issue-anchor.d.ts +2 -2
  393. package/dist/utils/issue-anchor.d.ts.map +1 -1
  394. package/dist/utils/issue-anchor.js +1 -1
  395. package/dist/utils/issue-rendering.d.ts +3 -3
  396. package/dist/utils/issue-rendering.d.ts.map +1 -1
  397. package/dist/utils/issue-rendering.js +3 -3
  398. package/dist/utils/issue-rendering.js.map +1 -1
  399. package/dist/utils/issue-severity.d.ts +12 -5
  400. package/dist/utils/issue-severity.d.ts.map +1 -1
  401. package/dist/utils/issue-severity.js +1 -1
  402. package/dist/utils/issue-severity.js.map +1 -1
  403. package/dist/utils/optional-backend.d.ts +78 -0
  404. package/dist/utils/optional-backend.d.ts.map +1 -0
  405. package/dist/utils/optional-backend.js +117 -0
  406. package/dist/utils/optional-backend.js.map +1 -0
  407. package/dist/utils/output.d.ts +26 -0
  408. package/dist/utils/output.d.ts.map +1 -1
  409. package/dist/utils/output.js +35 -0
  410. package/dist/utils/output.js.map +1 -1
  411. package/dist/utils/package-json.d.ts +24 -0
  412. package/dist/utils/package-json.d.ts.map +1 -0
  413. package/dist/utils/package-json.js +49 -0
  414. package/dist/utils/package-json.js.map +1 -0
  415. package/dist/utils/population-wiring.d.ts +100 -0
  416. package/dist/utils/population-wiring.d.ts.map +1 -0
  417. package/dist/utils/population-wiring.js +98 -0
  418. package/dist/utils/population-wiring.js.map +1 -0
  419. package/dist/utils/project-root-policy.d.ts +20 -0
  420. package/dist/utils/project-root-policy.d.ts.map +1 -1
  421. package/dist/utils/project-root-policy.js +30 -0
  422. package/dist/utils/project-root-policy.js.map +1 -1
  423. package/dist/utils/projection-lenses.d.ts +98 -0
  424. package/dist/utils/projection-lenses.d.ts.map +1 -0
  425. package/dist/utils/projection-lenses.js +203 -0
  426. package/dist/utils/projection-lenses.js.map +1 -0
  427. package/dist/utils/projection-query.d.ts +324 -0
  428. package/dist/utils/projection-query.d.ts.map +1 -0
  429. package/dist/utils/projection-query.js +357 -0
  430. package/dist/utils/projection-query.js.map +1 -0
  431. package/dist/utils/projection-store.d.ts +335 -0
  432. package/dist/utils/projection-store.d.ts.map +1 -0
  433. package/dist/utils/projection-store.js +522 -0
  434. package/dist/utils/projection-store.js.map +1 -0
  435. package/dist/utils/relation-limits.d.ts +50 -0
  436. package/dist/utils/relation-limits.d.ts.map +1 -0
  437. package/dist/utils/relation-limits.js +50 -0
  438. package/dist/utils/relation-limits.js.map +1 -0
  439. package/dist/utils/repeatable-option.d.ts +37 -0
  440. package/dist/utils/repeatable-option.d.ts.map +1 -0
  441. package/dist/utils/repeatable-option.js +39 -0
  442. package/dist/utils/repeatable-option.js.map +1 -0
  443. package/dist/utils/resource-loader.d.ts +134 -2
  444. package/dist/utils/resource-loader.d.ts.map +1 -1
  445. package/dist/utils/resource-loader.js +290 -27
  446. package/dist/utils/resource-loader.js.map +1 -1
  447. package/dist/utils/root-argv.d.ts +53 -0
  448. package/dist/utils/root-argv.d.ts.map +1 -0
  449. package/dist/utils/root-argv.js +215 -0
  450. package/dist/utils/root-argv.js.map +1 -0
  451. package/dist/utils/run-integrity.d.ts +95 -0
  452. package/dist/utils/run-integrity.d.ts.map +1 -0
  453. package/dist/utils/run-integrity.js +102 -0
  454. package/dist/utils/run-integrity.js.map +1 -0
  455. package/dist/utils/skill-discovery.d.ts.map +1 -1
  456. package/dist/utils/skill-discovery.js +2 -1
  457. package/dist/utils/skill-discovery.js.map +1 -1
  458. package/dist/utils/skill-packaging-config.d.ts +63 -1
  459. package/dist/utils/skill-packaging-config.d.ts.map +1 -1
  460. package/dist/utils/skill-packaging-config.js +56 -1
  461. package/dist/utils/skill-packaging-config.js.map +1 -1
  462. package/dist/utils/sqlite-experimental-warning.d.ts +69 -0
  463. package/dist/utils/sqlite-experimental-warning.d.ts.map +1 -0
  464. package/dist/utils/sqlite-experimental-warning.js +144 -0
  465. package/dist/utils/sqlite-experimental-warning.js.map +1 -0
  466. package/dist/utils/url-redact.d.ts.map +1 -1
  467. package/dist/utils/url-redact.js +4 -6
  468. package/dist/utils/url-redact.js.map +1 -1
  469. package/dist/utils/user-context-scanner.d.ts +8 -0
  470. package/dist/utils/user-context-scanner.d.ts.map +1 -1
  471. package/dist/utils/user-context-scanner.js +4 -2
  472. package/dist/utils/user-context-scanner.js.map +1 -1
  473. package/dist/utils/validate-help-files.d.ts.map +1 -1
  474. package/dist/utils/validate-help-files.js +12 -6
  475. package/dist/utils/validate-help-files.js.map +1 -1
  476. package/dist/utils/vat-bin-path.d.ts +36 -0
  477. package/dist/utils/vat-bin-path.d.ts.map +1 -0
  478. package/dist/utils/vat-bin-path.js +48 -0
  479. package/dist/utils/vat-bin-path.js.map +1 -0
  480. package/dist/utils/verdict-helpers.d.ts +1 -1
  481. package/dist/utils/verdict-helpers.d.ts.map +1 -1
  482. package/dist/utils/verdict-helpers.js +1 -1
  483. package/dist/utils/verdict-helpers.js.map +1 -1
  484. package/dist/version.d.ts.map +1 -1
  485. package/dist/version.js +1 -3
  486. package/dist/version.js.map +1 -1
  487. package/docs/agent.md +2 -2
  488. package/docs/audit.md +143 -39
  489. package/docs/doctor.md +7 -6
  490. package/docs/index.md +19 -11
  491. package/docs/mcp.md +2 -2
  492. package/docs/rag.md +3 -2
  493. package/docs/resources.md +13 -3
  494. package/docs/skill-test.md +10 -9
  495. package/docs/skills.md +53 -69
  496. package/package.json +36 -27
  497. package/schemas/ard-emit.json +152 -0
  498. package/schemas/okf-validate.json +170 -0
  499. package/schemas/resources-check.json +257 -0
  500. package/schemas/skill-review.json +230 -0
  501. package/dist/commands/resources/command-helpers.d.ts +0 -5
  502. package/dist/commands/resources/command-helpers.d.ts.map +0 -1
  503. package/dist/commands/resources/command-helpers.js +0 -6
  504. package/dist/commands/resources/command-helpers.js.map +0 -1
@@ -4,8 +4,12 @@
4
4
  * Discovers skills from config yaml skills.include/exclude, validates each
5
5
  * using validateSkillForPackaging with merged packaging config.
6
6
  */
7
- import { type SeverityCounts, type ValidationIssue } from '@vibe-agent-toolkit/agent-schema';
8
- import { type PackagingValidationResult } from '@vibe-agent-toolkit/agent-skills';
7
+ import { type DeclaredEvalSuite, type PackagingValidationResult, type SkillPackagingConfig, type SkillValidationSharedContext } from '@vibe-agent-toolkit/agent-skills';
8
+ import { ResourceRegistry, type ProjectConfig, type ResourcePopulationSource, type SkillsConfig } from '@vibe-agent-toolkit/resources';
9
+ import { type SeverityCounts, type ValidationIssue } from '@vibe-agent-toolkit/schema';
10
+ import { type createLogger } from '../../utils/logger.js';
11
+ import { type PhaseOutcome } from '../phase-utils.js';
12
+ import { type DiscoveredSkill } from './command-helpers.js';
9
13
  /**
10
14
  * Skills validate command options
11
15
  */
@@ -14,6 +18,12 @@ export interface SkillsValidateCommandOptions {
14
18
  debug?: boolean;
15
19
  verbose?: boolean;
16
20
  }
21
+ /**
22
+ * Discovered skill with merged packaging config for validation
23
+ */
24
+ export interface ValidatableSkill extends DiscoveredSkill {
25
+ packagingConfig: SkillPackagingConfig;
26
+ }
17
27
  /** The vocabulary of a validation verdict: worst ACTIONABLE severity. */
18
28
  type ValidationStatus = 'success' | 'warning' | 'error';
19
29
  /**
@@ -26,6 +36,46 @@ type ValidationStatus = 'success' | 'warning' | 'error';
26
36
  * validated at the time is what produced 78 warnings from 3 real entries.
27
37
  */
28
38
  type RunIssues = readonly ValidationIssue[];
39
+ /**
40
+ * The discovery declaration a run's document answers for: the globs that
41
+ * decided which skills it validated. Only these two keys are read, so a caller
42
+ * with a full `SkillsConfig` and a test with two arrays hand in the same thing.
43
+ */
44
+ export type SkillDiscoveryPatterns = Pick<SkillsConfig, 'include' | 'exclude'>;
45
+ /**
46
+ * The run-level findings, with the run-integrity refusal derived in front of
47
+ * them when the run validated no skill.
48
+ *
49
+ * 🚨 **Zero skills validated is an ERROR, not a clean run.** `skills.include`
50
+ * globs that discover nothing — a typo, a renamed directory, an `exclude` that
51
+ * swallows every match — used to take an early return that printed one info
52
+ * line and published NO document at exit 0, and `vat validate` folded that into
53
+ * `status: success`: the gate the docs name as THE gate, green forever on a
54
+ * config that checked nothing. `vat verify` refused the identical config in its
55
+ * `packaged-content` phase and its message sent the operator to this command,
56
+ * which then said nothing.
57
+ *
58
+ * 🔑 The ONE seam both channels read. {@link buildValidateSummary} (the
59
+ * document) and {@link formatValidationReportLines} (stderr) both derive their
60
+ * issue set here, so "denominator zero, status clean" is unrepresentable on
61
+ * either channel rather than merely unwritten, and the exit code — derived from
62
+ * the document's own counts — agrees with both by construction. Through the
63
+ * shared mechanism in `run-integrity.ts`: one non-overridable
64
+ * `RESOURCE_CHECK_BROKEN` at `error`.
65
+ *
66
+ * Only the empty GLOB is refused. A config with no `skills:` block at all is a
67
+ * choice — the project declares no skills — and both orchestrators already skip
68
+ * this phase on that config; the phase declines it the same way (no document,
69
+ * exit 0) rather than inventing a refusal for a gate nobody declared.
70
+ *
71
+ * @param results - One result per skill the run validated: the denominator
72
+ * @param runIssues - The run's own findings so far (`ALLOW_UNUSED`), so an
73
+ * existing run-integrity report is not duplicated
74
+ * @param patterns - The discovery globs, named in the refusal so the operator
75
+ * sees what matched nothing
76
+ * @returns The run-level issues the document and the stderr report publish
77
+ */
78
+ export declare function withRunIntegrity(results: readonly PackagingValidationResult[], runIssues: RunIssues, patterns: SkillDiscoveryPatterns): ValidationIssue[];
29
79
  /**
30
80
  * Build the YAML summary object.
31
81
  *
@@ -52,8 +102,13 @@ type RunIssues = readonly ValidationIssue[];
52
102
  * zeros: `issueCounts` and `runIssueCounts` keep their complete
53
103
  * `{errors, warnings, info}` shape in both modes, because they are the
54
104
  * reconciliation identity rather than something a reader scans.
105
+ *
106
+ * A run over ZERO skills is refused here, not passed — see
107
+ * {@link withRunIntegrity}, which is why the discovery `patterns` are a
108
+ * parameter of a document builder: the refusal names the globs that matched
109
+ * nothing, and the builder is where the refusal is derived.
55
110
  */
56
- export declare function buildValidateSummary(results: PackagingValidationResult[], duration: number, verbose: boolean, runIssues: RunIssues): {
111
+ export declare function buildValidateSummary(results: PackagingValidationResult[], duration: number, verbose: boolean, runIssues: RunIssues, patterns: SkillDiscoveryPatterns): {
57
112
  status: ValidationStatus;
58
113
  issueCounts: SeverityCounts;
59
114
  runIssueCounts: SeverityCounts;
@@ -79,8 +134,12 @@ export declare function buildValidateSummary(results: PackagingValidationResult[
79
134
  * Run-level findings and the banner are printed in full either way — there are
80
135
  * ~14 of the former, and they belong to the project config rather than to any
81
136
  * asset, so there is no row for them to collapse into.
137
+ *
138
+ * Reads the same seam as the document builder ({@link withRunIntegrity}), so a
139
+ * run over zero skills prints the refusal here too rather than a green banner
140
+ * over a document that says `error`.
82
141
  */
83
- export declare function formatValidationReportLines(results: PackagingValidationResult[], runIssues: RunIssues, verbose: boolean): string[];
142
+ export declare function formatValidationReportLines(results: PackagingValidationResult[], runIssues: RunIssues, verbose: boolean, patterns: SkillDiscoveryPatterns): string[];
84
143
  /**
85
144
  * Log validation progress for a single skill.
86
145
  *
@@ -90,6 +149,83 @@ export declare function formatValidationReportLines(results: PackagingValidation
90
149
  * collapse as the batch banner, one line earlier.
91
150
  */
92
151
  export declare function formatSkillProgressLine(skillName: string, result: PackagingValidationResult): string[];
152
+ /**
153
+ * Build a single shared validation context for an entire `vat skills validate`
154
+ * invocation.
155
+ *
156
+ * When every skill in the batch resolves to the same projectRoot (the normal
157
+ * monorepo case), we crawl the resource registry once and hand the same
158
+ * instance to each skill's validation — the per-skill markdown reparse
159
+ * disappears. Similarly, gitignore checks are backed by a single
160
+ * {@link GitTracker} when every skill sits inside the same git repository.
161
+ *
162
+ * When the batch is heterogeneous (e.g. multiple projectRoots), the helper
163
+ * returns an empty context and validators transparently fall back to their
164
+ * legacy per-skill setup — correctness first, perf second.
165
+ */
166
+ /**
167
+ * Options for {@link buildSkillsValidateRegistry}.
168
+ */
169
+ export interface SkillsValidateRegistryOptions {
170
+ /**
171
+ * The project's configuration, or `undefined` for a project that has none.
172
+ *
173
+ * **Not optional in the sense of "nice to have".** A collection may declare a
174
+ * `mimeType` that overrides the extension tables and decides which parser runs
175
+ * over a file. `ResourceRegistry` routes through `resources.collections` when —
176
+ * and only when — it was handed a config; the projection lane behind
177
+ * `populationSource` reads those same declarations off the root. A registry
178
+ * built without the config therefore reaches a DIFFERENT verdict about whether
179
+ * a file is prose than the population that enumerated it, inside one command.
180
+ *
181
+ * Passed rather than re-read here so this lane cannot answer from a second,
182
+ * later parse of the same file.
183
+ */
184
+ config?: ProjectConfig | undefined;
185
+ /**
186
+ * Where the file list comes from — omit for the incumbent walk, supply one to
187
+ * source it from a projection instead. Enumeration only: `include` below is
188
+ * re-applied to whatever the source offers.
189
+ */
190
+ populationSource?: ResourcePopulationSource | undefined;
191
+ }
192
+ /**
193
+ * The markdown-only, link-resolved registry `vat skills validate` shares across
194
+ * every skill in one invocation.
195
+ *
196
+ * Exported and named because it had two implementations: this one, and a
197
+ * restatement inside `pipeline-oracles/lanes.ts` whose own comment recorded that
198
+ * it was "the one lane with no reusable builder to point at". A copy of a
199
+ * registry builder is a copy of its ARGUMENTS, and the argument that matters
200
+ * here is `config` — see {@link SkillsValidateRegistryOptions.config}.
201
+ *
202
+ * @param projectRoot - Root every skill in the batch resolves to
203
+ * @param options - The governing config, and optionally the projection-backed
204
+ * enumeration to build from
205
+ * @returns A crawled registry whose links are already resolved
206
+ */
207
+ export declare function buildSkillsValidateRegistry(projectRoot: string, options?: SkillsValidateRegistryOptions): Promise<ResourceRegistry>;
208
+ export declare function buildSharedValidationContext(skills: ValidatableSkill[], projectSkills: readonly DeclaredEvalSuite[], config: ProjectConfig | undefined, logger: ReturnType<typeof createLogger>): Promise<SkillValidationSharedContext>;
209
+ /**
210
+ * Validate every configured skill and hand back the document and exit code,
211
+ * printing the document nowhere.
212
+ *
213
+ * The phase entry point for `vat validate` and `vat verify`. The one early
214
+ * return publishes NO document: a config with no `skills:` block prints one
215
+ * info line, exits 0, and `phaseResultFromOutcome` records that as `success`
216
+ * with no `report` — both orchestrators skip the phase on that config anyway,
217
+ * because declaring no skills is a choice.
218
+ *
219
+ * A `skills:` block whose globs discover nothing is NOT a second early return.
220
+ * It used to be — one info line, no document, exit 0 — and that made `vat
221
+ * validate` green forever on a typo'd glob. It now runs through the same
222
+ * builder as a populated batch, which refuses a zero denominator (see
223
+ * {@link withRunIntegrity}): a document with one `RESOURCE_CHECK_BROKEN` at
224
+ * `error`, `status: error`, exit 1. Exit 1 and not 2, deliberately: the run
225
+ * completed and the gate FAILED, which is the class an operator's CI already
226
+ * handles; 2 is for a run that could not answer at all.
227
+ */
228
+ export declare function runSkillsValidatePhase(pathArg: string | undefined, options: SkillsValidateCommandOptions): Promise<PhaseOutcome>;
93
229
  /**
94
230
  * Skills validate command implementation
95
231
  */
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/commands/skills/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAGL,KAAK,yBAAyB,EAG/B,MAAM,kCAAkC,CAAC;AA8B1C;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AASD,yEAAyE;AACzE,KAAK,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAaxD;;;;;;;;GAQG;AACH,KAAK,SAAS,GAAG,SAAS,eAAe,EAAE,CAAC;AA6D5C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,yBAAyB,EAAE,EACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,GACnB;IACD,MAAM,EAAE,gBAAgB,CAAC;IACzB,WAAW,EAAE,cAAc,CAAC;IAC5B,cAAc,EAAE,cAAc,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;CACtB,CA2BA;AAqHD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,yBAAyB,EAAE,EACpC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,GACf,MAAM,EAAE,CAeV;AAkCD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,yBAAyB,GAChC,MAAM,EAAE,CAeV;AAkGD;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,IAAI,CAAC,CA4Ff"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/commands/skills/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EAClC,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,gBAAgB,EAChB,KAAK,aAAa,EAClB,KAAK,wBAAwB,EAC7B,KAAK,YAAY,EAClB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,4BAA4B,CAAC;AAgBpC,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAW1D,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAErE,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAG9B;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,eAAe,EAAE,oBAAoB,CAAC;CACvC;AAED,yEAAyE;AACzE,KAAK,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAaxD;;;;;;;;GAQG;AACH,KAAK,SAAS,GAAG,SAAS,eAAe,EAAE,CAAC;AAE5C;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,SAAS,CAAC,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,SAAS,yBAAyB,EAAE,EAC7C,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,sBAAsB,GAC/B,eAAe,EAAE,CAKnB;AAgFD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,yBAAyB,EAAE,EACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,sBAAsB,GAC/B;IACD,MAAM,EAAE,gBAAgB,CAAC;IACzB,WAAW,EAAE,cAAc,CAAC;IAC5B,cAAc,EAAE,cAAc,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;CACtB,CA4BA;AA+GD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,yBAAyB,EAAE,EACpC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,sBAAsB,GAC/B,MAAM,EAAE,CAgBV;AAgCD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,yBAAyB,GAChC,MAAM,EAAE,CAeV;AAYD;;;;;;;;;;;;;GAaG;AACH;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACnC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;CACzD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,gBAAgB,CAAC,CAe3B;AAED,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,gBAAgB,EAAE,EAC1B,aAAa,EAAE,SAAS,iBAAiB,EAAE,EAC3C,MAAM,EAAE,aAAa,GAAG,SAAS,EACjC,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACtC,OAAO,CAAC,4BAA4B,CAAC,CAgHvC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,YAAY,CAAC,CAoGvB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,IAAI,CAAC,CAMf"}
@@ -4,19 +4,23 @@
4
4
  * Discovers skills from config yaml skills.include/exclude, validates each
5
5
  * using validateSkillForPackaging with merged packaging config.
6
6
  */
7
- import { allowUnusedIssues, calculateValidationStatus, countBySeverity, createAllowUsageLedger, } from '@vibe-agent-toolkit/agent-schema';
8
- import { validateSkillForPackaging, } from '@vibe-agent-toolkit/agent-skills';
9
- import { ResourceRegistry } from '@vibe-agent-toolkit/resources';
10
- import { findProjectRoot, gitFindRoot, GitTracker, safePath } from '@vibe-agent-toolkit/utils';
7
+ import { conventionalSuiteProbe, validateSkillForPackaging, } from '@vibe-agent-toolkit/agent-skills';
8
+ import { ResourceRegistry, } from '@vibe-agent-toolkit/resources';
9
+ import { allowUnusedIssues, calculateValidationStatus, countBySeverity, createAllowUsageLedger, } from '@vibe-agent-toolkit/schema';
10
+ import { findProjectRoot, safePath } from '@vibe-agent-toolkit/utils';
11
+ import { gitFindRoot, GitTracker } from '@vibe-agent-toolkit/utils/git';
11
12
  import * as yaml from 'yaml';
12
- import { handleCommandError } from '../../utils/command-error.js';
13
+ import { reportCommandError } from '../../utils/command-error.js';
13
14
  import { loadConfig } from '../../utils/config-loader.js';
14
15
  import { formatDurationSecs } from '../../utils/duration.js';
15
16
  import { formatIssueLines, formatRunIssueLines, formatSeverityBreakdown, issuesToRenderAtVerbosity, summarizeFindings, sumSeverityCounts, } from '../../utils/issue-rendering.js';
16
17
  import { requireProjectRoot } from '../../utils/project-root-policy.js';
18
+ import { RESOURCES_CRAWL_ENV, RESOURCES_CRAWL_PROJECTION, withResourcePopulationSource, } from '../../utils/resource-loader.js';
19
+ import { nothingCheckedFinding } from '../../utils/run-integrity.js';
17
20
  import { collectDeclaredEvalSuites, mergeSkillPackagingConfig } from '../../utils/skill-packaging-config.js';
18
21
  import { renderSkillQualityFooter } from '../../utils/skill-quality-footer.js';
19
22
  import { applyConfigVerdicts } from '../../utils/verdict-helpers.js';
23
+ import { finishCommand } from '../phase-utils.js';
20
24
  import { filterSkillsByName, setupCommandContext, } from './command-helpers.js';
21
25
  import { discoverSkillsFromConfig } from './skill-discovery.js';
22
26
  /**
@@ -29,6 +33,62 @@ import { discoverSkillsFromConfig } from './skill-discovery.js';
29
33
  function batchIssues(results) {
30
34
  return results.flatMap((r) => r.allErrors);
31
35
  }
36
+ /**
37
+ * The run-level findings, with the run-integrity refusal derived in front of
38
+ * them when the run validated no skill.
39
+ *
40
+ * 🚨 **Zero skills validated is an ERROR, not a clean run.** `skills.include`
41
+ * globs that discover nothing — a typo, a renamed directory, an `exclude` that
42
+ * swallows every match — used to take an early return that printed one info
43
+ * line and published NO document at exit 0, and `vat validate` folded that into
44
+ * `status: success`: the gate the docs name as THE gate, green forever on a
45
+ * config that checked nothing. `vat verify` refused the identical config in its
46
+ * `packaged-content` phase and its message sent the operator to this command,
47
+ * which then said nothing.
48
+ *
49
+ * 🔑 The ONE seam both channels read. {@link buildValidateSummary} (the
50
+ * document) and {@link formatValidationReportLines} (stderr) both derive their
51
+ * issue set here, so "denominator zero, status clean" is unrepresentable on
52
+ * either channel rather than merely unwritten, and the exit code — derived from
53
+ * the document's own counts — agrees with both by construction. Through the
54
+ * shared mechanism in `run-integrity.ts`: one non-overridable
55
+ * `RESOURCE_CHECK_BROKEN` at `error`.
56
+ *
57
+ * Only the empty GLOB is refused. A config with no `skills:` block at all is a
58
+ * choice — the project declares no skills — and both orchestrators already skip
59
+ * this phase on that config; the phase declines it the same way (no document,
60
+ * exit 0) rather than inventing a refusal for a gate nobody declared.
61
+ *
62
+ * @param results - One result per skill the run validated: the denominator
63
+ * @param runIssues - The run's own findings so far (`ALLOW_UNUSED`), so an
64
+ * existing run-integrity report is not duplicated
65
+ * @param patterns - The discovery globs, named in the refusal so the operator
66
+ * sees what matched nothing
67
+ * @returns The run-level issues the document and the stderr report publish
68
+ */
69
+ export function withRunIntegrity(results, runIssues, patterns) {
70
+ return [
71
+ ...nothingCheckedFinding(results.length, runIssues, () => nothingDiscoveredMessage(patterns)),
72
+ ...runIssues,
73
+ ];
74
+ }
75
+ /** The globs as an operator wrote them, back-quoted and comma-separated. */
76
+ function quoteGlobs(globs) {
77
+ return globs.map((glob) => `\`${glob}\``).join(', ');
78
+ }
79
+ /** What did not run, and what the operator can do — invariant 5 of `run-integrity.ts`. */
80
+ function nothingDiscoveredMessage(patterns) {
81
+ const include = quoteGlobs(patterns.include);
82
+ const exclude = patterns.exclude === undefined || patterns.exclude.length === 0
83
+ ? ''
84
+ : ` after \`skills.exclude\` (${quoteGlobs(patterns.exclude)})`;
85
+ return 'vat skills validate validated 0 skills, so this run is not a verdict: nothing was checked,'
86
+ + ' and the document reads the same as a run over clean skills. The `skills.include` globs in'
87
+ + ` vibe-agent-toolkit.config.yaml (${include}) matched no SKILL.md${exclude} — usually a typo`
88
+ + ' in the glob, a renamed directory, or an exclude that swallows every match. Fix the patterns'
89
+ + ' so they discover the skills this project ships, or remove the `skills:` block if it ships'
90
+ + ' none.';
91
+ }
32
92
  /**
33
93
  * One skill's VERBOSE YAML entry: the whole result plus the per-severity counts
34
94
  * its two-valued `status` cannot express.
@@ -111,12 +171,18 @@ function toSummaryYamlResult(result) {
111
171
  * zeros: `issueCounts` and `runIssueCounts` keep their complete
112
172
  * `{errors, warnings, info}` shape in both modes, because they are the
113
173
  * reconciliation identity rather than something a reader scans.
174
+ *
175
+ * A run over ZERO skills is refused here, not passed — see
176
+ * {@link withRunIntegrity}, which is why the discovery `patterns` are a
177
+ * parameter of a document builder: the refusal names the globs that matched
178
+ * nothing, and the builder is where the refusal is derived.
114
179
  */
115
- export function buildValidateSummary(results, duration, verbose, runIssues) {
180
+ export function buildValidateSummary(results, duration, verbose, runIssues, patterns) {
116
181
  const skillIssues = batchIssues(results);
117
- const runIssueCounts = countBySeverity(runIssues);
182
+ const published = withRunIntegrity(results, runIssues, patterns);
183
+ const runIssueCounts = countBySeverity(published);
118
184
  return {
119
- status: calculateValidationStatus([...skillIssues, ...runIssues]),
185
+ status: calculateValidationStatus([...skillIssues, ...published]),
120
186
  issueCounts: sumSeverityCounts([countBySeverity(skillIssues), runIssueCounts]),
121
187
  runIssueCounts,
122
188
  // `skillsValidated` stays the true denominator even though the default
@@ -136,16 +202,15 @@ export function buildValidateSummary(results, duration, verbose, runIssues) {
136
202
  results: verbose
137
203
  ? results.map((r) => toVerboseYamlResult(r))
138
204
  : results.filter((r) => hasFindings(r)).map((r) => toSummaryYamlResult(r)),
139
- runIssues: [...runIssues],
205
+ runIssues: published,
140
206
  durationSecs: formatDurationSecs(duration),
141
207
  };
142
208
  }
143
209
  /**
144
210
  * Output YAML summary to stdout
145
211
  */
146
- function outputYamlSummary(results, duration, verbose, runIssues) {
147
- const output = buildValidateSummary(results, duration, verbose, runIssues);
148
- console.log(yaml.stringify(output, { indent: 2, lineWidth: 0, aliasDuplicateObjects: false }));
212
+ function writeYamlSummary(summary) {
213
+ console.log(yaml.stringify(summary, { indent: 2, lineWidth: 0, aliasDuplicateObjects: false }));
149
214
  }
150
215
  /**
151
216
  * ONE line for one skill: its severity breakdown, its allowed count, and the
@@ -226,7 +291,7 @@ const STATUS_GLYPHS = {
226
291
  * expected pre-build state and must not fail CI); only the claim was wrong. It
227
292
  * is dropped rather than made conditional because the code registry carries no
228
293
  * build-blocking fact to condition it on — `CodeRegistryEntry` in
229
- * agent-schema/src/validation-codes.ts is exactly `defaultSeverity` /
294
+ * schema/src/validation-codes.ts is exactly `defaultSeverity` /
230
295
  * `description` / `fix` / `reference` — and keying the claim
231
296
  * on a hardcoded list of code names would assert a cause this renderer cannot
232
297
  * observe, and would go stale the next time a code is added.
@@ -259,9 +324,14 @@ function reportBanner(status, counts) {
259
324
  * Run-level findings and the banner are printed in full either way — there are
260
325
  * ~14 of the former, and they belong to the project config rather than to any
261
326
  * asset, so there is no row for them to collapse into.
327
+ *
328
+ * Reads the same seam as the document builder ({@link withRunIntegrity}), so a
329
+ * run over zero skills prints the refusal here too rather than a green banner
330
+ * over a document that says `error`.
262
331
  */
263
- export function formatValidationReportLines(results, runIssues, verbose) {
264
- const issues = [...batchIssues(results), ...runIssues];
332
+ export function formatValidationReportLines(results, runIssues, verbose, patterns) {
333
+ const published = withRunIntegrity(results, runIssues, patterns);
334
+ const issues = [...batchIssues(results), ...published];
265
335
  const counts = countBySeverity(issues);
266
336
  const status = calculateValidationStatus(issues);
267
337
  const lines = [reportBanner(status, counts)];
@@ -270,7 +340,7 @@ export function formatValidationReportLines(results, runIssues, verbose) {
270
340
  continue;
271
341
  lines.push(...skillReportLines(result, verbose));
272
342
  }
273
- const runLines = formatRunIssueLines(runIssues);
343
+ const runLines = formatRunIssueLines(published);
274
344
  if (runLines.length > 0) {
275
345
  lines.push(...runLines, '');
276
346
  }
@@ -279,8 +349,7 @@ export function formatValidationReportLines(results, runIssues, verbose) {
279
349
  /**
280
350
  * Output validation report to stdout (YAML) and stderr (human-readable)
281
351
  */
282
- function outputValidationReport(results, duration, logger, verbose, runIssues) {
283
- outputYamlSummary(results, duration, verbose, runIssues);
352
+ function reportValidationToStderr(results, logger, verbose, runIssues, patterns) {
284
353
  // Collect all emitted codes across skills (both errors and warnings) to drive the footer
285
354
  const emittedCodes = new Set();
286
355
  for (const r of results) {
@@ -288,11 +357,11 @@ function outputValidationReport(results, duration, logger, verbose, runIssues) {
288
357
  emittedCodes.add(issue.code);
289
358
  }
290
359
  }
291
- for (const issue of runIssues) {
360
+ for (const issue of withRunIntegrity(results, runIssues, patterns)) {
292
361
  emittedCodes.add(issue.code);
293
362
  }
294
363
  const hasSkillFindings = results.some((r) => calculateValidationStatus(r.allErrors) !== 'success');
295
- for (const line of formatValidationReportLines(results, runIssues, verbose)) {
364
+ for (const line of formatValidationReportLines(results, runIssues, verbose, patterns)) {
296
365
  logger.info(line);
297
366
  }
298
367
  renderSkillQualityFooter(logger, hasSkillFindings, emittedCodes);
@@ -326,30 +395,61 @@ function logSkillProgress(skillName, result, logger) {
326
395
  }
327
396
  }
328
397
  /**
329
- * Build a single shared validation context for an entire `vat skills validate`
330
- * invocation.
398
+ * The markdown-only, link-resolved registry `vat skills validate` shares across
399
+ * every skill in one invocation.
331
400
  *
332
- * When every skill in the batch resolves to the same projectRoot (the normal
333
- * monorepo case), we crawl the resource registry once and hand the same
334
- * instance to each skill's validation — the per-skill markdown reparse
335
- * disappears. Similarly, gitignore checks are backed by a single
336
- * {@link GitTracker} when every skill sits inside the same git repository.
401
+ * Exported and named because it had two implementations: this one, and a
402
+ * restatement inside `pipeline-oracles/lanes.ts` whose own comment recorded that
403
+ * it was "the one lane with no reusable builder to point at". A copy of a
404
+ * registry builder is a copy of its ARGUMENTS, and the argument that matters
405
+ * here is `config` — see {@link SkillsValidateRegistryOptions.config}.
337
406
  *
338
- * When the batch is heterogeneous (e.g. multiple projectRoots), the helper
339
- * returns an empty context and validators transparently fall back to their
340
- * legacy per-skill setup — correctness first, perf second.
407
+ * @param projectRoot - Root every skill in the batch resolves to
408
+ * @param options - The governing config, and optionally the projection-backed
409
+ * enumeration to build from
410
+ * @returns A crawled registry whose links are already resolved
341
411
  */
342
- async function buildSharedValidationContext(skills, projectSkills, logger) {
412
+ export async function buildSkillsValidateRegistry(projectRoot, options = {}) {
413
+ const { config, populationSource } = options;
414
+ const registry = await ResourceRegistry.fromCrawl({
415
+ baseDir: projectRoot,
416
+ include: ['**/*.md'],
417
+ // `vat skills validate` acts on this registry as the whole population: a
418
+ // directory it cannot list refuses the run by name, exit 2.
419
+ unreadable: 'refuse',
420
+ ...(populationSource !== undefined && { populationSource }),
421
+ }, config === undefined ? undefined : { config });
422
+ registry.resolveLinks();
423
+ return registry;
424
+ }
425
+ export async function buildSharedValidationContext(skills, projectSkills, config, logger) {
343
426
  // The allow-entry ledger is not an optimization like the two below — it is
344
427
  // what makes ALLOW_UNUSED true. `validation.allow` is declared once for the
345
428
  // package and matched per skill, so only the batch can say an entry matched
346
429
  // nothing. Always present, so no early return can drop it.
347
430
  const allowLedger = createAllowUsageLedger();
431
+ // The RUN's conventional-suite probe, and it belongs beside the ledger rather
432
+ // than with the two optimizations below: resolving a skill's test input probes
433
+ // `<skill-root>/evals/evals.json` for the subject AND for every entry in
434
+ // `projectSkills`, so a probe minted per skill asks S questions per skill and
435
+ // S² per run about the same S paths. Measured with the lab on a 103-skill
436
+ // adopter: 10,815 probes over 103 distinct paths, half the command's entire
437
+ // filesystem traffic; with the run's probe threaded, ~103.
438
+ //
439
+ // Created here, once, and handed to every skill in the batch — that is the
440
+ // whole contract of `SkillValidationSharedContext.suiteProbe`, whose fallback
441
+ // (`?? conventionalSuiteProbe()`) treats an omitting caller as claiming ITS
442
+ // call is the whole run. This lane loops, so omitting it made that claim
443
+ // falsely and silently.
444
+ //
445
+ // NOT module-scoped: the answer is a filesystem snapshot, and a cache
446
+ // outliving the run keeps answering for a tree that has since changed.
447
+ const suiteProbe = conventionalSuiteProbe();
348
448
  // Likewise not an optimization: the test-input rule is project-wide, so this
349
449
  // lane must model a bundle that excludes EVERY declared suite, not just the
350
450
  // subject's. Present even for an empty batch, so no early return can drop it.
351
451
  if (skills.length === 0) {
352
- return { allowLedger, projectSkills };
452
+ return { allowLedger, projectSkills, suiteProbe, unreadable: 'refuse' };
353
453
  }
354
454
  const projectRoots = new Set();
355
455
  const gitRoots = new Set();
@@ -367,27 +467,15 @@ async function buildSharedValidationContext(skills, projectSkills, logger) {
367
467
  gitRoots.add(safePath.resolve(gitRoot));
368
468
  }
369
469
  }
370
- const context = { allowLedger, projectSkills };
371
- // Only reuse a single registry when every skill shares the same project
372
- // root. Otherwise the per-skill fallback path is correct and the cost is
373
- // unchanged from the pre-refactor baseline.
374
- if (projectRoots.size === 1) {
375
- const [sharedRoot] = [...projectRoots];
376
- if (sharedRoot !== undefined) {
377
- logger.debug(`Building shared resource registry rooted at: ${sharedRoot}`);
378
- const registry = await ResourceRegistry.fromCrawl({
379
- baseDir: sharedRoot,
380
- include: ['**/*.md'],
381
- });
382
- registry.resolveLinks();
383
- context.registry = registry;
384
- }
385
- }
386
- else {
387
- logger.debug(`Skipping shared registry — batch spans ${projectRoots.size} project roots`);
388
- }
470
+ const context = { allowLedger, projectSkills, suiteProbe, unreadable: 'refuse' };
389
471
  // One tracker per repo; when the batch spans repos, skip rather than spawn
390
472
  // multiple `git ls-files`.
473
+ //
474
+ // Built BEFORE the registry, which is the one ordering constraint in this
475
+ // function: the projection lane below needs an ignore oracle, and without one
476
+ // every realization row reads `gitignored: false` — so the population would
477
+ // admit the ignored half of the tree and this command would start validating
478
+ // generated markdown. Nothing else here depends on the order.
391
479
  if (gitRoots.size === 1) {
392
480
  const [sharedGitRoot] = [...gitRoots];
393
481
  if (sharedGitRoot !== undefined) {
@@ -400,12 +488,63 @@ async function buildSharedValidationContext(skills, projectSkills, logger) {
400
488
  else if (gitRoots.size > 1) {
401
489
  logger.debug(`Skipping shared tracker — batch spans ${gitRoots.size} git roots`);
402
490
  }
491
+ // Only reuse a single registry when every skill shares the same project
492
+ // root. Otherwise the per-skill fallback path is correct and the cost is
493
+ // unchanged from the pre-refactor baseline.
494
+ if (projectRoots.size === 1) {
495
+ const [sharedRoot] = [...projectRoots];
496
+ if (sharedRoot !== undefined) {
497
+ logger.debug(`Building shared resource registry rooted at: ${sharedRoot}`);
498
+ // The lane, and the store that answers it, bracket the crawl and nothing
499
+ // else: the source is called from inside `fromCrawl` and nowhere after it.
500
+ // `include` is unchanged either way — `ResourceRegistry.crawl` re-applies
501
+ // it to whatever the source offers, so this stays a markdown-only registry
502
+ // on both lanes.
503
+ const registry = await withResourcePopulationSource({ root: sharedRoot, gitTracker: context.gitTracker }, async (populationSource) => {
504
+ logger.debug(populationSource
505
+ ? `Enumerating via the projection lane (${RESOURCES_CRAWL_ENV}=${RESOURCES_CRAWL_PROJECTION})`
506
+ : `Enumerating via the incumbent walk (${RESOURCES_CRAWL_ENV} unset)`);
507
+ return buildSkillsValidateRegistry(sharedRoot, {
508
+ // The command's OWN config, not a second read of the same file. It
509
+ // governs `sharedRoot` by construction: this command exits early
510
+ // without a config at `cwd`, every skill is discovered relative to
511
+ // `cwd`, and `findProjectRoot` stops at the nearest config — so the
512
+ // root every skill agrees on IS the root this config was loaded
513
+ // from. Withholding it routes parsing by the extension tables while
514
+ // the projection behind `populationSource` routes by the declared
515
+ // `mimeType`, and the two then disagree about which files are prose.
516
+ config,
517
+ ...(populationSource !== undefined && { populationSource }),
518
+ });
519
+ });
520
+ context.registry = registry;
521
+ }
522
+ }
523
+ else {
524
+ logger.debug(`Skipping shared registry — batch spans ${projectRoots.size} project roots`);
525
+ }
403
526
  return context;
404
527
  }
405
528
  /**
406
- * Skills validate command implementation
529
+ * Validate every configured skill and hand back the document and exit code,
530
+ * printing the document nowhere.
531
+ *
532
+ * The phase entry point for `vat validate` and `vat verify`. The one early
533
+ * return publishes NO document: a config with no `skills:` block prints one
534
+ * info line, exits 0, and `phaseResultFromOutcome` records that as `success`
535
+ * with no `report` — both orchestrators skip the phase on that config anyway,
536
+ * because declaring no skills is a choice.
537
+ *
538
+ * A `skills:` block whose globs discover nothing is NOT a second early return.
539
+ * It used to be — one info line, no document, exit 0 — and that made `vat
540
+ * validate` green forever on a typo'd glob. It now runs through the same
541
+ * builder as a populated batch, which refuses a zero denominator (see
542
+ * {@link withRunIntegrity}): a document with one `RESOURCE_CHECK_BROKEN` at
543
+ * `error`, `status: error`, exit 1. Exit 1 and not 2, deliberately: the run
544
+ * completed and the gate FAILED, which is the class an operator's CI already
545
+ * handles; 2 is for a run that could not answer at all.
407
546
  */
408
- export async function validateCommand(pathArg, options) {
547
+ export async function runSkillsValidatePhase(pathArg, options) {
409
548
  const { logger, cwd, startTime } = setupCommandContext(pathArg, options.debug);
410
549
  try {
411
550
  // Spec §7: `vat skills validate` requires a projectRoot — fails fast at
@@ -417,14 +556,16 @@ export async function validateCommand(pathArg, options) {
417
556
  const config = loadConfig(cwd);
418
557
  if (!config?.skills) {
419
558
  logger.info('No skills section in config yaml — nothing to validate');
420
- process.exit(0);
421
- }
422
- // Discover skills from config yaml (relative to cwd where config lives)
423
- const discovered = await discoverSkillsFromConfig(config.skills, cwd);
424
- if (discovered.length === 0) {
425
- logger.info('ℹ️ No skills found matching config yaml skills.include patterns');
426
- process.exit(0);
559
+ return { document: undefined, exitCode: 0 };
427
560
  }
561
+ // Discover skills from config yaml (relative to cwd where config lives).
562
+ // `'refuse'`: one fewer skill at exit 0 is the drop this command must not
563
+ // make. The throw lands in the catch below → `reportCommandError`, exit 2.
564
+ const discovered = await discoverSkillsFromConfig(config.skills, cwd, 'refuse');
565
+ // No early return on `discovered.length === 0` — see the function comment.
566
+ // The empty batch flows through every step below unchanged: the shared
567
+ // context is built for zero skills (its ledger and probe exist regardless),
568
+ // the loop runs zero times, and the builder refuses the zero denominator.
428
569
  // Merge packaging config for each skill.
429
570
  const { defaults, config: perSkillConfig } = config.skills;
430
571
  const validatableSkills = discovered.map(skill => ({
@@ -441,7 +582,7 @@ export async function validateCommand(pathArg, options) {
441
582
  // Every declared skill, not just `skillsToValidate`: `--skill x` narrows what is
442
583
  // REPORTED on, never what counts as some skill's declared test input.
443
584
  const projectSkills = collectDeclaredEvalSuites(config.skills, discovered);
444
- const sharedContext = await buildSharedValidationContext(skillsToValidate, projectSkills, logger);
585
+ const sharedContext = await buildSharedValidationContext(skillsToValidate, projectSkills, config, logger);
445
586
  // Validate each skill
446
587
  const results = [];
447
588
  for (const skill of skillsToValidate) {
@@ -461,16 +602,32 @@ export async function validateCommand(pathArg, options) {
461
602
  const runIssues = sharedContext.allowLedger === undefined
462
603
  ? []
463
604
  : allowUnusedIssues(sharedContext.allowLedger);
464
- // Output report and exit
465
605
  const duration = Date.now() - startTime;
466
606
  const verbose = options.verbose === true;
467
- outputValidationReport(results, duration, logger, verbose, runIssues);
468
- const hasErrors = results.some(r => r.status === 'error')
469
- || runIssues.some(i => i.severity === 'error');
470
- process.exit(hasErrors ? 1 : 0);
607
+ const document = buildValidateSummary(results, duration, verbose, runIssues, config.skills);
608
+ reportValidationToStderr(results, logger, verbose, runIssues, config.skills);
609
+ // The exit code is read off the DOCUMENT, not recomputed beside it, so the
610
+ // two cannot disagree: whatever the builder refused, the process refuses.
611
+ // `issueCounts.errors` counts an active error on any skill and every
612
+ // run-level error alike — including the zero-denominator refusal.
613
+ return { document, exitCode: document.issueCounts.errors > 0 ? 1 : 0 };
471
614
  }
472
615
  catch (error) {
473
- handleCommandError(error, logger, startTime, 'SkillsValidate');
616
+ return {
617
+ document: reportCommandError(error, logger, startTime, 'SkillsValidate'),
618
+ exitCode: 2,
619
+ failed: true,
620
+ };
474
621
  }
475
622
  }
623
+ /**
624
+ * Skills validate command implementation
625
+ */
626
+ export async function validateCommand(pathArg, options) {
627
+ // `undefined`: this command offers no `--format`, so its failure envelope is
628
+ // YAML like its report.
629
+ finishCommand(await runSkillsValidatePhase(pathArg, options), (document) => {
630
+ writeYamlSummary(document);
631
+ }, undefined);
632
+ }
476
633
  //# sourceMappingURL=validate.js.map