@sammorrowdrums/mcpi 0.70.8 → 0.85.0-bootstrap.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 (888) hide show
  1. package/CHANGELOG.md +1621 -0
  2. package/LICENSE +21 -0
  3. package/README.md +196 -141
  4. package/dist/bun/cli.d.ts.map +1 -1
  5. package/dist/bun/cli.js +4 -0
  6. package/dist/bun/cli.js.map +1 -1
  7. package/dist/bun/register-bedrock.d.ts.map +1 -1
  8. package/dist/bun/register-bedrock.js +1 -1
  9. package/dist/bun/register-bedrock.js.map +1 -1
  10. package/dist/bun/restore-sandbox-env.d.ts +17 -0
  11. package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
  12. package/dist/bun/restore-sandbox-env.js +36 -0
  13. package/dist/bun/restore-sandbox-env.js.map +1 -0
  14. package/dist/cli/args.d.ts +9 -2
  15. package/dist/cli/args.d.ts.map +1 -1
  16. package/dist/cli/args.js +116 -16
  17. package/dist/cli/args.js.map +1 -1
  18. package/dist/cli/auth-check.d.ts +19 -0
  19. package/dist/cli/auth-check.d.ts.map +1 -0
  20. package/dist/cli/auth-check.js +50 -0
  21. package/dist/cli/auth-check.js.map +1 -0
  22. package/dist/cli/auth-command.d.ts +24 -0
  23. package/dist/cli/auth-command.d.ts.map +1 -0
  24. package/dist/cli/auth-command.js +103 -0
  25. package/dist/cli/auth-command.js.map +1 -0
  26. package/dist/cli/config-selector.d.ts +6 -4
  27. package/dist/cli/config-selector.d.ts.map +1 -1
  28. package/dist/cli/config-selector.js +4 -4
  29. package/dist/cli/config-selector.js.map +1 -1
  30. package/dist/cli/credential-print.d.ts +13 -0
  31. package/dist/cli/credential-print.d.ts.map +1 -0
  32. package/dist/cli/credential-print.js +76 -0
  33. package/dist/cli/credential-print.js.map +1 -0
  34. package/dist/cli/experimental/auth.d.ts +16 -0
  35. package/dist/cli/experimental/auth.d.ts.map +1 -0
  36. package/dist/cli/experimental/auth.js +13 -0
  37. package/dist/cli/experimental/auth.js.map +1 -0
  38. package/dist/cli/experimental/cli.d.ts +6 -0
  39. package/dist/cli/experimental/cli.d.ts.map +1 -0
  40. package/dist/cli/experimental/cli.js +5 -0
  41. package/dist/cli/experimental/cli.js.map +1 -0
  42. package/dist/cli/experimental/command-options.d.ts +17 -0
  43. package/dist/cli/experimental/command-options.d.ts.map +1 -0
  44. package/dist/cli/experimental/command-options.js +35 -0
  45. package/dist/cli/experimental/command-options.js.map +1 -0
  46. package/dist/cli/experimental/command.d.ts +63 -0
  47. package/dist/cli/experimental/command.d.ts.map +1 -0
  48. package/dist/cli/experimental/command.js +130 -0
  49. package/dist/cli/experimental/command.js.map +1 -0
  50. package/dist/cli/experimental/commands/client.d.ts +13 -0
  51. package/dist/cli/experimental/commands/client.d.ts.map +1 -0
  52. package/dist/cli/experimental/commands/client.js +25 -0
  53. package/dist/cli/experimental/commands/client.js.map +1 -0
  54. package/dist/cli/experimental/commands/mcpi.d.ts +15 -0
  55. package/dist/cli/experimental/commands/mcpi.d.ts.map +1 -0
  56. package/dist/cli/experimental/commands/mcpi.js +28 -0
  57. package/dist/cli/experimental/commands/mcpi.js.map +1 -0
  58. package/dist/cli/experimental/commands/server.d.ts +13 -0
  59. package/dist/cli/experimental/commands/server.d.ts.map +1 -0
  60. package/dist/cli/experimental/commands/server.js +25 -0
  61. package/dist/cli/experimental/commands/server.js.map +1 -0
  62. package/dist/cli/experimental/transport-address.d.ts +10 -0
  63. package/dist/cli/experimental/transport-address.d.ts.map +1 -0
  64. package/dist/cli/experimental/transport-address.js +38 -0
  65. package/dist/cli/experimental/transport-address.js.map +1 -0
  66. package/dist/cli/file-processor.d.ts.map +1 -1
  67. package/dist/cli/file-processor.js +13 -26
  68. package/dist/cli/file-processor.js.map +1 -1
  69. package/dist/cli/initial-message.d.ts +1 -1
  70. package/dist/cli/initial-message.d.ts.map +1 -1
  71. package/dist/cli/initial-message.js.map +1 -1
  72. package/dist/cli/list-models.d.ts +2 -2
  73. package/dist/cli/list-models.d.ts.map +1 -1
  74. package/dist/cli/list-models.js +4 -4
  75. package/dist/cli/list-models.js.map +1 -1
  76. package/dist/cli/project-trust.d.ts +10 -0
  77. package/dist/cli/project-trust.d.ts.map +1 -0
  78. package/dist/cli/project-trust.js +48 -0
  79. package/dist/cli/project-trust.js.map +1 -0
  80. package/dist/cli/session-picker.d.ts +3 -2
  81. package/dist/cli/session-picker.d.ts.map +1 -1
  82. package/dist/cli/session-picker.js +5 -4
  83. package/dist/cli/session-picker.js.map +1 -1
  84. package/dist/cli/startup-ui.d.ts +20 -0
  85. package/dist/cli/startup-ui.d.ts.map +1 -0
  86. package/dist/cli/startup-ui.js +184 -0
  87. package/dist/cli/startup-ui.js.map +1 -0
  88. package/dist/cli.d.ts.map +1 -1
  89. package/dist/cli.js +6 -3
  90. package/dist/cli.js.map +1 -1
  91. package/dist/client/index.d.ts +3 -0
  92. package/dist/client/index.d.ts.map +1 -0
  93. package/dist/client/index.js +3 -0
  94. package/dist/client/index.js.map +1 -0
  95. package/dist/client/remote-session.d.ts +53 -0
  96. package/dist/client/remote-session.d.ts.map +1 -0
  97. package/dist/client/remote-session.js +340 -0
  98. package/dist/client/remote-session.js.map +1 -0
  99. package/dist/client/transcript.d.ts +12 -0
  100. package/dist/client/transcript.d.ts.map +1 -0
  101. package/dist/client/transcript.js +98 -0
  102. package/dist/client/transcript.js.map +1 -0
  103. package/dist/config.d.ts +34 -12
  104. package/dist/config.d.ts.map +1 -1
  105. package/dist/config.js +312 -61
  106. package/dist/config.js.map +1 -1
  107. package/dist/core/agent-session-runtime.d.ts +11 -9
  108. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  109. package/dist/core/agent-session-runtime.js +16 -7
  110. package/dist/core/agent-session-runtime.js.map +1 -1
  111. package/dist/core/agent-session-services.d.ts +13 -12
  112. package/dist/core/agent-session-services.d.ts.map +1 -1
  113. package/dist/core/agent-session-services.js +34 -14
  114. package/dist/core/agent-session-services.js.map +1 -1
  115. package/dist/core/agent-session.d.ts +110 -53
  116. package/dist/core/agent-session.d.ts.map +1 -1
  117. package/dist/core/agent-session.js +662 -488
  118. package/dist/core/agent-session.js.map +1 -1
  119. package/dist/core/auth-guidance.d.ts.map +1 -1
  120. package/dist/core/auth-guidance.js.map +1 -1
  121. package/dist/core/auth-storage.d.ts +35 -104
  122. package/dist/core/auth-storage.d.ts.map +1 -1
  123. package/dist/core/auth-storage.js +272 -286
  124. package/dist/core/auth-storage.js.map +1 -1
  125. package/dist/core/bash-executor.d.ts +1 -1
  126. package/dist/core/bash-executor.d.ts.map +1 -1
  127. package/dist/core/bash-executor.js +11 -8
  128. package/dist/core/bash-executor.js.map +1 -1
  129. package/dist/core/cache-stats.d.ts +49 -0
  130. package/dist/core/cache-stats.d.ts.map +1 -0
  131. package/dist/core/cache-stats.js +101 -0
  132. package/dist/core/cache-stats.js.map +1 -0
  133. package/dist/core/compaction/branch-summarization.d.ts +16 -6
  134. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  135. package/dist/core/compaction/branch-summarization.js +13 -10
  136. package/dist/core/compaction/branch-summarization.js.map +1 -1
  137. package/dist/core/compaction/compaction.d.ts +25 -9
  138. package/dist/core/compaction/compaction.d.ts.map +1 -1
  139. package/dist/core/compaction/compaction.js +163 -133
  140. package/dist/core/compaction/compaction.js.map +1 -1
  141. package/dist/core/compaction/index.d.ts +3 -3
  142. package/dist/core/compaction/index.d.ts.map +1 -1
  143. package/dist/core/compaction/index.js.map +1 -1
  144. package/dist/core/compaction/utils.d.ts +3 -3
  145. package/dist/core/compaction/utils.d.ts.map +1 -1
  146. package/dist/core/compaction/utils.js +7 -18
  147. package/dist/core/compaction/utils.js.map +1 -1
  148. package/dist/core/defaults.d.ts +1 -1
  149. package/dist/core/defaults.d.ts.map +1 -1
  150. package/dist/core/defaults.js.map +1 -1
  151. package/dist/core/env-overlay.d.ts +21 -0
  152. package/dist/core/env-overlay.d.ts.map +1 -0
  153. package/dist/core/env-overlay.js +25 -0
  154. package/dist/core/env-overlay.js.map +1 -0
  155. package/dist/core/exec.d.ts +8 -1
  156. package/dist/core/exec.d.ts.map +1 -1
  157. package/dist/core/exec.js +7 -1
  158. package/dist/core/exec.js.map +1 -1
  159. package/dist/core/experimental.d.ts +6 -0
  160. package/dist/core/experimental.d.ts.map +1 -0
  161. package/dist/core/experimental.js +8 -0
  162. package/dist/core/experimental.js.map +1 -0
  163. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  164. package/dist/core/export-html/ansi-to-html.js +1 -1
  165. package/dist/core/export-html/ansi-to-html.js.map +1 -1
  166. package/dist/core/export-html/index.d.ts +2 -2
  167. package/dist/core/export-html/index.d.ts.map +1 -1
  168. package/dist/core/export-html/index.js +8 -6
  169. package/dist/core/export-html/index.js.map +1 -1
  170. package/dist/core/export-html/template.css +53 -4
  171. package/dist/core/export-html/template.js +129 -35
  172. package/dist/core/export-html/tool-renderer.d.ts +2 -8
  173. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  174. package/dist/core/export-html/tool-renderer.js +15 -2
  175. package/dist/core/export-html/tool-renderer.js.map +1 -1
  176. package/dist/core/export-html/vendor/marked.min.js +75 -3
  177. package/dist/core/extensions/index.d.ts +8 -8
  178. package/dist/core/extensions/index.d.ts.map +1 -1
  179. package/dist/core/extensions/index.js.map +1 -1
  180. package/dist/core/extensions/loader.d.ts +5 -7
  181. package/dist/core/extensions/loader.d.ts.map +1 -1
  182. package/dist/core/extensions/loader.js +161 -79
  183. package/dist/core/extensions/loader.js.map +1 -1
  184. package/dist/core/extensions/runner.d.ts +32 -12
  185. package/dist/core/extensions/runner.d.ts.map +1 -1
  186. package/dist/core/extensions/runner.js +194 -3
  187. package/dist/core/extensions/runner.js.map +1 -1
  188. package/dist/core/extensions/types.d.ts +217 -59
  189. package/dist/core/extensions/types.d.ts.map +1 -1
  190. package/dist/core/extensions/types.js.map +1 -1
  191. package/dist/core/extensions/wrapper.d.ts +3 -3
  192. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  193. package/dist/core/extensions/wrapper.js +22 -3
  194. package/dist/core/extensions/wrapper.js.map +1 -1
  195. package/dist/core/footer-data-provider.d.ts +12 -0
  196. package/dist/core/footer-data-provider.d.ts.map +1 -1
  197. package/dist/core/footer-data-provider.js +30 -2
  198. package/dist/core/footer-data-provider.js.map +1 -1
  199. package/dist/core/http-dispatcher.d.ts +22 -0
  200. package/dist/core/http-dispatcher.d.ts.map +1 -0
  201. package/dist/core/http-dispatcher.js +96 -0
  202. package/dist/core/http-dispatcher.js.map +1 -0
  203. package/dist/core/index.d.ts +9 -8
  204. package/dist/core/index.d.ts.map +1 -1
  205. package/dist/core/index.js +1 -0
  206. package/dist/core/index.js.map +1 -1
  207. package/dist/core/keybindings.d.ts +79 -10
  208. package/dist/core/keybindings.d.ts.map +1 -1
  209. package/dist/core/keybindings.js +11 -10
  210. package/dist/core/keybindings.js.map +1 -1
  211. package/dist/core/messages.d.ts +2 -2
  212. package/dist/core/messages.d.ts.map +1 -1
  213. package/dist/core/messages.js.map +1 -1
  214. package/dist/core/model-config.d.ts +571 -0
  215. package/dist/core/model-config.d.ts.map +1 -0
  216. package/dist/core/model-config.js +254 -0
  217. package/dist/core/model-config.js.map +1 -0
  218. package/dist/core/model-registry.d.ts +23 -110
  219. package/dist/core/model-registry.d.ts.map +1 -1
  220. package/dist/core/model-registry.js +65 -616
  221. package/dist/core/model-registry.js.map +1 -1
  222. package/dist/core/model-resolver.d.ts +20 -7
  223. package/dist/core/model-resolver.d.ts.map +1 -1
  224. package/dist/core/model-resolver.js +139 -43
  225. package/dist/core/model-resolver.js.map +1 -1
  226. package/dist/core/model-runtime.d.ts +100 -0
  227. package/dist/core/model-runtime.d.ts.map +1 -0
  228. package/dist/core/model-runtime.js +602 -0
  229. package/dist/core/model-runtime.js.map +1 -0
  230. package/dist/core/models-store.d.ts +22 -0
  231. package/dist/core/models-store.d.ts.map +1 -0
  232. package/dist/core/models-store.js +113 -0
  233. package/dist/core/models-store.js.map +1 -0
  234. package/dist/core/output-guard.d.ts +1 -0
  235. package/dist/core/output-guard.d.ts.map +1 -1
  236. package/dist/core/output-guard.js +52 -22
  237. package/dist/core/output-guard.js.map +1 -1
  238. package/dist/core/package-manager.d.ts +21 -4
  239. package/dist/core/package-manager.d.ts.map +1 -1
  240. package/dist/core/package-manager.js +428 -191
  241. package/dist/core/package-manager.js.map +1 -1
  242. package/dist/core/pi-manifest.d.ts +8 -0
  243. package/dist/core/pi-manifest.d.ts.map +1 -0
  244. package/dist/core/pi-manifest.js +25 -0
  245. package/dist/core/pi-manifest.js.map +1 -0
  246. package/dist/core/project-trust.d.ts +15 -0
  247. package/dist/core/project-trust.d.ts.map +1 -0
  248. package/dist/core/project-trust.js +59 -0
  249. package/dist/core/project-trust.js.map +1 -0
  250. package/dist/core/prompt-templates.d.ts +4 -2
  251. package/dist/core/prompt-templates.d.ts.map +1 -1
  252. package/dist/core/prompt-templates.js +36 -50
  253. package/dist/core/prompt-templates.js.map +1 -1
  254. package/dist/core/provider-attribution.d.ts +4 -0
  255. package/dist/core/provider-attribution.d.ts.map +1 -0
  256. package/dist/core/provider-attribution.js +72 -0
  257. package/dist/core/provider-attribution.js.map +1 -0
  258. package/dist/core/provider-composer.d.ts +58 -0
  259. package/dist/core/provider-composer.d.ts.map +1 -0
  260. package/dist/core/provider-composer.js +396 -0
  261. package/dist/core/provider-composer.js.map +1 -0
  262. package/dist/core/radius.d.ts +2 -0
  263. package/dist/core/radius.d.ts.map +1 -0
  264. package/dist/core/radius.js +2 -0
  265. package/dist/core/radius.js.map +1 -0
  266. package/dist/core/remote-catalog-provider.d.ts +17 -0
  267. package/dist/core/remote-catalog-provider.d.ts.map +1 -0
  268. package/dist/core/remote-catalog-provider.js +137 -0
  269. package/dist/core/remote-catalog-provider.js.map +1 -0
  270. package/dist/core/resolve-config-value.d.ts +13 -6
  271. package/dist/core/resolve-config-value.d.ts.map +1 -1
  272. package/dist/core/resolve-config-value.js +143 -22
  273. package/dist/core/resolve-config-value.js.map +1 -1
  274. package/dist/core/resource-loader.d.ts +40 -12
  275. package/dist/core/resource-loader.d.ts.map +1 -1
  276. package/dist/core/resource-loader.js +236 -87
  277. package/dist/core/resource-loader.js.map +1 -1
  278. package/dist/core/runtime-credentials.d.ts +15 -0
  279. package/dist/core/runtime-credentials.d.ts.map +1 -0
  280. package/dist/core/runtime-credentials.js +39 -0
  281. package/dist/core/runtime-credentials.js.map +1 -0
  282. package/dist/core/sdk.d.ts +26 -25
  283. package/dist/core/sdk.d.ts.map +1 -1
  284. package/dist/core/sdk.js +56 -49
  285. package/dist/core/sdk.js.map +1 -1
  286. package/dist/core/session-manager.d.ts +42 -19
  287. package/dist/core/session-manager.d.ts.map +1 -1
  288. package/dist/core/session-manager.js +454 -223
  289. package/dist/core/session-manager.js.map +1 -1
  290. package/dist/core/settings-manager.d.ts +77 -8
  291. package/dist/core/settings-manager.d.ts.map +1 -1
  292. package/dist/core/settings-manager.js +255 -67
  293. package/dist/core/settings-manager.js.map +1 -1
  294. package/dist/core/skills.d.ts +2 -2
  295. package/dist/core/skills.d.ts.map +1 -1
  296. package/dist/core/skills.js +12 -34
  297. package/dist/core/skills.js.map +1 -1
  298. package/dist/core/slash-commands.d.ts +2 -1
  299. package/dist/core/slash-commands.d.ts.map +1 -1
  300. package/dist/core/slash-commands.js +4 -3
  301. package/dist/core/slash-commands.js.map +1 -1
  302. package/dist/core/source-info.d.ts +1 -1
  303. package/dist/core/source-info.d.ts.map +1 -1
  304. package/dist/core/source-info.js.map +1 -1
  305. package/dist/core/system-prompt.d.ts +1 -1
  306. package/dist/core/system-prompt.d.ts.map +1 -1
  307. package/dist/core/system-prompt.js +15 -25
  308. package/dist/core/system-prompt.js.map +1 -1
  309. package/dist/core/telemetry.d.ts +7 -1
  310. package/dist/core/telemetry.d.ts.map +1 -1
  311. package/dist/core/telemetry.js +7 -1
  312. package/dist/core/telemetry.js.map +1 -1
  313. package/dist/core/timings.d.ts +5 -3
  314. package/dist/core/timings.d.ts.map +1 -1
  315. package/dist/core/timings.js +26 -16
  316. package/dist/core/timings.js.map +1 -1
  317. package/dist/core/tools/bash.d.ts +11 -5
  318. package/dist/core/tools/bash.d.ts.map +1 -1
  319. package/dist/core/tools/bash.js +224 -185
  320. package/dist/core/tools/bash.js.map +1 -1
  321. package/dist/core/tools/edit-diff.d.ts +26 -5
  322. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  323. package/dist/core/tools/edit-diff.js +110 -23
  324. package/dist/core/tools/edit-diff.js.map +1 -1
  325. package/dist/core/tools/edit.d.ts +11 -5
  326. package/dist/core/tools/edit.d.ts.map +1 -1
  327. package/dist/core/tools/edit.js +67 -100
  328. package/dist/core/tools/edit.js.map +1 -1
  329. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  330. package/dist/core/tools/file-mutation-queue.js +27 -12
  331. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  332. package/dist/core/tools/find.d.ts +10 -3
  333. package/dist/core/tools/find.d.ts.map +1 -1
  334. package/dist/core/tools/find.js +41 -37
  335. package/dist/core/tools/find.js.map +1 -1
  336. package/dist/core/tools/grep.d.ts +7 -3
  337. package/dist/core/tools/grep.d.ts.map +1 -1
  338. package/dist/core/tools/grep.js +12 -8
  339. package/dist/core/tools/grep.js.map +1 -1
  340. package/dist/core/tools/index.d.ts +18 -18
  341. package/dist/core/tools/index.d.ts.map +1 -1
  342. package/dist/core/tools/index.js.map +1 -1
  343. package/dist/core/tools/ls.d.ts +7 -3
  344. package/dist/core/tools/ls.d.ts.map +1 -1
  345. package/dist/core/tools/ls.js +17 -15
  346. package/dist/core/tools/ls.js.map +1 -1
  347. package/dist/core/tools/output-accumulator.d.ts +52 -0
  348. package/dist/core/tools/output-accumulator.d.ts.map +1 -0
  349. package/dist/core/tools/output-accumulator.js +184 -0
  350. package/dist/core/tools/output-accumulator.js.map +1 -0
  351. package/dist/core/tools/path-utils.d.ts +2 -0
  352. package/dist/core/tools/path-utils.d.ts.map +1 -1
  353. package/dist/core/tools/path-utils.js +39 -21
  354. package/dist/core/tools/path-utils.js.map +1 -1
  355. package/dist/core/tools/read.d.ts +7 -3
  356. package/dist/core/tools/read.d.ts.map +1 -1
  357. package/dist/core/tools/read.js +101 -51
  358. package/dist/core/tools/read.js.map +1 -1
  359. package/dist/core/tools/render-utils.d.ts +5 -2
  360. package/dist/core/tools/render-utils.d.ts.map +1 -1
  361. package/dist/core/tools/render-utils.js +18 -2
  362. package/dist/core/tools/render-utils.js.map +1 -1
  363. package/dist/core/tools/tool-definition-wrapper.d.ts +2 -2
  364. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  365. package/dist/core/tools/tool-definition-wrapper.js +3 -3
  366. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  367. package/dist/core/tools/truncate.d.ts.map +1 -1
  368. package/dist/core/tools/truncate.js +12 -2
  369. package/dist/core/tools/truncate.js.map +1 -1
  370. package/dist/core/tools/write.d.ts +6 -2
  371. package/dist/core/tools/write.d.ts.map +1 -1
  372. package/dist/core/tools/write.js +35 -45
  373. package/dist/core/tools/write.js.map +1 -1
  374. package/dist/core/trust-manager.d.ts +36 -0
  375. package/dist/core/trust-manager.d.ts.map +1 -0
  376. package/dist/core/trust-manager.js +202 -0
  377. package/dist/core/trust-manager.js.map +1 -0
  378. package/dist/core/usage-totals.d.ts +19 -0
  379. package/dist/core/usage-totals.d.ts.map +1 -0
  380. package/dist/core/usage-totals.js +52 -0
  381. package/dist/core/usage-totals.js.map +1 -0
  382. package/dist/extensions/index.d.ts +3 -0
  383. package/dist/extensions/index.d.ts.map +1 -0
  384. package/dist/extensions/index.js +3 -0
  385. package/dist/extensions/index.js.map +1 -0
  386. package/dist/extensions/llama/client.d.ts +61 -0
  387. package/dist/extensions/llama/client.d.ts.map +1 -0
  388. package/dist/extensions/llama/client.js +302 -0
  389. package/dist/extensions/llama/client.js.map +1 -0
  390. package/dist/extensions/llama/huggingface.d.ts +23 -0
  391. package/dist/extensions/llama/huggingface.d.ts.map +1 -0
  392. package/dist/extensions/llama/huggingface.js +141 -0
  393. package/dist/extensions/llama/huggingface.js.map +1 -0
  394. package/dist/extensions/llama/index.d.ts +3 -0
  395. package/dist/extensions/llama/index.d.ts.map +1 -0
  396. package/dist/extensions/llama/index.js +217 -0
  397. package/dist/extensions/llama/index.js.map +1 -0
  398. package/dist/extensions/llama/provider.d.ts +10 -0
  399. package/dist/extensions/llama/provider.d.ts.map +1 -0
  400. package/dist/extensions/llama/provider.js +121 -0
  401. package/dist/extensions/llama/provider.js.map +1 -0
  402. package/dist/extensions/llama/ui.d.ts +42 -0
  403. package/dist/extensions/llama/ui.d.ts.map +1 -0
  404. package/dist/extensions/llama/ui.js +416 -0
  405. package/dist/extensions/llama/ui.js.map +1 -0
  406. package/dist/index.d.ts +34 -27
  407. package/dist/index.d.ts.map +1 -1
  408. package/dist/index.js +11 -5
  409. package/dist/index.js.map +1 -1
  410. package/dist/main.d.ts +2 -2
  411. package/dist/main.d.ts.map +1 -1
  412. package/dist/main.js +311 -101
  413. package/dist/main.js.map +1 -1
  414. package/dist/migrations.d.ts +5 -5
  415. package/dist/migrations.d.ts.map +1 -1
  416. package/dist/migrations.js +10 -10
  417. package/dist/migrations.js.map +1 -1
  418. package/dist/modes/index.d.ts +6 -5
  419. package/dist/modes/index.d.ts.map +1 -1
  420. package/dist/modes/index.js.map +1 -1
  421. package/dist/modes/interactive/components/armin.d.ts +1 -1
  422. package/dist/modes/interactive/components/armin.d.ts.map +1 -1
  423. package/dist/modes/interactive/components/armin.js.map +1 -1
  424. package/dist/modes/interactive/components/assistant-message.d.ts +8 -3
  425. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  426. package/dist/modes/interactive/components/assistant-message.js +55 -26
  427. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  428. package/dist/modes/interactive/components/bash-execution.d.ts +2 -2
  429. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  430. package/dist/modes/interactive/components/bash-execution.js +4 -4
  431. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  432. package/dist/modes/interactive/components/bordered-loader.d.ts +2 -2
  433. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  434. package/dist/modes/interactive/components/bordered-loader.js +1 -1
  435. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  436. package/dist/modes/interactive/components/branch-summary-message.d.ts +2 -2
  437. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  438. package/dist/modes/interactive/components/branch-summary-message.js +1 -1
  439. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  440. package/dist/modes/interactive/components/compaction-summary-message.d.ts +2 -2
  441. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  442. package/dist/modes/interactive/components/compaction-summary-message.js +1 -1
  443. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  444. package/dist/modes/interactive/components/config-selector.d.ts +37 -6
  445. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  446. package/dist/modes/interactive/components/config-selector.js +318 -34
  447. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  448. package/dist/modes/interactive/components/countdown-timer.d.ts +3 -3
  449. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  450. package/dist/modes/interactive/components/countdown-timer.js +2 -2
  451. package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  452. package/dist/modes/interactive/components/custom-editor.d.ts +2 -2
  453. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  454. package/dist/modes/interactive/components/custom-editor.js +9 -2
  455. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  456. package/dist/modes/interactive/components/custom-entry.d.ts +19 -0
  457. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -0
  458. package/dist/modes/interactive/components/custom-entry.js +52 -0
  459. package/dist/modes/interactive/components/custom-entry.js.map +1 -0
  460. package/dist/modes/interactive/components/custom-message.d.ts +6 -4
  461. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  462. package/dist/modes/interactive/components/custom-message.js +11 -3
  463. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  464. package/dist/modes/interactive/components/daxnuts.d.ts +1 -1
  465. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  466. package/dist/modes/interactive/components/daxnuts.js.map +1 -1
  467. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  468. package/dist/modes/interactive/components/diff.js.map +1 -1
  469. package/dist/modes/interactive/components/dynamic-border.d.ts +1 -1
  470. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  471. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  472. package/dist/modes/interactive/components/extension-editor.d.ts +5 -4
  473. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  474. package/dist/modes/interactive/components/extension-editor.js +19 -32
  475. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  476. package/dist/modes/interactive/components/extension-input.d.ts +1 -1
  477. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  478. package/dist/modes/interactive/components/extension-input.js +1 -1
  479. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  480. package/dist/modes/interactive/components/extension-selector.d.ts +3 -1
  481. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  482. package/dist/modes/interactive/components/extension-selector.js +7 -2
  483. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  484. package/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
  485. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -0
  486. package/dist/modes/interactive/components/first-time-setup.js +103 -0
  487. package/dist/modes/interactive/components/first-time-setup.js.map +1 -0
  488. package/dist/modes/interactive/components/footer.d.ts +9 -4
  489. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  490. package/dist/modes/interactive/components/footer.js +52 -31
  491. package/dist/modes/interactive/components/footer.js.map +1 -1
  492. package/dist/modes/interactive/components/index.d.ts +33 -31
  493. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  494. package/dist/modes/interactive/components/index.js +2 -0
  495. package/dist/modes/interactive/components/index.js.map +1 -1
  496. package/dist/modes/interactive/components/keybinding-hints.d.ts +6 -1
  497. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  498. package/dist/modes/interactive/components/keybinding-hints.js +20 -6
  499. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  500. package/dist/modes/interactive/components/login-dialog.d.ts +12 -6
  501. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  502. package/dist/modes/interactive/components/login-dialog.js +46 -17
  503. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  504. package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
  505. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
  506. package/dist/modes/interactive/components/markdown-transform.js +19 -0
  507. package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
  508. package/dist/modes/interactive/components/mermaid.d.ts +11 -0
  509. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
  510. package/dist/modes/interactive/components/mermaid.js +75 -0
  511. package/dist/modes/interactive/components/mermaid.js.map +1 -0
  512. package/dist/modes/interactive/components/model-selector.d.ts +13 -6
  513. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  514. package/dist/modes/interactive/components/model-selector.js +92 -44
  515. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  516. package/dist/modes/interactive/components/oauth-selector.d.ts +7 -4
  517. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  518. package/dist/modes/interactive/components/oauth-selector.js +32 -28
  519. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  520. package/dist/modes/interactive/components/scoped-models-selector.d.ts +5 -1
  521. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  522. package/dist/modes/interactive/components/scoped-models-selector.js +52 -14
  523. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  524. package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
  525. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  526. package/dist/modes/interactive/components/session-selector-search.js +1 -1
  527. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  528. package/dist/modes/interactive/components/session-selector.d.ts +4 -5
  529. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  530. package/dist/modes/interactive/components/session-selector.js +18 -16
  531. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  532. package/dist/modes/interactive/components/settings-selector.d.ts +23 -2
  533. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  534. package/dist/modes/interactive/components/settings-selector.js +322 -22
  535. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  536. package/dist/modes/interactive/components/show-images-selector.d.ts +1 -1
  537. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  538. package/dist/modes/interactive/components/show-images-selector.js +1 -1
  539. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  540. package/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -2
  541. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  542. package/dist/modes/interactive/components/skill-invocation-message.js +1 -1
  543. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  544. package/dist/modes/interactive/components/status-indicator.d.ts +28 -0
  545. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -0
  546. package/dist/modes/interactive/components/status-indicator.js +60 -0
  547. package/dist/modes/interactive/components/status-indicator.js.map +1 -0
  548. package/dist/modes/interactive/components/theme-selector.d.ts +1 -1
  549. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  550. package/dist/modes/interactive/components/theme-selector.js +1 -1
  551. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  552. package/dist/modes/interactive/components/thinking-selector.d.ts +2 -2
  553. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  554. package/dist/modes/interactive/components/thinking-selector.js +3 -2
  555. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  556. package/dist/modes/interactive/components/tool-execution.d.ts +2 -2
  557. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  558. package/dist/modes/interactive/components/tool-execution.js +33 -2
  559. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  560. package/dist/modes/interactive/components/tree-selector.d.ts +7 -2
  561. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  562. package/dist/modes/interactive/components/tree-selector.js +179 -26
  563. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  564. package/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  565. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -0
  566. package/dist/modes/interactive/components/trust-selector.js +91 -0
  567. package/dist/modes/interactive/components/trust-selector.js.map +1 -0
  568. package/dist/modes/interactive/components/user-message-selector.d.ts +1 -1
  569. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  570. package/dist/modes/interactive/components/user-message-selector.js +1 -1
  571. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  572. package/dist/modes/interactive/components/user-message.d.ts +9 -3
  573. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  574. package/dist/modes/interactive/components/user-message.js +26 -6
  575. package/dist/modes/interactive/components/user-message.js.map +1 -1
  576. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
  577. package/dist/modes/interactive/components/visual-truncate.js +1 -1
  578. package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
  579. package/dist/modes/interactive/external-editor.d.ts +12 -0
  580. package/dist/modes/interactive/external-editor.d.ts.map +1 -0
  581. package/dist/modes/interactive/external-editor.js +37 -0
  582. package/dist/modes/interactive/external-editor.js.map +1 -0
  583. package/dist/modes/interactive/interactive-mode.d.ts +104 -26
  584. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  585. package/dist/modes/interactive/interactive-mode.js +1565 -692
  586. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  587. package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
  588. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
  589. package/dist/modes/interactive/model-catalog-refresh.js +34 -0
  590. package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
  591. package/dist/modes/interactive/model-search.d.ts +12 -0
  592. package/dist/modes/interactive/model-search.d.ts.map +1 -0
  593. package/dist/modes/interactive/model-search.js +15 -0
  594. package/dist/modes/interactive/model-search.js.map +1 -0
  595. package/dist/modes/interactive/theme/dark.json +10 -5
  596. package/dist/modes/interactive/theme/light.json +10 -5
  597. package/dist/modes/interactive/theme/theme-controller.d.ts +40 -0
  598. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -0
  599. package/dist/modes/interactive/theme/theme-controller.js +125 -0
  600. package/dist/modes/interactive/theme/theme-controller.js.map +1 -0
  601. package/dist/modes/interactive/theme/theme-schema.json +22 -5
  602. package/dist/modes/interactive/theme/theme.d.ts +48 -7
  603. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  604. package/dist/modes/interactive/theme/theme.js +194 -76
  605. package/dist/modes/interactive/theme/theme.js.map +1 -1
  606. package/dist/modes/json-event.d.ts +31 -0
  607. package/dist/modes/json-event.d.ts.map +1 -0
  608. package/dist/modes/json-event.js +15 -0
  609. package/dist/modes/json-event.js.map +1 -0
  610. package/dist/modes/print-mode.d.ts +3 -3
  611. package/dist/modes/print-mode.d.ts.map +1 -1
  612. package/dist/modes/print-mode.js +16 -5
  613. package/dist/modes/print-mode.js.map +1 -1
  614. package/dist/modes/rpc/rpc-client.d.ts +33 -10
  615. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  616. package/dist/modes/rpc/rpc-client.js +89 -11
  617. package/dist/modes/rpc/rpc-client.js.map +1 -1
  618. package/dist/modes/rpc/rpc-mode.d.ts +2 -2
  619. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  620. package/dist/modes/rpc/rpc-mode.js +69 -9
  621. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  622. package/dist/modes/rpc/rpc-types.d.ts +43 -5
  623. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  624. package/dist/modes/rpc/rpc-types.js.map +1 -1
  625. package/dist/package-manager-cli.d.ts +6 -2
  626. package/dist/package-manager-cli.d.ts.map +1 -1
  627. package/dist/package-manager-cli.js +527 -25
  628. package/dist/package-manager-cli.js.map +1 -1
  629. package/dist/path-migration.d.ts +13 -0
  630. package/dist/path-migration.d.ts.map +1 -0
  631. package/dist/path-migration.js +52 -0
  632. package/dist/path-migration.js.map +1 -0
  633. package/dist/rpc-entry.d.ts +3 -0
  634. package/dist/rpc-entry.d.ts.map +1 -0
  635. package/dist/rpc-entry.js +11 -0
  636. package/dist/rpc-entry.js.map +1 -0
  637. package/dist/server/create-harness.d.ts +26 -0
  638. package/dist/server/create-harness.d.ts.map +1 -0
  639. package/dist/server/create-harness.js +106 -0
  640. package/dist/server/create-harness.js.map +1 -0
  641. package/dist/utils/abort.d.ts +5 -0
  642. package/dist/utils/abort.d.ts.map +1 -0
  643. package/dist/utils/abort.js +48 -0
  644. package/dist/utils/abort.js.map +1 -0
  645. package/dist/utils/ansi.d.ts +2 -0
  646. package/dist/utils/ansi.d.ts.map +1 -0
  647. package/dist/utils/ansi.js +52 -0
  648. package/dist/utils/ansi.js.map +1 -0
  649. package/dist/utils/changelog.d.ts +2 -1
  650. package/dist/utils/changelog.d.ts.map +1 -1
  651. package/dist/utils/changelog.js +85 -0
  652. package/dist/utils/changelog.js.map +1 -1
  653. package/dist/utils/child-process.d.ts +12 -5
  654. package/dist/utils/child-process.d.ts.map +1 -1
  655. package/dist/utils/child-process.js +33 -5
  656. package/dist/utils/child-process.js.map +1 -1
  657. package/dist/utils/clipboard-image.d.ts.map +1 -1
  658. package/dist/utils/clipboard-image.js +4 -4
  659. package/dist/utils/clipboard-image.js.map +1 -1
  660. package/dist/utils/clipboard-native.d.ts +4 -1
  661. package/dist/utils/clipboard-native.d.ts.map +1 -1
  662. package/dist/utils/clipboard-native.js +14 -8
  663. package/dist/utils/clipboard-native.js.map +1 -1
  664. package/dist/utils/clipboard.d.ts +2 -0
  665. package/dist/utils/clipboard.d.ts.map +1 -1
  666. package/dist/utils/clipboard.js +129 -46
  667. package/dist/utils/clipboard.js.map +1 -1
  668. package/dist/utils/deprecation.d.ts +4 -0
  669. package/dist/utils/deprecation.d.ts.map +1 -0
  670. package/dist/utils/deprecation.js +13 -0
  671. package/dist/utils/deprecation.js.map +1 -0
  672. package/dist/utils/exif-orientation.d.ts +1 -1
  673. package/dist/utils/exif-orientation.d.ts.map +1 -1
  674. package/dist/utils/exif-orientation.js.map +1 -1
  675. package/dist/utils/git.d.ts.map +1 -1
  676. package/dist/utils/git.js +54 -22
  677. package/dist/utils/git.js.map +1 -1
  678. package/dist/utils/html.d.ts +7 -0
  679. package/dist/utils/html.d.ts.map +1 -0
  680. package/dist/utils/html.js +40 -0
  681. package/dist/utils/html.js.map +1 -0
  682. package/dist/utils/image-convert.d.ts +1 -0
  683. package/dist/utils/image-convert.d.ts.map +1 -1
  684. package/dist/utils/image-convert.js +21 -15
  685. package/dist/utils/image-convert.js.map +1 -1
  686. package/dist/utils/image-process.d.ts +18 -0
  687. package/dist/utils/image-process.d.ts.map +1 -0
  688. package/dist/utils/image-process.js +83 -0
  689. package/dist/utils/image-process.js.map +1 -0
  690. package/dist/utils/image-resize-core.d.ts +30 -0
  691. package/dist/utils/image-resize-core.d.ts.map +1 -0
  692. package/dist/utils/image-resize-core.js +124 -0
  693. package/dist/utils/image-resize-core.js.map +1 -0
  694. package/dist/utils/image-resize-worker.d.ts +2 -0
  695. package/dist/utils/image-resize-worker.d.ts.map +1 -0
  696. package/dist/utils/image-resize-worker.js +31 -0
  697. package/dist/utils/image-resize-worker.js.map +1 -0
  698. package/dist/utils/image-resize.d.ts +7 -27
  699. package/dist/utils/image-resize.d.ts.map +1 -1
  700. package/dist/utils/image-resize.js +75 -115
  701. package/dist/utils/image-resize.js.map +1 -1
  702. package/dist/utils/json.d.ts +3 -0
  703. package/dist/utils/json.d.ts.map +1 -0
  704. package/dist/utils/json.js +7 -0
  705. package/dist/utils/json.js.map +1 -0
  706. package/dist/utils/management-http.d.ts +23 -0
  707. package/dist/utils/management-http.d.ts.map +1 -0
  708. package/dist/utils/management-http.js +50 -0
  709. package/dist/utils/management-http.js.map +1 -0
  710. package/dist/utils/mime.d.ts +1 -0
  711. package/dist/utils/mime.d.ts.map +1 -1
  712. package/dist/utils/mime.js +100 -16
  713. package/dist/utils/mime.js.map +1 -1
  714. package/dist/utils/open-browser.d.ts +9 -0
  715. package/dist/utils/open-browser.d.ts.map +1 -0
  716. package/dist/utils/open-browser.js +22 -0
  717. package/dist/utils/open-browser.js.map +1 -0
  718. package/dist/utils/paths.d.ts +28 -1
  719. package/dist/utils/paths.d.ts.map +1 -1
  720. package/dist/utils/paths.js +97 -2
  721. package/dist/utils/paths.js.map +1 -1
  722. package/dist/utils/pi-user-agent.d.ts +2 -0
  723. package/dist/utils/pi-user-agent.d.ts.map +1 -0
  724. package/dist/utils/pi-user-agent.js +5 -0
  725. package/dist/utils/pi-user-agent.js.map +1 -0
  726. package/dist/utils/shell.d.ts +1 -0
  727. package/dist/utils/shell.d.ts.map +1 -1
  728. package/dist/utils/shell.js +18 -6
  729. package/dist/utils/shell.js.map +1 -1
  730. package/dist/utils/syntax-highlight.d.ts +12 -0
  731. package/dist/utils/syntax-highlight.d.ts.map +1 -0
  732. package/dist/utils/syntax-highlight.js +118 -0
  733. package/dist/utils/syntax-highlight.js.map +1 -0
  734. package/dist/utils/tool-result-images.d.ts +19 -0
  735. package/dist/utils/tool-result-images.d.ts.map +1 -0
  736. package/dist/utils/tool-result-images.js +45 -0
  737. package/dist/utils/tool-result-images.js.map +1 -0
  738. package/dist/utils/tools-manager.d.ts +10 -1
  739. package/dist/utils/tools-manager.d.ts.map +1 -1
  740. package/dist/utils/tools-manager.js +105 -36
  741. package/dist/utils/tools-manager.js.map +1 -1
  742. package/dist/utils/version-check.d.ts +19 -0
  743. package/dist/utils/version-check.d.ts.map +1 -0
  744. package/dist/utils/version-check.js +85 -0
  745. package/dist/utils/version-check.js.map +1 -0
  746. package/dist/utils/windows-self-update.d.ts +3 -0
  747. package/dist/utils/windows-self-update.d.ts.map +1 -0
  748. package/dist/utils/windows-self-update.js +77 -0
  749. package/dist/utils/windows-self-update.js.map +1 -0
  750. package/docs/compaction.md +39 -32
  751. package/docs/containerization.md +113 -0
  752. package/docs/custom-provider.md +212 -75
  753. package/docs/development.md +9 -9
  754. package/docs/docs.json +156 -0
  755. package/docs/environment-variables.md +186 -0
  756. package/docs/extensions.md +652 -140
  757. package/docs/index.md +81 -0
  758. package/docs/json.md +26 -15
  759. package/docs/keybindings.md +60 -21
  760. package/docs/llama-cpp.md +99 -0
  761. package/docs/models.md +168 -34
  762. package/docs/packages.md +46 -36
  763. package/docs/prompt-templates.md +13 -5
  764. package/docs/providers.md +147 -26
  765. package/docs/quickstart.md +167 -0
  766. package/docs/rpc.md +218 -36
  767. package/docs/sdk.md +190 -125
  768. package/docs/security.md +59 -0
  769. package/docs/{session.md → session-format.md} +48 -22
  770. package/docs/sessions.md +145 -0
  771. package/docs/settings.md +130 -25
  772. package/docs/shell-aliases.md +2 -2
  773. package/docs/skills.md +13 -14
  774. package/docs/terminal-setup.md +73 -16
  775. package/docs/termux.md +10 -10
  776. package/docs/themes.md +41 -16
  777. package/docs/tmux.md +6 -4
  778. package/docs/tui.md +85 -61
  779. package/docs/usage.md +302 -0
  780. package/docs/windows.md +2 -2
  781. package/examples/README.md +1 -1
  782. package/examples/extensions/README.md +12 -9
  783. package/examples/extensions/bash-spawn-hook.ts +2 -2
  784. package/examples/extensions/border-status-editor.ts +145 -0
  785. package/examples/extensions/built-in-tool-renderer.ts +2 -2
  786. package/examples/extensions/claude-rules.ts +1 -1
  787. package/examples/extensions/commands.ts +1 -1
  788. package/examples/extensions/custom-compaction.ts +6 -16
  789. package/examples/extensions/custom-footer.ts +1 -1
  790. package/examples/extensions/custom-header.ts +7 -7
  791. package/examples/extensions/custom-provider-anthropic/index.ts +15 -8
  792. package/examples/extensions/custom-provider-anthropic/package-lock.json +4 -4
  793. package/examples/extensions/custom-provider-anthropic/package.json +3 -3
  794. package/examples/extensions/custom-provider-gitlab-duo/index.ts +65 -9
  795. package/examples/extensions/custom-provider-gitlab-duo/package.json +2 -2
  796. package/examples/extensions/custom-provider-gitlab-duo/test.ts +2 -2
  797. package/examples/extensions/doom-overlay/README.md +1 -1
  798. package/examples/extensions/doom-overlay/doom-component.ts +4 -4
  799. package/examples/extensions/doom-overlay/doom-keys.ts +1 -1
  800. package/examples/extensions/doom-overlay/index.ts +5 -5
  801. package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
  802. package/examples/extensions/dynamic-resources/dynamic.json +1 -1
  803. package/examples/extensions/entry-renderer.ts +41 -0
  804. package/examples/extensions/git-merge-and-resolve.ts +115 -0
  805. package/examples/extensions/github-issue-autocomplete.ts +2 -2
  806. package/examples/extensions/gondolin/index.ts +531 -0
  807. package/examples/extensions/gondolin/package-lock.json +185 -0
  808. package/examples/extensions/gondolin/package.json +19 -0
  809. package/examples/extensions/handoff.ts +50 -14
  810. package/examples/extensions/hidden-thinking-label.ts +1 -1
  811. package/examples/extensions/inline-bash.ts +2 -2
  812. package/examples/extensions/input-transform-streaming.ts +39 -0
  813. package/examples/extensions/input-transform.ts +2 -2
  814. package/examples/extensions/interactive-shell.ts +2 -2
  815. package/examples/extensions/kimi-deferred-tools.ts +61 -0
  816. package/examples/extensions/mac-system-theme.ts +2 -2
  817. package/examples/extensions/message-renderer.ts +3 -3
  818. package/examples/extensions/minimal-mode.ts +2 -2
  819. package/examples/extensions/modal-editor.ts +2 -2
  820. package/examples/extensions/model-status.ts +1 -1
  821. package/examples/extensions/notify.ts +3 -3
  822. package/examples/extensions/overlay-qa-tests.ts +242 -140
  823. package/examples/extensions/overlay-test.ts +9 -6
  824. package/examples/extensions/pirate.ts +1 -1
  825. package/examples/extensions/plan-mode/README.md +3 -2
  826. package/examples/extensions/plan-mode/index.ts +90 -40
  827. package/examples/extensions/preset.ts +16 -10
  828. package/examples/extensions/project-trust.ts +64 -0
  829. package/examples/extensions/prompt-customizer.ts +1 -1
  830. package/examples/extensions/provider-payload.ts +5 -5
  831. package/examples/extensions/qna.ts +4 -8
  832. package/examples/extensions/question.ts +41 -19
  833. package/examples/extensions/questionnaire.ts +50 -29
  834. package/examples/extensions/rainbow-editor.ts +1 -1
  835. package/examples/extensions/reload-runtime.ts +2 -2
  836. package/examples/extensions/rpc-demo.ts +1 -1
  837. package/examples/extensions/sandbox/index.ts +9 -9
  838. package/examples/extensions/sandbox/package-lock.json +7 -7
  839. package/examples/extensions/sandbox/package.json +3 -3
  840. package/examples/extensions/shutdown-command.ts +5 -5
  841. package/examples/extensions/snake.ts +2 -2
  842. package/examples/extensions/space-invaders.ts +2 -2
  843. package/examples/extensions/ssh.ts +2 -2
  844. package/examples/extensions/structured-output.ts +1 -1
  845. package/examples/extensions/subagent/README.md +18 -13
  846. package/examples/extensions/subagent/agents.ts +42 -11
  847. package/examples/extensions/subagent/index.ts +76 -30
  848. package/examples/extensions/summarize.ts +12 -19
  849. package/examples/extensions/tic-tac-toe.ts +2 -2
  850. package/examples/extensions/titlebar-spinner.ts +3 -3
  851. package/examples/extensions/todo.ts +2 -2
  852. package/examples/extensions/tool-override.ts +1 -1
  853. package/examples/extensions/tools.ts +7 -2
  854. package/examples/extensions/truncated-tool.ts +2 -2
  855. package/examples/extensions/with-deps/package-lock.json +4 -4
  856. package/examples/extensions/with-deps/package.json +4 -4
  857. package/examples/extensions/working-indicator.ts +4 -4
  858. package/examples/extensions/working-message-test.ts +1 -1
  859. package/examples/rpc-extension-ui.ts +11 -2
  860. package/examples/sdk/01-minimal.ts +15 -11
  861. package/examples/sdk/02-custom-model.ts +18 -18
  862. package/examples/sdk/03-custom-prompt.ts +25 -17
  863. package/examples/sdk/04-skills.ts +3 -3
  864. package/examples/sdk/05-tools.ts +8 -4
  865. package/examples/sdk/06-extensions.ts +13 -9
  866. package/examples/sdk/07-context-files.ts +2 -2
  867. package/examples/sdk/08-prompt-templates.ts +3 -3
  868. package/examples/sdk/09-api-keys-and-oauth.ts +19 -33
  869. package/examples/sdk/10-settings.ts +4 -4
  870. package/examples/sdk/11-sessions.ts +4 -0
  871. package/examples/sdk/12-full-control.ts +22 -21
  872. package/examples/sdk/README.md +23 -30
  873. package/npm-shrinkwrap.json +1818 -0
  874. package/package.json +117 -99
  875. package/dist/modes/interactive/assets/clankolas.png +0 -0
  876. package/dist/modes/interactive/components/auth-selector-status.d.ts +0 -20
  877. package/dist/modes/interactive/components/auth-selector-status.d.ts.map +0 -1
  878. package/dist/modes/interactive/components/auth-selector-status.js +0 -23
  879. package/dist/modes/interactive/components/auth-selector-status.js.map +0 -1
  880. package/dist/modes/interactive/components/earendil-announcement.d.ts +0 -5
  881. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +0 -1
  882. package/dist/modes/interactive/components/earendil-announcement.js +0 -40
  883. package/dist/modes/interactive/components/earendil-announcement.js.map +0 -1
  884. package/docs/images/exy.png +0 -0
  885. package/docs/tree.md +0 -233
  886. package/examples/extensions/antigravity-image-gen.ts +0 -418
  887. package/examples/extensions/custom-provider-qwen-cli/index.ts +0 -345
  888. package/examples/extensions/custom-provider-qwen-cli/package.json +0 -16
