create-chaaskit 0.1.0

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 (122) hide show
  1. package/dist/cli.d.ts +3 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +25 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/add-infra.d.ts +6 -0
  6. package/dist/commands/add-infra.d.ts.map +1 -0
  7. package/dist/commands/add-infra.js +160 -0
  8. package/dist/commands/add-infra.js.map +1 -0
  9. package/dist/commands/build.d.ts +2 -0
  10. package/dist/commands/build.d.ts.map +1 -0
  11. package/dist/commands/build.js +63 -0
  12. package/dist/commands/build.js.map +1 -0
  13. package/dist/commands/db-sync.d.ts +13 -0
  14. package/dist/commands/db-sync.d.ts.map +1 -0
  15. package/dist/commands/db-sync.js +108 -0
  16. package/dist/commands/db-sync.js.map +1 -0
  17. package/dist/commands/dev.d.ts +7 -0
  18. package/dist/commands/dev.d.ts.map +1 -0
  19. package/dist/commands/dev.js +61 -0
  20. package/dist/commands/dev.js.map +1 -0
  21. package/dist/commands/init.d.ts +9 -0
  22. package/dist/commands/init.d.ts.map +1 -0
  23. package/dist/commands/init.js +214 -0
  24. package/dist/commands/init.js.map +1 -0
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +57 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/templates/.env.example +24 -0
  30. package/dist/templates/README.md +81 -0
  31. package/dist/templates/app/components/AcceptInviteClient.tsx +10 -0
  32. package/dist/templates/app/components/AdminDashboardClient.tsx +10 -0
  33. package/dist/templates/app/components/AdminTeamClient.tsx +10 -0
  34. package/dist/templates/app/components/AdminTeamsClient.tsx +10 -0
  35. package/dist/templates/app/components/AdminUsersClient.tsx +10 -0
  36. package/dist/templates/app/components/ApiKeysClient.tsx +10 -0
  37. package/dist/templates/app/components/AutomationsClient.tsx +10 -0
  38. package/dist/templates/app/components/ChatClient.tsx +13 -0
  39. package/dist/templates/app/components/ClientOnly.tsx +6 -0
  40. package/dist/templates/app/components/DocumentsClient.tsx +10 -0
  41. package/dist/templates/app/components/OAuthConsentClient.tsx +10 -0
  42. package/dist/templates/app/components/PricingClient.tsx +10 -0
  43. package/dist/templates/app/components/TeamSettingsClient.tsx +10 -0
  44. package/dist/templates/app/components/VerifyEmailClient.tsx +10 -0
  45. package/dist/templates/app/entry.client.tsx +12 -0
  46. package/dist/templates/app/entry.server.tsx +67 -0
  47. package/dist/templates/app/root.tsx +91 -0
  48. package/dist/templates/app/routes/_index.tsx +82 -0
  49. package/dist/templates/app/routes/admin._index.tsx +57 -0
  50. package/dist/templates/app/routes/admin.teams.$teamId.tsx +57 -0
  51. package/dist/templates/app/routes/admin.teams._index.tsx +57 -0
  52. package/dist/templates/app/routes/admin.users.tsx +57 -0
  53. package/dist/templates/app/routes/api-keys.tsx +57 -0
  54. package/dist/templates/app/routes/automations.tsx +57 -0
  55. package/dist/templates/app/routes/chat._index.tsx +11 -0
  56. package/dist/templates/app/routes/chat.admin._index.tsx +10 -0
  57. package/dist/templates/app/routes/chat.admin.teams.$teamId.tsx +10 -0
  58. package/dist/templates/app/routes/chat.admin.teams._index.tsx +10 -0
  59. package/dist/templates/app/routes/chat.admin.users.tsx +10 -0
  60. package/dist/templates/app/routes/chat.api-keys.tsx +10 -0
  61. package/dist/templates/app/routes/chat.automations.tsx +10 -0
  62. package/dist/templates/app/routes/chat.documents.tsx +10 -0
  63. package/dist/templates/app/routes/chat.team.$teamId.settings.tsx +10 -0
  64. package/dist/templates/app/routes/chat.thread.$threadId.tsx +11 -0
  65. package/dist/templates/app/routes/chat.tsx +39 -0
  66. package/dist/templates/app/routes/documents.tsx +57 -0
  67. package/dist/templates/app/routes/invite.$token.tsx +10 -0
  68. package/dist/templates/app/routes/login.tsx +334 -0
  69. package/dist/templates/app/routes/oauth.consent.tsx +10 -0
  70. package/dist/templates/app/routes/pricing.tsx +10 -0
  71. package/dist/templates/app/routes/privacy.tsx +197 -0
  72. package/dist/templates/app/routes/register.tsx +398 -0
  73. package/dist/templates/app/routes/shared.$shareId.tsx +226 -0
  74. package/dist/templates/app/routes/team.$teamId.settings.tsx +57 -0
  75. package/dist/templates/app/routes/terms.tsx +173 -0
  76. package/dist/templates/app/routes/thread.$threadId.tsx +102 -0
  77. package/dist/templates/app/routes/verify-email.tsx +10 -0
  78. package/dist/templates/app/routes.ts +47 -0
  79. package/dist/templates/config/app.config.ts +216 -0
  80. package/dist/templates/docs/admin.md +257 -0
  81. package/dist/templates/docs/api-keys.md +403 -0
  82. package/dist/templates/docs/authentication.md +247 -0
  83. package/dist/templates/docs/configuration.md +1212 -0
  84. package/dist/templates/docs/custom-pages.md +466 -0
  85. package/dist/templates/docs/deployment.md +362 -0
  86. package/dist/templates/docs/development.md +411 -0
  87. package/dist/templates/docs/documents.md +293 -0
  88. package/dist/templates/docs/extensions.md +639 -0
  89. package/dist/templates/docs/index.md +139 -0
  90. package/dist/templates/docs/installation.md +286 -0
  91. package/dist/templates/docs/mcp.md +952 -0
  92. package/dist/templates/docs/native-tools.md +688 -0
  93. package/dist/templates/docs/queue.md +514 -0
  94. package/dist/templates/docs/scheduled-prompts.md +279 -0
  95. package/dist/templates/docs/settings.md +415 -0
  96. package/dist/templates/docs/slack.md +318 -0
  97. package/dist/templates/docs/styling.md +288 -0
  98. package/dist/templates/extensions/agents/.gitkeep +0 -0
  99. package/dist/templates/extensions/pages/.gitkeep +0 -0
  100. package/dist/templates/extensions/payment-plans/.gitkeep +0 -0
  101. package/dist/templates/index.html +16 -0
  102. package/dist/templates/infra-aws/.github/workflows/deploy.yml +95 -0
  103. package/dist/templates/infra-aws/README.md +207 -0
  104. package/dist/templates/infra-aws/bin/cdk.ts +18 -0
  105. package/dist/templates/infra-aws/cdk.json +43 -0
  106. package/dist/templates/infra-aws/config/deployment.ts +156 -0
  107. package/dist/templates/infra-aws/lib/chaaskit-stack.ts +419 -0
  108. package/dist/templates/infra-aws/package.json +27 -0
  109. package/dist/templates/infra-aws/scripts/build-app.sh +63 -0
  110. package/dist/templates/infra-aws/tsconfig.json +25 -0
  111. package/dist/templates/package.json +46 -0
  112. package/dist/templates/prisma/schema/base.prisma +584 -0
  113. package/dist/templates/prisma/schema/custom.prisma +24 -0
  114. package/dist/templates/prisma/schema.prisma +271 -0
  115. package/dist/templates/public/favicon.svg +4 -0
  116. package/dist/templates/public/logo.svg +4 -0
  117. package/dist/templates/react-router.config.ts +11 -0
  118. package/dist/templates/server.js +52 -0
  119. package/dist/templates/src/main.tsx +8 -0
  120. package/dist/templates/tsconfig.json +26 -0
  121. package/dist/templates/vite.config.ts +26 -0
  122. package/package.json +46 -0
