@donotdev/cli 0.0.13 → 0.0.15

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 (162) hide show
  1. package/dependencies-matrix.json +357 -89
  2. package/dist/bin/commands/agent-setup.d.ts +6 -0
  3. package/dist/bin/commands/agent-setup.d.ts.map +1 -0
  4. package/dist/bin/commands/agent-setup.js +629 -0
  5. package/dist/bin/commands/agent-setup.js.map +1 -0
  6. package/dist/bin/commands/build.js +131 -50
  7. package/dist/bin/commands/bump.js +137 -49
  8. package/dist/bin/commands/cacheout.js +50 -21
  9. package/dist/bin/commands/create-app.js +270 -261
  10. package/dist/bin/commands/create-project.js +418 -197
  11. package/dist/bin/commands/deploy.js +1752 -712
  12. package/dist/bin/commands/dev.js +151 -35
  13. package/dist/bin/commands/emu.js +228 -70
  14. package/dist/bin/commands/format.js +50 -21
  15. package/dist/bin/commands/lint.js +50 -21
  16. package/dist/bin/commands/preview.js +155 -35
  17. package/dist/bin/commands/supabase-setup.d.ts +6 -0
  18. package/dist/bin/commands/supabase-setup.d.ts.map +1 -0
  19. package/dist/bin/commands/supabase-setup.js +7 -0
  20. package/dist/bin/commands/supabase-setup.js.map +1 -0
  21. package/dist/bin/commands/sync-secrets.js +224 -46
  22. package/dist/bin/commands/type-check.d.ts +14 -0
  23. package/dist/bin/commands/type-check.d.ts.map +1 -0
  24. package/dist/bin/commands/type-check.js +314 -0
  25. package/dist/bin/commands/type-check.js.map +1 -0
  26. package/dist/bin/commands/wai.js +7399 -11
  27. package/dist/bin/dndev.js +27 -2
  28. package/dist/bin/donotdev.js +27 -2
  29. package/dist/index.js +3960 -2996
  30. package/package.json +2 -2
  31. package/templates/app-demo/src/App.tsx.example +1 -0
  32. package/templates/app-demo/src/pages/FullPage.tsx.example +2 -2
  33. package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +2 -2
  34. package/templates/app-demo/src/themes.css.example +5 -12
  35. package/templates/app-expo/.env.example +64 -0
  36. package/templates/app-expo/.expo/README.md.example +5 -0
  37. package/templates/app-expo/.gitignore.example +36 -0
  38. package/templates/app-expo/README.md.example +58 -0
  39. package/templates/app-expo/app/.gitkeep +2 -0
  40. package/templates/app-expo/app/_layout.tsx.example +41 -0
  41. package/templates/app-expo/app/form.tsx.example +52 -0
  42. package/templates/app-expo/app/index.tsx.example +89 -0
  43. package/templates/app-expo/app/list.tsx.example +32 -0
  44. package/templates/app-expo/app/profile.tsx.example +76 -0
  45. package/templates/app-expo/app/signin.tsx.example +53 -0
  46. package/templates/app-expo/app.json.example +39 -0
  47. package/templates/app-expo/babel.config.js.example +10 -0
  48. package/templates/app-expo/eas.json.example +20 -0
  49. package/templates/app-expo/expo-env.d.ts.example +4 -0
  50. package/templates/app-expo/metro.config.js.example +20 -0
  51. package/templates/app-expo/service-account-key.json.example +12 -0
  52. package/templates/app-expo/tsconfig.json.example +19 -0
  53. package/templates/app-next/.env.example +4 -33
  54. package/templates/app-next/src/app/ClientLayout.tsx.example +2 -0
  55. package/templates/app-next/src/app/layout.tsx.example +7 -6
  56. package/templates/app-next/src/globals.css.example +2 -11
  57. package/templates/app-next/src/pages/HomePage.tsx.example +1 -1
  58. package/templates/app-next/src/themes.css.example +10 -13
  59. package/templates/app-vite/.env.example +3 -32
  60. package/templates/app-vite/index.html.example +2 -24
  61. package/templates/app-vite/src/App.tsx.example +2 -0
  62. package/templates/app-vite/src/globals.css.example +2 -12
  63. package/templates/app-vite/src/pages/FormPageExample.tsx.example +1 -2
  64. package/templates/app-vite/src/pages/HomePage.tsx.example +1 -1
  65. package/templates/app-vite/src/themes.css.example +109 -79
  66. package/templates/app-vite/vercel.json.example +11 -0
  67. package/templates/functions-firebase/build.mjs.example +2 -72
  68. package/templates/functions-firebase/functions-firebase/.env.example.example +23 -25
  69. package/templates/functions-firebase/functions-firebase/build.mjs.example +2 -72
  70. package/templates/functions-firebase/functions-firebase/tsconfig.json.example +1 -1
  71. package/templates/functions-supabase/supabase/functions/cancel-subscription/index.ts.example +7 -0
  72. package/templates/functions-supabase/supabase/functions/change-plan/index.ts.example +11 -0
  73. package/templates/functions-supabase/supabase/functions/create-checkout-session/index.ts.example +11 -0
  74. package/templates/functions-supabase/supabase/functions/create-customer-portal/index.ts.example +7 -0
  75. package/templates/functions-supabase/supabase/functions/crud/index.ts.example +16 -0
  76. package/templates/functions-supabase/supabase/functions/delete-account/index.ts.example +7 -0
  77. package/templates/functions-supabase/supabase/functions/get-custom-claims/index.ts.example +7 -0
  78. package/templates/functions-supabase/supabase/functions/get-user-auth-status/index.ts.example +7 -0
  79. package/templates/functions-supabase/supabase/functions/refresh-subscription-status/index.ts.example +7 -0
  80. package/templates/functions-supabase/supabase/functions/remove-custom-claims/index.ts.example +7 -0
  81. package/templates/functions-supabase/supabase/functions/set-custom-claims/index.ts.example +7 -0
  82. package/templates/functions-supabase/supabase/migrations/20250101000000_idempotency.sql +24 -0
  83. package/templates/functions-supabase/supabase/migrations/20250101000001_rate_limits.sql +22 -0
  84. package/templates/functions-supabase/supabase/migrations/20250101000002_cleanup_jobs.sql +28 -0
  85. package/templates/functions-supabase/supabase/migrations/20250101000003_operation_metrics.sql +28 -0
  86. package/templates/functions-vercel/functions-vercel/tsconfig.json.example +1 -1
  87. package/templates/functions-vercel/functions-vercel/vercel.json.example +1 -1
  88. package/templates/functions-vercel/vercel.json.example +1 -1
  89. package/templates/github/github/workflows/firebase-deploy.yml.example +1 -1
  90. package/templates/github/workflows/firebase-deploy.yml.example +1 -1
  91. package/templates/overlay-firebase/env.fragment.example +34 -0
  92. package/templates/overlay-firebase/env.fragment.expo.example +34 -0
  93. package/templates/overlay-firebase/env.fragment.nextjs.example +34 -0
  94. package/templates/overlay-firebase/src/config/providers.expo.ts.example +49 -0
  95. package/templates/overlay-firebase/src/config/providers.ts.example +23 -0
  96. package/templates/overlay-supabase/env.fragment.example +7 -0
  97. package/templates/overlay-supabase/env.fragment.expo.example +7 -0
  98. package/templates/overlay-supabase/env.fragment.nextjs.example +7 -0
  99. package/templates/overlay-supabase/src/config/providers.expo.ts.example +35 -0
  100. package/templates/overlay-supabase/src/config/providers.ts.example +33 -0
  101. package/templates/overlay-supabase/vercel.headers.example +23 -0
  102. package/templates/overlay-supabase/vercel.json.example +22 -0
  103. package/templates/overlay-vercel/env.fragment.example +34 -0
  104. package/templates/overlay-vercel/env.fragment.nextjs.example +34 -0
  105. package/templates/overlay-vercel/src/config/providers.ts.example +24 -0
  106. package/templates/root-consumer/.claude/agents/architect.md.example +2 -310
  107. package/templates/root-consumer/.claude/agents/builder.md.example +2 -326
  108. package/templates/root-consumer/.claude/agents/coder.md.example +2 -83
  109. package/templates/root-consumer/.claude/agents/extractor.md.example +2 -231
  110. package/templates/root-consumer/.claude/agents/polisher.md.example +2 -132
  111. package/templates/root-consumer/.claude/agents/prompt-engineer.md.example +2 -81
  112. package/templates/root-consumer/.claude/commands/brainstorm.md.example +1 -1
  113. package/templates/root-consumer/.claude/commands/build.md.example +1 -1
  114. package/templates/root-consumer/.claude/commands/design.md.example +1 -1
  115. package/templates/root-consumer/.claude/commands/grill.md.example +30 -0
  116. package/templates/root-consumer/.claude/commands/polish.md.example +1 -1
  117. package/templates/root-consumer/.claude/commands/techdebt.md.example +28 -0
  118. package/templates/root-consumer/.clinerules.example +1 -0
  119. package/templates/root-consumer/.cursor/rules/no-docs.mdc.example +15 -0
  120. package/templates/root-consumer/.cursorrules.example +1 -0
  121. package/templates/root-consumer/.dndev/args.json.example +6 -0
  122. package/templates/root-consumer/.gemini/settings.json.example +2 -2
  123. package/templates/root-consumer/.github/copilot-instructions.md.example +1 -0
  124. package/templates/root-consumer/.windsurfrules.example +1 -0
  125. package/templates/root-consumer/AI.md.example +25 -108
  126. package/templates/root-consumer/CLAUDE.md.example +1 -128
  127. package/templates/root-consumer/CONVENTIONS.md.example +1 -0
  128. package/templates/root-consumer/GEMINI.md.example +1 -0
  129. package/templates/root-consumer/firebase.json.example +1 -1
  130. package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +54 -0
  131. package/templates/root-consumer/guides/dndev/COMPONENTS_ADV.md.example +0 -18
  132. package/templates/root-consumer/guides/dndev/COMPONENTS_UI.md.example +1 -1
  133. package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +99 -30
  134. package/templates/root-consumer/guides/dndev/GOTCHAS.md.example +186 -0
  135. package/templates/root-consumer/guides/dndev/INDEX.md.example +4 -1
  136. package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +143 -12
  137. package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +9 -3
  138. package/templates/root-consumer/guides/dndev/SETUP_FUNCTIONS.md.example +12 -7
  139. package/templates/root-consumer/guides/dndev/SETUP_SOC2.md.example +234 -0
  140. package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +124 -0
  141. package/templates/root-consumer/guides/dndev/SETUP_THEMES.md.example +6 -2
  142. package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +176 -0
  143. package/templates/root-consumer/guides/dndev/USE_ROUTING.md.example +5 -9
  144. package/templates/root-consumer/guides/dndev/essences_reference.css.example +174 -0
  145. package/templates/root-consumer/guides/wai-way/agents/builder.md.example +10 -0
  146. package/templates/root-consumer/guides/wai-way/agents/extractor.md.example +25 -5
  147. package/templates/root-consumer/guides/wai-way/agents/polisher.md.example +13 -2
  148. package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +2 -2
  149. package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +47 -11
  150. package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +15 -4
  151. package/templates/root-consumer/guides/wai-way/spec_template.md.example +7 -6
  152. package/templates/app-payload/.env.example +0 -28
  153. package/templates/app-payload/README.md.example +0 -233
  154. package/templates/app-payload/collections/Company.ts.example +0 -125
  155. package/templates/app-payload/collections/Hero.ts.example +0 -62
  156. package/templates/app-payload/collections/Media.ts.example +0 -41
  157. package/templates/app-payload/collections/Products.ts.example +0 -115
  158. package/templates/app-payload/collections/Services.ts.example +0 -104
  159. package/templates/app-payload/collections/Testimonials.ts.example +0 -92
  160. package/templates/app-payload/collections/Users.ts.example +0 -35
  161. package/templates/app-payload/src/server.ts.example +0 -79
  162. package/templates/app-payload/tsconfig.json.example +0 -24
