@vaclav-synacek/pi-coding-agent-termux 0.45.7

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 (478) hide show
  1. package/CHANGELOG.md +1961 -0
  2. package/README.md +1392 -0
  3. package/dist/cli/args.d.ts +42 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/args.js +248 -0
  6. package/dist/cli/args.js.map +1 -0
  7. package/dist/cli/file-processor.d.ts +15 -0
  8. package/dist/cli/file-processor.d.ts.map +1 -0
  9. package/dist/cli/file-processor.js +79 -0
  10. package/dist/cli/file-processor.js.map +1 -0
  11. package/dist/cli/list-models.d.ts +9 -0
  12. package/dist/cli/list-models.d.ts.map +1 -0
  13. package/dist/cli/list-models.js +92 -0
  14. package/dist/cli/list-models.js.map +1 -0
  15. package/dist/cli/session-picker.d.ts +9 -0
  16. package/dist/cli/session-picker.d.ts.map +1 -0
  17. package/dist/cli/session-picker.js +32 -0
  18. package/dist/cli/session-picker.js.map +1 -0
  19. package/dist/cli.d.ts +3 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +10 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/config.d.ts +61 -0
  24. package/dist/config.d.ts.map +1 -0
  25. package/dist/config.js +141 -0
  26. package/dist/config.js.map +1 -0
  27. package/dist/core/agent-session.d.ts +523 -0
  28. package/dist/core/agent-session.d.ts.map +1 -0
  29. package/dist/core/agent-session.js +1795 -0
  30. package/dist/core/agent-session.js.map +1 -0
  31. package/dist/core/auth-storage.d.ts +112 -0
  32. package/dist/core/auth-storage.d.ts.map +1 -0
  33. package/dist/core/auth-storage.js +297 -0
  34. package/dist/core/auth-storage.js.map +1 -0
  35. package/dist/core/bash-executor.d.ts +47 -0
  36. package/dist/core/bash-executor.d.ts.map +1 -0
  37. package/dist/core/bash-executor.js +211 -0
  38. package/dist/core/bash-executor.js.map +1 -0
  39. package/dist/core/compaction/branch-summarization.d.ts +84 -0
  40. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  41. package/dist/core/compaction/branch-summarization.js +235 -0
  42. package/dist/core/compaction/branch-summarization.js.map +1 -0
  43. package/dist/core/compaction/compaction.d.ts +110 -0
  44. package/dist/core/compaction/compaction.d.ts.map +1 -0
  45. package/dist/core/compaction/compaction.js +559 -0
  46. package/dist/core/compaction/compaction.js.map +1 -0
  47. package/dist/core/compaction/index.d.ts +7 -0
  48. package/dist/core/compaction/index.d.ts.map +1 -0
  49. package/dist/core/compaction/index.js +7 -0
  50. package/dist/core/compaction/index.js.map +1 -0
  51. package/dist/core/compaction/utils.d.ts +35 -0
  52. package/dist/core/compaction/utils.d.ts.map +1 -0
  53. package/dist/core/compaction/utils.js +138 -0
  54. package/dist/core/compaction/utils.js.map +1 -0
  55. package/dist/core/event-bus.d.ts +9 -0
  56. package/dist/core/event-bus.d.ts.map +1 -0
  57. package/dist/core/event-bus.js +25 -0
  58. package/dist/core/event-bus.js.map +1 -0
  59. package/dist/core/exec.d.ts +29 -0
  60. package/dist/core/exec.d.ts.map +1 -0
  61. package/dist/core/exec.js +71 -0
  62. package/dist/core/exec.js.map +1 -0
  63. package/dist/core/export-html/index.d.ts +17 -0
  64. package/dist/core/export-html/index.d.ts.map +1 -0
  65. package/dist/core/export-html/index.js +193 -0
  66. package/dist/core/export-html/index.js.map +1 -0
  67. package/dist/core/export-html/template.css +910 -0
  68. package/dist/core/export-html/template.html +54 -0
  69. package/dist/core/export-html/template.js +1329 -0
  70. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  71. package/dist/core/export-html/vendor/marked.min.js +6 -0
  72. package/dist/core/extensions/index.d.ts +10 -0
  73. package/dist/core/extensions/index.d.ts.map +1 -0
  74. package/dist/core/extensions/index.js +9 -0
  75. package/dist/core/extensions/index.js.map +1 -0
  76. package/dist/core/extensions/loader.d.ts +25 -0
  77. package/dist/core/extensions/loader.d.ts.map +1 -0
  78. package/dist/core/extensions/loader.js +383 -0
  79. package/dist/core/extensions/loader.js.map +1 -0
  80. package/dist/core/extensions/runner.d.ts +89 -0
  81. package/dist/core/extensions/runner.d.ts.map +1 -0
  82. package/dist/core/extensions/runner.js +406 -0
  83. package/dist/core/extensions/runner.js.map +1 -0
  84. package/dist/core/extensions/types.d.ts +654 -0
  85. package/dist/core/extensions/types.d.ts.map +1 -0
  86. package/dist/core/extensions/types.js +32 -0
  87. package/dist/core/extensions/types.js.map +1 -0
  88. package/dist/core/extensions/wrapper.d.ts +27 -0
  89. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  90. package/dist/core/extensions/wrapper.js +102 -0
  91. package/dist/core/extensions/wrapper.js.map +1 -0
  92. package/dist/core/footer-data-provider.d.ts +25 -0
  93. package/dist/core/footer-data-provider.d.ts.map +1 -0
  94. package/dist/core/footer-data-provider.js +121 -0
  95. package/dist/core/footer-data-provider.js.map +1 -0
  96. package/dist/core/index.d.ts +9 -0
  97. package/dist/core/index.d.ts.map +1 -0
  98. package/dist/core/index.js +9 -0
  99. package/dist/core/index.js.map +1 -0
  100. package/dist/core/keybindings.d.ts +59 -0
  101. package/dist/core/keybindings.d.ts.map +1 -0
  102. package/dist/core/keybindings.js +151 -0
  103. package/dist/core/keybindings.js.map +1 -0
  104. package/dist/core/messages.d.ts +77 -0
  105. package/dist/core/messages.d.ts.map +1 -0
  106. package/dist/core/messages.js +123 -0
  107. package/dist/core/messages.js.map +1 -0
  108. package/dist/core/model-registry.d.ts +57 -0
  109. package/dist/core/model-registry.d.ts.map +1 -0
  110. package/dist/core/model-registry.js +314 -0
  111. package/dist/core/model-registry.js.map +1 -0
  112. package/dist/core/model-resolver.d.ts +76 -0
  113. package/dist/core/model-resolver.d.ts.map +1 -0
  114. package/dist/core/model-resolver.js +308 -0
  115. package/dist/core/model-resolver.js.map +1 -0
  116. package/dist/core/prompt-templates.d.ts +40 -0
  117. package/dist/core/prompt-templates.d.ts.map +1 -0
  118. package/dist/core/prompt-templates.js +197 -0
  119. package/dist/core/prompt-templates.js.map +1 -0
  120. package/dist/core/sdk.d.ts +181 -0
  121. package/dist/core/sdk.d.ts.map +1 -0
  122. package/dist/core/sdk.js +466 -0
  123. package/dist/core/sdk.js.map +1 -0
  124. package/dist/core/session-manager.d.ts +313 -0
  125. package/dist/core/session-manager.d.ts.map +1 -0
  126. package/dist/core/session-manager.js +996 -0
  127. package/dist/core/session-manager.js.map +1 -0
  128. package/dist/core/settings-manager.d.ts +138 -0
  129. package/dist/core/settings-manager.d.ts.map +1 -0
  130. package/dist/core/settings-manager.js +327 -0
  131. package/dist/core/settings-manager.js.map +1 -0
  132. package/dist/core/skills.d.ts +50 -0
  133. package/dist/core/skills.d.ts.map +1 -0
  134. package/dist/core/skills.js +338 -0
  135. package/dist/core/skills.js.map +1 -0
  136. package/dist/core/system-prompt.d.ts +48 -0
  137. package/dist/core/system-prompt.d.ts.map +1 -0
  138. package/dist/core/system-prompt.js +224 -0
  139. package/dist/core/system-prompt.js.map +1 -0
  140. package/dist/core/timings.d.ts +7 -0
  141. package/dist/core/timings.d.ts.map +1 -0
  142. package/dist/core/timings.js +25 -0
  143. package/dist/core/timings.js.map +1 -0
  144. package/dist/core/tools/bash.d.ts +42 -0
  145. package/dist/core/tools/bash.d.ts.map +1 -0
  146. package/dist/core/tools/bash.js +223 -0
  147. package/dist/core/tools/bash.js.map +1 -0
  148. package/dist/core/tools/edit-diff.d.ts +33 -0
  149. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  150. package/dist/core/tools/edit-diff.js +171 -0
  151. package/dist/core/tools/edit-diff.js.map +1 -0
  152. package/dist/core/tools/edit.d.ts +37 -0
  153. package/dist/core/tools/edit.d.ts.map +1 -0
  154. package/dist/core/tools/edit.js +143 -0
  155. package/dist/core/tools/edit.js.map +1 -0
  156. package/dist/core/tools/find.d.ts +37 -0
  157. package/dist/core/tools/find.d.ts.map +1 -0
  158. package/dist/core/tools/find.js +206 -0
  159. package/dist/core/tools/find.js.map +1 -0
  160. package/dist/core/tools/grep.d.ts +43 -0
  161. package/dist/core/tools/grep.d.ts.map +1 -0
  162. package/dist/core/tools/grep.js +239 -0
  163. package/dist/core/tools/grep.js.map +1 -0
  164. package/dist/core/tools/index.d.ts +70 -0
  165. package/dist/core/tools/index.d.ts.map +1 -0
  166. package/dist/core/tools/index.js +56 -0
  167. package/dist/core/tools/index.js.map +1 -0
  168. package/dist/core/tools/ls.d.ts +38 -0
  169. package/dist/core/tools/ls.d.ts.map +1 -0
  170. package/dist/core/tools/ls.js +118 -0
  171. package/dist/core/tools/ls.js.map +1 -0
  172. package/dist/core/tools/path-utils.d.ts +8 -0
  173. package/dist/core/tools/path-utils.d.ts.map +1 -0
  174. package/dist/core/tools/path-utils.js +53 -0
  175. package/dist/core/tools/path-utils.js.map +1 -0
  176. package/dist/core/tools/read.d.ts +37 -0
  177. package/dist/core/tools/read.d.ts.map +1 -0
  178. package/dist/core/tools/read.js +165 -0
  179. package/dist/core/tools/read.js.map +1 -0
  180. package/dist/core/tools/truncate.d.ts +70 -0
  181. package/dist/core/tools/truncate.d.ts.map +1 -0
  182. package/dist/core/tools/truncate.js +205 -0
  183. package/dist/core/tools/truncate.js.map +1 -0
  184. package/dist/core/tools/write.d.ts +27 -0
  185. package/dist/core/tools/write.d.ts.map +1 -0
  186. package/dist/core/tools/write.js +78 -0
  187. package/dist/core/tools/write.js.map +1 -0
  188. package/dist/index.d.ts +19 -0
  189. package/dist/index.d.ts.map +1 -0
  190. package/dist/index.js +35 -0
  191. package/dist/index.js.map +1 -0
  192. package/dist/main.d.ts +8 -0
  193. package/dist/main.d.ts.map +1 -0
  194. package/dist/main.js +354 -0
  195. package/dist/main.js.map +1 -0
  196. package/dist/migrations.d.ts +33 -0
  197. package/dist/migrations.d.ts.map +1 -0
  198. package/dist/migrations.js +261 -0
  199. package/dist/migrations.js.map +1 -0
  200. package/dist/modes/index.d.ts +9 -0
  201. package/dist/modes/index.d.ts.map +1 -0
  202. package/dist/modes/index.js +8 -0
  203. package/dist/modes/index.js.map +1 -0
  204. package/dist/modes/interactive/components/armin.d.ts +34 -0
  205. package/dist/modes/interactive/components/armin.d.ts.map +1 -0
  206. package/dist/modes/interactive/components/armin.js +333 -0
  207. package/dist/modes/interactive/components/armin.js.map +1 -0
  208. package/dist/modes/interactive/components/assistant-message.d.ts +15 -0
  209. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  210. package/dist/modes/interactive/components/assistant-message.js +89 -0
  211. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  212. package/dist/modes/interactive/components/bash-execution.d.ts +35 -0
  213. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  214. package/dist/modes/interactive/components/bash-execution.js +161 -0
  215. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  216. package/dist/modes/interactive/components/bordered-loader.d.ts +12 -0
  217. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  218. package/dist/modes/interactive/components/bordered-loader.js +30 -0
  219. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  220. package/dist/modes/interactive/components/branch-summary-message.d.ts +15 -0
  221. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  222. package/dist/modes/interactive/components/branch-summary-message.js +39 -0
  223. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  224. package/dist/modes/interactive/components/compaction-summary-message.d.ts +15 -0
  225. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  226. package/dist/modes/interactive/components/compaction-summary-message.js +40 -0
  227. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  228. package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  229. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  230. package/dist/modes/interactive/components/countdown-timer.js +33 -0
  231. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  232. package/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  233. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  234. package/dist/modes/interactive/components/custom-editor.js +69 -0
  235. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  236. package/dist/modes/interactive/components/custom-message.d.ts +19 -0
  237. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  238. package/dist/modes/interactive/components/custom-message.js +84 -0
  239. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  240. package/dist/modes/interactive/components/diff.d.ts +12 -0
  241. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  242. package/dist/modes/interactive/components/diff.js +133 -0
  243. package/dist/modes/interactive/components/diff.js.map +1 -0
  244. package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  245. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  246. package/dist/modes/interactive/components/dynamic-border.js +21 -0
  247. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  248. package/dist/modes/interactive/components/extension-editor.d.ts +15 -0
  249. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  250. package/dist/modes/interactive/components/extension-editor.js +96 -0
  251. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  252. package/dist/modes/interactive/components/extension-input.d.ts +20 -0
  253. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  254. package/dist/modes/interactive/components/extension-input.js +51 -0
  255. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  256. package/dist/modes/interactive/components/extension-selector.d.ts +24 -0
  257. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  258. package/dist/modes/interactive/components/extension-selector.js +73 -0
  259. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  260. package/dist/modes/interactive/components/footer.d.ts +26 -0
  261. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  262. package/dist/modes/interactive/components/footer.js +207 -0
  263. package/dist/modes/interactive/components/footer.js.map +1 -0
  264. package/dist/modes/interactive/components/index.d.ts +29 -0
  265. package/dist/modes/interactive/components/index.d.ts.map +1 -0
  266. package/dist/modes/interactive/components/index.js +30 -0
  267. package/dist/modes/interactive/components/index.js.map +1 -0
  268. package/dist/modes/interactive/components/login-dialog.d.ts +39 -0
  269. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  270. package/dist/modes/interactive/components/login-dialog.js +135 -0
  271. package/dist/modes/interactive/components/login-dialog.js.map +1 -0
  272. package/dist/modes/interactive/components/model-selector.d.ts +35 -0
  273. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  274. package/dist/modes/interactive/components/model-selector.js +211 -0
  275. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  276. package/dist/modes/interactive/components/oauth-selector.d.ts +19 -0
  277. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  278. package/dist/modes/interactive/components/oauth-selector.js +98 -0
  279. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  280. package/dist/modes/interactive/components/scoped-models-selector.d.ts +46 -0
  281. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  282. package/dist/modes/interactive/components/scoped-models-selector.js +258 -0
  283. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  284. package/dist/modes/interactive/components/session-selector.d.ts +44 -0
  285. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  286. package/dist/modes/interactive/components/session-selector.js +311 -0
  287. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  288. package/dist/modes/interactive/components/settings-selector.d.ts +43 -0
  289. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  290. package/dist/modes/interactive/components/settings-selector.js +219 -0
  291. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  292. package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  293. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  294. package/dist/modes/interactive/components/show-images-selector.js +35 -0
  295. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  296. package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  297. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  298. package/dist/modes/interactive/components/theme-selector.js +46 -0
  299. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  300. package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  301. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  302. package/dist/modes/interactive/components/thinking-selector.js +47 -0
  303. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  304. package/dist/modes/interactive/components/tool-execution.d.ts +70 -0
  305. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  306. package/dist/modes/interactive/components/tool-execution.js +606 -0
  307. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  308. package/dist/modes/interactive/components/tree-selector.d.ts +52 -0
  309. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  310. package/dist/modes/interactive/components/tree-selector.js +745 -0
  311. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  312. package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  313. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  314. package/dist/modes/interactive/components/user-message-selector.js +113 -0
  315. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  316. package/dist/modes/interactive/components/user-message.d.ts +8 -0
  317. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  318. package/dist/modes/interactive/components/user-message.js +16 -0
  319. package/dist/modes/interactive/components/user-message.js.map +1 -0
  320. package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  321. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  322. package/dist/modes/interactive/components/visual-truncate.js +33 -0
  323. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  324. package/dist/modes/interactive/interactive-mode.d.ts +261 -0
  325. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  326. package/dist/modes/interactive/interactive-mode.js +3194 -0
  327. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  328. package/dist/modes/interactive/theme/dark.json +85 -0
  329. package/dist/modes/interactive/theme/light.json +84 -0
  330. package/dist/modes/interactive/theme/theme-schema.json +308 -0
  331. package/dist/modes/interactive/theme/theme.d.ts +71 -0
  332. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  333. package/dist/modes/interactive/theme/theme.js +893 -0
  334. package/dist/modes/interactive/theme/theme.js.map +1 -0
  335. package/dist/modes/print-mode.d.ts +28 -0
  336. package/dist/modes/print-mode.d.ts.map +1 -0
  337. package/dist/modes/print-mode.js +140 -0
  338. package/dist/modes/print-mode.js.map +1 -0
  339. package/dist/modes/rpc/rpc-client.d.ts +209 -0
  340. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  341. package/dist/modes/rpc/rpc-client.js +392 -0
  342. package/dist/modes/rpc/rpc-client.js.map +1 -0
  343. package/dist/modes/rpc/rpc-mode.d.ts +20 -0
  344. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  345. package/dist/modes/rpc/rpc-mode.js +486 -0
  346. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  347. package/dist/modes/rpc/rpc-types.d.ts +372 -0
  348. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  349. package/dist/modes/rpc/rpc-types.js +8 -0
  350. package/dist/modes/rpc/rpc-types.js.map +1 -0
  351. package/dist/utils/changelog.d.ts +21 -0
  352. package/dist/utils/changelog.d.ts.map +1 -0
  353. package/dist/utils/changelog.js +87 -0
  354. package/dist/utils/changelog.js.map +1 -0
  355. package/dist/utils/clipboard-image.d.ts +11 -0
  356. package/dist/utils/clipboard-image.d.ts.map +1 -0
  357. package/dist/utils/clipboard-image.js +129 -0
  358. package/dist/utils/clipboard-image.js.map +1 -0
  359. package/dist/utils/clipboard.d.ts +2 -0
  360. package/dist/utils/clipboard.d.ts.map +1 -0
  361. package/dist/utils/clipboard.js +73 -0
  362. package/dist/utils/clipboard.js.map +1 -0
  363. package/dist/utils/image-convert.d.ts +9 -0
  364. package/dist/utils/image-convert.d.ts.map +1 -0
  365. package/dist/utils/image-convert.js +31 -0
  366. package/dist/utils/image-convert.js.map +1 -0
  367. package/dist/utils/image-resize.d.ts +36 -0
  368. package/dist/utils/image-resize.d.ts.map +1 -0
  369. package/dist/utils/image-resize.js +188 -0
  370. package/dist/utils/image-resize.js.map +1 -0
  371. package/dist/utils/mime.d.ts +2 -0
  372. package/dist/utils/mime.d.ts.map +1 -0
  373. package/dist/utils/mime.js +26 -0
  374. package/dist/utils/mime.js.map +1 -0
  375. package/dist/utils/shell.d.ts +26 -0
  376. package/dist/utils/shell.d.ts.map +1 -0
  377. package/dist/utils/shell.js +151 -0
  378. package/dist/utils/shell.js.map +1 -0
  379. package/dist/utils/tools-manager.d.ts +3 -0
  380. package/dist/utils/tools-manager.d.ts.map +1 -0
  381. package/dist/utils/tools-manager.js +187 -0
  382. package/dist/utils/tools-manager.js.map +1 -0
  383. package/dist/utils/vips.d.ts +11 -0
  384. package/dist/utils/vips.d.ts.map +1 -0
  385. package/dist/utils/vips.js +35 -0
  386. package/dist/utils/vips.js.map +1 -0
  387. package/docs/compaction.md +388 -0
  388. package/docs/extensions.md +1524 -0
  389. package/docs/rpc.md +1046 -0
  390. package/docs/sdk.md +1024 -0
  391. package/docs/session.md +255 -0
  392. package/docs/skills.md +317 -0
  393. package/docs/theme.md +617 -0
  394. package/docs/tree.md +201 -0
  395. package/docs/tui.md +797 -0
  396. package/examples/README.md +24 -0
  397. package/examples/extensions/README.md +168 -0
  398. package/examples/extensions/auto-commit-on-exit.ts +49 -0
  399. package/examples/extensions/chalk-logger.ts +26 -0
  400. package/examples/extensions/claude-rules.ts +86 -0
  401. package/examples/extensions/confirm-destructive.ts +59 -0
  402. package/examples/extensions/custom-compaction.ts +114 -0
  403. package/examples/extensions/custom-footer.ts +64 -0
  404. package/examples/extensions/custom-header.ts +72 -0
  405. package/examples/extensions/dirty-repo-guard.ts +56 -0
  406. package/examples/extensions/doom-overlay/README.md +46 -0
  407. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
  408. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  409. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  410. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  411. package/examples/extensions/doom-overlay/doom-component.ts +132 -0
  412. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  413. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  414. package/examples/extensions/doom-overlay/index.ts +74 -0
  415. package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  416. package/examples/extensions/file-trigger.ts +41 -0
  417. package/examples/extensions/git-checkpoint.ts +53 -0
  418. package/examples/extensions/handoff.ts +150 -0
  419. package/examples/extensions/hello.ts +25 -0
  420. package/examples/extensions/interactive-shell.ts +196 -0
  421. package/examples/extensions/mac-system-theme.ts +47 -0
  422. package/examples/extensions/modal-editor.ts +85 -0
  423. package/examples/extensions/model-status.ts +31 -0
  424. package/examples/extensions/notify.ts +25 -0
  425. package/examples/extensions/overlay-qa-tests.ts +881 -0
  426. package/examples/extensions/overlay-test.ts +145 -0
  427. package/examples/extensions/permission-gate.ts +34 -0
  428. package/examples/extensions/pirate.ts +47 -0
  429. package/examples/extensions/plan-mode/README.md +65 -0
  430. package/examples/extensions/plan-mode/index.ts +340 -0
  431. package/examples/extensions/plan-mode/utils.ts +168 -0
  432. package/examples/extensions/preset.ts +398 -0
  433. package/examples/extensions/protected-paths.ts +30 -0
  434. package/examples/extensions/qna.ts +119 -0
  435. package/examples/extensions/question.ts +277 -0
  436. package/examples/extensions/questionnaire.ts +427 -0
  437. package/examples/extensions/rainbow-editor.ts +95 -0
  438. package/examples/extensions/sandbox/index.ts +318 -0
  439. package/examples/extensions/sandbox/package-lock.json +92 -0
  440. package/examples/extensions/sandbox/package.json +19 -0
  441. package/examples/extensions/send-user-message.ts +97 -0
  442. package/examples/extensions/shutdown-command.ts +63 -0
  443. package/examples/extensions/snake.ts +343 -0
  444. package/examples/extensions/ssh.ts +220 -0
  445. package/examples/extensions/status-line.ts +40 -0
  446. package/examples/extensions/subagent/README.md +172 -0
  447. package/examples/extensions/subagent/agents/planner.md +37 -0
  448. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  449. package/examples/extensions/subagent/agents/scout.md +50 -0
  450. package/examples/extensions/subagent/agents/worker.md +24 -0
  451. package/examples/extensions/subagent/agents.ts +156 -0
  452. package/examples/extensions/subagent/index.ts +963 -0
  453. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  454. package/examples/extensions/subagent/prompts/implement.md +10 -0
  455. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  456. package/examples/extensions/summarize.ts +195 -0
  457. package/examples/extensions/timed-confirm.ts +70 -0
  458. package/examples/extensions/todo.ts +299 -0
  459. package/examples/extensions/tool-override.ts +143 -0
  460. package/examples/extensions/tools.ts +146 -0
  461. package/examples/extensions/truncated-tool.ts +192 -0
  462. package/examples/extensions/with-deps/index.ts +36 -0
  463. package/examples/extensions/with-deps/package-lock.json +31 -0
  464. package/examples/extensions/with-deps/package.json +22 -0
  465. package/examples/sdk/01-minimal.ts +22 -0
  466. package/examples/sdk/02-custom-model.ts +49 -0
  467. package/examples/sdk/03-custom-prompt.ts +44 -0
  468. package/examples/sdk/04-skills.ts +47 -0
  469. package/examples/sdk/05-tools.ts +56 -0
  470. package/examples/sdk/06-extensions.ts +79 -0
  471. package/examples/sdk/07-context-files.ts +36 -0
  472. package/examples/sdk/08-prompt-templates.ts +42 -0
  473. package/examples/sdk/09-api-keys-and-oauth.ts +55 -0
  474. package/examples/sdk/10-settings.ts +38 -0
  475. package/examples/sdk/11-sessions.ts +48 -0
  476. package/examples/sdk/12-full-control.ts +72 -0
  477. package/examples/sdk/README.md +150 -0
  478. package/package.json +88 -0
