@vibe-agent-toolkit/cli 0.1.9 → 0.1.12

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 (71) hide show
  1. package/dist/bin/vat +174 -0
  2. package/dist/bin.js +2 -0
  3. package/dist/bin.js.map +1 -1
  4. package/dist/commands/audit/hierarchical-output.d.ts.map +1 -1
  5. package/dist/commands/audit/hierarchical-output.js +74 -13
  6. package/dist/commands/audit/hierarchical-output.js.map +1 -1
  7. package/dist/commands/audit.d.ts.map +1 -1
  8. package/dist/commands/audit.js +57 -33
  9. package/dist/commands/audit.js.map +1 -1
  10. package/dist/commands/resources/index.d.ts.map +1 -1
  11. package/dist/commands/resources/index.js +19 -4
  12. package/dist/commands/resources/index.js.map +1 -1
  13. package/dist/commands/resources/validate.d.ts +2 -0
  14. package/dist/commands/resources/validate.d.ts.map +1 -1
  15. package/dist/commands/resources/validate.js +6 -3
  16. package/dist/commands/resources/validate.js.map +1 -1
  17. package/dist/commands/skills/build.d.ts +13 -0
  18. package/dist/commands/skills/build.d.ts.map +1 -0
  19. package/dist/commands/skills/build.js +253 -0
  20. package/dist/commands/skills/build.js.map +1 -0
  21. package/dist/commands/skills/command-helpers.d.ts +46 -0
  22. package/dist/commands/skills/command-helpers.d.ts.map +1 -0
  23. package/dist/commands/skills/command-helpers.js +70 -0
  24. package/dist/commands/skills/command-helpers.js.map +1 -0
  25. package/dist/commands/skills/index.d.ts +8 -0
  26. package/dist/commands/skills/index.d.ts.map +1 -0
  27. package/dist/commands/skills/index.js +96 -0
  28. package/dist/commands/skills/index.js.map +1 -0
  29. package/dist/commands/skills/install-helpers.d.ts +45 -0
  30. package/dist/commands/skills/install-helpers.d.ts.map +1 -0
  31. package/dist/commands/skills/install-helpers.js +125 -0
  32. package/dist/commands/skills/install-helpers.js.map +1 -0
  33. package/dist/commands/skills/install.d.ts +20 -0
  34. package/dist/commands/skills/install.d.ts.map +1 -0
  35. package/dist/commands/skills/install.js +287 -0
  36. package/dist/commands/skills/install.js.map +1 -0
  37. package/dist/commands/skills/list.d.ts +12 -0
  38. package/dist/commands/skills/list.d.ts.map +1 -0
  39. package/dist/commands/skills/list.js +124 -0
  40. package/dist/commands/skills/list.js.map +1 -0
  41. package/dist/commands/skills/package.d.ts +16 -0
  42. package/dist/commands/skills/package.d.ts.map +1 -0
  43. package/dist/commands/skills/package.js +293 -0
  44. package/dist/commands/skills/package.js.map +1 -0
  45. package/dist/commands/skills/shared.d.ts +23 -0
  46. package/dist/commands/skills/shared.d.ts.map +1 -0
  47. package/dist/commands/skills/shared.js +33 -0
  48. package/dist/commands/skills/shared.js.map +1 -0
  49. package/dist/commands/skills/validate-command.d.ts +6 -0
  50. package/dist/commands/skills/validate-command.d.ts.map +1 -0
  51. package/dist/commands/skills/validate-command.js +89 -0
  52. package/dist/commands/skills/validate-command.js.map +1 -0
  53. package/dist/commands/skills/validate.d.ts +19 -0
  54. package/dist/commands/skills/validate.d.ts.map +1 -0
  55. package/dist/commands/skills/validate.js +180 -0
  56. package/dist/commands/skills/validate.js.map +1 -0
  57. package/dist/utils/claude-paths.d.ts +32 -0
  58. package/dist/utils/claude-paths.d.ts.map +1 -0
  59. package/dist/utils/claude-paths.js +34 -0
  60. package/dist/utils/claude-paths.js.map +1 -0
  61. package/dist/utils/skill-discovery.d.ts +49 -0
  62. package/dist/utils/skill-discovery.d.ts.map +1 -0
  63. package/dist/utils/skill-discovery.js +73 -0
  64. package/dist/utils/skill-discovery.js.map +1 -0
  65. package/dist/utils/user-context-scanner.d.ts +31 -0
  66. package/dist/utils/user-context-scanner.d.ts.map +1 -0
  67. package/dist/utils/user-context-scanner.js +60 -0
  68. package/dist/utils/user-context-scanner.js.map +1 -0
  69. package/docs/audit.md +1 -0
  70. package/docs/skills.md +561 -0
  71. package/package.json +18 -12
