Recreate source from .skill zip file

This commit is contained in:
Your Name 2026-05-21 10:29:13 +00:00
parent 38722fdcb8
commit c59c59b8ba
11 changed files with 2521 additions and 0 deletions

View File

@ -0,0 +1,278 @@
---
name: meta-skill-generator
description: Creates Claude Code skills with intelligent separation of deterministic operations into Go scripts. Use when users want to create a new skill or improve an existing skill by identifying repetitive code patterns that should be extracted into compiled Go scripts for performance and reliability. Analyzes workflows to determine what requires agent interaction versus what can be pre-compiled into efficient Go binaries.
---
# Meta Skill Generator
## Overview
This skill generates high-quality Claude Code skills with intelligent workflow analysis. It identifies deterministic operations that don't require agent interaction and generates efficient Go scripts for them, while preserving dynamic agent-based workflows for tasks requiring reasoning and adaptation.
## Workflow
Creating a skill follows these steps:
1. **Understanding phase**: Gather concrete examples and use cases
2. **Analysis phase**: Identify deterministic vs dynamic operations
3. **Planning phase**: Design skill structure with appropriate degrees of freedom
4. **Implementation phase**: Generate Go scripts, Python utilities, and SKILL.md
5. **Testing phase**: Validate scripts and skill structure
6. **Packaging phase**: Create distributable .skill file
## Step 1: Understanding the Skill with Concrete Examples
Begin by gathering concrete examples of how the skill will be used. Ask targeted questions:
- What specific tasks should this skill handle?
- Can you provide 3-5 example user requests?
- What would trigger this skill?
- Are there existing workflows or tools this should integrate with?
**Example questions for an image-processing skill:**
- "What image operations do you need? Resizing, format conversion, filtering?"
- "Can you show me an example image and what you'd want to do with it?"
- "How would you phrase a request to use this skill?"
Conclude when you have clear use cases and triggering patterns.
## Step 2: Analyze for Deterministic vs Dynamic Operations
For each concrete example, categorize operations:
**Deterministic operations** (candidates for Go scripts):
- File format conversions (PDF → images, DOCX → text)
- Data transformations with fixed logic (CSV parsing, JSON manipulation)
- Batch operations on multiple files
- Validation checks with clear pass/fail criteria
- Template-based generation with fixed structure
- Mathematical computations
- File system operations (copying, organizing, renaming)
**Dynamic operations** (keep as agent workflows):
- Content analysis requiring understanding (sentiment, summarization)
- Decision-making based on context
- Creative generation (writing, design suggestions)
- Interactive troubleshooting
- Adapting to unexpected inputs
- Multi-step reasoning chains
**Indicators for Go script extraction:**
1. Same code pattern rewritten >3 times
2. Performance-critical operations (large files, many iterations)
3. Binary/low-level data manipulation
4. Zero decision-making required
5. Clear input/output contract
## Step 3: Plan Skill Structure
Design the skill's organization based on complexity:
**Simple skills** (1-3 operations):
- SKILL.md with direct instructions
- 1-3 Go scripts in `scripts/`
- Optional: single reference file
**Medium skills** (4-10 operations):
- SKILL.md with workflow decision tree
- Multiple Go scripts organized by function
- References for detailed documentation
- Optional: assets for templates
**Complex skills** (10+ operations):
- SKILL.md with high-level workflow
- Multiple reference files by category
- Go scripts organized in subdirectories
- Assets for templates and examples
- Consider: Go package with multiple binaries
### Degrees of Freedom
Match specificity to task fragility:
**High freedom** (natural language instructions):
```markdown
Analyze the document and identify key themes, then structure your
findings based on what you discover.
```
**Medium freedom** (parameterized scripts):
```markdown
Run: ./scripts/analyze --format=json --depth=2 input.txt
Interpret the results and determine next steps.
```
**Low freedom** (specific scripts, fixed sequence):
```markdown
1. Run: ./scripts/extract_fields input.pdf > fields.json
2. Run: ./scripts/validate_fields fields.json
3. If validation passes, run: ./scripts/fill_form fields.json template.pdf
```
## Step 4: Implementation
### Initialize the Skill
```bash
python3 /mnt/skills/examples/skill-creator/scripts/init_skill.py <skill-name> --path <output-dir>
```
### Generate Go Scripts
For each deterministic operation identified in Step 2, use `scripts/generate_go_script.py`:
```bash
scripts/generate_go_script.py \
--name <operation-name> \
--description "<what it does>" \
--input "<input description>" \
--output "<output description>" \
--logic "<transformation logic>" \
--skill-path <path/to/skill>
```
**Example:**
```bash
scripts/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, 300 DPI" \
--skill-path ./my-pdf-skill
```
The script will:
1. Generate efficient Go code with proper error handling
2. Include CLI argument parsing
3. Add progress reporting for long operations
4. Create binary in `scripts/bin/`
5. Update SKILL.md with usage instructions
### Python Utilities
For operations requiring Python libraries (data science, ML, complex APIs), create Python scripts instead. Use Go for performance-critical, low-level operations.
### Write SKILL.md
Follow the skill-creator patterns:
**Frontmatter:**
```yaml
---
name: skill-name
description: Comprehensive description including WHAT it does and WHEN to use it. Mention specific triggers: file types, keywords, task patterns.
---
```
**Body structure:**
1. Overview (1-2 sentences)
2. Workflow or Quick Start
3. Detailed sections for each major capability
4. Reference to scripts with clear usage examples
5. Troubleshooting (if applicable)
**Writing style:**
- Imperative/infinitive form ("Extract text" not "Extracts text")
- Concise - every word must justify its token cost
- Examples over explanations
- Reference bundled resources clearly
### Reference Files
Create reference files for:
- API documentation
- Complex workflows (>10 steps)
- Domain knowledge (schemas, specifications)
- Large examples (>100 lines)
Keep SKILL.md lean by moving detailed content to references:
```markdown
## Advanced Features
For form field extraction, see [references/form-fields.md](references/form-fields.md)
For batch processing patterns, see [references/batch-operations.md](references/batch-operations.md)
```
### Assets
Include files to be used in output:
- Templates (.pptx, .docx, .html)
- Images (logos, icons)
- Boilerplate code (starter projects)
- Fonts, stylesheets
## Step 5: Testing
Test each Go script:
```bash
cd scripts/bin
./script-name --help # Verify CLI works
./script-name test-input.txt # Test with real data
./script-name invalid-input # Test error handling
```
Test Python scripts:
```bash
cd scripts
python3 script-name.py test-input
```
Verify SKILL.md:
- All script references are accurate
- Examples run successfully
- No broken links to references/assets
## Step 6: Package the Skill
```bash
python3 /mnt/skills/examples/skill-creator/scripts/package_skill.py <path/to/skill>
```
This automatically validates:
- YAML frontmatter completeness
- Naming conventions
- File organization
- Script executability
Fix any validation errors and repackage.
## Go Script Best Practices
**Performance:**
- Use goroutines for parallel operations
- Stream large files instead of loading into memory
- Buffer I/O operations
**Error handling:**
- Return descriptive error messages
- Use exit codes (0=success, 1=error, 2=invalid input)
- Validate inputs before processing
**CLI design:**
- Support `--help` flag
- Use standard flags package
- Accept input from stdin or file
- Write output to stdout or file
**Logging:**
- Progress indicators for long operations
- Verbose mode for debugging (`--verbose` flag)
- Errors to stderr, output to stdout
## Resources
### scripts/
- `generate_go_script.py`: Generate Go scripts from specifications
- `test_skill_scripts.py`: Automated testing for all scripts
- `init_skill_with_analysis.py`: End-to-end skill creation with workflow analysis
### references/
- `go-patterns.md`: Common Go patterns for skill scripts
- `workflow-analysis.md`: Detailed guide for identifying deterministic operations
- `skill-examples.md`: Real-world examples of well-structured skills
Run `scripts/generate_go_script.py --help` for detailed usage.

