Back to snippets
claude_skill_creation_guide_with_init_package_validate_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_package_validate_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### Anatomy of a Skill
28
29Every skill consists of a required SKILL.md file and optional bundled resources:
30
31```
32skill-name/
33├── SKILL.md (required)
34│ ├── YAML frontmatter metadata (required)
35│ │ ├── name: (required)
36│ │ └── description: (required)
37│ └── Markdown instructions (required)
38└── Bundled Resources (optional)
39 ├── scripts/ - Executable code (Python/Bash/etc.)
40 ├── references/ - Documentation intended to be loaded into context as needed
41 └── assets/ - Files used in output (templates, icons, fonts, etc.)
42```
43
44#### SKILL.md (required)
45
46**Metadata Quality:** The `name` and `description` in YAML frontmatter determine when Claude will use the skill. Be specific about what the skill does and when to use it. Use the third-person (e.g. "This skill should be used when..." instead of "Use this skill when...").
47
48#### Bundled Resources (optional)
49
50##### Scripts (`scripts/`)
51
52Executable code (Python/Bash/etc.) for tasks that require deterministic reliability or are repeatedly rewritten.
53
54- **When to include**: When the same code is being rewritten repeatedly or deterministic reliability is needed
55- **Example**: `scripts/rotate_pdf.py` for PDF rotation tasks
56- **Benefits**: Token efficient, deterministic, may be executed without loading into context
57- **Note**: Scripts may still need to be read by Claude for patching or environment-specific adjustments
58
59##### References (`references/`)
60
61Documentation and reference material intended to be loaded as needed into context to inform Claude's process and thinking.
62
63- **When to include**: For documentation that Claude should reference while working
64- **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
65- **Use cases**: Database schemas, API documentation, domain knowledge, company policies, detailed workflow guides
66- **Benefits**: Keeps SKILL.md lean, loaded only when Claude determines it's needed
67- **Best practice**: If files are large (>10k words), include grep search patterns in SKILL.md
68- **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.
69
70##### Assets (`assets/`)
71
72Files not intended to be loaded into context, but rather used within the output Claude produces.
73
74- **When to include**: When the skill needs files that will be used in the final output
75- **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
76- **Use cases**: Templates, images, icons, boilerplate code, fonts, sample documents that get copied or modified
77- **Benefits**: Separates output resources from documentation, enables Claude to use files without loading them into context
78
79### Progressive Disclosure Design Principle
80
81Skills use a three-level loading system to manage context efficiently:
82
831. **Metadata (name + description)** - Always in context (~100 words)
842. **SKILL.md body** - When skill triggers (<5k words)
853. **Bundled resources** - As needed by Claude (Unlimited*)
86
87*Unlimited because scripts can be executed without reading into context window.
88
89## Skill Creation Process
90
91To create a skill, follow the "Skill Creation Process" in order, skipping steps only if there is a clear reason why they are not applicable.
92
93### Step 1: Understanding the Skill with Concrete Examples
94
95Skip this step only when the skill's usage patterns are already clearly understood. It remains valuable even when working with an existing skill.
96
97To 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.
98
99For example, when building an image-editor skill, relevant questions include:
100
101- "What functionality should the image-editor skill support? Editing, rotating, anything else?"
102- "Can you give some examples of how this skill would be used?"
103- "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?"
104- "What would a user say that should trigger this skill?"
105
106To 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.
107
108Conclude this step when there is a clear sense of the functionality the skill should support.
109
110### Step 2: Planning the Reusable Skill Contents
111
112To turn concrete examples into an effective skill, analyze each example by:
113
1141. Considering how to execute on the example from scratch
1152. Identifying what scripts, references, and assets would be helpful when executing these workflows repeatedly
116
117Example: When building a `pdf-editor` skill to handle queries like "Help me rotate this PDF," the analysis shows:
118
1191. Rotating a PDF requires re-writing the same code each time
1202. A `scripts/rotate_pdf.py` script would be helpful to store in the skill
121
122Example: 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:
123
1241. Writing a frontend webapp requires the same boilerplate HTML/React each time
1252. An `assets/hello-world/` template containing the boilerplate HTML/React project files would be helpful to store in the skill
126
127Example: When building a `big-query` skill to handle queries like "How many users have logged in today?" the analysis shows:
128
1291. Querying BigQuery requires re-discovering the table schemas and relationships each time
1302. A `references/schema.md` file documenting the table schemas would be helpful to store in the skill
131
132To establish the skill's contents, analyze each concrete example to create a list of the reusable resources to include: scripts, references, and assets.
133
134### Step 3: Initializing the Skill
135
136At this point, it is time to actually create the skill.
137
138Skip this step only if the skill being developed already exists, and iteration or packaging is needed. In this case, continue to the next step.
139
140When 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.
141
142Usage:
143
144```bash
145scripts/init_skill.py <skill-name> --path <output-directory>
146```
147
148The script:
149
150- Creates the skill directory at the specified path
151- Generates a SKILL.md template with proper frontmatter and TODO placeholders
152- Creates example resource directories: `scripts/`, `references/`, and `assets/`
153- Adds example files in each directory that can be customized or deleted
154
155After initialization, customize or remove the generated SKILL.md and example files as needed.
156
157### Step 4: Edit the Skill
158
159When editing the (newly-generated or existing) skill, remember that the skill is being created for another instance of Claude to use. Focus on including 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.
160
161#### Start with Reusable Skill Contents
162
163To 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/`.
164
165Also, delete any example files and directories not needed for the skill. The initialization script creates example files in `scripts/`, `references/`, and `assets/` to demonstrate structure, but most skills won't need all of them.
166
167#### Update SKILL.md
168
169**Writing Style:** Write the entire skill using **imperative/infinitive form** (verb-first instructions), not second person. Use objective, instructional language (e.g., "To accomplish X, do Y" rather than "You should do X" or "If you need to do X"). This maintains consistency and clarity for AI consumption.
170
171To complete SKILL.md, answer the following questions:
172
1731. What is the purpose of the skill, in a few sentences?
1742. When should the skill be used?
1753. In practice, how should Claude use the skill? All reusable skill contents developed above should be referenced so that Claude knows how to use them.
176
177### Step 5: Packaging a Skill
178
179Once the skill is ready, it should be packaged into a distributable zip file that gets shared with the user. The packaging process automatically validates the skill first to ensure it meets all requirements:
180
181```bash
182scripts/package_skill.py <path/to/skill-folder>
183```
184
185Optional output directory specification:
186
187```bash
188scripts/package_skill.py <path/to/skill-folder> ./dist
189```
190
191The packaging script will:
192
1931. **Validate** the skill automatically, checking:
194 - YAML frontmatter format and required fields
195 - Skill naming conventions and directory structure
196 - Description completeness and quality
197 - File organization and resource references
198
1992. **Package** the skill if validation passes, creating a zip file named after the skill (e.g., `my-skill.zip`) that includes all files and maintains the proper directory structure for distribution.
200
201If validation fails, the script will report the errors and exit without creating a package. Fix any validation errors and run the packaging command again.
202
203### Step 6: Iterate
204
205After testing the skill, users may request improvements. Often this happens right after using the skill, with fresh context of how the skill performed.
206
207**Iteration workflow:**
2081. Use the skill on real tasks
2092. Notice struggles or inefficiencies
2103. Identify how SKILL.md or bundled resources should be updated
2114. Implement changes and test again
212
213
214
215# init_skill.py
216
217```python
218#!/usr/bin/env python3
219"""
220Skill Initializer - Creates a new skill from template
221
222Usage:
223 init_skill.py <skill-name> --path <path>
224
225Examples:
226 init_skill.py my-new-skill --path skills/public
227 init_skill.py my-api-helper --path skills/private
228 init_skill.py custom-skill --path /custom/location
229"""
230
231import sys
232from pathlib import Path
233
234
235SKILL_TEMPLATE = """---
236name: {skill_name}
237description: [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.]
238---
239
240# {skill_title}
241
242## Overview
243
244[TODO: 1-2 sentences explaining what this skill enables]
245
246## Structuring This Skill
247
248[TODO: Choose the structure that best fits this skill's purpose. Common patterns:
249
250**1. Workflow-Based** (best for sequential processes)
251- Works well when there are clear step-by-step procedures
252- Example: DOCX skill with "Workflow Decision Tree" → "Reading" → "Creating" → "Editing"
253- Structure: ## Overview → ## Workflow Decision Tree → ## Step 1 → ## Step 2...
254
255**2. Task-Based** (best for tool collections)
256- Works well when the skill offers different operations/capabilities
257- Example: PDF skill with "Quick Start" → "Merge PDFs" → "Split PDFs" → "Extract Text"
258- Structure: ## Overview → ## Quick Start → ## Task Category 1 → ## Task Category 2...
259
260**3. Reference/Guidelines** (best for standards or specifications)
261- Works well for brand guidelines, coding standards, or requirements
262- Example: Brand styling with "Brand Guidelines" → "Colors" → "Typography" → "Features"
263- Structure: ## Overview → ## Guidelines → ## Specifications → ## Usage...
264
265**4. Capabilities-Based** (best for integrated systems)
266- Works well when the skill provides multiple interrelated features
267- Example: Product Management with "Core Capabilities" → numbered capability list
268- Structure: ## Overview → ## Core Capabilities → ### 1. Feature → ### 2. Feature...
269
270Patterns can be mixed and matched as needed. Most skills combine patterns (e.g., start with task-based, add workflow for complex operations).
271
272Delete this entire "Structuring This Skill" section when done - it's just guidance.]
273
274## [TODO: Replace with the first main section based on chosen structure]
275
276[TODO: Add content here. See examples in existing skills:
277- Code samples for technical skills
278- Decision trees for complex workflows
279- Concrete examples with realistic user requests
280- References to scripts/templates/references as needed]
281
282## Resources
283
284This skill includes example resource directories that demonstrate how to organize different types of bundled resources:
285
286### scripts/
287Executable code (Python/Bash/etc.) that can be run directly to perform specific operations.
288
289**Examples from other skills:**
290- PDF skill: `fill_fillable_fields.py`, `extract_form_field_info.py` - utilities for PDF manipulation
291- DOCX skill: `document.py`, `utilities.py` - Python modules for document processing
292
293**Appropriate for:** Python scripts, shell scripts, or any executable code that performs automation, data processing, or specific operations.
294
295**Note:** Scripts may be executed without loading into context, but can still be read by Claude for patching or environment adjustments.
296
297### references/
298Documentation and reference material intended to be loaded into context to inform Claude's process and thinking.
299
300**Examples from other skills:**
301- Product management: `communication.md`, `context_building.md` - detailed workflow guides
302- BigQuery: API reference documentation and query examples
303- Finance: Schema documentation, company policies
304
305**Appropriate for:** In-depth documentation, API references, database schemas, comprehensive guides, or any detailed information that Claude should reference while working.
306
307### assets/
308Files not intended to be loaded into context, but rather used within the output Claude produces.
309
310**Examples from other skills:**
311- Brand styling: PowerPoint template files (.pptx), logo files
312- Frontend builder: HTML/React boilerplate project directories
313- Typography: Font files (.ttf, .woff2)
314
315**Appropriate for:** Templates, boilerplate code, document templates, images, icons, fonts, or any files meant to be copied or used in the final output.
316
317---
318
319**Any unneeded directories can be deleted.** Not every skill requires all three types of resources.
320"""
321
322EXAMPLE_SCRIPT = '''#!/usr/bin/env python3
323"""
324Example helper script for {skill_name}
325
326This is a placeholder script that can be executed directly.
327Replace with actual implementation or delete if not needed.
328
329Example real scripts from other skills:
330- pdf/scripts/fill_fillable_fields.py - Fills PDF form fields
331- pdf/scripts/convert_pdf_to_images.py - Converts PDF pages to images
332"""
333
334def main():
335 print("This is an example script for {skill_name}")
336 # TODO: Add actual script logic here
337 # This could be data processing, file conversion, API calls, etc.
338
339if __name__ == "__main__":
340 main()
341'''
342
343EXAMPLE_REFERENCE = """# Reference Documentation for {skill_title}
344
345This is a placeholder for detailed reference documentation.
346Replace with actual reference content or delete if not needed.
347
348Example real reference docs from other skills:
349- product-management/references/communication.md - Comprehensive guide for status updates
350- product-management/references/context_building.md - Deep-dive on gathering context
351- bigquery/references/ - API references and query examples
352
353## When Reference Docs Are Useful
354
355Reference docs are ideal for:
356- Comprehensive API documentation
357- Detailed workflow guides
358- Complex multi-step processes
359- Information too lengthy for main SKILL.md
360- Content that's only needed for specific use cases
361
362## Structure Suggestions
363
364### API Reference Example
365- Overview
366- Authentication
367- Endpoints with examples
368- Error codes
369- Rate limits
370
371### Workflow Guide Example
372- Prerequisites
373- Step-by-step instructions
374- Common patterns
375- Troubleshooting
376- Best practices
377"""
378
379EXAMPLE_ASSET = """# Example Asset File
380
381This placeholder represents where asset files would be stored.
382Replace with actual asset files (templates, images, fonts, etc.) or delete if not needed.
383
384Asset files are NOT intended to be loaded into context, but rather used within
385the output Claude produces.
386
387Example asset files from other skills:
388- Brand guidelines: logo.png, slides_template.pptx
389- Frontend builder: hello-world/ directory with HTML/React boilerplate
390- Typography: custom-font.ttf, font-family.woff2
391- Data: sample_data.csv, test_dataset.json
392
393## Common Asset Types
394
395- Templates: .pptx, .docx, boilerplate directories
396- Images: .png, .jpg, .svg, .gif
397- Fonts: .ttf, .otf, .woff, .woff2
398- Boilerplate code: Project directories, starter files
399- Icons: .ico, .svg
400- Data files: .csv, .json, .xml, .yaml
401
402Note: This is a text placeholder. Actual assets can be any file type.
403"""
404
405
406def title_case_skill_name(skill_name):
407 """Convert hyphenated skill name to Title Case for display."""
408 return ' '.join(word.capitalize() for word in skill_name.split('-'))
409
410
411def init_skill(skill_name, path):
412 """
413 Initialize a new skill directory with template SKILL.md.
414
415 Args:
416 skill_name: Name of the skill
417 path: Path where the skill directory should be created
418
419 Returns:
420 Path to created skill directory, or None if error
421 """
422 # Determine skill directory path
423 skill_dir = Path(path).resolve() / skill_name
424
425 # Check if directory already exists
426 if skill_dir.exists():
427 print(f"❌ Error: Skill directory already exists: {skill_dir}")
428 return None
429
430 # Create skill directory
431 try:
432 skill_dir.mkdir(parents=True, exist_ok=False)
433 print(f"✅ Created skill directory: {skill_dir}")
434 except Exception as e:
435 print(f"❌ Error creating directory: {e}")
436 return None
437
438 # Create SKILL.md from template
439 skill_title = title_case_skill_name(skill_name)
440 skill_content = SKILL_TEMPLATE.format(
441 skill_name=skill_name,
442 skill_title=skill_title
443 )
444
445 skill_md_path = skill_dir / 'SKILL.md'
446 try:
447 skill_md_path.write_text(skill_content)
448 print("✅ Created SKILL.md")
449 except Exception as e:
450 print(f"❌ Error creating SKILL.md: {e}")
451 return None
452
453 # Create resource directories with example files
454 try:
455 # Create scripts/ directory with example script
456 scripts_dir = skill_dir / 'scripts'
457 scripts_dir.mkdir(exist_ok=True)
458 example_script = scripts_dir / 'example.py'
459 example_script.write_text(EXAMPLE_SCRIPT.format(skill_name=skill_name))
460 example_script.chmod(0o755)
461 print("✅ Created scripts/example.py")
462
463 # Create references/ directory with example reference doc
464 references_dir = skill_dir / 'references'
465 references_dir.mkdir(exist_ok=True)
466 example_reference = references_dir / 'api_reference.md'
467 example_reference.write_text(EXAMPLE_REFERENCE.format(skill_title=skill_title))
468 print("✅ Created references/api_reference.md")
469
470 # Create assets/ directory with example asset placeholder
471 assets_dir = skill_dir / 'assets'
472 assets_dir.mkdir(exist_ok=True)
473 example_asset = assets_dir / 'example_asset.txt'
474 example_asset.write_text(EXAMPLE_ASSET)
475 print("✅ Created assets/example_asset.txt")
476 except Exception as e:
477 print(f"❌ Error creating resource directories: {e}")
478 return None
479
480 # Print next steps
481 print(f"\n✅ Skill '{skill_name}' initialized successfully at {skill_dir}")
482 print("\nNext steps:")
483 print("1. Edit SKILL.md to complete the TODO items and update the description")
484 print("2. Customize or delete the example files in scripts/, references/, and assets/")
485 print("3. Run the validator when ready to check the skill structure")
486
487 return skill_dir
488
489
490def main():
491 if len(sys.argv) < 4 or sys.argv[2] != '--path':
492 print("Usage: init_skill.py <skill-name> --path <path>")
493 print("\nSkill name requirements:")
494 print(" - Hyphen-case identifier (e.g., 'data-analyzer')")
495 print(" - Lowercase letters, digits, and hyphens only")
496 print(" - Max 40 characters")
497 print(" - Must match directory name exactly")
498 print("\nExamples:")
499 print(" init_skill.py my-new-skill --path skills/public")
500 print(" init_skill.py my-api-helper --path skills/private")
501 print(" init_skill.py custom-skill --path /custom/location")
502 sys.exit(1)
503
504 skill_name = sys.argv[1]
505 path = sys.argv[3]
506
507 print(f"🚀 Initializing skill: {skill_name}")
508 print(f" Location: {path}")
509 print()
510
511 result = init_skill(skill_name, path)
512
513 if result:
514 sys.exit(0)
515 else:
516 sys.exit(1)
517
518
519if __name__ == "__main__":
520 main()
521
522```
523
524
525# package_skill.py
526
527```python
528#!/usr/bin/env python3
529"""
530Skill Packager - Creates a distributable zip file of a skill folder
531
532Usage:
533 python utils/package_skill.py <path/to/skill-folder> [output-directory]
534
535Example:
536 python utils/package_skill.py skills/public/my-skill
537 python utils/package_skill.py skills/public/my-skill ./dist
538"""
539
540import sys
541import zipfile
542from pathlib import Path
543from quick_validate import validate_skill
544
545
546def package_skill(skill_path, output_dir=None):
547 """
548 Package a skill folder into a zip file.
549
550 Args:
551 skill_path: Path to the skill folder
552 output_dir: Optional output directory for the zip file (defaults to current directory)
553
554 Returns:
555 Path to the created zip file, or None if error
556 """
557 skill_path = Path(skill_path).resolve()
558
559 # Validate skill folder exists
560 if not skill_path.exists():
561 print(f"❌ Error: Skill folder not found: {skill_path}")
562 return None
563
564 if not skill_path.is_dir():
565 print(f"❌ Error: Path is not a directory: {skill_path}")
566 return None
567
568 # Validate SKILL.md exists
569 skill_md = skill_path / "SKILL.md"
570 if not skill_md.exists():
571 print(f"❌ Error: SKILL.md not found in {skill_path}")
572 return None
573
574 # Run validation before packaging
575 print("🔍 Validating skill...")
576 valid, message = validate_skill(skill_path)
577 if not valid:
578 print(f"❌ Validation failed: {message}")
579 print(" Please fix the validation errors before packaging.")
580 return None
581 print(f"✅ {message}\n")
582
583 # Determine output location
584 skill_name = skill_path.name
585 if output_dir:
586 output_path = Path(output_dir).resolve()
587 output_path.mkdir(parents=True, exist_ok=True)
588 else:
589 output_path = Path.cwd()
590
591 zip_filename = output_path / f"{skill_name}.zip"
592
593 # Create the zip file
594 try:
595 with zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
596 # Walk through the skill directory
597 for file_path in skill_path.rglob('*'):
598 if file_path.is_file():
599 # Calculate the relative path within the zip
600 arcname = file_path.relative_to(skill_path.parent)
601 zipf.write(file_path, arcname)
602 print(f" Added: {arcname}")
603
604 print(f"\n✅ Successfully packaged skill to: {zip_filename}")
605 return zip_filename
606
607 except Exception as e:
608 print(f"❌ Error creating zip file: {e}")
609 return None
610
611
612def main():
613 if len(sys.argv) < 2:
614 print("Usage: python utils/package_skill.py <path/to/skill-folder> [output-directory]")
615 print("\nExample:")
616 print(" python utils/package_skill.py skills/public/my-skill")
617 print(" python utils/package_skill.py skills/public/my-skill ./dist")
618 sys.exit(1)
619
620 skill_path = sys.argv[1]
621 output_dir = sys.argv[2] if len(sys.argv) > 2 else None
622
623 print(f"📦 Packaging skill: {skill_path}")
624 if output_dir:
625 print(f" Output directory: {output_dir}")
626 print()
627
628 result = package_skill(skill_path, output_dir)
629
630 if result:
631 sys.exit(0)
632 else:
633 sys.exit(1)
634
635
636if __name__ == "__main__":
637 main()
638
639```
640
641
642# quick_validate.py
643
644```python
645#!/usr/bin/env python3
646"""
647Quick validation script for skills - minimal version
648"""
649
650import sys
651import os
652import re
653from pathlib import Path
654
655def validate_skill(skill_path):
656 """Basic validation of a skill"""
657 skill_path = Path(skill_path)
658
659 # Check SKILL.md exists
660 skill_md = skill_path / 'SKILL.md'
661 if not skill_md.exists():
662 return False, "SKILL.md not found"
663
664 # Read and validate frontmatter
665 content = skill_md.read_text()
666 if not content.startswith('---'):
667 return False, "No YAML frontmatter found"
668
669 # Extract frontmatter
670 match = re.match(r'^---\n(.*?)\n---', content, re.DOTALL)
671 if not match:
672 return False, "Invalid frontmatter format"
673
674 frontmatter = match.group(1)
675
676 # Check required fields
677 if 'name:' not in frontmatter:
678 return False, "Missing 'name' in frontmatter"
679 if 'description:' not in frontmatter:
680 return False, "Missing 'description' in frontmatter"
681
682 # Extract name for validation
683 name_match = re.search(r'name:\s*(.+)', frontmatter)
684 if name_match:
685 name = name_match.group(1).strip()
686 # Check naming convention (hyphen-case: lowercase with hyphens)
687 if not re.match(r'^[a-z0-9-]+$', name):
688 return False, f"Name '{name}' should be hyphen-case (lowercase letters, digits, and hyphens only)"
689 if name.startswith('-') or name.endswith('-') or '--' in name:
690 return False, f"Name '{name}' cannot start/end with hyphen or contain consecutive hyphens"
691
692 # Extract and validate description
693 desc_match = re.search(r'description:\s*(.+)', frontmatter)
694 if desc_match:
695 description = desc_match.group(1).strip()
696 # Check for angle brackets
697 if '<' in description or '>' in description:
698 return False, "Description cannot contain angle brackets (< or >)"
699
700 return True, "Skill is valid!"
701
702if __name__ == "__main__":
703 if len(sys.argv) != 2:
704 print("Usage: python quick_validate.py <skill_directory>")
705 sys.exit(1)
706
707 valid, message = validate_skill(sys.argv[1])
708 print(message)
709 sys.exit(0 if valid else 1)
710```