114 lines
3.1 KiB
Bash
Executable file
114 lines
3.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
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|vibe] [-e rust] [--rebuild]" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
case "$app" in
|
|
claude)
|
|
image_name="claude-code-local"
|
|
install_pkg="RUN apt-get update && apt-get install -y npm && npm install -g @anthropic-ai/claude-code"
|
|
cmd="claude"
|
|
extra_volumes=(
|
|
-v "$HOME/.claude:$HOME/.claude"
|
|
-v "$HOME/.claude.json:$HOME/.claude.json"
|
|
)
|
|
;;
|
|
vibe)
|
|
image_name="vibe-local"
|
|
install_pkg="RUN apt-get update && apt-get install -y curl && curl -LsSf https://mistral.ai/vibe/install.sh | bash"
|
|
cmd="vibe"
|
|
;;
|
|
opencode)
|
|
image_name="opencode-local"
|
|
install_pkg="RUN apt-get update && apt-get install -y npm && npm install -g 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/.cache:$HOME/.cache"
|
|
-v "$HOME/.config/meridian:$HOME/.config/meridian"
|
|
-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 debian:bookworm
|
|
ENV PATH=/root/.local/bin/:$PATH
|
|
${env_layer}
|
|
$install_pkg
|
|
WORKDIR /workspace
|
|
CMD [\"$cmd\"]"
|
|
docker build --pull -t "$image_name" - <<< "$dockerfile"
|
|
fi
|
|
|
|
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"
|