From b5e356bfb35a2d43b3246cac6f8ad527aaf952d4 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 2 Oct 2026 12:02:05 -0400 Subject: [PATCH] workspace image: upgrade pi coding agent to 1.0.0 Bump the sha512-pinned tarball from 0.99.2 to 1.0.0. Pi 1.0 runs its TUI fullscreen by default; provision tuiMode "regular" (and backfill it for existing settings.json) so the web terminal keeps its normal scrollback. Verified the builtin extensions' API surface (getAgentDir, CustomEntry, EntryRenderOptions, ExtensionCommandContext, Theme, and pi-tui Container/Text) is unchanged in 1.0.0. --- docs/changes.md | 7 +++++++ docs/features/ai-coding-harnesses.md | 4 ++++ src/containers/workspace/Dockerfile | 4 ++-- .../workspace/builtin-extensions/startup-header.ts | 2 +- src/containers/workspace/klangk-setup-pi.py | 5 +++++ src/klangk/klangkd-tests/tests/test_setup_pi.py | 6 ++++++ 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/docs/changes.md b/docs/changes.md index cc22824fa..41cb1df79 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -2328,6 +2328,13 @@ stop)`) and a `server: stop at 23:00 (in 1h 12m)` status line in the ### Changed +- **Workspace Pi agent updated to 1.0.0 (#3542).** Workspaces now + bundle Pi coding agent 1.0.0 (previously 0.99.2). Pi 1.0 runs its + TUI fullscreen by default; workspace provisioning pins + `tuiMode: "regular"` so the web terminal keeps its normal + scrollback. Users who prefer fullscreen can set `tuiMode` to + `"fullscreen"` in their own `~/.pi/agent/settings.json`. + - **Pi startup phone-home to pi.dev is off in workspaces (#3530).** Workspace containers now set `PI_OFFLINE=1` (alongside the existing `PI_SKIP_VERSION_CHECK=1`), so a Pi session inside a workspace no diff --git a/docs/features/ai-coding-harnesses.md b/docs/features/ai-coding-harnesses.md index f808dce75..c828ca3ae 100644 --- a/docs/features/ai-coding-harnesses.md +++ b/docs/features/ai-coding-harnesses.md @@ -56,6 +56,10 @@ Extensions are installed at image build time into `~/.pi/agent/` at first login. Users can install additional extensions with `pi install`. +The per-user settings provisioned at login also pin +`tuiMode: "regular"`: Pi 1.0 runs its TUI fullscreen by default, +which would replace the web terminal's normal scrollback. + ## System prompt Agents share a system prompt installed at `~/AGENTS.md` on first diff --git a/src/containers/workspace/Dockerfile b/src/containers/workspace/Dockerfile index 525412650..9b945e3d5 100644 --- a/src/containers/workspace/Dockerfile +++ b/src/containers/workspace/Dockerfile @@ -17,8 +17,8 @@ FROM $WORKSPACE_BASE_IMAGE # registry's own integrity record: # npm view @earendil-works/pi-coding-agent@ dist.integrity # (base64 sha512 -> hex), or sha512sum of the fetched tarball. -ARG PI_AGENT_VERSION=0.99.2 -ARG PI_AGENT_SHA512=e91d4167637bec2ad57067f7782d8aa2f4f3d50e1162201ec9dbd55904f9e3a3767e2d6705cf356944656ce64282bb96a16f5563f52b2f30f29c5e184e8969a0 +ARG PI_AGENT_VERSION=1.0.0 +ARG PI_AGENT_SHA512=fc5b5bc6849053f984bf542789c8498d18eab5ea9a21a316c66841e06dfaefe33065f5fbfc323907d60083996a6cdee7ced16c90112d51267e16598c0440ad33 # Network downloads in this Dockerfile use `--retry 5 --retry-delay 2 # --retry-all-errors`: GitHub-hosted runners occasionally reset connections # mid-transfer (curl exit 35, #2797), and without retries a single blip diff --git a/src/containers/workspace/builtin-extensions/startup-header.ts b/src/containers/workspace/builtin-extensions/startup-header.ts index 29794279c..2e5b75f00 100644 --- a/src/containers/workspace/builtin-extensions/startup-header.ts +++ b/src/containers/workspace/builtin-extensions/startup-header.ts @@ -7,7 +7,7 @@ * re-prints the startup header's sections — loaded context files, * skills, prompt templates, and extensions — as a persistent session * entry that never enters the LLM context. The sections are rebuilt - * from live session data (pi 0.99.2 exposes no API to re-run its own + * from live session data (pi 1.0.0 exposes no API to re-run its own * renderer), so edge cases can diverge from the startup header: the * Skills section is empty when `enableSkillCommands` is off, and the * Extensions section lists files found on disk rather than ones that diff --git a/src/containers/workspace/klangk-setup-pi.py b/src/containers/workspace/klangk-setup-pi.py index 85793ebb9..746584cd9 100755 --- a/src/containers/workspace/klangk-setup-pi.py +++ b/src/containers/workspace/klangk-setup-pi.py @@ -75,6 +75,10 @@ def write_settings(): # repeats on every fresh shell; /header (a builtin extension) # re-prints it on demand (#3537). image_settings["quietStartup"] = True + # Pi 1.0 runs its TUI fullscreen by default, which replaces the + # normal terminal scrollback with pi's own viewport. The web + # terminal depends on that scrollback, so keep the regular mode. + image_settings["tuiMode"] = "regular" # Point at image dirs directly — Pi also auto-discovers # ~/.pi/agent/{extensions,skills,prompts}/ for user-installed ones. image_settings["extensions"] = [str(IMAGE_DIR / "extensions")] @@ -94,6 +98,7 @@ def ensure_settings_keys(): defaults = { "theme": "dark", "quietStartup": True, + "tuiMode": "regular", "extensions": [str(IMAGE_DIR / "extensions")], "skills": [str(IMAGE_DIR / "skills")], "prompts": [str(IMAGE_DIR / "prompts")], diff --git a/src/klangk/klangkd-tests/tests/test_setup_pi.py b/src/klangk/klangkd-tests/tests/test_setup_pi.py index b56486886..b5b6786a6 100644 --- a/src/klangk/klangkd-tests/tests/test_setup_pi.py +++ b/src/klangk/klangkd-tests/tests/test_setup_pi.py @@ -58,6 +58,7 @@ def test_creates_settings_with_all_keys(self, fake_home, monkeypatch): assert settings["hideThinkingBlock"] is True assert settings["theme"] == "dark" assert settings["quietStartup"] is True + assert settings["tuiMode"] == "regular" assert settings["extensions"] == [str(sc.IMAGE_DIR / "extensions")] assert settings["skills"] == [str(sc.IMAGE_DIR / "skills")] assert settings["prompts"] == [str(sc.IMAGE_DIR / "prompts")] @@ -102,6 +103,7 @@ def test_provisions_when_image_has_no_settings( assert settings["hideThinkingBlock"] is True assert settings["theme"] == "dark" assert settings["quietStartup"] is True + assert settings["tuiMode"] == "regular" assert settings["extensions"] == [str(image_dir / "extensions")] assert settings["skills"] == [str(image_dir / "skills")] assert settings["prompts"] == [str(image_dir / "prompts")] @@ -123,6 +125,7 @@ def test_backfills_missing_keys(self, fake_home): assert settings["prompts"] == [str(sc.IMAGE_DIR / "prompts")] assert settings["theme"] == "dark" assert settings["quietStartup"] is True + assert settings["tuiMode"] == "regular" assert settings["other"] == "keep" def test_preserves_explicit_user_overrides(self, fake_home): @@ -133,6 +136,7 @@ def test_preserves_explicit_user_overrides(self, fake_home): old = { "theme": "light", "quietStartup": False, + "tuiMode": "fullscreen", "extensions": ["/e"], "skills": ["/s"], "prompts": ["/p"], @@ -144,6 +148,7 @@ def test_preserves_explicit_user_overrides(self, fake_home): settings = json.loads((agent / "settings.json").read_text()) assert settings["theme"] == "light" assert settings["quietStartup"] is False + assert settings["tuiMode"] == "fullscreen" def test_no_write_when_all_present(self, fake_home): agent = fake_home / ".pi" / "agent" @@ -151,6 +156,7 @@ def test_no_write_when_all_present(self, fake_home): full = { "theme": "dark", "quietStartup": True, + "tuiMode": "regular", "extensions": ["/e"], "skills": ["/s"], "prompts": ["/p"],