@kingingwang/pi-darwin-arm64 1.0.0 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/CHANGELOG.md +104 -0
- package/bin/README.md +32 -7
- package/bin/docs/cli.md +17 -3
- package/bin/docs/codemode.md +7 -6
- package/bin/docs/extensions.md +5 -1
- package/bin/docs/keybindings.md +5 -5
- package/bin/docs/mcp.md +26 -2
- package/bin/docs/models.md +28 -2
- package/bin/docs/quickstart.md +16 -2
- package/bin/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/bin/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/bin/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/bin/examples/extensions/gondolin/package-lock.json +2 -2
- package/bin/examples/extensions/gondolin/package.json +1 -1
- package/bin/examples/extensions/sandbox/package-lock.json +2 -2
- package/bin/examples/extensions/sandbox/package.json +1 -1
- package/bin/examples/extensions/with-deps/package-lock.json +2 -2
- package/bin/examples/extensions/with-deps/package.json +1 -1
- package/bin/export-html/tool-renderer.d.ts +3 -3
- package/bin/export-html/tool-renderer.d.ts.map +1 -1
- package/bin/export-html/tool-renderer.js +3 -3
- package/bin/export-html/tool-renderer.js.map +1 -1
- package/bin/package.json +13 -14
- package/bin/pi +2 -2
- package/package.json +1 -1
package/bin/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,109 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.4] - 2026-10-05
|
|
4
|
+
|
|
5
|
+
### New Features
|
|
6
|
+
|
|
7
|
+
- **Tool patterns and `--no-mcp`**: `--tools` and `--exclude-tools` accept `*` patterns, for example `--tools read,codemode,'mcp__radius__*'` keeps only one MCP server's tools. `--tools` now keeps MCP tools unless an entry starts with `mcp__`, and `--no-mcp` turns off MCP for one run. See [Tools](docs/cli.md#tools) and [MCP tools](docs/cli.md#mcp-tools).
|
|
8
|
+
- **Codemode persists images**: `tools.read()` on an image file now gives back an image block that `image()` can show. See [Call tools](docs/codemode.md#call-tools).
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Added `*` patterns to `--tools` and `--exclude-tools`, for example `--tools read,codemode,'mcp__radius__*'`
|
|
13
|
+
- Added `--no-mcp` to disable the built-in MCP support for one run
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Fixed syntax highlighting losing colors after the first line of multiline strings and comments in fenced code blocks ([#10143](https://github.com/earendil-works/pi/issues/10143))
|
|
18
|
+
- Fixed codemode scripts not receiving images from `read`: `tools.read()` now resolves to an image block for image files, which `image()` shows ([#10251](https://github.com/earendil-works/pi/issues/10251))
|
|
19
|
+
- Fixed MCP OAuth sign-in failing with `invalid_redirect_uri` on servers with OpenID Connect client registration, such as `mcp.modem.dev`: pi now registers as a native client ([#10493](https://github.com/earendil-works/pi/issues/10493))
|
|
20
|
+
- Fixed `--tools` removing MCP tools, which left `pi --tools codemode` without any MCP servers. `--tools` now keeps MCP tools unless an entry starts with `mcp__`
|
|
21
|
+
- Fixed MCP session shutdown returning while a server was still connecting, leaving its transport open until the server answered or timed out ([#10249](https://github.com/earendil-works/pi/issues/10249))
|
|
22
|
+
- Fixed system prompt rules and the skills hint naming tools hidden by `prepareLoadout`. Hidden tools are left out of the rules, the skills hint names no tool when the file reader is hidden, and `codemode` shows each tool's prompt guidelines with its declaration; `ToolLoadout` gains `getPromptGuidelines()` ([#10343](https://github.com/earendil-works/pi/issues/10343))
|
|
23
|
+
- Fixed Bedrock requests that fail with `The pending stream has been canceled` after a stalled HTTP/2 connection not being retried automatically ([#10379](https://github.com/earendil-works/pi/issues/10379))
|
|
24
|
+
- Fixed codemode scripts that patch built-ins (for example `Array.prototype.toJSON = ...`) crashing pi and leaving the tool call unsettled. Built-ins are now frozen before the script runs, so such patches have no effect ([#10444](https://github.com/earendil-works/pi/issues/10444))
|
|
25
|
+
|
|
26
|
+
## [1.0.3] - 2026-10-05
|
|
27
|
+
|
|
28
|
+
### New Features
|
|
29
|
+
|
|
30
|
+
- **Azure Foundry Chat Completions** — The `azure` provider (renamed from `azure-openai-responses`) now also serves Foundry Chat Completions deployments, starting with `azure/deepseek-v4-pro`. See [Azure OpenAI](docs/providers.md#azure-openai).
|
|
31
|
+
- **Codemode images saved to files** — `image()` also writes each image to a temp file and names the path in the result, so later turns can copy or move generated images. See [Generate images](docs/codemode.md#generate-images).
|
|
32
|
+
|
|
33
|
+
### Breaking Changes
|
|
34
|
+
|
|
35
|
+
- Renamed the Azure provider from `azure-openai-responses` to `azure`. Rename the provider key in `auth.json` (or run `/login` again), in `models.json`, and in `settings.json` (`defaultProvider`, `enabledModels` patterns, and `modelThinkingLevels` keys). Sessions that used the old provider fall back to another model when resumed, and their prompt cache is not reused. The `AZURE_OPENAI_*` environment variables are unchanged ([#9714](https://github.com/earendil-works/pi/pull/9714) by [@jsanter27](https://github.com/jsanter27))
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
- Added Azure Foundry Chat Completions deployments, starting with `azure/deepseek-v4-pro` ([#9645](https://github.com/earendil-works/pi/issues/9645), [#9714](https://github.com/earendil-works/pi/pull/9714) by [@jsanter27](https://github.com/jsanter27))
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- Codemode `image()` now also saves each image to a temp file and names the path in the result, so later turns can copy or move generated images ([#10310](https://github.com/earendil-works/pi/issues/10310))
|
|
44
|
+
- Output files (full text of truncated tool output, binary MCP resources, codemode images) are now readable only by the user
|
|
45
|
+
- `Home`/`End` now always move the editor cursor to the line start/end; fullscreen transcript top/bottom moved to `Ctrl+Home`/`Ctrl+End`, which no longer move the editor cursor ([#10314](https://github.com/earendil-works/pi/issues/10314))
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
|
|
49
|
+
- Fixed subscription logins such as Sign in with ChatGPT failing with `refresh_token_invalidated` after a request was cancelled during an OAuth token refresh
|
|
50
|
+
- Fixed codemode failing for the rest of a session after a pnpm global update removed the running install, and added a restart hint when errors occur after pi was updated or removed on disk ([#10439](https://github.com/earendil-works/pi/issues/10439))
|
|
51
|
+
- Fixed interactive sessions reporting a `read EIO` or `setRawMode EIO` crash (and asking to run /bug) when the terminal went away, e.g. after closing the window or resuming a suspended pi in a closed terminal
|
|
52
|
+
|
|
53
|
+
## [1.0.2] - 2026-10-04
|
|
54
|
+
|
|
55
|
+
### New Features
|
|
56
|
+
|
|
57
|
+
- **Sampling by thinking level** — `samplingParamsByThinkingLevel` in `models.json` sets sampling parameters such as `temperature` and `top_p` for each thinking level on OpenAI-compatible APIs. See [Configure sampling by thinking level](docs/models.md#configure-sampling-by-thinking-level).
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
|
|
61
|
+
- Added `samplingParamsByThinkingLevel` to `models.json` for per-thinking-level sampling parameter overrides on OpenAI-compatible APIs. See [Configure sampling by thinking level](docs/models.md#configure-sampling-by-thinking-level) ([#9776](https://github.com/earendil-works/pi/pull/9776) by [@mrexodia](https://github.com/mrexodia))
|
|
62
|
+
|
|
63
|
+
## [1.0.1] - 2026-10-03
|
|
64
|
+
|
|
65
|
+
### New Features
|
|
66
|
+
|
|
67
|
+
- **Nix flake** — `nix run github:earendil-works/pi/stable` runs the latest release, and `nix profile add github:earendil-works/pi/stable` installs it. See [Install pi](docs/quickstart.md#1-install-pi).
|
|
68
|
+
- **Project overrides for MCP servers** — `.pi/mcp.json` and `/mcp` can enable, disable, or change the exposure of a user-level server for one project. See [Configure servers](docs/mcp.md#configure-servers).
|
|
69
|
+
- **MCP Client ID Metadata Documents** — `oauth.clientRegistration: "cimd"` lets authorization servers allow pi by its document URL instead of dynamic registration. See [Authenticate with OAuth](docs/mcp.md#authenticate-with-oauth).
|
|
70
|
+
- **Tool renderers for any tool** — `pi.registerToolRenderer()` draws calls to tools that are not registered yet, such as MCP tools in resumed sessions. See [Tool rendering](docs/extensions.md#tool-rendering).
|
|
71
|
+
- **Cloudflare Clef classifiers** — `@cf/cloudflare/clef` and `@cf/cloudflare/clef-flash` are usable from codemode scripts and extensions. See [Use classifier models](docs/models.md#use-classifier-models).
|
|
72
|
+
|
|
73
|
+
### Added
|
|
74
|
+
|
|
75
|
+
- Added a copy key (`app.message.copy`, default `ctrl+x`) to OAuth sign-in screens in `/login`, `/mcp`, and `/mcp login`, which copies the sign-in URL when the browser cannot be opened or the wrapped link cannot be selected.
|
|
76
|
+
- Added `oauth.clientRegistration: "cimd"` for MCP servers, which identifies pi with its Client ID Metadata Document on pi.dev instead of dynamic client registration, so authorization servers can allow pi by URL ([#10302](https://github.com/earendil-works/pi/issues/10302))
|
|
77
|
+
- Added project overrides for user-level MCP servers: a `.pi/mcp.json` entry without `command` or `url` sets only `enabled`, `exposure`, and `toolExposure` of the user-level server, and `/mcp` can enable or disable a server for the current project ([#10277](https://github.com/earendil-works/pi/issues/10277))
|
|
78
|
+
- Added Cloudflare's Clef and Clef Flash classifier models to `cloudflare-workers-ai`, usable from codemode scripts and extensions ([#10316](https://github.com/earendil-works/pi/pull/10316) by [@ndisidore](https://github.com/ndisidore), [#10322](https://github.com/earendil-works/pi/pull/10322) by [@RealAlexandreAI](https://github.com/RealAlexandreAI))
|
|
79
|
+
- Added `pi.registerToolRenderer()`, which chooses how calls to a tool are drawn, including tools that are not registered ([#10285](https://github.com/earendil-works/pi/issues/10285))
|
|
80
|
+
- Added a Nix flake for macOS and Linux: `nix run github:earendil-works/pi/stable` runs the latest release, and `nix profile add github:earendil-works/pi/stable` installs it. See [Install pi](docs/quickstart.md#1-install-pi) ([#9137](https://github.com/earendil-works/pi/pull/9137))
|
|
81
|
+
|
|
82
|
+
### Changed
|
|
83
|
+
|
|
84
|
+
- `pi update` on global npm installations now recommends migrating to the managed installation from the pi.dev installer, which pins all dependencies.
|
|
85
|
+
- Anthropic tools added or redefined mid-conversation are now defined inline in the conversation, so redefining a tool under the same name keeps the prompt cache instead of resending the full tool list.
|
|
86
|
+
|
|
87
|
+
### Fixed
|
|
88
|
+
|
|
89
|
+
- Fixed installations resolving vulnerable `brace-expansion` 5.0.9 by pinning `brace-expansion` 5.0.12 as a direct dependency (GHSA-q2hr-2g5m-vwhr, GHSA-qhr7-859c-m2p7, GHSA-6j4f-fj2g-mc7p) ([#10288](https://github.com/earendil-works/pi/issues/10288))
|
|
90
|
+
- Fixed a trailing comma in `--models` adding an extra model to the model cycle ([#10334](https://github.com/earendil-works/pi/issues/10334))
|
|
91
|
+
- Fixed a `codemode` script that prints in a loop crashing pi by running out of memory: a script fails once its output passes 16 Mi characters or 100000 items ([#10283](https://github.com/earendil-works/pi/issues/10283))
|
|
92
|
+
- Fixed JPEG, GIF, and WebP images rendered by extensions through `Image` not appearing in Kitty, Ghostty, WezTerm, and Warp ([#10292](https://github.com/earendil-works/pi/issues/10292))
|
|
93
|
+
- Fixed MCP tool calls in resumed sessions and HTML exports rendering fully expanded until their server connected, or for good if it never did ([#10285](https://github.com/earendil-works/pi/issues/10285))
|
|
94
|
+
- Fixed fullscreen Kitty images collapsing to a one-row strip after scrolling in WezTerm ([#10319](https://github.com/earendil-works/pi/issues/10319))
|
|
95
|
+
- Fixed "Selected model is at capacity" provider errors ending the turn instead of being retried ([#10278](https://github.com/earendil-works/pi/issues/10278))
|
|
96
|
+
- Fixed Cloudflare AI Gateway Claude models failing with a 404 by using dashed model IDs (`claude-opus-5-5` instead of `claude-opus-5.5`)
|
|
97
|
+
- Fixed Sign in with ChatGPT continuing when its callback port is taken by another login, which made the browser show "OAuth state mismatch"; it now fails with a port-in-use error ([#10265](https://github.com/earendil-works/pi/issues/10265))
|
|
98
|
+
- Fixed Amazon Bedrock OpenAI models costing requests above 272k input tokens at the short-context rate; Bedrock models now include the pricing tiers listed on models.dev ([#10326](https://github.com/earendil-works/pi/issues/10326))
|
|
99
|
+
- Fixed Amazon Bedrock Claude requests failing with "Invalid `signature` in `thinking` block" after the system prompt or tools changed ([#10324](https://github.com/earendil-works/pi/issues/10324))
|
|
100
|
+
- Fixed Together DeepSeek V4 Pro losing its thinking level controls after Together renamed it to `deepseek-ai/DeepSeek-V4-Pro-0813` ([#10336](https://github.com/earendil-works/pi/pull/10336) by [@cv](https://github.com/cv))
|
|
101
|
+
- Fixed the default NVIDIA model pointing at `nvidia/nemotron-3-super-120b-a12b`, which NVIDIA no longer serves; the default is now `nvidia/nemotron-3-ultra-550b-a55b`
|
|
102
|
+
|
|
103
|
+
### Removed
|
|
104
|
+
|
|
105
|
+
- Removed `npm-shrinkwrap.json` from the published package. npm installations no longer pin transitive dependencies, and library consumers can now override them. Use the pi.dev installer for pinned installations ([#5653](https://github.com/earendil-works/pi/issues/5653))
|
|
106
|
+
|
|
3
107
|
## [1.0.0] - 2026-10-01
|
|
4
108
|
|
|
5
109
|
### New Features
|
package/bin/README.md
CHANGED
|
@@ -12,26 +12,38 @@
|
|
|
12
12
|
|
|
13
13
|
# Pi
|
|
14
14
|
|
|
15
|
-
Pi is a minimal, extensible
|
|
15
|
+
Pi is a minimal, extensible agent harness that you can make your own.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Adapt Pi to your workflows, not the other way around. Customize Pi with [extensions](docs/extensions.md), [skills](docs/skills.md), [prompt templates](docs/prompt-templates.md), and [themes](docs/themes.md). Bundle them as [Pi packages](docs/packages.md) and share via npm or git.
|
|
18
|
+
|
|
19
|
+
Pi ships with powerful defaults but skips features like sub-agents and plan mode. Ask Pi to build what you want, or install a package that does it your way.
|
|
20
|
+
|
|
21
|
+
Use Pi [interactively](docs/usage.md), automate it in [print or JSON mode](docs/cli.md), control it over [RPC](docs/rpc.md), or build apps with the [Pi TypeScript SDK](docs/sdk.md). See [OpenClaw](https://github.com/OpenClaw/OpenClaw) for a real-world integration.
|
|
18
22
|
|
|
19
23
|
## Getting started
|
|
20
24
|
|
|
21
|
-
Install the command-line interface
|
|
25
|
+
Install the command-line interface:
|
|
22
26
|
|
|
23
27
|
```bash
|
|
24
|
-
|
|
28
|
+
curl -fsSL https://pi.dev/install.sh | sh
|
|
25
29
|
```
|
|
26
30
|
|
|
27
|
-
|
|
31
|
+
On Windows:
|
|
28
32
|
|
|
29
|
-
|
|
33
|
+
```shell
|
|
34
|
+
powershell -c "irm https://pi.dev/install.ps1 | iex"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The installer pins all dependencies and updates Pi with `pi update`. Alternatively, install directly with npm, which does not pin transitive dependencies:
|
|
30
38
|
|
|
31
39
|
```bash
|
|
32
|
-
|
|
40
|
+
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
|
|
33
41
|
```
|
|
34
42
|
|
|
43
|
+
Pi requires Node.js 22.19 or newer. The macOS, Linux, and Windows installers can install it if needed. Pi does not require dependency lifecycle scripts for a normal npm installation.
|
|
44
|
+
|
|
45
|
+
On macOS and Linux, Nix users can install the latest release with `nix profile add github:earendil-works/pi/stable`. See the [quickstart](docs/quickstart.md#1-install-pi) for updating and pinning releases.
|
|
46
|
+
|
|
35
47
|
Start Pi in the directory where you want it to work:
|
|
36
48
|
|
|
37
49
|
```bash
|
|
@@ -43,6 +55,19 @@ For a built-in AI provider, run `/login` inside Pi to connect a subscription or
|
|
|
43
55
|
|
|
44
56
|
See the [documentation](docs/index.md) for full setup and usage instructions.
|
|
45
57
|
|
|
58
|
+
## Share your OSS coding agent sessions
|
|
59
|
+
|
|
60
|
+
If you use Pi for open source work, please share your coding agent sessions.
|
|
61
|
+
|
|
62
|
+
Public OSS session data helps improve models, prompts, tools, and evaluations using real development workflows.
|
|
63
|
+
|
|
64
|
+
For the full explanation, see [this post on X](https://x.com/badlogicgames/status/2037811643774652911).
|
|
65
|
+
|
|
66
|
+
To publish sessions, use [`badlogic/pi-share-hf`](https://github.com/badlogic/pi-share-hf) using a Hugging Face account and the Hugging Face CLI.
|
|
67
|
+
|
|
68
|
+
- [Demo video](https://x.com/badlogicgames/status/2041151967695634619) on how to publish Pi sessions
|
|
69
|
+
- Published Pi development sessions: [`badlogicgames/pi-mono` on Hugging Face](https://huggingface.co/datasets/badlogicgames/pi-mono).
|
|
70
|
+
|
|
46
71
|
## Development
|
|
47
72
|
|
|
48
73
|
Clone the repository, install its dependencies, and run Pi from source:
|
package/bin/docs/cli.md
CHANGED
|
@@ -117,16 +117,26 @@ pi --tools read,grep,find,ls --print "Review this project"
|
|
|
117
117
|
See [Settings](settings.md#tools) for configuring the default tool selection.
|
|
118
118
|
|
|
119
119
|
- `-t`, `--tools <list>`<br>
|
|
120
|
-
Replaces the default selection with a comma-separated allowlist of built-in, extension, or custom tools.
|
|
120
|
+
Replaces the default selection with a comma-separated allowlist of built-in, extension, or custom tools. Entries are tool names or patterns where `*` matches any characters. MCP tools are kept unless an entry starts with `mcp__` (see [MCP tools](#mcp-tools)).
|
|
121
121
|
- `-xt`, `--exclude-tools <list>`<br>
|
|
122
|
-
Disables comma-separated tool names after all other selection options.
|
|
122
|
+
Disables comma-separated tool names or patterns after all other selection options, MCP tools included.
|
|
123
123
|
- `-nbt`, `--no-builtin-tools`<br>
|
|
124
124
|
Disables default built-in tools while retaining extension and custom tools.
|
|
125
125
|
- `-nt`, `--no-tools`<br>
|
|
126
|
-
Starts with all built-in, extension, and
|
|
126
|
+
Starts with all built-in, extension, custom, and MCP tools disabled.
|
|
127
127
|
|
|
128
128
|
Default enabled tools are `read`, `bash`, `edit`, and `write`, unless `defaultTools` changes them. `--tools` replaces the whole selection, so name every tool you want; `defaultTools` also accepts `+name` and `-name` to change the defaults instead.
|
|
129
129
|
|
|
130
|
+
<a id="mcp-tools"></a>
|
|
131
|
+
|
|
132
|
+
`--tools` selects the tools declared to the model. It does not remove MCP tools, whose reach is set by their [exposure](mcp.md#control-tool-exposure): `pi --tools read,codemode` keeps every MCP tool callable from codemode scripts. An MCP tool that no entry names or matches is never declared directly, whatever its exposure; only `tool_search`, if listed, can load it. Once an entry starts with `mcp__`, `--tools` filters MCP tools too, so this keeps only the tools of the `radius` server:
|
|
133
|
+
|
|
134
|
+
```sh
|
|
135
|
+
pi --tools read,bash,codemode,'mcp__radius__*'
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The MCP resource tools (`list_mcp_resources`, `list_mcp_resource_templates`, `read_mcp_resource`) count as MCP tools. To remove MCP tools, use `--exclude-tools 'mcp__*'` or [`--no-mcp`](#resource-options).
|
|
139
|
+
|
|
130
140
|
| Built-in | Purpose |
|
|
131
141
|
|---|---|
|
|
132
142
|
| `read` | Read text files and supported images |
|
|
@@ -185,6 +195,8 @@ See [Configuration](configuration.md) for conventional directories and project t
|
|
|
185
195
|
Loads an extension file or directory, or a built-in extension such as `builtin:mcp`, and is repeatable.
|
|
186
196
|
- `-ne`, `--no-extensions`<br>
|
|
187
197
|
Disables discovered, configured, and built-in extensions. Explicit `-e` paths still load, so `pi -ne -e builtin:mcp` keeps only the built-in MCP support.
|
|
198
|
+
- `--no-mcp`<br>
|
|
199
|
+
Disables the built-in MCP support for this run: no servers connect, and there are no MCP tools or `/mcp`. It does not affect an extension that replaces the built-in MCP support.
|
|
188
200
|
- `--skill <path>`<br>
|
|
189
201
|
Loads a skill file or directory and is repeatable.
|
|
190
202
|
- `-ns`, `--no-skills`<br>
|
|
@@ -268,6 +280,8 @@ Running `pi update` without a target updates Pi itself.
|
|
|
268
280
|
|
|
269
281
|
Add `--force` to reinstall Pi when the selected update includes Pi.
|
|
270
282
|
|
|
283
|
+
`pi update` cannot update Pi when another package manager provides it, such as Nix. Update Pi with that package manager, for example `nix profile upgrade pi`. Package and model catalog updates still work.
|
|
284
|
+
|
|
271
285
|
### Aliases and command options
|
|
272
286
|
|
|
273
287
|
- `pi uninstall <source>` is an alias for `pi remove <source>`.
|
package/bin/docs/codemode.md
CHANGED
|
@@ -12,7 +12,7 @@ A script may start with an options line:
|
|
|
12
12
|
// @options: {"max_output_tokens": 2000, "timeout_ms": 60000}
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
- `max_output_tokens` (default 10000) limits the output. Longer output keeps its start and end, and the full text is written to a temp file whose path is included in the result.
|
|
15
|
+
- `max_output_tokens` (default 10000) limits the output. Longer output keeps its start and end, and the full text is written to a temp file whose path is included in the result. A script fails when its output passes 16777216 characters of text and base64 image data or 100000 `text()`, `image()`, and `console` calls; write large data to a file with a tool instead.
|
|
16
16
|
- `timeout_ms` is a hard deadline for the whole script. It is unset by default. Image generation can take minutes, so do not set a short deadline for scripts that generate images.
|
|
17
17
|
|
|
18
18
|
The result starts with `Script completed` or `Script failed`, the wall time, and the output. A failed script keeps its partial output, followed by `Script error:` and the error. Tool calls are real: calls made before a failure are not undone. Calls still running when the script ends are cancelled, and unawaited promises are discarded.
|
|
@@ -23,7 +23,7 @@ The result starts with `Script completed` or `Script failed`, the wall time, and
|
|
|
23
23
|
|---|---|
|
|
24
24
|
| `tools.<name>(args)` | Call a tool. See [Call tools](#call-tools). |
|
|
25
25
|
| `text(value)` | Add a text item to the output. Strings are added as is, other values as JSON. |
|
|
26
|
-
| `image(value)` | Add an image to the output: a base64 `data:` URL, an `{ image_url }` object, or an image block `{ type: "image", data, mimeType }` such as those returned by MCP tools and `models.generateImages()`. Remote URLs are not supported. PNG, JPEG, GIF, and WebP are accepted. |
|
|
26
|
+
| `image(value)` | Add an image to the output: a base64 `data:` URL, an `{ image_url }` object, or an image block `{ type: "image", data, mimeType }` such as those returned by MCP tools and `models.generateImages()`. Remote URLs are not supported. PNG, JPEG, GIF, and WebP are accepted. Each image is also saved to a temp file, and the result names the path before the image. |
|
|
27
27
|
| `console.log(...)` | Like `text()`; `info`, `warn`, `error`, and `debug` do the same. |
|
|
28
28
|
| `return value` | A top-level `return` adds the value like `text()`. |
|
|
29
29
|
| `exit()` | End the script successfully. |
|
|
@@ -42,19 +42,20 @@ What a call resolves to depends on the tool:
|
|
|
42
42
|
|
|
43
43
|
- Tools with an output schema resolve to a structured value. `bash` resolves to `{ output, truncated, full_output_path?, exit_code, wall_time_seconds }`, also for non-zero exit codes. Its `output` is not limited to the 2000 lines or 50KB the model sees: it holds up to 1 MiB, and longer output keeps its first and last 512 KiB around an omission marker, with `truncated` set and the full output in `full_output_path`.
|
|
44
44
|
- MCP tools resolve to their `CallToolResult`, including `isError` and `structuredContent`.
|
|
45
|
-
-
|
|
45
|
+
- `read` resolves to the file's text, or for an image to an image block `{ type: "image", data, mimeType, note }` that `image()` shows. `data` is the base64 image the model would see and `note` the text that goes with it, such as resize hints.
|
|
46
|
+
- Other tools, such as `edit` and `write`, resolve to their text output.
|
|
46
47
|
|
|
47
48
|
A call that fails, is blocked, or gets invalid arguments rejects with an `Error` that carries the tool's error text. Use `Promise.allSettled()` to keep the results of the calls that succeed.
|
|
48
49
|
|
|
49
50
|
The `codemode` description lists tools with their TypeScript declarations, grouped by namespace (for example one MCP server). Tools with `deferred` exposure, which includes MCP tools with the default `codemode` exposure, are not listed, so the description stays the same while MCP servers connect. Listed declarations share a budget of 3000 estimated tokens (`codemode.inlineBudget` in [settings](settings.md#tools)). Scripts find the other tools with `searchTools()`, `describeTool()`, `describeNamespace()`, or by filtering `ALL_TOOLS`.
|
|
50
51
|
|
|
51
|
-
While `codemode` is active, `codemode.mode` in [settings](settings.md#tools) decides how the other tools are presented. With `on` (default) declared tools stay declared, and their descriptions say how to call them from scripts. With `only` they are hidden from the model and listed in the `codemode` description instead, so the model calls them through scripts.
|
|
52
|
+
While `codemode` is active, `codemode.mode` in [settings](settings.md#tools) decides how the other tools are presented. With `on` (default) declared tools stay declared, and their descriptions say how to call them from scripts. With `only` they are hidden from the model and listed in the `codemode` description instead, so the model calls them through scripts. Tool declarations in the `codemode` description, `describeTool()`, and `ALL_TOOLS` carry the tools' prompt guidelines, since the system prompt rules only cover declared tools.
|
|
52
53
|
|
|
53
54
|
## Store values
|
|
54
55
|
|
|
55
56
|
`store(key, value)` keeps a JSON value under a string key for later `codemode` calls; storing `undefined` deletes the key. `load(key)` returns the value, or `undefined`. Writes are kept only when the script succeeds: each successful script that stores values appends a `codemode-store` custom entry to the session, so resumed sessions keep the values and each branch sees only the values written on its path.
|
|
56
57
|
|
|
57
|
-
The store is for small state such as IDs, cursors, or summaries. One value may have at most 262144 characters of JSON and all values together at most 1048576. Do not store image data; show images with `image()
|
|
58
|
+
The store is for small state such as IDs, cursors, or summaries. One value may have at most 262144 characters of JSON and all values together at most 1048576. Do not store image data; show images with `image()`, which also saves them to a temp file.
|
|
58
59
|
|
|
59
60
|
## Models
|
|
60
61
|
|
|
@@ -185,7 +186,7 @@ type TextBlock = { type: "text"; text: string };
|
|
|
185
186
|
type ImageBlock = { type: "image"; data: string; mimeType: string };
|
|
186
187
|
```
|
|
187
188
|
|
|
188
|
-
Show generated images with `image(block)`. Do not print `data` with `text()`, `console`, or `return`: it is large and the model cannot read it as text.
|
|
189
|
+
Show generated images with `image(block)`. Do not print `data` with `text()`, `console`, or `return`: it is large and the model cannot read it as text. `image()` also saves each image to a temp file and puts its path in the result, so a later turn can copy or move the file.
|
|
189
190
|
|
|
190
191
|
```js
|
|
191
192
|
// @options: {"timeout_ms": 300000}
|
package/bin/docs/extensions.md
CHANGED
|
@@ -177,7 +177,7 @@ pi.on("tool_call", async (event, ctx) => {
|
|
|
177
177
|
});
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
-
A tool that orchestrates other tools can adjust what the model sees while it is active with `prepareLoadout(loadout)`. It runs whenever the active tools change and receives the declared tools, the callable tools, and every registered tool with its exposure and
|
|
180
|
+
A tool that orchestrates other tools can adjust what the model sees while it is active with `prepareLoadout(loadout)`. It runs whenever the active tools change and receives the declared tools, the callable tools, and every registered tool with its exposure, namespace, and prompt guidelines. It returns replacement `descriptions` for declared tools (including its own) and `hiddenDeclarations`: active tools whose declarations requests leave out while they stay active and callable. The default system prompt leaves hidden tools out of its tool list and rules, and names no tool in the skills hint when the file reader is hidden, so the orchestrating tool should present their guidelines itself. `codemode` uses only this hook, `exposure`, and `ctx.executeTool()`, so another tool can implement the same behavior under a different name.
|
|
181
181
|
|
|
182
182
|
### Activate tools dynamically
|
|
183
183
|
|
|
@@ -185,6 +185,10 @@ Register every tool first, keep optional tools inactive, and use `pi.setActiveTo
|
|
|
185
185
|
|
|
186
186
|
Pi records the initial prompt and tool set in the transcript's first system message, then appends tool and prompt changes before the next model request. Providers that cannot represent the transition receive a complete transcript checkpoint, which can invalidate the cached prefix.
|
|
187
187
|
|
|
188
|
+
### Tool rendering
|
|
189
|
+
|
|
190
|
+
A tool's `renderCall` and `renderResult` draw its calls in the interactive transcript and in HTML exports. `pi.registerToolRenderer((toolName, next) => renderers)` chooses renderers for calls to any tool, including tools that are not registered yet, such as MCP tools in a resumed session before their server connected. `next()` returns what the remaining resolvers (in extension load order), then the registered tool, would use, so `next() ?? mine` only fills in.
|
|
191
|
+
|
|
188
192
|
### MCP servers
|
|
189
193
|
|
|
190
194
|
`pi.registerMcpServer(name, config)` adds an MCP server for the current session. `config` has the shape of an `mcpServers` entry in [`mcp.json`](mcp.md): `command`, `args`, `env`, and `cwd` for stdio servers, `url`, `headers`, and `oauth` for HTTP servers, plus `exposure`, `toolExposure`, `description`, `enabled`, and `timeout`.
|
package/bin/docs/keybindings.md
CHANGED
|
@@ -57,8 +57,8 @@ Examples: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, `super+k`, `ctrl+sup
|
|
|
57
57
|
| `tui.editor.cursorRight` | `right`, `ctrl+f` | Move cursor right |
|
|
58
58
|
| `tui.editor.cursorWordLeft` | `alt+left`, `ctrl+left`, `alt+b` | Move cursor word left |
|
|
59
59
|
| `tui.editor.cursorWordRight` | `alt+right`, `ctrl+right`, `alt+f` | Move cursor word right |
|
|
60
|
-
| `tui.editor.cursorLineStart` | `home`, `ctrl+
|
|
61
|
-
| `tui.editor.cursorLineEnd` | `end`, `ctrl+
|
|
60
|
+
| `tui.editor.cursorLineStart` | `home`, `ctrl+a` | Move to line start |
|
|
61
|
+
| `tui.editor.cursorLineEnd` | `end`, `ctrl+e` | Move to line end |
|
|
62
62
|
| `tui.editor.jumpForward` | `ctrl+]` | Jump forward to character |
|
|
63
63
|
| `tui.editor.jumpBackward` | `ctrl+alt+]` | Jump backward to character |
|
|
64
64
|
| `tui.editor.pageUp` | `pageUp`, `ctrl+pageUp` | Scroll up by page |
|
|
@@ -113,8 +113,8 @@ In fullscreen mode, these actions control the transcript and take precedence ove
|
|
|
113
113
|
| `tui.altScreen.searchNext` | `enter`, `ctrl+g` | Select the next search match while searching |
|
|
114
114
|
| `tui.altScreen.searchPrevious` | `shift+enter`, `ctrl+shift+g` | Select the previous search match while searching |
|
|
115
115
|
| `tui.altScreen.searchClose` | `escape` | Close transcript search |
|
|
116
|
-
| `tui.altScreen.top` | `home` | Scroll to the beginning of the transcript |
|
|
117
|
-
| `tui.altScreen.bottom` | `end` | Scroll to the transcript end and follow new output |
|
|
116
|
+
| `tui.altScreen.top` | `ctrl+home` | Scroll to the beginning of the transcript |
|
|
117
|
+
| `tui.altScreen.bottom` | `ctrl+end` | Scroll to the transcript end and follow new output |
|
|
118
118
|
|
|
119
119
|
### Application
|
|
120
120
|
|
|
@@ -161,7 +161,7 @@ On native Windows, `app.suspend` has no default because Windows terminals do not
|
|
|
161
161
|
| Keybinding id | Default | Description |
|
|
162
162
|
|--------|---------|-------------|
|
|
163
163
|
| `app.tools.expand` | `ctrl+o` | Collapse or expand tool output |
|
|
164
|
-
| `app.message.copy` | `ctrl+x` | Copy the selected message in `/tree`; in fullscreen mode, copy the active selection when `fullscreenCopyOnSelect` is `false`; otherwise copy the last assistant message |
|
|
164
|
+
| `app.message.copy` | `ctrl+x` | Copy the selected message in `/tree`; in fullscreen mode, copy the active selection when `fullscreenCopyOnSelect` is `false`; otherwise copy the last assistant message. On OAuth sign-in screens, copy the sign-in URL |
|
|
165
165
|
| `app.message.followUp` | `alt+enter` (`ctrl+q` on Windows and WSL) | Queue follow-up message |
|
|
166
166
|
| `app.message.dequeue` | `alt+up` (`alt+q` on Windows and WSL) | Restore queued messages to editor |
|
|
167
167
|
|
package/bin/docs/mcp.md
CHANGED
|
@@ -31,6 +31,16 @@ Use `/mcp` inside an interactive session to inspect connections, sign in, reconn
|
|
|
31
31
|
|
|
32
32
|
Pi reads user-level servers from `~/.pi/agent/mcp.json` and project servers from `.pi/mcp.json`. Project configuration is read only after [project trust](security.md#understand-project-trust) is granted. A project entry replaces a user-level entry with the same name.
|
|
33
33
|
|
|
34
|
+
A project entry without `command`, `url`, or `type` overrides only `enabled`, `exposure`, and `toolExposure` of the user-level server with the same name and keeps the rest, including `env`, `headers`, and `auth`. For example, this turns off a user-level server in one project:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"mcpServers": {
|
|
39
|
+
"internal-tools": { "enabled": false }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
34
44
|
The format matches other MCP clients:
|
|
35
45
|
|
|
36
46
|
```json
|
|
@@ -77,7 +87,7 @@ Keep personal servers and servers with credentials in the user-level file. Use t
|
|
|
77
87
|
|
|
78
88
|
`/mcp` lists configured servers with their state, tool count, exposure, and configuration source. Servers that need attention appear first. Select a server to inspect its tools and connection details, reconnect, sign in or out, change exposure, or enable and disable it.
|
|
79
89
|
|
|
80
|
-
Exposure and enabled-state changes are saved to the file that defines the server without replacing unrelated content. Disabled servers remain listed. Outside the interactive TUI, `/mcp` prints server status; `/mcp login <server>`, `/mcp logout <server>`, and `/mcp reconnect <server>` perform those actions directly.
|
|
90
|
+
Exposure and enabled-state changes are saved to the file that defines the server without replacing unrelated content. In a trusted project, "Enable in this project" and "Disable in this project" add a project override for a user-level server; later changes to that server are saved to the override. Disabled servers remain listed. Outside the interactive TUI, `/mcp` prints server status; `/mcp login <server>`, `/mcp logout <server>`, and `/mcp reconnect <server>` perform those actions directly.
|
|
81
91
|
|
|
82
92
|
Shell commands work without a session: `pi mcp add`, `pi mcp remove`, `pi mcp list`, `pi mcp login`, and `pi mcp logout`. Shell commands do not load extensions.
|
|
83
93
|
|
|
@@ -149,6 +159,18 @@ Pi registers as `pi`. Some servers only accept registrations from known clients.
|
|
|
149
159
|
|
|
150
160
|
The name is only sent when Pi registers a client. To register again under a new name, sign out first.
|
|
151
161
|
|
|
162
|
+
Some authorization servers allow clients by their Client ID Metadata Document URL instead of registering them. Set `clientRegistration` to `cimd` to identify as Pi's document on pi.dev instead of registering:
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"mcpServers": {
|
|
167
|
+
"example": { "url": "https://mcp.example.com/mcp", "oauth": { "clientRegistration": "cimd" } }
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The client ID is `https://pi.dev/oauth/client.json` with the redirect URI `http://127.0.0.1:<port>/callback`. If the authorization server does not send the `iss` parameter in authorization responses (RFC 9207), Pi uses a document and redirect path specific to the MCP server instead: `https://pi.dev/oauth/<id>/client.json` with `http://127.0.0.1:<port>/callback/<id>`. The authorization server must advertise Client ID Metadata Document support and public clients, or sign-in fails. `cimd` cannot be combined with `clientId` or `clientName`, and a `callbackUrl` must use `localhost` or `127.0.0.1` with the path `/callback`.
|
|
173
|
+
|
|
152
174
|
Pi finds the authorization server through the server's protected resource metadata (RFC 9728) and checks that the authorization server's metadata names the expected issuer (RFC 8414). Some servers advertise the wrong authorization server or none, so sign-in opens a page that does not exist. Set `authServerMetadataUrl` to the metadata document of the right authorization server:
|
|
153
175
|
|
|
154
176
|
```json
|
|
@@ -203,6 +225,8 @@ Pi activates `codemode` when a server with `codemode` exposure connects. It acti
|
|
|
203
225
|
|
|
204
226
|
Tools with `codemode` or `deferred` exposure can be reached through either indirect mechanism: codemode scripts can call them, and `tool_search` can load them. Codemode calls do not depend on the active tool set, so they remain available after `/tree`, resume, and fork. Tools loaded by `tool_search` are recorded in the transcript and remain declared on that branch.
|
|
205
227
|
|
|
228
|
+
`--tools` does not remove MCP tools unless one of its entries starts with `mcp__`; `pi --tools read,codemode,'mcp__radius__*'` keeps only the tools of `radius`. `--exclude-tools` accepts the same patterns, and `--no-mcp` disables MCP for one run (see [Tools](cli.md#mcp-tools)).
|
|
229
|
+
|
|
206
230
|
To keep `codemode` active without MCP servers, add `"defaultTools": ["+codemode"]` to [settings](settings.md#tools). To prevent automatic codemode activation, set `"autoEnableCodemode": false` beside `mcpServers`. A project value overrides the user-level value. Pi warns once when neither `codemode` nor `tool_search` is active and non-direct tools cannot be called.
|
|
207
231
|
|
|
208
232
|
Text results over 20 KB reach the model with their middle removed around a `…N chars truncated…` marker. The full text is saved to a temporary file named in the result. Codemode scripts receive the complete result and can reduce it before returning output to the model.
|
|
@@ -239,7 +263,7 @@ Changes to enabled state or exposure apply only to the current session. A file-c
|
|
|
239
263
|
|
|
240
264
|
### Replace the built-in MCP support
|
|
241
265
|
|
|
242
|
-
An installed extension that registers `/mcp`, such as `pi-mcp-adapter`, replaces the built-in MCP support for sessions. Pi then does not read `mcp.json` or connect its servers in a session, and `/mcp` belongs to the extension. Remove the extension to restore the built-in behavior. To disable built-in MCP support without a replacement, disable `mcp` under Built-in in `pi config`, or set `"extensions": ["-builtin:mcp"]` in [settings](settings.md#resources).
|
|
266
|
+
An installed extension that registers `/mcp`, such as `pi-mcp-adapter`, replaces the built-in MCP support for sessions. Pi then does not read `mcp.json` or connect its servers in a session, and `/mcp` belongs to the extension. Remove the extension to restore the built-in behavior. To disable built-in MCP support without a replacement, disable `mcp` under Built-in in `pi config`, or set `"extensions": ["-builtin:mcp"]` in [settings](settings.md#resources). `--no-mcp` disables it for one run.
|
|
243
267
|
|
|
244
268
|
An extension that registers `codemode` or `tool_search` similarly replaces the built-in tool with that name. Shell-level `pi mcp` commands always use the built-in implementation.
|
|
245
269
|
|
package/bin/docs/models.md
CHANGED
|
@@ -98,17 +98,43 @@ Use `promptCache` to declare the provider's best-effort cache lifetime in second
|
|
|
98
98
|
|
|
99
99
|
Choose the conservative end of any published range. A model without a lifetime for the active tier is not eligible for cache warming. A `modelOverrides` entry can set `inputLimits` or `promptCache` for a built-in or extension model, including a model accessed through a validated proxy. See [`cacheWarming`](settings.md#model-and-thinking).
|
|
100
100
|
|
|
101
|
+
### Configure sampling by thinking level
|
|
102
|
+
|
|
103
|
+
OpenAI-compatible APIs support free-form `samplingParams` model defaults and `samplingParamsByThinkingLevel` overrides. The latter uses Pi thinking-level keys (`off`, `minimal`, `low`, `medium`, `high`, `xhigh`, and `max`), not provider values from `thinkingLevelMap`:
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"id": "qwen-thinking-model",
|
|
108
|
+
"reasoning": true,
|
|
109
|
+
"samplingParams": {
|
|
110
|
+
"temperature": 1.0,
|
|
111
|
+
"top_p": 0.95
|
|
112
|
+
},
|
|
113
|
+
"samplingParamsByThinkingLevel": {
|
|
114
|
+
"off": {
|
|
115
|
+
"temperature": 0.7,
|
|
116
|
+
"top_p": 0.8
|
|
117
|
+
},
|
|
118
|
+
"high": {
|
|
119
|
+
"top_k": 20
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Pi first clamps unsupported thinking levels, then merges model `samplingParams`, the effective level's override, and request-level `samplingParams` in that order. Later values win per key. Missing levels inherit the model defaults. `modelOverrides` merges per-level entries per key with the base model. These fields apply only to `openai-completions`, `openai-responses`, and `azure-openai-responses`; other APIs ignore them.
|
|
126
|
+
|
|
101
127
|
Compatibility settings should describe verified differences in the endpoint's request or response behavior. Do not enable them based only on an endpoint advertising OpenAI or Anthropic compatibility.
|
|
102
128
|
|
|
103
129
|
## Use classifier models
|
|
104
130
|
|
|
105
|
-
Classifier models do not chat. They answer typed questions about JSON state: pick one of several choices, answer yes or no, or give a score, each with probabilities. Pi includes TypeSafe's Jev model from these providers:
|
|
131
|
+
Classifier models do not chat. They answer typed questions about JSON state: pick one of several choices, answer yes or no, or give a score, each with probabilities. Pi includes TypeSafe's Jev model from these providers, and Cloudflare's Clef and Clef Flash models from Workers AI:
|
|
106
132
|
|
|
107
133
|
| Provider | Model IDs | Authentication |
|
|
108
134
|
|---|---|---|
|
|
109
135
|
| `typesafe` | `jev-latest` | `TYPESAFE_API_KEY` |
|
|
110
136
|
| `openrouter` | `typesafe/jev-1.13`, `~typesafe/jev-latest` | `OPENROUTER_API_KEY` or `/login` |
|
|
111
|
-
| `cloudflare-workers-ai` | `typesafe/jev` | `CLOUDFLARE_API_KEY` and `CLOUDFLARE_ACCOUNT_ID` |
|
|
137
|
+
| `cloudflare-workers-ai` | `typesafe/jev`, `@cf/cloudflare/clef`, `@cf/cloudflare/clef-flash` | `CLOUDFLARE_API_KEY` and `CLOUDFLARE_ACCOUNT_ID` |
|
|
112
138
|
| `vercel-ai-gateway` | `typesafe-ai/jev` | `AI_GATEWAY_API_KEY` |
|
|
113
139
|
| `opencode` | `jev-1.13`, `jev-1.13-free` | `OPENCODE_API_KEY` |
|
|
114
140
|
|
package/bin/docs/quickstart.md
CHANGED
|
@@ -12,7 +12,7 @@ On macOS or Linux, you can use the installer:
|
|
|
12
12
|
curl -fsSL https://pi.dev/install.sh | sh
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
Alternatively, install Pi from npm. This requires Node.js 22.19 or newer:
|
|
15
|
+
The installer pins all dependencies and updates Pi with `pi update`. Alternatively, install Pi from npm, which does not pin transitive dependencies. This requires Node.js 22.19 or newer:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
|
|
@@ -20,6 +20,14 @@ npm install -g --ignore-scripts @earendil-works/pi-coding-agent
|
|
|
20
20
|
|
|
21
21
|
Pi does not require dependency lifecycle scripts for a normal npm installation.
|
|
22
22
|
|
|
23
|
+
With Nix on macOS or Linux, install the latest release from Pi's flake. Nix builds Pi from source:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
nix profile add github:earendil-works/pi/stable
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Older Nix versions use `nix profile install` instead. Update with `nix profile upgrade pi`; `pi update` cannot update a Nix installation. To pin a release, use a tag such as `github:earendil-works/pi/v1.0.0`.
|
|
30
|
+
|
|
23
31
|
Verify the installation:
|
|
24
32
|
|
|
25
33
|
```bash
|
|
@@ -119,4 +127,10 @@ If you used the installer, run it again and choose **Uninstall Pi**:
|
|
|
119
127
|
curl -fsSL https://pi.dev/install.sh | sh
|
|
120
128
|
```
|
|
121
129
|
|
|
122
|
-
|
|
130
|
+
If you installed Pi with Nix, run:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
nix profile remove pi
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
None of these methods removes configuration, credentials, sessions, or installed Pi packages from `~/.pi/agent/`.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-custom-provider",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-custom-provider",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.4",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.52.0"
|
|
12
12
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-gondolin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-gondolin",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.4",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@earendil-works/gondolin": "0.12.0"
|
|
12
12
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-sandbox",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-sandbox",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.4",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sandbox-runtime": "^0.0.26"
|
|
12
12
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-with-deps",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-with-deps",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.4",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"ms": "^2.1.3"
|
|
12
12
|
},
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* and converting the ANSI output to HTML.
|
|
6
6
|
*/
|
|
7
7
|
import type { Theme } from "../../modes/interactive/theme/theme.ts";
|
|
8
|
-
import type {
|
|
8
|
+
import type { ToolRenderers } from "../extensions/types.ts";
|
|
9
9
|
export interface ToolHtmlRendererDeps {
|
|
10
|
-
/**
|
|
11
|
-
|
|
10
|
+
/** Renderers of calls to a tool, as resolved by extensions and the registered tool */
|
|
11
|
+
getToolRenderers: (name: string) => ToolRenderers | undefined;
|
|
12
12
|
/** Theme for styling */
|
|
13
13
|
theme: Theme;
|
|
14
14
|
/** Working directory for render context */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-renderer.d.ts","sourceRoot":"","sources":["../../../src/core/export-html/tool-renderer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"tool-renderer.d.ts","sourceRoot":"","sources":["../../../src/core/export-html/tool-renderer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,KAAK,EAAqB,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAG/E,MAAM,WAAW,oBAAoB;IACpC,sFAAsF;IACtF,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC;IAC9D,wBAAwB;IACxB,KAAK,EAAE,KAAK,CAAC;IACb,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAChC,oFAAoF;IACpF,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACpF,yGAAyG;IACzG,YAAY,CACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAChF,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,GACd;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CACzD;AAsBD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,GAAG,gBAAgB,CAkHnF"}
|
|
@@ -25,7 +25,7 @@ function trimRenderedResultLines(lines) {
|
|
|
25
25
|
return lines.slice(start, end);
|
|
26
26
|
}
|
|
27
27
|
export function createToolHtmlRenderer(deps) {
|
|
28
|
-
const {
|
|
28
|
+
const { getToolRenderers, theme, cwd, width = 100 } = deps;
|
|
29
29
|
const renderedCallComponents = new Map();
|
|
30
30
|
const renderedResultComponents = new Map();
|
|
31
31
|
const renderedStates = new Map();
|
|
@@ -58,7 +58,7 @@ export function createToolHtmlRenderer(deps) {
|
|
|
58
58
|
renderCall(toolCallId, toolName, args) {
|
|
59
59
|
try {
|
|
60
60
|
renderedArgs.set(toolCallId, args);
|
|
61
|
-
const toolDef =
|
|
61
|
+
const toolDef = getToolRenderers(toolName);
|
|
62
62
|
if (!toolDef?.renderCall) {
|
|
63
63
|
return undefined;
|
|
64
64
|
}
|
|
@@ -74,7 +74,7 @@ export function createToolHtmlRenderer(deps) {
|
|
|
74
74
|
},
|
|
75
75
|
renderResult(toolCallId, toolName, result, details, isError) {
|
|
76
76
|
try {
|
|
77
|
-
const toolDef =
|
|
77
|
+
const toolDef = getToolRenderers(toolName);
|
|
78
78
|
if (!toolDef?.renderResult) {
|
|
79
79
|
return undefined;
|
|
80
80
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-renderer.js","sourceRoot":"","sources":["../../../src/core/export-html/tool-renderer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AA0BpD;;;;;GAKG;AACH,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAE3C,SAAS,mBAAmB,CAAC,IAAY;IACxC,OAAO,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAe;IAC/C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC;IACvB,OAAO,KAAK,GAAG,GAAG,IAAI,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAAE,KAAK,EAAE,CAAC;IACjE,OAAO,GAAG,GAAG,KAAK,IAAI,mBAAmB,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAAE,GAAG,EAAE,CAAC;IACjE,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAA0B;IAChE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"tool-renderer.js","sourceRoot":"","sources":["../../../src/core/export-html/tool-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tool HTML renderer for custom tools in HTML export.\n *\n * Renders custom tool calls and results to HTML by invoking their TUI renderers\n * and converting the ANSI output to HTML.\n */\n\nimport type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type { Component } from \"@earendil-works/pi-tui\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport type { ToolRenderContext, ToolRenderers } from \"../extensions/types.ts\";\nimport { ansiLinesToHtml } from \"./ansi-to-html.ts\";\n\nexport interface ToolHtmlRendererDeps {\n\t/** Renderers of calls to a tool, as resolved by extensions and the registered tool */\n\tgetToolRenderers: (name: string) => ToolRenderers | undefined;\n\t/** Theme for styling */\n\ttheme: Theme;\n\t/** Working directory for render context */\n\tcwd: string;\n\t/** Terminal width for rendering (default: 100) */\n\twidth?: number;\n}\n\nexport interface ToolHtmlRenderer {\n\t/** Render a tool call to HTML. Returns undefined if tool has no custom renderer. */\n\trenderCall(toolCallId: string, toolName: string, args: unknown): string | undefined;\n\t/** Render a tool result to collapsed/expanded HTML. Returns undefined if tool has no custom renderer. */\n\trenderResult(\n\t\ttoolCallId: string,\n\t\ttoolName: string,\n\t\tresult: Array<{ type: string; text?: string; data?: string; mimeType?: string }>,\n\t\tdetails: unknown,\n\t\tisError: boolean,\n\t): { collapsed?: string; expanded?: string } | undefined;\n}\n\n/**\n * Create a tool HTML renderer.\n *\n * The renderer looks up tool definitions and invokes their renderCall/renderResult\n * methods, converting the resulting TUI Component output (ANSI) to HTML.\n */\nconst ANSI_ESCAPE_REGEX = /\\x1b\\[[\\d;]*m/g;\n\nfunction isBlankRenderedLine(line: string): boolean {\n\treturn line.replace(ANSI_ESCAPE_REGEX, \"\").trim().length === 0;\n}\n\nfunction trimRenderedResultLines(lines: string[]): string[] {\n\tlet start = 0;\n\tlet end = lines.length;\n\twhile (start < end && isBlankRenderedLine(lines[start])) start++;\n\twhile (end > start && isBlankRenderedLine(lines[end - 1])) end--;\n\treturn lines.slice(start, end);\n}\n\nexport function createToolHtmlRenderer(deps: ToolHtmlRendererDeps): ToolHtmlRenderer {\n\tconst { getToolRenderers, theme, cwd, width = 100 } = deps;\n\n\tconst renderedCallComponents = new Map<string, Component>();\n\tconst renderedResultComponents = new Map<string, Component>();\n\tconst renderedStates = new Map<string, any>();\n\tconst renderedArgs = new Map<string, unknown>();\n\n\tconst getState = (toolCallId: string): any => {\n\t\tlet state = renderedStates.get(toolCallId);\n\t\tif (!state) {\n\t\t\tstate = {};\n\t\t\trenderedStates.set(toolCallId, state);\n\t\t}\n\t\treturn state;\n\t};\n\n\tconst createRenderContext = (\n\t\ttoolCallId: string,\n\t\tlastComponent: Component | undefined,\n\t\texpanded: boolean,\n\t\tisPartial: boolean,\n\t\tisError: boolean,\n\t): ToolRenderContext => {\n\t\treturn {\n\t\t\targs: renderedArgs.get(toolCallId),\n\t\t\ttoolCallId,\n\t\t\tinvalidate: () => {},\n\t\t\tlastComponent,\n\t\t\tstate: getState(toolCallId),\n\t\t\tcwd,\n\t\t\texecutionStarted: true,\n\t\t\targsComplete: true,\n\t\t\tisPartial,\n\t\t\texpanded,\n\t\t\tshowImages: false,\n\t\t\tisError,\n\t\t};\n\t};\n\n\treturn {\n\t\trenderCall(toolCallId: string, toolName: string, args: unknown): string | undefined {\n\t\t\ttry {\n\t\t\t\trenderedArgs.set(toolCallId, args);\n\t\t\t\tconst toolDef = getToolRenderers(toolName);\n\t\t\t\tif (!toolDef?.renderCall) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\tconst component = toolDef.renderCall(\n\t\t\t\t\targs,\n\t\t\t\t\ttheme,\n\t\t\t\t\tcreateRenderContext(toolCallId, renderedCallComponents.get(toolCallId), false, true, false),\n\t\t\t\t);\n\t\t\t\trenderedCallComponents.set(toolCallId, component);\n\t\t\t\tconst lines = component.render(width);\n\t\t\t\treturn ansiLinesToHtml(lines);\n\t\t\t} catch {\n\t\t\t\t// On error, return undefined so HTML export can fall back to structured result rendering\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t},\n\n\t\trenderResult(\n\t\t\ttoolCallId: string,\n\t\t\ttoolName: string,\n\t\t\tresult: Array<{ type: string; text?: string; data?: string; mimeType?: string }>,\n\t\t\tdetails: unknown,\n\t\t\tisError: boolean,\n\t\t): { collapsed?: string; expanded?: string } | undefined {\n\t\t\ttry {\n\t\t\t\tconst toolDef = getToolRenderers(toolName);\n\t\t\t\tif (!toolDef?.renderResult) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\t// Build AgentToolResult from content array\n\t\t\t\t// Cast content since session storage uses generic object types\n\t\t\t\tconst agentToolResult = {\n\t\t\t\t\tcontent: result as (TextContent | ImageContent)[],\n\t\t\t\t\tdetails,\n\t\t\t\t\tisError,\n\t\t\t\t};\n\n\t\t\t\t// Render collapsed\n\t\t\t\tconst collapsedComponent = toolDef.renderResult(\n\t\t\t\t\tagentToolResult,\n\t\t\t\t\t{ expanded: false, isPartial: false },\n\t\t\t\t\ttheme,\n\t\t\t\t\tcreateRenderContext(toolCallId, renderedResultComponents.get(toolCallId), false, false, isError),\n\t\t\t\t);\n\t\t\t\trenderedResultComponents.set(toolCallId, collapsedComponent);\n\t\t\t\tconst collapsed = ansiLinesToHtml(trimRenderedResultLines(collapsedComponent.render(width)));\n\n\t\t\t\t// Render expanded\n\t\t\t\tconst expandedComponent = toolDef.renderResult(\n\t\t\t\t\tagentToolResult,\n\t\t\t\t\t{ expanded: true, isPartial: false },\n\t\t\t\t\ttheme,\n\t\t\t\t\tcreateRenderContext(toolCallId, renderedResultComponents.get(toolCallId), true, false, isError),\n\t\t\t\t);\n\t\t\t\trenderedResultComponents.set(toolCallId, expandedComponent);\n\t\t\t\tconst expanded = ansiLinesToHtml(trimRenderedResultLines(expandedComponent.render(width)));\n\n\t\t\t\treturn {\n\t\t\t\t\t...(collapsed && collapsed !== expanded ? { collapsed } : {}),\n\t\t\t\t\texpanded,\n\t\t\t\t};\n\t\t\t} catch {\n\t\t\t\t// On error, return undefined so HTML export can fall back to structured result rendering\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
|
package/bin/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@earendil-works/pi-coding-agent",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"piConfig": {
|
|
@@ -34,8 +34,7 @@
|
|
|
34
34
|
"docs",
|
|
35
35
|
"examples",
|
|
36
36
|
"containerization.md",
|
|
37
|
-
"CHANGELOG.md"
|
|
38
|
-
"npm-shrinkwrap.json"
|
|
37
|
+
"CHANGELOG.md"
|
|
39
38
|
],
|
|
40
39
|
"scripts": {
|
|
41
40
|
"clean": "shx rm -rf dist",
|
|
@@ -45,17 +44,17 @@
|
|
|
45
44
|
"copy-assets": "shx mkdir -p dist/modes/interactive/theme && shx cp src/modes/interactive/theme/*.json dist/modes/interactive/theme/ && shx mkdir -p dist/modes/interactive/assets && shx cp src/modes/interactive/assets/*.png dist/modes/interactive/assets/ && shx mkdir -p dist/core/export-html/vendor && shx cp src/core/export-html/template.html src/core/export-html/template.css src/core/export-html/template.js dist/core/export-html/ && shx cp src/core/export-html/vendor/*.js dist/core/export-html/vendor/",
|
|
46
45
|
"copy-binary-assets": "shx cp package.json dist/ && shx cp README.md dist/ && shx cp CHANGELOG.md dist/ && shx mkdir -p dist/theme && shx cp src/modes/interactive/theme/*.json dist/theme/ && shx mkdir -p dist/assets && shx cp src/modes/interactive/assets/*.png dist/assets/ && shx mkdir -p dist/export-html/vendor && shx cp src/core/export-html/template.html dist/export-html/ && shx cp src/core/export-html/vendor/*.js dist/export-html/vendor/ && shx cp -r docs dist/ && shx cp -r examples dist/ && shx cp ../../node_modules/@silvia-odwyer/photon-node/photon_rs_bg.wasm dist/",
|
|
47
46
|
"test": "vitest --run",
|
|
48
|
-
"
|
|
49
|
-
"prepublishOnly": "npm run clean && npm run build && npm run shrinkwrap"
|
|
47
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
50
48
|
},
|
|
51
49
|
"dependencies": {
|
|
52
|
-
"@earendil-works/chord": "^1.0.
|
|
53
|
-
"@earendil-works/pi-agent-core": "^1.0.
|
|
54
|
-
"@earendil-works/pi-ai": "^1.0.
|
|
55
|
-
"@earendil-works/pi-codemode": "^1.0.
|
|
56
|
-
"@earendil-works/pi-mcp": "^1.0.
|
|
57
|
-
"@earendil-works/pi-tui": "^1.0.
|
|
50
|
+
"@earendil-works/chord": "^1.0.4",
|
|
51
|
+
"@earendil-works/pi-agent-core": "^1.0.4",
|
|
52
|
+
"@earendil-works/pi-ai": "^1.0.4",
|
|
53
|
+
"@earendil-works/pi-codemode": "^1.0.4",
|
|
54
|
+
"@earendil-works/pi-mcp": "^1.0.4",
|
|
55
|
+
"@earendil-works/pi-tui": "^1.0.4",
|
|
58
56
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
57
|
+
"brace-expansion": "5.0.12",
|
|
59
58
|
"chalk": "6.0.0",
|
|
60
59
|
"cross-spawn": "7.0.6",
|
|
61
60
|
"diff": "8.0.4",
|
|
@@ -76,9 +75,9 @@
|
|
|
76
75
|
"protobufjs": "7.6.6"
|
|
77
76
|
},
|
|
78
77
|
"devDependencies": {
|
|
79
|
-
"@earendil-works/pi-client": "^1.0.
|
|
80
|
-
"@earendil-works/pi-protocol": "^1.0.
|
|
81
|
-
"@earendil-works/pi-server": "^1.0.
|
|
78
|
+
"@earendil-works/pi-client": "^1.0.4",
|
|
79
|
+
"@earendil-works/pi-protocol": "^1.0.4",
|
|
80
|
+
"@earendil-works/pi-server": "^1.0.4",
|
|
82
81
|
"@types/cross-spawn": "6.0.6",
|
|
83
82
|
"@types/hosted-git-info": "3.0.5",
|
|
84
83
|
"@types/node": "22.19.19",
|
package/bin/pi
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/bin/pi
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 76870370 bytes
|
|
4
|
+
sha256: bceb3f3b317940c58de01bddd9decdcb0755ffb544ae793fac1745502da6ddc2
|