Add skills
This commit is contained in:
391
.config/opencode/skills/.skill-builder.disabled/scripts/init-skill.sh
Executable file
391
.config/opencode/skills/.skill-builder.disabled/scripts/init-skill.sh
Executable file
@@ -0,0 +1,391 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# init-skill.sh - Scaffold a new skill with proper structure
|
||||
#
|
||||
# Usage: ./init-skill.sh <skill-name> [options]
|
||||
#
|
||||
# Options:
|
||||
# --local Create in current project (.opencode/skills/) instead of global
|
||||
# --with-scripts Include scripts/ directory
|
||||
# --with-refs Include references/ directory
|
||||
# --with-assets Include assets/ directory
|
||||
# --with-tests Include evals/ directory for test cases
|
||||
# --full Include all optional directories
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Get script directory
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
SKILL_BUILDER_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
# Parse arguments
|
||||
SKILL_NAME=""
|
||||
LOCAL=false
|
||||
WITH_SCRIPTS=false
|
||||
WITH_REFS=false
|
||||
WITH_ASSETS=false
|
||||
WITH_TESTS=false
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 <skill-name> [options]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --local Create in current project (.opencode/skills/)"
|
||||
echo " --with-scripts Include scripts/ directory"
|
||||
echo " --with-refs Include references/ directory"
|
||||
echo " --with-assets Include assets/ directory"
|
||||
echo " --with-tests Include evals/ directory for test cases"
|
||||
echo " --full Include all optional directories"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 my-skill"
|
||||
echo " $0 my-skill --full"
|
||||
echo " $0 my-skill --local --with-scripts"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Validate skill name
|
||||
validate_name() {
|
||||
local name="$1"
|
||||
|
||||
if [[ -z "$name" ]]; then
|
||||
echo -e "${RED}Error: Skill name is required${NC}"
|
||||
usage
|
||||
fi
|
||||
|
||||
if [[ ! "$name" =~ ^[a-z0-9-]+$ ]]; then
|
||||
echo -e "${RED}Error: Skill name must be lowercase alphanumeric with hyphens only${NC}"
|
||||
echo " Valid: my-skill, docker-helper, test-runner"
|
||||
echo " Invalid: My Skill, docker_helper, testRunner"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ${#name} -lt 1 ]]; then
|
||||
echo -e "${RED}Error: Skill name cannot be empty${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ${#name} -gt 64 ]]; then
|
||||
echo -e "${RED}Error: Skill name must be under 64 characters${NC}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--local)
|
||||
LOCAL=true
|
||||
shift
|
||||
;;
|
||||
--with-scripts)
|
||||
WITH_SCRIPTS=true
|
||||
shift
|
||||
;;
|
||||
--with-refs)
|
||||
WITH_REFS=true
|
||||
shift
|
||||
;;
|
||||
--with-assets)
|
||||
WITH_ASSETS=true
|
||||
shift
|
||||
;;
|
||||
--with-tests)
|
||||
WITH_TESTS=true
|
||||
shift
|
||||
;;
|
||||
--full)
|
||||
WITH_SCRIPTS=true
|
||||
WITH_REFS=true
|
||||
WITH_ASSETS=true
|
||||
WITH_TESTS=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
-*)
|
||||
echo -e "${RED}Error: Unknown option $1${NC}"
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
if [[ -z "$SKILL_NAME" ]]; then
|
||||
SKILL_NAME="$1"
|
||||
else
|
||||
echo -e "${RED}Error: Multiple skill names provided${NC}"
|
||||
usage
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Validate skill name
|
||||
validate_name "$SKILL_NAME"
|
||||
|
||||
# Determine target directory
|
||||
if [[ "$LOCAL" == true ]]; then
|
||||
# Check if we're in a git repository
|
||||
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
||||
echo -e "${RED}Error: --local requires being in a git repository${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET_DIR=".opencode/skills/$SKILL_NAME"
|
||||
|
||||
# Check for AGENTS.md in project
|
||||
if [[ -f "AGENTS.md" ]]; then
|
||||
echo -e "${GREEN}✓ Found AGENTS.md in project root${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ No AGENTS.md found in project root${NC}"
|
||||
echo " Consider creating one for project-specific rules"
|
||||
fi
|
||||
else
|
||||
TARGET_DIR="$HOME/.config/opencode/skills/$SKILL_NAME"
|
||||
fi
|
||||
|
||||
# Check if skill already exists
|
||||
if [[ -d "$TARGET_DIR" ]]; then
|
||||
echo -e "${RED}Error: Skill already exists at $TARGET_DIR${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Creating skill: $SKILL_NAME${NC}"
|
||||
echo " Location: $TARGET_DIR"
|
||||
echo ""
|
||||
|
||||
# Create skill directory
|
||||
mkdir -p "$TARGET_DIR"
|
||||
|
||||
# Create SKILL.md
|
||||
cat > "$TARGET_DIR/SKILL.md" << 'SKILL_TEMPLATE'
|
||||
---
|
||||
name: SKILL_NAME_PLACEHOLDER
|
||||
description: This skill should be used when the user asks to "DESCRIPTION_HERE". Add specific trigger phrases that would activate this skill.
|
||||
license: MIT
|
||||
compatibility: opencode
|
||||
metadata:
|
||||
category: general
|
||||
version: "1.0.0"
|
||||
---
|
||||
|
||||
# SKILL_NAME_PLACEHOLDER
|
||||
|
||||
Brief description of what this skill does and its purpose.
|
||||
|
||||
## What This Skill Provides
|
||||
|
||||
1. **Feature 1** - Brief description
|
||||
2. **Feature 2** - Brief description
|
||||
3. **Feature 3** - Brief description
|
||||
|
||||
## Quick Start
|
||||
|
||||
Basic usage example:
|
||||
|
||||
```bash
|
||||
# Example command
|
||||
some-tool --option value
|
||||
```
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Task 1: Description
|
||||
|
||||
Step-by-step instructions:
|
||||
|
||||
1. First step
|
||||
2. Second step
|
||||
3. Third step
|
||||
|
||||
### Task 2: Description
|
||||
|
||||
Step-by-step instructions:
|
||||
|
||||
1. First step
|
||||
2. Second step
|
||||
|
||||
## Important Notes
|
||||
|
||||
- Keep this section brief
|
||||
- Use bullet points for clarity
|
||||
- Reference supporting files if available
|
||||
|
||||
## Resources
|
||||
|
||||
SKILL_TEMPLATE
|
||||
|
||||
# Add resource section if directories were created
|
||||
if [[ "$WITH_REFS" == true ]]; then
|
||||
cat >> "$TARGET_DIR/SKILL.md" << 'REF_SECTION'
|
||||
|
||||
### Reference Files
|
||||
|
||||
- `references/detailed-guide.md` - Detailed documentation
|
||||
|
||||
REF_SECTION
|
||||
fi
|
||||
|
||||
if [[ "$WITH_SCRIPTS" == true ]]; then
|
||||
cat >> "$TARGET_DIR/SKILL.md" << 'SCRIPT_SECTION'
|
||||
|
||||
### Scripts
|
||||
|
||||
- `scripts/helper.sh` - Utility script
|
||||
|
||||
SCRIPT_SECTION
|
||||
fi
|
||||
|
||||
if [[ "$WITH_ASSETS" == true ]]; then
|
||||
cat >> "$TARGET_DIR/SKILL.md" << 'ASSET_SECTION'
|
||||
|
||||
### Assets
|
||||
|
||||
- `assets/template.txt` - Template file
|
||||
|
||||
ASSET_SECTION
|
||||
fi
|
||||
|
||||
# Replace placeholder with actual skill name
|
||||
sed -i "s/SKILL_NAME_PLACEHOLDER/$SKILL_NAME/g" "$TARGET_DIR/SKILL.md"
|
||||
|
||||
# Create optional directories
|
||||
if [[ "$WITH_SCRIPTS" == true ]]; then
|
||||
mkdir -p "$TARGET_DIR/scripts"
|
||||
|
||||
# Create example script
|
||||
cat > "$TARGET_DIR/scripts/helper.sh" << 'SCRIPT_EXAMPLE'
|
||||
#!/bin/bash
|
||||
#
|
||||
# Helper script for SKILL_NAME_PLACEHOLDER
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "Helper script for SKILL_NAME_PLACEHOLDER"
|
||||
echo "Modify this script for your needs"
|
||||
SCRIPT_EXAMPLE
|
||||
|
||||
sed -i "s/SKILL_NAME_PLACEHOLDER/$SKILL_NAME/g" "$TARGET_DIR/scripts/helper.sh"
|
||||
chmod +x "$TARGET_DIR/scripts/helper.sh"
|
||||
|
||||
echo -e "${GREEN} ✓ Created scripts/ directory${NC}"
|
||||
fi
|
||||
|
||||
if [[ "$WITH_REFS" == true ]]; then
|
||||
mkdir -p "$TARGET_DIR/references"
|
||||
|
||||
# Create example reference
|
||||
cat > "$TARGET_DIR/references/detailed-guide.md" << 'REF_EXAMPLE'
|
||||
# Detailed Guide for SKILL_NAME_PLACEHOLDER
|
||||
|
||||
This file contains detailed documentation that can be referenced on-demand.
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
Detailed instructions go here...
|
||||
|
||||
## Configuration
|
||||
|
||||
Configuration options and examples...
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Common issues and solutions...
|
||||
REF_EXAMPLE
|
||||
|
||||
sed -i "s/SKILL_NAME_PLACEHOLDER/$SKILL_NAME/g" "$TARGET_DIR/references/detailed-guide.md"
|
||||
|
||||
echo -e "${GREEN} ✓ Created references/ directory${NC}"
|
||||
fi
|
||||
|
||||
if [[ "$WITH_ASSETS" == true ]]; then
|
||||
mkdir -p "$TARGET_DIR/assets"
|
||||
|
||||
# Create example asset
|
||||
cat > "$TARGET_DIR/assets/template.txt" << 'ASSET_EXAMPLE'
|
||||
# Template file for SKILL_NAME_PLACEHOLDER
|
||||
|
||||
This is a template file that can be used as a starting point.
|
||||
Modify it according to your needs.
|
||||
ASSET_EXAMPLE
|
||||
|
||||
sed -i "s/SKILL_NAME_PLACEHOLDER/$SKILL_NAME/g" "$TARGET_DIR/assets/template.txt"
|
||||
|
||||
echo -e "${GREEN} ✓ Created assets/ directory${NC}"
|
||||
fi
|
||||
|
||||
if [[ "$WITH_TESTS" == true ]]; then
|
||||
mkdir -p "$TARGET_DIR/evals"
|
||||
|
||||
# Create template evals.json
|
||||
cat > "$TARGET_DIR/evals/evals.json" << 'EVALS_TEMPLATE'
|
||||
{
|
||||
"skill_name": "SKILL_NAME_PLACEHOLDER",
|
||||
"evals": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "common-case",
|
||||
"prompt": "Typical user request with realistic context, file paths, and specific details. This represents the most common way users will ask for help.",
|
||||
"expected_output": "Description of what the skill should produce for this request",
|
||||
"assertions": [
|
||||
"Check that output contains specific expected content",
|
||||
"Verify file is created at expected location (if applicable)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "edge-case",
|
||||
"prompt": "Unusual or tricky scenario that tests edge cases, error handling, or complex requirements. Include something that might break the skill.",
|
||||
"expected_output": "Description of expected behavior for this edge case",
|
||||
"assertions": [
|
||||
"Verify edge case is handled appropriately",
|
||||
"Check for graceful error handling if applicable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "varied-phrasing",
|
||||
"prompt": "Same intent as the common case but expressed with different words, casual language, or alternative phrasing. Tests skill robustness to language variation.",
|
||||
"expected_output": "Same expected output as common case",
|
||||
"assertions": [
|
||||
"Output should match common case results",
|
||||
"Skill triggers correctly with different phrasing"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
EVALS_TEMPLATE
|
||||
|
||||
sed -i "s/SKILL_NAME_PLACEHOLDER/$SKILL_NAME/g" "$TARGET_DIR/evals/evals.json"
|
||||
|
||||
echo -e "${GREEN} ✓ Created evals/ directory with template evals.json${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ Skill '$SKILL_NAME' created successfully!${NC}"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Edit $TARGET_DIR/SKILL.md"
|
||||
echo " 2. Fill in the description with specific trigger phrases"
|
||||
echo " 3. Add your skill content"
|
||||
if [[ "$WITH_REFS" == true ]]; then
|
||||
echo " 4. Add detailed content to references/ files"
|
||||
fi
|
||||
if [[ "$WITH_SCRIPTS" == true ]]; then
|
||||
echo " 5. Implement scripts in scripts/ directory"
|
||||
fi
|
||||
if [[ "$WITH_TESTS" == true ]]; then
|
||||
echo " 6. Customize test cases in evals/evals.json"
|
||||
echo " 7. Run tests: ${SKILL_BUILDER_DIR}/scripts/run-tests.sh $TARGET_DIR"
|
||||
fi
|
||||
echo ""
|
||||
echo "Validate your skill:"
|
||||
echo " ${SKILL_BUILDER_DIR}/scripts/validate-skill.sh $TARGET_DIR"
|
||||
Reference in New Issue
Block a user