@counterposition/skill-pi 0.87.1 → 1.0.0

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.
@@ -30,10 +30,15 @@ session.subscribe((event) => {
30
30
  }
31
31
  });
32
32
 
33
- await session.prompt("What files are in the current directory?");
33
+ try {
34
+ await session.prompt("What files are in the current directory?");
35
+ console.log(session.getLastAssistantText());
36
+ } finally {
37
+ session.dispose();
38
+ }
34
39
  ```
35
40
 
36
- Run with `npx tsx my-script.ts`.
41
+ Run with `npx tsx my-script.ts` (or Node's built-in type stripping). `prompt()` resolves when the run finishes, including automatic retries. `session.dispose()` aborts active work, invalidates extension contexts, and removes listeners. Checked against Pi v1.0.0: [sdk.md](https://github.com/earendil-works/pi/blob/v1.0.0/packages/coding-agent/docs/sdk.md), [SDK examples](https://github.com/earendil-works/pi/tree/v1.0.0/packages/coding-agent/examples/sdk).
37
42
 
38
43
  **Breaking (Pi 0.80.8):** `ModelRuntime` replaced the old `AuthStorage`/`ModelRegistry` pair as the SDK model/auth facade. `CreateAgentSessionOptions.authStorage` and `modelRegistry` are gone — pass the async `modelRuntime` instead. `AuthStorage` is no longer exported; use `ModelRuntime` (or a custom pi-ai `CredentialStore`), or `readStoredCredential()` for one-off reads of `auth.json`. `ModelRegistry` still exists only as the synchronous extension-facing compatibility facade, and its `refresh()` is now `Promise<void>`.
39
44
 
@@ -44,23 +49,29 @@ import {
44
49
  createAgentSession,
45
50
  DefaultResourceLoader,
46
51
  defineTool,
52
+ getAgentDir,
47
53
  ModelRuntime,
48
54
  SessionManager,
49
55
  } from "@earendil-works/pi-coding-agent";
50
56
  import { getBuiltinModel } from "@earendil-works/pi-ai/providers/all";
51
57
  ```
52
58
 
59
+ **Lightweight model construction (pi-ai 0.99.2):** `@earendil-works/pi-ai/models` builds model collections and providers without loading TypeBox, the built-in catalogs, or provider SDKs; use it in startup-sensitive code that brings its own models.
60
+
53
61
  **pi-ai 0.80.0 API move:** the old global API (`getModel`, `getModels`, `getProviders`, `stream`, `complete`, `completeSimple`, `registerApiProvider`, `getEnvApiKey`, ...) moved off the `@earendil-works/pi-ai` root entrypoint to `@earendil-works/pi-ai/compat` (a deprecated shim slated for removal). For built-in model lookup use `getBuiltinModel(provider, modelId)` from `@earendil-works/pi-ai/providers/all`, or the provider-factory API (`createModels()` / `Models.getModel()`). Extensions loaded by Pi are unaffected at runtime — the extension loader aliases the pi-ai root to the compat superset — but standalone SDK scripts and typechecked extension sources must use the new paths. The selective `@earendil-works/pi-ai/base` / `@earendil-works/pi-agent-core/base` entrypoints introduced in 0.79.8 were removed again in 0.80.0.
54
62
 
55
63
  ## Core Options
56
64
 
57
65
  ```typescript
58
66
  const cwd = "/path/to/project";
67
+ const agentDir = getAgentDir();
59
68
  const modelRuntime = await ModelRuntime.create();
69
+ const resourceLoader = new DefaultResourceLoader({ cwd, agentDir });
70
+ await resourceLoader.reload(); // a loader you pass in is not reloaded for you
60
71
 
61
72
  const { session } = await createAgentSession({
62
73
  cwd,
63
- agentDir: "~/.pi/agent",
74
+ agentDir,
64
75
  modelRuntime,
65
76
  model: getBuiltinModel("anthropic", "claude-opus-4-8"),
66
77
  thinkingLevel: "medium", // off | minimal | low | medium | high | xhigh | max
@@ -69,7 +80,7 @@ const { session } = await createAgentSession({
69
80
  ],
70
81
  tools: ["read", "bash", "edit", "write"],
71
82
  customTools: [/* defineTool(...) entries */],
72
- resourceLoader: new DefaultResourceLoader(),
83
+ resourceLoader,
73
84
  sessionManager: SessionManager.inMemory(),
74
85
  });
75
86
  ```
