#!/usr/bin/env python3 """ Go Script Generator for Claude Code Skills Analyzes operation requirements and generates efficient Go scripts for deterministic operations that don't require agent interaction. Usage: generate_go_script.py --name --description \ --input --output \ --logic --skill-path Example: generate_go_script.py \ --name pdf-to-images \ --description "Convert PDF pages to PNG images" \ --input "PDF file path" \ --output "Directory of PNG files" \ --logic "Extract each page as separate image at 300 DPI" \ --skill-path ./my-skill """ import argparse import sys from pathlib import Path from textwrap import dedent # Go script template with best practices GO_SCRIPT_TEMPLATE = '''package main import ( "flag" "fmt" "log" "os" {extra_imports} ) // {description} // Generated by meta-skill-generator for Claude Code skills var ( verbose = flag.Bool("verbose", false, "Enable verbose logging") help = flag.Bool("help", false, "Show this help message") ) func main() {{ flag.Usage = usage flag.Parse() if *help {{ usage() os.Exit(0) }} if *verbose {{ log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) }} else {{ log.SetFlags(0) }} // Validate command line arguments if err := validateArgs(); err != nil {{ fmt.Fprintf(os.Stderr, "Error: %v\\n", err) usage() os.Exit(2) }} // Execute main logic if err := run(); err != nil {{ fmt.Fprintf(os.Stderr, "Error: %v\\n", err) os.Exit(1) }} }} func usage() {{ fmt.Fprintf(os.Stderr, "Usage: %s [options] {usage_args}\\n", os.Args[0]) fmt.Fprintf(os.Stderr, "\\n{description}\\n\\n") fmt.Fprintf(os.Stderr, "Input: {input_desc}\\n") fmt.Fprintf(os.Stderr, "Output: {output_desc}\\n\\n") fmt.Fprintf(os.Stderr, "Options:\\n") flag.PrintDefaults() }} func validateArgs() error {{ {validation_logic} return nil }} func run() error {{ if *verbose {{ log.Println("Starting {name}...") }} {run_logic} if *verbose {{ log.Println("Completed successfully") }} return nil }} {helper_functions} ''' def infer_imports(logic_desc): """Infer required Go imports from operation description.""" imports = [] logic_lower = logic_desc.lower() if any(word in logic_lower for word in ['file', 'directory', 'path', 'copy', 'move']): imports.append('"io"') imports.append('"path/filepath"') if any(word in logic_lower for word in ['json', 'parse']): imports.append('"encoding/json"') if any(word in logic_lower for word in ['csv', 'comma']): imports.append('"encoding/csv"') if any(word in logic_lower for word in ['http', 'api', 'request']): imports.append('"net/http"') if any(word in logic_lower for word in ['string', 'text', 'replace']): imports.append('"strings"') if any(word in logic_lower for word in ['regex', 'pattern', 'match']): imports.append('"regexp"') if any(word in logic_lower for word in ['time', 'date', 'duration']): imports.append('"time"') if any(word in logic_lower for word in ['concurrent', 'parallel', 'goroutine']): imports.append('"sync"') if any(word in logic_lower for word in ['buffer', 'bytes']): imports.append('"bytes"') return imports def generate_validation_logic(input_desc): """Generate input validation logic.""" validations = [] if 'file' in input_desc.lower(): validations.append(dedent(''' if flag.NArg() < 1 { return fmt.Errorf("input file required") } inputFile := flag.Arg(0) if _, err := os.Stat(inputFile); os.IsNotExist(err) { return fmt.Errorf("input file does not exist: %s", inputFile) } ''').strip()) if 'directory' in input_desc.lower(): validations.append(dedent(''' if flag.NArg() < 1 { return fmt.Errorf("input directory required") } inputDir := flag.Arg(0) if info, err := os.Stat(inputDir); os.IsNotExist(err) || !info.IsDir() { return fmt.Errorf("input directory does not exist: %s", inputDir) } ''').strip()) return '\n\t'.join(validations) if validations else '// No validation needed' def generate_run_logic(logic_desc, input_desc, output_desc): """Generate main execution logic with placeholder.""" logic_lower = logic_desc.lower() # Start with input handling logic = [] if 'file' in input_desc.lower(): logic.append('inputFile := flag.Arg(0)') logic.append('') if 'directory' in input_desc.lower(): logic.append('inputDir := flag.Arg(0)') logic.append('') # Add operation-specific logic template logic.append('// TODO: Implement the following logic:') logic.append(f'// {logic_desc}') logic.append('') if any(word in logic_lower for word in ['convert', 'transform', 'process']): logic.append(dedent(''' // 1. Read input // 2. Process/transform data // 3. Write output ''').strip()) if 'parallel' in logic_lower or 'concurrent' in logic_lower: logic.append(dedent(''' // Consider using goroutines for parallel processing: // var wg sync.WaitGroup // for _, item := range items { // wg.Add(1) // go func(item Item) { // defer wg.Done() // // Process item // }(item) // } // wg.Wait() ''').strip()) # Add output handling if 'stdout' in output_desc.lower(): logic.append('') logic.append('// Write results to stdout') logic.append('fmt.Println(result)') elif 'file' in output_desc.lower(): logic.append('') logic.append('outputFile := "output.txt" // TODO: Make configurable') logic.append('if err := os.WriteFile(outputFile, []byte(result), 0644); err != nil {') logic.append(' return fmt.Errorf("failed to write output: %w", err)') logic.append('}') logic.append('') logic.append('return nil') return '\n\t'.join(logic) def generate_helper_functions(logic_desc): """Generate helper function templates.""" helpers = [] logic_lower = logic_desc.lower() if 'progress' in logic_lower or 'batch' in logic_lower: helpers.append(dedent(''' func showProgress(current, total int) { if total > 0 { percent := float64(current) / float64(total) * 100 fmt.Fprintf(os.Stderr, "\\rProgress: %.1f%% (%d/%d)", percent, current, total) if current == total { fmt.Fprintln(os.Stderr) } } } ''').strip()) if 'validate' in logic_lower or 'check' in logic_lower: helpers.append(dedent(''' func validateInput(data interface{}) error { // TODO: Implement validation logic return nil } ''').strip()) return '\n\n'.join(helpers) if helpers else '// No helper functions needed' def determine_usage_args(input_desc): """Determine usage string from input description.""" if 'file' in input_desc.lower(): return '' elif 'directory' in input_desc.lower(): return '' else: return '' def generate_go_script(name, description, input_desc, output_desc, logic_desc, skill_path): """Generate a complete Go script.""" # Infer what imports we need extra_imports = '\n\t'.join(infer_imports(logic_desc)) # Generate different sections validation_logic = generate_validation_logic(input_desc) run_logic = generate_run_logic(logic_desc, input_desc, output_desc) helper_functions = generate_helper_functions(logic_desc) usage_args = determine_usage_args(input_desc) # Fill in template script_content = GO_SCRIPT_TEMPLATE.format( description=description, name=name, input_desc=input_desc, output_desc=output_desc, usage_args=usage_args, extra_imports=extra_imports, validation_logic=validation_logic, run_logic=run_logic, helper_functions=helper_functions ) return script_content def create_build_script(skill_path, script_name): """Create a build script to compile the Go binary.""" build_script = f'''#!/bin/bash # Build script for {script_name} set -e SCRIPT_DIR="$(cd "$(dirname "${{BASH_SOURCE[0]}}")" && pwd)" BIN_DIR="$SCRIPT_DIR/bin" mkdir -p "$BIN_DIR" echo "Building {script_name}..." cd "$SCRIPT_DIR" go build -o "$BIN_DIR/{script_name}" {script_name}.go echo "✅ Built: $BIN_DIR/{script_name}" echo "Run with: $BIN_DIR/{script_name} --help" ''' build_path = skill_path / 'scripts' / f'build_{script_name}.sh' build_path.write_text(build_script) build_path.chmod(0o755) return build_path def update_skill_md(skill_path, script_name, description, input_desc, output_desc): """Add usage information to SKILL.md.""" skill_md = skill_path / 'SKILL.md' if not skill_md.exists(): print(f"⚠️ Warning: SKILL.md not found at {skill_md}") return content = skill_md.read_text() # Add script documentation if not already present script_section = f''' ### {script_name} {description} **Input:** {input_desc} **Output:** {output_desc} **Usage:** ```bash scripts/bin/{script_name} [options] scripts/bin/{script_name} --help # For detailed options ``` **Example:** ```bash scripts/bin/{script_name} input.txt ``` ''' if script_name not in content: # Try to add after "## Resources" or at the end if '## Resources' in content: content = content.replace('## Resources', script_section + '\n## Resources') else: content += '\n' + script_section skill_md.write_text(content) print(f"✅ Updated SKILL.md with {script_name} documentation") else: print(f"ℹ️ {script_name} already documented in SKILL.md") def main(): parser = argparse.ArgumentParser( description='Generate Go scripts for Claude Code skills', formatter_class=argparse.RawDescriptionHelpFormatter, epilog=dedent(''' Examples: generate_go_script.py \\ --name pdf-extract-text \\ --description "Extract text from PDF files" \\ --input "PDF file path" \\ --output "Text content to stdout" \\ --logic "Parse PDF and extract all text content" \\ --skill-path ./my-pdf-skill generate_go_script.py \\ --name csv-to-json \\ --description "Convert CSV files to JSON" \\ --input "CSV file path" \\ --output "JSON file" \\ --logic "Parse CSV rows and convert to JSON array" \\ --skill-path ./data-tools ''') ) parser.add_argument('--name', required=True, help='Name of the script (e.g., pdf-to-images)') parser.add_argument('--description', required=True, help='What the script does') parser.add_argument('--input', required=True, help='Description of input') parser.add_argument('--output', required=True, help='Description of output') parser.add_argument('--logic', required=True, help='Description of the transformation logic') parser.add_argument('--skill-path', required=True, help='Path to the skill directory') parser.add_argument('--no-build', action='store_true', help='Skip creating build script') parser.add_argument('--no-update-md', action='store_true', help='Skip updating SKILL.md') args = parser.parse_args() # Validate skill path skill_path = Path(args.skill_path).resolve() if not skill_path.exists(): print(f"❌ Error: Skill path does not exist: {skill_path}") sys.exit(1) # Create scripts directory if needed scripts_dir = skill_path / 'scripts' scripts_dir.mkdir(exist_ok=True) # Generate Go script print(f"🚀 Generating Go script: {args.name}") script_content = generate_go_script( args.name, args.description, args.input, args.output, args.logic, skill_path ) # Write Go file go_file = scripts_dir / f'{args.name}.go' go_file.write_text(script_content) print(f"✅ Created: {go_file}") # Create build script if not args.no_build: build_script = create_build_script(skill_path, args.name) print(f"✅ Created build script: {build_script}") print(f" Run: ./scripts/build_{args.name}.sh") # Update SKILL.md if not args.no_update_md: update_skill_md(skill_path, args.name, args.description, args.input, args.output) print(f"\n✅ Go script '{args.name}' generated successfully") print("\nNext steps:") print(f"1. Review and customize: {go_file}") print(f"2. Build the binary: ./scripts/build_{args.name}.sh") print(f"3. Test: ./scripts/bin/{args.name} --help") if __name__ == '__main__': main()