create-better-fullstack 1.5.4 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{addons-setup-Bll5VFJd.mjs → addons-setup-Cgup_RHm.mjs} +138 -101
- package/dist/addons-setup-Cx9DU_sr.mjs +5 -0
- package/dist/{bts-config-BYD8mHt-.mjs → bts-config-B_rZ4_sj.mjs} +30 -68
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +180 -45
- package/dist/index.mjs +2697 -1089
- package/dist/{mcp-CRjipp-w.mjs → mcp-CuEEG8e5.mjs} +1 -1
- package/dist/mcp-entry.mjs +112 -21
- package/dist/virtual.d.mts +1 -1
- package/package.json +24 -9
- package/dist/addons-setup-CWGwxN68.mjs +0 -5
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { s as dependencyVersionMap, t as readBtsConfig } from "./bts-config-
|
|
2
|
+
import { s as dependencyVersionMap, t as readBtsConfig } from "./bts-config-B_rZ4_sj.mjs";
|
|
3
3
|
import { autocompleteMultiselect, cancel, group, isCancel, log, multiselect, select, spinner } from "@clack/prompts";
|
|
4
4
|
import pc from "picocolors";
|
|
5
5
|
import fs from "fs-extra";
|
|
6
6
|
import path from "node:path";
|
|
7
|
-
import
|
|
8
|
-
import consola, { consola as consola$1 } from "consola";
|
|
7
|
+
import consola from "consola";
|
|
9
8
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
10
9
|
import { $ } from "execa";
|
|
11
10
|
|
|
@@ -179,6 +178,48 @@ function getPackageRunnerPrefix(packageManager) {
|
|
|
179
178
|
}
|
|
180
179
|
}
|
|
181
180
|
|
|
181
|
+
//#endregion
|
|
182
|
+
//#region src/utils/prompt-environment.ts
|
|
183
|
+
function hasOwnProperty(value, property) {
|
|
184
|
+
return Object.prototype.hasOwnProperty.call(value, property);
|
|
185
|
+
}
|
|
186
|
+
function resolveCiValue(environment) {
|
|
187
|
+
if (environment && hasOwnProperty(environment, "ci")) return environment.ci;
|
|
188
|
+
return process.env.CI;
|
|
189
|
+
}
|
|
190
|
+
function isCiEnvironment(value) {
|
|
191
|
+
if (!value) return false;
|
|
192
|
+
const normalizedValue = value.trim().toLowerCase();
|
|
193
|
+
return normalizedValue !== "" && normalizedValue !== "0" && normalizedValue !== "false";
|
|
194
|
+
}
|
|
195
|
+
function canPromptInteractively(environment = {}) {
|
|
196
|
+
const silent = environment.silent ?? isSilent();
|
|
197
|
+
const stdinIsTTY = environment.stdinIsTTY ?? process.stdin.isTTY === true;
|
|
198
|
+
const stdoutIsTTY = environment.stdoutIsTTY ?? process.stdout.isTTY === true;
|
|
199
|
+
const ci = resolveCiValue(environment);
|
|
200
|
+
return !silent && stdinIsTTY && stdoutIsTTY && !isCiEnvironment(ci);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
//#endregion
|
|
204
|
+
//#region src/helpers/addons/interactive-selection.ts
|
|
205
|
+
function shouldPromptForAddonSelection(environment = {}) {
|
|
206
|
+
return canPromptInteractively(environment);
|
|
207
|
+
}
|
|
208
|
+
async function selectAddonOptionOrDefault({ addonName, message, options, defaultValue }) {
|
|
209
|
+
if (!shouldPromptForAddonSelection()) {
|
|
210
|
+
const fallback = options.find((option) => option.value === defaultValue);
|
|
211
|
+
if (!isSilent() && fallback) log.info(`Using default ${addonName} template: ${fallback.label}`);
|
|
212
|
+
return defaultValue;
|
|
213
|
+
}
|
|
214
|
+
const selection = await select({
|
|
215
|
+
message,
|
|
216
|
+
options,
|
|
217
|
+
initialValue: defaultValue
|
|
218
|
+
});
|
|
219
|
+
if (isCancel(selection)) return exitCancelled("Operation cancelled");
|
|
220
|
+
return selection;
|
|
221
|
+
}
|
|
222
|
+
|
|
182
223
|
//#endregion
|
|
183
224
|
//#region src/helpers/addons/fumadocs-setup.ts
|
|
184
225
|
const TEMPLATES$2 = {
|
|
@@ -212,17 +253,16 @@ async function setupFumadocs(config) {
|
|
|
212
253
|
const { packageManager, projectDir } = config;
|
|
213
254
|
try {
|
|
214
255
|
log.info("Setting up Fumadocs...");
|
|
215
|
-
const
|
|
256
|
+
const args = getPackageExecutionArgs(packageManager, `create-fumadocs-app@latest fumadocs --template ${TEMPLATES$2[await selectAddonOptionOrDefault({
|
|
257
|
+
addonName: "Fumadocs",
|
|
216
258
|
message: "Choose a template",
|
|
217
|
-
options: Object.entries(TEMPLATES$2).map(([key, template
|
|
259
|
+
options: Object.entries(TEMPLATES$2).map(([key, template]) => ({
|
|
218
260
|
value: key,
|
|
219
|
-
label: template
|
|
220
|
-
hint: template
|
|
261
|
+
label: template.label,
|
|
262
|
+
hint: template.hint
|
|
221
263
|
})),
|
|
222
|
-
|
|
223
|
-
});
|
|
224
|
-
if (isCancel(template)) return exitCancelled("Operation cancelled");
|
|
225
|
-
const args = getPackageExecutionArgs(packageManager, `create-fumadocs-app@latest fumadocs --template ${TEMPLATES$2[template].value} --src --pm ${packageManager} --no-git`);
|
|
264
|
+
defaultValue: "next-mdx"
|
|
265
|
+
})].value} --src --pm ${packageManager} --no-git`);
|
|
226
266
|
const appsDir = path.join(projectDir, "apps");
|
|
227
267
|
await fs.ensureDir(appsDir);
|
|
228
268
|
const s = spinner();
|
|
@@ -446,51 +486,63 @@ function filterAgentsForScope(scope) {
|
|
|
446
486
|
return MCP_AGENTS.filter((a) => a.scope === "both" || a.scope === scope);
|
|
447
487
|
}
|
|
448
488
|
async function setupMcp(config) {
|
|
449
|
-
if (shouldSkipExternalCommands()) return;
|
|
450
489
|
const { packageManager, projectDir } = config;
|
|
451
490
|
log.info("Setting up MCP servers...");
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
options: [{
|
|
455
|
-
value: "project",
|
|
456
|
-
label: "Project",
|
|
457
|
-
hint: "Writes to project config files (recommended for teams)"
|
|
458
|
-
}, {
|
|
459
|
-
value: "global",
|
|
460
|
-
label: "Global",
|
|
461
|
-
hint: "Writes to user-level config files (personal machine)"
|
|
462
|
-
}],
|
|
463
|
-
initialValue: "project"
|
|
464
|
-
});
|
|
465
|
-
if (isCancel(scope)) return;
|
|
491
|
+
const skipExternalCommands = shouldSkipExternalCommands();
|
|
492
|
+
const canPrompt = canPromptInteractively() && !skipExternalCommands;
|
|
466
493
|
const recommendedServers = getRecommendedMcpServers(config);
|
|
467
494
|
if (recommendedServers.length === 0) return;
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
495
|
+
let scope = "project";
|
|
496
|
+
let selectedServerKeys = recommendedServers.map((server) => server.key);
|
|
497
|
+
if (canPrompt) {
|
|
498
|
+
const promptedScope = await select({
|
|
499
|
+
message: "Where should MCP servers be installed?",
|
|
500
|
+
options: [{
|
|
501
|
+
value: "project",
|
|
502
|
+
label: "Project",
|
|
503
|
+
hint: "Writes to project config files (recommended for teams)"
|
|
504
|
+
}, {
|
|
505
|
+
value: "global",
|
|
506
|
+
label: "Global",
|
|
507
|
+
hint: "Writes to user-level config files (personal machine)"
|
|
508
|
+
}],
|
|
509
|
+
initialValue: "project"
|
|
510
|
+
});
|
|
511
|
+
if (isCancel(promptedScope)) return;
|
|
512
|
+
scope = promptedScope;
|
|
513
|
+
const promptedServerKeys = await multiselect({
|
|
514
|
+
message: "Select MCP servers to install",
|
|
515
|
+
options: recommendedServers.map((server) => ({
|
|
516
|
+
value: server.key,
|
|
517
|
+
label: server.label,
|
|
518
|
+
hint: server.target
|
|
519
|
+
})),
|
|
520
|
+
required: false,
|
|
521
|
+
initialValues: selectedServerKeys
|
|
522
|
+
});
|
|
523
|
+
if (isCancel(promptedServerKeys) || promptedServerKeys.length === 0) return;
|
|
524
|
+
selectedServerKeys = [...promptedServerKeys];
|
|
525
|
+
}
|
|
479
526
|
const agentOptions = filterAgentsForScope(scope).map((a) => ({
|
|
480
527
|
value: a.value,
|
|
481
528
|
label: a.label
|
|
482
529
|
}));
|
|
483
|
-
const
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
530
|
+
const defaultAgents = uniqueValues$1([
|
|
531
|
+
"cursor",
|
|
532
|
+
"claude-code",
|
|
533
|
+
"vscode"
|
|
534
|
+
].filter((agent) => agentOptions.some((option) => option.value === agent)));
|
|
535
|
+
let selectedAgents = defaultAgents;
|
|
536
|
+
if (canPrompt) {
|
|
537
|
+
const promptedAgents = await multiselect({
|
|
538
|
+
message: "Select agents to install MCP servers to",
|
|
539
|
+
options: agentOptions,
|
|
540
|
+
required: false,
|
|
541
|
+
initialValues: defaultAgents
|
|
542
|
+
});
|
|
543
|
+
if (isCancel(promptedAgents) || promptedAgents.length === 0) return;
|
|
544
|
+
selectedAgents = [...promptedAgents];
|
|
545
|
+
}
|
|
494
546
|
const serversByKey = new Map(recommendedServers.map((server) => [server.key, server]));
|
|
495
547
|
const selectedServers = [];
|
|
496
548
|
for (const key of selectedServerKeys) {
|
|
@@ -498,6 +550,7 @@ async function setupMcp(config) {
|
|
|
498
550
|
if (server) selectedServers.push(server);
|
|
499
551
|
}
|
|
500
552
|
if (selectedServers.length === 0) return;
|
|
553
|
+
if (skipExternalCommands) return;
|
|
501
554
|
const installSpinner = spinner();
|
|
502
555
|
installSpinner.start("Installing MCP servers...");
|
|
503
556
|
const runner = getPackageRunnerPrefix(packageManager);
|
|
@@ -987,39 +1040,16 @@ async function setupStarlight(config) {
|
|
|
987
1040
|
|
|
988
1041
|
//#endregion
|
|
989
1042
|
//#region src/helpers/addons/tauri-setup.ts
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
const devUrl = `http://localhost:${getLocalWebDevPort(frontend)}`;
|
|
1001
|
-
const frontendDist = hasNuxt ? "../.output/public" : hasSvelte ? "../build" : hasNext ? "../.next" : frontend.includes("react-router") ? "../build/client" : frontend.includes("react-vite") ? "../dist" : "../dist";
|
|
1002
|
-
const tauriArgs = [
|
|
1003
|
-
"@tauri-apps/cli@latest",
|
|
1004
|
-
"init",
|
|
1005
|
-
`--app-name=${path.basename(projectDir)}`,
|
|
1006
|
-
`--window-title=${path.basename(projectDir)}`,
|
|
1007
|
-
`--frontend-dist=${frontendDist}`,
|
|
1008
|
-
`--dev-url=${devUrl}`,
|
|
1009
|
-
`--before-dev-command=${packageManager} run dev`,
|
|
1010
|
-
`--before-build-command=${packageManager} run build`
|
|
1011
|
-
];
|
|
1012
|
-
const prefix = getPackageRunnerPrefix(packageManager);
|
|
1013
|
-
await $({
|
|
1014
|
-
cwd: clientPackageDir,
|
|
1015
|
-
env: { CI: "true" }
|
|
1016
|
-
})`${[...prefix, ...tauriArgs]}`;
|
|
1017
|
-
s.stop("Tauri desktop app support configured successfully!");
|
|
1018
|
-
} catch (error) {
|
|
1019
|
-
s.stop(pc.red("Failed to set up Tauri"));
|
|
1020
|
-
if (error instanceof Error) consola$1.error(pc.red(error.message));
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1043
|
+
/**
|
|
1044
|
+
* Tauri setup is now handled entirely by template generation.
|
|
1045
|
+
* The src-tauri/ directory (tauri.conf.json, Cargo.toml, main.rs, lib.rs, etc.)
|
|
1046
|
+
* is emitted by the addons template handler from templates/addons/tauri/.
|
|
1047
|
+
* Dependencies (@tauri-apps/cli, @tauri-apps/api) and scripts (tauri, desktop:dev,
|
|
1048
|
+
* desktop:build) are added by addons-deps.ts.
|
|
1049
|
+
*
|
|
1050
|
+
* This function is kept as a no-op for backward compatibility with addons-setup.ts.
|
|
1051
|
+
*/
|
|
1052
|
+
async function setupTauri(_config) {}
|
|
1023
1053
|
|
|
1024
1054
|
//#endregion
|
|
1025
1055
|
//#region src/helpers/addons/tui-setup.ts
|
|
@@ -1041,17 +1071,16 @@ async function setupTui(config) {
|
|
|
1041
1071
|
const { packageManager, projectDir } = config;
|
|
1042
1072
|
try {
|
|
1043
1073
|
log.info("Setting up OpenTUI...");
|
|
1044
|
-
const
|
|
1074
|
+
const args = getPackageExecutionArgs(packageManager, `create-tui@latest --template ${await selectAddonOptionOrDefault({
|
|
1075
|
+
addonName: "OpenTUI",
|
|
1045
1076
|
message: "Choose a template",
|
|
1046
|
-
options: Object.entries(TEMPLATES$1).map(([key, template
|
|
1077
|
+
options: Object.entries(TEMPLATES$1).map(([key, template]) => ({
|
|
1047
1078
|
value: key,
|
|
1048
|
-
label: template
|
|
1049
|
-
hint: template
|
|
1079
|
+
label: template.label,
|
|
1080
|
+
hint: template.hint
|
|
1050
1081
|
})),
|
|
1051
|
-
|
|
1052
|
-
});
|
|
1053
|
-
if (isCancel(template)) return exitCancelled("Operation cancelled");
|
|
1054
|
-
const args = getPackageExecutionArgs(packageManager, `create-tui@latest --template ${template} --no-git --no-install tui`);
|
|
1082
|
+
defaultValue: "core"
|
|
1083
|
+
})} --no-git --no-install tui`);
|
|
1055
1084
|
const appsDir = path.join(projectDir, "apps");
|
|
1056
1085
|
await fs.ensureDir(appsDir);
|
|
1057
1086
|
const s = spinner();
|
|
@@ -1147,7 +1176,9 @@ async function setupUltracite(config, gitHooks) {
|
|
|
1147
1176
|
const { packageManager, projectDir, frontend } = config;
|
|
1148
1177
|
try {
|
|
1149
1178
|
log.info("Setting up Ultracite...");
|
|
1150
|
-
const
|
|
1179
|
+
const skipExternalCommands = shouldSkipExternalCommands();
|
|
1180
|
+
const canPrompt = canPromptInteractively() && !skipExternalCommands;
|
|
1181
|
+
const result = canPrompt ? await group({
|
|
1151
1182
|
linter: () => select({
|
|
1152
1183
|
message: "Choose linter/formatter",
|
|
1153
1184
|
options: Object.entries(LINTERS).map(([key, linter$1]) => ({
|
|
@@ -1182,7 +1213,12 @@ async function setupUltracite(config, gitHooks) {
|
|
|
1182
1213
|
})
|
|
1183
1214
|
}, { onCancel: () => {
|
|
1184
1215
|
exitCancelled("Operation cancelled");
|
|
1185
|
-
} })
|
|
1216
|
+
} }) : {
|
|
1217
|
+
linter: "biome",
|
|
1218
|
+
editors: [],
|
|
1219
|
+
agents: [],
|
|
1220
|
+
hooks: []
|
|
1221
|
+
};
|
|
1186
1222
|
const linter = result.linter;
|
|
1187
1223
|
const editors = result.editors;
|
|
1188
1224
|
const agents = result.agents;
|
|
@@ -1195,6 +1231,7 @@ async function setupUltracite(config, gitHooks) {
|
|
|
1195
1231
|
"--linter",
|
|
1196
1232
|
linter
|
|
1197
1233
|
];
|
|
1234
|
+
if (!canPrompt) ultraciteArgs.push("--quiet");
|
|
1198
1235
|
if (frameworks.length > 0) ultraciteArgs.push("--frameworks", ...frameworks);
|
|
1199
1236
|
if (editors.length > 0) ultraciteArgs.push("--editors", ...editors);
|
|
1200
1237
|
if (agents.length > 0) ultraciteArgs.push("--agents", ...agents);
|
|
@@ -1204,6 +1241,7 @@ async function setupUltracite(config, gitHooks) {
|
|
|
1204
1241
|
if (gitHooks.includes("husky")) integrations.push("lint-staged");
|
|
1205
1242
|
ultraciteArgs.push("--integrations", ...integrations);
|
|
1206
1243
|
}
|
|
1244
|
+
if (skipExternalCommands) return;
|
|
1207
1245
|
const args = getPackageExecutionArgs(packageManager, `ultracite@latest ${ultraciteArgs.join(" ")} --skip-install`);
|
|
1208
1246
|
const s = spinner();
|
|
1209
1247
|
s.start("Running Ultracite init command...");
|
|
@@ -1246,17 +1284,16 @@ async function setupWxt(config) {
|
|
|
1246
1284
|
const { packageManager, projectDir } = config;
|
|
1247
1285
|
try {
|
|
1248
1286
|
log.info("Setting up WXT...");
|
|
1249
|
-
const
|
|
1287
|
+
const args = getPackageExecutionArgs(packageManager, `wxt@latest init extension --template ${await selectAddonOptionOrDefault({
|
|
1288
|
+
addonName: "WXT",
|
|
1250
1289
|
message: "Choose a template",
|
|
1251
|
-
options: Object.entries(TEMPLATES).map(([key, template
|
|
1290
|
+
options: Object.entries(TEMPLATES).map(([key, template]) => ({
|
|
1252
1291
|
value: key,
|
|
1253
|
-
label: template
|
|
1254
|
-
hint: template
|
|
1292
|
+
label: template.label,
|
|
1293
|
+
hint: template.hint
|
|
1255
1294
|
})),
|
|
1256
|
-
|
|
1257
|
-
});
|
|
1258
|
-
if (isCancel(template)) return exitCancelled("Operation cancelled");
|
|
1259
|
-
const args = getPackageExecutionArgs(packageManager, `wxt@latest init extension --template ${template} --pm ${packageManager}`);
|
|
1295
|
+
defaultValue: "react"
|
|
1296
|
+
})} --pm ${packageManager}`);
|
|
1260
1297
|
const appsDir = path.join(projectDir, "apps");
|
|
1261
1298
|
await fs.ensureDir(appsDir);
|
|
1262
1299
|
const s = spinner();
|
|
@@ -1290,7 +1327,7 @@ async function setupAddons(config) {
|
|
|
1290
1327
|
const hasSvelteFrontend = frontend.includes("svelte");
|
|
1291
1328
|
const hasSolidFrontend = frontend.includes("solid");
|
|
1292
1329
|
const hasNextFrontend = frontend.includes("next");
|
|
1293
|
-
if (addons.includes("tauri") && (hasReactWebFrontend || hasNuxtFrontend || hasSvelteFrontend || hasSolidFrontend || hasNextFrontend)) await setupTauri(config);
|
|
1330
|
+
if (addons.includes("tauri") && (hasReactWebFrontend || hasNuxtFrontend || hasSvelteFrontend || hasSolidFrontend || hasNextFrontend)) await /* @__PURE__ */ setupTauri(config);
|
|
1294
1331
|
const hasUltracite = addons.includes("ultracite");
|
|
1295
1332
|
const hasBiome = addons.includes("biome");
|
|
1296
1333
|
const hasHusky = addons.includes("husky");
|
|
@@ -1370,4 +1407,4 @@ async function setupLefthook(projectDir) {
|
|
|
1370
1407
|
}
|
|
1371
1408
|
|
|
1372
1409
|
//#endregion
|
|
1373
|
-
export {
|
|
1410
|
+
export { setIsFirstPrompt as _, canPromptInteractively as a, CLIError as c, exitWithError as d, handleError as f, runWithContextAsync as g, isSilent as h, setupLefthook as i, UserCancelledError as l, isFirstPrompt as m, setupBiome as n, getPackageExecutionArgs as o, didLastPromptShowUI as p, setupHusky as r, addPackageDependency as s, setupAddons as t, exitCancelled as u, setLastPromptShownUI as v };
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import fs from "fs-extra";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { createCliDefaultProjectConfigBase } from "@better-fullstack/types";
|
|
5
6
|
import { dependencyVersionMap } from "@better-fullstack/template-generator";
|
|
6
7
|
import * as JSONC from "jsonc-parser";
|
|
7
8
|
|
|
@@ -10,6 +11,7 @@ const getUserPkgManager = () => {
|
|
|
10
11
|
const userAgent = process.env.npm_config_user_agent;
|
|
11
12
|
if (userAgent?.startsWith("pnpm")) return "pnpm";
|
|
12
13
|
if (userAgent?.startsWith("bun")) return "bun";
|
|
14
|
+
if (userAgent?.startsWith("yarn")) return "yarn";
|
|
13
15
|
return "npm";
|
|
14
16
|
};
|
|
15
17
|
|
|
@@ -18,74 +20,7 @@ const getUserPkgManager = () => {
|
|
|
18
20
|
const __filename = fileURLToPath(import.meta.url);
|
|
19
21
|
const distPath = path.dirname(__filename);
|
|
20
22
|
const PKG_ROOT = path.join(distPath, "../");
|
|
21
|
-
const DEFAULT_CONFIG_BASE =
|
|
22
|
-
projectName: "my-app",
|
|
23
|
-
relativePath: "my-app",
|
|
24
|
-
ecosystem: "typescript",
|
|
25
|
-
frontend: ["tanstack-router"],
|
|
26
|
-
database: "sqlite",
|
|
27
|
-
orm: "drizzle",
|
|
28
|
-
auth: "better-auth",
|
|
29
|
-
payments: "none",
|
|
30
|
-
email: "none",
|
|
31
|
-
fileUpload: "none",
|
|
32
|
-
effect: "none",
|
|
33
|
-
stateManagement: "none",
|
|
34
|
-
validation: "zod",
|
|
35
|
-
forms: "react-hook-form",
|
|
36
|
-
testing: "vitest",
|
|
37
|
-
ai: "none",
|
|
38
|
-
realtime: "none",
|
|
39
|
-
jobQueue: "none",
|
|
40
|
-
caching: "none",
|
|
41
|
-
search: "none",
|
|
42
|
-
fileStorage: "none",
|
|
43
|
-
animation: "none",
|
|
44
|
-
logging: "none",
|
|
45
|
-
observability: "none",
|
|
46
|
-
featureFlags: "none",
|
|
47
|
-
analytics: "none",
|
|
48
|
-
cms: "none",
|
|
49
|
-
addons: ["turborepo"],
|
|
50
|
-
examples: [],
|
|
51
|
-
git: true,
|
|
52
|
-
install: true,
|
|
53
|
-
versionChannel: "stable",
|
|
54
|
-
dbSetup: "none",
|
|
55
|
-
backend: "hono",
|
|
56
|
-
runtime: "bun",
|
|
57
|
-
api: "trpc",
|
|
58
|
-
webDeploy: "none",
|
|
59
|
-
serverDeploy: "none",
|
|
60
|
-
cssFramework: "tailwind",
|
|
61
|
-
uiLibrary: "shadcn-ui",
|
|
62
|
-
shadcnBase: "radix",
|
|
63
|
-
shadcnStyle: "nova",
|
|
64
|
-
shadcnIconLibrary: "lucide",
|
|
65
|
-
shadcnColorTheme: "neutral",
|
|
66
|
-
shadcnBaseColor: "neutral",
|
|
67
|
-
shadcnFont: "inter",
|
|
68
|
-
shadcnRadius: "default",
|
|
69
|
-
rustWebFramework: "none",
|
|
70
|
-
rustFrontend: "none",
|
|
71
|
-
rustOrm: "none",
|
|
72
|
-
rustApi: "none",
|
|
73
|
-
rustCli: "none",
|
|
74
|
-
rustLibraries: [],
|
|
75
|
-
rustLogging: "tracing",
|
|
76
|
-
pythonWebFramework: "fastapi",
|
|
77
|
-
pythonOrm: "sqlalchemy",
|
|
78
|
-
pythonValidation: "pydantic",
|
|
79
|
-
pythonAi: [],
|
|
80
|
-
pythonTaskQueue: "none",
|
|
81
|
-
pythonQuality: "ruff",
|
|
82
|
-
goWebFramework: "gin",
|
|
83
|
-
goOrm: "gorm",
|
|
84
|
-
goApi: "none",
|
|
85
|
-
goCli: "none",
|
|
86
|
-
goLogging: "zap",
|
|
87
|
-
aiDocs: ["claude-md"]
|
|
88
|
-
};
|
|
23
|
+
const DEFAULT_CONFIG_BASE = createCliDefaultProjectConfigBase(getUserPkgManager());
|
|
89
24
|
function getDefaultConfig() {
|
|
90
25
|
return {
|
|
91
26
|
...DEFAULT_CONFIG_BASE,
|
|
@@ -96,6 +31,8 @@ function getDefaultConfig() {
|
|
|
96
31
|
examples: [...DEFAULT_CONFIG_BASE.examples],
|
|
97
32
|
rustLibraries: [...DEFAULT_CONFIG_BASE.rustLibraries],
|
|
98
33
|
pythonAi: [...DEFAULT_CONFIG_BASE.pythonAi],
|
|
34
|
+
javaLibraries: [...DEFAULT_CONFIG_BASE.javaLibraries],
|
|
35
|
+
javaTestingLibraries: [...DEFAULT_CONFIG_BASE.javaTestingLibraries],
|
|
99
36
|
aiDocs: [...DEFAULT_CONFIG_BASE.aiDocs]
|
|
100
37
|
};
|
|
101
38
|
}
|
|
@@ -174,6 +111,7 @@ async function writeBtsConfig(projectConfig) {
|
|
|
174
111
|
analytics: projectConfig.analytics,
|
|
175
112
|
cms: projectConfig.cms,
|
|
176
113
|
caching: projectConfig.caching,
|
|
114
|
+
i18n: projectConfig.i18n,
|
|
177
115
|
search: projectConfig.search,
|
|
178
116
|
fileStorage: projectConfig.fileStorage,
|
|
179
117
|
rustWebFramework: projectConfig.rustWebFramework,
|
|
@@ -183,17 +121,29 @@ async function writeBtsConfig(projectConfig) {
|
|
|
183
121
|
rustCli: projectConfig.rustCli,
|
|
184
122
|
rustLibraries: projectConfig.rustLibraries,
|
|
185
123
|
rustLogging: projectConfig.rustLogging,
|
|
124
|
+
rustErrorHandling: projectConfig.rustErrorHandling,
|
|
125
|
+
rustCaching: projectConfig.rustCaching,
|
|
126
|
+
rustAuth: projectConfig.rustAuth,
|
|
186
127
|
pythonWebFramework: projectConfig.pythonWebFramework,
|
|
187
128
|
pythonOrm: projectConfig.pythonOrm,
|
|
188
129
|
pythonValidation: projectConfig.pythonValidation,
|
|
189
130
|
pythonAi: projectConfig.pythonAi,
|
|
131
|
+
pythonAuth: projectConfig.pythonAuth,
|
|
190
132
|
pythonTaskQueue: projectConfig.pythonTaskQueue,
|
|
133
|
+
pythonGraphql: projectConfig.pythonGraphql,
|
|
191
134
|
pythonQuality: projectConfig.pythonQuality,
|
|
192
135
|
goWebFramework: projectConfig.goWebFramework,
|
|
193
136
|
goOrm: projectConfig.goOrm,
|
|
194
137
|
goApi: projectConfig.goApi,
|
|
195
138
|
goCli: projectConfig.goCli,
|
|
196
139
|
goLogging: projectConfig.goLogging,
|
|
140
|
+
goAuth: projectConfig.goAuth,
|
|
141
|
+
javaWebFramework: projectConfig.javaWebFramework,
|
|
142
|
+
javaBuildTool: projectConfig.javaBuildTool,
|
|
143
|
+
javaOrm: projectConfig.javaOrm,
|
|
144
|
+
javaAuth: projectConfig.javaAuth,
|
|
145
|
+
javaLibraries: projectConfig.javaLibraries,
|
|
146
|
+
javaTestingLibraries: projectConfig.javaTestingLibraries,
|
|
197
147
|
aiDocs: projectConfig.aiDocs
|
|
198
148
|
};
|
|
199
149
|
const baseContent = {
|
|
@@ -235,6 +185,7 @@ async function writeBtsConfig(projectConfig) {
|
|
|
235
185
|
analytics: btsConfig.analytics,
|
|
236
186
|
cms: btsConfig.cms,
|
|
237
187
|
caching: btsConfig.caching,
|
|
188
|
+
i18n: btsConfig.i18n,
|
|
238
189
|
search: btsConfig.search,
|
|
239
190
|
fileStorage: btsConfig.fileStorage,
|
|
240
191
|
rustWebFramework: btsConfig.rustWebFramework,
|
|
@@ -244,10 +195,14 @@ async function writeBtsConfig(projectConfig) {
|
|
|
244
195
|
rustCli: btsConfig.rustCli,
|
|
245
196
|
rustLibraries: btsConfig.rustLibraries,
|
|
246
197
|
rustLogging: btsConfig.rustLogging,
|
|
198
|
+
rustErrorHandling: btsConfig.rustErrorHandling,
|
|
199
|
+
rustCaching: btsConfig.rustCaching,
|
|
200
|
+
rustAuth: btsConfig.rustAuth,
|
|
247
201
|
pythonWebFramework: btsConfig.pythonWebFramework,
|
|
248
202
|
pythonOrm: btsConfig.pythonOrm,
|
|
249
203
|
pythonValidation: btsConfig.pythonValidation,
|
|
250
204
|
pythonAi: btsConfig.pythonAi,
|
|
205
|
+
pythonAuth: btsConfig.pythonAuth,
|
|
251
206
|
pythonTaskQueue: btsConfig.pythonTaskQueue,
|
|
252
207
|
pythonQuality: btsConfig.pythonQuality,
|
|
253
208
|
goWebFramework: btsConfig.goWebFramework,
|
|
@@ -255,6 +210,13 @@ async function writeBtsConfig(projectConfig) {
|
|
|
255
210
|
goApi: btsConfig.goApi,
|
|
256
211
|
goCli: btsConfig.goCli,
|
|
257
212
|
goLogging: btsConfig.goLogging,
|
|
213
|
+
goAuth: btsConfig.goAuth,
|
|
214
|
+
javaWebFramework: btsConfig.javaWebFramework,
|
|
215
|
+
javaBuildTool: btsConfig.javaBuildTool,
|
|
216
|
+
javaOrm: btsConfig.javaOrm,
|
|
217
|
+
javaAuth: btsConfig.javaAuth,
|
|
218
|
+
javaLibraries: btsConfig.javaLibraries,
|
|
219
|
+
javaTestingLibraries: btsConfig.javaTestingLibraries,
|
|
258
220
|
aiDocs: btsConfig.aiDocs
|
|
259
221
|
};
|
|
260
222
|
let configContent = JSON.stringify(baseContent);
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
//#region src/cli.ts
|
|
3
|
-
if (process.argv[2] === "mcp" && process.argv.length === 3) import("./mcp-
|
|
3
|
+
if (process.argv[2] === "mcp" && process.argv.length === 3) import("./mcp-CuEEG8e5.mjs").then((m) => m.startMcpServer());
|
|
4
4
|
else import("./index.mjs").then((m) => m.createBtsCli().run());
|
|
5
5
|
|
|
6
6
|
//#endregion
|