@@ -225,19 +225,50 @@ else
225225 info " Workspace: ${WORKSPACE_DIR} (${file_count} files)"
226226fi
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.
236241CONFIG_REMOTE= " ${LPB_CONFIG_REMOTE:- ${LPB_CONFIG_FORK:- https:// github.com/ localpibox/ config.git} } "
237242CONFIG_REF= " ${LPB_CONFIG_REF:- main} "
238243
239244export 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+
241272if [[ ! -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
431462debug " Checking native modules..."
432463NEED_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
436467while 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..."
0 commit comments