@donotdev/cli 0.0.17 → 0.0.19

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 (183) hide show
  1. package/dependencies-matrix.json +67 -60
  2. package/dist/bin/commands/coach.js +8177 -0
  3. package/dist/bin/commands/create-app.js +94 -145
  4. package/dist/bin/commands/create-project.js +98 -149
  5. package/dist/bin/commands/deploy.js +81 -59
  6. package/dist/bin/commands/doctor.js +243 -698
  7. package/dist/bin/commands/emu.js +2 -2
  8. package/dist/bin/commands/format.js +4 -1
  9. package/dist/bin/commands/get-demo.js +8351 -0
  10. package/dist/bin/commands/make-admin.js +773 -152
  11. package/dist/bin/commands/setup.js +519 -1711
  12. package/dist/bin/commands/staging.js +17852 -0
  13. package/dist/bin/commands/sync-secrets.js +2 -11
  14. package/dist/bin/commands/type-check.js +7733 -1713
  15. package/dist/bin/dndev.js +913 -182
  16. package/dist/bin/donotdev.js +913 -182
  17. package/dist/index.js +191 -211
  18. package/package.json +1 -1
  19. package/templates/app-demo/index.html.example +147 -10
  20. package/templates/app-demo/src/App.tsx.example +7 -13
  21. package/templates/app-demo/src/config/app.ts.example +12 -48
  22. package/templates/app-demo/src/entities/product.ts.example +38 -0
  23. package/templates/app-demo/src/globals.css.example +5 -1
  24. package/templates/app-demo/src/main.tsx.example +13 -7
  25. package/templates/app-demo/src/pages/ChangelogPage.tsx.example +14 -0
  26. package/templates/app-demo/src/pages/DashboardPage.tsx.example +15 -0
  27. package/templates/app-demo/src/pages/HomePage.tsx.example +3 -77
  28. package/templates/app-demo/src/pages/PricingPage.tsx.example +14 -0
  29. package/templates/app-demo/src/pages/ProductsPage.tsx.example +17 -0
  30. package/templates/app-demo/src/pages/ProfilePage.tsx.example +16 -0
  31. package/templates/app-demo/src/pages/SettingsPage.tsx.example +15 -0
  32. package/templates/app-demo/src/pages/ShowcaseDetailPage.tsx.example +112 -0
  33. package/templates/app-demo/src/pages/ShowcasePage.tsx.example +91 -0
  34. package/templates/app-demo/src/pages/legal/LegalPage.tsx.example +14 -0
  35. package/templates/app-demo/src/pages/legal/PrivacyPage.tsx.example +14 -0
  36. package/templates/app-demo/src/pages/legal/TermsPage.tsx.example +14 -0
  37. package/templates/app-demo/tsconfig.json.example +1 -1
  38. package/templates/app-demo/vite.config.ts.example +23 -48
  39. package/templates/app-expo/README.md.example +1 -1
  40. package/templates/app-expo/app/index.tsx.example +1 -1
  41. package/templates/app-vite/src/pages/HomePage.tsx.example +8 -10
  42. package/templates/overlay-firebase/env.fragment.example +1 -1
  43. package/templates/overlay-firebase/env.fragment.expo.example +1 -1
  44. package/templates/overlay-firebase/env.fragment.nextjs.example +1 -1
  45. package/templates/overlay-supabase/env.fragment.example +1 -1
  46. package/templates/overlay-supabase/env.fragment.expo.example +1 -1
  47. package/templates/overlay-supabase/env.fragment.nextjs.example +1 -1
  48. package/templates/overlay-vercel/env.fragment.example +1 -1
  49. package/templates/overlay-vercel/env.fragment.nextjs.example +1 -1
  50. package/templates/root-consumer/.claude/commands/brainstorm.md.example +15 -1
  51. package/templates/root-consumer/.claude/commands/build.md.example +24 -2
  52. package/templates/root-consumer/.claude/commands/design.md.example +17 -0
  53. package/templates/root-consumer/.claude/commands/polish.md.example +17 -0
  54. package/templates/root-consumer/AI.md.example +54 -21
  55. package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +21 -6
  56. package/templates/root-consumer/guides/dndev/COMPONENTS_ADV.md.example +16 -179
  57. package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +19 -21
  58. package/templates/root-consumer/guides/dndev/GOTCHAS.md.example +14 -3
  59. package/templates/root-consumer/guides/dndev/INDEX.md.example +2 -2
  60. package/templates/root-consumer/guides/dndev/SETUP_APP_CONFIG.md.example +3 -3
  61. package/templates/root-consumer/guides/dndev/SETUP_BLOG.md.example +19 -2
  62. package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +35 -1
  63. package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +17 -12
  64. package/templates/root-consumer/guides/dndev/SETUP_LAYOUTS.md.example +32 -0
  65. package/templates/root-consumer/guides/dndev/SETUP_OAUTH_PROVIDERS.md.example +1 -1
  66. package/templates/root-consumer/guides/dndev/SETUP_PAGES.md.example +74 -6
  67. package/templates/root-consumer/guides/dndev/SETUP_STRIPE.md.example +2 -2
  68. package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +17 -12
  69. package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +37 -16
  70. package/templates/root-consumer/guides/dndev/USE_ROUTING.md.example +18 -18
  71. package/templates/root-consumer/guides/dndev/essences_reference.css.example +119 -2
  72. package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +1 -1
  73. package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +14 -0
  74. package/templates/root-consumer/guides/wai-way/blueprints/2_entities.md.example +6 -0
  75. package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +14 -0
  76. package/templates/root-consumer/guides/wai-way/entity_patterns.md.example +4 -5
  77. package/templates/root-consumer/guides/wai-way/page_patterns.md.example +2 -2
  78. package/dist/bin/commands/agent-setup.d.ts +0 -6
  79. package/dist/bin/commands/agent-setup.d.ts.map +0 -1
  80. package/dist/bin/commands/agent-setup.js.map +0 -1
  81. package/dist/bin/commands/build.d.ts +0 -11
  82. package/dist/bin/commands/build.d.ts.map +0 -1
  83. package/dist/bin/commands/build.js.map +0 -1
  84. package/dist/bin/commands/bump.d.ts +0 -11
  85. package/dist/bin/commands/bump.d.ts.map +0 -1
  86. package/dist/bin/commands/bump.js.map +0 -1
  87. package/dist/bin/commands/cacheout.d.ts +0 -11
  88. package/dist/bin/commands/cacheout.d.ts.map +0 -1
  89. package/dist/bin/commands/cacheout.js.map +0 -1
  90. package/dist/bin/commands/create-app.d.ts +0 -11
  91. package/dist/bin/commands/create-app.d.ts.map +0 -1
  92. package/dist/bin/commands/create-app.js.map +0 -1
  93. package/dist/bin/commands/create-project.d.ts +0 -11
  94. package/dist/bin/commands/create-project.d.ts.map +0 -1
  95. package/dist/bin/commands/create-project.js.map +0 -1
  96. package/dist/bin/commands/deploy.d.ts +0 -11
  97. package/dist/bin/commands/deploy.d.ts.map +0 -1
  98. package/dist/bin/commands/deploy.js.map +0 -1
  99. package/dist/bin/commands/dev.d.ts +0 -11
  100. package/dist/bin/commands/dev.d.ts.map +0 -1
  101. package/dist/bin/commands/dev.js.map +0 -1
  102. package/dist/bin/commands/doctor.d.ts +0 -6
  103. package/dist/bin/commands/doctor.d.ts.map +0 -1
  104. package/dist/bin/commands/doctor.js.map +0 -1
  105. package/dist/bin/commands/emu.d.ts +0 -11
  106. package/dist/bin/commands/emu.d.ts.map +0 -1
  107. package/dist/bin/commands/emu.js.map +0 -1
  108. package/dist/bin/commands/format.d.ts +0 -11
  109. package/dist/bin/commands/format.d.ts.map +0 -1
  110. package/dist/bin/commands/format.js.map +0 -1
  111. package/dist/bin/commands/make-admin.d.ts +0 -11
  112. package/dist/bin/commands/make-admin.d.ts.map +0 -1
  113. package/dist/bin/commands/make-admin.js.map +0 -1
  114. package/dist/bin/commands/preview.d.ts +0 -11
  115. package/dist/bin/commands/preview.d.ts.map +0 -1
  116. package/dist/bin/commands/preview.js.map +0 -1
  117. package/dist/bin/commands/setup.d.ts +0 -6
  118. package/dist/bin/commands/setup.d.ts.map +0 -1
  119. package/dist/bin/commands/setup.js.map +0 -1
  120. package/dist/bin/commands/sync-secrets.d.ts +0 -11
  121. package/dist/bin/commands/sync-secrets.d.ts.map +0 -1
  122. package/dist/bin/commands/sync-secrets.js.map +0 -1
  123. package/dist/bin/commands/type-check.d.ts +0 -14
  124. package/dist/bin/commands/type-check.d.ts.map +0 -1
  125. package/dist/bin/commands/type-check.js.map +0 -1
  126. package/dist/bin/commands/wai.d.ts +0 -11
  127. package/dist/bin/commands/wai.d.ts.map +0 -1
  128. package/dist/bin/commands/wai.js.map +0 -1
  129. package/dist/index.d.ts +0 -8
  130. package/dist/index.d.ts.map +0 -1
  131. package/dist/index.js.map +0 -1
  132. package/templates/app-demo/src/components/ThemeToggle.tsx.example +0 -48
  133. package/templates/app-demo/src/pages/DetailPage.tsx.example +0 -103
  134. package/templates/app-demo/src/pages/FullPage.tsx.example +0 -142
  135. package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +0 -266
  136. package/templates/app-demo/src/pages/components/LayoutRoute.tsx.example +0 -20
  137. package/templates/functions-firebase/functions-firebase/README.md.example +0 -123
  138. package/templates/functions-firebase/functions-firebase/build.mjs.example +0 -5
  139. package/templates/functions-firebase/functions-firebase/src/auth/getCustomClaims.ts.example +0 -19
  140. package/templates/functions-firebase/functions-firebase/src/auth/getUserAuthStatus.ts.example +0 -21
  141. package/templates/functions-firebase/functions-firebase/src/auth/index.ts.example +0 -11
  142. package/templates/functions-firebase/functions-firebase/src/auth/removeCustomClaims.ts.example +0 -21
  143. package/templates/functions-firebase/functions-firebase/src/auth/setCustomClaims.ts.example +0 -21
  144. package/templates/functions-firebase/functions-firebase/src/billing/handleStripeWebhook.ts.example +0 -24
  145. package/templates/functions-firebase/functions-firebase/src/billing/index.ts.example +0 -10
  146. package/templates/functions-firebase/functions-firebase/src/billing/processPaymentSuccess.ts.example +0 -14
  147. package/templates/functions-firebase/functions-firebase/src/billing/refreshSubscriptionStatus.ts.example +0 -14
  148. package/templates/functions-firebase/functions-firebase/src/index.ts.example +0 -39
  149. package/templates/functions-firebase/functions-firebase/src/oauth/checkGitHubAccess.ts.example +0 -14
  150. package/templates/functions-firebase/functions-firebase/src/oauth/disconnect.ts.example +0 -14
  151. package/templates/functions-firebase/functions-firebase/src/oauth/exchangeToken.ts.example +0 -14
  152. package/templates/functions-firebase/functions-firebase/src/oauth/getConnections.ts.example +0 -14
  153. package/templates/functions-firebase/functions-firebase/src/oauth/grantGitHubAccess.ts.example +0 -14
  154. package/templates/functions-firebase/functions-firebase/src/oauth/index.ts.example +0 -17
  155. package/templates/functions-firebase/functions-firebase/src/oauth/refreshToken.ts.example +0 -14
  156. package/templates/functions-firebase/functions-firebase/src/oauth/revokeGitHubAccess.ts.example +0 -14
  157. package/templates/functions-firebase/functions-firebase/tsconfig.json.example +0 -21
  158. package/templates/functions-vercel/functions-vercel/README.md.example +0 -116
  159. package/templates/functions-vercel/functions-vercel/build.mjs.example +0 -52
  160. package/templates/functions-vercel/functions-vercel/src/api/auth/getCustomClaims.ts.example +0 -20
  161. package/templates/functions-vercel/functions-vercel/src/api/auth/getUserAuthStatus.ts.example +0 -20
  162. package/templates/functions-vercel/functions-vercel/src/api/auth/removeCustomClaims.ts.example +0 -20
  163. package/templates/functions-vercel/functions-vercel/src/api/auth/setCustomClaims.ts.example +0 -20
  164. package/templates/functions-vercel/functions-vercel/src/api/billing/handleStripeWebhook.ts.example +0 -20
  165. package/templates/functions-vercel/functions-vercel/src/api/billing/processPaymentSuccess.ts.example +0 -20
  166. package/templates/functions-vercel/functions-vercel/src/api/billing/refreshSubscriptionStatus.ts.example +0 -20
  167. package/templates/functions-vercel/functions-vercel/src/api/crud/createEntity.ts.example +0 -20
  168. package/templates/functions-vercel/functions-vercel/src/api/crud/deleteEntity.ts.example +0 -20
  169. package/templates/functions-vercel/functions-vercel/src/api/crud/getEntity.ts.example +0 -20
  170. package/templates/functions-vercel/functions-vercel/src/api/crud/listEntities.ts.example +0 -20
  171. package/templates/functions-vercel/functions-vercel/src/api/crud/updateEntity.ts.example +0 -20
  172. package/templates/functions-vercel/functions-vercel/src/api/oauth/checkGitHubAccess.ts.example +0 -20
  173. package/templates/functions-vercel/functions-vercel/src/api/oauth/disconnect.ts.example +0 -20
  174. package/templates/functions-vercel/functions-vercel/src/api/oauth/exchangeToken.ts.example +0 -20
  175. package/templates/functions-vercel/functions-vercel/src/api/oauth/getConnections.ts.example +0 -20
  176. package/templates/functions-vercel/functions-vercel/src/api/oauth/grantGitHubAccess.ts.example +0 -20
  177. package/templates/functions-vercel/functions-vercel/src/api/oauth/refreshToken.ts.example +0 -20
  178. package/templates/functions-vercel/functions-vercel/src/api/oauth/revokeGitHubAccess.ts.example +0 -20
  179. package/templates/functions-vercel/functions-vercel/tsconfig.json.example +0 -21
  180. package/templates/functions-vercel/functions-vercel/vercel.json.example +0 -14
  181. package/templates/github/github/workflows/firebase-deploy.yml.example +0 -79
  182. /package/templates/functions-firebase/{functions-firebase/.env.example.example → .env.example} +0 -0
  183. /package/templates/functions-vercel/{functions-vercel/.env.example.example → .env.example} +0 -0