View File

@ -0,0 +1,443 @@
# Go Patterns for Skill Scripts
This reference provides battle-tested Go patterns for common operations in Claude Code skills.
## File Processing Patterns
### Reading Files Line by Line
```go
func processFileLineByLine(filename string) error {
file, err := os.Open(filename)
if err != nil {
return fmt.Errorf("failed to open file: %w", err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
lineNum := 0
for scanner.Scan() {
lineNum++
line := scanner.Text()
// Process line
if err := processLine(line); err != nil {
return fmt.Errorf("error on line %d: %w", lineNum, err)
}
}
if err := scanner.Err(); err != nil {
return fmt.Errorf("scanner error: %w", err)
}
return nil
}
```
### Streaming Large Files
```go
func streamProcess(input, output string) error {
inFile, err := os.Open(input)
if err != nil {
return err
}
defer inFile.Close()
outFile, err := os.Create(output)
if err != nil {
return err
}
defer outFile.Close()
reader := bufio.NewReader(inFile)
writer := bufio.NewWriter(outFile)
defer writer.Flush()
buf := make([]byte, 4096)
for {
n, err := reader.Read(buf)
if err != nil && err != io.EOF {
return err
}
if n == 0 {
break
}
// Process chunk
processed := processChunk(buf[:n])
if _, err := writer.Write(processed); err != nil {
return err
}
}
return nil
}
```
## Concurrent Processing Patterns
### Worker Pool
```go
func processParallel(items []string, workers int) error {
jobs := make(chan string, len(items))
results := make(chan error, len(items))
// Start workers
var wg sync.WaitGroup
for i := 0; i < workers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for item := range jobs {
if err := processItem(item); err != nil {
results <- err
} else {
results <- nil
}
}
}()
}
// Send jobs
for _, item := range items {
jobs <- item
}
close(jobs)
// Wait for completion
wg.Wait()
close(results)
// Check for errors
for err := range results {
if err != nil {
return err
}
}
return nil
}
```
### Rate Limited Processing
```go
func processWithRateLimit(items []string, requestsPerSecond int) error {
limiter := time.NewTicker(time.Second / time.Duration(requestsPerSecond))
defer limiter.Stop()
for i, item := range items {
<-limiter.C
if *verbose {
log.Printf("Processing %d/%d: %s", i+1, len(items), item)
}
if err := processItem(item); err != nil {
return fmt.Errorf("failed to process %s: %w", item, err)
}
}
return nil
}
```
## Progress Reporting
### Simple Progress Bar
```go
func showProgress(current, total int) {
if total == 0 {
return
}
percent := float64(current) / float64(total) * 100
filled := int(percent / 2) // 50 chars max
fmt.Fprintf(os.Stderr, "\r[")
for i := 0; i < 50; i++ {
if i < filled {
fmt.Fprintf(os.Stderr, "=")
} else {
fmt.Fprintf(os.Stderr, " ")
}
}
fmt.Fprintf(os.Stderr, "] %.1f%% (%d/%d)", percent, current, total)
if current == total {
fmt.Fprintln(os.Stderr)
}
}
```
### Timed Progress Updates
```go
type ProgressTracker struct {
total int
current int
lastUpdate time.Time
updateEvery time.Duration
}
func NewProgressTracker(total int) *ProgressTracker {
return &ProgressTracker{
total: total,
updateEvery: 500 * time.Millisecond,
lastUpdate: time.Now(),
}
}
func (p *ProgressTracker) Update(current int) {
p.current = current
if time.Since(p.lastUpdate) < p.updateEvery && current < p.total {
return
}
p.lastUpdate = time.Now()
showProgress(p.current, p.total)
}
```
## Error Handling Patterns
### Recoverable vs Fatal Errors
```go
type ProcessResult struct {
Processed int
Failed int
Errors []error
}
func processWithRecovery(items []string) (*ProcessResult, error) {
result := &ProcessResult{}
for _, item := range items {
if err := processItem(item); err != nil {
// Check if error is recoverable
if isRecoverable(err) {
result.Failed++
result.Errors = append(result.Errors,
fmt.Errorf("%s: %w", item, err))
continue
} else {
// Fatal error
return result, fmt.Errorf("fatal error processing %s: %w", item, err)
}
}
result.Processed++
}
return result, nil
}
func isRecoverable(err error) bool {
// Define what errors are recoverable
return errors.Is(err, os.ErrNotExist) ||
errors.Is(err, os.ErrPermission)
}
```
## CLI Patterns
### Multiple Input Sources
```go
func getInput() (io.Reader, func() error, error) {
if flag.NArg() > 0 {
// File input
filename := flag.Arg(0)
file, err := os.Open(filename)
if err != nil {
return nil, nil, err
}
return file, file.Close, nil
} else {
// Stdin input
return os.Stdin, func() error { return nil }, nil
}
}
func main() {
// ... flag parsing ...
input, cleanup, err := getInput()
if err != nil {
log.Fatal(err)
}
defer cleanup()
if err := process(input); err != nil {
log.Fatal(err)
}
}
```
### Configuration with Defaults
```go
type Config struct {
Workers int
BufferSize int
Timeout time.Duration
OutputDir string
}
func loadConfig() *Config {
cfg := &Config{
Workers: 4,
BufferSize: 4096,
Timeout: 30 * time.Second,
OutputDir: "output",
}
flag.IntVar(&cfg.Workers, "workers", cfg.Workers, "Number of worker goroutines")
flag.IntVar(&cfg.BufferSize, "buffer", cfg.BufferSize, "Buffer size in bytes")
flag.DurationVar(&cfg.Timeout, "timeout", cfg.Timeout, "Operation timeout")
flag.StringVar(&cfg.OutputDir, "output", cfg.OutputDir, "Output directory")
flag.Parse()
return cfg
}
```
## Data Processing Patterns
### CSV Processing
```go
func processCSV(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
reader := csv.NewReader(file)
reader.TrimLeadingSpace = true
// Read header
header, err := reader.Read()
if err != nil {
return fmt.Errorf("failed to read header: %w", err)
}
// Process rows
for {
record, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
return fmt.Errorf("failed to read row: %w", err)
}
// Convert to map for easy access
row := make(map[string]string)
for i, value := range record {
if i < len(header) {
row[header[i]] = value
}
}
if err := processRow(row); err != nil {
return err
}
}
return nil
}
```
### JSON Streaming
```go
func processJSONStream(r io.Reader) error {
decoder := json.NewDecoder(r)
// Expect array of objects
// Read opening bracket
if _, err := decoder.Token(); err != nil {
return err
}
// Process objects
for decoder.More() {
var obj YourType
if err := decoder.Decode(&obj); err != nil {
return err
}
if err := processObject(&obj); err != nil {
return err
}
}
// Read closing bracket
if _, err := decoder.Token(); err != nil {
return err
}
return nil
}
```
## Testing Patterns
### Table-Driven Tests
```go
func TestProcess(t *testing.T) {
tests := []struct {
name string
input string
want string
wantErr bool
}{
{
name: "valid input",
input: "test.txt",
want: "output.txt",
},
{
name: "invalid input",
input: "nonexistent.txt",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := process(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("process() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("process() = %v, want %v", got, tt.want)
}
})
}
}
```
## Best Practices Summary
1. **Always handle errors explicitly** - Never ignore errors
2. **Close resources** - Use defer for cleanup
3. **Validate inputs early** - Fail fast with clear messages
4. **Use buffered I/O** - For file operations
5. **Progress feedback** - For long operations
6. **Graceful degradation** - Separate recoverable from fatal errors
7. **Configurable behavior** - Use flags for common parameters
8. **Stream large data** - Don't load entire files into memory
9. **Parallel processing** - Use goroutines for independent operations
10. **Test thoroughly** - Use table-driven tests

