Skip to content

feat(pocket-pi): bump to pi 0.81 + self-contained embedded binary - #3

Merged
doodlewind merged 3 commits into
mainfrom
feat/ts-build-and-slim
Jul 22, 2026
Merged

feat(pocket-pi): bump to pi 0.81 + self-contained embedded binary#3
doodlewind merged 3 commits into
mainfrom
feat/ts-build-and-slim

Conversation

@doodlewind

Copy link
Copy Markdown
Contributor

Two phases of a larger effort (the TypeScript build-pipeline rewrite lands as a follow-up).

Phase 1 — bump to latest pi (@earendil-works/pi-coding-agent@0.81.1)

Upstream moved scope (@mariozechner@earendil-works) and jumped 0.73 → 0.81, which was a real migration, not a version bump:

  • Model/auth layer restructured → migrated the harness to the new ModelRuntime API (ModelRuntime.create, setRuntimeApiKey); auth classes moved off the barrel (deep-imported like loadExtensionFromFactory).
  • undici is new in 0.81 (pi's HTTP-proxy transport). It's never on our request path — the native hub owns proxying — so it's aliased to a stub at bundle time, keeping its whole web-fetch/websocket/cache stack out. pi's own source stays unmodified; same "heavy Node transport → native" rule the trimmed bundle applies to pi-ai.
  • New runtime surface the newer bundle needs: node:console, worker_threads.Worker, async_hooks.AsyncResource (real base class so class X extends AsyncResource loads), util.debuglog, path.toNamespacedPath, crypto.getHashes, process.execPath, Web globals (MessagePort/EventTarget/…), and fd-based fs writes (0.81 persists via openSync("wx") + writeFileSync(fd) instead of appendFileSync).

Validated end-to-end on 0.81: bundle loads, real gpt-5.6 turn (pocket pi lives), extension tool call (hook fires + echo executes), session persist/resume.

Phase 2 — minify + gzip-embed → 8.9 MB self-contained binary

  • Bundle 12.4 MB → 9.0 MB (whitespace minify — esbuild's identifier and syntax minification both emit tokens the embedded QuickJS parser rejects, so whitespace + --line-limit only; gzip reclaims the rest) → 1.8 MB gzip.
  • Behind an embed-full-pi Cargo feature (off by default so CI/dev — which path-load the bundle in #[ignore] tests — don't need it), the gzip is include_bytes!'d and gunzipped at load via PiRuntime::load_full_pi() (declare → set import.meta.url → eval).
  • A binary running the full unmodified pi is now one 8.9 MB file — vs. the old 7 MB binary + 13 MB sidecar. examples/self_contained.rs demonstrates it.

Tests / CI

  • Default suite green (23 unit + module-system tests), clippy -D warnings clean.
  • #[ignore] bundle-gated: loads_bundled_pi_coding_agent, binds_extension_into_session, persists_and_resumes_session, loads_pi_extension_via_our_loader (offline); runs_bundled_pi_turn, runs_pi_turn_with_extension_tool (network); loads_embedded_full_pi (feature + ignore).
  • README updated: footprint, sync scope, Path B jargon removed.

🤖 Generated with Claude Code

doodlewind and others added 3 commits July 22, 2026 13:24
…version)

Upstream pi moved scope (@mariozechner@earendil-works) and jumped 0.73→0.81,
which restructured the model/auth layer and pulled undici onto the HTTP path.
Migrated the runtime and harness to run the new unmodified pi end-to-end.

Model/auth (0.81):
- createAgentSession now takes a `modelRuntime` (ModelRuntime.create), not an
  authStorage+ModelRegistry. Harness builds an in-memory, offline ModelRuntime
  and sets the key via `setRuntimeApiKey`; the custom gpt-5.6 model is passed
  straight through. entry.mjs deep-imports ModelRuntime + the auth classes (off
  the barrel now).

undici (new transitive HTTP transport in 0.81):
- pi only uses undici for its proxy-fetch path, which Pocket Pi never triggers
  (the native hub owns proxying). Aliased `undici` to a tiny stub at bundle time
  so its whole web-fetch/websocket/cache stack stays out — pi's source unmodified,
  same "heavy Node transport → native" rule the trimmed bundle applies to pi-ai.

Runtime surface the newer bundle needs:
- new `node:console` builtin (Console class); worker_threads.Worker + friends;
  path.toNamespacedPath/format; util.debuglog; async_hooks.AsyncResource (real
  base class so `class X extends AsyncResource` loads); crypto.getHashes/
  timingSafeEqual; process.execPath/argv0/pid; Web globals MessagePort/
  MessageChannel/EventTarget/Event/CustomEvent/DOMException.
- fs: openSync now honors write/append/exclusive flags ("wx", "a", …) and
  writeFileSync/writeSync accept a file descriptor (0.81's SessionManager._persist
  writes via fd instead of appendFileSync).

Verified end-to-end on 0.81: bundle loads, real gpt-5.6 turn ("pocket pi lives"),
extension tool call (hook fires + echo executes), session persist/resume. Full
suite green (23), clippy clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-contained binary

Shrinks the one-shot distributable. The full unmodified pi-coding-agent bundle
was a 13 MB .js loaded from disk; now it minifies to 9 MB, gzips to 1.8 MB, and
(behind the `embed-full-pi` feature) is embedded in the binary and gunzipped at
load. A binary that runs the full pi is a single self-contained 8.9 MB file —
nothing alongside it, nothing to npm install (vs. the old 7 MB binary + 13 MB
sidecar).

- build-pi-full.mjs: whitespace-minify + --line-limit (identifier and syntax
  minification both emit tokens the embedded QuickJS parser rejects; gzip
  reclaims the difference), then emit pi-full.bundle.js.gz.
- Cargo `embed-full-pi` feature (off by default so dev/CI, which path-load the
  bundle in #[ignore] tests, don't need it) pulls in flate2 (pure-Rust backend)
  and include_bytes! the gzip.
- lib.rs: `embedded_full_pi_bundle()` (gunzip) + `PiRuntime::load_full_pi()`
  (declare → set import.meta.url → eval, since the in-memory module bypasses the
  loader that normally sets it). examples/self_contained.rs demonstrates it;
  loads_embedded_full_pi test (feature+ignore) asserts it initializes.

Default suite green (23), clippy clean; feature build + embedded load verified.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Corrects facts changed by the bump + embed work (and removes the internal
"Path B" jargon still on main): footprint is now one self-contained binary,
~8.9 MB with the full unmodified pi embedded (gzip) or ~7 MB trimmed-core only;
sync scope is @earendil-works; the full bundle is ~9 MB minified / ~1.8 MB gzip;
notes the undici stub.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@doodlewind
doodlewind merged commit fef8ac9 into main Jul 22, 2026
1 check passed
@doodlewind
doodlewind deleted the feat/ts-build-and-slim branch July 22, 2026 05:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant