@sheason/pi-coding-agent 0.74.1-sheason.0 → 0.78.0-sheason.0.6.0-alpha.2

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 (516) hide show
  1. package/CHANGELOG.md +256 -4
  2. package/README.md +16 -8
  3. package/dist/bun/cli.d.ts.map +1 -1
  4. package/dist/bun/cli.js.map +1 -1
  5. package/dist/cli/args.d.ts +7 -2
  6. package/dist/cli/args.d.ts.map +1 -1
  7. package/dist/cli/args.js +49 -1
  8. package/dist/cli/args.js.map +1 -1
  9. package/dist/cli/config-selector.d.ts +2 -2
  10. package/dist/cli/config-selector.d.ts.map +1 -1
  11. package/dist/cli/config-selector.js +1 -1
  12. package/dist/cli/config-selector.js.map +1 -1
  13. package/dist/cli/file-processor.d.ts.map +1 -1
  14. package/dist/cli/file-processor.js +2 -3
  15. package/dist/cli/file-processor.js.map +1 -1
  16. package/dist/cli/initial-message.d.ts +1 -1
  17. package/dist/cli/initial-message.d.ts.map +1 -1
  18. package/dist/cli/initial-message.js.map +1 -1
  19. package/dist/cli/list-models.d.ts +1 -1
  20. package/dist/cli/list-models.d.ts.map +1 -1
  21. package/dist/cli/list-models.js.map +1 -1
  22. package/dist/cli/session-picker.d.ts +1 -1
  23. package/dist/cli/session-picker.d.ts.map +1 -1
  24. package/dist/cli/session-picker.js.map +1 -1
  25. package/dist/cli.d.ts.map +1 -1
  26. package/dist/cli.js +4 -6
  27. package/dist/cli.js.map +1 -1
  28. package/dist/config.d.ts.map +1 -1
  29. package/dist/config.js +61 -32
  30. package/dist/config.js.map +1 -1
  31. package/dist/core/agent-session-proxy.d.ts +268 -0
  32. package/dist/core/agent-session-proxy.d.ts.map +1 -0
  33. package/dist/core/agent-session-proxy.js +2 -0
  34. package/dist/core/agent-session-proxy.js.map +1 -0
  35. package/dist/core/agent-session-runtime.d.ts +10 -10
  36. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  37. package/dist/core/agent-session-runtime.js +14 -14
  38. package/dist/core/agent-session-runtime.js.map +1 -1
  39. package/dist/core/agent-session-services.d.ts +8 -7
  40. package/dist/core/agent-session-services.d.ts.map +1 -1
  41. package/dist/core/agent-session-services.js +4 -2
  42. package/dist/core/agent-session-services.js.map +1 -1
  43. package/dist/core/agent-session.d.ts +60 -27
  44. package/dist/core/agent-session.d.ts.map +1 -1
  45. package/dist/core/agent-session.js +303 -177
  46. package/dist/core/agent-session.js.map +1 -1
  47. package/dist/core/auth-guidance.d.ts.map +1 -1
  48. package/dist/core/auth-guidance.js.map +1 -1
  49. package/dist/core/auth-storage.d.ts +1 -1
  50. package/dist/core/auth-storage.d.ts.map +1 -1
  51. package/dist/core/auth-storage.js +3 -2
  52. package/dist/core/auth-storage.js.map +1 -1
  53. package/dist/core/bash-executor.d.ts +1 -1
  54. package/dist/core/bash-executor.d.ts.map +1 -1
  55. package/dist/core/bash-executor.js.map +1 -1
  56. package/dist/core/compaction/branch-summarization.d.ts +3 -3
  57. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  58. package/dist/core/compaction/branch-summarization.js.map +1 -1
  59. package/dist/core/compaction/compaction.d.ts +5 -5
  60. package/dist/core/compaction/compaction.d.ts.map +1 -1
  61. package/dist/core/compaction/compaction.js +41 -37
  62. package/dist/core/compaction/compaction.js.map +1 -1
  63. package/dist/core/compaction/index.d.ts +3 -3
  64. package/dist/core/compaction/index.d.ts.map +1 -1
  65. package/dist/core/compaction/index.js.map +1 -1
  66. package/dist/core/exec.d.ts.map +1 -1
  67. package/dist/core/exec.js.map +1 -1
  68. package/dist/core/export-html/index.d.ts +1 -1
  69. package/dist/core/export-html/index.d.ts.map +1 -1
  70. package/dist/core/export-html/index.js +8 -6
  71. package/dist/core/export-html/index.js.map +1 -1
  72. package/dist/core/export-html/template.js +23 -6
  73. package/dist/core/export-html/tool-renderer.d.ts +2 -2
  74. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  75. package/dist/core/export-html/tool-renderer.js.map +1 -1
  76. package/dist/core/extensions/index.d.ts +8 -8
  77. package/dist/core/extensions/index.d.ts.map +1 -1
  78. package/dist/core/extensions/index.js.map +1 -1
  79. package/dist/core/extensions/loader.d.ts +2 -2
  80. package/dist/core/extensions/loader.d.ts.map +1 -1
  81. package/dist/core/extensions/loader.js +17 -34
  82. package/dist/core/extensions/loader.js.map +1 -1
  83. package/dist/core/extensions/runner.d.ts +12 -7
  84. package/dist/core/extensions/runner.d.ts.map +1 -1
  85. package/dist/core/extensions/runner.js +36 -2
  86. package/dist/core/extensions/runner.js.map +1 -1
  87. package/dist/core/extensions/types.d.ts +26 -24
  88. package/dist/core/extensions/types.d.ts.map +1 -1
  89. package/dist/core/extensions/types.js.map +1 -1
  90. package/dist/core/extensions/wrapper.d.ts +2 -2
  91. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  92. package/dist/core/extensions/wrapper.js.map +1 -1
  93. package/dist/core/footer-data-provider.d.ts +3 -1
  94. package/dist/core/footer-data-provider.d.ts.map +1 -1
  95. package/dist/core/footer-data-provider.js +4 -0
  96. package/dist/core/footer-data-provider.js.map +1 -1
  97. package/dist/core/http-dispatcher.d.ts +21 -0
  98. package/dist/core/http-dispatcher.d.ts.map +1 -0
  99. package/dist/core/http-dispatcher.js +48 -0
  100. package/dist/core/http-dispatcher.js.map +1 -0
  101. package/dist/core/index.d.ts +8 -8
  102. package/dist/core/index.d.ts.map +1 -1
  103. package/dist/core/index.js.map +1 -1
  104. package/dist/core/keybindings.d.ts.map +1 -1
  105. package/dist/core/keybindings.js.map +1 -1
  106. package/dist/core/local-agent-session-proxy.d.ts +82 -0
  107. package/dist/core/local-agent-session-proxy.d.ts.map +1 -0
  108. package/dist/core/local-agent-session-proxy.js +531 -0
  109. package/dist/core/local-agent-session-proxy.js.map +1 -0
  110. package/dist/core/messages.d.ts +0 -9
  111. package/dist/core/messages.d.ts.map +1 -1
  112. package/dist/core/messages.js +0 -10
  113. package/dist/core/messages.js.map +1 -1
  114. package/dist/core/model-registry.d.ts +4 -4
  115. package/dist/core/model-registry.d.ts.map +1 -1
  116. package/dist/core/model-registry.js +72 -16
  117. package/dist/core/model-registry.js.map +1 -1
  118. package/dist/core/model-resolver.d.ts +1 -1
  119. package/dist/core/model-resolver.d.ts.map +1 -1
  120. package/dist/core/model-resolver.js +1 -1
  121. package/dist/core/model-resolver.js.map +1 -1
  122. package/dist/core/output-guard.d.ts +1 -0
  123. package/dist/core/output-guard.d.ts.map +1 -1
  124. package/dist/core/output-guard.js +52 -22
  125. package/dist/core/output-guard.js.map +1 -1
  126. package/dist/core/package-manager.d.ts +7 -1
  127. package/dist/core/package-manager.d.ts.map +1 -1
  128. package/dist/core/package-manager.js +129 -64
  129. package/dist/core/package-manager.js.map +1 -1
  130. package/dist/core/prompt-templates.d.ts +1 -1
  131. package/dist/core/prompt-templates.d.ts.map +1 -1
  132. package/dist/core/prompt-templates.js +12 -24
  133. package/dist/core/prompt-templates.js.map +1 -1
  134. package/dist/core/provider-display-names.d.ts.map +1 -1
  135. package/dist/core/provider-display-names.js +0 -1
  136. package/dist/core/provider-display-names.js.map +1 -1
  137. package/dist/core/resolve-config-value.d.ts +9 -1
  138. package/dist/core/resolve-config-value.d.ts.map +1 -1
  139. package/dist/core/resolve-config-value.js +134 -11
  140. package/dist/core/resolve-config-value.js.map +1 -1
  141. package/dist/core/resource-loader.d.ts +13 -10
  142. package/dist/core/resource-loader.d.ts.map +1 -1
  143. package/dist/core/resource-loader.js +41 -33
  144. package/dist/core/resource-loader.js.map +1 -1
  145. package/dist/core/sdk.d.ts +15 -13
  146. package/dist/core/sdk.d.ts.map +1 -1
  147. package/dist/core/sdk.js +24 -17
  148. package/dist/core/sdk.js.map +1 -1
  149. package/dist/core/session-manager.d.ts +20 -10
  150. package/dist/core/session-manager.d.ts.map +1 -1
  151. package/dist/core/session-manager.js +201 -106
  152. package/dist/core/session-manager.js.map +1 -1
  153. package/dist/core/settings-manager.d.ts +5 -0
  154. package/dist/core/settings-manager.d.ts.map +1 -1
  155. package/dist/core/settings-manager.js +31 -13
  156. package/dist/core/settings-manager.js.map +1 -1
  157. package/dist/core/skills.d.ts +2 -2
  158. package/dist/core/skills.d.ts.map +1 -1
  159. package/dist/core/skills.js +10 -27
  160. package/dist/core/skills.js.map +1 -1
  161. package/dist/core/slash-commands.d.ts +1 -1
  162. package/dist/core/slash-commands.d.ts.map +1 -1
  163. package/dist/core/slash-commands.js.map +1 -1
  164. package/dist/core/source-info.d.ts +1 -1
  165. package/dist/core/source-info.d.ts.map +1 -1
  166. package/dist/core/source-info.js.map +1 -1
  167. package/dist/core/system-prompt.d.ts +1 -1
  168. package/dist/core/system-prompt.d.ts.map +1 -1
  169. package/dist/core/system-prompt.js +16 -9
  170. package/dist/core/system-prompt.js.map +1 -1
  171. package/dist/core/telemetry.d.ts +1 -1
  172. package/dist/core/telemetry.d.ts.map +1 -1
  173. package/dist/core/telemetry.js.map +1 -1
  174. package/dist/core/tools/bash.d.ts +2 -2
  175. package/dist/core/tools/bash.d.ts.map +1 -1
  176. package/dist/core/tools/bash.js +55 -54
  177. package/dist/core/tools/bash.js.map +1 -1
  178. package/dist/core/tools/edit-diff.d.ts +3 -1
  179. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  180. package/dist/core/tools/edit-diff.js +8 -1
  181. package/dist/core/tools/edit-diff.js.map +1 -1
  182. package/dist/core/tools/edit.d.ts +5 -3
  183. package/dist/core/tools/edit.d.ts.map +1 -1
  184. package/dist/core/tools/edit.js +51 -91
  185. package/dist/core/tools/edit.js.map +1 -1
  186. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  187. package/dist/core/tools/file-mutation-queue.js +27 -12
  188. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  189. package/dist/core/tools/find.d.ts +2 -2
  190. package/dist/core/tools/find.d.ts.map +1 -1
  191. package/dist/core/tools/find.js +2 -3
  192. package/dist/core/tools/find.js.map +1 -1
  193. package/dist/core/tools/grep.d.ts +2 -2
  194. package/dist/core/tools/grep.d.ts.map +1 -1
  195. package/dist/core/tools/grep.js +3 -3
  196. package/dist/core/tools/grep.js.map +1 -1
  197. package/dist/core/tools/index.d.ts +17 -17
  198. package/dist/core/tools/index.d.ts.map +1 -1
  199. package/dist/core/tools/index.js.map +1 -1
  200. package/dist/core/tools/ls.d.ts +2 -2
  201. package/dist/core/tools/ls.d.ts.map +1 -1
  202. package/dist/core/tools/ls.js +10 -12
  203. package/dist/core/tools/ls.js.map +1 -1
  204. package/dist/core/tools/output-accumulator.d.ts +3 -1
  205. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  206. package/dist/core/tools/output-accumulator.js +9 -3
  207. package/dist/core/tools/output-accumulator.js.map +1 -1
  208. package/dist/core/tools/path-utils.d.ts +2 -0
  209. package/dist/core/tools/path-utils.d.ts.map +1 -1
  210. package/dist/core/tools/path-utils.js +39 -21
  211. package/dist/core/tools/path-utils.js.map +1 -1
  212. package/dist/core/tools/read.d.ts +2 -2
  213. package/dist/core/tools/read.d.ts.map +1 -1
  214. package/dist/core/tools/read.js +15 -15
  215. package/dist/core/tools/read.js.map +1 -1
  216. package/dist/core/tools/render-utils.d.ts +5 -2
  217. package/dist/core/tools/render-utils.d.ts.map +1 -1
  218. package/dist/core/tools/render-utils.js +17 -1
  219. package/dist/core/tools/render-utils.js.map +1 -1
  220. package/dist/core/tools/tool-definition-wrapper.d.ts +1 -1
  221. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  222. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  223. package/dist/core/tools/truncate.d.ts.map +1 -1
  224. package/dist/core/tools/truncate.js +12 -2
  225. package/dist/core/tools/truncate.js.map +1 -1
  226. package/dist/core/tools/write.d.ts +1 -1
  227. package/dist/core/tools/write.d.ts.map +1 -1
  228. package/dist/core/tools/write.js +25 -41
  229. package/dist/core/tools/write.js.map +1 -1
  230. package/dist/d-pi-worker.d.ts +12 -0
  231. package/dist/d-pi-worker.d.ts.map +1 -0
  232. package/dist/d-pi-worker.js +9 -0
  233. package/dist/d-pi-worker.js.map +1 -0
  234. package/dist/index.d.ts +30 -28
  235. package/dist/index.d.ts.map +1 -1
  236. package/dist/index.js +5 -3
  237. package/dist/index.js.map +1 -1
  238. package/dist/main.d.ts +1 -1
  239. package/dist/main.d.ts.map +1 -1
  240. package/dist/main.js +100 -39
  241. package/dist/main.js.map +1 -1
  242. package/dist/migrations.d.ts.map +1 -1
  243. package/dist/migrations.js +118 -1
  244. package/dist/migrations.js.map +1 -1
  245. package/dist/modes/connect/auth-headers.d.ts +2 -0
  246. package/dist/modes/connect/auth-headers.d.ts.map +1 -0
  247. package/dist/modes/connect/auth-headers.js +2 -0
  248. package/dist/modes/connect/auth-headers.js.map +1 -0
  249. package/dist/modes/connect/client-extension-sync.d.ts +13 -0
  250. package/dist/modes/connect/client-extension-sync.d.ts.map +1 -0
  251. package/dist/modes/connect/client-extension-sync.js +51 -0
  252. package/dist/modes/connect/client-extension-sync.js.map +1 -0
  253. package/dist/modes/connect/connect-mode.d.ts +6 -0
  254. package/dist/modes/connect/connect-mode.d.ts.map +1 -0
  255. package/dist/modes/connect/connect-mode.js +29 -0
  256. package/dist/modes/connect/connect-mode.js.map +1 -0
  257. package/dist/modes/connect/remote-agent-session-proxy.d.ts +81 -0
  258. package/dist/modes/connect/remote-agent-session-proxy.d.ts.map +1 -0
  259. package/dist/modes/connect/remote-agent-session-proxy.js +326 -0
  260. package/dist/modes/connect/remote-agent-session-proxy.js.map +1 -0
  261. package/dist/modes/connect/sse-client.d.ts +18 -0
  262. package/dist/modes/connect/sse-client.d.ts.map +1 -0
  263. package/dist/modes/connect/sse-client.js +90 -0
  264. package/dist/modes/connect/sse-client.js.map +1 -0
  265. package/dist/modes/index.d.ts +5 -5
  266. package/dist/modes/index.d.ts.map +1 -1
  267. package/dist/modes/index.js.map +1 -1
  268. package/dist/modes/interactive/components/armin.d.ts.map +1 -1
  269. package/dist/modes/interactive/components/armin.js.map +1 -1
  270. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  271. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  272. package/dist/modes/interactive/components/bash-execution.d.ts +1 -1
  273. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  274. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  275. package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
  276. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  277. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  278. package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
  279. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  280. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  281. package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
  282. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  283. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  284. package/dist/modes/interactive/components/config-selector.d.ts +4 -4
  285. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  286. package/dist/modes/interactive/components/config-selector.js +8 -5
  287. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  288. package/dist/modes/interactive/components/countdown-timer.d.ts +2 -2
  289. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  290. package/dist/modes/interactive/components/countdown-timer.js +2 -2
  291. package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  292. package/dist/modes/interactive/components/custom-editor.d.ts +1 -1
  293. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  294. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  295. package/dist/modes/interactive/components/custom-message.d.ts +2 -2
  296. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  297. package/dist/modes/interactive/components/custom-message.js +0 -1
  298. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  299. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  300. package/dist/modes/interactive/components/daxnuts.js.map +1 -1
  301. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  302. package/dist/modes/interactive/components/diff.js.map +1 -1
  303. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  304. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  305. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
  306. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
  307. package/dist/modes/interactive/components/extension-editor.d.ts +1 -1
  308. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  309. package/dist/modes/interactive/components/extension-editor.js +14 -6
  310. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  311. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  312. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  313. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  314. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  315. package/dist/modes/interactive/components/footer.d.ts +15 -4
  316. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  317. package/dist/modes/interactive/components/footer.js +126 -8
  318. package/dist/modes/interactive/components/footer.js.map +1 -1
  319. package/dist/modes/interactive/components/index.d.ts +31 -31
  320. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  321. package/dist/modes/interactive/components/index.js.map +1 -1
  322. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  323. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  324. package/dist/modes/interactive/components/login-dialog.d.ts +7 -1
  325. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  326. package/dist/modes/interactive/components/login-dialog.js +28 -5
  327. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  328. package/dist/modes/interactive/components/model-selector.d.ts +2 -2
  329. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  330. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  331. package/dist/modes/interactive/components/oauth-selector.d.ts +1 -1
  332. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  333. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  334. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  335. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  336. package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
  337. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  338. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  339. package/dist/modes/interactive/components/session-selector.d.ts +3 -3
  340. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  341. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  342. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  343. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  344. package/dist/modes/interactive/components/settings-selector.js +15 -0
  345. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  346. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  347. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  348. package/dist/modes/interactive/components/skill-invocation-message.d.ts +1 -1
  349. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  350. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  351. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  352. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  353. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  354. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  355. package/dist/modes/interactive/components/tool-execution.d.ts +1 -1
  356. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  357. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  358. package/dist/modes/interactive/components/tree-selector.d.ts +1 -1
  359. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  360. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  361. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  362. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  363. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  364. package/dist/modes/interactive/components/user-message.js.map +1 -1
  365. package/dist/modes/interactive/interactive-mode.d.ts +53 -7
  366. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  367. package/dist/modes/interactive/interactive-mode.js +1247 -205
  368. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  369. package/dist/modes/interactive/theme/dark.json +5 -4
  370. package/dist/modes/interactive/theme/light.json +5 -4
  371. package/dist/modes/interactive/theme/theme.d.ts +22 -3
  372. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  373. package/dist/modes/interactive/theme/theme.js +130 -69
  374. package/dist/modes/interactive/theme/theme.js.map +1 -1
  375. package/dist/modes/print-mode.d.ts +1 -1
  376. package/dist/modes/print-mode.d.ts.map +1 -1
  377. package/dist/modes/print-mode.js.map +1 -1
  378. package/dist/modes/rpc/rpc-client.d.ts +8 -5
  379. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  380. package/dist/modes/rpc/rpc-client.js +65 -8
  381. package/dist/modes/rpc/rpc-client.js.map +1 -1
  382. package/dist/modes/rpc/rpc-mode.d.ts +2 -2
  383. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  384. package/dist/modes/rpc/rpc-mode.js +18 -4
  385. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  386. package/dist/modes/rpc/rpc-types.d.ts +5 -4
  387. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  388. package/dist/modes/rpc/rpc-types.js.map +1 -1
  389. package/dist/modes/serve/api-handlers.d.ts +4 -0
  390. package/dist/modes/serve/api-handlers.d.ts.map +1 -0
  391. package/dist/modes/serve/api-handlers.js +324 -0
  392. package/dist/modes/serve/api-handlers.js.map +1 -0
  393. package/dist/modes/serve/http-server.d.ts +14 -0
  394. package/dist/modes/serve/http-server.d.ts.map +1 -0
  395. package/dist/modes/serve/http-server.js +94 -0
  396. package/dist/modes/serve/http-server.js.map +1 -0
  397. package/dist/modes/serve/serve-mode.d.ts +10 -0
  398. package/dist/modes/serve/serve-mode.d.ts.map +1 -0
  399. package/dist/modes/serve/serve-mode.js +217 -0
  400. package/dist/modes/serve/serve-mode.js.map +1 -0
  401. package/dist/package-manager-cli.d.ts.map +1 -1
  402. package/dist/package-manager-cli.js +62 -7
  403. package/dist/package-manager-cli.js.map +1 -1
  404. package/dist/utils/ansi.d.ts.map +1 -1
  405. package/dist/utils/ansi.js +47 -72
  406. package/dist/utils/ansi.js.map +1 -1
  407. package/dist/utils/changelog.d.ts +1 -1
  408. package/dist/utils/changelog.d.ts.map +1 -1
  409. package/dist/utils/changelog.js.map +1 -1
  410. package/dist/utils/child-process.d.ts +5 -2
  411. package/dist/utils/child-process.d.ts.map +1 -1
  412. package/dist/utils/child-process.js +9 -7
  413. package/dist/utils/child-process.js.map +1 -1
  414. package/dist/utils/clipboard-image.d.ts.map +1 -1
  415. package/dist/utils/clipboard-image.js.map +1 -1
  416. package/dist/utils/clipboard-native.d.ts +3 -1
  417. package/dist/utils/clipboard-native.d.ts.map +1 -1
  418. package/dist/utils/clipboard-native.js +14 -8
  419. package/dist/utils/clipboard-native.js.map +1 -1
  420. package/dist/utils/clipboard.d.ts.map +1 -1
  421. package/dist/utils/clipboard.js.map +1 -1
  422. package/dist/utils/deprecation.d.ts +4 -0
  423. package/dist/utils/deprecation.d.ts.map +1 -0
  424. package/dist/utils/deprecation.js +13 -0
  425. package/dist/utils/deprecation.js.map +1 -0
  426. package/dist/utils/exif-orientation.d.ts +1 -1
  427. package/dist/utils/exif-orientation.d.ts.map +1 -1
  428. package/dist/utils/exif-orientation.js.map +1 -1
  429. package/dist/utils/html.d.ts +7 -0
  430. package/dist/utils/html.d.ts.map +1 -0
  431. package/dist/utils/html.js +40 -0
  432. package/dist/utils/html.js.map +1 -0
  433. package/dist/utils/image-convert.d.ts.map +1 -1
  434. package/dist/utils/image-convert.js.map +1 -1
  435. package/dist/utils/image-resize-core.d.ts +30 -0
  436. package/dist/utils/image-resize-core.d.ts.map +1 -0
  437. package/dist/utils/image-resize-core.js +124 -0
  438. package/dist/utils/image-resize-core.js.map +1 -0
  439. package/dist/utils/image-resize-worker.d.ts +2 -0
  440. package/dist/utils/image-resize-worker.d.ts.map +1 -0
  441. package/dist/utils/image-resize-worker.js +31 -0
  442. package/dist/utils/image-resize-worker.js.map +1 -0
  443. package/dist/utils/image-resize.d.ts +7 -27
  444. package/dist/utils/image-resize.d.ts.map +1 -1
  445. package/dist/utils/image-resize.js +75 -131
  446. package/dist/utils/image-resize.js.map +1 -1
  447. package/dist/utils/json.d.ts +3 -0
  448. package/dist/utils/json.d.ts.map +1 -0
  449. package/dist/utils/json.js +7 -0
  450. package/dist/utils/json.js.map +1 -0
  451. package/dist/utils/paths.d.ts +16 -1
  452. package/dist/utils/paths.d.ts.map +1 -1
  453. package/dist/utils/paths.js +49 -7
  454. package/dist/utils/paths.js.map +1 -1
  455. package/dist/utils/shell.d.ts.map +1 -1
  456. package/dist/utils/shell.js +6 -1
  457. package/dist/utils/shell.js.map +1 -1
  458. package/dist/utils/syntax-highlight.d.ts +12 -0
  459. package/dist/utils/syntax-highlight.d.ts.map +1 -0
  460. package/dist/utils/syntax-highlight.js +118 -0
  461. package/dist/utils/syntax-highlight.js.map +1 -0
  462. package/dist/utils/tools-manager.d.ts.map +1 -1
  463. package/dist/utils/tools-manager.js +4 -1
  464. package/dist/utils/tools-manager.js.map +1 -1
  465. package/dist/utils/version-check.d.ts +2 -1
  466. package/dist/utils/version-check.d.ts.map +1 -1
  467. package/dist/utils/version-check.js +9 -4
  468. package/dist/utils/version-check.js.map +1 -1
  469. package/dist/utils/windows-self-update.d.ts +3 -0
  470. package/dist/utils/windows-self-update.d.ts.map +1 -0
  471. package/dist/utils/windows-self-update.js +77 -0
  472. package/dist/utils/windows-self-update.js.map +1 -0
  473. package/docs/custom-provider.md +111 -21
  474. package/docs/development.md +1 -1
  475. package/docs/extensions.md +13 -7
  476. package/docs/index.md +13 -3
  477. package/docs/models.md +32 -13
  478. package/docs/packages.md +9 -6
  479. package/docs/providers.md +13 -5
  480. package/docs/quickstart.md +24 -1
  481. package/docs/rpc.md +2 -1
  482. package/docs/sdk.md +8 -0
  483. package/docs/session-format.md +1 -1
  484. package/docs/sessions.md +8 -0
  485. package/docs/settings.md +8 -6
  486. package/docs/skills.md +3 -4
  487. package/docs/terminal-setup.md +8 -0
  488. package/docs/termux.md +3 -3
  489. package/docs/tui.md +2 -2
  490. package/docs/usage.md +13 -2
  491. package/examples/extensions/README.md +1 -0
  492. package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
  493. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  494. package/examples/extensions/custom-provider-anthropic/package.json +2 -2
  495. package/examples/extensions/custom-provider-gitlab-duo/index.ts +54 -3
  496. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  497. package/examples/extensions/custom-provider-gitlab-duo/test.ts +1 -1
  498. package/examples/extensions/doom-overlay/doom-component.ts +2 -2
  499. package/examples/extensions/doom-overlay/index.ts +3 -3
  500. package/examples/extensions/git-merge-and-resolve.ts +115 -0
  501. package/examples/extensions/input-transform-streaming.ts +39 -0
  502. package/examples/extensions/overlay-qa-tests.ts +97 -66
  503. package/examples/extensions/overlay-test.ts +7 -4
  504. package/examples/extensions/plan-mode/index.ts +1 -1
  505. package/examples/extensions/sandbox/package-lock.json +2 -2
  506. package/examples/extensions/sandbox/package.json +2 -2
  507. package/examples/extensions/subagent/README.md +3 -0
  508. package/examples/extensions/subagent/index.ts +42 -20
  509. package/examples/extensions/with-deps/package-lock.json +2 -2
  510. package/examples/extensions/with-deps/package.json +3 -3
  511. package/npm-shrinkwrap.json +1790 -0
  512. package/package.json +39 -32
  513. package/dist/utils/uuid.d.ts +0 -2
  514. package/dist/utils/uuid.d.ts.map +0 -1
  515. package/dist/utils/uuid.js +0 -40
  516. package/dist/utils/uuid.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // Core session management
