@donotdev/cli 0.0.19 → 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 (128) hide show
  1. package/README.md +31 -0
  2. package/dependencies-matrix.json +205 -50
  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 +495 -70
  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 +24 -16
  9. package/dist/bin/commands/create-project.js +114 -18
  10. package/dist/bin/commands/db.js +142136 -0
  11. package/dist/bin/commands/deploy.js +354 -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 +259 -212
  22. package/dist/bin/commands/staging.js +361 -127
  23. package/dist/bin/commands/sync-secrets.js +55 -33
  24. package/dist/bin/commands/type-check.js +16 -10
  25. package/dist/bin/commands/wai.js +6 -6
  26. package/dist/bin/dndev.js +194 -188
  27. package/dist/bin/donotdev.js +139 -189
  28. package/dist/index.js +468 -144
  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-demo/public/apple-touch-icon.png.example +0 -0
  34. package/templates/app-demo/public/favicon.svg.example +1 -0
  35. package/templates/app-demo/public/icon-192x192.png.example +0 -0
  36. package/templates/app-demo/public/icon-512x512.png.example +0 -0
  37. package/templates/app-demo/src/App.tsx.example +3 -1
  38. package/templates/app-demo/src/config/app.ts.example +1 -0
  39. package/templates/app-demo/src/entities/booking.ts.example +75 -0
  40. package/templates/app-demo/src/entities/onboarding.ts.example +160 -0
  41. package/templates/app-demo/src/entities/product.ts.example +12 -0
  42. package/templates/app-demo/src/entities/quote.ts.example +70 -0
  43. package/templates/app-demo/src/pages/ChangelogPage.tsx.example +28 -1
  44. package/templates/app-demo/src/pages/ConditionalFormPage.tsx.example +88 -0
  45. package/templates/app-demo/src/pages/DashboardPage.tsx.example +2 -0
  46. package/templates/app-demo/src/pages/HomePage.tsx.example +355 -2
  47. package/templates/app-demo/src/pages/OnboardingPage.tsx.example +47 -0
  48. package/templates/app-demo/src/pages/PricingPage.tsx.example +28 -1
  49. package/templates/app-demo/src/pages/ProductsPage.tsx.example +2 -0
  50. package/templates/app-demo/src/pages/ProfilePage.tsx.example +2 -0
  51. package/templates/app-demo/src/pages/SettingsPage.tsx.example +2 -0
  52. package/templates/app-demo/src/pages/ShowcaseDetailPage.tsx.example +22 -16
  53. package/templates/app-demo/src/pages/ShowcasePage.tsx.example +3 -1
  54. package/templates/app-demo/src/pages/components/ComponentRenderer.tsx.example +147 -51
  55. package/templates/app-demo/src/pages/components/ComponentsData.tsx.example +103 -21
  56. package/templates/app-demo/src/pages/components/componentConfig.ts.example +139 -59
  57. package/templates/app-demo/src/pages/legal/LegalPage.tsx.example +12 -1
  58. package/templates/app-demo/src/pages/legal/PrivacyPage.tsx.example +10 -1
  59. package/templates/app-demo/src/pages/legal/TermsPage.tsx.example +10 -1
  60. package/templates/app-demo/src/themes.css.example +289 -77
  61. package/templates/app-demo/stats.html.example +4949 -0
  62. package/templates/app-dndev/index.html.example +164 -0
  63. package/templates/app-dndev/public/logo.svg.example +1 -0
  64. package/templates/app-dndev/public/manifest.json.example +10 -0
  65. package/templates/app-dndev/src/App.tsx.example +35 -0
  66. package/templates/app-dndev/src/components/CockpitLayout.css.example +181 -0
  67. package/templates/app-dndev/src/components/CockpitLayout.tsx.example +209 -0
  68. package/templates/app-dndev/src/components/Kanban.css.example +385 -0
  69. package/templates/app-dndev/src/components/ModeToggle.tsx.example +32 -0
  70. package/templates/app-dndev/src/components/OverlaySlot.tsx.example +68 -0
  71. package/templates/app-dndev/src/components/TerminalPanel.css.example +228 -0
  72. package/templates/app-dndev/src/components/TerminalPanel.tsx.example +714 -0
  73. package/templates/app-dndev/src/components/markdown-prose.css.example +49 -0
  74. package/templates/app-dndev/src/components/phases/CaptainLog.tsx.example +107 -0
  75. package/templates/app-dndev/src/components/phases/ContextTabs.tsx.example +352 -0
  76. package/templates/app-dndev/src/components/phases/PhaseCard.tsx.example +126 -0
  77. package/templates/app-dndev/src/components/phases/PhaseDetail.tsx.example +147 -0
  78. package/templates/app-dndev/src/components/phases/ReviewPanel.tsx.example +115 -0
  79. package/templates/app-dndev/src/components/phases/phaseData.ts.example +366 -0
  80. package/templates/app-dndev/src/config/app.ts.example +103 -0
  81. package/templates/app-dndev/src/config/commands.ts.example +171 -0
  82. package/templates/app-dndev/src/config/legal.ts.example +170 -0
  83. package/templates/app-dndev/src/config/providers.ts.example +7 -0
  84. package/templates/app-dndev/src/globals.css.example +10 -0
  85. package/templates/app-dndev/src/hooks/useDndevFile.ts.example +144 -0
  86. package/templates/app-dndev/src/main.tsx.example +21 -0
  87. package/templates/app-dndev/src/pages/BoardPage.tsx.example +640 -0
  88. package/templates/app-dndev/src/pages/GrillPage.tsx.example +658 -0
  89. package/templates/app-dndev/src/pages/HomePage.tsx.example +347 -0
  90. package/templates/app-dndev/src/pages/NotFoundPage.tsx.example +33 -0
  91. package/templates/app-dndev/src/pages/PhasesPage.tsx.example +137 -0
  92. package/templates/app-dndev/src/pages/SettingsPage.tsx.example +64 -0
  93. package/templates/app-dndev/src/pages/legal/LegalNoticePage.tsx.example +75 -0
  94. package/templates/app-dndev/src/pages/legal/PrivacyPage.tsx.example +69 -0
  95. package/templates/app-dndev/src/pages/legal/TermsPage.tsx.example +71 -0
  96. package/templates/app-dndev/src/stores/dndevStore.ts.example +386 -0
  97. package/templates/app-dndev/src/themes.css.example +161 -0
  98. package/templates/app-dndev/terminal-sidecar.cjs.example +341 -0
  99. package/templates/app-dndev/tsconfig.json.example +9 -0
  100. package/templates/app-dndev/vite.config.ts.example +24 -0
  101. package/templates/app-vite/index.html.example +1 -1
  102. package/templates/functions-supabase/supabase/functions/.env.example +0 -2
  103. package/templates/root-consumer/.claude/commands/grill.md.example +86 -8
  104. package/templates/root-consumer/.dndev.secrets.example +32 -0
  105. package/templates/root-consumer/.gitignore.example +3 -0
  106. package/templates/root-consumer/AI.md.example +4 -0
  107. package/templates/root-consumer/entities/index.ts.example +2 -5
  108. package/templates/root-consumer/guides/dndev/COMPONENTS_ATOMIC.md.example +4 -0
  109. package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +23 -20
  110. package/templates/root-consumer/guides/dndev/INDEX.md.example +1 -0
  111. package/templates/root-consumer/guides/dndev/SETUP_BILLING.md.example +3 -7
  112. package/templates/root-consumer/guides/dndev/SETUP_CICD.md.example +115 -0
  113. package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +41 -0
  114. package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +13 -18
  115. package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +17 -12
  116. package/templates/root-consumer/guides/wai-way/WAI_WAY_CLI.md.example +185 -251
  117. package/templates/root-consumer/guides/wai-way/agents/extractor.md.example +26 -8
  118. package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +66 -49
  119. package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +6 -5
  120. package/templates/root-consumer/guides/wai-way/blueprints/2_entities.md.example +9 -9
  121. package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +1 -1
  122. package/templates/root-consumer/guides/wai-way/blueprints/4_configure.md.example +7 -6
  123. package/templates/root-consumer/guides/wai-way/context_map.json.example +51 -20
  124. package/templates/root-consumer/guides/wai-way/hld_template.md.example +138 -0
  125. package/templates/root-consumer/guides/wai-way/lld_template.md.example +103 -0
  126. package/templates/root-consumer/guides/wai-way/prd_template.md.example +140 -0
  127. /package/templates/{root-consumer → app-demo}/entities/Contact.ts.example +0 -0
  128. /package/templates/{root-consumer → app-demo}/entities/demo.ts.example +0 -0
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)"
608
+ }
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)"
581
626
  }
