@vibe-agent-toolkit/cli 0.1.41-rc.5 → 0.1.41-rc.7

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 (171) hide show
  1. package/README.md +4 -3
  2. package/dist/bin/vat +1 -1
  3. package/dist/bin/vat.js +1 -1
  4. package/dist/bin/vat.js.map +1 -1
  5. package/dist/bin.js +2 -4
  6. package/dist/bin.js.map +1 -1
  7. package/dist/commands/agent/help.d.ts.map +1 -1
  8. package/dist/commands/agent/help.js +2 -4
  9. package/dist/commands/agent/help.js.map +1 -1
  10. package/dist/commands/audit/hierarchical-output.d.ts +6 -2
  11. package/dist/commands/audit/hierarchical-output.d.ts.map +1 -1
  12. package/dist/commands/audit/hierarchical-output.js +93 -50
  13. package/dist/commands/audit/hierarchical-output.js.map +1 -1
  14. package/dist/commands/audit-settings.d.ts +35 -0
  15. package/dist/commands/audit-settings.d.ts.map +1 -1
  16. package/dist/commands/audit-settings.js +121 -51
  17. package/dist/commands/audit-settings.js.map +1 -1
  18. package/dist/commands/audit.d.ts +63 -1
  19. package/dist/commands/audit.d.ts.map +1 -1
  20. package/dist/commands/audit.js +329 -187
  21. package/dist/commands/audit.js.map +1 -1
  22. package/dist/commands/build.d.ts.map +1 -1
  23. package/dist/commands/build.js +47 -18
  24. package/dist/commands/build.js.map +1 -1
  25. package/dist/commands/claude/marketplace/license-utils.d.ts +39 -2
  26. package/dist/commands/claude/marketplace/license-utils.d.ts.map +1 -1
  27. package/dist/commands/claude/marketplace/license-utils.js +114 -68
  28. package/dist/commands/claude/marketplace/license-utils.js.map +1 -1
  29. package/dist/commands/claude/marketplace/publish.js +5 -4
  30. package/dist/commands/claude/marketplace/publish.js.map +1 -1
  31. package/dist/commands/claude/marketplace/validate.d.ts.map +1 -1
  32. package/dist/commands/claude/marketplace/validate.js +13 -19
  33. package/dist/commands/claude/marketplace/validate.js.map +1 -1
  34. package/dist/commands/claude/org/skills.d.ts +21 -0
  35. package/dist/commands/claude/org/skills.d.ts.map +1 -1
  36. package/dist/commands/claude/org/skills.js +107 -30
  37. package/dist/commands/claude/org/skills.js.map +1 -1
  38. package/dist/commands/claude/plugin/build.d.ts +94 -1
  39. package/dist/commands/claude/plugin/build.d.ts.map +1 -1
  40. package/dist/commands/claude/plugin/build.js +307 -106
  41. package/dist/commands/claude/plugin/build.js.map +1 -1
  42. package/dist/commands/claude/plugin/install.d.ts.map +1 -1
  43. package/dist/commands/claude/plugin/install.js +7 -2
  44. package/dist/commands/claude/plugin/install.js.map +1 -1
  45. package/dist/commands/claude/plugin/marketplace-json.d.ts +36 -0
  46. package/dist/commands/claude/plugin/marketplace-json.d.ts.map +1 -0
  47. package/dist/commands/claude/plugin/marketplace-json.js +34 -0
  48. package/dist/commands/claude/plugin/marketplace-json.js.map +1 -0
  49. package/dist/commands/claude/plugin/plugin-json-merge.d.ts +30 -1
  50. package/dist/commands/claude/plugin/plugin-json-merge.d.ts.map +1 -1
  51. package/dist/commands/claude/plugin/plugin-json-merge.js +92 -14
  52. package/dist/commands/claude/plugin/plugin-json-merge.js.map +1 -1
  53. package/dist/commands/claude/plugin/tree-copy.d.ts +10 -3
  54. package/dist/commands/claude/plugin/tree-copy.d.ts.map +1 -1
  55. package/dist/commands/claude/plugin/tree-copy.js +0 -1
  56. package/dist/commands/claude/plugin/tree-copy.js.map +1 -1
  57. package/dist/commands/claude/plugin/uninstall.d.ts.map +1 -1
  58. package/dist/commands/claude/plugin/uninstall.js +10 -2
  59. package/dist/commands/claude/plugin/uninstall.js.map +1 -1
  60. package/dist/commands/corpus/runner.d.ts.map +1 -1
  61. package/dist/commands/corpus/runner.js +15 -26
  62. package/dist/commands/corpus/runner.js.map +1 -1
  63. package/dist/commands/doctor.d.ts +57 -8
  64. package/dist/commands/doctor.d.ts.map +1 -1
  65. package/dist/commands/doctor.js +142 -67
  66. package/dist/commands/doctor.js.map +1 -1
  67. package/dist/commands/phase-utils.d.ts +62 -2
  68. package/dist/commands/phase-utils.d.ts.map +1 -1
  69. package/dist/commands/phase-utils.js +74 -2
  70. package/dist/commands/phase-utils.js.map +1 -1
  71. package/dist/commands/rag/help.d.ts.map +1 -1
  72. package/dist/commands/rag/help.js +2 -4
  73. package/dist/commands/rag/help.js.map +1 -1
  74. package/dist/commands/resources/help.d.ts.map +1 -1
  75. package/dist/commands/resources/help.js +2 -4
  76. package/dist/commands/resources/help.js.map +1 -1
  77. package/dist/commands/resources/index.d.ts.map +1 -1
  78. package/dist/commands/resources/index.js +13 -6
  79. package/dist/commands/resources/index.js.map +1 -1
  80. package/dist/commands/resources/validate.d.ts +19 -0
  81. package/dist/commands/resources/validate.d.ts.map +1 -1
  82. package/dist/commands/resources/validate.js +89 -24
  83. package/dist/commands/resources/validate.js.map +1 -1
  84. package/dist/commands/skill/review.d.ts.map +1 -1
  85. package/dist/commands/skill/review.js +33 -20
  86. package/dist/commands/skill/review.js.map +1 -1
  87. package/dist/commands/skill/test/configure.d.ts.map +1 -1
  88. package/dist/commands/skill/test/configure.js +1 -1
  89. package/dist/commands/skill/test/configure.js.map +1 -1
  90. package/dist/commands/skill/test/run.d.ts +29 -2
  91. package/dist/commands/skill/test/run.d.ts.map +1 -1
  92. package/dist/commands/skill/test/run.js +67 -19
  93. package/dist/commands/skill/test/run.js.map +1 -1
  94. package/dist/commands/skills/build.d.ts +51 -0
  95. package/dist/commands/skills/build.d.ts.map +1 -1
  96. package/dist/commands/skills/build.js +94 -86
  97. package/dist/commands/skills/build.js.map +1 -1
  98. package/dist/commands/skills/install.d.ts.map +1 -1
  99. package/dist/commands/skills/install.js +79 -25
  100. package/dist/commands/skills/install.js.map +1 -1
  101. package/dist/commands/skills/list.d.ts.map +1 -1
  102. package/dist/commands/skills/list.js +9 -5
  103. package/dist/commands/skills/list.js.map +1 -1
  104. package/dist/commands/skills/package.d.ts +2 -0
  105. package/dist/commands/skills/package.d.ts.map +1 -1
  106. package/dist/commands/skills/package.js +61 -42
  107. package/dist/commands/skills/package.js.map +1 -1
  108. package/dist/commands/skills/skill-discovery.d.ts +7 -0
  109. package/dist/commands/skills/skill-discovery.d.ts.map +1 -1
  110. package/dist/commands/skills/skill-discovery.js +14 -4
  111. package/dist/commands/skills/skill-discovery.js.map +1 -1
  112. package/dist/commands/skills/validate.d.ts +38 -0
  113. package/dist/commands/skills/validate.d.ts.map +1 -1
  114. package/dist/commands/skills/validate.js +125 -70
  115. package/dist/commands/skills/validate.js.map +1 -1
  116. package/dist/commands/validate.d.ts.map +1 -1
  117. package/dist/commands/validate.js +11 -5
  118. package/dist/commands/validate.js.map +1 -1
  119. package/dist/commands/verify.d.ts.map +1 -1
  120. package/dist/commands/verify.js +76 -28
  121. package/dist/commands/verify.js.map +1 -1
  122. package/dist/skill-resolution/classify.d.ts +7 -2
  123. package/dist/skill-resolution/classify.d.ts.map +1 -1
  124. package/dist/skill-resolution/classify.js +7 -2
  125. package/dist/skill-resolution/classify.js.map +1 -1
  126. package/dist/skill-resolution/resolve-skill-reference.d.ts +10 -8
  127. package/dist/skill-resolution/resolve-skill-reference.d.ts.map +1 -1
  128. package/dist/skill-resolution/resolve-skill-reference.js +62 -23
  129. package/dist/skill-resolution/resolve-skill-reference.js.map +1 -1
  130. package/dist/skill-resolution/types.d.ts +3 -2
  131. package/dist/skill-resolution/types.d.ts.map +1 -1
  132. package/dist/utils/config-loader.d.ts.map +1 -1
  133. package/dist/utils/config-loader.js +0 -2
  134. package/dist/utils/config-loader.js.map +1 -1
  135. package/dist/utils/help-loader.d.ts +16 -0
  136. package/dist/utils/help-loader.d.ts.map +1 -1
  137. package/dist/utils/help-loader.js +31 -1
  138. package/dist/utils/help-loader.js.map +1 -1
  139. package/dist/utils/issue-anchor.d.ts +26 -0
  140. package/dist/utils/issue-anchor.d.ts.map +1 -0
  141. package/dist/utils/issue-anchor.js +39 -0
  142. package/dist/utils/issue-anchor.js.map +1 -0
  143. package/dist/utils/issue-rendering.d.ts +61 -0
  144. package/dist/utils/issue-rendering.d.ts.map +1 -0
  145. package/dist/utils/issue-rendering.js +135 -0
  146. package/dist/utils/issue-rendering.js.map +1 -0
  147. package/dist/utils/output.d.ts +26 -4
  148. package/dist/utils/output.d.ts.map +1 -1
  149. package/dist/utils/output.js +27 -6
  150. package/dist/utils/output.js.map +1 -1
  151. package/dist/utils/project-root-policy.d.ts +2 -2
  152. package/dist/utils/project-root-policy.js +2 -2
  153. package/dist/utils/skill-packaging-config.d.ts +15 -6
  154. package/dist/utils/skill-packaging-config.d.ts.map +1 -1
  155. package/dist/utils/skill-packaging-config.js +23 -5
  156. package/dist/utils/skill-packaging-config.js.map +1 -1
  157. package/dist/utils/validate-help-files.d.ts +3 -2
  158. package/dist/utils/validate-help-files.d.ts.map +1 -1
  159. package/dist/utils/validate-help-files.js +48 -5
  160. package/dist/utils/validate-help-files.js.map +1 -1
  161. package/dist/utils/verdict-helpers.d.ts +10 -2
  162. package/dist/utils/verdict-helpers.d.ts.map +1 -1
  163. package/dist/utils/verdict-helpers.js +13 -3
  164. package/dist/utils/verdict-helpers.js.map +1 -1
  165. package/docs/audit.md +40 -14
  166. package/docs/doctor.md +46 -10
  167. package/docs/index.md +1 -1
  168. package/docs/resources.md +24 -8
  169. package/docs/skill-test.md +47 -3
  170. package/docs/skills.md +28 -6
  171. package/package.json +12 -12
