@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,393 @@
1
+ "use client";
2
+
3
+ import { useCallback, useEffect, useMemo, useRef } from "react";
4
+ import {
5
+ unstable_useMentionAdapter,
6
+ unstable_useSlashCommandAdapter,
7
+ useAui,
8
+ useAuiState,
9
+ } from "@assistant-ui/react";
10
+ import {
11
+ copyMarkdownWithFallback,
12
+ serializeAssistantMarkdown,
13
+ serializeThreadMarkdown,
14
+ transcriptTurns,
15
+ type ChatExportFormat,
16
+ } from "../transcript";
17
+ import type {
18
+ ThreadMentionTrigger,
19
+ ThreadSlashTrigger,
20
+ } from "../gallery-thread/thread.aui";
21
+ import { useStockSendGate } from "./stock-send-gate";
22
+ import {
23
+ useEmbedChatPrefsOptional,
24
+ type EmbedChatPrefsApi,
25
+ } from "./embed-chat-prefs";
26
+ import { exportConversation } from "../../../replay/chat-export-run";
27
+ import { applyExportSlash } from "../../../replay/export-format";
28
+ import { useChatExportStrings } from "./message-export-menu";
29
+
30
+ /**
31
+ * Product slash-command wiring injected by the host (WS4). Structural mirror
32
+ * of the app's product-slash-commands + pending-headers signatures, so the
33
+ * real app functions assign directly. The skin never imports app code.
34
+ *
35
+ * - `SkinSlashCommand` mirrors assistant-ui's `Unstable_SlashCommand`
36
+ * (`{ readonly id; label?; description?; icon?; execute: () => void }`).
37
+ * - `SkinSlashExtraDef` mirrors the app's `SlashDef` minus `category`
38
+ * (optional-only there, so assignment holds both directions; runtime
39
+ * values are real app defs, and the skin never reads the extra fields).
40
+ * - `SkinSlashAction` mirrors the app's `SlashSubmitAction` (`pass`, not `none`).
41
+ */
42
+ export type SkinSlashCommand = {
43
+ readonly id: string;
44
+ readonly label?: string | undefined;
45
+ readonly description?: string | undefined;
46
+ readonly icon?: string | undefined;
47
+ readonly execute: () => void;
48
+ };
49
+
50
+ export type SkinSlashExtraDef = {
51
+ id: string;
52
+ names: readonly string[];
53
+ needsArg: boolean;
54
+ hint: string;
55
+ forceTool?: string;
56
+ choiceOptions?: readonly { value: string; label: string }[];
57
+ kind?: "toggle" | "action" | "tool" | "client";
58
+ };
59
+
60
+ export type SkinSlashAction =
61
+ | { kind: "pass" }
62
+ | { kind: "block" }
63
+ | { kind: "force"; forceTool: string; text: string }
64
+ | { kind: "force-web"; text: string }
65
+ | { kind: "pane"; command: SkinSlashExtraDef; arg: string }
66
+ | { kind: "run"; command: SkinSlashExtraDef; arg: string };
67
+
68
+ export type SkinPaletteKind = "closed" | "commands" | "pane";
69
+
70
+ export type SkinPaletteFrame = {
71
+ kind: SkinPaletteKind;
72
+ filter?: string;
73
+ menu?: string;
74
+ };
75
+
76
+ export type SkinPaletteApply = {
77
+ kind: SkinPaletteKind;
78
+ menu: "close" | "keep" | string;
79
+ filter: string;
80
+ };
81
+
82
+ /**
83
+ * Structural mirror of the app's `SlashAdapterLike`
84
+ * (`apps/digichat/src/lib/product-slash-commands.ts`). Identical shape keeps
85
+ * the app's generic `prefixSlashAdapter` assignable to the prop below (WS4):
86
+ * a constrained generic is only assignable to the same constraint.
87
+ */
88
+ export type SkinSlashAdapterLike = {
89
+ search?: (query: string) => readonly { id: string; label?: string }[];
90
+ categories?: () => readonly { id: string; label: string }[];
91
+ categoryItems?: (categoryId: string) => readonly unknown[];
92
+ };
93
+
94
+ export type DigichatSkinSlash = {
95
+ buildCommands: (prefs: EmbedChatPrefsApi) => SkinSlashCommand[];
96
+ extraDefs: (prefs: EmbedChatPrefsApi) => SkinSlashExtraDef[];
97
+ prefixAdapter: <T extends SkinSlashAdapterLike>(inner: T) => T;
98
+ shouldDraft: (id: string, extra: readonly SkinSlashExtraDef[]) => boolean;
99
+ submitAction: (
100
+ text: string,
101
+ extra?: readonly SkinSlashExtraDef[],
102
+ ) => SkinSlashAction;
103
+ executeDef: (
104
+ def: SkinSlashExtraDef,
105
+ arg: string,
106
+ prefs: EmbedChatPrefsApi,
107
+ ) => void;
108
+ executeFromComposer: (
109
+ id: "lang" | "effort" | "byok" | "mcp" | "tools",
110
+ composerText: string,
111
+ prefs: EmbedChatPrefsApi,
112
+ extra?: readonly SkinSlashExtraDef[],
113
+ ) => void;
114
+ /** Composer text → the one open surface. */
115
+ frame: (text: string) => SkinPaletteFrame;
116
+ /** Previous surface plus the next frame. A button-opened menu can stay. */
117
+ applyFrame: (prev: SkinPaletteKind, frame: SkinPaletteFrame) => SkinPaletteApply;
118
+ /** Draft written when a pane command is chosen (`/language `), or null. */
119
+ paneDraft: (id: string) => string | null;
120
+ armForceTool: (
121
+ sessionKey: string,
122
+ forceTool: string,
123
+ onHold: () => void,
124
+ ) => void;
125
+ setForceTool: (sessionKey: string, forceTool?: string) => void;
126
+ setWebSearchForce: (sessionKey: string, value: boolean) => void;
127
+ };
128
+
129
+ /** The product `/` palette, independent of the skin that renders it. */
130
+ export type SkinSlashPalette = {
131
+ /** True when the host passed slash wiring and mounted the prefs host. */
132
+ enabled: boolean;
133
+ /** `/` trigger for a composer popover; undefined when disabled. */
134
+ slash: ThreadSlashTrigger | undefined;
135
+ /** `@` tool trigger; undefined when disabled or the catalog is empty. */
136
+ mention: ThreadMentionTrigger | undefined;
137
+ /**
138
+ * Runs the slash submit action for the composer text. Returns true when the
139
+ * palette consumed the submit (block, pane, force, run); the caller must
140
+ * then not send. False means a plain message: the skin sends as usual.
141
+ */
142
+ handleSubmit: (event: { preventDefault(): void }) => boolean;
143
+ };
144
+
145
+ export type SkinSlashPaletteOptions = {
146
+ slash?: DigichatSkinSlash | undefined;
147
+ /** Rebuilds the rows when the private session flips (`/private` value). */
148
+ privateMode?: boolean | undefined;
149
+ };
150
+
151
+ /**
152
+ * Product slash-command palette logic shared by every skin. The digichat skin
153
+ * hands the result to its own composer; every other skin gets it through
154
+ * `SkinPaletteBridge`. Moved verbatim from the digichat skin.
155
+ */
156
+ export function useSkinSlashPalette({
157
+ slash: slashWiring,
158
+ privateMode,
159
+ }: SkinSlashPaletteOptions): SkinSlashPalette {
160
+ const gate = useStockSendGate();
161
+ const prefs = useEmbedChatPrefsOptional();
162
+ const aui = useAui();
163
+ const composerText = useAuiState((s) => s.composer.text);
164
+ const palettePrev = useRef<SkinPaletteKind>("closed");
165
+ const slashPrefs = useMemo(() => {
166
+ if (!prefs) return null;
167
+ return {
168
+ ...prefs,
169
+ newThread: () => {
170
+ prefs.newThread();
171
+ aui.threads.switchToNewThread();
172
+ },
173
+ };
174
+ }, [prefs, aui]);
175
+ const enableSlash = Boolean(slashPrefs) && Boolean(slashWiring);
176
+ useEffect(() => {
177
+ if (!enableSlash || !slashPrefs?.syncPalette || !slashWiring) return;
178
+ const next = slashWiring.applyFrame(palettePrev.current, slashWiring.frame(composerText));
179
+ palettePrev.current = next.kind;
180
+ slashPrefs.syncPalette(next);
181
+ }, [composerText, enableSlash, slashPrefs, slashWiring]);
182
+ useEffect(() => {
183
+ if (!slashPrefs?.bindComposerDraft) return;
184
+ slashPrefs.bindComposerDraft((text) => {
185
+ aui.composer.setText(text);
186
+ });
187
+ }, [slashPrefs, aui]);
188
+ const extra = useMemo(
189
+ () =>
190
+ slashPrefs && slashWiring ? slashWiring.extraDefs(slashPrefs) : [],
191
+ [slashPrefs, slashWiring],
192
+ );
193
+
194
+ const exportStrings = useChatExportStrings();
195
+ const copyExport = useMemo(
196
+ () => ({
197
+ copy: () => {
198
+ const turns = transcriptTurns(aui.thread().getState().messages);
199
+ const last = [...turns].reverse().find((t) => t.role === "assistant");
200
+ if (!last) return;
201
+ void copyMarkdownWithFallback(serializeAssistantMarkdown(last.content, last.sources));
202
+ },
203
+ /** The whole conversation, from the chat menu or a typed `/export md|html`. */
204
+ exportConversation: (format: ChatExportFormat) => {
205
+ if (privateMode) return;
206
+ void exportConversation({
207
+ format,
208
+ privateMode,
209
+ messages: aui.thread().getState().messages,
210
+ strings: exportStrings,
211
+ });
212
+ },
213
+ }),
214
+ [aui, exportStrings, privateMode],
215
+ );
216
+ // The settings menu and the `/export` pane live outside the runtime; they
217
+ // reach the thread through the prefs host.
218
+ useEffect(() => {
219
+ if (!slashPrefs?.bindThreadExport) return;
220
+ slashPrefs.bindThreadExport(copyExport.exportConversation);
221
+ }, [slashPrefs, copyExport]);
222
+
223
+ const commands = useMemo(() => {
224
+ if (!enableSlash || !slashPrefs || !slashWiring) return [];
225
+ return slashWiring.buildCommands(slashPrefs).map((c) => {
226
+ if (c.id === "copy") return { ...c, execute: copyExport.copy };
227
+ if (c.id === "compact") {
228
+ return {
229
+ ...c,
230
+ execute: () => {
231
+ const md = serializeThreadMarkdown(transcriptTurns(aui.thread().getState().messages));
232
+ slashPrefs.reset();
233
+ slashPrefs.newThread();
234
+ if (!md.trim()) return;
235
+ queueMicrotask(() => {
236
+ aui.composer.setText(
237
+ `Summarize this conversation so we can continue with a smaller context.\n\n${md}`,
238
+ );
239
+ aui.composer.send();
240
+ });
241
+ },
242
+ };
243
+ }
244
+ const draft = slashWiring.paneDraft(c.id);
245
+ if (draft) {
246
+ return {
247
+ ...c,
248
+ execute: () => {
249
+ queueMicrotask(() => aui.composer.setText(draft));
250
+ },
251
+ };
252
+ }
253
+ if (slashWiring.shouldDraft(c.id, extra)) {
254
+ const inserted = `${c.label?.startsWith("/") ? c.label : `/${c.id}`} `;
255
+ return {
256
+ ...c,
257
+ execute: () => {
258
+ queueMicrotask(() => aui.composer.setText(inserted));
259
+ },
260
+ };
261
+ }
262
+ return c;
263
+ });
264
+ // `privateMode` is read inside `buildCommands` (the `/private` row's
265
+ // value) from a store, not from an argument: listing it here rebuilds the
266
+ // rows when it flips, so the palette shows the current value.
267
+ // eslint-disable-next-line react-hooks/exhaustive-deps
268
+ }, [enableSlash, slashPrefs, slashWiring, copyExport, aui, extra, privateMode]);
269
+
270
+ const slash = unstable_useSlashCommandAdapter({
271
+ commands,
272
+ removeOnExecute: true,
273
+ });
274
+ const slashTrigger = useMemo((): ThreadSlashTrigger => {
275
+ return {
276
+ adapter: slashWiring?.prefixAdapter(slash.adapter) ?? slash.adapter,
277
+ action: slash.action,
278
+ matcher: (text, _triggerChar, cursorPosition) => {
279
+ if (!slashWiring || cursorPosition <= 0) return null;
280
+ const frame = slashWiring.frame(text);
281
+ if (frame.kind !== "commands") return null;
282
+ return { query: frame.filter ?? "", offset: 0, endOffset: cursorPosition };
283
+ },
284
+ };
285
+ }, [slash, slashWiring]);
286
+
287
+ const mentionItems = useMemo(
288
+ () =>
289
+ (slashPrefs?.catalogTools ?? [])
290
+ .filter((t) => t.id !== "web_search" || Boolean(slashPrefs?.tenantAllowsWeb))
291
+ .map((t) => ({
292
+ id: t.id,
293
+ type: "tool",
294
+ label: t.label?.trim() || t.id,
295
+ description: `Use ${t.label?.trim() || t.id}`,
296
+ })),
297
+ [slashPrefs],
298
+ );
299
+ const mention = unstable_useMentionAdapter({
300
+ items: mentionItems,
301
+ });
302
+ const mentionTrigger = useMemo(
303
+ () =>
304
+ mentionItems.length
305
+ ? {
306
+ adapter: mention.adapter,
307
+ directive: mention.directive,
308
+ }
309
+ : undefined,
310
+ [mention, mentionItems.length],
311
+ );
312
+
313
+ const handleSubmit = useCallback(
314
+ (event: { preventDefault(): void }): boolean => {
315
+ if (slashPrefs && slashWiring) {
316
+ const text = aui.composer.getState().text;
317
+ const action = slashWiring.submitAction(text, extra);
318
+ if (action.kind === "block" || action.kind === "pane") {
319
+ event.preventDefault();
320
+ return true;
321
+ }
322
+ if (action.kind === "force") {
323
+ event.preventDefault();
324
+ if (gate?.shouldHold(action.text)) {
325
+ aui.composer.setText("");
326
+ void aui.composer.clearAttachments();
327
+ slashWiring.armForceTool(slashPrefs.sessionKey, action.forceTool, () => {
328
+ gate.onHold(action.text);
329
+ });
330
+ return true;
331
+ }
332
+ slashWiring.setForceTool(slashPrefs.sessionKey, action.forceTool);
333
+ aui.composer.setText(action.text);
334
+ gate?.onAllowSend?.();
335
+ aui.composer.send();
336
+ return true;
337
+ }
338
+ if (action.kind === "force-web") {
339
+ event.preventDefault();
340
+ // Tenant-gated arm (#3871): a deny tenant typing
341
+ // /websearch must not set the pending flag — same tenantAllowsWeb
342
+ // signal as the mention filter above. The BFF deny stays as backstop.
343
+ if (slashPrefs.tenantAllowsWeb) {
344
+ slashWiring.setWebSearchForce(slashPrefs.sessionKey, true);
345
+ }
346
+ if (gate?.shouldHold(action.text)) {
347
+ aui.composer.setText("");
348
+ void aui.composer.clearAttachments();
349
+ gate.onHold(action.text);
350
+ return true;
351
+ }
352
+ aui.composer.setText(action.text);
353
+ gate?.onAllowSend?.();
354
+ aui.composer.send();
355
+ return true;
356
+ }
357
+ if (action.kind === "run") {
358
+ event.preventDefault();
359
+ if (action.command.id === "copy") copyExport.copy();
360
+ else if (action.command.id === "export") {
361
+ applyExportSlash(action.arg, document, {
362
+ html: () => copyExport.exportConversation("html"),
363
+ markdown: () => copyExport.exportConversation("md"),
364
+ });
365
+ }
366
+ else if (action.command.id === "compact") {
367
+ // Palette compact serializes the thread and queues a summary.
368
+ // executeDef only resets prefs and opens an empty thread.
369
+ const compact = commands.find((command) => command.id === "compact");
370
+ if (compact) compact.execute();
371
+ else slashWiring.executeDef(action.command, action.arg, slashPrefs);
372
+ } else slashWiring.executeDef(action.command, action.arg, slashPrefs);
373
+ aui.composer.setText("");
374
+ return true;
375
+ }
376
+ }
377
+ return false;
378
+ },
379
+ [slashPrefs, slashWiring, aui, gate, copyExport, extra, commands],
380
+ );
381
+
382
+ return useMemo(
383
+ () => ({
384
+ enabled: enableSlash,
385
+ slash: enableSlash ? slashTrigger : undefined,
386
+ mention: enableSlash ? mentionTrigger : undefined,
387
+ handleSubmit,
388
+ }),
389
+ [enableSlash, slashTrigger, mentionTrigger, handleSubmit],
390
+ );
391
+ }
392
+
393
+
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Shared skin/chrome value types for the package thread + skins.
3
+ *
4
+ * These are structural twins of the app's deploy-config literals
5
+ * (`ChromeModeSchema`, `PageContextModeSchema`, `UserAlignSchema` in
6
+ * `apps/digichat/src/lib/deploy-config/schema.ts`, `ChainDisclosureMode` in
7
+ * `apps/digichat/src/lib/view-modes.ts`). The app schema stays the single
8
+ * source of truth for config validation; this module keeps the presentation
9
+ * layer free of app imports (WS4).
10
+ */
11
+
12
+ export type ChromeMode = "app" | "embed" | "modal" | "sidebar";
13
+
14
+ export type PageContextMode = "off" | "silent" | "visible";
15
+
16
+ export type UserAlign = "right" | "left";
17
+
18
+ export type ChainDisclosureMode =
19
+ | "off"
20
+ | "collapsed"
21
+ | "balanced"
22
+ | "expanded";
23
+
24
+ /**
25
+ * How much of the agent's work (reasoning + tool calls) a client wants its
26
+ * users to see. Structural twin of the app's `workVisibility` literal in
27
+ * `apps/digichat/src/lib/deploy-config/schema.ts`.
28
+ *
29
+ * - `quiet` — the chain is there, folded, and its header reads as a status
30
+ * line ("Working — digisearch", "Used 3 tools"); the rows stay closed.
31
+ * - `balanced` — the chain is expanded while it runs, so the arguments and
32
+ * the reasoning are visible, and collapses when it finishes.
33
+ * - `verbose` — the chain stays expanded; everything is readable.
34
+ *
35
+ * There is no `hidden` level any more: a client that wants the least reads
36
+ * the live status line and nothing else, which is `quiet`. Old values fold
37
+ * forward — see `LEGACY_VIEW_MODE_ALIASES` and `workVisibilityForView`.
38
+ */
39
+ export type WorkVisibility = "quiet" | "balanced" | "verbose";
40
+
41
+ /** What the disclosure policy resolves to for the thread components. */
42
+ export type WorkDisclosure = {
43
+ /**
44
+ * A single summary line replaces the chain. The hidden level is gone, so
45
+ * this is always false now; it stays on the type while the thread renderer
46
+ * still holds the branch that reads it.
47
+ *
48
+ * @deprecated the chain folds to its titles instead (`quiet`).
49
+ */
50
+ summaryOnly: boolean;
51
+ /** The rows expand while their work streams. */
52
+ openWhileRunning: boolean;
53
+ /** The rows stay open once the work has finished. */
54
+ openAtRest: boolean;
55
+ /** Per-tool detail (arguments, results) is rendered. */
56
+ showDetails: boolean;
57
+ /**
58
+ * The chain folds as soon as the answer starts streaming, rather than
59
+ * waiting for the turn to end. The quiet level: the titles are there while
60
+ * the agent works, then they get out of the way of the answer.
61
+ */
62
+ foldOnAnswer: boolean;
63
+ };
64
+
65
+ /**
66
+ * The client-facing view level becomes the work visibility the thread uses.
67
+ * The retired `hidden` level means "the titles only, folded" now, so a host
68
+ * bundle still carrying it folds forward to `quiet`.
69
+ */
70
+ export function workVisibilityForView(
71
+ view: ViewMode | undefined,
72
+ ): WorkVisibility {
73
+ switch (view) {
74
+ case "quiet":
75
+ return "quiet";
76
+ case "verbose":
77
+ return "verbose";
78
+ // Includes `balanced` and a host bundle that has not been rebuilt yet.
79
+ default:
80
+ return (view as string | undefined) === "hidden" ? "quiet" : "balanced";
81
+ }
82
+ }
83
+
84
+ /** The one place the visibility level becomes behaviour. */
85
+ export function resolveWorkDisclosure(
86
+ visibility: WorkVisibility | undefined,
87
+ ): WorkDisclosure {
88
+ switch (visibility) {
89
+ // The titles only: the chain and its rows are there, folded. The folded
90
+ // header is the status line, so this is also the level that used to be
91
+ // called `hidden`.
92
+ case "quiet":
93
+ return {
94
+ summaryOnly: false,
95
+ openWhileRunning: false,
96
+ openAtRest: false,
97
+ showDetails: false,
98
+ foldOnAnswer: true,
99
+ };
100
+ // Open while the work streams, folded when the turn ends.
101
+ case "balanced":
102
+ return {
103
+ summaryOnly: false,
104
+ openWhileRunning: true,
105
+ openAtRest: false,
106
+ showDetails: true,
107
+ foldOnAnswer: false,
108
+ };
109
+ // Nothing ever folds: everything stays open and can be closed by hand.
110
+ case "verbose":
111
+ return {
112
+ summaryOnly: false,
113
+ openWhileRunning: true,
114
+ openAtRest: true,
115
+ showDetails: true,
116
+ foldOnAnswer: false,
117
+ };
118
+ default:
119
+ return {
120
+ summaryOnly: false,
121
+ openWhileRunning: true,
122
+ openAtRest: false,
123
+ showDetails: true,
124
+ foldOnAnswer: false,
125
+ };
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Prefs value literals (WS4). Structural twins of `ViewMode` /
131
+ * `ThinkingMode` (`VIEW_MODES`, `THINKING_MODES` in
132
+ * `apps/digichat/src/lib/view-modes.ts`, defaults `"balanced"` / `"auto"`).
133
+ */
134
+ export type ViewMode = "quiet" | "balanced" | "verbose";
135
+
136
+ /**
137
+ * Retired view ids still found in saved prefs. `hidden` was the level that
138
+ * folded the trace to a single line — the chain folds to its titles and shows
139
+ * the same status line now, so it means `quiet`. `compact` was the
140
+ * closed-summary level (also now `quiet`); `detailed` was the fully-open one
141
+ * (now `verbose`). The app's `view-modes.ts` holds the twin of this map.
142
+ */
143
+ export const LEGACY_VIEW_MODE_ALIASES = {
144
+ hidden: "quiet",
145
+ compact: "quiet",
146
+ detailed: "verbose",
147
+ } as const;
148
+
149
+ /** A current view id, a retired one folded forward, or the default. */
150
+ export function normalizeViewPref(value: unknown): ViewMode {
151
+ if (value === "quiet" || value === "balanced" || value === "verbose") {
152
+ return value;
153
+ }
154
+ if (value === "hidden" || value === "compact") return "quiet";
155
+ if (value === "detailed") return "verbose";
156
+ return "balanced";
157
+ }
158
+
159
+ export type ThinkingMode = "auto" | "collapsed" | "open";
160
+
161
+ /**
162
+ * Session MCP server config (WS4). Structural twin of `SessionMcpConfig` in
163
+ * `apps/digichat/src/components/stock/embed-mcp-flow.ts` (`auth` /
164
+ * `source` literals mirror `McpAuthKind` / `McpSource`). The app type stays
165
+ * the source of truth for BFF validation; identical shape keeps host values
166
+ * assignable across the boundary.
167
+ */
168
+ export type SkinMcpServerConfig = {
169
+ id: string;
170
+ label: string;
171
+ url: string;
172
+ auth: "none" | "bearer" | "oauth";
173
+ token: string;
174
+ extra: Record<string, string>;
175
+ source: "operator" | "session";
176
+ };
177
+
178
+ /**
179
+ * Composer menu pane ids (WS4). Structural twin of `ComposerMenuKind` in
180
+ * `apps/digichat/src/components/stock/embed-composer-menu.tsx`.
181
+ */
182
+ export type StockComposerMenuKind =
183
+ | "settings"
184
+ | "models"
185
+ | "mcp"
186
+ | "tools"
187
+ | "language"
188
+ | "effort"
189
+ | "search-engine"
190
+ | "view"
191
+ | "density"
192
+ | "theme"
193
+ | "thinking"
194
+ | "provider"
195
+ | "help"
196
+ | "export";
197
+
198
+ const STOCK_COMPOSER_MENU_KINDS: readonly StockComposerMenuKind[] = [
199
+ "settings",
200
+ "models",
201
+ "mcp",
202
+ "tools",
203
+ "language",
204
+ "effort",
205
+ "search-engine",
206
+ "view",
207
+ "density",
208
+ "theme",
209
+ "thinking",
210
+ "provider",
211
+ "help",
212
+ "export",
213
+ ];
214
+
215
+ export function isStockComposerMenuKind(value: string): value is StockComposerMenuKind {
216
+ return (STOCK_COMPOSER_MENU_KINDS as readonly string[]).includes(value);
217
+ }