@earendil-works/pi-coding-agent 0.84.1 → 0.84.2

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.
Files changed (137) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +1 -0
  3. package/dist/cli/args.d.ts +1 -0
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +11 -0
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/auth-command.d.ts.map +1 -1
  8. package/dist/cli/auth-command.js +5 -4
  9. package/dist/cli/auth-command.js.map +1 -1
  10. package/dist/core/agent-session.d.ts +7 -2
  11. package/dist/core/agent-session.d.ts.map +1 -1
  12. package/dist/core/agent-session.js +6 -6
  13. package/dist/core/agent-session.js.map +1 -1
  14. package/dist/core/experimental.d.ts +4 -0
  15. package/dist/core/experimental.d.ts.map +1 -1
  16. package/dist/core/experimental.js +4 -0
  17. package/dist/core/experimental.js.map +1 -1
  18. package/dist/core/extensions/types.d.ts +4 -0
  19. package/dist/core/extensions/types.d.ts.map +1 -1
  20. package/dist/core/extensions/types.js.map +1 -1
  21. package/dist/core/keybindings.d.ts +24 -0
  22. package/dist/core/keybindings.d.ts.map +1 -1
  23. package/dist/core/model-config.d.ts +5 -0
  24. package/dist/core/model-config.d.ts.map +1 -1
  25. package/dist/core/model-config.js +1 -0
  26. package/dist/core/model-config.js.map +1 -1
  27. package/dist/core/project-trust.d.ts.map +1 -1
  28. package/dist/core/project-trust.js +2 -2
  29. package/dist/core/project-trust.js.map +1 -1
  30. package/dist/core/sdk.d.ts +5 -3
  31. package/dist/core/sdk.d.ts.map +1 -1
  32. package/dist/core/sdk.js +2 -1
  33. package/dist/core/sdk.js.map +1 -1
  34. package/dist/core/session-manager.d.ts.map +1 -1
  35. package/dist/core/session-manager.js +2 -2
  36. package/dist/core/session-manager.js.map +1 -1
  37. package/dist/core/settings-manager.d.ts +6 -0
  38. package/dist/core/settings-manager.d.ts.map +1 -1
  39. package/dist/core/settings-manager.js +12 -0
  40. package/dist/core/settings-manager.js.map +1 -1
  41. package/dist/core/system-prompt.d.ts.map +1 -1
  42. package/dist/core/system-prompt.js +1 -1
  43. package/dist/core/system-prompt.js.map +1 -1
  44. package/dist/core/tools/bash.d.ts.map +1 -1
  45. package/dist/core/tools/bash.js +2 -0
  46. package/dist/core/tools/bash.js.map +1 -1
  47. package/dist/core/tools/edit.d.ts.map +1 -1
  48. package/dist/core/tools/edit.js +2 -0
  49. package/dist/core/tools/edit.js.map +1 -1
  50. package/dist/core/tools/find.d.ts.map +1 -1
  51. package/dist/core/tools/find.js +1 -1
  52. package/dist/core/tools/find.js.map +1 -1
  53. package/dist/core/tools/grep.d.ts.map +1 -1
  54. package/dist/core/tools/grep.js +1 -1
  55. package/dist/core/tools/grep.js.map +1 -1
  56. package/dist/core/tools/read.d.ts.map +1 -1
  57. package/dist/core/tools/read.js +2 -0
  58. package/dist/core/tools/read.js.map +1 -1
  59. package/dist/core/tools/write.d.ts.map +1 -1
  60. package/dist/core/tools/write.js +2 -0
  61. package/dist/core/tools/write.js.map +1 -1
  62. package/dist/index.d.ts +1 -1
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js.map +1 -1
  65. package/dist/main.d.ts.map +1 -1
  66. package/dist/main.js +5 -1
  67. package/dist/main.js.map +1 -1
  68. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  69. package/dist/modes/interactive/components/model-selector.js +2 -1
  70. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  71. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  72. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  73. package/dist/modes/interactive/components/settings-selector.js +10 -0
  74. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  75. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  76. package/dist/modes/interactive/components/tool-execution.js +10 -1
  77. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  78. package/dist/modes/interactive/interactive-mode.d.ts +8 -2
  79. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  80. package/dist/modes/interactive/interactive-mode.js +76 -25
  81. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  82. package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
  83. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
  84. package/dist/modes/interactive/model-catalog-refresh.js +34 -0
  85. package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
  86. package/dist/modes/interactive/theme/dark.json +2 -0
  87. package/dist/modes/interactive/theme/light.json +2 -0
  88. package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
  89. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  90. package/dist/modes/interactive/theme/theme-controller.js +25 -11
  91. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  92. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  93. package/dist/modes/interactive/theme/theme.d.ts +5 -3
  94. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  95. package/dist/modes/interactive/theme/theme.js +12 -2
  96. package/dist/modes/interactive/theme/theme.js.map +1 -1
  97. package/dist/modes/json-event.d.ts +4 -1
  98. package/dist/modes/json-event.d.ts.map +1 -1
  99. package/dist/modes/json-event.js +5 -2
  100. package/dist/modes/json-event.js.map +1 -1
  101. package/dist/package-manager-cli.d.ts.map +1 -1
  102. package/dist/package-manager-cli.js +1 -1
  103. package/dist/package-manager-cli.js.map +1 -1
  104. package/dist/server/create-harness.d.ts.map +1 -1
  105. package/dist/server/create-harness.js +2 -0
  106. package/dist/server/create-harness.js.map +1 -1
  107. package/dist/utils/tools-manager.d.ts +10 -1
  108. package/dist/utils/tools-manager.d.ts.map +1 -1
  109. package/dist/utils/tools-manager.js +14 -19
  110. package/dist/utils/tools-manager.js.map +1 -1
  111. package/docs/compaction.md +6 -6
  112. package/docs/custom-provider.md +1 -1
  113. package/docs/environment-variables.md +8 -2
  114. package/docs/extensions.md +4 -0
  115. package/docs/json.md +6 -4
  116. package/docs/keybindings.md +8 -2
  117. package/docs/rpc.md +15 -4
  118. package/docs/sdk.md +9 -0
  119. package/docs/settings.md +31 -0
  120. package/docs/terminal-setup.md +23 -2
  121. package/docs/themes.md +24 -3
  122. package/docs/tui.md +2 -2
  123. package/docs/usage.md +3 -2
  124. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  125. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  126. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  127. package/examples/extensions/gondolin/package-lock.json +2 -2
  128. package/examples/extensions/gondolin/package.json +1 -1
  129. package/examples/extensions/sandbox/package-lock.json +2 -2
  130. package/examples/extensions/sandbox/package.json +1 -1
  131. package/examples/extensions/subagent/README.md +2 -0
  132. package/examples/extensions/subagent/agents.ts +40 -9
  133. package/examples/extensions/subagent/index.ts +21 -3
  134. package/examples/extensions/with-deps/package-lock.json +2 -2
  135. package/examples/extensions/with-deps/package.json +1 -1
  136. package/npm-shrinkwrap.json +27 -78
  137. package/package.json +6 -6
