@phi-code-admin/phi-code 0.74.2 → 0.75.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 (656) hide show
  1. package/CHANGELOG.md +1186 -4
  2. package/README.md +478 -379
  3. package/dist/bun/cli.d.ts +3 -0
  4. package/dist/bun/cli.d.ts.map +1 -0
  5. package/dist/bun/cli.js +9 -0
  6. package/dist/bun/cli.js.map +1 -0
  7. package/dist/bun/register-bedrock.d.ts +2 -0
  8. package/dist/bun/register-bedrock.d.ts.map +1 -0
  9. package/dist/bun/register-bedrock.js +4 -0
  10. package/dist/bun/register-bedrock.js.map +1 -0
  11. package/dist/bun/restore-sandbox-env.d.ts +13 -0
  12. package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
  13. package/dist/bun/restore-sandbox-env.js +32 -0
  14. package/dist/bun/restore-sandbox-env.js.map +1 -0
  15. package/dist/cli/args.d.ts +12 -7
  16. package/dist/cli/args.d.ts.map +1 -1
  17. package/dist/cli/args.js +87 -45
  18. package/dist/cli/args.js.map +1 -1
  19. package/dist/cli/config-selector.d.ts.map +1 -1
  20. package/dist/cli/config-selector.js.map +1 -1
  21. package/dist/cli/file-processor.d.ts.map +1 -1
  22. package/dist/cli/file-processor.js +4 -0
  23. package/dist/cli/file-processor.js.map +1 -1
  24. package/dist/cli/initial-message.d.ts +18 -0
  25. package/dist/cli/initial-message.d.ts.map +1 -0
  26. package/dist/cli/initial-message.js +22 -0
  27. package/dist/cli/initial-message.js.map +1 -0
  28. package/dist/cli/list-models.d.ts.map +1 -1
  29. package/dist/cli/list-models.js +7 -1
  30. package/dist/cli/list-models.js.map +1 -1
  31. package/dist/cli/session-picker.d.ts.map +1 -1
  32. package/dist/cli/session-picker.js +2 -1
  33. package/dist/cli/session-picker.js.map +1 -1
  34. package/dist/cli.d.ts.map +1 -1
  35. package/dist/cli.js +9 -5
  36. package/dist/cli.js.map +1 -1
  37. package/dist/config.d.ts +24 -0
  38. package/dist/config.d.ts.map +1 -1
  39. package/dist/config.js +226 -30
  40. package/dist/config.js.map +1 -1
  41. package/dist/core/agent-session-runtime.d.ts +117 -0
  42. package/dist/core/agent-session-runtime.d.ts.map +1 -0
  43. package/dist/core/agent-session-runtime.js +300 -0
  44. package/dist/core/agent-session-runtime.js.map +1 -0
  45. package/dist/core/agent-session-services.d.ts +86 -0
  46. package/dist/core/agent-session-services.d.ts.map +1 -0
  47. package/dist/core/agent-session-services.js +117 -0
  48. package/dist/core/agent-session-services.js.map +1 -0
  49. package/dist/core/agent-session.d.ts +63 -82
  50. package/dist/core/agent-session.d.ts.map +1 -1
  51. package/dist/core/agent-session.js +674 -628
  52. package/dist/core/agent-session.js.map +1 -1
  53. package/dist/core/api-key-store.d.ts +87 -0
  54. package/dist/core/api-key-store.d.ts.map +1 -0
  55. package/dist/core/api-key-store.js +168 -0
  56. package/dist/core/api-key-store.js.map +1 -0
  57. package/dist/core/auth-guidance.d.ts +5 -0
  58. package/dist/core/auth-guidance.d.ts.map +1 -0
  59. package/dist/core/auth-guidance.js +21 -0
  60. package/dist/core/auth-guidance.js.map +1 -0
  61. package/dist/core/auth-storage.d.ts +12 -5
  62. package/dist/core/auth-storage.d.ts.map +1 -1
  63. package/dist/core/auth-storage.js +34 -8
  64. package/dist/core/auth-storage.js.map +1 -1
  65. package/dist/core/bash-executor.d.ts +0 -15
  66. package/dist/core/bash-executor.d.ts.map +1 -1
  67. package/dist/core/bash-executor.js +28 -129
  68. package/dist/core/bash-executor.js.map +1 -1
  69. package/dist/core/compaction/branch-summarization.d.ts +2 -0
  70. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  71. package/dist/core/compaction/branch-summarization.js +3 -2
  72. package/dist/core/compaction/branch-summarization.js.map +1 -1
  73. package/dist/core/compaction/compaction.d.ts +4 -4
  74. package/dist/core/compaction/compaction.d.ts.map +1 -1
  75. package/dist/core/compaction/compaction.js +32 -27
  76. package/dist/core/compaction/compaction.js.map +1 -1
  77. package/dist/core/compaction/index.d.ts.map +1 -1
  78. package/dist/core/compaction/utils.d.ts.map +1 -1
  79. package/dist/core/compaction/utils.js.map +1 -1
  80. package/dist/core/config-watcher.d.ts +47 -0
  81. package/dist/core/config-watcher.d.ts.map +1 -0
  82. package/dist/core/config-watcher.js +135 -0
  83. package/dist/core/config-watcher.js.map +1 -0
  84. package/dist/core/default-models.json +80 -0
  85. package/dist/core/defaults.d.ts.map +1 -1
  86. package/dist/core/diagnostics.d.ts.map +1 -1
  87. package/dist/core/event-bus.d.ts.map +1 -1
  88. package/dist/core/event-bus.js.map +1 -1
  89. package/dist/core/exec.d.ts.map +1 -1
  90. package/dist/core/exec.js +7 -3
  91. package/dist/core/exec.js.map +1 -1
  92. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  93. package/dist/core/export-html/ansi-to-html.js +1 -1
  94. package/dist/core/export-html/ansi-to-html.js.map +1 -1
  95. package/dist/core/export-html/index.d.ts +7 -4
  96. package/dist/core/export-html/index.d.ts.map +1 -1
  97. package/dist/core/export-html/index.js +15 -13
  98. package/dist/core/export-html/index.js.map +1 -1
  99. package/dist/core/export-html/template.css +112 -17
  100. package/dist/core/export-html/template.html +1 -0
  101. package/dist/core/export-html/template.js +312 -64
  102. package/dist/core/export-html/tool-renderer.d.ts +9 -10
  103. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  104. package/dist/core/export-html/tool-renderer.js +61 -16
  105. package/dist/core/export-html/tool-renderer.js.map +1 -1
  106. package/dist/core/extensions/index.d.ts +5 -4
  107. package/dist/core/extensions/index.d.ts.map +1 -1
  108. package/dist/core/extensions/index.js +2 -2
  109. package/dist/core/extensions/index.js.map +1 -1
  110. package/dist/core/extensions/loader.d.ts +0 -1
  111. package/dist/core/extensions/loader.d.ts.map +1 -1
  112. package/dist/core/extensions/loader.js +98 -18
  113. package/dist/core/extensions/loader.js.map +1 -1
  114. package/dist/core/extensions/runner.d.ts +27 -14
  115. package/dist/core/extensions/runner.d.ts.map +1 -1
  116. package/dist/core/extensions/runner.js +299 -115
  117. package/dist/core/extensions/runner.js.map +1 -1
  118. package/dist/core/extensions/types.d.ts +200 -44
  119. package/dist/core/extensions/types.d.ts.map +1 -1
  120. package/dist/core/extensions/types.js +10 -0
  121. package/dist/core/extensions/types.js.map +1 -1
  122. package/dist/core/extensions/wrapper.d.ts +4 -11
  123. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  124. package/dist/core/extensions/wrapper.js +7 -87
  125. package/dist/core/extensions/wrapper.js.map +1 -1
  126. package/dist/core/footer-data-provider.d.ts +22 -2
  127. package/dist/core/footer-data-provider.d.ts.map +1 -1
  128. package/dist/core/footer-data-provider.js +225 -49
  129. package/dist/core/footer-data-provider.js.map +1 -1
  130. package/dist/core/index.d.ts +5 -2
  131. package/dist/core/index.d.ts.map +1 -1
  132. package/dist/core/index.js +5 -2
  133. package/dist/core/index.js.map +1 -1
  134. package/dist/core/keybindings.d.ts +348 -50
  135. package/dist/core/keybindings.d.ts.map +1 -1
  136. package/dist/core/keybindings.js +276 -132
  137. package/dist/core/keybindings.js.map +1 -1
  138. package/dist/core/messages.d.ts.map +1 -1
  139. package/dist/core/messages.js.map +1 -1
  140. package/dist/core/model-registry.d.ts +41 -5
  141. package/dist/core/model-registry.d.ts.map +1 -1
  142. package/dist/core/model-registry.js +316 -136
  143. package/dist/core/model-registry.js.map +1 -1
  144. package/dist/core/model-resolver.d.ts +6 -0
  145. package/dist/core/model-resolver.d.ts.map +1 -1
  146. package/dist/core/model-resolver.js +70 -37
  147. package/dist/core/model-resolver.js.map +1 -1
  148. package/dist/core/output-guard.d.ts +6 -0
  149. package/dist/core/output-guard.d.ts.map +1 -0
  150. package/dist/core/output-guard.js +59 -0
  151. package/dist/core/output-guard.js.map +1 -0
  152. package/dist/core/package-manager.d.ts +49 -7
  153. package/dist/core/package-manager.d.ts.map +1 -1
  154. package/dist/core/package-manager.js +655 -122
  155. package/dist/core/package-manager.js.map +1 -1
  156. package/dist/core/prompt-templates.d.ts +12 -10
  157. package/dist/core/prompt-templates.d.ts.map +1 -1
  158. package/dist/core/prompt-templates.js +37 -38
  159. package/dist/core/prompt-templates.js.map +1 -1
  160. package/dist/core/provider-display-names.d.ts +2 -0
  161. package/dist/core/provider-display-names.d.ts.map +1 -0
  162. package/dist/core/provider-display-names.js +33 -0
  163. package/dist/core/provider-display-names.js.map +1 -0
  164. package/dist/core/resolve-config-value.d.ts +6 -0
  165. package/dist/core/resolve-config-value.d.ts.map +1 -1
  166. package/dist/core/resolve-config-value.js +75 -8
  167. package/dist/core/resolve-config-value.js.map +1 -1
  168. package/dist/core/resource-loader.d.ts +18 -8
  169. package/dist/core/resource-loader.d.ts.map +1 -1
  170. package/dist/core/resource-loader.js +217 -123
  171. package/dist/core/resource-loader.js.map +1 -1
  172. package/dist/core/sdk.d.ts +25 -8
  173. package/dist/core/sdk.d.ts.map +1 -1
  174. package/dist/core/sdk.js +84 -37
  175. package/dist/core/sdk.js.map +1 -1
  176. package/dist/core/session-cwd.d.ts +19 -0
  177. package/dist/core/session-cwd.d.ts.map +1 -0
  178. package/dist/core/session-cwd.js +38 -0
  179. package/dist/core/session-cwd.js.map +1 -0
  180. package/dist/core/session-manager.d.ts +11 -1
  181. package/dist/core/session-manager.d.ts.map +1 -1
  182. package/dist/core/session-manager.js +42 -27
  183. package/dist/core/session-manager.js.map +1 -1
  184. package/dist/core/settings-manager.d.ts +34 -5
  185. package/dist/core/settings-manager.d.ts.map +1 -1
  186. package/dist/core/settings-manager.js +113 -13
  187. package/dist/core/settings-manager.js.map +1 -1
  188. package/dist/core/skills.d.ts +13 -11
  189. package/dist/core/skills.d.ts.map +1 -1
  190. package/dist/core/skills.js +59 -19
  191. package/dist/core/skills.js.map +1 -1
  192. package/dist/core/slash-commands.d.ts +2 -3
  193. package/dist/core/slash-commands.d.ts.map +1 -1
  194. package/dist/core/slash-commands.js +9 -6
  195. package/dist/core/slash-commands.js.map +1 -1
  196. package/dist/core/source-info.d.ts +18 -0
  197. package/dist/core/source-info.d.ts.map +1 -0
  198. package/dist/core/source-info.js +19 -0
  199. package/dist/core/source-info.js.map +1 -0
  200. package/dist/core/system-prompt.d.ts +3 -3
  201. package/dist/core/system-prompt.d.ts.map +1 -1
  202. package/dist/core/system-prompt.js +16 -55
  203. package/dist/core/system-prompt.js.map +1 -1
  204. package/dist/core/telemetry.d.ts +3 -0
  205. package/dist/core/telemetry.d.ts.map +1 -0
  206. package/dist/core/telemetry.js +9 -0
  207. package/dist/core/telemetry.js.map +1 -0
  208. package/dist/core/timings.d.ts +1 -0
  209. package/dist/core/timings.d.ts.map +1 -1
  210. package/dist/core/timings.js +6 -0
  211. package/dist/core/timings.js.map +1 -1
  212. package/dist/core/tools/bash.d.ts +27 -14
  213. package/dist/core/tools/bash.d.ts.map +1 -1
  214. package/dist/core/tools/bash.js +301 -208
  215. package/dist/core/tools/bash.js.map +1 -1
  216. package/dist/core/tools/edit-diff.d.ts +23 -1
  217. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  218. package/dist/core/tools/edit-diff.js +154 -59
  219. package/dist/core/tools/edit-diff.js.map +1 -1
  220. package/dist/core/tools/edit.d.ts +22 -12
  221. package/dist/core/tools/edit.d.ts.map +1 -1
  222. package/dist/core/tools/edit.js +243 -65
  223. package/dist/core/tools/edit.js.map +1 -1
  224. package/dist/core/tools/file-mutation-queue.d.ts +6 -0
  225. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
  226. package/dist/core/tools/file-mutation-queue.js +37 -0
  227. package/dist/core/tools/file-mutation-queue.js.map +1 -0
  228. package/dist/core/tools/find.d.ts +10 -14
  229. package/dist/core/tools/find.d.ts.map +1 -1
  230. package/dist/core/tools/find.js +202 -110
  231. package/dist/core/tools/find.js.map +1 -1
  232. package/dist/core/tools/grep.d.ts +14 -22
  233. package/dist/core/tools/grep.d.ts.map +1 -1
  234. package/dist/core/tools/grep.js +100 -35
  235. package/dist/core/tools/grep.js.map +1 -1
  236. package/dist/core/tools/index.d.ts +27 -60
  237. package/dist/core/tools/index.d.ts.map +1 -1
  238. package/dist/core/tools/index.js +96 -45
  239. package/dist/core/tools/index.js.map +1 -1
  240. package/dist/core/tools/ls.d.ts +8 -11
  241. package/dist/core/tools/ls.d.ts.map +1 -1
  242. package/dist/core/tools/ls.js +66 -15
  243. package/dist/core/tools/ls.js.map +1 -1
  244. package/dist/core/tools/output-accumulator.d.ts +50 -0
  245. package/dist/core/tools/output-accumulator.d.ts.map +1 -0
  246. package/dist/core/tools/output-accumulator.js +178 -0
  247. package/dist/core/tools/output-accumulator.js.map +1 -0
  248. package/dist/core/tools/path-utils.d.ts.map +1 -1
  249. package/dist/core/tools/path-utils.js +1 -1
  250. package/dist/core/tools/path-utils.js.map +1 -1
  251. package/dist/core/tools/read.d.ts +9 -13
  252. package/dist/core/tools/read.d.ts.map +1 -1
  253. package/dist/core/tools/read.js +175 -52
  254. package/dist/core/tools/read.js.map +1 -1
  255. package/dist/core/tools/render-utils.d.ts +21 -0
  256. package/dist/core/tools/render-utils.d.ts.map +1 -0
  257. package/dist/core/tools/render-utils.js +49 -0
  258. package/dist/core/tools/render-utils.js.map +1 -0
  259. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  260. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
  261. package/dist/core/tools/tool-definition-wrapper.js +34 -0
  262. package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
  263. package/dist/core/tools/truncate.d.ts.map +1 -1
  264. package/dist/core/tools/truncate.js.map +1 -1
  265. package/dist/core/tools/write.d.ts +8 -11
  266. package/dist/core/tools/write.d.ts.map +1 -1
  267. package/dist/core/tools/write.js +167 -32
  268. package/dist/core/tools/write.js.map +1 -1
  269. package/dist/index.d.ts +12 -9
  270. package/dist/index.d.ts.map +1 -1
  271. package/dist/index.js +12 -10
  272. package/dist/index.js.map +1 -1
  273. package/dist/main.d.ts +5 -1
  274. package/dist/main.d.ts.map +1 -1
  275. package/dist/main.js +326 -404
  276. package/dist/main.js.map +1 -1
  277. package/dist/migrations.d.ts +2 -2
  278. package/dist/migrations.d.ts.map +1 -1
  279. package/dist/migrations.js +24 -4
  280. package/dist/migrations.js.map +1 -1
  281. package/dist/modes/index.d.ts.map +1 -1
  282. package/dist/modes/interactive/components/armin.d.ts.map +1 -1
  283. package/dist/modes/interactive/components/armin.js +10 -6
  284. package/dist/modes/interactive/components/armin.js.map +1 -1
  285. package/dist/modes/interactive/components/assistant-message.d.ts +5 -1
  286. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  287. package/dist/modes/interactive/components/assistant-message.js +32 -3
  288. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  289. package/dist/modes/interactive/components/bash-execution.d.ts +0 -1
  290. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  291. package/dist/modes/interactive/components/bash-execution.js +31 -12
  292. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  293. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  294. package/dist/modes/interactive/components/bordered-loader.js +7 -1
  295. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  296. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  297. package/dist/modes/interactive/components/branch-summary-message.js +5 -3
  298. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  299. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  300. package/dist/modes/interactive/components/compaction-summary-message.js +5 -3
  301. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  302. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  303. package/dist/modes/interactive/components/config-selector.js +49 -16
  304. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  305. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  306. package/dist/modes/interactive/components/countdown-timer.js +5 -0
  307. package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  308. package/dist/modes/interactive/components/custom-editor.d.ts +3 -3
  309. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  310. package/dist/modes/interactive/components/custom-editor.js +14 -7
  311. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  312. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  313. package/dist/modes/interactive/components/custom-message.js +6 -1
  314. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  315. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  316. package/dist/modes/interactive/components/daxnuts.js +8 -6
  317. package/dist/modes/interactive/components/daxnuts.js.map +1 -1
  318. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  319. package/dist/modes/interactive/components/diff.js.map +1 -1
  320. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  321. package/dist/modes/interactive/components/dynamic-border.js +1 -0
  322. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  323. package/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  324. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -0
  325. package/dist/modes/interactive/components/earendil-announcement.js +40 -0
  326. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -0
  327. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  328. package/dist/modes/interactive/components/extension-editor.js +16 -10
  329. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  330. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  331. package/dist/modes/interactive/components/extension-input.js +13 -7
  332. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  333. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  334. package/dist/modes/interactive/components/extension-selector.js +18 -11
  335. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  336. package/dist/modes/interactive/components/footer.d.ts +1 -0
  337. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  338. package/dist/modes/interactive/components/footer.js +7 -2
  339. package/dist/modes/interactive/components/footer.js.map +1 -1
  340. package/dist/modes/interactive/components/index.d.ts +1 -1
  341. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  342. package/dist/modes/interactive/components/index.js +1 -1
  343. package/dist/modes/interactive/components/index.js.map +1 -1
  344. package/dist/modes/interactive/components/keybinding-hints.d.ts +8 -36
  345. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  346. package/dist/modes/interactive/components/keybinding-hints.js +23 -48
  347. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  348. package/dist/modes/interactive/components/login-dialog.d.ts +5 -1
  349. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  350. package/dist/modes/interactive/components/login-dialog.js +35 -14
  351. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  352. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  353. package/dist/modes/interactive/components/model-selector.js +41 -22
  354. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  355. package/dist/modes/interactive/components/oauth-selector.d.ts +18 -6
  356. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  357. package/dist/modes/interactive/components/oauth-selector.js +104 -31
  358. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  359. package/dist/modes/interactive/components/scoped-models-selector.d.ts +5 -12
  360. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  361. package/dist/modes/interactive/components/scoped-models-selector.js +61 -42
  362. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  363. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  364. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  365. package/dist/modes/interactive/components/session-selector.d.ts +2 -1
  366. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  367. package/dist/modes/interactive/components/session-selector.js +109 -73
  368. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  369. package/dist/modes/interactive/components/settings-selector.d.ts +9 -0
  370. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  371. package/dist/modes/interactive/components/settings-selector.js +84 -4
  372. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  373. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  374. package/dist/modes/interactive/components/show-images-selector.js +6 -1
  375. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  376. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  377. package/dist/modes/interactive/components/skill-invocation-message.js +5 -3
  378. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  379. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  380. package/dist/modes/interactive/components/theme-selector.js +7 -1
  381. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  382. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  383. package/dist/modes/interactive/components/thinking-selector.js +6 -1
  384. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  385. package/dist/modes/interactive/components/tool-execution.d.ts +20 -34
  386. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  387. package/dist/modes/interactive/components/tool-execution.js +158 -636
  388. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  389. package/dist/modes/interactive/components/tree-selector.d.ts +21 -2
  390. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  391. package/dist/modes/interactive/components/tree-selector.js +224 -52
  392. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  393. package/dist/modes/interactive/components/user-message-selector.d.ts +2 -2
  394. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  395. package/dist/modes/interactive/components/user-message-selector.js +20 -16
  396. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  397. package/dist/modes/interactive/components/user-message.d.ts +1 -0
  398. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  399. package/dist/modes/interactive/components/user-message.js +8 -6
  400. package/dist/modes/interactive/components/user-message.js.map +1 -1
  401. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
  402. package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
  403. package/dist/modes/interactive/interactive-mode.d.ts +67 -39
  404. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  405. package/dist/modes/interactive/interactive-mode.js +1556 -680
  406. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  407. package/dist/modes/interactive/theme/dark.json +1 -1
  408. package/dist/modes/interactive/theme/light.json +1 -1
  409. package/dist/modes/interactive/theme/theme.d.ts +3 -0
  410. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  411. package/dist/modes/interactive/theme/theme.js +101 -72
  412. package/dist/modes/interactive/theme/theme.js.map +1 -1
  413. package/dist/modes/print-mode.d.ts +2 -2
  414. package/dist/modes/print-mode.d.ts.map +1 -1
  415. package/dist/modes/print-mode.js +107 -77
  416. package/dist/modes/print-mode.js.map +1 -1
  417. package/dist/modes/rpc/jsonl.d.ts +17 -0
  418. package/dist/modes/rpc/jsonl.d.ts.map +1 -0
  419. package/dist/modes/rpc/jsonl.js +49 -0
  420. package/dist/modes/rpc/jsonl.js.map +1 -0
  421. package/dist/modes/rpc/rpc-client.d.ts +8 -1
  422. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  423. package/dist/modes/rpc/rpc-client.js +22 -16
  424. package/dist/modes/rpc/rpc-client.js.map +1 -1
  425. package/dist/modes/rpc/rpc-mode.d.ts +2 -2
  426. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  427. package/dist/modes/rpc/rpc-mode.js +184 -94
  428. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  429. package/dist/modes/rpc/rpc-types.d.ts +14 -4
  430. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  431. package/dist/modes/rpc/rpc-types.js.map +1 -1
  432. package/dist/package-manager-cli.d.ts +4 -0
  433. package/dist/package-manager-cli.d.ts.map +1 -0
  434. package/dist/package-manager-cli.js +460 -0
  435. package/dist/package-manager-cli.js.map +1 -0
  436. package/dist/utils/changelog.d.ts.map +1 -1
  437. package/dist/utils/changelog.js.map +1 -1
  438. package/dist/utils/child-process.d.ts +12 -0
  439. package/dist/utils/child-process.d.ts.map +1 -0
  440. package/dist/utils/child-process.js +86 -0
  441. package/dist/utils/child-process.js.map +1 -0
  442. package/dist/utils/clipboard-image.d.ts.map +1 -1
  443. package/dist/utils/clipboard-image.js +94 -11
  444. package/dist/utils/clipboard-image.js.map +1 -1
  445. package/dist/utils/clipboard-native.d.ts +1 -0
  446. package/dist/utils/clipboard-native.d.ts.map +1 -1
  447. package/dist/utils/clipboard-native.js.map +1 -1
  448. package/dist/utils/clipboard.d.ts +1 -1
  449. package/dist/utils/clipboard.d.ts.map +1 -1
  450. package/dist/utils/clipboard.js +96 -46
  451. package/dist/utils/clipboard.js.map +1 -1
  452. package/dist/utils/exif-orientation.d.ts +5 -0
  453. package/dist/utils/exif-orientation.d.ts.map +1 -0
  454. package/dist/utils/exif-orientation.js +158 -0
  455. package/dist/utils/exif-orientation.js.map +1 -0
  456. package/dist/utils/frontmatter.d.ts.map +1 -1
  457. package/dist/utils/frontmatter.js.map +1 -1
  458. package/dist/utils/fs-watch.d.ts +5 -0
  459. package/dist/utils/fs-watch.d.ts.map +1 -0
  460. package/dist/utils/fs-watch.js +25 -0
  461. package/dist/utils/fs-watch.js.map +1 -0
  462. package/dist/utils/git.d.ts.map +1 -1
  463. package/dist/utils/git.js.map +1 -1
  464. package/dist/utils/image-convert.d.ts.map +1 -1
  465. package/dist/utils/image-convert.js +5 -1
  466. package/dist/utils/image-convert.js.map +1 -1
  467. package/dist/utils/image-resize.d.ts +5 -5
  468. package/dist/utils/image-resize.d.ts.map +1 -1
  469. package/dist/utils/image-resize.js +51 -95
  470. package/dist/utils/image-resize.js.map +1 -1
  471. package/dist/utils/mime.d.ts.map +1 -1
  472. package/dist/utils/mime.js.map +1 -1
  473. package/dist/utils/paths.d.ts +16 -0
  474. package/dist/utils/paths.d.ts.map +1 -0
  475. package/dist/utils/paths.js +50 -0
  476. package/dist/utils/paths.js.map +1 -0
  477. package/dist/utils/photon.d.ts.map +1 -1
  478. package/dist/utils/photon.js.map +1 -1
  479. package/dist/utils/pi-user-agent.d.ts +2 -0
  480. package/dist/utils/pi-user-agent.d.ts.map +1 -0
  481. package/dist/utils/pi-user-agent.js +5 -0
  482. package/dist/utils/pi-user-agent.js.map +1 -0
  483. package/dist/utils/shell.d.ts +10 -6
  484. package/dist/utils/shell.d.ts.map +1 -1
  485. package/dist/utils/shell.js +29 -25
  486. package/dist/utils/shell.js.map +1 -1
  487. package/dist/utils/sleep.d.ts.map +1 -1
  488. package/dist/utils/sleep.js.map +1 -1
  489. package/dist/utils/tools-manager.d.ts.map +1 -1
  490. package/dist/utils/tools-manager.js +11 -6
  491. package/dist/utils/tools-manager.js.map +1 -1
  492. package/dist/utils/version-check.d.ts +14 -0
  493. package/dist/utils/version-check.d.ts.map +1 -0
  494. package/dist/utils/version-check.js +77 -0
  495. package/dist/utils/version-check.js.map +1 -0
  496. package/docs/compaction.md +394 -0
  497. package/docs/custom-provider.md +646 -0
  498. package/docs/development.md +71 -0
  499. package/docs/docs.json +148 -0
  500. package/docs/extensions.md +2596 -0
  501. package/docs/images/doom-extension.png +0 -0
  502. package/docs/images/exy.png +0 -0
  503. package/docs/images/interactive-mode.png +0 -0
  504. package/docs/images/tree-view.png +0 -0
  505. package/docs/index.md +70 -0
  506. package/docs/json.md +82 -0
  507. package/docs/keybindings.md +197 -0
  508. package/docs/models.md +474 -0
  509. package/docs/packages.md +223 -0
  510. package/docs/prompt-templates.md +88 -0
  511. package/docs/providers.md +243 -0
  512. package/docs/quickstart.md +142 -0
  513. package/docs/rpc.md +1407 -0
  514. package/docs/sdk.md +1149 -0
  515. package/docs/session-format.md +412 -0
  516. package/docs/sessions.md +137 -0
  517. package/docs/settings.md +279 -0
  518. package/docs/shell-aliases.md +13 -0
  519. package/docs/skills.md +232 -0
  520. package/docs/terminal-setup.md +106 -0
  521. package/docs/termux.md +127 -0
  522. package/docs/themes.md +295 -0
  523. package/docs/tmux.md +61 -0
  524. package/docs/tui.md +918 -0
  525. package/docs/usage.md +277 -0
  526. package/docs/windows.md +17 -0
  527. package/examples/README.md +25 -0
  528. package/examples/extensions/README.md +208 -0
  529. package/examples/extensions/auto-commit-on-exit.ts +49 -0
  530. package/examples/extensions/bash-spawn-hook.ts +30 -0
  531. package/examples/extensions/bookmark.ts +50 -0
  532. package/examples/extensions/border-status-editor.ts +150 -0
  533. package/examples/extensions/built-in-tool-renderer.ts +249 -0
  534. package/examples/extensions/claude-rules.ts +86 -0
  535. package/examples/extensions/commands.ts +72 -0
  536. package/examples/extensions/confirm-destructive.ts +59 -0
  537. package/examples/extensions/custom-compaction.ts +127 -0
  538. package/examples/extensions/custom-footer.ts +64 -0
  539. package/examples/extensions/custom-header.ts +73 -0
  540. package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
  541. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  542. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  543. package/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
  544. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  545. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  546. package/examples/extensions/dirty-repo-guard.ts +56 -0
  547. package/examples/extensions/doom-overlay/README.md +46 -0
  548. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
  549. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  550. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  551. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  552. package/examples/extensions/doom-overlay/doom-component.ts +132 -0
  553. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  554. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  555. package/examples/extensions/doom-overlay/index.ts +74 -0
  556. package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  557. package/examples/extensions/dynamic-resources/SKILL.md +8 -0
  558. package/examples/extensions/dynamic-resources/dynamic.json +79 -0
  559. package/examples/extensions/dynamic-resources/dynamic.md +5 -0
  560. package/examples/extensions/dynamic-resources/index.ts +15 -0
  561. package/examples/extensions/dynamic-tools.ts +74 -0
  562. package/examples/extensions/event-bus.ts +43 -0
  563. package/examples/extensions/file-trigger.ts +41 -0
  564. package/examples/extensions/git-checkpoint.ts +53 -0
  565. package/examples/extensions/github-issue-autocomplete.ts +185 -0
  566. package/examples/extensions/handoff.ts +191 -0
  567. package/examples/extensions/hello.ts +26 -0
  568. package/examples/extensions/hidden-thinking-label.ts +53 -0
  569. package/examples/extensions/inline-bash.ts +94 -0
  570. package/examples/extensions/input-transform.ts +43 -0
  571. package/examples/extensions/interactive-shell.ts +196 -0
  572. package/examples/extensions/mac-system-theme.ts +47 -0
  573. package/examples/extensions/message-renderer.ts +59 -0
  574. package/examples/extensions/minimal-mode.ts +426 -0
  575. package/examples/extensions/modal-editor.ts +85 -0
  576. package/examples/extensions/model-status.ts +31 -0
  577. package/examples/extensions/notify.ts +55 -0
  578. package/examples/extensions/overlay-qa-tests.ts +1348 -0
  579. package/examples/extensions/overlay-test.ts +150 -0
  580. package/examples/extensions/permission-gate.ts +34 -0
  581. package/examples/extensions/pirate.ts +47 -0
  582. package/examples/extensions/plan-mode/README.md +65 -0
  583. package/examples/extensions/plan-mode/index.ts +340 -0
  584. package/examples/extensions/plan-mode/utils.ts +168 -0
  585. package/examples/extensions/preset.ts +430 -0
  586. package/examples/extensions/prompt-customizer.ts +97 -0
  587. package/examples/extensions/protected-paths.ts +30 -0
  588. package/examples/extensions/provider-payload.ts +18 -0
  589. package/examples/extensions/qna.ts +122 -0
  590. package/examples/extensions/question.ts +264 -0
  591. package/examples/extensions/questionnaire.ts +427 -0
  592. package/examples/extensions/rainbow-editor.ts +88 -0
  593. package/examples/extensions/reload-runtime.ts +37 -0
  594. package/examples/extensions/rpc-demo.ts +118 -0
  595. package/examples/extensions/sandbox/index.ts +321 -0
  596. package/examples/extensions/sandbox/package-lock.json +92 -0
  597. package/examples/extensions/sandbox/package.json +19 -0
  598. package/examples/extensions/send-user-message.ts +97 -0
  599. package/examples/extensions/session-name.ts +27 -0
  600. package/examples/extensions/shutdown-command.ts +63 -0
  601. package/examples/extensions/snake.ts +343 -0
  602. package/examples/extensions/space-invaders.ts +560 -0
  603. package/examples/extensions/ssh.ts +220 -0
  604. package/examples/extensions/status-line.ts +32 -0
  605. package/examples/extensions/structured-output.ts +65 -0
  606. package/examples/extensions/subagent/README.md +172 -0
  607. package/examples/extensions/subagent/agents/planner.md +37 -0
  608. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  609. package/examples/extensions/subagent/agents/scout.md +50 -0
  610. package/examples/extensions/subagent/agents/worker.md +24 -0
  611. package/examples/extensions/subagent/agents.ts +126 -0
  612. package/examples/extensions/subagent/index.ts +987 -0
  613. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  614. package/examples/extensions/subagent/prompts/implement.md +10 -0
  615. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  616. package/examples/extensions/summarize.ts +206 -0
  617. package/examples/extensions/system-prompt-header.ts +17 -0
  618. package/examples/extensions/tic-tac-toe.ts +1008 -0
  619. package/examples/extensions/timed-confirm.ts +70 -0
  620. package/examples/extensions/titlebar-spinner.ts +58 -0
  621. package/examples/extensions/todo.ts +297 -0
  622. package/examples/extensions/tool-override.ts +144 -0
  623. package/examples/extensions/tools.ts +141 -0
  624. package/examples/extensions/trigger-compact.ts +50 -0
  625. package/examples/extensions/truncated-tool.ts +195 -0
  626. package/examples/extensions/widget-placement.ts +9 -0
  627. package/examples/extensions/with-deps/index.ts +32 -0
  628. package/examples/extensions/with-deps/package-lock.json +31 -0
  629. package/examples/extensions/with-deps/package.json +22 -0
  630. package/examples/extensions/working-indicator.ts +123 -0
  631. package/examples/extensions/working-message-test.ts +25 -0
  632. package/examples/rpc-extension-ui.ts +632 -0
  633. package/examples/sdk/01-minimal.ts +22 -0
  634. package/examples/sdk/02-custom-model.ts +49 -0
  635. package/examples/sdk/03-custom-prompt.ts +62 -0
  636. package/examples/sdk/04-skills.ts +55 -0
  637. package/examples/sdk/05-tools.ts +44 -0
  638. package/examples/sdk/06-extensions.ts +90 -0
  639. package/examples/sdk/07-context-files.ts +42 -0
  640. package/examples/sdk/08-prompt-templates.ts +51 -0
  641. package/examples/sdk/09-api-keys-and-oauth.ts +48 -0
  642. package/examples/sdk/10-settings.ts +53 -0
  643. package/examples/sdk/11-sessions.ts +48 -0
  644. package/examples/sdk/12-full-control.ts +73 -0
  645. package/examples/sdk/13-session-runtime.ts +67 -0
  646. package/examples/sdk/README.md +147 -0
  647. package/extensions/phi/init.ts +15 -1
  648. package/extensions/phi/keys.ts +186 -0
  649. package/extensions/phi/providers/alibaba.ts +126 -0
  650. package/extensions/phi/providers/opencode-go.ts +204 -0
  651. package/extensions/phi/setup.ts +692 -0
  652. package/extensions/phi/smart-router.ts +8 -0
  653. package/extensions/phi/web-search.ts +432 -186
  654. package/package.json +111 -106
  655. package/scripts/copy-assets.sh +0 -0
  656. package/scripts/migrate-sessions.sh +0 -0