@@ -0,0 +1,42 @@
1
+ /**
2
+ * CLI argument parsing and help display
3
+ */
4
+ import type { ThinkingLevel } from "@mariozechner/pi-agent-core";
5
+ import { type ToolName } from "../core/tools/index.js";
6
+ export type Mode = "text" | "json" | "rpc";
7
+ export interface Args {
8
+ provider?: string;
9
+ model?: string;
10
+ apiKey?: string;
11
+ systemPrompt?: string;
12
+ appendSystemPrompt?: string;
13
+ thinking?: ThinkingLevel;
14
+ continue?: boolean;
15
+ resume?: boolean;
16
+ help?: boolean;
17
+ version?: boolean;
18
+ mode?: Mode;
19
+ noSession?: boolean;
20
+ session?: string;
21
+ sessionDir?: string;
22
+ models?: string[];
23
+ tools?: ToolName[];
24
+ noTools?: boolean;
25
+ extensions?: string[];
26
+ noExtensions?: boolean;
27
+ print?: boolean;
28
+ export?: string;
29
+ noSkills?: boolean;
30
+ skills?: string[];
31
+ listModels?: string | true;
32
+ messages: string[];
33
+ fileArgs: string[];
34
+ /** Unknown flags (potentially extension flags) - map of flag name to value */
35
+ unknownFlags: Map<string, boolean | string>;
36
+ }
37
+ export declare function isValidThinkingLevel(level: string): level is ThinkingLevel;
38
+ export declare function parseArgs(args: string[], extensionFlags?: Map<string, {
39
+ type: "boolean" | "string";
40
+ }>): Args;
41
+ export declare function printHelp(): void;
42
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAGjE,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEjE,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAE3C,MAAM,WAAW,IAAI;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8EAA8E;IAC9E,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC;CAC5C;AAID,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa,CAE1E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,CAAC,GAAG,IAAI,CA4G5G;AAED,wBAAgB,SAAS,IAAI,IAAI,CA0GhC","sourcesContent":["/**\n * CLI argument parsing and help display\n */\n\nimport type { ThinkingLevel } from \"@mariozechner/pi-agent-core\";\nimport chalk from \"chalk\";\nimport { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR } from \"../config.js\";\nimport { allTools, type ToolName } from \"../core/tools/index.js\";\n\nexport type Mode = \"text\" | \"json\" | \"rpc\";\n\nexport interface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tappendSystemPrompt?: string;\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tmode?: Mode;\n\tnoSession?: boolean;\n\tsession?: string;\n\tsessionDir?: string;\n\tmodels?: string[];\n\ttools?: ToolName[];\n\tnoTools?: boolean;\n\textensions?: string[];\n\tnoExtensions?: boolean;\n\tprint?: boolean;\n\texport?: string;\n\tnoSkills?: boolean;\n\tskills?: string[];\n\tlistModels?: string | true;\n\tmessages: string[];\n\tfileArgs: string[];\n\t/** Unknown flags (potentially extension flags) - map of flag name to value */\n\tunknownFlags: Map<string, boolean | string>;\n}\n\nconst VALID_THINKING_LEVELS = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\"] as const;\n\nexport function isValidThinkingLevel(level: string): level is ThinkingLevel {\n\treturn VALID_THINKING_LEVELS.includes(level as ThinkingLevel);\n}\n\nexport function parseArgs(args: string[], extensionFlags?: Map<string, { type: \"boolean\" | \"string\" }>): Args {\n\tconst result: Args = {\n\t\tmessages: [],\n\t\tfileArgs: [],\n\t\tunknownFlags: new Map(),\n\t};\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\n\t\tif (arg === \"--help\" || arg === \"-h\") {\n\t\t\tresult.help = true;\n\t\t} else if (arg === \"--version\" || arg === \"-v\") {\n\t\t\tresult.version = true;\n\t\t} else if (arg === \"--mode\" && i + 1 < args.length) {\n\t\t\tconst mode = args[++i];\n\t\t\tif (mode === \"text\" || mode === \"json\" || mode === \"rpc\") {\n\t\t\t\tresult.mode = mode;\n\t\t\t}\n\t\t} else if (arg === \"--continue\" || arg === \"-c\") {\n\t\t\tresult.continue = true;\n\t\t} else if (arg === \"--resume\" || arg === \"-r\") {\n\t\t\tresult.resume = true;\n\t\t} else if (arg === \"--provider\" && i + 1 < args.length) {\n\t\t\tresult.provider = args[++i];\n\t\t} else if (arg === \"--model\" && i + 1 < args.length) {\n\t\t\tresult.model = args[++i];\n\t\t} else if (arg === \"--api-key\" && i + 1 < args.length) {\n\t\t\tresult.apiKey = args[++i];\n\t\t} else if (arg === \"--system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.systemPrompt = args[++i];\n\t\t} else if (arg === \"--append-system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.appendSystemPrompt = args[++i];\n\t\t} else if (arg === \"--no-session\") {\n\t\t\tresult.noSession = true;\n\t\t} else if (arg === \"--session\" && i + 1 < args.length) {\n\t\t\tresult.session = args[++i];\n\t\t} else if (arg === \"--session-dir\" && i + 1 < args.length) {\n\t\t\tresult.sessionDir = args[++i];\n\t\t} else if (arg === \"--models\" && i + 1 < args.length) {\n\t\t\tresult.models = args[++i].split(\",\").map((s) => s.trim());\n\t\t} else if (arg === \"--no-tools\") {\n\t\t\tresult.noTools = true;\n\t\t} else if (arg === \"--tools\" && i + 1 < args.length) {\n\t\t\tconst toolNames = args[++i].split(\",\").map((s) => s.trim());\n\t\t\tconst validTools: ToolName[] = [];\n\t\t\tfor (const name of toolNames) {\n\t\t\t\tif (name in allTools) {\n\t\t\t\t\tvalidTools.push(name as ToolName);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\tchalk.yellow(`Warning: Unknown tool \"${name}\". Valid tools: ${Object.keys(allTools).join(\", \")}`),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tresult.tools = validTools;\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (isValidThinkingLevel(level)) {\n\t\t\t\tresult.thinking = level;\n\t\t\t} else {\n\t\t\t\tconsole.error(\n\t\t\t\t\tchalk.yellow(\n\t\t\t\t\t\t`Warning: Invalid thinking level \"${level}\". Valid values: ${VALID_THINKING_LEVELS.join(\", \")}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t} else if (arg === \"--print\" || arg === \"-p\") {\n\t\t\tresult.print = true;\n\t\t} else if (arg === \"--export\" && i + 1 < args.length) {\n\t\t\tresult.export = args[++i];\n\t\t} else if ((arg === \"--extension\" || arg === \"-e\") && i + 1 < args.length) {\n\t\t\tresult.extensions = result.extensions ?? [];\n\t\t\tresult.extensions.push(args[++i]);\n\t\t} else if (arg === \"--no-extensions\") {\n\t\t\tresult.noExtensions = true;\n\t\t} else if (arg === \"--no-skills\") {\n\t\t\tresult.noSkills = true;\n\t\t} else if (arg === \"--skills\" && i + 1 < args.length) {\n\t\t\t// Comma-separated glob patterns for skill filtering\n\t\t\tresult.skills = args[++i].split(\",\").map((s) => s.trim());\n\t\t} else if (arg === \"--list-models\") {\n\t\t\t// Check if next arg is a search pattern (not a flag or file arg)\n\t\t\tif (i + 1 < args.length && !args[i + 1].startsWith(\"-\") && !args[i + 1].startsWith(\"@\")) {\n\t\t\t\tresult.listModels = args[++i];\n\t\t\t} else {\n\t\t\t\tresult.listModels = true;\n\t\t\t}\n\t\t} else if (arg.startsWith(\"@\")) {\n\t\t\tresult.fileArgs.push(arg.slice(1)); // Remove @ prefix\n\t\t} else if (arg.startsWith(\"--\") && extensionFlags) {\n\t\t\t// Check if it's an extension-registered flag\n\t\t\tconst flagName = arg.slice(2);\n\t\t\tconst extFlag = extensionFlags.get(flagName);\n\t\t\tif (extFlag) {\n\t\t\t\tif (extFlag.type === \"boolean\") {\n\t\t\t\t\tresult.unknownFlags.set(flagName, true);\n\t\t\t\t} else if (extFlag.type === \"string\" && i + 1 < args.length) {\n\t\t\t\t\tresult.unknownFlags.set(flagName, args[++i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Unknown flags without extensionFlags are silently ignored (first pass)\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tresult.messages.push(arg);\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function printHelp(): void {\n\tconsole.log(`${chalk.bold(APP_NAME)} - AI coding assistant with read, bash, edit, write tools\n\n${chalk.bold(\"Usage:\")}\n ${APP_NAME} [options] [@files...] [messages...]\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (default: google)\n --model <id> Model ID (default: gemini-2.5-flash)\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> System prompt (default: coding assistant prompt)\n --append-system-prompt <text> Append text or file contents to the system prompt\n --mode <mode> Output mode: text (default), json, or rpc\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select a session to resume\n --session <path> Use specific session file\n --session-dir <dir> Directory for session storage and lookup\n --no-session Don't save session (ephemeral)\n --models <patterns> Comma-separated model patterns for Ctrl+P cycling\n Supports globs (anthropic/*, *sonnet*) and fuzzy matching\n --no-tools Disable all built-in tools\n --tools <tools> Comma-separated list of tools to enable (default: read,bash,edit,write)\n Available: read, bash, edit, write, grep, find, ls\n --thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh\n --extension, -e <path> Load an extension file (can be used multiple times)\n --no-extensions Disable extension discovery (explicit -e paths still work)\n --no-skills Disable skills discovery and loading\n --skills <patterns> Comma-separated glob patterns to filter skills (e.g., git-*,docker)\n --export <file> Export session file to HTML and exit\n --list-models [search] List available models (with optional fuzzy search)\n --help, -h Show this help\n --version, -v Show version number\n\nExtensions can register additional flags (e.g., --plan from plan-mode extension).\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n ${APP_NAME}\n\n # Interactive mode with initial prompt\n ${APP_NAME} \"List all .ts files in src/\"\n\n # Include files in initial message\n ${APP_NAME} @prompt.md @image.png \"What color is the sky?\"\n\n # Non-interactive mode (process and exit)\n ${APP_NAME} -p \"List all .ts files in src/\"\n\n # Multiple messages (interactive)\n ${APP_NAME} \"Read package.json\" \"What dependencies do we have?\"\n\n # Continue previous session\n ${APP_NAME} --continue \"What did we discuss?\"\n\n # Use different model\n ${APP_NAME} --provider openai --model gpt-4o-mini \"Help me refactor this code\"\n\n # Limit model cycling to specific models\n ${APP_NAME} --models claude-sonnet,claude-haiku,gpt-4o\n\n # Limit to a specific provider with glob pattern\n ${APP_NAME} --models \"github-copilot/*\"\n\n # Cycle models with fixed thinking levels\n ${APP_NAME} --models sonnet:high,haiku:low\n\n # Start with a specific thinking level\n ${APP_NAME} --thinking high \"Solve this complex problem\"\n\n # Read-only mode (no file modifications possible)\n ${APP_NAME} --tools read,grep,find,ls -p \"Review the code in src/\"\n\n # Export a session file to HTML\n ${APP_NAME} --export ~/${CONFIG_DIR_NAME}/agent/sessions/--path--/session.jsonl\n ${APP_NAME} --export session.jsonl output.html\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY - Anthropic Claude API key\n ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)\n OPENAI_API_KEY - OpenAI GPT API key\n GEMINI_API_KEY - Google Gemini API key\n GROQ_API_KEY - Groq API key\n CEREBRAS_API_KEY - Cerebras API key\n XAI_API_KEY - xAI Grok API key\n OPENROUTER_API_KEY - OpenRouter API key\n AI_GATEWAY_API_KEY - Vercel AI Gateway API key\n ZAI_API_KEY - ZAI API key\n MISTRAL_API_KEY - Mistral API key\n MINIMAX_API_KEY - MiniMax API key\n AWS_PROFILE - AWS profile for Amazon Bedrock\n AWS_ACCESS_KEY_ID - AWS access key for Amazon Bedrock\n AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock\n AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (bearer token)\n AWS_REGION - AWS region for Amazon Bedrock (e.g., us-east-1)\n ${ENV_AGENT_DIR.padEnd(23)} - Session storage directory (default: ~/${CONFIG_DIR_NAME}/agent)\n\n${chalk.bold(\"Available Tools (default: read, bash, edit, write):\")}\n read - Read file contents\n bash - Execute bash commands\n edit - Edit files with find/replace\n write - Write files (creates/overwrites)\n grep - Search file contents (read-only, off by default)\n find - Find files by glob pattern (read-only, off by default)\n ls - List directory contents (read-only, off by default)\n`);\n}\n"]}
@@ -0,0 +1,248 @@
1
+ /**
2
+ * CLI argument parsing and help display
3
+ */
4
+ import chalk from "chalk";
5
+ import { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR } from "../config.js";
6
+ import { allTools } from "../core/tools/index.js";
7
+ const VALID_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh"];
8
+ export function isValidThinkingLevel(level) {
9
+ return VALID_THINKING_LEVELS.includes(level);
10
+ }
11
+ export function parseArgs(args, extensionFlags) {
12
+ const result = {
13
+ messages: [],
14
+ fileArgs: [],
15
+ unknownFlags: new Map(),
16
+ };
17
+ for (let i = 0; i < args.length; i++) {
18
+ const arg = args[i];
19
+ if (arg === "--help" || arg === "-h") {
20
+ result.help = true;
21
+ }
22
+ else if (arg === "--version" || arg === "-v") {
23
+ result.version = true;
24
+ }
25
+ else if (arg === "--mode" && i + 1 < args.length) {
26
+ const mode = args[++i];
27
+ if (mode === "text" || mode === "json" || mode === "rpc") {
28
+ result.mode = mode;
29
+ }
30
+ }
31
+ else if (arg === "--continue" || arg === "-c") {
32
+ result.continue = true;
33
+ }
34
+ else if (arg === "--resume" || arg === "-r") {
35
+ result.resume = true;
36
+ }
37
+ else if (arg === "--provider" && i + 1 < args.length) {
38
+ result.provider = args[++i];
39
+ }
40
+ else if (arg === "--model" && i + 1 < args.length) {
41
+ result.model = args[++i];
42
+ }
43
+ else if (arg === "--api-key" && i + 1 < args.length) {
44
+ result.apiKey = args[++i];
45
+ }
46
+ else if (arg === "--system-prompt" && i + 1 < args.length) {
47
+ result.systemPrompt = args[++i];
48
+ }
49
+ else if (arg === "--append-system-prompt" && i + 1 < args.length) {
50
+ result.appendSystemPrompt = args[++i];
51
+ }
52
+ else if (arg === "--no-session") {
53
+ result.noSession = true;
54
+ }
55
+ else if (arg === "--session" && i + 1 < args.length) {
56
+ result.session = args[++i];
57
+ }
58
+ else if (arg === "--session-dir" && i + 1 < args.length) {
59
+ result.sessionDir = args[++i];
60
+ }
61
+ else if (arg === "--models" && i + 1 < args.length) {
62
+ result.models = args[++i].split(",").map((s) => s.trim());
63
+ }
64
+ else if (arg === "--no-tools") {
65
+ result.noTools = true;
66
+ }
67
+ else if (arg === "--tools" && i + 1 < args.length) {
68
+ const toolNames = args[++i].split(",").map((s) => s.trim());
69
+ const validTools = [];
70
+ for (const name of toolNames) {
71
+ if (name in allTools) {
72
+ validTools.push(name);
73
+ }
74
+ else {
75
+ console.error(chalk.yellow(`Warning: Unknown tool "${name}". Valid tools: ${Object.keys(allTools).join(", ")}`));
76
+ }
77
+ }
78
+ result.tools = validTools;
79
+ }
80
+ else if (arg === "--thinking" && i + 1 < args.length) {
81
+ const level = args[++i];
82
+ if (isValidThinkingLevel(level)) {
83
+ result.thinking = level;
84
+ }
85
+ else {
86
+ console.error(chalk.yellow(`Warning: Invalid thinking level "${level}". Valid values: ${VALID_THINKING_LEVELS.join(", ")}`));
87
+ }
88
+ }
89
+ else if (arg === "--print" || arg === "-p") {
90
+ result.print = true;
91
+ }
92
+ else if (arg === "--export" && i + 1 < args.length) {
93
+ result.export = args[++i];
94
+ }
95
+ else if ((arg === "--extension" || arg === "-e") && i + 1 < args.length) {
96
+ result.extensions = result.extensions ?? [];
97
+ result.extensions.push(args[++i]);
98
+ }
99
+ else if (arg === "--no-extensions") {
100
+ result.noExtensions = true;
101
+ }
102
+ else if (arg === "--no-skills") {
103
+ result.noSkills = true;
104
+ }
105
+ else if (arg === "--skills" && i + 1 < args.length) {
106
+ // Comma-separated glob patterns for skill filtering
107
+ result.skills = args[++i].split(",").map((s) => s.trim());
108
+ }
109
+ else if (arg === "--list-models") {
110
+ // Check if next arg is a search pattern (not a flag or file arg)
111
+ if (i + 1 < args.length && !args[i + 1].startsWith("-") && !args[i + 1].startsWith("@")) {
112
+ result.listModels = args[++i];
113
+ }
114
+ else {
115
+ result.listModels = true;
116
+ }
117
+ }
118
+ else if (arg.startsWith("@")) {
119
+ result.fileArgs.push(arg.slice(1)); // Remove @ prefix
120
+ }
121
+ else if (arg.startsWith("--") && extensionFlags) {
122
+ // Check if it's an extension-registered flag
123
+ const flagName = arg.slice(2);
124
+ const extFlag = extensionFlags.get(flagName);
125
+ if (extFlag) {
126
+ if (extFlag.type === "boolean") {
127
+ result.unknownFlags.set(flagName, true);
128
+ }
129
+ else if (extFlag.type === "string" && i + 1 < args.length) {
130
+ result.unknownFlags.set(flagName, args[++i]);
131
+ }
132
+ }
133
+ // Unknown flags without extensionFlags are silently ignored (first pass)
134
+ }
135
+ else if (!arg.startsWith("-")) {
136
+ result.messages.push(arg);
137
+ }
138
+ }
139
+ return result;
140
+ }
141
+ export function printHelp() {
142
+ console.log(`${chalk.bold(APP_NAME)} - AI coding assistant with read, bash, edit, write tools
143
+
144
+ ${chalk.bold("Usage:")}
145
+ ${APP_NAME} [options] [@files...] [messages...]
146
+
147
+ ${chalk.bold("Options:")}
148
+ --provider <name> Provider name (default: google)
149
+ --model <id> Model ID (default: gemini-2.5-flash)
150
+ --api-key <key> API key (defaults to env vars)
151
+ --system-prompt <text> System prompt (default: coding assistant prompt)
152
+ --append-system-prompt <text> Append text or file contents to the system prompt
153
+ --mode <mode> Output mode: text (default), json, or rpc
154
+ --print, -p Non-interactive mode: process prompt and exit
155
+ --continue, -c Continue previous session
156
+ --resume, -r Select a session to resume
157
+ --session <path> Use specific session file
158
+ --session-dir <dir> Directory for session storage and lookup
159
+ --no-session Don't save session (ephemeral)
160
+ --models <patterns> Comma-separated model patterns for Ctrl+P cycling
161
+ Supports globs (anthropic/*, *sonnet*) and fuzzy matching
162
+ --no-tools Disable all built-in tools
163
+ --tools <tools> Comma-separated list of tools to enable (default: read,bash,edit,write)
164
+ Available: read, bash, edit, write, grep, find, ls
165
+ --thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh
166
+ --extension, -e <path> Load an extension file (can be used multiple times)
167
+ --no-extensions Disable extension discovery (explicit -e paths still work)
168
+ --no-skills Disable skills discovery and loading
169
+ --skills <patterns> Comma-separated glob patterns to filter skills (e.g., git-*,docker)
170
+ --export <file> Export session file to HTML and exit
171
+ --list-models [search] List available models (with optional fuzzy search)
172
+ --help, -h Show this help
173
+ --version, -v Show version number
174
+
175
+ Extensions can register additional flags (e.g., --plan from plan-mode extension).
176
+
177
+ ${chalk.bold("Examples:")}
178
+ # Interactive mode
179
+ ${APP_NAME}
180
+
181
+ # Interactive mode with initial prompt
182
+ ${APP_NAME} "List all .ts files in src/"
183
+
184
+ # Include files in initial message
185
+ ${APP_NAME} @prompt.md @image.png "What color is the sky?"
186
+
187
+ # Non-interactive mode (process and exit)
188
+ ${APP_NAME} -p "List all .ts files in src/"
189
+
190
+ # Multiple messages (interactive)
191
+ ${APP_NAME} "Read package.json" "What dependencies do we have?"
192
+
193
+ # Continue previous session
194
+ ${APP_NAME} --continue "What did we discuss?"
195
+
196
+ # Use different model
197
+ ${APP_NAME} --provider openai --model gpt-4o-mini "Help me refactor this code"
198
+
199
+ # Limit model cycling to specific models
200
+ ${APP_NAME} --models claude-sonnet,claude-haiku,gpt-4o
201
+
202
+ # Limit to a specific provider with glob pattern
203
+ ${APP_NAME} --models "github-copilot/*"
204
+
205
+ # Cycle models with fixed thinking levels
206
+ ${APP_NAME} --models sonnet:high,haiku:low
207
+
208
+ # Start with a specific thinking level
209
+ ${APP_NAME} --thinking high "Solve this complex problem"
210
+
211
+ # Read-only mode (no file modifications possible)
212
+ ${APP_NAME} --tools read,grep,find,ls -p "Review the code in src/"
213
+
214
+ # Export a session file to HTML
215
+ ${APP_NAME} --export ~/${CONFIG_DIR_NAME}/agent/sessions/--path--/session.jsonl
216
+ ${APP_NAME} --export session.jsonl output.html
217
+
218
+ ${chalk.bold("Environment Variables:")}
219
+ ANTHROPIC_API_KEY - Anthropic Claude API key
220
+ ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)
221
+ OPENAI_API_KEY - OpenAI GPT API key
222
+ GEMINI_API_KEY - Google Gemini API key
223
+ GROQ_API_KEY - Groq API key
224
+ CEREBRAS_API_KEY - Cerebras API key
225
+ XAI_API_KEY - xAI Grok API key
226
+ OPENROUTER_API_KEY - OpenRouter API key
227
+ AI_GATEWAY_API_KEY - Vercel AI Gateway API key
228
+ ZAI_API_KEY - ZAI API key
229
+ MISTRAL_API_KEY - Mistral API key
230
+ MINIMAX_API_KEY - MiniMax API key
231
+ AWS_PROFILE - AWS profile for Amazon Bedrock
232
+ AWS_ACCESS_KEY_ID - AWS access key for Amazon Bedrock
233
+ AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock
234
+ AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (bearer token)
235
+ AWS_REGION - AWS region for Amazon Bedrock (e.g., us-east-1)
236
+ ${ENV_AGENT_DIR.padEnd(23)} - Session storage directory (default: ~/${CONFIG_DIR_NAME}/agent)
237
+
238
+ ${chalk.bold("Available Tools (default: read, bash, edit, write):")}
239
+ read - Read file contents
240
+ bash - Execute bash commands
241
+ edit - Edit files with find/replace
242
+ write - Write files (creates/overwrites)
243
+ grep - Search file contents (read-only, off by default)
244
+ find - Find files by glob pattern (read-only, off by default)
245
+ ls - List directory contents (read-only, off by default)
246
+ `);
247
+ }
248
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CLI argument parsing and help display\n */\n\nimport type { ThinkingLevel } from \"@mariozechner/pi-agent-core\";\nimport chalk from \"chalk\";\nimport { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR } from \"../config.js\";\nimport { allTools, type ToolName } from \"../core/tools/index.js\";\n\nexport type Mode = \"text\" | \"json\" | \"rpc\";\n\nexport interface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tappendSystemPrompt?: string;\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tmode?: Mode;\n\tnoSession?: boolean;\n\tsession?: string;\n\tsessionDir?: string;\n\tmodels?: string[];\n\ttools?: ToolName[];\n\tnoTools?: boolean;\n\textensions?: string[];\n\tnoExtensions?: boolean;\n\tprint?: boolean;\n\texport?: string;\n\tnoSkills?: boolean;\n\tskills?: string[];\n\tlistModels?: string | true;\n\tmessages: string[];\n\tfileArgs: string[];\n\t/** Unknown flags (potentially extension flags) - map of flag name to value */\n\tunknownFlags: Map<string, boolean | string>;\n}\n\nconst VALID_THINKING_LEVELS = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\"] as const;\n\nexport function isValidThinkingLevel(level: string): level is ThinkingLevel {\n\treturn VALID_THINKING_LEVELS.includes(level as ThinkingLevel);\n}\n\nexport function parseArgs(args: string[], extensionFlags?: Map<string, { type: \"boolean\" | \"string\" }>): Args {\n\tconst result: Args = {\n\t\tmessages: [],\n\t\tfileArgs: [],\n\t\tunknownFlags: new Map(),\n\t};\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\n\t\tif (arg === \"--help\" || arg === \"-h\") {\n\t\t\tresult.help = true;\n\t\t} else if (arg === \"--version\" || arg === \"-v\") {\n\t\t\tresult.version = true;\n\t\t} else if (arg === \"--mode\" && i + 1 < args.length) {\n\t\t\tconst mode = args[++i];\n\t\t\tif (mode === \"text\" || mode === \"json\" || mode === \"rpc\") {\n\t\t\t\tresult.mode = mode;\n\t\t\t}\n\t\t} else if (arg === \"--continue\" || arg === \"-c\") {\n\t\t\tresult.continue = true;\n\t\t} else if (arg === \"--resume\" || arg === \"-r\") {\n\t\t\tresult.resume = true;\n\t\t} else if (arg === \"--provider\" && i + 1 < args.length) {\n\t\t\tresult.provider = args[++i];\n\t\t} else if (arg === \"--model\" && i + 1 < args.length) {\n\t\t\tresult.model = args[++i];\n\t\t} else if (arg === \"--api-key\" && i + 1 < args.length) {\n\t\t\tresult.apiKey = args[++i];\n\t\t} else if (arg === \"--system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.systemPrompt = args[++i];\n\t\t} else if (arg === \"--append-system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.appendSystemPrompt = args[++i];\n\t\t} else if (arg === \"--no-session\") {\n\t\t\tresult.noSession = true;\n\t\t} else if (arg === \"--session\" && i + 1 < args.length) {\n\t\t\tresult.session = args[++i];\n\t\t} else if (arg === \"--session-dir\" && i + 1 < args.length) {\n\t\t\tresult.sessionDir = args[++i];\n\t\t} else if (arg === \"--models\" && i + 1 < args.length) {\n\t\t\tresult.models = args[++i].split(\",\").map((s) => s.trim());\n\t\t} else if (arg === \"--no-tools\") {\n\t\t\tresult.noTools = true;\n\t\t} else if (arg === \"--tools\" && i + 1 < args.length) {\n\t\t\tconst toolNames = args[++i].split(\",\").map((s) => s.trim());\n\t\t\tconst validTools: ToolName[] = [];\n\t\t\tfor (const name of toolNames) {\n\t\t\t\tif (name in allTools) {\n\t\t\t\t\tvalidTools.push(name as ToolName);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\tchalk.yellow(`Warning: Unknown tool \"${name}\". Valid tools: ${Object.keys(allTools).join(\", \")}`),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tresult.tools = validTools;\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (isValidThinkingLevel(level)) {\n\t\t\t\tresult.thinking = level;\n\t\t\t} else {\n\t\t\t\tconsole.error(\n\t\t\t\t\tchalk.yellow(\n\t\t\t\t\t\t`Warning: Invalid thinking level \"${level}\". Valid values: ${VALID_THINKING_LEVELS.join(\", \")}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t} else if (arg === \"--print\" || arg === \"-p\") {\n\t\t\tresult.print = true;\n\t\t} else if (arg === \"--export\" && i + 1 < args.length) {\n\t\t\tresult.export = args[++i];\n\t\t} else if ((arg === \"--extension\" || arg === \"-e\") && i + 1 < args.length) {\n\t\t\tresult.extensions = result.extensions ?? [];\n\t\t\tresult.extensions.push(args[++i]);\n\t\t} else if (arg === \"--no-extensions\") {\n\t\t\tresult.noExtensions = true;\n\t\t} else if (arg === \"--no-skills\") {\n\t\t\tresult.noSkills = true;\n\t\t} else if (arg === \"--skills\" && i + 1 < args.length) {\n\t\t\t// Comma-separated glob patterns for skill filtering\n\t\t\tresult.skills = args[++i].split(\",\").map((s) => s.trim());\n\t\t} else if (arg === \"--list-models\") {\n\t\t\t// Check if next arg is a search pattern (not a flag or file arg)\n\t\t\tif (i + 1 < args.length && !args[i + 1].startsWith(\"-\") && !args[i + 1].startsWith(\"@\")) {\n\t\t\t\tresult.listModels = args[++i];\n\t\t\t} else {\n\t\t\t\tresult.listModels = true;\n\t\t\t}\n\t\t} else if (arg.startsWith(\"@\")) {\n\t\t\tresult.fileArgs.push(arg.slice(1)); // Remove @ prefix\n\t\t} else if (arg.startsWith(\"--\") && extensionFlags) {\n\t\t\t// Check if it's an extension-registered flag\n\t\t\tconst flagName = arg.slice(2);\n\t\t\tconst extFlag = extensionFlags.get(flagName);\n\t\t\tif (extFlag) {\n\t\t\t\tif (extFlag.type === \"boolean\") {\n\t\t\t\t\tresult.unknownFlags.set(flagName, true);\n\t\t\t\t} else if (extFlag.type === \"string\" && i + 1 < args.length) {\n\t\t\t\t\tresult.unknownFlags.set(flagName, args[++i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Unknown flags without extensionFlags are silently ignored (first pass)\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tresult.messages.push(arg);\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function printHelp(): void {\n\tconsole.log(`${chalk.bold(APP_NAME)} - AI coding assistant with read, bash, edit, write tools\n\n${chalk.bold(\"Usage:\")}\n ${APP_NAME} [options] [@files...] [messages...]\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (default: google)\n --model <id> Model ID (default: gemini-2.5-flash)\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> System prompt (default: coding assistant prompt)\n --append-system-prompt <text> Append text or file contents to the system prompt\n --mode <mode> Output mode: text (default), json, or rpc\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select a session to resume\n --session <path> Use specific session file\n --session-dir <dir> Directory for session storage and lookup\n --no-session Don't save session (ephemeral)\n --models <patterns> Comma-separated model patterns for Ctrl+P cycling\n Supports globs (anthropic/*, *sonnet*) and fuzzy matching\n --no-tools Disable all built-in tools\n --tools <tools> Comma-separated list of tools to enable (default: read,bash,edit,write)\n Available: read, bash, edit, write, grep, find, ls\n --thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh\n --extension, -e <path> Load an extension file (can be used multiple times)\n --no-extensions Disable extension discovery (explicit -e paths still work)\n --no-skills Disable skills discovery and loading\n --skills <patterns> Comma-separated glob patterns to filter skills (e.g., git-*,docker)\n --export <file> Export session file to HTML and exit\n --list-models [search] List available models (with optional fuzzy search)\n --help, -h Show this help\n --version, -v Show version number\n\nExtensions can register additional flags (e.g., --plan from plan-mode extension).\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n ${APP_NAME}\n\n # Interactive mode with initial prompt\n ${APP_NAME} \"List all .ts files in src/\"\n\n # Include files in initial message\n ${APP_NAME} @prompt.md @image.png \"What color is the sky?\"\n\n # Non-interactive mode (process and exit)\n ${APP_NAME} -p \"List all .ts files in src/\"\n\n # Multiple messages (interactive)\n ${APP_NAME} \"Read package.json\" \"What dependencies do we have?\"\n\n # Continue previous session\n ${APP_NAME} --continue \"What did we discuss?\"\n\n # Use different model\n ${APP_NAME} --provider openai --model gpt-4o-mini \"Help me refactor this code\"\n\n # Limit model cycling to specific models\n ${APP_NAME} --models claude-sonnet,claude-haiku,gpt-4o\n\n # Limit to a specific provider with glob pattern\n ${APP_NAME} --models \"github-copilot/*\"\n\n # Cycle models with fixed thinking levels\n ${APP_NAME} --models sonnet:high,haiku:low\n\n # Start with a specific thinking level\n ${APP_NAME} --thinking high \"Solve this complex problem\"\n\n # Read-only mode (no file modifications possible)\n ${APP_NAME} --tools read,grep,find,ls -p \"Review the code in src/\"\n\n # Export a session file to HTML\n ${APP_NAME} --export ~/${CONFIG_DIR_NAME}/agent/sessions/--path--/session.jsonl\n ${APP_NAME} --export session.jsonl output.html\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY - Anthropic Claude API key\n ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)\n OPENAI_API_KEY - OpenAI GPT API key\n GEMINI_API_KEY - Google Gemini API key\n GROQ_API_KEY - Groq API key\n CEREBRAS_API_KEY - Cerebras API key\n XAI_API_KEY - xAI Grok API key\n OPENROUTER_API_KEY - OpenRouter API key\n AI_GATEWAY_API_KEY - Vercel AI Gateway API key\n ZAI_API_KEY - ZAI API key\n MISTRAL_API_KEY - Mistral API key\n MINIMAX_API_KEY - MiniMax API key\n AWS_PROFILE - AWS profile for Amazon Bedrock\n AWS_ACCESS_KEY_ID - AWS access key for Amazon Bedrock\n AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock\n AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (bearer token)\n AWS_REGION - AWS region for Amazon Bedrock (e.g., us-east-1)\n ${ENV_AGENT_DIR.padEnd(23)} - Session storage directory (default: ~/${CONFIG_DIR_NAME}/agent)\n\n${chalk.bold(\"Available Tools (default: read, bash, edit, write):\")}\n read - Read file contents\n bash - Execute bash commands\n edit - Edit files with find/replace\n write - Write files (creates/overwrites)\n grep - Search file contents (read-only, off by default)\n find - Find files by glob pattern (read-only, off by default)\n ls - List directory contents (read-only, off by default)\n`);\n}\n"]}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Process @file CLI arguments into text content and image attachments
3
+ */
4
+ import type { ImageContent } from "@mariozechner/pi-ai";
5
+ export interface ProcessedFiles {
6
+ text: string;
7
+ images: ImageContent[];
8
+ }
9
+ export interface ProcessFileOptions {
10
+ /** Whether to auto-resize images to 2000x2000 max. Default: true */
11
+ autoResizeImages?: boolean;
12
+ }
13
+ /** Process @file arguments into text content and image attachments */
14
+ export declare function processFileArguments(fileArgs: string[], options?: ProcessFileOptions): Promise<ProcessedFiles>;
15
+ //# sourceMappingURL=file-processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-processor.d.ts","sourceRoot":"","sources":["../../src/cli/file-processor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAOxD,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IAClC,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,sEAAsE;AACtE,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CAwEpH","sourcesContent":["/**\n * Process @file CLI arguments into text content and image attachments\n */\n\nimport { access, readFile, stat } from \"node:fs/promises\";\nimport type { ImageContent } from \"@mariozechner/pi-ai\";\nimport chalk from \"chalk\";\nimport { resolve } from \"path\";\nimport { resolveReadPath } from \"../core/tools/path-utils.js\";\nimport { formatDimensionNote, resizeImage } from \"../utils/image-resize.js\";\nimport { detectSupportedImageMimeTypeFromFile } from \"../utils/mime.js\";\n\nexport interface ProcessedFiles {\n\ttext: string;\n\timages: ImageContent[];\n}\n\nexport interface ProcessFileOptions {\n\t/** Whether to auto-resize images to 2000x2000 max. Default: true */\n\tautoResizeImages?: boolean;\n}\n\n/** Process @file arguments into text content and image attachments */\nexport async function processFileArguments(fileArgs: string[], options?: ProcessFileOptions): Promise<ProcessedFiles> {\n\tconst autoResizeImages = options?.autoResizeImages ?? true;\n\tlet text = \"\";\n\tconst images: ImageContent[] = [];\n\n\tfor (const fileArg of fileArgs) {\n\t\t// Expand and resolve path (handles ~ expansion and macOS screenshot Unicode spaces)\n\t\tconst absolutePath = resolve(resolveReadPath(fileArg, process.cwd()));\n\n\t\t// Check if file exists\n\t\ttry {\n\t\t\tawait access(absolutePath);\n\t\t} catch {\n\t\t\tconsole.error(chalk.red(`Error: File not found: ${absolutePath}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Check if file is empty\n\t\tconst stats = await stat(absolutePath);\n\t\tif (stats.size === 0) {\n\t\t\t// Skip empty files\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst mimeType = await detectSupportedImageMimeTypeFromFile(absolutePath);\n\n\t\tif (mimeType) {\n\t\t\t// Handle image file\n\t\t\tconst content = await readFile(absolutePath);\n\t\t\tconst base64Content = content.toString(\"base64\");\n\n\t\t\tlet attachment: ImageContent;\n\t\t\tlet dimensionNote: string | undefined;\n\n\t\t\tif (autoResizeImages) {\n\t\t\t\tconst resized = await resizeImage({ type: \"image\", data: base64Content, mimeType });\n\t\t\t\tdimensionNote = formatDimensionNote(resized);\n\t\t\t\tattachment = {\n\t\t\t\t\ttype: \"image\",\n\t\t\t\t\tmimeType: resized.mimeType,\n\t\t\t\t\tdata: resized.data,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tattachment = {\n\t\t\t\t\ttype: \"image\",\n\t\t\t\t\tmimeType,\n\t\t\t\t\tdata: base64Content,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\timages.push(attachment);\n\n\t\t\t// Add text reference to image with optional dimension note\n\t\t\tif (dimensionNote) {\n\t\t\t\ttext += `<file name=\"${absolutePath}\">${dimensionNote}</file>\\n`;\n\t\t\t} else {\n\t\t\t\ttext += `<file name=\"${absolutePath}\"></file>\\n`;\n\t\t\t}\n\t\t} else {\n\t\t\t// Handle text file\n\t\t\ttry {\n\t\t\t\tconst content = await readFile(absolutePath, \"utf-8\");\n\t\t\t\ttext += `<file name=\"${absolutePath}\">\\n${content}\\n</file>\\n`;\n\t\t\t} catch (error: unknown) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tconsole.error(chalk.red(`Error: Could not read file ${absolutePath}: ${message}`));\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { text, images };\n}\n"]}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Process @file CLI arguments into text content and image attachments
3
+ */
4
+ import { access, readFile, stat } from "node:fs/promises";
5
+ import chalk from "chalk";
6
+ import { resolve } from "path";
7
+ import { resolveReadPath } from "../core/tools/path-utils.js";
8
+ import { formatDimensionNote, resizeImage } from "../utils/image-resize.js";
9
+ import { detectSupportedImageMimeTypeFromFile } from "../utils/mime.js";
10
+ /** Process @file arguments into text content and image attachments */
11
+ export async function processFileArguments(fileArgs, options) {
12
+ const autoResizeImages = options?.autoResizeImages ?? true;
13
+ let text = "";
14
+ const images = [];
15
+ for (const fileArg of fileArgs) {
16
+ // Expand and resolve path (handles ~ expansion and macOS screenshot Unicode spaces)
17
+ const absolutePath = resolve(resolveReadPath(fileArg, process.cwd()));
18
+ // Check if file exists
19
+ try {
20
+ await access(absolutePath);
21
+ }
22
+ catch {
23
+ console.error(chalk.red(`Error: File not found: ${absolutePath}`));
24
+ process.exit(1);
25
+ }
26
+ // Check if file is empty
27
+ const stats = await stat(absolutePath);
28
+ if (stats.size === 0) {
29
+ // Skip empty files
30
+ continue;
31
+ }
32
+ const mimeType = await detectSupportedImageMimeTypeFromFile(absolutePath);
33
+ if (mimeType) {
34
+ // Handle image file
35
+ const content = await readFile(absolutePath);
36
+ const base64Content = content.toString("base64");
37
+ let attachment;
38
+ let dimensionNote;
39
+ if (autoResizeImages) {
40
+ const resized = await resizeImage({ type: "image", data: base64Content, mimeType });
41
+ dimensionNote = formatDimensionNote(resized);
42
+ attachment = {
43
+ type: "image",
44
+ mimeType: resized.mimeType,
45
+ data: resized.data,
46
+ };
47
+ }
48
+ else {
49
+ attachment = {
50
+ type: "image",
51
+ mimeType,
52
+ data: base64Content,
53
+ };
54
+ }
55
+ images.push(attachment);
56
+ // Add text reference to image with optional dimension note
57
+ if (dimensionNote) {
58
+ text += `<file name="${absolutePath}">${dimensionNote}</file>\n`;
59
+ }
60
+ else {
61
+ text += `<file name="${absolutePath}"></file>\n`;
62
+ }
63
+ }
64
+ else {
65
+ // Handle text file
66
+ try {
67
+ const content = await readFile(absolutePath, "utf-8");
68
+ text += `<file name="${absolutePath}">\n${content}\n</file>\n`;
69
+ }
70
+ catch (error) {
71
+ const message = error instanceof Error ? error.message : String(error);
72
+ console.error(chalk.red(`Error: Could not read file ${absolutePath}: ${message}`));
73
+ process.exit(1);
74
+ }
75
+ }
76
+ }
77
+ return { text, images };
78
+ }
79
+ //# sourceMappingURL=file-processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-processor.js","sourceRoot":"","sources":["../../src/cli/file-processor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Process @file CLI arguments into text content and image attachments\n */\n\nimport { access, readFile, stat } from \"node:fs/promises\";\nimport type { ImageContent } from \"@mariozechner/pi-ai\";\nimport chalk from \"chalk\";\nimport { resolve } from \"path\";\nimport { resolveReadPath } from \"../core/tools/path-utils.js\";\nimport { formatDimensionNote, resizeImage } from \"../utils/image-resize.js\";\nimport { detectSupportedImageMimeTypeFromFile } from \"../utils/mime.js\";\n\nexport interface ProcessedFiles {\n\ttext: string;\n\timages: ImageContent[];\n}\n\nexport interface ProcessFileOptions {\n\t/** Whether to auto-resize images to 2000x2000 max. Default: true */\n\tautoResizeImages?: boolean;\n}\n\n/** Process @file arguments into text content and image attachments */\nexport async function processFileArguments(fileArgs: string[], options?: ProcessFileOptions): Promise<ProcessedFiles> {\n\tconst autoResizeImages = options?.autoResizeImages ?? true;\n\tlet text = \"\";\n\tconst images: ImageContent[] = [];\n\n\tfor (const fileArg of fileArgs) {\n\t\t// Expand and resolve path (handles ~ expansion and macOS screenshot Unicode spaces)\n\t\tconst absolutePath = resolve(resolveReadPath(fileArg, process.cwd()));\n\n\t\t// Check if file exists\n\t\ttry {\n\t\t\tawait access(absolutePath);\n\t\t} catch {\n\t\t\tconsole.error(chalk.red(`Error: File not found: ${absolutePath}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Check if file is empty\n\t\tconst stats = await stat(absolutePath);\n\t\tif (stats.size === 0) {\n\t\t\t// Skip empty files\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst mimeType = await detectSupportedImageMimeTypeFromFile(absolutePath);\n\n\t\tif (mimeType) {\n\t\t\t// Handle image file\n\t\t\tconst content = await readFile(absolutePath);\n\t\t\tconst base64Content = content.toString(\"base64\");\n\n\t\t\tlet attachment: ImageContent;\n\t\t\tlet dimensionNote: string | undefined;\n\n\t\t\tif (autoResizeImages) {\n\t\t\t\tconst resized = await resizeImage({ type: \"image\", data: base64Content, mimeType });\n\t\t\t\tdimensionNote = formatDimensionNote(resized);\n\t\t\t\tattachment = {\n\t\t\t\t\ttype: \"image\",\n\t\t\t\t\tmimeType: resized.mimeType,\n\t\t\t\t\tdata: resized.data,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tattachment = {\n\t\t\t\t\ttype: \"image\",\n\t\t\t\t\tmimeType,\n\t\t\t\t\tdata: base64Content,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\timages.push(attachment);\n\n\t\t\t// Add text reference to image with optional dimension note\n\t\t\tif (dimensionNote) {\n\t\t\t\ttext += `<file name=\"${absolutePath}\">${dimensionNote}</file>\\n`;\n\t\t\t} else {\n\t\t\t\ttext += `<file name=\"${absolutePath}\"></file>\\n`;\n\t\t\t}\n\t\t} else {\n\t\t\t// Handle text file\n\t\t\ttry {\n\t\t\t\tconst content = await readFile(absolutePath, \"utf-8\");\n\t\t\t\ttext += `<file name=\"${absolutePath}\">\\n${content}\\n</file>\\n`;\n\t\t\t} catch (error: unknown) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tconsole.error(chalk.red(`Error: Could not read file ${absolutePath}: ${message}`));\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { text, images };\n}\n"]}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * List available models with optional fuzzy search
3
+ */
4
+ import type { ModelRegistry } from "../core/model-registry.js";
5
+ /**
6
+ * List available models, optionally filtered by search pattern
7
+ */
8
+ export declare function listModels(modelRegistry: ModelRegistry, searchPattern?: string): Promise<void>;
9
+ //# sourceMappingURL=list-models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-models.d.ts","sourceRoot":"","sources":["../../src/cli/list-models.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAiB/D;;GAEG;AACH,wBAAsB,UAAU,CAAC,aAAa,EAAE,aAAa,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6EpG","sourcesContent":["/**\n * List available models with optional fuzzy search\n */\n\nimport type { Api, Model } from \"@mariozechner/pi-ai\";\nimport { fuzzyFilter } from \"@mariozechner/pi-tui\";\nimport type { ModelRegistry } from \"../core/model-registry.js\";\n\n/**\n * Format a number as human-readable (e.g., 200000 -> \"200K\", 1000000 -> \"1M\")\n */\nfunction formatTokenCount(count: number): string {\n\tif (count >= 1_000_000) {\n\t\tconst millions = count / 1_000_000;\n\t\treturn millions % 1 === 0 ? `${millions}M` : `${millions.toFixed(1)}M`;\n\t}\n\tif (count >= 1_000) {\n\t\tconst thousands = count / 1_000;\n\t\treturn thousands % 1 === 0 ? `${thousands}K` : `${thousands.toFixed(1)}K`;\n\t}\n\treturn count.toString();\n}\n\n/**\n * List available models, optionally filtered by search pattern\n */\nexport async function listModels(modelRegistry: ModelRegistry, searchPattern?: string): Promise<void> {\n\tconst models = modelRegistry.getAvailable();\n\n\tif (models.length === 0) {\n\t\tconsole.log(\"No models available. Set API keys in environment variables.\");\n\t\treturn;\n\t}\n\n\t// Apply fuzzy filter if search pattern provided\n\tlet filteredModels: Model<Api>[] = models;\n\tif (searchPattern) {\n\t\tfilteredModels = fuzzyFilter(models, searchPattern, (m) => `${m.provider} ${m.id}`);\n\t}\n\n\tif (filteredModels.length === 0) {\n\t\tconsole.log(`No models matching \"${searchPattern}\"`);\n\t\treturn;\n\t}\n\n\t// Sort by provider, then by model id\n\tfilteredModels.sort((a, b) => {\n\t\tconst providerCmp = a.provider.localeCompare(b.provider);\n\t\tif (providerCmp !== 0) return providerCmp;\n\t\treturn a.id.localeCompare(b.id);\n\t});\n\n\t// Calculate column widths\n\tconst rows = filteredModels.map((m) => ({\n\t\tprovider: m.provider,\n\t\tmodel: m.id,\n\t\tcontext: formatTokenCount(m.contextWindow),\n\t\tmaxOut: formatTokenCount(m.maxTokens),\n\t\tthinking: m.reasoning ? \"yes\" : \"no\",\n\t\timages: m.input.includes(\"image\") ? \"yes\" : \"no\",\n\t}));\n\n\tconst headers = {\n\t\tprovider: \"provider\",\n\t\tmodel: \"model\",\n\t\tcontext: \"context\",\n\t\tmaxOut: \"max-out\",\n\t\tthinking: \"thinking\",\n\t\timages: \"images\",\n\t};\n\n\tconst widths = {\n\t\tprovider: Math.max(headers.provider.length, ...rows.map((r) => r.provider.length)),\n\t\tmodel: Math.max(headers.model.length, ...rows.map((r) => r.model.length)),\n\t\tcontext: Math.max(headers.context.length, ...rows.map((r) => r.context.length)),\n\t\tmaxOut: Math.max(headers.maxOut.length, ...rows.map((r) => r.maxOut.length)),\n\t\tthinking: Math.max(headers.thinking.length, ...rows.map((r) => r.thinking.length)),\n\t\timages: Math.max(headers.images.length, ...rows.map((r) => r.images.length)),\n\t};\n\n\t// Print header\n\tconst headerLine = [\n\t\theaders.provider.padEnd(widths.provider),\n\t\theaders.model.padEnd(widths.model),\n\t\theaders.context.padEnd(widths.context),\n\t\theaders.maxOut.padEnd(widths.maxOut),\n\t\theaders.thinking.padEnd(widths.thinking),\n\t\theaders.images.padEnd(widths.images),\n\t].join(\" \");\n\tconsole.log(headerLine);\n\n\t// Print rows\n\tfor (const row of rows) {\n\t\tconst line = [\n\t\t\trow.provider.padEnd(widths.provider),\n\t\t\trow.model.padEnd(widths.model),\n\t\t\trow.context.padEnd(widths.context),\n\t\t\trow.maxOut.padEnd(widths.maxOut),\n\t\t\trow.thinking.padEnd(widths.thinking),\n\t\t\trow.images.padEnd(widths.images),\n\t\t].join(\" \");\n\t\tconsole.log(line);\n\t}\n}\n"]}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * List available models with optional fuzzy search
3
+ */
4
+ import { fuzzyFilter } from "@mariozechner/pi-tui";
5
+ /**
6
+ * Format a number as human-readable (e.g., 200000 -> "200K", 1000000 -> "1M")
7
+ */
8
+ function formatTokenCount(count) {
9
+ if (count >= 1_000_000) {
10
+ const millions = count / 1_000_000;
11
+ return millions % 1 === 0 ? `${millions}M` : `${millions.toFixed(1)}M`;
12
+ }
13
+ if (count >= 1_000) {
14
+ const thousands = count / 1_000;
15
+ return thousands % 1 === 0 ? `${thousands}K` : `${thousands.toFixed(1)}K`;
16
+ }
17
+ return count.toString();
18
+ }
19
+ /**
20
+ * List available models, optionally filtered by search pattern
21
+ */
22
+ export async function listModels(modelRegistry, searchPattern) {
23
+ const models = modelRegistry.getAvailable();
24
+ if (models.length === 0) {
25
+ console.log("No models available. Set API keys in environment variables.");
26
+ return;
27
+ }
28
+ // Apply fuzzy filter if search pattern provided
29
+ let filteredModels = models;
30
+ if (searchPattern) {
31
+ filteredModels = fuzzyFilter(models, searchPattern, (m) => `${m.provider} ${m.id}`);
32
+ }
33
+ if (filteredModels.length === 0) {
34
+ console.log(`No models matching "${searchPattern}"`);
35
+ return;
36
+ }
37
+ // Sort by provider, then by model id
38
+ filteredModels.sort((a, b) => {
39
+ const providerCmp = a.provider.localeCompare(b.provider);
40
+ if (providerCmp !== 0)
41
+ return providerCmp;
42
+ return a.id.localeCompare(b.id);
43
+ });
44
+ // Calculate column widths
45
+ const rows = filteredModels.map((m) => ({
46
+ provider: m.provider,
47
+ model: m.id,
48
+ context: formatTokenCount(m.contextWindow),
49
+ maxOut: formatTokenCount(m.maxTokens),
50
+ thinking: m.reasoning ? "yes" : "no",
51
+ images: m.input.includes("image") ? "yes" : "no",
52
+ }));
53
+ const headers = {
54
+ provider: "provider",
55
+ model: "model",
56
+ context: "context",
57
+ maxOut: "max-out",
58
+ thinking: "thinking",
59
+ images: "images",
60
+ };
61
+ const widths = {
62
+ provider: Math.max(headers.provider.length, ...rows.map((r) => r.provider.length)),
63
+ model: Math.max(headers.model.length, ...rows.map((r) => r.model.length)),
64
+ context: Math.max(headers.context.length, ...rows.map((r) => r.context.length)),
65
+ maxOut: Math.max(headers.maxOut.length, ...rows.map((r) => r.maxOut.length)),
66
+ thinking: Math.max(headers.thinking.length, ...rows.map((r) => r.thinking.length)),
67
+ images: Math.max(headers.images.length, ...rows.map((r) => r.images.length)),
68
+ };
69
+ // Print header
70
+ const headerLine = [
71
+ headers.provider.padEnd(widths.provider),
72
+ headers.model.padEnd(widths.model),
73
+ headers.context.padEnd(widths.context),
74
+ headers.maxOut.padEnd(widths.maxOut),
75
+ headers.thinking.padEnd(widths.thinking),
76
+ headers.images.padEnd(widths.images),
77
+ ].join(" ");
78
+ console.log(headerLine);
79
+ // Print rows
80
+ for (const row of rows) {
81
+ const line = [
82
+ row.provider.padEnd(widths.provider),
83
+ row.model.padEnd(widths.model),
84
+ row.context.padEnd(widths.context),
85
+ row.maxOut.padEnd(widths.maxOut),
86
+ row.thinking.padEnd(widths.thinking),
87
+ row.images.padEnd(widths.images),
88
+ ].join(" ");
89
+ console.log(line);
90
+ }
91
+ }
92
+ //# sourceMappingURL=list-models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-models.js","sourceRoot":"","sources":["../../src/cli/list-models.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * List available models with optional fuzzy search\n */\n\nimport type { Api, Model } from \"@mariozechner/pi-ai\";\nimport { fuzzyFilter } from \"@mariozechner/pi-tui\";\nimport type { ModelRegistry } from \"../core/model-registry.js\";\n\n/**\n * Format a number as human-readable (e.g., 200000 -> \"200K\", 1000000 -> \"1M\")\n */\nfunction formatTokenCount(count: number): string {\n\tif (count >= 1_000_000) {\n\t\tconst millions = count / 1_000_000;\n\t\treturn millions % 1 === 0 ? `${millions}M` : `${millions.toFixed(1)}M`;\n\t}\n\tif (count >= 1_000) {\n\t\tconst thousands = count / 1_000;\n\t\treturn thousands % 1 === 0 ? `${thousands}K` : `${thousands.toFixed(1)}K`;\n\t}\n\treturn count.toString();\n}\n\n/**\n * List available models, optionally filtered by search pattern\n */\nexport async function listModels(modelRegistry: ModelRegistry, searchPattern?: string): Promise<void> {\n\tconst models = modelRegistry.getAvailable();\n\n\tif (models.length === 0) {\n\t\tconsole.log(\"No models available. Set API keys in environment variables.\");\n\t\treturn;\n\t}\n\n\t// Apply fuzzy filter if search pattern provided\n\tlet filteredModels: Model<Api>[] = models;\n\tif (searchPattern) {\n\t\tfilteredModels = fuzzyFilter(models, searchPattern, (m) => `${m.provider} ${m.id}`);\n\t}\n\n\tif (filteredModels.length === 0) {\n\t\tconsole.log(`No models matching \"${searchPattern}\"`);\n\t\treturn;\n\t}\n\n\t// Sort by provider, then by model id\n\tfilteredModels.sort((a, b) => {\n\t\tconst providerCmp = a.provider.localeCompare(b.provider);\n\t\tif (providerCmp !== 0) return providerCmp;\n\t\treturn a.id.localeCompare(b.id);\n\t});\n\n\t// Calculate column widths\n\tconst rows = filteredModels.map((m) => ({\n\t\tprovider: m.provider,\n\t\tmodel: m.id,\n\t\tcontext: formatTokenCount(m.contextWindow),\n\t\tmaxOut: formatTokenCount(m.maxTokens),\n\t\tthinking: m.reasoning ? \"yes\" : \"no\",\n\t\timages: m.input.includes(\"image\") ? \"yes\" : \"no\",\n\t}));\n\n\tconst headers = {\n\t\tprovider: \"provider\",\n\t\tmodel: \"model\",\n\t\tcontext: \"context\",\n\t\tmaxOut: \"max-out\",\n\t\tthinking: \"thinking\",\n\t\timages: \"images\",\n\t};\n\n\tconst widths = {\n\t\tprovider: Math.max(headers.provider.length, ...rows.map((r) => r.provider.length)),\n\t\tmodel: Math.max(headers.model.length, ...rows.map((r) => r.model.length)),\n\t\tcontext: Math.max(headers.context.length, ...rows.map((r) => r.context.length)),\n\t\tmaxOut: Math.max(headers.maxOut.length, ...rows.map((r) => r.maxOut.length)),\n\t\tthinking: Math.max(headers.thinking.length, ...rows.map((r) => r.thinking.length)),\n\t\timages: Math.max(headers.images.length, ...rows.map((r) => r.images.length)),\n\t};\n\n\t// Print header\n\tconst headerLine = [\n\t\theaders.provider.padEnd(widths.provider),\n\t\theaders.model.padEnd(widths.model),\n\t\theaders.context.padEnd(widths.context),\n\t\theaders.maxOut.padEnd(widths.maxOut),\n\t\theaders.thinking.padEnd(widths.thinking),\n\t\theaders.images.padEnd(widths.images),\n\t].join(\" \");\n\tconsole.log(headerLine);\n\n\t// Print rows\n\tfor (const row of rows) {\n\t\tconst line = [\n\t\t\trow.provider.padEnd(widths.provider),\n\t\t\trow.model.padEnd(widths.model),\n\t\t\trow.context.padEnd(widths.context),\n\t\t\trow.maxOut.padEnd(widths.maxOut),\n\t\t\trow.thinking.padEnd(widths.thinking),\n\t\t\trow.images.padEnd(widths.images),\n\t\t].join(\" \");\n\t\tconsole.log(line);\n\t}\n}\n"]}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * TUI session selector for --resume flag
3
+ */
4
+ import type { SessionInfo, SessionListProgress } from "../core/session-manager.js";
5
+ type SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;
6
+ /** Show TUI session selector and return selected session path or null if cancelled */
7
+ export declare function selectSession(currentSessionsLoader: SessionsLoader, allSessionsLoader: SessionsLoader): Promise<string | null>;
8
+ export {};
9
+ //# sourceMappingURL=session-picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-picker.d.ts","sourceRoot":"","sources":["../../src/cli/session-picker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGnF,KAAK,cAAc,GAAG,CAAC,UAAU,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;AAEnF,sFAAsF;AACtF,wBAAsB,aAAa,CAClC,qBAAqB,EAAE,cAAc,EACrC,iBAAiB,EAAE,cAAc,GAC/B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiCxB","sourcesContent":["/**\n * TUI session selector for --resume flag\n */\n\nimport { ProcessTerminal, TUI } from \"@mariozechner/pi-tui\";\nimport type { SessionInfo, SessionListProgress } from \"../core/session-manager.js\";\nimport { SessionSelectorComponent } from \"../modes/interactive/components/session-selector.js\";\n\ntype SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;\n\n/** Show TUI session selector and return selected session path or null if cancelled */\nexport async function selectSession(\n\tcurrentSessionsLoader: SessionsLoader,\n\tallSessionsLoader: SessionsLoader,\n): Promise<string | null> {\n\treturn new Promise((resolve) => {\n\t\tconst ui = new TUI(new ProcessTerminal());\n\t\tlet resolved = false;\n\n\t\tconst selector = new SessionSelectorComponent(\n\t\t\tcurrentSessionsLoader,\n\t\t\tallSessionsLoader,\n\t\t\t(path: string) => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(path);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tui.stop();\n\t\t\t\tprocess.exit(0);\n\t\t\t},\n\t\t\t() => ui.requestRender(),\n\t\t);\n\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector.getSessionList());\n\t\tui.start();\n\t});\n}\n"]}