Files
lvmh/deploy/rsync-pi-agent.sh
T

73 lines
2.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Sync the user's pi config (from dotfiles) into docker/pi-agent/ so the
# worker image bakes it. Filtered: no secrets, no machine-local state.
set -euo pipefail
SRC="${LVMH_PI_AGENT_DIR:-$HOME/.dotfiles/pi/agent}"
DEST="${LVMH_PI_BAKE_DIR:-$(dirname "$0")/../docker/pi-agent}"
# DEST must exist even without dotfiles: the worker Dockerfile COPYs it
# unconditionally (a missing dir would fail the build).
mkdir -p "$DEST"
if [ ! -f "$SRC/settings.json" ]; then
echo "rsync-pi-agent: $SRC/settings.json not found — skipping dotfiles sync" >&2
exit 0
fi
rsync -a --delete \
--exclude 'auth.json' \
--exclude 'models.json' \
--exclude 'models-store.json' \
--exclude 'sessions/' \
--exclude 'cache/' \
--exclude 'npm/' \
--exclude 'git/' \
--exclude 'trust.json' \
--exclude 'mcp-*' \
--exclude 'run-history*' \
--exclude 'vibes' \
--exclude '*.log' \
--exclude 'scratch/' \
--exclude '.pi/' \
"$SRC/" "$DEST/"
# Pre-seed the git: package cache: clone each pinned git: package into
# docker/pi-agent/git/... where pi's package manager installs them, with
# lifecycle scripts ignored (postinstalls like husky crash headless).
# Keeps subagents/todo/async tooling present with no runtime network need.
# Requires network access to github.com at bake time.
python3 - "$DEST" <<'PY'
import json, re, shutil, subprocess, sys
from pathlib import Path
dest = Path(sys.argv[1])
settings = json.loads((dest / "settings.json").read_text())
git_root = dest / "git"
if git_root.exists():
shutil.rmtree(git_root)
for pkg in settings.get("packages") or []:
if not pkg.startswith("git:"):
continue
rest = pkg[4:]
m = re.match(r"^(.+)@([0-9a-f]{7,40})$", rest)
repo, ref = (m.group(1), m.group(2)) if m else (rest, None)
target = git_root / repo
target.parent.mkdir(parents=True, exist_ok=True)
url = f"https://{repo}" if not repo.startswith("https://") else repo
print(f"rsync-pi-agent: cloning {repo}@{ref or 'HEAD'}")
subprocess.run(["git", "clone", "--quiet", url, str(target)], check=True)
if ref:
subprocess.run(["git", "checkout", "--quiet", ref], cwd=target, check=True)
# keep .git: pi's package manager runs `git fetch` + `rev-parse` on
# existing installs; a stripped dir would fail resolution.
if (target / "package.json").exists():
npm = "/usr/bin/npm" if Path("/usr/bin/npm").exists() else "npm"
subprocess.run(
[npm, "install", "--omit=dev", "--ignore-scripts", "--no-audit", "--no-fund"],
cwd=target, check=True, capture_output=True,
)
PY
echo "rsync-pi-agent: synced $(find "$DEST" -type f | wc -l) files from $SRC (git: packages preserved)"