v1.8.0: bump pi 0.84.1 → 0.84.2 and pi-atelier v0.8.0 → v0.8.1, audited
Publish Docker Image / resolve-versions (push) Successful in 12s
Lint / actionlint (push) Successful in 23s
Publish Docker Image / base-decide (push) Successful in 8s
Lint / hadolint (push) Successful in 1m20s
Publish Docker Image / build-base (push) Successful in 41m34s
Publish Docker Image / smoke (push) Failing after 4m41s
Publish Docker Image / build-variant (push) Has been skipped
Publish Docker Image / promote-base-latest (push) Has been skipped
Publish Docker Image / update-description (push) Has been skipped
Publish Docker Image / smoke-studio (push) Failing after 8m22s
Publish Docker Image / build-variant-studio (push) Has been skipped

pi 0.84.2 closes the Amazon Bedrock tool-argument poison pill that v1.6.4
recorded as "Not fixed upstream". pi-ai 0.84.2 adds a recursive
sanitizeBedrockDocument() and applies it at exactly the site that entry named
(dist/api/bedrock-converse-stream.js, line 692 -> 704; upstream PR #7882):

  - toolUse: { ..., input: c.arguments },
  + toolUse: { ..., input: sanitizeBedrockDocument(c.arguments) },

It strips object members whose key is the empty string, recursing through arrays
and nested objects. It runs at request-build time, so it covers the live turn and
a resume alike: a session already bricked by an empty-key tool argument now
replays instead of dying on a Bedrock ValidationException. pi-session-repair is
therefore no longer the recovery path on this image -- it stays useful for older
images and for inspection, since the fix sanitises what is sent, not what was
recorded.

Bumping PI_VERSION is the ONLY way to get that fix: pi publishes an
npm-shrinkwrap.json, so pi 0.84.1 pins pi-ai to exactly 0.84.1 even though its
package.json range (^0.84.1) would admit 0.84.2. Transitive upstream fixes never
leak into this image.

pi-atelier v0.8.1 is the matching companion -- both sides changed fullscreen
input handling within three days. Its only code change (src/split-pane.ts) stops
atelier writing its own 1002h/1006h pair around a sidebar resize under pi's
fullscreen renderer, which had been tearing down the mouse reporting pi itself
enabled and leaving the wheel dead.

Audited against the surfaces the pin policies name:
  - session .jsonl: identical migrateV1ToV2/migrateV2ToV3 ladder
  - node engine floor: unchanged >=22.19.0 (image ships 22.23.2)
  - atelier's three private couplings all intact in pi-tui 0.84.2 --
    class TuiAltScreen extends TuiBase (detected by constructor NAME, so a
    rename would fail silently), inputListeners still `new Set()` at the same
    line 103, own render(width) descriptor still present
  - pi's mouse sequences byte-identical between 0.84.1 and 0.84.2
  - atelier metadata unchanged: engines >=22.19.0, peerDeps >=0.80.7, zero
    runtime deps, so the "no npm install step" note holds

Not proven by execution: CI smoke does not drive the TUI, and 0.84.2 adds a
focused fullscreen search overlay that also participates in input handling. The
pairing is reasoned from the diffs. Worth an alt+a plus a sidebar resize and
wheel scroll in fullscreen on first use.
This commit is contained in:
Joakim Persson
2026-08-15 00:22:08 +02:00
parent cbd7cf5c67
commit 29b62093f0
3 changed files with 131 additions and 7 deletions
+126 -2
View File
@@ -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
+3 -3
View File
@@ -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
+2 -2
View File
@@ -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