@earendil-works/pi-coding-agent 0.83.0 → 0.84.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.
Files changed (302) hide show
  1. package/CHANGELOG.md +198 -0
  2. package/README.md +5 -0
  3. package/dist/cli/args.d.ts +2 -0
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +19 -0
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/config-selector.d.ts.map +1 -1
  8. package/dist/cli/config-selector.js +2 -2
  9. package/dist/cli/config-selector.js.map +1 -1
  10. package/dist/cli/credential-print.d.ts +1 -1
  11. package/dist/cli/credential-print.d.ts.map +1 -1
  12. package/dist/cli/credential-print.js +6 -5
  13. package/dist/cli/credential-print.js.map +1 -1
  14. package/dist/cli/experimental/auth.d.ts +16 -0
  15. package/dist/cli/experimental/auth.d.ts.map +1 -0
  16. package/dist/cli/experimental/auth.js +13 -0
  17. package/dist/cli/experimental/auth.js.map +1 -0
  18. package/dist/cli/experimental/cli.d.ts +6 -0
  19. package/dist/cli/experimental/cli.d.ts.map +1 -0
  20. package/dist/cli/experimental/cli.js +5 -0
  21. package/dist/cli/experimental/cli.js.map +1 -0
  22. package/dist/cli/experimental/command-options.d.ts +17 -0
  23. package/dist/cli/experimental/command-options.d.ts.map +1 -0
  24. package/dist/cli/experimental/command-options.js +35 -0
  25. package/dist/cli/experimental/command-options.js.map +1 -0
  26. package/dist/cli/experimental/command.d.ts +63 -0
  27. package/dist/cli/experimental/command.d.ts.map +1 -0
  28. package/dist/cli/experimental/command.js +130 -0
  29. package/dist/cli/experimental/command.js.map +1 -0
  30. package/dist/cli/experimental/commands/client.d.ts +13 -0
  31. package/dist/cli/experimental/commands/client.d.ts.map +1 -0
  32. package/dist/cli/experimental/commands/client.js +25 -0
  33. package/dist/cli/experimental/commands/client.js.map +1 -0
  34. package/dist/cli/experimental/commands/pi.d.ts +15 -0
  35. package/dist/cli/experimental/commands/pi.d.ts.map +1 -0
  36. package/dist/cli/experimental/commands/pi.js +28 -0
  37. package/dist/cli/experimental/commands/pi.js.map +1 -0
  38. package/dist/cli/experimental/commands/server.d.ts +13 -0
  39. package/dist/cli/experimental/commands/server.d.ts.map +1 -0
  40. package/dist/cli/experimental/commands/server.js +25 -0
  41. package/dist/cli/experimental/commands/server.js.map +1 -0
  42. package/dist/cli/experimental/transport-address.d.ts +10 -0
  43. package/dist/cli/experimental/transport-address.d.ts.map +1 -0
  44. package/dist/cli/experimental/transport-address.js +38 -0
  45. package/dist/cli/experimental/transport-address.js.map +1 -0
  46. package/dist/cli/list-models.d.ts +1 -1
  47. package/dist/cli/list-models.d.ts.map +1 -1
  48. package/dist/cli/list-models.js +2 -2
  49. package/dist/cli/list-models.js.map +1 -1
  50. package/dist/cli/startup-ui.d.ts +1 -1
  51. package/dist/cli/startup-ui.d.ts.map +1 -1
  52. package/dist/cli/startup-ui.js +2 -2
  53. package/dist/cli/startup-ui.js.map +1 -1
  54. package/dist/cli.d.ts.map +1 -1
  55. package/dist/cli.js +1 -0
  56. package/dist/cli.js.map +1 -1
  57. package/dist/client/index.d.ts +3 -0
  58. package/dist/client/index.d.ts.map +1 -0
  59. package/dist/client/index.js +3 -0
  60. package/dist/client/index.js.map +1 -0
  61. package/dist/client/remote-session.d.ts +53 -0
  62. package/dist/client/remote-session.d.ts.map +1 -0
  63. package/dist/client/remote-session.js +340 -0
  64. package/dist/client/remote-session.js.map +1 -0
  65. package/dist/client/transcript.d.ts +12 -0
  66. package/dist/client/transcript.d.ts.map +1 -0
  67. package/dist/client/transcript.js +98 -0
  68. package/dist/client/transcript.js.map +1 -0
  69. package/dist/core/agent-session-services.d.ts +1 -0
  70. package/dist/core/agent-session-services.d.ts.map +1 -1
  71. package/dist/core/agent-session-services.js +1 -0
  72. package/dist/core/agent-session-services.js.map +1 -1
  73. package/dist/core/agent-session.d.ts +1 -10
  74. package/dist/core/agent-session.d.ts.map +1 -1
  75. package/dist/core/agent-session.js +72 -70
  76. package/dist/core/agent-session.js.map +1 -1
  77. package/dist/core/auth-storage.d.ts +15 -9
  78. package/dist/core/auth-storage.d.ts.map +1 -1
  79. package/dist/core/auth-storage.js +159 -38
  80. package/dist/core/auth-storage.js.map +1 -1
  81. package/dist/core/extensions/index.d.ts +1 -1
  82. package/dist/core/extensions/index.d.ts.map +1 -1
  83. package/dist/core/extensions/index.js.map +1 -1
  84. package/dist/core/extensions/loader.d.ts.map +1 -1
  85. package/dist/core/extensions/loader.js +43 -20
  86. package/dist/core/extensions/loader.js.map +1 -1
  87. package/dist/core/extensions/runner.d.ts +2 -1
  88. package/dist/core/extensions/runner.d.ts.map +1 -1
  89. package/dist/core/extensions/runner.js +3 -0
  90. package/dist/core/extensions/runner.js.map +1 -1
  91. package/dist/core/extensions/types.d.ts +21 -3
  92. package/dist/core/extensions/types.d.ts.map +1 -1
  93. package/dist/core/extensions/types.js.map +1 -1
  94. package/dist/core/http-dispatcher.d.ts.map +1 -1
  95. package/dist/core/http-dispatcher.js +5 -0
  96. package/dist/core/http-dispatcher.js.map +1 -1
  97. package/dist/core/keybindings.d.ts +36 -4
  98. package/dist/core/keybindings.d.ts.map +1 -1
  99. package/dist/core/model-config.d.ts +29 -5
  100. package/dist/core/model-config.d.ts.map +1 -1
  101. package/dist/core/model-config.js +4 -0
  102. package/dist/core/model-config.js.map +1 -1
  103. package/dist/core/model-registry.d.ts +5 -3
  104. package/dist/core/model-registry.d.ts.map +1 -1
  105. package/dist/core/model-registry.js +13 -10
  106. package/dist/core/model-registry.js.map +1 -1
  107. package/dist/core/model-resolver.d.ts +4 -3
  108. package/dist/core/model-resolver.d.ts.map +1 -1
  109. package/dist/core/model-resolver.js +41 -10
  110. package/dist/core/model-resolver.js.map +1 -1
  111. package/dist/core/model-runtime.d.ts +28 -13
  112. package/dist/core/model-runtime.d.ts.map +1 -1
  113. package/dist/core/model-runtime.js +231 -73
  114. package/dist/core/model-runtime.js.map +1 -1
  115. package/dist/core/models-store.d.ts +12 -7
  116. package/dist/core/models-store.d.ts.map +1 -1
  117. package/dist/core/models-store.js +83 -14
  118. package/dist/core/models-store.js.map +1 -1
  119. package/dist/core/package-manager.d.ts +4 -1
  120. package/dist/core/package-manager.d.ts.map +1 -1
  121. package/dist/core/package-manager.js +63 -36
  122. package/dist/core/package-manager.js.map +1 -1
  123. package/dist/core/pi-manifest.d.ts +8 -0
  124. package/dist/core/pi-manifest.d.ts.map +1 -0
  125. package/dist/core/pi-manifest.js +25 -0
  126. package/dist/core/pi-manifest.js.map +1 -0
  127. package/dist/core/provider-composer.d.ts +4 -1
  128. package/dist/core/provider-composer.d.ts.map +1 -1
  129. package/dist/core/provider-composer.js +36 -15
  130. package/dist/core/provider-composer.js.map +1 -1
  131. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  132. package/dist/core/remote-catalog-provider.js +73 -67
  133. package/dist/core/remote-catalog-provider.js.map +1 -1
  134. package/dist/core/resource-loader.d.ts.map +1 -1
  135. package/dist/core/resource-loader.js +2 -2
  136. package/dist/core/resource-loader.js.map +1 -1
  137. package/dist/core/runtime-credentials.d.ts +5 -5
  138. package/dist/core/runtime-credentials.d.ts.map +1 -1
  139. package/dist/core/runtime-credentials.js +11 -8
  140. package/dist/core/runtime-credentials.js.map +1 -1
  141. package/dist/core/session-manager.d.ts.map +1 -1
  142. package/dist/core/session-manager.js +3 -1
  143. package/dist/core/session-manager.js.map +1 -1
  144. package/dist/core/settings-manager.d.ts +12 -0
  145. package/dist/core/settings-manager.d.ts.map +1 -1
  146. package/dist/core/settings-manager.js +40 -16
  147. package/dist/core/settings-manager.js.map +1 -1
  148. package/dist/core/tools/find.d.ts +3 -0
  149. package/dist/core/tools/find.d.ts.map +1 -1
  150. package/dist/core/tools/find.js +11 -18
  151. package/dist/core/tools/find.js.map +1 -1
  152. package/dist/core/tools/read.d.ts.map +1 -1
  153. package/dist/core/tools/read.js +1 -1
  154. package/dist/core/tools/read.js.map +1 -1
  155. package/dist/extensions/llama/index.d.ts.map +1 -1
  156. package/dist/extensions/llama/index.js +11 -2
  157. package/dist/extensions/llama/index.js.map +1 -1
  158. package/dist/extensions/llama/provider.d.ts.map +1 -1
  159. package/dist/extensions/llama/provider.js +21 -7
  160. package/dist/extensions/llama/provider.js.map +1 -1
  161. package/dist/index.d.ts +4 -4
  162. package/dist/index.d.ts.map +1 -1
  163. package/dist/index.js +1 -1
  164. package/dist/index.js.map +1 -1
  165. package/dist/main.d.ts.map +1 -1
  166. package/dist/main.js +16 -7
  167. package/dist/main.js.map +1 -1
  168. package/dist/modes/index.d.ts +1 -0
  169. package/dist/modes/index.d.ts.map +1 -1
  170. package/dist/modes/index.js.map +1 -1
  171. package/dist/modes/interactive/components/assistant-message.d.ts +5 -2
  172. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  173. package/dist/modes/interactive/components/assistant-message.js +13 -4
  174. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  175. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  176. package/dist/modes/interactive/components/custom-editor.js +7 -0
  177. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  178. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  179. package/dist/modes/interactive/components/footer.js +1 -1
  180. package/dist/modes/interactive/components/footer.js.map +1 -1
  181. package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
  182. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
  183. package/dist/modes/interactive/components/markdown-transform.js +19 -0
  184. package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
  185. package/dist/modes/interactive/components/mermaid.d.ts +11 -0
  186. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
  187. package/dist/modes/interactive/components/mermaid.js +75 -0
  188. package/dist/modes/interactive/components/mermaid.js.map +1 -0
  189. package/dist/modes/interactive/components/model-selector.d.ts +1 -1
  190. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  191. package/dist/modes/interactive/components/model-selector.js +16 -4
  192. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  193. package/dist/modes/interactive/components/scoped-models-selector.d.ts +4 -0
  194. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  195. package/dist/modes/interactive/components/scoped-models-selector.js +26 -0
  196. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  197. package/dist/modes/interactive/components/settings-selector.d.ts +8 -2
  198. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  199. package/dist/modes/interactive/components/settings-selector.js +30 -0
  200. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  201. package/dist/modes/interactive/components/user-message.d.ts +3 -1
  202. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  203. package/dist/modes/interactive/components/user-message.js +9 -2
  204. package/dist/modes/interactive/components/user-message.js.map +1 -1
  205. package/dist/modes/interactive/interactive-mode.d.ts +33 -2
  206. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  207. package/dist/modes/interactive/interactive-mode.js +423 -138
  208. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  209. package/dist/modes/interactive/theme/dark.json +1 -0
  210. package/dist/modes/interactive/theme/light.json +1 -0
  211. package/dist/modes/interactive/theme/theme-controller.d.ts +3 -0
  212. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  213. package/dist/modes/interactive/theme/theme-controller.js +10 -1
  214. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  215. package/dist/modes/interactive/theme/theme-schema.json +5 -1
  216. package/dist/modes/interactive/theme/theme.d.ts +2 -2
  217. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  218. package/dist/modes/interactive/theme/theme.js +13 -3
  219. package/dist/modes/interactive/theme/theme.js.map +1 -1
  220. package/dist/modes/json-event.d.ts +28 -0
  221. package/dist/modes/json-event.d.ts.map +1 -0
  222. package/dist/modes/json-event.js +12 -0
  223. package/dist/modes/json-event.js.map +1 -0
  224. package/dist/modes/print-mode.d.ts.map +1 -1
  225. package/dist/modes/print-mode.js +12 -2
  226. package/dist/modes/print-mode.js.map +1 -1
  227. package/dist/modes/rpc/rpc-client.d.ts +5 -4
  228. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  229. package/dist/modes/rpc/rpc-client.js.map +1 -1
  230. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  231. package/dist/modes/rpc/rpc-mode.js +4 -3
  232. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  233. package/dist/package-manager-cli.d.ts.map +1 -1
  234. package/dist/package-manager-cli.js +11 -9
  235. package/dist/package-manager-cli.js.map +1 -1
  236. package/dist/rpc-entry.d.ts.map +1 -1
  237. package/dist/rpc-entry.js +1 -0
  238. package/dist/rpc-entry.js.map +1 -1
  239. package/dist/utils/abort.d.ts +5 -0
  240. package/dist/utils/abort.d.ts.map +1 -0
  241. package/dist/utils/abort.js +48 -0
  242. package/dist/utils/abort.js.map +1 -0
  243. package/dist/utils/clipboard.d.ts +1 -1
  244. package/dist/utils/clipboard.d.ts.map +1 -1
  245. package/dist/utils/clipboard.js +22 -2
  246. package/dist/utils/clipboard.js.map +1 -1
  247. package/dist/utils/management-http.d.ts +23 -0
  248. package/dist/utils/management-http.d.ts.map +1 -0
  249. package/dist/utils/management-http.js +50 -0
  250. package/dist/utils/management-http.js.map +1 -0
  251. package/dist/utils/paths.d.ts +3 -0
  252. package/dist/utils/paths.d.ts.map +1 -1
  253. package/dist/utils/paths.js +23 -1
  254. package/dist/utils/paths.js.map +1 -1
  255. package/dist/utils/tool-result-images.d.ts +19 -0
  256. package/dist/utils/tool-result-images.d.ts.map +1 -0
  257. package/dist/utils/tool-result-images.js +45 -0
  258. package/dist/utils/tool-result-images.js.map +1 -0
  259. package/dist/utils/tools-manager.d.ts.map +1 -1
  260. package/dist/utils/tools-manager.js +4 -6
  261. package/dist/utils/tools-manager.js.map +1 -1
  262. package/dist/utils/version-check.d.ts +4 -0
  263. package/dist/utils/version-check.d.ts.map +1 -1
  264. package/dist/utils/version-check.js +20 -2
  265. package/dist/utils/version-check.js.map +1 -1
  266. package/docs/compaction.md +2 -2
  267. package/docs/custom-provider.md +7 -5
  268. package/docs/extensions.md +27 -3
  269. package/docs/json.md +19 -14
  270. package/docs/keybindings.md +38 -10
  271. package/docs/models.md +24 -3
  272. package/docs/providers.md +1 -0
  273. package/docs/quickstart.md +2 -0
  274. package/docs/rpc.md +13 -11
  275. package/docs/sdk.md +21 -2
  276. package/docs/security.md +1 -1
  277. package/docs/settings.md +4 -1
  278. package/docs/themes.md +5 -3
  279. package/docs/usage.md +7 -0
  280. package/examples/extensions/custom-compaction.ts +1 -16
  281. package/examples/extensions/custom-provider-anthropic/index.ts +2 -1
  282. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  283. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  284. package/examples/extensions/custom-provider-gitlab-duo/index.ts +2 -1
  285. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  286. package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
  287. package/examples/extensions/gondolin/package-lock.json +2 -2
  288. package/examples/extensions/gondolin/package.json +1 -1
  289. package/examples/extensions/handoff.ts +2 -11
  290. package/examples/extensions/qna.ts +3 -7
  291. package/examples/extensions/sandbox/package-lock.json +2 -2
  292. package/examples/extensions/sandbox/package.json +1 -1
  293. package/examples/extensions/summarize.ts +7 -18
  294. package/examples/extensions/with-deps/package-lock.json +2 -2
  295. package/examples/extensions/with-deps/package.json +1 -1
  296. package/examples/rpc-extension-ui.ts +11 -2
  297. package/examples/sdk/02-custom-model.ts +1 -2
  298. package/examples/sdk/09-api-keys-and-oauth.ts +1 -1
  299. package/examples/sdk/12-full-control.ts +1 -1
  300. package/examples/sdk/README.md +1 -1
  301. package/npm-shrinkwrap.json +64 -20
  302. package/package.json +13 -6
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider-anthropic",
3
3
  "private": true,
