4b4b76e80e
Adds pi-atelier.json (defaults for the pi-atelier extension) and an install/uninstall step for it, so the config survives a devbox volume wipe and applies to pi on the host too — ~/.pi/agent is a named volume in a container, which the extension's own config path alone does not outlive. cp-if-absent rather than a symlink, unlike keybindings.json/AGENTS.md: the extension rewrites this exact path when the user saves from its menu (src/config.ts writeJsonAtomic -> "<path>.<pid>.tmp" then rename). rename(2) REPLACES a symlink with a regular file instead of following it, so a link would detach on the first menu save and the repo copy would quietly stop applying. Verified empirically before choosing the idiom, not assumed. Drift is respected in both directions, matching the pi-env.zsh shape: install never clobbers an existing file (warns + prints a diff hint), uninstall removes it only while its content still matches the repo. All five paths exercised against an isolated HOME: fresh copy, idempotent re-run, drift-preserved install, drift-preserved uninstall, matched-content uninstall. Values chosen for this setup and validated against the extension's own validateConfig (no warnings, no coercion): - segments drop "brand" (decoration, and first in the drop order anyway) - density compact — the rail relayouts at 132/96/72/56 cols and these sessions run over plain SSH at unknown width - contextWarning/Danger 60/85, earlier than the 70/90 default because defaultModel is opus-5 at xhigh thinking with obsmem compaction behind it - showSidebarToolNames true — MCP/tool-heavy sessions, names beat "something is running" - completionNotifications false — deliverSystemNotification only spawns for darwin/win32 and returns undefined on linux, and a container has no desktop session to reach anyway Docs: file inventory + install/uninstall tables in README.md and AGENTS.md, including why the symlink idiom does not apply here.
232 lines
9.6 KiB
Markdown
232 lines
9.6 KiB
Markdown
# pi-toolkit
|
|
|
|
Harness-side bring-up for the [pi coding-agent](https://github.com/earendil-works/pi).
|
|
|
|
**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`).
|
|
- `pi-atelier.json` — Status Rail defaults for the [pi-atelier](https://github.com/michaelmjhhhh/pi-atelier) extension (rail segments, context warning thresholds, sidebar tool names). Inert if that extension isn't installed.
|
|
- `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 these 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/earendil-works/pi 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. |
|
|
| Copy `pi-atelier.json` | `~/.pi/agent/pi-atelier.json`, **only if absent**. NOT symlinked: pi-atelier rewrites this path on menu saves via write-temp-then-`rename`, and `rename(2)` replaces a symlink rather than following it — so a link would silently detach. An existing file is left alone with a `diff` hint. |
|
|
| `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 and `AGENTS.md` symlinks, plus the shell-loader and `pi-atelier.json` copies — the copies only if their content still matches the repo, so local edits (including pi-atelier menu saves) survive. 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/earendil-works/pi 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-5` |
|
|
| us-east-1 | `us.` | `us.anthropic.claude-sonnet-5` |
|
|
| non-Bedrock | (none) | `anthropic:claude-sonnet-5` |
|
|
|
|
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-opus-5",
|
|
"enabledModels": [
|
|
"eu.anthropic.claude-opus-5",
|
|
"eu.anthropic.claude-sonnet-5",
|
|
"eu.anthropic.claude-opus-4-8",
|
|
"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).
|