@astralyn/pi 1.4.11 → 1.5.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 (546) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/dist/bundle/chunks/anthropic-messages-G5ZGBHOH.js +6 -0
  3. package/dist/bundle/chunks/azure-openai-responses-EMPTMYNF.js +2 -0
  4. package/dist/bundle/chunks/bedrock-converse-stream.js +22 -15
  5. package/dist/bundle/chunks/chunk-AXX7FFFD.js +2 -0
  6. package/dist/bundle/chunks/chunk-FNGB3ASD.js +2 -0
  7. package/dist/bundle/chunks/chunk-FPALVF3F.js +4 -0
  8. package/dist/bundle/chunks/chunk-H3UF54OB.js +9 -0
  9. package/dist/bundle/chunks/chunk-IC6JXX2J.js +10 -0
  10. package/dist/bundle/chunks/{chunk-TH3QDDPD.js → chunk-IRUUTK4W.js} +1 -1
  11. package/dist/bundle/chunks/{chunk-MZJC45TM.js → chunk-J7L6O5XA.js} +3 -3
  12. package/dist/bundle/chunks/{chunk-DLVLAQEG.js → chunk-KBFO53OG.js} +3 -3
  13. package/dist/bundle/chunks/{chunk-TPVFPFJP.js → chunk-P7VXFB2M.js} +1 -1
  14. package/dist/bundle/chunks/chunk-PSYLMRL6.js +9 -0
  15. package/dist/bundle/chunks/chunk-QNZARXLE.js +82 -0
  16. package/dist/bundle/chunks/chunk-R3YHAMWH.js +1503 -0
  17. package/dist/bundle/chunks/chunk-RAIYJ5FC.js +4 -0
  18. package/dist/bundle/chunks/{chunk-OV2VMHBX.js → chunk-SR6EWNPW.js} +1 -1
  19. package/dist/bundle/chunks/chunk-TA3YH2ZI.js +16 -0
  20. package/dist/bundle/chunks/{chunk-NUQMVNKQ.js → chunk-THAJ4BZF.js} +58 -62
  21. package/dist/bundle/chunks/{chunk-24FY4C5S.js → chunk-TRSJS3FM.js} +1 -1
  22. package/dist/bundle/chunks/chunk-ZRI3ICDE.js +2 -0
  23. package/dist/bundle/chunks/{cli-MBFCFGI2.js → cli-LAZQG54B.js} +11 -9
  24. package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-7BKATOEJ.js → cloudflare-workers-ai-system-one-4L2ABUJE.js} +1 -1
  25. package/dist/bundle/chunks/{execute-VLAIP26K.js → execute-ACWDKC3C.js} +1 -1
  26. package/dist/bundle/chunks/github-copilot.js +1 -1
  27. package/dist/bundle/chunks/{google-generative-ai-HTUSU45F.js → google-generative-ai-OOVDGS5W.js} +1 -1
  28. package/dist/bundle/chunks/{google-vertex-AVQV4P76.js → google-vertex-IK5RNG7J.js} +1 -1
  29. package/dist/bundle/chunks/image-resize-worker.js +1 -1
  30. package/dist/bundle/chunks/kimi-coding.js +1 -1
  31. package/dist/bundle/chunks/{llama-cpp-classify-27QYLJZY.js → llama-cpp-classify-XHAVT37C.js} +1 -1
  32. package/dist/bundle/chunks/meta.js +1 -1
  33. package/dist/bundle/chunks/mistral-conversations-Z56KY4OJ.js +5 -0
  34. package/dist/bundle/chunks/{openai-codex-responses-Q25MHDFX.js → openai-codex-responses-5NAH3SK6.js} +1 -1
  35. package/dist/bundle/chunks/openai-completions-S7S6PO3J.js +7 -0
  36. package/dist/bundle/chunks/{openai-decisions-3WYFPGSK.js → openai-decisions-7A36EAHE.js} +1 -1
  37. package/dist/bundle/chunks/{openai-responses-E4BNZIQK.js → openai-responses-ZQRZJKH4.js} +1 -1
  38. package/dist/bundle/chunks/{openrouter-images-CBP3OPOD.js → openrouter-images-X7PX72ON.js} +1 -1
  39. package/dist/bundle/chunks/pi-messages-TXNWPLI4.js +8 -0
  40. package/dist/bundle/chunks/radius.js +1 -1
  41. package/dist/bundle/chunks/{runtime-3RPOJS5T.js → runtime-X3XOMNXQ.js} +1 -1
  42. package/dist/bundle/chunks/{typesafe-system-one-BNICP2LS.js → typesafe-system-one-XJGMSHWL.js} +1 -1
  43. package/dist/bundle/chunks/virtual-modules-T2KLVAFL.js +2 -0
  44. package/dist/bundle/cli.js +1 -1
  45. package/dist/bundle/index.js +1 -1
  46. package/dist/bundle/rpc-entry.js +1 -1
  47. package/dist/cli/args.d.ts.map +1 -1
  48. package/dist/cli/args.js +8 -7
  49. package/dist/cli/args.js.map +1 -1
  50. package/dist/config.d.ts +10 -0
  51. package/dist/config.d.ts.map +1 -1
  52. package/dist/config.js +24 -5
  53. package/dist/config.js.map +1 -1
  54. package/dist/core/agent-session-runtime.d.ts +0 -5
  55. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  56. package/dist/core/agent-session-runtime.js +12 -28
  57. package/dist/core/agent-session-runtime.js.map +1 -1
  58. package/dist/core/agent-session.d.ts +21 -14
  59. package/dist/core/agent-session.d.ts.map +1 -1
  60. package/dist/core/agent-session.js +67 -93
  61. package/dist/core/agent-session.js.map +1 -1
  62. package/dist/core/compaction/branch-summarization.d.ts +4 -2
  63. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  64. package/dist/core/compaction/branch-summarization.js +16 -4
  65. package/dist/core/compaction/branch-summarization.js.map +1 -1
  66. package/dist/core/exec.d.ts +9 -1
  67. package/dist/core/exec.d.ts.map +1 -1
  68. package/dist/core/exec.js +104 -60
  69. package/dist/core/exec.js.map +1 -1
  70. package/dist/core/export-html/template.css +9 -0
  71. package/dist/core/export-html/template.js +165 -45
  72. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  73. package/dist/core/export-html/tool-renderer.js +5 -0
  74. package/dist/core/export-html/tool-renderer.js.map +1 -1
  75. package/dist/core/extensions/index.d.ts +1 -1
  76. package/dist/core/extensions/index.d.ts.map +1 -1
  77. package/dist/core/extensions/index.js.map +1 -1
  78. package/dist/core/extensions/loader.d.ts.map +1 -1
  79. package/dist/core/extensions/loader.js +7 -6
  80. package/dist/core/extensions/loader.js.map +1 -1
  81. package/dist/core/extensions/pi-ai-extension-view.d.ts +19 -0
  82. package/dist/core/extensions/pi-ai-extension-view.d.ts.map +1 -0
  83. package/dist/core/extensions/pi-ai-extension-view.js +22 -0
  84. package/dist/core/extensions/pi-ai-extension-view.js.map +1 -0
  85. package/dist/core/extensions/runner.d.ts +0 -1
  86. package/dist/core/extensions/runner.d.ts.map +1 -1
  87. package/dist/core/extensions/runner.js +7 -12
  88. package/dist/core/extensions/runner.js.map +1 -1
  89. package/dist/core/extensions/types.d.ts +41 -23
  90. package/dist/core/extensions/types.d.ts.map +1 -1
  91. package/dist/core/extensions/types.js.map +1 -1
  92. package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
  93. package/dist/core/extensions/virtual-modules.js +8 -7
  94. package/dist/core/extensions/virtual-modules.js.map +1 -1
  95. package/dist/core/mcp-servers.d.ts +11 -4
  96. package/dist/core/mcp-servers.d.ts.map +1 -1
  97. package/dist/core/mcp-servers.js +15 -5
  98. package/dist/core/mcp-servers.js.map +1 -1
  99. package/dist/core/model-config.d.ts +1678 -2029
  100. package/dist/core/model-config.d.ts.map +1 -1
  101. package/dist/core/model-config.js +2 -3
  102. package/dist/core/model-config.js.map +1 -1
  103. package/dist/core/model-resolver.d.ts.map +1 -1
  104. package/dist/core/model-resolver.js +16 -10
  105. package/dist/core/model-resolver.js.map +1 -1
  106. package/dist/core/package-manager.d.ts +14 -0
  107. package/dist/core/package-manager.d.ts.map +1 -1
  108. package/dist/core/package-manager.js +160 -46
  109. package/dist/core/package-manager.js.map +1 -1
  110. package/dist/core/pi-ai-schemas.d.ts +163 -0
  111. package/dist/core/pi-ai-schemas.d.ts.map +1 -0
  112. package/dist/core/pi-ai-schemas.js +21 -0
  113. package/dist/core/pi-ai-schemas.js.map +1 -0
  114. package/dist/core/pi-manifest.d.ts +1 -0
  115. package/dist/core/pi-manifest.d.ts.map +1 -1
  116. package/dist/core/pi-manifest.js +4 -0
  117. package/dist/core/pi-manifest.js.map +1 -1
  118. package/dist/core/project-trust.js +1 -1
  119. package/dist/core/project-trust.js.map +1 -1
  120. package/dist/core/quiescence.d.ts +24 -0
  121. package/dist/core/quiescence.d.ts.map +1 -0
  122. package/dist/core/quiescence.js +81 -0
  123. package/dist/core/quiescence.js.map +1 -0
  124. package/dist/core/resource-loader.d.ts +4 -1
  125. package/dist/core/resource-loader.d.ts.map +1 -1
  126. package/dist/core/resource-loader.js +41 -28
  127. package/dist/core/resource-loader.js.map +1 -1
  128. package/dist/core/sdk.d.ts.map +1 -1
  129. package/dist/core/sdk.js +3 -1
  130. package/dist/core/sdk.js.map +1 -1
  131. package/dist/core/session-manager.d.ts +7 -0
  132. package/dist/core/session-manager.d.ts.map +1 -1
  133. package/dist/core/session-manager.js +32 -13
  134. package/dist/core/session-manager.js.map +1 -1
  135. package/dist/core/settings-manager.d.ts +2 -0
  136. package/dist/core/settings-manager.d.ts.map +1 -1
  137. package/dist/core/settings-manager.js +11 -0
  138. package/dist/core/settings-manager.js.map +1 -1
  139. package/dist/core/settings-schema.d.ts +4 -2
  140. package/dist/core/settings-schema.d.ts.map +1 -1
  141. package/dist/core/settings-schema.js +8 -1
  142. package/dist/core/settings-schema.js.map +1 -1
  143. package/dist/core/skills.d.ts.map +1 -1
  144. package/dist/core/skills.js +6 -14
  145. package/dist/core/skills.js.map +1 -1
  146. package/dist/core/slash-command-name.d.ts +6 -0
  147. package/dist/core/slash-command-name.d.ts.map +1 -0
  148. package/dist/core/slash-command-name.js +11 -0
  149. package/dist/core/slash-command-name.js.map +1 -0
  150. package/dist/core/slash-commands.js +2 -2
  151. package/dist/core/slash-commands.js.map +1 -1
  152. package/dist/core/source-info.d.ts +9 -0
  153. package/dist/core/source-info.d.ts.map +1 -1
  154. package/dist/core/source-info.js +13 -0
  155. package/dist/core/source-info.js.map +1 -1
  156. package/dist/core/system-prompt.d.ts.map +1 -1
  157. package/dist/core/system-prompt.js +5 -6
  158. package/dist/core/system-prompt.js.map +1 -1
  159. package/dist/core/tasks/codec.d.ts +14 -0
  160. package/dist/core/tasks/codec.d.ts.map +1 -1
  161. package/dist/core/tasks/codec.js +57 -4
  162. package/dist/core/tasks/codec.js.map +1 -1
  163. package/dist/core/tasks/record.d.ts +1 -7
  164. package/dist/core/tasks/record.d.ts.map +1 -1
  165. package/dist/core/tasks/record.js +0 -18
  166. package/dist/core/tasks/record.js.map +1 -1
  167. package/dist/core/tasks/reminder.d.ts +3 -2
  168. package/dist/core/tasks/reminder.d.ts.map +1 -1
  169. package/dist/core/tasks/reminder.js +4 -3
  170. package/dist/core/tasks/reminder.js.map +1 -1
  171. package/dist/core/tasks/runtime.d.ts +0 -2
  172. package/dist/core/tasks/runtime.d.ts.map +1 -1
  173. package/dist/core/tasks/runtime.js +2 -15
  174. package/dist/core/tasks/runtime.js.map +1 -1
  175. package/dist/core/tasks/session.d.ts +9 -2
  176. package/dist/core/tasks/session.d.ts.map +1 -1
  177. package/dist/core/tasks/session.js +23 -9
  178. package/dist/core/tasks/session.js.map +1 -1
  179. package/dist/core/tasks/types.d.ts +1 -18
  180. package/dist/core/tasks/types.d.ts.map +1 -1
  181. package/dist/core/tasks/types.js +1 -1
  182. package/dist/core/tasks/types.js.map +1 -1
  183. package/dist/core/tools/bash.d.ts +8 -7
  184. package/dist/core/tools/bash.d.ts.map +1 -1
  185. package/dist/core/tools/bash.js +6 -5
  186. package/dist/core/tools/bash.js.map +1 -1
  187. package/dist/core/tools/edit.d.ts +3 -3
  188. package/dist/core/tools/edit.d.ts.map +1 -1
  189. package/dist/core/tools/edit.js +2 -4
  190. package/dist/core/tools/edit.js.map +1 -1
  191. package/dist/core/tools/find.d.ts +2 -2
  192. package/dist/core/tools/find.d.ts.map +1 -1
  193. package/dist/core/tools/find.js.map +1 -1
  194. package/dist/core/tools/grep.d.ts +2 -2
  195. package/dist/core/tools/grep.d.ts.map +1 -1
  196. package/dist/core/tools/grep.js +1 -1
  197. package/dist/core/tools/grep.js.map +1 -1
  198. package/dist/core/tools/ls.d.ts +2 -2
  199. package/dist/core/tools/ls.d.ts.map +1 -1
  200. package/dist/core/tools/ls.js.map +1 -1
  201. package/dist/core/tools/powershell.d.ts +1 -5
  202. package/dist/core/tools/powershell.d.ts.map +1 -1
  203. package/dist/core/tools/read.d.ts +2 -2
  204. package/dist/core/tools/read.d.ts.map +1 -1
  205. package/dist/core/tools/read.js.map +1 -1
  206. package/dist/core/tools/render-utils.d.ts +4 -6
  207. package/dist/core/tools/render-utils.d.ts.map +1 -1
  208. package/dist/core/tools/render-utils.js +19 -41
  209. package/dist/core/tools/render-utils.js.map +1 -1
  210. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  211. package/dist/core/tools/renderers/bash.js +3 -25
  212. package/dist/core/tools/renderers/bash.js.map +1 -1
  213. package/dist/core/tools/renderers/write.d.ts.map +1 -1
  214. package/dist/core/tools/renderers/write.js +18 -19
  215. package/dist/core/tools/renderers/write.js.map +1 -1
  216. package/dist/core/tools/shell-execution.d.ts +20 -13
  217. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  218. package/dist/core/tools/shell-execution.js +165 -183
  219. package/dist/core/tools/shell-execution.js.map +1 -1
  220. package/dist/core/tools/shell-tool.d.ts +9 -14
  221. package/dist/core/tools/shell-tool.d.ts.map +1 -1
  222. package/dist/core/tools/shell-tool.js +38 -66
  223. package/dist/core/tools/shell-tool.js.map +1 -1
  224. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -4
  225. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  226. package/dist/core/tools/tool-definition-wrapper.js +2 -3
  227. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  228. package/dist/core/tools/write.d.ts +2 -2
  229. package/dist/core/tools/write.d.ts.map +1 -1
  230. package/dist/core/tools/write.js.map +1 -1
  231. package/dist/core/trust-manager.d.ts.map +1 -1
  232. package/dist/core/trust-manager.js +30 -13
  233. package/dist/core/trust-manager.js.map +1 -1
  234. package/dist/core/usage-totals.d.ts +0 -9
  235. package/dist/core/usage-totals.d.ts.map +1 -1
  236. package/dist/core/usage-totals.js +24 -91
  237. package/dist/core/usage-totals.js.map +1 -1
  238. package/dist/extensions/agent/activity-lines.d.ts +2 -3
  239. package/dist/extensions/agent/activity-lines.d.ts.map +1 -1
  240. package/dist/extensions/agent/activity-lines.js +5 -9
  241. package/dist/extensions/agent/activity-lines.js.map +1 -1
  242. package/dist/extensions/agent/activity.d.ts +0 -2
  243. package/dist/extensions/agent/activity.d.ts.map +1 -1
  244. package/dist/extensions/agent/activity.js +1 -1
  245. package/dist/extensions/agent/activity.js.map +1 -1
  246. package/dist/extensions/agent/progress.d.ts +0 -3
  247. package/dist/extensions/agent/progress.d.ts.map +1 -1
  248. package/dist/extensions/agent/progress.js +2 -8
  249. package/dist/extensions/agent/progress.js.map +1 -1
  250. package/dist/extensions/agent/render.js +1 -1
  251. package/dist/extensions/agent/render.js.map +1 -1
  252. package/dist/extensions/agent/tool.d.ts.map +1 -1
  253. package/dist/extensions/agent/tool.js +0 -6
  254. package/dist/extensions/agent/tool.js.map +1 -1
  255. package/dist/{core/isolated-session.d.ts → extensions/agent/worker-session.d.ts} +6 -6
  256. package/dist/extensions/agent/worker-session.d.ts.map +1 -0
  257. package/dist/{core/isolated-session.js → extensions/agent/worker-session.js} +9 -9
  258. package/dist/extensions/agent/worker-session.js.map +1 -0
  259. package/dist/extensions/agent/worker.d.ts +0 -3
  260. package/dist/extensions/agent/worker.d.ts.map +1 -1
  261. package/dist/extensions/agent/worker.js +2 -3
  262. package/dist/extensions/agent/worker.js.map +1 -1
  263. package/dist/extensions/btw/agent.d.ts.map +1 -1
  264. package/dist/extensions/btw/agent.js +2 -1
  265. package/dist/extensions/btw/agent.js.map +1 -1
  266. package/dist/extensions/cached-compaction/render.d.ts.map +1 -1
  267. package/dist/extensions/cached-compaction/render.js +3 -3
  268. package/dist/extensions/cached-compaction/render.js.map +1 -1
  269. package/dist/extensions/codemode/renderer.d.ts.map +1 -1
  270. package/dist/extensions/codemode/renderer.js +6 -2
  271. package/dist/extensions/codemode/renderer.js.map +1 -1
  272. package/dist/extensions/codemode/tool.d.ts +2 -1
  273. package/dist/extensions/codemode/tool.d.ts.map +1 -1
  274. package/dist/extensions/codemode/tool.js +33 -8
  275. package/dist/extensions/codemode/tool.js.map +1 -1
  276. package/dist/extensions/deepwiki/schema.d.ts.map +1 -1
  277. package/dist/extensions/deepwiki/schema.js +1 -1
  278. package/dist/extensions/deepwiki/schema.js.map +1 -1
  279. package/dist/extensions/llama/ui.d.ts.map +1 -1
  280. package/dist/extensions/llama/ui.js +16 -4
  281. package/dist/extensions/llama/ui.js.map +1 -1
  282. package/dist/extensions/mcp/cli.d.ts.map +1 -1
  283. package/dist/extensions/mcp/cli.js +34 -8
  284. package/dist/extensions/mcp/cli.js.map +1 -1
  285. package/dist/extensions/mcp/oauth.d.ts +1 -1
  286. package/dist/extensions/mcp/oauth.d.ts.map +1 -1
  287. package/dist/extensions/mcp/oauth.js +36 -13
  288. package/dist/extensions/mcp/oauth.js.map +1 -1
  289. package/dist/extensions/mcp/ui.d.ts +1 -0
  290. package/dist/extensions/mcp/ui.d.ts.map +1 -1
  291. package/dist/extensions/mcp/ui.js +33 -24
  292. package/dist/extensions/mcp/ui.js.map +1 -1
  293. package/dist/extensions/run-summary/index.d.ts +1 -1
  294. package/dist/extensions/run-summary/index.d.ts.map +1 -1
  295. package/dist/extensions/run-summary/index.js +11 -23
  296. package/dist/extensions/run-summary/index.js.map +1 -1
  297. package/dist/extensions/statusline/usage.d.ts.map +1 -1
  298. package/dist/extensions/statusline/usage.js +2 -1
  299. package/dist/extensions/statusline/usage.js.map +1 -1
  300. package/dist/extensions/tasks/tool/schema.d.ts.map +1 -1
  301. package/dist/extensions/tasks/tool/schema.js +1 -1
  302. package/dist/extensions/tasks/tool/schema.js.map +1 -1
  303. package/dist/extensions/tasks/ui/completion-render.d.ts +5 -1
  304. package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -1
  305. package/dist/extensions/tasks/ui/completion-render.js +25 -70
  306. package/dist/extensions/tasks/ui/completion-render.js.map +1 -1
  307. package/dist/extensions/tasks/ui/inspector.d.ts +1 -1
  308. package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -1
  309. package/dist/extensions/tasks/ui/inspector.js +0 -6
  310. package/dist/extensions/tasks/ui/inspector.js.map +1 -1
  311. package/dist/extensions/tasks/ui/manager.d.ts +1 -1
  312. package/dist/extensions/tasks/ui/manager.d.ts.map +1 -1
  313. package/dist/extensions/tasks/ui/manager.js.map +1 -1
  314. package/dist/extensions/tasks/ui/views.d.ts +2 -4
  315. package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
  316. package/dist/extensions/tasks/ui/views.js +3 -7
  317. package/dist/extensions/tasks/ui/views.js.map +1 -1
  318. package/dist/extensions/tool-presentation/fallback.d.ts.map +1 -0
  319. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/fallback.js +5 -5
  320. package/dist/extensions/tool-presentation/fallback.js.map +1 -0
  321. package/dist/extensions/tool-presentation/index.js +1 -1
  322. package/dist/extensions/tool-presentation/index.js.map +1 -1
  323. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/shell.d.ts +1 -1
  324. package/dist/extensions/tool-presentation/shell.d.ts.map +1 -0
  325. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/shell.js +3 -3
  326. package/dist/extensions/tool-presentation/shell.js.map +1 -0
  327. package/dist/extensions/tool-search/tool.d.ts +21 -6
  328. package/dist/extensions/tool-search/tool.d.ts.map +1 -1
  329. package/dist/extensions/tool-search/tool.js +104 -36
  330. package/dist/extensions/tool-search/tool.js.map +1 -1
  331. package/dist/index.d.ts +2 -2
  332. package/dist/index.d.ts.map +1 -1
  333. package/dist/index.js.map +1 -1
  334. package/dist/main.d.ts.map +1 -1
  335. package/dist/main.js +15 -8
  336. package/dist/main.js.map +1 -1
  337. package/dist/modes/interactive/components/assistant-message.d.ts +5 -3
  338. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  339. package/dist/modes/interactive/components/assistant-message.js +61 -45
  340. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  341. package/dist/modes/interactive/components/config-selector-skills.d.ts +54 -0
  342. package/dist/modes/interactive/components/config-selector-skills.d.ts.map +1 -0
  343. package/dist/modes/interactive/components/config-selector-skills.js +178 -0
  344. package/dist/modes/interactive/components/config-selector-skills.js.map +1 -0
  345. package/dist/modes/interactive/components/config-selector.d.ts +2 -11
  346. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  347. package/dist/modes/interactive/components/config-selector.js +31 -181
  348. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  349. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  350. package/dist/modes/interactive/components/custom-editor.js +7 -0
  351. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  352. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  353. package/dist/modes/interactive/components/custom-entry.js +2 -1
  354. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  355. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  356. package/dist/modes/interactive/components/custom-message.js +2 -1
  357. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  358. package/dist/modes/interactive/components/extension-editor.d.ts +2 -0
  359. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  360. package/dist/modes/interactive/components/extension-editor.js +4 -0
  361. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  362. package/dist/modes/interactive/components/login-dialog.d.ts +5 -0
  363. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  364. package/dist/modes/interactive/components/login-dialog.js +103 -10
  365. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  366. package/dist/modes/interactive/components/markdown-transform.d.ts +2 -1
  367. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
  368. package/dist/modes/interactive/components/markdown-transform.js +3 -2
  369. package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
  370. package/dist/modes/interactive/components/model-selector.d.ts +1 -0
  371. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  372. package/dist/modes/interactive/components/model-selector.js +17 -6
  373. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  374. package/dist/modes/interactive/components/oauth-selector.d.ts +1 -0
  375. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  376. package/dist/modes/interactive/components/oauth-selector.js +13 -4
  377. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  378. package/dist/modes/interactive/components/scoped-models-selector.d.ts +1 -0
  379. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  380. package/dist/modes/interactive/components/scoped-models-selector.js +14 -3
  381. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  382. package/dist/modes/interactive/components/session-selector-search.d.ts +4 -0
  383. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  384. package/dist/modes/interactive/components/session-selector-search.js +86 -22
  385. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  386. package/dist/modes/interactive/components/session-selector.d.ts +2 -1
  387. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  388. package/dist/modes/interactive/components/session-selector.js +15 -23
  389. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  390. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
  391. package/dist/modes/interactive/components/settings-submenu.js +2 -0
  392. package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
  393. package/dist/modes/interactive/components/tool-execution.d.ts +7 -0
  394. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  395. package/dist/modes/interactive/components/tool-execution.js +48 -9
  396. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  397. package/dist/modes/interactive/components/tree-selector.d.ts +1 -0
  398. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  399. package/dist/modes/interactive/components/tree-selector.js +5 -6
  400. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  401. package/dist/modes/interactive/components/user-message-selector.d.ts +1 -0
  402. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  403. package/dist/modes/interactive/components/user-message-selector.js +9 -1
  404. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  405. package/dist/modes/interactive/components/user-message.d.ts +3 -1
  406. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  407. package/dist/modes/interactive/components/user-message.js +4 -2
  408. package/dist/modes/interactive/components/user-message.js.map +1 -1
  409. package/dist/modes/interactive/editor-host.d.ts.map +1 -1
  410. package/dist/modes/interactive/editor-host.js +3 -2
  411. package/dist/modes/interactive/editor-host.js.map +1 -1
  412. package/dist/modes/interactive/external-editor.d.ts +1 -0
  413. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  414. package/dist/modes/interactive/external-editor.js +17 -5
  415. package/dist/modes/interactive/external-editor.js.map +1 -1
  416. package/dist/modes/interactive/interactive-mode.d.ts +8 -12
  417. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  418. package/dist/modes/interactive/interactive-mode.js +169 -112
  419. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  420. package/dist/modes/interactive/model-search.d.ts +10 -0
  421. package/dist/modes/interactive/model-search.d.ts.map +1 -1
  422. package/dist/modes/interactive/model-search.js +21 -0
  423. package/dist/modes/interactive/model-search.js.map +1 -1
  424. package/dist/modes/interactive/theme/theme.d.ts +10 -0
  425. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  426. package/dist/modes/interactive/theme/theme.js +30 -23
  427. package/dist/modes/interactive/theme/theme.js.map +1 -1
  428. package/dist/modes/interactive/tool-view/chat.d.ts +2 -2
  429. package/dist/modes/interactive/tool-view/chat.d.ts.map +1 -1
  430. package/dist/modes/interactive/tool-view/chat.js +22 -19
  431. package/dist/modes/interactive/tool-view/chat.js.map +1 -1
  432. package/dist/modes/interactive/transcript-layout.d.ts +2 -0
  433. package/dist/modes/interactive/transcript-layout.d.ts.map +1 -1
  434. package/dist/modes/interactive/transcript-layout.js +5 -2
  435. package/dist/modes/interactive/transcript-layout.js.map +1 -1
  436. package/dist/modes/rpc/rpc-client.d.ts +9 -1
  437. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  438. package/dist/modes/rpc/rpc-client.js +23 -23
  439. package/dist/modes/rpc/rpc-client.js.map +1 -1
  440. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  441. package/dist/modes/rpc/rpc-mode.js +0 -3
  442. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  443. package/dist/package-manager-cli.d.ts.map +1 -1
  444. package/dist/package-manager-cli.js +55 -4
  445. package/dist/package-manager-cli.js.map +1 -1
  446. package/dist/utils/ansi.d.ts.map +1 -1
  447. package/dist/utils/ansi.js +5 -2
  448. package/dist/utils/ansi.js.map +1 -1
  449. package/dist/utils/clipboard-command.d.ts.map +1 -1
  450. package/dist/utils/clipboard-command.js +4 -0
  451. package/dist/utils/clipboard-command.js.map +1 -1
  452. package/dist/utils/git.d.ts +1 -1
  453. package/dist/utils/git.d.ts.map +1 -1
  454. package/dist/utils/git.js.map +1 -1
  455. package/dist/utils/image-resize-core.d.ts.map +1 -1
  456. package/dist/utils/image-resize-core.js +5 -3
  457. package/dist/utils/image-resize-core.js.map +1 -1
  458. package/dist/utils/open-browser.d.ts.map +1 -1
  459. package/dist/utils/open-browser.js +4 -1
  460. package/dist/utils/open-browser.js.map +1 -1
  461. package/dist/utils/paths.d.ts +17 -0
  462. package/dist/utils/paths.d.ts.map +1 -1
  463. package/dist/utils/paths.js +42 -1
  464. package/dist/utils/paths.js.map +1 -1
  465. package/dist/utils/shell.d.ts.map +1 -1
  466. package/dist/utils/shell.js +14 -0
  467. package/dist/utils/shell.js.map +1 -1
  468. package/dist/utils/syntax-highlight.d.ts +5 -0
  469. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  470. package/dist/utils/syntax-highlight.js +7 -0
  471. package/dist/utils/syntax-highlight.js.map +1 -1
  472. package/dist/utils/tools-manager.d.ts.map +1 -1
  473. package/dist/utils/tools-manager.js +30 -35
  474. package/dist/utils/tools-manager.js.map +1 -1
  475. package/dist/utils/usage.d.ts +5 -0
  476. package/dist/utils/usage.d.ts.map +1 -0
  477. package/dist/utils/usage.js +16 -0
  478. package/dist/utils/usage.js.map +1 -0
  479. package/docs/bundled/README.md +1 -1
  480. package/docs/bundled/extensions/agent.md +5 -5
  481. package/docs/bundled/extensions/run-summary.md +4 -4
  482. package/docs/bundled/tasks.md +2 -4
  483. package/docs/bundled/tool-presentation.md +2 -2
  484. package/docs/custom-provider.md +1 -1
  485. package/docs/environment-variables.md +2 -0
  486. package/docs/extensions.md +36 -21
  487. package/docs/keybindings.md +1 -1
  488. package/docs/llama-cpp.md +17 -12
  489. package/docs/mcp.md +6 -4
  490. package/docs/packages.md +26 -1
  491. package/docs/rpc.md +1 -1
  492. package/docs/sdk.md +7 -5
  493. package/docs/session-format.md +2 -2
  494. package/docs/sessions.md +10 -0
  495. package/docs/settings.md +5 -4
  496. package/docs/terminal-setup.md +2 -2
  497. package/docs/tmux.md +6 -0
  498. package/docs/tui.md +12 -7
  499. package/docs/usage.md +19 -9
  500. package/docs/windows.md +29 -0
  501. package/examples/extensions/README.md +2 -1
  502. package/examples/extensions/custom-provider-anthropic/index.ts +27 -31
  503. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  504. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  505. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  506. package/examples/extensions/debug-provider.ts +2 -2
  507. package/examples/extensions/gondolin/package-lock.json +19 -29
  508. package/examples/extensions/gondolin/package.json +2 -2
  509. package/examples/extensions/preset.ts +2 -0
  510. package/examples/extensions/reload-runtime.ts +17 -5
  511. package/examples/extensions/tools.ts +2 -0
  512. package/examples/extensions/with-deps/package-lock.json +2 -2
  513. package/examples/extensions/with-deps/package.json +1 -1
  514. package/package.json +9 -9
  515. package/schemas/models.schema.json +36 -36
  516. package/schemas/settings.schema.json +17 -0
  517. package/dist/bundle/chunks/anthropic-messages-HWL6AS7T.js +0 -6
  518. package/dist/bundle/chunks/azure-openai-responses-4YYPDYV5.js +0 -2
  519. package/dist/bundle/chunks/chunk-6JS2SOFO.js +0 -11
  520. package/dist/bundle/chunks/chunk-ANCZPKX7.js +0 -2
  521. package/dist/bundle/chunks/chunk-FEZ5RM2B.js +0 -2
  522. package/dist/bundle/chunks/chunk-LPF7HQ3S.js +0 -4
  523. package/dist/bundle/chunks/chunk-MMNIHCU7.js +0 -2
  524. package/dist/bundle/chunks/chunk-PUU43PDV.js +0 -1484
  525. package/dist/bundle/chunks/chunk-R267VV5T.js +0 -82
  526. package/dist/bundle/chunks/chunk-RVKT7OUB.js +0 -9
  527. package/dist/bundle/chunks/chunk-SA2AQYEI.js +0 -7
  528. package/dist/bundle/chunks/chunk-ZAIGBRV5.js +0 -16
  529. package/dist/bundle/chunks/mistral-conversations-V2JJTMJ5.js +0 -5
  530. package/dist/bundle/chunks/openai-completions-TXZXILJR.js +0 -7
  531. package/dist/bundle/chunks/pi-messages-LBJQ4NGP.js +0 -8
  532. package/dist/bundle/chunks/virtual-modules-63XNTSVN.js +0 -2
  533. package/dist/core/isolated-session.d.ts.map +0 -1
  534. package/dist/core/isolated-session.js.map +0 -1
  535. package/dist/modes/interactive/tool-view/fallback.d.ts.map +0 -1
  536. package/dist/modes/interactive/tool-view/fallback.js.map +0 -1
  537. package/dist/modes/interactive/tool-view/shell.d.ts.map +0 -1
  538. package/dist/modes/interactive/tool-view/shell.js.map +0 -1
  539. package/dist/utils/path-identity.d.ts +0 -12
  540. package/dist/utils/path-identity.d.ts.map +0 -1
  541. package/dist/utils/path-identity.js +0 -63
  542. package/dist/utils/path-identity.js.map +0 -1
  543. package/examples/extensions/sandbox/index.ts +0 -321
  544. package/examples/extensions/sandbox/package-lock.json +0 -92
  545. package/examples/extensions/sandbox/package.json +0 -19
  546. /package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/fallback.d.ts +0 -0
