feat(extensions/pi): ship pi-env.zsh shell loader

The loader that sources ~/.config/pi/.env into every shell was only
living in the myconfigs tor-ms22 backup \u2014 a fresh machine had nowhere
to get it from except copying by hand. Now canonical here.

- extensions/pi/pi-env.zsh: 20-line POSIX-compatible loader
  (set -a; source ~/.config/pi/.env; set +a). Works in bash and zsh.
- install.sh install_pi_env_loader:
  * oh-my-zsh detected (~/.oh-my-zsh/custom/ exists)
    \u2192 cp into that dir (NOT symlink \u2014 that dir is typically part of
      a dotfiles backup, and a symlink to mempalace-toolkit would
      break when restored on another host).
    \u2192 Idempotent: if target content matches repo, says 'already
      installed'. If it differs, leaves user edits alone and points
      at diff for manual reconcile.
  * No oh-my-zsh \u2192 prints source-this-line snippet for ~/.zshrc or
    ~/.bashrc (derived from $SHELL). Does NOT auto-edit rc files.
- install.sh uninstall: only removes the copy if content still matches
  repo. Local edits preserved.
- Docs:
  * extensions/pi/README.md Environment setup section rewritten with
    both install paths, step 5 of deploy recipe updated.
  * AGENTS.md Structure block lists pi-env.zsh.
  * Root README repo-contents line mentions it.

Verified on tor-ms22: install fresh \u2192 uninstall (content match \u2192 remove)
\u2192 reinstall \u2192 zsh -ic loads AWS vars correctly. Also tested bash fallback
path via HOME=/tmp/fake-home SHELL=/bin/bash \u2014 prints right .bashrc snippet.
This commit is contained in:
2026-05-05 16:58:56 +02:00
parent 5d8f523cb3
commit 118bd20fec
5 changed files with 136 additions and 7 deletions
+77
View File
@@ -29,6 +29,10 @@ PI_KEYS_DEST="${HOME}/.pi/agent/keybindings.json"
PI_SETTINGS_EXAMPLE="${SCRIPT_DIR}/extensions/pi/settings.example.json"
PI_SETTINGS_DEST="${HOME}/.pi/agent/settings.json"
# pi env loader (shell glue that sources ~/.config/pi/.env into every shell)
PI_ENV_SRC="${SCRIPT_DIR}/extensions/pi/pi-env.zsh"
PI_ENV_OMZ_DEST="${HOME}/.oh-my-zsh/custom/pi-env.zsh"
# ── args ─────────────────────────────────────────────
ACTION="install"
ASSUME_YES="no"
@@ -58,6 +62,14 @@ What install does:
- If pi exists, warns if ~/.pi/agent/settings.json is missing and points
at extensions/pi/settings.example.json as a template (NOT symlinked —
pi rewrites this file at runtime).
- If oh-my-zsh is detected (~/.oh-my-zsh/custom/ exists), copies
extensions/pi/pi-env.zsh into ~/.oh-my-zsh/custom/pi-env.zsh so every
new zsh shell sources ~/.config/pi/.env. Uses cp (not symlink) because
that dir gets backed up by rsync_copy and symlinks would break
portability. Re-runs are idempotent when content matches the repo;
warns and leaves local edits alone if they differ.
- If oh-my-zsh is NOT detected, prints a shell-specific source snippet
for ~/.zshrc or ~/.bashrc. Does not auto-edit rc files.
- Warns if AWS_PROFILE / AWS_REGION are unset (only relevant to users
whose pi settings.json selects amazon-bedrock as defaultProvider).
- Drops a .skill-source marker in the skill dir so sibling tooling
@@ -292,6 +304,56 @@ install_pi_keybindings() {
ok "Linked keybindings.json → $PI_KEYS_SRC"
}
install_pi_env_loader() {
# Ship pi-env.zsh (sources ~/.config/pi/.env so AWS vars etc. are in
# every shell that starts pi). Two paths depending on shell setup:
#
# 1. oh-my-zsh present → cp into ~/.oh-my-zsh/custom/ (auto-loaded by
# omz). cp not symlink because that directory is typically part of
# a dotfiles backup (rsync_copy.sh in the myconfigs repo) and a
# symlink into mempalace-toolkit would break when restored on
# another host.
# 2. No oh-my-zsh → print a source snippet for ~/.zshrc or ~/.bashrc.
# We don't auto-edit rc files — too invasive for an optional glue
# file. The loader itself is POSIX-compatible (set -a / source /
# set +a), so bash users can source it directly.
[[ -d "$PI_EXT_DEST_DIR" ]] || return 0 # no pi → skip
if [[ -d "$HOME/.oh-my-zsh/custom" ]]; then
note "Installing pi-env.zsh into ~/.oh-my-zsh/custom/"
if [[ -f "$PI_ENV_OMZ_DEST" ]]; then
if cmp -s "$PI_ENV_SRC" "$PI_ENV_OMZ_DEST"; then
ok "pi-env.zsh already installed (content matches repo)"
return 0
fi
warn "$PI_ENV_OMZ_DEST exists and differs from repo copy"
printf ' Leaving your edits alone. Compare with:\n'
printf ' diff %q %q\n' "$PI_ENV_OMZ_DEST" "$PI_ENV_SRC"
printf ' To adopt the repo version: rm that file and re-run install.sh\n'
return 0
fi
cp "$PI_ENV_SRC" "$PI_ENV_OMZ_DEST"
ok "Copied pi-env.zsh → $PI_ENV_OMZ_DEST"
printf ' Open a new shell (or `exec zsh`) to load AWS_PROFILE / AWS_REGION.\n'
return 0
fi
# No oh-my-zsh — print shell-specific snippet.
note "oh-my-zsh not detected — manual shell setup needed"
local shell_name
shell_name="$(basename "${SHELL:-bash}")"
local rc_file
case "$shell_name" in
zsh) rc_file="~/.zshrc" ;;
bash) rc_file="~/.bashrc" ;;
*) rc_file="~/.${shell_name}rc # adjust for your shell" ;;
esac
printf ' Add this line to %s so every shell sources ~/.config/pi/.env:\n' "$rc_file"
printf ' source %q\n' "$PI_ENV_SRC"
printf ' (the loader itself is POSIX-compatible — works in bash and zsh.)\n'
}
# ── Verify ~/.pi/agent/settings.json exists ──────────────────────────
# If pi is installed but settings.json is missing, `pi` refuses to start
# without `--provider ... --model ...` on every invocation. The toolkit
@@ -370,6 +432,8 @@ do_install() {
echo
install_pi_keybindings
echo
install_pi_env_loader
echo
check_path
echo
check_wake_up_protocol
@@ -436,6 +500,19 @@ do_uninstall() {
ok "No pi keybindings symlink to remove"
fi
echo
note "Removing pi-env.zsh loader (oh-my-zsh path)"
# Only remove if content still matches the repo copy — user may have
# local edits we shouldn't silently discard.
if [[ -f "$PI_ENV_OMZ_DEST" ]] && cmp -s "$PI_ENV_SRC" "$PI_ENV_OMZ_DEST"; then
rm "$PI_ENV_OMZ_DEST"
ok "Removed $PI_ENV_OMZ_DEST"
elif [[ -f "$PI_ENV_OMZ_DEST" ]]; then
warn "$PI_ENV_OMZ_DEST differs from repo copy — left alone"
else
ok "No pi-env.zsh loader to remove"
fi
# Remove the marker and the now-empty skill directory, but only if
# the marker was written by us and the directory has nothing else in it.
local marker="$SKILL_DEST_DIR/.skill-source"