@vibe-agent-toolkit/cli 0.1.8 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) 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 +36 -32
  9. package/dist/commands/audit.js.map +1 -1
  10. package/dist/commands/skills/build.d.ts +13 -0
  11. package/dist/commands/skills/build.d.ts.map +1 -0
  12. package/dist/commands/skills/build.js +205 -0
  13. package/dist/commands/skills/build.js.map +1 -0
  14. package/dist/commands/skills/command-helpers.d.ts +30 -0
  15. package/dist/commands/skills/command-helpers.d.ts.map +1 -0
  16. package/dist/commands/skills/command-helpers.js +54 -0
  17. package/dist/commands/skills/command-helpers.js.map +1 -0
  18. package/dist/commands/skills/index.d.ts +8 -0
  19. package/dist/commands/skills/index.d.ts.map +1 -0
  20. package/dist/commands/skills/index.js +96 -0
  21. package/dist/commands/skills/index.js.map +1 -0
  22. package/dist/commands/skills/install-helpers.d.ts +45 -0
  23. package/dist/commands/skills/install-helpers.d.ts.map +1 -0
  24. package/dist/commands/skills/install-helpers.js +120 -0
  25. package/dist/commands/skills/install-helpers.js.map +1 -0
  26. package/dist/commands/skills/install.d.ts +20 -0
  27. package/dist/commands/skills/install.d.ts.map +1 -0
  28. package/dist/commands/skills/install.js +287 -0
  29. package/dist/commands/skills/install.js.map +1 -0
  30. package/dist/commands/skills/list.d.ts +12 -0
  31. package/dist/commands/skills/list.d.ts.map +1 -0
  32. package/dist/commands/skills/list.js +124 -0
  33. package/dist/commands/skills/list.js.map +1 -0
  34. package/dist/commands/skills/package.d.ts +16 -0
  35. package/dist/commands/skills/package.d.ts.map +1 -0
  36. package/dist/commands/skills/package.js +293 -0
  37. package/dist/commands/skills/package.js.map +1 -0
  38. package/dist/commands/skills/validate-command.d.ts +6 -0
  39. package/dist/commands/skills/validate-command.d.ts.map +1 -0
  40. package/dist/commands/skills/validate-command.js +76 -0
  41. package/dist/commands/skills/validate-command.js.map +1 -0
  42. package/dist/commands/skills/validate.d.ts +24 -0
  43. package/dist/commands/skills/validate.d.ts.map +1 -0
  44. package/dist/commands/skills/validate.js +264 -0
  45. package/dist/commands/skills/validate.js.map +1 -0
  46. package/dist/utils/claude-paths.d.ts +32 -0
  47. package/dist/utils/claude-paths.d.ts.map +1 -0
  48. package/dist/utils/claude-paths.js +34 -0
  49. package/dist/utils/claude-paths.js.map +1 -0
  50. package/dist/utils/skill-discovery.d.ts +49 -0
  51. package/dist/utils/skill-discovery.d.ts.map +1 -0
  52. package/dist/utils/skill-discovery.js +73 -0
  53. package/dist/utils/skill-discovery.js.map +1 -0
  54. package/dist/utils/user-context-scanner.d.ts +31 -0
  55. package/dist/utils/user-context-scanner.d.ts.map +1 -0
  56. package/dist/utils/user-context-scanner.js +60 -0
  57. package/dist/utils/user-context-scanner.js.map +1 -0
  58. package/docs/audit.md +1 -0
  59. package/docs/skills.md +561 -0
  60. package/package.json +18 -12