View File

@ -0,0 +1,334 @@
# Skill Examples
Real-world examples of well-structured skills with Go scripts and agent workflows.
## Example 1: PDF Tools Skill
### Structure
```
pdf-tools/
├── SKILL.md
├── scripts/
│ ├── pdf-to-images.go
│ ├── merge-pdfs.go
│ ├── extract-text.go
│ ├── rotate-pages.go
│ └── bin/
│ ├── pdf-to-images
│ ├── merge-pdfs
│ ├── extract-text
│ └── rotate-pages
└── references/
└── pdf-formats.md
```
### SKILL.md Excerpt
```markdown
---
name: pdf-tools
description: Comprehensive PDF manipulation toolkit. Use when users need to convert, merge, split, rotate, or extract content from PDF files. Triggers: mentions of PDF, .pdf files uploaded, requests for document manipulation.
---
# PDF Tools
Tools for efficient PDF manipulation with compiled binaries for performance.
## Quick Start
Common operations:
**Extract text:**
```bash
scripts/bin/extract-text document.pdf
```
**Convert to images:**
```bash
scripts/bin/pdf-to-images document.pdf output/
```
**Merge multiple PDFs:**
```bash
scripts/bin/merge-pdfs file1.pdf file2.pdf file3.pdf output.pdf
```
## Workflow Decision Tree
1. **Simple operations** (extract, convert, merge, rotate)
→ Use appropriate Go script from scripts/bin/
2. **Content analysis** (summarize, find information)
→ First extract text, then analyze content
3. **Form filling**
→ See references/pdf-forms.md for detailed workflow
```
### When to Use What
- **Go scripts:** All standard PDF operations (deterministic)
- **Agent workflow:** Content analysis, recommendations
- **References:** Complex topics like form handling
## Example 2: Data Processing Skill
### Structure
```
data-processor/
├── SKILL.md
├── scripts/
│ ├── csv-to-json.go
│ ├── json-to-csv.go
│ ├── validate-schema.go
│ ├── analyze_data.py (Python for pandas)
│ └── bin/
│ ├── csv-to-json
│ ├── json-to-csv
│ └── validate-schema
└── references/
├── schemas.md
└── analysis-patterns.md
```
### SKILL.md Excerpt
```markdown
---
name: data-processor
description: Convert and analyze structured data formats. Use for CSV, JSON, XML conversions, data validation, and exploratory analysis. Triggers: data files uploaded, mentions of CSV/JSON/XML, requests for data analysis or conversion.
---
# Data Processor
## Operations
### Format Conversions (Go Scripts)
Fast, deterministic conversions:
```bash
# CSV to JSON
scripts/bin/csv-to-json input.csv output.json
# JSON to CSV
scripts/bin/json-to-csv input.json output.csv
# Validate against schema
scripts/bin/validate-schema data.json schema.json
```
### Data Analysis (Python + Agent)
1. Run initial analysis:
```bash
python3 scripts/analyze_data.py data.csv
```
2. Interpret results and provide insights:
- Identify patterns
- Suggest visualizations
- Recommend next steps
```
### Pattern: Two-Phase Processing
This skill demonstrates the common pattern:
**Phase 1: Go Scripts**
- Fast data transformation
- Schema validation
- Format conversion
- Output: structured data
**Phase 2: Agent Workflow**
- Interpret results
- Find insights
- Make recommendations
- Output: human-readable analysis
## Example 3: Image Tools Skill
### Structure
```
image-tools/
├── SKILL.md
├── scripts/
│ ├── resize-image.go
│ ├── convert-format.go
│ ├── batch-process.go
│ └── bin/
│ ├── resize-image
│ ├── convert-format
│ └── batch-process
└── assets/
└── watermark.png
```
### SKILL.md Excerpt
```markdown
---
name: image-tools
description: Image manipulation and batch processing. Use for resizing, format conversion, cropping, rotating images. Supports batch operations. Triggers: image files uploaded, mentions of image processing, resize, convert, crop, rotate.
---
# Image Tools
## Single Image Operations
```bash
# Resize
scripts/bin/resize-image input.jpg 800x600 output.jpg
# Convert format
scripts/bin/convert-format input.jpg output.png
# Rotate
scripts/bin/rotate-image input.jpg 90 output.jpg
```
## Batch Processing
Process entire directories efficiently:
```bash
scripts/bin/batch-process \
--operation resize \
--size 800x600 \
--input images/ \
--output resized/
```
The batch processor uses parallel goroutines for performance.
## When to Use Agent vs Scripts
**Use Go scripts for:**
- Standard operations (resize, crop, rotate, convert)
- Batch processing
- Operations with clear parameters
**Use agent workflow for:**
- "Make this image look better" (subjective)
- "Find the best crop for this portrait" (requires understanding)
- Choosing between multiple processing options
```
## Key Patterns Across Examples
### 1. Clear Separation of Concerns
**Deterministic → Go scripts**
- Format conversions
- Standard transformations
- Validation
- Batch operations
**Reasoning required → Agent workflows**
- Content analysis
- Recommendations
- Context-dependent decisions
- Creative tasks
### 2. Performance Where It Matters
Use Go for:
- Large file processing
- Batch operations (parallel)
- High-volume tasks
- Binary data manipulation
### 3. Progressive Disclosure
**SKILL.md:** High-level workflows and common operations
**References/:** Detailed documentation for complex topics
**Scripts/:** Implementation of deterministic operations
### 4. User-Friendly CLI
All Go scripts follow patterns:
- `--help` flag
- Clear error messages
- Progress indicators for long operations
- Verbose mode for debugging
### 5. Testing Strategy
Each skill includes:
- Example inputs in README or references
- Test commands for each script
- Expected outputs documented
## Anti-Example: What Not to Do
### ❌ Over-Scripting
```markdown
# DON'T: Script everything including one-liners
scripts/bin/list-files # Just use 'ls'!
scripts/bin/copy-file # Just use 'cp'!
```
### ❌ Under-Scripting
```markdown
# DON'T: Agent workflow for repeated deterministic tasks
For each file:
1. Read the file content
2. Convert JSON to YAML
3. Save to new location
# SHOULD BE: scripts/bin/json-to-yaml (called once for batch)
```
### ❌ Wrong Tool
```markdown
# DON'T: Go for data science
scripts/bin/train-ml-model # Use Python!
# DON'T: Python for file conversion
scripts/convert_csv.py # Use Go for performance!
```
## Template for New Skills
Based on these patterns:
```markdown
---
name: my-skill
description: What it does and when to use it. Include specific triggers.
---
# My Skill
## Quick Start
[Most common operation with example]
## Operations
### Category 1: [Deterministic Operations]
[Go script usage examples]
### Category 2: [Analysis/Reasoning]
[Agent workflow description]
## Workflow Patterns
[When to use what]
## Resources
[References to scripts, references, assets]
```
## Measuring Success
A well-designed skill has:
✅ Clear triggering in description
✅ Go scripts for repeated deterministic tasks
✅ Agent workflows for reasoning tasks
✅ Lean SKILL.md (<500 lines)
✅ Detailed references for complex topics
✅ Tested, working scripts
✅ Clear usage examples
✅ No redundant tools (use bash when appropriate)