2
+ export { parseArgs } from "./cli/args.js";
2
3
  // Config paths
3
4
  export { getAgentDir, VERSION } from "./config.js";
4
5
  export { AgentSession, parseSkillBlock, } from "./core/agent-session.js";
@@ -7,8 +8,7 @@ export { AuthStorage, FileAuthStorageBackend, InMemoryAuthStorageBackend, } from
7
8
  // Compaction
8
9
  export { calculateContextTokens, collectEntriesForBranchSummary, compact, DEFAULT_COMPACTION_SETTINGS, estimateTokens, findCutPoint, findTurnStartIndex, generateBranchSummary, generateSummary, getLastAssistantUsage, prepareBranchEntries, serializeConversation, shouldCompact, } from "./core/compaction/index.js";
9
10
  export { createEventBus } from "./core/event-bus.js";
10
- export { createExtensionRuntime, defineTool, discoverAndLoadExtensions, ExtensionRunner, isBashToolResult, isEditToolResult, isFindToolResult, isGrepToolResult, isLsToolResult, isReadToolResult, isToolCallEventType, isWriteToolResult, loadExtensionFromFactory, wrapRegisteredTool, wrapRegisteredTools, } from "./core/extensions/index.js";
11
- export { KEYBINDINGS, KeybindingsManager, migrateKeybindingsConfig } from "./core/keybindings.js";
11
+ export { createExtensionRuntime, defineTool, discoverAndLoadExtensions, ExtensionRunner, isBashToolResult, isEditToolResult, isFindToolResult, isGrepToolResult, isLsToolResult, isReadToolResult, isToolCallEventType, isWriteToolResult, wrapRegisteredTool, wrapRegisteredTools, } from "./core/extensions/index.js";
12
12
  export { convertToLlm } from "./core/messages.js";
13
13
  export { ModelRegistry } from "./core/model-registry.js";
14
14
  export { DefaultPackageManager } from "./core/package-manager.js";
@@ -33,10 +33,12 @@ export { InteractiveMode, RpcClient, runPrintMode, runRpcMode, } from "./modes/i
33
33
  // UI components for extensions
34
34
  export { ArminComponent, AssistantMessageComponent, BashExecutionComponent, BorderedLoader, BranchSummaryMessageComponent, CompactionSummaryMessageComponent, CustomEditor, CustomMessageComponent, DynamicBorder, ExtensionEditorComponent, ExtensionInputComponent, ExtensionSelectorComponent, FooterComponent, keyHint, keyText, LoginDialogComponent, ModelSelectorComponent, OAuthSelectorComponent, rawKeyHint, renderDiff, SessionSelectorComponent, SettingsSelectorComponent, ShowImagesSelectorComponent, SkillInvocationMessageComponent, ThemeSelectorComponent, ThinkingSelectorComponent, ToolExecutionComponent, TreeSelectorComponent, truncateToVisualLines, UserMessageComponent, UserMessageSelectorComponent, } from "./modes/interactive/components/index.js";
35
35
  // Theme utilities for custom tools and extensions
36
- export { getEditorTheme, getLanguageFromPath, getMarkdownTheme, getSelectListTheme, getSettingsListTheme, highlightCode, initTheme, Theme, theme, } from "./modes/interactive/theme/theme.js";
36
+ export { getLanguageFromPath, getMarkdownTheme, getSelectListTheme, getSettingsListTheme, highlightCode, initTheme, Theme, } from "./modes/interactive/theme/theme.js";
37
37
  // Clipboard utilities
38
38
  export { copyToClipboard } from "./utils/clipboard.js";
39
39
  export { parseFrontmatter, stripFrontmatter } from "./utils/frontmatter.js";
40
+ export { convertToPng } from "./utils/image-convert.js";
41
+ export { formatDimensionNote, resizeImage } from "./utils/image-resize.js";
40
42
  // Shell utilities
41
43
  export { getShellConfig } from "./utils/shell.js";
