@openadapter/koda 1.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (357) hide show
  1. package/CHANGELOG.md +4448 -0
  2. package/README.md +665 -0
  3. package/dist/bun/cli.d.ts +2 -0
  4. package/dist/bun/cli.js +2 -0
  5. package/dist/bun/register-bedrock.d.ts +1 -0
  6. package/dist/bun/register-bedrock.js +1 -0
  7. package/dist/bun/restore-sandbox-env.d.ts +12 -0
  8. package/dist/bun/restore-sandbox-env.js +1 -0
  9. package/dist/cli/args.d.ts +55 -0
  10. package/dist/cli/args.js +167 -0
  11. package/dist/cli/config-selector.d.ts +13 -0
  12. package/dist/cli/config-selector.js +1 -0
  13. package/dist/cli/file-processor.d.ts +14 -0
  14. package/dist/cli/file-processor.js +7 -0
  15. package/dist/cli/import-sessions.d.ts +34 -0
  16. package/dist/cli/import-sessions.js +6 -0
  17. package/dist/cli/initial-message.d.ts +17 -0
  18. package/dist/cli/initial-message.js +1 -0
  19. package/dist/cli/list-models.d.ts +8 -0
  20. package/dist/cli/list-models.js +2 -0
  21. package/dist/cli/openadapter-setup.d.ts +29 -0
  22. package/dist/cli/openadapter-setup.js +3 -0
  23. package/dist/cli/session-picker.d.ts +8 -0
  24. package/dist/cli/session-picker.js +1 -0
  25. package/dist/cli.d.ts +2 -0
  26. package/dist/cli.js +2 -0
  27. package/dist/config.d.ts +92 -0
  28. package/dist/config.js +1 -0
  29. package/dist/core/agent-session-runtime.d.ts +116 -0
  30. package/dist/core/agent-session-runtime.js +1 -0
  31. package/dist/core/agent-session-services.d.ts +86 -0
  32. package/dist/core/agent-session-services.js +1 -0
  33. package/dist/core/agent-session.d.ts +747 -0
  34. package/dist/core/agent-session.js +32 -0
  35. package/dist/core/auth-guidance.d.ts +4 -0
  36. package/dist/core/auth-guidance.js +8 -0
  37. package/dist/core/auth-storage.d.ts +140 -0
  38. package/dist/core/auth-storage.js +1 -0
  39. package/dist/core/bash-executor.d.ts +31 -0
  40. package/dist/core/bash-executor.js +1 -0
  41. package/dist/core/compaction/branch-summarization.d.ts +89 -0
  42. package/dist/core/compaction/branch-summarization.js +38 -0
  43. package/dist/core/compaction/compaction.d.ts +120 -0
  44. package/dist/core/compaction/compaction.js +104 -0
  45. package/dist/core/compaction/index.d.ts +6 -0
  46. package/dist/core/compaction/index.js +1 -0
  47. package/dist/core/compaction/utils.d.ts +37 -0
  48. package/dist/core/compaction/utils.js +19 -0
  49. package/dist/core/defaults.d.ts +2 -0
  50. package/dist/core/defaults.js +1 -0
  51. package/dist/core/diagnostics.d.ts +14 -0
  52. package/dist/core/diagnostics.js +0 -0
  53. package/dist/core/event-bus.d.ts +8 -0
  54. package/dist/core/event-bus.js +1 -0
  55. package/dist/core/exec.d.ts +28 -0
  56. package/dist/core/exec.js +1 -0
  57. package/dist/core/export-html/ansi-to-html.d.ts +21 -0
  58. package/dist/core/export-html/ansi-to-html.js +1 -0
  59. package/dist/core/export-html/index.d.ts +36 -0
  60. package/dist/core/export-html/index.js +2 -0
  61. package/dist/core/export-html/template.css +1066 -0
  62. package/dist/core/export-html/template.html +55 -0
  63. package/dist/core/export-html/template.js +72 -0
  64. package/dist/core/export-html/tool-renderer.d.ts +33 -0
  65. package/dist/core/export-html/tool-renderer.js +1 -0
  66. package/dist/core/export-html/vendor/highlight.min.js +8 -0
  67. package/dist/core/export-html/vendor/marked.min.js +56 -0
  68. package/dist/core/extensions/index.d.ts +11 -0
  69. package/dist/core/extensions/index.js +1 -0
  70. package/dist/core/extensions/loader.d.ts +23 -0
  71. package/dist/core/extensions/loader.js +1 -0
  72. package/dist/core/extensions/runner.d.ts +160 -0
  73. package/dist/core/extensions/runner.js +1 -0
  74. package/dist/core/extensions/types.d.ts +1180 -0
  75. package/dist/core/extensions/types.js +1 -0
  76. package/dist/core/extensions/wrapper.d.ts +19 -0
  77. package/dist/core/extensions/wrapper.js +1 -0
  78. package/dist/core/footer-data-provider.d.ts +53 -0
  79. package/dist/core/footer-data-provider.js +1 -0
  80. package/dist/core/http-dispatcher.d.ts +20 -0
  81. package/dist/core/http-dispatcher.js +1 -0
  82. package/dist/core/index.d.ts +11 -0
  83. package/dist/core/index.js +1 -0
  84. package/dist/core/keybindings.d.ts +352 -0
  85. package/dist/core/keybindings.js +1 -0
  86. package/dist/core/messages.d.ts +76 -0
  87. package/dist/core/messages.js +17 -0
  88. package/dist/core/model-registry.d.ts +149 -0
  89. package/dist/core/model-registry.js +9 -0
  90. package/dist/core/model-resolver.d.ts +109 -0
  91. package/dist/core/model-resolver.js +1 -0
  92. package/dist/core/output-guard.d.ts +6 -0
  93. package/dist/core/output-guard.js +1 -0
  94. package/dist/core/package-manager.d.ts +203 -0
  95. package/dist/core/package-manager.js +3 -0
  96. package/dist/core/prompt-templates.d.ts +51 -0
  97. package/dist/core/prompt-templates.js +2 -0
  98. package/dist/core/provider-attribution.d.ts +3 -0
  99. package/dist/core/provider-attribution.js +1 -0
  100. package/dist/core/provider-display-names.d.ts +1 -0
  101. package/dist/core/provider-display-names.js +1 -0
  102. package/dist/core/resolve-config-value.d.ts +30 -0
  103. package/dist/core/resolve-config-value.js +1 -0
  104. package/dist/core/resource-loader.d.ts +193 -0
  105. package/dist/core/resource-loader.js +1 -0
  106. package/dist/core/sdk.d.ts +108 -0
  107. package/dist/core/sdk.js +1 -0
  108. package/dist/core/session-cwd.d.ts +18 -0
  109. package/dist/core/session-cwd.js +7 -0
  110. package/dist/core/session-manager.d.ts +331 -0
  111. package/dist/core/session-manager.js +11 -0
  112. package/dist/core/settings-manager.d.ts +265 -0
  113. package/dist/core/settings-manager.js +1 -0
  114. package/dist/core/skills.d.ts +59 -0
  115. package/dist/core/skills.js +4 -0
  116. package/dist/core/slash-commands.d.ts +13 -0
  117. package/dist/core/slash-commands.js +1 -0
  118. package/dist/core/source-info.d.ts +17 -0
  119. package/dist/core/source-info.js +1 -0
  120. package/dist/core/system-prompt.d.ts +27 -0
  121. package/dist/core/system-prompt.js +52 -0
  122. package/dist/core/telemetry.d.ts +2 -0
  123. package/dist/core/telemetry.js +1 -0
  124. package/dist/core/timings.d.ts +7 -0
  125. package/dist/core/timings.js +3 -0
  126. package/dist/core/tools/bash.d.ts +67 -0
  127. package/dist/core/tools/bash.js +18 -0
  128. package/dist/core/tools/edit-diff.d.ts +86 -0
  129. package/dist/core/tools/edit-diff.js +16 -0
  130. package/dist/core/tools/edit.d.ts +50 -0
  131. package/dist/core/tools/edit.js +2 -0
  132. package/dist/core/tools/file-mutation-queue.d.ts +5 -0
  133. package/dist/core/tools/file-mutation-queue.js +1 -0
  134. package/dist/core/tools/find.d.ts +34 -0
  135. package/dist/core/tools/find.js +13 -0
  136. package/dist/core/tools/grep.d.ts +36 -0
  137. package/dist/core/tools/grep.js +13 -0
  138. package/dist/core/tools/index.d.ts +39 -0
  139. package/dist/core/tools/index.js +1 -0
  140. package/dist/core/tools/ls.d.ts +36 -0
  141. package/dist/core/tools/ls.js +9 -0
  142. package/dist/core/tools/output-accumulator.d.ts +51 -0
  143. package/dist/core/tools/output-accumulator.js +4 -0
  144. package/dist/core/tools/path-utils.d.ts +9 -0
  145. package/dist/core/tools/path-utils.js +1 -0
  146. package/dist/core/tools/read.d.ts +34 -0
  147. package/dist/core/tools/read.js +22 -0
  148. package/dist/core/tools/render-utils.d.ts +23 -0
  149. package/dist/core/tools/render-utils.js +4 -0
  150. package/dist/core/tools/tool-definition-wrapper.d.ts +13 -0
  151. package/dist/core/tools/tool-definition-wrapper.js +1 -0
  152. package/dist/core/tools/truncate.d.ts +69 -0
  153. package/dist/core/tools/truncate.js +5 -0
  154. package/dist/core/tools/write.d.ts +25 -0
  155. package/dist/core/tools/write.js +13 -0
  156. package/dist/index.d.ts +30 -0
  157. package/dist/index.js +1 -0
  158. package/dist/main.d.ts +11 -0
  159. package/dist/main.js +1 -0
  160. package/dist/migrations.d.ts +32 -0
  161. package/dist/migrations.js +8 -0
  162. package/dist/modes/index.d.ts +8 -0
  163. package/dist/modes/index.js +1 -0
  164. package/dist/modes/interactive/assets/clankolas.png +0 -0
  165. package/dist/modes/interactive/components/armin.d.ts +33 -0
  166. package/dist/modes/interactive/components/armin.js +1 -0
  167. package/dist/modes/interactive/components/assistant-message.d.ts +19 -0
  168. package/dist/modes/interactive/components/assistant-message.js +1 -0
  169. package/dist/modes/interactive/components/bash-execution.d.ts +33 -0
  170. package/dist/modes/interactive/components/bash-execution.js +13 -0
  171. package/dist/modes/interactive/components/bordered-loader.d.ts +15 -0
  172. package/dist/modes/interactive/components/bordered-loader.js +1 -0
  173. package/dist/modes/interactive/components/branch-summary-message.d.ts +15 -0
  174. package/dist/modes/interactive/components/branch-summary-message.js +3 -0
  175. package/dist/modes/interactive/components/compaction-summary-message.d.ts +15 -0
  176. package/dist/modes/interactive/components/compaction-summary-message.js +3 -0
  177. package/dist/modes/interactive/components/config-selector.d.ts +70 -0
  178. package/dist/modes/interactive/components/config-selector.js +1 -0
  179. package/dist/modes/interactive/components/countdown-timer.d.ts +13 -0
  180. package/dist/modes/interactive/components/countdown-timer.js +1 -0
  181. package/dist/modes/interactive/components/custom-editor.d.ts +20 -0
  182. package/dist/modes/interactive/components/custom-editor.js +1 -0
  183. package/dist/modes/interactive/components/custom-message.d.ts +19 -0
  184. package/dist/modes/interactive/components/custom-message.js +2 -0
  185. package/dist/modes/interactive/components/daxnuts.d.ts +22 -0
  186. package/dist/modes/interactive/components/daxnuts.js +1 -0
  187. package/dist/modes/interactive/components/diff.d.ts +11 -0
  188. package/dist/modes/interactive/components/diff.js +3 -0
  189. package/dist/modes/interactive/components/dynamic-border.d.ts +14 -0
  190. package/dist/modes/interactive/components/dynamic-border.js +1 -0
  191. package/dist/modes/interactive/components/earendil-announcement.d.ts +4 -0
  192. package/dist/modes/interactive/components/earendil-announcement.js +1 -0
  193. package/dist/modes/interactive/components/extension-editor.d.ts +19 -0
  194. package/dist/modes/interactive/components/extension-editor.js +3 -0
  195. package/dist/modes/interactive/components/extension-input.d.ts +22 -0
  196. package/dist/modes/interactive/components/extension-input.js +2 -0
  197. package/dist/modes/interactive/components/extension-selector.d.ts +25 -0
  198. package/dist/modes/interactive/components/extension-selector.js +2 -0
  199. package/dist/modes/interactive/components/footer.d.ts +27 -0
  200. package/dist/modes/interactive/components/footer.js +1 -0
  201. package/dist/modes/interactive/components/index.d.ts +31 -0
  202. package/dist/modes/interactive/components/index.js +1 -0
  203. package/dist/modes/interactive/components/keybinding-hints.d.ts +12 -0
  204. package/dist/modes/interactive/components/keybinding-hints.js +1 -0
  205. package/dist/modes/interactive/components/login-dialog.d.ts +51 -0
  206. package/dist/modes/interactive/components/login-dialog.js +1 -0
  207. package/dist/modes/interactive/components/model-selector.d.ts +46 -0
  208. package/dist/modes/interactive/components/model-selector.js +2 -0
  209. package/dist/modes/interactive/components/oauth-selector.d.ts +30 -0
  210. package/dist/modes/interactive/components/oauth-selector.js +1 -0
  211. package/dist/modes/interactive/components/scoped-models-selector.d.ts +41 -0
  212. package/dist/modes/interactive/components/scoped-models-selector.js +1 -0
  213. package/dist/modes/interactive/components/session-selector-search.d.ts +22 -0
  214. package/dist/modes/interactive/components/session-selector-search.js +1 -0
  215. package/dist/modes/interactive/components/session-selector.d.ts +95 -0
  216. package/dist/modes/interactive/components/session-selector.js +2 -0
  217. package/dist/modes/interactive/components/settings-selector.d.ts +68 -0
  218. package/dist/modes/interactive/components/settings-selector.js +1 -0
  219. package/dist/modes/interactive/components/show-images-selector.d.ts +9 -0
  220. package/dist/modes/interactive/components/show-images-selector.js +1 -0
  221. package/dist/modes/interactive/components/skill-invocation-message.d.ts +16 -0
  222. package/dist/modes/interactive/components/skill-invocation-message.js +3 -0
  223. package/dist/modes/interactive/components/theme-selector.d.ts +10 -0
  224. package/dist/modes/interactive/components/theme-selector.js +1 -0
  225. package/dist/modes/interactive/components/thinking-selector.d.ts +10 -0
  226. package/dist/modes/interactive/components/thinking-selector.js +1 -0
  227. package/dist/modes/interactive/components/tool-execution.d.ts +62 -0
  228. package/dist/modes/interactive/components/tool-execution.js +4 -0
  229. package/dist/modes/interactive/components/tree-selector.d.ts +88 -0
  230. package/dist/modes/interactive/components/tree-selector.js +1 -0
  231. package/dist/modes/interactive/components/user-message-selector.d.ts +29 -0
  232. package/dist/modes/interactive/components/user-message-selector.js +1 -0
  233. package/dist/modes/interactive/components/user-message.d.ts +9 -0
  234. package/dist/modes/interactive/components/user-message.js +1 -0
  235. package/dist/modes/interactive/components/visual-truncate.d.ts +23 -0
  236. package/dist/modes/interactive/components/visual-truncate.js +1 -0
  237. package/dist/modes/interactive/interactive-mode.d.ts +417 -0
  238. package/dist/modes/interactive/interactive-mode.js +116 -0
  239. package/dist/modes/interactive/theme/dark.json +86 -0
  240. package/dist/modes/interactive/theme/light.json +85 -0
  241. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  242. package/dist/modes/interactive/theme/theme.d.ts +101 -0
  243. package/dist/modes/interactive/theme/theme.js +18 -0
  244. package/dist/modes/print-mode.d.ts +27 -0
  245. package/dist/modes/print-mode.js +4 -0
  246. package/dist/modes/rpc/jsonl.d.ts +16 -0
  247. package/dist/modes/rpc/jsonl.js +3 -0
  248. package/dist/modes/rpc/rpc-client.d.ts +226 -0
  249. package/dist/modes/rpc/rpc-client.js +1 -0
  250. package/dist/modes/rpc/rpc-mode.d.ts +19 -0
  251. package/dist/modes/rpc/rpc-mode.js +1 -0
  252. package/dist/modes/rpc/rpc-types.d.ts +419 -0
  253. package/dist/modes/rpc/rpc-types.js +0 -0
  254. package/dist/package-manager-cli.d.ts +3 -0
  255. package/dist/package-manager-cli.js +49 -0
  256. package/dist/utils/ansi.d.ts +1 -0
  257. package/dist/utils/ansi.js +1 -0
  258. package/dist/utils/auto-update.d.ts +13 -0
  259. package/dist/utils/auto-update.js +1 -0
  260. package/dist/utils/changelog.d.ts +20 -0
  261. package/dist/utils/changelog.js +4 -0
  262. package/dist/utils/child-process.d.ts +14 -0
  263. package/dist/utils/child-process.js +1 -0
  264. package/dist/utils/clipboard-image.d.ts +10 -0
  265. package/dist/utils/clipboard-image.js +1 -0
  266. package/dist/utils/clipboard-native.d.ts +9 -0
  267. package/dist/utils/clipboard-native.js +1 -0
  268. package/dist/utils/clipboard.d.ts +1 -0
  269. package/dist/utils/clipboard.js +1 -0
  270. package/dist/utils/deprecation.d.ts +3 -0
  271. package/dist/utils/deprecation.js +1 -0
  272. package/dist/utils/exif-orientation.d.ts +4 -0
  273. package/dist/utils/exif-orientation.js +1 -0
  274. package/dist/utils/frontmatter.d.ts +7 -0
  275. package/dist/utils/frontmatter.js +4 -0
  276. package/dist/utils/fs-watch.d.ts +4 -0
  277. package/dist/utils/fs-watch.js +1 -0
  278. package/dist/utils/git.d.ts +25 -0
  279. package/dist/utils/git.js +1 -0
  280. package/dist/utils/html.d.ts +6 -0
  281. package/dist/utils/html.js +1 -0
  282. package/dist/utils/image-convert.d.ts +8 -0
  283. package/dist/utils/image-convert.js +1 -0
  284. package/dist/utils/image-resize-core.d.ts +29 -0
  285. package/dist/utils/image-resize-core.js +1 -0
  286. package/dist/utils/image-resize-worker.d.ts +1 -0
  287. package/dist/utils/image-resize-worker.js +1 -0
  288. package/dist/utils/image-resize.d.ts +15 -0
  289. package/dist/utils/image-resize.js +1 -0
  290. package/dist/utils/json.d.ts +2 -0
  291. package/dist/utils/json.js +1 -0
  292. package/dist/utils/koda-user-agent.d.ts +1 -0
  293. package/dist/utils/koda-user-agent.js +1 -0
  294. package/dist/utils/mime.d.ts +2 -0
  295. package/dist/utils/mime.js +1 -0
  296. package/dist/utils/paths.d.ts +30 -0
  297. package/dist/utils/paths.js +1 -0
  298. package/dist/utils/photon.d.ts +20 -0
  299. package/dist/utils/photon.js +1 -0
  300. package/dist/utils/shell.d.ts +29 -0
  301. package/dist/utils/shell.js +8 -0
  302. package/dist/utils/sleep.d.ts +4 -0
  303. package/dist/utils/sleep.js +1 -0
  304. package/dist/utils/syntax-highlight.d.ts +11 -0
  305. package/dist/utils/syntax-highlight.js +2 -0
  306. package/dist/utils/tools-manager.d.ts +2 -0
  307. package/dist/utils/tools-manager.js +1 -0
  308. package/dist/utils/version-check.d.ts +14 -0
  309. package/dist/utils/version-check.js +1 -0
  310. package/dist/utils/windows-self-update.d.ts +2 -0
  311. package/dist/utils/windows-self-update.js +1 -0
  312. package/docs/compaction.md +394 -0
  313. package/docs/custom-provider.md +736 -0
  314. package/docs/development.md +71 -0
  315. package/docs/docs.json +148 -0
  316. package/docs/extensions.md +2626 -0
  317. package/docs/images/doom-extension.png +0 -0
  318. package/docs/images/exy.png +0 -0
  319. package/docs/images/interactive-mode.png +0 -0
  320. package/docs/images/tree-view.png +0 -0
  321. package/docs/index.md +80 -0
  322. package/docs/json.md +82 -0
  323. package/docs/keybindings.md +197 -0
  324. package/docs/models.md +493 -0
  325. package/docs/packages.md +226 -0
  326. package/docs/prompt-templates.md +88 -0
  327. package/docs/providers.md +253 -0
  328. package/docs/quickstart.md +165 -0
  329. package/docs/rpc.md +1408 -0
  330. package/docs/sdk.md +1137 -0
  331. package/docs/session-format.md +412 -0
  332. package/docs/sessions.md +145 -0
  333. package/docs/settings.md +281 -0
  334. package/docs/shell-aliases.md +13 -0
  335. package/docs/skills.md +231 -0
  336. package/docs/terminal-setup.md +114 -0
  337. package/docs/termux.md +127 -0
  338. package/docs/themes.md +295 -0
  339. package/docs/tmux.md +61 -0
  340. package/docs/tui.md +927 -0
  341. package/docs/usage.md +288 -0
  342. package/docs/windows.md +17 -0
  343. package/npm-shrinkwrap.json +1792 -0
  344. package/openadapter/extensions/koda-ask.js +12 -0
  345. package/openadapter/extensions/koda-bg.js +14 -0
  346. package/openadapter/extensions/koda-commands.mjs +15 -0
  347. package/openadapter/extensions/koda-help.js +8 -0
  348. package/openadapter/extensions/koda-memory.js +16 -0
  349. package/openadapter/extensions/koda-status.js +1 -0
  350. package/openadapter/extensions/koda-todo.js +4 -0
  351. package/openadapter/extensions/koda-vision.js +4 -0
  352. package/openadapter/extensions/koda-web.js +7 -0
  353. package/openadapter/setup.mjs +173 -0
  354. package/openadapter/skills/code-review/SKILL.md +22 -0
  355. package/openadapter/skills/debugging/SKILL.md +28 -0
  356. package/openadapter/skills/frontend/SKILL.md +38 -0
  357. package/package.json +108 -0
