@donotdev/cli 0.0.18 → 0.0.20

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 (150) hide show
  1. package/dependencies-matrix.json +42 -55
  2. package/dist/bin/commands/bump.js +5 -2
  3. package/dist/bin/commands/coach.js +8177 -0
  4. package/dist/bin/commands/create-app.js +6 -6
  5. package/dist/bin/commands/create-project.js +23 -9
  6. package/dist/bin/commands/deploy.js +99 -59
  7. package/dist/bin/commands/doctor.js +243 -698
  8. package/dist/bin/commands/emu.js +2 -2
  9. package/dist/bin/commands/format.js +4 -1
  10. package/dist/bin/commands/get-demo.js +8351 -0
  11. package/dist/bin/commands/make-admin.js +773 -152
  12. package/dist/bin/commands/setup.js +524 -1713
  13. package/dist/bin/commands/staging.js +17870 -0
  14. package/dist/bin/commands/sync-secrets.js +2 -11
  15. package/dist/bin/commands/type-check.js +7738 -1712
  16. package/dist/bin/dndev.js +868 -199
  17. package/dist/bin/donotdev.js +868 -199
  18. package/dist/index.js +127 -67
  19. package/package.json +1 -1
  20. package/templates/app-demo/index.html.example +147 -10
  21. package/templates/app-demo/public/apple-touch-icon.png.example +0 -0
  22. package/templates/app-demo/public/favicon.svg.example +1 -0
  23. package/templates/app-demo/public/icon-192x192.png.example +0 -0
  24. package/templates/app-demo/public/icon-512x512.png.example +0 -0
  25. package/templates/app-demo/src/App.tsx.example +7 -11
  26. package/templates/app-demo/src/config/app.ts.example +13 -48
  27. package/templates/app-demo/src/entities/booking.ts.example +75 -0
  28. package/templates/app-demo/src/entities/onboarding.ts.example +160 -0
  29. package/templates/app-demo/src/entities/product.ts.example +50 -0
  30. package/templates/app-demo/src/entities/quote.ts.example +70 -0
  31. package/templates/app-demo/src/globals.css.example +5 -1
  32. package/templates/app-demo/src/main.tsx.example +13 -7
  33. package/templates/app-demo/src/pages/ChangelogPage.tsx.example +41 -0
  34. package/templates/app-demo/src/pages/ConditionalFormPage.tsx.example +88 -0
  35. package/templates/app-demo/src/pages/DashboardPage.tsx.example +17 -0
  36. package/templates/app-demo/src/pages/HomePage.tsx.example +339 -60
  37. package/templates/app-demo/src/pages/OnboardingPage.tsx.example +47 -0
  38. package/templates/app-demo/src/pages/PricingPage.tsx.example +41 -0
  39. package/templates/app-demo/src/pages/ProductsPage.tsx.example +19 -0
  40. package/templates/app-demo/src/pages/ProfilePage.tsx.example +18 -0
  41. package/templates/app-demo/src/pages/SettingsPage.tsx.example +17 -0
  42. package/templates/app-demo/src/pages/ShowcaseDetailPage.tsx.example +118 -0
  43. package/templates/app-demo/src/pages/ShowcasePage.tsx.example +93 -0
  44. package/templates/app-demo/src/pages/components/ComponentRenderer.tsx.example +147 -51
  45. package/templates/app-demo/src/pages/components/ComponentsData.tsx.example +103 -21
  46. package/templates/app-demo/src/pages/components/componentConfig.ts.example +139 -59
  47. package/templates/app-demo/src/pages/legal/LegalPage.tsx.example +25 -0
  48. package/templates/app-demo/src/pages/legal/PrivacyPage.tsx.example +23 -0
  49. package/templates/app-demo/src/pages/legal/TermsPage.tsx.example +23 -0
  50. package/templates/app-demo/src/themes.css.example +289 -77
  51. package/templates/app-demo/stats.html.example +4949 -0
  52. package/templates/app-demo/tsconfig.json.example +1 -1
  53. package/templates/app-demo/vite.config.ts.example +23 -48
  54. package/templates/app-expo/README.md.example +1 -1
  55. package/templates/app-expo/app/index.tsx.example +1 -1
  56. package/templates/app-next/src/locales/home_en.json.example +6 -6
  57. package/templates/app-vite/src/locales/home_en.json.example +6 -6
  58. package/templates/app-vite/src/pages/HomePage.tsx.example +8 -10
  59. package/templates/overlay-firebase/env.fragment.example +1 -1
  60. package/templates/overlay-firebase/env.fragment.expo.example +1 -1
  61. package/templates/overlay-firebase/env.fragment.nextjs.example +1 -1
  62. package/templates/overlay-supabase/env.fragment.example +1 -1
  63. package/templates/overlay-supabase/env.fragment.expo.example +1 -1
  64. package/templates/overlay-supabase/env.fragment.nextjs.example +1 -1
  65. package/templates/overlay-vercel/env.fragment.example +1 -1
  66. package/templates/overlay-vercel/env.fragment.nextjs.example +1 -1
  67. package/templates/root-consumer/AI.md.example +4 -3
  68. package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +21 -6
  69. package/templates/root-consumer/guides/dndev/COMPONENTS_ADV.md.example +16 -179
  70. package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +19 -21
  71. package/templates/root-consumer/guides/dndev/GOTCHAS.md.example +14 -3
  72. package/templates/root-consumer/guides/dndev/INDEX.md.example +2 -2
  73. package/templates/root-consumer/guides/dndev/SETUP_APP_CONFIG.md.example +3 -3
  74. package/templates/root-consumer/guides/dndev/SETUP_BLOG.md.example +19 -2
  75. package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +35 -1
  76. package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +17 -12
  77. package/templates/root-consumer/guides/dndev/SETUP_LAYOUTS.md.example +32 -0
  78. package/templates/root-consumer/guides/dndev/SETUP_OAUTH_PROVIDERS.md.example +1 -1
  79. package/templates/root-consumer/guides/dndev/SETUP_PAGES.md.example +19 -15
  80. package/templates/root-consumer/guides/dndev/SETUP_STRIPE.md.example +2 -2
  81. package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +17 -12
  82. package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +37 -16
  83. package/templates/root-consumer/guides/dndev/USE_ROUTING.md.example +18 -18
  84. package/templates/root-consumer/guides/dndev/advanced/COOKIE_REFERENCE.md.example +252 -252
  85. package/templates/root-consumer/guides/dndev/advanced/VERSION_CONTROL.md.example +174 -174
  86. package/templates/root-consumer/guides/dndev/essences_reference.css.example +119 -2
  87. package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +14 -0
  88. package/templates/root-consumer/guides/wai-way/blueprints/2_entities.md.example +6 -0
  89. package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +14 -0
  90. package/templates/root-consumer/guides/wai-way/entity_patterns.md.example +4 -5
  91. package/templates/root-consumer/guides/wai-way/page_patterns.md.example +2 -2
  92. package/dist/bin/commands/agent-setup.d.ts +0 -6
  93. package/dist/bin/commands/agent-setup.d.ts.map +0 -1
  94. package/dist/bin/commands/agent-setup.js.map +0 -1
  95. package/dist/bin/commands/build.d.ts +0 -11
  96. package/dist/bin/commands/build.d.ts.map +0 -1
  97. package/dist/bin/commands/build.js.map +0 -1
  98. package/dist/bin/commands/bump.d.ts +0 -11
  99. package/dist/bin/commands/bump.d.ts.map +0 -1
  100. package/dist/bin/commands/bump.js.map +0 -1
  101. package/dist/bin/commands/cacheout.d.ts +0 -11
  102. package/dist/bin/commands/cacheout.d.ts.map +0 -1
  103. package/dist/bin/commands/cacheout.js.map +0 -1
  104. package/dist/bin/commands/create-app.d.ts +0 -11
  105. package/dist/bin/commands/create-app.d.ts.map +0 -1
  106. package/dist/bin/commands/create-app.js.map +0 -1
  107. package/dist/bin/commands/create-project.d.ts +0 -11
  108. package/dist/bin/commands/create-project.d.ts.map +0 -1
  109. package/dist/bin/commands/create-project.js.map +0 -1
  110. package/dist/bin/commands/deploy.d.ts +0 -11
  111. package/dist/bin/commands/deploy.d.ts.map +0 -1
  112. package/dist/bin/commands/deploy.js.map +0 -1
  113. package/dist/bin/commands/dev.d.ts +0 -11
  114. package/dist/bin/commands/dev.d.ts.map +0 -1
  115. package/dist/bin/commands/dev.js.map +0 -1
  116. package/dist/bin/commands/doctor.d.ts +0 -6
  117. package/dist/bin/commands/doctor.d.ts.map +0 -1
  118. package/dist/bin/commands/doctor.js.map +0 -1
  119. package/dist/bin/commands/emu.d.ts +0 -11
  120. package/dist/bin/commands/emu.d.ts.map +0 -1
  121. package/dist/bin/commands/emu.js.map +0 -1
  122. package/dist/bin/commands/format.d.ts +0 -11
  123. package/dist/bin/commands/format.d.ts.map +0 -1
  124. package/dist/bin/commands/format.js.map +0 -1
  125. package/dist/bin/commands/make-admin.d.ts +0 -11
  126. package/dist/bin/commands/make-admin.d.ts.map +0 -1
  127. package/dist/bin/commands/make-admin.js.map +0 -1
  128. package/dist/bin/commands/preview.d.ts +0 -11
  129. package/dist/bin/commands/preview.d.ts.map +0 -1
  130. package/dist/bin/commands/preview.js.map +0 -1
  131. package/dist/bin/commands/setup.d.ts +0 -6
  132. package/dist/bin/commands/setup.d.ts.map +0 -1
  133. package/dist/bin/commands/setup.js.map +0 -1
  134. package/dist/bin/commands/sync-secrets.d.ts +0 -11
  135. package/dist/bin/commands/sync-secrets.d.ts.map +0 -1
  136. package/dist/bin/commands/sync-secrets.js.map +0 -1
  137. package/dist/bin/commands/type-check.d.ts +0 -14
  138. package/dist/bin/commands/type-check.d.ts.map +0 -1
  139. package/dist/bin/commands/type-check.js.map +0 -1
  140. package/dist/bin/commands/wai.d.ts +0 -11
  141. package/dist/bin/commands/wai.d.ts.map +0 -1
  142. package/dist/bin/commands/wai.js.map +0 -1
  143. package/dist/index.d.ts +0 -8
  144. package/dist/index.d.ts.map +0 -1
  145. package/dist/index.js.map +0 -1
  146. package/templates/app-demo/src/components/ThemeToggle.tsx.example +0 -48
  147. package/templates/app-demo/src/pages/DetailPage.tsx.example +0 -103
  148. package/templates/app-demo/src/pages/FullPage.tsx.example +0 -142
  149. package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +0 -266
  150. package/templates/app-demo/src/pages/components/LayoutRoute.tsx.example +0 -20