582
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",
@@ -753,11 +818,47 @@ var init_command_registry = __esm({
753
818
  // packages/cli/src/bin/dndev.mjs
754
819
  init_utils();
755
820
  init_command_registry();
756
- import { readFileSync } from "node:fs";
757
821
  import { Command } from "commander";
758
- var CLI_VERSION = JSON.parse(
759
- readFileSync(new URL("../../package.json", import.meta.url), "utf-8")
760
- ).version;
822
+
823
+ // packages/tooling/src/cli/entry-helpers.ts
824
+ init_utils();
825
+ function baseName2(commanderName) {
826
+ return commanderName.split(" ")[0] ?? commanderName;
827
+ }
828
+ function extractCommonOptions(commanderOptions) {
829
+ const quiet = process.env.QUIET === "true" || process.env.QUIET === "1" || commanderOptions.quiet || false;
830
+ const debug = process.env.DEBUG === "true" || process.env.DEBUG === "1" || commanderOptions.debug || false;
831
+ const verbose = !debug && (process.env.VERBOSE === "true" || process.env.VERBOSE === "1" || commanderOptions.verbose || false);
832
+ const dryRun = process.env.DRY_RUN === "true" || process.env.DRY_RUN === "1" || commanderOptions.dryRun || commanderOptions.dry || false;
833
+ return { dryRun, quiet, verbose, debug };
834
+ }
835
+ function addCommonOptions(cmd) {
836
+ cmd.option("--dry, --dry-run", "Preview changes without applying").option("--verbose", "Verbose output").option("--debug", "Debug output").option("-q, --quiet", "Quiet output (errors only)");
837
+ }
838
+ function registerCommand(program2, def, action) {
839
+ const cmd = program2.command(def.name);
840
+ if (def.alias) {
841
+ const aliases = Array.isArray(def.alias) ? def.alias : [def.alias];
842
+ for (const a of aliases) cmd.alias(a);
843
+ }
844
+ cmd.description(def.description);
845
+ if (def.options) {
846
+ for (const opt of def.options) {
847
+ cmd.option(opt.flags, opt.description);
848
+ }
849
+ }
850
+ addCommonOptions(cmd);
851
+ cmd.action(async (...commanderArgs) => {
852
+ const commanderOptions = commanderArgs[commanderArgs.length - 2];
853
+ const positionalArgs = commanderArgs.slice(0, -2);
854
+ const commonOptions = extractCommonOptions(commanderOptions);
855
+ const parsedOptions = { ...commonOptions, ...commanderOptions };
856
+ await action(parsedOptions, ...positionalArgs);
857
+ });
858
+ }
859
+
860
+ // packages/cli/src/bin/dndev.mjs
861
+ var CLI_VERSION = true ? "0.0.21" : "0.0.0";
761
862
  var args = process.argv.slice(2);
762
863
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v")) {
763
864
  console.log(CLI_VERSION);
@@ -772,214 +873,119 @@ if (args.length === 0 || args.length === 1 && (args[0] === "--help" || args[0] =
772
873
  }
773
874
  var program = new Command();
774
875
  program.name("dndev").description("DoNotDev Framework CLI").version(CLI_VERSION, "-v, --version", "display version number").usage("<command>[:<app>] [options]").helpCommand("help [command]", "display help for command");
775
- function extractCommonOptions(commanderOptions) {
776
- const quiet = process.env.QUIET === "true" || process.env.QUIET === "1" || commanderOptions.quiet || false;
777
- const debug = process.env.DEBUG === "true" || process.env.DEBUG === "1" || commanderOptions.debug || false;
778
- const verbose = !debug && (process.env.VERBOSE === "true" || process.env.VERBOSE === "1" || commanderOptions.verbose || false);
779
- const dryRun = process.env.DRY_RUN === "true" || process.env.DRY_RUN === "1" || commanderOptions.dryRun || false;
780
- return { dryRun, quiet, verbose, debug };
781
- }
782
- function addCommonOptions(cmd) {
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)");
784
- }
785
- async function runAppCommand(commandPath, app) {
876
+ async function runAppCommand(commandPath, app, commonOptions) {
786
877
  const savedArgv = process.argv;
787
878
  process.argv = app ? [savedArgv[0], savedArgv[1], app] : [savedArgv[0], savedArgv[1]];
788
879
  try {
789
880
  const { main } = await import(commandPath);
790
- process.exit(await main());
881
+ process.exitCode = await main(commonOptions);
882
+ } catch (error) {
883
+ console.error(`Command failed: ${error.message}`);
884
+ process.exitCode = error.context?.exitCode || 1;
791
885
  } finally {
792
886
  process.argv = savedArgv;
793
887
  }
794
888
  }
795
- function baseName2(name) {
796
- return name.split(" ")[0] ?? name;
889
+ function makeStandardAction(commandPath) {
890
+ return async (options, ...positionalArgs) => {
891
+ try {
892
+ const { main } = await import(commandPath);
893
+ await main(options, ...positionalArgs);
894
+ } catch (error) {
895
+ console.error(`Command failed: ${error.message}`);
896
+ process.exitCode = error.context?.exitCode || 1;
897
+ }
898
+ };
899
+ }
900
+ function makeAppAction(commandPath) {
901
+ return async (options, app) => {
902
+ await runAppCommand(commandPath, app, extractCommonOptions(options));
903
+ };
797
904
  }
798
905
  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
- });
906
+ "create-app": async (options, name) => {
907
+ const appName = name || options.name;
908
+ const { main } = await import("./commands/create-app.js");
909
+ if (appName) {
910
+ await main({
911
+ ...options,
912
+ name: appName
913
+ });
914
+ } else {
915
+ await main(options);
916
+ }
819
917
  },
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
- });
918
+ "type-check": async (options, app) => {
919
+ const { main } = await import("./commands/type-check.js");
920
+ process.exitCode = await main({ ...options, package: app });
834
921
  },
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
- });
922
+ "cacheout": async (options, app) => {
923
+ if (app) options.app = app;
924
+ const { main } = await import("./commands/cacheout.js");
925
+ process.exitCode = await main(options);
849
926
  },
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
- });
927
+ "staging": async (options, app) => {
928
+ const { main } = await import("./commands/deploy.js");
929
+ await main({ ...options, app, staging: true });
858
930
  },
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
- });
931
+ "deploy": async (options, app) => {
932
+ const { main } = await import("./commands/deploy.js");
933
+ await main({ ...options, app });
881
934
  },
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
- });
935
+ "sync-secrets": async (options) => {
936
+ if (options.project) options.projectId = options.project;
937
+ const { main } = await import("./commands/sync-secrets.js");
938
+ process.exitCode = await main(options);
898
939
  },
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");
940
+ "make-admin": async (options, userId) => {
941
+ const args2 = [];
942
+ if (userId) args2.push(userId);
943
+ if (options.project) args2.push(`--project=${options.project}`);
944
+ if (options.projectId) args2.push(`--project-id=${options.projectId}`);
945
+ if (options.super) args2.push("--super");
946
+ if (options.dryRun) args2.push("--dry-run");
947
+ if (options.verbose) args2.push("--verbose");
948
+ if (options.debug) args2.push("--debug");
949
+ try {
906
950
  const { main } = await import("./commands/make-admin.js");
907
951
  await main(args2);
908
- });
952
+ } catch (error) {
953
+ console.error(`make-admin failed: ${error.message}`);
954
+ process.exitCode = error.context?.exitCode || 1;
955
+ }
909
956
  },
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
- });
957
+ "setup": async (options, provider) => {
958
+ const { main } = await import("./commands/setup.js");
959
+ process.exitCode = await main({ ...options, provider });
916
960
  },
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
- });
961
+ "doctor": async (options) => {
962
+ const { main } = await import("./commands/doctor.js");
963
+ process.exitCode = await main({ ...options, check: options.check });
924
964
  },
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";
965
+ "wai": async () => {
966
+ const { main } = await import("./commands/wai.js");
967
+ process.exitCode = await main();
936
968
  },
