@digithings-ai/ui 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (424) hide show
  1. package/README.md +48 -2
  2. package/package.json +143 -4
  3. package/src/components/NavShell.tsx +776 -0
  4. package/src/components/SocialRow.tsx +87 -0
  5. package/src/components/Spinner.tsx +27 -0
  6. package/src/components/StackLogo.tsx +40 -0
  7. package/src/components/Terminal.tsx +110 -0
  8. package/src/components/TerminalManifest.tsx +212 -0
  9. package/src/components/ThemeProvider.tsx +271 -0
  10. package/src/components/account/AuthCard.tsx +309 -0
  11. package/src/components/assistant-ui/elements/mermaid-diagram.aui.tsx +63 -0
  12. package/src/components/assistant-ui/elements/mermaid-diagram.tsx +340 -0
  13. package/src/components/brand/BrandWordmark.tsx +32 -0
  14. package/src/components/changelog/ReleaseRail.tsx +81 -0
  15. package/src/components/changelog/index.ts +1 -0
  16. package/src/components/chat/ChatCodeBlock.tsx +67 -0
  17. package/src/components/chat/ChatMarkdown.tsx +66 -0
  18. package/src/components/chat/ChatMarkdownSource.tsx +203 -0
  19. package/src/components/chat/ChatMermaidBlock.tsx +202 -0
  20. package/src/components/chat/ChatMessage.tsx +77 -0
  21. package/src/components/chat/ChatPlayback.tsx +422 -0
  22. package/src/components/chat/ChatStreamCursor.tsx +25 -0
  23. package/src/components/chat/ChatThinking.tsx +113 -0
  24. package/src/components/chat/ChatToolCall.tsx +190 -0
  25. package/src/components/chat/ChatTranscript.tsx +60 -0
  26. package/src/components/chat/ChatWidgetFrame.tsx +107 -0
  27. package/src/components/chat/DigichatBootLoader.tsx +683 -0
  28. package/src/components/chat/DigichatLauncher.tsx +361 -0
  29. package/src/components/chat/DigichatThread.tsx +118 -0
  30. package/src/components/chat/DigichatThreadList.tsx +54 -0
  31. package/src/components/chat/DigichatWordmark.tsx +24 -0
  32. package/src/components/chat/DotMatrix.tsx +650 -0
  33. package/src/components/chat/boot-lab.tsx +766 -0
  34. package/src/components/chat/boot-signal.ts +144 -0
  35. package/src/components/chat/chat-surfaces.ts +52 -0
  36. package/src/components/chat/connection-status.ts +40 -0
  37. package/src/components/chat/digichat-wordmark.ts +355 -0
  38. package/src/components/chat/disclosure-chevron.tsx +49 -0
  39. package/src/components/chat/followable-href.ts +9 -0
  40. package/src/components/chat/gallery-thread/action-icons.tsx +25 -0
  41. package/src/components/chat/gallery-thread/attachment.aui.tsx +262 -0
  42. package/src/components/chat/gallery-thread/block-caret.tsx +439 -0
  43. package/src/components/chat/gallery-thread/cn.ts +1 -0
  44. package/src/components/chat/gallery-thread/composer-keyboard.ts +106 -0
  45. package/src/components/chat/gallery-thread/composer-trigger-popover.aui.tsx +235 -0
  46. package/src/components/chat/gallery-thread/css.d.ts +6 -0
  47. package/src/components/chat/gallery-thread/file.tsx +238 -0
  48. package/src/components/chat/gallery-thread/follow-up-suggestions.aui.tsx +92 -0
  49. package/src/components/chat/gallery-thread/format-json-dump.ts +112 -0
  50. package/src/components/chat/gallery-thread/hooks/use-attachment-src.ts +46 -0
  51. package/src/components/chat/gallery-thread/hooks/use-copy-to-clipboard.ts +9 -0
  52. package/src/components/chat/gallery-thread/image.tsx +519 -0
  53. package/src/components/chat/gallery-thread/markdown-text.tsx +278 -0
  54. package/src/components/chat/gallery-thread/message-error.aui.tsx +105 -0
  55. package/src/components/chat/gallery-thread/message-timing.aui.tsx +143 -0
  56. package/src/components/chat/gallery-thread/private-work-step.tsx +188 -0
  57. package/src/components/chat/gallery-thread/reasoning.tsx +332 -0
  58. package/src/components/chat/gallery-thread/scroll-mode.ts +174 -0
  59. package/src/components/chat/gallery-thread/source.tsx +76 -0
  60. package/src/components/chat/gallery-thread/thread.aui.tsx +1619 -0
  61. package/src/components/chat/gallery-thread/tooltip-icon-button.tsx +53 -0
  62. package/src/components/chat/gallery-thread/typed-welcome-copy.tsx +18 -0
  63. package/src/components/chat/gallery-thread/ui/tooltip.tsx +22 -0
  64. package/src/components/chat/gallery-thread/work-chain-summary.tsx +48 -0
  65. package/src/components/chat/gallery-thread/work-chain.tsx +110 -0
  66. package/src/components/chat/gallery-thread/work-status.ts +66 -0
  67. package/src/components/chat/overlay-scrollbar.tsx +86 -0
  68. package/src/components/chat/sanitize-mermaid-svg.ts +38 -0
  69. package/src/components/chat/skins/SOURCE.md +36 -0
  70. package/src/components/chat/skins/base/attachment.aui.tsx +287 -0
  71. package/src/components/chat/skins/base/aui-default/README.md +45 -0
  72. package/src/components/chat/skins/base/aui-default/collapsible-root.tsx +19 -0
  73. package/src/components/chat/skins/base/aui-default/collapsible.tsx +21 -0
  74. package/src/components/chat/skins/base/aui-default/reasoning.aui.tsx +120 -0
  75. package/src/components/chat/skins/base/aui-default/reasoning.tsx +331 -0
  76. package/src/components/chat/skins/base/aui-default/surfaces.ts +7 -0
  77. package/src/components/chat/skins/base/aui-default/tool-fallback.aui.tsx +772 -0
  78. package/src/components/chat/skins/base/aui-default/tool-group.aui.tsx +241 -0
  79. package/src/components/chat/skins/base/docs-model-options.ts +6 -0
  80. package/src/components/chat/skins/base/elements/assistant-trace.aui.tsx +169 -0
  81. package/src/components/chat/skins/base/elements/composer-trigger-popover.aui.tsx +271 -0
  82. package/src/components/chat/skins/base/elements/directive-text.aui.tsx +29 -0
  83. package/src/components/chat/skins/base/elements/directive-text.tsx +76 -0
  84. package/src/components/chat/skins/base/elements/message-timing.aui.tsx +104 -0
  85. package/src/components/chat/skins/base/elements/model-selector.aui.tsx +140 -0
  86. package/src/components/chat/skins/base/elements/model-selector.tsx +720 -0
  87. package/src/components/chat/skins/base/elements/quote.aui.tsx +290 -0
  88. package/src/components/chat/skins/base/elements/work-chain.tsx +100 -0
  89. package/src/components/chat/skins/base/markdown-text.tsx +294 -0
  90. package/src/components/chat/skins/base/model.ts +1 -0
  91. package/src/components/chat/skins/base/thread.tsx +1050 -0
  92. package/src/components/chat/skins/base/tooltip-icon-button.tsx +56 -0
  93. package/src/components/chat/skins/base/ui/avatar.tsx +115 -0
  94. package/src/components/chat/skins/base/ui/badge.tsx +51 -0
  95. package/src/components/chat/skins/base/ui/button.tsx +67 -0
  96. package/src/components/chat/skins/base/ui/command.tsx +185 -0
  97. package/src/components/chat/skins/base/ui/dialog.tsx +168 -0
  98. package/src/components/chat/skins/base/ui/dot-matrix.tsx +267 -0
  99. package/src/components/chat/skins/base/ui/popover.tsx +97 -0
  100. package/src/components/chat/skins/base/ui/skeleton.tsx +20 -0
  101. package/src/components/chat/skins/base/ui/textarea.tsx +24 -0
  102. package/src/components/chat/skins/base/ui/tooltip.tsx +73 -0
  103. package/src/components/chat/skins/base-assistant-ui/config-provider.tsx +90 -0
  104. package/src/components/chat/skins/base-assistant-ui/defaults.ts +419 -0
  105. package/src/components/chat/skins/base-assistant-ui/index.tsx +44 -0
  106. package/src/components/chat/skins/chatgpt.tsx +448 -0
  107. package/src/components/chat/skins/claude.tsx +380 -0
  108. package/src/components/chat/skins/digichat-composer-toolbar.tsx +151 -0
  109. package/src/components/chat/skins/digichat-context-meter-shares.ts +158 -0
  110. package/src/components/chat/skins/digichat-context-meter.tsx +243 -0
  111. package/src/components/chat/skins/digichat-meter-tone.ts +26 -0
  112. package/src/components/chat/skins/digichat-usage-meter.tsx +103 -0
  113. package/src/components/chat/skins/digichat.tsx +144 -0
  114. package/src/components/chat/skins/expo-react-native.tsx +29 -0
  115. package/src/components/chat/skins/gemini.tsx +322 -0
  116. package/src/components/chat/skins/grok-icon.tsx +34 -0
  117. package/src/components/chat/skins/grok.tsx +369 -0
  118. package/src/components/chat/skins/index.ts +46 -0
  119. package/src/components/chat/skins/perplexity.tsx +462 -0
  120. package/src/components/chat/skins/product-page-assistant/assistant-modal.tsx +73 -0
  121. package/src/components/chat/skins/product-page-assistant/index.tsx +19 -0
  122. package/src/components/chat/skins/product-page-assistant/product-dashboard.tsx +164 -0
  123. package/src/components/chat/skins/react-ink.tsx +97 -0
  124. package/src/components/chat/skins/thread-skin-host-contract.ts +102 -0
  125. package/src/components/chat/skins/thread-skin-view.tsx +156 -0
  126. package/src/components/chat/skins/thread-skins.ts +143 -0
  127. package/src/components/chat/skins/tooltip-icon-button.tsx +35 -0
  128. package/src/components/chat/skins/ui/dropdown-menu.tsx +272 -0
  129. package/src/components/chat/skins/webpage-assistant/assistant-config.ts +238 -0
  130. package/src/components/chat/skins/webpage-assistant/assistant-modal.tsx +78 -0
  131. package/src/components/chat/skins/webpage-assistant/config-provider.tsx +132 -0
  132. package/src/components/chat/skins/webpage-assistant/docs-app.tsx +106 -0
  133. package/src/components/chat/skins/webpage-assistant/docs-article.tsx +109 -0
  134. package/src/components/chat/skins/webpage-assistant/docs-assistant.tsx +73 -0
  135. package/src/components/chat/skins/webpage-assistant/docs-nav.tsx +81 -0
  136. package/src/components/chat/skins/webpage-assistant/host-ui.ts +79 -0
  137. package/src/components/chat/skins/webpage-assistant/index.tsx +12 -0
  138. package/src/components/chat/skins/webpage-assistant/markdown-page.tsx +11 -0
  139. package/src/components/chat/skins/webpage-assistant/pages.ts +9 -0
  140. package/src/components/chat/skins/webpage-assistant/types.ts +178 -0
  141. package/src/components/chat/skins/webpage-assistant/use-mobile.ts +19 -0
  142. package/src/components/chat/stock/SOURCE.md +90 -0
  143. package/src/components/chat/stock/artifacts-panel.tsx +305 -0
  144. package/src/components/chat/stock/attachment.aui.tsx +280 -0
  145. package/src/components/chat/stock/chat-notice.tsx +143 -0
  146. package/src/components/chat/stock/chat-private-mode.tsx +64 -0
  147. package/src/components/chat/stock/deploy-ui-context.tsx +89 -0
  148. package/src/components/chat/stock/embed-chat-prefs.tsx +471 -0
  149. package/src/components/chat/stock/file.tsx +265 -0
  150. package/src/components/chat/stock/follow-up-suggestions.aui.tsx +83 -0
  151. package/src/components/chat/stock/image.tsx +531 -0
  152. package/src/components/chat/stock/index.ts +129 -0
  153. package/src/components/chat/stock/json-view.tsx +140 -0
  154. package/src/components/chat/stock/markdown-text.tsx +319 -0
  155. package/src/components/chat/stock/message-error.aui.tsx +96 -0
  156. package/src/components/chat/stock/message-export-menu.tsx +156 -0
  157. package/src/components/chat/stock/palette-row-preview.tsx +26 -0
  158. package/src/components/chat/stock/reasoning.aui.tsx +120 -0
  159. package/src/components/chat/stock/reasoning.tsx +335 -0
  160. package/src/components/chat/stock/skin-chrome.tsx +81 -0
  161. package/src/components/chat/stock/skin-credit.tsx +63 -0
  162. package/src/components/chat/stock/skin-palette-bridge.tsx +235 -0
  163. package/src/components/chat/stock/skin-palette-context.ts +16 -0
  164. package/src/components/chat/stock/skin-runtime.tsx +52 -0
  165. package/src/components/chat/stock/skin-slash-palette.tsx +393 -0
  166. package/src/components/chat/stock/skin-types.ts +217 -0
  167. package/src/components/chat/stock/stock-chat-prefs-host.tsx +501 -0
  168. package/src/components/chat/stock/stock-send-gate.tsx +94 -0
  169. package/src/components/chat/stock/stock-shape.tsx +39 -0
  170. package/src/components/chat/stock/thread.aui.tsx +645 -0
  171. package/src/components/chat/stock/tool-display.ts +6 -0
  172. package/src/components/chat/stock/tool-fallback.aui.tsx +866 -0
  173. package/src/components/chat/stock/tool-group.aui.tsx +244 -0
  174. package/src/components/chat/stock/tool-surface.ts +120 -0
  175. package/src/components/chat/stock/tooltip-icon-button.tsx +49 -0
  176. package/src/components/chat/stock/ui/avatar.tsx +108 -0
  177. package/src/components/chat/stock/ui/button.tsx +81 -0
  178. package/src/components/chat/stock/ui/collapsible.tsx +21 -0
  179. package/src/components/chat/stock/ui/dialog.tsx +163 -0
  180. package/src/components/chat/stock/ui/skeleton.tsx +13 -0
  181. package/src/components/chat/stock/ui/textarea.tsx +20 -0
  182. package/src/components/chat/stock/ui/tooltip.tsx +68 -0
  183. package/src/components/chat/stock/use-attachment-src.ts +42 -0
  184. package/src/components/chat/stock/use-copy-to-clipboard.ts +29 -0
  185. package/src/components/chat/strip-model-boilerplate.ts +42 -0
  186. package/src/components/chat/suggestion-cycle.tsx +230 -0
  187. package/src/components/chat/suggestion-scroll-row.tsx +81 -0
  188. package/src/components/chat/trace-grouping/chain-group-by.ts +44 -0
  189. package/src/components/chat/trace-grouping/chain-state.ts +141 -0
  190. package/src/components/chat/trace-grouping/index.ts +32 -0
  191. package/src/components/chat/trace-grouping/tool-row.ts +74 -0
  192. package/src/components/chat/trace-grouping/use-deploy-work-disclosure.ts +35 -0
  193. package/src/components/chat/trace-grouping/use-work-chain.ts +103 -0
  194. package/src/components/chat/trace-i18n/core.ts +48 -0
  195. package/src/components/chat/trace-i18n/index.tsx +23 -0
  196. package/src/components/chat/trace-i18n/locales/en.ts +24 -0
  197. package/src/components/chat/trace-i18n/locales/fr.ts +28 -0
  198. package/src/components/chat/trace-i18n/types.ts +35 -0
  199. package/src/components/chat/trace-spacing.ts +249 -0
  200. package/src/components/chat/transcript/activity-view.ts +375 -0
  201. package/src/components/chat/transcript/chat-export.ts +133 -0
  202. package/src/components/chat/transcript/index.ts +10 -0
  203. package/src/components/chat/transcript/save-file.ts +209 -0
  204. package/src/components/chat/transcript/transcript-markdown.ts +428 -0
  205. package/src/components/chat/transcript/types.ts +81 -0
  206. package/src/components/chat/turn-outcome.ts +52 -0
  207. package/src/components/chat/use-warmup-phase.ts +18 -0
  208. package/src/components/chat/work-status-lead.tsx +49 -0
  209. package/src/components/chrome.tsx +264 -0
  210. package/src/components/command-palette/CommandPalette.tsx +404 -0
  211. package/src/components/command-palette/index.ts +6 -0
  212. package/src/components/contact/ContactMailto.tsx +112 -0
  213. package/src/components/contact/index.ts +5 -0
  214. package/src/components/conviction/ConvictionMeter.tsx +40 -0
  215. package/src/components/conviction/SignedConvictionBadge.tsx +26 -0
  216. package/src/components/conviction/index.ts +7 -0
  217. package/src/components/data-layout/BentoGrid.tsx +52 -0
  218. package/src/components/data-layout/CardRail.tsx +150 -0
  219. package/src/components/data-layout/DotMatrixStat.tsx +65 -0
  220. package/src/components/data-layout/FeatureCell.tsx +80 -0
  221. package/src/components/data-layout/MediaFrame.tsx +125 -0
  222. package/src/components/data-layout/ModuleGrid.tsx +735 -0
  223. package/src/components/data-layout/Odometer.tsx +149 -0
  224. package/src/components/data-layout/ProductFrame.tsx +79 -0
  225. package/src/components/data-layout/TestimonialWall.tsx +139 -0
  226. package/src/components/data-layout/index.ts +19 -0
  227. package/src/components/data-layout/treemap.ts +368 -0
  228. package/src/components/deck/DeckStack.tsx +243 -0
  229. package/src/components/desk/DataTable.tsx +373 -0
  230. package/src/components/desk/KpiGrid.tsx +80 -0
  231. package/src/components/desk/Sparkline.tsx +63 -0
  232. package/src/components/desk/StateBlock.tsx +132 -0
  233. package/src/components/desk/index.ts +18 -0
  234. package/src/components/diagrams/ArchitectureDiagram.tsx +350 -0
  235. package/src/components/diagrams/ArchitectureTour.tsx +912 -0
  236. package/src/components/diagrams/TerminalSchematic.tsx +192 -0
  237. package/src/components/diagrams/architecture-svg.tsx +384 -0
  238. package/src/components/diagrams/index.ts +30 -0
  239. package/src/components/diagrams/mermaid-theme.ts +115 -0
  240. package/src/components/diagrams/tour-camera.ts +171 -0
  241. package/src/components/docs/CodeTabs.tsx +90 -0
  242. package/src/components/docs/CopyCommand.tsx +151 -0
  243. package/src/components/docs/DocsLayout.tsx +197 -0
  244. package/src/components/docs/DocsSearch.tsx +97 -0
  245. package/src/components/docs/Endpoint.tsx +135 -0
  246. package/src/components/document/DocumentFrame.tsx +43 -0
  247. package/src/components/document/GlyphList.tsx +51 -0
  248. package/src/components/document/PageTitle.tsx +44 -0
  249. package/src/components/document/Prose.tsx +38 -0
  250. package/src/components/document/Section.tsx +55 -0
  251. package/src/components/document/index.ts +13 -0
  252. package/src/components/effects-chrome/AnnouncementBar.tsx +88 -0
  253. package/src/components/effects-chrome/HorizontalScrollTrack.tsx +461 -0
  254. package/src/components/effects-chrome/Pipeline.tsx +226 -0
  255. package/src/components/effects-chrome/RotatingPrompts.tsx +116 -0
  256. package/src/components/effects-chrome/StackingPanels.tsx +101 -0
  257. package/src/components/effects-chrome/TabStrip.tsx +232 -0
  258. package/src/components/effects-chrome/ToastStack.tsx +201 -0
  259. package/src/components/effects-chrome/horizontal-track-core.ts +70 -0
  260. package/src/components/effects-chrome/index.ts +35 -0
  261. package/src/components/emblems.tsx +188 -0
  262. package/src/components/faviconTheme.ts +23 -0
  263. package/src/components/figure/Figure.tsx +38 -0
  264. package/src/components/figure/index.ts +2 -0
  265. package/src/components/finance-charts/DrawdownPlot.tsx +76 -0
  266. package/src/components/finance-charts/EquityCurve.tsx +71 -0
  267. package/src/components/finance-charts/PriceChart.tsx +119 -0
  268. package/src/components/finance-charts/chart-host.tsx +236 -0
  269. package/src/components/finance-charts/chart-scale.ts +93 -0
  270. package/src/components/finance-charts/demo-data.ts +88 -0
  271. package/src/components/finance-charts/index.ts +46 -0
  272. package/src/components/finance-charts/lw-chart.tsx +292 -0
  273. package/src/components/finance-composites/MarketBar.tsx +243 -0
  274. package/src/components/finance-composites/OrderBook.tsx +133 -0
  275. package/src/components/finance-composites/PerformanceDashboard.tsx +185 -0
  276. package/src/components/finance-composites/SortableTable.tsx +144 -0
  277. package/src/components/finance-composites/StockTicker.tsx +65 -0
  278. package/src/components/finance-composites/SyncedTearsheet.tsx +226 -0
  279. package/src/components/finance-composites/index.ts +28 -0
  280. package/src/components/finance-tearsheet/KpiStrip.tsx +49 -0
  281. package/src/components/finance-tearsheet/LiveBadge.tsx +29 -0
  282. package/src/components/finance-tearsheet/ReturnsMatrix.tsx +321 -0
  283. package/src/components/finance-tearsheet/StrategyTearsheet.tsx +99 -0
  284. package/src/components/finance-tearsheet/TearsheetCard.tsx +54 -0
  285. package/src/components/finance-tearsheet/TradeLogTable.tsx +73 -0
  286. package/src/components/finance-tearsheet/charts.tsx +2624 -0
  287. package/src/components/finance-tearsheet/demo-data.ts +177 -0
  288. package/src/components/finance-tearsheet/format.ts +41 -0
  289. package/src/components/finance-tearsheet/index.ts +120 -0
  290. package/src/components/finance-tearsheet/print.ts +52 -0
  291. package/src/components/finance-tearsheet/risk-bands.ts +48 -0
  292. package/src/components/finance-tearsheet/stats.ts +35 -0
  293. package/src/components/finance-tearsheet/strategy-sheet-model.ts +238 -0
  294. package/src/components/finance-tearsheet/types.ts +58 -0
  295. package/src/components/footer/FooterCells.tsx +109 -0
  296. package/src/components/footer/index.ts +6 -0
  297. package/src/components/graph.tsx +158 -0
  298. package/src/components/icons.tsx +98 -0
  299. package/src/components/landing/PixelWordmark.tsx +36 -0
  300. package/src/components/logos.ts +39 -0
  301. package/src/components/marquee/Marquee.tsx +204 -0
  302. package/src/components/metrics/PerfMetrics.tsx +68 -0
  303. package/src/components/metrics/StatCounter.tsx +104 -0
  304. package/src/components/page-geometry.tsx +177 -0
  305. package/src/components/pricing/Pricing.tsx +174 -0
  306. package/src/components/pricing/PricingMatrix.tsx +219 -0
  307. package/src/components/prose/index.ts +2 -0
  308. package/src/components/prose/prose.tsx +86 -0
  309. package/src/components/repo-activity/RepoActivity.tsx +599 -0
  310. package/src/components/repo-activity/RepoHeatmap.tsx +225 -0
  311. package/src/components/repo-activity/demo.ts +201 -0
  312. package/src/components/repo-activity/fetch.ts +211 -0
  313. package/src/components/repo-activity/heatmap.ts +123 -0
  314. package/src/components/repo-activity/index.ts +28 -0
  315. package/src/components/repo-activity/types.ts +99 -0
  316. package/src/components/stages/NumberedStages.tsx +116 -0
  317. package/src/components/symbols/marks.tsx +116 -0
  318. package/src/components/symbols/terminal-lockup.tsx +136 -0
  319. package/src/components/symbols/terminal-marks.tsx +226 -0
  320. package/src/components/terminal/ChatResponseLoader.tsx +67 -0
  321. package/src/components/terminal/ContainerBootLoader.tsx +82 -0
  322. package/src/components/terminal/TerminalStepCaret.tsx +202 -0
  323. package/src/components/themeInit.ts +24 -0
  324. package/src/components/typography/MotionReveal.tsx +108 -0
  325. package/src/components/typography/TypewriterReveal.tsx +101 -0
  326. package/src/components/typography/WordReveal.tsx +143 -0
  327. package/src/data/modules.ts +378 -0
  328. package/src/data/subsystems.ts +101 -0
  329. package/src/index.ts +587 -0
  330. package/src/lib/base-path.ts +60 -0
  331. package/src/lib/cx.ts +25 -0
  332. package/src/lib/gloomberb.ts +69 -0
  333. package/src/lib/record.ts +19 -0
  334. package/src/lib/stub-payload.ts +183 -0
  335. package/src/lib/useBodyScrollLock.ts +44 -0
  336. package/src/lib/utils.ts +6 -0
  337. package/src/motion/primitives.tsx +105 -0
  338. package/src/motion/scroll-glide.ts +62 -0
  339. package/src/motion/scrolly-core.ts +38 -0
  340. package/src/motion/scrolly.tsx +95 -0
  341. package/src/navigation/HashScrollManager.tsx +167 -0
  342. package/src/navigation/hashScroll.ts +78 -0
  343. package/src/replay/browser.ts +280 -0
  344. package/src/replay/chat-export-run.ts +121 -0
  345. package/src/replay/export-format.ts +25 -0
  346. package/src/replay/export-mount.ts +32 -0
  347. package/src/replay/filename.ts +54 -0
  348. package/src/replay/index.ts +21 -0
  349. package/src/replay/redact-dom.ts +178 -0
  350. package/src/replay/redact.ts +113 -0
  351. package/src/replay/snapshot.ts +659 -0
  352. package/src/styles/account-auth.css +339 -0
  353. package/src/styles/brand-wordmark.css +11 -0
  354. package/src/styles/card-rail.css +120 -0
  355. package/src/styles/chat-aui.css +1143 -0
  356. package/src/styles/chat-core.css +469 -0
  357. package/src/styles/chat-digichat.css +2531 -0
  358. package/src/styles/chat-math.css +70 -0
  359. package/src/styles/chat-skin-palette.css +138 -0
  360. package/src/styles/chat-stock-menu.css +37 -0
  361. package/src/styles/chat-widgets.css +190 -0
  362. package/src/styles/command-palette.css +372 -0
  363. package/src/styles/controls-core.css +2261 -0
  364. package/src/styles/controls-overlay.css +603 -0
  365. package/src/styles/data-layout.css +288 -0
  366. package/src/styles/deck.css +141 -0
  367. package/src/styles/diagrams.css +1860 -0
  368. package/src/styles/digichat-app-theme.css +250 -0
  369. package/src/styles/digichat-boot-loader.css +487 -0
  370. package/src/styles/digichat-launcher.css +377 -0
  371. package/src/styles/docs.css +165 -0
  372. package/src/styles/effects-chrome.css +888 -0
  373. package/src/styles/finance-composites.css +214 -0
  374. package/src/styles/finance-tearsheet-overlay.css +90 -0
  375. package/src/styles/finance-tearsheet.css +945 -0
  376. package/src/styles/marquee.css +168 -0
  377. package/src/styles/metrics.css +82 -0
  378. package/src/styles/nav-shell.css +551 -0
  379. package/src/styles/pricing.css +79 -0
  380. package/src/styles/repo-activity.css +575 -0
  381. package/src/styles/stages.css +69 -0
  382. package/src/styles/terminal-loaders.css +122 -0
  383. package/src/styles/terminal-manifest.css +228 -0
  384. package/src/styles/web-theme.css +1007 -0
  385. package/src/styles/word-reveal.css +204 -0
  386. package/src/theme/apply-theme.ts +214 -0
  387. package/src/theme/index.ts +27 -0
  388. package/src/theme/palette-registry.ts +855 -0
  389. package/src/theme/tui-prefs.ts +64 -0
  390. package/src/ui/alert.tsx +78 -0
  391. package/src/ui/avatar.tsx +104 -0
  392. package/src/ui/badge.tsx +75 -0
  393. package/src/ui/breadcrumb.tsx +61 -0
  394. package/src/ui/button.tsx +67 -0
  395. package/src/ui/card.tsx +139 -0
  396. package/src/ui/checkbox.tsx +27 -0
  397. package/src/ui/collapsible.tsx +32 -0
  398. package/src/ui/date-pager.tsx +325 -0
  399. package/src/ui/dialog.tsx +157 -0
  400. package/src/ui/dropdown-menu.tsx +267 -0
  401. package/src/ui/empty-state.tsx +165 -0
  402. package/src/ui/field.tsx +104 -0
  403. package/src/ui/form.tsx +36 -0
  404. package/src/ui/icon-button.tsx +36 -0
  405. package/src/ui/index.ts +34 -0
  406. package/src/ui/input.tsx +33 -0
  407. package/src/ui/kbd.tsx +30 -0
  408. package/src/ui/label.tsx +32 -0
  409. package/src/ui/pager.tsx +119 -0
  410. package/src/ui/pagination.tsx +126 -0
  411. package/src/ui/radio-group.tsx +51 -0
  412. package/src/ui/search-bar.tsx +85 -0
  413. package/src/ui/segmented-control.tsx +76 -0
  414. package/src/ui/select.tsx +257 -0
  415. package/src/ui/separator.tsx +24 -0
  416. package/src/ui/sheet.tsx +141 -0
  417. package/src/ui/skeleton.tsx +76 -0
  418. package/src/ui/slider.tsx +76 -0
  419. package/src/ui/switch.tsx +31 -0
  420. package/src/ui/table.tsx +179 -0
  421. package/src/ui/tabs.tsx +89 -0
  422. package/src/ui/tags-input.tsx +168 -0
  423. package/src/ui/textarea.tsx +17 -0
  424. package/src/ui/tooltip.tsx +71 -0
