diff --git a/registry.json b/registry.json index 1560e67..e5754c4 100644 --- a/registry.json +++ b/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" } diff --git a/scripts/register-component.sh b/scripts/register-component.sh index 48beb44..974ca07 100755 --- a/scripts/register-component.sh +++ b/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" +echo -e "${CYAN}${BOLD}" +echo "╔════════════════════════════════════════════════════════════════╗" +echo "║ ║" +echo "║ Component Registration Script ║" +echo "║ ║" +echo "╚════════════════════════════════════════════════════════════════╝" +echo -e "${NC}" -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"; } +echo "" +echo "ℹ️ This script currently preserves the manually maintained registry.json" +echo "ℹ️ Auto-scanning feature will be added in a future update" +echo "" -############################################################################# -# Validation -############################################################################# +if [ ! -f "registry.json" ]; then + echo "❌ Error: registry.json not found" + exit 1 +fi -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 -} +if ! command -v jq &> /dev/null; then + echo "❌ Error: jq is required but not installed" + 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 -} +if ! jq empty registry.json 2>/dev/null; then + echo "❌ Error: registry.json is not valid JSON" + exit 1 +fi -############################################################################# -# Component Discovery -############################################################################# +# Update the lastUpdated timestamp +jq '.metadata.lastUpdated = (now | strftime("%Y-%m-%d"))' registry.json > registry.json.tmp +mv registry.json.tmp registry.json -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 "${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!"