package/docs/packages.md CHANGED
@@ -9,6 +9,7 @@ Pi packages bundle extensions, skills, prompt templates, and themes so you can s
9
9
  - [Install and Manage](#install-and-manage)
10
10
  - [Package Sources](#package-sources)
11
11
  - [Creating a Pi Package](#creating-a-pi-package)
12
+ - [Show a changelog](#show-a-changelog)
12
13
  - [Package Structure](#package-structure)
13
14
  - [Dependencies](#dependencies)
14
15
  - [Package Filtering](#package-filtering)
@@ -42,13 +43,17 @@ These commands manage pi packages and `pi update` can update the pi CLI installa
42
43
 
43
44
  By default, `install` and `remove` write to user settings (`~/.pi/agent/settings.json`). Use `-l` to write to project settings (`.pi/settings.json`) instead. Project settings can be shared with your team, and pi installs any missing packages automatically on startup after the project is trusted.
44
45
 
45
- To try a package without installing it, use `--extension` or `-e`. This installs to a temporary directory for the current run only:
46
+ If a configured package fails to install at startup, for example because npm cannot reach the registry, pi warns about it, skips that package's resources, and keeps running. It tries again on the next start or `/reload`. `pi install` and `pi update --extensions` still report the failure and exit non-zero.
47
+
48
+ To try a package without installing it, use `--extension` or `-e`. It is not added to settings:
46
49
 
47
50
  ```bash
48
51
  pi -e npm:@foo/bar
49
52
  pi -e git:github.com/user/repo
50
53
  ```
51
54
 
55
+ Pi caches `-e` packages under `~/.pi/agent/tmp/extensions/` and checks them on every start and `/reload`. An npm package is reinstalled when the registry has a newer version that matches the specification; an exact version such as `@1.2.3` is not checked. A git package is fetched and reset to the remote branch or ref; a commit hash that is already checked out is not fetched. If the check fails or offline mode is on, pi loads the cached copy.
56
+
52
57
  ## Package Sources
53
58
 
54
59
  Pi accepts three source types in settings and `pi install`.
@@ -154,6 +159,26 @@ The [package gallery](https://pi.dev/packages) displays packages tagged with `pi
154
159
 
155
160
  If both are set, video takes precedence.
156
161
 
162
+ ## Show a changelog
163
+
164
+ After a package update, pi can show what changed. On the next fresh launch, pi reads the package changelog and shows entries newer than the last seen version under "Extension Updates", the same way it shows its own changelog. The first time pi sees a package, it records the version without showing anything.
165
+
166
+ This applies to packages that load at least one extension. Packages that only provide skills, prompt templates, or themes do not show a changelog.
167
+
168
+ By default pi reads `CHANGELOG.md` from the package root. Point `pi.changelogPath` at another file inside the package, or set it to `""` to disable the changelog:
169
+
170
+ ```json
171
+ {
172
+ "name": "my-package",
173
+ "version": "1.2.0",
174
+ "pi": {
175
+ "changelogPath": "./docs/CHANGELOG.md"
176
+ }
177
+ }
178
+ ```
179
+
180
+ Use version headings such as `## [1.2.0]` or `## 1.2.0 - 2026-01-01`. Entries are matched against the `version` field in `package.json`, so a git package only shows a changelog when that field increases. The `collapseChangelog` setting condenses the section to one line per package, such as `Updated my-package to v1.2.0.` `/changelog` does not show package changelogs; read the package's changelog file or repository for details.
181
+
157
182
  ## Package Structure
158
183
 
159
184
  ### Convention Directories
package/docs/rpc.md CHANGED
@@ -959,7 +959,7 @@ Emitted when nothing more will happen without new input: no run, compaction, ret
959
959
  {"type": "session_quiescent"}
960
960
  ```
961
961
 
962
- `RpcClient.waitForQuiescence(timeout?)` resolves on this event, or at once when `get_state` reports `isQuiescent`; `collectEventsUntilQuiescent(timeout?)` collects events until it. `waitForIdle()` and `collectEvents()` still resolve on the first `agent_settled`. Closing stdin shuts the process down immediately, without waiting for Background work.
962
+ `RpcClient.waitForQuiescence(timeout?)` resolves on this event, or at once when `get_state` reports `isQuiescent`. `collectEventsUntilQuiescent(timeout?)` collects events until the next one: start it before the prompt it should cover, since it does not resolve early when the session is quiescent before that prompt begins. `waitForIdle()` and `collectEvents()` still resolve on the first `agent_settled`. Closing stdin shuts the process down immediately, without waiting for Background work.
963
963
 
964
964
  ### turn_start / turn_end
965
965
 
package/docs/sdk.md CHANGED
@@ -116,7 +116,9 @@ interface AgentSession {
116
116
 
117
117
  // Background host controls (see Background execution below)
118
118
  pauseTaskNotifications(): () => void;
119
+ withTaskNotificationsPaused<T>(operation: () => Promise<T>): Promise<T>;
119
120
  retryTaskNotifications(): void;
121
+ shutdownTasks(graceMs?: number): Promise<void>;
120
122
  getSessionStats(): SessionStats;
121
123
 
122
124
  // Cleanup (does not await Background draining)
@@ -258,10 +260,10 @@ Background work is admitted only while the `tasks` management tool is active in
258
260
 
259
261
  The host must choose:
260
262
 
261
- - **Lifetime and cancellation:** a settled main-agent turn is not the end of background work. `session.abort()` cancels foreground-owned work, not detached work. Use `session.tasks.kill(id)` for a whole execution, or `await session.tasks.shutdown(graceMs?)` to close admission, cancel all owned work and drain within a bounded grace period (default 2 seconds, maximum 60 seconds). A non-cooperating executor can outlive that grace period.
262
- - **Result-driven turns and cost:** automatic completions join the host's prompt queue, so a running turn receives them as steering and an idle session starts a completion turn. Use the nestable `session.pauseTaskNotifications()` to defer delivery; its returned release function is idempotent. Pausing does not stop execution or its costs. Budget worker activity and completion-triggered turns explicitly.
263
+ - **Lifetime and cancellation:** a settled main-agent turn is not the end of background work. `session.abort()` cancels foreground-owned work, not detached work. Use `session.tasks.kill(id)` for a whole execution, or `await session.shutdownTasks(graceMs?)` to close admission, abort the main agent, cancel all owned work and drain within a bounded grace period (default 2 seconds, maximum 60 seconds). A non-cooperating executor can outlive that grace period.
264
+ - **Result-driven turns and cost:** automatic completions join the host's prompt queue, so a running turn receives them as steering and an idle session starts a completion turn. Use the nestable `session.pauseTaskNotifications()` to defer delivery; its returned release function is idempotent. `session.withTaskNotificationsPaused(operation)` holds a pause for the duration of an async operation. Pausing does not stop execution or its costs. Budget worker activity and completion-triggered turns explicitly.
263
265
  - **Observation and delivery:** `session.tasks` exposes the [public supervision methods](extensions.md#ctxtasks). `list()`, `get()` and `read()` observe; a terminal snapshot alone does not acknowledge model delivery, and there is no blocking wait: subscribe with `session.tasks.subscribe()` or use `waitForQuiescence()` below. A direct SDK consumer that handles a result outside model history can call `session.acknowledgeTaskDelivery(task.id)` after successful consumption, which stops the session from notifying the model about it (an unknown or already delivered ID is ignored). An undelivered completion keeps its task and output retained until it is delivered or acknowledged, or its runtime closes. Failed notification delivery leaves the result available for inspection; after fixing the host failure, call `session.retryTaskNotifications()` explicitly. Pi does not retry a failed delivery forever on a timer.
264
- - **Shutdown:** `await runtime.dispose()` handles background shutdown and extension lifecycle when using the runtime API. For a directly owned session, drain Background, abort the main agent, then dispose; synchronous `session.dispose()` alone is not an awaited drain.
266
+ - **Shutdown:** `await runtime.dispose()` handles background shutdown and extension lifecycle when using the runtime API. For a directly owned session, `await session.shutdownTasks()`, then dispose; synchronous `session.dispose()` alone is not an awaited drain.
265
267
  - **Waiting for all work:** `prompt()` resolves when its own run settles, before any Background completion turn. `await session.waitForQuiescence(signal?)` resolves once the session is quiescent: no run, compaction, retry or branch summary, no unsettled Background task, and no completion left to deliver (the `session_quiescent` event marks the same moment, once per transition). It uses no timers and rejects when `signal` aborts or the session is disposed. A completion whose delivery failed does not count, since it retries only on the next input; a Background task that never ends keeps the wait open, so pass a signal when that matters.
266
268
 
267
269
  A deliberately single-turn embedding can suppress completion-triggered turns and cancel leftover work on exit:
@@ -279,7 +281,7 @@ try {
279
281
  // Snapshot only: some executions may still be running.
280
282
  console.log(session.tasks.list());
281
283
  } finally {
282
- await Promise.all([session.tasks.shutdown(), session.abort()]);
284
+ await session.shutdownTasks();
283
285
  session.dispose();
284
286
  resumeNotifications();
285
287
  }
@@ -289,7 +291,7 @@ For a longer-lived embedding, keep the host alive, subscribe to snapshots and ch
289
291
 
290
292
  Automatic completion messages carry `{ version: 3, task }` in `details`: the bounded terminal snapshot with its input, facts, diagnostics, up to 40 KiB of output and explicit truncation flags. This snapshot is self-contained for transcript replay and is not sent to the model. `content` is separately bounded prose: a log contributes an 8 KiB tail, while a report arrives from its beginning, whole when it fits the 48 KiB budget. After compaction, one request-local reminder lists still-active background tasks to prevent duplicate work; it is not persisted and does not start a turn. Each settlement appends one version-3 `task-record` holding the terminal snapshot and its usage, with no migration of earlier result records. See [Background records](session-format.md#background-records).
291
293
 
292
- `backgroundAllowed: false` on `createAgentSession()` is a host capability ceiling, independent of task kind. It prevents enabling background execution through `bindExtensions` or direct runtime activation, including after reload. Requests for `background: true` are rejected before startup; foreground execution remains available. Omitting this option permits host opt-in but does not enable background execution by itself. This capability restriction is not an OS sandbox.
294
+ `backgroundAllowed: false` on `createAgentSession()` is a host capability ceiling, independent of task kind. It prevents enabling background execution through `bindExtensions`, including after reload. Requests for `background: true` are rejected before startup; foreground execution remains available. Omitting this option permits host opt-in but does not enable background execution by itself. This capability restriction is not an OS sandbox.
293
295
 
294
296
  Reload, replacement/fork, shutdown and branch navigation enforce the [Background lifetime rules](bundled/tasks.md#lifetime). Saved terminal branch history is observational only: no live processes/workers resume, and restoration does not replay accounting or completion events. Managed logs expire with their runtime records; save anything needed before eviction or shutdown.
295
297
 
@@ -126,7 +126,7 @@ interface AssistantMessage {
126
126
  api: Api;
127
127
  provider: ProviderId;
128
128
  model: string;
129
- responseModel?: string;
129
+ responseModel?: string; // Concrete model the provider reported, when it reports one; may equal `model`
130
130
  responseId?: string;
131
131
  providerThinkingLevel?: string;
132
132
  thinkingLevel?: ModelThinkingLevel;
@@ -356,7 +356,7 @@ Terminal history is restored only from the selected branch's valid version-3 rec
356
356
 
357
357
  These `custom` entries do not enter model context. Automatic terminal delivery creates a `custom_message` with `customType: "task-completion"`, `display: true`, and `{ version: 3, task }` in `details`. The session formats `content` from the same snapshot, with a total limit of 48 KiB and 2,000 lines. A `log` task contributes only an 8 KiB output tail to the automatic model turn; a `report` task contributes its beginning, whole when it fits. Only `content` is sent to the model.
358
358
 
359
- Completion details are bounded to 120 KiB of serialized JSON including escaping. `task` is the terminal snapshot without `display`. Its `input` is clipped to 8 KiB, and its `result` keeps the end of a log or the beginning of a report, up to 40 KiB for replay and expanded rendering. The smaller model-facing projection does not change these stored fields. Source flags survive further clipping. The renderer sanitizes terminal control sequences and applies separate display row limits.
359
+ Completion details are bounded to 120 KiB of serialized JSON including escaping. `task` is the terminal snapshot without `display`. Its `input` is clipped to 8 KiB, and its `result` keeps the end of a log or the beginning of a report, up to 40 KiB for replay. The smaller model-facing projection does not change these stored fields. Source flags survive further clipping. The renderer sanitizes terminal control sequences and applies separate display row limits.
360
360
 
361
361
  A shell completion's `details` can look like this:
362
362
 
package/docs/sessions.md CHANGED
@@ -15,6 +15,16 @@ pi --session <path|id> # Use a specific session file or partial session ID
15
15
  pi --fork <path|id> # Fork a session file or partial session ID into a new session
16
16
  ```
17
17
 
18
+ Each session records the working directory it was created in and never changes it. Pi runs a session in its working directory, so tools, `@path` references, project configuration, and context files resolve from there.
19
+
20
+ | Entry point | Working directory |
21
+ |---|---|
22
+ | `-c`, `--continue` | The current directory |
23
+ | `-r`, `--resume`, `/resume`, `--session`, `/import` | The session's working directory, which can differ from the current directory |
24
+ | `--fork`, or a `--session` ID from another directory that you choose to fork | The current directory, in a new session |
25
+
26
+ If a session's working directory no longer exists, interactive mode offers to run the session in the current directory instead. Pi does not store that choice, so it asks again the next time you open the session. Other modes exit with an error.
27
+
18
28
  Use `/session` in interactive mode to see the current session file, session ID, message count, tokens, and cost.
19
29
 
20
30
  For the JSONL file format and SessionManager API, see [Session Format](session-format.md).
package/docs/settings.md CHANGED
@@ -81,7 +81,7 @@ Selecting a model or thinking level with Enter changes only the current session.
81
81
  | `externalEditor` | string | `$VISUAL`, then `$EDITOR`, then Notepad on Windows or `nano` elsewhere | Command for Ctrl+G external editor; takes precedence over environment variables |
82
82
  | `quietStartup` | boolean | `"header"` | `false` | `true` hides the startup header and loaded-resource listing. `"header"` keeps the header (version and key hints) but hides the model scope line and loaded-resource listing |
83
83
  | `defaultProjectTrust` | string | `"ask"` | Fallback project trust behavior: `"ask"`, `"always"`, or `"never"`. Global setting only |
84
- | `collapseChangelog` | boolean | `false` | Show condensed changelog after updates |
84
+ | `collapseChangelog` | boolean | `false` | Show condensed changelog after updates; also condenses extension package changelogs to one line per package |
85
85
  | `enableInstallTelemetry` | boolean | `true` | Legacy setting name for optional provider attribution headers. This does not control update checks |
86
86
  | `enableAnalytics` | boolean | `false` | Opt-in analytics data sharing. Currently only asked for during the experimental first-time setup (`PI_EXPERIMENTAL=1`) |
87
87
  | `trackingId` | string | - | Analytics tracking identifier, generated when `enableAnalytics` is turned on |
@@ -233,8 +233,8 @@ Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explic
233
233
  | `steeringMode` | string | `"one-at-a-time"` | How steering messages are sent: `"all"` or `"one-at-a-time"` |
234
234
  | `followUpMode` | string | `"one-at-a-time"` | How follow-up messages are sent: `"all"` or `"one-at-a-time"` |
235
235
  | `transport` | string | `"auto"` | Preferred transport for providers that support multiple transports: `"sse"`, `"websocket"`, `"websocket-cached"`, or `"auto"` |
236
- | `httpIdleTimeoutMs` | number | `300000` | HTTP header/body idle timeout in milliseconds, also used by providers with explicit stream idle timeouts. Set to `0` to disable. |
237
- | `websocketConnectTimeoutMs` | number | `15000` | WebSocket connect/open handshake timeout in milliseconds for providers that support WebSocket transports. Set to `0` to disable. |
236
+ | `httpIdleTimeoutMs` | number \| `"disabled"` | `300000` | HTTP header/body idle timeout in milliseconds, also used by providers with explicit stream idle timeouts. Set to `0` or `"disabled"` to disable. |
237
+ | `websocketConnectTimeoutMs` | number \| `"disabled"` | `15000` | WebSocket connect/open handshake timeout in milliseconds for providers that support WebSocket transports. Set to `0` or `"disabled"` to disable. |
238
238
 
239
239
  ### Terminal & Images
240
240
 
@@ -242,7 +242,7 @@ Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explic
242
242
  |---------|------|---------|-------------|
243
243
  | `terminal.showImages` | boolean | `true` | Show images in terminal (if supported) |
244
244
  | `terminal.imageWidthCells` | number | `60` | Preferred inline image width in terminal cells |
245
- | `terminal.clearOnShrink` | boolean | `false` | Clear empty rows when content shrinks (can cause flicker) |
245
+ | `terminal.clearOnShrink` | boolean | `false` | Clear empty rows when content shrinks (can cause flicker). When unset, `PI_CLEAR_ON_SHRINK=1` enables it |
246
246
  | `terminal.hyperlinks` | boolean or `"auto"` | `"auto"` | Override OSC 8 hyperlink support (advanced, JSON-only) |
247
247
  | `terminal.images` | string or boolean | `"auto"` | Override image protocol support with `"kitty"`, `"iterm2"`, `false`, or `"auto"` (advanced, JSON-only) |
248
248
  | `terminal.trueColor` | boolean or `"auto"` | `"auto"` | Override truecolor support (advanced, JSON-only) |
@@ -256,6 +256,7 @@ Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explic
256
256
  | `shellPath` | string | - | Custom shell path (e.g., for Cygwin on Windows); supports a leading `~` for the home directory |
257
257
  | `shellCommandPrefix` | string | - | Prefix for every bash command (e.g., `"shopt -s expand_aliases"`) |
258
258
  | `npmCommand` | string[] | - | Command argv used for npm package lookup/install operations (e.g., `["mise", "exec", "node@20", "--", "npm"]`) |
259
+ | `selfUpdateCommand` | string[] | - | Command argv `pi update` runs to update Pi itself, with `{packageName}`, `{version}`, and `{installSpec}` placeholders. `PI_SELF_UPDATE_COMMAND` takes precedence. Global setting only. See [Custom update command](usage.md#custom-update-command) |
259
260
 
260
261
  Windows paths in JSON must use forward slashes or escaped backslashes:
261
262
 
@@ -37,7 +37,7 @@ This is an iTerm2-wide workaround and may also change native trackpad scrolling.
37
37
 
38
38
  ## Apple Terminal
39
39
 
40
- Pi enables enhanced key reporting when available. If Terminal.app still sends plain Return for `Shift+Enter`, pi uses a local macOS modifier fallback to treat that Return as `Shift+Enter`.
40
+ Pi enables enhanced key reporting when available. If Terminal.app still sends plain Return or `ESC` + Return for `Shift+Enter`, pi uses a local macOS modifier fallback to treat it as `Shift+Enter`. `ESC` + Return without Shift held remains `Alt+Enter`.
41
41
 
42
42
  This fallback only works when pi runs on the same Mac as Terminal.app. It cannot detect the local keyboard over remote SSH.
43
43
 
@@ -140,7 +140,7 @@ Pi uses Windows-style keybindings when running natively on Windows or in WSL:
140
140
  - `Ctrl+Z` undoes editing on native Windows; WSL uses `Alt+Z` so `Ctrl+Z` can suspend pi.
141
141
  - `Ctrl+Q` queues a follow-up message and `Alt+Q` restores queued messages.
142
142
 
143
- Add to `settings.json` (Ctrl+Shift+, or Settings → Open JSON file) to forward `Shift+Enter` for inserting a new line:
143
+ When pi runs natively on Windows, it checks the local Shift key state and treats plain Return or `ESC` + Return as `Shift+Enter` while Shift is held. This fallback does not work in WSL or over SSH. If `Shift+Enter` still submits, add to `settings.json` (Ctrl+Shift+, or Settings → Open JSON file) to forward it explicitly:
144
144
 
145
145
  ```json
146
146
  {
package/docs/tmux.md CHANGED
@@ -61,3 +61,9 @@ This affects the default keybindings (`Enter` to submit, `Shift+Enter` for newli
61
61
  - A terminal emulator that supports extended keys (Ghostty, Kitty, iTerm2, WezTerm, Windows Terminal)
62
62
 
63
63
  With tmux 3.2 through 3.4, omit `extended-keys-format csi-u`; Pi still supports tmux's default xterm `modifyOtherKeys` format.
64
+
65
+ ## Known issues
66
+
67
+ | Issue | Affects | Remedy |
68
+ |---|---|---|
69
+ | Text such as `c0c/0c0c/0c0c` appears in the editor at startup ([tmux#4749](https://github.com/tmux/tmux/issues/4749)) | tmux 3.6 | Upgrade tmux. Changing pi's theme does not help. |
package/docs/tui.md CHANGED
@@ -176,6 +176,8 @@ export default function (pi: ExtensionAPI) {
176
176
 
177
177
  This component does not display a text cursor, so it does not need `Focusable`. A component containing `Input` or `Editor` must implement `Focusable` and propagate its `focused` value to that child.
178
178
 
179
+ Custom components do not report pi as waiting for the user, because `ctx.ui.custom()` also hosts loaders and other non-blocking UI. When an inline component waits for an answer, pass `blocked: { kind: "question", message: "Pick a color" }` so terminals that support [program status](terminal-setup.md#program-status) show pi as blocked while the component is visible. `kind` is `"question"`, `"permission"`, or `"auth"`. Overlays ignore this option.
180
+
179
181
  ### Disposal
180
182
 
181
183
  A component returned from `ctx.ui.custom()`, `setWidget()`, `setFooter()`, or `setHeader()` may also implement `dispose(): void`. Use it to stop timers, abort owned work, and unsubscribe listeners. Pi calls it after a custom component finishes, or when a widget, footer, or header is replaced or cleared.
@@ -759,18 +761,21 @@ The factory's component is disposed when that widget key is replaced or cleared.
759
761
 
760
762
  **Examples:** [widget-placement.ts](../examples/extensions/widget-placement.ts)
761
763
 
762
- ### Pattern 5b: Ephemeral Transcript Notes
764
+ ### Pattern 5b: Transcript Annotations
763
765
 
764
- Use `addTranscriptNote()` for a short display-only annotation tied to an existing session entry. Pi renders it in `dim` after that entry, including when compaction or branch navigation rebuilds the transcript. Notes are not persisted, are never sent to the model, and are cleared with the current extension UI runtime. Reusing a key is a no-op, which makes event retries safe.
766
+ For a short display-only line in the transcript, such as how long a run took, append a custom entry and render it. The entry is saved where it was appended and never sent to the model, so the line reappears in place whenever Pi rebuilds the transcript, such as on resume or after branch navigation.
765
767
 
766
768
  ```typescript
767
- const afterEntryId = ctx.sessionManager.getLeafId();
768
- if (afterEntryId) {
769
- ctx.ui.addTranscriptNote("run-summary", "Worked for 8s", { afterEntryId });
770
- }
769
+ pi.registerEntryRenderer<{ seconds: number }>("run-time", (entry, { outputPad }, theme) =>
770
+ new Text(theme.fg("dim", `Worked for ${entry.data?.seconds}s`), outputPad, 0),
771
+ );
772
+
773
+ pi.on("agent_settled", () => {
774
+ pi.appendEntry("run-time", { seconds: 8 });
775
+ });
771
776
  ```
772
777
 
773
- This is intended for settled annotations. It is not a replacement for widgets, footers, streaming components, or durable custom entries.
778
+ Use widgets, footers or streaming components for content that changes while it is shown.
774
779
 
775
780
  ### Pattern 6: Custom Footer
776
781
 
package/docs/usage.md CHANGED
@@ -44,7 +44,7 @@ Type `/` in the editor to open command completion. Extensions can register custo
44
44
  | `/thinking` | Switch thinking level; Ctrl+S in the picker saves the startup default |
45
45
  | `/scoped-models` | Enable/disable models for Ctrl+P cycling |
46
46
  | `/settings` | Theme, message delivery, transport, and other preferences |
47
- | `/resume` | Pick from previous sessions |
47
+ | `/resume` | Resume another session |
48
48
  | `/new` | Start a new session |
49
49
  | `/name <name>` | Set session display name |
50
50
  | `/session` | Show session file, ID, messages, tokens, and cost |
@@ -55,7 +55,7 @@ Type `/` in the editor to open command completion. Extensions can register custo
55
55
  | `/compact [prompt]` | Manually compact context, optionally with custom instructions |
56
56
  | `/copy` | Copy last assistant message to clipboard |
57
57
  | `/export [file]` | Export session to HTML or JSONL |
58
- | `/import <file>` | Import and resume a session from a JSONL file |
58
+ | `/import <file>` | Import a JSONL session, preserving its ID and working directory |
59
59
  | `/share` | Upload as private GitHub gist with shareable HTML link |
60
60
  | `/bug [description]` | Report a bug to the Pi developers; see [Sessions](sessions.md#reporting-bugs) |
61
61
  | `/reload` | Reload keybindings, extensions, skills, prompts, themes, and context files |
@@ -163,6 +163,16 @@ To uninstall pi itself, see [Quickstart](quickstart.md#uninstall). `pi config` a
163
163
 
164
164
  See [Pi Packages](packages.md) for package sources and security notes.
165
165
 
166
+ #### Custom update command
167
+
168
+ If a wrapper or another package manager provides Pi, set `PI_SELF_UPDATE_COMMAND` so `pi update` runs its update command:
169
+
170
+ ```sh
171
+ export PI_SELF_UPDATE_COMMAND="mise use -g npm:{packageName}@{version}"
172
+ ```
173
+
174
+ `pi update` runs it only when the npm registry has a newer release, replacing `{packageName}`, `{version}`, and `{installSpec}` (`{packageName}@{version}`) with that release. The value is split on spaces. For arguments with spaces, use the `selfUpdateCommand` setting in `~/.pi/agent/settings.json` instead, an argv array such as `["nix", "profile", "upgrade", "pi"]`.
175
+
166
176
  ### Modes
167
177
 
168
178
  | Flag | Description |
@@ -201,10 +211,10 @@ cat README.md | pi -p "Summarize this text"
201
211
 
202
212
  | Option | Description |
203
213
  |--------|-------------|
204
- | `-c`, `--continue` | Continue the most recent session |
205
- | `-r`, `--resume` | Browse and select a session |
206
- | `--session <path\|id>` | Use a specific session file or partial UUID |
207
- | `--fork <path\|id>` | Fork a session file or partial UUID into a new session |
214
+ | `-c`, `--continue` | Continue the most recent session for the current directory |
215
+ | `-r`, `--resume` | Browse and select a session; it resumes in its own working directory. Press Tab to include sessions from other directories |
216
+ | `--session <path\|id>` | Use a specific session file or partial UUID and resume it in its working directory. A match stored only for another directory is offered as a fork into the current directory |
217
+ | `--fork <path\|id>` | Fork a session file or partial UUID into a new session in the current directory |
208
218
  | `--session-dir <dir>` | Custom session storage directory |
209
219
  | `--no-session` | Ephemeral mode; do not save |
210
220
  | `--name <name>`, `-n <name>` | Set session display name at startup |
@@ -365,11 +375,11 @@ These commands work outside a session, so agents can run them through `bash`. Se
365
375
  | Command | Description |
366
376
  |---|---|
367
377
  | `pi mcp add <server> [options] -- <command> [args...]` | Add or replace a stdio server in `mcp.json`; `--env KEY=VALUE` (repeatable) and `--cwd <dir>` set its environment and working directory. Arguments after the command are passed to it |
368
- | `pi mcp add <server> [options] --url <url>` | Add or replace a streamable HTTP server; `--header KEY=VALUE` (repeatable), `--bearer-token-env-var <NAME>` (sends `Authorization: Bearer ${NAME}`), `--oauth-client-id`, `--oauth-client-secret`, `--oauth-callback-port`, and `--oauth-client-name` configure authentication |
378
+ | `pi mcp add <server> [options] --url <url>` | Add or replace a streamable HTTP server; `--header KEY=VALUE` (repeatable), `--bearer-token-env-var <NAME>` (sends `Authorization: Bearer ${NAME}`), `--oauth-client-id`, `--oauth-client-secret`, `--oauth-callback-port`, `--oauth-client-name`, and `--oauth-client-registration` (`auto`, `cimd`, or `dcr`) configure authentication |
369
379
  | `pi mcp remove <server>` | Remove a server from `mcp.json`; stored OAuth credentials are kept |
370
380
  | `pi mcp list [--json]` | Connect to every enabled server and print its state, tools, and errors; exit with `1` when a config entry is invalid or an enabled server is not connected |
371
- | `pi mcp login <server> [--timeout <seconds>]` | Sign in to an OAuth server: open the authorization page and wait for the browser (default 300 seconds); a terminal also accepts the pasted redirect URL |
372
- | `pi mcp logout <server>` | Delete the stored OAuth credentials of a server |
381
+ | `pi mcp login <server> [-l] [--timeout <seconds>]` | Sign in to an OAuth server: open the authorization page and wait for the browser (default 300 seconds); a terminal also accepts the pasted redirect URL. `-l` requires the server to be defined in the project's `.pi/mcp.json` |
382
+ | `pi mcp logout <server> [-l]` | Delete the stored OAuth credentials of a server |
373
383
 
374
384
  `add` and `remove` change `~/.pi/agent/mcp.json`, or `.pi/mcp.json` in the current directory with `--local` (`-l`). `add` also takes `--exposure <mode>` (see [Exposure](mcp.md#control-tool-exposure)) and `--description <text>` and does not connect; run `pi mcp list` to check the server.
375
385
 
package/docs/windows.md CHANGED
@@ -23,6 +23,24 @@ Start Pi and enter this command to verify the shell:
23
23
 
24
24
  If Pi cannot find Bash, it reports the locations it checked. Install Git for Windows, set `shellPath`, or add Bash to `PATH`.
25
25
 
26
+ ## Choose a terminal
27
+
28
+ Windows terminals run pi through a console host (conhost). Some bundle an up-to-date copy; others use the older one built into Windows, which has bugs that affect pi.
29
+
30
+ We recommend [Windows Terminal](https://aka.ms/terminal). It always ships an up-to-date conhost, and pi is best tested with it.
31
+
32
+ Last updated: October 2026.
33
+
34
+ | Terminal | Conhost | Status |
35
+ |---|---|---|
36
+ | [Windows Terminal](https://aka.ms/terminal) | Bundled, current | Recommended |
37
+ | [VS Code](https://code.visualstudio.com), [Tabby](https://tabby.sh), [WezTerm](https://wezterm.org) nightly | Bundled, current | Works |
38
+ | [Alacritty](https://alacritty.org) | Built-in, unless `conpty.dll` and `OpenConsole.exe` from Windows Terminal are next to `alacritty.exe` | Works only with those files |
39
+ | WezTerm 20240203 and older | Bundled, old | [Known issues](#known-issues) |
40
+ | Classic console (`cmd.exe` or PowerShell without Windows Terminal), mintty (Git Bash), ConEmu, Cmder, [Hyper](https://hyper.is), Windows OpenSSH | Built-in | [Known issues](#known-issues) |
41
+
42
+ See [Windows Terminal](terminal-setup.md#windows-terminal) to configure `Shift+Enter` and `Alt+Enter`.
43
+
26
44
  ## PowerShell Tool
27
45
 
28
46
  The optional `powershell` tool runs commands through `pwsh.exe` when available, otherwise Windows PowerShell. It starts PowerShell with `-NoProfile -NonInteractive -ExecutionPolicy Bypass`. Administrator-enforced execution policies can still take precedence.
@@ -67,3 +85,14 @@ When using the legacy WSL `bash.exe` launcher from Windows, Pi sends commands ov
67
85
  ```
68
86
 
69
87
  `"defaultTools": ["-bash", "+powershell"]` replaces Bash while preserving other configured default tools.
88
+
89
+ ## Known issues
90
+
91
+ These issues come from conhost. Microsoft has fixed them in its source, but has not said when the built-in conhost will get the fixes.
92
+
93
+ | Issue | Affects | Remedy |
94
+ |---|---|---|
95
+ | Switching from fullscreen to regular mode, or `Ctrl+G` from fullscreen, crashes the session ([#9186](https://github.com/earendil-works/pi/issues/9186), [microsoft/terminal#17515](https://github.com/microsoft/terminal/issues/17515)) | Built-in conhost | Use a terminal with a current conhost, or start pi with `--tui-mode regular` |
96
+ | Text such as `;0;rgb:0000/0000/0000` appears in the prompt, and BEL opens the external editor ([#10256](https://github.com/earendil-works/pi/issues/10256)) | Built-in conhost behind another terminal: mintty, Windows OpenSSH | Use a terminal with a current conhost |
97
+ | Fragments such as `79` or `55` appear in the prompt ([#10717](https://github.com/earendil-works/pi/issues/10717)) | WezTerm 20240203 | Use WezTerm nightly |
98
+ | In regular mode, each keystroke redraws the input line on a new row ([#6300](https://github.com/earendil-works/pi/issues/6300)) | Built-in conhost, classic console | Use fullscreen mode (the default), or a terminal with a current conhost |
@@ -23,9 +23,10 @@ cp permission-gate.ts ~/.pi/agent/extensions/
23
23
  | `protected-paths.ts` | Blocks writes to protected paths (.env, .git/, node_modules/) |
24
24
  | `confirm-destructive.ts` | Confirms before destructive session actions (clear, switch, fork) |
25
25
  | `dirty-repo-guard.ts` | Prevents session changes with uncommitted git changes |
26
- | `sandbox/` | OS-level sandboxing using `@anthropic-ai/sandbox-runtime` with per-project config |
27
26
  | `gondolin/` | Route built-in tools and `!` commands into a Gondolin micro-VM |
28
27
 
28
+ For isolation setup and limitations, see [Run Pi in an isolated environment](../../docs/containerization.md).
29
+
29
30
  ### Custom Tools
30
31
 
31
32
  | Extension | Description |
@@ -42,7 +42,7 @@ import {
42
42
  type TextContent,
43
43
  type ThinkingContent,
44
44
  type Tool,
45
- type ToolCall,
45
+ ToolCallArgumentsStream,
46
46
  type ToolResultMessage,
47
47
  type TranscriptContext,
48
48
  } from "@earendil-works/pi-ai";
@@ -454,8 +454,9 @@ function streamCustomAnthropic(
454
454
  const anthropicStream = client.messages.stream({ ...params }, { signal: options?.signal });
455
455
  stream.push({ type: "start", partial: output });
456
456
 
457
- type Block = (ThinkingContent | TextContent | (ToolCall & { partialJson: string })) & { index: number };
458
- const blocks = output.content as Block[];
457
+ // Stream state per Anthropic block index, kept off the content blocks so it never reaches partial messages.
458
+ // ToolCallArgumentsStream reads each argument delta once and shows the arguments parsed so far.
459
+ const openBlocks = new Map<number, { contentIndex: number; arguments?: ToolCallArgumentsStream }>();
459
460
 
460
461
  for await (const event of anthropicStream) {
461
462
  if (event.type === "message_start") {
@@ -468,15 +469,12 @@ function streamCustomAnthropic(
468
469
  calculateCost(model, output.usage);
469
470
  } else if (event.type === "content_block_start") {
470
471
  if (event.content_block.type === "text") {
471
- output.content.push({ type: "text", text: "", index: event.index } as any);
472
+ output.content.push({ type: "text", text: "" });
473
+ openBlocks.set(event.index, { contentIndex: output.content.length - 1 });
472
474
  stream.push({ type: "text_start", contentIndex: output.content.length - 1, partial: output });
473
475
  } else if (event.content_block.type === "thinking") {
474
- output.content.push({
475
- type: "thinking",
476
- thinking: "",
477
- thinkingSignature: "",
478
- index: event.index,
479
- } as any);
476
+ output.content.push({ type: "thinking", thinking: "", thinkingSignature: "" });
477
+ openBlocks.set(event.index, { contentIndex: output.content.length - 1 });
480
478
  stream.push({ type: "thinking_start", contentIndex: output.content.length - 1, partial: output });
481
479
  } else if (event.content_block.type === "tool_use") {
482
480
  output.content.push({
@@ -484,15 +482,18 @@ function streamCustomAnthropic(
484
482
  id: event.content_block.id,
485
483
  name: isOAuth ? fromClaudeCodeName(event.content_block.name, tools) : event.content_block.name,
486
484
  arguments: {},
487
- partialJson: "",
488
- index: event.index,
489
- } as any);
485
+ });
486
+ openBlocks.set(event.index, {
487
+ contentIndex: output.content.length - 1,
488
+ arguments: new ToolCallArgumentsStream(),
489
+ });
490
490
  stream.push({ type: "toolcall_start", contentIndex: output.content.length - 1, partial: output });
491
491
  }
492
492
  } else if (event.type === "content_block_delta") {
493
- const index = blocks.findIndex((b) => b.index === event.index);
494
- const block = blocks[index];
495
- if (!block) continue;
493
+ const open = openBlocks.get(event.index);
494
+ if (!open) continue;
495
+ const index = open.contentIndex;
496
+ const block = output.content[index]!;
496
497
 
497
498
  if (event.delta.type === "text_delta" && block.type === "text") {
498
499
  block.text += event.delta.text;
@@ -505,11 +506,8 @@ function streamCustomAnthropic(
505
506
  delta: event.delta.thinking,
506
507
  partial: output,
507
508
  });
508
- } else if (event.delta.type === "input_json_delta" && block.type === "toolCall") {
509
- (block as any).partialJson += event.delta.partial_json;
510
- try {
511
- block.arguments = JSON.parse((block as any).partialJson);
512
- } catch {}
509
+ } else if (event.delta.type === "input_json_delta" && block.type === "toolCall" && open.arguments) {
510
+ block.arguments = open.arguments.append(event.delta.partial_json);
513
511
  stream.push({
514
512
  type: "toolcall_delta",
515
513
  contentIndex: index,
@@ -520,20 +518,19 @@ function streamCustomAnthropic(
520
518
  block.thinkingSignature = (block.thinkingSignature || "") + (event.delta as any).signature;
521
519
  }
522
520
  } else if (event.type === "content_block_stop") {
523
- const index = blocks.findIndex((b) => b.index === event.index);
524
- const block = blocks[index];
525
- if (!block) continue;
521
+ const open = openBlocks.get(event.index);
522
+ if (!open) continue;
523
+ openBlocks.delete(event.index);
524
+ const index = open.contentIndex;
525
+ const block = output.content[index]!;
526
526
 
527
- delete (block as any).index;
528
527
  if (block.type === "text") {
529
528
  stream.push({ type: "text_end", contentIndex: index, content: block.text, partial: output });
530
529
  } else if (block.type === "thinking") {
531
530
  stream.push({ type: "thinking_end", contentIndex: index, content: block.thinking, partial: output });
532
- } else if (block.type === "toolCall") {
533
- try {
534
- block.arguments = JSON.parse((block as any).partialJson);
535
- } catch {}
536
- delete (block as any).partialJson;
531
+ } else if (block.type === "toolCall" && open.arguments) {
532
+ // One full parse of the complete text; malformed arguments are reported in `argumentsError`.
533
+ Object.assign(block, open.arguments.finish());
537
534
  stream.push({ type: "toolcall_end", contentIndex: index, toolCall: block, partial: output });
538
535
  }
539
536
  } else if (event.type === "message_delta") {
@@ -563,7 +560,6 @@ function streamCustomAnthropic(
563
560
  stream.push({ type: "done", reason: output.stopReason, message: output });
564
561
  stream.end();
565
562
  } catch (error) {
566
- for (const block of output.content) delete (block as any).index;
567
563
  output.stopReason = options?.signal?.aborted ? "aborted" : "error";
568
564
  output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
569
565
  stream.push({ type: "error", reason: output.stopReason, error: output });
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-custom-provider",
9
- "version": "1.4.0",
9
+ "version": "1.5.0",
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": "1.4.0",
4
+ "version": "1.5.0",
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": "1.4.0",
4
+ "version": "1.5.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -6,7 +6,7 @@
6
6
  * as expandable custom entries.
7
7
  */
8
8
 
9
- import { type ExtensionAPI, keyHint } from "@earendil-works/pi-coding-agent";
9
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
10
10
  import { Box, Text } from "@earendil-works/pi-tui";
11
11
 
12
12
  const ENTRY_TYPE = "debug-provider-events";
@@ -24,7 +24,7 @@ export default function (pi: ExtensionAPI) {
24
24
  let activeEvents: unknown[] | undefined;
25
25
  let completedEntry: ProviderDebugEntry | undefined;
26
26
 
27
- pi.registerEntryRenderer<ProviderDebugEntry>(ENTRY_TYPE, (entry, { expanded }, theme) => {
27
+ pi.registerEntryRenderer<ProviderDebugEntry>(ENTRY_TYPE, (entry, { expanded, keyHint }, theme) => {
28
28
  const data = entry.data;
29
29
  if (!data) return new Text(theme.fg("warning", "[provider debug] Missing event data"), 0, 0);
30
30