@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,495 @@
1
+ /**
2
+ * `<AdminUsersPage />` — the Users sub-page mounted inside
3
+ * `<DataClubAIHubAdmin />` ([05-admin-users.md]).
4
+ *
5
+ * Shows every user in the deployment in `users_table`, with per-row
6
+ * actions (`[role▼]`, `[reset pw]`, 🗑). Disabled-action conditions per
7
+ * [05-admin-users.md]:
8
+ *
9
+ * - **Admin shield** — an `admin` caller sees the role dropdown / reset /
10
+ * delete disabled on every other admin's row and on every super_admin's
11
+ * row.
12
+ * - **Super-admin min-count** — actions on the only super_admin are
13
+ * disabled regardless of caller role.
14
+ * - **Self-protection** — delete is disabled on the caller's own row
15
+ * (server enforces too).
16
+ *
17
+ * The role dropdown's options are filtered by caller role — `admin` cannot
18
+ * promote to `super_admin`, so that option is omitted (the option is
19
+ * client-side filtered to mirror what the server enforces; passing it
20
+ * anyway would 403).
21
+ *
22
+ * Two-phase Create User and Reset Password flows: the Phase-1 dialog
23
+ * triggers the server call, which on success swaps in
24
+ * `<PasswordRevealModal />` as Phase 2. The password is held in this
25
+ * component's state until the admin clicks Done — once dismissed it is
26
+ * unrecoverable.
27
+ *
28
+ * @see SPECIFICATIONS.md §6.3.4 / §8.1 / §8.5
29
+ * @see ui-sketches/05-admin-users.md
30
+ */
31
+ import { useEffect, useState, type ReactNode } from "react";
32
+
33
+ import type { AIHubAdminTexts } from "../../auth/texts.js";
34
+ import type {
35
+ AdminUserView,
36
+ AIHubRequestError as AIHubRequestErrorType,
37
+ } from "../../client/AIHubClient.js";
38
+ import { useAIHub } from "../../context/useAIHub.js";
39
+ import { useAIHubAuth } from "../../context/useAIHubAuth.js";
40
+ import type { AIHubRole } from "../../types.js";
41
+
42
+ import { CreateUserModal } from "./CreateUserModal.js";
43
+ import { PasswordRevealModal } from "./PasswordRevealModal.js";
44
+ import { ResetPasswordModal } from "./ResetPasswordModal.js";
45
+
46
+ /**
47
+ * Per-target lifecycle state for the password-reveal Phase 2 modal. The
48
+ * password lives here (and ONLY here) until the admin dismisses the modal.
49
+ */
50
+ interface RevealState {
51
+ variant: "create" | "reset";
52
+ username: string;
53
+ password: string;
54
+ }
55
+
56
+ /** A pending row-level toast / flash. */
57
+ interface RowFlash {
58
+ userId: string;
59
+ text: string;
60
+ tone: "success" | "error";
61
+ }
62
+
63
+ /**
64
+ * Returns whether the role-mutation / reset / delete actions are disabled
65
+ * for `target` when the caller has `callerRole` and `callerId`, accounting
66
+ * for the §8.1 shield + min-count rules. The boolean drives the disabled
67
+ * state of the row's controls; the server enforces independently.
68
+ *
69
+ * @param callerRole - caller's role.
70
+ * @param callerId - caller's user id (for self-protection on delete).
71
+ * @param target - the row being inspected.
72
+ * @param superAdminCount - count of super_admins in the deployment.
73
+ * @returns a record of disabled flags + the reason hint to surface.
74
+ */
75
+ function rowDisabledFlags(
76
+ callerRole: AIHubRole | null,
77
+ callerId: string | null,
78
+ target: AdminUserView,
79
+ superAdminCount: number,
80
+ ): { role: boolean; reset: boolean; delete: boolean; reason: "shield" | "minCount" | null } {
81
+ // The only-super_admin row: every destructive action is locked.
82
+ if (target.role === "super_admin" && superAdminCount <= 1) {
83
+ return { role: true, reset: true, delete: true, reason: "minCount" };
84
+ }
85
+ if (callerRole === "admin") {
86
+ if (target.role === "admin" || target.role === "super_admin") {
87
+ return { role: true, reset: true, delete: true, reason: "shield" };
88
+ }
89
+ }
90
+ // Self-delete is blocked outright (server enforces too).
91
+ const isSelf = callerId !== null && callerId === target.id;
92
+ return { role: false, reset: false, delete: isSelf, reason: null };
93
+ }
94
+
95
+ /**
96
+ * Returns the role options visible to the caller.
97
+ *
98
+ * - `admin` cannot grant `super_admin` (server enforces, see §6.3.4).
99
+ * - `super_admin` sees all four roles.
100
+ */
101
+ function callerRoleOptions(role: AIHubRole | null): AIHubRole[] {
102
+ if (role === "super_admin") {
103
+ return ["user", "power_user", "admin", "super_admin"];
104
+ }
105
+ return ["user", "power_user", "admin"];
106
+ }
107
+
108
+ /**
109
+ * Props for `<AdminUsersPage />`.
110
+ */
111
+ export interface AdminUsersPageProps {
112
+ /** Resolved admin texts. */
113
+ texts: AIHubAdminTexts;
114
+ }
115
+
116
+ /**
117
+ * Renders the Users sub-page.
118
+ *
119
+ * @param props - see `AdminUsersPageProps`.
120
+ * @returns the rendered page.
121
+ */
122
+ export function AdminUsersPage(props: AdminUsersPageProps): ReactNode {
123
+ const { client } = useAIHub();
124
+ const auth = useAIHubAuth();
125
+ const callerRole = auth.role;
126
+ const callerId = auth.user?.id ?? null;
127
+
128
+ const [users, setUsers] = useState<AdminUserView[] | null>(null);
129
+ const [loadError, setLoadError] = useState<string | null>(null);
130
+
131
+ const [showCreate, setShowCreate] = useState(false);
132
+ const [resetTarget, setResetTarget] = useState<AdminUserView | null>(null);
133
+ const [reveal, setReveal] = useState<RevealState | null>(null);
134
+ const [flash, setFlash] = useState<RowFlash | null>(null);
135
+
136
+ // Tracks rows currently being mutated (role change in flight) so the
137
+ // dropdown can disable itself while we wait.
138
+ const [pendingRoleId, setPendingRoleId] = useState<string | null>(null);
139
+
140
+ // Initial load.
141
+ useEffect(() => {
142
+ let cancelled = false;
143
+ void (async () => {
144
+ try {
145
+ const rows = await client.listAdminUsers();
146
+ if (!cancelled) {
147
+ setUsers(rows);
148
+ setLoadError(null);
149
+ }
150
+ } catch (err) {
151
+ if (!cancelled) {
152
+ setLoadError(
153
+ err instanceof Error && err.message
154
+ ? err.message
155
+ : props.texts.usersGenericError,
156
+ );
157
+ }
158
+ }
159
+ })();
160
+ return () => {
161
+ cancelled = true;
162
+ };
163
+ }, [client, props.texts.usersGenericError]);
164
+
165
+ // Auto-clear the flash after a short window so it doesn't linger.
166
+ useEffect(() => {
167
+ if (flash === null) return;
168
+ const id = setTimeout(() => setFlash(null), 3000);
169
+ return () => clearTimeout(id);
170
+ }, [flash]);
171
+
172
+ const superAdminCount = (users ?? []).filter(
173
+ (u) => u.role === "super_admin",
174
+ ).length;
175
+ const roleOptions = callerRoleOptions(callerRole);
176
+
177
+ function roleLabel(role: AIHubRole): string {
178
+ if (role === "super_admin") return props.texts.roleOptionSuperAdmin;
179
+ if (role === "admin") return props.texts.roleOptionAdmin;
180
+ if (role === "power_user") return props.texts.roleOptionPowerUser;
181
+ return props.texts.roleOptionUser;
182
+ }
183
+
184
+ async function handleCreate(input: {
185
+ username: string;
186
+ displayName: string | null;
187
+ role: AIHubRole;
188
+ }): Promise<void> {
189
+ const result = await client.createAdminUser({
190
+ username: input.username,
191
+ displayName: input.displayName,
192
+ role: input.role,
193
+ });
194
+ setUsers((prev) =>
195
+ prev === null ? [result.user] : sortByUsername([...prev, result.user]),
196
+ );
197
+ setShowCreate(false);
198
+ setReveal({
199
+ variant: "create",
200
+ username: result.user.username,
201
+ password: result.generatedPassword,
202
+ });
203
+ }
204
+
205
+ async function handleRoleChange(
206
+ target: AdminUserView,
207
+ newRole: AIHubRole,
208
+ ): Promise<void> {
209
+ if (newRole === target.role) return;
210
+ setPendingRoleId(target.id);
211
+ setFlash(null);
212
+ try {
213
+ const updated = await client.patchAdminUserRole(target.id, newRole);
214
+ setUsers((prev) =>
215
+ prev === null
216
+ ? null
217
+ : prev.map((u) => (u.id === updated.id ? updated : u)),
218
+ );
219
+ setFlash({
220
+ userId: target.id,
221
+ text: props.texts.roleChangeSuccessToast.replace(
222
+ "{role}",
223
+ roleLabel(newRole),
224
+ ),
225
+ tone: "success",
226
+ });
227
+ } catch (err) {
228
+ const errAsAny = err as AIHubRequestErrorType | Error;
229
+ const message =
230
+ errAsAny instanceof Error && errAsAny.message
231
+ ? errAsAny.message
232
+ : props.texts.roleChangeForbiddenFallback;
233
+ setFlash({ userId: target.id, text: message, tone: "error" });
234
+ } finally {
235
+ setPendingRoleId(null);
236
+ }
237
+ }
238
+
239
+ async function handleResetConfirm(target: AdminUserView): Promise<void> {
240
+ const result = await client.resetAdminUserPassword(target.id);
241
+ setResetTarget(null);
242
+ // Re-fetch the row so the ⚠ marker (is_initial_password=true) refreshes.
243
+ setUsers((prev) =>
244
+ prev === null
245
+ ? null
246
+ : prev.map((u) =>
247
+ u.id === target.id ? { ...u, is_initial_password: true } : u,
248
+ ),
249
+ );
250
+ setReveal({
251
+ variant: "reset",
252
+ username: target.username,
253
+ password: result.generatedPassword,
254
+ });
255
+ }
256
+
257
+ async function handleDelete(target: AdminUserView): Promise<void> {
258
+ const prompt = props.texts.deleteUserConfirmPrompt.replace(
259
+ "{username}",
260
+ target.username,
261
+ );
262
+ // Native confirm is fine for v1 per [05-admin-users.md].
263
+ // eslint-disable-next-line no-alert
264
+ const ok =
265
+ typeof window !== "undefined" && typeof window.confirm === "function"
266
+ ? window.confirm(prompt)
267
+ : true;
268
+ if (!ok) return;
269
+ try {
270
+ await client.deleteAdminUser(target.id);
271
+ setUsers((prev) =>
272
+ prev === null ? null : prev.filter((u) => u.id !== target.id),
273
+ );
274
+ } catch (err) {
275
+ const message =
276
+ err instanceof Error && err.message
277
+ ? err.message
278
+ : props.texts.deleteUserGenericError;
279
+ setFlash({ userId: target.id, text: message, tone: "error" });
280
+ }
281
+ }
282
+
283
+ return (
284
+ <div
285
+ className="data-club-ai-hub-admin__users-page"
286
+ data-testid="admin-users-page"
287
+ >
288
+ <header className="data-club-ai-hub-admin__page-header">
289
+ <h1
290
+ className="data-club-ai-hub-admin__page-heading"
291
+ data-testid="admin-users-heading"
292
+ >
293
+ {props.texts.usersHeading}
294
+ </h1>
295
+ <button
296
+ type="button"
297
+ className="data-club-ai-hub-admin__button data-club-ai-hub-admin__button--primary"
298
+ data-testid="admin-users-create"
299
+ onClick={() => setShowCreate(true)}
300
+ >
301
+ {props.texts.createUserButton}
302
+ </button>
303
+ </header>
304
+ {loadError !== null ? (
305
+ <div
306
+ className="data-club-ai-hub-admin__error"
307
+ data-testid="admin-users-error"
308
+ role="alert"
309
+ >
310
+ {loadError}
311
+ </div>
312
+ ) : null}
313
+ {users === null && loadError === null ? (
314
+ <p
315
+ className="data-club-ai-hub-admin__loading"
316
+ data-testid="admin-users-loading"
317
+ >
318
+ {props.texts.usersLoading}
319
+ </p>
320
+ ) : null}
321
+ {users !== null && users.length === 0 ? (
322
+ <p
323
+ className="data-club-ai-hub-admin__empty"
324
+ data-testid="admin-users-empty"
325
+ >
326
+ {props.texts.usersEmpty}
327
+ </p>
328
+ ) : null}
329
+ {users !== null && users.length > 0 ? (
330
+ <table
331
+ className="data-club-ai-hub-admin__users-table"
332
+ data-testid="admin-users-table"
333
+ >
334
+ <thead>
335
+ <tr>
336
+ <th>{props.texts.userColumnUsername}</th>
337
+ <th>{props.texts.userColumnDisplay}</th>
338
+ <th>{props.texts.userColumnRole}</th>
339
+ <th>{props.texts.userColumnActions}</th>
340
+ </tr>
341
+ </thead>
342
+ <tbody>
343
+ {users.map((u) => {
344
+ const flags = rowDisabledFlags(
345
+ callerRole,
346
+ callerId,
347
+ u,
348
+ superAdminCount,
349
+ );
350
+ const reasonText =
351
+ flags.reason === "shield"
352
+ ? props.texts.roleSelectShieldDisabledHint
353
+ : flags.reason === "minCount"
354
+ ? props.texts.roleSelectMinCountDisabledHint
355
+ : "";
356
+ const flashForRow =
357
+ flash !== null && flash.userId === u.id ? flash : null;
358
+ return (
359
+ <tr
360
+ key={u.id}
361
+ data-testid={`admin-user-row-${u.id}`}
362
+ data-username={u.username}
363
+ data-role={u.role}
364
+ className={
365
+ u.is_initial_password
366
+ ? "data-club-ai-hub-admin__users-row data-club-ai-hub-admin__users-row--initial-password"
367
+ : "data-club-ai-hub-admin__users-row"
368
+ }
369
+ >
370
+ <td>
371
+ {u.is_initial_password ? (
372
+ <span
373
+ className="data-club-ai-hub-admin__initial-password-indicator"
374
+ data-testid={`admin-user-row-${u.id}-initial-password`}
375
+ title={props.texts.initialPasswordIndicator}
376
+ aria-label={props.texts.initialPasswordIndicator}
377
+ >
378
+
379
+ </span>
380
+ ) : null}{" "}
381
+ {u.username}
382
+ </td>
383
+ <td>{u.display_name ?? "—"}</td>
384
+ <td>
385
+ {flags.role ? (
386
+ <span
387
+ className="data-club-ai-hub-admin__role-static"
388
+ data-testid={`admin-user-row-${u.id}-role-static`}
389
+ title={reasonText}
390
+ >
391
+ {roleLabel(u.role)}
392
+ </span>
393
+ ) : (
394
+ <select
395
+ value={u.role}
396
+ onChange={(e) => {
397
+ void handleRoleChange(
398
+ u,
399
+ e.target.value as AIHubRole,
400
+ );
401
+ }}
402
+ disabled={pendingRoleId === u.id}
403
+ className="data-club-ai-hub-admin__role-select"
404
+ data-testid={`admin-user-row-${u.id}-role-select`}
405
+ aria-label={`${props.texts.userColumnRole}: ${u.username}`}
406
+ >
407
+ {roleOptions.map((r) => (
408
+ <option key={r} value={r}>
409
+ {roleLabel(r)}
410
+ </option>
411
+ ))}
412
+ </select>
413
+ )}
414
+ </td>
415
+ <td>
416
+ <button
417
+ type="button"
418
+ className="data-club-ai-hub-admin__row-action"
419
+ data-testid={`admin-user-row-${u.id}-reset`}
420
+ onClick={() => setResetTarget(u)}
421
+ disabled={flags.reset}
422
+ title={flags.reset ? reasonText : undefined}
423
+ aria-label={`${props.texts.resetPasswordButtonLabel}: ${u.username}`}
424
+ >
425
+ 🔑
426
+ </button>
427
+ <button
428
+ type="button"
429
+ className="data-club-ai-hub-admin__row-action data-club-ai-hub-admin__row-action--delete"
430
+ data-testid={`admin-user-row-${u.id}-delete`}
431
+ onClick={() => {
432
+ void handleDelete(u);
433
+ }}
434
+ disabled={flags.delete}
435
+ title={flags.delete ? reasonText : undefined}
436
+ aria-label={`${props.texts.deleteUserButtonLabel}: ${u.username}`}
437
+ >
438
+ 🗑
439
+ </button>
440
+ {flashForRow !== null ? (
441
+ <span
442
+ className={
443
+ flashForRow.tone === "success"
444
+ ? "data-club-ai-hub-admin__row-flash data-club-ai-hub-admin__row-flash--success"
445
+ : "data-club-ai-hub-admin__row-flash data-club-ai-hub-admin__row-flash--error"
446
+ }
447
+ data-testid={`admin-user-row-${u.id}-flash`}
448
+ role={flashForRow.tone === "error" ? "alert" : "status"}
449
+ aria-live="polite"
450
+ >
451
+ {flashForRow.text}
452
+ </span>
453
+ ) : null}
454
+ </td>
455
+ </tr>
456
+ );
457
+ })}
458
+ </tbody>
459
+ </table>
460
+ ) : null}
461
+
462
+ {showCreate ? (
463
+ <CreateUserModal
464
+ callerRole={callerRole}
465
+ texts={props.texts}
466
+ onSubmit={handleCreate}
467
+ onCancel={() => setShowCreate(false)}
468
+ />
469
+ ) : null}
470
+
471
+ {resetTarget !== null ? (
472
+ <ResetPasswordModal
473
+ username={resetTarget.username}
474
+ texts={props.texts}
475
+ onConfirm={() => handleResetConfirm(resetTarget)}
476
+ onCancel={() => setResetTarget(null)}
477
+ />
478
+ ) : null}
479
+
480
+ {reveal !== null ? (
481
+ <PasswordRevealModal
482
+ variant={reveal.variant}
483
+ username={reveal.username}
484
+ password={reveal.password}
485
+ texts={props.texts}
486
+ onClose={() => setReveal(null)}
487
+ />
488
+ ) : null}
489
+ </div>
490
+ );
491
+ }
492
+
493
+ function sortByUsername(rows: AdminUserView[]): AdminUserView[] {
494
+ return [...rows].sort((a, b) => a.username.localeCompare(b.username));
495
+ }