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

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 +95 -28
  3. package/dist/bin/vat.js +95 -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 +153 -0
  41. package/dist/commands/ard/emit.d.ts.map +1 -0
  42. package/dist/commands/ard/emit.js +276 -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 +80 -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 +1126 -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 +340 -0
  97. package/dist/commands/claude/context.d.ts.map +1 -0
  98. package/dist/commands/claude/context.js +1080 -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 +114 -0
  226. package/dist/commands/okf/index.js.map +1 -0
  227. package/dist/commands/okf/validate.d.ts +191 -0
  228. package/dist/commands/okf/validate.d.ts.map +1 -0
  229. package/dist/commands/okf/validate.js +190 -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 +154 -0
  259. package/dist/commands/resources/check-progress.d.ts.map +1 -0
  260. package/dist/commands/resources/check-progress.js +222 -0
  261. package/dist/commands/resources/check-progress.js.map +1 -0
  262. package/dist/commands/resources/check-supervisor.d.ts +465 -0
  263. package/dist/commands/resources/check-supervisor.d.ts.map +1 -0
  264. package/dist/commands/resources/check-supervisor.js +573 -0
  265. package/dist/commands/resources/check-supervisor.js.map +1 -0
  266. package/dist/commands/resources/check.d.ts +593 -0
  267. package/dist/commands/resources/check.d.ts.map +1 -0
  268. package/dist/commands/resources/check.js +1365 -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 +418 -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 +99 -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 +3 -5
  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 +138 -20
  374. package/dist/utils/command-error.d.ts.map +1 -1
  375. package/dist/utils/command-error.js +172 -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 +35 -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 +132 -2
  444. package/dist/utils/resource-loader.d.ts.map +1 -1
  445. package/dist/utils/resource-loader.js +288 -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 +141 -37
  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 +35 -26
  497. package/schemas/ard-emit.json +149 -0
  498. package/schemas/okf-validate.json +170 -0
  499. package/schemas/resources-check.json +229 -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
@@ -9,7 +9,8 @@
9
9
  */
10
10
  import { existsSync, statSync } from 'node:fs';
11
11
  import { readFile } from 'node:fs/promises';
12
- import { safeExecSync, safePath } from '@vibe-agent-toolkit/utils';
12
+ import { safePath } from '@vibe-agent-toolkit/utils';
13
+ import { safeExecSync } from '@vibe-agent-toolkit/utils/process';
13
14
  import * as tar from 'tar';
14
15
  /**
15
16
  * Detect source type from user input
@@ -33,9 +34,7 @@ export function detectSource(input) {
33
34
  }
34
35
  // Check filesystem
35
36
  const absolutePath = safePath.resolve(input);
36
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- User-provided CLI argument
37
37
  if (existsSync(absolutePath)) {
38
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- User-provided CLI argument, validated above
39
38
  const stat = statSync(absolutePath);
40
39
  if (stat.isDirectory()) {
41
40
  return 'local';
@@ -55,11 +54,9 @@ export function detectSource(input) {
55
54
  */
