@donotdev/cli 0.0.14 → 0.0.16

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 (184) hide show
  1. package/dependencies-matrix.json +372 -88
  2. package/dist/bin/commands/agent-setup.js +7 -1
  3. package/dist/bin/commands/build.js +141 -44
  4. package/dist/bin/commands/bump.js +81 -41
  5. package/dist/bin/commands/cacheout.js +37 -9
  6. package/dist/bin/commands/create-app.js +276 -121
  7. package/dist/bin/commands/create-project.js +506 -217
  8. package/dist/bin/commands/deploy.js +1785 -694
  9. package/dist/bin/commands/dev.js +177 -43
  10. package/dist/bin/commands/doctor.d.ts +6 -0
  11. package/dist/bin/commands/doctor.d.ts.map +1 -0
  12. package/dist/bin/commands/{lint.js → doctor.js} +1215 -156
  13. package/dist/bin/commands/doctor.js.map +1 -0
  14. package/dist/bin/commands/emu.js +451 -104
  15. package/dist/bin/commands/format.js +37 -9
  16. package/dist/bin/commands/make-admin.js +77499 -11
  17. package/dist/bin/commands/preview.js +181 -43
  18. package/dist/bin/commands/setup.d.ts +6 -0
  19. package/dist/bin/commands/setup.d.ts.map +1 -0
  20. package/dist/bin/commands/setup.js +11733 -0
  21. package/dist/bin/commands/setup.js.map +1 -0
  22. package/dist/bin/commands/supabase-setup.d.ts +6 -0
  23. package/dist/bin/commands/supabase-setup.d.ts.map +1 -0
  24. package/dist/bin/commands/supabase-setup.js +7 -0
  25. package/dist/bin/commands/supabase-setup.js.map +1 -0
  26. package/dist/bin/commands/sync-secrets.js +211 -34
  27. package/dist/bin/commands/type-check.d.ts +14 -0
  28. package/dist/bin/commands/type-check.d.ts.map +1 -0
  29. package/dist/bin/commands/type-check.js +2049 -0
  30. package/dist/bin/commands/type-check.js.map +1 -0
  31. package/dist/bin/commands/wai.js +3 -1
  32. package/dist/bin/dndev.js +73 -52
  33. package/dist/bin/donotdev.js +54 -45
  34. package/dist/index.js +4212 -3050
  35. package/package.json +3 -3
  36. package/templates/app-demo/src/App.tsx.example +1 -0
  37. package/templates/app-demo/src/pages/FullPage.tsx.example +2 -2
  38. package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +2 -2
  39. package/templates/app-demo/src/themes.css.example +5 -12
  40. package/templates/app-expo/.env.example +44 -0
  41. package/templates/app-expo/.expo/README.md.example +5 -0
  42. package/templates/app-expo/.gitignore.example +36 -0
  43. package/templates/app-expo/README.md.example +58 -0
  44. package/templates/app-expo/app/.gitkeep +2 -0
  45. package/templates/app-expo/app/_layout.tsx.example +41 -0
  46. package/templates/app-expo/app/form.tsx.example +52 -0
  47. package/templates/app-expo/app/index.tsx.example +89 -0
  48. package/templates/app-expo/app/list.tsx.example +32 -0
  49. package/templates/app-expo/app/profile.tsx.example +76 -0
  50. package/templates/app-expo/app/signin.tsx.example +53 -0
  51. package/templates/app-expo/app.json.example +39 -0
  52. package/templates/app-expo/assets/adaptive-icon.png +0 -0
  53. package/templates/app-expo/assets/favicon.png +0 -0
  54. package/templates/app-expo/assets/icon.png +0 -0
  55. package/templates/app-expo/assets/splash.png +0 -0
  56. package/templates/app-expo/babel.config.js.example +10 -0
  57. package/templates/app-expo/eas.json.example +20 -0
  58. package/templates/app-expo/expo-env.d.ts.example +4 -0
  59. package/templates/app-expo/metro.config.js.example +20 -0
  60. package/templates/app-expo/service-account-key.json.example +12 -0
  61. package/templates/app-expo/src/config/app.ts.example +46 -0
  62. package/templates/app-expo/src/config/providers.ts.example +7 -0
  63. package/templates/app-expo/tsconfig.json.example +19 -0
  64. package/templates/app-next/.env.example +4 -33
  65. package/templates/app-next/src/app/ClientLayout.tsx.example +2 -0
  66. package/templates/app-next/src/app/layout.tsx.example +7 -6
  67. package/templates/app-next/src/config/providers.ts.example +7 -0
  68. package/templates/app-next/src/globals.css.example +2 -11
  69. package/templates/app-next/src/pages/HomePage.tsx.example +1 -1
  70. package/templates/app-next/src/themes.css.example +10 -13
  71. package/templates/app-vite/.env.example +3 -32
  72. package/templates/app-vite/index.html.example +2 -24
  73. package/templates/app-vite/src/App.tsx.example +2 -0
  74. package/templates/app-vite/src/config/providers.ts.example +7 -0
  75. package/templates/app-vite/src/globals.css.example +2 -12
  76. package/templates/app-vite/src/pages/FormPageExample.tsx.example +1 -2
  77. package/templates/app-vite/src/pages/HomePage.tsx.example +2 -2
  78. package/templates/app-vite/src/themes.css.example +109 -79
  79. package/templates/app-vite/vercel.json.example +11 -0
  80. package/templates/functions-firebase/README.md.example +1 -1
  81. package/templates/functions-firebase/build.mjs.example +2 -72
  82. package/templates/functions-firebase/functions-firebase/.env.example.example +24 -26
  83. package/templates/functions-firebase/functions-firebase/README.md.example +1 -1
  84. package/templates/functions-firebase/functions-firebase/build.mjs.example +2 -72
  85. package/templates/functions-firebase/functions-firebase/tsconfig.json.example +1 -1
  86. package/templates/functions-firebase/functions.config.js.example +1 -1
  87. package/templates/functions-supabase/supabase/config.toml.example +59 -0
  88. package/templates/functions-supabase/supabase/functions/.env.example +13 -0
  89. package/templates/functions-supabase/supabase/functions/cancel-subscription/index.ts.example +7 -0
  90. package/templates/functions-supabase/supabase/functions/change-plan/index.ts.example +11 -0
  91. package/templates/functions-supabase/supabase/functions/create-checkout-session/index.ts.example +11 -0
  92. package/templates/functions-supabase/supabase/functions/create-customer-portal/index.ts.example +7 -0
  93. package/templates/functions-supabase/supabase/functions/crud/index.ts.example +16 -0
  94. package/templates/functions-supabase/supabase/functions/delete-account/index.ts.example +7 -0
  95. package/templates/functions-supabase/supabase/functions/deno.json.example +8 -0
  96. package/templates/functions-supabase/supabase/functions/get-custom-claims/index.ts.example +7 -0
  97. package/templates/functions-supabase/supabase/functions/get-user-auth-status/index.ts.example +7 -0
  98. package/templates/functions-supabase/supabase/functions/refresh-subscription-status/index.ts.example +7 -0
  99. package/templates/functions-supabase/supabase/functions/remove-custom-claims/index.ts.example +7 -0
  100. package/templates/functions-supabase/supabase/functions/set-custom-claims/index.ts.example +7 -0
  101. package/templates/functions-supabase/supabase/migrations/20250101000000_idempotency.sql +24 -0
  102. package/templates/functions-supabase/supabase/migrations/20250101000001_rate_limits.sql +22 -0
  103. package/templates/functions-supabase/supabase/migrations/20250101000002_cleanup_jobs.sql +28 -0
  104. package/templates/functions-supabase/supabase/migrations/20250101000003_operation_metrics.sql +28 -0
  105. package/templates/functions-vercel/functions-vercel/tsconfig.json.example +1 -1
  106. package/templates/functions-vercel/functions-vercel/vercel.json.example +1 -1
  107. package/templates/functions-vercel/vercel.json.example +1 -1
  108. package/templates/github/github/workflows/firebase-deploy.yml.example +1 -1
  109. package/templates/github/workflows/firebase-deploy.yml.example +1 -1
  110. package/templates/overlay-firebase/env.fragment.example +34 -0
  111. package/templates/overlay-firebase/env.fragment.expo.example +34 -0
  112. package/templates/overlay-firebase/env.fragment.nextjs.example +34 -0
  113. package/templates/overlay-firebase/src/config/providers.expo.ts.example +49 -0
  114. package/templates/overlay-firebase/src/config/providers.ts.example +23 -0
  115. package/templates/overlay-supabase/env.fragment.example +12 -0
  116. package/templates/overlay-supabase/env.fragment.expo.example +12 -0
  117. package/templates/overlay-supabase/env.fragment.nextjs.example +12 -0
  118. package/templates/overlay-supabase/src/config/providers.expo.ts.example +35 -0
  119. package/templates/overlay-supabase/src/config/providers.ts.example +33 -0
  120. package/templates/overlay-supabase/vercel.headers.example +23 -0
  121. package/templates/overlay-supabase/vercel.json.example +22 -0
  122. package/templates/overlay-vercel/env.fragment.example +34 -0
  123. package/templates/overlay-vercel/env.fragment.nextjs.example +34 -0
  124. package/templates/overlay-vercel/src/config/providers.ts.example +24 -0
  125. package/templates/root-consumer/.claude/agents/architect.md.example +2 -310
  126. package/templates/root-consumer/.claude/agents/builder.md.example +2 -326
  127. package/templates/root-consumer/.claude/agents/coder.md.example +2 -83
  128. package/templates/root-consumer/.claude/agents/extractor.md.example +2 -231
  129. package/templates/root-consumer/.claude/agents/polisher.md.example +2 -132
  130. package/templates/root-consumer/.claude/agents/prompt-engineer.md.example +2 -81
  131. package/templates/root-consumer/.claude/commands/grill.md.example +30 -0
  132. package/templates/root-consumer/.claude/commands/techdebt.md.example +28 -0
  133. package/templates/root-consumer/.clinerules.example +1 -0
  134. package/templates/root-consumer/.cursor/rules/no-docs.mdc.example +15 -0
  135. package/templates/root-consumer/.cursorrules.example +1 -0
  136. package/templates/root-consumer/.github/copilot-instructions.md.example +1 -0
  137. package/templates/root-consumer/.windsurfrules.example +1 -0
  138. package/templates/root-consumer/AI.md.example +44 -123
  139. package/templates/root-consumer/CLAUDE.md.example +1 -134
  140. package/templates/root-consumer/CONVENTIONS.md.example +1 -0
  141. package/templates/root-consumer/GEMINI.md.example +1 -0
  142. package/templates/root-consumer/firebase.json.example +1 -1
  143. package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +22 -2
  144. package/templates/root-consumer/guides/dndev/COMPONENTS_ADV.md.example +0 -18
  145. package/templates/root-consumer/guides/dndev/COMPONENTS_UI.md.example +1 -1
  146. package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +101 -32
  147. package/templates/root-consumer/guides/dndev/INDEX.md.example +4 -2
  148. package/templates/root-consumer/guides/dndev/SETUP_APP_CONFIG.md.example +3 -3
  149. package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +241 -12
  150. package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +13 -7
  151. package/templates/root-consumer/guides/dndev/SETUP_OAUTH_PROVIDERS.md.example +60 -0
  152. package/templates/root-consumer/guides/dndev/SETUP_SOC2.md.example +234 -0
  153. package/templates/root-consumer/guides/dndev/SETUP_STRIPE.md.example +62 -0
  154. package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +124 -0
  155. package/templates/root-consumer/guides/dndev/SETUP_THEMES.md.example +6 -2
  156. package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +176 -0
  157. package/templates/root-consumer/guides/dndev/USE_ROUTING.md.example +5 -9
  158. package/templates/root-consumer/guides/dndev/essences_reference.css.example +174 -0
  159. package/templates/root-consumer/guides/wai-way/WAI_WAY_CLI.md.example +7 -8
  160. package/templates/root-consumer/guides/wai-way/agents/builder.md.example +10 -0
  161. package/templates/root-consumer/guides/wai-way/agents/extractor.md.example +25 -5
  162. package/templates/root-consumer/guides/wai-way/agents/polisher.md.example +13 -2
  163. package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +2 -2
  164. package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +55 -15
  165. package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +15 -4
  166. package/templates/root-consumer/guides/wai-way/spec_template.md.example +7 -6
  167. package/dist/bin/commands/lint.d.ts +0 -11
  168. package/dist/bin/commands/lint.d.ts.map +0 -1
  169. package/dist/bin/commands/lint.js.map +0 -1
  170. package/dist/bin/commands/staging.d.ts +0 -11
  171. package/dist/bin/commands/staging.d.ts.map +0 -1
  172. package/dist/bin/commands/staging.js +0 -12
  173. package/dist/bin/commands/staging.js.map +0 -1
  174. package/templates/app-payload/.env.example +0 -28
  175. package/templates/app-payload/README.md.example +0 -233
  176. package/templates/app-payload/collections/Company.ts.example +0 -125
  177. package/templates/app-payload/collections/Hero.ts.example +0 -62
  178. package/templates/app-payload/collections/Media.ts.example +0 -41
  179. package/templates/app-payload/collections/Products.ts.example +0 -115
  180. package/templates/app-payload/collections/Services.ts.example +0 -104
  181. package/templates/app-payload/collections/Testimonials.ts.example +0 -92
  182. package/templates/app-payload/collections/Users.ts.example +0 -35
  183. package/templates/app-payload/src/server.ts.example +0 -79
  184. package/templates/app-payload/tsconfig.json.example +0 -24