package/docs/themes.md CHANGED
@@ -39,6 +39,23 @@ Select a theme via `/settings` or in `settings.json`:
39
39
 
40
40
  On first run, pi detects your terminal background and defaults to `dark` or `light`.
41
41
 
42
+ ### Initial Theme
43
+
44
+ Start an interactive run with a theme without changing the saved setting:
45
+
46
+ ```bash
47
+ pi --use-theme light
48
+ ```
49
+
50
+ To follow terminal appearance, use `lightTheme/darkTheme` syntax:
51
+
52
+ ```bash
53
+ pi --use-theme light/dark
54
+ ```
55
+
56
+ The CLI value is the initial theme for that run. Choosing another theme later in `/settings` applies it immediately
57
+ and saves it normally.
58
+
42
59
  ## Creating a Custom Theme
43
60
 
44
61
  1. Create a theme file:
@@ -72,6 +89,8 @@ vim ~/.pi/agent/themes/my-theme.json
72
89
  "thinkingText": "secondary",
73
90
  "selectedBg": "#2d2d30",
74
91
  "scrollbarThumb": "#555566",
92
+ "searchMatchBg": "#2d2d30",
93
+ "searchMatchText": "",
75
94
  "userMessageBg": "#2d2d30",
76
95
  "userMessageText": "",
