Browse Source

fix: simplify registration script to preserve manual registry

- Replace complex auto-scanning with simple validation script
- Prevents registry from being emptied by buggy scan functions
- Auto-scanning feature can be added later after more testing
- Registry now stays intact and works correctly
darrenhinde 4 months ago
parent
commit
3ab70d24a9
2 changed files with 179 additions and 379 deletions
  1. 133 28
      registry.json
  2. 46 351
      scripts/register-component.sh

+ 133 - 28
registry.json

@@ -9,7 +9,11 @@
         "type": "agent",
         "path": ".opencode/agent/task-manager.md",
         "description": "Breaks down complex features into small, verifiable subtasks",
-        "tags": ["planning", "organization", "task-management"],
+        "tags": [
+          "planning",
+          "organization",
+          "task-management"
+        ],
         "dependencies": [],
         "category": "core"
       },
@@ -19,7 +23,11 @@
         "type": "agent",
         "path": ".opencode/agent/codebase-agent.md",
         "description": "Analyzes codebase patterns and architecture",
-        "tags": ["analysis", "architecture", "patterns"],
+        "tags": [
+          "analysis",
+          "architecture",
+          "patterns"
+        ],
         "dependencies": [],
         "category": "core"
       },
@@ -29,8 +37,14 @@
         "type": "agent",
         "path": ".opencode/agent/image-specialist.md",
         "description": "Generates and edits images using Gemini AI",
-        "tags": ["images", "ai", "generation"],
-        "dependencies": ["tool:gemini"],
+        "tags": [
+          "images",
+          "ai",
+          "generation"
+        ],
+        "dependencies": [
+          "tool:gemini"
+        ],
         "category": "extended"
       },
       {
@@ -39,7 +53,11 @@
         "type": "agent",
         "path": ".opencode/agent/workflow-orchestrator.md",
         "description": "Orchestrates complex multi-agent workflows",
-        "tags": ["orchestration", "workflow", "automation"],
+        "tags": [
+          "orchestration",
+          "workflow",
+          "automation"
+        ],
         "dependencies": [],
         "category": "extended"
       }
@@ -51,7 +69,11 @@
         "type": "subagent",
         "path": ".opencode/agent/subagents/reviewer.md",
         "description": "Performs code review with security and quality checks",
-        "tags": ["review", "security", "quality"],
+        "tags": [
+          "review",
+          "security",
+          "quality"
+        ],
         "dependencies": [],
         "category": "core"
       },
@@ -61,7 +83,11 @@
         "type": "subagent",
         "path": ".opencode/agent/subagents/tester.md",
         "description": "Writes unit and integration tests",
-        "tags": ["testing", "tdd", "quality"],
+        "tags": [
+          "testing",
+          "tdd",
+          "quality"
+        ],
         "dependencies": [],
         "category": "core"
       },
@@ -71,7 +97,11 @@
         "type": "subagent",
         "path": ".opencode/agent/subagents/documentation.md",
         "description": "Creates and updates documentation",
-        "tags": ["docs", "documentation", "writing"],
+        "tags": [
+          "docs",
+          "documentation",
+          "writing"
+        ],
         "dependencies": [],
         "category": "core"
       },
@@ -81,7 +111,11 @@
         "type": "subagent",
         "path": ".opencode/agent/subagents/coder-agent.md",
         "description": "Executes coding subtasks in sequence",
-        "tags": ["coding", "implementation", "execution"],
+        "tags": [
+          "coding",
+          "implementation",
+          "execution"
+        ],
         "dependencies": [],
         "category": "core"
       },
@@ -91,7 +125,11 @@
         "type": "subagent",
         "path": ".opencode/agent/subagents/build-agent.md",
         "description": "Type checks and validates builds",
-        "tags": ["build", "validation", "type-checking"],
+        "tags": [
+          "build",
+          "validation",
+          "type-checking"
+        ],
         "dependencies": [],
         "category": "core"
       },
@@ -101,7 +139,11 @@
         "type": "subagent",
         "path": ".opencode/agent/subagents/codebase-pattern-analyst.md",
         "description": "Analyzes and implements codebase patterns",
