Skip to content

Commit 87d1809

Browse files
committed
fix: config repo init over non-empty ~/.pi + correct extension root
The refactor made ~/.pi (a persistent bind mount) BE the config repo clone, but booting over existing pre-refactor state made 'git clone' fail silently, leaving no settings.json → no packages → no extension installs. - start.sh: init the config repo in place (git init + fetch + reset --hard) when ~/.pi is non-empty but not a git repo instead of relying on clone. - start.sh/validate.sh: point extension root at ~/.git (Pi's agentDir/git) instead of the old ~/.pi/agent/git for .npmrc, npm install and the better-sqlite3 native-module rebuild scan; also create ~/.pi/npm. - lpb-config: shared clone_or_init() so update/reset also survive a non-empty AGENT_DIR. - Dockerfile/lpb.stack.env comments: drop the stale .pi/agent path.
1 parent 110043e commit 87d1809

5 files changed

Lines changed: 56 additions & 17 deletions

File tree

Dockerfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
# LPB_PI_FORK, LPB_PI_REF, LPB_NODE_VERSION, LPB_VSCODIUM_VERSION
1515
#
1616
# NOTE: Runtime extensions (lemonade-pi-plugin, lpb-memory) are NOT
17-
# built into the image. They are cloned at container startup by
18-
# `pi update --extensions`, which reads their branches from
19-
# .pi/agent/settings.json → "packages" array.
17+
# built into the image. They are installed at container startup by
18+
# `pi update --extensions`, which reads their branches from the
19+
# config repo served at ~/.pi/settings.json → "packages" array.
2020
# ═══════════════════════════════════════════════════════════════════════════
2121

2222
# 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/agent config without editing the repo.
24+
# runtime ~/.pi/ 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: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,24 @@ info() { echo "[lpb-config] $*"; }
2121
warn() { echo "[lpb-config] $*" >&2; }
2222
err() { echo "[lpb-config] ERROR: $*" >&2; exit 1; }
2323

24+
# Clone the config repo, or initialize it in place when the target exists
25+
# and is non-empty (stale runtime state from previous boots). Mirrors the
26+
# logic in start.sh — `git clone` refuses a non-empty target directory.
27+
clone_or_init() {
28+
if [[ -d "${AGENT_DIR}" && -n "$(ls -A "${AGENT_DIR}" 2>/dev/null)" ]]; then
29+
warn "Config area not empty — initializing config repo in place..."
30+
git -C "${AGENT_DIR}" init -q
31+
git -C "${AGENT_DIR}" remote add origin "${CONFIG_REMOTE}" 2>/dev/null || true
32+
if git -C "${AGENT_DIR}" fetch --depth=1 origin "${CONFIG_REF}"; then
33+
git -C "${AGENT_DIR}" reset -q --hard "origin/${CONFIG_REF}" 2>/dev/null || true
34+
else
35+
err "Failed to fetch config repo"
36+
fi
37+
else
38+
git clone --depth=1 --branch "${CONFIG_REF}" "${CONFIG_REMOTE}" "${AGENT_DIR}"
39+
fi
40+
}
41+
2442
# ─── status ─────────────────────────────────────────────────────────────────
2543
cmd_status() {
2644
if [[ ! -d "${AGENT_DIR}/.git" ]]; then
@@ -69,8 +87,8 @@ cmd_status() {
6987
cmd_update() {
7088
if [[ ! -d "${AGENT_DIR}/.git" ]]; then
7189
info "Cloning config repo from ${CONFIG_REMOTE}..."
72-
git clone --depth=1 --branch "${CONFIG_REF}" "${CONFIG_REMOTE}" "${AGENT_DIR}"
73-
info "Cloned. Run 'lpb-config status' to verify."
90+
clone_or_init
91+
info "Done. Run 'lpb-config status' to verify."
7492
exit 0
7593
fi
7694

@@ -118,8 +136,8 @@ cmd_update() {
118136
cmd_reset() {
119137
if [[ ! -d "${AGENT_DIR}/.git" ]]; then
120138
info "Cloning config repo from ${CONFIG_REMOTE}..."
121-
git clone --depth=1 --branch "${CONFIG_REF}" "${CONFIG_REMOTE}" "${AGENT_DIR}"
122-
info "Cloned."
139+
clone_or_init
140+
info "Done."
123141
exit 0
124142
fi
125143

support/start.sh

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,31 @@ CONFIG_REF="${LPB_CONFIG_REF:-main}"
222222
export PI_CODING_AGENT_DIR="${AGENT_DIR}"
223223

224224
if [[ ! -d "${AGENT_DIR}/.git" ]]; then
225-
info "Cloning config repo from ${CONFIG_REMOTE}..."
226-
if git clone --depth=1 --branch "${CONFIG_REF}" "${CONFIG_REMOTE}" "${AGENT_DIR}"; then
227-
info "Config repo cloned."
225+
if [[ -d "${AGENT_DIR}" && -n "$(ls -A "${AGENT_DIR}" 2>/dev/null)" ]]; then
226+
# ~/.pi already exists and is non-empty but not a git repo — e.g. stale
227+
# pre-refactor state, or a fresh container booting over a persisted
228+
# ~/.pi volume. `git clone` refuses a non-empty target, so initialize
229+
# the repo in place instead. Existing files are left untouched
230+
# (gitignored by the config repo) so nothing is lost.
231+
info "Config area not empty — initializing config repo in place..."
232+
if git -C "${AGENT_DIR}" init -q \
233+
&& git -C "${AGENT_DIR}" remote add origin "${CONFIG_REMOTE}" 2>/dev/null \
234+
&& git -C "${AGENT_DIR}" fetch --depth=1 origin "${CONFIG_REF}"; then
235+
# Reset to the fetched ref: tracked files land at the repo root,
236+
# untracked runtime state stays as-is. No force (won't clobber a
237+
# conflicting local i.e. settings file).
238+
git -C "${AGENT_DIR}" reset -q --hard "origin/${CONFIG_REF}" 2>/dev/null || true
239+
info "Config repo initialized."
240+
else
241+
warn "Config repo initialization failed — Pi will use defaults."
242+
fi
228243
else
229-
warn "Config clone failed — Pi will use defaults."
244+
info "Cloning config repo from ${CONFIG_REMOTE}..."
245+
if git clone --depth=1 --branch "${CONFIG_REF}" "${CONFIG_REMOTE}" "${AGENT_DIR}"; then
246+
info "Config repo cloned."
247+
else
248+
warn "Config clone failed — Pi will use defaults."
249+
fi
230250
fi
231251
else
232252
# Non-destructive fetch only — local customizations are never wiped.
@@ -248,7 +268,8 @@ if [[ "$FIRST_RUN" = "true" ]]; then
248268
chown -R "$(id -u):$(id -g)" "${HOME_DIR}/.pi" "${HOME_DIR}/.npm" "${HOME_DIR}/.config" 2>/dev/null || true
249269
chmod -R u+rwX "${HOME_DIR}/.pi" "${HOME_DIR}/.npm" 2>/dev/null || true
250270

251-
mkdir -p "${HOME_DIR}/.pi/agent/git" \
271+
mkdir -p "${HOME_DIR}/.pi/git" \
272+
"${HOME_DIR}/.pi/npm" \
252273
"${HOME_DIR}/.venvs"
253274

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

264285
# Pre-create .npmrc so npm reads allow-scripts from parent dir
265-
printf 'allow-scripts=better-sqlite3\nallow-scripts=agent-browser\nallow-scripts=esbuild\nallow-scripts=protobufjs\nallow-scripts=@google/genai\n' > "${HOME_DIR}/.pi/agent/git/.npmrc" 2>/dev/null || true
286+
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
266287
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
267288

268289
# Fix pi-coding-agent package.json to include allowScripts
@@ -373,7 +394,7 @@ persist_devstack_env
373394
374395
debug "Checking native modules..."
375396
NEED_REBUILD=false
376-
EXT_BASE="${HOME_DIR}/.pi/agent/git"
397+
EXT_BASE="${HOME_DIR}/.pi/git"
377398
378399
# Look for any better-sqlite3 that's missing its bindings
379400
while IFS= read -r pkg_json; do
@@ -421,7 +442,7 @@ if [[ "$NEED_REBUILD" = "true" ]]; then
421442
[[ -f "$path" ]] && binding_found=true && break
422443
done
423444
if [[ "$binding_found" = "false" ]]; then
424-
local_name=$(echo "$ext_dir" | sed "s|.*/agent/git/||")
445+
local_name=$(echo "$ext_dir" | sed "s|.*/\.pi/git/||")
425446
info " Rebuilding: ${local_name}..."
426447
(cd "$ext_dir" && PATH="/home/lpb/.npm-global/bin:${PATH}" npm rebuild better-sqlite3 --loglevel=error 2>&1 | tail -3) || \
427448
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
@@ -60,7 +60,7 @@ echo ""
6060

6161
# ── 3. Native modules (better-sqlite3) ──────────────────────────────────────
6262
echo -e "${CYAN}── Native modules ────────────────────────────────────────${NC}"
63-
EXT_BASE="/home/lpb/.pi/agent/git"
63+
EXT_BASE="/home/lpb/.pi/git"
6464
for ext_dir in "${EXT_BASE}"/*/*/node_modules/better-sqlite3; do
6565
[ -d "$ext_dir" ] || continue
6666
ext_name=$(basename "$(dirname "$ext_dir")")

0 commit comments

Comments
 (0)