create-better-fullstack 2.2.0 → 2.3.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.
Files changed (28) hide show
  1. package/README.md +4 -4
  2. package/dist/{add-handler-CE3XIs3y.mjs → add-handler-z4NCxoq6.mjs} +7 -6
  3. package/dist/addons-setup-COE1e1db.mjs +7 -0
  4. package/dist/{addons-setup-DR924M7b.mjs → addons-setup-DKtiNexf.mjs} +1 -1
  5. package/dist/{analytics-BXlOG6u6.mjs → analytics-BD8hZvIj.mjs} +1 -1
  6. package/dist/{bts-config-B_HhcMXL.mjs → bts-config-Bwd6GB7B.mjs} +29 -0
  7. package/dist/cli.mjs +2 -2
  8. package/dist/command-exists-DtX9ldL8.mjs +15 -0
  9. package/dist/{config-processing-DJisMeW-.mjs → config-processing-B-RT_mVE.mjs} +16 -3
  10. package/dist/{doctor-Cc7sLuow.mjs → doctor-LmNs-hDr.mjs} +4 -3
  11. package/dist/{file-formatter-BgbfpYf4.mjs → file-formatter-DxF56-mO.mjs} +109 -3
  12. package/dist/{gen-BZ0QCxCC.mjs → gen-CQfQU0uZ.mjs} +1 -1
  13. package/dist/{generated-checks-CbioGjCh.mjs → generated-checks-BUcI5VM2.mjs} +55 -22
  14. package/dist/index.d.mts +292 -40
  15. package/dist/index.mjs +19 -9
  16. package/dist/{install-dependencies-D__bmW4k.mjs → install-dependencies-CJiUklm3.mjs} +49 -8
  17. package/dist/{mcp-DNKAo8nO.mjs → mcp-BBammItk.mjs} +5 -5
  18. package/dist/mcp-entry.mjs +47 -19
  19. package/dist/{registry-Cm3D45oT.mjs → registry-D0JfLCoH.mjs} +1 -1
  20. package/dist/{run-DmN7QRt5.mjs → run-BAIeghcU.mjs} +819 -52
  21. package/dist/run-CAl4L4uU.mjs +16 -0
  22. package/dist/{scaffold-manifest-ByKtMhTd.mjs → scaffold-manifest-CQwvyttq.mjs} +1 -1
  23. package/dist/{update-B270pWHc.mjs → update-CnrBdWrh.mjs} +3 -3
  24. package/package.json +21 -4
  25. package/dist/addons-setup-Du2VSv8V.mjs +0 -7
  26. package/dist/run-C_S7ujfY.mjs +0 -15
  27. /package/dist/{scaffold-manifest-CNFz-lmH.mjs → scaffold-manifest-Dr3Anmlf.mjs} +0 -0
  28. /package/dist/{update-deps-aD-iQw4U.mjs → update-deps-G3FgqBlW.mjs} +0 -0
package/dist/index.mjs CHANGED
@@ -1,16 +1,17 @@
1
1
  #!/usr/bin/env node
2
- import "./bts-config-B_HhcMXL.mjs";
3
- import { a as createBtsCli, c as history, d as telemetry, f as update, i as create, l as router, n as builder, o as docs, r as check, s as doctor, t as add, u as sponsors } from "./run-DmN7QRt5.mjs";
2
+ import "./bts-config-Bwd6GB7B.mjs";
3
+ import { a as createBtsCli, c as history, d as telemetry, f as update, i as create, l as router, n as builder, o as docs, r as check, s as doctor, t as add, u as sponsors } from "./run-BAIeghcU.mjs";
4
4
  import "./render-title-zvyKC1ej.mjs";
5
5
  import "./errors-ns_o2OKg.mjs";
6
6
  import "./prompt-environment-BR0Kkw2W.mjs";
7
- import "./analytics-BXlOG6u6.mjs";
8
- import "./file-formatter-BgbfpYf4.mjs";
9
- import "./install-dependencies-D__bmW4k.mjs";
10
- import "./generated-checks-CbioGjCh.mjs";
11
- import { t as applyEffectBackendDefaults } from "./config-processing-DJisMeW-.mjs";
12
- import "./scaffold-manifest-CNFz-lmH.mjs";
13
- import "./addons-setup-DR924M7b.mjs";
7
+ import "./analytics-BD8hZvIj.mjs";
8
+ import "./file-formatter-DxF56-mO.mjs";
9
+ import "./install-dependencies-CJiUklm3.mjs";
10
+ import "./command-exists-DtX9ldL8.mjs";
11
+ import { t as applyEffectBackendDefaults } from "./config-processing-B-RT_mVE.mjs";
12
+ import "./generated-checks-BUcI5VM2.mjs";
13
+ import "./scaffold-manifest-Dr3Anmlf.mjs";
14
+ import "./addons-setup-DKtiNexf.mjs";
14
15
  import { EMBEDDED_TEMPLATES, TEMPLATE_COUNT, VirtualFileSystem, generateVirtualProject } from "@better-fullstack/template-generator";
15
16
 
16
17
  //#region src/index.ts
