mirror of
https://github.com/Heretek-OpenCode/heretek-opencode.git
synced 2026-11-09 17:18:05 -10:00
- compose.yaml: distro :2.0.26-r1 (4096+healthcheck), gateway (POST /mcp), fleet (bun run), valkey; frontend (gateway-egress-only) + internal (isolated) networks; state vs workspace-disposable volumes; all rootless - compose.override.dev.yaml: local live mounts, no privilege escalation - scripts/studio (POSIX sh, +x): init refuses privileged-dev without ALLOW_PRIVILEGED=1, generates OPENCODE_PASSWORD; up/down/logs/status wrap docker compose - scripts/test-e2e-mission.ts: mock-adapter canonical mission (grill 3 criteria, research provenance envelope+hash, 1-task DAG, tmp patch, GateReport via SDK schema, dual QA reports, PR evidence table, prev-hash journal verify); 19 PASS, no network/docker - config/autonomy.json + src/autonomy.ts: advisory/balanced/full dial gate - cockpit projections (pure Fleet-event fold + MissionViewer) with tests - package @heretek-ai/homelab + READMEs
101 lines
3.3 KiB
Bash
Executable File
101 lines
3.3 KiB
Bash
Executable File
#!/bin/sh
|
|
# studio — homelab operator CLI (POSIX sh): init|up|down|logs|status.
|
|
# init — rootless .env writer. REFUSES privileged-dev unless ALLOW_PRIVILEGED=1.
|
|
# up — docker compose up -d (dev override only with ALLOW_PRIVILEGED=1).
|
|
# down — docker compose down (passes extra args, e.g. -v for volume drills).
|
|
# logs — docker compose logs (passes service/flag args).
|
|
# status — docker compose ps + config sanity.
|
|
set -eu
|
|
|
|
HERE=$(CDPATH= cd -- "$(dirname -- "$0")" >/dev/null 2>&1 && pwd)
|
|
PKGDIR=$(CDPATH= cd -- "$HERE/.." >/dev/null 2>&1 && pwd)
|
|
ENVFILE="$PKGDIR/.env"
|
|
COMPOSE="$PKGDIR/compose.yaml"
|
|
DEV_OVERRIDE="$PKGDIR/compose.override.dev.yaml"
|
|
|
|
usage() {
|
|
echo "usage: studio {init|up|down|logs|status} [args...]" >&2
|
|
echo " init write rootless .env (refuses privileged-dev without ALLOW_PRIVILEGED=1)" >&2
|
|
echo " up docker compose up -d" >&2
|
|
echo " down docker compose down [extra args]" >&2
|
|
echo " logs docker compose logs [service...]" >&2
|
|
echo " status docker compose ps + config check" >&2
|
|
exit 2
|
|
}
|
|
|
|
gen_password() {
|
|
if command -v openssl >/dev/null 2>&1; then
|
|
openssl rand -base64 24 | tr -d '\n'
|
|
else
|
|
# fallback: bun hash of pid+time (no key material logged)
|
|
bun -e 'console.log(require("node:crypto").randomBytes(18).toString("base64"))' 2>/dev/null || echo "CHANGE_ME_$(date +%s)"
|
|
fi
|
|
}
|
|
|
|
cmd_init() {
|
|
if [ -f "$ENVFILE" ]; then
|
|
echo "studio init: $ENVFILE exists; refusing to overwrite (delete it to re-init)" >&2
|
|
exit 1
|
|
fi
|
|
if [ "${PRIVILEGED_DEV:-0}" = "1" ] && [ "${ALLOW_PRIVILEGED:-0}" != "1" ]; then
|
|
echo "studio init: REFUSED privileged-dev without explicit ALLOW_PRIVILEGED=1" >&2
|
|
echo "Rootless is the default. Re-run with ALLOW_PRIVILEGED=1 only on a trusted local machine." >&2
|
|
exit 1
|
|
fi
|
|
PASS=$(gen_password)
|
|
{
|
|
echo "# Generated by scripts/studio init — rootless defaults. Do not commit."
|
|
echo "OPENCODE_PASSWORD=$PASS"
|
|
echo "DISTRO_PORT=${DISTRO_PORT:-4096}"
|
|
echo "GATEWAY_PORT=${GATEWAY_PORT:-8080}"
|
|
echo "FLEET_PORT=${FLEET_PORT:-7070}"
|
|
echo "FLEET_AUTONOMY=${FLEET_AUTONOMY:-balanced}"
|
|
echo "HOST_UID=$(id -u)"
|
|
echo "HOST_GID=$(id -g)"
|
|
} > "$ENVFILE"
|
|
chmod 600 "$ENVFILE"
|
|
echo "studio init: wrote $ENVFILE (0600, OPENCODE_PASSWORD generated, ports ${DISTRO_PORT:-4096}/${GATEWAY_PORT:-8080}/${FLEET_PORT:-7070})"
|
|
}
|
|
|
|
compose_files() {
|
|
if [ "${ALLOW_PRIVILEGED:-0}" = "1" ]; then
|
|
echo "studio: privileged dev override ENABLED (explicit ALLOW_PRIVILEGED=1)" >&2
|
|
printf '%s\n' "-f" "$COMPOSE" "-f" "$DEV_OVERRIDE"
|
|
else
|
|
printf '%s\n' "-f" "$COMPOSE"
|
|
fi
|
|
}
|
|
|
|
cmd_up() {
|
|
# shellcheck disable=SC2046
|
|
docker compose $(compose_files) --env-file "$ENVFILE" up -d "$@"
|
|
}
|
|
|
|
cmd_down() {
|
|
# shellcheck disable=SC2046
|
|
docker compose $(compose_files) --env-file "$ENVFILE" down "$@"
|
|
}
|
|
|
|
cmd_logs() {
|
|
# shellcheck disable=SC2046
|
|
docker compose $(compose_files) --env-file "$ENVFILE" logs "$@"
|
|
}
|
|
|
|
cmd_status() {
|
|
# shellcheck disable=SC2046
|
|
docker compose $(compose_files) --env-file "$ENVFILE" ps
|
|
# shellcheck disable=SC2046
|
|
docker compose $(compose_files) --env-file "$ENVFILE" config -q && echo "studio status: compose config OK"
|
|
}
|
|
|
|
[ $# -ge 1 ] || usage
|
|
CMD="$1"; shift
|
|
case "$CMD" in
|
|
init) cmd_init "$@" ;;
|
|
up) cmd_up "$@" ;;
|
|
down) cmd_down "$@" ;;
|
|
logs) cmd_logs "$@" ;;
|
|
status) cmd_status "$@" ;;
|
|
*) usage ;;
|
|
esac
|