View File

@ -0,0 +1,283 @@
# Workflow Analysis Guide
This guide helps identify which operations should be Go scripts vs agent workflows.
## Decision Framework
### Ask These Questions
For each operation in your skill, evaluate:
1. **Does it require understanding/interpretation?**
- YES → Agent workflow
- NO → Continue
2. **Is the logic completely deterministic?**
- NO → Agent workflow
- YES → Continue
3. **Could it benefit from compilation/performance?**
- YES → Go script
- NO → Continue
4. **Does it need Python libraries?**
- YES → Python script
- NO → Go script
## Detailed Analysis
### Strongly Favor Go Scripts For:
**File operations:**
- Format conversions (PDF→PNG, CSV→JSON)
- Splitting/merging files
- Batch renaming/organizing
- File validation (format checks)
- Compression/decompression
**Data transformations:**
- Parsing structured data (CSV, JSON, XML)
- Format conversions with fixed rules
- Data validation against schemas
- Mathematical computations
- Text processing with regex
**Batch operations:**
- Processing thousands of files
- Parallel operations on independent items
- High-volume data processing
- Performance-critical tasks
**Binary/low-level:**
- Image manipulation (resize, crop, rotate)
- Audio/video processing
- Network protocols
- Cryptographic operations
### Strongly Favor Agent Workflows For:
**Content understanding:**
- Sentiment analysis
- Topic extraction
- Summarization
- Question answering
- Semantic search
**Decision-making:**
- Choosing strategies based on context
- Adapting to unexpected inputs
- Multi-step reasoning
- Evaluating trade-offs
**Creative tasks:**
- Writing (articles, emails, code comments)
- Design suggestions
- Naming (variables, files, projects)
- Brainstorming
**Interactive processes:**
- Troubleshooting
- Guided workflows with user input
- Adaptive error handling
- Context-dependent branching
### Consider Python Scripts For:
**Data science:**
- Pandas/NumPy operations
- Statistical analysis
- Data visualization
- Machine learning inference
**Specialized libraries:**
- Computer vision (OpenCV)
- NLP (spaCy, NLTK)
- Web scraping (BeautifulSoup)
- API clients with complex auth
**Prototyping:**
- Quick experiments
- One-off utilities
- Testing ideas before Go implementation
## Real-World Examples
### Example 1: PDF Processing Skill
**User requests:**
1. "Extract text from this PDF"
2. "Rotate all pages 90 degrees"
3. "Summarize the key points in this PDF"
4. "Split this PDF into separate pages"
**Analysis:**
| Request | Operation | Type | Reason |
|---------|-----------|------|--------|
| Extract text | pdf-extract-text | Go script | Deterministic, parsing |
| Rotate pages | pdf-rotate-pages | Go script | Deterministic, binary |
| Summarize | summarize-document | Agent workflow | Understanding required |
| Split pages | pdf-split-pages | Go script | Deterministic, file ops |
**Go scripts:** 3
**Agent workflows:** 1
### Example 2: Data Analysis Skill
**User requests:**
1. "Convert this CSV to JSON"
2. "Find outliers in this dataset"
3. "Plot the trends in this data"
4. "What insights can you find?"
**Analysis:**
| Request | Operation | Type | Reason |
|---------|-----------|------|--------|
| CSV to JSON | csv-to-json | Go script | Simple conversion |
| Find outliers | find-outliers | Python script | Statistical libraries |
| Plot trends | plot-data | Python script | Matplotlib/Seaborn |
| Find insights | analyze-insights | Agent workflow | Interpretation needed |
**Go scripts:** 1
**Python scripts:** 2
**Agent workflows:** 1
### Example 3: Code Generation Skill
**User requests:**
1. "Format this code"
2. "Generate boilerplate for a REST API"
3. "Review this code for bugs"
4. "Add error handling"
**Analysis:**
| Request | Operation | Type | Reason |
|---------|-----------|------|--------|
| Format code | format-code | Go script | Deterministic rules |
| Generate boilerplate | generate-boilerplate | Go script | Template-based |
| Review for bugs | review-code | Agent workflow | Reasoning required |
| Add error handling | add-error-handling | Agent workflow | Context-dependent |
**Go scripts:** 2
**Agent workflows:** 2
## Common Patterns
### Pattern: "Process and Analyze"
Many skills have this two-phase pattern:
1. **Process phase** (Go script)
- Extract/transform/validate data
- Fixed, deterministic operations
- Output: structured data
2. **Analyze phase** (Agent workflow)
- Interpret results
- Make recommendations
- Context-dependent decisions
**Example:**
```markdown
1. Run: scripts/bin/extract-metrics data.log
Extracts structured metrics to metrics.json
2. Analyze the metrics and identify:
- Performance bottlenecks
- Unusual patterns
- Recommended optimizations
```
### Pattern: "Validate and Act"
1. **Validate** (Go script)
- Check format/schema
- Fast, deterministic
- Output: valid/invalid + errors
2. **Act** (Agent workflow or Go script)
- If valid → Go script for fixed action
- If invalid → Agent helps troubleshoot
**Example:**
```markdown
1. Run: scripts/bin/validate-config config.yaml
- Validates against schema
- Returns validation errors
2. If valid:
- Run: scripts/bin/apply-config config.yaml
If invalid:
- Review errors and suggest fixes
```
### Pattern: "Batch with Exceptions"
1. **Batch process** (Go script)
- Process 95% of standard cases
- Fast, parallel
- Flag exceptions
2. **Handle exceptions** (Agent workflow)
- Review flagged items
- Make case-by-case decisions
- Learn patterns for future
## Anti-Patterns
### ❌ Over-Engineering
Don't create Go scripts for:
- Operations done once
- Simple 5-line operations
- Operations that may need frequent changes
**Better:** Keep as agent workflow or simple bash command
### ❌ Under-Engineering
Don't use agent workflows for:
- Operations rewritten 10+ times
- Performance-critical bottlenecks
- Operations with clear pass/fail criteria
**Better:** Extract to Go script
### ❌ Wrong Tool
Don't use Go for:
- Complex data science (use Python)
- Operations requiring heavyweight libraries
- Rapid prototyping
Don't use Python for:
- High-performance requirements
- Binary/low-level operations
- Simple file processing
## Optimization Checklist
When reviewing a skill design:
- [ ] Every Go script is truly deterministic
- [ ] Every agent workflow truly needs reasoning
- [ ] No operations rewritten 3+ times
- [ ] Performance-critical paths identified
- [ ] Python used only where libraries needed
- [ ] Clear boundaries between phases
- [ ] Error handling strategy defined
- [ ] Testing approach planned
## Next Steps
After analysis:
1. List all Go scripts to create
2. List all Python scripts to create
3. Document agent workflows in SKILL.md
4. Create integration points between scripts and workflows
5. Plan testing strategy
6. Implement in priority order

