kitcn 0.0.1 → 0.12.1

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 (93) hide show
  1. package/bin/intent.js +3 -0
  2. package/dist/aggregate/index.d.ts +388 -0
  3. package/dist/aggregate/index.js +37 -0
  4. package/dist/api-entry-BckXqaLb.js +66 -0
  5. package/dist/auth/client/index.d.ts +37 -0
  6. package/dist/auth/client/index.js +217 -0
  7. package/dist/auth/config/index.d.ts +45 -0
  8. package/dist/auth/config/index.js +24 -0
  9. package/dist/auth/generated/index.d.ts +2 -0
  10. package/dist/auth/generated/index.js +3 -0
  11. package/dist/auth/http/index.d.ts +64 -0
  12. package/dist/auth/http/index.js +461 -0
  13. package/dist/auth/index.d.ts +221 -0
  14. package/dist/auth/index.js +1398 -0
  15. package/dist/auth/nextjs/index.d.ts +50 -0
  16. package/dist/auth/nextjs/index.js +81 -0
  17. package/dist/auth-store-Cljlmdmi.js +197 -0
  18. package/dist/builder-CBdG5W6A.js +1974 -0
  19. package/dist/caller-factory-cTXNvYdz.js +216 -0
  20. package/dist/cli.mjs +13264 -0
  21. package/dist/codegen-lF80HSWu.mjs +3416 -0
  22. package/dist/context-utils-HPC5nXzx.d.ts +17 -0
  23. package/dist/create-schema-odyF4kCy.js +156 -0
  24. package/dist/create-schema-orm-DOyiNDCx.js +246 -0
  25. package/dist/crpc/index.d.ts +105 -0
  26. package/dist/crpc/index.js +169 -0
  27. package/dist/customFunctions-C0voKmtx.js +144 -0
  28. package/dist/error-BZEnI7Sq.js +41 -0
  29. package/dist/generated-contract-disabled-Cih4eITO.js +50 -0
  30. package/dist/generated-contract-disabled-D-sOFy92.d.ts +354 -0
  31. package/dist/http-types-DqJubRPJ.d.ts +292 -0
  32. package/dist/meta-utils-0Pu0Nrap.js +117 -0
  33. package/dist/middleware-BUybuv9n.d.ts +34 -0
  34. package/dist/middleware-C2qTZ3V7.js +84 -0
  35. package/dist/orm/index.d.ts +17 -0
  36. package/dist/orm/index.js +10713 -0
  37. package/dist/plugins/index.d.ts +2 -0
  38. package/dist/plugins/index.js +3 -0
  39. package/dist/procedure-caller-DtxLmGwA.d.ts +1467 -0
  40. package/dist/procedure-caller-MWcxhQDv.js +349 -0
  41. package/dist/query-context-B8o6-8kC.js +1518 -0
  42. package/dist/query-context-CFZqIvD7.d.ts +42 -0
  43. package/dist/query-options-Dw7cOyXl.js +121 -0
  44. package/dist/ratelimit/index.d.ts +269 -0
  45. package/dist/ratelimit/index.js +856 -0
  46. package/dist/ratelimit/react/index.d.ts +76 -0
  47. package/dist/ratelimit/react/index.js +183 -0
  48. package/dist/react/index.d.ts +1284 -0
  49. package/dist/react/index.js +2526 -0
  50. package/dist/rsc/index.d.ts +276 -0
  51. package/dist/rsc/index.js +233 -0
  52. package/dist/runtime-CtvJPkur.js +2453 -0
  53. package/dist/server/index.d.ts +5 -0
  54. package/dist/server/index.js +6 -0
  55. package/dist/solid/index.d.ts +1221 -0
  56. package/dist/solid/index.js +2940 -0
  57. package/dist/transformer-DtDhR3Lc.js +194 -0
  58. package/dist/types-BTb_4BaU.d.ts +42 -0
  59. package/dist/types-BiJE7qxR.d.ts +4 -0
  60. package/dist/types-DEJpkIhw.d.ts +88 -0
  61. package/dist/types-HhO_R6pd.d.ts +213 -0
  62. package/dist/validators-B7oIJCAp.js +279 -0
  63. package/dist/validators-vzRKjBJC.d.ts +88 -0
  64. package/dist/watcher.mjs +96 -0
  65. package/dist/where-clause-compiler-DdjN63Io.d.ts +4756 -0
  66. package/package.json +107 -34
  67. package/skills/convex/SKILL.md +486 -0
  68. package/skills/convex/references/features/aggregates.md +353 -0
  69. package/skills/convex/references/features/auth-admin.md +446 -0
  70. package/skills/convex/references/features/auth-organizations.md +1141 -0
  71. package/skills/convex/references/features/auth-polar.md +579 -0
  72. package/skills/convex/references/features/auth.md +470 -0
  73. package/skills/convex/references/features/create-plugins.md +153 -0
  74. package/skills/convex/references/features/http.md +676 -0
  75. package/skills/convex/references/features/migrations.md +162 -0
  76. package/skills/convex/references/features/orm.md +1166 -0
  77. package/skills/convex/references/features/react.md +657 -0
  78. package/skills/convex/references/features/scheduling.md +267 -0
  79. package/skills/convex/references/features/testing.md +209 -0
  80. package/skills/convex/references/setup/auth.md +501 -0
  81. package/skills/convex/references/setup/biome.md +190 -0
  82. package/skills/convex/references/setup/doc-guidelines.md +145 -0
  83. package/skills/convex/references/setup/index.md +761 -0
  84. package/skills/convex/references/setup/next.md +116 -0
  85. package/skills/convex/references/setup/react.md +175 -0
  86. package/skills/convex/references/setup/server.md +473 -0
  87. package/skills/convex/references/setup/start.md +67 -0
  88. package/LICENSE +0 -21
  89. package/README.md +0 -0
  90. package/dist/index.d.mts +0 -5
  91. package/dist/index.d.mts.map +0 -1
  92. package/dist/index.mjs +0 -6
  93. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,761 @@
