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
@@ -1,15 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import { _ as DEFAULT_UI_LIBRARY_BY_FRONTEND, b as types_exports, c as getGraphBackendDeployInstructions, d as getGraphSummary, g as DEFAULT_CONFIG, h as BUILDER_URL, i as readBtsConfigFromFile, l as getGraphBackendUrl, m as getLatestCLIVersion, o as writeBtsConfig, p as hasGraphPart, t as buildBtsConfigForPersistence, u as getGraphPart, v as getDefaultConfig, y as getUserPkgManager } from "./bts-config-B_HhcMXL.mjs";
2
+ import { _ as DEFAULT_UI_LIBRARY_BY_FRONTEND, b as types_exports, c as getGraphBackendDeployInstructions, d as getGraphSummary, g as DEFAULT_CONFIG, h as BUILDER_URL, i as readBtsConfigFromFile, l as getGraphBackendUrl, m as getLatestCLIVersion, o as writeBtsConfig, p as hasGraphPart, t as buildBtsConfigForPersistence, u as getGraphPart, v as getDefaultConfig, y as getUserPkgManager } from "./bts-config-Bwd6GB7B.mjs";
3
3
  import { t as renderTitle } from "./render-title-zvyKC1ej.mjs";
4
4
  import { a as handleError, c as isSilent, d as setLastPromptShownUI, i as exitWithError, l as runWithContextAsync, n as UserCancelledError, o as didLastPromptShowUI, r as exitCancelled, s as isFirstPrompt, t as CLIError, u as setIsFirstPrompt } from "./errors-ns_o2OKg.mjs";
5
5
  import { t as canPromptInteractively } from "./prompt-environment-BR0Kkw2W.mjs";
6
- import { a as trackProjectCreation, i as trackEvent, n as isTelemetryEnabled, o as getPersistedTelemetryPreference, r as maybeShowTelemetryNotice, s as setTelemetryPreference, t as hasTelemetryEnvOverride } from "./analytics-BXlOG6u6.mjs";
7
- import { C as CreateCommandInputSchema, _ as isExampleChatSdkAllowed$1, b as requiresChatSdkVercelAI, d as allowedApisForFrontends$1, g as isExampleAIAllowed$1, h as hasWebStyling$1, i as validateFullConfig, m as getCompatibleUILibraries$1, n as formatProject, p as getCompatibleCSSFrameworks$1, r as validateConfigForProgrammaticUse, u as resolveCompatibilityAdjustments, v as isFrontendAllowedWithBackend$1, w as CreateCommandOptionsSchema, x as splitFrontends$1, y as isWebFrontend$1 } from "./file-formatter-BgbfpYf4.mjs";
8
- import { _ as GO_BACK_SYMBOL, a as runMavenTests, c as applyDependencyVersionChannel, d as getAppPlatformsChoice, f as isCancel$1, g as setIsFirstPrompt$1, h as navigableSelect, i as runGradleTests, l as getAddonsChoice, m as navigableMultiselect, n as runCargoBuild, o as runMixCompile, p as navigableConfirm, r as runGoModTidy, s as runUvSync, t as installDependencies, v as isGoBack } from "./install-dependencies-D__bmW4k.mjs";
9
- import { n as commandExists, t as runGeneratedChecks } from "./generated-checks-CbioGjCh.mjs";
10
- import { a as getTemplateConfig, i as validateArrayOptions, n as getProvidedFlags, o as getTemplateDescription, r as processFlags, s as generateReproducibleCommand, t as applyEffectBackendDefaults } from "./config-processing-DJisMeW-.mjs";
11
- import { n as collectStructuredBaselines, s as recordScaffoldManifest } from "./scaffold-manifest-CNFz-lmH.mjs";
12
- import { n as getPackageExecutionArgs, r as addPackageDependency, t as setupAddons } from "./addons-setup-DR924M7b.mjs";
6
+ import { a as trackProjectCreation, i as trackEvent, n as isTelemetryEnabled, o as getPersistedTelemetryPreference, r as maybeShowTelemetryNotice, s as setTelemetryPreference, t as hasTelemetryEnvOverride } from "./analytics-BD8hZvIj.mjs";
7
+ import { C as CreateCommandInputSchema, _ as isExampleChatSdkAllowed$1, b as requiresChatSdkVercelAI, d as allowedApisForFrontends$1, g as isExampleAIAllowed$1, h as hasWebStyling$1, i as validateFullConfig, m as getCompatibleUILibraries$1, n as formatProject, p as getCompatibleCSSFrameworks$1, r as validateConfigForProgrammaticUse, u as resolveCompatibilityAdjustments, v as isFrontendAllowedWithBackend$1, w as CreateCommandOptionsSchema, x as splitFrontends$1, y as isWebFrontend$1 } from "./file-formatter-DxF56-mO.mjs";
8
+ import { _ as GO_BACK_SYMBOL, a as runMavenTests, c as applyDependencyVersionChannel, d as getAppPlatformsChoice, f as isCancel$1, g as setIsFirstPrompt$1, h as navigableSelect, i as runGradleTests, l as getAddonsChoice, m as navigableMultiselect, n as runCargoBuild, o as runMixCompile, p as navigableConfirm, r as runGoModTidy, s as runPythonInstall, t as installDependencies, v as isGoBack } from "./install-dependencies-CJiUklm3.mjs";
9
+ import { t as commandExists } from "./command-exists-DtX9ldL8.mjs";
10
+ import { a as getTemplateConfig, i as validateArrayOptions, n as getProvidedFlags, o as getTemplateDescription, r as processFlags, s as generateReproducibleCommand, t as applyEffectBackendDefaults } from "./config-processing-B-RT_mVE.mjs";
11
+ import { t as runGeneratedChecks } from "./generated-checks-BUcI5VM2.mjs";
12
+ import { n as collectStructuredBaselines, s as recordScaffoldManifest } from "./scaffold-manifest-Dr3Anmlf.mjs";
13
+ import { n as getPackageExecutionArgs, r as addPackageDependency, t as setupAddons } from "./addons-setup-DKtiNexf.mjs";
13
14
  import { cancel, confirm, intro, isCancel, log, note, outro, select, spinner, text } from "@clack/prompts";
14
15
  import { createRouterClient, os } from "@orpc/server";
15
16
  import pc from "picocolors";
@@ -1070,7 +1071,8 @@ const CONFIG_SCOPE_REGISTRY = {
1070
1071
  promptKeys: [
1071
1072
  "mobileUI",
1072
1073
  "mobileStorage",
1073
- "mobileDeepLinking"
1074
+ "mobileDeepLinking",
1075
+ "mobileLibraries"
1074
1076
  ]
1075
1077
  },
1076
1078
  {
@@ -1158,17 +1160,25 @@ const CONFIG_SCOPE_REGISTRY = {
1158
1160
  },
1159
1161
  {
1160
1162
  id: "api-jobs",
1161
- label: "GraphQL, Tasks & CLI",
1163
+ label: "GraphQL, Queues & CLI",
1162
1164
  promptKeys: [
1163
1165
  "pythonGraphql",
1164
1166
  "pythonTaskQueue",
1167
+ "pythonMessageQueue",
1165
1168
  "pythonCli"
1166
1169
  ]
1167
1170
  },
1168
1171
  {
1169
1172
  id: "data-realtime",
1170
- label: "Caching & Realtime",
1171
- promptKeys: ["pythonCaching", "pythonRealtime"]
1173
+ label: "Data, Media & Integrations",
1174
+ promptKeys: [
1175
+ "pythonData",
1176
+ "pythonMedia",
1177
+ "pythonCloudSdk",
1178
+ "pythonHttpClient",
1179
+ "pythonCaching",
1180
+ "pythonRealtime"
1181
+ ]
1172
1182
  },
1173
1183
  {
1174
1184
  id: "quality",
@@ -1178,6 +1188,11 @@ const CONFIG_SCOPE_REGISTRY = {
1178
1188
  "pythonTesting",
1179
1189
  "pythonObservability"
1180
1190
  ]
1191
+ },
1192
+ {
1193
+ id: "runtime-tooling",
1194
+ label: "Server & Package Manager",
1195
+ promptKeys: ["pythonServer", "pythonPackageManager"]
1181
1196
  }
1182
1197
  ]
1183
1198
  },
@@ -1279,7 +1294,11 @@ const CONFIG_SCOPE_REGISTRY = {
1279
1294
  {
1280
1295
  id: "validation-deploy",
1281
1296
  label: "Validation & Deployment",
1282
- promptKeys: ["dotnetValidation", "dotnetDeploy"]
1297
+ promptKeys: [
1298
+ "dotnetValidation",
1299
+ "dotnetDeploy",
1300
+ "dotnetLibraries"
1301
+ ]
1283
1302
  }
1284
1303
  ]
1285
1304
  },
@@ -1977,6 +1996,113 @@ const DEPLOY_OPTIONS$1 = [
1977
1996
  hint: "No .NET deploy target"
1978
1997
  }
1979
1998
  ];
