#!/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) shutil.rmtree(target / ".git", ignore_errors=True) 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)"