@@ -0,0 +1 @@
1
+ Enforce AI.md
@@ -314,7 +314,7 @@
314
314
  "**/*.test.ts",
315
315
  "**/__tests__/**"
316
316
  ],
317
- "runtime": "nodejs20"
317
+ "runtime": "nodejs22"
318
318
  }
319
319
  ],
320
320
  "firestore": {
@@ -9,6 +9,26 @@
9
9
 
10
10
  ---
11
11
 
12
+ ## Getting Started (for humans)
13
+
14
+ **Canonical flow:** The showcase app’s **Get Started** page is the single source of truth: `apps/showcase/src/pages/GetStartedPage.tsx` and `apps/showcase/src/pages/locales/getstarted_*.json`. Below is the same flow in short form.
15
+
16
+ 1. **P0 — Prerequisites**
17
+ - **Runtime:** **Node.js 24** (nodejs.org) and **Bun 1.3+** (bun.sh). Both required.
18
+ - **IDE:** Any IDE (Cursor, VS Code, Windsurf, etc.). Need help? Use the collapsible “Need help setting up?” on the Get Started page.
19
+ 2. **Install our CLI and create your project’s monorepo**
20
+ - `npm install -g @donotdev/cli`
21
+ - `dndev init my-app`
22
+ 3. **Open the repo in your IDE, terminal, bun install**
23
+ - Start your IDE in that repo, open the terminal: `cd my-app` → `bun install`
24
+ 4. **Enable MCP, then read AI.md and follow the flow**
25
+ - Talk with your agent; ask it to load the MCP (Cursor: Ctrl+Shift+P → “MCP Server” → enable “donotdev”; other IDEs: see “How to enable MCP” collapsible on the Get Started page).
26
+ - Then have the agent read the root **`AI.md`** and this file (**`guides/dndev/AGENT_START_HERE.md`**). Follow the phases.
27
+ 5. **AI helps with provider; cd there, bun install, run**
28
+ - AI helps you choose and set up your provider (Firebase, Supabase, or custom). Then `cd` into the app directory if needed, `bun install`, and `dndev dev` / `dndev build` / `dndev deploy`.
29
+
30
+ ---
31
+
12
32
  ## First Thing to Call: list_features()
13
33
 
14
34
  Call **`list_features()`** before designing or coding. It lists all framework packages with a one-line summary from each README (templates, core, ui, auth, billing, etc.). Use it so you don't reinvent what the framework already provides (blog, CRUD, billing, legal pages, etc.).
@@ -63,4 +83,38 @@ Check that the user has completed environment setup:
63
83
 
64
84
  If not, coach them: "Run `dndev firebase:setup` first, then follow the prompts." See [SETUP_FIREBASE.md](./SETUP_FIREBASE.md).
65
85
 
86
+ ---
87
+
88
+ ## Project Args (`.dndev/args.json`)
89
+
90
+ Generated by `dndev init`. All features ON by default — Phase 0 narrows down based on what the user actually needs.
91
+
92
+ ```json
93
+ {
94
+ "platform": "firebase",
95
+ "strictness": "enforced",
96
+ "features": ["crud", "auth", "i18n", "billing", "oauth", "functions"],
97
+ "region": "europe-west1"
98
+ }
99
+ ```
100
+
101
+ | Field | Values | Effect |
102
+ |-------|--------|--------|
103
+ | `platform` | `firebase`, `vercel` | Derived from builder choice |
104
+ | `strictness` | `enforced`, `warnings`, `permissive` | `enforced` = blocks `complete_phase` on convention violations. `warnings` = reports but allows. `permissive` = skips checks. |
105
+ | `features` | `crud`, `auth`, `i18n`, `billing`, `oauth`, `functions` | Filters gotchas — remove features the project doesn't use to reduce noise |
106
+ | `region` | any GCP region | Informational, shown in `start_phase` context |
107
+
108
+ `start_phase()` returns project args + phase-relevant gotchas automatically. `complete_phase()` respects `strictness`.
109
+
110
+ **Without MCP:** `args.json` and `GOTCHAS.md` are plain files. Any agent can read them directly.
111
+
112
+ ---
113
+
114
+ ## Gotchas (`guides/dndev/GOTCHAS.md`)
115
+
116
+ Common mistakes, phase-tagged. `start_phase(N)` automatically filters and returns only the gotchas relevant to phase N and your enabled features. Read the full file for reference: [GOTCHAS.md](../guides/dndev/GOTCHAS.md).
117
+
118
+ ---
119
+
66
120
  **Starting:** Call `list_features()` first, then `get_phase_status()` to see where you are, then `start_phase(0)` to begin.
@@ -335,24 +335,6 @@ import { StartChallengeForm } from '@donotdev/adv-comps';
335
335
  />
336
336
  ```
337
337
 
338
- ### Waterfall
339
-
340
- Waterfall component with lazy loading built-in. Features clean cascade layout with diagonal staircase effect, perfect for step-by-step processes or feature showcases.
341
-
342
- ```tsx
343
- import { Waterfall } from '@donotdev/adv-comps';
344
- import type { WaterfallProps } from '@donotdev/adv-comps';
345
-
346
- <Waterfall
347
- items: ComponentData[]
348
- className?: string
349
- connectorClassName?: string
350
- density?: 'compact' | 'comfortable'
351
- ariaLabel?: string
352
- direction?: 'horizontal' | 'descending'
353
- />
354
- ```
355
-
356
338
  ## Notes
357
339
 
358
340
  - All components are lazy-loaded by default for optimal performance
@@ -83,7 +83,7 @@
83
83
  - **usePrefetch** - Prefetch route data.
84
84
  - **useLocation** - Get current location.
85
85
  - **useParams** - Get route parameters.
86
- - **useSearchParams** - Get URL search parameters.
86
+ - **useSearchParams** - Get URL search parameters. Returns `URLSearchParams` directly (NOT a tuple). Use `.get('key')` to read values.
87
87
  - **useMatch** - Match current route pattern.
88
88
  - **useQueryParams** - Get and set query parameters.
89
89
  - **useRedirectGuard** - Guard against redirects.
@@ -2,16 +2,20 @@
2
2
 
3
3
  **The complete onboarding flow — from `dndev init` to deployed app.**
4
4
 
5
+ If you haven’t run `dndev init` yet, see [AGENT_START_HERE.md](./AGENT_START_HERE.md) § **Getting started (for humans)** (P0 → Install CLI → Run AI.md → Enjoy).
6
+
5
7
  ---
6
8
 
7
9
  ## The Flow
8
10
 
9
11
  ```
10
- bun install install dependencies
11
- bun dev start app, read the homepage setup guide
12
- dndev firebase:setup configure Firebase project + .env
13
- dndev emu start → test locally with emulators
14
- dndev deploy → deploy to production
12
+ bun install -> install dependencies
13
+ bun dev -> start app, read the homepage setup guide
14
+ dndev firebase:setup -> configure Firebase project + .env
15
+ -- or --
16
+ dndev supabase:setup -> configure Supabase project + .env
17
+ dndev emu start -> test locally with emulators (Firebase)
18
+ dndev deploy -> deploy to production
15
19
  ```
16
20
 
17
21
  ---
@@ -43,29 +47,45 @@ git push -u origin main
43
47
 
44
48
  ---
45
49
 
46
- ## Step 3: Firebase
50
+ ## Step 3: Backend Setup
51
+
52
+ ### Firebase
47
53
 
48
54
  ```bash
49
55
  dndev firebase:setup
50
56
  ```
51
57
 
52
- Automates: project selection/creation, web app, SDK config `.env`, `.firebaserc`.
58
+ Automates: project selection/creation, web app, SDK config -> `.env`, `.firebaserc`.
53
59
 
54
60
  Then 2 manual steps (CLI gives you direct links):
55
- 1. Download service account key save as `service-account-key.json`
61
+ 1. Download service account key -> save as `service-account-key.json`
56
62
  2. Enable Auth + Firestore in Firebase Console
57
63
 
58
64
  See [SETUP_FIREBASE.md](./SETUP_FIREBASE.md) for full details.
59
65
 
66
+ ### Supabase
67
+
68
+ ```bash
69
+ dndev supabase:setup
70
+ ```
71
+
72
+ Asks for your **public** project URL and anon key (both safe to share -- shipped in client bundle).
73
+
74
+ Get them from: https://supabase.com/dashboard -> your project -> Settings -> API
75
+
76
+ See [SETUP_SUPABASE.md](./SETUP_SUPABASE.md) for full details (tables, RLS, `dn generate sql`). See [Secrets Philosophy](#secrets-philosophy) for how we handle secret keys.
77
+
60
78
  ---
61
79
 
62
80
  ## Step 4: Test Locally
63
81
 
64
82
  ```bash
65
- dndev emu start
83
+ dndev emu start # Firebase emulators
66
84
  ```
67
85
 
68
- Select Auth + Firestore + Functions. Develops against local emulators.
86
+ Select services: Auth + Firestore + Functions. This starts Firebase emulators so you can develop without touching production.
87
+
88
+ For Supabase, development runs against your Supabase project directly (or use `supabase start` for local Supabase if installed).
69
89
 
70
90
  ---
71
91
 
@@ -74,11 +94,11 @@ Select Auth + Firestore + Functions. Develops against local emulators.
74
94
  Open the project in **Cursor**, **Claude Code**, **Windsurf**, or **AntiGravity**.
75
95
 
76
96
  The AI reads `AI.md` and follows the WAI-WAY protocol:
77
- - Phase 0: Brainstorm produce a spec
78
- - Phase 1: Scaffold create pages
79
- - Phase 2: Entities define data models
80
- - Phase 3: Compose build pages with components
81
- - Phase 4: Configure generate tests, firestore rules, CI/CD
97
+ - Phase 0: Brainstorm -> produce a spec
98
+ - Phase 1: Scaffold -> create pages
99
+ - Phase 2: Entities -> define data models
100
+ - Phase 3: Compose -> build pages with components
101
+ - Phase 4: Configure -> generate tests, firestore rules, CI/CD
82
102
 
83
103
  Read `guides/wai-way/WAI_WAY_CLI.md` for the full workflow.
84
104
 
@@ -90,7 +110,51 @@ Read `guides/wai-way/WAI_WAY_CLI.md` for the full workflow.
90
110
  dndev deploy
91
111
  ```
92
112
 
93
- Deploys hosting + functions + rules. Cloud Run IAM handled automatically.
113
+ Deploys hosting + functions + rules. Syncs runtime secrets automatically before deploying functions.
114
+
115
+ ---
116
+
117
+ ## Secrets Philosophy
118
+
119
+ **DoNotDev follows strict rules about credentials:**
120
+
121
+ ### Tier 1: Public Keys -- We Ask Directly
122
+
123
+ These are safe to share, shipped in your client JS bundle. We ask for them during setup.
124
+
125
+ | Key | Where It Goes |
126
+ |-----|--------------|
127
+ | Firebase API key, project ID, auth domain, etc. | `apps/<app>/.env` as `VITE_FIREBASE_*` |
128
+ | Supabase project URL | `apps/<app>/.env` as `VITE_SUPABASE_URL` |
129
+ | Supabase anon key (public JWT) | `apps/<app>/.env` as `VITE_SUPABASE_ANON_KEY` |
130
+ | Stripe publishable key | `apps/<app>/.env` as `VITE_STRIPE_PUBLISHABLE_KEY` |
131
+
132
+ ### Tier 2: Secret Keys -- We NEVER Ask, We Tell You Where To Put Them
133
+
134
+ These are server-side only. We never prompt for them, never store them in client code.
135
+
136
+ | Key | Where It Goes | How To Get It |
137
+ |-----|--------------|---------------|
138
+ | Stripe secret key | `functions/.env` as `STRIPE_SECRET_KEY` | https://dashboard.stripe.com/apikeys |
139
+ | Stripe webhook secret | `functions/.env` as `STRIPE_WEBHOOK_SECRET` | Stripe Dashboard -> Webhooks |
140
+ | Supabase service_role key | `functions/.env` as `SUPABASE_SERVICE_ROLE_KEY` | Supabase Dashboard -> Settings -> API |
141
+ | OAuth client secrets | `functions/.env` as `*_CLIENT_SECRET` | Provider dashboard |
142
+
143
+ Then sync to your runtime:
144
+
145
+ ```bash
146
+ dndev sync-secrets # -> Firebase Secret Manager or Vercel env
147
+ dndev sync-secrets --target github # -> GitHub Secrets (for CI/CD)
148
+ ```
149
+
150
+ ### Tier 3: Service Account Files -- Download, Place, Gitignore
151
+
152
+ | File | Where It Goes | How To Get It |
153
+ |------|--------------|---------------|
154
+ | `service-account-key.json` | App root (next to firebase.json) | Firebase Console -> Settings -> Service Accounts |
155
+ | `service-account-key.staging.json` | Same location, for staging | Same, from staging project |
156
+
157
+ These files are `.gitignored`. Never commit them. For CI/CD, upload the file content as a GitHub Secret and decode it in your workflow.
94
158
 
95
159
  ---
96
160
 
@@ -100,18 +164,21 @@ Deploys hosting + functions + rules. Cloud Run IAM handled automatically.
100
164
 
101
165
  ```
102
166
  my-project/
103
- ├── .env.example NOT loaded by Vite (reference only)
104
- ├── apps/
105
- └── my-app/
106
- ├── .env Vite reads THIS
107
- ├── .env.local Overrides .env (gitignored)
108
- ├── .env.staging Used by dndev staging
109
- └── .env.production Production overrides
110
- └── functions/
111
- └── .env Server secrets (Stripe, OAuth)
167
+ +-- .env.example <-- NOT loaded by Vite (reference only)
168
+ +-- apps/
169
+ | +-- my-app/
170
+ | +-- .env <-- Vite reads THIS (public keys: VITE_*)
171
+ | +-- .env.local <-- Overrides .env (gitignored)
172
+ | +-- .env.staging <-- Used by dndev staging
173
+ | +-- .env.production <-- Production overrides
174
+ +-- functions/
175
+ +-- .env <-- Server secrets (Stripe, OAuth, service_role)
112
176
  ```
113
177
 
114
- **Rule:** `VITE_*` vars go in `apps/<app>/.env`. Server secrets go in `functions/.env`.
178
+ **Rules:**
179
+ - `VITE_*` / `NEXT_PUBLIC_*` vars -> `apps/<app>/.env` (public, shipped to browser)
180
+ - Server secrets -> `functions/.env` (never exposed to client)
181
+ - Service account files -> app root, gitignored
115
182
 
116
183
  ---
117
184
 
@@ -122,9 +189,11 @@ my-project/
122
189
  | `bun dev` | Start dev server |
123
190
  | `dndev emu start` | Start Firebase emulators |
124
191
  | `dndev firebase:setup` | Configure Firebase project + .env |
125
- | `dndev deploy` | Deploy to Firebase (hosting + functions + rules) |
192
+ | `dndev supabase:setup` | Configure Supabase project + .env |
193
+ | `dndev deploy` | **Firebase:** hosting + functions + rules. **Supabase:** deploys frontend to [Vercel](https://vercel.com) (via scaffolded vercel.json) and Edge Functions to Supabase. Set `VITE_SUPABASE_*` in Vercel project env. |
126
194
  | `dndev staging` | Deploy to staging environment |
127
- | `dndev sync-secrets` | Push functions/.env to Firebase Secret Manager |
195
+ | `dndev sync-secrets` | Push functions/.env to runtime (Firebase/Vercel) |
196
+ | `dndev sync-secrets --target github` | Push secrets to GitHub Secrets (CI/CD) |
128
197
  | `bun test` | Run tests (after Phase 4) |
129
198
  | `bun run type-check` | TypeScript validation |
130
199
 
@@ -135,8 +204,8 @@ my-project/
135
204
  | Feature | Required? | When to Set Up |
136
205
  |---------|-----------|---------------|
137
206
  | Git + GitHub | Recommended | Before starting development |
138
- | Firebase (Auth + Firestore) | Yes | Before building any features |
139
- | Cloud Functions | If using backend | Before deploying functions |
207
+ | Firebase or Supabase | Yes (pick one) | Before building any features |
208
+ | Cloud Functions | If using server logic | Before deploying functions |
140
209
  | Stripe | If using billing | When adding payment features |
141
210
  | GitHub Actions CI/CD | Optional | Phase 4 generates the workflow |
142
211
  | Staging environment | Optional | When you want a test environment |
@@ -0,0 +1,186 @@
1
+ # Framework Gotchas
2
+
3
+ **Common mistakes. Read before coding. Phase tags show when each matters most.**
4
+
5
+ ---
6
+
7
+ ## Imports [Phase 1, 2, 3]
8
+
9
+ **Server code MUST use `/server` imports — client imports crash on deploy.**
10
+
11
+ ```typescript
12
+ // ✅ CORRECT
13
+ import { getFirebaseAdminFirestore } from '@donotdev/firebase/server';
14
+ import { handleError } from '@donotdev/core/server';
15
+
16
+ // ❌ WRONG - crashes on deploy
17
+ import { getFirestore } from '@donotdev/firebase';
18
+ import { handleError } from '@donotdev/core';
19
+ ```
20
+
21
+ **Rule:** Always use `/server` suffix for `@donotdev/firebase/server`, `@donotdev/core/server`, `@donotdev/utils/server`.
22
+
23
+ **ESM only — never use `require()`.**
24
+
25
+ ```typescript
26
+ // ❌ WRONG
27
+ const { something } = require('@donotdev/package');
28
+
29
+ // ✅ CORRECT
30
+ import { something } from '@donotdev/package';
31
+ ```
32
+
33
+ **Import ordering is mandatory:**
34
+ 1. React (values, then types)
35
+ 2. Other vendors (values, then types)
36
+ 3. `@donotdev/*` packages (values, then types)
37
+ 4. Relative imports (values, then types)
38
+
39
+ One line for values, one line for types. Blank line between categories.
40
+
41
+ ---
42
+
43
+ ## Routing [Phase 1, 3]
44
+
45
+ **Never import from `react-router-dom` — use framework routing.**
46
+
47
+ ```tsx
48
+ // ❌ WRONG - breaks framework features
49
+ import { Link, useNavigate, useParams } from 'react-router-dom';
50
+
51
+ // ✅ CORRECT
52
+ import { Link, useNavigate, useParams } from '@donotdev/ui/routing';
53
+ ```
54
+
55
+ **Routes are auto-discovered** from `src/pages/*Page.tsx` with `pageMeta`. Don't use `<Routes>`, `<Route>`, or manual `<Outlet />`.
56
+
57
+ **Use `useRouteParam('id')` for typed route params** — not `useParams()` from react-router-dom.
58
+
59
+ **Navigation is auto-built.** Use `<DnDevNavigationMenu>` or `useNavigationItems()`. Don't build nav manually — you lose auth filtering and route discovery.
60
+
61
+ ---
62
+
63
+ ## Styling [Phase 3, 4]
64
+
65
+ **No inline `fontSize` or `font-size` — use `Text` level prop.**
66
+
67
+ ```tsx
68
+ // ❌ WRONG
69
+ <Text style={{ fontSize: '18px' }}>Title</Text>
70
+
71
+ // ✅ CORRECT
72
+ <Text level="h2">Title</Text>
73
+ ```
74
+
75
+ Levels: `h1`, `h2`, `h3`, `h4`, `body`, `small`, `caption`. Limit to 2–3 levels per page.
76
+
77
+ **RTL: Always use `start`/`end` — never `left`/`right`.**
78
+
79
+ ```css
80
+ /* ❌ WRONG - breaks RTL */
81
+ text-align: left;
82
+
83
+ /* ✅ CORRECT - works in both LTR and RTL */
84
+ text-align: start;
85
+ ```
86
+
87
+ Same for inline styles: `textAlign: 'start'` not `textAlign: 'left'`. Same for data attributes: `data-text-align="start|center|end"`.
88
+
89
+ ---
90
+
91
+ ## Components [Phase 3]
92
+
93
+ **Always `lookup_symbol` before using any `@donotdev` component.** Never guess props.
94
+
95
+ Common wrong props:
96
+ - `Button`: no `size`, `tone`, `gap` — use `variant`, `display`
97
+ - `Text`: no `size`, `tone`, `color` — use `level`, `variant`
98
+ - `Stack`: no `spacing`, `size` — use `gap`
99
+ - `Card`: no `padding`, `margin`, `size` — use `title`, `subtitle`, `content`, `footer`
100
+ - `Grid`: no `columns` — use `cols`
101
+
102
+ **If you can't do it with framework components:** Stop. Tell the user what's missing. Don't invent custom workarounds.
103
+
104
+ ---
105
+
106
+ ## CRUD [Phase 2, 3]
107
+
108
+ **Hidden fields are auto-added by `defineEntity()` — don't define them manually:**
109
+ - `id`, `createdAt`, `updatedAt`, `createdById`, `updatedById`, `status`
110
+
111
+ **Scope field is auto-added** when `scope` is configured. Don't manually define the scope field (e.g., `companyId`).
112
+
113
+ **Custom form fields MUST use framework's `useController`:**
114
+
115
+ ```typescript
116
+ // ❌ WRONG
117
+ import { useController } from 'react-hook-form';
118
+
119
+ // ✅ CORRECT
120
+ import { useController } from '@donotdev/crud';
121
+ ```
122
+
123
+ **Form components receive `control` prop, not `field` prop.**
124
+
125
+ **Price field is structured:** `{ amount, currency, vatIncluded, discountPercent }`. Don't store computed discount amounts.
126
+
127
+ **File uploads are deferred** — files upload on form submit, not on selection. Images show optimistic blob URLs.
128
+
129
+ **Entity namespace defaults to `entity-{name}`** (lowercase). Translation files must match: `locales/entity-product_en.json`.
130
+
131
+ ---
132
+
133
+ ## Functions [Phase 3, 4]
134
+
135
+ **Use `createFunction` for custom functions — 3 params, everything included:**
136
+
137
+ ```typescript
138
+ import { createFunction } from '@donotdev/functions/firebase';
139
+
140
+ export const myFunction = createFunction(schema, 'operation_name', async (data, { uid }) => {
141
+ // Your logic
142
+ });
143
+ ```
144
+
145
+ **Use `createBaseFunction` only when you need custom config** (memory, timeout, region override).
146
+
147
+ **Deploy with `dndev deploy`** — not `firebase deploy`. Manual deploy causes CORS 403 on preflight because Cloud Run blocks unauthenticated OPTIONS by default.
148
+
149
+ **Naming:** Export in camelCase (`getDashboardMetrics`), operation ID in snake_case (`get_dashboard_metrics`).
150
+
151
+ **CRUD functions are one-liner:** `export const crud = createCrudFunctions(entities);` — generates all CRUD endpoints per entity. Access controlled via `entity.access`.
152
+
153
+ ---
154
+
155
+ ## i18n [Phase 3, 4]
156
+
157
+ **Phase 3: hardcode strings. Phase 4: add translations.** Don't i18n too early.
158
+
159
+ **Two loading strategies:**
160
+ - **Eager** (always loaded): `src/locales/common_en.json` — navigation, buttons, common UI
161
+ - **Lazy** (loaded per page): `src/pages/locales/home_en.json` — page-specific content
162
+
163
+ **Status field translations** fall back: `entity-{name}` namespace → `crud` namespace.
164
+
165
+ **Rich text uses `<Trans>` component** with supported tags only: `<accent>`, `<primary>`, `<muted>`, `<success>`, `<warning>`, `<error>`, `<bold>`, `<code>`.
166
+
167
+ **Array translations use `tList`:**
168
+ ```tsx
169
+ import { tList } from '@donotdev/ui';
170
+ <Card content={tList(t, 'features.items', 4)} />
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Dependencies [Phase 1]
176
+
177
+ **Apps don't declare bundled deps.** Framework packages (`@donotdev/*`) provide everything. Don't add `react-router-dom`, `react-hook-form`, `valibot`, etc. to app's `package.json` — they come through framework deps.
178
+
179
+ **Environment variables:**
180
+ - Client: `apps/my-app/.env` (prefix with `VITE_*`)
181
+ - Server: `functions/.env` (secrets: `STRIPE_*`, OAuth tokens)
182
+ - Local overrides: `.env.local` (gitignored)
183
+
184
+ ---
185
+
186
+ **When in doubt: search the codebase first, ask the user second, never guess.**
@@ -8,8 +8,11 @@
8
8
 
9
9
  ## Getting Started
10
10
 
11
- - [ENV_SETUP.md](./ENV_SETUP.md) - **START HERE** Full onboarding flow (installfirebasedeploy)
11
+ - **Human flow:** P0 (Bun/Node + AI IDE) Install CLI & `dndev init` Run **AI.md** Enjoy. See [AGENT_START_HERE.md](./AGENT_START_HERE.md) § Getting started (for humans).
12
+ - [ENV_SETUP.md](./ENV_SETUP.md) — After `dndev init`: env, Firebase/Supabase, deploy
13
+ - [GOTCHAS.md](./GOTCHAS.md) - **Common mistakes & pitfalls** (phase-tagged, read before coding)
12
14
  - [SETUP_FIREBASE.md](./SETUP_FIREBASE.md) - Firebase project setup (`dndev firebase:setup`)
15
+ - [SETUP_SUPABASE.md](./SETUP_SUPABASE.md) - Supabase project setup (`dndev supabase:setup`, `dn generate sql`)
13
16
  - [SETUP_TESTING.md](./SETUP_TESTING.md) - Test generation (Phase 4)
14
17
 
15
18
  ---