@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.
Files changed (96) hide show
  1. package/LICENSE +21 -0
  2. package/dist/lib/index.js +1023 -160
  3. package/dist/lib/index.js.map +1 -1
  4. package/dist/lib/routes/AcceptInviteRoute.js +1 -1
  5. package/dist/lib/routes/AcceptInviteRoute.js.map +1 -1
  6. package/dist/lib/routes/AdminDashboardRoute.js +1 -1
  7. package/dist/lib/routes/AdminDashboardRoute.js.map +1 -1
  8. package/dist/lib/routes/AdminPromoCodesRoute.js +19 -0
  9. package/dist/lib/routes/AdminPromoCodesRoute.js.map +1 -0
  10. package/dist/lib/routes/AdminTeamRoute.js +1 -1
  11. package/dist/lib/routes/AdminTeamRoute.js.map +1 -1
  12. package/dist/lib/routes/AdminTeamsRoute.js +1 -1
  13. package/dist/lib/routes/AdminTeamsRoute.js.map +1 -1
  14. package/dist/lib/routes/AdminUsersRoute.js +1 -1
  15. package/dist/lib/routes/AdminUsersRoute.js.map +1 -1
  16. package/dist/lib/routes/AdminWaitlistRoute.js +19 -0
  17. package/dist/lib/routes/AdminWaitlistRoute.js.map +1 -0
  18. package/dist/lib/routes/ApiKeysRoute.js +1 -1
  19. package/dist/lib/routes/ApiKeysRoute.js.map +1 -1
  20. package/dist/lib/routes/AutomationsRoute.js +1 -1
  21. package/dist/lib/routes/AutomationsRoute.js.map +1 -1
  22. package/dist/lib/routes/ChatRoute.js +1 -1
  23. package/dist/lib/routes/ChatRoute.js.map +1 -1
  24. package/dist/lib/routes/DocumentsRoute.js +1 -1
  25. package/dist/lib/routes/DocumentsRoute.js.map +1 -1
  26. package/dist/lib/routes/OAuthConsentRoute.js +1 -1
  27. package/dist/lib/routes/OAuthConsentRoute.js.map +1 -1
  28. package/dist/lib/routes/PricingRoute.js +1 -1
  29. package/dist/lib/routes/PricingRoute.js.map +1 -1
  30. package/dist/lib/routes/PrivacyRoute.js +1 -1
  31. package/dist/lib/routes/PrivacyRoute.js.map +1 -1
  32. package/dist/lib/routes/TeamSettingsRoute.js +1 -1
  33. package/dist/lib/routes/TeamSettingsRoute.js.map +1 -1
  34. package/dist/lib/routes/TermsRoute.js +1 -1
  35. package/dist/lib/routes/TermsRoute.js.map +1 -1
  36. package/dist/lib/routes/VerifyEmailRoute.js +1 -1
  37. package/dist/lib/routes/VerifyEmailRoute.js.map +1 -1
  38. package/dist/lib/routes.js +47 -37
  39. package/dist/lib/routes.js.map +1 -1
  40. package/dist/lib/ssr-utils.js +64 -1
  41. package/dist/lib/ssr-utils.js.map +1 -1
  42. package/dist/lib/ssr.js +23 -0
  43. package/dist/lib/ssr.js.map +1 -1
  44. package/dist/lib/styles.css +58 -62
  45. package/dist/lib/useExtensions-B5nX_8XD.js.map +1 -1
  46. package/package.json +25 -12
  47. package/src/components/MessageItem.tsx +35 -4
  48. package/src/components/MessageList.tsx +51 -5
  49. package/src/components/OAuthAppsSection.tsx +1 -1
  50. package/src/components/Sidebar.tsx +1 -3
  51. package/src/components/ToolCallDisplay.tsx +102 -11
  52. package/src/components/tool-renderers/DocumentListRenderer.tsx +44 -0
  53. package/src/components/tool-renderers/DocumentReadRenderer.tsx +33 -0
  54. package/src/components/tool-renderers/DocumentSaveRenderer.tsx +32 -0
  55. package/src/components/tool-renderers/DocumentSearchRenderer.tsx +33 -0
  56. package/src/components/tool-renderers/index.ts +36 -0
  57. package/src/components/tool-renderers/utils.ts +7 -0
  58. package/src/contexts/AuthContext.tsx +16 -6
  59. package/src/contexts/ConfigContext.tsx +60 -28
  60. package/src/contexts/ThemeContext.tsx +39 -68
  61. package/src/extensions/registry.ts +2 -1
  62. package/src/hooks/__tests__/basePath.test.ts +42 -0
  63. package/src/index.tsx +11 -2
  64. package/src/pages/AdminDashboardPage.tsx +15 -1
  65. package/src/pages/AdminPromoCodesPage.tsx +378 -0
  66. package/src/pages/AdminTeamPage.tsx +29 -1
  67. package/src/pages/AdminTeamsPage.tsx +15 -1
  68. package/src/pages/AdminUsersPage.tsx +15 -1
  69. package/src/pages/AdminWaitlistPage.tsx +156 -0
  70. package/src/pages/RegisterPage.tsx +91 -9
  71. package/src/routes/AcceptInviteRoute.tsx +1 -1
  72. package/src/routes/AdminDashboardRoute.tsx +1 -1
  73. package/src/routes/AdminPromoCodesRoute.tsx +24 -0
  74. package/src/routes/AdminTeamRoute.tsx +1 -1
  75. package/src/routes/AdminTeamsRoute.tsx +1 -1
  76. package/src/routes/AdminUsersRoute.tsx +1 -1
  77. package/src/routes/AdminWaitlistRoute.tsx +24 -0
  78. package/src/routes/ApiKeysRoute.tsx +1 -1
  79. package/src/routes/AutomationsRoute.tsx +1 -1
  80. package/src/routes/ChatRoute.tsx +2 -1
  81. package/src/routes/DocumentsRoute.tsx +1 -1
  82. package/src/routes/OAuthConsentRoute.tsx +1 -1
  83. package/src/routes/PricingRoute.tsx +1 -1
  84. package/src/routes/PrivacyRoute.tsx +1 -1
  85. package/src/routes/TeamSettingsRoute.tsx +1 -1
  86. package/src/routes/TermsRoute.tsx +1 -1
  87. package/src/routes/VerifyEmailRoute.tsx +1 -1
  88. package/src/routes/index.ts +2 -0
  89. package/src/ssr-utils.tsx +100 -1
  90. package/src/ssr.ts +59 -0
  91. package/src/stores/chatStore.ts +5 -0
  92. package/src/styles/index.css +16 -63
  93. package/src/tailwind-preset.js +360 -0
  94. package/dist/favicon.svg +0 -11
  95. package/dist/index.html +0 -17
  96. 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
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
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.
@@ -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(),
@@ -2,69 +2,22 @@
2
2
  @tailwind components;
3
3
  @tailwind utilities;
4
4
 
5
- /* Default theme variables (Light) */
6
- :root {
7
- --color-primary: 99 102 241;
8
- --color-primary-hover: 79 70 229;
9
- --color-secondary: 139 92 246;
10
-
11
- --color-background: 255 255 255;
12
- --color-background-secondary: 249 250 251;
13
- --color-sidebar: 243 244 246;
14
-
15
- --color-text-primary: 17 24 39;
16
- --color-text-secondary: 107 114 128;
17
- --color-text-muted: 156 163 175;
18
-
19
- --color-border: 229 231 235;
20
- --color-input-background: 255 255 255;
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>