@@ -0,0 +1,318 @@
1
+ # Slack Integration
2
+
3
+ Connect your team's Slack workspace to chat with your AI assistant directly from Slack. Team members can @mention the bot in any channel to get instant AI responses.
4
+
5
+ ## Features
6
+
7
+ - **AI Chat via @mentions**: Mention your bot in any channel to get AI responses
8
+ - **Thread Continuity**: Follow-up messages in a Slack thread maintain conversation context
9
+ - **Team Notifications**: Get notified in Slack when threads are shared, messages are liked, or new members join
10
+ - **Per-Team Configuration**: Each team can connect their own Slack workspace
11
+
12
+ ## Prerequisites
13
+
14
+ Before enabling Slack integration, you need:
15
+
16
+ 1. **Teams feature enabled** - Slack integration requires the teams feature
17
+ 2. **A Slack App** - Create one at https://api.slack.com/apps
18
+
19
+ ## Creating a Slack App
20
+
21
+ ### 1. Create the App
22
+
23
+ 1. Go to https://api.slack.com/apps
24
+ 2. Click "Create New App" → "From scratch"
25
+ 3. Name your app and select your workspace
26
+ 4. Note the **Client ID**, **Client Secret**, and **Signing Secret** from "Basic Information"
27
+
28
+ ### 2. Configure Bot Token Scopes
29
+
30
+ Go to "OAuth & Permissions" and add these Bot Token Scopes:
31
+
32
+ | Scope | Purpose |
33
+ |-------|---------|
34
+ | `app_mentions:read` | Receive @mention events |
35
+ | `channels:history` | Read channel messages for thread context |
36
+ | `groups:history` | Read private channel messages |
37
+ | `im:history` | Read direct messages |
38
+ | `chat:write` | Send messages as the bot |
39
+ | `reactions:write` | Add reactions (processing indicators) |
40
+ | `users:read` | Look up user information |
41
+
42
+ ### 3. Enable Event Subscriptions
43
+
44
+ 1. Go to "Event Subscriptions"
45
+ 2. Turn on "Enable Events"
46
+ 3. Set the Request URL to: `{API_URL}/api/slack/events` (e.g., `https://api.your-app.com/api/slack/events`)
47
+ 4. Subscribe to these bot events:
48
+ - `app_mention` - When someone @mentions your bot
49
+ - `message.channels` - Messages in public channels (optional, for DM support)
50
+ - `message.groups` - Messages in private channels (optional)
51
+ - `message.im` - Direct messages to the bot (optional)
52
+
53
+ ### 4. Set OAuth Redirect URL
54
+
55
+ 1. Go to "OAuth & Permissions"
56
+ 2. Add a Redirect URL: `{API_URL}/api/slack/callback` (e.g., `https://api.your-app.com/api/slack/callback`)
57
+
58
+ ### Sample App Manifest
59
+
60
+ You can use this manifest as a starting point when creating your Slack app. Go to "App Manifest" in your app settings and paste this JSON (update the URLs to match your deployment):
61
+
62
+ ```json
63
+ {
64
+ "display_information": {
65
+ "name": "My AI Assistant",
66
+ "description": "Chat with AI directly in Slack",
67
+ "background_color": "#6366f1"
68
+ },
69
+ "features": {
70
+ "app_home": {
71
+ "messages_tab_enabled": true,
72
+ "messages_tab_read_only_enabled": false
73
+ },
74
+ "bot_user": {
75
+ "display_name": "AI Assistant",
76
+ "always_online": true
77
+ }
78
+ },
79
+ "oauth_config": {
80
+ "redirect_urls": [
81
+ "https://api.your-app.com/api/slack/callback"
82
+ ],
83
+ "scopes": {
84
+ "bot": [
85
+ "app_mentions:read",
86
+ "channels:history",
87
+ "groups:history",
88
+ "im:history",
89
+ "chat:write",
90
+ "reactions:write",
91
+ "users:read"
92
+ ]
93
+ }
94
+ },
95
+ "settings": {
96
+ "event_subscriptions": {
97
+ "request_url": "https://api.your-app.com/api/slack/events",
98
+ "bot_events": [
99
+ "app_mention",
100
+ "message.channels",
101
+ "message.groups",
102
+ "message.im"
103
+ ]
104
+ },
105
+ "org_deploy_enabled": false,
106
+ "socket_mode_enabled": false,
107
+ "token_rotation_enabled": false
108
+ }
109
+ }
110
+ ```
111
+
112
+ **Note**: Replace `api.your-app.com` with your actual API domain (the value of `API_URL`). Both the `request_url` and `redirect_urls` must be publicly accessible.
113
+
114
+ ## Configuration
115
+
116
+ ### Environment Variables
117
+
118
+ Add these to your `.env` file:
119
+
120
+ ```bash
121
+ SLACK_CLIENT_ID=your-client-id
122
+ SLACK_CLIENT_SECRET=your-client-secret
123
+ SLACK_SIGNING_SECRET=your-signing-secret
124
+ SLACK_INTERNAL_SECRET=any-random-secret-for-internal-calls
125
+ ```
126
+
127
+ Generate the internal secret with:
128
+ ```bash
129
+ openssl rand -hex 32
130
+ ```
131
+
132
+ ### App Configuration
133
+
134
+ Enable Slack in your `config/app.config.ts`:
135
+
136
+ ```typescript
137
+ import type { AppConfig } from '@chaaskit/shared';
138
+
139
+ export const config: AppConfig = {
140
+ // ... other config
141
+
142
+ teams: {
143
+ enabled: true, // Required for Slack
144
+ },
145
+
146
+ slack: {
147
+ enabled: true,
148
+ clientIdEnvVar: 'SLACK_CLIENT_ID',
149
+ clientSecretEnvVar: 'SLACK_CLIENT_SECRET',
150
+ signingSecretEnvVar: 'SLACK_SIGNING_SECRET',
151
+ internalSecretEnvVar: 'SLACK_INTERNAL_SECRET',
152
+
153
+ // Optional: Restrict to specific plans
154
+ allowedPlans: ['pro', 'enterprise'],
155
+
156
+ // AI chat settings
157
+ aiChat: {
158
+ enabled: true,
159
+ threadContinuity: true, // Maintain context across Slack thread replies
160
+ },
161
+
162
+ // Team notifications
163
+ notifications: {
164
+ events: [
165
+ { event: 'thread_shared', enabled: true },
166
+ { event: 'message_liked', enabled: true },
167
+ { event: 'team_member_joined', enabled: true },
168
+ ],
169
+ },
170
+ },
171
+ };
172
+ ```
173
+
174
+ ## Connecting a Team
175
+
176
+ Once configured, team admins can connect Slack from the Team Settings page:
177
+
178
+ 1. Go to Team Settings
179
+ 2. Find the "Slack Integration" section
180
+ 3. Click "Add to Slack"
181
+ 4. Authorize the app in your Slack workspace
182
+ 5. You'll be redirected back with a success message
183
+
184
+ ## Using the Bot
185
+
186
+ ### Basic Usage
187
+
188
+ Mention the bot in any channel:
189
+
190
+ ```
191
+ @YourBot What's the weather like today?
192
+ ```
193
+
194
+ The bot will:
195
+ 1. Add an 👀 reaction to show it's processing
196
+ 2. Generate a response using your AI agent
197
+ 3. Reply in a thread
198
+ 4. Replace the 👀 with ✅ when complete
199
+
200
+ **Note:** The bot only responds to messages that @mention it. Regular channel messages without an @mention are ignored.
201
+
202
+ ### Thread Continuity
203
+
204
+ Once you've @mentioned the bot, you can continue the conversation in the thread **without** needing to @mention it again:
205
+
206
+ ```
207
+ User: @YourBot Explain quantum computing
208
+ Bot: Quantum computing uses quantum bits (qubits)...
209
+
210
+ User: Can you give me an example?
211
+ Bot: Sure! A classic example is Shor's algorithm...
212
+ ```
213
+
214
+ The bot automatically responds to all messages in threads where it has been mentioned, maintaining context from the conversation.
215
+
216
+ ### Response Formatting
217
+
218
+ The bot formats responses using Slack's mrkdwn syntax, so you'll see proper formatting for bold text, code blocks, lists, and links.
219
+
220
+ ### Context from Your App
221
+
222
+ The bot uses the same AI agent and team context as your web app. If you've configured team context in Team Settings, it will be included in Slack conversations.
223
+
224
+ ## Notifications
225
+
226
+ When enabled, your team's Slack channel will receive notifications for:
227
+
228
+ | Event | Notification |
229
+ |-------|--------------|
230
+ | Thread Shared | When a team member shares a conversation |
231
+ | Message Liked | When someone gives positive feedback on an AI response |
232
+ | Member Joined | When a new member joins the team |
233
+
234
+ ### Configuring Notification Channel
235
+
236
+ 1. Go to Team Settings → Slack Integration
237
+ 2. Enter the notification channel (e.g., `#general`)
238
+ 3. Click "Save Settings"
239
+
240
+ ## Architecture
241
+
242
+ ### Event Flow
243
+
244
+ ```
245
+ 1. User @mentions bot in Slack
246
+ 2. Slack sends event to /api/slack/events
247
+ 3. Server verifies signature, stores event, responds 200 OK (within 3s)
248
+ 4. Server triggers /api/slack/internal/process asynchronously
249
+ 5. Event processor:
250
+ - Fetches Slack thread history for context
251
+ - Finds/creates internal thread for continuity
252
+ - Calls AI agent with conversation
253
+ - Posts response back to Slack
254
+ ```
255
+
256
+ ### Data Storage
257
+
258
+ | Model | Purpose |
259
+ |-------|---------|
260
+ | `SlackIntegration` | Stores team's Slack connection (workspace ID, encrypted tokens, settings) |
261
+ | `SlackMessageEvent` | Tracks incoming events for deduplication and retry |
262
+
263
+ Tokens are encrypted at rest using AES-256-GCM.
264
+
265
+ ### Retry Logic
266
+
267
+ Failed events are automatically retried:
268
+ - Events stuck in "pending" or "processing" for >3 minutes are retried
269
+ - Maximum 3 retry attempts per event
270
+ - Use `POST /api/slack/internal/retry` to trigger retry (requires internal secret)
271
+
272
+ ## API Endpoints
273
+
274
+ | Endpoint | Method | Auth | Description |
275
+ |----------|--------|------|-------------|
276
+ | `/api/slack/install/:teamId` | GET | User (Admin) | Start OAuth flow |
277
+ | `/api/slack/callback` | GET | None | OAuth callback |
278
+ | `/api/slack/:teamId/status` | GET | User (Viewer+) | Get integration status |
279
+ | `/api/slack/:teamId/settings` | PATCH | User (Admin) | Update settings |
280
+ | `/api/slack/:teamId` | DELETE | User (Admin) | Disconnect Slack |
281
+ | `/api/slack/events` | POST | Slack Signature | Receive Slack events |
282
+ | `/api/slack/internal/process` | POST | Internal Secret | Process an event |
283
+ | `/api/slack/internal/retry` | POST | Internal Secret | Retry stale events |
284
+
285
+ ## Troubleshooting
286
+
287
+ ### Bot doesn't respond
288
+
289
+ 1. Check that your Slack app has the required scopes
290
+ 2. Verify Event Subscriptions URL is correct and verified
291
+ 3. Check server logs for errors
292
+ 4. Ensure the team has Slack connected (check Team Settings)
293
+
294
+ ### "Invalid signature" errors
295
+
296
+ - Verify `SLACK_SIGNING_SECRET` matches your Slack app's signing secret
297
+ - Ensure raw request body is being used for signature verification
298
+
299
+ ### Events timing out
300
+
301
+ Slack requires a response within 3 seconds. The integration handles this by:
302
+ 1. Quickly acknowledging the event
303
+ 2. Processing asynchronously via internal endpoint
304
+
305
+ If you see timeout errors, check that `/api/slack/internal/process` is accessible from your server.
306
+
307
+ ### Thread context not working
308
+
309
+ - Ensure `threadContinuity` is enabled in config
310
+ - The bot needs `channels:history` (or equivalent) scope to read thread history
311
+ - Private channels require `groups:history`
312
+
313
+ ## Security Considerations
314
+
315
+ - **Token Encryption**: Slack tokens are encrypted at rest using your `SESSION_SECRET`
316
+ - **Signature Verification**: All incoming Slack requests are verified using HMAC-SHA256
317
+ - **Internal Endpoints**: Protected by a separate secret to prevent external access
318
+ - **Scope Minimization**: Only request the Slack scopes you need
@@ -0,0 +1,288 @@
1
+ # Styling Guide
2
+
3
+ This guide documents the styling conventions used throughout the application to maintain visual consistency. Follow these patterns when building new pages and components.
4
+
5
+ ## Design Principles
6
+
7
+ 1. **Soft, not harsh**: Avoid hard borders and stark contrasts. Use subtle background colors for separation instead of explicit borders.
8
+ 2. **Consistent spacing**: Use the same padding and margin patterns across similar components.
9
+ 3. **Visual hierarchy**: Use typography and subtle color differences, not heavy borders, to establish hierarchy.
10
+
11
+ ## Color Variables
12
+
13
+ Use CSS variables for all colors. Never hardcode color values.
14
+
15
+ ### Primary Colors
16
+
17
+ | Variable | Usage |
18
+ |----------|-------|
19
+ | `--color-primary` | Primary actions, active states, links |
20
+ | `--color-primary-hover` | Hover state for primary elements |
21
+ | `--color-secondary` | Secondary accent color |
22
+
23
+ ### Background Colors
24
+
25
+ | Variable | Usage |
26
+ |----------|-------|
27
+ | `--color-background` | Main page background |
28
+ | `--color-background-secondary` | Cards, sections, elevated surfaces |
29
+ | `--color-sidebar` | Sidebar background |
30
+
31
+ ### Text Colors
32
+
33
+ | Variable | Usage |
34
+ |----------|-------|
35
+ | `--color-text-primary` | Main text, headings |
36
+ | `--color-text-secondary` | Body text, descriptions |
37
+ | `--color-text-muted` | Helper text, timestamps, placeholders |
38
+
39
+ ### Input Colors
40
+
41
+ | Variable | Usage |
42
+ |----------|-------|
43
+ | `--color-input-background` | Input field backgrounds |
44
+ | `--color-input-border` | Input field borders (subtle) |
45
+
46
+ ### Status Colors
47
+
48
+ | Variable | Usage |
49
+ |----------|-------|
50
+ | `--color-success` | Success messages, positive states |
51
+ | `--color-warning` | Warning messages, caution states |
52
+ | `--color-error` | Error messages, destructive actions |
53
+
54
+ ## Section Styling
55
+
56
+ ### Cards and Sections
57
+
58
+ **DO**: Use background colors for visual separation
59
+
60
+ ```tsx
61
+ // Good - Soft, borderless card
62
+ <div className="rounded-lg bg-[var(--color-background-secondary)] p-6">
63
+ <h2 className="text-lg font-semibold text-[var(--color-text-primary)] mb-4">
64
+ Section Title
65
+ </h2>
66
+ {/* content */}
67
+ </div>
68
+ ```
69
+
70
+ **DON'T**: Use explicit borders for main sections
71
+
72
+ ```tsx
73
+ // Bad - Harsh border
74
+ <div className="rounded-lg border border-[var(--color-border)] bg-[var(--color-background-secondary)] p-6">
75
+ ```
76
+
77
+ ### List Items with Dividers
78
+
79
+ When items need visual separation, use the background color as a subtle divider:
80
+
81
+ ```tsx
82
+ // Good - Subtle dividers using background color
83
+ <div className="divide-y divide-[var(--color-background)]">
84
+ {items.map(item => (
85
+ <div key={item.id} className="px-4 py-3">
86
+ {/* item content */}
87
+ </div>
88
+ ))}
89
+ </div>
90
+ ```
91
+
92
+ ### Table-like Lists
93
+
94
+ Use grid layouts with background-based headers instead of traditional bordered tables:
95
+
96
+ ```tsx
97
+ // Header
98
+ <div className="px-4 py-3 bg-[var(--color-background)]">
99
+ <div className="grid grid-cols-12 gap-4 text-sm font-medium text-[var(--color-text-muted)]">
100
+ <div className="col-span-3">Name</div>
101
+ <div className="col-span-2">Status</div>
102
+ {/* ... */}
103
+ </div>
104
+ </div>
105
+
106
+ // Body
107
+ <div className="divide-y divide-[var(--color-background)]">
108
+ {items.map(item => (
109
+ <div key={item.id} className="px-4 py-3 hover:bg-[var(--color-background)]/50">
110
+ <div className="grid grid-cols-12 gap-4 items-center">
111
+ {/* item content */}
112
+ </div>
113
+ </div>
114
+ ))}
115
+ </div>
116
+ ```
117
+
118
+ ## Button Styling
119
+
120
+ ### Primary Buttons
121
+
122
+ ```tsx
123
+ <button className="rounded-lg bg-[var(--color-primary)] px-4 py-2 font-medium text-white hover:bg-[var(--color-primary-hover)]">
124
+ Save
125
+ </button>
126
+ ```
127
+
128
+ ### Secondary Buttons (Soft)
129
+
130
+ ```tsx
131
+ // Good - Background-based, no border
132
+ <button className="rounded-lg bg-[var(--color-background-secondary)] px-4 py-2 text-[var(--color-text-primary)] hover:bg-[var(--color-background-secondary)]/80">
133
+ Cancel
134
+ </button>
135
+ ```
136
+
137
+ ```tsx
138
+ // Avoid - Bordered button
139
+ <button className="rounded-lg border border-[var(--color-border)] px-4 py-2">
140
+ ```
141
+
142
+ ### Text/Link Buttons
143
+
144
+ ```tsx
145
+ <button className="text-sm text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)]">
146
+ Back to chat
147
+ </button>
148
+ ```
149
+
150
+ ### Destructive Buttons
151
+
152
+ ```tsx
153
+ <button className="rounded-lg bg-[var(--color-error)] px-4 py-2 font-medium text-white hover:bg-[var(--color-error)]/90">
154
+ Delete
155
+ </button>
156
+ ```
157
+
158
+ ## Form Inputs
159
+
160
+ Inputs should have subtle borders using the input-specific variables:
161
+
162
+ ```tsx
163
+ <input
164
+ type="text"
165
+ className="w-full rounded-lg border border-[var(--color-input-border)] bg-[var(--color-input-background)] px-4 py-2 text-[var(--color-text-primary)] placeholder-[var(--color-text-muted)] focus:border-[var(--color-primary)] focus:outline-none"
166
+ />
167
+ ```
168
+
169
+ For selects in compact contexts (like inline dropdowns):
170
+
171
+ ```tsx
172
+ <select className="rounded border border-[var(--color-input-border)] bg-[var(--color-input-background)] px-2 py-1 text-sm text-[var(--color-text-primary)]">
173
+ ```
174
+
175
+ ## Pills and Badges
176
+
177
+ Use background colors with no borders:
178
+
179
+ ```tsx
180
+ // Status badge
181
+ <span className="rounded-full bg-[var(--color-primary)]/10 px-2 py-0.5 text-xs font-medium text-[var(--color-primary)]">
182
+ Active
183
+ </span>
184
+
185
+ // Clickable pill
186
+ <Link className="inline-flex items-center rounded-full bg-[var(--color-background)] px-2 py-0.5 text-xs text-[var(--color-text-secondary)] hover:bg-[var(--color-primary)]/10 hover:text-[var(--color-primary)]">
187
+ Team Name
188
+ </Link>
189
+ ```
190
+
191
+ ## Avatar Placeholders
192
+
193
+ When showing initials instead of an image, use the primary color:
194
+
195
+ ```tsx
196
+ <div className="w-8 h-8 rounded-full bg-primary flex items-center justify-center text-white text-sm font-medium">
197
+ {name[0].toUpperCase()}
198
+ </div>
199
+ ```
200
+
201
+ Note: Use Tailwind's `bg-primary` class rather than `bg-[var(--color-primary)]` for avatars, as it's more reliable in some contexts.
202
+
203
+ ## Page Layout
204
+
205
+ ### Standard Admin/Settings Page
206
+
207
+ ```tsx
208
+ <div className="min-h-screen bg-[var(--color-background)] p-8">
209
+ <div className="mx-auto max-w-6xl">
210
+ {/* Header */}
211
+ <div className="flex items-center justify-between mb-8">
212
+ <h1 className="text-2xl font-bold text-[var(--color-text-primary)]">
213
+ Page Title
214
+ </h1>
215
+ <div className="flex gap-4">
216
+ {/* Navigation buttons */}
217
+ </div>
218
+ </div>
219
+
220
+ {/* Error/Success messages */}
221
+ {error && (
222
+ <div className="mb-6 rounded-lg bg-[var(--color-error)]/10 p-4 text-sm text-[var(--color-error)]">
223
+ {error}
224
+ </div>
225
+ )}
226
+
227
+ {/* Content sections */}
228
+ <div className="rounded-lg bg-[var(--color-background-secondary)] p-6 mb-6">
229
+ {/* Section content */}
230
+ </div>
231
+ </div>
232
+ </div>
233
+ ```
234
+
235
+ ## Hover States
236
+
237
+ Use subtle background changes for hover states:
238
+
239
+ ```tsx
240
+ // List item hover
241
+ className="hover:bg-[var(--color-background)]/50"
242
+
243
+ // Card hover (when clickable)
244
+ className="hover:bg-[var(--color-background-secondary)]/80"
245
+ ```
246
+
247
+ ## Spacing Constants
248
+
249
+ | Use Case | Padding | Margin |
250
+ |----------|---------|--------|
251
+ | Page padding | `p-8` | - |
252
+ | Card/Section padding | `p-6` | `mb-6` or `mb-8` |
253
+ | List item padding | `px-4 py-3` | - |
254
+ | Compact item padding | `px-2 py-1` | - |
255
+ | Button padding | `px-4 py-2` | - |
256
+ | Badge padding | `px-2 py-0.5` | - |
257
+
258
+ ## Reference Components
259
+
260
+ When building new UI, refer to these existing components for styling patterns:
261
+
262
+ | Component | Location | Good For |
263
+ |-----------|----------|----------|
264
+ | Settings Modal | `components/SettingsModal.tsx` | Modal dialogs, form layouts |
265
+ | Team Settings | `pages/TeamSettingsPage.tsx` | Full-page settings, member lists |
266
+ | Admin Dashboard | `pages/AdminDashboardPage.tsx` | Stats cards, charts, data display |
267
+ | Admin Users | `pages/AdminUsersPage.tsx` | Data tables, search, pagination |
268
+ | Sidebar | `components/Sidebar.tsx` | Navigation, lists, collapsible sections |
269
+
270
+ ## Anti-Patterns to Avoid
271
+
272
+ 1. **Explicit borders on cards**: Use `bg-background-secondary` instead of `border border-[var(--color-border)]`
273
+
274
+ 2. **Dark/harsh dividers**: Use `divide-[var(--color-background)]` instead of `divide-[var(--color-border)]`
275
+
276
+ 3. **Bordered buttons**: Use background colors for secondary buttons
277
+
278
+ 4. **CSS variable syntax for avatars**: Use Tailwind classes like `bg-primary` for avatar backgrounds
279
+
280
+ 5. **Inconsistent spacing**: Follow the spacing constants above
281
+
282
+ 6. **Hardcoded colors**: Always use CSS variables
283
+
284
+ ## Tailwind vs CSS Variables
285
+
286
+ - **Use Tailwind classes** (`bg-primary`, `text-text-primary`) when available and working correctly
287
+ - **Use CSS variables** (`bg-[var(--color-primary)]`) when Tailwind classes don't resolve properly or for complex color manipulation
288
+ - **For avatars specifically**, prefer Tailwind classes as they're more reliable
File without changes
File without changes
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>{{APP_NAME}}</title>
8
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
9
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
10
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
11
+ </head>
12
+ <body>
13
+ <div id="root"></div>
14
+ <script type="module" src="/src/main.tsx"></script>
15
+ </body>
16
+ </html>