- Add comprehensive documentation (README, WORKFLOW, DEPLOYMENT) - Add skill template for creating new skills - Port worklog skill from dotfiles (org-mode session documentation) - Port update-spec-kit skill from dotfiles (ecosystem updates) - Include spec-kit framework for structured development - Add OpenCode commands for spec-kit workflow integration Repository provides unified skill development for both Claude Code and OpenCode agents.
499 lines
10 KiB
Markdown
499 lines
10 KiB
Markdown
# Deployment Guide
|
|
|
|
This guide covers all deployment methods for skills to both Claude Code and OpenCode.
|
|
|
|
## Quick Reference
|
|
|
|
| Method | Use Case | Pros | Cons |
|
|
|--------|----------|------|------|
|
|
| Symlink | Active development | Live updates | Manual per-skill |
|
|
| Copy | Testing specific version | Isolated | Must re-copy for updates |
|
|
| Nix Home Manager | Production (NixOS) | Declarative, versioned | Requires rebuild |
|
|
| Git Submodule | Multi-repo sharing | Centralized updates | More complexity |
|
|
|
|
## Method 1: Symlink Deployment (Development)
|
|
|
|
Best for active development - changes in repo immediately available to agent.
|
|
|
|
### Claude Code
|
|
|
|
```bash
|
|
# Single skill
|
|
ln -s $(pwd)/skills/worklog ~/.claude/skills/worklog
|
|
|
|
# All skills
|
|
for skill in skills/*/; do
|
|
skill_name=$(basename "$skill")
|
|
if [ "$skill_name" != "template" ]; then
|
|
ln -s "$(pwd)/skills/$skill_name" ~/.claude/skills/$skill_name
|
|
fi
|
|
done
|
|
```
|
|
|
|
### OpenCode
|
|
|
|
```bash
|
|
# Single skill
|
|
ln -s $(pwd)/skills/worklog ~/.config/opencode/skills/worklog
|
|
|
|
# All skills
|
|
for skill in skills/*/; do
|
|
skill_name=$(basename "$skill")
|
|
if [ "$skill_name" != "template" ]; then
|
|
ln -s "$(pwd)/skills/$skill_name" ~/.config/opencode/skills/$skill_name
|
|
fi
|
|
done
|
|
```
|
|
|
|
### Verify Symlinks
|
|
|
|
```bash
|
|
# Claude Code
|
|
ls -la ~/.claude/skills/
|
|
|
|
# OpenCode
|
|
ls -la ~/.config/opencode/skills/
|
|
```
|
|
|
|
### Remove Symlinks
|
|
|
|
```bash
|
|
# Claude Code - single skill
|
|
rm ~/.claude/skills/worklog
|
|
|
|
# OpenCode - all skills (keeps directories, removes symlinks)
|
|
find ~/.config/opencode/skills -type l -delete
|
|
```
|
|
|
|
## Method 2: Copy Deployment (Testing)
|
|
|
|
Best for testing specific versions without affecting your main deployment.
|
|
|
|
### Claude Code
|
|
|
|
```bash
|
|
# Single skill
|
|
cp -r skills/worklog ~/.claude/skills/
|
|
|
|
# All skills (excluding template)
|
|
for skill in skills/*/; do
|
|
skill_name=$(basename "$skill")
|
|
if [ "$skill_name" != "template" ]; then
|
|
cp -r "skills/$skill_name" ~/.claude/skills/
|
|
fi
|
|
done
|
|
```
|
|
|
|
### OpenCode
|
|
|
|
```bash
|
|
# Single skill
|
|
cp -r skills/worklog ~/.config/opencode/skills/
|
|
|
|
# All skills (excluding template)
|
|
for skill in skills/*/; do
|
|
skill_name=$(basename "$skill")
|
|
if [ "$skill_name" != "template" ]; then
|
|
cp -r "skills/$skill_name" ~/.config/opencode/skills/
|
|
fi
|
|
done
|
|
```
|
|
|
|
### Update After Changes
|
|
|
|
```bash
|
|
# Must re-copy after making changes
|
|
cp -r skills/worklog ~/.claude/skills/
|
|
cp -r skills/worklog ~/.config/opencode/skills/
|
|
```
|
|
|
|
## Method 3: Nix Home Manager (Production)
|
|
|
|
Best for NixOS users - declarative, version-controlled, atomic deployments.
|
|
|
|
### Configuration
|
|
|
|
Add to your `home.nix` or equivalent:
|
|
|
|
```nix
|
|
{ config, pkgs, ... }:
|
|
|
|
{
|
|
# Claude Code skills
|
|
home.file.".claude/skills/worklog" = {
|
|
source = /home/user/proj/skills/skills/worklog;
|
|
recursive = true;
|
|
};
|
|
|
|
home.file.".claude/skills/update-spec-kit" = {
|
|
source = /home/user/proj/skills/skills/update-spec-kit;
|
|
recursive = true;
|
|
};
|
|
|
|
# OpenCode skills
|
|
home.file.".config/opencode/skills/worklog" = {
|
|
source = /home/user/proj/skills/skills/worklog;
|
|
recursive = true;
|
|
};
|
|
|
|
home.file.".config/opencode/skills/update-spec-kit" = {
|
|
source = /home/user/proj/skills/skills/update-spec-kit;
|
|
recursive = true;
|
|
};
|
|
|
|
# OpenCode plugin configuration
|
|
home.file.".config/opencode/config.json".text = builtins.toJSON {
|
|
plugin = [ "opencode-skills" ];
|
|
# ... other config
|
|
};
|
|
}
|
|
```
|
|
|
|
### Deploy All Skills Programmatically
|
|
|
|
For many skills, use a loop:
|
|
|
|
```nix
|
|
{ config, pkgs, lib, ... }:
|
|
|
|
let
|
|
skillsPath = /home/user/proj/skills/skills;
|
|
|
|
# List of skills to deploy (exclude template)
|
|
skills = [
|
|
"worklog"
|
|
"update-spec-kit"
|
|
# Add more skills here
|
|
];
|
|
|
|
# Generate home.file entries for a skill
|
|
mkSkillDeployment = skillName: {
|
|
".claude/skills/${skillName}" = {
|
|
source = "${skillsPath}/${skillName}";
|
|
recursive = true;
|
|
};
|
|
".config/opencode/skills/${skillName}" = {
|
|
source = "${skillsPath}/${skillName}";
|
|
recursive = true;
|
|
};
|
|
};
|
|
|
|
# Merge all skill deployments
|
|
allSkillDeployments = lib.foldl' (acc: skill: acc // (mkSkillDeployment skill)) {} skills;
|
|
|
|
in {
|
|
home.file = allSkillDeployments // {
|
|
# Other file configurations
|
|
".config/opencode/config.json".text = builtins.toJSON {
|
|
plugin = [ "opencode-skills" ];
|
|
};
|
|
};
|
|
}
|
|
```
|
|
|
|
### Apply Configuration
|
|
|
|
```bash
|
|
# Home Manager standalone
|
|
home-manager switch
|
|
|
|
# NixOS with flake
|
|
sudo nixos-rebuild switch --flake .#hostname
|
|
|
|
# Test first
|
|
sudo nixos-rebuild test --flake .#hostname
|
|
```
|
|
|
|
### Rollback
|
|
|
|
```bash
|
|
# Home Manager
|
|
home-manager generations
|
|
home-manager switch --rollback
|
|
|
|
# NixOS
|
|
sudo nixos-rebuild switch --rollback
|
|
```
|
|
|
|
## Method 4: Git Submodule (Shared Projects)
|
|
|
|
Best when multiple repositories need to share the same skills.
|
|
|
|
### Setup in Target Repository
|
|
|
|
```bash
|
|
# In your project repository
|
|
cd ~/proj/my-project
|
|
|
|
# Add skills as submodule
|
|
git submodule add https://github.com/yourusername/skills.git .skills
|
|
|
|
# Initialize submodule
|
|
git submodule update --init --recursive
|
|
```
|
|
|
|
### Deploy from Submodule
|
|
|
|
```bash
|
|
# Create deployment script: scripts/deploy-skills.sh
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SKILLS_DIR=".skills/skills"
|
|
|
|
# Deploy to Claude Code
|
|
for skill in "$SKILLS_DIR"/*; do
|
|
skill_name=$(basename "$skill")
|
|
if [ "$skill_name" != "template" ]; then
|
|
ln -sf "$(realpath "$skill")" ~/.claude/skills/"$skill_name"
|
|
fi
|
|
done
|
|
|
|
# Deploy to OpenCode
|
|
for skill in "$SKILLS_DIR"/*; do
|
|
skill_name=$(basename "$skill")
|
|
if [ "$skill_name" != "template" ]; then
|
|
ln -sf "$(realpath "$skill")" ~/.config/opencode/skills/"$skill_name"
|
|
fi
|
|
done
|
|
|
|
echo "Skills deployed from submodule"
|
|
```
|
|
|
|
### Update Submodule
|
|
|
|
```bash
|
|
# Update to latest
|
|
git submodule update --remote .skills
|
|
|
|
# Or specific commit
|
|
cd .skills
|
|
git checkout main
|
|
git pull
|
|
cd ..
|
|
git add .skills
|
|
git commit -m "Update skills submodule"
|
|
```
|
|
|
|
## OpenCode Plugin Setup
|
|
|
|
OpenCode requires the `opencode-skills` plugin to discover skills.
|
|
|
|
### Manual Installation
|
|
|
|
```bash
|
|
# Edit OpenCode config
|
|
vim ~/.config/opencode/config.json
|
|
```
|
|
|
|
Add plugin:
|
|
```json
|
|
{
|
|
"plugin": ["opencode-skills"],
|
|
"other-settings": "..."
|
|
}
|
|
```
|
|
|
|
### Verify Plugin Loaded
|
|
|
|
```bash
|
|
# Start OpenCode and check for skills in output
|
|
opencode
|
|
|
|
# Or check logs for plugin loading
|
|
# (Plugin installation happens on first start after config change)
|
|
```
|
|
|
|
### Nix Configuration
|
|
|
|
```nix
|
|
home.file.".config/opencode/config.json".text = builtins.toJSON {
|
|
plugin = [ "opencode-skills" ];
|
|
};
|
|
```
|
|
|
|
## Verification
|
|
|
|
### Check Deployment
|
|
|
|
```bash
|
|
# Claude Code
|
|
ls -la ~/.claude/skills/
|
|
cat ~/.claude/skills/worklog/SKILL.md | head -5
|
|
|
|
# OpenCode
|
|
ls -la ~/.config/opencode/skills/
|
|
cat ~/.config/opencode/skills/worklog/SKILL.md | head -5
|
|
```
|
|
|
|
### Test Skill Discovery
|
|
|
|
**Claude Code:**
|
|
```bash
|
|
# Start Claude Code
|
|
claude
|
|
|
|
# In chat, try triggering a skill
|
|
# Example: "Create a worklog"
|
|
```
|
|
|
|
**OpenCode:**
|
|
```bash
|
|
# Start OpenCode
|
|
opencode
|
|
|
|
# In chat, try triggering a skill
|
|
# Example: "Document today's work"
|
|
```
|
|
|
|
### Debug Discovery Issues
|
|
|
|
**Claude Code:**
|
|
- Check SKILL.md frontmatter is valid YAML
|
|
- Verify file permissions are readable
|
|
- Restart Claude Code
|
|
- Check Claude logs (if available)
|
|
|
|
**OpenCode:**
|
|
- Verify opencode-skills plugin is installed
|
|
- Check plugin loaded at startup
|
|
- Restart OpenCode after config changes
|
|
- Check SKILL.md frontmatter
|
|
|
|
## Multi-Environment Deployment
|
|
|
|
Deploy same skills to multiple machines.
|
|
|
|
### Using Dotfiles Repository
|
|
|
|
```bash
|
|
# In your dotfiles repo
|
|
mkdir -p skills
|
|
cd skills
|
|
git submodule add https://github.com/yourusername/skills.git
|
|
|
|
# Create deployment script in dotfiles
|
|
cat > scripts/deploy-skills.sh << 'EOF'
|
|
#!/usr/bin/env bash
|
|
for skill in skills/skills/*; do
|
|
skill_name=$(basename "$skill")
|
|
[ "$skill_name" = "template" ] && continue
|
|
|
|
ln -sf "$(realpath "$skill")" ~/.claude/skills/"$skill_name"
|
|
ln -sf "$(realpath "$skill")" ~/.config/opencode/skills/"$skill_name"
|
|
done
|
|
EOF
|
|
|
|
chmod +x scripts/deploy-skills.sh
|
|
```
|
|
|
|
### Using Configuration Management
|
|
|
|
**Ansible example:**
|
|
```yaml
|
|
- name: Deploy agentic skills
|
|
file:
|
|
src: "{{ playbook_dir }}/skills/{{ item }}"
|
|
dest: "~/.claude/skills/{{ item }}"
|
|
state: link
|
|
loop:
|
|
- worklog
|
|
- update-spec-kit
|
|
```
|
|
|
|
## Cleanup
|
|
|
|
### Remove All Skills
|
|
|
|
```bash
|
|
# Claude Code
|
|
rm -rf ~/.claude/skills/*
|
|
|
|
# OpenCode
|
|
rm -rf ~/.config/opencode/skills/*
|
|
```
|
|
|
|
### Remove Specific Skill
|
|
|
|
```bash
|
|
# Claude Code
|
|
rm -rf ~/.claude/skills/worklog
|
|
|
|
# OpenCode
|
|
rm -rf ~/.config/opencode/skills/worklog
|
|
```
|
|
|
|
### Nix Cleanup
|
|
|
|
Remove from `home.nix` and rebuild:
|
|
```bash
|
|
# Edit home.nix to remove skill entries
|
|
vim home.nix
|
|
|
|
# Rebuild
|
|
home-manager switch
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Symlink Target Not Found
|
|
|
|
```bash
|
|
# Check symlink
|
|
ls -la ~/.claude/skills/worklog
|
|
|
|
# If broken, recreate
|
|
rm ~/.claude/skills/worklog
|
|
ln -s $(pwd)/skills/worklog ~/.claude/skills/worklog
|
|
```
|
|
|
|
### Permission Denied
|
|
|
|
```bash
|
|
# Fix permissions on scripts
|
|
chmod +x skills/*/scripts/*.sh
|
|
|
|
# Fix ownership
|
|
chown -R $USER:$USER skills/
|
|
```
|
|
|
|
### Skills Not Updating (Nix)
|
|
|
|
```bash
|
|
# Nix copies files, doesn't symlink by default
|
|
# Changes to source won't appear until rebuild
|
|
sudo nixos-rebuild switch --flake .#hostname
|
|
```
|
|
|
|
### OpenCode Plugin Not Loading
|
|
|
|
```bash
|
|
# Check config
|
|
cat ~/.config/opencode/config.json | jq .plugin
|
|
|
|
# Ensure valid JSON
|
|
jq . ~/.config/opencode/config.json
|
|
|
|
# Restart OpenCode
|
|
pkill opencode
|
|
opencode
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Development**: Use symlinks for instant updates
|
|
2. **Testing**: Use copies to test specific versions
|
|
3. **Production**: Use Nix for declarative, atomic deployments
|
|
4. **Multi-machine**: Use git submodules or dotfiles
|
|
5. **Version Control**: Always commit before deploying
|
|
6. **Documentation**: Keep deployment notes in project README
|
|
7. **Rollback Plan**: Know how to revert (especially for Nix)
|
|
|
|
## See Also
|
|
|
|
- [README.md](./README.md) - Repository overview
|
|
- [WORKFLOW.md](./WORKFLOW.md) - Development workflow
|
|
- [Nix Home Manager Manual](https://nix-community.github.io/home-manager/)
|
|
- [Claude Code Documentation](https://docs.claude.com/en/docs/claude-code)
|
|
- [OpenCode Skills Plugin](https://github.com/opencode-ai/opencode-skills)
|