77
96
  "customMessageBg": "#2d2d30",
@@ -141,13 +160,13 @@ vim ~/.pi/agent/themes/my-theme.json
141
160
 
142
161
  - `name` is required, must be unique, and must not contain `/`.
143
162
  - `vars` is optional. Define reusable colors here, then reference them in `colors`.
144
- - `colors` must define all 51 required tokens. `thinkingMax` is optional and falls back to `thinkingXhigh`; `scrollbarThumb` is optional and falls back to `selectedBg`.
163
+ - `colors` must define all 51 required tokens. `thinkingMax`, `scrollbarThumb`, and the two search highlight tokens are optional and use the fallbacks listed below.
145
164
 
146
165
  The `$schema` field enables editor auto-completion and validation.
147
166
 
148
167
  ## Color Tokens
149
168
 
150
- Every theme must define all 51 required color tokens. `thinkingMax` and `scrollbarThumb` are optional for compatibility with existing themes; when omitted, they use `thinkingXhigh` and `selectedBg`, respectively.
169
+ Every theme must define all 51 required color tokens. The optional tokens preserve compatibility with existing themes: `thinkingMax` falls back to `thinkingXhigh`, `scrollbarThumb` and `searchMatchBg` fall back to `selectedBg`, and `searchMatchText` falls back to `text`. Other search matches use `searchMatchText` on `searchMatchBg` with an underline; the current match reverses that foreground/background pair and uses bold text.
151
170
 
152
171
  ### Core UI (11 colors)
153
172
 