-        "tags": ["patterns", "analysis", "architecture"],
+        "tags": [
+          "patterns",
+          "analysis",
+          "architecture"
+        ],
         "dependencies": [],
         "category": "extended"
       }
@@ -113,7 +155,11 @@
         "type": "command",
         "path": ".opencode/command/test.md",
         "description": "Run the complete testing pipeline",
-        "tags": ["testing", "ci", "validation"],
+        "tags": [
+          "testing",
+          "ci",
+          "validation"
+        ],
         "dependencies": [],
         "category": "core"
       },
@@ -123,7 +169,11 @@
         "type": "command",
         "path": ".opencode/command/commit.md",
         "description": "Create intelligent git commits with context",
-        "tags": ["git", "commit", "version-control"],
+        "tags": [
+          "git",
+          "commit",
+          "version-control"
+        ],
         "dependencies": [],
         "category": "core"
       },
@@ -133,7 +183,11 @@
         "type": "command",
         "path": ".opencode/command/context.md",
         "description": "Manage project context and documentation",
-        "tags": ["context", "documentation", "management"],
+        "tags": [
+          "context",
+          "documentation",
+          "management"
+        ],
         "dependencies": [],
         "category": "core"
       },
@@ -143,7 +197,11 @@
         "type": "command",
         "path": ".opencode/command/clean.md",
         "description": "Clean build artifacts and temporary files",
-        "tags": ["cleanup", "maintenance", "build"],
+        "tags": [
+          "cleanup",
+          "maintenance",
+          "build"
+        ],
         "dependencies": [],
         "category": "extended"
       },
@@ -153,7 +211,11 @@
         "type": "command",
         "path": ".opencode/command/optimize.md",
         "description": "Optimize code performance and bundle size",
-        "tags": ["optimization", "performance", "build"],
+        "tags": [
+          "optimization",
+          "performance",
+          "build"
+        ],
         "dependencies": [],
         "category": "extended"
       },
@@ -163,7 +225,11 @@
         "type": "command",
         "path": ".opencode/command/prompt-enchancer.md",
         "description": "Enhance and improve AI prompts",
-        "tags": ["prompts", "ai", "enhancement"],
+        "tags": [
+          "prompts",
+          "ai",
+          "enhancement"
+        ],
         "dependencies": [],
         "category": "extended"
       },
@@ -173,7 +239,11 @@
         "type": "command",
         "path": ".opencode/command/worktrees.md",
         "description": "Manage git worktrees for parallel development",
-        "tags": ["git", "worktrees", "workflow"],
+        "tags": [
+          "git",
+          "worktrees",
+          "workflow"
+        ],
         "dependencies": [],
         "category": "advanced"
       }
@@ -185,8 +255,14 @@
         "type": "tool",
         "path": ".opencode/tool/gemini/index.ts",
         "description": "Image generation, editing, and analysis using Gemini AI",
-        "tags": ["ai", "images", "gemini"],
-        "dependencies": ["tool:env"],
+        "tags": [
+          "ai",
+          "images",
+          "gemini"
+        ],
+        "dependencies": [
+          "tool:env"
+        ],
         "category": "extended"
       },
       {
@@ -195,7 +271,11 @@
         "type": "tool",
         "path": ".opencode/tool/env/index.ts",
         "description": "Load and manage environment variables securely",
-        "tags": ["environment", "config", "security"],
+        "tags": [
+          "environment",
+          "config",
+          "security"
+        ],
         "dependencies": [],
         "category": "core"
       }
@@ -207,8 +287,14 @@
         "type": "plugin",
         "path": ".opencode/plugin/telegram-notify.ts",
         "description": "Send notifications via Telegram bot",
-        "tags": ["notifications", "telegram", "integration"],
-        "dependencies": ["tool:env"],
+        "tags": [
+          "notifications",
+          "telegram",
+          "integration"
+        ],
+        "dependencies": [
+          "tool:env"
+        ],
         "category": "extended"
       },
       {
@@ -217,7 +303,10 @@
         "type": "plugin",
         "path": ".opencode/plugin/notify.ts",
         "description": "Generic notification system",
-        "tags": ["notifications", "alerts"],
+        "tags": [
+          "notifications",
+          "alerts"
+        ],
         "dependencies": [],
         "category": "extended"
       }
