Initial commit: opencode config with 32 skills, 3 agents, 11 MCPs
- Cross-platform install scripts (Windows PowerShell + Unix bash) - Template-based config generation with env var support - Skills: coding-standards, frontend-patterns, backend-patterns, security-review, tdd-workflow, e2e-testing, deep-research, exa-search, content-engine, crosspost, x-api, and 20 more - Agents: explorer, reviewer, docs-researcher - MCPs: codegraph, brave-search, playwright, github, context7, exa, memory, sequential-thinking, git, filesystem
This commit is contained in:
+242
@@ -0,0 +1,242 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
DARKGRAY='\033[0;90m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Detect OS
|
||||
OS="unknown"
|
||||
case "$(uname -s)" in
|
||||
Linux*) OS="linux";;
|
||||
Darwin*) OS="macos";;
|
||||
CYGWIN*|MINGW*|MSYS*) OS="windows";;
|
||||
esac
|
||||
|
||||
# Config paths
|
||||
if [ "$OS" = "windows" ]; then
|
||||
CONFIG_DIR="$USERPROFILE/.config/opencode"
|
||||
else
|
||||
CONFIG_DIR="$HOME/.config/opencode"
|
||||
fi
|
||||
|
||||
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
echo -e "${CYAN}========================================${NC}"
|
||||
echo -e "${CYAN} Opencode Config Installer (Unix) ${NC}"
|
||||
echo -e "${CYAN} OS: $OS ${NC}"
|
||||
echo -e "${CYAN}========================================${NC}"
|
||||
echo ""
|
||||
|
||||
# Check prerequisites
|
||||
echo -e "${YELLOW}[*] Checking prerequisites...${NC}"
|
||||
|
||||
if ! command -v git &> /dev/null; then
|
||||
echo -e "${RED}[ERROR] Git not found. Install git first.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v npm &> /dev/null; then
|
||||
echo -e "${RED}[ERROR] npm not found. Install Node.js from https://nodejs.org/${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v python3 &> /dev/null && ! command -v python &> /dev/null; then
|
||||
echo -e "${RED}[ERROR] Python not found. Install Python 3.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}[OK] Prerequisites met${NC}"
|
||||
echo ""
|
||||
|
||||
# Get or prompt for API keys
|
||||
get_env_or_prompt() {
|
||||
local name="$1"
|
||||
local prompt="$2"
|
||||
local required="${3:-false}"
|
||||
local val=""
|
||||
|
||||
# Check environment
|
||||
val="${!name:-}"
|
||||
|
||||
if [ -z "$val" ]; then
|
||||
if [ "$required" = "true" ]; then
|
||||
read -rp "$prompt (required): " val
|
||||
if [ -z "$val" ]; then
|
||||
echo -e "${RED}[ERROR] $name is required${NC}"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
read -rp "$prompt (optional, press Enter to skip): " val
|
||||
fi
|
||||
|
||||
# Save to shell rc file
|
||||
if [ -n "$val" ]; then
|
||||
local shell_rc=""
|
||||
if [ -f "$HOME/.zshrc" ]; then
|
||||
shell_rc="$HOME/.zshrc"
|
||||
elif [ -f "$HOME/.bashrc" ]; then
|
||||
shell_rc="$HOME/.bashrc"
|
||||
fi
|
||||
|
||||
if [ -n "$shell_rc" ]; then
|
||||
echo "export $name=\"$val\"" >> "$shell_rc"
|
||||
echo -e "${DARKGRAY} Saved $name to $shell_rc${NC}"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo -e "${DARKGRAY} Found $name in environment${NC}"
|
||||
fi
|
||||
|
||||
echo "$val"
|
||||
}
|
||||
|
||||
echo -e "${YELLOW}[*] Configuring secrets...${NC}"
|
||||
API_KEY=$(get_env_or_prompt "OPENCODE_API_KEY" "Enter your OpenAI-compatible API key" "true")
|
||||
BRAVE_KEY=$(get_env_or_prompt "BRAVE_API_KEY" "Enter your Brave Search API key" "false")
|
||||
|
||||
# Detect or prompt for projects path
|
||||
PROJECTS_PATH="${PROJECTS_PATH:-}"
|
||||
if [ -z "$PROJECTS_PATH" ]; then
|
||||
default_path="$HOME/projects"
|
||||
read -rp "Enter your projects directory path [default: $default_path]: " PROJECTS_PATH
|
||||
if [ -z "$PROJECTS_PATH" ]; then
|
||||
PROJECTS_PATH="$default_path"
|
||||
fi
|
||||
|
||||
if [ ! -d "$PROJECTS_PATH" ]; then
|
||||
echo -e "${DARKGRAY} Creating projects directory: $PROJECTS_PATH${NC}"
|
||||
mkdir -p "$PROJECTS_PATH"
|
||||
fi
|
||||
fi
|
||||
echo -e "${GREEN}[OK] Projects path: $PROJECTS_PATH${NC}"
|
||||
echo ""
|
||||
|
||||
# Backup existing config
|
||||
if [ -f "$CONFIG_DIR/opencode.json" ]; then
|
||||
backup="$CONFIG_DIR/opencode.json.backup.$(date +%Y%m%d%H%M%S)"
|
||||
cp "$CONFIG_DIR/opencode.json" "$backup"
|
||||
echo -e "${YELLOW}[*] Backed up existing config to: $backup${NC}"
|
||||
fi
|
||||
|
||||
# Create config directory
|
||||
mkdir -p "$CONFIG_DIR"
|
||||
|
||||
# Generate opencode.json from template
|
||||
echo -e "${YELLOW}[*] Generating opencode.json...${NC}"
|
||||
|
||||
# Escape path for JSON (handle backslashes on Windows)
|
||||
PROJECTS_PATH_ESCAPED="$PROJECTS_PATH"
|
||||
if [ "$OS" = "windows" ]; then
|
||||
# Double backslashes for JSON
|
||||
PROJECTS_PATH_ESCAPED="${PROJECTS_PATH//\\//\\\\}"
|
||||
fi
|
||||
|
||||
# Read template and substitute
|
||||
sed -e "s|\\\${OPENCODE_API_KEY}|$API_KEY|g" \
|
||||
-e "s|\\\${BRAVE_API_KEY}|$BRAVE_KEY|g" \
|
||||
-e "s|\\\${PROJECTS_PATH}|$PROJECTS_PATH_ESCAPED|g" \
|
||||
"$REPO_DIR/opencode.json.template" > "$CONFIG_DIR/opencode.json"
|
||||
|
||||
# Disable brave-search if no key
|
||||
if [ -z "$BRAVE_KEY" ]; then
|
||||
echo -e "${DARKGRAY} [!] No Brave API key - disabling brave-search MCP${NC}"
|
||||
# Use python to safely modify JSON
|
||||
python3 -c "
|
||||
import json
|
||||
with open('$CONFIG_DIR/opencode.json', 'r') as f:
|
||||
config = json.load(f)
|
||||
if 'brave-search' in config.get('mcp', {}):
|
||||
config['mcp']['brave-search']['enabled'] = False
|
||||
if 'env' in config['mcp']['brave-search']:
|
||||
del config['mcp']['brave-search']['env']
|
||||
with open('$CONFIG_DIR/opencode.json', 'w') as f:
|
||||
json.dump(config, f, indent=2)
|
||||
" 2>/dev/null || python -c "
|
||||
import json
|
||||
with open('$CONFIG_DIR/opencode.json', 'r') as f:
|
||||
config = json.load(f)
|
||||
if 'brave-search' in config.get('mcp', {}):
|
||||
config['mcp']['brave-search']['enabled'] = False
|
||||
if 'env' in config['mcp']['brave-search']:
|
||||
del config['mcp']['brave-search']['env']
|
||||
with open('$CONFIG_DIR/opencode.json', 'w') as f:
|
||||
json.dump(config, f, indent=2)
|
||||
"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}[OK] Config written to $CONFIG_DIR/opencode.json${NC}"
|
||||
echo ""
|
||||
|
||||
# Copy agents and skills
|
||||
echo -e "${YELLOW}[*] Syncing agents and skills...${NC}"
|
||||
|
||||
# Remove old skills/agents to ensure clean sync
|
||||
rm -rf "$CONFIG_DIR/agents" "$CONFIG_DIR/skills"
|
||||
|
||||
cp -r "$REPO_DIR/agents" "$CONFIG_DIR/"
|
||||
cp -r "$REPO_DIR/skills" "$CONFIG_DIR/"
|
||||
|
||||
SKILL_COUNT=$(find "$CONFIG_DIR/skills" -maxdepth 1 -type d | wc -l)
|
||||
SKILL_COUNT=$((SKILL_COUNT - 1)) # Exclude skills dir itself
|
||||
|
||||
echo -e "${GREEN}[OK] Copied 3 agents and $SKILL_COUNT skills${NC}"
|
||||
echo ""
|
||||
|
||||
# Install global dependencies
|
||||
echo -e "${YELLOW}[*] Installing global dependencies...${NC}"
|
||||
|
||||
GLOBAL_PACKAGES=(
|
||||
"@colbymchenry/codegraph"
|
||||
"@brave/brave-search-mcp-server"
|
||||
"@modelcontextprotocol/server-filesystem"
|
||||
"@modelcontextprotocol/server-github"
|
||||
"@modelcontextprotocol/server-memory"
|
||||
"@modelcontextprotocol/server-sequential-thinking"
|
||||
"@playwright/mcp"
|
||||
"@upstash/context7-mcp"
|
||||
"mcp-remote"
|
||||
)
|
||||
|
||||
for pkg in "${GLOBAL_PACKAGES[@]}"; do
|
||||
echo -e "${DARKGRAY} Installing $pkg...${NC}" -n
|
||||
if npm install -g "$pkg" 2>/dev/null; then
|
||||
echo -e "${GREEN} OK${NC}"
|
||||
else
|
||||
echo -e "${YELLOW} SKIP (may already be installed)${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Install Python git MCP
|
||||
echo -e "${DARKGRAY} Installing Python git MCP...${NC}" -n
|
||||
if python3 -m pip install mcp-server-git 2>/dev/null || python -m pip install mcp-server-git 2>/dev/null; then
|
||||
echo -e "${GREEN} OK${NC}"
|
||||
else
|
||||
echo -e "${YELLOW} SKIP${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN}========================================${NC}"
|
||||
echo -e "${GREEN} Installation Complete! ${NC}"
|
||||
echo -e "${CYAN}========================================${NC}"
|
||||
echo ""
|
||||
echo -e "${WHITE}Next steps:${NC}"
|
||||
echo -e " 1. Restart opencode to load new config"
|
||||
echo -e " 2. Run 'opencode' in your project directory"
|
||||
echo -e " 3. Initialize CodeGraph: codegraph init"
|
||||
echo ""
|
||||
echo -e "${DARKGRAY}Config location: $CONFIG_DIR${NC}"
|
||||
echo ""
|
||||
|
||||
# Verify config
|
||||
echo -e "${YELLOW}[*] Verifying config...${NC}"
|
||||
if python3 -c "import json; config=json.load(open('$CONFIG_DIR/opencode.json')); print(f'[OK] Config valid - {len(config.get(\"mcp\", {}))} MCP servers configured')" 2>/dev/null || \
|
||||
python -c "import json; config=json.load(open('$CONFIG_DIR/opencode.json')); print(f'[OK] Config valid - {len(config.get(\"mcp\", {}))} MCP servers configured')" 2>/dev/null; then
|
||||
:
|
||||
else
|
||||
echo -e "${YELLOW}[WARN] Config may have syntax issues - please check $CONFIG_DIR/opencode.json${NC}"
|
||||
fi
|
||||
Reference in New Issue
Block a user