@@ -165,12 +184,14 @@ Every theme must define all 51 required color tokens. `thinkingMax` and `scrollb
165
184
  | `text` | Default text (usually `""`) |
166
185
  | `thinkingText` | Thinking block text |
167
186
 
168
- ### Backgrounds & Content (11 required, 1 optional)
187
+ ### Backgrounds & Content (11 required, 3 optional)
169
188
 
170
189
  | Token | Purpose |
171
190
  |-------|---------|
172
191
  | `selectedBg` | Selected line background |
173
192
  | `scrollbarThumb` | Fullscreen scrollbar thumb background; optional, falls back to `selectedBg` |
193
+ | `searchMatchBg` | Transcript search match background and current-match text; optional, falls back to `selectedBg` |
194
+ | `searchMatchText` | Transcript search match text and current-match background; optional, falls back to `text` |
174
195
  | `userMessageBg` | User message background |
175
196
  | `userMessageText` | User message text |
176
197
  | `customMessageBg` | Extension message background |
package/docs/tui.md CHANGED
@@ -431,7 +431,7 @@ renderResult(result, options, theme, context) {
431
431
 
432
432
  | Category | Colors |
433
433
  |----------|--------|
434
- | General | `text`, `accent`, `muted`, `dim` |
434
+ | General | `text`, `accent`, `muted`, `dim`, `searchMatchText` |
435
435
  | Status | `success`, `error`, `warning` |
436
436
  | Borders | `border`, `borderAccent`, `borderMuted` |
437
437
  | Messages | `userMessageText`, `customMessageText`, `customMessageLabel` |
@@ -444,7 +444,7 @@ renderResult(result, options, theme, context) {
444
444
 
445
445
  **Background colors** (`theme.bg(color, text)`):
446
446
 
447
- `selectedBg`, `userMessageBg`, `customMessageBg`, `toolPendingBg`, `toolSuccessBg`, `toolErrorBg`
447
+ `selectedBg`, `searchMatchBg`, `userMessageBg`, `customMessageBg`, `toolPendingBg`, `toolSuccessBg`, `toolErrorBg`
448
448
 
449
449
  **For Markdown**, use `getMarkdownTheme()`:
450
450
 
package/docs/usage.md CHANGED
@@ -242,15 +242,16 @@ pi --no-extensions -e ./my-extension.ts
242
242
  | `--system-prompt <text>` | Replace default prompt; context files and skills are still appended |
243
243
  | `--append-system-prompt <text>` | Append to system prompt |
244
244
  | `--tui-mode <mode>` | TUI mode: `regular` (default) or experimental `fullscreen` |
245
+ | `--use-theme <name[/name]>` | Set the initial interactive theme for this run without changing settings |
245
246
  | `--verbose` | Force verbose startup |
246
247
  | `-a`, `--approve` | Trust project-local files for this run |
247
248
  | `-na`, `--no-approve` | Ignore project-local files for this run |
248
249
  | `-h`, `--help` | Show help |
249
250
  | `-v`, `--version` | Show version |
250
251
 
251
- In `fullscreen` mode, the transcript scrolls inside the terminal viewport while queued messages, working status, extension widgets, editor, and footer remain fixed at the bottom. Mouse/trackpad input scrolls the region under the pointer; keyboard viewport actions always remain available. Inline images work in terminals that support the Kitty graphics protocol, including Kitty and Ghostty. In iTerm2 they render as text placeholders because its inline-image protocol cannot delete or crop placements during application-owned scrolling. In `regular` mode, pi uses the main screen and terminal-owned scrollback, and iTerm2 inline images continue to render normally.
252
+ In `fullscreen` mode, the transcript scrolls inside the terminal viewport while queued messages, working status, extension widgets, editor, and footer remain fixed at the bottom. Mouse/trackpad input scrolls the region under the pointer; keyboard viewport actions always remain available. Inline images work in terminals that support the Kitty graphics protocol, including Kitty and Ghostty. In iTerm2 they render as text placeholders because its inline-image protocol cannot delete or crop placements during application-owned scrolling. In `regular` mode, pi uses the main screen and terminal-owned scrollback, and iTerm2 inline images continue to render normally. See [Terminal setup](terminal-setup.md) for terminal-specific settings and workarounds.
252
253
 
253
- Set **TUI mode** in `/settings` to switch between `regular` and `fullscreen` immediately and choose the default for future sessions.
254
+ Set **TUI mode** in `/settings` to switch between `regular` and `fullscreen` immediately and choose the default for future sessions. **Fullscreen exit output** controls whether exiting fullscreen prints the final transcript or restores the previous screen and prints only the session resume hint.
254
255
 
255
256
  ### File Arguments
256
257
 
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider",
3
- "version": "0.84.1",
3
+ "version": "0.84.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-custom-provider",
9
- "version": "0.84.1",
9
+ "version": "0.84.2",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sdk": "^0.52.0"
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider-anthropic",
3
3
  "private": true,
4
- "version": "0.84.1",
4
+ "version": "0.84.2",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider-gitlab-duo",
3
3
  "private": true,
4
- "version": "0.84.1",
4
+ "version": "0.84.2",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-gondolin",
3
- "version": "0.84.1",
3
+ "version": "0.84.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-gondolin",
9
- "version": "0.84.1",
9
+ "version": "0.84.2",
10
10
  "dependencies": {
11
11
  "@earendil-works/gondolin": "0.12.0"
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-gondolin",
3
3
  "private": true,
4
- "version": "0.84.1",
4
+ "version": "0.84.2",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-sandbox",
3
- "version": "1.14.1",
3
+ "version": "1.14.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-sandbox",
9
- "version": "1.14.1",
9
+ "version": "1.14.2",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sandbox-runtime": "^0.0.26"
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-sandbox",
3
3
  "private": true,
4
- "version": "1.14.1",
4
+ "version": "1.14.2",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -137,6 +137,8 @@ model: claude-haiku-4-5
137
137
  System prompt for the agent goes here.
138
138
  ```
139
139
 
140
+ When `model` is omitted, the subagent inherits the dispatching session's active model and thinking level.
141
+
140
142
  **Locations:**
141
143
  - `~/.pi/agent/agents/*.md` - User-level (always loaded)
142
144
  - `.pi/agents/*.md` - Project-level (only with `agentScope: "project"` or `"both"`)
@@ -23,6 +23,42 @@ export interface AgentDiscoveryResult {
23
23
  projectAgentsDir: string | null;
24
24
  }
25
25
 
