@chaaskit/client 0.1.0 → 0.1.2
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/LICENSE +21 -0
- package/dist/lib/index.js +1023 -160
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/routes/AcceptInviteRoute.js +1 -1
- package/dist/lib/routes/AcceptInviteRoute.js.map +1 -1
- package/dist/lib/routes/AdminDashboardRoute.js +1 -1
- package/dist/lib/routes/AdminDashboardRoute.js.map +1 -1
- package/dist/lib/routes/AdminPromoCodesRoute.js +19 -0
- package/dist/lib/routes/AdminPromoCodesRoute.js.map +1 -0
- package/dist/lib/routes/AdminTeamRoute.js +1 -1
- package/dist/lib/routes/AdminTeamRoute.js.map +1 -1
- package/dist/lib/routes/AdminTeamsRoute.js +1 -1
- package/dist/lib/routes/AdminTeamsRoute.js.map +1 -1
- package/dist/lib/routes/AdminUsersRoute.js +1 -1
- package/dist/lib/routes/AdminUsersRoute.js.map +1 -1
- package/dist/lib/routes/AdminWaitlistRoute.js +19 -0
- package/dist/lib/routes/AdminWaitlistRoute.js.map +1 -0
- package/dist/lib/routes/ApiKeysRoute.js +1 -1
- package/dist/lib/routes/ApiKeysRoute.js.map +1 -1
- package/dist/lib/routes/AutomationsRoute.js +1 -1
- package/dist/lib/routes/AutomationsRoute.js.map +1 -1
- package/dist/lib/routes/ChatRoute.js +1 -1
- package/dist/lib/routes/ChatRoute.js.map +1 -1
- package/dist/lib/routes/DocumentsRoute.js +1 -1
- package/dist/lib/routes/DocumentsRoute.js.map +1 -1
- package/dist/lib/routes/OAuthConsentRoute.js +1 -1
- package/dist/lib/routes/OAuthConsentRoute.js.map +1 -1
- package/dist/lib/routes/PricingRoute.js +1 -1
- package/dist/lib/routes/PricingRoute.js.map +1 -1
- package/dist/lib/routes/PrivacyRoute.js +1 -1
- package/dist/lib/routes/PrivacyRoute.js.map +1 -1
- package/dist/lib/routes/TeamSettingsRoute.js +1 -1
- package/dist/lib/routes/TeamSettingsRoute.js.map +1 -1
- package/dist/lib/routes/TermsRoute.js +1 -1
- package/dist/lib/routes/TermsRoute.js.map +1 -1
- package/dist/lib/routes/VerifyEmailRoute.js +1 -1
- package/dist/lib/routes/VerifyEmailRoute.js.map +1 -1
- package/dist/lib/routes.js +47 -37
- package/dist/lib/routes.js.map +1 -1
- package/dist/lib/ssr-utils.js +64 -1
- package/dist/lib/ssr-utils.js.map +1 -1
- package/dist/lib/ssr.js +23 -0
- package/dist/lib/ssr.js.map +1 -1
- package/dist/lib/styles.css +58 -62
- package/dist/lib/useExtensions-B5nX_8XD.js.map +1 -1
- package/package.json +25 -12
- package/src/components/MessageItem.tsx +35 -4
- package/src/components/MessageList.tsx +51 -5
- package/src/components/OAuthAppsSection.tsx +1 -1
- package/src/components/Sidebar.tsx +1 -3
- package/src/components/ToolCallDisplay.tsx +102 -11
- package/src/components/tool-renderers/DocumentListRenderer.tsx +44 -0
- package/src/components/tool-renderers/DocumentReadRenderer.tsx +33 -0
- package/src/components/tool-renderers/DocumentSaveRenderer.tsx +32 -0
- package/src/components/tool-renderers/DocumentSearchRenderer.tsx +33 -0
- package/src/components/tool-renderers/index.ts +36 -0
- package/src/components/tool-renderers/utils.ts +7 -0
- package/src/contexts/AuthContext.tsx +16 -6
- package/src/contexts/ConfigContext.tsx +60 -28
- package/src/contexts/ThemeContext.tsx +39 -68
- package/src/extensions/registry.ts +2 -1
- package/src/hooks/__tests__/basePath.test.ts +42 -0
- package/src/index.tsx +11 -2
- package/src/pages/AdminDashboardPage.tsx +15 -1
- package/src/pages/AdminPromoCodesPage.tsx +378 -0
- package/src/pages/AdminTeamPage.tsx +29 -1
- package/src/pages/AdminTeamsPage.tsx +15 -1
- package/src/pages/AdminUsersPage.tsx +15 -1
- package/src/pages/AdminWaitlistPage.tsx +156 -0
- package/src/pages/RegisterPage.tsx +91 -9
- package/src/routes/AcceptInviteRoute.tsx +1 -1
- package/src/routes/AdminDashboardRoute.tsx +1 -1
- package/src/routes/AdminPromoCodesRoute.tsx +24 -0
- package/src/routes/AdminTeamRoute.tsx +1 -1
- package/src/routes/AdminTeamsRoute.tsx +1 -1
- package/src/routes/AdminUsersRoute.tsx +1 -1
- package/src/routes/AdminWaitlistRoute.tsx +24 -0
- package/src/routes/ApiKeysRoute.tsx +1 -1
- package/src/routes/AutomationsRoute.tsx +1 -1
- package/src/routes/ChatRoute.tsx +2 -1
- package/src/routes/DocumentsRoute.tsx +1 -1
- package/src/routes/OAuthConsentRoute.tsx +1 -1
- package/src/routes/PricingRoute.tsx +1 -1
- package/src/routes/PrivacyRoute.tsx +1 -1
- package/src/routes/TeamSettingsRoute.tsx +1 -1
- package/src/routes/TermsRoute.tsx +1 -1
- package/src/routes/VerifyEmailRoute.tsx +1 -1
- package/src/routes/index.ts +2 -0
- package/src/ssr-utils.tsx +100 -1
- package/src/ssr.ts +59 -0
- package/src/stores/chatStore.ts +5 -0
- package/src/styles/index.css +16 -63
- package/src/tailwind-preset.js +360 -0
- package/dist/favicon.svg +0 -11
- package/dist/index.html +0 -17
- package/dist/logo.svg +0 -12
package/src/ssr-utils.tsx
CHANGED
|
@@ -19,11 +19,109 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import { lazy, Suspense, type ComponentType, type LazyExoticComponent } from 'react';
|
|
22
|
+
import type { AppConfig } from '@chaaskit/shared';
|
|
22
23
|
import { ClientOnly } from './components/ClientOnly';
|
|
23
24
|
import { ChatLoadingSkeleton, SimpleLoadingSkeleton } from './components/LoadingSkeletons';
|
|
24
25
|
|
|
25
26
|
export { ClientOnly, ChatLoadingSkeleton, SimpleLoadingSkeleton };
|
|
26
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Props for ConfigScript component.
|
|
30
|
+
*/
|
|
31
|
+
interface ConfigScriptProps {
|
|
32
|
+
/**
|
|
33
|
+
* The app config to inject into the page.
|
|
34
|
+
* This should come from the SSR loader.
|
|
35
|
+
*/
|
|
36
|
+
config: AppConfig;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Injects the app config into the page as a script tag.
|
|
41
|
+
* Place this in the <head> of your root layout to make the config
|
|
42
|
+
* available immediately on page load, avoiding flash of default values.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```tsx
|
|
46
|
+
* // app/root.tsx
|
|
47
|
+
* import { ConfigScript } from '@chaaskit/client/ssr-utils';
|
|
48
|
+
* import { config } from '../config/app.config';
|
|
49
|
+
*
|
|
50
|
+
* export default function Root() {
|
|
51
|
+
* return (
|
|
52
|
+
* <html>
|
|
53
|
+
* <head>
|
|
54
|
+
* <ConfigScript config={config} />
|
|
55
|
+
* </head>
|
|
56
|
+
* <body>...</body>
|
|
57
|
+
* </html>
|
|
58
|
+
* );
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export function ConfigScript({ config }: ConfigScriptProps) {
|
|
63
|
+
// Only include the UI-related config to avoid exposing sensitive data
|
|
64
|
+
const safeConfig = {
|
|
65
|
+
app: config.app,
|
|
66
|
+
ui: config.ui,
|
|
67
|
+
theming: config.theming,
|
|
68
|
+
auth: {
|
|
69
|
+
methods: config.auth?.methods,
|
|
70
|
+
allowUnauthenticated: config.auth?.allowUnauthenticated,
|
|
71
|
+
magicLink: config.auth?.magicLink,
|
|
72
|
+
emailVerification: config.auth?.emailVerification,
|
|
73
|
+
gating: config.auth?.gating,
|
|
74
|
+
},
|
|
75
|
+
payments: {
|
|
76
|
+
enabled: config.payments?.enabled,
|
|
77
|
+
provider: config.payments?.provider,
|
|
78
|
+
},
|
|
79
|
+
legal: config.legal,
|
|
80
|
+
sharing: config.sharing,
|
|
81
|
+
teams: config.teams,
|
|
82
|
+
projects: config.projects,
|
|
83
|
+
documents: config.documents ? {
|
|
84
|
+
enabled: config.documents.enabled,
|
|
85
|
+
maxFileSizeMB: config.documents.maxFileSizeMB,
|
|
86
|
+
hybridThreshold: config.documents.hybridThreshold,
|
|
87
|
+
acceptedTypes: config.documents.acceptedTypes,
|
|
88
|
+
} : undefined,
|
|
89
|
+
api: {
|
|
90
|
+
enabled: config.api?.enabled,
|
|
91
|
+
},
|
|
92
|
+
promptTemplates: config.promptTemplates ? {
|
|
93
|
+
enabled: config.promptTemplates.enabled,
|
|
94
|
+
allowUserTemplates: config.promptTemplates.allowUserTemplates,
|
|
95
|
+
} : undefined,
|
|
96
|
+
scheduledPrompts: config.scheduledPrompts ? {
|
|
97
|
+
enabled: config.scheduledPrompts.enabled,
|
|
98
|
+
featureName: config.scheduledPrompts.featureName,
|
|
99
|
+
allowUserPrompts: config.scheduledPrompts.allowUserPrompts,
|
|
100
|
+
allowTeamPrompts: config.scheduledPrompts.allowTeamPrompts,
|
|
101
|
+
defaultTimezone: config.scheduledPrompts.defaultTimezone,
|
|
102
|
+
defaultMaxUserPrompts: config.scheduledPrompts.defaultMaxUserPrompts,
|
|
103
|
+
defaultMaxTeamPrompts: config.scheduledPrompts.defaultMaxTeamPrompts,
|
|
104
|
+
} : undefined,
|
|
105
|
+
credits: config.credits ? {
|
|
106
|
+
enabled: config.credits.enabled,
|
|
107
|
+
expiryEnabled: config.credits.expiryEnabled,
|
|
108
|
+
promoEnabled: config.credits.promoEnabled,
|
|
109
|
+
} : undefined,
|
|
110
|
+
metering: config.metering ? {
|
|
111
|
+
enabled: config.metering.enabled,
|
|
112
|
+
recordPromptCompletion: config.metering.recordPromptCompletion,
|
|
113
|
+
} : undefined,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<script
|
|
118
|
+
dangerouslySetInnerHTML={{
|
|
119
|
+
__html: `window.__CHAASKIT_CONFIG__=${JSON.stringify(safeConfig)};`,
|
|
120
|
+
}}
|
|
121
|
+
/>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
27
125
|
/**
|
|
28
126
|
* Route configuration options
|
|
29
127
|
*/
|
|
@@ -61,7 +159,8 @@ export function createRoute(config: RouteConfig) {
|
|
|
61
159
|
}
|
|
62
160
|
|
|
63
161
|
function links() {
|
|
64
|
-
|
|
162
|
+
// CSS is bundled via app's Tailwind preset - no separate stylesheet needed
|
|
163
|
+
return [];
|
|
65
164
|
}
|
|
66
165
|
|
|
67
166
|
function RouteComponent() {
|
package/src/ssr.ts
CHANGED
|
@@ -109,6 +109,65 @@ export function getThemeVariables(config: AppConfig, theme: string): Record<stri
|
|
|
109
109
|
return vars;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Generates CSS for ALL themes using html[data-theme] selectors.
|
|
114
|
+
* This is the recommended way to include theme styles - it allows instant
|
|
115
|
+
* theme switching by just changing the data-theme attribute on <html>.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```tsx
|
|
119
|
+
* // app/root.tsx
|
|
120
|
+
* import { generateAllThemesCSS, baseStyles } from '@chaaskit/client/ssr';
|
|
121
|
+
*
|
|
122
|
+
* // Cache on server - only generate once
|
|
123
|
+
* let cachedCSS: string | null = null;
|
|
124
|
+
*
|
|
125
|
+
* export async function loader() {
|
|
126
|
+
* if (!cachedCSS) cachedCSS = generateAllThemesCSS(config);
|
|
127
|
+
* return { themeCSS: cachedCSS };
|
|
128
|
+
* }
|
|
129
|
+
*
|
|
130
|
+
* export default function Root() {
|
|
131
|
+
* const { themeCSS } = useLoaderData();
|
|
132
|
+
* return (
|
|
133
|
+
* <html data-theme="dark">
|
|
134
|
+
* <head>
|
|
135
|
+
* <style dangerouslySetInnerHTML={{ __html: themeCSS + baseStyles }} />
|
|
136
|
+
* </head>
|
|
137
|
+
* ...
|
|
138
|
+
* </html>
|
|
139
|
+
* );
|
|
140
|
+
* }
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
export function generateAllThemesCSS(config: AppConfig): string {
|
|
144
|
+
const themes = config.theming.themes;
|
|
145
|
+
let css = '';
|
|
146
|
+
|
|
147
|
+
for (const [themeName, themeConfig] of Object.entries(themes)) {
|
|
148
|
+
const cssVars = Object.entries(themeConfig.colors)
|
|
149
|
+
.map(([key, value]) => {
|
|
150
|
+
const cssKey = `--color-${key.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
|
|
151
|
+
return `${cssKey}: ${hexToRgb(value)};`;
|
|
152
|
+
})
|
|
153
|
+
.join('\n ');
|
|
154
|
+
|
|
155
|
+
css += `
|
|
156
|
+
html[data-theme="${themeName}"] {
|
|
157
|
+
${cssVars}
|
|
158
|
+
--font-sans: ${config.theming.fonts.sans};
|
|
159
|
+
--font-mono: ${config.theming.fonts.mono};
|
|
160
|
+
--radius-sm: ${config.theming.borderRadius.sm};
|
|
161
|
+
--radius-md: ${config.theming.borderRadius.md};
|
|
162
|
+
--radius-lg: ${config.theming.borderRadius.lg};
|
|
163
|
+
--radius-full: ${config.theming.borderRadius.full};
|
|
164
|
+
}
|
|
165
|
+
`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return css;
|
|
169
|
+
}
|
|
170
|
+
|
|
112
171
|
/**
|
|
113
172
|
* Base CSS styles for SSR pages.
|
|
114
173
|
* Include this in your HTML template for consistent styling.
|
package/src/stores/chatStore.ts
CHANGED
|
@@ -19,6 +19,7 @@ interface CompletedToolCall extends PendingToolCall {
|
|
|
19
19
|
result: MCPContent[];
|
|
20
20
|
isError?: boolean;
|
|
21
21
|
uiResource?: UIResource;
|
|
22
|
+
structuredContent?: Record<string, unknown>;
|
|
22
23
|
autoApproveReason?: AutoApproveReason;
|
|
23
24
|
}
|
|
24
25
|
|
|
@@ -324,6 +325,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
324
325
|
input?: Record<string, unknown>;
|
|
325
326
|
isError?: boolean;
|
|
326
327
|
uiResource?: UIResource;
|
|
328
|
+
structuredContent?: Record<string, unknown>;
|
|
327
329
|
// Tool confirmation fields
|
|
328
330
|
confirmationId?: string;
|
|
329
331
|
toolName?: string;
|
|
@@ -397,6 +399,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
397
399
|
result: (data.content as unknown as MCPContent[]) || [],
|
|
398
400
|
isError: data.isError,
|
|
399
401
|
uiResource: data.uiResource,
|
|
402
|
+
structuredContent: (data.structuredContent as Record<string, unknown> | undefined),
|
|
400
403
|
}
|
|
401
404
|
: {
|
|
402
405
|
// Fallback: create from tool_result event data (server now includes name/serverId/input)
|
|
@@ -407,6 +410,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
407
410
|
result: (data.content as unknown as MCPContent[]) || [],
|
|
408
411
|
isError: data.isError,
|
|
409
412
|
uiResource: data.uiResource,
|
|
413
|
+
structuredContent: (data.structuredContent as Record<string, unknown> | undefined),
|
|
410
414
|
};
|
|
411
415
|
|
|
412
416
|
return {
|
|
@@ -492,6 +496,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
492
496
|
content: tc.result,
|
|
493
497
|
isError: tc.isError,
|
|
494
498
|
uiResource: tc.uiResource,
|
|
499
|
+
structuredContent: tc.structuredContent,
|
|
495
500
|
}))
|
|
496
501
|
: undefined,
|
|
497
502
|
createdAt: new Date(),
|
package/src/styles/index.css
CHANGED
|
@@ -2,69 +2,22 @@
|
|
|
2
2
|
@tailwind components;
|
|
3
3
|
@tailwind utilities;
|
|
4
4
|
|
|
5
|
-
/*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
--color-input-border: 209 213 219;
|
|
22
|
-
|
|
23
|
-
--color-user-message-bg: 99 102 241;
|
|
24
|
-
--color-user-message-text: 255 255 255;
|
|
25
|
-
--color-assistant-message-bg: 243 244 246;
|
|
26
|
-
--color-assistant-message-text: 17 24 39;
|
|
27
|
-
|
|
28
|
-
--color-success: 16 185 129;
|
|
29
|
-
--color-warning: 245 158 11;
|
|
30
|
-
--color-error: 239 68 68;
|
|
31
|
-
|
|
32
|
-
--font-sans: 'Inter', system-ui, sans-serif;
|
|
33
|
-
--font-mono: 'JetBrains Mono', Menlo, monospace;
|
|
34
|
-
|
|
35
|
-
--radius-sm: 0.25rem;
|
|
36
|
-
--radius-md: 0.5rem;
|
|
37
|
-
--radius-lg: 0.75rem;
|
|
38
|
-
--radius-full: 9999px;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/* Dark theme */
|
|
42
|
-
[data-theme="dark"] {
|
|
43
|
-
--color-primary: 129 140 248;
|
|
44
|
-
--color-primary-hover: 165 180 252;
|
|
45
|
-
--color-secondary: 167 139 250;
|
|
46
|
-
|
|
47
|
-
--color-background: 17 24 39;
|
|
48
|
-
--color-background-secondary: 31 41 55;
|
|
49
|
-
--color-sidebar: 15 23 42;
|
|
50
|
-
|
|
51
|
-
--color-text-primary: 249 250 251;
|
|
52
|
-
--color-text-secondary: 209 213 219;
|
|
53
|
-
--color-text-muted: 107 114 128;
|
|
54
|
-
|
|
55
|
-
--color-border: 55 65 81;
|
|
56
|
-
--color-input-background: 31 41 55;
|
|
57
|
-
--color-input-border: 75 85 99;
|
|
58
|
-
|
|
59
|
-
--color-user-message-bg: 79 70 229;
|
|
60
|
-
--color-user-message-text: 255 255 255;
|
|
61
|
-
--color-assistant-message-bg: 31 41 55;
|
|
62
|
-
--color-assistant-message-text: 249 250 251;
|
|
63
|
-
|
|
64
|
-
--color-success: 52 211 153;
|
|
65
|
-
--color-warning: 251 191 36;
|
|
66
|
-
--color-error: 248 113 113;
|
|
67
|
-
}
|
|
5
|
+
/*
|
|
6
|
+
* Theme CSS variables are NOT defined here.
|
|
7
|
+
* The consuming app (chaaskit-app) is responsible for providing CSS variable values
|
|
8
|
+
* via inline styles on <html> from config/app.config.ts.
|
|
9
|
+
*
|
|
10
|
+
* Required variables:
|
|
11
|
+
* --color-primary, --color-primary-hover, --color-secondary
|
|
12
|
+
* --color-background, --color-background-secondary, --color-sidebar
|
|
13
|
+
* --color-text-primary, --color-text-secondary, --color-text-muted
|
|
14
|
+
* --color-border, --color-input-background, --color-input-border
|
|
15
|
+
* --color-user-message-bg, --color-user-message-text
|
|
16
|
+
* --color-assistant-message-bg, --color-assistant-message-text
|
|
17
|
+
* --color-success, --color-warning, --color-error
|
|
18
|
+
* --font-sans, --font-mono
|
|
19
|
+
* --radius-sm, --radius-md, --radius-lg, --radius-full
|
|
20
|
+
*/
|
|
68
21
|
|
|
69
22
|
/* Base styles */
|
|
70
23
|
html {
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import plugin from 'tailwindcss/plugin.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Converts a hex color to RGB values string (e.g., "#ff0000" -> "255 0 0")
|
|
5
|
+
*/
|
|
6
|
+
function hexToRgb(hex) {
|
|
7
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
8
|
+
if (!result) return '0 0 0';
|
|
9
|
+
return `${parseInt(result[1], 16)} ${parseInt(result[2], 16)} ${parseInt(result[3], 16)}`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Default ChaasKit themes.
|
|
14
|
+
* Apps can override these by passing their own themes to createChaaskitPreset().
|
|
15
|
+
*/
|
|
16
|
+
const defaultThemes = {
|
|
17
|
+
light: {
|
|
18
|
+
primary: '#6366f1',
|
|
19
|
+
primaryHover: '#4f46e5',
|
|
20
|
+
secondary: '#8b5cf6',
|
|
21
|
+
background: '#ffffff',
|
|
22
|
+
backgroundSecondary: '#f9fafb',
|
|
23
|
+
sidebar: '#f3f4f6',
|
|
24
|
+
textPrimary: '#111827',
|
|
25
|
+
textSecondary: '#6b7280',
|
|
26
|
+
textMuted: '#9ca3af',
|
|
27
|
+
border: '#e5e7eb',
|
|
28
|
+
inputBackground: '#ffffff',
|
|
29
|
+
inputBorder: '#d1d5db',
|
|
30
|
+
userMessageBg: '#6366f1',
|
|
31
|
+
userMessageText: '#ffffff',
|
|
32
|
+
assistantMessageBg: '#f3f4f6',
|
|
33
|
+
assistantMessageText: '#111827',
|
|
34
|
+
success: '#10b981',
|
|
35
|
+
warning: '#f59e0b',
|
|
36
|
+
error: '#ef4444',
|
|
37
|
+
},
|
|
38
|
+
dark: {
|
|
39
|
+
primary: '#818cf8',
|
|
40
|
+
primaryHover: '#a5b4fc',
|
|
41
|
+
secondary: '#a78bfa',
|
|
42
|
+
background: '#111827',
|
|
43
|
+
backgroundSecondary: '#1f2937',
|
|
44
|
+
sidebar: '#0f172a',
|
|
45
|
+
textPrimary: '#f9fafb',
|
|
46
|
+
textSecondary: '#d1d5db',
|
|
47
|
+
textMuted: '#6b7280',
|
|
48
|
+
border: '#374151',
|
|
49
|
+
inputBackground: '#1f2937',
|
|
50
|
+
inputBorder: '#4b5563',
|
|
51
|
+
userMessageBg: '#4f46e5',
|
|
52
|
+
userMessageText: '#ffffff',
|
|
53
|
+
assistantMessageBg: '#1f2937',
|
|
54
|
+
assistantMessageText: '#f9fafb',
|
|
55
|
+
success: '#34d399',
|
|
56
|
+
warning: '#fbbf24',
|
|
57
|
+
error: '#f87171',
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Default fonts and border radius.
|
|
63
|
+
*/
|
|
64
|
+
const defaultStyles = {
|
|
65
|
+
fonts: {
|
|
66
|
+
sans: "'Inter', system-ui, sans-serif",
|
|
67
|
+
mono: "'JetBrains Mono', Menlo, monospace",
|
|
68
|
+
},
|
|
69
|
+
borderRadius: {
|
|
70
|
+
sm: '0.25rem',
|
|
71
|
+
md: '0.5rem',
|
|
72
|
+
lg: '0.75rem',
|
|
73
|
+
full: '9999px',
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Creates a ChaasKit Tailwind preset with custom themes.
|
|
79
|
+
*
|
|
80
|
+
* @param {Object} options
|
|
81
|
+
* @param {Object} options.themes - Theme definitions (light, dark, etc.)
|
|
82
|
+
* @param {string} options.defaultTheme - Which theme to use for :root (default: 'light')
|
|
83
|
+
* @param {Object} options.fonts - Font family overrides
|
|
84
|
+
* @param {Object} options.borderRadius - Border radius overrides
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* // tailwind.config.ts
|
|
88
|
+
* import { createChaaskitPreset } from '@chaaskit/client/tailwind-preset';
|
|
89
|
+
*
|
|
90
|
+
* export default {
|
|
91
|
+
* presets: [
|
|
92
|
+
* createChaaskitPreset({
|
|
93
|
+
* themes: {
|
|
94
|
+
* light: { primary: '#dc2626', ... },
|
|
95
|
+
* dark: { primary: '#ef4444', ... },
|
|
96
|
+
* },
|
|
97
|
+
* defaultTheme: 'dark',
|
|
98
|
+
* }),
|
|
99
|
+
* ],
|
|
100
|
+
* };
|
|
101
|
+
*/
|
|
102
|
+
export function createChaaskitPreset(options = {}) {
|
|
103
|
+
const themes = options.themes || defaultThemes;
|
|
104
|
+
const defaultTheme = options.defaultTheme || 'light';
|
|
105
|
+
const fonts = { ...defaultStyles.fonts, ...options.fonts };
|
|
106
|
+
const borderRadius = { ...defaultStyles.borderRadius, ...options.borderRadius };
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Generate CSS-in-JS for all themes
|
|
110
|
+
*/
|
|
111
|
+
function generateThemeStyles() {
|
|
112
|
+
const styles = {};
|
|
113
|
+
|
|
114
|
+
for (const [themeName, colors] of Object.entries(themes)) {
|
|
115
|
+
const cssVars = {};
|
|
116
|
+
|
|
117
|
+
// Add color variables
|
|
118
|
+
for (const [key, value] of Object.entries(colors)) {
|
|
119
|
+
const cssKey = `--color-${key.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
|
|
120
|
+
cssVars[cssKey] = hexToRgb(value);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Add font and radius variables
|
|
124
|
+
cssVars['--font-sans'] = fonts.sans;
|
|
125
|
+
cssVars['--font-mono'] = fonts.mono;
|
|
126
|
+
cssVars['--radius-sm'] = borderRadius.sm;
|
|
127
|
+
cssVars['--radius-md'] = borderRadius.md;
|
|
128
|
+
cssVars['--radius-lg'] = borderRadius.lg;
|
|
129
|
+
cssVars['--radius-full'] = borderRadius.full;
|
|
130
|
+
|
|
131
|
+
// Use :root for default theme, data-theme selector for all
|
|
132
|
+
if (themeName === defaultTheme) {
|
|
133
|
+
styles[':root'] = cssVars;
|
|
134
|
+
}
|
|
135
|
+
styles[`html[data-theme="${themeName}"]`] = cssVars;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return styles;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
content: [
|
|
143
|
+
'./node_modules/@chaaskit/client/src/**/*.{js,ts,jsx,tsx}',
|
|
144
|
+
'./node_modules/@chaaskit/client/dist/**/*.js',
|
|
145
|
+
],
|
|
146
|
+
theme: {
|
|
147
|
+
extend: {
|
|
148
|
+
colors: {
|
|
149
|
+
primary: 'rgb(var(--color-primary) / <alpha-value>)',
|
|
150
|
+
'primary-hover': 'rgb(var(--color-primary-hover) / <alpha-value>)',
|
|
151
|
+
secondary: 'rgb(var(--color-secondary) / <alpha-value>)',
|
|
152
|
+
background: 'rgb(var(--color-background) / <alpha-value>)',
|
|
153
|
+
'background-secondary': 'rgb(var(--color-background-secondary) / <alpha-value>)',
|
|
154
|
+
sidebar: 'rgb(var(--color-sidebar) / <alpha-value>)',
|
|
155
|
+
'text-primary': 'rgb(var(--color-text-primary) / <alpha-value>)',
|
|
156
|
+
'text-secondary': 'rgb(var(--color-text-secondary) / <alpha-value>)',
|
|
157
|
+
'text-muted': 'rgb(var(--color-text-muted) / <alpha-value>)',
|
|
158
|
+
border: 'rgb(var(--color-border) / <alpha-value>)',
|
|
159
|
+
'input-background': 'rgb(var(--color-input-background) / <alpha-value>)',
|
|
160
|
+
'input-border': 'rgb(var(--color-input-border) / <alpha-value>)',
|
|
161
|
+
'user-message-bg': 'rgb(var(--color-user-message-bg) / <alpha-value>)',
|
|
162
|
+
'user-message-text': 'rgb(var(--color-user-message-text) / <alpha-value>)',
|
|
163
|
+
'assistant-message-bg': 'rgb(var(--color-assistant-message-bg) / <alpha-value>)',
|
|
164
|
+
'assistant-message-text': 'rgb(var(--color-assistant-message-text) / <alpha-value>)',
|
|
165
|
+
success: 'rgb(var(--color-success) / <alpha-value>)',
|
|
166
|
+
warning: 'rgb(var(--color-warning) / <alpha-value>)',
|
|
167
|
+
error: 'rgb(var(--color-error) / <alpha-value>)',
|
|
168
|
+
},
|
|
169
|
+
fontFamily: {
|
|
170
|
+
sans: ['var(--font-sans)', 'system-ui', 'sans-serif'],
|
|
171
|
+
mono: ['var(--font-mono)', 'Menlo', 'monospace'],
|
|
172
|
+
},
|
|
173
|
+
borderRadius: {
|
|
174
|
+
sm: 'var(--radius-sm)',
|
|
175
|
+
md: 'var(--radius-md)',
|
|
176
|
+
lg: 'var(--radius-lg)',
|
|
177
|
+
full: 'var(--radius-full)',
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
plugins: [
|
|
182
|
+
// Inject theme CSS variables
|
|
183
|
+
plugin(function ({ addBase }) {
|
|
184
|
+
addBase(generateThemeStyles());
|
|
185
|
+
}),
|
|
186
|
+
// Custom variant for touch devices
|
|
187
|
+
plugin(function ({ addVariant }) {
|
|
188
|
+
addVariant('touch-device', '@media (pointer: coarse)');
|
|
189
|
+
}),
|
|
190
|
+
// Base styles and utilities
|
|
191
|
+
plugin(function ({ addBase, addUtilities }) {
|
|
192
|
+
// Base element styles
|
|
193
|
+
addBase({
|
|
194
|
+
'html': {
|
|
195
|
+
fontFamily: 'var(--font-sans)',
|
|
196
|
+
},
|
|
197
|
+
'pre': {
|
|
198
|
+
fontFamily: 'var(--font-mono)',
|
|
199
|
+
fontSize: '0.875rem',
|
|
200
|
+
},
|
|
201
|
+
'code': {
|
|
202
|
+
fontFamily: 'var(--font-mono)',
|
|
203
|
+
},
|
|
204
|
+
'kbd': {
|
|
205
|
+
fontFamily: 'var(--font-sans)',
|
|
206
|
+
},
|
|
207
|
+
// Scrollbar styling
|
|
208
|
+
'::-webkit-scrollbar': {
|
|
209
|
+
width: '8px',
|
|
210
|
+
height: '8px',
|
|
211
|
+
},
|
|
212
|
+
'::-webkit-scrollbar-track': {
|
|
213
|
+
backgroundColor: 'transparent',
|
|
214
|
+
},
|
|
215
|
+
'::-webkit-scrollbar-thumb': {
|
|
216
|
+
backgroundColor: 'rgb(var(--color-border))',
|
|
217
|
+
borderRadius: '9999px',
|
|
218
|
+
},
|
|
219
|
+
'::-webkit-scrollbar-thumb:hover': {
|
|
220
|
+
backgroundColor: 'rgb(var(--color-text-muted))',
|
|
221
|
+
},
|
|
222
|
+
// Markdown content styling
|
|
223
|
+
'.markdown-content': {
|
|
224
|
+
lineHeight: '1.625',
|
|
225
|
+
},
|
|
226
|
+
'.markdown-content h1': {
|
|
227
|
+
fontSize: '1.5rem',
|
|
228
|
+
fontWeight: '700',
|
|
229
|
+
marginTop: '1.5rem',
|
|
230
|
+
marginBottom: '1rem',
|
|
231
|
+
},
|
|
232
|
+
'.markdown-content h2': {
|
|
233
|
+
fontSize: '1.25rem',
|
|
234
|
+
fontWeight: '700',
|
|
235
|
+
marginTop: '1.25rem',
|
|
236
|
+
marginBottom: '0.75rem',
|
|
237
|
+
},
|
|
238
|
+
'.markdown-content h3': {
|
|
239
|
+
fontSize: '1.125rem',
|
|
240
|
+
fontWeight: '600',
|
|
241
|
+
marginTop: '1rem',
|
|
242
|
+
marginBottom: '0.5rem',
|
|
243
|
+
},
|
|
244
|
+
'.markdown-content p': {
|
|
245
|
+
marginBottom: '1rem',
|
|
246
|
+
},
|
|
247
|
+
'.markdown-content ul, .markdown-content ol': {
|
|
248
|
+
marginBottom: '1rem',
|
|
249
|
+
paddingLeft: '1.5rem',
|
|
250
|
+
},
|
|
251
|
+
'.markdown-content ul': {
|
|
252
|
+
listStyleType: 'disc',
|
|
253
|
+
},
|
|
254
|
+
'.markdown-content ol': {
|
|
255
|
+
listStyleType: 'decimal',
|
|
256
|
+
},
|
|
257
|
+
'.markdown-content li': {
|
|
258
|
+
marginBottom: '0.25rem',
|
|
259
|
+
},
|
|
260
|
+
'.markdown-content blockquote': {
|
|
261
|
+
borderLeftWidth: '4px',
|
|
262
|
+
borderLeftColor: 'rgb(var(--color-border))',
|
|
263
|
+
paddingLeft: '1rem',
|
|
264
|
+
fontStyle: 'italic',
|
|
265
|
+
marginTop: '1rem',
|
|
266
|
+
marginBottom: '1rem',
|
|
267
|
+
},
|
|
268
|
+
'.markdown-content a': {
|
|
269
|
+
color: 'rgb(var(--color-primary))',
|
|
270
|
+
},
|
|
271
|
+
'.markdown-content a:hover': {
|
|
272
|
+
textDecoration: 'underline',
|
|
273
|
+
},
|
|
274
|
+
'.markdown-content table': {
|
|
275
|
+
width: '100%',
|
|
276
|
+
borderCollapse: 'collapse',
|
|
277
|
+
marginTop: '1rem',
|
|
278
|
+
marginBottom: '1rem',
|
|
279
|
+
},
|
|
280
|
+
'.markdown-content th, .markdown-content td': {
|
|
281
|
+
borderWidth: '1px',
|
|
282
|
+
borderColor: 'rgb(var(--color-border))',
|
|
283
|
+
paddingLeft: '1rem',
|
|
284
|
+
paddingRight: '1rem',
|
|
285
|
+
paddingTop: '0.5rem',
|
|
286
|
+
paddingBottom: '0.5rem',
|
|
287
|
+
textAlign: 'left',
|
|
288
|
+
},
|
|
289
|
+
'.markdown-content th': {
|
|
290
|
+
backgroundColor: 'rgb(var(--color-background-secondary))',
|
|
291
|
+
fontWeight: '600',
|
|
292
|
+
},
|
|
293
|
+
'.markdown-content hr': {
|
|
294
|
+
marginTop: '1.5rem',
|
|
295
|
+
marginBottom: '1.5rem',
|
|
296
|
+
borderColor: 'rgb(var(--color-border))',
|
|
297
|
+
},
|
|
298
|
+
// Search highlight
|
|
299
|
+
'mark': {
|
|
300
|
+
backgroundColor: 'rgb(var(--color-warning) / 0.3)',
|
|
301
|
+
color: 'rgb(var(--color-text-primary))',
|
|
302
|
+
borderRadius: '0.125rem',
|
|
303
|
+
paddingLeft: '0.125rem',
|
|
304
|
+
paddingRight: '0.125rem',
|
|
305
|
+
},
|
|
306
|
+
// Animations
|
|
307
|
+
'@keyframes fade-in': {
|
|
308
|
+
from: { opacity: '0' },
|
|
309
|
+
to: { opacity: '1' },
|
|
310
|
+
},
|
|
311
|
+
'@keyframes slide-up': {
|
|
312
|
+
from: { transform: 'translateY(10px)', opacity: '0' },
|
|
313
|
+
to: { transform: 'translateY(0)', opacity: '1' },
|
|
314
|
+
},
|
|
315
|
+
'@keyframes typing': {
|
|
316
|
+
'0%, 60%, 100%': { opacity: '1' },
|
|
317
|
+
'30%': { opacity: '0.3' },
|
|
318
|
+
},
|
|
319
|
+
'.animate-fade-in': {
|
|
320
|
+
animation: 'fade-in 0.2s ease-out',
|
|
321
|
+
},
|
|
322
|
+
'.animate-slide-up': {
|
|
323
|
+
animation: 'slide-up 0.2s ease-out',
|
|
324
|
+
},
|
|
325
|
+
'.typing-indicator span': {
|
|
326
|
+
animation: 'typing 1s infinite',
|
|
327
|
+
},
|
|
328
|
+
'.typing-indicator span:nth-child(2)': {
|
|
329
|
+
animationDelay: '0.2s',
|
|
330
|
+
},
|
|
331
|
+
'.typing-indicator span:nth-child(3)': {
|
|
332
|
+
animationDelay: '0.4s',
|
|
333
|
+
},
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
// Custom utilities
|
|
337
|
+
addUtilities({
|
|
338
|
+
// Mobile viewport height fix - dvh with fallback
|
|
339
|
+
'.h-screen-safe': {
|
|
340
|
+
height: '100vh',
|
|
341
|
+
'@supports (height: 100dvh)': {
|
|
342
|
+
height: '100dvh',
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
// Line clamp
|
|
346
|
+
'.line-clamp-2': {
|
|
347
|
+
display: '-webkit-box',
|
|
348
|
+
'-webkit-line-clamp': '2',
|
|
349
|
+
'-webkit-box-orient': 'vertical',
|
|
350
|
+
overflow: 'hidden',
|
|
351
|
+
},
|
|
352
|
+
});
|
|
353
|
+
}),
|
|
354
|
+
],
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Default export for simple usage
|
|
359
|
+
const chaaskitPreset = createChaaskitPreset();
|
|
360
|
+
export default chaaskitPreset;
|
package/dist/favicon.svg
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32">
|
|
2
|
-
<defs>
|
|
3
|
-
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
-
<stop offset="0%" style="stop-color:#6366f1"/>
|
|
5
|
-
<stop offset="100%" style="stop-color:#8b5cf6"/>
|
|
6
|
-
</linearGradient>
|
|
7
|
-
</defs>
|
|
8
|
-
<rect width="32" height="32" rx="6" fill="url(#grad)"/>
|
|
9
|
-
<path d="M10 12 L16 9 L22 12 L22 18 L16 21 L10 18 Z" fill="none" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
|
|
10
|
-
<circle cx="16" cy="15" r="2.5" fill="white"/>
|
|
11
|
-
</svg>
|