@phi-code-admin/phi-code 0.56.3

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 (459) hide show
  1. package/CHANGELOG.md +2994 -0
  2. package/README.md +567 -0
  3. package/dist/cli/args.d.ts +48 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/args.js +299 -0
  6. package/dist/cli/args.js.map +1 -0
  7. package/dist/cli/config-selector.d.ts +14 -0
  8. package/dist/cli/config-selector.d.ts.map +1 -0
  9. package/dist/cli/config-selector.js +31 -0
  10. package/dist/cli/config-selector.js.map +1 -0
  11. package/dist/cli/file-processor.d.ts +15 -0
  12. package/dist/cli/file-processor.d.ts.map +1 -0
  13. package/dist/cli/file-processor.js +79 -0
  14. package/dist/cli/file-processor.js.map +1 -0
  15. package/dist/cli/list-models.d.ts +9 -0
  16. package/dist/cli/list-models.d.ts.map +1 -0
  17. package/dist/cli/list-models.js +92 -0
  18. package/dist/cli/list-models.js.map +1 -0
  19. package/dist/cli/session-picker.d.ts +9 -0
  20. package/dist/cli/session-picker.d.ts.map +1 -0
  21. package/dist/cli/session-picker.js +34 -0
  22. package/dist/cli/session-picker.js.map +1 -0
  23. package/dist/cli.d.ts +3 -0
  24. package/dist/cli.d.ts.map +1 -0
  25. package/dist/cli.js +16 -0
  26. package/dist/cli.js.map +1 -0
  27. package/dist/config.d.ts +68 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +203 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/core/agent-session.d.ts +614 -0
  32. package/dist/core/agent-session.d.ts.map +1 -0
  33. package/dist/core/agent-session.js +2475 -0
  34. package/dist/core/agent-session.js.map +1 -0
  35. package/dist/core/auth-storage.d.ts +134 -0
  36. package/dist/core/auth-storage.d.ts.map +1 -0
  37. package/dist/core/auth-storage.js +415 -0
  38. package/dist/core/auth-storage.js.map +1 -0
  39. package/dist/core/bash-executor.d.ts +47 -0
  40. package/dist/core/bash-executor.d.ts.map +1 -0
  41. package/dist/core/bash-executor.js +212 -0
  42. package/dist/core/bash-executor.js.map +1 -0
  43. package/dist/core/compaction/branch-summarization.d.ts +86 -0
  44. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  45. package/dist/core/compaction/branch-summarization.js +242 -0
  46. package/dist/core/compaction/branch-summarization.js.map +1 -0
  47. package/dist/core/compaction/compaction.d.ts +121 -0
  48. package/dist/core/compaction/compaction.d.ts.map +1 -0
  49. package/dist/core/compaction/compaction.js +610 -0
  50. package/dist/core/compaction/compaction.js.map +1 -0
  51. package/dist/core/compaction/index.d.ts +7 -0
  52. package/dist/core/compaction/index.d.ts.map +1 -0
  53. package/dist/core/compaction/index.js +7 -0
  54. package/dist/core/compaction/index.js.map +1 -0
  55. package/dist/core/compaction/utils.d.ts +38 -0
  56. package/dist/core/compaction/utils.d.ts.map +1 -0
  57. package/dist/core/compaction/utils.js +153 -0
  58. package/dist/core/compaction/utils.js.map +1 -0
  59. package/dist/core/defaults.d.ts +3 -0
  60. package/dist/core/defaults.d.ts.map +1 -0
  61. package/dist/core/defaults.js +2 -0
  62. package/dist/core/defaults.js.map +1 -0
  63. package/dist/core/diagnostics.d.ts +15 -0
  64. package/dist/core/diagnostics.d.ts.map +1 -0
  65. package/dist/core/diagnostics.js +2 -0
  66. package/dist/core/diagnostics.js.map +1 -0
  67. package/dist/core/event-bus.d.ts +9 -0
  68. package/dist/core/event-bus.d.ts.map +1 -0
  69. package/dist/core/event-bus.js +25 -0
  70. package/dist/core/event-bus.js.map +1 -0
  71. package/dist/core/exec.d.ts +29 -0
  72. package/dist/core/exec.d.ts.map +1 -0
  73. package/dist/core/exec.js +71 -0
  74. package/dist/core/exec.js.map +1 -0
  75. package/dist/core/export-html/ansi-to-html.d.ts +22 -0
  76. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  77. package/dist/core/export-html/ansi-to-html.js +249 -0
  78. package/dist/core/export-html/ansi-to-html.js.map +1 -0
  79. package/dist/core/export-html/index.d.ts +34 -0
  80. package/dist/core/export-html/index.d.ts.map +1 -0
  81. package/dist/core/export-html/index.js +222 -0
  82. package/dist/core/export-html/index.js.map +1 -0
  83. package/dist/core/export-html/tool-renderer.d.ts +35 -0
  84. package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  85. package/dist/core/export-html/tool-renderer.js +63 -0
  86. package/dist/core/export-html/tool-renderer.js.map +1 -0
  87. package/dist/core/extensions/index.d.ts +11 -0
  88. package/dist/core/extensions/index.d.ts.map +1 -0
  89. package/dist/core/extensions/index.js +9 -0
  90. package/dist/core/extensions/index.js.map +1 -0
  91. package/dist/core/extensions/loader.d.ts +25 -0
  92. package/dist/core/extensions/loader.d.ts.map +1 -0
  93. package/dist/core/extensions/loader.js +426 -0
  94. package/dist/core/extensions/loader.js.map +1 -0
  95. package/dist/core/extensions/runner.d.ts +146 -0
  96. package/dist/core/extensions/runner.d.ts.map +1 -0
  97. package/dist/core/extensions/runner.js +640 -0
  98. package/dist/core/extensions/runner.js.map +1 -0
  99. package/dist/core/extensions/types.d.ts +1017 -0
  100. package/dist/core/extensions/types.d.ts.map +1 -0
  101. package/dist/core/extensions/types.js +35 -0
  102. package/dist/core/extensions/types.js.map +1 -0
  103. package/dist/core/extensions/wrapper.d.ts +27 -0
  104. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  105. package/dist/core/extensions/wrapper.js +102 -0
  106. package/dist/core/extensions/wrapper.js.map +1 -0
  107. package/dist/core/footer-data-provider.d.ts +32 -0
  108. package/dist/core/footer-data-provider.d.ts.map +1 -0
  109. package/dist/core/footer-data-provider.js +134 -0
  110. package/dist/core/footer-data-provider.js.map +1 -0
  111. package/dist/core/index.d.ts +9 -0
  112. package/dist/core/index.d.ts.map +1 -0
  113. package/dist/core/index.js +9 -0
  114. package/dist/core/index.js.map +1 -0
  115. package/dist/core/keybindings.d.ts +55 -0
  116. package/dist/core/keybindings.d.ts.map +1 -0
  117. package/dist/core/keybindings.js +151 -0
  118. package/dist/core/keybindings.js.map +1 -0
  119. package/dist/core/messages.d.ts +77 -0
  120. package/dist/core/messages.d.ts.map +1 -0
  121. package/dist/core/messages.js +123 -0
  122. package/dist/core/messages.js.map +1 -0
  123. package/dist/core/model-registry.d.ts +114 -0
  124. package/dist/core/model-registry.d.ts.map +1 -0
  125. package/dist/core/model-registry.js +548 -0
  126. package/dist/core/model-registry.js.map +1 -0
  127. package/dist/core/model-resolver.d.ts +104 -0
  128. package/dist/core/model-resolver.d.ts.map +1 -0
  129. package/dist/core/model-resolver.js +462 -0
  130. package/dist/core/model-resolver.js.map +1 -0
  131. package/dist/core/package-manager.d.ts +156 -0
  132. package/dist/core/package-manager.d.ts.map +1 -0
  133. package/dist/core/package-manager.js +1442 -0
  134. package/dist/core/package-manager.js.map +1 -0
  135. package/dist/core/prompt-templates.d.ts +50 -0
  136. package/dist/core/prompt-templates.d.ts.map +1 -0
  137. package/dist/core/prompt-templates.js +251 -0
  138. package/dist/core/prompt-templates.js.map +1 -0
  139. package/dist/core/resolve-config-value.d.ts +17 -0
  140. package/dist/core/resolve-config-value.d.ts.map +1 -0
  141. package/dist/core/resolve-config-value.js +59 -0
  142. package/dist/core/resolve-config-value.js.map +1 -0
  143. package/dist/core/resource-loader.d.ts +184 -0
  144. package/dist/core/resource-loader.d.ts.map +1 -0
  145. package/dist/core/resource-loader.js +633 -0
  146. package/dist/core/resource-loader.js.map +1 -0
  147. package/dist/core/sdk.d.ts +90 -0
  148. package/dist/core/sdk.d.ts.map +1 -0
  149. package/dist/core/sdk.js +235 -0
  150. package/dist/core/sdk.js.map +1 -0
  151. package/dist/core/session-manager.d.ts +323 -0
  152. package/dist/core/session-manager.d.ts.map +1 -0
  153. package/dist/core/session-manager.js +1094 -0
  154. package/dist/core/session-manager.js.map +1 -0
  155. package/dist/core/settings-manager.d.ts +232 -0
  156. package/dist/core/settings-manager.d.ts.map +1 -0
  157. package/dist/core/settings-manager.js +682 -0
  158. package/dist/core/settings-manager.js.map +1 -0
  159. package/dist/core/skills.d.ts +58 -0
  160. package/dist/core/skills.d.ts.map +1 -0
  161. package/dist/core/skills.js +364 -0
  162. package/dist/core/skills.js.map +1 -0
  163. package/dist/core/slash-commands.d.ts +15 -0
  164. package/dist/core/slash-commands.d.ts.map +1 -0
  165. package/dist/core/slash-commands.js +22 -0
  166. package/dist/core/slash-commands.js.map +1 -0
  167. package/dist/core/system-prompt.d.ts +28 -0
  168. package/dist/core/system-prompt.d.ts.map +1 -0
  169. package/dist/core/system-prompt.js +159 -0
  170. package/dist/core/system-prompt.js.map +1 -0
  171. package/dist/core/timings.d.ts +7 -0
  172. package/dist/core/timings.d.ts.map +1 -0
  173. package/dist/core/timings.js +25 -0
  174. package/dist/core/timings.js.map +1 -0
  175. package/dist/core/tools/bash.d.ts +55 -0
  176. package/dist/core/tools/bash.d.ts.map +1 -0
  177. package/dist/core/tools/bash.js +242 -0
  178. package/dist/core/tools/bash.js.map +1 -0
  179. package/dist/core/tools/edit-diff.d.ts +63 -0
  180. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  181. package/dist/core/tools/edit-diff.js +243 -0
  182. package/dist/core/tools/edit-diff.js.map +1 -0
  183. package/dist/core/tools/edit.d.ts +39 -0
  184. package/dist/core/tools/edit.d.ts.map +1 -0
  185. package/dist/core/tools/edit.js +146 -0
  186. package/dist/core/tools/edit.js.map +1 -0
  187. package/dist/core/tools/find.d.ts +39 -0
  188. package/dist/core/tools/find.d.ts.map +1 -0
  189. package/dist/core/tools/find.js +206 -0
  190. package/dist/core/tools/find.js.map +1 -0
  191. package/dist/core/tools/grep.d.ts +45 -0
  192. package/dist/core/tools/grep.d.ts.map +1 -0
  193. package/dist/core/tools/grep.js +239 -0
  194. package/dist/core/tools/grep.js.map +1 -0
  195. package/dist/core/tools/index.d.ts +73 -0
  196. package/dist/core/tools/index.d.ts.map +1 -0
  197. package/dist/core/tools/index.js +61 -0
  198. package/dist/core/tools/index.js.map +1 -0
  199. package/dist/core/tools/ls.d.ts +40 -0
  200. package/dist/core/tools/ls.d.ts.map +1 -0
  201. package/dist/core/tools/ls.js +118 -0
  202. package/dist/core/tools/ls.js.map +1 -0
  203. package/dist/core/tools/path-utils.d.ts +8 -0
  204. package/dist/core/tools/path-utils.d.ts.map +1 -0
  205. package/dist/core/tools/path-utils.js +81 -0
  206. package/dist/core/tools/path-utils.js.map +1 -0
  207. package/dist/core/tools/read.d.ts +39 -0
  208. package/dist/core/tools/read.d.ts.map +1 -0
  209. package/dist/core/tools/read.js +166 -0
  210. package/dist/core/tools/read.js.map +1 -0
  211. package/dist/core/tools/truncate.d.ts +70 -0
  212. package/dist/core/tools/truncate.d.ts.map +1 -0
  213. package/dist/core/tools/truncate.js +205 -0
  214. package/dist/core/tools/truncate.js.map +1 -0
  215. package/dist/core/tools/write.d.ts +29 -0
  216. package/dist/core/tools/write.d.ts.map +1 -0
  217. package/dist/core/tools/write.js +78 -0
  218. package/dist/core/tools/write.js.map +1 -0
  219. package/dist/index.d.ts +27 -0
  220. package/dist/index.d.ts.map +1 -0
  221. package/dist/index.js +42 -0
  222. package/dist/index.js.map +1 -0
  223. package/dist/main.d.ts +8 -0
  224. package/dist/main.d.ts.map +1 -0
  225. package/dist/main.js +661 -0
  226. package/dist/main.js.map +1 -0
  227. package/dist/migrations.d.ts +33 -0
  228. package/dist/migrations.d.ts.map +1 -0
  229. package/dist/migrations.js +261 -0
  230. package/dist/migrations.js.map +1 -0
  231. package/dist/modes/index.d.ts +9 -0
  232. package/dist/modes/index.d.ts.map +1 -0
  233. package/dist/modes/index.js +8 -0
  234. package/dist/modes/index.js.map +1 -0
  235. package/dist/modes/interactive/components/armin.d.ts +34 -0
  236. package/dist/modes/interactive/components/armin.d.ts.map +1 -0
  237. package/dist/modes/interactive/components/armin.js +329 -0
  238. package/dist/modes/interactive/components/armin.js.map +1 -0
  239. package/dist/modes/interactive/components/assistant-message.d.ts +16 -0
  240. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  241. package/dist/modes/interactive/components/assistant-message.js +92 -0
  242. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  243. package/dist/modes/interactive/components/bash-execution.d.ts +35 -0
  244. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  245. package/dist/modes/interactive/components/bash-execution.js +156 -0
  246. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  247. package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  248. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  249. package/dist/modes/interactive/components/bordered-loader.js +48 -0
  250. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  251. package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  252. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  253. package/dist/modes/interactive/components/branch-summary-message.js +42 -0
  254. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  255. package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  256. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  257. package/dist/modes/interactive/components/compaction-summary-message.js +43 -0
  258. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  259. package/dist/modes/interactive/components/config-selector.d.ts +71 -0
  260. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  261. package/dist/modes/interactive/components/config-selector.js +470 -0
  262. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  263. package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  264. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  265. package/dist/modes/interactive/components/countdown-timer.js +28 -0
  266. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  267. package/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  268. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  269. package/dist/modes/interactive/components/custom-editor.js +63 -0
  270. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  271. package/dist/modes/interactive/components/custom-message.d.ts +20 -0
  272. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  273. package/dist/modes/interactive/components/custom-message.js +74 -0
  274. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  275. package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  276. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  277. package/dist/modes/interactive/components/daxnuts.js +138 -0
  278. package/dist/modes/interactive/components/daxnuts.js.map +1 -0
  279. package/dist/modes/interactive/components/diff.d.ts +12 -0
  280. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  281. package/dist/modes/interactive/components/diff.js +133 -0
  282. package/dist/modes/interactive/components/diff.js.map +1 -0
  283. package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  284. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  285. package/dist/modes/interactive/components/dynamic-border.js +20 -0
  286. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  287. package/dist/modes/interactive/components/extension-editor.d.ts +20 -0
  288. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  289. package/dist/modes/interactive/components/extension-editor.js +105 -0
  290. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  291. package/dist/modes/interactive/components/extension-input.d.ts +23 -0
  292. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  293. package/dist/modes/interactive/components/extension-input.js +55 -0
  294. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  295. package/dist/modes/interactive/components/extension-selector.d.ts +24 -0
  296. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  297. package/dist/modes/interactive/components/extension-selector.js +71 -0
  298. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  299. package/dist/modes/interactive/components/footer.d.ts +26 -0
  300. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  301. package/dist/modes/interactive/components/footer.js +196 -0
  302. package/dist/modes/interactive/components/footer.js.map +1 -0
  303. package/dist/modes/interactive/components/index.d.ts +32 -0
  304. package/dist/modes/interactive/components/index.d.ts.map +1 -0
  305. package/dist/modes/interactive/components/index.js +33 -0
  306. package/dist/modes/interactive/components/index.js.map +1 -0
  307. package/dist/modes/interactive/components/keybinding-hints.d.ts +41 -0
  308. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  309. package/dist/modes/interactive/components/keybinding-hints.js +61 -0
  310. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  311. package/dist/modes/interactive/components/login-dialog.d.ts +42 -0
  312. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  313. package/dist/modes/interactive/components/login-dialog.js +139 -0
  314. package/dist/modes/interactive/components/login-dialog.js.map +1 -0
  315. package/dist/modes/interactive/components/model-selector.d.ts +47 -0
  316. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  317. package/dist/modes/interactive/components/model-selector.js +259 -0
  318. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  319. package/dist/modes/interactive/components/oauth-selector.d.ts +19 -0
  320. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  321. package/dist/modes/interactive/components/oauth-selector.js +92 -0
  322. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  323. package/dist/modes/interactive/components/scoped-models-selector.d.ts +49 -0
  324. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  325. package/dist/modes/interactive/components/scoped-models-selector.js +271 -0
  326. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  327. package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  328. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  329. package/dist/modes/interactive/components/session-selector-search.js +155 -0
  330. package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  331. package/dist/modes/interactive/components/session-selector.d.ts +95 -0
  332. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  333. package/dist/modes/interactive/components/session-selector.js +825 -0
  334. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  335. package/dist/modes/interactive/components/settings-selector.d.ts +58 -0
  336. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  337. package/dist/modes/interactive/components/settings-selector.js +295 -0
  338. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  339. package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  340. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  341. package/dist/modes/interactive/components/show-images-selector.js +34 -0
  342. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  343. package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  344. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  345. package/dist/modes/interactive/components/skill-invocation-message.js +45 -0
  346. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  347. package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  348. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  349. package/dist/modes/interactive/components/theme-selector.js +44 -0
  350. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  351. package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  352. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  353. package/dist/modes/interactive/components/thinking-selector.js +46 -0
  354. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  355. package/dist/modes/interactive/components/tool-execution.d.ts +77 -0
  356. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  357. package/dist/modes/interactive/components/tool-execution.js +773 -0
  358. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  359. package/dist/modes/interactive/components/tree-selector.d.ts +70 -0
  360. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  361. package/dist/modes/interactive/components/tree-selector.js +921 -0
  362. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  363. package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  364. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  365. package/dist/modes/interactive/components/user-message-selector.js +110 -0
  366. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  367. package/dist/modes/interactive/components/user-message.d.ts +9 -0
  368. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  369. package/dist/modes/interactive/components/user-message.js +27 -0
  370. package/dist/modes/interactive/components/user-message.js.map +1 -0
  371. package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  372. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  373. package/dist/modes/interactive/components/visual-truncate.js +33 -0
  374. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  375. package/dist/modes/interactive/interactive-mode.d.ts +329 -0
  376. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  377. package/dist/modes/interactive/interactive-mode.js +3710 -0
  378. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  379. package/dist/modes/interactive/theme/theme.d.ts +78 -0
  380. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  381. package/dist/modes/interactive/theme/theme.js +944 -0
  382. package/dist/modes/interactive/theme/theme.js.map +1 -0
  383. package/dist/modes/print-mode.d.ts +28 -0
  384. package/dist/modes/print-mode.d.ts.map +1 -0
  385. package/dist/modes/print-mode.js +101 -0
  386. package/dist/modes/print-mode.js.map +1 -0
  387. package/dist/modes/rpc/rpc-client.d.ts +217 -0
  388. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  389. package/dist/modes/rpc/rpc-client.js +404 -0
  390. package/dist/modes/rpc/rpc-client.js.map +1 -0
  391. package/dist/modes/rpc/rpc-mode.d.ts +20 -0
  392. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  393. package/dist/modes/rpc/rpc-mode.js +511 -0
  394. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  395. package/dist/modes/rpc/rpc-types.d.ts +409 -0
  396. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  397. package/dist/modes/rpc/rpc-types.js +8 -0
  398. package/dist/modes/rpc/rpc-types.js.map +1 -0
  399. package/dist/utils/changelog.d.ts +21 -0
  400. package/dist/utils/changelog.d.ts.map +1 -0
  401. package/dist/utils/changelog.js +87 -0
  402. package/dist/utils/changelog.js.map +1 -0
  403. package/dist/utils/clipboard-image.d.ts +11 -0
  404. package/dist/utils/clipboard-image.d.ts.map +1 -0
  405. package/dist/utils/clipboard-image.js +162 -0
  406. package/dist/utils/clipboard-image.js.map +1 -0
  407. package/dist/utils/clipboard-native.d.ts +7 -0
  408. package/dist/utils/clipboard-native.d.ts.map +1 -0
  409. package/dist/utils/clipboard-native.js +14 -0
  410. package/dist/utils/clipboard-native.js.map +1 -0
  411. package/dist/utils/clipboard.d.ts +2 -0
  412. package/dist/utils/clipboard.d.ts.map +1 -0
  413. package/dist/utils/clipboard.js +67 -0
  414. package/dist/utils/clipboard.js.map +1 -0
  415. package/dist/utils/frontmatter.d.ts +8 -0
  416. package/dist/utils/frontmatter.d.ts.map +1 -0
  417. package/dist/utils/frontmatter.js +26 -0
  418. package/dist/utils/frontmatter.js.map +1 -0
  419. package/dist/utils/git.d.ts +26 -0
  420. package/dist/utils/git.d.ts.map +1 -0
  421. package/dist/utils/git.js +163 -0
  422. package/dist/utils/git.js.map +1 -0
  423. package/dist/utils/image-convert.d.ts +9 -0
  424. package/dist/utils/image-convert.d.ts.map +1 -0
  425. package/dist/utils/image-convert.js +35 -0
  426. package/dist/utils/image-convert.js.map +1 -0
  427. package/dist/utils/image-resize.d.ts +36 -0
  428. package/dist/utils/image-resize.d.ts.map +1 -0
  429. package/dist/utils/image-resize.js +181 -0
  430. package/dist/utils/image-resize.js.map +1 -0
  431. package/dist/utils/mime.d.ts +2 -0
  432. package/dist/utils/mime.d.ts.map +1 -0
  433. package/dist/utils/mime.js +26 -0
  434. package/dist/utils/mime.js.map +1 -0
  435. package/dist/utils/photon.d.ts +21 -0
  436. package/dist/utils/photon.d.ts.map +1 -0
  437. package/dist/utils/photon.js +121 -0
  438. package/dist/utils/photon.js.map +1 -0
  439. package/dist/utils/shell.d.ts +26 -0
  440. package/dist/utils/shell.d.ts.map +1 -0
  441. package/dist/utils/shell.js +186 -0
  442. package/dist/utils/shell.js.map +1 -0
  443. package/dist/utils/sleep.d.ts +5 -0
  444. package/dist/utils/sleep.d.ts.map +1 -0
  445. package/dist/utils/sleep.js +17 -0
  446. package/dist/utils/sleep.js.map +1 -0
  447. package/dist/utils/tools-manager.d.ts +3 -0
  448. package/dist/utils/tools-manager.d.ts.map +1 -0
  449. package/dist/utils/tools-manager.js +251 -0
  450. package/dist/utils/tools-manager.js.map +1 -0
  451. package/extensions/phi/README.md +228 -0
  452. package/extensions/phi/benchmark.ts +490 -0
  453. package/extensions/phi/init.ts +331 -0
  454. package/extensions/phi/memory.ts +285 -0
  455. package/extensions/phi/orchestrator.ts +411 -0
  456. package/extensions/phi/skill-loader.ts +336 -0
  457. package/extensions/phi/smart-router.ts +290 -0
  458. package/extensions/phi/web-search.ts +284 -0
  459. package/package.json +101 -0