1999
+ const LIBRARIES_OPTIONS = [
2000
+ {
2001
+ value: "automapper",
2002
+ label: "AutoMapper",
2003
+ hint: "Convention-based object mapping"
2004
+ },
2005
+ {
2006
+ value: "mediatr",
2007
+ label: "MediatR",
2008
+ hint: "In-process request and notification dispatch"
2009
+ },
2010
+ {
2011
+ value: "fastendpoints",
2012
+ label: "FastEndpoints",
2013
+ hint: "REPR-style endpoint framework"
2014
+ },
2015
+ {
2016
+ value: "api-versioning",
2017
+ label: "ASP.NET API Versioning",
2018
+ hint: "Versioned HTTP APIs"
2019
+ },
2020
+ {
2021
+ value: "scalar",
2022
+ label: "Scalar",
2023
+ hint: "Interactive OpenAPI reference UI"
2024
+ },
2025
+ {
2026
+ value: "polly",
2027
+ label: "Polly",
2028
+ hint: "Resilience and transient-fault handling"
2029
+ },
2030
+ {
2031
+ value: "masstransit",
2032
+ label: "MassTransit",
2033
+ hint: "Distributed messaging abstraction"
2034
+ },
2035
+ {
2036
+ value: "rebus",
2037
+ label: "Rebus",
2038
+ hint: "Service bus and message workflows"
2039
+ },
2040
+ {
2041
+ value: "coravel",
2042
+ label: "Coravel",
2043
+ hint: "Task scheduling and queuing"
2044
+ },
2045
+ {
2046
+ value: "magic-onion",
2047
+ label: "MagicOnion",
2048
+ hint: "Realtime RPC over gRPC"
2049
+ },
2050
+ {
2051
+ value: "prometheus-net",
2052
+ label: "prometheus-net",
2053
+ hint: "Prometheus metrics endpoint"
2054
+ },
2055
+ {
2056
+ value: "seq",
2057
+ label: "Seq",
2058
+ hint: "Structured log sink for Seq"
2059
+ },
2060
+ {
2061
+ value: "application-insights",
2062
+ label: "Application Insights",
2063
+ hint: "Azure application telemetry"
2064
+ },
2065
+ {
2066
+ value: "sentry",
2067
+ label: "Sentry",
2068
+ hint: "Error and performance monitoring"
2069
+ },
2070
+ {
2071
+ value: "mongodb-driver",
2072
+ label: "MongoDB Driver",
2073
+ hint: "Official MongoDB client"
2074
+ },
2075
+ {
2076
+ value: "nhibernate",
2077
+ label: "NHibernate",
2078
+ hint: "Mature object-relational mapper"
2079
+ },
2080
+ {
2081
+ value: "mapster",
2082
+ label: "Mapster",
2083
+ hint: "Fast object mapping with DI"
2084
+ },
2085
+ {
2086
+ value: "scrutor",
2087
+ label: "Scrutor",
2088
+ hint: "Assembly scanning and decoration"
2089
+ },
2090
+ {
2091
+ value: "refit",
2092
+ label: "Refit",
2093
+ hint: "Type-safe REST clients"
2094
+ },
2095
+ {
2096
+ value: "fluent-email",
2097
+ label: "FluentEmail",
2098
+ hint: "Fluent email composition"
2099
+ },
2100
+ {
2101
+ value: "none",
2102
+ label: "None",
2103
+ hint: "No additional .NET libraries"
2104
+ }
2105
+ ];
1980
2106
  const resolveDotnetWebFrameworkPrompt = (value) => createStaticSinglePromptResolution(WEB_FRAMEWORK_OPTIONS$1, "aspnet-minimal", value);
1981
2107
  const resolveDotnetOrmPrompt = (value) => createStaticSinglePromptResolution(ORM_OPTIONS$1, "ef-core", value);
1982
2108
  const resolveDotnetAuthPrompt = (value) => createStaticSinglePromptResolution(AUTH_OPTIONS$1, "aspnet-identity", value);
@@ -1987,6 +2113,7 @@ const resolveDotnetRealtimePrompt = (value) => createStaticSinglePromptResolutio
1987
2113
  const resolveDotnetObservabilityPrompt = (value) => createStaticMultiPromptResolution(OBSERVABILITY_OPTIONS$1, ["serilog"], value);
1988
2114
  const resolveDotnetCachingPrompt = (value) => createStaticSinglePromptResolution(CACHING_OPTIONS$1, "none", value);
1989
2115
  const resolveDotnetDeployPrompt = (value) => createStaticSinglePromptResolution(DEPLOY_OPTIONS$1, "docker", value);
2116
+ const resolveDotnetLibrariesPrompt = (value) => createStaticMultiPromptResolution(LIBRARIES_OPTIONS, [], value);
1990
2117
  const getDotnetWebFrameworkChoice = (value) => makeChoice$1("Select .NET web framework", WEB_FRAMEWORK_OPTIONS$1, "aspnet-minimal", value);
1991
2118
  const getDotnetOrmChoice = (value) => makeChoice$1("Select .NET data access", ORM_OPTIONS$1, "ef-core", value);
1992
2119
  const getDotnetAuthChoice = (value) => makeChoice$1("Select .NET auth", AUTH_OPTIONS$1, "aspnet-identity", value);