@@ -2,37 +2,44 @@
2
2
  * Extension runner - executes extensions and manages their lifecycle.
3
3
  */
4
4
  import { theme } from "../../modes/interactive/theme/theme.js";
5
- // Keybindings for these actions cannot be overridden by extensions
6
- const RESERVED_ACTIONS_FOR_EXTENSION_CONFLICTS = [
7
- "interrupt",
8
- "clear",
9
- "exit",
10
- "suspend",
11
- "cycleThinkingLevel",
12
- "cycleModelForward",
13
- "cycleModelBackward",
14
- "selectModel",
15
- "expandTools",
16
- "toggleThinking",
17
- "externalEditor",
18
- "followUp",
19
- "submit",
20
- "selectConfirm",
21
- "selectCancel",
22
- "copy",
23
- "deleteToLineEnd",
5
+ // Extension shortcuts compete with canonical keybinding ids from keybindings.json.
6
+ // Only editor-global shortcuts are reserved here. Picker-specific bindings are not.
7
+ const RESERVED_KEYBINDINGS_FOR_EXTENSION_CONFLICTS = [
8
+ "app.interrupt",
9
+ "app.clear",
10
+ "app.exit",
11
+ "app.suspend",
12
+ "app.thinking.cycle",
13
+ "app.model.cycleForward",
14
+ "app.model.cycleBackward",
15
+ "app.model.select",
16
+ "app.tools.expand",
17
+ "app.thinking.toggle",
18
+ "app.editor.external",
19
+ "app.message.followUp",
20
+ "tui.input.submit",
21
+ "tui.select.confirm",
22
+ "tui.select.cancel",
23
+ "tui.input.copy",
24
+ "tui.editor.deleteToLineEnd",
24
25
  ];
25
- const buildBuiltinKeybindings = (effectiveKeybindings) => {
26
+ const buildBuiltinKeybindings = (resolvedKeybindings) => {
26
27
  const builtinKeybindings = {};
27
- for (const [action, keys] of Object.entries(effectiveKeybindings)) {
28
- const keyAction = action;
28
+ for (const [keybinding, keys] of Object.entries(resolvedKeybindings)) {
29
+ if (keys === undefined)
30
+ continue;
29
31
  const keyList = Array.isArray(keys) ? keys : [keys];
30
- const restrictOverride = RESERVED_ACTIONS_FOR_EXTENSION_CONFLICTS.includes(keyAction);
32
+ const restrictOverride = RESERVED_KEYBINDINGS_FOR_EXTENSION_CONFLICTS.includes(keybinding);
31
33
  for (const key of keyList) {
32
34
  const normalizedKey = key.toLowerCase();
35
+ // If multiple actions bind the same key, the reserved action wins so extensions
36
+ // remain blocked by reserved shortcuts regardless of iteration order.
37
+ const existing = builtinKeybindings[normalizedKey];
38
+ if (existing?.restrictOverride && !restrictOverride)
39
+ continue;
33
40
  builtinKeybindings[normalizedKey] = {
34
- action: keyAction,
35
- restrictOverride: restrictOverride,
41
+ keybinding,
42
+ restrictOverride,
36
43
  };
37
44
  }
38
45
  }
@@ -42,11 +49,9 @@ const buildBuiltinKeybindings = (effectiveKeybindings) => {
42
49
  * Helper function to emit session_shutdown event to extensions.
43
50
  * Returns true if the event was emitted, false if there were no handlers.
44
51
  */
45
- export async function emitSessionShutdownEvent(extensionRunner) {
46
- if (extensionRunner?.hasHandlers("session_shutdown")) {
47
- await extensionRunner.emit({
48
- type: "session_shutdown",
49
- });
52
+ export async function emitSessionShutdownEvent(extensionRunner, event) {
53
+ if (extensionRunner.hasHandlers("session_shutdown")) {
54
+ await extensionRunner.emit(event);
50
55
  return true;
51
56
  }
52
57
  return false;
@@ -59,6 +64,9 @@ const noOpUIContext = {
59
64
  onTerminalInput: () => () => { },
60
65
  setStatus: () => { },
61
66
  setWorkingMessage: () => { },
67
+ setWorkingVisible: () => { },
68
+ setWorkingIndicator: () => { },
69
+ setHiddenThinkingLabel: () => { },
62
70
  setWidget: () => { },
63
71
  setFooter: () => { },
64
72
  setHeader: () => { },
@@ -68,7 +76,9 @@ const noOpUIContext = {
68
76
  setEditorText: () => { },
69
77
  getEditorText: () => "",
70
78
  editor: async () => undefined,
79
+ addAutocompleteProvider: () => { },
71
80
  setEditorComponent: () => { },
81
+ getEditorComponent: () => undefined,
72
82
  get theme() {
73
83
  return theme;
74
84
  },
@@ -79,24 +89,32 @@ const noOpUIContext = {
79
89
  setToolsExpanded: () => { },
80
90
  };
81
91
  export class ExtensionRunner {
92
+ extensions;
93
+ runtime;
94
+ uiContext;
95
+ cwd;
96
+ sessionManager;
97
+ modelRegistry;
98
+ errorListeners = new Set();
99
+ getModel = () => undefined;
100
+ isIdleFn = () => true;
101
+ getSignalFn = () => undefined;
102
+ waitForIdleFn = async () => { };
103
+ abortFn = () => { };
104
+ hasPendingMessagesFn = () => false;
105
+ getContextUsageFn = () => undefined;
106
+ compactFn = () => { };
107
+ getSystemPromptFn = () => "";
108
+ newSessionHandler = async () => ({ cancelled: false });
109
+ forkHandler = async () => ({ cancelled: false });
110
+ navigateTreeHandler = async () => ({ cancelled: false });
111
+ switchSessionHandler = async () => ({ cancelled: false });
112
+ reloadHandler = async () => { };
113
+ shutdownHandler = () => { };
114
+ shortcutDiagnostics = [];
115
+ commandDiagnostics = [];
116
+ staleMessage;
82
117
  constructor(extensions, runtime, cwd, sessionManager, modelRegistry) {
83
- this.errorListeners = new Set();
84
- this.getModel = () => undefined;
85
- this.isIdleFn = () => true;
86
- this.waitForIdleFn = async () => { };
87
- this.abortFn = () => { };
88
- this.hasPendingMessagesFn = () => false;
89
- this.getContextUsageFn = () => undefined;
90
- this.compactFn = () => { };
91
- this.getSystemPromptFn = () => "";
92
- this.newSessionHandler = async () => ({ cancelled: false });
93
- this.forkHandler = async () => ({ cancelled: false });
94
- this.navigateTreeHandler = async () => ({ cancelled: false });
95
- this.switchSessionHandler = async () => ({ cancelled: false });
96
- this.reloadHandler = async () => { };
97
- this.shutdownHandler = () => { };
98
- this.shortcutDiagnostics = [];
99
- this.commandDiagnostics = [];
100
118
  this.extensions = extensions;
101
119
  this.runtime = runtime;
102
120
  this.uiContext = noOpUIContext;
@@ -104,7 +122,7 @@ export class ExtensionRunner {
104
122
  this.sessionManager = sessionManager;
105
123
  this.modelRegistry = modelRegistry;
106
124
  }
107
- bindCore(actions, contextActions) {
125
+ bindCore(actions, contextActions, providerActions) {
108
126
  // Copy actions into the shared runtime (all extension APIs reference this)
109
127
  this.runtime.sendMessage = actions.sendMessage;
110
128
  this.runtime.sendUserMessage = actions.sendUserMessage;
@@ -123,6 +141,7 @@ export class ExtensionRunner {
123
141
  // Context actions (required)
124
142
  this.getModel = contextActions.getModel;
125
143
  this.isIdleFn = contextActions.isIdle;
144
+ this.getSignalFn = contextActions.getSignal;
126
145
  this.abortFn = contextActions.abort;
127
146
  this.hasPendingMessagesFn = contextActions.hasPendingMessages;
128
147
  this.shutdownHandler = contextActions.shutdown;
@@ -130,14 +149,41 @@ export class ExtensionRunner {
130
149
  this.compactFn = contextActions.compact;
131
150
  this.getSystemPromptFn = contextActions.getSystemPrompt;
132
151
  // Flush provider registrations queued during extension loading
133
- for (const { name, config } of this.runtime.pendingProviderRegistrations) {
134
- this.modelRegistry.registerProvider(name, config);
152
+ for (const { name, config, extensionPath } of this.runtime.pendingProviderRegistrations) {
153
+ try {
154
+ if (providerActions?.registerProvider) {
155
+ providerActions.registerProvider(name, config);
156
+ }
157
+ else {
158
+ this.modelRegistry.registerProvider(name, config);
159
+ }
160
+ }
161
+ catch (err) {
162
+ this.emitError({
163
+ extensionPath,
164
+ event: "register_provider",
165
+ error: err instanceof Error ? err.message : String(err),
166
+ stack: err instanceof Error ? err.stack : undefined,
167
+ });
168
+ }
135
169
  }
136
170
  this.runtime.pendingProviderRegistrations = [];
137
171
  // From this point on, provider registration/unregistration takes effect immediately
138
172
  // without requiring a /reload.
139
- this.runtime.registerProvider = (name, config) => this.modelRegistry.registerProvider(name, config);
140
- this.runtime.unregisterProvider = (name) => this.modelRegistry.unregisterProvider(name);
173
+ this.runtime.registerProvider = (name, config) => {
174
+ if (providerActions?.registerProvider) {
175
+ providerActions.registerProvider(name, config);
176
+ return;
177
+ }
178
+ this.modelRegistry.registerProvider(name, config);
179
+ };
180
+ this.runtime.unregisterProvider = (name) => {
181
+ if (providerActions?.unregisterProvider) {
182
+ providerActions.unregisterProvider(name);
183
+ return;
184
+ }
185
+ this.modelRegistry.unregisterProvider(name);
186
+ };
141
187
  }
142
188
  bindCommandContext(actions) {
143
189
  if (actions) {
@@ -207,9 +253,9 @@ export class ExtensionRunner {
207
253
  getFlagValues() {
208
254
  return new Map(this.runtime.flagValues);
209
255
  }
210
- getShortcuts(effectiveKeybindings) {
256
+ getShortcuts(resolvedKeybindings) {
211
257
  this.shortcutDiagnostics = [];
212
- const builtinKeybindings = buildBuiltinKeybindings(effectiveKeybindings);
258
+ const builtinKeybindings = buildBuiltinKeybindings(resolvedKeybindings);
213
259
  const extensionShortcuts = new Map();
214
260
  const addDiagnostic = (message, extensionPath) => {
215
261
  this.shortcutDiagnostics.push({ type: "warning", message, path: extensionPath });
@@ -226,7 +272,7 @@ export class ExtensionRunner {
226
272
  continue;
227
273
  }
228
274
  if (builtInKeybinding?.restrictOverride === false) {
229
- addDiagnostic(`Extension shortcut conflict: '${key}' is built-in shortcut for ${builtInKeybinding.action} and ${shortcut.extensionPath}. Using ${shortcut.extensionPath}.`, shortcut.extensionPath);
275
+ addDiagnostic(`Extension shortcut conflict: '${key}' is built-in shortcut for ${builtInKeybinding.keybinding} and ${shortcut.extensionPath}. Using ${shortcut.extensionPath}.`, shortcut.extensionPath);
230
276
  }
231
277
  const existingExtensionShortcut = extensionShortcuts.get(normalizedKey);
232
278
  if (existingExtensionShortcut) {
@@ -240,6 +286,17 @@ export class ExtensionRunner {
240
286
  getShortcutDiagnostics() {
241
287
  return this.shortcutDiagnostics;
242
288
  }
289
+ invalidate(message = "This extension ctx is stale after session replacement or reload. Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().") {
290
+ if (!this.staleMessage) {
291
+ this.staleMessage = message;
292
+ this.runtime.invalidate(message);
293
+ }
294
+ }
295
+ assertActive() {
296
+ if (this.staleMessage) {
297
+ throw new Error(this.staleMessage);
298
+ }
299
+ }
243
300
  onError(listener) {
244
301
  this.errorListeners.add(listener);
245
302
  return () => this.errorListeners.delete(listener);
@@ -267,55 +324,44 @@ export class ExtensionRunner {
267
324
  }
268
325
  return undefined;
269
326
  }
270
- getRegisteredCommands(reserved) {
271
- this.commandDiagnostics = [];
327
+ resolveRegisteredCommands() {
272
328
  const commands = [];
273
- const commandOwners = new Map();
329
+ const counts = new Map();
274
330
  for (const ext of this.extensions) {
275
331
  for (const command of ext.commands.values()) {
276
- if (reserved?.has(command.name)) {
277
- const message = `Extension command '${command.name}' from ${ext.path} conflicts with built-in commands. Skipping.`;
278
- this.commandDiagnostics.push({ type: "warning", message, path: ext.path });
279
- if (!this.hasUI()) {
280
- console.warn(message);
281
- }
282
- continue;
283
- }
284
- const existingOwner = commandOwners.get(command.name);
285
- if (existingOwner) {
286
- const message = `Extension command '${command.name}' from ${ext.path} conflicts with ${existingOwner}. Skipping.`;
287
- this.commandDiagnostics.push({ type: "warning", message, path: ext.path });
288
- if (!this.hasUI()) {
289
- console.warn(message);
290
- }
291
- continue;
292
- }
293
- commandOwners.set(command.name, ext.path);
294
332
  commands.push(command);
333
+ counts.set(command.name, (counts.get(command.name) ?? 0) + 1);
295
334
  }
296
335
  }
297
- return commands;
336
+ const seen = new Map();
337
+ const takenInvocationNames = new Set();
338
+ return commands.map((command) => {
339
+ const occurrence = (seen.get(command.name) ?? 0) + 1;
340
+ seen.set(command.name, occurrence);
341
+ let invocationName = (counts.get(command.name) ?? 0) > 1 ? `${command.name}:${occurrence}` : command.name;
342
+ if (takenInvocationNames.has(invocationName)) {
343
+ let suffix = occurrence;
344
+ do {
345
+ suffix++;
346
+ invocationName = `${command.name}:${suffix}`;
347
+ } while (takenInvocationNames.has(invocationName));
348
+ }
349
+ takenInvocationNames.add(invocationName);
350
+ return {
351
+ ...command,
352
+ invocationName,
353
+ };
354
+ });
355
+ }
356
+ getRegisteredCommands() {
357
+ this.commandDiagnostics = [];
358
+ return this.resolveRegisteredCommands();
298
359
  }
299
360
  getCommandDiagnostics() {
300
361
  return this.commandDiagnostics;
301
362
  }
302
- getRegisteredCommandsWithPaths() {
303
- const result = [];
304
- for (const ext of this.extensions) {
305
- for (const command of ext.commands.values()) {
306
- result.push({ command, extensionPath: ext.path });
307
- }
308
- }
309
- return result;
310
- }
311
363
  getCommand(name) {
312
- for (const ext of this.extensions) {
313
- const command = ext.commands.get(name);
314
- if (command) {
315
- return command;
316
- }
317
- }
318
- return undefined;
364
+ return this.resolveRegisteredCommands().find((command) => command.invocationName === name);
319
365
  }
320
366
  /**
321
367
  * Request a graceful shutdown. Called by extension tools and event handlers.
@@ -329,35 +375,97 @@ export class ExtensionRunner {
329
375
  * Context values are resolved at call time, so changes via bindCore/bindUI are reflected.
330
376
  */
331
377
  createContext() {
378
+ const runner = this;
332
379
  const getModel = this.getModel;
333
380
  return {
334
- ui: this.uiContext,
335
- hasUI: this.hasUI(),
336
- cwd: this.cwd,
337
- sessionManager: this.sessionManager,
338
- modelRegistry: this.modelRegistry,
381
+ get ui() {
382
+ runner.assertActive();
383
+ return runner.uiContext;
384
+ },
385
+ get hasUI() {
386
+ runner.assertActive();
387
+ return runner.hasUI();
388
+ },
389
+ get cwd() {
390
+ runner.assertActive();
391
+ return runner.cwd;
392
+ },
393
+ get sessionManager() {
394
+ runner.assertActive();
395
+ return runner.sessionManager;
396
+ },
397
+ get modelRegistry() {
398
+ runner.assertActive();
399
+ return runner.modelRegistry;
400
+ },
339
401
  get model() {
402
+ runner.assertActive();
340
403
  return getModel();
341
404
  },
342
- isIdle: () => this.isIdleFn(),
343
- abort: () => this.abortFn(),
344
- hasPendingMessages: () => this.hasPendingMessagesFn(),
345
- shutdown: () => this.shutdownHandler(),
346
- getContextUsage: () => this.getContextUsageFn(),
347
- compact: (options) => this.compactFn(options),
348
- getSystemPrompt: () => this.getSystemPromptFn(),
405
+ isIdle: () => {
406
+ runner.assertActive();
407
+ return runner.isIdleFn();
408
+ },
409
+ get signal() {
410
+ runner.assertActive();
411
+ return runner.getSignalFn();
412
+ },
413
+ abort: () => {
414
+ runner.assertActive();
415
+ runner.abortFn();
416
+ },
417
+ hasPendingMessages: () => {
418
+ runner.assertActive();
419
+ return runner.hasPendingMessagesFn();
420
+ },
421
+ shutdown: () => {
422
+ runner.assertActive();
423
+ runner.shutdownHandler();
424
+ },
425
+ getContextUsage: () => {
426
+ runner.assertActive();
427
+ return runner.getContextUsageFn();
428
+ },
429
+ compact: (options) => {
430
+ runner.assertActive();
431
+ runner.compactFn(options);
432
+ },
433
+ getSystemPrompt: () => {
434
+ runner.assertActive();
435
+ return runner.getSystemPromptFn();
436
+ },
349
437
  };
350
438
  }
351
439
  createCommandContext() {
352
- return {
353
- ...this.createContext(),
354
- waitForIdle: () => this.waitForIdleFn(),
355
- newSession: (options) => this.newSessionHandler(options),
356
- fork: (entryId) => this.forkHandler(entryId),
357
- navigateTree: (targetId, options) => this.navigateTreeHandler(targetId, options),
358
- switchSession: (sessionPath) => this.switchSessionHandler(sessionPath),
359
- reload: () => this.reloadHandler(),
440
+ // Use property descriptors instead of object spread so the guarded getters from
441
+ // createContext() stay lazy. A spread would eagerly read them once and freeze the
442
+ // old values into the returned object, bypassing stale-instance checks.
443
+ const context = Object.defineProperties({}, Object.getOwnPropertyDescriptors(this.createContext()));
444
+ context.waitForIdle = () => {
445
+ this.assertActive();
446
+ return this.waitForIdleFn();
447
+ };
448
+ context.newSession = (options) => {
449
+ this.assertActive();
450
+ return this.newSessionHandler(options);
451
+ };
452
+ context.fork = (entryId, options) => {
453
+ this.assertActive();
454
+ return this.forkHandler(entryId, options);
455
+ };
456
+ context.navigateTree = (targetId, options) => {
457
+ this.assertActive();
458
+ return this.navigateTreeHandler(targetId, options);
459
+ };
460
+ context.switchSession = (sessionPath, options) => {
461
+ this.assertActive();
462
+ return this.switchSessionHandler(sessionPath, options);
463
+ };
464
+ context.reload = () => {
465
+ this.assertActive();
466
+ return this.reloadHandler();
360
467
  };
468
+ return context;
361
469
  }
362
470
  isSessionBeforeEvent(event) {
363
471
  return (event.type === "session_before_switch" ||
@@ -396,6 +504,45 @@ export class ExtensionRunner {
396
504
  }
397
505
  return result;
398
506
  }
507
+ async emitMessageEnd(event) {
508
+ const ctx = this.createContext();
509
+ let currentMessage = event.message;
510
+ let modified = false;
511
+ for (const ext of this.extensions) {
512
+ const handlers = ext.handlers.get("message_end");
513
+ if (!handlers || handlers.length === 0)
514
+ continue;
515
+ for (const handler of handlers) {
516
+ try {
517
+ const currentEvent = { ...event, message: currentMessage };
518
+ const handlerResult = (await handler(currentEvent, ctx));
519
+ if (!handlerResult?.message)
520
+ continue;
521
+ if (handlerResult.message.role !== currentMessage.role) {
522
+ this.emitError({
523
+ extensionPath: ext.path,
524
+ event: "message_end",
525
+ error: "message_end handlers must return a message with the same role",
526
+ });
527
+ continue;
528
+ }
529
+ currentMessage = handlerResult.message;
530
+ modified = true;
531
+ }
532
+ catch (err) {
533
+ const message = err instanceof Error ? err.message : String(err);
534
+ const stack = err instanceof Error ? err.stack : undefined;
535
+ this.emitError({
536
+ extensionPath: ext.path,
537
+ event: "message_end",
538
+ error: message,
539
+ stack,
540
+ });
541
+ }
542
+ }
543
+ }
544
+ return modified ? currentMessage : undefined;
545
+ }
399
546
  async emitToolResult(event) {
400
547
  const ctx = this.createContext();
401
548
  const currentEvent = { ...event };
@@ -518,10 +665,46 @@ export class ExtensionRunner {
518
665
  }
519
666
  return currentMessages;
520
667
  }
521
- async emitBeforeAgentStart(prompt, images, systemPrompt) {
668
+ async emitBeforeProviderRequest(payload) {
522
669
  const ctx = this.createContext();
523
- const messages = [];
670
+ let currentPayload = payload;
671
+ for (const ext of this.extensions) {
672
+ const handlers = ext.handlers.get("before_provider_request");
673
+ if (!handlers || handlers.length === 0)
674
+ continue;
675
+ for (const handler of handlers) {
676
+ try {
677
+ const event = {
678
+ type: "before_provider_request",
679
+ payload: currentPayload,
680
+ };
681
+ const handlerResult = await handler(event, ctx);
682
+ if (handlerResult !== undefined) {
683
+ currentPayload = handlerResult;
684
+ }
685
+ }
686
+ catch (err) {
687
+ const message = err instanceof Error ? err.message : String(err);
688
+ const stack = err instanceof Error ? err.stack : undefined;
689
+ this.emitError({
690
+ extensionPath: ext.path,
691
+ event: "before_provider_request",
692
+ error: message,
693
+ stack,
694
+ });
695
+ }
696
+ }
697
+ }
698
+ return currentPayload;
699
+ }
700
+ async emitBeforeAgentStart(prompt, images, systemPrompt, systemPromptOptions) {
524
701
  let currentSystemPrompt = systemPrompt;
702
+ const ctx = Object.defineProperties({}, Object.getOwnPropertyDescriptors(this.createContext()));
703
+ ctx.getSystemPrompt = () => {
704
+ this.assertActive();
705
+ return currentSystemPrompt;
706
+ };
707
+ const messages = [];
525
708
  let systemPromptModified = false;
526
709
  for (const ext of this.extensions) {
527
710
  const handlers = ext.handlers.get("before_agent_start");
@@ -534,6 +717,7 @@ export class ExtensionRunner {
534
717
  prompt,
535
718
  images,
536
719
  systemPrompt: currentSystemPrompt,
720
+ systemPromptOptions,
537
721
  };
538
722
  const handlerResult = await handler(event, ctx);
539
723
  if (handlerResult) {