42
44
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAE1B,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EACN,YAAY,EAOZ,eAAe,GAEf,MAAM,yBAAyB,CAAC;AACjC,0BAA0B;AAC1B,OAAO,EAIN,WAAW,EAEX,sBAAsB,EACtB,0BAA0B,GAE1B,MAAM,wBAAwB,CAAC;AAChC,aAAa;AACb,OAAO,EAMN,sBAAsB,EACtB,8BAA8B,EAC9B,OAAO,EACP,2BAA2B,EAC3B,cAAc,EAEd,YAAY,EACZ,kBAAkB,EAElB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,GACb,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAA0C,MAAM,qBAAqB,CAAC;AAiF7F,OAAO,EACN,sBAAsB,EACtB,UAAU,EACV,yBAAyB,EACzB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,GACnB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAClG,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AASzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAC3F,6BAA6B;AAC7B,OAAO,EACN,mBAAmB;AASnB,UAAU;AACV,kBAAkB,EAClB,8BAA8B,EAC9B,yBAAyB,EACzB,0BAA0B,EAC1B,cAAc;AACd,kCAAkC;AAClC,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,eAAe,GAEf,MAAM,eAAe,CAAC;AACvB,OAAO,EAEN,mBAAmB,EAEnB,uBAAuB,EAIvB,wBAAwB,EAExB,qBAAqB,EAErB,mBAAmB,EAOnB,cAAc,GAGd,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAKN,eAAe,GACf,MAAM,4BAA4B,CAAC;AACpC,SAAS;AACT,OAAO,EACN,qBAAqB,EAGrB,UAAU,EACV,iBAAiB,GAGjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,QAAQ;AACR,OAAO,EAON,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,yBAAyB,EACzB,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,EASjB,UAAU,EAgBV,YAAY,EACZ,YAAY,EACZ,YAAY,EAIZ,qBAAqB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,mBAAmB;AACnB,OAAO,EAAoB,IAAI,EAAE,MAAM,WAAW,CAAC;AACnD,uCAAuC;AACvC,OAAO,EACN,eAAe,EAIf,SAAS,EAMT,YAAY,EACZ,UAAU,GACV,MAAM,kBAAkB,CAAC;AAC1B,+BAA+B;AAC/B,OAAO,EACN,cAAc,EACd,yBAAyB,EACzB,sBAAsB,EACtB,cAAc,EACd,6BAA6B,EAC7B,iCAAiC,EACjC,YAAY,EACZ,sBAAsB,EACtB,aAAa,EACb,wBAAwB,EACxB,uBAAuB,EACvB,0BAA0B,EAC1B,eAAe,EACf,OAAO,EACP,OAAO,EACP,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EAEtB,UAAU,EACV,UAAU,EACV,wBAAwB,EAGxB,yBAAyB,EACzB,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,EACtB,yBAAyB,EACzB,sBAAsB,EAEtB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,GAE5B,MAAM,yCAAyC,CAAC;AACjD,kDAAkD;AAClD,OAAO,EACN,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,SAAS,EACT,KAAK,EAEL,KAAK,GACL,MAAM,oCAAoC,CAAC;AAC5C,sBAAsB;AACtB,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC5E,kBAAkB;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["// Core session management\n\n// Config paths\nexport { getAgentDir, VERSION } from \"./config.js\";\nexport {\n\tAgentSession,\n\ttype AgentSessionConfig,\n\ttype AgentSessionEvent,\n\ttype AgentSessionEventListener,\n\ttype ModelCycleResult,\n\ttype ParsedSkillBlock,\n\ttype PromptOptions,\n\tparseSkillBlock,\n\ttype SessionStats,\n} from \"./core/agent-session.js\";\n// Auth and model registry\nexport {\n\ttype ApiKeyCredential,\n\ttype AuthCredential,\n\ttype AuthStatus,\n\tAuthStorage,\n\ttype AuthStorageBackend,\n\tFileAuthStorageBackend,\n\tInMemoryAuthStorageBackend,\n\ttype OAuthCredential,\n} from \"./core/auth-storage.js\";\n// Compaction\nexport {\n\ttype BranchPreparation,\n\ttype BranchSummaryResult,\n\ttype CollectEntriesResult,\n\ttype CompactionResult,\n\ttype CutPointResult,\n\tcalculateContextTokens,\n\tcollectEntriesForBranchSummary,\n\tcompact,\n\tDEFAULT_COMPACTION_SETTINGS,\n\testimateTokens,\n\ttype FileOperations,\n\tfindCutPoint,\n\tfindTurnStartIndex,\n\ttype GenerateBranchSummaryOptions,\n\tgenerateBranchSummary,\n\tgenerateSummary,\n\tgetLastAssistantUsage,\n\tprepareBranchEntries,\n\tserializeConversation,\n\tshouldCompact,\n} from \"./core/compaction/index.js\";\nexport { createEventBus, type EventBus, type EventBusController } from \"./core/event-bus.js\";\n// Extension system\nexport type {\n\tAgentEndEvent,\n\tAgentStartEvent,\n\tAgentToolResult,\n\tAgentToolUpdateCallback,\n\tAppKeybinding,\n\tAutocompleteProviderFactory,\n\tBashToolCallEvent,\n\tBeforeAgentStartEvent,\n\tBeforeAgentStartEventResult,\n\tBeforeProviderRequestEvent,\n\tBeforeProviderRequestEventResult,\n\tBuildSystemPromptOptions,\n\tCompactOptions,\n\tContextEvent,\n\tContextUsage,\n\tCustomToolCallEvent,\n\tEditToolCallEvent,\n\tExecOptions,\n\tExecResult,\n\tExtension,\n\tExtensionActions,\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionCommandContextActions,\n\tExtensionContext,\n\tExtensionContextActions,\n\tExtensionError,\n\tExtensionEvent,\n\tExtensionFactory,\n\tExtensionFlag,\n\tExtensionHandler,\n\tExtensionRuntime,\n\tExtensionShortcut,\n\tExtensionUIContext,\n\tExtensionUIDialogOptions,\n\tExtensionWidgetOptions,\n\tFindToolCallEvent,\n\tGrepToolCallEvent,\n\tInputEvent,\n\tInputEventResult,\n\tInputSource,\n\tLoadExtensionsResult,\n\tLsToolCallEvent,\n\tMessageRenderer,\n\tMessageRenderOptions,\n\tProviderConfig,\n\tProviderModelConfig,\n\tReadToolCallEvent,\n\tRegisteredCommand,\n\tRegisteredTool,\n\tResolvedCommand,\n\tSessionBeforeCompactEvent,\n\tSessionBeforeForkEvent,\n\tSessionBeforeSwitchEvent,\n\tSessionBeforeTreeEvent,\n\tSessionCompactEvent,\n\tSessionShutdownEvent,\n\tSessionStartEvent,\n\tSessionTreeEvent,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tSourceInfo,\n\tTerminalInputHandler,\n\tToolCallEvent,\n\tToolCallEventResult,\n\tToolDefinition,\n\tToolExecutionMode,\n\tToolInfo,\n\tToolRenderResultOptions,\n\tToolResultEvent,\n\tTurnEndEvent,\n\tTurnStartEvent,\n\tUserBashEvent,\n\tUserBashEventResult,\n\tWidgetPlacement,\n\tWorkingIndicatorOptions,\n\tWriteToolCallEvent,\n} from \"./core/extensions/index.js\";\nexport {\n\tcreateExtensionRuntime,\n\tdefineTool,\n\tdiscoverAndLoadExtensions,\n\tExtensionRunner,\n\tisBashToolResult,\n\tisEditToolResult,\n\tisFindToolResult,\n\tisGrepToolResult,\n\tisLsToolResult,\n\tisReadToolResult,\n\tisToolCallEventType,\n\tisWriteToolResult,\n\tloadExtensionFromFactory,\n\twrapRegisteredTool,\n\twrapRegisteredTools,\n} from \"./core/extensions/index.js\";\n// Footer data provider (git branch + extension statuses - data not otherwise available to extensions)\nexport type { ReadonlyFooterDataProvider } from \"./core/footer-data-provider.js\";\nexport { KEYBINDINGS, KeybindingsManager, migrateKeybindingsConfig } from \"./core/keybindings.js\";\nexport { convertToLlm } from \"./core/messages.js\";\nexport { ModelRegistry } from \"./core/model-registry.js\";\nexport type {\n\tPackageManager,\n\tPathMetadata,\n\tProgressCallback,\n\tProgressEvent,\n\tResolvedPaths,\n\tResolvedResource,\n} from \"./core/package-manager.js\";\nexport { DefaultPackageManager } from \"./core/package-manager.js\";\nexport type { ResourceCollision, ResourceDiagnostic, ResourceLoader } from \"./core/resource-loader.js\";\nexport { DefaultResourceLoader, loadProjectContextFiles } from \"./core/resource-loader.js\";\n// SDK for programmatic usage\nexport {\n\tAgentSessionRuntime,\n\ttype AgentSessionRuntimeDiagnostic,\n\ttype AgentSessionServices,\n\ttype CreateAgentSessionFromServicesOptions,\n\ttype CreateAgentSessionOptions,\n\ttype CreateAgentSessionResult,\n\ttype CreateAgentSessionRuntimeFactory,\n\ttype CreateAgentSessionRuntimeResult,\n\ttype CreateAgentSessionServicesOptions,\n\t// Factory\n\tcreateAgentSession,\n\tcreateAgentSessionFromServices,\n\tcreateAgentSessionRuntime,\n\tcreateAgentSessionServices,\n\tcreateBashTool,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype PromptTemplate,\n} from \"./core/sdk.js\";\nexport {\n\ttype BranchSummaryEntry,\n\tbuildSessionContext,\n\ttype CompactionEntry,\n\tCURRENT_SESSION_VERSION,\n\ttype CustomEntry,\n\ttype CustomMessageEntry,\n\ttype FileEntry,\n\tgetLatestCompactionEntry,\n\ttype ModelChangeEntry,\n\tmigrateSessionEntries,\n\ttype NewSessionOptions,\n\tparseSessionEntries,\n\ttype SessionContext,\n\ttype SessionEntry,\n\ttype SessionEntryBase,\n\ttype SessionHeader,\n\ttype SessionInfo,\n\ttype SessionInfoEntry,\n\tSessionManager,\n\ttype SessionMessageEntry,\n\ttype ThinkingLevelChangeEntry,\n} from \"./core/session-manager.js\";\nexport {\n\ttype CompactionSettings,\n\ttype ImageSettings,\n\ttype PackageSource,\n\ttype RetrySettings,\n\tSettingsManager,\n} from \"./core/settings-manager.js\";\n// Skills\nexport {\n\tformatSkillsForPrompt,\n\ttype LoadSkillsFromDirOptions,\n\ttype LoadSkillsResult,\n\tloadSkills,\n\tloadSkillsFromDir,\n\ttype Skill,\n\ttype SkillFrontmatter,\n} from \"./core/skills.js\";\nexport { createSyntheticSourceInfo } from \"./core/source-info.js\";\n// Tools\nexport {\n\ttype BashOperations,\n\ttype BashSpawnContext,\n\ttype BashSpawnHook,\n\ttype BashToolDetails,\n\ttype BashToolInput,\n\ttype BashToolOptions,\n\tcreateBashToolDefinition,\n\tcreateEditToolDefinition,\n\tcreateFindToolDefinition,\n\tcreateGrepToolDefinition,\n\tcreateLocalBashOperations,\n\tcreateLsToolDefinition,\n\tcreateReadToolDefinition,\n\tcreateWriteToolDefinition,\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolInput,\n\ttype EditToolOptions,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolInput,\n\ttype FindToolOptions,\n\tformatSize,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolInput,\n\ttype GrepToolOptions,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolInput,\n\ttype LsToolOptions,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolInput,\n\ttype ReadToolOptions,\n\ttype ToolsOptions,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n\ttype WriteOperations,\n\ttype WriteToolInput,\n\ttype WriteToolOptions,\n\twithFileMutationQueue,\n} from \"./core/tools/index.js\";\n// Main entry point\nexport { type MainOptions, main } from \"./main.js\";\n// Run modes for programmatic SDK usage\nexport {\n\tInteractiveMode,\n\ttype InteractiveModeOptions,\n\ttype ModelInfo,\n\ttype PrintModeOptions,\n\tRpcClient,\n\ttype RpcClientOptions,\n\ttype RpcCommand,\n\ttype RpcEventListener,\n\ttype RpcResponse,\n\ttype RpcSessionState,\n\trunPrintMode,\n\trunRpcMode,\n} from \"./modes/index.js\";\n// UI components for extensions\nexport {\n\tArminComponent,\n\tAssistantMessageComponent,\n\tBashExecutionComponent,\n\tBorderedLoader,\n\tBranchSummaryMessageComponent,\n\tCompactionSummaryMessageComponent,\n\tCustomEditor,\n\tCustomMessageComponent,\n\tDynamicBorder,\n\tExtensionEditorComponent,\n\tExtensionInputComponent,\n\tExtensionSelectorComponent,\n\tFooterComponent,\n\tkeyHint,\n\tkeyText,\n\tLoginDialogComponent,\n\tModelSelectorComponent,\n\tOAuthSelectorComponent,\n\ttype RenderDiffOptions,\n\trawKeyHint,\n\trenderDiff,\n\tSessionSelectorComponent,\n\ttype SettingsCallbacks,\n\ttype SettingsConfig,\n\tSettingsSelectorComponent,\n\tShowImagesSelectorComponent,\n\tSkillInvocationMessageComponent,\n\tThemeSelectorComponent,\n\tThinkingSelectorComponent,\n\tToolExecutionComponent,\n\ttype ToolExecutionOptions,\n\tTreeSelectorComponent,\n\ttruncateToVisualLines,\n\tUserMessageComponent,\n\tUserMessageSelectorComponent,\n\ttype VisualTruncateResult,\n} from \"./modes/interactive/components/index.js\";\n// Theme utilities for custom tools and extensions\nexport {\n\tgetEditorTheme,\n\tgetLanguageFromPath,\n\tgetMarkdownTheme,\n\tgetSelectListTheme,\n\tgetSettingsListTheme,\n\thighlightCode,\n\tinitTheme,\n\tTheme,\n\ttype ThemeColor,\n\ttheme,\n} from \"./modes/interactive/theme/theme.js\";\n// Clipboard utilities\nexport { copyToClipboard } from \"./utils/clipboard.js\";\nexport { parseFrontmatter, stripFrontmatter } from \"./utils/frontmatter.js\";\n// Shell utilities\nexport { getShellConfig } from \"./utils/shell.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAE1B,OAAO,EAAa,SAAS,EAAE,MAAM,eAAe,CAAC;AAErD,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EACN,YAAY,EAOZ,eAAe,GAEf,MAAM,yBAAyB,CAAC;AACjC,0BAA0B;AAC1B,OAAO,EAIN,WAAW,EAEX,sBAAsB,EACtB,0BAA0B,GAE1B,MAAM,wBAAwB,CAAC;AAChC,aAAa;AACb,OAAO,EAMN,sBAAsB,EACtB,8BAA8B,EAC9B,OAAO,EACP,2BAA2B,EAC3B,cAAc,EAEd,YAAY,EACZ,kBAAkB,EAElB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,GACb,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAA0C,MAAM,qBAAqB,CAAC;AAkF7F,OAAO,EACN,sBAAsB,EACtB,UAAU,EACV,yBAAyB,EACzB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,GACnB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AASzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAC3F,6BAA6B;AAC7B,OAAO,EACN,mBAAmB;AASnB,UAAU;AACV,kBAAkB,EAClB,8BAA8B,EAC9B,yBAAyB,EACzB,0BAA0B,EAC1B,cAAc;AACd,kCAAkC;AAClC,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,eAAe,GAEf,MAAM,eAAe,CAAC;AACvB,OAAO,EAEN,mBAAmB,EAEnB,uBAAuB,EAIvB,wBAAwB,EAExB,qBAAqB,EAErB,mBAAmB,EAOnB,cAAc,GAGd,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAKN,eAAe,GACf,MAAM,4BAA4B,CAAC;AACpC,SAAS;AACT,OAAO,EACN,qBAAqB,EAGrB,UAAU,EACV,iBAAiB,GAGjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,QAAQ;AACR,OAAO,EAON,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,yBAAyB,EACzB,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,EASjB,UAAU,EAgBV,YAAY,EACZ,YAAY,EACZ,YAAY,EAIZ,qBAAqB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,mBAAmB;AACnB,OAAO,EAAoB,IAAI,EAAE,MAAM,WAAW,CAAC;AACnD,uCAAuC;AACvC,OAAO,EACN,eAAe,EAIf,SAAS,EAMT,YAAY,EACZ,UAAU,GACV,MAAM,kBAAkB,CAAC;AAC1B,+BAA+B;AAC/B,OAAO,EACN,cAAc,EACd,yBAAyB,EACzB,sBAAsB,EACtB,cAAc,EACd,6BAA6B,EAC7B,iCAAiC,EACjC,YAAY,EACZ,sBAAsB,EACtB,aAAa,EACb,wBAAwB,EACxB,uBAAuB,EACvB,0BAA0B,EAC1B,eAAe,EACf,OAAO,EACP,OAAO,EACP,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EAEtB,UAAU,EACV,UAAU,EACV,wBAAwB,EAGxB,yBAAyB,EACzB,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,EACtB,yBAAyB,EACzB,sBAAsB,EAEtB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,GAE5B,MAAM,yCAAyC,CAAC;AACjD,kDAAkD;AAClD,OAAO,EACN,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,SAAS,EACT,KAAK,GAEL,MAAM,oCAAoC,CAAC;AAC5C,sBAAsB;AACtB,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAqB,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC9F,kBAAkB;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["// Core session management\n\nexport { type Args, parseArgs } from \"./cli/args.ts\";\n\n// Config paths\nexport { getAgentDir, VERSION } from \"./config.ts\";\nexport {\n\tAgentSession,\n\ttype AgentSessionConfig,\n\ttype AgentSessionEvent,\n\ttype AgentSessionEventListener,\n\ttype ModelCycleResult,\n\ttype ParsedSkillBlock,\n\ttype PromptOptions,\n\tparseSkillBlock,\n\ttype SessionStats,\n} from \"./core/agent-session.ts\";\n// Auth and model registry\nexport {\n\ttype ApiKeyCredential,\n\ttype AuthCredential,\n\ttype AuthStatus,\n\tAuthStorage,\n\ttype AuthStorageBackend,\n\tFileAuthStorageBackend,\n\tInMemoryAuthStorageBackend,\n\ttype OAuthCredential,\n} from \"./core/auth-storage.ts\";\n// Compaction\nexport {\n\ttype BranchPreparation,\n\ttype BranchSummaryResult,\n\ttype CollectEntriesResult,\n\ttype CompactionResult,\n\ttype CutPointResult,\n\tcalculateContextTokens,\n\tcollectEntriesForBranchSummary,\n\tcompact,\n\tDEFAULT_COMPACTION_SETTINGS,\n\testimateTokens,\n\ttype FileOperations,\n\tfindCutPoint,\n\tfindTurnStartIndex,\n\ttype GenerateBranchSummaryOptions,\n\tgenerateBranchSummary,\n\tgenerateSummary,\n\tgetLastAssistantUsage,\n\tprepareBranchEntries,\n\tserializeConversation,\n\tshouldCompact,\n} from \"./core/compaction/index.ts\";\nexport { createEventBus, type EventBus, type EventBusController } from \"./core/event-bus.ts\";\n// Extension system\nexport type {\n\tAgentEndEvent,\n\tAgentStartEvent,\n\tAgentToolResult,\n\tAgentToolUpdateCallback,\n\tAppKeybinding,\n\tAutocompleteProviderFactory,\n\tBashToolCallEvent,\n\tBeforeAgentStartEvent,\n\tBeforeAgentStartEventResult,\n\tBeforeProviderRequestEvent,\n\tBeforeProviderRequestEventResult,\n\tBuildSystemPromptOptions,\n\tCompactOptions,\n\tContextEvent,\n\tContextUsage,\n\tCustomToolCallEvent,\n\tEditToolCallEvent,\n\tExecOptions,\n\tExecResult,\n\tExtension,\n\tExtensionActions,\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionCommandContextActions,\n\tExtensionContext,\n\tExtensionContextActions,\n\tExtensionError,\n\tExtensionEvent,\n\tExtensionFactory,\n\tExtensionFlag,\n\tExtensionHandler,\n\tExtensionRuntime,\n\tExtensionShortcut,\n\tExtensionUIContext,\n\tExtensionUIDialogOptions,\n\tExtensionWidgetOptions,\n\tFindToolCallEvent,\n\tGrepToolCallEvent,\n\tInputEvent,\n\tInputEventResult,\n\tInputSource,\n\tKeybindingsManager,\n\tLoadExtensionsResult,\n\tLsToolCallEvent,\n\tMessageRenderer,\n\tMessageRenderOptions,\n\tProviderConfig,\n\tProviderModelConfig,\n\tReadToolCallEvent,\n\tRegisteredCommand,\n\tRegisteredTool,\n\tResolvedCommand,\n\tSessionBeforeCompactEvent,\n\tSessionBeforeForkEvent,\n\tSessionBeforeSwitchEvent,\n\tSessionBeforeTreeEvent,\n\tSessionCompactEvent,\n\tSessionShutdownEvent,\n\tSessionStartEvent,\n\tSessionTreeEvent,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tSourceInfo,\n\tTerminalInputHandler,\n\tToolCallEvent,\n\tToolCallEventResult,\n\tToolDefinition,\n\tToolExecutionMode,\n\tToolInfo,\n\tToolRenderResultOptions,\n\tToolResultEvent,\n\tTurnEndEvent,\n\tTurnStartEvent,\n\tUserBashEvent,\n\tUserBashEventResult,\n\tWidgetPlacement,\n\tWorkingIndicatorOptions,\n\tWriteToolCallEvent,\n} from \"./core/extensions/index.ts\";\nexport {\n\tcreateExtensionRuntime,\n\tdefineTool,\n\tdiscoverAndLoadExtensions,\n\tExtensionRunner,\n\tisBashToolResult,\n\tisEditToolResult,\n\tisFindToolResult,\n\tisGrepToolResult,\n\tisLsToolResult,\n\tisReadToolResult,\n\tisToolCallEventType,\n\tisWriteToolResult,\n\twrapRegisteredTool,\n\twrapRegisteredTools,\n} from \"./core/extensions/index.ts\";\n// Footer data provider (git branch + extension statuses - data not otherwise available to extensions)\nexport type { ReadonlyFooterDataProvider } from \"./core/footer-data-provider.ts\";\nexport { convertToLlm } from \"./core/messages.ts\";\nexport { ModelRegistry } from \"./core/model-registry.ts\";\nexport type {\n\tPackageManager,\n\tPathMetadata,\n\tProgressCallback,\n\tProgressEvent,\n\tResolvedPaths,\n\tResolvedResource,\n} from \"./core/package-manager.ts\";\nexport { DefaultPackageManager } from \"./core/package-manager.ts\";\nexport type { ResourceCollision, ResourceDiagnostic, ResourceLoader } from \"./core/resource-loader.ts\";\nexport { DefaultResourceLoader, loadProjectContextFiles } from \"./core/resource-loader.ts\";\n// SDK for programmatic usage\nexport {\n\tAgentSessionRuntime,\n\ttype AgentSessionRuntimeDiagnostic,\n\ttype AgentSessionServices,\n\ttype CreateAgentSessionFromServicesOptions,\n\ttype CreateAgentSessionOptions,\n\ttype CreateAgentSessionResult,\n\ttype CreateAgentSessionRuntimeFactory,\n\ttype CreateAgentSessionRuntimeResult,\n\ttype CreateAgentSessionServicesOptions,\n\t// Factory\n\tcreateAgentSession,\n\tcreateAgentSessionFromServices,\n\tcreateAgentSessionRuntime,\n\tcreateAgentSessionServices,\n\tcreateBashTool,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype PromptTemplate,\n} from \"./core/sdk.ts\";\nexport {\n\ttype BranchSummaryEntry,\n\tbuildSessionContext,\n\ttype CompactionEntry,\n\tCURRENT_SESSION_VERSION,\n\ttype CustomEntry,\n\ttype CustomMessageEntry,\n\ttype FileEntry,\n\tgetLatestCompactionEntry,\n\ttype ModelChangeEntry,\n\tmigrateSessionEntries,\n\ttype NewSessionOptions,\n\tparseSessionEntries,\n\ttype SessionContext,\n\ttype SessionEntry,\n\ttype SessionEntryBase,\n\ttype SessionHeader,\n\ttype SessionInfo,\n\ttype SessionInfoEntry,\n\tSessionManager,\n\ttype SessionMessageEntry,\n\ttype ThinkingLevelChangeEntry,\n} from \"./core/session-manager.ts\";\nexport {\n\ttype CompactionSettings,\n\ttype ImageSettings,\n\ttype PackageSource,\n\ttype RetrySettings,\n\tSettingsManager,\n} from \"./core/settings-manager.ts\";\n// Skills\nexport {\n\tformatSkillsForPrompt,\n\ttype LoadSkillsFromDirOptions,\n\ttype LoadSkillsResult,\n\tloadSkills,\n\tloadSkillsFromDir,\n\ttype Skill,\n\ttype SkillFrontmatter,\n} from \"./core/skills.ts\";\nexport { createSyntheticSourceInfo } from \"./core/source-info.ts\";\n// Tools\nexport {\n\ttype BashOperations,\n\ttype BashSpawnContext,\n\ttype BashSpawnHook,\n\ttype BashToolDetails,\n\ttype BashToolInput,\n\ttype BashToolOptions,\n\tcreateBashToolDefinition,\n\tcreateEditToolDefinition,\n\tcreateFindToolDefinition,\n\tcreateGrepToolDefinition,\n\tcreateLocalBashOperations,\n\tcreateLsToolDefinition,\n\tcreateReadToolDefinition,\n\tcreateWriteToolDefinition,\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolInput,\n\ttype EditToolOptions,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolInput,\n\ttype FindToolOptions,\n\tformatSize,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolInput,\n\ttype GrepToolOptions,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolInput,\n\ttype LsToolOptions,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolInput,\n\ttype ReadToolOptions,\n\ttype ToolsOptions,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n\ttype WriteOperations,\n\ttype WriteToolInput,\n\ttype WriteToolOptions,\n\twithFileMutationQueue,\n} from \"./core/tools/index.ts\";\n// Main entry point\nexport { type MainOptions, main } from \"./main.ts\";\n// Run modes for programmatic SDK usage\nexport {\n\tInteractiveMode,\n\ttype InteractiveModeOptions,\n\ttype ModelInfo,\n\ttype PrintModeOptions,\n\tRpcClient,\n\ttype RpcClientOptions,\n\ttype RpcCommand,\n\ttype RpcEventListener,\n\ttype RpcResponse,\n\ttype RpcSessionState,\n\trunPrintMode,\n\trunRpcMode,\n} from \"./modes/index.ts\";\n// UI components for extensions\nexport {\n\tArminComponent,\n\tAssistantMessageComponent,\n\tBashExecutionComponent,\n\tBorderedLoader,\n\tBranchSummaryMessageComponent,\n\tCompactionSummaryMessageComponent,\n\tCustomEditor,\n\tCustomMessageComponent,\n\tDynamicBorder,\n\tExtensionEditorComponent,\n\tExtensionInputComponent,\n\tExtensionSelectorComponent,\n\tFooterComponent,\n\tkeyHint,\n\tkeyText,\n\tLoginDialogComponent,\n\tModelSelectorComponent,\n\tOAuthSelectorComponent,\n\ttype RenderDiffOptions,\n\trawKeyHint,\n\trenderDiff,\n\tSessionSelectorComponent,\n\ttype SettingsCallbacks,\n\ttype SettingsConfig,\n\tSettingsSelectorComponent,\n\tShowImagesSelectorComponent,\n\tSkillInvocationMessageComponent,\n\tThemeSelectorComponent,\n\tThinkingSelectorComponent,\n\tToolExecutionComponent,\n\ttype ToolExecutionOptions,\n\tTreeSelectorComponent,\n\ttruncateToVisualLines,\n\tUserMessageComponent,\n\tUserMessageSelectorComponent,\n\ttype VisualTruncateResult,\n} from \"./modes/interactive/components/index.ts\";\n// Theme utilities for custom tools and extensions\nexport {\n\tgetLanguageFromPath,\n\tgetMarkdownTheme,\n\tgetSelectListTheme,\n\tgetSettingsListTheme,\n\thighlightCode,\n\tinitTheme,\n\tTheme,\n\ttype ThemeColor,\n} from \"./modes/interactive/theme/theme.ts\";\n// Clipboard utilities\nexport { copyToClipboard } from \"./utils/clipboard.ts\";\nexport { parseFrontmatter, stripFrontmatter } from \"./utils/frontmatter.ts\";\nexport { convertToPng } from \"./utils/image-convert.ts\";\nexport { formatDimensionNote, type ResizedImage, resizeImage } from \"./utils/image-resize.ts\";\n// Shell utilities\nexport { getShellConfig } from \"./utils/shell.ts\";\n"]}
package/dist/main.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * This file handles CLI argument parsing and translates them into
5
5
  * createAgentSession() options. The SDK does the heavy lifting.
6
6
  */
7
- import type { ExtensionFactory } from "./core/extensions/types.js";
7
+ import type { ExtensionFactory } from "./core/extensions/types.ts";
8
8
  export interface MainOptions {
9
9
  extensionFactories?: ExtensionFactory[];
10
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAsBH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAuYnE,MAAM,WAAW,WAAW;IAC3B,kBAAkB,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACxC;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,iBAgT/D","sourcesContent":["/**\n * Main entry point for the coding agent CLI.\n *\n * This file handles CLI argument parsing and translates them into\n * createAgentSession() options. The SDK does the heavy lifting.\n */\n\nimport { resolve } from \"node:path\";\nimport { createInterface } from \"node:readline\";\nimport { type ImageContent, modelsAreEqual } from \"@sheason/pi-ai\";\nimport { ProcessTerminal, setKeybindings, TUI } from \"@sheason/pi-tui\";\nimport chalk from \"chalk\";\nimport { type Args, type Mode, parseArgs, printHelp } from \"./cli/args.js\";\nimport { processFileArguments } from \"./cli/file-processor.js\";\nimport { buildInitialMessage } from \"./cli/initial-message.js\";\nimport { listModels } from \"./cli/list-models.js\";\nimport { selectSession } from \"./cli/session-picker.js\";\nimport { ENV_SESSION_DIR, expandTildePath, getAgentDir, VERSION } from \"./config.js\";\nimport { type CreateAgentSessionRuntimeFactory, createAgentSessionRuntime } from \"./core/agent-session-runtime.js\";\nimport {\n\ttype AgentSessionRuntimeDiagnostic,\n\tcreateAgentSessionFromServices,\n\tcreateAgentSessionServices,\n} from \"./core/agent-session-services.js\";\nimport { formatNoModelsAvailableMessage } from \"./core/auth-guidance.js\";\nimport { AuthStorage } from \"./core/auth-storage.js\";\nimport { exportFromFile } from \"./core/export-html/index.js\";\nimport type { ExtensionFactory } from \"./core/extensions/types.js\";\nimport { KeybindingsManager } from \"./core/keybindings.js\";\nimport type { ModelRegistry } from \"./core/model-registry.js\";\nimport { resolveCliModel, resolveModelScope, type ScopedModel } from \"./core/model-resolver.js\";\nimport { restoreStdout, takeOverStdout } from \"./core/output-guard.js\";\nimport type { CreateAgentSessionOptions } from \"./core/sdk.js\";\nimport {\n\tformatMissingSessionCwdPrompt,\n\tgetMissingSessionCwdIssue,\n\tMissingSessionCwdError,\n\ttype SessionCwdIssue,\n} from \"./core/session-cwd.js\";\nimport { SessionManager } from \"./core/session-manager.js\";\nimport { SettingsManager } from \"./core/settings-manager.js\";\nimport { printTimings, resetTimings, time } from \"./core/timings.js\";\nimport { runMigrations, showDeprecationWarnings } from \"./migrations.js\";\nimport { InteractiveMode, runPrintMode, runRpcMode } from \"./modes/index.js\";\nimport { ExtensionSelectorComponent } from \"./modes/interactive/components/extension-selector.js\";\nimport { initTheme, stopThemeWatcher } from \"./modes/interactive/theme/theme.js\";\nimport { handleConfigCommand, handlePackageCommand } from \"./package-manager-cli.js\";\nimport { isLocalPath } from \"./utils/paths.js\";\n\n/**\n * Read all content from piped stdin.\n * Returns undefined if stdin is a TTY (interactive terminal).\n */\nasync function readPipedStdin(): Promise<string | undefined> {\n\t// If stdin is a TTY, we're running interactively - don't read stdin\n\tif (process.stdin.isTTY) {\n\t\treturn undefined;\n\t}\n\n\treturn new Promise((resolve) => {\n\t\tlet data = \"\";\n\t\tprocess.stdin.setEncoding(\"utf8\");\n\t\tprocess.stdin.on(\"data\", (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\t\tprocess.stdin.on(\"end\", () => {\n\t\t\tresolve(data.trim() || undefined);\n\t\t});\n\t\tprocess.stdin.resume();\n\t});\n}\n\nfunction collectSettingsDiagnostics(\n\tsettingsManager: SettingsManager,\n\tcontext: string,\n): AgentSessionRuntimeDiagnostic[] {\n\treturn settingsManager.drainErrors().map(({ scope, error }) => ({\n\t\ttype: \"warning\",\n\t\tmessage: `(${context}, ${scope} settings) ${error.message}`,\n\t}));\n}\n\nfunction reportDiagnostics(diagnostics: readonly AgentSessionRuntimeDiagnostic[]): void {\n\tfor (const diagnostic of diagnostics) {\n\t\tconst color = diagnostic.type === \"error\" ? chalk.red : diagnostic.type === \"warning\" ? chalk.yellow : chalk.dim;\n\t\tconst prefix = diagnostic.type === \"error\" ? \"Error: \" : diagnostic.type === \"warning\" ? \"Warning: \" : \"\";\n\t\tconsole.error(color(`${prefix}${diagnostic.message}`));\n\t}\n}\n\nfunction isTruthyEnvFlag(value: string | undefined): boolean {\n\tif (!value) return false;\n\treturn value === \"1\" || value.toLowerCase() === \"true\" || value.toLowerCase() === \"yes\";\n}\n\ntype AppMode = \"interactive\" | \"print\" | \"json\" | \"rpc\";\n\nfunction resolveAppMode(parsed: Args, stdinIsTTY: boolean): AppMode {\n\tif (parsed.mode === \"rpc\") {\n\t\treturn \"rpc\";\n\t}\n\tif (parsed.mode === \"json\") {\n\t\treturn \"json\";\n\t}\n\tif (parsed.print || !stdinIsTTY) {\n\t\treturn \"print\";\n\t}\n\treturn \"interactive\";\n}\n\nfunction toPrintOutputMode(appMode: AppMode): Exclude<Mode, \"rpc\"> {\n\treturn appMode === \"json\" ? \"json\" : \"text\";\n}\n\nasync function prepareInitialMessage(\n\tparsed: Args,\n\tautoResizeImages: boolean,\n\tstdinContent?: string,\n): Promise<{\n\tinitialMessage?: string;\n\tinitialImages?: ImageContent[];\n}> {\n\tif (parsed.fileArgs.length === 0) {\n\t\treturn buildInitialMessage({ parsed, stdinContent });\n\t}\n\n\tconst { text, images } = await processFileArguments(parsed.fileArgs, { autoResizeImages });\n\treturn buildInitialMessage({\n\t\tparsed,\n\t\tfileText: text,\n\t\tfileImages: images,\n\t\tstdinContent,\n\t});\n}\n\n/** Result from resolving a session argument */\ntype ResolvedSession =\n\t| { type: \"path\"; path: string } // Direct file path\n\t| { type: \"local\"; path: string } // Found in current project\n\t| { type: \"global\"; path: string; cwd: string } // Found in different project\n\t| { type: \"not_found\"; arg: string }; // Not found anywhere\n\n/**\n * Resolve a session argument to a file path.\n * If it looks like a path, use as-is. Otherwise try to match as session ID prefix.\n */\nasync function resolveSessionPath(sessionArg: string, cwd: string, sessionDir?: string): Promise<ResolvedSession> {\n\t// If it looks like a file path, use as-is\n\tif (sessionArg.includes(\"/\") || sessionArg.includes(\"\\\\\") || sessionArg.endsWith(\".jsonl\")) {\n\t\treturn { type: \"path\", path: sessionArg };\n\t}\n\n\t// Try to match as session ID in current project first\n\tconst localSessions = await SessionManager.list(cwd, sessionDir);\n\tconst localMatches = localSessions.filter((s) => s.id.startsWith(sessionArg));\n\n\tif (localMatches.length >= 1) {\n\t\treturn { type: \"local\", path: localMatches[0].path };\n\t}\n\n\t// Try global search across all projects\n\tconst allSessions = await SessionManager.listAll();\n\tconst globalMatches = allSessions.filter((s) => s.id.startsWith(sessionArg));\n\n\tif (globalMatches.length >= 1) {\n\t\tconst match = globalMatches[0];\n\t\treturn { type: \"global\", path: match.path, cwd: match.cwd };\n\t}\n\n\t// Not found anywhere\n\treturn { type: \"not_found\", arg: sessionArg };\n}\n\n/** Prompt user for yes/no confirmation */\nasync function promptConfirm(message: string): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst rl = createInterface({\n\t\t\tinput: process.stdin,\n\t\t\toutput: process.stdout,\n\t\t});\n\t\trl.question(`${message} [y/N] `, (answer) => {\n\t\t\trl.close();\n\t\t\tresolve(answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\");\n\t\t});\n\t});\n}\n\nfunction validateForkFlags(parsed: Args): void {\n\tif (!parsed.fork) return;\n\n\tconst conflictingFlags = [\n\t\tparsed.session ? \"--session\" : undefined,\n\t\tparsed.continue ? \"--continue\" : undefined,\n\t\tparsed.resume ? \"--resume\" : undefined,\n\t\tparsed.noSession ? \"--no-session\" : undefined,\n\t].filter((flag): flag is string => flag !== undefined);\n\n\tif (conflictingFlags.length > 0) {\n\t\tconsole.error(chalk.red(`Error: --fork cannot be combined with ${conflictingFlags.join(\", \")}`));\n\t\tprocess.exit(1);\n\t}\n}\n\nfunction forkSessionOrExit(sourcePath: string, cwd: string, sessionDir?: string): SessionManager {\n\ttry {\n\t\treturn SessionManager.forkFrom(sourcePath, cwd, sessionDir);\n\t} catch (error: unknown) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconsole.error(chalk.red(`Error: ${message}`));\n\t\tprocess.exit(1);\n\t}\n}\n\nasync function createSessionManager(\n\tparsed: Args,\n\tcwd: string,\n\tsessionDir: string | undefined,\n\tsettingsManager: SettingsManager,\n): Promise<SessionManager> {\n\tif (parsed.noSession) {\n\t\treturn SessionManager.inMemory();\n\t}\n\n\tif (parsed.fork) {\n\t\tconst resolved = await resolveSessionPath(parsed.fork, cwd, sessionDir);\n\n\t\tswitch (resolved.type) {\n\t\t\tcase \"path\":\n\t\t\tcase \"local\":\n\t\t\tcase \"global\":\n\t\t\t\treturn forkSessionOrExit(resolved.path, cwd, sessionDir);\n\n\t\t\tcase \"not_found\":\n\t\t\t\tconsole.error(chalk.red(`No session found matching '${resolved.arg}'`));\n\t\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tif (parsed.session) {\n\t\tconst resolved = await resolveSessionPath(parsed.session, cwd, sessionDir);\n\n\t\tswitch (resolved.type) {\n\t\t\tcase \"path\":\n\t\t\tcase \"local\":\n\t\t\t\treturn SessionManager.open(resolved.path, sessionDir);\n\n\t\t\tcase \"global\": {\n\t\t\t\tconsole.log(chalk.yellow(`Session found in different project: ${resolved.cwd}`));\n\t\t\t\tconst shouldFork = await promptConfirm(\"Fork this session into current directory?\");\n\t\t\t\tif (!shouldFork) {\n\t\t\t\t\tconsole.log(chalk.dim(\"Aborted.\"));\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t}\n\t\t\t\treturn forkSessionOrExit(resolved.path, cwd, sessionDir);\n\t\t\t}\n\n\t\t\tcase \"not_found\":\n\t\t\t\tconsole.error(chalk.red(`No session found matching '${resolved.arg}'`));\n\t\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tif (parsed.resume) {\n\t\tinitTheme(settingsManager.getTheme(), true);\n\t\ttry {\n\t\t\tconst selectedPath = await selectSession(\n\t\t\t\t(onProgress) => SessionManager.list(cwd, sessionDir, onProgress),\n\t\t\t\tSessionManager.listAll,\n\t\t\t);\n\t\t\tif (!selectedPath) {\n\t\t\t\tconsole.log(chalk.dim(\"No session selected\"));\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\t\t\treturn SessionManager.open(selectedPath, sessionDir);\n\t\t} finally {\n\t\t\tstopThemeWatcher();\n\t\t}\n\t}\n\n\tif (parsed.continue) {\n\t\treturn SessionManager.continueRecent(cwd, sessionDir);\n\t}\n\n\treturn SessionManager.create(cwd, sessionDir);\n}\n\nfunction buildSessionOptions(\n\tparsed: Args,\n\tscopedModels: ScopedModel[],\n\thasExistingSession: boolean,\n\tmodelRegistry: ModelRegistry,\n\tsettingsManager: SettingsManager,\n): {\n\toptions: CreateAgentSessionOptions;\n\tcliThinkingFromModel: boolean;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n} {\n\tconst options: CreateAgentSessionOptions = {};\n\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [];\n\tlet cliThinkingFromModel = false;\n\n\t// Model from CLI\n\t// - supports --provider <name> --model <pattern>\n\t// - supports --model <provider>/<pattern>\n\tif (parsed.model) {\n\t\tconst resolved = resolveCliModel({\n\t\t\tcliProvider: parsed.provider,\n\t\t\tcliModel: parsed.model,\n\t\t\tmodelRegistry,\n\t\t});\n\t\tif (resolved.warning) {\n\t\t\tdiagnostics.push({ type: \"warning\", message: resolved.warning });\n\t\t}\n\t\tif (resolved.error) {\n\t\t\tdiagnostics.push({ type: \"error\", message: resolved.error });\n\t\t}\n\t\tif (resolved.model) {\n\t\t\toptions.model = resolved.model;\n\t\t\t// Allow \"--model <pattern>:<thinking>\" as a shorthand.\n\t\t\t// Explicit --thinking still takes precedence (applied later).\n\t\t\tif (!parsed.thinking && resolved.thinkingLevel) {\n\t\t\t\toptions.thinkingLevel = resolved.thinkingLevel;\n\t\t\t\tcliThinkingFromModel = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!options.model && scopedModels.length > 0 && !hasExistingSession) {\n\t\t// Check if saved default is in scoped models - use it if so, otherwise first scoped model\n\t\tconst savedProvider = settingsManager.getDefaultProvider();\n\t\tconst savedModelId = settingsManager.getDefaultModel();\n\t\tconst savedModel = savedProvider && savedModelId ? modelRegistry.find(savedProvider, savedModelId) : undefined;\n\t\tconst savedInScope = savedModel ? scopedModels.find((sm) => modelsAreEqual(sm.model, savedModel)) : undefined;\n\n\t\tif (savedInScope) {\n\t\t\toptions.model = savedInScope.model;\n\t\t\t// Use thinking level from scoped model config if explicitly set\n\t\t\tif (!parsed.thinking && savedInScope.thinkingLevel) {\n\t\t\t\toptions.thinkingLevel = savedInScope.thinkingLevel;\n\t\t\t}\n\t\t} else {\n\t\t\toptions.model = scopedModels[0].model;\n\t\t\t// Use thinking level from first scoped model if explicitly set\n\t\t\tif (!parsed.thinking && scopedModels[0].thinkingLevel) {\n\t\t\t\toptions.thinkingLevel = scopedModels[0].thinkingLevel;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Thinking level from CLI (takes precedence over scoped model thinking levels set above)\n\tif (parsed.thinking) {\n\t\toptions.thinkingLevel = parsed.thinking;\n\t}\n\n\t// Scoped models for Ctrl+P cycling\n\t// Keep thinking level undefined when not explicitly set in the model pattern.\n\t// Undefined means \"inherit current session thinking level\" during cycling.\n\tif (scopedModels.length > 0) {\n\t\toptions.scopedModels = scopedModels.map((sm) => ({\n\t\t\tmodel: sm.model,\n\t\t\tthinkingLevel: sm.thinkingLevel,\n\t\t}));\n\t}\n\n\t// API key from CLI - set in authStorage\n\t// (handled by caller before createAgentSession)\n\n\t// Tools\n\tif (parsed.noTools) {\n\t\toptions.noTools = \"all\";\n\t} else if (parsed.noBuiltinTools) {\n\t\toptions.noTools = \"builtin\";\n\t}\n\tif (parsed.tools) {\n\t\toptions.tools = [...parsed.tools];\n\t}\n\n\treturn { options, cliThinkingFromModel, diagnostics };\n}\n\nfunction resolveCliPaths(cwd: string, paths: string[] | undefined): string[] | undefined {\n\treturn paths?.map((value) => (isLocalPath(value) ? resolve(cwd, value) : value));\n}\n\nasync function promptForMissingSessionCwd(\n\tissue: SessionCwdIssue,\n\tsettingsManager: SettingsManager,\n): Promise<string | undefined> {\n\tinitTheme(settingsManager.getTheme());\n\tsetKeybindings(KeybindingsManager.create());\n\n\treturn new Promise((resolve) => {\n\t\tconst ui = new TUI(new ProcessTerminal(), settingsManager.getShowHardwareCursor());\n\t\tui.setClearOnShrink(settingsManager.getClearOnShrink());\n\n\t\tlet settled = false;\n\t\tconst finish = (result: string | undefined) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tui.stop();\n\t\t\tresolve(result);\n\t\t};\n\n\t\tconst selector = new ExtensionSelectorComponent(\n\t\t\tformatMissingSessionCwdPrompt(issue),\n\t\t\t[\"Continue\", \"Cancel\"],\n\t\t\t(option) => finish(option === \"Continue\" ? issue.fallbackCwd : undefined),\n\t\t\t() => finish(undefined),\n\t\t\t{ tui: ui },\n\t\t);\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector);\n\t\tui.start();\n\t});\n}\n\nexport interface MainOptions {\n\textensionFactories?: ExtensionFactory[];\n}\n\nexport async function main(args: string[], options?: MainOptions) {\n\tresetTimings();\n\tconst offlineMode = args.includes(\"--offline\") || isTruthyEnvFlag(process.env.PI_OFFLINE);\n\tif (offlineMode) {\n\t\tprocess.env.PI_OFFLINE = \"1\";\n\t\tprocess.env.PI_SKIP_VERSION_CHECK = \"1\";\n\t}\n\n\tif (await handlePackageCommand(args)) {\n\t\treturn;\n\t}\n\n\tif (await handleConfigCommand(args)) {\n\t\treturn;\n\t}\n\n\tconst parsed = parseArgs(args);\n\tif (parsed.diagnostics.length > 0) {\n\t\tfor (const d of parsed.diagnostics) {\n\t\t\tconst color = d.type === \"error\" ? chalk.red : chalk.yellow;\n\t\t\tconsole.error(color(`${d.type === \"error\" ? \"Error\" : \"Warning\"}: ${d.message}`));\n\t\t}\n\t\tif (parsed.diagnostics.some((d) => d.type === \"error\")) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\ttime(\"parseArgs\");\n\tlet appMode = resolveAppMode(parsed, process.stdin.isTTY);\n\tconst shouldTakeOverStdout = appMode !== \"interactive\";\n\tif (shouldTakeOverStdout) {\n\t\ttakeOverStdout();\n\t}\n\n\tif (parsed.version) {\n\t\tconsole.log(VERSION);\n\t\tprocess.exit(0);\n\t}\n\n\tif (parsed.export) {\n\t\tlet result: string;\n\t\ttry {\n\t\t\tconst outputPath = parsed.messages.length > 0 ? parsed.messages[0] : undefined;\n\t\t\tresult = await exportFromFile(parsed.export, outputPath);\n\t\t} catch (error: unknown) {\n\t\t\tconst message = error instanceof Error ? error.message : \"Failed to export session\";\n\t\t\tconsole.error(chalk.red(`Error: ${message}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tconsole.log(`Exported to: ${result}`);\n\t\tprocess.exit(0);\n\t}\n\n\tif (parsed.mode === \"rpc\" && parsed.fileArgs.length > 0) {\n\t\tconsole.error(chalk.red(\"Error: @file arguments are not supported in RPC mode\"));\n\t\tprocess.exit(1);\n\t}\n\n\tvalidateForkFlags(parsed);\n\n\t// Run migrations (pass cwd for project-local migrations)\n\tconst { migratedAuthProviders: migratedProviders, deprecationWarnings } = runMigrations(process.cwd());\n\ttime(\"runMigrations\");\n\n\tconst cwd = process.cwd();\n\tconst agentDir = getAgentDir();\n\tconst startupSettingsManager = SettingsManager.create(cwd, agentDir);\n\treportDiagnostics(collectSettingsDiagnostics(startupSettingsManager, \"startup session lookup\"));\n\n\t// Decide the final runtime cwd before creating cwd-bound runtime services.\n\t// --session and --resume may select a session from another project, so project-local\n\t// settings, resources, provider registrations, and models must be resolved only after\n\t// the target session cwd is known. The startup-cwd settings manager is used only for\n\t// sessionDir lookup during session selection.\n\tconst envSessionDir = process.env[ENV_SESSION_DIR];\n\tconst sessionDir =\n\t\tparsed.sessionDir ??\n\t\t(envSessionDir ? expandTildePath(envSessionDir) : undefined) ??\n\t\tstartupSettingsManager.getSessionDir();\n\tlet sessionManager = await createSessionManager(parsed, cwd, sessionDir, startupSettingsManager);\n\tconst missingSessionCwdIssue = getMissingSessionCwdIssue(sessionManager, cwd);\n\tif (missingSessionCwdIssue) {\n\t\tif (appMode === \"interactive\") {\n\t\t\tconst selectedCwd = await promptForMissingSessionCwd(missingSessionCwdIssue, startupSettingsManager);\n\t\t\tif (!selectedCwd) {\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\t\t\tsessionManager = SessionManager.open(missingSessionCwdIssue.sessionFile!, sessionDir, selectedCwd);\n\t\t} else {\n\t\t\tconsole.error(chalk.red(new MissingSessionCwdError(missingSessionCwdIssue).message));\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\ttime(\"createSessionManager\");\n\n\tconst resolvedExtensionPaths = resolveCliPaths(cwd, parsed.extensions);\n\tconst resolvedSkillPaths = resolveCliPaths(cwd, parsed.skills);\n\tconst resolvedPromptTemplatePaths = resolveCliPaths(cwd, parsed.promptTemplates);\n\tconst resolvedThemePaths = resolveCliPaths(cwd, parsed.themes);\n\tconst authStorage = AuthStorage.create();\n\tconst createRuntime: CreateAgentSessionRuntimeFactory = async ({\n\t\tcwd,\n\t\tagentDir,\n\t\tsessionManager,\n\t\tsessionStartEvent,\n\t}) => {\n\t\tconst services = await createAgentSessionServices({\n\t\t\tcwd,\n\t\t\tagentDir,\n\t\t\tauthStorage,\n\t\t\textensionFlagValues: parsed.unknownFlags,\n\t\t\tresourceLoaderOptions: {\n\t\t\t\tadditionalExtensionPaths: resolvedExtensionPaths,\n\t\t\t\tadditionalSkillPaths: resolvedSkillPaths,\n\t\t\t\tadditionalPromptTemplatePaths: resolvedPromptTemplatePaths,\n\t\t\t\tadditionalThemePaths: resolvedThemePaths,\n\t\t\t\tnoExtensions: parsed.noExtensions,\n\t\t\t\tnoSkills: parsed.noSkills,\n\t\t\t\tnoPromptTemplates: parsed.noPromptTemplates,\n\t\t\t\tnoThemes: parsed.noThemes,\n\t\t\t\tnoContextFiles: parsed.noContextFiles,\n\t\t\t\tsystemPrompt: parsed.systemPrompt,\n\t\t\t\tappendSystemPrompt: parsed.appendSystemPrompt,\n\t\t\t\textensionFactories: options?.extensionFactories,\n\t\t\t},\n\t\t});\n\t\tconst { settingsManager, modelRegistry, resourceLoader } = services;\n\t\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [\n\t\t\t...services.diagnostics,\n\t\t\t...collectSettingsDiagnostics(settingsManager, \"runtime creation\"),\n\t\t\t...resourceLoader.getExtensions().errors.map(({ path, error }) => ({\n\t\t\t\ttype: \"error\" as const,\n\t\t\t\tmessage: `Failed to load extension \"${path}\": ${error}`,\n\t\t\t})),\n\t\t];\n\n\t\tconst modelPatterns = parsed.models ?? settingsManager.getEnabledModels();\n\t\tconst scopedModels =\n\t\t\tmodelPatterns && modelPatterns.length > 0 ? await resolveModelScope(modelPatterns, modelRegistry) : [];\n\t\tconst {\n\t\t\toptions: sessionOptions,\n\t\t\tcliThinkingFromModel,\n\t\t\tdiagnostics: sessionOptionDiagnostics,\n\t\t} = buildSessionOptions(\n\t\t\tparsed,\n\t\t\tscopedModels,\n\t\t\tsessionManager.buildSessionContext().messages.length > 0,\n\t\t\tmodelRegistry,\n\t\t\tsettingsManager,\n\t\t);\n\t\tdiagnostics.push(...sessionOptionDiagnostics);\n\n\t\tif (parsed.apiKey) {\n\t\t\tif (!sessionOptions.model) {\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\ttype: \"error\",\n\t\t\t\t\tmessage: \"--api-key requires a model to be specified via --model, --provider/--model, or --models\",\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tauthStorage.setRuntimeApiKey(sessionOptions.model.provider, parsed.apiKey);\n\t\t\t}\n\t\t}\n\n\t\tconst created = await createAgentSessionFromServices({\n\t\t\tservices,\n\t\t\tsessionManager,\n\t\t\tsessionStartEvent,\n\t\t\tmodel: sessionOptions.model,\n\t\t\tthinkingLevel: sessionOptions.thinkingLevel,\n\t\t\tscopedModels: sessionOptions.scopedModels,\n\t\t\ttools: sessionOptions.tools,\n\t\t\tnoTools: sessionOptions.noTools,\n\t\t\tcustomTools: sessionOptions.customTools,\n\t\t});\n\t\tconst cliThinkingOverride = parsed.thinking !== undefined || cliThinkingFromModel;\n\t\tif (created.session.model && cliThinkingOverride) {\n\t\t\tcreated.session.setThinkingLevel(created.session.thinkingLevel);\n\t\t}\n\n\t\treturn {\n\t\t\t...created,\n\t\t\tservices,\n\t\t\tdiagnostics,\n\t\t};\n\t};\n\ttime(\"createRuntime\");\n\tconst runtime = await createAgentSessionRuntime(createRuntime, {\n\t\tcwd: sessionManager.getCwd(),\n\t\tagentDir,\n\t\tsessionManager,\n\t});\n\tconst { services, session, modelFallbackMessage } = runtime;\n\tconst { settingsManager, modelRegistry, resourceLoader } = services;\n\n\tif (parsed.help) {\n\t\tconst extensionFlags = resourceLoader\n\t\t\t.getExtensions()\n\t\t\t.extensions.flatMap((extension) => Array.from(extension.flags.values()));\n\t\tprintHelp(extensionFlags);\n\t\tprocess.exit(0);\n\t}\n\n\tif (parsed.listModels !== undefined) {\n\t\tconst searchPattern = typeof parsed.listModels === \"string\" ? parsed.listModels : undefined;\n\t\tawait listModels(modelRegistry, searchPattern);\n\t\tprocess.exit(0);\n\t}\n\n\t// Read piped stdin content (if any) - skip for RPC mode which uses stdin for JSON-RPC\n\tlet stdinContent: string | undefined;\n\tif (appMode !== \"rpc\") {\n\t\tstdinContent = await readPipedStdin();\n\t\tif (stdinContent !== undefined && appMode === \"interactive\") {\n\t\t\tappMode = \"print\";\n\t\t}\n\t}\n\ttime(\"readPipedStdin\");\n\n\tconst { initialMessage, initialImages } = await prepareInitialMessage(\n\t\tparsed,\n\t\tsettingsManager.getImageAutoResize(),\n\t\tstdinContent,\n\t);\n\ttime(\"prepareInitialMessage\");\n\tinitTheme(settingsManager.getTheme(), appMode === \"interactive\");\n\ttime(\"initTheme\");\n\n\t// Show deprecation warnings in interactive mode\n\tif (appMode === \"interactive\" && deprecationWarnings.length > 0) {\n\t\tawait showDeprecationWarnings(deprecationWarnings);\n\t}\n\n\tconst scopedModels = [...session.scopedModels];\n\ttime(\"resolveModelScope\");\n\treportDiagnostics(runtime.diagnostics);\n\tif (runtime.diagnostics.some((diagnostic) => diagnostic.type === \"error\")) {\n\t\tprocess.exit(1);\n\t}\n\ttime(\"createAgentSession\");\n\n\tif (appMode !== \"interactive\" && !session.model) {\n\t\tconsole.error(chalk.red(formatNoModelsAvailableMessage()));\n\t\tprocess.exit(1);\n\t}\n\n\tconst startupBenchmark = isTruthyEnvFlag(process.env.PI_STARTUP_BENCHMARK);\n\tif (startupBenchmark && appMode !== \"interactive\") {\n\t\tconsole.error(chalk.red(\"Error: PI_STARTUP_BENCHMARK only supports interactive mode\"));\n\t\tprocess.exit(1);\n\t}\n\n\tif (appMode === \"rpc\") {\n\t\tprintTimings();\n\t\tawait runRpcMode(runtime);\n\t} else if (appMode === \"interactive\") {\n\t\tif (scopedModels.length > 0 && (parsed.verbose || !settingsManager.getQuietStartup())) {\n\t\t\tconst modelList = scopedModels\n\t\t\t\t.map((sm) => {\n\t\t\t\t\tconst thinkingStr = sm.thinkingLevel ? `:${sm.thinkingLevel}` : \"\";\n\t\t\t\t\treturn `${sm.model.id}${thinkingStr}`;\n\t\t\t\t})\n\t\t\t\t.join(\", \");\n\t\t\tconsole.log(chalk.dim(`Model scope: ${modelList} ${chalk.gray(\"(Ctrl+P to cycle)\")}`));\n\t\t}\n\n\t\tconst interactiveMode = new InteractiveMode(runtime, {\n\t\t\tmigratedProviders,\n\t\t\tmodelFallbackMessage,\n\t\t\tinitialMessage,\n\t\t\tinitialImages,\n\t\t\tinitialMessages: parsed.messages,\n\t\t\tverbose: parsed.verbose,\n\t\t});\n\t\tif (startupBenchmark) {\n\t\t\tawait interactiveMode.init();\n\t\t\ttime(\"interactiveMode.init\");\n\t\t\tprintTimings();\n\t\t\tinteractiveMode.stop();\n\t\t\tstopThemeWatcher();\n\t\t\tif (process.stdout.writableLength > 0) {\n\t\t\t\tawait new Promise<void>((resolve) => process.stdout.once(\"drain\", resolve));\n\t\t\t}\n\t\t\tif (process.stderr.writableLength > 0) {\n\t\t\t\tawait new Promise<void>((resolve) => process.stderr.once(\"drain\", resolve));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tprintTimings();\n\t\tawait interactiveMode.run();\n\t} else {\n\t\tprintTimings();\n\t\tconst exitCode = await runPrintMode(runtime, {\n\t\t\tmode: toPrintOutputMode(appMode),\n\t\t\tmessages: parsed.messages,\n\t\t\tinitialMessage,\n\t\t\tinitialImages,\n\t\t});\n\t\tstopThemeWatcher();\n\t\trestoreStdout();\n\t\tif (exitCode !== 0) {\n\t\t\tprocess.exitCode = exitCode;\n\t\t}\n\t\treturn;\n\t}\n}\n"]}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAqBH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AA0bnE,MAAM,WAAW,WAAW;IAC3B,kBAAkB,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACxC;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,iBAiU/D","sourcesContent":["/**\n * Main entry point for the coding agent CLI.\n *\n * This file handles CLI argument parsing and translates them into\n * createAgentSession() options. The SDK does the heavy lifting.\n */\n\nimport { createInterface } from \"node:readline\";\nimport { type ImageContent, modelsAreEqual } from \"@sheason/pi-ai\";\nimport { ProcessTerminal, setKeybindings, TUI } from \"@sheason/pi-tui\";\nimport chalk from \"chalk\";\nimport { type Args, type Mode, parseArgs, printHelp } from \"./cli/args.ts\";\nimport { processFileArguments } from \"./cli/file-processor.ts\";\nimport { buildInitialMessage } from \"./cli/initial-message.ts\";\nimport { listModels } from \"./cli/list-models.ts\";\nimport { selectSession } from \"./cli/session-picker.ts\";\nimport { ENV_SESSION_DIR, expandTildePath, getAgentDir, getPackageDir, VERSION } from \"./config.ts\";\nimport { type CreateAgentSessionRuntimeFactory, createAgentSessionRuntime } from \"./core/agent-session-runtime.ts\";\nimport {\n\ttype AgentSessionRuntimeDiagnostic,\n\tcreateAgentSessionFromServices,\n\tcreateAgentSessionServices,\n} from \"./core/agent-session-services.ts\";\nimport { formatNoModelsAvailableMessage } from \"./core/auth-guidance.ts\";\nimport { AuthStorage } from \"./core/auth-storage.ts\";\nimport { exportFromFile } from \"./core/export-html/index.ts\";\nimport type { ExtensionFactory } from \"./core/extensions/types.ts\";\nimport { configureHttpDispatcher } from \"./core/http-dispatcher.ts\";\nimport { KeybindingsManager } from \"./core/keybindings.ts\";\nimport type { ModelRegistry } from \"./core/model-registry.ts\";\nimport { resolveCliModel, resolveModelScope, type ScopedModel } from \"./core/model-resolver.ts\";\nimport { restoreStdout, takeOverStdout } from \"./core/output-guard.ts\";\nimport type { CreateAgentSessionOptions } from \"./core/sdk.ts\";\nimport {\n\tformatMissingSessionCwdPrompt,\n\tgetMissingSessionCwdIssue,\n\tMissingSessionCwdError,\n\ttype SessionCwdIssue,\n} from \"./core/session-cwd.ts\";\nimport { assertValidSessionId, SessionManager } from \"./core/session-manager.ts\";\nimport { SettingsManager } from \"./core/settings-manager.ts\";\nimport { printTimings, resetTimings, time } from \"./core/timings.ts\";\nimport { runMigrations, showDeprecationWarnings } from \"./migrations.ts\";\nimport { InteractiveMode, runPrintMode, runRpcMode } from \"./modes/index.ts\";\nimport { ExtensionSelectorComponent } from \"./modes/interactive/components/extension-selector.ts\";\nimport { initTheme, stopThemeWatcher } from \"./modes/interactive/theme/theme.ts\";\nimport { handleConfigCommand, handlePackageCommand } from \"./package-manager-cli.ts\";\nimport { isLocalPath, normalizePath, resolvePath } from \"./utils/paths.ts\";\nimport { cleanupWindowsSelfUpdateQuarantine } from \"./utils/windows-self-update.ts\";\n\n/**\n * Read all content from piped stdin.\n * Returns undefined if stdin is a TTY (interactive terminal).\n */\nasync function readPipedStdin(): Promise<string | undefined> {\n\t// If stdin is a TTY, we're running interactively - don't read stdin\n\tif (process.stdin.isTTY) {\n\t\treturn undefined;\n\t}\n\n\treturn new Promise((resolve) => {\n\t\tlet data = \"\";\n\t\tprocess.stdin.setEncoding(\"utf8\");\n\t\tprocess.stdin.on(\"data\", (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\t\tprocess.stdin.on(\"end\", () => {\n\t\t\tresolve(data.trim() || undefined);\n\t\t});\n\t\tprocess.stdin.resume();\n\t});\n}\n\nfunction collectSettingsDiagnostics(\n\tsettingsManager: SettingsManager,\n\tcontext: string,\n): AgentSessionRuntimeDiagnostic[] {\n\treturn settingsManager.drainErrors().map(({ scope, error }) => ({\n\t\ttype: \"warning\",\n\t\tmessage: `(${context}, ${scope} settings) ${error.message}`,\n\t}));\n}\n\nfunction reportDiagnostics(diagnostics: readonly AgentSessionRuntimeDiagnostic[]): void {\n\tfor (const diagnostic of diagnostics) {\n\t\tconst color = diagnostic.type === \"error\" ? chalk.red : diagnostic.type === \"warning\" ? chalk.yellow : chalk.dim;\n\t\tconst prefix = diagnostic.type === \"error\" ? \"Error: \" : diagnostic.type === \"warning\" ? \"Warning: \" : \"\";\n\t\tconsole.error(color(`${prefix}${diagnostic.message}`));\n\t}\n}\n\nfunction isTruthyEnvFlag(value: string | undefined): boolean {\n\tif (!value) return false;\n\treturn value === \"1\" || value.toLowerCase() === \"true\" || value.toLowerCase() === \"yes\";\n}\n\ntype AppMode = \"interactive\" | \"print\" | \"json\" | \"rpc\" | \"serve\" | \"connect\";\n\nfunction resolveAppMode(parsed: Args, stdinIsTTY: boolean): AppMode {\n\tif (parsed.mode === \"rpc\") return \"rpc\";\n\tif (parsed.mode === \"serve\") return \"serve\";\n\tif (parsed.mode === \"connect\") return \"connect\";\n\tif (parsed.mode === \"json\") return \"json\";\n\tif (parsed.print || !stdinIsTTY) return \"print\";\n\treturn \"interactive\";\n}\n\nfunction toPrintOutputMode(appMode: AppMode): Exclude<Mode, \"rpc\" | \"serve\" | \"connect\"> {\n\treturn appMode === \"json\" ? \"json\" : \"text\";\n}\n\nasync function prepareInitialMessage(\n\tparsed: Args,\n\tautoResizeImages: boolean,\n\tstdinContent?: string,\n): Promise<{\n\tinitialMessage?: string;\n\tinitialImages?: ImageContent[];\n}> {\n\tif (parsed.fileArgs.length === 0) {\n\t\treturn buildInitialMessage({ parsed, stdinContent });\n\t}\n\n\tconst { text, images } = await processFileArguments(parsed.fileArgs, { autoResizeImages });\n\treturn buildInitialMessage({\n\t\tparsed,\n\t\tfileText: text,\n\t\tfileImages: images,\n\t\tstdinContent,\n\t});\n}\n\n/** Result from resolving a session argument */\ntype ResolvedSession =\n\t| { type: \"path\"; path: string } // Direct file path\n\t| { type: \"local\"; path: string } // Found in current project\n\t| { type: \"global\"; path: string; cwd: string } // Found in different project\n\t| { type: \"not_found\"; arg: string }; // Not found anywhere\n\n/**\n * Resolve a session argument to a file path.\n * If it looks like a path, use as-is. Otherwise try to match as session ID prefix.\n */\nasync function findLocalSessionByExactId(\n\tsessionId: string,\n\tcwd: string,\n\tsessionDir?: string,\n): Promise<{ type: \"local\"; path: string } | undefined> {\n\tconst localSessions = await SessionManager.list(cwd, sessionDir);\n\tconst localMatch = localSessions.find((s) => s.id === sessionId);\n\treturn localMatch ? { type: \"local\", path: localMatch.path } : undefined;\n}\n\nasync function resolveSessionPath(sessionArg: string, cwd: string, sessionDir?: string): Promise<ResolvedSession> {\n\t// If it looks like a file path, resolve it before handing it to the session manager.\n\tif (sessionArg.includes(\"/\") || sessionArg.includes(\"\\\\\") || sessionArg.endsWith(\".jsonl\")) {\n\t\treturn { type: \"path\", path: resolvePath(sessionArg, cwd) };\n\t}\n\n\t// Try to match as session ID in current project first\n\tconst localSessions = await SessionManager.list(cwd, sessionDir);\n\tconst localMatch =\n\t\tlocalSessions.find((s) => s.id === sessionArg) ?? localSessions.find((s) => s.id.startsWith(sessionArg));\n\n\tif (localMatch) {\n\t\treturn { type: \"local\", path: localMatch.path };\n\t}\n\n\t// Try global search across all projects\n\tconst allSessions = await SessionManager.listAll(sessionDir);\n\tconst globalMatch =\n\t\tallSessions.find((s) => s.id === sessionArg) ?? allSessions.find((s) => s.id.startsWith(sessionArg));\n\n\tif (globalMatch) {\n\t\treturn { type: \"global\", path: globalMatch.path, cwd: globalMatch.cwd };\n\t}\n\n\t// Not found anywhere\n\treturn { type: \"not_found\", arg: sessionArg };\n}\n\n/** Prompt user for yes/no confirmation */\nasync function promptConfirm(message: string): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst rl = createInterface({\n\t\t\tinput: process.stdin,\n\t\t\toutput: process.stdout,\n\t\t});\n\t\trl.question(`${message} [y/N] `, (answer) => {\n\t\t\trl.close();\n\t\t\tresolve(answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\");\n\t\t});\n\t});\n}\n\nfunction validateForkFlags(parsed: Args): void {\n\tif (!parsed.fork) return;\n\n\tconst conflictingFlags = [\n\t\tparsed.session ? \"--session\" : undefined,\n\t\tparsed.continue ? \"--continue\" : undefined,\n\t\tparsed.resume ? \"--resume\" : undefined,\n\t\tparsed.noSession ? \"--no-session\" : undefined,\n\t].filter((flag): flag is string => flag !== undefined);\n\n\tif (conflictingFlags.length > 0) {\n\t\tconsole.error(chalk.red(`Error: --fork cannot be combined with ${conflictingFlags.join(\", \")}`));\n\t\tprocess.exit(1);\n\t}\n}\n\nfunction validateSessionIdFlags(parsed: Args): void {\n\tif (parsed.sessionId === undefined) return;\n\n\tconst conflictingFlags = [\n\t\tparsed.session ? \"--session\" : undefined,\n\t\tparsed.continue ? \"--continue\" : undefined,\n\t\tparsed.resume ? \"--resume\" : undefined,\n\t\tparsed.noSession ? \"--no-session\" : undefined,\n\t].filter((flag): flag is string => flag !== undefined);\n\n\tif (conflictingFlags.length > 0) {\n\t\tconsole.error(chalk.red(`Error: --session-id cannot be combined with ${conflictingFlags.join(\", \")}`));\n\t\tprocess.exit(1);\n\t}\n\n\ttry {\n\t\tassertValidSessionId(parsed.sessionId);\n\t} catch (error: unknown) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconsole.error(chalk.red(`Error: ${message}`));\n\t\tprocess.exit(1);\n\t}\n}\n\nfunction forkSessionOrExit(sourcePath: string, cwd: string, sessionDir?: string, sessionId?: string): SessionManager {\n\ttry {\n\t\treturn SessionManager.forkFrom(sourcePath, cwd, sessionDir, { id: sessionId });\n\t} catch (error: unknown) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconsole.error(chalk.red(`Error: ${message}`));\n\t\tprocess.exit(1);\n\t}\n}\n\nasync function createSessionManager(\n\tparsed: Args,\n\tcwd: string,\n\tsessionDir: string | undefined,\n\tsettingsManager: SettingsManager,\n): Promise<SessionManager> {\n\tif (parsed.noSession || parsed.help || parsed.listModels !== undefined) {\n\t\treturn SessionManager.inMemory(cwd);\n\t}\n\n\tif (parsed.fork) {\n\t\tif (parsed.sessionId) {\n\t\t\tconst existingTarget = await findLocalSessionByExactId(parsed.sessionId, cwd, sessionDir);\n\t\t\tif (existingTarget) {\n\t\t\t\tconsole.error(chalk.red(`Session already exists with id '${parsed.sessionId}'`));\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t}\n\n\t\tconst resolved = await resolveSessionPath(parsed.fork, cwd, sessionDir);\n\n\t\tswitch (resolved.type) {\n\t\t\tcase \"path\":\n\t\t\tcase \"local\":\n\t\t\tcase \"global\":\n\t\t\t\treturn forkSessionOrExit(resolved.path, cwd, sessionDir, parsed.sessionId);\n\n\t\t\tcase \"not_found\":\n\t\t\t\tconsole.error(chalk.red(`No session found matching '${resolved.arg}'`));\n\t\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tif (parsed.session) {\n\t\tconst resolved = await resolveSessionPath(parsed.session, cwd, sessionDir);\n\n\t\tswitch (resolved.type) {\n\t\t\tcase \"path\":\n\t\t\tcase \"local\":\n\t\t\t\treturn SessionManager.open(resolved.path, sessionDir);\n\n\t\t\tcase \"global\": {\n\t\t\t\tconsole.log(chalk.yellow(`Session found in different project: ${resolved.cwd}`));\n\t\t\t\tconst shouldFork = await promptConfirm(\"Fork this session into current directory?\");\n\t\t\t\tif (!shouldFork) {\n\t\t\t\t\tconsole.log(chalk.dim(\"Aborted.\"));\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t}\n\t\t\t\treturn forkSessionOrExit(resolved.path, cwd, sessionDir);\n\t\t\t}\n\n\t\t\tcase \"not_found\":\n\t\t\t\tconsole.error(chalk.red(`No session found matching '${resolved.arg}'`));\n\t\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tif (parsed.resume) {\n\t\tinitTheme(settingsManager.getTheme(), true);\n\t\ttry {\n\t\t\tconst selectedPath = await selectSession(\n\t\t\t\t(onProgress) => SessionManager.list(cwd, sessionDir, onProgress),\n\t\t\t\t(onProgress) => SessionManager.listAll(sessionDir, onProgress),\n\t\t\t);\n\t\t\tif (!selectedPath) {\n\t\t\t\tconsole.log(chalk.dim(\"No session selected\"));\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\t\t\treturn SessionManager.open(selectedPath, sessionDir);\n\t\t} finally {\n\t\t\tstopThemeWatcher();\n\t\t}\n\t}\n\n\tif (parsed.continue) {\n\t\treturn SessionManager.continueRecent(cwd, sessionDir);\n\t}\n\n\tif (parsed.sessionId) {\n\t\tconst existingSession = await findLocalSessionByExactId(parsed.sessionId, cwd, sessionDir);\n\t\tif (existingSession) {\n\t\t\treturn SessionManager.open(existingSession.path, sessionDir);\n\t\t}\n\t}\n\n\treturn SessionManager.create(cwd, sessionDir, { id: parsed.sessionId });\n}\n\nfunction buildSessionOptions(\n\tparsed: Args,\n\tscopedModels: ScopedModel[],\n\thasExistingSession: boolean,\n\tmodelRegistry: ModelRegistry,\n\tsettingsManager: SettingsManager,\n): {\n\toptions: CreateAgentSessionOptions;\n\tcliThinkingFromModel: boolean;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n} {\n\tconst options: CreateAgentSessionOptions = {};\n\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [];\n\tlet cliThinkingFromModel = false;\n\n\t// Model from CLI\n\t// - supports --provider <name> --model <pattern>\n\t// - supports --model <provider>/<pattern>\n\tif (parsed.model) {\n\t\tconst resolved = resolveCliModel({\n\t\t\tcliProvider: parsed.provider,\n\t\t\tcliModel: parsed.model,\n\t\t\tmodelRegistry,\n\t\t});\n\t\tif (resolved.warning) {\n\t\t\tdiagnostics.push({ type: \"warning\", message: resolved.warning });\n\t\t}\n\t\tif (resolved.error) {\n\t\t\tdiagnostics.push({ type: \"error\", message: resolved.error });\n\t\t}\n\t\tif (resolved.model) {\n\t\t\toptions.model = resolved.model;\n\t\t\t// Allow \"--model <pattern>:<thinking>\" as a shorthand.\n\t\t\t// Explicit --thinking still takes precedence (applied later).\n\t\t\tif (!parsed.thinking && resolved.thinkingLevel) {\n\t\t\t\toptions.thinkingLevel = resolved.thinkingLevel;\n\t\t\t\tcliThinkingFromModel = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!options.model && scopedModels.length > 0 && !hasExistingSession) {\n\t\t// Check if saved default is in scoped models - use it if so, otherwise first scoped model\n\t\tconst savedProvider = settingsManager.getDefaultProvider();\n\t\tconst savedModelId = settingsManager.getDefaultModel();\n\t\tconst savedModel = savedProvider && savedModelId ? modelRegistry.find(savedProvider, savedModelId) : undefined;\n\t\tconst savedInScope = savedModel ? scopedModels.find((sm) => modelsAreEqual(sm.model, savedModel)) : undefined;\n\n\t\tif (savedInScope) {\n\t\t\toptions.model = savedInScope.model;\n\t\t\t// Use thinking level from scoped model config if explicitly set\n\t\t\tif (!parsed.thinking && savedInScope.thinkingLevel) {\n\t\t\t\toptions.thinkingLevel = savedInScope.thinkingLevel;\n\t\t\t}\n\t\t} else {\n\t\t\toptions.model = scopedModels[0].model;\n\t\t\t// Use thinking level from first scoped model if explicitly set\n\t\t\tif (!parsed.thinking && scopedModels[0].thinkingLevel) {\n\t\t\t\toptions.thinkingLevel = scopedModels[0].thinkingLevel;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Thinking level from CLI (takes precedence over scoped model thinking levels set above)\n\tif (parsed.thinking) {\n\t\toptions.thinkingLevel = parsed.thinking;\n\t}\n\n\t// Scoped models for Ctrl+P cycling\n\t// Keep thinking level undefined when not explicitly set in the model pattern.\n\t// Undefined means \"inherit current session thinking level\" during cycling.\n\tif (scopedModels.length > 0) {\n\t\toptions.scopedModels = scopedModels.map((sm) => ({\n\t\t\tmodel: sm.model,\n\t\t\tthinkingLevel: sm.thinkingLevel,\n\t\t}));\n\t}\n\n\t// API key from CLI - set in authStorage\n\t// (handled by caller before createAgentSession)\n\n\t// Tools\n\tif (parsed.noTools) {\n\t\toptions.noTools = \"all\";\n\t} else if (parsed.noBuiltinTools) {\n\t\toptions.noTools = \"builtin\";\n\t}\n\tif (parsed.tools) {\n\t\toptions.tools = [...parsed.tools];\n\t}\n\tif (parsed.excludeTools) {\n\t\toptions.excludeTools = [...parsed.excludeTools];\n\t}\n\n\treturn { options, cliThinkingFromModel, diagnostics };\n}\n\nfunction resolveCliPaths(cwd: string, paths: string[] | undefined): string[] | undefined {\n\treturn paths?.map((value) => (isLocalPath(value) ? resolvePath(value, cwd) : value));\n}\n\nasync function promptForMissingSessionCwd(\n\tissue: SessionCwdIssue,\n\tsettingsManager: SettingsManager,\n): Promise<string | undefined> {\n\tinitTheme(settingsManager.getTheme());\n\tsetKeybindings(KeybindingsManager.create());\n\n\treturn new Promise((resolve) => {\n\t\tconst ui = new TUI(new ProcessTerminal(), settingsManager.getShowHardwareCursor());\n\t\tui.setClearOnShrink(settingsManager.getClearOnShrink());\n\n\t\tlet settled = false;\n\t\tconst finish = (result: string | undefined) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tui.stop();\n\t\t\tresolve(result);\n\t\t};\n\n\t\tconst selector = new ExtensionSelectorComponent(\n\t\t\tformatMissingSessionCwdPrompt(issue),\n\t\t\t[\"Continue\", \"Cancel\"],\n\t\t\t(option) => finish(option === \"Continue\" ? issue.fallbackCwd : undefined),\n\t\t\t() => finish(undefined),\n\t\t\t{ tui: ui },\n\t\t);\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector);\n\t\tui.start();\n\t});\n}\n\nexport interface MainOptions {\n\textensionFactories?: ExtensionFactory[];\n}\n\nexport async function main(args: string[], options?: MainOptions) {\n\tresetTimings();\n\tconst offlineMode = args.includes(\"--offline\") || isTruthyEnvFlag(process.env.PI_OFFLINE);\n\tif (offlineMode) {\n\t\tprocess.env.PI_OFFLINE = \"1\";\n\t\tprocess.env.PI_SKIP_VERSION_CHECK = \"1\";\n\t}\n\n\tif (process.platform === \"win32\") {\n\t\tcleanupWindowsSelfUpdateQuarantine(getPackageDir());\n\t}\n\n\tif (await handlePackageCommand(args)) {\n\t\treturn;\n\t}\n\n\tif (await handleConfigCommand(args)) {\n\t\treturn;\n\t}\n\n\tconst parsed = parseArgs(args);\n\tif (parsed.diagnostics.length > 0) {\n\t\tfor (const d of parsed.diagnostics) {\n\t\t\tconst color = d.type === \"error\" ? chalk.red : chalk.yellow;\n\t\t\tconsole.error(color(`${d.type === \"error\" ? \"Error\" : \"Warning\"}: ${d.message}`));\n\t\t}\n\t\tif (parsed.diagnostics.some((d) => d.type === \"error\")) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\ttime(\"parseArgs\");\n\tlet appMode = resolveAppMode(parsed, process.stdin.isTTY);\n\tconst shouldTakeOverStdout = appMode !== \"interactive\";\n\tif (shouldTakeOverStdout) {\n\t\ttakeOverStdout();\n\t}\n\n\tif (parsed.version) {\n\t\tconsole.log(VERSION);\n\t\tprocess.exit(0);\n\t}\n\n\tif (parsed.export) {\n\t\tlet result: string;\n\t\ttry {\n\t\t\tconst outputPath = parsed.messages.length > 0 ? parsed.messages[0] : undefined;\n\t\t\tresult = await exportFromFile(parsed.export, outputPath);\n\t\t} catch (error: unknown) {\n\t\t\tconst message = error instanceof Error ? error.message : \"Failed to export session\";\n\t\t\tconsole.error(chalk.red(`Error: ${message}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tconsole.log(`Exported to: ${result}`);\n\t\tprocess.exit(0);\n\t}\n\n\tif (parsed.mode === \"rpc\" && parsed.fileArgs.length > 0) {\n\t\tconsole.error(chalk.red(\"Error: @file arguments are not supported in RPC mode\"));\n\t\tprocess.exit(1);\n\t}\n\n\tvalidateForkFlags(parsed);\n\tvalidateSessionIdFlags(parsed);\n\n\t// Run migrations (pass cwd for project-local migrations)\n\tconst { migratedAuthProviders: migratedProviders, deprecationWarnings } = runMigrations(process.cwd());\n\ttime(\"runMigrations\");\n\n\tconst cwd = process.cwd();\n\tconst agentDir = getAgentDir();\n\tconst startupSettingsManager = SettingsManager.create(cwd, agentDir);\n\treportDiagnostics(collectSettingsDiagnostics(startupSettingsManager, \"startup session lookup\"));\n\n\t// Decide the final runtime cwd before creating cwd-bound runtime services.\n\t// --session and --resume may select a session from another project, so project-local\n\t// settings, resources, provider registrations, and models must be resolved only after\n\t// the target session cwd is known. The startup-cwd settings manager is used only for\n\t// sessionDir lookup during session selection.\n\tconst envSessionDir = process.env[ENV_SESSION_DIR];\n\tconst sessionDir =\n\t\t(parsed.sessionDir ? normalizePath(parsed.sessionDir) : undefined) ??\n\t\t(envSessionDir ? expandTildePath(envSessionDir) : undefined) ??\n\t\tstartupSettingsManager.getSessionDir();\n\tlet sessionManager = await createSessionManager(parsed, cwd, sessionDir, startupSettingsManager);\n\tconst missingSessionCwdIssue = getMissingSessionCwdIssue(sessionManager, cwd);\n\tif (missingSessionCwdIssue) {\n\t\tif (appMode === \"interactive\") {\n\t\t\tconst selectedCwd = await promptForMissingSessionCwd(missingSessionCwdIssue, startupSettingsManager);\n\t\t\tif (!selectedCwd) {\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\t\t\tsessionManager = SessionManager.open(missingSessionCwdIssue.sessionFile!, sessionDir, selectedCwd);\n\t\t} else {\n\t\t\tconsole.error(chalk.red(new MissingSessionCwdError(missingSessionCwdIssue).message));\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\tif (parsed.name !== undefined) {\n\t\tconst name = parsed.name.trim();\n\t\tif (!name) {\n\t\t\tconsole.error(chalk.red(\"Error: --name requires a non-empty value\"));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tsessionManager.appendSessionInfo(name);\n\t}\n\ttime(\"createSessionManager\");\n\n\t// Extensions load normally in serve mode — tool registration and event\n\t// subscriptions work without UI. UI calls degrade to no-ops via noOpUIContext.\n\tconst resolvedExtensionPaths = resolveCliPaths(cwd, parsed.extensions);\n\tconst resolvedSkillPaths = resolveCliPaths(cwd, parsed.skills);\n\tconst resolvedPromptTemplatePaths = resolveCliPaths(cwd, parsed.promptTemplates);\n\tconst resolvedThemePaths = resolveCliPaths(cwd, parsed.themes);\n\tconst authStorage = AuthStorage.create();\n\tconst createRuntime: CreateAgentSessionRuntimeFactory = async ({\n\t\tcwd,\n\t\tagentDir,\n\t\tsessionManager,\n\t\tsessionStartEvent,\n\t}) => {\n\t\tconst services = await createAgentSessionServices({\n\t\t\tcwd,\n\t\t\tagentDir,\n\t\t\tauthStorage,\n\t\t\textensionFlagValues: parsed.unknownFlags,\n\t\t\tresourceLoaderOptions: {\n\t\t\t\tadditionalExtensionPaths: resolvedExtensionPaths,\n\t\t\t\tadditionalSkillPaths: resolvedSkillPaths,\n\t\t\t\tadditionalPromptTemplatePaths: resolvedPromptTemplatePaths,\n\t\t\t\tadditionalThemePaths: resolvedThemePaths,\n\t\t\t\tnoExtensions: parsed.noExtensions,\n\t\t\t\tnoSkills: parsed.noSkills,\n\t\t\t\tnoPromptTemplates: parsed.noPromptTemplates,\n\t\t\t\tnoThemes: parsed.noThemes,\n\t\t\t\tnoContextFiles: parsed.noContextFiles,\n\t\t\t\tsystemPrompt: parsed.systemPrompt,\n\t\t\t\tappendSystemPrompt: parsed.appendSystemPrompt,\n\t\t\t\textensionFactories: options?.extensionFactories,\n\t\t\t},\n\t\t});\n\t\tconst { settingsManager, modelRegistry, resourceLoader } = services;\n\t\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [\n\t\t\t...services.diagnostics,\n\t\t\t...collectSettingsDiagnostics(settingsManager, \"runtime creation\"),\n\t\t\t...resourceLoader.getExtensions().errors.map(({ path, error }) => ({\n\t\t\t\ttype: \"error\" as const,\n\t\t\t\tmessage: `Failed to load extension \"${path}\": ${error}`,\n\t\t\t})),\n\t\t];\n\n\t\tconst modelPatterns = parsed.models ?? settingsManager.getEnabledModels();\n\t\tconst scopedModels =\n\t\t\tmodelPatterns && modelPatterns.length > 0 ? await resolveModelScope(modelPatterns, modelRegistry) : [];\n\t\tconst {\n\t\t\toptions: sessionOptions,\n\t\t\tcliThinkingFromModel,\n\t\t\tdiagnostics: sessionOptionDiagnostics,\n\t\t} = buildSessionOptions(\n\t\t\tparsed,\n\t\t\tscopedModels,\n\t\t\tsessionManager.buildSessionContext().messages.length > 0,\n\t\t\tmodelRegistry,\n\t\t\tsettingsManager,\n\t\t);\n\t\tdiagnostics.push(...sessionOptionDiagnostics);\n\n\t\tif (parsed.apiKey) {\n\t\t\tif (!sessionOptions.model) {\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\ttype: \"error\",\n\t\t\t\t\tmessage: \"--api-key requires a model to be specified via --model, --provider/--model, or --models\",\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tauthStorage.setRuntimeApiKey(sessionOptions.model.provider, parsed.apiKey);\n\t\t\t}\n\t\t}\n\n\t\tconst created = await createAgentSessionFromServices({\n\t\t\tservices,\n\t\t\tsessionManager,\n\t\t\tsessionStartEvent,\n\t\t\tmodel: sessionOptions.model,\n\t\t\tthinkingLevel: sessionOptions.thinkingLevel,\n\t\t\tscopedModels: sessionOptions.scopedModels,\n\t\t\ttools: sessionOptions.tools,\n\t\t\texcludeTools: sessionOptions.excludeTools,\n\t\t\tnoTools: sessionOptions.noTools,\n\t\t\tcustomTools: sessionOptions.customTools,\n\t\t});\n\t\tconst cliThinkingOverride = parsed.thinking !== undefined || cliThinkingFromModel;\n\t\tif (created.session.model && cliThinkingOverride) {\n\t\t\tcreated.session.setThinkingLevel(created.session.thinkingLevel);\n\t\t}\n\n\t\treturn {\n\t\t\t...created,\n\t\t\tservices,\n\t\t\tdiagnostics,\n\t\t};\n\t};\n\ttime(\"createRuntime\");\n\tconst runtime = await createAgentSessionRuntime(createRuntime, {\n\t\tcwd: sessionManager.getCwd(),\n\t\tagentDir,\n\t\tsessionManager,\n\t});\n\ttime(\"createAgentSessionRuntime\");\n\tconst { services, session, modelFallbackMessage } = runtime;\n\tconst { settingsManager, modelRegistry, resourceLoader } = services;\n\tconfigureHttpDispatcher(settingsManager.getHttpIdleTimeoutMs());\n\n\tif (parsed.help) {\n\t\tconst extensionFlags = resourceLoader\n\t\t\t.getExtensions()\n\t\t\t.extensions.flatMap((extension) => Array.from(extension.flags.values()));\n\t\tprintHelp(extensionFlags);\n\t\tprocess.exit(0);\n\t}\n\n\tif (parsed.listModels !== undefined) {\n\t\tconst searchPattern = typeof parsed.listModels === \"string\" ? parsed.listModels : undefined;\n\t\tawait listModels(modelRegistry, searchPattern);\n\t\tprocess.exit(0);\n\t}\n\n\t// Read piped stdin content (if any) - skip for RPC mode which uses stdin for JSON-RPC\n\tlet stdinContent: string | undefined;\n\tif (appMode !== \"rpc\") {\n\t\tstdinContent = await readPipedStdin();\n\t\tif (stdinContent !== undefined && appMode === \"interactive\") {\n\t\t\tappMode = \"print\";\n\t\t}\n\t}\n\ttime(\"readPipedStdin\");\n\n\tconst { initialMessage, initialImages } = await prepareInitialMessage(\n\t\tparsed,\n\t\tsettingsManager.getImageAutoResize(),\n\t\tstdinContent,\n\t);\n\ttime(\"prepareInitialMessage\");\n\tinitTheme(settingsManager.getTheme(), appMode === \"interactive\");\n\ttime(\"initTheme\");\n\n\t// Show deprecation warnings in interactive mode\n\tif (appMode === \"interactive\" && deprecationWarnings.length > 0) {\n\t\tawait showDeprecationWarnings(deprecationWarnings);\n\t}\n\n\ttime(\"resolveModelScope\");\n\treportDiagnostics(runtime.diagnostics);\n\tif (runtime.diagnostics.some((diagnostic) => diagnostic.type === \"error\")) {\n\t\tprocess.exit(1);\n\t}\n\ttime(\"createAgentSession\");\n\n\tif (appMode !== \"interactive\" && !session.model) {\n\t\tconsole.error(chalk.red(formatNoModelsAvailableMessage()));\n\t\tprocess.exit(1);\n\t}\n\n\tconst startupBenchmark = isTruthyEnvFlag(process.env.PI_STARTUP_BENCHMARK);\n\tif (startupBenchmark && appMode !== \"interactive\") {\n\t\tconsole.error(chalk.red(\"Error: PI_STARTUP_BENCHMARK only supports interactive mode\"));\n\t\tprocess.exit(1);\n\t}\n\n\tif (appMode === \"serve\") {\n\t\tconst { runServeMode } = await import(\"./modes/serve/serve-mode.ts\");\n\t\tawait runServeMode(runtime, { port: parsed.port });\n\t\treturn;\n\t}\n\tif (appMode === \"connect\") {\n\t\tconst { runConnectMode } = await import(\"./modes/connect/connect-mode.ts\");\n\t\tawait runConnectMode({ url: parsed.url! });\n\t\treturn;\n\t}\n\tif (appMode === \"rpc\") {\n\t\tprintTimings();\n\t\tawait runRpcMode(runtime);\n\t} else if (appMode === \"interactive\") {\n\t\tconst interactiveMode = new InteractiveMode(runtime, {\n\t\t\tmigratedProviders,\n\t\t\tmodelFallbackMessage,\n\t\t\tinitialMessage,\n\t\t\tinitialImages,\n\t\t\tinitialMessages: parsed.messages,\n\t\t\tverbose: parsed.verbose,\n\t\t});\n\t\tif (startupBenchmark) {\n\t\t\tawait interactiveMode.init();\n\t\t\ttime(\"interactiveMode.init\");\n\t\t\tprintTimings();\n\t\t\tinteractiveMode.stop();\n\t\t\tstopThemeWatcher();\n\t\t\tif (process.stdout.writableLength > 0) {\n\t\t\t\tawait new Promise<void>((resolve) => process.stdout.once(\"drain\", resolve));\n\t\t\t}\n\t\t\tif (process.stderr.writableLength > 0) {\n\t\t\t\tawait new Promise<void>((resolve) => process.stderr.once(\"drain\", resolve));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tprintTimings();\n\t\tawait interactiveMode.run();\n\t} else {\n\t\tprintTimings();\n\t\tconst exitCode = await runPrintMode(runtime, {\n\t\t\tmode: toPrintOutputMode(appMode),\n\t\t\tmessages: parsed.messages,\n\t\t\tinitialMessage,\n\t\t\tinitialImages,\n\t\t});\n\t\tstopThemeWatcher();\n\t\trestoreStdout();\n\t\tif (exitCode !== 0) {\n\t\t\tprocess.exitCode = exitCode;\n\t\t}\n\t\treturn;\n\t}\n}\n"]}
package/dist/main.js CHANGED
@@ -4,7 +4,6 @@
4
4
  * This file handles CLI argument parsing and translates them into
