@donotdev/cli 0.0.20 → 0.0.21

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 (103) hide show
  1. package/README.md +31 -0
  2. package/dependencies-matrix.json +86 -19
  3. package/dist/bin/commands/agent-setup.js +2 -2
  4. package/dist/bin/commands/build.js +6 -6
  5. package/dist/bin/commands/bump.js +491 -69
  6. package/dist/bin/commands/cacheout.js +6 -6
  7. package/dist/bin/commands/coach.js +6 -6
  8. package/dist/bin/commands/create-app.js +23 -15
  9. package/dist/bin/commands/create-project.js +101 -16
  10. package/dist/bin/commands/db.js +142136 -0
  11. package/dist/bin/commands/deploy.js +336 -126
  12. package/dist/bin/commands/dev.js +6 -6
  13. package/dist/bin/commands/doctor.js +140 -33
  14. package/dist/bin/commands/emu.js +6 -6
  15. package/dist/bin/commands/format.js +6 -6
  16. package/dist/bin/commands/get-demo.js +11 -6
  17. package/dist/bin/commands/make-admin.js +14210 -13770
  18. package/dist/bin/commands/preview.js +6 -6
  19. package/dist/bin/commands/seed.js +142426 -0
  20. package/dist/bin/commands/setup-cicd.js +8904 -0
  21. package/dist/bin/commands/setup.js +256 -212
  22. package/dist/bin/commands/staging.js +343 -127
  23. package/dist/bin/commands/sync-secrets.js +55 -33
  24. package/dist/bin/commands/type-check.js +6 -6
  25. package/dist/bin/commands/wai.js +6 -6
  26. package/dist/bin/dndev.js +76 -11
  27. package/dist/bin/donotdev.js +21 -12
  28. package/dist/index.js +437 -142
  29. package/package.json +1 -1
  30. package/templates/app-demo/.env.example +1 -0
  31. package/templates/{root-consumer → app-demo}/entities/ExampleEntity.ts.example +15 -9
  32. package/templates/app-demo/index.html.example +1 -1
  33. package/templates/app-dndev/index.html.example +164 -0
  34. package/templates/app-dndev/public/logo.svg.example +1 -0
  35. package/templates/app-dndev/public/manifest.json.example +10 -0
  36. package/templates/app-dndev/src/App.tsx.example +35 -0
  37. package/templates/app-dndev/src/components/CockpitLayout.css.example +181 -0
  38. package/templates/app-dndev/src/components/CockpitLayout.tsx.example +209 -0
  39. package/templates/app-dndev/src/components/Kanban.css.example +385 -0
  40. package/templates/app-dndev/src/components/ModeToggle.tsx.example +32 -0
  41. package/templates/app-dndev/src/components/OverlaySlot.tsx.example +68 -0
  42. package/templates/app-dndev/src/components/TerminalPanel.css.example +228 -0
  43. package/templates/app-dndev/src/components/TerminalPanel.tsx.example +714 -0
  44. package/templates/app-dndev/src/components/markdown-prose.css.example +49 -0
  45. package/templates/app-dndev/src/components/phases/CaptainLog.tsx.example +107 -0
  46. package/templates/app-dndev/src/components/phases/ContextTabs.tsx.example +352 -0
  47. package/templates/app-dndev/src/components/phases/PhaseCard.tsx.example +126 -0
  48. package/templates/app-dndev/src/components/phases/PhaseDetail.tsx.example +147 -0
  49. package/templates/app-dndev/src/components/phases/ReviewPanel.tsx.example +115 -0
  50. package/templates/app-dndev/src/components/phases/phaseData.ts.example +366 -0
  51. package/templates/app-dndev/src/config/app.ts.example +103 -0
  52. package/templates/app-dndev/src/config/commands.ts.example +171 -0
  53. package/templates/app-dndev/src/config/legal.ts.example +170 -0
  54. package/templates/app-dndev/src/config/providers.ts.example +7 -0
  55. package/templates/app-dndev/src/globals.css.example +10 -0
  56. package/templates/app-dndev/src/hooks/useDndevFile.ts.example +144 -0
  57. package/templates/app-dndev/src/main.tsx.example +21 -0
  58. package/templates/app-dndev/src/pages/BoardPage.tsx.example +640 -0
  59. package/templates/app-dndev/src/pages/GrillPage.tsx.example +658 -0
  60. package/templates/app-dndev/src/pages/HomePage.tsx.example +347 -0
  61. package/templates/app-dndev/src/pages/NotFoundPage.tsx.example +33 -0
  62. package/templates/app-dndev/src/pages/PhasesPage.tsx.example +137 -0
  63. package/templates/app-dndev/src/pages/SettingsPage.tsx.example +64 -0
  64. package/templates/app-dndev/src/pages/legal/LegalNoticePage.tsx.example +75 -0
  65. package/templates/app-dndev/src/pages/legal/PrivacyPage.tsx.example +69 -0
  66. package/templates/app-dndev/src/pages/legal/TermsPage.tsx.example +71 -0
  67. package/templates/app-dndev/src/stores/dndevStore.ts.example +386 -0
  68. package/templates/app-dndev/src/themes.css.example +161 -0
  69. package/templates/app-dndev/terminal-sidecar.cjs.example +341 -0
  70. package/templates/app-dndev/tsconfig.json.example +9 -0
  71. package/templates/app-dndev/vite.config.ts.example +24 -0
  72. package/templates/app-next/src/locales/home_en.json.example +6 -6
  73. package/templates/app-vite/index.html.example +1 -1
  74. package/templates/app-vite/src/locales/home_en.json.example +6 -6
  75. package/templates/functions-supabase/supabase/functions/.env.example +0 -2
  76. package/templates/root-consumer/.claude/commands/grill.md.example +86 -8
  77. package/templates/root-consumer/.dndev.secrets.example +32 -0
  78. package/templates/root-consumer/.gitignore.example +3 -0
  79. package/templates/root-consumer/AI.md.example +4 -0
  80. package/templates/root-consumer/entities/index.ts.example +2 -5
  81. package/templates/root-consumer/guides/dndev/COMPONENTS_ATOMIC.md.example +4 -0
  82. package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +23 -20
  83. package/templates/root-consumer/guides/dndev/INDEX.md.example +1 -0
  84. package/templates/root-consumer/guides/dndev/SETUP_BILLING.md.example +3 -7
  85. package/templates/root-consumer/guides/dndev/SETUP_CICD.md.example +115 -0
  86. package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +41 -0
  87. package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +13 -18
  88. package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +17 -12
  89. package/templates/root-consumer/guides/dndev/advanced/COOKIE_REFERENCE.md.example +252 -252
  90. package/templates/root-consumer/guides/dndev/advanced/VERSION_CONTROL.md.example +174 -174
  91. package/templates/root-consumer/guides/wai-way/WAI_WAY_CLI.md.example +185 -251
  92. package/templates/root-consumer/guides/wai-way/agents/extractor.md.example +26 -8
  93. package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +66 -49
  94. package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +6 -5
  95. package/templates/root-consumer/guides/wai-way/blueprints/2_entities.md.example +9 -9
  96. package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +1 -1
  97. package/templates/root-consumer/guides/wai-way/blueprints/4_configure.md.example +7 -6
  98. package/templates/root-consumer/guides/wai-way/context_map.json.example +51 -20
  99. package/templates/root-consumer/guides/wai-way/hld_template.md.example +138 -0
  100. package/templates/root-consumer/guides/wai-way/lld_template.md.example +103 -0
  101. package/templates/root-consumer/guides/wai-way/prd_template.md.example +140 -0
  102. /package/templates/{root-consumer → app-demo}/entities/Contact.ts.example +0 -0
  103. /package/templates/{root-consumer → app-demo}/entities/demo.ts.example +0 -0
