diff --git a/README.md b/README.md index ce3ca2a..dd5ea07 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Producer-side tooling for [MemPalace](https://github.com/MemPalace/mempalace) - `bin/mempalace-docs` — mines project directories into MemPalace while excluding source code, keeping the palace signal-dense. - [`ARCHITECTURE.md`](ARCHITECTURE.md) — **canonical spec**: architecture diagram, component details, setup recipe, operational notes, upstream-retirement roadmap. - [`SKILL.md`](SKILL.md) — the companion agent skill, symlinked into `~/.agents/skills/opencode-mempalace-bridge/` on install. -- [`extensions/pi/`](extensions/pi/) — the [pi coding-agent](https://github.com/mariozechner/pi-coding-agent) extension that bridges pi to the MemPalace MCP server (wake-up auto-injection, `/mempalace-diary` command, schema passthrough). Symlinked into `~/.pi/agent/extensions/` on install when pi is detected. +- [`extensions/pi/`](extensions/pi/) — pi coding-agent bridge: the MemPalace MCP extension (symlinked), a mosh/tmux-friendly keybindings file (symlinked), and a `settings.example.json` template for starting pi without `--model`. `install.sh` also probes for `AWS_PROFILE`/`AWS_REGION` (needed by pi's Bedrock provider) and points at the recommended `~/.config/pi/.env` layout if missing. **If you're just trying to get this working on a new machine → jump to [Setup](#setup).** **If you want the full architecture story → read [`ARCHITECTURE.md`](ARCHITECTURE.md).** diff --git a/extensions/pi/README.md b/extensions/pi/README.md index 1471c59..2ef6dc1 100644 --- a/extensions/pi/README.md +++ b/extensions/pi/README.md @@ -73,17 +73,71 @@ If you ever need to re-loosen the schema for debugging, fall back to the `Type.Object({}, { additionalProperties: true })` default only for that specific tool, not globally. +## Keybindings (mosh/tmux newline fix) + +`keybindings.json` is symlinked so edits flow through git. Default: + +```json +{ + "tui.input.newLine": ["shift+enter", "ctrl+j", "alt+j"] +} +``` + +Rationale: when pi runs over `kitty → mosh → tmux`, shift+enter doesn't +forward cleanly (mosh uses vt220-ish emulation, no kitty-keyboard-protocol +or csi-u extended keys). `ctrl+j` and `alt+j` pass through as plain +control/meta bytes and give you reliable newline insertion. + +## Settings template (start pi without `--model`) + +`settings.example.json` is a template — **not symlinked**. pi rewrites +its `settings.json` at runtime (`lastChangelogVersion` bumps on upgrade), +which would dirty a symlinked repo file. Instead, bootstrap with: + +```bash +cp /path/to/mempalace-toolkit/extensions/pi/settings.example.json \ + ~/.pi/agent/settings.json +$EDITOR ~/.pi/agent/settings.json +``` + +The Bedrock inference-profile prefix on model IDs (`eu.`, `us.`) is +**region-specific** and must match `AWS_REGION` in `~/.config/pi/.env`. +For a bare Anthropic provider (non-Bedrock) drop the prefix entirely +and use `anthropic:claude-...`. Run `pi --list-models` to confirm what +your credentials can actually invoke. + +`install.sh` warns (non-fatal) if `settings.json` is missing. + +## Environment setup + +pi with `defaultProvider=amazon-bedrock` needs `AWS_PROFILE` and +`AWS_REGION` exported into the shell that launches it. Recommended +layout (matches the tor-ms22 dotfiles pattern): + +``` +~/.config/pi/.env ← AWS_PROFILE=..., AWS_REGION=... + (git-crypt encrypted in dotfiles repo) +~/.oh-my-zsh/custom/pi-env.zsh ← set -a; source ~/.config/pi/.env; set +a +``` + +Historical note: these vars used to live under a `# Environment variables +for pi` block inside `~/.config/opencode/.env`. Split out 2026-05-05 so +each tool owns its own env file. `install.sh` runs a `check_aws_env` +probe that warns if the vars are missing and points back here. + ## File layout ``` mempalace-toolkit/ └── extensions/ └── pi/ - ├── README.md ← this file - └── mempalace.ts ← symlinked into ~/.pi/agent/extensions/ + ├── README.md ← this file + ├── mempalace.ts ← symlinked into ~/.pi/agent/extensions/ + ├── keybindings.json ← symlinked into ~/.pi/agent/ + └── settings.example.json ← template; copy + edit into ~/.pi/agent/ ``` `install.sh` detects pi by probing for `~/.pi/agent/extensions/` and -only creates the symlink when that directory exists. On machines -without pi the file stays dormant in the repo. Re-runs are idempotent -(same pattern as `bin/` and `SKILL.md`). +only creates symlinks when that directory exists. On machines without +pi the files stay dormant in the repo. Re-runs are idempotent (same +pattern as `bin/` and `SKILL.md`). diff --git a/extensions/pi/keybindings.json b/extensions/pi/keybindings.json new file mode 100644 index 0000000..b28db1b --- /dev/null +++ b/extensions/pi/keybindings.json @@ -0,0 +1,3 @@ +{ + "tui.input.newLine": ["shift+enter", "ctrl+j", "alt+j"] +} diff --git a/extensions/pi/settings.example.json b/extensions/pi/settings.example.json new file mode 100644 index 0000000..e947401 --- /dev/null +++ b/extensions/pi/settings.example.json @@ -0,0 +1,12 @@ +{ + "_comment": "Template for ~/.pi/agent/settings.json. Copy to that path and adjust for your region/account — this file is NOT symlinked by install.sh because pi rewrites settings.json at runtime (lastChangelogVersion bumps), which would dirty the repo. This template exists so a fresh machine can start pi without --model by copying + editing.", + "_comment_models": "The 'eu.' prefix on Bedrock model IDs is an inference-profile prefix tied to the AWS region. Must match AWS_REGION in ~/.config/pi/.env. For us-east use 'us.anthropic.*'; for bare Anthropic provider (non-Bedrock) use the raw 'anthropic:claude-*' IDs. Run `pi --list-models` to see what your credentials can actually invoke.", + + "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" + ] +} diff --git a/install.sh b/install.sh index 3932c49..094fa4a 100755 --- a/install.sh +++ b/install.sh @@ -21,6 +21,14 @@ PI_EXT_SRC="${SCRIPT_DIR}/extensions/pi/mempalace.ts" PI_EXT_DEST_DIR="${HOME}/.pi/agent/extensions" PI_EXT_DEST="${PI_EXT_DEST_DIR}/mempalace.ts" +# pi keybindings (generic mosh/tmux newline fix — safe on any machine) +PI_KEYS_SRC="${SCRIPT_DIR}/extensions/pi/keybindings.json" +PI_KEYS_DEST="${HOME}/.pi/agent/keybindings.json" + +# pi settings template (NOT symlinked — pi rewrites this file at runtime) +PI_SETTINGS_EXAMPLE="${SCRIPT_DIR}/extensions/pi/settings.example.json" +PI_SETTINGS_DEST="${HOME}/.pi/agent/settings.json" + # ── args ───────────────────────────────────────────── ACTION="install" ASSUME_YES="no" @@ -45,6 +53,13 @@ What install does: reach Claude Code and Kiro) - If pi (~/.pi/agent/extensions/) exists, symlinks extensions/pi/mempalace.ts into ~/.pi/agent/extensions/mempalace.ts (pi bridge). Skipped otherwise. + - If pi exists, symlinks extensions/pi/keybindings.json into + ~/.pi/agent/keybindings.json (generic mosh/tmux newline fix). + - If pi exists, warns if ~/.pi/agent/settings.json is missing and points + at extensions/pi/settings.example.json as a template (NOT symlinked — + pi rewrites this file at runtime). + - Warns if AWS_PROFILE / AWS_REGION are unset (only relevant to users + whose pi settings.json selects amazon-bedrock as defaultProvider). - Drops a .skill-source marker in the skill dir so sibling tooling (deploy-skills.sh, agents-sync.zsh) knows the dir is externally owned @@ -52,6 +67,7 @@ What uninstall does: - Removes symlinks in ~/.local/bin/ that point into this repo - Removes the skill symlink if it points into this repo - Removes the pi extension symlink if it points into this repo + - Removes the pi keybindings symlink if it points into this repo - Removes the .skill-source marker and empty skill dir EOF exit 0 ;; @@ -257,6 +273,80 @@ install_pi_extension() { printf ' at startup only).\n' } +install_pi_keybindings() { + # Generic mosh/tmux newline fix. Non-destructive: if a real + # keybindings.json exists we back it up rather than clobber. + [[ -d "$PI_EXT_DEST_DIR" ]] || return 0 # no pi → no keybindings + + note "Linking pi keybindings → $PI_KEYS_DEST" + if [[ -e "$PI_KEYS_DEST" || -L "$PI_KEYS_DEST" ]]; then + if link_if_into_repo "$PI_KEYS_DEST"; then + ok "pi keybindings already linked" + return 0 + fi + local backup="${PI_KEYS_DEST}.bak.$(date +%Y%m%d-%H%M%S)" + mv "$PI_KEYS_DEST" "$backup" + warn "Existing $PI_KEYS_DEST backed up to $backup" + fi + ln -s "$PI_KEYS_SRC" "$PI_KEYS_DEST" + ok "Linked keybindings.json → $PI_KEYS_SRC" +} + +# ── Verify ~/.pi/agent/settings.json exists ────────────────────────── +# If pi is installed but settings.json is missing, `pi` refuses to start +# without `--provider ... --model ...` on every invocation. The toolkit +# ships extensions/pi/settings.example.json as a template with a working +# Bedrock (eu-west-1) stanza — copy + edit for your region/account. +# +# NOT symlinked: pi rewrites settings.json at runtime (lastChangelogVersion +# bumps on upgrade), which would dirty the repo and cause merge noise. +# Template-only install is the right trade-off. +check_pi_settings() { + [[ -d "$PI_EXT_DEST_DIR" ]] || return 0 # no pi → nothing to check + + if [[ -f "$PI_SETTINGS_DEST" ]]; then + ok "pi settings.json present at $PI_SETTINGS_DEST" + return 0 + fi + + warn "pi settings.json NOT found at $PI_SETTINGS_DEST" + printf ' Without it, pi must be invoked with --provider/--model on every run.\n' + printf ' Bootstrap from the shipped template:\n' + printf ' cp %q %q\n' "$PI_SETTINGS_EXAMPLE" "$PI_SETTINGS_DEST" + printf ' $EDITOR %q # adjust region prefix + model IDs\n' "$PI_SETTINGS_DEST" + printf ' See extensions/pi/README.md for the eu./us./anthropic: prefix rules.\n' + return 0 +} + +# ── Verify AWS env vars are present for Bedrock-backed pi ──────────── +# Only meaningful if pi's settings.json selects amazon-bedrock. We do a +# best-effort grep rather than parsing JSON — false positives are cheap +# (one extra probe) and the check is gated on pi being installed at all. +check_aws_env() { + [[ -d "$PI_EXT_DEST_DIR" ]] || return 0 # no pi → nothing to check + + # Only warn if settings.json selects amazon-bedrock. If pi uses a + # non-Bedrock provider (bare anthropic, openai, ...) AWS creds are + # irrelevant and this probe would be noise. + if [[ -f "$PI_SETTINGS_DEST" ]] \ + && ! grep -q '"amazon-bedrock"' "$PI_SETTINGS_DEST" 2>/dev/null; then + return 0 + fi + + if [[ -n "${AWS_PROFILE:-}" && -n "${AWS_REGION:-}" ]]; then + ok "AWS env present (AWS_PROFILE=$AWS_PROFILE, AWS_REGION=$AWS_REGION)" + return 0 + fi + + warn "AWS_PROFILE and/or AWS_REGION not set in this shell" + printf ' pi with defaultProvider=amazon-bedrock needs both to invoke Bedrock.\n' + printf ' Recommended layout (matches the tor-ms22 dotfiles pattern):\n' + printf ' ~/.config/pi/.env # AWS_PROFILE=..., AWS_REGION=...\n' + printf ' ~/.oh-my-zsh/custom/pi-env.zsh # set -a; source ~/.config/pi/.env; set +a\n' + printf ' See extensions/pi/README.md#environment-setup for the template.\n' + return 0 +} + do_install() { echo echo "mempalace-toolkit installer" @@ -267,6 +357,7 @@ do_install() { echo " Symlink SKILL.md into $SKILL_DEST" if [[ -d "$PI_EXT_DEST_DIR" ]]; then echo " Symlink extensions/pi/mempalace.ts into $PI_EXT_DEST" + echo " Symlink extensions/pi/keybindings.json into $PI_KEYS_DEST" fi echo confirm || { echo "Aborted."; exit 0; } @@ -277,12 +368,18 @@ do_install() { echo install_pi_extension echo + install_pi_keybindings + echo check_path echo check_wake_up_protocol echo check_opencode_mcp echo + check_pi_settings + echo + check_aws_env + echo ok "Done." echo echo "Next: ./bin/mempalace-session --dry-run" @@ -330,6 +427,15 @@ do_uninstall() { ok "No pi extension symlink to remove" fi + echo + note "Removing pi keybindings symlink" + if link_if_into_repo "$PI_KEYS_DEST"; then + rm "$PI_KEYS_DEST" + ok "Removed pi keybindings symlink" + else + ok "No pi keybindings symlink to remove" + fi + # Remove the marker and the now-empty skill directory, but only if # the marker was written by us and the directory has nothing else in it. local marker="$SKILL_DEST_DIR/.skill-source"