create-better-fullstack 1.1.16 → 1.2.0

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/README.md CHANGED
@@ -33,7 +33,7 @@ Options:
33
33
  --runtime <runtime> Runtime (bun, node, workers, none)
34
34
  --api <type> API type (trpc, orpc, ts-rest, garph, none)
35
35
  --addons <types...> Additional addons
36
- --examples <types...> Examples to include (todo, ai, none)
36
+ --examples <types...> Examples to include (ai, none)
37
37
  --git / --no-git Initialize git repository
38
38
  --package-manager <pm> Package manager (npm, pnpm, bun)
39
39
  --install / --no-install Install dependencies
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { o as createBtsCli } from "./src-DDAojCKV.mjs";
2
+ import { o as createBtsCli } from "./src-BJjCw5ar.mjs";
3
3
 
4
4
  //#region src/cli.ts
5
5
  createBtsCli().run();
package/dist/index.d.mts CHANGED
@@ -236,7 +236,6 @@ declare const router: {
236
236
  }>>>;
237
237
  examples: z.ZodOptional<z.ZodArray<z.ZodEnum<{
238
238
  none: "none";
239
- todo: "todo";
240
239
  ai: "ai";
241
240
  }>>>;
242
241
  git: z.ZodOptional<z.ZodBoolean>;
@@ -419,6 +418,12 @@ declare const router: {
419
418
  none: "none";
420
419
  zap: "zap";
421
420
  }>>;