1
+ # kitcn Setup (Canonical, Greenfield)
2
+
3
+ Use this runbook to set up a project from scratch so agents can ship features end-to-end without additional setup context.
4
+
5
+ ## 1. Purpose and Scope
6
+
7
+ This document is the canonical setup reference for kitcn in `.claude`.
8
+
9
+ In scope:
10
+
11
+ - Greenfield setup from empty/new app
12
+ - ORM-first backend (`ctx.orm`)
13
+ - cRPC setup, auth setup, client setup, framework setup
14
+ - Optional modules and plugin setup gates
15
+
16
+ Out of scope:
17
+
18
+ - Migrations from existing Convex/Ents/legacy data-layer projects
19
+
20
+ If migration is needed, stop and use migration docs separately. Do not mix migration steps into this runbook.
21
+
22
+ ## 2. Agent Decision Intake
23
+
24
+ This is the **mandatory first prompt** for agents helping users set up kitcn.
25
+ Ask these questions before editing files.
26
+
27
+ ### 2.1 Ask These First (match `/www/content/docs/index.mdx`)
28
+
29
+ #### Required choices
30
+
31
+ | Feature | Options | Default |
32
+ | --------------- | --------------------------------------------------- | ------------------ |
33
+ | Bootstrap | CLI (`kitcn init` / `add`), Docs by section | CLI |
34
+ | React Framework | Next.js App Router, TanStack Start, Other | Next.js App Router |
35
+ | Database | ORM (`ctx.orm`) | ORM |
36
+
37
+ #### Optional features
38
+
39
+ | Feature | Options | When to include |
40
+ | ------------- | --------------------------------- | --------------------------------- |
41
+ | Auth | Better Auth, Custom, None | Most apps need auth |
42
+ | SSR/RSC | Yes, No | Next.js App Router apps |
43
+ | Triggers | Yes, No | Auto side effects on data changes |
44
+ | Aggregates | Yes, No | Counts, sums, leaderboards |
45
+ | Rate Limiting | Yes, No | API protection |
46
+ | Scheduling | Yes, No | Background jobs, delayed tasks |
47
+ | HTTP router | Yes, No | REST/webhook style endpoints |
48
+ | RLS | Yes, No | Runtime row-level access control |
49
+ | Auth plugins | admin, organizations, polar, none | Only when product requires them |
50
+
51
+ ### 2.2 First Prompt Template
52
+
53
+ Use this exact structure:
54
+
55
+ 1. Bootstrap: CLI (`kitcn init` / `add`) or docs by section?
56
+ 2. Framework: Next.js App Router, TanStack Start, or other?
57
+ 3. Database: ORM (`ctx.orm`) or other?
58
+ 4. Auth: Better Auth, custom auth, or no auth?
59
+ 5. Need SSR/RSC?
60
+ 6. Enable triggers?
61
+ 7. Enable aggregates?
62
+ 8. Enable rate limiting?
63
+ 9. Enable scheduling?
64
+ 10. Need HTTP router endpoints?
65
+ 11. Enable RLS?
66
+ 12. Any auth plugins (admin/organizations/polar)?
67
+
68
+ ### 2.3 Decision Mapping
69
+
70
+ Map answers to setup execution in this order:
71
+
72
+ 1. Build base setup first (non-auth only).
73
+ 2. Pass the non-auth baseline gate (Section 11.2) before starting auth work.
74
+ 3. If auth is enabled: add auth core.
75
+ 4. If auth is enabled: pass the auth sign-in gate (Section 11.3) before optional modules/plugins.
76
+ 5. Add framework branch (Next.js or TanStack Start).
77
+ 6. Add optional modules/plugins only when selected.
78
+ 7. If framework is `Other`, stop this runbook and route to non-setup docs (`react`, `server/*`) instead of guessing.
79
+
80
+ ## 3. Base Bootstrap
81
+
82
+ ### 3.1 Preferred bootstrap path
83
+
84
+ Quickstart path:
85
+
86
+ ```bash
87
+ mkdir my-app
88
+ cd my-app
89
+ bunx kitcn init -t next --yes
90
+ ```
91
+
92
+ Then start the long-running backend with `bunx kitcn dev`, run the
93
+ framework dev server (`bun dev` for the Next starter), and open `/convex` for
94
+ the scaffolded messages demo. In `--yes` mode, kitcn provisions an anonymous
95
+ local Convex deployment when no account is linked yet, so the starter path does
96
+ not stop on a login prompt.
97
+
98
+ Use the CLI first:
99
+
100
+ ```bash
101
+ # Adopt the current supported app in place
102
+ bunx kitcn init --yes
103
+
104
+ # Adopt the current supported app on Concave
105
+ bunx kitcn --backend concave init --yes
106
+
107
+ # New Next.js app with deterministic shadcn bootstrap + first local Convex bootstrap
108
+ bunx kitcn init -t next --yes
109
+
110
+ # New Vite app with the React baseline + first local Convex bootstrap
111
+ bunx kitcn init -t vite --yes
112
+
113
+ # Nested app target
114
+ bunx kitcn init -t next --yes --cwd apps --name web
115
+ ```
116
+
117
+ Then add only the features you want:
118
+
119
+ ```bash
120
+ bunx kitcn add auth
121
+ bunx kitcn add ratelimit
122
+ bunx kitcn add resend
123
+ ```
124
+
125
+ `kitcn init -t next --yes` owns the kitcn integration layer for:
126
+
127
+ - `app/convex/page.tsx`
128
+ - `package.json`
129
+ - `tsconfig.json`
130
+ - `.env.local`
131
+ - `components/providers.tsx`
132
+ - `lib/convex/*`
133
+ - `convex/functions/messages.ts`
134
+ - `convex/functions/generated/messages.runtime.ts`
135
+ - `convex/functions/schema.ts`
136
+ - `convex/functions/http.ts`
137
+ - `convex/functions/generated/server.ts`
138
+ - `convex/lib/crpc.ts`
139
+ - `convex/lib/get-env.ts`
140
+ - `convex/shared/api.ts`
141
+ - `kitcn.json`
142
+
143
+ Template-mode `init -t next` preserves the shadcn-owned shell (`app/layout.tsx`, `app/page.tsx`, `app/globals.css`, `components/theme-provider.tsx`, `lib/utils.ts`, `components.json`, `eslint.config.mjs`, `next.config.mjs`, `postcss.config.mjs`) and only patches:
144
+
145
+ - `app/layout.tsx` to mount `Providers`
146
+ - `tsconfig.json` to add `@convex/*`
147
+ - `components.json` when `tailwind.css` needs to follow the resolved app root
148
+ - `package.json` to add `kitcn codegen` as `codegen` (or `convex:codegen` when `codegen` is already taken)
149
+
150
+ `init -t` also runs the first kitcn codegen pass so `convex/lib/crpc.ts` can import `../functions/generated/server` immediately.
151
+ Template-mode `init -t` also seeds a live messages demo route plus starter schema and
152
+ procedures, so the scaffold has one working query/mutation flow out of the box.
153
+ Template-mode `init -t` infers `src/` vs root app layouts and writes the Next client scaffold into the matching tree. Conflicting `src` + root layouts should fail instead of guessing.
154
+ Backend resolves from `--backend`, then `backend` in `kitcn.json`, then `convex`.
155
+
156
+ Universal scaffold rule:
157
+
158
+ 1. `init -t next` owns the stack everyone needs:
159
+ - typed `get-env`
160
+ - client core
161
+ - server core
162
+ - root + Convex tsconfig wiring
163
+ - `.gitignore` entries for `.convex/` and `.concave/`
164
+ - baseline scripts
165
+ - fixed `/convex` messages demo
166
+ 2. `kitcn init` bootstraps the app in both modes: with `-t` for fresh scaffold, without `-t` for in-place adoption.
167
+ 3. Optional capability belongs in `add`, not the base scaffold:
168
+ - `add auth`
169
+ - `add ratelimit`
170
+ - `add resend`
171
+ 4. `add auth` is the minimal auth bundle. It owns auth server/client files,
172
+ auth-aware provider wiring, auth env fields, and auth cRPC families.
173
+ 5. `add auth` does not own role/admin policy, orgs, or other app-policy layers.
174
+
175
+ Public template keys stay concrete:
176
+
177
+ - `next`
178
+ - `vite`
179
+
180
+ Internal scaffold modes stay broad:
181
+
182
+ - `next-app`
183
+ - `react`
184
+
185
+ Framework mapping:
186
+
187
+ - `next-app` -> `next-app`
188
+ - `next-pages`, `vite`, `react-router`, `tanstack-start`, `manual` -> `react`
189
+
190
+ React-mode notes:
191
+
192
+ 1. `init -t vite` scaffolds the universal baseline plus the React client core.
193
+ 2. It does not scaffold RSC helpers.
194
+ 3. It does not scaffold the `/convex` messages demo in v1.
195
+ 4. `add auth` on the React baseline follows the Better Auth React/Vite SPA shape and skips auth page/router UX in v1.
196
+
197
+ ### 3.2 Manual app creation and baseline packages
198
+
199
+ ```bash
200
+ bunx create-next-app@latest my-app --typescript --tailwind --eslint --app --src-dir
201
+ cd my-app
202
+ bun add convex kitcn zod @tanstack/react-query
203
+ ```
204
+
205
+ ### 3.3 Create baseline folders
206
+
207
+ ```bash
208
+ mkdir -p convex/functions convex/lib convex/shared src/lib/convex
209
+ ```
210
+
211
+ If the goal is full template-level backend parity, also scaffold:
212
+
213
+ ```bash
214
+ mkdir -p convex/functions/items convex/lib/auth convex/lib/emails convex/routers
215
+ ```
216
+
217
+ Recommended monolithic structure:
218
+
219
+ ```text
220
+ src/ # app/client
221
+ convex/functions/ # deployed Convex functions
222
+ convex/lib/ # backend helpers (not deployed as API)
223
+ convex/shared/ # shared types/meta imported by client
224
+ ```
225
+
226
+ ### 3.4 Configure Convex functions path and static codegen
227
+
228
+ **Create:** `convex.json`
229
+
230
+ ```json
231
+ {
232
+ "functions": "convex/functions",
233
+ "codegen": {
234
+ "staticApi": true,
235
+ "staticDataModel": true
236
+ }
237
+ }
238
+ ```
239
+
240
+ ### 3.5 Configure TypeScript aliases and strict function typing
241
+
242
+ **Edit:** `tsconfig.json`
243
+
244
+ ```json
245
+ {
246
+ "compilerOptions": {
247
+ "strict": true,
248
+ "strictFunctionTypes": false,
249
+ "types": ["node"],
250
+ "paths": {
251
+ "@/*": ["./src/*"],
252
+ "@convex/*": ["./convex/shared/*"]
253
+ }
254
+ }
255
+ }
256
+ ```
257
+
258
+ Type-clean baseline notes:
259
+
260
+ 1. Keep app/runtime node globals available (`types: ["node"]`) so `process.env` and server modules typecheck.
261
+ 2. Add test-only globals (for example `vitest/globals`) in a test-specific tsconfig instead of the main app tsconfig.
262
+ 3. If third-party declaration noise blocks setup, temporarily set `"skipLibCheck": true` and remove it once dependency versions are stabilized.
263
+ 4. In backend Convex files, import `./_generated/*` relatively; `@convex/*` is for shared generated surface (`convex/shared/*`).
264
+
265
+ ### 3.6 Enforce import boundaries (recommended)
266
+
267
+ **Edit:** `biome.jsonc`
268
+
269
+ ```jsonc
270
+ {
271
+ "extends": ["ultracite/core", "ultracite/react", "ultracite/next"],
272
+ "overrides": [
273
+ {
274
+ "includes": ["src/**/*.ts*"],
275
+ "linter": {
276
+ "rules": {
277
+ "style": {
278
+ "noRestrictedImports": {
279
+ "level": "error",
280
+ "options": {
281
+ "paths": {
282
+ "convex/values": {
283
+ "importNames": ["ConvexError"],
284
+ "message": "Use CRPCError from 'kitcn/crpc' instead.",
285
+ },
286
+ "convex/react": "Use useCRPC from '@/lib/convex/crpc' instead.",
287
+ "convex/nextjs": "Use caller from '@/lib/convex/rsc' instead.",
288
+ },
289
+ "patterns": [
290
+ {
291
+ "group": ["**/../convex/**"],
292
+ "message": "Use @convex/* alias instead of relative convex imports.",
293
+ },
294
+ ],
295
+ },
296
+ },
297
+ },
298
+ },
299
+ },
300
+ },
301
+ {
302
+ "includes": ["convex/**/*.ts*"],
303
+ "linter": {
304
+ "rules": {
305
+ "style": {
306
+ "noRestrictedImports": {
307
+ "level": "error",
308
+ "options": {
309
+ "patterns": [
310
+ {
311
+ "group": ["@/*", "**/src/**"],
312
+ "message": "Convex files cannot import from src/.",
313
+ },
314
+ ],
315
+ },
316
+ },
317
+ },
318
+ },
319
+ },
320
+ },
321
+ {
322
+ "includes": ["convex/shared/**/*.ts*"],
323
+ "linter": {
324
+ "rules": {
325
+ "style": {
326
+ "noRestrictedImports": {
327
+ "level": "error",
328
+ "options": {
329
+ "patterns": [
330
+ {
331
+ "group": ["**/convex/lib/**"],
332
+ "message": "convex/shared cannot import from convex/lib.",
333
+ },
334
+ ],
335
+ },
336
+ },
337
+ },
338
+ },
339
+ },
340
+ },
341
+ ],
342
+ }
343
+ ```
344
+
345
+ ## 4. Environment Variables
346
+
347
+ ### 4.1 Local
348
+
349
+ **Create:** `.env.local`
350
+
351
+ ```bash
352
+ # Convex WebSocket API
353
+ NEXT_PUBLIC_CONVEX_URL=http://localhost:3210
354
+
355
+ # Convex HTTP site URL
356
+ NEXT_PUBLIC_CONVEX_SITE_URL=http://localhost:3211
357
+
358
+ # App URL for Better Auth client
359
+ NEXT_PUBLIC_SITE_URL=http://localhost:3000
360
+ ```
361
+
362
+ ### 4.2 Cloud
363
+
364
+ ```bash
365
+ # Generated by Convex
366
+ NEXT_PUBLIC_CONVEX_URL=https://your-project.convex.cloud
367
+
368
+ # Must be set manually
369
+ NEXT_PUBLIC_CONVEX_SITE_URL=https://your-project.convex.site
370
+
371
+ NEXT_PUBLIC_SITE_URL=http://localhost:3000
372
+ ```
373
+
374
+ Rule: real-time URL uses `.cloud`; HTTP/router/caller URL uses `.site`.
375
+
376
+ ### 4.3 Typed env helper (recommended for full backend parity)
377
+
378
+ When multiple Convex functions and libs share env values (auth, billing, dev guards), create one typed helper:
379
+
380
+ **Create:** `convex/lib/get-env.ts`
381
+
382
+ ```ts
383
+ import { createEnv } from "kitcn/server";
384
+ import { z } from "zod";
385
+
386
+ export const getEnv = createEnv({
387
+ schema: z.object({
388
+ DEPLOY_ENV: z.string().default("production"),
389
+ SITE_URL: z.string().default("http://localhost:3000"),
390
+ BETTER_AUTH_SECRET: z.string(),
391
+ JWKS: z.string().optional(),
392
+ ADMIN: z
393
+ .string()
394
+ .default("")
395
+ .transform((s) => (s ? s.split(",") : []))
396
+ .pipe(z.array(z.string())),
397
+ RESEND_API_KEY: z.string().optional(),
398
+ POLAR_ACCESS_TOKEN: z.string().optional(),
399
+ POLAR_SERVER: z.enum(["production", "sandbox"]).default("sandbox"),
400
+ POLAR_PRODUCT_PREMIUM: z.string().optional(),
401
+ POLAR_WEBHOOK_SECRET: z.string().optional(),
402
+ }),
403
+ });
404
+ ```
405
+
406
+ Then prefer `getEnv()` in Convex code instead of scattered `process.env`.
407
+
408
+ ## 11. Dev Scripts and CLI Workflow
409
+
410
+ ### 11.0 Plugin scaffold inspection
411
+
412
+ Use the plugin CLI as a plan engine, not a blind writer:
413
+
414
+ 1. `bunx kitcn add <plugin> --dry-run` → compact full-plan summary.
415
+ 2. `bunx kitcn add <plugin> --diff [path]` → unified diffs for planned file changes.
416
+ 3. `bunx kitcn add <plugin> --view [path]` → rendered planned file contents.
417
+ 4. `bunx kitcn view <plugin>` → inspect resolved preset, selection source, docs link, files, operations.
418
+ 5. `bunx kitcn info --json` → project paths, versions, installed plugins, schema/lockfile mismatch, missing deps, scaffold drift.
419
+ 6. `bunx kitcn docs <topic...>` → local/public docs links for `cli`, `plugins`, `auth`, `orm`, `migrations`, `resend`, `ratelimit`.
420
+
421
+ Rules:
422
+
423
+ 1. `kitcn add <plugin>` bootstraps baseline files first when they are missing.
424
+ 2. `--diff [path]` / `--view [path]` match workspace-relative output path by exact match first, substring fallback.
425
+ 3. Preview scope includes scaffold files, env bootstrap, `kitcn.json`, schema registration, lockfile write, dependency install status, codegen/hooks, env reminders.
426
+
427
+ ### 11.1 Dev bootstrap functions (example parity mode)
428
+
429
+ If you want the same operational model as the scaffolded baseline, use these canonical snippets.
430
+
431
+ **Create:** `convex/functions/init.ts`
432
+
433
+ ```ts
434
+ import { z } from "zod";
435
+
436
+ import { createUser } from "../lib/auth/auth-helpers";
437
+ import { privateMutation } from "../lib/crpc";
438
+ import { getEnv } from "../lib/get-env";
439
+ import { createSeedHandler } from "./generated/seed.runtime";
440
+
441
+ export default privateMutation
442
+ .meta({ dev: true })
443
+
444
+ .mutation(async ({ ctx }) => {
445
+ const env = getEnv();
446
+ const adminEmails = env.ADMIN;
447
+
448
+ if (!adminEmails || adminEmails.length === 0) {
449
+ return null;
450
+ }
451
+
452
+ let isFirstInit = true;
453
+
454
+ for (const adminEmail of adminEmails) {
455
+ const existingUser = await ctx.orm.query.user.findFirst({
456
+ where: { email: adminEmail },
457
+ });
458
+
459
+ if (existingUser) {
460
+ isFirstInit = false;
461
+ continue;
462
+ }
463
+
464
+ await createUser(ctx, {
465
+ email: adminEmail,
466
+ name: "Admin",
467
+ role: "admin",
468
+ });
469
+ }
470
+
471
+ if (isFirstInit && getEnv().DEPLOY_ENV === "development") {
472
+ const handler = createSeedHandler(ctx);
473
+ await handler.seed({});
474
+ }
475
+
476
+ return null;
477
+ });
478
+ ```
479
+
480
+ **Create:** `convex/functions/reset.ts`
481
+
482
+ ```ts
483
+ /** biome-ignore-all lint/suspicious/noExplicitAny: dev */
484
+ import { eq } from "kitcn/orm";
485
+ import { CRPCError } from "kitcn/server";
486
+ import { z } from "zod";
487
+
488
+ import { privateAction, privateMutation } from "../lib/crpc";
489
+ import { getEnv } from "../lib/get-env";
490
+ import type { TableNames } from "./_generated/dataModel";
491
+ import { createResetCaller } from "./generated/reset.runtime";
492
+ import schema, { tables } from "./schema";
493
+
494
+ const DELETE_BATCH_SIZE = 64;
495
+ const excludedTables = new Set<TableNames>();
496
+
497
+ const assertDevOnly = () => {
498
+ if (getEnv().DEPLOY_ENV === "production") {
499
+ throw new CRPCError({
500
+ code: "FORBIDDEN",
501
+ message: "This function is only available in development",
502
+ });
503
+ }
504
+ };
505
+
506
+ export const reset = privateAction.action(async ({ ctx }) => {
507
+ assertDevOnly();
508
+ const caller = createResetCaller(ctx);
509
+
510
+ for (const tableName of Object.keys(schema.tables)) {
511
+ if (excludedTables.has(tableName as TableNames)) {
512
+ continue;
513
+ }
514
+
515
+ await caller.schedule.now.deletePage({
516
+ cursor: null,
517
+ tableName,
518
+ });
519
+ }
520
+
521
+ return null;
522
+ });
523
+
524
+ export const deletePage = privateMutation
525
+ .input(
526
+ z.object({
527
+ cursor: z.union([z.string(), z.null()]),
528
+ tableName: z.string(),
529
+ }),
530
+ )
531
+
532
+ .mutation(async ({ ctx, input }) => {
533
+ assertDevOnly();
534
+ const caller = createResetCaller(ctx);
535
+
536
+ const table = (tables as Record<string, any>)[input.tableName];
537
+ if (!table) {
538
+ throw new CRPCError({
539
+ code: "BAD_REQUEST",
540
+ message: `Unknown table: ${input.tableName}`,
541
+ });
542
+ }
543
+
544
+ const query = (ctx.orm.query as Record<string, any>)[input.tableName];
545
+ if (!query || typeof query.findMany !== "function") {
546
+ throw new CRPCError({
547
+ code: "BAD_REQUEST",
548
+ message: `Unknown query table: ${input.tableName}`,
549
+ });
550
+ }
551
+
552
+ const results = await query.findMany({
553
+ cursor: input.cursor,
554
+ limit: DELETE_BATCH_SIZE,
555
+ });
556
+
557
+ for (const row of results.page) {
558
+ try {
559
+ await ctx.orm.delete(table).where(eq(table.id, (row as any).id));
560
+ } catch {
561
+ // Can already be deleted by trigger or concurrent process.
562
+ }
563
+ }
564
+
565
+ if (!results.isDone) {
566
+ await caller.schedule.now.deletePage({
567
+ cursor: results.continueCursor,
568
+ tableName: input.tableName,
569
+ });
570
+ }
571
+
572
+ return null;
573
+ });
574
+ ```
575
+
576
+ `convex/functions/seed.ts` stays project-specific, but should expose a `privateMutation` entrypoint used by `init.ts`.
577
+
578
+ Recommended scripts:
579
+
580
+ ```json
581
+ {
582
+ "scripts": {
583
+ "convex:dev": "kitcn dev",
584
+ "verify": "kitcn verify",
585
+ "reset": "kitcn reset --yes --after init",
586
+ "seed": "convex run seed:seed",
587
+ "env:push": "kitcn env push",
588
+ "env:push:rotate": "kitcn env push --rotate"
589
+ }
590
+ }
591
+ ```
592
+
593
+ Set `dev.preRun = "init"` in `kitcn.json` when the
594
+ app owns an `init.ts` preflight.
595
+
596
+ CLI commands:
597
+
598
+ ```bash
599
+ bunx kitcn dev
600
+ # deterministic one-shot local runtime proof:
601
+ bunx kitcn verify
602
+ # optional fallback only if dev cannot run and backend is already active:
603
+ bunx kitcn codegen
604
+ bunx kitcn env push
605
+ bunx kitcn env push --prod
606
+ bunx kitcn env push --rotate
607
+ # deploy with automatic aggregate backfill:
608
+ bunx kitcn deploy --prod
609
+ # aggregate index management:
610
+ bunx kitcn aggregate rebuild --prod
611
+ bunx kitcn aggregate backfill --prod
612
+ # bundle analysis:
613
+ bunx kitcn analyze
614
+ ```
615
+
616
+ On backend `convex`, `kitcn dev` watches `convex/.env` during a local
617
+ dev session and auto-pushes later edits. Keep `env push` for `--prod`,
618
+ `--rotate`, or explicit repair against an already active deployment.
619
+
620
+ ### 11.2 Phase A gate: non-auth baseline (required before auth work)
621
+
622
+ Run these after base setup (Sections 3-5) and before starting Section 6:
623
+
624
+ ```bash
625
+ bunx kitcn verify
626
+ bunx convex run internal.seed.seed
627
+ bunx convex run internal.init.default
628
+ # run project checks after bootstrap smoke:
629
+ bun run typecheck || bunx tsc --noEmit
630
+ bun test
631
+ bun run build
632
+ ```
633
+
634
+ Then sanity-check runtime paths (non-auth only):
635
+
636
+ 1. Run one public query endpoint.
637
+ 2. Run one public mutation endpoint.
638
+ 3. Run one public HTTP route endpoint.
639
+ 4. Do not proceed to Section 6 until this gate is green.
640
+
641
+ ### 11.3 Phase B gate: auth sign-in working (required before optional modules/plugins)
642
+
643
+ Run this after Section 6 and before Sections 7-10:
644
+
645
+ ```bash
646
+ bunx kitcn verify
647
+ bun run typecheck || bunx tsc --noEmit
648
+ bun test
649
+ bun run build
650
+ ```
651
+
652
+ Then sanity-check auth runtime paths:
653
+
654
+ 1. Sign in successfully from `/auth` in headed browser.
655
+ 2. Run one protected query/mutation in signed-in context and confirm success.
656
+ 3. Run one protected endpoint in signed-out context and confirm `UNAUTHORIZED`.
657
+ 4. Do not proceed to optional modules/plugins until this gate is green.
658
+
659
+ ## 12. Final From-Scratch Execution Checklist
660
+
661
+ 1. `convex.json` configured with `functions: convex/functions` and static codegen enabled.
662
+ 2. `tsconfig.json` has `strictFunctionTypes: false` and `@convex/*` alias.
663
+ 3. `.env.local` has `NEXT_PUBLIC_CONVEX_URL` and `NEXT_PUBLIC_CONVEX_SITE_URL`.
664
+ 4. `schema.ts` + `relations` + generated `initCRPC` wiring are in place.
665
+ 5. `crpc.ts` builders exported and app procedures use `ctx.orm`.
666
+ 6. `kitcn dev` runs and generates `_generated` + `api.ts`.
667
+ 7. If auth enabled: `auth.config.ts`, `auth.ts`, `http.ts`, and env bootstrap
668
+ are complete.
669
+ 8. Client `CRPCProvider` + QueryClient + Convex provider are mounted.
670
+ 9. Framework branch is complete (Next.js or TanStack Start).
671
+ 10. If using typed envs: `convex/lib/get-env.ts` exists and Convex code reads through `getEnv()`.
672
+ 11. Optional modules/plugins added only if selected.
673
+ 12. If multiple components enabled: `convex/functions/convex.config.ts` composes all `app.use(...)` calls in one file.
674
+ 13. If organizations + invite mail enabled: `email.tsx` + invite template + resend component are wired.
675
+ 14. If dev bootstrap mode enabled: `init.ts`, `seed.ts`, `reset.ts` exist and scripts call them.
676
+ 15. If `Aggregates: No`, no aggregate helper/import/config references remain.
677
+ 16. Phase A gate (Section 11.2) passes before any auth implementation.
678
+ 17. If auth enabled: Phase B auth sign-in gate (Section 11.3) passes before optional modules/plugins.
679
+ 18. No legacy Ents patterns in setup code.
680
+ 19. NEVER use `@ts-nocheck` in app/convex source files.
681
+
682
+ ## 13. Troubleshooting
683
+
684
+ See the [Troubleshooting Reference](#troubleshooting-reference) at the bottom of this document for the full symptom/cause/fix matrix.
685
+
686
+ ## Coverage Matrix
687
+
688
+ Source coverage mapping used to build this runbook:
689
+
690
+ | Source | Mapped In Setup |
691
+ | ------------------------------------------------- | -------------------- |
692
+ | `www/content/docs/cli/registry.mdx` | Sections 3, 11 |
693
+ | `www/content/docs/quickstart.mdx` | Sections 3, 4, 11, 12 |
694
+ | `www/content/docs/server/setup.mdx` | Section 5.3 |
695
+ | `www/content/docs/auth/server.mdx` | Sections 6.1 - 6.10 |
696
+ | `www/content/docs/auth/client.mdx` | Section 7.1 |
697
+ | `www/content/docs/auth/server.mdx#triggers` | Section 6.3, 9.2 |
698
+ | `www/content/docs/react/index.mdx` | Sections 7.2 - 7.4 |
699
+ | `www/content/docs/nextjs/index.mdx` | Section 8.A |
700
+ | `www/content/docs/tanstack-start.mdx` | Section 8.B |
701
+ | `www/content/docs/server/http.mdx` | Sections 6.6, 9.6 |
702
+ | `www/content/docs/server/server-side-calls.mdx` | Section 8.A.1, 8.B.3 |
703
+ | `www/content/docs/plugins/ratelimit.mdx` | Section 9.4 |
704
+ | `www/content/docs/orm/queries/aggregates.mdx` | Section 9.3 |
705
+ | `www/content/docs/server/scheduling.mdx` | Section 9.5 |
706
+ | `www/content/docs/orm/queries/index.mdx` | Sections 5, 12 |
707
+ | `www/content/docs/orm/mutations/index.mdx` | Sections 5, 12 |
708
+ | `www/content/docs/orm/triggers.mdx` | Sections 9.2, 9.3 |
709
+ | `www/content/docs/orm/rls.mdx` | Section 9.1 |
710
+ | `www/content/docs/auth/plugins/admin.mdx` | Section 10.1 |
711
+ | `www/content/docs/auth/plugins/organizations.mdx` | Section 10.2 |
712
+ | `www/content/docs/auth/plugins/polar.mdx` | Section 10.3 |
713
+ | `www/content/docs/cli/backend.mdx` | Section 11 |
714
+
715
+ ### Template Coverage (Recreation Target)
716
+
717
+ This runbook + references map to the canonical template shape as follows:
718
+
719
+ | Example Group | Primary Setup Section | Additional Reference |
720
+ | --------------------------------------------------------------------------------------------------------- | ------------------------------- | ---------------------------------------- |
721
+ | Core infra (`schema.ts`, `functions/generated/`, `crpc.ts`, `http.ts`) | Sections 5, 6.6, 9.6 | `orm.md`, `http.md` |
722
+ | Shared contracts (`shared/api.ts`, `shared/auth-shared.ts`, `shared/polar-shared.ts`) | Sections 5.4, 6.3.2, 10.2, 10.3 | `auth-organizations.md` |
723
+ | Auth core (`auth.config.ts`, `auth.ts`) | Section 6 | `auth.md` |
724
+ | Auth plugins (`admin.ts`, `organization.ts`, `polar*`) | Section 10 | `auth-admin.md`, `auth-organizations.md` |
725
+ | Feature modules (`user.ts`, `projects.ts`, `tags.ts`, `todoComments.ts`, `public.ts`, `items/queries.ts`) | Sections 5, 6.3.1, 9 | core `SKILL.md`, `orm.md` |
726
+ | HTTP routers (`routers/health.ts`, `routers/todos.ts`, `routers/examples.ts`) | Section 9.6 | `http.md` |
727
+ | Aggregates + rate limits (`aggregates.ts`, `lib/plugins/ratelimit/plugin.ts`) | Sections 9.3, 9.4 | `aggregates.md`, `orm.md` |
728
+ | Scheduling + internals (`todoInternal.ts`, delayed jobs) | Sections 9.5, 11.1 | `scheduling.md` |
729
+ | Email + Resend (`functions/plugins/email.tsx`, `lib/plugins/resend/*`) | Section 9.7 | `auth-organizations.md` |
730
+ | Dev bootstrap (`init.ts`, `seed.ts`, `reset.ts`) | Section 11.1 | `testing.md` (for verification) |
731
+ | Generated outputs (`functions/_generated/*`, `functions/generated/`, `shared/api.ts`) | Section 5.5 | n/a (generated by CLI) |
732
+
733
+ ## Troubleshooting Reference
734
+
735
+ | Symptom | Likely Cause | Fix |
736
+ | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
737
+ | `@convex/api` not found | `kitcn dev` not run | Run `bunx kitcn dev` and regenerate API metadata |
738
+ | `Cannot prompt for input in non-interactive terminals` during bootstrap | Convex deployment selection still needs a local choice | Use `bunx kitcn verify` for local proof, or pass `--env-file` / deployment-target args so Convex can resolve the deployment without prompting |
739
+ | Can't find new local backend files under `~/.convex` | Convex now stores new local deployment state per project | Check `.convex/local/default/` in the current project root; treat `~/.convex/**` as legacy storage |
740
+ | `kitcn env push` fails to set auth vars | Target deployment is not active or not initialized | For local proof, run `bunx kitcn verify`. For remote targets, resolve deployment targeting, then rerun `bunx kitcn env push` |
741
+ | `Failed to analyze auth.js` with `Unexpected token` / `map is not a function` on JWKS | Static `JWKS` value is malformed JSON | Unset/fix `JWKS`; use `getAuthConfigProvider()` fallback or repush with `bunx kitcn env push` |
742
+ | `Local backend isn't running` during manual `kitcn codegen` | Convex local deployment not active | Prefer `bunx kitcn dev` (it already codegens); use manual `codegen` only as fallback with active backend |
743
+ | HTTP calls fail but queries work | `.site` URL missing or wrong | Set `NEXT_PUBLIC_CONVEX_SITE_URL` correctly |
744
+ | Auth works locally but fails in prod | JWKS not pushed | Run `bunx kitcn env push --prod` |
745
+ | Sign-in fails on `/auth` (loop, no session, or immediate sign-out) | Auth route/env/provider wiring mismatch | Recheck Sections 6.5-6.7 (`authMiddleware`, route registration, env push), verify provider credentials/URLs, then rerun Section 11.3 |
746
+ | `UNAUTHORIZED` on protected procedures | auth middleware not attaching `userId` | Ensure `getAuth(ctx)` + `getHeaders(ctx)` session lookup is in middleware |
747
+ | `ctx.orm` missing in handlers | Generated `initCRPC` not used | Use `initCRPC` from `../functions/generated/server` — ORM context is pre-wired |
748
+ | `Property 'insert'/'update' does not exist on type 'OrmReader'` | Using query context for mutations | Ensure mutation handlers use `publicMutation` / `protectedMutation` builders |
749
+ | `useCRPC must be used within CRPCProvider` | Provider chain not mounted around route tree | Wrap app with `AppConvexProvider` and verify `CRPCProvider` is inside QueryClientProvider (Section 7.4 / 8.A.4) |
750
+ | Route auth cookies not set | Missing CORS auth headers | Add `Better-Auth-Cookie` allow/expose headers + credentials |
751
+ | TanStack Start auth helper import errors | Using `kitcn/auth/nextjs` in Start app | Use TanStack Start exception with `@convex-dev/better-auth/*` helpers |
752
+ | `Returned promise will never resolve` from internal function | Trigger path is recursively querying/updating related rows or stale component wiring still runs | Isolate failing write with logs, disable/move trigger-side sync into explicit mutation helper, rerun `bunx kitcn verify`, then retry the runtime proof |
753
+ | Better Auth secret mismatch/warnings in setup flows | `BETTER_AUTH_SECRET` manually set inconsistently or low entropy | Let `bunx kitcn dev` manage local bootstrap, or regenerate/push via `bunx kitcn env push` for active non-local targets |
754
+ | `Invalid orderBy value. Use a column or asc()/desc()` | Wrong `orderBy` shape (`[{ field, direction }]`) | Use object form only, e.g. `orderBy: { updatedAt: "desc" }` |
755
+ | `Invalid argument id for db.get` while testing `NOT_FOUND` | Fabricated Convex document ID | Use real inserted IDs or non-ID lookup keys (slug/name/email) for not-found tests |
756
+ | Trigger side effects too slow | Heavy sync work inside trigger | Move heavy work to scheduled actions via `ctx.scheduler` |
757
+ | Rate limiter throws missing-table/setup guidance | local ratelimit scaffold missing or not registered | Run `bunx kitcn add ratelimit`, then ensure `convex/functions/schema.ts` imports `../lib/plugins/ratelimit/schema` |
758
+ | fallback `kitcn codegen` fails after disabling aggregates | Aggregate helper/import references still exist | Remove `app.use(aggregate...)`, `defineTriggers` aggregate handlers, and aggregate helper modules in the same change; prefer rerunning `kitcn verify` |
759
+ | Aggregate counts drift | trigger not registered in `defineTriggers` | Register `aggregate.trigger` in `defineTriggers` `change:` handler |
760
+ | Invite emails never send | Resend schema scaffold missing or not registered | Run `bunx kitcn add resend`, ensure `convex/functions/schema.ts` imports `../lib/plugins/resend/schema`, and wire `internal.plugins.email.sendTemplatedEmail` |
761
+ | Dev reset/seed commands do nothing | `init.ts`/`seed.ts`/`reset.ts` missing or not wired | Add dev bootstrap functions and scripts from Section 11.1 |