diff --git a/CHANGELOG.md b/CHANGELOG.md index b24f7a4..0beaa19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,15 +11,21 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`). --- -## Unreleased +## v1.8.0 — 2026-08-15 -Minor-shaped. Headline: **pi sessions now feed MemPalace by themselves.** The +Minor release. Headline: **pi sessions now feed MemPalace by themselves.** The image already shipped `mempalace-toolkit`, but its pi feeder (`mempalace-pi-session`) was never symlinked onto `PATH`, so nothing ever mined pi's transcripts — the palace only ever contained what an agent remembered to file by hand. A container that gets recreated regularly has no other memory, so a missed wind-down was a permanently lost session. +Also here: **pi 0.84.1 → 0.84.2 and pi-atelier v0.8.0 → v0.8.1**, bumped +together. The pi bump closes the Amazon Bedrock tool-argument poison pill that +v1.6.4 recorded as unfixed upstream; the atelier bump is the matching companion, +since both sides changed fullscreen input handling in the same fortnight. Audits +for both are below. + *Why event-driven and not a timer:* there is nothing schedulable inside the container — PID 1 is `bash -l`, with no systemd and no cron — and anything installed would not survive recreate anyway. The triggers therefore live where @@ -96,6 +102,124 @@ the events already are: pi's own lifecycle, plus container start. (the branch only runs at container start, so a `docker run` one-shot cannot reach it). +### Bumped: pi 0.84.1 → 0.84.2 + +- **`ARG PI_VERSION=0.84.2`** (`Dockerfile.variant`), with the audit the pin + policy in that file requires. + + **Headline for this image: the Bedrock tool-argument poison pill is FIXED + upstream.** The v1.6.4 entry below recorded it as *"Not fixed upstream … still + replayed unsanitised"* — that note is now superseded. pi-ai 0.84.2 adds a + recursive `sanitizeBedrockDocument()` and applies it at exactly the site that + entry named ([#7882](https://github.com/earendil-works/pi/pull/7882)): + + ```diff + - toolUse: { toolUseId: c.id, name: c.name, input: c.arguments }, + + toolUse: { toolUseId: c.id, name: c.name, input: sanitizeBedrockDocument(c.arguments) }, + ``` + + (`dist/api/bedrock-converse-stream.js` — line 692 in pi-ai 0.84.1, 704 in + 0.84.2; it was 644 in 0.83.0 and 634 in 0.82.1.) The sanitiser drops object + members whose key is the empty string, recursing through arrays and nested + objects and preserving every valid value. It runs while the request is built, + so it covers the live turn *and* a resume: a session already bricked by an + empty-key tool argument now replays instead of dying on a Bedrock + `ValidationException`. **`pi-session-repair` (in `cli_utils`) is therefore no + longer the recovery path on this image.** It stays useful for older images and + for inspecting a transcript, because the stored `.jsonl` is still malformed — + the fix sanitises what is *sent*, not what was *recorded*. + + **Why bumping `PI_VERSION` is the only way to get it:** pi publishes an + `npm-shrinkwrap.json`, which pins transitive dependencies *exactly*. pi + 0.84.1's shrinkwrap pins `@earendil-works/pi-ai` to **0.84.1**, so although + 0.84.1's `package.json` range is `^0.84.1` — which would otherwise admit + 0.84.2 — rebuilding the old pin can never pick the fix up. Transitive upstream + fixes do not leak into this image; `PI_VERSION` is the whole gate. + + Rest of the audit, against the integration surface the pin policy names: + + - **Session `.jsonl` format — unchanged.** Identical + `migrateV1ToV2`/`migrateV2ToV3` ladder in both versions, so existing sessions + on the named volume load as-is and `pi-session-repair`'s parse target is + untouched. + - **Node engine floor — unchanged** at `>=22.19.0` (image ships 22.23.2). + - **pi-atelier — no change needed.** The pin stays `v0.8.0`: the hard floor is + "never pair < 0.7.1 with pi >= 0.84", this bump does not leave 0.84.x, and + atelier's `peerDependencies` (`>=0.80.7`) are satisfied. pi-atelier **0.8.1** + is published but deliberately NOT adopted here — one variable at a time, and + atelier is the component that has drawn blood at startup. + - **Directly relevant to `pi --ssh` use of this image:** 0.84.2 fixes split + `Alt+Enter` over SSH being misread as Escape, and adds `PI_TUI_ESC_TIMEOUT` + for high-latency terminals. + - **Keybindings — one surface worth knowing.** `pi-toolkit` ships exactly one + override, `tui.input.newLine: [shift+enter, ctrl+j, alt+j]`. 0.84.2's new + fullscreen transcript search (`Ctrl+Shift+F`) binds `Shift+Enter` to + *previous match* while its overlay is focused. Different context, so no + conflict is expected — but it is the one place the override meets a new + default, and the first place to look if "shift+enter stopped inserting a + newline" is ever reported. + - **New `defaultTools` setting** (choose startup built-in tools globally or per + project) is additive; `pi-toolkit`'s `settings.example.json` does not set it, + so the bootstrap template needs no change. + +### Bumped: pi-atelier v0.8.0 → v0.8.1 + +- **`ARG PI_ATELIER_REF` / `ARG PI_ATELIER_VERSION` = `v0.8.1`** + (`Dockerfile.variant`), bumped *together* with `PI_VERSION` as that pin's + comment requires — and this pairing is a good advert for the rule, because both + sides touched fullscreen input handling within three days of each other. + + atelier 0.8.1 (2026-08-12) is two changes, only one of them code: *"Preserve + fullscreen transcript mouse-wheel scrolling after Sidebar resize and visibility + changes by leaving Pi's persistent mouse reporting enabled"*, plus a README + simplification. The single source file that differs from 0.8.0 is + `src/split-pane.ts`. It extracts an `isPiFullscreenRenderer()` predicate and, + under pi's fullscreen renderer, stops writing its own + `\e[?1002h\e[?1006h` / `\e[?1006l\e[?1002l` pair around a sidebar resize — + previously it enabled mouse reporting on grab and disabled it on release, which + tore down the reporting **pi itself** had switched on and left the wheel dead + afterwards. Outside fullscreen it manages mouse mode exactly as before. It also + now captures the terminal it enabled mouse on and writes the disable sequence to + *that* terminal instead of to whatever `tui` currently points at. + + **The audit that matters is the private-internals coupling**, since that is what + hung startup at 0.6.0/0.7.0. atelier reaches into three pi internals; all three + are unchanged in pi 0.84.2: + + - **`TuiAltScreen`** — detected *by constructor name*, so a rename would + silently disable both the resize-input prioritisation and the new mouse + behaviour, with no error. Still + `class TuiAltScreen extends TuiBase implements ViewportTUI`. + - **`tui.inputListeners`** — a private `Set` that atelier deletes from and + re-adds to, to get its resize handler ahead of pi's viewport listener (which + "consumes every mouse event for text selection"). Still `inputListeners = new + Set()`, at the identical line 103 of `pi-tui/dist/tui.js` in both versions, + and still a `Set` — atelier guards with `instanceof Set`. + - **the prototype `render` descriptor** it wraps via `findPrototypeRender`. + Still an own `render(width)` on `TuiAltScreen`. + + pi's mouse sequences are byte-identical between 0.84.1 and 0.84.2 (same + `1002h`/`1006h`/`1002l`/`1006l`/`1003h` occurrence counts), so atelier's + assumption about what pi leaves enabled still holds. `pi-tui`'s base class + changed additively only (one new `isOverlayFocused()`), and `TuiAltScreen`'s own + changes are the new search feature (`activeSearch`, `openSearch`/`closeSearch`, + the two search match styles, `copySelection`). + + **Caveat, stated plainly:** pi 0.84.2 adds a focused fullscreen *search overlay* + that participates in input handling, while atelier reorders input listeners + around pi's viewport listener. The two look convergent — 0.84.2 separately fixes + *"focused fullscreen overlays not receiving mouse wheel or viewport scroll + keys"* — but this pairing is reasoned from the diffs, **not proven by + execution**: the CI smoke test does not drive the TUI, so a fullscreen + interaction regression would not be caught before pull. Worth an `alt+a` plus a + sidebar resize and a wheel scroll in fullscreen on first use of this image. + + Version metadata is unchanged: `engines.node >=22.19.0`, `peerDependencies` + still the uninformative `>=0.80.7` on both pi packages (so still nothing in npm + metadata encodes the real floor), and still zero runtime dependencies — so the + "no `npm install` step" note above stays true. The GitHub tag `v0.8.1` exists + (commit `c31d7439`), which is what CI resolves to a SHA. + ### Notes - The `Dockerfile.base` change moves the base hash, so this needs a base diff --git a/Dockerfile.variant b/Dockerfile.variant index a228004..5fafa5a 100644 --- a/Dockerfile.variant +++ b/Dockerfile.variant @@ -56,7 +56,7 @@ ARG USER_NAME=developer # current when it was first populated (shipped the same bytes for pi-devbox # v0.74.0..v0.75.5; discovered + fixed in v0.75.5b, 2026-05-23). The `latest` # branch below is kept only for a deliberate local `docker build` override. -ARG PI_VERSION=0.84.1 +ARG PI_VERSION=0.84.2 ARG PI_TOOLKIT_REF=main ARG PI_EXTENSIONS_REF=main # Repo URLs default to the canonical gitea origin but are overridable so a @@ -92,9 +92,9 @@ ARG PI_OBSMEM_REF=master # the /opt checkout. Adding an install here would be a no-op that only costs # build time. ARG PI_ATELIER_REPO=https://github.com/michaelmjhhhh/pi-atelier.git -ARG PI_ATELIER_REF=v0.8.0 +ARG PI_ATELIER_REF=v0.8.1 # Human-readable tag PI_ATELIER_REF was resolved from; recorded as a label. -ARG PI_ATELIER_VERSION=v0.8.0 +ARG PI_ATELIER_VERSION=v0.8.1 RUN set -e && \ # git_fetch_ref: clone-equivalent helper that accepts EITHER a branch name diff --git a/README.md b/README.md index e54b0ab..458bc44 100644 --- a/README.md +++ b/README.md @@ -989,8 +989,8 @@ resolved to `latest` at build time: | Component | Pin | Where | |---|---|---| -| pi | `0.84.1` | `ARG PI_VERSION` — `Dockerfile.variant` | -| pi-atelier | `v0.8.0` | `ARG PI_ATELIER_REF` — `Dockerfile.variant` | +| pi | `0.84.2` | `ARG PI_VERSION` — `Dockerfile.variant` | +| pi-atelier | `v0.8.1` | `ARG PI_ATELIER_REF` — `Dockerfile.variant` | | mempalace | `3.6.0` | `ARG MEMPALACE_VERSION` — `Dockerfile.base` | The objective is **not** to freeze versions. Bumping is routine — usually one