Skip to content

Commit a2b67ce

Browse files
committed
fix: reshape config repo to ~/.pi/agent; migrate legacy ~/.pi layout
Pi and its extensions hardcode the agent dir at ~/.pi/agent/ (getAgentDir(), package-manager git/npm, lemonade auth/models-store). Move the config repo there and add a one-time migration that relocates legacy ~/.pi root contents (repo + runtime state) while preserving infra markers and sibling mounts. Update lpb-config and validate.sh paths accordingly.
1 parent 7e259c5 commit a2b67ce

5 files changed

Lines changed: 65 additions & 16 deletions

File tree

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# NOTE: Runtime extensions (lemonade-pi-plugin, lpb-memory) are NOT
1818
# built into the image. They are installed at container startup by
1919
# `pi update --extensions`, which reads their branches from the
20-
# config repo served at ~/.pi/settings.json → "packages" array.
20+
# config repo served at ~/.pi/agent/settings.json → "packages" array.
2121
# ═══════════════════════════════════════════════════════════════════════════
2222

2323
# Source fork configuration — ARG defaults come from lpb.stack.env

lpb.stack.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ LPB_PI_UPSTREAM=https://github.com/earendil-works/pi.git
2121
# ─── Config Preset ───────────────────────────────────────────────────────
2222
# Fork URL + branch of the preset repo (localpibox/config) baked into the
2323
# image. Repoint these to your own forked preset to fully customize the
24-
# runtime ~/.pi/ config without editing the repo.
24+
# runtime ~/.pi/agent/ config without editing the repo.
2525
LPB_CONFIG_FORK=https://github.com/localpibox/config.git
2626
LPB_CONFIG_REF=main
2727

support/lpb-config

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,28 @@ set -euo pipefail
1212
# Config repo location — override via env vars (see help below).
1313
# NOTE: positionals are reserved for the subcommand ($1), so the
1414
# repo path/remote/ref come from the environment, not $1/$2/$3.
15-
AGENT_DIR="${AGENT_DIR:-/home/lpb/.pi}"
15+
AGENT_DIR="${AGENT_DIR:-/home/lpb/.pi/agent}"
1616
CONFIG_REMOTE="${CONFIG_REMOTE:-https://github.com/localpibox/config.git}"
1717
CONFIG_REF="${CONFIG_REF:-main}"
1818