View File

@ -0,0 +1,271 @@
#!/usr/bin/env python3
"""
Workflow Analysis Script for Meta Skill Generator
Analyzes user requirements and suggests which operations should be:
- Go scripts (deterministic, performance-critical)
- Python scripts (library-heavy, data science)
- Agent workflows (requires reasoning, context-dependent)
Usage:
analyze_workflow.py [--examples file1.txt file2.txt ...] [--interactive]
"""
import argparse
import sys
from pathlib import Path
from typing import List, Dict, Tuple
# Keywords that indicate deterministic operations
DETERMINISTIC_KEYWORDS = {
'convert', 'transform', 'parse', 'extract', 'validate',
'format', 'encode', 'decode', 'compress', 'decompress',
'resize', 'crop', 'rotate', 'merge', 'split',
'sort', 'filter', 'calculate', 'compute'
}
# Keywords that indicate dynamic/reasoning operations
DYNAMIC_KEYWORDS = {
'analyze', 'understand', 'interpret', 'decide', 'choose',
'suggest', 'recommend', 'summarize', 'explain', 'describe',
'evaluate', 'assess', 'determine', 'identify', 'classify'
}
# Keywords that suggest Go (performance-critical)
GO_INDICATORS = {
'large file', 'batch', 'thousands', 'millions', 'concurrent',
'parallel', 'performance', 'fast', 'binary', 'low-level',
'file system', 'network', 'stream'
}
# Keywords that suggest Python (library-heavy)
PYTHON_INDICATORS = {
'pandas', 'numpy', 'scikit', 'machine learning', 'data science',
'plot', 'graph', 'visualization', 'api client', 'requests',
'beautiful soup', 'selenium', 'opencv'
}
class OperationAnalyzer:
def __init__(self):
self.operations = []
def analyze_text(self, text: str) -> List[Dict]:
"""Analyze text and identify operations."""
text_lower = text.lower()
sentences = text.replace('?', '.').replace('!', '.').split('.')
operations = []
for sentence in sentences:
sentence = sentence.strip()
if not sentence:
continue
op = self._analyze_sentence(sentence)
if op:
operations.append(op)
return operations
def _analyze_sentence(self, sentence: str) -> Dict:
"""Analyze a single sentence for operation type."""
sentence_lower = sentence.lower()
# Check for deterministic vs dynamic
det_score = sum(1 for kw in DETERMINISTIC_KEYWORDS if kw in sentence_lower)
dyn_score = sum(1 for kw in DYNAMIC_KEYWORDS if kw in sentence_lower)
# Check for Go vs Python indicators
go_score = sum(1 for kw in GO_INDICATORS if kw in sentence_lower)
py_score = sum(1 for kw in PYTHON_INDICATORS if kw in sentence_lower)
if det_score == 0 and dyn_score == 0:
return None
# Determine operation type
if det_score > dyn_score:
if go_score > py_score:
op_type = 'go_script'
reason = 'Deterministic operation with performance/binary characteristics'
elif py_score > 0:
op_type = 'python_script'
reason = 'Deterministic operation requiring specialized libraries'
else:
op_type = 'go_script'
reason = 'Deterministic operation suitable for compiled binary'
else:
op_type = 'agent_workflow'
reason = 'Requires reasoning, context analysis, or decision-making'
return {
'description': sentence,
'type': op_type,
'reason': reason,
'det_score': det_score,
'dyn_score': dyn_score,
'go_score': go_score,
'py_score': py_score
}
def generate_recommendations(self, operations: List[Dict]) -> str:
"""Generate recommendations report."""
go_ops = [op for op in operations if op['type'] == 'go_script']
py_ops = [op for op in operations if op['type'] == 'python_script']
agent_ops = [op for op in operations if op['type'] == 'agent_workflow']
report = []
report.append("=" * 70)
report.append("WORKFLOW ANALYSIS REPORT")
report.append("=" * 70)
report.append("")
report.append(f"Total operations identified: {len(operations)}")
report.append(f" - Go scripts recommended: {len(go_ops)}")
report.append(f" - Python scripts recommended: {len(py_ops)}")
report.append(f" - Agent workflows recommended: {len(agent_ops)}")
report.append("")
if go_ops:
report.append("-" * 70)
report.append("GO SCRIPTS (Deterministic, Performance-Critical)")
report.append("-" * 70)
for i, op in enumerate(go_ops, 1):
report.append(f"\n{i}. {op['description']}")
report.append(f" Reason: {op['reason']}")
report.append(f" Suggested name: {self._suggest_script_name(op['description'])}")
report.append("")
if py_ops:
report.append("-" * 70)
report.append("PYTHON SCRIPTS (Library-Heavy Operations)")
report.append("-" * 70)
for i, op in enumerate(py_ops, 1):
report.append(f"\n{i}. {op['description']}")
report.append(f" Reason: {op['reason']}")
report.append(f" Suggested name: {self._suggest_script_name(op['description'])}")
report.append("")
if agent_ops:
report.append("-" * 70)
report.append("AGENT WORKFLOWS (Reasoning Required)")
report.append("-" * 70)
for i, op in enumerate(agent_ops, 1):
report.append(f"\n{i}. {op['description']}")
report.append(f" Reason: {op['reason']}")
report.append(f" Implementation: Keep as natural language workflow in SKILL.md")
report.append("")
report.append("=" * 70)
report.append("RECOMMENDATIONS")
report.append("=" * 70)
report.append("")
if go_ops:
report.append("For Go scripts:")
report.append(" 1. Use generate_go_script.py to create each script")
report.append(" 2. Focus on performance and error handling")
report.append(" 3. Support parallel processing where applicable")
report.append("")
if py_ops:
report.append("For Python scripts:")
report.append(" 1. Create scripts in scripts/ directory")
report.append(" 2. Add requirements.txt for dependencies")
report.append(" 3. Consider virtual environments")
report.append("")
if agent_ops:
report.append("For agent workflows:")
report.append(" 1. Document in SKILL.md with clear decision points")
report.append(" 2. Provide examples for different scenarios")
report.append(" 3. Use references/ for detailed guidance")
report.append("")
return '\n'.join(report)
def _suggest_script_name(self, description: str) -> str:
"""Suggest a script name from description."""
# Extract key verbs and nouns
words = description.lower().split()
important_words = []
for word in words:
cleaned = ''.join(c for c in word if c.isalnum())
if cleaned in DETERMINISTIC_KEYWORDS or len(cleaned) > 3:
important_words.append(cleaned)
if len(important_words) >= 3:
break
return '-'.join(important_words[:3]) if important_words else 'operation'
def interactive_mode():
"""Run in interactive mode to gather requirements."""
print("=" * 70)
print("WORKFLOW ANALYSIS - INTERACTIVE MODE")
print("=" * 70)
print("\nDescribe the operations your skill should perform.")
print("Enter each operation on a separate line.")
print("Press Ctrl+D (Unix) or Ctrl+Z (Windows) when done.\n")
lines = []
try:
while True:
line = input("> ")
if line.strip():
lines.append(line)
except EOFError:
pass
return '\n'.join(lines)
def main():
parser = argparse.ArgumentParser(
description='Analyze workflows to identify deterministic vs dynamic operations',
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument('--examples', nargs='+', help='Files containing example requests')
parser.add_argument('--interactive', action='store_true', help='Run in interactive mode')
parser.add_argument('--output', help='Output file for report (default: stdout)')
args = parser.parse_args()
analyzer = OperationAnalyzer()
# Gather input
text = ""
if args.interactive:
text = interactive_mode()
elif args.examples:
for example_file in args.examples:
path = Path(example_file)
if path.exists():
text += path.read_text() + '\n'
else:
print(f"Warning: File not found: {example_file}", file=sys.stderr)
else:
print("Error: Provide --examples or use --interactive mode", file=sys.stderr)
sys.exit(1)
if not text.strip():
print("Error: No input provided", file=sys.stderr)
sys.exit(1)
# Analyze
operations = analyzer.analyze_text(text)
if not operations:
print("No operations detected in input", file=sys.stderr)
sys.exit(1)
# Generate report
report = analyzer.generate_recommendations(operations)
# Output
if args.output:
Path(args.output).write_text(report)
print(f"✅ Report written to: {args.output}")
else:
print(report)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,438 @@
#!/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 <script-name> --description <desc> \
--input <input-desc> --output <output-desc> \
--logic <logic-desc> --skill-path <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 '<input-file>'
elif 'directory' in input_desc.lower():
return '<input-dir>'
else:
return '<input>'
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] <input>
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()

View File

@ -0,0 +1,280 @@
#!/usr/bin/env python3
"""
End-to-End Skill Creator with Workflow Analysis
Guides through the complete process of creating a Claude Code skill with
intelligent Go script generation.
Usage:
init_skill_with_analysis.py <skill-name> --path <output-dir>
"""
import argparse
import subprocess
import sys
from pathlib import Path
def run_command(cmd, cwd=None):
"""Run a command and return success status."""
try:
result = subprocess.run(
cmd,
cwd=cwd,
capture_output=True,
text=True,
check=True
)
return True, result.stdout
except subprocess.CalledProcessError as e:
return False, e.stderr
def gather_examples():
"""Gather example use cases from user."""
print("\n" + "="*70)
print("STEP 1: GATHER EXAMPLE USE CASES")
print("="*70)
print("\nProvide 3-5 example requests that your skill should handle.")
print("Each example should be a concrete user request.")
print("Press Enter twice when done.\n")
examples = []
blank_count = 0
while blank_count < 2:
line = input(f"Example {len(examples)+1}: ").strip()
if not line:
blank_count += 1
else:
blank_count = 0
examples.append(line)
if not examples:
print("Error: No examples provided")
sys.exit(1)
return examples
def analyze_workflow(examples):
"""Analyze examples to identify operation types."""
print("\n" + "="*70)
print("STEP 2: ANALYZING WORKFLOW")
print("="*70)
# Create temporary file with examples
temp_file = Path("/tmp/skill_examples.txt")
temp_file.write_text('\n'.join(examples))
# Run analysis
script_path = Path(__file__).parent / "analyze_workflow.py"
cmd = [sys.executable, str(script_path), "--examples", str(temp_file)]
success, output = run_command(cmd)
if not success:
print(f"Warning: Workflow analysis failed: {output}")
return None
print(output)
return output
def confirm_plan():
"""Ask user to confirm the plan."""
print("\n" + "="*70)
print("Does this analysis look correct?")
response = input("Continue with skill creation? (y/n): ").lower()
return response == 'y'
def initialize_skill(skill_name, path):
"""Initialize skill directory structure."""
print("\n" + "="*70)
print("STEP 3: INITIALIZING SKILL")
print("="*70)
# Run init_skill.py
init_script = Path("/mnt/skills/examples/skill-creator/scripts/init_skill.py")
cmd = [sys.executable, str(init_script), skill_name, "--path", path]
success, output = run_command(cmd)
if not success:
print(f"Error: Failed to initialize skill: {output}")
sys.exit(1)
print(output)
return Path(path) / skill_name
def gather_script_specs(skill_path):
"""Gather specifications for Go scripts."""
print("\n" + "="*70)
print("STEP 4: SPECIFY GO SCRIPTS")
print("="*70)
print("\nBased on the analysis, let's define the Go scripts.")
print("Enter details for each deterministic operation.")
print()
scripts = []
while True:
print(f"\n--- Go Script {len(scripts)+1} ---")
print("Press Enter with empty name to finish")
name = input("Script name (e.g., pdf-to-images): ").strip()
if not name:
break
description = input("Description: ").strip()
if not description:
print("Description required")
continue
input_desc = input("Input (e.g., 'PDF file path'): ").strip()
if not input_desc:
print("Input description required")
continue
output_desc = input("Output (e.g., 'Directory of PNG files'): ").strip()
if not output_desc:
print("Output description required")
continue
logic = input("Logic (e.g., 'Extract each page at 300 DPI'): ").strip()
if not logic:
print("Logic description required")
continue
scripts.append({
'name': name,
'description': description,
'input': input_desc,
'output': output_desc,
'logic': logic
})
print(f"✅ Script '{name}' configured")
return scripts
def generate_go_scripts(skill_path, scripts):
"""Generate Go scripts using generate_go_script.py."""
if not scripts:
print("\nNo Go scripts to generate")
return
print("\n" + "="*70)
print("STEP 5: GENERATING GO SCRIPTS")
print("="*70)
generator = Path(__file__).parent / "generate_go_script.py"
for script in scripts:
print(f"\nGenerating {script['name']}...")
cmd = [
sys.executable, str(generator),
"--name", script['name'],
"--description", script['description'],
"--input", script['input'],
"--output", script['output'],
"--logic", script['logic'],
"--skill-path", str(skill_path)
]
success, output = run_command(cmd)
if not success:
print(f"⚠️ Warning: Failed to generate {script['name']}: {output}")
else:
print(f"✅ Generated {script['name']}")
def finalize_skill_md(skill_path, examples):
"""Add examples to SKILL.md."""
print("\n" + "="*70)
print("STEP 6: FINALIZING SKILL.MD")
print("="*70)
skill_md = skill_path / "SKILL.md"
content = skill_md.read_text()
# Add examples section
examples_section = "\n## Example Use Cases\n\n"
for i, example in enumerate(examples, 1):
examples_section += f"{i}. {example}\n"
# Insert before ## Resources section
if "## Resources" in content:
content = content.replace("## Resources", examples_section + "\n## Resources")
else:
content += examples_section
skill_md.write_text(content)
print(f"✅ Updated SKILL.md with {len(examples)} example use cases")
def print_next_steps(skill_path):
"""Print next steps for the user."""
print("\n" + "="*70)
print("✅ SKILL CREATED SUCCESSFULLY")
print("="*70)
print(f"\nSkill location: {skill_path}")
print("\nNext steps:")
print(f"1. Review and customize SKILL.md:")
print(f" - Complete the description in frontmatter")
print(f" - Add detailed workflow instructions")
print(f" - Remove TODO placeholders")
print()
print(f"2. Build Go scripts:")
print(f" cd {skill_path}")
for script_file in (skill_path / "scripts").glob("build_*.sh"):
print(f" ./{script_file.relative_to(skill_path)}")
print()
print(f"3. Test the scripts:")
for bin_file in (skill_path / "scripts" / "bin").glob("*"):
if bin_file.is_file():
print(f" ./scripts/bin/{bin_file.name} --help")
print()
print(f"4. Package the skill:")
print(f" python3 /mnt/skills/examples/skill-creator/scripts/package_skill.py {skill_path}")
print()
def main():
parser = argparse.ArgumentParser(
description='Create a Claude Code skill with workflow analysis and Go script generation',
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument('skill_name', help='Name of the skill (e.g., pdf-tools)')
parser.add_argument('--path', required=True, help='Directory where skill will be created')
parser.add_argument('--skip-analysis', action='store_true',
help='Skip workflow analysis (use for simple skills)')
parser.add_argument('--skip-go', action='store_true',
help='Skip Go script generation (create structure only)')
args = parser.parse_args()
print("="*70)
print("CLAUDE CODE SKILL CREATOR")
print("="*70)
print(f"\nCreating skill: {args.skill_name}")
print(f"Location: {args.path}")
# Step 1: Gather examples
examples = gather_examples()
# Step 2: Analyze workflow (optional)
if not args.skip_analysis:
analysis = analyze_workflow(examples)
if analysis and not confirm_plan():
print("\nAborted by user")
sys.exit(0)
# Step 3: Initialize skill
skill_path = initialize_skill(args.skill_name, args.path)
# Step 4-5: Generate Go scripts (optional)
if not args.skip_go:
scripts = gather_script_specs(skill_path)
generate_go_scripts(skill_path, scripts)
# Step 6: Finalize
finalize_skill_md(skill_path, examples)
# Done
print_next_steps(skill_path)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,194 @@
#!/usr/bin/env python3
"""
Test runner for skill scripts
Validates that all scripts in a skill are properly structured and executable.
Usage:
test_skill_scripts.py <skill-path>
"""
import argparse
import subprocess
import sys
from pathlib import Path
def test_python_scripts(scripts_dir):
"""Test Python scripts for syntax and executability."""
results = []
for script in scripts_dir.glob("*.py"):
if script.name.startswith("test_") or script.name == "__init__.py":
continue
# Check if executable
is_executable = script.stat().st_mode & 0o111
# Check syntax
try:
subprocess.run(
[sys.executable, "-m", "py_compile", str(script)],
capture_output=True,
check=True
)
syntax_ok = True
except subprocess.CalledProcessError:
syntax_ok = False
results.append({
'name': script.name,
'type': 'python',
'executable': is_executable,
'syntax_ok': syntax_ok
})
return results
def test_go_scripts(scripts_dir):
"""Test Go scripts for compilation."""
results = []
for script in scripts_dir.glob("*.go"):
# Try to compile
try:
result = subprocess.run(
["go", "build", "-o", "/dev/null", str(script)],
capture_output=True,
check=True
)
compiles = True
error = None
except subprocess.CalledProcessError as e:
compiles = False
error = e.stderr.decode()
except FileNotFoundError:
compiles = None # Go not installed
error = "Go compiler not found"
results.append({
'name': script.name,
'type': 'go',
'compiles': compiles,
'error': error
})
return results
def test_bash_scripts(scripts_dir):
"""Test Bash scripts for syntax."""
results = []
for script in scripts_dir.glob("*.sh"):
# Check if executable
is_executable = script.stat().st_mode & 0o111
# Check syntax
try:
subprocess.run(
["bash", "-n", str(script)],
capture_output=True,
check=True
)
syntax_ok = True
except subprocess.CalledProcessError:
syntax_ok = False
results.append({
'name': script.name,
'type': 'bash',
'executable': is_executable,
'syntax_ok': syntax_ok
})
return results
def print_results(results):
"""Print test results."""
print("\n" + "="*70)
print("SCRIPT TEST RESULTS")
print("="*70 + "\n")
all_passed = True
for result in results:
name = result['name']
script_type = result['type']
print(f"{name} ({script_type})")
if script_type == 'python':
if result['syntax_ok']:
print(" ✅ Syntax: OK")
else:
print(" ❌ Syntax: FAILED")
all_passed = False
if result['executable']:
print(" ✅ Executable: Yes")
else:
print(" ⚠️ Executable: No (run: chmod +x)")
elif script_type == 'go':
if result['compiles'] is None:
print(" ⚠️ Go compiler not found (skipped)")
elif result['compiles']:
print(" ✅ Compiles: OK")
else:
print(" ❌ Compiles: FAILED")
if result['error']:
print(f" Error: {result['error'][:100]}")
all_passed = False
elif script_type == 'bash':
if result['syntax_ok']:
print(" ✅ Syntax: OK")
else:
print(" ❌ Syntax: FAILED")
all_passed = False
if result['executable']:
print(" ✅ Executable: Yes")
else:
print(" ⚠️ Executable: No (run: chmod +x)")
print()
return all_passed
def main():
parser = argparse.ArgumentParser(
description='Test all scripts in a skill directory'
)
parser.add_argument('skill_path', help='Path to skill directory')
args = parser.parse_args()
skill_path = Path(args.skill_path).resolve()
scripts_dir = skill_path / 'scripts'
if not scripts_dir.exists():
print(f"Error: scripts directory not found: {scripts_dir}")
sys.exit(1)
print(f"Testing scripts in: {scripts_dir}")
results = []
results.extend(test_python_scripts(scripts_dir))
results.extend(test_go_scripts(scripts_dir))
results.extend(test_bash_scripts(scripts_dir))
if not results:
print("No scripts found to test")
sys.exit(0)
all_passed = print_results(results)
if all_passed:
print("✅ All tests passed!")
sys.exit(0)
else:
print("❌ Some tests failed")
sys.exit(1)
if __name__ == '__main__':
main()