Pi-generic config artifacts (no mempalace dependency): - pi-env.zsh: shell loader sourcing ~/.config/pi/.env for AWS_PROFILE / AWS_REGION. POSIX-compatible (works in bash and zsh). - keybindings.json: mosh/tmux newline bindings (shift+enter, ctrl+j, alt+j). - settings.example.json: ~/.pi/agent/settings.json template so pi starts without --provider/--model. Region-specific (Bedrock inference-profile prefix). install.sh mirrors mempalace-toolkit + opencode-toolkit patterns: - require_pi_installed: hard exit 4 if ~/.pi/agent/ missing (cannot do anything useful; user must install pi first). - symlink keybindings.json (safe: pi doesn't rewrite it). - cp pi-env.zsh into ~/.oh-my-zsh/custom/ (portability over symlink, that dir is part of dotfiles backups). Print source snippet for bash / plain-zsh users. - settings.example.json NOT installed \u2014 pi rewrites settings.json at runtime. check_pi_settings probe prints the cp command instead. - check_aws_env: gated on settings.json selecting amazon-bedrock; silent for non-Bedrock providers or missing settings. - All probes warn + return 0, never halt. - Non-destructive: backup on symlink collision, cmp-based drift detection on the cp path, uninstall only removes copies whose content still matches repo. Split rationale: opencode-devbox's mempalace opt-out (~300 MB saved) wants pi available without mempalace. That dependency asymmetry is cleanest when pi's own config lives in its own repo, same shape as opencode-toolkit split out earlier today. The pi\u2194mempalace MCP bridge (mempalace.ts) stays in mempalace-toolkit where it belongs \u2014 it imports pi's ExtensionAPI but only exists to bridge to the palace. Verified on tor-ms22: fresh install \u2192 drift detect \u2192 adopt canonical \u2192 uninstall \u2192 reinstall \u2192 zsh -ic loads AWS vars. Bash fallback path also tested via HOME=/tmp/fake SHELL=/bin/bash.
8.8 KiB
AGENTS.md
What this is
Harness-side bring-up for the pi coding-agent. Installs three pi-generic config artifacts into the right places and runs a couple of non-halting probes. Does not depend on MemPalace.
Sibling to opencode-toolkit —
same shape: one install.sh at the root, cp-or-symlink the config files,
probe the environment, compose independently of the palace memory layer.
Read README.md first for the user-facing walk-through.
This file is for agents modifying the repo.
Structure
install.sh # Idempotent installer (symlink + cp + probes)
pi-env.zsh # Shell loader sourcing ~/.config/pi/.env (POSIX-compatible)
keybindings.json # ~/.pi/agent/keybindings.json — mosh/tmux newline fix
settings.example.json # Template for ~/.pi/agent/settings.json (copy + edit)
README.md # User-facing quickstart + new-machine deploy recipe.
AGENTS.md # This file.
LICENSE # MIT.
Conventions
- One install step per artifact, with a matching uninstall step.
- Symlink what's safe to symlink, cp what's part of a dotfiles backup,
template what the harness rewrites.
keybindings.json→ symlink. pi doesn't rewrite it; the symlink lets edits flow through git without a re-install step.pi-env.zsh→cpinto~/.oh-my-zsh/custom/. That dir is typically part of a dotfiles backup (e.g.myconfigs'srsync_copy.sh); a symlink into this repo's absolute path breaks when the backup is restored on another host.settings.example.json→ not installed. pi rewrites~/.pi/agent/settings.jsonat runtime (lastChangelogVersionbumps on upgrade), so any symlink back to the repo would dirty the working tree. Installer prints thecpcommand and walks away.
- Probes warn, never halt.
warn+return 0. The installer's only hard-fail path is "pi isn't installed at all" — that's an earlyexit 4fromrequire_pi_installedbecause there's nothing useful to do without~/.pi/agent/. - Non-destructive. Existing real files at symlink destinations get
backed up with a timestamp (
.bak.YYYYMMDD-HHMMSS) before linking. The shell loader's cp path refuses to clobber local edits: detects drift viacmp -s, prints adiffhint, leaves the file alone. - Do not auto-edit rc files. If oh-my-zsh isn't present, print the
sourcesnippet the user manually adds to~/.zshrcor~/.bashrc. Invasive shell-rc edits belong in a dotfiles installer, not here. - No hard dependency on mempalace. If the surface ever grows
mempalace-aware (unlikely — those pieces live in
mempalace-toolkiton purpose), it must degrade gracefully when mempalace is absent. - POSIX-compatible shell glue.
set -a/source/set +awork in bash and zsh both. Don't add zsh-only constructs to files that may end up sourced from~/.bashrc.
What install.sh does
Hard-required:
require_pi_installed— aborts with exit 4 if~/.pi/agent/is missing. Creates~/.pi/agent/extensions/proactively so a latermempalace-toolkitinstall has somewhere to symlink into.
Always (once pi is present):
- Symlinks
keybindings.jsoninto~/.pi/agent/. Backs up any pre-existing real file.
oh-my-zsh path (gated on ~/.oh-my-zsh/custom/ existing):
- Copies
pi-env.zshinto that directory. Drift-safe — prints adiffhint if installed content differs from repo, doesn't clobber.
No oh-my-zsh path:
- Prints a shell-specific source snippet for
~/.zshrcor~/.bashrc(selected from$SHELL). User pastes manually.
Probes (non-halting):
~/.pi/agent/settings.jsonexists. Without it pi refuses to start without--provider/--model. Prints thecp settings.example.jsoncommand.AWS_PROFILE+AWS_REGIONare set, only ifsettings.jsonselectsamazon-bedrock. Silent for non-Bedrock providers. Silent if settings.json is missing (check_pi_settings already handled that case).
Adding a new artifact
Follow the same shape keybindings.json / pi-env.zsh / settings.example.json use:
- One file at repo root. Flat layout; no
extensions/subdir yet. Revisit if five+ artifacts ever accumulate. - Choose symlink / cp / template per the conventions above. Document
the choice in a comment next to the variable declarations at the top
of
install.sh. - One install step + one uninstall step in
install.sh, guarded bylink_if_into_repo(for symlinks) orcmp -s(for copies). Never remove user edits silently. - One probe per external dependency the artifact implies.
warn+return 0. - Update this file's Structure block and
README.md.
Adding mempalace-aware functionality
Don't. Those pieces belong in mempalace-toolkit/extensions/pi/:
- The mempalace MCP bridge TypeScript extension (
mempalace.ts) — imports pi'sExtensionAPI, registers MCP tools, injects wake-up context. - The
install_pi_extensionfunction that symlinks it in. - Any probes that check for mempalace being reachable through pi.
That boundary is load-bearing for opencode-devbox's slim container
path: a container built with INSTALL_MEMPALACE=false should install
pi-toolkit cleanly and get a functional pi without dragging in
chromadb + embedding models (~300 MB).
Testing
No framework. Manual:
./install.sh --help # flags
./install.sh --yes # fresh install
./install.sh --yes # re-run (idempotent)
./install.sh --uninstall --yes # remove
./install.sh --yes # reinstall
oh-my-zsh fallback simulation:
SHELL=/bin/bash HOME=/tmp/fake ./install.sh --yes # should print ~/.bashrc snippet
Environment verification (after install + exec zsh or new shell):
zsh -ic 'echo $AWS_PROFILE $AWS_REGION' # should print values from ~/.config/pi/.env
Drift simulation:
echo "# local edit" >> ~/.oh-my-zsh/custom/pi-env.zsh
./install.sh --yes # should warn "differs from repo" and leave alone
Gotchas
- pi must be installed upstream first.
~/.pi/agent/is created by pi on first run, not by this installer. Missing → exit 4 with pointer to https://github.com/mariozechner/pi-coding-agent. settings.example.jsonis region-specific. The shipped default useseu.Bedrock inference-profile prefixes. Users on us-east need to swap tous.before first run, or pi will reject the model ID.- Bedrock is not the only provider. If the user is on bare
Anthropic or OpenAI,
AWS_PROFILE/AWS_REGIONare irrelevant. The probe gates ongrep -q '"amazon-bedrock"' settings.jsonto stay quiet in those cases. - Mosh strips modifiers upstream of tmux. The keybindings file's
ctrl+j/alt+jfallbacks are specifically because mosh's vt220-ish emulation does not forwardShift+Enteras CSI-u — tmux'sextended-keys csi-usetting doesn't help over mosh (only helps on direct ssh / local / WireGuard). Documented in README. - The shell loader runs on every shell start. Keep it fast. If it
grows beyond a few lines, gate on
[[ $- == *i* ]]so non-interactive shells skip the work. ~/.config/pi/.envshould be chmod 600. It's plaintext on disk; git-crypt encryption only applies in the dotfiles repo. The installer does not enforce this because it doesn't ship the file.
Related repos
mempalace-toolkit— adds a pi↔mempalace MCP bridge on top of this toolkit. Installs themempalace.tsextension into~/.pi/agent/extensions/. Optional.opencode-toolkit— sibling pattern for the opencode coding-agent. Same install.sh shape.opencode-devbox— Docker containers; composes any subset of these toolkits via independent install.sh invocations.myconfigs— dotfiles repo where~/.config/pi/.envis tracked (git-crypt encrypted).
History
Split out of mempalace-toolkit/extensions/pi/ on 2026-05-05. Previously
the pi-generic config artifacts (env loader, keybindings, settings
template) lived alongside the mempalace.ts MCP bridge inside
mempalace-toolkit because that's where the pattern first crystallized.
The split was motivated by opencode-devbox's mempalace opt-out and
future pi-option: a container built with mempalace off should still be
able to install a functional pi, and that dependency asymmetry is
cleanest when pi's own config lives in its own repo. Mirrors the
2026-05-05 split of opencode-toolkit out of the same parent.