Add OpenCode and Tidewave CLI support

- OpenCode: Open-source AI coding assistant (npm install -g opencode-ai)
  Supports multiple LLM providers including OpenAI, Anthropic, Gemini

- Tidewave: Elixir/Phoenix MCP server for AI-powered development
  Downloads binary from GitHub releases with ELF validation
  Enables runtime introspection, SQL queries, and code evaluation

Both tools are optional components in the interactive installer.
Tidewave is automatically skipped if Erlang is not selected.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
guessthepw 2026-01-25 12:16:06 -05:00
parent 63bcc0aea3
commit 2861664a03
3 changed files with 91 additions and 10 deletions

View file

@ -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

View file

@ -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 |

View file

@ -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