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:
@@ -22,6 +22,7 @@ extensions/
|
|||||||
pi/ # pi coding-agent bring-up: MCP bridge, keybindings, settings template
|
pi/ # pi coding-agent bring-up: MCP bridge, keybindings, settings template
|
||||||
mempalace.ts # Symlinked into ~/.pi/agent/extensions/ (MCP <→ pi glue)
|
mempalace.ts # Symlinked into ~/.pi/agent/extensions/ (MCP <→ pi glue)
|
||||||
keybindings.json # Symlinked into ~/.pi/agent/ (mosh/tmux newline fix)
|
keybindings.json # Symlinked into ~/.pi/agent/ (mosh/tmux newline fix)
|
||||||
|
pi-env.zsh # Copied into ~/.oh-my-zsh/custom/ or sourced from .bashrc (loads ~/.config/pi/.env)
|
||||||
settings.example.json # Template; user copies + edits (pi rewrites settings.json at runtime)
|
settings.example.json # Template; user copies + edits (pi rewrites settings.json at runtime)
|
||||||
README.md # Extension internals, schema-passthrough gotcha, env setup
|
README.md # Extension internals, schema-passthrough gotcha, env setup
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Producer-side tooling for [MemPalace](https://github.com/MemPalace/mempalace)
|
|||||||
- `bin/mempalace-docs` — mines project directories into MemPalace while excluding source code, keeping the palace signal-dense.
|
- `bin/mempalace-docs` — mines project directories into MemPalace while excluding source code, keeping the palace signal-dense.
|
||||||
- [`ARCHITECTURE.md`](ARCHITECTURE.md) — **canonical spec**: architecture diagram, component details, setup recipe, operational notes, upstream-retirement roadmap.
|
- [`ARCHITECTURE.md`](ARCHITECTURE.md) — **canonical spec**: architecture diagram, component details, setup recipe, operational notes, upstream-retirement roadmap.
|
||||||
- [`SKILL.md`](SKILL.md) — the companion agent skill, symlinked into `~/.agents/skills/opencode-mempalace-bridge/` on install.
|
- [`SKILL.md`](SKILL.md) — the companion agent skill, symlinked into `~/.agents/skills/opencode-mempalace-bridge/` on install.
|
||||||
- [`extensions/pi/`](extensions/pi/) — pi coding-agent bridge: the MemPalace MCP extension (symlinked), a mosh/tmux-friendly keybindings file (symlinked), and a `settings.example.json` template for starting pi without `--model`. `install.sh` also probes for `AWS_PROFILE`/`AWS_REGION` (needed by pi's Bedrock provider) and points at the recommended `~/.config/pi/.env` layout if missing.
|
- [`extensions/pi/`](extensions/pi/) — pi coding-agent bridge: the MemPalace MCP extension (symlinked), a mosh/tmux-friendly keybindings file (symlinked), a `pi-env.zsh` shell loader (copied into `~/.oh-my-zsh/custom/` on zsh+omz hosts, or source'd from `.bashrc` / `.zshrc` otherwise), and a `settings.example.json` template for starting pi without `--model`. `install.sh` also probes for `AWS_PROFILE`/`AWS_REGION` (needed by pi's Bedrock provider) and points at the recommended `~/.config/pi/.env` layout if missing.
|
||||||
|
|
||||||
**If you're just trying to get this working on a new machine → jump to [Setup](#setup).**
|
**If you're just trying to get this working on a new machine → jump to [Setup](#setup).**
|
||||||
**If you want the full architecture story → read [`ARCHITECTURE.md`](ARCHITECTURE.md).**
|
**If you want the full architecture story → read [`ARCHITECTURE.md`](ARCHITECTURE.md).**
|
||||||
|
|||||||
+29
-6
@@ -97,17 +97,22 @@ Run `pi --list-models` to confirm what your credentials can actually invoke.
|
|||||||
|
|
||||||
### 5. Ensure AWS env vars are live in your shell
|
### 5. Ensure AWS env vars are live in your shell
|
||||||
|
|
||||||
If you provisioned via step 1, `~/.config/pi/.env` exists and
|
**On zsh + oh-my-zsh hosts:** step 3's `install.sh` already copied
|
||||||
`~/.oh-my-zsh/custom/pi-env.zsh` sources it on every new shell. Verify:
|
`pi-env.zsh` into `~/.oh-my-zsh/custom/`, so every new shell sources
|
||||||
|
`~/.config/pi/.env` automatically. Verify:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
exec zsh
|
exec zsh
|
||||||
echo "$AWS_PROFILE $AWS_REGION" # should print your values
|
echo "$AWS_PROFILE $AWS_REGION" # should print your values
|
||||||
```
|
```
|
||||||
|
|
||||||
If empty, check that `~/.config/pi/.env` decrypted (`head ~/.config/pi/.env`
|
**On bash or plain zsh (no oh-my-zsh):** `install.sh` printed a
|
||||||
should show plain text, not binary). `git-crypt unlock` in step 1 is the
|
`source <repo>/extensions/pi/pi-env.zsh` snippet — add that one line to
|
||||||
usual culprit when this is empty.
|
`~/.bashrc` or `~/.zshrc`, open a fresh shell, verify as above.
|
||||||
|
|
||||||
|
If vars are empty, check that `~/.config/pi/.env` decrypted
|
||||||
|
(`head ~/.config/pi/.env` should show plain text, not binary).
|
||||||
|
`git-crypt unlock` in step 1 is the usual culprit when this is empty.
|
||||||
|
|
||||||
### 6. Register mempalace MCP with opencode (if using opencode too)
|
### 6. Register mempalace MCP with opencode (if using opencode too)
|
||||||
|
|
||||||
@@ -259,9 +264,26 @@ layout (matches the tor-ms22 dotfiles pattern):
|
|||||||
```
|
```
|
||||||
~/.config/pi/.env ← AWS_PROFILE=..., AWS_REGION=...
|
~/.config/pi/.env ← AWS_PROFILE=..., AWS_REGION=...
|
||||||
(git-crypt encrypted in dotfiles repo)
|
(git-crypt encrypted in dotfiles repo)
|
||||||
~/.oh-my-zsh/custom/pi-env.zsh ← set -a; source ~/.config/pi/.env; set +a
|
~/.oh-my-zsh/custom/pi-env.zsh ← installed by mempalace-toolkit install.sh
|
||||||
|
(sources the .env into every shell)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The loader file `pi-env.zsh` is canonical here in `extensions/pi/` and
|
||||||
|
installed by `install.sh` in one of two ways:
|
||||||
|
|
||||||
|
| Detected | Action |
|
||||||
|
|---|---|
|
||||||
|
| `~/.oh-my-zsh/custom/` exists | `cp` (not symlink) into that directory — auto-loaded by omz on every new shell. cp not symlink because that directory is part of the dotfiles backup, and a symlink into mempalace-toolkit would break when the backup is restored on another host. |
|
||||||
|
| No oh-my-zsh | Prints a shell-specific `source <repo>/extensions/pi/pi-env.zsh` snippet for `~/.zshrc` or `~/.bashrc`. Installer does not auto-edit rc files. |
|
||||||
|
|
||||||
|
The loader itself is POSIX-compatible (`set -a` / `source` / `set +a`),
|
||||||
|
so bash users can source it directly — no zsh dependency in the file.
|
||||||
|
|
||||||
|
Re-runs are idempotent: if the installed copy matches the repo, prints
|
||||||
|
"already installed". If it differs, leaves your edits alone and points
|
||||||
|
at `diff` for comparison. Uninstall only removes the file if it still
|
||||||
|
matches the repo copy; local edits are preserved.
|
||||||
|
|
||||||
Historical note: these vars used to live under a `# Environment variables
|
Historical note: these vars used to live under a `# Environment variables
|
||||||
for pi` block inside `~/.config/opencode/.env`. Split out 2026-05-05 so
|
for pi` block inside `~/.config/opencode/.env`. Split out 2026-05-05 so
|
||||||
each tool owns its own env file. `install.sh` runs a `check_aws_env`
|
each tool owns its own env file. `install.sh` runs a `check_aws_env`
|
||||||
@@ -276,6 +298,7 @@ mempalace-toolkit/
|
|||||||
├── README.md ← this file
|
├── README.md ← this file
|
||||||
├── mempalace.ts ← symlinked into ~/.pi/agent/extensions/
|
├── mempalace.ts ← symlinked into ~/.pi/agent/extensions/
|
||||||
├── keybindings.json ← symlinked into ~/.pi/agent/
|
├── keybindings.json ← symlinked into ~/.pi/agent/
|
||||||
|
├── pi-env.zsh ← cp'd into ~/.oh-my-zsh/custom/ (or source'd manually for bash)
|
||||||
└── settings.example.json ← template; copy + edit into ~/.pi/agent/
|
└── settings.example.json ← template; copy + edit into ~/.pi/agent/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Load pi coding-agent environment variables from ~/.config/pi/.env
|
||||||
|
#
|
||||||
|
# Canonical source: mempalace-toolkit/extensions/pi/pi-env.zsh
|
||||||
|
# Installed by mempalace-toolkit/install.sh via `cp` (not symlink) to keep
|
||||||
|
# ~/.oh-my-zsh/custom/ portable across machines with different $HOME paths.
|
||||||
|
# See extensions/pi/README.md#environment-setup for the full story.
|
||||||
|
#
|
||||||
|
# Sources ~/.config/pi/.env (AWS_PROFILE, AWS_REGION, and any future
|
||||||
|
# pi-scoped secrets) so pi's Bedrock provider works when spawned from any
|
||||||
|
# shell. The .env file itself is shipped (git-crypt encrypted) from the
|
||||||
|
# myconfigs dotfiles repo.
|
||||||
|
#
|
||||||
|
# `set -a` auto-exports every assignment in the sourced file, so plain
|
||||||
|
# KEY=VALUE lines become exported env vars without needing `export` in .env.
|
||||||
|
# Also works in bash (set -a and source are POSIX) — non-oh-my-zsh users
|
||||||
|
# can source this file directly from ~/.bashrc or ~/.zshrc instead.
|
||||||
|
#
|
||||||
|
# Historical note: these vars used to live in ~/.config/opencode/.env
|
||||||
|
# under a "# Environment variables for pi" block. Split out 2026-05-05
|
||||||
|
# so each tool owns its own env file.
|
||||||
|
|
||||||
|
_pi_env="${HOME}/.config/pi/.env"
|
||||||
|
if [[ -r "${_pi_env}" ]]; then
|
||||||
|
set -a
|
||||||
|
source "${_pi_env}"
|
||||||
|
set +a
|
||||||
|
fi
|
||||||
|
unset _pi_env
|
||||||
+77
@@ -29,6 +29,10 @@ PI_KEYS_DEST="${HOME}/.pi/agent/keybindings.json"
|
|||||||
PI_SETTINGS_EXAMPLE="${SCRIPT_DIR}/extensions/pi/settings.example.json"
|
PI_SETTINGS_EXAMPLE="${SCRIPT_DIR}/extensions/pi/settings.example.json"
|
||||||
PI_SETTINGS_DEST="${HOME}/.pi/agent/settings.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 ─────────────────────────────────────────────
|
# ── args ─────────────────────────────────────────────
|
||||||
ACTION="install"
|
ACTION="install"
|
||||||
ASSUME_YES="no"
|
ASSUME_YES="no"
|
||||||
@@ -58,6 +62,14 @@ What install does:
|
|||||||
- If pi exists, warns if ~/.pi/agent/settings.json is missing and points
|
- If pi exists, warns if ~/.pi/agent/settings.json is missing and points
|
||||||
at extensions/pi/settings.example.json as a template (NOT symlinked —
|
at extensions/pi/settings.example.json as a template (NOT symlinked —
|
||||||
pi rewrites this file at runtime).
|
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
|
- Warns if AWS_PROFILE / AWS_REGION are unset (only relevant to users
|
||||||
whose pi settings.json selects amazon-bedrock as defaultProvider).
|
whose pi settings.json selects amazon-bedrock as defaultProvider).
|
||||||
- Drops a .skill-source marker in the skill dir so sibling tooling
|
- 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"
|
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 ──────────────────────────
|
# ── Verify ~/.pi/agent/settings.json exists ──────────────────────────
|
||||||
# If pi is installed but settings.json is missing, `pi` refuses to start
|
# If pi is installed but settings.json is missing, `pi` refuses to start
|
||||||
# without `--provider ... --model ...` on every invocation. The toolkit
|
# without `--provider ... --model ...` on every invocation. The toolkit
|
||||||
@@ -370,6 +432,8 @@ do_install() {
|
|||||||
echo
|
echo
|
||||||
install_pi_keybindings
|
install_pi_keybindings
|
||||||
echo
|
echo
|
||||||
|
install_pi_env_loader
|
||||||
|
echo
|
||||||
check_path
|
check_path
|
||||||
echo
|
echo
|
||||||
check_wake_up_protocol
|
check_wake_up_protocol
|
||||||
@@ -436,6 +500,19 @@ do_uninstall() {
|
|||||||
ok "No pi keybindings symlink to remove"
|
ok "No pi keybindings symlink to remove"
|
||||||
fi
|
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
|
# 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.
|
# the marker was written by us and the directory has nothing else in it.
|
||||||
local marker="$SKILL_DEST_DIR/.skill-source"
|
local marker="$SKILL_DEST_DIR/.skill-source"
|
||||||
|
|||||||
Reference in New Issue
Block a user