@@ -98,6 +99,7 @@ async function createVirtual(options) {
98
99
  mobilePush: options.mobilePush || "none",
99
100
  mobileOTA: options.mobileOTA || "none",
100
101
  mobileDeepLinking: options.mobileDeepLinking || (hasNativeFrontend ? "expo-linking" : "none"),
102
+ mobileLibraries: options.mobileLibraries || [],
101
103
  cms: options.cms || "none",
102
104
  caching: options.caching || "none",
103
105
  rateLimit: options.rateLimit || "none",
@@ -133,6 +135,13 @@ async function createVirtual(options) {
133
135
  pythonRealtime: options.pythonRealtime || "none",
134
136
  pythonObservability: options.pythonObservability || "none",
135
137
  pythonCli: options.pythonCli || [],
138
+ pythonCloudSdk: options.pythonCloudSdk || "none",
139
+ pythonHttpClient: options.pythonHttpClient || "none",
140
+ pythonData: options.pythonData || [],
141
+ pythonMedia: options.pythonMedia || "none",
142
+ pythonServer: options.pythonServer || "none",
143
+ pythonPackageManager: options.pythonPackageManager || "uv",
144
+ pythonMessageQueue: options.pythonMessageQueue || "none",
136
145
  goWebFramework: options.goWebFramework || "none",
137
146
  goOrm: options.goOrm || "none",
138
147
  goApi: options.goApi || "none",
@@ -171,6 +180,7 @@ async function createVirtual(options) {
171
180
  dotnetValidation: options.dotnetValidation || "none",
172
181
  dotnetCaching: options.dotnetCaching || "none",
173
182
  dotnetDeploy: options.dotnetDeploy || (options.ecosystem === "dotnet" ? "docker" : "none"),
183
+ dotnetLibraries: options.dotnetLibraries || [],
174
184
  elixirWebFramework: options.elixirWebFramework || (options.ecosystem === "elixir" ? "phoenix" : "none"),
175
185
  elixirOrm: options.elixirOrm || (options.ecosystem === "elixir" ? "ecto-sql" : "none"),
176
186
  elixirAuth: options.elixirAuth || "none",
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { b as types_exports, g as DEFAULT_CONFIG } from "./bts-config-B_HhcMXL.mjs";
2
+ import { b as types_exports, g as DEFAULT_CONFIG } from "./bts-config-Bwd6GB7B.mjs";
3
3
  import { d as setLastPromptShownUI, r as exitCancelled, s as isFirstPrompt, u as setIsFirstPrompt$1 } from "./errors-ns_o2OKg.mjs";
4
- import { S as validateAddonCompatibility, f as getCompatibleAddons } from "./file-formatter-BgbfpYf4.mjs";
4
+ import { S as validateAddonCompatibility, f as getCompatibleAddons } from "./file-formatter-DxF56-mO.mjs";
5
+ import { t as commandExists } from "./command-exists-DtX9ldL8.mjs";
5
6
  import { log, spinner } from "@clack/prompts";
6
7
  import pc from "picocolors";
7
8
  import fs from "fs-extra";
@@ -843,22 +844,62 @@ async function runCargoBuild({ projectDir }) {
843
844
  }
844
845
  async function runUvSync({ projectDir }) {
845
846
  const s = spinner();
846
- const step = "uv sync (Python dependencies)";
847
+ const step = "uv sync --extra dev (Python dependencies)";
847
848
  try {
848
- s.start("Running uv sync...");
849
+ s.start("Running uv sync --extra dev...");
849
850
  await $({
850
851
  cwd: projectDir,
851
852
  stderr: "inherit"
852
- })`uv sync`;
853
+ })`uv sync --extra dev`;
853
854
  s.stop("Python dependencies installed successfully");
854
855
  return {
855
856
  step,
856
857
  success: true
857
858
  };
858
859
  } catch (error) {
859
- s.stop(pc.red("uv sync failed"));
860
+ s.stop(pc.red("uv sync --extra dev failed"));
860
861
  const errorMessage = toErrorMessage(error);
861
- consola.error(pc.red(`uv sync error: ${errorMessage}`));
862
+ consola.error(pc.red(`uv sync --extra dev error: ${errorMessage}`));
863
+ return {
864
+ step,
865
+ success: false,
866
+ errorMessage
867
+ };
868
+ }
869
+ }
870
+ async function runPythonInstall({ projectDir, packageManager }) {
871
+ if (packageManager === "uv") return runUvSync({ projectDir });
872
+ const s = spinner();
873
+ const step = `${packageManager} install (Python dependencies)`;
874
+ try {
875
+ if (packageManager === "poetry") {
876
+ s.start("Running poetry install...");
877
+ await $({
878
+ cwd: projectDir,
879
+ stderr: "inherit"
880
+ })`poetry install --extras dev`;
881
+ } else {
882
+ s.start("Creating a virtual environment and installing with pip...");
883
+ const python = await commandExists("python") ? "python" : "python3";
884
+ await $({
885
+ cwd: projectDir,
886
+ stderr: "inherit"
887
+ })`${python} -m venv .venv`;
888
+ const pip = process.platform === "win32" ? ".venv/Scripts/pip.exe" : ".venv/bin/pip";
889
+ await $({
890
+ cwd: projectDir,
891
+ stderr: "inherit"
892
+ })`${pip} install -e .[dev]`;
893
+ }
894
+ s.stop("Python dependencies installed successfully");
895
+ return {
896
+ step,
897
+ success: true
898
+ };
899
+ } catch (error) {
900
+ s.stop(pc.red("Python dependency installation failed"));
901
+ const errorMessage = toErrorMessage(error);
902
+ consola.error(pc.red(`Python installation error: ${errorMessage}`));
862
903
  return {
863
904
  step,
864
905
  success: false,
@@ -974,4 +1015,4 @@ async function runMixCompile({ projectDir }) {
974
1015
  }
975
1016
 
976
1017
  //#endregion
977
- export { GO_BACK_SYMBOL as _, runMavenTests as a, applyDependencyVersionChannel as c, getAppPlatformsChoice as d, isCancel$1 as f, setIsFirstPrompt as g, navigableSelect as h, runGradleTests as i, getAddonsChoice as l, navigableMultiselect as m, runCargoBuild as n, runMixCompile as o, navigableConfirm as p, runGoModTidy as r, runUvSync as s, installDependencies as t, getAddonsToAdd as u, isGoBack as v };
1018
+ export { GO_BACK_SYMBOL as _, runMavenTests as a, applyDependencyVersionChannel as c, getAppPlatformsChoice as d, isCancel$1 as f, setIsFirstPrompt as g, navigableSelect as h, runGradleTests as i, getAddonsChoice as l, navigableMultiselect as m, runCargoBuild as n, runMixCompile as o, navigableConfirm as p, runGoModTidy as r, runPythonInstall as s, installDependencies as t, getAddonsToAdd as u, isGoBack as v };
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import "./bts-config-B_HhcMXL.mjs";
2
+ import "./bts-config-Bwd6GB7B.mjs";
3
3
  import "./errors-ns_o2OKg.mjs";
4
4
  import "./prompt-environment-BR0Kkw2W.mjs";
5
- import "./analytics-BXlOG6u6.mjs";
6
- import "./file-formatter-BgbfpYf4.mjs";
7
- import "./config-processing-DJisMeW-.mjs";
8
- import "./scaffold-manifest-CNFz-lmH.mjs";
5
+ import "./analytics-BD8hZvIj.mjs";
6
+ import "./file-formatter-DxF56-mO.mjs";
7
+ import "./config-processing-B-RT_mVE.mjs";
8
+ import "./scaffold-manifest-Dr3Anmlf.mjs";
9
9
  import { a as startMcpServer, i as recommendStackFromBrief, n as MCP_STACK_UPDATE_SCHEMA, r as getMcpGraphPreview, t as MCP_PLAN_CREATE_SCHEMA } from "./mcp-entry.mjs";
10
10
 
11
11
  export { recommendStackFromBrief, startMcpServer };
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
- import { b as types_exports, d as getGraphSummary, m as getLatestCLIVersion, n as previewBtsConfigUpdate, o as writeBtsConfig, r as readBtsConfig, s as getEffectiveStack, t as buildBtsConfigForPersistence, v as getDefaultConfig } from "./bts-config-B_HhcMXL.mjs";
2
+ import { b as types_exports, d as getGraphSummary, m as getLatestCLIVersion, n as previewBtsConfigUpdate, o as writeBtsConfig, r as readBtsConfig, s as getEffectiveStack, t as buildBtsConfigForPersistence, v as getDefaultConfig } from "./bts-config-Bwd6GB7B.mjs";
3
3
  import "./errors-ns_o2OKg.mjs";
4
4
  import "./prompt-environment-BR0Kkw2W.mjs";
5
- import { a as trackProjectCreation, i as trackEvent } from "./analytics-BXlOG6u6.mjs";
6
- import { a as asString, c as compatibilityChangesToProjectConfig, l as getCompatibilityBackend, o as asStringArray, r as validateConfigForProgrammaticUse, s as buildCompatibilityInputFromConfig, t as formatCode, w as CreateCommandOptionsSchema } from "./file-formatter-BgbfpYf4.mjs";
7
- import { a as getTemplateConfig, o as getTemplateDescription, s as generateReproducibleCommand, t as applyEffectBackendDefaults } from "./config-processing-DJisMeW-.mjs";
8
- import { c as refreshScaffoldManifestFiles, n as collectStructuredBaselines } from "./scaffold-manifest-CNFz-lmH.mjs";
5
+ import { a as trackProjectCreation, i as trackEvent } from "./analytics-BD8hZvIj.mjs";
6
+ import { a as asString, c as compatibilityChangesToProjectConfig, l as getCompatibilityBackend, o as asStringArray, r as validateConfigForProgrammaticUse, s as buildCompatibilityInputFromConfig, t as formatCode, w as CreateCommandOptionsSchema } from "./file-formatter-DxF56-mO.mjs";
7
+ import { a as getTemplateConfig, o as getTemplateDescription, s as generateReproducibleCommand, t as applyEffectBackendDefaults } from "./config-processing-B-RT_mVE.mjs";
8
+ import { c as refreshScaffoldManifestFiles, n as collectStructuredBaselines } from "./scaffold-manifest-Dr3Anmlf.mjs";
9
9
  import z from "zod";
10
10
  import fs from "fs-extra";
11
11
  import path from "node:path";
12
- import { AISchema, APISchema, AddonsSchema, AiDocsSchema, AnalyticsSchema, AnimationSchema, AstroIntegrationSchema, AuthSchema, BackendSchema, CATEGORY_ORDER, CMSSchema, CSSFrameworkSchema, CachingSchema, DatabaseSchema, DatabaseSetupSchema, DotnetApiSchema, DotnetAuthSchema, DotnetCachingSchema, DotnetDeploySchema, DotnetJobQueueSchema, DotnetObservabilitySchema, DotnetOrmSchema, DotnetRealtimeSchema, DotnetTestingSchema, DotnetValidationSchema, DotnetWebFrameworkSchema, EcosystemSchema, EffectSchema, ElixirApiSchema, ElixirApplicationFrameworkSchema, ElixirAuthSchema, ElixirCachingSchema, ElixirClusteringSchema, ElixirDeploySchema, ElixirDocumentationSchema, ElixirEmailSchema, ElixirHttpSchema, ElixirHttpServerSchema, ElixirI18nSchema, ElixirJobsSchema, ElixirJsonSchema, ElixirLibrariesSchema, ElixirObservabilitySchema, ElixirOrmSchema, ElixirQualitySchema, ElixirRealtimeSchema, ElixirTestingSchema, ElixirValidationSchema, ElixirWebFrameworkSchema, EmailSchema, ExamplesSchema, FeatureFlagsSchema, FileStorageSchema, FileUploadSchema, FormsSchema, FrontendSchema, GoApiSchema, GoAuthSchema, GoCachingSchema, GoCliSchema, GoConfigSchema, GoDISchema, GoLoggingSchema, GoMessageQueueSchema, GoMigrationsSchema, GoObservabilitySchema, GoOrmSchema, GoProtoToolingSchema, GoQualitySchema, GoRealtimeSchema, GoTemplatingSchema, GoTestingSchema, GoValidationSchema, GoWebFrameworkSchema, I18nSchema, JavaApiSchema, JavaAuthSchema, JavaBuildToolSchema, JavaLanguageSchema, JavaLibrariesSchema, JavaLoggingSchema, JavaOrmSchema, JavaTestingLibrariesSchema, JavaWebFrameworkSchema, JobQueueSchema, LoggingSchema, MobileDeepLinkingSchema, MobileNavigationSchema, MobileOTASchema, MobilePushSchema, MobileStorageSchema, MobileTestingSchema, MobileUISchema, OPTION_CATEGORY_METADATA, ORMSchema, ObservabilitySchema, PackageManagerSchema, PaymentsSchema, PythonAiSchema, PythonApiSchema, PythonAuthSchema, PythonCachingSchema, PythonCliSchema, PythonGraphqlSchema, PythonObservabilitySchema, PythonOrmSchema, PythonQualitySchema, PythonRealtimeSchema, PythonTaskQueueSchema, PythonTestingSchema, PythonValidationSchema, PythonWebFrameworkSchema, RateLimitSchema, RealtimeSchema, RuntimeSchema, RustApiSchema, RustAuthSchema, RustCachingSchema, RustCliSchema, RustErrorHandlingSchema, RustFrontendSchema, RustLibrariesSchema, RustLoggingSchema, RustMessageQueueSchema, RustObservabilitySchema, RustOrmSchema, RustRealtimeSchema, RustTemplatingSchema, RustWebFrameworkSchema, SearchSchema, ServerDeploySchema, ShadcnBaseColorSchema, ShadcnBaseSchema, ShadcnColorThemeSchema, ShadcnFontSchema, ShadcnIconLibrarySchema, ShadcnRadiusSchema, ShadcnStyleSchema, StateManagementSchema, TEMPLATE_VALUES, TestingSchema, UILibrarySchema, ValidationSchema, VectorDbSchema, VersionChannelSchema, WebDeploySchema, analyzeStackCompatibility, evaluateCompatibility, formatStackPartSpec, getCategoryOrderForEcosystem, legacyProjectConfigToStackParts, parseStackPartSpecs, stackPartsToLegacyProjectConfigPartial } from "@better-fullstack/types";
12
+ import { AISchema, APISchema, AddonsSchema, AiDocsSchema, AnalyticsSchema, AnimationSchema, AstroIntegrationSchema, AuthSchema, BackendSchema, CATEGORY_ORDER, CMSSchema, CSSFrameworkSchema, CachingSchema, DatabaseSchema, DatabaseSetupSchema, DotnetApiSchema, DotnetAuthSchema, DotnetCachingSchema, DotnetDeploySchema, DotnetJobQueueSchema, DotnetLibrariesSchema, DotnetObservabilitySchema, DotnetOrmSchema, DotnetRealtimeSchema, DotnetTestingSchema, DotnetValidationSchema, DotnetWebFrameworkSchema, EcosystemSchema, EffectSchema, ElixirApiSchema, ElixirApplicationFrameworkSchema, ElixirAuthSchema, ElixirCachingSchema, ElixirClusteringSchema, ElixirDeploySchema, ElixirDocumentationSchema, ElixirEmailSchema, ElixirHttpSchema, ElixirHttpServerSchema, ElixirI18nSchema, ElixirJobsSchema, ElixirJsonSchema, ElixirLibrariesSchema, ElixirObservabilitySchema, ElixirOrmSchema, ElixirQualitySchema, ElixirRealtimeSchema, ElixirTestingSchema, ElixirValidationSchema, ElixirWebFrameworkSchema, EmailSchema, ExamplesSchema, FeatureFlagsSchema, FileStorageSchema, FileUploadSchema, FormsSchema, FrontendSchema, GoApiSchema, GoAuthSchema, GoCachingSchema, GoCliSchema, GoConfigSchema, GoDISchema, GoLoggingSchema, GoMessageQueueSchema, GoMigrationsSchema, GoObservabilitySchema, GoOrmSchema, GoProtoToolingSchema, GoQualitySchema, GoRealtimeSchema, GoTemplatingSchema, GoTestingSchema, GoValidationSchema, GoWebFrameworkSchema, I18nSchema, JavaApiSchema, JavaAuthSchema, JavaBuildToolSchema, JavaLanguageSchema, JavaLibrariesSchema, JavaLoggingSchema, JavaOrmSchema, JavaTestingLibrariesSchema, JavaWebFrameworkSchema, JobQueueSchema, LoggingSchema, MobileDeepLinkingSchema, MobileLibrariesSchema, MobileNavigationSchema, MobileOTASchema, MobilePushSchema, MobileStorageSchema, MobileTestingSchema, MobileUISchema, OPTION_CATEGORY_METADATA, ORMSchema, ObservabilitySchema, PackageManagerSchema, PaymentsSchema, PythonAiSchema, PythonApiSchema, PythonAuthSchema, PythonCachingSchema, PythonCliSchema, PythonCloudSdkSchema, PythonDataSchema, PythonGraphqlSchema, PythonHttpClientSchema, PythonMediaSchema, PythonMessageQueueSchema, PythonObservabilitySchema, PythonOrmSchema, PythonPackageManagerSchema, PythonQualitySchema, PythonRealtimeSchema, PythonServerSchema, PythonTaskQueueSchema, PythonTestingSchema, PythonValidationSchema, PythonWebFrameworkSchema, RateLimitSchema, RealtimeSchema, RuntimeSchema, RustApiSchema, RustAuthSchema, RustCachingSchema, RustCliSchema, RustErrorHandlingSchema, RustFrontendSchema, RustLibrariesSchema, RustLoggingSchema, RustMessageQueueSchema, RustObservabilitySchema, RustOrmSchema, RustRealtimeSchema, RustTemplatingSchema, RustWebFrameworkSchema, SearchSchema, ServerDeploySchema, ShadcnBaseColorSchema, ShadcnBaseSchema, ShadcnColorThemeSchema, ShadcnFontSchema, ShadcnIconLibrarySchema, ShadcnRadiusSchema, ShadcnStyleSchema, StateManagementSchema, TEMPLATE_VALUES, TestingSchema, UILibrarySchema, ValidationSchema, VectorDbSchema, VersionChannelSchema, WebDeploySchema, analyzeStackCompatibility, evaluateCompatibility, formatStackPartSpec, getCategoryOrderForEcosystem, legacyProjectConfigToStackParts, parseStackPartSpecs, stackPartsToLegacyProjectConfigPartial } from "@better-fullstack/types";
13
13
  import { tmpdir } from "node:os";
14
14
  import { EMBEDDED_TEMPLATES, generateVirtualProject } from "@better-fullstack/template-generator";
15
15
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -26,11 +26,14 @@ const ARRAY_UPDATE_KEYS = new Set([
26
26
  "pythonAi",
27
27
  "pythonTesting",
28
28
  "pythonCli",
29
+ "pythonData",
29
30
  "goTesting",
30
31
  "javaLibraries",
31
32
  "javaTestingLibraries",
32
33
  "dotnetTesting",
33
34
  "dotnetObservability",
35
+ "mobileLibraries",
36
+ "dotnetLibraries",
34
37
  "elixirLibraries"
35
38
  ]);
36
39
  const NON_STACK_UPDATE_CREATE_KEYS = new Set([
@@ -369,7 +372,7 @@ function getDefaultWebFrontendForRequestedUpdate(requestedChanges) {
369
372
  }
370
373
  function getDefaultNativeFrontendForRequestedUpdate(requestedChanges) {
371
374
  if (requestedChanges.mobileUI === "uniwind" || requestedChanges.mobileUI === "unistyles") return;
372
- return hasRequestedNonNoneValue(requestedChanges, "mobileNavigation") || hasRequestedNonNoneValue(requestedChanges, "mobileUI") || hasRequestedNonNoneValue(requestedChanges, "mobileStorage") || hasRequestedNonNoneValue(requestedChanges, "mobileTesting") || hasRequestedNonNoneValue(requestedChanges, "mobilePush") || hasRequestedNonNoneValue(requestedChanges, "mobileOTA") || hasRequestedNonNoneValue(requestedChanges, "mobileDeepLinking") ? "native-bare" : void 0;
375
+ return hasRequestedNonNoneValue(requestedChanges, "mobileNavigation") || hasRequestedNonNoneValue(requestedChanges, "mobileUI") || hasRequestedNonNoneValue(requestedChanges, "mobileStorage") || hasRequestedNonNoneValue(requestedChanges, "mobileTesting") || hasRequestedNonNoneValue(requestedChanges, "mobilePush") || hasRequestedNonNoneValue(requestedChanges, "mobileOTA") || hasRequestedNonNoneValue(requestedChanges, "mobileDeepLinking") || (requestedChanges.mobileLibraries?.some((value) => value !== "none") ?? false) ? "native-bare" : void 0;
373
376
  }
374
377
  function applyKnownDependencyExpansions(config, requestedChanges) {
375
378
  const next = { ...config };
@@ -734,7 +737,10 @@ async function addMissingEnvExampleOperation(options) {
734
737
  function getInstallCommand$1(config) {
735
738
  switch (config.ecosystem) {
736
739
  case "rust": return "cargo build";
737
- case "python": return "uv sync";
740
+ case "python":
741
+ if (config.pythonPackageManager === "poetry") return "poetry install --extras dev";
742
+ if (config.pythonPackageManager === "none") return `${process.platform === "win32" ? "python" : "python3"} -m venv .venv && ${process.platform === "win32" ? ".venv\\Scripts\\pip" : ".venv/bin/pip"} install -e ".[dev]"`;
743
+ return "uv sync --extra dev";
738
744
  case "go": return "go mod tidy";
739
745
  case "java": return config.javaBuildTool === "gradle" ? "./gradlew test" : "./mvnw test";
740
746
  case "elixir": return "mix deps.get && mix compile";
@@ -994,7 +1000,8 @@ async function applyStackUpdate(projectDirInput, input) {
994
1000
 
995
1001
  //#endregion
996
1002
  //#region src/mcp.ts
997
- const INSTRUCTIONS = `Better-Fullstack scaffolds fullstack projects across TypeScript, React Native, Rust, Go, Python, Java, .NET, and Elixir ecosystems with ${Object.values(OPTION_CATEGORY_METADATA).reduce((sum, metadata) => sum + metadata.options.length, 0)} configurable options.
1003
+ const OPTION_ENTRY_COUNT = Object.values(OPTION_CATEGORY_METADATA).reduce((sum, metadata) => sum + metadata.options.length, 0);
1004
+ const INSTRUCTIONS = `Better-Fullstack scaffolds fullstack projects across ${EcosystemSchema.options.join(", ")} ecosystems with ${OPTION_ENTRY_COUNT} configurable options.
998
1005
 
999
1006
  RECOMMENDED WORKFLOW:
1000
1007
  1. Call bfs_get_guidance to understand field semantics, required fields, and workflow rules.
@@ -1010,7 +1017,7 @@ For existing projects:
1010
1017
 
1011
1018
  CRITICAL RULES:
1012
1019
  - Dependency installation is ALWAYS skipped in MCP mode (timeout risk). After scaffolding, tell the user to run install manually.
1013
- - Array fields: "frontend", "addons", "examples", "aiDocs", "rustLibraries", "pythonAi", "pythonTesting", "pythonCli", "goTesting", "javaLibraries", "javaTestingLibraries", "dotnetTesting", "dotnetObservability", and "elixirLibraries". Most other option fields are strings.
1020
+ - Array fields: "frontend", "addons", "examples", "aiDocs", "rustLibraries", "pythonAi", "pythonTesting", "pythonCli", "pythonData", "goTesting", "javaLibraries", "javaTestingLibraries", "dotnetTesting", "dotnetObservability", "elixirLibraries", "mobileLibraries", and "dotnetLibraries". Most other option fields are strings.
1014
1021
  - "none" means "skip this feature entirely", not "use the default".
1015
1022
  - Always specify "ecosystem" first — it determines which other fields are relevant.
1016
1023
  - TypeScript web-specific fields (web frontend, backend, orm, etc.) are IGNORED for react-native/rust/python/go/java/dotnet/elixir ecosystems.
@@ -1040,7 +1047,7 @@ function getGuidance() {
1040
1047
  projectName: "kebab-case directory name. Required for bfs_create_project.",
1041
1048
  ecosystem: "Must be set first. Determines which other fields are relevant.",
1042
1049
  frontend: "ARRAY of strings. TypeScript only. Supports multiple frontends in one monorepo. Use [] for API-only.",
1043
- arrayFields: "Use arrays for frontend, addons, examples, aiDocs, rustLibraries, pythonAi, pythonTesting, pythonCli, goTesting, javaLibraries, javaTestingLibraries, dotnetTesting, dotnetObservability, and elixirLibraries. Use [] for \"none\" on multi-select fields.",
1050
+ arrayFields: "Use arrays for frontend, addons, examples, aiDocs, rustLibraries, pythonAi, pythonTesting, pythonCli, pythonData, goTesting, javaLibraries, javaTestingLibraries, dotnetTesting, dotnetObservability, elixirLibraries, mobileLibraries, and dotnetLibraries. Use [] for \"none\" on multi-select fields.",
1044
1051
  backend: "String. \"self\" means fullstack mode (Next.js/Vinext/TanStack Start/Nuxt/Astro API routes). \"none\" for frontend-only.",
1045
1052
  runtime: "\"bun\" or \"node\". Must be \"none\" when backend is \"self\" or \"convex\".",
1046
1053
  addons: "ARRAY of strings. Monorepo tools, code quality, desktop (tauri), browser extensions (wxt), etc.",
@@ -1155,10 +1162,13 @@ function getSchemaOptions(category, ecosystem) {
1155
1162
  }
1156
1163
  return result;
1157
1164
  }
1158
- function getInstallCommand(ecosystem, projectName, packageManager, javaBuildTool, javaWebFramework) {
1165
+ function getInstallCommand(ecosystem, projectName, packageManager, javaBuildTool, javaWebFramework, pythonPackageManager) {
1159
1166
  switch (ecosystem) {
1160
1167
  case "rust": return `cd ${projectName} && cargo build`;
1161
- case "python": return `cd ${projectName} && uv sync`;
1168
+ case "python":
1169
+ if (pythonPackageManager === "poetry") return `cd ${projectName} && poetry install --extras dev`;
1170
+ if (pythonPackageManager === "none") return `cd ${projectName} && ${process.platform === "win32" ? "python" : "python3"} -m venv .venv && ${process.platform === "win32" ? ".venv/Scripts/pip.exe" : ".venv/bin/pip"} install -e ".[dev]"`;
1171
+ return `cd ${projectName} && uv sync --extra dev`;
1162
1172
  case "go": return `cd ${projectName} && go mod tidy`;
1163
1173
  case "elixir": return `cd ${projectName} && mix deps.get && mix compile && mix test`;
1164
1174
  case "java":
@@ -1238,6 +1248,7 @@ const MCP_COMPATIBILITY_DEFAULTS = {
1238
1248
  mobileTesting: "none",
1239
1249
  mobilePush: "none",
1240
1250
  mobileOTA: "none",
1251
+ mobileLibraries: [],
1241
1252
  packageManager: "bun",
1242
1253
  workspaceShape: "monorepo",
1243
1254
  versionChannel: "stable",
@@ -1278,6 +1289,13 @@ const MCP_COMPATIBILITY_DEFAULTS = {
1278
1289
  pythonRealtime: "none",
1279
1290
  pythonObservability: "none",
1280
1291
  pythonCli: [],
1292
+ pythonCloudSdk: "none",
1293
+ pythonHttpClient: "none",
1294
+ pythonData: [],
1295
+ pythonMedia: "none",
1296
+ pythonServer: "none",
1297
+ pythonPackageManager: "uv",
1298
+ pythonMessageQueue: "none",
1281
1299
  goWebFramework: "none",
1282
1300
  goOrm: "none",
1283
1301
  goApi: "none",
@@ -1316,6 +1334,7 @@ const MCP_COMPATIBILITY_DEFAULTS = {
1316
1334
  dotnetValidation: "none",
1317
1335
  dotnetCaching: "none",
1318
1336
  dotnetDeploy: "docker",
1337
+ dotnetLibraries: [],
1319
1338
  elixirWebFramework: "phoenix",
1320
1339
  elixirOrm: "ecto-sql",
1321
1340
  elixirAuth: "none",
@@ -1538,7 +1557,7 @@ const GETTING_STARTED_MD = `# Getting Started with Better-Fullstack MCP
1538
1557
  - pythonOrm: "sqlalchemy"
1539
1558
  - email: "resend" (optional)
1540
1559
  - observability: "sentry" (optional)
1541
- 2. Tell the user to run: cd my-python-app && uv sync
1560
+ 2. Tell the user to run: cd my-python-app && uv sync --extra dev
1542
1561
 
1543
1562
  ## Quick Start — Go Project
1544
1563
  1. Call bfs_create_project with:
@@ -1881,7 +1900,8 @@ const mobileInputSchema = {
1881
1900
  mobileTesting: MobileTestingSchema.optional().describe("Mobile testing"),
1882
1901
  mobilePush: MobilePushSchema.optional().describe("Mobile push notifications"),
1883
1902
  mobileOTA: MobileOTASchema.optional().describe("Mobile OTA updates"),
1884
- mobileDeepLinking: MobileDeepLinkingSchema.optional().describe("Mobile deep linking")
1903
+ mobileDeepLinking: MobileDeepLinkingSchema.optional().describe("Mobile deep linking"),
1904
+ mobileLibraries: z.array(MobileLibrariesSchema).optional().describe("Mobile application libraries")
1885
1905
  };
1886
1906
  const deploymentInputSchema = {
1887
1907
  dbSetup: DatabaseSetupSchema.optional().describe("Database hosting provider"),
@@ -1917,6 +1937,13 @@ const crossEcosystemInputSchema = {
1917
1937
  pythonRealtime: PythonRealtimeSchema.optional().describe("Python realtime library"),
1918
1938
  pythonObservability: PythonObservabilitySchema.optional().describe("Python observability"),
1919
1939
  pythonCli: z.array(PythonCliSchema).optional().describe("Python CLI tooling"),
1940
+ pythonCloudSdk: PythonCloudSdkSchema.optional().describe("Python cloud SDK"),
1941
+ pythonHttpClient: PythonHttpClientSchema.optional().describe("Python HTTP client"),
1942
+ pythonData: z.array(PythonDataSchema).optional().describe("Python data/scientific libraries"),
1943
+ pythonMedia: PythonMediaSchema.optional().describe("Python media library"),
1944
+ pythonServer: PythonServerSchema.optional().describe("Python production server"),
1945
+ pythonPackageManager: PythonPackageManagerSchema.optional().describe("Python package manager"),
1946
+ pythonMessageQueue: PythonMessageQueueSchema.optional().describe("Python message queue client"),
1920
1947
  goWebFramework: GoWebFrameworkSchema.optional().describe("Go web framework"),
1921
1948
  goOrm: GoOrmSchema.optional().describe("Go ORM"),
1922
1949
  goApi: GoApiSchema.optional().describe("Go API layer"),
@@ -1955,6 +1982,7 @@ const crossEcosystemInputSchema = {
1955
1982
  dotnetValidation: DotnetValidationSchema.optional().describe(".NET validation"),
1956
1983
  dotnetCaching: DotnetCachingSchema.optional().describe(".NET caching library"),
1957
1984
  dotnetDeploy: DotnetDeploySchema.optional().describe(".NET deployment target"),
1985
+ dotnetLibraries: z.array(DotnetLibrariesSchema).optional().describe(".NET application libraries"),
1958
1986
  elixirWebFramework: ElixirWebFrameworkSchema.optional().describe("Elixir web framework"),
1959
1987
  elixirOrm: ElixirOrmSchema.optional().describe("Elixir persistence layer"),
1960
1988
  elixirAuth: ElixirAuthSchema.optional().describe("Elixir authentication"),
@@ -2355,12 +2383,12 @@ async function startMcpServer() {
2355
2383
  const graphPreview = getMcpGraphPreview(config);
2356
2384
  let addonWarnings = [];
2357
2385
  if (config.addons.length > 0 && config.addons[0] !== "none") {
2358
- const { setupAddons } = await import("./addons-setup-Du2VSv8V.mjs");
2386
+ const { setupAddons } = await import("./addons-setup-COE1e1db.mjs");
2359
2387
  addonWarnings = await setupAddons(config);
2360
2388
  }
2361
- const { collectStructuredBaselines: collectStructuredBaselines$1, recordScaffoldManifest } = await import("./scaffold-manifest-ByKtMhTd.mjs");
2389
+ const { collectStructuredBaselines: collectStructuredBaselines$1, recordScaffoldManifest } = await import("./scaffold-manifest-CQwvyttq.mjs");
2362
2390
  await recordScaffoldManifest(projectDir, { baselines: collectStructuredBaselines$1(result.tree) });
2363
- const installCmd = getInstallCommand(input.ecosystem ?? "typescript", projectName, input.packageManager, input.javaBuildTool, input.javaWebFramework);
2391
+ const installCmd = getInstallCommand(input.ecosystem ?? "typescript", projectName, input.packageManager, input.javaBuildTool, input.javaWebFramework, input.pythonPackageManager);
2364
2392
  await trackProjectCreation(config, false, {
2365
2393
  source: "mcp",
2366
2394
  success: true,
@@ -2639,7 +2667,7 @@ async function startMcpServer() {
2639
2667
  if (result?.success) {
2640
2668
  const existingConfig = await readBtsConfig(safePath);
2641
2669
  const graphPreview = existingConfig ? getMcpGraphPreview(existingConfig) : void 0;
2642
- const installCmd = getInstallCommand(existingConfig?.ecosystem ?? "typescript", safePath.split("/").pop() ?? "project", input.packageManager, existingConfig?.javaBuildTool, existingConfig?.javaWebFramework);
2670
+ const installCmd = getInstallCommand(existingConfig?.ecosystem ?? "typescript", safePath.split("/").pop() ?? "project", input.packageManager, existingConfig?.javaBuildTool, existingConfig?.javaWebFramework, existingConfig?.pythonPackageManager);
2643
2671
  const payload = {
2644
2672
  success: true,
2645
2673
  addedAddons: result.addedAddons,
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { b as types_exports, r as readBtsConfig } from "./bts-config-B_HhcMXL.mjs";
2
+ import { b as types_exports, r as readBtsConfig } from "./bts-config-Bwd6GB7B.mjs";
3
3
  import { t as renderTitle } from "./render-title-zvyKC1ej.mjs";
4
4
  import { t as CLIError } from "./errors-ns_o2OKg.mjs";
5
5
  import { intro, log, outro } from "@clack/prompts";