@@ -80,12 +91,61 @@ Notes:
80
91
  - Pi 0.68.0 changed the SDK `tools` option from `Tool[]` to a `string[]` allowlist of built-in, extension, and custom tool names. Use `noTools: "builtin"` to disable built-ins while keeping extension/custom tools enabled, or `noTools: "all"` for none.
81
92
  - `customTools` accepts `ToolDefinition[]`. Build them with `defineTool({...})` for full TypeScript inference.
82
93
  - The `create*Tool(cwd)` factories still exist for code that needs explicit `AgentTool` instances (e.g. when wiring tools into pi-agent-core directly), but they are no longer the value passed to `createAgentSession({ tools })`.
83
- - `DefaultResourceLoader` loads extensions, skills, prompt templates, themes, and context files. Replace it to drive resource discovery from custom sources (and it must implement `loadProjectContextFiles()` if you want `AGENTS.md`/`CLAUDE.md` discovery; that helper is also exported standalone).
94
+ - `DefaultResourceLoader` requires `{ cwd, agentDir }` and loads extensions, skills, prompt templates, themes, and context files. Replace it to drive resource discovery from custom sources (and it must implement `loadProjectContextFiles()` if you want `AGENTS.md`/`CLAUDE.md` discovery; that helper is also exported standalone).
84
95
  - **Breaking (Pi 0.87.0):** pi-agent-core's `shouldStopAfterTurn` option was removed (it was never a `createAgentSession()` option). On a low-level `Agent`, set `finishTurn` instead: it runs after the assistant message and tool results are finalized but before `turn_end`, also for error/aborted responses. Return `{ action: "end" }` to stop, `{ action: "continue" }` to ensure one more request, or `undefined` for normal scheduling — guard hard exits first: `if (turn.message.stopReason === "error" || turn.message.stopReason === "aborted") return;`. Inside `createAgentSession()`, use an extension's actionable `turn_end` / `agent_before_settle` boundaries (see `references/extensions.md`).
85
96
 
