@effect-tui/react 0.1.1 → 0.1.4

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 (442) hide show
  1. package/dist/jsx-runtime.d.ts +13 -0
  2. package/dist/jsx-runtime.d.ts.map +1 -1
  3. package/dist/jsx-runtime.js.map +1 -1
  4. package/dist/src/codeblock.d.ts.map +1 -1
  5. package/dist/src/codeblock.js.map +1 -1
  6. package/dist/src/components/Divider.d.ts +18 -0
  7. package/dist/src/components/Divider.d.ts.map +1 -0
  8. package/dist/src/components/Divider.js +17 -0
  9. package/dist/src/components/Divider.js.map +1 -0
  10. package/dist/src/components/Markdown.d.ts +66 -0
  11. package/dist/src/components/Markdown.d.ts.map +1 -0
  12. package/dist/src/components/Markdown.js +226 -0
  13. package/dist/src/components/Markdown.js.map +1 -0
  14. package/dist/src/components/MultilineTextInput.d.ts +65 -0
  15. package/dist/src/components/MultilineTextInput.d.ts.map +1 -0
  16. package/dist/src/components/MultilineTextInput.js +607 -0
  17. package/dist/src/components/MultilineTextInput.js.map +1 -0
  18. package/dist/src/components/Overlay.d.ts +46 -0
  19. package/dist/src/components/Overlay.d.ts.map +1 -0
  20. package/dist/src/components/Overlay.js +11 -0
  21. package/dist/src/components/Overlay.js.map +1 -0
  22. package/dist/src/components/Static.d.ts +44 -0
  23. package/dist/src/components/Static.d.ts.map +1 -0
  24. package/dist/src/components/Static.js +53 -0
  25. package/dist/src/components/Static.js.map +1 -0
  26. package/dist/src/components/TextInput.d.ts +53 -0
  27. package/dist/src/components/TextInput.d.ts.map +1 -0
  28. package/dist/src/components/TextInput.js +210 -0
  29. package/dist/src/components/TextInput.js.map +1 -0
  30. package/dist/src/components/index.d.ts +7 -0
  31. package/dist/src/components/index.d.ts.map +1 -0
  32. package/dist/src/components/index.js +7 -0
  33. package/dist/src/components/index.js.map +1 -0
  34. package/dist/src/components/text-editing.d.ts +62 -0
  35. package/dist/src/components/text-editing.d.ts.map +1 -0
  36. package/dist/src/components/text-editing.js +385 -0
  37. package/dist/src/components/text-editing.js.map +1 -0
  38. package/dist/src/console/ConsoleCapture.d.ts +36 -0
  39. package/dist/src/console/ConsoleCapture.d.ts.map +1 -0
  40. package/dist/src/console/ConsoleCapture.js +210 -0
  41. package/dist/src/console/ConsoleCapture.js.map +1 -0
  42. package/dist/src/console/ConsolePopover.d.ts +18 -0
  43. package/dist/src/console/ConsolePopover.d.ts.map +1 -0
  44. package/dist/src/console/ConsolePopover.js +324 -0
  45. package/dist/src/console/ConsolePopover.js.map +1 -0
  46. package/dist/src/console/clipboard.d.ts +10 -0
  47. package/dist/src/console/clipboard.d.ts.map +1 -0
  48. package/dist/src/console/clipboard.js +74 -0
  49. package/dist/src/console/clipboard.js.map +1 -0
  50. package/dist/src/console/index.d.ts +5 -0
  51. package/dist/src/console/index.d.ts.map +1 -0
  52. package/dist/src/console/index.js +33 -0
  53. package/dist/src/console/index.js.map +1 -0
  54. package/dist/src/console/useConsole.d.ts +44 -0
  55. package/dist/src/console/useConsole.d.ts.map +1 -0
  56. package/dist/src/console/useConsole.js +91 -0
  57. package/dist/src/console/useConsole.js.map +1 -0
  58. package/dist/src/debug/DebugOverlay.d.ts +49 -0
  59. package/dist/src/debug/DebugOverlay.d.ts.map +1 -0
  60. package/dist/src/debug/DebugOverlay.js +438 -0
  61. package/dist/src/debug/DebugOverlay.js.map +1 -0
  62. package/dist/src/debug/DiagnosticsPanel.d.ts.map +1 -1
  63. package/dist/src/debug/DiagnosticsPanel.js.map +1 -1
  64. package/dist/src/dev/Toast.d.ts +19 -0
  65. package/dist/src/dev/Toast.d.ts.map +1 -0
  66. package/dist/src/dev/Toast.js +72 -0
  67. package/dist/src/dev/Toast.js.map +1 -0
  68. package/dist/src/dev/index.d.ts +2 -0
  69. package/dist/src/dev/index.d.ts.map +1 -0
  70. package/dist/src/dev/index.js +3 -0
  71. package/dist/src/dev/index.js.map +1 -0
  72. package/dist/src/dev.d.ts +114 -0
  73. package/dist/src/dev.d.ts.map +1 -0
  74. package/dist/src/dev.js +373 -0
  75. package/dist/src/dev.js.map +1 -0
  76. package/dist/src/highlight.d.ts +3 -3
  77. package/dist/src/highlight.d.ts.map +1 -1
  78. package/dist/src/highlight.js.map +1 -1
  79. package/dist/src/hmr-plugin.d.ts +2 -0
  80. package/dist/src/hmr-plugin.d.ts.map +1 -0
  81. package/dist/src/hmr-plugin.js +53 -0
  82. package/dist/src/hmr-plugin.js.map +1 -0
  83. package/dist/src/hooks/index.d.ts +4 -0
  84. package/dist/src/hooks/index.d.ts.map +1 -1
  85. package/dist/src/hooks/index.js +2 -0
  86. package/dist/src/hooks/index.js.map +1 -1
  87. package/dist/src/hooks/use-keyboard.d.ts +11 -0
  88. package/dist/src/hooks/use-keyboard.d.ts.map +1 -1
  89. package/dist/src/hooks/use-keyboard.js +22 -4
  90. package/dist/src/hooks/use-keyboard.js.map +1 -1
  91. package/dist/src/hooks/use-mouse.d.ts +24 -0
  92. package/dist/src/hooks/use-mouse.d.ts.map +1 -0
  93. package/dist/src/hooks/use-mouse.js +41 -0
  94. package/dist/src/hooks/use-mouse.js.map +1 -0
  95. package/dist/src/hooks/use-paste.d.ts +11 -0
  96. package/dist/src/hooks/use-paste.d.ts.map +1 -1
  97. package/dist/src/hooks/use-paste.js +17 -3
  98. package/dist/src/hooks/use-paste.js.map +1 -1
  99. package/dist/src/hooks/use-scroll.d.ts +79 -0
  100. package/dist/src/hooks/use-scroll.d.ts.map +1 -0
  101. package/dist/src/hooks/use-scroll.js +239 -0
  102. package/dist/src/hooks/use-scroll.js.map +1 -0
  103. package/dist/src/hooks/useFrameStats.js.map +1 -1
  104. package/dist/src/hosts/base.d.ts +62 -1
  105. package/dist/src/hosts/base.d.ts.map +1 -1
  106. package/dist/src/hosts/base.js +118 -5
  107. package/dist/src/hosts/base.js.map +1 -1
  108. package/dist/src/hosts/box.d.ts +7 -7
  109. package/dist/src/hosts/box.d.ts.map +1 -1
  110. package/dist/src/hosts/box.js +31 -26
  111. package/dist/src/hosts/box.js.map +1 -1
  112. package/dist/src/hosts/canvas.d.ts +8 -8
  113. package/dist/src/hosts/canvas.d.ts.map +1 -1
  114. package/dist/src/hosts/canvas.js +13 -22
  115. package/dist/src/hosts/canvas.js.map +1 -1
  116. package/dist/src/hosts/codeblock.d.ts +7 -7
  117. package/dist/src/hosts/codeblock.d.ts.map +1 -1
  118. package/dist/src/hosts/codeblock.js +11 -20
  119. package/dist/src/hosts/codeblock.js.map +1 -1
  120. package/dist/src/hosts/flex-container.d.ts +45 -0
  121. package/dist/src/hosts/flex-container.d.ts.map +1 -0
  122. package/dist/src/hosts/flex-container.js +90 -0
  123. package/dist/src/hosts/flex-container.js.map +1 -0
  124. package/dist/src/hosts/hstack.d.ts +6 -11
  125. package/dist/src/hosts/hstack.d.ts.map +1 -1
  126. package/dist/src/hosts/hstack.js +6 -41
  127. package/dist/src/hosts/hstack.js.map +1 -1
  128. package/dist/src/hosts/index.d.ts +4 -0
  129. package/dist/src/hosts/index.d.ts.map +1 -1
  130. package/dist/src/hosts/index.js +10 -0
  131. package/dist/src/hosts/index.js.map +1 -1
  132. package/dist/src/hosts/overlay-item.d.ts +32 -0
  133. package/dist/src/hosts/overlay-item.d.ts.map +1 -0
  134. package/dist/src/hosts/overlay-item.js +54 -0
  135. package/dist/src/hosts/overlay-item.js.map +1 -0
  136. package/dist/src/hosts/overlay.d.ts +30 -0
  137. package/dist/src/hosts/overlay.d.ts.map +1 -0
  138. package/dist/src/hosts/overlay.js +105 -0
  139. package/dist/src/hosts/overlay.js.map +1 -0
  140. package/dist/src/hosts/scroll.d.ts +56 -0
  141. package/dist/src/hosts/scroll.d.ts.map +1 -0
  142. package/dist/src/hosts/scroll.js +204 -0
  143. package/dist/src/hosts/scroll.js.map +1 -0
  144. package/dist/src/hosts/single-child.d.ts +16 -0
  145. package/dist/src/hosts/single-child.d.ts.map +1 -0
  146. package/dist/src/hosts/single-child.js +45 -0
  147. package/dist/src/hosts/single-child.js.map +1 -0
  148. package/dist/src/hosts/spacer.d.ts.map +1 -1
  149. package/dist/src/hosts/spacer.js +7 -3
  150. package/dist/src/hosts/spacer.js.map +1 -1
  151. package/dist/src/hosts/text.d.ts +9 -6
  152. package/dist/src/hosts/text.d.ts.map +1 -1
  153. package/dist/src/hosts/text.js +49 -22
  154. package/dist/src/hosts/text.js.map +1 -1
  155. package/dist/src/hosts/vstack.d.ts +6 -11
  156. package/dist/src/hosts/vstack.d.ts.map +1 -1
  157. package/dist/src/hosts/vstack.js +6 -41
  158. package/dist/src/hosts/vstack.js.map +1 -1
  159. package/dist/src/hosts/zstack.d.ts.map +1 -1
  160. package/dist/src/hosts/zstack.js +16 -5
  161. package/dist/src/hosts/zstack.js.map +1 -1
  162. package/dist/src/index.d.ts +9 -2
  163. package/dist/src/index.d.ts.map +1 -1
  164. package/dist/src/index.js +10 -2
  165. package/dist/src/index.js.map +1 -1
  166. package/dist/src/inline/index.d.ts.map +1 -1
  167. package/dist/src/inline/index.js.map +1 -1
  168. package/dist/src/motion/color-motion-value.d.ts.map +1 -1
  169. package/dist/src/motion/color-motion-value.js.map +1 -1
  170. package/dist/src/motion/color.d.ts +1 -29
  171. package/dist/src/motion/color.d.ts.map +1 -1
  172. package/dist/src/motion/color.js +2 -170
  173. package/dist/src/motion/color.js.map +1 -1
  174. package/dist/src/motion/color.test.js.map +1 -1
  175. package/dist/src/motion/event-emitter.d.ts.map +1 -1
  176. package/dist/src/motion/event-emitter.js.map +1 -1
  177. package/dist/src/motion/frame.js.map +1 -1
  178. package/dist/src/motion/hooks.d.ts.map +1 -1
  179. package/dist/src/motion/hooks.js +8 -3
  180. package/dist/src/motion/hooks.js.map +1 -1
  181. package/dist/src/motion/index.d.ts.map +1 -1
  182. package/dist/src/motion/index.js.map +1 -1
  183. package/dist/src/motion/motion-value.d.ts.map +1 -1
  184. package/dist/src/motion/motion-value.js.map +1 -1
  185. package/dist/src/motion/motion-value.test.js.map +1 -1
  186. package/dist/src/motion/spring-math.d.ts +6 -1
  187. package/dist/src/motion/spring-math.d.ts.map +1 -1
  188. package/dist/src/motion/spring-math.js +6 -1
  189. package/dist/src/motion/spring-math.js.map +1 -1
  190. package/dist/src/motion/types.d.ts.map +1 -1
  191. package/dist/src/motion/types.js.map +1 -1
  192. package/dist/src/profiler.js.map +1 -1
  193. package/dist/src/reconciler/host-config.d.ts +5 -5
  194. package/dist/src/reconciler/host-config.d.ts.map +1 -1
  195. package/dist/src/reconciler/host-config.js +43 -51
  196. package/dist/src/reconciler/host-config.js.map +1 -1
  197. package/dist/src/reconciler/noop-methods.d.ts +29 -0
  198. package/dist/src/reconciler/noop-methods.d.ts.map +1 -0
  199. package/dist/src/reconciler/noop-methods.js +43 -0
  200. package/dist/src/reconciler/noop-methods.js.map +1 -0
  201. package/dist/src/reconciler/types.d.ts +68 -14
  202. package/dist/src/reconciler/types.d.ts.map +1 -1
  203. package/dist/src/remote/Procedures.d.ts +22 -0
  204. package/dist/src/remote/Procedures.d.ts.map +1 -0
  205. package/dist/src/remote/Procedures.js +42 -0
  206. package/dist/src/remote/Procedures.js.map +1 -0
  207. package/dist/src/remote/Router.d.ts +20 -0
  208. package/dist/src/remote/Router.d.ts.map +1 -0
  209. package/dist/src/remote/Router.js +26 -0
  210. package/dist/src/remote/Router.js.map +1 -0
  211. package/dist/src/remote/Server.d.ts +6 -0
  212. package/dist/src/remote/Server.d.ts.map +1 -0
  213. package/dist/src/remote/Server.js +53 -0
  214. package/dist/src/remote/Server.js.map +1 -0
  215. package/dist/src/remote/index.d.ts +18 -0
  216. package/dist/src/remote/index.d.ts.map +1 -0
  217. package/dist/src/remote/index.js +74 -0
  218. package/dist/src/remote/index.js.map +1 -0
  219. package/dist/src/renderer/core/FrameBuilder.d.ts +18 -0
  220. package/dist/src/renderer/core/FrameBuilder.d.ts.map +1 -0
  221. package/dist/src/renderer/core/FrameBuilder.js +38 -0
  222. package/dist/src/renderer/core/FrameBuilder.js.map +1 -0
  223. package/dist/src/renderer/core/RendererState.d.ts +41 -0
  224. package/dist/src/renderer/core/RendererState.d.ts.map +1 -0
  225. package/dist/src/renderer/core/RendererState.js +70 -0
  226. package/dist/src/renderer/core/RendererState.js.map +1 -0
  227. package/dist/src/renderer/core/index.d.ts +3 -0
  228. package/dist/src/renderer/core/index.d.ts.map +1 -0
  229. package/dist/src/renderer/core/index.js +3 -0
  230. package/dist/src/renderer/core/index.js.map +1 -0
  231. package/dist/src/renderer/input/InputProcessor.d.ts +25 -0
  232. package/dist/src/renderer/input/InputProcessor.d.ts.map +1 -0
  233. package/dist/src/renderer/input/InputProcessor.js +81 -0
  234. package/dist/src/renderer/input/InputProcessor.js.map +1 -0
  235. package/dist/src/renderer/input/index.d.ts +2 -0
  236. package/dist/src/renderer/input/index.d.ts.map +1 -0
  237. package/dist/src/renderer/input/index.js +2 -0
  238. package/dist/src/renderer/input/index.js.map +1 -0
  239. package/dist/src/renderer/lifecycle/EventBus.d.ts +41 -0
  240. package/dist/src/renderer/lifecycle/EventBus.d.ts.map +1 -0
  241. package/dist/src/renderer/lifecycle/EventBus.js +78 -0
  242. package/dist/src/renderer/lifecycle/EventBus.js.map +1 -0
  243. package/dist/src/renderer/lifecycle/ResizeManager.d.ts +34 -0
  244. package/dist/src/renderer/lifecycle/ResizeManager.d.ts.map +1 -0
  245. package/dist/src/renderer/lifecycle/ResizeManager.js +47 -0
  246. package/dist/src/renderer/lifecycle/ResizeManager.js.map +1 -0
  247. package/dist/src/renderer/lifecycle/TerminalSetup.d.ts +36 -0
  248. package/dist/src/renderer/lifecycle/TerminalSetup.d.ts.map +1 -0
  249. package/dist/src/renderer/lifecycle/TerminalSetup.js +82 -0
  250. package/dist/src/renderer/lifecycle/TerminalSetup.js.map +1 -0
  251. package/dist/src/renderer/lifecycle/index.d.ts +4 -0
  252. package/dist/src/renderer/lifecycle/index.d.ts.map +1 -0
  253. package/dist/src/renderer/lifecycle/index.js +4 -0
  254. package/dist/src/renderer/lifecycle/index.js.map +1 -0
  255. package/dist/src/renderer/modes/FullscreenRenderer.d.ts +12 -0
  256. package/dist/src/renderer/modes/FullscreenRenderer.d.ts.map +1 -0
  257. package/dist/src/renderer/modes/FullscreenRenderer.js +52 -0
  258. package/dist/src/renderer/modes/FullscreenRenderer.js.map +1 -0
  259. package/dist/src/renderer/modes/InlineRenderer.d.ts +22 -0
  260. package/dist/src/renderer/modes/InlineRenderer.d.ts.map +1 -0
  261. package/dist/src/renderer/modes/InlineRenderer.js +154 -0
  262. package/dist/src/renderer/modes/InlineRenderer.js.map +1 -0
  263. package/dist/src/renderer/modes/RendererMode.d.ts +42 -0
  264. package/dist/src/renderer/modes/RendererMode.d.ts.map +1 -0
  265. package/dist/src/renderer/modes/RendererMode.js +2 -0
  266. package/dist/src/renderer/modes/RendererMode.js.map +1 -0
  267. package/dist/src/renderer/modes/StaticContentRenderer.d.ts +25 -0
  268. package/dist/src/renderer/modes/StaticContentRenderer.d.ts.map +1 -0
  269. package/dist/src/renderer/modes/StaticContentRenderer.js +47 -0
  270. package/dist/src/renderer/modes/StaticContentRenderer.js.map +1 -0
  271. package/dist/src/renderer/modes/index.d.ts +5 -0
  272. package/dist/src/renderer/modes/index.d.ts.map +1 -0
  273. package/dist/src/renderer/modes/index.js +4 -0
  274. package/dist/src/renderer/modes/index.js.map +1 -0
  275. package/dist/src/renderer-context.d.ts +9 -0
  276. package/dist/src/renderer-context.d.ts.map +1 -0
  277. package/dist/src/renderer-context.js +22 -0
  278. package/dist/src/renderer-context.js.map +1 -0
  279. package/dist/src/renderer-types.d.ts +103 -0
  280. package/dist/src/renderer-types.d.ts.map +1 -0
  281. package/dist/src/renderer-types.js +2 -0
  282. package/dist/src/renderer-types.js.map +1 -0
  283. package/dist/src/renderer.d.ts +4 -86
  284. package/dist/src/renderer.d.ts.map +1 -1
  285. package/dist/src/renderer.js +213 -384
  286. package/dist/src/renderer.js.map +1 -1
  287. package/dist/src/test/index.d.ts.map +1 -1
  288. package/dist/src/test/index.js.map +1 -1
  289. package/dist/src/test/mock-streams.d.ts.map +1 -1
  290. package/dist/src/test/mock-streams.js.map +1 -1
  291. package/dist/src/test/render-tui.d.ts.map +1 -1
  292. package/dist/src/test/render-tui.js +2 -5
  293. package/dist/src/test/render-tui.js.map +1 -1
  294. package/dist/src/trace/SpanTree.d.ts.map +1 -1
  295. package/dist/src/trace/SpanTree.js +21 -11
  296. package/dist/src/trace/SpanTree.js.map +1 -1
  297. package/dist/src/trace/format-value.d.ts +15 -0
  298. package/dist/src/trace/format-value.d.ts.map +1 -0
  299. package/dist/src/trace/format-value.js +77 -0
  300. package/dist/src/trace/format-value.js.map +1 -0
  301. package/dist/src/trace/index.d.ts.map +1 -1
  302. package/dist/src/trace/index.js.map +1 -1
  303. package/dist/src/trace/location.js +1 -1
  304. package/dist/src/trace/location.js.map +1 -1
  305. package/dist/src/trace/span-processor.d.ts.map +1 -1
  306. package/dist/src/trace/span-processor.js.map +1 -1
  307. package/dist/src/trace/span-state.d.ts +19 -2
  308. package/dist/src/trace/span-state.d.ts.map +1 -1
  309. package/dist/src/trace/span-state.js +62 -31
  310. package/dist/src/trace/span-state.js.map +1 -1
  311. package/dist/src/trace/tui-logger.js.map +1 -1
  312. package/dist/src/utils/border.d.ts +1 -1
  313. package/dist/src/utils/border.d.ts.map +1 -1
  314. package/dist/src/utils/border.js +6 -0
  315. package/dist/src/utils/border.js.map +1 -1
  316. package/dist/src/utils/flex-layout.d.ts +2 -1
  317. package/dist/src/utils/flex-layout.d.ts.map +1 -1
  318. package/dist/src/utils/flex-layout.js +22 -33
  319. package/dist/src/utils/flex-layout.js.map +1 -1
  320. package/dist/src/utils/index.d.ts +1 -1
  321. package/dist/src/utils/index.d.ts.map +1 -1
  322. package/dist/src/utils/index.js +1 -1
  323. package/dist/src/utils/index.js.map +1 -1
  324. package/dist/src/utils/padding.d.ts.map +1 -1
  325. package/dist/src/utils/padding.js.map +1 -1
  326. package/dist/src/utils/styles.d.ts +20 -1
  327. package/dist/src/utils/styles.d.ts.map +1 -1
  328. package/dist/src/utils/styles.js +36 -1
  329. package/dist/src/utils/styles.js.map +1 -1
  330. package/dist/src/visualize/index.d.ts +8 -19
  331. package/dist/src/visualize/index.d.ts.map +1 -1
  332. package/dist/src/visualize/index.js +11 -25
  333. package/dist/src/visualize/index.js.map +1 -1
  334. package/dist/tsconfig.tsbuildinfo +1 -1
  335. package/jsx-dev-runtime.ts +5 -0
  336. package/jsx-runtime.ts +54 -0
  337. package/package.json +124 -92
  338. package/src/codeblock.tsx +34 -34
  339. package/src/components/Divider.tsx +23 -0
  340. package/src/components/Markdown.tsx +380 -0
  341. package/src/components/MultilineTextInput.tsx +749 -0
  342. package/src/components/Overlay.tsx +56 -0
  343. package/src/components/Static.tsx +68 -0
  344. package/src/components/TextInput.tsx +285 -0
  345. package/src/components/index.ts +6 -0
  346. package/src/components/text-editing.ts +464 -0
  347. package/src/console/ConsoleCapture.ts +272 -0
  348. package/src/console/ConsolePopover.tsx +487 -0
  349. package/src/console/clipboard.ts +81 -0
  350. package/src/console/index.ts +42 -0
  351. package/src/console/useConsole.ts +129 -0
  352. package/src/debug/DebugOverlay.ts +557 -0
  353. package/src/debug/DiagnosticsPanel.tsx +27 -27
  354. package/src/dev/Toast.tsx +117 -0
  355. package/src/dev/index.ts +2 -0
  356. package/src/dev.tsx +489 -0
  357. package/src/highlight.ts +46 -46
  358. package/src/hmr-plugin.ts +61 -0
  359. package/src/hooks/index.ts +4 -0
  360. package/src/hooks/use-keyboard.ts +44 -24
  361. package/src/hooks/use-mouse.ts +51 -0
  362. package/src/hooks/use-paste.ts +21 -6
  363. package/src/hooks/use-scroll.ts +386 -0
  364. package/src/hooks/useFrameStats.ts +17 -17
  365. package/src/hosts/base.ts +180 -59
  366. package/src/hosts/box.ts +117 -96
  367. package/src/hosts/canvas.ts +137 -141
  368. package/src/hosts/codeblock.ts +117 -133
  369. package/src/hosts/flex-container.ts +124 -0
  370. package/src/hosts/hstack.ts +11 -59
  371. package/src/hosts/index.ts +24 -14
  372. package/src/hosts/overlay-item.ts +72 -0
  373. package/src/hosts/overlay.ts +125 -0
  374. package/src/hosts/scroll.ts +255 -0
  375. package/src/hosts/single-child.ts +52 -0
  376. package/src/hosts/spacer.ts +30 -26
  377. package/src/hosts/text.ts +198 -164
  378. package/src/hosts/vstack.ts +11 -59
  379. package/src/hosts/zstack.ts +79 -67
  380. package/src/index.ts +44 -19
  381. package/src/inline/index.tsx +123 -123
  382. package/src/motion/color-motion-value.ts +67 -67
  383. package/src/motion/color.test.ts +107 -107
  384. package/src/motion/color.ts +9 -190
  385. package/src/motion/event-emitter.ts +20 -20
  386. package/src/motion/frame.ts +35 -35
  387. package/src/motion/hooks.ts +144 -139
  388. package/src/motion/index.ts +10 -10
  389. package/src/motion/motion-value.test.ts +207 -207
  390. package/src/motion/motion-value.ts +112 -112
  391. package/src/motion/spring-math.ts +88 -83
  392. package/src/motion/types.ts +25 -25
  393. package/src/profiler.ts +50 -50
  394. package/src/reconciler/host-config.ts +152 -174
  395. package/src/reconciler/noop-methods.ts +55 -0
  396. package/src/reconciler/types.ts +112 -46
  397. package/src/remote/Procedures.ts +52 -0
  398. package/src/remote/Router.ts +58 -0
  399. package/src/remote/Server.ts +76 -0
  400. package/src/remote/index.ts +90 -0
  401. package/src/renderer/core/FrameBuilder.ts +49 -0
  402. package/src/renderer/core/RendererState.ts +80 -0
  403. package/src/renderer/core/index.ts +2 -0
  404. package/src/renderer/input/InputProcessor.ts +94 -0
  405. package/src/renderer/input/index.ts +1 -0
  406. package/src/renderer/lifecycle/EventBus.ts +90 -0
  407. package/src/renderer/lifecycle/ResizeManager.ts +65 -0
  408. package/src/renderer/lifecycle/TerminalSetup.ts +105 -0
  409. package/src/renderer/lifecycle/index.ts +3 -0
  410. package/src/renderer/modes/FullscreenRenderer.ts +53 -0
  411. package/src/renderer/modes/InlineRenderer.ts +178 -0
  412. package/src/renderer/modes/RendererMode.ts +46 -0
  413. package/src/renderer/modes/StaticContentRenderer.ts +56 -0
  414. package/src/renderer/modes/index.ts +4 -0
  415. package/src/renderer-context.ts +27 -0
  416. package/src/renderer-types.ts +109 -0
  417. package/src/renderer.ts +391 -642
  418. package/src/test/index.ts +5 -5
  419. package/src/test/mock-streams.ts +115 -115
  420. package/src/test/render-tui.ts +84 -87
  421. package/src/utils/border.ts +79 -73
  422. package/src/utils/flex-layout.ts +80 -93
  423. package/src/utils/index.ts +1 -1
  424. package/src/utils/padding.ts +27 -27
  425. package/src/utils/styles.ts +50 -7
  426. package/src/visualize/index.tsx +225 -240
  427. package/dist/src/output.d.ts +0 -47
  428. package/dist/src/output.d.ts.map +0 -1
  429. package/dist/src/output.js +0 -125
  430. package/dist/src/output.js.map +0 -1
  431. package/dist/src/terminal.d.ts +0 -37
  432. package/dist/src/terminal.d.ts.map +0 -1
  433. package/dist/src/terminal.js +0 -65
  434. package/dist/src/terminal.js.map +0 -1
  435. package/src/output.ts +0 -156
  436. package/src/terminal.ts +0 -67
  437. package/src/trace/SpanTree.tsx +0 -195
  438. package/src/trace/index.tsx +0 -205
  439. package/src/trace/location.ts +0 -90
  440. package/src/trace/span-processor.ts +0 -65
  441. package/src/trace/span-state.ts +0 -286
  442. package/src/trace/tui-logger.ts +0 -72
