nastech-tui 0.0.1

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 (424) hide show
  1. package/.prettierrc +11 -0
  2. package/README.md +346 -0
  3. package/eslint.config.mjs +111 -0
  4. package/package.json +51 -0
  5. package/packages/nastech-ink/ambient.d.ts +83 -0
  6. package/packages/nastech-ink/index.d.ts +40 -0
  7. package/packages/nastech-ink/index.js +1 -0
  8. package/packages/nastech-ink/nastech-ink/ambient.d.ts +83 -0
  9. package/packages/nastech-ink/nastech-ink/index.d.ts +40 -0
  10. package/packages/nastech-ink/nastech-ink/index.js +1 -0
  11. package/packages/nastech-ink/nastech-ink/package.json +54 -0
  12. package/packages/nastech-ink/nastech-ink/src/bootstrap/state.ts +9 -0
  13. package/packages/nastech-ink/nastech-ink/src/entry-exports.ts +32 -0
  14. package/packages/nastech-ink/nastech-ink/src/hooks/use-stderr.ts +15 -0
  15. package/packages/nastech-ink/nastech-ink/src/hooks/use-stdout.ts +15 -0
  16. package/packages/nastech-ink/nastech-ink/src/ink/Ansi.tsx +435 -0
  17. package/packages/nastech-ink/nastech-ink/src/ink/app-mouse.test.ts +123 -0
  18. package/packages/nastech-ink/nastech-ink/src/ink/bidi.ts +145 -0
  19. package/packages/nastech-ink/nastech-ink/src/ink/cache-eviction.ts +45 -0
  20. package/packages/nastech-ink/nastech-ink/src/ink/clearTerminal.ts +68 -0
  21. package/packages/nastech-ink/nastech-ink/src/ink/colorize.test.ts +60 -0
  22. package/packages/nastech-ink/nastech-ink/src/ink/colorize.ts +277 -0
  23. package/packages/nastech-ink/nastech-ink/src/ink/components/AlternateScreen.tsx +133 -0
  24. package/packages/nastech-ink/nastech-ink/src/ink/components/App.tsx +830 -0
  25. package/packages/nastech-ink/nastech-ink/src/ink/components/AppContext.ts +20 -0
  26. package/packages/nastech-ink/nastech-ink/src/ink/components/Box.tsx +294 -0
  27. package/packages/nastech-ink/nastech-ink/src/ink/components/Button.tsx +236 -0
  28. package/packages/nastech-ink/nastech-ink/src/ink/components/ClockContext.tsx +133 -0
  29. package/packages/nastech-ink/nastech-ink/src/ink/components/CursorAdvanceContext.ts +35 -0
  30. package/packages/nastech-ink/nastech-ink/src/ink/components/CursorDeclarationContext.ts +28 -0
  31. package/packages/nastech-ink/nastech-ink/src/ink/components/ErrorOverview.tsx +130 -0
  32. package/packages/nastech-ink/nastech-ink/src/ink/components/Link.tsx +38 -0
  33. package/packages/nastech-ink/nastech-ink/src/ink/components/Newline.tsx +43 -0
  34. package/packages/nastech-ink/nastech-ink/src/ink/components/NoSelect.tsx +73 -0
  35. package/packages/nastech-ink/nastech-ink/src/ink/components/RawAnsi.tsx +61 -0
  36. package/packages/nastech-ink/nastech-ink/src/ink/components/ScrollBox.tsx +290 -0
  37. package/packages/nastech-ink/nastech-ink/src/ink/components/Spacer.tsx +23 -0
  38. package/packages/nastech-ink/nastech-ink/src/ink/components/StdinContext.ts +25 -0
  39. package/packages/nastech-ink/nastech-ink/src/ink/components/TerminalFocusContext.tsx +63 -0
  40. package/packages/nastech-ink/nastech-ink/src/ink/components/TerminalSizeContext.tsx +7 -0
  41. package/packages/nastech-ink/nastech-ink/src/ink/components/Text.test.ts +38 -0
  42. package/packages/nastech-ink/nastech-ink/src/ink/components/Text.tsx +336 -0
  43. package/packages/nastech-ink/nastech-ink/src/ink/constants.ts +6 -0
  44. package/packages/nastech-ink/nastech-ink/src/ink/cursor.ts +5 -0
  45. package/packages/nastech-ink/nastech-ink/src/ink/devtools.ts +2 -0
  46. package/packages/nastech-ink/nastech-ink/src/ink/dom.ts +495 -0
  47. package/packages/nastech-ink/nastech-ink/src/ink/events/click-event.ts +38 -0
  48. package/packages/nastech-ink/nastech-ink/src/ink/events/cmd-shortcuts.test.ts +65 -0
  49. package/packages/nastech-ink/nastech-ink/src/ink/events/dispatcher.ts +242 -0
  50. package/packages/nastech-ink/nastech-ink/src/ink/events/emitter.ts +40 -0
  51. package/packages/nastech-ink/nastech-ink/src/ink/events/event-handlers.ts +84 -0
  52. package/packages/nastech-ink/nastech-ink/src/ink/events/event.ts +11 -0
  53. package/packages/nastech-ink/nastech-ink/src/ink/events/focus-event.ts +18 -0
  54. package/packages/nastech-ink/nastech-ink/src/ink/events/input-event.ts +176 -0
  55. package/packages/nastech-ink/nastech-ink/src/ink/events/keyboard-event.ts +57 -0
  56. package/packages/nastech-ink/nastech-ink/src/ink/events/mouse-event.ts +18 -0
  57. package/packages/nastech-ink/nastech-ink/src/ink/events/paste-event.ts +10 -0
  58. package/packages/nastech-ink/nastech-ink/src/ink/events/resize-event.ts +12 -0
  59. package/packages/nastech-ink/nastech-ink/src/ink/events/terminal-event.ts +107 -0
  60. package/packages/nastech-ink/nastech-ink/src/ink/events/terminal-focus-event.ts +19 -0
  61. package/packages/nastech-ink/nastech-ink/src/ink/focus.ts +219 -0
  62. package/packages/nastech-ink/nastech-ink/src/ink/frame.ts +124 -0
  63. package/packages/nastech-ink/nastech-ink/src/ink/get-max-width.ts +27 -0
  64. package/packages/nastech-ink/nastech-ink/src/ink/global.d.ts +1 -0
  65. package/packages/nastech-ink/nastech-ink/src/ink/hit-test.test.ts +38 -0
  66. package/packages/nastech-ink/nastech-ink/src/ink/hit-test.ts +224 -0
  67. package/packages/nastech-ink/nastech-ink/src/ink/hooks/use-animation-frame.ts +62 -0
  68. package/packages/nastech-ink/nastech-ink/src/ink/hooks/use-app.ts +9 -0
  69. package/packages/nastech-ink/nastech-ink/src/ink/hooks/use-cursor-advance.ts +33 -0
  70. package/packages/nastech-ink/nastech-ink/src/ink/hooks/use-declared-cursor.ts +75 -0
  71. package/packages/nastech-ink/nastech-ink/src/ink/hooks/use-external-process.ts +27 -0
  72. package/packages/nastech-ink/nastech-ink/src/ink/hooks/use-input.ts +95 -0
  73. package/packages/nastech-ink/nastech-ink/src/ink/hooks/use-interval.ts +71 -0
  74. package/packages/nastech-ink/package.json +57 -0
  75. package/packages/nastech-ink/src/bootstrap/state.ts +9 -0
  76. package/packages/nastech-ink/src/entry-exports.ts +32 -0
  77. package/packages/nastech-ink/src/hooks/use-stderr.ts +15 -0
  78. package/packages/nastech-ink/src/hooks/use-stdout.ts +15 -0
  79. package/packages/nastech-ink/src/ink/Ansi.tsx +435 -0
  80. package/packages/nastech-ink/src/ink/app-mouse.test.ts +123 -0
  81. package/packages/nastech-ink/src/ink/app-rawmode-mouse.test.ts +91 -0
  82. package/packages/nastech-ink/src/ink/bidi.ts +145 -0
  83. package/packages/nastech-ink/src/ink/cache-eviction.ts +45 -0
  84. package/packages/nastech-ink/src/ink/clearTerminal.ts +68 -0
  85. package/packages/nastech-ink/src/ink/colorize.test.ts +60 -0
  86. package/packages/nastech-ink/src/ink/colorize.ts +277 -0
  87. package/packages/nastech-ink/src/ink/components/AlternateScreen.tsx +133 -0
  88. package/packages/nastech-ink/src/ink/components/App.tsx +855 -0
  89. package/packages/nastech-ink/src/ink/components/AppContext.ts +20 -0
  90. package/packages/nastech-ink/src/ink/components/Box.tsx +294 -0
  91. package/packages/nastech-ink/src/ink/components/Button.tsx +236 -0
  92. package/packages/nastech-ink/src/ink/components/ClockContext.tsx +133 -0
  93. package/packages/nastech-ink/src/ink/components/CursorAdvanceContext.ts +35 -0
  94. package/packages/nastech-ink/src/ink/components/CursorDeclarationContext.ts +28 -0
  95. package/packages/nastech-ink/src/ink/components/ErrorOverview.tsx +130 -0
  96. package/packages/nastech-ink/src/ink/components/Link.tsx +38 -0
  97. package/packages/nastech-ink/src/ink/components/Newline.tsx +43 -0
  98. package/packages/nastech-ink/src/ink/components/NoSelect.tsx +73 -0
  99. package/packages/nastech-ink/src/ink/components/RawAnsi.tsx +61 -0
  100. package/packages/nastech-ink/src/ink/components/ScrollBox.tsx +290 -0
  101. package/packages/nastech-ink/src/ink/components/Spacer.tsx +23 -0
  102. package/packages/nastech-ink/src/ink/components/StdinContext.ts +25 -0
  103. package/packages/nastech-ink/src/ink/components/TerminalFocusContext.tsx +63 -0
  104. package/packages/nastech-ink/src/ink/components/TerminalSizeContext.tsx +7 -0
  105. package/packages/nastech-ink/src/ink/components/Text.test.ts +38 -0
  106. package/packages/nastech-ink/src/ink/components/Text.tsx +336 -0
  107. package/packages/nastech-ink/src/ink/constants.ts +6 -0
  108. package/packages/nastech-ink/src/ink/cursor.ts +5 -0
  109. package/packages/nastech-ink/src/ink/devtools.ts +2 -0
  110. package/packages/nastech-ink/src/ink/dom.ts +495 -0
  111. package/packages/nastech-ink/src/ink/events/click-event.ts +38 -0
  112. package/packages/nastech-ink/src/ink/events/cmd-shortcuts.test.ts +65 -0
  113. package/packages/nastech-ink/src/ink/events/dispatcher.ts +242 -0
  114. package/packages/nastech-ink/src/ink/events/emitter.ts +40 -0
  115. package/packages/nastech-ink/src/ink/events/event-handlers.ts +84 -0
  116. package/packages/nastech-ink/src/ink/events/event.ts +11 -0
  117. package/packages/nastech-ink/src/ink/events/focus-event.ts +18 -0
  118. package/packages/nastech-ink/src/ink/events/input-event.ts +176 -0
  119. package/packages/nastech-ink/src/ink/events/keyboard-event.ts +57 -0
  120. package/packages/nastech-ink/src/ink/events/mouse-event.ts +18 -0
  121. package/packages/nastech-ink/src/ink/events/paste-event.ts +10 -0
  122. package/packages/nastech-ink/src/ink/events/resize-event.ts +12 -0
  123. package/packages/nastech-ink/src/ink/events/terminal-event.ts +107 -0
  124. package/packages/nastech-ink/src/ink/events/terminal-focus-event.ts +19 -0
  125. package/packages/nastech-ink/src/ink/focus.ts +219 -0
  126. package/packages/nastech-ink/src/ink/frame.ts +124 -0
  127. package/packages/nastech-ink/src/ink/get-max-width.ts +27 -0
  128. package/packages/nastech-ink/src/ink/global.d.ts +1 -0
  129. package/packages/nastech-ink/src/ink/hit-test.test.ts +38 -0
  130. package/packages/nastech-ink/src/ink/hit-test.ts +224 -0
  131. package/packages/nastech-ink/src/ink/hooks/use-animation-frame.ts +62 -0
  132. package/packages/nastech-ink/src/ink/hooks/use-app.ts +9 -0
  133. package/packages/nastech-ink/src/ink/hooks/use-cursor-advance.ts +33 -0
  134. package/packages/nastech-ink/src/ink/hooks/use-declared-cursor.ts +75 -0
  135. package/packages/nastech-ink/src/ink/hooks/use-external-process.ts +27 -0
  136. package/packages/nastech-ink/src/ink/hooks/use-input.ts +95 -0
  137. package/packages/nastech-ink/src/ink/hooks/use-interval.ts +71 -0
  138. package/packages/nastech-ink/src/ink/hooks/use-search-highlight.ts +56 -0
  139. package/packages/nastech-ink/src/ink/hooks/use-selection.ts +101 -0
  140. package/packages/nastech-ink/src/ink/hooks/use-stdin.ts +9 -0
  141. package/packages/nastech-ink/src/ink/hooks/use-tab-status.ts +71 -0
  142. package/packages/nastech-ink/src/ink/hooks/use-terminal-focus.ts +18 -0
  143. package/packages/nastech-ink/src/ink/hooks/use-terminal-title.ts +34 -0
  144. package/packages/nastech-ink/src/ink/hooks/use-terminal-viewport.ts +100 -0
  145. package/packages/nastech-ink/src/ink/hyperlinkHover.ts +52 -0
  146. package/packages/nastech-ink/src/ink/ink-cursor-advance.test.ts +234 -0
  147. package/packages/nastech-ink/src/ink/ink-resize.test.ts +50 -0
  148. package/packages/nastech-ink/src/ink/ink.tsx +2705 -0
  149. package/packages/nastech-ink/src/ink/instances.ts +10 -0
  150. package/packages/nastech-ink/src/ink/layout/engine.ts +6 -0
  151. package/packages/nastech-ink/src/ink/layout/geometry.ts +98 -0
  152. package/packages/nastech-ink/src/ink/layout/node.ts +145 -0
  153. package/packages/nastech-ink/src/ink/layout/yoga.ts +313 -0
  154. package/packages/nastech-ink/src/ink/line-width-cache.ts +38 -0
  155. package/packages/nastech-ink/src/ink/log-update.test.ts +223 -0
  156. package/packages/nastech-ink/src/ink/log-update.ts +752 -0
  157. package/packages/nastech-ink/src/ink/lru.ts +14 -0
  158. package/packages/nastech-ink/src/ink/measure-element.ts +23 -0
  159. package/packages/nastech-ink/src/ink/measure-text.ts +50 -0
  160. package/packages/nastech-ink/src/ink/node-cache.ts +53 -0
  161. package/packages/nastech-ink/src/ink/optimizer.ts +99 -0
  162. package/packages/nastech-ink/src/ink/output.ts +845 -0
  163. package/packages/nastech-ink/src/ink/parse-keypress.test.ts +133 -0
  164. package/packages/nastech-ink/src/ink/parse-keypress.ts +848 -0
  165. package/packages/nastech-ink/src/ink/reconciler.ts +382 -0
  166. package/packages/nastech-ink/src/ink/render-border.ts +206 -0
  167. package/packages/nastech-ink/src/ink/render-node-to-output.ts +1582 -0
  168. package/packages/nastech-ink/src/ink/render-to-screen.ts +236 -0
  169. package/packages/nastech-ink/src/ink/renderer.ts +169 -0
  170. package/packages/nastech-ink/src/ink/root.ts +204 -0
  171. package/packages/nastech-ink/src/ink/screen.ts +1590 -0
  172. package/packages/nastech-ink/src/ink/searchHighlight.ts +91 -0
  173. package/packages/nastech-ink/src/ink/selection.test.ts +82 -0
  174. package/packages/nastech-ink/src/ink/selection.ts +1143 -0
  175. package/packages/nastech-ink/src/ink/squash-text-nodes.ts +74 -0
  176. package/packages/nastech-ink/src/ink/stringWidth.ts +341 -0
  177. package/packages/nastech-ink/src/ink/styles.ts +750 -0
  178. package/packages/nastech-ink/src/ink/supports-hyperlinks.ts +51 -0
  179. package/packages/nastech-ink/src/ink/tabstops.ts +44 -0
  180. package/packages/nastech-ink/src/ink/terminal-focus-state.ts +52 -0
  181. package/packages/nastech-ink/src/ink/terminal-querier.ts +222 -0
  182. package/packages/nastech-ink/src/ink/terminal.test.ts +15 -0
  183. package/packages/nastech-ink/src/ink/terminal.ts +299 -0
  184. package/packages/nastech-ink/src/ink/termio/ansi.ts +75 -0
  185. package/packages/nastech-ink/src/ink/termio/csi.ts +334 -0
  186. package/packages/nastech-ink/src/ink/termio/dec.ts +99 -0
  187. package/packages/nastech-ink/src/ink/termio/esc.ts +69 -0
  188. package/packages/nastech-ink/src/ink/termio/osc.test.ts +191 -0
  189. package/packages/nastech-ink/src/ink/termio/osc.ts +724 -0
  190. package/packages/nastech-ink/src/ink/termio/parser.ts +467 -0
  191. package/packages/nastech-ink/src/ink/termio/sgr.ts +362 -0
  192. package/packages/nastech-ink/src/ink/termio/tokenize.test.ts +185 -0
  193. package/packages/nastech-ink/src/ink/termio/tokenize.ts +350 -0
  194. package/packages/nastech-ink/src/ink/termio/types.ts +230 -0
  195. package/packages/nastech-ink/src/ink/termio.ts +42 -0
  196. package/packages/nastech-ink/src/ink/useTerminalNotification.ts +110 -0
  197. package/packages/nastech-ink/src/ink/warn.ts +15 -0
  198. package/packages/nastech-ink/src/ink/widest-line.ts +22 -0
  199. package/packages/nastech-ink/src/ink/wrap-text.test.ts +17 -0
  200. package/packages/nastech-ink/src/ink/wrap-text.ts +144 -0
  201. package/packages/nastech-ink/src/ink/wrapAnsi.ts +13 -0
  202. package/packages/nastech-ink/src/native-ts/yoga-layout/enums.ts +112 -0
  203. package/packages/nastech-ink/src/native-ts/yoga-layout/index.ts +2326 -0
  204. package/packages/nastech-ink/src/utils/debug.ts +6 -0
  205. package/packages/nastech-ink/src/utils/earlyInput.ts +131 -0
  206. package/packages/nastech-ink/src/utils/env.ts +66 -0
  207. package/packages/nastech-ink/src/utils/envUtils.ts +13 -0
  208. package/packages/nastech-ink/src/utils/execFileNoThrow.test.ts +146 -0
  209. package/packages/nastech-ink/src/utils/execFileNoThrow.ts +115 -0
  210. package/packages/nastech-ink/src/utils/fullscreen.ts +3 -0
  211. package/packages/nastech-ink/src/utils/intl.ts +87 -0
  212. package/packages/nastech-ink/src/utils/log.ts +7 -0
  213. package/packages/nastech-ink/src/utils/semver.ts +57 -0
  214. package/packages/nastech-ink/src/utils/sliceAnsi.ts +106 -0
  215. package/packages/nastech-ink/text-input.d.ts +2 -0
  216. package/packages/nastech-ink/text-input.js +1 -0
  217. package/scripts/build.mjs +61 -0
  218. package/scripts/profile-tui.mjs +121 -0
  219. package/src/__tests__/activeSessionSwitcher.test.ts +157 -0
  220. package/src/__tests__/appChromeStatusRule.test.tsx +84 -0
  221. package/src/__tests__/appChromeStatusRuleDevCredits.test.tsx +73 -0
  222. package/src/__tests__/approvalAction.test.ts +50 -0
  223. package/src/__tests__/asCommandDispatch.test.ts +27 -0
  224. package/src/__tests__/blockLayout.test.ts +122 -0
  225. package/src/__tests__/clipboard.test.ts +369 -0
  226. package/src/__tests__/constants.test.ts +53 -0
  227. package/src/__tests__/createGatewayEventHandler.test.ts +1091 -0
  228. package/src/__tests__/createSlashHandler.test.ts +822 -0
  229. package/src/__tests__/creditsCommand.test.ts +144 -0
  230. package/src/__tests__/cursorDriftRegression.test.ts +114 -0
  231. package/src/__tests__/details.test.ts +115 -0
  232. package/src/__tests__/emoji.test.ts +64 -0
  233. package/src/__tests__/externalLink.test.ts +144 -0
  234. package/src/__tests__/forceTruecolor.test.ts +191 -0
  235. package/src/__tests__/gatewayClient.test.ts +394 -0
  236. package/src/__tests__/gatewayRecovery.test.ts +47 -0
  237. package/src/__tests__/markdown.test.ts +331 -0
  238. package/src/__tests__/mathUnicode.test.ts +293 -0
  239. package/src/__tests__/memoryMonitor.test.ts +102 -0
  240. package/src/__tests__/messageLine.test.ts +19 -0
  241. package/src/__tests__/messages.test.ts +92 -0
  242. package/src/__tests__/orchestratorPromptSession.test.ts +64 -0
  243. package/src/__tests__/osc52.test.ts +67 -0
  244. package/src/__tests__/parentLog.test.ts +75 -0
  245. package/src/__tests__/paths.test.ts +70 -0
  246. package/src/__tests__/platform.test.ts +556 -0
  247. package/src/__tests__/precisionWheel.test.ts +44 -0
  248. package/src/__tests__/prompt.test.ts +31 -0
  249. package/src/__tests__/providers.test.ts +65 -0
  250. package/src/__tests__/reasoning.test.ts +76 -0
  251. package/src/__tests__/rpc.test.ts +27 -0
  252. package/src/__tests__/scroll.test.ts +99 -0
  253. package/src/__tests__/slashParity.test.ts +123 -0
  254. package/src/__tests__/spawnHistoryStore.test.ts +46 -0
  255. package/src/__tests__/stateIsolation.test.ts +46 -0
  256. package/src/__tests__/statusBarTicker.test.ts +18 -0
  257. package/src/__tests__/statusRule.test.ts +32 -0
  258. package/src/__tests__/streamingMarkdown.test.ts +121 -0
  259. package/src/__tests__/subagentTree.test.ts +407 -0
  260. package/src/__tests__/syntax.test.ts +45 -0
  261. package/src/__tests__/terminalModes.test.ts +39 -0
  262. package/src/__tests__/terminalParity.test.ts +77 -0
  263. package/src/__tests__/terminalSetup.test.ts +386 -0
  264. package/src/__tests__/termux.test.ts +35 -0
  265. package/src/__tests__/termuxComposerLayout.test.ts +40 -0
  266. package/src/__tests__/text.test.ts +233 -0
  267. package/src/__tests__/textInputBurstInput.test.ts +40 -0
  268. package/src/__tests__/textInputCursorSourceOfTruth.test.ts +50 -0
  269. package/src/__tests__/textInputFastEcho.test.ts +200 -0
  270. package/src/__tests__/textInputLineNav.test.ts +55 -0
  271. package/src/__tests__/textInputPassThrough.test.ts +59 -0
  272. package/src/__tests__/textInputRightClick.test.ts +48 -0
  273. package/src/__tests__/textInputWrap.test.ts +151 -0
  274. package/src/__tests__/theme.test.ts +311 -0
  275. package/src/__tests__/turnControllerNotice.test.ts +43 -0
  276. package/src/__tests__/turnStore.test.ts +66 -0
  277. package/src/__tests__/useCompletion.test.ts +35 -0
  278. package/src/__tests__/useComposerState.test.ts +59 -0
  279. package/src/__tests__/useConfigSync.test.ts +460 -0
  280. package/src/__tests__/useInputHandlers.test.ts +77 -0
  281. package/src/__tests__/useQueue.test.ts +28 -0
  282. package/src/__tests__/useSessionLifecycle.test.ts +60 -0
  283. package/src/__tests__/useVirtualHistoryHeights.test.ts +39 -0
  284. package/src/__tests__/viewport.test.ts +58 -0
  285. package/src/__tests__/viewportStore.test.ts +85 -0
  286. package/src/__tests__/virtualHeights.test.ts +96 -0
  287. package/src/__tests__/virtualHistoryClamp.test.ts +19 -0
  288. package/src/__tests__/virtualHistoryOffsetCache.test.ts +282 -0
  289. package/src/__tests__/wheelAccel.test.ts +138 -0
  290. package/src/app/createGatewayEventHandler.ts +833 -0
  291. package/src/app/createSlashHandler.ts +130 -0
  292. package/src/app/delegationStore.ts +77 -0
  293. package/src/app/gatewayContext.tsx +19 -0
  294. package/src/app/gatewayRecovery.ts +35 -0
  295. package/src/app/inputSelectionStore.ts +15 -0
  296. package/src/app/interfaces.ts +394 -0
  297. package/src/app/overlayStore.ts +53 -0
  298. package/src/app/scroll.ts +71 -0
  299. package/src/app/setupHandoff.ts +54 -0
  300. package/src/app/slash/commands/core.ts +648 -0
  301. package/src/app/slash/commands/credits.ts +57 -0
  302. package/src/app/slash/commands/debug.ts +48 -0
  303. package/src/app/slash/commands/ops.ts +717 -0
  304. package/src/app/slash/commands/session.ts +554 -0
  305. package/src/app/slash/commands/setup.ts +20 -0
  306. package/src/app/slash/registry.ts +20 -0
  307. package/src/app/slash/types.ts +21 -0
  308. package/src/app/spawnHistoryStore.ts +159 -0
  309. package/src/app/turnController.ts +866 -0
  310. package/src/app/turnStore.ts +85 -0
  311. package/src/app/uiStore.ts +44 -0
  312. package/src/app/useComposerState.ts +367 -0
  313. package/src/app/useConfigSync.ts +288 -0
  314. package/src/app/useInputHandlers.ts +576 -0
  315. package/src/app/useLongRunToolCharms.ts +69 -0
  316. package/src/app/useMainApp.ts +1039 -0
  317. package/src/app/useSessionLifecycle.ts +366 -0
  318. package/src/app/useSubmission.ts +429 -0
  319. package/src/app.tsx +25 -0
  320. package/src/banner.ts +93 -0
  321. package/src/components/activeSessionSwitcher.tsx +635 -0
  322. package/src/components/agentsOverlay.tsx +1073 -0
  323. package/src/components/appChrome.tsx +554 -0
  324. package/src/components/appLayout.tsx +444 -0
  325. package/src/components/appOverlays.tsx +254 -0
  326. package/src/components/branding.tsx +466 -0
  327. package/src/components/fpsOverlay.tsx +30 -0
  328. package/src/components/helpHint.tsx +73 -0
  329. package/src/components/markdown.tsx +1119 -0
  330. package/src/components/maskedPrompt.tsx +34 -0
  331. package/src/components/messageLine.tsx +237 -0
  332. package/src/components/modelPicker.tsx +527 -0
  333. package/src/components/overlayControls.tsx +50 -0
  334. package/src/components/pluginsHub.tsx +238 -0
  335. package/src/components/prompts.tsx +276 -0
  336. package/src/components/queuedMessages.tsx +64 -0
  337. package/src/components/sessionPicker.tsx +227 -0
  338. package/src/components/skillsHub.tsx +308 -0
  339. package/src/components/streamingAssistant.tsx +110 -0
  340. package/src/components/streamingMarkdown.tsx +174 -0
  341. package/src/components/textInput.tsx +1340 -0
  342. package/src/components/themed.tsx +30 -0
  343. package/src/components/thinking.tsx +1224 -0
  344. package/src/components/todoPanel.tsx +93 -0
  345. package/src/config/env.ts +64 -0
  346. package/src/config/limits.ts +13 -0
  347. package/src/config/timing.ts +6 -0
  348. package/src/content/charms.ts +1 -0
  349. package/src/content/faces.ts +17 -0
  350. package/src/content/fortunes.ts +30 -0
  351. package/src/content/hotkeys.ts +37 -0
  352. package/src/content/placeholders.ts +13 -0
  353. package/src/content/setup.ts +17 -0
  354. package/src/content/verbs.ts +38 -0
  355. package/src/domain/blockLayout.ts +146 -0
  356. package/src/domain/details.ts +76 -0
  357. package/src/domain/messages.ts +91 -0
  358. package/src/domain/paths.ts +16 -0
  359. package/src/domain/providers.ts +11 -0
  360. package/src/domain/roles.ts +9 -0
  361. package/src/domain/slash.ts +10 -0
  362. package/src/domain/usage.ts +3 -0
  363. package/src/domain/viewport.ts +51 -0
  364. package/src/entry.tsx +104 -0
  365. package/src/gatewayClient.ts +730 -0
  366. package/src/gatewayTypes.ts +568 -0
  367. package/src/hooks/useCompletion.ts +112 -0
  368. package/src/hooks/useGitBranch.ts +72 -0
  369. package/src/hooks/useInputHistory.ts +11 -0
  370. package/src/hooks/useQueue.ts +76 -0
  371. package/src/hooks/useVirtualHistory.ts +554 -0
  372. package/src/lib/circularBuffer.ts +48 -0
  373. package/src/lib/clipboard.ts +182 -0
  374. package/src/lib/editor.test.ts +74 -0
  375. package/src/lib/editor.ts +47 -0
  376. package/src/lib/emoji.ts +55 -0
  377. package/src/lib/externalCli.ts +16 -0
  378. package/src/lib/externalLink.ts +435 -0
  379. package/src/lib/forceTruecolor.ts +60 -0
  380. package/src/lib/fpsStore.ts +51 -0
  381. package/src/lib/fuzzy.test.ts +109 -0
  382. package/src/lib/fuzzy.ts +177 -0
  383. package/src/lib/gracefulExit.ts +47 -0
  384. package/src/lib/history.ts +82 -0
  385. package/src/lib/inputMetrics.ts +203 -0
  386. package/src/lib/liveProgress.test.ts +116 -0
  387. package/src/lib/liveProgress.ts +79 -0
  388. package/src/lib/mathUnicode.ts +770 -0
  389. package/src/lib/memory.test.ts +155 -0
  390. package/src/lib/memory.ts +188 -0
  391. package/src/lib/memoryMonitor.ts +109 -0
  392. package/src/lib/messages.test.ts +29 -0
  393. package/src/lib/messages.ts +8 -0
  394. package/src/lib/openExternalUrl.test.ts +217 -0
  395. package/src/lib/openExternalUrl.ts +158 -0
  396. package/src/lib/osc52.ts +73 -0
  397. package/src/lib/parentLog.ts +57 -0
  398. package/src/lib/perfPane.tsx +107 -0
  399. package/src/lib/platform.ts +409 -0
  400. package/src/lib/precisionWheel.ts +48 -0
  401. package/src/lib/prompt.ts +35 -0
  402. package/src/lib/reasoning.ts +55 -0
  403. package/src/lib/rpc.ts +41 -0
  404. package/src/lib/subagentTree.ts +355 -0
  405. package/src/lib/syntax.ts +117 -0
  406. package/src/lib/terminalModes.ts +51 -0
  407. package/src/lib/terminalParity.ts +78 -0
  408. package/src/lib/terminalSetup.ts +444 -0
  409. package/src/lib/termux.ts +29 -0
  410. package/src/lib/text.test.ts +18 -0
  411. package/src/lib/text.ts +339 -0
  412. package/src/lib/todo.test.ts +21 -0
  413. package/src/lib/todo.ts +9 -0
  414. package/src/lib/viewportStore.ts +124 -0
  415. package/src/lib/virtualHeights.ts +145 -0
  416. package/src/lib/wheelAccel.ts +190 -0
  417. package/src/protocol/interpolation.ts +3 -0
  418. package/src/protocol/paste.ts +1 -0
  419. package/src/theme.ts +589 -0
  420. package/src/types/nastech-ink.d.ts +176 -0
  421. package/src/types.ts +212 -0
  422. package/tsconfig.build.json +9 -0
  423. package/tsconfig.json +19 -0
  424. package/vitest.config.ts +7 -0