@@ -3,22 +3,76 @@
3
3
  *
4
4
  * Handles SPDX shortcut identifiers (e.g., "mit" → full MIT license text)
5
5
  * and file path references (e.g., "./LICENSE" → copy as-is).
6
+ *
7
+ * The output of {@link generateLicenseText} is written verbatim as the LICENSE
8
+ * file of a published marketplace, so VAT only accepts an SPDX shortcut when it
9
+ * carries that license's complete text. For everything else it refuses and
10
+ * directs the user at the file-path form — see {@link UNRENDERABLE_SPDX_IDS}.
6
11
  */
7
12
  import { readFileSync } from 'node:fs';
8
13
  import { safePath } from '@vibe-agent-toolkit/utils';
9
- /** Known SPDX identifiers (lowercase). Extend as needed. */
10
- const KNOWN_SPDX_IDS = new Set([
11
- 'mit',
12
- 'apache-2.0',
13
- 'gpl-2.0',
14
- 'gpl-3.0',
15
- 'lgpl-2.1',
16
- 'lgpl-3.0',
17
- 'bsd-2-clause',
18
- 'bsd-3-clause',
19
- 'isc',
20
- 'mpl-2.0',
21
- 'unlicense',
14
+ /** Build a lowercase-keyed lookup from canonical SPDX identifiers. */
15
+ function byLowercaseId(canonicalIds) {
16
+ return new Map(canonicalIds.map(id => [id.toLowerCase(), id]));
17
+ }
18
+ /**
19
+ * Complete license texts VAT can emit, keyed by canonical SPDX identifier.
20
+ *
21
+ * This table — not a separate list of identifiers — is the source of truth for
22
+ * what VAT will render, so it is structurally impossible to vouch for an
23
+ * identifier without supplying its text. The returned string is written
24
+ * verbatim as the LICENSE file of a published marketplace, so every entry must
25
+ * be the license itself: not a summary, not a notice header.
26
+ */
27
+ const LICENSE_TEXT_RENDERERS = {
28
+ MIT: (ownerName, year) => `MIT License
29
+
30
+ Copyright (c) ${year} ${ownerName}
31
+
32
+ Permission is hereby granted, free of charge, to any person obtaining a copy
33
+ of this software and associated documentation files (the "Software"), to deal
34
+ in the Software without restriction, including without limitation the rights
35
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
+ copies of the Software, and to permit persons to whom the Software is
37
+ furnished to do so, subject to the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be included in all
40
+ copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
48
+ SOFTWARE.
49
+ `,
50
+ };
51
+ /**
52
+ * SPDX identifiers VAT embeds the complete license text for.
53
+ *
54
+ * Derived from {@link LICENSE_TEXT_RENDERERS} so the two can never disagree.
55
+ */
56
+ export const RENDERABLE_SPDX_IDS = byLowercaseId(Object.keys(LICENSE_TEXT_RENDERERS));
57
+ /**
58
+ * SPDX identifiers VAT recognizes but refuses to render.
59
+ *
60
+ * VAT carries no vetted copy of these texts, and a summary or a notice header
61
+ * is not a license: GPL-3.0 §4 and Apache-2.0 §4(a) both require conveying a
62
+ * copy of the License with the work. Listing them here buys a specific,
63
+ * actionable error instead of a generic "unknown identifier".
64
+ */
65
+ export const UNRENDERABLE_SPDX_IDS = byLowercaseId([
66
+ 'Apache-2.0',
67
+ 'GPL-2.0',
68
+ 'GPL-3.0',
69
+ 'LGPL-2.1',
70
+ 'LGPL-3.0',
71
+ 'BSD-2-Clause',
72
+ 'BSD-3-Clause',
73
+ 'ISC',
74
+ 'MPL-2.0',
75
+ 'Unlicense',
22
76
  ]);
23
77
  /**
24
78
  * Check if a license value looks like a file path.
@@ -35,10 +89,39 @@ export function isFilePath(value) {
35
89
  return /\.[^\d]/.test(value);
36
90
  }
37
91
  /**
38
- * Check if a value is a known SPDX license identifier (case-insensitive).
92
+ * Check if a value is an SPDX identifier VAT can turn into a complete LICENSE
93
+ * file (case-insensitive).
94
+ *
95
+ * `true` here is a promise that {@link generateLicenseText} will produce the
96
+ * full license text, not a summary of it.
39
97
  */
40
98
  export function isSpdxIdentifier(value) {
41
- return KNOWN_SPDX_IDS.has(value.toLowerCase());
99
+ return RENDERABLE_SPDX_IDS.has(value.toLowerCase());
100
+ }
101
+ /**
102
+ * Explain why a license value cannot be turned into a LICENSE file, or return
103
+ * undefined when it can.
104
+ *
105
+ * Shared by every caller so the diagnosis is identical whether the value is
106
+ * rejected during option parsing or during tree composition.
107
+ */
108
+ export function explainUnusableLicense(value) {
109
+ const id = value.toLowerCase();
110
+ if (RENDERABLE_SPDX_IDS.has(id)) {
111
+ return undefined;
112
+ }
113
+ const canonical = UNRENDERABLE_SPDX_IDS.get(id);
114
+ if (canonical !== undefined) {
115
+ return (`VAT cannot generate the full text of the "${value}" license. ` +
116
+ `Emitting a summary or a notice header would produce a legally void LICENSE ` +
117
+ `file — most licenses require that a complete copy be conveyed with the work. ` +
118
+ `Download the official text from https://spdx.org/licenses/${canonical}.html ` +
119
+ `and set \`license\` to its file path instead (e.g. ./LICENSE).`);
120
+ }
121
+ const renderable = [...RENDERABLE_SPDX_IDS.keys()].join(', ');
122
+ return (`"${value}" is neither an SPDX identifier VAT can generate nor a file path. ` +
123
+ `Set \`license\` to a LICENSE file path (e.g. ./LICENSE), ` +
124
+ `or to one of: ${renderable}.`);
42
125
  }
43
126
  /**
44
127
  * Read a license file from disk.
@@ -49,58 +132,25 @@ export function readLicenseFile(filePath, baseDir) {
49
132
  return readFileSync(resolved, 'utf-8');
50
133
  }
51
134
  /**
52
- * Generate standard license text for a known SPDX identifier.
135
+ * Generate the complete license text for a renderable SPDX identifier.
136
+ *
137
+ * @throws when the identifier is not in {@link RENDERABLE_SPDX_IDS} — including
138
+ * for identifiers VAT recognizes but has no vetted text for. Producing a
139
+ * plausible-looking stub is worse than refusing: the caller writes this
140
+ * string straight to disk as LICENSE.
53
141
  */
54
142
  export function generateLicenseText(spdxId, ownerName, year) {
55
- const id = spdxId.toLowerCase();
56
- switch (id) {
57
- case 'mit':
58
- return `MIT License
59
-
60
- Copyright (c) ${year} ${ownerName}
61
-
62
- Permission is hereby granted, free of charge, to any person obtaining a copy
63
- of this software and associated documentation files (the "Software"), to deal
64
- in the Software without restriction, including without limitation the rights
65
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
66
- copies of the Software, and to permit persons to whom the Software is
67
- furnished to do so, subject to the following conditions:
68
-
69
- The above copyright notice and this permission notice shall be included in all
70
- copies or substantial portions of the Software.
71
-
72
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
73
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
74
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
75
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
76
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
77
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
78
- SOFTWARE.
79
- `;
80
- case 'apache-2.0':
81
- return `Copyright ${year} ${ownerName}
82
-
83
- Licensed under the Apache License, Version 2.0 (the "License");
84
- you may not use this file except in compliance with the License.
85
- You may obtain a copy of the License at
86
-
87
- http://www.apache.org/licenses/LICENSE-2.0
88
-
89
- Unless required by applicable law or agreed to in writing, software
90
- distributed under the License is distributed on an "AS IS" BASIS,
91
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
92
- See the License for the specific language governing permissions and
93
- limitations under the License.
94
- `;
95
- default:
96
- if (!KNOWN_SPDX_IDS.has(id)) {
97
- throw new Error(`Unknown SPDX license identifier: "${spdxId}". Use a file path instead.`);
98
- }
99
- return `This software is licensed under the ${spdxId} license.
100
-
101
- Copyright (c) ${year} ${ownerName}
102
- `;
143
+ const problem = explainUnusableLicense(spdxId);
144
+ if (problem !== undefined) {
145
+ throw new Error(problem);
103
146
  }
147
+ const canonical = RENDERABLE_SPDX_IDS.get(spdxId.toLowerCase()) ?? '';
148
+ const render = LICENSE_TEXT_RENDERERS[canonical];
149
+ if (render === undefined) {
150
+ // Unreachable while RENDERABLE_SPDX_IDS is derived from the renderer table.
151
+ throw new Error(`No license text renderer registered for "${spdxId}".`);
152
+ }
153
+ return render(ownerName, year);
104
154
  }
105
155
  /**
106
156
  * Resolve a license config value to LICENSE file content.
@@ -114,10 +164,6 @@ export function resolveLicense(licenseValue, ownerName, baseDir) {
114
164
  if (isFilePath(licenseValue)) {
115
165
  return readLicenseFile(licenseValue, baseDir);
116
166
  }
117
- if (!isSpdxIdentifier(licenseValue)) {
118
- throw new Error(`"${licenseValue}" is neither a known SPDX identifier nor a file path. ` +
119
- `Use a known identifier (mit, apache-2.0, etc.) or a file path (./LICENSE).`);
120
- }
121
167
  return generateLicenseText(licenseValue, ownerName, new Date().getFullYear());
122
168
  }
123
169
  //# sourceMappingURL=license-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"license-utils.js","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/license-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD,4DAA4D;AAC5D,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC7B,KAAK;IACL,YAAY;IACZ,SAAS;IACT,SAAS;IACT,UAAU;IACV,UAAU;IACV,cAAc;IACd,cAAc;IACd,KAAK;IACL,SAAS;IACT,WAAW;CACZ,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,yEAAyE;IACzE,OAAO,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,OAAO,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,OAAe;IAC/D,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACrD,iGAAiG;IACjG,OAAO,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAc,EAAE,SAAiB,EAAE,IAAY;IACjF,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAEhC,QAAQ,EAAE,EAAE,CAAC;QACX,KAAK,KAAK;YACR,OAAO;;gBAEG,IAAI,IAAI,SAAS;;;;;;;;;;;;;;;;;;;CAmBhC,CAAC;QAEE,KAAK,YAAY;YACf,OAAO,aAAa,IAAI,IAAI,SAAS;;;;;;;;;;;;;CAa1C,CAAC;QAEE;YACE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,qCAAqC,MAAM,6BAA6B,CAAC,CAAC;YAC5F,CAAC;YACD,OAAO,uCAAuC,MAAM;;gBAE1C,IAAI,IAAI,SAAS;CAChC,CAAC;IACA,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,YAAoB,EAAE,SAAiB,EAAE,OAAe;IACrF,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,OAAO,eAAe,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CACb,IAAI,YAAY,wDAAwD;YACtE,4EAA4E,CAC/E,CAAC;IACJ,CAAC;IAED,OAAO,mBAAmB,CAAC,YAAY,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AAChF,CAAC"}
1
+ {"version":3,"file":"license-utils.js","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/license-utils.ts"],"names":[],"mappings":"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"}
@@ -14,7 +14,7 @@ import { writeYamlOutput } from '../../../utils/output.js';
14
14
  import { redactUrlCredentials } from '../../../utils/url-redact.js';
15
15
  import { loadClaudeProjectConfig } from '../claude-config.js';
16
16
  import { createCommitMessage, publishToGitBranch } from './git-publish.js';
17
- import { isFilePath, isSpdxIdentifier } from './license-utils.js';
17
+ import { explainUnusableLicense, isFilePath } from './license-utils.js';
18
18
  import { composePublishTree } from './publish-tree.js';
19
19
  export function createMarketplacePublishCommand() {
20
20
  const command = new Command('publish');
@@ -78,10 +78,11 @@ function resolveLicenseOptions(licenseValue, ownerName) {
78
78
  if (isFilePath(licenseValue)) {
79
79
  return { type: 'file', filePath: licenseValue };
80
80
  }
81
- if (isSpdxIdentifier(licenseValue)) {
82
- return { type: 'spdx', value: licenseValue, ownerName };
81
+ const problem = explainUnusableLicense(licenseValue);
82
+ if (problem !== undefined) {
83
+ throw new Error(problem);
83
84
  }
84
- throw new Error(`License "${licenseValue}" is neither a known SPDX identifier nor a file path.`);
85
+ return { type: 'spdx', value: licenseValue, ownerName };
85
86
  }
86
87
  /**
87
88
  * Build ComposeOptions for a single marketplace entry.
@@ -1 +1 @@
1
- {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/publish.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/publish.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/validate.ts"],"names":[],"mappings":"AACA;;;;;;;;;GASG;AAaH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+JpC,wBAAgB,gCAAgC,IAAI,OAAO,CAyB1D"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/validate.ts"],"names":[],"mappings":"AACA;;;;;;;;;GASG;AAaH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyJpC,wBAAgB,gCAAgC,IAAI,OAAO,CAyB1D"}
@@ -10,9 +10,10 @@
10
10
  * - CHANGELOG.md should exist (warning)
11
11
  */
12
12
  import { existsSync, readdirSync } from 'node:fs';
13
+ import { calculateValidationStatus, countBySeverity } from '@vibe-agent-toolkit/agent-schema';
13
14
  import { validateMarketplace, validateSkill, } from '@vibe-agent-toolkit/agent-skills';
14
15
  import { validatePlugin } from '@vibe-agent-toolkit/claude-marketplace';
15
- import { safePath } from '@vibe-agent-toolkit/utils';
16
+ import { issueLocation, safePath } from '@vibe-agent-toolkit/utils';
16
17
  import { Command } from 'commander';
17
18
  import { formatDuration, handleCommandError } from '../../../utils/command-error.js';
18
19
  import { createLogger } from '../../../utils/logger.js';
@@ -33,7 +34,7 @@ function checkMarketplaceFiles(marketplacePath) {
33
34
  severity: check.severity,
34
35
  code: check.code,
35
36
  message: `Marketplace is missing a ${check.file} — ${check.verb}`,
36
- location: safePath.join(marketplacePath, check.file),
37
+ location: issueLocation(safePath.join(marketplacePath, check.file), marketplacePath),
37
38
  fix: `Add a ${check.file} to the marketplace root directory`,
38
39
  });
39
40
  }
@@ -43,7 +44,7 @@ function checkMarketplaceFiles(marketplacePath) {
43
44
  /**
44
45
  * Validate all SKILL.md files within a plugin's skills/ directory.
45
46
  */
46
- async function validatePluginSkills(pluginDir) {
47
+ async function validatePluginSkills(pluginDir, marketplacePath) {
47
48
  const skillsDir = safePath.join(pluginDir, 'skills');
48
49
  if (!existsSync(skillsDir))
49
50
  return [];
@@ -56,7 +57,7 @@ async function validatePluginSkills(pluginDir) {
56
57
  const skillMdPath = safePath.join(skillDir, 'SKILL.md');
57
58
  if (!existsSync(skillMdPath))
58
59
  continue;
59
- const skillResult = await validateSkill({ skillPath: skillMdPath, rootDir: skillDir });
60
+ const skillResult = await validateSkill({ skillPath: skillMdPath, rootDir: skillDir, locationRoot: marketplacePath });
60
61
  issues.push(...skillResult.issues);
61
62
  }
62
63
  return issues;
@@ -78,21 +79,11 @@ async function validatePlugins(marketplacePath) {
78
79
  const pluginResult = await validatePlugin(pluginDir, { strict: true });
79
80
  pluginResults.push(pluginResult);
80
81
  issues.push(...pluginResult.issues);
81
- const skillIssues = await validatePluginSkills(pluginDir);
82
+ const skillIssues = await validatePluginSkills(pluginDir, marketplacePath);
82
83
  issues.push(...skillIssues);
83
84
  }
84
85
  return { pluginResults, issues };
85
86
  }
86
- /**
87
- * Determine overall validation status from issues.
88
- */
89
- function determineStatus(issues) {
90
- if (issues.some(i => i.severity === 'error'))
91
- return 'error';
92
- if (issues.some(i => i.severity === 'warning'))
93
- return 'warning';
94
- return 'success';
95
- }
96
87
  async function marketplaceValidateCommand(targetPath, options) {
97
88
  const logger = createLogger(options.debug ? { debug: true } : {});
98
89
  const startTime = Date.now();
@@ -119,9 +110,8 @@ async function marketplaceValidateCommand(targetPath, options) {
119
110
  const { pluginResults, issues: pluginIssues } = await validatePlugins(marketplacePath);
120
111
  // Combine all issues
121
112
  const allIssues = [...marketplaceResult.issues, ...fileIssues, ...pluginIssues];
122
- const status = determineStatus(allIssues);
123
- const errorCount = allIssues.filter(i => i.severity === 'error').length;
124
- const warningCount = allIssues.filter(i => i.severity === 'warning').length;
113
+ const status = calculateValidationStatus(allIssues);
114
+ const issueCounts = countBySeverity(allIssues);
125
115
  const duration = formatDuration(Date.now() - startTime);
126
116
  writeYamlOutput({
127
117
  status,
@@ -134,7 +124,11 @@ async function marketplaceValidateCommand(targetPath, options) {
134
124
  issues: r.issues,
135
125
  })),
136
126
  issues: allIssues,
137
- summary: `${errorCount} error(s), ${warningCount} warning(s)`,
127
+ // Counts ride beside the status: `status` names only the worst ACTIONABLE
128
+ // severity, so an info-only run is `success` and the info would otherwise
129
+ // be unreported.
130
+ issueCounts,
131
+ summary: `${issueCounts.errors} error(s), ${issueCounts.warnings} warning(s), ${issueCounts.info} info`,
138
132
  duration,
139
133
  });
140
134
  process.exit(status === 'error' ? 1 : 0);
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/validate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/validate.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,24 @@
1
1
  import { Command } from 'commander';
2
+ interface CollectedUploadFiles {
3
+ files: Array<{
4
+ relativePath: string;
5
+ absolutePath: string;
6
+ }>;
7
+ /**
8
+ * Relative paths of everything deliberately withheld — a directory, or the
9
+ * single file of a suite declared at the skill root — so the skip is never
10
+ * silent. Under-reporting here is worse than the leak itself: it would
11
+ * affirmatively tell the operator nothing was held back.
12
+ */
13
+ excluded: string[];
14
+ }
15
+ /**
16
+ * Collect the upload payload for a skill directory. Exported for testing.
17
+ *
18
+ * Resolves the declared test-input paths itself rather than accepting them, so
19
+ * no caller can obtain an upload set with the exclusion skipped.
20
+ */
21
+ export declare function collectSkillUploadFiles(skillDir: string): Promise<CollectedUploadFiles>;
2
22
  export declare function createOrgSkillsCommand(): Command;
23
+ export {};
3
24
  //# sourceMappingURL=skills.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/org/skills.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoRpC,wBAAgB,sBAAsB,IAAI,OAAO,CA6JhD"}
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/org/skills.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwFpC,UAAU,oBAAoB;IAC7B,KAAK,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AA8DD;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAI7F;AAsMD,wBAAgB,sBAAsB,IAAI,OAAO,CAoKhD"}
@@ -3,9 +3,11 @@
3
3
  */
4
4
  import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync } from 'node:fs';
5
5
  import { basename } from 'node:path';
6
+ import { evalSuiteUnitPath, readDeclaredSkillName } from '@vibe-agent-toolkit/agent-skills';
6
7
  import { buildMultipartFormData } from '@vibe-agent-toolkit/claude-marketplace';
7
8
  import { normalizedTmpdir, safePath } from '@vibe-agent-toolkit/utils';
8
9
  import { Command } from 'commander';
10
+ import { resolveSkillPackagingConfig } from '../../../skill-resolution/packaging-config.js';
9
11
  import { downloadNpmPackage } from '../plugin/helpers.js';
10
12
  import { autopaginateSkills, executeOrgCommand } from './helpers.js';
11
13
  const SKILL_ID_ARG = '<skill-id>';
@@ -25,44 +27,106 @@ async function sendSkillUpload(client, displayTitle, files) {
25
27
  };
26
28
  }
27
29
  /**
28
- * Extract display_title from SKILL.md frontmatter.
29
- * Parses the `name` field from YAML frontmatter between --- delimiters.
30
+ * The name a SKILL.md declares, which is both the uploaded skill's display
31
+ * title and the top-level directory the API keys it by.
30
32
  */
31
- function extractDisplayTitle(skillMdPath) {
32
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- path from CLI arg, validated before call
33
- const content = readFileSync(skillMdPath, 'utf-8');
34
- // eslint-disable-next-line sonarjs/slow-regex -- bounded by small frontmatter block, not user-controlled input
35
- const match = /^---\s*\n([\s\S]*?)\n---/.exec(content);
36
- if (!match?.[1]) {
37
- throw new Error(`SKILL.md has no frontmatter: ${skillMdPath}`);
33
+ function requireDeclaredName(skillMdPath) {
34
+ const declared = readDeclaredSkillName(skillMdPath);
35
+ if (declared === undefined) {
36
+ throw new Error(`SKILL.md has no usable frontmatter "name" field: ${skillMdPath}`);
38
37
  }
39
- // eslint-disable-next-line sonarjs/slow-regex -- single-line match on small YAML block
40
- const nameMatch = /^name:\s*(.+)$/m.exec(match[1]);
41
- if (!nameMatch?.[1]) {
42
- throw new Error(`SKILL.md frontmatter missing "name" field: ${skillMdPath}`);
43
- }
44
- return nameMatch[1].trim();
38
+ return declared;
45
39
  }
46
40
  /**
47
- * Collect all files in a directory recursively, returning relative paths.
41
+ * Directories never uploaded to the organization, at any depth, by NAME.
42
+ *
43
+ * `evals/` is the conventional home of a skill's eval suite — its answer key.
44
+ * A correctly built skill directory (what this command documents as its input)
45
+ * never contains one, because the packager excludes declared test input; this
46
+ * is the backstop for the easy mistake of pointing the uploader at the *source*
47
+ * tree instead, where the suite does live. The invariant is "a published skill
48
+ * carries no answer key", not "…none when the operator remembered to build".
49
+ *
50
+ * The name match alone cannot uphold that invariant, because the suite's
51
+ * location is the ADOPTER's to declare (`skills.config.<name>.test.evals`;
52
+ * `evals/evals.json` is only the default). It stays as the unconditional
53
+ * fail-safe for the case where no config is discoverable at all — a fetched
54
+ * artifact, an extracted tarball, a tree outside any VAT project — where there
55
+ * is no declaration to read and the convention is the only thing left to honor.
56
+ * The declared location is resolved separately, in
57
+ * {@link declaredTestInputPaths}, and the two are unioned.
58
+ *
59
+ * This lane is deliberately BROADER than the packager, which excludes exactly
60
+ * `<skill-root>/evals` and never guesses from a name (see test-input.ts). Here
61
+ * a mistaken input is the entire scenario and the blast radius is an org-wide
62
+ * publish, so over-withholding a directory literally named `evals` is the cheap
63
+ * error and it is reported rather than silent.
64
+ *
65
+ * `node_modules`/`.git` are development detritus that has no meaning inside a
66
+ * published skill and would silently bloat the multipart payload.
48
67
  */
49
- function collectFiles(dir, baseDir) {
50
- const base = baseDir ?? dir;
51
- const results = [];
68
+ const NEVER_UPLOADED_DIR_NAMES = new Set(['evals', 'node_modules', '.git']);
69
+ /**
70
+ * The absolute path of this skill's DECLARED eval suite, when its governing VAT
71
+ * config declares one, as a set of paths to withhold.
72
+ *
73
+ * Resolution is anchored on the DIRECTORY ARGUMENT, not on a governing config
74
+ * being present: `resolveSkillPackagingConfig` walks up from the given skill dir
75
+ * to its nearest-ancestor `vibe-agent-toolkit.config.yaml` — the same walk-up
76
+ * `vat audit`, `vat skill review`, and skill-reference resolution use — and
77
+ * returns `null` when there is none or the skill is not declared there. That is
78
+ * exactly what this backstop needs: the scenario it exists for is an operator
79
+ * pointing at a source tree by mistake, and a source tree sits inside its own
80
+ * project, so the declaration is right there to be read. Requiring a governing
81
+ * config instead would refuse to protect the fetched-artifact case at all, and
82
+ * `null` here is not a failure — it falls through to the name-based fail-safe.
83
+ *
84
+ * `evalSuiteUnitPath` is the shared definition of the suite UNIT (the directory
85
+ * holding `evals.json` and its `fixtures/`, or the single file for a suite at
86
+ * the skill root) and yields `undefined` for a suite that lives outside the
87
+ * skill dir — nothing inside the tree to withhold.
88
+ */
89
+ async function declaredTestInputPaths(skillDir) {
90
+ const config = await resolveSkillPackagingConfig(safePath.join(skillDir, 'SKILL.md'));
91
+ const declared = config?.test?.evals;
92
+ if (declared === undefined)
93
+ return new Set();
94
+ const unit = evalSuiteUnitPath(safePath.resolve(skillDir), declared);
95
+ return unit === undefined ? new Set() : new Set([unit]);
96
+ }
97
+ /**
98
+ * Collect the files under a skill directory that should be uploaded,
99
+ * recursively, returning relative paths alongside what was deliberately left
100
+ * out.
101
+ */
102
+ function collectFiles(dir, base, testInput, collected) {
52
103
  // eslint-disable-next-line security/detect-non-literal-fs-filename -- dir from CLI arg
53
104
  for (const entry of readdirSync(dir, { withFileTypes: true })) {
54
105
  const fullPath = safePath.join(dir, entry.name);
106
+ const relativePath = safePath.relative(base, fullPath);
107
+ if (testInput.has(safePath.resolve(fullPath))
108
+ || (entry.isDirectory() && NEVER_UPLOADED_DIR_NAMES.has(entry.name))) {
109
+ collected.excluded.push(relativePath);
110
+ continue;
111
+ }
55
112
  if (entry.isDirectory()) {
56
- results.push(...collectFiles(fullPath, base));
113
+ collectFiles(fullPath, base, testInput, collected);
57
114
  }
58
115
  else {
59
- results.push({
60
- relativePath: safePath.relative(base, fullPath),
61
- absolutePath: fullPath,
62
- });
116
+ collected.files.push({ relativePath, absolutePath: fullPath });
63
117
  }
64
118
  }
65
- return results;
119
+ }
120
+ /**
121
+ * Collect the upload payload for a skill directory. Exported for testing.
122
+ *
123
+ * Resolves the declared test-input paths itself rather than accepting them, so
124
+ * no caller can obtain an upload set with the exclusion skipped.
125
+ */
126
+ export async function collectSkillUploadFiles(skillDir) {
127
+ const collected = { files: [], excluded: [] };
128
+ collectFiles(skillDir, skillDir, await declaredTestInputPaths(skillDir), collected);
129
+ return collected;
66
130
  }
67
131
  /**
68
132
  * Upload a single skill directory to the org via Skills API.
@@ -73,12 +137,15 @@ async function uploadSkillDir(client, skillDir, titleOverride, logger) {
73
137
  if (!existsSync(skillMdPath)) {
74
138
  throw new Error(`SKILL.md not found in ${skillDir}. Is this a built skill directory?`);
75
139
  }
76
- const displayTitle = titleOverride ?? extractDisplayTitle(skillMdPath);
140
+ // The skill's own declared name — not the directory it happens to sit in,
141
+ // which for a built or extracted tree carries no reliable identity.
142
+ const declaredName = requireDeclaredName(skillMdPath);
143
+ const displayTitle = titleOverride ?? declaredName;
77
144
  // API requires files inside a top-level directory (e.g. skill_name/SKILL.md)
78
- const dirName = basename(skillDir);
79
- const allFiles = collectFiles(skillDir);
145
+ const dirName = declaredName;
146
+ const collected = await collectSkillUploadFiles(skillDir);
80
147
  const files = [];
81
- for (const file of allFiles) {
148
+ for (const file of collected.files) {
82
149
  // eslint-disable-next-line security/detect-non-literal-fs-filename -- collected from dir walk
83
150
  const content = readFileSync(file.absolutePath);
84
151
  files.push({
@@ -89,6 +156,9 @@ async function uploadSkillDir(client, skillDir, titleOverride, logger) {
89
156
  }
90
157
  const totalSize = files.reduce((sum, f) => sum + f.content.length, 0);
91
158
  logger.info(` ${dirName}: ${files.length} files, ${(totalSize / 1024).toFixed(1)}KB, title="${displayTitle}"`);
159
+ for (const excluded of collected.excluded) {
160
+ logger.info(` Excluded from upload: ${excluded} (never published with a skill)`);
161
+ }
92
162
  return sendSkillUpload(client, displayTitle, files);
93
163
  }
94
164
  /**
@@ -272,7 +342,14 @@ Description:
272
342
  Accepts a built skill directory, a ZIP file, or an npm package.
273
343
  Requires ANTHROPIC_API_KEY (regular key, not admin key).
274
344
 
275
- The display_title defaults to the "name" field from SKILL.md frontmatter.
345
+ The skill uploads under the "name" its SKILL.md frontmatter declares, which
346
+ is also the default display_title.
347
+
348
+ A skill's eval suite is its answer key and is never uploaded: whatever the
349
+ governing vibe-agent-toolkit.config.yaml declares as this skill's test input
350
+ (skills.config.<name>.test.evals) is withheld, and so is any evals/ directory
351
+ when no config is discoverable. node_modules/ and .git/ are never uploaded
352
+ either. Each exclusion is reported in the output.
276
353
 
277
354
  Examples:
278
355
  $ vat claude org skills install dist/skills/org-admin