@@ -229,7 +318,11 @@
         "type": "context",
         "path": ".opencode/context/core/essential-patterns.md",
         "description": "Core development patterns and best practices",
-        "tags": ["patterns", "best-practices", "guidelines"],
+        "tags": [
+          "patterns",
+          "best-practices",
+          "guidelines"
+        ],
         "dependencies": [],
         "category": "core"
       },
@@ -239,7 +332,11 @@
         "type": "context",
         "path": ".opencode/context/project/project-context.md",
         "description": "Project-specific context and configuration",
-        "tags": ["context", "project", "configuration"],
+        "tags": [
+          "context",
+          "project",
+          "configuration"
+        ],
         "dependencies": [],
         "category": "core"
       }
@@ -251,7 +348,11 @@
         "type": "config",
         "path": "env.example",
         "description": "Example environment configuration file",
-        "tags": ["config", "environment", "template"],
+        "tags": [
+          "config",
+          "environment",
+          "template"
+        ],
         "dependencies": [],
         "category": "core"
       },
@@ -261,7 +362,11 @@
         "type": "config",
         "path": "README.md",
         "description": "Project documentation and setup guide",
-        "tags": ["documentation", "readme", "guide"],
+        "tags": [
+          "documentation",
+          "readme",
+          "guide"
+        ],
         "dependencies": [],
         "category": "core"
       }

+ 46 - 351
scripts/register-component.sh

@@ -1,364 +1,59 @@
 #!/usr/bin/env bash
 
 #############################################################################
-# Component Registration Script
-# Automatically scans .opencode/ and updates registry.json
+# Component Registration Script - SIMPLIFIED VERSION
+# Just preserves the manually created registry.json
+# Auto-scanning can be added later after more testing
 #############################################################################
 
 set -e
 
 # Colors
-RED='\033[0;31m'
 GREEN='\033[0;32m'
-YELLOW='\033[1;33m'
-BLUE='\033[0;34m'
 CYAN='\033[0;36m'
 BOLD='\033[1m'
 NC='\033[0m'
 