@@ -1998,6 +2125,7 @@ const getDotnetObservabilityChoice = (value) => makeMultiChoice$1("Select .NET o
1998
2125
  const getDotnetValidationChoice = (value) => makeChoice$1("Select .NET validation", VALIDATION_OPTIONS$1, "none", value);
1999
2126
  const getDotnetCachingChoice = (value) => makeChoice$1("Select .NET caching", CACHING_OPTIONS$1, "none", value);
2000
2127
  const getDotnetDeployChoice = (value) => makeChoice$1("Select .NET deploy target", DEPLOY_OPTIONS$1, "docker", value);
2128
+ const getDotnetLibrariesChoice = (value) => makeMultiChoice$1("Select .NET application libraries", LIBRARIES_OPTIONS, [], value);
2001
2129
 
2002
2130
  //#endregion
2003
2131
  //#region src/prompts/ecosystem.ts
@@ -3809,7 +3937,7 @@ async function getinstallChoice(install, ecosystem, javaBuildTool) {
3809
3937
  return false;
3810
3938
  }
3811
3939
  const response$1 = await navigableConfirm({
3812
- message: "Run uv sync?",
3940
+ message: "Run uv sync --extra dev?",
3813
3941
  initialValue: DEFAULT_CONFIG.install
3814
3942
  });
3815
3943
  if (isCancel$1(response$1)) return exitCancelled("Operation cancelled");
@@ -4095,6 +4223,106 @@ const JAVA_LIBRARY_PROMPT_OPTIONS = [
4095
4223
  label: "OpenTelemetry",
4096
4224
  hint: "OpenTelemetry SDK with OTLP export"
4097
4225
  },
4226
+ {
4227
+ value: "spring-data-redis",
4228
+ label: "Spring Data Redis",
4229
+ hint: "Redis repositories and template-based data access"
4230
+ },
4231
+ {
4232
+ value: "spring-data-mongodb",
4233
+ label: "Spring Data MongoDB",
4234
+ hint: "MongoDB repositories and document mapping"
4235
+ },
4236
+ {
4237
+ value: "spring-data-elasticsearch",
4238
+ label: "Spring Data Elasticsearch",
4239
+ hint: "Elasticsearch repositories and search operations"
4240
+ },
4241
+ {
4242
+ value: "spring-data-neo4j",
4243
+ label: "Spring Data Neo4j",
4244
+ hint: "Neo4j graph mapping and repositories"
4245
+ },
4246
+ {
4247
+ value: "spring-data-cassandra",
4248
+ label: "Spring Data Cassandra",
4249
+ hint: "Apache Cassandra mapping and repositories"
4250
+ },
4251
+ {
4252
+ value: "spring-data-couchbase",
4253
+ label: "Spring Data Couchbase",
4254
+ hint: "Couchbase document mapping and repositories"
4255
+ },
4256
+ {
4257
+ value: "spring-data-jdbc",
4258
+ label: "Spring Data JDBC",
4259
+ hint: "Aggregate-oriented relational persistence without JPA"
4260
+ },
4261
+ {
4262
+ value: "spring-data-rest",
4263
+ label: "Spring Data REST",
4264
+ hint: "REST endpoints backed by Spring Data repositories"
4265
+ },
4266
+ {
4267
+ value: "spring-quartz",
4268
+ label: "Quartz Scheduler",
4269
+ hint: "Durable scheduling and background jobs"
4270
+ },
4271
+ {
4272
+ value: "spring-pulsar",
4273
+ label: "Spring for Apache Pulsar",
4274
+ hint: "Apache Pulsar producers, consumers, and listeners"
4275
+ },
4276
+ {
4277
+ value: "spring-integration",
4278
+ label: "Spring Integration",
4279
+ hint: "Enterprise integration flows and messaging adapters"
4280
+ },
4281
+ {
4282
+ value: "spring-websocket",
4283
+ label: "Spring WebSocket",
4284
+ hint: "Real-time bidirectional WebSocket messaging"
4285
+ },
4286
+ {
4287
+ value: "spring-rsocket",
4288
+ label: "Spring RSocket",
4289
+ hint: "Reactive messaging over the RSocket protocol"
4290
+ },
4291
+ {
4292
+ value: "spring-hateoas",
4293
+ label: "Spring HATEOAS",
4294
+ hint: "Hypermedia links and representations for REST APIs"
4295
+ },
4296
+ {
4297
+ value: "spring-session-redis",
4298
+ label: "Spring Session Redis",
4299
+ hint: "Distributed HTTP sessions backed by Redis"
4300
+ },
4301
+ {
4302
+ value: "spring-session-jdbc",
4303
+ label: "Spring Session JDBC",
4304
+ hint: "Database-backed HTTP sessions through JDBC"
4305
+ },
4306
+ {
4307
+ value: "spring-ldap",
4308
+ label: "Spring LDAP",
4309
+ hint: "LDAP directory access and authentication support"
4310
+ },
4311
+ {
4312
+ value: "spring-oauth2-client",
4313
+ label: "Spring OAuth2 Client",
4314
+ hint: "OAuth2 login and authorized client support"
4315
+ },
4316
+ {
4317
+ value: "spring-saml2",
4318
+ label: "Spring SAML2",
4319
+ hint: "SAML 2.0 relying-party authentication"
4320
+ },
4321
+ {
4322
+ value: "spring-restclient",
4323
+ label: "Spring REST Client",
4324
+ hint: "Synchronous HTTP client with Spring RestClient"
4325
+ },
4098
4326
  {
4099
4327
  value: "none",
4100
4328
  label: "None",
@@ -4496,6 +4724,113 @@ const MOBILE_DEEP_LINKING_OPTIONS = [{
4496
4724
  label: "None",
4497
4725
  hint: "Skip deep link helpers"
4498
4726
  }];
4727
+ const MOBILE_LIBRARIES_OPTIONS = [
4728
+ {
4729
+ value: "expo-sqlite",
4730
+ label: "Expo SQLite",
4731
+ hint: "Persistent SQLite database"
4732
+ },
4733
+ {
4734
+ value: "expo-camera",
4735
+ label: "Expo Camera",
4736
+ hint: "Camera preview and capture"
4737
+ },
4738
+ {
4739
+ value: "expo-image-picker",
4740
+ label: "Expo Image Picker",
4741
+ hint: "System media picker"
4742
+ },
4743
+ {
4744
+ value: "expo-location",
4745
+ label: "Expo Location",
4746
+ hint: "Geolocation and geocoding"
4747
+ },
4748
+ {
4749
+ value: "expo-sensors",
4750
+ label: "Expo Sensors",
4751
+ hint: "Device motion and sensors"
4752
+ },
4753
+ {
4754
+ value: "expo-file-system",
4755
+ label: "Expo File System",
4756
+ hint: "Local file access"
4757
+ },
4758
+ {
4759
+ value: "expo-image",
4760
+ label: "Expo Image",
4761
+ hint: "Performant image component"
4762
+ },
4763
+ {
4764
+ value: "expo-audio",
4765
+ label: "Expo Audio",
4766
+ hint: "Audio playback and recording"
4767
+ },
4768
+ {
4769
+ value: "expo-video",
4770
+ label: "Expo Video",
4771
+ hint: "Cross-platform video playback"
4772
+ },
4773
+ {
4774
+ value: "expo-contacts",
4775
+ label: "Expo Contacts",
4776
+ hint: "Device contacts access"
4777
+ },
4778
+ {
4779
+ value: "expo-calendar",
4780
+ label: "Expo Calendar",
4781
+ hint: "Device calendars and events"
4782
+ },
4783
+ {
4784
+ value: "expo-local-authentication",
4785
+ label: "Expo Local Authentication",
4786
+ hint: "Biometric authentication"
4787
+ },
4788
+ {
4789
+ value: "expo-sharing",
4790
+ label: "Expo Sharing",
4791
+ hint: "Native share sheet"
4792
+ },
4793
+ {
4794
+ value: "expo-clipboard",
4795
+ label: "Expo Clipboard",
4796
+ hint: "System clipboard access"
4797
+ },
4798
+ {
4799
+ value: "expo-task-manager",
4800
+ label: "Expo Task Manager",
4801
+ hint: "Background task registry"
4802
+ },
4803
+ {
4804
+ value: "expo-background-task",
4805
+ label: "Expo Background Task",
4806
+ hint: "Deferrable background work"
4807
+ },
4808
+ {
4809
+ value: "expo-maps",
4810
+ label: "Expo Maps",
4811
+ hint: "Native Apple and Google maps"
4812
+ },
4813
+ {
4814
+ value: "expo-brightness",
4815
+ label: "Expo Brightness",
4816
+ hint: "Screen brightness control"
4817
+ },
4818
+ {
4819
+ value: "expo-battery",
4820
+ label: "Expo Battery",
4821
+ hint: "Battery status monitoring"
4822
+ },
4823
+ {
4824
+ value: "expo-screen-capture",
4825
+ label: "Expo Screen Capture",
4826
+ hint: "Screen capture detection and prevention"
4827
+ },
4828
+ {
4829
+ value: "none",
4830
+ label: "None",
4831
+ hint: "No additional mobile libraries"
4832
+ }
4833
+ ];
4499
4834
  async function promptMobileOption(options, defaultValue, selected, message) {
4500
4835
  const resolution = createStaticSinglePromptResolution(options, defaultValue, selected);
4501
4836
  if (!resolution.shouldPrompt) return resolution.autoValue ?? defaultValue;
@@ -4529,6 +4864,9 @@ function resolveMobileOTAPrompt(mobileOTA) {
4529
4864
  function resolveMobileDeepLinkingPrompt(mobileDeepLinking) {
4530
4865
  return createStaticSinglePromptResolution(MOBILE_DEEP_LINKING_OPTIONS, "expo-linking", mobileDeepLinking);
4531
4866
  }
4867
+ function resolveMobileLibrariesPrompt(mobileLibraries) {
4868
+ return createStaticMultiPromptResolution(MOBILE_LIBRARIES_OPTIONS, [], mobileLibraries);
4869
+ }
4532
4870
  function getMobileNavigationChoice(mobileNavigation) {
4533
4871
  return promptMobileOption(MOBILE_NAVIGATION_OPTIONS, "expo-router", mobileNavigation, "Select mobile navigation");
4534
4872
  }
@@ -4550,6 +4888,19 @@ function getMobileOTAChoice(mobileOTA) {
4550
4888
  function getMobileDeepLinkingChoice(mobileDeepLinking) {
4551
4889
  return promptMobileOption(MOBILE_DEEP_LINKING_OPTIONS, "expo-linking", mobileDeepLinking, "Select mobile deep linking");
4552
4890
  }
4891
+ async function getMobileLibrariesChoice(mobileLibraries) {
4892
+ const resolution = resolveMobileLibrariesPrompt(mobileLibraries);
4893
+ if (!resolution.shouldPrompt) return resolution.autoValue ?? [];
4894
+ if (!canPromptInteractively()) return [];
4895
+ const response = await navigableMultiselect({
4896
+ message: "Select mobile application libraries",
4897
+ options: resolution.options,
4898
+ required: false,
4899
+ initialValues: resolution.initialValue
4900
+ });
4901
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
4902
+ return response.includes("none") ? [] : response;
4903
+ }
4553
4904
 
4554
4905
  //#endregion
4555
4906
  //#region src/prompts/package-manager.ts
@@ -4615,6 +4966,16 @@ const PYTHON_WEB_FRAMEWORK_PROMPT_OPTIONS = [
4615
4966
  label: "Starlette",
4616
4967
  hint: "Minimal ASGI toolkit that powers FastAPI — great for lean async apps"
4617
4968
  },
4969
+ {
4970
+ value: "aiohttp",
4971
+ label: "aiohttp",
4972
+ hint: "Async HTTP server and client framework"
4973
+ },
4974
+ {
4975
+ value: "streamlit",
4976
+ label: "Streamlit",
4977
+ hint: "Turn Python data scripts into interactive web apps"
4978
+ },
4618
4979
  {
4619
4980
  value: "none",
4620
4981
  label: "None",
@@ -4642,6 +5003,11 @@ const PYTHON_ORM_PROMPT_OPTIONS = [
4642
5003
  label: "Peewee",
4643
5004
  hint: "Small, expressive ORM for SQLite, MySQL, and PostgreSQL"
4644
5005
  },
5006
+ {
5007
+ value: "pymongo",
5008
+ label: "PyMongo",
5009
+ hint: "Official MongoDB driver for Python"
5010
+ },
4645
5011
  {
4646
5012
  value: "none",
4647
5013
  label: "None",
@@ -4712,6 +5078,31 @@ const PYTHON_AI_PROMPT_OPTIONS = [
4712
5078
  value: "smolagents",
4713
5079
  label: "smolagents",
4714
5080
  hint: "HuggingFace's minimal, hackable agent library"
5081
+ },
5082
+ {
5083
+ value: "pytorch",
5084
+ label: "PyTorch",
5085
+ hint: "Tensor computation and deep learning platform"
5086
+ },
5087
+ {
5088
+ value: "transformers",
5089
+ label: "Transformers",
5090
+ hint: "Hugging Face pretrained model toolkit"
5091
+ },
5092
+ {
5093
+ value: "scikit-learn",
5094
+ label: "scikit-learn",
5095
+ hint: "Classical machine learning algorithms and pipelines"
5096
+ },
5097
+ {
5098
+ value: "tensorflow",
5099
+ label: "TensorFlow",
5100
+ hint: "End-to-end machine learning platform"
5101
+ },
5102
+ {
5103
+ value: "mcp",
5104
+ label: "MCP Python SDK",
5105
+ hint: "Official Model Context Protocol SDK"
4715
5106
  }
4716
5107
  ];
4717
5108
  const PYTHON_AUTH_PROMPT_OPTIONS = [
@@ -4725,6 +5116,11 @@ const PYTHON_AUTH_PROMPT_OPTIONS = [
4725
5116
  label: "JWT (python-jose)",
4726
5117
  hint: "Simple JWT token creation and verification"
4727
5118
  },
5119
+ {
5120
+ value: "pyjwt",
5121
+ label: "PyJWT",
5122
+ hint: "Focused JSON Web Token encoding and decoding"
5123
+ },
4728
5124
  {
4729
5125
  value: "fastapi-users",
4730
5126
  label: "FastAPI Users",
@@ -4963,6 +5359,11 @@ const PYTHON_TESTING_PROMPT_OPTIONS = [
4963
5359
  label: "Hypothesis",
4964
5360
  hint: "Property-based testing that generates edge-case inputs"
4965
5361
  },
5362
+ {
5363
+ value: "pytest-cov",
5364
+ label: "pytest-cov",
5365
+ hint: "Coverage reporting for pytest"
5366
+ },
4966
5367
  {
4967
5368
  value: "none",
4968
5369
  label: "None",
@@ -5003,15 +5404,23 @@ const PYTHON_REALTIME_PROMPT_OPTIONS = [
5003
5404
  hint: "No realtime layer"
5004
5405
  }
5005
5406
  ];
5006
- const PYTHON_OBSERVABILITY_PROMPT_OPTIONS = [{
5007
- value: "opentelemetry",
5008
- label: "OpenTelemetry",
5009
- hint: "Official OTel SDK with OTLP export and auto-instrumentation"
5010
- }, {
5011
- value: "none",
5012
- label: "None",
5013
- hint: "No tracing/metrics SDK"
5014
- }];
5407
+ const PYTHON_OBSERVABILITY_PROMPT_OPTIONS = [
5408
+ {
5409
+ value: "opentelemetry",
5410
+ label: "OpenTelemetry",
5411
+ hint: "Official OTel SDK with OTLP export and auto-instrumentation"
5412
+ },
5413
+ {
5414
+ value: "prometheus-client",
5415
+ label: "Prometheus Client",
5416
+ hint: "Prometheus metrics instrumentation and exposition"
5417
+ },
5418
+ {
5419
+ value: "none",
5420
+ label: "None",
5421
+ hint: "No tracing/metrics SDK"
5422
+ }
5423
+ ];
5015
5424
  const PYTHON_CLI_PROMPT_OPTIONS = [
5016
5425
  {
5017
5426
  value: "typer",
@@ -5034,6 +5443,90 @@ const PYTHON_CLI_PROMPT_OPTIONS = [
5034
5443
  hint: "No CLI tooling"
5035
5444
  }
5036
5445
  ];
5446
+ const PYTHON_CLOUD_SDK_PROMPT_OPTIONS = [{
5447
+ value: "boto3",
5448
+ label: "Boto3",
5449
+ hint: "Official AWS SDK for Python"
5450
+ }, {
5451
+ value: "none",
5452
+ label: "None",
5453
+ hint: "No cloud SDK"
5454
+ }];
5455
+ const PYTHON_HTTP_CLIENT_PROMPT_OPTIONS = [{
5456
+ value: "requests",
5457
+ label: "Requests",
5458
+ hint: "Simple, widely adopted synchronous HTTP client"
5459
+ }, {
5460
+ value: "none",
5461
+ label: "None",
5462
+ hint: "No HTTP client"
5463
+ }];
5464
+ const PYTHON_DATA_PROMPT_OPTIONS = [
5465
+ {
5466
+ value: "numpy",
5467
+ label: "NumPy",
5468
+ hint: "N-dimensional arrays and numerical computing"
5469
+ },
5470
+ {
5471
+ value: "pandas",
5472
+ label: "pandas",
5473
+ hint: "DataFrames and data analysis tools"
5474
+ },
5475
+ {
5476
+ value: "scipy",
5477
+ label: "SciPy",
5478
+ hint: "Scientific algorithms for optimization, statistics, and signals"
5479
+ },
5480
+ {
5481
+ value: "none",
5482
+ label: "None",
5483
+ hint: "No data/scientific libraries"
5484
+ }
5485
+ ];
5486
+ const PYTHON_MEDIA_PROMPT_OPTIONS = [{
5487
+ value: "pillow",
5488
+ label: "Pillow",
5489
+ hint: "Image loading, processing, and export"
5490
+ }, {
5491
+ value: "none",
5492
+ label: "None",
5493
+ hint: "No media library"
5494
+ }];
5495
+ const PYTHON_SERVER_PROMPT_OPTIONS = [{
5496
+ value: "gunicorn",
5497
+ label: "Gunicorn",
5498
+ hint: "Production WSGI/ASGI process manager"
5499
+ }, {
5500
+ value: "none",
5501
+ label: "None",
5502
+ hint: "No production server"
5503
+ }];
5504
+ const PYTHON_PACKAGE_MANAGER_PROMPT_OPTIONS = [
5505
+ {
5506
+ value: "uv",
5507
+ label: "uv",
5508
+ hint: "Fast Python package and project manager"
5509
+ },
5510
+ {
5511
+ value: "poetry",
5512
+ label: "Poetry",
5513
+ hint: "Dependency management and packaging workflow"
5514
+ },
5515
+ {
5516
+ value: "none",
5517
+ label: "None",
5518
+ hint: "Do not configure a Python package manager"
5519
+ }
5520
+ ];
5521
+ const PYTHON_MESSAGE_QUEUE_PROMPT_OPTIONS = [{
5522
+ value: "confluent-kafka",
5523
+ label: "Confluent Kafka",
5524
+ hint: "High-performance Apache Kafka producer and consumer client"
5525
+ }, {
5526
+ value: "none",
5527
+ label: "None",
5528
+ hint: "No message queue client"
5529
+ }];
5037
5530
  function resolvePythonTestingPrompt(pythonTesting) {
5038
5531
  return createStaticMultiPromptResolution(PYTHON_TESTING_PROMPT_OPTIONS, [], pythonTesting);
5039
5532
  }
@@ -5106,6 +5599,105 @@ async function getPythonCliChoice(pythonCli) {
5106
5599
  if (isCancel$1(response)) return exitCancelled("Operation cancelled");
5107
5600
  return response.includes("none") ? [] : response;
5108
5601
  }
5602
+ function resolvePythonCloudSdkPrompt(value) {
5603
+ return createStaticSinglePromptResolution(PYTHON_CLOUD_SDK_PROMPT_OPTIONS, "none", value);
5604
+ }
5605
+ async function getPythonCloudSdkChoice(value) {
5606
+ const resolution = resolvePythonCloudSdkPrompt(value);
5607
+ if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
5608
+ const response = await navigableSelect({
5609
+ message: "Select Python cloud SDK",
5610
+ options: resolution.options,
5611
+ initialValue: resolution.initialValue
5612
+ });
5613
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
5614
+ return response;
5615
+ }
5616
+ function resolvePythonHttpClientPrompt(value) {
5617
+ return createStaticSinglePromptResolution(PYTHON_HTTP_CLIENT_PROMPT_OPTIONS, "none", value);
5618
+ }
5619
+ async function getPythonHttpClientChoice(value) {
5620
+ const resolution = resolvePythonHttpClientPrompt(value);
5621
+ if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
5622
+ const response = await navigableSelect({
5623
+ message: "Select Python HTTP client",
5624
+ options: resolution.options,
5625
+ initialValue: resolution.initialValue
5626
+ });
5627
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
5628
+ return response;
5629
+ }
5630
+ function resolvePythonDataPrompt(value) {
5631
+ return createStaticMultiPromptResolution(PYTHON_DATA_PROMPT_OPTIONS, [], value);
5632
+ }
5633
+ async function getPythonDataChoice(value) {
5634
+ const resolution = resolvePythonDataPrompt(value);
5635
+ if (!resolution.shouldPrompt) return resolution.autoValue ?? [];
5636
+ const response = await navigableMultiselect({
5637
+ message: "Select Python data and scientific libraries",
5638
+ options: resolution.options,
5639
+ required: false,
5640
+ initialValues: resolution.initialValue
5641
+ });
5642
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
5643
+ return response.includes("none") ? [] : response;
5644
+ }
5645
+ function resolvePythonMediaPrompt(value) {
5646
+ return createStaticSinglePromptResolution(PYTHON_MEDIA_PROMPT_OPTIONS, "none", value);
5647
+ }
5648
+ async function getPythonMediaChoice(value) {
5649
+ const resolution = resolvePythonMediaPrompt(value);
5650
+ if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
5651
+ const response = await navigableSelect({
5652
+ message: "Select Python media library",
5653
+ options: resolution.options,
5654
+ initialValue: resolution.initialValue
5655
+ });
5656
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
5657
+ return response;
5658
+ }
5659
+ function resolvePythonServerPrompt(value) {
5660
+ return createStaticSinglePromptResolution(PYTHON_SERVER_PROMPT_OPTIONS, "none", value);
5661
+ }
5662
+ async function getPythonServerChoice(value) {
5663
+ const resolution = resolvePythonServerPrompt(value);
5664
+ if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
5665
+ const response = await navigableSelect({
5666
+ message: "Select Python production server",
5667
+ options: resolution.options,
5668
+ initialValue: resolution.initialValue
5669
+ });
5670
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
5671
+ return response;
5672
+ }
5673
+ function resolvePythonPackageManagerPrompt(value) {
5674
+ return createStaticSinglePromptResolution(PYTHON_PACKAGE_MANAGER_PROMPT_OPTIONS, "uv", value);
5675
+ }
5676
+ async function getPythonPackageManagerChoice(value) {
5677
+ const resolution = resolvePythonPackageManagerPrompt(value);
5678
+ if (!resolution.shouldPrompt) return resolution.autoValue ?? "uv";
5679
+ const response = await navigableSelect({
5680
+ message: "Select Python package manager",
5681
+ options: resolution.options,
5682
+ initialValue: resolution.initialValue
5683
+ });
5684
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
5685
+ return response;
5686
+ }
5687
+ function resolvePythonMessageQueuePrompt(value) {
5688
+ return createStaticSinglePromptResolution(PYTHON_MESSAGE_QUEUE_PROMPT_OPTIONS, "none", value);
5689
+ }
5690
+ async function getPythonMessageQueueChoice(value) {
5691
+ const resolution = resolvePythonMessageQueuePrompt(value);
5692
+ if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
5693
+ const response = await navigableSelect({
5694
+ message: "Select Python message queue client",
5695
+ options: resolution.options,
5696
+ initialValue: resolution.initialValue
5697
+ });
5698
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
5699
+ return response;
5700
+ }
5109
5701
 
5110
5702
  //#endregion
5111
5703
  //#region src/prompts/rust-ecosystem.ts
@@ -6562,6 +7154,13 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
6562
7154
  const pythonRealtime = pythonWebFramework === "none" ? "none" : await scopedPromptValue("python", "pythonRealtime", configScope, backendSections, () => getPythonRealtimeChoice(flags.pythonRealtime));
6563
7155
  const pythonObservability = pythonWebFramework === "none" ? "none" : await scopedPromptValue("python", "pythonObservability", configScope, backendSections, () => getPythonObservabilityChoice(flags.pythonObservability));
6564
7156
  const pythonCli = pythonWebFramework === "none" ? [] : await scopedPromptValue("python", "pythonCli", configScope, backendSections, () => getPythonCliChoice(flags.pythonCli));
7157
+ const pythonCloudSdk = pythonWebFramework === "none" ? "none" : await scopedPromptValue("python", "pythonCloudSdk", configScope, backendSections, () => getPythonCloudSdkChoice(flags.pythonCloudSdk));
7158
+ const pythonHttpClient = pythonWebFramework === "none" ? "none" : await scopedPromptValue("python", "pythonHttpClient", configScope, backendSections, () => getPythonHttpClientChoice(flags.pythonHttpClient));
7159
+ const pythonData = pythonWebFramework === "none" ? [] : await scopedPromptValue("python", "pythonData", configScope, backendSections, () => getPythonDataChoice(flags.pythonData));
7160
+ const pythonMedia = pythonWebFramework === "none" ? "none" : await scopedPromptValue("python", "pythonMedia", configScope, backendSections, () => getPythonMediaChoice(flags.pythonMedia));
7161
+ const pythonServer = pythonWebFramework === "none" ? "none" : await scopedPromptValue("python", "pythonServer", configScope, backendSections, () => getPythonServerChoice(flags.pythonServer));
7162
+ const pythonPackageManager = pythonWebFramework === "none" ? "uv" : await scopedPromptValue("python", "pythonPackageManager", configScope, backendSections, () => getPythonPackageManagerChoice(flags.pythonPackageManager));
7163
+ const pythonMessageQueue = pythonWebFramework === "none" ? "none" : await scopedPromptValue("python", "pythonMessageQueue", configScope, backendSections, () => getPythonMessageQueueChoice(flags.pythonMessageQueue));
6565
7164
  Object.assign(backendChoices, {
6566
7165
  pythonWebFramework,
6567
7166
  pythonOrm,
@@ -6575,7 +7174,14 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
6575
7174
  pythonCaching,
6576
7175
  pythonRealtime,
6577
7176
  pythonObservability,
6578
- pythonCli
7177
+ pythonCli,
7178
+ pythonCloudSdk,
7179
+ pythonHttpClient,
7180
+ pythonData,
7181
+ pythonMedia,
7182
+ pythonServer,
7183
+ pythonPackageManager,
7184
+ pythonMessageQueue
6579
7185
  });
6580
7186
  if (pythonWebFramework !== "none") stackPartSpecs.push(`backend:python:${pythonWebFramework}`);
6581
7187
  if (pythonOrm !== "none") stackPartSpecs.push(`backend.orm:python:${pythonOrm}`);
@@ -6587,6 +7193,13 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
6587
7193
  if (pythonRealtime !== "none") stackPartSpecs.push(`backend.realtime:python:${pythonRealtime}`);
6588
7194
  if (pythonObservability !== "none") stackPartSpecs.push(`backend.observability:python:${pythonObservability}`);
6589
7195
  for (const cli of pythonCli) if (cli !== "none") stackPartSpecs.push(`backend.cli:python:${cli}`);
7196
+ if (pythonCloudSdk !== "none") stackPartSpecs.push(`backend.cloudSdk:python:${pythonCloudSdk}`);
7197
+ if (pythonHttpClient !== "none") stackPartSpecs.push(`backend.httpClient:python:${pythonHttpClient}`);
7198
+ for (const data of pythonData) if (data !== "none") stackPartSpecs.push(`backend.data:python:${data}`);
7199
+ if (pythonMedia !== "none") stackPartSpecs.push(`backend.media:python:${pythonMedia}`);
7200
+ if (pythonServer !== "none") stackPartSpecs.push(`backend.server:python:${pythonServer}`);
7201
+ if (pythonPackageManager !== "none") stackPartSpecs.push(`backend.packageManager:python:${pythonPackageManager}`);
7202
+ if (pythonMessageQueue !== "none") stackPartSpecs.push(`backend.messageQueue:python:${pythonMessageQueue}`);
6590
7203
  }
6591
7204
  if (backendEcosystem === "java") {
6592
7205
  const javaWebFramework = promptValue(await getJavaWebFrameworkChoice(flags.javaWebFramework));
@@ -6638,6 +7251,7 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
6638
7251
  const dotnetValidation = dotnetWebFramework === "none" ? "none" : await scopedPromptValue("dotnet", "dotnetValidation", configScope, backendSections, () => getDotnetValidationChoice(flags.dotnetValidation));
6639
7252
  const dotnetCaching = dotnetWebFramework === "none" ? "none" : await scopedPromptValue("dotnet", "dotnetCaching", configScope, backendSections, () => getDotnetCachingChoice(flags.dotnetCaching));
6640
7253
  const dotnetDeploy = dotnetWebFramework === "none" ? "none" : await scopedPromptValue("dotnet", "dotnetDeploy", configScope, backendSections, () => getDotnetDeployChoice(flags.dotnetDeploy));
7254
+ const dotnetLibraries = dotnetWebFramework === "none" ? [] : await scopedPromptValue("dotnet", "dotnetLibraries", configScope, backendSections, () => getDotnetLibrariesChoice(flags.dotnetLibraries));
6641
7255
  Object.assign(backendChoices, {
6642
7256
  dotnetWebFramework,
6643
7257
  dotnetOrm,
@@ -6649,7 +7263,8 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
6649
7263
  dotnetObservability,
6650
7264
  dotnetValidation,
6651
7265
  dotnetCaching,
6652
- dotnetDeploy
7266
+ dotnetDeploy,
7267
+ dotnetLibraries
6653
7268
  });
6654
7269
  if (dotnetWebFramework !== "none") stackPartSpecs.push(`backend:dotnet:${dotnetWebFramework}`);
6655
7270
  if (dotnetOrm !== "none") stackPartSpecs.push(`backend.orm:dotnet:${dotnetOrm}`);
@@ -6662,6 +7277,7 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
6662
7277
  if (dotnetValidation !== "none") stackPartSpecs.push(`backend.validation:dotnet:${dotnetValidation}`);
6663
7278
  if (dotnetCaching !== "none") stackPartSpecs.push(`backend.caching:dotnet:${dotnetCaching}`);
6664
7279
  if (dotnetDeploy !== "none") stackPartSpecs.push(`backend.deploy:dotnet:${dotnetDeploy}`);
7280
+ for (const library of dotnetLibraries) if (library !== "none") stackPartSpecs.push(`backend.libraries:dotnet:${library}`);
6665
7281
  }
6666
7282
  if (backendEcosystem === "elixir") {
6667
7283
  const elixirWebFramework = promptValue(await getElixirWebFrameworkChoice(flags.elixirWebFramework));
@@ -7738,6 +8354,11 @@ const PROMPT_RESOLVER_REGISTRY = {
7738
8354
  resolve: ({ value } = {}) => resolveMobileDeepLinkingPrompt(value),
7739
8355
  coverageContexts: [{}]
7740
8356
  },
8357
+ mobileLibraries: {
8358
+ schemaValues: types_exports.MOBILE_LIBRARIES_VALUES,
8359
+ resolve: ({ value } = {}) => resolveMobileLibrariesPrompt(value),
8360
+ coverageContexts: [{}, { value: ["none"] }]
8361
+ },
7741
8362
  uiLibrary: {
7742
8363
  schemaValues: types_exports.UI_LIBRARY_VALUES,
7743
8364
  resolve: resolveUILibraryPrompt,
@@ -7848,6 +8469,41 @@ const PROMPT_RESOLVER_REGISTRY = {
7848
8469
  resolve: ({ value } = {}) => resolvePythonQualityPrompt(value),
7849
8470
  coverageContexts: [{}]
7850
8471
  },
8472
+ pythonCloudSdk: {
8473
+ schemaValues: types_exports.PYTHON_CLOUD_SDK_VALUES,
8474
+ resolve: ({ value } = {}) => resolvePythonCloudSdkPrompt(value),
8475
+ coverageContexts: [{}]
8476
+ },
8477
+ pythonHttpClient: {
8478
+ schemaValues: types_exports.PYTHON_HTTP_CLIENT_VALUES,
8479
+ resolve: ({ value } = {}) => resolvePythonHttpClientPrompt(value),
8480
+ coverageContexts: [{}]
8481
+ },
8482
+ pythonData: {
8483
+ schemaValues: types_exports.PYTHON_DATA_VALUES,
8484
+ resolve: ({ value } = {}) => resolvePythonDataPrompt(value),
8485
+ coverageContexts: [{}, { value: ["none"] }]
8486
+ },
8487
+ pythonMedia: {
8488
+ schemaValues: types_exports.PYTHON_MEDIA_VALUES,
8489
+ resolve: ({ value } = {}) => resolvePythonMediaPrompt(value),
8490
+ coverageContexts: [{}]
8491
+ },
8492
+ pythonServer: {
8493
+ schemaValues: types_exports.PYTHON_SERVER_VALUES,
8494
+ resolve: ({ value } = {}) => resolvePythonServerPrompt(value),
8495
+ coverageContexts: [{}]
8496
+ },
8497
+ pythonPackageManager: {
8498
+ schemaValues: types_exports.PYTHON_PACKAGE_MANAGER_VALUES,
8499
+ resolve: ({ value } = {}) => resolvePythonPackageManagerPrompt(value),
8500
+ coverageContexts: [{}]
8501
+ },
8502
+ pythonMessageQueue: {
8503
+ schemaValues: types_exports.PYTHON_MESSAGE_QUEUE_VALUES,
8504
+ resolve: ({ value } = {}) => resolvePythonMessageQueuePrompt(value),
8505
+ coverageContexts: [{}]
8506
+ },
7851
8507
  goWebFramework: {
7852
8508
  schemaValues: types_exports.GO_WEB_FRAMEWORK_VALUES,
7853
8509
  resolve: ({ value } = {}) => resolveGoWebFrameworkPrompt(value),
@@ -7988,6 +8644,11 @@ const PROMPT_RESOLVER_REGISTRY = {
7988
8644
  resolve: ({ value } = {}) => resolveDotnetDeployPrompt(value),
7989
8645
  coverageContexts: [{}]
7990
8646
  },
8647
+ dotnetLibraries: {
8648
+ schemaValues: types_exports.DOTNET_LIBRARIES_VALUES,
8649
+ resolve: ({ value } = {}) => resolveDotnetLibrariesPrompt(value),
8650
+ coverageContexts: [{}, { value: ["none"] }]
8651
+ },
7991
8652
  elixirWebFramework: {
7992
8653
  schemaValues: types_exports.ELIXIR_WEB_FRAMEWORK_VALUES,
7993
8654
  resolve: ({ value } = {}) => resolveElixirWebFrameworkPrompt(value),
@@ -8419,6 +9080,7 @@ const CONFIG_PROMPT_ENTRY_KEY_MAP = {
8419
9080
  mobilePush: true,
8420
9081
  mobileOTA: true,
8421
9082
  mobileDeepLinking: true,
9083
+ mobileLibraries: true,
8422
9084
  rustWebFramework: true,
8423
9085
  rustFrontend: true,
8424
9086
  rustOrm: true,
@@ -8447,6 +9109,13 @@ const CONFIG_PROMPT_ENTRY_KEY_MAP = {
8447
9109
  pythonRealtime: true,
8448
9110
  pythonObservability: true,
8449
9111
  pythonCli: true,
9112
+ pythonCloudSdk: true,
9113
+ pythonHttpClient: true,
9114
+ pythonData: true,
9115
+ pythonMedia: true,
9116
+ pythonServer: true,
9117
+ pythonPackageManager: true,
9118
+ pythonMessageQueue: true,
8450
9119
  goWebFramework: true,
8451
9120
  goOrm: true,
8452
9121
  goApi: true,
@@ -8485,6 +9154,7 @@ const CONFIG_PROMPT_ENTRY_KEY_MAP = {
8485
9154
  dotnetValidation: true,
8486
9155
  dotnetCaching: true,
8487
9156
  dotnetDeploy: true,
9157
+ dotnetLibraries: true,
8488
9158
  elixirWebFramework: true,
8489
9159
  elixirOrm: true,
8490
9160
  elixirAuth: true,
@@ -8900,6 +9570,11 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
8900
9570
  if (!results.frontend?.some((frontend) => frontend.startsWith("native-"))) return Promise.resolve("none");
8901
9571
  return getMobileDeepLinkingChoice(flags.mobileDeepLinking);
8902
9572
  },
9573
+ mobileLibraries: ({ results }) => {
9574
+ if (results.ecosystem !== "typescript" && results.ecosystem !== "react-native") return Promise.resolve([]);
9575
+ if (!results.frontend?.some((frontend) => frontend.startsWith("native-"))) return Promise.resolve([]);
9576
+ return getMobileLibrariesChoice(flags.mobileLibraries);
9577
+ },
8903
9578
  rustWebFramework: ({ results }) => {
8904
9579
  if (results.ecosystem !== "rust") return Promise.resolve("none");
8905
9580
  return getRustWebFrameworkChoice(flags.rustWebFramework);
@@ -9013,6 +9688,34 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
9013
9688
  if (results.ecosystem !== "python") return Promise.resolve([]);
9014
9689
  return getPythonCliChoice(flags.pythonCli);
9015
9690
  },
9691
+ pythonCloudSdk: ({ results }) => {
9692
+ if (results.ecosystem !== "python") return Promise.resolve("none");
9693
+ return getPythonCloudSdkChoice(flags.pythonCloudSdk);
9694
+ },
9695
+ pythonHttpClient: ({ results }) => {
9696
+ if (results.ecosystem !== "python") return Promise.resolve("none");
9697
+ return getPythonHttpClientChoice(flags.pythonHttpClient);
9698
+ },
9699
+ pythonData: ({ results }) => {
9700
+ if (results.ecosystem !== "python") return Promise.resolve([]);
9701
+ return getPythonDataChoice(flags.pythonData);
9702
+ },
9703
+ pythonMedia: ({ results }) => {
9704
+ if (results.ecosystem !== "python") return Promise.resolve("none");
9705
+ return getPythonMediaChoice(flags.pythonMedia);
9706
+ },
9707
+ pythonServer: ({ results }) => {
9708
+ if (results.ecosystem !== "python") return Promise.resolve("none");
9709
+ return getPythonServerChoice(flags.pythonServer);
9710
+ },
9711
+ pythonPackageManager: ({ results }) => {
9712
+ if (results.ecosystem !== "python") return Promise.resolve("uv");
9713
+ return getPythonPackageManagerChoice(flags.pythonPackageManager);
9714
+ },
9715
+ pythonMessageQueue: ({ results }) => {
9716
+ if (results.ecosystem !== "python") return Promise.resolve("none");
9717
+ return getPythonMessageQueueChoice(flags.pythonMessageQueue);
9718
+ },
9016
9719
  goWebFramework: ({ results }) => {
9017
9720
  if (results.ecosystem !== "go") return Promise.resolve("none");
9018
9721
  return getGoWebFrameworkChoice(flags.goWebFramework);
@@ -9198,6 +9901,11 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
9198
9901
  if (results.dotnetWebFramework === "none") return Promise.resolve("none");
9199
9902
  return getDotnetDeployChoice(flags.dotnetDeploy);
9200
9903
  },
9904
+ dotnetLibraries: ({ results }) => {
9905
+ if (results.ecosystem !== "dotnet") return Promise.resolve([]);
9906
+ if (results.dotnetWebFramework === "none") return Promise.resolve([]);
9907
+ return getDotnetLibrariesChoice(flags.dotnetLibraries);
9908
+ },
9201
9909
  elixirWebFramework: ({ results }) => {
9202
9910
  if (results.ecosystem !== "elixir") return Promise.resolve("none");
9203
9911
  return getElixirWebFrameworkChoice(flags.elixirWebFramework);
@@ -9345,6 +10053,7 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
9345
10053
  mobilePush: result.mobilePush,
9346
10054
  mobileOTA: result.mobileOTA,
9347
10055
  mobileDeepLinking: result.mobileDeepLinking,
10056
+ mobileLibraries: result.mobileLibraries,
9348
10057
  ecosystem: result.ecosystem,
9349
10058
  rustWebFramework: result.rustWebFramework,
9350
10059
  rustFrontend: result.rustFrontend,
@@ -9374,6 +10083,13 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
9374
10083
  pythonRealtime: result.pythonRealtime,
9375
10084
  pythonObservability: result.pythonObservability,
9376
10085
  pythonCli: result.pythonCli,
10086
+ pythonCloudSdk: result.pythonCloudSdk,
10087
+ pythonHttpClient: result.pythonHttpClient,
10088
+ pythonData: result.pythonData,
10089
+ pythonMedia: result.pythonMedia,
10090
+ pythonServer: result.pythonServer,
10091
+ pythonPackageManager: result.pythonPackageManager,
10092
+ pythonMessageQueue: result.pythonMessageQueue,
9377
10093
  goWebFramework: result.goWebFramework,
9378
10094
  goOrm: result.goOrm,
9379
10095
  goApi: result.goApi,
@@ -9412,6 +10128,7 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
9412
10128
  dotnetValidation: result.dotnetValidation,
9413
10129
  dotnetCaching: result.dotnetCaching,
9414
10130
  dotnetDeploy: result.dotnetDeploy,
10131
+ dotnetLibraries: result.dotnetLibraries,
9415
10132
  elixirWebFramework: result.elixirWebFramework,
9416
10133
  elixirOrm: result.elixirOrm,
9417
10134
  elixirAuth: result.elixirAuth,
@@ -9698,6 +10415,8 @@ function displayConfig(config) {
9698
10415
  if (config.mobilePush !== void 0) configDisplay.push(`${pc.blue("Mobile Push:")} ${String(config.mobilePush)}`);
9699
10416
  if (config.mobileOTA !== void 0) configDisplay.push(`${pc.blue("Mobile OTA:")} ${String(config.mobileOTA)}`);
9700
10417
  if (config.mobileDeepLinking !== void 0) configDisplay.push(`${pc.blue("Mobile Deep Linking:")} ${String(config.mobileDeepLinking)}`);
10418
+ if (config.mobileLibraries && config.mobileLibraries.length > 0) configDisplay.push(`${pc.blue("Mobile Libraries:")} ${config.mobileLibraries.join(", ")}`);
10419
+ if (config.dotnetLibraries && config.dotnetLibraries.length > 0) configDisplay.push(`${pc.blue(".NET Libraries:")} ${config.dotnetLibraries.join(", ")}`);
9701
10420
  if (config.caching !== void 0) configDisplay.push(`${pc.blue("Caching:")} ${String(config.caching)}`);
9702
10421
  if (config.i18n !== void 0) configDisplay.push(`${pc.blue("i18n:")} ${String(config.i18n)}`);
9703
10422
  if (config.cms !== void 0) configDisplay.push(`${pc.blue("CMS:")} ${String(config.cms)}`);
@@ -11731,7 +12450,27 @@ function displayJavaInstructions(config) {
11731
12450
  "springdoc-openapi": "Springdoc OpenAPI",
11732
12451
  lombok: "Lombok",
11733
12452
  mapstruct: "MapStruct",
11734
- caffeine: "Caffeine"
12453
+ caffeine: "Caffeine",
12454
+ "spring-data-redis": "Spring Data Redis",
12455
+ "spring-data-mongodb": "Spring Data MongoDB",
12456
+ "spring-data-elasticsearch": "Spring Data Elasticsearch",
12457
+ "spring-data-neo4j": "Spring Data Neo4j",
12458
+ "spring-data-cassandra": "Spring Data Cassandra",
12459
+ "spring-data-couchbase": "Spring Data Couchbase",
12460
+ "spring-data-jdbc": "Spring Data JDBC",
12461
+ "spring-data-rest": "Spring Data REST",
12462
+ "spring-quartz": "Quartz Scheduler",
12463
+ "spring-pulsar": "Spring for Apache Pulsar",
12464
+ "spring-integration": "Spring Integration",
12465
+ "spring-websocket": "Spring WebSocket",
12466
+ "spring-rsocket": "Spring RSocket",
12467
+ "spring-hateoas": "Spring HATEOAS",
12468
+ "spring-session-redis": "Spring Session Redis",
12469
+ "spring-session-jdbc": "Spring Session JDBC",
12470
+ "spring-ldap": "Spring LDAP",
12471
+ "spring-oauth2-client": "Spring OAuth2 Client",
12472
+ "spring-saml2": "Spring SAML2",
12473
+ "spring-restclient": "Spring REST Client"
11735
12474
  };
11736
12475
  const libraryList = effectiveJavaLibraries.map((library) => libraryNames[library] || library).join(", ");
11737
12476
  output += `${pc.cyan("•")} Libraries: ${libraryList}\n`;
@@ -11770,27 +12509,37 @@ function displayJavaInstructions(config) {
11770
12509
  consola$1.box(output);
11771
12510
  }
11772
12511
  function displayPythonInstructions(config) {
11773
- const { relativePath, depsInstalled, pythonWebFramework, pythonOrm, pythonValidation, pythonAi, pythonApi, pythonTaskQueue, pythonQuality } = config;
12512
+ const { relativePath, depsInstalled, pythonWebFramework, pythonOrm, pythonValidation, pythonAi, pythonApi, pythonTaskQueue, pythonQuality, pythonPackageManager } = config;
11774
12513
  const cdCmd = `cd ${relativePath}`;
11775
- let runCommand = "uv run uvicorn app.main:app --reload";
11776
- if (pythonWebFramework === "django") runCommand = "uv run python manage.py runserver";
11777
- else if (pythonWebFramework === "flask") runCommand = "uv run flask --app app.main run --reload";
11778
- else if (pythonWebFramework === "litestar") runCommand = "litestar --app src.app.main:app run --reload --port 3001";
12514
+ const venvBin = process.platform === "win32" ? ".venv\\Scripts\\" : ".venv/bin/";
12515
+ const runPrefix = pythonPackageManager === "poetry" ? "poetry run " : pythonPackageManager === "uv" ? "uv run " : venvBin;
12516
+ const installCommand = pythonPackageManager === "poetry" ? "poetry install --extras dev" : pythonPackageManager === "uv" ? "uv sync --extra dev" : `${process.platform === "win32" ? "python" : "python3"} -m venv .venv && ${venvBin}pip install -e ".[dev]"`;
12517
+ let runCommand = `${runPrefix}uvicorn app.main:app --reload`;
12518
+ if (pythonWebFramework === "django") runCommand = `${runPrefix}python -m app.main`;
12519
+ else if (pythonWebFramework === "flask") runCommand = `${runPrefix}flask --app app.main run --reload --port 8000`;
12520
+ else if (pythonWebFramework === "litestar") runCommand = `${runPrefix}litestar --app src.app.main:app run --reload --port 8000`;
12521
+ else if (pythonWebFramework === "streamlit") runCommand = `${runPrefix}streamlit run src/app/main.py --server.port 8000`;
12522
+ else if (pythonWebFramework !== "fastapi") runCommand = `${runPrefix}python -m app.main`;
11779
12523
  let output = `${pc.bold("Next steps")}\n${pc.cyan("1.")} ${cdCmd}\n`;
11780
12524
  let stepCounter = 2;
11781
- if (!depsInstalled) output += `${pc.cyan(`${stepCounter++}.`)} uv sync\n`;
12525
+ if (!depsInstalled) output += `${pc.cyan(`${stepCounter++}.`)} ${installCommand}\n`;
11782
12526
  output += `${pc.cyan(`${stepCounter++}.`)} ${runCommand}\n`;
11783
12527
  output += `\n${pc.bold("Your Python project includes:")}\n`;
11784
12528
  if (pythonWebFramework && pythonWebFramework !== "none") output += `${pc.cyan("•")} Web Framework: ${{
11785
12529
  fastapi: "FastAPI",
11786
12530
  django: "Django",
11787
12531
  flask: "Flask",
11788
- litestar: "Litestar"
12532
+ litestar: "Litestar",
12533
+ starlette: "Starlette",
12534
+ aiohttp: "aiohttp",
12535
+ streamlit: "Streamlit"
11789
12536
  }[pythonWebFramework] || pythonWebFramework}\n`;
11790
12537
  if (pythonOrm && pythonOrm !== "none") output += `${pc.cyan("•")} ORM: ${{
11791
12538
  sqlalchemy: "SQLAlchemy",
11792
12539
  sqlmodel: "SQLModel",
11793
- "tortoise-orm": "Tortoise ORM"
12540
+ "tortoise-orm": "Tortoise ORM",
12541
+ peewee: "Peewee",
12542
+ pymongo: "PyMongo"
11794
12543
  }[pythonOrm] || pythonOrm}\n`;
11795
12544
  if (pythonValidation && pythonValidation !== "none") output += `${pc.cyan("•")} Validation: ${{ pydantic: "Pydantic" }[pythonValidation] || pythonValidation}\n`;
11796
12545
  if (pythonAi && pythonAi.length > 0 && !pythonAi.includes("none")) {
@@ -11800,7 +12549,12 @@ function displayPythonInstructions(config) {
11800
12549
  llamaindex: "LlamaIndex",
11801
12550
  "openai-sdk": "OpenAI SDK",
11802
12551
  "anthropic-sdk": "Anthropic SDK",
11803
- crewai: "CrewAI"
12552
+ crewai: "CrewAI",
12553
+ pytorch: "PyTorch",
12554
+ transformers: "Transformers",
12555
+ "scikit-learn": "scikit-learn",
12556
+ tensorflow: "TensorFlow",
12557
+ mcp: "MCP Python SDK"
11804
12558
  };
11805
12559
  const aiList = pythonAi.filter((ai) => ai !== "none").map((ai) => aiNames[ai] || ai).join(", ");
11806
12560
  output += `${pc.cyan("•")} AI: ${aiList}\n`;
@@ -11816,14 +12570,14 @@ function displayPythonInstructions(config) {
11816
12570
  pyright: "Pyright"
11817
12571
  }[pythonQuality] || pythonQuality}\n`;
11818
12572
  output += `\n${pc.bold("Common Python commands:")}\n`;
11819
- output += `${pc.cyan("•")} Install: uv sync\n`;
12573
+ output += `${pc.cyan("•")} Install: ${installCommand}\n`;
11820
12574
  output += `${pc.cyan("•")} Run: ${runCommand}\n`;
11821
- output += `${pc.cyan("•")} Test: uv run pytest\n`;
12575
+ output += `${pc.cyan("•")} Test: ${runPrefix}pytest\n`;
11822
12576
  if (pythonQuality === "ruff") {
11823
- output += `${pc.cyan("•")} Format: uv run ruff format .\n`;
11824
- output += `${pc.cyan("•")} Lint: uv run ruff check .\n`;
11825
- } else if (pythonQuality === "mypy") output += `${pc.cyan("•")} Type check: uv run mypy src/app tests\n`;
11826
- else if (pythonQuality === "pyright") output += `${pc.cyan("•")} Type check: uv run pyright\n`;
12577
+ output += `${pc.cyan("•")} Format: ${runPrefix}ruff format .\n`;
12578
+ output += `${pc.cyan("•")} Lint: ${runPrefix}ruff check .\n`;
12579
+ } else if (pythonQuality === "mypy") output += `${pc.cyan("•")} Type check: ${runPrefix}mypy src/app tests\n`;
12580
+ else if (pythonQuality === "pyright") output += `${pc.cyan("•")} Type check: ${runPrefix}pyright\n`;
11827
12581
  output += `\n${pc.bold("Your project will be available at:")}\n`;
11828
12582
  output += `${pc.cyan("•")} API: http://localhost:8000\n`;
11829
12583
  output += `\n${pc.bold("Enjoying Better Fullstack?")} Help us grow — star the repo!\n`;
@@ -11902,7 +12656,10 @@ async function createProject(options, cliInput = {}) {
11902
12656
  if (!result$1.success) setupFailures.push(result$1);
11903
12657
  }
11904
12658
  if (options.install && options.ecosystem === "python") {
11905
- const result$1 = await runUvSync({ projectDir });
12659
+ const result$1 = await runPythonInstall({
12660
+ projectDir,
12661
+ packageManager: options.pythonPackageManager
12662
+ });
11906
12663
  if (!result$1.success) setupFailures.push(result$1);
11907
12664
  }
11908
12665
  if (options.install && options.ecosystem === "go") {
@@ -12087,7 +12844,8 @@ function getYesBaseConfig(flagConfig) {
12087
12844
  mobileTesting: "none",
12088
12845
  mobilePush: "none",
12089
12846
  mobileOTA: "none",
12090
- mobileDeepLinking: "none"
12847
+ mobileDeepLinking: "none",
12848
+ mobileLibraries: []
12091
12849
  };
12092
12850
  }
12093
12851
  function reportCompatibilityAdjustments(adjustments) {
@@ -12235,6 +12993,7 @@ async function createProjectHandler(input, options = {}) {
12235
12993
  mobilePush: "none",
12236
12994
  mobileOTA: "none",
12237
12995
  mobileDeepLinking: "none",
12996
+ mobileLibraries: [],
12238
12997
  pythonWebFramework: "none",
12239
12998
  pythonOrm: "none",
12240
12999
  pythonValidation: "none",
@@ -12249,6 +13008,13 @@ async function createProjectHandler(input, options = {}) {
12249
13008
  pythonRealtime: "none",
12250
13009
  pythonObservability: "none",
12251
13010
  pythonCli: [],
13011
+ pythonCloudSdk: "none",
13012
+ pythonHttpClient: "none",
13013
+ pythonData: [],
13014
+ pythonMedia: "none",
13015
+ pythonServer: "none",
13016
+ pythonPackageManager: "uv",
13017
+ pythonMessageQueue: "none",
12252
13018
  goWebFramework: "none",
12253
13019
  goOrm: "none",
12254
13020
  goApi: "none",
@@ -12286,6 +13052,7 @@ async function createProjectHandler(input, options = {}) {
12286
13052
  dotnetValidation: "none",
12287
13053
  dotnetCaching: "none",
12288
13054
  dotnetDeploy: "none",
13055
+ dotnetLibraries: [],
12289
13056
  elixirWebFramework: "none",
12290
13057
  elixirOrm: "none",
12291
13058
  elixirAuth: "none",
@@ -12674,7 +13441,7 @@ const router = os.router({
12674
13441
  }
12675
13442
  }),
12676
13443
  add: os.meta({ description: "Add addons, deploy targets, or stack capabilities to an existing Better Fullstack project using its bts.jsonc config" }).input(AddCommandInputSchema).handler(async ({ input }) => {
12677
- const { addHandler } = await import("./add-handler-CE3XIs3y.mjs");
13444
+ const { addHandler } = await import("./add-handler-z4NCxoq6.mjs");
12678
13445
  await addHandler(input);
12679
13446
  }),
12680
13447
  history: os.meta({ description: "Show history of scaffolded projects with reproducible commands" }).input(z.object({
@@ -12702,7 +13469,7 @@ const router = os.router({
12702
13469
  ecosystem: z.string().optional().describe("Filter by ecosystem (effect, tanstack, prisma, etc.)"),
12703
13470
  "list-ecosystems": z.boolean().default(false).describe("List available ecosystems")
12704
13471
  })).handler(async ({ input }) => {
12705
- const { updateDepsHandler, showEcosystems } = await import("./update-deps-aD-iQw4U.mjs");
13472
+ const { updateDepsHandler, showEcosystems } = await import("./update-deps-G3FgqBlW.mjs");
12706
13473
  if (input["list-ecosystems"]) {
12707
13474
  showEcosystems();
12708
13475
  return;
@@ -12723,7 +13490,7 @@ const router = os.router({
12723
13490
  })
12724
13491
  ])).handler(async ({ input }) => {
12725
13492
  const [kind, name, options] = input;
12726
- const { genCommand } = await import("./gen-BZ0QCxCC.mjs");
13493
+ const { genCommand } = await import("./gen-CQfQU0uZ.mjs");
12727
13494
  await genCommand({
12728
13495
  kind,
12729
13496
  name,
@@ -12741,7 +13508,7 @@ const router = os.router({
12741
13508
  })
12742
13509
  ])).handler(async ({ input }) => {
12743
13510
  const [action, source, options] = input;
12744
- const { registryHandler } = await import("./registry-Cm3D45oT.mjs");
13511
+ const { registryHandler } = await import("./registry-D0JfLCoH.mjs");
12745
13512
  await registryHandler({
12746
13513
  action,
12747
13514
  source,
@@ -12758,7 +13525,7 @@ const router = os.router({
12758
13525
  recordBaseline: z.boolean().optional().default(false).describe("Adopt the current on-disk state as the scaffold baseline (for projects created before the update engine)")
12759
13526
  })])).handler(async ({ input }) => {
12760
13527
  const [projectDir, options] = input;
12761
- const { updateCommand } = await import("./update-B270pWHc.mjs");
13528
+ const { updateCommand } = await import("./update-CnrBdWrh.mjs");
12762
13529
  await updateCommand({
12763
13530
  projectDir,
12764
13531
  ...options
@@ -12770,7 +13537,7 @@ const router = os.router({
12770
13537
  }),
12771
13538
  doctor: os.meta({ description: "Diagnose a scaffolded Better Fullstack project: verify its bts.jsonc, installed dependencies, required env vars, and run ecosystem build/type checks" }).input(ProjectCheckInputSchema).handler(async ({ input }) => {
12772
13539
  const [projectDir, options] = input;
12773
- const { doctorCommand } = await import("./doctor-Cc7sLuow.mjs");
13540
+ const { doctorCommand } = await import("./doctor-LmNs-hDr.mjs");
12774
13541
  await doctorCommand({
12775
13542
  projectDir,
12776
13543
  ...options
@@ -12778,7 +13545,7 @@ const router = os.router({
12778
13545
  }),
12779
13546
  check: os.meta({ description: "Check a scaffolded Better Fullstack project for config, dependency, env, and generated build/type drift" }).input(ProjectCheckInputSchema).handler(async ({ input }) => {
12780
13547
  const [projectDir, options] = input;
12781
- const { doctorCommand } = await import("./doctor-Cc7sLuow.mjs");
13548
+ const { doctorCommand } = await import("./doctor-LmNs-hDr.mjs");
12782
13549
  await doctorCommand({
12783
13550
  projectDir,
12784
13551
  ...options
@@ -12789,7 +13556,7 @@ const router = os.router({
12789
13556
  ecosystem: z.string().optional().describe("Force an ecosystem (typescript, react-native, rust, go, python, java, ...)"),
12790
13557
  json: z.boolean().default(false).describe("Output the recommendation as JSON")
12791
13558
  })).handler(async ({ input }) => {
12792
- const { recommendStackFromBrief } = await import("./mcp-DNKAo8nO.mjs");
13559
+ const { recommendStackFromBrief } = await import("./mcp-BBammItk.mjs");
12793
13560
  const result = recommendStackFromBrief(input.brief, input.ecosystem);
12794
13561
  if (input.json) {
12795
13562
  log.message(JSON.stringify(result, null, 2));
@@ -12865,7 +13632,7 @@ async function builder() {
12865
13632
  return caller.builder();
12866
13633
  }
12867
13634
  async function add(input, options) {
12868
- const { addHandler } = await import("./add-handler-CE3XIs3y.mjs");
13635
+ const { addHandler } = await import("./add-handler-z4NCxoq6.mjs");
12869
13636
  return addHandler(input, {
12870
13637
  silent: true,
12871
13638
  telemetrySource: options?.telemetrySource ?? "programmatic"