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