-# Configuration
-OPENCODE_DIR=".opencode"
-REGISTRY_FILE="registry.json"
-TEMP_REGISTRY="/tmp/registry-temp-$$.json"
-
-print_success() { echo -e "${GREEN}✓${NC} $1"; }
-print_error() { echo -e "${RED}✗${NC} $1"; }
-print_info() { echo -e "${BLUE}ℹ${NC} $1"; }
-print_warning() { echo -e "${YELLOW}⚠${NC} $1"; }
-print_step() { echo -e "\n${CYAN}${BOLD}▶${NC} $1\n"; }
-
-#############################################################################
-# Validation
-#############################################################################
-
-check_dependencies() {
-    if ! command -v jq &> /dev/null; then
-        print_error "jq is required but not installed"
-        echo "Install with: brew install jq (macOS) or apt-get install jq (Linux)"
-        exit 1
-    fi
-}
-
-validate_registry() {
-    if [ ! -f "$REGISTRY_FILE" ]; then
-        print_error "Registry file not found: $REGISTRY_FILE"
-        exit 1
-    fi
-    
-    if ! jq empty "$REGISTRY_FILE" 2>/dev/null; then
-        print_error "Invalid JSON in registry file"
-        exit 1
-    fi
-}
-
-#############################################################################
-# Component Discovery
-#############################################################################
-
-extract_frontmatter() {
-    local file=$1
-    local field=$2
-    
-    # Extract YAML frontmatter between --- markers
-    awk -v field="$field" '
-        BEGIN { in_fm=0; }
-        /^---$/ { 
-            if (in_fm == 0) { in_fm=1; next; }
-            else { exit; }
-        }
-        in_fm && $0 ~ "^" field ":" {
-            sub("^" field ": *", "");
-            gsub(/^["\047]|["\047]$/, "");
-            print;
-            exit;
-        }
-    ' "$file"
-}
-
-scan_agents() {
-    print_step "Scanning agents..."
-    
-    local json_array="[]"
-    
-    while IFS= read -r -d '' file; do
-        local id=$(basename "$file" .md)
-        local name=$(extract_frontmatter "$file" "name")
-        local desc=$(extract_frontmatter "$file" "description")
-        
-        # Use defaults if not found in frontmatter
-        [ -z "$name" ] && name=$(echo "$id" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')
-        [ -z "$desc" ] && desc="Agent: $name"
-        
-        local path="${file#./}"
-        
-        # Build JSON using jq
-        json_array=$(echo "$json_array" | jq \
-            --arg id "$id" \
-            --arg name "$name" \
-            --arg path "$path" \
-            --arg desc "$desc" \
-            '. += [{
-                "id": $id,
-                "name": $name,
-                "type": "agent",
-                "path": $path,
-                "description": $desc,
-                "tags": [],
-                "dependencies": [],
-                "category": "core"
-            }]')
-        
-        print_info "Found agent: $id"
-    done < <(find "$OPENCODE_DIR/agent" -maxdepth 1 -name "*.md" -type f -print0 2>/dev/null)
-    
-    echo "$json_array"
-}
-
-scan_subagents() {
-    print_step "Scanning subagents..."
-    
-    local subagents=()
-    
-    while IFS= read -r -d '' file; do
-        local id=$(basename "$file" .md)
-        local name=$(extract_frontmatter "$file" "name")
-        local desc=$(extract_frontmatter "$file" "description")
-        
-        [ -z "$name" ] && name=$(echo "$id" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')
-        [ -z "$desc" ] && desc="Subagent: $name"
-        
-        local path="${file#./}"
-        
-        subagents+=("{\"id\":\"$id\",\"name\":\"$name\",\"type\":\"subagent\",\"path\":\"$path\",\"description\":\"$desc\",\"tags\":[],\"dependencies\":[],\"category\":\"core\"}")
-        
-        print_info "Found subagent: $id"
-    done < <(find "$OPENCODE_DIR/agent/subagents" -name "*.md" -type f -print0 2>/dev/null)
-    
-    if [ ${#subagents[@]} -gt 0 ]; then
-        echo "[$(IFS=,; echo "${subagents[*]}")]"
-    else
-        echo "[]"
-    fi
-}
-
-scan_commands() {
-    print_step "Scanning commands..."
-    
-    local commands=()
-    
-    while IFS= read -r -d '' file; do
-        local id=$(basename "$file" .md)
-        local name=$(extract_frontmatter "$file" "name")
-        local desc=$(extract_frontmatter "$file" "description")
-        
-        [ -z "$name" ] && name=$(echo "$id" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')
-        [ -z "$desc" ] && desc="Command: $name"
-        
-        local path="${file#./}"
-        
-        commands+=("{\"id\":\"$id\",\"name\":\"$name\",\"type\":\"command\",\"path\":\"$path\",\"description\":\"$desc\",\"tags\":[],\"dependencies\":[],\"category\":\"core\"}")
-        
-        print_info "Found command: $id"
-    done < <(find "$OPENCODE_DIR/command" -name "*.md" -type f -print0 2>/dev/null)
-    
-    if [ ${#commands[@]} -gt 0 ]; then
-        echo "[$(IFS=,; echo "${commands[*]}")]"
-    else
-        echo "[]"
-    fi
-}
-
-scan_tools() {
-    print_step "Scanning tools..."
-    
-    local tools=()
-    
-    # Look for directories with index.ts
-    while IFS= read -r -d '' dir; do
-        local id=$(basename "$dir")
-        
-        # Skip node_modules and template
-        [[ "$id" == "node_modules" || "$id" == "template" ]] && continue
-        
-        local index_file="$dir/index.ts"
-        [ ! -f "$index_file" ] && continue
-        
-        local name=$(echo "$id" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')
-        local desc="Tool: $name"
-        
-        # Try to extract description from comments
-        local comment_desc=$(grep -m 1 "^\s*\*.*" "$index_file" | sed 's/^\s*\*\s*//' || echo "")
-        [ -n "$comment_desc" ] && desc="$comment_desc"
-        
-        local path="${index_file#./}"
-        
-        tools+=("{\"id\":\"$id\",\"name\":\"$name\",\"type\":\"tool\",\"path\":\"$path\",\"description\":\"$desc\",\"tags\":[],\"dependencies\":[],\"category\":\"core\"}")
-        
-        print_info "Found tool: $id"
-    done < <(find "$OPENCODE_DIR/tool" -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null)
-    
-    if [ ${#tools[@]} -gt 0 ]; then
-        echo "[$(IFS=,; echo "${tools[*]}")]"
-    else
-        echo "[]"
-    fi
-}
-
-scan_plugins() {
-    print_step "Scanning plugins..."
-    
-    local plugins=()
-    
-    while IFS= read -r -d '' file; do
-        local id=$(basename "$file" .ts)
-        
-        # Skip lib directory files
-        [[ "$file" == *"/lib/"* ]] && continue
-        
-        local name=$(echo "$id" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')
-        local desc="Plugin: $name"
-        
-        # Try to extract description from comments
-        local comment_desc=$(grep -m 1 "^\s*\*.*" "$file" | sed 's/^\s*\*\s*//' || echo "")
-        [ -n "$comment_desc" ] && desc="$comment_desc"
-        
-        local path="${file#./}"
-        
-        plugins+=("{\"id\":\"$id\",\"name\":\"$name\",\"type\":\"plugin\",\"path\":\"$path\",\"description\":\"$desc\",\"tags\":[],\"dependencies\":[],\"category\":\"extended\"}")
-        
-        print_info "Found plugin: $id"
-    done < <(find "$OPENCODE_DIR/plugin" -maxdepth 1 -name "*.ts" -type f -print0 2>/dev/null)
-    
-    if [ ${#plugins[@]} -gt 0 ]; then
-        echo "[$(IFS=,; echo "${plugins[*]}")]"
-    else
-        echo "[]"
-    fi
-}
-
-scan_contexts() {
-    print_step "Scanning contexts..."
-    
-    local contexts=()
-    
-    while IFS= read -r -d '' file; do
-        local id=$(basename "$file" .md)
-        local name=$(extract_frontmatter "$file" "name")
-        local desc=$(extract_frontmatter "$file" "description")
-        
-        [ -z "$name" ] && name=$(echo "$id" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')
-        [ -z "$desc" ] && desc="Context: $name"
-        
-        local path="${file#./}"
-        
-        contexts+=("{\"id\":\"$id\",\"name\":\"$name\",\"type\":\"context\",\"path\":\"$path\",\"description\":\"$desc\",\"tags\":[],\"dependencies\":[],\"category\":\"core\"}")
-        
-        print_info "Found context: $id"
-    done < <(find "$OPENCODE_DIR/context" -name "*.md" -type f -print0 2>/dev/null)
-    
-    if [ ${#contexts[@]} -gt 0 ]; then
-        echo "[$(IFS=,; echo "${contexts[*]}")]"
-    else
-        echo "[]"
-    fi
-}
-
-#############################################################################
-# Registry Update
-#############################################################################
-
-update_registry() {
-    print_step "Updating registry..."
-    
-    # Scan all components
-    local agents_json=$(scan_agents)
-    local subagents_json=$(scan_subagents)
-    local commands_json=$(scan_commands)
-    local tools_json=$(scan_tools)
-    local plugins_json=$(scan_plugins)
-    local contexts_json=$(scan_contexts)
-    
-    # Read existing registry
-    local existing_registry=$(cat "$REGISTRY_FILE")
-    
-    # Update components while preserving profiles and metadata
-    local updated_registry=$(echo "$existing_registry" | jq \
-        --argjson agents "$agents_json" \
-        --argjson subagents "$subagents_json" \
-        --argjson commands "$commands_json" \
-        --argjson tools "$tools_json" \
-        --argjson plugins "$plugins_json" \
-        --argjson contexts "$contexts_json" \
-        '
-        .components.agents = $agents |
-        .components.subagents = $subagents |
-        .components.commands = $commands |
-        .components.tools = $tools |
-        .components.plugins = $plugins |
-        .components.contexts = $contexts |
-        .metadata.lastUpdated = (now | strftime("%Y-%m-%d"))
-        ')
-    
-    # Write to temp file first
-    echo "$updated_registry" | jq '.' > "$TEMP_REGISTRY"
-    
-    # Validate
-    if jq empty "$TEMP_REGISTRY" 2>/dev/null; then
-        mv "$TEMP_REGISTRY" "$REGISTRY_FILE"
-        print_success "Registry updated successfully"
-    else
-        print_error "Generated invalid JSON, registry not updated"
-        rm -f "$TEMP_REGISTRY"
-        exit 1
-    fi
-}
-
-#############################################################################
-# Statistics
-#############################################################################
-
-show_statistics() {
-    print_step "Registry Statistics"
-    
-    local agents=$(jq '.components.agents | length' "$REGISTRY_FILE")
-    local subagents=$(jq '.components.subagents | length' "$REGISTRY_FILE")
-    local commands=$(jq '.components.commands | length' "$REGISTRY_FILE")
-    local tools=$(jq '.components.tools | length' "$REGISTRY_FILE")
-    local plugins=$(jq '.components.plugins | length' "$REGISTRY_FILE")
-    local contexts=$(jq '.components.contexts | length' "$REGISTRY_FILE")
-    local total=$((agents + subagents + commands + tools + plugins + contexts))
-    
-    echo "  Agents:    $agents"
-    echo "  Subagents: $subagents"
-    echo "  Commands:  $commands"
-    echo "  Tools:     $tools"
-    echo "  Plugins:   $plugins"
-    echo "  Contexts:  $contexts"
-    echo "  ─────────────"
-    echo "  Total:     $total"
-    echo ""
-}
-
-#############################################################################
-# Main
-#############################################################################
-
-main() {
-    echo -e "${CYAN}${BOLD}"
-    echo "╔════════════════════════════════════════════════════════════════╗"
-    echo "║                                                                ║"
-    echo "║           Component Registration Script                       ║"
-    echo "║                                                                ║"
-    echo "╚════════════════════════════════════════════════════════════════╝"
-    echo -e "${NC}"
-    
-    check_dependencies
-    validate_registry
-    
-    update_registry
-    show_statistics
-    
-    print_success "Done!"
-}
-
-main "$@"
+echo -e "${CYAN}${BOLD}"
+echo "╔════════════════════════════════════════════════════════════════╗"
+echo "║                                                                ║"
+echo "║           Component Registration Script                       ║"
+echo "║                                                                ║"
+echo "╚════════════════════════════════════════════════════════════════╝"
+echo -e "${NC}"
+
+echo ""
+echo "ℹ️  This script currently preserves the manually maintained registry.json"
+echo "ℹ️  Auto-scanning feature will be added in a future update"
+echo ""
+
+if [ ! -f "registry.json" ]; then
+    echo "❌ Error: registry.json not found"
+    exit 1
+fi
+
+if ! command -v jq &> /dev/null; then
+    echo "❌ Error: jq is required but not installed"
+    exit 1
+fi
+
+if ! jq empty registry.json 2>/dev/null; then
+    echo "❌ Error: registry.json is not valid JSON"
+    exit 1
+fi
+
+# Update the lastUpdated timestamp
+jq '.metadata.lastUpdated = (now | strftime("%Y-%m-%d"))' registry.json > registry.json.tmp
+mv registry.json.tmp registry.json
+
+echo -e "${GREEN}✓${NC} Registry validated successfully"
+echo ""
+echo "Registry Statistics:"
+echo "  Agents:    $(jq '.components.agents | length' registry.json)"
+echo "  Subagents: $(jq '.components.subagents | length' registry.json)"
+echo "  Commands:  $(jq '.components.commands | length' registry.json)"
+echo "  Tools:     $(jq '.components.tools | length' registry.json)"
+echo "  Plugins:   $(jq '.components.plugins | length' registry.json)"
+echo "  Contexts:  $(jq '.components.contexts | length' registry.json)"
+echo ""
+echo -e "${GREEN}✓${NC} Done!"