26ce9aa490
Add entrypoint logic to detect and run the skillset deploy script on container start. Detection order: SKILLSET_CONTAINER_PATH env var, then ~/skillset dedicated mount, then /workspace/skillset fallback. The deploy script (from the skillset repo) creates relative symlinks that resolve inside the container regardless of the host path layout. Also adds SKILLSET_PATH volume mount option to docker-compose files and documents SKILLSET_CONTAINER_PATH in .env.example for hosts where the skillset lives in a workspace subdirectory.
123 lines
5.1 KiB
Bash
123 lines
5.1 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# ── Shell defaults: copy baked files from /etc/skel-devbox/ if absent
|
|
# Respects host bind-mounts and user customizations — existing files
|
|
# are never overwritten. To restore defaults: rm ~/.bash_aliases (or
|
|
# .inputrc) and recreate the container, or cp from /etc/skel-devbox/
|
|
# directly.
|
|
SKEL_DIR="/etc/skel-devbox"
|
|
if [ -d "$SKEL_DIR" ]; then
|
|
for f in .bash_aliases .inputrc; do
|
|
if [ -f "$SKEL_DIR/$f" ] && [ ! -e "$HOME/$f" ]; then
|
|
cp "$SKEL_DIR/$f" "$HOME/$f"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# ── MemPalace: initialize palace for the workspace if mempalace is installed
|
|
# Creates the palace directory structure on first run. Idempotent — skips
|
|
# if palace already exists, so upgrades from older versions preserve
|
|
# existing data. `--yes` auto-accepts detected entities so the init is
|
|
# non-interactive — the container entrypoint has no usable stdin for
|
|
# prompts anyway.
|
|
if command -v mempalace &>/dev/null && [ -d /workspace ]; then
|
|
PALACE_DIR="${HOME}/.mempalace"
|
|
if [ ! -d "$PALACE_DIR/palace" ]; then
|
|
echo "Initializing MemPalace for workspace (non-interactive)..."
|
|
mempalace init --yes /workspace >/dev/null 2>&1 || true
|
|
fi
|
|
fi
|
|
|
|
# ── Git config defaults ──────────────────────────────────────────────
|
|
if [ -n "${GIT_USER_NAME:-}" ] && ! git config --global user.name &>/dev/null; then
|
|
git config --global user.name "$GIT_USER_NAME"
|
|
fi
|
|
if [ -n "${GIT_USER_EMAIL:-}" ] && ! git config --global user.email &>/dev/null; then
|
|
git config --global user.email "$GIT_USER_EMAIL"
|
|
fi
|
|
|
|
# ── Generate opencode config from env vars if no config mounted ──────
|
|
# Delegated to a standalone Python script for clarity and testability.
|
|
# The script is idempotent: it never overwrites an existing opencode.json
|
|
# (bind-mounted from host, persisted in named volume, or previously
|
|
# generated) and no-ops if OPENCODE_PROVIDER is unset.
|
|
python3 /usr/local/lib/opencode-devbox/generate-config.py
|
|
|
|
# ── Skillset: deploy skills/instructions from mounted skillset repo ──
|
|
# When the skillset repo is mounted (at $HOME/skillset or /workspace/skillset),
|
|
# run the deploy script to create relative symlinks for skills and instructions.
|
|
# This ensures skills resolve correctly inside the container regardless of
|
|
# where the repo lives on the host. Idempotent — second run is a no-op.
|
|
#
|
|
# Detection order:
|
|
# 1. SKILLSET_CONTAINER_PATH env var (explicit, for non-standard layouts)
|
|
# 2. $HOME/skillset (dedicated volume mount via SKILLSET_PATH in compose)
|
|
# 3. /workspace/skillset (skillset is directly inside workspace root)
|
|
SKILLSET_DEPLOY=""
|
|
if [ -n "${SKILLSET_CONTAINER_PATH:-}" ] && [ -x "${SKILLSET_CONTAINER_PATH}/deploy-skills.sh" ]; then
|
|
SKILLSET_DEPLOY="${SKILLSET_CONTAINER_PATH}/deploy-skills.sh"
|
|
elif [ -x "$HOME/skillset/deploy-skills.sh" ]; then
|
|
SKILLSET_DEPLOY="$HOME/skillset/deploy-skills.sh"
|
|
elif [ -x /workspace/skillset/deploy-skills.sh ]; then
|
|
SKILLSET_DEPLOY="/workspace/skillset/deploy-skills.sh"
|
|
fi
|
|
if [ -n "$SKILLSET_DEPLOY" ]; then
|
|
"$SKILLSET_DEPLOY" --bootstrap --prune-stale >/dev/null 2>&1 || true
|
|
fi
|
|
|
|
CONFIG_DIR="$HOME/.config/opencode"
|
|
OMOS_CONFIG="$CONFIG_DIR/oh-my-opencode-slim.json"
|
|
|
|
# ── oh-my-opencode-slim setup (multi-agent orchestration) ────────────
|
|
# Activated by ENABLE_OMOS=true. Requires the image to be built with
|
|
# INSTALL_OMOS=true (which installs bun + the oh-my-opencode-slim package).
|
|
OMOS_CONFIG="$CONFIG_DIR/oh-my-opencode-slim.json"
|
|
|
|
if [ "${ENABLE_OMOS:-false}" = "true" ]; then
|
|
if ! command -v bun &>/dev/null; then
|
|
echo "WARNING: ENABLE_OMOS=true but bun is not installed."
|
|
echo "Rebuild with: docker compose build --build-arg INSTALL_OMOS=true"
|
|
elif [ ! -f "$OMOS_CONFIG" ]; then
|
|
echo "Setting up oh-my-opencode-slim agents..."
|
|
|
|
# Determine installer flags
|
|
OMOS_TMUX_FLAG="no"
|
|
if [ "${OMOS_TMUX:-false}" = "true" ]; then
|
|
OMOS_TMUX_FLAG="yes"
|
|
fi
|
|
|
|
OMOS_SKILLS_FLAG="yes"
|
|
if [ "${OMOS_SKILLS:-true}" = "false" ]; then
|
|
OMOS_SKILLS_FLAG="no"
|
|
fi
|
|
|
|
bun x oh-my-opencode-slim@latest install \
|
|
--no-tui \
|
|
--tmux="${OMOS_TMUX_FLAG}" \
|
|
--skills="${OMOS_SKILLS_FLAG}"
|
|
|
|
echo "oh-my-opencode-slim configured successfully."
|
|
else
|
|
echo "oh-my-opencode-slim config found at $OMOS_CONFIG (use OMOS_RESET=true to overwrite)."
|
|
|
|
# Allow reset via env var (creates backup automatically)
|
|
if [ "${OMOS_RESET:-false}" = "true" ]; then
|
|
echo "OMOS_RESET=true — regenerating oh-my-opencode-slim config..."
|
|
OMOS_TMUX_FLAG="no"
|
|
[ "${OMOS_TMUX:-false}" = "true" ] && OMOS_TMUX_FLAG="yes"
|
|
OMOS_SKILLS_FLAG="yes"
|
|
[ "${OMOS_SKILLS:-true}" = "false" ] && OMOS_SKILLS_FLAG="no"
|
|
|
|
bun x oh-my-opencode-slim@latest install \
|
|
--no-tui \
|
|
--tmux="${OMOS_TMUX_FLAG}" \
|
|
--skills="${OMOS_SKILLS_FLAG}" \
|
|
--reset
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# ── Execute command ──────────────────────────────────────────────────
|
|
exec "$@"
|