5
5
  * createAgentSession() options. The SDK does the heavy lifting.
6
6
  */
7
- import { resolve } from "node:path";
8
7
  import { createInterface } from "node:readline";
9
8
  import { modelsAreEqual } from "@sheason/pi-ai";
10
9
  import { ProcessTerminal, setKeybindings, TUI } from "@sheason/pi-tui";
@@ -14,17 +13,18 @@ import { processFileArguments } from "./cli/file-processor.js";
14
13
  import { buildInitialMessage } from "./cli/initial-message.js";
15
14
  import { listModels } from "./cli/list-models.js";
16
15
  import { selectSession } from "./cli/session-picker.js";
17
- import { ENV_SESSION_DIR, expandTildePath, getAgentDir, VERSION } from "./config.js";
16
+ import { ENV_SESSION_DIR, expandTildePath, getAgentDir, getPackageDir, VERSION } from "./config.js";
18
17
  import { createAgentSessionRuntime } from "./core/agent-session-runtime.js";
19
18
  import { createAgentSessionFromServices, createAgentSessionServices, } from "./core/agent-session-services.js";
20
19
  import { formatNoModelsAvailableMessage } from "./core/auth-guidance.js";
21
20
  import { AuthStorage } from "./core/auth-storage.js";
22
21
  import { exportFromFile } from "./core/export-html/index.js";