@@ -1,8 +1,13 @@
1
1
  #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
2
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
3
4
  var __esm = (fn, res) => function __init() {
4
5
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
6
  };
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
6
11
 
7
12
  // packages/tooling/src/bundler/utils.ts
8
13
  import { Buffer as Buffer2 } from "node:buffer";
@@ -30,241 +35,905 @@ var init_utils = __esm({
30
35
  }
31
36
  });
32
37
 
33
- // packages/cli/src/bin/dndev.mjs
34
- init_utils();
35
- import { readFileSync } from "node:fs";
36
- import { Command } from "commander";
37
- var CLI_VERSION = JSON.parse(
38
- readFileSync(new URL("../../package.json", import.meta.url), "utf-8")
39
- ).version;
40
- var args = process.argv.slice(2);
41
- if (args.length === 1 && (args[0] === "--version" || args[0] === "-v")) {
42
- console.log(CLI_VERSION);
43
- process.exit(0);
38
+ // packages/tooling/src/cli/command-registry.ts
39
+ var command_registry_exports = {};
40
+ __export(command_registry_exports, {
41
+ COMMAND_REGISTRY: () => COMMAND_REGISTRY,
42
+ generateHelpText: () => generateHelpText,
43
+ getAppCommandNames: () => getAppCommandNames,
44
+ getBundleCommandNames: () => getBundleCommandNames,
45
+ getPublicCommands: () => getPublicCommands
46
+ });
47
+ function baseName(commanderName) {
48
+ return commanderName.split(" ")[0] ?? commanderName;
44
49
  }
45
- if (args.length === 0 || args.length === 1 && (args[0] === "--help" || args[0] === "-h")) {
46
- console.log(`DoNotDev CLI v${CLI_VERSION}
50
+ function getPublicCommands() {
51
+ return COMMAND_REGISTRY.filter((cmd) => cmd.public === true);
52
+ }
53
+ function getAppCommandNames() {
54
+ const names = [];
55
+ for (const cmd of COMMAND_REGISTRY) {
56
+ if (!cmd.appCommand) continue;
57
+ names.push(baseName(cmd.name));
58
+ if (cmd.alias) {
59
+ const aliases = Array.isArray(cmd.alias) ? cmd.alias : [cmd.alias];
60
+ names.push(...aliases);
61
+ }
62
+ }
63
+ return names;
64
+ }
65
+ function getBundleCommandNames() {
66
+ return COMMAND_REGISTRY.filter((cmd) => cmd.public === true).map(
67
+ (cmd) => cmd.wrapperFile ?? baseName(cmd.name)
68
+ );
69
+ }
70
+ function generateHelpText(cli) {
71
+ const commands = cli === "dndev" ? COMMAND_REGISTRY.filter((cmd) => cmd.public === true) : COMMAND_REGISTRY;
72
+ const cliName = cli === "dn" ? "dn" : "dndev";
73
+ const title = cli === "dn" ? "DoNotDev Framework CLI - Internal Tooling" : "DoNotDev CLI";
74
+ const grouped = /* @__PURE__ */ new Map();
75
+ for (const cmd of commands) {
76
+ const list = grouped.get(cmd.category) ?? [];
77
+ list.push(cmd);
78
+ grouped.set(cmd.category, list);
79
+ }
80
+ const CATEGORY_LABELS = {
81
+ project: "Project Commands",
82
+ development: "Development Commands",
83
+ build: "Build & Maintenance",
84
+ deployment: "Deployment",
85
+ content: "Content",
86
+ internal: "Internal",
87
+ other: "Other"
88
+ };
89
+ const sections = [];
90
+ for (const [cat, cmds] of grouped) {
91
+ const label = CATEGORY_LABELS[cat] ?? cat;
92
+ const lines = cmds.map((cmd) => {
93
+ const nameStr = cmd.name;
94
+ const aliasStr = cmd.alias ? `, ${Array.isArray(cmd.alias) ? cmd.alias.join(", ") : cmd.alias}` : "";
95
+ const left = ` ${nameStr}${aliasStr}`;
96
+ const pad = Math.max(2, 28 - left.length);
97
+ return `${left}${" ".repeat(pad)}${cmd.description}`;
98
+ });
99
+ sections.push(`${label}:
100
+ ${lines.join("\n")}`);
101
+ }
102
+ const header = cli === "dn" ? `${title}
47
103
 
48
- Usage: dndev <command>[:<app>] [options]
104
+ Usage: ${cliName} <command>[:<app>] [options]` : `${title}
49
105
 
50
- Commands:
51
- init, create-project Create a new DoNotDev project
52
- create-app [name] Add app (--builder, --host, --functions, --backend)
53
- dev [app] Start development server
54
- build [app] Build for production
55
- preview [app] Preview production build
56
- emu [app] Start dev with local backend
57
- format Format code with Prettier
58
- tc [app] Type-check TypeScript (all packages or specific app)
59
- deploy [app] Deploy to Firebase
60
- staging [subcommand] Deploy to staging/UAT (deploy, deploy:hosting, deploy:functions, seed, status)
61
- sync-secrets Sync env vars to Firebase/Vercel/GitHub Secrets
62
- make-admin [userId] Set a user as admin (custom claims / app_metadata)
63
- setup [provider] Set up provider credentials (firebase, supabase, vercel, stripe, oauth, auth)
64
- doctor Check project health: validate provider connections and .env files
65
- cacheout [app] Clear build caches
66
- bump Update framework packages and peer dependencies
67
- agent Configure MCP server for AI agents (Cursor, Claude, Gemini)
68
- wai Output WAI-WAY activation prompt (paste into any AI agent)
106
+ Usage: ${cliName} <command>[:<app>] [options]`;
107
+ const footer = cli === "dn" ? `Options:
108
+ -v, --version Display version number
109
+ -h, --help Display this help
110
+
111
+ Examples:
112
+ ${cliName} dev Start dev server
113
+ ${cliName} dev:demo Start dev server for 'demo' app
114
+ ${cliName} create-app Interactive app creation
115
+ ${cliName} create-app my-app Create 'my-app' with defaults (vite, frontend-only)
116
+ ${cliName} create-app my-app --builder next --host vercel Next.js + Vercel hosting
117
+ ${cliName} create-app my-app --functions firebase --backend firebase Full Firebase stack
118
+ ${cliName} bundle Build all packages
119
+ ${cliName} lint --fix Lint and auto-fix issues
120
+ ${cliName} wai Output WAI-WAY activation prompt
69
121
 
70
- Options:
122
+ Run '${cliName} <command> --help' for command-specific help.` : `Options:
71
123
  -v, --version Display version number
72
124
  -h, --help Display this help
73
125
 
74
126
  Examples:
75
- dndev init my-project Create a new project
76
- dndev create-app Interactive app creation
77
- dndev create-app my-app Create 'my-app' with defaults (vite, frontend-only)
78
- dndev create-app my-app --builder next --host vercel Next.js + Vercel hosting
79
- dndev create-app my-app --functions firebase --backend firebase Full Firebase stack
80
- dndev create-app my-app --backend supabase --project my-fb-id Supabase + custom project
81
- dndev dev Start dev server
82
- dndev dev:web Start dev server for 'web' app
83
- dndev agent Configure MCP for all AI agents
84
- dndev wai Output WAI-WAY activation prompt
127
+ ${cliName} init my-project Create a new project
128
+ ${cliName} create-app Interactive app creation
129
+ ${cliName} create-app my-app Create 'my-app' with defaults (vite, frontend-only)
130
+ ${cliName} create-app my-app --builder next --host vercel Next.js + Vercel hosting
131
+ ${cliName} create-app my-app --functions firebase --backend firebase Full Firebase stack
132
+ ${cliName} create-app my-app --backend supabase --project my-fb-id Supabase + custom project
133
+ ${cliName} dev Start dev server
134
+ ${cliName} dev:web Start dev server for 'web' app
135
+ ${cliName} agent Configure MCP for all AI agents
136
+ ${cliName} wai Output WAI-WAY activation prompt
85
137
 
86
- Run 'dndev <command> --help' for command-specific help.`);
87
- process.exit(0);
138
+ Run '${cliName} <command> --help' for command-specific help.`;
139
+ return `${header}
140
+
141
+ ${sections.join("\n\n")}
142
+
143
+ ${footer}
144
+ `;
145
+ }
146
+ var COMMAND_REGISTRY;
147
+ var init_command_registry = __esm({
148
+ "packages/tooling/src/cli/command-registry.ts"() {
149
+ init_utils();
150
+ COMMAND_REGISTRY = [
151
+ // ---------------------------------------------------------------------------
152
+ // Project
153
+ // ---------------------------------------------------------------------------
154
+ {
155
+ name: "init [name]",
156
+ description: "Create a new DoNotDev project",
157
+ alias: "create-project",
158
+ category: "project",
159
+ public: true,
160
+ loader: "../scaffolding/create-project.ts",
161
+ wrapperFile: "create-project",
162
+ exportName: "createProject"
163
+ },
164
+ {
165
+ name: "create-app [name]",
166
+ description: "Add a new app to existing project",
167
+ category: "project",
168
+ public: true,
169
+ options: [
170
+ { flags: "--name <name>", description: "App name (non-interactive)" },
171
+ {
172
+ flags: "--builder <builder>",
173
+ description: "Framework: vite, next, or expo (default: vite)"
174
+ },
175
+ {
176
+ flags: "--host <host>",
177
+ description: "Hosting: none, vercel, or firebase (default: none)"
178
+ },
179
+ {
180
+ flags: "--functions <runtime>",
181
+ description: "Functions: none, vercel, firebase, or supabase (default: none)"
182
+ },
183
+ {
184
+ flags: "--backend <backend>",
185
+ description: "BaaS: none, firebase, or supabase (default: none)"
186
+ }
187
+ ],
188
+ loader: "../scaffolding/create-app.ts",
189
+ wrapperFile: "create-app",
190
+ exportName: "createApp"
191
+ },
192
+ {
193
+ name: "get-demo",
194
+ description: "Copy the demo app into apps/demo",
195
+ category: "project",
196
+ public: true,
197
+ options: [
198
+ {
199
+ flags: "--force",
200
+ description: "Replace existing demo app without prompting"
201
+ }
202
+ ],
203
+ loader: "../scaffolding/get-demo.ts",
204
+ wrapperFile: "get-demo",
205
+ exportName: "getDemo"
206
+ },
207
+ // ---------------------------------------------------------------------------
208
+ // Development
209
+ // ---------------------------------------------------------------------------
210
+ {
211
+ name: "dev [app]",
212
+ description: "Start development server",
213
+ category: "development",
214
+ public: true,
215
+ appCommand: true,
216
+ actionPattern: "app",
217
+ options: [
218
+ { flags: "-c, --concurrency <n>", description: "set concurrency" }
219
+ ],
220
+ loader: "../apps/dev.ts",
221
+ exportName: "dev"
222
+ },
223
+ {
224
+ name: "build [app]",
225
+ description: "Build for production",
226
+ category: "development",
227
+ public: true,
228
+ appCommand: true,
229
+ actionPattern: "app",
230
+ loader: "../apps/build.ts",
231
+ exportName: "build"
232
+ },
233
+ {
234
+ name: "preview [app]",
235
+ description: "Preview production build",
236
+ category: "development",
237
+ public: true,
238
+ appCommand: true,
239
+ actionPattern: "app",
240
+ loader: "../apps/preview.ts",
241
+ exportName: "preview"
242
+ },
243
+ {
244
+ name: "emu [app]",
245
+ description: "Start dev with local backend",
246
+ category: "development",
247
+ public: true,
248
+ appCommand: true,
249
+ actionPattern: "app",
250
+ options: [
251
+ {
252
+ flags: "--services <services>",
253
+ description: "Comma-separated list of services: auth,functions,firestore,stripe"
254
+ },
255
+ { flags: "--auth", description: "Enable Auth emulator" },
256
+ { flags: "--firestore", description: "Enable Firestore emulator" },
257
+ { flags: "--stripe", description: "Enable Stripe webhook forwarding" }
258
+ ],
259
+ loader: "../apps/emu.ts",
260
+ exportName: "emu"
261
+ },
262
+ {
263
+ name: "format",
264
+ description: "Format code with framework standards",
265
+ category: "development",
266
+ public: true,
267
+ loader: "../quality/format.ts",
268
+ exportName: "format"
269
+ },
270
+ {
271
+ name: "lint",
272
+ description: "Lint code using ESLint",
273
+ category: "development",
274
+ options: [
275
+ { flags: "-f, --fix", description: "automatically fix linting issues" }
276
+ ],
277
+ loader: "../quality/lint.ts",
278
+ exportName: "lint"
279
+ },
280
+ {
281
+ name: "type-check [package]",
282
+ description: "Type-check packages",
283
+ alias: "tc",
284
+ category: "development",
285
+ public: true,
286
+ appCommand: true,
287
+ options: [
288
+ {
289
+ flags: "--package <package>",
290
+ description: "type-check a specific package"
291
+ }
292
+ ],
293
+ loader: "../quality/type-check.ts",
294
+ wrapperFile: "type-check",
295
+ exportName: "typeCheck"
296
+ },
297
+ {
298
+ name: "check-ui",
299
+ description: "Check UI compliance with STYLING_SYSTEM.md rules",
300
+ category: "development",
301
+ options: [
302
+ { flags: "-d, --dir <dir>", description: "target directory to check" },
303
+ { flags: "-r, --report <file>", description: "save report to JSON file" }
304
+ ],
305
+ loader: "../quality/check-ui.ts",
306
+ exportName: "checkUI"
307
+ },
308
+ {
309
+ name: "check-expo",
310
+ description: "Check Expo API parity with web packages (exports, props, hooks)",
311
+ category: "development",
312
+ loader: "../quality/check-expo-api.ts",
313
+ exportName: "checkExpo"
314
+ },
315
+ {
316
+ name: "check-translations [target]",
317
+ description: "Validate translation files across languages (missing keys, type mismatches)",
318
+ category: "development",
319
+ options: [
320
+ {
321
+ flags: "-r, --report <file>",
322
+ description: "Write full report to file"
323
+ },
324
+ { flags: "--all", description: "Check all apps and i18n package" }
325
+ ],
326
+ loader: "../quality/check-translations.ts",
327
+ exportName: "checkTranslations"
328
+ },
329
+ {
330
+ name: "sync-translations [app]",
331
+ description: "Sync locale structure from English reference, fix missing keys and array lengths",
332
+ category: "development",
333
+ loader: "../quality/sync-translations.ts"
334
+ },
335
+ {
336
+ name: "validate-package [package]",
337
+ description: "Validate package(s) before bundle/publish (checklist: types, CSS, exports, etc.)",
338
+ category: "development",
339
+ options: [{ flags: "--all", description: "validate all packages" }],
340
+ loader: "../quality/validate-package.ts",
341
+ exportName: "validatePackage"
342
+ },
343
+ // ---------------------------------------------------------------------------
344
+ // Build & Maintenance
345
+ // ---------------------------------------------------------------------------
346
+ {
347
+ name: "bundle [package]",
348
+ description: "Build all packages, create changeset, and publish",
349
+ category: "build",
350
+ options: [
351
+ { flags: "--package <package>", description: "build a specific package" },
352
+ { flags: "--all", description: "build all packages" },
353
+ { flags: "--skip-build", description: "skip build step" },
354
+ { flags: "--skip-minify", description: "skip minification" },
355
+ {
356
+ flags: "--changeset",
357
+ description: "create changeset before publish (default: skip)"
358
+ },
359
+ { flags: "--skip-publish", description: "skip publishing" },
360
+ {
361
+ flags: "--skip-validation",
362
+ description: "skip package validation before build"
363
+ },
364
+ {
365
+ flags: "--verdaccio",
366
+ description: "publish to local Verdaccio registry instead of npm"
367
+ },
368
+ {
369
+ flags: "--tar",
370
+ description: "Create tarballs + update test repo (no publish)"
371
+ },
372
+ { flags: "--force", description: "force publish (npm publish --force)" }
373
+ ],
374
+ loader: "../bundler/bundle.ts",
375
+ exportName: "bundle"
376
+ },
377
+ {
378
+ name: "clean",
379
+ description: "Clean build artifacts, caches, and node_modules",
380
+ category: "build",
381
+ loader: "../maintenance/clean.ts",
382
+ exportName: "clean"
383
+ },
384
+ {
385
+ name: "cacheout [app]",
386
+ description: "Clear build caches without touching node_modules",
387
+ alias: "co",
388
+ category: "build",
389
+ public: true,
390
+ appCommand: true,
391
+ options: [
392
+ { flags: "--app <app>", description: "App name to clear cache for" }
393
+ ],
394
+ loader: "../maintenance/cacheout.ts",
395
+ exportName: "cacheout"
396
+ },
397
+ {
398
+ name: "sync-deps",
399
+ description: "Sync dependencies with dependencies-matrix.json (packages, apps, functions, root)",
400
+ alias: "sync-dependencies",
401
+ category: "build",
402
+ options: [
403
+ {
404
+ flags: "-c, --check-only",
405
+ description: "only check for issues, do not fix"
406
+ },
407
+ {
408
+ flags: "-f, --fix",
409
+ description: "automatically fix dependency issues"
410
+ }
411
+ ],
412
+ loader: "../bundler/sync-dependencies.ts",
413
+ exportName: "syncDependencies"
414
+ },
415
+ {
416
+ name: "bump",
417
+ description: "Update framework packages and peer dependencies to latest compatible versions",
418
+ category: "build",
419
+ public: true,
420
+ loader: "../maintenance/bump.ts",
421
+ exportName: "bump"
422
+ },
423
+ {
424
+ name: "versions",
425
+ description: "Check latest npm versions of all @donotdev/* packages",
426
+ alias: "v",
427
+ category: "build",
428
+ loader: "../maintenance/versions.ts"
429
+ },
430
+ // ---------------------------------------------------------------------------
431
+ // Deployment
432
+ // ---------------------------------------------------------------------------
433
+ {
434
+ name: "deploy [app]",
435
+ description: "Deploy app",
436
+ category: "deployment",
437
+ public: true,
438
+ appCommand: true,
439
+ options: [
440
+ { flags: "-p, --project <project>", description: "Firebase project ID" },
441
+ { flags: "--skip-build", description: "skip build step" },
442
+ { flags: "--force", description: "Force deployment / cleanup policy" },
443
+ {
444
+ flags: "--staging",
445
+ description: "Deploy to staging (uses .env.staging, service-account-key.staging.json, .firebaserc staging project)"
446
+ }
447
+ ],
448
+ loader: "../apps/deploy.ts",
449
+ exportName: "deploy"
450
+ },
451
+ {
452
+ name: "staging [app]",
453
+ description: "Deploy to staging/UAT (shorthand for deploy --staging)",
454
+ alias: "uat",
455
+ category: "deployment",
456
+ public: true,
457
+ appCommand: true,
458
+ options: [
459
+ {
460
+ flags: "-p, --project <project>",
461
+ description: "Firebase project ID (overrides .firebaserc)"
462
+ },
463
+ { flags: "--skip-build", description: "skip build step" },
464
+ { flags: "--force", description: "Force deployment / cleanup policy" }
465
+ ],
466
+ loader: "../apps/deploy.ts"
467
+ },
468
+ {
469
+ name: "sync-secrets",
470
+ description: "Sync environment variables to Firebase/Vercel or GitHub Secrets",
471
+ category: "deployment",
472
+ public: true,
473
+ options: [
474
+ { flags: "-e, --env-file <file>", description: "environment file path" },
475
+ {
476
+ flags: "--target <target>",
477
+ description: "sync target: runtime (default) or github"
478
+ },
479
+ {
480
+ flags: "--platform <platform>",
481
+ description: "platform (firebase|vercel) for runtime target"
482
+ },
483
+ { flags: "-p, --project <project>", description: "project ID" },
484
+ {
485
+ flags: "--repo <repo>",
486
+ description: "GitHub repo (owner/repo) for github target"
487
+ }
488
+ ],
489
+ loader: "../apps/sync-secrets.ts",
490
+ wrapperFile: "sync-secrets",
491
+ exportName: "syncSecrets"
492
+ },
493
+ {
494
+ name: "make-admin [userId]",
495
+ description: "Set a user as admin (custom claims / app_metadata)",
496
+ alias: "ma",
497
+ category: "deployment",
498
+ public: true,
499
+ options: [
500
+ {
501
+ flags: "--project <projectId>",
502
+ description: "Project ID (Firebase or Supabase)"
503
+ },
504
+ {
505
+ flags: "--project-id <projectId>",
506
+ description: "Project ID (alias for --project)"
507
+ },
508
+ {
509
+ flags: "--super",
510
+ description: "Assign super role (isAdmin=true, isSuper=true, role=super)"
511
+ }
512
+ ],
513
+ loader: "../internal/make-admin.ts",
514
+ wrapperFile: "make-admin",
515
+ exportName: "makeAdmin"
516
+ },
517
+ {
518
+ name: "coach",
519
+ description: "Show what to configure before running setup",
520
+ category: "deployment",
521
+ public: true,
522
+ options: [],
523
+ loader: "../cli/coach/coach.ts",
524
+ exportName: "coach"
525
+ },
526
+ {
527
+ name: "setup [provider]",
528
+ description: "Set up infrastructure providers (firebase, supabase, vercel)",
529
+ category: "deployment",
530
+ public: true,
531
+ options: [],
532
+ loader: "../cli/setup/setup.ts",
533
+ exportName: "setup"
534
+ },
535
+ {
536
+ name: "setup-cicd",
537
+ description: "Setup CI/CD configuration",
538
+ category: "deployment",
539
+ loader: "../scaffolding/setup-cicd.ts",
540
+ exportName: "setupCICD"
541
+ },
542
+ {
543
+ name: "soc2",
544
+ description: "Run SOC2 readiness check \u2014 pass/fail report per Trust Service Criteria",
545
+ category: "deployment",
546
+ options: [
547
+ {
548
+ flags: "-a, --app <app>",
549
+ description: "app name to scan (if multiple apps)"
550
+ },
551
+ { flags: "--json", description: "output machine-readable JSON report" }
552
+ ],
553
+ loader: "../apps/soc2-check.ts",
554
+ exportName: "soc2Check"
555
+ },
556
+ {
557
+ name: "doctor",
558
+ description: "Check project health: validate provider connections and .env files",
559
+ category: "deployment",
560
+ public: true,
561
+ options: [
562
+ {
563
+ flags: "-c, --check <check>",
564
+ description: "run a single check (env, firebase, supabase, auth)"
565
+ }
566
+ ],
567
+ loader: "../cli/doctor/doctor.ts",
568
+ exportName: "doctor"
569
+ },
570
+ // ---------------------------------------------------------------------------
571
+ // Content
572
+ // ---------------------------------------------------------------------------
573
+ {
574
+ name: "blog <source>",
575
+ description: "Convert source image to optimized WebP for blog (1200px, quality 80)",
576
+ category: "content",
577
+ options: [
578
+ {
579
+ flags: "--slug <slug>",
580
+ description: "Output filename (default: source filename)"
581
+ }
582
+ ],
583
+ loader: "../apps/blog.ts"
584
+ },
585
+ // ---------------------------------------------------------------------------
586
+ // Internal
587
+ // ---------------------------------------------------------------------------
588
+ {
589
+ name: "keygen",
590
+ description: "Generate DoNotDev Framework license keys",
591
+ alias: "kg",
592
+ category: "internal",
593
+ options: [
594
+ {
595
+ flags: "--tier <tier>",
596
+ description: "license tier (dev_seat_1, project_1, etc.)"
597
+ },
598
+ {
599
+ flags: "--count <count>",
600
+ description: "number of keys to generate (default: 1)"
601
+ }
602
+ ],
603
+ loader: "../utils/keygen.ts",
604
+ exportName: "keygen"
605
+ },
606
+ {
607
+ name: "add-licenses [userId]",
608
+ description: "Add licenses to a user account (manual sales, gifts, Stripe fixes)",
609
+ alias: "al",
610
+ category: "internal",
611
+ options: [
612
+ { flags: "--dev-seats <n>", description: "number of dev seats to add" },
613
+ { flags: "--projects <n>", description: "number of projects to add" },
614
+ { flags: "--clean", description: "clean existing licenses first" }
615
+ ],
616
+ loader: "../internal/add-licenses.ts"
617
+ },
618
+ {
619
+ name: "grill-review",
620
+ description: "Interactive review of grill report (.dndev/grill-report.json)",
621
+ alias: "gr",
622
+ category: "internal",
623
+ options: [
624
+ {
625
+ flags: "-f, --filter <status>",
626
+ description: "Filter by status: pending (default), approved, rejected, skipped, all"
627
+ },
628
+ {
629
+ flags: "-s, --severity <level>",
630
+ description: "Filter by severity: blocker, warn, note"
631
+ },
632
+ {
633
+ flags: "--summary",
634
+ description: "Show summary only, no interactive review"
635
+ },
636
+ {
637
+ flags: "--export-pairs",
638
+ description: "Export reviewed items as DPO training pairs to .dndev/dpo-pairs.jsonl"
639
+ }
640
+ ],
641
+ loader: "../quality/grill-review.ts"
642
+ },
643
+ {
644
+ name: "generate sql",
645
+ description: "Generate PostgreSQL CREATE TABLE + RLS + trigger from entity definitions",
646
+ category: "internal",
647
+ options: [
648
+ {
649
+ flags: "--entity-dir <dir>",
650
+ description: "directory containing entity files (default: entities)"
651
+ },
652
+ {
653
+ flags: "--output-dir <dir>",
654
+ description: "output directory for migrations (default: supabase/migrations)"
655
+ },
656
+ {
657
+ flags: "--no-single-file",
658
+ description: "emit one migration file per entity"
659
+ }
660
+ ],
661
+ loader: "../generators/sql-generator.ts"
662
+ },
663
+ // ---------------------------------------------------------------------------
664
+ // Other
665
+ // ---------------------------------------------------------------------------
666
+ {
667
+ name: "test",
668
+ description: "Run tests across packages and apps",
669
+ category: "other",
670
+ options: [
671
+ {
672
+ flags: "-p, --package <package>",
673
+ description: "test a specific package (e.g., expo, core)"
674
+ },
675
+ { flags: "-a, --app <app>", description: "test a specific app" },
676
+ { flags: "-w, --watch", description: "run tests in watch mode" },
677
+ { flags: "-c, --coverage", description: "generate coverage report" },
678
+ { flags: "--ui", description: "open Vitest UI" },
679
+ {
680
+ flags: "--all",
681
+ description: "run all tests from root (uses root vitest.config.ts)"
682
+ }
683
+ ],
684
+ loader: "../quality/test.ts"
685
+ },
686
+ {
687
+ name: "test:e2e",
688
+ description: "Run Playwright E2E tests in apps/e2e-test",
689
+ category: "other",
690
+ options: [
691
+ { flags: "--ui", description: "open Playwright UI mode" },
692
+ { flags: "--headed", description: "run tests in headed browser" }
693
+ ],
694
+ loader: "../quality/test-e2e.ts"
695
+ },
696
+ {
697
+ name: "fix-turbo",
698
+ description: "Fix Turborepo binary platform mismatch (Windows/WSL/Linux)",
699
+ category: "other",
700
+ loader: "../maintenance/fix-turbo.ts",
701
+ exportName: "fixTurbo"
702
+ },
703
+ {
704
+ name: "zof",
705
+ description: "Nuclear cache clear + fresh bundle + tarball test",
706
+ category: "other",
707
+ options: [
708
+ {
709
+ flags: "--skip-bundle",
710
+ description: "Skip bundling (only clear caches)"
711
+ },
712
+ {
713
+ flags: "--skip-test",
714
+ description: "Skip ../test/ cleanup and reinstall"
715
+ },
716
+ {
717
+ flags: "--cleanup",
718
+ description: "Clean up tarballs after install (default: keep for testing)"
719
+ },
720
+ {
721
+ flags: "--fast",
722
+ description: "Fast mode: skip cache clearing (for iterative testing)"
723
+ }
724
+ ],
725
+ loader: "../maintenance/ZeOneOf"
726
+ },
727
+ {
728
+ name: "wai",
729
+ description: "Output WAI-WAY activation prompt for AI agents",
730
+ alias: "wai-way",
731
+ category: "other",
732
+ public: true,
733
+ options: [
734
+ { flags: "-w, --workflow", description: "Show workflow summary only" },
735
+ { flags: "-c, --copy", description: "Copy prompt to clipboard" }
736
+ ],
737
+ loader: "../cli/wai.ts",
738
+ exportName: "wai"
739
+ },
740
+ {
741
+ name: "agent:setup",
742
+ description: "Configure local and global agents to connect to the DoNotDev Intelligence Engine (MCP)",
743
+ category: "other",
744
+ public: true,
745
+ wrapperFile: "agent-setup",
746
+ exportName: "agentSetup",
747
+ loader: "../cli/agent-setup.ts"
748
+ }
749
+ ];
750
+ }
751
+ });
752
+
753
+ // packages/cli/src/bin/dndev.mjs
754
+ init_utils();
755
+ init_command_registry();
756
+ import { Command } from "commander";
757
+
758
+ // packages/tooling/src/cli/entry-helpers.ts
759
+ init_utils();
760
+ function baseName2(commanderName) {
761
+ return commanderName.split(" ")[0] ?? commanderName;
88
762
  }
89
- var program = new Command();
90
- program.name("dndev").description("DoNotDev Framework CLI").version(CLI_VERSION, "-v, --version", "display version number").usage("<command>[:<app>] [options]").helpCommand("help [command]", "display help for command");
91
763
  function extractCommonOptions(commanderOptions) {
92
764
  const quiet = process.env.QUIET === "true" || process.env.QUIET === "1" || commanderOptions.quiet || false;
93
765
  const debug = process.env.DEBUG === "true" || process.env.DEBUG === "1" || commanderOptions.debug || false;
94
766
  const verbose = !debug && (process.env.VERBOSE === "true" || process.env.VERBOSE === "1" || commanderOptions.verbose || false);
95
- const dryRun = process.env.DRY_RUN === "true" || process.env.DRY_RUN === "1" || commanderOptions.dryRun || false;
767
+ const dryRun = process.env.DRY_RUN === "true" || process.env.DRY_RUN === "1" || commanderOptions.dryRun || commanderOptions.dry || false;
96
768
  return { dryRun, quiet, verbose, debug };
97
769
  }
98
770
  function addCommonOptions(cmd) {
99
- cmd.option("-d, --dry-run", "Preview changes without applying").option("--verbose", "Verbose output").option("--debug", "Debug output").option("-q, --quiet", "Quiet output (errors only)");
771
+ cmd.option("--dry, --dry-run", "Preview changes without applying").option("--verbose", "Verbose output").option("--debug", "Debug output").option("-q, --quiet", "Quiet output (errors only)");
100
772
  }
101
- program.command("init [name]").alias("create-project").description("Create a new DoNotDev project").action(async (name) => {
102
- const { main } = await import("./commands/create-project.js");
103
- await main({ projectName: name });
104
- });
105
- program.command("create-app [name]").description("Add a new app to existing project").option("--name <name>", "App name (non-interactive)").option("--builder <builder>", "Framework: vite, next, or expo (default: vite)").option("--host <host>", "Hosting: none, vercel, or firebase (default: none)").option("--functions <runtime>", "Functions: none, vercel, firebase, or supabase (default: none)").option("--backend <backend>", "BaaS: none, firebase, or supabase (default: none)").option("--project <id>", "Firebase project ID (default: app name)").option("--region <region>", "Firebase region (default: europe-west1)").action(async (name, options) => {
106
- const { main } = await import("./commands/create-app.js");
107
- const appName = name || options.name;
108
- if (appName) {
109
- await main({
110
- name: appName,
111
- builder: options.builder,
112
- host: options.host,
113
- functions: options.functions,
114
- backend: options.backend,
115
- firebaseProjectId: options.project,
116
- firebaseRegion: options.region
117
- });
118
- } else {
119
- await main();
773
+ function registerCommand(program2, def, action) {
774
+ const cmd = program2.command(def.name);
775
+ if (def.alias) {
776
+ const aliases = Array.isArray(def.alias) ? def.alias : [def.alias];
777
+ for (const a of aliases) cmd.alias(a);
120
778
  }
121
- });
122
- var formatCmd = program.command("format").description("Format code with Prettier");
123
- addCommonOptions(formatCmd);
124
- formatCmd.action(async (commanderOptions) => {
125
- const commonOptions = extractCommonOptions(commanderOptions);
126
- const options = { ...commonOptions, ...commanderOptions };
127
- try {
128
- const { main } = await import("./commands/format.js");
129
- process.exitCode = await main(options);
130
- } catch (error) {
131
- if (error.code === "invalid-argument" || error.name === "DoNotDevError") {
132
- process.exit(error.context?.exitCode || 1);
779
+ cmd.description(def.description);
780
+ if (def.options) {
781
+ for (const opt of def.options) {
782
+ cmd.option(opt.flags, opt.description);
133
783
  }
134
- throw error;
135
784
  }
136
- });
137
- var tcCmd = program.command("tc [app]").alias("type-check").description("TypeScript type-check (runs bun run type-check in all packages)");
138
- addCommonOptions(tcCmd);
139
- tcCmd.action(async (app, commanderOptions) => {
140
- const commonOptions = extractCommonOptions(commanderOptions);
141
- const options = { ...commonOptions, app };
142
- try {
143
- const { main } = await import("./commands/type-check.js");
144
- process.exit(await main(options));
145
- } catch (error) {
146
- if (error.code === "invalid-argument" || error.name === "DoNotDevError") {
147
- process.exit(error.context?.exitCode || 1);
148
- }
149
- throw error;
150
- }
151
- });
152
- var cacheoutCmd = program.command("cacheout [app]").alias("co").description("Clear build caches").option("--app <app>", "App name to clear cache for");
153
- addCommonOptions(cacheoutCmd);
154
- cacheoutCmd.action(async (app, commanderOptions) => {
155
- const commonOptions = extractCommonOptions(commanderOptions);
156
- const options = { ...commonOptions, ...commanderOptions };
157
- if (app) {
158
- options.app = app;
159
- }
160
- const { main } = await import("./commands/cacheout.js");
161
- process.exitCode = await main(options);
162
- });
163
- var bumpCmd = program.command("bump").description("Update framework packages and peer dependencies to latest compatible versions");
164
- addCommonOptions(bumpCmd);
165
- bumpCmd.action(async (commanderOptions) => {
166
- const commonOptions = extractCommonOptions(commanderOptions);
167
- const options = { ...commonOptions, ...commanderOptions };
168
- try {
169
- const { main } = await import("./commands/bump.js");
170
- process.exitCode = await main(options);
171
- } catch (error) {
172
- if (error.code === "invalid-argument" || error.name === "DoNotDevError") {
173
- process.exit(error.context?.exitCode || 1);
174
- }
175
- throw error;
176
- }
177
- });
178
- var stagingCmd = program.command("staging [app]").alias("uat").description("Deploy to staging/UAT (shorthand for deploy --staging)").option("-p, --project <project>", "Firebase project ID (overrides .firebaserc)").option("--skip-build", "skip build step").option("--force", "Force deployment / cleanup policy");
179
- addCommonOptions(stagingCmd);
180
- stagingCmd.action(async (app, commanderOptions) => {
181
- const commonOptions = extractCommonOptions(commanderOptions);
182
- const options = { ...commonOptions, ...commanderOptions, app, staging: true };
183
- const { main } = await import("./commands/deploy.js");
184
- await main(options);
185
- });
186
- var deployCmd = program.command("deploy [app]").description("Deploy to Firebase").option("-p, --project <project>", "Firebase project ID").option("--skip-build", "skip build step").option("--staging", "Deploy to staging (uses .env.staging, service-account-key.staging.json, .firebaserc staging project)");
187
- addCommonOptions(deployCmd);
188
- deployCmd.action(async (app, commanderOptions) => {
189
- const commonOptions = extractCommonOptions(commanderOptions);
190
- const options = { ...commonOptions, ...commanderOptions, app };
191
- const { main } = await import("./commands/deploy.js");
192
- await main(options);
193
- });
194
- var syncSecretsCmd = program.command("sync-secrets").description("Sync env vars to Firebase/Vercel or GitHub Secrets").option("-e, --env-file <file>", "environment file path").option("--target <target>", "sync target: runtime (default) or github").option("--platform <platform>", "platform (firebase|vercel) for runtime target").option("-p, --project <project>", "project ID").option("--repo <repo>", "GitHub repo (owner/repo) for github target");
195
- addCommonOptions(syncSecretsCmd);
196
- syncSecretsCmd.action(async (commanderOptions) => {
197
- const commonOptions = extractCommonOptions(commanderOptions);
198
- const options = { ...commonOptions, ...commanderOptions };
199
- if (options.project) {
200
- options.projectId = options.project;
201
- }
202
- const { main } = await import("./commands/sync-secrets.js");
203
- process.exitCode = await main(options);
204
- });
205
- var makeAdminCmd = program.command("make-admin [userId]").alias("ma").description("Set a user as admin (custom claims / app_metadata)").option("--project <projectId>", "Project ID (Firebase or Supabase)").option("--project-id <projectId>", "Project ID (alias for --project)").option("--super", "Assign super role (isAdmin=true, isSuper=true, role=super)");
206
- addCommonOptions(makeAdminCmd);
207
- makeAdminCmd.action(async (userId, commanderOptions) => {
208
- const args2 = [];
209
- if (userId) args2.push(userId);
210
- if (commanderOptions.project) args2.push(`--project=${commanderOptions.project}`);
211
- if (commanderOptions.projectId) args2.push(`--project-id=${commanderOptions.projectId}`);
212
- if (commanderOptions.super) args2.push("--super");
213
- const { main } = await import("./commands/make-admin.js");
214
- await main(args2);
215
- });
216
- var setupCmd = program.command("setup [provider]").description("Set up provider credentials and connections (firebase, supabase, vercel, stripe, oauth, auth)").option("-a, --app <app>", "app name (if multiple apps)").option("--skip-doctor", "Skip running doctor after setup");
217
- addCommonOptions(setupCmd);
218
- setupCmd.action(async (provider, commanderOptions) => {
219
- const commonOptions = extractCommonOptions(commanderOptions);
220
- const options = { ...commonOptions, provider, app: commanderOptions.app, skipDoctor: commanderOptions.skipDoctor };
221
- const { main } = await import("./commands/setup.js");
222
- process.exitCode = await main(options);
223
- });
224
- var doctorCmd = program.command("doctor").description("Check project health: validate provider connections and .env files").option("-a, --app <app>", "app name (if multiple apps)").option("-c, --check <check>", "run a single check (env, firebase, supabase, stripe, auth)");
225
- addCommonOptions(doctorCmd);
226
- doctorCmd.action(async (commanderOptions) => {
227
- const commonOptions = extractCommonOptions(commanderOptions);
228
- const options = { ...commonOptions, app: commanderOptions.app, check: commanderOptions.check };
229
- const { main } = await import("./commands/doctor.js");
230
- process.exit(await main(options));
231
- });
232
- async function runAppCommand(commandPath, app) {
785
+ addCommonOptions(cmd);
786
+ cmd.action(async (...commanderArgs) => {
787
+ const commanderOptions = commanderArgs[commanderArgs.length - 2];
788
+ const positionalArgs = commanderArgs.slice(0, -2);
789
+ const commonOptions = extractCommonOptions(commanderOptions);
790
+ const parsedOptions = { ...commonOptions, ...commanderOptions };
791
+ await action(parsedOptions, ...positionalArgs);
792
+ });
793
+ }
794
+
795
+ // packages/cli/src/bin/dndev.mjs
796
+ var CLI_VERSION = true ? "0.0.20" : "0.0.0";
797
+ var args = process.argv.slice(2);
798
+ if (args.length === 1 && (args[0] === "--version" || args[0] === "-v")) {
799
+ console.log(CLI_VERSION);
800
+ process.exit(0);
801
+ }
802
+ if (args.length === 0 || args.length === 1 && (args[0] === "--help" || args[0] === "-h")) {
803
+ const { generateHelpText: generateHelpText2 } = await Promise.resolve().then(() => (init_command_registry(), command_registry_exports));
804
+ console.log(`DoNotDev CLI v${CLI_VERSION}
805
+ `);
806
+ console.log(generateHelpText2("dndev"));
807
+ process.exit(0);
808
+ }
809
+ var program = new Command();
810
+ program.name("dndev").description("DoNotDev Framework CLI").version(CLI_VERSION, "-v, --version", "display version number").usage("<command>[:<app>] [options]").helpCommand("help [command]", "display help for command");
811
+ async function runAppCommand(commandPath, app, commonOptions) {
233
812
  const savedArgv = process.argv;
234
813
  process.argv = app ? [savedArgv[0], savedArgv[1], app] : [savedArgv[0], savedArgv[1]];
235
814
  try {
236
815
  const { main } = await import(commandPath);
237
- process.exit(await main());
816
+ process.exitCode = await main(commonOptions);
817
+ } catch (error) {
818
+ console.error(`Command failed: ${error.message}`);
819
+ process.exitCode = error.context?.exitCode || 1;
238
820
  } finally {
239
821
  process.argv = savedArgv;
240
822
  }
241
823
  }
242
- program.command("dev [app]").description("Start development server").action((app) => runAppCommand("./commands/dev.js", app));
243
- program.command("emu [app]").description("Start dev with local backend").action((app) => runAppCommand("./commands/emu.js", app));
244
- program.command("build [app]").description("Build for production").action((app) => runAppCommand("./commands/build.js", app));
245
- program.command("preview [app]").description("Preview production build").action((app) => runAppCommand("./commands/preview.js", app));
246
- program.command("agent").alias("agent:setup").description("Configure MCP server for all AI agents (Cursor, Claude Code, Gemini, Claude Desktop)").option("-d, --dry-run", "Preview changes without applying").action(async (commanderOptions) => {
247
- const options = extractCommonOptions(commanderOptions);
248
- const { main } = await import("./commands/agent-setup.js");
249
- await main(options);
250
- });
251
- program.command("wai").alias("wai-way").description("Output WAI-WAY activation prompt for AI agents").option("-w, --workflow", "Show workflow summary only").option("-c, --copy", "Copy prompt to clipboard").action(async () => {
252
- const { main } = await import("./commands/wai.js");
253
- process.exit(await main());
254
- });
255
- function preprocessArgs(args2) {
256
- if (args2.length === 0) return args2;
257
- const firstArg = args2[0];
258
- const appCommands = ["dev", "build", "preview", "emu", "deploy", "staging", "tc", "type-check", "cacheout", "co"];
824
+ function makeStandardAction(commandPath) {
825
+ return async (options, ...positionalArgs) => {
826
+ try {
827
+ const { main } = await import(commandPath);
828
+ await main(options, ...positionalArgs);
829
+ } catch (error) {
830
+ console.error(`Command failed: ${error.message}`);
831
+ process.exitCode = error.context?.exitCode || 1;
832
+ }
833
+ };
834
+ }
835
+ function makeAppAction(commandPath) {
836
+ return async (options, app) => {
837
+ await runAppCommand(commandPath, app, extractCommonOptions(options));
838
+ };
839
+ }
840
+ var ACTION_OVERRIDES = {
841
+ "create-app": async (options, name) => {
842
+ const appName = name || options.name;
843
+ const { main } = await import("./commands/create-app.js");
844
+ if (appName) {
845
+ await main({
846
+ ...options,
847
+ name: appName
848
+ });
849
+ } else {
850
+ await main(options);
851
+ }
852
+ },
853
+ "type-check": async (options, app) => {
854
+ const { main } = await import("./commands/type-check.js");
855
+ process.exitCode = await main({ ...options, package: app });
856
+ },
857
+ "cacheout": async (options, app) => {
858
+ if (app) options.app = app;
859
+ const { main } = await import("./commands/cacheout.js");
860
+ process.exitCode = await main(options);
861
+ },
862
+ "staging": async (options, app) => {
863
+ const { main } = await import("./commands/deploy.js");
864
+ await main({ ...options, app, staging: true });
865
+ },
866
+ "deploy": async (options, app) => {
867
+ const { main } = await import("./commands/deploy.js");
868
+ await main({ ...options, app });
869
+ },
870
+ "sync-secrets": async (options) => {
871
+ if (options.project) options.projectId = options.project;
872
+ const { main } = await import("./commands/sync-secrets.js");
873
+ process.exitCode = await main(options);
874
+ },
875
+ "make-admin": async (options, userId) => {
876
+ const args2 = [];
877
+ if (userId) args2.push(userId);
878
+ if (options.project) args2.push(`--project=${options.project}`);
879
+ if (options.projectId) args2.push(`--project-id=${options.projectId}`);
880
+ if (options.super) args2.push("--super");
881
+ if (options.dryRun) args2.push("--dry-run");
882
+ if (options.verbose) args2.push("--verbose");
883
+ if (options.debug) args2.push("--debug");
884
+ try {
885
+ const { main } = await import("./commands/make-admin.js");
886
+ await main(args2);
887
+ } catch (error) {
888
+ console.error(`make-admin failed: ${error.message}`);
889
+ process.exitCode = error.context?.exitCode || 1;
890
+ }
891
+ },
892
+ "setup": async (options, provider) => {
893
+ const { main } = await import("./commands/setup.js");
894
+ process.exitCode = await main({ ...options, provider });
895
+ },
896
+ "doctor": async (options) => {
897
+ const { main } = await import("./commands/doctor.js");
898
+ process.exitCode = await main({ ...options, check: options.check });
899
+ },
900
+ "wai": async () => {
901
+ const { main } = await import("./commands/wai.js");
902
+ process.exitCode = await main();
903
+ },
904
+ "agent:setup": async (options) => {
905
+ const { main } = await import("./commands/agent-setup.js");
906
+ await main(options);
907
+ }
908
+ };
909
+ for (const def of getPublicCommands()) {
910
+ const cmdName = baseName2(def.name);
911
+ const wrapperFile = def.wrapperFile ?? cmdName;
912
+ const commandPath = `./commands/${wrapperFile}.js`;
913
+ const override = ACTION_OVERRIDES[def.name] ?? ACTION_OVERRIDES[cmdName];
914
+ let action;
915
+ if (override) {
916
+ action = override;
917
+ } else if (def.actionPattern === "app") {
918
+ action = makeAppAction(commandPath);
919
+ } else {
920
+ action = makeStandardAction(commandPath);
921
+ }
922
+ registerCommand(program, def, action);
923
+ }
924
+ function preprocessArgs(rawArgs) {
925
+ if (rawArgs.length === 0) return rawArgs;
926
+ const firstArg = rawArgs[0];
927
+ const appCommands = getAppCommandNames();
259
928
  if (firstArg && firstArg.includes(":")) {
260
929
  const colonIndex = firstArg.indexOf(":");
261
930
  const command = firstArg.substring(0, colonIndex);
262
931
  const app = firstArg.substring(colonIndex + 1);
263
932
  if (appCommands.includes(command) && app) {
264
- return [command, app, ...args2.slice(1)];
933
+ return [command, app, ...rawArgs.slice(1)];
265
934
  }
266
935
  }
267
- return args2;
936
+ return rawArgs;
268
937
  }
269
938
  program.on("command:*", () => {
270
939
  console.error(`Unknown command: ${program.args.join(" ")}`);