v0.3.0
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-coreandpi-coding-agentcode, copied from the pinned 0.87.1 release, instead of PiG's earlier stand-ins. This includes Pi'sResourceLoaderandcreateAgentSession, and the theme helpers such asgetSelectListTheme(#88).pi-mcp-adapternow loads and its/mcppanel, 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 asmain.tsno 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 aspi-wardenwork in-pruns (#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-whichandcross-spawnresolve them, including drive-relative paths. Canonical paths are walked as Node'srealpathSyncdoes, and a link target rooted on a drive keeps the drive./loginopens 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 usedcmd /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
/loginand--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.orRequest timed out., as they do in Pi (#86, co-authored with @ShoichiTect). - Anthropic
/loginaccepts 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
httpProxysettings apply.
- Providers such as DeepSeek, OpenCode Go and xAI now appear in
- Go installs. The release procedure publishes the
extensions/sdk/v0.3.0tag before the root release, and CI checks public tags and checksums without the workspace override, sogo install github.com/MichaelKinsy/PiG/cmd/pig@v0.3.0builds outside the checkout (#82). - Startup and Sessions. A missing
auth.jsonis created as{}with owner-only permissions, as in Pi./resumelists, 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
experimentalserver, Session workers and client TUI are ported. They are in no release binary. Build withgo build -tags=pig_experimental ./cmd/pigand setPI_EXPERIMENTAL=1to useserverandclient. They are Unix-only. Seecmd/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
Contextgetters now return anerrorlast. A host or transport failure is an error, not an empty value or an assumed default.IsIdleno longer assumes idle,IsProjectTrustedno longer assumes trusted, andGetFlagno longer falls back to the registered default. - Pi's
undefinedis a nil pointer.GetSessionName,GetSessionFileandGetLeafIDreturn(*string, error).GetContextUsageandGetModelInforeturn a nil pointer when absent.GetContextUsagefieldsTokensandPercentare*intand*float64, nil when unknown. GetBranchandGetEntriesreturn([]T, error).ExecOptions.TimeoutandDialogOptions.Timeoutarefloat64, as Pi's timeouts are numbers.- Optional booleans such as
SendMessageOptions.TriggerTurnare*bool. Usesdk.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
/arminsayshiand/dementedelvescommands) 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 focusesnull, 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
getProviderstill 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 nopi.events. Payloads no longer arrive as JSON copies. - D77 (explicit Node isolation prevents sharing
pi.events) is retired. All Node processes share onepi.eventsbus, 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-recordscomparison 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,RegisterNativeProviderorUnregisterProvideron 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/reloadmatch 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.
uninstallremoves 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.
/settingsstays open while applying changes, and/thinkingcompletes 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 generaterefreshes committed inventories, andmake set-version VERSION=x.y.zprepares 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
- Stop older PiG processes before replacing the executable.
- 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 updatedoes not switch methods (D39). On Windows, run the installer again. - Keep your agent directory. Do not delete credentials, settings or lock directories. If an older process holds a lock, stop that process.
- Node.js 22.13 or newer is needed only for TypeScript and JavaScript extensions. The core binary does not need Node.
- Separate
.pigstorage is the default. SetPIG_USE_PI_DIRS=1only to share Pi's agent directory and project.piresources (D2). Do not edit one Session from two processes. - Mask secret input in
/settingsis 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. - 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
- @ShoichiTect: reported #53, #59, #86 and #87, and contributed PRs #54 and #60 (catalog-derived provider availability and the startup model builder).
- @klonuo: reported the
pi-acpproblem (#47), whose discussion led to the RPC record, shutdown and response-order fixes (#70). - @drg407: reported #82 and #83.
- @luiul: reported #78.
- @fooofei: reported #65.
- @fireirohuncle: reported #71.
- @ByronFinn: reported #75 and contributed the fix (#76).
- @nguyen-tran-100x: reported #88.
- @SilverTab: reported #85.
- @charkear: reported #44 and contributed the docs fix (#45).
- @ExcuseMeBro: requested DeepSeek support (#50).
- @kanishkaverma: contributed the pasted-redirect Anthropic login (#63) and identified the missing default-model selection after login.
- @baggiiiie: reported #89 (
pig configEsc and Ctrl-C) and contributed the fix (#90).
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.