421
+ aiDocs: z.ZodOptional<z.ZodArray<z.ZodEnum<{
422
+ none: "none";
423
+ "claude-md": "claude-md";
424
+ "agents-md": "agents-md";
425
+ cursorrules: "cursorrules";
426
+ }>>>;
422
427
  }, z.core.$strip>], null>, _orpc_server0.Schema<{
423
428
  success: boolean;
424
429
  projectConfig: {
@@ -432,7 +437,7 @@ declare const router: {
432
437
  runtime: "none" | "bun" | "node" | "workers";
433
438
  frontend: ("none" | "tanstack-router" | "react-router" | "tanstack-start" | "next" | "nuxt" | "native-bare" | "native-uniwind" | "native-unistyles" | "svelte" | "solid" | "astro" | "qwik" | "angular" | "redwood" | "fresh")[];
434
439
  addons: ("none" | "pwa" | "tauri" | "starlight" | "biome" | "lefthook" | "husky" | "ruler" | "turborepo" | "fumadocs" | "ultracite" | "oxlint" | "opentui" | "wxt" | "msw" | "storybook")[];
435
- examples: ("ai" | "none" | "todo")[];
440
+ examples: ("ai" | "none")[];
436
441
  auth: "none" | "better-auth" | "clerk" | "nextauth" | "stack-auth" | "supabase-auth" | "auth0";
437
442
  payments: "none" | "polar" | "stripe" | "lemon-squeezy" | "paddle" | "dodo";
438
443
  git: boolean;
@@ -480,6 +485,7 @@ declare const router: {
480
485
  goApi: "none" | "grpc-go";
481
486
  goCli: "none" | "cobra" | "bubbletea";
482
487
  goLogging: "none" | "zap";
488
+ aiDocs: ("none" | "claude-md" | "agents-md" | "cursorrules")[];
483
489
  astroIntegration?: "none" | "svelte" | "solid" | "react" | "vue" | undefined;
484
490
  };
485
491
  reproducibleCommand: string;
@@ -510,7 +516,7 @@ declare const router: {
510
516
  runtime: "none" | "bun" | "node" | "workers";
511
517
  frontend: ("none" | "tanstack-router" | "react-router" | "tanstack-start" | "next" | "nuxt" | "native-bare" | "native-uniwind" | "native-unistyles" | "svelte" | "solid" | "astro" | "qwik" | "angular" | "redwood" | "fresh")[];
512
518
  addons: ("none" | "pwa" | "tauri" | "starlight" | "biome" | "lefthook" | "husky" | "ruler" | "turborepo" | "fumadocs" | "ultracite" | "oxlint" | "opentui" | "wxt" | "msw" | "storybook")[];
513
- examples: ("ai" | "none" | "todo")[];
519
+ examples: ("ai" | "none")[];
514
520
  auth: "none" | "better-auth" | "clerk" | "nextauth" | "stack-auth" | "supabase-auth" | "auth0";
515
521
  payments: "none" | "polar" | "stripe" | "lemon-squeezy" | "paddle" | "dodo";
516
522
  git: boolean;
@@ -558,6 +564,7 @@ declare const router: {
558
564
  goApi: "none" | "grpc-go";
559
565
  goCli: "none" | "cobra" | "bubbletea";
560
566
  goLogging: "none" | "zap";
567
+ aiDocs: ("none" | "claude-md" | "agents-md" | "cursorrules")[];
561
568
  astroIntegration?: "none" | "svelte" | "solid" | "react" | "vue" | undefined;
562
569
  };
563
570
  reproducibleCommand: string;
@@ -642,6 +649,7 @@ declare function createVirtual(options: Partial<Omit<types_d_exports.ProjectConf
642
649
  }>;
643
650
  type API = import__better_fullstack_types.API;
644
651
  type Addons = import__better_fullstack_types.Addons;
652
+ type AiDocs = import__better_fullstack_types.AiDocs;
645
653
  type Analytics = import__better_fullstack_types.Analytics;
646
654
  type Animation = import__better_fullstack_types.Animation;
647
655
  type Auth = import__better_fullstack_types.Auth;
@@ -686,4 +694,4 @@ type ServerDeploy = import__better_fullstack_types.ServerDeploy;
686
694
  type Template = import__better_fullstack_types.Template;
687
695
  type UILibrary = import__better_fullstack_types.UILibrary;
688
696
  type WebDeploy = import__better_fullstack_types.WebDeploy;
689
- export { type API, type Addons, type Analytics, type Animation, type Auth, type Backend, type BetterTStackConfig, type CMS, type CSSFramework, type Caching, type CreateInput, type Database, type DatabaseSetup, type DirectoryConflict, EMBEDDED_TEMPLATES, type Ecosystem, type Effect, type Examples, type Frontend, type GeneratorOptions, type GeneratorResult, type GoApi, type GoCli, type GoLogging, type GoOrm, type GoWebFramework, type InitResult, type Logging, type ORM, type PackageManager, type Payments, type PythonAi, type PythonOrm, type PythonQuality, type PythonTaskQueue, type PythonValidation, type PythonWebFramework, type Realtime, type Runtime, type RustApi, type RustCli, type RustFrontend, type RustLibraries, type RustOrm, type RustWebFramework, type ServerDeploy, TEMPLATE_COUNT, type Template, type UILibrary, type VirtualDirectory, type VirtualFile, VirtualFileSystem, type VirtualFileTree, type VirtualNode, type WebDeploy, builder, create, createBtsCli, createVirtual, docs, generateVirtualProject, router, sponsors };
697
+ export { type API, type Addons, type AiDocs, type Analytics, type Animation, type Auth, type Backend, type BetterTStackConfig, type CMS, type CSSFramework, type Caching, type CreateInput, type Database, type DatabaseSetup, type DirectoryConflict, EMBEDDED_TEMPLATES, type Ecosystem, type Effect, type Examples, type Frontend, type GeneratorOptions, type GeneratorResult, type GoApi, type GoCli, type GoLogging, type GoOrm, type GoWebFramework, type InitResult, type Logging, type ORM, type PackageManager, type Payments, type PythonAi, type PythonOrm, type PythonQuality, type PythonTaskQueue, type PythonValidation, type PythonWebFramework, type Realtime, type Runtime, type RustApi, type RustCli, type RustFrontend, type RustLibraries, type RustOrm, type RustWebFramework, type ServerDeploy, TEMPLATE_COUNT, type Template, type UILibrary, type VirtualDirectory, type VirtualFile, VirtualFileSystem, type VirtualFileTree, type VirtualNode, type WebDeploy, builder, create, createBtsCli, createVirtual, docs, generateVirtualProject, router, sponsors };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { a as create, c as docs, d as sponsors, i as builder, l as generateVirtualProject, n as TEMPLATE_COUNT, o as createBtsCli, r as VirtualFileSystem, s as createVirtual, t as EMBEDDED_TEMPLATES, u as router } from "./src-DDAojCKV.mjs";
2
+ import { a as create, c as docs, d as sponsors, i as builder, l as generateVirtualProject, n as TEMPLATE_COUNT, o as createBtsCli, r as VirtualFileSystem, s as createVirtual, t as EMBEDDED_TEMPLATES, u as router } from "./src-BJjCw5ar.mjs";
3
3
 
4
4
  export { EMBEDDED_TEMPLATES, TEMPLATE_COUNT, VirtualFileSystem, builder, create, createBtsCli, createVirtual, docs, generateVirtualProject, router, sponsors };
@@ -266,7 +266,8 @@ const DEFAULT_CONFIG_BASE = {
266
266
  goOrm: "gorm",
267
267
  goApi: "none",
268
268
  goCli: "none",
269
- goLogging: "zap"
269
+ goLogging: "zap",
270
+ aiDocs: ["claude-md"]
270
271
  };
271
272
  function getDefaultConfig() {
272
273
  return {
@@ -277,7 +278,8 @@ function getDefaultConfig() {
277
278
  addons: [...DEFAULT_CONFIG_BASE.addons],
278
279
  examples: [...DEFAULT_CONFIG_BASE.examples],
279
280
  rustLibraries: [...DEFAULT_CONFIG_BASE.rustLibraries],
280
- pythonAi: [...DEFAULT_CONFIG_BASE.pythonAi]
281
+ pythonAi: [...DEFAULT_CONFIG_BASE.pythonAi],
282
+ aiDocs: [...DEFAULT_CONFIG_BASE.aiDocs]
281
283
  };
282
284
  }
283
285
  const DEFAULT_CONFIG = getDefaultConfig();
@@ -950,11 +952,6 @@ function allowedApisForFrontends(frontends = [], astroIntegration) {
950
952
  if (includesAstro && astroIntegration && astroIntegration !== "react") return ["orpc", "none"];
951
953
  return base;
952
954
  }
953
- function isExampleTodoAllowed(backend, database, api) {
954
- if (backend === "convex") return true;
955
- if (database === "none" || api === "none") return false;
956
- return true;
957
- }
958
955
  function isExampleAIAllowed(backend, frontends = []) {
959
956
  if (frontends.includes("solid")) return false;
960
957
  if (backend === "convex") {
@@ -995,13 +992,9 @@ function validatePaymentsCompatibility(payments, auth, _backend, frontends = [])
995
992
  if (web.length === 0 && frontends.length > 0) exitWithError("Polar payments requires a web frontend or no frontend. Please select a web frontend or choose a different payments provider.");
996
993
  }
997
994
  }
998
- function validateExamplesCompatibility(examples, backend, database, frontend, api) {
995
+ function validateExamplesCompatibility(examples, backend, frontend) {
999
996
  const examplesArr = examples ?? [];
1000
997
  if (examplesArr.length === 0 || examplesArr.includes("none")) return;
1001
- if (examplesArr.includes("todo") && backend !== "convex") {
1002
- if (database === "none") exitWithError("The 'todo' example requires a database. Cannot use --examples todo when database is 'none'.");
1003
- if (api === "none") exitWithError("The 'todo' example requires an API layer (tRPC or oRPC). Cannot use --examples todo when api is 'none'.");
1004
- }
1005
998
  if (examplesArr.includes("ai") && (frontend ?? []).includes("solid")) exitWithError("The 'ai' example is not compatible with the Solid frontend.");
1006
999
  if (examplesArr.includes("ai") && backend === "convex") {
1007
1000
  const frontendArr = frontend ?? [];
@@ -1546,6 +1539,42 @@ async function getAIChoice(ai) {
1546
1539
  return response;
1547
1540
  }
1548
1541
 
1542
+ //#endregion
1543
+ //#region src/prompts/ai-docs.ts
1544
+ const AI_DOCS_OPTIONS = [
1545
+ {
1546
+ value: "claude-md",
1547
+ label: "CLAUDE.md",
1548
+ hint: "Claude Code CLI documentation"
1549
+ },
1550
+ {
1551
+ value: "agents-md",
1552
+ label: "Agents.md",
1553
+ hint: "Generic AI assistant documentation"
1554
+ },
1555
+ {
1556
+ value: "cursorrules",
1557
+ label: ".cursorrules",
1558
+ hint: "Cursor IDE rules file"
1559
+ },
1560
+ {
1561
+ value: "none",
1562
+ label: "None",
1563
+ hint: "Skip AI documentation"
1564
+ }
1565
+ ];
1566
+ async function getAiDocsChoice(aiDocs) {
1567
+ if (aiDocs !== void 0) return aiDocs;
1568
+ const response = await navigableMultiselect({
1569
+ message: "Generate AI documentation files?",
1570
+ options: AI_DOCS_OPTIONS,
1571
+ initialValues: DEFAULT_CONFIG.aiDocs
1572
+ });
1573
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
1574
+ if (response.includes("none")) return [];
1575
+ return response;
1576
+ }
1577
+
1549
1578
  //#endregion
1550
1579
  //#region src/prompts/animation.ts
1551
1580
  async function getAnimationChoice(animation, frontends) {
@@ -2237,16 +2266,11 @@ async function getEmailChoice(email, backend) {
2237
2266
 
2238
2267
  //#endregion
2239
2268
  //#region src/prompts/examples.ts
2240
- async function getExamplesChoice(examples, database, frontends, backend, api) {
2269
+ async function getExamplesChoice(examples, frontends, backend) {
2241
2270
  if (examples !== void 0) return examples;
2242
2271
  if (backend === "none") return [];
2243
2272
  let response = [];
2244
2273
  const options = [];
2245
- if (isExampleTodoAllowed(backend, database, api)) options.push({
2246
- value: "todo",
2247
- label: "Todo App",
2248
- hint: "A simple CRUD example app"
2249
- });
2250
2274
  if (isExampleAIAllowed(backend, frontends ?? [])) options.push({
2251
2275
  value: "ai",
2252
2276
  label: "AI Chat",
@@ -2691,6 +2715,18 @@ async function getinstallChoice(install, ecosystem) {
2691
2715
  if (isCancel$1(response$1)) return exitCancelled("Operation cancelled");
2692
2716
  return response$1;
2693
2717
  }
2718
+ if (ecosystem === "go") {
2719
+ if (!await commandExists("go")) {
2720
+ log.warn("Go is not installed. Please install Go from https://go.dev/dl/");
2721
+ return false;
2722
+ }
2723
+ const response$1 = await navigableConfirm({
2724
+ message: "Run go mod tidy?",
2725
+ initialValue: DEFAULT_CONFIG.install
2726
+ });
2727
+ if (isCancel$1(response$1)) return exitCancelled("Operation cancelled");
2728
+ return response$1;
2729
+ }
2694
2730
  const response = await navigableConfirm({
2695
2731
  message: "Install dependencies?",
2696
2732
  initialValue: DEFAULT_CONFIG.install
@@ -3772,7 +3808,7 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
3772
3808
  },
3773
3809
  examples: ({ results }) => {
3774
3810
  if (results.ecosystem !== "typescript") return Promise.resolve([]);
3775
- return getExamplesChoice(flags.examples, results.database, results.frontend, results.backend, results.api);
3811
+ return getExamplesChoice(flags.examples, results.frontend, results.backend);
3776
3812
  },
3777
3813
  dbSetup: ({ results }) => {
3778
3814
  if (results.ecosystem !== "typescript") return Promise.resolve("none");
@@ -3922,6 +3958,7 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
3922
3958
  if (results.ecosystem !== "go") return Promise.resolve("none");
3923
3959
  return getGoLoggingChoice(flags.goLogging);
3924
3960
  },
3961
+ aiDocs: () => getAiDocsChoice(flags.aiDocs),
3925
3962
  git: () => getGitChoice(flags.git),
3926
3963
  packageManager: ({ results }) => {
3927
3964
  if (results.ecosystem === "rust" || results.ecosystem === "python" || results.ecosystem === "go") return Promise.resolve("npm");
@@ -3988,7 +4025,8 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
3988
4025
  goOrm: result.goOrm,
3989
4026
  goApi: result.goApi,
3990
4027
  goCli: result.goCli,
3991
- goLogging: result.goLogging
4028
+ goLogging: result.goLogging,
4029
+ aiDocs: result.aiDocs
3992
4030
  };
3993
4031
  }
3994
4032
 
@@ -4159,6 +4197,11 @@ function generateReproducibleCommand(config) {
4159
4197
  flags.push(`--db-setup ${config.dbSetup}`);
4160
4198
  flags.push(`--web-deploy ${config.webDeploy}`);
4161
4199
  flags.push(`--server-deploy ${config.serverDeploy}`);
4200
+ if (config.aiDocs && config.aiDocs.length > 0) {
4201
+ const validDocs = config.aiDocs.filter((d) => d !== "none");
4202
+ if (validDocs.length > 0) flags.push(`--ai-docs ${validDocs.join(" ")}`);
4203
+ else flags.push("--ai-docs none");
4204
+ } else flags.push("--ai-docs none");
4162
4205
  flags.push(config.git ? "--git" : "--no-git");
4163
4206
  flags.push(`--package-manager ${config.packageManager}`);
4164
4207
  flags.push(config.install ? "--install" : "--no-install");
@@ -4297,7 +4340,7 @@ const TEMPLATE_PRESETS = {
4297
4340
  auth: "better-auth",
4298
4341
  payments: "none",
4299
4342
  addons: ["turborepo"],
4300
- examples: ["todo"],
4343
+ examples: ["none"],
4301
4344
  dbSetup: "mongodb-atlas",
4302
4345
  webDeploy: "none",
4303
4346
  serverDeploy: "none"
@@ -4312,7 +4355,7 @@ const TEMPLATE_PRESETS = {
4312
4355
  auth: "better-auth",
4313
4356
  payments: "none",
4314
4357
  addons: ["turborepo"],
4315
- examples: ["todo"],
4358
+ examples: ["none"],
4316
4359
  dbSetup: "none",
4317
4360
  webDeploy: "none",
4318
4361
  serverDeploy: "none"
@@ -4420,6 +4463,7 @@ function processFlags(options, projectName) {
4420
4463
  if (options.uiLibrary) config.uiLibrary = options.uiLibrary;
4421
4464
  if (options.addons && options.addons.length > 0) config.addons = processArrayOption(options.addons);
4422
4465
  if (options.examples && options.examples.length > 0) config.examples = processArrayOption(options.examples);
4466
+ if (options.aiDocs !== void 0) config.aiDocs = processArrayOption(options.aiDocs);
4423
4467
  return config;
4424
4468
  }
4425
4469
  function getProvidedFlags(options) {
@@ -4880,11 +4924,7 @@ function validateFrontendConstraints(config, providedFlags) {
4880
4924
  const hasWebFrontendFlag = (frontend ?? []).some((f) => isWebFrontend(f));
4881
4925
  validateWebDeployRequiresWebFrontend(config.webDeploy, hasWebFrontendFlag);
4882
4926
  }
4883
- function validateApiConstraints(config, options) {
4884
- if (config.api === "none") {
4885
- if (options.examples?.includes("todo") && options.backend !== "convex" && options.backend !== "none") exitWithError("Cannot use '--examples todo' when '--api' is set to 'none'. The todo example requires an API layer. Please remove 'todo' from --examples or choose an API type.");
4886
- }
4887
- }
4927
+ function validateApiConstraints(_config, _options) {}
4888
4928
  function validateFullConfig(config, providedFlags, options) {
4889
4929
  validateDatabaseOrmAuth(config, providedFlags);
4890
4930
  validateDatabaseSetup(config, providedFlags);
@@ -4895,7 +4935,7 @@ function validateFullConfig(config, providedFlags, options) {
4895
4935
  validateAdonisJSConstraints(config, providedFlags);
4896
4936
  validateBackendConstraints(config, providedFlags, options);
4897
4937
  validateFrontendConstraints(config, providedFlags);
4898
- validateApiConstraints(config, options);
4938
+ /* @__PURE__ */ validateApiConstraints(config, options);
4899
4939
  validateServerDeployRequiresBackend(config.serverDeploy, config.backend);
4900
4940
  validateSelfBackendCompatibility(providedFlags, options, config);
4901
4941
  validateWorkersCompatibility(providedFlags, options, config);
@@ -4905,7 +4945,7 @@ function validateFullConfig(config, providedFlags, options) {
4905
4945
  validateAddonsAgainstFrontends(config.addons, config.frontend, config.auth);
4906
4946
  config.addons = [...new Set(config.addons)];
4907
4947
  }
4908
- validateExamplesCompatibility(config.examples ?? [], config.backend, config.database, config.frontend ?? [], config.api);
4948
+ validateExamplesCompatibility(config.examples ?? [], config.backend, config.frontend ?? []);
4909
4949
  validatePaymentsCompatibility(config.payments, config.auth, config.backend, config.frontend ?? []);
4910
4950
  validateNextAuthCompatibility(config.auth, config.backend, config.frontend ?? []);
4911
4951
  validateStackAuthCompatibility(config.auth, config.backend, config.frontend ?? []);
@@ -4926,7 +4966,7 @@ function validateConfigForProgrammaticUse(config) {
4926
4966
  validateSupabaseAuthCompatibility(config.auth, config.backend, config.frontend ?? []);
4927
4967
  validateAuth0Compatibility(config.auth, config.backend, config.frontend ?? []);
4928
4968
  if (config.addons && config.addons.length > 0) validateAddonsAgainstFrontends(config.addons, config.frontend, config.auth);
4929
- validateExamplesCompatibility(config.examples ?? [], config.backend, config.database, config.frontend ?? [], config.api);
4969
+ validateExamplesCompatibility(config.examples ?? [], config.backend, config.frontend ?? []);
4930
4970
  validateUILibraryFrontendCompatibility(config.uiLibrary, config.frontend ?? [], config.astroIntegration);
4931
4971
  validateUILibraryCSSFrameworkCompatibility(config.uiLibrary, config.cssFramework);
4932
4972
  validatePeerDependencies(config);
@@ -5074,7 +5114,8 @@ async function writeBtsConfig(projectConfig) {
5074
5114
  goOrm: projectConfig.goOrm,
5075
5115
  goApi: projectConfig.goApi,
5076
5116
  goCli: projectConfig.goCli,
5077
- goLogging: projectConfig.goLogging
5117
+ goLogging: projectConfig.goLogging,
5118
+ aiDocs: projectConfig.aiDocs
5078
5119
  };
5079
5120
  const baseContent = {
5080
5121
  $schema: "https://better-fullstack-web.vercel.app/schema.json",
@@ -5132,7 +5173,8 @@ async function writeBtsConfig(projectConfig) {
5132
5173
  goOrm: btsConfig.goOrm,
5133
5174
  goApi: btsConfig.goApi,
5134
5175
  goCli: btsConfig.goCli,
5135
- goLogging: btsConfig.goLogging
5176
+ goLogging: btsConfig.goLogging,
5177
+ aiDocs: btsConfig.aiDocs
5136
5178
  };
5137
5179
  let configContent = JSON.stringify(baseContent);
5138
5180
  const formatResult = JSONC.format(configContent, void 0, {
@@ -6983,6 +7025,20 @@ async function runUvSync({ projectDir }) {
6983
7025
  if (error instanceof Error) consola.error(pc.red(`uv sync error: ${error.message}`));
6984
7026
  }
6985
7027
  }
7028
+ async function runGoModTidy({ projectDir }) {
7029
+ const s = spinner();
7030
+ try {
7031
+ s.start("Running go mod tidy...");
7032
+ await $({
7033
+ cwd: projectDir,
7034
+ stderr: "inherit"
7035
+ })`go mod tidy`;
7036
+ s.stop("Go dependencies installed successfully");
7037
+ } catch (error) {
7038
+ s.stop(pc.red("go mod tidy failed"));
7039
+ if (error instanceof Error) consola.error(pc.red(`go mod tidy error: ${error.message}`));
7040
+ }
7041
+ }
6986
7042
 
6987
7043
  //#endregion
6988
7044
  //#region src/utils/docker-utils.ts
@@ -7042,6 +7098,14 @@ async function displayPostInstallInstructions(config) {
7042
7098
  displayRustInstructions(config);
7043
7099
  return;
7044
7100
  }
7101
+ if (ecosystem === "go") {
7102
+ displayGoInstructions(config);
7103
+ return;
7104
+ }
7105
+ if (ecosystem === "python") {
7106
+ displayPythonInstructions(config);
7107
+ return;
7108
+ }
7045
7109
  const isConvex = backend === "convex";
7046
7110
  const isBackendSelf = backend === "self";
7047
7111
  const runCmd = packageManager === "npm" ? "npm run" : packageManager === "pnpm" ? "pnpm run" : "bun run";
@@ -7251,6 +7315,87 @@ function displayRustInstructions(config) {
7251
7315
  output += pc.cyan("https://github.com/Marve10s/Better-Fullstack");
7252
7316
  consola$1.box(output);
7253
7317
  }
7318
+ function displayGoInstructions(config) {
7319
+ const { relativePath, depsInstalled, goWebFramework, goOrm, goApi, goCli, goLogging } = config;
7320
+ const cdCmd = `cd ${relativePath}`;
7321
+ let output = `${pc.bold("Next steps")}\n${pc.cyan("1.")} ${cdCmd}\n`;
7322
+ let stepCounter = 2;
7323
+ if (!depsInstalled) output += `${pc.cyan(`${stepCounter++}.`)} go mod tidy\n`;
7324
+ output += `${pc.cyan(`${stepCounter++}.`)} go run cmd/server/main.go\n`;
7325
+ output += `\n${pc.bold("Your Go project includes:")}\n`;
7326
+ if (goWebFramework && goWebFramework !== "none") output += `${pc.cyan("•")} Web Framework: ${{
7327
+ gin: "Gin",
7328
+ echo: "Echo"
7329
+ }[goWebFramework] || goWebFramework}\n`;
7330
+ if (goOrm && goOrm !== "none") output += `${pc.cyan("•")} Database: ${{
7331
+ gorm: "GORM",
7332
+ sqlc: "sqlc"
7333
+ }[goOrm] || goOrm}\n`;
7334
+ if (goApi && goApi !== "none") output += `${pc.cyan("•")} API: ${{ "grpc-go": "gRPC-Go" }[goApi] || goApi}\n`;
7335
+ if (goCli && goCli !== "none") output += `${pc.cyan("•")} CLI: ${{
7336
+ cobra: "Cobra",
7337
+ bubbletea: "Bubble Tea"
7338
+ }[goCli] || goCli}\n`;
7339
+ if (goLogging && goLogging !== "none") output += `${pc.cyan("•")} Logging: ${{ zap: "Zap" }[goLogging] || goLogging}\n`;
7340
+ output += `\n${pc.bold("Common Go commands:")}\n`;
7341
+ output += `${pc.cyan("•")} Build: go build ./...\n`;
7342
+ output += `${pc.cyan("•")} Run: go run cmd/server/main.go\n`;
7343
+ output += `${pc.cyan("•")} Test: go test ./...\n`;
7344
+ output += `${pc.cyan("•")} Tidy: go mod tidy\n`;
7345
+ output += `${pc.cyan("•")} Format: go fmt ./...\n`;
7346
+ output += `${pc.cyan("•")} Lint: golangci-lint run\n`;
7347
+ output += `\n${pc.bold("Your project will be available at:")}\n`;
7348
+ output += `${pc.cyan("•")} API: http://localhost:8080\n`;
7349
+ if (goApi === "grpc-go") output += `${pc.cyan("•")} gRPC: localhost:50051\n`;
7350
+ output += `\n${pc.bold("Like Better Fullstack?")} Please consider giving us a star\n on GitHub:\n`;
7351
+ output += pc.cyan("https://github.com/Marve10s/Better-Fullstack");
7352
+ consola$1.box(output);
7353
+ }
7354
+ function displayPythonInstructions(config) {
7355
+ const { relativePath, depsInstalled, pythonWebFramework, pythonOrm, pythonValidation, pythonAi, pythonTaskQueue, pythonQuality } = config;
7356
+ const cdCmd = `cd ${relativePath}`;
7357
+ let runCommand = "uv run uvicorn app.main:app --reload";
7358
+ if (pythonWebFramework === "django") runCommand = "uv run python manage.py runserver";
7359
+ let output = `${pc.bold("Next steps")}\n${pc.cyan("1.")} ${cdCmd}\n`;
7360
+ let stepCounter = 2;
7361
+ if (!depsInstalled) output += `${pc.cyan(`${stepCounter++}.`)} uv sync\n`;
7362
+ output += `${pc.cyan(`${stepCounter++}.`)} ${runCommand}\n`;
7363
+ output += `\n${pc.bold("Your Python project includes:")}\n`;
7364
+ if (pythonWebFramework && pythonWebFramework !== "none") output += `${pc.cyan("•")} Web Framework: ${{
7365
+ fastapi: "FastAPI",
7366
+ django: "Django"
7367
+ }[pythonWebFramework] || pythonWebFramework}\n`;
7368
+ if (pythonOrm && pythonOrm !== "none") output += `${pc.cyan("•")} ORM: ${{
7369
+ sqlalchemy: "SQLAlchemy",
7370
+ sqlmodel: "SQLModel"
7371
+ }[pythonOrm] || pythonOrm}\n`;
7372
+ if (pythonValidation && pythonValidation !== "none") output += `${pc.cyan("•")} Validation: ${{ pydantic: "Pydantic" }[pythonValidation] || pythonValidation}\n`;
7373
+ if (pythonAi && pythonAi.length > 0 && !pythonAi.includes("none")) {
7374
+ const aiNames = {
7375
+ langchain: "LangChain",
7376
+ langgraph: "LangGraph",
7377
+ llamaindex: "LlamaIndex",
7378
+ "openai-sdk": "OpenAI SDK",
7379
+ "anthropic-sdk": "Anthropic SDK",
7380
+ crewai: "CrewAI"
7381
+ };
7382
+ const aiList = pythonAi.filter((ai) => ai !== "none").map((ai) => aiNames[ai] || ai).join(", ");
7383
+ output += `${pc.cyan("•")} AI: ${aiList}\n`;
7384
+ }
7385
+ if (pythonTaskQueue && pythonTaskQueue !== "none") output += `${pc.cyan("•")} Task Queue: ${{ celery: "Celery" }[pythonTaskQueue] || pythonTaskQueue}\n`;
7386
+ if (pythonQuality && pythonQuality !== "none") output += `${pc.cyan("•")} Code Quality: ${{ ruff: "Ruff" }[pythonQuality] || pythonQuality}\n`;
7387
+ output += `\n${pc.bold("Common Python commands:")}\n`;
7388
+ output += `${pc.cyan("•")} Install: uv sync\n`;
7389
+ output += `${pc.cyan("•")} Run: ${runCommand}\n`;
7390
+ output += `${pc.cyan("•")} Test: uv run pytest\n`;
7391
+ output += `${pc.cyan("•")} Format: uv run ruff format .\n`;
7392
+ output += `${pc.cyan("•")} Lint: uv run ruff check .\n`;
7393
+ output += `\n${pc.bold("Your project will be available at:")}\n`;
7394
+ output += `${pc.cyan("•")} API: http://localhost:8000\n`;
7395
+ output += `\n${pc.bold("Like Better Fullstack?")} Please consider giving us a star\n on GitHub:\n`;
7396
+ output += pc.cyan("https://github.com/Marve10s/Better-Fullstack");
7397
+ consola$1.box(output);
7398
+ }
7254
7399
 
7255
7400
  //#endregion
7256
7401
  //#region src/helpers/core/create-project.ts
@@ -7277,6 +7422,7 @@ async function createProject(options, cliInput = {}) {
7277
7422
  });
7278
7423
  if (options.install && options.ecosystem === "rust") await runCargoBuild({ projectDir });
7279
7424
  if (options.install && options.ecosystem === "python") await runUvSync({ projectDir });
7425
+ if (options.install && options.ecosystem === "go") await runGoModTidy({ projectDir });
7280
7426
  await initializeGit(projectDir, options.git);
7281
7427
  if (!isSilent()) await displayPostInstallInstructions({
7282
7428
  ...options,
@@ -7406,7 +7552,8 @@ async function createProjectHandler(input, options = {}) {
7406
7552
  goOrm: "none",
7407
7553
  goApi: "none",
7408
7554
  goCli: "none",
7409
- goLogging: "none"
7555
+ goLogging: "none",
7556
+ aiDocs: []
7410
7557
  },
7411
7558
  reproducibleCommand: "",
7412
7559
  timeScaffolded,
@@ -7678,7 +7825,8 @@ const router = os.router({
7678
7825
  goOrm: types_exports.GoOrmSchema.optional().describe("Go ORM/database (gorm, sqlc)"),
7679
7826
  goApi: types_exports.GoApiSchema.optional().describe("Go API layer (grpc-go)"),
7680
7827
  goCli: types_exports.GoCliSchema.optional().describe("Go CLI tools (cobra, bubbletea)"),
7681
- goLogging: types_exports.GoLoggingSchema.optional().describe("Go logging (zap)")
7828
+ goLogging: types_exports.GoLoggingSchema.optional().describe("Go logging (zap)"),
7829
+ aiDocs: z.array(types_exports.AiDocsSchema).optional().describe("AI documentation files (claude-md, agents-md, cursorrules)")
7682
7830
  })])).handler(async ({ input }) => {
7683
7831
  const [projectName, options] = input;
7684
7832
  const result = await createProjectHandler({
@@ -7878,7 +8026,8 @@ async function createVirtual(options) {
7878
8026
  goOrm: options.goOrm || "none",
7879
8027
  goApi: options.goApi || "none",
7880
8028
  goCli: options.goCli || "none",
7881
- goLogging: options.goLogging || "none"
8029
+ goLogging: options.goLogging || "none",
8030
+ aiDocs: options.aiDocs || ["claude-md"]
7882
8031
  },
7883
8032
  templates: EMBEDDED_TEMPLATES
7884
8033
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-better-fullstack",
3
- "version": "1.1.16",
3
+ "version": "1.2.0",
4
4
  "description": "A CLI-first toolkit for building Full Stack applications. Skip the configuration. Ship the code.",
5
5
  "keywords": [
6
6
  "better-auth",
@@ -76,8 +76,8 @@
76
76
  "prepublishOnly": "npm run build"
77
77
  },
78
78
  "dependencies": {
79
- "@better-fullstack/template-generator": "^1.1.16",
80
- "@better-fullstack/types": "^1.1.16",
79
+ "@better-fullstack/template-generator": "^1.2.0",
80
+ "@better-fullstack/types": "^1.2.0",
81
81
  "@clack/core": "^0.5.0",
82
82
  "@clack/prompts": "^1.0.0-alpha.8",
83
83
  "@orpc/server": "^1.13.0",