@@ -0,0 +1,44 @@
1
+ import { groupPartByType } from "@assistant-ui/react";
2
+
3
+ /**
4
+ * The chain grouping every first-party trace uses (the digichat skin's
5
+ * gallery thread, the base skins and the stock thread).
6
+ *
7
+ * Reasoning and tool calls nest under one `group-chainOfThought`, and inside
8
+ * it adjacent reasoning parts coalesce into `group-reasoning` and adjacent
9
+ * tool calls into `group-tool`.
10
+ *
11
+ * A source or a status part between two work runs must not split the chain:
12
+ * only text ends a work run, so two runs with nothing but a source between
13
+ * them are one chain, not two. The library's helper covers the part types it
14
+ * knows; the status parts (`data-*`) are matched here, and the memo
15
+ * fingerprint is kept so the tree is not rebuilt on every render.
16
+ */
17
+ export const chainGroupBy = (() => {
18
+ const base = groupPartByType({
19
+ reasoning: ["group-chainOfThought", "group-reasoning"],
20
+ "tool-call": ["group-chainOfThought", "group-tool"],
21
+ "standalone-tool-call": [],
22
+ source: ["group-chainOfThought", "group-tool"],
23
+ });
24
+ const fn = (part: { type: string; name?: string }, context?: unknown) => {
25
+ const dataName =
26
+ part.type === "data"
27
+ ? part.name
28
+ : part.type.startsWith("data-")
29
+ ? part.type.slice("data-".length)
30
+ : undefined;
31
+ // A data-notice (a rate-limit wait, and any other status notice) stays
32
+ // outside the chain. The chain folds once the answer arrives, which would
33
+ // hide the notice inside the collapsed work block.
34
+ if (dataName === "notice") return base(part as never, context as never);
35
+ if (part.type === "data" || part.type.startsWith("data-")) {
36
+ return ["group-chainOfThought", "group-tool"] as const;
37
+ }
38
+ return base(part as never, context as never);
39
+ };
40
+ (fn as unknown as Record<symbol, string>)[
41
+ Symbol.for("@assistant-ui/groupBy.memoKey")
42
+ ] = "digichat:chain-v3";
43
+ return fn;
44
+ })();
@@ -0,0 +1,141 @@
1
+ /**
2
+ * The trace grouping rules, as pure functions of the message parts and the
3
+ * disclosure policy. The digichat skin's gallery thread and the base skins
4
+ * both read them, so the two traces fold, open and count the same way and
5
+ * differ only in how they look.
6
+ *
7
+ * Kept free of React so a test can call every rule with plain objects.
8
+ */
9
+ import type { WorkDisclosure } from "../stock/skin-types";
10
+
11
+ /** The part fields the rules need. */
12
+ export type ChainPartLike = {
13
+ readonly type: string;
14
+ readonly text?: unknown;
15
+ };
16
+
17
+ /**
18
+ * Disclosure behaviour for one kind of row inside the chain. `off` hides it,
19
+ * `collapsed` renders it closed, `balanced` opens it while it streams,
20
+ * `expanded` starts open and `locked_open` pins it open.
21
+ */
22
+ export type ChainRowMode =
23
+ | "off"
24
+ | "collapsed"
25
+ | "balanced"
26
+ | "expanded"
27
+ | "locked_open";
28
+
29
+ const isWork = (part: ChainPartLike | undefined) =>
30
+ part?.type === "reasoning" || part?.type === "tool-call";
31
+
32
+ /** The message holds reasoning or a tool call somewhere. */
33
+ export function messageHasWork(parts: readonly (ChainPartLike | undefined)[]): boolean {
34
+ return parts.some(isWork);
35
+ }
36
+
37
+ /**
38
+ * Anything real arrived from the agent: reasoning, a tool call, the answer.
39
+ * A status part (the connection state) is not content; it is the
40
+ * pre-response phase, which is when the loading row belongs.
41
+ */
42
+ export function messageHasContent(parts: readonly (ChainPartLike | undefined)[]): boolean {
43
+ return parts.some((part) => part !== undefined && part.type !== "data");
44
+ }
45
+
46
+ /**
47
+ * The chain holds real work. The grouping puts status and source parts into
48
+ * the chain too; a chain of only those draws no header (the loading row
49
+ * covers that phase).
50
+ */
51
+ export function chainHoldsWork(
52
+ parts: readonly (ChainPartLike | undefined)[],
53
+ indices: readonly number[],
54
+ ): boolean {
55
+ return indices.some((index) => isWork(parts[index]));
56
+ }
57
+
58
+ /**
59
+ * Only text ends a work run: a chain with non-empty text after it has
60
+ * answered, so its work is over. A chain without one is still the agent's
61
+ * current work, even if the model streams another run of tool calls.
62
+ */
63
+ export function chainFollowedByText(
64
+ parts: readonly (ChainPartLike | undefined)[],
65
+ indices: readonly number[],
66
+ ): boolean {
67
+ const last = indices.length > 0 ? indices[indices.length - 1]! : -1;
68
+ return parts.some((part, index) => {
69
+ if (index <= last || part?.type !== "text") return false;
70
+ return typeof part.text === "string" && part.text.trim() !== "";
71
+ });
72
+ }
73
+
74
+ /** The tool calls in a tool group; sources and status parts do not count. */
75
+ export function chainToolCount(
76
+ parts: readonly (ChainPartLike | undefined)[],
77
+ indices: readonly number[],
78
+ ): number {
79
+ return indices.filter((index) => parts[index]?.type === "tool-call").length;
80
+ }
81
+
82
+ /** How long the chain waits before it folds away once its work is over. */
83
+ export const CHAIN_SETTLE_MS = 600;
84
+
85
+ /**
86
+ * Whether the whole chain is open. The first manual toggle wins; otherwise
87
+ * the verbose level keeps it open, the quiet level folds it as soon as the
88
+ * answer starts, and the balanced level folds it once the work has settled.
89
+ */
90
+ export function chainOpen({
91
+ userOpen,
92
+ openAtRest,
93
+ foldOnAnswer,
94
+ working,
95
+ settled,
96
+ }: {
97
+ userOpen: boolean | null;
98
+ openAtRest: boolean;
99
+ foldOnAnswer: boolean;
100
+ working: boolean;
101
+ settled: boolean;
102
+ }): boolean {
103
+ return userOpen ?? (openAtRest ? true : foldOnAnswer ? working : !settled && working);
104
+ }
105
+
106
+ export type ChainGroupDisclosure = {
107
+ /** Open on mount. */
108
+ defaultOpen: boolean;
109
+ /** Open while the group streams, folded again once it completes. */
110
+ streamingOpen: boolean;
111
+ /** Pinned open: the trigger does nothing. */
112
+ locked: boolean;
113
+ };
114
+
115
+ /** The `N tool calls` group inside the chain. */
116
+ export function toolGroupDisclosure(
117
+ disclosure: Pick<WorkDisclosure, "openAtRest" | "openWhileRunning">,
118
+ mode: ChainRowMode,
119
+ live: boolean,
120
+ ): ChainGroupDisclosure {
121
+ const locked = mode === "locked_open";
122
+ return {
123
+ locked,
124
+ defaultOpen: disclosure.openAtRest || mode === "expanded" || locked,
125
+ streamingOpen: (disclosure.openWhileRunning || mode === "balanced") && live,
126
+ };
127
+ }
128
+
129
+ /** The reasoning box inside the chain. */
130
+ export function reasoningGroupDisclosure(
131
+ disclosure: Pick<WorkDisclosure, "openAtRest" | "openWhileRunning">,
132
+ mode: ChainRowMode,
133
+ live: boolean,
134
+ ): ChainGroupDisclosure {
135
+ const locked = mode === "locked_open";
136
+ return {
137
+ locked,
138
+ defaultOpen: disclosure.openAtRest || mode === "expanded" || locked,
139
+ streamingOpen: live && (disclosure.openWhileRunning || mode === "balanced"),
140
+ };
141
+ }
@@ -0,0 +1,32 @@
1
+ export { chainGroupBy } from "./chain-group-by";
2
+ export {
3
+ CHAIN_SETTLE_MS,
4
+ chainFollowedByText,
5
+ chainHoldsWork,
6
+ chainOpen,
7
+ chainToolCount,
8
+ messageHasContent,
9
+ messageHasWork,
10
+ reasoningGroupDisclosure,
11
+ toolGroupDisclosure,
12
+ type ChainGroupDisclosure,
13
+ type ChainPartLike,
14
+ type ChainRowMode,
15
+ } from "./chain-state";
16
+ export {
17
+ useWorkChain,
18
+ type WorkChainMarker,
19
+ type WorkChainOptions,
20
+ type WorkChainState,
21
+ } from "./use-work-chain";
22
+ export {
23
+ effectiveToolStatus,
24
+ resolveToolStatus,
25
+ toolRowStatus,
26
+ type ToolRowStatus,
27
+ } from "./tool-row";
28
+ export {
29
+ useDeployWorkDisclosure,
30
+ useToolRowOpenWhileRunning,
31
+ type DeployWorkDisclosure,
32
+ } from "./use-deploy-work-disclosure";
@@ -0,0 +1,74 @@
1
+ /**
2
+ * What a tool-call row says about its call, shared by every first-party
3
+ * trace so the digichat skin and the base skins word a row the same way.
4
+ * Pure: no React, callable from a test with plain objects.
5
+ */
6
+ import type { ToolCallMessagePartStatus } from "@assistant-ui/react";
7
+ import { EN_TRACE_T, type TraceT } from "../trace-i18n/core";
8
+ import type { TurnOutcome } from "../turn-outcome";
9
+
10
+ /**
11
+ * assistant-ui's `toMessagePartStatus` returns `{ type: "complete" }` for any
12
+ * tool-call part with a defined `result` — even when `isError` is set, because
13
+ * an `output-error` part carries `result = { error }`. Derive the error state
14
+ * from `isError` so a failed or orphaned row does not render as success.
15
+ */
16
+ export function resolveToolStatus(
17
+ status: ToolCallMessagePartStatus | undefined,
18
+ isError: boolean | undefined,
19
+ result: unknown,
20
+ ): ToolCallMessagePartStatus | undefined {
21
+ if (!isError || status?.type === "incomplete") return status;
22
+ const error =
23
+ result && typeof result === "object" && "error" in result
24
+ ? (result as { error?: unknown }).error
25
+ : undefined;
26
+ return { type: "incomplete", reason: "error", error };
27
+ }
28
+
29
+ /**
30
+ * A call still waiting on a result when the turn was stopped will never get
31
+ * one: it reads cancelled, not "Waiting on tool". A call that waits on the
32
+ * visitor (approval, interrupt) keeps its controls.
33
+ */
34
+ export function effectiveToolStatus(
35
+ resolved: ToolCallMessagePartStatus | undefined,
36
+ outcome: TurnOutcome,
37
+ offersVisitorAction: boolean,
38
+ ): ToolCallMessagePartStatus | undefined {
39
+ return outcome === "stopped" &&
40
+ resolved?.type === "requires-action" &&
41
+ !offersVisitorAction
42
+ ? { type: "incomplete", reason: "cancelled" }
43
+ : resolved;
44
+ }
45
+
46
+ export type ToolRowStatus = {
47
+ label: string;
48
+ statusType: ToolCallMessagePartStatus["type"];
49
+ isRunning: boolean;
50
+ isCancelled: boolean;
51
+ isError: boolean;
52
+ };
53
+
54
+ /** The row's words for a tool status: one word per state, upstream wording. */
55
+ export function toolRowStatus(
56
+ status: ToolCallMessagePartStatus | undefined,
57
+ tr: TraceT = EN_TRACE_T,
58
+ ): ToolRowStatus {
59
+ const statusType = status?.type ?? "complete";
60
+ const isRunning = statusType === "running";
61
+ const isCancelled =
62
+ status?.type === "incomplete" && status.reason === "cancelled";
63
+ const isError = status?.type === "incomplete" && status.reason === "error";
64
+ const label = isCancelled
65
+ ? tr.t("cancelledTool")
66
+ : isError
67
+ ? tr.t("failedTool")
68
+ : statusType === "running"
69
+ ? tr.t("runningTool")
70
+ : statusType === "requires-action"
71
+ ? tr.t("waitingOnTool")
72
+ : tr.t("usedTool");
73
+ return { label, statusType, isRunning, isCancelled, isError };
74
+ }
@@ -0,0 +1,35 @@
1
+ "use client";
2
+
3
+ import { useDeployUi } from "../stock/deploy-ui-context";
4
+ import {
5
+ resolveWorkDisclosure,
6
+ workVisibilityForView,
7
+ type WorkDisclosure,
8
+ } from "../stock/skin-types";
9
+ import type { ChainRowMode } from "./chain-state";
10
+
11
+ export type DeployWorkDisclosure = {
12
+ reasoningMode: ChainRowMode;
13
+ toolCallsMode: ChainRowMode;
14
+ disclosure: WorkDisclosure;
15
+ };
16
+
17
+ /**
18
+ * The deploy's view level and row modes, resolved the way the digichat skin
19
+ * resolves them before handing them to its thread (`skins/digichat.tsx`), for
20
+ * skins that read them from context instead of props.
21
+ */
22
+ export function useDeployWorkDisclosure(): DeployWorkDisclosure {
23
+ const ui = useDeployUi();
24
+ return {
25
+ reasoningMode: ui.reasoning,
26
+ toolCallsMode: ui.toolCalls,
27
+ disclosure: resolveWorkDisclosure(workVisibilityForView(ui.view)),
28
+ };
29
+ }
30
+
31
+ /** Base skins: a tool card shows its arguments while its call runs. */
32
+ export function useToolRowOpenWhileRunning(): boolean {
33
+ const { toolCallsMode, disclosure } = useDeployWorkDisclosure();
34
+ return toolCallsMode !== "off" && disclosure.openWhileRunning;
35
+ }
@@ -0,0 +1,103 @@
1
+ "use client";
2
+
3
+ import { useEffect, useState } from "react";
4
+ import { useAuiState } from "@assistant-ui/react";
5
+ import { workStatusText } from "../gallery-thread/work-status";
6
+ import { useTraceT } from "../trace-i18n";
7
+ import { turnCutShort, useTurnOutcome, type TurnOutcome } from "../turn-outcome";
8
+ import { CHAIN_SETTLE_MS, chainOpen } from "./chain-state";
9
+
10
+ /** The header marker: what the chain is doing, or how it ended. */
11
+ export type WorkChainMarker = "loading" | "idle" | "error" | "stop";
12
+
13
+ export type WorkChainOptions = {
14
+ /**
15
+ * The message-part indices this chain holds. The folded header describes
16
+ * them ("Working — digisearch", "Used 3 tools"); without them the header
17
+ * keeps the plain title.
18
+ */
19
+ indices?: readonly number[] | undefined;
20
+ /** Nothing ever folds (the verbose level). */
21
+ openAtRest?: boolean | undefined;
22
+ /** Fold as soon as the answer starts, not when the work settles (quiet). */
23
+ foldOnAnswer?: boolean | undefined;
24
+ /** A text part follows this chain: its work is over. */
25
+ followedByText?: boolean | undefined;
26
+ };
27
+
28
+ export type WorkChainState = {
29
+ open: boolean;
30
+ onOpenChange: (open: boolean) => void;
31
+ /** The header text. */
32
+ title: string;
33
+ marker: WorkChainMarker;
34
+ /** `running`, `done`, or how a cut-short turn ended. */
35
+ outcome: "running" | "done" | Exclude<TurnOutcome, "running" | "done">;
36
+ };
37
+
38
+ /**
39
+ * The whole chain of reasoning and tool calls under one header: when it is
40
+ * open, what the header says and which marker it shows.
41
+ *
42
+ * The header stays open for the whole run of work (not only while a group
43
+ * happens to be running) so the block never flickers shut between two tool
44
+ * calls, and folds `CHAIN_SETTLE_MS` after the answer starts. Folded, the
45
+ * header is a live status line ("Working — web_search", "Used 3 tools");
46
+ * open, it is the plain "Working" / "Worked" title, because the rows are
47
+ * right underneath. The first manual toggle wins.
48
+ *
49
+ * A turn that was stopped or failed before any text is over too: the marker
50
+ * stops and the title says how it ended.
51
+ */
52
+ export function useWorkChain({
53
+ indices,
54
+ openAtRest = false,
55
+ foldOnAnswer = false,
56
+ followedByText = false,
57
+ }: WorkChainOptions): WorkChainState {
58
+ const [userOpen, setUserOpen] = useState<boolean | null>(null);
59
+ const [settled, setSettled] = useState(false);
60
+
61
+ const outcome = useTurnOutcome();
62
+ const cutShort = !followedByText && turnCutShort(outcome);
63
+ const working = !followedByText && !cutShort;
64
+
65
+ useEffect(() => {
66
+ if (working) {
67
+ setSettled(false);
68
+ return;
69
+ }
70
+ const id = setTimeout(() => setSettled(true), CHAIN_SETTLE_MS);
71
+ return () => clearTimeout(id);
72
+ }, [working]);
73
+
74
+ const open = chainOpen({ userOpen, openAtRest, foldOnAnswer, working, settled });
75
+
76
+ const parts = useAuiState((s) => s.message.parts);
77
+ const tr = useTraceT();
78
+ const status = !open && indices ? workStatusText(parts, indices, tr) : undefined;
79
+ const endedTitle = outcome === "failed" ? tr.t("failed") : tr.t("stopped");
80
+ const title = cutShort
81
+ ? endedTitle
82
+ : status
83
+ ? status.label
84
+ : working
85
+ ? tr.t("working")
86
+ : tr.t("worked");
87
+ const markerRunning = !cutShort && (status ? status.running : working);
88
+ const marker: WorkChainMarker = cutShort
89
+ ? outcome === "failed"
90
+ ? "error"
91
+ : "stop"
92
+ : markerRunning
93
+ ? "loading"
94
+ : "idle";
95
+
96
+ return {
97
+ open,
98
+ onOpenChange: setUserOpen,
99
+ title,
100
+ marker,
101
+ outcome: cutShort ? (outcome as "stopped" | "failed") : working ? "running" : "done",
102
+ };
103
+ }
@@ -0,0 +1,48 @@
1
+ /** Pure trace i18n core: tables, plural rules, no React. */
2
+ import { en } from "./locales/en";
3
+ import { fr } from "./locales/fr";
4
+ import type { TracePluralKey, TraceStringKey, TraceStrings } from "./types";
5
+
6
+ /** Registered trace tables. A language without a table falls back to English. */
7
+ export const TRACE_LOCALES: Readonly<Record<string, TraceStrings>> = { en, fr };
8
+
9
+ export const DEFAULT_TRACE_LOCALE = "en";
10
+
11
+ function primary(locale: string | null | undefined): string {
12
+ return (locale ?? "").split(/[-_]/)[0]?.toLowerCase() ?? "";
13
+ }
14
+
15
+ export function resolveTraceLocale(locale: string | null | undefined): string {
16
+ const code = primary(locale);
17
+ return TRACE_LOCALES[code] ? code : DEFAULT_TRACE_LOCALE;
18
+ }
19
+
20
+ export type TraceT = {
21
+ locale: string;
22
+ t: (key: TraceStringKey, vars?: Record<string, string>) => string;
23
+ plural: (key: TracePluralKey, count: number) => string;
24
+ };
25
+
26
+ function fill(text: string, vars?: Record<string, string>): string {
27
+ if (!vars) return text;
28
+ return text.replace(/\{(\w+)\}/g, (m, k: string) => vars[k] ?? m);
29
+ }
30
+
31
+ export function createTraceT(locale: string | null | undefined): TraceT {
32
+ const code = resolveTraceLocale(locale);
33
+ const table = TRACE_LOCALES[code] ?? en;
34
+ const rules = new Intl.PluralRules(code);
35
+ const num = new Intl.NumberFormat(code);
36
+ return {
37
+ locale: code,
38
+ t: (key, vars) => fill(table[key] ?? en[key], vars),
39
+ plural: (key, count) => {
40
+ const msg = table[key] ?? en[key];
41
+ const text = msg[rules.select(count)] ?? msg.other;
42
+ return fill(text, { count: num.format(count) });
43
+ },
44
+ };
45
+ }
46
+
47
+ /** Default English helper for pure functions called without a hook. */
48
+ export const EN_TRACE_T: TraceT = createTraceT(DEFAULT_TRACE_LOCALE);
@@ -0,0 +1,23 @@
1
+ "use client";
2
+
3
+ import { createContext, useContext, useMemo, type ReactNode } from "react";
4
+ import { useEmbedChatPrefsOptional } from "../stock/embed-chat-prefs";
5
+ import { DEFAULT_TRACE_LOCALE, createTraceT, type TraceT } from "./core";
6
+
7
+ export * from "./core";
8
+ export type { TraceStrings, PluralMessage } from "./types";
9
+
10
+ const TraceLocaleContext = createContext<string | null>(null);
11
+
12
+ /** Pins the trace language below it (tests, hosts without chat prefs). */
13
+ export function TraceLocaleProvider({ locale, children }: { locale: string; children: ReactNode }) {
14
+ return <TraceLocaleContext.Provider value={locale}>{children}</TraceLocaleContext.Provider>;
15
+ }
16
+
17
+ /** Trace strings in the session language: the provider, else the chat prefs `/language`, else English. */
18
+ export function useTraceT(): TraceT {
19
+ const pinned = useContext(TraceLocaleContext);
20
+ const prefs = useEmbedChatPrefsOptional();
21
+ const locale = pinned ?? prefs?.prefs.language ?? DEFAULT_TRACE_LOCALE;
22
+ return useMemo(() => createTraceT(locale), [locale]);
23
+ }
@@ -0,0 +1,24 @@
1
+ import type { TraceStrings } from "../types";
2
+
3
+ export const en: TraceStrings = {
4
+ reasoning: "Reasoning",
5
+ thinking: "Thinking",
6
+ thought: "Thought",
7
+ working: "Working",
8
+ worked: "Worked",
9
+ workingOn: "Working — {tool}",
10
+ toolFallbackName: "tool",
11
+ needsInput: "Needs your input",
12
+ stopped: "Stopped",
13
+ failed: "Failed",
14
+ usedTools: { one: "Used {count} tool", other: "Used {count} tools" },
15
+ thoughtAndUsedTools: { one: "Thought and used {count} tool", other: "Thought and used {count} tools" },
16
+ toolCalls: { one: "{count} tool call", other: "{count} tool calls" },
17
+ usedTool: "Used tool",
18
+ cancelledTool: "Cancelled tool",
19
+ failedTool: "Failed tool",
20
+ runningTool: "Running tool",
21
+ waitingOnTool: "Waiting on tool",
22
+ errorPrefix: "Error:",
23
+ cancelledPrefix: "Cancelled:",
24
+ };
@@ -0,0 +1,28 @@
1
+ import type { TraceStrings } from "../types";
2
+
3
+ export const fr: TraceStrings = {
4
+ reasoning: "Raisonnement",
5
+ thinking: "Réflexion en cours",
6
+ thought: "Réflexion terminée",
7
+ working: "En cours",
8
+ worked: "Terminé",
9
+ workingOn: "En cours — {tool}",
10
+ toolFallbackName: "outil",
11
+ needsInput: "Votre réponse est requise",
12
+ stopped: "Arrêté",
13
+ failed: "Échec",
14
+ usedTools: { one: "{count} outil utilisé", many: "{count} d’outils utilisés", other: "{count} outils utilisés" },
15
+ thoughtAndUsedTools: {
16
+ one: "Réflexion et {count} outil utilisé",
17
+ many: "Réflexion et {count} d’outils utilisés",
18
+ other: "Réflexion et {count} outils utilisés",
19
+ },
20
+ toolCalls: { one: "{count} appel d’outil", many: "{count} d’appels d’outils", other: "{count} appels d’outils" },
21
+ usedTool: "Outil utilisé",
22
+ cancelledTool: "Outil annulé",
23
+ failedTool: "Échec de l’outil",
24
+ runningTool: "Outil en cours",
25
+ waitingOnTool: "En attente de l’outil",
26
+ errorPrefix: "Erreur :",
27
+ cancelledPrefix: "Annulé :",
28
+ };
@@ -0,0 +1,35 @@
1
+ /** One plural message: `{count}` is replaced by the formatted number. */
2
+ export type PluralMessage = Partial<Record<Intl.LDMLPluralRule, string>> & { other: string };
3
+
4
+ /**
5
+ * Every static string the chat trace (reasoning, tool calls, the grouped
6
+ * summary line, status tags) shows. One table per language under `locales/`;
7
+ * adding a language means adding one table and registering it in `index.tsx`.
8
+ * Tool names and model text are not here: they stay as they come.
9
+ */
10
+ export type TraceStrings = {
11
+ reasoning: string;
12
+ thinking: string;
13
+ thought: string;
14
+ working: string;
15
+ worked: string;
16
+ /** `{tool}` is the running tool's name. */
17
+ workingOn: string;
18
+ toolFallbackName: string;
19
+ needsInput: string;
20
+ stopped: string;
21
+ failed: string;
22
+ usedTools: PluralMessage;
23
+ thoughtAndUsedTools: PluralMessage;
24
+ toolCalls: PluralMessage;
25
+ usedTool: string;
26
+ cancelledTool: string;
27
+ failedTool: string;
28
+ runningTool: string;
29
+ waitingOnTool: string;
30
+ errorPrefix: string;
31
+ cancelledPrefix: string;
32
+ };
33
+
34
+ export type TraceStringKey = { [K in keyof TraceStrings]: TraceStrings[K] extends string ? K : never }[keyof TraceStrings];
35
+ export type TracePluralKey = { [K in keyof TraceStrings]: TraceStrings[K] extends PluralMessage ? K : never }[keyof TraceStrings];