205 lines
4.9 KiB
Python
Executable File
205 lines
4.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Create a new OpenCode skill with proper structure."""
|
|
|
|
import os
|
|
import sys
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
|
|
SKILL_TEMPLATE = """---
|
|
name: {name}
|
|
description: {description}
|
|
---
|
|
|
|
# {title}
|
|
|
|
Brief description of what this skill does.
|
|
|
|
## Commands
|
|
|
|
| Command | Args | Description |
|
|
|---------|------|-------------|
|
|
| `command1` | `<arg>` | Description |
|
|
|
|
## Options
|
|
|
|
| Option | Default | Range | Description |
|
|
|--------|---------|-------|-------------|
|
|
| `--option` | 100 | 1-1000 | Description |
|
|
|
|
## Examples
|
|
|
|
```bash
|
|
python3 scripts/{script_name}.py command "arg" --option 50
|
|
```
|
|
|
|
## Output Format
|
|
|
|
- Success: `Result: filename [id]`
|
|
- Error: `Error: message` (to stderr)
|
|
|
|
## Notes
|
|
|
|
- Required environment variables: API_KEY
|
|
- Additional constraints or notes
|
|
"""
|
|
|
|
|
|
SCRIPT_TEMPLATE = """#!/usr/bin/env python3
|
|
|
|
import os
|
|
import sys
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
|
|
def load_env():
|
|
env_path = Path(__file__).parent / ".env"
|
|
if env_path.exists():
|
|
for line in env_path.read_text().splitlines():
|
|
line = line.strip()
|
|
if line and not line.startswith("#") and "=" in line:
|
|
k, v = line.split("=", 1)
|
|
os.environ.setdefault(k.strip(), v.strip().strip("\"'"))
|
|
|
|
|
|
load_env()
|
|
|
|
API_KEY = os.environ.get("API_KEY")
|
|
API_URL = "https://api.example.com/endpoint"
|
|
|
|
|
|
def main_action(arg1, option1=100):
|
|
if not API_KEY:
|
|
print("Error: API_KEY not set in environment", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
# TODO: Implement the main functionality
|
|
|
|
print(f"Result: output [1]")
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="{title} skill")
|
|
parser.add_argument("arg1", help="First argument")
|
|
parser.add_argument("--option1", type=int, default=100, help="Option description")
|
|
|
|
args = parser.parse_args()
|
|
|
|
main_action(args.arg1, args.option1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
"""
|
|
|
|
|
|
ENV_EXAMPLE_TEMPLATE = """# API credentials
|
|
# Get your token from https://service.com/account
|
|
#
|
|
# WARNING: Never commit actual credentials!
|
|
|
|
API_KEY=your_api_key_here
|
|
"""
|
|
|
|
|
|
REQUIREMENTS_TEMPLATE = """requests>=2.28.0
|
|
"""
|
|
|
|
|
|
def validate_name(name):
|
|
"""Validate skill name follows OpenCode rules."""
|
|
import re
|
|
|
|
if not name:
|
|
print("Error: Name cannot be empty", file=sys.stderr)
|
|
return False
|
|
|
|
if len(name) > 64:
|
|
print("Error: Name must be 64 characters or less", file=sys.stderr)
|
|
return False
|
|
|
|
pattern = r"^[a-z0-9]+(-[a-z0-9]+)*$"
|
|
if not re.match(pattern, name):
|
|
print(
|
|
"Error: Name must be lowercase alphanumeric with single hyphens",
|
|
file=sys.stderr,
|
|
)
|
|
print(" - No leading/trailing hyphens", file=sys.stderr)
|
|
print(" - No consecutive hyphens", file=sys.stderr)
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
def create_skill(name, description, output_dir):
|
|
"""Create a new skill directory structure."""
|
|
|
|
if not validate_name(name):
|
|
sys.exit(1)
|
|
|
|
title = name.replace("-", " ").title()
|
|
script_name = name.replace("-", "_")
|
|
|
|
skill_dir = Path(output_dir) / name
|
|
scripts_dir = skill_dir / "scripts"
|
|
|
|
if skill_dir.exists():
|
|
print(f"Error: Skill '{name}' already exists at {skill_dir}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
# Create directories
|
|
scripts_dir.mkdir(parents=True)
|
|
|
|
# Create SKILL.md
|
|
skill_md = skill_dir / "SKILL.md"
|
|
skill_md.write_text(
|
|
SKILL_TEMPLATE.format(
|
|
name=name, description=description, title=title, script_name=script_name
|
|
)
|
|
)
|
|
|
|
# Create script
|
|
script_file = scripts_dir / f"{script_name}.py"
|
|
script_file.write_text(SCRIPT_TEMPLATE.format(title=title))
|
|
script_file.chmod(0o755)
|
|
|
|
# Create .env.example
|
|
env_example = scripts_dir / ".env.example"
|
|
env_example.write_text(ENV_EXAMPLE_TEMPLATE)
|
|
|
|
# Create requirements.txt
|
|
requirements = scripts_dir / "requirements.txt"
|
|
requirements.write_text(REQUIREMENTS_TEMPLATE)
|
|
|
|
print(f"Created skill: {name}")
|
|
print(f" {skill_dir}/")
|
|
print(f" {skill_dir}/SKILL.md")
|
|
print(f" {scripts_dir}/{script_name}.py")
|
|
print(f" {scripts_dir}/.env.example")
|
|
print(f" {scripts_dir}/requirements.txt")
|
|
print()
|
|
print("Next steps:")
|
|
print(f" 1. Edit {skill_dir}/SKILL.md to define commands")
|
|
print(f" 2. Implement {scripts_dir}/{script_name}.py")
|
|
print(f" 3. Update {scripts_dir}/.env.example with required env vars")
|
|
print(f" 4. Run: ./scripts/install-skills.sh")
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Create a new OpenCode skill")
|
|
parser.add_argument("name", help="Skill name (lowercase, hyphens only)")
|
|
parser.add_argument("description", help="Brief description of the skill")
|
|
parser.add_argument(
|
|
"--output", "-o", default="skills", help="Output directory (default: skills)"
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
create_skill(args.name, args.description, args.output)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|