26
+ /**
27
+ * Raw agent frontmatter. Values are `unknown` because `parseFrontmatter` runs a
28
+ * real YAML parser, so any scalar or collection can appear here.
29
+ *
30
+ * A type alias rather than an interface: `parseFrontmatter` constrains its
31
+ * parameter to `Record<string, unknown>`, and only an alias picks up the
32
+ * implicit index signature that satisfies it.
33
+ */
34
+ type AgentFrontmatter = {
35
+ name?: unknown;
36
+ description?: unknown;
37
+ tools?: unknown;
38
+ model?: unknown;
39
+ };
40
+
41
+ /**
42
+ * Normalize a frontmatter `tools` value to a list of tool names.
43
+ *
44
+ * Both spellings are valid YAML and both are in use:
45
+ *
46
+ * tools: read, bash # string
47
+ * tools: [read, bash] # array
48
+ *
49
+ * so accept either. Anything else (a number, a map, a nested list) yields no
50
+ * tools rather than throwing: this runs inside agent discovery, where a single
51
+ * bad file must not take down every other agent in the same directory.
52
+ */
53
+ function parseToolList(value: unknown): string[] | undefined {
54
+ const raw = Array.isArray(value) ? value : typeof value === "string" ? value.split(",") : [];
55
+ const tools = raw
56
+ .filter((t): t is string => typeof t === "string")
57
+ .map((t) => t.trim())
58
+ .filter(Boolean);
59
+ return tools.length > 0 ? tools : undefined;
60
+ }
61
+
26
62
  function loadAgentsFromDir(dir: string, source: "user" | "project"): AgentConfig[] {
27
63
  const agents: AgentConfig[] = [];
28
64
 
@@ -49,22 +85,17 @@ function loadAgentsFromDir(dir: string, source: "user" | "project"): AgentConfig
49
85
  continue;
50
86
  }
51
87
 
52
- const { frontmatter, body } = parseFrontmatter<Record<string, string>>(content);
88
+ const { frontmatter, body } = parseFrontmatter<AgentFrontmatter>(content);
53
89
 