22
+ import { configureHttpDispatcher } from "./core/http-dispatcher.js";
23
23
  import { KeybindingsManager } from "./core/keybindings.js";
24
24
  import { resolveCliModel, resolveModelScope } from "./core/model-resolver.js";
25
25
  import { restoreStdout, takeOverStdout } from "./core/output-guard.js";
26
26
  import { formatMissingSessionCwdPrompt, getMissingSessionCwdIssue, MissingSessionCwdError, } from "./core/session-cwd.js";
27
- import { SessionManager } from "./core/session-manager.js";
27
+ import { assertValidSessionId, SessionManager } from "./core/session-manager.js";
28
28
  import { SettingsManager } from "./core/settings-manager.js";
29
29
  import { printTimings, resetTimings, time } from "./core/timings.js";
30
30
  import { runMigrations, showDeprecationWarnings } from "./migrations.js";
@@ -32,7 +32,8 @@ import { InteractiveMode, runPrintMode, runRpcMode } from "./modes/index.js";
32
32
  import { ExtensionSelectorComponent } from "./modes/interactive/components/extension-selector.js";
33
33
  import { initTheme, stopThemeWatcher } from "./modes/interactive/theme/theme.js";
34
34
  import { handleConfigCommand, handlePackageCommand } from "./package-manager-cli.js";