@@ -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,8 +35,724 @@ var init_utils = __esm({
30
35
  }
31
36
  });
32
37
 
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;
49
+ }
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}
103
+
104
+ Usage: ${cliName} <command>[:<app>] [options]` : `${title}
105
+
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
121
+
122
+ Run '${cliName} <command> --help' for command-specific help.` : `Options:
123
+ -v, --version Display version number
124
+ -h, --help Display this help
125
+
126
+ Examples:
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
137
+
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
+
33
753
  // packages/cli/src/bin/dndev.mjs
34
754
  init_utils();
755
+ init_command_registry();
35
756
  import { readFileSync } from "node:fs";
36
757
  import { Command } from "commander";
37
758
  var CLI_VERSION = JSON.parse(
@@ -43,46 +764,10 @@ if (args.length === 1 && (args[0] === "--version" || args[0] === "-v")) {
43
764
  process.exit(0);
44
765
  }
45
766
  if (args.length === 0 || args.length === 1 && (args[0] === "--help" || args[0] === "-h")) {
767
+ const { generateHelpText: generateHelpText2 } = await Promise.resolve().then(() => (init_command_registry(), command_registry_exports));
46
768
  console.log(`DoNotDev CLI v${CLI_VERSION}
47
-
48
- Usage: dndev <command>[:<app>] [options]
49
-
50
- Commands:
51
- init, create-project Create a new DoNotDev project
52
- create-app [name] Add app (--builder vite|next, --functions, --project <id>)
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)
69
-
70
- Options:
71
- -v, --version Display version number
72
- -h, --help Display this help
73
-
74
- 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, no functions)
78
- dndev create-app my-app --builder next --functions Next.js + functions
79
- dndev create-app my-app --functions --project my-fb-id Set Firebase project (2-min setup)
80
- dndev dev Start dev server
81
- dndev dev:web Start dev server for 'web' app
82
- dndev agent Configure MCP for all AI agents
83
- dndev wai Output WAI-WAY activation prompt
84
-
85
- Run 'dndev <command> --help' for command-specific help.`);
769
+ `);
770
+ console.log(generateHelpText2("dndev"));
86
771
  process.exit(0);
87
772
  }
88
773
  var program = new Command();
@@ -97,135 +782,6 @@ function extractCommonOptions(commanderOptions) {
97
782
  function addCommonOptions(cmd) {
98
783
  cmd.option("-d, --dry-run", "Preview changes without applying").option("--verbose", "Verbose output").option("--debug", "Debug output").option("-q, --quiet", "Quiet output (errors only)");
99
784
  }
100
- program.command("init [name]").alias("create-project").description("Create a new DoNotDev project").action(async (name) => {
101
- const { main } = await import("./commands/create-project.js");
102
- await main({ projectName: name });
103
- });
104
- 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 or next (default: vite)").option("--functions", "Include Firebase functions").option("--project <id>", "Firebase project ID (default: app name)").option("--region <region>", "Firebase region (default: europe-west1)").action(async (name, options) => {
105
- const { main } = await import("./commands/create-app.js");
106
- const appName = name || options.name;
107
- if (appName) {
108
- await main({
109
- name: appName,
110
- builder: options.builder,
111
- functions: options.functions,
112
- firebaseProjectId: options.project,
113
- firebaseRegion: options.region
114
- });
115
- } else {
116
- await main();
117
- }
118
- });
119
- var formatCmd = program.command("format").description("Format code with Prettier");
120
- addCommonOptions(formatCmd);
121
- formatCmd.action(async (commanderOptions) => {
122
- const commonOptions = extractCommonOptions(commanderOptions);
123
- const options = { ...commonOptions, ...commanderOptions };
124
- try {
125
- const { main } = await import("./commands/format.js");
126
- process.exitCode = await main(options);
127
- } catch (error) {
128
- if (error.code === "invalid-argument" || error.name === "DoNotDevError") {
129
- process.exit(error.context?.exitCode || 1);
130
- }
131
- throw error;
132
- }
133
- });
134
- var tcCmd = program.command("tc [app]").alias("type-check").description("TypeScript type-check (runs bun run type-check in all packages)");
135
- addCommonOptions(tcCmd);
136
- tcCmd.action(async (app, commanderOptions) => {
137
- const commonOptions = extractCommonOptions(commanderOptions);
138
- const options = { ...commonOptions, app };
139
- try {
140
- const { main } = await import("./commands/type-check.js");
141
- process.exit(await main(options));
142
- } catch (error) {
143
- if (error.code === "invalid-argument" || error.name === "DoNotDevError") {
144
- process.exit(error.context?.exitCode || 1);
145
- }
146
- throw error;
147
- }
148
- });
149
- var cacheoutCmd = program.command("cacheout [app]").alias("co").description("Clear build caches").option("--app <app>", "App name to clear cache for");
150
- addCommonOptions(cacheoutCmd);
151
- cacheoutCmd.action(async (app, commanderOptions) => {
152
- const commonOptions = extractCommonOptions(commanderOptions);
153
- const options = { ...commonOptions, ...commanderOptions };
154
- if (app) {
155
- options.app = app;
156
- }
157
- const { main } = await import("./commands/cacheout.js");
158
- process.exitCode = await main(options);
159
- });
160
- var bumpCmd = program.command("bump").description("Update framework packages and peer dependencies to latest compatible versions");
161
- addCommonOptions(bumpCmd);
162
- bumpCmd.action(async (commanderOptions) => {
163
- const commonOptions = extractCommonOptions(commanderOptions);
164
- const options = { ...commonOptions, ...commanderOptions };
165
- try {
166
- const { main } = await import("./commands/bump.js");
167
- process.exitCode = await main(options);
168
- } catch (error) {
169
- if (error.code === "invalid-argument" || error.name === "DoNotDevError") {
170
- process.exit(error.context?.exitCode || 1);
171
- }
172
- throw error;
173
- }
174
- });
175
- 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");
176
- addCommonOptions(stagingCmd);
177
- stagingCmd.action(async (app, commanderOptions) => {
178
- const commonOptions = extractCommonOptions(commanderOptions);
179
- const options = { ...commonOptions, ...commanderOptions, app, staging: true };
180
- const { main } = await import("./commands/deploy.js");
181
- await main(options);
182
- });
183
- 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)");
184
- addCommonOptions(deployCmd);
185
- deployCmd.action(async (app, commanderOptions) => {
186
- const commonOptions = extractCommonOptions(commanderOptions);
187
- const options = { ...commonOptions, ...commanderOptions, app };
188
- const { main } = await import("./commands/deploy.js");
189
- await main(options);
190
- });
191
- 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");
192
- addCommonOptions(syncSecretsCmd);
193
- syncSecretsCmd.action(async (commanderOptions) => {
194
- const commonOptions = extractCommonOptions(commanderOptions);
195
- const options = { ...commonOptions, ...commanderOptions };
196
- if (options.project) {
197
- options.projectId = options.project;
198
- }
199
- const { main } = await import("./commands/sync-secrets.js");
200
- process.exitCode = await main(options);
201
- });
202
- 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)");
203
- addCommonOptions(makeAdminCmd);
204
- makeAdminCmd.action(async (userId, commanderOptions) => {
205
- const args2 = [];
206
- if (userId) args2.push(userId);
207
- if (commanderOptions.project) args2.push(`--project=${commanderOptions.project}`);
208
- if (commanderOptions.projectId) args2.push(`--project-id=${commanderOptions.projectId}`);
209
- if (commanderOptions.super) args2.push("--super");
210
- const { main } = await import("./commands/make-admin.js");
211
- await main(args2);
212
- });
213
- 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");
214
- addCommonOptions(setupCmd);
215
- setupCmd.action(async (provider, commanderOptions) => {
216
- const commonOptions = extractCommonOptions(commanderOptions);
217
- const options = { ...commonOptions, provider, app: commanderOptions.app, skipDoctor: commanderOptions.skipDoctor };
218
- const { main } = await import("./commands/setup.js");
219
- process.exitCode = await main(options);
220
- });
221
- 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)");
222
- addCommonOptions(doctorCmd);
223
- doctorCmd.action(async (commanderOptions) => {
224
- const commonOptions = extractCommonOptions(commanderOptions);
225
- const options = { ...commonOptions, app: commanderOptions.app, check: commanderOptions.check };
226
- const { main } = await import("./commands/doctor.js");
227
- process.exit(await main(options));
228
- });
229
785
  async function runAppCommand(commandPath, app) {
230
786
  const savedArgv = process.argv;
231
787
  process.argv = app ? [savedArgv[0], savedArgv[1], app] : [savedArgv[0], savedArgv[1]];
@@ -236,32 +792,207 @@ async function runAppCommand(commandPath, app) {
236
792
  process.argv = savedArgv;
237
793
  }
238
794
  }
239
- program.command("dev [app]").description("Start development server").action((app) => runAppCommand("./commands/dev.js", app));
240
- program.command("emu [app]").description("Start dev with local backend").action((app) => runAppCommand("./commands/emu.js", app));
241
- program.command("build [app]").description("Build for production").action((app) => runAppCommand("./commands/build.js", app));
242
- program.command("preview [app]").description("Preview production build").action((app) => runAppCommand("./commands/preview.js", app));
795
+ function baseName2(name) {
796
+ return name.split(" ")[0] ?? name;
797
+ }
798
+ var ACTION_OVERRIDES = {
799
+ "create-app": (cmd) => {
800
+ cmd.option("--project <id>", "Firebase project ID (default: app name)");
801
+ cmd.option("--region <region>", "Firebase region (default: europe-west1)");
802
+ cmd.action(async (name, options) => {
803
+ const { main } = await import("./commands/create-app.js");
804
+ const appName = name || options.name;
805
+ if (appName) {
806
+ await main({
807
+ name: appName,
808
+ builder: options.builder,
809
+ host: options.host,
810
+ functions: options.functions,
811
+ backend: options.backend,
812
+ firebaseProjectId: options.project,
813
+ firebaseRegion: options.region
814
+ });
815
+ } else {
816
+ await main();
817
+ }
818
+ });
819
+ },
820
+ "format": (cmd) => {
821
+ cmd.action(async (commanderOptions) => {
822
+ const commonOptions = extractCommonOptions(commanderOptions);
823
+ const options = { ...commonOptions, ...commanderOptions };
824
+ try {
825
+ const { main } = await import("./commands/format.js");
826
+ process.exitCode = await main(options);
827
+ } catch (error) {
828
+ if (error.code === "invalid-argument" || error.name === "DoNotDevError") {
829
+ process.exit(error.context?.exitCode || 1);
830
+ }
831
+ throw error;
832
+ }
833
+ });
834
+ },
835
+ "type-check": (cmd) => {
836
+ cmd.action(async (app, commanderOptions) => {
837
+ const commonOptions = extractCommonOptions(commanderOptions);
838
+ const options = { ...commonOptions, package: app };
839
+ try {
840
+ const { main } = await import("./commands/type-check.js");
841
+ process.exit(await main(options));
842
+ } catch (error) {
843
+ if (error.code === "invalid-argument" || error.name === "DoNotDevError") {
844
+ process.exit(error.context?.exitCode || 1);
845
+ }
846
+ throw error;
847
+ }
848
+ });
849
+ },
850
+ "cacheout": (cmd) => {
851
+ cmd.action(async (app, commanderOptions) => {
852
+ const commonOptions = extractCommonOptions(commanderOptions);
853
+ const options = { ...commonOptions, ...commanderOptions };
854
+ if (app) options.app = app;
855
+ const { main } = await import("./commands/cacheout.js");
856
+ process.exitCode = await main(options);
857
+ });
858
+ },
859
+ "bump": (cmd) => {
860
+ cmd.action(async (commanderOptions) => {
861
+ const commonOptions = extractCommonOptions(commanderOptions);
862
+ const options = { ...commonOptions, ...commanderOptions };
863
+ try {
864
+ const { main } = await import("./commands/bump.js");
865
+ process.exitCode = await main(options);
866
+ } catch (error) {
867
+ if (error.code === "invalid-argument" || error.name === "DoNotDevError") {
868
+ process.exit(error.context?.exitCode || 1);
869
+ }
870
+ throw error;
871
+ }
872
+ });
873
+ },
874
+ "staging": (cmd) => {
875
+ cmd.action(async (app, commanderOptions) => {
876
+ const commonOptions = extractCommonOptions(commanderOptions);
877
+ const options = { ...commonOptions, ...commanderOptions, app, staging: true };
878
+ const { main } = await import("./commands/deploy.js");
879
+ await main(options);
880
+ });
881
+ },
882
+ "deploy": (cmd) => {
883
+ cmd.action(async (app, commanderOptions) => {
884
+ const commonOptions = extractCommonOptions(commanderOptions);
885
+ const options = { ...commonOptions, ...commanderOptions, app };
886
+ const { main } = await import("./commands/deploy.js");
887
+ await main(options);
888
+ });
889
+ },
890
+ "sync-secrets": (cmd) => {
891
+ cmd.action(async (commanderOptions) => {
892
+ const commonOptions = extractCommonOptions(commanderOptions);
893
+ const options = { ...commonOptions, ...commanderOptions };
894
+ if (options.project) options.projectId = options.project;
895
+ const { main } = await import("./commands/sync-secrets.js");
896
+ process.exitCode = await main(options);
897
+ });
898
+ },
899
+ "make-admin": (cmd) => {
900
+ cmd.action(async (userId, commanderOptions) => {
901
+ const args2 = [];
902
+ if (userId) args2.push(userId);
903
+ if (commanderOptions.project) args2.push(`--project=${commanderOptions.project}`);
904
+ if (commanderOptions.projectId) args2.push(`--project-id=${commanderOptions.projectId}`);
905
+ if (commanderOptions.super) args2.push("--super");
906
+ const { main } = await import("./commands/make-admin.js");
907
+ await main(args2);
908
+ });
909
+ },
910
+ "coach": (cmd) => {
911
+ cmd.action(async (commanderOptions) => {
912
+ const commonOptions = extractCommonOptions(commanderOptions);
913
+ const { main } = await import("./commands/coach.js");
914
+ process.exitCode = await main(commonOptions);
915
+ });
916
+ },
917
+ "setup": (cmd) => {
918
+ cmd.action(async (provider, commanderOptions) => {
919
+ const commonOptions = extractCommonOptions(commanderOptions);
920
+ const options = { ...commonOptions, provider };
921
+ const { main } = await import("./commands/setup.js");
922
+ process.exitCode = await main(options);
923
+ });
924
+ },
925
+ "doctor": (cmd) => {
926
+ cmd.action(async (commanderOptions) => {
927
+ const commonOptions = extractCommonOptions(commanderOptions);
928
+ const options = { ...commonOptions, check: commanderOptions.check };
929
+ const { main } = await import("./commands/doctor.js");
930
+ process.exit(await main(options));
931
+ });
932
+ },
933
+ "agent:setup": (cmd) => {
934
+ cmd.removeCommand?.();
935
+ return "skip";
936
+ },
937
+ "wai": (cmd) => {
938
+ cmd.action(async () => {
939
+ const { main } = await import("./commands/wai.js");
940
+ process.exit(await main());
941
+ });
942
+ }
943
+ };
944
+ var publicCommands = getPublicCommands();
945
+ for (const def of publicCommands) {
946
+ const cmdName = baseName2(def.name);
947
+ const wrapperFile = def.wrapperFile ?? cmdName;
948
+ const commandPath = `./commands/${wrapperFile}.js`;
949
+ const cmd = program.command(def.name);
950
+ if (def.alias) {
951
+ const aliases = Array.isArray(def.alias) ? def.alias : [def.alias];
952
+ for (const a of aliases) cmd.alias(a);
953
+ }
954
+ cmd.description(def.description);
955
+ if (def.options) {
956
+ for (const opt of def.options) {
957
+ cmd.option(opt.flags, opt.description);
958
+ }
959
+ }
960
+ addCommonOptions(cmd);
961
+ const override = ACTION_OVERRIDES[def.name] ?? ACTION_OVERRIDES[cmdName];
962
+ if (override) {
963
+ const result = override(cmd);
964
+ if (result === "skip") continue;
965
+ } else if (def.actionPattern === "app") {
966
+ cmd.action((app) => runAppCommand(commandPath, app));
967
+ } else {
968
+ cmd.action(async (...commanderArgs) => {
969
+ const commanderOptions = commanderArgs[commanderArgs.length - 2];
970
+ const positionalArgs = commanderArgs.slice(0, -2);
971
+ const commonOptions = extractCommonOptions(commanderOptions);
972
+ const options = { ...commonOptions, ...commanderOptions };
973
+ const { main } = await import(commandPath);
974
+ await main(options, ...positionalArgs);
975
+ });
976
+ }
977
+ }
243
978
  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) => {
244
979
  const options = extractCommonOptions(commanderOptions);
245
980
  const { main } = await import("./commands/agent-setup.js");
246
981
  await main(options);
247
982
  });
248
- 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 () => {
249
- const { main } = await import("./commands/wai.js");
250
- process.exit(await main());
251
- });
252
- function preprocessArgs(args2) {
253
- if (args2.length === 0) return args2;
254
- const firstArg = args2[0];
255
- const appCommands = ["dev", "build", "preview", "emu", "deploy", "staging"];
983
+ function preprocessArgs(rawArgs) {
984
+ if (rawArgs.length === 0) return rawArgs;
985
+ const firstArg = rawArgs[0];
986
+ const appCommands = getAppCommandNames();
256
987
  if (firstArg && firstArg.includes(":")) {
257
988
  const colonIndex = firstArg.indexOf(":");
258
989
  const command = firstArg.substring(0, colonIndex);
259
990
  const app = firstArg.substring(colonIndex + 1);
260
991
  if (appCommands.includes(command) && app) {
261
- return [command, app, ...args2.slice(1)];
992
+ return [command, app, ...rawArgs.slice(1)];
262
993
  }
263
994
  }
264
- return args2;
995
+ return rawArgs;
265
996
  }
266
997
  program.on("command:*", () => {
267
998
  console.error(`Unknown command: ${program.args.join(" ")}`);