97
+ ## Built-in Extensions: Codemode, Tool Search, MCP
98
+
99
+ The CLI loads `codemode`, `tool_search`, MCP, and llama.cpp as built-in extensions. SDK sessions load none of them. Opt in through the resource loader (Pi 0.99.0, [example](https://github.com/earendil-works/pi/blob/v1.0.0/packages/coding-agent/examples/sdk/14-codemode-mcp.ts)):
100
+
101
+ ```typescript
102
+ import {
103
+ createAgentSession,
104
+ createCodemodeExtension,
105
+ createMcpExtension,
106
+ createToolSearchExtension,
107
+ DefaultResourceLoader,
108
+ getAgentDir,
109
+ SessionManager,
110
+ SettingsManager,
111
+ } from "@earendil-works/pi-coding-agent";
112
+
113
+ const cwd = process.cwd();
114
+ const resourceLoader = new DefaultResourceLoader({
115
+ cwd,
116
+ agentDir: getAgentDir(),
117
+ extensionFactories: [
118
+ createCodemodeExtension({ mode: "on" }), // options override codemode.mode / inlineBudget
119
+ createToolSearchExtension(),
120
+ createMcpExtension(), // reads mcp.json like the CLI (project file only when trusted)
121
+ ],
122
+ });
123
+ await resourceLoader.reload();
124
+
125
+ const settingsManager = SettingsManager.create(cwd);
126
+ settingsManager.applyOverrides({ defaultTools: ["+codemode", "+tool_search"] });
127
+
128
+ const { session } = await createAgentSession({
129
+ resourceLoader,
130
+ settingsManager,
131
+ sessionManager: SessionManager.inMemory(),
132
+ });
133
+
134
+ try {
135
+ await session.bindExtensions({}); // emits session_start; MCP connects here, in the background
136
+ await session.prompt("Use codemode to count the TypeScript files in src/.");
137
+ } finally {
138
+ session.dispose();
139
+ }
140
+ ```
141
+
142
+ - `codemode` and `tool_search` are registered inactive. Enable them with `defaultTools` (`+name` keeps the other defaults), or let MCP activate them for servers that need them. Passing `tools: [...]` instead restricts the session to the named tools, which hides MCP tools.
143
+ - Extension `session_start` handlers run only when the host calls `session.bindExtensions()`. Without it, MCP servers never connect.
144
+ - Inline extensions can be named `{ name, factory, replaceable?: true, builtin?: true }`. `replaceable` drops the extension when another one registers the same tool, command, or flag name. `builtin` supplies the code for `builtin:<name>`: it loads by default, is listed in `pi config`, is disabled by `-builtin:<name>` or `noExtensions`, and loads after project trust (so it cannot handle `project_trust`).
145
+
86
146
  ## Models & Auth (`ModelRuntime`)
87
147
 
88
- `ModelRuntime` (Pi 0.80.8) implements the pi-ai `Models` interface and owns credential storage. Auth resolution priority: runtime overrides (`setRuntimeApiKey`, not persisted) → stored credentials in `auth.json` → environment variables → fallback resolver for `models.json` keys.
148
+ `ModelRuntime` (Pi 0.80.8) implements the pi-ai `Models` interface and owns credential storage. Auth resolution priority: runtime overrides (`setRuntimeApiKey`, not persisted) → stored credentials in `auth.json` → `apiKey` from `models.json` or an extension registration → the provider's environment variables or ambient cloud credentials.
89
149
 
90
150
  ```typescript
91
151
  import { InMemoryCredentialStore } from "@earendil-works/pi-ai";
@@ -115,6 +175,8 @@ const inMemory = await ModelRuntime.create({ credentials: new InMemoryCredential
115
175
 
116
176
  Pi 0.84.x made catalog refresh cancellation-aware: `refresh(options?)` accepts `{ providers?, allowNetwork?, force?, signal? }` and returns a `ModelsRefreshResult` (`{ errors, aborted }`) instead of discarding provider errors; `create({ signal })`, `login()`, `logout()`, and the now-async `setRuntimeApiKey()/removeRuntimeApiKey()` accept optional abort signals too (unbounded when omitted — applications own deadline policy). Credential mutations resolve once local state is consistent, without waiting for remote freshness; if that synchronization fails they reject with the exported `CredentialSynchronizationError` (inspect `providerId`, `operation`, `credential`, `cause` rather than retrying blindly). A failed refresh never undoes a committed credential change, and each `refresh()` starts a fresh generation so stale refreshes cannot publish afterward.
117
177
 
178
+ Non-chat models (Pi 0.99.0): `getModelsOfType(type, provider?)`, `getModelOfType(type, provider, id)`, `getAvailableOfType()`, `getAllModels()`, and `getAllAvailable()` cover `"chat"`, `"image"`, and `"classifier"` entries; `getModels()` stays chat-only. `modelRuntime.classify(model, context, options?)` and `modelRuntime.generateImages(model, context, options?)` resolve auth at request time and return error results (`stopReason: "error" | "aborted"`) instead of rejecting. `modelRuntime.registerVirtualModel(definition)` registers a routing model without an extension. See `references/providers.md#model-types`.
179
+
118
180
  To match CLI model parsing, use the exported resolver helpers (Pi 0.80.4):
119
181
 
120
182
  ```typescript
@@ -138,11 +200,11 @@ await session.prompt("Review the current directory");
138
200
  await session.prompt("Stop and do this instead", { streamingBehavior: "steer" });
139
201
  await session.prompt("After you finish, also check tests", { streamingBehavior: "followUp" });
140
202
 
141
- await session.steer("Use a smaller diff");
203
+ const disposition = await session.steer("Use a smaller diff"); // "queued" | "handled"
142
204
  await session.followUp("Summarize the changes afterward");
143
205
  ```
144
206
 
145
- `prompt()` expands file-based prompt templates. During active streaming, calling it without `streamingBehavior` throws.
207
+ `prompt()` expands file-based prompt templates and resolves after an accepted run finishes. During active streaming, calling it without `streamingBehavior` throws. Since Pi 0.99.0 `steer()` and `followUp()` return a disposition: `"queued"` (also after an extension transformed the input) or `"handled"` (an extension consumed it, so nothing was queued). Both throw for extension commands (`/name`); send those through `prompt()`, which runs them immediately, even while streaming. Read state through `session.messages`, `session.model`, `session.thinkingLevel`, `session.systemPrompt`, and `session.getActiveToolNames()`.
146
208
 
147
209
  ## Session Runtime
148
210
 
@@ -230,7 +292,7 @@ session.subscribe((event) => {
230
292
  process.stdout.write(event.assistantMessageEvent.delta);
231
293
  }
232
294
  break;
233
- case "tool_execution_start":
295
+ case "tool_execution_start": // nested calls (ctx.executeTool, codemode) carry parentToolCallId
234
296
  case "tool_execution_update":
235
297
  case "tool_execution_end":
236
298
  case "agent_start":
@@ -261,8 +323,9 @@ Pi 0.84.0 added transport-neutral remote-session client APIs: `@earendil-works/p
261
323
 
262
324
  ## RPC Mode
263
325
 
264
- `pi --mode rpc` speaks newline-delimited JSON over stdio. Additions since Pi 0.79:
326
+ `pi --mode rpc` speaks newline-delimited JSON over stdio ([rpc.md](https://github.com/earendil-works/pi/blob/v1.0.0/packages/coding-agent/docs/rpc.md), [rpc-commands.md](https://github.com/earendil-works/pi/blob/v1.0.0/packages/coding-agent/docs/rpc-commands.md)). Additions since Pi 0.79:
265
327
 
328
+ - Input dispositions (Pi 0.99.0): a successful `prompt` response carries `data.disposition` — `"started"` (a run started), `"queued"` (queued during a run), or `"handled"` (an extension command or input handler consumed it). `steer` and `follow_up` responses carry `"queued"` or `"handled"`. On `"handled"` no run started for that input: do not wait for `agent_settled`. Otherwise keep consuming events and wait for `agent_settled`, not `agent_end`. Failures after acceptance arrive as events, never as a second response. `RpcClient.prompt(message, images?, streamingBehavior?)`, `steer()`, and `followUp()` return the disposition.
266
329
  - `agent_settled` event (Pi 0.80.4) fires when a run is fully settled — no automatic retry, compaction retry, or queued continuation remains; `agent_end` now carries `willRetry`. `set_thinking_level` accepts `"max"` where the model supports it.
267
330
  - `clear_queue` (Pi 0.84.4) returns and removes queued steering and follow-up messages; direct RPC `steer`/`follow_up` commands pass through extension `input` handlers since Pi 0.86.0.
268
331
  - `get_entries` / `get_tree` (Pi 0.80.3) read session entries and tree snapshots over RPC; `get_available_thinking_levels` (Pi 0.81.0) lists the current model's supported thinking levels.
@@ -285,13 +348,18 @@ Pi 0.84.0 added transport-neutral remote-session client APIs: `@earendil-works/p
285
348
  To name an inline factory in the startup Extensions list (instead of `<inline:1>`), wrap it in an `InlineExtension` (Pi 0.80.4):
286
349
 
287
350
  ```typescript
288
- import type { InlineExtension } from "@earendil-works/pi-coding-agent";
351
+ import { DefaultResourceLoader, getAgentDir, type InlineExtension } from "@earendil-works/pi-coding-agent";
289
352
 
290
353
  const myProvider: InlineExtension = {
291
354
  name: "my-provider",
292
355
  factory: (pi) => { /* ... */ },
293
356
  };
294
- const loader = new DefaultResourceLoader({ extensionFactories: [myProvider] });
357
+ const loader = new DefaultResourceLoader({
358
+ cwd: process.cwd(),
359
+ agentDir: getAgentDir(),
360
+ extensionFactories: [myProvider],
361
+ });
362
+ await loader.reload();
295
363
  ```
296
364
 
297
365
  Bare factory functions are still accepted.
@@ -38,7 +38,7 @@ Edit JSON directly or use `/settings` for common interactive options.
38
38
 
39
39
  ```json
40
40
  {
41
- "theme": "dark",
41
+ "theme": "system",
42
42
  "quietStartup": false,
43
43
  "collapseChangelog": false,
44
44
  "doubleEscapeAction": "tree",
@@ -51,30 +51,33 @@ Edit JSON directly or use `/settings` for common interactive options.
51
51
  }
52
52
  ```
53
53
 
54
+ - `quietStartup`: `true` hides the startup header and loaded-resource listing; `"header"` (Pi 1.0.0) keeps the header (version and key hints) but hides the model scope line and resource listing
54
55
  - `doubleEscapeAction`: `"tree"`, `"fork"`, or `"none"`
55
56
  - `treeFilterMode`: `"default"`, `"no-tools"`, `"user-only"`, `"labeled-only"`, or `"all"`
56
57
  - In `/tree`, `Shift+T` toggles timestamps on entry labels
57
- - `theme` also accepts `"light-name/dark-name"` (Pi 0.79.7) to switch themes automatically with the terminal color scheme; `/` is reserved in theme names for this. On first run Pi detects the terminal background and defaults to `dark` or `light`. `--use-theme <name[/name]>` (Pi 0.84.2) sets a per-run initial theme without changing saved settings.
58
+ - `theme` defaults to `"system"` (Pi 0.99.0), which builds Pi's colors from the terminal's reported foreground, background, and ANSI palette and follows light/dark switches; `system` is a reserved theme name. `dark` and `light` are the other built-ins. `"light-name/dark-name"` (Pi 0.79.7) switches themes with the terminal color scheme; `/` is reserved in theme names for this. `--use-theme <name[/name]>` (Pi 0.84.2) sets a per-run initial theme without changing saved settings.
58
59
  - `outputPad` (Pi 0.80.3, `0` or `1`) sets horizontal padding for user messages, assistant messages, and thinking blocks; custom message renderers receive it as `options.outputPad` (Pi 0.82.1).
59
60
  - `externalEditor` (Pi 0.80.3) sets the `Ctrl+G` external editor command and takes precedence over `$VISUAL`/`$EDITOR`.
60
61
 
61
62
  ## Fullscreen TUI Mode
62
63
 
63
- Experimental since Pi 0.84.0:
64
+ Fullscreen is the default since Pi 1.0.0 (added in 0.84.0):
64
65
 
65
66
  ```json
66
67
  {
67
- "tuiMode": "regular",
68
+ "tuiMode": "fullscreen",
68
69
  "fullscreenExitOutput": "transcript",
69
70
  "fullscreenScrollbar": "auto",
70
- "fullscreenCopyOnSelect": true
71
+ "fullscreenCopyOnSelect": true,
72
+ "fullscreenWheelScrollLines": "auto"
71
73
  }
72
74
  ```
73
75
 
74
- - `tuiMode`: `"regular"` (default) or `"fullscreen"`; `/settings` switches at runtime, `--tui-mode` overrides per run
76
+ - `tuiMode`: `"fullscreen"` (default since Pi 1.0.0) or `"regular"` for the terminal's normal scrollback; `/settings` switches at runtime, `--tui-mode` overrides per run. Scripts that capture Pi's screen (VHS, tmux) see the fullscreen layout unless they set `regular`
75
77
  - `fullscreenExitOutput` (Pi 0.84.2): `"transcript"` prints the final transcript on exit; `"resume-hint"` restores the previous screen and prints only a resume hint
76
78
  - `fullscreenScrollbar`: `"auto"` shows while scrolling, `"always"` reserves the rightmost column, `"hidden"`
77
79
  - `fullscreenCopyOnSelect` (Pi 0.84.4, default `true`): when `false`, `Ctrl+X` copies the active selection (falling back to the last assistant message)
80
+ - `fullscreenWheelScrollLines` (Pi 0.99.0): `"auto"` (default) or 1–100 lines per mouse-wheel event. `"auto"` moves one line per event in local macOS terminals and accelerates fast spins elsewhere (up to 6 lines); Alt+wheel moves five times as far
78
81
  - Fullscreen keeps editor/status/widgets/footer docked while the transcript scrolls independently; transcript search (`Ctrl+Shift+F`, Pi 0.84.2), page/half-page/line scrolling, and marked-message navigation are configurable via `tui.altScreen.*` keybindings
79
82
  - Theme tokens `scrollbarThumb`, `searchMatchBg`, `searchMatchText` are optional additions with fallbacks (`selectedBg`, `selectedBg`, `text`)
80
83
 
@@ -181,7 +184,6 @@ Notes:
181
184
  {
182
185
  "sessionDir": ".pi/sessions",
183
186
  "enabledModels": ["claude-*", "gpt-4o", "gemini-2*"],
184
- "defaultTools": ["bash", "read", "edit"],
185
187
  "markdown": {
186
188
  "codeBlockIndent": " ",
187
189
  "mermaid": "streaming"
@@ -191,12 +193,26 @@ Notes:
191
193
 
192
194
  When multiple sources specify a session directory, `--session-dir` takes precedence over `sessionDir` in settings. Pi 0.65.0 removed the old `session_directory` extension/settings hook.
193
195
 
194
- - `defaultTools` (Pi 0.84.2) picks the built-in tools enabled at startup (default `read`, `bash`, `edit`, `write`; also available: `grep`, `find`, `ls`, and `powershell` on Windows since Pi 0.84.3) (global or per project; project replaces global). An empty array starts with no built-in tools while keeping extension/SDK custom tools. `--tools` remains a strict allowlist for all tools, `--exclude-tools` filters the resulting list.
195
196
  - `markdown.mermaid` (Pi 0.84.0): `"off"`, `"final"`, or `"streaming"` — themed Unicode rendering of supported Mermaid diagrams in interactive messages. Pi 0.84.0 also renders terminal-friendly Unicode for LaTeX expressions.
196
197
 
198
+ ## Tools & Codemode
199
+
200
+ ```json
201
+ {
202
+ "defaultTools": ["+codemode"],
203
+ "codemode": { "mode": "on", "inlineBudget": 3000 }
204
+ }
205
+ ```
206
+
207
+ - `defaultTools` picks the tools enabled at startup (default `read`, `bash`, `edit`, `write`; also `grep`, `find`, `ls`, `powershell`, and the built-in extension tools `codemode` and `tool_search`). Plain names replace the defaults. A list of only `+name`/`-name` entries (Pi 0.99.0) changes the inherited selection instead; in a mixed list the plain names form the selection and `+`/`-` apply in order. A project list of only `+`/`-` entries applies on top of the user setting; a project list with a plain name replaces it. An empty array disables built-in tools but keeps extension/SDK tools.
208
+ - `--tools` replaces the whole selection for one run and does not accept `+`/`-`; `--exclude-tools` filters the result.
209
+ - `/reload` (Pi 0.99.2) enables tools newly added to `defaultTools`. It does not disable tools removed from it or re-enable unchanged tools turned off in the session; `--tools`, `--no-tools`, and `--no-builtin-tools` still win on reload.
210
+ - `codemode.mode`: `"on"` (default) keeps declared tools declared; `"only"` hides active built-in and extension tools from the model so it reaches them through `codemode`. `codemode.inlineBudget` (default `3000`, estimated tokens) caps tool declarations in the `codemode` description. See `references/codemode.md`.
211
+ - MCP servers are configured in `~/.pi/agent/mcp.json` and the trust-gated `.pi/mcp.json`, not in `settings.json`. See `references/mcp.md`.
212
+
197
213
  ## Project Trust
198
214
 
199
- Since Pi 0.79.0, project-local settings, resources, and packages (`.pi/` settings/extensions/skills/prompts/themes, project packages) only load after the project is trusted. `AGENTS.md` / `CLAUDE.md` context files load regardless of trust. Trust is a loading gate, not a sandbox.
215
+ Since Pi 0.79.0, project-local settings, resources, and packages (`.pi/` settings/extensions/skills/prompts/themes/`mcp.json`, project packages) only load after the project is trusted. `AGENTS.md` / `CLAUDE.md` context files load regardless of trust. Trust is a loading gate, not a sandbox.
200
216
 
201
217
  ```json
202
218
  {
@@ -238,6 +254,7 @@ Notes:
238
254
  - `packages` loads npm/git/local Pi packages.
239
255
  - `extensions`, `skills`, `prompts`, and `themes` are for local files/directories.
240
256
  - `enableSkillCommands` controls `/skill:name` registration.
257
+ - Built-in extensions (Pi 0.99.0) are `builtin:mcp`, `builtin:llama.cpp`, `builtin:codemode`, and `builtin:tool-search`. They load by default; `"extensions": ["-builtin:mcp"]` disables one, and a project `+builtin:<name>`/`-builtin:<name>` entry overrides the user setting. `pi config` lists them under Built-in.
241
258
 
242
259
  ## Include / Exclude Patterns
243
260
 
@@ -266,6 +283,7 @@ Run `pi --help` for the authoritative list. Most commonly:
266
283
  pi [options] [@files...] [messages...]
267
284
 
268
285
  # package commands: install/remove/uninstall/update/list/config (all support -l for project scope)
286
+ # MCP commands: pi mcp add|remove|list|login|logout (see references/mcp.md)
269
287
 
270
288
  # modes
271
289
  -p, --print single-shot text output
@@ -273,7 +291,7 @@ pi [options] [@files...] [messages...]
273
291
  --export <in> [out] export a session to HTML
274
292
 
275
293
  # model
276
- --provider <name> e.g. anthropic, openai, google
294
+ --provider <name> e.g. anthropic, openai, google; needs --model (Pi 1.0.0)
277
295
  --model <pattern> supports provider/id and optional :<thinking>
278
296
  --api-key <key>
279
297
  --thinking off|minimal|low|medium|high|xhigh|max
@@ -291,15 +309,16 @@ pi [options] [@files...] [messages...]
291
309
  --no-session ephemeral
292
310
 
293
311
  # tools and resources
294
- --tools <list>, -t name allowlist (read,bash,edit,write,grep,find,ls,...)
312
+ --tools <list>, -t name allowlist (read,bash,edit,write,grep,find,ls,codemode,...)
295
313
  --exclude-tools <list>, -xt disable specific built-in/extension/custom tools, keep the rest
296
314
  --no-tools, -nt disable everything
297
315
  --no-builtin-tools, -nbt disable built-ins, keep extension/custom
298
- -e, --extension <source> repeatable; npm/git/path
316
+ -e, --extension <source> repeatable; npm/git/path, or builtin:<name>
299
317
  --skill <path> repeatable
300
318
  --prompt-template <path> repeatable
301
319
  --theme <path> repeatable
302
- --no-extensions / --no-skills / --no-prompt-templates / --no-themes
320
+ --no-extensions, -ne also disables built-in extensions (pi -ne -e builtin:mcp keeps only MCP)
321
+ --no-skills / --no-prompt-templates / --no-themes
303
322
  --no-context-files, -nc skip AGENTS.md / CLAUDE.md discovery
304
323
 
305
324
  # trust and network
@@ -308,9 +327,9 @@ pi [options] [@files...] [messages...]
308
327
  --offline disable startup network operations (same as PI_OFFLINE=1)
309
328
 
310
329
  # prompts and misc
311
- --system-prompt <text> replace default
312
- --append-system-prompt <text> repeatable; appended with double newlines
313
- --tui-mode regular|fullscreen experimental fullscreen TUI (Pi 0.84.0)
330
+ --system-prompt <text|path> replace default
331
+ --append-system-prompt <text|path> repeatable; appended with double newlines
332
+ --tui-mode regular|fullscreen fullscreen is the default (Pi 1.0.0)
314
333
  --use-theme <name[/name]> per-run initial theme, saved settings untouched (Pi 0.84.2)
315
334
  --verbose
316
335
  ```