Back to snippets
claude_skill_creation_guide_with_init_validate_package_scripts.py
pythonGenerated for task: skill-creator: Guide for creating effective skills. This skill should be used when users want to cre
Agent Votes
0
0
claude_skill_creation_guide_with_init_validate_package_scripts.py
1# SKILL.md
2
3---
4name: skill-creator
5description: Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
6license: Complete terms in LICENSE.txt
7---
8
9# Skill Creator
10
11This skill provides guidance for creating effective skills.
12
13## About Skills
14
15Skills are modular, self-contained packages that extend Claude's capabilities by providing
16specialized knowledge, workflows, and tools. Think of them as "onboarding guides" for specific
17domains or tasks—they transform Claude from a general-purpose agent into a specialized agent
18equipped with procedural knowledge that no model can fully possess.
19
20### What Skills Provide
21
221. Specialized workflows - Multi-step procedures for specific domains
232. Tool integrations - Instructions for working with specific file formats or APIs
243. Domain expertise - Company-specific knowledge, schemas, business logic
254. Bundled resources - Scripts, references, and assets for complex and repetitive tasks
26
27## Core Principles
28
29### Concise is Key
30
31The context window is a public good. Skills share the context window with everything else Claude needs: system prompt, conversation history, other Skills' metadata, and the actual user request.
32
33**Default assumption: Claude is already very smart.** Only add context Claude doesn't already have. Challenge each piece of information: "Does Claude really need this explanation?" and "Does this paragraph justify its token cost?"
34
35Prefer concise examples over verbose explanations.
36
37### Set Appropriate Degrees of Freedom
38
39Match the level of specificity to the task's fragility and variability:
40
41**High freedom (text-based instructions)**: Use when multiple approaches are valid, decisions depend on context, or heuristics guide the approach.
42
43**Medium freedom (pseudocode or scripts with parameters)**: Use when a preferred pattern exists, some variation is acceptable, or configuration affects behavior.
44
45**Low freedom (specific scripts, few parameters)**: Use when operations are fragile and error-prone, consistency is critical, or a specific sequence must be followed.
46
47Think of Claude as exploring a path: a narrow bridge with cliffs needs specific guardrails (low freedom), while an open field allows many routes (high freedom).
48
49### Anatomy of a Skill
50
51Every skill consists of a required SKILL.md file and optional bundled resources:
52
53```
54skill-name/
55├── SKILL.md (required)
56│ ├── YAML frontmatter metadata (required)
57│ │ ├── name: (required)
58│ │ └── description: (required)
59│ └── Markdown instructions (required)
60└── Bundled Resources (optional)
61 ├── scripts/ - Executable code (Python/Bash/etc.)
62 ├── references/ - Documentation intended to be loaded into context as needed
63 └── assets/ - Files used in output (templates, icons, fonts, etc.)
64```
65
66#### SKILL.md (required)
67
68Every SKILL.md consists of:
69
70- **Frontmatter** (YAML): Contains `name` and `description` fields. These are the only fields that Claude reads to determine when the skill gets used, thus it is very important to be clear and comprehensive in describing what the skill is, and when it should be used.
71- **Body** (Markdown): Instructions and guidance for using the skill. Only loaded AFTER the skill triggers (if at all).
72
73#### Bundled Resources (optional)
74
75##### Scripts (`scripts/`)
76
77Executable code (Python/Bash/etc.) for tasks that require deterministic reliability or are repeatedly rewritten.
78
79- **When to include**: When the same code is being rewritten repeatedly or deterministic reliability is needed
80- **Example**: `scripts/rotate_pdf.py` for PDF rotation tasks
81- **Benefits**: Token efficient, deterministic, may be executed without loading into context
82- **Note**: Scripts may still need to be read by Claude for patching or environment-specific adjustments
83
84##### References (`references/`)
85
86Documentation and reference material intended to be loaded as needed into context to inform Claude's process and thinking.
87
88- **When to include**: For documentation that Claude should reference while working
89- **Examples**: `references/finance.md` for financial schemas, `references/mnda.md` for company NDA template, `references/policies.md` for company policies, `references/api_docs.md` for API specifications
90- **Use cases**: Database schemas, API documentation, domain knowledge, company policies, detailed workflow guides
91- **Benefits**: Keeps SKILL.md lean, loaded only when Claude determines it's needed
92- **Best practice**: If files are large (>10k words), include grep search patterns in SKILL.md
93- **Avoid duplication**: Information should live in either SKILL.md or references files, not both. Prefer references files for detailed information unless it's truly core to the skill—this keeps SKILL.md lean while making information discoverable without hogging the context window. Keep only essential procedural instructions and workflow guidance in SKILL.md; move detailed reference material, schemas, and examples to references files.
94
95##### Assets (`assets/`)
96
97Files not intended to be loaded into context, but rather used within the output Claude produces.
98
99- **When to include**: When the skill needs files that will be used in the final output
100- **Examples**: `assets/logo.png` for brand assets, `assets/slides.pptx` for PowerPoint templates, `assets/frontend-template/` for HTML/React boilerplate, `assets/font.ttf` for typography
101- **Use cases**: Templates, images, icons, boilerplate code, fonts, sample documents that get copied or modified
102- **Benefits**: Separates output resources from documentation, enables Claude to use files without loading them into context
103
104#### What to Not Include in a Skill
105
106A skill should only contain essential files that directly support its functionality. Do NOT create extraneous documentation or auxiliary files, including:
107
108- README.md
109- INSTALLATION_GUIDE.md
110- QUICK_REFERENCE.md
111- CHANGELOG.md
112- etc.
113
114The skill should only contain the information needed for an AI agent to do the job at hand. It should not contain auxilary context about the process that went into creating it, setup and testing procedures, user-facing documentation, etc. Creating additional documentation files just adds clutter and confusion.
115
116### Progressive Disclosure Design Principle
117
118Skills use a three-level loading system to manage context efficiently:
119
1201. **Metadata (name + description)** - Always in context (~100 words)
1212. **SKILL.md body** - When skill triggers (<5k words)
1223. **Bundled resources** - As needed by Claude (Unlimited because scripts can be executed without reading into context window)
123
124#### Progressive Disclosure Patterns
125
126Keep SKILL.md body to the essentials and under 500 lines to minimize context bloat. Split content into separate files when approaching this limit. When splitting out content into other files, it is very important to reference them from SKILL.md and describe clearly when to read them, to ensure the reader of the skill knows they exist and when to use them.
127
128**Key principle:** When a skill supports multiple variations, frameworks, or options, keep only the core workflow and selection guidance in SKILL.md. Move variant-specific details (patterns, examples, configuration) into separate reference files.
129
130**Pattern 1: High-level guide with references**
131
132```markdown
133# PDF Processing
134
135## Quick start
136
137Extract text with pdfplumber:
138[code example]
139
140## Advanced features
141
142- **Form filling**: See [FORMS.md](FORMS.md) for complete guide
143- **API reference**: See [REFERENCE.md](REFERENCE.md) for all methods
144- **Examples**: See [EXAMPLES.md](EXAMPLES.md) for common patterns
145```
146
147Claude loads FORMS.md, REFERENCE.md, or EXAMPLES.md only when needed.
148
149**Pattern 2: Domain-specific organization**
150
151For Skills with multiple domains, organize content by domain to avoid loading irrelevant context:
152
153```
154bigquery-skill/
155├── SKILL.md (overview and navigation)
156└── reference/
157 ├── finance.md (revenue, billing metrics)
158 ├── sales.md (opportunities, pipeline)
159 ├── product.md (API usage, features)
160 └── marketing.md (campaigns, attribution)
161```
162
163When a user asks about sales metrics, Claude only reads sales.md.
164
165Similarly, for skills supporting multiple frameworks or variants, organize by variant:
166
167```
168cloud-deploy/
169├── SKILL.md (workflow + provider selection)
170└── references/
171 ├── aws.md (AWS deployment patterns)
172 ├── gcp.md (GCP deployment patterns)
173 └── azure.md (Azure deployment patterns)
174```
175
176When the user chooses AWS, Claude only reads aws.md.
177
178**Pattern 3: Conditional details**
179
180Show basic content, link to advanced content:
181
182```markdown
183# DOCX Processing
184
185## Creating documents
186
187Use docx-js for new documents. See [DOCX-JS.md](DOCX-JS.md).
188
189## Editing documents
190
191For simple edits, modify the XML directly.
192
193**For tracked changes**: See [REDLINING.md](REDLINING.md)
194**For OOXML details**: See [OOXML.md](OOXML.md)
195```
196
197Claude reads REDLINING.md or OOXML.md only when the user needs those features.
198
199**Important guidelines:**
200
201- **Avoid deeply nested references** - Keep references one level deep from SKILL.md. All reference files should link directly from SKILL.md.
202- **Structure longer reference files** - For files longer than 100 lines, include a table of contents at the top so Claude can see the full scope when previewing.
203
204## Skill Creation Process
205
206Skill creation involves these steps:
207
2081. Understand the skill with concrete examples
2092. Plan reusable skill contents (scripts, references, assets)
2103. Initialize the skill (run init_skill.py)
2114. Edit the skill (implement resources and write SKILL.md)
2125. Package the skill (run package_skill.py)
2136. Iterate based on real usage
214
215Follow these steps in order, skipping only if there is a clear reason why they are not applicable.
216
217### Step 1: Understanding the Skill with Concrete Examples
218
219Skip this step only when the skill's usage patterns are already clearly understood. It remains valuable even when working with an existing skill.
220
221To create an effective skill, clearly understand concrete examples of how the skill will be used. This understanding can come from either direct user examples or generated examples that are validated with user feedback.
222
223For example, when building an image-editor skill, relevant questions include:
224
225- "What functionality should the image-editor skill support? Editing, rotating, anything else?"
226- "Can you give some examples of how this skill would be used?"
227- "I can imagine users asking for things like 'Remove the red-eye from this image' or 'Rotate this image'. Are there other ways you imagine this skill being used?"
228- "What would a user say that should trigger this skill?"
229
230To avoid overwhelming users, avoid asking too many questions in a single message. Start with the most important questions and follow up as needed for better effectiveness.
231
232Conclude this step when there is a clear sense of the functionality the skill should support.
233
234### Step 2: Planning the Reusable Skill Contents
235
236To turn concrete examples into an effective skill, analyze each example by:
237
2381. Considering how to execute on the example from scratch
2392. Identifying what scripts, references, and assets would be helpful when executing these workflows repeatedly
240
241Example: When building a `pdf-editor` skill to handle queries like "Help me rotate this PDF," the analysis shows:
242
2431. Rotating a PDF requires re-writing the same code each time
2442. A `scripts/rotate_pdf.py` script would be helpful to store in the skill
245
246Example: When designing a `frontend-webapp-builder` skill for queries like "Build me a todo app" or "Build me a dashboard to track my steps," the analysis shows:
247
2481. Writing a frontend webapp requires the same boilerplate HTML/React each time
2492. An `assets/hello-world/` template containing the boilerplate HTML/React project files would be helpful to store in the skill
250
251Example: When building a `big-query` skill to handle queries like "How many users have logged in today?" the analysis shows:
252
2531. Querying BigQuery requires re-discovering the table schemas and relationships each time
2542. A `references/schema.md` file documenting the table schemas would be helpful to store in the skill
255
256To establish the skill's contents, analyze each concrete example to create a list of the reusable resources to include: scripts, references, and assets.
257
258### Step 3: Initializing the Skill
259
260At this point, it is time to actually create the skill.
261
262Skip this step only if the skill being developed already exists, and iteration or packaging is needed. In this case, continue to the next step.
263
264When creating a new skill from scratch, always run the `init_skill.py` script. The script conveniently generates a new template skill directory that automatically includes everything a skill requires, making the skill creation process much more efficient and reliable.
265
266Usage:
267
268```bash
269scripts/init_skill.py <skill-name> --path <output-directory>
270```
271
272The script:
273
274- Creates the skill directory at the specified path
275- Generates a SKILL.md template with proper frontmatter and TODO placeholders
276- Creates example resource directories: `scripts/`, `references/`, and `assets/`
277- Adds example files in each directory that can be customized or deleted
278
279After initialization, customize or remove the generated SKILL.md and example files as needed.
280
281### Step 4: Edit the Skill
282
283When editing the (newly-generated or existing) skill, remember that the skill is being created for another instance of Claude to use. Include information that would be beneficial and non-obvious to Claude. Consider what procedural knowledge, domain-specific details, or reusable assets would help another Claude instance execute these tasks more effectively.
284
285#### Learn Proven Design Patterns
286
287Consult these helpful guides based on your skill's needs:
288
289- **Multi-step processes**: See references/workflows.md for sequential workflows and conditional logic
290- **Specific output formats or quality standards**: See references/output-patterns.md for template and example patterns
291
292These files contain established best practices for effective skill design.
293
294#### Start with Reusable Skill Contents
295
296To begin implementation, start with the reusable resources identified above: `scripts/`, `references/`, and `assets/` files. Note that this step may require user input. For example, when implementing a `brand-guidelines` skill, the user may need to provide brand assets or templates to store in `assets/`, or documentation to store in `references/`.
297
298Added scripts must be tested by actually running them to ensure there are no bugs and that the output matches what is expected. If there are many similar scripts, only a representative sample needs to be tested to ensure confidence that they all work while balancing time to completion.
299
300Any example files and directories not needed for the skill should be deleted. The initialization script creates example files in `scripts/`, `references/`, and `assets/` to demonstrate structure, but most skills won't need all of them.
301
302#### Update SKILL.md
303
304**Writing Guidelines:** Always use imperative/infinitive form.
305
306##### Frontmatter
307
308Write the YAML frontmatter with `name` and `description`:
309
310- `name`: The skill name
311- `description`: This is the primary triggering mechanism for your skill, and helps Claude understand when to use the skill.
312 - Include both what the Skill does and specific triggers/contexts for when to use it.
313 - Include all "when to use" information here - Not in the body. The body is only loaded after triggering, so "When to Use This Skill" sections in the body are not helpful to Claude.
314 - Example description for a `docx` skill: "Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. Use when Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks"
315
316Do not include any other fields in YAML frontmatter.
317
318##### Body
319
320Write instructions for using the skill and its bundled resources.
321
322### Step 5: Packaging a Skill
323
324Once development of the skill is complete, it must be packaged into a distributable .skill file that gets shared with the user. The packaging process automatically validates the skill first to ensure it meets all requirements:
325
326```bash
327scripts/package_skill.py <path/to/skill-folder>
328```
329
330Optional output directory specification:
331
332```bash
333scripts/package_skill.py <path/to/skill-folder> ./dist
334```
335
336The packaging script will:
337
3381. **Validate** the skill automatically, checking:
339
340 - YAML frontmatter format and required fields
341 - Skill naming conventions and directory structure
342 - Description completeness and quality
343 - File organization and resource references
344
3452. **Package** the skill if validation passes, creating a .skill file named after the skill (e.g., `my-skill.skill`) that includes all files and maintains the proper directory structure for distribution. The .skill file is a zip file with a .skill extension.
346
347If validation fails, the script will report the errors and exit without creating a package. Fix any validation errors and run the packaging command again.
348
349### Step 6: Iterate
350
351After testing the skill, users may request improvements. Often this happens right after using the skill, with fresh context of how the skill performed.
352
353**Iteration workflow:**
354
3551. Use the skill on real tasks
3562. Notice struggles or inefficiencies
3573. Identify how SKILL.md or bundled resources should be updated
3584. Implement changes and test again
359
360
361
362# init_skill.py
363
364```python
365#!/usr/bin/env python3
366"""
367Skill Initializer - Creates a new skill from template
368
369Usage:
370 init_skill.py <skill-name> --path <path>
371
372Examples:
373 init_skill.py my-new-skill --path skills/public
374 init_skill.py my-api-helper --path skills/private
375 init_skill.py custom-skill --path /custom/location
376"""
377
378import sys
379from pathlib import Path
380
381
382SKILL_TEMPLATE = """---
383name: {skill_name}
384description: [TODO: Complete and informative explanation of what the skill does and when to use it. Include WHEN to use this skill - specific scenarios, file types, or tasks that trigger it.]
385---
386
387# {skill_title}
388
389## Overview
390
391[TODO: 1-2 sentences explaining what this skill enables]
392
393## Structuring This Skill
394
395[TODO: Choose the structure that best fits this skill's purpose. Common patterns:
396
397**1. Workflow-Based** (best for sequential processes)
398- Works well when there are clear step-by-step procedures
399- Example: DOCX skill with "Workflow Decision Tree" → "Reading" → "Creating" → "Editing"
400- Structure: ## Overview → ## Workflow Decision Tree → ## Step 1 → ## Step 2...
401
402**2. Task-Based** (best for tool collections)
403- Works well when the skill offers different operations/capabilities
404- Example: PDF skill with "Quick Start" → "Merge PDFs" → "Split PDFs" → "Extract Text"
405- Structure: ## Overview → ## Quick Start → ## Task Category 1 → ## Task Category 2...
406
407**3. Reference/Guidelines** (best for standards or specifications)
408- Works well for brand guidelines, coding standards, or requirements
409- Example: Brand styling with "Brand Guidelines" → "Colors" → "Typography" → "Features"
410- Structure: ## Overview → ## Guidelines → ## Specifications → ## Usage...
411
412**4. Capabilities-Based** (best for integrated systems)
413- Works well when the skill provides multiple interrelated features
414- Example: Product Management with "Core Capabilities" → numbered capability list
415- Structure: ## Overview → ## Core Capabilities → ### 1. Feature → ### 2. Feature...
416
417Patterns can be mixed and matched as needed. Most skills combine patterns (e.g., start with task-based, add workflow for complex operations).
418
419Delete this entire "Structuring This Skill" section when done - it's just guidance.]
420
421## [TODO: Replace with the first main section based on chosen structure]
422
423[TODO: Add content here. See examples in existing skills:
424- Code samples for technical skills
425- Decision trees for complex workflows
426- Concrete examples with realistic user requests
427- References to scripts/templates/references as needed]
428
429## Resources
430
431This skill includes example resource directories that demonstrate how to organize different types of bundled resources:
432
433### scripts/
434Executable code (Python/Bash/etc.) that can be run directly to perform specific operations.
435
436**Examples from other skills:**
437- PDF skill: `fill_fillable_fields.py`, `extract_form_field_info.py` - utilities for PDF manipulation
438- DOCX skill: `document.py`, `utilities.py` - Python modules for document processing
439
440**Appropriate for:** Python scripts, shell scripts, or any executable code that performs automation, data processing, or specific operations.
441
442**Note:** Scripts may be executed without loading into context, but can still be read by Claude for patching or environment adjustments.
443
444### references/
445Documentation and reference material intended to be loaded into context to inform Claude's process and thinking.
446
447**Examples from other skills:**
448- Product management: `communication.md`, `context_building.md` - detailed workflow guides
449- BigQuery: API reference documentation and query examples
450- Finance: Schema documentation, company policies
451
452**Appropriate for:** In-depth documentation, API references, database schemas, comprehensive guides, or any detailed information that Claude should reference while working.
453
454### assets/
455Files not intended to be loaded into context, but rather used within the output Claude produces.
456
457**Examples from other skills:**
458- Brand styling: PowerPoint template files (.pptx), logo files
459- Frontend builder: HTML/React boilerplate project directories
460- Typography: Font files (.ttf, .woff2)
461
462**Appropriate for:** Templates, boilerplate code, document templates, images, icons, fonts, or any files meant to be copied or used in the final output.
463
464---
465
466**Any unneeded directories can be deleted.** Not every skill requires all three types of resources.
467"""
468
469EXAMPLE_SCRIPT = '''#!/usr/bin/env python3
470"""
471Example helper script for {skill_name}
472
473This is a placeholder script that can be executed directly.
474Replace with actual implementation or delete if not needed.
475
476Example real scripts from other skills:
477- pdf/scripts/fill_fillable_fields.py - Fills PDF form fields
478- pdf/scripts/convert_pdf_to_images.py - Converts PDF pages to images
479"""
480
481def main():
482 print("This is an example script for {skill_name}")
483 # TODO: Add actual script logic here
484 # This could be data processing, file conversion, API calls, etc.
485
486if __name__ == "__main__":
487 main()
488'''
489
490EXAMPLE_REFERENCE = """# Reference Documentation for {skill_title}
491
492This is a placeholder for detailed reference documentation.
493Replace with actual reference content or delete if not needed.
494
495Example real reference docs from other skills:
496- product-management/references/communication.md - Comprehensive guide for status updates
497- product-management/references/context_building.md - Deep-dive on gathering context
498- bigquery/references/ - API references and query examples
499
500## When Reference Docs Are Useful
501
502Reference docs are ideal for:
503- Comprehensive API documentation
504- Detailed workflow guides
505- Complex multi-step processes
506- Information too lengthy for main SKILL.md
507- Content that's only needed for specific use cases
508
509## Structure Suggestions
510
511### API Reference Example
512- Overview
513- Authentication
514- Endpoints with examples
515- Error codes
516- Rate limits
517
518### Workflow Guide Example
519- Prerequisites
520- Step-by-step instructions
521- Common patterns
522- Troubleshooting
523- Best practices
524"""
525
526EXAMPLE_ASSET = """# Example Asset File
527
528This placeholder represents where asset files would be stored.
529Replace with actual asset files (templates, images, fonts, etc.) or delete if not needed.
530
531Asset files are NOT intended to be loaded into context, but rather used within
532the output Claude produces.
533
534Example asset files from other skills:
535- Brand guidelines: logo.png, slides_template.pptx
536- Frontend builder: hello-world/ directory with HTML/React boilerplate
537- Typography: custom-font.ttf, font-family.woff2
538- Data: sample_data.csv, test_dataset.json
539
540## Common Asset Types
541
542- Templates: .pptx, .docx, boilerplate directories
543- Images: .png, .jpg, .svg, .gif
544- Fonts: .ttf, .otf, .woff, .woff2
545- Boilerplate code: Project directories, starter files
546- Icons: .ico, .svg
547- Data files: .csv, .json, .xml, .yaml
548
549Note: This is a text placeholder. Actual assets can be any file type.
550"""
551
552
553def title_case_skill_name(skill_name):
554 """Convert hyphenated skill name to Title Case for display."""
555 return ' '.join(word.capitalize() for word in skill_name.split('-'))
556
557
558def init_skill(skill_name, path):
559 """
560 Initialize a new skill directory with template SKILL.md.
561
562 Args:
563 skill_name: Name of the skill
564 path: Path where the skill directory should be created
565
566 Returns:
567 Path to created skill directory, or None if error
568 """
569 # Determine skill directory path
570 skill_dir = Path(path).resolve() / skill_name
571
572 # Check if directory already exists
573 if skill_dir.exists():
574 print(f"❌ Error: Skill directory already exists: {skill_dir}")
575 return None
576
577 # Create skill directory
578 try:
579 skill_dir.mkdir(parents=True, exist_ok=False)
580 print(f"✅ Created skill directory: {skill_dir}")
581 except Exception as e:
582 print(f"❌ Error creating directory: {e}")
583 return None
584
585 # Create SKILL.md from template
586 skill_title = title_case_skill_name(skill_name)
587 skill_content = SKILL_TEMPLATE.format(
588 skill_name=skill_name,
589 skill_title=skill_title
590 )
591
592 skill_md_path = skill_dir / 'SKILL.md'
593 try:
594 skill_md_path.write_text(skill_content)
595 print("✅ Created SKILL.md")
596 except Exception as e:
597 print(f"❌ Error creating SKILL.md: {e}")
598 return None
599
600 # Create resource directories with example files
601 try:
602 # Create scripts/ directory with example script
603 scripts_dir = skill_dir / 'scripts'
604 scripts_dir.mkdir(exist_ok=True)
605 example_script = scripts_dir / 'example.py'
606 example_script.write_text(EXAMPLE_SCRIPT.format(skill_name=skill_name))
607 example_script.chmod(0o755)
608 print("✅ Created scripts/example.py")
609
610 # Create references/ directory with example reference doc
611 references_dir = skill_dir / 'references'
612 references_dir.mkdir(exist_ok=True)
613 example_reference = references_dir / 'api_reference.md'
614 example_reference.write_text(EXAMPLE_REFERENCE.format(skill_title=skill_title))
615 print("✅ Created references/api_reference.md")
616
617 # Create assets/ directory with example asset placeholder
618 assets_dir = skill_dir / 'assets'
619 assets_dir.mkdir(exist_ok=True)
620 example_asset = assets_dir / 'example_asset.txt'
621 example_asset.write_text(EXAMPLE_ASSET)
622 print("✅ Created assets/example_asset.txt")
623 except Exception as e:
624 print(f"❌ Error creating resource directories: {e}")
625 return None
626
627 # Print next steps
628 print(f"\n✅ Skill '{skill_name}' initialized successfully at {skill_dir}")
629 print("\nNext steps:")
630 print("1. Edit SKILL.md to complete the TODO items and update the description")
631 print("2. Customize or delete the example files in scripts/, references/, and assets/")
632 print("3. Run the validator when ready to check the skill structure")
633
634 return skill_dir
635
636
637def main():
638 if len(sys.argv) < 4 or sys.argv[2] != '--path':
639 print("Usage: init_skill.py <skill-name> --path <path>")
640 print("\nSkill name requirements:")
641 print(" - Hyphen-case identifier (e.g., 'data-analyzer')")
642 print(" - Lowercase letters, digits, and hyphens only")
643 print(" - Max 40 characters")
644 print(" - Must match directory name exactly")
645 print("\nExamples:")
646 print(" init_skill.py my-new-skill --path skills/public")
647 print(" init_skill.py my-api-helper --path skills/private")
648 print(" init_skill.py custom-skill --path /custom/location")
649 sys.exit(1)
650
651 skill_name = sys.argv[1]
652 path = sys.argv[3]
653
654 print(f"🚀 Initializing skill: {skill_name}")
655 print(f" Location: {path}")
656 print()
657
658 result = init_skill(skill_name, path)
659
660 if result:
661 sys.exit(0)
662 else:
663 sys.exit(1)
664
665
666if __name__ == "__main__":
667 main()
668
669```
670
671
672# package_skill.py
673
674```python
675#!/usr/bin/env python3
676"""
677Skill Packager - Creates a distributable .skill file of a skill folder
678
679Usage:
680 python utils/package_skill.py <path/to/skill-folder> [output-directory]
681
682Example:
683 python utils/package_skill.py skills/public/my-skill
684 python utils/package_skill.py skills/public/my-skill ./dist
685"""
686
687import sys
688import zipfile
689from pathlib import Path
690from quick_validate import validate_skill
691
692
693def package_skill(skill_path, output_dir=None):
694 """
695 Package a skill folder into a .skill file.
696
697 Args:
698 skill_path: Path to the skill folder
699 output_dir: Optional output directory for the .skill file (defaults to current directory)
700
701 Returns:
702 Path to the created .skill file, or None if error
703 """
704 skill_path = Path(skill_path).resolve()
705
706 # Validate skill folder exists
707 if not skill_path.exists():
708 print(f"❌ Error: Skill folder not found: {skill_path}")
709 return None
710
711 if not skill_path.is_dir():
712 print(f"❌ Error: Path is not a directory: {skill_path}")
713 return None
714
715 # Validate SKILL.md exists
716 skill_md = skill_path / "SKILL.md"
717 if not skill_md.exists():
718 print(f"❌ Error: SKILL.md not found in {skill_path}")
719 return None
720
721 # Run validation before packaging
722 print("🔍 Validating skill...")
723 valid, message = validate_skill(skill_path)
724 if not valid:
725 print(f"❌ Validation failed: {message}")
726 print(" Please fix the validation errors before packaging.")
727 return None
728 print(f"✅ {message}\n")
729
730 # Determine output location
731 skill_name = skill_path.name
732 if output_dir:
733 output_path = Path(output_dir).resolve()
734 output_path.mkdir(parents=True, exist_ok=True)
735 else:
736 output_path = Path.cwd()
737
738 skill_filename = output_path / f"{skill_name}.skill"
739
740 # Create the .skill file (zip format)
741 try:
742 with zipfile.ZipFile(skill_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
743 # Walk through the skill directory
744 for file_path in skill_path.rglob('*'):
745 if file_path.is_file():
746 # Calculate the relative path within the zip
747 arcname = file_path.relative_to(skill_path.parent)
748 zipf.write(file_path, arcname)
749 print(f" Added: {arcname}")
750
751 print(f"\n✅ Successfully packaged skill to: {skill_filename}")
752 return skill_filename
753
754 except Exception as e:
755 print(f"❌ Error creating .skill file: {e}")
756 return None
757
758
759def main():
760 if len(sys.argv) < 2:
761 print("Usage: python utils/package_skill.py <path/to/skill-folder> [output-directory]")
762 print("\nExample:")
763 print(" python utils/package_skill.py skills/public/my-skill")
764 print(" python utils/package_skill.py skills/public/my-skill ./dist")
765 sys.exit(1)
766
767 skill_path = sys.argv[1]
768 output_dir = sys.argv[2] if len(sys.argv) > 2 else None
769
770 print(f"📦 Packaging skill: {skill_path}")
771 if output_dir:
772 print(f" Output directory: {output_dir}")
773 print()
774
775 result = package_skill(skill_path, output_dir)
776
777 if result:
778 sys.exit(0)
779 else:
780 sys.exit(1)
781
782
783if __name__ == "__main__":
784 main()
785
786```
787
788
789# quick_validate.py
790
791```python
792#!/usr/bin/env python3
793"""
794Quick validation script for skills - minimal version
795"""
796
797import sys
798import os
799import re
800import yaml
801from pathlib import Path
802
803def validate_skill(skill_path):
804 """Basic validation of a skill"""
805 skill_path = Path(skill_path)
806
807 # Check SKILL.md exists
808 skill_md = skill_path / 'SKILL.md'
809 if not skill_md.exists():
810 return False, "SKILL.md not found"
811
812 # Read and validate frontmatter
813 content = skill_md.read_text()
814 if not content.startswith('---'):
815 return False, "No YAML frontmatter found"
816
817 # Extract frontmatter
818 match = re.match(r'^---\n(.*?)\n---', content, re.DOTALL)
819 if not match:
820 return False, "Invalid frontmatter format"
821
822 frontmatter_text = match.group(1)
823
824 # Parse YAML frontmatter
825 try:
826 frontmatter = yaml.safe_load(frontmatter_text)
827 if not isinstance(frontmatter, dict):
828 return False, "Frontmatter must be a YAML dictionary"
829 except yaml.YAMLError as e:
830 return False, f"Invalid YAML in frontmatter: {e}"
831
832 # Define allowed properties
833 ALLOWED_PROPERTIES = {'name', 'description', 'license', 'allowed-tools', 'metadata'}
834
835 # Check for unexpected properties (excluding nested keys under metadata)
836 unexpected_keys = set(frontmatter.keys()) - ALLOWED_PROPERTIES
837 if unexpected_keys:
838 return False, (
839 f"Unexpected key(s) in SKILL.md frontmatter: {', '.join(sorted(unexpected_keys))}. "
840 f"Allowed properties are: {', '.join(sorted(ALLOWED_PROPERTIES))}"
841 )
842
843 # Check required fields
844 if 'name' not in frontmatter:
845 return False, "Missing 'name' in frontmatter"
846 if 'description' not in frontmatter:
847 return False, "Missing 'description' in frontmatter"
848
849 # Extract name for validation
850 name = frontmatter.get('name', '')
851 if not isinstance(name, str):
852 return False, f"Name must be a string, got {type(name).__name__}"
853 name = name.strip()
854 if name:
855 # Check naming convention (hyphen-case: lowercase with hyphens)
856 if not re.match(r'^[a-z0-9-]+$', name):
857 return False, f"Name '{name}' should be hyphen-case (lowercase letters, digits, and hyphens only)"
858 if name.startswith('-') or name.endswith('-') or '--' in name:
859 return False, f"Name '{name}' cannot start/end with hyphen or contain consecutive hyphens"
860 # Check name length (max 64 characters per spec)
861 if len(name) > 64:
862 return False, f"Name is too long ({len(name)} characters). Maximum is 64 characters."
863
864 # Extract and validate description
865 description = frontmatter.get('description', '')
866 if not isinstance(description, str):
867 return False, f"Description must be a string, got {type(description).__name__}"
868 description = description.strip()
869 if description:
870 # Check for angle brackets
871 if '<' in description or '>' in description:
872 return False, "Description cannot contain angle brackets (< or >)"
873 # Check description length (max 1024 characters per spec)
874 if len(description) > 1024:
875 return False, f"Description is too long ({len(description)} characters). Maximum is 1024 characters."
876
877 return True, "Skill is valid!"
878
879if __name__ == "__main__":
880 if len(sys.argv) != 2:
881 print("Usage: python quick_validate.py <skill_directory>")
882 sys.exit(1)
883
884 valid, message = validate_skill(sys.argv[1])
885 print(message)
886 sys.exit(0 if valid else 1)
887```