@@ -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,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,CA0E/C"}
@@ -0,0 +1,76 @@
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 SKILL.md files (links, frontmatter, skill rules)')
10
+ .argument('[path]', 'Path to validate (default: current directory)')
11
+ .option('-u, --user', 'Validate user-installed skills in ~/.claude')
12
+ .option('-d, --debug', 'Enable debug logging')
13
+ .action(validateCommand)
14
+ .addHelpText('after', `
15
+ Description:
16
+ Validates all SKILL.md files using both resource validation (markdown,
17
+ links, frontmatter) and skill-specific validation (reserved words, XML
18
+ tags, console compatibility). Reports all errors in a unified format.
19
+
20
+ Supports three modes:
21
+ - Project mode (default): Validate project skills with strict filename validation
22
+ - User mode (--user): Validate ~/.claude skills with permissive validation
23
+ - Path mode: Validate skills at specific path with strict validation
24
+
25
+ Validation Modes:
26
+ Project mode (strict):
27
+ - Respects vibe-agent-toolkit.config.yaml boundaries
28
+ - Filename must be exactly "SKILL.md" (case-sensitive)
29
+ - Errors on non-standard filenames (skill.md, Skill.md)
30
+
31
+ User mode (permissive):
32
+ - Scans ~/.claude/plugins and ~/.claude/skills
33
+ - Filename warnings for non-standard names (not errors)
34
+ - More tolerant for user-installed content
35
+
36
+ Validation Checks:
37
+ Resource validation:
38
+ - Internal file links (relative paths)
39
+ - Anchor links within files (#heading)
40
+ - Cross-file anchor links (file.md#heading)
41
+ - Frontmatter schema (if SKILL.md has frontmatter)
42
+
43
+ Skill-specific validation:
44
+ - Reserved word checks (name field)
45
+ - XML tag detection (name/description fields)
46
+ - Console compatibility warnings
47
+ - Frontmatter required fields (name, description)
48
+
49
+ Filename validation:
50
+ - Must be "SKILL.md" (uppercase)
51
+ - Strict mode: error on skill.md, Skill.md
52
+ - Permissive mode: warning only
53
+
54
+ Output:
55
+ YAML summary → stdout (for programmatic parsing)
56
+ Detailed errors → stderr (for human reading)
57
+
58
+ Output includes:
59
+ - status: success/error
60
+ - skillsValidated: number of SKILL.md files found
61
+ - results: per-skill validation details
62
+ - durationSecs: validation time
63
+
64
+ Exit Codes:
65
+ 0 - All validations passed
66
+ 1 - Validation errors found (warnings don't fail)
67
+ 2 - System error (file not found, config invalid, etc.)
68
+
69
+ Examples:
70
+ $ vat skills validate # Project mode: validate all project skills
71
+ $ vat skills validate --user # User mode: validate ~/.claude skills
72
+ $ vat skills validate packages/ # Path mode: validate specific directory
73
+ `);
74
+ return command;
75
+ }
76
+ //# 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,2DAA2D,CAAC;SACxE,QAAQ,CAAC,QAAQ,EAAE,+CAA+C,CAAC;SACnE,MAAM,CAAC,YAAY,EAAE,6CAA6C,CAAC;SACnE,MAAM,CAAC,aAAa,EAAE,sBAAsB,CAAC;SAC7C,MAAM,CAAC,eAAe,CAAC;SACvB,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2DL,CACI,CAAC;IAEJ,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Skills validate command - unified validation for SKILL.md files
3
+ *
4
+ * Combines resource validation (markdown, links, frontmatter) with
5
+ * skill-specific validation (reserved words, XML tags, console compatibility).
6
+ *
7
+ * Supports three modes:
8
+ * 1. Project context (default): Validate project skills with strict filename validation
9
+ * 2. User context (--user flag): Validate ~/.claude skills with permissive validation
10
+ * 3. Path context (explicit path): Validate skills at specific path
11
+ */
12
+ /**
13
+ * Skills validate command options
14
+ */
15
+ interface SkillsValidateCommandOptions {
16
+ debug?: boolean;
17
+ user?: boolean;
18
+ }
19
+ /**
20
+ * Skills validate command implementation
21
+ */
22
+ export declare function validateCommand(pathArg: string | undefined, options: SkillsValidateCommandOptions): Promise<void>;
23
+ export {};
24
+ //# 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;;;;;;;;;;GAUG;AAoSH;;GAEG;AACH,UAAU,4BAA4B;IACpC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,IAAI,CAAC,CAkGf"}