Initial commit: pi harness bring-up split out of mempalace-toolkit

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.
This commit is contained in:
2026-05-05 17:22:06 +02:00
commit ff774cf88f
7 changed files with 762 additions and 0 deletions
+228
View File
@@ -0,0 +1,228 @@
# pi-toolkit
Harness-side bring-up for the [pi coding-agent](https://github.com/mariozechner/pi-coding-agent).
**What's here:**
- `pi-env.zsh` — loads `~/.config/pi/.env` into every shell so pi's Bedrock provider has `AWS_PROFILE` / `AWS_REGION` available.
- `keybindings.json` — mosh/tmux-friendly newline bindings (`shift+enter`, `ctrl+j`, `alt+j`).
- `settings.example.json` — template for `~/.pi/agent/settings.json` so `pi` starts without having to pass `--provider`/`--model` on every invocation.
- `install.sh` — idempotent installer wiring all three into place.
**No dependency on MemPalace.** For the palace memory layer see [`mempalace-toolkit`](https://gitea.jordbo.se/joakimp/mempalace-toolkit) — it installs a pi↔mempalace MCP bridge on top of this toolkit. The two repos compose but don't require each other, same pattern as [`opencode-toolkit`](https://gitea.jordbo.se/joakimp/opencode-toolkit) ↔ mempalace.
---
## Why this exists
Pi, out of the box on a fresh machine, has three friction points that this toolkit fixes:
1. **No model selection without `--model`.** Every invocation needs `pi --provider ... --model ...` until `~/.pi/agent/settings.json` exists with defaults. The shipped `settings.example.json` is a working eu-west-1 Bedrock template — copy, edit for your region, done.
2. **`Shift+Enter` (newline in the TUI) doesn't work over mosh/tmux.** mosh's vt220-ish emulation strips modifier keys upstream of tmux, so pi never sees the Shift bit. The shipped `keybindings.json` adds `ctrl+j` and `alt+j` fallbacks that pass through as plain control/meta bytes.
3. **Bedrock provider needs `AWS_PROFILE` and `AWS_REGION` in the shell environment at spawn time.** The shipped `pi-env.zsh` sources `~/.config/pi/.env` into every shell (`set -a; source; set +a`), so you can edit credentials in one plaintext-on-disk, encrypted-in-git-repo file.
None of this talks to MemPalace; it's all pi's own configuration surface.
---
## Install
```bash
git clone ssh://git@gitea.jordbo.se:2222/joakimp/pi-toolkit.git ~/pi-toolkit
cd ~/pi-toolkit
./install.sh
```
Requires pi to be installed first (`~/.pi/agent/` must exist). Install via:
```bash
brew install pi-coding-agent # macOS
# or see https://github.com/mariozechner/pi-coding-agent for Linux
pi --help # first run creates ~/.pi/agent/
```
What `install.sh` does:
| Step | Action |
|---|---|
| Symlink `keybindings.json` | `~/.pi/agent/keybindings.json` → repo. Safe to symlink: pi doesn't rewrite it. |
| Install `pi-env.zsh` | `cp` into `~/.oh-my-zsh/custom/` if oh-my-zsh detected; otherwise print shell-specific `source` snippet for `~/.zshrc` or `~/.bashrc`. Does not auto-edit rc files. |
| `settings.example.json` | **Not installed.** Installer warns if `~/.pi/agent/settings.json` is missing and prints the `cp` command. NOT symlinked because pi rewrites `settings.json` at runtime (`lastChangelogVersion` bumps) and a symlink would dirty the repo. |
| AWS env probe | If `settings.json` selects `amazon-bedrock`, warn if `AWS_PROFILE` / `AWS_REGION` not set. Silent otherwise. |
Everything is non-destructive: existing real files get backed up with a timestamp before symlinking; shell loader copy refuses to clobber local edits (prints `diff` hint and moves on). Re-runs are idempotent.
## Uninstall
```bash
./install.sh --uninstall
```
Removes the keybindings symlink and the shell-loader copy (only if content still matches the repo). Your `settings.json` is never touched.
---
## Deploying pi on a new machine
Full recipe from a clean macOS or Linux box to a working pi install. Follow in order.
### 0. Prerequisites
- Shell: zsh + oh-my-zsh recommended (the `pi-env.zsh` loader installs into `~/.oh-my-zsh/custom/`). Bash or plain zsh works too — installer prints a manual source snippet.
- `git`, pi (installed upstream), optional: `tmux` ≥ 3.2 for CSI-u extended keys on non-mosh paths.
- AWS credentials reachable via `AWS_PROFILE` (either `aws configure sso` cache or static keys in `~/.aws/credentials`) — only if using `amazon-bedrock` as pi's provider.
### 1. Dotfiles (if you keep one)
Your dotfiles repo should ship `~/.config/pi/.env` (git-crypt encrypted, containing `AWS_PROFILE` and `AWS_REGION`). Provision it first so the loader has something to source:
```bash
git clone <your-dotfiles> ~/src/dotfiles
cd ~/src/dotfiles
git-crypt unlock <key>
# Run your dotfiles provisioner (example: myconfigs)
./provision.sh --profile <profile>
```
If you don't use a dotfiles repo, create the file manually after step 3 (installer will point you at the right path).
### 2. Install pi
```bash
brew install pi-coding-agent # macOS
# or see https://github.com/mariozechner/pi-coding-agent for Linux
pi --help # creates ~/.pi/agent/
```
### 3. Install this toolkit
```bash
git clone ssh://git@gitea.jordbo.se:2222/joakimp/pi-toolkit.git ~/pi-toolkit
cd ~/pi-toolkit && ./install.sh
```
This symlinks `keybindings.json`, copies `pi-env.zsh`, and prints the `settings.json` bootstrap command.
### 4. Bootstrap pi settings
```bash
cp ~/pi-toolkit/settings.example.json ~/.pi/agent/settings.json
$EDITOR ~/.pi/agent/settings.json
```
Adjust the inference-profile prefix to match your AWS region:
| Region | Prefix | Example model ID |
|---|---|---|
| eu-west-1 | `eu.` | `eu.anthropic.claude-sonnet-4-6` |
| us-east-1 | `us.` | `us.anthropic.claude-sonnet-4-6` |
| non-Bedrock | (none) | `anthropic:claude-sonnet-4-6` |
Run `pi --list-models` to confirm what your credentials can actually invoke.
### 5. Verify AWS env vars in your shell
If step 1 provisioned `~/.config/pi/.env` and step 3 installed `pi-env.zsh`:
```bash
exec zsh
echo "$AWS_PROFILE $AWS_REGION" # should print your values
```
If empty, check that `~/.config/pi/.env` decrypted (plain text, not binary) — `git-crypt unlock` in step 1 is the usual culprit.
### 6. First run
```bash
pi # should start with the default model, no --model needed
```
### 7. (Optional) Add MemPalace memory
If you want pi to have persistent memory across sessions, install [`mempalace-toolkit`](https://gitea.jordbo.se/joakimp/mempalace-toolkit):
```bash
uv tool install mempalace
git clone ssh://git@gitea.jordbo.se:2222/joakimp/mempalace-toolkit.git ~/mempalace-toolkit
cd ~/mempalace-toolkit && ./install.sh
```
It detects pi and symlinks a `mempalace.ts` extension into `~/.pi/agent/extensions/` that wires pi's MCP client to the palace.
### Verification checklist
```bash
# keybindings symlinked into this repo
ls -la ~/.pi/agent/keybindings.json
# shell loader installed
ls -la ~/.oh-my-zsh/custom/pi-env.zsh
# env vars loaded in a fresh shell
zsh -ic 'echo $AWS_PROFILE $AWS_REGION'
# pi starts with its defaults
pi --version
# Re-run is idempotent
./install.sh --yes # all rows should say "already linked/installed"
```
---
## Settings template reference
`settings.example.json`:
```json
{
"defaultProvider": "amazon-bedrock",
"defaultModel": "eu.anthropic.claude-sonnet-4-6",
"enabledModels": [
"eu.anthropic.claude-sonnet-4-6",
"eu.anthropic.claude-opus-4-7",
"eu.anthropic.claude-haiku-4-5-20251001-v1:0"
]
}
```
- `defaultProvider` — most common values: `amazon-bedrock`, `anthropic`, `openai`.
- `defaultModel` — Bedrock IDs have region-specific prefixes (`eu.`, `us.`). Bare Anthropic uses `anthropic:claude-...`. Run `pi --list-models` to see what you can actually call.
- `enabledModels` — optional; restricts the model picker inside pi to this subset.
pi rewrites `settings.json` at runtime (`lastChangelogVersion` bumps on upgrade), so don't symlink this file.
## Keybindings reference
`keybindings.json`:
```json
{
"tui.input.newLine": ["shift+enter", "ctrl+j", "alt+j"]
}
```
Over direct `kitty` / `iTerm2` / `WezTerm` with tmux configured for CSI-u extended keys, `Shift+Enter` works natively. The `ctrl+j` / `alt+j` fallbacks kick in when modifier forwarding is stripped (most commonly: mosh). Pi reads this file once at startup — restart pi after editing.
## Environment file reference
`~/.config/pi/.env` format (plaintext on disk, chmod 600, encrypt in your dotfiles repo):
```bash
AWS_PROFILE=YourBedrockProfile
AWS_REGION=eu-west-1
```
Loaded by `pi-env.zsh` via `set -a; source; set +a` — plain `KEY=VALUE`, no `export` needed. Add any other pi-scoped env vars here as the surface grows.
---
## Related repos
- [`mempalace-toolkit`](https://gitea.jordbo.se/joakimp/mempalace-toolkit) — MemPalace memory layer. Installs a pi↔mempalace MCP bridge on top of this toolkit. Optional.
- [`opencode-toolkit`](https://gitea.jordbo.se/joakimp/opencode-toolkit) — sibling repo for the opencode coding-agent. Same shape (shell loader + install.sh). Independent of this repo.
- [`opencode-devbox`](https://gitea.jordbo.se/joakimp/opencode-devbox) — Docker containers with coding agents preinstalled. Can compose pi-toolkit and mempalace-toolkit as independent layers.
- [`myconfigs`](https://gitea.jordbo.se/joakimp/myconfigs) — dotfiles repo where `~/.config/pi/.env` is tracked (git-crypt encrypted).
## License
MIT — see [`LICENSE`](LICENSE).