leaf-coding-agent 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (598) hide show
  1. package/dist/cli/args.d.ts +55 -0
  2. package/dist/cli/args.d.ts.map +1 -0
  3. package/dist/cli/args.js +356 -0
  4. package/dist/cli/args.js.map +1 -0
  5. package/dist/cli/config-selector.d.ts +14 -0
  6. package/dist/cli/config-selector.d.ts.map +1 -0
  7. package/dist/cli/config-selector.js +31 -0
  8. package/dist/cli/config-selector.js.map +1 -0
  9. package/dist/cli/file-processor.d.ts +15 -0
  10. package/dist/cli/file-processor.d.ts.map +1 -0
  11. package/dist/cli/file-processor.js +82 -0
  12. package/dist/cli/file-processor.js.map +1 -0
  13. package/dist/cli/initial-message.d.ts +18 -0
  14. package/dist/cli/initial-message.d.ts.map +1 -0
  15. package/dist/cli/initial-message.js +22 -0
  16. package/dist/cli/initial-message.js.map +1 -0
  17. package/dist/cli/list-models.d.ts +9 -0
  18. package/dist/cli/list-models.d.ts.map +1 -0
  19. package/dist/cli/list-models.js +98 -0
  20. package/dist/cli/list-models.js.map +1 -0
  21. package/dist/cli/session-picker.d.ts +9 -0
  22. package/dist/cli/session-picker.d.ts.map +1 -0
  23. package/dist/cli/session-picker.js +35 -0
  24. package/dist/cli/session-picker.js.map +1 -0
  25. package/dist/cli.d.ts +3 -0
  26. package/dist/cli.d.ts.map +1 -0
  27. package/dist/cli.js +18 -0
  28. package/dist/cli.js.map +1 -0
  29. package/dist/config.d.ts +92 -0
  30. package/dist/config.d.ts.map +1 -0
  31. package/dist/config.js +428 -0
  32. package/dist/config.js.map +1 -0
  33. package/dist/core/agent-session-runtime.d.ts +117 -0
  34. package/dist/core/agent-session-runtime.d.ts.map +1 -0
  35. package/dist/core/agent-session-runtime.js +300 -0
  36. package/dist/core/agent-session-runtime.js.map +1 -0
  37. package/dist/core/agent-session-services.d.ts +87 -0
  38. package/dist/core/agent-session-services.d.ts.map +1 -0
  39. package/dist/core/agent-session-services.js +119 -0
  40. package/dist/core/agent-session-services.js.map +1 -0
  41. package/dist/core/agent-session.d.ts +602 -0
  42. package/dist/core/agent-session.d.ts.map +1 -0
  43. package/dist/core/agent-session.js +2523 -0
  44. package/dist/core/agent-session.js.map +1 -0
  45. package/dist/core/auth-guidance.d.ts +5 -0
  46. package/dist/core/auth-guidance.d.ts.map +1 -0
  47. package/dist/core/auth-guidance.js +21 -0
  48. package/dist/core/auth-guidance.js.map +1 -0
  49. package/dist/core/auth-storage.d.ts +141 -0
  50. package/dist/core/auth-storage.d.ts.map +1 -0
  51. package/dist/core/auth-storage.js +442 -0
  52. package/dist/core/auth-storage.js.map +1 -0
  53. package/dist/core/bash-executor.d.ts +32 -0
  54. package/dist/core/bash-executor.d.ts.map +1 -0
  55. package/dist/core/bash-executor.js +111 -0
  56. package/dist/core/bash-executor.js.map +1 -0
  57. package/dist/core/compaction/branch-summarization.d.ts +88 -0
  58. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  59. package/dist/core/compaction/branch-summarization.js +243 -0
  60. package/dist/core/compaction/branch-summarization.js.map +1 -0
  61. package/dist/core/compaction/compaction.d.ts +121 -0
  62. package/dist/core/compaction/compaction.d.ts.map +1 -0
  63. package/dist/core/compaction/compaction.js +619 -0
  64. package/dist/core/compaction/compaction.js.map +1 -0
  65. package/dist/core/compaction/index.d.ts +7 -0
  66. package/dist/core/compaction/index.d.ts.map +1 -0
  67. package/dist/core/compaction/index.js +7 -0
  68. package/dist/core/compaction/index.js.map +1 -0
  69. package/dist/core/compaction/utils.d.ts +38 -0
  70. package/dist/core/compaction/utils.d.ts.map +1 -0
  71. package/dist/core/compaction/utils.js +153 -0
  72. package/dist/core/compaction/utils.js.map +1 -0
  73. package/dist/core/defaults.d.ts +3 -0
  74. package/dist/core/defaults.d.ts.map +1 -0
  75. package/dist/core/defaults.js +2 -0
  76. package/dist/core/defaults.js.map +1 -0
  77. package/dist/core/diagnostics.d.ts +15 -0
  78. package/dist/core/diagnostics.d.ts.map +1 -0
  79. package/dist/core/diagnostics.js +2 -0
  80. package/dist/core/diagnostics.js.map +1 -0
  81. package/dist/core/event-bus.d.ts +9 -0
  82. package/dist/core/event-bus.d.ts.map +1 -0
  83. package/dist/core/event-bus.js +25 -0
  84. package/dist/core/event-bus.js.map +1 -0
  85. package/dist/core/exec.d.ts +29 -0
  86. package/dist/core/exec.d.ts.map +1 -0
  87. package/dist/core/exec.js +75 -0
  88. package/dist/core/exec.js.map +1 -0
  89. package/dist/core/export-html/ansi-to-html.d.ts +22 -0
  90. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  91. package/dist/core/export-html/ansi-to-html.js +249 -0
  92. package/dist/core/export-html/ansi-to-html.js.map +1 -0
  93. package/dist/core/export-html/index.d.ts +37 -0
  94. package/dist/core/export-html/index.d.ts.map +1 -0
  95. package/dist/core/export-html/index.js +226 -0
  96. package/dist/core/export-html/index.js.map +1 -0
  97. package/dist/core/export-html/template.css +1066 -0
  98. package/dist/core/export-html/template.html +55 -0
  99. package/dist/core/export-html/template.js +1851 -0
  100. package/dist/core/export-html/tool-renderer.d.ts +34 -0
  101. package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  102. package/dist/core/export-html/tool-renderer.js +108 -0
  103. package/dist/core/export-html/tool-renderer.js.map +1 -0
  104. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  105. package/dist/core/export-html/vendor/marked.min.js +6 -0
  106. package/dist/core/extensions/index.d.ts +12 -0
  107. package/dist/core/extensions/index.d.ts.map +1 -0
  108. package/dist/core/extensions/index.js +9 -0
  109. package/dist/core/extensions/index.js.map +1 -0
  110. package/dist/core/extensions/loader.d.ts +24 -0
  111. package/dist/core/extensions/loader.d.ts.map +1 -0
  112. package/dist/core/extensions/loader.js +481 -0
  113. package/dist/core/extensions/loader.js.map +1 -0
  114. package/dist/core/extensions/runner.d.ts +159 -0
  115. package/dist/core/extensions/runner.d.ts.map +1 -0
  116. package/dist/core/extensions/runner.js +830 -0
  117. package/dist/core/extensions/runner.js.map +1 -0
  118. package/dist/core/extensions/types.d.ts +1175 -0
  119. package/dist/core/extensions/types.d.ts.map +1 -0
  120. package/dist/core/extensions/types.js +45 -0
  121. package/dist/core/extensions/types.js.map +1 -0
  122. package/dist/core/extensions/wrapper.d.ts +20 -0
  123. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  124. package/dist/core/extensions/wrapper.js +22 -0
  125. package/dist/core/extensions/wrapper.js.map +1 -0
  126. package/dist/core/footer-data-provider.d.ts +52 -0
  127. package/dist/core/footer-data-provider.d.ts.map +1 -0
  128. package/dist/core/footer-data-provider.js +310 -0
  129. package/dist/core/footer-data-provider.js.map +1 -0
  130. package/dist/core/http-dispatcher.d.ts +21 -0
  131. package/dist/core/http-dispatcher.d.ts.map +1 -0
  132. package/dist/core/http-dispatcher.js +48 -0
  133. package/dist/core/http-dispatcher.js.map +1 -0
  134. package/dist/core/index.d.ts +12 -0
  135. package/dist/core/index.d.ts.map +1 -0
  136. package/dist/core/index.js +12 -0
  137. package/dist/core/index.js.map +1 -0
  138. package/dist/core/keybindings.d.ts +353 -0
  139. package/dist/core/keybindings.d.ts.map +1 -0
  140. package/dist/core/keybindings.js +295 -0
  141. package/dist/core/keybindings.js.map +1 -0
  142. package/dist/core/messages.d.ts +77 -0
  143. package/dist/core/messages.d.ts.map +1 -0
  144. package/dist/core/messages.js +123 -0
  145. package/dist/core/messages.js.map +1 -0
  146. package/dist/core/model-registry.d.ts +150 -0
  147. package/dist/core/model-registry.d.ts.map +1 -0
  148. package/dist/core/model-registry.js +784 -0
  149. package/dist/core/model-registry.js.map +1 -0
  150. package/dist/core/model-resolver.d.ts +110 -0
  151. package/dist/core/model-resolver.d.ts.map +1 -0
  152. package/dist/core/model-resolver.js +495 -0
  153. package/dist/core/model-resolver.js.map +1 -0
  154. package/dist/core/output-guard.d.ts +7 -0
  155. package/dist/core/output-guard.d.ts.map +1 -0
  156. package/dist/core/output-guard.js +89 -0
  157. package/dist/core/output-guard.js.map +1 -0
  158. package/dist/core/package-manager.d.ts +204 -0
  159. package/dist/core/package-manager.d.ts.map +1 -0
  160. package/dist/core/package-manager.js +2040 -0
  161. package/dist/core/package-manager.js.map +1 -0
  162. package/dist/core/prompt-templates.d.ts +52 -0
  163. package/dist/core/prompt-templates.d.ts.map +1 -0
  164. package/dist/core/prompt-templates.js +238 -0
  165. package/dist/core/prompt-templates.js.map +1 -0
  166. package/dist/core/provider-display-names.d.ts +2 -0
  167. package/dist/core/provider-display-names.d.ts.map +1 -0
  168. package/dist/core/provider-display-names.js +33 -0
  169. package/dist/core/provider-display-names.js.map +1 -0
  170. package/dist/core/resolve-config-value.d.ts +31 -0
  171. package/dist/core/resolve-config-value.d.ts.map +1 -0
  172. package/dist/core/resolve-config-value.js +249 -0
  173. package/dist/core/resolve-config-value.js.map +1 -0
  174. package/dist/core/resource-loader.d.ts +194 -0
  175. package/dist/core/resource-loader.d.ts.map +1 -0
  176. package/dist/core/resource-loader.js +734 -0
  177. package/dist/core/resource-loader.js.map +1 -0
  178. package/dist/core/sdk.d.ts +109 -0
  179. package/dist/core/sdk.d.ts.map +1 -0
  180. package/dist/core/sdk.js +291 -0
  181. package/dist/core/sdk.js.map +1 -0
  182. package/dist/core/session-cwd.d.ts +19 -0
  183. package/dist/core/session-cwd.d.ts.map +1 -0
  184. package/dist/core/session-cwd.js +38 -0
  185. package/dist/core/session-cwd.js.map +1 -0
  186. package/dist/core/session-manager.d.ts +332 -0
  187. package/dist/core/session-manager.d.ts.map +1 -0
  188. package/dist/core/session-manager.js +1194 -0
  189. package/dist/core/session-manager.js.map +1 -0
  190. package/dist/core/settings-manager.d.ts +266 -0
  191. package/dist/core/settings-manager.d.ts.map +1 -0
  192. package/dist/core/settings-manager.js +800 -0
  193. package/dist/core/settings-manager.js.map +1 -0
  194. package/dist/core/skills.d.ts +60 -0
  195. package/dist/core/skills.d.ts.map +1 -0
  196. package/dist/core/skills.js +387 -0
  197. package/dist/core/skills.js.map +1 -0
  198. package/dist/core/slash-commands.d.ts +14 -0
  199. package/dist/core/slash-commands.d.ts.map +1 -0
  200. package/dist/core/slash-commands.js +25 -0
  201. package/dist/core/slash-commands.js.map +1 -0
  202. package/dist/core/source-info.d.ts +18 -0
  203. package/dist/core/source-info.d.ts.map +1 -0
  204. package/dist/core/source-info.js +19 -0
  205. package/dist/core/source-info.js.map +1 -0
  206. package/dist/core/system-prompt.d.ts +30 -0
  207. package/dist/core/system-prompt.d.ts.map +1 -0
  208. package/dist/core/system-prompt.js +117 -0
  209. package/dist/core/system-prompt.js.map +1 -0
  210. package/dist/core/telemetry.d.ts +3 -0
  211. package/dist/core/telemetry.d.ts.map +1 -0
  212. package/dist/core/telemetry.js +9 -0
  213. package/dist/core/telemetry.js.map +1 -0
  214. package/dist/core/timings.d.ts +8 -0
  215. package/dist/core/timings.d.ts.map +1 -0
  216. package/dist/core/timings.js +31 -0
  217. package/dist/core/timings.js.map +1 -0
  218. package/dist/core/tools/bash.d.ts +68 -0
  219. package/dist/core/tools/bash.d.ts.map +1 -0
  220. package/dist/core/tools/bash.js +337 -0
  221. package/dist/core/tools/bash.js.map +1 -0
  222. package/dist/core/tools/edit-diff.d.ts +87 -0
  223. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  224. package/dist/core/tools/edit-diff.js +345 -0
  225. package/dist/core/tools/edit-diff.js.map +1 -0
  226. package/dist/core/tools/edit.d.ts +51 -0
  227. package/dist/core/tools/edit.d.ts.map +1 -0
  228. package/dist/core/tools/edit.js +287 -0
  229. package/dist/core/tools/edit.js.map +1 -0
  230. package/dist/core/tools/file-mutation-queue.d.ts +6 -0
  231. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
  232. package/dist/core/tools/file-mutation-queue.js +52 -0
  233. package/dist/core/tools/file-mutation-queue.js.map +1 -0
  234. package/dist/core/tools/find.d.ts +35 -0
  235. package/dist/core/tools/find.d.ts.map +1 -0
  236. package/dist/core/tools/find.js +297 -0
  237. package/dist/core/tools/find.js.map +1 -0
  238. package/dist/core/tools/grep.d.ts +37 -0
  239. package/dist/core/tools/grep.d.ts.map +1 -0
  240. package/dist/core/tools/grep.js +304 -0
  241. package/dist/core/tools/grep.js.map +1 -0
  242. package/dist/core/tools/index.d.ts +40 -0
  243. package/dist/core/tools/index.d.ts.map +1 -0
  244. package/dist/core/tools/index.js +112 -0
  245. package/dist/core/tools/index.js.map +1 -0
  246. package/dist/core/tools/ls.d.ts +37 -0
  247. package/dist/core/tools/ls.d.ts.map +1 -0
  248. package/dist/core/tools/ls.js +169 -0
  249. package/dist/core/tools/ls.js.map +1 -0
  250. package/dist/core/tools/output-accumulator.d.ts +52 -0
  251. package/dist/core/tools/output-accumulator.d.ts.map +1 -0
  252. package/dist/core/tools/output-accumulator.js +184 -0
  253. package/dist/core/tools/output-accumulator.js.map +1 -0
  254. package/dist/core/tools/path-utils.d.ts +10 -0
  255. package/dist/core/tools/path-utils.d.ts.map +1 -0
  256. package/dist/core/tools/path-utils.js +99 -0
  257. package/dist/core/tools/path-utils.js.map +1 -0
  258. package/dist/core/tools/read.d.ts +35 -0
  259. package/dist/core/tools/read.d.ts.map +1 -0
  260. package/dist/core/tools/read.js +290 -0
  261. package/dist/core/tools/read.js.map +1 -0
  262. package/dist/core/tools/render-utils.d.ts +21 -0
  263. package/dist/core/tools/render-utils.d.ts.map +1 -0
  264. package/dist/core/tools/render-utils.js +49 -0
  265. package/dist/core/tools/render-utils.js.map +1 -0
  266. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  267. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
  268. package/dist/core/tools/tool-definition-wrapper.js +34 -0
  269. package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
  270. package/dist/core/tools/truncate.d.ts +70 -0
  271. package/dist/core/tools/truncate.d.ts.map +1 -0
  272. package/dist/core/tools/truncate.js +215 -0
  273. package/dist/core/tools/truncate.js.map +1 -0
  274. package/dist/core/tools/worker.d.ts +23 -0
  275. package/dist/core/tools/worker.d.ts.map +1 -0
  276. package/dist/core/tools/worker.js +150 -0
  277. package/dist/core/tools/worker.js.map +1 -0
  278. package/dist/core/tools/write.d.ts +26 -0
  279. package/dist/core/tools/write.d.ts.map +1 -0
  280. package/dist/core/tools/write.js +198 -0
  281. package/dist/core/tools/write.js.map +1 -0
  282. package/dist/core/worker-integration.d.ts +79 -0
  283. package/dist/core/worker-integration.d.ts.map +1 -0
  284. package/dist/core/worker-integration.js +108 -0
  285. package/dist/core/worker-integration.js.map +1 -0
  286. package/dist/index.d.ts +29 -0
  287. package/dist/index.d.ts.map +1 -0
  288. package/dist/index.js +42 -0
  289. package/dist/index.js.map +1 -0
  290. package/dist/main.d.ts +12 -0
  291. package/dist/main.d.ts.map +1 -0
  292. package/dist/main.js +623 -0
  293. package/dist/main.js.map +1 -0
  294. package/dist/migrations.d.ts +33 -0
  295. package/dist/migrations.d.ts.map +1 -0
  296. package/dist/migrations.js +398 -0
  297. package/dist/migrations.js.map +1 -0
  298. package/dist/modes/index.d.ts +9 -0
  299. package/dist/modes/index.d.ts.map +1 -0
  300. package/dist/modes/index.js +8 -0
  301. package/dist/modes/index.js.map +1 -0
  302. package/dist/modes/interactive/assets/clankolas.png +0 -0
  303. package/dist/modes/interactive/components/armin.d.ts +34 -0
  304. package/dist/modes/interactive/components/armin.d.ts.map +1 -0
  305. package/dist/modes/interactive/components/armin.js +333 -0
  306. package/dist/modes/interactive/components/armin.js.map +1 -0
  307. package/dist/modes/interactive/components/assistant-message.d.ts +20 -0
  308. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  309. package/dist/modes/interactive/components/assistant-message.js +121 -0
  310. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  311. package/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  312. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  313. package/dist/modes/interactive/components/bash-execution.js +175 -0
  314. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  315. package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  316. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  317. package/dist/modes/interactive/components/bordered-loader.js +54 -0
  318. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  319. package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  320. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  321. package/dist/modes/interactive/components/branch-summary-message.js +44 -0
  322. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  323. package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  324. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  325. package/dist/modes/interactive/components/compaction-summary-message.js +45 -0
  326. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  327. package/dist/modes/interactive/components/config-selector.d.ts +71 -0
  328. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  329. package/dist/modes/interactive/components/config-selector.js +506 -0
  330. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  331. package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  332. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  333. package/dist/modes/interactive/components/countdown-timer.js +33 -0
  334. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  335. package/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  336. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  337. package/dist/modes/interactive/components/custom-editor.js +70 -0
  338. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  339. package/dist/modes/interactive/components/custom-message.d.ts +20 -0
  340. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  341. package/dist/modes/interactive/components/custom-message.js +79 -0
  342. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  343. package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  344. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  345. package/dist/modes/interactive/components/daxnuts.js +140 -0
  346. package/dist/modes/interactive/components/daxnuts.js.map +1 -0
  347. package/dist/modes/interactive/components/diff.d.ts +12 -0
  348. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  349. package/dist/modes/interactive/components/diff.js +133 -0
  350. package/dist/modes/interactive/components/diff.js.map +1 -0
  351. package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  352. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  353. package/dist/modes/interactive/components/dynamic-border.js +21 -0
  354. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  355. package/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  356. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -0
  357. package/dist/modes/interactive/components/earendil-announcement.js +40 -0
  358. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -0
  359. package/dist/modes/interactive/components/extension-editor.d.ts +20 -0
  360. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  361. package/dist/modes/interactive/components/extension-editor.js +119 -0
  362. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  363. package/dist/modes/interactive/components/extension-input.d.ts +23 -0
  364. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  365. package/dist/modes/interactive/components/extension-input.js +61 -0
  366. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  367. package/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  368. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  369. package/dist/modes/interactive/components/extension-selector.js +83 -0
  370. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  371. package/dist/modes/interactive/components/footer.d.ts +28 -0
  372. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  373. package/dist/modes/interactive/components/footer.js +210 -0
  374. package/dist/modes/interactive/components/footer.js.map +1 -0
  375. package/dist/modes/interactive/components/index.d.ts +32 -0
  376. package/dist/modes/interactive/components/index.d.ts.map +1 -0
  377. package/dist/modes/interactive/components/index.js +33 -0
  378. package/dist/modes/interactive/components/index.js.map +1 -0
  379. package/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  380. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  381. package/dist/modes/interactive/components/keybinding-hints.js +36 -0
  382. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  383. package/dist/modes/interactive/components/login-dialog.d.ts +52 -0
  384. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  385. package/dist/modes/interactive/components/login-dialog.js +183 -0
  386. package/dist/modes/interactive/components/login-dialog.js.map +1 -0
  387. package/dist/modes/interactive/components/model-selector.d.ts +47 -0
  388. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  389. package/dist/modes/interactive/components/model-selector.js +278 -0
  390. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  391. package/dist/modes/interactive/components/oauth-selector.d.ts +31 -0
  392. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  393. package/dist/modes/interactive/components/oauth-selector.js +165 -0
  394. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  395. package/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
  396. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  397. package/dist/modes/interactive/components/scoped-models-selector.js +290 -0
  398. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  399. package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  400. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  401. package/dist/modes/interactive/components/session-selector-search.js +155 -0
  402. package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  403. package/dist/modes/interactive/components/session-selector.d.ts +96 -0
  404. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  405. package/dist/modes/interactive/components/session-selector.js +861 -0
  406. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  407. package/dist/modes/interactive/components/settings-selector.d.ts +69 -0
  408. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  409. package/dist/modes/interactive/components/settings-selector.js +390 -0
  410. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  411. package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  412. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  413. package/dist/modes/interactive/components/show-images-selector.js +39 -0
  414. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  415. package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  416. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  417. package/dist/modes/interactive/components/skill-invocation-message.js +47 -0
  418. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  419. package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  420. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  421. package/dist/modes/interactive/components/theme-selector.js +50 -0
  422. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  423. package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  424. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  425. package/dist/modes/interactive/components/thinking-selector.js +51 -0
  426. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  427. package/dist/modes/interactive/components/tool-execution.d.ts +63 -0
  428. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  429. package/dist/modes/interactive/components/tool-execution.js +295 -0
  430. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  431. package/dist/modes/interactive/components/tree-selector.d.ts +89 -0
  432. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  433. package/dist/modes/interactive/components/tree-selector.js +1093 -0
  434. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  435. package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  436. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  437. package/dist/modes/interactive/components/user-message-selector.js +114 -0
  438. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  439. package/dist/modes/interactive/components/user-message.d.ts +10 -0
  440. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  441. package/dist/modes/interactive/components/user-message.js +29 -0
  442. package/dist/modes/interactive/components/user-message.js.map +1 -0
  443. package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  444. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  445. package/dist/modes/interactive/components/visual-truncate.js +33 -0
  446. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  447. package/dist/modes/interactive/components/worker-status.d.ts +23 -0
  448. package/dist/modes/interactive/components/worker-status.d.ts.map +1 -0
  449. package/dist/modes/interactive/components/worker-status.js +77 -0
  450. package/dist/modes/interactive/components/worker-status.js.map +1 -0
  451. package/dist/modes/interactive/interactive-mode.d.ts +370 -0
  452. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  453. package/dist/modes/interactive/interactive-mode.js +4674 -0
  454. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  455. package/dist/modes/interactive/theme/dark.json +86 -0
  456. package/dist/modes/interactive/theme/light.json +85 -0
  457. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  458. package/dist/modes/interactive/theme/theme.d.ts +100 -0
  459. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  460. package/dist/modes/interactive/theme/theme.js +1034 -0
  461. package/dist/modes/interactive/theme/theme.js.map +1 -0
  462. package/dist/modes/interactive/worker-ui-integration.d.ts +102 -0
  463. package/dist/modes/interactive/worker-ui-integration.d.ts.map +1 -0
  464. package/dist/modes/interactive/worker-ui-integration.js +147 -0
  465. package/dist/modes/interactive/worker-ui-integration.js.map +1 -0
  466. package/dist/modes/print-mode.d.ts +28 -0
  467. package/dist/modes/print-mode.d.ts.map +1 -0
  468. package/dist/modes/print-mode.js +131 -0
  469. package/dist/modes/print-mode.js.map +1 -0
  470. package/dist/modes/rpc/jsonl.d.ts +17 -0
  471. package/dist/modes/rpc/jsonl.d.ts.map +1 -0
  472. package/dist/modes/rpc/jsonl.js +49 -0
  473. package/dist/modes/rpc/jsonl.js.map +1 -0
  474. package/dist/modes/rpc/rpc-client.d.ts +227 -0
  475. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  476. package/dist/modes/rpc/rpc-client.js +467 -0
  477. package/dist/modes/rpc/rpc-client.js.map +1 -0
  478. package/dist/modes/rpc/rpc-mode.d.ts +20 -0
  479. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  480. package/dist/modes/rpc/rpc-mode.js +615 -0
  481. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  482. package/dist/modes/rpc/rpc-types.d.ts +420 -0
  483. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  484. package/dist/modes/rpc/rpc-types.js +8 -0
  485. package/dist/modes/rpc/rpc-types.js.map +1 -0
  486. package/dist/package-manager-cli.d.ts +4 -0
  487. package/dist/package-manager-cli.d.ts.map +1 -0
  488. package/dist/package-manager-cli.js +515 -0
  489. package/dist/package-manager-cli.js.map +1 -0
  490. package/dist/utils/ansi.d.ts +2 -0
  491. package/dist/utils/ansi.d.ts.map +1 -0
  492. package/dist/utils/ansi.js +52 -0
  493. package/dist/utils/ansi.js.map +1 -0
  494. package/dist/utils/changelog.d.ts +21 -0
  495. package/dist/utils/changelog.d.ts.map +1 -0
  496. package/dist/utils/changelog.js +87 -0
  497. package/dist/utils/changelog.js.map +1 -0
  498. package/dist/utils/child-process.d.ts +15 -0
  499. package/dist/utils/child-process.d.ts.map +1 -0
  500. package/dist/utils/child-process.js +88 -0
  501. package/dist/utils/child-process.js.map +1 -0
  502. package/dist/utils/clipboard-image.d.ts +11 -0
  503. package/dist/utils/clipboard-image.d.ts.map +1 -0
  504. package/dist/utils/clipboard-image.js +245 -0
  505. package/dist/utils/clipboard-image.js.map +1 -0
  506. package/dist/utils/clipboard-native.d.ts +10 -0
  507. package/dist/utils/clipboard-native.d.ts.map +1 -0
  508. package/dist/utils/clipboard-native.js +20 -0
  509. package/dist/utils/clipboard-native.js.map +1 -0
  510. package/dist/utils/clipboard.d.ts +2 -0
  511. package/dist/utils/clipboard.d.ts.map +1 -0
  512. package/dist/utils/clipboard.js +117 -0
  513. package/dist/utils/clipboard.js.map +1 -0
  514. package/dist/utils/deprecation.d.ts +4 -0
  515. package/dist/utils/deprecation.d.ts.map +1 -0
  516. package/dist/utils/deprecation.js +13 -0
  517. package/dist/utils/deprecation.js.map +1 -0
  518. package/dist/utils/exif-orientation.d.ts +5 -0
  519. package/dist/utils/exif-orientation.d.ts.map +1 -0
  520. package/dist/utils/exif-orientation.js +158 -0
  521. package/dist/utils/exif-orientation.js.map +1 -0
  522. package/dist/utils/frontmatter.d.ts +8 -0
  523. package/dist/utils/frontmatter.d.ts.map +1 -0
  524. package/dist/utils/frontmatter.js +26 -0
  525. package/dist/utils/frontmatter.js.map +1 -0
  526. package/dist/utils/fs-watch.d.ts +5 -0
  527. package/dist/utils/fs-watch.d.ts.map +1 -0
  528. package/dist/utils/fs-watch.js +25 -0
  529. package/dist/utils/fs-watch.js.map +1 -0
  530. package/dist/utils/git.d.ts +26 -0
  531. package/dist/utils/git.d.ts.map +1 -0
  532. package/dist/utils/git.js +163 -0
  533. package/dist/utils/git.js.map +1 -0
  534. package/dist/utils/html.d.ts +7 -0
  535. package/dist/utils/html.d.ts.map +1 -0
  536. package/dist/utils/html.js +40 -0
  537. package/dist/utils/html.js.map +1 -0
  538. package/dist/utils/image-convert.d.ts +9 -0
  539. package/dist/utils/image-convert.d.ts.map +1 -0
  540. package/dist/utils/image-convert.js +39 -0
  541. package/dist/utils/image-convert.js.map +1 -0
  542. package/dist/utils/image-resize-core.d.ts +30 -0
  543. package/dist/utils/image-resize-core.d.ts.map +1 -0
  544. package/dist/utils/image-resize-core.js +124 -0
  545. package/dist/utils/image-resize-core.js.map +1 -0
  546. package/dist/utils/image-resize-worker.d.ts +2 -0
  547. package/dist/utils/image-resize-worker.d.ts.map +1 -0
  548. package/dist/utils/image-resize-worker.js +31 -0
  549. package/dist/utils/image-resize-worker.js.map +1 -0
  550. package/dist/utils/image-resize.d.ts +16 -0
  551. package/dist/utils/image-resize.d.ts.map +1 -0
  552. package/dist/utils/image-resize.js +97 -0
  553. package/dist/utils/image-resize.js.map +1 -0
  554. package/dist/utils/json.d.ts +3 -0
  555. package/dist/utils/json.d.ts.map +1 -0
  556. package/dist/utils/json.js +7 -0
  557. package/dist/utils/json.js.map +1 -0
  558. package/dist/utils/leaf-user-agent.d.ts +2 -0
  559. package/dist/utils/leaf-user-agent.d.ts.map +1 -0
  560. package/dist/utils/leaf-user-agent.js +5 -0
  561. package/dist/utils/leaf-user-agent.js.map +1 -0
  562. package/dist/utils/mime.d.ts +3 -0
  563. package/dist/utils/mime.d.ts.map +1 -0
  564. package/dist/utils/mime.js +69 -0
  565. package/dist/utils/mime.js.map +1 -0
  566. package/dist/utils/paths.d.ts +31 -0
  567. package/dist/utils/paths.d.ts.map +1 -0
  568. package/dist/utils/paths.js +92 -0
  569. package/dist/utils/paths.js.map +1 -0
  570. package/dist/utils/photon.d.ts +21 -0
  571. package/dist/utils/photon.d.ts.map +1 -0
  572. package/dist/utils/photon.js +121 -0
  573. package/dist/utils/photon.js.map +1 -0
  574. package/dist/utils/shell.d.ts +30 -0
  575. package/dist/utils/shell.d.ts.map +1 -0
  576. package/dist/utils/shell.js +195 -0
  577. package/dist/utils/shell.js.map +1 -0
  578. package/dist/utils/sleep.d.ts +5 -0
  579. package/dist/utils/sleep.d.ts.map +1 -0
  580. package/dist/utils/sleep.js +17 -0
  581. package/dist/utils/sleep.js.map +1 -0
  582. package/dist/utils/syntax-highlight.d.ts +12 -0
  583. package/dist/utils/syntax-highlight.d.ts.map +1 -0
  584. package/dist/utils/syntax-highlight.js +118 -0
  585. package/dist/utils/syntax-highlight.js.map +1 -0
  586. package/dist/utils/tools-manager.d.ts +3 -0
  587. package/dist/utils/tools-manager.d.ts.map +1 -0
  588. package/dist/utils/tools-manager.js +328 -0
  589. package/dist/utils/tools-manager.js.map +1 -0
  590. package/dist/utils/version-check.d.ts +15 -0
  591. package/dist/utils/version-check.d.ts.map +1 -0
  592. package/dist/utils/version-check.js +82 -0
  593. package/dist/utils/version-check.js.map +1 -0
  594. package/dist/utils/windows-self-update.d.ts +3 -0
  595. package/dist/utils/windows-self-update.d.ts.map +1 -0
  596. package/dist/utils/windows-self-update.js +77 -0
  597. package/dist/utils/windows-self-update.js.map +1 -0
  598. package/package.json +100 -0