@@ -0,0 +1,116 @@
1
+ var He=Object.defineProperty;var h=(p,e)=>He(p,"name",{value:e,configurable:!0});import*as Fe from"node:crypto";import*as v from"node:fs";import*as F from"node:os";import*as E from"node:path";import{getProviders as qe}from"@openadapter/koda-ai";import{CombinedAutocompleteProvider as Be,Container as A,fuzzyFilter as Ue,getCapabilities as Oe,hyperlink as _e,Loader as D,Markdown as q,matchesKey as Ne,ProcessTerminal as Ke,Spacer as g,setKeybindings as je,Text as f,TruncatedText as K,TUI as ze,visibleWidth as Ge}from"@openadapter/koda-tui";import Ve from"chalk";import{spawn as j,spawnSync as Qe}from"child_process";import{APP_NAME as z,APP_TITLE as te,getAgentDir as Xe,getAuthPath as se,getDebugLogPath as Je,getDocsPath as Ye,getShareViewerUrl as Ze,KODA_VERSION as et,VERSION as L}from"../../config.js";import{parseSkillBlock as tt}from"../../core/agent-session.js";import{SessionImportFileNotFoundError as st}from"../../core/agent-session-runtime.js";import{FooterDataProvider as it}from"../../core/footer-data-provider.js";import{configureHttpDispatcher as G,formatHttpIdleTimeoutMs as nt}from"../../core/http-dispatcher.js";import{KeybindingsManager as ot}from"../../core/keybindings.js";import{createCompactionSummaryMessage as rt}from"../../core/messages.js";import{defaultModelPerProvider as ie,findExactModelReferenceMatch as at,resolveModelScope as ne}from"../../core/model-resolver.js";import{DefaultPackageManager as ht}from"../../core/package-manager.js";import{BUILT_IN_PROVIDER_DISPLAY_NAMES as dt}from"../../core/provider-display-names.js";import{formatMissingSessionCwdPrompt as lt,MissingSessionCwdError as oe}from"../../core/session-cwd.js";import{SessionManager as B}from"../../core/session-manager.js";import{BUILTIN_SLASH_COMMANDS as re}from"../../core/slash-commands.js";import{isInstallTelemetryEnabled as ct}from"../../core/telemetry.js";import{runBackgroundSelfUpdate as ut}from"../../utils/auto-update.js";import{getChangelogPath as ae,getNewEntries as gt,parseChangelog as he}from"../../utils/changelog.js";import{copyToClipboard as pt}from"../../utils/clipboard.js";import{extensionForImageMimeType as mt,readClipboardImage as ft}from"../../utils/clipboard-image.js";import{parseGitUrl as de}from"../../utils/git.js";import{getKodaUserAgent as Ct}from"../../utils/koda-user-agent.js";import{getCwdRelativePath as wt}from"../../utils/paths.js";import{killTrackedDetachedChildren as V}from"../../utils/shell.js";import{ensureTool as le}from"../../utils/tools-manager.js";import{checkForNewPiVersion as St}from"../../utils/version-check.js";import{ArminComponent as yt}from"./components/armin.js";import{AssistantMessageComponent as U}from"./components/assistant-message.js";import{BashExecutionComponent as Q}from"./components/bash-execution.js";import{BorderedLoader as Et}from"./components/bordered-loader.js";import{BranchSummaryMessageComponent as kt}from"./components/branch-summary-message.js";import{CompactionSummaryMessageComponent as bt}from"./components/compaction-summary-message.js";import{CountdownTimer as xt}from"./components/countdown-timer.js";import{CustomEditor as Mt}from"./components/custom-editor.js";import{CustomMessageComponent as Tt}from"./components/custom-message.js";import{DaxnutsComponent as $t}from"./components/daxnuts.js";import{DynamicBorder as k}from"./components/dynamic-border.js";import{EarendilAnnouncementComponent as Pt}from"./components/earendil-announcement.js";import{ExtensionEditorComponent as At}from"./components/extension-editor.js";import{ExtensionInputComponent as Rt}from"./components/extension-input.js";import{ExtensionSelectorComponent as X}from"./components/extension-selector.js";import{FooterComponent as vt}from"./components/footer.js";import{formatKeyText as ce,keyDisplayText as ue,keyHint as ge,keyText as P,rawKeyHint as R}from"./components/keybinding-hints.js";import{LoginDialogComponent as J}from"./components/login-dialog.js";import{ModelSelectorComponent as It}from"./components/model-selector.js";import{OAuthSelectorComponent as pe}from"./components/oauth-selector.js";import{ScopedModelsSelectorComponent as Dt}from"./components/scoped-models-selector.js";import{SessionSelectorComponent as Lt}from"./components/session-selector.js";import{SettingsSelectorComponent as Wt}from"./components/settings-selector.js";import{SkillInvocationMessageComponent as Ht}from"./components/skill-invocation-message.js";import{ToolExecutionComponent as W}from"./components/tool-execution.js";import{TreeSelectorComponent as Ft}from"./components/tree-selector.js";import{UserMessageComponent as me}from"./components/user-message.js";import{UserMessageSelectorComponent as qt}from"./components/user-message-selector.js";import{getAvailableThemes as Bt,getAvailableThemesWithPaths as Ut,getEditorTheme as fe,getMarkdownTheme as Ot,getThemeByName as _t,initTheme as Nt,onThemeChange as Kt,setRegisteredThemes as Y,setTheme as O,setThemeInstance as jt,stopThemeWatcher as zt,Theme as Gt,theme as a}from"./theme/theme.js";function H(p){return typeof p=="object"&&p!==null&&"setExpanded"in p&&typeof p.setExpanded=="function"}h(H,"isExpandable");class Ce extends f{static{h(this,"ExpandableText")}getCollapsedText;getExpandedText;constructor(e,s,t=!1,i=0,n=0){super(t?s():e(),i,n),this.getCollapsedText=e,this.getExpandedText=s}setExpanded(e){this.setText(e?this.getExpandedText():this.getCollapsedText())}}const Vt=new Set(["EIO","EPIPE","ENOTCONN"]);function Qt(p){if(!p||typeof p!="object"||!("code"in p))return!1;const e=p.code;return e!==void 0&&Vt.has(e)}h(Qt,"isDeadTerminalError");const we="Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage.";function Xt(p){return typeof p=="string"&&p.startsWith("sk-ant-oat")}h(Xt,"isAnthropicSubscriptionAuthKey");function Jt(p){return!!p&&p.provider==="unknown"&&p.id==="unknown"&&p.api==="unknown"}h(Jt,"isUnknownModel");function Yt(p){return p.length>0&&!/[^a-zA-Z0-9_\-./~:@]/.test(p)?p:`'${p.replace(/'/g,"'\\''")}'`}h(Yt,"quoteIfNeeded");function Zt(p){if(!process.stdout.isTTY||!p.isPersisted())return;const e=p.getSessionFile();if(!e||!v.existsSync(e))return;const s=[z];return p.usesDefaultSessionDir()||s.push("--session-dir",Yt(p.getSessionDir())),s.push("--session",p.getSessionId()),s.join(" ")}h(Zt,"formatResumeCommand");function es(p){return p in ie}h(es,"hasDefaultModelProvider");const ts="amazon-bedrock",ss=new Set(qe());function is(p,e,s=ss){return dt[p]?!0:s.has(p)?!1:!e.has(p)}h(is,"isApiKeyLoginProvider");class _{static{h(this,"InteractiveMode")}runtimeHost;ui;chatContainer;pendingMessagesContainer;statusContainer;defaultEditor;editor;editorComponentFactory;autocompleteProvider;autocompleteProviderWrappers=[];fdPath;editorContainer;footer;footerDataProvider;keybindings;version;isInitialized=!1;onInputCallback;pendingUserInputs=[];loadingAnimation=void 0;workingMessage=void 0;workingVisible=!0;workingIndicatorOptions=void 0;defaultWorkingMessage="Koda is working\u2026";_workStartTs=0;_workWord="Working";_workTicker;static WORK_WORDS=["Flummoxing","Cogitating","Noodling","Percolating","Conjuring","Wrangling","Finagling","Cookifying","Flibbertigibbeting","Discombobulating","Hornswoggling","Bamboozling","Marinating","Concocting","Spelunking","Tinkering","Befuddling","Whirring","Schlepping","Razzledazzling","Confabulating","Snazzifying","Galumphing","Kerfuffling","Bedazzling","Vibing","Churning","Brewing"];defaultHiddenThinkingLabel="Thinking...";hiddenThinkingLabel=this.defaultHiddenThinkingLabel;lastSigintTime=0;lastEscapeTime=0;changelogMarkdown=void 0;startupNoticesShown=!1;anthropicSubscriptionWarningShown=!1;lastStatusSpacer=void 0;lastStatusText=void 0;streamingComponent=void 0;streamingMessage=void 0;pendingTools=new Map;toolOutputExpanded=!1;hideThinkingBlock=!1;skillCommands=new Map;unsubscribe;signalCleanupHandlers=[];isBashMode=!1;bashComponent=void 0;pendingBashComponents=[];autoCompactionLoader=void 0;autoCompactionEscapeHandler;overseerEscapeHandler;compactionStartMs=0;compactionReason=void 0;compactionCancelHint="";compactionTicker=void 0;_kodaTitleBase="idle";_kodaReviewing=!1;retryLoader=void 0;overseerLoader=void 0;retryCountdown=void 0;retryEscapeHandler;compactionQueuedMessages=[];shutdownRequested=!1;extensionSelector=void 0;extensionInput=void 0;extensionEditor=void 0;extensionTerminalInputUnsubscribers=new Set;extensionWidgetsAbove=new Map;extensionWidgetsBelow=new Map;widgetContainerAbove;widgetContainerBelow;customFooter=void 0;headerContainer;builtInHeader=void 0;customHeader=void 0;options;get session(){return this.runtimeHost.session}get agent(){return this.session.agent}get sessionManager(){return this.session.sessionManager}get settingsManager(){return this.session.settingsManager}constructor(e,s={}){this.runtimeHost=e,this.options=s,this.runtimeHost.setBeforeSessionInvalidate(()=>{this.resetExtensionUI()}),this.runtimeHost.setRebindSession(async()=>{await this.rebindCurrentSession()}),this.version=L,this.ui=new ze(new Ke,this.settingsManager.getShowHardwareCursor()),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink()),this.headerContainer=new A,this.chatContainer=new A,this.pendingMessagesContainer=new A,this.statusContainer=new A,this.widgetContainerAbove=new A,this.widgetContainerBelow=new A,this.keybindings=ot.create(),je(this.keybindings);const t=this.settingsManager.getEditorPaddingX(),i=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor=new Mt(this.ui,fe(),this.keybindings,{paddingX:t,autocompleteMaxVisible:i}),this.defaultEditor.title=this.kodaTitleText(),this.editor=this.defaultEditor,this.editorContainer=new A,this.editorContainer.addChild(this.editor),this.footerDataProvider=new it(this.sessionManager.getCwd()),this.footer=new vt(this.session,this.footerDataProvider),this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled),this.hideThinkingBlock=this.settingsManager.getHideThinkingBlock(),Y(this.session.resourceLoader.getThemes().themes),Nt(this.settingsManager.getTheme(),!0)}getAutocompleteSourceTag(e){if(!e)return;const s=e.scope==="user"?"u":e.scope==="project"?"p":"t",t=e.source.trim();if(t==="auto"||t==="local"||t==="cli")return s;if(t.startsWith("npm:"))return`${s}:${t}`;const i=de(t);if(i){const n=i.ref?`@${i.ref}`:"";return`${s}:git:${i.host}/${i.path}${n}`}return s}prefixAutocompleteDescription(e,s){const t=this.getAutocompleteSourceTag(s);return t?e?`[${t}] ${e}`:`[${t}]`:e}getBuiltInCommandConflictDiagnostics(e){const s=new Set(re.map(t=>t.name));return e.getRegisteredCommands().filter(t=>s.has(t.name)).map(t=>({type:"warning",message:t.invocationName===t.name?`Extension command '/${t.name}' conflicts with built-in interactive command. Skipping in autocomplete.`:`Extension command '/${t.name}' conflicts with built-in interactive command. Available as '/${t.invocationName}'.`,path:t.sourceInfo.path}))}createBaseAutocompleteProvider(){const e=re.map(r=>({name:r.name,description:r.description})),s=e.find(r=>r.name==="model");s&&(s.getArgumentCompletions=r=>{const d=this.session.scopedModels.length>0?this.session.scopedModels.map(u=>u.model):this.session.modelRegistry.getAvailable();if(d.length===0)return null;const l=d.map(u=>({id:u.id,provider:u.provider,label:`${u.provider}/${u.id}`})),m=Ue(l,r,u=>`${u.id} ${u.provider}`);return m.length===0?null:m.map(u=>({value:u.label,label:u.id,description:u.provider}))});const t=this.session.promptTemplates.map(r=>({name:r.name,description:this.prefixAutocompleteDescription(r.description,r.sourceInfo),...r.argumentHint&&{argumentHint:r.argumentHint}})),i=new Set(e.map(r=>r.name)),n=this.session.extensionRunner.getRegisteredCommands().filter(r=>!i.has(r.name)).map(r=>({name:r.invocationName,description:this.prefixAutocompleteDescription(r.description,r.sourceInfo),getArgumentCompletions:r.getArgumentCompletions}));this.skillCommands.clear();const o=[];if(this.settingsManager.getEnableSkillCommands())for(const r of this.session.resourceLoader.getSkills().skills){const d=`skill:${r.name}`;this.skillCommands.set(d,r.filePath),o.push({name:d,description:this.prefixAutocompleteDescription(r.description,r.sourceInfo)})}return new Be([...e,...t,...n,...o],this.sessionManager.getCwd(),this.fdPath)}setupAutocompleteProvider(){let e=this.createBaseAutocompleteProvider();for(const s of this.autocompleteProviderWrappers)e=s(e);this.autocompleteProvider=e,this.defaultEditor.setAutocompleteProvider(e),this.editor!==this.defaultEditor&&this.editor.setAutocompleteProvider?.(e)}showStartupNoticesIfNeeded(){if(!this.startupNoticesShown&&(this.startupNoticesShown=!0,!!this.changelogMarkdown)){if(this.chatContainer.children.length>0&&this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k),this.settingsManager.getCollapseChangelog()){const e=this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/),t=`Updated to v${e?e[1]:this.version}. Use ${a.bold("/changelog")} to view full changelog.`;this.chatContainer.addChild(new f(t,1,0))}else this.chatContainer.addChild(new f(a.bold(a.fg("accent","What's New")),1,0)),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new q(this.changelogMarkdown.trim(),1,0,this.getMarkdownThemeWithSettings())),this.chatContainer.addChild(new g(1));this.chatContainer.addChild(new k)}}async init(){if(this.isInitialized)return;this.registerSignalHandlers(),this.changelogMarkdown=this.getChangelogForDisplay();const[e]=await Promise.all([le("fd"),le("rg")]);if(this.fdPath=e,this.session.scopedModels.length>0&&(this.options.verbose||!this.settingsManager.getQuietStartup())){const s=this.session.scopedModels.map(n=>{const o=n.thinkingLevel?`:${n.thinkingLevel}`:"";return`${n.model.id}${o}`}).join(", "),t=this.keybindings.getKeys("app.model.cycleForward"),i=t.length>0?a.fg("muted",` (${ce(t.join("/"),{capitalize:!0})} to cycle)`):"";console.log(a.fg("dim",`Model scope: ${s}${i}`))}if(this.ui.addChild(this.headerContainer),this.options.verbose||!this.settingsManager.getQuietStartup()){const s=["\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557","\u2588\u2588\u2551 \u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557","\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551","\u2588\u2588\u2554\u2550\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551","\u2588\u2588\u2551 \u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551","\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D"].join(`
2
+ `),t=a.bold(a.fg("accent",s))+`
3
+ `+a.fg("dim",`v${et} \xB7 built for OpenAdapter`),i=h((l,m)=>ge(l,m),"hint"),n=[i("app.interrupt","to interrupt"),i("app.clear","to clear"),R(`${P("app.clear")} twice`,"to exit"),i("app.exit","to exit (empty)"),i("app.suspend","to suspend"),ge("tui.editor.deleteToLineEnd","to delete to end"),i("app.thinking.cycle","to cycle thinking level"),R(`${P("app.model.cycleForward")}/${P("app.model.cycleBackward")}`,"to cycle models"),i("app.model.select","to select model"),i("app.tools.expand","to expand tools"),i("app.thinking.toggle","to expand thinking"),i("app.editor.external","for external editor"),R("/","for commands"),R("!","to run bash"),R("!!","to run bash (no context)"),i("app.message.followUp","to queue follow-up"),i("app.message.dequeue","to edit all queued messages"),i("app.clipboard.pasteImage","to paste image"),R("drop files","to attach")].join(`
4
+ `),o=[i("app.interrupt","interrupt"),R(`${P("app.clear")}/${P("app.exit")}`,"clear/exit"),R("/","commands"),R("!","bash"),i("app.tools.expand","more")].join(a.fg("muted"," \xB7 ")),r=a.fg("dim",`Press ${P("app.tools.expand")} to show full startup help and loaded resources.`),d=a.fg("dim","Koda can explain its own features and look up its docs. Ask it how to use or extend Koda.");this.builtInHeader=new Ce(()=>`${t}
5
+ ${o}
6
+ ${r}
7
+
8
+ ${d}`,()=>`${t}
9
+ ${n}
10
+
11
+ ${d}`,this.getStartupExpansionState(),1,0),this.headerContainer.addChild(new g(1)),this.headerContainer.addChild(this.builtInHeader),this.headerContainer.addChild(new g(1))}else this.builtInHeader=new f("",0,0),this.headerContainer.addChild(this.builtInHeader);this.ui.addChild(this.chatContainer),this.ui.addChild(this.pendingMessagesContainer),this.ui.addChild(this.statusContainer),this.renderWidgets(),this.ui.addChild(this.widgetContainerAbove),this.ui.addChild(this.editorContainer),this.ui.addChild(this.widgetContainerBelow),this.ui.addChild(this.footer),this.ui.setFocus(this.editor),this.setupKeyHandlers(),this.setupEditorSubmitHandler(),this.ui.start(),this.isInitialized=!0,await this.rebindCurrentSession(),this.renderInitialMessages(),Kt(()=>{this.ui.invalidate(),this.updateEditorBorderColor(),this.ui.requestRender()}),this.footerDataProvider.onBranchChange(()=>{this.ui.requestRender()}),await this.updateAvailableProviderCount()}updateTerminalTitle(){const e=E.basename(this.sessionManager.getCwd()),s=this.sessionManager.getSessionName();s?this.ui.terminal.setTitle(`${te} - ${s} - ${e}`):this.ui.terminal.setTitle(`${te} - ${e}`)}async run(){await this.init(),St(this.version).then(r=>{r&&(this.showNewVersionNotification(r),process.env.KODA_NO_AUTO_UPDATE!=="1"&&ut().then(d=>{d&&this.showStatus(`Updated to ${r.version} \u2014 restart koda to apply.`)}))}),this.checkForPackageUpdates().then(r=>{r.length>0&&this.showPackageUpdateNotification(r)}),this.checkTmuxKeyboardSetup().then(r=>{r&&this.showWarning(r)});const{migratedProviders:e,modelFallbackMessage:s,initialMessage:t,initialImages:i,initialMessages:n}=this.options;e&&e.length>0&&this.showWarning(`Migrated credentials to auth.json: ${e.join(", ")}`);const o=this.session.modelRegistry.getError();if(o&&this.showError(`models.json error: ${o}`),s&&this.showWarning(s),this.maybeWarnAboutAnthropicSubscriptionAuth(),t)try{await this.session.prompt(t,{images:i})}catch(r){const d=r instanceof Error?r.message:"Unknown error occurred";this.showError(d)}if(n)for(const r of n)try{await this.session.prompt(r)}catch(d){const l=d instanceof Error?d.message:"Unknown error occurred";this.showError(l)}for(;;){const r=await this.getUserInput();try{await this.session.prompt(r)}catch(d){const l=d instanceof Error?d.message:"Unknown error occurred";this.showError(l)}}}async checkForPackageUpdates(){if(process.env.KODA_OFFLINE)return[];try{return(await new ht({cwd:this.sessionManager.getCwd(),agentDir:Xe(),settingsManager:this.settingsManager}).checkForAvailableUpdates()).map(t=>t.displayName)}catch{return[]}}async checkTmuxKeyboardSetup(){if(!process.env.TMUX)return;const e=h(i=>new Promise(n=>{const o=j("tmux",["show","-gv",i],{stdio:["ignore","pipe","ignore"]});let r="";const d=setTimeout(()=>{o.kill(),n(void 0)},2e3);o.stdout?.on("data",l=>{r+=l.toString()}),o.on("error",()=>{clearTimeout(d),n(void 0)}),o.on("close",l=>{clearTimeout(d),n(l===0?r.trim():void 0)})}),"runTmuxShow"),[s,t]=await Promise.all([e("extended-keys"),e("extended-keys-format")]);if(s!==void 0){if(s!=="on"&&s!=="always")return"tmux extended-keys is off. Modified Enter keys may not work. Add `set -g extended-keys on` to ~/.tmux.conf and restart tmux.";if(t==="xterm")return"tmux extended-keys-format is xterm. Koda works best with csi-u. Add `set -g extended-keys-format csi-u` to ~/.tmux.conf and restart tmux."}}getChangelogForDisplay(){if(this.session.state.messages.length>0)return;const e=this.settingsManager.getLastChangelogVersion(),s=ae(),t=he(s);if(!e){this.settingsManager.setLastChangelogVersion(L),this.reportInstallTelemetry(L);return}const i=gt(t,e);if(i.length>0)return this.settingsManager.setLastChangelogVersion(L),this.reportInstallTelemetry(L),i.map(n=>n.content).join(`
12
+
13
+ `)}reportInstallTelemetry(e){process.env.KODA_OFFLINE||ct(this.settingsManager)&&fetch(`https://openadapter.in/api/report-install?version=${encodeURIComponent(e)}`,{headers:{"User-Agent":Ct(e)},signal:AbortSignal.timeout(5e3)}).then(()=>{}).catch(()=>{})}getMarkdownThemeWithSettings(){return{...Ot(),codeBlockIndent:this.settingsManager.getCodeBlockIndent()}}formatDisplayPath(e){const s=F.homedir();let t=e;return t.startsWith(s)&&(t=`~${t.slice(s.length)}`),t}formatExtensionDisplayPath(e){let s=this.formatDisplayPath(e);return s=s.replace(/\/index\.ts$/,"").replace(/\/index\.js$/,""),s}formatContextPath(e){const s=E.resolve(this.sessionManager.getCwd()),t=E.isAbsolute(e)?E.resolve(e):E.resolve(s,e),i=wt(t,s);return i!==void 0?i:this.formatDisplayPath(t)}getStartupExpansionState(){return this.options.verbose||this.toolOutputExpanded}getShortPath(e,s){const t=s?.baseDir;if(t&&this.isPackageSource(s)){const r=E.relative(E.resolve(t),E.resolve(e));if(r&&r!=="."&&!r.startsWith("..")&&!r.startsWith(`..${E.sep}`)&&!E.isAbsolute(r))return r.replace(/\\/g,"/")}const i=s?.source??"",n=e.match(/node_modules\/(@?[^/]+(?:\/[^/]+)?)\/(.*)/);if(n&&i.startsWith("npm:"))return n[2];const o=e.match(/git\/[^/]+\/[^/]+\/(.*)/);return o&&i.startsWith("git:")?o[1]:this.formatDisplayPath(e)}formatCompactElapsed(e){const s=Math.max(0,Math.floor(e/1e3)),t=Math.floor(s/60);return t>0?`${t}m ${s%60}s`:`${s}s`}buildCompactionLabel(){const e=this.compactionStartMs?Date.now()-this.compactionStartMs:0,s=this.formatCompactElapsed(e),t=e/1e3,i=Math.min(95,Math.round(95*(1-Math.exp(-t/11)))),n=24,o=Math.max(0,Math.min(n,Math.round(i/100*n))),r=a.fg("accent","\u25B0".repeat(o))+a.fg("dim","\u25B1".repeat(n-o)),d=this.compactionReason==="overflow"?"Context overflow \u2014 compacting":this.compactionReason==="manual"?"Compacting context":"Auto-compacting context";return`${a.fg("muted",`${d} (${s})`)}
14
+ ${r} ${a.fg("muted",`${i}%`)} ${a.fg("dim",this.compactionCancelHint)}`}kodaTitleText(){const e=a;return this._kodaReviewing?e.bold(e.fg("accent","koda"))+e.fg("muted"," \xB7 reviewing\u2026"):this._kodaTitleBase==="beefed"?e.bold(e.fg("error","KODA \u2191 BEEFED UP")):this._kodaTitleBase==="rerouted"?e.bold(e.fg("warning","koda \xBB REROUTED")):e.bold(e.fg("accent","koda"))}updateKodaTitle(){this.defaultEditor.title=this.kodaTitleText(),this.ui.requestRender()}getCompactPathLabel(e,s){const t=this.getShortPath(e,s),n=t.replace(/\\/g,"/").split("/").filter(o=>o.length>0&&o!=="~");return n.length>0?n[n.length-1]:t}getCompactPackageSourceLabel(e){const s=e?.source??"";if(s.startsWith("npm:"))return s.slice(4)||s;const t=de(s);return t&&t.path||s}getCompactExtensionLabel(e,s){if(!this.isPackageSource(s))return this.getCompactPathLabel(e,s);const t=this.getCompactPackageSourceLabel(s);if(!t)return this.getCompactPathLabel(e,s);const i=this.getShortPath(e,s).replace(/\\/g,"/"),n=i.startsWith("extensions/")?i.slice(11):i,o=E.posix.parse(n);return o.name==="index"?!o.dir||o.dir==="."?t:`${t}:${o.dir}`:`${t}:${n}`}getCompactDisplayPathSegments(e){return this.formatDisplayPath(e).replace(/\\/g,"/").split("/").filter(s=>s.length>0&&s!=="~")}getCompactNonPackageExtensionLabel(e,s,t){const i=t[s]?.segments;if(!i||i.length===0)return this.getCompactPathLabel(e);for(let n=1;n<=i.length;n+=1){const o=i.slice(-n).join("/");if(t.every((d,l)=>l===s?!0:d.segments.slice(-n).join("/")!==o))return o}return i.join("/")}getCompactExtensionLabels(e){const s=e.map(t=>{const i=this.getCompactDisplayPathSegments(t.path),n=i[i.length-1];return i.length>1&&(n==="index.ts"||n==="index.js")&&i.pop(),{path:t.path,sourceInfo:t.sourceInfo,segments:i}}).filter(t=>!this.isPackageSource(t.sourceInfo));return e.map(t=>{if(this.isPackageSource(t.sourceInfo))return this.getCompactExtensionLabel(t.path,t.sourceInfo);const i=s.findIndex(n=>n.path===t.path);return i===-1?this.getCompactPathLabel(t.path,t.sourceInfo):this.getCompactNonPackageExtensionLabel(t.path,i,s)})}getDisplaySourceInfo(e){const s=e?.source??"local",t=e?.scope??"project";return s==="local"?t==="user"?{label:"user",color:"muted"}:t==="project"?{label:"project",color:"muted"}:t==="temporary"?{label:"path",scopeLabel:"temp",color:"muted"}:{label:"path",color:"muted"}:s==="cli"?{label:"path",scopeLabel:t==="temporary"?"temp":void 0,color:"muted"}:{label:s,scopeLabel:t==="user"?"user":t==="project"?"project":t==="temporary"?"temp":void 0,color:"accent"}}getScopeGroup(e){const s=e?.source??"local",t=e?.scope??"project";return s==="cli"||t==="temporary"?"path":t==="user"?"user":t==="project"?"project":"path"}isPackageSource(e){const s=e?.source??"";return s.startsWith("npm:")||s.startsWith("git:")}buildScopeGroups(e){const s={user:{scope:"user",paths:[],packages:new Map},project:{scope:"project",paths:[],packages:new Map},path:{scope:"path",paths:[],packages:new Map}};for(const t of e){const i=this.getScopeGroup(t.sourceInfo),n=s[i],o=t.sourceInfo?.source??"local";if(this.isPackageSource(t.sourceInfo)){const r=n.packages.get(o)??[];r.push(t),n.packages.set(o,r)}else n.paths.push(t)}return[s.project,s.user,s.path].filter(t=>t.paths.length>0||t.packages.size>0)}formatScopeGroups(e,s){const t=[];for(const i of e){t.push(` ${a.fg("accent",i.scope)}`);const n=[...i.paths].sort((r,d)=>r.path.localeCompare(d.path));for(const r of n)t.push(a.fg("dim",` ${s.formatPath(r)}`));const o=Array.from(i.packages.entries()).sort(([r],[d])=>r.localeCompare(d));for(const[r,d]of o){t.push(` ${a.fg("mdLink",r)}`);const l=[...d].sort((m,u)=>m.path.localeCompare(u.path));for(const m of l)t.push(a.fg("dim",` ${s.formatPackagePath(m,r)}`))}}return t.join(`
15
+ `)}findSourceInfoForPath(e,s){const t=s.get(e);if(t)return t;let i=e;for(;i.includes("/");){i=i.substring(0,i.lastIndexOf("/"));const n=s.get(i);if(n)return n}}formatPathWithSource(e,s){if(s){const t=this.getShortPath(e,s),{label:i,scopeLabel:n}=this.getDisplaySourceInfo(s);return`${n?`${i} (${n})`:i} ${t}`}return this.formatDisplayPath(e)}formatDiagnostics(e,s){const t=[],i=new Map,n=[];for(const o of e)if(o.type==="collision"&&o.collision){const r=i.get(o.collision.name)??[];r.push(o),i.set(o.collision.name,r)}else n.push(o);for(const[o,r]of i){const d=r[0]?.collision;if(d){t.push(a.fg("warning",` "${o}" collision:`)),t.push(a.fg("dim",` ${a.fg("success","\u2713")} ${this.formatPathWithSource(d.winnerPath,this.findSourceInfoForPath(d.winnerPath,s))}`));for(const l of r)l.collision&&t.push(a.fg("dim",` ${a.fg("warning","\u2717")} ${this.formatPathWithSource(l.collision.loserPath,this.findSourceInfoForPath(l.collision.loserPath,s))} (skipped)`))}}for(const o of n)if(o.path){const r=this.formatPathWithSource(o.path,this.findSourceInfoForPath(o.path,s));t.push(a.fg(o.type==="error"?"error":"warning",` ${r}`)),t.push(a.fg(o.type==="error"?"error":"warning",` ${o.message}`))}else t.push(a.fg(o.type==="error"?"error":"warning",` ${o.message}`));return t.join(`
16
+ `)}showLoadedResources(e){const s=e?.force||this.options.verbose||!this.settingsManager.getQuietStartup(),t=s||e?.showDiagnosticsWhenQuiet===!0;if(!s&&!t)return;const i=h((c,y="mdHeading")=>a.fg(y,`[${c}]`),"sectionHeader"),n=h((c,y)=>{const S=c.map(b=>b.trim()).filter(b=>b.length>0);return y?.sort!==!1&&S.sort((b,$)=>b.localeCompare($)),a.fg("dim",` ${S.join(", ")}`)},"formatCompactList"),o=h((c,y,S=y,b="mdHeading")=>{const $=new Ce(()=>`${i(c,b)}
17
+ ${y}`,()=>`${i(c,b)}
18
+ ${S}`,this.getStartupExpansionState(),0,0);this.chatContainer.addChild($),this.chatContainer.addChild(new g(1))},"addLoadedSection"),r=this.session.resourceLoader.getSkills(),d=this.session.resourceLoader.getPrompts(),l=this.session.resourceLoader.getThemes(),m=e?.extensions??this.session.resourceLoader.getExtensions().extensions.map(c=>({path:c.path,sourceInfo:c.sourceInfo})),u=new Map;for(const c of m)c.sourceInfo&&u.set(c.path,c.sourceInfo);for(const c of r.skills)c.sourceInfo&&u.set(c.filePath,c.sourceInfo);for(const c of d.prompts)c.sourceInfo&&u.set(c.filePath,c.sourceInfo);for(const c of l.themes)c.sourcePath&&c.sourceInfo&&u.set(c.sourcePath,c.sourceInfo);if(s){const c=this.session.resourceLoader.getAgentsFiles().agentsFiles;if(c.length>0){this.chatContainer.addChild(new g(1));const x=c.map(w=>a.fg("dim",` ${this.formatDisplayPath(w.path)}`)).join(`
19
+ `),M=n(c.map(w=>this.formatContextPath(w.path)),{sort:!1});o("Context",M,x)}const y=r.skills;if(y.length>0){const x=this.buildScopeGroups(y.map(C=>({path:C.filePath,sourceInfo:C.sourceInfo}))),M=this.formatScopeGroups(x,{formatPath:h(C=>this.formatDisplayPath(C.path),"formatPath"),formatPackagePath:h(C=>this.getShortPath(C.path,C.sourceInfo),"formatPackagePath")}),w=n(y.map(C=>C.name));o("Skills",w,M)}const S=this.session.promptTemplates;if(S.length>0){const x=this.buildScopeGroups(S.map(T=>({path:T.filePath,sourceInfo:T.sourceInfo}))),M=new Map(S.map(T=>[T.filePath,T])),w=this.formatScopeGroups(x,{formatPath:h(T=>{const I=M.get(T.path);return I?`/${I.name}`:this.formatDisplayPath(T.path)},"formatPath"),formatPackagePath:h(T=>{const I=M.get(T.path);return I?`/${I.name}`:this.formatDisplayPath(T.path)},"formatPackagePath")}),C=n(S.map(T=>`/${T.name}`));o("Prompts",C,w)}if(m.length>0){const x=this.buildScopeGroups(m),M=this.formatScopeGroups(x,{formatPath:h(C=>this.formatExtensionDisplayPath(C.path),"formatPath"),formatPackagePath:h(C=>this.formatExtensionDisplayPath(this.getShortPath(C.path,C.sourceInfo)),"formatPackagePath")}),w=n(this.getCompactExtensionLabels(m));o("Extensions",w,M,"mdHeading")}const $=l.themes.filter(x=>x.sourcePath);if($.length>0){const x=this.buildScopeGroups($.map(C=>({path:C.sourcePath,sourceInfo:C.sourceInfo}))),M=this.formatScopeGroups(x,{formatPath:h(C=>this.formatDisplayPath(C.path),"formatPath"),formatPackagePath:h(C=>this.getShortPath(C.path,C.sourceInfo),"formatPackagePath")}),w=n($.map(C=>C.name??this.getCompactPathLabel(C.sourcePath,C.sourceInfo)));o("Themes",w,M)}}if(t){const c=r.diagnostics;if(c.length>0){const w=this.formatDiagnostics(c,u);this.chatContainer.addChild(new f(`${a.fg("warning","[Skill conflicts]")}
20
+ ${w}`,0,0)),this.chatContainer.addChild(new g(1))}const y=d.diagnostics;if(y.length>0){const w=this.formatDiagnostics(y,u);this.chatContainer.addChild(new f(`${a.fg("warning","[Prompt conflicts]")}
21
+ ${w}`,0,0)),this.chatContainer.addChild(new g(1))}const S=[],b=this.session.resourceLoader.getExtensions().errors;if(b.length>0)for(const w of b)S.push({type:"error",message:w.error,path:w.path});const $=this.session.extensionRunner.getCommandDiagnostics();S.push(...$),S.push(...this.getBuiltInCommandConflictDiagnostics(this.session.extensionRunner));const x=this.session.extensionRunner.getShortcutDiagnostics();if(S.push(...x),S.length>0){const w=this.formatDiagnostics(S,u);this.chatContainer.addChild(new f(`${a.fg("warning","[Extension issues]")}
22
+ ${w}`,0,0)),this.chatContainer.addChild(new g(1))}const M=l.diagnostics;if(M.length>0){const w=this.formatDiagnostics(M,u);this.chatContainer.addChild(new f(`${a.fg("warning","[Theme conflicts]")}
23
+ ${w}`,0,0)),this.chatContainer.addChild(new g(1))}}}async bindCurrentSessionExtensions(){const e=this.createExtensionUIContext();await this.session.bindExtensions({uiContext:e,mode:"tui",abortHandler:h(()=>{this.restoreQueuedMessagesToEditor({abort:!0})},"abortHandler"),commandContextActions:{waitForIdle:h(()=>this.session.agent.waitForIdle(),"waitForIdle"),newSession:h(async t=>{this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear();try{const i=await this.runtimeHost.newSession(t);return i.cancelled||(this.renderCurrentSessionState(),this.ui.requestRender()),i}catch(i){return this.handleFatalRuntimeError("Failed to create session",i)}},"newSession"),fork:h(async(t,i)=>{try{const n=await this.runtimeHost.fork(t,i);return n.cancelled||(this.renderCurrentSessionState(),this.editor.setText(n.selectedText??""),this.showStatus("Forked to new session")),{cancelled:n.cancelled}}catch(n){return this.handleFatalRuntimeError("Failed to fork session",n)}},"fork"),navigateTree:h(async(t,i)=>{const n=await this.session.navigateTree(t,{summarize:i?.summarize,customInstructions:i?.customInstructions,replaceInstructions:i?.replaceInstructions,label:i?.label});return n.cancelled?{cancelled:!0}:(this.chatContainer.clear(),this.renderInitialMessages(),n.editorText&&!this.editor.getText().trim()&&this.editor.setText(n.editorText),this.showStatus("Navigated to selected point"),this.flushCompactionQueue({willRetry:!1}),{cancelled:!1})},"navigateTree"),switchSession:h(async(t,i)=>this.handleResumeSession(t,i),"switchSession"),reload:h(async()=>{await this.handleReloadCommand()},"reload")},shutdownHandler:h(()=>{this.shutdownRequested=!0,this.session.isStreaming||this.shutdown()},"shutdownHandler"),onError:h(t=>{this.showExtensionError(t.extensionPath,t.error,t.stack)},"onError")}),Y(this.session.resourceLoader.getThemes().themes),this.setupAutocompleteProvider();const s=this.session.extensionRunner;this.setupExtensionShortcuts(s),this.showLoadedResources({force:!1,showDiagnosticsWhenQuiet:!0}),this.showStartupNoticesIfNeeded()}applyRuntimeSettings(){G(this.settingsManager.getHttpIdleTimeoutMs()),this.footer.setSession(this.session),this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled),this.footerDataProvider.setCwd(this.sessionManager.getCwd()),this.hideThinkingBlock=this.settingsManager.getHideThinkingBlock(),this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor()),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());const e=this.settingsManager.getEditorPaddingX(),s=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor.setPaddingX(e),this.defaultEditor.setAutocompleteMaxVisible(s),this.editor!==this.defaultEditor&&(this.editor.setPaddingX?.(e),this.editor.setAutocompleteMaxVisible?.(s))}async rebindCurrentSession(){this.unsubscribe?.(),this.unsubscribe=void 0,this.applyRuntimeSettings(),await this.bindCurrentSessionExtensions(),this.subscribeToAgent(),await this.updateAvailableProviderCount(),this.updateEditorBorderColor(),this.updateTerminalTitle()}async handleFatalRuntimeError(e,s){const t=s instanceof Error?s.message:String(s);this.showError(`${e}: ${t}`),zt(),this.stop(),process.exit(1)}renderCurrentSessionState(){this.chatContainer.clear(),this.pendingMessagesContainer.clear(),this.compactionQueuedMessages=[],this.streamingComponent=void 0,this.streamingMessage=void 0,this.pendingTools.clear(),this.renderInitialMessages()}getRegisteredToolDefinition(e){return this.session.getToolDefinition(e)}setupExtensionShortcuts(e){const s=e.getShortcuts(this.keybindings.getEffectiveConfig());if(s.size===0)return;const t=h(()=>({ui:this.createExtensionUIContext(),mode:"tui",hasUI:!0,cwd:this.sessionManager.getCwd(),sessionManager:this.sessionManager,modelRegistry:this.session.modelRegistry,model:this.session.model,isIdle:h(()=>!this.session.isStreaming,"isIdle"),signal:this.session.agent.signal,abort:h(()=>{this.restoreQueuedMessagesToEditor({abort:!0})},"abort"),hasPendingMessages:h(()=>this.session.pendingMessageCount>0,"hasPendingMessages"),shutdown:h(()=>{this.shutdownRequested=!0},"shutdown"),getContextUsage:h(()=>this.session.getContextUsage(),"getContextUsage"),compact:h(i=>{(async()=>{try{const n=await this.session.compact(i?.customInstructions);i?.onComplete?.(n)}catch(n){const o=n instanceof Error?n:new Error(String(n));i?.onError?.(o)}})()},"compact"),getSystemPrompt:h(()=>this.session.systemPrompt,"getSystemPrompt")}),"createContext");this.defaultEditor.onExtensionShortcut=i=>{for(const[n,o]of s)if(Ne(i,n))return Promise.resolve(o.handler(t())).catch(r=>{this.showError(`Shortcut handler error: ${r instanceof Error?r.message:String(r)}`)}),!0;return!1}}setExtensionStatus(e,s){this.footerDataProvider.setExtensionStatus(e,s),this.ui.requestRender()}getWorkingLoaderMessage(){return this.workingMessage??this._workStatusText()}_pickWorkWord(){const e=_.WORK_WORDS;return e[Math.floor(Math.random()*e.length)]??"Working"}_workStatusText(){this._workStartTs||(this._workStartTs=Date.now());const e=Math.max(0,Math.floor((Date.now()-this._workStartTs)/1e3)),s=Math.floor(e/60),t=s>0?`${s}m ${e%60}s`:`${e}s`;let i="";try{const n=this.session.getContextUsage?.()?.tokens;n&&n>0&&(i=` \xB7 \u2191 ${n>=1e6?`${(n/1e6).toFixed(1)}M`:n>=1e3?`${(n/1e3).toFixed(1)}k`:String(n)} tokens`)}catch{}return`${this._workWord}\u2026 (${t}${i})`}_startWorkTicker(){this._clearWorkTicker(),!this.workingMessage&&(this._workTicker=setInterval(()=>{if(!this.loadingAnimation){this._clearWorkTicker();return}const e=Math.floor((Date.now()-this._workStartTs)/1e3);e>0&&e%10===0&&(this._workWord=this._pickWorkWord()),this.loadingAnimation.setMessage(this._workStatusText()),this.ui.requestRender()},1e3))}_clearWorkTicker(){this._workTicker&&(clearInterval(this._workTicker),this._workTicker=void 0)}createWorkingLoader(){this._workStartTs=Date.now(),this._workWord=this._pickWorkWord();const e=new D(this.ui,s=>a.fg("accent",s),s=>a.fg("muted",s),this.getWorkingLoaderMessage(),this.workingIndicatorOptions);return this._startWorkTicker(),e}stopWorkingLoader(){this._clearWorkTicker(),this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear()}setWorkingVisible(e){if(this.workingVisible=e,!e){this.stopWorkingLoader(),this.ui.requestRender();return}this.session.isStreaming&&!this.loadingAnimation&&(this.statusContainer.clear(),this.loadingAnimation=this.createWorkingLoader(),this.statusContainer.addChild(this.loadingAnimation)),this.ui.requestRender()}setWorkingIndicator(e){this.workingIndicatorOptions=e,this.loadingAnimation?.setIndicator(e),this.ui.requestRender()}setHiddenThinkingLabel(e){this.hiddenThinkingLabel=e??this.defaultHiddenThinkingLabel;for(const s of this.chatContainer.children)s instanceof U&&s.setHiddenThinkingLabel(this.hiddenThinkingLabel);this.streamingComponent&&this.streamingComponent.setHiddenThinkingLabel(this.hiddenThinkingLabel),this.ui.requestRender()}setExtensionWidget(e,s,t){const i=t?.placement??"aboveEditor",n=h(d=>{const l=d.get(e);l?.dispose&&l.dispose(),d.delete(e)},"removeExisting");if(n(this.extensionWidgetsAbove),n(this.extensionWidgetsBelow),s===void 0){this.renderWidgets();return}let o;if(Array.isArray(s)){const d=new A;for(const l of s.slice(0,_.MAX_WIDGET_LINES))d.addChild(new f(l,1,0));s.length>_.MAX_WIDGET_LINES&&d.addChild(new f(a.fg("muted","... (widget truncated)"),1,0)),o=d}else o=s(this.ui,a);(i==="belowEditor"?this.extensionWidgetsBelow:this.extensionWidgetsAbove).set(e,o),this.renderWidgets()}clearExtensionWidgets(){for(const e of this.extensionWidgetsAbove.values())e.dispose?.();for(const e of this.extensionWidgetsBelow.values())e.dispose?.();this.extensionWidgetsAbove.clear(),this.extensionWidgetsBelow.clear(),this.renderWidgets()}resetExtensionUI(){this.extensionSelector&&this.hideExtensionSelector(),this.extensionInput&&this.hideExtensionInput(),this.extensionEditor&&this.hideExtensionEditor(),this.ui.hideOverlay(),this.clearExtensionTerminalInputListeners(),this.setExtensionFooter(void 0),this.setExtensionHeader(void 0),this.clearExtensionWidgets(),this.footerDataProvider.clearExtensionStatuses(),this.footer.invalidate(),this.autocompleteProviderWrappers=[],this.setCustomEditorComponent(void 0),this.setupAutocompleteProvider(),this.defaultEditor.onExtensionShortcut=void 0,this.updateTerminalTitle(),this.workingMessage=void 0,this.workingVisible=!0,this.setWorkingIndicator(),this.loadingAnimation&&this.loadingAnimation.setMessage(`${this.defaultWorkingMessage} (${P("app.interrupt")} to interrupt)`),this.setHiddenThinkingLabel()}static MAX_WIDGET_LINES=10;renderWidgets(){!this.widgetContainerAbove||!this.widgetContainerBelow||(this.renderWidgetContainer(this.widgetContainerAbove,this.extensionWidgetsAbove,!0,!0),this.renderWidgetContainer(this.widgetContainerBelow,this.extensionWidgetsBelow,!1,!1),this.ui.requestRender())}renderWidgetContainer(e,s,t,i){if(e.clear(),s.size===0){t&&e.addChild(new g(1));return}i&&e.addChild(new g(1));for(const n of s.values())e.addChild(n)}setExtensionFooter(e){this.customFooter?.dispose&&this.customFooter.dispose(),this.customFooter?this.ui.removeChild(this.customFooter):this.ui.removeChild(this.footer),e?(this.customFooter=e(this.ui,a,this.footerDataProvider),this.ui.addChild(this.customFooter)):(this.customFooter=void 0,this.ui.addChild(this.footer)),this.ui.requestRender()}setExtensionHeader(e){if(!this.builtInHeader)return;this.customHeader?.dispose&&this.customHeader.dispose();const s=this.customHeader||this.builtInHeader,t=this.headerContainer.children.indexOf(s);e?(this.customHeader=e(this.ui,a),H(this.customHeader)&&this.customHeader.setExpanded(this.toolOutputExpanded),t!==-1?this.headerContainer.children[t]=this.customHeader:this.headerContainer.children.unshift(this.customHeader)):(this.customHeader=void 0,H(this.builtInHeader)&&this.builtInHeader.setExpanded(this.toolOutputExpanded),t!==-1&&(this.headerContainer.children[t]=this.builtInHeader)),this.ui.requestRender()}addExtensionTerminalInputListener(e){const s=this.ui.addInputListener(e);return this.extensionTerminalInputUnsubscribers.add(s),()=>{s(),this.extensionTerminalInputUnsubscribers.delete(s)}}clearExtensionTerminalInputListeners(){for(const e of this.extensionTerminalInputUnsubscribers)e();this.extensionTerminalInputUnsubscribers.clear()}createExtensionUIContext(){return{select:h((e,s,t)=>this.showExtensionSelector(e,s,t),"select"),confirm:h((e,s,t)=>this.showExtensionConfirm(e,s,t),"confirm"),input:h((e,s,t)=>this.showExtensionInput(e,s,t),"input"),notify:h((e,s)=>this.showExtensionNotify(e,s),"notify"),onTerminalInput:h(e=>this.addExtensionTerminalInputListener(e),"onTerminalInput"),setStatus:h((e,s)=>this.setExtensionStatus(e,s),"setStatus"),setWorkingMessage:h(e=>{this.workingMessage=e,this.loadingAnimation&&this.loadingAnimation.setMessage(e??this.defaultWorkingMessage)},"setWorkingMessage"),setWorkingVisible:h(e=>this.setWorkingVisible(e),"setWorkingVisible"),setWorkingIndicator:h(e=>this.setWorkingIndicator(e),"setWorkingIndicator"),setHiddenThinkingLabel:h(e=>this.setHiddenThinkingLabel(e),"setHiddenThinkingLabel"),setWidget:h((e,s,t)=>this.setExtensionWidget(e,s,t),"setWidget"),setFooter:h(e=>this.setExtensionFooter(e),"setFooter"),setHeader:h(e=>this.setExtensionHeader(e),"setHeader"),setTitle:h(e=>this.ui.terminal.setTitle(e),"setTitle"),custom:h((e,s)=>this.showExtensionCustom(e,s),"custom"),pasteToEditor:h(e=>this.editor.handleInput(`\x1B[200~${e}\x1B[201~`),"pasteToEditor"),setEditorText:h(e=>this.editor.setText(e),"setEditorText"),getEditorText:h(()=>this.editor.getExpandedText?.()??this.editor.getText(),"getEditorText"),editor:h((e,s)=>this.showExtensionEditor(e,s),"editor"),addAutocompleteProvider:h(e=>{this.autocompleteProviderWrappers.push(e),this.setupAutocompleteProvider()},"addAutocompleteProvider"),setEditorComponent:h(e=>this.setCustomEditorComponent(e),"setEditorComponent"),getEditorComponent:h(()=>this.editorComponentFactory,"getEditorComponent"),get theme(){return a},getAllThemes:h(()=>Ut(),"getAllThemes"),getTheme:h(e=>_t(e),"getTheme"),setTheme:h(e=>{if(e instanceof Gt)return jt(e),this.ui.requestRender(),{success:!0};const s=O(e,!0);return s.success&&(this.settingsManager.getTheme()!==e&&this.settingsManager.setTheme(e),this.ui.requestRender()),s},"setTheme"),getToolsExpanded:h(()=>this.toolOutputExpanded,"getToolsExpanded"),setToolsExpanded:h(e=>this.setToolsExpanded(e),"setToolsExpanded")}}showExtensionSelector(e,s,t){return new Promise(i=>{if(t?.signal?.aborted){i(void 0);return}const n=h(()=>{this.hideExtensionSelector(),i(void 0)},"onAbort");t?.signal?.addEventListener("abort",n,{once:!0}),this.extensionSelector=new X(e,s,o=>{t?.signal?.removeEventListener("abort",n),this.hideExtensionSelector(),i(o)},()=>{t?.signal?.removeEventListener("abort",n),this.hideExtensionSelector(),i(void 0)},{tui:this.ui,timeout:t?.timeout,onToggleToolsExpanded:h(()=>this.toggleToolOutputExpansion(),"onToggleToolsExpanded")}),this.editorContainer.clear(),this.editorContainer.addChild(this.extensionSelector),this.ui.setFocus(this.extensionSelector),this.ui.requestRender()})}hideExtensionSelector(){this.extensionSelector?.dispose(),this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.extensionSelector=void 0,this.ui.setFocus(this.editor),this.ui.requestRender()}async showExtensionConfirm(e,s,t){return await this.showExtensionSelector(`${e}
24
+ ${s}`,["Yes","No"],t)==="Yes"}async promptForMissingSessionCwd(e){return await this.showExtensionConfirm("Session cwd not found",lt(e.issue))?e.issue.fallbackCwd:void 0}showExtensionInput(e,s,t){return new Promise(i=>{if(t?.signal?.aborted){i(void 0);return}const n=h(()=>{this.hideExtensionInput(),i(void 0)},"onAbort");t?.signal?.addEventListener("abort",n,{once:!0}),this.extensionInput=new Rt(e,s,o=>{t?.signal?.removeEventListener("abort",n),this.hideExtensionInput(),i(o)},()=>{t?.signal?.removeEventListener("abort",n),this.hideExtensionInput(),i(void 0)},{tui:this.ui,timeout:t?.timeout}),this.editorContainer.clear(),this.editorContainer.addChild(this.extensionInput),this.ui.setFocus(this.extensionInput),this.ui.requestRender()})}hideExtensionInput(){this.extensionInput?.dispose(),this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.extensionInput=void 0,this.ui.setFocus(this.editor),this.ui.requestRender()}showExtensionEditor(e,s){return new Promise(t=>{this.extensionEditor=new At(this.ui,this.keybindings,e,s,i=>{this.hideExtensionEditor(),t(i)},()=>{this.hideExtensionEditor(),t(void 0)}),this.editorContainer.clear(),this.editorContainer.addChild(this.extensionEditor),this.ui.setFocus(this.extensionEditor),this.ui.requestRender()})}hideExtensionEditor(){this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.extensionEditor=void 0,this.ui.setFocus(this.editor),this.ui.requestRender()}setCustomEditorComponent(e){this.editorComponentFactory=e;const s=this.editor.getText();if(this.editorContainer.clear(),e){const t=e(this.ui,fe(),this.keybindings);t.onSubmit=this.defaultEditor.onSubmit,t.onChange=this.defaultEditor.onChange,t.setText(s),t.borderColor!==void 0&&(t.borderColor=this.defaultEditor.borderColor),t.setPaddingX!==void 0&&t.setPaddingX(this.defaultEditor.getPaddingX()),t.setAutocompleteProvider&&this.autocompleteProvider&&t.setAutocompleteProvider(this.autocompleteProvider);const i=t;if("actionHandlers"in i&&i.actionHandlers instanceof Map){i.onEscape||(i.onEscape=()=>this.defaultEditor.onEscape?.()),i.onCtrlD||(i.onCtrlD=()=>this.defaultEditor.onCtrlD?.()),i.onPasteImage||(i.onPasteImage=()=>this.defaultEditor.onPasteImage?.()),i.onExtensionShortcut||(i.onExtensionShortcut=n=>this.defaultEditor.onExtensionShortcut?.(n));for(const[n,o]of this.defaultEditor.actionHandlers)i.actionHandlers.set(n,o)}this.editor=t}else this.defaultEditor.setText(s),this.editor=this.defaultEditor;this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor),this.ui.requestRender()}showExtensionNotify(e,s){s==="error"?this.showError(e):s==="warning"?this.showWarning(e):this.showStatus(e)}async showExtensionCustom(e,s){const t=this.editor.getText(),i=s?.overlay??!1,n=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.editor.setText(t),this.ui.setFocus(this.editor),this.ui.requestRender()},"restoreEditor");return new Promise((o,r)=>{let d,l=!1;const m=h(u=>{if(!l){l=!0,i?this.ui.hideOverlay():n(),o(u);try{d?.dispose?.()}catch{}}},"close");Promise.resolve(e(this.ui,a,this.keybindings,m)).then(u=>{if(!l)if(d=u,i){const c=h(()=>{if(s?.overlayOptions)return typeof s.overlayOptions=="function"?s.overlayOptions():s.overlayOptions;const S=d.width;return S?{width:S}:void 0},"resolveOptions"),y=this.ui.showOverlay(d,c());s?.onHandle?.(y)}else this.editorContainer.clear(),this.editorContainer.addChild(d),this.ui.setFocus(d),this.ui.requestRender()}).catch(u=>{l||(i||n(),r(u))})})}showExtensionError(e,s,t){const i=`Extension "${e}" error: ${s}`,n=new f(a.fg("error",i),1,0);if(this.chatContainer.addChild(n),t){const o=t.split(`
25
+ `).slice(1).map(r=>a.fg("dim",` ${r.trim()}`)).join(`
26
+ `);o&&this.chatContainer.addChild(new f(o,1,0))}this.ui.requestRender()}setupKeyHandlers(){this.defaultEditor.onEscape=()=>{if(this.session.isStreaming)this.restoreQueuedMessagesToEditor({abort:!0});else if(this.session.isBashRunning)this.session.abortBash();else if(this.isBashMode)this.editor.setText(""),this.isBashMode=!1,this.updateEditorBorderColor();else if(!this.editor.getText().trim()){const e=this.settingsManager.getDoubleEscapeAction();if(e!=="none"){const s=Date.now();s-this.lastEscapeTime<500?(e==="tree"?this.showTreeSelector():this.showUserMessageSelector(),this.lastEscapeTime=0):this.lastEscapeTime=s}}},this.defaultEditor.onAction("app.clear",()=>this.handleCtrlC()),this.defaultEditor.onCtrlD=()=>this.handleCtrlD(),this.defaultEditor.onAction("app.suspend",()=>this.handleCtrlZ()),this.defaultEditor.onAction("app.thinking.cycle",()=>this.cycleThinkingLevel()),this.defaultEditor.onAction("app.model.cycleForward",()=>this.cycleModel("forward")),this.defaultEditor.onAction("app.model.cycleBackward",()=>this.cycleModel("backward")),this.ui.onDebug=()=>this.handleDebugCommand(),this.defaultEditor.onAction("app.model.select",()=>this.showModelSelector()),this.defaultEditor.onAction("app.tools.expand",()=>this.toggleToolOutputExpansion()),this.defaultEditor.onAction("app.thinking.toggle",()=>this.toggleThinkingBlockVisibility()),this.defaultEditor.onAction("app.editor.external",()=>this.openExternalEditor()),this.defaultEditor.onAction("app.message.followUp",()=>this.handleFollowUp()),this.defaultEditor.onAction("app.message.dequeue",()=>this.handleDequeue()),this.defaultEditor.onAction("app.session.new",()=>this.handleClearCommand()),this.defaultEditor.onAction("app.session.tree",()=>this.showTreeSelector()),this.defaultEditor.onAction("app.session.fork",()=>this.showUserMessageSelector()),this.defaultEditor.onAction("app.session.resume",()=>this.showSessionSelector()),this.defaultEditor.onChange=e=>{const s=this.isBashMode;this.isBashMode=e.trimStart().startsWith("!"),s!==this.isBashMode&&this.updateEditorBorderColor()},this.defaultEditor.onPasteImage=()=>{this.handleClipboardImagePaste()}}async handleClipboardImagePaste(){try{const e=await ft();if(!e)return;const s=F.tmpdir(),t=mt(e.mimeType)??"png",i=`pi-clipboard-${Fe.randomUUID()}.${t}`,n=E.join(s,i);v.writeFileSync(n,Buffer.from(e.bytes)),this.editor.insertTextAtCursor?.(n),this.ui.requestRender()}catch{}}setupEditorSubmitHandler(){this.defaultEditor.onSubmit=async e=>{if(e=e.trim(),!!e){if(e==="/settings"){this.showSettingsSelector(),this.editor.setText("");return}if(e==="/scoped-models"){this.editor.setText(""),await this.showModelsSelector();return}if(e==="/model"||e.startsWith("/model ")){const s=e.startsWith("/model ")?e.slice(7).trim():void 0;this.editor.setText(""),await this.handleModelCommand(s);return}if(e==="/export"||e.startsWith("/export ")){await this.handleExportCommand(e),this.editor.setText("");return}if(e==="/import"||e.startsWith("/import ")){await this.handleImportCommand(e),this.editor.setText("");return}if(e==="/share"){await this.handleShareCommand(),this.editor.setText("");return}if(e==="/copy"){await this.handleCopyCommand(),this.editor.setText("");return}if(e==="/name"||e.startsWith("/name ")){this.handleNameCommand(e),this.editor.setText("");return}if(e==="/session"){this.handleSessionCommand(),this.editor.setText("");return}if(e==="/changelog"){this.handleChangelogCommand(),this.editor.setText("");return}if(e==="/hotkeys"){this.handleHotkeysCommand(),this.editor.setText("");return}if(e==="/fork"){this.showUserMessageSelector(),this.editor.setText("");return}if(e==="/clone"){this.editor.setText(""),await this.handleCloneCommand();return}if(e==="/tree"){this.showTreeSelector(),this.editor.setText("");return}if(e==="/login"){this.showOAuthSelector("login"),this.editor.setText("");return}if(e==="/logout"){this.showOAuthSelector("logout"),this.editor.setText("");return}if(e==="/new"||e==="/clear"){this.editor.setText(""),await this.handleClearCommand();return}if(e==="/goal"||e.startsWith("/goal ")){this.editor.setText(""),await this.handleGoalCommand(e.startsWith("/goal ")?e.slice(6).trim():"");return}if(e==="/use"||e.startsWith("/use ")){this.editor.setText(""),this.handleUseCommand(e.startsWith("/use ")?e.slice(5).trim():"");return}if(e==="/trace"){this.editor.setText(""),this.handleTraceCommand();return}if(e==="/compact"||e.startsWith("/compact ")){const s=e.startsWith("/compact ")?e.slice(9).trim():void 0;this.editor.setText(""),await this.handleCompactCommand(s);return}if(e==="/reload"){this.editor.setText(""),await this.handleReloadCommand();return}if(e==="/debug"){this.handleDebugCommand(),this.editor.setText("");return}if(e==="/arminsayshi"){this.handleArminSaysHi(),this.editor.setText("");return}if(e==="/dementedelves"){this.handleDementedDelves(),this.editor.setText("");return}if(e==="/resume"){this.showSessionSelector(),this.editor.setText("");return}if(e==="/quit"){this.editor.setText(""),await this.shutdown();return}if(e.startsWith("!")){const s=e.startsWith("!!"),t=s?e.slice(2).trim():e.slice(1).trim();if(t){if(this.session.isBashRunning){this.showWarning("A bash command is already running. Press Esc to cancel it first."),this.editor.setText(e);return}this.editor.addToHistory?.(e),await this.handleBashCommand(t,s),this.isBashMode=!1,this.updateEditorBorderColor();return}}if(this.session.isCompacting){this.isExtensionCommand(e)?(this.editor.addToHistory?.(e),this.editor.setText(""),await this.session.prompt(e)):this.queueCompactionMessage(e,"steer");return}if(this.session.isStreaming){this.editor.addToHistory?.(e),this.editor.setText(""),await this.session.prompt(e,{streamingBehavior:"steer"}),this.updatePendingMessagesDisplay(),this.ui.requestRender();return}this.flushPendingBashComponents(),this.onInputCallback?this.onInputCallback(e):this.pendingUserInputs.push(e),this.editor.addToHistory?.(e)}}}subscribeToAgent(){this.unsubscribe=this.session.subscribe(async e=>{await this.handleEvent(e)})}async handleEvent(e){switch(this.isInitialized||await this.init(),this.footer.invalidate(),e.type){case"agent_start":this.pendingTools.clear(),this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!0),this.retryEscapeHandler&&(this.defaultEditor.onEscape=this.retryEscapeHandler,this.retryEscapeHandler=void 0),this.retryCountdown&&(this.retryCountdown.dispose(),this.retryCountdown=void 0),this.retryLoader&&(this.retryLoader.stop(),this.retryLoader=void 0),this.stopWorkingLoader(),this.workingVisible&&(this.loadingAnimation=this.createWorkingLoader(),this.statusContainer.addChild(this.loadingAnimation)),this.ui.requestRender();break;case"queue_update":this.updatePendingMessagesDisplay(),this.ui.requestRender();break;case"session_info_changed":this.updateTerminalTitle(),this.footer.invalidate(),this.ui.requestRender();break;case"thinking_level_changed":this.footer.invalidate(),this.updateEditorBorderColor();break;case"message_start":e.message.role==="custom"?(this.addMessageToChat(e.message),this.ui.requestRender()):e.message.role==="user"?(this.addMessageToChat(e.message),this.updatePendingMessagesDisplay(),this.ui.requestRender()):e.message.role==="assistant"&&(this.streamingComponent=new U(void 0,this.hideThinkingBlock,this.getMarkdownThemeWithSettings(),this.hiddenThinkingLabel),this.streamingMessage=e.message,this.chatContainer.addChild(this.streamingComponent),this.streamingComponent.updateContent(this.streamingMessage),this.ui.requestRender());break;case"message_update":if(this.streamingComponent&&e.message.role==="assistant"){this.streamingMessage=e.message,this.streamingComponent.updateContent(this.streamingMessage);for(const s of this.streamingMessage.content)if(s.type==="toolCall")if(this.pendingTools.has(s.id)){const t=this.pendingTools.get(s.id);t&&t.updateArgs(s.arguments)}else{const t=new W(s.name,s.id,s.arguments,{showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells()},this.getRegisteredToolDefinition(s.name),this.ui,this.sessionManager.getCwd());t.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(t),this.pendingTools.set(s.id,t)}this.ui.requestRender()}break;case"message_end":if(e.message.role==="user")break;if(this.streamingComponent&&e.message.role==="assistant"){this.streamingMessage=e.message;let s;if(this.streamingMessage.stopReason==="aborted"){const t=this.session.retryAttempt;s=t>0?`Aborted after ${t} retry attempt${t>1?"s":""}`:"Operation aborted",this.streamingMessage.errorMessage=s}if(this.streamingComponent.updateContent(this.streamingMessage),this.streamingMessage.stopReason==="aborted"||this.streamingMessage.stopReason==="error"){s||(s=this.streamingMessage.errorMessage||"Error");for(const[,t]of this.pendingTools.entries())t.updateResult({content:[{type:"text",text:s}],isError:!0});this.pendingTools.clear()}else for(const[,t]of this.pendingTools.entries())t.setArgsComplete();this.streamingComponent=void 0,this.streamingMessage=void 0,this.footer.invalidate()}this.ui.requestRender();break;case"tool_execution_start":{let s=this.pendingTools.get(e.toolCallId);s||(s=new W(e.toolName,e.toolCallId,e.args,{showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells()},this.getRegisteredToolDefinition(e.toolName),this.ui,this.sessionManager.getCwd()),s.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(s),this.pendingTools.set(e.toolCallId,s)),s.markExecutionStarted(),this.ui.requestRender();break}case"tool_execution_update":{const s=this.pendingTools.get(e.toolCallId);s&&(s.updateResult({...e.partialResult,isError:!1},!0),this.ui.requestRender());break}case"tool_execution_end":{const s=this.pendingTools.get(e.toolCallId);s&&(s.updateResult({...e.result,isError:e.isError}),this.pendingTools.delete(e.toolCallId),this.ui.requestRender());break}case"agent_end":this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!1),this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0,this.statusContainer.clear()),this.streamingComponent&&(this.chatContainer.removeChild(this.streamingComponent),this.streamingComponent=void 0,this.streamingMessage=void 0),this.pendingTools.clear(),await this.checkShutdownRequested(),this.ui.requestRender();break;case"compaction_start":{this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!0),this.autoCompactionEscapeHandler=this.defaultEditor.onEscape,this.defaultEditor.onEscape=()=>{this.session.abortCompaction()},this.statusContainer.clear(),this.compactionStartMs=Date.now(),this.compactionReason=e.reason,this.compactionCancelHint=`(${P("app.interrupt")} to cancel)`,this.autoCompactionLoader=new D(this.ui,s=>a.fg("accent",s),s=>s,this.buildCompactionLabel()),this.statusContainer.addChild(this.autoCompactionLoader),this.compactionTicker&&clearInterval(this.compactionTicker),this.compactionTicker=setInterval(()=>{this.autoCompactionLoader?.setMessage(this.buildCompactionLabel())},250),this.ui.requestRender();break}case"compaction_end":{this.compactionTicker&&(clearInterval(this.compactionTicker),this.compactionTicker=void 0),this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!1),this.autoCompactionEscapeHandler&&(this.defaultEditor.onEscape=this.autoCompactionEscapeHandler,this.autoCompactionEscapeHandler=void 0),this.autoCompactionLoader&&(this.autoCompactionLoader.stop(),this.autoCompactionLoader=void 0,this.statusContainer.clear()),e.aborted?e.reason==="manual"?this.showError("Compaction cancelled"):this.showStatus("Auto-compaction cancelled"):e.result?(this.chatContainer.clear(),this.rebuildChatFromMessages(),this.addMessageToChat(rt(e.result.summary,e.result.tokensBefore,new Date().toISOString())),this.footer.invalidate()):e.errorMessage&&(e.reason==="manual"?this.showError(e.errorMessage):(this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("error",e.errorMessage),1,0)))),this.flushCompactionQueue({willRetry:e.willRetry}),this.ui.requestRender();break}case"auto_retry_start":{this.retryEscapeHandler=this.defaultEditor.onEscape,this.defaultEditor.onEscape=()=>{this.session.abortRetry()},this.statusContainer.clear(),this.retryCountdown?.dispose();const s=h(t=>`Retrying (${e.attempt}/${e.maxAttempts}) in ${t}s... (${P("app.interrupt")} to cancel)`,"retryMessage");this.retryLoader=new D(this.ui,t=>a.fg("warning",t),t=>a.fg("muted",t),s(Math.ceil(e.delayMs/1e3))),this.retryCountdown=new xt(e.delayMs,this.ui,t=>{this.retryLoader?.setMessage(s(t))},()=>{this.retryCountdown=void 0}),this.statusContainer.addChild(this.retryLoader),this.ui.requestRender();break}case"auto_retry_end":{this.retryEscapeHandler&&(this.defaultEditor.onEscape=this.retryEscapeHandler,this.retryEscapeHandler=void 0),this.retryCountdown&&(this.retryCountdown.dispose(),this.retryCountdown=void 0),this.retryLoader&&(this.retryLoader.stop(),this.retryLoader=void 0,this.statusContainer.clear()),e.success||this.showError(`Retry failed after ${e.attempt} attempts: ${e.finalError||"Unknown error"}`),this.ui.requestRender();break}case"overseer_start":{this.overseerLoader?.stop(),this.statusContainer.clear();const s=`(${P("app.interrupt")} to skip)`;this.overseerLoader=new D(this.ui,t=>a.fg("accent",t),t=>a.fg("muted",t),`Koda is reviewing the result\u2026 ${s}`),this.statusContainer.addChild(this.overseerLoader),this.overseerEscapeHandler=this.defaultEditor.onEscape,this.defaultEditor.onEscape=()=>{this.session.abortOverseer()},this._kodaReviewing=!0,this.updateKodaTitle(),this.ui.requestRender();break}case"overseer_end":{this.overseerLoader&&(this.overseerLoader.stop(),this.overseerLoader=void 0,this.statusContainer.clear()),this.overseerEscapeHandler!==void 0&&(this.defaultEditor.onEscape=this.overseerEscapeHandler,this.overseerEscapeHandler=void 0),this._kodaReviewing=!1,this.updateKodaTitle(),e.outcome==="nudging"?this.showStatus(`Overseer: not done yet \u2014 ${e.detail??"continuing"}`):e.outcome==="skipped"?this.showStatus(`Overseer: review skipped (${e.detail??"unavailable"})`):this.showStatus("Overseer: looks complete \u2713"),this.ui.requestRender();break}case"model_switch_notice":{const s=e.message;s.startsWith("\u2191")||s.startsWith("\u25B2")?this._kodaTitleBase="beefed":s.startsWith("\xBB")?this._kodaTitleBase="rerouted":s.startsWith("\u2190")&&(this._kodaTitleBase="idle"),this.updateKodaTitle(),!s.startsWith("\xBB")&&!s.startsWith("\u2190")&&this.showStatus(e.message),this.ui.requestRender();break}case"goal_set":{this._goalAchievedShown=!1,this.renderGoalBlock({text:e.text,milestones:e.milestones});break}case"goal_progress":{const s=e.milestones.filter(i=>i.done).length,t=e.milestones.length;if(e.achieved&&!this._goalAchievedShown)this._goalAchievedShown=!0,this.renderGoalBlock({text:e.text,milestones:e.milestones,achieved:!0});else if(!e.achieved){const i=e.drift?` \xB7 drifting: ${e.drift}`:"";this.showStatus(`Goal: ${s}/${t} milestones${i}`)}break}case"goal_cleared":{this.showStatus("Goal cleared.");break}case"suggest_feature":{const s=e.message.split(/(\/[a-z_]+|run_background)/);let t=a.fg("warning",a.bold("\xBB tip "));s.forEach((i,n)=>{i&&(t+=n%2===1?a.fg("accent",a.bold(i)):a.fg("muted",i))}),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(t,1,0)),this.ui.requestRender();break}case"task_recap":{const s=e.elapsedMs,t=Math.max(0,Math.floor(s/1e3)),i=Math.floor(t/60),n=i>0?`${i}m ${t%60}s`:`${t}s`;this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("accent","\u273B ")+a.fg("dim",`Churned for ${n}`),1,0)),e.recap&&this.chatContainer.addChild(new f(a.fg("dim","\u203B recap: ")+a.fg("muted",e.recap),1,0)),this.ui.requestRender();break}}}getUserMessageText(e){return e.role!=="user"?"":(typeof e.content=="string"?[{type:"text",text:e.content}]:e.content.filter(t=>t.type==="text")).map(t=>t.text).join("")}showStatus(e){const s=this.chatContainer.children,t=s.length>0?s[s.length-1]:void 0,i=s.length>1?s[s.length-2]:void 0;if(t&&i&&t===this.lastStatusText&&i===this.lastStatusSpacer){this.lastStatusText.setText(a.fg("dim",e)),this.ui.requestRender();return}const n=new g(1),o=new f(a.fg("dim",e),1,0);this.chatContainer.addChild(n),this.chatContainer.addChild(o),this.lastStatusSpacer=n,this.lastStatusText=o,this.ui.requestRender()}addMessageToChat(e,s){switch(e.role){case"bashExecution":{const t=new Q(e.command,this.ui,e.excludeFromContext);e.output&&t.appendOutput(e.output),t.setComplete(e.exitCode,e.cancelled,e.truncated?{truncated:!0}:void 0,e.fullOutputPath),this.chatContainer.addChild(t);break}case"custom":{if(e.display){const t=this.session.extensionRunner.getMessageRenderer(e.customType),i=new Tt(e,t,this.getMarkdownThemeWithSettings());i.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(i)}break}case"compactionSummary":{this.chatContainer.addChild(new g(1));const t=new bt(e,this.getMarkdownThemeWithSettings());t.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(t);break}case"branchSummary":{this.chatContainer.addChild(new g(1));const t=new kt(e,this.getMarkdownThemeWithSettings());t.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(t);break}case"user":{const t=this.getUserMessageText(e);if(t){this.chatContainer.children.length>0&&this.chatContainer.addChild(new g(1));const i=tt(t);if(i){const n=new Ht(i,this.getMarkdownThemeWithSettings());if(n.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(n),i.userMessage){const o=new me(i.userMessage,this.getMarkdownThemeWithSettings());this.chatContainer.addChild(o)}}else{const n=new me(t,this.getMarkdownThemeWithSettings());this.chatContainer.addChild(n)}s?.populateHistory&&this.editor.addToHistory?.(t)}break}case"assistant":{const t=new U(e,this.hideThinkingBlock,this.getMarkdownThemeWithSettings(),this.hiddenThinkingLabel);this.chatContainer.addChild(t);break}case"toolResult":break;default:{const t=e}}}renderSessionContext(e,s={}){this.pendingTools.clear();const t=new Map;s.updateFooter&&(this.footer.invalidate(),this.updateEditorBorderColor());for(const i of e.messages)if(i.role==="assistant"){this.addMessageToChat(i);for(const n of i.content)if(n.type==="toolCall"){const o=new W(n.name,n.id,n.arguments,{showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells()},this.getRegisteredToolDefinition(n.name),this.ui,this.sessionManager.getCwd());if(o.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(o),i.stopReason==="aborted"||i.stopReason==="error"){let r;if(i.stopReason==="aborted"){const d=this.session.retryAttempt;r=d>0?`Aborted after ${d} retry attempt${d>1?"s":""}`:"Operation aborted"}else r=i.errorMessage||"Error";o.updateResult({content:[{type:"text",text:r}],isError:!0})}else t.set(n.id,o)}}else if(i.role==="toolResult"){const n=t.get(i.toolCallId);n&&(n.updateResult(i),t.delete(i.toolCallId))}else this.addMessageToChat(i,s);for(const[i,n]of t)this.pendingTools.set(i,n);this.ui.requestRender()}renderInitialMessages(){const e=this.sessionManager.buildSessionContext();this.renderSessionContext(e,{updateFooter:!0,populateHistory:!0});const t=this.sessionManager.getEntries().filter(i=>i.type==="compaction").length;if(t>0){const i=t===1?"1 time":`${t} times`;this.showStatus(`Session compacted ${i}`)}}async getUserInput(){const e=this.pendingUserInputs.shift();return e!==void 0?e:new Promise(s=>{this.onInputCallback=t=>{this.onInputCallback=void 0,s(t)}})}rebuildChatFromMessages(){this.chatContainer.clear();const e=this.sessionManager.buildSessionContext();this.renderSessionContext(e)}handleCtrlC(){const e=Date.now();e-this.lastSigintTime<500?this.shutdown():(this.clearEditor(),this.lastSigintTime=e)}handleCtrlD(){this.shutdown()}isShuttingDown=!1;async shutdown(e){if(this.isShuttingDown)return;this.isShuttingDown=!0,this.unregisterSignalHandlers(),e?.fromSignal&&(await this.runtimeHost.dispose(),await this.ui.terminal.drainInput(1e3),this.stop(),process.exit(0)),await this.ui.terminal.drainInput(1e3),this.stop(),await this.runtimeHost.dispose();const s=Zt(this.sessionManager);s&&process.stdout.write(`${Ve.dim("To resume this session:")} ${s}
27
+ `),process.exit(0)}emergencyTerminalExit(){this.isShuttingDown=!0,this.unregisterSignalHandlers(),V(),process.exit(129)}uncaughtCrash(e){this.isShuttingDown&&process.exit(1),this.isShuttingDown=!0;try{this.unregisterSignalHandlers()}catch{}try{V()}catch{}try{this.ui.stop()}catch{}console.error("koda exiting due to uncaughtException:"),console.error(e),process.exit(1)}async checkShutdownRequested(){this.shutdownRequested&&await this.shutdown()}registerSignalHandlers(){this.unregisterSignalHandlers();const e=["SIGTERM"];process.platform!=="win32"&&e.push("SIGHUP");for(const i of e){const n=h(()=>{V(),this.shutdown({fromSignal:!0})},"handler");process.prependListener(i,n),this.signalCleanupHandlers.push(()=>process.off(i,n))}const s=h(i=>{throw Qt(i)&&this.emergencyTerminalExit(),i},"terminalErrorHandler");process.stdout.on("error",s),process.stderr.on("error",s),this.signalCleanupHandlers.push(()=>process.stdout.off("error",s)),this.signalCleanupHandlers.push(()=>process.stderr.off("error",s));const t=h(i=>this.uncaughtCrash(i),"uncaughtExceptionHandler");process.prependListener("uncaughtException",t),this.signalCleanupHandlers.push(()=>process.off("uncaughtException",t))}unregisterSignalHandlers(){for(const e of this.signalCleanupHandlers)e();this.signalCleanupHandlers=[]}handleCtrlZ(){if(process.platform==="win32"){this.showStatus("Suspend to background is not supported on Windows");return}const e=setInterval(()=>{},2**30),s=h(()=>{},"ignoreSigint");process.on("SIGINT",s),process.once("SIGCONT",()=>{clearInterval(e),process.removeListener("SIGINT",s),this.ui.start(),this.ui.requestRender(!0)});try{this.ui.stop(),process.kill(0,"SIGTSTP")}catch(t){throw clearInterval(e),process.removeListener("SIGINT",s),t}}async handleFollowUp(){const e=(this.editor.getExpandedText?.()??this.editor.getText()).trim();if(e){if(this.session.isCompacting){this.isExtensionCommand(e)?(this.editor.addToHistory?.(e),this.editor.setText(""),await this.session.prompt(e)):this.queueCompactionMessage(e,"followUp");return}this.session.isStreaming?(this.editor.addToHistory?.(e),this.editor.setText(""),await this.session.prompt(e,{streamingBehavior:"followUp"}),this.updatePendingMessagesDisplay(),this.ui.requestRender()):this.editor.onSubmit&&(this.editor.setText(""),this.editor.onSubmit(e))}}handleDequeue(){const e=this.restoreQueuedMessagesToEditor();e===0?this.showStatus("No queued messages to restore"):this.showStatus(`Restored ${e} queued message${e>1?"s":""} to editor`)}updateEditorBorderColor(){if(this.isBashMode)this.editor.borderColor=a.getBashModeBorderColor();else{const e=this.session.thinkingLevel||"off";this.editor.borderColor=a.getThinkingBorderColor(e)}this.ui.requestRender()}cycleThinkingLevel(){const e=this.session.cycleThinkingLevel();e===void 0?this.showStatus("Current model does not support thinking"):(this.footer.invalidate(),this.updateEditorBorderColor(),this.showStatus(`Thinking level: ${e}`))}async cycleModel(e){try{const s=await this.session.cycleModel(e);if(s===void 0){const t=this.session.scopedModels.length>0?"Only one model in scope":"Only one model available";this.showStatus(t)}else{this.footer.invalidate(),this.updateEditorBorderColor();const t=s.model.reasoning&&s.thinkingLevel!=="off"?` (thinking: ${s.thinkingLevel})`:"";this.showStatus(`Switched to ${s.model.name||s.model.id}${t}`),this.maybeWarnAboutAnthropicSubscriptionAuth(s.model)}}catch(s){this.showError(s instanceof Error?s.message:String(s))}}toggleToolOutputExpansion(){this.setToolsExpanded(!this.toolOutputExpanded)}setToolsExpanded(e){this.toolOutputExpanded=e;const s=this.customHeader??this.builtInHeader;H(s)&&s.setExpanded(e);for(const t of this.chatContainer.children)H(t)&&t.setExpanded(e);this.ui.requestRender()}toggleThinkingBlockVisibility(){this.hideThinkingBlock=!this.hideThinkingBlock,this.settingsManager.setHideThinkingBlock(this.hideThinkingBlock),this.chatContainer.clear(),this.rebuildChatFromMessages(),this.streamingComponent&&this.streamingMessage&&(this.streamingComponent.setHideThinkingBlock(this.hideThinkingBlock),this.streamingComponent.updateContent(this.streamingMessage),this.chatContainer.addChild(this.streamingComponent)),this.showStatus(`Thinking blocks: ${this.hideThinkingBlock?"hidden":"visible"}`)}async openExternalEditor(){const e=process.env.VISUAL||process.env.EDITOR;if(!e){this.showWarning("No editor configured. Set $VISUAL or $EDITOR environment variable.");return}const s=this.editor.getExpandedText?.()??this.editor.getText(),t=E.join(F.tmpdir(),`pi-editor-${Date.now()}.pi.md`);try{v.writeFileSync(t,s,"utf-8"),this.ui.stop();const[i,...n]=e.split(" ");if(process.stdout.write(`Launching external editor: ${e}
28
+ Pi will resume when the editor exits.
29
+ `),await new Promise(r=>{const d=j(i,[...n,t],{stdio:"inherit",shell:process.platform==="win32"});d.on("error",()=>r(null)),d.on("close",l=>r(l))})===0){const r=v.readFileSync(t,"utf-8").replace(/\n$/,"");this.editor.setText(r)}}finally{try{v.unlinkSync(t)}catch{}this.ui.start(),this.ui.requestRender(!0)}}clearEditor(){this.editor.setText(""),this.ui.requestRender()}showError(e){this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("error",`Error: ${e}`),1,0)),this.chatContainer.addChild(new g(1)),this.ui.requestRender()}showWarning(e){this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("warning",`Warning: ${e}`),1,0)),this.ui.requestRender()}showNewVersionNotification(e){const s=a.fg("accent",`${z} update`),t=a.fg("muted",`New version ${e.version} is available. Run `)+s,i="https://openadapter.in/changelog",n=Oe().hyperlinks?_e(a.fg("accent","open changelog"),i):a.fg("accent",i),o=a.fg("muted","Changelog: ")+n,r=e.note?.trim();this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k(d=>a.fg("warning",d))),this.chatContainer.addChild(new f(`${a.bold(a.fg("warning","Update Available"))}
30
+ ${t}`,1,0)),r&&(this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new q(r,1,0,this.getMarkdownThemeWithSettings(),{color:h(d=>a.fg("muted",d),"color")})),this.chatContainer.addChild(new g(1))),this.chatContainer.addChild(new f(o,1,0)),this.chatContainer.addChild(new k(d=>a.fg("warning",d))),this.ui.requestRender()}showPackageUpdateNotification(e){const s=a.fg("accent",`${z} update`),t=a.fg("muted","Package updates are available. Run ")+s,i=e.map(n=>`- ${n}`).join(`
31
+ `);this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k(n=>a.fg("warning",n))),this.chatContainer.addChild(new f(`${a.bold(a.fg("warning","Package Updates Available"))}
32
+ ${t}
33
+ ${a.fg("muted","Packages:")}
34
+ ${i}`,1,0)),this.chatContainer.addChild(new k(n=>a.fg("warning",n))),this.ui.requestRender()}getAllQueuedMessages(){return{steering:[...this.session.getSteeringMessages(),...this.compactionQueuedMessages.filter(e=>e.mode==="steer").map(e=>e.text)],followUp:[...this.session.getFollowUpMessages(),...this.compactionQueuedMessages.filter(e=>e.mode==="followUp").map(e=>e.text)]}}clearAllQueues(){const{steering:e,followUp:s}=this.session.clearQueue(),t=this.compactionQueuedMessages.filter(n=>n.mode==="steer").map(n=>n.text),i=this.compactionQueuedMessages.filter(n=>n.mode==="followUp").map(n=>n.text);return this.compactionQueuedMessages=[],{steering:[...e,...t],followUp:[...s,...i]}}updatePendingMessagesDisplay(){this.pendingMessagesContainer.clear();const{steering:e,followUp:s}=this.getAllQueuedMessages();if(e.length>0||s.length>0){this.pendingMessagesContainer.addChild(new g(1));for(const n of e){const o=a.fg("dim",`Steering: ${n}`);this.pendingMessagesContainer.addChild(new K(o,1,0))}for(const n of s){const o=a.fg("dim",`Follow-up: ${n}`);this.pendingMessagesContainer.addChild(new K(o,1,0))}const t=this.getAppKeyDisplay("app.message.dequeue"),i=a.fg("dim",`\u21B3 ${t} to edit all queued messages`);this.pendingMessagesContainer.addChild(new K(i,1,0))}}restoreQueuedMessagesToEditor(e){const{steering:s,followUp:t}=this.clearAllQueues(),i=[...s,...t];if(i.length===0)return this.updatePendingMessagesDisplay(),e?.abort&&this.agent.abort(),0;const n=i.join(`
35
+
36
+ `),o=e?.currentText??this.editor.getText(),r=[n,o].filter(d=>d.trim()).join(`
37
+
38
+ `);return this.editor.setText(r),this.updatePendingMessagesDisplay(),e?.abort&&this.agent.abort(),i.length}queueCompactionMessage(e,s){this.compactionQueuedMessages.push({text:e,mode:s}),this.editor.addToHistory?.(e),this.editor.setText(""),this.updatePendingMessagesDisplay(),this.showStatus("Queued message for after compaction")}isExtensionCommand(e){if(!e.startsWith("/"))return!1;const s=this.session.extensionRunner,t=e.indexOf(" "),i=t===-1?e.slice(1):e.slice(1,t);return!!s.getCommand(i)}async flushCompactionQueue(e){if(this.compactionQueuedMessages.length===0)return;const s=[...this.compactionQueuedMessages];this.compactionQueuedMessages=[],this.updatePendingMessagesDisplay();const t=h(i=>{this.session.clearQueue(),this.compactionQueuedMessages=s,this.updatePendingMessagesDisplay(),this.showError(`Failed to send queued message${s.length>1?"s":""}: ${i instanceof Error?i.message:String(i)}`)},"restoreQueue");try{if(e?.willRetry){for(const l of s)this.isExtensionCommand(l.text)?await this.session.prompt(l.text):l.mode==="followUp"?await this.session.followUp(l.text):await this.session.steer(l.text);this.updatePendingMessagesDisplay();return}const i=s.findIndex(l=>!this.isExtensionCommand(l.text));if(i===-1){for(const l of s)await this.session.prompt(l.text);return}const n=s.slice(0,i),o=s[i],r=s.slice(i+1);for(const l of n)await this.session.prompt(l.text);const d=this.session.prompt(o.text).catch(l=>{t(l)});for(const l of r)this.isExtensionCommand(l.text)?await this.session.prompt(l.text):l.mode==="followUp"?await this.session.followUp(l.text):await this.session.steer(l.text);this.updatePendingMessagesDisplay()}catch(i){t(i)}}flushPendingBashComponents(){for(const e of this.pendingBashComponents)this.pendingMessagesContainer.removeChild(e),this.chatContainer.addChild(e);this.pendingBashComponents=[]}showSelector(e){const s=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor)},"done"),{component:t,focus:i}=e(s);this.editorContainer.clear(),this.editorContainer.addChild(t),this.ui.setFocus(i),this.ui.requestRender()}showSettingsSelector(){this.showSelector(e=>{const s=new Wt({autoCompact:this.session.autoCompactionEnabled,showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells(),autoResizeImages:this.settingsManager.getImageAutoResize(),blockImages:this.settingsManager.getBlockImages(),enableSkillCommands:this.settingsManager.getEnableSkillCommands(),steeringMode:this.session.steeringMode,followUpMode:this.session.followUpMode,transport:this.settingsManager.getTransport(),httpIdleTimeoutMs:this.settingsManager.getHttpIdleTimeoutMs(),thinkingLevel:this.session.thinkingLevel,availableThinkingLevels:this.session.getAvailableThinkingLevels(),currentTheme:this.settingsManager.getTheme()||"dark",availableThemes:Bt(),hideThinkingBlock:this.hideThinkingBlock,collapseChangelog:this.settingsManager.getCollapseChangelog(),enableInstallTelemetry:this.settingsManager.getEnableInstallTelemetry(),doubleEscapeAction:this.settingsManager.getDoubleEscapeAction(),treeFilterMode:this.settingsManager.getTreeFilterMode(),showHardwareCursor:this.settingsManager.getShowHardwareCursor(),editorPaddingX:this.settingsManager.getEditorPaddingX(),autocompleteMaxVisible:this.settingsManager.getAutocompleteMaxVisible(),quietStartup:this.settingsManager.getQuietStartup(),clearOnShrink:this.settingsManager.getClearOnShrink(),showTerminalProgress:this.settingsManager.getShowTerminalProgress(),warnings:this.settingsManager.getWarnings()},{onAutoCompactChange:h(t=>{this.session.setAutoCompactionEnabled(t),this.footer.setAutoCompactEnabled(t)},"onAutoCompactChange"),onShowImagesChange:h(t=>{this.settingsManager.setShowImages(t);for(const i of this.chatContainer.children)i instanceof W&&i.setShowImages(t)},"onShowImagesChange"),onImageWidthCellsChange:h(t=>{this.settingsManager.setImageWidthCells(t);for(const i of this.chatContainer.children)i instanceof W&&i.setImageWidthCells(t)},"onImageWidthCellsChange"),onAutoResizeImagesChange:h(t=>{this.settingsManager.setImageAutoResize(t)},"onAutoResizeImagesChange"),onBlockImagesChange:h(t=>{this.settingsManager.setBlockImages(t)},"onBlockImagesChange"),onEnableSkillCommandsChange:h(t=>{this.settingsManager.setEnableSkillCommands(t),this.setupAutocompleteProvider()},"onEnableSkillCommandsChange"),onSteeringModeChange:h(t=>{this.session.setSteeringMode(t)},"onSteeringModeChange"),onFollowUpModeChange:h(t=>{this.session.setFollowUpMode(t)},"onFollowUpModeChange"),onTransportChange:h(t=>{this.settingsManager.setTransport(t),this.session.agent.transport=t},"onTransportChange"),onHttpIdleTimeoutMsChange:h(t=>{this.settingsManager.setHttpIdleTimeoutMs(t),G(t),this.showStatus(`HTTP idle timeout: ${nt(t)}`)},"onHttpIdleTimeoutMsChange"),onThinkingLevelChange:h(t=>{this.session.setThinkingLevel(t),this.footer.invalidate(),this.updateEditorBorderColor()},"onThinkingLevelChange"),onThemeChange:h(t=>{const i=O(t,!0);this.settingsManager.setTheme(t),this.ui.invalidate(),i.success||this.showError(`Failed to load theme "${t}": ${i.error}
39
+ Fell back to dark theme.`)},"onThemeChange"),onThemePreview:h(t=>{O(t,!0).success&&(this.ui.invalidate(),this.ui.requestRender())},"onThemePreview"),onHideThinkingBlockChange:h(t=>{this.hideThinkingBlock=t,this.settingsManager.setHideThinkingBlock(t);for(const i of this.chatContainer.children)i instanceof U&&i.setHideThinkingBlock(t);this.chatContainer.clear(),this.rebuildChatFromMessages()},"onHideThinkingBlockChange"),onCollapseChangelogChange:h(t=>{this.settingsManager.setCollapseChangelog(t)},"onCollapseChangelogChange"),onEnableInstallTelemetryChange:h(t=>{this.settingsManager.setEnableInstallTelemetry(t)},"onEnableInstallTelemetryChange"),onQuietStartupChange:h(t=>{this.settingsManager.setQuietStartup(t)},"onQuietStartupChange"),onDoubleEscapeActionChange:h(t=>{this.settingsManager.setDoubleEscapeAction(t)},"onDoubleEscapeActionChange"),onTreeFilterModeChange:h(t=>{this.settingsManager.setTreeFilterMode(t)},"onTreeFilterModeChange"),onShowHardwareCursorChange:h(t=>{this.settingsManager.setShowHardwareCursor(t),this.ui.setShowHardwareCursor(t)},"onShowHardwareCursorChange"),onEditorPaddingXChange:h(t=>{this.settingsManager.setEditorPaddingX(t),this.defaultEditor.setPaddingX(t),this.editor!==this.defaultEditor&&this.editor.setPaddingX!==void 0&&this.editor.setPaddingX(t)},"onEditorPaddingXChange"),onAutocompleteMaxVisibleChange:h(t=>{this.settingsManager.setAutocompleteMaxVisible(t),this.defaultEditor.setAutocompleteMaxVisible(t),this.editor!==this.defaultEditor&&this.editor.setAutocompleteMaxVisible!==void 0&&this.editor.setAutocompleteMaxVisible(t)},"onAutocompleteMaxVisibleChange"),onClearOnShrinkChange:h(t=>{this.settingsManager.setClearOnShrink(t),this.ui.setClearOnShrink(t)},"onClearOnShrinkChange"),onShowTerminalProgressChange:h(t=>{this.settingsManager.setShowTerminalProgress(t)},"onShowTerminalProgressChange"),onWarningsChange:h(t=>{this.settingsManager.setWarnings(t)},"onWarningsChange"),onCancel:h(()=>{e(),this.ui.requestRender()},"onCancel")});return{component:s,focus:s.getSettingsList()}})}async handleModelCommand(e){if(!e){this.showModelSelector();return}const s=await this.findExactModelMatch(e);if(s){try{await this.session.setModel(s),this.footer.invalidate(),this.updateEditorBorderColor(),this.showStatus(`Model: ${s.id}`),this.maybeWarnAboutAnthropicSubscriptionAuth(s),this.checkDaxnutsEasterEgg(s)}catch(t){this.showError(t instanceof Error?t.message:String(t))}return}this.showModelSelector(e)}async findExactModelMatch(e){const s=await this.getModelCandidates();return at(e,s)}async getModelCandidates(){if(this.session.scopedModels.length>0)return this.session.scopedModels.map(e=>e.model);this.session.modelRegistry.refresh();try{return await this.session.modelRegistry.getAvailable()}catch{return[]}}async updateAvailableProviderCount(){const e=await this.getModelCandidates(),s=new Set(e.map(t=>t.provider));this.footerDataProvider.setAvailableProviderCount(s.size)}async maybeWarnAboutAnthropicSubscriptionAuth(e=this.session.model){if(this.settingsManager.getWarnings().anthropicExtraUsage===!1||this.anthropicSubscriptionWarningShown||!e||e.provider!=="anthropic")return;if(this.session.modelRegistry.authStorage.get("anthropic")?.type==="oauth"){this.anthropicSubscriptionWarningShown=!0,this.showWarning(we);return}try{const t=await this.session.modelRegistry.getApiKeyForProvider(e.provider);if(!Xt(t))return;this.anthropicSubscriptionWarningShown=!0,this.showWarning(we)}catch{}}showModelSelector(e){this.showSelector(s=>{const t=new It(this.ui,this.session.model,this.settingsManager,this.session.modelRegistry,this.session.scopedModels,async i=>{try{await this.session.setModel(i),this.footer.invalidate(),this.updateEditorBorderColor(),s(),this.showStatus(`Model: ${i.id}`),this.maybeWarnAboutAnthropicSubscriptionAuth(i),this.checkDaxnutsEasterEgg(i)}catch(n){s(),this.showError(n instanceof Error?n.message:String(n))}},()=>{s(),this.ui.requestRender()},e);return{component:t,focus:t}})}async showModelsSelector(){this.session.modelRegistry.refresh();const e=this.session.modelRegistry.getAvailable();if(e.length===0){this.showStatus("No models available");return}const s=this.session.scopedModels,t=s.length>0;let i=null;if(t)i=s.map(o=>`${o.model.provider}/${o.model.id}`);else{const o=this.settingsManager.getEnabledModels();o!==void 0&&o.length>0&&(i=(await ne(o,this.session.modelRegistry)).map(d=>`${d.model.provider}/${d.model.id}`))}const n=h(async o=>{if(i=o===null?null:[...o],o&&o.length>0&&o.length<e.length){const r=await ne(o,this.session.modelRegistry);this.session.setScopedModels(r.map(d=>({model:d.model,thinkingLevel:d.thinkingLevel})))}else this.session.setScopedModels([]);await this.updateAvailableProviderCount(),this.ui.requestRender()},"updateSessionModels");this.showSelector(o=>{const r=new Dt({allModels:e,enabledModelIds:i},{onChange:h(async d=>{await n(d)},"onChange"),onPersist:h(d=>{const l=d===null||d.length===e.length?void 0:d;this.settingsManager.setEnabledModels(l?[...l]:void 0),this.showStatus("Model selection saved to settings")},"onPersist"),onCancel:h(()=>{o(),this.ui.requestRender()},"onCancel")});return{component:r,focus:r}})}showUserMessageSelector(){const e=this.session.getUserMessagesForForking();if(e.length===0){this.showStatus("No messages to fork from");return}const s=e[e.length-1]?.entryId;this.showSelector(t=>{const i=new qt(e.map(n=>({id:n.entryId,text:n.text})),async n=>{try{const o=await this.runtimeHost.fork(n);if(o.cancelled){t(),this.ui.requestRender();return}this.renderCurrentSessionState(),this.editor.setText(o.selectedText??""),t(),this.showStatus("Forked to new session")}catch(o){t(),this.showError(o instanceof Error?o.message:String(o))}},()=>{t(),this.ui.requestRender()},s);return{component:i,focus:i.getMessageList()}})}async handleCloneCommand(){const e=this.sessionManager.getLeafId();if(!e){this.showStatus("Nothing to clone yet");return}try{if((await this.runtimeHost.fork(e,{position:"at"})).cancelled){this.ui.requestRender();return}this.renderCurrentSessionState(),this.editor.setText(""),this.showStatus("Cloned to new session")}catch(s){this.showError(s instanceof Error?s.message:String(s))}}showTreeSelector(e){const s=this.sessionManager.getTree(),t=this.sessionManager.getLeafId(),i=this.settingsManager.getTreeFilterMode();if(s.length===0){this.showStatus("No entries in session");return}this.showSelector(n=>{const o=new Ft(s,t,this.ui.terminal.rows,async r=>{if(r===t){n(),this.showStatus("Already at this point");return}n();let d=!1,l;if(!this.settingsManager.getBranchSummarySkipPrompt())for(;;){const c=await this.showExtensionSelector("Summarize branch?",["No summary","Summarize","Summarize with custom prompt"]);if(c===void 0){this.showTreeSelector(r);return}if(d=c!=="No summary",!(c==="Summarize with custom prompt"&&(l=await this.showExtensionEditor("Custom summarization instructions"),l===void 0)))break}let m;const u=this.defaultEditor.onEscape;d&&(this.defaultEditor.onEscape=()=>{this.session.abortBranchSummary()},this.chatContainer.addChild(new g(1)),m=new D(this.ui,c=>a.fg("accent",c),c=>a.fg("muted",c),`Summarizing branch... (${P("app.interrupt")} to cancel)`),this.statusContainer.addChild(m),this.ui.requestRender());try{const c=await this.session.navigateTree(r,{summarize:d,customInstructions:l});if(c.aborted){this.showStatus("Branch summarization cancelled"),this.showTreeSelector(r);return}if(c.cancelled){this.showStatus("Navigation cancelled");return}this.chatContainer.clear(),this.renderInitialMessages(),c.editorText&&!this.editor.getText().trim()&&this.editor.setText(c.editorText),this.showStatus("Navigated to selected point"),this.flushCompactionQueue({willRetry:!1})}catch(c){this.showError(c instanceof Error?c.message:String(c))}finally{m&&(m.stop(),this.statusContainer.clear()),this.defaultEditor.onEscape=u}},()=>{n(),this.ui.requestRender()},(r,d)=>{this.sessionManager.appendLabelChange(r,d),this.ui.requestRender()},e,i);return{component:o,focus:o}})}showSessionSelector(){this.showSelector(e=>{const s=new Lt(t=>B.list(this.sessionManager.getCwd(),this.sessionManager.getSessionDir(),t),t=>this.sessionManager.usesDefaultSessionDir()?B.listAll(t):B.listAll(this.sessionManager.getSessionDir(),t),async t=>{e(),await this.handleResumeSession(t)},()=>{e(),this.ui.requestRender()},()=>{this.shutdown()},()=>this.ui.requestRender(),{renameSession:h(async(t,i)=>{const n=(i??"").trim();if(!n)return;B.open(t).appendSessionInfo(n)},"renameSession"),showRenameHint:!0,keybindings:this.keybindings},this.sessionManager.getSessionFile());return{component:s,focus:s}})}async handleResumeSession(e,s){this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear();try{const t=await this.runtimeHost.switchSession(e,{withSession:s?.withSession});return t.cancelled||(this.renderCurrentSessionState(),this.showStatus("Resumed session")),t}catch(t){if(t instanceof oe){const i=await this.promptForMissingSessionCwd(t);if(!i)return this.showStatus("Resume cancelled"),{cancelled:!0};const n=await this.runtimeHost.switchSession(e,{cwdOverride:i,withSession:s?.withSession});return n.cancelled||(this.renderCurrentSessionState(),this.showStatus("Resumed session in current cwd")),n}return this.handleFatalRuntimeError("Failed to resume session",t)}}getLoginProviderOptions(e){const t=this.session.modelRegistry.authStorage.getOAuthProviders(),i=new Set(t.map(d=>d.id)),n=t.map(d=>({id:d.id,name:d.name,authType:"oauth"})),o=new Set(this.session.modelRegistry.getAll().map(d=>d.provider));for(const d of o)is(d,i)&&n.push({id:d,name:this.session.modelRegistry.getProviderDisplayName(d),authType:"api_key"});return(e?n.filter(d=>d.authType===e):n).sort((d,l)=>d.name.localeCompare(l.name))}getLogoutProviderOptions(){const e=this.session.modelRegistry.authStorage,s=[];for(const t of e.list()){const i=e.get(t);i&&s.push({id:t,name:this.session.modelRegistry.getProviderDisplayName(t),authType:i.type})}return s.sort((t,i)=>t.name.localeCompare(i.name))}showLoginAuthTypeSelector(){const e="Use a subscription",s="Use an API key";this.showSelector(t=>{const i=new X("Select authentication method:",[e,s],n=>{t();const o=n===e?"oauth":"api_key";this.showLoginProviderSelector(o)},()=>{t(),this.ui.requestRender()});return{component:i,focus:i}})}showLoginProviderSelector(e){const s=this.getLoginProviderOptions(e);if(s.length===0){this.showStatus(e==="oauth"?"No subscription providers available.":"No API key providers available.");return}this.showSelector(t=>{const i=new pe("login",this.session.modelRegistry.authStorage,s,async n=>{t();const o=s.find(r=>r.id===n);o&&(o.authType==="oauth"?await this.showLoginDialog(o.id,o.name):o.id===ts?this.showBedrockSetupDialog(o.id,o.name):await this.showApiKeyLoginDialog(o.id,o.name))},()=>{t(),this.showLoginAuthTypeSelector()},n=>this.session.modelRegistry.getProviderAuthStatus(n));return{component:i,focus:i}})}async showOAuthSelector(e){if(e==="login"){this.showLoginAuthTypeSelector();return}const s=this.getLogoutProviderOptions();if(s.length===0){this.showStatus("No stored credentials to remove. /logout only removes credentials saved by /login; environment variables and models.json config are unchanged.");return}this.showSelector(t=>{const i=new pe(e,this.session.modelRegistry.authStorage,s,async n=>{t();const o=s.find(r=>r.id===n);if(o)try{this.session.modelRegistry.authStorage.logout(o.id),this.session.modelRegistry.refresh(),await this.updateAvailableProviderCount();const r=o.authType==="oauth"?`Logged out of ${o.name}`:`Removed stored API key for ${o.name}. Environment variables and models.json config are unchanged.`;this.showStatus(r)}catch(r){this.showError(`Logout failed: ${r instanceof Error?r.message:String(r)}`)}},()=>{t(),this.ui.requestRender()});return{component:i,focus:i}})}async completeProviderAuthentication(e,s,t,i){this.session.modelRegistry.refresh();const n=t==="oauth"?`Logged in to ${s}`:`Saved API key for ${s}`;let o,r;if(Jt(i)){const l=this.session.modelRegistry.getAvailable().filter(m=>m.provider===e);if(!es(e))r=`${n}, but no default model is configured for provider "${e}". Use /model to select a model.`;else if(l.length===0)r=`${n}, but no models are available for that provider. Use /model to select a model.`;else{const m=ie[e];if(o=l.find(u=>u.id===m),!o)r=`${n}, but its default model "${m}" is not available. Use /model to select a model.`;else try{await this.session.setModel(o)}catch(u){o=void 0;const c=u instanceof Error?u.message:String(u);r=`${n}, but selecting its default model failed: ${c}. Use /model to select a model.`}}}await this.updateAvailableProviderCount(),this.footer.invalidate(),this.updateEditorBorderColor(),o?(this.showStatus(`${n}. Selected ${o.id}. Credentials saved to ${se()}`),this.maybeWarnAboutAnthropicSubscriptionAuth(o),this.checkDaxnutsEasterEgg(o)):(this.showStatus(`${n}. Credentials saved to ${se()}`),r?this.showError(r):this.maybeWarnAboutAnthropicSubscriptionAuth())}showBedrockSetupDialog(e,s){const t=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor),this.ui.requestRender()},"restoreEditor"),i=new J(this.ui,e,()=>t(),s,"Amazon Bedrock setup");i.showInfo([a.fg("text","Amazon Bedrock uses AWS credentials instead of a single API key."),a.fg("text","Configure an AWS profile, IAM keys, bearer token, or role-based credentials."),a.fg("muted","See:"),a.fg("accent",` ${E.join(Ye(),"providers.md")}`)]),this.editorContainer.clear(),this.editorContainer.addChild(i),this.ui.setFocus(i),this.ui.requestRender()}async showApiKeyLoginDialog(e,s){const t=this.session.model,i=new J(this.ui,e,(o,r)=>{},s);this.editorContainer.clear(),this.editorContainer.addChild(i),this.ui.setFocus(i),this.ui.requestRender();const n=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor),this.ui.requestRender()},"restoreEditor");try{const o=(await i.showPrompt("Enter API key:")).trim();if(!o)throw new Error("API key cannot be empty.");this.session.modelRegistry.authStorage.set(e,{type:"api_key",key:o}),n(),await this.completeProviderAuthentication(e,s,"api_key",t)}catch(o){n();const r=o instanceof Error?o.message:String(o);r!=="Login cancelled"&&this.showError(`Failed to save API key for ${s}: ${r}`)}}showOAuthLoginSelect(e,s){return new Promise(t=>{const i=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(e),this.ui.setFocus(e),this.ui.requestRender()},"restoreDialog"),n=s.options.map(r=>r.label),o=new X(s.message,n,r=>{i(),t(s.options.find(d=>d.label===r)?.id)},()=>{i(),t(void 0)});this.editorContainer.clear(),this.editorContainer.addChild(o),this.ui.setFocus(o),this.ui.requestRender()})}async showLoginDialog(e,s){const t=this.session.modelRegistry.authStorage.getOAuthProviders().find(u=>u.id===e),i=this.session.model,n=t?.usesCallbackServer??!1,o=new J(this.ui,e,(u,c)=>{},s);this.editorContainer.clear(),this.editorContainer.addChild(o),this.ui.setFocus(o),this.ui.requestRender();let r,d;const l=new Promise((u,c)=>{r=u,d=c}),m=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor),this.ui.requestRender()},"restoreEditor");try{await this.session.modelRegistry.authStorage.login(e,{onAuth:h(u=>{o.showAuth(u.url,u.instructions),n&&o.showManualInput("Paste redirect URL below, or complete login in browser:").then(c=>{c&&r&&(r(c),r=void 0)}).catch(()=>{d&&(d(new Error("Login cancelled")),d=void 0)})},"onAuth"),onDeviceCode:h(u=>{o.showDeviceCode(u),o.showWaiting("Waiting for authentication...")},"onDeviceCode"),onPrompt:h(async u=>o.showPrompt(u.message,u.placeholder),"onPrompt"),onProgress:h(u=>{o.showProgress(u)},"onProgress"),onSelect:h(u=>this.showOAuthLoginSelect(o,u),"onSelect"),onManualCodeInput:h(()=>l,"onManualCodeInput"),signal:o.signal}),m(),await this.completeProviderAuthentication(e,s,"oauth",i)}catch(u){m();const c=u instanceof Error?u.message:String(u);c!=="Login cancelled"&&this.showError(`Failed to login to ${s}: ${c}`)}}async handleReloadCommand(){if(this.session.isStreaming){this.showWarning("Wait for the current response to finish before reloading.");return}if(this.session.isCompacting){this.showWarning("Wait for compaction to finish before reloading.");return}this.resetExtensionUI();const e=new A,s=h(n=>a.fg("border",n),"borderColor");e.addChild(new k(s)),e.addChild(new g(1)),e.addChild(new f(a.fg("muted","Reloading keybindings, extensions, skills, prompts, themes..."),1,0)),e.addChild(new g(1)),e.addChild(new k(s));const t=this.editor;this.editorContainer.clear(),this.editorContainer.addChild(e),this.ui.setFocus(e),this.ui.requestRender(!0),await new Promise(n=>process.nextTick(n));const i=h(n=>{this.editorContainer.clear(),this.editorContainer.addChild(n),this.ui.setFocus(n),this.ui.requestRender()},"dismissReloadBox");try{await this.session.reload(),G(this.settingsManager.getHttpIdleTimeoutMs()),this.keybindings.reload();const n=this.customHeader??this.builtInHeader;H(n)&&n.setExpanded(this.toolOutputExpanded),Y(this.session.resourceLoader.getThemes().themes),this.hideThinkingBlock=this.settingsManager.getHideThinkingBlock();const o=this.settingsManager.getTheme(),r=o?O(o,!0):{success:!0};r.success||this.showError(`Failed to load theme "${o}": ${r.error}
40
+ Fell back to dark theme.`);const d=this.settingsManager.getEditorPaddingX(),l=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor.setPaddingX(d),this.defaultEditor.setAutocompleteMaxVisible(l),this.editor!==this.defaultEditor&&(this.editor.setPaddingX?.(d),this.editor.setAutocompleteMaxVisible?.(l)),this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor()),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink()),this.setupAutocompleteProvider();const m=this.session.extensionRunner;this.setupExtensionShortcuts(m),this.rebuildChatFromMessages(),i(this.editor),this.showLoadedResources({force:!1,showDiagnosticsWhenQuiet:!0});const u=this.session.modelRegistry.getError();u&&this.showError(`models.json error: ${u}`),this.showStatus("Reloaded keybindings, extensions, skills, prompts, themes")}catch(n){i(t),this.showError(`Reload failed: ${n instanceof Error?n.message:String(n)}`)}}async handleExportCommand(e){const s=this.getPathCommandArgument(e,"/export");try{if(s?.endsWith(".jsonl")){const t=this.session.exportToJsonl(s);this.showStatus(`Session exported to: ${t}`)}else{const t=await this.session.exportToHtml(s);this.showStatus(`Session exported to: ${t}`)}}catch(t){this.showError(`Failed to export session: ${t instanceof Error?t.message:"Unknown error"}`)}}getPathCommandArgument(e,s){if(e===s||!e.startsWith(`${s} `))return;const t=e.slice(s.length+1).trimStart();if(!t)return;const i=t[0];if(i==='"'||i==="'"){const o=t.indexOf(i,1);return o<0?void 0:t.slice(1,o)}const n=t.search(/\s/);return n<0?t:t.slice(0,n)}async handleImportCommand(e){const s=this.getPathCommandArgument(e,"/import");if(!s){this.showError("Usage: /import <path.jsonl>");return}if(!await this.showExtensionConfirm("Import session",`Replace current session with ${s}?`)){this.showStatus("Import cancelled");return}try{if(this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear(),(await this.runtimeHost.importFromJsonl(s)).cancelled){this.showStatus("Import cancelled");return}this.renderCurrentSessionState(),this.showStatus(`Session imported from: ${s}`)}catch(i){if(i instanceof oe){const n=await this.promptForMissingSessionCwd(i);if(!n){this.showStatus("Import cancelled");return}if((await this.runtimeHost.importFromJsonl(s,n)).cancelled){this.showStatus("Import cancelled");return}this.renderCurrentSessionState(),this.showStatus(`Session imported from: ${s}`);return}if(i instanceof st){this.showError(`Failed to import session: ${i.message}`);return}await this.handleFatalRuntimeError("Failed to import session",i)}}async handleShareCommand(){try{if(Qe("gh",["auth","status"],{encoding:"utf-8"}).status!==0){this.showError("GitHub CLI is not logged in. Run 'gh auth login' first.");return}}catch{this.showError("GitHub CLI (gh) is not installed. Install it from https://cli.github.com/");return}const e=E.join(F.tmpdir(),"session.html");try{await this.session.exportToHtml(e)}catch(n){this.showError(`Failed to export session: ${n instanceof Error?n.message:"Unknown error"}`);return}const s=new Et(this.ui,a,"Creating gist...");this.editorContainer.clear(),this.editorContainer.addChild(s),this.ui.setFocus(s),this.ui.requestRender();const t=h(()=>{s.dispose(),this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor);try{v.unlinkSync(e)}catch{}},"restoreEditor");let i=null;s.onAbort=()=>{i?.kill(),t(),this.showStatus("Share cancelled")};try{const n=await new Promise(l=>{i=j("gh",["gist","create","--public=false",e]);let m="",u="";i.stdout?.on("data",c=>{m+=c.toString()}),i.stderr?.on("data",c=>{u+=c.toString()}),i.on("close",c=>l({stdout:m,stderr:u,code:c}))});if(s.signal.aborted)return;if(t(),n.code!==0){const l=n.stderr?.trim()||"Unknown error";this.showError(`Failed to create gist: ${l}`);return}const o=n.stdout?.trim(),r=o?.split("/").pop();if(!r){this.showError("Failed to parse gist ID from gh output");return}const d=Ze(r);this.showStatus(`Share URL: ${d}
41
+ Gist: ${o}`)}catch(n){s.signal.aborted||(t(),this.showError(`Failed to create gist: ${n instanceof Error?n.message:"Unknown error"}`))}}async handleCopyCommand(){const e=this.session.getLastAssistantText();if(!e){this.showError("No agent messages to copy yet.");return}try{await pt(e),this.showStatus("Copied last agent message to clipboard")}catch(s){this.showError(s instanceof Error?s.message:String(s))}}handleNameCommand(e){const s=e.replace(/^\/name\s*/,"").trim();if(!s){const t=this.sessionManager.getSessionName();t?(this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("dim",`Session name: ${t}`),1,0))):this.showWarning("Usage: /name <name>"),this.ui.requestRender();return}this.session.setSessionName(s),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("dim",`Session name set: ${s}`),1,0)),this.ui.requestRender()}handleSessionCommand(){const e=this.session.getSessionStats(),s=this.sessionManager.getSessionName();let t=`${a.bold("Session Info")}
42
+
43
+ `;s&&(t+=`${a.fg("dim","Name:")} ${s}
44
+ `),t+=`${a.fg("dim","File:")} ${e.sessionFile??"In-memory"}
45
+ `,t+=`${a.fg("dim","ID:")} ${e.sessionId}
46
+
47
+ `,t+=`${a.bold("Messages")}
48
+ `,t+=`${a.fg("dim","User:")} ${e.userMessages}
49
+ `,t+=`${a.fg("dim","Assistant:")} ${e.assistantMessages}
50
+ `,t+=`${a.fg("dim","Tool Calls:")} ${e.toolCalls}
51
+ `,t+=`${a.fg("dim","Tool Results:")} ${e.toolResults}
52
+ `,t+=`${a.fg("dim","Total:")} ${e.totalMessages}
53
+
54
+ `,t+=`${a.bold("Tokens")}
55
+ `,t+=`${a.fg("dim","Input:")} ${e.tokens.input.toLocaleString()}
56
+ `,t+=`${a.fg("dim","Output:")} ${e.tokens.output.toLocaleString()}
57
+ `,e.tokens.cacheRead>0&&(t+=`${a.fg("dim","Cache Read:")} ${e.tokens.cacheRead.toLocaleString()}
58
+ `),e.tokens.cacheWrite>0&&(t+=`${a.fg("dim","Cache Write:")} ${e.tokens.cacheWrite.toLocaleString()}
59
+ `),t+=`${a.fg("dim","Total:")} ${e.tokens.total.toLocaleString()}
60
+ `,e.cost>0&&(t+=`
61
+ ${a.bold("Cost")}
62
+ `,t+=`${a.fg("dim","Total:")} ${e.cost.toFixed(4)}`),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(t,1,0)),this.ui.requestRender()}handleChangelogCommand(){const e=ae(),s=he(e),t=s.length>0?s.reverse().map(i=>i.content).join(`
63
+
64
+ `):"No changelog entries found.";this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k),this.chatContainer.addChild(new f(a.bold(a.fg("accent","What's New")),1,0)),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new q(t,1,1,this.getMarkdownThemeWithSettings())),this.chatContainer.addChild(new k),this.ui.requestRender()}getAppKeyDisplay(e){return ue(e)}getEditorKeyDisplay(e){return ue(e)}handleHotkeysCommand(){const e=this.getEditorKeyDisplay("tui.editor.cursorUp"),s=this.getEditorKeyDisplay("tui.editor.cursorDown"),t=this.getEditorKeyDisplay("tui.editor.cursorLeft"),i=this.getEditorKeyDisplay("tui.editor.cursorRight"),n=this.getEditorKeyDisplay("tui.editor.cursorWordLeft"),o=this.getEditorKeyDisplay("tui.editor.cursorWordRight"),r=this.getEditorKeyDisplay("tui.editor.cursorLineStart"),d=this.getEditorKeyDisplay("tui.editor.cursorLineEnd"),l=this.getEditorKeyDisplay("tui.editor.jumpForward"),m=this.getEditorKeyDisplay("tui.editor.jumpBackward"),u=this.getEditorKeyDisplay("tui.editor.pageUp"),c=this.getEditorKeyDisplay("tui.editor.pageDown"),y=this.getEditorKeyDisplay("tui.input.submit"),S=this.getEditorKeyDisplay("tui.input.newLine"),b=this.getEditorKeyDisplay("tui.editor.deleteWordBackward"),$=this.getEditorKeyDisplay("tui.editor.deleteWordForward"),x=this.getEditorKeyDisplay("tui.editor.deleteToLineStart"),M=this.getEditorKeyDisplay("tui.editor.deleteToLineEnd"),w=this.getEditorKeyDisplay("tui.editor.yank"),C=this.getEditorKeyDisplay("tui.editor.yankPop"),T=this.getEditorKeyDisplay("tui.editor.undo"),I=this.getEditorKeyDisplay("tui.input.tab"),Se=this.getAppKeyDisplay("app.interrupt"),ye=this.getAppKeyDisplay("app.clear"),Ee=this.getAppKeyDisplay("app.exit"),ke=this.getAppKeyDisplay("app.suspend"),be=this.getAppKeyDisplay("app.thinking.cycle"),xe=this.getAppKeyDisplay("app.model.cycleForward"),Me=this.getAppKeyDisplay("app.model.select"),Te=this.getAppKeyDisplay("app.tools.expand"),$e=this.getAppKeyDisplay("app.thinking.toggle"),Pe=this.getAppKeyDisplay("app.editor.external"),Ae=this.getAppKeyDisplay("app.model.cycleBackward"),Re=this.getAppKeyDisplay("app.message.followUp"),ve=this.getAppKeyDisplay("app.message.dequeue"),Ie=this.getAppKeyDisplay("app.clipboard.pasteImage");let N=`
65
+ **Navigation**
66
+ | Key | Action |
67
+ |-----|--------|
68
+ | \`${e}\` / \`${s}\` / \`${t}\` / \`${i}\` | Move cursor / browse history (Up when empty) |
69
+ | \`${n}\` / \`${o}\` | Move by word |
70
+ | \`${r}\` | Start of line |
71
+ | \`${d}\` | End of line |
72
+ | \`${l}\` | Jump forward to character |
73
+ | \`${m}\` | Jump backward to character |
74
+ | \`${u}\` / \`${c}\` | Scroll by page |
75
+
76
+ **Editing**
77
+ | Key | Action |
78
+ |-----|--------|
79
+ | \`${y}\` | Send message |
80
+ | \`${S}\` | New line${process.platform==="win32"?" (Ctrl+Enter on Windows Terminal)":""} |
81
+ | \`${b}\` | Delete word backwards |
82
+ | \`${$}\` | Delete word forwards |
83
+ | \`${x}\` | Delete to start of line |
84
+ | \`${M}\` | Delete to end of line |
85
+ | \`${w}\` | Paste the most-recently-deleted text |
86
+ | \`${C}\` | Cycle through the deleted text after pasting |
87
+ | \`${T}\` | Undo |
88
+
89
+ **Other**
90
+ | Key | Action |
91
+ |-----|--------|
92
+ | \`${I}\` | Path completion / accept autocomplete |
93
+ | \`${Se}\` | Cancel autocomplete / abort streaming |
94
+ | \`${ye}\` | Clear editor (first) / exit (second) |
95
+ | \`${Ee}\` | Exit (when editor is empty) |
96
+ | \`${ke}\` | Suspend to background |
97
+ | \`${be}\` | Cycle thinking level |
98
+ | \`${xe}\` / \`${Ae}\` | Cycle models |
99
+ | \`${Me}\` | Open model selector |
100
+ | \`${Te}\` | Toggle tool output expansion |
101
+ | \`${$e}\` | Toggle thinking block visibility |
102
+ | \`${Pe}\` | Edit message in external editor |
103
+ | \`${Re}\` | Queue follow-up message |
104
+ | \`${ve}\` | Restore queued messages |
105
+ | \`${Ie}\` | Paste image from clipboard |
106
+ | \`/\` | Slash commands |
107
+ | \`!\` | Run bash command |
108
+ | \`!!\` | Run bash command (excluded from context) |
109
+ `;const Z=this.session.extensionRunner.getShortcuts(this.keybindings.getEffectiveConfig());if(Z.size>0){N+=`
110
+ **Extensions**
111
+ | Key | Action |
112
+ |-----|--------|
113
+ `;for(const[De,ee]of Z){const Le=ee.description??ee.extensionPath,We=ce(De,{capitalize:!0});N+=`| \`${We}\` | ${Le} |
114
+ `}}this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k),this.chatContainer.addChild(new f(a.bold(a.fg("accent","Keyboard Shortcuts")),1,0)),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new q(N.trim(),1,1,this.getMarkdownThemeWithSettings())),this.chatContainer.addChild(new k),this.ui.requestRender()}_goalAchievedShown=!1;renderGoalBlock(e){const s=e.milestones.filter(n=>n.done).length,t=e.milestones.length;this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k);const i=e.achieved?a.bold(a.fg("success",`\u2713 Goal achieved \u2014 ${e.text}`)):a.bold(a.fg("accent",`Goal \u2014 ${e.text}`))+a.fg("dim",` ${s}/${t}`);this.chatContainer.addChild(new f(i,1,0));for(const n of e.milestones){const o=n.done?a.fg("success","\u2713"):a.fg("dim","\u25CB"),r=n.done?a.fg("success",n.text):a.fg("text",n.text);this.chatContainer.addChild(new f(` ${o} ${r}`,1,0))}this.chatContainer.addChild(new k),this.ui.requestRender()}async handleGoalCommand(e){if(e==="clear"){this.session.clearSessionGoal();return}if(e){this._goalAchievedShown=!1,this.statusContainer.clear();const t=new D(this.ui,i=>a.fg("accent",i),i=>a.fg("muted",i),"Setting goal \u2014 breaking it into milestones\u2026");this.statusContainer.addChild(t),this.ui.requestRender();try{await this.session.setSessionGoal(e)}finally{t.stop(),this.statusContainer.clear(),this.ui.requestRender()}return}const s=this.session.getSessionGoal();if(!s){this.showStatus("No session goal set. Use /goal <what you want to accomplish this session>.");return}this.renderGoalBlock(s)}handleTraceCommand(){const e=this.session.getHarnessTrace();if(e.length===0){this.showStatus("No harness activity yet (no model switches, verification, or escalation this session).");return}this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k),this.chatContainer.addChild(new f(a.bold(a.fg("accent","Harness trace")),1,0));for(const s of e.slice(-25)){const t=new Date(s.ts).toLocaleTimeString();this.chatContainer.addChild(new f(` ${a.fg("dim",t)} ${a.fg("accent",s.kind.padEnd(9))} ${a.fg("text",s.detail)}`,1,0))}this.chatContainer.addChild(new k),this.ui.requestRender()}handleUseCommand(e){const s=this.session.getPinnedSkills(),t=this.session.listSkillNames();if(!e){if(t.length===0){this.showStatus("No skills installed. Drop SKILL.md folders in ~/.koda/agent/skills.");return}const i=t.map(n=>s.includes(n)?`${n} (active)`:n).join(", ");this.showStatus(`Skills: ${i}. /use <name> to toggle on/off (no chat).`);return}if(e==="clear"||e==="none"){for(const i of s)this.session.unpinSkill(i);this.showStatus(s.length?`Skills off: ${s.join(", ")}.`:"No skills were active.");return}s.includes(e)?(this.session.unpinSkill(e),this.showStatus(`Skill "${e}" off.`)):this.session.pinSkill(e)?this.showStatus(`\u25B8 Skill "${e}" active for this session \u2014 it'll guide every task until /use ${e} again.`):this.showStatus(`No skill named "${e}". Available: ${t.join(", ")||"(none)"}.`)}async handleClearCommand(){this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear();try{if((await this.runtimeHost.newSession()).cancelled)return;this.renderCurrentSessionState(),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(`${a.fg("accent","\u2713 New session started")}`,1,1)),this.ui.requestRender()}catch(e){await this.handleFatalRuntimeError("Failed to create session",e)}}handleDebugCommand(){const e=this.ui.terminal.columns,s=this.ui.terminal.rows,t=this.ui.render(e),i=Je(),n=[`Debug output at ${new Date().toISOString()}`,`Terminal: ${e}x${s}`,`Total lines: ${t.length}`,"","=== All rendered lines with visible widths ===",...t.map((o,r)=>{const d=Ge(o),l=JSON.stringify(o);return`[${r}] (w=${d}) ${l}`}),"","=== Agent messages (JSONL) ===",...this.session.messages.map(o=>JSON.stringify(o)),""].join(`
115
+ `);v.mkdirSync(E.dirname(i),{recursive:!0}),v.writeFileSync(i,n),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(`${a.fg("accent","\u2713 Debug log written")}
116
+ ${a.fg("muted",i)}`,1,1)),this.ui.requestRender()}handleArminSaysHi(){this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new yt(this.ui)),this.ui.requestRender()}handleDementedDelves(){this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new Pt),this.ui.requestRender()}handleDaxnuts(){this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new $t(this.ui)),this.ui.requestRender()}checkDaxnutsEasterEgg(e){e.provider==="opencode"&&e.id.toLowerCase().includes("kimi-k2.5")&&this.handleDaxnuts()}async handleBashCommand(e,s=!1){const i=await this.session.extensionRunner.emitUserBash({type:"user_bash",command:e,excludeFromContext:s,cwd:this.sessionManager.getCwd()});if(i?.result){const o=i.result;this.bashComponent=new Q(e,this.ui,s),this.session.isStreaming?(this.pendingMessagesContainer.addChild(this.bashComponent),this.pendingBashComponents.push(this.bashComponent)):this.chatContainer.addChild(this.bashComponent),o.output&&this.bashComponent.appendOutput(o.output),this.bashComponent.setComplete(o.exitCode,o.cancelled,o.truncated?{truncated:!0,content:o.output}:void 0,o.fullOutputPath),this.session.recordBashResult(e,o,{excludeFromContext:s}),this.bashComponent=void 0,this.ui.requestRender();return}const n=this.session.isStreaming;this.bashComponent=new Q(e,this.ui,s),n?(this.pendingMessagesContainer.addChild(this.bashComponent),this.pendingBashComponents.push(this.bashComponent)):this.chatContainer.addChild(this.bashComponent),this.ui.requestRender();try{const o=await this.session.executeBash(e,r=>{this.bashComponent&&(this.bashComponent.appendOutput(r),this.ui.requestRender())},{excludeFromContext:s,operations:i?.operations});this.bashComponent&&this.bashComponent.setComplete(o.exitCode,o.cancelled,o.truncated?{truncated:!0,content:o.output}:void 0,o.fullOutputPath)}catch(o){this.bashComponent&&this.bashComponent.setComplete(void 0,!1),this.showError(`Bash command failed: ${o instanceof Error?o.message:"Unknown error"}`)}this.bashComponent=void 0,this.ui.requestRender()}async handleCompactCommand(e){if(this.sessionManager.getEntries().filter(i=>i.type==="message").length<2){this.showWarning("Nothing to compact (no messages yet)");return}this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear();try{await this.session.compact(e)}catch{}}stop(){this.unregisterSignalHandlers(),this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!1),this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.clearExtensionTerminalInputListeners(),this.footer.dispose(),this.footerDataProvider.dispose(),this.unsubscribe&&this.unsubscribe(),this.isInitialized&&(this.ui.stop(),this.isInitialized=!1)}}export{_ as InteractiveMode,Zt as formatResumeCommand,is as isApiKeyLoginProvider};
@@ -0,0 +1,86 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
3
+ "name": "dark",
4
+ "vars": {
5
+ "cyan": "#00d7ff",
6
+ "blue": "#5f87ff",
7
+ "green": "#b5bd68",
8
+ "red": "#cc6666",
9
+ "yellow": "#ffff00",
10
+ "text": "#d4d4d4",
11
+ "gray": "#808080",
12
+ "dimGray": "#666666",
13
+ "darkGray": "#505050",
14
+ "accent": "#a78bfa",
15
+ "selectedBg": "#3a3a4a",
16
+ "userMsgBg": "#343541",
17
+ "toolPendingBg": "#282832",
18
+ "toolSuccessBg": "#283228",
19
+ "toolErrorBg": "#3c2828",
20
+ "customMsgBg": "#2d2838"
21
+ },
22
+ "colors": {
23
+ "accent": "accent",
24
+ "border": "blue",
25
+ "borderAccent": "accent",
26
+ "borderMuted": "darkGray",
27
+ "success": "green",
28
+ "error": "red",
29
+ "warning": "yellow",
30
+ "muted": "gray",
31
+ "dim": "dimGray",
32
+ "text": "text",
33
+ "thinkingText": "gray",
34
+
35
+ "selectedBg": "selectedBg",
36
+ "userMessageBg": "userMsgBg",
37
+ "userMessageText": "text",
38
+ "customMessageBg": "customMsgBg",
39
+ "customMessageText": "text",
40
+ "customMessageLabel": "#9575cd",
41
+ "toolPendingBg": "toolPendingBg",
42
+ "toolSuccessBg": "toolSuccessBg",
43
+ "toolErrorBg": "toolErrorBg",
44
+ "toolTitle": "text",
45
+ "toolOutput": "gray",
46
+
47
+ "mdHeading": "#f0c674",
48
+ "mdLink": "#81a2be",
49
+ "mdLinkUrl": "dimGray",
50
+ "mdCode": "accent",
51
+ "mdCodeBlock": "green",
52
+ "mdCodeBlockBorder": "gray",
53
+ "mdQuote": "gray",
54
+ "mdQuoteBorder": "gray",
55
+ "mdHr": "gray",
56
+ "mdListBullet": "accent",
57
+
58
+ "toolDiffAdded": "green",
59
+ "toolDiffRemoved": "red",
60
+ "toolDiffContext": "gray",
61
+
62
+ "syntaxComment": "#6A9955",
63
+ "syntaxKeyword": "#569CD6",
64
+ "syntaxFunction": "#DCDCAA",
65
+ "syntaxVariable": "#9CDCFE",
66
+ "syntaxString": "#CE9178",
67
+ "syntaxNumber": "#B5CEA8",
68
+ "syntaxType": "#4EC9B0",
69
+ "syntaxOperator": "#D4D4D4",
70
+ "syntaxPunctuation": "#D4D4D4",
71
+
72
+ "thinkingOff": "darkGray",
73
+ "thinkingMinimal": "#6e6e6e",
74
+ "thinkingLow": "#5f87af",
75
+ "thinkingMedium": "#81a2be",
76
+ "thinkingHigh": "#b294bb",
77
+ "thinkingXhigh": "#d183e8",
78
+
79
+ "bashMode": "green"
80
+ },
81
+ "export": {
82
+ "pageBg": "#18181e",
83
+ "cardBg": "#1e1e24",
84
+ "infoBg": "#3c3728"
85
+ }
86
+ }
@@ -0,0 +1,85 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
3
+ "name": "light",
4
+ "vars": {
5
+ "teal": "#5a8080",
6
+ "blue": "#547da7",
7
+ "green": "#588458",
8
+ "red": "#aa5555",
9
+ "yellow": "#9a7326",
10
+ "text": "#1f2328",
11
+ "mediumGray": "#6c6c6c",
12
+ "dimGray": "#767676",
13
+ "lightGray": "#b0b0b0",
14
+ "selectedBg": "#d0d0e0",
15
+ "userMsgBg": "#e8e8e8",
16
+ "toolPendingBg": "#e8e8f0",
17
+ "toolSuccessBg": "#e8f0e8",
18
+ "toolErrorBg": "#f0e8e8",
19
+ "customMsgBg": "#ede7f6"
20
+ },
21
+ "colors": {
22
+ "accent": "#7c3aed",
23
+ "border": "blue",
24
+ "borderAccent": "#7c3aed",
25
+ "borderMuted": "lightGray",
26
+ "success": "green",
27
+ "error": "red",
28
+ "warning": "yellow",
29
+ "muted": "mediumGray",
30
+ "dim": "dimGray",
31
+ "text": "text",
32
+ "thinkingText": "mediumGray",
33
+
34
+ "selectedBg": "selectedBg",
35
+ "userMessageBg": "userMsgBg",
36
+ "userMessageText": "text",
37
+ "customMessageBg": "customMsgBg",
38
+ "customMessageText": "text",
39
+ "customMessageLabel": "#7e57c2",
40
+ "toolPendingBg": "toolPendingBg",
41
+ "toolSuccessBg": "toolSuccessBg",
42
+ "toolErrorBg": "toolErrorBg",
43
+ "toolTitle": "text",
44
+ "toolOutput": "mediumGray",
45
+
46
+ "mdHeading": "yellow",
47
+ "mdLink": "blue",
48
+ "mdLinkUrl": "dimGray",
49
+ "mdCode": "teal",
50
+ "mdCodeBlock": "green",
51
+ "mdCodeBlockBorder": "mediumGray",
52
+ "mdQuote": "mediumGray",
53
+ "mdQuoteBorder": "mediumGray",
54
+ "mdHr": "mediumGray",
55
+ "mdListBullet": "green",
56
+
57
+ "toolDiffAdded": "green",
58
+ "toolDiffRemoved": "red",
59
+ "toolDiffContext": "mediumGray",
60
+
61
+ "syntaxComment": "#008000",
62
+ "syntaxKeyword": "#0000FF",
63
+ "syntaxFunction": "#795E26",
64
+ "syntaxVariable": "#001080",
65
+ "syntaxString": "#A31515",
66
+ "syntaxNumber": "#098658",
67
+ "syntaxType": "#267F99",
68
+ "syntaxOperator": "#000000",
69
+ "syntaxPunctuation": "#000000",
70
+
71
+ "thinkingOff": "lightGray",
72
+ "thinkingMinimal": "#767676",
73
+ "thinkingLow": "blue",
74
+ "thinkingMedium": "teal",
75
+ "thinkingHigh": "#875f87",
76
+ "thinkingXhigh": "#8b008b",
77
+
78
+ "bashMode": "green"
79
+ },
80
+ "export": {
81
+ "pageBg": "#f8f8f8",
82
+ "cardBg": "#ffffff",
83
+ "infoBg": "#fffae6"
84
+ }
85
+ }