35
- import { isLocalPath } from "./utils/paths.js";
35
+ import { isLocalPath, normalizePath, resolvePath } from "./utils/paths.js";
36
+ import { cleanupWindowsSelfUpdateQuarantine } from "./utils/windows-self-update.js";
36
37
  /**
37
38
  * Read all content from piped stdin.
38
39
  * Returns undefined if stdin is a TTY (interactive terminal).
@@ -73,15 +74,16 @@ function isTruthyEnvFlag(value) {
73
74
  return value === "1" || value.toLowerCase() === "true" || value.toLowerCase() === "yes";
74
75
  }
75
76
  function resolveAppMode(parsed, stdinIsTTY) {
76
- if (parsed.mode === "rpc") {
77
+ if (parsed.mode === "rpc")
77
78
  return "rpc";
78
- }
79
- if (parsed.mode === "json") {
79
+ if (parsed.mode === "serve")
80
+ return "serve";
81
+ if (parsed.mode === "connect")
82
+ return "connect";
83
+ if (parsed.mode === "json")
80
84
  return "json";
81
- }
82
- if (parsed.print || !stdinIsTTY) {
85
+ if (parsed.print || !stdinIsTTY)
83
86
  return "print";
84
- }
85
87
  return "interactive";
86
88
  }
87
89
  function toPrintOutputMode(appMode) {
@@ -103,23 +105,27 @@ async function prepareInitialMessage(parsed, autoResizeImages, stdinContent) {
103
105
  * Resolve a session argument to a file path.
104
106
  * If it looks like a path, use as-is. Otherwise try to match as session ID prefix.
105
107
  */