56
55
  export async function readPackageJsonVatMetadata(dir) {
57
56
  const packageJsonPath = safePath.join(dir, 'package.json');
58
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Directory path validated by caller
59
57
  if (!existsSync(packageJsonPath)) {
60
58
  throw new Error(`package.json not found in: ${dir}`);
61
59
  }
62
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Directory path validated by caller
63
60
  const content = await readFile(packageJsonPath, 'utf-8');
64
61
  const packageJson = JSON.parse(content);
65
62
  if (!packageJson.vat?.skills || packageJson.vat.skills.length === 0) {
@@ -94,7 +91,6 @@ export function downloadNpmPackage(packageName, tempDir) {
94
91
  // npm pack outputs the filename (e.g., "package-1.0.0.tgz")
95
92
  const tarballName = packOutput.toString().trim();
96
93
  const tarballPath = safePath.join(tempDir, tarballName);
97
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is constructed from temp dir
98
94
  if (!existsSync(tarballPath)) {
99
95
  throw new Error(`npm pack succeeded but tarball not found: ${tarballPath}`);
100
96
  }
@@ -106,7 +102,6 @@ export function downloadNpmPackage(packageName, tempDir) {
106
102
  sync: true,
107
103
  });
108
104
  const packageDir = safePath.join(tempDir, 'package');
109
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is constructed from temp dir
110
105
  if (!existsSync(packageDir)) {
111
106
  throw new Error(`npm tarball extracted but package/ directory not found`);
112
107
  }
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../../src/commands/claude/plugin/helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../../src/commands/claude/plugin/helpers.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,18 @@ import { getClaudeUserPaths } from '@vibe-agent-toolkit/claude-marketplace';
16
16
  import { Command } from 'commander';
17
17
  import { createLogger } from '../../../utils/logger.js';
18
18
  import { type PackageJsonVatReplaces } from './helpers.js';
19
+ /**
20
+ * A name about to become `join(skillsDir, name)` on a path that is deleted
21
+ * or overwritten. Refused unless it is ONE entry name — the sweep installed a
22
+ * SKILL.md declaring `name: ../victim` and watched `--force` delete
23
+ * `<skillsDir>/../victim`, exit 0, `status: success`.
24
+ *
25
+ * @param name - The declared name, exactly as it arrived
26
+ * @param origin - What declared it, for the refusal's wording
27
+ * @returns `name`, unchanged, when it is a single segment
28
+ * @throws When it is not
29
+ */
30
+ export declare function assertSkillEntryName(name: string, origin: string): string;
19
31
  export interface PluginInstallCommandOptions {
20
32
  skillsDir?: string;
21
33
  name?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/plugin/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,OAAO,EAAE,kBAAkB,EAAkC,MAAM,wCAAwC,CAAC;AAG5G,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAKL,KAAK,sBAAsB,EAG5B,MAAM,cAAc,CAAC;AA6EtB,MAAM,WAAW,2BAA2B;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,0BAA0B,IAAI,OAAO,CA0DpD;AA8pBD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/G;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GAAG,IAAI,CAEpG;AAED,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAAE,GAAG,SAAS,EAChC,gBAAgB,EAAE,MAAM,EAAE,EAC1B,KAAK,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC5C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,sBAAsB,EAChC,gBAAgB,EAAE,MAAM,EAAE,EAC1B,KAAK,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC5C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC,CAwBf"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/plugin/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,OAAO,EAAE,kBAAkB,EAAkC,MAAM,wCAAwC,CAAC;AAK5G,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAKL,KAAK,sBAAsB,EAG5B,MAAM,cAAc,CAAC;AA8EtB;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAQzE;AAED,MAAM,WAAW,2BAA2B;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,0BAA0B,IAAI,OAAO,CA0DpD;AAkqBD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/G;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GAAG,IAAI,CAEpG;AAED,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAAE,GAAG,SAAS,EAChC,gBAAgB,EAAE,MAAM,EAAE,EAC1B,KAAK,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC5C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,sBAAsB,EAChC,gBAAgB,EAAE,MAAM,EAAE,EAC1B,KAAK,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC5C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC,CA6Bf"}
@@ -17,7 +17,9 @@ import { mkdir, mkdtemp, rm, symlink } from 'node:fs/promises';
17
17
  import { basename } from 'node:path';
18
18
  import { readDeclaredSkillName } from '@vibe-agent-toolkit/agent-skills';
19
19
  import { getClaudeUserPaths, installPlugin, uninstallPlugin } from '@vibe-agent-toolkit/claude-marketplace';
20
- import { normalizedTmpdir, safeExecSync, toForwardSlash, safePath } from '@vibe-agent-toolkit/utils';
20
+ import { ExitCode } from '@vibe-agent-toolkit/schema';
21
+ import { direntKindFollowingSync, isPathAbsentError, isSingleFsSegment, normalizedTmpdir, toForwardSlash, safePath } from '@vibe-agent-toolkit/utils';
22
+ import { safeExecSync } from '@vibe-agent-toolkit/utils/process';
21
23
  import AdmZip from 'adm-zip';
22
24
  import { Command } from 'commander';
23
25
  import * as tar from 'tar';
@@ -28,16 +30,18 @@ import { detectSource, downloadNpmPackage, isGlobalNpmInstall, readPackageJsonVa
28
30
  const PLUGIN_MARKETPLACES_SUBPATH = safePath.join('dist', '.claude', 'plugins', 'marketplaces');
29
31
  const PACKAGE_JSON = 'package.json';
30
32
  /**
31
- * List immediate subdirectory names inside a directory.
33
+ * List immediate subdirectory names inside a directory, following links.
32
34
  * Returns empty array when the directory does not exist.
35
+ *
36
+ * Followed on purpose: a `--dev` install puts a plugin or marketplace here AS
37
+ * a symlink, and `Dirent.isDirectory()` is false for a link — so every dev
38
+ * install was invisible to the listing that uninstalls, lists and re-installs.
33
39
  */
34
40
  function listSubdirectories(dir) {
35
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- caller validates dir
36
41
  if (!existsSync(dir))
37
42
  return [];
38
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- caller validates dir
39
43
  return readdirSync(dir, { withFileTypes: true })
40
- .filter(d => d.isDirectory())
44
+ .filter(d => direntKindFollowingSync(dir, d) === 'directory')
41
45
  .map(d => d.name);
42
46
  }
43
47
  /**
@@ -64,13 +68,12 @@ async function registerPlugin(mpName, pluginName, pluginDir, version, packageNam
64
68
  * Shared between npm and local install paths to avoid duplication.
65
69
  */
66
70
  async function installPluginTreeAndExit(rootDir, marketplacesDir, sourceLabel, sourceType, startTime, logger, dryRun) {
67
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- rootDir from controlled source
68
71
  const pkgRaw = readFileSync(safePath.join(rootDir, PACKAGE_JSON), 'utf-8');
69
72
  const packageJson = JSON.parse(pkgRaw);
70
73
  const installedSkills = await copyPluginTree(marketplacesDir, packageJson, logger, dryRun);
71
74
  const duration = Date.now() - startTime;
72
75
  outputInstallSuccess(installedSkills, sourceLabel, sourceType, duration, logger, dryRun);
73
- process.exit(0);
76
+ process.exit(ExitCode.OK);
74
77
  }
75
78
  /**
76
79
  * Convert a skill name to a filesystem-safe path segment.
@@ -79,6 +82,24 @@ async function installPluginTreeAndExit(rootDir, marketplacesDir, sourceLabel, s
79
82
  function skillNameToFsPath(name) {
80
83
  return name.replaceAll(':', '__');
81
84
  }
85
+ /**
86
+ * A name about to become `join(skillsDir, name)` on a path that is deleted
87
+ * or overwritten. Refused unless it is ONE entry name — the sweep installed a
88
+ * SKILL.md declaring `name: ../victim` and watched `--force` delete
89
+ * `<skillsDir>/../victim`, exit 0, `status: success`.
90
+ *
91
+ * @param name - The declared name, exactly as it arrived
92
+ * @param origin - What declared it, for the refusal's wording
93
+ * @returns `name`, unchanged, when it is a single segment
94
+ * @throws When it is not
95
+ */
96
+ export function assertSkillEntryName(name, origin) {
97
+ if (!isSingleFsSegment(name)) {
98
+ throw new Error(`Refusing to install "${name}" (${origin}): a skill name must be a single path segment ` +
99
+ `(no separators, not "." or "..").`);
100
+ }
101
+ return name;
102
+ }
82
103
  export function createPluginInstallCommand() {
83
104
  const command = new Command('install');
84
105
  command
@@ -142,7 +163,7 @@ async function installCommand(source, options) {
142
163
  process.stdout.write(`reason: "claude.ai org provisioning API not yet confirmed as public"\n`);
143
164
  process.stdout.write(`requestedTarget: claude.ai\n`);
144
165
  process.stdout.write(`guidance: "Use claude.ai admin console to upload a .zip manually, or use --target api.anthropic.com for workspace-scoped skill management"\n`);
145
- process.exit(1);
166
+ process.exit(ExitCode.ERROR);
146
167
  }
147
168
  // Handle --build (implies --dev)
148
169
  if (options.build) {
@@ -209,7 +230,6 @@ async function handleNpmInstall(source, options, logger, startTime) {
209
230
  const extractedPath = downloadNpmPackage(packageName, tempDir);
210
231
  // If the package ships a pre-built plugin tree, install via dumb copy.
211
232
  const marketplacesDir = safePath.join(extractedPath, PLUGIN_MARKETPLACES_SUBPATH);
212
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- path from controlled extractedPath + constant subpath
213
233
  const hasPlugin = !options.userInstallWithoutPlugin && existsSync(marketplacesDir);
214
234
  if (hasPlugin) {
215
235
  logger.info(' Plugin detected — installing via Claude plugin system');
@@ -238,7 +258,7 @@ async function handleNpmInstall(source, options, logger, startTime) {
238
258
  name,
239
259
  installPath: safePath.join(skillsDir, name),
240
260
  })), `npm:${packageName}`, 'npm', duration, logger, options.dryRun);
241
- process.exit(0);
261
+ process.exit(ExitCode.OK);
242
262
  }
243
263
  finally {
244
264
  await rm(tempDir, { recursive: true, force: true });
@@ -253,13 +273,11 @@ async function handleLocalInstall(source, options, logger, startTime) {
253
273
  const skillsDir = options.skillsDir ?? getClaudeUserPaths().skillsDir;
254
274
  // Check for pre-built plugin tree first
255
275
  const marketplacesDir = safePath.join(sourcePath, PLUGIN_MARKETPLACES_SUBPATH);
256
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- User-provided CLI argument
257
276
  if (!options.userInstallWithoutPlugin && existsSync(marketplacesDir)) {
258
277
  await installPluginTreeAndExit(sourcePath, marketplacesDir, `local:${sourcePath}`, 'local', startTime, logger, options.dryRun);
259
278
  }
260
279
  // Check if directory contains package.json with vat.skills
261
280
  const packageJsonPath = safePath.join(sourcePath, 'package.json');
262
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- User-provided CLI argument
263
281
  const hasPackageJson = existsSync(packageJsonPath);
264
282
  let installed;
265
283
  if (hasPackageJson) {
@@ -287,7 +305,7 @@ async function handleLocalInstall(source, options, logger, startTime) {
287
305
  }
288
306
  const duration = Date.now() - startTime;
289
307
  outputInstallSuccess(installed, `local:${sourcePath}`, 'local', duration, logger, options.dryRun);
290
- process.exit(0);
308
+ process.exit(ExitCode.OK);
291
309
  }
292
310
  /**
293
311
  * Handle ZIP file installation
@@ -295,7 +313,6 @@ async function handleLocalInstall(source, options, logger, startTime) {
295
313
  async function handleZipInstall(source, options, logger, startTime) {
296
314
  const sourcePath = safePath.resolve(source);
297
315
  logger.info(`📥 Installing skill from ZIP: ${sourcePath}`);
298
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- User-provided CLI argument
299
316
  if (!existsSync(sourcePath)) {
300
317
  throw new Error(`ZIP file not found: ${sourcePath}`);
301
318
  }
@@ -304,12 +321,11 @@ async function handleZipInstall(source, options, logger, startTime) {
304
321
  if (!options.dryRun) {
305
322
  logger.info(' Extracting ZIP...');
306
323
  const zip = new AdmZip(sourcePath);
307
- // eslint-disable-next-line sonarjs/no-unsafe-unzip -- User-provided local files, isolated plugin directory
308
324
  zip.extractAllTo(installPath, /* overwrite */ true);
309
325
  }
310
326
  const duration = Date.now() - startTime;
311
327
  outputInstallSuccess([{ name: skillName, installPath }], sourcePath, 'zip', duration, logger, options.dryRun);
312
- process.exit(0);
328
+ process.exit(ExitCode.OK);
313
329
  }
314
330
  /**
315
331
  * Handle npm tarball (.tgz / .tar.gz) installation.
@@ -319,7 +335,6 @@ async function handleZipInstall(source, options, logger, startTime) {
319
335
  async function handleTgzInstall(source, options, logger, startTime) {
320
336
  const sourcePath = safePath.resolve(source);
321
337
  logger.info(`📥 Installing skill from tarball: ${sourcePath}`);
322
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- User-provided CLI argument
323
338
  if (!existsSync(sourcePath)) {
324
339
  throw new Error(`Tarball not found: ${sourcePath}`);
325
340
  }
@@ -329,11 +344,9 @@ async function handleTgzInstall(source, options, logger, startTime) {
329
344
  await tar.extract({ file: sourcePath, cwd: tempDir });
330
345
  // npm pack tarballs extract under package/ subdirectory
331
346
  const packageDir = safePath.join(tempDir, 'package');
332
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- tempDir is controlled
333
347
  const extractedDir = existsSync(packageDir) ? packageDir : tempDir;
334
348
  // Delegate to local install logic
335
349
  const marketplacesDir = safePath.join(extractedDir, PLUGIN_MARKETPLACES_SUBPATH);
336
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- tempDir is controlled
337
350
  if (!options.userInstallWithoutPlugin && existsSync(marketplacesDir)) {
338
351
  await installPluginTreeAndExit(extractedDir, marketplacesDir, sourcePath, 'tgz', startTime, logger, options.dryRun);
339
352
  }
@@ -347,7 +360,7 @@ async function handleTgzInstall(source, options, logger, startTime) {
347
360
  }
348
361
  const duration = Date.now() - startTime;
349
362
  outputInstallSuccess(skillNames.map(name => ({ name, installPath: safePath.join(skillsDir, name) })), sourcePath, 'tgz', duration, logger, options.dryRun);
350
- process.exit(0);
363
+ process.exit(ExitCode.OK);
351
364
  }
352
365
  finally {
353
366
  await rm(tempDir, { recursive: true, force: true });
@@ -358,22 +371,23 @@ async function handleTgzInstall(source, options, logger, startTime) {
358
371
  * Throws if the path exists and --force was not passed.
359
372
  */
360
373
  async function prepareDevSymlinkDest(destPath, skillFsName, options) {
374
+ // The probe is the ONLY thing whose failure may read as "nothing there". A
375
+ // refusal on the probe, or a failed removal, stays loud: this used to catch
376
+ // everything and recognise its own throw by the words in its message.
361
377
  try {
362
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
363
378
  lstatSync(destPath);
364
- if (!options.force) {
365
- throw new Error(`Skill "${skillFsName}" already installed at ${destPath}.\n` +
366
- `Use --force to overwrite.`);
367
- }
368
- if (!options.dryRun) {
369
- await rm(destPath, { recursive: true, force: true });
370
- }
371
379
  }
372
380
  catch (error) {
373
- if (error instanceof Error && error.message.includes('already installed')) {
374
- throw error;
375
- }
376
- // Does not exist — that's fine
381
+ if (isPathAbsentError(error))
382
+ return;
383
+ throw error;
384
+ }
385
+ if (!options.force) {
386
+ throw new Error(`Skill "${skillFsName}" already installed at ${destPath}.\n` +
387
+ `Use --force to overwrite.`);
388
+ }
389
+ if (!options.dryRun) {
390
+ await rm(destPath, { recursive: true, force: true });
377
391
  }
378
392
  }
379
393
  /**
@@ -383,15 +397,34 @@ async function prepareDevSymlinkDest(destPath, skillFsName, options) {
383
397
  async function symlinkDevSkill(skillFsName, destSkillsDir, cwd, pluginName, options, logger) {
384
398
  const srcSkillPath = safePath.resolve(cwd, 'dist', 'skills', skillFsName);
385
399
  const destSkillPath = safePath.join(destSkillsDir, skillFsName);
386
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
387
400
  if (!existsSync(srcSkillPath)) {
388
401
  logger.info(` Warning: skill not built at ${srcSkillPath} — skipping symlink`);
389
402
  return null;
390
403
  }
391
404
  await prepareDevSymlinkDest(destSkillPath, skillFsName, options);
392
405
  if (!options.dryRun) {
393
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
394
- await symlink(srcSkillPath, destSkillPath, 'dir');
406
+ try {
407
+ // eslint-disable-next-line local/no-bare-symlink-in-tests -- eyes open: `handleDevInstall` refuses win32 upstream, so the Windows privilege hazard the rule names cannot be reached here.
408
+ await symlink(srcSkillPath, destSkillPath, 'dir');
409
+ }
410
+ catch (error) {
411
+ // ⚠️ POSIX-only in practice: `handleDevInstall` throws on win32 before
412
+ // this call chain begins, so Windows-specific handling here would be dead
413
+ // code — an earlier revision added exactly that. Making `--dev` work on
414
+ // Windows means changing that guard (a junction needs no elevation), not
415
+ // this catch. Not falling back to a copy either — dev mode exists so a
416
+ // rebuild is picked up live, and a copy would quietly stop that.
417
+ //
418
+ // ⚠️ This throws mid-loop, after `devInstallMarketplace` already removed
419
+ // the previous marketplace directory and `devInstallPlugin` copied the
420
+ // non-skill content. Earlier skills are linked, later ones are not, and
421
+ // `registerPlugin` never runs — so the tree is on disk but unregistered.
422
+ // Recoverable by re-running, which starts over.
423
+ const detail = error instanceof Error ? error.message : String(error);
424
+ throw new Error(`Could not symlink ${skillFsName} to ${destSkillPath}: ${detail}\n` +
425
+ 'Check that the destination directory is writable. This install is now ' +
426
+ 'incomplete — re-run the same command to start over.');
427
+ }
395
428
  }
396
429
  logger.info(` Symlinked: ${safePath.relative(cwd, destSkillPath)} → ${srcSkillPath}`);
397
430
  return {
@@ -406,17 +439,16 @@ async function symlinkDevSkill(skillFsName, destSkillsDir, cwd, pluginName, opti
406
439
  async function symlinkPluginSkills(srcPluginDir, destPluginDir, pluginName, cwd, options, logger) {
407
440
  const installed = [];
408
441
  const srcSkillsDir = safePath.join(srcPluginDir, 'skills');
409
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
410
442
  if (!existsSync(srcSkillsDir)) {
411
443
  return installed;
412
444
  }
413
445
  const destSkillsDir = safePath.join(destPluginDir, 'skills');
414
446
  if (!options.dryRun) {
415
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
416
447
  await mkdir(destSkillsDir, { recursive: true });
417
448
  }
418
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
419
- const skillEntries = readdirSync(srcSkillsDir, { withFileTypes: true }).filter(d => d.isDirectory());
449
+ // Followed: a skill directory that is itself a link is still a skill to link.
450
+ const skillEntries = readdirSync(srcSkillsDir, { withFileTypes: true })
451
+ .filter(d => direntKindFollowingSync(srcSkillsDir, d) === 'directory');
420
452
  for (const skillEntry of skillEntries) {
421
453
  const result = await symlinkDevSkill(skillEntry.name, destSkillsDir, cwd, pluginName, options, logger);
422
454
  if (result) {
@@ -431,11 +463,9 @@ async function symlinkPluginSkills(srcPluginDir, destPluginDir, pluginName, cwd,
431
463
  async function devInstallPlugin(ctx, cwd, options, logger) {
432
464
  const { mpName, pluginName, srcPluginDir, destPluginDir, packageName, version, paths } = ctx;
433
465
  if (!options.dryRun) {
434
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
435
466
  await mkdir(destPluginDir, { recursive: true });
436
467
  }
437
468
  // Copy non-skill entries (e.g. .claude-plugin/)
438
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
439
469
  for (const entry of readdirSync(srcPluginDir, { withFileTypes: true })) {
440
470
  if (entry.name !== 'skills' && !options.dryRun) {
441
471
  const srcEntry = safePath.join(srcPluginDir, entry.name);
@@ -459,12 +489,10 @@ async function devInstallMarketplace(mpName, srcMpDir, packageInfo, cwd, options
459
489
  const installed = [];
460
490
  if (!options.dryRun) {
461
491
  await rm(destMpDir, { recursive: true, force: true });
462
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
463
492
  await mkdir(destMpDir, { recursive: true });
464
493
  }
465
494
  logger.info(` Marketplace: ${mpName} → ${destMpDir}`);
466
495
  // Copy non-plugin content (e.g. .claude-plugin/marketplace.json)
467
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
468
496
  for (const entry of readdirSync(srcMpDir, { withFileTypes: true })) {
469
497
  if (entry.name !== 'plugins' && !options.dryRun) {
470
498
  const srcEntry = safePath.join(srcMpDir, entry.name);
@@ -510,13 +538,11 @@ async function handleDevInstall(options, logger, startTime) {
510
538
  }
511
539
  // Check for pre-built plugin tree
512
540
  const marketplacesDir = safePath.join(cwd, PLUGIN_MARKETPLACES_SUBPATH);
513
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- cwd from CLI option or process.cwd()
514
541
  if (!existsSync(marketplacesDir)) {
515
542
  throw new Error(`Plugin tree not found at ${marketplacesDir}\n` +
516
543
  `Run: vat build first (builds the plugin tree)`);
517
544
  }
518
545
  // Read package.json for package name/version
519
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- cwd from CLI option or process.cwd()
520
546
  const pkgRaw = readFileSync(safePath.join(cwd, PACKAGE_JSON), 'utf-8');
521
547
  const packageJson = JSON.parse(pkgRaw);
522
548
  logger.info(`📥 Dev-installing plugin tree from ${packageJson.name}`);
@@ -535,7 +561,7 @@ async function handleDevInstall(options, logger, startTime) {
535
561
  }
536
562
  const duration = Date.now() - startTime;
537
563
  outputDevSuccess(installed, packageJson.name, duration, logger, options.dryRun);
538
- process.exit(0);
564
+ process.exit(ExitCode.OK);
539
565
  }
540
566
  /**
541
567
  * Shell out to vat build (skills + claude plugin tree)
@@ -556,16 +582,14 @@ async function handleNpmPostinstall(options, logger, startTime) {
556
582
  logger.info(`📥 Running npm postinstall hook`);
557
583
  if (!isGlobalNpmInstall()) {
558
584
  logger.info(' Skipping: Not a global npm install');
559
- process.exit(0);
585
+ process.exit(ExitCode.OK);
560
586
  }
561
587
  const cwd = process.cwd();
562
588
  // Check for pre-built plugin tree (dist/.claude/plugins/marketplaces/)
563
589
  const marketplacesDir = safePath.join(cwd, PLUGIN_MARKETPLACES_SUBPATH);
564
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- path constructed from validated cwd and constant subpath
565
590
  const hasPluginTree = existsSync(marketplacesDir);
566
591
  if (!options.userInstallWithoutPlugin) {
567
592
  if (hasPluginTree) {
568
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- path constructed from validated cwd and constant package.json name
569
593
  const pkgRaw = readFileSync(safePath.join(cwd, PACKAGE_JSON), 'utf-8');
570
594
  const packageJson = JSON.parse(pkgRaw);
571
595
  logger.info(` Package: ${packageJson.name}@${packageJson.version ?? 'unknown'}`);
@@ -580,7 +604,7 @@ async function handleNpmPostinstall(options, logger, startTime) {
580
604
  logger.info(` Run 'vat build' to generate plugin artifacts before publishing.`);
581
605
  logger.info(` Skipping install — no skills registered.`);
582
606
  }
583
- process.exit(0);
607
+ process.exit(ExitCode.OK);
584
608
  }
585
609
  // --user-install-without-plugin: install skills directly to ~/.claude/skills/
586
610
  const { packageJson, skills } = await readPackageJsonVatMetadata(cwd);
@@ -593,7 +617,7 @@ async function handleNpmPostinstall(options, logger, startTime) {
593
617
  const duration = Date.now() - startTime;
594
618
  logger.info(`✅ Installed ${skills.length} skill(s) from ${packageJson.name}`);
595
619
  logger.info(` Duration: ${duration}ms`);
596
- process.exit(0);
620
+ process.exit(ExitCode.OK);
597
621
  }
598
622
  /**
599
623
  * Execute vat.replaces cleanup before installing the new plugin.
@@ -630,15 +654,21 @@ export async function executeReplaces(replaces, marketplaceNames, paths, dryRun,
630
654
  await removeOldPlugins(replaces.plugins, marketplaceNames, paths, dryRun, logger);
631
655
  // Remove legacy flat-skill installs from ~/.claude/skills/<name>
632
656
  for (const skillName of replaces.flatSkills ?? []) {
633
- const skillPath = safePath.join(paths.skillsDir, skillName);
657
+ // The entry comes from the INSTALLED package's package.json, and this is
658
+ // an `rm -rf` with no flag in front of it: `"../victim"` used to remove a
659
+ // sibling of the skills dir (with the default paths, `"../.."` is $HOME).
660
+ const skillPath = safePath.join(paths.skillsDir, assertSkillEntryName(skillName, 'vat.replaces.flatSkills'));
634
661
  let pathExists = false;
635
662
  try {
636
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- derived from Claude user paths + skill name
637
663
  lstatSync(skillPath); // throws if path itself doesn't exist (doesn't follow symlinks)
638
664
  pathExists = true;
639
665
  }
640
- catch {
641
- // path doesn't exist or is inaccessible — nothing to remove
666
+ catch (error) {
667
+ // Path doesn't exist — nothing to remove. One the OS refuses to examine
668
+ // is not "nothing to remove": the legacy install is still there and a
669
+ // silent skip leaves it beside its replacement.
670
+ if (!isPathAbsentError(error))
671
+ throw error;
642
672
  }
643
673
  if (pathExists) {
644
674
  if (dryRun) {
@@ -673,7 +703,6 @@ async function copyPluginTree(marketplacesDir, packageJson, logger, dryRun) {
673
703
  // package do not persist in the user's Claude installation.
674
704
  logger.info(` Copying marketplace: ${mpName} → ${destMpDir}`);
675
705
  await rm(destMpDir, { recursive: true, force: true });
676
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Resolved from constant subpath
677
706
  await mkdir(destMpDir, { recursive: true });
678
707
  cpSync(srcMpDir, destMpDir, { recursive: true, force: true });
679
708
  // Register each plugin and collect installed skill names
@@ -696,15 +725,19 @@ async function copyPluginTree(marketplacesDir, packageJson, logger, dryRun) {
696
725
  */
697
726
  async function prepareInstallation(skillName, options) {
698
727
  const skillsDir = options.skillsDir ?? getClaudeUserPaths().skillsDir;
699
- const installPath = safePath.join(skillsDir, skillName);
728
+ // The declared name is author-controlled (SKILL.md `name:`, package.json
729
+ // `vat.skills[]`) and `--force` turns this path into an `rm -rf`.
730
+ const installPath = safePath.join(skillsDir, assertSkillEntryName(skillName, 'skill name'));
700
731
  let exists = false;
701
732
  try {
702
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Install path from config
703
733
  lstatSync(installPath);
704
734
  exists = true;
705
735
  }
706
- catch {
707
- // Does not exist
736
+ catch (error) {
737
+ // Does not exist. A refusal is not that: it used to read as "free", and
738
+ // the extraction that followed then met the same refusal without a name.
739
+ if (!isPathAbsentError(error))
740
+ throw error;
708
741
  }
709
742
  if (exists && !options.force) {
710
743
  throw new Error(`Skill already exists at ${installPath}. Use --force to overwrite.`);
@@ -713,7 +746,6 @@ async function prepareInstallation(skillName, options) {
713
746
  await rm(installPath, { recursive: true, force: true });
714
747
  }
715
748
  if (!options.dryRun) {
716
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Skills directory path, safe
717
749
  await mkdir(skillsDir, { recursive: true });
718
750
  }
719
751
  return { skillsDir, installPath };
@@ -722,7 +754,6 @@ async function prepareInstallation(skillName, options) {
722
754
  * Install skill from a path to plugins directory
723
755
  */
724
756
  async function installSkillFromPath(skillPath, skillName, options, logger) {
725
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Validated path
726
757
  if (!existsSync(skillPath)) {
727
758
  throw new Error(`Skill path not found: ${skillPath}`);
728
759
  }