#!/usr/bin/env bash workspace="$HOME/ai_workspace" app="opencode" env="" rebuild=false while [[ $# -gt 0 ]]; do case "$1" in -p|--path) workspace="$(readlink -f "$2")" shift 2 ;; -a|--app) app="$2" shift 2 ;; -e|--env) env="$2" shift 2 ;; --rebuild) rebuild=true shift ;; *) echo "Usage: $0 [-p /path/to/workspace] [-a claude|opencode] [-e rust] [--rebuild]" >&2 exit 1 ;; esac done case "$app" in claude) image_name="claude-code-local" npm_pkg="@anthropic-ai/claude-code" cmd="claude" extra_volumes=( -v "$HOME/.claude:$HOME/.claude" -v "$HOME/.claude.json:$HOME/.claude.json" ) ;; opencode) image_name="opencode-local" npm_pkg="opencode-ai" cmd="opencode" extra_volumes=( -v "$HOME/.config/opencode:$HOME/.config/opencode" -v "$HOME/.local/share/opencode:$HOME/.local/share/opencode" -v "$HOME/.local/state/opencode:$HOME/.local/state/opencode" -v "$HOME/.claude:$HOME/.claude" # allow access to claude config for hacked auth ) ;; *) echo "Unknown app '$app'. Choose 'claude' or 'opencode'." >&2 exit 1 ;; esac env_suffix="" env_layer="" case "$env" in "") ;; rust) env_suffix="-rust" env_layer='ENV RUSTUP_HOME=/opt/rust/rustup CARGO_HOME=/opt/rust/cargo PATH=/opt/rust/cargo/bin:${PATH} RUN curl --proto '"'"'=https'"'"' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path && chmod -R a+rwX /opt/rust' ;; rust-esp32) env_suffix="-rust-esp32" env_layer='ENV RUSTUP_HOME=/opt/rust/rustup CARGO_HOME=/opt/rust/cargo PATH=/opt/rust/cargo/bin:${PATH} RUN curl --proto '"'"'=https'"'"' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path RUN cargo install espup && espup install --export-file /opt/rust/export-esp.sh RUN chmod -R a+rwX /opt/rust RUN printf '"'"'#!/bin/bash\n. /opt/rust/export-esp.sh\nexec "$@"\n'"'"' > /entrypoint.sh && chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]' ;; *) echo "Unknown env '$env'. Supported: rust, rust-esp32" >&2 exit 1 ;; esac image_name="${image_name}${env_suffix}" if $rebuild || ! docker image inspect "$image_name" &>/dev/null; then echo "Building $image_name..." dockerfile="FROM node:24-bookworm ${env_layer} RUN npm install -g $npm_pkg WORKDIR /workspace CMD [\"$cmd\"]" docker build --pull -t "$image_name" - <<< "$dockerfile" fi clear docker run -it --rm \ --name "${image_name}-container" \ --user "$(id -u):$(id -g)" \ -e HOME="$HOME" \ -v "$workspace:/workspace" \ "${extra_volumes[@]}" \ -w /workspace \ "$image_name"