Recreate source from .skill zip file
This commit is contained in:
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user