create-stackforge 0.1.2 → 0.1.4

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.
package/dist/cli.js CHANGED
@@ -275,7 +275,6 @@ async function promptForConfig(input) {
275
275
 
276
276
  // src/generators/core/project-creator.ts
277
277
  import { join as join3 } from "path";
278
- import { fileURLToPath } from "url";
279
278
 
280
279
  // src/utils/file-system.ts
281
280
  import { mkdir, readFile, rm, writeFile } from "fs/promises";
@@ -643,19 +642,33 @@ async function readProjectConfig(root) {
643
642
  }
644
643
 
645
644
  // src/generators/core/project-creator.ts
645
+ var GITIGNORE_CONTENT = `node_modules/
646
+ .next/
647
+ dist/
648
+ .env
649
+ .env.local
650
+ .env.*.local
651
+ .DS_Store
652
+ `;
653
+ var EDITORCONFIG_CONTENT = `root = true
654
+
655
+ [*]
656
+ charset = utf-8
657
+ end_of_line = lf
658
+ insert_final_newline = true
659
+ indent_style = space
660
+ indent_size = 2
661
+ `;
646
662
  async function createProjectSkeleton(root, config, ctx) {
647
663
  const projectRoot = join3(root, config.projectName);
648
- const templatesRoot = fileURLToPath(new URL("../../../templates", import.meta.url));
649
664
  await ensureDir(projectRoot, ctx);
650
665
  const readme = buildProjectReadme(config);
651
666
  await writeTextFile(join3(projectRoot, "README.md"), readme + "\n", ctx);
652
667
  const envExample = `# Environment Variables
653
668
  `;
654
669
  await writeTextFile(join3(projectRoot, ".env.example"), envExample, ctx);
655
- const gitignore = await readTextFile(join3(templatesRoot, "shared", "_gitignore"));
656
- await writeTextFile(join3(projectRoot, ".gitignore"), gitignore, ctx);
657
- const editorconfig = await readTextFile(join3(templatesRoot, "shared", ".editorconfig"));
658
- await writeTextFile(join3(projectRoot, ".editorconfig"), editorconfig, ctx);
670
+ await writeTextFile(join3(projectRoot, ".gitignore"), GITIGNORE_CONTENT, ctx);
671
+ await writeTextFile(join3(projectRoot, ".editorconfig"), EDITORCONFIG_CONTENT, ctx);
659
672
  const pkg = {
660
673
  name: config.projectName,
661
674
  version: "0.0.0",
@@ -698,8 +711,7 @@ async function createProjectSkeleton(root, config, ctx) {
698
711
  }
699
712
 
700
713
  // src/generators/database/database-files.ts
701
- import { join as join4 } from "path";
702
- import { fileURLToPath as fileURLToPath2 } from "url";
714
+ import { join as join5 } from "path";
703
715
 
704
716
  // src/utils/env-file.ts
705
717
  import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
@@ -740,12 +752,30 @@ async function removeEnvKey(path, key, ctx) {
740
752
  await writeFile3(path, filtered.join("\n"), "utf8");
741
753
  }
742
754
 
755
+ // src/utils/templates-dir.ts
756
+ import { dirname as dirname3, join as join4 } from "path";
757
+ import { existsSync as existsSync2 } from "fs";
758
+ import { fileURLToPath } from "url";
759
+ function findPackageRoot() {
760
+ let dir = dirname3(fileURLToPath(import.meta.url));
761
+ for (let i = 0; i < 10; i++) {
762
+ if (existsSync2(join4(dir, "package.json"))) {
763
+ return dir;
764
+ }
765
+ const parent = dirname3(dir);
766
+ if (parent === dir) break;
767
+ dir = parent;
768
+ }
769
+ throw new Error("Could not find package root (package.json)");
770
+ }
771
+ var TEMPLATES_DIR = join4(findPackageRoot(), "templates");
772
+
743
773
  // src/generators/database/database-files.ts
744
774
  async function generateDatabaseFiles(root, config, ctx) {
745
- const projectRoot = join4(root, config.projectName);
746
- const templatesRoot = fileURLToPath2(new URL("../../../templates", import.meta.url));
775
+ const projectRoot = join5(root, config.projectName);
776
+ const templatesRoot = TEMPLATES_DIR;
747
777
  if (config.database.provider !== "none") {
748
- const envPath = join4(projectRoot, ".env.example");
778
+ const envPath = join5(projectRoot, ".env.example");
749
779
  if (config.database.provider === "mongodb") {
750
780
  await appendEnvLine(envPath, 'MONGODB_URI=""', ctx);
751
781
  } else {
@@ -754,91 +784,90 @@ async function generateDatabaseFiles(root, config, ctx) {
754
784
  if (config.database.provider === "neon") {
755
785
  await appendEnvLine(envPath, 'NEON_API_KEY=""', ctx);
756
786
  await appendEnvLine(envPath, 'NEON_PROJECT_ID=""', ctx);
757
- const providerDir = join4(projectRoot, "database");
787
+ const providerDir = join5(projectRoot, "database");
758
788
  await ensureDir(providerDir, ctx);
759
- const providerReadme = await readTextFile(join4(templatesRoot, "database", "providers", "neon.README.md"));
760
- await writeTextFile(join4(providerDir, "README.md"), providerReadme, ctx);
789
+ const providerReadme = await readTextFile(join5(templatesRoot, "database", "providers", "neon.README.md"));
790
+ await writeTextFile(join5(providerDir, "README.md"), providerReadme, ctx);
761
791
  }
762
792
  if (config.database.provider === "supabase") {
763
793
  await appendEnvLine(envPath, 'SUPABASE_URL=""', ctx);
764
794
  await appendEnvLine(envPath, 'SUPABASE_ANON_KEY=""', ctx);
765
- const providerDir = join4(projectRoot, "database");
795
+ const providerDir = join5(projectRoot, "database");
766
796
  await ensureDir(providerDir, ctx);
767
- const providerReadme = await readTextFile(join4(templatesRoot, "database", "providers", "supabase.README.md"));
768
- await writeTextFile(join4(providerDir, "README.md"), providerReadme, ctx);
797
+ const providerReadme = await readTextFile(join5(templatesRoot, "database", "providers", "supabase.README.md"));
798
+ await writeTextFile(join5(providerDir, "README.md"), providerReadme, ctx);
769
799
  }
770
800
  }
771
801
  if (config.database.orm === "drizzle") {
772
- const drizzleDir = join4(projectRoot, "drizzle");
802
+ const drizzleDir = join5(projectRoot, "drizzle");
773
803
  await ensureDir(drizzleDir, ctx);
774
- const configContent = await readTextFile(join4(templatesRoot, "database", "drizzle", "drizzle.config.ts"));
775
- const schemaContent = await readTextFile(join4(templatesRoot, "database", "drizzle", "schema.ts"));
804
+ const configContent = await readTextFile(join5(templatesRoot, "database", "drizzle", "drizzle.config.ts"));
805
+ const schemaContent = await readTextFile(join5(templatesRoot, "database", "drizzle", "schema.ts"));
776
806
  const ext = config.frontend.language === "ts" ? "ts" : "js";
777
- const clientContent = await readTextFile(join4(templatesRoot, "database", "drizzle", `client.${ext}`));
778
- const exampleContent = await readTextFile(join4(templatesRoot, "database", "drizzle", `example.${ext}`));
779
- await writeTextFile(join4(projectRoot, "drizzle.config.ts"), configContent, ctx);
780
- await writeTextFile(join4(drizzleDir, "schema.ts"), schemaContent, ctx);
781
- await writeTextFile(join4(drizzleDir, `client.${ext}`), clientContent, ctx);
782
- await writeTextFile(join4(drizzleDir, `example.${ext}`), exampleContent, ctx);
807
+ const clientContent = await readTextFile(join5(templatesRoot, "database", "drizzle", `client.${ext}`));
808
+ const exampleContent = await readTextFile(join5(templatesRoot, "database", "drizzle", `example.${ext}`));
809
+ await writeTextFile(join5(projectRoot, "drizzle.config.ts"), configContent, ctx);
810
+ await writeTextFile(join5(drizzleDir, "schema.ts"), schemaContent, ctx);
811
+ await writeTextFile(join5(drizzleDir, `client.${ext}`), clientContent, ctx);
812
+ await writeTextFile(join5(drizzleDir, `example.${ext}`), exampleContent, ctx);
783
813
  }
784
814
  if (config.database.orm === "prisma") {
785
- const prismaDir = join4(projectRoot, "prisma");
815
+ const prismaDir = join5(projectRoot, "prisma");
786
816
  await ensureDir(prismaDir, ctx);
787
- const schema = await readTextFile(join4(templatesRoot, "database", "prisma", "schema.prisma"));
788
- await writeTextFile(join4(prismaDir, "schema.prisma"), schema, ctx);
789
- const dbDir = join4(projectRoot, "src", "db");
817
+ const schema = await readTextFile(join5(templatesRoot, "database", "prisma", "schema.prisma"));
818
+ await writeTextFile(join5(prismaDir, "schema.prisma"), schema, ctx);
819
+ const dbDir = join5(projectRoot, "src", "db");
790
820
  await ensureDir(dbDir, ctx);
791
821
  const ext = config.frontend.language === "ts" ? "ts" : "js";
792
- const client = await readTextFile(join4(templatesRoot, "database", "prisma", `client.${ext}`));
793
- const example = await readTextFile(join4(templatesRoot, "database", "prisma", `example.${ext}`));
794
- await writeTextFile(join4(dbDir, `prisma.${ext}`), client, ctx);
795
- await writeTextFile(join4(dbDir, `prisma-example.${ext}`), example, ctx);
796
- const usage = await readTextFile(join4(templatesRoot, "database", "usage", `prisma-users.${ext}`));
797
- await writeTextFile(join4(dbDir, `users.${ext}`), usage, ctx);
822
+ const client = await readTextFile(join5(templatesRoot, "database", "prisma", `client.${ext}`));
823
+ const example = await readTextFile(join5(templatesRoot, "database", "prisma", `example.${ext}`));
824
+ await writeTextFile(join5(dbDir, `prisma.${ext}`), client, ctx);
825
+ await writeTextFile(join5(dbDir, `prisma-example.${ext}`), example, ctx);
826
+ const usage = await readTextFile(join5(templatesRoot, "database", "usage", `prisma-users.${ext}`));
827
+ await writeTextFile(join5(dbDir, `users.${ext}`), usage, ctx);
798
828
  }
799
829
  if (config.database.orm === "mongoose") {
800
- const dbDir = join4(projectRoot, "src", "db");
830
+ const dbDir = join5(projectRoot, "src", "db");
801
831
  await ensureDir(dbDir, ctx);
802
832
  const ext = config.frontend.language === "ts" ? "ts" : "js";
803
- const connection = await readTextFile(join4(templatesRoot, "database", "mongoose", `connection.${ext}`));
804
- const model = await readTextFile(join4(templatesRoot, "database", "mongoose", `model.${ext}`));
805
- await writeTextFile(join4(dbDir, `mongoose.${ext}`), connection, ctx);
806
- await writeTextFile(join4(dbDir, `mongoose-model.${ext}`), model, ctx);
807
- const usage = await readTextFile(join4(templatesRoot, "database", "usage", `mongoose-users.${ext}`));
808
- await writeTextFile(join4(dbDir, `users.${ext}`), usage, ctx);
833
+ const connection = await readTextFile(join5(templatesRoot, "database", "mongoose", `connection.${ext}`));
834
+ const model = await readTextFile(join5(templatesRoot, "database", "mongoose", `model.${ext}`));
835
+ await writeTextFile(join5(dbDir, `mongoose.${ext}`), connection, ctx);
836
+ await writeTextFile(join5(dbDir, `mongoose-model.${ext}`), model, ctx);
837
+ const usage = await readTextFile(join5(templatesRoot, "database", "usage", `mongoose-users.${ext}`));
838
+ await writeTextFile(join5(dbDir, `users.${ext}`), usage, ctx);
809
839
  }
810
840
  if (config.database.orm === "typeorm") {
811
- const dbDir = join4(projectRoot, "src", "db");
841
+ const dbDir = join5(projectRoot, "src", "db");
812
842
  await ensureDir(dbDir, ctx);
813
843
  const ext = config.frontend.language === "ts" ? "ts" : "js";
814
- const template = await readTextFile(join4(templatesRoot, "database", "typeorm", `data-source.${ext}`));
844
+ const template = await readTextFile(join5(templatesRoot, "database", "typeorm", `data-source.${ext}`));
815
845
  const typeormType = config.database.provider === "mysql" ? "mysql" : config.database.provider === "sqlite" ? "sqlite" : "postgres";
816
846
  const migrationsPath = config.frontend.language === "ts" ? "migrations/*.ts" : "migrations/*.js";
817
847
  const content = template.replace("{{typeormType}}", typeormType).replace("{{migrationsPath}}", migrationsPath);
818
- await writeTextFile(join4(dbDir, `data-source.${ext}`), content, ctx);
819
- const entitiesDir = join4(dbDir, "entities");
848
+ await writeTextFile(join5(dbDir, `data-source.${ext}`), content, ctx);
849
+ const entitiesDir = join5(dbDir, "entities");
820
850
  await ensureDir(entitiesDir, ctx);
821
- const entity = await readTextFile(join4(templatesRoot, "database", "typeorm", `entity.${ext}`));
822
- await writeTextFile(join4(entitiesDir, `User.${ext}`), entity, ctx);
823
- const migrationsDir = join4(dbDir, "migrations");
851
+ const entity = await readTextFile(join5(templatesRoot, "database", "typeorm", `entity.${ext}`));
852
+ await writeTextFile(join5(entitiesDir, `User.${ext}`), entity, ctx);
853
+ const migrationsDir = join5(dbDir, "migrations");
824
854
  await ensureDir(migrationsDir, ctx);
825
- const migrationReadme = await readTextFile(join4(templatesRoot, "database", "typeorm", "migrations", "README.md"));
826
- await writeTextFile(join4(migrationsDir, "README.md"), migrationReadme, ctx);
827
- const usage = await readTextFile(join4(templatesRoot, "database", "usage", `typeorm-users.${ext}`));
828
- await writeTextFile(join4(dbDir, `users.${ext}`), usage, ctx);
855
+ const migrationReadme = await readTextFile(join5(templatesRoot, "database", "typeorm", "migrations", "README.md"));
856
+ await writeTextFile(join5(migrationsDir, "README.md"), migrationReadme, ctx);
857
+ const usage = await readTextFile(join5(templatesRoot, "database", "usage", `typeorm-users.${ext}`));
858
+ await writeTextFile(join5(dbDir, `users.${ext}`), usage, ctx);
829
859
  }
830
860
  if (config.database.orm === "drizzle") {
831
- const dbDir = join4(projectRoot, "src", "db");
861
+ const dbDir = join5(projectRoot, "src", "db");
832
862
  await ensureDir(dbDir, ctx);
833
863
  const ext = config.frontend.language === "ts" ? "ts" : "js";
834
- const usage = await readTextFile(join4(templatesRoot, "database", "usage", `drizzle-users.${ext}`));
835
- await writeTextFile(join4(dbDir, `users.${ext}`), usage, ctx);
864
+ const usage = await readTextFile(join5(templatesRoot, "database", "usage", `drizzle-users.${ext}`));
865
+ await writeTextFile(join5(dbDir, `users.${ext}`), usage, ctx);
836
866
  }
837
867
  }
838
868
 
839
869
  // src/generators/frontend/frontend-files.ts
840
- import { join as join5 } from "path";
841
- import { fileURLToPath as fileURLToPath3 } from "url";
870
+ import { join as join6 } from "path";
842
871
 
843
872
  // src/generators/templates/template-engine.ts
844
873
  function applyTemplate(content, vars) {
@@ -851,10 +880,10 @@ function applyTemplate(content, vars) {
851
880
 
852
881
  // src/generators/frontend/frontend-files.ts
853
882
  async function generateFrontendFiles(root, config, ctx) {
854
- const projectRoot = join5(root, config.projectName);
855
- const templatesRoot = fileURLToPath3(new URL("../../../templates", import.meta.url));
883
+ const projectRoot = join6(root, config.projectName);
884
+ const templatesRoot = TEMPLATES_DIR;
856
885
  if (config.frontend.type === "nextjs") {
857
- const appDir = join5(projectRoot, "app");
886
+ const appDir = join6(projectRoot, "app");
858
887
  await ensureDir(appDir, ctx);
859
888
  const uiCssImports = buildUiCssImports(config, "nextjs");
860
889
  const importCss = uiCssImports.length ? uiCssImports.join("") + "\n" : "";
@@ -863,25 +892,25 @@ async function generateFrontendFiles(root, config, ctx) {
863
892
  const hasProviders = hasTrpc || hasUiProvider;
864
893
  const providersImport = hasProviders ? "import { Providers } from './providers';\n" : "";
865
894
  const wrapChildren = hasProviders ? "<Providers>{children}</Providers>" : "{children}";
866
- const layoutTemplatePath = join5(
895
+ const layoutTemplatePath = join6(
867
896
  templatesRoot,
868
897
  "nextjs",
869
898
  "app",
870
899
  config.frontend.language === "ts" ? "layout.tsx" : "layout.jsx"
871
900
  );
872
- const pageTemplatePath = join5(
901
+ const pageTemplatePath = join6(
873
902
  templatesRoot,
874
903
  "nextjs",
875
904
  "app",
876
905
  config.frontend.language === "ts" ? "page.tsx" : "page.jsx"
877
906
  );
878
- const actionsTemplatePath = join5(
907
+ const actionsTemplatePath = join6(
879
908
  templatesRoot,
880
909
  "nextjs",
881
910
  "app",
882
911
  config.frontend.language === "ts" ? "actions.ts" : "actions.js"
883
912
  );
884
- const nextConfigTemplatePath = join5(
913
+ const nextConfigTemplatePath = join6(
885
914
  templatesRoot,
886
915
  "nextjs",
887
916
  config.frontend.language === "ts" ? "next.config.ts" : "next.config.js"
@@ -889,7 +918,7 @@ async function generateFrontendFiles(root, config, ctx) {
889
918
  const layoutTemplate = await readTextFile(layoutTemplatePath);
890
919
  const pageTemplate = await readTextFile(pageTemplatePath);
891
920
  const examplesTemplate = await readTextFile(
892
- join5(
921
+ join6(
893
922
  templatesRoot,
894
923
  "nextjs",
895
924
  "app",
@@ -906,15 +935,15 @@ async function generateFrontendFiles(root, config, ctx) {
906
935
  const links = buildPageLinks(config);
907
936
  const page = applyTemplate(pageTemplate, { projectName: config.projectName, links });
908
937
  await writeTextFile(
909
- join5(projectRoot, config.frontend.language === "ts" ? "next.config.ts" : "next.config.js"),
938
+ join6(projectRoot, config.frontend.language === "ts" ? "next.config.ts" : "next.config.js"),
910
939
  nextConfigTemplate,
911
940
  ctx
912
941
  );
913
- await writeTextFile(join5(appDir, config.frontend.language === "ts" ? "layout.tsx" : "layout.jsx"), layout, ctx);
914
- await writeTextFile(join5(appDir, config.frontend.language === "ts" ? "page.tsx" : "page.jsx"), page, ctx);
915
- await writeTextFile(join5(appDir, config.frontend.language === "ts" ? "actions.ts" : "actions.js"), actionsTemplate, ctx);
942
+ await writeTextFile(join6(appDir, config.frontend.language === "ts" ? "layout.tsx" : "layout.jsx"), layout, ctx);
943
+ await writeTextFile(join6(appDir, config.frontend.language === "ts" ? "page.tsx" : "page.jsx"), page, ctx);
944
+ await writeTextFile(join6(appDir, config.frontend.language === "ts" ? "actions.ts" : "actions.js"), actionsTemplate, ctx);
916
945
  if (config.api.type !== "none") {
917
- const examplesDir = join5(appDir, "examples");
946
+ const examplesDir = join6(appDir, "examples");
918
947
  await ensureDir(examplesDir, ctx);
919
948
  const { imports, components } = buildApiExamples(config, "nextjs");
920
949
  const featureNotes = buildFeatureNotes(config);
@@ -927,7 +956,7 @@ async function generateFrontendFiles(root, config, ctx) {
927
956
  uiDemoComponent
928
957
  });
929
958
  await writeTextFile(
930
- join5(examplesDir, config.frontend.language === "ts" ? "page.tsx" : "page.jsx"),
959
+ join6(examplesDir, config.frontend.language === "ts" ? "page.tsx" : "page.jsx"),
931
960
  examplesPage,
932
961
  ctx
933
962
  );
@@ -935,23 +964,23 @@ async function generateFrontendFiles(root, config, ctx) {
935
964
  if (hasProviders) {
936
965
  const providers = buildProvidersComponent(config, "nextjs");
937
966
  await writeTextFile(
938
- join5(appDir, config.frontend.language === "ts" ? "providers.tsx" : "providers.jsx"),
967
+ join6(appDir, config.frontend.language === "ts" ? "providers.tsx" : "providers.jsx"),
939
968
  providers,
940
969
  ctx
941
970
  );
942
971
  }
943
972
  }
944
973
  if (config.frontend.type === "vite") {
945
- const srcDir = join5(projectRoot, "src");
974
+ const srcDir = join6(projectRoot, "src");
946
975
  await ensureDir(srcDir, ctx);
947
976
  const uiCssImports = buildUiCssImports(config, "vite");
948
977
  const cssImport = uiCssImports.length ? uiCssImports.join("") : "";
949
978
  const ext = config.frontend.language === "ts" ? "tsx" : "jsx";
950
- const mainTemplatePath = join5(templatesRoot, "vite", config.frontend.language === "ts" ? "main.tsx" : "main.jsx");
951
- const appTemplatePath = join5(templatesRoot, "vite", config.frontend.language === "ts" ? "App.tsx" : "App.jsx");
952
- const indexTemplatePath = join5(templatesRoot, "vite", "index.html");
953
- const viteConfigTemplatePath = join5(templatesRoot, "vite", "vite.config.ts");
954
- const viteEnvTemplatePath = join5(templatesRoot, "vite", "vite-env.d.ts");
979
+ const mainTemplatePath = join6(templatesRoot, "vite", config.frontend.language === "ts" ? "main.tsx" : "main.jsx");
980
+ const appTemplatePath = join6(templatesRoot, "vite", config.frontend.language === "ts" ? "App.tsx" : "App.jsx");
981
+ const indexTemplatePath = join6(templatesRoot, "vite", "index.html");
982
+ const viteConfigTemplatePath = join6(templatesRoot, "vite", "vite.config.ts");
983
+ const viteEnvTemplatePath = join6(templatesRoot, "vite", "vite-env.d.ts");
955
984
  const mainTemplate = await readTextFile(mainTemplatePath);
956
985
  const appTemplate = await readTextFile(appTemplatePath);
957
986
  const indexTemplate = await readTextFile(indexTemplatePath);
@@ -984,17 +1013,17 @@ async function generateFrontendFiles(root, config, ctx) {
984
1013
  uiDemoComponent
985
1014
  });
986
1015
  const indexHtml = applyTemplate(indexTemplate, { projectName: config.projectName, ext });
987
- await writeTextFile(join5(projectRoot, "index.html"), indexHtml, ctx);
988
- await writeTextFile(join5(projectRoot, "vite.config.ts"), viteConfigTemplate, ctx);
989
- await writeTextFile(join5(srcDir, config.frontend.language === "ts" ? "main.tsx" : "main.jsx"), main, ctx);
990
- await writeTextFile(join5(srcDir, config.frontend.language === "ts" ? "App.tsx" : "App.jsx"), app, ctx);
1016
+ await writeTextFile(join6(projectRoot, "index.html"), indexHtml, ctx);
1017
+ await writeTextFile(join6(projectRoot, "vite.config.ts"), viteConfigTemplate, ctx);
1018
+ await writeTextFile(join6(srcDir, config.frontend.language === "ts" ? "main.tsx" : "main.jsx"), main, ctx);
1019
+ await writeTextFile(join6(srcDir, config.frontend.language === "ts" ? "App.tsx" : "App.jsx"), app, ctx);
991
1020
  if (config.frontend.language === "ts") {
992
- await writeTextFile(join5(srcDir, "vite-env.d.ts"), viteEnvTemplate, ctx);
1021
+ await writeTextFile(join6(srcDir, "vite-env.d.ts"), viteEnvTemplate, ctx);
993
1022
  }
994
- await appendEnvLine(join5(projectRoot, ".env.example"), 'VITE_API_URL="http://localhost:3001"', ctx);
1023
+ await appendEnvLine(join6(projectRoot, ".env.example"), 'VITE_API_URL="http://localhost:3001"', ctx);
995
1024
  if (hasProviders) {
996
1025
  const providers = buildProvidersComponent(config, "vite");
997
- await writeTextFile(join5(srcDir, config.frontend.language === "ts" ? "providers.tsx" : "providers.jsx"), providers, ctx);
1026
+ await writeTextFile(join6(srcDir, config.frontend.language === "ts" ? "providers.tsx" : "providers.jsx"), providers, ctx);
998
1027
  }
999
1028
  }
1000
1029
  }
@@ -1188,70 +1217,69 @@ function buildPageLinks(config) {
1188
1217
  }
1189
1218
 
1190
1219
  // src/generators/ui/ui-files.ts
1191
- import { join as join6 } from "path";
1192
- import { fileURLToPath as fileURLToPath4 } from "url";
1220
+ import { join as join7 } from "path";
1193
1221
  async function generateUiFiles(root, config, ctx) {
1194
- const projectRoot = join6(root, config.projectName);
1195
- const templatesRoot = fileURLToPath4(new URL("../../../templates", import.meta.url));
1222
+ const projectRoot = join7(root, config.projectName);
1223
+ const templatesRoot = TEMPLATES_DIR;
1196
1224
  if (config.ui.library === "tailwind") {
1197
- const tailwindTemplate = await readTextFile(join6(templatesRoot, "ui", "tailwind.config.js"));
1198
- const postcssTemplate = await readTextFile(join6(templatesRoot, "ui", "postcss.config.js"));
1199
- const stylesTemplate = await readTextFile(join6(templatesRoot, "ui", "styles.css"));
1200
- await writeTextFile(join6(projectRoot, "tailwind.config.js"), tailwindTemplate, ctx);
1201
- await writeTextFile(join6(projectRoot, "postcss.config.js"), postcssTemplate, ctx);
1202
- const stylesDir = join6(projectRoot, "src");
1225
+ const tailwindTemplate = await readTextFile(join7(templatesRoot, "ui", "tailwind.config.js"));
1226
+ const postcssTemplate = await readTextFile(join7(templatesRoot, "ui", "postcss.config.js"));
1227
+ const stylesTemplate = await readTextFile(join7(templatesRoot, "ui", "styles.css"));
1228
+ await writeTextFile(join7(projectRoot, "tailwind.config.js"), tailwindTemplate, ctx);
1229
+ await writeTextFile(join7(projectRoot, "postcss.config.js"), postcssTemplate, ctx);
1230
+ const stylesDir = join7(projectRoot, "src");
1203
1231
  await ensureDir(stylesDir, ctx);
1204
- await writeTextFile(join6(stylesDir, "styles.css"), stylesTemplate, ctx);
1232
+ await writeTextFile(join7(stylesDir, "styles.css"), stylesTemplate, ctx);
1205
1233
  const demo = await readTextFile(
1206
- join6(templatesRoot, "ui", config.frontend.language === "ts" ? "demo-tailwind.tsx" : "demo-tailwind.jsx")
1234
+ join7(templatesRoot, "ui", config.frontend.language === "ts" ? "demo-tailwind.tsx" : "demo-tailwind.jsx")
1207
1235
  );
1208
- await ensureDir(join6(projectRoot, "src", "components"), ctx);
1236
+ await ensureDir(join7(projectRoot, "src", "components"), ctx);
1209
1237
  await writeTextFile(
1210
- join6(projectRoot, "src", "components", config.frontend.language === "ts" ? "ui-demo.tsx" : "ui-demo.jsx"),
1238
+ join7(projectRoot, "src", "components", config.frontend.language === "ts" ? "ui-demo.tsx" : "ui-demo.jsx"),
1211
1239
  demo,
1212
1240
  ctx
1213
1241
  );
1214
1242
  }
1215
1243
  if (config.ui.library === "shadcn") {
1216
- await ensureDir(join6(projectRoot, "components"), ctx);
1217
- const shadcnReadme = await readTextFile(join6(templatesRoot, "ui", "shadcn.README.md"));
1218
- await writeTextFile(join6(projectRoot, "components", "README.md"), shadcnReadme, ctx);
1219
- const componentsJson = await readTextFile(join6(templatesRoot, "ui", "components.json"));
1220
- await writeTextFile(join6(projectRoot, "components.json"), componentsJson, ctx);
1221
- const srcDir = join6(projectRoot, "src");
1222
- await ensureDir(join6(srcDir, "lib"), ctx);
1223
- await ensureDir(join6(srcDir, "components", "ui"), ctx);
1244
+ await ensureDir(join7(projectRoot, "components"), ctx);
1245
+ const shadcnReadme = await readTextFile(join7(templatesRoot, "ui", "shadcn.README.md"));
1246
+ await writeTextFile(join7(projectRoot, "components", "README.md"), shadcnReadme, ctx);
1247
+ const componentsJson = await readTextFile(join7(templatesRoot, "ui", "components.json"));
1248
+ await writeTextFile(join7(projectRoot, "components.json"), componentsJson, ctx);
1249
+ const srcDir = join7(projectRoot, "src");
1250
+ await ensureDir(join7(srcDir, "lib"), ctx);
1251
+ await ensureDir(join7(srcDir, "components", "ui"), ctx);
1224
1252
  const ext = config.frontend.language === "ts" ? "ts" : "js";
1225
- const utilsTemplate = await readTextFile(join6(templatesRoot, "ui", `utils.${ext}`));
1226
- await writeTextFile(join6(srcDir, "lib", `utils.${ext}`), utilsTemplate, ctx);
1253
+ const utilsTemplate = await readTextFile(join7(templatesRoot, "ui", `utils.${ext}`));
1254
+ await writeTextFile(join7(srcDir, "lib", `utils.${ext}`), utilsTemplate, ctx);
1227
1255
  const buttonTemplate = await readTextFile(
1228
- join6(templatesRoot, "ui", config.frontend.language === "ts" ? "button.tsx" : "button.jsx")
1256
+ join7(templatesRoot, "ui", config.frontend.language === "ts" ? "button.tsx" : "button.jsx")
1229
1257
  );
1230
- await writeTextFile(join6(srcDir, "components", "ui", config.frontend.language === "ts" ? "button.tsx" : "button.jsx"), buttonTemplate, ctx);
1258
+ await writeTextFile(join7(srcDir, "components", "ui", config.frontend.language === "ts" ? "button.tsx" : "button.jsx"), buttonTemplate, ctx);
1231
1259
  const demo = await readTextFile(
1232
- join6(templatesRoot, "ui", config.frontend.language === "ts" ? "demo-shadcn.tsx" : "demo-shadcn.jsx")
1260
+ join7(templatesRoot, "ui", config.frontend.language === "ts" ? "demo-shadcn.tsx" : "demo-shadcn.jsx")
1233
1261
  );
1234
1262
  await writeTextFile(
1235
- join6(srcDir, "components", config.frontend.language === "ts" ? "ui-demo.tsx" : "ui-demo.jsx"),
1263
+ join7(srcDir, "components", config.frontend.language === "ts" ? "ui-demo.tsx" : "ui-demo.jsx"),
1236
1264
  demo,
1237
1265
  ctx
1238
1266
  );
1239
1267
  }
1240
1268
  if (["mui", "chakra", "mantine", "antd", "nextui"].includes(config.ui.library)) {
1241
- await ensureDir(join6(projectRoot, "components"), ctx);
1242
- const readme = await readTextFile(join6(templatesRoot, "ui", `${config.ui.library}.README.md`));
1243
- await writeTextFile(join6(projectRoot, "components", "README.md"), readme, ctx);
1244
- const srcDir = join6(projectRoot, "src");
1269
+ await ensureDir(join7(projectRoot, "components"), ctx);
1270
+ const readme = await readTextFile(join7(templatesRoot, "ui", `${config.ui.library}.README.md`));
1271
+ await writeTextFile(join7(projectRoot, "components", "README.md"), readme, ctx);
1272
+ const srcDir = join7(projectRoot, "src");
1245
1273
  await ensureDir(srcDir, ctx);
1246
1274
  const ext = config.frontend.language === "ts" ? "ts" : "js";
1247
- const themeTemplate = await readTextFile(join6(templatesRoot, "ui", `${config.ui.library}.theme.${ext}`));
1248
- await writeTextFile(join6(srcDir, `theme.${ext}`), themeTemplate, ctx);
1275
+ const themeTemplate = await readTextFile(join7(templatesRoot, "ui", `${config.ui.library}.theme.${ext}`));
1276
+ await writeTextFile(join7(srcDir, `theme.${ext}`), themeTemplate, ctx);
1249
1277
  const demo = await readTextFile(
1250
- join6(templatesRoot, "ui", `demo-${config.ui.library}.${config.frontend.language === "ts" ? "tsx" : "jsx"}`)
1278
+ join7(templatesRoot, "ui", `demo-${config.ui.library}.${config.frontend.language === "ts" ? "tsx" : "jsx"}`)
1251
1279
  );
1252
- await ensureDir(join6(srcDir, "components"), ctx);
1280
+ await ensureDir(join7(srcDir, "components"), ctx);
1253
1281
  await writeTextFile(
1254
- join6(srcDir, "components", config.frontend.language === "ts" ? "ui-demo.tsx" : "ui-demo.jsx"),
1282
+ join7(srcDir, "components", config.frontend.language === "ts" ? "ui-demo.tsx" : "ui-demo.jsx"),
1255
1283
  demo,
1256
1284
  ctx
1257
1285
  );
@@ -1259,54 +1287,53 @@ async function generateUiFiles(root, config, ctx) {
1259
1287
  }
1260
1288
 
1261
1289
  // src/generators/auth/auth-files.ts
1262
- import { join as join7 } from "path";
1263
- import { fileURLToPath as fileURLToPath5 } from "url";
1290
+ import { join as join8 } from "path";
1264
1291
  async function generateAuthFiles(root, config, ctx) {
1265
- const projectRoot = join7(root, config.projectName);
1266
- const templatesRoot = fileURLToPath5(new URL("../../../templates", import.meta.url));
1292
+ const projectRoot = join8(root, config.projectName);
1293
+ const templatesRoot = TEMPLATES_DIR;
1267
1294
  if (config.auth.provider === "nextauth") {
1268
- await appendEnvLine(join7(projectRoot, ".env.example"), 'NEXTAUTH_SECRET=""', ctx);
1269
- await appendEnvLine(join7(projectRoot, ".env.example"), 'NEXTAUTH_URL=""', ctx);
1295
+ await appendEnvLine(join8(projectRoot, ".env.example"), 'NEXTAUTH_SECRET=""', ctx);
1296
+ await appendEnvLine(join8(projectRoot, ".env.example"), 'NEXTAUTH_URL=""', ctx);
1270
1297
  const ext = config.frontend.language === "ts" ? "ts" : "js";
1271
1298
  if (config.frontend.type === "nextjs") {
1272
- const routeDir = join7(projectRoot, "app", "api", "auth", "[...nextauth]");
1299
+ const routeDir = join8(projectRoot, "app", "api", "auth", "[...nextauth]");
1273
1300
  await ensureDir(routeDir, ctx);
1274
- const route = await readTextFile(join7(templatesRoot, "auth", `nextauth-route.${ext}`));
1275
- await writeTextFile(join7(routeDir, config.frontend.language === "ts" ? "route.ts" : "route.js"), route, ctx);
1301
+ const route = await readTextFile(join8(templatesRoot, "auth", `nextauth-route.${ext}`));
1302
+ await writeTextFile(join8(routeDir, config.frontend.language === "ts" ? "route.ts" : "route.js"), route, ctx);
1276
1303
  }
1277
- const authDir = join7(projectRoot, "auth");
1304
+ const authDir = join8(projectRoot, "auth");
1278
1305
  await ensureDir(authDir, ctx);
1279
- const readme = await readTextFile(join7(templatesRoot, "auth", "nextauth.README.md"));
1280
- await writeTextFile(join7(authDir, "README.md"), readme, ctx);
1281
- const options = await readTextFile(join7(templatesRoot, "auth", `nextauth-options.${ext}`));
1282
- await writeTextFile(join7(authDir, `auth-options.${ext}`), options, ctx);
1306
+ const readme = await readTextFile(join8(templatesRoot, "auth", "nextauth.README.md"));
1307
+ await writeTextFile(join8(authDir, "README.md"), readme, ctx);
1308
+ const options = await readTextFile(join8(templatesRoot, "auth", `nextauth-options.${ext}`));
1309
+ await writeTextFile(join8(authDir, `auth-options.${ext}`), options, ctx);
1283
1310
  if (config.frontend.type === "nextjs") {
1284
- const protectedDir = join7(projectRoot, "app", "auth", "protected");
1311
+ const protectedDir = join8(projectRoot, "app", "auth", "protected");
1285
1312
  await ensureDir(protectedDir, ctx);
1286
1313
  const protectedPage = await readTextFile(
1287
- join7(templatesRoot, "auth", `nextauth-protected-page.${ext}x`)
1314
+ join8(templatesRoot, "auth", `nextauth-protected-page.${ext}x`)
1288
1315
  );
1289
- await writeTextFile(join7(protectedDir, `page.${ext}x`), protectedPage, ctx);
1290
- const signInDir = join7(projectRoot, "app", "auth", "signin");
1316
+ await writeTextFile(join8(protectedDir, `page.${ext}x`), protectedPage, ctx);
1317
+ const signInDir = join8(projectRoot, "app", "auth", "signin");
1291
1318
  await ensureDir(signInDir, ctx);
1292
- const signInPage = await readTextFile(join7(templatesRoot, "auth", `nextauth-signin.${ext}x`));
1293
- await writeTextFile(join7(signInDir, `page.${ext}x`), signInPage, ctx);
1319
+ const signInPage = await readTextFile(join8(templatesRoot, "auth", `nextauth-signin.${ext}x`));
1320
+ await writeTextFile(join8(signInDir, `page.${ext}x`), signInPage, ctx);
1294
1321
  } else {
1295
- const protectedPage = await readTextFile(join7(templatesRoot, "auth", `nextauth-protected.${ext}x`));
1296
- await writeTextFile(join7(authDir, `protected.${ext}x`), protectedPage, ctx);
1322
+ const protectedPage = await readTextFile(join8(templatesRoot, "auth", `nextauth-protected.${ext}x`));
1323
+ await writeTextFile(join8(authDir, `protected.${ext}x`), protectedPage, ctx);
1297
1324
  }
1298
1325
  }
1299
1326
  if (config.auth.provider === "clerk") {
1300
- await appendEnvLine(join7(projectRoot, ".env.example"), 'CLERK_SECRET_KEY=""', ctx);
1301
- await appendEnvLine(join7(projectRoot, ".env.example"), 'NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=""', ctx);
1302
- const libDir = join7(projectRoot, "src", "lib");
1327
+ await appendEnvLine(join8(projectRoot, ".env.example"), 'CLERK_SECRET_KEY=""', ctx);
1328
+ await appendEnvLine(join8(projectRoot, ".env.example"), 'NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=""', ctx);
1329
+ const libDir = join8(projectRoot, "src", "lib");
1303
1330
  await ensureDir(libDir, ctx);
1304
1331
  const clerkClient = `import { clerkClient } from '@clerk/nextjs/server';
1305
1332
 
1306
1333
  export { clerkClient };
1307
1334
  `;
1308
1335
  const ext = config.frontend.language === "ts" ? "ts" : "js";
1309
- await writeTextFile(join7(libDir, `clerk.${ext}`), clerkClient, ctx);
1336
+ await writeTextFile(join8(libDir, `clerk.${ext}`), clerkClient, ctx);
1310
1337
  if (config.frontend.type === "nextjs") {
1311
1338
  const middleware = `import { authMiddleware } from '@clerk/nextjs';
1312
1339
 
@@ -1316,63 +1343,63 @@ export const config = {
1316
1343
  matcher: ['/((?!.*\\..*|_next).*)', '/', '/(api|trpc)(.*)']
1317
1344
  };
1318
1345
  `;
1319
- await writeTextFile(join7(projectRoot, `middleware.${ext}`), middleware, ctx);
1346
+ await writeTextFile(join8(projectRoot, `middleware.${ext}`), middleware, ctx);
1320
1347
  }
1321
- const authDir = join7(projectRoot, "auth");
1348
+ const authDir = join8(projectRoot, "auth");
1322
1349
  await ensureDir(authDir, ctx);
1323
- const readme = await readTextFile(join7(templatesRoot, "auth", "clerk.README.md"));
1324
- await writeTextFile(join7(authDir, "README.md"), readme, ctx);
1350
+ const readme = await readTextFile(join8(templatesRoot, "auth", "clerk.README.md"));
1351
+ await writeTextFile(join8(authDir, "README.md"), readme, ctx);
1325
1352
  if (config.frontend.type === "nextjs") {
1326
- const protectedDir = join7(projectRoot, "app", "auth", "protected");
1353
+ const protectedDir = join8(projectRoot, "app", "auth", "protected");
1327
1354
  await ensureDir(protectedDir, ctx);
1328
1355
  const protectedPage = await readTextFile(
1329
- join7(templatesRoot, "auth", `clerk-protected-page.${ext}x`)
1356
+ join8(templatesRoot, "auth", `clerk-protected-page.${ext}x`)
1330
1357
  );
1331
- await writeTextFile(join7(protectedDir, `page.${ext}x`), protectedPage, ctx);
1332
- const signInDir = join7(projectRoot, "app", "auth", "signin");
1358
+ await writeTextFile(join8(protectedDir, `page.${ext}x`), protectedPage, ctx);
1359
+ const signInDir = join8(projectRoot, "app", "auth", "signin");
1333
1360
  await ensureDir(signInDir, ctx);
1334
- const signInPage = await readTextFile(join7(templatesRoot, "auth", `clerk-signin.${ext}x`));
1335
- await writeTextFile(join7(signInDir, `page.${ext}x`), signInPage, ctx);
1361
+ const signInPage = await readTextFile(join8(templatesRoot, "auth", `clerk-signin.${ext}x`));
1362
+ await writeTextFile(join8(signInDir, `page.${ext}x`), signInPage, ctx);
1336
1363
  } else {
1337
- const protectedPage = await readTextFile(join7(templatesRoot, "auth", `clerk-protected.${ext}x`));
1338
- await writeTextFile(join7(authDir, `protected.${ext}x`), protectedPage, ctx);
1364
+ const protectedPage = await readTextFile(join8(templatesRoot, "auth", `clerk-protected.${ext}x`));
1365
+ await writeTextFile(join8(authDir, `protected.${ext}x`), protectedPage, ctx);
1339
1366
  }
1340
1367
  }
1341
1368
  if (config.auth.provider === "better-auth") {
1342
- await appendEnvLine(join7(projectRoot, ".env.example"), 'BETTER_AUTH_SECRET=""', ctx);
1343
- await appendEnvLine(join7(projectRoot, ".env.example"), 'BETTER_AUTH_URL=""', ctx);
1369
+ await appendEnvLine(join8(projectRoot, ".env.example"), 'BETTER_AUTH_SECRET=""', ctx);
1370
+ await appendEnvLine(join8(projectRoot, ".env.example"), 'BETTER_AUTH_URL=""', ctx);
1344
1371
  const ext = config.frontend.language === "ts" ? "ts" : "js";
1345
- const authDir = join7(projectRoot, "auth");
1372
+ const authDir = join8(projectRoot, "auth");
1346
1373
  await ensureDir(authDir, ctx);
1347
- const readme = await readTextFile(join7(templatesRoot, "auth", "better-auth.README.md"));
1348
- await writeTextFile(join7(authDir, "README.md"), readme, ctx);
1349
- const serverConfig = await readTextFile(join7(templatesRoot, "auth", `better-auth-server.${ext}`));
1350
- await writeTextFile(join7(authDir, `auth.${ext}`), serverConfig, ctx);
1351
- const libDir = join7(projectRoot, "src", "lib");
1374
+ const readme = await readTextFile(join8(templatesRoot, "auth", "better-auth.README.md"));
1375
+ await writeTextFile(join8(authDir, "README.md"), readme, ctx);
1376
+ const serverConfig = await readTextFile(join8(templatesRoot, "auth", `better-auth-server.${ext}`));
1377
+ await writeTextFile(join8(authDir, `auth.${ext}`), serverConfig, ctx);
1378
+ const libDir = join8(projectRoot, "src", "lib");
1352
1379
  await ensureDir(libDir, ctx);
1353
- const clientConfig = await readTextFile(join7(templatesRoot, "auth", `better-auth-client.${ext}`));
1354
- await writeTextFile(join7(libDir, `auth-client.${ext}`), clientConfig, ctx);
1380
+ const clientConfig = await readTextFile(join8(templatesRoot, "auth", `better-auth-client.${ext}`));
1381
+ await writeTextFile(join8(libDir, `auth-client.${ext}`), clientConfig, ctx);
1355
1382
  if (config.frontend.type === "nextjs") {
1356
- const routeDir = join7(projectRoot, "app", "api", "auth", "[...all]");
1383
+ const routeDir = join8(projectRoot, "app", "api", "auth", "[...all]");
1357
1384
  await ensureDir(routeDir, ctx);
1358
- const route = await readTextFile(join7(templatesRoot, "auth", `better-auth-route.${ext}`));
1359
- await writeTextFile(join7(routeDir, `route.${ext}`), route, ctx);
1360
- const protectedDir = join7(projectRoot, "app", "auth", "protected");
1385
+ const route = await readTextFile(join8(templatesRoot, "auth", `better-auth-route.${ext}`));
1386
+ await writeTextFile(join8(routeDir, `route.${ext}`), route, ctx);
1387
+ const protectedDir = join8(projectRoot, "app", "auth", "protected");
1361
1388
  await ensureDir(protectedDir, ctx);
1362
1389
  const protectedPage = await readTextFile(
1363
- join7(templatesRoot, "auth", `better-auth-protected-page.${ext}x`)
1390
+ join8(templatesRoot, "auth", `better-auth-protected-page.${ext}x`)
1364
1391
  );
1365
- await writeTextFile(join7(protectedDir, `page.${ext}x`), protectedPage, ctx);
1366
- const signInDir = join7(projectRoot, "app", "auth", "signin");
1392
+ await writeTextFile(join8(protectedDir, `page.${ext}x`), protectedPage, ctx);
1393
+ const signInDir = join8(projectRoot, "app", "auth", "signin");
1367
1394
  await ensureDir(signInDir, ctx);
1368
- const signInPage = await readTextFile(join7(templatesRoot, "auth", `better-auth-signin.${ext}x`));
1369
- await writeTextFile(join7(signInDir, `page.${ext}x`), signInPage, ctx);
1395
+ const signInPage = await readTextFile(join8(templatesRoot, "auth", `better-auth-signin.${ext}x`));
1396
+ await writeTextFile(join8(signInDir, `page.${ext}x`), signInPage, ctx);
1370
1397
  }
1371
1398
  }
1372
1399
  if (config.auth.provider === "supabase") {
1373
- await appendEnvLine(join7(projectRoot, ".env.example"), 'NEXT_PUBLIC_SUPABASE_URL=""', ctx);
1374
- await appendEnvLine(join7(projectRoot, ".env.example"), 'NEXT_PUBLIC_SUPABASE_ANON_KEY=""', ctx);
1375
- const libDir = join7(projectRoot, "src", "lib");
1400
+ await appendEnvLine(join8(projectRoot, ".env.example"), 'NEXT_PUBLIC_SUPABASE_URL=""', ctx);
1401
+ await appendEnvLine(join8(projectRoot, ".env.example"), 'NEXT_PUBLIC_SUPABASE_ANON_KEY=""', ctx);
1402
+ const libDir = join8(projectRoot, "src", "lib");
1376
1403
  await ensureDir(libDir, ctx);
1377
1404
  const supabaseClient = `import { createClient } from '@supabase/supabase-js';
1378
1405
 
@@ -1382,7 +1409,7 @@ const key = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || '';
1382
1409
  export const supabase = createClient(url, key);
1383
1410
  `;
1384
1411
  const ext = config.frontend.language === "ts" ? "ts" : "js";
1385
- await writeTextFile(join7(libDir, `supabase.${ext}`), supabaseClient, ctx);
1412
+ await writeTextFile(join8(libDir, `supabase.${ext}`), supabaseClient, ctx);
1386
1413
  if (config.frontend.type === "nextjs") {
1387
1414
  const supabaseServer = `import { createServerClient } from '@supabase/ssr';
1388
1415
  import { cookies } from 'next/headers';
@@ -1402,47 +1429,46 @@ export function createSupabaseServerClient() {
1402
1429
  );
1403
1430
  }
1404
1431
  `;
1405
- await writeTextFile(join7(libDir, `supabase-server.${ext}`), supabaseServer, ctx);
1432
+ await writeTextFile(join8(libDir, `supabase-server.${ext}`), supabaseServer, ctx);
1406
1433
  }
1407
- const authDir = join7(projectRoot, "auth");
1434
+ const authDir = join8(projectRoot, "auth");
1408
1435
  await ensureDir(authDir, ctx);
1409
- const readme = await readTextFile(join7(templatesRoot, "auth", "supabase.README.md"));
1410
- await writeTextFile(join7(authDir, "README.md"), readme, ctx);
1436
+ const readme = await readTextFile(join8(templatesRoot, "auth", "supabase.README.md"));
1437
+ await writeTextFile(join8(authDir, "README.md"), readme, ctx);
1411
1438
  if (config.frontend.type === "nextjs") {
1412
- const protectedDir = join7(projectRoot, "app", "auth", "protected");
1439
+ const protectedDir = join8(projectRoot, "app", "auth", "protected");
1413
1440
  await ensureDir(protectedDir, ctx);
1414
1441
  const protectedPage = await readTextFile(
1415
- join7(templatesRoot, "auth", `supabase-protected-page.${ext}x`)
1442
+ join8(templatesRoot, "auth", `supabase-protected-page.${ext}x`)
1416
1443
  );
1417
- await writeTextFile(join7(protectedDir, `page.${ext}x`), protectedPage, ctx);
1418
- const signInDir = join7(projectRoot, "app", "auth", "signin");
1444
+ await writeTextFile(join8(protectedDir, `page.${ext}x`), protectedPage, ctx);
1445
+ const signInDir = join8(projectRoot, "app", "auth", "signin");
1419
1446
  await ensureDir(signInDir, ctx);
1420
- const signInPage = await readTextFile(join7(templatesRoot, "auth", `supabase-signin.${ext}x`));
1421
- await writeTextFile(join7(signInDir, `page.${ext}x`), signInPage, ctx);
1447
+ const signInPage = await readTextFile(join8(templatesRoot, "auth", `supabase-signin.${ext}x`));
1448
+ await writeTextFile(join8(signInDir, `page.${ext}x`), signInPage, ctx);
1422
1449
  } else {
1423
- const protectedPage = await readTextFile(join7(templatesRoot, "auth", `supabase-protected.${ext}x`));
1424
- await writeTextFile(join7(authDir, `protected.${ext}x`), protectedPage, ctx);
1450
+ const protectedPage = await readTextFile(join8(templatesRoot, "auth", `supabase-protected.${ext}x`));
1451
+ await writeTextFile(join8(authDir, `protected.${ext}x`), protectedPage, ctx);
1425
1452
  const signin = await readTextFile(
1426
- join7(templatesRoot, "auth", `supabase-vite-signin.${ext}x`)
1453
+ join8(templatesRoot, "auth", `supabase-vite-signin.${ext}x`)
1427
1454
  );
1428
- const authUiDir = join7(projectRoot, "src", "auth");
1455
+ const authUiDir = join8(projectRoot, "src", "auth");
1429
1456
  await ensureDir(authUiDir, ctx);
1430
- await writeTextFile(join7(authUiDir, `signin.${ext}x`), signin, ctx);
1457
+ await writeTextFile(join8(authUiDir, `signin.${ext}x`), signin, ctx);
1431
1458
  }
1432
1459
  }
1433
1460
  }
1434
1461
 
1435
1462
  // src/generators/api/api-files.ts
1436
- import { join as join8 } from "path";
1437
- import { fileURLToPath as fileURLToPath6 } from "url";
1463
+ import { join as join9 } from "path";
1438
1464
  async function generateApiFiles(root, config, ctx) {
1439
- const projectRoot = join8(root, config.projectName);
1440
- const templatesRoot = fileURLToPath6(new URL("../../../templates", import.meta.url));
1465
+ const projectRoot = join9(root, config.projectName);
1466
+ const templatesRoot = TEMPLATES_DIR;
1441
1467
  if (config.api.type === "rest") {
1442
- const apiDir = join8(projectRoot, "api");
1468
+ const apiDir = join9(projectRoot, "api");
1443
1469
  await ensureDir(apiDir, ctx);
1444
1470
  await writeTextFile(
1445
- join8(apiDir, "README.md"),
1471
+ join9(apiDir, "README.md"),
1446
1472
  `# REST API
1447
1473
 
1448
1474
  ## Overview
@@ -1458,56 +1484,56 @@ async function generateApiFiles(root, config, ctx) {
1458
1484
  ctx
1459
1485
  );
1460
1486
  if (config.frontend.type === "nextjs") {
1461
- const routeDir = join8(projectRoot, "app", "api", "hello");
1487
+ const routeDir = join9(projectRoot, "app", "api", "hello");
1462
1488
  await ensureDir(routeDir, ctx);
1463
1489
  const ext = config.frontend.language === "ts" ? "ts" : "js";
1464
- const handler = await readTextFile(join8(templatesRoot, "api", "rest", `route.${ext}`));
1465
- await writeTextFile(join8(routeDir, `route.${ext}`), handler, ctx);
1490
+ const handler = await readTextFile(join9(templatesRoot, "api", "rest", `route.${ext}`));
1491
+ await writeTextFile(join9(routeDir, `route.${ext}`), handler, ctx);
1466
1492
  if (config.database.orm) {
1467
- const usersDir = join8(projectRoot, "app", "api", "users");
1493
+ const usersDir = join9(projectRoot, "app", "api", "users");
1468
1494
  await ensureDir(usersDir, ctx);
1469
1495
  const usersRoute = await readTextFile(
1470
- join8(templatesRoot, "api", "rest", config.frontend.language === "ts" ? "users-route.ts" : "users-route.js")
1496
+ join9(templatesRoot, "api", "rest", config.frontend.language === "ts" ? "users-route.ts" : "users-route.js")
1471
1497
  );
1472
1498
  await writeTextFile(
1473
- join8(usersDir, config.frontend.language === "ts" ? "route.ts" : "route.js"),
1499
+ join9(usersDir, config.frontend.language === "ts" ? "route.ts" : "route.js"),
1474
1500
  usersRoute,
1475
1501
  ctx
1476
1502
  );
1477
1503
  }
1478
1504
  }
1479
1505
  if (config.frontend.type === "vite") {
1480
- const serverDir = join8(projectRoot, "src", "server");
1506
+ const serverDir = join9(projectRoot, "src", "server");
1481
1507
  await ensureDir(serverDir, ctx);
1482
1508
  const serverTemplate = await readTextFile(
1483
- join8(templatesRoot, "api", "rest", config.frontend.language === "ts" ? "vite-server.ts" : "vite-server.js")
1509
+ join9(templatesRoot, "api", "rest", config.frontend.language === "ts" ? "vite-server.ts" : "vite-server.js")
1484
1510
  );
1485
1511
  await writeTextFile(
1486
- join8(serverDir, config.frontend.language === "ts" ? "index.ts" : "index.js"),
1512
+ join9(serverDir, config.frontend.language === "ts" ? "index.ts" : "index.js"),
1487
1513
  serverTemplate,
1488
1514
  ctx
1489
1515
  );
1490
1516
  }
1491
- const clientDir = join8(projectRoot, "src", "api");
1517
+ const clientDir = join9(projectRoot, "src", "api");
1492
1518
  await ensureDir(clientDir, ctx);
1493
1519
  const client = await readTextFile(
1494
- join8(templatesRoot, "api", "rest", config.frontend.language === "ts" ? "client.ts" : "client.js")
1520
+ join9(templatesRoot, "api", "rest", config.frontend.language === "ts" ? "client.ts" : "client.js")
1495
1521
  );
1496
- await writeTextFile(join8(clientDir, config.frontend.language === "ts" ? "client.ts" : "client.js"), client, ctx);
1522
+ await writeTextFile(join9(clientDir, config.frontend.language === "ts" ? "client.ts" : "client.js"), client, ctx);
1497
1523
  const usage = await readTextFile(
1498
- join8(templatesRoot, "api", "rest", config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx")
1524
+ join9(templatesRoot, "api", "rest", config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx")
1499
1525
  );
1500
1526
  await writeTextFile(
1501
- join8(clientDir, config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx"),
1527
+ join9(clientDir, config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx"),
1502
1528
  usage,
1503
1529
  ctx
1504
1530
  );
1505
1531
  }
1506
1532
  if (config.api.type === "trpc") {
1507
- const apiDir = join8(projectRoot, "api");
1533
+ const apiDir = join9(projectRoot, "api");
1508
1534
  await ensureDir(apiDir, ctx);
1509
1535
  await writeTextFile(
1510
- join8(apiDir, "README.md"),
1536
+ join9(apiDir, "README.md"),
1511
1537
  `# tRPC Setup
1512
1538
 
1513
1539
  ## Overview
@@ -1523,69 +1549,69 @@ async function generateApiFiles(root, config, ctx) {
1523
1549
  ctx
1524
1550
  );
1525
1551
  if (config.frontend.type === "nextjs") {
1526
- const trpcDir = join8(projectRoot, "src", "server", "api");
1552
+ const trpcDir = join9(projectRoot, "src", "server", "api");
1527
1553
  await ensureDir(trpcDir, ctx);
1528
- const router = await readTextFile(join8(templatesRoot, "api", "trpc", "trpc.ts"));
1529
- const appRouter = await readTextFile(join8(templatesRoot, "api", "trpc", "root.ts"));
1530
- await writeTextFile(join8(trpcDir, "trpc.ts"), router, ctx);
1531
- await writeTextFile(join8(trpcDir, "root.ts"), appRouter, ctx);
1532
- const routeDir = join8(projectRoot, "app", "api", "trpc", "[trpc]");
1554
+ const router = await readTextFile(join9(templatesRoot, "api", "trpc", "trpc.ts"));
1555
+ const appRouter = await readTextFile(join9(templatesRoot, "api", "trpc", "root.ts"));
1556
+ await writeTextFile(join9(trpcDir, "trpc.ts"), router, ctx);
1557
+ await writeTextFile(join9(trpcDir, "root.ts"), appRouter, ctx);
1558
+ const routeDir = join9(projectRoot, "app", "api", "trpc", "[trpc]");
1533
1559
  await ensureDir(routeDir, ctx);
1534
- const handler = await readTextFile(join8(templatesRoot, "api", "trpc", "route.ts"));
1535
- await writeTextFile(join8(routeDir, config.frontend.language === "ts" ? "route.ts" : "route.js"), handler, ctx);
1536
- const clientDir = join8(projectRoot, "src", "trpc");
1560
+ const handler = await readTextFile(join9(templatesRoot, "api", "trpc", "route.ts"));
1561
+ await writeTextFile(join9(routeDir, config.frontend.language === "ts" ? "route.ts" : "route.js"), handler, ctx);
1562
+ const clientDir = join9(projectRoot, "src", "trpc");
1537
1563
  await ensureDir(clientDir, ctx);
1538
1564
  const client = await readTextFile(
1539
- join8(templatesRoot, "api", "trpc", config.frontend.language === "ts" ? "client.ts" : "client.js")
1565
+ join9(templatesRoot, "api", "trpc", config.frontend.language === "ts" ? "client.ts" : "client.js")
1540
1566
  );
1541
- await writeTextFile(join8(clientDir, config.frontend.language === "ts" ? "client.ts" : "client.js"), client, ctx);
1567
+ await writeTextFile(join9(clientDir, config.frontend.language === "ts" ? "client.ts" : "client.js"), client, ctx);
1542
1568
  const usage = await readTextFile(
1543
- join8(templatesRoot, "api", "trpc", config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx")
1569
+ join9(templatesRoot, "api", "trpc", config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx")
1544
1570
  );
1545
1571
  await writeTextFile(
1546
- join8(clientDir, config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx"),
1572
+ join9(clientDir, config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx"),
1547
1573
  usage,
1548
1574
  ctx
1549
1575
  );
1550
1576
  }
1551
1577
  if (config.frontend.type === "vite") {
1552
- const trpcDir = join8(projectRoot, "src", "server", "api");
1578
+ const trpcDir = join9(projectRoot, "src", "server", "api");
1553
1579
  await ensureDir(trpcDir, ctx);
1554
- const router = await readTextFile(join8(templatesRoot, "api", "trpc", "trpc.ts"));
1555
- const appRouter = await readTextFile(join8(templatesRoot, "api", "trpc", "root.ts"));
1556
- await writeTextFile(join8(trpcDir, "trpc.ts"), router, ctx);
1557
- await writeTextFile(join8(trpcDir, "root.ts"), appRouter, ctx);
1558
- const clientDir = join8(projectRoot, "src", "trpc");
1580
+ const router = await readTextFile(join9(templatesRoot, "api", "trpc", "trpc.ts"));
1581
+ const appRouter = await readTextFile(join9(templatesRoot, "api", "trpc", "root.ts"));
1582
+ await writeTextFile(join9(trpcDir, "trpc.ts"), router, ctx);
1583
+ await writeTextFile(join9(trpcDir, "root.ts"), appRouter, ctx);
1584
+ const clientDir = join9(projectRoot, "src", "trpc");
1559
1585
  await ensureDir(clientDir, ctx);
1560
1586
  const client = await readTextFile(
1561
- join8(templatesRoot, "api", "trpc", config.frontend.language === "ts" ? "client-vite.ts" : "client-vite.js")
1587
+ join9(templatesRoot, "api", "trpc", config.frontend.language === "ts" ? "client-vite.ts" : "client-vite.js")
1562
1588
  );
1563
- await writeTextFile(join8(clientDir, config.frontend.language === "ts" ? "client.ts" : "client.js"), client, ctx);
1589
+ await writeTextFile(join9(clientDir, config.frontend.language === "ts" ? "client.ts" : "client.js"), client, ctx);
1564
1590
  const usage = await readTextFile(
1565
- join8(templatesRoot, "api", "trpc", config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx")
1591
+ join9(templatesRoot, "api", "trpc", config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx")
1566
1592
  );
1567
1593
  await writeTextFile(
1568
- join8(clientDir, config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx"),
1594
+ join9(clientDir, config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx"),
1569
1595
  usage,
1570
1596
  ctx
1571
1597
  );
1572
- const serverDir = join8(projectRoot, "src", "server");
1598
+ const serverDir = join9(projectRoot, "src", "server");
1573
1599
  await ensureDir(serverDir, ctx);
1574
1600
  const serverTemplate = await readTextFile(
1575
- join8(templatesRoot, "api", "trpc", config.frontend.language === "ts" ? "vite-server.ts" : "vite-server.js")
1601
+ join9(templatesRoot, "api", "trpc", config.frontend.language === "ts" ? "vite-server.ts" : "vite-server.js")
1576
1602
  );
1577
1603
  await writeTextFile(
1578
- join8(serverDir, config.frontend.language === "ts" ? "index.ts" : "index.js"),
1604
+ join9(serverDir, config.frontend.language === "ts" ? "index.ts" : "index.js"),
1579
1605
  serverTemplate,
1580
1606
  ctx
1581
1607
  );
1582
1608
  }
1583
1609
  }
1584
1610
  if (config.api.type === "graphql") {
1585
- const apiDir = join8(projectRoot, "api");
1611
+ const apiDir = join9(projectRoot, "api");
1586
1612
  await ensureDir(apiDir, ctx);
1587
1613
  await writeTextFile(
1588
- join8(apiDir, "README.md"),
1614
+ join9(apiDir, "README.md"),
1589
1615
  `# GraphQL Setup
1590
1616
 
1591
1617
  ## Overview
@@ -1601,54 +1627,54 @@ async function generateApiFiles(root, config, ctx) {
1601
1627
  ctx
1602
1628
  );
1603
1629
  if (config.frontend.type === "nextjs") {
1604
- const gqlDir = join8(projectRoot, "src", "graphql");
1630
+ const gqlDir = join9(projectRoot, "src", "graphql");
1605
1631
  await ensureDir(gqlDir, ctx);
1606
- const schema = await readTextFile(join8(templatesRoot, "api", "graphql", "schema.graphql"));
1607
- await writeTextFile(join8(gqlDir, "schema.graphql"), schema, ctx);
1608
- const routeDir = join8(projectRoot, "app", "api", "graphql");
1632
+ const schema = await readTextFile(join9(templatesRoot, "api", "graphql", "schema.graphql"));
1633
+ await writeTextFile(join9(gqlDir, "schema.graphql"), schema, ctx);
1634
+ const routeDir = join9(projectRoot, "app", "api", "graphql");
1609
1635
  await ensureDir(routeDir, ctx);
1610
1636
  const gqlExt = config.frontend.language === "ts" ? "ts" : "js";
1611
- const handler = await readTextFile(join8(templatesRoot, "api", "graphql", `route.${gqlExt}`));
1612
- await writeTextFile(join8(routeDir, `route.${gqlExt}`), handler, ctx);
1613
- const clientDir = join8(projectRoot, "src", "graphql");
1637
+ const handler = await readTextFile(join9(templatesRoot, "api", "graphql", `route.${gqlExt}`));
1638
+ await writeTextFile(join9(routeDir, `route.${gqlExt}`), handler, ctx);
1639
+ const clientDir = join9(projectRoot, "src", "graphql");
1614
1640
  const client = await readTextFile(
1615
- join8(templatesRoot, "api", "graphql", config.frontend.language === "ts" ? "client.ts" : "client.js")
1641
+ join9(templatesRoot, "api", "graphql", config.frontend.language === "ts" ? "client.ts" : "client.js")
1616
1642
  );
1617
- await writeTextFile(join8(clientDir, config.frontend.language === "ts" ? "client.ts" : "client.js"), client, ctx);
1643
+ await writeTextFile(join9(clientDir, config.frontend.language === "ts" ? "client.ts" : "client.js"), client, ctx);
1618
1644
  const usage = await readTextFile(
1619
- join8(templatesRoot, "api", "graphql", config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx")
1645
+ join9(templatesRoot, "api", "graphql", config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx")
1620
1646
  );
1621
1647
  await writeTextFile(
1622
- join8(clientDir, config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx"),
1648
+ join9(clientDir, config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx"),
1623
1649
  usage,
1624
1650
  ctx
1625
1651
  );
1626
1652
  }
1627
1653
  if (config.frontend.type === "vite") {
1628
- const gqlDir = join8(projectRoot, "src", "graphql");
1654
+ const gqlDir = join9(projectRoot, "src", "graphql");
1629
1655
  await ensureDir(gqlDir, ctx);
1630
- const schema = await readTextFile(join8(templatesRoot, "api", "graphql", "schema.graphql"));
1631
- await writeTextFile(join8(gqlDir, "schema.graphql"), schema, ctx);
1632
- const serverDir = join8(projectRoot, "src", "server");
1656
+ const schema = await readTextFile(join9(templatesRoot, "api", "graphql", "schema.graphql"));
1657
+ await writeTextFile(join9(gqlDir, "schema.graphql"), schema, ctx);
1658
+ const serverDir = join9(projectRoot, "src", "server");
1633
1659
  await ensureDir(serverDir, ctx);
1634
1660
  const serverTemplate = await readTextFile(
1635
- join8(templatesRoot, "api", "graphql", config.frontend.language === "ts" ? "vite-server.ts" : "vite-server.js")
1661
+ join9(templatesRoot, "api", "graphql", config.frontend.language === "ts" ? "vite-server.ts" : "vite-server.js")
1636
1662
  );
1637
1663
  await writeTextFile(
1638
- join8(serverDir, config.frontend.language === "ts" ? "index.ts" : "index.js"),
1664
+ join9(serverDir, config.frontend.language === "ts" ? "index.ts" : "index.js"),
1639
1665
  serverTemplate,
1640
1666
  ctx
1641
1667
  );
1642
- const clientDir = join8(projectRoot, "src", "graphql");
1668
+ const clientDir = join9(projectRoot, "src", "graphql");
1643
1669
  const client = await readTextFile(
1644
- join8(templatesRoot, "api", "graphql", config.frontend.language === "ts" ? "client.ts" : "client.js")
1670
+ join9(templatesRoot, "api", "graphql", config.frontend.language === "ts" ? "client.ts" : "client.js")
1645
1671
  );
1646
- await writeTextFile(join8(clientDir, config.frontend.language === "ts" ? "client.ts" : "client.js"), client, ctx);
1672
+ await writeTextFile(join9(clientDir, config.frontend.language === "ts" ? "client.ts" : "client.js"), client, ctx);
1647
1673
  const usage = await readTextFile(
1648
- join8(templatesRoot, "api", "graphql", config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx")
1674
+ join9(templatesRoot, "api", "graphql", config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx")
1649
1675
  );
1650
1676
  await writeTextFile(
1651
- join8(clientDir, config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx"),
1677
+ join9(clientDir, config.frontend.language === "ts" ? "client-usage.tsx" : "client-usage.jsx"),
1652
1678
  usage,
1653
1679
  ctx
1654
1680
  );
@@ -1657,8 +1683,8 @@ async function generateApiFiles(root, config, ctx) {
1657
1683
  }
1658
1684
 
1659
1685
  // src/ai-agents/config-generator.ts
1660
- import { join as join9 } from "path";
1661
- import { existsSync as existsSync2 } from "fs";
1686
+ import { join as join10 } from "path";
1687
+ import { existsSync as existsSync3 } from "fs";
1662
1688
  function buildAgentContext(config) {
1663
1689
  return {
1664
1690
  stack: {
@@ -1840,22 +1866,22 @@ function buildHints(config) {
1840
1866
  async function generateAiAgentConfigs(root, config, ctx) {
1841
1867
  if (!config.aiAgents || config.aiAgents.length === 0) return;
1842
1868
  const projectRoot = resolveProjectRoot(root, config);
1843
- const agentsRoot = join9(projectRoot, ".ai-agents");
1869
+ const agentsRoot = join10(projectRoot, ".ai-agents");
1844
1870
  await ensureDir(agentsRoot, ctx);
1845
- const serversRoot = join9(agentsRoot, "servers");
1871
+ const serversRoot = join10(agentsRoot, "servers");
1846
1872
  await ensureDir(serversRoot, ctx);
1847
- const protocolsRoot = join9(agentsRoot, "protocols");
1873
+ const protocolsRoot = join10(agentsRoot, "protocols");
1848
1874
  await ensureDir(protocolsRoot, ctx);
1849
1875
  const tools = buildTools(config);
1850
1876
  const hints = buildHints(config);
1851
1877
  for (const agent of config.aiAgents) {
1852
- const agentDir = join9(agentsRoot, agent);
1878
+ const agentDir = join10(agentsRoot, agent);
1853
1879
  await ensureDir(agentDir, ctx);
1854
1880
  const ext = config.frontend.language === "ts" ? "ts" : "js";
1855
1881
  const contextJson = JSON.stringify(buildAgentContext(config), null, 2);
1856
- await writeTextFile(join9(agentDir, "context.json"), contextJson + "\n", ctx);
1882
+ await writeTextFile(join10(agentDir, "context.json"), contextJson + "\n", ctx);
1857
1883
  const toolsJson = JSON.stringify({ tools }, null, 2);
1858
- await writeTextFile(join9(agentDir, "tools.json"), toolsJson + "\n", ctx);
1884
+ await writeTextFile(join10(agentDir, "tools.json"), toolsJson + "\n", ctx);
1859
1885
  if (agent === "claude") {
1860
1886
  const content = JSON.stringify(
1861
1887
  {
@@ -1869,19 +1895,19 @@ async function generateAiAgentConfigs(root, config, ctx) {
1869
1895
  null,
1870
1896
  2
1871
1897
  );
1872
- await writeTextFile(join9(agentDir, "claude_desktop_config.json"), content + "\n", ctx);
1873
- const claudeRoot = join9(projectRoot, ".claude");
1898
+ await writeTextFile(join10(agentDir, "claude_desktop_config.json"), content + "\n", ctx);
1899
+ const claudeRoot = join10(projectRoot, ".claude");
1874
1900
  await ensureDir(claudeRoot, ctx);
1875
- await writeTextFile(join9(claudeRoot, "claude_desktop_config.json"), content + "\n", ctx);
1901
+ await writeTextFile(join10(claudeRoot, "claude_desktop_config.json"), content + "\n", ctx);
1876
1902
  await writeTextFile(
1877
- join9(claudeRoot, "README.md"),
1903
+ join10(claudeRoot, "README.md"),
1878
1904
  "StackForge generated this folder for Claude. Use claude_desktop_config.json to configure the MCP server. The server lives in .ai-agents/servers/claude/mcp-server.(ts|js).\n",
1879
1905
  ctx
1880
1906
  );
1881
- const serverDir = join9(serversRoot, "claude");
1907
+ const serverDir = join10(serversRoot, "claude");
1882
1908
  await ensureDir(serverDir, ctx);
1883
1909
  const serverContent = buildMcpServerContent(ext, tools, hints);
1884
- await writeTextFile(join9(serverDir, `mcp-server.${ext}`), serverContent, ctx);
1910
+ await writeTextFile(join10(serverDir, `mcp-server.${ext}`), serverContent, ctx);
1885
1911
  const mcpSpec = JSON.stringify(
1886
1912
  {
1887
1913
  name: "stackforge",
@@ -1890,17 +1916,17 @@ async function generateAiAgentConfigs(root, config, ctx) {
1890
1916
  null,
1891
1917
  2
1892
1918
  );
1893
- await writeTextFile(join9(serverDir, "mcp.json"), mcpSpec + "\n", ctx);
1919
+ await writeTextFile(join10(serverDir, "mcp.json"), mcpSpec + "\n", ctx);
1894
1920
  await writeTextFile(
1895
- join9(serverDir, "README.md"),
1921
+ join10(serverDir, "README.md"),
1896
1922
  "Run the MCP server: `node mcp-server.js` (or .ts with tsx). Endpoints: /tools and /invoke.\n",
1897
1923
  ctx
1898
1924
  );
1899
1925
  }
1900
1926
  if (agent === "copilot") {
1901
1927
  const content = JSON.stringify({ functions: buildFunctionDefinitions(tools) }, null, 2);
1902
- await writeTextFile(join9(agentDir, "functions.json"), content + "\n", ctx);
1903
- const serverDir = join9(serversRoot, "copilot");
1928
+ await writeTextFile(join10(agentDir, "functions.json"), content + "\n", ctx);
1929
+ const serverDir = join10(serversRoot, "copilot");
1904
1930
  await ensureDir(serverDir, ctx);
1905
1931
  const serverContent = `export const functions = ${JSON.stringify(buildFunctionDefinitions(tools), null, 2)};
1906
1932
 
@@ -1908,21 +1934,21 @@ export function handleFunctionCall(name, args) {
1908
1934
  return { name, args, ok: true, message: 'Implement tool logic here.' };
1909
1935
  }
1910
1936
  `;
1911
- await writeTextFile(join9(serverDir, `functions.${ext}`), serverContent, ctx);
1912
- await writeTextFile(join9(serverDir, "functions.json"), content + "\n", ctx);
1937
+ await writeTextFile(join10(serverDir, `functions.${ext}`), serverContent, ctx);
1938
+ await writeTextFile(join10(serverDir, "functions.json"), content + "\n", ctx);
1913
1939
  }
1914
1940
  if (agent === "codex") {
1915
1941
  const content = JSON.stringify({ functions: buildFunctionDefinitions(tools) }, null, 2);
1916
- await writeTextFile(join9(agentDir, "functions.json"), content + "\n", ctx);
1917
- const codexRoot = join9(projectRoot, ".codex");
1942
+ await writeTextFile(join10(agentDir, "functions.json"), content + "\n", ctx);
1943
+ const codexRoot = join10(projectRoot, ".codex");
1918
1944
  await ensureDir(codexRoot, ctx);
1919
- await writeTextFile(join9(codexRoot, "functions.json"), content + "\n", ctx);
1945
+ await writeTextFile(join10(codexRoot, "functions.json"), content + "\n", ctx);
1920
1946
  await writeTextFile(
1921
- join9(codexRoot, "README.md"),
1947
+ join10(codexRoot, "README.md"),
1922
1948
  "StackForge generated this folder for Codex. Use functions.json for OpenAI function calling integrations.\n",
1923
1949
  ctx
1924
1950
  );
1925
- const serverDir = join9(serversRoot, "codex");
1951
+ const serverDir = join10(serversRoot, "codex");
1926
1952
  await ensureDir(serverDir, ctx);
1927
1953
  const serverContent = `export const functions = ${JSON.stringify(buildFunctionDefinitions(tools), null, 2)};
1928
1954
 
@@ -1930,13 +1956,13 @@ export function handleFunctionCall(name, args) {
1930
1956
  return { name, args, ok: true, message: 'Implement tool logic here.' };
1931
1957
  }
1932
1958
  `;
1933
- await writeTextFile(join9(serverDir, `functions.${ext}`), serverContent, ctx);
1934
- await writeTextFile(join9(serverDir, "functions.json"), content + "\n", ctx);
1959
+ await writeTextFile(join10(serverDir, `functions.${ext}`), serverContent, ctx);
1960
+ await writeTextFile(join10(serverDir, "functions.json"), content + "\n", ctx);
1935
1961
  }
1936
1962
  if (agent === "gemini") {
1937
1963
  const content = JSON.stringify({ functions: buildFunctionDefinitions(tools) }, null, 2);
1938
- await writeTextFile(join9(agentDir, "function_declarations.json"), content + "\n", ctx);
1939
- const serverDir = join9(serversRoot, "gemini");
1964
+ await writeTextFile(join10(agentDir, "function_declarations.json"), content + "\n", ctx);
1965
+ const serverDir = join10(serversRoot, "gemini");
1940
1966
  await ensureDir(serverDir, ctx);
1941
1967
  const serverContent = `export const functions = ${JSON.stringify(buildFunctionDefinitions(tools), null, 2)};
1942
1968
 
@@ -1944,46 +1970,46 @@ export function handleFunctionCall(name, args) {
1944
1970
  return { name, args, ok: true, message: 'Implement tool logic here.' };
1945
1971
  }
1946
1972
  `;
1947
- await writeTextFile(join9(serverDir, `functions.${ext}`), serverContent, ctx);
1948
- await writeTextFile(join9(serverDir, "function_declarations.json"), content + "\n", ctx);
1973
+ await writeTextFile(join10(serverDir, `functions.${ext}`), serverContent, ctx);
1974
+ await writeTextFile(join10(serverDir, "function_declarations.json"), content + "\n", ctx);
1949
1975
  }
1950
1976
  if (agent === "cursor") {
1951
1977
  const content = `# Cursor rules
1952
1978
  # See context.json for project stack details
1953
1979
  `;
1954
- await writeTextFile(join9(agentDir, ".cursorrules"), content, ctx);
1955
- await writeTextFile(join9(projectRoot, ".cursorrules"), content, ctx);
1956
- const cursorRoot = join9(projectRoot, ".cursor");
1980
+ await writeTextFile(join10(agentDir, ".cursorrules"), content, ctx);
1981
+ await writeTextFile(join10(projectRoot, ".cursorrules"), content, ctx);
1982
+ const cursorRoot = join10(projectRoot, ".cursor");
1957
1983
  await ensureDir(cursorRoot, ctx);
1958
1984
  const extensions = JSON.stringify({ recommendations: ["cursor.cursor"] }, null, 2);
1959
- await writeTextFile(join9(cursorRoot, "extensions.json"), extensions + "\n", ctx);
1960
- const serverDir = join9(serversRoot, "cursor");
1985
+ await writeTextFile(join10(cursorRoot, "extensions.json"), extensions + "\n", ctx);
1986
+ const serverDir = join10(serversRoot, "cursor");
1961
1987
  await ensureDir(serverDir, ctx);
1962
1988
  const serverContent = `# Cursor uses .cursorrules for guidance.
1963
1989
  `;
1964
- await writeTextFile(join9(serverDir, "README.md"), serverContent, ctx);
1990
+ await writeTextFile(join10(serverDir, "README.md"), serverContent, ctx);
1965
1991
  }
1966
1992
  if (agent === "codeium") {
1967
1993
  const content = JSON.stringify({ protocol: "lsp", tools, hints }, null, 2);
1968
- await writeTextFile(join9(agentDir, "server-config.json"), content + "\n", ctx);
1994
+ await writeTextFile(join10(agentDir, "server-config.json"), content + "\n", ctx);
1969
1995
  }
1970
1996
  if (agent === "windsurf") {
1971
- const windsurfRoot = join9(projectRoot, ".windsurf");
1997
+ const windsurfRoot = join10(projectRoot, ".windsurf");
1972
1998
  await ensureDir(windsurfRoot, ctx);
1973
1999
  const content = JSON.stringify({ protocol: "cascade", tools, hints }, null, 2);
1974
- await writeTextFile(join9(windsurfRoot, "cascade.json"), content + "\n", ctx);
2000
+ await writeTextFile(join10(windsurfRoot, "cascade.json"), content + "\n", ctx);
1975
2001
  }
1976
2002
  if (agent === "tabnine") {
1977
- const tabnineRoot = join9(projectRoot, ".tabnine");
2003
+ const tabnineRoot = join10(projectRoot, ".tabnine");
1978
2004
  await ensureDir(tabnineRoot, ctx);
1979
2005
  const content = JSON.stringify({ tools, hints }, null, 2);
1980
- await writeTextFile(join9(tabnineRoot, "config.json"), content + "\n", ctx);
2006
+ await writeTextFile(join10(tabnineRoot, "config.json"), content + "\n", ctx);
1981
2007
  }
1982
2008
  }
1983
2009
  const protocolTools = tools;
1984
2010
  const openAiFunctions = buildFunctionDefinitions(protocolTools);
1985
2011
  const openAiSchema = JSON.stringify({ functions: openAiFunctions }, null, 2);
1986
- await writeTextFile(join9(protocolsRoot, "openai-functions.json"), openAiSchema + "\n", ctx);
2012
+ await writeTextFile(join10(protocolsRoot, "openai-functions.json"), openAiSchema + "\n", ctx);
1987
2013
  const lspSchema = JSON.stringify(
1988
2014
  {
1989
2015
  version: "0.1",
@@ -1994,16 +2020,16 @@ export function handleFunctionCall(name, args) {
1994
2020
  null,
1995
2021
  2
1996
2022
  );
1997
- await writeTextFile(join9(protocolsRoot, "lsp.json"), lspSchema + "\n", ctx);
1998
- const docsDir = join9(projectRoot, "docs");
2023
+ await writeTextFile(join10(protocolsRoot, "lsp.json"), lspSchema + "\n", ctx);
2024
+ const docsDir = join10(projectRoot, "docs");
1999
2025
  await ensureDir(docsDir, ctx);
2000
2026
  const aiDoc = buildAiAgentsDoc(config);
2001
- await writeTextFile(join9(docsDir, "AI_AGENTS.md"), aiDoc + "\n", ctx);
2027
+ await writeTextFile(join10(docsDir, "AI_AGENTS.md"), aiDoc + "\n", ctx);
2002
2028
  }
2003
2029
  function resolveProjectRoot(root, config) {
2004
- const candidate = join9(root, "stackforge.json");
2005
- if (existsSync2(candidate)) return root;
2006
- return join9(root, config.projectName);
2030
+ const candidate = join10(root, "stackforge.json");
2031
+ if (existsSync3(candidate)) return root;
2032
+ return join10(root, config.projectName);
2007
2033
  }
2008
2034
  function buildAiAgentsDoc(config) {
2009
2035
  const agentsList = config.aiAgents.map((agent) => `- ${agent}`).join("\n");
@@ -2113,73 +2139,72 @@ server.listen(port, () => {
2113
2139
  }
2114
2140
 
2115
2141
  // src/generators/features/feature-files.ts
2116
- import { join as join10 } from "path";
2117
- import { fileURLToPath as fileURLToPath7 } from "url";
2142
+ import { join as join11 } from "path";
2118
2143
  async function generateFeatureFiles(root, config, ctx) {
2119
- const projectRoot = join10(root, config.projectName);
2120
- const templatesRoot = fileURLToPath7(new URL("../../../templates", import.meta.url));
2121
- const libDir = join10(projectRoot, "src", "lib");
2144
+ const projectRoot = join11(root, config.projectName);
2145
+ const templatesRoot = TEMPLATES_DIR;
2146
+ const libDir = join11(projectRoot, "src", "lib");
2122
2147
  const isTs = config.frontend.language === "ts";
2123
2148
  if (config.features.includes("email")) {
2124
- const dir = join10(projectRoot, "features", "email");
2149
+ const dir = join11(projectRoot, "features", "email");
2125
2150
  await ensureDir(dir, ctx);
2126
2151
  await ensureDir(libDir, ctx);
2127
- const readme = await readTextFile(join10(templatesRoot, "features", "email", "README.md"));
2152
+ const readme = await readTextFile(join11(templatesRoot, "features", "email", "README.md"));
2128
2153
  const resendClient = await readTextFile(
2129
- join10(templatesRoot, "features", "email", isTs ? "resend.ts" : "resend.js")
2154
+ join11(templatesRoot, "features", "email", isTs ? "resend.ts" : "resend.js")
2130
2155
  );
2131
- await writeTextFile(join10(dir, "README.md"), readme, ctx);
2132
- await writeTextFile(join10(libDir, isTs ? "resend.ts" : "resend.js"), resendClient, ctx);
2133
- await appendEnvLine(join10(projectRoot, ".env.example"), 'RESEND_API_KEY=""', ctx);
2156
+ await writeTextFile(join11(dir, "README.md"), readme, ctx);
2157
+ await writeTextFile(join11(libDir, isTs ? "resend.ts" : "resend.js"), resendClient, ctx);
2158
+ await appendEnvLine(join11(projectRoot, ".env.example"), 'RESEND_API_KEY=""', ctx);
2134
2159
  }
2135
2160
  if (config.features.includes("storage")) {
2136
- const dir = join10(projectRoot, "features", "storage");
2161
+ const dir = join11(projectRoot, "features", "storage");
2137
2162
  await ensureDir(dir, ctx);
2138
2163
  await ensureDir(libDir, ctx);
2139
- const readme = await readTextFile(join10(templatesRoot, "features", "storage", "README.md"));
2140
- await writeTextFile(join10(dir, "README.md"), readme, ctx);
2164
+ const readme = await readTextFile(join11(templatesRoot, "features", "storage", "README.md"));
2165
+ await writeTextFile(join11(dir, "README.md"), readme, ctx);
2141
2166
  const storageClient = await readTextFile(
2142
- join10(templatesRoot, "features", "storage", isTs ? "storage.ts" : "storage.js")
2167
+ join11(templatesRoot, "features", "storage", isTs ? "storage.ts" : "storage.js")
2143
2168
  );
2144
- await writeTextFile(join10(libDir, isTs ? "storage.ts" : "storage.js"), storageClient, ctx);
2145
- await appendEnvLine(join10(projectRoot, ".env.example"), 'CLOUDINARY_URL=""', ctx);
2169
+ await writeTextFile(join11(libDir, isTs ? "storage.ts" : "storage.js"), storageClient, ctx);
2170
+ await appendEnvLine(join11(projectRoot, ".env.example"), 'CLOUDINARY_URL=""', ctx);
2146
2171
  }
2147
2172
  if (config.features.includes("payments")) {
2148
- const dir = join10(projectRoot, "features", "payments");
2173
+ const dir = join11(projectRoot, "features", "payments");
2149
2174
  await ensureDir(dir, ctx);
2150
2175
  await ensureDir(libDir, ctx);
2151
- const readme = await readTextFile(join10(templatesRoot, "features", "payments", "README.md"));
2176
+ const readme = await readTextFile(join11(templatesRoot, "features", "payments", "README.md"));
2152
2177
  const stripeClient = await readTextFile(
2153
- join10(templatesRoot, "features", "payments", isTs ? "stripe.ts" : "stripe.js")
2178
+ join11(templatesRoot, "features", "payments", isTs ? "stripe.ts" : "stripe.js")
2154
2179
  );
2155
- await writeTextFile(join10(dir, "README.md"), readme, ctx);
2156
- await writeTextFile(join10(libDir, isTs ? "stripe.ts" : "stripe.js"), stripeClient, ctx);
2157
- await appendEnvLine(join10(projectRoot, ".env.example"), 'STRIPE_SECRET_KEY=""', ctx);
2180
+ await writeTextFile(join11(dir, "README.md"), readme, ctx);
2181
+ await writeTextFile(join11(libDir, isTs ? "stripe.ts" : "stripe.js"), stripeClient, ctx);
2182
+ await appendEnvLine(join11(projectRoot, ".env.example"), 'STRIPE_SECRET_KEY=""', ctx);
2158
2183
  }
2159
2184
  if (config.features.includes("analytics")) {
2160
- const dir = join10(projectRoot, "features", "analytics");
2185
+ const dir = join11(projectRoot, "features", "analytics");
2161
2186
  await ensureDir(dir, ctx);
2162
2187
  await ensureDir(libDir, ctx);
2163
- const readme = await readTextFile(join10(templatesRoot, "features", "analytics", "README.md"));
2188
+ const readme = await readTextFile(join11(templatesRoot, "features", "analytics", "README.md"));
2164
2189
  const client = await readTextFile(
2165
- join10(templatesRoot, "features", "analytics", isTs ? "posthog.ts" : "posthog.js")
2190
+ join11(templatesRoot, "features", "analytics", isTs ? "posthog.ts" : "posthog.js")
2166
2191
  );
2167
- await writeTextFile(join10(dir, "README.md"), readme, ctx);
2168
- await writeTextFile(join10(libDir, isTs ? "posthog.ts" : "posthog.js"), client, ctx);
2169
- await appendEnvLine(join10(projectRoot, ".env.example"), 'NEXT_PUBLIC_POSTHOG_KEY=""', ctx);
2170
- await appendEnvLine(join10(projectRoot, ".env.example"), 'NEXT_PUBLIC_POSTHOG_HOST=""', ctx);
2192
+ await writeTextFile(join11(dir, "README.md"), readme, ctx);
2193
+ await writeTextFile(join11(libDir, isTs ? "posthog.ts" : "posthog.js"), client, ctx);
2194
+ await appendEnvLine(join11(projectRoot, ".env.example"), 'NEXT_PUBLIC_POSTHOG_KEY=""', ctx);
2195
+ await appendEnvLine(join11(projectRoot, ".env.example"), 'NEXT_PUBLIC_POSTHOG_HOST=""', ctx);
2171
2196
  }
2172
2197
  if (config.features.includes("error-tracking")) {
2173
- const dir = join10(projectRoot, "features", "error-tracking");
2198
+ const dir = join11(projectRoot, "features", "error-tracking");
2174
2199
  await ensureDir(dir, ctx);
2175
2200
  await ensureDir(libDir, ctx);
2176
- const readme = await readTextFile(join10(templatesRoot, "features", "error-tracking", "README.md"));
2201
+ const readme = await readTextFile(join11(templatesRoot, "features", "error-tracking", "README.md"));
2177
2202
  const client = await readTextFile(
2178
- join10(templatesRoot, "features", "error-tracking", isTs ? "sentry.ts" : "sentry.js")
2203
+ join11(templatesRoot, "features", "error-tracking", isTs ? "sentry.ts" : "sentry.js")
2179
2204
  );
2180
- await writeTextFile(join10(dir, "README.md"), readme, ctx);
2181
- await writeTextFile(join10(libDir, isTs ? "sentry.ts" : "sentry.js"), client, ctx);
2182
- await appendEnvLine(join10(projectRoot, ".env.example"), 'SENTRY_DSN=""', ctx);
2205
+ await writeTextFile(join11(dir, "README.md"), readme, ctx);
2206
+ await writeTextFile(join11(libDir, isTs ? "sentry.ts" : "sentry.js"), client, ctx);
2207
+ await appendEnvLine(join11(projectRoot, ".env.example"), 'SENTRY_DSN=""', ctx);
2183
2208
  }
2184
2209
  }
2185
2210
 
@@ -2316,7 +2341,7 @@ function runInstall(pm, cwd) {
2316
2341
  }
2317
2342
 
2318
2343
  // src/cli/commands/create.ts
2319
- import { join as join11, resolve } from "path";
2344
+ import { join as join12, resolve } from "path";
2320
2345
  function parseCsv(input) {
2321
2346
  if (!input) return void 0;
2322
2347
  return input.split(",").map((a) => a.trim()).filter(Boolean);
@@ -2341,7 +2366,7 @@ var createCommand = new Command("create").argument("[project-name]", "name of th
2341
2366
  const outDir = options.outDir ? resolve(options.outDir) : process.cwd();
2342
2367
  await runGenerators(outDir, config, ctx);
2343
2368
  if (options.install !== false && !options.dryRun) {
2344
- const projectRoot = join11(outDir, config.projectName);
2369
+ const projectRoot = join12(outDir, config.projectName);
2345
2370
  logger.info("Installing dependencies...");
2346
2371
  await runInstall(config.packageManager, projectRoot);
2347
2372
  }
@@ -2519,7 +2544,7 @@ async function syncPackageJson(path, oldConfig, newConfig) {
2519
2544
  }
2520
2545
 
2521
2546
  // src/cli/commands/add.ts
2522
- import { dirname as dirname3, join as join12 } from "path";
2547
+ import { dirname as dirname4, join as join13 } from "path";
2523
2548
  function parseFeature(feature) {
2524
2549
  const parts = feature.split(":");
2525
2550
  if (parts.length !== 2 || !parts[0] || !parts[1]) {
@@ -2539,14 +2564,14 @@ var addCommand = new Command3("add").argument("<feature>", "feature to add (cate
2539
2564
  validateDependencies(next);
2540
2565
  await writeProjectConfig(cwd, next);
2541
2566
  await syncPackageJson(`${cwd}/package.json`, current, next);
2542
- const root = dirname3(cwd);
2567
+ const root = dirname4(cwd);
2543
2568
  if (category === "ui") await generateUiFiles(root, next);
2544
2569
  if (category === "database" || category === "orm") await generateDatabaseFiles(root, next);
2545
2570
  if (category === "auth") await generateAuthFiles(root, next);
2546
2571
  if (category === "api") await generateApiFiles(root, next);
2547
2572
  if (category === "feature") await generateFeatureFiles(root, next);
2548
2573
  const readme = buildProjectReadme(next);
2549
- await writeTextFile(join12(cwd, "README.md"), readme + "\n");
2574
+ await writeTextFile(join13(cwd, "README.md"), readme + "\n");
2550
2575
  logger.info(`Added ${feature}`);
2551
2576
  } catch (err) {
2552
2577
  logger.error(err instanceof Error ? err.message : String(err));
@@ -2558,188 +2583,188 @@ var addCommand = new Command3("add").argument("<feature>", "feature to add (cate
2558
2583
  import { Command as Command4 } from "commander";
2559
2584
 
2560
2585
  // src/utils/feature-cleanup.ts
2561
- import { join as join13 } from "path";
2586
+ import { join as join14 } from "path";
2562
2587
  async function cleanupFeature(cwd, config, category, value) {
2563
2588
  const root = cwd;
2564
2589
  if (category === "ui") {
2565
2590
  if (config.ui.library === "tailwind") {
2566
- await removePath(join13(root, "tailwind.config.js"));
2567
- await removePath(join13(root, "postcss.config.js"));
2568
- await removePath(join13(root, "src", "styles.css"));
2569
- await removePath(join13(root, "src", "components", "ui-demo.tsx"));
2570
- await removePath(join13(root, "src", "components", "ui-demo.jsx"));
2591
+ await removePath(join14(root, "tailwind.config.js"));
2592
+ await removePath(join14(root, "postcss.config.js"));
2593
+ await removePath(join14(root, "src", "styles.css"));
2594
+ await removePath(join14(root, "src", "components", "ui-demo.tsx"));
2595
+ await removePath(join14(root, "src", "components", "ui-demo.jsx"));
2571
2596
  }
2572
2597
  if (config.ui.library === "shadcn") {
2573
- await removePath(join13(root, "components"));
2574
- await removePath(join13(root, "components.json"));
2575
- await removePath(join13(root, "src", "lib", "utils.ts"));
2576
- await removePath(join13(root, "src", "lib", "utils.js"));
2577
- await removePath(join13(root, "src", "components", "ui"));
2578
- await removePath(join13(root, "src", "components", "ui-demo.tsx"));
2579
- await removePath(join13(root, "src", "components", "ui-demo.jsx"));
2598
+ await removePath(join14(root, "components"));
2599
+ await removePath(join14(root, "components.json"));
2600
+ await removePath(join14(root, "src", "lib", "utils.ts"));
2601
+ await removePath(join14(root, "src", "lib", "utils.js"));
2602
+ await removePath(join14(root, "src", "components", "ui"));
2603
+ await removePath(join14(root, "src", "components", "ui-demo.tsx"));
2604
+ await removePath(join14(root, "src", "components", "ui-demo.jsx"));
2580
2605
  }
2581
2606
  if (config.ui.library === "mui" || config.ui.library === "chakra" || config.ui.library === "mantine" || config.ui.library === "antd" || config.ui.library === "nextui") {
2582
- await removePath(join13(root, "components"));
2583
- await removePath(join13(root, "src", "theme.ts"));
2584
- await removePath(join13(root, "src", "theme.js"));
2585
- await removePath(join13(root, "src", "components", "ui-demo.tsx"));
2586
- await removePath(join13(root, "src", "components", "ui-demo.jsx"));
2607
+ await removePath(join14(root, "components"));
2608
+ await removePath(join14(root, "src", "theme.ts"));
2609
+ await removePath(join14(root, "src", "theme.js"));
2610
+ await removePath(join14(root, "src", "components", "ui-demo.tsx"));
2611
+ await removePath(join14(root, "src", "components", "ui-demo.jsx"));
2587
2612
  }
2588
2613
  }
2589
2614
  if (category === "auth") {
2590
2615
  if (config.auth.provider === "nextauth") {
2591
- await removePath(join13(root, "app", "api", "auth"));
2592
- await removePath(join13(root, "app", "auth", "protected"));
2593
- await removePath(join13(root, "app", "auth", "signin"));
2594
- await removeEnvKey(join13(root, ".env.example"), "NEXTAUTH_SECRET");
2595
- await removeEnvKey(join13(root, ".env.example"), "NEXTAUTH_URL");
2616
+ await removePath(join14(root, "app", "api", "auth"));
2617
+ await removePath(join14(root, "app", "auth", "protected"));
2618
+ await removePath(join14(root, "app", "auth", "signin"));
2619
+ await removeEnvKey(join14(root, ".env.example"), "NEXTAUTH_SECRET");
2620
+ await removeEnvKey(join14(root, ".env.example"), "NEXTAUTH_URL");
2596
2621
  }
2597
2622
  if (config.auth.provider === "clerk") {
2598
- await removePath(join13(root, "middleware.ts"));
2599
- await removePath(join13(root, "middleware.js"));
2600
- await removePath(join13(root, "src", "lib", "clerk.ts"));
2601
- await removePath(join13(root, "src", "lib", "clerk.js"));
2602
- await removePath(join13(root, "app", "auth", "protected"));
2603
- await removePath(join13(root, "app", "auth", "signin"));
2604
- await removeEnvKey(join13(root, ".env.example"), "CLERK_SECRET_KEY");
2605
- await removeEnvKey(join13(root, ".env.example"), "NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY");
2623
+ await removePath(join14(root, "middleware.ts"));
2624
+ await removePath(join14(root, "middleware.js"));
2625
+ await removePath(join14(root, "src", "lib", "clerk.ts"));
2626
+ await removePath(join14(root, "src", "lib", "clerk.js"));
2627
+ await removePath(join14(root, "app", "auth", "protected"));
2628
+ await removePath(join14(root, "app", "auth", "signin"));
2629
+ await removeEnvKey(join14(root, ".env.example"), "CLERK_SECRET_KEY");
2630
+ await removeEnvKey(join14(root, ".env.example"), "NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY");
2606
2631
  }
2607
2632
  if (config.auth.provider === "supabase") {
2608
- await removePath(join13(root, "src", "lib", "supabase.ts"));
2609
- await removePath(join13(root, "src", "lib", "supabase.js"));
2610
- await removePath(join13(root, "src", "lib", "supabase-server.ts"));
2611
- await removePath(join13(root, "src", "lib", "supabase-server.js"));
2612
- await removePath(join13(root, "app", "auth", "protected"));
2613
- await removePath(join13(root, "app", "auth", "signin"));
2614
- await removePath(join13(root, "src", "auth", "signin.tsx"));
2615
- await removePath(join13(root, "src", "auth", "signin.jsx"));
2616
- await removeEnvKey(join13(root, ".env.example"), "NEXT_PUBLIC_SUPABASE_URL");
2617
- await removeEnvKey(join13(root, ".env.example"), "NEXT_PUBLIC_SUPABASE_ANON_KEY");
2618
- }
2619
- await removePath(join13(root, "auth"));
2633
+ await removePath(join14(root, "src", "lib", "supabase.ts"));
2634
+ await removePath(join14(root, "src", "lib", "supabase.js"));
2635
+ await removePath(join14(root, "src", "lib", "supabase-server.ts"));
2636
+ await removePath(join14(root, "src", "lib", "supabase-server.js"));
2637
+ await removePath(join14(root, "app", "auth", "protected"));
2638
+ await removePath(join14(root, "app", "auth", "signin"));
2639
+ await removePath(join14(root, "src", "auth", "signin.tsx"));
2640
+ await removePath(join14(root, "src", "auth", "signin.jsx"));
2641
+ await removeEnvKey(join14(root, ".env.example"), "NEXT_PUBLIC_SUPABASE_URL");
2642
+ await removeEnvKey(join14(root, ".env.example"), "NEXT_PUBLIC_SUPABASE_ANON_KEY");
2643
+ }
2644
+ await removePath(join14(root, "auth"));
2620
2645
  }
2621
2646
  if (category === "api") {
2622
2647
  if (config.api.type === "rest") {
2623
- await removePath(join13(root, "app", "api", "hello"));
2624
- await removePath(join13(root, "app", "api", "users"));
2625
- await removePath(join13(root, "app", "examples"));
2626
- await removePath(join13(root, "src", "server"));
2627
- await removePath(join13(root, "src", "api"));
2628
- await removePath(join13(root, "src", "api", "client-usage.tsx"));
2629
- await removePath(join13(root, "src", "api", "client-usage.jsx"));
2648
+ await removePath(join14(root, "app", "api", "hello"));
2649
+ await removePath(join14(root, "app", "api", "users"));
2650
+ await removePath(join14(root, "app", "examples"));
2651
+ await removePath(join14(root, "src", "server"));
2652
+ await removePath(join14(root, "src", "api"));
2653
+ await removePath(join14(root, "src", "api", "client-usage.tsx"));
2654
+ await removePath(join14(root, "src", "api", "client-usage.jsx"));
2630
2655
  }
2631
2656
  if (config.api.type === "trpc") {
2632
- await removePath(join13(root, "app", "api", "trpc"));
2633
- await removePath(join13(root, "app", "examples"));
2634
- await removePath(join13(root, "src", "server", "api"));
2635
- await removePath(join13(root, "src", "trpc"));
2636
- await removePath(join13(root, "src", "trpc", "client-usage.tsx"));
2637
- await removePath(join13(root, "src", "trpc", "client-usage.jsx"));
2638
- await removePath(join13(root, "src", "server"));
2657
+ await removePath(join14(root, "app", "api", "trpc"));
2658
+ await removePath(join14(root, "app", "examples"));
2659
+ await removePath(join14(root, "src", "server", "api"));
2660
+ await removePath(join14(root, "src", "trpc"));
2661
+ await removePath(join14(root, "src", "trpc", "client-usage.tsx"));
2662
+ await removePath(join14(root, "src", "trpc", "client-usage.jsx"));
2663
+ await removePath(join14(root, "src", "server"));
2639
2664
  }
2640
2665
  if (config.api.type === "graphql") {
2641
- await removePath(join13(root, "app", "api", "graphql"));
2642
- await removePath(join13(root, "app", "examples"));
2643
- await removePath(join13(root, "src", "graphql"));
2644
- await removePath(join13(root, "src", "server"));
2645
- await removePath(join13(root, "src", "graphql", "client-usage.tsx"));
2646
- await removePath(join13(root, "src", "graphql", "client-usage.jsx"));
2666
+ await removePath(join14(root, "app", "api", "graphql"));
2667
+ await removePath(join14(root, "app", "examples"));
2668
+ await removePath(join14(root, "src", "graphql"));
2669
+ await removePath(join14(root, "src", "server"));
2670
+ await removePath(join14(root, "src", "graphql", "client-usage.tsx"));
2671
+ await removePath(join14(root, "src", "graphql", "client-usage.jsx"));
2647
2672
  }
2648
- await removePath(join13(root, "api"));
2673
+ await removePath(join14(root, "api"));
2649
2674
  }
2650
2675
  if (category === "database") {
2651
2676
  if (config.database.orm === "drizzle") {
2652
- await removePath(join13(root, "drizzle.config.ts"));
2653
- await removePath(join13(root, "drizzle"));
2677
+ await removePath(join14(root, "drizzle.config.ts"));
2678
+ await removePath(join14(root, "drizzle"));
2654
2679
  }
2655
2680
  if (config.database.orm === "prisma") {
2656
- await removePath(join13(root, "prisma"));
2657
- await removePath(join13(root, "src", "db", "prisma.ts"));
2658
- await removePath(join13(root, "src", "db", "prisma.js"));
2659
- await removePath(join13(root, "src", "db", "prisma-example.ts"));
2660
- await removePath(join13(root, "src", "db", "prisma-example.js"));
2681
+ await removePath(join14(root, "prisma"));
2682
+ await removePath(join14(root, "src", "db", "prisma.ts"));
2683
+ await removePath(join14(root, "src", "db", "prisma.js"));
2684
+ await removePath(join14(root, "src", "db", "prisma-example.ts"));
2685
+ await removePath(join14(root, "src", "db", "prisma-example.js"));
2661
2686
  }
2662
2687
  if (config.database.orm === "mongoose") {
2663
- await removePath(join13(root, "src", "db", "mongoose.ts"));
2664
- await removePath(join13(root, "src", "db", "mongoose.js"));
2665
- await removePath(join13(root, "src", "db", "mongoose-model.ts"));
2666
- await removePath(join13(root, "src", "db", "mongoose-model.js"));
2688
+ await removePath(join14(root, "src", "db", "mongoose.ts"));
2689
+ await removePath(join14(root, "src", "db", "mongoose.js"));
2690
+ await removePath(join14(root, "src", "db", "mongoose-model.ts"));
2691
+ await removePath(join14(root, "src", "db", "mongoose-model.js"));
2667
2692
  }
2668
2693
  if (config.database.orm === "typeorm") {
2669
- await removePath(join13(root, "src", "db", "data-source.ts"));
2670
- await removePath(join13(root, "src", "db", "data-source.js"));
2671
- await removePath(join13(root, "src", "db", "entities"));
2672
- await removePath(join13(root, "src", "db", "migrations"));
2694
+ await removePath(join14(root, "src", "db", "data-source.ts"));
2695
+ await removePath(join14(root, "src", "db", "data-source.js"));
2696
+ await removePath(join14(root, "src", "db", "entities"));
2697
+ await removePath(join14(root, "src", "db", "migrations"));
2673
2698
  }
2674
- await removeEnvKey(join13(root, ".env.example"), "DATABASE_URL");
2675
- await removeEnvKey(join13(root, ".env.example"), "NEON_API_KEY");
2676
- await removeEnvKey(join13(root, ".env.example"), "NEON_PROJECT_ID");
2677
- await removeEnvKey(join13(root, ".env.example"), "SUPABASE_URL");
2678
- await removeEnvKey(join13(root, ".env.example"), "SUPABASE_ANON_KEY");
2699
+ await removeEnvKey(join14(root, ".env.example"), "DATABASE_URL");
2700
+ await removeEnvKey(join14(root, ".env.example"), "NEON_API_KEY");
2701
+ await removeEnvKey(join14(root, ".env.example"), "NEON_PROJECT_ID");
2702
+ await removeEnvKey(join14(root, ".env.example"), "SUPABASE_URL");
2703
+ await removeEnvKey(join14(root, ".env.example"), "SUPABASE_ANON_KEY");
2679
2704
  }
2680
2705
  if (category === "orm") {
2681
2706
  if (config.database.orm === "drizzle") {
2682
- await removePath(join13(root, "drizzle.config.ts"));
2683
- await removePath(join13(root, "drizzle"));
2707
+ await removePath(join14(root, "drizzle.config.ts"));
2708
+ await removePath(join14(root, "drizzle"));
2684
2709
  }
2685
2710
  if (config.database.orm === "prisma") {
2686
- await removePath(join13(root, "prisma"));
2687
- await removePath(join13(root, "src", "db", "prisma.ts"));
2688
- await removePath(join13(root, "src", "db", "prisma.js"));
2689
- await removePath(join13(root, "src", "db", "prisma-example.ts"));
2690
- await removePath(join13(root, "src", "db", "prisma-example.js"));
2711
+ await removePath(join14(root, "prisma"));
2712
+ await removePath(join14(root, "src", "db", "prisma.ts"));
2713
+ await removePath(join14(root, "src", "db", "prisma.js"));
2714
+ await removePath(join14(root, "src", "db", "prisma-example.ts"));
2715
+ await removePath(join14(root, "src", "db", "prisma-example.js"));
2691
2716
  }
2692
2717
  if (config.database.orm === "mongoose") {
2693
- await removePath(join13(root, "src", "db", "mongoose.ts"));
2694
- await removePath(join13(root, "src", "db", "mongoose.js"));
2695
- await removePath(join13(root, "src", "db", "mongoose-model.ts"));
2696
- await removePath(join13(root, "src", "db", "mongoose-model.js"));
2718
+ await removePath(join14(root, "src", "db", "mongoose.ts"));
2719
+ await removePath(join14(root, "src", "db", "mongoose.js"));
2720
+ await removePath(join14(root, "src", "db", "mongoose-model.ts"));
2721
+ await removePath(join14(root, "src", "db", "mongoose-model.js"));
2697
2722
  }
2698
2723
  if (config.database.orm === "typeorm") {
2699
- await removePath(join13(root, "src", "db", "data-source.ts"));
2700
- await removePath(join13(root, "src", "db", "data-source.js"));
2701
- await removePath(join13(root, "src", "db", "entities"));
2702
- await removePath(join13(root, "src", "db", "migrations"));
2724
+ await removePath(join14(root, "src", "db", "data-source.ts"));
2725
+ await removePath(join14(root, "src", "db", "data-source.js"));
2726
+ await removePath(join14(root, "src", "db", "entities"));
2727
+ await removePath(join14(root, "src", "db", "migrations"));
2703
2728
  }
2704
2729
  }
2705
2730
  if (category === "feature") {
2706
2731
  const targets = value ? [value] : config.features;
2707
2732
  if (targets.includes("email")) {
2708
- await removePath(join13(root, "features", "email"));
2709
- await removeEnvKey(join13(root, ".env.example"), "RESEND_API_KEY");
2710
- await removePath(join13(root, "src", "lib", "resend.ts"));
2711
- await removePath(join13(root, "src", "lib", "resend.js"));
2733
+ await removePath(join14(root, "features", "email"));
2734
+ await removeEnvKey(join14(root, ".env.example"), "RESEND_API_KEY");
2735
+ await removePath(join14(root, "src", "lib", "resend.ts"));
2736
+ await removePath(join14(root, "src", "lib", "resend.js"));
2712
2737
  }
2713
2738
  if (targets.includes("storage")) {
2714
- await removePath(join13(root, "features", "storage"));
2715
- await removeEnvKey(join13(root, ".env.example"), "CLOUDINARY_URL");
2716
- await removePath(join13(root, "src", "lib", "storage.ts"));
2717
- await removePath(join13(root, "src", "lib", "storage.js"));
2739
+ await removePath(join14(root, "features", "storage"));
2740
+ await removeEnvKey(join14(root, ".env.example"), "CLOUDINARY_URL");
2741
+ await removePath(join14(root, "src", "lib", "storage.ts"));
2742
+ await removePath(join14(root, "src", "lib", "storage.js"));
2718
2743
  }
2719
2744
  if (targets.includes("payments")) {
2720
- await removePath(join13(root, "features", "payments"));
2721
- await removeEnvKey(join13(root, ".env.example"), "STRIPE_SECRET_KEY");
2722
- await removePath(join13(root, "src", "lib", "stripe.ts"));
2723
- await removePath(join13(root, "src", "lib", "stripe.js"));
2745
+ await removePath(join14(root, "features", "payments"));
2746
+ await removeEnvKey(join14(root, ".env.example"), "STRIPE_SECRET_KEY");
2747
+ await removePath(join14(root, "src", "lib", "stripe.ts"));
2748
+ await removePath(join14(root, "src", "lib", "stripe.js"));
2724
2749
  }
2725
2750
  if (targets.includes("analytics")) {
2726
- await removePath(join13(root, "features", "analytics"));
2727
- await removeEnvKey(join13(root, ".env.example"), "NEXT_PUBLIC_POSTHOG_KEY");
2728
- await removeEnvKey(join13(root, ".env.example"), "NEXT_PUBLIC_POSTHOG_HOST");
2729
- await removePath(join13(root, "src", "lib", "posthog.ts"));
2730
- await removePath(join13(root, "src", "lib", "posthog.js"));
2751
+ await removePath(join14(root, "features", "analytics"));
2752
+ await removeEnvKey(join14(root, ".env.example"), "NEXT_PUBLIC_POSTHOG_KEY");
2753
+ await removeEnvKey(join14(root, ".env.example"), "NEXT_PUBLIC_POSTHOG_HOST");
2754
+ await removePath(join14(root, "src", "lib", "posthog.ts"));
2755
+ await removePath(join14(root, "src", "lib", "posthog.js"));
2731
2756
  }
2732
2757
  if (targets.includes("error-tracking")) {
2733
- await removePath(join13(root, "features", "error-tracking"));
2734
- await removeEnvKey(join13(root, ".env.example"), "SENTRY_DSN");
2735
- await removePath(join13(root, "src", "lib", "sentry.ts"));
2736
- await removePath(join13(root, "src", "lib", "sentry.js"));
2758
+ await removePath(join14(root, "features", "error-tracking"));
2759
+ await removeEnvKey(join14(root, ".env.example"), "SENTRY_DSN");
2760
+ await removePath(join14(root, "src", "lib", "sentry.ts"));
2761
+ await removePath(join14(root, "src", "lib", "sentry.js"));
2737
2762
  }
2738
2763
  }
2739
2764
  }
2740
2765
 
2741
2766
  // src/cli/commands/remove.ts
2742
- import { join as join14 } from "path";
2767
+ import { join as join15 } from "path";
2743
2768
  function parseFeature2(feature) {
2744
2769
  const parts = feature.split(":");
2745
2770
  if (parts.length !== 2 || !parts[0] || !parts[1]) {
@@ -2798,7 +2823,7 @@ var removeCommand = new Command4("remove").argument("<feature>", "feature to rem
2798
2823
  await writeProjectConfig(cwd, next);
2799
2824
  await syncPackageJson(`${cwd}/package.json`, current, next);
2800
2825
  const readme = buildProjectReadme(next);
2801
- await writeTextFile(join14(cwd, "README.md"), readme + "\n");
2826
+ await writeTextFile(join15(cwd, "README.md"), readme + "\n");
2802
2827
  logger.info(`Removed ${feature}`);
2803
2828
  } catch (err) {
2804
2829
  logger.error(err instanceof Error ? err.message : String(err));
@@ -2808,13 +2833,13 @@ var removeCommand = new Command4("remove").argument("<feature>", "feature to rem
2808
2833
 
2809
2834
  // src/cli/commands/update.ts
2810
2835
  import { Command as Command5 } from "commander";
2811
- import { join as join15 } from "path";
2836
+ import { join as join16 } from "path";
2812
2837
  import { readFile as readFile5 } from "fs/promises";
2813
2838
  var updateCommand = new Command5("update").option("--check", "check for updates").option("--major", "allow major updates").option("--live", "compare against latest registry versions").action(async (options) => {
2814
2839
  try {
2815
2840
  const cwd = process.cwd();
2816
2841
  const config = await readProjectConfig(cwd);
2817
- const pkgPath = join15(cwd, "package.json");
2842
+ const pkgPath = join16(cwd, "package.json");
2818
2843
  if (options.check) {
2819
2844
  const pkg = JSON.parse(await readFile5(pkgPath, "utf8"));
2820
2845
  const expectedScripts = resolveScripts(config);
@@ -2884,7 +2909,7 @@ var updateCommand = new Command5("update").option("--check", "check for updates"
2884
2909
  await writePackageJson(pkgPath, pkg);
2885
2910
  }
2886
2911
  const readme = buildProjectReadme(config);
2887
- await writeTextFile(join15(cwd, "README.md"), readme + "\n");
2912
+ await writeTextFile(join16(cwd, "README.md"), readme + "\n");
2888
2913
  logger.info("Project updated.");
2889
2914
  } catch (err) {
2890
2915
  logger.error(err instanceof Error ? err.message : String(err));
@@ -2899,13 +2924,13 @@ function parseMajor(version2) {
2899
2924
 
2900
2925
  // src/cli/commands/doctor.ts
2901
2926
  import { Command as Command6 } from "commander";
2902
- import { existsSync as existsSync4 } from "fs";
2903
- import { join as join17 } from "path";
2927
+ import { existsSync as existsSync5 } from "fs";
2928
+ import { join as join18 } from "path";
2904
2929
 
2905
2930
  // src/utils/doctor.ts
2906
- import { existsSync as existsSync3 } from "fs";
2931
+ import { existsSync as existsSync4 } from "fs";
2907
2932
  import { readFile as readFile6 } from "fs/promises";
2908
- import { join as join16, dirname as dirname4, basename } from "path";
2933
+ import { join as join17, dirname as dirname5, basename } from "path";
2909
2934
  function requiredEnvKeys(config) {
2910
2935
  const keys = [];
2911
2936
  if (config.database.provider !== "none") keys.push("DATABASE_URL");
@@ -2934,21 +2959,21 @@ function agentFiles(agent) {
2934
2959
  return files;
2935
2960
  }
2936
2961
  async function checkProject(cwd) {
2937
- const configPath = join16(cwd, "stackforge.json");
2938
- const pkgPath = join16(cwd, "package.json");
2939
- const envPath = join16(cwd, ".env.example");
2962
+ const configPath = join17(cwd, "stackforge.json");
2963
+ const pkgPath = join17(cwd, "package.json");
2964
+ const envPath = join17(cwd, ".env.example");
2940
2965
  const issues = [];
2941
- if (!existsSync3(configPath)) {
2966
+ if (!existsSync4(configPath)) {
2942
2967
  return {
2943
2968
  issues: ["Missing stackforge.json. Run from a StackForge project root."],
2944
2969
  config: void 0,
2945
2970
  pkgPath,
2946
2971
  envPath,
2947
2972
  hasConfig: false,
2948
- hasPackageJson: existsSync3(pkgPath)
2973
+ hasPackageJson: existsSync4(pkgPath)
2949
2974
  };
2950
2975
  }
2951
- if (!existsSync3(pkgPath)) {
2976
+ if (!existsSync4(pkgPath)) {
2952
2977
  return {
2953
2978
  issues: ["Missing package.json"],
2954
2979
  config: await readProjectConfig(cwd),
@@ -2978,7 +3003,7 @@ async function checkProject(cwd) {
2978
3003
  }
2979
3004
  }
2980
3005
  let envContent = "";
2981
- if (existsSync3(envPath)) {
3006
+ if (existsSync4(envPath)) {
2982
3007
  envContent = await readFile6(envPath, "utf8");
2983
3008
  }
2984
3009
  const envKeys = new Set(
@@ -2991,25 +3016,25 @@ async function checkProject(cwd) {
2991
3016
  }
2992
3017
  }
2993
3018
  for (const agent of config.aiAgents) {
2994
- const agentRoot = join16(cwd, ".ai-agents", agent);
3019
+ const agentRoot = join17(cwd, ".ai-agents", agent);
2995
3020
  for (const file of agentFiles(agent)) {
2996
- if (!existsSync3(join16(agentRoot, file))) {
3021
+ if (!existsSync4(join17(agentRoot, file))) {
2997
3022
  issues.push(`Missing AI agent file: .ai-agents/${agent}/${file}`);
2998
3023
  }
2999
3024
  }
3000
- if (agent === "claude" && !existsSync3(join16(cwd, ".claude", "claude_desktop_config.json"))) {
3025
+ if (agent === "claude" && !existsSync4(join17(cwd, ".claude", "claude_desktop_config.json"))) {
3001
3026
  issues.push("Missing Claude config: .claude/claude_desktop_config.json");
3002
3027
  }
3003
- if (agent === "codex" && !existsSync3(join16(cwd, ".codex", "functions.json"))) {
3028
+ if (agent === "codex" && !existsSync4(join17(cwd, ".codex", "functions.json"))) {
3004
3029
  issues.push("Missing Codex config: .codex/functions.json");
3005
3030
  }
3006
- if (agent === "cursor" && !existsSync3(join16(cwd, ".cursor", "extensions.json"))) {
3031
+ if (agent === "cursor" && !existsSync4(join17(cwd, ".cursor", "extensions.json"))) {
3007
3032
  issues.push("Missing Cursor config: .cursor/extensions.json");
3008
3033
  }
3009
- if (agent === "windsurf" && !existsSync3(join16(cwd, ".windsurf", "cascade.json"))) {
3034
+ if (agent === "windsurf" && !existsSync4(join17(cwd, ".windsurf", "cascade.json"))) {
3010
3035
  issues.push("Missing Windsurf config: .windsurf/cascade.json");
3011
3036
  }
3012
- if (agent === "tabnine" && !existsSync3(join16(cwd, ".tabnine", "config.json"))) {
3037
+ if (agent === "tabnine" && !existsSync4(join17(cwd, ".tabnine", "config.json"))) {
3013
3038
  issues.push("Missing Tabnine config: .tabnine/config.json");
3014
3039
  }
3015
3040
  }
@@ -3026,7 +3051,7 @@ async function fixProject(result, cwd) {
3026
3051
  const { config, pkgPath, envPath } = result;
3027
3052
  if (!config) return;
3028
3053
  await syncPackageJson(pkgPath, config, config);
3029
- const envContent = existsSync3(envPath) ? await readFile6(envPath, "utf8") : "";
3054
+ const envContent = existsSync4(envPath) ? await readFile6(envPath, "utf8") : "";
3030
3055
  const envKeys = new Set(
3031
3056
  envContent.split(/\r?\n/).map((line) => line.trim()).filter((line) => line && !line.startsWith("#")).map((line) => line.split("=")[0])
3032
3057
  );
@@ -3035,19 +3060,19 @@ async function fixProject(result, cwd) {
3035
3060
  await appendEnvLine(envPath, `${key}=""`);
3036
3061
  }
3037
3062
  if (config.aiAgents.length > 0) {
3038
- const base = basename(cwd) === config.projectName ? dirname4(cwd) : cwd;
3063
+ const base = basename(cwd) === config.projectName ? dirname5(cwd) : cwd;
3039
3064
  await generateAiAgentConfigs(base, config);
3040
3065
  }
3041
3066
  const readme = buildProjectReadme(config);
3042
- await writeTextFile(join16(cwd, "README.md"), readme + "\n");
3067
+ await writeTextFile(join17(cwd, "README.md"), readme + "\n");
3043
3068
  }
3044
3069
 
3045
3070
  // src/cli/commands/doctor.ts
3046
3071
  import { readFile as readFile7 } from "fs/promises";
3047
3072
  var doctorCommand = new Command6("doctor").option("--fix", "apply non-destructive fixes").action(async (options) => {
3048
3073
  const cwd = process.cwd();
3049
- const configPath = join17(cwd, "stackforge.json");
3050
- if (!existsSync4(configPath)) {
3074
+ const configPath = join18(cwd, "stackforge.json");
3075
+ if (!existsSync5(configPath)) {
3051
3076
  logger.error("Missing stackforge.json. Run from a StackForge project root.");
3052
3077
  return;
3053
3078
  }
@@ -3065,8 +3090,8 @@ var doctorCommand = new Command6("doctor").option("--fix", "apply non-destructiv
3065
3090
  logger.error("Failed to read stackforge.json");
3066
3091
  return;
3067
3092
  }
3068
- const pkgPath = join17(cwd, "package.json");
3069
- if (!existsSync4(pkgPath)) {
3093
+ const pkgPath = join18(cwd, "package.json");
3094
+ if (!existsSync5(pkgPath)) {
3070
3095
  logger.error("Missing package.json");
3071
3096
  return;
3072
3097
  }
@@ -3145,11 +3170,11 @@ var listAgentsCommand = new Command10("list-agents").action(async () => {
3145
3170
  // src/cli/commands/migrate.ts
3146
3171
  import { Command as Command11 } from "commander";
3147
3172
  import { readFile as readFile8, writeFile as writeFile5 } from "fs/promises";
3148
- import { join as join18 } from "path";
3173
+ import { join as join19 } from "path";
3149
3174
  var migrateCommand = new Command11("migrate").option("--dry-run", "show planned migration without writing").action(async (options) => {
3150
3175
  try {
3151
3176
  const cwd = process.cwd();
3152
- const path = join18(cwd, "stackforge.json");
3177
+ const path = join19(cwd, "stackforge.json");
3153
3178
  const raw = await readFile8(path, "utf8");
3154
3179
  const parsed = JSON.parse(raw);
3155
3180
  const current = parsed._schemaVersion ?? 0;
@@ -3239,7 +3264,7 @@ var fixCommand = new Command15("fix").description("apply safe fixes to project c
3239
3264
 
3240
3265
  // src/cli/commands/upgrade.ts
3241
3266
  import { Command as Command16 } from "commander";
3242
- import { join as join19, dirname as dirname5 } from "path";
3267
+ import { join as join20, dirname as dirname6 } from "path";
3243
3268
  var upgradeCommand = new Command16("upgrade").option("--preset <name>", "preset to upgrade to").action(async (options) => {
3244
3269
  const cwd = process.cwd();
3245
3270
  const current = await readProjectConfig(cwd);
@@ -3281,8 +3306,8 @@ var upgradeCommand = new Command16("upgrade").option("--preset <name>", "preset
3281
3306
  await cleanupFeature(cwd, current, "feature", feature);
3282
3307
  }
3283
3308
  await writeProjectConfig(cwd, next);
3284
- await syncPackageJson(join19(cwd, "package.json"), current, next);
3285
- const root = dirname5(cwd);
3309
+ await syncPackageJson(join20(cwd, "package.json"), current, next);
3310
+ const root = dirname6(cwd);
3286
3311
  await generateFrontendFiles(root, next);
3287
3312
  await generateUiFiles(root, next);
3288
3313
  await generateDatabaseFiles(root, next);
@@ -3290,7 +3315,7 @@ var upgradeCommand = new Command16("upgrade").option("--preset <name>", "preset
3290
3315
  await generateApiFiles(root, next);
3291
3316
  await generateFeatureFiles(root, next);
3292
3317
  const readme = buildProjectReadme(next);
3293
- await writeTextFile(join19(cwd, "README.md"), readme + "\n");
3318
+ await writeTextFile(join20(cwd, "README.md"), readme + "\n");
3294
3319
  logger.info(`Upgraded project to preset: ${options.preset}`);
3295
3320
  });
3296
3321