Skip to content

v0.3.0

Latest

Choose a tag to compare

@github-actions github-actions released this 29 Sep 20:12
Immutable release. Only release title and notes can be modified.
f144ac8

v0.3.0

PiG-v03 0-herd

PiG 0.3.0 is a Go implementation of Pi 0.87.1. These notes cover changes since 0.2.0. The unpublished 0.2.1 candidate is included, so upgrade directly from 0.2.0.

Thanks to everyone who reported an issue or sent a change: @ShoichiTect, @klonuo, @drg407, @luiul, @fooofei, @fireirohuncle, @ByronFinn, @nguyen-tran-100x, @SilverTab, @charkear, @ExcuseMeBro, @kanishkaverma and @baggiiiie. Details are under Thanks.

What you will notice

  • Pi extensions load more often, and behave more like they do in Pi. Node extensions now import Pi's own pi-tui, pi-ai, pi-agent-core and pi-coding-agent code, copied from the pinned 0.87.1 release, instead of PiG's earlier stand-ins. This includes Pi's ResourceLoader and createAgentSession, and the theme helpers such as getSelectListTheme (#88). pi-mcp-adapter now loads and its /mcp panel, tool cards and argument completions work (#85). Package entry points, default exports and compatibility exports follow Pi (#71). This does not qualify every Package; see the extension compatibility boundary.
  • TypeScript extensions load on Node 22, 24 and 26. PiG loads extensions with the same jiti release and options as Pi. The removed mode: 'transform' call that broke Node 24 and later is gone (#65). A malformed Package manifest no longer stops startup, and conventional entry files such as main.ts no longer hide sibling extensions (#78). Node 22.13 is still the minimum. The eleven npm packages from the reports were checked against Pi on Node 22, 24 and 26, and CI loads Packages on the minimum and the current Node.
  • Session IDs in every mode. Print and JSON mode, including --no-session, now give extensions a Session ID, so session-keyed extensions such as pi-warden work in -p runs (#83). Interactive and RPC modes keep their existing behavior. The Go, Python and Rust SDKs now return the host's Session ID, file path and leaf ID, including after a switch to an in-memory Session.
  • Windows process and path parity. Child processes start with Node's command-line quoting, including Git Bash. Commands resolve as node-which and cross-spawn resolve them, including drive-relative paths. Canonical paths are walked as Node's realpathSync does, and a link target rooted on a drive keeps the drive. /login opens URLs without a command shell, so OAuth parameters are not cut at & and a crafted URL is not interpreted as a command (0.2.0 used cmd /c start; macOS and Linux were not affected). Windows remains a preview.
  • Provider fixes.
    • Providers such as DeepSeek, OpenCode Go and xAI now appear in /login and --list-models, and the first request goes to the catalog endpoint with the right API kind (#50, #53).
    • Z.ai thinking requests send clear_thinking: false, so prior reasoning is kept (#75).
    • OpenAI-compatible transport failures read Connection error. or Request timed out., as they do in Pi (#86, co-authored with @ShoichiTect).
    • Anthropic /login accepts a pasted redirect URL or code. Bedrock, Vertex and Cloudflare setup steps are restored. After a login with no model selected, PiG picks and saves that provider's default.
    • Request and stream details are corrected across OpenAI Completions and Responses, Azure, Google, Vertex, Anthropic, Bedrock and Codex. Global httpProxy settings apply.
  • Go installs. The release procedure publishes the extensions/sdk/v0.3.0 tag before the root release, and CI checks public tags and checksums without the workspace override, so go install github.com/MichaelKinsy/PiG/cmd/pig@v0.3.0 builds outside the checkout (#82).
  • Startup and Sessions. A missing auth.json is created as {} with owner-only permissions, as in Pi. /resume lists, highlights and protects the current Session. Long Sessions resume without reading the whole history for branch settings. Stale empty lock files from 0.2.0 are reclaimed safely.
  • Experimental server and client, source builds only. Pi's experimental server, Session workers and client TUI are ported. They are in no release binary. Build with go build -tags=pig_experimental ./cmd/pig and set PI_EXPERIMENTAL=1 to use server and client. They are Unix-only. See cmd/pig-experimental/README.md.

Issues fixed

Issue Fix Reporter
#89 pig config Esc and Ctrl-C close the selector like Pi; prompt below the menu (with #90 by @baggiiiie) @baggiiiie
#88 pi-bro fails to load: getSelectListTheme missing from the Node bridge @nguyen-tran-100x
#86 OpenAI transport errors use Pi's Connection error. and Request timed out. @ShoichiTect (co-author)
#85 pi-mcp-adapter crashes and missing UI, tool and completion behavior @SilverTab
#83 No Session ID in print and JSON mode @drg407
#82 go install fails without the extensions/sdk/v0.3.0 tag @drg407
#78 Startup exits on a Package manifest such as npm:context-mode @luiul
#75 Z.ai thinking payload lacks clear_thinking: false @ByronFinn
#71 Pi Package extensions fail on missing exports and entry points @fireirohuncle
#65 TypeScript extensions fail on Node 24 and later @fooofei
#53 Catalog providers missing from --list-models and /login @ShoichiTect
#50 DeepSeek support @ExcuseMeBro
#44 defaultModel needs a separate provider; the docs now say so @charkear

Go SDK migration

This affects Go extensions written against 0.2.0. Rust and Python change in the same way, and Node is unchanged.

  • Host-backed Context getters now return an error last. A host or transport failure is an error, not an empty value or an assumed default. IsIdle no longer assumes idle, IsProjectTrusted no longer assumes trusted, and GetFlag no longer falls back to the registered default.
  • Pi's undefined is a nil pointer. GetSessionName, GetSessionFile and GetLeafID return (*string, error). GetContextUsage and GetModelInfo return a nil pointer when absent. GetContextUsage fields Tokens and Percent are *int and *float64, nil when unknown.
  • GetBranch and GetEntries return ([]T, error).
  • ExecOptions.Timeout and DialogOptions.Timeout are float64, as Pi's timeouts are numbers.
  • Optional booleans such as SendMessageOptions.TriggerTurn are *bool. Use sdk.Bool(true).

Before and after:

// 0.2.0
if usage := ctx.GetContextUsage(); usage != nil && usage.Tokens > 0 { ... }

// 0.3.0
usage, err := ctx.GetContextUsage()
if err != nil { return err }
if usage != nil && usage.Tokens != nil && *usage.Tokens > 0 { ... }

Rust methods return io::Result<T> (or io::Result<Option<T>>), and Python methods raise HostCallError and return None when absent. The full table is in the extension guide and extensions/sdk/README.md.

Divergence changes

Read the full divergence ledger for scope and removal conditions.

  • D27 (word segmentation) is narrowed to one case: the first cold-cache segmentation of a dictionary span that starts at ー (U+30FC) or ー (U+FF70) in a fresh Pi process. Every other result matches Pi.
  • D35 (hidden /arminsayshi and /dementedelves commands) is retired. Every frame and the announcement match Pi.
  • D73 (main-process objects do not cross into Node extensions) is narrowed. OverlayHandle.unfocus({ target }) now focuses null, the extension's editor component, or another of its mounted overlays, as Pi does. A component the extension did not mount still throws.
  • D78 (SDK Provider objects) is narrowed. Node extensions in one process share Pi's single registered configuration root, and Node extensions in different processes see the same root by reference. Go, Rust and Python registrations remain snapshots, and getProvider still cannot return every built-in or composed Provider from those SDKs.
  • D83 (cross-process event-bus identity) is narrowed to five named boundaries: atomicity at synchronous waits, microtask order after the first continuation, cross-process reference cycles, proxy brand checks such as util.types.isMap, and native SDKs, which have no pi.events. Payloads no longer arrive as JSON copies.
  • D77 (explicit Node isolation prevents sharing pi.events) is retired. All Node processes share one pi.events bus, including strict-isolation extensions and exact standalones. Listeners receive the emitter's original object. Process and crash isolation remain.
  • D82 (partial-message observation over RPC) is narrowed to extension processes. Same-process observation now matches Pi for every built-in provider API on the HTTP/1 transport, and the strict rpc/33-rpc-real-provider-records comparison passes. An extension process still receives a snapshot of each partial message, not Pi's live object.
  • D84 (new): direct Go provider registration. A Go program that calls RegisterProvider, RegisterNativeProvider or UnregisterProvider on the Model Registry or Model Runtime, with no extension host, sees the catalog and provisional auth at once. Pi's follow-up refresh runs at that caller's next awaited model-runtime call, not on its own. Extension registrations, startup and /reload match Pi.
  • D85 (new): RPC shutdown residuals from process-per-extension hosting. When RPC input ends, PiG matches Pi for commands that settle within Pi's window (microtasks and the first event-loop iteration) and holds back a response for a command that is still suspended. Two residuals remain. One Node runtime cannot observe a command in another runtime process that settles while a suspended handler in its own process keeps Pi alive. Host-call suspension during the shutdown tail and keepalive across separate runtime cells are not fully covered.

D79 (user-package metadata lookups skip the invoking project's .npmrc) and D80 (maskSecretInput, on by default) are new since 0.2.0.

Other changes

Extensions and Packages

  • Custom tool renderers, headers, footers, overlays, editors, keybindings, theme lookups and argument completions follow Pi. Tool results keep the order of their text and images through hooks, Sessions and export.
  • Retained extension contexts stay on their original connection. Extension crashes are reported once, and normal-shutdown logs are removed.
  • uninstall removes Packages. Filters survive a ref change, npm and Git output streams, and failed Git checkouts are cleaned up. Package-manager commands respect project trust.

Sessions and terminal

  • Branch-local model and thinking state, labels, compaction boundaries and older Pi Session formats are preserved. Session listing is progressive and cancellable.
  • RPC follows Pi's record order, queues, JSONL framing and signal exits. Print and JSON mode dispatch extension commands before input transformation.
  • Tree ordering and search, Unicode cursor and width handling, remapped submit keys, clipboard image conversion and overlay focus are corrected. /settings stays open while applying changes, and /thinking completes its arguments.

Startup and performance

  • Model-catalog reads share one cached copy. The embedded Node runtime is compressed, and its Jiti and bytecode caches are validated against source. These are reductions in repeated work, not a general speedup claim; the performance findings list workloads and remaining gaps.

Development

  • make generate refreshes committed inventories, and make set-version VERSION=x.y.z prepares a release. Commits need a DCO sign-off and a GitHub-verified signature.
  • More of Pi's own tests are ported with their original inputs. The release gate rejects pending or partial hot-path test ports. Known gaps are listed in docs/parity/KNOWN-GAPS-0.3.x.md.
  • A nightly Live providers workflow runs provider tests with real credentials. It is not a pull-request check.

Upgrade notes

  1. Stop older PiG processes before replacing the executable.
  2. Update through the method that installed PiG: npm update -g @pi-in-go/pig, go install github.com/MichaelKinsy/PiG/cmd/pig@v0.3.0, or the release installer. pig update does not switch methods (D39). On Windows, run the installer again.
  3. Keep your agent directory. Do not delete credentials, settings or lock directories. If an older process holds a lock, stop that process.
  4. Node.js 22.13 or newer is needed only for TypeScript and JavaScript extensions. The core binary does not need Node.
  5. Separate .pig storage is the default. Set PIG_USE_PI_DIRS=1 only to share Pi's agent directory and project .pi resources (D2). Do not edit one Session from two processes.
  6. Mask secret input in /settings is on by default (D80). Secret prompts show dots, a count and the last four characters. Turn it off to get Pi's plain-text prompt.
  7. Go extension authors: read the Go SDK migration.

PiG is pre-stable. Read the extension compatibility boundary and the SDK matrix before relying on a Package.

Links: installation guide, provider guide, coverage report, full changelog.

Thanks

Reddit users rokrdev, WorriedAcanthisitta3, slypheed and zRafox reported extension failures that led to fixes in 0.2.1 and 0.3.0.

Pi is the reference implementation, and its documentation describes the upstream behavior. Michael Kinsy created PiG, which was originally developed at Hewlett Packard Enterprise. PiG is an independent implementation and does not imply endorsement by Pi's maintainers.