228 lines
6.8 KiB
Markdown
228 lines
6.8 KiB
Markdown
# Scripts and Code
|
|
|
|
Best practices for including scripts, handling errors, managing dependencies, and documenting configuration in skills.
|
|
|
|
## Table of Contents
|
|
|
|
- [When to Include Scripts](#when-to-include-scripts)
|
|
- [Error Handling](#error-handling)
|
|
- [Dependencies and Packages](#dependencies-and-packages)
|
|
- [File Paths and Cross-Platform Compatibility](#file-paths-and-cross-platform-compatibility)
|
|
- [Configuration Documentation](#configuration-documentation)
|
|
- [Script Execution vs. Reference](#script-execution-vs-reference)
|
|
- [Validation Scripts](#validation-scripts)
|
|
- [MCP Tools Integration](#mcp-tools-integration)
|
|
|
|
## When to Include Scripts
|
|
|
|
Pre-made scripts are more reliable than code generation for critical operations.
|
|
|
|
### Scripts vs. Generated Code
|
|
|
|
**Use pre-made scripts for:**
|
|
|
|
- Critical operations requiring exact sequences
|
|
- Complex error handling
|
|
- Repeated utility functions
|
|
- Fragile operations (database migrations, API calls)
|
|
- Operations where order matters
|
|
|
|
**Use code generation for:**
|
|
|
|
- Creative solutions
|
|
- Context-specific implementations
|
|
- One-off operations
|
|
- Exploratory tasks
|
|
|
|
## Error Handling
|
|
|
|
Scripts should solve problems, not punt to Claude. Provide specific, actionable error messages.
|
|
|
|
### Good Error Handling
|
|
|
|
✓ **What to do:**
|
|
```python
|
|
def process_file(filename):
|
|
"""
|
|
Process input file with comprehensive error handling.
|
|
|
|
Args:
|
|
filename: Path to the file to process
|
|
|
|
Returns:
|
|
Processed data string
|
|
|
|
Raises:
|
|
FileNotFoundError: With specific path and suggestions
|
|
PermissionError: With permission requirements
|
|
ValueError: With format expectations
|
|
"""
|
|
import os
|
|
|
|
# Check file exists
|
|
if not os.path.exists(filename):
|
|
raise FileNotFoundError(
|
|
f"File not found: {filename}\n"
|
|
f"Current directory: {os.getcwd()}\n"
|
|
f"Please verify:\n"
|
|
f" 1. File path is correct\n"
|
|
f" 2. File exists in the expected location\n"
|
|
f" 3. You have permission to access the directory"
|
|
)
|
|
|
|
# Check file is readable
|
|
if not os.access(filename, os.R_OK):
|
|
raise PermissionError(
|
|
f"Cannot read file: {filename}\n"
|
|
f"Current user: {os.getenv('USER')}\n"
|
|
f"File permissions: {oct(os.stat(filename).st_mode)[-3:]}\n"
|
|
f"Solution: Run 'chmod +r {filename}' or contact system administrator"
|
|
)
|
|
|
|
# Check file is not empty
|
|
if os.path.getsize(filename) == 0:
|
|
raise ValueError(
|
|
f"File is empty: {filename}\n"
|
|
f"Expected: Non-empty CSV file with headers\n"
|
|
f"Please provide a file with data"
|
|
)
|
|
|
|
# Check file format
|
|
try:
|
|
with open(filename, 'r') as f:
|
|
first_line = f.readline()
|
|
if not first_line.strip():
|
|
raise ValueError(
|
|
f"File appears to be empty or invalid: {filename}\n"
|
|
f"Expected: CSV file with comma-separated headers"
|
|
)
|
|
|
|
if ',' not in first_line:
|
|
raise ValueError(
|
|
f"File does not appear to be CSV format: {filename}\n"
|
|
f"First line: {first_line[:100]}\n"
|
|
f"Expected: Comma-separated values\n"
|
|
f"Detected: {first_line.count('\t')} tabs, {first_line.count('|')} pipes\n"
|
|
f"Suggestion: Check delimiter or convert to CSV"
|
|
)
|
|
|
|
# Process file
|
|
f.seek(0)
|
|
data = f.read()
|
|
return data
|
|
|
|
except UnicodeDecodeError as e:
|
|
raise ValueError(
|
|
f"File encoding error: {filename}\n"
|
|
f"Error: {str(e)}\n"
|
|
f"File might be binary or use unsupported encoding\n"
|
|
f"Solution: Convert to UTF-8 encoding or verify file type"
|
|
)
|
|
```
|
|
|
|
## Dependencies and Packages
|
|
|
|
Document required packages with versions and explain why they're needed.
|
|
|
|
## File Paths and Cross-Platform Compatibility
|
|
|
|
Always use forward slashes for file paths to ensure cross-platform compatibility.
|
|
|
|
### Path Best Practices
|
|
|
|
**Always use forward slashes:**
|
|
```python
|
|
# ✓ Correct - works on all platforms
|
|
data_file = "data/input/customers.csv"
|
|
output_dir = "reports/2024/march"
|
|
config_path = "config/settings.json"
|
|
|
|
# ✗ Wrong - fails on Unix-like systems
|
|
data_file = "data\\input\\customers.csv"
|
|
output_dir = "reports\\2024\\march"
|
|
```
|
|
|
|
**Use pathlib for path operations:**
|
|
```python
|
|
from pathlib import Path
|
|
|
|
# Automatically handles platform differences
|
|
data_dir = Path("data") / "input"
|
|
output_file = data_dir / "processed_data.csv"
|
|
|
|
# Always converts to forward slashes for display
|
|
print(output_file.as_posix()) # "data/input/processed_data.csv"
|
|
```
|
|
|
|
**Convert user-provided paths:**
|
|
```python
|
|
def normalize_path(path_str):
|
|
"""Convert any path format to forward-slash format."""
|
|
from pathlib import Path
|
|
return Path(path_str).as_posix()
|
|
|
|
# Example usage
|
|
user_path = "data\\input\\file.csv" # User on Windows
|
|
normalized = normalize_path(user_path) # "data/input/file.csv"
|
|
```
|
|
|
|
## Configuration Documentation
|
|
|
|
Document why configuration values exist. No "magic numbers."
|
|
|
|
### Good Configuration
|
|
|
|
✓ **What to do:**
|
|
```python
|
|
# Maximum retry attempts for API calls
|
|
# Set to 3 because:
|
|
# - API typically recovers within 3 attempts
|
|
# - Higher values cause unacceptable user wait times
|
|
# - Exponential backoff means 3 attempts = ~7 seconds total
|
|
MAX_RETRIES = 3
|
|
|
|
# Request timeout in seconds
|
|
# Set to 30 because:
|
|
# - API SLA guarantees response within 20 seconds
|
|
# - 10 second buffer prevents false timeouts
|
|
# - Longer timeouts risk resource exhaustion
|
|
TIMEOUT = 30
|
|
```
|
|
|
|
## Script Execution vs. Reference
|
|
|
|
Clarify whether Claude should execute scripts or use them as reference patterns.
|
|
|
|
## Validation Scripts
|
|
|
|
Create validation scripts with explicit, actionable error messages for critical operations.
|
|
|
|
## MCP Tools Integration
|
|
|
|
When referencing MCP (Model Context Protocol) tools, always use fully qualified names.
|
|
|
|
### Fully Qualified Names
|
|
|
|
MCP tools must be referenced with the server name prefix:
|
|
|
|
✓ **Correct:**
|
|
```markdown
|
|
Use the `DatabaseServer:search_database` tool to find records.
|
|
Use the `FileServer:list_files` tool to see available files.
|
|
```
|
|
|
|
## Validation Checklist
|
|
|
|
Scripts and code checklist:
|
|
|
|
- [ ] Scripts included only for critical/complex/repeated operations
|
|
- [ ] Error messages are specific and actionable
|
|
- [ ] Error messages include context and solutions
|
|
- [ ] All error conditions explicitly handled
|
|
- [ ] Dependencies documented with versions and purposes
|
|
- [ ] File paths use forward slashes (cross-platform)
|
|
- [ ] Configuration values explained (no magic numbers)
|
|
- [ ] Clear indication whether to execute or reference scripts
|
|
- [ ] Validation scripts provide comprehensive error reports
|
|
- [ ] MCP tools referenced with fully qualified names (ServerName:tool_name)
|