@data-club/ai-hub 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. package/dist/auth/passwordPolicy.d.ts +55 -0
  2. package/dist/auth/passwordPolicy.d.ts.map +1 -0
  3. package/dist/auth/passwordPolicy.js +63 -0
  4. package/dist/auth/passwordPolicy.js.map +1 -0
  5. package/dist/auth/texts.d.ts +815 -0
  6. package/dist/auth/texts.d.ts.map +1 -0
  7. package/dist/auth/texts.js +429 -0
  8. package/dist/auth/texts.js.map +1 -0
  9. package/dist/client/AIHubClient.d.ts +1058 -0
  10. package/dist/client/AIHubClient.d.ts.map +1 -0
  11. package/dist/client/AIHubClient.js +950 -0
  12. package/dist/client/AIHubClient.js.map +1 -0
  13. package/dist/client/index.d.ts +11 -0
  14. package/dist/client/index.d.ts.map +1 -0
  15. package/dist/client/index.js +9 -0
  16. package/dist/client/index.js.map +1 -0
  17. package/dist/client/sseParser.d.ts +41 -0
  18. package/dist/client/sseParser.d.ts.map +1 -0
  19. package/dist/client/sseParser.js +153 -0
  20. package/dist/client/sseParser.js.map +1 -0
  21. package/dist/client/tokenStorage.d.ts +56 -0
  22. package/dist/client/tokenStorage.d.ts.map +1 -0
  23. package/dist/client/tokenStorage.js +116 -0
  24. package/dist/client/tokenStorage.js.map +1 -0
  25. package/dist/components/AgentsPicker/index.d.ts +70 -0
  26. package/dist/components/AgentsPicker/index.d.ts.map +1 -0
  27. package/dist/components/AgentsPicker/index.js +63 -0
  28. package/dist/components/AgentsPicker/index.js.map +1 -0
  29. package/dist/components/AuthGate/index.d.ts +79 -0
  30. package/dist/components/AuthGate/index.d.ts.map +1 -0
  31. package/dist/components/AuthGate/index.js +61 -0
  32. package/dist/components/AuthGate/index.js.map +1 -0
  33. package/dist/components/CacheBadge/index.d.ts +88 -0
  34. package/dist/components/CacheBadge/index.d.ts.map +1 -0
  35. package/dist/components/CacheBadge/index.js +127 -0
  36. package/dist/components/CacheBadge/index.js.map +1 -0
  37. package/dist/components/ChangePassword/index.d.ts +109 -0
  38. package/dist/components/ChangePassword/index.d.ts.map +1 -0
  39. package/dist/components/ChangePassword/index.js +142 -0
  40. package/dist/components/ChangePassword/index.js.map +1 -0
  41. package/dist/components/ChatShell/ShellHeader.d.ts +44 -0
  42. package/dist/components/ChatShell/ShellHeader.d.ts.map +1 -0
  43. package/dist/components/ChatShell/ShellHeader.js +14 -0
  44. package/dist/components/ChatShell/ShellHeader.js.map +1 -0
  45. package/dist/components/ChatShell/UserMenu.d.ts +48 -0
  46. package/dist/components/ChatShell/UserMenu.d.ts.map +1 -0
  47. package/dist/components/ChatShell/UserMenu.js +86 -0
  48. package/dist/components/ChatShell/UserMenu.js.map +1 -0
  49. package/dist/components/ChatShell/index.d.ts +98 -0
  50. package/dist/components/ChatShell/index.d.ts.map +1 -0
  51. package/dist/components/ChatShell/index.js +124 -0
  52. package/dist/components/ChatShell/index.js.map +1 -0
  53. package/dist/components/DataClubAIHub/index.d.ts +132 -0
  54. package/dist/components/DataClubAIHub/index.d.ts.map +1 -0
  55. package/dist/components/DataClubAIHub/index.js +124 -0
  56. package/dist/components/DataClubAIHub/index.js.map +1 -0
  57. package/dist/components/DataClubAIHubAdmin/AgentEditorModal.d.ts +89 -0
  58. package/dist/components/DataClubAIHubAdmin/AgentEditorModal.d.ts.map +1 -0
  59. package/dist/components/DataClubAIHubAdmin/AgentEditorModal.js +199 -0
  60. package/dist/components/DataClubAIHubAdmin/AgentEditorModal.js.map +1 -0
  61. package/dist/components/DataClubAIHubAdmin/AgentsPage.d.ts +33 -0
  62. package/dist/components/DataClubAIHubAdmin/AgentsPage.d.ts.map +1 -0
  63. package/dist/components/DataClubAIHubAdmin/AgentsPage.js +137 -0
  64. package/dist/components/DataClubAIHubAdmin/AgentsPage.js.map +1 -0
  65. package/dist/components/DataClubAIHubAdmin/CreateUserModal.d.ts +50 -0
  66. package/dist/components/DataClubAIHubAdmin/CreateUserModal.d.ts.map +1 -0
  67. package/dist/components/DataClubAIHubAdmin/CreateUserModal.js +93 -0
  68. package/dist/components/DataClubAIHubAdmin/CreateUserModal.js.map +1 -0
  69. package/dist/components/DataClubAIHubAdmin/PasswordRevealModal.d.ts +49 -0
  70. package/dist/components/DataClubAIHubAdmin/PasswordRevealModal.d.ts.map +1 -0
  71. package/dist/components/DataClubAIHubAdmin/PasswordRevealModal.js +94 -0
  72. package/dist/components/DataClubAIHubAdmin/PasswordRevealModal.js.map +1 -0
  73. package/dist/components/DataClubAIHubAdmin/ResetPasswordModal.d.ts +37 -0
  74. package/dist/components/DataClubAIHubAdmin/ResetPasswordModal.d.ts.map +1 -0
  75. package/dist/components/DataClubAIHubAdmin/ResetPasswordModal.js +44 -0
  76. package/dist/components/DataClubAIHubAdmin/ResetPasswordModal.js.map +1 -0
  77. package/dist/components/DataClubAIHubAdmin/RotatingMessageEditorModal.d.ts +56 -0
  78. package/dist/components/DataClubAIHubAdmin/RotatingMessageEditorModal.d.ts.map +1 -0
  79. package/dist/components/DataClubAIHubAdmin/RotatingMessageEditorModal.js +158 -0
  80. package/dist/components/DataClubAIHubAdmin/RotatingMessageEditorModal.js.map +1 -0
  81. package/dist/components/DataClubAIHubAdmin/RotatingMessagesPage.d.ts +29 -0
  82. package/dist/components/DataClubAIHubAdmin/RotatingMessagesPage.d.ts.map +1 -0
  83. package/dist/components/DataClubAIHubAdmin/RotatingMessagesPage.js +183 -0
  84. package/dist/components/DataClubAIHubAdmin/RotatingMessagesPage.js.map +1 -0
  85. package/dist/components/DataClubAIHubAdmin/SessionsOverviewPage.d.ts +38 -0
  86. package/dist/components/DataClubAIHubAdmin/SessionsOverviewPage.d.ts.map +1 -0
  87. package/dist/components/DataClubAIHubAdmin/SessionsOverviewPage.js +294 -0
  88. package/dist/components/DataClubAIHubAdmin/SessionsOverviewPage.js.map +1 -0
  89. package/dist/components/DataClubAIHubAdmin/SettingsPage.d.ts +36 -0
  90. package/dist/components/DataClubAIHubAdmin/SettingsPage.d.ts.map +1 -0
  91. package/dist/components/DataClubAIHubAdmin/SettingsPage.js +373 -0
  92. package/dist/components/DataClubAIHubAdmin/SettingsPage.js.map +1 -0
  93. package/dist/components/DataClubAIHubAdmin/UsersPage.d.ts +47 -0
  94. package/dist/components/DataClubAIHubAdmin/UsersPage.d.ts.map +1 -0
  95. package/dist/components/DataClubAIHubAdmin/UsersPage.js +233 -0
  96. package/dist/components/DataClubAIHubAdmin/UsersPage.js.map +1 -0
  97. package/dist/components/DataClubAIHubAdmin/index.d.ts +87 -0
  98. package/dist/components/DataClubAIHubAdmin/index.d.ts.map +1 -0
  99. package/dist/components/DataClubAIHubAdmin/index.js +137 -0
  100. package/dist/components/DataClubAIHubAdmin/index.js.map +1 -0
  101. package/dist/components/DataClubAIHubLogin/index.d.ts +113 -0
  102. package/dist/components/DataClubAIHubLogin/index.d.ts.map +1 -0
  103. package/dist/components/DataClubAIHubLogin/index.js +123 -0
  104. package/dist/components/DataClubAIHubLogin/index.js.map +1 -0
  105. package/dist/components/EffortControl/index.d.ts +57 -0
  106. package/dist/components/EffortControl/index.d.ts.map +1 -0
  107. package/dist/components/EffortControl/index.js +84 -0
  108. package/dist/components/EffortControl/index.js.map +1 -0
  109. package/dist/components/Layout/index.d.ts +63 -0
  110. package/dist/components/Layout/index.d.ts.map +1 -0
  111. package/dist/components/Layout/index.js +45 -0
  112. package/dist/components/Layout/index.js.map +1 -0
  113. package/dist/components/MainColumn/index.d.ts +69 -0
  114. package/dist/components/MainColumn/index.d.ts.map +1 -0
  115. package/dist/components/MainColumn/index.js +47 -0
  116. package/dist/components/MainColumn/index.js.map +1 -0
  117. package/dist/components/MarkdownRenderer/index.d.ts +66 -0
  118. package/dist/components/MarkdownRenderer/index.d.ts.map +1 -0
  119. package/dist/components/MarkdownRenderer/index.js +153 -0
  120. package/dist/components/MarkdownRenderer/index.js.map +1 -0
  121. package/dist/components/MessageInput/index.d.ts +85 -0
  122. package/dist/components/MessageInput/index.d.ts.map +1 -0
  123. package/dist/components/MessageInput/index.js +139 -0
  124. package/dist/components/MessageInput/index.js.map +1 -0
  125. package/dist/components/MessageList/index.d.ts +156 -0
  126. package/dist/components/MessageList/index.d.ts.map +1 -0
  127. package/dist/components/MessageList/index.js +352 -0
  128. package/dist/components/MessageList/index.js.map +1 -0
  129. package/dist/components/ReasoningSelector/index.d.ts +77 -0
  130. package/dist/components/ReasoningSelector/index.d.ts.map +1 -0
  131. package/dist/components/ReasoningSelector/index.js +156 -0
  132. package/dist/components/ReasoningSelector/index.js.map +1 -0
  133. package/dist/components/ReasoningView/index.d.ts +94 -0
  134. package/dist/components/ReasoningView/index.d.ts.map +1 -0
  135. package/dist/components/ReasoningView/index.js +83 -0
  136. package/dist/components/ReasoningView/index.js.map +1 -0
  137. package/dist/components/ScrollToPresentButton/index.d.ts +54 -0
  138. package/dist/components/ScrollToPresentButton/index.d.ts.map +1 -0
  139. package/dist/components/ScrollToPresentButton/index.js +44 -0
  140. package/dist/components/ScrollToPresentButton/index.js.map +1 -0
  141. package/dist/components/SessionsPanel/SessionTitleModal.d.ts +79 -0
  142. package/dist/components/SessionsPanel/SessionTitleModal.d.ts.map +1 -0
  143. package/dist/components/SessionsPanel/SessionTitleModal.js +102 -0
  144. package/dist/components/SessionsPanel/SessionTitleModal.js.map +1 -0
  145. package/dist/components/SessionsPanel/index.d.ts +100 -0
  146. package/dist/components/SessionsPanel/index.d.ts.map +1 -0
  147. package/dist/components/SessionsPanel/index.js +176 -0
  148. package/dist/components/SessionsPanel/index.js.map +1 -0
  149. package/dist/components/SystemNotice/index.d.ts +66 -0
  150. package/dist/components/SystemNotice/index.d.ts.map +1 -0
  151. package/dist/components/SystemNotice/index.js +81 -0
  152. package/dist/components/SystemNotice/index.js.map +1 -0
  153. package/dist/components/ThemeSwitcher/index.d.ts +66 -0
  154. package/dist/components/ThemeSwitcher/index.d.ts.map +1 -0
  155. package/dist/components/ThemeSwitcher/index.js +73 -0
  156. package/dist/components/ThemeSwitcher/index.js.map +1 -0
  157. package/dist/components/ToolCallView/formatContent.d.ts +36 -0
  158. package/dist/components/ToolCallView/formatContent.d.ts.map +1 -0
  159. package/dist/components/ToolCallView/formatContent.js +53 -0
  160. package/dist/components/ToolCallView/formatContent.js.map +1 -0
  161. package/dist/components/ToolCallView/index.d.ts +120 -0
  162. package/dist/components/ToolCallView/index.d.ts.map +1 -0
  163. package/dist/components/ToolCallView/index.js +104 -0
  164. package/dist/components/ToolCallView/index.js.map +1 -0
  165. package/dist/components/TpmBanner/index.d.ts +53 -0
  166. package/dist/components/TpmBanner/index.d.ts.map +1 -0
  167. package/dist/components/TpmBanner/index.js +116 -0
  168. package/dist/components/TpmBanner/index.js.map +1 -0
  169. package/dist/components/TurnStatusIndicator/index.d.ts +77 -0
  170. package/dist/components/TurnStatusIndicator/index.d.ts.map +1 -0
  171. package/dist/components/TurnStatusIndicator/index.js +122 -0
  172. package/dist/components/TurnStatusIndicator/index.js.map +1 -0
  173. package/dist/components/internal/PasswordInput.d.ts +62 -0
  174. package/dist/components/internal/PasswordInput.d.ts.map +1 -0
  175. package/dist/components/internal/PasswordInput.js +42 -0
  176. package/dist/components/internal/PasswordInput.js.map +1 -0
  177. package/dist/context/AIHubContext.d.ts +220 -0
  178. package/dist/context/AIHubContext.d.ts.map +1 -0
  179. package/dist/context/AIHubContext.js +19 -0
  180. package/dist/context/AIHubContext.js.map +1 -0
  181. package/dist/context/AIHubProvider.d.ts +75 -0
  182. package/dist/context/AIHubProvider.d.ts.map +1 -0
  183. package/dist/context/AIHubProvider.js +954 -0
  184. package/dist/context/AIHubProvider.js.map +1 -0
  185. package/dist/context/index.d.ts +9 -0
  186. package/dist/context/index.d.ts.map +1 -0
  187. package/dist/context/index.js +9 -0
  188. package/dist/context/index.js.map +1 -0
  189. package/dist/context/theme.d.ts +43 -0
  190. package/dist/context/theme.d.ts.map +1 -0
  191. package/dist/context/theme.js +70 -0
  192. package/dist/context/theme.js.map +1 -0
  193. package/dist/context/useAIHub.d.ts +104 -0
  194. package/dist/context/useAIHub.d.ts.map +1 -0
  195. package/dist/context/useAIHub.js +63 -0
  196. package/dist/context/useAIHub.js.map +1 -0
  197. package/dist/context/useAIHubAuth.d.ts +44 -0
  198. package/dist/context/useAIHubAuth.d.ts.map +1 -0
  199. package/dist/context/useAIHubAuth.js +35 -0
  200. package/dist/context/useAIHubAuth.js.map +1 -0
  201. package/dist/index.d.ts +76 -0
  202. package/dist/index.d.ts.map +1 -0
  203. package/dist/index.js +57 -0
  204. package/dist/index.js.map +1 -0
  205. package/dist/primitives/index.d.ts +99 -0
  206. package/dist/primitives/index.d.ts.map +1 -0
  207. package/dist/primitives/index.js +97 -0
  208. package/dist/primitives/index.js.map +1 -0
  209. package/dist/state/affordances.d.ts +182 -0
  210. package/dist/state/affordances.d.ts.map +1 -0
  211. package/dist/state/affordances.js +189 -0
  212. package/dist/state/affordances.js.map +1 -0
  213. package/dist/state/stateReducer.d.ts +72 -0
  214. package/dist/state/stateReducer.d.ts.map +1 -0
  215. package/dist/state/stateReducer.js +122 -0
  216. package/dist/state/stateReducer.js.map +1 -0
  217. package/dist/stories/EffortControl.stories.d.ts +14 -0
  218. package/dist/stories/EffortControl.stories.d.ts.map +1 -0
  219. package/dist/stories/EffortControl.stories.js +43 -0
  220. package/dist/stories/EffortControl.stories.js.map +1 -0
  221. package/dist/stories/MarkdownRenderer.stories.d.ts +25 -0
  222. package/dist/stories/MarkdownRenderer.stories.d.ts.map +1 -0
  223. package/dist/stories/MarkdownRenderer.stories.js +178 -0
  224. package/dist/stories/MarkdownRenderer.stories.js.map +1 -0
  225. package/dist/stories/MessageBubble.stories.d.ts +21 -0
  226. package/dist/stories/MessageBubble.stories.d.ts.map +1 -0
  227. package/dist/stories/MessageBubble.stories.js +59 -0
  228. package/dist/stories/MessageBubble.stories.js.map +1 -0
  229. package/dist/stories/ReasoningView.stories.d.ts +18 -0
  230. package/dist/stories/ReasoningView.stories.d.ts.map +1 -0
  231. package/dist/stories/ReasoningView.stories.js +62 -0
  232. package/dist/stories/ReasoningView.stories.js.map +1 -0
  233. package/dist/stories/ScrollToPresentButton.stories.d.ts +18 -0
  234. package/dist/stories/ScrollToPresentButton.stories.d.ts.map +1 -0
  235. package/dist/stories/ScrollToPresentButton.stories.js +34 -0
  236. package/dist/stories/ScrollToPresentButton.stories.js.map +1 -0
  237. package/dist/stories/SystemNotice.stories.d.ts +17 -0
  238. package/dist/stories/SystemNotice.stories.d.ts.map +1 -0
  239. package/dist/stories/SystemNotice.stories.js +42 -0
  240. package/dist/stories/SystemNotice.stories.js.map +1 -0
  241. package/dist/stories/ThemeSwitcher.stories.d.ts +15 -0
  242. package/dist/stories/ThemeSwitcher.stories.d.ts.map +1 -0
  243. package/dist/stories/ThemeSwitcher.stories.js +35 -0
  244. package/dist/stories/ThemeSwitcher.stories.js.map +1 -0
  245. package/dist/stories/ToolCallView.stories.d.ts +20 -0
  246. package/dist/stories/ToolCallView.stories.d.ts.map +1 -0
  247. package/dist/stories/ToolCallView.stories.js +65 -0
  248. package/dist/stories/ToolCallView.stories.js.map +1 -0
  249. package/dist/stories/TpmBanner.stories.d.ts +24 -0
  250. package/dist/stories/TpmBanner.stories.d.ts.map +1 -0
  251. package/dist/stories/TpmBanner.stories.js +63 -0
  252. package/dist/stories/TpmBanner.stories.js.map +1 -0
  253. package/dist/stories/TurnStatusIndicator.stories.d.ts +25 -0
  254. package/dist/stories/TurnStatusIndicator.stories.d.ts.map +1 -0
  255. package/dist/stories/TurnStatusIndicator.stories.js +56 -0
  256. package/dist/stories/TurnStatusIndicator.stories.js.map +1 -0
  257. package/dist/stories/_mockProvider.d.ts +44 -0
  258. package/dist/stories/_mockProvider.d.ts.map +1 -0
  259. package/dist/stories/_mockProvider.js +84 -0
  260. package/dist/stories/_mockProvider.js.map +1 -0
  261. package/dist/types.d.ts +787 -0
  262. package/dist/types.d.ts.map +1 -0
  263. package/dist/types.js +19 -0
  264. package/dist/types.js.map +1 -0
  265. package/dist/webcomponent/defineWebComponent.d.ts +106 -0
  266. package/dist/webcomponent/defineWebComponent.d.ts.map +1 -0
  267. package/dist/webcomponent/defineWebComponent.js +126 -0
  268. package/dist/webcomponent/defineWebComponent.js.map +1 -0
  269. package/dist/webcomponent/index.d.ts +7 -0
  270. package/dist/webcomponent/index.d.ts.map +1 -0
  271. package/dist/webcomponent/index.js +7 -0
  272. package/dist/webcomponent/index.js.map +1 -0
  273. package/package.json +63 -0
  274. package/src/__lint-canary__/step1-lint-canary.ts.disabled +28 -0
  275. package/src/auth/passwordPolicy.ts +75 -0
  276. package/src/auth/texts.ts +1294 -0
  277. package/src/client/AIHubClient.ts +1718 -0
  278. package/src/client/index.ts +30 -0
  279. package/src/client/sseParser.ts +168 -0
  280. package/src/client/tokenStorage.ts +131 -0
  281. package/src/components/AgentsPicker/index.tsx +147 -0
  282. package/src/components/AuthGate/index.tsx +132 -0
  283. package/src/components/CacheBadge/index.tsx +245 -0
  284. package/src/components/ChangePassword/index.tsx +375 -0
  285. package/src/components/ChatShell/ShellHeader.tsx +80 -0
  286. package/src/components/ChatShell/UserMenu.tsx +196 -0
  287. package/src/components/ChatShell/index.tsx +307 -0
  288. package/src/components/DataClubAIHub/index.tsx +300 -0
  289. package/src/components/DataClubAIHubAdmin/AgentEditorModal.tsx +505 -0
  290. package/src/components/DataClubAIHubAdmin/AgentsPage.tsx +342 -0
  291. package/src/components/DataClubAIHubAdmin/CreateUserModal.tsx +214 -0
  292. package/src/components/DataClubAIHubAdmin/PasswordRevealModal.tsx +204 -0
  293. package/src/components/DataClubAIHubAdmin/ResetPasswordModal.tsx +122 -0
  294. package/src/components/DataClubAIHubAdmin/RotatingMessageEditorModal.tsx +408 -0
  295. package/src/components/DataClubAIHubAdmin/RotatingMessagesPage.tsx +373 -0
  296. package/src/components/DataClubAIHubAdmin/SessionsOverviewPage.tsx +639 -0
  297. package/src/components/DataClubAIHubAdmin/SettingsPage.tsx +979 -0
  298. package/src/components/DataClubAIHubAdmin/UsersPage.tsx +495 -0
  299. package/src/components/DataClubAIHubAdmin/index.tsx +277 -0
  300. package/src/components/DataClubAIHubLogin/index.tsx +282 -0
  301. package/src/components/EffortControl/index.tsx +138 -0
  302. package/src/components/Layout/index.tsx +92 -0
  303. package/src/components/MainColumn/index.tsx +131 -0
  304. package/src/components/MarkdownRenderer/index.tsx +256 -0
  305. package/src/components/MessageInput/index.tsx +283 -0
  306. package/src/components/MessageList/index.tsx +753 -0
  307. package/src/components/ReasoningSelector/index.tsx +268 -0
  308. package/src/components/ReasoningView/index.tsx +183 -0
  309. package/src/components/ScrollToPresentButton/index.tsx +85 -0
  310. package/src/components/SessionsPanel/SessionTitleModal.tsx +256 -0
  311. package/src/components/SessionsPanel/index.tsx +406 -0
  312. package/src/components/SystemNotice/index.tsx +151 -0
  313. package/src/components/ThemeSwitcher/index.tsx +136 -0
  314. package/src/components/ToolCallView/formatContent.ts +50 -0
  315. package/src/components/ToolCallView/index.tsx +274 -0
  316. package/src/components/TpmBanner/index.tsx +172 -0
  317. package/src/components/TurnStatusIndicator/index.tsx +203 -0
  318. package/src/components/internal/PasswordInput.tsx +145 -0
  319. package/src/context/AIHubContext.ts +249 -0
  320. package/src/context/AIHubProvider.tsx +1084 -0
  321. package/src/context/index.ts +9 -0
  322. package/src/context/theme.ts +76 -0
  323. package/src/context/useAIHub.ts +151 -0
  324. package/src/context/useAIHubAuth.ts +65 -0
  325. package/src/index.ts +275 -0
  326. package/src/primitives/index.ts +101 -0
  327. package/src/state/affordances.ts +321 -0
  328. package/src/state/stateReducer.ts +131 -0
  329. package/src/stories/EffortControl.stories.tsx +63 -0
  330. package/src/stories/MarkdownRenderer.stories.tsx +201 -0
  331. package/src/stories/MessageBubble.stories.tsx +101 -0
  332. package/src/stories/ReasoningView.stories.tsx +81 -0
  333. package/src/stories/ScrollToPresentButton.stories.tsx +52 -0
  334. package/src/stories/SystemNotice.stories.tsx +59 -0
  335. package/src/stories/ThemeSwitcher.stories.tsx +55 -0
  336. package/src/stories/ToolCallView.stories.tsx +95 -0
  337. package/src/stories/TpmBanner.stories.tsx +93 -0
  338. package/src/stories/TurnStatusIndicator.stories.tsx +86 -0
  339. package/src/stories/_mockProvider.tsx +116 -0
  340. package/src/styles/CLASSES.md +356 -0
  341. package/src/styles/default.css +2937 -0
  342. package/src/types.ts +867 -0
  343. package/src/webcomponent/defineWebComponent.tsx +193 -0
  344. package/src/webcomponent/index.ts +11 -0
