init_skill.py raw

   1  #!/usr/bin/env python3
   2  """
   3  Skill Initializer - Creates a new skill from template
   4  
   5  Usage:
   6      init_skill.py <skill-name> --path <path>
   7  
   8  Examples:
   9      init_skill.py my-new-skill --path skills/public
  10      init_skill.py my-api-helper --path skills/private
  11      init_skill.py custom-skill --path /custom/location
  12  """
  13  
  14  import sys
  15  from pathlib import Path
  16  
  17  
  18  SKILL_TEMPLATE = """---
  19  name: {skill_name}
  20  description: [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.]
  21  ---
  22  
  23  # {skill_title}
  24  
  25  ## Overview
  26  
  27  [TODO: 1-2 sentences explaining what this skill enables]
  28  
  29  ## Structuring This Skill
  30  
  31  [TODO: Choose the structure that best fits this skill's purpose. Common patterns:
  32  
  33  **1. Workflow-Based** (best for sequential processes)
  34  - Works well when there are clear step-by-step procedures
  35  - Example: DOCX skill with "Workflow Decision Tree" → "Reading" → "Creating" → "Editing"
  36  - Structure: ## Overview → ## Workflow Decision Tree → ## Step 1 → ## Step 2...
  37  
  38  **2. Task-Based** (best for tool collections)
  39  - Works well when the skill offers different operations/capabilities
  40  - Example: PDF skill with "Quick Start" → "Merge PDFs" → "Split PDFs" → "Extract Text"
  41  - Structure: ## Overview → ## Quick Start → ## Task Category 1 → ## Task Category 2...
  42  
  43  **3. Reference/Guidelines** (best for standards or specifications)
  44  - Works well for brand guidelines, coding standards, or requirements
  45  - Example: Brand styling with "Brand Guidelines" → "Colors" → "Typography" → "Features"
  46  - Structure: ## Overview → ## Guidelines → ## Specifications → ## Usage...
  47  
  48  **4. Capabilities-Based** (best for integrated systems)
  49  - Works well when the skill provides multiple interrelated features
  50  - Example: Product Management with "Core Capabilities" → numbered capability list
  51  - Structure: ## Overview → ## Core Capabilities → ### 1. Feature → ### 2. Feature...
  52  
  53  Patterns can be mixed and matched as needed. Most skills combine patterns (e.g., start with task-based, add workflow for complex operations).
  54  
  55  Delete this entire "Structuring This Skill" section when done - it's just guidance.]
  56  
  57  ## [TODO: Replace with the first main section based on chosen structure]
  58  
  59  [TODO: Add content here. See examples in existing skills:
  60  - Code samples for technical skills
  61  - Decision trees for complex workflows
  62  - Concrete examples with realistic user requests
  63  - References to scripts/templates/references as needed]
  64  
  65  ## Resources
  66  
  67  This skill includes example resource directories that demonstrate how to organize different types of bundled resources:
  68  
  69  ### scripts/
  70  Executable code (Python/Bash/etc.) that can be run directly to perform specific operations.
  71  
  72  **Examples from other skills:**
  73  - PDF skill: `fill_fillable_fields.py`, `extract_form_field_info.py` - utilities for PDF manipulation
  74  - DOCX skill: `document.py`, `utilities.py` - Python modules for document processing
  75  
  76  **Appropriate for:** Python scripts, shell scripts, or any executable code that performs automation, data processing, or specific operations.
  77  
  78  **Note:** Scripts may be executed without loading into context, but can still be read by Claude for patching or environment adjustments.
  79  
  80  ### references/
  81  Documentation and reference material intended to be loaded into context to inform Claude's process and thinking.
  82  
  83  **Examples from other skills:**
  84  - Product management: `communication.md`, `context_building.md` - detailed workflow guides
  85  - BigQuery: API reference documentation and query examples
  86  - Finance: Schema documentation, company policies
  87  
  88  **Appropriate for:** In-depth documentation, API references, database schemas, comprehensive guides, or any detailed information that Claude should reference while working.
  89  
  90  ### assets/
  91  Files not intended to be loaded into context, but rather used within the output Claude produces.
  92  
  93  **Examples from other skills:**
  94  - Brand styling: PowerPoint template files (.pptx), logo files
  95  - Frontend builder: HTML/React boilerplate project directories
  96  - Typography: Font files (.ttf, .woff2)
  97  
  98  **Appropriate for:** Templates, boilerplate code, document templates, images, icons, fonts, or any files meant to be copied or used in the final output.
  99  
 100  ---
 101  
 102  **Any unneeded directories can be deleted.** Not every skill requires all three types of resources.
 103  """
 104  
 105  EXAMPLE_SCRIPT = '''#!/usr/bin/env python3
 106  """
 107  Example helper script for {skill_name}
 108  
 109  This is a placeholder script that can be executed directly.
 110  Replace with actual implementation or delete if not needed.
 111  
 112  Example real scripts from other skills:
 113  - pdf/scripts/fill_fillable_fields.py - Fills PDF form fields
 114  - pdf/scripts/convert_pdf_to_images.py - Converts PDF pages to images
 115  """
 116  
 117  def main():
 118      print("This is an example script for {skill_name}")
 119      # TODO: Add actual script logic here
 120      # This could be data processing, file conversion, API calls, etc.
 121  
 122  if __name__ == "__main__":
 123      main()
 124  '''
 125  
 126  EXAMPLE_REFERENCE = """# Reference Documentation for {skill_title}
 127  
 128  This is a placeholder for detailed reference documentation.
 129  Replace with actual reference content or delete if not needed.
 130  
 131  Example real reference docs from other skills:
 132  - product-management/references/communication.md - Comprehensive guide for status updates
 133  - product-management/references/context_building.md - Deep-dive on gathering context
 134  - bigquery/references/ - API references and query examples
 135  
 136  ## When Reference Docs Are Useful
 137  
 138  Reference docs are ideal for:
 139  - Comprehensive API documentation
 140  - Detailed workflow guides
 141  - Complex multi-step processes
 142  - Information too lengthy for main SKILL.md
 143  - Content that's only needed for specific use cases
 144  
 145  ## Structure Suggestions
 146  
 147  ### API Reference Example
 148  - Overview
 149  - Authentication
 150  - Endpoints with examples
 151  - Error codes
 152  - Rate limits
 153  
 154  ### Workflow Guide Example
 155  - Prerequisites
 156  - Step-by-step instructions
 157  - Common patterns
 158  - Troubleshooting
 159  - Best practices
 160  """
 161  
 162  EXAMPLE_ASSET = """# Example Asset File
 163  
 164  This placeholder represents where asset files would be stored.
 165  Replace with actual asset files (templates, images, fonts, etc.) or delete if not needed.
 166  
 167  Asset files are NOT intended to be loaded into context, but rather used within
 168  the output Claude produces.
 169  
 170  Example asset files from other skills:
 171  - Brand guidelines: logo.png, slides_template.pptx
 172  - Frontend builder: hello-world/ directory with HTML/React boilerplate
 173  - Typography: custom-font.ttf, font-family.woff2
 174  - Data: sample_data.csv, test_dataset.json
 175  
 176  ## Common Asset Types
 177  
 178  - Templates: .pptx, .docx, boilerplate directories
 179  - Images: .png, .jpg, .svg, .gif
 180  - Fonts: .ttf, .otf, .woff, .woff2
 181  - Boilerplate code: Project directories, starter files
 182  - Icons: .ico, .svg
 183  - Data files: .csv, .json, .xml, .yaml
 184  
 185  Note: This is a text placeholder. Actual assets can be any file type.
 186  """
 187  
 188  
 189  def title_case_skill_name(skill_name):
 190      """Convert hyphenated skill name to Title Case for display."""
 191      return ' '.join(word.capitalize() for word in skill_name.split('-'))
 192  
 193  
 194  def init_skill(skill_name, path):
 195      """
 196      Initialize a new skill directory with template SKILL.md.
 197  
 198      Args:
 199          skill_name: Name of the skill
 200          path: Path where the skill directory should be created
 201  
 202      Returns:
 203          Path to created skill directory, or None if error
 204      """
 205      # Determine skill directory path
 206      skill_dir = Path(path).resolve() / skill_name
 207  
 208      # Check if directory already exists
 209      if skill_dir.exists():
 210          print(f"❌ Error: Skill directory already exists: {skill_dir}")
 211          return None
 212  
 213      # Create skill directory
 214      try:
 215          skill_dir.mkdir(parents=True, exist_ok=False)
 216          print(f"✅ Created skill directory: {skill_dir}")
 217      except Exception as e:
 218          print(f"❌ Error creating directory: {e}")
 219          return None
 220  
 221      # Create SKILL.md from template
 222      skill_title = title_case_skill_name(skill_name)
 223      skill_content = SKILL_TEMPLATE.format(
 224          skill_name=skill_name,
 225          skill_title=skill_title
 226      )
 227  
 228      skill_md_path = skill_dir / 'SKILL.md'
 229      try:
 230          skill_md_path.write_text(skill_content)
 231          print("✅ Created SKILL.md")
 232      except Exception as e:
 233          print(f"❌ Error creating SKILL.md: {e}")
 234          return None
 235  
 236      # Create resource directories with example files
 237      try:
 238          # Create scripts/ directory with example script
 239          scripts_dir = skill_dir / 'scripts'
 240          scripts_dir.mkdir(exist_ok=True)
 241          example_script = scripts_dir / 'example.py'
 242          example_script.write_text(EXAMPLE_SCRIPT.format(skill_name=skill_name))
 243          example_script.chmod(0o755)
 244          print("✅ Created scripts/example.py")
 245  
 246          # Create references/ directory with example reference doc
 247          references_dir = skill_dir / 'references'
 248          references_dir.mkdir(exist_ok=True)
 249          example_reference = references_dir / 'api_reference.md'
 250          example_reference.write_text(EXAMPLE_REFERENCE.format(skill_title=skill_title))
 251          print("✅ Created references/api_reference.md")
 252  
 253          # Create assets/ directory with example asset placeholder
 254          assets_dir = skill_dir / 'assets'
 255          assets_dir.mkdir(exist_ok=True)
 256          example_asset = assets_dir / 'example_asset.txt'
 257          example_asset.write_text(EXAMPLE_ASSET)
 258          print("✅ Created assets/example_asset.txt")
 259      except Exception as e:
 260          print(f"❌ Error creating resource directories: {e}")
 261          return None
 262  
 263      # Print next steps
 264      print(f"\n✅ Skill '{skill_name}' initialized successfully at {skill_dir}")
 265      print("\nNext steps:")
 266      print("1. Edit SKILL.md to complete the TODO items and update the description")
 267      print("2. Customize or delete the example files in scripts/, references/, and assets/")
 268      print("3. Run the validator when ready to check the skill structure")
 269  
 270      return skill_dir
 271  
 272  
 273  def main():
 274      if len(sys.argv) < 4 or sys.argv[2] != '--path':
 275          print("Usage: init_skill.py <skill-name> --path <path>")
 276          print("\nSkill name requirements:")
 277          print("  - Hyphen-case identifier (e.g., 'data-analyzer')")
 278          print("  - Lowercase letters, digits, and hyphens only")
 279          print("  - Max 40 characters")
 280          print("  - Must match directory name exactly")
 281          print("\nExamples:")
 282          print("  init_skill.py my-new-skill --path skills/public")
 283          print("  init_skill.py my-api-helper --path skills/private")
 284          print("  init_skill.py custom-skill --path /custom/location")
 285          sys.exit(1)
 286  
 287      skill_name = sys.argv[1]
 288      path = sys.argv[3]
 289  
 290      print(f"🚀 Initializing skill: {skill_name}")
 291      print(f"   Location: {path}")
 292      print()
 293  
 294      result = init_skill(skill_name, path)
 295  
 296      if result:
 297          sys.exit(0)
 298      else:
 299          sys.exit(1)
 300  
 301  
 302  if __name__ == "__main__":
 303      main()
 304