Files
ai-sandbox/install.sh
T
ducoterra 8ee535f6ae bridge the host pi config, with the credential by env only
The image ships pi with no provider and no preferences, so a sandboxed run
meant configuring the model twice. ai-sandbox now reads the host
~/.pi/agent/{models,settings}.json and rewrites them instead of copying them:
every provider apiKey becomes "$AI_API_TOKEN" (pi resolves an env reference
itself, so no value is written to disk), '!command' header values are dropped
rather than executed, settings that point into $HOME are dropped because that
path is not mounted, and auth.json / models-store.json / sessions / extensions
are never read.

The rewritten pair is seeded into /home/sandbox/.pi/agent at container start,
owned by uid 1000 and mode 600, and is treated as managed: a host change is
re-seeded, an edit made inside the sandbox is kept and reported, a deletion
takes the host version again.

The token follows the existing environment rules -- one variable, passed by
name through the 0600 env file, announced when auto-passed. A bridged run
whose token variable is unset or empty is refused instead of starting a pi
that cannot reach its model, and the bridge never widens the allowlist: it
warns with the exact --allow to add.

Docs and examples now use a self-hosted gateway (https://aipi.reeseapps.com)
instead of vendor API endpoints, since that is the only thing this tool is
used against. 391 assertions pass (make lint, ./tests/run.sh --e2e).

LLM-Generated: true
2026-10-27 17:29:17 -04:00

65 lines
2.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# install.sh -- put ai-sandbox on PATH and wire up an alias.
#
# ./install.sh install to ~/.local/bin, print the alias line
# ./install.sh --alias pi also append the alias to ~/.bashrc
# ./install.sh --prefix DIR install somewhere else
# ./install.sh --uninstall remove what this script installed
set -Eeuo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PREFIX="${HOME}/.local/bin"
ALIAS_NAME=""
UNINSTALL=0
while (($#)); do
case "$1" in
--prefix) PREFIX="${2:?--prefix needs a directory}"; shift 2 ;;
--prefix=*) PREFIX="${1#*=}"; shift ;;
--alias) ALIAS_NAME="${2:?--alias needs a name, e.g. --alias pi}"; shift 2 ;;
--alias=*) ALIAS_NAME="${1#*=}"; shift ;;
--uninstall) UNINSTALL=1; shift ;;
-h|--help) sed -n '2,10p' "$0"; exit 0 ;;
*) echo "unknown option: $1" >&2; exit 2 ;;
esac
done
target="$PREFIX/ai-sandbox"
rcfile="${HOME}/.bashrc"
if (( UNINSTALL )); then
[[ -L "$target" || -f "$target" ]] && { rm -f "$target"; echo "removed $target"; } || echo "nothing at $target"
if [[ -n "$ALIAS_NAME" ]]; then
tmp="$(mktemp)"
grep -v "^alias ${ALIAS_NAME}=" "$rcfile" > "$tmp" 2>/dev/null || true
mv "$tmp" "$rcfile"; echo "removed the ${ALIAS_NAME} alias from $rcfile"
fi
exit 0
fi
[[ -x "$HERE/bin/ai-sandbox" ]] || { echo "bin/ai-sandbox is missing or not executable" >&2; exit 1; }
command -v podman > /dev/null || echo "warning: podman is not installed; ai-sandbox needs it"
mkdir -p "$PREFIX"
ln -sfn "$HERE/bin/ai-sandbox" "$target"
echo "installed $target -> $HERE/bin/ai-sandbox"
if [[ -n "$ALIAS_NAME" ]]; then
line="alias ${ALIAS_NAME}='${target}'"
if grep -qxF "$line" "$rcfile" 2>/dev/null; then
echo "alias already present in $rcfile"
else
printf '\n# added by ai-sandbox install.sh\n%s\n' "$line" >> "$rcfile"
echo "added to $rcfile: $line"
fi
else
echo
echo "To use it as a harness wrapper, add this to $rcfile:"
echo " alias pi='$target'"
echo "then: source $rcfile && cd your/project && pi --allow aipi.reeseapps.com --env AI_API_TOKEN"
fi
echo
echo "next: $target doctor # sanity-check this machine"
echo " $target build # build the sandbox image now (otherwise built on first run)"