diff --git a/AGENTS.md b/AGENTS.md index c4654c0..46bc77f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,6 +19,7 @@ This file is for agents modifying the repo. 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 +pi-atelier.json # ~/.pi/agent/pi-atelier.json (cp) — Status Rail defaults pi-global-AGENTS.md # ~/.pi/agent/AGENTS.md (symlink) — global agent instructions settings.example.json # Template for ~/.pi/agent/settings.json (copy + edit) README.md # User-facing quickstart + new-machine deploy recipe. @@ -37,6 +38,14 @@ LICENSE # MIT. typically part of a dotfiles backup (e.g. `myconfigs`'s `rsync_copy.sh`); a symlink into this repo's absolute path breaks when the backup is restored on another host. + - `pi-atelier.json` → `cp` **if absent**. The pi-atelier extension + rewrites this exact path when the user saves from its menu, using + write-temp-then-`rename`. `rename(2)` replaces a symlink with a + regular file instead of following it, so a symlink would detach + silently on the first menu save and the repo copy would quietly stop + applying. Verified, not assumed. Drift is respected in both + directions: install won't clobber an existing file, uninstall only + removes one whose content still matches the repo. - `settings.example.json` → **not installed**. pi rewrites `~/.pi/agent/settings.json` at runtime (`lastChangelogVersion` bumps on upgrade), so any symlink back to the repo would dirty the diff --git a/README.md b/README.md index 8e2ddf3..e08bbf0 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,9 @@ Harness-side bring-up for the [pi coding-agent](https://github.com/earendil-work **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 all three into place. +- `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. @@ -46,6 +47,7 @@ What `install.sh` does: |---|---| | 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. | @@ -57,7 +59,7 @@ Everything is non-destructive: existing real files get backed up with a timestam ./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. +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. --- diff --git a/install.sh b/install.sh index eda6643..4c15b28 100755 --- a/install.sh +++ b/install.sh @@ -11,6 +11,8 @@ # (e.g. "read the pi-extensions skill at session start"). # - settings.example.json : template for ~/.pi/agent/settings.json so pi # starts without --provider/--model. Copy + edit. +# - pi-atelier.json : default Status Rail config for the pi-atelier +# extension (cp'd, not symlinked — see below). # # No dependency on MemPalace. For the palace bridge see # https://gitea.jordbo.se/joakimp/mempalace-toolkit (optional). @@ -40,6 +42,16 @@ PI_AGENTS_DEST="${HOME}/.pi/agent/AGENTS.md" PI_SETTINGS_EXAMPLE="${SCRIPT_DIR}/settings.example.json" PI_SETTINGS_DEST="${HOME}/.pi/agent/settings.json" +# pi-atelier Status Rail config — cp'd, NOT symlinked. pi-atelier rewrites this +# file at runtime ("Save as user default" in its menu, and sidebar/notification +# toggles save immediately) via a write-temp-then-rename, and rename(2) REPLACES +# a symlink with a regular file rather than following it — so a symlink would +# silently detach on the user's first menu save and the repo copy would stop +# taking effect. cp-if-absent + cmp drift check instead, same shape as +# pi-env.zsh. +PI_ATELIER_SRC="${SCRIPT_DIR}/pi-atelier.json" +PI_ATELIER_DEST="${HOME}/.pi/agent/pi-atelier.json" + # shell env loader — cp'd into oh-my-zsh custom dir (portability over symlink) PI_ENV_SRC="${SCRIPT_DIR}/pi-env.zsh" PI_ENV_OMZ_DEST="${HOME}/.oh-my-zsh/custom/pi-env.zsh" @@ -66,6 +78,9 @@ What install does: - Symlinks keybindings.json into ~/.pi/agent/keybindings.json. - Symlinks pi-global-AGENTS.md into ~/.pi/agent/AGENTS.md (global instructions loaded by pi at every start). + - Copies pi-atelier.json into ~/.pi/agent/ if absent (Status Rail + defaults). cp not symlink: pi-atelier rewrites it on menu saves. + Existing file is left alone, with a diff hint. - If oh-my-zsh is present (~/.oh-my-zsh/custom/), copies pi-env.zsh there so every new zsh shell sources ~/.config/pi/.env. Uses cp (not symlink) for dotfile-backup portability. Prints source snippet otherwise. @@ -76,6 +91,8 @@ What uninstall does: - Removes keybindings.json symlink if it points into this repo. - Removes the AGENTS.md symlink if it points into this repo. - Removes pi-env.zsh copy ONLY if its content still matches the repo. + - Removes pi-atelier.json ONLY if its content still matches the repo + (a menu save makes it yours — then it's left alone). - Never touches settings.json (it's your file, not managed here). No dependency on MemPalace. For memory integration see: @@ -198,6 +215,28 @@ install_env_loader() { printf ' (the loader itself is POSIX-compatible — works in bash and zsh.)\n' } +install_atelier_config() { + # Status Rail defaults for the pi-atelier extension. cp-if-absent, never + # clobber: the extension writes this same path when the user saves from its + # menu, so an existing file is assumed to be the user's own preference. + # See the comment at PI_ATELIER_SRC for why this is a cp and not a symlink. + note "Installing pi-atelier.json → $PI_ATELIER_DEST" + if [[ -e "$PI_ATELIER_DEST" || -L "$PI_ATELIER_DEST" ]]; then + if cmp -s "$PI_ATELIER_SRC" "$PI_ATELIER_DEST"; then + ok "pi-atelier config already installed (content matches repo)" + return 0 + fi + warn "$PI_ATELIER_DEST exists and differs from repo copy" + printf ' Leaving your settings alone (pi-atelier saves here too). Compare with:\n' + printf ' diff %q %q\n' "$PI_ATELIER_DEST" "$PI_ATELIER_SRC" + printf ' To adopt the repo defaults: rm that file and re-run install.sh\n' + return 0 + fi + cp "$PI_ATELIER_SRC" "$PI_ATELIER_DEST" + ok "Copied pi-atelier.json → $PI_ATELIER_DEST" + printf ' Inert unless the pi-atelier extension is installed; read at session start.\n' +} + # ── Probes ─────────────────────────────────────────── # Never halt. warn + return 0 — mirrors opencode-toolkit and mempalace-toolkit. check_pi_settings() { @@ -248,6 +287,7 @@ do_install() { echo "==> Installation plan:" echo " Symlink keybindings.json → $PI_KEYS_DEST" echo " Symlink pi-global-AGENTS.md → $PI_AGENTS_DEST" + echo " Copy pi-atelier.json → $PI_ATELIER_DEST (if absent)" if [[ -d "$HOME/.oh-my-zsh/custom" ]]; then echo " Copy pi-env.zsh → $PI_ENV_OMZ_DEST" else @@ -262,6 +302,8 @@ do_install() { echo install_env_loader echo + install_atelier_config + echo check_pi_settings echo check_aws_env @@ -295,6 +337,17 @@ do_uninstall() { ok "No pi global AGENTS.md symlink to remove" fi + echo + note "Removing pi-atelier.json (only if unmodified)" + if [[ -f "$PI_ATELIER_DEST" ]] && cmp -s "$PI_ATELIER_SRC" "$PI_ATELIER_DEST"; then + rm "$PI_ATELIER_DEST" + ok "Removed $PI_ATELIER_DEST" + elif [[ -f "$PI_ATELIER_DEST" ]]; then + warn "$PI_ATELIER_DEST differs from repo copy — left alone" + else + ok "No pi-atelier.json 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 diff --git a/pi-atelier.json b/pi-atelier.json new file mode 100644 index 0000000..582f8d3 --- /dev/null +++ b/pi-atelier.json @@ -0,0 +1,14 @@ +{ + "preset": "editorial", + "shortcut": "alt+a", + "segments": ["activity", "metrics", "context", "model", "git", "statuses", "menu"], + "density": "compact", + "ornament": "none", + "contextWarning": 60, + "contextDanger": 85, + "currencyDecimals": 3, + "showExtensionStatuses": true, + "showSessionActions": true, + "showSidebarToolNames": true, + "completionNotifications": false +}