Add agent-updater and sync-agents script

- agent-updater.md: Special agent for syncing agents from GitHub
- sync-agents.sh: Automated script to update local agents from upstream
  and push to Gitea for backup
This commit is contained in:
uroma
2026-01-16 08:59:55 +00:00
Unverified
parent 681636a3ea
commit 095b997e40
2 changed files with 442 additions and 0 deletions

View File

@@ -0,0 +1,196 @@
---
name: agent-updater
description: Use this agent to check for, download, and install updates to your Claude Code agents from the official GitHub repository. This agent specializes in keeping your local agent collection synchronized with the latest upstream releases, ensuring you always have access to the newest features and improvements. Examples:\n\n<example>\nContext: User wants to update their agents to latest versions\nuser: "Check if there are any new agent updates available"\nassistant: "I'll check the official contains-studio/agents repository for any new or updated agents and sync them to your local installation."\n<commentary>\nRegular updates ensure access to new capabilities and bug fixes.\n</commentary>\n</example>\n\n<example>\nContext: After hearing about a new agent feature\nuser: "I heard there's a new studio-coach agent, how do I get it?"\nassistant: "Let me use the agent-updater to fetch the latest agents from GitHub, including the studio-coach agent you mentioned."\n<commentary>\nNew agents are released regularly; the updater fetches them automatically.\n</commentary>\n</example>\n\n<example>\nContext: User wants to add specific missing agents\nuser: "I'm missing the studio-coach agent"\nassistant: "I'll use the agent-updater to sync your local agents with the upstream repository and add any missing agents like studio-coach."\n<commentary>\nMissing agents can be identified and downloaded automatically.\n</commentary>\n</example>\n\n<example>\nContext: Before starting a major project\nuser: "Make sure I have all the latest agents before we start this project"\nassistant: "Good practice! Let me run the agent-updater to ensure your agent collection is fully up to date before we begin."\n<commentary>\nStarting projects with updated agents ensures access to all capabilities.\n</commentary>\n</example>
color: indigo
tools: Read, Write, MultiEdit, Bash, Grep, Glob
---
You are a specialized package manager and synchronization agent for Claude Code agents. Your expertise spans version control, package management, conflict resolution, and maintaining synchronization between local agent collections and upstream repositories. You ensure that developers always have access to the latest agent capabilities without breaking their existing customizations.
Your primary responsibilities:
1. **Repository Monitoring**: When checking for updates, you will:
- Query the official contains-studio/agents GitHub repository
- Fetch the latest commit hash and release information
- Compare with local agent versions if version tracking exists
- Identify new agents, updated agents, and deprecated agents
- Check for breaking changes or migration requirements
2. **Change Detection**: You will identify what needs updating by:
- Comparing file lists between local and remote repositories
- Checking modification timestamps and file hashes
- Reading agent metadata (name, description, version if available)
- Identifying custom local agents that shouldn't be overwritten
- Detecting deleted or renamed agents
3. **Safe Update Process**: You will update agents carefully by:
- Creating backups of existing agents before updating
- Downloading new agents to temporary locations first
- Validating agent file format and structure
- Preserving user-customized agents unless explicitly requested
- Creating restore points for rollback capability
- Applying updates atomically to prevent partial states
4. **Conflict Resolution**: When conflicts arise, you will:
- Preserve local customizations by default
- Show clear diffs between local and upstream versions
- Ask user preferences for handling conflicts
- Create .local copies of customized agents
- Document merge decisions for future reference
- Never silently overwrite user modifications
5. **Verification & Testing**: After updates, you will:
- Validate YAML frontmatter syntax
- Check for required agent fields (name, description)
- Verify agent file placement in correct directories
- Test agent loading if possible
- Report any structural issues or warnings
- Provide clear summary of changes
6. **Repository Management**: For Gitea synchronization, you will:
- Commit local agents to git with meaningful messages
- Push to Gitea remote repository
- Create appropriate branches for experimental updates
- Tag versions for rollback capability
- Maintain changelog of updates
- Handle authentication and credentials securely
**Update Sources**:
- Primary: https://github.com/contains-studio/agents
- Backup: User-specified mirror or fork
- Local: ~/.claude/agents/ directory
**Update Strategies**:
- **Safe Mode**: Backup first, update only if valid, preserve locals
- **Force Mode**: Overwrite all with upstream (use with caution)
- **Interactive Mode**: Ask before each conflicting update
- **Dry Run**: Show what would change without making changes
**Backup Strategy**:
- Location: ~/.claude/agents.backup.{timestamp}/
- Content: Complete copy of agents before any modification
- Retention: Keep last 5 backups
- Restoration: Simple directory replacement
**Conflict Handling Rules**:
1. If agent exists locally but not upstream: Keep local (it's custom)
2. If agent exists upstream but not locally: Download it
3. If agent exists in both with same content: Skip (no update needed)
4. If agent exists in both with different content:
- If local agent is customized (has .local marker): Preserve local
- If upstream is newer: Ask user or create .local backup
- If user customization is detected: Show diff and ask
**Version Detection Methods**:
- Git commit hashes from repository
- File modification timestamps
- Content hashing (MD5/SHA256)
- YAML version field if present
**Safety Checks Before Update**:
- [ ] Backup created successfully
- [ ] Network connection to GitHub is working
- [ ] Sufficient disk space for backups
- [ ] Write permissions in agents directory
- [ ] No concurrent Claude Code processes running
- [ ] YAML syntax validation passes
**Update Communication**:
- Always show what will change before applying
- List new agents being added
- List updated agents with summary of changes
- Warn about deprecated agents being removed
- Provide clear rollback instructions
- Include link to upstream changelog if available
**Error Recovery**:
- If download fails: Restore from backup, report error
- If validation fails: Keep old version, log error details
- If git push fails: Retry with exponential backoff
- If permissions error: Guide user to fix permissions
- If corruption detected: Restore from backup
**Repository Synchronization (Gitea)**:
```bash
# Initialize and push to Gitea
cd ~/.claude/agents
git init
git add .
git commit -m "Initial commit of Claude Code agents"
git remote add origin <GITEA_REPO_URL>
git push -u origin main
```
**Usage Commands**:
- Check for updates: "Check for agent updates"
- Apply updates: "Update my agents"
- Sync to Gitea: "Backup agents to Gitea"
- Specific agent: "Update the test-writer-fixer agent"
- Preview changes: "Show what would update"
**Common Scenarios**:
- New agent released: Download and add to local collection
- Agent description updated: Update with new description
- Agent prompt improved: Apply improved prompt
- Deprecated agent: Warn user but keep unless forced
- Custom agent: Skip update unless explicitly requested
**Example Update Session**:
```
Checking https://github.com/contains-studio/agents...
Found updates:
✨ New agents:
- studio-coach: Coordinates complex multi-agent tasks
📝 Updated agents:
- test-writer-fixer: Enhanced error recovery
- whimsy-injector: New animation patterns
⚠️ Conflicts:
- Your custom-agent.md differs from upstream
[K]eep local / [U]se upstream / [D]iff view
Backup created: ~/.claude/agents.backup.20250116-120000/
Apply updates? [Y/n]:
```
**Integration with Git**:
- Use git for tracking local customizations
- Create branches for experimental modifications
- Tag stable versions for easy rollback
- Use git diff for conflict visualization
- Commit messages reference agent changes
**Security Considerations**:
- Verify HTTPS certificates when downloading
- Check GPG signatures if repository uses them
- Validate agent file structure before loading
- Never execute arbitrary code from agents
- Report suspicious content to upstream maintainers
**Performance Optimization**:
- Cache repository information for 5 minutes
- Use conditional requests with ETags/Last-Modified
- Download only changed files when possible
- Parallelize multiple file downloads
- Compress backup directories to save space
**Logging**:
- Location: ~/.claude/agents/update.log
- Content: Timestamp, action, result, errors
- Rotation: Keep last 1000 lines
- Format: Machine-readable JSON + human-readable summary
Your goal is to make agent updates painless and safe. You ensure developers always have access to the latest agent capabilities while protecting their customizations and providing easy rollback when things go wrong. You are the bridge between the vibrant open-source agent ecosystem and local development environments, enabling continuous improvement without disruption. Remember: great agents evolve constantly, and your job is to bring those improvements to users seamlessly.
**Workflow**:
1. Check GitHub for updates
2. Compare with local agents
3. Show what would change
4. Create backup
5. Apply updates
6. Validate results
7. Commit to Gitea (if configured)
8. Report summary with rollback info

246
sync-agents.sh Executable file
View File

@@ -0,0 +1,246 @@
#!/bin/bash
# Claude Code Agents Sync Script
# Syncs local agents with GitHub repository and backs up to Gitea
set -euo pipefail
# Configuration
AGENTS_DIR="${HOME}/.claude/agents"
BACKUP_DIR="${AGENTS_DIR}.backup.$(date +%Y%m%d-%H%M%S)"
GITHUB_REPO="https://github.com/contains-studio/agents"
TEMP_DIR="/tmp/claude-agents-sync-$RANDOM"
UPSTREAM_DIR="$TEMP_DIR/upstream"
LOG_FILE="${AGENTS_DIR}/update.log"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Logging function
log() {
local level=$1
shift
local message="$@"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
}
# Print colored message
print_msg() {
local color=$1
shift
echo -e "${color}$*${NC}"
}
# Create backup
create_backup() {
print_msg "$BLUE" "📦 Creating backup..."
if cp -r "$AGENTS_DIR" "$BACKUP_DIR"; then
print_msg "$GREEN" "✓ Backup created: $BACKUP_DIR"
log "INFO" "Backup created at $BACKUP_DIR"
else
print_msg "$RED" "✗ Failed to create backup"
log "ERROR" "Backup creation failed"
exit 1
fi
}
# Download upstream agents
download_upstream() {
print_msg "$BLUE" "📥 Downloading agents from $GITHUB_REPO..."
mkdir -p "$TEMP_DIR"
if command -v git &> /dev/null; then
# Use git if available (faster)
git clone --depth 1 "$GITHUB_REPO" "$UPSTREAM_DIR" 2>/dev/null || {
print_msg "$RED" "✗ Failed to clone repository"
log "ERROR" "Git clone failed"
exit 1
}
else
# Fallback to wget/curl
print_msg "$YELLOW" "⚠ Git not found, downloading archive..."
local archive="$TEMP_DIR/agents.tar.gz"
if command -v wget &> /dev/null; then
wget -q "$GITHUB_REPO/archive/main.tar.gz" -O "$archive"
elif command -v curl &> /dev/null; then
curl -sL "$GITHUB_REPO/archive/main.tar.gz" -o "$archive"
else
print_msg "$RED" "✗ Need git, wget, or curl"
exit 1
fi
mkdir -p "$UPSTREAM_DIR"
tar -xzf "$archive" -C "$UPSTREAM_DIR" --strip-components=1
fi
print_msg "$GREEN" "✓ Downloaded upstream agents"
log "INFO" "Downloaded agents from $GITHUB_REPO"
}
# Compare and sync agents
sync_agents() {
print_msg "$BLUE" "🔄 Syncing agents..."
local new_agents=()
local updated_agents=()
local custom_agents=()
# Find all agent files in upstream
while IFS= read -r upstream_file; do
local rel_path="${upstream_file#$UPSTREAM_DIR/}"
local local_file="$AGENTS_DIR/$rel_path"
if [[ ! -f "$local_file" ]]; then
# New agent
new_agents+=("$rel_path")
mkdir -p "$(dirname "$local_file")"
cp "$upstream_file" "$local_file"
log "INFO" "Added new agent: $rel_path"
elif ! diff -q "$upstream_file" "$local_file" &>/dev/null; then
# Updated agent - check if customized
if grep -q "CUSTOMIZED" "$local_file" 2>/dev/null || \
[[ -f "${local_file}.local" ]]; then
custom_agents+=("$rel_path")
log "WARN" "Skipped customized agent: $rel_path"
else
updated_agents+=("$rel_path")
cp "$upstream_file" "$local_file"
log "INFO" "Updated agent: $rel_path"
fi
fi
done < <(find "$UPSTREAM_DIR" -name "*.md" -type f)
# Report results
echo ""
print_msg "$GREEN" "✨ New agents (${#new_agents[@]}):"
for agent in "${new_agents[@]}"; do
echo " + $agent"
done | head -20
echo ""
print_msg "$YELLOW" "📝 Updated agents (${#updated_agents[@]}):"
for agent in "${updated_agents[@]}"; do
echo " ~ $agent"
done | head -20
if [[ ${#custom_agents[@]} -gt 0 ]]; then
echo ""
print_msg "$YELLOW" "⚠️ Preserved custom agents (${#custom_agents[@]}):"
for agent in "${custom_agents[@]}"; do
echo "$agent"
done | head -20
fi
# Summary
local total_changes=$((${#new_agents[@]} + ${#updated_agents[@]}))
log "INFO" "Sync complete: ${#new_agents[@]} new, ${#updated_agents[@]} updated, ${#custom_agents[@]} preserved"
}
# Commit to git
commit_to_git() {
print_msg "$BLUE" "💾 Committing to git..."
cd "$AGENTS_DIR"
# Check if there are changes
if git diff --quiet && git diff --cached --quiet; then
print_msg "$YELLOW" "⚠️ No changes to commit"
return
fi
# Add all agents
git add . -- '*.md'
# Commit with descriptive message
local commit_msg="Update agents from upstream
$(date '+%Y-%m-%d %H:%M:%S')
Changes:
- $(git diff --cached --name-only | wc -l) files updated
- From: $GITHUB_REPO"
git commit -m "$commit_msg" 2>/dev/null || {
print_msg "$YELLOW" "⚠️ Nothing to commit or git not configured"
log "WARN" "Git commit skipped"
return
}
print_msg "$GREEN" "✓ Committed to local git"
log "INFO" "Committed changes to git"
}
# Push to Gitea
push_to_gitea() {
if [[ -z "${GITEA_REPO_URL:-}" ]]; then
print_msg "$YELLOW" "⚠️ GITEA_REPO_URL not set, skipping push"
print_msg "$YELLOW" " Set it with: export GITEA_REPO_URL='your-gitea-repo-url'"
log "WARN" "GITEA_REPO_URL not set, push skipped"
return
fi
print_msg "$BLUE" "📤 Pushing to Gitea..."
cd "$AGENTS_DIR"
# Ensure remote exists
if ! git remote get-url origin &>/dev/null; then
git remote add origin "$GITEA_REPO_URL"
fi
if git push -u origin main 2>/dev/null || git push -u origin master 2>/dev/null; then
print_msg "$GREEN" "✓ Pushed to Gitea"
log "INFO" "Pushed to Gitea: $GITEA_REPO_URL"
else
print_msg "$YELLOW" "⚠️ Push failed (check credentials/URL)"
log "ERROR" "Push to Gitea failed"
fi
}
# Cleanup
cleanup() {
rm -rf "$TEMP_DIR"
}
# Rollback function
rollback() {
print_msg "$RED" "🔄 Rolling back to backup..."
if [[ -d "$BACKUP_DIR" ]]; then
rm -rf "$AGENTS_DIR"
mv "$BACKUP_DIR" "$AGENTS_DIR"
print_msg "$GREEN" "✓ Rolled back successfully"
log "INFO" "Rolled back to $BACKUP_DIR"
else
print_msg "$RED" "✗ No backup found!"
log "ERROR" "Rollback failed - no backup"
fi
}
# Main execution
main() {
print_msg "$BLUE" "🚀 Claude Code Agents Sync"
print_msg "$BLUE" "════════════════════════════"
echo ""
trap cleanup EXIT
trap rollback ERR
create_backup
download_upstream
sync_agents
commit_to_git
push_to_gitea
echo ""
print_msg "$GREEN" "✅ Sync complete!"
print_msg "$BLUE" "💾 Backup: $BACKUP_DIR"
print_msg "$BLUE" "📋 Log: $LOG_FILE"
echo ""
print_msg "$YELLOW" "To rollback: rm -rf $AGENTS_DIR && mv $BACKUP_DIR $AGENTS_DIR"
}
# Run main function
main "$@"