claude-skills-cli 0.0.1

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 ADDED
@@ -0,0 +1,455 @@
1
+ # claude-skills-cli
2
+
3
+ TypeScript CLI toolkit for creating, validating, and packaging Claude skills.
4
+
5
+ **Status:** 🚧 In Development - See implementation plan below
6
+
7
+ ---
8
+
9
+ ## What This Is
10
+
11
+ A portable command-line tool for managing Claude Agent Skills, inspired by tools like `create-next-app` and `create-vite`. Install once, use anywhere:
12
+
13
+ ```bash
14
+ pnpx claude-skills-cli init --name my-skill --description "..."
15
+ pnpx claude-skills-cli validate .claude/skills/my-skill
16
+ pnpx claude-skills-cli package .claude/skills/my-skill
17
+ ```
18
+
19
+ This replaces the Python scripts that were previously in project `.claude/scripts/` directories.
20
+
21
+ ---
22
+
23
+ ## Repository Structure (Planned)
24
+
25
+ Following the **mcpick** pattern:
26
+
27
+ ```
28
+ claude-skills-cli/
29
+ ā”œā”€ā”€ package.json # CLI package config
30
+ ā”œā”€ā”€ tsconfig.json # TypeScript ES modules config
31
+ ā”œā”€ā”€ README.md # This file
32
+ ā”œā”€ā”€ .gitignore # Ignore node_modules, dist, etc.
33
+ ā”œā”€ā”€ .prettierrc # Code formatting
34
+ ā”œā”€ā”€ .changeset/ # Version management
35
+ │ ā”œā”€ā”€ README.md
36
+ │ └── config.json
37
+ ā”œā”€ā”€ src/
38
+ │ ā”œā”€ā”€ index.ts # CLI entry (#!/usr/bin/env node)
39
+ │ ā”œā”€ā”€ types.ts # TypeScript type definitions
40
+ │ ā”œā”€ā”€ commands/
41
+ │ │ ā”œā”€ā”€ init.ts # Create new skill structure
42
+ │ │ ā”œā”€ā”€ validate.ts # Validate skill format
43
+ │ │ └── package.ts # Package skill to zip
44
+ │ ā”œā”€ā”€ core/
45
+ │ │ ā”œā”€ā”€ templates.ts # SKILL.md templates as strings
46
+ │ │ └── validator.ts # Validation logic (class-based)
47
+ │ └── utils/
48
+ │ ā”œā”€ā”€ fs.ts # File system helpers
49
+ │ └── output.ts # Emoji/formatting (chalk)
50
+ ā”œā”€ā”€ templates/ # Copied from devhub-crm
51
+ │ ā”œā”€ā”€ SKILL-TEMPLATE.md
52
+ │ └── skill-structure/
53
+ │ ā”œā”€ā”€ README.md
54
+ │ ā”œā”€ā”€ references/
55
+ │ ā”œā”€ā”€ scripts/
56
+ │ └── assets/
57
+ ā”œā”€ā”€ docs/ # Copied from devhub-crm
58
+ │ ā”œā”€ā”€ SKILLS-ARCHITECTURE.md
59
+ │ ā”œā”€ā”€ SKILL-DEVELOPMENT.md
60
+ │ └── SKILL-EXAMPLES.md
61
+ └── skills/ # Portable example skills
62
+ └── skill-creator/ # Meta-skill from devhub-crm
63
+ ā”œā”€ā”€ SKILL.md
64
+ └── references/
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Files to Move from devhub-crm
70
+
71
+ The `.claude/` directory was copied wholesale, but needs reorganization:
72
+
73
+ ### āœ… Keep and Move to Root:
74
+
75
+ ```
76
+ devhub-crm/.claude/docs/ → claude-skills-cli/docs/
77
+ devhub-crm/.claude/templates/ → claude-skills-cli/templates/
78
+ devhub-crm/.claude/skills/skill-creator/ → claude-skills-cli/skills/skill-creator/
79
+ ```
80
+
81
+ ### āœ… Convert to TypeScript:
82
+
83
+ ```
84
+ devhub-crm/.claude/scripts/init_skill.py → src/commands/init.ts
85
+ devhub-crm/.claude/scripts/validate_skill.py → src/commands/validate.ts
86
+ devhub-crm/.claude/scripts/package_skill.py → src/commands/package.ts
87
+ ```
88
+
89
+ ### āŒ Delete (Not Needed):
90
+
91
+ ```
92
+ devhub-crm/.claude/settings.local.json # Project-specific
93
+ devhub-crm/.claude/skills/database-patterns/ # Project-specific
94
+ devhub-crm/.claude/TYPESCRIPT-CONVERSION-PROMPT.md # Completed
95
+ ```
96
+
97
+ ---
98
+
99
+ ## package.json Configuration
100
+
101
+ ```json
102
+ {
103
+ "name": "claude-skills-cli",
104
+ "version": "0.0.1",
105
+ "description": "CLI toolkit for creating and managing Claude Agent Skills",
106
+ "type": "module",
107
+ "main": "./dist/index.js",
108
+ "bin": {
109
+ "claude-skills-cli": "./dist/index.js"
110
+ },
111
+ "engines": {
112
+ "node": ">=22.0.0"
113
+ },
114
+ "scripts": {
115
+ "build": "tsc",
116
+ "dev": "tsc --watch",
117
+ "start": "node ./dist/index.js",
118
+ "format": "prettier --write .",
119
+ "format:check": "prettier --check .",
120
+ "changeset": "changeset",
121
+ "version": "changeset version",
122
+ "release": "pnpm run build && changeset publish"
123
+ },
124
+ "keywords": ["claude", "skills", "cli", "agent", "anthropic", "claude-code"],
125
+ "author": "Scott Spence",
126
+ "license": "MIT",
127
+ "dependencies": {
128
+ "@clack/prompts": "^0.11.0",
129
+ "chalk": "^5.3.0",
130
+ "archiver": "^7.0.0"
131
+ },
132
+ "devDependencies": {
133
+ "@changesets/cli": "^2.29.7",
134
+ "@types/node": "^24.7.0",
135
+ "@types/archiver": "^6.0.0",
136
+ "prettier": "^3.6.2",
137
+ "typescript": "^5.9.3"
138
+ }
139
+ }
140
+ ```
141
+
142
+ ---
143
+
144
+ ## tsconfig.json Configuration
145
+
146
+ ```json
147
+ {
148
+ "compilerOptions": {
149
+ "target": "ES2022",
150
+ "module": "nodenext",
151
+ "moduleResolution": "nodenext",
152
+ "strict": true,
153
+ "outDir": "./dist",
154
+ "sourceMap": true,
155
+ "esModuleInterop": true,
156
+ "allowSyntheticDefaultImports": true,
157
+ "skipLibCheck": true
158
+ },
159
+ "include": ["src/**/*"],
160
+ "exclude": ["node_modules", "dist"]
161
+ }
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Dependencies Explained
167
+
168
+ ### Runtime Dependencies:
169
+
170
+ - **@clack/prompts** - Interactive CLI prompts (like mcpick uses)
171
+ - **chalk** - Terminal string styling and colors
172
+ - **archiver** - Create zip files (replaces Python's zipfile)
173
+
174
+ ### Dev Dependencies:
175
+
176
+ - **@changesets/cli** - Version management and changelog
177
+ - **@types/node** - TypeScript types for Node.js
178
+ - **@types/archiver** - TypeScript types for archiver
179
+ - **prettier** - Code formatting
180
+ - **typescript** - TypeScript compiler
181
+
182
+ ---
183
+
184
+ ## CLI Interface (Must Match Python Version)
185
+
186
+ ### Command: init
187
+
188
+ ```bash
189
+ claude-skills init --name my-skill --description "What it does and when to use it"
190
+ claude-skills init --path /custom/path/my-skill
191
+ ```
192
+
193
+ **Creates:**
194
+
195
+ - SKILL.md with YAML frontmatter
196
+ - README.md
197
+ - references/detailed-guide.md
198
+ - scripts/example.py (executable)
199
+ - assets/ directory
200
+
201
+ **Output:**
202
+
203
+ ```
204
+ āœ… Skill created at: .claude/skills/my-skill
205
+
206
+ Next steps:
207
+ 1. Edit .claude/skills/my-skill/SKILL.md with your skill instructions
208
+ 2. Add detailed documentation to references/
209
+ 3. Add executable scripts to scripts/
210
+ 4. Remove example files you don't need
211
+
212
+ Validate with: claude-skills validate .claude/skills/my-skill
213
+ ```
214
+
215
+ ### Command: validate
216
+
217
+ ```bash
218
+ claude-skills validate .claude/skills/my-skill
219
+ claude-skills validate .claude/skills/my-skill --strict
220
+ ```
221
+
222
+ **Checks:**
223
+
224
+ - SKILL.md exists
225
+ - YAML frontmatter format
226
+ - Required fields (name, description)
227
+ - Name format (kebab-case, max 64 chars)
228
+ - Description length (max 1024 chars)
229
+ - References mentioned in SKILL.md
230
+ - Scripts are executable
231
+ - No TODO placeholders
232
+
233
+ **Output:**
234
+
235
+ ```
236
+ šŸ“‹ Validating skill: my-skill
237
+ ============================================================
238
+
239
+ āš ļø Warnings:
240
+ āš ļø Reference file 'schema.md' not mentioned in SKILL.md
241
+
242
+ āœ… Skill is valid (with warnings)
243
+ ```
244
+
245
+ **Exit codes:**
246
+
247
+ - 0 = success
248
+ - 1 = validation failed
249
+ - 1 with --strict = warnings treated as errors
250
+
251
+ ### Command: package
252
+
253
+ ```bash
254
+ claude-skills package .claude/skills/my-skill
255
+ claude-skills package .claude/skills/my-skill --output dist/
256
+ claude-skills package .claude/skills/my-skill --skip-validation
257
+ ```
258
+
259
+ **Creates:**
260
+
261
+ - Zip file with skill contents
262
+ - Excludes hidden files, .pyc, **pycache**, etc.
263
+ - Runs validation first (unless --skip-validation)
264
+
265
+ **Output:**
266
+
267
+ ```
268
+ šŸ” Validating skill...
269
+ āœ… Skill is valid!
270
+
271
+ šŸ“¦ Packaging skill: my-skill
272
+ + my-skill/SKILL.md
273
+ + my-skill/README.md
274
+ + my-skill/references/detailed-guide.md
275
+
276
+ āœ… Skill packaged successfully!
277
+ File: dist/my-skill.zip
278
+ Size: 12.3 KB
279
+
280
+ šŸ“¤ Upload to Claude.ai: Settings > Features > Skills > Upload
281
+ ```
282
+
283
+ ---
284
+
285
+ ## Implementation Roadmap
286
+
287
+ ### Phase 1: Setup (You're here!)
288
+
289
+ - [x] Create claude-skills-cli repo
290
+ - [x] Copy .claude/ from devhub-crm
291
+ - [ ] Create package.json
292
+ - [ ] Create tsconfig.json
293
+ - [ ] Setup .gitignore, .prettierrc
294
+ - [ ] Install dependencies: `pnpm install`
295
+
296
+ ### Phase 2: Reorganize Files
297
+
298
+ - [ ] Move `docs/` to root
299
+ - [ ] Move `templates/` to root
300
+ - [ ] Move `skills/skill-creator/` to root
301
+ - [ ] Delete `.claude/settings.local.json`
302
+ - [ ] Delete `.claude/skills/database-patterns/`
303
+
304
+ ### Phase 3: Convert Python → TypeScript
305
+
306
+ #### init.ts (from init_skill.py)
307
+
308
+ - [ ] Import types, fs, path, chalk
309
+ - [ ] Create template strings (SKILL.md, README.md, etc.)
310
+ - [ ] Implement createSkill() function
311
+ - Use fs.mkdirSync(path, { recursive: true })
312
+ - Use fs.writeFileSync()
313
+ - Use fs.chmodSync(scriptPath, 0o755) for executable
314
+ - [ ] Use @clack/prompts for interactive mode (optional)
315
+ - [ ] Match Python output format exactly (emoji, messages)
316
+
317
+ #### validate.ts (from validate_skill.py)
318
+
319
+ - [ ] Create SkillValidator class
320
+ - errors: string[]
321
+ - warnings: string[]
322
+ - [ ] Implement validation methods:
323
+ - validateDirectory()
324
+ - validateSkillMd() - parse YAML frontmatter
325
+ - validateReferences()
326
+ - validateScripts() - check executable with fs.statSync()
327
+ - validateAssets()
328
+ - [ ] Use chalk for colored output
329
+ - [ ] Match Python emoji output exactly
330
+ - [ ] Support --strict flag
331
+
332
+ #### package.ts (from package_skill.py)
333
+
334
+ - [ ] Import archiver for zip creation
335
+ - [ ] Call validate.ts first (child_process.spawnSync)
336
+ - [ ] Create zip with exclusions:
337
+ - Hidden files (starts with .)
338
+ - .pyc, .pyo, .swp, ~
339
+ - **pycache**, .DS_Store
340
+ - [ ] Report file size in KB
341
+ - [ ] Match Python output format
342
+
343
+ ### Phase 4: CLI Entry Point
344
+
345
+ #### index.ts
346
+
347
+ - [ ] Add shebang: `#!/usr/bin/env node`
348
+ - [ ] Import @clack/prompts
349
+ - [ ] Import commands (init, validate, package)
350
+ - [ ] Create interactive menu (like mcpick)
351
+ - "Create new skill"
352
+ - "Validate skill"
353
+ - "Package skill"
354
+ - "Exit"
355
+ - [ ] Handle command-line arguments (for non-interactive)
356
+ - [ ] Error handling with try/catch
357
+
358
+ ### Phase 5: Testing
359
+
360
+ - [ ] Build: `pnpm build`
361
+ - [ ] Test init: `node dist/index.js init --name test-skill`
362
+ - [ ] Test validate: `node dist/index.js validate skills/skill-creator`
363
+ - [ ] Test package: `node dist/index.js package skills/skill-creator`
364
+ - [ ] Verify output matches Python version
365
+
366
+ ### Phase 6: Publishing
367
+
368
+ - [ ] Setup .changeset config
369
+ - [ ] Add initial changeset
370
+ - [ ] Test with `pnpx` locally
371
+ - [ ] Publish to npm: `pnpm release`
372
+ - [ ] Update devhub-crm to use `pnpx claude-skills-cli`
373
+
374
+ ---
375
+
376
+ ## Design Decisions
377
+
378
+ ### Why @clack/prompts instead of commander?
379
+
380
+ - mcpick uses @clack/prompts for beautiful interactive menus
381
+ - Provides better UX than raw commander arguments
382
+ - Still support non-interactive mode with args
383
+
384
+ ### Why archiver instead of node:zlib?
385
+
386
+ - archiver is battle-tested for creating zips
387
+ - Handles file permissions, directory structure
388
+ - Direct replacement for Python's zipfile
389
+
390
+ ### Why chalk for colors?
391
+
392
+ - Match Python's emoji output (āœ… āŒ āš ļø)
393
+ - Better terminal color support
394
+ - Widely used, stable
395
+
396
+ ### Why ES modules (type: "module")?
397
+
398
+ - Modern Node.js best practice
399
+ - Matches mcpick setup
400
+ - Better tree-shaking, cleaner imports
401
+
402
+ ---
403
+
404
+ ## Testing Checklist
405
+
406
+ Before publishing v1.0.0:
407
+
408
+ - [ ] All three commands work (init, validate, package)
409
+ - [ ] Output matches Python version exactly
410
+ - [ ] Exit codes match (0 = success, 1 = error)
411
+ - [ ] Emoji indicators work (āœ… āŒ āš ļø)
412
+ - [ ] --strict mode works on validate
413
+ - [ ] --skip-validation works on package
414
+ - [ ] Created skills validate successfully
415
+ - [ ] Packaged zips can be uploaded to Claude.ai
416
+ - [ ] Works via `pnpx claude-skills-cli`
417
+ - [ ] Works when installed globally
418
+
419
+ ---
420
+
421
+ ## Resources
422
+
423
+ ### Official Anthropic Documentation:
424
+
425
+ - [Agent Skills Overview](https://www.anthropic.com/news/skills)
426
+ - [Engineering Blog: Agent Skills](https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills)
427
+ - [Claude Docs: Skills](https://docs.claude.com/en/docs/agents-and-tools/agent-skills/overview)
428
+ - [Anthropic Skills Repo](https://github.com/anthropics/skills)
429
+
430
+ ### Included Documentation:
431
+
432
+ - [docs/SKILLS-ARCHITECTURE.md](docs/SKILLS-ARCHITECTURE.md) - Progressive disclosure system
433
+ - [docs/SKILL-DEVELOPMENT.md](docs/SKILL-DEVELOPMENT.md) - 6-step creation workflow
434
+ - [docs/SKILL-EXAMPLES.md](docs/SKILL-EXAMPLES.md) - Real-world examples
435
+
436
+ ### Reference Implementation:
437
+
438
+ - [mcpick](https://github.com/spences10/mcpick) - Similar CLI structure to follow
439
+
440
+ ---
441
+
442
+ ## Notes for Next Chat Session
443
+
444
+ 1. **Start with setup:** Create package.json and tsconfig.json first
445
+ 2. **Install deps:** `pnpm install` to get @clack/prompts, chalk, archiver
446
+ 3. **Reorganize files:** Move docs/, templates/, skills/ from .claude/ to root
447
+ 4. **Convert Python scripts one by one:** Start with init.ts (simplest), then validate.ts, then package.ts
448
+ 5. **Create index.ts:** Wire up commands with @clack/prompts menu
449
+ 6. **Test everything:** Build and run against skill-creator to verify
450
+
451
+ **Key principle:** Match Python output and behavior EXACTLY. Users should not notice any difference except it's faster and more portable.
452
+
453
+ ---
454
+
455
+ **Ready to build!** šŸš€
@@ -0,0 +1,70 @@
1
+ import { join } from 'path';
2
+ import { SKILL_MD_TEMPLATE, REFERENCE_TEMPLATE, SCRIPT_TEMPLATE, README_TEMPLATE, } from '../core/templates.js';
3
+ import { ensure_dir, write_file, make_executable, to_title_case, is_lowercase, } from '../utils/fs.js';
4
+ import { success, error } from '../utils/output.js';
5
+ export function init_command(options) {
6
+ let skill_path;
7
+ let name;
8
+ let description;
9
+ // Determine path and name
10
+ if (options.path) {
11
+ skill_path = options.path;
12
+ name = skill_path.split('/').pop() || '';
13
+ description = options.description || 'TODO: Add description';
14
+ }
15
+ else if (options.name) {
16
+ name = options.name;
17
+ description = options.description || 'TODO: Add description';
18
+ // Default to .claude/skills/ directory
19
+ skill_path = join('.claude', 'skills', name);
20
+ }
21
+ else {
22
+ error('Either --name or --path must be provided');
23
+ console.log('\nUsage:');
24
+ console.log(' claude-skills init --name my-skill --description "Description"');
25
+ console.log(' claude-skills init --path /custom/path/my-skill');
26
+ process.exit(1);
27
+ }
28
+ // Validate name format
29
+ const alphanumeric_check = name.replace(/-/g, '').replace(/_/g, '');
30
+ if (!/^[a-z0-9]+$/.test(alphanumeric_check)) {
31
+ error(`Skill name must be kebab-case alphanumeric: ${name}`);
32
+ process.exit(1);
33
+ }
34
+ if (!is_lowercase(name)) {
35
+ error(`Skill name must be lowercase: ${name}`);
36
+ process.exit(1);
37
+ }
38
+ // Create skill
39
+ create_skill(skill_path, name, description);
40
+ }
41
+ function create_skill(path, name, description) {
42
+ // Create directories
43
+ ensure_dir(path);
44
+ ensure_dir(join(path, 'references'));
45
+ ensure_dir(join(path, 'scripts'));
46
+ ensure_dir(join(path, 'assets'));
47
+ // Create SKILL.md
48
+ const title = to_title_case(name);
49
+ const skill_md = SKILL_MD_TEMPLATE(name, description, title);
50
+ write_file(join(path, 'SKILL.md'), skill_md);
51
+ // Create example reference
52
+ const reference_md = REFERENCE_TEMPLATE(title);
53
+ write_file(join(path, 'references', 'detailed-guide.md'), reference_md);
54
+ // Create example script
55
+ const script_py = SCRIPT_TEMPLATE('example.py');
56
+ const script_path = join(path, 'scripts', 'example.py');
57
+ write_file(script_path, script_py);
58
+ make_executable(script_path);
59
+ // Create README
60
+ const readme_md = README_TEMPLATE(title, description);
61
+ write_file(join(path, 'README.md'), readme_md);
62
+ success(`Skill created at: ${path}`);
63
+ console.log('\nNext steps:');
64
+ console.log(`1. Edit ${path}/SKILL.md with your skill instructions`);
65
+ console.log(`2. Add detailed documentation to references/`);
66
+ console.log(`3. Add executable scripts to scripts/`);
67
+ console.log(`4. Remove example files you don't need`);
68
+ console.log(`\nValidate with: claude-skills validate ${path}`);
69
+ }
70
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,133 @@
1
+ import { basename, join } from 'path';
2
+ import { existsSync, statSync, readdirSync } from 'fs';
3
+ import archiver from 'archiver';
4
+ import { createWriteStream } from 'fs';
5
+ import { SkillValidator } from '../core/validator.js';
6
+ import { ensure_dir } from '../utils/fs.js';
7
+ import { error, success, package_, upload, search, step, } from '../utils/output.js';
8
+ function validate_skill(skill_path) {
9
+ search('Validating skill...');
10
+ const validator = new SkillValidator(skill_path);
11
+ const result = validator.validate_all();
12
+ if (result.errors.length > 0) {
13
+ console.log('\nāŒ Errors:');
14
+ for (const err of result.errors) {
15
+ console.log(` ${err}`);
16
+ }
17
+ }
18
+ if (result.warnings.length > 0) {
19
+ console.log('\nāš ļø Warnings:');
20
+ for (const warn of result.warnings) {
21
+ console.log(` ${warn}`);
22
+ }
23
+ }
24
+ if (result.is_valid) {
25
+ success('Skill is valid!');
26
+ console.log('');
27
+ return true;
28
+ }
29
+ else {
30
+ error('Validation failed. Fix errors before packaging.');
31
+ return false;
32
+ }
33
+ }
34
+ function package_skill(skill_path, output_dir) {
35
+ return new Promise((resolve, reject) => {
36
+ const skill_name = basename(skill_path);
37
+ const output_file = join(output_dir, `${skill_name}.zip`);
38
+ package_(`Packaging skill: ${skill_name}`);
39
+ // Ensure output directory exists
40
+ ensure_dir(output_dir);
41
+ // Create output stream
42
+ const output = createWriteStream(output_file);
43
+ const archive = archiver('zip', {
44
+ zlib: { level: 9 },
45
+ });
46
+ // Listen for all archive data to be written
47
+ output.on('close', () => {
48
+ resolve(output_file);
49
+ });
50
+ // Handle errors
51
+ archive.on('error', (err) => {
52
+ reject(err);
53
+ });
54
+ // Pipe archive data to the file
55
+ archive.pipe(output);
56
+ // Add files recursively
57
+ function add_files(dir_path, base_path) {
58
+ const items = readdirSync(dir_path);
59
+ for (const item of items) {
60
+ const item_path = join(dir_path, item);
61
+ const stats = statSync(item_path);
62
+ // Skip hidden files and directories
63
+ if (item.startsWith('.')) {
64
+ continue;
65
+ }
66
+ // Skip common temporary files
67
+ if (item.endsWith('.pyc') ||
68
+ item.endsWith('.pyo') ||
69
+ item.endsWith('.swp') ||
70
+ item.endsWith('~')) {
71
+ continue;
72
+ }
73
+ if (item === '__pycache__' || item === '.DS_Store') {
74
+ continue;
75
+ }
76
+ if (stats.isDirectory()) {
77
+ add_files(item_path, base_path);
78
+ }
79
+ else {
80
+ const relative_path = item_path.replace(base_path + '/', '');
81
+ archive.file(item_path, { name: relative_path });
82
+ step(`+ ${relative_path}`);
83
+ }
84
+ }
85
+ }
86
+ add_files(skill_path, skill_path.substring(0, skill_path.lastIndexOf('/')));
87
+ // Finalize the archive
88
+ archive.finalize();
89
+ });
90
+ }
91
+ export async function package_command(options) {
92
+ const { skill_path, output, skip_validation } = options;
93
+ // Validate path
94
+ if (!existsSync(skill_path)) {
95
+ error(`Skill directory does not exist: ${skill_path}`);
96
+ process.exit(1);
97
+ }
98
+ const stats = statSync(skill_path);
99
+ if (!stats.isDirectory()) {
100
+ error(`Path is not a directory: ${skill_path}`);
101
+ process.exit(1);
102
+ }
103
+ // Check for SKILL.md
104
+ if (!existsSync(join(skill_path, 'SKILL.md'))) {
105
+ error(`SKILL.md not found in ${skill_path}`);
106
+ process.exit(1);
107
+ }
108
+ // Validate skill
109
+ if (!skip_validation) {
110
+ if (!validate_skill(skill_path)) {
111
+ process.exit(1);
112
+ }
113
+ }
114
+ // Package skill
115
+ try {
116
+ const output_dir = output || 'dist';
117
+ const output_file = await package_skill(skill_path, output_dir);
118
+ // Print success
119
+ const file_stats = statSync(output_file);
120
+ const size_kb = file_stats.size / 1024;
121
+ console.log('');
122
+ success('Skill packaged successfully!');
123
+ console.log(` File: ${output_file}`);
124
+ console.log(` Size: ${size_kb.toFixed(1)} KB`);
125
+ console.log('');
126
+ upload('Upload to Claude.ai: Settings > Features > Skills > Upload');
127
+ }
128
+ catch (err) {
129
+ error(`Failed to package skill: ${err}`);
130
+ process.exit(1);
131
+ }
132
+ }
133
+ //# sourceMappingURL=package.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.js","sourceRoot":"","sources":["../../src/commands/package.ts"],"names":[],"mappings":"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"}