Skip to content

v0.3.1

Choose a tag to compare

@github-actions github-actions released this 01 Oct 05:56
Immutable release. Only release title and notes can be modified.
5c9a635

v0.3.1

PiG v0.3.1 herd

PiG 0.3.1 is a patch release of PiG 0.3.0 (a Go implementation of Pi 0.87.1). Upgrade with pig update, or npm install -g @pi-in-go/pig@0.3.1.

Thanks to everyone who reported an issue or sent a change: @jkerdreux-imt, @nguyen-tran-100x, @sj0n, @nickdeighton, @ShoichiTect, @baggiiiie and @SamarthBoranna. Details are under Thanks.

Fixed

  • Fullscreen (alternate-screen) mode keeps the Kitty keyboard-protocol flags on the active screen, as Pi does. The main and alternate screens keep independent protocol stacks, so the flags pushed for the main screen did not apply in fullscreen: Shift+Enter degraded to a bare Enter and ctrl+digit extension shortcuts stopped matching. PiG also no longer leaves the Kitty keyboard flags set in the shell after it exits fullscreen, where ctrl+c arrived as an escape sequence instead of ^C. Thanks @jkerdreux-imt.

  • Color the bash execution block, the compaction and branch summary label, the editor thinking-level border (low, medium, high), and the settings list cursor from the active theme, as Pi does. Light and custom themes now apply their own colors to these elements instead of the dark theme's fixed values. Thanks @jkerdreux-imt.

  • Report a transport failure before response headers on the openai-completions, openai-responses, azure-openai-responses, and openrouter-images paths as Connection error., or Request timed out. for a timeout, as Pi's OpenAI SDK does (openai@6.40.0 APIConnectionError/APIConnectionTimeoutError). Thanks to @ShoichiTect for reporting this (#86).

  • pig config exits on Ctrl-C (also when the terminal reports it as a Kitty CSI-u sequence) and on Escape, and leaves the shell prompt below the selector with the terminal restored, as Pi does (Pi 0.87.1 config-selector.ts:487-493, cli/config-selector.ts:41-49). Thanks @baggiiiie for reporting #89 and the cursor-parking fix in #90.

  • /reload re-invokes each extension factory inside the extension runtime process that already holds its module, as Pi does, instead of starting a fresh process. Module-level state now follows Pi's loader: a native ESM module (.mjs, or .js in a "type": "module" package) keeps its state and, as in Pi, an edit to it is not seen until pig restarts; a .ts module is re-evaluated, and package or module state in a compiled Go, Rust or Python factory persists (D70 is closed). The old generation leaves the shared event bus and its connection closes when the new generation replaces it. A Session replacement in pig still starts a fresh extension host and fresh runtime processes (D70 now covers session replacement only); subprocess.RuntimeRetention is the additive host API for retaining them. Module state lives in the process that holds the module, so changing an extension's isolation setting (a PiG setting Pi lacks) starts a new process and a new module on the next /reload. An extension path holding a tab, line feed or carriage return no longer breaks a Node extension's load or /reload.

  • Apply --exclude-tools (-xt) in --mode rpc, and to the Session that new_session and other replacements create, as Pi does in every mode (Pi 0.87.1 main.ts:541-543,822-830, sdk.ts:258-265). RPC started its Session with only the allowlist, so an excluded tool stayed active and callable.

  • Let an explicit --tools list take precedence over --no-tools and --no-builtin-tools in every mode, as Pi's allowedToolNames = tools ?? (noTools === "all" ? [] : undefined) does. --no-tools --tools bash now leaves bash available, and RPC mode applies --tools to extension tools when --no-builtin-tools is set.

  • Parse --tools (-t) and --exclude-tools (-xt) as Pi's args.ts:147-156 does in every mode: the last occurrence replaces earlier ones instead of merging with them, names are trimmed with JavaScript String.prototype.trim, and an empty --tools "" list is an explicit empty allowlist that leaves no tools instead of the default tools.

  • pig update on an npm-installed PiG installs @pi-in-go/pig. The signed update manifest named the unrelated npm package pig, so the command ran npm install -g pig@<version>. The release generator, the npm packer and the client now read the package name from one place (PackageName in internal/codingagent/paths.go).

  • An npm-installed PiG is owned by the launcher package @pi-in-go/pig, not by the platform package (@pi-in-go/pig-linux-x64 and the other five) that holds the native binary. The update no longer uninstalls the platform package. This holds for npm's nested layout, yarn and bun's hoisted layout, and pnpm's virtual store.

  • The update-available notice pads every line by one column, as Pi does, shows a Changelog: line with the release page from the signed manifest, and renders a release note as a muted Markdown block. The package-updates notice pads its lines the same way.

  • A standalone pig update removes its <executable>.update.lock file when it ends, as Pi removes its lock, and keeps concurrent updates exclusive while it does.

  • The /model selector dispatches keys as Pi 0.87.1's model-selector.ts handleInput does. PageUp and PageDown no longer move the cursor, Shift+Tab and a literal tab no longer toggle the scope (only the tui.input.tab binding does), every key that is not bound to an action reapplies the search query and selects the first match, and a scope toggle selects the current model, or the first row when the current model is not in the new scope.

  • RPC export_html, /export, /share and /bug embed the Session's live system prompt and tools, as Pi's AgentSession.exportToHtml does (Pi 0.87.1 export-html/index.ts:267-268, agent-session.ts:3921). The export carries the system prompt that the transcript records, including a section that a before_agent_start handler added, and tool parameters appear in the order the schema declares them. CLI --export of a file is unchanged.

  • A provider that answers a whole response at once no longer lets the first message_start of an assistant message carry the finished message in RPC and JSON output. The stream forwarder now registers in the same continuation that creates the provider stream, as Pi's lazy.ts does, so a buffered response delivers its message_start, message_update and message_end events in Pi's order under load.

  • A Node extension command no longer ends the extension process when it returns or is cancelled while a host call is in flight. A command's return cancelled its outstanding host calls, and a cancelled host call that nothing awaited surfaced as an unhandled rejection that crashed Node. A host call now keeps its own context until it completes, a cancelled request's cancel is queued before its host calls are cancelled, and the runtime forgives only its own cancellation errors: any other unhandled rejection still ends the process, and an extension's own unhandledRejection listener runs first. Thanks to @sj0n for reporting this (#103).

  • A footer, header or string-list widget set through the Go, Rust or Python extension SDK no longer ends the session with Rendered line N exceeds terminal width (128 > 114) after the pane narrows. Pi renders a footer or header component at the current width on every frame (Pi 0.87.1 interactive-mode.ts:2418-2480) and lays a string[] widget out with Text(line, 1, 0) (interactive-mode.ts:2321-2336), so neither reaches the renderer over-wide. The SDKs now send the width each set of footer or header rows was laid out for, and the host paints rows only at that width. A string[] widget is sent without a width, and the host wraps it at its own width on every frame, with Pi's ten-row limit and muted ... (widget truncated) row. Thanks to Nick Deighton (@nickdeighton) for reporting this (#104).

  • Stop a Node extension from identifying PiG as Pi. An extension that called the bundled Pi SDK (createAgentSession) sent Pi's OpenRouter HTTP-Referer: https://pi.dev and X-OpenRouter-Title: pi, NVIDIA X-BILLING-INVOKE-ORIGIN: Pi, Cloudflare User-Agent: pi-coding-agent and OpenCode x-opencode-client: pi. The vendored Pi JavaScript now sends PiG's values, the same ones the Go host sends, from one shared file (D26). A guard test scans the bundled runtime for any remaining Pi identity literal.

  • Name PiG, not Pi, as the OpenAI Codex originator (requests, websocket and login URL), the xAI device-code referrer and the AI_AGENT marker child processes inherit.

  • Send the vendored Pi version check, model catalog overlay, install report and installer requests to PiG's own pi-in-go.dev, refuse the bug-report upload, and never send a Radius token to Radius's share gateway, as the Go host already does (D62, D64).

  • Classify lock-directory creation errors as Node's proper-lockfile does (only EEXIST is contention), read a lock directory that Windows is deleting as Node's fs.stat does, and record the mtime the lock heartbeat wrote, so auth, settings and update locks behave as Pi's do under load and on Windows.

  • pig piglet show --effective keeps local and inherited source paths, and revalidates the effective view. Thanks to @SamarthBoranna for reporting this and for the fix (#98, #99).

Added

  • Context.SetFooterRenderer/SetHeaderRenderer (Go), set_footer_renderer/set_header_renderer (Python and Rust) install a footer or header as a render(width) callback, the subprocess form of Pi's component factory. The SDK renders at the host's width on install and again after every resize, so the rows always match the pane. Rows set with SetFooter/SetHeader stay hidden after a resize until the extension sends rows for the new width (from OnWidthChange/on_width_change); use a renderer to follow resizes automatically (#104).

Thanks

  • @jkerdreux-imt: contributed the fullscreen Kitty keyboard fix (#105) and the theme color fix (#108), landed together in #109.
  • @nguyen-tran-100x: reported --exclude-tools being ignored in RPC mode (#101).
  • @sj0n: reported a Node extension command crashing its extension (#103).
  • @nickdeighton: reported the startup panic when an extension footer is wider than the terminal (#104).
  • @ShoichiTect: reported transport errors saying fetch failed where Pi says Connection error. or Request timed out. (#86).
  • @baggiiiie: reported pig config not exiting on Escape (#89) and contributed the fix (#90).
  • @SamarthBoranna: reported pig piglet show --effective rejecting local paths (#98) and contributed the fix (#99).

What's Changed

New Contributors

Full Changelog: v0.3.0...v0.3.1