@@ -0,0 +1,121 @@
1
+ import { Container, Markdown, Spacer, Text } from "@looze/leaf-tui";
2
+ import { getMarkdownTheme, theme } from "../theme/theme.js";
3
+ const OSC133_ZONE_START = "\x1b]133;A\x07";
4
+ const OSC133_ZONE_END = "\x1b]133;B\x07";
5
+ const OSC133_ZONE_FINAL = "\x1b]133;C\x07";
6
+ /**
7
+ * Component that renders a complete assistant message
8
+ */
9
+ export class AssistantMessageComponent extends Container {
10
+ contentContainer;
11
+ hideThinkingBlock;
12
+ markdownTheme;
13
+ hiddenThinkingLabel;
14
+ lastMessage;
15
+ hasToolCalls = false;
16
+ constructor(message, hideThinkingBlock = false, markdownTheme = getMarkdownTheme(), hiddenThinkingLabel = "Thinking...") {
17
+ super();
18
+ this.hideThinkingBlock = hideThinkingBlock;
19
+ this.markdownTheme = markdownTheme;
20
+ this.hiddenThinkingLabel = hiddenThinkingLabel;
21
+ // Container for text/thinking content
22
+ this.contentContainer = new Container();
23
+ this.addChild(this.contentContainer);
24
+ if (message) {
25
+ this.updateContent(message);
26
+ }
27
+ }
28
+ invalidate() {
29
+ super.invalidate();
30
+ if (this.lastMessage) {
31
+ this.updateContent(this.lastMessage);
32
+ }
33
+ }
34
+ setHideThinkingBlock(hide) {
35
+ this.hideThinkingBlock = hide;
36
+ if (this.lastMessage) {
37
+ this.updateContent(this.lastMessage);
38
+ }
39
+ }
40
+ setHiddenThinkingLabel(label) {
41
+ this.hiddenThinkingLabel = label;
42
+ if (this.lastMessage) {
43
+ this.updateContent(this.lastMessage);
44
+ }
45
+ }
46
+ render(width) {
47
+ const lines = super.render(width);
48
+ if (this.hasToolCalls || lines.length === 0) {
49
+ return lines;
50
+ }
51
+ lines[0] = OSC133_ZONE_START + lines[0];
52
+ lines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1];
53
+ return lines;
54
+ }
55
+ updateContent(message) {
56
+ this.lastMessage = message;
57
+ // Clear content container
58
+ this.contentContainer.clear();
59
+ const hasVisibleContent = message.content.some((c) => (c.type === "text" && c.text.trim()) || (c.type === "thinking" && c.thinking.trim()));
60
+ if (hasVisibleContent) {
61
+ this.contentContainer.addChild(new Spacer(1));
62
+ }
63
+ // Render content in order
64
+ for (let i = 0; i < message.content.length; i++) {
65
+ const content = message.content[i];
66
+ if (content.type === "text" && content.text.trim()) {
67
+ // Assistant text messages with no background - trim the text
68
+ // Set paddingY=0 to avoid extra spacing before tool executions
69
+ this.contentContainer.addChild(new Markdown(content.text.trim(), 1, 0, this.markdownTheme));
70
+ }
71
+ else if (content.type === "thinking" && content.thinking.trim()) {
72
+ // Add spacing only when another visible assistant content block follows.
73
+ // This avoids a superfluous blank line before separately-rendered tool execution blocks.
74
+ const hasVisibleContentAfter = message.content
75
+ .slice(i + 1)
76
+ .some((c) => (c.type === "text" && c.text.trim()) || (c.type === "thinking" && c.thinking.trim()));
77
+ if (this.hideThinkingBlock) {
78
+ // Show static thinking label when hidden
79
+ this.contentContainer.addChild(new Text(theme.italic(theme.fg("thinkingText", this.hiddenThinkingLabel)), 1, 0));
80
+ if (hasVisibleContentAfter) {
81
+ this.contentContainer.addChild(new Spacer(1));
82
+ }
83
+ }
84
+ else {
85
+ // Thinking traces in thinkingText color, italic
86
+ this.contentContainer.addChild(new Markdown(content.thinking.trim(), 1, 0, this.markdownTheme, {
87
+ color: (text) => theme.fg("thinkingText", text),
88
+ italic: true,
89
+ }));
90
+ if (hasVisibleContentAfter) {
91
+ this.contentContainer.addChild(new Spacer(1));
92
+ }
93
+ }
94
+ }
95
+ }
96
+ // Check if aborted - show after partial content
97
+ // But only if there are no tool calls (tool execution components will show the error)
98
+ const hasToolCalls = message.content.some((c) => c.type === "toolCall");
99
+ this.hasToolCalls = hasToolCalls;
100
+ if (!hasToolCalls) {
101
+ if (message.stopReason === "aborted") {
102
+ const abortMessage = message.errorMessage && message.errorMessage !== "Request was aborted"
103
+ ? message.errorMessage
104
+ : "Operation aborted";
105
+ if (hasVisibleContent) {
106
+ this.contentContainer.addChild(new Spacer(1));
107
+ }
108
+ else {
109
+ this.contentContainer.addChild(new Spacer(1));
110
+ }
111
+ this.contentContainer.addChild(new Text(theme.fg("error", abortMessage), 1, 0));
112
+ }
113
+ else if (message.stopReason === "error") {
114
+ const errorMsg = message.errorMessage || "Unknown error";
115
+ this.contentContainer.addChild(new Spacer(1));
116
+ this.contentContainer.addChild(new Text(theme.fg("error", `Error: ${errorMsg}`), 1, 0));
117
+ }
118
+ }
119
+ }
120
+ }
121
+ //# sourceMappingURL=assistant-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistant-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/assistant-message.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"@looze/leaf-ai\";\nimport { Container, Markdown, type MarkdownTheme, Spacer, Text } from \"@looze/leaf-tui\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\n\nconst OSC133_ZONE_START = \"\\x1b]133;A\\x07\";\nconst OSC133_ZONE_END = \"\\x1b]133;B\\x07\";\nconst OSC133_ZONE_FINAL = \"\\x1b]133;C\\x07\";\n\n/**\n * Component that renders a complete assistant message\n */\nexport class AssistantMessageComponent extends Container {\n\tprivate contentContainer: Container;\n\tprivate hideThinkingBlock: boolean;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate hiddenThinkingLabel: string;\n\tprivate lastMessage?: AssistantMessage;\n\tprivate hasToolCalls = false;\n\n\tconstructor(\n\t\tmessage?: AssistantMessage,\n\t\thideThinkingBlock = false,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\thiddenThinkingLabel = \"Thinking...\",\n\t) {\n\t\tsuper();\n\n\t\tthis.hideThinkingBlock = hideThinkingBlock;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.hiddenThinkingLabel = hiddenThinkingLabel;\n\n\t\t// Container for text/thinking content\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\tif (message) {\n\t\t\tthis.updateContent(message);\n\t\t}\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage);\n\t\t}\n\t}\n\n\tsetHideThinkingBlock(hide: boolean): void {\n\t\tthis.hideThinkingBlock = hide;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage);\n\t\t}\n\t}\n\n\tsetHiddenThinkingLabel(label: string): void {\n\t\tthis.hiddenThinkingLabel = label;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage);\n\t\t}\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst lines = super.render(width);\n\t\tif (this.hasToolCalls || lines.length === 0) {\n\t\t\treturn lines;\n\t\t}\n\n\t\tlines[0] = OSC133_ZONE_START + lines[0];\n\t\tlines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1];\n\t\treturn lines;\n\t}\n\n\tupdateContent(message: AssistantMessage): void {\n\t\tthis.lastMessage = message;\n\n\t\t// Clear content container\n\t\tthis.contentContainer.clear();\n\n\t\tconst hasVisibleContent = message.content.some(\n\t\t\t(c) => (c.type === \"text\" && c.text.trim()) || (c.type === \"thinking\" && c.thinking.trim()),\n\t\t);\n\n\t\tif (hasVisibleContent) {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t}\n\n\t\t// Render content in order\n\t\tfor (let i = 0; i < message.content.length; i++) {\n\t\t\tconst content = message.content[i];\n\t\t\tif (content.type === \"text\" && content.text.trim()) {\n\t\t\t\t// Assistant text messages with no background - trim the text\n\t\t\t\t// Set paddingY=0 to avoid extra spacing before tool executions\n\t\t\t\tthis.contentContainer.addChild(new Markdown(content.text.trim(), 1, 0, this.markdownTheme));\n\t\t\t} else if (content.type === \"thinking\" && content.thinking.trim()) {\n\t\t\t\t// Add spacing only when another visible assistant content block follows.\n\t\t\t\t// This avoids a superfluous blank line before separately-rendered tool execution blocks.\n\t\t\t\tconst hasVisibleContentAfter = message.content\n\t\t\t\t\t.slice(i + 1)\n\t\t\t\t\t.some((c) => (c.type === \"text\" && c.text.trim()) || (c.type === \"thinking\" && c.thinking.trim()));\n\n\t\t\t\tif (this.hideThinkingBlock) {\n\t\t\t\t\t// Show static thinking label when hidden\n\t\t\t\t\tthis.contentContainer.addChild(\n\t\t\t\t\t\tnew Text(theme.italic(theme.fg(\"thinkingText\", this.hiddenThinkingLabel)), 1, 0),\n\t\t\t\t\t);\n\t\t\t\t\tif (hasVisibleContentAfter) {\n\t\t\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Thinking traces in thinkingText color, italic\n\t\t\t\t\tthis.contentContainer.addChild(\n\t\t\t\t\t\tnew Markdown(content.thinking.trim(), 1, 0, this.markdownTheme, {\n\t\t\t\t\t\t\tcolor: (text: string) => theme.fg(\"thinkingText\", text),\n\t\t\t\t\t\t\titalic: true,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\tif (hasVisibleContentAfter) {\n\t\t\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Check if aborted - show after partial content\n\t\t// But only if there are no tool calls (tool execution components will show the error)\n\t\tconst hasToolCalls = message.content.some((c) => c.type === \"toolCall\");\n\t\tthis.hasToolCalls = hasToolCalls;\n\t\tif (!hasToolCalls) {\n\t\t\tif (message.stopReason === \"aborted\") {\n\t\t\t\tconst abortMessage =\n\t\t\t\t\tmessage.errorMessage && message.errorMessage !== \"Request was aborted\"\n\t\t\t\t\t\t? message.errorMessage\n\t\t\t\t\t\t: \"Operation aborted\";\n\t\t\t\tif (hasVisibleContent) {\n\t\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\t} else {\n\t\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\t}\n\t\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"error\", abortMessage), 1, 0));\n\t\t\t} else if (message.stopReason === \"error\") {\n\t\t\t\tconst errorMsg = message.errorMessage || \"Unknown error\";\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"error\", `Error: ${errorMsg}`), 1, 0));\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Component for displaying bash command execution with streaming output.
3
+ */
4
+ import { Container, type TUI } from "@looze/leaf-tui";
5
+ import { type TruncationResult } from "../../../core/tools/truncate.ts";
6
+ export declare class BashExecutionComponent extends Container {
7
+ private command;
8
+ private outputLines;
9
+ private status;
10
+ private exitCode;
11
+ private loader;
12
+ private truncationResult?;
13
+ private fullOutputPath?;
14
+ private expanded;
15
+ private contentContainer;
16
+ constructor(command: string, ui: TUI, excludeFromContext?: boolean);
17
+ /**
18
+ * Set whether the output is expanded (shows full output) or collapsed (preview only).
19
+ */
20
+ setExpanded(expanded: boolean): void;
21
+ invalidate(): void;
22
+ appendOutput(chunk: string): void;
23
+ setComplete(exitCode: number | undefined, cancelled: boolean, truncationResult?: TruncationResult, fullOutputPath?: string): void;
24
+ private updateDisplay;
25
+ /**
26
+ * Get the raw output for creating BashExecutionMessage.
27
+ */
28
+ getOutput(): string;
29
+ /**
30
+ * Get the command that was executed.
31
+ */
32
+ getCommand(): string;
33
+ }
34
+ //# sourceMappingURL=bash-execution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash-execution.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/bash-execution.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAwB,KAAK,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAGN,KAAK,gBAAgB,EAErB,MAAM,iCAAiC,CAAC;AAUzC,qBAAa,sBAAuB,SAAQ,SAAS;IACpD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,MAAM,CAA6D;IAC3E,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAC5C,OAAO,CAAC,cAAc,CAAC,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,gBAAgB,CAAY;IAEpC,YAAY,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,kBAAkB,UAAQ,EAiC/D;IAED;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAGnC;IAEQ,UAAU,IAAI,IAAI,CAG1B;IAED,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAgBhC;IAED,WAAW,CACV,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,SAAS,EAAE,OAAO,EAClB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,cAAc,CAAC,EAAE,MAAM,GACrB,IAAI,CAcN;IAED,OAAO,CAAC,aAAa;IAsFrB;;OAEG;IACH,SAAS,IAAI,MAAM,CAElB;IAED;;OAEG;IACH,UAAU,IAAI,MAAM,CAEnB;CACD","sourcesContent":["/**\n * Component for displaying bash command execution with streaming output.\n */\n\nimport { Container, Loader, Spacer, Text, type TUI } from \"@looze/leaf-tui\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\ttype TruncationResult,\n\ttruncateTail,\n} from \"../../../core/tools/truncate.ts\";\nimport { stripAnsi } from \"../../../utils/ansi.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint, keyText } from \"./keybinding-hints.ts\";\nimport { truncateToVisualLines } from \"./visual-truncate.ts\";\n\n// Preview line limit when not expanded (matches tool execution behavior)\nconst PREVIEW_LINES = 20;\n\nexport class BashExecutionComponent extends Container {\n\tprivate command: string;\n\tprivate outputLines: string[] = [];\n\tprivate status: \"running\" | \"complete\" | \"cancelled\" | \"error\" = \"running\";\n\tprivate exitCode: number | undefined = undefined;\n\tprivate loader: Loader;\n\tprivate truncationResult?: TruncationResult;\n\tprivate fullOutputPath?: string;\n\tprivate expanded = false;\n\tprivate contentContainer: Container;\n\n\tconstructor(command: string, ui: TUI, excludeFromContext = false) {\n\t\tsuper();\n\t\tthis.command = command;\n\n\t\t// Use dim border for excluded-from-context commands (!! prefix)\n\t\tconst colorKey = excludeFromContext ? \"dim\" : \"bashMode\";\n\t\tconst borderColor = (str: string) => theme.fg(colorKey, str);\n\n\t\t// Add spacer\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Top border\n\t\tthis.addChild(new DynamicBorder(borderColor));\n\n\t\t// Content container (holds dynamic content between borders)\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\t// Command header\n\t\tconst header = new Text(theme.fg(colorKey, theme.bold(`$ ${command}`)), 1, 0);\n\t\tthis.contentContainer.addChild(header);\n\n\t\t// Loader\n\t\tthis.loader = new Loader(\n\t\t\tui,\n\t\t\t(spinner) => theme.fg(colorKey, spinner),\n\t\t\t(text) => theme.fg(\"muted\", text),\n\t\t\t`Running... (${keyText(\"tui.select.cancel\")} to cancel)`, // Plain text for loader\n\t\t);\n\t\tthis.contentContainer.addChild(this.loader);\n\n\t\t// Bottom border\n\t\tthis.addChild(new DynamicBorder(borderColor));\n\t}\n\n\t/**\n\t * Set whether the output is expanded (shows full output) or collapsed (preview only).\n\t */\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tappendOutput(chunk: string): void {\n\t\t// Strip ANSI codes and normalize line endings\n\t\t// Note: binary data is already sanitized in tui-renderer.ts executeBashCommand\n\t\tconst clean = stripAnsi(chunk).replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n\n\t\t// Append to output lines\n\t\tconst newLines = clean.split(\"\\n\");\n\t\tif (this.outputLines.length > 0 && newLines.length > 0) {\n\t\t\t// Append first chunk to last line (incomplete line continuation)\n\t\t\tthis.outputLines[this.outputLines.length - 1] += newLines[0];\n\t\t\tthis.outputLines.push(...newLines.slice(1));\n\t\t} else {\n\t\t\tthis.outputLines.push(...newLines);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tsetComplete(\n\t\texitCode: number | undefined,\n\t\tcancelled: boolean,\n\t\ttruncationResult?: TruncationResult,\n\t\tfullOutputPath?: string,\n\t): void {\n\t\tthis.exitCode = exitCode;\n\t\tthis.status = cancelled\n\t\t\t? \"cancelled\"\n\t\t\t: exitCode !== 0 && exitCode !== undefined && exitCode !== null\n\t\t\t\t? \"error\"\n\t\t\t\t: \"complete\";\n\t\tthis.truncationResult = truncationResult;\n\t\tthis.fullOutputPath = fullOutputPath;\n\n\t\t// Stop loader\n\t\tthis.loader.stop();\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\t// Apply truncation for LLM context limits (same limits as bash tool)\n\t\tconst fullOutput = this.outputLines.join(\"\\n\");\n\t\tconst contextTruncation = truncateTail(fullOutput, {\n\t\t\tmaxLines: DEFAULT_MAX_LINES,\n\t\t\tmaxBytes: DEFAULT_MAX_BYTES,\n\t\t});\n\n\t\t// Get the lines to potentially display (after context truncation)\n\t\tconst availableLines = contextTruncation.content ? contextTruncation.content.split(\"\\n\") : [];\n\n\t\t// Apply preview truncation based on expanded state\n\t\tconst previewLogicalLines = availableLines.slice(-PREVIEW_LINES);\n\t\tconst hiddenLineCount = availableLines.length - previewLogicalLines.length;\n\n\t\t// Rebuild content container\n\t\tthis.contentContainer.clear();\n\n\t\t// Command header\n\t\tconst header = new Text(theme.fg(\"bashMode\", theme.bold(`$ ${this.command}`)), 1, 0);\n\t\tthis.contentContainer.addChild(header);\n\n\t\t// Output\n\t\tif (availableLines.length > 0) {\n\t\t\tif (this.expanded) {\n\t\t\t\t// Show all lines\n\t\t\t\tconst displayText = availableLines.map((line) => theme.fg(\"muted\", line)).join(\"\\n\");\n\t\t\t\tthis.contentContainer.addChild(new Text(`\\n${displayText}`, 1, 0));\n\t\t\t} else {\n\t\t\t\t// Use shared visual truncation utility with width-aware caching\n\t\t\t\tconst styledOutput = previewLogicalLines.map((line) => theme.fg(\"muted\", line)).join(\"\\n\");\n\t\t\t\tconst styledInput = `\\n${styledOutput}`;\n\t\t\t\tlet cachedWidth: number | undefined;\n\t\t\t\tlet cachedLines: string[] | undefined;\n\t\t\t\tthis.contentContainer.addChild({\n\t\t\t\t\trender: (width: number) => {\n\t\t\t\t\t\tif (cachedLines === undefined || cachedWidth !== width) {\n\t\t\t\t\t\t\tconst result = truncateToVisualLines(styledInput, PREVIEW_LINES, width, 1);\n\t\t\t\t\t\t\tcachedLines = result.visualLines;\n\t\t\t\t\t\t\tcachedWidth = width;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn cachedLines ?? [];\n\t\t\t\t\t},\n\t\t\t\t\tinvalidate: () => {\n\t\t\t\t\t\tcachedWidth = undefined;\n\t\t\t\t\t\tcachedLines = undefined;\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Loader or status\n\t\tif (this.status === \"running\") {\n\t\t\tthis.contentContainer.addChild(this.loader);\n\t\t} else {\n\t\t\tconst statusParts: string[] = [];\n\n\t\t\t// Show how many lines are hidden (collapsed preview)\n\t\t\tif (hiddenLineCount > 0) {\n\t\t\t\tif (this.expanded) {\n\t\t\t\t\tstatusParts.push(`(${keyHint(\"app.tools.expand\", \"to collapse\")})`);\n\t\t\t\t} else {\n\t\t\t\t\tstatusParts.push(\n\t\t\t\t\t\t`${theme.fg(\"muted\", `... ${hiddenLineCount} more lines`)} (${keyHint(\"app.tools.expand\", \"to expand\")})`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.status === \"cancelled\") {\n\t\t\t\tstatusParts.push(theme.fg(\"warning\", \"(cancelled)\"));\n\t\t\t} else if (this.status === \"error\") {\n\t\t\t\tstatusParts.push(theme.fg(\"error\", `(exit ${this.exitCode})`));\n\t\t\t}\n\n\t\t\t// Add truncation warning (context truncation, not preview truncation)\n\t\t\tconst wasTruncated = this.truncationResult?.truncated || contextTruncation.truncated;\n\t\t\tif (wasTruncated && this.fullOutputPath) {\n\t\t\t\tstatusParts.push(theme.fg(\"warning\", `Output truncated. Full output: ${this.fullOutputPath}`));\n\t\t\t}\n\n\t\t\tif (statusParts.length > 0) {\n\t\t\t\tthis.contentContainer.addChild(new Text(`\\n${statusParts.join(\"\\n\")}`, 1, 0));\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the raw output for creating BashExecutionMessage.\n\t */\n\tgetOutput(): string {\n\t\treturn this.outputLines.join(\"\\n\");\n\t}\n\n\t/**\n\t * Get the command that was executed.\n\t */\n\tgetCommand(): string {\n\t\treturn this.command;\n\t}\n}\n"]}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Component for displaying bash command execution with streaming output.
3
+ */
4
+ import { Container, Loader, Spacer, Text } from "@looze/leaf-tui";
5
+ import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateTail, } from "../../../core/tools/truncate.js";
6
+ import { stripAnsi } from "../../../utils/ansi.js";
7
+ import { theme } from "../theme/theme.js";
8
+ import { DynamicBorder } from "./dynamic-border.js";
9
+ import { keyHint, keyText } from "./keybinding-hints.js";
10
+ import { truncateToVisualLines } from "./visual-truncate.js";
11
+ // Preview line limit when not expanded (matches tool execution behavior)
12
+ const PREVIEW_LINES = 20;
13
+ export class BashExecutionComponent extends Container {
14
+ command;
15
+ outputLines = [];
16
+ status = "running";
17
+ exitCode = undefined;
18
+ loader;
19
+ truncationResult;
20
+ fullOutputPath;
21
+ expanded = false;
22
+ contentContainer;
23
+ constructor(command, ui, excludeFromContext = false) {
24
+ super();
25
+ this.command = command;
26
+ // Use dim border for excluded-from-context commands (!! prefix)
27
+ const colorKey = excludeFromContext ? "dim" : "bashMode";
28
+ const borderColor = (str) => theme.fg(colorKey, str);
29
+ // Add spacer
30
+ this.addChild(new Spacer(1));
31
+ // Top border
32
+ this.addChild(new DynamicBorder(borderColor));
33
+ // Content container (holds dynamic content between borders)
34
+ this.contentContainer = new Container();
35
+ this.addChild(this.contentContainer);
36
+ // Command header
37
+ const header = new Text(theme.fg(colorKey, theme.bold(`$ ${command}`)), 1, 0);
38
+ this.contentContainer.addChild(header);
39
+ // Loader
40
+ this.loader = new Loader(ui, (spinner) => theme.fg(colorKey, spinner), (text) => theme.fg("muted", text), `Running... (${keyText("tui.select.cancel")} to cancel)`);
41
+ this.contentContainer.addChild(this.loader);
42
+ // Bottom border
43
+ this.addChild(new DynamicBorder(borderColor));
44
+ }
45
+ /**
46
+ * Set whether the output is expanded (shows full output) or collapsed (preview only).
47
+ */
48
+ setExpanded(expanded) {
49
+ this.expanded = expanded;
50
+ this.updateDisplay();
51
+ }
52
+ invalidate() {
53
+ super.invalidate();
54
+ this.updateDisplay();
55
+ }
56
+ appendOutput(chunk) {
57
+ // Strip ANSI codes and normalize line endings
58
+ // Note: binary data is already sanitized in tui-renderer.ts executeBashCommand
59
+ const clean = stripAnsi(chunk).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
60
+ // Append to output lines
61
+ const newLines = clean.split("\n");
62
+ if (this.outputLines.length > 0 && newLines.length > 0) {
63
+ // Append first chunk to last line (incomplete line continuation)
64
+ this.outputLines[this.outputLines.length - 1] += newLines[0];
65
+ this.outputLines.push(...newLines.slice(1));
66
+ }
67
+ else {
68
+ this.outputLines.push(...newLines);
69
+ }
70
+ this.updateDisplay();
71
+ }
72
+ setComplete(exitCode, cancelled, truncationResult, fullOutputPath) {
73
+ this.exitCode = exitCode;
74
+ this.status = cancelled
75
+ ? "cancelled"
76
+ : exitCode !== 0 && exitCode !== undefined && exitCode !== null
77
+ ? "error"
78
+ : "complete";
79
+ this.truncationResult = truncationResult;
80
+ this.fullOutputPath = fullOutputPath;
81
+ // Stop loader
82
+ this.loader.stop();
83
+ this.updateDisplay();
84
+ }
85
+ updateDisplay() {
86
+ // Apply truncation for LLM context limits (same limits as bash tool)
87
+ const fullOutput = this.outputLines.join("\n");
88
+ const contextTruncation = truncateTail(fullOutput, {
89
+ maxLines: DEFAULT_MAX_LINES,
90
+ maxBytes: DEFAULT_MAX_BYTES,
91
+ });
92
+ // Get the lines to potentially display (after context truncation)
93
+ const availableLines = contextTruncation.content ? contextTruncation.content.split("\n") : [];
94
+ // Apply preview truncation based on expanded state
95
+ const previewLogicalLines = availableLines.slice(-PREVIEW_LINES);
96
+ const hiddenLineCount = availableLines.length - previewLogicalLines.length;
97
+ // Rebuild content container
98
+ this.contentContainer.clear();
99
+ // Command header
100
+ const header = new Text(theme.fg("bashMode", theme.bold(`$ ${this.command}`)), 1, 0);
101
+ this.contentContainer.addChild(header);
102
+ // Output
103
+ if (availableLines.length > 0) {
104
+ if (this.expanded) {
105
+ // Show all lines
106
+ const displayText = availableLines.map((line) => theme.fg("muted", line)).join("\n");
107
+ this.contentContainer.addChild(new Text(`\n${displayText}`, 1, 0));
108
+ }
109
+ else {
110
+ // Use shared visual truncation utility with width-aware caching
111
+ const styledOutput = previewLogicalLines.map((line) => theme.fg("muted", line)).join("\n");
112
+ const styledInput = `\n${styledOutput}`;
113
+ let cachedWidth;
114
+ let cachedLines;
115
+ this.contentContainer.addChild({
116
+ render: (width) => {
117
+ if (cachedLines === undefined || cachedWidth !== width) {
118
+ const result = truncateToVisualLines(styledInput, PREVIEW_LINES, width, 1);
119
+ cachedLines = result.visualLines;
120
+ cachedWidth = width;
121
+ }
122
+ return cachedLines ?? [];
123
+ },
124
+ invalidate: () => {
125
+ cachedWidth = undefined;
126
+ cachedLines = undefined;
127
+ },
128
+ });
129
+ }
130
+ }
131
+ // Loader or status
132
+ if (this.status === "running") {
133
+ this.contentContainer.addChild(this.loader);
134
+ }
135
+ else {
136
+ const statusParts = [];
137
+ // Show how many lines are hidden (collapsed preview)
138
+ if (hiddenLineCount > 0) {
139
+ if (this.expanded) {
140
+ statusParts.push(`(${keyHint("app.tools.expand", "to collapse")})`);
141
+ }
142
+ else {
143
+ statusParts.push(`${theme.fg("muted", `... ${hiddenLineCount} more lines`)} (${keyHint("app.tools.expand", "to expand")})`);
144
+ }
145
+ }
146
+ if (this.status === "cancelled") {
147
+ statusParts.push(theme.fg("warning", "(cancelled)"));
148
+ }
149
+ else if (this.status === "error") {
150
+ statusParts.push(theme.fg("error", `(exit ${this.exitCode})`));
151
+ }
152
+ // Add truncation warning (context truncation, not preview truncation)
153
+ const wasTruncated = this.truncationResult?.truncated || contextTruncation.truncated;
154
+ if (wasTruncated && this.fullOutputPath) {
155
+ statusParts.push(theme.fg("warning", `Output truncated. Full output: ${this.fullOutputPath}`));
156
+ }
157
+ if (statusParts.length > 0) {
158
+ this.contentContainer.addChild(new Text(`\n${statusParts.join("\n")}`, 1, 0));
159
+ }
160
+ }
161
+ }
162
+ /**
163
+ * Get the raw output for creating BashExecutionMessage.
164
+ */
165
+ getOutput() {
166
+ return this.outputLines.join("\n");
167
+ }
168
+ /**
169
+ * Get the command that was executed.
170
+ */
171
+ getCommand() {
172
+ return this.command;
173
+ }
174
+ }
175
+ //# sourceMappingURL=bash-execution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash-execution.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/bash-execution.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Component for displaying bash command execution with streaming output.\n */\n\nimport { Container, Loader, Spacer, Text, type TUI } from \"@looze/leaf-tui\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\ttype TruncationResult,\n\ttruncateTail,\n} from \"../../../core/tools/truncate.ts\";\nimport { stripAnsi } from \"../../../utils/ansi.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint, keyText } from \"./keybinding-hints.ts\";\nimport { truncateToVisualLines } from \"./visual-truncate.ts\";\n\n// Preview line limit when not expanded (matches tool execution behavior)\nconst PREVIEW_LINES = 20;\n\nexport class BashExecutionComponent extends Container {\n\tprivate command: string;\n\tprivate outputLines: string[] = [];\n\tprivate status: \"running\" | \"complete\" | \"cancelled\" | \"error\" = \"running\";\n\tprivate exitCode: number | undefined = undefined;\n\tprivate loader: Loader;\n\tprivate truncationResult?: TruncationResult;\n\tprivate fullOutputPath?: string;\n\tprivate expanded = false;\n\tprivate contentContainer: Container;\n\n\tconstructor(command: string, ui: TUI, excludeFromContext = false) {\n\t\tsuper();\n\t\tthis.command = command;\n\n\t\t// Use dim border for excluded-from-context commands (!! prefix)\n\t\tconst colorKey = excludeFromContext ? \"dim\" : \"bashMode\";\n\t\tconst borderColor = (str: string) => theme.fg(colorKey, str);\n\n\t\t// Add spacer\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Top border\n\t\tthis.addChild(new DynamicBorder(borderColor));\n\n\t\t// Content container (holds dynamic content between borders)\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\t// Command header\n\t\tconst header = new Text(theme.fg(colorKey, theme.bold(`$ ${command}`)), 1, 0);\n\t\tthis.contentContainer.addChild(header);\n\n\t\t// Loader\n\t\tthis.loader = new Loader(\n\t\t\tui,\n\t\t\t(spinner) => theme.fg(colorKey, spinner),\n\t\t\t(text) => theme.fg(\"muted\", text),\n\t\t\t`Running... (${keyText(\"tui.select.cancel\")} to cancel)`, // Plain text for loader\n\t\t);\n\t\tthis.contentContainer.addChild(this.loader);\n\n\t\t// Bottom border\n\t\tthis.addChild(new DynamicBorder(borderColor));\n\t}\n\n\t/**\n\t * Set whether the output is expanded (shows full output) or collapsed (preview only).\n\t */\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tappendOutput(chunk: string): void {\n\t\t// Strip ANSI codes and normalize line endings\n\t\t// Note: binary data is already sanitized in tui-renderer.ts executeBashCommand\n\t\tconst clean = stripAnsi(chunk).replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n\n\t\t// Append to output lines\n\t\tconst newLines = clean.split(\"\\n\");\n\t\tif (this.outputLines.length > 0 && newLines.length > 0) {\n\t\t\t// Append first chunk to last line (incomplete line continuation)\n\t\t\tthis.outputLines[this.outputLines.length - 1] += newLines[0];\n\t\t\tthis.outputLines.push(...newLines.slice(1));\n\t\t} else {\n\t\t\tthis.outputLines.push(...newLines);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tsetComplete(\n\t\texitCode: number | undefined,\n\t\tcancelled: boolean,\n\t\ttruncationResult?: TruncationResult,\n\t\tfullOutputPath?: string,\n\t): void {\n\t\tthis.exitCode = exitCode;\n\t\tthis.status = cancelled\n\t\t\t? \"cancelled\"\n\t\t\t: exitCode !== 0 && exitCode !== undefined && exitCode !== null\n\t\t\t\t? \"error\"\n\t\t\t\t: \"complete\";\n\t\tthis.truncationResult = truncationResult;\n\t\tthis.fullOutputPath = fullOutputPath;\n\n\t\t// Stop loader\n\t\tthis.loader.stop();\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\t// Apply truncation for LLM context limits (same limits as bash tool)\n\t\tconst fullOutput = this.outputLines.join(\"\\n\");\n\t\tconst contextTruncation = truncateTail(fullOutput, {\n\t\t\tmaxLines: DEFAULT_MAX_LINES,\n\t\t\tmaxBytes: DEFAULT_MAX_BYTES,\n\t\t});\n\n\t\t// Get the lines to potentially display (after context truncation)\n\t\tconst availableLines = contextTruncation.content ? contextTruncation.content.split(\"\\n\") : [];\n\n\t\t// Apply preview truncation based on expanded state\n\t\tconst previewLogicalLines = availableLines.slice(-PREVIEW_LINES);\n\t\tconst hiddenLineCount = availableLines.length - previewLogicalLines.length;\n\n\t\t// Rebuild content container\n\t\tthis.contentContainer.clear();\n\n\t\t// Command header\n\t\tconst header = new Text(theme.fg(\"bashMode\", theme.bold(`$ ${this.command}`)), 1, 0);\n\t\tthis.contentContainer.addChild(header);\n\n\t\t// Output\n\t\tif (availableLines.length > 0) {\n\t\t\tif (this.expanded) {\n\t\t\t\t// Show all lines\n\t\t\t\tconst displayText = availableLines.map((line) => theme.fg(\"muted\", line)).join(\"\\n\");\n\t\t\t\tthis.contentContainer.addChild(new Text(`\\n${displayText}`, 1, 0));\n\t\t\t} else {\n\t\t\t\t// Use shared visual truncation utility with width-aware caching\n\t\t\t\tconst styledOutput = previewLogicalLines.map((line) => theme.fg(\"muted\", line)).join(\"\\n\");\n\t\t\t\tconst styledInput = `\\n${styledOutput}`;\n\t\t\t\tlet cachedWidth: number | undefined;\n\t\t\t\tlet cachedLines: string[] | undefined;\n\t\t\t\tthis.contentContainer.addChild({\n\t\t\t\t\trender: (width: number) => {\n\t\t\t\t\t\tif (cachedLines === undefined || cachedWidth !== width) {\n\t\t\t\t\t\t\tconst result = truncateToVisualLines(styledInput, PREVIEW_LINES, width, 1);\n\t\t\t\t\t\t\tcachedLines = result.visualLines;\n\t\t\t\t\t\t\tcachedWidth = width;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn cachedLines ?? [];\n\t\t\t\t\t},\n\t\t\t\t\tinvalidate: () => {\n\t\t\t\t\t\tcachedWidth = undefined;\n\t\t\t\t\t\tcachedLines = undefined;\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Loader or status\n\t\tif (this.status === \"running\") {\n\t\t\tthis.contentContainer.addChild(this.loader);\n\t\t} else {\n\t\t\tconst statusParts: string[] = [];\n\n\t\t\t// Show how many lines are hidden (collapsed preview)\n\t\t\tif (hiddenLineCount > 0) {\n\t\t\t\tif (this.expanded) {\n\t\t\t\t\tstatusParts.push(`(${keyHint(\"app.tools.expand\", \"to collapse\")})`);\n\t\t\t\t} else {\n\t\t\t\t\tstatusParts.push(\n\t\t\t\t\t\t`${theme.fg(\"muted\", `... ${hiddenLineCount} more lines`)} (${keyHint(\"app.tools.expand\", \"to expand\")})`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.status === \"cancelled\") {\n\t\t\t\tstatusParts.push(theme.fg(\"warning\", \"(cancelled)\"));\n\t\t\t} else if (this.status === \"error\") {\n\t\t\t\tstatusParts.push(theme.fg(\"error\", `(exit ${this.exitCode})`));\n\t\t\t}\n\n\t\t\t// Add truncation warning (context truncation, not preview truncation)\n\t\t\tconst wasTruncated = this.truncationResult?.truncated || contextTruncation.truncated;\n\t\t\tif (wasTruncated && this.fullOutputPath) {\n\t\t\t\tstatusParts.push(theme.fg(\"warning\", `Output truncated. Full output: ${this.fullOutputPath}`));\n\t\t\t}\n\n\t\t\tif (statusParts.length > 0) {\n\t\t\t\tthis.contentContainer.addChild(new Text(`\\n${statusParts.join(\"\\n\")}`, 1, 0));\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the raw output for creating BashExecutionMessage.\n\t */\n\tgetOutput(): string {\n\t\treturn this.outputLines.join(\"\\n\");\n\t}\n\n\t/**\n\t * Get the command that was executed.\n\t */\n\tgetCommand(): string {\n\t\treturn this.command;\n\t}\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { Container, type TUI } from "@looze/leaf-tui";
2
+ import type { Theme } from "../theme/theme.ts";
3
+ /** Loader wrapped with borders for extension UI */
4
+ export declare class BorderedLoader extends Container {
5
+ private loader;
6
+ private cancellable;
7
+ private signalController?;
8
+ constructor(tui: TUI, theme: Theme, message: string, options?: {
9
+ cancellable?: boolean;
10
+ });
11
+ get signal(): AbortSignal;
12
+ set onAbort(fn: (() => void) | undefined);
13
+ handleInput(data: string): void;
14
+ dispose(): void;
15
+ }
16
+ //# sourceMappingURL=bordered-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bordered-loader.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/bordered-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,SAAS,EAAwB,KAAK,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAI/C,mDAAmD;AACnD,qBAAa,cAAe,SAAQ,SAAS;IAC5C,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,gBAAgB,CAAC,CAAkB;IAE3C,YAAY,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,EA4BvF;IAED,IAAI,MAAM,IAAI,WAAW,CAKxB;IAED,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,EAIvC;IAED,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI9B;IAED,OAAO,IAAI,IAAI,CAMd;CACD","sourcesContent":["import { CancellableLoader, Container, Loader, Spacer, Text, type TUI } from \"@looze/leaf-tui\";\nimport type { Theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.ts\";\n\n/** Loader wrapped with borders for extension UI */\nexport class BorderedLoader extends Container {\n\tprivate loader: CancellableLoader | Loader;\n\tprivate cancellable: boolean;\n\tprivate signalController?: AbortController;\n\n\tconstructor(tui: TUI, theme: Theme, message: string, options?: { cancellable?: boolean }) {\n\t\tsuper();\n\t\tthis.cancellable = options?.cancellable ?? true;\n\t\tconst borderColor = (s: string) => theme.fg(\"border\", s);\n\t\tthis.addChild(new DynamicBorder(borderColor));\n\t\tif (this.cancellable) {\n\t\t\tthis.loader = new CancellableLoader(\n\t\t\t\ttui,\n\t\t\t\t(s) => theme.fg(\"accent\", s),\n\t\t\t\t(s) => theme.fg(\"muted\", s),\n\t\t\t\tmessage,\n\t\t\t);\n\t\t} else {\n\t\t\tthis.signalController = new AbortController();\n\t\t\tthis.loader = new Loader(\n\t\t\t\ttui,\n\t\t\t\t(s) => theme.fg(\"accent\", s),\n\t\t\t\t(s) => theme.fg(\"muted\", s),\n\t\t\t\tmessage,\n\t\t\t);\n\t\t}\n\t\tthis.addChild(this.loader);\n\t\tif (this.cancellable) {\n\t\t\tthis.addChild(new Spacer(1));\n\t\t\tthis.addChild(new Text(keyHint(\"tui.select.cancel\", \"cancel\"), 1, 0));\n\t\t}\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder(borderColor));\n\t}\n\n\tget signal(): AbortSignal {\n\t\tif (this.cancellable) {\n\t\t\treturn (this.loader as CancellableLoader).signal;\n\t\t}\n\t\treturn this.signalController?.signal ?? new AbortController().signal;\n\t}\n\n\tset onAbort(fn: (() => void) | undefined) {\n\t\tif (this.cancellable) {\n\t\t\t(this.loader as CancellableLoader).onAbort = fn;\n\t\t}\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (this.cancellable) {\n\t\t\t(this.loader as CancellableLoader).handleInput(data);\n\t\t}\n\t}\n\n\tdispose(): void {\n\t\tif (\"dispose\" in this.loader && typeof this.loader.dispose === \"function\") {\n\t\t\tthis.loader.dispose();\n\t\t} else if (\"stop\" in this.loader && typeof this.loader.stop === \"function\") {\n\t\t\tthis.loader.stop();\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,54 @@
1
+ import { CancellableLoader, Container, Loader, Spacer, Text } from "@looze/leaf-tui";
2
+ import { DynamicBorder } from "./dynamic-border.js";
3
+ import { keyHint } from "./keybinding-hints.js";
4
+ /** Loader wrapped with borders for extension UI */
5
+ export class BorderedLoader extends Container {
6
+ loader;
7
+ cancellable;
8
+ signalController;
9
+ constructor(tui, theme, message, options) {
10
+ super();
11
+ this.cancellable = options?.cancellable ?? true;
12
+ const borderColor = (s) => theme.fg("border", s);
13
+ this.addChild(new DynamicBorder(borderColor));
14
+ if (this.cancellable) {
15
+ this.loader = new CancellableLoader(tui, (s) => theme.fg("accent", s), (s) => theme.fg("muted", s), message);
16
+ }
17
+ else {
18
+ this.signalController = new AbortController();
19
+ this.loader = new Loader(tui, (s) => theme.fg("accent", s), (s) => theme.fg("muted", s), message);
20
+ }
21
+ this.addChild(this.loader);
22
+ if (this.cancellable) {
23
+ this.addChild(new Spacer(1));
24
+ this.addChild(new Text(keyHint("tui.select.cancel", "cancel"), 1, 0));
25
+ }
26
+ this.addChild(new Spacer(1));
27
+ this.addChild(new DynamicBorder(borderColor));
28
+ }
29
+ get signal() {
30
+ if (this.cancellable) {
31
+ return this.loader.signal;
32
+ }
33
+ return this.signalController?.signal ?? new AbortController().signal;
34
+ }
35
+ set onAbort(fn) {
36
+ if (this.cancellable) {
37
+ this.loader.onAbort = fn;
38
+ }
39
+ }
40
+ handleInput(data) {
41
+ if (this.cancellable) {
42
+ this.loader.handleInput(data);
43
+ }
44
+ }
45
+ dispose() {
46
+ if ("dispose" in this.loader && typeof this.loader.dispose === "function") {
47
+ this.loader.dispose();
48
+ }
49
+ else if ("stop" in this.loader && typeof this.loader.stop === "function") {
50
+ this.loader.stop();
51
+ }
52
+ }
53
+ }
54
+ //# sourceMappingURL=bordered-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bordered-loader.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/bordered-loader.ts"],"names":[],"mappings":"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","sourcesContent":["import { CancellableLoader, Container, Loader, Spacer, Text, type TUI } from \"@looze/leaf-tui\";\nimport type { Theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.ts\";\n\n/** Loader wrapped with borders for extension UI */\nexport class BorderedLoader extends Container {\n\tprivate loader: CancellableLoader | Loader;\n\tprivate cancellable: boolean;\n\tprivate signalController?: AbortController;\n\n\tconstructor(tui: TUI, theme: Theme, message: string, options?: { cancellable?: boolean }) {\n\t\tsuper();\n\t\tthis.cancellable = options?.cancellable ?? true;\n\t\tconst borderColor = (s: string) => theme.fg(\"border\", s);\n\t\tthis.addChild(new DynamicBorder(borderColor));\n\t\tif (this.cancellable) {\n\t\t\tthis.loader = new CancellableLoader(\n\t\t\t\ttui,\n\t\t\t\t(s) => theme.fg(\"accent\", s),\n\t\t\t\t(s) => theme.fg(\"muted\", s),\n\t\t\t\tmessage,\n\t\t\t);\n\t\t} else {\n\t\t\tthis.signalController = new AbortController();\n\t\t\tthis.loader = new Loader(\n\t\t\t\ttui,\n\t\t\t\t(s) => theme.fg(\"accent\", s),\n\t\t\t\t(s) => theme.fg(\"muted\", s),\n\t\t\t\tmessage,\n\t\t\t);\n\t\t}\n\t\tthis.addChild(this.loader);\n\t\tif (this.cancellable) {\n\t\t\tthis.addChild(new Spacer(1));\n\t\t\tthis.addChild(new Text(keyHint(\"tui.select.cancel\", \"cancel\"), 1, 0));\n\t\t}\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder(borderColor));\n\t}\n\n\tget signal(): AbortSignal {\n\t\tif (this.cancellable) {\n\t\t\treturn (this.loader as CancellableLoader).signal;\n\t\t}\n\t\treturn this.signalController?.signal ?? new AbortController().signal;\n\t}\n\n\tset onAbort(fn: (() => void) | undefined) {\n\t\tif (this.cancellable) {\n\t\t\t(this.loader as CancellableLoader).onAbort = fn;\n\t\t}\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (this.cancellable) {\n\t\t\t(this.loader as CancellableLoader).handleInput(data);\n\t\t}\n\t}\n\n\tdispose(): void {\n\t\tif (\"dispose\" in this.loader && typeof this.loader.dispose === \"function\") {\n\t\t\tthis.loader.dispose();\n\t\t} else if (\"stop\" in this.loader && typeof this.loader.stop === \"function\") {\n\t\t\tthis.loader.stop();\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { Box, type MarkdownTheme } from "@looze/leaf-tui";
2
+ import type { BranchSummaryMessage } from "../../../core/messages.ts";
3
+ /**
4
+ * Component that renders a branch summary message with collapsed/expanded state.
5
+ * Uses same background color as custom messages for visual consistency.
6
+ */
7
+ export declare class BranchSummaryMessageComponent extends Box {
8
+ private expanded;
9
+ private message;
10
+ private markdownTheme;
11
+ constructor(message: BranchSummaryMessage, markdownTheme?: MarkdownTheme);
12
+ setExpanded(expanded: boolean): void;
13
+ invalidate(): void;
14
+ private updateDisplay;
15
+ }
16
+ //# sourceMappingURL=branch-summary-message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-summary-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/branch-summary-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAY,KAAK,aAAa,EAAgB,MAAM,iBAAiB,CAAC;AAClF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAItE;;;GAGG;AACH,qBAAa,6BAA8B,SAAQ,GAAG;IACrD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,aAAa,CAAgB;IAErC,YAAY,OAAO,EAAE,oBAAoB,EAAE,aAAa,GAAE,aAAkC,EAK3F;IAED,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAGnC;IAEQ,UAAU,IAAI,IAAI,CAG1B;IAED,OAAO,CAAC,aAAa;CA0BrB","sourcesContent":["import { Box, Markdown, type MarkdownTheme, Spacer, Text } from \"@looze/leaf-tui\";\nimport type { BranchSummaryMessage } from \"../../../core/messages.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { keyText } from \"./keybinding-hints.ts\";\n\n/**\n * Component that renders a branch summary message with collapsed/expanded state.\n * Uses same background color as custom messages for visual consistency.\n */\nexport class BranchSummaryMessageComponent extends Box {\n\tprivate expanded = false;\n\tprivate message: BranchSummaryMessage;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(message: BranchSummaryMessage, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper(1, 1, (t) => theme.bg(\"customMessageBg\", t));\n\t\tthis.message = message;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.clear();\n\n\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[branch]\\x1b[22m`);\n\t\tthis.addChild(new Text(label, 0, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\tif (this.expanded) {\n\t\t\tconst header = \"**Branch Summary**\\n\\n\";\n\t\t\tthis.addChild(\n\t\t\t\tnew Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\"customMessageText\", \"Branch summary (\") +\n\t\t\t\t\t\ttheme.fg(\"dim\", keyText(\"app.tools.expand\")) +\n\t\t\t\t\t\ttheme.fg(\"customMessageText\", \" to expand)\"),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,44 @@
1
+ import { Box, Markdown, Spacer, Text } from "@looze/leaf-tui";
2
+ import { getMarkdownTheme, theme } from "../theme/theme.js";
3
+ import { keyText } from "./keybinding-hints.js";
4
+ /**
5
+ * Component that renders a branch summary message with collapsed/expanded state.
6
+ * Uses same background color as custom messages for visual consistency.
7
+ */
8
+ export class BranchSummaryMessageComponent extends Box {
9
+ expanded = false;
10
+ message;
11
+ markdownTheme;
12
+ constructor(message, markdownTheme = getMarkdownTheme()) {
13
+ super(1, 1, (t) => theme.bg("customMessageBg", t));
14
+ this.message = message;
15
+ this.markdownTheme = markdownTheme;
16
+ this.updateDisplay();
17
+ }
18
+ setExpanded(expanded) {
19
+ this.expanded = expanded;
20
+ this.updateDisplay();
21
+ }
22
+ invalidate() {
23
+ super.invalidate();
24
+ this.updateDisplay();
25
+ }
26
+ updateDisplay() {
27
+ this.clear();
28
+ const label = theme.fg("customMessageLabel", `\x1b[1m[branch]\x1b[22m`);
29
+ this.addChild(new Text(label, 0, 0));
30
+ this.addChild(new Spacer(1));
31
+ if (this.expanded) {
32
+ const header = "**Branch Summary**\n\n";
33
+ this.addChild(new Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {
34
+ color: (text) => theme.fg("customMessageText", text),
35
+ }));
36
+ }
37
+ else {
38
+ this.addChild(new Text(theme.fg("customMessageText", "Branch summary (") +
39
+ theme.fg("dim", keyText("app.tools.expand")) +
40
+ theme.fg("customMessageText", " to expand)"), 0, 0));
41
+ }
42
+ }
43
+ }
44
+ //# sourceMappingURL=branch-summary-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-summary-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/branch-summary-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAsB,MAAM,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAElF,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD;;;GAGG;AACH,MAAM,OAAO,6BAA8B,SAAQ,GAAG;IAC7C,QAAQ,GAAG,KAAK,CAAC;IACjB,OAAO,CAAuB;IAC9B,aAAa,CAAgB;IAErC,YAAY,OAA6B,EAAE,aAAa,GAAkB,gBAAgB,EAAE,EAAE;QAC7F,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAED,WAAW,CAAC,QAAiB,EAAQ;QACpC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAEQ,UAAU,GAAS;QAC3B,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAEO,aAAa,GAAS;QAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,oBAAoB,EAAE,yBAAyB,CAAC,CAAC;QACxE,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAE7B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,wBAAwB,CAAC;YACxC,IAAI,CAAC,QAAQ,CACZ,IAAI,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE;gBACrE,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC;aAC5D,CAAC,CACF,CAAC;QACH,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,QAAQ,CACZ,IAAI,IAAI,CACP,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,kBAAkB,CAAC;gBAChD,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;gBAC5C,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,aAAa,CAAC,EAC7C,CAAC,EACD,CAAC,CACD,CACD,CAAC;QACH,CAAC;IAAA,CACD;CACD","sourcesContent":["import { Box, Markdown, type MarkdownTheme, Spacer, Text } from \"@looze/leaf-tui\";\nimport type { BranchSummaryMessage } from \"../../../core/messages.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { keyText } from \"./keybinding-hints.ts\";\n\n/**\n * Component that renders a branch summary message with collapsed/expanded state.\n * Uses same background color as custom messages for visual consistency.\n */\nexport class BranchSummaryMessageComponent extends Box {\n\tprivate expanded = false;\n\tprivate message: BranchSummaryMessage;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(message: BranchSummaryMessage, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper(1, 1, (t) => theme.bg(\"customMessageBg\", t));\n\t\tthis.message = message;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.clear();\n\n\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[branch]\\x1b[22m`);\n\t\tthis.addChild(new Text(label, 0, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\tif (this.expanded) {\n\t\t\tconst header = \"**Branch Summary**\\n\\n\";\n\t\t\tthis.addChild(\n\t\t\t\tnew Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\"customMessageText\", \"Branch summary (\") +\n\t\t\t\t\t\ttheme.fg(\"dim\", keyText(\"app.tools.expand\")) +\n\t\t\t\t\t\ttheme.fg(\"customMessageText\", \" to expand)\"),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { Box, type MarkdownTheme } from "@looze/leaf-tui";
2
+ import type { CompactionSummaryMessage } from "../../../core/messages.ts";
3
+ /**
4
+ * Component that renders a compaction message with collapsed/expanded state.
5
+ * Uses same background color as custom messages for visual consistency.
6
+ */
7
+ export declare class CompactionSummaryMessageComponent extends Box {
8
+ private expanded;
9
+ private message;
10
+ private markdownTheme;
11
+ constructor(message: CompactionSummaryMessage, markdownTheme?: MarkdownTheme);
12
+ setExpanded(expanded: boolean): void;
13
+ invalidate(): void;
14
+ private updateDisplay;
15
+ }
16
+ //# sourceMappingURL=compaction-summary-message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction-summary-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/compaction-summary-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAY,KAAK,aAAa,EAAgB,MAAM,iBAAiB,CAAC;AAClF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAI1E;;;GAGG;AACH,qBAAa,iCAAkC,SAAQ,GAAG;IACzD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,aAAa,CAAgB;IAErC,YAAY,OAAO,EAAE,wBAAwB,EAAE,aAAa,GAAE,aAAkC,EAK/F;IAED,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAGnC;IAEQ,UAAU,IAAI,IAAI,CAG1B;IAED,OAAO,CAAC,aAAa;CA2BrB","sourcesContent":["import { Box, Markdown, type MarkdownTheme, Spacer, Text } from \"@looze/leaf-tui\";\nimport type { CompactionSummaryMessage } from \"../../../core/messages.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { keyText } from \"./keybinding-hints.ts\";\n\n/**\n * Component that renders a compaction message with collapsed/expanded state.\n * Uses same background color as custom messages for visual consistency.\n */\nexport class CompactionSummaryMessageComponent extends Box {\n\tprivate expanded = false;\n\tprivate message: CompactionSummaryMessage;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(message: CompactionSummaryMessage, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper(1, 1, (t) => theme.bg(\"customMessageBg\", t));\n\t\tthis.message = message;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.clear();\n\n\t\tconst tokenStr = this.message.tokensBefore.toLocaleString();\n\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[compaction]\\x1b[22m`);\n\t\tthis.addChild(new Text(label, 0, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\tif (this.expanded) {\n\t\t\tconst header = `**Compacted from ${tokenStr} tokens**\\n\\n`;\n\t\t\tthis.addChild(\n\t\t\t\tnew Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\"customMessageText\", `Compacted from ${tokenStr} tokens (`) +\n\t\t\t\t\t\ttheme.fg(\"dim\", keyText(\"app.tools.expand\")) +\n\t\t\t\t\t\ttheme.fg(\"customMessageText\", \" to expand)\"),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n}\n"]}