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.
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +25 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/add-infra.d.ts +6 -0
- package/dist/commands/add-infra.d.ts.map +1 -0
- package/dist/commands/add-infra.js +160 -0
- package/dist/commands/add-infra.js.map +1 -0
- package/dist/commands/build.d.ts +2 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +63 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/db-sync.d.ts +13 -0
- package/dist/commands/db-sync.d.ts.map +1 -0
- package/dist/commands/db-sync.js +108 -0
- package/dist/commands/db-sync.js.map +1 -0
- package/dist/commands/dev.d.ts +7 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +61 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +214 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/templates/.env.example +24 -0
- package/dist/templates/README.md +81 -0
- package/dist/templates/app/components/AcceptInviteClient.tsx +10 -0
- package/dist/templates/app/components/AdminDashboardClient.tsx +10 -0
- package/dist/templates/app/components/AdminTeamClient.tsx +10 -0
- package/dist/templates/app/components/AdminTeamsClient.tsx +10 -0
- package/dist/templates/app/components/AdminUsersClient.tsx +10 -0
- package/dist/templates/app/components/ApiKeysClient.tsx +10 -0
- package/dist/templates/app/components/AutomationsClient.tsx +10 -0
- package/dist/templates/app/components/ChatClient.tsx +13 -0
- package/dist/templates/app/components/ClientOnly.tsx +6 -0
- package/dist/templates/app/components/DocumentsClient.tsx +10 -0
- package/dist/templates/app/components/OAuthConsentClient.tsx +10 -0
- package/dist/templates/app/components/PricingClient.tsx +10 -0
- package/dist/templates/app/components/TeamSettingsClient.tsx +10 -0
- package/dist/templates/app/components/VerifyEmailClient.tsx +10 -0
- package/dist/templates/app/entry.client.tsx +12 -0
- package/dist/templates/app/entry.server.tsx +67 -0
- package/dist/templates/app/root.tsx +91 -0
- package/dist/templates/app/routes/_index.tsx +82 -0
- package/dist/templates/app/routes/admin._index.tsx +57 -0
- package/dist/templates/app/routes/admin.teams.$teamId.tsx +57 -0
- package/dist/templates/app/routes/admin.teams._index.tsx +57 -0
- package/dist/templates/app/routes/admin.users.tsx +57 -0
- package/dist/templates/app/routes/api-keys.tsx +57 -0
- package/dist/templates/app/routes/automations.tsx +57 -0
- package/dist/templates/app/routes/chat._index.tsx +11 -0
- package/dist/templates/app/routes/chat.admin._index.tsx +10 -0
- package/dist/templates/app/routes/chat.admin.teams.$teamId.tsx +10 -0
- package/dist/templates/app/routes/chat.admin.teams._index.tsx +10 -0
- package/dist/templates/app/routes/chat.admin.users.tsx +10 -0
- package/dist/templates/app/routes/chat.api-keys.tsx +10 -0
- package/dist/templates/app/routes/chat.automations.tsx +10 -0
- package/dist/templates/app/routes/chat.documents.tsx +10 -0
- package/dist/templates/app/routes/chat.team.$teamId.settings.tsx +10 -0
- package/dist/templates/app/routes/chat.thread.$threadId.tsx +11 -0
- package/dist/templates/app/routes/chat.tsx +39 -0
- package/dist/templates/app/routes/documents.tsx +57 -0
- package/dist/templates/app/routes/invite.$token.tsx +10 -0
- package/dist/templates/app/routes/login.tsx +334 -0
- package/dist/templates/app/routes/oauth.consent.tsx +10 -0
- package/dist/templates/app/routes/pricing.tsx +10 -0
- package/dist/templates/app/routes/privacy.tsx +197 -0
- package/dist/templates/app/routes/register.tsx +398 -0
- package/dist/templates/app/routes/shared.$shareId.tsx +226 -0
- package/dist/templates/app/routes/team.$teamId.settings.tsx +57 -0
- package/dist/templates/app/routes/terms.tsx +173 -0
- package/dist/templates/app/routes/thread.$threadId.tsx +102 -0
- package/dist/templates/app/routes/verify-email.tsx +10 -0
- package/dist/templates/app/routes.ts +47 -0
- package/dist/templates/config/app.config.ts +216 -0
- package/dist/templates/docs/admin.md +257 -0
- package/dist/templates/docs/api-keys.md +403 -0
- package/dist/templates/docs/authentication.md +247 -0
- package/dist/templates/docs/configuration.md +1212 -0
- package/dist/templates/docs/custom-pages.md +466 -0
- package/dist/templates/docs/deployment.md +362 -0
- package/dist/templates/docs/development.md +411 -0
- package/dist/templates/docs/documents.md +293 -0
- package/dist/templates/docs/extensions.md +639 -0
- package/dist/templates/docs/index.md +139 -0
- package/dist/templates/docs/installation.md +286 -0
- package/dist/templates/docs/mcp.md +952 -0
- package/dist/templates/docs/native-tools.md +688 -0
- package/dist/templates/docs/queue.md +514 -0
- package/dist/templates/docs/scheduled-prompts.md +279 -0
- package/dist/templates/docs/settings.md +415 -0
- package/dist/templates/docs/slack.md +318 -0
- package/dist/templates/docs/styling.md +288 -0
- package/dist/templates/extensions/agents/.gitkeep +0 -0
- package/dist/templates/extensions/pages/.gitkeep +0 -0
- package/dist/templates/extensions/payment-plans/.gitkeep +0 -0
- package/dist/templates/index.html +16 -0
- package/dist/templates/infra-aws/.github/workflows/deploy.yml +95 -0
- package/dist/templates/infra-aws/README.md +207 -0
- package/dist/templates/infra-aws/bin/cdk.ts +18 -0
- package/dist/templates/infra-aws/cdk.json +43 -0
- package/dist/templates/infra-aws/config/deployment.ts +156 -0
- package/dist/templates/infra-aws/lib/chaaskit-stack.ts +419 -0
- package/dist/templates/infra-aws/package.json +27 -0
- package/dist/templates/infra-aws/scripts/build-app.sh +63 -0
- package/dist/templates/infra-aws/tsconfig.json +25 -0
- package/dist/templates/package.json +46 -0
- package/dist/templates/prisma/schema/base.prisma +584 -0
- package/dist/templates/prisma/schema/custom.prisma +24 -0
- package/dist/templates/prisma/schema.prisma +271 -0
- package/dist/templates/public/favicon.svg +4 -0
- package/dist/templates/public/logo.svg +4 -0
- package/dist/templates/react-router.config.ts +11 -0
- package/dist/templates/server.js +52 -0
- package/dist/templates/src/main.tsx +8 -0
- package/dist/templates/tsconfig.json +26 -0
- package/dist/templates/vite.config.ts +26 -0
- package/package.json +46 -0
|
@@ -0,0 +1,1212 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
All application configuration is centralized in `config/app.config.ts`. This file controls the UI, theming, authentication, AI agent, payments, MCP, and more.
|
|
4
|
+
|
|
5
|
+
## Configuration File
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// config/app.config.ts
|
|
9
|
+
import type { AppConfig } from '@chaaskit/shared';
|
|
10
|
+
|
|
11
|
+
const config: AppConfig = {
|
|
12
|
+
app: { ... },
|
|
13
|
+
ui: { ... },
|
|
14
|
+
theming: { ... },
|
|
15
|
+
auth: { ... },
|
|
16
|
+
agent: { ... },
|
|
17
|
+
payments: { ... },
|
|
18
|
+
legal: { ... },
|
|
19
|
+
userSettings: { ... },
|
|
20
|
+
mcp: { ... },
|
|
21
|
+
sharing: { ... },
|
|
22
|
+
promptTemplates: { ... },
|
|
23
|
+
teams: { ... },
|
|
24
|
+
projects: { ... },
|
|
25
|
+
admin: { ... },
|
|
26
|
+
api: { ... },
|
|
27
|
+
documents: { ... },
|
|
28
|
+
slack: { ... },
|
|
29
|
+
queue: { ... },
|
|
30
|
+
email: { ... },
|
|
31
|
+
scheduledPrompts: { ... },
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default config;
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Environment Variables
|
|
38
|
+
|
|
39
|
+
Required variables in `.env`:
|
|
40
|
+
|
|
41
|
+
| Variable | Description | Example |
|
|
42
|
+
|----------|-------------|---------|
|
|
43
|
+
| `DATABASE_URL` | PostgreSQL connection string | `postgresql://...` |
|
|
44
|
+
| `SESSION_SECRET` | Session encryption key (32+ chars) | `your-secret-key` |
|
|
45
|
+
| `JWT_SECRET` | JWT signing key (32+ chars) | `your-jwt-key` |
|
|
46
|
+
| `APP_URL` | Frontend URL | `http://localhost:5173` |
|
|
47
|
+
| `API_URL` | Backend URL | `http://localhost:3000` |
|
|
48
|
+
|
|
49
|
+
AI Provider (at least one required):
|
|
50
|
+
|
|
51
|
+
| Variable | Description |
|
|
52
|
+
|----------|-------------|
|
|
53
|
+
| `ANTHROPIC_API_KEY` | Anthropic API key |
|
|
54
|
+
| `OPENAI_API_KEY` | OpenAI API key |
|
|
55
|
+
|
|
56
|
+
MCP (optional):
|
|
57
|
+
|
|
58
|
+
| Variable | Description |
|
|
59
|
+
|----------|-------------|
|
|
60
|
+
| `MCP_CREDENTIAL_KEY` | Encryption key for user credentials (32+ chars, falls back to SESSION_SECRET) |
|
|
61
|
+
|
|
62
|
+
Payments (optional):
|
|
63
|
+
|
|
64
|
+
| Variable | Description |
|
|
65
|
+
|----------|-------------|
|
|
66
|
+
| `STRIPE_SECRET_KEY` | Stripe secret key |
|
|
67
|
+
| `STRIPE_WEBHOOK_SECRET` | Stripe webhook secret |
|
|
68
|
+
|
|
69
|
+
OAuth (optional):
|
|
70
|
+
|
|
71
|
+
| Variable | Description |
|
|
72
|
+
|----------|-------------|
|
|
73
|
+
| `GOOGLE_CLIENT_ID` | Google OAuth client ID |
|
|
74
|
+
| `GOOGLE_CLIENT_SECRET` | Google OAuth client secret |
|
|
75
|
+
| `GITHUB_CLIENT_ID` | GitHub OAuth client ID |
|
|
76
|
+
| `GITHUB_CLIENT_SECRET` | GitHub OAuth client secret |
|
|
77
|
+
|
|
78
|
+
Slack (optional):
|
|
79
|
+
|
|
80
|
+
| Variable | Description |
|
|
81
|
+
|----------|-------------|
|
|
82
|
+
| `SLACK_CLIENT_ID` | Slack OAuth client ID |
|
|
83
|
+
| `SLACK_CLIENT_SECRET` | Slack OAuth client secret |
|
|
84
|
+
| `SLACK_SIGNING_SECRET` | Slack request signing secret |
|
|
85
|
+
| `SLACK_INTERNAL_SECRET` | Random secret for internal endpoints |
|
|
86
|
+
|
|
87
|
+
Queue (optional, for SQS provider):
|
|
88
|
+
|
|
89
|
+
| Variable | Description |
|
|
90
|
+
|----------|-------------|
|
|
91
|
+
| `AWS_ACCESS_KEY_ID` | AWS access key (or use IAM role) |
|
|
92
|
+
| `AWS_SECRET_ACCESS_KEY` | AWS secret key (or use IAM role) |
|
|
93
|
+
| `SQS_QUEUE_URL` | SQS queue URL |
|
|
94
|
+
| `SQS_DLQ_URL` | SQS dead letter queue URL (optional) |
|
|
95
|
+
|
|
96
|
+
## Configuration Sections
|
|
97
|
+
|
|
98
|
+
### App Info
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
app: {
|
|
102
|
+
name: 'AI Chat',
|
|
103
|
+
description: 'Your AI assistant',
|
|
104
|
+
url: process.env.APP_URL || 'http://localhost:5173',
|
|
105
|
+
basePath: '/app', // Optional: run chat app under a path
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Base Path (Marketing Site Integration)
|
|
110
|
+
|
|
111
|
+
The `basePath` option allows you to run the authenticated chat application under a sub-path (e.g., `/chat`), freeing up the root URL for a marketing site or other public pages.
|
|
112
|
+
|
|
113
|
+
**Default behavior** (no basePath or `basePath: '/'`):
|
|
114
|
+
- Chat app routes: `/`, `/login`, `/thread/:id`, etc.
|
|
115
|
+
|
|
116
|
+
**With basePath: '/chat'**:
|
|
117
|
+
- Chat app routes: `/chat`, `/chat/thread/:id`, `/chat/documents`, etc.
|
|
118
|
+
- Auth routes: `/login`, `/register` (remain at root for better UX)
|
|
119
|
+
- Root path `/` is free for your landing page
|
|
120
|
+
|
|
121
|
+
**Example configuration:**
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// config/app.config.ts
|
|
125
|
+
app: {
|
|
126
|
+
name: 'My App',
|
|
127
|
+
basePath: '/chat', // Chat app lives under /chat/*
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Adding custom pages:**
|
|
132
|
+
|
|
133
|
+
With React Router v7, add pages by creating files in `app/routes/`:
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
// app/routes/_index.tsx - Landing page at /
|
|
137
|
+
// app/routes/pricing.tsx - Pricing page at /pricing
|
|
138
|
+
// app/routes/about.tsx - About page at /about
|
|
139
|
+
// app/routes/chat._index.tsx - Main chat at /chat
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
See [Custom Pages](./custom-pages.md) for detailed examples.
|
|
143
|
+
|
|
144
|
+
**Notes:**
|
|
145
|
+
- The API routes (`/api/*`) are unaffected - they always live at the root
|
|
146
|
+
- Use `useAppPath()` hook to build paths that respect the basePath
|
|
147
|
+
- Shared thread links use the appropriate path (e.g., `/shared/:id`)
|
|
148
|
+
|
|
149
|
+
### UI Settings
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
ui: {
|
|
153
|
+
welcomeTitle: 'Welcome to AI Chat',
|
|
154
|
+
welcomeSubtitle: 'How can I help you today?',
|
|
155
|
+
inputPlaceholder: 'Type your message...',
|
|
156
|
+
logo: '/logo.svg', // or { light: '/logo-light.svg', dark: '/logo-dark.svg' }
|
|
157
|
+
samplePrompts: [
|
|
158
|
+
{ label: 'Explain a concept', prompt: 'Explain quantum computing...' },
|
|
159
|
+
{ label: 'Write code', prompt: 'Write a function to sort...' },
|
|
160
|
+
],
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Theming
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
theming: {
|
|
168
|
+
defaultTheme: 'light', // 'light' | 'dark'
|
|
169
|
+
allowUserThemeSwitch: true,
|
|
170
|
+
themes: {
|
|
171
|
+
light: {
|
|
172
|
+
name: 'Light',
|
|
173
|
+
colors: {
|
|
174
|
+
primary: '#6366f1',
|
|
175
|
+
primaryHover: '#4f46e5',
|
|
176
|
+
background: '#ffffff',
|
|
177
|
+
// ... see full color list in types
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
dark: {
|
|
181
|
+
name: 'Dark',
|
|
182
|
+
colors: { ... },
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
fonts: {
|
|
186
|
+
sans: 'Inter, system-ui, sans-serif',
|
|
187
|
+
mono: 'JetBrains Mono, monospace',
|
|
188
|
+
},
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
See [Styling Guide](./styling.md) for CSS variables and component styling conventions.
|
|
193
|
+
|
|
194
|
+
### AI Agent
|
|
195
|
+
|
|
196
|
+
The platform supports both single-agent and multi-agent configurations.
|
|
197
|
+
|
|
198
|
+
#### Multi-Agent Configuration (Recommended)
|
|
199
|
+
|
|
200
|
+
Configure multiple AI agents with different providers, models, and capabilities:
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
agent: {
|
|
204
|
+
agents: [
|
|
205
|
+
// General purpose assistant - available to all users
|
|
206
|
+
{
|
|
207
|
+
id: 'general',
|
|
208
|
+
name: 'General Assistant',
|
|
209
|
+
provider: 'openai',
|
|
210
|
+
model: 'gpt-4o-mini',
|
|
211
|
+
systemPrompt: 'You are a helpful AI assistant.',
|
|
212
|
+
maxTokens: 4096,
|
|
213
|
+
isDefault: true,
|
|
214
|
+
// No allowedTools = all tools available
|
|
215
|
+
// No plans = available to all users
|
|
216
|
+
},
|
|
217
|
+
// Code expert - available to pro users only
|
|
218
|
+
{
|
|
219
|
+
id: 'code-expert',
|
|
220
|
+
name: 'Code Expert',
|
|
221
|
+
provider: 'anthropic',
|
|
222
|
+
model: 'claude-sonnet-4-20250514',
|
|
223
|
+
systemPrompt: 'You are an expert programmer.',
|
|
224
|
+
maxTokens: 8192,
|
|
225
|
+
allowedTools: ['github:*', 'filesystem:read_file'],
|
|
226
|
+
plans: ['pro', 'enterprise'],
|
|
227
|
+
},
|
|
228
|
+
// External agent - custom endpoint
|
|
229
|
+
{
|
|
230
|
+
id: 'custom-agent',
|
|
231
|
+
name: 'Custom Agent',
|
|
232
|
+
type: 'external',
|
|
233
|
+
endpoint: 'https://my-agent.example.com/chat',
|
|
234
|
+
headers: { 'Authorization': 'Bearer ${CUSTOM_AGENT_KEY}' },
|
|
235
|
+
plans: ['enterprise'],
|
|
236
|
+
},
|
|
237
|
+
],
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Agent Properties:**
|
|
242
|
+
|
|
243
|
+
| Property | Type | Description |
|
|
244
|
+
|----------|------|-------------|
|
|
245
|
+
| `id` | string | Unique identifier for the agent |
|
|
246
|
+
| `name` | string | Display name shown in the selector |
|
|
247
|
+
| `provider` | `'anthropic'` \| `'openai'` | AI provider (for built-in agents) |
|
|
248
|
+
| `model` | string | Model identifier (e.g., `gpt-4o-mini`, `claude-sonnet-4-20250514`) |
|
|
249
|
+
| `systemPrompt` | string | System prompt for the agent |
|
|
250
|
+
| `maxTokens` | number | Maximum tokens per response |
|
|
251
|
+
| `isDefault` | boolean | If true, this agent is used for new threads by default |
|
|
252
|
+
| `allowedTools` | string[] | Tool patterns to restrict access (optional) |
|
|
253
|
+
| `plans` | string[] | Plan IDs that can access this agent (optional, omit for all plans) |
|
|
254
|
+
|
|
255
|
+
**Tool Pattern Syntax:**
|
|
256
|
+
|
|
257
|
+
- `server:*` - All tools from an MCP server (e.g., `github:*`)
|
|
258
|
+
- `server:tool-name` - Specific MCP tool (e.g., `filesystem:read_file`)
|
|
259
|
+
- `native:*` - All native tools (built into the application)
|
|
260
|
+
- `native:tool-name` - Specific native tool (e.g., `native:web-scrape`)
|
|
261
|
+
- Omit `allowedTools` to allow all MCP tools (native tools are opt-in)
|
|
262
|
+
|
|
263
|
+
**Native Tools:**
|
|
264
|
+
|
|
265
|
+
Native tools are built into the application and don't require external MCP servers. They are opt-in and must be explicitly listed in `allowedTools` to be available to an agent.
|
|
266
|
+
|
|
267
|
+
| Tool | Description |
|
|
268
|
+
|------|-------------|
|
|
269
|
+
| `native:web-scrape` | Fetches a URL and returns the content as plain text. Useful for reading web pages, documentation, or articles. |
|
|
270
|
+
|
|
271
|
+
Example enabling native tools:
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
{
|
|
275
|
+
id: 'research-assistant',
|
|
276
|
+
name: 'Research Assistant',
|
|
277
|
+
provider: 'anthropic',
|
|
278
|
+
model: 'claude-sonnet-4-20250514',
|
|
279
|
+
systemPrompt: 'You are a research assistant.',
|
|
280
|
+
maxTokens: 8192,
|
|
281
|
+
allowedTools: ['native:web-scrape', 'search:*'], // Native web-scrape + all search server tools
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
See [Native Tools](./native-tools.md) for the full list of available native tools and how to create custom ones.
|
|
286
|
+
|
|
287
|
+
**Agent Selection:**
|
|
288
|
+
|
|
289
|
+
- When multiple agents are configured, a selector appears on the welcome screen
|
|
290
|
+
- Each thread is locked to the agent it was created with
|
|
291
|
+
- If only one agent is configured or available to the user, the selector is hidden
|
|
292
|
+
|
|
293
|
+
#### Legacy Single-Agent Configuration
|
|
294
|
+
|
|
295
|
+
For simpler setups, you can still use the legacy single-agent configuration:
|
|
296
|
+
|
|
297
|
+
Built-in provider:
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
agent: {
|
|
301
|
+
type: 'built-in',
|
|
302
|
+
provider: 'anthropic', // or 'openai'
|
|
303
|
+
model: 'claude-sonnet-4-20250514',
|
|
304
|
+
systemPrompt: 'You are a helpful AI assistant.',
|
|
305
|
+
maxTokens: 4096,
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
External provider:
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
agent: {
|
|
313
|
+
type: 'external',
|
|
314
|
+
endpoint: 'https://your-api.com/chat',
|
|
315
|
+
headers: {
|
|
316
|
+
'Authorization': '${API_KEY}', // Env var substitution
|
|
317
|
+
},
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Authentication
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
auth: {
|
|
325
|
+
methods: ['email-password', 'google', 'github', 'magic-link'],
|
|
326
|
+
allowUnauthenticated: false, // Allow anonymous chats
|
|
327
|
+
magicLink: {
|
|
328
|
+
enabled: true,
|
|
329
|
+
expiresInMinutes: 15,
|
|
330
|
+
},
|
|
331
|
+
emailVerification: {
|
|
332
|
+
enabled: true, // Require email verification for new users
|
|
333
|
+
codeLength: 6, // Length of verification code (default: 6)
|
|
334
|
+
expiresInMinutes: 15, // Code expiration time (default: 15)
|
|
335
|
+
allowResendAfterSeconds: 60, // Cooldown before resend (default: 60)
|
|
336
|
+
},
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
#### Email Verification
|
|
341
|
+
|
|
342
|
+
When email verification is enabled, new users registering with email/password will need to verify their email address before accessing protected features.
|
|
343
|
+
|
|
344
|
+
**How it works:**
|
|
345
|
+
1. User registers with email/password
|
|
346
|
+
2. A 6-digit numeric code is sent to their email
|
|
347
|
+
3. User is redirected to the verification page
|
|
348
|
+
4. User enters the code to verify their email
|
|
349
|
+
5. After verification, user can access all features
|
|
350
|
+
|
|
351
|
+
**Graceful degradation:** If email verification is enabled but the email provider isn't configured, users are auto-verified on registration. This allows you to enable the feature in config before setting up email.
|
|
352
|
+
|
|
353
|
+
**OAuth and Magic Link users:** Users who sign in via OAuth (Google, GitHub) or magic link are automatically verified since they've already proven email ownership through those flows.
|
|
354
|
+
|
|
355
|
+
**Existing users:** When you enable email verification on an existing app, previously unverified users will be prompted to verify their email on their next protected action.
|
|
356
|
+
|
|
357
|
+
See [Authentication](./authentication.md) for full documentation on auth methods, OAuth setup, and customization.
|
|
358
|
+
|
|
359
|
+
### MCP Integration
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
mcp: {
|
|
363
|
+
servers: [
|
|
364
|
+
// Stdio server (local process, no auth)
|
|
365
|
+
{
|
|
366
|
+
id: 'filesystem',
|
|
367
|
+
name: 'File System',
|
|
368
|
+
transport: 'stdio',
|
|
369
|
+
command: 'npx',
|
|
370
|
+
args: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'],
|
|
371
|
+
enabled: true,
|
|
372
|
+
},
|
|
373
|
+
// Streamable HTTP with admin API key
|
|
374
|
+
{
|
|
375
|
+
id: 'company-tools',
|
|
376
|
+
name: 'Company Tools',
|
|
377
|
+
transport: 'streamable-http',
|
|
378
|
+
url: 'https://tools.company.com/mcp',
|
|
379
|
+
enabled: true,
|
|
380
|
+
authMode: 'admin',
|
|
381
|
+
adminApiKeyEnvVar: 'COMPANY_TOOLS_API_KEY',
|
|
382
|
+
},
|
|
383
|
+
// Streamable HTTP with user API key
|
|
384
|
+
{
|
|
385
|
+
id: 'openai-tools',
|
|
386
|
+
name: 'OpenAI Tools',
|
|
387
|
+
transport: 'streamable-http',
|
|
388
|
+
url: 'https://mcp.openai.com',
|
|
389
|
+
enabled: true,
|
|
390
|
+
authMode: 'user-apikey',
|
|
391
|
+
userInstructions: 'Enter your OpenAI API key',
|
|
392
|
+
},
|
|
393
|
+
// Streamable HTTP with user OAuth
|
|
394
|
+
{
|
|
395
|
+
id: 'github-tools',
|
|
396
|
+
name: 'GitHub Tools',
|
|
397
|
+
transport: 'streamable-http',
|
|
398
|
+
url: 'https://github-mcp.example.com',
|
|
399
|
+
enabled: true,
|
|
400
|
+
authMode: 'user-oauth',
|
|
401
|
+
oauth: {
|
|
402
|
+
authorizationEndpoint: 'https://github.com/login/oauth/authorize',
|
|
403
|
+
tokenEndpoint: 'https://github.com/login/oauth/access_token',
|
|
404
|
+
clientId: '${GITHUB_MCP_CLIENT_ID}',
|
|
405
|
+
clientSecretEnvVar: 'GITHUB_MCP_CLIENT_SECRET',
|
|
406
|
+
scopes: ['repo', 'read:user'],
|
|
407
|
+
},
|
|
408
|
+
userInstructions: 'Connect your GitHub account',
|
|
409
|
+
},
|
|
410
|
+
],
|
|
411
|
+
allowUserServers: true,
|
|
412
|
+
requireToolConfirmation: true,
|
|
413
|
+
toolTimeout: 30000,
|
|
414
|
+
showToolCalls: true, // Set to false to hide tool execution cards
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
See [MCP Integration](./mcp.md) for full documentation.
|
|
419
|
+
|
|
420
|
+
### Payments
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
payments: {
|
|
424
|
+
enabled: true,
|
|
425
|
+
provider: 'stripe',
|
|
426
|
+
plans: [
|
|
427
|
+
{
|
|
428
|
+
id: 'free',
|
|
429
|
+
name: 'Free',
|
|
430
|
+
type: 'free',
|
|
431
|
+
params: { monthlyMessageLimit: 20 },
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
id: 'pro',
|
|
435
|
+
name: 'Pro',
|
|
436
|
+
type: 'subscription',
|
|
437
|
+
params: {
|
|
438
|
+
stripePriceId: 'price_...',
|
|
439
|
+
monthlyMessageLimit: 1000,
|
|
440
|
+
},
|
|
441
|
+
},
|
|
442
|
+
],
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### Legal
|
|
447
|
+
|
|
448
|
+
Configure required legal document links:
|
|
449
|
+
|
|
450
|
+
```typescript
|
|
451
|
+
legal: {
|
|
452
|
+
privacyPolicyUrl: 'https://example.com/privacy',
|
|
453
|
+
termsOfServiceUrl: 'https://example.com/terms',
|
|
454
|
+
}
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
These URLs are displayed in the registration form and footer.
|
|
458
|
+
|
|
459
|
+
### User Settings
|
|
460
|
+
|
|
461
|
+
Define custom settings fields that users can configure in their profile. These settings provide context to the AI:
|
|
462
|
+
|
|
463
|
+
```typescript
|
|
464
|
+
userSettings: {
|
|
465
|
+
fields: [
|
|
466
|
+
{
|
|
467
|
+
key: 'name',
|
|
468
|
+
label: 'Your Name',
|
|
469
|
+
type: 'text',
|
|
470
|
+
placeholder: 'Enter your name',
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
key: 'role',
|
|
474
|
+
label: 'Your Role',
|
|
475
|
+
type: 'select',
|
|
476
|
+
options: ['Developer', 'Designer', 'Manager', 'Other'],
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
key: 'context',
|
|
480
|
+
label: 'Additional Context',
|
|
481
|
+
type: 'textarea',
|
|
482
|
+
placeholder: 'Any context the AI should know about you...',
|
|
483
|
+
},
|
|
484
|
+
],
|
|
485
|
+
}
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
**Field Types:**
|
|
489
|
+
|
|
490
|
+
| Type | Description |
|
|
491
|
+
|------|-------------|
|
|
492
|
+
| `text` | Single-line text input |
|
|
493
|
+
| `select` | Dropdown selection from predefined options |
|
|
494
|
+
| `textarea` | Multi-line text input |
|
|
495
|
+
|
|
496
|
+
See [User Settings](./settings.md) for full documentation on settings integration and MCP credentials.
|
|
497
|
+
|
|
498
|
+
### Prompt Templates
|
|
499
|
+
|
|
500
|
+
Enable reusable prompt templates with variable substitution:
|
|
501
|
+
|
|
502
|
+
```typescript
|
|
503
|
+
promptTemplates: {
|
|
504
|
+
enabled: true,
|
|
505
|
+
allowUserTemplates: true, // Allow users to create their own templates
|
|
506
|
+
builtIn: [
|
|
507
|
+
{
|
|
508
|
+
id: 'code-review',
|
|
509
|
+
name: 'Code Review',
|
|
510
|
+
prompt: 'Review this {{language}} code for best practices:\n\n{{code}}',
|
|
511
|
+
variables: ['language', 'code'],
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
id: 'explain-concept',
|
|
515
|
+
name: 'Explain Concept',
|
|
516
|
+
prompt: 'Explain {{concept}} in simple terms for a {{audience}}.',
|
|
517
|
+
variables: ['concept', 'audience'],
|
|
518
|
+
},
|
|
519
|
+
],
|
|
520
|
+
}
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
Templates use `{{variable}}` syntax for substitution. Users fill in the variables when using a template.
|
|
524
|
+
|
|
525
|
+
### Admin Dashboard
|
|
526
|
+
|
|
527
|
+
Configure admin access for site-wide management:
|
|
528
|
+
|
|
529
|
+
```typescript
|
|
530
|
+
admin: {
|
|
531
|
+
emails: [
|
|
532
|
+
'admin@example.com',
|
|
533
|
+
'another-admin@example.com',
|
|
534
|
+
],
|
|
535
|
+
}
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
Users whose email addresses are in this list have access to the admin dashboard with user management, team management, and usage analytics.
|
|
539
|
+
|
|
540
|
+
See [Admin Dashboard](./admin.md) for full documentation.
|
|
541
|
+
|
|
542
|
+
### API Keys
|
|
543
|
+
|
|
544
|
+
Enable programmatic API access via API keys:
|
|
545
|
+
|
|
546
|
+
```typescript
|
|
547
|
+
api: {
|
|
548
|
+
enabled: true,
|
|
549
|
+
keyPrefix: 'myapp-', // Optional, default: "sk-"
|
|
550
|
+
allowedPlans: ['pro', 'enterprise'], // Optional: restrict to specific plans
|
|
551
|
+
allowedEndpoints: [ // Required: whitelist endpoints
|
|
552
|
+
'/api/chat',
|
|
553
|
+
'/api/threads',
|
|
554
|
+
'/api/threads/*',
|
|
555
|
+
'/api/threads/**',
|
|
556
|
+
'/api/search',
|
|
557
|
+
'/api/export/*',
|
|
558
|
+
],
|
|
559
|
+
}
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
**Endpoint Patterns:**
|
|
563
|
+
- `/api/threads` - Exact match only
|
|
564
|
+
- `/api/threads/*` - Single path segment (e.g., `/api/threads/123`)
|
|
565
|
+
- `/api/threads/**` - Any depth (e.g., `/api/threads/123/messages`)
|
|
566
|
+
|
|
567
|
+
See [API Keys](./api-keys.md) for full documentation.
|
|
568
|
+
|
|
569
|
+
### Sharing
|
|
570
|
+
|
|
571
|
+
```typescript
|
|
572
|
+
sharing: {
|
|
573
|
+
enabled: true, // Enable thread sharing feature
|
|
574
|
+
scope: 'public', // 'public' = anyone with link, 'team' = team members only
|
|
575
|
+
expirationOptions: ['1h', '24h', '7d', '30d', 'never'],
|
|
576
|
+
}
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
See [Thread Sharing](#thread-sharing) below for more details.
|
|
580
|
+
|
|
581
|
+
## Config API Endpoint
|
|
582
|
+
|
|
583
|
+
The frontend loads configuration from the server via `/api/config`:
|
|
584
|
+
|
|
585
|
+
```http
|
|
586
|
+
GET /api/config
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
Response includes client-safe configuration (excludes sensitive server-side settings like API keys).
|
|
590
|
+
|
|
591
|
+
This allows the frontend to stay in sync with `config/app.config.ts` without hardcoding values.
|
|
592
|
+
|
|
593
|
+
## Hot Reloading
|
|
594
|
+
|
|
595
|
+
The backend watches the config directory and auto-restarts on changes:
|
|
596
|
+
|
|
597
|
+
```bash
|
|
598
|
+
# In package.json (server)
|
|
599
|
+
"dev": "tsx watch --watch=../../config src/index.ts"
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
## Type Safety
|
|
603
|
+
|
|
604
|
+
The configuration is fully typed. Import types from `@chaaskit/shared`:
|
|
605
|
+
|
|
606
|
+
```typescript
|
|
607
|
+
import type { AppConfig, ThemeConfig, AgentConfig, MCPConfig } from '@chaaskit/shared';
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
## Thread Sharing
|
|
611
|
+
|
|
612
|
+
Thread sharing allows users to create read-only links to share conversations with others.
|
|
613
|
+
|
|
614
|
+
### Configuration
|
|
615
|
+
|
|
616
|
+
```typescript
|
|
617
|
+
sharing: {
|
|
618
|
+
enabled: false, // Set to true to enable sharing
|
|
619
|
+
scope: 'public', // Who can view shared links
|
|
620
|
+
expirationOptions: ['1h', '24h', '7d', '30d', 'never'],
|
|
621
|
+
}
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
### Scope Options
|
|
625
|
+
|
|
626
|
+
| Scope | Description |
|
|
627
|
+
|-------|-------------|
|
|
628
|
+
| `public` | Anyone with the link can view the conversation |
|
|
629
|
+
| `team` | Only authenticated users who share a team with the thread owner can view |
|
|
630
|
+
|
|
631
|
+
### How It Works
|
|
632
|
+
|
|
633
|
+
1. **Creating a share**: Users click "Share" in the sidebar when viewing a conversation
|
|
634
|
+
2. **Choose expiration**: Select how long the link should remain active
|
|
635
|
+
3. **Copy link**: The shareable URL is automatically copied to clipboard
|
|
636
|
+
4. **Managing shares**: Users can view active shares and revoke them at any time
|
|
637
|
+
|
|
638
|
+
### API Endpoints
|
|
639
|
+
|
|
640
|
+
| Method | Endpoint | Description |
|
|
641
|
+
|--------|----------|-------------|
|
|
642
|
+
| `POST` | `/api/share/:threadId` | Create a shareable link |
|
|
643
|
+
| `GET` | `/api/share/thread/:threadId` | List active shares for a thread |
|
|
644
|
+
| `GET` | `/api/share/view/:shareId` | View a shared thread (public or team-scoped) |
|
|
645
|
+
| `DELETE` | `/api/share/:shareId` | Revoke a share link |
|
|
646
|
+
|
|
647
|
+
### Shared Thread Page
|
|
648
|
+
|
|
649
|
+
Shared threads are viewable at `/shared/:shareId`. The page displays:
|
|
650
|
+
- Thread title and messages (read-only)
|
|
651
|
+
- App branding with link to sign up
|
|
652
|
+
- Appropriate error messages for expired or inaccessible links
|
|
653
|
+
|
|
654
|
+
### Team Scope Behavior
|
|
655
|
+
|
|
656
|
+
When `scope: 'team'`:
|
|
657
|
+
- Viewers must be authenticated
|
|
658
|
+
- Viewers must share at least one team with the thread owner
|
|
659
|
+
- Unauthenticated users see "Please sign in to view this shared conversation"
|
|
660
|
+
- Users without team access see "You don't have access to this conversation"
|
|
661
|
+
|
|
662
|
+
## Team Workspaces
|
|
663
|
+
|
|
664
|
+
Team workspaces allow users to collaborate on conversations within shared team contexts.
|
|
665
|
+
|
|
666
|
+
### Configuration
|
|
667
|
+
|
|
668
|
+
```typescript
|
|
669
|
+
teams: {
|
|
670
|
+
enabled: true, // Set to false to disable team workspaces (personal only)
|
|
671
|
+
}
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### Enabling/Disabling Teams
|
|
675
|
+
|
|
676
|
+
| Setting | Behavior |
|
|
677
|
+
|---------|----------|
|
|
678
|
+
| `enabled: true` | Team selector shown in sidebar, team settings accessible, team threads supported |
|
|
679
|
+
| `enabled: false` | Team features completely hidden, API endpoints blocked, personal workspaces only |
|
|
680
|
+
|
|
681
|
+
When teams are disabled:
|
|
682
|
+
- Team selector is hidden from the sidebar
|
|
683
|
+
- Team settings page redirects to home
|
|
684
|
+
- All `/api/teams/*` endpoints return 403 Forbidden
|
|
685
|
+
- `teamId` parameter is ignored in chat requests
|
|
686
|
+
- Team context is not sent to the AI agent
|
|
687
|
+
- Existing team data is preserved (can re-enable later)
|
|
688
|
+
|
|
689
|
+
### Team Features
|
|
690
|
+
|
|
691
|
+
**Team Selector**: Users can switch between personal workspace and team workspaces in the sidebar.
|
|
692
|
+
|
|
693
|
+
**Team Roles**:
|
|
694
|
+
|
|
695
|
+
| Role | Permissions |
|
|
696
|
+
|------|-------------|
|
|
697
|
+
| `owner` | Full control, can archive team, manage all members |
|
|
698
|
+
| `admin` | Can invite/remove members, edit team settings, create threads |
|
|
699
|
+
| `member` | Can create and participate in team threads |
|
|
700
|
+
| `viewer` | Can view team threads (read-only) |
|
|
701
|
+
|
|
702
|
+
**Team Context**: Admins and owners can set team-wide context that is automatically included in all team conversations. This is useful for:
|
|
703
|
+
- Project guidelines and coding standards
|
|
704
|
+
- Company policies or preferences
|
|
705
|
+
- Domain-specific knowledge
|
|
706
|
+
- Team conventions
|
|
707
|
+
|
|
708
|
+
The team context is combined with user context when sent to the AI:
|
|
709
|
+
|
|
710
|
+
```
|
|
711
|
+
Team context:
|
|
712
|
+
<team context here>
|
|
713
|
+
|
|
714
|
+
User context:
|
|
715
|
+
<user context here>
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
### URL-Based Team Selection
|
|
719
|
+
|
|
720
|
+
Team selection is persisted via URL query parameter (`?team=<teamId>`), enabling:
|
|
721
|
+
- Bookmarkable team-specific URLs
|
|
722
|
+
- Shareable links that open in the correct team context
|
|
723
|
+
- Persistence across page reloads
|
|
724
|
+
|
|
725
|
+
Priority: URL parameter > localStorage
|
|
726
|
+
|
|
727
|
+
### Team Settings Page
|
|
728
|
+
|
|
729
|
+
Accessible at `/team/:teamId/settings` for team members. Features include:
|
|
730
|
+
- **Team Name**: Editable by admins and owners
|
|
731
|
+
- **Team Context**: AI context editable by admins and owners
|
|
732
|
+
- **Invite Members**: Send email invitations (admins and owners)
|
|
733
|
+
- **Manage Members**: Update roles, remove members (admins and owners)
|
|
734
|
+
- **Danger Zone**: Archive team (owner) or leave team (members)
|
|
735
|
+
|
|
736
|
+
### API Endpoints
|
|
737
|
+
|
|
738
|
+
| Method | Endpoint | Description | Required Role |
|
|
739
|
+
|--------|----------|-------------|---------------|
|
|
740
|
+
| `GET` | `/api/teams` | List user's teams | Authenticated |
|
|
741
|
+
| `POST` | `/api/teams` | Create a new team | Authenticated |
|
|
742
|
+
| `GET` | `/api/teams/:teamId` | Get team details | Team member |
|
|
743
|
+
| `PATCH` | `/api/teams/:teamId` | Update team name/context | Admin |
|
|
744
|
+
| `POST` | `/api/teams/:teamId/archive` | Archive team | Owner |
|
|
745
|
+
| `POST` | `/api/teams/:teamId/invite` | Invite a member | Admin |
|
|
746
|
+
| `DELETE` | `/api/teams/:teamId/invite/:inviteId` | Cancel invite | Admin |
|
|
747
|
+
| `POST` | `/api/teams/:teamId/leave` | Leave team | Member (not owner) |
|
|
748
|
+
| `DELETE` | `/api/teams/:teamId/members/:userId` | Remove member | Admin |
|
|
749
|
+
| `PATCH` | `/api/teams/:teamId/members/:userId` | Update member role | Owner |
|
|
750
|
+
| `POST` | `/api/teams/accept-invite/:token` | Accept invitation | Authenticated |
|
|
751
|
+
|
|
752
|
+
### Database Schema
|
|
753
|
+
|
|
754
|
+
Teams are stored with the following structure:
|
|
755
|
+
|
|
756
|
+
```prisma
|
|
757
|
+
model Team {
|
|
758
|
+
id String @id @default(cuid())
|
|
759
|
+
name String
|
|
760
|
+
context String? // AI context for team conversations
|
|
761
|
+
archivedAt DateTime? // null = active, set = archived
|
|
762
|
+
members TeamMember[]
|
|
763
|
+
threads Thread[]
|
|
764
|
+
invites TeamInvite[]
|
|
765
|
+
createdAt DateTime @default(now())
|
|
766
|
+
updatedAt DateTime @updatedAt
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
model TeamMember {
|
|
770
|
+
id String @id @default(cuid())
|
|
771
|
+
teamId String
|
|
772
|
+
userId String
|
|
773
|
+
role String // 'owner' | 'admin' | 'member' | 'viewer'
|
|
774
|
+
team Team @relation(...)
|
|
775
|
+
user User @relation(...)
|
|
776
|
+
createdAt DateTime @default(now())
|
|
777
|
+
}
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
## Projects
|
|
781
|
+
|
|
782
|
+
Projects allow users to organize conversations into folders with shared AI context. Projects can be personal or team-based, with configurable sharing settings.
|
|
783
|
+
|
|
784
|
+
### Configuration
|
|
785
|
+
|
|
786
|
+
```typescript
|
|
787
|
+
projects: {
|
|
788
|
+
enabled: true, // Set to false to disable projects feature
|
|
789
|
+
colors: [ // Preset colors for project folders
|
|
790
|
+
'#ef4444', // red
|
|
791
|
+
'#f97316', // orange
|
|
792
|
+
'#eab308', // yellow
|
|
793
|
+
'#22c55e', // green
|
|
794
|
+
'#14b8a6', // teal
|
|
795
|
+
'#3b82f6', // blue
|
|
796
|
+
'#8b5cf6', // purple
|
|
797
|
+
'#ec4899', // pink
|
|
798
|
+
],
|
|
799
|
+
}
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
### Enabling/Disabling Projects
|
|
803
|
+
|
|
804
|
+
| Setting | Behavior |
|
|
805
|
+
|---------|----------|
|
|
806
|
+
| `enabled: true` | Project folders shown in sidebar, create/edit project buttons visible |
|
|
807
|
+
| `enabled: false` | Project features completely hidden, API endpoints blocked, threads have no project association |
|
|
808
|
+
|
|
809
|
+
When projects are disabled:
|
|
810
|
+
- Project folders are hidden from the sidebar
|
|
811
|
+
- "New Project" button is hidden
|
|
812
|
+
- All `/api/projects/*` endpoints return 403 Forbidden
|
|
813
|
+
- `projectId` parameter is ignored in thread creation
|
|
814
|
+
- Project context is not sent to the AI agent
|
|
815
|
+
- Existing project data is preserved (can re-enable later)
|
|
816
|
+
|
|
817
|
+
### Project Features
|
|
818
|
+
|
|
819
|
+
**Project Folders**: Display in the sidebar with collapsible thread lists. Each project shows a colored folder icon and thread count.
|
|
820
|
+
|
|
821
|
+
**Project Context**: Each project can have AI context that is automatically included in all conversations within the project. This is combined with team and user context in the following order:
|
|
822
|
+
|
|
823
|
+
```
|
|
824
|
+
Team context:
|
|
825
|
+
<team context here>
|
|
826
|
+
|
|
827
|
+
Project context:
|
|
828
|
+
<project context here>
|
|
829
|
+
|
|
830
|
+
User context:
|
|
831
|
+
<user context here>
|
|
832
|
+
```
|
|
833
|
+
|
|
834
|
+
**Project Colors**: Projects are assigned a color from the configured preset list, displayed as a colored folder icon.
|
|
835
|
+
|
|
836
|
+
### Project Sharing
|
|
837
|
+
|
|
838
|
+
Projects can be personal (private) or team-based with configurable sharing:
|
|
839
|
+
|
|
840
|
+
| Sharing | Description |
|
|
841
|
+
|---------|-------------|
|
|
842
|
+
| `private` | Only the project creator can see the project and its threads |
|
|
843
|
+
| `team` | All team members can see and contribute to the project |
|
|
844
|
+
|
|
845
|
+
Personal projects (no team association) are always private to the creator.
|
|
846
|
+
|
|
847
|
+
### Project Hierarchy
|
|
848
|
+
|
|
849
|
+
- **Personal Projects**: Created without a team, visible only to the creator
|
|
850
|
+
- **Team Projects**: Created within a team context, can be private or team-shared
|
|
851
|
+
- **Thread Assignment**: Threads belong to exactly one project (or no project). Threads cannot be moved between projects after creation.
|
|
852
|
+
|
|
853
|
+
### Project Archiving
|
|
854
|
+
|
|
855
|
+
When a project is archived:
|
|
856
|
+
- The project is hidden from the sidebar
|
|
857
|
+
- All threads within the project are also archived
|
|
858
|
+
- Archived data is preserved (can be restored if needed via database)
|
|
859
|
+
|
|
860
|
+
### Permissions
|
|
861
|
+
|
|
862
|
+
| Action | Personal Project | Team Project (Private) | Team Project (Team-shared) |
|
|
863
|
+
|--------|-----------------|----------------------|---------------------------|
|
|
864
|
+
| View | Creator only | Creator only | All team members |
|
|
865
|
+
| Create threads | Creator | Creator | Team members (except viewers) |
|
|
866
|
+
| Edit project | Creator | Creator | Owner/Admin |
|
|
867
|
+
| Archive project | Creator | Creator | Owner/Admin |
|
|
868
|
+
|
|
869
|
+
### API Endpoints
|
|
870
|
+
|
|
871
|
+
| Method | Endpoint | Description |
|
|
872
|
+
|--------|----------|-------------|
|
|
873
|
+
| `GET` | `/api/projects` | List user's accessible projects |
|
|
874
|
+
| `GET` | `/api/projects?teamId=<id>` | List projects for a specific team |
|
|
875
|
+
| `POST` | `/api/projects` | Create a new project |
|
|
876
|
+
| `GET` | `/api/projects/:projectId` | Get project details |
|
|
877
|
+
| `PATCH` | `/api/projects/:projectId` | Update project name/context/sharing |
|
|
878
|
+
| `POST` | `/api/projects/:projectId/archive` | Archive project and its threads |
|
|
879
|
+
|
|
880
|
+
### Database Schema
|
|
881
|
+
|
|
882
|
+
Projects are stored with the following structure:
|
|
883
|
+
|
|
884
|
+
```prisma
|
|
885
|
+
model Project {
|
|
886
|
+
id String @id @default(cuid())
|
|
887
|
+
name String
|
|
888
|
+
context String? // AI context for project threads
|
|
889
|
+
color String // Hex color from preset list
|
|
890
|
+
sharing String @default("private") // 'private' | 'team'
|
|
891
|
+
userId String // Creator
|
|
892
|
+
teamId String? // Optional team association
|
|
893
|
+
threads Thread[]
|
|
894
|
+
archivedAt DateTime? // null = active, set = archived
|
|
895
|
+
createdAt DateTime @default(now())
|
|
896
|
+
updatedAt DateTime @updatedAt
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
model Thread {
|
|
900
|
+
id String @id @default(cuid())
|
|
901
|
+
title String
|
|
902
|
+
projectId String? // Optional project association
|
|
903
|
+
project Project? @relation(...)
|
|
904
|
+
archivedAt DateTime? // null = active, set = archived
|
|
905
|
+
// ... other fields
|
|
906
|
+
}
|
|
907
|
+
```
|
|
908
|
+
|
|
909
|
+
### User Interface
|
|
910
|
+
|
|
911
|
+
**Sidebar Behavior**:
|
|
912
|
+
- Project folders are collapsible - click to expand/collapse
|
|
913
|
+
- Threads within projects are displayed nested under the folder
|
|
914
|
+
- The currently viewed thread is highlighted with a subtle background
|
|
915
|
+
- Threads without a project appear in an "Other Threads" section
|
|
916
|
+
|
|
917
|
+
**Project Context Bar**:
|
|
918
|
+
When creating a new chat within a project or viewing a thread that belongs to a project, a context bar appears at the top of the chat pane showing:
|
|
919
|
+
- The project's colored folder icon
|
|
920
|
+
- The project name
|
|
921
|
+
- For new chats: "New chat will be added to this project"
|
|
922
|
+
|
|
923
|
+
**Thread-Driven Selection**:
|
|
924
|
+
- Viewing a thread automatically updates the project context to match the thread's project
|
|
925
|
+
- Clicking the main "New Chat" button clears any project selection
|
|
926
|
+
- Clicking the "+" button on a project folder creates a new chat within that project
|
|
927
|
+
|
|
928
|
+
---
|
|
929
|
+
|
|
930
|
+
## Documents
|
|
931
|
+
|
|
932
|
+
Mentionable documents allow users to upload and reference content in chat using @-mentions.
|
|
933
|
+
|
|
934
|
+
### Configuration
|
|
935
|
+
|
|
936
|
+
```typescript
|
|
937
|
+
documents: {
|
|
938
|
+
enabled: true,
|
|
939
|
+
storage: {
|
|
940
|
+
provider: 'database', // 'database' | 'filesystem' | 's3'
|
|
941
|
+
// filesystem: { basePath: './uploads/documents' },
|
|
942
|
+
// s3: { bucket: 'my-bucket', region: 'us-east-1' },
|
|
943
|
+
},
|
|
944
|
+
maxFileSizeMB: 10,
|
|
945
|
+
hybridThreshold: 1000, // Documents under this char count are injected into context
|
|
946
|
+
acceptedTypes: [
|
|
947
|
+
'text/plain',
|
|
948
|
+
'text/markdown',
|
|
949
|
+
'text/x-markdown',
|
|
950
|
+
'text/csv',
|
|
951
|
+
'application/json',
|
|
952
|
+
],
|
|
953
|
+
}
|
|
954
|
+
```
|
|
955
|
+
|
|
956
|
+
### Key Features
|
|
957
|
+
|
|
958
|
+
- **Scoped documents**: Personal (`@my/`), team (`@team/slug/`), project (`@project/slug/`)
|
|
959
|
+
- **Hybrid access**: Small docs injected into context, large docs accessed via AI tools
|
|
960
|
+
- **File attachments**: Chat attachments automatically upload as documents with @-mentions
|
|
961
|
+
- **AI tools**: `list_documents`, `read_document`, `search_in_document`, `save_document`
|
|
962
|
+
|
|
963
|
+
See [Mentionable Documents](./documents.md) for full documentation.
|
|
964
|
+
|
|
965
|
+
---
|
|
966
|
+
|
|
967
|
+
## Slack Integration
|
|
968
|
+
|
|
969
|
+
Connect your team's Slack workspace to chat with the AI assistant via @mentions.
|
|
970
|
+
|
|
971
|
+
### Configuration
|
|
972
|
+
|
|
973
|
+
```typescript
|
|
974
|
+
slack: {
|
|
975
|
+
enabled: true,
|
|
976
|
+
clientIdEnvVar: 'SLACK_CLIENT_ID',
|
|
977
|
+
clientSecretEnvVar: 'SLACK_CLIENT_SECRET',
|
|
978
|
+
signingSecretEnvVar: 'SLACK_SIGNING_SECRET',
|
|
979
|
+
internalSecretEnvVar: 'SLACK_INTERNAL_SECRET',
|
|
980
|
+
|
|
981
|
+
// Optional: Restrict to specific plans
|
|
982
|
+
allowedPlans: ['pro', 'enterprise'],
|
|
983
|
+
|
|
984
|
+
aiChat: {
|
|
985
|
+
enabled: true,
|
|
986
|
+
threadContinuity: true, // Maintain context across Slack thread replies
|
|
987
|
+
},
|
|
988
|
+
|
|
989
|
+
notifications: {
|
|
990
|
+
events: [
|
|
991
|
+
{ event: 'thread_shared', enabled: true },
|
|
992
|
+
{ event: 'message_liked', enabled: true },
|
|
993
|
+
{ event: 'team_member_joined', enabled: true },
|
|
994
|
+
],
|
|
995
|
+
},
|
|
996
|
+
}
|
|
997
|
+
```
|
|
998
|
+
|
|
999
|
+
### Environment Variables
|
|
1000
|
+
|
|
1001
|
+
| Variable | Description |
|
|
1002
|
+
|----------|-------------|
|
|
1003
|
+
| `SLACK_CLIENT_ID` | OAuth Client ID from your Slack app |
|
|
1004
|
+
| `SLACK_CLIENT_SECRET` | OAuth Client Secret from your Slack app |
|
|
1005
|
+
| `SLACK_SIGNING_SECRET` | Signing secret for request verification |
|
|
1006
|
+
| `SLACK_INTERNAL_SECRET` | Random secret for internal endpoint auth |
|
|
1007
|
+
|
|
1008
|
+
### Key Features
|
|
1009
|
+
|
|
1010
|
+
- **AI Chat via @mentions**: Team members mention the bot in Slack to get AI responses
|
|
1011
|
+
- **Thread Continuity**: Follow-up messages in a Slack thread maintain conversation context
|
|
1012
|
+
- **Team Notifications**: Get notified when threads are shared, messages are liked, or members join
|
|
1013
|
+
- **Per-Team Connection**: Each team connects their own Slack workspace
|
|
1014
|
+
|
|
1015
|
+
See [Slack Integration](./slack.md) for setup instructions and full documentation.
|
|
1016
|
+
|
|
1017
|
+
---
|
|
1018
|
+
|
|
1019
|
+
## Email
|
|
1020
|
+
|
|
1021
|
+
Transactional email support for email verification, team invitations, and notifications.
|
|
1022
|
+
|
|
1023
|
+
### Configuration
|
|
1024
|
+
|
|
1025
|
+
```typescript
|
|
1026
|
+
email: {
|
|
1027
|
+
enabled: true,
|
|
1028
|
+
providerConfig: {
|
|
1029
|
+
type: 'ses',
|
|
1030
|
+
region: 'us-east-1',
|
|
1031
|
+
},
|
|
1032
|
+
fromAddress: 'noreply@example.com',
|
|
1033
|
+
fromName: 'My App',
|
|
1034
|
+
}
|
|
1035
|
+
```
|
|
1036
|
+
|
|
1037
|
+
### AWS Credentials
|
|
1038
|
+
|
|
1039
|
+
The SES provider uses the AWS SDK's default credential chain, which automatically checks (in order):
|
|
1040
|
+
|
|
1041
|
+
1. **Environment variables** - `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`
|
|
1042
|
+
2. **Shared credentials file** - `~/.aws/credentials`
|
|
1043
|
+
3. **ECS container credentials** - Task IAM role
|
|
1044
|
+
4. **EC2 instance metadata** - Instance IAM role
|
|
1045
|
+
5. **Web identity token** - For EKS pods
|
|
1046
|
+
|
|
1047
|
+
**For local development**, set environment variables in `.env`:
|
|
1048
|
+
```
|
|
1049
|
+
AWS_ACCESS_KEY_ID=your-access-key
|
|
1050
|
+
AWS_SECRET_ACCESS_KEY=your-secret-key
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
**For production on AWS**, use IAM roles (recommended):
|
|
1054
|
+
- EC2: Attach an IAM role with SES permissions to your instance
|
|
1055
|
+
- ECS: Configure a task IAM role with SES permissions
|
|
1056
|
+
- Lambda: The execution role needs SES permissions
|
|
1057
|
+
|
|
1058
|
+
No explicit credentials are needed when using IAM roles - the SDK discovers them automatically.
|
|
1059
|
+
|
|
1060
|
+
### Supported Providers
|
|
1061
|
+
|
|
1062
|
+
Currently supported:
|
|
1063
|
+
- **SES** (Amazon Simple Email Service)
|
|
1064
|
+
|
|
1065
|
+
Future providers (not yet implemented):
|
|
1066
|
+
- Resend
|
|
1067
|
+
- SendGrid
|
|
1068
|
+
- Postmark
|
|
1069
|
+
|
|
1070
|
+
### Email Features
|
|
1071
|
+
|
|
1072
|
+
When email is configured, the following features are available:
|
|
1073
|
+
|
|
1074
|
+
| Feature | Description |
|
|
1075
|
+
|---------|-------------|
|
|
1076
|
+
| **Email Verification** | 6-digit codes sent to verify new user emails |
|
|
1077
|
+
| **Team Invitations** | Invitation emails when users are invited to teams |
|
|
1078
|
+
| **Magic Links** | Login links sent via email (existing feature) |
|
|
1079
|
+
|
|
1080
|
+
### Graceful Degradation
|
|
1081
|
+
|
|
1082
|
+
Email features gracefully handle the case where email is not configured:
|
|
1083
|
+
- **Email Verification**: Users are auto-verified on registration
|
|
1084
|
+
- **Team Invitations**: Invite URL is returned but no email sent
|
|
1085
|
+
- **Magic Links**: Link is logged to console in development
|
|
1086
|
+
|
|
1087
|
+
This allows you to develop locally without email setup and add it when deploying.
|
|
1088
|
+
|
|
1089
|
+
### Testing Email
|
|
1090
|
+
|
|
1091
|
+
In development, when email is not configured, verification codes and invitation URLs are logged to the console:
|
|
1092
|
+
|
|
1093
|
+
```
|
|
1094
|
+
[Auth] Email disabled - verification code for user@example.com: 123456
|
|
1095
|
+
[Teams] Email disabled - invitation URL for user@example.com: http://localhost:5173/invite/abc123
|
|
1096
|
+
```
|
|
1097
|
+
|
|
1098
|
+
### API Endpoints
|
|
1099
|
+
|
|
1100
|
+
| Method | Endpoint | Description |
|
|
1101
|
+
|--------|----------|-------------|
|
|
1102
|
+
| `POST` | `/api/auth/verify-email` | Verify email with 6-digit code |
|
|
1103
|
+
| `POST` | `/api/auth/resend-verification` | Resend verification email |
|
|
1104
|
+
|
|
1105
|
+
### Database Schema
|
|
1106
|
+
|
|
1107
|
+
```prisma
|
|
1108
|
+
model EmailVerification {
|
|
1109
|
+
id String @id @default(cuid())
|
|
1110
|
+
code String // Hashed 6-digit code
|
|
1111
|
+
userId String
|
|
1112
|
+
user User @relation(...)
|
|
1113
|
+
expiresAt DateTime
|
|
1114
|
+
usedAt DateTime?
|
|
1115
|
+
attempts Int @default(0) // Brute force protection
|
|
1116
|
+
createdAt DateTime @default(now())
|
|
1117
|
+
}
|
|
1118
|
+
```
|
|
1119
|
+
|
|
1120
|
+
---
|
|
1121
|
+
|
|
1122
|
+
## Job Queue
|
|
1123
|
+
|
|
1124
|
+
Background job processing for async tasks, scheduled jobs, and recurring workflows.
|
|
1125
|
+
|
|
1126
|
+
### Configuration
|
|
1127
|
+
|
|
1128
|
+
```typescript
|
|
1129
|
+
queue: {
|
|
1130
|
+
enabled: true,
|
|
1131
|
+
|
|
1132
|
+
// Provider: 'memory' for dev, 'sqs' for production
|
|
1133
|
+
providerConfig: {
|
|
1134
|
+
type: 'memory',
|
|
1135
|
+
maxHistorySize: 1000,
|
|
1136
|
+
},
|
|
1137
|
+
// Or for production:
|
|
1138
|
+
// providerConfig: {
|
|
1139
|
+
// type: 'sqs',
|
|
1140
|
+
// region: 'us-east-1',
|
|
1141
|
+
// queueUrl: process.env.SQS_QUEUE_URL!,
|
|
1142
|
+
// deadLetterQueueUrl: process.env.SQS_DLQ_URL,
|
|
1143
|
+
// visibilityTimeout: 60,
|
|
1144
|
+
// },
|
|
1145
|
+
|
|
1146
|
+
worker: {
|
|
1147
|
+
mode: 'in-process', // 'in-process' | 'standalone'
|
|
1148
|
+
concurrency: 5,
|
|
1149
|
+
pollInterval: 1000,
|
|
1150
|
+
shutdownTimeout: 30000,
|
|
1151
|
+
},
|
|
1152
|
+
|
|
1153
|
+
scheduler: {
|
|
1154
|
+
enabled: true,
|
|
1155
|
+
pollInterval: 60000,
|
|
1156
|
+
},
|
|
1157
|
+
}
|
|
1158
|
+
```
|
|
1159
|
+
|
|
1160
|
+
### Configuration Options
|
|
1161
|
+
|
|
1162
|
+
| Option | Type | Default | Description |
|
|
1163
|
+
|--------|------|---------|-------------|
|
|
1164
|
+
| `enabled` | boolean | `false` | Enable the queue system |
|
|
1165
|
+
| `providerConfig.type` | `'memory'` \| `'sqs'` | - | Queue backend |
|
|
1166
|
+
| `worker.mode` | `'in-process'` \| `'standalone'` | `'in-process'` | Run workers in server process or separately |
|
|
1167
|
+
| `worker.concurrency` | number | `5` | Concurrent jobs per worker |
|
|
1168
|
+
| `scheduler.enabled` | boolean | `false` | Enable database-backed job scheduling |
|
|
1169
|
+
|
|
1170
|
+
See [Job Queue](./queue.md) for full documentation on handlers, scheduling, and production deployment.
|
|
1171
|
+
|
|
1172
|
+
---
|
|
1173
|
+
|
|
1174
|
+
## Scheduled Prompts (Automations)
|
|
1175
|
+
|
|
1176
|
+
Run AI prompts automatically on a schedule with notifications.
|
|
1177
|
+
|
|
1178
|
+
### Configuration
|
|
1179
|
+
|
|
1180
|
+
```typescript
|
|
1181
|
+
scheduledPrompts: {
|
|
1182
|
+
enabled: true,
|
|
1183
|
+
featureName: 'Automations', // Display name in UI
|
|
1184
|
+
allowUserPrompts: true, // Personal automations
|
|
1185
|
+
allowTeamPrompts: true, // Team automations
|
|
1186
|
+
defaultTimezone: 'UTC',
|
|
1187
|
+
|
|
1188
|
+
// Plan-based limits
|
|
1189
|
+
planLimits: [
|
|
1190
|
+
{ plan: 'free', maxUserPrompts: 1, maxTeamPrompts: 0 },
|
|
1191
|
+
{ plan: 'pro', maxUserPrompts: 5, maxTeamPrompts: 10 },
|
|
1192
|
+
{ plan: 'enterprise', maxUserPrompts: 20, maxTeamPrompts: 50 },
|
|
1193
|
+
],
|
|
1194
|
+
defaultMaxUserPrompts: 0, // Fallback for unlisted plans
|
|
1195
|
+
defaultMaxTeamPrompts: 0,
|
|
1196
|
+
}
|
|
1197
|
+
```
|
|
1198
|
+
|
|
1199
|
+
### Configuration Options
|
|
1200
|
+
|
|
1201
|
+
| Option | Type | Default | Description |
|
|
1202
|
+
|--------|------|---------|-------------|
|
|
1203
|
+
| `enabled` | boolean | `false` | Enable scheduled prompts |
|
|
1204
|
+
| `featureName` | string | `"Scheduled Prompts"` | Display name in sidebar |
|
|
1205
|
+
| `allowUserPrompts` | boolean | `true` | Allow personal automations |
|
|
1206
|
+
| `allowTeamPrompts` | boolean | `true` | Allow team automations |
|
|
1207
|
+
| `defaultTimezone` | string | `"UTC"` | Default timezone for new prompts |
|
|
1208
|
+
| `planLimits` | array | `[]` | Limits per subscription plan |
|
|
1209
|
+
|
|
1210
|
+
**Note:** Scheduled prompts require the [Job Queue](#job-queue) to be enabled.
|
|
1211
|
+
|
|
1212
|
+
See [Scheduled Prompts](./scheduled-prompts.md) for full documentation on creating automations and notifications.
|