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,411 @@
|
|
|
1
|
+
# Development
|
|
2
|
+
|
|
3
|
+
This guide covers the development workflow for ChaasKit projects.
|
|
4
|
+
|
|
5
|
+
## Starting Development
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# In your project directory
|
|
9
|
+
pnpm dev
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
This starts the React Router v7 dev server with HMR at `http://localhost:5173`, which proxies API requests to the Express backend at `http://localhost:3000`.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Project Structure
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
my-app/
|
|
20
|
+
├── app/
|
|
21
|
+
│ ├── routes/ # React Router v7 routes
|
|
22
|
+
│ │ ├── _index.tsx # Landing page (/)
|
|
23
|
+
│ │ ├── login.tsx # Login page (/login)
|
|
24
|
+
│ │ ├── register.tsx # Registration (/register)
|
|
25
|
+
│ │ ├── chat._index.tsx # Main chat (/chat)
|
|
26
|
+
│ │ ├── chat.thread.$threadId.tsx # Thread view
|
|
27
|
+
│ │ ├── chat.documents.tsx # Documents (/chat/documents)
|
|
28
|
+
│ │ ├── chat.api-keys.tsx # API Keys (/chat/api-keys)
|
|
29
|
+
│ │ └── ...
|
|
30
|
+
│ ├── components/ # Client wrapper components
|
|
31
|
+
│ │ ├── ChatClient.tsx # Chat page client wrapper
|
|
32
|
+
│ │ └── ClientOnly.tsx # SSR boundary component
|
|
33
|
+
│ ├── root.tsx # HTML shell, theme, providers
|
|
34
|
+
│ ├── routes.ts # Route configuration
|
|
35
|
+
│ ├── entry.client.tsx # Client hydration
|
|
36
|
+
│ └── entry.server.tsx # Server rendering
|
|
37
|
+
├── config/
|
|
38
|
+
│ └── app.config.ts # Application configuration
|
|
39
|
+
├── extensions/
|
|
40
|
+
│ ├── agents/ # Custom AI agents
|
|
41
|
+
│ ├── payment-plans/ # Custom pricing plans
|
|
42
|
+
│ └── pages/ # Custom frontend pages
|
|
43
|
+
├── prisma/
|
|
44
|
+
│ └── schema/
|
|
45
|
+
│ ├── base.prisma # ChaasKit models (synced)
|
|
46
|
+
│ └── custom.prisma # Your custom models
|
|
47
|
+
├── public/
|
|
48
|
+
│ ├── logo.svg # Your logo
|
|
49
|
+
│ └── favicon.svg # Favicon
|
|
50
|
+
├── .env # Environment variables
|
|
51
|
+
├── server.js # Production server
|
|
52
|
+
├── vite.config.ts # Vite configuration
|
|
53
|
+
├── react-router.config.ts # React Router configuration
|
|
54
|
+
└── package.json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Commands
|
|
60
|
+
|
|
61
|
+
### Development
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pnpm dev # Start dev server with HMR
|
|
65
|
+
pnpm build # Build for production
|
|
66
|
+
pnpm typecheck # Run TypeScript checks
|
|
67
|
+
pnpm start # Start production server
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Database
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pnpm db:generate # Generate Prisma client
|
|
74
|
+
pnpm db:push # Push schema changes (dev)
|
|
75
|
+
pnpm db:migrate # Create and run migrations (prod)
|
|
76
|
+
pnpm db:studio # Open Prisma Studio
|
|
77
|
+
pnpm db:sync # Sync base.prisma from @chaaskit/db
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Common Tasks
|
|
83
|
+
|
|
84
|
+
### Customize Configuration
|
|
85
|
+
|
|
86
|
+
Edit `config/app.config.ts`:
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import type { AppConfig } from '@chaaskit/shared';
|
|
90
|
+
|
|
91
|
+
export const config: AppConfig = {
|
|
92
|
+
app: {
|
|
93
|
+
name: 'My App',
|
|
94
|
+
description: 'My AI chat application',
|
|
95
|
+
url: 'http://localhost:5173',
|
|
96
|
+
basePath: '/chat',
|
|
97
|
+
},
|
|
98
|
+
agent: {
|
|
99
|
+
type: 'built-in',
|
|
100
|
+
provider: 'anthropic',
|
|
101
|
+
model: 'claude-sonnet-4-20250514',
|
|
102
|
+
systemPrompt: 'You are a helpful assistant.',
|
|
103
|
+
},
|
|
104
|
+
// ... other options
|
|
105
|
+
};
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The server automatically reloads when config changes.
|
|
109
|
+
|
|
110
|
+
### Add a Custom Agent
|
|
111
|
+
|
|
112
|
+
Create `extensions/agents/my-agent.ts`:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { BaseAgent, registry } from '@chaaskit/server';
|
|
116
|
+
|
|
117
|
+
export class MyAgent extends BaseAgent {
|
|
118
|
+
async *chat(messages, options) {
|
|
119
|
+
yield { type: 'text', content: 'Hello!' };
|
|
120
|
+
yield { type: 'done' };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
registry.register('agent', 'my-agent', MyAgent);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Then reference it in config:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
agent: {
|
|
131
|
+
type: 'custom',
|
|
132
|
+
agentId: 'my-agent',
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Add a Custom Route
|
|
137
|
+
|
|
138
|
+
Create a new route file in `app/routes/`. React Router v7 uses file-based routing:
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
// app/routes/chat.my-page.tsx
|
|
142
|
+
// This creates a route at /chat/my-page
|
|
143
|
+
|
|
144
|
+
import { ChatProviders } from '@chaaskit/client';
|
|
145
|
+
|
|
146
|
+
export default function MyPage() {
|
|
147
|
+
return (
|
|
148
|
+
<ChatProviders>
|
|
149
|
+
<div className="min-h-screen bg-background p-8">
|
|
150
|
+
<h1 className="text-2xl font-bold text-text-primary">
|
|
151
|
+
My Custom Page
|
|
152
|
+
</h1>
|
|
153
|
+
</div>
|
|
154
|
+
</ChatProviders>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
For pages that need data loading:
|
|
160
|
+
|
|
161
|
+
```tsx
|
|
162
|
+
// app/routes/chat.stats.tsx
|
|
163
|
+
import type { Route } from './+types/chat.stats';
|
|
164
|
+
import { ChatProviders } from '@chaaskit/client';
|
|
165
|
+
|
|
166
|
+
export async function loader({ request }: Route.LoaderArgs) {
|
|
167
|
+
// Server-side data loading
|
|
168
|
+
return { stats: { threads: 42 } };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export default function StatsPage({ loaderData }: Route.ComponentProps) {
|
|
172
|
+
return (
|
|
173
|
+
<ChatProviders>
|
|
174
|
+
<div className="p-8">
|
|
175
|
+
<h1>Stats</h1>
|
|
176
|
+
<p>Total threads: {loaderData.stats.threads}</p>
|
|
177
|
+
</div>
|
|
178
|
+
</ChatProviders>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Add a Custom Database Model
|
|
184
|
+
|
|
185
|
+
1. Edit `prisma/schema/custom.prisma`:
|
|
186
|
+
|
|
187
|
+
```prisma
|
|
188
|
+
model MyModel {
|
|
189
|
+
id String @id @default(cuid())
|
|
190
|
+
name String
|
|
191
|
+
userId String
|
|
192
|
+
user User @relation(fields: [userId], references: [id])
|
|
193
|
+
createdAt DateTime @default(now())
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
2. Apply changes:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
pnpm db:push # Development
|
|
201
|
+
pnpm db:generate # Regenerate client
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
3. Use in your code:
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
import { db } from '@chaaskit/db';
|
|
208
|
+
|
|
209
|
+
const items = await db.myModel.findMany({
|
|
210
|
+
where: { userId: user.id }
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Adding Custom API Routes
|
|
217
|
+
|
|
218
|
+
Create a custom server entry point to add routes alongside ChaasKit's API.
|
|
219
|
+
|
|
220
|
+
### Custom Server
|
|
221
|
+
|
|
222
|
+
Create `src/server.ts`:
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
import { createApp } from '@chaaskit/server';
|
|
226
|
+
import { Router } from 'express';
|
|
227
|
+
import { config } from '../config/app.config.js';
|
|
228
|
+
|
|
229
|
+
async function start() {
|
|
230
|
+
const app = await createApp({ config });
|
|
231
|
+
|
|
232
|
+
// Add custom routes
|
|
233
|
+
const customRouter = Router();
|
|
234
|
+
|
|
235
|
+
customRouter.get('/api/custom/hello', (req, res) => {
|
|
236
|
+
res.json({ message: 'Hello!' });
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
app.use(customRouter);
|
|
240
|
+
|
|
241
|
+
const port = process.env.PORT || 3000;
|
|
242
|
+
app.listen(port, () => {
|
|
243
|
+
console.log(`Server running on port ${port}`);
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
start().catch(console.error);
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Using Auth Middleware
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
import { requireAuth, optionalAuth } from '@chaaskit/server';
|
|
254
|
+
|
|
255
|
+
// Protected route
|
|
256
|
+
customRouter.get('/api/custom/profile', requireAuth, (req, res) => {
|
|
257
|
+
res.json({
|
|
258
|
+
userId: req.user!.id,
|
|
259
|
+
email: req.user!.email,
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// Optional auth
|
|
264
|
+
customRouter.get('/api/custom/public', optionalAuth, (req, res) => {
|
|
265
|
+
if (req.user) {
|
|
266
|
+
res.json({ greeting: `Hello, ${req.user.email}!` });
|
|
267
|
+
} else {
|
|
268
|
+
res.json({ greeting: 'Hello, guest!' });
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Accessing the Database
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
import { db } from '@chaaskit/db';
|
|
277
|
+
import { requireAuth } from '@chaaskit/server';
|
|
278
|
+
|
|
279
|
+
customRouter.get('/api/custom/stats', requireAuth, async (req, res) => {
|
|
280
|
+
const threadCount = await db.thread.count({
|
|
281
|
+
where: { userId: req.user!.id },
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
res.json({ threads: threadCount });
|
|
285
|
+
});
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Route Naming Convention
|
|
291
|
+
|
|
292
|
+
React Router v7 uses dot notation for nested routes:
|
|
293
|
+
|
|
294
|
+
| File | URL Path |
|
|
295
|
+
|------|----------|
|
|
296
|
+
| `app/routes/_index.tsx` | `/` |
|
|
297
|
+
| `app/routes/login.tsx` | `/login` |
|
|
298
|
+
| `app/routes/chat._index.tsx` | `/chat` |
|
|
299
|
+
| `app/routes/chat.thread.$threadId.tsx` | `/chat/thread/:threadId` |
|
|
300
|
+
| `app/routes/chat.documents.tsx` | `/chat/documents` |
|
|
301
|
+
| `app/routes/shared.$shareId.tsx` | `/shared/:shareId` |
|
|
302
|
+
|
|
303
|
+
The `$` prefix creates dynamic segments. The `_index` suffix creates index routes.
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Client-Side Navigation
|
|
308
|
+
|
|
309
|
+
Use `useAppPath` for navigation that respects `basePath`:
|
|
310
|
+
|
|
311
|
+
```tsx
|
|
312
|
+
import { useAppPath } from '@chaaskit/client';
|
|
313
|
+
import { Link } from 'react-router';
|
|
314
|
+
|
|
315
|
+
function MyComponent() {
|
|
316
|
+
const appPath = useAppPath();
|
|
317
|
+
|
|
318
|
+
return (
|
|
319
|
+
<Link to={appPath('/documents')}>
|
|
320
|
+
Go to Documents
|
|
321
|
+
</Link>
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
This ensures links work correctly whether `basePath` is `/` or `/chat`.
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## Debugging
|
|
331
|
+
|
|
332
|
+
### Server Logs
|
|
333
|
+
|
|
334
|
+
Watch the terminal for:
|
|
335
|
+
- Request logs: `GET /api/threads 200 15ms`
|
|
336
|
+
- Config loading: `[Config] Loaded from ./config/app.config.ts`
|
|
337
|
+
- Extension loading: `[Extensions] Loaded: extensions/agents/my-agent.ts`
|
|
338
|
+
- Errors with stack traces
|
|
339
|
+
|
|
340
|
+
### Database Inspection
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
pnpm db:studio # Opens at http://localhost:5555
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Frontend DevTools
|
|
347
|
+
|
|
348
|
+
- React DevTools for component inspection
|
|
349
|
+
- Network tab for API requests
|
|
350
|
+
- Console for errors
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## Type Checking
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
pnpm typecheck
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
This runs TypeScript across all files to catch type errors.
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Network Access
|
|
365
|
+
|
|
366
|
+
To access from other devices on your network:
|
|
367
|
+
|
|
368
|
+
1. The dev server exposes on `0.0.0.0:5173` via the `--host` flag
|
|
369
|
+
2. Add allowed hostnames to `vite.config.ts`:
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
server: {
|
|
373
|
+
host: true,
|
|
374
|
+
allowedHosts: ['my-machine.local', '192.168.1.100'],
|
|
375
|
+
}
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## Monorepo Development
|
|
381
|
+
|
|
382
|
+
If you're contributing to ChaasKit itself, see the main repository's CLAUDE.md for monorepo-specific instructions.
|
|
383
|
+
|
|
384
|
+
### Building Packages
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
pnpm build
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Linking for Local Development
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
# In the chaaskit monorepo
|
|
394
|
+
pnpm build
|
|
395
|
+
pnpm -r exec pnpm link --global
|
|
396
|
+
|
|
397
|
+
# In your test project
|
|
398
|
+
pnpm link --global @chaaskit/server @chaaskit/client @chaaskit/db @chaaskit/shared
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### Testing the CLI
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
# Build and run directly
|
|
405
|
+
cd packages/create-chaaskit
|
|
406
|
+
pnpm build
|
|
407
|
+
node dist/index.js create my-test-app --skip-install
|
|
408
|
+
|
|
409
|
+
# Or use the test script
|
|
410
|
+
./scripts/create-test-project.sh
|
|
411
|
+
```
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# Mentionable Documents
|
|
2
|
+
|
|
3
|
+
Mentionable documents allow users to reference stored content in chat using @-mention syntax. Documents are organized by scope (personal, team, or project) and can be automatically injected into the AI context or accessed via tools.
|
|
4
|
+
|
|
5
|
+
File attachments in chat also use this system - when you attach a file to a message, it's uploaded as a document and automatically @-mentioned.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
1. Enable documents in your config:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
// config/app.config.ts
|
|
13
|
+
documents: {
|
|
14
|
+
enabled: true,
|
|
15
|
+
storage: { provider: 'database' },
|
|
16
|
+
maxFileSizeMB: 10,
|
|
17
|
+
hybridThreshold: 1000,
|
|
18
|
+
acceptedTypes: ['text/plain', 'text/markdown', 'text/x-markdown', 'text/csv', 'application/json'],
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
2. Create or upload documents via the Documents page (`/documents`)
|
|
23
|
+
3. Reference documents in chat using `@my/document-name` syntax
|
|
24
|
+
|
|
25
|
+
## Mention Syntax
|
|
26
|
+
|
|
27
|
+
Documents are referenced using scoped paths:
|
|
28
|
+
|
|
29
|
+
| Scope | Syntax | Example |
|
|
30
|
+
|-------|--------|---------|
|
|
31
|
+
| Personal | `@my/<name>` | `@my/api-guidelines` |
|
|
32
|
+
| Team | `@team/<slug>/<name>` | `@team/engineering/style-guide` |
|
|
33
|
+
| Project | `@project/<slug>/<name>` | `@project/acme/requirements` |
|
|
34
|
+
|
|
35
|
+
Document names should be lowercase with hyphens (e.g., `api-guidelines`, `meeting-notes`).
|
|
36
|
+
|
|
37
|
+
## How It Works
|
|
38
|
+
|
|
39
|
+
### Hybrid Access Model
|
|
40
|
+
|
|
41
|
+
Documents use a hybrid approach based on size:
|
|
42
|
+
|
|
43
|
+
- **Small documents** (under `hybridThreshold` chars): Content is automatically injected into the AI context when mentioned
|
|
44
|
+
- **Large documents** (over threshold): AI receives tools to read, search, and list document contents
|
|
45
|
+
|
|
46
|
+
This balances context efficiency with full access to large documents.
|
|
47
|
+
|
|
48
|
+
### Document Scopes
|
|
49
|
+
|
|
50
|
+
| Scope | Access | Use Case |
|
|
51
|
+
|-------|--------|----------|
|
|
52
|
+
| **Personal** (`my`) | Only the owner | Personal notes, private references |
|
|
53
|
+
| **Team** | All team members | Shared team knowledge, guidelines |
|
|
54
|
+
| **Project** | Project participants | Project-specific documentation |
|
|
55
|
+
|
|
56
|
+
## Configuration
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
interface DocumentsConfig {
|
|
60
|
+
enabled: boolean;
|
|
61
|
+
storage: {
|
|
62
|
+
provider: 'database' | 'filesystem' | 's3';
|
|
63
|
+
filesystem?: { basePath: string };
|
|
64
|
+
s3?: { bucket: string; region: string; endpoint?: string };
|
|
65
|
+
};
|
|
66
|
+
maxFileSizeMB: number;
|
|
67
|
+
hybridThreshold: number; // Character count threshold for context injection
|
|
68
|
+
acceptedTypes: string[]; // MIME types
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Storage Providers
|
|
73
|
+
|
|
74
|
+
**Database (default)** - Content stored in the Document table. Best for small to medium documents.
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
storage: { provider: 'database' }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Filesystem** - Content stored on disk. Good for larger files or when you need direct file access.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
storage: {
|
|
84
|
+
provider: 'filesystem',
|
|
85
|
+
filesystem: { basePath: './uploads/documents' }
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**S3** - Content stored in S3-compatible storage. Best for production deployments.
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
storage: {
|
|
93
|
+
provider: 's3',
|
|
94
|
+
s3: {
|
|
95
|
+
bucket: 'my-documents-bucket',
|
|
96
|
+
region: 'us-east-1',
|
|
97
|
+
endpoint: 'https://s3.amazonaws.com' // Optional, for S3-compatible services
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Accepted File Types
|
|
103
|
+
|
|
104
|
+
The `acceptedTypes` array specifies which MIME types can be uploaded. Default types:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
acceptedTypes: [
|
|
108
|
+
'text/plain', // .txt files
|
|
109
|
+
'text/markdown', // .md files
|
|
110
|
+
'text/x-markdown', // .md files (alternate MIME type)
|
|
111
|
+
'text/csv', // .csv files
|
|
112
|
+
'application/json', // .json files
|
|
113
|
+
]
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Hybrid Threshold
|
|
117
|
+
|
|
118
|
+
The `hybridThreshold` controls when documents are injected vs accessed via tools:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
hybridThreshold: 1000 // Characters
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
- Documents with `charCount <= 1000`: Injected directly into AI context
|
|
125
|
+
- Documents with `charCount > 1000`: AI uses tools to read content
|
|
126
|
+
|
|
127
|
+
Adjust based on your typical document sizes and context budget.
|
|
128
|
+
|
|
129
|
+
## AI Tools
|
|
130
|
+
|
|
131
|
+
When large documents are mentioned, the AI receives these tools:
|
|
132
|
+
|
|
133
|
+
### `list_documents`
|
|
134
|
+
Lists available documents, optionally filtered by query or scope.
|
|
135
|
+
|
|
136
|
+
### `read_document`
|
|
137
|
+
Reads content from a document with pagination support.
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
{
|
|
141
|
+
path: '@my/api-guidelines',
|
|
142
|
+
offset: 0, // Start line
|
|
143
|
+
limit: 100 // Max lines
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### `search_in_document`
|
|
148
|
+
Searches for text within a document.
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
{
|
|
152
|
+
path: '@my/api-guidelines',
|
|
153
|
+
query: 'authentication',
|
|
154
|
+
context_lines: 3
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### `save_document`
|
|
159
|
+
Saves AI-generated content as a new document.
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
{
|
|
163
|
+
name: 'meeting-summary',
|
|
164
|
+
content: '...',
|
|
165
|
+
scope: 'my' // or 'team', 'project'
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## API Endpoints
|
|
170
|
+
|
|
171
|
+
| Endpoint | Method | Description |
|
|
172
|
+
|----------|--------|-------------|
|
|
173
|
+
| `/api/documents` | GET | List documents |
|
|
174
|
+
| `/api/documents` | POST | Create text document |
|
|
175
|
+
| `/api/documents/upload` | POST | Upload file |
|
|
176
|
+
| `/api/documents/:id` | GET | Get document metadata |
|
|
177
|
+
| `/api/documents/:id` | PATCH | Update document |
|
|
178
|
+
| `/api/documents/:id` | DELETE | Archive document |
|
|
179
|
+
| `/api/documents/:id/content` | GET | Get document content |
|
|
180
|
+
| `/api/mentions/search` | GET | Search mentionable documents |
|
|
181
|
+
| `/api/mentions/resolve` | POST | Resolve mention paths |
|
|
182
|
+
|
|
183
|
+
## File Attachments in Chat
|
|
184
|
+
|
|
185
|
+
The chat file attachment button (paperclip icon) uploads files as documents and automatically @-mentions them in your message. This provides a unified experience:
|
|
186
|
+
|
|
187
|
+
1. Click the attachment icon in the chat input
|
|
188
|
+
2. Select one or more files
|
|
189
|
+
3. Files are uploaded as documents to your personal scope (or team/project if selected)
|
|
190
|
+
4. @-mentions are automatically appended to your message
|
|
191
|
+
|
|
192
|
+
For example, attaching `report.csv` will:
|
|
193
|
+
- Create a document at `@my/report`
|
|
194
|
+
- Append `@my/report` to your message
|
|
195
|
+
- The AI can then access the document content via the hybrid system
|
|
196
|
+
|
|
197
|
+
**Note**: The attachment button only appears when documents are enabled in configuration.
|
|
198
|
+
|
|
199
|
+
## Frontend Components
|
|
200
|
+
|
|
201
|
+
### Documents Page
|
|
202
|
+
|
|
203
|
+
Access via `/documents` or the sidebar link. Features:
|
|
204
|
+
|
|
205
|
+
- Create text documents inline
|
|
206
|
+
- Upload files (drag & drop supported)
|
|
207
|
+
- View, edit, and delete documents
|
|
208
|
+
- Filter by scope and search by name
|
|
209
|
+
|
|
210
|
+
### Mention Input
|
|
211
|
+
|
|
212
|
+
When typing in chat:
|
|
213
|
+
|
|
214
|
+
1. Type `@` to trigger the mention dropdown
|
|
215
|
+
2. Continue typing to filter documents
|
|
216
|
+
3. Use arrow keys to navigate, Enter to select
|
|
217
|
+
4. Selected document path is inserted into the message
|
|
218
|
+
|
|
219
|
+
### Mention Chips
|
|
220
|
+
|
|
221
|
+
Document mentions in messages render as styled chips showing:
|
|
222
|
+
|
|
223
|
+
- Scope icon (user/team/project)
|
|
224
|
+
- Document name
|
|
225
|
+
- Full path on hover
|
|
226
|
+
|
|
227
|
+
## Database Schema
|
|
228
|
+
|
|
229
|
+
```prisma
|
|
230
|
+
model Document {
|
|
231
|
+
id String @id @default(cuid())
|
|
232
|
+
name String
|
|
233
|
+
content String? @db.Text
|
|
234
|
+
storageKey String?
|
|
235
|
+
mimeType String @default("text/plain")
|
|
236
|
+
fileSize Int @default(0)
|
|
237
|
+
charCount Int @default(0)
|
|
238
|
+
|
|
239
|
+
userId String
|
|
240
|
+
user User @relation(...)
|
|
241
|
+
teamId String?
|
|
242
|
+
team Team? @relation(...)
|
|
243
|
+
projectId String?
|
|
244
|
+
project Project? @relation(...)
|
|
245
|
+
|
|
246
|
+
createdAt DateTime @default(now())
|
|
247
|
+
updatedAt DateTime @updatedAt
|
|
248
|
+
archivedAt DateTime?
|
|
249
|
+
|
|
250
|
+
@@unique([userId, name, teamId, projectId])
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Text Extraction
|
|
255
|
+
|
|
256
|
+
Documents are processed to extract plain text for AI consumption:
|
|
257
|
+
|
|
258
|
+
| File Type | Handling |
|
|
259
|
+
|-----------|----------|
|
|
260
|
+
| Plain text (.txt) | Passthrough |
|
|
261
|
+
| Markdown (.md) | Passthrough |
|
|
262
|
+
| CSV (.csv) | Converted to readable table format |
|
|
263
|
+
| JSON (.json) | Passthrough |
|
|
264
|
+
|
|
265
|
+
The extractor system is extensible. Future versions may support PDF, DOCX, and XLSX.
|
|
266
|
+
|
|
267
|
+
## Best Practices
|
|
268
|
+
|
|
269
|
+
1. **Use descriptive names**: `api-authentication-guide` is better than `doc1`
|
|
270
|
+
2. **Keep documents focused**: One topic per document improves mention relevance
|
|
271
|
+
3. **Set appropriate scope**: Use team/project scope for shared knowledge
|
|
272
|
+
4. **Consider document size**: Very large documents may be slow to search
|
|
273
|
+
5. **Update regularly**: Keep referenced documents current
|
|
274
|
+
|
|
275
|
+
## Troubleshooting
|
|
276
|
+
|
|
277
|
+
### Documents not appearing in mentions
|
|
278
|
+
|
|
279
|
+
- Verify documents feature is enabled in config
|
|
280
|
+
- Check that the document isn't archived
|
|
281
|
+
- Ensure you have access to the document's scope
|
|
282
|
+
|
|
283
|
+
### Upload fails
|
|
284
|
+
|
|
285
|
+
- Check file size against `maxFileSizeMB`
|
|
286
|
+
- Verify MIME type is in `acceptedTypes`
|
|
287
|
+
- Check server logs for detailed errors
|
|
288
|
+
|
|
289
|
+
### AI not reading document content
|
|
290
|
+
|
|
291
|
+
- For large documents, ensure the AI is using the `read_document` tool
|
|
292
|
+
- Check that document tools are registered (visible in tool calls)
|
|
293
|
+
- Verify the document path is correct in the mention
|