@@ -0,0 +1,487 @@
1
+ // Console popover component for displaying captured console output
2
+ // Shows logs in a scrollable overlay with text selection and copy functionality
3
+
4
+ import { useState, useCallback, useEffect, useMemo, useRef } from "react"
5
+ import { Colors, type ColorValue } from "@effect-tui/core"
6
+ import { useTerminalSize } from "../renderer.js"
7
+ import { useKeyboard } from "../hooks/use-keyboard.js"
8
+ import { useMouse } from "../hooks/use-mouse.js"
9
+ import { useScroll } from "../hooks/use-scroll.js"
10
+ import { getConsoleCapture, type LogEntry, type LogLevel } from "./ConsoleCapture.js"
11
+ import { copyToClipboardSync, copyToClipboard } from "./clipboard.js"
12
+
13
+ // ─────────────────────────────────────────────────────────────
14
+ // Types
15
+ // ─────────────────────────────────────────────────────────────
16
+
17
+ export interface ConsolePopoverProps {
18
+ /** Initial height as percentage of terminal (default: 30) */
19
+ heightPercent?: number
20
+ /** Custom copy handler (default: system clipboard) */
21
+ onCopy?: (text: string) => void
22
+ /** Show file location for each log entry */
23
+ showLocations?: boolean
24
+ /** Minimum height percent (default: 10) */
25
+ minHeightPercent?: number
26
+ /** Maximum height percent (default: 80) */
27
+ maxHeightPercent?: number
28
+ /** Render mode - inline skips the full-height zstack wrapper */
29
+ mode?: "overlay" | "inline"
30
+ /** Fixed height in lines for inline mode */
31
+ fixedHeight?: number
32
+ }
33
+
34
+ interface SelectionPoint {
35
+ line: number
36
+ col: number
37
+ }
38
+
39
+ // ─────────────────────────────────────────────────────────────
40
+ // Color scheme
41
+ // ─────────────────────────────────────────────────────────────
42
+
43
+ const LOG_COLORS: Record<LogLevel, ColorValue> = {
44
+ LOG: Colors.white,
45
+ INFO: Colors.cyan,
46
+ WARN: Colors.yellow,
47
+ ERROR: Colors.red,
48
+ DEBUG: Colors.gray(12),
49
+ }
50
+
51
+ const TITLE_BG = Colors.gray(4)
52
+ const TITLE_FG = Colors.white
53
+ const CONTENT_BG = Colors.gray(2)
54
+ const SELECTION_BG = Colors.rgb(60, 90, 140)
55
+
56
+ // ─────────────────────────────────────────────────────────────
57
+ // Helpers
58
+ // ─────────────────────────────────────────────────────────────
59
+
60
+ function formatTimestamp(date: Date): string {
61
+ const h = date.getHours().toString().padStart(2, "0")
62
+ const m = date.getMinutes().toString().padStart(2, "0")
63
+ const s = date.getSeconds().toString().padStart(2, "0")
64
+ return `${h}:${m}:${s}`
65
+ }
66
+
67
+ function formatLocation(loc?: { file: string; line: number }): string {
68
+ if (!loc) return ""
69
+ const parts = loc.file.split("/")
70
+ const filename = parts[parts.length - 1]
71
+ return `${filename}:${loc.line}`
72
+ }
73
+
74
+ function wrapLine(text: string, maxWidth: number): string[] {
75
+ if (text.length <= maxWidth) return [text]
76
+
77
+ const lines: string[] = []
78
+ let remaining = text
79
+
80
+ while (remaining.length > 0) {
81
+ if (remaining.length <= maxWidth) {
82
+ lines.push(remaining)
83
+ break
84
+ }
85
+
86
+ let breakAt = maxWidth
87
+ const lastSpace = remaining.lastIndexOf(" ", maxWidth)
88
+ if (lastSpace > maxWidth * 0.5) {
89
+ breakAt = lastSpace
90
+ }
91
+
92
+ lines.push(remaining.slice(0, breakAt))
93
+ remaining = remaining.slice(breakAt).trimStart()
94
+ }
95
+
96
+ return lines
97
+ }
98
+
99
+ /** Normalize selection so start is before end */
100
+ function normalizeSelection(
101
+ anchor: SelectionPoint,
102
+ head: SelectionPoint,
103
+ ): [SelectionPoint, SelectionPoint] {
104
+ if (anchor.line < head.line || (anchor.line === head.line && anchor.col <= head.col)) {
105
+ return [anchor, head]
106
+ }
107
+ return [head, anchor]
108
+ }
109
+
110
+ /** Get selection bounds for a specific line */
111
+ function getLineSelection(
112
+ lineIndex: number,
113
+ lineLength: number,
114
+ start: SelectionPoint,
115
+ end: SelectionPoint,
116
+ ): { startCol: number; endCol: number } | null {
117
+ if (lineIndex < start.line || lineIndex > end.line) return null
118
+
119
+ const startCol = lineIndex === start.line ? Math.min(start.col, lineLength) : 0
120
+ const endCol = lineIndex === end.line ? Math.min(end.col, lineLength) : lineLength
121
+
122
+ if (startCol >= endCol && lineIndex === start.line && lineIndex === end.line) return null
123
+
124
+ return { startCol, endCol }
125
+ }
126
+
127
+ // ─────────────────────────────────────────────────────────────
128
+ // Component
129
+ // ─────────────────────────────────────────────────────────────
130
+
131
+ export function ConsolePopover({
132
+ heightPercent: initialHeightPercent = 30,
133
+ onCopy,
134
+ showLocations = true,
135
+ minHeightPercent = 10,
136
+ maxHeightPercent = 80,
137
+ mode = "overlay",
138
+ fixedHeight = 10,
139
+ }: ConsolePopoverProps) {
140
+ const { width: termWidth, height: termHeight } = useTerminalSize()
141
+ const capture = useMemo(() => getConsoleCapture(), [])
142
+
143
+ // Log entries state
144
+ const [entries, setEntries] = useState<LogEntry[]>(() => capture.getEntries())
145
+
146
+ // Size state (adjustable with +/-)
147
+ const [sizePercent, setSizePercent] = useState(initialHeightPercent)
148
+ const [inlineHeight, setInlineHeight] = useState(fixedHeight)
149
+
150
+ // Selection state
151
+ const [selectionAnchor, setSelectionAnchor] = useState<SelectionPoint | null>(null)
152
+ const [selectionHead, setSelectionHead] = useState<SelectionPoint | null>(null)
153
+ const isSelectingRef = useRef(false)
154
+
155
+ // Feedback state
156
+ const [feedback, setFeedback] = useState<string | null>(null)
157
+
158
+ // Calculate dimensions - inline mode uses adjustable fixed height
159
+ const popoverHeight = mode === "inline"
160
+ ? inlineHeight
161
+ : Math.max(5, Math.floor(termHeight * (sizePercent / 100)))
162
+ const contentStartY = termHeight - popoverHeight + 1 // +1 for title bar
163
+
164
+ // Use scroll hook for content scrolling
165
+ const { state: scrollState, scrollProps, scrollToEnd, scrollToStart, scrollBy } = useScroll({
166
+ axis: "vertical",
167
+ sticky: true,
168
+ enableKeyboard: false,
169
+ })
170
+
171
+ // Subscribe to new log entries
172
+ useEffect(() => {
173
+ const handleEntry = (_entry: LogEntry) => {
174
+ setEntries(capture.getEntries())
175
+ }
176
+
177
+ capture.on("entry", handleEntry)
178
+ return () => {
179
+ capture.off("entry", handleEntry)
180
+ }
181
+ }, [capture])
182
+
183
+ // Compute display lines (each entry may span multiple lines)
184
+ const displayLines = useMemo(() => {
185
+ const lines: Array<{
186
+ entryIndex: number
187
+ lineIndex: number
188
+ text: string
189
+ level: LogLevel
190
+ }> = []
191
+
192
+ const availableWidth = termWidth - 1 // Leave room for scrollbar
193
+
194
+ for (let i = 0; i < entries.length; i++) {
195
+ const entry = entries[i]
196
+ const timestamp = formatTimestamp(entry.timestamp)
197
+ const location = showLocations ? formatLocation(entry.location) : ""
198
+
199
+ const prefix = `[${timestamp}] [${entry.level}] `
200
+ const suffix = location ? ` (${location})` : ""
201
+
202
+ const messageLines = entry.message.split("\n")
203
+
204
+ for (let j = 0; j < messageLines.length; j++) {
205
+ const msgLine = messageLines[j]
206
+ const isFirstLine = j === 0
207
+ const isLastLine = j === messageLines.length - 1
208
+
209
+ const linePrefix = isFirstLine ? prefix : " "
210
+ const lineSuffix = isLastLine ? suffix : ""
211
+
212
+ const fullLine = linePrefix + msgLine + lineSuffix
213
+ const wrappedLines = wrapLine(fullLine, availableWidth)
214
+
215
+ for (const wrappedLine of wrappedLines) {
216
+ lines.push({
217
+ entryIndex: i,
218
+ lineIndex: lines.length,
219
+ text: wrappedLine,
220
+ level: entry.level,
221
+ })
222
+ }
223
+ }
224
+ }
225
+
226
+ return lines
227
+ }, [entries, termWidth, showLocations])
228
+
229
+ // Get selected text
230
+ const getSelectedText = useCallback((): string => {
231
+ if (!selectionAnchor || !selectionHead) return ""
232
+
233
+ const [start, end] = normalizeSelection(selectionAnchor, selectionHead)
234
+ const lines: string[] = []
235
+
236
+ for (let i = start.line; i <= end.line && i < displayLines.length; i++) {
237
+ const lineText = displayLines[i]?.text ?? ""
238
+ const startCol = i === start.line ? Math.min(start.col, lineText.length) : 0
239
+ const endCol = i === end.line ? Math.min(end.col, lineText.length) : lineText.length
240
+ lines.push(lineText.slice(startCol, endCol))
241
+ }
242
+
243
+ return lines.join("\n")
244
+ }, [selectionAnchor, selectionHead, displayLines])
245
+
246
+ // Copy selection to clipboard
247
+ const handleCopy = useCallback(() => {
248
+ const text = getSelectedText()
249
+ if (!text) return
250
+
251
+ if (onCopy) {
252
+ onCopy(text)
253
+ } else {
254
+ const copied = copyToClipboardSync(text)
255
+ if (!copied) {
256
+ copyToClipboard(text)
257
+ }
258
+ }
259
+
260
+ setFeedback("Copied!")
261
+ setTimeout(() => setFeedback(null), 1000)
262
+ }, [getSelectedText, onCopy])
263
+
264
+ // Save logs to tmp file
265
+ const handleSave = useCallback(async () => {
266
+ const allText = displayLines.map((l) => l.text).join("\n")
267
+ const tmpPath = `/tmp/console-logs-${Date.now()}.txt`
268
+
269
+ try {
270
+ await Bun.write(tmpPath, allText)
271
+
272
+ // Copy path to clipboard
273
+ const copied = copyToClipboardSync(tmpPath)
274
+ if (!copied) {
275
+ await copyToClipboard(tmpPath)
276
+ }
277
+
278
+ setFeedback(`Saved: ${tmpPath}`)
279
+ setTimeout(() => setFeedback(null), 2000)
280
+ } catch (err) {
281
+ setFeedback("Save failed")
282
+ setTimeout(() => setFeedback(null), 1000)
283
+ }
284
+ }, [displayLines])
285
+
286
+ // Convert mouse position to selection point
287
+ const mouseToSelectionPoint = useCallback(
288
+ (mouseX: number, mouseY: number): SelectionPoint | null => {
289
+ const relativeY = mouseY - contentStartY
290
+ const lineIndex = relativeY + scrollState.offset
291
+
292
+ if (lineIndex < 0 || lineIndex >= displayLines.length) return null
293
+
294
+ // X is relative to left edge of content
295
+ const col = Math.max(0, mouseX)
296
+
297
+ return { line: Math.floor(lineIndex), col }
298
+ },
299
+ [contentStartY, scrollState.offset, displayLines.length],
300
+ )
301
+
302
+ // Keyboard handler
303
+ useKeyboard(
304
+ useCallback(
305
+ (key) => {
306
+ // Ctrl+Y or Ctrl+C - Copy selection
307
+ if (key.ctrl && !key.shift && key.name === "char" && (key.text === "y" || key.text === "c")) {
308
+ handleCopy()
309
+ return
310
+ }
311
+
312
+ // Ctrl+S - Save logs to file
313
+ if (key.ctrl && !key.shift && key.name === "char" && key.text === "s") {
314
+ handleSave()
315
+ return
316
+ }
317
+
318
+ // Size controls
319
+ if (key.name === "char" && (key.text === "+" || key.text === "=")) {
320
+ if (mode === "inline") {
321
+ setInlineHeight((prev) => Math.min(30, prev + 2))
322
+ } else {
323
+ setSizePercent((prev) => Math.min(maxHeightPercent, prev + 5))
324
+ }
325
+ return
326
+ }
327
+ if (key.name === "char" && key.text === "-") {
328
+ if (mode === "inline") {
329
+ setInlineHeight((prev) => Math.max(4, prev - 2))
330
+ } else {
331
+ setSizePercent((prev) => Math.max(minHeightPercent, prev - 5))
332
+ }
333
+ return
334
+ }
335
+
336
+ // Shift+up/down - jump to top/bottom
337
+ if (key.shift && key.name === "up") {
338
+ scrollToStart()
339
+ return
340
+ }
341
+ if (key.shift && key.name === "down") {
342
+ scrollToEnd()
343
+ return
344
+ }
345
+
346
+ // Regular up/down - scroll
347
+ if (key.name === "up") {
348
+ scrollBy(-1)
349
+ return
350
+ }
351
+ if (key.name === "down") {
352
+ scrollBy(1)
353
+ return
354
+ }
355
+
356
+ // Home/End
357
+ if (key.name === "home") {
358
+ scrollToStart()
359
+ return
360
+ }
361
+ if (key.name === "end") {
362
+ scrollToEnd()
363
+ return
364
+ }
365
+ },
366
+ [handleCopy, handleSave, maxHeightPercent, minHeightPercent, scrollToStart, scrollToEnd, scrollBy],
367
+ ),
368
+ )
369
+
370
+ // Mouse handler for text selection
371
+ useMouse(
372
+ useCallback(
373
+ (mouse) => {
374
+ // Only handle events in content area
375
+ if (mouse.y < contentStartY || mouse.y >= termHeight) return
376
+
377
+ const point = mouseToSelectionPoint(mouse.x, mouse.y)
378
+ if (!point) return
379
+
380
+ if (mouse.action === "press") {
381
+ // Start new selection
382
+ setSelectionAnchor(point)
383
+ setSelectionHead(point)
384
+ isSelectingRef.current = true
385
+ } else if (mouse.action === "drag" && isSelectingRef.current) {
386
+ // Extend selection
387
+ setSelectionHead(point)
388
+
389
+ // Auto-scroll when dragging near edges
390
+ const relativeY = mouse.y - contentStartY
391
+ const viewportHeight = popoverHeight - 1 // -1 for title
392
+ if (relativeY <= 1) {
393
+ scrollBy(-1)
394
+ } else if (relativeY >= viewportHeight - 2) {
395
+ scrollBy(1)
396
+ }
397
+ } else if (mouse.action === "release") {
398
+ isSelectingRef.current = false
399
+ }
400
+ },
401
+ [contentStartY, termHeight, mouseToSelectionPoint, popoverHeight, scrollBy],
402
+ ),
403
+ { action: "any", button: "left" },
404
+ )
405
+
406
+ // Title bar text
407
+ const titleText = feedback ?? "Console"
408
+ const hints = `[\` toggle] [~ screenshot] [+/- ${sizePercent}%]`
409
+
410
+ // Render a line with selection highlighting
411
+ const renderLine = (line: (typeof displayLines)[0], index: number) => {
412
+ const paddedText = line.text.padEnd(termWidth - 1, " ")
413
+
414
+ // Check if this line has selection
415
+ if (selectionAnchor && selectionHead) {
416
+ const [start, end] = normalizeSelection(selectionAnchor, selectionHead)
417
+ const sel = getLineSelection(index, paddedText.length, start, end)
418
+
419
+ if (sel) {
420
+ const before = paddedText.slice(0, sel.startCol)
421
+ const selected = paddedText.slice(sel.startCol, sel.endCol)
422
+ const after = paddedText.slice(sel.endCol)
423
+
424
+ return (
425
+ <hstack key={index}>
426
+ {before.length > 0 && (
427
+ <text fg={LOG_COLORS[line.level]} bg={CONTENT_BG}>
428
+ {before}
429
+ </text>
430
+ )}
431
+ <text fg={Colors.white} bg={SELECTION_BG}>
432
+ {selected}
433
+ </text>
434
+ {after.length > 0 && (
435
+ <text fg={LOG_COLORS[line.level]} bg={CONTENT_BG}>
436
+ {after}
437
+ </text>
438
+ )}
439
+ </hstack>
440
+ )
441
+ }
442
+ }
443
+
444
+ // No selection on this line
445
+ return (
446
+ <text key={index} fg={LOG_COLORS[line.level]} bg={CONTENT_BG}>
447
+ {paddedText}
448
+ </text>
449
+ )
450
+ }
451
+
452
+ // Inline mode title bar
453
+ const inlineHints = `[\` toggle] [+/- size]`
454
+
455
+ const consoleContent = (
456
+ <box width={termWidth} height={popoverHeight} bg={CONTENT_BG}>
457
+ <vstack width={termWidth} height={popoverHeight}>
458
+ {/* Title bar */}
459
+ <hstack height={1} bg={TITLE_BG}>
460
+ <text fg={feedback ? Colors.green : TITLE_FG} bg={TITLE_BG}>
461
+ {" " + titleText}
462
+ </text>
463
+ <spacer />
464
+ <text fg={Colors.gray(14)} bg={TITLE_BG}>
465
+ {(mode === "inline" ? inlineHints : hints) + " "}
466
+ </text>
467
+ </hstack>
468
+
469
+ {/* Scrollable content */}
470
+ <scroll {...scrollProps} sticky>
471
+ <vstack>
472
+ {displayLines.length === 0 ? (
473
+ <text fg={Colors.gray(10)} bg={CONTENT_BG}>
474
+ No console output yet
475
+ </text>
476
+ ) : (
477
+ displayLines.map((line, i) => renderLine(line, i))
478
+ )}
479
+ </vstack>
480
+ </scroll>
481
+ </vstack>
482
+ </box>
483
+ )
484
+
485
+ // Just render the box - parent handles positioning (zstack alignment or vstack order)
486
+ return consoleContent
487
+ }
@@ -0,0 +1,81 @@
1
+ // Platform-aware clipboard helper for console copy functionality
2
+
3
+ import { spawn } from "node:child_process"
4
+
5
+ /**
6
+ * Copy text to system clipboard.
7
+ * Uses pbcopy on macOS, clip.exe on Windows, xclip on Linux.
8
+ */
9
+ export function copyToClipboard(text: string): Promise<boolean> {
10
+ return new Promise((resolve) => {
11
+ let cmd: string
12
+ let args: string[]
13
+
14
+ switch (process.platform) {
15
+ case "darwin":
16
+ cmd = "pbcopy"
17
+ args = []
18
+ break
19
+ case "win32":
20
+ cmd = "clip"
21
+ args = []
22
+ break
23
+ default:
24
+ // Linux/other - try xclip first
25
+ cmd = "xclip"
26
+ args = ["-selection", "clipboard"]
27
+ break
28
+ }
29
+
30
+ try {
31
+ const proc = spawn(cmd, args, { stdio: ["pipe", "ignore", "ignore"] })
32
+
33
+ proc.on("error", () => {
34
+ // Command not found or failed to spawn
35
+ resolve(false)
36
+ })
37
+
38
+ proc.on("close", (code) => {
39
+ resolve(code === 0)
40
+ })
41
+
42
+ proc.stdin?.write(text)
43
+ proc.stdin?.end()
44
+ } catch {
45
+ resolve(false)
46
+ }
47
+ })
48
+ }
49
+
50
+ /**
51
+ * Sync version using Bun.spawn if available (preferred for TUI apps)
52
+ */
53
+ export function copyToClipboardSync(text: string): boolean {
54
+ if (typeof Bun !== "undefined") {
55
+ try {
56
+ let cmd: string[]
57
+ switch (process.platform) {
58
+ case "darwin":
59
+ cmd = ["pbcopy"]
60
+ break
61
+ case "win32":
62
+ cmd = ["clip"]
63
+ break
64
+ default:
65
+ cmd = ["xclip", "-selection", "clipboard"]
66
+ break
67
+ }
68
+
69
+ const proc = Bun.spawn(cmd, { stdin: "pipe" })
70
+ proc.stdin.write(text)
71
+ proc.stdin.end()
72
+ return true
73
+ } catch {
74
+ return false
75
+ }
76
+ }
77
+
78
+ // Fallback: can't do sync copy without Bun
79
+ // In this case, the caller should use the async version
80
+ return false
81
+ }
@@ -0,0 +1,42 @@
1
+ // Console capture and popover for TUI debugging
2
+ //
3
+ // Usage:
4
+ // ```tsx
5
+ // import { ConsolePopover, useConsole } from "@effect-tui/react/console"
6
+ //
7
+ // function App() {
8
+ // const { visible } = useConsole({ autoShowOnError: true })
9
+ //
10
+ // return (
11
+ // <zstack>
12
+ // <MainContent />
13
+ // {visible && <ConsolePopover position="bottom" heightPercent={30} />}
14
+ // </zstack>
15
+ // )
16
+ // }
17
+ // ```
18
+ //
19
+ // Keybindings:
20
+ // - ` (backtick): Toggle console visibility
21
+ // - ~ (tilde): Screenshot (saves to /tmp and copies path)
22
+ // - Ctrl+Y: Copy selected text (when console visible)
23
+ //
24
+ // Navigation (when console visible):
25
+ // - Up/Down: Scroll log entries
26
+ // - Shift+Up/Down: Jump to top/bottom
27
+ // - Home/End: Jump to start/end
28
+ // - +/-: Resize console height
29
+
30
+ export {
31
+ ConsoleCapture,
32
+ getConsoleCapture,
33
+ type LogEntry,
34
+ type LogLevel,
35
+ type SourceLocation,
36
+ } from "./ConsoleCapture.js"
37
+
38
+ export { ConsolePopover, type ConsolePopoverProps } from "./ConsolePopover.js"
39
+
40
+ export { useConsole, type UseConsoleOptions, type UseConsoleReturn } from "./useConsole.js"
41
+
42
+ export { copyToClipboard, copyToClipboardSync } from "./clipboard.js"