@@ -596,7 +596,13 @@ async function main(options = {}) {
596
596
  log.error(`Failed to configure Gemini: ${e2.message}`);
597
597
  }
598
598
  }
599
- const claudeConfigPath = isWindows ? join(process.env.APPDATA || "", "Claude", "claude_desktop_config.json") : isMac ? join(homeDir, "Library", "Application Support", "Claude", "claude_desktop_config.json") : null;
599
+ const claudeConfigPath = isWindows ? join(process.env.APPDATA || "", "Claude", "claude_desktop_config.json") : isMac ? join(
600
+ homeDir,
601
+ "Library",
602
+ "Application Support",
603
+ "Claude",
604
+ "claude_desktop_config.json"
605
+ ) : null;
600
606
  if (claudeConfigPath) {
601
607
  if (options.dryRun) {
602
608
  Me(`[DRY RUN] Would update ${claudeConfigPath}`, "Claude Desktop");
@@ -7603,11 +7603,39 @@ var init_PathResolver = __esm({
7603
7603
  });
7604
7604
 
7605
7605
  // packages/tooling/src/utils/errors.ts
7606
- var DoNotDevError;
7606
+ var DO_NOT_DEV_ERROR_CODES, DoNotDevError;
7607
7607
  var init_errors = __esm({
7608
7608
  "packages/tooling/src/utils/errors.ts"() {
7609
7609
  "use strict";
7610
7610
  init_utils();
7611
+ DO_NOT_DEV_ERROR_CODES = {
7612
+ CONFIGURATION_ERROR: "configuration-error",
7613
+ CONFIG_NOT_FOUND: "config-not-found",
7614
+ CONFIG_INVALID: "config-invalid",
7615
+ PATH_RESOLUTION_ERROR: "path-resolution-error",
7616
+ FILE_OPERATION_ERROR: "file-operation-error",
7617
+ FILE_NOT_FOUND: "file-not-found",
7618
+ PERMISSION_DENIED: "permission-denied",
7619
+ GENERATION_ERROR: "generation-error",
7620
+ TEMPLATE_ERROR: "template-error",
7621
+ TEMPLATE_NOT_FOUND: "template-not-found",
7622
+ CLI_EXECUTION_ERROR: "cli-execution-error",
7623
+ COMMAND_NOT_FOUND: "command-not-found",
7624
+ COMMAND_FAILED: "command-failed",
7625
+ VALIDATION_ERROR: "validation-error",
7626
+ SCHEMA_ERROR: "schema-error",
7627
+ DEPENDENCY_ERROR: "dependency-error",
7628
+ DEPENDENCY_NOT_FOUND: "dependency-not-found",
7629
+ DEPENDENCY_VERSION_ERROR: "dependency-version-error",
7630
+ INVALID_ARGUMENT: "invalid-argument",
7631
+ MISSING_ARGUMENT: "missing-argument",
7632
+ MISSING_PROJECT_ID: "missing-project-id",
7633
+ FIREBASE_CLI_ERROR: "firebase-cli-error",
7634
+ DEPLOYMENT_FAILED: "deployment-failed",
7635
+ OPERATION_CANCELLED: "operation-cancelled",
7636
+ TIMEOUT_ERROR: "timeout-error",
7637
+ UNKNOWN_ERROR: "unknown-error"
7638
+ };
7611
7639
  DoNotDevError = class _DoNotDevError extends Error {
7612
7640
  /** The error code categorizing this error */
7613
7641
  code;
@@ -7627,7 +7655,7 @@ var init_errors = __esm({
7627
7655
  * @param {Record<string, any>} [options.context] - Additional context data
7628
7656
  * @param {boolean} [options.displayable=true] - Whether this error should be displayed to the user
7629
7657
  */
7630
- constructor(message, code = "unknown-error", options) {
7658
+ constructor(message, code = DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR, options) {
7631
7659
  super(message);
7632
7660
  this.name = "DoNotDevError";
7633
7661
  this.code = code;
@@ -7658,7 +7686,7 @@ var init_errors = __esm({
7658
7686
  * @param {boolean} [options.displayable=true] - Whether this error should be displayed to the user
7659
7687
  * @returns {DoNotDevError} New DoNotDev error wrapping the original
7660
7688
  */
7661
- static from(error2, context, code = "unknown-error", options) {
7689
+ static from(error2, context, code = DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR, options) {
7662
7690
  if (!(error2 instanceof Error)) {
7663
7691
  return new _DoNotDevError(
7664
7692
  `Unknown error: ${String(error2)}`,
@@ -7695,21 +7723,21 @@ var init_errors = __esm({
7695
7723
  }
7696
7724
  const message = error2.message.toLowerCase();
7697
7725
  if (error2.name === "ValidationError" || message.includes("validation")) {
7698
- return "validation-error";
7726
+ return DO_NOT_DEV_ERROR_CODES.VALIDATION_ERROR;
7699
7727
  }
7700
7728
  if (message.includes("not found") || message.includes("no such file")) {
7701
- return "file-not-found";
7729
+ return DO_NOT_DEV_ERROR_CODES.FILE_NOT_FOUND;
7702
7730
  }
7703
7731
  if (message.includes("permission") || message.includes("access denied")) {
7704
- return "permission-denied";
7732
+ return DO_NOT_DEV_ERROR_CODES.PERMISSION_DENIED;
7705
7733
  }
7706
7734
  if (message.includes("timeout") || message.includes("timed out")) {
7707
- return "timeout-error";
7735
+ return DO_NOT_DEV_ERROR_CODES.TIMEOUT_ERROR;
7708
7736
  }
7709
7737
  if (message.includes("dependency") || message.includes("module not found")) {
7710
- return "dependency-error";
7738
+ return DO_NOT_DEV_ERROR_CODES.DEPENDENCY_ERROR;
7711
7739
  }
7712
- return "unknown-error";
7740
+ return DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR;
7713
7741
  }
7714
7742
  };
7715
7743
  }
@@ -7751,6 +7779,52 @@ var init_pathResolver = __esm({
7751
7779
  }
7752
7780
  });
7753
7781
 
7782
+ // packages/tooling/src/utils/typed-file-operations.ts
7783
+ function readFirebaseJson(filePath) {
7784
+ if (!pathExists(filePath)) {
7785
+ throw new DoNotDevError(
7786
+ `firebase.json not found: ${filePath}`,
7787
+ DO_NOT_DEV_ERROR_CODES.FILE_NOT_FOUND,
7788
+ { context: { filePath } }
7789
+ );
7790
+ }
7791
+ const content = readSync(filePath, { format: "json" });
7792
+ if (!content || typeof content !== "object") {
7793
+ throw new DoNotDevError(
7794
+ `Invalid firebase.json: ${filePath}`,
7795
+ DO_NOT_DEV_ERROR_CODES.CONFIG_INVALID,
7796
+ { context: { filePath } }
7797
+ );
7798
+ }
7799
+ return content;
7800
+ }
7801
+ function readPackageJson(filePath) {
7802
+ if (!pathExists(filePath)) {
7803
+ throw new DoNotDevError(
7804
+ `package.json not found: ${filePath}`,
7805
+ DO_NOT_DEV_ERROR_CODES.FILE_NOT_FOUND,
7806
+ { context: { filePath } }
7807
+ );
7808
+ }
7809
+ const content = readSync(filePath, { format: "json" });
7810
+ if (!content || typeof content !== "object" || !("name" in content)) {
7811
+ throw new DoNotDevError(
7812
+ `Invalid package.json: ${filePath}`,
7813
+ DO_NOT_DEV_ERROR_CODES.CONFIG_INVALID,
7814
+ { context: { filePath } }
7815
+ );
7816
+ }
7817
+ return content;
7818
+ }
7819
+ var init_typed_file_operations = __esm({
7820
+ "packages/tooling/src/utils/typed-file-operations.ts"() {
7821
+ "use strict";
7822
+ init_utils();
7823
+ init_pathResolver();
7824
+ init_errors();
7825
+ }
7826
+ });
7827
+
7754
7828
  // packages/tooling/src/bundler/utils.ts
7755
7829
  import { Buffer as Buffer2 } from "node:buffer";
7756
7830
  import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
@@ -7778,26 +7852,7 @@ var init_utils = __esm({
7778
7852
  }
7779
7853
  });
7780
7854
 
7781
- // packages/cli/src/bin/commands/build.ts
7782
- init_utils();
7783
-
7784
- // packages/tooling/src/index.ts
7785
- init_utils();
7786
-
7787
- // packages/tooling/src/cli/index.ts
7788
- init_utils();
7789
-
7790
- // packages/tooling/src/apps/build.ts
7791
- init_utils();
7792
- import { spawnSync, execSync } from "node:child_process";
7793
-
7794
- // packages/tooling/src/utils/app-selector.ts
7795
- init_utils();
7796
- init_dist2();
7797
-
7798
7855
  // packages/tooling/src/utils/app-detection.ts
7799
- init_utils();
7800
- init_pathResolver();
7801
7856
  function detectApps(projectRoot) {
7802
7857
  const apps = [];
7803
7858
  const appsDir = joinPath(projectRoot, "apps");
@@ -7818,9 +7873,7 @@ function detectApps(projectRoot) {
7818
7873
  const packageJsonPath = joinPath(projectRoot, "package.json");
7819
7874
  if (pathExists(packageJsonPath)) {
7820
7875
  try {
7821
- const packageJson = readSync(packageJsonPath, {
7822
- format: "json"
7823
- });
7876
+ const packageJson = readPackageJson(packageJsonPath);
7824
7877
  if (packageJson && (packageJson.dependencies?.vite || packageJson.devDependencies?.vite || packageJson.dependencies?.next || packageJson.devDependencies?.next)) {
7825
7878
  const pathParts = projectRoot.split(/[/\\]/);
7826
7879
  const appName = pathParts[pathParts.length - 1] || "app";
@@ -7840,10 +7893,10 @@ function analyzeApp(appPath, appName) {
7840
7893
  if (!pathExists(packageJsonPath)) {
7841
7894
  return null;
7842
7895
  }
7843
- let packageJson;
7896
+ let packageJson = null;
7844
7897
  try {
7845
- packageJson = readSync(packageJsonPath, { format: "json" });
7846
- if (!packageJson) {
7898
+ packageJson = readPackageJson(packageJsonPath);
7899
+ if (!packageJson.name) {
7847
7900
  return null;
7848
7901
  }
7849
7902
  } catch {
@@ -7859,12 +7912,21 @@ function analyzeApp(appPath, appName) {
7859
7912
  const functionsStat = statSync2(functionsPath);
7860
7913
  const hasFunctions = pathExists(functionsPath) && (functionsStat?.isDirectory() ?? false);
7861
7914
  let platform;
7862
- if (hasFunctions) {
7863
- const firebaseJsonPath = joinPath(functionsPath, "firebase.json");
7915
+ const firebaseJsonInFunctions = hasFunctions && pathExists(joinPath(functionsPath, "firebase.json"));
7916
+ const firebaseJsonInApp = pathExists(joinPath(appPath, "firebase.json"));
7917
+ if (firebaseJsonInFunctions || firebaseJsonInApp) {
7918
+ platform = "firebase";
7919
+ }
7920
+ if (!platform) {
7921
+ const supabaseConfigPath = joinPath(appPath, "supabase", "config.toml");
7922
+ const hasSupabaseDep = !!(packageJson.dependencies?.["@donotdev/supabase"] || packageJson.dependencies?.["@supabase/supabase-js"]);
7923
+ if (pathExists(supabaseConfigPath) || hasSupabaseDep) {
7924
+ platform = "supabase";
7925
+ }
7926
+ }
7927
+ if (!platform) {
7864
7928
  const vercelJsonPath = joinPath(appPath, "vercel.json");
7865
- if (pathExists(firebaseJsonPath)) {
7866
- platform = "firebase";
7867
- } else if (pathExists(vercelJsonPath)) {
7929
+ if (pathExists(vercelJsonPath)) {
7868
7930
  platform = "vercel";
7869
7931
  }
7870
7932
  }
@@ -7879,9 +7941,16 @@ function analyzeApp(appPath, appName) {
7879
7941
  platform
7880
7942
  };
7881
7943
  }
7944
+ var init_app_detection = __esm({
7945
+ "packages/tooling/src/utils/app-detection.ts"() {
7946
+ "use strict";
7947
+ init_utils();
7948
+ init_pathResolver();
7949
+ init_typed_file_operations();
7950
+ }
7951
+ });
7882
7952
 
7883
7953
  // packages/tooling/src/utils/app-selector.ts
7884
- init_cli_output();
7885
7954
  async function selectApp(projectRoot, appName) {
7886
7955
  const apps = detectApps(projectRoot);
7887
7956
  if (apps.length === 0) {
@@ -7915,10 +7984,17 @@ async function selectApp(projectRoot, appName) {
7915
7984
  }
7916
7985
  return apps.find((a) => a.name === selected) || null;
7917
7986
  }
7987
+ var init_app_selector = __esm({
7988
+ "packages/tooling/src/utils/app-selector.ts"() {
7989
+ "use strict";
7990
+ init_utils();
7991
+ init_dist2();
7992
+ init_app_detection();
7993
+ init_cli_output();
7994
+ }
7995
+ });
7918
7996
 
7919
7997
  // packages/tooling/src/utils/cli-input.ts
7920
- init_utils();
7921
- init_dist2();
7922
7998
  async function askForSelection(message, choices, defaultValue = 0) {
7923
7999
  const options = choices.map((choice) => ({
7924
8000
  value: choice.value,
@@ -7936,11 +8012,32 @@ async function askForSelection(message, choices, defaultValue = 0) {
7936
8012
  }
7937
8013
  return result;
7938
8014
  }
8015
+ var init_cli_input = __esm({
8016
+ "packages/tooling/src/utils/cli-input.ts"() {
8017
+ "use strict";
8018
+ init_utils();
8019
+ init_dist2();
8020
+ }
8021
+ });
8022
+
8023
+ // packages/cli/src/bin/commands/build.ts
8024
+ init_utils();
8025
+
8026
+ // packages/tooling/src/index.ts
8027
+ init_utils();
8028
+
8029
+ // packages/tooling/src/cli/index.ts
8030
+ init_utils();
7939
8031
 
7940
8032
  // packages/tooling/src/apps/build.ts
8033
+ init_utils();
8034
+ init_app_selector();
8035
+ init_cli_input();
7941
8036
  init_cli_output();
7942
8037
  init_errors();
7943
8038
  init_pathResolver();
8039
+ init_typed_file_operations();
8040
+ import { spawnSync, execSync } from "node:child_process";
7944
8041
  function validateFirebaseJson(appDir) {
7945
8042
  const firebaseJsonPath = joinPath(appDir, "firebase.json");
7946
8043
  if (!pathExists(firebaseJsonPath)) {
@@ -7951,8 +8048,8 @@ function validateFirebaseJson(appDir) {
7951
8048
  };
7952
8049
  }
7953
8050
  try {
7954
- const config = readSync(firebaseJsonPath, { format: "json" });
7955
- if (!config) {
8051
+ const config = readFirebaseJson(firebaseJsonPath);
8052
+ if (!config.projectId) {
7956
8053
  return {
7957
8054
  valid: false,
7958
8055
  hasHosting: false,
@@ -7565,11 +7565,39 @@ var init_PathResolver = __esm({
7565
7565
  });
7566
7566
 
7567
7567
  // packages/tooling/src/utils/errors.ts
7568
- var DoNotDevError;
7568
+ var DO_NOT_DEV_ERROR_CODES, DoNotDevError;
7569
7569
  var init_errors = __esm({
7570
7570
  "packages/tooling/src/utils/errors.ts"() {
7571
7571
  "use strict";
7572
7572
  init_utils();
7573
+ DO_NOT_DEV_ERROR_CODES = {
7574
+ CONFIGURATION_ERROR: "configuration-error",
7575
+ CONFIG_NOT_FOUND: "config-not-found",
7576
+ CONFIG_INVALID: "config-invalid",
7577
+ PATH_RESOLUTION_ERROR: "path-resolution-error",
7578
+ FILE_OPERATION_ERROR: "file-operation-error",
7579
+ FILE_NOT_FOUND: "file-not-found",
7580
+ PERMISSION_DENIED: "permission-denied",
7581
+ GENERATION_ERROR: "generation-error",
7582
+ TEMPLATE_ERROR: "template-error",
7583
+ TEMPLATE_NOT_FOUND: "template-not-found",
7584
+ CLI_EXECUTION_ERROR: "cli-execution-error",
7585
+ COMMAND_NOT_FOUND: "command-not-found",
7586
+ COMMAND_FAILED: "command-failed",
7587
+ VALIDATION_ERROR: "validation-error",
7588
+ SCHEMA_ERROR: "schema-error",
7589
+ DEPENDENCY_ERROR: "dependency-error",
7590
+ DEPENDENCY_NOT_FOUND: "dependency-not-found",
7591
+ DEPENDENCY_VERSION_ERROR: "dependency-version-error",
7592
+ INVALID_ARGUMENT: "invalid-argument",
7593
+ MISSING_ARGUMENT: "missing-argument",
7594
+ MISSING_PROJECT_ID: "missing-project-id",
7595
+ FIREBASE_CLI_ERROR: "firebase-cli-error",
7596
+ DEPLOYMENT_FAILED: "deployment-failed",
7597
+ OPERATION_CANCELLED: "operation-cancelled",
7598
+ TIMEOUT_ERROR: "timeout-error",
7599
+ UNKNOWN_ERROR: "unknown-error"
7600
+ };
7573
7601
  DoNotDevError = class _DoNotDevError extends Error {
7574
7602
  /** The error code categorizing this error */
7575
7603
  code;
@@ -7589,7 +7617,7 @@ var init_errors = __esm({
7589
7617
  * @param {Record<string, any>} [options.context] - Additional context data
7590
7618
  * @param {boolean} [options.displayable=true] - Whether this error should be displayed to the user
7591
7619
  */
7592
- constructor(message, code = "unknown-error", options) {
7620
+ constructor(message, code = DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR, options) {
7593
7621
  super(message);
7594
7622
  this.name = "DoNotDevError";
7595
7623
  this.code = code;
@@ -7620,7 +7648,7 @@ var init_errors = __esm({
7620
7648
  * @param {boolean} [options.displayable=true] - Whether this error should be displayed to the user
7621
7649
  * @returns {DoNotDevError} New DoNotDev error wrapping the original
7622
7650
  */
7623
- static from(error2, context, code = "unknown-error", options) {
7651
+ static from(error2, context, code = DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR, options) {
7624
7652
  if (!(error2 instanceof Error)) {
7625
7653
  return new _DoNotDevError(
7626
7654
  `Unknown error: ${String(error2)}`,
@@ -7657,21 +7685,21 @@ var init_errors = __esm({
7657
7685
  }
7658
7686
  const message = error2.message.toLowerCase();
7659
7687
  if (error2.name === "ValidationError" || message.includes("validation")) {
7660
- return "validation-error";
7688
+ return DO_NOT_DEV_ERROR_CODES.VALIDATION_ERROR;
7661
7689
  }
7662
7690
  if (message.includes("not found") || message.includes("no such file")) {
7663
- return "file-not-found";
7691
+ return DO_NOT_DEV_ERROR_CODES.FILE_NOT_FOUND;
7664
7692
  }
7665
7693
  if (message.includes("permission") || message.includes("access denied")) {
7666
- return "permission-denied";
7694
+ return DO_NOT_DEV_ERROR_CODES.PERMISSION_DENIED;
7667
7695
  }
7668
7696
  if (message.includes("timeout") || message.includes("timed out")) {
7669
- return "timeout-error";
7697
+ return DO_NOT_DEV_ERROR_CODES.TIMEOUT_ERROR;
7670
7698
  }
7671
7699
  if (message.includes("dependency") || message.includes("module not found")) {
7672
- return "dependency-error";
7700
+ return DO_NOT_DEV_ERROR_CODES.DEPENDENCY_ERROR;
7673
7701
  }
7674
- return "unknown-error";
7702
+ return DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR;
7675
7703
  }
7676
7704
  };
7677
7705
  }
@@ -7694,16 +7722,19 @@ function getDirnameFromUrl(importMetaUrl) {
7694
7722
  return dirname2(fileURLToPath2(importMetaUrl));
7695
7723
  }
7696
7724
  function detectExecutionMode() {
7697
- const fileUrlPath = new URL(import.meta.url).pathname;
7698
- if (!fileUrlPath.includes("node_modules")) {
7699
- return "development";
7725
+ const fileUrlPath = fileURLToPath2(import.meta.url);
7726
+ if (fileUrlPath.includes("node_modules")) {
7727
+ return "published";
7728
+ }
7729
+ if (fileUrlPath.includes("/dist/")) {
7730
+ return "published";
7700
7731
  }
7701
- return "published";
7732
+ return "development";
7702
7733
  }
7703
7734
  function getTemplatesRoot() {
7704
7735
  const mode = detectExecutionMode();
7705
7736
  if (mode === "development") {
7706
- const fileUrlPath = new URL(import.meta.url).pathname;
7737
+ const fileUrlPath = fileURLToPath2(import.meta.url);
7707
7738
  const frameworkRoot = normalizePath(dirname2(fileUrlPath), "../../../..");
7708
7739
  return normalizePath(frameworkRoot, PACKAGE_PATHS.CLI, "templates");
7709
7740
  } else {
@@ -7826,14 +7857,13 @@ function globSync(pattern, options = {}) {
7826
7857
  });
7827
7858
  return results.map((p2) => pathResolverInstance.normalizePath(p2));
7828
7859
  }
7829
- var pathResolverInstance, getRepoRoot, getAppRoot, resolveFrameworkPackage, normalizePath, pathExists, read, readSync, write, writeSync, ensureDir, getRelativePathBetween, getDirname, joinPath;
7860
+ var pathResolverInstance, getAppRoot, resolveFrameworkPackage, normalizePath, pathExists, read, readSync, write, writeSync, ensureDir, getRelativePathBetween, getDirname, joinPath;
7830
7861
  var init_pathResolver = __esm({
7831
7862
  "packages/tooling/src/utils/pathResolver.ts"() {
7832
7863
  "use strict";
7833
7864
  init_utils();
7834
7865
  init_PathResolver();
7835
7866
  pathResolverInstance = PathResolver.getInstance({ debug: false });
7836
- getRepoRoot = () => pathResolverInstance.getRepoRoot();
7837
7867
  getAppRoot = () => pathResolverInstance.getAppRoot();
7838
7868
  resolveFrameworkPackage = (name, from) => pathResolverInstance.resolveFrameworkPackage(name, from || null);
7839
7869
  normalizePath = (...pathSegments) => {
@@ -7884,18 +7914,7 @@ var init_utils = __esm({
7884
7914
  }
7885
7915
  });
7886
7916
 
7887
- // packages/cli/src/bin/commands/bump.ts
7888
- init_utils();
7889
-
7890
- // packages/tooling/src/index.ts
7891
- init_utils();
7892
-
7893
- // packages/tooling/src/cli/index.ts
7894
- init_utils();
7895
-
7896
7917
  // packages/tooling/src/utils/cli-input.ts
7897
- init_utils();
7898
- init_dist2();
7899
7918
  async function askForConfirmation(message, defaultValue = false) {
7900
7919
  const result = await ye({
7901
7920
  message,
@@ -7924,6 +7943,22 @@ async function askForSelection(message, choices, defaultValue = 0) {
7924
7943
  }
7925
7944
  return result;
7926
7945
  }
7946
+ var init_cli_input = __esm({
7947
+ "packages/tooling/src/utils/cli-input.ts"() {
7948
+ "use strict";
7949
+ init_utils();
7950
+ init_dist2();
7951
+ }
7952
+ });
7953
+
7954
+ // packages/cli/src/bin/commands/bump.ts
7955
+ init_utils();
7956
+
7957
+ // packages/tooling/src/index.ts
7958
+ init_utils();
7959
+
7960
+ // packages/tooling/src/cli/index.ts
7961
+ init_utils();
7927
7962
 
7928
7963
  // packages/tooling/src/utils/matrix.ts
7929
7964
  init_utils();
@@ -7941,15 +7976,10 @@ function getMatrixPath(mode) {
7941
7976
  }
7942
7977
  const executionMode = mode || detectExecutionMode();
7943
7978
  if (executionMode === "development") {
7944
- const repoRoot = getRepoRoot();
7945
- if (repoRoot) {
7946
- const devPath = normalizePath(
7947
- repoRoot,
7948
- "packages/cli/dependencies-matrix.json"
7949
- );
7950
- if (pathExists(devPath)) {
7951
- return devPath;
7952
- }
7979
+ const templatesRoot = getTemplatesRoot();
7980
+ const devPath = normalizePath(templatesRoot, "..", "dependencies-matrix.json");
7981
+ if (pathExists(devPath)) {
7982
+ return devPath;
7953
7983
  }
7954
7984
  }
7955
7985
  return null;
@@ -7964,8 +7994,8 @@ function getCliVersion(mode) {
7964
7994
  }
7965
7995
  const executionMode = mode || detectExecutionMode();
7966
7996
  if (executionMode === "development") {
7967
- const repoRoot = getRepoRoot();
7968
- const cliPackageJson = joinPath(repoRoot, "packages/cli/package.json");
7997
+ const templatesRoot = getTemplatesRoot();
7998
+ const cliPackageJson = normalizePath(templatesRoot, "..", "package.json");
7969
7999
  if (pathExists(cliPackageJson)) {
7970
8000
  const pkg = readSync(cliPackageJson, { format: "json" });
7971
8001
  return String(pkg?.version || "0.0.0");
@@ -8070,6 +8100,7 @@ function compareVersions(current, expected) {
8070
8100
 
8071
8101
  // packages/tooling/src/maintenance/bump.ts
8072
8102
  init_utils();
8103
+ init_cli_input();
8073
8104
  init_cli_output();
8074
8105
  init_pathResolver();
8075
8106
 
@@ -8112,13 +8143,22 @@ function getSourceTemplatesPath() {
8112
8143
  }
8113
8144
  const appRoot = getAppRoot();
8114
8145
  if (appRoot) {
8115
- const directPath = joinPath(appRoot, "node_modules", "@donotdev", "cli", "templates", "root-consumer");
8146
+ const directPath = joinPath(
8147
+ appRoot,
8148
+ "node_modules",
8149
+ "@donotdev",
8150
+ "cli",
8151
+ "templates",
8152
+ "root-consumer"
8153
+ );
8116
8154
  if (pathExists(directPath)) {
8117
8155
  log.info("Found templates via node_modules lookup");
8118
8156
  return normalizePath(directPath);
8119
8157
  }
8120
8158
  }
8121
- log.warn("Could not find @donotdev/cli templates. Is @donotdev/cli installed?");
8159
+ log.warn(
8160
+ "Could not find @donotdev/cli templates. Is @donotdev/cli installed?"
8161
+ );
8122
8162
  return null;
8123
8163
  }
8124
8164
  async function syncFile(sourcePath, destPath, preserveIfExists, appRoot) {
@@ -8149,7 +8189,7 @@ async function syncFile(sourcePath, destPath, preserveIfExists, appRoot) {
8149
8189
  }
8150
8190
  }
8151
8191
  await ensureDir(getDirname(destPathWithoutExample));
8152
- await write(destPathWithoutExample, content, { format: "text" });
8192
+ await write(destPathWithoutExample, content, { format: "text", overwrite: true });
8153
8193
  return true;
8154
8194
  }
8155
8195
  async function syncTemplates(sourceRoot, destRoot, dryRun) {
@@ -7215,11 +7215,39 @@ var init_PathResolver = __esm({
7215
7215
  });
7216
7216
 
7217
7217
  // packages/tooling/src/utils/errors.ts
7218
- var DoNotDevError;
7218
+ var DO_NOT_DEV_ERROR_CODES, DoNotDevError;
7219
7219
  var init_errors = __esm({
7220
7220
  "packages/tooling/src/utils/errors.ts"() {
7221
7221
  "use strict";
7222
7222
  init_utils();
7223
+ DO_NOT_DEV_ERROR_CODES = {
7224
+ CONFIGURATION_ERROR: "configuration-error",
7225
+ CONFIG_NOT_FOUND: "config-not-found",
7226
+ CONFIG_INVALID: "config-invalid",
7227
+ PATH_RESOLUTION_ERROR: "path-resolution-error",
7228
+ FILE_OPERATION_ERROR: "file-operation-error",
7229
+ FILE_NOT_FOUND: "file-not-found",
7230
+ PERMISSION_DENIED: "permission-denied",
7231
+ GENERATION_ERROR: "generation-error",
7232
+ TEMPLATE_ERROR: "template-error",
7233
+ TEMPLATE_NOT_FOUND: "template-not-found",
7234
+ CLI_EXECUTION_ERROR: "cli-execution-error",
7235
+ COMMAND_NOT_FOUND: "command-not-found",
7236
+ COMMAND_FAILED: "command-failed",
7237
+ VALIDATION_ERROR: "validation-error",
7238
+ SCHEMA_ERROR: "schema-error",
7239
+ DEPENDENCY_ERROR: "dependency-error",
7240
+ DEPENDENCY_NOT_FOUND: "dependency-not-found",
7241
+ DEPENDENCY_VERSION_ERROR: "dependency-version-error",
7242
+ INVALID_ARGUMENT: "invalid-argument",
7243
+ MISSING_ARGUMENT: "missing-argument",
7244
+ MISSING_PROJECT_ID: "missing-project-id",
7245
+ FIREBASE_CLI_ERROR: "firebase-cli-error",
7246
+ DEPLOYMENT_FAILED: "deployment-failed",
7247
+ OPERATION_CANCELLED: "operation-cancelled",
7248
+ TIMEOUT_ERROR: "timeout-error",
7249
+ UNKNOWN_ERROR: "unknown-error"
7250
+ };
7223
7251
  DoNotDevError = class _DoNotDevError extends Error {
7224
7252
  /** The error code categorizing this error */
7225
7253
  code;
@@ -7239,7 +7267,7 @@ var init_errors = __esm({
7239
7267
  * @param {Record<string, any>} [options.context] - Additional context data
7240
7268
  * @param {boolean} [options.displayable=true] - Whether this error should be displayed to the user
7241
7269
  */
7242
- constructor(message, code = "unknown-error", options) {
7270
+ constructor(message, code = DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR, options) {
7243
7271
  super(message);
7244
7272
  this.name = "DoNotDevError";
7245
7273
  this.code = code;
@@ -7270,7 +7298,7 @@ var init_errors = __esm({
7270
7298
  * @param {boolean} [options.displayable=true] - Whether this error should be displayed to the user
7271
7299
  * @returns {DoNotDevError} New DoNotDev error wrapping the original
7272
7300
  */
7273
- static from(error2, context, code = "unknown-error", options) {
7301
+ static from(error2, context, code = DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR, options) {
7274
7302
  if (!(error2 instanceof Error)) {
7275
7303
  return new _DoNotDevError(
7276
7304
  `Unknown error: ${String(error2)}`,
@@ -7307,21 +7335,21 @@ var init_errors = __esm({
7307
7335
  }
7308
7336
  const message = error2.message.toLowerCase();
7309
7337
  if (error2.name === "ValidationError" || message.includes("validation")) {
7310
- return "validation-error";
7338
+ return DO_NOT_DEV_ERROR_CODES.VALIDATION_ERROR;
7311
7339
  }
7312
7340
  if (message.includes("not found") || message.includes("no such file")) {
7313
- return "file-not-found";
7341
+ return DO_NOT_DEV_ERROR_CODES.FILE_NOT_FOUND;
7314
7342
  }
7315
7343
  if (message.includes("permission") || message.includes("access denied")) {
7316
- return "permission-denied";
7344
+ return DO_NOT_DEV_ERROR_CODES.PERMISSION_DENIED;
7317
7345
  }
7318
7346
  if (message.includes("timeout") || message.includes("timed out")) {
7319
- return "timeout-error";
7347
+ return DO_NOT_DEV_ERROR_CODES.TIMEOUT_ERROR;
7320
7348
  }
7321
7349
  if (message.includes("dependency") || message.includes("module not found")) {
7322
- return "dependency-error";
7350
+ return DO_NOT_DEV_ERROR_CODES.DEPENDENCY_ERROR;
7323
7351
  }
7324
- return "unknown-error";
7352
+ return DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR;
7325
7353
  }
7326
7354
  };
7327
7355
  }