19+
# ── Migrate legacy ~/.pi root layout → ~/.pi/agent/ (one-time) ──────────
20+
# Mirrors the migration in start.sh: earlier builds kept the config repo at
21+
# ~/.pi/ root, which broke pi's hardcoded ~/.pi/agent/* paths. If the default
22+
# agent dir holds no repo but the legacy root does, relocate it so lpb-config
23+
# keeps working against the reshaped layout.
24+
if [[ "$AGENT_DIR" = "/home/lpb/.pi/agent" && -d "/home/lpb/.pi/.git" && ! -d "/home/lpb/.pi/agent/.git" ]]; then
25+
warn "Migrating legacy config layout from ~/.pi to ~/.pi/agent/ ..."
26+
mkdir -p "/home/lpb/.pi/agent"
27+
shopt -s dotglob nullglob
28+
for _item in "/home/lpb/.pi"/*; do
29+
case "$(basename "${_item}")" in
30+
.initialized|ssh-host-keys|gh-config|agent) continue ;;
31+
esac
32+
mv "${_item}" "/home/lpb/.pi/agent/" 2>/dev/null || true
33+
done
34+
shopt -u dotglob nullglob
35+
fi
36+
1937
# ─── Helpers ────────────────────────────────────────────────────────────────
2038
info() { echo "[lpb-config] $*"; }
2139
warn() { echo "[lpb-config] $*" >&2; }
@@ -206,7 +224,7 @@ case "${1:-help}" in
206224
echo " merge — Open git merge flow for advanced users"
207225
echo ""
208226
echo "Environment:"
209-
echo " AGENT_DIR — Config repo path (default: /home/lpb/.pi)"
227+
echo " AGENT_DIR — Config repo path (default: /home/lpb/.pi/agent)"
210228
echo " CONFIG_REMOTE — Git remote URL (default: https://github.com/localpibox/config.git)"
211229
echo " CONFIG_REF — Branch to track (default: main)"
212230
;;

support/start.sh

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -225,19 +225,50 @@ else
225225
info "Workspace: ${WORKSPACE_DIR} (${file_count} files)"
226226
fi
227227

228-
# ─── 4a. CONFIG REPO — CLONE/FETCH INTO ~/.pi/ (BEFORE FIRST-RUN) ─────────
229-
# The config repo (localpibox/config) IS the runtime config directory (~/.pi/).
230-
# No copy step — Pi reads the repo root directly via PI_CODING_AGENT_DIR.
231-
# Done BEFORE first-run mkdirs so ~/.pi/ is empty when we clone into it.
228+
# ─── 4a. CONFIG REPO — CLONE/FETCH INTO ~/.pi/agent/ (BEFORE FIRST-RUN) ────
229+
# The config repo (localpibox/config) IS the runtime agent config directory
230+
# (~/.pi/agent/). Pi reads the repo root directly via PI_CODING_AGENT_DIR.
231+
# The agent dir is ~/.pi/agent/ (upstream pi default) — NOT ~/.pi/ root —
232+
# because pi and its extensions hardcode that path: getAgentDir() defaults to
233+
# ~/.pi/agent/, package-manager keeps git/npm under <agentDir>/, and the
234+
# lemonade plugin reads/writes ~/.pi/agent/auth.json and models-store.json.
235+
# Done BEFORE first-run mkdirs so ~/.pi/agent/ is empty when we clone into it.
232236
# Runs every boot: clones on first run, non-destructive fetch afterwards.
233-
AGENT_DIR="${HOME_DIR}/.pi"
237+
AGENT_PI_ROOT="${HOME_DIR}/.pi"
238+
AGENT_DIR="${AGENT_PI_ROOT}/agent"
234239
# Config preset repo — baked into the image from lpb.stack.env (Dockerfile
235240
# ENV LPB_CONFIG_REMOTE / LPB_CONFIG_REF). Shell env can still override.
236241
CONFIG_REMOTE="${LPB_CONFIG_REMOTE:-${LPB_CONFIG_FORK:-https://github.com/localpibox/config.git}}"
237242
CONFIG_REF="${LPB_CONFIG_REF:-main}"
238243

239244
export PI_CODING_AGENT_DIR="${AGENT_DIR}"
240245

246+
# ── Migrate legacy ~/.pi root layout → ~/.pi/agent/ (one-time) ──────────
247+
# Earlier versions used ~/.pi/ root as the agent dir: the config repo (.git)
248+
# plus all runtime state (auth.json, models-store.json, sessions/, git/, npm/)
249+
# lived directly in ~/.pi. That broke pi's hardcoded ~/.pi/agent/* paths.
250+
# One-time relocation: move everything (repo + untracked runtime) into
251+
# ~/.pi/agent/, leaving only infra markers (.initialized, ssh-host-keys) at
252+
# the root. No-op on fresh volumes or already-reshaped ones.
253+
if [[ -d "${AGENT_PI_ROOT}/.git" && ! -d "${AGENT_DIR}/.git" ]]; then
254+
info "Migrating legacy config layout from ~/.pi to ~/.pi/agent/ ..."
255+
mkdir -p "${AGENT_DIR}"
256+
shopt -s dotglob nullglob
257+
for _item in "${AGENT_PI_ROOT}"/*; do
258+
case "$(basename "${_item}")" in
259+
# Keep infra + sibling mounts at the root:
260+
# .initialized — first-run marker
261+
# ssh-host-keys — persisted sshd host identity
262+
# gh-config — dedicated gh volume mount (~/.config/gh)
263+
# agent — the migration target itself
264+
.initialized|ssh-host-keys|gh-config|agent) continue ;;
265+
esac
266+
mv "${_item}" "${AGENT_DIR}/" 2>/dev/null || true
267+
done
268+
shopt -u dotglob nullglob
269+
info "Legacy config layout migrated to ${AGENT_DIR}."
270+
fi
271+
241272
if [[ ! -d "${AGENT_DIR}/.git" ]]; then
242273
if [[ -d "${AGENT_DIR}" && -n "$(ls -A "${AGENT_DIR}" 2>/dev/null)" ]]; then
243274
# ~/.pi already exists and is non-empty but not a git repo — e.g. stale
@@ -285,8 +316,8 @@ if [[ "$FIRST_RUN" = "true" ]]; then
285316
chown -R "$(id -u):$(id -g)" "${HOME_DIR}/.pi" "${HOME_DIR}/.npm" "${HOME_DIR}/.config" 2>/dev/null || true
286317
chmod -R u+rwX "${HOME_DIR}/.pi" "${HOME_DIR}/.npm" 2>/dev/null || true
287318

288-
mkdir -p "${HOME_DIR}/.pi/git" \
289-
"${HOME_DIR}/.pi/npm" \
319+
mkdir -p "${AGENT_DIR}/git" \
320+
"${AGENT_DIR}/npm" \
290321
"${HOME_DIR}/.venvs"
291322

292323
npm config set prefix '/home/lpb/.npm-global' 2>/dev/null || true
@@ -300,7 +331,7 @@ if [[ "$FIRST_RUN" = "true" ]]; then
300331
npm config set allow-scripts 'better-sqlite3 agent-browser esbuild protobufjs @google/genai' 2>/dev/null || true
301332

302333
# Pre-create .npmrc so npm reads allow-scripts from parent dir
303-
printf 'allow-scripts=better-sqlite3\nallow-scripts=agent-browser\nallow-scripts=esbuild\nallow-scripts=protobufjs\nallow-scripts=@google/genai\n' > "${HOME_DIR}/.pi/git/.npmrc" 2>/dev/null || true
334+
printf 'allow-scripts=better-sqlite3\nallow-scripts=agent-browser\nallow-scripts=esbuild\nallow-scripts=protobufjs\nallow-scripts=@google/genai\n' > "${AGENT_DIR}/git/.npmrc" 2>/dev/null || true
304335
printf 'allow-scripts=better-sqlite3\nallow-scripts=agent-browser\nallow-scripts=esbuild\nallow-scripts=protobufjs\nallow-scripts=@google/genai\n' > "${HOME_DIR}/.npmrc" 2>/dev/null || true
305336

306337
# Fix pi-coding-agent package.json to include allowScripts
@@ -323,7 +354,7 @@ with open(sys.argv[1], 'w') as f: json.dump(pkg, f, indent=2)
323354
info "Patched pi-coding-agent package.json with allowScripts."
324355
fi
325356

326-
# ── Config repo: clone/fetch into ~/.pi/ (runs every boot — see §4a) ──
357+
# ── Config repo: clone/fetch into ~/.pi/agent/ (runs every boot — see §4a)
327358
touch "${HOME_DIR}/.pi/.initialized"
328359

329360
# ── Unlock the user account with a random password ──────────────────
@@ -430,7 +461,7 @@ persist_devstack_env
430461
431462
debug "Checking native modules..."
432463
NEED_REBUILD=false
433-
EXT_BASE="${HOME_DIR}/.pi/git"
464+
EXT_BASE="${AGENT_DIR}/git"
434465
435466
# Look for any better-sqlite3 that's missing its bindings
436467
while IFS= read -r pkg_json; do
@@ -478,7 +509,7 @@ if [[ "$NEED_REBUILD" = "true" ]]; then
478509
[[ -f "$path" ]] && binding_found=true && break
479510
done
480511
if [[ "$binding_found" = "false" ]]; then
481-
local_name=$(echo "$ext_dir" | sed "s|.*/\.pi/git/||")
512+
local_name=$(echo "$ext_dir" | sed "s|.*/\.pi/agent/git/||")
482513
info " Rebuilding: ${local_name}..."
483514
(cd "$ext_dir" && PATH="/home/lpb/.npm-global/bin:${PATH}" npm rebuild better-sqlite3 --loglevel=error 2>&1 | tail -3) || \
484515
warn " npm rebuild failed for ${local_name}, trying node-gyp..."

support/validate.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ echo ""
6262

6363
# ── 3. Native modules (better-sqlite3) ──────────────────────────────────────
6464
echo -e "${CYAN}── Native modules ────────────────────────────────────────${NC}"
65-
EXT_BASE="/home/lpb/.pi/git"
65+
EXT_BASE="/home/lpb/.pi/agent/git"
6666
# Find ALL better_sqlite3.node files (glob */*/ only matches 2 levels,
6767
# but extensions live at github.com/<org>/<repo>/node_modules/ = 3 levels).
6868
found_better_sqlite3=false

0 commit comments

Comments
 (0)