feat(pi-atelier): ship Status Rail defaults, cp'd not symlinked
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.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+53
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user