@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.
- package/dist/auth/passwordPolicy.d.ts +55 -0
- package/dist/auth/passwordPolicy.d.ts.map +1 -0
- package/dist/auth/passwordPolicy.js +63 -0
- package/dist/auth/passwordPolicy.js.map +1 -0
- package/dist/auth/texts.d.ts +815 -0
- package/dist/auth/texts.d.ts.map +1 -0
- package/dist/auth/texts.js +429 -0
- package/dist/auth/texts.js.map +1 -0
- package/dist/client/AIHubClient.d.ts +1058 -0
- package/dist/client/AIHubClient.d.ts.map +1 -0
- package/dist/client/AIHubClient.js +950 -0
- package/dist/client/AIHubClient.js.map +1 -0
- package/dist/client/index.d.ts +11 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +9 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/sseParser.d.ts +41 -0
- package/dist/client/sseParser.d.ts.map +1 -0
- package/dist/client/sseParser.js +153 -0
- package/dist/client/sseParser.js.map +1 -0
- package/dist/client/tokenStorage.d.ts +56 -0
- package/dist/client/tokenStorage.d.ts.map +1 -0
- package/dist/client/tokenStorage.js +116 -0
- package/dist/client/tokenStorage.js.map +1 -0
- package/dist/components/AgentsPicker/index.d.ts +70 -0
- package/dist/components/AgentsPicker/index.d.ts.map +1 -0
- package/dist/components/AgentsPicker/index.js +63 -0
- package/dist/components/AgentsPicker/index.js.map +1 -0
- package/dist/components/AuthGate/index.d.ts +79 -0
- package/dist/components/AuthGate/index.d.ts.map +1 -0
- package/dist/components/AuthGate/index.js +61 -0
- package/dist/components/AuthGate/index.js.map +1 -0
- package/dist/components/CacheBadge/index.d.ts +88 -0
- package/dist/components/CacheBadge/index.d.ts.map +1 -0
- package/dist/components/CacheBadge/index.js +127 -0
- package/dist/components/CacheBadge/index.js.map +1 -0
- package/dist/components/ChangePassword/index.d.ts +109 -0
- package/dist/components/ChangePassword/index.d.ts.map +1 -0
- package/dist/components/ChangePassword/index.js +142 -0
- package/dist/components/ChangePassword/index.js.map +1 -0
- package/dist/components/ChatShell/ShellHeader.d.ts +44 -0
- package/dist/components/ChatShell/ShellHeader.d.ts.map +1 -0
- package/dist/components/ChatShell/ShellHeader.js +14 -0
- package/dist/components/ChatShell/ShellHeader.js.map +1 -0
- package/dist/components/ChatShell/UserMenu.d.ts +48 -0
- package/dist/components/ChatShell/UserMenu.d.ts.map +1 -0
- package/dist/components/ChatShell/UserMenu.js +86 -0
- package/dist/components/ChatShell/UserMenu.js.map +1 -0
- package/dist/components/ChatShell/index.d.ts +98 -0
- package/dist/components/ChatShell/index.d.ts.map +1 -0
- package/dist/components/ChatShell/index.js +124 -0
- package/dist/components/ChatShell/index.js.map +1 -0
- package/dist/components/DataClubAIHub/index.d.ts +132 -0
- package/dist/components/DataClubAIHub/index.d.ts.map +1 -0
- package/dist/components/DataClubAIHub/index.js +124 -0
- package/dist/components/DataClubAIHub/index.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/AgentEditorModal.d.ts +89 -0
- package/dist/components/DataClubAIHubAdmin/AgentEditorModal.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/AgentEditorModal.js +199 -0
- package/dist/components/DataClubAIHubAdmin/AgentEditorModal.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/AgentsPage.d.ts +33 -0
- package/dist/components/DataClubAIHubAdmin/AgentsPage.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/AgentsPage.js +137 -0
- package/dist/components/DataClubAIHubAdmin/AgentsPage.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/CreateUserModal.d.ts +50 -0
- package/dist/components/DataClubAIHubAdmin/CreateUserModal.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/CreateUserModal.js +93 -0
- package/dist/components/DataClubAIHubAdmin/CreateUserModal.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/PasswordRevealModal.d.ts +49 -0
- package/dist/components/DataClubAIHubAdmin/PasswordRevealModal.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/PasswordRevealModal.js +94 -0
- package/dist/components/DataClubAIHubAdmin/PasswordRevealModal.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/ResetPasswordModal.d.ts +37 -0
- package/dist/components/DataClubAIHubAdmin/ResetPasswordModal.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/ResetPasswordModal.js +44 -0
- package/dist/components/DataClubAIHubAdmin/ResetPasswordModal.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessageEditorModal.d.ts +56 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessageEditorModal.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessageEditorModal.js +158 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessageEditorModal.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessagesPage.d.ts +29 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessagesPage.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessagesPage.js +183 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessagesPage.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/SessionsOverviewPage.d.ts +38 -0
- package/dist/components/DataClubAIHubAdmin/SessionsOverviewPage.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/SessionsOverviewPage.js +294 -0
- package/dist/components/DataClubAIHubAdmin/SessionsOverviewPage.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/SettingsPage.d.ts +36 -0
- package/dist/components/DataClubAIHubAdmin/SettingsPage.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/SettingsPage.js +373 -0
- package/dist/components/DataClubAIHubAdmin/SettingsPage.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/UsersPage.d.ts +47 -0
- package/dist/components/DataClubAIHubAdmin/UsersPage.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/UsersPage.js +233 -0
- package/dist/components/DataClubAIHubAdmin/UsersPage.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/index.d.ts +87 -0
- package/dist/components/DataClubAIHubAdmin/index.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/index.js +137 -0
- package/dist/components/DataClubAIHubAdmin/index.js.map +1 -0
- package/dist/components/DataClubAIHubLogin/index.d.ts +113 -0
- package/dist/components/DataClubAIHubLogin/index.d.ts.map +1 -0
- package/dist/components/DataClubAIHubLogin/index.js +123 -0
- package/dist/components/DataClubAIHubLogin/index.js.map +1 -0
- package/dist/components/EffortControl/index.d.ts +57 -0
- package/dist/components/EffortControl/index.d.ts.map +1 -0
- package/dist/components/EffortControl/index.js +84 -0
- package/dist/components/EffortControl/index.js.map +1 -0
- package/dist/components/Layout/index.d.ts +63 -0
- package/dist/components/Layout/index.d.ts.map +1 -0
- package/dist/components/Layout/index.js +45 -0
- package/dist/components/Layout/index.js.map +1 -0
- package/dist/components/MainColumn/index.d.ts +69 -0
- package/dist/components/MainColumn/index.d.ts.map +1 -0
- package/dist/components/MainColumn/index.js +47 -0
- package/dist/components/MainColumn/index.js.map +1 -0
- package/dist/components/MarkdownRenderer/index.d.ts +66 -0
- package/dist/components/MarkdownRenderer/index.d.ts.map +1 -0
- package/dist/components/MarkdownRenderer/index.js +153 -0
- package/dist/components/MarkdownRenderer/index.js.map +1 -0
- package/dist/components/MessageInput/index.d.ts +85 -0
- package/dist/components/MessageInput/index.d.ts.map +1 -0
- package/dist/components/MessageInput/index.js +139 -0
- package/dist/components/MessageInput/index.js.map +1 -0
- package/dist/components/MessageList/index.d.ts +156 -0
- package/dist/components/MessageList/index.d.ts.map +1 -0
- package/dist/components/MessageList/index.js +352 -0
- package/dist/components/MessageList/index.js.map +1 -0
- package/dist/components/ReasoningSelector/index.d.ts +77 -0
- package/dist/components/ReasoningSelector/index.d.ts.map +1 -0
- package/dist/components/ReasoningSelector/index.js +156 -0
- package/dist/components/ReasoningSelector/index.js.map +1 -0
- package/dist/components/ReasoningView/index.d.ts +94 -0
- package/dist/components/ReasoningView/index.d.ts.map +1 -0
- package/dist/components/ReasoningView/index.js +83 -0
- package/dist/components/ReasoningView/index.js.map +1 -0
- package/dist/components/ScrollToPresentButton/index.d.ts +54 -0
- package/dist/components/ScrollToPresentButton/index.d.ts.map +1 -0
- package/dist/components/ScrollToPresentButton/index.js +44 -0
- package/dist/components/ScrollToPresentButton/index.js.map +1 -0
- package/dist/components/SessionsPanel/SessionTitleModal.d.ts +79 -0
- package/dist/components/SessionsPanel/SessionTitleModal.d.ts.map +1 -0
- package/dist/components/SessionsPanel/SessionTitleModal.js +102 -0
- package/dist/components/SessionsPanel/SessionTitleModal.js.map +1 -0
- package/dist/components/SessionsPanel/index.d.ts +100 -0
- package/dist/components/SessionsPanel/index.d.ts.map +1 -0
- package/dist/components/SessionsPanel/index.js +176 -0
- package/dist/components/SessionsPanel/index.js.map +1 -0
- package/dist/components/SystemNotice/index.d.ts +66 -0
- package/dist/components/SystemNotice/index.d.ts.map +1 -0
- package/dist/components/SystemNotice/index.js +81 -0
- package/dist/components/SystemNotice/index.js.map +1 -0
- package/dist/components/ThemeSwitcher/index.d.ts +66 -0
- package/dist/components/ThemeSwitcher/index.d.ts.map +1 -0
- package/dist/components/ThemeSwitcher/index.js +73 -0
- package/dist/components/ThemeSwitcher/index.js.map +1 -0
- package/dist/components/ToolCallView/formatContent.d.ts +36 -0
- package/dist/components/ToolCallView/formatContent.d.ts.map +1 -0
- package/dist/components/ToolCallView/formatContent.js +53 -0
- package/dist/components/ToolCallView/formatContent.js.map +1 -0
- package/dist/components/ToolCallView/index.d.ts +120 -0
- package/dist/components/ToolCallView/index.d.ts.map +1 -0
- package/dist/components/ToolCallView/index.js +104 -0
- package/dist/components/ToolCallView/index.js.map +1 -0
- package/dist/components/TpmBanner/index.d.ts +53 -0
- package/dist/components/TpmBanner/index.d.ts.map +1 -0
- package/dist/components/TpmBanner/index.js +116 -0
- package/dist/components/TpmBanner/index.js.map +1 -0
- package/dist/components/TurnStatusIndicator/index.d.ts +77 -0
- package/dist/components/TurnStatusIndicator/index.d.ts.map +1 -0
- package/dist/components/TurnStatusIndicator/index.js +122 -0
- package/dist/components/TurnStatusIndicator/index.js.map +1 -0
- package/dist/components/internal/PasswordInput.d.ts +62 -0
- package/dist/components/internal/PasswordInput.d.ts.map +1 -0
- package/dist/components/internal/PasswordInput.js +42 -0
- package/dist/components/internal/PasswordInput.js.map +1 -0
- package/dist/context/AIHubContext.d.ts +220 -0
- package/dist/context/AIHubContext.d.ts.map +1 -0
- package/dist/context/AIHubContext.js +19 -0
- package/dist/context/AIHubContext.js.map +1 -0
- package/dist/context/AIHubProvider.d.ts +75 -0
- package/dist/context/AIHubProvider.d.ts.map +1 -0
- package/dist/context/AIHubProvider.js +954 -0
- package/dist/context/AIHubProvider.js.map +1 -0
- package/dist/context/index.d.ts +9 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +9 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/theme.d.ts +43 -0
- package/dist/context/theme.d.ts.map +1 -0
- package/dist/context/theme.js +70 -0
- package/dist/context/theme.js.map +1 -0
- package/dist/context/useAIHub.d.ts +104 -0
- package/dist/context/useAIHub.d.ts.map +1 -0
- package/dist/context/useAIHub.js +63 -0
- package/dist/context/useAIHub.js.map +1 -0
- package/dist/context/useAIHubAuth.d.ts +44 -0
- package/dist/context/useAIHubAuth.d.ts.map +1 -0
- package/dist/context/useAIHubAuth.js +35 -0
- package/dist/context/useAIHubAuth.js.map +1 -0
- package/dist/index.d.ts +76 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/primitives/index.d.ts +99 -0
- package/dist/primitives/index.d.ts.map +1 -0
- package/dist/primitives/index.js +97 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/state/affordances.d.ts +182 -0
- package/dist/state/affordances.d.ts.map +1 -0
- package/dist/state/affordances.js +189 -0
- package/dist/state/affordances.js.map +1 -0
- package/dist/state/stateReducer.d.ts +72 -0
- package/dist/state/stateReducer.d.ts.map +1 -0
- package/dist/state/stateReducer.js +122 -0
- package/dist/state/stateReducer.js.map +1 -0
- package/dist/stories/EffortControl.stories.d.ts +14 -0
- package/dist/stories/EffortControl.stories.d.ts.map +1 -0
- package/dist/stories/EffortControl.stories.js +43 -0
- package/dist/stories/EffortControl.stories.js.map +1 -0
- package/dist/stories/MarkdownRenderer.stories.d.ts +25 -0
- package/dist/stories/MarkdownRenderer.stories.d.ts.map +1 -0
- package/dist/stories/MarkdownRenderer.stories.js +178 -0
- package/dist/stories/MarkdownRenderer.stories.js.map +1 -0
- package/dist/stories/MessageBubble.stories.d.ts +21 -0
- package/dist/stories/MessageBubble.stories.d.ts.map +1 -0
- package/dist/stories/MessageBubble.stories.js +59 -0
- package/dist/stories/MessageBubble.stories.js.map +1 -0
- package/dist/stories/ReasoningView.stories.d.ts +18 -0
- package/dist/stories/ReasoningView.stories.d.ts.map +1 -0
- package/dist/stories/ReasoningView.stories.js +62 -0
- package/dist/stories/ReasoningView.stories.js.map +1 -0
- package/dist/stories/ScrollToPresentButton.stories.d.ts +18 -0
- package/dist/stories/ScrollToPresentButton.stories.d.ts.map +1 -0
- package/dist/stories/ScrollToPresentButton.stories.js +34 -0
- package/dist/stories/ScrollToPresentButton.stories.js.map +1 -0
- package/dist/stories/SystemNotice.stories.d.ts +17 -0
- package/dist/stories/SystemNotice.stories.d.ts.map +1 -0
- package/dist/stories/SystemNotice.stories.js +42 -0
- package/dist/stories/SystemNotice.stories.js.map +1 -0
- package/dist/stories/ThemeSwitcher.stories.d.ts +15 -0
- package/dist/stories/ThemeSwitcher.stories.d.ts.map +1 -0
- package/dist/stories/ThemeSwitcher.stories.js +35 -0
- package/dist/stories/ThemeSwitcher.stories.js.map +1 -0
- package/dist/stories/ToolCallView.stories.d.ts +20 -0
- package/dist/stories/ToolCallView.stories.d.ts.map +1 -0
- package/dist/stories/ToolCallView.stories.js +65 -0
- package/dist/stories/ToolCallView.stories.js.map +1 -0
- package/dist/stories/TpmBanner.stories.d.ts +24 -0
- package/dist/stories/TpmBanner.stories.d.ts.map +1 -0
- package/dist/stories/TpmBanner.stories.js +63 -0
- package/dist/stories/TpmBanner.stories.js.map +1 -0
- package/dist/stories/TurnStatusIndicator.stories.d.ts +25 -0
- package/dist/stories/TurnStatusIndicator.stories.d.ts.map +1 -0
- package/dist/stories/TurnStatusIndicator.stories.js +56 -0
- package/dist/stories/TurnStatusIndicator.stories.js.map +1 -0
- package/dist/stories/_mockProvider.d.ts +44 -0
- package/dist/stories/_mockProvider.d.ts.map +1 -0
- package/dist/stories/_mockProvider.js +84 -0
- package/dist/stories/_mockProvider.js.map +1 -0
- package/dist/types.d.ts +787 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/dist/webcomponent/defineWebComponent.d.ts +106 -0
- package/dist/webcomponent/defineWebComponent.d.ts.map +1 -0
- package/dist/webcomponent/defineWebComponent.js +126 -0
- package/dist/webcomponent/defineWebComponent.js.map +1 -0
- package/dist/webcomponent/index.d.ts +7 -0
- package/dist/webcomponent/index.d.ts.map +1 -0
- package/dist/webcomponent/index.js +7 -0
- package/dist/webcomponent/index.js.map +1 -0
- package/package.json +63 -0
- package/src/__lint-canary__/step1-lint-canary.ts.disabled +28 -0
- package/src/auth/passwordPolicy.ts +75 -0
- package/src/auth/texts.ts +1294 -0
- package/src/client/AIHubClient.ts +1718 -0
- package/src/client/index.ts +30 -0
- package/src/client/sseParser.ts +168 -0
- package/src/client/tokenStorage.ts +131 -0
- package/src/components/AgentsPicker/index.tsx +147 -0
- package/src/components/AuthGate/index.tsx +132 -0
- package/src/components/CacheBadge/index.tsx +245 -0
- package/src/components/ChangePassword/index.tsx +375 -0
- package/src/components/ChatShell/ShellHeader.tsx +80 -0
- package/src/components/ChatShell/UserMenu.tsx +196 -0
- package/src/components/ChatShell/index.tsx +307 -0
- package/src/components/DataClubAIHub/index.tsx +300 -0
- package/src/components/DataClubAIHubAdmin/AgentEditorModal.tsx +505 -0
- package/src/components/DataClubAIHubAdmin/AgentsPage.tsx +342 -0
- package/src/components/DataClubAIHubAdmin/CreateUserModal.tsx +214 -0
- package/src/components/DataClubAIHubAdmin/PasswordRevealModal.tsx +204 -0
- package/src/components/DataClubAIHubAdmin/ResetPasswordModal.tsx +122 -0
- package/src/components/DataClubAIHubAdmin/RotatingMessageEditorModal.tsx +408 -0
- package/src/components/DataClubAIHubAdmin/RotatingMessagesPage.tsx +373 -0
- package/src/components/DataClubAIHubAdmin/SessionsOverviewPage.tsx +639 -0
- package/src/components/DataClubAIHubAdmin/SettingsPage.tsx +979 -0
- package/src/components/DataClubAIHubAdmin/UsersPage.tsx +495 -0
- package/src/components/DataClubAIHubAdmin/index.tsx +277 -0
- package/src/components/DataClubAIHubLogin/index.tsx +282 -0
- package/src/components/EffortControl/index.tsx +138 -0
- package/src/components/Layout/index.tsx +92 -0
- package/src/components/MainColumn/index.tsx +131 -0
- package/src/components/MarkdownRenderer/index.tsx +256 -0
- package/src/components/MessageInput/index.tsx +283 -0
- package/src/components/MessageList/index.tsx +753 -0
- package/src/components/ReasoningSelector/index.tsx +268 -0
- package/src/components/ReasoningView/index.tsx +183 -0
- package/src/components/ScrollToPresentButton/index.tsx +85 -0
- package/src/components/SessionsPanel/SessionTitleModal.tsx +256 -0
- package/src/components/SessionsPanel/index.tsx +406 -0
- package/src/components/SystemNotice/index.tsx +151 -0
- package/src/components/ThemeSwitcher/index.tsx +136 -0
- package/src/components/ToolCallView/formatContent.ts +50 -0
- package/src/components/ToolCallView/index.tsx +274 -0
- package/src/components/TpmBanner/index.tsx +172 -0
- package/src/components/TurnStatusIndicator/index.tsx +203 -0
- package/src/components/internal/PasswordInput.tsx +145 -0
- package/src/context/AIHubContext.ts +249 -0
- package/src/context/AIHubProvider.tsx +1084 -0
- package/src/context/index.ts +9 -0
- package/src/context/theme.ts +76 -0
- package/src/context/useAIHub.ts +151 -0
- package/src/context/useAIHubAuth.ts +65 -0
- package/src/index.ts +275 -0
- package/src/primitives/index.ts +101 -0
- package/src/state/affordances.ts +321 -0
- package/src/state/stateReducer.ts +131 -0
- package/src/stories/EffortControl.stories.tsx +63 -0
- package/src/stories/MarkdownRenderer.stories.tsx +201 -0
- package/src/stories/MessageBubble.stories.tsx +101 -0
- package/src/stories/ReasoningView.stories.tsx +81 -0
- package/src/stories/ScrollToPresentButton.stories.tsx +52 -0
- package/src/stories/SystemNotice.stories.tsx +59 -0
- package/src/stories/ThemeSwitcher.stories.tsx +55 -0
- package/src/stories/ToolCallView.stories.tsx +95 -0
- package/src/stories/TpmBanner.stories.tsx +93 -0
- package/src/stories/TurnStatusIndicator.stories.tsx +86 -0
- package/src/stories/_mockProvider.tsx +116 -0
- package/src/styles/CLASSES.md +356 -0
- package/src/styles/default.css +2937 -0
- package/src/types.ts +867 -0
- package/src/webcomponent/defineWebComponent.tsx +193 -0
- package/src/webcomponent/index.ts +11 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stories for `<TpmBanner />` — TPM-recovery banner with live
|
|
3
|
+
* countdown.
|
|
4
|
+
*
|
|
5
|
+
* The banner reads state from the provider; we mount each story under
|
|
6
|
+
* `<MockProvider>` and feed a fixed `nowProvider` so the countdown
|
|
7
|
+
* shows a deterministic value (60s / 5s) regardless of wall-clock.
|
|
8
|
+
*
|
|
9
|
+
* The "exhausted" path is gated on `lastTurnError` containing the word
|
|
10
|
+
* "rate" (case-insensitive) per the component's matching rule.
|
|
11
|
+
*
|
|
12
|
+
* @see SPECIFICATIONS.md §6.5 — TPM recovery
|
|
13
|
+
* @see SPECIFICATIONS.md §10.4 — phase-bound predicates
|
|
14
|
+
*/
|
|
15
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
16
|
+
|
|
17
|
+
import { TpmBanner } from "../components/TpmBanner/index.js";
|
|
18
|
+
|
|
19
|
+
import { MockProvider, type MockProviderOpts } from "./_mockProvider.js";
|
|
20
|
+
|
|
21
|
+
/** Fixed "now" so the countdown is deterministic in the iframe. */
|
|
22
|
+
const NOW_MS = Date.parse("2026-05-13T12:00:00Z");
|
|
23
|
+
const RETRY_AT_60S = new Date(NOW_MS + 60_000).toISOString();
|
|
24
|
+
const RETRY_AT_5S = new Date(NOW_MS + 5_000).toISOString();
|
|
25
|
+
|
|
26
|
+
function withProvider(opts: MockProviderOpts) {
|
|
27
|
+
return (Story: () => React.ReactNode) => (
|
|
28
|
+
<MockProvider opts={opts}>
|
|
29
|
+
<Story />
|
|
30
|
+
</MockProvider>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const meta: Meta<typeof TpmBanner> = {
|
|
35
|
+
title: "Affordances/TpmBanner",
|
|
36
|
+
component: TpmBanner,
|
|
37
|
+
parameters: {
|
|
38
|
+
docs: {
|
|
39
|
+
description: {
|
|
40
|
+
component:
|
|
41
|
+
"Specialization of SystemNotice that renders during waiting_provider, briefly flashes Resumed on recovery, and surfaces a Retry action on tpm_exhausted. Renders nothing otherwise.",
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
export default meta;
|
|
47
|
+
|
|
48
|
+
type Story = StoryObj<typeof TpmBanner>;
|
|
49
|
+
|
|
50
|
+
export const WaitingPhase60sLeft: Story = {
|
|
51
|
+
decorators: [
|
|
52
|
+
withProvider({
|
|
53
|
+
status: "running",
|
|
54
|
+
phase: "waiting_provider",
|
|
55
|
+
tpm_retry_at: RETRY_AT_60S,
|
|
56
|
+
}),
|
|
57
|
+
],
|
|
58
|
+
args: { nowProvider: () => NOW_MS },
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const WaitingPhase5sLeft: Story = {
|
|
62
|
+
decorators: [
|
|
63
|
+
withProvider({
|
|
64
|
+
status: "running",
|
|
65
|
+
phase: "waiting_provider",
|
|
66
|
+
tpm_retry_at: RETRY_AT_5S,
|
|
67
|
+
}),
|
|
68
|
+
],
|
|
69
|
+
args: { nowProvider: () => NOW_MS },
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const Exhausted: Story = {
|
|
73
|
+
decorators: [
|
|
74
|
+
withProvider({
|
|
75
|
+
status: "failed",
|
|
76
|
+
phase: null,
|
|
77
|
+
lastTurnError: "Provider rate limit exhausted after 5 retries.",
|
|
78
|
+
}),
|
|
79
|
+
],
|
|
80
|
+
args: { onRetry: () => undefined },
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const NoBannerInIdleState: Story = {
|
|
84
|
+
decorators: [withProvider({ status: "idle", phase: null })],
|
|
85
|
+
parameters: {
|
|
86
|
+
docs: {
|
|
87
|
+
description: {
|
|
88
|
+
story:
|
|
89
|
+
"When neither waiting_provider nor an exhausted error is present, the banner self-suppresses and renders nothing.",
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stories for `<TurnStatusIndicator />` — one per row of the §10.4
|
|
3
|
+
* turn-status table.
|
|
4
|
+
*
|
|
5
|
+
* Each story passes an explicit `state` prop AND wraps the component
|
|
6
|
+
* in `<MockProvider>`, because `TurnStatusIndicator` reads the context
|
|
7
|
+
* for the default but accepts the override prop for stories + tests.
|
|
8
|
+
*
|
|
9
|
+
* @see SPECIFICATIONS.md §10.4 — turn-status indicator table
|
|
10
|
+
*/
|
|
11
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
12
|
+
|
|
13
|
+
import { TurnStatusIndicator } from "../components/TurnStatusIndicator/index.js";
|
|
14
|
+
import type { AIHubState, RunningPhase, TurnStatus } from "../types.js";
|
|
15
|
+
|
|
16
|
+
import { MockProvider } from "./_mockProvider.js";
|
|
17
|
+
|
|
18
|
+
function makeState(status: TurnStatus, phase: RunningPhase | null): AIHubState {
|
|
19
|
+
return {
|
|
20
|
+
status,
|
|
21
|
+
phase,
|
|
22
|
+
last_seq: -1,
|
|
23
|
+
turn_id: status !== "idle" ? "t-mock" : null,
|
|
24
|
+
session_id: null,
|
|
25
|
+
tpm_retry_at: null,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const meta: Meta<typeof TurnStatusIndicator> = {
|
|
30
|
+
title: "Affordances/TurnStatusIndicator",
|
|
31
|
+
component: TurnStatusIndicator,
|
|
32
|
+
decorators: [
|
|
33
|
+
(Story) => (
|
|
34
|
+
<MockProvider>
|
|
35
|
+
<Story />
|
|
36
|
+
</MockProvider>
|
|
37
|
+
),
|
|
38
|
+
],
|
|
39
|
+
parameters: {
|
|
40
|
+
docs: {
|
|
41
|
+
description: {
|
|
42
|
+
component:
|
|
43
|
+
"Renders the active turn's (status, phase) as a colored dot + label. Pure function of state; see SPECIFICATIONS.md §10.4.",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
export default meta;
|
|
49
|
+
|
|
50
|
+
type Story = StoryObj<typeof TurnStatusIndicator>;
|
|
51
|
+
|
|
52
|
+
export const Idle: Story = {
|
|
53
|
+
args: { state: makeState("idle", null) },
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const Running_ModelText: Story = {
|
|
57
|
+
args: { state: makeState("running", "model_text") },
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const Running_ModelReasoning: Story = {
|
|
61
|
+
args: { state: makeState("running", "model_reasoning") },
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const Running_ModelToolInput: Story = {
|
|
65
|
+
args: { state: makeState("running", "model_tool_input") },
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const Running_ToolExecuting: Story = {
|
|
69
|
+
args: { state: makeState("running", "tool_executing") },
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const Running_WaitingProvider: Story = {
|
|
73
|
+
args: { state: makeState("running", "waiting_provider") },
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const Done: Story = {
|
|
77
|
+
args: { state: makeState("done", null) },
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const Cancelled: Story = {
|
|
81
|
+
args: { state: makeState("cancelled", null) },
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const Failed: Story = {
|
|
85
|
+
args: { state: makeState("failed", null) },
|
|
86
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal `<AIHubProvider>` stand-in for Storybook.
|
|
3
|
+
*
|
|
4
|
+
* The real provider boots a network client and a pile of `useEffect`s
|
|
5
|
+
* that fetch `/auth/me`, `/feature-toggles`, etc. — none of which work
|
|
6
|
+
* in the Storybook iframe. The stories only need the context shape
|
|
7
|
+
* (status / phase / theme / lastTurnError / messages / …) so we mount
|
|
8
|
+
* a hand-built `AIHubContextValue` directly.
|
|
9
|
+
*
|
|
10
|
+
* Mirrors the pattern in `__tests__/components/Affordances.test.tsx` so
|
|
11
|
+
* tests + stories share the same minimal context.
|
|
12
|
+
*
|
|
13
|
+
* @see packages/ai-hub/__tests__/components/Affordances.test.tsx
|
|
14
|
+
*/
|
|
15
|
+
import { type ReactNode } from "react";
|
|
16
|
+
|
|
17
|
+
import { aiHubContext, type AIHubContextValue } from "../context/AIHubContext.js";
|
|
18
|
+
import type { AIHubEffort } from "../client/AIHubClient.js";
|
|
19
|
+
import type {
|
|
20
|
+
AIHubFeatureToggles,
|
|
21
|
+
AIHubMessage,
|
|
22
|
+
AIHubState,
|
|
23
|
+
RunningPhase,
|
|
24
|
+
TurnStatus,
|
|
25
|
+
} from "../types.js";
|
|
26
|
+
|
|
27
|
+
/** Options accepted by `<MockProvider>`. Everything is optional. */
|
|
28
|
+
export interface MockProviderOpts {
|
|
29
|
+
status?: TurnStatus;
|
|
30
|
+
phase?: RunningPhase | null;
|
|
31
|
+
tpm_retry_at?: string | null;
|
|
32
|
+
lastTurnError?: string | null;
|
|
33
|
+
themeSwitcherEnabled?: boolean;
|
|
34
|
+
theme?: "light" | "dark";
|
|
35
|
+
effort?: AIHubEffort;
|
|
36
|
+
messages?: AIHubMessage[];
|
|
37
|
+
streamingAssistantText?: string | null;
|
|
38
|
+
streamingReasoning?: string | null;
|
|
39
|
+
streamingToolCalls?: AIHubContextValue["streamingToolCalls"];
|
|
40
|
+
activeSessionId?: string | null;
|
|
41
|
+
featureToggles?: AIHubFeatureToggles | null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function noopAsync(): Promise<void> {
|
|
45
|
+
return Promise.resolve();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function makeState(opts: MockProviderOpts): AIHubState {
|
|
49
|
+
return {
|
|
50
|
+
status: opts.status ?? "idle",
|
|
51
|
+
phase: opts.phase ?? null,
|
|
52
|
+
last_seq: -1,
|
|
53
|
+
turn_id: opts.status && opts.status !== "idle" ? "t-mock" : null,
|
|
54
|
+
session_id: opts.activeSessionId ?? null,
|
|
55
|
+
tpm_retry_at: opts.tpm_retry_at ?? null,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Wraps `children` in a fully-populated `aiHubContext.Provider`. Every
|
|
61
|
+
* function-shaped field is a no-op; non-functional fields fall back to
|
|
62
|
+
* sensible defaults. The story decides which ones matter via `opts`.
|
|
63
|
+
*/
|
|
64
|
+
export function MockProvider(props: {
|
|
65
|
+
opts?: MockProviderOpts;
|
|
66
|
+
children: ReactNode;
|
|
67
|
+
}): ReactNode {
|
|
68
|
+
const opts = props.opts ?? {};
|
|
69
|
+
const value: AIHubContextValue = {
|
|
70
|
+
client: {} as never,
|
|
71
|
+
user: null,
|
|
72
|
+
role: null,
|
|
73
|
+
deployment: null,
|
|
74
|
+
mustChangePassword: false,
|
|
75
|
+
hydrating: false,
|
|
76
|
+
login: (() => Promise.resolve({} as never)) as never,
|
|
77
|
+
logout: noopAsync,
|
|
78
|
+
changePassword: noopAsync,
|
|
79
|
+
state: makeState(opts),
|
|
80
|
+
effort: opts.effort ?? "medium",
|
|
81
|
+
setEffort: () => undefined,
|
|
82
|
+
theme: opts.theme ?? "light",
|
|
83
|
+
setTheme: noopAsync,
|
|
84
|
+
themeSwitcherEnabled: opts.themeSwitcherEnabled ?? true,
|
|
85
|
+
agents: [],
|
|
86
|
+
agentsLoading: false,
|
|
87
|
+
refreshAgents: noopAsync,
|
|
88
|
+
activeAgentId: null,
|
|
89
|
+
setActiveAgent: () => undefined,
|
|
90
|
+
sessions: [],
|
|
91
|
+
sessionsLoading: false,
|
|
92
|
+
refreshSessions: noopAsync,
|
|
93
|
+
includeArchivedSessions: false,
|
|
94
|
+
setIncludeArchivedSessions: () => undefined,
|
|
95
|
+
activeSessionId: opts.activeSessionId ?? null,
|
|
96
|
+
setActiveSession: () => undefined,
|
|
97
|
+
createSession: (() => Promise.resolve({} as never)) as never,
|
|
98
|
+
patchSession: (() => Promise.resolve({} as never)) as never,
|
|
99
|
+
messages: opts.messages ?? [],
|
|
100
|
+
messagesLoading: false,
|
|
101
|
+
streamingAssistantText: opts.streamingAssistantText ?? null,
|
|
102
|
+
streamingReasoning: opts.streamingReasoning ?? null,
|
|
103
|
+
streamingToolCalls: opts.streamingToolCalls ?? [],
|
|
104
|
+
sendMessage: noopAsync,
|
|
105
|
+
stop: noopAsync,
|
|
106
|
+
isStoppingTurn: false,
|
|
107
|
+
pendingDraft: null,
|
|
108
|
+
consumePendingDraft: () => null,
|
|
109
|
+
lastTurnError: opts.lastTurnError ?? null,
|
|
110
|
+
featureToggles: opts.featureToggles ?? null,
|
|
111
|
+
refreshFeatureToggles: noopAsync,
|
|
112
|
+
};
|
|
113
|
+
return (
|
|
114
|
+
<aiHubContext.Provider value={value}>{props.children}</aiHubContext.Provider>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
# `@data-club/ai-hub` — BEM class contract
|
|
2
|
+
|
|
3
|
+
> The class names below are the **public contract** every per-customer
|
|
4
|
+
> wrapper relies on for theming. Step 7 ships the root + theme scaffolding;
|
|
5
|
+
> Steps 8–12 fill in the per-component classes as those components land.
|
|
6
|
+
> When a new component class is introduced, append it here so wrappers
|
|
7
|
+
> have one place to grep.
|
|
8
|
+
|
|
9
|
+
## Root + theming
|
|
10
|
+
|
|
11
|
+
| Class | What it scopes | When it's set |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| `.data-club-ai-hub` | Every chat-side component (login, change-password, chat, primitives). Applied to the wrapper `<div>` rendered by `<AIHubProvider>`. | Always present once the provider mounts. |
|
|
14
|
+
| `.data-club-ai-hub-admin` | Every admin-side component (`<DataClubAIHubAdmin />` and sub-pages). Applied to the admin root. | Only when an admin component is rendered. |
|
|
15
|
+
| `.data-club-ai-hub-mount` | Internal: the `<div>` `defineWebComponent` mounts the React root onto. Wrappers should not target this; theme via `.data-club-ai-hub` instead. | Inside Web Component shadow roots. |
|
|
16
|
+
|
|
17
|
+
### Theme attribute
|
|
18
|
+
|
|
19
|
+
The active theme is selected by `data-theme="light"` or `data-theme="dark"`
|
|
20
|
+
on the provider's root `<div>`. CSS custom properties redefine themselves
|
|
21
|
+
under the dark-theme attribute selector — components reference the custom
|
|
22
|
+
properties only, never the attribute directly.
|
|
23
|
+
|
|
24
|
+
```css
|
|
25
|
+
.data-club-ai-hub { --dc-aih-bg: #ffffff; }
|
|
26
|
+
.data-club-ai-hub[data-theme="dark"] { --dc-aih-bg: #0f1117; }
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## CSS custom properties (theming tokens)
|
|
30
|
+
|
|
31
|
+
Per-customer wrappers override these to brand the UI; they don't fork the
|
|
32
|
+
stylesheet.
|
|
33
|
+
|
|
34
|
+
### Surface
|
|
35
|
+
|
|
36
|
+
| Variable | Default (light) | Default (dark) |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `--dc-aih-bg` | `#ffffff` | `#0f1117` |
|
|
39
|
+
| `--dc-aih-bg-elevated` | `#f8f9fb` | `#181b23` |
|
|
40
|
+
| `--dc-aih-bg-overlay` | `rgba(255,255,255,0.92)` | `rgba(15,17,23,0.9)` |
|
|
41
|
+
| `--dc-aih-border` | `#e2e5ec` | `#2a2e38` |
|
|
42
|
+
| `--dc-aih-border-strong` | `#c8ccd6` | `#3c4250` |
|
|
43
|
+
|
|
44
|
+
### Text
|
|
45
|
+
|
|
46
|
+
| Variable | Default (light) | Default (dark) |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `--dc-aih-fg` | `#1a1d24` | `#e8eaef` |
|
|
49
|
+
| `--dc-aih-fg-muted` | `#5c6473` | `#a1a7b3` |
|
|
50
|
+
| `--dc-aih-fg-subtle` | `#8a909c` | `#6c727e` |
|
|
51
|
+
| `--dc-aih-fg-inverse` | `#ffffff` | `#0f1117` |
|
|
52
|
+
|
|
53
|
+
### Accent (per-customer override target)
|
|
54
|
+
|
|
55
|
+
| Variable | Default (light) | Default (dark) |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| `--dc-aih-accent` | `#4a6cf7` | `#7a96ff` |
|
|
58
|
+
| `--dc-aih-accent-hover` | `#3b58d8` | `#95acff` |
|
|
59
|
+
| `--dc-aih-accent-fg` | `#ffffff` | `#0f1117` |
|
|
60
|
+
|
|
61
|
+
### State + focus
|
|
62
|
+
|
|
63
|
+
| Variable | Default (light) | Default (dark) |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| `--dc-aih-success` | `#2f9e44` | `#51cf66` |
|
|
66
|
+
| `--dc-aih-warning` | `#d97706` | `#f59f00` |
|
|
67
|
+
| `--dc-aih-danger` | `#d92d20` | `#ff6b6b` |
|
|
68
|
+
| `--dc-aih-focus-ring` | `rgba(74,108,247,0.4)` | `rgba(122,150,255,0.4)` |
|
|
69
|
+
|
|
70
|
+
### Scrollbar (themable, applies to every scrollable region in the chat / admin scope)
|
|
71
|
+
|
|
72
|
+
| Variable | Default (light) | Default (dark) |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| `--dc-aih-scrollbar-thumb` | `#c8ccd6` | `#3c4250` |
|
|
75
|
+
| `--dc-aih-scrollbar-thumb-hover` | `#a1a7b3` | `#4a5160` |
|
|
76
|
+
| `--dc-aih-scrollbar-track` | `transparent` | `transparent` |
|
|
77
|
+
|
|
78
|
+
The library styles every scrollable element inside `.data-club-ai-hub` / `.data-club-ai-hub-admin` via Firefox's `scrollbar-color` + WebKit's `::-webkit-scrollbar*` selectors. Override these properties on the root to match brand chrome.
|
|
79
|
+
|
|
80
|
+
### Markdown renderer (assistant bubble bodies)
|
|
81
|
+
|
|
82
|
+
| Variable | Default |
|
|
83
|
+
|---|---|
|
|
84
|
+
| `--dc-aih-markdown-code-bg` | `color-mix(in srgb, var(--dc-aih-fg) 6%, transparent)` |
|
|
85
|
+
| `--dc-aih-markdown-code-fg` | `var(--dc-aih-fg)` |
|
|
86
|
+
| `--dc-aih-markdown-quote-border` | `var(--dc-aih-border-strong)` |
|
|
87
|
+
| `--dc-aih-markdown-table-border` | `var(--dc-aih-border)` |
|
|
88
|
+
| `--dc-aih-markdown-table-header-bg` | `var(--dc-aih-bg-elevated)` |
|
|
89
|
+
| `--dc-aih-markdown-link-fg` | `var(--dc-aih-accent)` |
|
|
90
|
+
|
|
91
|
+
These theme the markdown elements emitted by `<MarkdownRenderer />` (GFM tables, code blocks, blockquotes, links). User bubbles automatically remap them to legible variants against the accent background. KaTeX math styling is governed by `katex/dist/katex.min.css`, which consumers import alongside `default.css` — see [`react/markdown-rendering.md`](../../../docs/react/markdown-rendering.md).
|
|
92
|
+
|
|
93
|
+
### Sizing / type / motion
|
|
94
|
+
|
|
95
|
+
| Variable | Default |
|
|
96
|
+
|---|---|
|
|
97
|
+
| `--dc-aih-radius-sm` / `-md` / `-lg` | `4px` / `8px` / `12px` |
|
|
98
|
+
| `--dc-aih-space-xs..xl` | `4px` / `8px` / `16px` / `24px` / `32px` |
|
|
99
|
+
| `--dc-aih-font-sans` | `system-ui, -apple-system, "Segoe UI", Roboto, sans-serif` |
|
|
100
|
+
| `--dc-aih-font-mono` | `ui-monospace, "SF Mono", Menlo, Consolas, monospace` |
|
|
101
|
+
| `--dc-aih-font-size-sm` / `-md` / `-lg` | `0.875rem` / `1rem` / `1.125rem` |
|
|
102
|
+
| `--dc-aih-transition` | `150ms ease-in-out` |
|
|
103
|
+
|
|
104
|
+
## Component classes
|
|
105
|
+
|
|
106
|
+
Filled in by Steps 8–12 as each component lands. Convention: BEM,
|
|
107
|
+
kebab-case, with `__` separating block and element and `--` separating
|
|
108
|
+
block and modifier.
|
|
109
|
+
|
|
110
|
+
### Login screen (Step 8 — `ui-sketches/01-login.md`)
|
|
111
|
+
|
|
112
|
+
| Class | Where it's applied |
|
|
113
|
+
|---|---|
|
|
114
|
+
| `data-club-ai-hub__login` | Outer wrapper that centers the card. |
|
|
115
|
+
| `data-club-ai-hub__login-card` | The card itself. |
|
|
116
|
+
| `data-club-ai-hub__login-card__title` | Gradient product-name title. |
|
|
117
|
+
| `data-club-ai-hub__login-card__error` | Server-error banner above the form. |
|
|
118
|
+
| `data-club-ai-hub__login-card__form` | The `<form>`. |
|
|
119
|
+
| `data-club-ai-hub__login-card__field` | Each label + input group. |
|
|
120
|
+
| `data-club-ai-hub__login-card__label` | `<label>` element. |
|
|
121
|
+
| `data-club-ai-hub__login-card__input` | Plain inputs (username). |
|
|
122
|
+
| `data-club-ai-hub__login-card__input--password` | Modifier added to the password `<input>` so themers can target it directly. |
|
|
123
|
+
| `data-club-ai-hub__login-card__password` | Wrapper around the password input + toggle (relative positioning). |
|
|
124
|
+
| `data-club-ai-hub__login-card__toggle` | Show/hide eye-icon button. |
|
|
125
|
+
| `data-club-ai-hub__login-card__submit` | Submit button. |
|
|
126
|
+
| `data-club-ai-hub__login-card__forgot` | The static "contact your administrator" note. |
|
|
127
|
+
|
|
128
|
+
### Change-password screen (Step 8 — `ui-sketches/02-change-password.md`)
|
|
129
|
+
|
|
130
|
+
| Class | Where it's applied |
|
|
131
|
+
|---|---|
|
|
132
|
+
| `data-club-ai-hub__change-password` | Outer wrapper. |
|
|
133
|
+
| `data-club-ai-hub__change-password-card` | The card itself. |
|
|
134
|
+
| `data-club-ai-hub__change-password-card__title` | Gradient title. |
|
|
135
|
+
| `data-club-ai-hub__change-password-card__intro` | Intro message (forced variant only). |
|
|
136
|
+
| `data-club-ai-hub__change-password-card__error` | Server-error banner. |
|
|
137
|
+
| `data-club-ai-hub__change-password-card__form` | The `<form>`. |
|
|
138
|
+
| `data-club-ai-hub__change-password-card__field` | Each label + input group. |
|
|
139
|
+
| `data-club-ai-hub__change-password-card__label` | `<label>` element. |
|
|
140
|
+
| `data-club-ai-hub__change-password-card__input` | Password inputs. |
|
|
141
|
+
| `data-club-ai-hub__change-password-card__input--password` | Modifier added to all three password inputs. |
|
|
142
|
+
| `data-club-ai-hub__change-password-card__field-error` | Inline client-side validation error under the confirm field. |
|
|
143
|
+
| `data-club-ai-hub__change-password-card__password` | Wrapper around each password input + toggle. |
|
|
144
|
+
| `data-club-ai-hub__change-password-card__toggle` | Per-field show/hide eye button. |
|
|
145
|
+
| `data-club-ai-hub__change-password-card__submit` | Submit button. |
|
|
146
|
+
| `data-club-ai-hub__change-password-card__cancel` | Cancel button (voluntary variant only). |
|
|
147
|
+
|
|
148
|
+
### Shared
|
|
149
|
+
|
|
150
|
+
| Class | Where it's applied |
|
|
151
|
+
|---|---|
|
|
152
|
+
| `data-club-ai-hub__spinner` | Inline submit-button spinner (login + change-password). |
|
|
153
|
+
| `data-club-ai-hub__chat-placeholder` | Step-8 chat placeholder (now unused — the real chat replaces it from Step 9). |
|
|
154
|
+
| `data-club-ai-hub__chat-placeholder__body` | Inner block of the placeholder. |
|
|
155
|
+
|
|
156
|
+
### Shell — Step 9 (`ui-sketches/00-shell.md`)
|
|
157
|
+
|
|
158
|
+
| Class | Where it's applied |
|
|
159
|
+
|---|---|
|
|
160
|
+
| `data-club-ai-hub__shell` | Outer authenticated shell — flex column wrapping header + main + footer. |
|
|
161
|
+
| `data-club-ai-hub__shell-header` | Sticky top bar (logo on the left, user menu on the right). |
|
|
162
|
+
| `data-club-ai-hub__shell-header-left` | Wrapper-owned slot. When unset, the default gradient logo lives inside. |
|
|
163
|
+
| `data-club-ai-hub__shell-header-logo` | Default gradient text logo derived from `productName`. |
|
|
164
|
+
| `data-club-ai-hub__shell-header-right` | Library-owned right-side region of the shell header (user menu + Step-10 affordances). |
|
|
165
|
+
| `data-club-ai-hub__shell-main` | The body between header and footer. |
|
|
166
|
+
| `data-club-ai-hub__shell-footer` | Wrapper-owned slot; only rendered when `customShellFooter` is set. |
|
|
167
|
+
|
|
168
|
+
### User menu — Step 9 (`ui-sketches/00-shell.md`)
|
|
169
|
+
|
|
170
|
+
| Class | Where it's applied |
|
|
171
|
+
|---|---|
|
|
172
|
+
| `data-club-ai-hub__user-menu` | Wrapper holding the button + dropdown. |
|
|
173
|
+
| `data-club-ai-hub__user-menu__button` | The avatar + username button. |
|
|
174
|
+
| `data-club-ai-hub__user-menu__avatar` | Circular avatar inside the button. |
|
|
175
|
+
| `data-club-ai-hub__user-menu__username` | Username text next to the avatar. |
|
|
176
|
+
| `data-club-ai-hub__user-menu__dropdown` | Dropdown rendered when the button is open. |
|
|
177
|
+
| `data-club-ai-hub__user-menu__header` | Header row inside the dropdown (username + role). |
|
|
178
|
+
| `data-club-ai-hub__user-menu__username-large` | Larger username text in the dropdown header. |
|
|
179
|
+
| `data-club-ai-hub__user-menu__role` | Role label below the username. |
|
|
180
|
+
| `data-club-ai-hub__user-menu__item` | A menu item (Sign out today; Theme / Admin / Letta ADE in Steps 10–11). |
|
|
181
|
+
|
|
182
|
+
### Agents picker — Step 9 (`ui-sketches/03-chat.md`)
|
|
183
|
+
|
|
184
|
+
| Class | Where it's applied |
|
|
185
|
+
|---|---|
|
|
186
|
+
| `data-club-ai-hub__agents-picker` | Outer wrapper. |
|
|
187
|
+
| `data-club-ai-hub__agents-picker__heading` | Page heading. |
|
|
188
|
+
| `data-club-ai-hub__agents-picker__loading` | Loading state line. |
|
|
189
|
+
| `data-club-ai-hub__agents-picker__error` | Error state banner. |
|
|
190
|
+
| `data-club-ai-hub__agents-picker__empty` | Empty-state container (zero agents). |
|
|
191
|
+
| `data-club-ai-hub__agents-picker__empty-heading` | Empty-state heading. |
|
|
192
|
+
| `data-club-ai-hub__agents-picker__empty-body` | Empty-state body text. |
|
|
193
|
+
| `data-club-ai-hub__agents-picker__grid` | Card grid container. |
|
|
194
|
+
| `data-club-ai-hub__agent-card` | A single clickable agent tile. |
|
|
195
|
+
| `data-club-ai-hub__agent-card__name` | Agent display name. |
|
|
196
|
+
| `data-club-ai-hub__agent-card__subtitle` | Per-caller session-count subtitle. |
|
|
197
|
+
|
|
198
|
+
### Chat layout — Step 9 (`ui-sketches/03-chat.md`)
|
|
199
|
+
|
|
200
|
+
| Class | Where it's applied |
|
|
201
|
+
|---|---|
|
|
202
|
+
| `data-club-ai-hub__layout` | Flex container of sessions panel + main column. |
|
|
203
|
+
| `data-club-ai-hub__layout--panel-left` | Modifier when the panel is on the left (default). |
|
|
204
|
+
| `data-club-ai-hub__layout--panel-right` | Modifier when the panel is on the right. |
|
|
205
|
+
| `data-club-ai-hub__sessions-panel` | The sessions sidebar. |
|
|
206
|
+
| `data-club-ai-hub__sessions-panel--collapsed` | Collapsed state (thin reveal strip). |
|
|
207
|
+
| `data-club-ai-hub__sessions-panel__custom-header` | Slot wrapper at the top of the panel. |
|
|
208
|
+
| `data-club-ai-hub__sessions-panel__new-button` | "+ New chat" button. |
|
|
209
|
+
| `data-club-ai-hub__sessions-panel__reveal` | Reveal-strip button shown in collapsed state. |
|
|
210
|
+
| `data-club-ai-hub__sessions-panel__collapse-toggle` | Collapse button shown in expanded state. |
|
|
211
|
+
| `data-club-ai-hub__sessions-panel__list` | Scrollable list region. |
|
|
212
|
+
| `data-club-ai-hub__sessions-panel__empty` | Empty-state line ("No chats yet."). |
|
|
213
|
+
| `data-club-ai-hub__sessions-panel__loading` | Loading state line. |
|
|
214
|
+
| `data-club-ai-hub__sessions-panel__item` | Session row. |
|
|
215
|
+
| `data-club-ai-hub__sessions-panel__item--active` | Modifier for the currently-selected row. |
|
|
216
|
+
| `data-club-ai-hub__sessions-panel__item--archived` | Modifier for archived rows (only visible with the filter on). |
|
|
217
|
+
| `data-club-ai-hub__sessions-panel__item-title` | Row title button (opens the session). |
|
|
218
|
+
| `data-club-ai-hub__sessions-panel__item-meta` | Row meta (relative timestamp). |
|
|
219
|
+
| `data-club-ai-hub__sessions-panel__item-actions` | Hover-revealed action group on the right of the row. |
|
|
220
|
+
| `data-club-ai-hub__sessions-panel__action-button` | Edit / archive / unarchive button. |
|
|
221
|
+
| `data-club-ai-hub__sessions-panel__footer` | Footer wrapping the archived filter + custom slot. |
|
|
222
|
+
| `data-club-ai-hub__sessions-panel__archived-toggle` | Show / hide archived filter. |
|
|
223
|
+
| `data-club-ai-hub__sessions-panel__custom-footer` | Slot wrapper at the bottom of the panel. |
|
|
224
|
+
|
|
225
|
+
### Main column + message list + input — Step 9 (`ui-sketches/03-chat.md`)
|
|
226
|
+
|
|
227
|
+
| Class | Where it's applied |
|
|
228
|
+
|---|---|
|
|
229
|
+
| `data-club-ai-hub__main-column` | Right side of the layout (header + body). |
|
|
230
|
+
| `data-club-ai-hub__main-column__body` | Body region under the chat header. |
|
|
231
|
+
| `data-club-ai-hub__chat-header` | The strip above the messages with back-link + agent name. |
|
|
232
|
+
| `data-club-ai-hub__chat-header__back` | `[← Agents]` back-to-picker link. |
|
|
233
|
+
| `data-club-ai-hub__chat-header__title` | Agent display-name text. |
|
|
234
|
+
| `data-club-ai-hub__chat-header__extras` | Slot for `customHeaderContent`. |
|
|
235
|
+
| `data-club-ai-hub__messages` | Scroll container for the message list. |
|
|
236
|
+
| `data-club-ai-hub__messages__inner` | Inner block; `aria-live="polite"` is on this element. |
|
|
237
|
+
| `data-club-ai-hub__messages__empty` | Empty-session placeholder body. |
|
|
238
|
+
| `data-club-ai-hub__messages__no-session` | Placeholder when no session is selected. |
|
|
239
|
+
| `data-club-ai-hub__messages__loading` | Loading state line. |
|
|
240
|
+
| `data-club-ai-hub__messages__error` | Turn-failure banner — surfaced when the send loop ended with an `error` event or no assistant output. Step 10 pairs this with a Retry button. |
|
|
241
|
+
| `data-club-ai-hub__message-bubble` | Per-bubble wrapper. |
|
|
242
|
+
| `data-club-ai-hub__message-bubble--user` | User variant — right-aligned. |
|
|
243
|
+
| `data-club-ai-hub__message-bubble--assistant` | Assistant variant — left-aligned. |
|
|
244
|
+
| `data-club-ai-hub__message-bubble__role` | Role label inside the bubble. |
|
|
245
|
+
| `data-club-ai-hub__message-bubble__body` | Text body inside the bubble. |
|
|
246
|
+
| `data-club-ai-hub__message-bubble__caret` | Thin blinking caret at the end of the streaming-assistant bubble. Step 10 replaces it with the proper §10.4 streaming-dots affordance; until then it's the typing signal. Width / color / animation are themable. |
|
|
247
|
+
| `data-club-ai-hub__input-area` | Outer wrapper for the input. |
|
|
248
|
+
| `data-club-ai-hub__input-area__form` | The `<form>` element. |
|
|
249
|
+
| `data-club-ai-hub__input-area__row` | Row holding the textarea + send/stop button. |
|
|
250
|
+
| `data-club-ai-hub__input-area__textarea` | The auto-growing textarea. |
|
|
251
|
+
| `data-club-ai-hub__input-area__send` | Send button. |
|
|
252
|
+
| `data-club-ai-hub__input-area__stop` | Stop button (replaces send while streaming). |
|
|
253
|
+
| `data-club-ai-hub__input-area__toolbar` | Toolbar slot under the textarea (Step 10 fills it with the effort dropdown). |
|
|
254
|
+
|
|
255
|
+
### Generic modal — Step 9 (used by SessionTitleModal; reused by Step 11/12 admin modals)
|
|
256
|
+
|
|
257
|
+
| Class | Where it's applied |
|
|
258
|
+
|---|---|
|
|
259
|
+
| `data-club-ai-hub__modal-overlay` | Backdrop covering the page. |
|
|
260
|
+
| `data-club-ai-hub__modal` | The modal card. |
|
|
261
|
+
| `data-club-ai-hub__modal__title` | Modal heading. |
|
|
262
|
+
| `data-club-ai-hub__modal__form` | `<form>` inside the modal. |
|
|
263
|
+
| `data-club-ai-hub__modal__field` | Field group (label + input). |
|
|
264
|
+
| `data-club-ai-hub__modal__label` | Field label. |
|
|
265
|
+
| `data-club-ai-hub__modal__input` | Text input. |
|
|
266
|
+
| `data-club-ai-hub__modal__field-error` | Inline validation / server error. |
|
|
267
|
+
| `data-club-ai-hub__modal__actions` | Button row at the bottom. |
|
|
268
|
+
| `data-club-ai-hub__modal__cancel` | Cancel button. |
|
|
269
|
+
| `data-club-ai-hub__modal__confirm` | Primary confirm button (Create / Save). |
|
|
270
|
+
|
|
271
|
+
### Affordance classes — Step 10
|
|
272
|
+
|
|
273
|
+
| Class | Where it's applied |
|
|
274
|
+
|---|---|
|
|
275
|
+
| `data-club-ai-hub__message-bubble--system` | System-role bubble — centered, italic. Gated by `system_messages_visible` (§8.4). |
|
|
276
|
+
| `data-club-ai-hub__message-bubble--tool` | Tool-role bubble — monospace, dashed border. Gated by `system_messages_visible`. |
|
|
277
|
+
| `data-club-ai-hub__message-bubble--failed` | The latest assistant bubble of a failed turn — danger border, retry button visible. |
|
|
278
|
+
| `data-club-ai-hub__message-bubble--cancelled` | The latest assistant bubble of a cancelled turn — reduced opacity, "Stopped" stamp visible. |
|
|
279
|
+
| `data-club-ai-hub__message-bubble__actions` | Action row inside the bubble (retry, cancelled stamp, custom action slot). |
|
|
280
|
+
| `data-club-ai-hub__message-bubble__retry` | Retry button on `--failed` bubbles. |
|
|
281
|
+
| `data-club-ai-hub__message-bubble__cancelled-stamp` | "Stopped" stamp on `--cancelled` bubbles. |
|
|
282
|
+
| `data-club-ai-hub__turn-status` | Turn-status indicator (chat header). |
|
|
283
|
+
| `data-club-ai-hub__turn-status__dot` | The dot. |
|
|
284
|
+
| `data-club-ai-hub__turn-status__dot--idle` | Dot variant — gray static. |
|
|
285
|
+
| `data-club-ai-hub__turn-status__dot--running` | Dot variant — accent pulsing. |
|
|
286
|
+
| `data-club-ai-hub__turn-status__dot--warning` | Dot variant — yellow pulsing (rate-limit wait). |
|
|
287
|
+
| `data-club-ai-hub__turn-status__dot--error` | Dot variant — red static. |
|
|
288
|
+
| `data-club-ai-hub__turn-status__dot--pulse` | Modifier added when motion is allowed. |
|
|
289
|
+
| `data-club-ai-hub__turn-status__label` | Label next to the dot. |
|
|
290
|
+
| `data-club-ai-hub__theme-switcher` | Theme toggle button. |
|
|
291
|
+
| `data-club-ai-hub__theme-switcher--light` | Modifier when light is active. |
|
|
292
|
+
| `data-club-ai-hub__theme-switcher--dark` | Modifier when dark is active. |
|
|
293
|
+
| `data-club-ai-hub__theme-switcher__icon` | Sun/moon icon span. |
|
|
294
|
+
| `data-club-ai-hub__theme-switcher__label` | Label text next to the icon. |
|
|
295
|
+
| `data-club-ai-hub__system-notice` | Generic banner — base. |
|
|
296
|
+
| `data-club-ai-hub__system-notice--tpm-wait` | TPM-wait variant (warning yellow). |
|
|
297
|
+
| `data-club-ai-hub__system-notice--resumed` | Recovery-resumed variant (success green). |
|
|
298
|
+
| `data-club-ai-hub__system-notice--error` | Non-recoverable variant (danger red). |
|
|
299
|
+
| `data-club-ai-hub__system-notice__icon` | Icon glyph. |
|
|
300
|
+
| `data-club-ai-hub__system-notice__body` | Body text. |
|
|
301
|
+
| `data-club-ai-hub__system-notice__action` | Optional inline action button. |
|
|
302
|
+
| `data-club-ai-hub__reasoning-block` | Reasoning-view wrapper. |
|
|
303
|
+
| `data-club-ai-hub__reasoning-block--collapsed` / `--expanded` | Expansion state. |
|
|
304
|
+
| `data-club-ai-hub__reasoning-block__header` | Header row. |
|
|
305
|
+
| `data-club-ai-hub__reasoning-block__title` | Title text. |
|
|
306
|
+
| `data-club-ai-hub__reasoning-block__toggle` | Expand/collapse toggle. |
|
|
307
|
+
| `data-club-ai-hub__reasoning-block__body` | Body content (monospace, scrollable). |
|
|
308
|
+
| `data-club-ai-hub__tool-call-card` | Tool-call card wrapper. |
|
|
309
|
+
| `data-club-ai-hub__tool-call-card--running` / `--done` / `--error` | Status modifiers. |
|
|
310
|
+
| `data-club-ai-hub__tool-call-card--collapsed` / `--expanded` | Expansion state. |
|
|
311
|
+
| `data-club-ai-hub__tool-call-card__header` | Header row. |
|
|
312
|
+
| `data-club-ai-hub__tool-call-card__tool-name` | Tool name + 🔧 emoji. |
|
|
313
|
+
| `data-club-ai-hub__tool-call-card__status` | Status text. |
|
|
314
|
+
| `data-club-ai-hub__tool-call-card__duration` | Duration text (monospace). |
|
|
315
|
+
| `data-club-ai-hub__tool-call-card__toggle` | Expand/collapse toggle. |
|
|
316
|
+
| `data-club-ai-hub__tool-call-card__body` | Body — input + output/error. |
|
|
317
|
+
| `data-club-ai-hub__tool-call-card__body--error` | Body modifier — error variant. |
|
|
318
|
+
| `data-club-ai-hub__tool-call-card__input-section` / `__output-section` | Sections. |
|
|
319
|
+
| `data-club-ai-hub__tool-call-card__section-label` | Section heading. |
|
|
320
|
+
| `data-club-ai-hub__tool-call-card__section-content` | `<pre>` content. |
|
|
321
|
+
| `data-club-ai-hub__messages-wrapper` | Non-scrolling wrapper around the scroll container; lets the scroll-to-present button stay anchored to the visible chat area instead of sliding off with the content. |
|
|
322
|
+
| `data-club-ai-hub__scroll-to-present-button` | Floating "↓ Jump to latest" button — bottom-center of the wrapper. |
|
|
323
|
+
| `data-club-ai-hub__effort-control` | Effort dropdown wrapper (`<label>`). |
|
|
324
|
+
| `data-club-ai-hub__effort-control__label` | "Effort" label. |
|
|
325
|
+
| `data-club-ai-hub__effort-control__select` | The `<select>` element. |
|
|
326
|
+
| `data-club-ai-hub__markdown` | Wrapper around an assistant bubble's rendered markdown. |
|
|
327
|
+
| `data-club-ai-hub__markdown__p` | Paragraph. |
|
|
328
|
+
| `data-club-ai-hub__markdown__heading` (+ `--1` … `--6`) | Headings + level modifier. |
|
|
329
|
+
| `data-club-ai-hub__markdown__ul` / `__ol` / `__li` | Lists + items. |
|
|
330
|
+
| `data-club-ai-hub__markdown__a` | Markdown link (`target="_blank" rel="noopener noreferrer"`). |
|
|
331
|
+
| `data-club-ai-hub__markdown__blockquote` | Blockquote. |
|
|
332
|
+
| `data-club-ai-hub__markdown__hr` | Horizontal rule. |
|
|
333
|
+
| `data-club-ai-hub__markdown__code--inline` | Inline `<code>` (no language). |
|
|
334
|
+
| `data-club-ai-hub__markdown__pre` | Fenced-code `<pre>` (inner `<code>` keeps `language-<lang>` for highlighters). |
|
|
335
|
+
| `data-club-ai-hub__markdown__table-wrapper` | Horizontal-scroll `<div>` around tables. |
|
|
336
|
+
| `data-club-ai-hub__markdown__table` / `__thead` / `__tbody` / `__tr` / `__th` / `__td` | Table parts. |
|
|
337
|
+
|
|
338
|
+
## Customizing in a wrapper
|
|
339
|
+
|
|
340
|
+
The library accepts a `className` prop on every visible component plus a
|
|
341
|
+
`classNames` partial map for individual sub-elements (§7.3). For
|
|
342
|
+
theme-only customizations, prefer overriding the custom properties on
|
|
343
|
+
`.data-club-ai-hub` in the wrapper's `theme.css`:
|
|
344
|
+
|
|
345
|
+
```css
|
|
346
|
+
/* per-customer wrapper theme.css */
|
|
347
|
+
bankxyz-chat::part(root),
|
|
348
|
+
.data-club-ai-hub {
|
|
349
|
+
--dc-aih-accent: #d70000;
|
|
350
|
+
--dc-aih-radius-md: 14px;
|
|
351
|
+
--dc-aih-font-sans: "Brand Sans", system-ui, sans-serif;
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
For layout-level changes ("move the input above the messages"), drop to
|
|
356
|
+
**Tier 3** and compose the `AIHub.*` primitives directly.
|