@@ -0,0 +1,10 @@
1
+ // Store all instances of Ink (instance.js) to ensure that consecutive render() calls
2
+ // use the same instance of Ink and don't create a new one
3
+ //
4
+ // This map has to be stored in a separate file, because render.js creates instances,
5
+ // but instance.js should delete itself from the map on unmount
6
+
7
+ import type Ink from './ink.js'
8
+
9
+ const instances = new Map<NodeJS.WriteStream, Ink>()
10
+ export default instances
@@ -0,0 +1,6 @@
1
+ import type { LayoutNode } from './node.js'
2
+ import { createYogaLayoutNode } from './yoga.js'
3
+
4
+ export function createLayoutNode(): LayoutNode {
5
+ return createYogaLayoutNode()
6
+ }
@@ -0,0 +1,98 @@
1
+ export type Point = {
2
+ x: number
3
+ y: number
4
+ }
5
+
6
+ export type Size = {
7
+ width: number
8
+ height: number
9
+ }
10
+
11
+ export type Rectangle = Point & Size
12
+
13
+ /** Edge insets (padding, margin, border) */
14
+ export type Edges = {
15
+ top: number
16
+ right: number
17
+ bottom: number
18
+ left: number
19
+ }
20
+
21
+ /** Create uniform edges */
22
+ export function edges(all: number): Edges
23
+ export function edges(vertical: number, horizontal: number): Edges
24
+ export function edges(top: number, right: number, bottom: number, left: number): Edges
25
+
26
+ export function edges(a: number, b?: number, c?: number, d?: number): Edges {
27
+ if (b === undefined) {
28
+ return { top: a, right: a, bottom: a, left: a }
29
+ }
30
+
31
+ if (c === undefined) {
32
+ return { top: a, right: b, bottom: a, left: b }
33
+ }
34
+
35
+ return { top: a, right: b, bottom: c, left: d! }
36
+ }
37
+
38
+ /** Add two edge values */
39
+ export function addEdges(a: Edges, b: Edges): Edges {
40
+ return {
41
+ top: a.top + b.top,
42
+ right: a.right + b.right,
43
+ bottom: a.bottom + b.bottom,
44
+ left: a.left + b.left
45
+ }
46
+ }
47
+
48
+ /** Zero edges constant */
49
+ export const ZERO_EDGES: Edges = { top: 0, right: 0, bottom: 0, left: 0 }
50
+
51
+ /** Convert partial edges to full edges with defaults */
52
+ export function resolveEdges(partial?: Partial<Edges>): Edges {
53
+ return {
54
+ top: partial?.top ?? 0,
55
+ right: partial?.right ?? 0,
56
+ bottom: partial?.bottom ?? 0,
57
+ left: partial?.left ?? 0
58
+ }
59
+ }
60
+
61
+ export function unionRect(a: Rectangle, b: Rectangle): Rectangle {
62
+ const minX = Math.min(a.x, b.x)
63
+ const minY = Math.min(a.y, b.y)
64
+ const maxX = Math.max(a.x + a.width, b.x + b.width)
65
+ const maxY = Math.max(a.y + a.height, b.y + b.height)
66
+
67
+ return { x: minX, y: minY, width: maxX - minX, height: maxY - minY }
68
+ }
69
+
70
+ export function clampRect(rect: Rectangle, size: Size): Rectangle {
71
+ const minX = Math.max(0, rect.x)
72
+ const minY = Math.max(0, rect.y)
73
+ const maxX = Math.min(size.width - 1, rect.x + rect.width - 1)
74
+ const maxY = Math.min(size.height - 1, rect.y + rect.height - 1)
75
+
76
+ return {
77
+ x: minX,
78
+ y: minY,
79
+ width: Math.max(0, maxX - minX + 1),
80
+ height: Math.max(0, maxY - minY + 1)
81
+ }
82
+ }
83
+
84
+ export function withinBounds(size: Size, point: Point): boolean {
85
+ return point.x >= 0 && point.y >= 0 && point.x < size.width && point.y < size.height
86
+ }
87
+
88
+ export function clamp(value: number, min?: number, max?: number): number {
89
+ if (min !== undefined && value < min) {
90
+ return min
91
+ }
92
+
93
+ if (max !== undefined && value > max) {
94
+ return max
95
+ }
96
+
97
+ return value
98
+ }
@@ -0,0 +1,145 @@
1
+ // --
2
+ // Adapter interface for the layout engine (Yoga)
3
+
4
+ export const LayoutEdge = {
5
+ All: 'all',
6
+ Horizontal: 'horizontal',
7
+ Vertical: 'vertical',
8
+ Left: 'left',
9
+ Right: 'right',
10
+ Top: 'top',
11
+ Bottom: 'bottom',
12
+ Start: 'start',
13
+ End: 'end'
14
+ } as const
15
+ export type LayoutEdge = (typeof LayoutEdge)[keyof typeof LayoutEdge]
16
+
17
+ export const LayoutGutter = {
18
+ All: 'all',
19
+ Column: 'column',
20
+ Row: 'row'
21
+ } as const
22
+ export type LayoutGutter = (typeof LayoutGutter)[keyof typeof LayoutGutter]
23
+
24
+ export const LayoutDisplay = {
25
+ Flex: 'flex',
26
+ None: 'none'
27
+ } as const
28
+ export type LayoutDisplay = (typeof LayoutDisplay)[keyof typeof LayoutDisplay]
29
+
30
+ export const LayoutFlexDirection = {
31
+ Row: 'row',
32
+ RowReverse: 'row-reverse',
33
+ Column: 'column',
34
+ ColumnReverse: 'column-reverse'
35
+ } as const
36
+ export type LayoutFlexDirection = (typeof LayoutFlexDirection)[keyof typeof LayoutFlexDirection]
37
+
38
+ export const LayoutAlign = {
39
+ Auto: 'auto',
40
+ Stretch: 'stretch',
41
+ FlexStart: 'flex-start',
42
+ Center: 'center',
43
+ FlexEnd: 'flex-end'
44
+ } as const
45
+ export type LayoutAlign = (typeof LayoutAlign)[keyof typeof LayoutAlign]
46
+
47
+ export const LayoutJustify = {
48
+ FlexStart: 'flex-start',
49
+ Center: 'center',
50
+ FlexEnd: 'flex-end',
51
+ SpaceBetween: 'space-between',
52
+ SpaceAround: 'space-around',
53
+ SpaceEvenly: 'space-evenly'
54
+ } as const
55
+ export type LayoutJustify = (typeof LayoutJustify)[keyof typeof LayoutJustify]
56
+
57
+ export const LayoutWrap = {
58
+ NoWrap: 'nowrap',
59
+ Wrap: 'wrap',
60
+ WrapReverse: 'wrap-reverse'
61
+ } as const
62
+ export type LayoutWrap = (typeof LayoutWrap)[keyof typeof LayoutWrap]
63
+
64
+ export const LayoutPositionType = {
65
+ Relative: 'relative',
66
+ Absolute: 'absolute'
67
+ } as const
68
+ export type LayoutPositionType = (typeof LayoutPositionType)[keyof typeof LayoutPositionType]
69
+
70
+ export const LayoutOverflow = {
71
+ Visible: 'visible',
72
+ Hidden: 'hidden',
73
+ Scroll: 'scroll'
74
+ } as const
75
+ export type LayoutOverflow = (typeof LayoutOverflow)[keyof typeof LayoutOverflow]
76
+
77
+ export type LayoutMeasureFunc = (width: number, widthMode: LayoutMeasureMode) => { width: number; height: number }
78
+
79
+ export const LayoutMeasureMode = {
80
+ Undefined: 'undefined',
81
+ Exactly: 'exactly',
82
+ AtMost: 'at-most'
83
+ } as const
84
+ export type LayoutMeasureMode = (typeof LayoutMeasureMode)[keyof typeof LayoutMeasureMode]
85
+
86
+ export type LayoutNode = {
87
+ // Tree
88
+ insertChild(child: LayoutNode, index: number): void
89
+ removeChild(child: LayoutNode): void
90
+ getChildCount(): number
91
+ getParent(): LayoutNode | null
92
+
93
+ // Layout computation
94
+ calculateLayout(width?: number, height?: number): void
95
+ setMeasureFunc(fn: LayoutMeasureFunc): void
96
+ unsetMeasureFunc(): void
97
+ markDirty(): void
98
+
99
+ // Layout reading (post-layout)
100
+ getComputedLeft(): number
101
+ getComputedTop(): number
102
+ getComputedWidth(): number
103
+ getComputedHeight(): number
104
+ getComputedBorder(edge: LayoutEdge): number
105
+ getComputedPadding(edge: LayoutEdge): number
106
+
107
+ // Style setters
108
+ setWidth(value: number): void
109
+ setWidthPercent(value: number): void
110
+ setWidthAuto(): void
111
+ setHeight(value: number): void
112
+ setHeightPercent(value: number): void
113
+ setHeightAuto(): void
114
+ setMinWidth(value: number): void
115
+ setMinWidthPercent(value: number): void
116
+ setMinHeight(value: number): void
117
+ setMinHeightPercent(value: number): void
118
+ setMaxWidth(value: number): void
119
+ setMaxWidthPercent(value: number): void
120
+ setMaxHeight(value: number): void
121
+ setMaxHeightPercent(value: number): void
122
+ setFlexDirection(dir: LayoutFlexDirection): void
123
+ setFlexGrow(value: number): void
124
+ setFlexShrink(value: number): void
125
+ setFlexBasis(value: number): void
126
+ setFlexBasisPercent(value: number): void
127
+ setFlexWrap(wrap: LayoutWrap): void
128
+ setAlignItems(align: LayoutAlign): void
129
+ setAlignSelf(align: LayoutAlign): void
130
+ setJustifyContent(justify: LayoutJustify): void
131
+ setDisplay(display: LayoutDisplay): void
132
+ getDisplay(): LayoutDisplay
133
+ setPositionType(type: LayoutPositionType): void
134
+ setPosition(edge: LayoutEdge, value: number): void
135
+ setPositionPercent(edge: LayoutEdge, value: number): void
136
+ setOverflow(overflow: LayoutOverflow): void
137
+ setMargin(edge: LayoutEdge, value: number): void
138
+ setPadding(edge: LayoutEdge, value: number): void
139
+ setBorder(edge: LayoutEdge, value: number): void
140
+ setGap(gutter: LayoutGutter, value: number): void
141
+
142
+ // Lifecycle
143
+ free(): void
144
+ freeRecursive(): void
145
+ }
@@ -0,0 +1,313 @@
1
+ import Yoga, {
2
+ Align,
3
+ Direction,
4
+ Display,
5
+ Edge,
6
+ FlexDirection,
7
+ Gutter,
8
+ Justify,
9
+ MeasureMode,
10
+ Overflow,
11
+ PositionType,
12
+ Wrap,
13
+ type Node as YogaNode
14
+ } from '../../native-ts/yoga-layout/index.js'
15
+
16
+ import {
17
+ type LayoutAlign,
18
+ LayoutDisplay,
19
+ type LayoutEdge,
20
+ type LayoutFlexDirection,
21
+ type LayoutGutter,
22
+ type LayoutJustify,
23
+ type LayoutMeasureFunc,
24
+ LayoutMeasureMode,
25
+ type LayoutNode,
26
+ type LayoutOverflow,
27
+ type LayoutPositionType,
28
+ type LayoutWrap
29
+ } from './node.js'
30
+
31
+ // --
32
+ // Edge/Gutter mapping
33
+
34
+ const EDGE_MAP: Record<LayoutEdge, Edge> = {
35
+ all: Edge.All,
36
+ horizontal: Edge.Horizontal,
37
+ vertical: Edge.Vertical,
38
+ left: Edge.Left,
39
+ right: Edge.Right,
40
+ top: Edge.Top,
41
+ bottom: Edge.Bottom,
42
+ start: Edge.Start,
43
+ end: Edge.End
44
+ }
45
+
46
+ const GUTTER_MAP: Record<LayoutGutter, Gutter> = {
47
+ all: Gutter.All,
48
+ column: Gutter.Column,
49
+ row: Gutter.Row
50
+ }
51
+
52
+ // --
53
+ // Yoga adapter
54
+
55
+ export class YogaLayoutNode implements LayoutNode {
56
+ readonly yoga: YogaNode
57
+
58
+ constructor(yoga: YogaNode) {
59
+ this.yoga = yoga
60
+ }
61
+
62
+ // Tree
63
+
64
+ insertChild(child: LayoutNode, index: number): void {
65
+ this.yoga.insertChild((child as YogaLayoutNode).yoga, index)
66
+ }
67
+
68
+ removeChild(child: LayoutNode): void {
69
+ this.yoga.removeChild((child as YogaLayoutNode).yoga)
70
+ }
71
+
72
+ getChildCount(): number {
73
+ return this.yoga.getChildCount()
74
+ }
75
+
76
+ getParent(): LayoutNode | null {
77
+ const p = this.yoga.getParent()
78
+
79
+ return p ? new YogaLayoutNode(p) : null
80
+ }
81
+
82
+ // Layout
83
+
84
+ calculateLayout(width?: number, _height?: number): void {
85
+ this.yoga.calculateLayout(width, undefined, Direction.LTR)
86
+ }
87
+
88
+ setMeasureFunc(fn: LayoutMeasureFunc): void {
89
+ this.yoga.setMeasureFunc((w, wMode) => {
90
+ const mode =
91
+ wMode === MeasureMode.Exactly
92
+ ? LayoutMeasureMode.Exactly
93
+ : wMode === MeasureMode.AtMost
94
+ ? LayoutMeasureMode.AtMost
95
+ : LayoutMeasureMode.Undefined
96
+
97
+ return fn(w, mode)
98
+ })
99
+ }
100
+
101
+ unsetMeasureFunc(): void {
102
+ this.yoga.unsetMeasureFunc()
103
+ }
104
+
105
+ markDirty(): void {
106
+ this.yoga.markDirty()
107
+ }
108
+
109
+ // Computed layout
110
+
111
+ getComputedLeft(): number {
112
+ return this.yoga.getComputedLeft()
113
+ }
114
+
115
+ getComputedTop(): number {
116
+ return this.yoga.getComputedTop()
117
+ }
118
+
119
+ getComputedWidth(): number {
120
+ return this.yoga.getComputedWidth()
121
+ }
122
+
123
+ getComputedHeight(): number {
124
+ return this.yoga.getComputedHeight()
125
+ }
126
+
127
+ getComputedBorder(edge: LayoutEdge): number {
128
+ return this.yoga.getComputedBorder(EDGE_MAP[edge]!)
129
+ }
130
+
131
+ getComputedPadding(edge: LayoutEdge): number {
132
+ return this.yoga.getComputedPadding(EDGE_MAP[edge]!)
133
+ }
134
+
135
+ // Style setters
136
+
137
+ setWidth(value: number): void {
138
+ this.yoga.setWidth(value)
139
+ }
140
+ setWidthPercent(value: number): void {
141
+ this.yoga.setWidthPercent(value)
142
+ }
143
+ setWidthAuto(): void {
144
+ this.yoga.setWidthAuto()
145
+ }
146
+ setHeight(value: number): void {
147
+ this.yoga.setHeight(value)
148
+ }
149
+ setHeightPercent(value: number): void {
150
+ this.yoga.setHeightPercent(value)
151
+ }
152
+ setHeightAuto(): void {
153
+ this.yoga.setHeightAuto()
154
+ }
155
+ setMinWidth(value: number): void {
156
+ this.yoga.setMinWidth(value)
157
+ }
158
+ setMinWidthPercent(value: number): void {
159
+ this.yoga.setMinWidthPercent(value)
160
+ }
161
+ setMinHeight(value: number): void {
162
+ this.yoga.setMinHeight(value)
163
+ }
164
+ setMinHeightPercent(value: number): void {
165
+ this.yoga.setMinHeightPercent(value)
166
+ }
167
+ setMaxWidth(value: number): void {
168
+ this.yoga.setMaxWidth(value)
169
+ }
170
+ setMaxWidthPercent(value: number): void {
171
+ this.yoga.setMaxWidthPercent(value)
172
+ }
173
+ setMaxHeight(value: number): void {
174
+ this.yoga.setMaxHeight(value)
175
+ }
176
+ setMaxHeightPercent(value: number): void {
177
+ this.yoga.setMaxHeightPercent(value)
178
+ }
179
+
180
+ setFlexDirection(dir: LayoutFlexDirection): void {
181
+ const map: Record<LayoutFlexDirection, FlexDirection> = {
182
+ row: FlexDirection.Row,
183
+ 'row-reverse': FlexDirection.RowReverse,
184
+ column: FlexDirection.Column,
185
+ 'column-reverse': FlexDirection.ColumnReverse
186
+ }
187
+
188
+ this.yoga.setFlexDirection(map[dir]!)
189
+ }
190
+
191
+ setFlexGrow(value: number): void {
192
+ this.yoga.setFlexGrow(value)
193
+ }
194
+ setFlexShrink(value: number): void {
195
+ this.yoga.setFlexShrink(value)
196
+ }
197
+ setFlexBasis(value: number): void {
198
+ this.yoga.setFlexBasis(value)
199
+ }
200
+ setFlexBasisPercent(value: number): void {
201
+ this.yoga.setFlexBasisPercent(value)
202
+ }
203
+
204
+ setFlexWrap(wrap: LayoutWrap): void {
205
+ const map: Record<LayoutWrap, Wrap> = {
206
+ nowrap: Wrap.NoWrap,
207
+ wrap: Wrap.Wrap,
208
+ 'wrap-reverse': Wrap.WrapReverse
209
+ }
210
+
211
+ this.yoga.setFlexWrap(map[wrap]!)
212
+ }
213
+
214
+ setAlignItems(align: LayoutAlign): void {
215
+ const map: Record<LayoutAlign, Align> = {
216
+ auto: Align.Auto,
217
+ stretch: Align.Stretch,
218
+ 'flex-start': Align.FlexStart,
219
+ center: Align.Center,
220
+ 'flex-end': Align.FlexEnd
221
+ }
222
+
223
+ this.yoga.setAlignItems(map[align]!)
224
+ }
225
+
226
+ setAlignSelf(align: LayoutAlign): void {
227
+ const map: Record<LayoutAlign, Align> = {
228
+ auto: Align.Auto,
229
+ stretch: Align.Stretch,
230
+ 'flex-start': Align.FlexStart,
231
+ center: Align.Center,
232
+ 'flex-end': Align.FlexEnd
233
+ }
234
+
235
+ this.yoga.setAlignSelf(map[align]!)
236
+ }
237
+
238
+ setJustifyContent(justify: LayoutJustify): void {
239
+ const map: Record<LayoutJustify, Justify> = {
240
+ 'flex-start': Justify.FlexStart,
241
+ center: Justify.Center,
242
+ 'flex-end': Justify.FlexEnd,
243
+ 'space-between': Justify.SpaceBetween,
244
+ 'space-around': Justify.SpaceAround,
245
+ 'space-evenly': Justify.SpaceEvenly
246
+ }
247
+
248
+ this.yoga.setJustifyContent(map[justify]!)
249
+ }
250
+
251
+ setDisplay(display: LayoutDisplay): void {
252
+ this.yoga.setDisplay(display === 'flex' ? Display.Flex : Display.None)
253
+ }
254
+
255
+ getDisplay(): LayoutDisplay {
256
+ return this.yoga.getDisplay() === Display.None ? LayoutDisplay.None : LayoutDisplay.Flex
257
+ }
258
+
259
+ setPositionType(type: LayoutPositionType): void {
260
+ this.yoga.setPositionType(type === 'absolute' ? PositionType.Absolute : PositionType.Relative)
261
+ }
262
+
263
+ setPosition(edge: LayoutEdge, value: number): void {
264
+ this.yoga.setPosition(EDGE_MAP[edge]!, value)
265
+ }
266
+
267
+ setPositionPercent(edge: LayoutEdge, value: number): void {
268
+ this.yoga.setPositionPercent(EDGE_MAP[edge]!, value)
269
+ }
270
+
271
+ setOverflow(overflow: LayoutOverflow): void {
272
+ const map: Record<LayoutOverflow, Overflow> = {
273
+ visible: Overflow.Visible,
274
+ hidden: Overflow.Hidden,
275
+ scroll: Overflow.Scroll
276
+ }
277
+
278
+ this.yoga.setOverflow(map[overflow]!)
279
+ }
280
+
281
+ setMargin(edge: LayoutEdge, value: number): void {
282
+ this.yoga.setMargin(EDGE_MAP[edge]!, value)
283
+ }
284
+ setPadding(edge: LayoutEdge, value: number): void {
285
+ this.yoga.setPadding(EDGE_MAP[edge]!, value)
286
+ }
287
+ setBorder(edge: LayoutEdge, value: number): void {
288
+ this.yoga.setBorder(EDGE_MAP[edge]!, value)
289
+ }
290
+ setGap(gutter: LayoutGutter, value: number): void {
291
+ this.yoga.setGap(GUTTER_MAP[gutter]!, value)
292
+ }
293
+
294
+ // Lifecycle
295
+
296
+ free(): void {
297
+ this.yoga.free()
298
+ }
299
+ freeRecursive(): void {
300
+ this.yoga.freeRecursive()
301
+ }
302
+ }
303
+
304
+ // --
305
+ // Instance management
306
+ //
307
+ // The TS yoga-layout port is synchronous — no WASM loading, no linear memory
308
+ // growth, so no preload/swap/reset machinery is needed. The Yoga instance is
309
+ // just a plain JS object available at import time.
310
+
311
+ export function createYogaLayoutNode(): LayoutNode {
312
+ return new YogaLayoutNode(Yoga.Node.create())
313
+ }
@@ -0,0 +1,38 @@
1
+ import { lruEvict } from './lru.js'
2
+ import { stringWidth } from './stringWidth.js'
3
+
4
+ // During streaming, text grows but completed lines are immutable.
5
+ // Caching stringWidth per-line avoids re-measuring hundreds of
6
+ // unchanged lines on every token (~50x reduction in stringWidth calls).
7
+ const cache = new Map<string, number>()
8
+
9
+ const MAX_CACHE_SIZE = 4096
10
+
11
+ export function lineWidth(line: string): number {
12
+ const cached = cache.get(line)
13
+
14
+ if (cached !== undefined) {
15
+ cache.delete(line)
16
+ cache.set(line, cached)
17
+
18
+ return cached
19
+ }
20
+
21
+ const width = stringWidth(line)
22
+
23
+ if (cache.size >= MAX_CACHE_SIZE) {
24
+ cache.delete(cache.keys().next().value!)
25
+ }
26
+
27
+ cache.set(line, width)
28
+
29
+ return width
30
+ }
31
+
32
+ export function lineWidthCacheSize(): number {
33
+ return cache.size
34
+ }
35
+
36
+ export function evictLineWidthCache(keepRatio = 0): void {
37
+ lruEvict(cache, keepRatio)
38
+ }