diff --git a/CHANGELOG.md b/CHANGELOG.md index 898c179..5e6d4ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.10.0] - 2025-01-25 + +### Added +- OpenCode: Open-source AI coding assistant with multi-provider support +- Tidewave CLI: Elixir/Phoenix MCP server for AI-powered development +- New component selection options for OpenCode and Tidewave + ## [0.9.1] - 2025-01-25 ### Fixed diff --git a/README.md b/README.md index 7fad4d0..6448198 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,9 @@ All components are optional — deselect what you don't need in the interactive | Playwright | latest | Browser testing framework | | PostgreSQL | system default | Database | | Ollama | latest | Local LLM inference | -| Claude Code | latest | AI coding assistant | +| Claude Code | latest | AI coding assistant (Anthropic) | +| OpenCode | latest | Open-source AI coding assistant (multi-provider) | +| Tidewave | latest | Elixir/Phoenix MCP server for AI tools | | yq | latest | YAML processor | | watchexec | latest | File watcher (via cargo) | | TigerVNC + XFCE | system | VNC access for browser login flows | diff --git a/setup_env.sh b/setup_env.sh index 74101c1..ee5eba4 100755 --- a/setup_env.sh +++ b/setup_env.sh @@ -284,7 +284,7 @@ if [[ "$(uname -s)" == "Darwin" ]]; then # ---- Interactive component selection ---- # Component IDs and descriptions - COMP_IDS=(postgresql mise node erlang chromium vnc ollama claude playwright plugins) + COMP_IDS=(postgresql mise node erlang chromium vnc ollama claude opencode playwright plugins) COMP_NAMES=( "PostgreSQL" "mise" @@ -294,20 +294,22 @@ if [[ "$(uname -s)" == "Darwin" ]]; then "VNC + XFCE" "Ollama" "Claude Code" + "OpenCode" "Playwright" - "Claude Plugins" + "Claude Plugins + Tidewave" ) COMP_DESCS=( "Database server for local development" "Version manager for Node.js, Erlang, Elixir" - "JavaScript runtime (required for Claude Code)" + "JavaScript runtime (required for Claude/OpenCode)" "BEAM VM + Elixir functional language" "Browser for automation and testing" "Remote desktop for browser-based login flows" "Local LLM runner for offline inference" "AI coding assistant CLI from Anthropic" + "Open-source AI coding assistant (multi-provider)" "Browser testing and automation framework" - "Code review, feature dev, browser automation plugins" + "Code review, Tidewave MCP, browser automation" ) # All selected by default @@ -1077,6 +1079,54 @@ install_playwright() { fi } +install_opencode() { + export PATH="$HOME/.local/share/mise/shims:$HOME/.local/bin:$PATH" + if command_exists opencode; then + echo "OpenCode already installed" + return 0 + fi + npm install -g opencode-ai +} + +install_tidewave() { + if command_exists tidewave; then + echo "Tidewave already installed" + return 0 + fi + + # Download Tidewave CLI binary + local arch + arch=$(detect_architecture) + local tidewave_arch="" + case "$arch" in + amd64) tidewave_arch="x86_64-unknown-linux-gnu" ;; + arm64) tidewave_arch="aarch64-unknown-linux-gnu" ;; + esac + + # Get latest release URL from GitHub + local release_url="https://github.com/tidewave-ai/tidewave/releases/latest/download/tidewave-${tidewave_arch}" + + # Security: Download to temp file first, validate, then install + local temp_file + temp_file=$(mktemp) + if curl -fsSL "$release_url" -o "$temp_file"; then + # Verify it's an executable (ELF binary) + if file "$temp_file" | grep -q "ELF"; then + sudo mv "$temp_file" /usr/local/bin/tidewave + sudo chmod +x /usr/local/bin/tidewave + echo "Tidewave CLI installed" + else + log_error "Downloaded tidewave is not a valid binary" + rm -f "$temp_file" + return 1 + fi + else + log_error "Failed to download Tidewave CLI" + rm -f "$temp_file" + return 1 + fi +} + install_plugins() { export PATH="$HOME/.local/share/mise/shims:$HOME/.local/bin:$PATH" mkdir -p ~/.config/claude @@ -1096,6 +1146,12 @@ install_plugins() { echo "Adding MCP servers..." claude mcp add playwright --scope user -- npx @anthropic-ai/mcp-server-playwright 2>/dev/null || true claude mcp add superpowers-chrome --scope user -- npx github:obra/superpowers-chrome --headless 2>/dev/null || true + + # Note: Tidewave MCP is configured per-project when running a Phoenix app + # Use: claude mcp add --transport http tidewave http://localhost:4000/tidewave/mcp + echo "" + echo "Tidewave MCP: Add per-project with your Phoenix app running:" + echo " claude mcp add --transport http tidewave http://localhost:PORT/tidewave/mcp" } install_base_deps() { @@ -1246,6 +1302,8 @@ register_step "chromium" "Chromium browser" register_step "vnc" "VNC server + XFCE desktop" register_step "ollama" "Ollama local LLM runner" register_step "claude" "Claude Code CLI" +register_step "opencode" "OpenCode CLI" +register_step "tidewave" "Tidewave CLI (Elixir MCP)" register_step "playwright" "Playwright browser automation" register_step "plugins" "Claude Code plugins" @@ -1258,16 +1316,21 @@ should_skip "chromium" && skip_step "chromium" should_skip "vnc" && skip_step "vnc" should_skip "ollama" && skip_step "ollama" should_skip "claude" && skip_step "claude" +should_skip "opencode" && skip_step "opencode" should_skip "playwright" && skip_step "playwright" should_skip "plugins" && skip_step "plugins" # Elixir skipped if Erlang skipped [ "${STEP_STATUS[erlang]}" = "skipped" ] && skip_step "elixir" -# Claude/Playwright skipped if Node skipped +# Tidewave skipped if Erlang skipped (it's for Phoenix/Elixir projects) +[ "${STEP_STATUS[erlang]}" = "skipped" ] && skip_step "tidewave" + +# Claude/OpenCode/Playwright skipped if Node skipped if [ "${STEP_STATUS[node]}" = "skipped" ]; then [ "${STEP_STATUS[mise]}" = "skipped" ] || true # mise can still install skip_step "claude" + skip_step "opencode" skip_step "playwright" skip_step "plugins" fi @@ -1315,11 +1378,14 @@ if [ "${STEP_STATUS[mise]}" = "done" ]; then fi # ============================================================================ -# Phase 4: Elixir + Claude + Playwright (Elixir needs Erlang, others need Node) +# Phase 4: Elixir + Claude + OpenCode + Playwright + Tidewave +# (Elixir/Tidewave need Erlang, others need Node) # ============================================================================ -[ "${STEP_STATUS[erlang]}" = "done" ] && [ "${STEP_STATUS[elixir]}" != "skipped" ] && start_step "elixir" install_elixir -[ "${STEP_STATUS[node]}" = "done" ] && [ "${STEP_STATUS[claude]}" != "skipped" ] && start_step "claude" install_claude -[ "${STEP_STATUS[node]}" = "done" ] && [ "${STEP_STATUS[playwright]}" != "skipped" ] && start_step "playwright" install_playwright +[ "${STEP_STATUS[erlang]}" = "done" ] && [ "${STEP_STATUS[elixir]}" != "skipped" ] && start_step "elixir" install_elixir +[ "${STEP_STATUS[erlang]}" = "done" ] && [ "${STEP_STATUS[tidewave]}" != "skipped" ] && start_step "tidewave" install_tidewave +[ "${STEP_STATUS[node]}" = "done" ] && [ "${STEP_STATUS[claude]}" != "skipped" ] && start_step "claude" install_claude +[ "${STEP_STATUS[node]}" = "done" ] && [ "${STEP_STATUS[opencode]}" != "skipped" ] && start_step "opencode" install_opencode +[ "${STEP_STATUS[node]}" = "done" ] && [ "${STEP_STATUS[playwright]}" != "skipped" ] && start_step "playwright" install_playwright wait_for_running_steps @@ -1393,6 +1459,12 @@ fi if [ "${STEP_STATUS[claude]}" = "done" ]; then echo -e "${CYAN}Claude:${NC} claude" fi +if [ "${STEP_STATUS[opencode]}" = "done" ]; then + echo -e "${CYAN}OpenCode:${NC} opencode" +fi +if [ "${STEP_STATUS[tidewave]}" = "done" ]; then + echo -e "${CYAN}Tidewave:${NC} tidewave (run in Phoenix project dir)" +fi if [ "${STEP_STATUS[ollama]}" = "done" ]; then echo -e "${CYAN}Ollama:${NC} ollama run llama3.2" fi