@@ -1,10 +1,10 @@
1
- > pi can create extensions. Ask it to build one for your use case.
1
+ > mcpi can create extensions. Ask it to build one for your use case.
2
2
 
3
3
  # Extensions
4
4
 
5
- Extensions are TypeScript modules that extend pi's behavior. They can subscribe to lifecycle events, register custom tools callable by the LLM, add commands, and more.
5
+ Extensions are TypeScript modules that extend mcpi's behavior. They can subscribe to lifecycle events, register custom tools callable by the LLM, add commands, and more. The extension API parameter remains named `pi`.
6
6
 
7
- > **Placement for /reload:** Put extensions in `~/.pi/agent/extensions/` (global) or `.pi/extensions/` (project-local) for auto-discovery. Use `pi -e ./path.ts` only for quick tests. Extensions in auto-discovered locations can be hot-reloaded with `/reload`.
7
+ > **Placement for /reload:** Put extensions in `$XDG_CONFIG_HOME/mcpi/extensions/` (fallback `~/.config/mcpi/extensions/`; `%APPDATA%\mcpi\extensions\` on Windows) or `.mcpi/extensions/` (project-local) for auto-discovery. Use `mcpi -e ./path.ts` only for quick tests. Extensions in auto-discovered locations can be hot-reloaded with `/reload`.
8
8
 
9
9
  **Key capabilities:**
10
10
  - **Custom tools** - Register tools the LLM can call via `pi.registerTool()`
@@ -40,12 +40,14 @@ See [examples/extensions/](../examples/extensions/) for working implementations.
40
40
  - [Resource Events](#resource-events)
41
41
  - [Session Events](#session-events)
42
42
  - [Agent Events](#agent-events)
43
+ - [Model Events](#model-events)
43
44
  - [Tool Events](#tool-events)
44
45
  - [ExtensionContext](#extensioncontext)
45
46
  - [ExtensionCommandContext](#extensioncommandcontext)
46
47
  - [ExtensionAPI Methods](#extensionapi-methods)
47
48
  - [State Management](#state-management)
48
49
  - [Custom Tools](#custom-tools)
50
+ - [Dynamic Tool Loading](#dynamic-tool-loading)
49
51
  - [Custom UI](#custom-ui)
50
52
  - [Error Handling](#error-handling)
51
53
  - [Mode Behavior](#mode-behavior)
@@ -53,10 +55,10 @@ See [examples/extensions/](../examples/extensions/) for working implementations.
53
55
 
54
56
  ## Quick Start
55
57
 
56
- Create `~/.pi/agent/extensions/my-extension.ts`:
58
+ Create `$XDG_CONFIG_HOME/mcpi/extensions/my-extension.ts` (fallback `~/.config/mcpi/extensions/my-extension.ts`; `%APPDATA%\mcpi\extensions\my-extension.ts` on Windows):
57
59
 
58
60
  ```typescript
59
- import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
61
+ import type { ExtensionAPI } from "@sammorrowdrums/mcpi";
60
62
  import { Type } from "typebox";
61
63
 
62
64
  export default function (pi: ExtensionAPI) {
@@ -101,21 +103,21 @@ export default function (pi: ExtensionAPI) {
101
103
  Test with `--extension` (or `-e`) flag:
102
104
 
103
105
  ```bash
104
- pi -e ./my-extension.ts
106
+ mcpi -e ./my-extension.ts
105
107
  ```
106
108
 
107
109
  ## Extension Locations
108
110
 
109
111
  > **Security:** Extensions run with your full system permissions and can execute arbitrary code. Only install from sources you trust.
110
112
 
111
- Extensions are auto-discovered from:
113
+ Extensions are auto-discovered from trusted locations. Project-local `.mcpi/extensions` entries load only after the project is trusted.
112
114
 
113
115
  | Location | Scope |
114
116
  |----------|-------|
115
- | `~/.pi/agent/extensions/*.ts` | Global (all projects) |
116
- | `~/.pi/agent/extensions/*/index.ts` | Global (subdirectory) |
117
- | `.pi/extensions/*.ts` | Project-local |
118
- | `.pi/extensions/*/index.ts` | Project-local (subdirectory) |
117
+ | `$XDG_CONFIG_HOME/mcpi/extensions/*.ts` | Global (all projects; uses the platform config fallback when XDG is unset) |
118
+ | `$XDG_CONFIG_HOME/mcpi/extensions/*/index.ts` | Global (subdirectory) |
119
+ | `.mcpi/extensions/*.ts` | Project-local |
120
+ | `.mcpi/extensions/*/index.ts` | Project-local (subdirectory) |
119
121
 
120
122
  Additional paths via `settings.json`:
121
123
 
@@ -132,20 +134,20 @@ Additional paths via `settings.json`:
132
134
  }
133
135
  ```
134
136
 
135
- To share extensions via npm or git as pi packages, see [packages.md](packages.md).
137
+ To share extensions via npm or git as mcpi packages, see [packages.md](packages.md).
136
138
 
137
139
  ## Available Imports
138
140
 
139
141
  | Package | Purpose |
140
142
  |---------|---------|
141
- | `@mariozechner/pi-coding-agent` | Extension types (`ExtensionAPI`, `ExtensionContext`, events) |
143
+ | `@sammorrowdrums/mcpi` | Extension types (`ExtensionAPI`, `ExtensionContext`, events) |
142
144
  | `typebox` | Schema definitions for tool parameters |
143
- | `@mariozechner/pi-ai` | AI utilities (`StringEnum` for Google-compatible enums) |
144
- | `@mariozechner/pi-tui` | TUI components for custom rendering |
145
+ | `@sammorrowdrums/mcpi-ai` | AI utilities (`StringEnum` for Google-compatible enums) |
146
+ | `@sammorrowdrums/mcpi-tui` | TUI components for custom rendering |
145
147
 
146
148
  npm dependencies work too. Add a `package.json` next to your extension (or in a parent directory), run `npm install`, and imports from `node_modules/` are resolved automatically.
147
149
 
148
- For distributed pi packages installed with `pi install` (npm or git), runtime deps must be in `dependencies`. Package installation uses production installs (`npm install --omit=dev`) by default, so `devDependencies` are not available at runtime; when `npmCommand` is configured, git packages use plain `install` for compatibility with wrappers.
150
+ For distributed mcpi packages installed with `mcpi install` (npm or git), runtime deps must be in `dependencies`. Package installation uses production installs (`npm install --omit=dev`) by default, so `devDependencies` are not available at runtime; when `npmCommand` is configured, git packages use plain `install` for compatibility with wrappers.
149
151
 
150
152
  Node.js built-ins (`node:fs`, `node:path`, etc.) are also available.
151
153
 
@@ -154,14 +156,14 @@ Node.js built-ins (`node:fs`, `node:path`, etc.) are also available.
154
156
  An extension exports a default factory function that receives `ExtensionAPI`. The factory can be synchronous or asynchronous:
155
157
 
156
158
  ```typescript
157
- import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
159
+ import type { ExtensionAPI } from "@sammorrowdrums/mcpi";
158
160
 
159
161
  export default function (pi: ExtensionAPI) {
160
162
  // Subscribe to events
161
163
  pi.on("event_name", async (event, ctx) => {
162
164
  // ctx.ui for user interaction
163
165
  const ok = await ctx.ui.confirm("Title", "Are you sure?");
164
- ctx.ui.notify("Done!", "success");
166
+ ctx.ui.notify("Done!", "info");
165
167
  ctx.ui.setStatus("my-ext", "Processing..."); // Footer status
166
168
  ctx.ui.setWidget("my-ext", ["Line 1", "Line 2"]); // Widget above editor (default)
167
169
  });
@@ -176,14 +178,14 @@ export default function (pi: ExtensionAPI) {
176
178
 
177
179
  Extensions are loaded via [jiti](https://github.com/unjs/jiti), so TypeScript works without compilation.
178
180
 
179
- If the factory returns a `Promise`, pi awaits it before continuing startup. That means async initialization completes before `session_start`, before `resources_discover`, and before provider registrations queued via `pi.registerProvider()` are flushed.
181
+ If the factory returns a `Promise`, mcpi awaits it before continuing startup. That means async initialization completes before `session_start`, before `resources_discover`, and before provider registrations queued via `pi.registerProvider()` are flushed.
180
182
 
181
183
  ### Async factory functions
182
184
 
183
185
  Use an async factory for one-time startup work such as fetching remote configuration or dynamically discovering available models.
184
186
 
185
187
  ```typescript
186
- import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
188
+ import type { ExtensionAPI } from "@sammorrowdrums/mcpi";
187
189
 
188
190
  export default async function (pi: ExtensionAPI) {
189
191
  const response = await fetch("http://localhost:1234/v1/models");
@@ -198,7 +200,7 @@ export default async function (pi: ExtensionAPI) {
198
200
 
199
201
  pi.registerProvider("local-openai", {
200
202
  baseUrl: "http://localhost:1234/v1",
201
- apiKey: "LOCAL_OPENAI_API_KEY",
203
+ apiKey: "$LOCAL_OPENAI_API_KEY",
202
204
  api: "openai-completions",
203
205
  models: payload.data.map((model) => ({
204
206
  id: model.id,
@@ -213,21 +215,27 @@ export default async function (pi: ExtensionAPI) {
213
215
  }
214
216
  ```
215
217
 
216
- This pattern makes the fetched models available during normal startup and to `pi --list-models`.
218
+ This pattern makes the fetched models available during normal startup and to `mcpi --list-models`.
219
+
220
+ ### Long-lived resources and shutdown
221
+
222
+ Extension factories may run in invocations that never start a session. Do not start background resources such as processes, sockets, file watchers, or timers from the factory.
223
+
224
+ Defer background resource startup until `session_start` or the command/tool/event that needs the resource. Register an idempotent `session_shutdown` handler to close any session-scoped resources you start.
217
225
 
218
226
  ### Extension Styles
219
227
 
220
228
  **Single file** - simplest, for small extensions:
221
229
 
222
230
  ```
223
- ~/.pi/agent/extensions/
231
+ ~/.config/mcpi/extensions/
224
232
  └── my-extension.ts
225
233
  ```
226
234
 
227
235
  **Directory with index.ts** - for multi-file extensions:
228
236
 
229
237
  ```
230
- ~/.pi/agent/extensions/
238
+ ~/.config/mcpi/extensions/
231
239
  └── my-extension/
232
240
  ├── index.ts # Entry point (exports default function)
233
241
  ├── tools.ts # Helper module
@@ -237,7 +245,7 @@ This pattern makes the fetched models available during normal startup and to `pi
237
245
  **Package with dependencies** - for extensions that need npm packages:
238
246
 
239
247
  ```
240
- ~/.pi/agent/extensions/
248
+ ~/.config/mcpi/extensions/
241
249
  └── my-extension/
242
250
  ├── package.json # Declares dependencies and entry points
243
251
  ├── package-lock.json
@@ -267,8 +275,9 @@ Run `npm install` in the extension directory, then imports from `node_modules/`
267
275
  ### Lifecycle Overview
268
276
 
269
277
  ```
270
- pi starts
278
+ mcpi starts
271
279
 
280
+ ├─► project_trust (user/global and CLI extensions only, before project resources load)
272
281
  ├─► session_start { reason: "startup" }
273
282
  └─► resources_discover { reason: "startup" }
274
283
 
@@ -286,6 +295,7 @@ user sends prompt ────────────────────
286
295
  │ │ │ │
287
296
  │ ├─► turn_start │ │
288
297
  │ ├─► context (can modify messages) │ │
298
+ │ ├─► before_provider_headers (can mutate headers) |
289
299
  │ ├─► before_provider_request (can inspect or replace payload)
290
300
  │ ├─► after_provider_response (status + headers, before stream consume)
291
301
  │ │ │ │
@@ -298,7 +308,8 @@ user sends prompt ────────────────────
298
308
  │ │ │ │
299
309
  │ └─► turn_end │ │
300
310
  │ │
301
- └─► agent_end │
311
+ ├─► agent_end │
312
+ └─► agent_settled (no retry/compaction/follow-up left) │
302
313
 
303
314
  user sends another prompt ◄────────────────────────────────┘
304
315
 
@@ -314,6 +325,9 @@ user sends another prompt ◄─────────────────
314
325
  ├─► session_start { reason: "fork", previousSessionFile }
315
326
  └─► resources_discover { reason: "startup" }
316
327
 
328
+ /name or pi.setSessionName()
329
+ └─► session_info_changed
330
+
317
331
  /compact or auto-compaction
318
332
  ├─► session_before_compact (can cancel or customize)
319
333
  └─► session_compact
@@ -323,12 +337,35 @@ user sends another prompt ◄─────────────────
323
337
  └─► session_tree
324
338
 
325
339
  /model or Ctrl+P (model selection/cycling)
340
+ ├─► thinking_level_select (if model change changes/clamps thinking level)
326
341
  └─► model_select
327
342
 
343
+ thinking level changes (settings, keybinding, pi.setThinkingLevel())
344
+ └─► thinking_level_select
345
+
328
346
  exit (Ctrl+C, Ctrl+D, SIGHUP, SIGTERM)
329
347
  └─► session_shutdown
330
348
  ```
331
349
 
350
+ ### Startup Events
351
+
352
+ #### project_trust
353
+
354
+ Fired before mcpi decides whether to trust a project with dynamic configs (`.mcpi` or `.agents/skills`). It runs during startup and when session replacement (for example `/resume`) enters a cwd whose trust has not been resolved in the current process. Only user/global extensions and CLI `-e` extensions participate; project-local extensions are not loaded until after trust is resolved.
355
+
356
+ ```typescript
357
+ pi.on("project_trust", async (event, ctx) => {
358
+ // event.cwd - current working directory
359
+ // ctx has a limited trust context: cwd, mode, hasUI, and select/confirm/input/notify UI helpers
360
+ if (await ctx.ui.confirm("Trust project?", event.cwd)) {
361
+ return { trusted: "yes", remember: true };
362
+ }
363
+ return { trusted: "undecided" };
364
+ });
365
+ ```
366
+
367
+ A `project_trust` handler must return `{ trusted: "yes" | "no" | "undecided" }`. A user/global or CLI extension that returns `"yes"` or `"no"` owns the decision; the first yes/no decision wins and suppresses the built-in trust prompt. Use `remember: true` to persist a yes/no decision; otherwise it applies only to the current process. Return `"undecided"` to let later handlers or the built-in trust flow decide. Check `ctx.hasUI` before prompting. If no handler returns yes/no, normal trust resolution continues: saved `trust.json` decisions apply first, then `defaultProjectTrust` controls whether mcpi asks, trusts, or declines by default.
368
+
332
369
  ### Resource Events
333
370
 
334
371
  #### resources_discover
@@ -350,7 +387,7 @@ pi.on("resources_discover", async (event, _ctx) => {
350
387
 
351
388
  ### Session Events
352
389
 
353
- See [session.md](session.md) for session storage internals and the SessionManager API.
390
+ See [Session Format](session-format.md) for session storage internals and the SessionManager API.
354
391
 
355
392
  #### session_start
356
393
 
@@ -364,6 +401,17 @@ pi.on("session_start", async (event, ctx) => {
364
401
  });
365
402
  ```
366
403
 
404
+ #### session_info_changed
405
+
406
+ Fired when the current session display name is set via `/name`, RPC, or `pi.setSessionName()`.
407
+
408
+ ```typescript
409
+ pi.on("session_info_changed", async (event, ctx) => {
410
+ // event.name - current normalized name, or undefined if cleared
411
+ ctx.ui.notify(`Session renamed: ${event.name ?? "(none)"}`, "info");
412
+ });
413
+ ```
414
+
367
415
  #### session_before_switch
368
416
 
369
417
  Fired before starting a new session (`/new`) or switching sessions (`/resume`).
@@ -380,7 +428,7 @@ pi.on("session_before_switch", async (event, ctx) => {
380
428
  });
381
429
  ```
382
430
 
383
- After a successful switch or new-session action, pi emits `session_shutdown` for the old extension instance, reloads and rebinds extensions for the new session, then emits `session_start` with `reason: "new" | "resume"` and `previousSessionFile`.
431
+ After a successful switch or new-session action, mcpi emits `session_shutdown` for the old extension instance, reloads and rebinds extensions for the new session, then emits `session_start` with `reason: "new" | "resume"` and `previousSessionFile`.
384
432
  Do cleanup work in `session_shutdown`, then reestablish any in-memory state in `session_start`.
385
433
 
386
434
  #### session_before_fork
@@ -397,7 +445,7 @@ pi.on("session_before_fork", async (event, ctx) => {
397
445
  });
398
446
  ```
399
447
 
400
- After a successful fork or clone, pi emits `session_shutdown` for the old extension instance, reloads and rebinds extensions for the new session, then emits `session_start` with `reason: "fork"` and `previousSessionFile`.
448
+ After a successful fork or clone, mcpi emits `session_shutdown` for the old extension instance, reloads and rebinds extensions for the new session, then emits `session_start` with `reason: "fork"` and `previousSessionFile`.
401
449
  Do cleanup work in `session_shutdown`, then reestablish any in-memory state in `session_start`.
402
450
 
403
451
  #### session_before_compact / session_compact
@@ -406,7 +454,10 @@ Fired on compaction. See [compaction.md](compaction.md) for details.
406
454
 
407
455
  ```typescript
408
456
  pi.on("session_before_compact", async (event, ctx) => {
409
- const { preparation, branchEntries, customInstructions, signal } = event;
457
+ const { preparation, branchEntries, customInstructions, reason, willRetry, signal } = event;
458
+
459
+ // reason - "manual" (/compact), "threshold", or "overflow"
460
+ // willRetry - whether the aborted turn is retried after compaction (overflow recovery)
410
461
 
411
462
  // Cancel:
412
463
  return { cancel: true };
@@ -417,6 +468,7 @@ pi.on("session_before_compact", async (event, ctx) => {
417
468
  summary: "...",
418
469
  firstKeptEntryId: preparation.firstKeptEntryId,
419
470
  tokensBefore: preparation.tokensBefore,
471
+ // usage: summaryResponse.usage, // Optional; included in session totals
420
472
  }
421
473
  };
422
474
  });
@@ -424,19 +476,27 @@ pi.on("session_before_compact", async (event, ctx) => {
424
476
  pi.on("session_compact", async (event, ctx) => {
425
477
  // event.compactionEntry - the saved compaction
426
478
  // event.fromExtension - whether extension provided it
479
+ // event.reason - "manual" (/compact), "threshold", or "overflow"
480
+ // event.willRetry - whether the aborted turn is retried after compaction (overflow recovery)
427
481
  });
428
482
  ```
429
483
 
430
484
  #### session_before_tree / session_tree
431
485
 
432
- Fired on `/tree` navigation. See [tree.md](tree.md) for tree navigation concepts.
486
+ Fired on `/tree` navigation. See [Sessions](sessions.md) for tree navigation concepts.
433
487
 
434
488
  ```typescript
435
489
  pi.on("session_before_tree", async (event, ctx) => {
436
490
  const { preparation, signal } = event;
437
491
  return { cancel: true };
438
492
  // OR provide custom summary:
439
- return { summary: { summary: "...", details: {} } };
493
+ return {
494
+ summary: {
495
+ summary: "...",
496
+ // usage: summaryResponse.usage, // Optional; included in session totals
497
+ details: {},
498
+ },
499
+ };
440
500
  });
441
501
 
442
502
  pi.on("session_tree", async (event, ctx) => {
@@ -446,7 +506,7 @@ pi.on("session_tree", async (event, ctx) => {
446
506
 
447
507
  #### session_shutdown
448
508
 
449
- Fired before an extension runtime is torn down.
509
+ Fired before a started session runtime is torn down. Use this to clean up resources opened from `session_start` or other session-scoped hooks.
450
510
 
451
511
  ```typescript
452
512
  pi.on("session_shutdown", async (event, ctx) => {
@@ -491,19 +551,23 @@ pi.on("before_agent_start", async (event, ctx) => {
491
551
  });
492
552
  ```
493
553
 
494
- The `systemPromptOptions` field gives extensions access to the same structured data Pi uses to build the system prompt. This lets you inspect what Pi has loaded — custom prompts, guidelines, tool snippets, context files, skills — without re-discovering resources or re-parsing flags. Use it when your extension needs to make deep, informed changes to the system prompt while respecting user-provided configuration.
554
+ The `systemPromptOptions` field gives extensions access to the same structured data mcpi uses to build the system prompt. This lets you inspect what mcpi has loaded — custom prompts, guidelines, tool snippets, context files, skills — without re-discovering resources or re-parsing flags. Use it when your extension needs to make deep, informed changes to the system prompt while respecting user-provided configuration.
495
555
 
496
556
  Inside `before_agent_start`, `event.systemPrompt` and `ctx.getSystemPrompt()` both reflect the chained system prompt as of the current handler. Later `before_agent_start` handlers can still modify it again.
497
557
 
498
- #### agent_start / agent_end
558
+ #### agent_start / agent_end / agent_settled
499
559
 
500
- Fired once per user prompt.
560
+ `agent_start` fires when a low-level agent run begins. `agent_end` fires when that run ends, but mcpi may still auto-retry, auto-compact and retry, or continue with queued follow-up messages. Use `agent_settled` for status integrations that need to know mcpi will not continue running automatically.
501
561
 
502
562
  ```typescript
503
563
  pi.on("agent_start", async (_event, ctx) => {});
504
564
 
505
565
  pi.on("agent_end", async (event, ctx) => {
506
- // event.messages - messages from this prompt
566
+ // event.messages - messages from this low-level run
567
+ });
568
+
569
+ pi.on("agent_settled", async (_event, ctx) => {
570
+ // ctx.isIdle() is true here unless another extension started a new run.
507
571
  });
508
572
  ```
509
573
 
@@ -527,6 +591,7 @@ Fired for message lifecycle updates.
527
591
 
528
592
  - `message_start` and `message_end` fire for user, assistant, and toolResult messages.
529
593
  - `message_update` fires for assistant streaming updates.
594
+ - `message_end` handlers can return `{ message }` to replace the finalized message. The replacement must keep the same `role`.
530
595
 
531
596
  ```typescript
532
597
  pi.on("message_start", async (event, ctx) => {
@@ -539,7 +604,20 @@ pi.on("message_update", async (event, ctx) => {
539
604
  });
540
605
 
541
606
  pi.on("message_end", async (event, ctx) => {
542
- // event.message
607
+ if (event.message.role !== "assistant") return;
608
+
609
+ return {
610
+ message: {
611
+ ...event.message,
612
+ usage: {
613
+ ...event.message.usage,
614
+ cost: {
615
+ ...event.message.usage.cost,
616
+ total: 0.123,
617
+ },
618
+ },
619
+ },
620
+ };
543
621
  });
544
622
  ```
545
623
 
@@ -569,7 +647,7 @@ pi.on("tool_execution_end", async (event, ctx) => {
569
647
 
570
648
  #### context
571
649
 
572
- Fired before each LLM call. Modify messages non-destructively. See [session.md](session.md) for message types.
650
+ Fired before each LLM call. Modify messages non-destructively. See [Session Format](session-format.md) for message types.
573
651
 
574
652
  ```typescript
575
653
  pi.on("context", async (event, ctx) => {
@@ -579,11 +657,29 @@ pi.on("context", async (event, ctx) => {
579
657
  });
580
658
  ```
581
659
 
660
+ #### before_provider_headers
661
+
662
+ Fired after the outgoing HTTP headers are assembled. Use it to add, override, or remove request headers.
663
+
664
+ Handlers mutate `event.headers` in place. Set a key to a string to add or override it, or to `null` to delete it.
665
+
666
+ ```typescript
667
+ pi.on("before_provider_headers", (event, ctx) => {
668
+ // Add or override — e.g. a session id for gateway tracing/attribution
669
+ event.headers["x-session-id"] = ctx.sessionManager.getSessionId();
670
+
671
+ // Drop a tracking header mcpi adds for this call
672
+ event.headers["X-OpenRouter-Title"] = null;
673
+ });
674
+ ```
675
+
676
+ Runs once per provider request; retries reuse the same headers rather than re-firing the hook.
677
+
582
678
  #### before_provider_request
583
679
 
584
680
  Fired after the provider-specific payload is built, right before the request is sent. Handlers run in extension load order. Returning `undefined` keeps the payload unchanged. Returning any other value replaces the payload for later handlers and for the actual request.
585
681
 
586
- This hook can rewrite provider-level system instructions or remove them entirely. Those payload-level changes are not reflected by `ctx.getSystemPrompt()`, which reports Pi's system prompt string rather than the final serialized provider payload.
682
+ This hook can rewrite provider-level system instructions or remove them entirely. Those payload-level changes are not reflected by `ctx.getSystemPrompt()`, which reports mcpi's system prompt string rather than the final serialized provider payload.
587
683
 
588
684
  ```typescript
589
685
  pi.on("before_provider_request", (event, ctx) => {
@@ -635,13 +731,28 @@ pi.on("model_select", async (event, ctx) => {
635
731
 
636
732
  Use this to update UI elements (status bars, footers) or perform model-specific initialization when the active model changes.
637
733
 
734
+ #### thinking_level_select
735
+
736
+ Fired when the thinking level changes. This is notification-only; handler return values are ignored.
737
+
738
+ ```typescript
739
+ pi.on("thinking_level_select", async (event, ctx) => {
740
+ // event.level - newly selected thinking level
741
+ // event.previousLevel - previous thinking level
742
+
743
+ ctx.ui.setStatus("thinking", `thinking: ${event.level}`);
744
+ });
745
+ ```
746
+
747
+ Use this to update extension UI when `pi.setThinkingLevel()`, model changes, or built-in thinking-level controls change the active thinking level.
748
+
638
749
  ### Tool Events
639
750
 
640
751
  #### tool_call
641
752
 
642
753
  Fired after `tool_execution_start`, before the tool executes. **Can block.** Use `isToolCallEventType` to narrow and get typed inputs.
643
754
 
644
- Before `tool_call` runs, pi waits for previously emitted Agent events to finish draining through `AgentSession`. This means `ctx.sessionManager` is up to date through the current assistant tool-calling message.
755
+ Before `tool_call` runs, mcpi waits for previously emitted Agent events to finish draining through `AgentSession`. This means `ctx.sessionManager` is up to date through the current assistant tool-calling message.
645
756
 
646
757
  In the default parallel tool execution mode, sibling tool calls from the same assistant message are preflighted sequentially, then executed concurrently. `tool_call` is not guaranteed to see sibling tool results from that same assistant message in `ctx.sessionManager`.
647
758
 
@@ -651,10 +762,11 @@ Behavior guarantees:
651
762
  - Mutations to `event.input` affect the actual tool execution
652
763
  - Later `tool_call` handlers see mutations made by earlier handlers
653
764
  - No re-validation is performed after your mutation
654
- - Return values from `tool_call` only control blocking via `{ block: true, reason?: string }`
765
+ - Return values from `tool_call` control blocking via `{ block: true, reason?: string, terminate?: boolean }`
766
+ - `terminate` only applies to a blocked call; the agent stops early only when every finalized result in the batch is terminating
655
767
 
656
768
  ```typescript
657
- import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
769
+ import { isToolCallEventType } from "@sammorrowdrums/mcpi";
658
770
 
659
771
  pi.on("tool_call", async (event, ctx) => {
660
772
  // event.toolName - "bash", "read", "write", "edit", etc.
@@ -667,7 +779,7 @@ pi.on("tool_call", async (event, ctx) => {
667
779
  event.input.command = `source ~/.profile\n${event.input.command}`;
668
780
 
669
781
  if (event.input.command.includes("rm -rf")) {
670
- return { block: true, reason: "Dangerous command" };
782
+ return { block: true, reason: "Dangerous command", terminate: true };
671
783
  }
672
784
  }
673
785
 
@@ -690,7 +802,7 @@ export type MyToolInput = Static<typeof myToolSchema>;
690
802
  Use `isToolCallEventType` with explicit type parameters:
691
803
 
692
804
  ```typescript
693
- import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
805
+ import { isToolCallEventType } from "@sammorrowdrums/mcpi";
694
806
  import type { MyToolInput } from "my-extension";
695
807
 
696
808
  pi.on("tool_call", (event) => {
@@ -709,16 +821,16 @@ In parallel tool mode, `tool_result` and `tool_execution_end` may interleave in
709
821
  `tool_result` handlers chain like middleware:
710
822
  - Handlers run in extension load order
711
823
  - Each handler sees the latest result after previous handler changes
712
- - Handlers can return partial patches (`content`, `details`, or `isError`); omitted fields keep their current values
824
+ - Handlers can return partial patches (`content`, `details`, `isError`, or `usage`); omitted fields keep their current values
713
825
 
714
826
  Use `ctx.signal` for nested async work inside the handler. This lets Esc cancel model calls, `fetch()`, and other abort-aware operations started by the extension.
715
827
 
716
828
  ```typescript
717
- import { isBashToolResult } from "@mariozechner/pi-coding-agent";
829
+ import { isBashToolResult } from "@sammorrowdrums/mcpi";
718
830
 
719
831
  pi.on("tool_result", async (event, ctx) => {
720
832
  // event.toolName, event.toolCallId, event.input
721
- // event.content, event.details, event.isError
833
+ // event.content, event.details, event.isError, event.usage
722
834
 
723
835
  if (isBashToolResult(event)) {
724
836
  // event.details is typed as BashToolDetails
@@ -731,7 +843,7 @@ pi.on("tool_result", async (event, ctx) => {
731
843
  });
732
844
 
733
845
  // Modify result:
734
- return { content: [...], details: {...}, isError: false };
846
+ return { content: [...], details: {...}, isError: false, usage: nestedModelUsage };
735
847
  });
736
848
  ```
737
849
 
@@ -742,7 +854,7 @@ pi.on("tool_result", async (event, ctx) => {
742
854
  Fired when user executes `!` or `!!` commands. **Can intercept.**
743
855
 
744
856
  ```typescript
745
- import { createLocalBashOperations } from "@mariozechner/pi-coding-agent";
857
+ import { createLocalBashOperations } from "@sammorrowdrums/mcpi";
746
858
 
747
859
  pi.on("user_bash", (event, ctx) => {
748
860
  // event.command - the bash command
@@ -752,7 +864,7 @@ pi.on("user_bash", (event, ctx) => {
752
864
  // Option 1: Provide custom operations (e.g., SSH)
753
865
  return { operations: remoteBashOps };
754
866
 
755
- // Option 2: Wrap pi's built-in local bash backend
867
+ // Option 2: Wrap mcpi's built-in local bash backend
756
868
  const local = createLocalBashOperations();
757
869
  return {
758
870
  operations: {
@@ -785,6 +897,9 @@ pi.on("input", async (event, ctx) => {
785
897
  // event.text - raw input (before skill/template expansion)
786
898
  // event.images - attached images, if any
787
899
  // event.source - "interactive" (typed), "rpc" (API), or "extension" (via sendUserMessage)
900
+ // event.streamingBehavior - "steer" | "followUp" | undefined
901
+ // undefined when idle, "steer" for mid-stream interrupts,
902
+ // "followUp" for messages queued until the agent finishes
788
903
 
789
904
  // Transform: rewrite input before expansion
790
905
  if (event.text.startsWith("?quick "))
@@ -813,7 +928,7 @@ pi.on("input", async (event, ctx) => {
813
928
  - `transform` - modify text/images, then continue to expansion
814
929
  - `handled` - skip agent entirely (first handler to return this wins)
815
930
 
816
- Transforms chain across handlers. See [input-transform.ts](../examples/extensions/input-transform.ts).
931
+ Transforms chain across handlers. See [input-transform.ts](../examples/extensions/input-transform.ts) and [input-transform-streaming.ts](../examples/extensions/input-transform-streaming.ts) for `streamingBehavior`-aware routing.
817
932
 
818
933
  ## ExtensionContext
819
934
 
@@ -823,29 +938,56 @@ All handlers receive `ctx: ExtensionContext`.
823
938
 
824
939
  UI methods for user interaction. See [Custom UI](#custom-ui) for full details.
825
940
 
941
+ ### ctx.mode
942
+
943
+ Current run mode: `"tui"`, `"rpc"`, `"json"`, or `"print"`. Use `ctx.mode === "tui"` to guard terminal-only features such as `custom()`, component factories, terminal input, and direct TUI rendering.
944
+
826
945
  ### ctx.hasUI
827
946
 
828
- `false` in print mode (`-p`) and JSON mode. `true` in interactive and RPC mode. In RPC mode, dialog methods (`select`, `confirm`, `input`, `editor`) work via the extension UI sub-protocol, and fire-and-forget methods (`notify`, `setStatus`, `setWidget`, `setTitle`, `setEditorText`) emit requests to the client. Some TUI-specific methods are no-ops or return defaults (see [rpc.md](rpc.md#extension-ui-protocol)).
947
+ `true` in TUI and RPC modes. `false` in print mode (`-p`) and JSON mode. Use this to guard dialog methods (`select`, `confirm`, `input`, `editor`) and fire-and-forget methods (`notify`, `setStatus`, `setWidget`, `setTitle`, `setEditorText`) that work in both TUI and RPC modes. In RPC mode, some TUI-specific methods are no-ops or return defaults (see [rpc.md](rpc.md#extension-ui-protocol)).
829
948
 
830
949
  ### ctx.cwd
831
950
 
832
951
  Current working directory.
833
952
 
953
+ Use `CONFIG_DIR_NAME` instead of hardcoding `.mcpi` when constructing project-local config paths.
954
+
955
+ ```typescript
956
+ import { CONFIG_DIR_NAME, type ExtensionAPI } from "@sammorrowdrums/mcpi";
957
+ import { join } from "node:path";
958
+
959
+ export default function (pi: ExtensionAPI) {
960
+ pi.on("session_start", (_event, ctx) => {
961
+ const projectConfigPath = join(ctx.cwd, CONFIG_DIR_NAME, "my-extension.json");
962
+ // ...
963
+ });
964
+ }
965
+ ```
966
+
967
+ ### ctx.isProjectTrusted()
968
+
969
+ Returns whether project-local trust is active for the current session context. This includes temporary trust decisions and CLI trust overrides, not just saved decisions in the global trust store.
970
+
971
+ Use this before reading project-local extension configuration that should only be honored for trusted projects.
972
+
834
973
  ### ctx.sessionManager
835
974
 
836
- Read-only access to session state. See [session.md](session.md) for the full SessionManager API and entry types.
975
+ Read-only access to session state. See [Session Format](session-format.md) for the full SessionManager API and entry types.
837
976
 
838
977
  For `tool_call`, this state is synchronized through the current assistant message before handlers run. In parallel tool execution mode it is still not guaranteed to include sibling tool results from the same assistant message.
839
978
 
840
979
  ```typescript
841
- ctx.sessionManager.getEntries() // All entries
842
- ctx.sessionManager.getBranch() // Current branch
843
- ctx.sessionManager.getLeafId() // Current leaf entry ID
980
+ ctx.sessionManager.getEntries() // All entries
981
+ ctx.sessionManager.getBranch() // Current branch
982
+ ctx.sessionManager.buildContextEntries() // Active branch entries with compaction applied
983
+ ctx.sessionManager.getLeafId() // Current leaf entry ID
844
984
  ```
845
985
 
846
- ### ctx.modelRegistry / ctx.model
986
+ ### ctx.modelRegistry / ctx.model / ctx.thinkingLevel / ctx.scopedModels
987
+
988
+ Access to models, providers, and resolved authentication. `ctx.modelRegistry.getProvider(id)` returns the effective pi-ai provider, while `getProviderAuth(id)` resolves its current API key, headers, base URL, and provider-scoped environment without requiring a loaded model. `ctx.model` is the active model, and `ctx.thinkingLevel` is its current effective thinking level.
847
989
 
848
- Access to models and API keys.
990
+ `ctx.scopedModels` is the read-only list of models scoped to the current session — the same set the `/scoped-models` command shows. It is resolved at session start from the `--models` CLI flag and the `enabledModels` setting (matched against the available catalogue with minimatch on `provider/modelId` or a bare `modelId`). It is empty when no scoping is configured, meaning every available model is usable. Each entry is `{ model, thinkingLevel? }`, where `thinkingLevel` is set only when a pattern pinned it (e.g. `anthropic/*:high`). Use it to populate a model picker that mirrors the built-in one instead of enumerating the whole catalogue via `ctx.modelRegistry.getAvailable()`.
849
991
 
850
992
  ### ctx.signal
851
993
 
@@ -857,7 +999,7 @@ Use this for abort-aware nested work started by extension handlers, for example:
857
999
  - file or process helpers that accept `AbortSignal`
858
1000
 
859
1001
  `ctx.signal` is typically defined during active turn events such as `tool_call`, `tool_result`, `message_update`, and `turn_end`.
860
- It is usually `undefined` in idle or non-turn contexts such as session events, extension commands, and shortcuts fired while pi is idle.
1002
+ It is usually `undefined` in idle or non-turn contexts such as session events, extension commands, and shortcuts fired while mcpi is idle.
861
1003
 
862
1004
  ```typescript
863
1005
  pi.on("tool_result", async (event, ctx) => {
@@ -874,11 +1016,11 @@ pi.on("tool_result", async (event, ctx) => {
874
1016
 
875
1017
  ### ctx.isIdle() / ctx.abort() / ctx.hasPendingMessages()
876
1018
 
877
- Control flow helpers.
1019
+ Control flow helpers. `ctx.isIdle()` is false while mcpi is processing an agent run, automatic retry, auto-compaction retry, or queued continuation.
878
1020
 
879
1021
  ### ctx.shutdown()
880
1022
 
881
- Request a graceful shutdown of pi.
1023
+ Request a graceful shutdown of mcpi.
882
1024
 
883
1025
  - **Interactive mode:** Deferred until the agent becomes idle (after processing all queued steering and follow-up messages).
884
1026
  - **RPC mode:** Deferred until the next idle state (after completing the current command response, when waiting for the next command).
@@ -923,7 +1065,7 @@ ctx.compact({
923
1065
 
924
1066
  ### ctx.getSystemPrompt()
925
1067
 
926
- Returns Pi's current system prompt string.
1068
+ Returns mcpi's current system prompt string.
927
1069
 
928
1070
  - During `before_agent_start`, this reflects chained system-prompt changes made so far for the current turn.
929
1071
  - It does not include later `context` message mutations.
@@ -941,9 +1083,22 @@ pi.on("before_agent_start", (event, ctx) => {
941
1083
 
942
1084
  Command handlers receive `ExtensionCommandContext`, which extends `ExtensionContext` with session control methods. These are only available in commands because they can deadlock if called from event handlers.
943
1085
 
1086
+ ### ctx.getSystemPromptOptions()
1087
+
1088
+ Returns the base inputs mcpi currently uses to build the system prompt.
1089
+
1090
+ ```typescript
1091
+ const options = ctx.getSystemPromptOptions();
1092
+ const contextPaths = options.contextFiles?.map((file) => file.path) ?? [];
1093
+ ```
1094
+
1095
+ This has the same shape and mutability as `before_agent_start` `event.systemPromptOptions`: custom prompt, active tools, tool snippets, prompt guidelines, appended system prompt text, cwd, loaded context files, and loaded skills. It may include full context file contents, so treat it as sensitive extension-local data and avoid exposing it through command lists, logs, or autocomplete metadata.
1096
+
1097
+ This reports the current base prompt inputs. It does not include per-turn `before_agent_start` chained system-prompt changes, later `context` event message mutations, or `before_provider_request` payload rewrites.
1098
+
944
1099
  ### ctx.waitForIdle()
945
1100
 
946
- Wait for the agent to finish streaming:
1101
+ Wait for the agent to fully settle, including automatic retries, auto-compaction retries, and queued continuations:
947
1102
 
948
1103
  ```typescript
949
1104
  pi.registerCommand("my-cmd", {
@@ -1053,7 +1208,7 @@ Options:
1053
1208
  To discover available sessions, use the static `SessionManager.list()` or `SessionManager.listAll()` methods:
1054
1209
 
1055
1210
  ```typescript
1056
- import { SessionManager } from "@mariozechner/pi-coding-agent";
1211
+ import { SessionManager } from "@sammorrowdrums/mcpi";
1057
1212
 
1058
1213
  pi.registerCommand("switch", {
1059
1214
  description: "Switch to another session",
@@ -1124,7 +1279,7 @@ Run the same reload flow as `/reload`.
1124
1279
 
1125
1280
  ```typescript
1126
1281
  pi.registerCommand("reload-runtime", {
1127
- description: "Reload extensions, skills, prompts, and themes",
1282
+ description: "Reload extensions, skills, prompts, themes, and context files",
1128
1283
  handler: async (_args, ctx) => {
1129
1284
  await ctx.reload();
1130
1285
  return;
@@ -1147,12 +1302,12 @@ Tools run with `ExtensionContext`, so they cannot call `ctx.reload()` directly.
1147
1302
  Example tool the LLM can call to trigger reload:
1148
1303
 
1149
1304
  ```typescript
1150
- import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
1305
+ import type { ExtensionAPI } from "@sammorrowdrums/mcpi";
1151
1306
  import { Type } from "typebox";
1152
1307
 
1153
1308
  export default function (pi: ExtensionAPI) {
1154
1309
  pi.registerCommand("reload-runtime", {
1155
- description: "Reload extensions, skills, prompts, and themes",
1310
+ description: "Reload extensions, skills, prompts, themes, and context files",
1156
1311
  handler: async (_args, ctx) => {
1157
1312
  await ctx.reload();
1158
1313
  return;
@@ -1162,7 +1317,7 @@ export default function (pi: ExtensionAPI) {
1162
1317
  pi.registerTool({
1163
1318
  name: "reload_runtime",
1164
1319
  label: "Reload Runtime",
1165
- description: "Reload extensions, skills, prompts, and themes",
1320
+ description: "Reload extensions, skills, prompts, themes, and context files",
1166
1321
  parameters: Type.Object({}),
1167
1322
  async execute() {
1168
1323
  pi.sendUserMessage("/reload-runtime", { deliverAs: "followUp" });
@@ -1196,7 +1351,7 @@ See [dynamic-tools.ts](../examples/extensions/dynamic-tools.ts) for a full examp
1196
1351
 
1197
1352
  ```typescript
1198
1353
  import { Type } from "typebox";
1199
- import { StringEnum } from "@mariozechner/pi-ai";
1354
+ import { StringEnum } from "@sammorrowdrums/mcpi-ai";
1200
1355
 
1201
1356
  pi.registerTool({
1202
1357
  name: "my_tool",
@@ -1233,7 +1388,7 @@ pi.registerTool({
1233
1388
 
1234
1389
  ### pi.sendMessage(message, options?)
1235
1390
 
1236
- Inject a custom message into the session.
1391
+ Inject a custom message into the session. Custom messages participate in LLM context. For durable TUI-only content that should not be sent to the LLM, use [`pi.appendEntry()`](#piappendentrycustomtype-data) with [`pi.registerEntryRenderer()`](#piregisterentryrenderercustomtype-renderer).
1237
1392
 
1238
1393
  ```typescript
1239
1394
  pi.sendMessage({
@@ -1271,12 +1426,16 @@ pi.sendUserMessage([
1271
1426
  // During streaming - must specify delivery mode
1272
1427
  pi.sendUserMessage("Focus on error handling", { deliverAs: "steer" });
1273
1428
  pi.sendUserMessage("And then summarize", { deliverAs: "followUp" });
1429
+
1430
+ // Opt in to extension command dispatch and skill/prompt template expansion
1431
+ pi.sendUserMessage("/review src/index.ts", { expandPromptTemplates: true });
1274
1432
  ```
1275
1433
 
1276
1434
  **Options:**
1277
1435
  - `deliverAs` - Required when agent is streaming:
1278
1436
  - `"steer"` - Queues the message for delivery after the current assistant turn finishes executing its tool calls
1279
1437
  - `"followUp"` - Waits for agent to finish all tools
1438
+ - `expandPromptTemplates` - Dispatch extension commands and expand skill commands and prompt templates. Defaults to `false`.
1280
1439
 
1281
1440
  When not streaming, the message is sent immediately and triggers a new turn. When streaming without `deliverAs`, throws an error.
1282
1441
 
@@ -1284,10 +1443,11 @@ See [send-user-message.ts](../examples/extensions/send-user-message.ts) for a co
1284
1443
 
1285
1444
  ### pi.appendEntry(customType, data?)
1286
1445
 
1287
- Persist extension state (does NOT participate in LLM context).
1446
+ Persist extension data. Custom entries do NOT participate in LLM context. In interactive mode, they can also render inside the chat transcript when paired with `pi.registerEntryRenderer()`.
1288
1447
 
1289
1448
  ```typescript
1290
1449
  pi.appendEntry("my-state", { count: 42 });
1450
+ pi.appendEntry("status-card", { title: "Indexed files", count: 17 });
1291
1451
 
1292
1452
  // Restore on reload
1293
1453
  pi.on("session_start", async (_event, ctx) => {
@@ -1339,7 +1499,7 @@ Labels persist in the session and survive restarts. Use them to mark important p
1339
1499
 
1340
1500
  Register a command.
1341
1501
 
1342
- If multiple extensions register the same command name, pi keeps them all and assigns numeric invocation suffixes in load order, for example `/review:1` and `/review:2`.
1502
+ If multiple extensions register the same command name, mcpi keeps them all and assigns numeric invocation suffixes in load order, for example `/review:1` and `/review:2`.
1343
1503
 
1344
1504
  ```typescript
1345
1505
  pi.registerCommand("stats", {
@@ -1354,7 +1514,7 @@ pi.registerCommand("stats", {
1354
1514
  Optional: add argument auto-completion for `/command ...`:
1355
1515
 
1356
1516
  ```typescript
1357
- import type { AutocompleteItem } from "@mariozechner/pi-tui";
1517
+ import type { AutocompleteItem } from "@sammorrowdrums/mcpi-tui";
1358
1518
 
1359
1519
  pi.registerCommand("deploy", {
1360
1520
  description: "Deploy to an environment",
@@ -1405,7 +1565,48 @@ mode and would not execute if sent via `prompt`.
1405
1565
 
1406
1566
  ### pi.registerMessageRenderer(customType, renderer)
1407
1567
 
1408
- Register a custom TUI renderer for messages with your `customType`. See [Custom UI](#custom-ui).
1568
+ Register a custom TUI renderer for custom messages with your `customType`. Custom messages are created with `pi.sendMessage()` and participate in LLM context. See [Custom UI](#custom-ui).
1569
+
1570
+ ### pi.registerMarkdownTransformer(transformer)
1571
+
1572
+ Register a transformer for the Markdown in normal user text, assistant text, and thinking blocks. Transformers run in extension load order, and each transformer receives the Markdown returned by the previous transformer. After the chain finishes, mcpi renders the transformed content with its built-in renderer.
1573
+
1574
+ The transformer receives the Markdown string and a context with:
1575
+
1576
+ - `messageType` — `"user"`, `"assistant"`, or `"assistant-thinking"`
1577
+ - `isStreaming` — `true` for partial assistant updates; `false` for user, finalized assistant, and restored messages
1578
+ - `availableWidth` — exact terminal columns available for the transformed Markdown content
1579
+
1580
+ Return the transformed Markdown:
1581
+
1582
+ ```typescript
1583
+ pi.registerMarkdownTransformer((markdown, { messageType, isStreaming }) => {
1584
+ if (isStreaming || messageType === "assistant-thinking") return markdown;
1585
+ return markdown.replaceAll("-->", "→");
1586
+ });
1587
+ ```
1588
+
1589
+ If a transformer throws, mcpi keeps the Markdown produced so far and continues with the next transformer. The hook is display-only: the original message remains unchanged in the session and model context. It runs for new user messages, assistant streaming updates, restored session messages, and terminal width changes, so transformers should remain synchronous and inexpensive.
1590
+
1591
+ ### pi.registerEntryRenderer(customType, renderer)
1592
+
1593
+ Register a custom TUI renderer for custom entries with your `customType`. Custom entries are created with `pi.appendEntry()` and do not participate in LLM context.
1594
+
1595
+ ```typescript
1596
+ import { Box, Text } from "@sammorrowdrums/mcpi-tui";
1597
+
1598
+ pi.registerEntryRenderer("status-card", (entry, { expanded }, theme) => {
1599
+ const data = entry.data as { title: string; count: number };
1600
+ const box = new Box(1, 1, (text) => theme.bg("customMessageBg", text));
1601
+ box.addChild(new Text(`${theme.bold(data.title)}: ${data.count}`));
1602
+ if (expanded) {
1603
+ box.addChild(new Text(theme.fg("dim", JSON.stringify(data, null, 2))));
1604
+ }
1605
+ return box;
1606
+ });
1607
+
1608
+ pi.appendEntry("status-card", { title: "Indexed files", count: 17 });
1609
+ ```
1409
1610
 
1410
1611
  ### pi.registerShortcut(shortcut, options)
1411
1612
 
@@ -1432,7 +1633,7 @@ pi.registerFlag("plan", {
1432
1633
  });
1433
1634
 
1434
1635
  // Check value
1435
- if (pi.getFlag("--plan")) {
1636
+ if (pi.getFlag("plan")) {
1436
1637
  // Plan mode enabled
1437
1638
  }
1438
1639
  ```
@@ -1446,26 +1647,68 @@ const result = await pi.exec("git", ["status"], { signal, timeout: 5000 });
1446
1647
  // result.stdout, result.stderr, result.code, result.killed
1447
1648
  ```
1448
1649
 
1650
+ Pass `env` to set variables for a single call. Values set this way take precedence over the session
1651
+ environment described below:
1652
+
1653
+ ```typescript
1654
+ await pi.exec("npm", ["test"], { env: { CI: "1" } });
1655
+ ```
1656
+
1657
+ ### Session Environment
1658
+
1659
+ #### pi.setEnv(key, value) / pi.unsetEnv(key)
1660
+
1661
+ Set environment variables for every subprocess mcpi spawns for the rest of the session. This covers
1662
+ both the LLM-callable bash tool and `pi.exec()`.
1663
+
1664
+ ```typescript
1665
+ export default function (pi) {
1666
+ pi.setEnv("NO_COLOR", "1");
1667
+ pi.setEnv("MY_TOOL_TOKEN", token);
1668
+ }
1669
+ ```
1670
+
1671
+ `pi.unsetEnv(key)` masks a variable so spawned commands do not see it. It removes a value set by
1672
+ `pi.setEnv()` *and* hides a variable mcpi itself inherited:
1673
+
1674
+ ```typescript
1675
+ pi.unsetEnv("GITHUB_TOKEN"); // Not visible to bash commands or pi.exec()
1676
+ ```
1677
+
1678
+ Semantics:
1679
+
1680
+ - The session environment is **shared by all extensions** and applies for the lifetime of the
1681
+ session. Later writes win.
1682
+ - mcpi's own `process.env` is **never** modified, so masking a variable does not affect mcpi itself or
1683
+ anything outside the spawned command.
1684
+ - Precedence is: per-call `pi.exec({ env })` > session environment > variables mcpi inherited.
1685
+ - Session metadata (`MCPI_SESSION_ID`, `MCPI_MODEL`, and friends) is injected first, so `pi.setEnv()`
1686
+ can override it and `pi.unsetEnv()` can hide it. See
1687
+ [environment-variables.md](environment-variables.md).
1688
+ - Values are applied when each command starts, so calling `pi.setEnv()` from an event handler
1689
+ affects the next command without a restart.
1690
+
1449
1691
  ### pi.getActiveTools() / pi.getAllTools() / pi.setActiveTools(names)
1450
1692
 
1451
- Manage active tools. This works for both built-in tools and dynamically registered tools.
1693
+ Manage active tools. This works for both built-in tools and dynamically registered tools. `pi.getActiveTools()` returns the active tool names as `string[]`; `pi.getAllTools()` returns metadata for all configured tools.
1452
1694
 
1453
1695
  ```typescript
1454
- const active = pi.getActiveTools();
1696
+ const active = pi.getActiveTools(); // ["read", "bash", ...]
1455
1697
  const all = pi.getAllTools();
1456
- // [{
1698
+ // all = [{
1457
1699
  // name: "read",
1458
1700
  // description: "Read file contents...",
1459
- // parameters: ...,
1701
+ // parameters: ...,
1702
+ // promptGuidelines: ["Use read to examine files instead of cat or sed."],
1460
1703
  // sourceInfo: { path: "<builtin:read>", source: "builtin", scope: "temporary", origin: "top-level" }
1461
1704
  // }, ...]
1462
- const names = all.map(t => t.name);
1463
1705
  const builtinTools = all.filter((t) => t.sourceInfo.source === "builtin");
1464
1706
  const extensionTools = all.filter((t) => t.sourceInfo.source !== "builtin" && t.sourceInfo.source !== "sdk");
1707
+ pi.setActiveTools([...new Set([...active, "my_custom_tool"])]); // Keep current tools and enable my_custom_tool
1465
1708
  pi.setActiveTools(["read", "bash"]); // Switch to read-only
1466
1709
  ```
1467
1710
 
1468
- `pi.getAllTools()` returns `name`, `description`, `parameters`, and `sourceInfo`.
1711
+ `pi.getAllTools()` returns `name`, `description`, `parameters`, `promptGuidelines`, and `sourceInfo`.
1469
1712
 
1470
1713
  Typical `sourceInfo.source` values:
1471
1714
  - `builtin` for built-in tools
@@ -1488,10 +1731,10 @@ if (model) {
1488
1731
 
1489
1732
  ### pi.getThinkingLevel() / pi.setThinkingLevel(level)
1490
1733
 
1491
- Get or set the thinking level. Level is clamped to model capabilities (non-reasoning models always use "off").
1734
+ Get or set the thinking level. Level is clamped to model capabilities (non-reasoning models always use "off"). Changes emit `thinking_level_select`.
1492
1735
 
1493
1736
  ```typescript
1494
- const current = pi.getThinkingLevel(); // "off" | "minimal" | "low" | "medium" | "high" | "xhigh"
1737
+ const current = pi.getThinkingLevel(); // "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max"
1495
1738
  pi.setThinkingLevel("high");
1496
1739
  ```
1497
1740
 
@@ -1510,13 +1753,46 @@ Register or override a model provider dynamically. Useful for proxies, custom en
1510
1753
 
1511
1754
  Calls made during the extension factory function are queued and applied once the runner initialises. Calls made after that — for example from a command handler following a user setup flow — take effect immediately without requiring a `/reload`.
1512
1755
 
1513
- If you need to discover models from a remote endpoint, prefer an async extension factory over deferring the fetch to `session_start`. pi waits for the factory before startup continues, so the registered models are available immediately, including to `pi --list-models`.
1756
+ Dynamic providers can implement `refreshModels`. mcpi calls it during model refresh, publishes the returned list synchronously through the provider, and passes the canonical credential/stored-catalog/network/signal context. The extension decides whether to persist catalog metadata through generation-checked `context.publish({ persist: entry })`; live servers such as llama.cpp can return models without persisting them.
1757
+
1758
+ `context.signal` is always a concrete signal and provider callbacks must pass it to blocking I/O. Public `ModelRuntime.refresh()` and `ModelRegistry.refresh()` calls accept an optional signal and are unbounded when it is omitted; extensions and applications choose their own deadlines. Cancellation stops the caller waiting even if a provider ignores the signal, but cooperation is still required to stop the underlying work.
1759
+
1760
+ Extensions that need native provider auth, filtering, refresh, or stream behavior can register a complete `Provider` from `@sammorrowdrums/mcpi-ai`. The provider becomes the composition base and `models.json` overrides still apply above it.
1514
1761
 
1515
1762
  ```typescript
1763
+ import { createProvider, openAICompletionsApi } from "@sammorrowdrums/mcpi-ai";
1764
+
1765
+ const provider = createProvider({
1766
+ id: "local-server",
1767
+ name: "Local Server",
1768
+ baseUrl: "http://localhost:8080/v1",
1769
+ auth: {
1770
+ apiKey: {
1771
+ name: "Local server setup",
1772
+ async login(interaction) {
1773
+ return {
1774
+ type: "api_key",
1775
+ key: await interaction.prompt({ type: "secret", message: "API key" }),
1776
+ };
1777
+ },
1778
+ async resolve({ credential }) {
1779
+ return credential?.key
1780
+ ? { auth: { apiKey: credential.key }, source: "stored API key" }
1781
+ : undefined;
1782
+ },
1783
+ },
1784
+ },
1785
+ models: [],
1786
+ api: openAICompletionsApi(),
1787
+ });
1788
+
1789
+ pi.registerProvider(provider);
1790
+
1516
1791
  // Register a new provider with custom models
1517
1792
  pi.registerProvider("my-proxy", {
1793
+ name: "My Proxy",
1518
1794
  baseUrl: "https://proxy.example.com",
1519
- apiKey: "PROXY_API_KEY", // env var name or literal
1795
+ apiKey: "$PROXY_API_KEY", // env var reference
1520
1796
  api: "anthropic-messages",
1521
1797
  models: [
1522
1798
  {
@@ -1531,6 +1807,26 @@ pi.registerProvider("my-proxy", {
1531
1807
  ]
1532
1808
  });
1533
1809
 
1810
+ // Register a live llama.cpp catalog without persisting discovered models
1811
+ pi.registerProvider("llama.cpp", {
1812
+ baseUrl: "http://localhost:8080/v1",
1813
+ apiKey: "local",
1814
+ api: "openai-completions",
1815
+ async refreshModels({ signal }) {
1816
+ const response = await fetch("http://localhost:8080/v1/models", { signal });
1817
+ const { data } = await response.json();
1818
+ return data.map(({ id }) => ({
1819
+ id,
1820
+ name: id,
1821
+ reasoning: false,
1822
+ input: ["text"],
1823
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1824
+ contextWindow: 128000,
1825
+ maxTokens: 16384
1826
+ }));
1827
+ }
1828
+ });
1829
+
1534
1830
  // Override baseUrl for an existing provider (keeps all models)
1535
1831
  pi.registerProvider("anthropic", {
1536
1832
  baseUrl: "https://proxy.example.com"
@@ -1549,7 +1845,8 @@ pi.registerProvider("corporate-ai", {
1549
1845
  const code = await callbacks.onPrompt({ message: "Enter code:" });
1550
1846
  return { refresh: code, access: code, expires: Date.now() + 3600000 };
1551
1847
  },
1552
- async refreshToken(credentials) {
1848
+ async refreshToken(credentials, signal) {
1849
+ signal.throwIfAborted();
1553
1850
  // Refresh logic
1554
1851
  return credentials;
1555
1852
  },
@@ -1560,13 +1857,17 @@ pi.registerProvider("corporate-ai", {
1560
1857
  });
1561
1858
  ```
1562
1859
 
1563
- **Config options:**
1860
+ The object form accepts a complete pi-ai `Provider`, including native `auth`, `getModels`, `refreshModels`, `filterModels`, `stream`, and `streamSimple` behavior.
1861
+
1862
+ **Legacy config options:**
1863
+ - `name` - Display name for the provider in UI such as `/login`.
1564
1864
  - `baseUrl` - API endpoint URL. Required when defining models.
1565
- - `apiKey` - API key or environment variable name. Required when defining models (unless `oauth` provided).
1865
+ - `apiKey` - API key literal, environment interpolation (`$ENV_VAR` or `${ENV_VAR}`), or leading `!command`. Required when defining models (unless `oauth` provided). `$$` escapes `$`, and `$!` escapes a literal `!` without triggering command execution.
1566
1866
  - `api` - API type: `"anthropic-messages"`, `"openai-completions"`, `"openai-responses"`, etc.
1567
1867
  - `headers` - Custom headers to include in requests.
1568
1868
  - `authHeader` - If true, adds `Authorization: Bearer` header automatically.
1569
- - `models` - Array of model definitions. If provided, replaces all existing models for this provider.
1869
+ - `models` - Array of model definitions. If provided, replaces all existing models for this provider. Model definitions can set `baseUrl` to override the provider endpoint for that model.
1870
+ - `refreshModels` - Async dynamic discovery callback. Its returned models replace extension-provided models. `context.stored` contains the persisted provider snapshot; use generation-checked `context.publish({ persist: entry })` only when updated catalog data should persist. Use `persist: null` to delete that snapshot.
1570
1871
  - `oauth` - OAuth provider config for `/login` support. When provided, the provider appears in the login menu.
1571
1872
  - `streamSimple` - Custom streaming implementation for non-standard APIs.
1572
1873
 
@@ -1642,7 +1943,7 @@ Pass the real target file path to `withFileMutationQueue()`, not the raw user ar
1642
1943
  Queue the entire mutation window on that target path. That includes read-modify-write logic, not just the final write.
1643
1944
 
1644
1945
  ```typescript
1645
- import { withFileMutationQueue } from "@mariozechner/pi-coding-agent";
1946
+ import { withFileMutationQueue } from "@sammorrowdrums/mcpi";
1646
1947
  import { mkdir, readFile, writeFile } from "node:fs/promises";
1647
1948
  import { dirname, resolve } from "node:path";
1648
1949
 
@@ -1667,8 +1968,8 @@ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
1667
1968
 
1668
1969
  ```typescript
1669
1970
  import { Type } from "typebox";
1670
- import { StringEnum } from "@mariozechner/pi-ai";
1671
- import { Text } from "@mariozechner/pi-tui";
1971
+ import { StringEnum } from "@sammorrowdrums/mcpi-ai";
1972
+ import { Text } from "@sammorrowdrums/mcpi-tui";
1672
1973
 
1673
1974
  pi.registerTool({
1674
1975
  name: "my_tool",
@@ -1710,6 +2011,7 @@ pi.registerTool({
1710
2011
  return {
1711
2012
  content: [{ type: "text", text: "Done" }], // Sent to LLM
1712
2013
  details: { data: result }, // For rendering & state
2014
+ // usage: nestedModelResponse.usage, // Optional nested LLM usage
1713
2015
  // Optional: stop after this tool batch when every finalized tool result
1714
2016
  // in the batch also returns terminate: true.
1715
2017
  terminate: true,
@@ -1722,6 +2024,8 @@ pi.registerTool({
1722
2024
  });
1723
2025
  ```
1724
2026
 
2027
+ **Usage accounting:** If a tool makes nested LLM calls, return their combined `Usage` as `usage`. mcpi persists it on the tool result and includes it in footer, `/session`, and RPC session totals. `tool_result` handlers can inspect or replace this value.
2028
+
1725
2029
  **Signaling errors:** To mark a tool execution as failed (sets `isError: true` on the result and reports it to the LLM), throw an error from `execute`. Returning a value never sets the error flag regardless of what properties you include in the return object.
1726
2030
 
1727
2031
  **Early termination:** Return `terminate: true` from `execute()` to hint that the automatic follow-up LLM call should be skipped after the current tool batch. This only takes effect when every finalized tool result in that batch is terminating. See [examples/extensions/structured-output.ts](../examples/extensions/structured-output.ts) for a minimal example where the agent ends on a final structured-output tool call.
@@ -1736,9 +2040,9 @@ async execute(toolCallId, params) {
1736
2040
  }
1737
2041
  ```
1738
2042
 
1739
- **Important:** Use `StringEnum` from `@mariozechner/pi-ai` for string enums. `Type.Union`/`Type.Literal` doesn't work with Google's API.
2043
+ **Important:** Use `StringEnum` from `@sammorrowdrums/mcpi-ai` for string enums. `Type.Union`/`Type.Literal` doesn't work with Google's API.
1740
2044
 
1741
- **Argument preparation:** `prepareArguments(args)` is optional. If defined, it runs before schema validation and before `execute()`. Use it to mimic an older accepted input shape when pi resumes an older session whose stored tool call arguments no longer match the current schema. Return the object you want validated against `parameters`. Keep the public schema strict. Do not add deprecated compatibility fields to `parameters` just to keep old resumed sessions working.
2045
+ **Argument preparation:** `prepareArguments(args)` is optional. If defined, it runs before schema validation and before `execute()`. Use it to mimic an older accepted input shape when mcpi resumes an older session whose stored tool call arguments no longer match the current schema. Return the object you want validated against `parameters`. Keep the public schema strict. Do not add deprecated compatibility fields to `parameters` just to keep old resumed sessions working.
1742
2046
 
1743
2047
  Example: an older session may contain an `edit` tool call with top-level `oldText` and `newText`, while the current schema only accepts `edits: [{ oldText, newText }]`.
1744
2048
 
@@ -1791,13 +2095,13 @@ Extensions can override built-in tools (`read`, `bash`, `edit`, `write`, `grep`,
1791
2095
 
1792
2096
  ```bash
1793
2097
  # Extension's read tool replaces built-in read
1794
- pi -e ./tool-override.ts
2098
+ mcpi -e ./tool-override.ts
1795
2099
  ```
1796
2100
 
1797
2101
  Alternatively, use `--no-builtin-tools` to start without any built-in tools while keeping extension tools enabled:
1798
2102
  ```bash
1799
2103
  # No built-in tools, only extension tools
1800
- pi --no-builtin-tools -e ./my-extension.ts
2104
+ mcpi --no-builtin-tools -e ./my-extension.ts
1801
2105
  ```
1802
2106
 
1803
2107
  See [examples/extensions/tool-override.ts](../examples/extensions/tool-override.ts) for a complete example that overrides `read` with logging and access control.
@@ -1809,20 +2113,20 @@ See [examples/extensions/tool-override.ts](../examples/extensions/tool-override.
1809
2113
  **Your implementation must match the exact result shape**, including the `details` type. The UI and session logic depend on these shapes for rendering and state tracking.
1810
2114
 
1811
2115
  Built-in tool implementations:
1812
- - [read.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/tools/read.ts) - `ReadToolDetails`
1813
- - [bash.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/tools/bash.ts) - `BashToolDetails`
1814
- - [edit.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/tools/edit.ts)
1815
- - [write.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/tools/write.ts)
1816
- - [grep.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/tools/grep.ts) - `GrepToolDetails`
1817
- - [find.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/tools/find.ts) - `FindToolDetails`
1818
- - [ls.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/tools/ls.ts) - `LsToolDetails`
2116
+ - [read.ts](https://github.com/SamMorrowDrums/mcpi/blob/main/packages/coding-agent/src/core/tools/read.ts) - `ReadToolDetails`
2117
+ - [bash.ts](https://github.com/SamMorrowDrums/mcpi/blob/main/packages/coding-agent/src/core/tools/bash.ts) - `BashToolDetails`
2118
+ - [edit.ts](https://github.com/SamMorrowDrums/mcpi/blob/main/packages/coding-agent/src/core/tools/edit.ts)
2119
+ - [write.ts](https://github.com/SamMorrowDrums/mcpi/blob/main/packages/coding-agent/src/core/tools/write.ts)
2120
+ - [grep.ts](https://github.com/SamMorrowDrums/mcpi/blob/main/packages/coding-agent/src/core/tools/grep.ts) - `GrepToolDetails`
2121
+ - [find.ts](https://github.com/SamMorrowDrums/mcpi/blob/main/packages/coding-agent/src/core/tools/find.ts) - `FindToolDetails`
2122
+ - [ls.ts](https://github.com/SamMorrowDrums/mcpi/blob/main/packages/coding-agent/src/core/tools/ls.ts) - `LsToolDetails`
1819
2123
 
1820
2124
  ### Remote Execution
1821
2125
 
1822
2126
  Built-in tools support pluggable operations for delegating to remote systems (SSH, containers, etc.):
1823
2127
 
1824
2128
  ```typescript
1825
- import { createReadTool, createBashTool, type ReadOperations } from "@mariozechner/pi-coding-agent";
2129
+ import { createReadTool, createBashTool, type ReadOperations } from "@sammorrowdrums/mcpi";
1826
2130
 
1827
2131
  // Create tool with custom operations
1828
2132
  const remoteRead = createReadTool(cwd, {
@@ -1848,12 +2152,12 @@ pi.registerTool({
1848
2152
 
1849
2153
  **Operations interfaces:** `ReadOperations`, `WriteOperations`, `EditOperations`, `BashOperations`, `LsOperations`, `GrepOperations`, `FindOperations`
1850
2154
 
1851
- For `user_bash`, extensions can reuse pi's local shell backend via `createLocalBashOperations()` instead of reimplementing local process spawning, shell resolution, and process-tree termination.
2155
+ For `user_bash`, extensions can reuse mcpi's local shell backend via `createLocalBashOperations()` instead of reimplementing local process spawning, shell resolution, and process-tree termination.
1852
2156
 
1853
2157
  The bash tool also supports a spawn hook to adjust the command, cwd, or env before execution:
1854
2158
 
1855
2159
  ```typescript
1856
- import { createBashTool } from "@mariozechner/pi-coding-agent";
2160
+ import { createBashTool } from "@sammorrowdrums/mcpi";
1857
2161
 
1858
2162
  const bashTool = createBashTool(cwd, {
1859
2163
  spawnHook: ({ command, cwd, env }) => ({
@@ -1864,7 +2168,19 @@ const bashTool = createBashTool(cwd, {
1864
2168
  });
1865
2169
  ```
1866
2170
 
1867
- See [examples/extensions/ssh.ts](../examples/extensions/ssh.ts) for a complete SSH example with `--ssh` flag.
2171
+ `createBashTool()` exposes the current session to commands through `MCPI_SESSION_ID`, `MCPI_SESSION_FILE`, `MCPI_PROVIDER`, `MCPI_MODEL`, and `MCPI_REASONING_LEVEL`. Injection happens before `spawnHook`, so hooks receive these values in `env` and preserve them when they spread the existing environment as above. Set `exposeSessionEnvironment: false` to disable them:
2172
+
2173
+ ```typescript
2174
+ const bashTool = createBashTool(cwd, {
2175
+ exposeSessionEnvironment: false,
2176
+ });
2177
+ ```
2178
+
2179
+ See [Bash tool session environment](environment-variables.md#bash-tool-session-environment) for variable semantics. See [examples/extensions/ssh.ts](../examples/extensions/ssh.ts) for a complete SSH example with `--ssh` flag.
2180
+
2181
+ When mcpi builds its own bash tool it installs a `spawnHook` that applies variables set with
2182
+ [`pi.setEnv()`](#session-environment) on top of the session metadata. A `spawnHook` you supply to
2183
+ your own `createBashTool()` runs independently of that and is responsible for its own environment.
1868
2184
 
1869
2185
  ### Output Truncation
1870
2186
 
@@ -1883,7 +2199,7 @@ import {
1883
2199
  formatSize, // Human-readable size (e.g., "50KB", "1.5MB")
1884
2200
  DEFAULT_MAX_BYTES, // 50KB
1885
2201
  DEFAULT_MAX_LINES, // 2000
1886
- } from "@mariozechner/pi-coding-agent";
2202
+ } from "@sammorrowdrums/mcpi";
1887
2203
 
1888
2204
  async execute(toolCallId, params, signal, onUpdate, ctx) {
1889
2205
  const output = await runCommand();
@@ -1938,7 +2254,7 @@ export default function (pi: ExtensionAPI) {
1938
2254
 
1939
2255
  ### Custom Rendering
1940
2256
 
1941
- Tools can provide `renderCall` and `renderResult` for custom TUI display. See [tui.md](tui.md) for the full component API and [tool-execution.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/modes/interactive/components/tool-execution.ts) for how tool rows are composed.
2257
+ Tools can provide `renderCall` and `renderResult` for custom TUI display. See [tui.md](tui.md) for the full component API and [tool-execution.ts](https://github.com/SamMorrowDrums/mcpi/blob/main/packages/coding-agent/src/modes/interactive/components/tool-execution.ts) for how tool rows are composed.
1942
2258
 
1943
2259
  By default, tool output is wrapped in a `Box` that handles padding and background. A defined `renderCall` or `renderResult` must return a `Component`. If a slot renderer is not defined, `tool-execution.ts` uses fallback rendering for that slot.
1944
2260
 
@@ -1974,7 +2290,7 @@ Use `context.state` for cross-slot shared state. Keep slot-local caches on the r
1974
2290
  Renders the tool call or header:
1975
2291
 
1976
2292
  ```typescript
1977
- import { Text } from "@mariozechner/pi-tui";
2293
+ import { Text } from "@sammorrowdrums/mcpi-tui";
1978
2294
 
1979
2295
  renderCall(args, theme, context) {
1980
2296
  const text = (context.lastComponent as Text | undefined) ?? new Text("", 0, 0);
@@ -2019,7 +2335,7 @@ If a slot intentionally has no visible content, return an empty `Component` such
2019
2335
  Use `keyHint()` to display keybinding hints that respect the active keybinding configuration:
2020
2336
 
2021
2337
  ```typescript
2022
- import { keyHint } from "@mariozechner/pi-coding-agent";
2338
+ import { keyHint } from "@sammorrowdrums/mcpi";
2023
2339
 
2024
2340
  renderResult(result, { expanded }, theme, context) {
2025
2341
  let text = theme.fg("success", "✓ Done");
@@ -2061,6 +2377,163 @@ If a slot renderer is not defined or throws:
2061
2377
  - `renderCall`: Shows the tool name
2062
2378
  - `renderResult`: Shows raw text from `content`
2063
2379
 
2380
+ ### Dynamic Tool Loading
2381
+
2382
+ Extensions can register many tools while keeping only a small initial set active. A tool can then add more tools with `pi.setActiveTools()` during execution. mcpi detects purely additive changes, records the newly available tool names on that tool result, and applies the updated active set before the next model request.
2383
+
2384
+ This works with every model. Models with native deferred-loading support preserve the stable prompt prefix and load the new definitions at the tool-result position. Other models use the fallback described below.
2385
+
2386
+ The lifecycle is:
2387
+
2388
+ 1. Register every tool with `pi.registerTool()` so it appears in `pi.getAllTools()`.
2389
+ 2. Keep loader tools, such as `search_tools`, active and leave searchable tools inactive.
2390
+ 3. During loader execution, call `pi.setActiveTools([...currentTools, ...matchingTools])`. The change must be additive: do not remove currently active tools in the same call.
2391
+ 4. mcpi records which tools were added on the loader's tool result.
2392
+ 5. Before the next model response, mcpi exposes the added definitions using native deferred loading when supported, or the normal active tool list otherwise.
2393
+
2394
+ You do not need to return provider-specific tool references or mark the loader as a special search tool. The active-tool change is the signal. Names passed to `pi.setActiveTools()` must already be registered; unknown names are ignored.
2395
+
2396
+ #### Models with native deferred loading
2397
+
2398
+ Native deferred loading depends on the **provider** as well as the model. The same Claude model can support native deferred loading when served directly by Anthropic and fall back to the normal tool list when served through another provider.
2399
+
2400
+ - **Anthropic (first-party `anthropic` provider only)**
2401
+ - **Models:** Sonnet, Opus, Fable version 4.5 or newer, including Claude Opus 5. Haiku is excluded.
2402
+ - **Native representation:** Deferred definitions use `defer_loading`; the load point uses `tool_reference` content.
2403
+ - **Provider gate:** Auto-detection requires `provider === "anthropic"`. Claude models served by GitHub Copilot, Amazon Bedrock, Google Vertex, or an OpenAI-compatible proxy do not auto-enable, even when they use the `anthropic-messages` API.
2404
+ - **OpenAI**
2405
+ - **Models:** `gpt-5.4` and newer family
2406
+ - **Native representation:** Models with `supportsAdditionalTools` anchor the new definitions to the transcript with a developer-role `additional_tools` message. Models with only `supportsToolSearch` instead get completed client `tool_search_call` and `tool_search_output` items at the load point.
2407
+ - **Provider gate:** Auto-detection applies to the `openai` and `openai-codex` providers. Other hosts of the same models use the fallback.
2408
+
2409
+ For a verified custom model or proxy, native handling can be enabled with `compat.supportsToolReferences: true` for `anthropic-messages`, or `compat.supportsToolSearch: true` for `openai-responses` and `openai-codex-responses`. Leave these disabled unless the endpoint and model accept the corresponding native protocol.
2410
+
2411
+ #### Claude Opus 5 compatibility matrix
2412
+
2413
+ Claude Opus 5 is the default model for the `anthropic`, `github-copilot`, and `amazon-bedrock` providers. Its deferred-loading behavior differs per provider:
2414
+
2415
+ | Provider | Model id | API | Deferred loading | Verified by |
2416
+ | --- | --- | --- | --- | --- |
2417
+ | `anthropic` | `claude-opus-5` | `anthropic-messages` | Native `defer_loading` + `tool_reference` | Offline contract test |
2418
+ | `github-copilot` | `claude-opus-5` | `anthropic-messages` | Safe fallback: full active tool list, no `defer_loading` | Offline contract test |
2419
+ | `amazon-bedrock` | `us.anthropic.claude-opus-5` | `bedrock-converse-stream` | Safe fallback; the Converse API has no tool-reference protocol | Offline contract test |
2420
+
2421
+ **Scope of this matrix.** Deferred loading is the only capability that varies here, so "safe fallback" is not a general capability rating. `us.anthropic.claude-opus-5` keeps adaptive thinking, native `xhigh` effort, and prompt caching; `bedrock-converse-stream` derives those from model-id predicates rather than from `compat.forceAdaptiveThinking`. Only tool deferral is unavailable, because the Converse API has no tool-reference protocol.
2422
+
2423
+ Switching between these providers mid-session is supported. A tool marked as added under one provider is loaded correctly after switching to another, including across API families such as an `openai-responses` transcript continued on `anthropic/claude-opus-5`.
2424
+
2425
+ **Offline contract tests.** The behaviors above are asserted by offline contract tests that capture the outgoing request payload and abort before any network call, so they need no credentials and make no billable requests. See `packages/ai/test/deferred-tools.test.ts` and `packages/ai/test/claude-opus-5-provider-matrix.test.ts`.
2426
+
2427
+ #### Fallback behavior
2428
+
2429
+ For all other models and providers, dynamic activation still works: mcpi sends the complete current active tool list normally on the next request. The model can call the newly activated tools, but adding their definitions may invalidate the provider's cached prompt prefix.
2430
+
2431
+ mcpi also uses this safe fallback when the active set is not purely additive, such as replacing one group of tools with another. Tool removals therefore work, but they do not use deferred loading.
2432
+
2433
+ For the best cache behavior, keep the loader tool active for the whole session and add tools instead of replacing the active set. Also note that activating a tool with `promptSnippet` or `promptGuidelines` rebuilds the system prompt; that system-prompt change can invalidate the prefix even when the provider supports deferred schemas. Lazily loaded tools should usually rely on their tool `description` and omit active-only prompt metadata.
2434
+
2435
+ #### Search tool example
2436
+
2437
+ The following extension registers two searchable tools, removes them from the initial active set, and keeps only `search_tools` as their loader. The example uses simple keyword matching, but the search implementation could use BM25, embeddings, a remote catalog, or project-specific routing.
2438
+
2439
+ ```typescript
2440
+ import type { ExtensionAPI } from "@sammorrowdrums/mcpi";
2441
+ import { Type } from "typebox";
2442
+
2443
+ const SEARCHABLE_TOOL_NAMES = new Set(["lookup_weather", "search_issues"]);
2444
+
2445
+ export default function (pi: ExtensionAPI) {
2446
+ pi.registerTool({
2447
+ name: "lookup_weather",
2448
+ label: "Lookup Weather",
2449
+ description: "Look up the current weather for a city",
2450
+ parameters: Type.Object({ city: Type.String() }),
2451
+ async execute(_toolCallId, params) {
2452
+ return {
2453
+ content: [{ type: "text", text: `Weather for ${params.city}: sunny` }],
2454
+ details: {},
2455
+ };
2456
+ },
2457
+ });
2458
+
2459
+ pi.registerTool({
2460
+ name: "search_issues",
2461
+ label: "Search Issues",
2462
+ description: "Search project issues by keyword",
2463
+ parameters: Type.Object({ query: Type.String() }),
2464
+ async execute(_toolCallId, params) {
2465
+ return {
2466
+ content: [{ type: "text", text: `No open issues matching ${params.query}` }],
2467
+ details: {},
2468
+ };
2469
+ },
2470
+ });
2471
+
2472
+ pi.registerTool({
2473
+ name: "search_tools",
2474
+ label: "Search Tools",
2475
+ description: "Search for and enable tools relevant to a task",
2476
+ promptSnippet: "Search for additional tools when the active tools cannot perform the task",
2477
+ promptGuidelines: [
2478
+ "Use search_tools when a task requires a capability that is not currently available.",
2479
+ ],
2480
+ parameters: Type.Object({
2481
+ query: Type.String({ description: "Capability or task to search for" }),
2482
+ limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 10 })),
2483
+ }),
2484
+ async execute(_toolCallId, params) {
2485
+ const terms = params.query.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
2486
+ const matches = pi.getAllTools()
2487
+ .filter((tool) => SEARCHABLE_TOOL_NAMES.has(tool.name))
2488
+ .map((tool) => ({
2489
+ tool,
2490
+ score: terms.reduce(
2491
+ (score, term) =>
2492
+ score + (`${tool.name} ${tool.description}`.toLowerCase().includes(term) ? 1 : 0),
2493
+ 0,
2494
+ ),
2495
+ }))
2496
+ .filter((match) => match.score > 0)
2497
+ .sort((a, b) => b.score - a.score)
2498
+ .slice(0, params.limit ?? 3)
2499
+ .map((match) => match.tool.name);
2500
+
2501
+ if (matches.length === 0) {
2502
+ return {
2503
+ content: [{ type: "text", text: `No tools found for: ${params.query}` }],
2504
+ details: { matches: [] },
2505
+ };
2506
+ }
2507
+
2508
+ const active = pi.getActiveTools();
2509
+ const added = matches.filter((name) => !active.includes(name));
2510
+ pi.setActiveTools([...new Set([...active, ...added])]);
2511
+
2512
+ return {
2513
+ content: [{
2514
+ type: "text",
2515
+ text: added.length > 0
2516
+ ? `Loaded tools: ${added.join(", ")}`
2517
+ : `Matching tools already active: ${matches.join(", ")}`,
2518
+ }],
2519
+ details: { matches, added },
2520
+ };
2521
+ },
2522
+ });
2523
+
2524
+ pi.on("session_start", () => {
2525
+ // Keep searchable tools registered but initially inactive. Preserve built-ins
2526
+ // and tools owned by other extensions, and keep the loader itself active.
2527
+ const initialTools = pi.getActiveTools().filter(
2528
+ (name) => !SEARCHABLE_TOOL_NAMES.has(name),
2529
+ );
2530
+ pi.setActiveTools([...new Set([...initialTools, "search_tools"])]);
2531
+ });
2532
+ }
2533
+ ```
2534
+
2535
+ When `search_tools` adds a match, the model receives that definition on the immediately following request. On a native-capable model the definition is anchored after the search result without changing the initial tool-schema prefix. On other models it appears in the normal tool list on that same following request.
2536
+
2064
2537
  ## Custom UI
2065
2538
 
2066
2539
  Extensions can interact with users via `ctx.ui` methods and customize how messages/tools render.
@@ -2070,7 +2543,7 @@ Extensions can interact with users via `ctx.ui` methods and customize how messag
2070
2543
  - Async operations with cancel (BorderedLoader)
2071
2544
  - Settings toggles (SettingsList)
2072
2545
  - Status indicators (setStatus)
2073
- - Working message and indicator during streaming (`setWorkingMessage`, `setWorkingIndicator`)
2546
+ - Working message, visibility, and indicator during streaming (`setWorkingMessage`, `setWorkingVisible`, `setWorkingIndicator`)
2074
2547
  - Widgets above/below editor (setWidget)
2075
2548
  - Autocomplete providers layered on top of built-in slash/path completion (addAutocompleteProvider)
2076
2549
  - Custom footers (setFooter)
@@ -2152,9 +2625,11 @@ See [examples/extensions/timed-confirm.ts](../examples/extensions/timed-confirm.
2152
2625
  ctx.ui.setStatus("my-ext", "Processing...");
2153
2626
  ctx.ui.setStatus("my-ext", undefined); // Clear
2154
2627
 
2155
- // Working message (shown during streaming)
2628
+ // Working loader (shown during streaming)
2156
2629
  ctx.ui.setWorkingMessage("Thinking deeply...");
2157
2630
  ctx.ui.setWorkingMessage(); // Restore default
2631
+ ctx.ui.setWorkingVisible(false); // Hide the built-in working loader row entirely
2632
+ ctx.ui.setWorkingVisible(true); // Show the built-in working loader row
2158
2633
 
2159
2634
  // Working indicator (shown during streaming)
2160
2635
  ctx.ui.setWorkingIndicator({ frames: [ctx.ui.theme.fg("accent", "●")] }); // Static dot
@@ -2185,7 +2660,7 @@ ctx.ui.setFooter((tui, theme) => ({
2185
2660
  ctx.ui.setFooter(undefined); // Restore built-in footer
2186
2661
 
2187
2662
  // Terminal title
2188
- ctx.ui.setTitle("pi - my-project");
2663
+ ctx.ui.setTitle("mcpi - my-project");
2189
2664
 
2190
2665
  // Editor text
2191
2666
  ctx.ui.setEditorText("Prefill text");
@@ -2196,6 +2671,7 @@ ctx.ui.pasteToEditor("pasted content");
2196
2671
 
2197
2672
  // Stack custom autocomplete behavior on top of the built-in provider
2198
2673
  ctx.ui.addAutocompleteProvider((current) => ({
2674
+ triggerCharacters: ["#"],
2199
2675
  async getSuggestions(lines, line, col, options) {
2200
2676
  const beforeCursor = (lines[line] ?? "").slice(0, col);
2201
2677
  const match = beforeCursor.match(/(?:^|[ \t])#([^\s#]*)$/);
@@ -2223,6 +2699,10 @@ ctx.ui.setToolsExpanded(wasExpanded);
2223
2699
 
2224
2700
  // Custom editor (vim mode, emacs mode, etc.)
2225
2701
  ctx.ui.setEditorComponent((tui, theme, keybindings) => new VimEditor(tui, theme, keybindings));
2702
+ const currentEditor = ctx.ui.getEditorComponent();
2703
+ ctx.ui.setEditorComponent((tui, theme, keybindings) =>
2704
+ new WrappedEditor(tui, theme, keybindings, currentEditor?.(tui, theme, keybindings))
2705
+ );
2226
2706
  ctx.ui.setEditorComponent(undefined); // Restore default editor
2227
2707
 
2228
2708
  // Theme management (see themes.md for creating themes)
@@ -2240,7 +2720,7 @@ Custom working-indicator frames are rendered verbatim. If you want colors, add t
2240
2720
 
2241
2721
  ### Autocomplete Providers
2242
2722
 
2243
- Use `ctx.ui.addAutocompleteProvider()` to stack custom autocomplete logic on top of the built-in slash-command and path provider.
2723
+ Use `ctx.ui.addAutocompleteProvider()` to stack custom autocomplete logic on top of the built-in slash-command and path provider. Set `triggerCharacters` for custom natural triggers such as `$`.
2244
2724
 
2245
2725
  Typical pattern:
2246
2726
 
@@ -2252,6 +2732,7 @@ Typical pattern:
2252
2732
  ```typescript
2253
2733
  pi.on("session_start", (_event, ctx) => {
2254
2734
  ctx.ui.addAutocompleteProvider((current) => ({
2735
+ triggerCharacters: ["#"],
2255
2736
  async getSuggestions(lines, cursorLine, cursorCol, options) {
2256
2737
  const line = lines[cursorLine] ?? "";
2257
2738
  const beforeCursor = line.slice(0, cursorCol);
@@ -2287,7 +2768,7 @@ See [github-issue-autocomplete.ts](../examples/extensions/github-issue-autocompl
2287
2768
  For complex UI, use `ctx.ui.custom()`. This temporarily replaces the editor with your component until `done()` is called:
2288
2769
 
2289
2770
  ```typescript
2290
- import { Text, Component } from "@mariozechner/pi-tui";
2771
+ import { Text, Component } from "@sammorrowdrums/mcpi-tui";
2291
2772
 
2292
2773
  const result = await ctx.ui.custom<boolean>((tui, theme, keybindings, done) => {
2293
2774
  const text = new Text("Press Enter to confirm, Escape to cancel", 1, 1);
@@ -2325,7 +2806,7 @@ const result = await ctx.ui.custom<string | null>(
2325
2806
  );
2326
2807
  ```
2327
2808
 
2328
- For advanced positioning (anchors, margins, percentages, responsive visibility), pass `overlayOptions`. Use `onHandle` to control visibility programmatically:
2809
+ For advanced positioning (anchors, margins, percentages, responsive visibility), pass `overlayOptions`. Use `onHandle` to control focus or visibility programmatically:
2329
2810
 
2330
2811
  ```typescript
2331
2812
  const result = await ctx.ui.custom<string | null>(
@@ -2333,20 +2814,27 @@ const result = await ctx.ui.custom<string | null>(
2333
2814
  {
2334
2815
  overlay: true,
2335
2816
  overlayOptions: { anchor: "top-right", width: "50%", margin: 2 },
2336
- onHandle: (handle) => { /* handle.setHidden(true/false) */ }
2817
+ onHandle: (handle) => {
2818
+ handle.focus(); // focus this overlay and bring it to the visual front
2819
+ // handle.unfocus({ target: editorComponent }); // release input to a specific component
2820
+ // handle.setHidden(true/false); // toggle visibility
2821
+ // handle.hide(); // permanently remove
2822
+ }
2337
2823
  }
2338
2824
  );
2339
2825
  ```
2340
2826
 
2341
- See [tui.md](tui.md) for the full `OverlayOptions` API and [overlay-qa-tests.ts](../examples/extensions/overlay-qa-tests.ts) for examples.
2827
+ A focused visible overlay can reclaim input after temporary non-overlay custom UI closes. If you intentionally want another component to keep input while the overlay stays visible, call `handle.unfocus({ target })`. Passing `{ target: null }` releases the overlay without focusing another component.
2828
+
2829
+ See [tui.md](tui.md) for the full `OverlayOptions` and `OverlayHandle` API and [overlay-qa-tests.ts](../examples/extensions/overlay-qa-tests.ts) for examples.
2342
2830
 
2343
2831
  ### Custom Editor
2344
2832
 
2345
2833
  Replace the main input editor with a custom implementation (vim mode, emacs mode, etc.):
2346
2834
 
2347
2835
  ```typescript
2348
- import { CustomEditor, type ExtensionAPI } from "@mariozechner/pi-coding-agent";
2349
- import { matchesKey } from "@mariozechner/pi-tui";
2836
+ import { CustomEditor, type ExtensionAPI } from "@sammorrowdrums/mcpi";
2837
+ import { matchesKey } from "@sammorrowdrums/mcpi-tui";
2350
2838
 
2351
2839
  class VimEditor extends CustomEditor {
2352
2840
  private mode: "normal" | "insert" = "insert";
@@ -2366,8 +2854,8 @@ class VimEditor extends CustomEditor {
2366
2854
 
2367
2855
  export default function (pi: ExtensionAPI) {
2368
2856
  pi.on("session_start", (_event, ctx) => {
2369
- ctx.ui.setEditorComponent((_tui, theme, keybindings) =>
2370
- new VimEditor(theme, keybindings)
2857
+ ctx.ui.setEditorComponent((tui, theme, keybindings) =>
2858
+ new VimEditor(tui, theme, keybindings)
2371
2859
  );
2372
2860
  });
2373
2861
  }
@@ -2376,20 +2864,30 @@ export default function (pi: ExtensionAPI) {
2376
2864
  **Key points:**
2377
2865
  - Extend `CustomEditor` (not base `Editor`) to get app keybindings (escape to abort, ctrl+d, model switching)
2378
2866
  - Call `super.handleInput(data)` for keys you don't handle
2379
- - Factory receives `theme` and `keybindings` from the app
2867
+ - Factory receives `tui`, `theme`, and `keybindings` from the app
2868
+ - Use `ctx.ui.getEditorComponent()` before `setEditorComponent()` to wrap the previously configured custom editor
2380
2869
  - Pass `undefined` to restore default: `ctx.ui.setEditorComponent(undefined)`
2381
2870
 
2871
+ To compose with another extension that already replaced the editor, capture the previous factory before setting yours:
2872
+
2873
+ ```typescript
2874
+ const previous = ctx.ui.getEditorComponent();
2875
+ ctx.ui.setEditorComponent((tui, theme, keybindings) =>
2876
+ new MyEditor(tui, theme, keybindings, { base: previous?.(tui, theme, keybindings) })
2877
+ );
2878
+ ```
2879
+
2382
2880
  See [tui.md](tui.md) Pattern 7 for a complete example with mode indicator.
2383
2881
 
2384
- ### Message Rendering
2882
+ ### Message and Entry Rendering
2385
2883
 
2386
- Register a custom renderer for messages with your `customType`:
2884
+ Register a custom renderer for messages with your `customType`. Use message renderers for content that should participate in LLM context:
2387
2885
 
2388
2886
  ```typescript
2389
- import { Text } from "@mariozechner/pi-tui";
2887
+ import { Text } from "@sammorrowdrums/mcpi-tui";
2390
2888
 
2391
2889
  pi.registerMessageRenderer("my-extension", (message, options, theme) => {
2392
- const { expanded } = options;
2890
+ const { expanded, outputPad } = options;
2393
2891
  let text = theme.fg("accent", `[${message.customType}] `);
2394
2892
  text += message.content;
2395
2893
 
@@ -2397,7 +2895,7 @@ pi.registerMessageRenderer("my-extension", (message, options, theme) => {
2397
2895
  text += "\n" + theme.fg("dim", JSON.stringify(message.details, null, 2));
2398
2896
  }
2399
2897
 
2400
- return new Text(text, 0, 0);
2898
+ return new Text(text, outputPad, 0);
2401
2899
  });
2402
2900
  ```
2403
2901
 
@@ -2412,6 +2910,16 @@ pi.sendMessage({
2412
2910
  });
2413
2911
  ```
2414
2912
 
2913
+ For TUI-only content that should not be sent to the LLM, render custom entries instead:
2914
+
2915
+ ```typescript
2916
+ pi.registerEntryRenderer("my-card", (entry, options, theme) => {
2917
+ return new Text(theme.fg("accent", JSON.stringify(entry.data)));
2918
+ });
2919
+
2920
+ pi.appendEntry("my-card", { status: "done" });
2921
+ ```
2922
+
2415
2923
  ### Theme Colors
2416
2924
 
2417
2925
  All render functions receive a `theme` object. See [themes.md](themes.md) for creating custom themes and the full color palette.
@@ -2435,7 +2943,7 @@ theme.strikethrough(text)
2435
2943
  For syntax highlighting in custom tool renderers:
2436
2944
 
2437
2945
  ```typescript
2438
- import { highlightCode, getLanguageFromPath } from "@mariozechner/pi-coding-agent";
2946
+ import { highlightCode, getLanguageFromPath } from "@sammorrowdrums/mcpi";
2439
2947
 
2440
2948
  // Highlight code with explicit language
2441
2949
  const highlighted = highlightCode("const x = 1;", "typescript", theme);
@@ -2453,14 +2961,14 @@ const highlighted = highlightCode(code, lang, theme);
2453
2961
 
2454
2962
  ## Mode Behavior
2455
2963
 
2456
- | Mode | UI Methods | Notes |
2457
- |------|-----------|-------|
2458
- | Interactive | Full TUI | Normal operation |
2459
- | RPC (`--mode rpc`) | JSON protocol | Host handles UI, see [rpc.md](rpc.md) |
2460
- | JSON (`--mode json`) | No-op | Event stream to stdout, see [json.md](json.md) |
2461
- | Print (`-p`) | No-op | Extensions run but can't prompt |
2964
+ | Mode | `ctx.mode` | `ctx.hasUI` | Notes |
2965
+ |------|------------|-------------|-------|
2966
+ | Interactive | `"tui"` | `true` | Full TUI with terminal rendering |
2967
+ | RPC (`--mode rpc`) | `"rpc"` | `true` | Dialogs and notifications via JSON protocol; `custom()` returns `undefined`. See [rpc.md](rpc.md) |
2968
+ | JSON (`--mode json`) | `"json"` | `false` | Event stream to stdout; UI methods are no-ops |
2969
+ | Print (`-p`) | `"print"` | `false` | Extensions run but can't prompt |
2462
2970
 
2463
- In non-interactive modes, check `ctx.hasUI` before using UI methods.
2971
+ Use `ctx.mode === "tui"` before TUI-specific features (`custom()`, component factories, terminal input). Use `ctx.hasUI` before dialog and notification methods that work in both TUI and RPC modes.
2464
2972
 
2465
2973
  ## Examples Reference
2466
2974
 
@@ -2487,10 +2995,12 @@ All examples in [examples/extensions/](../examples/extensions/).
2487
2995
  | `shutdown-command.ts` | Graceful shutdown command | `registerCommand`, `shutdown()` |
2488
2996
  | **Events & Gates** |||
2489
2997
  | `permission-gate.ts` | Block dangerous commands | `on("tool_call")`, `ui.confirm` |
2998
+ | `project-trust.ts` | Decide or defer project trust from a user/global or CLI extension | `on("project_trust")`, trust UI, required trust result |
2490
2999
  | `protected-paths.ts` | Block writes to specific paths | `on("tool_call")` |
2491
3000
  | `confirm-destructive.ts` | Confirm session changes | `on("session_before_switch")`, `on("session_before_fork")` |
2492
3001
  | `dirty-repo-guard.ts` | Warn on dirty git repo | `on("session_before_*")`, `exec` |
2493
3002
  | `input-transform.ts` | Transform user input | `on("input")` |
3003
+ | `input-transform-streaming.ts` | Streaming-aware input transform | `on("input")`, `streamingBehavior` |
2494
3004
  | `model-status.ts` | React to model changes | `on("model_select")`, `setStatus` |
2495
3005
  | `provider-payload.ts` | Inspect payloads and provider response headers | `on("before_provider_request")`, `on("after_provider_response")` |
2496
3006
  | `system-prompt-header.ts` | Display system prompt info | `on("agent_start")`, `getSystemPrompt` |
@@ -2501,6 +3011,7 @@ All examples in [examples/extensions/](../examples/extensions/).
2501
3011
  | `custom-compaction.ts` | Custom compaction summary | `on("session_before_compact")` |
2502
3012
  | `trigger-compact.ts` | Trigger compaction manually | `compact()` |
2503
3013
  | `git-checkpoint.ts` | Git stash on turns | `on("turn_start")`, `on("session_before_fork")`, `exec` |
3014
+ | `git-merge-and-resolve.ts` | Fetch, merge, and resolve conflicts | `on("agent_end")`, `exec`, `sendUserMessage` |
2504
3015
  | `auto-commit-on-exit.ts` | Commit on shutdown | `on("session_shutdown")`, `exec` |
2505
3016
  | **UI Components** |||
2506
3017
  | `status-line.ts` | Footer status indicator | `setStatus`, session events |
@@ -2524,6 +3035,7 @@ All examples in [examples/extensions/](../examples/extensions/).
2524
3035
  | `ssh.ts` | SSH remote execution | `registerFlag`, `on("user_bash")`, `on("before_agent_start")`, tool operations |
2525
3036
  | `interactive-shell.ts` | Persistent shell session | `on("user_bash")` |
2526
3037
  | `sandbox/` | Sandboxed tool execution | Tool operations |
3038
+ | `gondolin/` | Route built-in tools and `!` commands into a Gondolin micro-VM | Tool operations, built-in tool overrides, `on("user_bash")` |
2527
3039
  | `subagent/` | Spawn sub-agents | `registerTool`, `exec` |
2528
3040
  | **Games** |||
2529
3041
  | `snake.ts` | Snake game | `registerCommand`, `ui.custom`, keyboard handling |
@@ -2534,12 +3046,12 @@ All examples in [examples/extensions/](../examples/extensions/).
2534
3046
  | `custom-provider-gitlab-duo/` | GitLab Duo integration | `registerProvider` with OAuth |
2535
3047
  | **Messages & Communication** |||
2536
3048
  | `message-renderer.ts` | Custom message rendering | `registerMessageRenderer`, `sendMessage` |
3049
+ | `entry-renderer.ts` | TUI-only custom entry rendering | `registerEntryRenderer`, `appendEntry` |
2537
3050
  | `event-bus.ts` | Inter-extension events | `pi.events` |
2538
3051
  | **Session Metadata** |||
2539
3052
  | `session-name.ts` | Name sessions for selector | `setSessionName`, `getSessionName` |
2540
3053
  | `bookmark.ts` | Bookmark entries for /tree | `setLabel` |
2541
3054
  | **Misc** |||
2542
- | `antigravity-image-gen.ts` | Image generation tool | `registerTool`, Google Antigravity |
2543
3055
  | `inline-bash.ts` | Inline bash in tool calls | `on("tool_call")` |
2544
3056
  | `bash-spawn-hook.ts` | Adjust bash command, cwd, and env before execution | `createBashTool`, `spawnHook` |
2545
3057
  | `with-deps/` | Extension with npm dependencies | Package structure with `package.json` |