937
- "wai": (cmd) => {
938
- cmd.action(async () => {
939
- const { main } = await import("./commands/wai.js");
940
- process.exit(await main());
941
- });
969
+ "agent-setup": async (options) => {
970
+ const { main } = await import("./commands/agent-setup.js");
971
+ await main(options);
942
972
  }
943
973
  };
944
- var publicCommands = getPublicCommands();
945
- for (const def of publicCommands) {
974
+ for (const def of getPublicCommands()) {
946
975
  const cmdName = baseName2(def.name);
947
976
  const wrapperFile = def.wrapperFile ?? cmdName;
948
977
  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
978
  const override = ACTION_OVERRIDES[def.name] ?? ACTION_OVERRIDES[cmdName];
979
+ let action;
962
980
  if (override) {
963
- const result = override(cmd);
964
- if (result === "skip") continue;
981
+ action = override;
965
982
  } else if (def.actionPattern === "app") {
966
- cmd.action((app) => runAppCommand(commandPath, app));
983
+ action = makeAppAction(commandPath);
967
984
  } 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
- });
985
+ action = makeStandardAction(commandPath);
976
986
  }
987
+ registerCommand(program, def, action);
977
988
  }
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) => {
979
- const options = extractCommonOptions(commanderOptions);
980
- const { main } = await import("./commands/agent-setup.js");
981
- await main(options);
982
- });
983
989
  function preprocessArgs(rawArgs) {
984
990
  if (rawArgs.length === 0) return rawArgs;
985
991
  const firstArg = rawArgs[0];