@kolisachint/hoocode-agent 0.4.106 → 0.4.107

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 (289) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/cli/args.d.ts.map +1 -1
  3. package/dist/cli/args.js +4 -4
  4. package/dist/cli/args.js.map +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +0 -1
  7. package/dist/cli.js.map +1 -1
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +2 -2
  10. package/dist/config.js.map +1 -1
  11. package/dist/core/agent-session.d.ts +1 -3
  12. package/dist/core/agent-session.d.ts.map +1 -1
  13. package/dist/core/agent-session.js +2 -2
  14. package/dist/core/agent-session.js.map +1 -1
  15. package/dist/core/bash-executor.d.ts.map +1 -1
  16. package/dist/core/bash-executor.js +1 -1
  17. package/dist/core/bash-executor.js.map +1 -1
  18. package/dist/core/extension-mcp-servers.d.ts +1 -1
  19. package/dist/core/extension-mcp-servers.d.ts.map +1 -1
  20. package/dist/core/extension-mcp-servers.js +1 -1
  21. package/dist/core/extension-mcp-servers.js.map +1 -1
  22. package/dist/core/extensions/plugins/index.d.ts.map +1 -1
  23. package/dist/core/extensions/plugins/index.js +1 -1
  24. package/dist/core/extensions/plugins/index.js.map +1 -1
  25. package/dist/core/extensions/types.d.ts +1 -3
  26. package/dist/core/extensions/types.d.ts.map +1 -1
  27. package/dist/core/extensions/types.js.map +1 -1
  28. package/dist/core/index.d.ts +1 -1
  29. package/dist/core/index.d.ts.map +1 -1
  30. package/dist/core/index.js.map +1 -1
  31. package/dist/core/mode-prompts.d.ts +1 -1
  32. package/dist/core/mode-prompts.d.ts.map +1 -1
  33. package/dist/core/mode-prompts.js +1 -1
  34. package/dist/core/mode-prompts.js.map +1 -1
  35. package/dist/core/package-manager.d.ts.map +1 -1
  36. package/dist/core/package-manager.js +1 -1
  37. package/dist/core/package-manager.js.map +1 -1
  38. package/dist/core/sdk.d.ts.map +1 -1
  39. package/dist/core/sdk.js +1 -2
  40. package/dist/core/sdk.js.map +1 -1
  41. package/dist/core/session-manager.d.ts +2 -97
  42. package/dist/core/session-manager.d.ts.map +1 -1
  43. package/dist/core/session-manager.js +4 -65
  44. package/dist/core/session-manager.js.map +1 -1
  45. package/dist/core/settings-manager.d.ts.map +1 -1
  46. package/dist/core/settings-manager.js +2 -3
  47. package/dist/core/settings-manager.js.map +1 -1
  48. package/dist/core/telemetry.d.ts.map +1 -1
  49. package/dist/core/telemetry.js +1 -1
  50. package/dist/core/telemetry.js.map +1 -1
  51. package/dist/core/timings.d.ts +1 -1
  52. package/dist/core/timings.d.ts.map +1 -1
  53. package/dist/core/timings.js +2 -2
  54. package/dist/core/timings.js.map +1 -1
  55. package/dist/core/tools/{browser-continue.d.ts → browser/browser-continue.d.ts} +1 -1
  56. package/dist/core/tools/browser/browser-continue.d.ts.map +1 -0
  57. package/dist/core/tools/{browser-continue.js → browser/browser-continue.js} +2 -2
  58. package/dist/core/tools/browser/browser-continue.js.map +1 -0
  59. package/dist/core/tools/{browser-run.d.ts → browser/browser-run.d.ts} +2 -2
  60. package/dist/core/tools/browser/browser-run.d.ts.map +1 -0
  61. package/dist/core/tools/{browser-run.js → browser/browser-run.js} +2 -2
  62. package/dist/core/tools/browser/browser-run.js.map +1 -0
  63. package/dist/core/tools/browser/browsertools-shared.d.ts.map +1 -0
  64. package/dist/core/tools/{browsertools-shared.js → browser/browsertools-shared.js} +1 -1
  65. package/dist/core/tools/browser/browsertools-shared.js.map +1 -0
  66. package/dist/core/tools/browser/index.d.ts +8 -0
  67. package/dist/core/tools/browser/index.d.ts.map +1 -0
  68. package/dist/core/tools/browser/index.js +8 -0
  69. package/dist/core/tools/browser/index.js.map +1 -0
  70. package/dist/core/tools/{docedit.d.ts → doc/docedit.d.ts} +2 -2
  71. package/dist/core/tools/doc/docedit.d.ts.map +1 -0
  72. package/dist/core/tools/{docedit.js → doc/docedit.js} +7 -7
  73. package/dist/core/tools/doc/docedit.js.map +1 -0
  74. package/dist/core/tools/{docgrep.d.ts → doc/docgrep.d.ts} +2 -2
  75. package/dist/core/tools/doc/docgrep.d.ts.map +1 -0
  76. package/dist/core/tools/{docgrep.js → doc/docgrep.js} +6 -6
  77. package/dist/core/tools/doc/docgrep.js.map +1 -0
  78. package/dist/core/tools/{docpeek.d.ts → doc/docpeek.d.ts} +2 -2
  79. package/dist/core/tools/{docpeek.js.map → doc/docpeek.d.ts.map} +1 -1
  80. package/dist/core/tools/{docpeek.js → doc/docpeek.js} +6 -6
  81. package/dist/core/tools/doc/docpeek.js.map +1 -0
  82. package/dist/core/tools/{docread.d.ts → doc/docread.d.ts} +2 -2
  83. package/dist/core/tools/doc/docread.d.ts.map +1 -0
  84. package/dist/core/tools/{docread.js → doc/docread.js} +6 -6
  85. package/dist/core/tools/doc/docread.js.map +1 -0
  86. package/dist/core/tools/{docscan.d.ts → doc/docscan.d.ts} +2 -2
  87. package/dist/core/tools/doc/docscan.d.ts.map +1 -0
  88. package/dist/core/tools/{docscan.js → doc/docscan.js} +6 -6
  89. package/dist/core/tools/doc/docscan.js.map +1 -0
  90. package/dist/core/tools/{docwrite.d.ts → doc/docwrite.d.ts} +1 -1
  91. package/dist/core/tools/doc/docwrite.d.ts.map +1 -0
  92. package/dist/core/tools/{docwrite.js → doc/docwrite.js} +6 -6
  93. package/dist/core/tools/doc/docwrite.js.map +1 -0
  94. package/dist/core/tools/doc/index.d.ts +11 -0
  95. package/dist/core/tools/doc/index.d.ts.map +1 -0
  96. package/dist/core/tools/doc/index.js +11 -0
  97. package/dist/core/tools/doc/index.js.map +1 -0
  98. package/dist/core/tools/grep.d.ts.map +1 -1
  99. package/dist/core/tools/grep.js +1 -1
  100. package/dist/core/tools/grep.js.map +1 -1
  101. package/dist/core/tools/index.d.ts +42 -28
  102. package/dist/core/tools/index.d.ts.map +1 -1
  103. package/dist/core/tools/index.js +61 -199
  104. package/dist/core/tools/index.js.map +1 -1
  105. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  106. package/dist/core/tools/output-accumulator.js +1 -1
  107. package/dist/core/tools/output-accumulator.js.map +1 -1
  108. package/dist/core/tools/read.d.ts.map +1 -1
  109. package/dist/core/tools/read.js +1 -1
  110. package/dist/core/tools/read.js.map +1 -1
  111. package/dist/extensions/core/ask-options.d.ts +10 -0
  112. package/dist/extensions/core/ask-options.d.ts.map +1 -0
  113. package/dist/extensions/core/ask-options.js +83 -0
  114. package/dist/extensions/core/ask-options.js.map +1 -0
  115. package/dist/extensions/core/config.d.ts +80 -0
  116. package/dist/extensions/core/config.d.ts.map +1 -0
  117. package/dist/extensions/core/config.js +110 -0
  118. package/dist/extensions/core/config.js.map +1 -0
  119. package/dist/extensions/core/cost.d.ts +11 -0
  120. package/dist/extensions/core/cost.d.ts.map +1 -0
  121. package/dist/extensions/core/cost.js +64 -0
  122. package/dist/extensions/core/cost.js.map +1 -0
  123. package/dist/extensions/core/hoo-core.d.ts +16 -179
  124. package/dist/extensions/core/hoo-core.d.ts.map +1 -1
  125. package/dist/extensions/core/hoo-core.js +27 -1663
  126. package/dist/extensions/core/hoo-core.js.map +1 -1
  127. package/dist/extensions/core/loop.d.ts +15 -0
  128. package/dist/extensions/core/loop.d.ts.map +1 -0
  129. package/dist/extensions/core/loop.js +235 -0
  130. package/dist/extensions/core/loop.js.map +1 -0
  131. package/dist/extensions/core/marketplace.d.ts +17 -0
  132. package/dist/extensions/core/marketplace.d.ts.map +1 -0
  133. package/dist/extensions/core/marketplace.js +167 -0
  134. package/dist/extensions/core/marketplace.js.map +1 -0
  135. package/dist/extensions/core/mcp-loader.d.ts +26 -0
  136. package/dist/extensions/core/mcp-loader.d.ts.map +1 -0
  137. package/dist/extensions/core/mcp-loader.js +391 -0
  138. package/dist/extensions/core/mcp-loader.js.map +1 -0
  139. package/dist/extensions/core/modes.d.ts +56 -0
  140. package/dist/extensions/core/modes.d.ts.map +1 -0
  141. package/dist/extensions/core/modes.js +268 -0
  142. package/dist/extensions/core/modes.js.map +1 -0
  143. package/dist/extensions/core/permission-gate.d.ts +10 -0
  144. package/dist/extensions/core/permission-gate.d.ts.map +1 -0
  145. package/dist/extensions/core/permission-gate.js +167 -0
  146. package/dist/extensions/core/permission-gate.js.map +1 -0
  147. package/dist/extensions/core/scaffold.d.ts +9 -0
  148. package/dist/extensions/core/scaffold.d.ts.map +1 -0
  149. package/dist/extensions/core/scaffold.js +146 -0
  150. package/dist/extensions/core/scaffold.js.map +1 -0
  151. package/dist/extensions/core/thinking-escalation.d.ts +18 -0
  152. package/dist/extensions/core/thinking-escalation.d.ts.map +1 -0
  153. package/dist/extensions/core/thinking-escalation.js +70 -0
  154. package/dist/extensions/core/thinking-escalation.js.map +1 -0
  155. package/dist/index.d.ts +2 -3
  156. package/dist/index.d.ts.map +1 -1
  157. package/dist/index.js +3 -4
  158. package/dist/index.js.map +1 -1
  159. package/dist/main.d.ts.map +1 -1
  160. package/dist/main.js +2 -2
  161. package/dist/main.js.map +1 -1
  162. package/dist/modes/interactive/command-executor.d.ts +0 -5
  163. package/dist/modes/interactive/command-executor.d.ts.map +1 -1
  164. package/dist/modes/interactive/command-executor.js +0 -7
  165. package/dist/modes/interactive/command-executor.js.map +1 -1
  166. package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
  167. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  168. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  169. package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
  170. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  171. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  172. package/dist/modes/interactive/components/custom-message.d.ts +1 -1
  173. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  174. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  175. package/dist/modes/interactive/components/index.d.ts +0 -2
  176. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  177. package/dist/modes/interactive/components/index.js +0 -2
  178. package/dist/modes/interactive/components/index.js.map +1 -1
  179. package/dist/modes/interactive/extension-chrome.d.ts +56 -0
  180. package/dist/modes/interactive/extension-chrome.d.ts.map +1 -0
  181. package/dist/modes/interactive/extension-chrome.js +172 -0
  182. package/dist/modes/interactive/extension-chrome.js.map +1 -0
  183. package/dist/modes/interactive/extension-dialogs.d.ts +82 -0
  184. package/dist/modes/interactive/extension-dialogs.d.ts.map +1 -0
  185. package/dist/modes/interactive/extension-dialogs.js +259 -0
  186. package/dist/modes/interactive/extension-dialogs.js.map +1 -0
  187. package/dist/modes/interactive/interactive-mode.d.ts +11 -161
  188. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  189. package/dist/modes/interactive/interactive-mode.js +261 -1584
  190. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  191. package/dist/modes/interactive/resource-display.d.ts +59 -0
  192. package/dist/modes/interactive/resource-display.d.ts.map +1 -0
  193. package/dist/modes/interactive/resource-display.js +499 -0
  194. package/dist/modes/interactive/resource-display.js.map +1 -0
  195. package/dist/modes/interactive/startup-checks.d.ts +17 -0
  196. package/dist/modes/interactive/startup-checks.d.ts.map +1 -0
  197. package/dist/modes/interactive/startup-checks.js +102 -0
  198. package/dist/modes/interactive/startup-checks.js.map +1 -0
  199. package/dist/modes/interactive/team-focus.d.ts +56 -0
  200. package/dist/modes/interactive/team-focus.d.ts.map +1 -0
  201. package/dist/modes/interactive/team-focus.js +167 -0
  202. package/dist/modes/interactive/team-focus.js.map +1 -0
  203. package/dist/modes/interactive/voice/voice-controller.d.ts +66 -0
  204. package/dist/modes/interactive/voice/voice-controller.d.ts.map +1 -0
  205. package/dist/modes/interactive/voice/voice-controller.js +312 -0
  206. package/dist/modes/interactive/voice/voice-controller.js.map +1 -0
  207. package/dist/modes/interactive/voice/voice-panel.d.ts.map +1 -0
  208. package/dist/modes/interactive/voice/voice-panel.js.map +1 -0
  209. package/dist/modes/interactive/voice/voice-transcribe.d.ts.map +1 -0
  210. package/dist/modes/interactive/voice/voice-transcribe.js.map +1 -0
  211. package/dist/modes/rpc/rpc-client.d.ts +1 -2
  212. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  213. package/dist/modes/rpc/rpc-client.js.map +1 -1
  214. package/dist/modes/rpc/rpc-types.d.ts +1 -2
  215. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  216. package/dist/modes/rpc/rpc-types.js.map +1 -1
  217. package/dist/resources-cli.d.ts.map +1 -1
  218. package/dist/resources-cli.js +1 -1
  219. package/dist/resources-cli.js.map +1 -1
  220. package/dist/utils/tools-manager.d.ts.map +1 -1
  221. package/dist/utils/tools-manager.js +1 -1
  222. package/dist/utils/tools-manager.js.map +1 -1
  223. package/dist/utils/version-check.d.ts.map +1 -1
  224. package/dist/utils/version-check.js +2 -2
  225. package/dist/utils/version-check.js.map +1 -1
  226. package/docs/project-local-resources.md +1 -1
  227. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  228. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  229. package/examples/extensions/sandbox/package.json +1 -1
  230. package/examples/extensions/with-deps/package.json +1 -1
  231. package/package.json +4 -4
  232. package/dist/core/compaction/branch-summarization.d.ts +0 -88
  233. package/dist/core/compaction/branch-summarization.d.ts.map +0 -1
  234. package/dist/core/compaction/branch-summarization.js +0 -243
  235. package/dist/core/compaction/branch-summarization.js.map +0 -1
  236. package/dist/core/compaction/compaction.d.ts +0 -123
  237. package/dist/core/compaction/compaction.d.ts.map +0 -1
  238. package/dist/core/compaction/compaction.js +0 -635
  239. package/dist/core/compaction/compaction.js.map +0 -1
  240. package/dist/core/compaction/index.d.ts +0 -7
  241. package/dist/core/compaction/index.d.ts.map +0 -1
  242. package/dist/core/compaction/index.js +0 -7
  243. package/dist/core/compaction/index.js.map +0 -1
  244. package/dist/core/compaction/utils.d.ts +0 -38
  245. package/dist/core/compaction/utils.d.ts.map +0 -1
  246. package/dist/core/compaction/utils.js +0 -156
  247. package/dist/core/compaction/utils.js.map +0 -1
  248. package/dist/core/messages.d.ts +0 -124
  249. package/dist/core/messages.d.ts.map +0 -1
  250. package/dist/core/messages.js +0 -221
  251. package/dist/core/messages.js.map +0 -1
  252. package/dist/core/tools/browser-continue.d.ts.map +0 -1
  253. package/dist/core/tools/browser-continue.js.map +0 -1
  254. package/dist/core/tools/browser-run.d.ts.map +0 -1
  255. package/dist/core/tools/browser-run.js.map +0 -1
  256. package/dist/core/tools/browsertools-shared.d.ts.map +0 -1
  257. package/dist/core/tools/browsertools-shared.js.map +0 -1
  258. package/dist/core/tools/docedit.d.ts.map +0 -1
  259. package/dist/core/tools/docedit.js.map +0 -1
  260. package/dist/core/tools/docgrep.d.ts.map +0 -1
  261. package/dist/core/tools/docgrep.js.map +0 -1
  262. package/dist/core/tools/docpeek.d.ts.map +0 -1
  263. package/dist/core/tools/docread.d.ts.map +0 -1
  264. package/dist/core/tools/docread.js.map +0 -1
  265. package/dist/core/tools/docscan.d.ts.map +0 -1
  266. package/dist/core/tools/docscan.js.map +0 -1
  267. package/dist/core/tools/docwrite.d.ts.map +0 -1
  268. package/dist/core/tools/docwrite.js.map +0 -1
  269. package/dist/core/tools/output-compression.d.ts +0 -53
  270. package/dist/core/tools/output-compression.d.ts.map +0 -1
  271. package/dist/core/tools/output-compression.js +0 -392
  272. package/dist/core/tools/output-compression.js.map +0 -1
  273. package/dist/modes/interactive/components/armin.d.ts +0 -34
  274. package/dist/modes/interactive/components/armin.d.ts.map +0 -1
  275. package/dist/modes/interactive/components/armin.js +0 -333
  276. package/dist/modes/interactive/components/armin.js.map +0 -1
  277. package/dist/modes/interactive/components/daxnuts.d.ts +0 -23
  278. package/dist/modes/interactive/components/daxnuts.d.ts.map +0 -1
  279. package/dist/modes/interactive/components/daxnuts.js +0 -140
  280. package/dist/modes/interactive/components/daxnuts.js.map +0 -1
  281. package/dist/modes/interactive/components/voice-panel.d.ts.map +0 -1
  282. package/dist/modes/interactive/components/voice-panel.js.map +0 -1
  283. package/dist/modes/interactive/voice-transcribe.d.ts.map +0 -1
  284. package/dist/modes/interactive/voice-transcribe.js.map +0 -1
  285. /package/dist/core/tools/{browsertools-shared.d.ts → browser/browsertools-shared.d.ts} +0 -0
  286. /package/dist/modes/interactive/{components → voice}/voice-panel.d.ts +0 -0
  287. /package/dist/modes/interactive/{components → voice}/voice-panel.js +0 -0
  288. /package/dist/modes/interactive/{voice-transcribe.d.ts → voice/voice-transcribe.d.ts} +0 -0
  289. /package/dist/modes/interactive/{voice-transcribe.js → voice/voice-transcribe.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,iCAAiC,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,KAAK,iBAAiB,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACrH,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC","sourcesContent":["// UI Components for extensions\nexport { ArminComponent } from \"./armin.js\";\nexport { AskOptionsComponent } from \"./ask-options.js\";\nexport { AssistantMessageComponent } from \"./assistant-message.js\";\nexport { BashExecutionComponent } from \"./bash-execution.js\";\nexport { BorderedLoader } from \"./bordered-loader.js\";\nexport { BranchSummaryMessageComponent } from \"./branch-summary-message.js\";\nexport { CompactionSummaryMessageComponent } from \"./compaction-summary-message.js\";\nexport { CustomEditor } from \"./custom-editor.js\";\nexport { CustomMessageComponent } from \"./custom-message.js\";\nexport { DaxnutsComponent } from \"./daxnuts.js\";\nexport { type RenderDiffOptions, renderDiff } from \"./diff.js\";\nexport { DynamicBorder } from \"./dynamic-border.js\";\nexport { ExtensionEditorComponent } from \"./extension-editor.js\";\nexport { ExtensionInputComponent } from \"./extension-input.js\";\nexport { ExtensionSelectorComponent } from \"./extension-selector.js\";\nexport { FooterComponent } from \"./footer.js\";\nexport { keyHint, keyText, rawKeyHint } from \"./keybinding-hints.js\";\nexport { LoginDialogComponent } from \"./login-dialog.js\";\nexport { ModelSelectorComponent } from \"./model-selector.js\";\nexport { OAuthSelectorComponent } from \"./oauth-selector.js\";\nexport { type ModelsCallbacks, type ModelsConfig, ScopedModelsSelectorComponent } from \"./scoped-models-selector.js\";\nexport { SessionSelectorComponent } from \"./session-selector.js\";\nexport { type SettingsCallbacks, type SettingsConfig, SettingsSelectorComponent } from \"./settings-selector.js\";\nexport { ShowImagesSelectorComponent } from \"./show-images-selector.js\";\nexport { SkillInvocationMessageComponent } from \"./skill-invocation-message.js\";\nexport { TaskPanelComponent } from \"./task-panel.js\";\nexport { ThemeSelectorComponent } from \"./theme-selector.js\";\nexport { ThinkingSelectorComponent } from \"./thinking-selector.js\";\nexport { ToolExecutionComponent, type ToolExecutionOptions } from \"./tool-execution.js\";\nexport { TreeSelectorComponent } from \"./tree-selector.js\";\nexport { UserMessageComponent } from \"./user-message.js\";\nexport { UserMessageSelectorComponent } from \"./user-message-selector.js\";\nexport { truncateToVisualLines, type VisualTruncateResult } from \"./visual-truncate.js\";\n"]}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,iCAAiC,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,KAAK,iBAAiB,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACrH,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC","sourcesContent":["// UI Components for extensions\nexport { AskOptionsComponent } from \"./ask-options.js\";\nexport { AssistantMessageComponent } from \"./assistant-message.js\";\nexport { BashExecutionComponent } from \"./bash-execution.js\";\nexport { BorderedLoader } from \"./bordered-loader.js\";\nexport { BranchSummaryMessageComponent } from \"./branch-summary-message.js\";\nexport { CompactionSummaryMessageComponent } from \"./compaction-summary-message.js\";\nexport { CustomEditor } from \"./custom-editor.js\";\nexport { CustomMessageComponent } from \"./custom-message.js\";\nexport { type RenderDiffOptions, renderDiff } from \"./diff.js\";\nexport { DynamicBorder } from \"./dynamic-border.js\";\nexport { ExtensionEditorComponent } from \"./extension-editor.js\";\nexport { ExtensionInputComponent } from \"./extension-input.js\";\nexport { ExtensionSelectorComponent } from \"./extension-selector.js\";\nexport { FooterComponent } from \"./footer.js\";\nexport { keyHint, keyText, rawKeyHint } from \"./keybinding-hints.js\";\nexport { LoginDialogComponent } from \"./login-dialog.js\";\nexport { ModelSelectorComponent } from \"./model-selector.js\";\nexport { OAuthSelectorComponent } from \"./oauth-selector.js\";\nexport { type ModelsCallbacks, type ModelsConfig, ScopedModelsSelectorComponent } from \"./scoped-models-selector.js\";\nexport { SessionSelectorComponent } from \"./session-selector.js\";\nexport { type SettingsCallbacks, type SettingsConfig, SettingsSelectorComponent } from \"./settings-selector.js\";\nexport { ShowImagesSelectorComponent } from \"./show-images-selector.js\";\nexport { SkillInvocationMessageComponent } from \"./skill-invocation-message.js\";\nexport { TaskPanelComponent } from \"./task-panel.js\";\nexport { ThemeSelectorComponent } from \"./theme-selector.js\";\nexport { ThinkingSelectorComponent } from \"./thinking-selector.js\";\nexport { ToolExecutionComponent, type ToolExecutionOptions } from \"./tool-execution.js\";\nexport { TreeSelectorComponent } from \"./tree-selector.js\";\nexport { UserMessageComponent } from \"./user-message.js\";\nexport { UserMessageSelectorComponent } from \"./user-message-selector.js\";\nexport { truncateToVisualLines, type VisualTruncateResult } from \"./visual-truncate.js\";\n"]}
@@ -1,5 +1,4 @@
1
1
  // UI Components for extensions
2
- export { ArminComponent } from "./armin.js";
3
2
  export { AskOptionsComponent } from "./ask-options.js";
4
3
  export { AssistantMessageComponent } from "./assistant-message.js";
5
4
  export { BashExecutionComponent } from "./bash-execution.js";
@@ -8,7 +7,6 @@ export { BranchSummaryMessageComponent } from "./branch-summary-message.js";
8
7
  export { CompactionSummaryMessageComponent } from "./compaction-summary-message.js";
9
8
  export { CustomEditor } from "./custom-editor.js";
10
9
  export { CustomMessageComponent } from "./custom-message.js";
11
- export { DaxnutsComponent } from "./daxnuts.js";
12
10
  export { renderDiff } from "./diff.js";
13
11
  export { DynamicBorder } from "./dynamic-border.js";
14
12
  export { ExtensionEditorComponent } from "./extension-editor.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,iCAAiC,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAA0B,UAAU,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAA2C,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACrH,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAA+C,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAA6B,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAA6B,MAAM,sBAAsB,CAAC","sourcesContent":["// UI Components for extensions\nexport { ArminComponent } from \"./armin.js\";\nexport { AskOptionsComponent } from \"./ask-options.js\";\nexport { AssistantMessageComponent } from \"./assistant-message.js\";\nexport { BashExecutionComponent } from \"./bash-execution.js\";\nexport { BorderedLoader } from \"./bordered-loader.js\";\nexport { BranchSummaryMessageComponent } from \"./branch-summary-message.js\";\nexport { CompactionSummaryMessageComponent } from \"./compaction-summary-message.js\";\nexport { CustomEditor } from \"./custom-editor.js\";\nexport { CustomMessageComponent } from \"./custom-message.js\";\nexport { DaxnutsComponent } from \"./daxnuts.js\";\nexport { type RenderDiffOptions, renderDiff } from \"./diff.js\";\nexport { DynamicBorder } from \"./dynamic-border.js\";\nexport { ExtensionEditorComponent } from \"./extension-editor.js\";\nexport { ExtensionInputComponent } from \"./extension-input.js\";\nexport { ExtensionSelectorComponent } from \"./extension-selector.js\";\nexport { FooterComponent } from \"./footer.js\";\nexport { keyHint, keyText, rawKeyHint } from \"./keybinding-hints.js\";\nexport { LoginDialogComponent } from \"./login-dialog.js\";\nexport { ModelSelectorComponent } from \"./model-selector.js\";\nexport { OAuthSelectorComponent } from \"./oauth-selector.js\";\nexport { type ModelsCallbacks, type ModelsConfig, ScopedModelsSelectorComponent } from \"./scoped-models-selector.js\";\nexport { SessionSelectorComponent } from \"./session-selector.js\";\nexport { type SettingsCallbacks, type SettingsConfig, SettingsSelectorComponent } from \"./settings-selector.js\";\nexport { ShowImagesSelectorComponent } from \"./show-images-selector.js\";\nexport { SkillInvocationMessageComponent } from \"./skill-invocation-message.js\";\nexport { TaskPanelComponent } from \"./task-panel.js\";\nexport { ThemeSelectorComponent } from \"./theme-selector.js\";\nexport { ThinkingSelectorComponent } from \"./thinking-selector.js\";\nexport { ToolExecutionComponent, type ToolExecutionOptions } from \"./tool-execution.js\";\nexport { TreeSelectorComponent } from \"./tree-selector.js\";\nexport { UserMessageComponent } from \"./user-message.js\";\nexport { UserMessageSelectorComponent } from \"./user-message-selector.js\";\nexport { truncateToVisualLines, type VisualTruncateResult } from \"./visual-truncate.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,iCAAiC,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAA0B,UAAU,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAA2C,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACrH,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAA+C,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAA6B,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAA6B,MAAM,sBAAsB,CAAC","sourcesContent":["// UI Components for extensions\nexport { AskOptionsComponent } from \"./ask-options.js\";\nexport { AssistantMessageComponent } from \"./assistant-message.js\";\nexport { BashExecutionComponent } from \"./bash-execution.js\";\nexport { BorderedLoader } from \"./bordered-loader.js\";\nexport { BranchSummaryMessageComponent } from \"./branch-summary-message.js\";\nexport { CompactionSummaryMessageComponent } from \"./compaction-summary-message.js\";\nexport { CustomEditor } from \"./custom-editor.js\";\nexport { CustomMessageComponent } from \"./custom-message.js\";\nexport { type RenderDiffOptions, renderDiff } from \"./diff.js\";\nexport { DynamicBorder } from \"./dynamic-border.js\";\nexport { ExtensionEditorComponent } from \"./extension-editor.js\";\nexport { ExtensionInputComponent } from \"./extension-input.js\";\nexport { ExtensionSelectorComponent } from \"./extension-selector.js\";\nexport { FooterComponent } from \"./footer.js\";\nexport { keyHint, keyText, rawKeyHint } from \"./keybinding-hints.js\";\nexport { LoginDialogComponent } from \"./login-dialog.js\";\nexport { ModelSelectorComponent } from \"./model-selector.js\";\nexport { OAuthSelectorComponent } from \"./oauth-selector.js\";\nexport { type ModelsCallbacks, type ModelsConfig, ScopedModelsSelectorComponent } from \"./scoped-models-selector.js\";\nexport { SessionSelectorComponent } from \"./session-selector.js\";\nexport { type SettingsCallbacks, type SettingsConfig, SettingsSelectorComponent } from \"./settings-selector.js\";\nexport { ShowImagesSelectorComponent } from \"./show-images-selector.js\";\nexport { SkillInvocationMessageComponent } from \"./skill-invocation-message.js\";\nexport { TaskPanelComponent } from \"./task-panel.js\";\nexport { ThemeSelectorComponent } from \"./theme-selector.js\";\nexport { ThinkingSelectorComponent } from \"./thinking-selector.js\";\nexport { ToolExecutionComponent, type ToolExecutionOptions } from \"./tool-execution.js\";\nexport { TreeSelectorComponent } from \"./tree-selector.js\";\nexport { UserMessageComponent } from \"./user-message.js\";\nexport { UserMessageSelectorComponent } from \"./user-message-selector.js\";\nexport { truncateToVisualLines, type VisualTruncateResult } from \"./visual-truncate.js\";\n"]}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Extension chrome: the widget slots above/below the editor and the custom
3
+ * footer/header overrides that extensions can install via the
4
+ * ExtensionUIContext. Extracted from interactive-mode.ts.
5
+ */
6
+ import { type Component, Container, type TUI } from "@kolisachint/hoocode-tui";
7
+ import type { ExtensionWidgetOptions } from "../../core/extensions/index.js";
8
+ import type { FooterDataProvider } from "../../core/footer-data-provider.js";
9
+ import { type Theme } from "./theme/theme.js";
10
+ type DisposableComponent = Component & {
11
+ dispose?(): void;
12
+ };
13
+ /** The slice of the interactive mode the chrome renders into. */
14
+ export interface ExtensionChromeDeps {
15
+ ui: TUI;
16
+ widgetContainerAbove: Container;
17
+ widgetContainerBelow: Container;
18
+ headerContainer: Container;
19
+ /** The built-in footer component (restored when the custom footer is removed). */
20
+ footer: Component;
21
+ footerDataProvider: FooterDataProvider;
22
+ /** The built-in header, once init() created it (undefined before that). */
23
+ getBuiltInHeader(): Component | undefined;
24
+ isToolOutputExpanded(): boolean;
25
+ }
26
+ export declare class ExtensionChrome {
27
+ private readonly deps;
28
+ private widgetsAbove;
29
+ private widgetsBelow;
30
+ /** Custom footer set by an extension; undefined = built-in footer. */
31
+ private footerOverride;
32
+ /** Custom header set by an extension; undefined = built-in header. */
33
+ private headerOverride;
34
+ constructor(deps: ExtensionChromeDeps);
35
+ /** The extension-installed header, if any (combined with the built-in by callers). */
36
+ get customHeader(): DisposableComponent | undefined;
37
+ setWidget(key: string, content: string[] | ((tui: TUI, thm: Theme) => DisposableComponent) | undefined, options?: ExtensionWidgetOptions): void;
38
+ clearWidgets(): void;
39
+ /**
40
+ * Render all extension widgets to the widget container.
41
+ */
42
+ renderWidgets(): void;
43
+ private renderWidgetContainer;
44
+ /**
45
+ * Set a custom footer component, or restore the built-in footer.
46
+ */
47
+ setFooter(factory: ((tui: TUI, thm: Theme, footerData: FooterDataProvider) => DisposableComponent) | undefined): void;
48
+ /**
49
+ * Set a custom header component, or restore the built-in header.
50
+ */
51
+ setHeader(factory: ((tui: TUI, thm: Theme) => DisposableComponent) | undefined): void;
52
+ /** Remove custom footer/header and all widgets (session reset). */
53
+ reset(): void;
54
+ }
55
+ export {};
56
+ //# sourceMappingURL=extension-chrome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-chrome.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/extension-chrome.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAE,SAAS,EAAgB,KAAK,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAC7F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAE7E,OAAO,EAAE,KAAK,KAAK,EAAS,MAAM,kBAAkB,CAAC;AAKrD,KAAK,mBAAmB,GAAG,SAAS,GAAG;IAAE,OAAO,CAAC,IAAI,IAAI,CAAA;CAAE,CAAC;AAE5D,iEAAiE;AACjE,MAAM,WAAW,mBAAmB;IACnC,EAAE,EAAE,GAAG,CAAC;IACR,oBAAoB,EAAE,SAAS,CAAC;IAChC,oBAAoB,EAAE,SAAS,CAAC;IAChC,eAAe,EAAE,SAAS,CAAC;IAC3B,kFAAkF;IAClF,MAAM,EAAE,SAAS,CAAC;IAClB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,2EAA2E;IAC3E,gBAAgB,IAAI,SAAS,GAAG,SAAS,CAAC;IAC1C,oBAAoB,IAAI,OAAO,CAAC;CAChC;AAED,qBAAa,eAAe;IAQf,OAAO,CAAC,QAAQ,CAAC,IAAI;IAPjC,OAAO,CAAC,YAAY,CAA0C;IAC9D,OAAO,CAAC,YAAY,CAA0C;IAC9D,sEAAsE;IACtE,OAAO,CAAC,cAAc,CAA8C;IACpE,sEAAsE;IACtE,OAAO,CAAC,cAAc,CAA8C;IAEpE,YAA6B,IAAI,EAAE,mBAAmB,EAAI;IAE1D,sFAAsF;IACtF,IAAI,YAAY,IAAI,mBAAmB,GAAG,SAAS,CAElD;IAED,SAAS,CACR,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,KAAK,mBAAmB,CAAC,GAAG,SAAS,EAC/E,OAAO,CAAC,EAAE,sBAAsB,GAC9B,IAAI,CAoCN;IAED,YAAY,IAAI,IAAI,CAUnB;IAED;;OAEG;IACH,aAAa,IAAI,IAAI,CAKpB;IAED,OAAO,CAAC,qBAAqB;IAuB7B;;OAEG;IACH,SAAS,CACR,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,kBAAkB,KAAK,mBAAmB,CAAC,GAAG,SAAS,GAClG,IAAI,CAwBN;IAED;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,KAAK,mBAAmB,CAAC,GAAG,SAAS,GAAG,IAAI,CAwCpF;IAED,mEAAmE;IACnE,KAAK,IAAI,IAAI,CAIZ;CACD","sourcesContent":["/**\n * Extension chrome: the widget slots above/below the editor and the custom\n * footer/header overrides that extensions can install via the\n * ExtensionUIContext. Extracted from interactive-mode.ts.\n */\n\nimport { type Component, Container, Spacer, Text, type TUI } from \"@kolisachint/hoocode-tui\";\nimport type { ExtensionWidgetOptions } from \"../../core/extensions/index.js\";\nimport type { FooterDataProvider } from \"../../core/footer-data-provider.js\";\nimport { isExpandable } from \"./resource-display.js\";\nimport { type Theme, theme } from \"./theme/theme.js\";\n\n// Maximum total widget lines to prevent viewport overflow\nconst MAX_WIDGET_LINES = 10;\n\ntype DisposableComponent = Component & { dispose?(): void };\n\n/** The slice of the interactive mode the chrome renders into. */\nexport interface ExtensionChromeDeps {\n\tui: TUI;\n\twidgetContainerAbove: Container;\n\twidgetContainerBelow: Container;\n\theaderContainer: Container;\n\t/** The built-in footer component (restored when the custom footer is removed). */\n\tfooter: Component;\n\tfooterDataProvider: FooterDataProvider;\n\t/** The built-in header, once init() created it (undefined before that). */\n\tgetBuiltInHeader(): Component | undefined;\n\tisToolOutputExpanded(): boolean;\n}\n\nexport class ExtensionChrome {\n\tprivate widgetsAbove = new Map<string, DisposableComponent>();\n\tprivate widgetsBelow = new Map<string, DisposableComponent>();\n\t/** Custom footer set by an extension; undefined = built-in footer. */\n\tprivate footerOverride: DisposableComponent | undefined = undefined;\n\t/** Custom header set by an extension; undefined = built-in header. */\n\tprivate headerOverride: DisposableComponent | undefined = undefined;\n\n\tconstructor(private readonly deps: ExtensionChromeDeps) {}\n\n\t/** The extension-installed header, if any (combined with the built-in by callers). */\n\tget customHeader(): DisposableComponent | undefined {\n\t\treturn this.headerOverride;\n\t}\n\n\tsetWidget(\n\t\tkey: string,\n\t\tcontent: string[] | ((tui: TUI, thm: Theme) => DisposableComponent) | undefined,\n\t\toptions?: ExtensionWidgetOptions,\n\t): void {\n\t\tconst placement = options?.placement ?? \"aboveEditor\";\n\t\tconst removeExisting = (map: Map<string, DisposableComponent>) => {\n\t\t\tconst existing = map.get(key);\n\t\t\tif (existing?.dispose) existing.dispose();\n\t\t\tmap.delete(key);\n\t\t};\n\n\t\tremoveExisting(this.widgetsAbove);\n\t\tremoveExisting(this.widgetsBelow);\n\n\t\tif (content === undefined) {\n\t\t\tthis.renderWidgets();\n\t\t\treturn;\n\t\t}\n\n\t\tlet component: DisposableComponent;\n\n\t\tif (Array.isArray(content)) {\n\t\t\t// Wrap string array in a Container with Text components\n\t\t\tconst container = new Container();\n\t\t\tfor (const line of content.slice(0, MAX_WIDGET_LINES)) {\n\t\t\t\tcontainer.addChild(new Text(line, 1, 0));\n\t\t\t}\n\t\t\tif (content.length > MAX_WIDGET_LINES) {\n\t\t\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"... (widget truncated)\"), 1, 0));\n\t\t\t}\n\t\t\tcomponent = container;\n\t\t} else {\n\t\t\t// Factory function - create component\n\t\t\tcomponent = content(this.deps.ui, theme);\n\t\t}\n\n\t\tconst targetMap = placement === \"belowEditor\" ? this.widgetsBelow : this.widgetsAbove;\n\t\ttargetMap.set(key, component);\n\t\tthis.renderWidgets();\n\t}\n\n\tclearWidgets(): void {\n\t\tfor (const widget of this.widgetsAbove.values()) {\n\t\t\twidget.dispose?.();\n\t\t}\n\t\tfor (const widget of this.widgetsBelow.values()) {\n\t\t\twidget.dispose?.();\n\t\t}\n\t\tthis.widgetsAbove.clear();\n\t\tthis.widgetsBelow.clear();\n\t\tthis.renderWidgets();\n\t}\n\n\t/**\n\t * Render all extension widgets to the widget container.\n\t */\n\trenderWidgets(): void {\n\t\tif (!this.deps.widgetContainerAbove || !this.deps.widgetContainerBelow) return;\n\t\tthis.renderWidgetContainer(this.deps.widgetContainerAbove, this.widgetsAbove, true, true);\n\t\tthis.renderWidgetContainer(this.deps.widgetContainerBelow, this.widgetsBelow, false, false);\n\t\tthis.deps.ui.requestRender();\n\t}\n\n\tprivate renderWidgetContainer(\n\t\tcontainer: Container,\n\t\twidgets: Map<string, DisposableComponent>,\n\t\tspacerWhenEmpty: boolean,\n\t\tleadingSpacer: boolean,\n\t): void {\n\t\tcontainer.clear();\n\n\t\tif (widgets.size === 0) {\n\t\t\tif (spacerWhenEmpty) {\n\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (leadingSpacer) {\n\t\t\tcontainer.addChild(new Spacer(1));\n\t\t}\n\t\tfor (const component of widgets.values()) {\n\t\t\tcontainer.addChild(component);\n\t\t}\n\t}\n\n\t/**\n\t * Set a custom footer component, or restore the built-in footer.\n\t */\n\tsetFooter(\n\t\tfactory: ((tui: TUI, thm: Theme, footerData: FooterDataProvider) => DisposableComponent) | undefined,\n\t): void {\n\t\t// Dispose existing custom footer\n\t\tif (this.footerOverride?.dispose) {\n\t\t\tthis.footerOverride.dispose();\n\t\t}\n\n\t\t// Remove current footer from UI\n\t\tif (this.footerOverride) {\n\t\t\tthis.deps.ui.removeChild(this.footerOverride);\n\t\t} else {\n\t\t\tthis.deps.ui.removeChild(this.deps.footer);\n\t\t}\n\n\t\tif (factory) {\n\t\t\t// Create and add custom footer, passing the data provider\n\t\t\tthis.footerOverride = factory(this.deps.ui, theme, this.deps.footerDataProvider);\n\t\t\tthis.deps.ui.addChild(this.footerOverride);\n\t\t} else {\n\t\t\t// Restore built-in footer\n\t\t\tthis.footerOverride = undefined;\n\t\t\tthis.deps.ui.addChild(this.deps.footer);\n\t\t}\n\n\t\tthis.deps.ui.requestRender();\n\t}\n\n\t/**\n\t * Set a custom header component, or restore the built-in header.\n\t */\n\tsetHeader(factory: ((tui: TUI, thm: Theme) => DisposableComponent) | undefined): void {\n\t\t// Header may not be initialized yet if called during early initialization\n\t\tconst builtInHeader = this.deps.getBuiltInHeader();\n\t\tif (!builtInHeader) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Dispose existing custom header\n\t\tif (this.headerOverride?.dispose) {\n\t\t\tthis.headerOverride.dispose();\n\t\t}\n\n\t\t// Find the index of the current header in the header container\n\t\tconst currentHeader = this.headerOverride || builtInHeader;\n\t\tconst index = this.deps.headerContainer.children.indexOf(currentHeader);\n\n\t\tif (factory) {\n\t\t\t// Create and add custom header\n\t\t\tthis.headerOverride = factory(this.deps.ui, theme);\n\t\t\tif (isExpandable(this.headerOverride)) {\n\t\t\t\tthis.headerOverride.setExpanded(this.deps.isToolOutputExpanded());\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.deps.headerContainer.children[index] = this.headerOverride;\n\t\t\t} else {\n\t\t\t\t// If not found (e.g. builtInHeader was never added), add at the top\n\t\t\t\tthis.deps.headerContainer.children.unshift(this.headerOverride);\n\t\t\t}\n\t\t} else {\n\t\t\t// Restore built-in header\n\t\t\tthis.headerOverride = undefined;\n\t\t\tif (isExpandable(builtInHeader)) {\n\t\t\t\tbuiltInHeader.setExpanded(this.deps.isToolOutputExpanded());\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.deps.headerContainer.children[index] = builtInHeader;\n\t\t\t}\n\t\t}\n\n\t\tthis.deps.ui.requestRender();\n\t}\n\n\t/** Remove custom footer/header and all widgets (session reset). */\n\treset(): void {\n\t\tthis.setFooter(undefined);\n\t\tthis.setHeader(undefined);\n\t\tthis.clearWidgets();\n\t}\n}\n"]}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Extension chrome: the widget slots above/below the editor and the custom
3
+ * footer/header overrides that extensions can install via the
4
+ * ExtensionUIContext. Extracted from interactive-mode.ts.
5
+ */
6
+ import { Container, Spacer, Text } from "@kolisachint/hoocode-tui";
7
+ import { isExpandable } from "./resource-display.js";
8
+ import { theme } from "./theme/theme.js";
9
+ // Maximum total widget lines to prevent viewport overflow
10
+ const MAX_WIDGET_LINES = 10;
11
+ export class ExtensionChrome {
12
+ deps;
13
+ widgetsAbove = new Map();
14
+ widgetsBelow = new Map();
15
+ /** Custom footer set by an extension; undefined = built-in footer. */
16
+ footerOverride = undefined;
17
+ /** Custom header set by an extension; undefined = built-in header. */
18
+ headerOverride = undefined;
19
+ constructor(deps) {
20
+ this.deps = deps;
21
+ }
22
+ /** The extension-installed header, if any (combined with the built-in by callers). */
23
+ get customHeader() {
24
+ return this.headerOverride;
25
+ }
26
+ setWidget(key, content, options) {
27
+ const placement = options?.placement ?? "aboveEditor";
28
+ const removeExisting = (map) => {
29
+ const existing = map.get(key);
30
+ if (existing?.dispose)
31
+ existing.dispose();
32
+ map.delete(key);
33
+ };
34
+ removeExisting(this.widgetsAbove);
35
+ removeExisting(this.widgetsBelow);
36
+ if (content === undefined) {
37
+ this.renderWidgets();
38
+ return;
39
+ }
40
+ let component;
41
+ if (Array.isArray(content)) {
42
+ // Wrap string array in a Container with Text components
43
+ const container = new Container();
44
+ for (const line of content.slice(0, MAX_WIDGET_LINES)) {
45
+ container.addChild(new Text(line, 1, 0));
46
+ }
47
+ if (content.length > MAX_WIDGET_LINES) {
48
+ container.addChild(new Text(theme.fg("muted", "... (widget truncated)"), 1, 0));
49
+ }
50
+ component = container;
51
+ }
52
+ else {
53
+ // Factory function - create component
54
+ component = content(this.deps.ui, theme);
55
+ }
56
+ const targetMap = placement === "belowEditor" ? this.widgetsBelow : this.widgetsAbove;
57
+ targetMap.set(key, component);
58
+ this.renderWidgets();
59
+ }
60
+ clearWidgets() {
61
+ for (const widget of this.widgetsAbove.values()) {
62
+ widget.dispose?.();
63
+ }
64
+ for (const widget of this.widgetsBelow.values()) {
65
+ widget.dispose?.();
66
+ }
67
+ this.widgetsAbove.clear();
68
+ this.widgetsBelow.clear();
69
+ this.renderWidgets();
70
+ }
71
+ /**
72
+ * Render all extension widgets to the widget container.
73
+ */
74
+ renderWidgets() {
75
+ if (!this.deps.widgetContainerAbove || !this.deps.widgetContainerBelow)
76
+ return;
77
+ this.renderWidgetContainer(this.deps.widgetContainerAbove, this.widgetsAbove, true, true);
78
+ this.renderWidgetContainer(this.deps.widgetContainerBelow, this.widgetsBelow, false, false);
79
+ this.deps.ui.requestRender();
80
+ }
81
+ renderWidgetContainer(container, widgets, spacerWhenEmpty, leadingSpacer) {
82
+ container.clear();
83
+ if (widgets.size === 0) {
84
+ if (spacerWhenEmpty) {
85
+ container.addChild(new Spacer(1));
86
+ }
87
+ return;
88
+ }
89
+ if (leadingSpacer) {
90
+ container.addChild(new Spacer(1));
91
+ }
92
+ for (const component of widgets.values()) {
93
+ container.addChild(component);
94
+ }
95
+ }
96
+ /**
97
+ * Set a custom footer component, or restore the built-in footer.
98
+ */
99
+ setFooter(factory) {
100
+ // Dispose existing custom footer
101
+ if (this.footerOverride?.dispose) {
102
+ this.footerOverride.dispose();
103
+ }
104
+ // Remove current footer from UI
105
+ if (this.footerOverride) {
106
+ this.deps.ui.removeChild(this.footerOverride);
107
+ }
108
+ else {
109
+ this.deps.ui.removeChild(this.deps.footer);
110
+ }
111
+ if (factory) {
112
+ // Create and add custom footer, passing the data provider
113
+ this.footerOverride = factory(this.deps.ui, theme, this.deps.footerDataProvider);
114
+ this.deps.ui.addChild(this.footerOverride);
115
+ }
116
+ else {
117
+ // Restore built-in footer
118
+ this.footerOverride = undefined;
119
+ this.deps.ui.addChild(this.deps.footer);
120
+ }
121
+ this.deps.ui.requestRender();
122
+ }
123
+ /**
124
+ * Set a custom header component, or restore the built-in header.
125
+ */
126
+ setHeader(factory) {
127
+ // Header may not be initialized yet if called during early initialization
128
+ const builtInHeader = this.deps.getBuiltInHeader();
129
+ if (!builtInHeader) {
130
+ return;
131
+ }
132
+ // Dispose existing custom header
133
+ if (this.headerOverride?.dispose) {
134
+ this.headerOverride.dispose();
135
+ }
136
+ // Find the index of the current header in the header container
137
+ const currentHeader = this.headerOverride || builtInHeader;
138
+ const index = this.deps.headerContainer.children.indexOf(currentHeader);
139
+ if (factory) {
140
+ // Create and add custom header
141
+ this.headerOverride = factory(this.deps.ui, theme);
142
+ if (isExpandable(this.headerOverride)) {
143
+ this.headerOverride.setExpanded(this.deps.isToolOutputExpanded());
144
+ }
145
+ if (index !== -1) {
146
+ this.deps.headerContainer.children[index] = this.headerOverride;
147
+ }
148
+ else {
149
+ // If not found (e.g. builtInHeader was never added), add at the top
150
+ this.deps.headerContainer.children.unshift(this.headerOverride);
151
+ }
152
+ }
153
+ else {
154
+ // Restore built-in header
155
+ this.headerOverride = undefined;
156
+ if (isExpandable(builtInHeader)) {
157
+ builtInHeader.setExpanded(this.deps.isToolOutputExpanded());
158
+ }
159
+ if (index !== -1) {
160
+ this.deps.headerContainer.children[index] = builtInHeader;
161
+ }
162
+ }
163
+ this.deps.ui.requestRender();
164
+ }
165
+ /** Remove custom footer/header and all widgets (session reset). */
166
+ reset() {
167
+ this.setFooter(undefined);
168
+ this.setHeader(undefined);
169
+ this.clearWidgets();
170
+ }
171
+ }
172
+ //# sourceMappingURL=extension-chrome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-chrome.js","sourceRoot":"","sources":["../../../src/modes/interactive/extension-chrome.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Extension chrome: the widget slots above/below the editor and the custom\n * footer/header overrides that extensions can install via the\n * ExtensionUIContext. Extracted from interactive-mode.ts.\n */\n\nimport { type Component, Container, Spacer, Text, type TUI } from \"@kolisachint/hoocode-tui\";\nimport type { ExtensionWidgetOptions } from \"../../core/extensions/index.js\";\nimport type { FooterDataProvider } from \"../../core/footer-data-provider.js\";\nimport { isExpandable } from \"./resource-display.js\";\nimport { type Theme, theme } from \"./theme/theme.js\";\n\n// Maximum total widget lines to prevent viewport overflow\nconst MAX_WIDGET_LINES = 10;\n\ntype DisposableComponent = Component & { dispose?(): void };\n\n/** The slice of the interactive mode the chrome renders into. */\nexport interface ExtensionChromeDeps {\n\tui: TUI;\n\twidgetContainerAbove: Container;\n\twidgetContainerBelow: Container;\n\theaderContainer: Container;\n\t/** The built-in footer component (restored when the custom footer is removed). */\n\tfooter: Component;\n\tfooterDataProvider: FooterDataProvider;\n\t/** The built-in header, once init() created it (undefined before that). */\n\tgetBuiltInHeader(): Component | undefined;\n\tisToolOutputExpanded(): boolean;\n}\n\nexport class ExtensionChrome {\n\tprivate widgetsAbove = new Map<string, DisposableComponent>();\n\tprivate widgetsBelow = new Map<string, DisposableComponent>();\n\t/** Custom footer set by an extension; undefined = built-in footer. */\n\tprivate footerOverride: DisposableComponent | undefined = undefined;\n\t/** Custom header set by an extension; undefined = built-in header. */\n\tprivate headerOverride: DisposableComponent | undefined = undefined;\n\n\tconstructor(private readonly deps: ExtensionChromeDeps) {}\n\n\t/** The extension-installed header, if any (combined with the built-in by callers). */\n\tget customHeader(): DisposableComponent | undefined {\n\t\treturn this.headerOverride;\n\t}\n\n\tsetWidget(\n\t\tkey: string,\n\t\tcontent: string[] | ((tui: TUI, thm: Theme) => DisposableComponent) | undefined,\n\t\toptions?: ExtensionWidgetOptions,\n\t): void {\n\t\tconst placement = options?.placement ?? \"aboveEditor\";\n\t\tconst removeExisting = (map: Map<string, DisposableComponent>) => {\n\t\t\tconst existing = map.get(key);\n\t\t\tif (existing?.dispose) existing.dispose();\n\t\t\tmap.delete(key);\n\t\t};\n\n\t\tremoveExisting(this.widgetsAbove);\n\t\tremoveExisting(this.widgetsBelow);\n\n\t\tif (content === undefined) {\n\t\t\tthis.renderWidgets();\n\t\t\treturn;\n\t\t}\n\n\t\tlet component: DisposableComponent;\n\n\t\tif (Array.isArray(content)) {\n\t\t\t// Wrap string array in a Container with Text components\n\t\t\tconst container = new Container();\n\t\t\tfor (const line of content.slice(0, MAX_WIDGET_LINES)) {\n\t\t\t\tcontainer.addChild(new Text(line, 1, 0));\n\t\t\t}\n\t\t\tif (content.length > MAX_WIDGET_LINES) {\n\t\t\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"... (widget truncated)\"), 1, 0));\n\t\t\t}\n\t\t\tcomponent = container;\n\t\t} else {\n\t\t\t// Factory function - create component\n\t\t\tcomponent = content(this.deps.ui, theme);\n\t\t}\n\n\t\tconst targetMap = placement === \"belowEditor\" ? this.widgetsBelow : this.widgetsAbove;\n\t\ttargetMap.set(key, component);\n\t\tthis.renderWidgets();\n\t}\n\n\tclearWidgets(): void {\n\t\tfor (const widget of this.widgetsAbove.values()) {\n\t\t\twidget.dispose?.();\n\t\t}\n\t\tfor (const widget of this.widgetsBelow.values()) {\n\t\t\twidget.dispose?.();\n\t\t}\n\t\tthis.widgetsAbove.clear();\n\t\tthis.widgetsBelow.clear();\n\t\tthis.renderWidgets();\n\t}\n\n\t/**\n\t * Render all extension widgets to the widget container.\n\t */\n\trenderWidgets(): void {\n\t\tif (!this.deps.widgetContainerAbove || !this.deps.widgetContainerBelow) return;\n\t\tthis.renderWidgetContainer(this.deps.widgetContainerAbove, this.widgetsAbove, true, true);\n\t\tthis.renderWidgetContainer(this.deps.widgetContainerBelow, this.widgetsBelow, false, false);\n\t\tthis.deps.ui.requestRender();\n\t}\n\n\tprivate renderWidgetContainer(\n\t\tcontainer: Container,\n\t\twidgets: Map<string, DisposableComponent>,\n\t\tspacerWhenEmpty: boolean,\n\t\tleadingSpacer: boolean,\n\t): void {\n\t\tcontainer.clear();\n\n\t\tif (widgets.size === 0) {\n\t\t\tif (spacerWhenEmpty) {\n\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (leadingSpacer) {\n\t\t\tcontainer.addChild(new Spacer(1));\n\t\t}\n\t\tfor (const component of widgets.values()) {\n\t\t\tcontainer.addChild(component);\n\t\t}\n\t}\n\n\t/**\n\t * Set a custom footer component, or restore the built-in footer.\n\t */\n\tsetFooter(\n\t\tfactory: ((tui: TUI, thm: Theme, footerData: FooterDataProvider) => DisposableComponent) | undefined,\n\t): void {\n\t\t// Dispose existing custom footer\n\t\tif (this.footerOverride?.dispose) {\n\t\t\tthis.footerOverride.dispose();\n\t\t}\n\n\t\t// Remove current footer from UI\n\t\tif (this.footerOverride) {\n\t\t\tthis.deps.ui.removeChild(this.footerOverride);\n\t\t} else {\n\t\t\tthis.deps.ui.removeChild(this.deps.footer);\n\t\t}\n\n\t\tif (factory) {\n\t\t\t// Create and add custom footer, passing the data provider\n\t\t\tthis.footerOverride = factory(this.deps.ui, theme, this.deps.footerDataProvider);\n\t\t\tthis.deps.ui.addChild(this.footerOverride);\n\t\t} else {\n\t\t\t// Restore built-in footer\n\t\t\tthis.footerOverride = undefined;\n\t\t\tthis.deps.ui.addChild(this.deps.footer);\n\t\t}\n\n\t\tthis.deps.ui.requestRender();\n\t}\n\n\t/**\n\t * Set a custom header component, or restore the built-in header.\n\t */\n\tsetHeader(factory: ((tui: TUI, thm: Theme) => DisposableComponent) | undefined): void {\n\t\t// Header may not be initialized yet if called during early initialization\n\t\tconst builtInHeader = this.deps.getBuiltInHeader();\n\t\tif (!builtInHeader) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Dispose existing custom header\n\t\tif (this.headerOverride?.dispose) {\n\t\t\tthis.headerOverride.dispose();\n\t\t}\n\n\t\t// Find the index of the current header in the header container\n\t\tconst currentHeader = this.headerOverride || builtInHeader;\n\t\tconst index = this.deps.headerContainer.children.indexOf(currentHeader);\n\n\t\tif (factory) {\n\t\t\t// Create and add custom header\n\t\t\tthis.headerOverride = factory(this.deps.ui, theme);\n\t\t\tif (isExpandable(this.headerOverride)) {\n\t\t\t\tthis.headerOverride.setExpanded(this.deps.isToolOutputExpanded());\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.deps.headerContainer.children[index] = this.headerOverride;\n\t\t\t} else {\n\t\t\t\t// If not found (e.g. builtInHeader was never added), add at the top\n\t\t\t\tthis.deps.headerContainer.children.unshift(this.headerOverride);\n\t\t\t}\n\t\t} else {\n\t\t\t// Restore built-in header\n\t\t\tthis.headerOverride = undefined;\n\t\t\tif (isExpandable(builtInHeader)) {\n\t\t\t\tbuiltInHeader.setExpanded(this.deps.isToolOutputExpanded());\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.deps.headerContainer.children[index] = builtInHeader;\n\t\t\t}\n\t\t}\n\n\t\tthis.deps.ui.requestRender();\n\t}\n\n\t/** Remove custom footer/header and all widgets (session reset). */\n\treset(): void {\n\t\tthis.setFooter(undefined);\n\t\tthis.setHeader(undefined);\n\t\tthis.clearWidgets();\n\t}\n}\n"]}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Extension dialog primitives: the selector, options pane, confirm, text
3
+ * input, multi-line editor, and custom-component dialogs that swap into the
4
+ * editor slot (or an overlay) and restore the prompt editor when done.
5
+ * Extracted from interactive-mode.ts; consumed by the ExtensionUIContext.
6
+ */
7
+ import type { Component, Container, OverlayHandle, OverlayOptions, TUI } from "@kolisachint/hoocode-tui";
8
+ import type { AskQuestion, ExtensionUIDialogOptions } from "../../core/extensions/index.js";
9
+ import type { KeybindingsManager } from "../../core/keybindings.js";
10
+ import { type Theme } from "./theme/theme.js";
11
+ /** The slice of the interactive mode the dialogs render into. */
12
+ export interface ExtensionDialogsDeps {
13
+ ui: TUI;
14
+ editorContainer: Container;
15
+ keybindings: KeybindingsManager;
16
+ /** The prompt editor (read at call time; the editor can be swapped). */
17
+ getEditor(): Component & {
18
+ getText(): string;
19
+ setText(text: string): void;
20
+ };
21
+ }
22
+ export declare class ExtensionDialogs {
23
+ private readonly deps;
24
+ private selector;
25
+ private input;
26
+ private askOptionsPane;
27
+ private editorDialog;
28
+ constructor(deps: ExtensionDialogsDeps);
29
+ /** True while the options pane is on screen (used to queue team approvals). */
30
+ isAskOptionsOpen(): boolean;
31
+ /** Hide whatever dialog is open and restore the prompt editor. */
32
+ reset(): void;
33
+ private restoreEditor;
34
+ /**
35
+ * Show a selector for extensions.
36
+ */
37
+ showSelector(title: string, options: string[], opts?: ExtensionUIDialogOptions): Promise<string | undefined>;
38
+ /**
39
+ * Hide the extension selector.
40
+ */
41
+ hideSelector(): void;
42
+ /**
43
+ * Show the options pane — the agent asking the user one or more questions.
44
+ * Resolves with one answer per question, or undefined if skipped/aborted.
45
+ */
46
+ showAskOptions(questions: AskQuestion[], opts?: ExtensionUIDialogOptions): Promise<string[] | undefined>;
47
+ /**
48
+ * Hide the options pane and restore the editor.
49
+ */
50
+ hideAskOptions(): void;
51
+ /**
52
+ * Show a confirmation dialog for extensions.
53
+ */
54
+ confirm(title: string, message: string, opts?: ExtensionUIDialogOptions): Promise<boolean>;
55
+ /**
56
+ * Show a text input for extensions.
57
+ */
58
+ showInput(title: string, placeholder?: string, opts?: ExtensionUIDialogOptions): Promise<string | undefined>;
59
+ /**
60
+ * Hide the extension input.
61
+ */
62
+ hideInput(): void;
63
+ /**
64
+ * Show a multi-line editor for extensions (with Ctrl+G support).
65
+ */
66
+ showEditor(title: string, prefill?: string): Promise<string | undefined>;
67
+ /**
68
+ * Hide the extension editor.
69
+ */
70
+ hideEditor(): void;
71
+ /** Show a custom component with keyboard focus. Overlay mode renders on top of existing content. */
72
+ showCustom<T>(factory: (tui: TUI, theme: Theme, keybindings: KeybindingsManager, done: (result: T) => void) => (Component & {
73
+ dispose?(): void;
74
+ }) | Promise<Component & {
75
+ dispose?(): void;
76
+ }>, options?: {
77
+ overlay?: boolean;
78
+ overlayOptions?: OverlayOptions | (() => OverlayOptions);
79
+ onHandle?: (handle: OverlayHandle) => void;
80
+ }): Promise<T>;
81
+ }
82
+ //# sourceMappingURL=extension-dialogs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-dialogs.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/extension-dialogs.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Extension dialog primitives: the selector, options pane, confirm, text\n * input, multi-line editor, and custom-component dialogs that swap into the\n * editor slot (or an overlay) and restore the prompt editor when done.\n * Extracted from interactive-mode.ts; consumed by the ExtensionUIContext.\n */\n\nimport type { Component, Container, OverlayHandle, OverlayOptions, TUI } from \"@kolisachint/hoocode-tui\";\nimport type { AskQuestion, ExtensionUIDialogOptions } from \"../../core/extensions/index.js\";\nimport type { KeybindingsManager } from \"../../core/keybindings.js\";\nimport { AskOptionsComponent } from \"./components/ask-options.js\";\nimport { ExtensionEditorComponent } from \"./components/extension-editor.js\";\nimport { ExtensionInputComponent } from \"./components/extension-input.js\";\nimport { ExtensionSelectorComponent } from \"./components/extension-selector.js\";\nimport { type Theme, theme } from \"./theme/theme.js\";\n\n/** The slice of the interactive mode the dialogs render into. */\nexport interface ExtensionDialogsDeps {\n\tui: TUI;\n\teditorContainer: Container;\n\tkeybindings: KeybindingsManager;\n\t/** The prompt editor (read at call time; the editor can be swapped). */\n\tgetEditor(): Component & { getText(): string; setText(text: string): void };\n}\n\nexport class ExtensionDialogs {\n\tprivate selector: ExtensionSelectorComponent | undefined = undefined;\n\tprivate input: ExtensionInputComponent | undefined = undefined;\n\tprivate askOptionsPane: AskOptionsComponent | undefined = undefined;\n\tprivate editorDialog: ExtensionEditorComponent | undefined = undefined;\n\n\tconstructor(private readonly deps: ExtensionDialogsDeps) {}\n\n\t/** True while the options pane is on screen (used to queue team approvals). */\n\tisAskOptionsOpen(): boolean {\n\t\treturn this.askOptionsPane !== undefined;\n\t}\n\n\t/** Hide whatever dialog is open and restore the prompt editor. */\n\treset(): void {\n\t\tif (this.selector) {\n\t\t\tthis.hideSelector();\n\t\t}\n\t\tif (this.input) {\n\t\t\tthis.hideInput();\n\t\t}\n\t\tif (this.askOptionsPane) {\n\t\t\tthis.hideAskOptions();\n\t\t}\n\t\tif (this.editorDialog) {\n\t\t\tthis.hideEditor();\n\t\t}\n\t}\n\n\tprivate restoreEditor(): void {\n\t\tconst editor = this.deps.getEditor();\n\t\tthis.deps.editorContainer.clear();\n\t\tthis.deps.editorContainer.addChild(editor);\n\t\tthis.deps.ui.setFocus(editor);\n\t\tthis.deps.ui.requestRender();\n\t}\n\n\t/**\n\t * Show a selector for extensions.\n\t */\n\tshowSelector(title: string, options: string[], opts?: ExtensionUIDialogOptions): Promise<string | undefined> {\n\t\treturn new Promise((resolve) => {\n\t\t\tif (opts?.signal?.aborted) {\n\t\t\t\tresolve(undefined);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst onAbort = () => {\n\t\t\t\tthis.hideSelector();\n\t\t\t\tresolve(undefined);\n\t\t\t};\n\t\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\tthis.selector = new ExtensionSelectorComponent(\n\t\t\t\ttitle,\n\t\t\t\toptions,\n\t\t\t\t(option) => {\n\t\t\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\tthis.hideSelector();\n\t\t\t\t\tresolve(option);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\tthis.hideSelector();\n\t\t\t\t\tresolve(undefined);\n\t\t\t\t},\n\t\t\t\t{ tui: this.deps.ui, timeout: opts?.timeout },\n\t\t\t);\n\n\t\t\tthis.deps.editorContainer.clear();\n\t\t\tthis.deps.editorContainer.addChild(this.selector);\n\t\t\tthis.deps.ui.setFocus(this.selector);\n\t\t\tthis.deps.ui.requestRender();\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension selector.\n\t */\n\thideSelector(): void {\n\t\tthis.selector?.dispose();\n\t\tthis.selector = undefined;\n\t\tthis.restoreEditor();\n\t}\n\n\t/**\n\t * Show the options pane — the agent asking the user one or more questions.\n\t * Resolves with one answer per question, or undefined if skipped/aborted.\n\t */\n\tshowAskOptions(questions: AskQuestion[], opts?: ExtensionUIDialogOptions): Promise<string[] | undefined> {\n\t\treturn new Promise((resolve) => {\n\t\t\tif (!questions.length || opts?.signal?.aborted) {\n\t\t\t\tresolve(undefined);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst onAbort = () => {\n\t\t\t\tthis.hideAskOptions();\n\t\t\t\tresolve(undefined);\n\t\t\t};\n\t\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\tthis.askOptionsPane = new AskOptionsComponent(\n\t\t\t\tquestions,\n\t\t\t\t(answers) => {\n\t\t\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\tthis.hideAskOptions();\n\t\t\t\t\tresolve(answers);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\tthis.hideAskOptions();\n\t\t\t\t\tresolve(undefined);\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tthis.deps.editorContainer.clear();\n\t\t\tthis.deps.editorContainer.addChild(this.askOptionsPane);\n\t\t\tthis.deps.ui.setFocus(this.askOptionsPane);\n\t\t\tthis.deps.ui.requestRender();\n\t\t});\n\t}\n\n\t/**\n\t * Hide the options pane and restore the editor.\n\t */\n\thideAskOptions(): void {\n\t\tif (!this.askOptionsPane) return;\n\t\tthis.askOptionsPane = undefined;\n\t\tthis.restoreEditor();\n\t}\n\n\t/**\n\t * Show a confirmation dialog for extensions.\n\t */\n\tasync confirm(title: string, message: string, opts?: ExtensionUIDialogOptions): Promise<boolean> {\n\t\tconst result = await this.showSelector(`${title}\\n${message}`, [\"Yes\", \"No\"], opts);\n\t\treturn result === \"Yes\";\n\t}\n\n\t/**\n\t * Show a text input for extensions.\n\t */\n\tshowInput(title: string, placeholder?: string, opts?: ExtensionUIDialogOptions): Promise<string | undefined> {\n\t\treturn new Promise((resolve) => {\n\t\t\tif (opts?.signal?.aborted) {\n\t\t\t\tresolve(undefined);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst onAbort = () => {\n\t\t\t\tthis.hideInput();\n\t\t\t\tresolve(undefined);\n\t\t\t};\n\t\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\tthis.input = new ExtensionInputComponent(\n\t\t\t\ttitle,\n\t\t\t\tplaceholder,\n\t\t\t\t(value) => {\n\t\t\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\tthis.hideInput();\n\t\t\t\t\tresolve(value);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\tthis.hideInput();\n\t\t\t\t\tresolve(undefined);\n\t\t\t\t},\n\t\t\t\t{ tui: this.deps.ui, timeout: opts?.timeout },\n\t\t\t);\n\n\t\t\tthis.deps.editorContainer.clear();\n\t\t\tthis.deps.editorContainer.addChild(this.input);\n\t\t\tthis.deps.ui.setFocus(this.input);\n\t\t\tthis.deps.ui.requestRender();\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension input.\n\t */\n\thideInput(): void {\n\t\tthis.input?.dispose();\n\t\tthis.input = undefined;\n\t\tthis.restoreEditor();\n\t}\n\n\t/**\n\t * Show a multi-line editor for extensions (with Ctrl+G support).\n\t */\n\tshowEditor(title: string, prefill?: string): Promise<string | undefined> {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.editorDialog = new ExtensionEditorComponent(\n\t\t\t\tthis.deps.ui,\n\t\t\t\tthis.deps.keybindings,\n\t\t\t\ttitle,\n\t\t\t\tprefill,\n\t\t\t\t(value) => {\n\t\t\t\t\tthis.hideEditor();\n\t\t\t\t\tresolve(value);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\tthis.hideEditor();\n\t\t\t\t\tresolve(undefined);\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tthis.deps.editorContainer.clear();\n\t\t\tthis.deps.editorContainer.addChild(this.editorDialog);\n\t\t\tthis.deps.ui.setFocus(this.editorDialog);\n\t\t\tthis.deps.ui.requestRender();\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension editor.\n\t */\n\thideEditor(): void {\n\t\tthis.editorDialog = undefined;\n\t\tthis.restoreEditor();\n\t}\n\n\t/** Show a custom component with keyboard focus. Overlay mode renders on top of existing content. */\n\tasync showCustom<T>(\n\t\tfactory: (\n\t\t\ttui: TUI,\n\t\t\ttheme: Theme,\n\t\t\tkeybindings: KeybindingsManager,\n\t\t\tdone: (result: T) => void,\n\t\t) => (Component & { dispose?(): void }) | Promise<Component & { dispose?(): void }>,\n\t\toptions?: {\n\t\t\toverlay?: boolean;\n\t\t\toverlayOptions?: OverlayOptions | (() => OverlayOptions);\n\t\t\tonHandle?: (handle: OverlayHandle) => void;\n\t\t},\n\t): Promise<T> {\n\t\tconst savedText = this.deps.getEditor().getText();\n\t\tconst isOverlay = options?.overlay ?? false;\n\n\t\tconst restoreEditorWithText = () => {\n\t\t\tthis.restoreEditor();\n\t\t\tthis.deps.getEditor().setText(savedText);\n\t\t};\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tlet component: Component & { dispose?(): void };\n\t\t\tlet closed = false;\n\n\t\t\tconst close = (result: T) => {\n\t\t\t\tif (closed) return;\n\t\t\t\tclosed = true;\n\t\t\t\tif (isOverlay) this.deps.ui.hideOverlay();\n\t\t\t\telse restoreEditorWithText();\n\t\t\t\t// Note: both branches above already call requestRender\n\t\t\t\tresolve(result);\n\t\t\t\ttry {\n\t\t\t\t\tcomponent?.dispose?.();\n\t\t\t\t} catch {\n\t\t\t\t\t/* ignore dispose errors */\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tPromise.resolve(factory(this.deps.ui, theme, this.deps.keybindings, close))\n\t\t\t\t.then((c) => {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tcomponent = c;\n\t\t\t\t\tif (isOverlay) {\n\t\t\t\t\t\t// Resolve overlay options - can be static or dynamic function\n\t\t\t\t\t\tconst resolveOptions = (): OverlayOptions | undefined => {\n\t\t\t\t\t\t\tif (options?.overlayOptions) {\n\t\t\t\t\t\t\t\tconst opts =\n\t\t\t\t\t\t\t\t\ttypeof options.overlayOptions === \"function\"\n\t\t\t\t\t\t\t\t\t\t? options.overlayOptions()\n\t\t\t\t\t\t\t\t\t\t: options.overlayOptions;\n\t\t\t\t\t\t\t\treturn opts;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Fallback: use component's width property if available\n\t\t\t\t\t\t\tconst w = (component as { width?: number }).width;\n\t\t\t\t\t\t\treturn w ? { width: w } : undefined;\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst handle = this.deps.ui.showOverlay(component, resolveOptions());\n\t\t\t\t\t\t// Expose handle to caller for visibility control\n\t\t\t\t\t\toptions?.onHandle?.(handle);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.deps.editorContainer.clear();\n\t\t\t\t\t\tthis.deps.editorContainer.addChild(component);\n\t\t\t\t\t\tthis.deps.ui.setFocus(component);\n\t\t\t\t\t\tthis.deps.ui.requestRender();\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tif (!isOverlay) restoreEditorWithText();\n\t\t\t\t\treject(err);\n\t\t\t\t});\n\t\t});\n\t}\n}\n"]}