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:
parent
63bcc0aea3
commit
2861664a03
3 changed files with 91 additions and 10 deletions
|
|
@ -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/),
|
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).
|
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
|
## [0.9.1] - 2025-01-25
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,9 @@ All components are optional — deselect what you don't need in the interactive
|
||||||
| Playwright | latest | Browser testing framework |
|
| Playwright | latest | Browser testing framework |
|
||||||
| PostgreSQL | system default | Database |
|
| PostgreSQL | system default | Database |
|
||||||
| Ollama | latest | Local LLM inference |
|
| 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 |
|
| yq | latest | YAML processor |
|
||||||
| watchexec | latest | File watcher (via cargo) |
|
| watchexec | latest | File watcher (via cargo) |
|
||||||
| TigerVNC + XFCE | system | VNC access for browser login flows |
|
| TigerVNC + XFCE | system | VNC access for browser login flows |
|
||||||
|
|
|
||||||
90
setup_env.sh
90
setup_env.sh
|
|
@ -284,7 +284,7 @@ if [[ "$(uname -s)" == "Darwin" ]]; then
|
||||||
|
|
||||||
# ---- Interactive component selection ----
|
# ---- Interactive component selection ----
|
||||||
# Component IDs and descriptions
|
# 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=(
|
COMP_NAMES=(
|
||||||
"PostgreSQL"
|
"PostgreSQL"
|
||||||
"mise"
|
"mise"
|
||||||
|
|
@ -294,20 +294,22 @@ if [[ "$(uname -s)" == "Darwin" ]]; then
|
||||||
"VNC + XFCE"
|
"VNC + XFCE"
|
||||||
"Ollama"
|
"Ollama"
|
||||||
"Claude Code"
|
"Claude Code"
|
||||||
|
"OpenCode"
|
||||||
"Playwright"
|
"Playwright"
|
||||||
"Claude Plugins"
|
"Claude Plugins + Tidewave"
|
||||||
)
|
)
|
||||||
COMP_DESCS=(
|
COMP_DESCS=(
|
||||||
"Database server for local development"
|
"Database server for local development"
|
||||||
"Version manager for Node.js, Erlang, Elixir"
|
"Version manager for Node.js, Erlang, Elixir"
|
||||||
"JavaScript runtime (required for Claude Code)"
|
"JavaScript runtime (required for Claude/OpenCode)"
|
||||||
"BEAM VM + Elixir functional language"
|
"BEAM VM + Elixir functional language"
|
||||||
"Browser for automation and testing"
|
"Browser for automation and testing"
|
||||||
"Remote desktop for browser-based login flows"
|
"Remote desktop for browser-based login flows"
|
||||||
"Local LLM runner for offline inference"
|
"Local LLM runner for offline inference"
|
||||||
"AI coding assistant CLI from Anthropic"
|
"AI coding assistant CLI from Anthropic"
|
||||||
|
"Open-source AI coding assistant (multi-provider)"
|
||||||
"Browser testing and automation framework"
|
"Browser testing and automation framework"
|
||||||
"Code review, feature dev, browser automation plugins"
|
"Code review, Tidewave MCP, browser automation"
|
||||||
)
|
)
|
||||||
|
|
||||||
# All selected by default
|
# All selected by default
|
||||||
|
|
@ -1077,6 +1079,54 @@ install_playwright() {
|
||||||
fi
|
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() {
|
install_plugins() {
|
||||||
export PATH="$HOME/.local/share/mise/shims:$HOME/.local/bin:$PATH"
|
export PATH="$HOME/.local/share/mise/shims:$HOME/.local/bin:$PATH"
|
||||||
mkdir -p ~/.config/claude
|
mkdir -p ~/.config/claude
|
||||||
|
|
@ -1096,6 +1146,12 @@ install_plugins() {
|
||||||
echo "Adding MCP servers..."
|
echo "Adding MCP servers..."
|
||||||
claude mcp add playwright --scope user -- npx @anthropic-ai/mcp-server-playwright 2>/dev/null || true
|
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
|
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() {
|
install_base_deps() {
|
||||||
|
|
@ -1246,6 +1302,8 @@ register_step "chromium" "Chromium browser"
|
||||||
register_step "vnc" "VNC server + XFCE desktop"
|
register_step "vnc" "VNC server + XFCE desktop"
|
||||||
register_step "ollama" "Ollama local LLM runner"
|
register_step "ollama" "Ollama local LLM runner"
|
||||||
register_step "claude" "Claude Code CLI"
|
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 "playwright" "Playwright browser automation"
|
||||||
register_step "plugins" "Claude Code plugins"
|
register_step "plugins" "Claude Code plugins"
|
||||||
|
|
||||||
|
|
@ -1258,16 +1316,21 @@ should_skip "chromium" && skip_step "chromium"
|
||||||
should_skip "vnc" && skip_step "vnc"
|
should_skip "vnc" && skip_step "vnc"
|
||||||
should_skip "ollama" && skip_step "ollama"
|
should_skip "ollama" && skip_step "ollama"
|
||||||
should_skip "claude" && skip_step "claude"
|
should_skip "claude" && skip_step "claude"
|
||||||
|
should_skip "opencode" && skip_step "opencode"
|
||||||
should_skip "playwright" && skip_step "playwright"
|
should_skip "playwright" && skip_step "playwright"
|
||||||
should_skip "plugins" && skip_step "plugins"
|
should_skip "plugins" && skip_step "plugins"
|
||||||
|
|
||||||
# Elixir skipped if Erlang skipped
|
# Elixir skipped if Erlang skipped
|
||||||
[ "${STEP_STATUS[erlang]}" = "skipped" ] && skip_step "elixir"
|
[ "${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
|
if [ "${STEP_STATUS[node]}" = "skipped" ]; then
|
||||||
[ "${STEP_STATUS[mise]}" = "skipped" ] || true # mise can still install
|
[ "${STEP_STATUS[mise]}" = "skipped" ] || true # mise can still install
|
||||||
skip_step "claude"
|
skip_step "claude"
|
||||||
|
skip_step "opencode"
|
||||||
skip_step "playwright"
|
skip_step "playwright"
|
||||||
skip_step "plugins"
|
skip_step "plugins"
|
||||||
fi
|
fi
|
||||||
|
|
@ -1315,11 +1378,14 @@ if [ "${STEP_STATUS[mise]}" = "done" ]; then
|
||||||
fi
|
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[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[erlang]}" = "done" ] && [ "${STEP_STATUS[tidewave]}" != "skipped" ] && start_step "tidewave" install_tidewave
|
||||||
[ "${STEP_STATUS[node]}" = "done" ] && [ "${STEP_STATUS[playwright]}" != "skipped" ] && start_step "playwright" install_playwright
|
[ "${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
|
wait_for_running_steps
|
||||||
|
|
||||||
|
|
@ -1393,6 +1459,12 @@ fi
|
||||||
if [ "${STEP_STATUS[claude]}" = "done" ]; then
|
if [ "${STEP_STATUS[claude]}" = "done" ]; then
|
||||||
echo -e "${CYAN}Claude:${NC} claude"
|
echo -e "${CYAN}Claude:${NC} claude"
|
||||||
fi
|
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
|
if [ "${STEP_STATUS[ollama]}" = "done" ]; then
|
||||||
echo -e "${CYAN}Ollama:${NC} ollama run llama3.2"
|
echo -e "${CYAN}Ollama:${NC} ollama run llama3.2"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue