@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.
- package/README.md +4 -3
- package/dist/bin/vat +1 -1
- package/dist/bin/vat.js +1 -1
- package/dist/bin/vat.js.map +1 -1
- package/dist/bin.js +2 -4
- package/dist/bin.js.map +1 -1
- package/dist/commands/agent/help.d.ts.map +1 -1
- package/dist/commands/agent/help.js +2 -4
- package/dist/commands/agent/help.js.map +1 -1
- package/dist/commands/audit/hierarchical-output.d.ts +6 -2
- package/dist/commands/audit/hierarchical-output.d.ts.map +1 -1
- package/dist/commands/audit/hierarchical-output.js +93 -50
- package/dist/commands/audit/hierarchical-output.js.map +1 -1
- package/dist/commands/audit-settings.d.ts +35 -0
- package/dist/commands/audit-settings.d.ts.map +1 -1
- package/dist/commands/audit-settings.js +121 -51
- package/dist/commands/audit-settings.js.map +1 -1
- package/dist/commands/audit.d.ts +63 -1
- package/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +329 -187
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +47 -18
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/claude/marketplace/license-utils.d.ts +39 -2
- package/dist/commands/claude/marketplace/license-utils.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/license-utils.js +114 -68
- package/dist/commands/claude/marketplace/license-utils.js.map +1 -1
- package/dist/commands/claude/marketplace/publish.js +5 -4
- package/dist/commands/claude/marketplace/publish.js.map +1 -1
- package/dist/commands/claude/marketplace/validate.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/validate.js +13 -19
- package/dist/commands/claude/marketplace/validate.js.map +1 -1
- package/dist/commands/claude/org/skills.d.ts +21 -0
- package/dist/commands/claude/org/skills.d.ts.map +1 -1
- package/dist/commands/claude/org/skills.js +107 -30
- package/dist/commands/claude/org/skills.js.map +1 -1
- package/dist/commands/claude/plugin/build.d.ts +94 -1
- package/dist/commands/claude/plugin/build.d.ts.map +1 -1
- package/dist/commands/claude/plugin/build.js +307 -106
- package/dist/commands/claude/plugin/build.js.map +1 -1
- package/dist/commands/claude/plugin/install.d.ts.map +1 -1
- package/dist/commands/claude/plugin/install.js +7 -2
- package/dist/commands/claude/plugin/install.js.map +1 -1
- package/dist/commands/claude/plugin/marketplace-json.d.ts +36 -0
- package/dist/commands/claude/plugin/marketplace-json.d.ts.map +1 -0
- package/dist/commands/claude/plugin/marketplace-json.js +34 -0
- package/dist/commands/claude/plugin/marketplace-json.js.map +1 -0
- package/dist/commands/claude/plugin/plugin-json-merge.d.ts +30 -1
- package/dist/commands/claude/plugin/plugin-json-merge.d.ts.map +1 -1
- package/dist/commands/claude/plugin/plugin-json-merge.js +92 -14
- package/dist/commands/claude/plugin/plugin-json-merge.js.map +1 -1
- package/dist/commands/claude/plugin/tree-copy.d.ts +10 -3
- package/dist/commands/claude/plugin/tree-copy.d.ts.map +1 -1
- package/dist/commands/claude/plugin/tree-copy.js +0 -1
- package/dist/commands/claude/plugin/tree-copy.js.map +1 -1
- package/dist/commands/claude/plugin/uninstall.d.ts.map +1 -1
- package/dist/commands/claude/plugin/uninstall.js +10 -2
- package/dist/commands/claude/plugin/uninstall.js.map +1 -1
- package/dist/commands/corpus/runner.d.ts.map +1 -1
- package/dist/commands/corpus/runner.js +15 -26
- package/dist/commands/corpus/runner.js.map +1 -1
- package/dist/commands/doctor.d.ts +57 -8
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +142 -67
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/phase-utils.d.ts +62 -2
- package/dist/commands/phase-utils.d.ts.map +1 -1
- package/dist/commands/phase-utils.js +74 -2
- package/dist/commands/phase-utils.js.map +1 -1
- package/dist/commands/rag/help.d.ts.map +1 -1
- package/dist/commands/rag/help.js +2 -4
- package/dist/commands/rag/help.js.map +1 -1
- package/dist/commands/resources/help.d.ts.map +1 -1
- package/dist/commands/resources/help.js +2 -4
- package/dist/commands/resources/help.js.map +1 -1
- package/dist/commands/resources/index.d.ts.map +1 -1
- package/dist/commands/resources/index.js +13 -6
- package/dist/commands/resources/index.js.map +1 -1
- package/dist/commands/resources/validate.d.ts +19 -0
- package/dist/commands/resources/validate.d.ts.map +1 -1
- package/dist/commands/resources/validate.js +89 -24
- package/dist/commands/resources/validate.js.map +1 -1
- package/dist/commands/skill/review.d.ts.map +1 -1
- package/dist/commands/skill/review.js +33 -20
- package/dist/commands/skill/review.js.map +1 -1
- package/dist/commands/skill/test/configure.d.ts.map +1 -1
- package/dist/commands/skill/test/configure.js +1 -1
- package/dist/commands/skill/test/configure.js.map +1 -1
- package/dist/commands/skill/test/run.d.ts +29 -2
- package/dist/commands/skill/test/run.d.ts.map +1 -1
- package/dist/commands/skill/test/run.js +67 -19
- package/dist/commands/skill/test/run.js.map +1 -1
- package/dist/commands/skills/build.d.ts +51 -0
- package/dist/commands/skills/build.d.ts.map +1 -1
- package/dist/commands/skills/build.js +94 -86
- package/dist/commands/skills/build.js.map +1 -1
- package/dist/commands/skills/install.d.ts.map +1 -1
- package/dist/commands/skills/install.js +79 -25
- package/dist/commands/skills/install.js.map +1 -1
- package/dist/commands/skills/list.d.ts.map +1 -1
- package/dist/commands/skills/list.js +9 -5
- package/dist/commands/skills/list.js.map +1 -1
- package/dist/commands/skills/package.d.ts +2 -0
- package/dist/commands/skills/package.d.ts.map +1 -1
- package/dist/commands/skills/package.js +61 -42
- package/dist/commands/skills/package.js.map +1 -1
- package/dist/commands/skills/skill-discovery.d.ts +7 -0
- package/dist/commands/skills/skill-discovery.d.ts.map +1 -1
- package/dist/commands/skills/skill-discovery.js +14 -4
- package/dist/commands/skills/skill-discovery.js.map +1 -1
- package/dist/commands/skills/validate.d.ts +38 -0
- package/dist/commands/skills/validate.d.ts.map +1 -1
- package/dist/commands/skills/validate.js +125 -70
- package/dist/commands/skills/validate.js.map +1 -1
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +11 -5
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +76 -28
- package/dist/commands/verify.js.map +1 -1
- package/dist/skill-resolution/classify.d.ts +7 -2
- package/dist/skill-resolution/classify.d.ts.map +1 -1
- package/dist/skill-resolution/classify.js +7 -2
- package/dist/skill-resolution/classify.js.map +1 -1
- package/dist/skill-resolution/resolve-skill-reference.d.ts +10 -8
- package/dist/skill-resolution/resolve-skill-reference.d.ts.map +1 -1
- package/dist/skill-resolution/resolve-skill-reference.js +62 -23
- package/dist/skill-resolution/resolve-skill-reference.js.map +1 -1
- package/dist/skill-resolution/types.d.ts +3 -2
- package/dist/skill-resolution/types.d.ts.map +1 -1
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-loader.js +0 -2
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/help-loader.d.ts +16 -0
- package/dist/utils/help-loader.d.ts.map +1 -1
- package/dist/utils/help-loader.js +31 -1
- package/dist/utils/help-loader.js.map +1 -1
- package/dist/utils/issue-anchor.d.ts +26 -0
- package/dist/utils/issue-anchor.d.ts.map +1 -0
- package/dist/utils/issue-anchor.js +39 -0
- package/dist/utils/issue-anchor.js.map +1 -0
- package/dist/utils/issue-rendering.d.ts +61 -0
- package/dist/utils/issue-rendering.d.ts.map +1 -0
- package/dist/utils/issue-rendering.js +135 -0
- package/dist/utils/issue-rendering.js.map +1 -0
- package/dist/utils/output.d.ts +26 -4
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +27 -6
- package/dist/utils/output.js.map +1 -1
- package/dist/utils/project-root-policy.d.ts +2 -2
- package/dist/utils/project-root-policy.js +2 -2
- package/dist/utils/skill-packaging-config.d.ts +15 -6
- package/dist/utils/skill-packaging-config.d.ts.map +1 -1
- package/dist/utils/skill-packaging-config.js +23 -5
- package/dist/utils/skill-packaging-config.js.map +1 -1
- package/dist/utils/validate-help-files.d.ts +3 -2
- package/dist/utils/validate-help-files.d.ts.map +1 -1
- package/dist/utils/validate-help-files.js +48 -5
- package/dist/utils/validate-help-files.js.map +1 -1
- package/dist/utils/verdict-helpers.d.ts +10 -2
- package/dist/utils/verdict-helpers.d.ts.map +1 -1
- package/dist/utils/verdict-helpers.js +13 -3
- package/dist/utils/verdict-helpers.js.map +1 -1
- package/docs/audit.md +40 -14
- package/docs/doctor.md +46 -10
- package/docs/index.md +1 -1
- package/docs/resources.md +24 -8
- package/docs/skill-test.md +47 -3
- package/docs/skills.md +28 -6
- 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
|
-
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
56
|
-
|
|
57
|
-
|
|
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
|
|
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 {
|
|
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
|
-
|
|
82
|
-
|
|
81
|
+
const problem = explainUnusableLicense(licenseValue);
|
|
82
|
+
if (problem !== undefined) {
|
|
83
|
+
throw new Error(problem);
|
|
83
84
|
}
|
|
84
|
-
|
|
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":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAItC,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,YAAY,EAAe,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/publish.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAItC,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,YAAY,EAAe,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAA4C,MAAM,mBAAmB,CAAC;AAyBjG,MAAM,UAAU,+BAA+B;IAC7C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvC,OAAO;SACJ,WAAW,CAAC,2CAA2C,CAAC;SACxD,MAAM,CAAC,WAAW,EAAE,8CAA8C,CAAC;SACnE,MAAM,CAAC,WAAW,EAAE,iDAAiD,CAAC;SACtE,MAAM,CAAC,iBAAiB,EAAE,yBAAyB,CAAC;SACpD,MAAM,CAAC,SAAS,EAAE,wCAAwC,CAAC;SAC3D,MAAM,CAAC,sBAAsB,EAAE,mCAAmC,CAAC;SACnE,MAAM,CAAC,SAAS,EAAE,sBAAsB,CAAC;SACzC,MAAM,CAAC,yBAAyB,CAAC;SACjC,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCzB,CAAC,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAC5B,YAAoB,EACpB,SAAiB;IAEjB,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;IAClD,CAAC;IACD,MAAM,OAAO,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAC;IACrD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AAC1D,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAC1B,MAAc,EACd,SAAiB,EACjB,aAA8D,EAC9D,WAAuC;IAEvC,MAAM,IAAI,GAAmB;QAC3B,eAAe,EAAE,MAAM;QACvB,SAAS;QACT,SAAS,EAAE,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,oBAAoB,MAAM,GAAG,CAAC,CAAC;KACzF,CAAC;IACF,IAAI,aAAa,CAAC,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,SAAS,GAAG,EAAE,UAAU,EAAE,aAAa,CAAC,SAAS,EAAE,CAAC;IAC3D,CAAC;IACD,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,EAAE,UAAU,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC;IACrD,CAAC;IACD,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC;IAC7B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAWD;;GAEG;AACH,KAAK,UAAU,qBAAqB,CAAC,GAAsB;IACzD,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAC5E,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC,MAAM,IAAI,oBAAoB,CAAC;IAC9E,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,IAAI,QAAQ,CAAC;IAEhD,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO;QACvC,CAAC,CAAC,qBAAqB,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;QACnE,CAAC,CAAC,SAAS,CAAC;IAEd,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;IACvF,MAAM,aAAa,GAAG,MAAM,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAE5D,MAAM,YAAY,GAAG,aAAa,CAAC,OAAO,CAAC;IAC3C,MAAM,MAAM,GAAG,YAAY;QACzB,CAAC,CAAC,2BAA2B,MAAM,MAAM,YAAY,EAAE;QACvD,CAAC,CAAC,2BAA2B,MAAM,GAAG,CAAC;IACzC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEpB,0CAA0C;IAC1C,MAAM,UAAU,GAAG,OAAO,aAAa,CAAC,UAAU,KAAK,QAAQ;QAC7D,CAAC,CAAC,aAAa,CAAC,UAAU;QAC1B,CAAC,CAAC,SAAS,CAAC;IAEd,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,YAAY,EAAE,CAAC,CAAC,CAAC,WAAW,MAAM,EAAE,CAAC;IACjF,MAAM,aAAa,GAAG,mBAAmB,CACvC,QAAQ,EACR,aAAa,CAAC,cAAc,EAC5B,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CACxC,CAAC;IAEF,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,CAAC,IAAI,CAAC,8BAA8B,oBAAoB,CAAC,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC;QACpF,MAAM,CAAC,IAAI,CAAC,sBAAsB,YAAY,IAAI,uCAAuC,EAAE,CAAC,CAAC;QAC7F,MAAM,CAAC,IAAI,CAAC,oBAAoB,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpE,CAAC;SAAM,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,mCAAmC,MAAM,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,kBAAkB,CAAC;QACvB,UAAU,EAAE,WAAW,CAAC,SAAS;QACjC,MAAM;QACN,MAAM;QACN,aAAa;QACb,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK;QAC7B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;QAC/B,MAAM,EAAE,OAAO,CAAC,IAAI,KAAK,KAAK;QAC9B,MAAM;KACP,CAAC,CAAC;IAEH,OAAO;QACL,WAAW,EAAE,MAAM;QACnB,OAAO,EAAE,YAAY;QACrB,MAAM;QACN,KAAK,EAAE,aAAa,CAAC,KAAK;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;KAChC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,yBAAyB,CAAC,QAAmC,EAAE,OAAgB;IAC5F,wEAAwE;IACxE,MAAM,OAAO,GAAG,OAAO,CAAC,eAAe,EAA+B,CAAC;IACvE,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,uBAAuB,EAAE,CAAC;QAEpE,IAAI,CAAC,YAAY,EAAE,YAAY,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,yGAAyG,CAC1G,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAoB,EAAE,CAAC;QAEpC,KAAK,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC;YAC3E,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,KAAK,MAAM,EAAE,CAAC;gBAC1D,SAAS;YACX,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC,aAAa,MAAM,uBAAuB,CAAC,CAAC;gBACxD,SAAS;YACX,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC;gBACzC,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM;aAC9E,CAAC,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACb,OAAO,CAAC,WAAW;gBACjB,CAAC,CAAC,gBAAgB,OAAO,CAAC,WAAW,uCAAuC;gBAC5E,CAAC,CAAC,4CAA4C,CACjD,CAAC;QACJ,CAAC;QAED,eAAe,CAAC;YACd,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,OAAO;SACnB,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;IACrE,CAAC;AACH,CAAC"}
|
|
@@ -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;
|
|
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 =
|
|
123
|
-
const
|
|
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
|
-
|
|
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":"AAAA,qGAAqG;AACrG;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
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":"
|
|
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
|
-
*
|
|
29
|
-
*
|
|
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
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
113
|
+
collectFiles(fullPath, base, testInput, collected);
|
|
57
114
|
}
|
|
58
115
|
else {
|
|
59
|
-
|
|
60
|
-
relativePath: safePath.relative(base, fullPath),
|
|
61
|
-
absolutePath: fullPath,
|
|
62
|
-
});
|
|
116
|
+
collected.files.push({ relativePath, absolutePath: fullPath });
|
|
63
117
|
}
|
|
64
118
|
}
|
|
65
|
-
|
|
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
|
-
|
|
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 =
|
|
79
|
-
const
|
|
145
|
+
const dirName = declaredName;
|
|
146
|
+
const collected = await collectSkillUploadFiles(skillDir);
|
|
80
147
|
const files = [];
|
|
81
|
-
for (const file of
|
|
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
|
|
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
|