@@ -6920,7 +6920,7 @@ var init_PathResolver = __esm({
6920
6920
  }
6921
6921
  const detectedFormat = this._detectFormat(filePath, format);
6922
6922
  let writeContent;
6923
- if (Buffer2.isBuffer(content)) {
6923
+ if (Buffer.isBuffer(content)) {
6924
6924
  writeContent = content;
6925
6925
  } else if (detectedFormat === "json" && typeof content === "object") {
6926
6926
  writeContent = JSON.stringify(content, null, 2);
@@ -6929,7 +6929,7 @@ var init_PathResolver = __esm({
6929
6929
  }
6930
6930
  try {
6931
6931
  return await safeExecuteAsync(async () => {
6932
- if (Buffer2.isBuffer(writeContent)) {
6932
+ if (Buffer.isBuffer(writeContent)) {
6933
6933
  await fs.promises.writeFile(normalizedPath, writeContent);
6934
6934
  } else {
6935
6935
  await fs.promises.writeFile(normalizedPath, writeContent, "utf8");
@@ -6981,7 +6981,7 @@ var init_PathResolver = __esm({
6981
6981
  }
6982
6982
  const detectedFormat = this._detectFormat(filePath, format);
6983
6983
  let writeContent;
6984
- if (Buffer2.isBuffer(content)) {
6984
+ if (Buffer.isBuffer(content)) {
6985
6985
  writeContent = content;
6986
6986
  } else if (detectedFormat === "json" && typeof content === "object") {
6987
6987
  writeContent = JSON.stringify(content, null, 2);
@@ -6989,7 +6989,7 @@ var init_PathResolver = __esm({
6989
6989
  writeContent = String(content);
6990
6990
  }
6991
6991
  try {
6992
- if (Buffer2.isBuffer(writeContent)) {
6992
+ if (Buffer.isBuffer(writeContent)) {
6993
6993
  fs.writeFileSync(normalizedPath, writeContent);
6994
6994
  } else {
6995
6995
  fs.writeFileSync(normalizedPath, writeContent, "utf8");
@@ -7716,7 +7716,7 @@ var init_pathResolver = __esm({
7716
7716
  });
7717
7717
 
7718
7718
  // packages/tooling/src/bundler/utils.ts
7719
- import { Buffer as Buffer2 } from "node:buffer";
7719
+ import { Buffer } from "node:buffer";
7720
7720
  import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
7721
7721
  import { createRequire as createRequire3 } from "node:module";
7722
7722
  import { dirname as dirname3, resolve as resolve3 } from "node:path";
@@ -7733,7 +7733,7 @@ var init_utils = __esm({
7733
7733
  globalThis.require = require2;
7734
7734
  globalThis.__filename = __filename;
7735
7735
  globalThis.__dirname = __dirname;
7736
- globalThis.Buffer = Buffer2;
7736
+ globalThis.Buffer = Buffer;
7737
7737
  globalThis.process = process;
7738
7738
  if (typeof global === "undefined") {
7739
7739
  globalThis.global = globalThis;
@@ -7768,9 +7768,39 @@ var init_cli_input = __esm({
7768
7768
  }
7769
7769
  });
7770
7770
 
7771
+ // packages/tooling/src/utils/secrets-resolver.ts
7772
+ function parseEnvFile(filePath) {
7773
+ if (!pathExists(filePath)) return {};
7774
+ const content = readSync(filePath, { format: "text" });
7775
+ if (typeof content !== "string" || !content) return {};
7776
+ const result = {};
7777
+ for (const line of content.split(/\r?\n/)) {
7778
+ const trimmed = line.trim();
7779
+ if (!trimmed || trimmed.startsWith("#")) continue;
7780
+ const eqIdx = trimmed.indexOf("=");
7781
+ if (eqIdx === -1) continue;
7782
+ const key = trimmed.slice(0, eqIdx).trim();
7783
+ let value = trimmed.slice(eqIdx + 1).trim();
7784
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
7785
+ value = value.slice(1, -1);
7786
+ }
7787
+ if (key && value) {
7788
+ result[key] = value;
7789
+ }
7790
+ }
7791
+ return result;
7792
+ }
7793
+ var init_secrets_resolver = __esm({
7794
+ "packages/tooling/src/utils/secrets-resolver.ts"() {
7795
+ "use strict";
7796
+ init_utils();
7797
+ init_pathResolver();
7798
+ }
7799
+ });
7800
+
7771
7801
  // packages/tooling/src/apps/sync-secrets.ts
7772
7802
  import { spawnSync } from "node:child_process";
7773
- function parseEnvFile(filePath) {
7803
+ function parseEnvFile2(filePath) {
7774
7804
  if (!pathExists(filePath)) {
7775
7805
  throw new DoNotDevError(
7776
7806
  `Environment file not found: ${filePath}`,
@@ -7778,30 +7808,22 @@ function parseEnvFile(filePath) {
7778
7808
  { context: { filePath } }
7779
7809
  );
7780
7810
  }
7781
- const contentRaw = readSync(filePath, { format: "text" });
7782
- const content = typeof contentRaw === "string" ? contentRaw : null;
7783
- if (!content) {
7784
- throw new Error(`Failed to read secrets file: ${filePath}`);
7811
+ const result = parseEnvFile(filePath);
7812
+ if (Object.keys(result).length === 0) {
7813
+ log.debug(`No key-value pairs found in ${filePath}`);
7785
7814
  }
7786
- const secrets = {};
7787
- content.split("\n").forEach((line, index) => {
7788
- const trimmedLine = line.trim();
7789
- if (!trimmedLine || trimmedLine.startsWith("#")) {
7790
- return;
7791
- }
7792
- const equalIndex = trimmedLine.indexOf("=");
7793
- if (equalIndex === -1) {
7794
- log.warn(`Invalid line format at line ${index + 1}: ${trimmedLine}`);
7795
- return;
7796
- }
7797
- const key = trimmedLine.substring(0, equalIndex).trim();
7798
- const value = trimmedLine.substring(equalIndex + 1).trim();
7799
- const cleanValue = value.replace(/^["']|["']$/g, "");
7800
- if (key && cleanValue) {
7801
- secrets[key] = cleanValue;
7815
+ return result;
7816
+ }
7817
+ function parseSecretsWithFallback(envFilePath, projectRoot) {
7818
+ const dndevSecretsPath = joinPath(projectRoot, ".dndev.secrets");
7819
+ if (pathExists(dndevSecretsPath)) {
7820
+ const secrets = parseEnvFile(dndevSecretsPath);
7821
+ if (Object.keys(secrets).length > 0) {
7822
+ log.info(`Reading secrets from: ${dndevSecretsPath}`);
7823
+ return secrets;
7802
7824
  }
7803
- });
7804
- return secrets;
7825
+ }
7826
+ return parseEnvFile2(envFilePath);
7805
7827
  }
7806
7828
  function detectPlatform() {
7807
7829
  const currentDir = process.cwd();
@@ -8161,7 +8183,7 @@ function uploadServiceAccountToGitHub(appDir, repo, dryRun = false, staging = fa
8161
8183
  const contentRaw = readSync(filePath, { format: "text" });
8162
8184
  const content = typeof contentRaw === "string" ? contentRaw : null;
8163
8185
  if (!content) return;
8164
- const encoded = Buffer2.from(content).toString("base64");
8186
+ const encoded = Buffer.from(content).toString("base64");
8165
8187
  setGitHubSecret(secretName, encoded, repo, dryRun);
8166
8188
  }
8167
8189
  async function main(options = {}) {
@@ -8248,7 +8270,7 @@ Examples:
8248
8270
  return 1;
8249
8271
  }
8250
8272
  log.info(`Syncing secrets to GitHub repository: ${repo}`);
8251
- const secrets2 = parseEnvFile(envFilePath);
8273
+ const secrets2 = parseSecretsWithFallback(envFilePath, currentDir);
8252
8274
  const secretKeys2 = Object.keys(secrets2);
8253
8275
  if (secretKeys2.length === 0) {
8254
8276
  log.info("No secrets found in .env file");
@@ -8284,14 +8306,13 @@ Examples:
8284
8306
  return 0;
8285
8307
  }
8286
8308
  const platform = config.platform || detectPlatform();
8287
- log.info(`Reading secrets from: ${envFilePath}`);
8288
8309
  if (config.verbose) {
8289
8310
  log.debug(`Working directory: ${currentDir}`);
8290
8311
  log.debug(`Environment file: ${envFilePath}`);
8291
8312
  log.debug(`Platform: ${platform}`);
8292
8313
  log.debug(`Dry run mode: ${config.dryRun}`);
8293
8314
  }
8294
- const secrets = parseEnvFile(envFilePath);
8315
+ const secrets = parseSecretsWithFallback(envFilePath, currentDir);
8295
8316
  const secretKeys = Object.keys(secrets);
8296
8317
  if (secretKeys.length === 0) {
8297
8318
  log.info("No secrets found in .env file");
@@ -8351,6 +8372,7 @@ var init_sync_secrets = __esm({
8351
8372
  init_cli_output();
8352
8373
  init_errors();
8353
8374
  init_pathResolver();
8375
+ init_secrets_resolver();
8354
8376
  }
8355
8377
  });
8356
8378
 
@@ -6712,7 +6712,7 @@ var init_PathResolver = __esm({
6712
6712
  }
6713
6713
  const detectedFormat = this._detectFormat(filePath, format);
6714
6714
  let writeContent;
6715
- if (Buffer2.isBuffer(content)) {
6715
+ if (Buffer.isBuffer(content)) {
6716
6716
  writeContent = content;
6717
6717
  } else if (detectedFormat === "json" && typeof content === "object") {
6718
6718
  writeContent = JSON.stringify(content, null, 2);
@@ -6721,7 +6721,7 @@ var init_PathResolver = __esm({
6721
6721
  }
6722
6722
  try {
6723
6723
  return await safeExecuteAsync(async () => {
6724
- if (Buffer2.isBuffer(writeContent)) {
6724
+ if (Buffer.isBuffer(writeContent)) {
6725
6725
  await fs.promises.writeFile(normalizedPath, writeContent);
6726
6726
  } else {
6727
6727
  await fs.promises.writeFile(normalizedPath, writeContent, "utf8");
@@ -6773,7 +6773,7 @@ var init_PathResolver = __esm({
6773
6773
  }
6774
6774
  const detectedFormat = this._detectFormat(filePath, format);
6775
6775
  let writeContent;
6776
- if (Buffer2.isBuffer(content)) {
6776
+ if (Buffer.isBuffer(content)) {
6777
6777
  writeContent = content;
6778
6778
  } else if (detectedFormat === "json" && typeof content === "object") {
6779
6779
  writeContent = JSON.stringify(content, null, 2);
@@ -6781,7 +6781,7 @@ var init_PathResolver = __esm({
6781
6781
  writeContent = String(content);
6782
6782
  }
6783
6783
  try {
6784
- if (Buffer2.isBuffer(writeContent)) {
6784
+ if (Buffer.isBuffer(writeContent)) {
6785
6785
  fs.writeFileSync(normalizedPath, writeContent);
6786
6786
  } else {
6787
6787
  fs.writeFileSync(normalizedPath, writeContent, "utf8");
@@ -7535,7 +7535,7 @@ var init_pathResolver = __esm({
7535
7535
  });
7536
7536
 
7537
7537
  // packages/tooling/src/bundler/utils.ts
7538
- import { Buffer as Buffer2 } from "node:buffer";
7538
+ import { Buffer } from "node:buffer";
7539
7539
  import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
7540
7540
  import { createRequire as createRequire3 } from "node:module";
7541
7541
  import { dirname as dirname3, resolve as resolve3 } from "node:path";
@@ -7552,7 +7552,7 @@ var init_utils = __esm({
7552
7552
  globalThis.require = require2;
7553
7553
  globalThis.__filename = __filename;
7554
7554
  globalThis.__dirname = __dirname;
7555
- globalThis.Buffer = Buffer2;
7555
+ globalThis.Buffer = Buffer;
7556
7556
  globalThis.process = process;
7557
7557
  if (typeof global === "undefined") {
7558
7558
  globalThis.global = globalThis;
@@ -6601,7 +6601,7 @@ var init_PathResolver = __esm({
6601
6601
  }
6602
6602
  const detectedFormat = this._detectFormat(filePath, format);
6603
6603
  let writeContent;
6604
- if (Buffer2.isBuffer(content)) {
6604
+ if (Buffer.isBuffer(content)) {
6605
6605
  writeContent = content;
6606
6606
  } else if (detectedFormat === "json" && typeof content === "object") {
6607
6607
  writeContent = JSON.stringify(content, null, 2);
@@ -6610,7 +6610,7 @@ var init_PathResolver = __esm({
6610
6610
  }
6611
6611
  try {
6612
6612
  return await safeExecuteAsync(async () => {
6613
- if (Buffer2.isBuffer(writeContent)) {
6613
+ if (Buffer.isBuffer(writeContent)) {
6614
6614
  await fs.promises.writeFile(normalizedPath, writeContent);
6615
6615
  } else {
6616
6616
  await fs.promises.writeFile(normalizedPath, writeContent, "utf8");
@@ -6662,7 +6662,7 @@ var init_PathResolver = __esm({
6662
6662
  }
6663
6663
  const detectedFormat = this._detectFormat(filePath, format);
6664
6664
  let writeContent;
6665
- if (Buffer2.isBuffer(content)) {
6665
+ if (Buffer.isBuffer(content)) {
6666
6666
  writeContent = content;
6667
6667
  } else if (detectedFormat === "json" && typeof content === "object") {
6668
6668
  writeContent = JSON.stringify(content, null, 2);
@@ -6670,7 +6670,7 @@ var init_PathResolver = __esm({
6670
6670
  writeContent = String(content);
6671
6671
  }
6672
6672
  try {
6673
- if (Buffer2.isBuffer(writeContent)) {
6673
+ if (Buffer.isBuffer(writeContent)) {
6674
6674
  fs.writeFileSync(normalizedPath, writeContent);
6675
6675
  } else {
6676
6676
  fs.writeFileSync(normalizedPath, writeContent, "utf8");
@@ -7247,7 +7247,7 @@ var init_pathResolver = __esm({
7247
7247
  });
7248
7248
 
7249
7249
  // packages/tooling/src/bundler/utils.ts
7250
- import { Buffer as Buffer2 } from "node:buffer";
7250
+ import { Buffer } from "node:buffer";
7251
7251
  import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
7252
7252
  import { createRequire as createRequire3 } from "node:module";
7253
7253
  import { dirname as dirname3, resolve as resolve3 } from "node:path";
@@ -7264,7 +7264,7 @@ var init_utils = __esm({
7264
7264
  globalThis.require = require2;
7265
7265
  globalThis.__filename = __filename;
7266
7266
  globalThis.__dirname = __dirname;
7267
- globalThis.Buffer = Buffer2;
7267
+ globalThis.Buffer = Buffer;
7268
7268
  globalThis.process = process;
7269
7269
  if (typeof global === "undefined") {
7270
7270
  globalThis.global = globalThis;
package/dist/bin/dndev.js CHANGED
@@ -533,10 +533,23 @@ var init_command_registry = __esm({
533
533
  exportName: "setup"
534
534
  },
535
535
  {
536
- name: "setup-cicd",
537
- description: "Setup CI/CD configuration",
536
+ name: "setup-cicd [app]",
537
+ description: "Setup CI/CD: detect providers, upload GitHub secrets, generate workflow YAML",
538
538
  category: "deployment",
539
+ public: true,
540
+ appCommand: true,
541
+ options: [
542
+ {
543
+ flags: "--app <app>",
544
+ description: "App name (auto-detected if single app)"
545
+ },
546
+ {
547
+ flags: "--staging",
548
+ description: "Include staging workflow generation"
549
+ }
550
+ ],
539
551
  loader: "../scaffolding/setup-cicd.ts",
552
+ wrapperFile: "setup-cicd",
540
553
  exportName: "setupCICD"
541
554
  },
542
555
  {
@@ -568,18 +581,61 @@ var init_command_registry = __esm({
568
581
  exportName: "doctor"
569
582
  },
570
583
  // ---------------------------------------------------------------------------
571
- // Content
584
+ // Database
572
585
  // ---------------------------------------------------------------------------
573
586
  {
574
- name: "blog <source>",
575
- description: "Convert source image to optimized WebP for blog (1200px, quality 80)",
576
- category: "content",
587
+ name: "seed [app]",
588
+ description: "Generate and insert sample data into your database",
589
+ category: "deployment",
590
+ public: true,
591
+ appCommand: true,
577
592
  options: [
578
593
  {
579
- flags: "--slug <slug>",
580
- description: "Output filename (default: source filename)"
594
+ flags: "-n, --count <number>",
595
+ description: "Rows per entity (default: 10)"
596
+ },
597
+ {
598
+ flags: "--clean",
599
+ description: "Truncate tables before seeding"
600
+ },
601
+ {
602
+ flags: "--only <entities>",
603
+ description: "Comma-separated entity names to seed"
604
+ },
605
+ {
606
+ flags: "--seed <number>",
607
+ description: "Random seed for reproducible output (default: 42)"
581
608
  }
582
609
  ],
610
+ loader: "../cli/seed/seed.ts",
611
+ exportName: "seed"
612
+ },
613
+ {
614
+ name: "db [script]",
615
+ description: "Run a custom database script with injected DbContext",
616
+ category: "deployment",
617
+ public: true,
618
+ options: [
619
+ {
620
+ flags: "-l, --list",
621
+ description: "List available scripts in .dndev/scripts/"
622
+ },
623
+ {
624
+ flags: "-a, --app <app>",
625
+ description: "App name (for multi-app monorepos)"
626
+ }
627
+ ],
628
+ loader: "../cli/db/db.ts",
629
+ exportName: "db"
630
+ },
631
+ // ---------------------------------------------------------------------------
632
+ // Content
633
+ // ---------------------------------------------------------------------------
634
+ {
635
+ name: "blog <slug>",
636
+ description: "Convert source image to optimized WebP for blog (1200px, quality 80)",
637
+ category: "content",
638
+ options: [],
583
639
  loader: "../apps/blog.ts"
584
640
  },
585
641
  // ---------------------------------------------------------------------------
@@ -640,6 +696,14 @@ var init_command_registry = __esm({
640
696
  ],
641
697
  loader: "../quality/grill-review.ts"
642
698
  },
699
+ {
700
+ name: "sync-app-templates",
701
+ description: "Copy live apps/demo and apps/dndev to CLI templates (with .example suffix)",
702
+ alias: "sat",
703
+ category: "internal",
704
+ loader: "../internal/sync-app-templates.ts",
705
+ exportName: "syncAppTemplates"
706
+ },
643
707
  {
644
708
  name: "generate sql",
645
709
  description: "Generate PostgreSQL CREATE TABLE + RLS + trigger from entity definitions",
@@ -738,8 +802,9 @@ var init_command_registry = __esm({
738
802
  exportName: "wai"
739
803
  },
740
804
  {
741
- name: "agent:setup",
805
+ name: "agent-setup",
742
806
  description: "Configure local and global agents to connect to the DoNotDev Intelligence Engine (MCP)",
807
+ alias: "agent",
743
808
  category: "other",
744
809
  public: true,
745
810
  wrapperFile: "agent-setup",
@@ -793,7 +858,7 @@ function registerCommand(program2, def, action) {
793
858
  }
794
859
 
795
860
  // packages/cli/src/bin/dndev.mjs
796
- var CLI_VERSION = true ? "0.0.20" : "0.0.0";
861
+ var CLI_VERSION = true ? "0.0.21" : "0.0.0";
797
862
  var args = process.argv.slice(2);
798
863
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v")) {
799
864
  console.log(CLI_VERSION);
@@ -901,7 +966,7 @@ var ACTION_OVERRIDES = {
901
966
  const { main } = await import("./commands/wai.js");
902
967
  process.exitCode = await main();
903
968
  },
904
- "agent:setup": async (options) => {
969
+ "agent-setup": async (options) => {
905
970
  const { main } = await import("./commands/agent-setup.js");
906
971
  await main(options);
907
972
  }
@@ -533,10 +533,23 @@ var init_command_registry = __esm({
533
533
  exportName: "setup"
534
534
  },
535
535
  {
536
- name: "setup-cicd",
537
- description: "Setup CI/CD configuration",
536
+ name: "setup-cicd [app]",
537
+ description: "Setup CI/CD: detect providers, upload GitHub secrets, generate workflow YAML",
538
538
  category: "deployment",
539
+ public: true,
540
+ appCommand: true,
541
+ options: [
542
+ {
543
+ flags: "--app <app>",
544
+ description: "App name (auto-detected if single app)"
545
+ },
546
+ {
547
+ flags: "--staging",
548
+ description: "Include staging workflow generation"
549
+ }
550
+ ],
539
551
  loader: "../scaffolding/setup-cicd.ts",
552
+ wrapperFile: "setup-cicd",
540
553
  exportName: "setupCICD"
541
554
  },
542
555
  {
@@ -571,15 +584,10 @@ var init_command_registry = __esm({
571
584
  // Content
572
585
  // ---------------------------------------------------------------------------
573
586
  {
574
- name: "blog <source>",
587
+ name: "blog <slug>",
575
588
  description: "Convert source image to optimized WebP for blog (1200px, quality 80)",
576
589
  category: "content",
577
- options: [
578
- {
579
- flags: "--slug <slug>",
580
- description: "Output filename (default: source filename)"
581
- }
582
- ],
590
+ options: [],
583
591
  loader: "../apps/blog.ts"
584
592
  },
585
593
  // ---------------------------------------------------------------------------
@@ -738,8 +746,9 @@ var init_command_registry = __esm({
738
746
  exportName: "wai"
739
747
  },
740
748
  {
741
- name: "agent:setup",
749
+ name: "agent-setup",
742
750
  description: "Configure local and global agents to connect to the DoNotDev Intelligence Engine (MCP)",
751
+ alias: "agent",
743
752
  category: "other",
744
753
  public: true,
745
754
  wrapperFile: "agent-setup",
@@ -793,7 +802,7 @@ function registerCommand(program2, def, action) {
793
802
  }
794
803
 
795
804
  // packages/cli/src/bin/dndev.mjs
796
- var CLI_VERSION = true ? "0.0.20" : "0.0.0";
805
+ var CLI_VERSION = true ? "0.0.21" : "0.0.0";
797
806
  var args = process.argv.slice(2);
798
807
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v")) {
799
808
  console.log(CLI_VERSION);
@@ -901,7 +910,7 @@ var ACTION_OVERRIDES = {
901
910
  const { main } = await import("./commands/wai.js");
902
911
  process.exitCode = await main();
903
912
  },
904
- "agent:setup": async (options) => {
913
+ "agent-setup": async (options) => {
905
914
  const { main } = await import("./commands/agent-setup.js");
906
915
  await main(options);
907
916
  }