4
- "version": "0.83.0",
4
+ "version": "0.84.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -274,7 +274,7 @@ async function loginGitLab(callbacks: OAuthLoginCallbacks): Promise<OAuthCredent
274
274
  };
275
275
  }
276
276
 
277
- async function refreshGitLabToken(credentials: OAuthCredentials): Promise<OAuthCredentials> {
277
+ async function refreshGitLabToken(credentials: OAuthCredentials, signal: AbortSignal): Promise<OAuthCredentials> {
278
278
  const response = await fetch(`${GITLAB_COM_URL}/oauth/token`, {
279
279
  method: "POST",
280
280
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
@@ -283,6 +283,7 @@ async function refreshGitLabToken(credentials: OAuthCredentials): Promise<OAuthC
283
283
  grant_type: "refresh_token",
284
284
  refresh_token: credentials.refresh,
285
285
  }).toString(),
286
+ signal,
286
287
  });
287
288
  if (!response.ok) throw new Error(`Token refresh failed: ${await response.text()}`);
288
289
  const data = (await response.json()) as {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider-gitlab-duo",
3
3
  "private": true,
4
- "version": "0.83.0",
4
+ "version": "0.84.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,11 +1,12 @@
1
1
  import { existsSync, writeFileSync } from "node:fs";
2
2
  import { dirname, join, resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
+ import { gunzipSync } from "node:zlib";
4
5
 
5
6
  // Get the bundled WAD path (relative to this module)
6
7
  const __dirname = dirname(fileURLToPath(import.meta.url));
7
8
  const BUNDLED_WAD = join(__dirname, "doom1.wad");
8
- const WAD_URL = "https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad";
9
+ const WAD_URL = "https://www.gamers.org/pub/idgames/idstuff/doom/doom-1.8.wad.gz";
9
10
 
10
11
  const DEFAULT_WAD_PATHS = ["./doom1.wad", "./DOOM1.WAD", "~/doom1.wad", "~/.doom/doom1.wad"];
11
12
 
@@ -42,8 +43,11 @@ export async function ensureWadFile(): Promise<string | null> {
42
43
  if (!response.ok) {
43
44
  throw new Error(`HTTP ${response.status}`);
44
45
  }
45
- const buffer = await response.arrayBuffer();
46
- writeFileSync(BUNDLED_WAD, Buffer.from(buffer));
46
+ const wad = gunzipSync(Buffer.from(await response.arrayBuffer()));
47
+ if (wad.subarray(0, 4).toString("ascii") !== "IWAD") {
48
+ throw new Error("Downloaded file is not a valid IWAD");
49
+ }
50
+ writeFileSync(BUNDLED_WAD, wad);
47
51
  return BUNDLED_WAD;
48
52
  } catch {
49
53
  return null;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-gondolin",
3
- "version": "0.83.0",
3
+ "version": "0.84.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-gondolin",
9
- "version": "0.83.0",
9
+ "version": "0.84.0",
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.83.0",
4
+ "version": "0.84.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -13,8 +13,7 @@
13
13
  */
14
14
 
15
15
  import type { AgentMessage } from "@earendil-works/pi-agent-core";
16
- import { uuidv7 } from "@earendil-works/pi-ai";
17
- import { complete, type Message } from "@earendil-works/pi-ai/compat";
16
+ import { type Message, uuidv7 } from "@earendil-works/pi-ai";
18
17
  import type { ExtensionAPI, SessionEntry } from "@earendil-works/pi-coding-agent";
19
18
  import { BorderedLoader, convertToLlm, serializeConversation } from "@earendil-works/pi-coding-agent";
20
19
 
@@ -118,11 +117,6 @@ export default function (pi: ExtensionAPI) {
118
117
  loader.onAbort = () => done(null);
119
118
 
120
119
  const doGenerate = async () => {
121
- const auth = await ctx.modelRegistry.getApiKeyAndHeaders(ctx.model!);
122
- if (!auth.ok || !auth.apiKey) {
123
- throw new Error(auth.ok ? `No API key for ${ctx.model!.provider}` : auth.error);
124
- }
125
-
126
120
  const userMessage: Message = {
127
121
  role: "user",
128
122
  content: [
@@ -134,13 +128,10 @@ export default function (pi: ExtensionAPI) {
134
128
  timestamp: Date.now(),
135
129
  };
136
130
 
137
- const response = await complete(
131
+ const response = await ctx.modelRegistry.complete(
138
132
  ctx.model!,
139
133
  { systemPrompt: SYSTEM_PROMPT, messages: [userMessage] },
140
134
  {
141
- apiKey: auth.apiKey,
142
- headers: auth.headers,
143
- env: auth.env,
144
135
  signal: loader.signal,
145
136
  cacheRetention: "none",
146
137
  sessionId: uuidv7(),
@@ -7,7 +7,7 @@
7
7
  * 3. Loads the result into the editor for user to fill in answers
8
8
  */
9
9
 
10
- import { complete, type UserMessage } from "@earendil-works/pi-ai/compat";
10
+ import type { UserMessage } from "@earendil-works/pi-ai";
11
11
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
12
12
  import { BorderedLoader } from "@earendil-works/pi-coding-agent";
13
13
 
@@ -77,20 +77,16 @@ export default function (pi: ExtensionAPI) {
77
77
 
78
78
  // Do the work
79
79
  const doExtract = async () => {
80
- const auth = await ctx.modelRegistry.getApiKeyAndHeaders(ctx.model!);
81
- if (!auth.ok || !auth.apiKey) {
82
- throw new Error(auth.ok ? `No API key for ${ctx.model!.provider}` : auth.error);
83
- }
84
80
  const userMessage: UserMessage = {
85
81
  role: "user",
86
82
  content: [{ type: "text", text: lastAssistantText! }],
87
83
  timestamp: Date.now(),
88
84
  };
89
85
 
90
- const response = await complete(
86
+ const response = await ctx.modelRegistry.complete(
91
87
  ctx.model!,
92
88
  { systemPrompt: SYSTEM_PROMPT, messages: [userMessage] },
93
- { apiKey: auth.apiKey, headers: auth.headers, env: auth.env, signal: loader.signal },
89
+ { signal: loader.signal },
94
90
  );
95
91
 
96
92
  if (response.stopReason === "aborted") {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-sandbox",
3
- "version": "1.13.0",
3
+ "version": "1.14.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-sandbox",
9
- "version": "1.13.0",
9
+ "version": "1.14.0",
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.13.0",
4
+ "version": "1.14.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,5 +1,4 @@
1
1
  import { uuidv7 } from "@earendil-works/pi-ai";
2
- import { complete, getModel } from "@earendil-works/pi-ai/compat";
3
2
  import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
4
3
  import { DynamicBorder, getMarkdownTheme } from "@earendil-works/pi-coding-agent";
5
4
  import { Container, Markdown, matchesKey, Text } from "@earendil-works/pi-tui";
@@ -161,20 +160,13 @@ export default function (pi: ExtensionAPI) {
161
160
  ctx.ui.notify("Preparing summary...", "info");
162
161
  }
163
162
 
164
- const model = getModel("openai", "gpt-5.2");
165
- if (!model && ctx.hasUI) {
166
- ctx.ui.notify("Model openai/gpt-5.2 not found", "warning");
167
- }
168
-
169
- const auth = model ? await ctx.modelRegistry.getApiKeyAndHeaders(model) : undefined;
170
- if (auth && !auth.ok && ctx.hasUI) {
171
- ctx.ui.notify(auth.error, "warning");
172
- }
173
- if (auth?.ok && !auth.apiKey && ctx.hasUI) {
174
- ctx.ui.notify("No API key for openai/gpt-5.2", "warning");
163
+ const model = ctx.modelRegistry.find("openai", "gpt-5.2");
164
+ if (!model) {
165
+ if (ctx.hasUI) ctx.ui.notify("Model openai/gpt-5.2 not found", "warning");
166
+ return;
175
167
  }
176
-
177
- if (!model || !auth?.ok || !auth.apiKey) {
168
+ if (!ctx.modelRegistry.hasConfiguredAuth(model)) {
169
+ if (ctx.hasUI) ctx.ui.notify("No authentication configured for openai/gpt-5.2", "warning");
178
170
  return;
179
171
  }
180
172
 
@@ -186,13 +178,10 @@ export default function (pi: ExtensionAPI) {
186
178
  },
187
179
  ];
188
180
 
189
- const response = await complete(
181
+ const response = await ctx.modelRegistry.complete(
190
182
  model,
191
183
  { messages: summaryMessages },
192
184
  {
193
- apiKey: auth.apiKey,
194
- headers: auth.headers,
195
- env: auth.env,
196
185
  reasoningEffort: "high",
197
186
  cacheRetention: "none",
198
187
  sessionId: uuidv7(),
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-with-deps",
3
- "version": "0.83.0",
3
+ "version": "0.84.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-with-deps",
9
- "version": "0.83.0",
9
+ "version": "0.84.0",
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.83.0",
4
+ "version": "0.84.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -18,7 +18,16 @@ import { spawn } from "node:child_process";
18
18
  import { dirname, join } from "node:path";
19
19
  import * as readline from "node:readline";
20
20
  import { fileURLToPath } from "node:url";
21
- import { type Component, Container, Input, matchesKey, ProcessTerminal, SelectList, TUI } from "@earendil-works/pi-tui";
21
+ import {
22
+ type Component,
23
+ Container,
24
+ Input,
25
+ matchesKey,
26
+ ProcessTerminal,
27
+ SelectList,
28
+ type TUI,
29
+ TuiMainScreen,
30
+ } from "@earendil-works/pi-tui";
22
31
 
23
32
  const __dirname = dirname(fileURLToPath(import.meta.url));
24
33
 
@@ -267,7 +276,7 @@ async function main() {
267
276
  // -- TUI setup --
268
277
 
269
278
  const terminal = new ProcessTerminal();
270
- const tui = new TUI(terminal);
279
+ const tui: TUI = new TuiMainScreen(terminal);
271
280
 
272
281
  const outputLog = new OutputLog();
273
282
  const loadingIndicator = new LoadingIndicator();
@@ -4,13 +4,12 @@
4
4
  * Shows how to select a specific model and thinking level.
5
5
  */
6
6
 
7
- import { getModel } from "@earendil-works/pi-ai/compat";
8
7
  import { createAgentSession, ModelRuntime } from "@earendil-works/pi-coding-agent";
9
8
 
10
9
  const modelRuntime = await ModelRuntime.create();
11
10
 
12
11
  // Option 1: Find a specific built-in model by provider/id
13
- const opus = getModel("anthropic", "claude-opus-4-5");
12
+ const opus = modelRuntime.getModel("anthropic", "claude-opus-4-5");
14
13
  if (opus) {
15
14
  console.log(`Found model: ${opus.provider}/${opus.id}`);
16
15
  }
@@ -25,7 +25,7 @@ const { session: customAuthSession } = await createAgentSession({
25
25
  console.log("Session with custom auth and models locations");
26
26
  customAuthSession.dispose();
27
27
 
28
- modelRuntime.setRuntimeApiKey("anthropic", "sk-my-temp-key");
28
+ await modelRuntime.setRuntimeApiKey("anthropic", "sk-my-temp-key");
29
29
  const { session: runtimeKeySession } = await createAgentSession({
30
30
  sessionManager: SessionManager.inMemory(),
31
31
  modelRuntime,
@@ -19,7 +19,7 @@ const modelRuntime = await ModelRuntime.create({
19
19
  modelsPath: "/tmp/my-agent/models.json",
20
20
  });
21
21
  if (process.env.MY_ANTHROPIC_KEY) {
22
- modelRuntime.setRuntimeApiKey("anthropic", process.env.MY_ANTHROPIC_KEY);
22
+ await modelRuntime.setRuntimeApiKey("anthropic", process.env.MY_ANTHROPIC_KEY);
23
23
  }
24
24
 
25
25
  const model = getModel("anthropic", "claude-sonnet-4-5");
@@ -71,7 +71,7 @@ const customRuntime = await ModelRuntime.create({
71
71
  authPath: "/my/app/auth.json",
72
72
  modelsPath: "/my/app/models.json",
73
73
  });
74
- customRuntime.setRuntimeApiKey("anthropic", process.env.MY_KEY!);
74
+ await customRuntime.setRuntimeApiKey("anthropic", process.env.MY_KEY!);
75
75
 
76
76
  const resourceLoader = new DefaultResourceLoader({
77
77
  systemPromptOverride: () => "You are helpful.",
@@ -1,22 +1,25 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-coding-agent",
3
- "version": "0.83.0",
3
+ "version": "0.84.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@earendil-works/pi-coding-agent",
9
- "version": "0.83.0",
9
+ "version": "0.84.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
- "@earendil-works/pi-agent-core": "^0.83.0",
13
- "@earendil-works/pi-ai": "^0.83.0",
14
- "@earendil-works/pi-tui": "^0.83.0",
12
+ "@earendil-works/pi-agent-core": "^0.84.0",
13
+ "@earendil-works/pi-ai": "^0.84.0",
14
+ "@earendil-works/pi-client": "^0.84.0",
15
+ "@earendil-works/pi-protocol": "^0.84.0",
16
+ "@earendil-works/pi-tui": "^0.84.0",
15
17
  "@silvia-odwyer/photon-node": "0.3.4",
16
18
  "chalk": "5.6.2",
17
19
  "cross-spawn": "7.0.6",
18
20
  "diff": "8.0.4",
19
21
  "glob": "13.0.6",
22
+ "grok-mermaid": "0.2.2",
20
23
  "highlight.js": "10.7.3",
21
24
  "hosted-git-info": "9.0.3",
22
25
  "ignore": "7.0.5",
@@ -25,7 +28,7 @@
25
28
  "proper-lockfile": "4.1.2",
26
29
  "semver": "7.8.0",
27
30
  "typebox": "1.3.7",
28
- "undici": "8.5.0",
31
+ "undici": "8.9.0",
29
32
  "yaml": "2.9.0"
30
33
  },
31
34
  "optionalDependencies": {
@@ -474,11 +477,12 @@
474
477
  }
475
478
  },
476
479
  "node_modules/@earendil-works/pi-agent-core": {
477
- "version": "0.83.0",
478
- "resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.83.0.tgz",
480
+ "version": "0.84.0",
481
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.84.0.tgz",
479
482
  "license": "MIT",
480
483
  "dependencies": {
481
- "@earendil-works/pi-ai": "^0.83.0",
484
+ "@earendil-works/pi-ai": "^0.84.0",
485
+ "@earendil-works/pi-telemetry": "^0.84.0",
482
486
  "diff": "8.0.4",
483
487
  "ignore": "7.0.5",
484
488
  "typebox": "1.3.7",
@@ -489,12 +493,13 @@
489
493
  }
490
494
  },
491
495
  "node_modules/@earendil-works/pi-ai": {
492
- "version": "0.83.0",
493
- "resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.83.0.tgz",
496
+ "version": "0.84.0",
497
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.84.0.tgz",
494
498
  "license": "MIT",
495
499
  "dependencies": {
496
500
  "@anthropic-ai/sdk": "0.91.1",
497
501
  "@aws-sdk/client-bedrock-runtime": "3.1048.0",
502
+ "@earendil-works/pi-telemetry": "^0.84.0",
498
503
  "@google/genai": "1.52.0",
499
504
  "@mistralai/mistralai": "2.2.6",
500
505
  "@opentelemetry/api": "1.9.0",
@@ -512,9 +517,39 @@
512
517
  "node": ">=22.19.0"
513
518
  }
514
519
  },
520
+ "node_modules/@earendil-works/pi-client": {
521
+ "version": "0.84.0",
522
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-client/-/pi-client-0.84.0.tgz",
523
+ "license": "MIT",
524
+ "dependencies": {
525
+ "@earendil-works/pi-protocol": "^0.84.0"
526
+ },
527
+ "engines": {
528
+ "node": ">=22.19.0"
529
+ }
530
+ },
531
+ "node_modules/@earendil-works/pi-protocol": {
532
+ "version": "0.84.0",
533
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-protocol/-/pi-protocol-0.84.0.tgz",
534
+ "license": "MIT",
535
+ "dependencies": {
536
+ "typebox": "1.3.7"
537
+ },
538
+ "engines": {
539
+ "node": ">=22.19.0"
540
+ }
541
+ },
542
+ "node_modules/@earendil-works/pi-telemetry": {
543
+ "version": "0.84.0",
544
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-telemetry/-/pi-telemetry-0.84.0.tgz",
545
+ "license": "MIT",
546
+ "engines": {
547
+ "node": ">=22.19.0"
548
+ }
549
+ },
515
550
  "node_modules/@earendil-works/pi-tui": {
516
- "version": "0.83.0",
517
- "resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.83.0.tgz",
551
+ "version": "0.84.0",
552
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.84.0.tgz",
518
553
  "license": "MIT",
519
554
  "dependencies": {
520
555
  "get-east-asian-width": "1.6.0",
@@ -1023,15 +1058,15 @@
1023
1058
  "license": "MIT"
1024
1059
  },
1025
1060
  "node_modules/brace-expansion": {
1026
- "version": "5.0.7",
1027
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz",
1028
- "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==",
1061
+ "version": "5.0.9",
1062
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
1063
+ "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
1029
1064
  "license": "MIT",
1030
1065
  "dependencies": {
1031
1066
  "balanced-match": "^4.0.2"
1032
1067
  },
1033
1068
  "engines": {
1034
- "node": "18 || 20 || >=22"
1069
+ "node": "20 || >=22"
1035
1070
  }
1036
1071
  },
1037
1072
  "node_modules/buffer-equal-constant-time": {
@@ -1277,6 +1312,15 @@
1277
1312
  "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
1278
1313
  "license": "ISC"
1279
1314
  },
1315
+ "node_modules/grok-mermaid": {
1316
+ "version": "0.2.2",
1317
+ "resolved": "https://registry.npmjs.org/grok-mermaid/-/grok-mermaid-0.2.2.tgz",
1318
+ "integrity": "sha512-XcJEP5dDC8liHBh52mlLjU18fNvu1ckFsu0QpIG3+APZ270fsj9wxpiA6cOURmbUEuoMVgjbC2+UYgTdCqqgzA==",
1319
+ "license": "Apache-2.0",
1320
+ "engines": {
1321
+ "node": ">=18"
1322
+ }
1323
+ },
1280
1324
  "node_modules/highlight.js": {
1281
1325
  "version": "10.7.3",
1282
1326
  "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
@@ -1714,9 +1758,9 @@
1714
1758
  "license": "MIT"
1715
1759
  },
1716
1760
  "node_modules/undici": {
1717
- "version": "8.5.0",
1718
- "resolved": "https://registry.npmjs.org/undici/-/undici-8.5.0.tgz",
1719
- "integrity": "sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==",
1761
+ "version": "8.9.0",
1762
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.9.0.tgz",
1763
+ "integrity": "sha512-aWZpUj7XoGonMClx4gdDRfgBjqeA+F473aDmROQQbM9n6PRfK/u1q/a0X4wMTgcHfT8H6fpbt98PFuDUwFg2YA==",
1720
1764
  "license": "MIT",
1721
1765
  "engines": {
1722
1766
  "node": ">=22.19.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-coding-agent",
3
- "version": "0.83.0",
3
+ "version": "0.84.0",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -18,6 +18,10 @@
18
18
  },
19
19
  "./rpc-entry": {
20
20
  "import": "./dist/rpc-entry.js"
21
+ },
22
+ "./client": {
23
+ "types": "./dist/client/index.d.ts",
24
+ "import": "./dist/client/index.js"
21
25
  }
22
26
  },
23
27
  "files": [
@@ -31,7 +35,7 @@
31
35
  "scripts": {
32
36
  "clean": "shx rm -rf dist",
33
37
  "build": "tsgo -p tsconfig.build.json && shx chmod +x dist/cli.js dist/rpc-entry.js && npm run copy-assets",
34
- "build:binary": "npm --prefix ../tui run build && npm --prefix ../ai run build && npm --prefix ../agent run build && npm run build && bun build --compile ./dist/bun/cli.js ./src/utils/image-resize-worker.ts --outfile dist/pi && npm run copy-binary-assets",
38
+ "build:binary": "npm --prefix ../tui run build && npm --prefix ../telemetry run build && npm --prefix ../ai run build && npm --prefix ../agent run build && npm --prefix ../protocol run build && npm --prefix ../client run build && npm run build && bun build --compile ./dist/bun/cli.js ./src/utils/image-resize-worker.ts --outfile dist/pi && npm run copy-binary-assets",
35
39
  "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/",
36
40
  "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/",
37
41
  "test": "vitest --run",
@@ -39,14 +43,17 @@
39
43
  "prepublishOnly": "npm run clean && npm run build && npm run shrinkwrap"
40
44
  },
41
45
  "dependencies": {
42
- "@earendil-works/pi-agent-core": "^0.83.0",
43
- "@earendil-works/pi-ai": "^0.83.0",
44
- "@earendil-works/pi-tui": "^0.83.0",
46
+ "@earendil-works/pi-agent-core": "^0.84.0",
47
+ "@earendil-works/pi-ai": "^0.84.0",
48
+ "@earendil-works/pi-client": "^0.84.0",
49
+ "@earendil-works/pi-protocol": "^0.84.0",
50
+ "@earendil-works/pi-tui": "^0.84.0",
45
51
  "@silvia-odwyer/photon-node": "0.3.4",
46
52
  "chalk": "5.6.2",
47
53
  "cross-spawn": "7.0.6",
48
54
  "diff": "8.0.4",
49
55
  "glob": "13.0.6",
56
+ "grok-mermaid": "0.2.2",
50
57
  "highlight.js": "10.7.3",
51
58
  "hosted-git-info": "9.0.3",
52
59
  "ignore": "7.0.5",
@@ -55,7 +62,7 @@
55
62
  "proper-lockfile": "4.1.2",
56
63
  "semver": "7.8.0",
57
64
  "typebox": "1.3.7",
58
- "undici": "8.5.0",
65
+ "undici": "8.9.0",
59
66
  "yaml": "2.9.0"
60
67
  },
61
68
  "overrides": {