@@ -0,0 +1,124 @@
1
+ /**
2
+ * List skills in project or user installation
3
+ *
4
+ * By default, lists project skills. Use --user flag to list user-installed skills.
5
+ */
6
+ import * as path from 'node:path';
7
+ import { scan } from '@vibe-agent-toolkit/discovery';
8
+ import { loadConfig } from '../../utils/config-loader.js';
9
+ import { createLogger } from '../../utils/logger.js';
10
+ import { discoverSkills, validateSkillFilename } from '../../utils/skill-discovery.js';
11
+ import { scanUserContext } from '../../utils/user-context-scanner.js';
12
+ /**
13
+ * Extract skill name from SKILL.md path
14
+ */
15
+ function extractSkillName(skillPath) {
16
+ // Extract skill name from path (directory name containing SKILL.md)
17
+ const dir = path.dirname(skillPath);
18
+ return path.basename(dir);
19
+ }
20
+ /**
21
+ * Convert discovered skills to DiscoveredSkill format with validation
22
+ */
23
+ function processDiscoveredSkills(discoveredSkills) {
24
+ return discoveredSkills.map(s => {
25
+ const filenameCheck = validateSkillFilename(s.path);
26
+ const skill = {
27
+ path: s.path,
28
+ name: extractSkillName(s.path),
29
+ valid: filenameCheck.valid,
30
+ };
31
+ // Only add warning if it exists (exactOptionalPropertyTypes)
32
+ if (filenameCheck.message !== undefined) {
33
+ skill.warning = filenameCheck.message;
34
+ }
35
+ return skill;
36
+ });
37
+ }
38
+ /**
39
+ * Output skills as YAML
40
+ */
41
+ function outputSkillsYaml(skills, context) {
42
+ process.stdout.write('---\n');
43
+ process.stdout.write(`status: success\n`);
44
+ process.stdout.write(`context: ${context}\n`);
45
+ process.stdout.write(`skillsFound: ${skills.length}\n`);
46
+ process.stdout.write(`skills:\n`);
47
+ for (const skill of skills) {
48
+ process.stdout.write(` - name: ${skill.name}\n`);
49
+ process.stdout.write(` path: ${skill.path}\n`);
50
+ process.stdout.write(` valid: ${skill.valid}\n`);
51
+ if (skill.warning) {
52
+ process.stdout.write(` warning: "${skill.warning}"\n`);
53
+ }
54
+ }
55
+ }
56
+ /**
57
+ * Output human-readable skill list
58
+ */
59
+ function outputSkillsHuman(skills, logger, options) {
60
+ if (skills.length === 0) {
61
+ logger.info(`\n No skills found`);
62
+ return;
63
+ }
64
+ logger.info(`\n Found ${skills.length} skill${skills.length === 1 ? '' : 's'}:\n`);
65
+ for (const skill of skills) {
66
+ const statusIcon = skill.valid ? '✅' : '⚠️';
67
+ const displayName = skill.name;
68
+ if (options.verbose) {
69
+ logger.info(` ${statusIcon} ${displayName}`);
70
+ if (skill.warning) {
71
+ logger.info(` Warning: ${skill.warning}`);
72
+ }
73
+ logger.info(` Path: ${skill.path}\n`);
74
+ }
75
+ else if (skill.warning) {
76
+ logger.info(` ${statusIcon} ${displayName} (${skill.warning})`);
77
+ }
78
+ else {
79
+ logger.info(` ${statusIcon} ${displayName}`);
80
+ }
81
+ }
82
+ }
83
+ export async function listCommand(pathArg, options) {
84
+ const logger = createLogger(options.debug ? { debug: true } : {});
85
+ try {
86
+ let skills;
87
+ let context;
88
+ if (options.user) {
89
+ // User context: scan ~/.claude
90
+ logger.info('📋 Listing user-installed skills');
91
+ const { plugins, skills: standaloneSkills } = await scanUserContext();
92
+ const allResources = [...plugins, ...standaloneSkills];
93
+ const discoveredSkills = discoverSkills(allResources);
94
+ skills = processDiscoveredSkills(discoveredSkills);
95
+ context = 'user';
96
+ }
97
+ else {
98
+ // Project context: use resources config
99
+ const rootDir = pathArg ?? process.cwd();
100
+ logger.info(`📋 Listing skills in: ${rootDir}`);
101
+ const config = loadConfig(rootDir);
102
+ const scanResult = await scan({
103
+ path: rootDir,
104
+ recursive: true,
105
+ include: config.resources?.include ?? [],
106
+ exclude: config.resources?.exclude ?? [],
107
+ });
108
+ const discoveredSkills = discoverSkills(scanResult.results);
109
+ skills = processDiscoveredSkills(discoveredSkills);
110
+ context = 'project';
111
+ }
112
+ // Output YAML to stdout
113
+ outputSkillsYaml(skills, context);
114
+ // Human-friendly output to stderr
115
+ outputSkillsHuman(skills, logger, options);
116
+ process.exit(0);
117
+ }
118
+ catch (error) {
119
+ const errorMessage = error instanceof Error ? error.message : String(error);
120
+ logger.error(`Failed to list skills: ${errorMessage}`);
121
+ process.exit(2);
122
+ }
123
+ }
124
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/skills/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Package a skill for distribution
3
+ *
4
+ * Creates distributable artifacts (directory, ZIP, npm) from a SKILL.md file
5
+ */
6
+ import { Command } from 'commander';
7
+ export interface SkillsPackageCommandOptions {
8
+ output: string;
9
+ formats?: string;
10
+ 'no-rewrite-links'?: boolean;
11
+ 'base-path'?: string;
12
+ dryRun?: boolean;
13
+ debug?: boolean;
14
+ }
15
+ export declare function createPackageCommand(): Command;
16
+ //# sourceMappingURL=package.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../../../src/commands/skills/package.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAkD9C"}
@@ -0,0 +1,293 @@
1
+ /**
2
+ * Package a skill for distribution
3
+ *
4
+ * Creates distributable artifacts (directory, ZIP, npm) from a SKILL.md file
5
+ */
6
+ import { existsSync, statSync } from 'node:fs';
7
+ import { basename, dirname, relative, resolve } from 'node:path';
8
+ import { packageSkill, validateSkill, } from '@vibe-agent-toolkit/agent-skills';
9
+ import { parseMarkdown } from '@vibe-agent-toolkit/resources';
10
+ import { Command } from 'commander';
11
+ import { handleCommandError } from '../../utils/command-error.js';
12
+ import { createLogger } from '../../utils/logger.js';
13
+ export function createPackageCommand() {
14
+ const command = new Command('package');
15
+ command
16
+ .description('Package a skill for distribution (creates directory + ZIP artifacts)')
17
+ .argument('<skill-path>', 'Path to SKILL.md file')
18
+ .requiredOption('-o, --output <path>', 'Output directory for packaged skill')
19
+ .option('-f, --formats <formats>', 'Package formats (comma-separated: directory,zip,npm,marketplace)', 'directory,zip')
20
+ .option('--no-rewrite-links', 'Skip rewriting relative links in copied files')
21
+ .option('-b, --base-path <path>', 'Base path for resolving relative links (default: dirname of SKILL.md)')
22
+ .option('--dry-run', 'Preview packaging without creating files')
23
+ .option('--debug', 'Enable debug logging')
24
+ .action(packageCommand)
25
+ .addHelpText('after', `
26
+ Description:
27
+ Packages a SKILL.md file and all linked resources into distributable
28
+ formats. Recursively collects all markdown files linked from SKILL.md,
29
+ rewrites links to maintain correctness after relocation, and creates
30
+ artifacts for distribution.
31
+
32
+ Default formats: directory (ready-to-use) + ZIP (single file)
33
+
34
+ REQUIRED: --output flag must specify where to create the package
35
+
36
+ Output:
37
+ - outputPath: Where the packaged skill was created
38
+ - skill.name: Skill name (from frontmatter or H1 title)
39
+ - files.dependencies: List of files included in package
40
+ - artifacts: Map of format → file path
41
+ - dryRun: true if --dry-run was used (no files created)
42
+
43
+ Exit Codes:
44
+ 0 - Packaging successful (or dry-run preview)
45
+ 1 - Invalid skill path or packaging error
46
+ 2 - System error
47
+
48
+ Examples:
49
+ $ vat skills package SKILL.md -o dist/my-skill
50
+ $ vat skills package SKILL.md -o /tmp/skill --dry-run
51
+ $ vat skills package SKILL.md -o dist -f zip,npm
52
+ `);
53
+ return command;
54
+ }
55
+ /**
56
+ * Validate skill and exit if errors found
57
+ */
58
+ async function validateSkillOrExit(skillPath, basePath, logger) {
59
+ logger.info(`\n🔍 Validating skill...`);
60
+ const validationResult = await validateSkill({
61
+ skillPath,
62
+ rootDir: basePath,
63
+ });
64
+ if (validationResult.status === 'error') {
65
+ displayValidationErrors(validationResult, logger);
66
+ process.exit(1);
67
+ }
68
+ logger.info(`✅ Validation passed`);
69
+ }
70
+ /**
71
+ * Display a single validation issue
72
+ */
73
+ function displayIssue(issue, logger, useErrorLevel) {
74
+ const logFn = useErrorLevel ? logger.error : logger.info;
75
+ logFn(` [${issue.code}] ${issue.message}`);
76
+ if (issue.location) {
77
+ logFn(` Location: ${issue.location}`);
78
+ }
79
+ if (issue.fix) {
80
+ logFn(` Fix: ${issue.fix}`);
81
+ }
82
+ }
83
+ /**
84
+ * Format and display validation errors
85
+ */
86
+ function displayValidationErrors(validationResult, logger) {
87
+ logger.error(`\n❌ Skill validation failed`);
88
+ logger.error(` Status: ${validationResult.status}`);
89
+ logger.error(` Summary: ${validationResult.summary}\n`);
90
+ // Group issues by severity
91
+ const errors = validationResult.issues.filter(i => i.severity === 'error');
92
+ const warnings = validationResult.issues.filter(i => i.severity === 'warning');
93
+ // Display errors
94
+ if (errors.length > 0) {
95
+ logger.error(`Errors:`);
96
+ for (const issue of errors) {
97
+ displayIssue(issue, logger, true);
98
+ }
99
+ logger.error('');
100
+ }
101
+ // Display warnings
102
+ if (warnings.length > 0) {
103
+ logger.info(`Warnings:`);
104
+ for (const issue of warnings) {
105
+ displayIssue(issue, logger, false);
106
+ }
107
+ logger.info('');
108
+ }
109
+ }
110
+ /**
111
+ * Recursively collect linked markdown files
112
+ */
113
+ async function collectLinkedFiles(markdownPath, basePath, visited) {
114
+ const normalizedPath = resolve(markdownPath);
115
+ if (visited.has(normalizedPath)) {
116
+ return [];
117
+ }
118
+ visited.add(normalizedPath);
119
+ const parseResult = await parseMarkdown(markdownPath);
120
+ const linkedFiles = [];
121
+ for (const link of parseResult.links) {
122
+ if (link.type !== 'local_file')
123
+ continue;
124
+ const hrefWithoutAnchor = link.href.split('#')[0] ?? link.href;
125
+ if (hrefWithoutAnchor === '')
126
+ continue;
127
+ const resolvedPath = resolve(dirname(markdownPath), hrefWithoutAnchor);
128
+ // Only include markdown files (no basePath filtering - collect all valid linked files)
129
+ if (!resolvedPath.endsWith('.md'))
130
+ continue;
131
+ // Skip missing files
132
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Path resolved from validated markdown links
133
+ if (!existsSync(resolvedPath))
134
+ continue;
135
+ linkedFiles.push(resolvedPath);
136
+ // Recursively collect from this file
137
+ const transitive = await collectLinkedFiles(resolvedPath, basePath, visited);
138
+ linkedFiles.push(...transitive);
139
+ }
140
+ // Deduplicate
141
+ return [...new Set(linkedFiles)];
142
+ }
143
+ /**
144
+ * Extract skill name from parse result
145
+ */
146
+ function extractSkillName(parseResult) {
147
+ if (parseResult.frontmatter?.['name']) {
148
+ return parseResult.frontmatter['name'];
149
+ }
150
+ // Try to extract H1
151
+ const lines = parseResult.content.split('\n');
152
+ for (const line of lines) {
153
+ const trimmed = line.trim();
154
+ if (trimmed.startsWith('# ')) {
155
+ return trimmed.slice(2).trim();
156
+ }
157
+ }
158
+ return 'unknown';
159
+ }
160
+ /**
161
+ * Calculate estimated ZIP size for files
162
+ */
163
+ function calculateZipSize(skillPath, linkedFiles) {
164
+ let totalSize = 0;
165
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- User-provided path, validated
166
+ totalSize += statSync(skillPath).size;
167
+ for (const file of linkedFiles) {
168
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Collected from validated markdown links
169
+ if (existsSync(file)) {
170
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Collected from validated markdown links
171
+ totalSize += statSync(file).size;
172
+ }
173
+ }
174
+ // Rough estimate: 60% compression for markdown
175
+ return Math.round((totalSize * 0.6) / 1024);
176
+ }
177
+ /**
178
+ * Output dry-run results as YAML
179
+ */
180
+ function outputDryRunYaml(skillName, outputPath, fileCount, formats, duration) {
181
+ process.stdout.write('---\n');
182
+ process.stdout.write(`status: success\n`);
183
+ process.stdout.write(`dryRun: true\n`);
184
+ process.stdout.write(`skill: ${skillName}\n`);
185
+ process.stdout.write(`outputPath: ${outputPath}\n`);
186
+ process.stdout.write(`filesPackaged: ${fileCount}\n`);
187
+ process.stdout.write(`formats:\n`);
188
+ for (const format of formats) {
189
+ process.stdout.write(` - ${format}\n`);
190
+ }
191
+ process.stdout.write(`duration: ${duration}ms\n`);
192
+ }
193
+ /**
194
+ * Perform dry-run preview of packaging operation
195
+ */
196
+ async function performDryRun(skillPath, options, logger) {
197
+ const startTime = Date.now();
198
+ // Validate skill path exists
199
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- User-provided CLI argument, validated
200
+ if (!existsSync(skillPath)) {
201
+ throw new Error(`SKILL.md not found: ${skillPath}`);
202
+ }
203
+ logger.info(`🔍 Dry-run: Analyzing skill packaging...`);
204
+ logger.info(` Source: ${skillPath}`);
205
+ logger.info(` Output: ${options.output}`);
206
+ // VALIDATE FIRST - shift left to catch errors early
207
+ await validateSkillOrExit(skillPath, options['base-path'] ?? dirname(skillPath), logger);
208
+ // Parse SKILL.md and extract metadata
209
+ const parseResult = await parseMarkdown(skillPath);
210
+ const skillName = extractSkillName(parseResult);
211
+ logger.info(` Skill: ${skillName}`);
212
+ // Collect linked files (recursively)
213
+ const basePath = options['base-path'] ?? dirname(skillPath);
214
+ const linkedFiles = await collectLinkedFiles(skillPath, basePath, new Set());
215
+ logger.info(`\n📁 Files to be packaged:`);
216
+ logger.info(` - SKILL.md (root)`);
217
+ for (const file of linkedFiles) {
218
+ const relPath = relative(basePath, file);
219
+ logger.info(` - ${relPath}`);
220
+ }
221
+ logger.info(`\n Total: ${linkedFiles.length + 1} files`);
222
+ // Parse and display formats
223
+ const formats = options.formats?.split(',').map(f => f.trim()) ?? ['directory', 'zip'];
224
+ logger.info(`\n📦 Formats to create:`);
225
+ for (const format of formats) {
226
+ logger.info(` - ${format}`);
227
+ }
228
+ // Estimate ZIP size if needed
229
+ if (formats.includes('zip')) {
230
+ const estimatedZipSize = calculateZipSize(skillPath, linkedFiles);
231
+ logger.info(`\n📊 Estimated ZIP size: ~${estimatedZipSize}KB`);
232
+ }
233
+ const duration = Date.now() - startTime;
234
+ // Output YAML results
235
+ outputDryRunYaml(skillName, options.output, linkedFiles.length + 1, formats, duration);
236
+ logger.info(`\n✅ Dry-run complete (no files created)`);
237
+ logger.info(` Run without --dry-run to create the package`);
238
+ }
239
+ async function packageCommand(skillPath, options) {
240
+ const logger = createLogger(options.debug ? { debug: true } : {});
241
+ const startTime = Date.now();
242
+ try {
243
+ logger.info(`📦 Packaging skill: ${skillPath}`);
244
+ // Parse formats
245
+ const formats = options.formats
246
+ ?.split(',')
247
+ .map(f => f.trim()) ?? ['directory', 'zip'];
248
+ // Build package options
249
+ const packageOptions = {
250
+ formats,
251
+ rewriteLinks: options['no-rewrite-links'] !== true,
252
+ outputPath: options.output,
253
+ };
254
+ if (options['base-path']) {
255
+ packageOptions.basePath = options['base-path'];
256
+ }
257
+ // Handle dry-run mode
258
+ if (options.dryRun) {
259
+ await performDryRun(skillPath, options, logger);
260
+ process.exit(0);
261
+ }
262
+ // VALIDATE FIRST - shift left to catch errors early
263
+ await validateSkillOrExit(skillPath, options['base-path'] ?? dirname(skillPath), logger);
264
+ logger.info('');
265
+ // Package the skill
266
+ const result = await packageSkill(skillPath, packageOptions);
267
+ const duration = Date.now() - startTime;
268
+ // Output YAML to stdout
269
+ process.stdout.write('---\n');
270
+ process.stdout.write(`status: success\n`);
271
+ process.stdout.write(`skill: ${result.skill.name}\n`);
272
+ process.stdout.write(`version: ${result.skill.version ?? 'unspecified'}\n`);
273
+ process.stdout.write(`outputPath: ${result.outputPath}\n`);
274
+ process.stdout.write(`filesPackaged: ${result.files.dependencies.length + 1}\n`);
275
+ if (result.artifacts) {
276
+ process.stdout.write(`artifacts:\n`);
277
+ for (const [format, path] of Object.entries(result.artifacts)) {
278
+ process.stdout.write(` ${format}: ${path}\n`);
279
+ }
280
+ }
281
+ process.stdout.write(`duration: ${duration}ms\n`);
282
+ logger.info(`✅ Packaged skill: ${result.skill.name}`);
283
+ logger.info(` Output: ${result.outputPath}`);
284
+ if (result.artifacts?.['zip']) {
285
+ logger.info(` ZIP: ${basename(result.artifacts['zip'])}`);
286
+ }
287
+ process.exit(0);
288
+ }
289
+ catch (error) {
290
+ handleCommandError(error, logger, startTime, 'SkillsPackage');
291
+ }
292
+ }
293
+ //# sourceMappingURL=package.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.js","sourceRoot":"","sources":["../../../src/commands/skills/package.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Shared utilities for skills commands
3
+ */
4
+ import type { VatSkillMetadata } from '@vibe-agent-toolkit/agent-schema';
5
+ import type { createLogger } from '../../utils/logger.js';
6
+ /**
7
+ * Package.json with VAT skill metadata
8
+ */
9
+ export interface PackageJson {
10
+ name?: string;
11
+ vat?: {
12
+ skills: VatSkillMetadata[];
13
+ };
14
+ }
15
+ /**
16
+ * Read and parse package.json from current directory
17
+ */
18
+ export declare function readPackageJson(cwd: string): Promise<PackageJson>;
19
+ /**
20
+ * Validate skill source exists
21
+ */
22
+ export declare function validateSkillSource(skill: VatSkillMetadata, cwd: string, logger: ReturnType<typeof createLogger>): string;
23
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/commands/skills/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE;QACL,MAAM,EAAE,gBAAgB,EAAE,CAAC;KAC3B,CAAC;CACF;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAWvE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,gBAAgB,EACvB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACrC,MAAM,CAWR"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Shared utilities for skills commands
3
+ */
4
+ import { existsSync } from 'node:fs';
5
+ import { readFile } from 'node:fs/promises';
6
+ import { join, resolve } from 'node:path';
7
+ /**
8
+ * Read and parse package.json from current directory
9
+ */
10
+ export async function readPackageJson(cwd) {
11
+ const packageJsonPath = join(cwd, 'package.json');
12
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Reading from validated current directory
13
+ if (!existsSync(packageJsonPath)) {
14
+ throw new Error(`package.json not found in current directory: ${cwd}`);
15
+ }
16
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Reading from validated current directory
17
+ const content = await readFile(packageJsonPath, 'utf-8');
18
+ return JSON.parse(content);
19
+ }
20
+ /**
21
+ * Validate skill source exists
22
+ */
23
+ export function validateSkillSource(skill, cwd, logger) {
24
+ const sourcePath = resolve(cwd, skill.source);
25
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Path resolved from package.json
26
+ if (!existsSync(sourcePath)) {
27
+ logger.error(`❌ Skill source not found: ${skill.source}`);
28
+ logger.error(` Expected path: ${sourcePath}`);
29
+ process.exit(1);
30
+ }
31
+ return sourcePath;
32
+ }
33
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/commands/skills/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgB1C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAW;IAChD,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAElD,+GAA+G;IAC/G,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,gDAAgD,GAAG,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,+GAA+G;IAC/G,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IACzD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAClC,KAAuB,EACvB,GAAW,EACX,MAAuC;IAEvC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAE9C,sGAAsG;IACtG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,6BAA6B,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1D,MAAM,CAAC,KAAK,CAAC,qBAAqB,UAAU,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,UAAU,CAAC;AACnB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Skills validate command - Commander.js wrapper
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare function createValidateCommand(): Command;
6
+ //# sourceMappingURL=validate-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-command.d.ts","sourceRoot":"","sources":["../../../src/commands/skills/validate-command.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,qBAAqB,IAAI,OAAO,CAuF/C"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Skills validate command - Commander.js wrapper
3
+ */
4
+ import { Command } from 'commander';
5
+ import { validateCommand } from './validate.js';
6
+ export function createValidateCommand() {
7
+ const command = new Command('validate');
8
+ command
9
+ .description('Validate skills for packaging (reads vat.skills from package.json)')
10
+ .argument('[path]', 'Path to directory with package.json (default: current directory)')
11
+ .option('--skill <name>', 'Validate specific skill only')
12
+ .option('-v, --verbose', 'Show full details including excluded reference paths')
13
+ .option('-d, --debug', 'Enable debug logging')
14
+ .action(validateCommand)
15
+ .addHelpText('after', `
16
+ Description:
17
+ Validates skills declared in package.json vat.skills field using
18
+ enhanced packaging validation. Checks size/complexity, link depth,
19
+ navigation patterns, and applies validation overrides.
20
+
21
+ Reads skills from package.json vat.skills and runs validateSkillForPackaging()
22
+ for each skill. Supports validation overrides with expiration checking.
23
+
24
+ Validation Checks:
25
+ Required (non-overridable):
26
+ - Valid YAML frontmatter
27
+ - Skill has a name
28
+ - No reserved words (anthropic/claude)
29
+ - No broken internal links
30
+ - No circular references
31
+ - Links stay within package boundary
32
+ - No filename collisions
33
+ - Forward slashes in paths (not backslashes)
34
+
35
+ Best practices (overridable):
36
+ - SKILL.md ≤500 lines (recommended)
37
+ - Total skill size ≤2000 lines
38
+ - File count ≤6 files
39
+ - Reference depth ≤2 levels
40
+ - No links to navigation files (README.md, index.md)
41
+ - Description ≥50 characters
42
+ - Progressive disclosure pattern
43
+
44
+ Validation Overrides:
45
+ Configure overrides in package.json vat.skills:
46
+
47
+ {
48
+ "vat": {
49
+ "skills": [{
50
+ "name": "my-skill",
51
+ "source": "./SKILL.md",
52
+ "path": "./dist/skills/my-skill",
53
+ "ignoreValidationErrors": {
54
+ "SKILL_LENGTH_EXCEEDS_RECOMMENDED": "Complex domain requires detailed examples",
55
+ "SKILL_TOO_MANY_FILES": {
56
+ "reason": "Migration in progress - will split skill",
57
+ "expires": "2026-06-01"
58
+ }
59
+ }
60
+ }]
61
+ }
62
+ }
63
+
64
+ Non-overridable rules (required for correctness) cannot be ignored.
65
+ Expired overrides are reported as errors.
66
+
67
+ Output:
68
+ YAML summary → stdout (for programmatic parsing)
69
+ Detailed errors → stderr (for human reading)
70
+
71
+ Output includes:
72
+ - status: success/error
73
+ - skillsValidated: number of skills validated
74
+ - results: per-skill validation details (activeErrors, ignoredErrors, expiredOverrides)
75
+ - durationSecs: validation time
76
+
77
+ Exit Codes:
78
+ 0 - All validations passed (or all errors ignored by valid overrides)
79
+ 1 - Active validation errors found (or expired overrides)
80
+ 2 - System error (file not found, invalid config, etc.)
81
+
82
+ Examples:
83
+ $ vat skills validate # Validate all skills in package.json
84
+ $ vat skills validate --skill my-skill # Validate specific skill only
85
+ $ vat skills validate packages/my-pkg/ # Validate skills in specific directory
86
+ `);
87
+ return command;
88
+ }
89
+ //# sourceMappingURL=validate-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-command.js","sourceRoot":"","sources":["../../../src/commands/skills/validate-command.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,UAAU,qBAAqB;IACnC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAExC,OAAO;SACJ,WAAW,CAAC,oEAAoE,CAAC;SACjF,QAAQ,CAAC,QAAQ,EAAE,kEAAkE,CAAC;SACtF,MAAM,CAAC,gBAAgB,EAAE,8BAA8B,CAAC;SACxD,MAAM,CAAC,eAAe,EAAE,sDAAsD,CAAC;SAC/E,MAAM,CAAC,aAAa,EAAE,sBAAsB,CAAC;SAC7C,MAAM,CAAC,eAAe,CAAC;SACvB,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuEL,CACI,CAAC;IAEJ,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Skills validate command - validate skills for packaging
3
+ *
4
+ * Validates skills declared in package.json vat.skills using validateSkillForPackaging.
5
+ * Supports validation overrides and expiration checking.
6
+ */
7
+ /**
8
+ * Skills validate command options
9
+ */
10
+ export interface SkillsValidateCommandOptions {
11
+ skill?: string;
12
+ debug?: boolean;
13
+ verbose?: boolean;
14
+ }
15
+ /**
16
+ * Skills validate command implementation
17
+ */
18
+ export declare function validateCommand(pathArg: string | undefined, options: SkillsValidateCommandOptions): Promise<void>;
19
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/commands/skills/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAmBH;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA6LD;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,IAAI,CAAC,CAoCf"}