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,466 @@
1
+ # Custom Pages
2
+
3
+ This guide explains how to add custom pages (marketing pages, landing pages, documentation, etc.) to your ChaasKit application using React Router v7's file-based routing.
4
+
5
+ ## Architecture Overview
6
+
7
+ ChaasKit uses React Router v7 framework mode with file-based routing. Pages are created by adding files to the `app/routes/` directory:
8
+
9
+ ```
10
+ app/routes/
11
+ ├── _index.tsx # / (landing page)
12
+ ├── login.tsx # /login
13
+ ├── register.tsx # /register
14
+ ├── pricing.tsx # /pricing
15
+ ├── about.tsx # /about
16
+ ├── chat._index.tsx # /chat (main chat)
17
+ ├── chat.thread.$threadId.tsx # /chat/thread/:id
18
+ └── chat.documents.tsx # /chat/documents
19
+ ```
20
+
21
+ The `basePath` configuration (typically `/chat`) determines where the authenticated chat app lives, leaving the root path available for marketing pages.
22
+
23
+ ## Adding a New Page
24
+
25
+ ### Step 1: Create the Route File
26
+
27
+ Create a new file in `app/routes/`. The filename determines the URL path:
28
+
29
+ ```tsx
30
+ // app/routes/pricing.tsx
31
+ // This creates a route at /pricing
32
+
33
+ export default function PricingPage() {
34
+ return (
35
+ <div className="min-h-screen bg-background">
36
+ <nav className="flex items-center justify-between p-6">
37
+ <a href="/" className="text-xl font-bold text-text-primary">
38
+ MyApp
39
+ </a>
40
+ <div className="flex items-center gap-6">
41
+ <a href="/pricing" className="text-text-secondary hover:text-text-primary">
42
+ Pricing
43
+ </a>
44
+ <a href="/chat" className="rounded-lg bg-primary px-4 py-2 text-white">
45
+ Launch App
46
+ </a>
47
+ </div>
48
+ </nav>
49
+
50
+ <main className="mx-auto max-w-4xl px-6 py-16">
51
+ <h1 className="text-4xl font-bold text-text-primary text-center">
52
+ Simple, Transparent Pricing
53
+ </h1>
54
+ {/* Your pricing content */}
55
+ </main>
56
+ </div>
57
+ );
58
+ }
59
+ ```
60
+
61
+ ### Step 2: Add Server-Side Data Loading (Optional)
62
+
63
+ Use a loader function for server-side data fetching:
64
+
65
+ ```tsx
66
+ // app/routes/pricing.tsx
67
+ import type { Route } from './+types/pricing';
68
+
69
+ export async function loader({ request }: Route.LoaderArgs) {
70
+ // Fetch pricing plans from your API or database
71
+ const plans = await fetchPricingPlans();
72
+ return { plans };
73
+ }
74
+
75
+ export default function PricingPage({ loaderData }: Route.ComponentProps) {
76
+ const { plans } = loaderData;
77
+
78
+ return (
79
+ <div className="min-h-screen bg-background">
80
+ {/* Your page content using plans data */}
81
+ </div>
82
+ );
83
+ }
84
+ ```
85
+
86
+ ## Route Naming Convention
87
+
88
+ React Router v7 uses dot notation for nested routes:
89
+
90
+ | Filename | URL Path | Description |
91
+ |----------|----------|-------------|
92
+ | `_index.tsx` | `/` | Root index page |
93
+ | `pricing.tsx` | `/pricing` | Simple route |
94
+ | `about.tsx` | `/about` | Simple route |
95
+ | `blog._index.tsx` | `/blog` | Blog index |
96
+ | `blog.$slug.tsx` | `/blog/:slug` | Blog post with dynamic slug |
97
+ | `chat._index.tsx` | `/chat` | Chat app index |
98
+ | `chat.thread.$threadId.tsx` | `/chat/thread/:id` | Chat thread |
99
+
100
+ The `$` prefix creates dynamic segments (URL parameters).
101
+
102
+ ## Accessing URL Parameters
103
+
104
+ For dynamic routes, access parameters in the loader or component:
105
+
106
+ ```tsx
107
+ // app/routes/blog.$slug.tsx
108
+ import type { Route } from './+types/blog.$slug';
109
+
110
+ export async function loader({ params }: Route.LoaderArgs) {
111
+ const post = await getPostBySlug(params.slug);
112
+ if (!post) {
113
+ throw new Response('Not Found', { status: 404 });
114
+ }
115
+ return { post };
116
+ }
117
+
118
+ export default function BlogPost({ loaderData }: Route.ComponentProps) {
119
+ const { post } = loaderData;
120
+ return (
121
+ <article>
122
+ <h1>{post.title}</h1>
123
+ <div dangerouslySetInnerHTML={{ __html: post.content }} />
124
+ </article>
125
+ );
126
+ }
127
+ ```
128
+
129
+ ## Sharing Layout Between Pages
130
+
131
+ ### Option 1: Layout Route
132
+
133
+ Create a layout route that wraps child routes:
134
+
135
+ ```tsx
136
+ // app/routes/marketing.tsx
137
+ // This wraps all routes starting with /marketing/*
138
+
139
+ import { Outlet } from 'react-router';
140
+
141
+ export default function MarketingLayout() {
142
+ return (
143
+ <div className="min-h-screen bg-background">
144
+ <nav className="border-b border-border">
145
+ {/* Shared navigation */}
146
+ </nav>
147
+ <Outlet />
148
+ <footer className="border-t border-border">
149
+ {/* Shared footer */}
150
+ </footer>
151
+ </div>
152
+ );
153
+ }
154
+ ```
155
+
156
+ Then create child routes:
157
+
158
+ ```
159
+ app/routes/
160
+ ├── marketing.tsx # Layout wrapper
161
+ ├── marketing._index.tsx # /marketing
162
+ ├── marketing.about.tsx # /marketing/about
163
+ └── marketing.contact.tsx # /marketing/contact
164
+ ```
165
+
166
+ ### Option 2: Shared Component
167
+
168
+ Create a reusable layout component:
169
+
170
+ ```tsx
171
+ // app/components/MarketingLayout.tsx
172
+ import { Link } from 'react-router';
173
+
174
+ interface MarketingLayoutProps {
175
+ children: React.ReactNode;
176
+ }
177
+
178
+ export function MarketingLayout({ children }: MarketingLayoutProps) {
179
+ return (
180
+ <div className="min-h-screen bg-background">
181
+ <nav className="flex items-center justify-between p-6 border-b border-border">
182
+ <Link to="/" className="text-xl font-bold text-text-primary">
183
+ MyApp
184
+ </Link>
185
+ <div className="flex items-center gap-6">
186
+ <Link to="/pricing" className="text-text-secondary hover:text-text-primary">
187
+ Pricing
188
+ </Link>
189
+ <Link to="/about" className="text-text-secondary hover:text-text-primary">
190
+ About
191
+ </Link>
192
+ <Link to="/chat" className="rounded-lg bg-primary px-4 py-2 text-white">
193
+ Launch App
194
+ </Link>
195
+ </div>
196
+ </nav>
197
+ <main>{children}</main>
198
+ <footer className="border-t border-border p-6 text-center text-text-muted">
199
+ &copy; 2024 MyApp
200
+ </footer>
201
+ </div>
202
+ );
203
+ }
204
+ ```
205
+
206
+ Use it in your pages:
207
+
208
+ ```tsx
209
+ // app/routes/pricing.tsx
210
+ import { MarketingLayout } from '~/components/MarketingLayout';
211
+
212
+ export default function PricingPage() {
213
+ return (
214
+ <MarketingLayout>
215
+ <div className="mx-auto max-w-4xl px-6 py-16">
216
+ <h1>Pricing</h1>
217
+ {/* Content */}
218
+ </div>
219
+ </MarketingLayout>
220
+ );
221
+ }
222
+ ```
223
+
224
+ ## Styling Custom Pages
225
+
226
+ ### Using ChaasKit's Theme
227
+
228
+ Custom pages automatically have access to the theme CSS variables defined in `root.tsx`:
229
+
230
+ ```tsx
231
+ // Theme classes work everywhere
232
+ <div className="bg-background text-text-primary">
233
+ <button className="bg-primary hover:bg-primary-hover text-white">
234
+ Click me
235
+ </button>
236
+ </div>
237
+ ```
238
+
239
+ ### Custom Styles
240
+
241
+ Add page-specific styles using Tailwind or CSS modules:
242
+
243
+ ```tsx
244
+ // With Tailwind (already configured)
245
+ <div className="bg-gradient-to-br from-purple-600 to-blue-500">
246
+ Custom gradient background
247
+ </div>
248
+ ```
249
+
250
+ ## SEO and Meta Tags
251
+
252
+ Add meta tags using the `meta` export:
253
+
254
+ ```tsx
255
+ // app/routes/pricing.tsx
256
+ import type { Route } from './+types/pricing';
257
+
258
+ export function meta({}: Route.MetaArgs) {
259
+ return [
260
+ { title: 'Pricing - MyApp' },
261
+ { name: 'description', content: 'Simple, transparent pricing for MyApp' },
262
+ { property: 'og:title', content: 'Pricing - MyApp' },
263
+ { property: 'og:description', content: 'Simple, transparent pricing' },
264
+ ];
265
+ }
266
+
267
+ export default function PricingPage() {
268
+ // ...
269
+ }
270
+ ```
271
+
272
+ ## Handling Forms
273
+
274
+ Use React Router's form handling for actions:
275
+
276
+ ```tsx
277
+ // app/routes/contact.tsx
278
+ import type { Route } from './+types/contact';
279
+ import { Form, useActionData } from 'react-router';
280
+
281
+ export async function action({ request }: Route.ActionArgs) {
282
+ const formData = await request.formData();
283
+ const email = formData.get('email');
284
+ const message = formData.get('message');
285
+
286
+ // Process the form
287
+ await sendContactEmail({ email, message });
288
+
289
+ return { success: true };
290
+ }
291
+
292
+ export default function ContactPage() {
293
+ const actionData = useActionData<typeof action>();
294
+
295
+ return (
296
+ <div className="max-w-md mx-auto p-6">
297
+ {actionData?.success ? (
298
+ <p className="text-success">Thanks for reaching out!</p>
299
+ ) : (
300
+ <Form method="post" className="space-y-4">
301
+ <input
302
+ type="email"
303
+ name="email"
304
+ placeholder="Your email"
305
+ className="w-full rounded-lg border border-input-border bg-input-background px-4 py-2"
306
+ />
307
+ <textarea
308
+ name="message"
309
+ placeholder="Your message"
310
+ className="w-full rounded-lg border border-input-border bg-input-background px-4 py-2"
311
+ />
312
+ <button
313
+ type="submit"
314
+ className="w-full rounded-lg bg-primary px-4 py-2 text-white"
315
+ >
316
+ Send Message
317
+ </button>
318
+ </Form>
319
+ )}
320
+ </div>
321
+ );
322
+ }
323
+ ```
324
+
325
+ ## Protected Custom Pages
326
+
327
+ For pages that require authentication, use a loader to check auth:
328
+
329
+ ```tsx
330
+ // app/routes/dashboard.tsx
331
+ import type { Route } from './+types/dashboard';
332
+ import { redirect } from 'react-router';
333
+ import { getUser } from '~/utils/auth.server';
334
+
335
+ export async function loader({ request }: Route.LoaderArgs) {
336
+ const user = await getUser(request);
337
+ if (!user) {
338
+ return redirect('/login');
339
+ }
340
+ return { user };
341
+ }
342
+
343
+ export default function DashboardPage({ loaderData }: Route.ComponentProps) {
344
+ const { user } = loaderData;
345
+ return (
346
+ <div>
347
+ <h1>Welcome, {user.name}!</h1>
348
+ </div>
349
+ );
350
+ }
351
+ ```
352
+
353
+ ## Example: Complete Landing Page
354
+
355
+ ```tsx
356
+ // app/routes/_index.tsx
357
+ import { Link } from 'react-router';
358
+
359
+ export function meta() {
360
+ return [
361
+ { title: 'MyApp - AI-Powered Chat' },
362
+ { name: 'description', content: 'Build AI chat applications with MyApp' },
363
+ ];
364
+ }
365
+
366
+ export default function LandingPage() {
367
+ return (
368
+ <div className="min-h-screen bg-background">
369
+ {/* Navigation */}
370
+ <nav className="flex items-center justify-between p-6">
371
+ <span className="text-xl font-bold text-text-primary">MyApp</span>
372
+ <div className="flex items-center gap-6">
373
+ <Link to="/pricing" className="text-text-secondary hover:text-text-primary">
374
+ Pricing
375
+ </Link>
376
+ <Link to="/login" className="text-text-secondary hover:text-text-primary">
377
+ Log in
378
+ </Link>
379
+ <Link
380
+ to="/register"
381
+ className="rounded-lg bg-primary px-4 py-2 text-white hover:bg-primary-hover"
382
+ >
383
+ Get Started
384
+ </Link>
385
+ </div>
386
+ </nav>
387
+
388
+ {/* Hero */}
389
+ <main className="mx-auto max-w-4xl px-6 py-24 text-center">
390
+ <h1 className="text-5xl font-bold text-text-primary leading-tight">
391
+ Build AI Chat Apps
392
+ <br />
393
+ <span className="text-primary">In Minutes</span>
394
+ </h1>
395
+ <p className="mt-6 text-xl text-text-secondary max-w-2xl mx-auto">
396
+ ChaasKit gives you everything you need to build production-ready
397
+ AI chat applications with authentication, teams, and more.
398
+ </p>
399
+ <div className="mt-10 flex justify-center gap-4">
400
+ <Link
401
+ to="/register"
402
+ className="rounded-lg bg-primary px-6 py-3 text-lg font-medium text-white hover:bg-primary-hover"
403
+ >
404
+ Start Building Free
405
+ </Link>
406
+ <Link
407
+ to="/chat"
408
+ className="rounded-lg border border-border px-6 py-3 text-lg font-medium text-text-primary hover:bg-background-secondary"
409
+ >
410
+ View Demo
411
+ </Link>
412
+ </div>
413
+ </main>
414
+
415
+ {/* Features */}
416
+ <section className="border-t border-border py-24">
417
+ <div className="mx-auto max-w-5xl px-6">
418
+ <h2 className="text-3xl font-bold text-text-primary text-center mb-12">
419
+ Everything You Need
420
+ </h2>
421
+ <div className="grid md:grid-cols-3 gap-8">
422
+ {[
423
+ { title: 'AI Integration', desc: 'OpenAI and Anthropic support out of the box' },
424
+ { title: 'Authentication', desc: 'Email, OAuth, and magic links built in' },
425
+ { title: 'Team Workspaces', desc: 'Collaborate with shared threads and projects' },
426
+ ].map((feature) => (
427
+ <div key={feature.title} className="rounded-lg bg-background-secondary p-6">
428
+ <h3 className="text-lg font-semibold text-text-primary">{feature.title}</h3>
429
+ <p className="mt-2 text-text-secondary">{feature.desc}</p>
430
+ </div>
431
+ ))}
432
+ </div>
433
+ </div>
434
+ </section>
435
+
436
+ {/* Footer */}
437
+ <footer className="border-t border-border py-8">
438
+ <div className="mx-auto max-w-5xl px-6 flex justify-between items-center">
439
+ <span className="text-text-muted">&copy; 2024 MyApp</span>
440
+ <div className="flex gap-6">
441
+ <Link to="/privacy" className="text-text-muted hover:text-text-primary">
442
+ Privacy
443
+ </Link>
444
+ <Link to="/terms" className="text-text-muted hover:text-text-primary">
445
+ Terms
446
+ </Link>
447
+ </div>
448
+ </div>
449
+ </footer>
450
+ </div>
451
+ );
452
+ }
453
+ ```
454
+
455
+ ## Summary
456
+
457
+ | Aspect | How It Works |
458
+ |--------|--------------|
459
+ | Create a page | Add a file to `app/routes/` |
460
+ | URL path | Determined by filename (`pricing.tsx` → `/pricing`) |
461
+ | Dynamic routes | Use `$` prefix (`blog.$slug.tsx` → `/blog/:slug`) |
462
+ | Data loading | Export a `loader` function |
463
+ | Form handling | Export an `action` function |
464
+ | Meta tags | Export a `meta` function |
465
+ | Layouts | Use layout routes or shared components |
466
+ | Styling | Tailwind + theme CSS variables |