#!/usr/bin/env bash # x402 Registry Installer for OpenCode # Usage: curl -fsSL https://registry.mcpay.tech/install.sh | bash # or: bash install.sh set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[1;33m' CYAN='\033[0;36m' BOLD='\033[1m' NC='\033[0m' # No Color # Registry URL REGISTRY_URL="https://registry.mcpay.tech" # Print functions print_header() { echo "" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${BOLD}$1${NC}" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" } print_step() { echo -e "\n${CYAN}▶${NC} $1" } print_success() { echo -e "${GREEN}✓${NC} $1" } print_warning() { echo -e "${YELLOW}!${NC} $1" } print_error() { echo -e "${RED}✗${NC} $1" } # Check for required commands check_dependencies() { local missing=() if ! command -v curl &> /dev/null; then missing+=("curl") fi if ! command -v jq &> /dev/null; then missing+=("jq") fi if [ ${#missing[@]} -gt 0 ]; then print_error "Missing required dependencies: ${missing[*]}" echo "Please install them and try again." exit 1 fi } # Check if OpenCode is installed check_opencode() { if command -v opencode &> /dev/null; then local version=$(opencode --version 2>/dev/null || echo "unknown") print_success "OpenCode found: $version" return 0 else return 1 fi } # Install OpenCode install_opencode() { print_step "Installing OpenCode..." curl -fsSL https://opencode.ai/install | bash # Reload shell path export PATH="$HOME/.local/bin:$PATH" if check_opencode; then print_success "OpenCode installed successfully" else print_error "Failed to install OpenCode" exit 1 fi } # Fetch available packages from registry fetch_packages() { local response response=$(curl -fsSL "$REGISTRY_URL/api/packages" 2>/dev/null) if [ $? -ne 0 ]; then print_error "Failed to fetch packages from registry" exit 1 fi echo "$response" } # Display package selection menu select_packages() { local packages_json="$1" local package_slugs package_slugs=$(echo "$packages_json" | jq -r '.packages[].slug') if [ -z "$package_slugs" ]; then print_warning "No packages available in the registry" return fi echo "" echo -e "${BOLD}Available packages:${NC}" echo "" local i=1 local pkg_array=() while IFS= read -r slug; do local desc=$(echo "$packages_json" | jq -r ".packages[] | select(.slug == \"$slug\") | .description") local version=$(echo "$packages_json" | jq -r ".packages[] | select(.slug == \"$slug\") | .version") local skills=$(echo "$packages_json" | jq -r ".packages[] | select(.slug == \"$slug\") | .counts.skills") local agents=$(echo "$packages_json" | jq -r ".packages[] | select(.slug == \"$slug\") | .counts.agents") local commands=$(echo "$packages_json" | jq -r ".packages[] | select(.slug == \"$slug\") | .counts.commands") local tools=$(echo "$packages_json" | jq -r ".packages[] | select(.slug == \"$slug\") | .counts.tools") pkg_array+=("$slug") echo -e " ${CYAN}[$i]${NC} ${BOLD}$slug${NC} ${BLUE}v$version${NC}" echo -e " $desc" local meta="" [ "$skills" != "0" ] && meta+="${skills} skill(s) " [ "$agents" != "0" ] && meta+="${agents} agent(s) " [ "$commands" != "0" ] && meta+="${commands} command(s) " [ "$tools" != "0" ] && meta+="${tools} tool(s) " if [ -n "$meta" ]; then echo -e " ${YELLOW}$meta${NC}" fi echo "" ((i++)) done <<< "$package_slugs" echo -e " ${CYAN}[a]${NC} Install all packages" echo -e " ${CYAN}[n]${NC} Skip package installation" echo "" read -p "Select packages (comma-separated numbers, 'a' for all, 'n' to skip): " selection /dev/null) if [ $? -ne 0 ]; then print_error "Failed to fetch package: $slug" return 1 fi local opencode_dir="$project_dir/.opencode" # Install skills local skills_count=$(echo "$bundle" | jq '.skills | length') if [ "$skills_count" -gt 0 ]; then mkdir -p "$opencode_dir/skill" for i in $(seq 0 $((skills_count - 1))); do local skill_slug=$(echo "$bundle" | jq -r ".skills[$i].slug") local skill_content=$(echo "$bundle" | jq -r ".skills[$i].content") mkdir -p "$opencode_dir/skill/$skill_slug" echo "$skill_content" > "$opencode_dir/skill/$skill_slug/SKILL.md" print_success "Installed skill: $skill_slug" done fi # Install agents local agents_count=$(echo "$bundle" | jq '.agents | length') if [ "$agents_count" -gt 0 ]; then mkdir -p "$opencode_dir/agent" for i in $(seq 0 $((agents_count - 1))); do local agent_slug=$(echo "$bundle" | jq -r ".agents[$i].slug") local agent_content=$(echo "$bundle" | jq -r ".agents[$i].content") echo "$agent_content" > "$opencode_dir/agent/$agent_slug.md" print_success "Installed agent: $agent_slug" done fi # Install commands local commands_count=$(echo "$bundle" | jq '.commands | length') if [ "$commands_count" -gt 0 ]; then mkdir -p "$opencode_dir/command" for i in $(seq 0 $((commands_count - 1))); do local cmd_slug=$(echo "$bundle" | jq -r ".commands[$i].slug") local cmd_content=$(echo "$bundle" | jq -r ".commands[$i].content") echo "$cmd_content" > "$opencode_dir/command/$cmd_slug.md" print_success "Installed command: $cmd_slug" done fi # Install tools local tools_count=$(echo "$bundle" | jq '.tools | length') if [ "$tools_count" -gt 0 ]; then mkdir -p "$opencode_dir/tool" for i in $(seq 0 $((tools_count - 1))); do local tool_slug=$(echo "$bundle" | jq -r ".tools[$i].slug") local tool_ext=$(echo "$bundle" | jq -r ".tools[$i].extension") local tool_content=$(echo "$bundle" | jq -r ".tools[$i].content") echo "$tool_content" > "$opencode_dir/tool/$tool_slug.$tool_ext" print_success "Installed tool: $tool_slug" done fi # Install plugins local plugins_count=$(echo "$bundle" | jq '.plugins | length') if [ "$plugins_count" -gt 0 ]; then mkdir -p "$opencode_dir/plugin" for i in $(seq 0 $((plugins_count - 1))); do local plugin_slug=$(echo "$bundle" | jq -r ".plugins[$i].slug") local plugin_ext=$(echo "$bundle" | jq -r ".plugins[$i].extension") local plugin_content=$(echo "$bundle" | jq -r ".plugins[$i].content") echo "$plugin_content" > "$opencode_dir/plugin/$plugin_slug.$plugin_ext" print_success "Installed plugin: $plugin_slug" done fi # Install AGENTS.md rules if present local has_rules=$(echo "$bundle" | jq 'has("rules") and .rules != null') if [ "$has_rules" = "true" ]; then local rules_content=$(echo "$bundle" | jq -r ".rules.content") # Append to existing AGENTS.md or create new one if [ -f "$project_dir/AGENTS.md" ]; then echo "" >> "$project_dir/AGENTS.md" echo "" >> "$project_dir/AGENTS.md" echo "$rules_content" >> "$project_dir/AGENTS.md" print_success "Appended rules to AGENTS.md" else echo "$rules_content" > "$project_dir/AGENTS.md" print_success "Created AGENTS.md with rules" fi fi return 0 } # Create initial opencode.json config create_config() { local project_dir="$1" local project_name="$2" local initial_prompt="$3" local config_file="$project_dir/opencode.json" if [ -f "$config_file" ]; then print_warning "opencode.json already exists, skipping config creation" return fi cat > "$config_file" << 'CONFIGEOF' { "$schema": "https://opencode.ai/config.json", "instructions": [ "AGENTS.md" ], "share": "manual" } CONFIGEOF print_success "Created opencode.json" } # Update opencode.json with installed package metadata update_config_with_packages() { local project_dir="$1" shift local packages=("$@") local config_file="$project_dir/opencode.json" if [ ! -f "$config_file" ] || [ ${#packages[@]} -eq 0 ]; then return fi # Create a packages manifest in .opencode local manifest="$project_dir/.opencode/packages.json" # Build JSON array of installed packages local pkg_json="[" local first=true for pkg in "${packages[@]}"; do if [ "$first" = true ]; then first=false else pkg_json+="," fi pkg_json+="\"$pkg\"" done pkg_json+="]" cat > "$manifest" << MANIFESTEOF { "installedAt": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")", "registry": "$REGISTRY_URL", "packages": $pkg_json } MANIFESTEOF print_success "Created package manifest" } # Create initial AGENTS.md with project context create_agents_md() { local project_dir="$1" local project_name="$2" local initial_prompt="$3" local agents_file="$project_dir/AGENTS.md" if [ -f "$agents_file" ]; then print_warning "AGENTS.md already exists, will append package rules" return fi cat > "$agents_file" << AGENTSEOF # $project_name $initial_prompt --- ## Project Guidelines AGENTSEOF print_success "Created AGENTS.md" } # Main installation flow main() { print_header "x402 Registry Installer" echo "" echo "This script will set up a new OpenCode project with packages" echo "from the x402 Registry." echo "" # Check dependencies check_dependencies # Check/install OpenCode print_step "Checking for OpenCode..." if ! check_opencode; then print_warning "OpenCode not found" read -p "Would you like to install OpenCode? [Y/n] " install_oc " initial_prompt