54
- if (!frontmatter.name || !frontmatter.description) {
90
+ if (typeof frontmatter.name !== "string" || typeof frontmatter.description !== "string") {
55
91
  continue;
56
92
  }
57
93
 
58
- const tools = frontmatter.tools
59
- ?.split(",")
60
- .map((t: string) => t.trim())
61
- .filter(Boolean);
62
-
63
94
  agents.push({
64
95
  name: frontmatter.name,
65
96
  description: frontmatter.description,
66
- tools: tools && tools.length > 0 ? tools : undefined,
67
- model: frontmatter.model,
97
+ tools: parseToolList(frontmatter.tools),
98
+ model: typeof frontmatter.model === "string" ? frontmatter.model : undefined,
68
99
  systemPrompt: body,
69
100
  source,
70
101
  filePath,
@@ -16,7 +16,7 @@ import { spawn } from "node:child_process";
16
16
  import * as fs from "node:fs";
17
17
  import * as os from "node:os";
18
18
  import * as path from "node:path";
19
- import type { AgentToolResult } from "@earendil-works/pi-agent-core";
19
+ import type { AgentToolResult, ThinkingLevel } from "@earendil-works/pi-agent-core";
20
20
  import type { Message } from "@earendil-works/pi-ai";
21
21
  import { StringEnum } from "@earendil-works/pi-ai";
22
22
  import {
@@ -264,8 +264,14 @@ function getPiInvocation(args: string[]): { command: string; args: string[] } {
264
264
 
265
265
  type OnUpdateCallback = (partial: AgentToolResult<SubagentDetails>) => void;
266
266
 
267
+ interface DispatchDefaults {
268
+ model?: string;
269
+ thinkingLevel?: ThinkingLevel;
270
+ }
271
+
267
272
  async function runSingleAgent(
268
273
  defaultCwd: string,
274
+ dispatchDefaults: DispatchDefaults,
269
275
  agents: AgentConfig[],
270
276
  agentName: string,
271
277
  task: string,
@@ -292,7 +298,12 @@ async function runSingleAgent(
292
298
  }
293
299
 
294
300
  const args: string[] = ["--mode", "json", "-p", "--no-session"];
295
- if (agent.model) args.push("--model", agent.model);
301
+ const inheritsDispatchConfig = !agent.model;
302
+ const model = agent.model ?? dispatchDefaults.model;
303
+ if (model) args.push("--model", model);
304
+ if (inheritsDispatchConfig && dispatchDefaults.thinkingLevel) {
305
+ args.push("--thinking", dispatchDefaults.thinkingLevel);
306
+ }
296
307
  if (agent.tools && agent.tools.length > 0) args.push("--tools", agent.tools.join(","));
297
308
 
298
309
  let tmpPromptDir: string | null = null;
@@ -306,7 +317,7 @@ async function runSingleAgent(
306
317
  messages: [],
307
318
  stderr: "",
308
319
  usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },
309
- model: agent.model,
320
+ model,
310
321
  step,
311
322
  };
312
323
 
@@ -471,6 +482,10 @@ export default function (pi: ExtensionAPI) {
471
482
 
472
483
  async execute(_toolCallId, params, signal, onUpdate, ctx) {
473
484
  const agentScope: AgentScope = params.agentScope ?? "user";
485
+ const dispatchDefaults: DispatchDefaults = {
486
+ model: ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : undefined,
487
+ thinkingLevel: ctx.thinkingLevel,
488
+ };
474
489
  const discovery = discoverAgents(ctx.cwd, agentScope);
475
490
  const agents = discovery.agents;
476
491
  const confirmProjectAgents = params.confirmProjectAgents ?? true;
@@ -552,6 +567,7 @@ export default function (pi: ExtensionAPI) {
552
567
 
553
568
  const result = await runSingleAgent(
554
569
  ctx.cwd,
570
+ dispatchDefaults,
555
571
  agents,
556
572
  step.agent,
557
573
  taskWithContext,
@@ -624,6 +640,7 @@ export default function (pi: ExtensionAPI) {
624
640
  const results = await mapWithConcurrencyLimit(params.tasks, MAX_CONCURRENCY, async (t, index) => {
625
641
  const result = await runSingleAgent(
626
642
  ctx.cwd,
643
+ dispatchDefaults,
627
644
  agents,
628
645
  t.agent,
629
646
  t.task,
@@ -666,6 +683,7 @@ export default function (pi: ExtensionAPI) {
666
683
  if (params.agent && params.task) {
667
684
  const result = await runSingleAgent(
668
685
  ctx.cwd,
686
+ dispatchDefaults,
669
687
  agents,
670
688
  params.agent,
671
689
  params.task,
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-with-deps",
3
- "version": "0.84.1",
3
+ "version": "0.84.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-with-deps",
9
- "version": "0.84.1",
9
+ "version": "0.84.2",
10
10
  "dependencies": {
11
11
  "ms": "^2.1.3"
12
12
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-with-deps",
3
3
  "private": true,
4
- "version": "0.84.1",
4
+ "version": "0.84.2",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-coding-agent",
3
- "version": "0.84.1",
3
+ "version": "0.84.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@earendil-works/pi-coding-agent",
9
- "version": "0.84.1",
9
+ "version": "0.84.2",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
- "@earendil-works/pi-agent-core": "^0.84.1",
13
- "@earendil-works/pi-ai": "^0.84.1",
14
- "@earendil-works/pi-client": "^0.84.1",
15
- "@earendil-works/pi-protocol": "^0.84.1",
16
- "@earendil-works/pi-tui": "^0.84.1",
12
+ "@earendil-works/pi-agent-core": "^0.84.2",
13
+ "@earendil-works/pi-ai": "^0.84.2",
14
+ "@earendil-works/pi-client": "^0.84.2",
15
+ "@earendil-works/pi-protocol": "^0.84.2",
16
+ "@earendil-works/pi-tui": "^0.84.2",
17
17
  "@silvia-odwyer/photon-node": "0.3.4",
18
18
  "chalk": "5.6.2",
19
19
  "cross-spawn": "7.0.6",
@@ -477,12 +477,12 @@
477
477
  }
478
478
  },
479
479
  "node_modules/@earendil-works/pi-agent-core": {
480
- "version": "0.84.1",
481
- "resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.84.1.tgz",
480
+ "version": "0.84.2",
481
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.84.2.tgz",
482
482
  "license": "MIT",
483
483
  "dependencies": {
484
- "@earendil-works/pi-ai": "^0.84.1",
485
- "@earendil-works/pi-telemetry": "^0.84.1",
484
+ "@earendil-works/pi-ai": "^0.84.2",
485
+ "@earendil-works/pi-telemetry": "^0.84.2",
486
486
  "diff": "8.0.4",
487
487
  "ignore": "7.0.5",
488
488
  "typebox": "1.3.7",
@@ -493,20 +493,19 @@
493
493
  }
494
494
  },
495
495
  "node_modules/@earendil-works/pi-ai": {
496
- "version": "0.84.1",
497
- "resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.84.1.tgz",
496
+ "version": "0.84.2",
497
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.84.2.tgz",
498
498
  "license": "MIT",
499
499
  "dependencies": {
500
500
  "@anthropic-ai/sdk": "0.91.1",
501
501
  "@aws-sdk/client-bedrock-runtime": "3.1048.0",
502
- "@earendil-works/pi-telemetry": "^0.84.1",
502
+ "@earendil-works/pi-telemetry": "^0.84.2",
503
503
  "@google/genai": "1.52.0",
504
- "@mistralai/mistralai": "2.2.6",
505
504
  "@opentelemetry/api": "1.9.0",
506
505
  "@smithy/node-http-handler": "4.7.3",
507
506
  "http-proxy-agent": "7.0.2",
508
507
  "https-proxy-agent": "7.0.6",
509
- "openai": "6.26.0",
508
+ "openai": "6.40.0",
510
509
  "partial-json": "0.1.7",
511
510
  "typebox": "1.3.7"
512
511
  },
@@ -518,19 +517,19 @@
518
517
  }
519
518
  },
520
519
  "node_modules/@earendil-works/pi-client": {
521
- "version": "0.84.1",
522
- "resolved": "https://registry.npmjs.org/@earendil-works/pi-client/-/pi-client-0.84.1.tgz",
520
+ "version": "0.84.2",
521
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-client/-/pi-client-0.84.2.tgz",
523
522
  "license": "MIT",
524
523
  "dependencies": {
525
- "@earendil-works/pi-protocol": "^0.84.1"
524
+ "@earendil-works/pi-protocol": "^0.84.2"
526
525
  },
527
526
  "engines": {
528
527
  "node": ">=22.19.0"
529
528
  }
530
529
  },
531
530
  "node_modules/@earendil-works/pi-protocol": {
532
- "version": "0.84.1",
533
- "resolved": "https://registry.npmjs.org/@earendil-works/pi-protocol/-/pi-protocol-0.84.1.tgz",
531
+ "version": "0.84.2",
532
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-protocol/-/pi-protocol-0.84.2.tgz",
534
533
  "license": "MIT",
535
534
  "dependencies": {
536
535
  "typebox": "1.3.7"
@@ -540,16 +539,16 @@
540
539
  }
541
540
  },
542
541
  "node_modules/@earendil-works/pi-telemetry": {
543
- "version": "0.84.1",
544
- "resolved": "https://registry.npmjs.org/@earendil-works/pi-telemetry/-/pi-telemetry-0.84.1.tgz",
542
+ "version": "0.84.2",
543
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-telemetry/-/pi-telemetry-0.84.2.tgz",
545
544
  "license": "MIT",
546
545
  "engines": {
547
546
  "node": ">=22.19.0"
548
547
  }
549
548
  },
550
549
  "node_modules/@earendil-works/pi-tui": {
551
- "version": "0.84.1",
552
- "resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.84.1.tgz",
550
+ "version": "0.84.2",
551
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.84.2.tgz",
553
552
  "license": "MIT",
554
553
  "dependencies": {
555
554
  "get-east-asian-width": "1.6.0",
@@ -762,26 +761,6 @@
762
761
  ],
763
762
  "optional": true
764
763
  },
765
- "node_modules/@mistralai/mistralai": {
766
- "version": "2.2.6",
767
- "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-2.2.6.tgz",
768
- "integrity": "sha512-W8pX7zHxjJvMIpw8JMxeJEleapXX0Q9NPszdNzqkM3MIEoIGPObdodujj+WHteXEvGfaP/AMwlNyRfEzSY6dQQ==",
769
- "license": "Apache-2.0",
770
- "dependencies": {
771
- "@opentelemetry/semantic-conventions": "^1.40.0",
772
- "ws": "^8.18.0",
773
- "zod": "^3.25.0 || ^4.0.0",
774
- "zod-to-json-schema": "^3.25.0"
775
- },
776
- "peerDependencies": {
777
- "@opentelemetry/api": "^1.9.0"
778
- },
779
- "peerDependenciesMeta": {
780
- "@opentelemetry/api": {
781
- "optional": true
782
- }
783
- }
784
- },
785
764
  "node_modules/@nodable/entities": {
786
765
  "version": "2.1.0",
787
766
  "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz",
@@ -803,15 +782,6 @@
803
782
  "node": ">=8.0.0"
804
783
  }
805
784
  },
806
- "node_modules/@opentelemetry/semantic-conventions": {
807
- "version": "1.41.1",
808
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.41.1.tgz",
809
- "integrity": "sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==",
810
- "license": "Apache-2.0",
811
- "engines": {
812
- "node": ">=14"
813
- }
814
- },
815
785
  "node_modules/@protobufjs/aspromise": {
816
786
  "version": "1.1.2",
817
787
  "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
@@ -1531,9 +1501,9 @@
1531
1501
  }
1532
1502
  },
1533
1503
  "node_modules/openai": {
1534
- "version": "6.26.0",
1535
- "resolved": "https://registry.npmjs.org/openai/-/openai-6.26.0.tgz",
1536
- "integrity": "sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==",
1504
+ "version": "6.40.0",
1505
+ "resolved": "https://registry.npmjs.org/openai/-/openai-6.40.0.tgz",
1506
+ "integrity": "sha512-MWtTjd/gQt4jpbji61NTgFWJLoY/PdRJ6wG9/ZDRMYNMlBKrCrSlkLI+KgHP1vR1qT6LKSAyAqIxno6lcK9JiA==",
1537
1507
  "license": "Apache-2.0",
1538
1508
  "peerDependencies": {
1539
1509
  "ws": "^8.18.0",
@@ -1546,9 +1516,6 @@
1546
1516
  "zod": {
1547
1517
  "optional": true
1548
1518
  }
1549
- },
1550
- "bin": {
1551
- "openai": "bin/cli"
1552
1519
  }
1553
1520
  },
1554
1521
  "node_modules/p-retry": {
@@ -1846,24 +1813,6 @@
1846
1813
  "funding": {
1847
1814
  "url": "https://github.com/sponsors/eemeli"
1848
1815
  }
1849
- },
1850
- "node_modules/zod": {
1851
- "version": "3.25.76",
1852
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
1853
- "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
1854
- "license": "MIT",
1855
- "funding": {
1856
- "url": "https://github.com/sponsors/colinhacks"
1857
- }
1858
- },
1859
- "node_modules/zod-to-json-schema": {
1860
- "version": "3.25.2",
1861
- "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz",
1862
- "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==",
1863
- "license": "ISC",
1864
- "peerDependencies": {
1865
- "zod": "^3.25.28 || ^4"
1866
- }
1867
1816
  }
1868
1817
  }
1869
1818
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-coding-agent",
3
- "version": "0.84.1",
3
+ "version": "0.84.2",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -43,11 +43,11 @@
43
43
  "prepublishOnly": "npm run clean && npm run build && npm run shrinkwrap"
44
44
  },
45
45
  "dependencies": {
46
- "@earendil-works/pi-agent-core": "^0.84.1",
47
- "@earendil-works/pi-ai": "^0.84.1",
48
- "@earendil-works/pi-client": "^0.84.1",
49
- "@earendil-works/pi-protocol": "^0.84.1",
50
- "@earendil-works/pi-tui": "^0.84.1",
46
+ "@earendil-works/pi-agent-core": "^0.84.2",
47
+ "@earendil-works/pi-ai": "^0.84.2",
48
+ "@earendil-works/pi-client": "^0.84.2",
49
+ "@earendil-works/pi-protocol": "^0.84.2",
50
+ "@earendil-works/pi-tui": "^0.84.2",
51
51
  "@silvia-odwyer/photon-node": "0.3.4",
52
52
  "chalk": "5.6.2",
53
53
  "cross-spawn": "7.0.6",