Files
Heretek-OpenCode Coordinator a37a393755 feat(homelab): compose topology, studio CLI, autonomy dial, cockpit projections, E2E mission
- 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
2026-10-12 12:49:03 -04:00

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