108
+ async function findLocalSessionByExactId(sessionId, cwd, sessionDir) {
109
+ const localSessions = await SessionManager.list(cwd, sessionDir);
110
+ const localMatch = localSessions.find((s) => s.id === sessionId);
111
+ return localMatch ? { type: "local", path: localMatch.path } : undefined;
112
+ }
106
113
  async function resolveSessionPath(sessionArg, cwd, sessionDir) {
107
- // If it looks like a file path, use as-is
114
+ // If it looks like a file path, resolve it before handing it to the session manager.
108
115
  if (sessionArg.includes("/") || sessionArg.includes("\\") || sessionArg.endsWith(".jsonl")) {
109
- return { type: "path", path: sessionArg };
116
+ return { type: "path", path: resolvePath(sessionArg, cwd) };
110
117
  }
111
118
  // Try to match as session ID in current project first
112
119
  const localSessions = await SessionManager.list(cwd, sessionDir);
113
- const localMatches = localSessions.filter((s) => s.id.startsWith(sessionArg));
114
- if (localMatches.length >= 1) {
115
- return { type: "local", path: localMatches[0].path };
120
+ const localMatch = localSessions.find((s) => s.id === sessionArg) ?? localSessions.find((s) => s.id.startsWith(sessionArg));
121
+ if (localMatch) {
122
+ return { type: "local", path: localMatch.path };
116
123
  }
117
124
  // Try global search across all projects
118
- const allSessions = await SessionManager.listAll();
119
- const globalMatches = allSessions.filter((s) => s.id.startsWith(sessionArg));
120
- if (globalMatches.length >= 1) {
121
- const match = globalMatches[0];
122
- return { type: "global", path: match.path, cwd: match.cwd };
125
+ const allSessions = await SessionManager.listAll(sessionDir);
126
+ const globalMatch = allSessions.find((s) => s.id === sessionArg) ?? allSessions.find((s) => s.id.startsWith(sessionArg));
127
+ if (globalMatch) {
128
+ return { type: "global", path: globalMatch.path, cwd: globalMatch.cwd };
123
129
  }
124
130
  // Not found anywhere
125
131
  return { type: "not_found", arg: sessionArg };
@@ -151,9 +157,31 @@ function validateForkFlags(parsed) {
151
157
  process.exit(1);
152
158
  }
153
159
  }
154
- function forkSessionOrExit(sourcePath, cwd, sessionDir) {
160
+ function validateSessionIdFlags(parsed) {
161
+ if (parsed.sessionId === undefined)
162
+ return;
163
+ const conflictingFlags = [
164
+ parsed.session ? "--session" : undefined,
165
+ parsed.continue ? "--continue" : undefined,
166
+ parsed.resume ? "--resume" : undefined,
167
+ parsed.noSession ? "--no-session" : undefined,
168
+ ].filter((flag) => flag !== undefined);
169
+ if (conflictingFlags.length > 0) {
170
+ console.error(chalk.red(`Error: --session-id cannot be combined with ${conflictingFlags.join(", ")}`));
171
+ process.exit(1);
172
+ }
155
173
  try {
156
- return SessionManager.forkFrom(sourcePath, cwd, sessionDir);
174
+ assertValidSessionId(parsed.sessionId);
175
+ }
176
+ catch (error) {
177
+ const message = error instanceof Error ? error.message : String(error);
178
+ console.error(chalk.red(`Error: ${message}`));
179
+ process.exit(1);
180
+ }
181
+ }
182
+ function forkSessionOrExit(sourcePath, cwd, sessionDir, sessionId) {
183
+ try {
184
+ return SessionManager.forkFrom(sourcePath, cwd, sessionDir, { id: sessionId });
157
185
  }
158
186
  catch (error) {
159
187
  const message = error instanceof Error ? error.message : String(error);
@@ -162,16 +190,23 @@ function forkSessionOrExit(sourcePath, cwd, sessionDir) {
162
190
  }
163
191
  }
164
192
  async function createSessionManager(parsed, cwd, sessionDir, settingsManager) {
165
- if (parsed.noSession) {
166
- return SessionManager.inMemory();
193
+ if (parsed.noSession || parsed.help || parsed.listModels !== undefined) {
194
+ return SessionManager.inMemory(cwd);
167
195
  }
168
196
  if (parsed.fork) {
197
+ if (parsed.sessionId) {
198
+ const existingTarget = await findLocalSessionByExactId(parsed.sessionId, cwd, sessionDir);
199
+ if (existingTarget) {
200
+ console.error(chalk.red(`Session already exists with id '${parsed.sessionId}'`));
201
+ process.exit(1);
202
+ }
203
+ }
169
204
  const resolved = await resolveSessionPath(parsed.fork, cwd, sessionDir);
170
205
  switch (resolved.type) {
171
206
  case "path":
172
207
  case "local":
173
208
  case "global":
174
- return forkSessionOrExit(resolved.path, cwd, sessionDir);
209
+ return forkSessionOrExit(resolved.path, cwd, sessionDir, parsed.sessionId);
175
210
  case "not_found":
176
211
  console.error(chalk.red(`No session found matching '${resolved.arg}'`));
177
212
  process.exit(1);
@@ -200,7 +235,7 @@ async function createSessionManager(parsed, cwd, sessionDir, settingsManager) {
200
235
  if (parsed.resume) {
201
236
  initTheme(settingsManager.getTheme(), true);
202
237
  try {
203
- const selectedPath = await selectSession((onProgress) => SessionManager.list(cwd, sessionDir, onProgress), SessionManager.listAll);
238
+ const selectedPath = await selectSession((onProgress) => SessionManager.list(cwd, sessionDir, onProgress), (onProgress) => SessionManager.listAll(sessionDir, onProgress));
204
239
  if (!selectedPath) {
205
240
  console.log(chalk.dim("No session selected"));
206
241
  process.exit(0);
@@ -214,7 +249,13 @@ async function createSessionManager(parsed, cwd, sessionDir, settingsManager) {
214
249
  if (parsed.continue) {
215
250
  return SessionManager.continueRecent(cwd, sessionDir);
216
251
  }
217
- return SessionManager.create(cwd, sessionDir);
252
+ if (parsed.sessionId) {
253
+ const existingSession = await findLocalSessionByExactId(parsed.sessionId, cwd, sessionDir);
254
+ if (existingSession) {
255
+ return SessionManager.open(existingSession.path, sessionDir);
256
+ }
257
+ }
258
+ return SessionManager.create(cwd, sessionDir, { id: parsed.sessionId });
218
259
  }
219
260
  function buildSessionOptions(parsed, scopedModels, hasExistingSession, modelRegistry, settingsManager) {
220
261
  const options = {};
@@ -291,10 +332,13 @@ function buildSessionOptions(parsed, scopedModels, hasExistingSession, modelRegi
291
332
  if (parsed.tools) {
292
333
  options.tools = [...parsed.tools];
293
334
  }
335
+ if (parsed.excludeTools) {
336
+ options.excludeTools = [...parsed.excludeTools];
337
+ }
294
338
  return { options, cliThinkingFromModel, diagnostics };
295
339
  }
296
340
  function resolveCliPaths(cwd, paths) {
297
- return paths?.map((value) => (isLocalPath(value) ? resolve(cwd, value) : value));
341
+ return paths?.map((value) => (isLocalPath(value) ? resolvePath(value, cwd) : value));
298
342
  }
299
343
  async function promptForMissingSessionCwd(issue, settingsManager) {
300
344
  initTheme(settingsManager.getTheme());
@@ -324,6 +368,9 @@ export async function main(args, options) {
324
368
  process.env.PI_OFFLINE = "1";
325
369
  process.env.PI_SKIP_VERSION_CHECK = "1";
326
370
  }
371
+ if (process.platform === "win32") {
372
+ cleanupWindowsSelfUpdateQuarantine(getPackageDir());
373
+ }
327
374
  if (await handlePackageCommand(args)) {
328
375
  return;
329
376
  }
@@ -369,6 +416,7 @@ export async function main(args, options) {
369
416
  process.exit(1);
370
417
  }
371
418
  validateForkFlags(parsed);
419
+ validateSessionIdFlags(parsed);
372
420
  // Run migrations (pass cwd for project-local migrations)
373
421
  const { migratedAuthProviders: migratedProviders, deprecationWarnings } = runMigrations(process.cwd());
374
422
  time("runMigrations");
@@ -382,7 +430,7 @@ export async function main(args, options) {
382
430
  // the target session cwd is known. The startup-cwd settings manager is used only for
383
431
  // sessionDir lookup during session selection.
384
432
  const envSessionDir = process.env[ENV_SESSION_DIR];
385
- const sessionDir = parsed.sessionDir ??
433
+ const sessionDir = (parsed.sessionDir ? normalizePath(parsed.sessionDir) : undefined) ??
386
434
  (envSessionDir ? expandTildePath(envSessionDir) : undefined) ??
387
435
  startupSettingsManager.getSessionDir();
388
436
  let sessionManager = await createSessionManager(parsed, cwd, sessionDir, startupSettingsManager);
@@ -400,7 +448,17 @@ export async function main(args, options) {
400
448
  process.exit(1);
401
449
  }
402
450
  }
451
+ if (parsed.name !== undefined) {
452
+ const name = parsed.name.trim();
453
+ if (!name) {
454
+ console.error(chalk.red("Error: --name requires a non-empty value"));
455
+ process.exit(1);
456
+ }
457
+ sessionManager.appendSessionInfo(name);
458
+ }
403
459
  time("createSessionManager");
460
+ // Extensions load normally in serve mode — tool registration and event
461
+ // subscriptions work without UI. UI calls degrade to no-ops via noOpUIContext.
404
462
  const resolvedExtensionPaths = resolveCliPaths(cwd, parsed.extensions);
405
463
  const resolvedSkillPaths = resolveCliPaths(cwd, parsed.skills);
406
464
  const resolvedPromptTemplatePaths = resolveCliPaths(cwd, parsed.promptTemplates);
@@ -459,6 +517,7 @@ export async function main(args, options) {
459
517
  thinkingLevel: sessionOptions.thinkingLevel,
460
518
  scopedModels: sessionOptions.scopedModels,
461
519
  tools: sessionOptions.tools,
520
+ excludeTools: sessionOptions.excludeTools,
462
521
  noTools: sessionOptions.noTools,
463
522
  customTools: sessionOptions.customTools,
464
523
  });
@@ -478,8 +537,10 @@ export async function main(args, options) {
478
537
  agentDir,
479
538
  sessionManager,
480
539
  });
540
+ time("createAgentSessionRuntime");
481
541
  const { services, session, modelFallbackMessage } = runtime;
482
542
  const { settingsManager, modelRegistry, resourceLoader } = services;
543
+ configureHttpDispatcher(settingsManager.getHttpIdleTimeoutMs());
483
544
  if (parsed.help) {
484
545
  const extensionFlags = resourceLoader
485
546
  .getExtensions()
@@ -509,7 +570,6 @@ export async function main(args, options) {
509
570
  if (appMode === "interactive" && deprecationWarnings.length > 0) {
510
571
  await showDeprecationWarnings(deprecationWarnings);
511
572
  }
512
- const scopedModels = [...session.scopedModels];
513
573
  time("resolveModelScope");
514
574
  reportDiagnostics(runtime.diagnostics);
515
575
  if (runtime.diagnostics.some((diagnostic) => diagnostic.type === "error")) {
@@ -525,20 +585,21 @@ export async function main(args, options) {
525
585
  console.error(chalk.red("Error: PI_STARTUP_BENCHMARK only supports interactive mode"));
526
586
  process.exit(1);
527
587
  }
588
+ if (appMode === "serve") {
589
+ const { runServeMode } = await import("./modes/serve/serve-mode.js");
590
+ await runServeMode(runtime, { port: parsed.port });
591
+ return;
592
+ }
593
+ if (appMode === "connect") {
594
+ const { runConnectMode } = await import("./modes/connect/connect-mode.js");
595
+ await runConnectMode({ url: parsed.url });
596
+ return;
597
+ }
528
598
  if (appMode === "rpc") {
529
599
  printTimings();
530
600
  await runRpcMode(runtime);
531
601
  }
532
602
  else if (appMode === "interactive") {
533
- if (scopedModels.length > 0 && (parsed.verbose || !settingsManager.getQuietStartup())) {
534
- const modelList = scopedModels
535
- .map((sm) => {
536
- const thinkingStr = sm.thinkingLevel ? `:${sm.thinkingLevel}` : "";
537
- return `${sm.model.id}${thinkingStr}`;
538
- })
539
- .join(", ");
540
- console.log(chalk.dim(`Model scope: ${modelList} ${chalk.gray("(Ctrl+P to cycle)")}`));
541
- }
542
603
  const interactiveMode = new InteractiveMode(runtime, {
543
604
  migratedProviders,
544
605
  modelFallbackMessage,