@@ -0,0 +1,336 @@
1
+ /**
2
+ * Skill Loader Extension - Dynamic skill loading and context injection
3
+ *
4
+ * Automatically discovers and loads skills from ~/.phi/agent/skills/ and .phi/skills/
5
+ * directories. Skills are folders containing SKILL.md files with specialized knowledge
6
+ * or procedures. When skill-related keywords are detected in user input, the skill
7
+ * content is automatically injected into the conversation context.
8
+ *
9
+ * Features:
10
+ * - Automatic skill discovery at startup
11
+ * - Keyword-based skill detection and loading
12
+ * - /skills command to list available skills
13
+ * - Contextual skill injection via pi.sendHookMessage
14
+ *
15
+ * Usage:
16
+ * 1. Copy to packages/coding-agent/extensions/phi/skill-loader.ts
17
+ * 2. Create skill directories with SKILL.md files
18
+ * 3. Skills auto-load when relevant keywords are detected
19
+ */
20
+
21
+ import type { ExtensionAPI, ExtensionContext } from "phi-code";
22
+ import { readdir, readFile, access, stat } from "node:fs/promises";
23
+ import { join } from "node:path";
24
+ import { homedir } from "node:os";
25
+
26
+ interface Skill {
27
+ name: string;
28
+ path: string;
29
+ content: string;
30
+ keywords: string[];
31
+ description: string;
32
+ source: "global" | "local";
33
+ }
34
+
35
+ export default function skillLoaderExtension(pi: ExtensionAPI) {
36
+ let availableSkills: Skill[] = [];
37
+ const globalSkillsDir = join(homedir(), ".phi", "agent", "skills");
38
+ const localSkillsDir = join(process.cwd(), ".phi", "skills");
39
+
40
+ /**
41
+ * Extract keywords and description from SKILL.md content
42
+ */
43
+ function parseSkillContent(content: string): { keywords: string[]; description: string } {
44
+ const lines = content.split('\n');
45
+ const keywords: string[] = [];
46
+ let description = "";
47
+
48
+ // Look for keywords in frontmatter or explicit sections
49
+ let inFrontmatter = false;
50
+ let foundKeywords = false;
51
+
52
+ for (const line of lines) {
53
+ const trimmed = line.trim();
54
+
55
+ // YAML frontmatter
56
+ if (trimmed === '---') {
57
+ inFrontmatter = !inFrontmatter;
58
+ continue;
59
+ }
60
+
61
+ if (inFrontmatter) {
62
+ if (trimmed.startsWith('keywords:') || trimmed.startsWith('tags:')) {
63
+ const keywordLine = trimmed.split(':')[1];
64
+ if (keywordLine) {
65
+ // Parse YAML array or comma-separated
66
+ const parsed = keywordLine
67
+ .replace(/[\[\]]/g, '')
68
+ .split(',')
69
+ .map(k => k.trim().toLowerCase())
70
+ .filter(k => k.length > 0);
71
+ keywords.push(...parsed);
72
+ foundKeywords = true;
73
+ }
74
+ }
75
+ if (trimmed.startsWith('description:')) {
76
+ description = trimmed.split(':', 2)[1]?.trim() || "";
77
+ }
78
+ continue;
79
+ }
80
+
81
+ // Look for explicit keywords section
82
+ if (trimmed.toLowerCase().includes('keywords:') || trimmed.toLowerCase().includes('tags:')) {
83
+ const keywordText = trimmed.split(':')[1];
84
+ if (keywordText) {
85
+ const parsed = keywordText
86
+ .split(',')
87
+ .map(k => k.trim().toLowerCase())
88
+ .filter(k => k.length > 0);
89
+ keywords.push(...parsed);
90
+ foundKeywords = true;
91
+ }
92
+ continue;
93
+ }
94
+
95
+ // Use first heading as description if none found
96
+ if (!description && trimmed.startsWith('#')) {
97
+ description = trimmed.replace(/^#+\s*/, '').trim();
98
+ }
99
+ }
100
+
101
+ // If no explicit keywords, derive from content
102
+ if (!foundKeywords) {
103
+ const contentLower = content.toLowerCase();
104
+ const commonKeywords = [
105
+ 'docker', 'kubernetes', 'aws', 'azure', 'gcp', 'terraform',
106
+ 'python', 'javascript', 'typescript', 'react', 'node',
107
+ 'git', 'github', 'gitlab', 'ci/cd', 'devops',
108
+ 'database', 'postgresql', 'mysql', 'mongodb', 'redis',
109
+ 'api', 'rest', 'graphql', 'microservices',
110
+ 'security', 'auth', 'oauth', 'jwt',
111
+ 'test', 'testing', 'unit', 'integration',
112
+ 'deploy', 'deployment', 'production'
113
+ ];
114
+
115
+ for (const keyword of commonKeywords) {
116
+ if (contentLower.includes(keyword)) {
117
+ keywords.push(keyword);
118
+ }
119
+ }
120
+
121
+ // Also include skill directory name as keyword
122
+ const skillName = description.toLowerCase().replace(/\s+/g, '-');
123
+ if (skillName) keywords.push(skillName);
124
+ }
125
+
126
+ return { keywords, description };
127
+ }
128
+
129
+ /**
130
+ * Load skills from a directory
131
+ */
132
+ async function loadSkillsFromDirectory(directory: string, source: "global" | "local"): Promise<Skill[]> {
133
+ const skills: Skill[] = [];
134
+
135
+ try {
136
+ await access(directory);
137
+ const entries = await readdir(directory);
138
+
139
+ for (const entry of entries) {
140
+ const skillPath = join(directory, entry);
141
+
142
+ try {
143
+ const skillStat = await stat(skillPath);
144
+ if (!skillStat.isDirectory()) continue;
145
+
146
+ const skillFilePath = join(skillPath, "SKILL.md");
147
+
148
+ try {
149
+ await access(skillFilePath);
150
+ const content = await readFile(skillFilePath, 'utf-8');
151
+ const { keywords, description } = parseSkillContent(content);
152
+
153
+ skills.push({
154
+ name: entry,
155
+ path: skillPath,
156
+ content,
157
+ keywords,
158
+ description: description || entry,
159
+ source
160
+ });
161
+
162
+ } catch {
163
+ // No SKILL.md file, skip this directory
164
+ }
165
+ } catch {
166
+ // Can't access directory, skip
167
+ }
168
+ }
169
+ } catch {
170
+ // Directory doesn't exist, return empty array
171
+ }
172
+
173
+ return skills;
174
+ }
175
+
176
+ /**
177
+ * Load all available skills
178
+ */
179
+ async function loadAllSkills(): Promise<void> {
180
+ const globalSkills = await loadSkillsFromDirectory(globalSkillsDir, "global");
181
+ const localSkills = await loadSkillsFromDirectory(localSkillsDir, "local");
182
+
183
+ availableSkills = [...globalSkills, ...localSkills];
184
+
185
+ console.log(`Loaded ${availableSkills.length} skills (${globalSkills.length} global, ${localSkills.length} local)`);
186
+ }
187
+
188
+ /**
189
+ * Find relevant skills for input text
190
+ */
191
+ function findRelevantSkills(text: string): Skill[] {
192
+ const textLower = text.toLowerCase();
193
+ const relevantSkills: Array<{ skill: Skill; matchCount: number }> = [];
194
+
195
+ for (const skill of availableSkills) {
196
+ let matches = 0;
197
+
198
+ // Check for keyword matches
199
+ for (const keyword of skill.keywords) {
200
+ if (textLower.includes(keyword)) {
201
+ matches++;
202
+ }
203
+ }
204
+
205
+ // Check for skill name match
206
+ if (textLower.includes(skill.name.toLowerCase())) {
207
+ matches += 2; // Name match gets higher weight
208
+ }
209
+
210
+ if (matches > 0) {
211
+ relevantSkills.push({ skill, matchCount: matches });
212
+ }
213
+ }
214
+
215
+ // Sort by match count (most relevant first) and return top 3
216
+ return relevantSkills
217
+ .sort((a, b) => b.matchCount - a.matchCount)
218
+ .slice(0, 3)
219
+ .map(item => item.skill);
220
+ }
221
+
222
+ /**
223
+ * Input interceptor for skill detection
224
+ */
225
+ pi.on("input", async (event, ctx) => {
226
+ // Skip if this is an extension-generated message
227
+ if (event.source === "extension") {
228
+ return { action: "continue" };
229
+ }
230
+
231
+ // Find relevant skills
232
+ const relevantSkills = findRelevantSkills(event.text);
233
+
234
+ if (relevantSkills.length > 0) {
235
+ // Inject skill content into context
236
+ for (const skill of relevantSkills) {
237
+ const skillMessage = `Skill Context: ${skill.name}
238
+
239
+ ${skill.content}
240
+
241
+ ---
242
+ This skill was automatically loaded based on your request. Use this knowledge to assist with the task.`;
243
+
244
+ await pi.sendHookMessage({
245
+ role: "system",
246
+ content: skillMessage,
247
+ }, { source: "extension" });
248
+ }
249
+
250
+ // Notify user which skills were loaded
251
+ const skillNames = relevantSkills.map(s => s.name).join(", ");
252
+ ctx.ui.notify(`🧠 Loaded ${relevantSkills.length} skill(s): ${skillNames}`, "info");
253
+ }
254
+
255
+ return { action: "continue" };
256
+ });
257
+
258
+ /**
259
+ * /skills command - List available skills
260
+ */
261
+ pi.registerCommand("skills", {
262
+ description: "List available skills or show skill details",
263
+ getArgumentCompletions: (prefix) => {
264
+ const skillNames = availableSkills.map(s => s.name);
265
+ const filtered = skillNames.filter(name => name.toLowerCase().startsWith(prefix.toLowerCase()));
266
+ return filtered.length > 0 ? filtered.map(name => ({ value: name, label: name })) : null;
267
+ },
268
+ handler: async (args, ctx) => {
269
+ const skillName = args.trim();
270
+
271
+ if (!skillName) {
272
+ // List all skills
273
+ if (availableSkills.length === 0) {
274
+ ctx.ui.notify("No skills found. Create skill directories with SKILL.md files in:\n- ~/.phi/agent/skills/\n- .phi/skills/", "info");
275
+ return;
276
+ }
277
+
278
+ let message = `🧠 **Available Skills** (${availableSkills.length})\n\n`;
279
+
280
+ // Group by source
281
+ const globalSkills = availableSkills.filter(s => s.source === "global");
282
+ const localSkills = availableSkills.filter(s => s.source === "local");
283
+
284
+ if (globalSkills.length > 0) {
285
+ message += "**Global Skills:**\n";
286
+ globalSkills.forEach(skill => {
287
+ const keywords = skill.keywords.slice(0, 3).join(", ");
288
+ message += `- **${skill.name}** - ${skill.description}\n`;
289
+ message += ` Keywords: ${keywords}\n\n`;
290
+ });
291
+ }
292
+
293
+ if (localSkills.length > 0) {
294
+ message += "**Project Skills:**\n";
295
+ localSkills.forEach(skill => {
296
+ const keywords = skill.keywords.slice(0, 3).join(", ");
297
+ message += `- **${skill.name}** - ${skill.description}\n`;
298
+ message += ` Keywords: ${keywords}\n\n`;
299
+ });
300
+ }
301
+
302
+ message += "\nUse `/skills <name>` to view a specific skill.";
303
+
304
+ ctx.ui.notify(message, "info");
305
+
306
+ } else {
307
+ // Show specific skill
308
+ const skill = availableSkills.find(s => s.name.toLowerCase() === skillName.toLowerCase());
309
+
310
+ if (!skill) {
311
+ ctx.ui.notify(`Skill "${skillName}" not found. Use /skills to list available skills.`, "warning");
312
+ return;
313
+ }
314
+
315
+ const message = `🧠 **Skill: ${skill.name}**
316
+
317
+ **Description:** ${skill.description}
318
+ **Source:** ${skill.source}
319
+ **Path:** ${skill.path}
320
+ **Keywords:** ${skill.keywords.join(", ")}
321
+
322
+ **Content Preview:**
323
+ ${skill.content.slice(0, 500)}${skill.content.length > 500 ? "..." : ""}`;
324
+
325
+ ctx.ui.notify(message, "info");
326
+ }
327
+ },
328
+ });
329
+
330
+ /**
331
+ * Load skills on session start
332
+ */
333
+ pi.on("session_start", async (_event, _ctx) => {
334
+ await loadAllSkills();
335
+ });
336
+ }
@@ -0,0 +1,290 @@
1
+ /**
2
+ * Smart Router Extension - Intelligent model routing for different task types
3
+ *
4
+ * Analyzes user input to suggest the most appropriate model for the task:
5
+ * - Code tasks (implement, create, refactor, build) → coder model
6
+ * - Debug tasks (fix, bug, error, debug) → reasoning model
7
+ * - Exploration tasks (read, analyze, explain, understand) → fast model
8
+ * - Planning tasks (plan, design, architect, spec) → reasoning model
9
+ *
10
+ * Reads configuration from ~/.phi/agent/routing.json if available.
11
+ * Currently only notifies user of recommendations - automatic switching to be added later.
12
+ *
13
+ * Features:
14
+ * - Input analysis and model recommendations
15
+ * - Configurable routing rules
16
+ * - User notifications via ctx.ui.notify
17
+ *
18
+ * Usage:
19
+ * 1. Copy to packages/coding-agent/extensions/phi/smart-router.ts
20
+ * 2. Optionally configure via ~/.phi/agent/routing.json
21
+ */
22
+
23
+ import type { ExtensionAPI } from "phi-code";
24
+ import { readFile, mkdir, writeFile, access } from "node:fs/promises";
25
+ import { join } from "node:path";
26
+ import { homedir } from "node:os";
27
+
28
+ interface RoutingConfig {
29
+ patterns: {
30
+ code: string[];
31
+ debug: string[];
32
+ exploration: string[];
33
+ planning: string[];
34
+ };
35
+ models: {
36
+ coder: string;
37
+ reasoning: string;
38
+ fast: string;
39
+ };
40
+ enabled: boolean;
41
+ notifyOnRecommendation: boolean;
42
+ }
43
+
44
+ const DEFAULT_CONFIG: RoutingConfig = {
45
+ patterns: {
46
+ code: ["implement", "create", "build", "refactor", "code", "write", "develop", "generate"],
47
+ debug: ["fix", "bug", "error", "debug", "troubleshoot", "repair", "solve", "issue"],
48
+ exploration: ["read", "analyze", "explain", "understand", "explore", "examine", "review", "what is"],
49
+ planning: ["plan", "design", "architect", "spec", "strategy", "approach", "organize", "structure"]
50
+ },
51
+ models: {
52
+ coder: "anthropic/claude-sonnet-3.5",
53
+ reasoning: "anthropic/claude-opus",
54
+ fast: "anthropic/claude-haiku"
55
+ },
56
+ enabled: true,
57
+ notifyOnRecommendation: true
58
+ };
59
+
60
+ export default function smartRouterExtension(pi: ExtensionAPI) {
61
+ let config: RoutingConfig = DEFAULT_CONFIG;
62
+ const configDir = join(homedir(), ".phi", "agent");
63
+ const configPath = join(configDir, "routing.json");
64
+
65
+ /**
66
+ * Load routing configuration
67
+ */
68
+ async function loadConfig() {
69
+ try {
70
+ await access(configPath);
71
+ const configText = await readFile(configPath, 'utf-8');
72
+ const userConfig = JSON.parse(configText) as Partial<RoutingConfig>;
73
+
74
+ // Merge with defaults
75
+ config = {
76
+ ...DEFAULT_CONFIG,
77
+ ...userConfig,
78
+ patterns: { ...DEFAULT_CONFIG.patterns, ...userConfig.patterns },
79
+ models: { ...DEFAULT_CONFIG.models, ...userConfig.models }
80
+ };
81
+ } catch (error) {
82
+ // Config doesn't exist or is invalid, use defaults
83
+ console.log("Using default routing configuration");
84
+ await saveDefaultConfig();
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Save default configuration file
90
+ */
91
+ async function saveDefaultConfig() {
92
+ try {
93
+ await mkdir(configDir, { recursive: true });
94
+ await writeFile(configPath, JSON.stringify(DEFAULT_CONFIG, null, 2), 'utf-8');
95
+ console.log(`Created default routing config at ${configPath}`);
96
+ } catch (error) {
97
+ console.warn("Failed to save default routing config:", error);
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Analyze input text to determine task type
103
+ */
104
+ function analyzeTaskType(text: string): { type: keyof RoutingConfig['patterns'] | null; confidence: number; matches: string[] } {
105
+ const normalizedText = text.toLowerCase();
106
+ const results: Array<{ type: keyof RoutingConfig['patterns']; confidence: number; matches: string[] }> = [];
107
+
108
+ // Check each pattern category
109
+ for (const [category, patterns] of Object.entries(config.patterns)) {
110
+ const matches: string[] = [];
111
+ let matchCount = 0;
112
+
113
+ for (const pattern of patterns) {
114
+ if (normalizedText.includes(pattern.toLowerCase())) {
115
+ matches.push(pattern);
116
+ matchCount++;
117
+ }
118
+ }
119
+
120
+ if (matchCount > 0) {
121
+ // Calculate confidence based on match count and pattern length
122
+ const confidence = (matchCount / patterns.length) * 100;
123
+ results.push({
124
+ type: category as keyof RoutingConfig['patterns'],
125
+ confidence,
126
+ matches
127
+ });
128
+ }
129
+ }
130
+
131
+ // Return the highest confidence match
132
+ if (results.length === 0) {
133
+ return { type: null, confidence: 0, matches: [] };
134
+ }
135
+
136
+ results.sort((a, b) => b.confidence - a.confidence);
137
+ return results[0];
138
+ }
139
+
140
+ /**
141
+ * Get recommended model for task type
142
+ */
143
+ function getRecommendedModel(taskType: keyof RoutingConfig['patterns'] | null): string | null {
144
+ if (!taskType) return null;
145
+
146
+ switch (taskType) {
147
+ case 'code':
148
+ return config.models.coder;
149
+ case 'debug':
150
+ case 'planning':
151
+ return config.models.reasoning;
152
+ case 'exploration':
153
+ return config.models.fast;
154
+ default:
155
+ return null;
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Get task type description
161
+ */
162
+ function getTaskDescription(taskType: keyof RoutingConfig['patterns'] | null): string {
163
+ switch (taskType) {
164
+ case 'code':
165
+ return 'Code Implementation';
166
+ case 'debug':
167
+ return 'Debugging & Problem Solving';
168
+ case 'exploration':
169
+ return 'Analysis & Understanding';
170
+ case 'planning':
171
+ return 'Planning & Design';
172
+ default:
173
+ return 'General Task';
174
+ }
175
+ }
176
+
177
+ /**
178
+ * Input interceptor for smart routing
179
+ */
180
+ pi.on("input", async (event, ctx) => {
181
+ // Skip if routing is disabled or this is an extension-generated message
182
+ if (!config.enabled || event.source === "extension") {
183
+ return { action: "continue" };
184
+ }
185
+
186
+ // Analyze the input
187
+ const analysis = analyzeTaskType(event.text);
188
+
189
+ // Only recommend if we have good confidence (>= 30%)
190
+ if (analysis.type && analysis.confidence >= 30) {
191
+ const recommendedModel = getRecommendedModel(analysis.type);
192
+ const taskDescription = getTaskDescription(analysis.type);
193
+
194
+ if (recommendedModel && config.notifyOnRecommendation) {
195
+ const message = `💡 Detected: ${taskDescription} (${analysis.confidence.toFixed(0)}% confidence)
196
+ Recommended model: ${recommendedModel}
197
+ Matched patterns: ${analysis.matches.join(", ")}`;
198
+
199
+ ctx.ui.notify(message, "info");
200
+ }
201
+ }
202
+
203
+ return { action: "continue" };
204
+ });
205
+
206
+ /**
207
+ * Register routing configuration command
208
+ */
209
+ pi.registerCommand("routing", {
210
+ description: "Show or configure smart routing settings",
211
+ handler: async (args, ctx) => {
212
+ if (!args.trim()) {
213
+ // Show current configuration
214
+ const statusMessage = `Smart Router Configuration:
215
+
216
+ **Status:** ${config.enabled ? "Enabled" : "Disabled"}
217
+ **Notifications:** ${config.notifyOnRecommendation ? "Enabled" : "Disabled"}
218
+
219
+ **Model Assignments:**
220
+ - Code tasks: ${config.models.coder}
221
+ - Debug tasks: ${config.models.reasoning}
222
+ - Exploration: ${config.models.fast}
223
+ - Planning: ${config.models.reasoning}
224
+
225
+ **Pattern Matching:**
226
+ - Code: ${config.patterns.code.join(", ")}
227
+ - Debug: ${config.patterns.debug.join(", ")}
228
+ - Exploration: ${config.patterns.exploration.join(", ")}
229
+ - Planning: ${config.patterns.planning.join(", ")}
230
+
231
+ Config file: ${configPath}`;
232
+
233
+ ctx.ui.notify(statusMessage, "info");
234
+ return;
235
+ }
236
+
237
+ const arg = args.trim().toLowerCase();
238
+
239
+ switch (arg) {
240
+ case "enable":
241
+ config.enabled = true;
242
+ ctx.ui.notify("Smart routing enabled", "info");
243
+ break;
244
+ case "disable":
245
+ config.enabled = false;
246
+ ctx.ui.notify("Smart routing disabled", "info");
247
+ break;
248
+ case "notify-on":
249
+ config.notifyOnRecommendation = true;
250
+ ctx.ui.notify("Routing notifications enabled", "info");
251
+ break;
252
+ case "notify-off":
253
+ config.notifyOnRecommendation = false;
254
+ ctx.ui.notify("Routing notifications disabled", "info");
255
+ break;
256
+ case "reload":
257
+ await loadConfig();
258
+ ctx.ui.notify("Routing configuration reloaded", "info");
259
+ break;
260
+ case "test":
261
+ // Test mode - show what would be recommended for different inputs
262
+ const testInputs = [
263
+ "implement a new feature",
264
+ "fix this bug",
265
+ "explain how this works",
266
+ "plan the system architecture"
267
+ ];
268
+
269
+ let testResults = "**Routing Test Results:**\n\n";
270
+ for (const input of testInputs) {
271
+ const analysis = analyzeTaskType(input);
272
+ const model = getRecommendedModel(analysis.type);
273
+ testResults += `"${input}" → ${analysis.type || 'none'} (${analysis.confidence.toFixed(0)}%) → ${model || 'default'}\n`;
274
+ }
275
+
276
+ ctx.ui.notify(testResults, "info");
277
+ break;
278
+ default:
279
+ ctx.ui.notify("Usage: /routing [enable|disable|notify-on|notify-off|reload|test]", "warning");
280
+ }
281
+ },
282
+ });
283
+
284
+ /**
285
+ * Load configuration on session start
286
+ */
287
+ pi.on("session_start", async (_event, _ctx) => {
288
+ await loadConfig();
289
+ });
290
+ }