@@ -0,0 +1,172 @@
1
+ /**
2
+ * `<TpmBanner />` — TPM-recovery banner with countdown.
3
+ *
4
+ * Specialization of `<SystemNotice />` that:
5
+ *
6
+ * 1. Reads the active turn's `tpm_retry_at` from `useAIHub().state` and
7
+ * computes the remaining seconds at ~1Hz.
8
+ * 2. Switches variant based on §10.4: `tpm-wait` while `phase ===
9
+ * waiting_provider`, transient `resumed` flash on the `running →
10
+ * running(model_*)` recovery transition, and `error` when the
11
+ * `lastTurnError` is `tpm_exhausted`.
12
+ * 3. Renders nothing when none of the conditions apply — components can
13
+ * mount it unconditionally without flicker.
14
+ *
15
+ * The provider's reducer already clears `tpm_retry_at` on the `resumed`
16
+ * notice; the banner observes that change and shows the brief "Resumed."
17
+ * flash for 2s. The exhausted-error path renders a Retry button that
18
+ * re-issues the last user message (delegated to the parent via
19
+ * `onRetry`).
20
+ *
21
+ * @see SPECIFICATIONS.md §6.5 — TPM recovery
22
+ * @see SPECIFICATIONS.md §10.4 — predicates bound to (status, phase)
23
+ * @see ui-sketches/03-chat.md — system_notice variants
24
+ */
25
+
26
+ import { useEffect, useState, type ReactNode } from "react";
27
+
28
+ import {
29
+ resolveAIHubTexts,
30
+ type AIHubTexts,
31
+ type DeepPartial,
32
+ } from "../../auth/texts.js";
33
+ import { useAIHub } from "../../context/useAIHub.js";
34
+
35
+ import { SystemNotice } from "../SystemNotice/index.js";
36
+
37
+ /** Duration of the post-recovery "Resumed." flash, in milliseconds. */
38
+ const RESUMED_FLASH_MS = 2000;
39
+
40
+ /**
41
+ * Renders the countdown text by replacing `{seconds}` in the template.
42
+ *
43
+ * @param template - i18n template with `{seconds}` placeholder.
44
+ * @param seconds - integer seconds remaining; floors at 0.
45
+ * @returns the resolved text.
46
+ */
47
+ function renderCountdown(template: string, seconds: number): string {
48
+ const safe = Math.max(0, Math.floor(seconds));
49
+ return template.replace("{seconds}", String(safe));
50
+ }
51
+
52
+ /**
53
+ * Computes seconds-until against an ISO timestamp.
54
+ *
55
+ * @param retryAt - ISO timestamp from `tpm_retry_at`.
56
+ * @param now - epoch ms (test injection point).
57
+ * @returns seconds remaining (>= 0). Returns 0 when `retryAt` is invalid.
58
+ */
59
+ function secondsUntil(retryAt: string, now: number): number {
60
+ const target = Date.parse(retryAt);
61
+ if (!Number.isFinite(target)) return 0;
62
+ return Math.max(0, (target - now) / 1000);
63
+ }
64
+
65
+ /** Props for `<TpmBanner />`. */
66
+ export interface TpmBannerProps {
67
+ /**
68
+ * Called when the user clicks the Retry button on the `--error`
69
+ * variant. Wraps `sendMessage` of the last user message; the parent
70
+ * decides what "last user message" means (the monolith threads its
71
+ * own ref through).
72
+ */
73
+ onRetry?: () => void;
74
+ /** Wrapper-supplied i18n. */
75
+ texts?: DeepPartial<AIHubTexts>;
76
+ /** Extra class merged onto the root. */
77
+ className?: string;
78
+ /**
79
+ * Override the resolved "now" — test injection point. Production code
80
+ * leaves this unset (defaults to `Date.now()` at each tick).
81
+ */
82
+ nowProvider?: () => number;
83
+ }
84
+
85
+ /**
86
+ * Renders the banner.
87
+ *
88
+ * @param props - see `TpmBannerProps`.
89
+ * @returns the rendered banner, or `null` when nothing should render.
90
+ */
91
+ export function TpmBanner(props: TpmBannerProps): ReactNode {
92
+ const { state, lastTurnError } = useAIHub();
93
+ const texts = resolveAIHubTexts(props.texts);
94
+
95
+ // Tick at 1Hz while we're in the wait phase. The interval is
96
+ // re-installed when the deadline changes (new wait) or removed when
97
+ // we leave the wait phase.
98
+ const [, forceTick] = useState(0);
99
+ useEffect(() => {
100
+ if (state.phase !== "waiting_provider") return;
101
+ const tick = setInterval(() => {
102
+ forceTick((n) => n + 1);
103
+ }, 1000);
104
+ return () => clearInterval(tick);
105
+ }, [state.phase, state.tpm_retry_at]);
106
+
107
+ // Track the *previous* phase so the `running(waiting_provider) →
108
+ // running(model_*)` transition triggers the "Resumed." flash. We hold
109
+ // the flash on the screen for RESUMED_FLASH_MS, then clear.
110
+ const [showResumed, setShowResumed] = useState(false);
111
+ const [prevPhase, setPrevPhase] = useState(state.phase);
112
+ useEffect(() => {
113
+ if (
114
+ prevPhase === "waiting_provider" &&
115
+ state.phase !== "waiting_provider" &&
116
+ state.status === "running"
117
+ ) {
118
+ setShowResumed(true);
119
+ const t = setTimeout(() => setShowResumed(false), RESUMED_FLASH_MS);
120
+ setPrevPhase(state.phase);
121
+ return () => clearTimeout(t);
122
+ }
123
+ setPrevPhase(state.phase);
124
+ return undefined;
125
+ }, [state.phase, state.status]);
126
+
127
+ // Wait phase: render `--tpm-wait` with countdown.
128
+ if (state.phase === "waiting_provider" && state.tpm_retry_at) {
129
+ const now = (props.nowProvider ?? Date.now)();
130
+ const remaining = secondsUntil(state.tpm_retry_at, now);
131
+ return (
132
+ <SystemNotice
133
+ variant="tpm-wait"
134
+ message={renderCountdown(texts.chat.tpmWaitText, remaining)}
135
+ {...(props.className !== undefined ? { className: props.className } : {})}
136
+ />
137
+ );
138
+ }
139
+
140
+ // Brief "Resumed." flash right after a successful recovery.
141
+ if (showResumed) {
142
+ return (
143
+ <SystemNotice
144
+ variant="resumed"
145
+ message={texts.chat.systemResumedText}
146
+ {...(props.className !== undefined ? { className: props.className } : {})}
147
+ />
148
+ );
149
+ }
150
+
151
+ // Exhausted-error path — the provider sets `lastTurnError` on
152
+ // `error{tpm_exhausted}` + `stream_end{error}`. The retry button only
153
+ // surfaces here (the generic `--failed` Retry button on the message
154
+ // bubble is the equivalent for non-TPM failures).
155
+ if (
156
+ lastTurnError &&
157
+ lastTurnError.toLowerCase().includes("rate")
158
+ ) {
159
+ return (
160
+ <SystemNotice
161
+ variant="error"
162
+ message={texts.chat.tpmExhaustedText}
163
+ {...(props.onRetry !== undefined
164
+ ? { action: { label: texts.chat.tpmRetryButton, onClick: props.onRetry } }
165
+ : {})}
166
+ {...(props.className !== undefined ? { className: props.className } : {})}
167
+ />
168
+ );
169
+ }
170
+
171
+ return null;
172
+ }
@@ -0,0 +1,203 @@
1
+ /**
2
+ * `<TurnStatusIndicator />` — a small `●` dot + short label reflecting the
3
+ * active turn's `(status, phase)`.
4
+ *
5
+ * Pure function of state (via `turnStatusVisual` in `state/affordances.ts`).
6
+ * Two soft-state behaviors are local to the component:
7
+ *
8
+ * 1. **`done` flash.** On the transition `running → done`, the indicator
9
+ * briefly shows "Done" (~2s) and then settles to "Ready" — this is the
10
+ * visual "the turn finished" affordance the predicate table calls for.
11
+ * 2. **`cancelled` auto-clear.** After ~3s the indicator clears back to
12
+ * "Ready" so the cancelled stamp doesn't sit forever in the header.
13
+ *
14
+ * Both timers respect `prefers-reduced-motion` by skipping the pulse
15
+ * animation; the timer logic still runs, but the dot stays static.
16
+ *
17
+ * Rendering is gated by:
18
+ *
19
+ * - the `showTurnStatus` React prop (default true) AND
20
+ * - the `turn_status_visible` server toggle (§8.4) — precedence: server > prop.
21
+ *
22
+ * Both gates are AND-combined in `useAffordanceFlags` upstream so the
23
+ * primitive itself only checks `if (!visible) return null`.
24
+ *
25
+ * Exported under `AIHub.TurnStatusIndicator`.
26
+ *
27
+ * @see SPECIFICATIONS.md §10.4 — predicate table + label map
28
+ * @see ui-sketches/03-chat.md — turn_status_indicator
29
+ */
30
+
31
+ import { useEffect, useRef, useState, type ReactNode } from "react";
32
+
33
+ import { useAIHub } from "../../context/useAIHub.js";
34
+ import { turnStatusVisual } from "../../state/affordances.js";
35
+ import type {
36
+ AIHubState,
37
+ RunningPhase,
38
+ TurnStatus,
39
+ } from "../../types.js";
40
+
41
+ /**
42
+ * BEM class names emitted by `<TurnStatusIndicator />`.
43
+ */
44
+ export interface TurnStatusIndicatorClassNames {
45
+ /** Outer wrapper. */
46
+ root: string;
47
+ /** Dot element — pulse animation hooks here. */
48
+ dot: string;
49
+ /** Modifier on the dot — `--idle` (gray static). */
50
+ dotIdle: string;
51
+ /** Modifier on the dot — `--running` (accent pulsing). */
52
+ dotRunning: string;
53
+ /** Modifier on the dot — `--warning` (yellow pulsing). */
54
+ dotWarning: string;
55
+ /** Modifier on the dot — `--error` (red static). */
56
+ dotError: string;
57
+ /** Modifier added when pulsing is allowed (drops under reduced-motion). */
58
+ dotPulse: string;
59
+ /** Label text. */
60
+ label: string;
61
+ }
62
+
63
+ const DEFAULT_CLASS_NAMES: TurnStatusIndicatorClassNames = Object.freeze({
64
+ root: "data-club-ai-hub__turn-status",
65
+ dot: "data-club-ai-hub__turn-status__dot",
66
+ dotIdle: "data-club-ai-hub__turn-status__dot--idle",
67
+ dotRunning: "data-club-ai-hub__turn-status__dot--running",
68
+ dotWarning: "data-club-ai-hub__turn-status__dot--warning",
69
+ dotError: "data-club-ai-hub__turn-status__dot--error",
70
+ dotPulse: "data-club-ai-hub__turn-status__dot--pulse",
71
+ label: "data-club-ai-hub__turn-status__label",
72
+ }) as TurnStatusIndicatorClassNames;
73
+
74
+ /**
75
+ * Maps the visual variant to its modifier class.
76
+ */
77
+ function dotModifier(
78
+ variant: "idle" | "running" | "warning" | "error",
79
+ cls: TurnStatusIndicatorClassNames,
80
+ ): string {
81
+ switch (variant) {
82
+ case "running":
83
+ return cls.dotRunning;
84
+ case "warning":
85
+ return cls.dotWarning;
86
+ case "error":
87
+ return cls.dotError;
88
+ case "idle":
89
+ return cls.dotIdle;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Props for `<TurnStatusIndicator />`.
95
+ *
96
+ * `state` is optional — when omitted the component reads it from the
97
+ * provider via `useAIHub()`. Passing it explicitly is useful for the
98
+ * Storybook stories (Step 10 ships them for every cell of the §10.4
99
+ * table) and for the test harness, both of which render the indicator
100
+ * in isolation without a real reducer in scope.
101
+ */
102
+ export interface TurnStatusIndicatorProps {
103
+ /** Override the state read from context (used by stories + tests). */
104
+ state?: AIHubState;
105
+ /** Extra class merged onto the root. */
106
+ className?: string;
107
+ /** Per-element class overrides. */
108
+ classNames?: Partial<TurnStatusIndicatorClassNames>;
109
+ }
110
+
111
+ /**
112
+ * Duration of the post-done "Done" flash, in milliseconds. After this
113
+ * expires the indicator settles back to "Ready" (`idle` dot).
114
+ */
115
+ const DONE_FLASH_MS = 2000;
116
+
117
+ /**
118
+ * Duration of the post-cancel "Cancelled" stamp, in milliseconds.
119
+ */
120
+ const CANCELLED_CLEAR_MS = 3000;
121
+
122
+ /**
123
+ * Renders the indicator.
124
+ *
125
+ * @param props - see `TurnStatusIndicatorProps`.
126
+ * @returns the rendered indicator.
127
+ */
128
+ export function TurnStatusIndicator(
129
+ props: TurnStatusIndicatorProps,
130
+ ): ReactNode {
131
+ const ctx = useAIHub();
132
+ const state = props.state ?? ctx.state;
133
+ const cls = { ...DEFAULT_CLASS_NAMES, ...(props.classNames ?? {}) };
134
+
135
+ // Capture the *effective* status / phase for rendering. After done /
136
+ // cancelled clear timers expire we treat the state as `idle` so the
137
+ // dot doesn't sit on "Done" forever.
138
+ const [effective, setEffective] = useState<{
139
+ status: TurnStatus;
140
+ phase: RunningPhase | null;
141
+ }>({ status: state.status, phase: state.phase });
142
+
143
+ // Track the previous status so we know when to start the
144
+ // done/cancelled clear timer (state only updates on transitions).
145
+ const prevStatusRef = useRef<TurnStatus>(state.status);
146
+
147
+ useEffect(() => {
148
+ const prev = prevStatusRef.current;
149
+ prevStatusRef.current = state.status;
150
+
151
+ // No timer needed when the status is steady at running or idle.
152
+ if (state.status === prev) {
153
+ setEffective({ status: state.status, phase: state.phase });
154
+ return;
155
+ }
156
+
157
+ // Fresh state — lift it.
158
+ setEffective({ status: state.status, phase: state.phase });
159
+
160
+ if (state.status === "done") {
161
+ const t = setTimeout(() => {
162
+ setEffective({ status: "idle", phase: null });
163
+ }, DONE_FLASH_MS);
164
+ return () => clearTimeout(t);
165
+ }
166
+ if (state.status === "cancelled") {
167
+ const t = setTimeout(() => {
168
+ setEffective({ status: "idle", phase: null });
169
+ }, CANCELLED_CLEAR_MS);
170
+ return () => clearTimeout(t);
171
+ }
172
+ return undefined;
173
+ }, [state.status, state.phase]);
174
+
175
+ const visual = turnStatusVisual(effective.status, effective.phase);
176
+ const rootClass = props.className
177
+ ? `${cls.root} ${props.className}`
178
+ : cls.root;
179
+ const dotClass = [
180
+ cls.dot,
181
+ dotModifier(visual.dot, cls),
182
+ visual.pulse ? cls.dotPulse : null,
183
+ ]
184
+ .filter(Boolean)
185
+ .join(" ");
186
+
187
+ return (
188
+ <div
189
+ className={rootClass}
190
+ data-testid="turn-status-indicator"
191
+ data-status={effective.status}
192
+ data-phase={effective.phase ?? "none"}
193
+ data-variant={visual.dot}
194
+ role="status"
195
+ aria-live="polite"
196
+ >
197
+ <span className={dotClass} aria-hidden="true" />
198
+ <span className={cls.label} data-testid="turn-status-label">
199
+ {visual.label}
200
+ </span>
201
+ </div>
202
+ );
203
+ }
@@ -0,0 +1,145 @@
1
+ /**
2
+ * `<PasswordInput>` — internal helper used by `<DataClubAIHubLogin />` and
3
+ * `<DataClubAIHubChangePassword />` to render a password field with its own
4
+ * show/hide eye-icon toggle.
5
+ *
6
+ * The toggle is **per-field** (each input owns its own state) so a user
7
+ * can reveal one field while keeping another masked — useful for visually
8
+ * verifying a match between New and Confirm without exposing both at once.
9
+ *
10
+ * Not exported from the package (no JSDoc-required interface surfaces here);
11
+ * lives under `components/internal/` to make that explicit.
12
+ *
13
+ * @see ui-sketches/01-login.md — show_password_toggle
14
+ * @see ui-sketches/02-change-password.md — per-field toggle
15
+ */
16
+
17
+ import { useState, type ReactNode } from "react";
18
+
19
+ /**
20
+ * Props for the internal `<PasswordInput>` helper.
21
+ */
22
+ export interface PasswordInputProps {
23
+ /** Stable DOM id used by the label + `aria-describedby` if any. */
24
+ id: string;
25
+ /** Input value. */
26
+ value: string;
27
+ /** Change handler — receives the next plaintext value. */
28
+ onChange: (next: string) => void;
29
+ /** Native `name` attribute for autofill / form submission. */
30
+ name: string;
31
+ /** Native `autoComplete` value — caller picks per field. */
32
+ autoComplete?: string;
33
+ /** Placeholder text. Defaults to "••••••••". */
34
+ placeholder?: string;
35
+ /** Whether the input is disabled (e.g. during submit). */
36
+ disabled?: boolean;
37
+ /** Whether to autofocus on mount. */
38
+ autoFocus?: boolean;
39
+ /** Required field — mirrors HTML `required` for browser-side validation. */
40
+ required?: boolean;
41
+ /** `aria-label` for the toggle when the password is currently hidden. */
42
+ showAriaLabel: string;
43
+ /** `aria-label` for the toggle when the password is currently shown. */
44
+ hideAriaLabel: string;
45
+ /** BEM class for the wrapper `<div>` that holds the input + toggle. */
46
+ wrapperClassName: string;
47
+ /** BEM class for the `<input>` itself. */
48
+ inputClassName: string;
49
+ /** BEM class for the toggle `<button>`. */
50
+ toggleClassName: string;
51
+ /** Optional `data-testid` on the wrapper — used by RTL tests. */
52
+ testId?: string;
53
+ }
54
+
55
+ /**
56
+ * Renders a password field with a show/hide eye-icon toggle.
57
+ *
58
+ * The toggle is `type="button"` (not submit) and keyboard-accessible
59
+ * (Enter / Space activate without submitting the surrounding form).
60
+ *
61
+ * @param props - the input props.
62
+ * @returns the input + toggle pair.
63
+ */
64
+ export function PasswordInput(props: PasswordInputProps): ReactNode {
65
+ const {
66
+ id,
67
+ value,
68
+ onChange,
69
+ name,
70
+ autoComplete,
71
+ placeholder = "••••••••",
72
+ disabled,
73
+ autoFocus,
74
+ required,
75
+ showAriaLabel,
76
+ hideAriaLabel,
77
+ wrapperClassName,
78
+ inputClassName,
79
+ toggleClassName,
80
+ testId,
81
+ } = props;
82
+
83
+ const [revealed, setRevealed] = useState(false);
84
+
85
+ return (
86
+ <div
87
+ className={wrapperClassName}
88
+ {...(testId !== undefined ? { "data-testid": testId } : {})}
89
+ >
90
+ <input
91
+ id={id}
92
+ type={revealed ? "text" : "password"}
93
+ value={value}
94
+ onChange={(e) => onChange(e.target.value)}
95
+ name={name}
96
+ {...(autoComplete !== undefined ? { autoComplete } : {})}
97
+ placeholder={placeholder}
98
+ disabled={disabled}
99
+ autoFocus={autoFocus}
100
+ required={required}
101
+ className={inputClassName}
102
+ />
103
+ <button
104
+ type="button"
105
+ className={toggleClassName}
106
+ aria-label={revealed ? hideAriaLabel : showAriaLabel}
107
+ aria-pressed={revealed}
108
+ onClick={() => setRevealed((r) => !r)}
109
+ tabIndex={0}
110
+ >
111
+ {/* Inline SVG — sized via CSS, color follows currentColor. */}
112
+ <EyeIcon open={revealed} />
113
+ </button>
114
+ </div>
115
+ );
116
+ }
117
+
118
+ /**
119
+ * Inline eye icon. Two paths so the open / closed variants share weight
120
+ * and stroke caps without two `<svg>` trees.
121
+ *
122
+ * @param props - icon props.
123
+ * @param props.open - true → "show" (eye), false → "hide" (eye with slash).
124
+ */
125
+ function EyeIcon(props: { open: boolean }): ReactNode {
126
+ return (
127
+ <svg
128
+ xmlns="http://www.w3.org/2000/svg"
129
+ viewBox="0 0 24 24"
130
+ width="18"
131
+ height="18"
132
+ fill="none"
133
+ stroke="currentColor"
134
+ strokeWidth="2"
135
+ strokeLinecap="round"
136
+ strokeLinejoin="round"
137
+ aria-hidden="true"
138
+ focusable="false"
139
+ >
140
+ <path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z" />
141
+ <circle cx="12" cy="12" r="3" />
142
+ {!props.open ? <path d="M3 3l18 18" /> : null}
143
+ </svg>
144
+ );
145
+ }