create-better-fullstack 2.0.0 → 2.0.2
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/add-handler-BPAZM8Zo.mjs +149 -0
- package/dist/addons-setup-CV5uZyhH.mjs +5 -0
- package/dist/{addons-setup-DHoByttt.mjs → addons-setup-HSghQS7c.mjs} +29 -33
- package/dist/bts-config-Bg1Qea9Y.mjs +737 -0
- package/dist/cli.mjs +2 -2
- package/dist/index.d.mts +404 -96
- package/dist/index.mjs +38 -11545
- package/dist/install-dependencies-D6-GO3BZ.mjs +1139 -0
- package/dist/mcp-58r70ZcL.mjs +5 -0
- package/dist/mcp-entry.mjs +377 -543
- package/dist/run-DQlymC4z.mjs +11546 -0
- package/dist/run-QRBymn-p.mjs +7 -0
- package/dist/update-deps-CLebIM70.mjs +189 -0
- package/package.json +7 -10
- package/dist/addons-setup-Ca069cmy.mjs +0 -5
- package/dist/bts-config-BMniWIbd.mjs +0 -497
- package/dist/mcp-YvDMaVXB.mjs +0 -5
package/dist/mcp-entry.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { a as getEffectiveStack, i as writeBtsConfig, l as getGraphSummary, n as readBtsConfig, p as getLatestCLIVersion, t as previewBtsConfigUpdate } from "./bts-config-Bg1Qea9Y.mjs";
|
|
3
3
|
import z from "zod";
|
|
4
|
-
import { AISchema, APISchema, AddonsSchema, AnalyticsSchema, AnimationSchema, AstroIntegrationSchema, AuthSchema, BackendSchema, CMSSchema, CSSFrameworkSchema, CachingSchema, DatabaseSchema, DatabaseSetupSchema, EcosystemSchema, EffectSchema, ElixirApiSchema, ElixirAuthSchema, ElixirCachingSchema, ElixirDeploySchema, ElixirEmailSchema, ElixirHttpSchema, ElixirJobsSchema, ElixirJsonSchema, ElixirObservabilitySchema, ElixirOrmSchema, ElixirQualitySchema, ElixirRealtimeSchema, ElixirTestingSchema, ElixirValidationSchema, ElixirWebFrameworkSchema, EmailSchema, ExamplesSchema, FeatureFlagsSchema, FileStorageSchema, FileUploadSchema, FormsSchema, FrontendSchema, GoApiSchema, GoAuthSchema, GoCliSchema, GoLoggingSchema, GoOrmSchema, GoWebFrameworkSchema, I18nSchema, JavaAuthSchema, JavaBuildToolSchema, JavaLibrariesSchema, JavaOrmSchema, JavaTestingLibrariesSchema, JavaWebFrameworkSchema, JobQueueSchema, LoggingSchema, MobileDeepLinkingSchema, MobileNavigationSchema, MobileOTASchema, MobilePushSchema, MobileStorageSchema, MobileTestingSchema, MobileUISchema, OPTION_CATEGORY_METADATA, ORMSchema, ObservabilitySchema, PackageManagerSchema, PaymentsSchema, PythonAiSchema, PythonApiSchema, PythonAuthSchema, PythonGraphqlSchema, PythonOrmSchema, PythonQualitySchema, PythonTaskQueueSchema, PythonValidationSchema, PythonWebFrameworkSchema, RealtimeSchema, RuntimeSchema, RustApiSchema, RustAuthSchema, RustCachingSchema, RustCliSchema, RustErrorHandlingSchema, RustFrontendSchema, RustLibrariesSchema, RustLoggingSchema, RustOrmSchema, RustWebFrameworkSchema, SearchSchema, ServerDeploySchema, StateManagementSchema, TestingSchema, UILibrarySchema, ValidationSchema, WebDeploySchema, analyzeStackCompatibility } from "@better-fullstack/types";
|
|
4
|
+
import { AISchema, APISchema, AddonsSchema, 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, ElixirAuthSchema, ElixirCachingSchema, ElixirDeploySchema, ElixirEmailSchema, ElixirHttpSchema, ElixirJobsSchema, ElixirJsonSchema, ElixirLibrariesSchema, ElixirObservabilitySchema, ElixirOrmSchema, ElixirQualitySchema, ElixirRealtimeSchema, ElixirTestingSchema, ElixirValidationSchema, ElixirWebFrameworkSchema, EmailSchema, ExamplesSchema, FeatureFlagsSchema, FileStorageSchema, FileUploadSchema, FormsSchema, FrontendSchema, GoApiSchema, GoAuthSchema, GoCachingSchema, GoCliSchema, GoConfigSchema, GoLoggingSchema, GoMessageQueueSchema, GoObservabilitySchema, GoOrmSchema, GoRealtimeSchema, GoTestingSchema, GoWebFrameworkSchema, I18nSchema, JavaApiSchema, JavaAuthSchema, JavaBuildToolSchema, 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, StateManagementSchema, TestingSchema, UILibrarySchema, ValidationSchema, WebDeploySchema, analyzeStackCompatibility, formatStackPartSpec, getCategoryOrderForEcosystem, legacyProjectConfigToStackParts } from "@better-fullstack/types";
|
|
5
5
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
6
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
7
|
|
|
8
8
|
//#region src/mcp.ts
|
|
9
|
-
const INSTRUCTIONS = `Better-Fullstack scaffolds fullstack projects across TypeScript, React Native, Rust, Go, Python, Java, and Elixir ecosystems with ${Object.values(OPTION_CATEGORY_METADATA).reduce((sum, metadata) => sum + metadata.options.length, 0)} configurable options.
|
|
9
|
+
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.
|
|
10
10
|
|
|
11
11
|
RECOMMENDED WORKFLOW:
|
|
12
12
|
1. Call bfs_get_guidance to understand field semantics, required fields, and workflow rules.
|
|
@@ -21,10 +21,10 @@ For existing projects:
|
|
|
21
21
|
|
|
22
22
|
CRITICAL RULES:
|
|
23
23
|
- Dependency installation is ALWAYS skipped in MCP mode (timeout risk). After scaffolding, tell the user to run install manually.
|
|
24
|
-
- Array fields: "frontend", "addons", "examples", "aiDocs", "rustLibraries", "pythonAi", "javaLibraries", and "
|
|
24
|
+
- Array fields: "frontend", "addons", "examples", "aiDocs", "rustLibraries", "pythonAi", "pythonTesting", "pythonCli", "goTesting", "javaLibraries", "javaTestingLibraries", "dotnetTesting", "dotnetObservability", and "elixirLibraries". Most other option fields are strings.
|
|
25
25
|
- "none" means "skip this feature entirely", not "use the default".
|
|
26
26
|
- Always specify "ecosystem" first — it determines which other fields are relevant.
|
|
27
|
-
- TypeScript web-specific fields (web frontend, backend, orm, etc.) are IGNORED for react-native/rust/python/go/java/elixir ecosystems.
|
|
27
|
+
- TypeScript web-specific fields (web frontend, backend, orm, etc.) are IGNORED for react-native/rust/python/go/java/dotnet/elixir ecosystems.
|
|
28
28
|
- The compatibility engine auto-adjusts invalid combinations — always call bfs_check_compatibility first to see adjustments.`;
|
|
29
29
|
function getGuidance() {
|
|
30
30
|
return {
|
|
@@ -43,13 +43,14 @@ function getGuidance() {
|
|
|
43
43
|
python: "Backend/AI: web framework (fastapi/django), ORM (sqlalchemy/sqlmodel), AI/ML integrations, task queues.",
|
|
44
44
|
go: "Backend/CLI: web framework (gin/echo), ORM (gorm/sqlc), gRPC, CLI tools, logging.",
|
|
45
45
|
java: "Backend/API: Spring Boot with Maven or Gradle Wrapper, optional Spring Data JPA, Spring Security, app libraries, and Java testing libraries.",
|
|
46
|
+
dotnet: "Backend/API: ASP.NET Core Minimal APIs, MVC, or Blazor with EF Core/Dapper, Identity/Auth0, SignalR, xUnit, and Docker-ready output.",
|
|
46
47
|
elixir: "Phoenix: Phoenix or Phoenix LiveView with Ecto SQL, PostgreSQL-ready config, REST or Absinthe, Channels/Presence, Oban, and Mix releases/Docker."
|
|
47
48
|
},
|
|
48
49
|
fieldRules: {
|
|
49
50
|
projectName: "kebab-case directory name. Required for bfs_create_project.",
|
|
50
51
|
ecosystem: "Must be set first. Determines which other fields are relevant.",
|
|
51
52
|
frontend: "ARRAY of strings. TypeScript only. Supports multiple frontends in one monorepo. Use [] for API-only.",
|
|
52
|
-
arrayFields: "Use arrays for frontend, addons, examples, aiDocs, rustLibraries, pythonAi, javaLibraries, and
|
|
53
|
+
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.",
|
|
53
54
|
backend: "String. \"self\" means fullstack mode (Next.js/Vinext/TanStack Start/Nuxt/Astro API routes). \"none\" for frontend-only.",
|
|
54
55
|
runtime: "\"bun\" or \"node\". Must be \"none\" when backend is \"self\" or \"convex\".",
|
|
55
56
|
addons: "ARRAY of strings. Monorepo tools, code quality, desktop (tauri), browser extensions (wxt), etc.",
|
|
@@ -82,245 +83,89 @@ function getGuidance() {
|
|
|
82
83
|
]
|
|
83
84
|
};
|
|
84
85
|
}
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
observability: ObservabilitySchema,
|
|
110
|
-
featureFlags: FeatureFlagsSchema,
|
|
111
|
-
analytics: AnalyticsSchema,
|
|
112
|
-
cms: CMSSchema,
|
|
113
|
-
caching: CachingSchema,
|
|
114
|
-
i18n: I18nSchema,
|
|
115
|
-
search: SearchSchema,
|
|
116
|
-
fileStorage: FileStorageSchema,
|
|
117
|
-
mobileNavigation: MobileNavigationSchema,
|
|
118
|
-
mobileUI: MobileUISchema,
|
|
119
|
-
mobileStorage: MobileStorageSchema,
|
|
120
|
-
mobileTesting: MobileTestingSchema,
|
|
121
|
-
mobilePush: MobilePushSchema,
|
|
122
|
-
mobileOTA: MobileOTASchema,
|
|
123
|
-
mobileDeepLinking: MobileDeepLinkingSchema,
|
|
124
|
-
addons: AddonsSchema,
|
|
125
|
-
examples: ExamplesSchema,
|
|
126
|
-
packageManager: PackageManagerSchema,
|
|
127
|
-
dbSetup: DatabaseSetupSchema,
|
|
128
|
-
webDeploy: WebDeploySchema,
|
|
129
|
-
serverDeploy: ServerDeploySchema,
|
|
130
|
-
astroIntegration: AstroIntegrationSchema,
|
|
131
|
-
rustWebFramework: RustWebFrameworkSchema,
|
|
132
|
-
rustFrontend: RustFrontendSchema,
|
|
133
|
-
rustOrm: RustOrmSchema,
|
|
134
|
-
rustApi: RustApiSchema,
|
|
135
|
-
rustCli: RustCliSchema,
|
|
136
|
-
rustLibraries: RustLibrariesSchema,
|
|
137
|
-
rustLogging: RustLoggingSchema,
|
|
138
|
-
rustErrorHandling: RustErrorHandlingSchema,
|
|
139
|
-
rustCaching: RustCachingSchema,
|
|
140
|
-
rustAuth: RustAuthSchema,
|
|
141
|
-
pythonWebFramework: PythonWebFrameworkSchema,
|
|
142
|
-
pythonOrm: PythonOrmSchema,
|
|
143
|
-
pythonValidation: PythonValidationSchema,
|
|
144
|
-
pythonAi: PythonAiSchema,
|
|
145
|
-
pythonAuth: PythonAuthSchema,
|
|
146
|
-
pythonApi: PythonApiSchema,
|
|
147
|
-
pythonTaskQueue: PythonTaskQueueSchema,
|
|
148
|
-
pythonGraphql: PythonGraphqlSchema,
|
|
149
|
-
pythonQuality: PythonQualitySchema,
|
|
150
|
-
goWebFramework: GoWebFrameworkSchema,
|
|
151
|
-
goOrm: GoOrmSchema,
|
|
152
|
-
goApi: GoApiSchema,
|
|
153
|
-
goCli: GoCliSchema,
|
|
154
|
-
goLogging: GoLoggingSchema,
|
|
155
|
-
goAuth: GoAuthSchema,
|
|
156
|
-
javaWebFramework: JavaWebFrameworkSchema,
|
|
157
|
-
javaBuildTool: JavaBuildToolSchema,
|
|
158
|
-
javaOrm: JavaOrmSchema,
|
|
159
|
-
javaAuth: JavaAuthSchema,
|
|
160
|
-
javaLibraries: JavaLibrariesSchema,
|
|
161
|
-
javaTestingLibraries: JavaTestingLibrariesSchema,
|
|
162
|
-
elixirWebFramework: ElixirWebFrameworkSchema,
|
|
163
|
-
elixirOrm: ElixirOrmSchema,
|
|
164
|
-
elixirAuth: ElixirAuthSchema,
|
|
165
|
-
elixirApi: ElixirApiSchema,
|
|
166
|
-
elixirRealtime: ElixirRealtimeSchema,
|
|
167
|
-
elixirJobs: ElixirJobsSchema,
|
|
168
|
-
elixirValidation: ElixirValidationSchema,
|
|
169
|
-
elixirHttp: ElixirHttpSchema,
|
|
170
|
-
elixirJson: ElixirJsonSchema,
|
|
171
|
-
elixirEmail: ElixirEmailSchema,
|
|
172
|
-
elixirCaching: ElixirCachingSchema,
|
|
173
|
-
elixirObservability: ElixirObservabilitySchema,
|
|
174
|
-
elixirTesting: ElixirTestingSchema,
|
|
175
|
-
elixirQuality: ElixirQualitySchema,
|
|
176
|
-
elixirDeploy: ElixirDeploySchema
|
|
86
|
+
const MCP_ECOSYSTEMS = new Set(EcosystemSchema.options);
|
|
87
|
+
const MCP_SHARED_SCHEMA_KEYS = [
|
|
88
|
+
"ecosystem",
|
|
89
|
+
"packageManager",
|
|
90
|
+
"addons",
|
|
91
|
+
"examples",
|
|
92
|
+
"webDeploy",
|
|
93
|
+
"serverDeploy",
|
|
94
|
+
"dbSetup"
|
|
95
|
+
];
|
|
96
|
+
const MCP_SHARED_COMPATIBILITY_KEYS = [
|
|
97
|
+
...MCP_SHARED_SCHEMA_KEYS,
|
|
98
|
+
"projectName",
|
|
99
|
+
"git",
|
|
100
|
+
"install",
|
|
101
|
+
"aiDocs"
|
|
102
|
+
];
|
|
103
|
+
const MCP_LEGACY_CATEGORY_KEYS = {
|
|
104
|
+
webFrontend: ["frontend"],
|
|
105
|
+
nativeFrontend: ["frontend"],
|
|
106
|
+
backendLibraries: ["effect"],
|
|
107
|
+
codeQuality: ["addons"],
|
|
108
|
+
documentation: ["addons"],
|
|
109
|
+
appPlatforms: ["addons"]
|
|
177
110
|
};
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
"analytics",
|
|
205
|
-
"cms",
|
|
206
|
-
"caching",
|
|
207
|
-
"i18n",
|
|
208
|
-
"search",
|
|
209
|
-
"fileStorage",
|
|
210
|
-
"astroIntegration"
|
|
211
|
-
],
|
|
212
|
-
"react-native": [
|
|
213
|
-
"frontend",
|
|
214
|
-
"auth",
|
|
215
|
-
"mobileNavigation",
|
|
216
|
-
"mobileUI",
|
|
217
|
-
"mobileStorage",
|
|
218
|
-
"mobileTesting",
|
|
219
|
-
"mobilePush",
|
|
220
|
-
"mobileOTA",
|
|
221
|
-
"mobileDeepLinking"
|
|
222
|
-
],
|
|
223
|
-
rust: [
|
|
224
|
-
"rustWebFramework",
|
|
225
|
-
"rustFrontend",
|
|
226
|
-
"rustOrm",
|
|
227
|
-
"rustApi",
|
|
228
|
-
"rustCli",
|
|
229
|
-
"rustLibraries",
|
|
230
|
-
"rustLogging",
|
|
231
|
-
"rustErrorHandling",
|
|
232
|
-
"rustCaching",
|
|
233
|
-
"rustAuth",
|
|
234
|
-
"email",
|
|
235
|
-
"observability",
|
|
236
|
-
"caching",
|
|
237
|
-
"search"
|
|
238
|
-
],
|
|
239
|
-
python: [
|
|
240
|
-
"pythonWebFramework",
|
|
241
|
-
"pythonOrm",
|
|
242
|
-
"pythonValidation",
|
|
243
|
-
"pythonAi",
|
|
244
|
-
"pythonAuth",
|
|
245
|
-
"pythonApi",
|
|
246
|
-
"pythonTaskQueue",
|
|
247
|
-
"pythonGraphql",
|
|
248
|
-
"pythonQuality",
|
|
249
|
-
"email",
|
|
250
|
-
"observability",
|
|
251
|
-
"caching",
|
|
252
|
-
"search"
|
|
253
|
-
],
|
|
254
|
-
go: [
|
|
255
|
-
"goWebFramework",
|
|
256
|
-
"goOrm",
|
|
257
|
-
"goApi",
|
|
258
|
-
"goCli",
|
|
259
|
-
"goLogging",
|
|
260
|
-
"goAuth",
|
|
261
|
-
"auth",
|
|
262
|
-
"email",
|
|
263
|
-
"observability",
|
|
264
|
-
"caching",
|
|
265
|
-
"search"
|
|
266
|
-
],
|
|
267
|
-
java: [
|
|
268
|
-
"javaWebFramework",
|
|
269
|
-
"javaBuildTool",
|
|
270
|
-
"javaOrm",
|
|
271
|
-
"javaAuth",
|
|
272
|
-
"javaLibraries",
|
|
273
|
-
"javaTestingLibraries",
|
|
274
|
-
"email",
|
|
275
|
-
"observability",
|
|
276
|
-
"caching",
|
|
277
|
-
"search"
|
|
278
|
-
],
|
|
279
|
-
elixir: [
|
|
280
|
-
"elixirWebFramework",
|
|
281
|
-
"elixirOrm",
|
|
282
|
-
"elixirAuth",
|
|
283
|
-
"elixirApi",
|
|
284
|
-
"elixirRealtime",
|
|
285
|
-
"elixirJobs",
|
|
286
|
-
"elixirValidation",
|
|
287
|
-
"elixirHttp",
|
|
288
|
-
"elixirJson",
|
|
289
|
-
"elixirEmail",
|
|
290
|
-
"elixirCaching",
|
|
291
|
-
"elixirObservability",
|
|
292
|
-
"elixirTesting",
|
|
293
|
-
"elixirQuality",
|
|
294
|
-
"elixirDeploy"
|
|
295
|
-
],
|
|
296
|
-
shared: [
|
|
297
|
-
"ecosystem",
|
|
298
|
-
"packageManager",
|
|
299
|
-
"addons",
|
|
300
|
-
"examples",
|
|
301
|
-
"webDeploy",
|
|
302
|
-
"serverDeploy",
|
|
303
|
-
"dbSetup"
|
|
304
|
-
]
|
|
111
|
+
const MCP_SCHEMA_EXCLUDED_CATEGORIES = new Set([
|
|
112
|
+
"webFrontend",
|
|
113
|
+
"nativeFrontend",
|
|
114
|
+
"backendLibraries",
|
|
115
|
+
"codeQuality",
|
|
116
|
+
"documentation",
|
|
117
|
+
"appPlatforms",
|
|
118
|
+
"aiDocs",
|
|
119
|
+
"git",
|
|
120
|
+
"install",
|
|
121
|
+
"versionChannel",
|
|
122
|
+
"shadcnBase",
|
|
123
|
+
"shadcnStyle",
|
|
124
|
+
"shadcnIconLibrary",
|
|
125
|
+
"shadcnColorTheme",
|
|
126
|
+
"shadcnBaseColor",
|
|
127
|
+
"shadcnFont",
|
|
128
|
+
"shadcnRadius"
|
|
129
|
+
]);
|
|
130
|
+
const MCP_SCHEMA_OPTION_OVERRIDES = {
|
|
131
|
+
ecosystem: EcosystemSchema.options,
|
|
132
|
+
frontend: FrontendSchema.options,
|
|
133
|
+
backend: BackendSchema.options,
|
|
134
|
+
addons: AddonsSchema.options,
|
|
135
|
+
examples: ExamplesSchema.options,
|
|
136
|
+
effect: EffectSchema.options
|
|
305
137
|
};
|
|
138
|
+
const MCP_ALL_SCHEMA_KEYS = ["ecosystem", ...CATEGORY_ORDER.flatMap((category) => MCP_LEGACY_CATEGORY_KEYS[category] ?? [category]).filter((key, index, keys) => keys.indexOf(key) === index)].filter((key) => getMcpSchemaOptionValues(key).length > 0);
|
|
139
|
+
function isMcpEcosystem(ecosystem) {
|
|
140
|
+
return MCP_ECOSYSTEMS.has(ecosystem);
|
|
141
|
+
}
|
|
142
|
+
function getMcpSchemaOptionValues(key) {
|
|
143
|
+
const override = MCP_SCHEMA_OPTION_OVERRIDES[key];
|
|
144
|
+
if (override) return [...override];
|
|
145
|
+
const categories = key in OPTION_CATEGORY_METADATA && !MCP_SCHEMA_EXCLUDED_CATEGORIES.has(key) ? [key] : [];
|
|
146
|
+
return [...new Set(categories.flatMap((category) => OPTION_CATEGORY_METADATA[category].options.map((option) => option.id)))];
|
|
147
|
+
}
|
|
148
|
+
function getMcpCategoryKeysForEcosystem(ecosystem) {
|
|
149
|
+
const keys = getCategoryOrderForEcosystem(ecosystem).flatMap((category) => MCP_LEGACY_CATEGORY_KEYS[category] ?? [category]);
|
|
150
|
+
return [...new Set(keys.filter((key) => getMcpSchemaOptionValues(key).length > 0))];
|
|
151
|
+
}
|
|
152
|
+
function getMcpSchemaKeysForEcosystem(ecosystem) {
|
|
153
|
+
return new Set([...getMcpCategoryKeysForEcosystem(ecosystem), ...MCP_SHARED_SCHEMA_KEYS]);
|
|
154
|
+
}
|
|
306
155
|
function getSchemaOptions(category, ecosystem) {
|
|
307
156
|
if (category) {
|
|
308
|
-
const
|
|
309
|
-
if (
|
|
310
|
-
if (schema instanceof z.ZodEnum) return {
|
|
311
|
-
category,
|
|
312
|
-
options: schema.options
|
|
313
|
-
};
|
|
157
|
+
const options = getMcpSchemaOptionValues(category);
|
|
158
|
+
if (options.length === 0) return { error: `Unknown category: ${category}. Available: ${MCP_ALL_SCHEMA_KEYS.join(", ")}` };
|
|
314
159
|
return {
|
|
315
160
|
category,
|
|
316
|
-
|
|
161
|
+
options
|
|
317
162
|
};
|
|
318
163
|
}
|
|
319
|
-
const allowedKeys = ecosystem &&
|
|
164
|
+
const allowedKeys = ecosystem && isMcpEcosystem(ecosystem) ? getMcpSchemaKeysForEcosystem(ecosystem) : null;
|
|
320
165
|
const result = {};
|
|
321
|
-
for (const
|
|
166
|
+
for (const key of MCP_ALL_SCHEMA_KEYS) {
|
|
322
167
|
if (allowedKeys && !allowedKeys.has(key)) continue;
|
|
323
|
-
|
|
168
|
+
result[key] = getMcpSchemaOptionValues(key);
|
|
324
169
|
}
|
|
325
170
|
return result;
|
|
326
171
|
}
|
|
@@ -345,14 +190,8 @@ function filterCompatibilityResult(result, ecosystem) {
|
|
|
345
190
|
adjustedStack: null,
|
|
346
191
|
changes
|
|
347
192
|
};
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
...ECOSYSTEM_CATEGORIES.shared,
|
|
351
|
-
"projectName",
|
|
352
|
-
"git",
|
|
353
|
-
"install",
|
|
354
|
-
"aiDocs"
|
|
355
|
-
]);
|
|
193
|
+
const relevantEcosystem = isMcpEcosystem(ecosystem) ? ecosystem : "typescript";
|
|
194
|
+
const relevantKeys = new Set([...getMcpCategoryKeysForEcosystem(relevantEcosystem), ...MCP_SHARED_COMPATIBILITY_KEYS]);
|
|
356
195
|
const filtered = {};
|
|
357
196
|
for (const [key, value] of Object.entries(adjustedStack)) if (relevantKeys.has(key)) filtered[key] = value;
|
|
358
197
|
return {
|
|
@@ -360,35 +199,185 @@ function filterCompatibilityResult(result, ecosystem) {
|
|
|
360
199
|
changes
|
|
361
200
|
};
|
|
362
201
|
}
|
|
202
|
+
const MCP_CODE_QUALITY_ADDONS = new Set([
|
|
203
|
+
"biome",
|
|
204
|
+
"oxlint",
|
|
205
|
+
"ultracite",
|
|
206
|
+
"lefthook",
|
|
207
|
+
"husky",
|
|
208
|
+
"ruler"
|
|
209
|
+
]);
|
|
210
|
+
const MCP_DOCUMENTATION_ADDONS = new Set(["starlight", "fumadocs"]);
|
|
211
|
+
const MCP_COMPATIBILITY_DEFAULTS = {
|
|
212
|
+
astroIntegration: "none",
|
|
213
|
+
runtime: "bun",
|
|
214
|
+
backend: "hono",
|
|
215
|
+
database: "none",
|
|
216
|
+
orm: "none",
|
|
217
|
+
dbSetup: "none",
|
|
218
|
+
auth: "none",
|
|
219
|
+
payments: "none",
|
|
220
|
+
email: "none",
|
|
221
|
+
fileUpload: "none",
|
|
222
|
+
logging: "none",
|
|
223
|
+
observability: "none",
|
|
224
|
+
featureFlags: "none",
|
|
225
|
+
analytics: "none",
|
|
226
|
+
backendLibraries: "none",
|
|
227
|
+
stateManagement: "none",
|
|
228
|
+
forms: "none",
|
|
229
|
+
validation: "none",
|
|
230
|
+
testing: "none",
|
|
231
|
+
realtime: "none",
|
|
232
|
+
jobQueue: "none",
|
|
233
|
+
caching: "none",
|
|
234
|
+
rateLimit: "none",
|
|
235
|
+
i18n: "none",
|
|
236
|
+
animation: "none",
|
|
237
|
+
cssFramework: "tailwind",
|
|
238
|
+
uiLibrary: "none",
|
|
239
|
+
shadcnBase: "radix",
|
|
240
|
+
shadcnStyle: "nova",
|
|
241
|
+
shadcnIconLibrary: "lucide",
|
|
242
|
+
shadcnColorTheme: "neutral",
|
|
243
|
+
shadcnBaseColor: "neutral",
|
|
244
|
+
shadcnFont: "inter",
|
|
245
|
+
shadcnRadius: "default",
|
|
246
|
+
cms: "none",
|
|
247
|
+
search: "none",
|
|
248
|
+
fileStorage: "none",
|
|
249
|
+
mobileUI: "none",
|
|
250
|
+
mobileStorage: "none",
|
|
251
|
+
mobileTesting: "none",
|
|
252
|
+
mobilePush: "none",
|
|
253
|
+
mobileOTA: "none",
|
|
254
|
+
packageManager: "bun",
|
|
255
|
+
versionChannel: "stable",
|
|
256
|
+
examples: [],
|
|
257
|
+
aiSdk: "none",
|
|
258
|
+
aiDocs: ["claude-md"],
|
|
259
|
+
git: "true",
|
|
260
|
+
install: "false",
|
|
261
|
+
api: "none",
|
|
262
|
+
webDeploy: "none",
|
|
263
|
+
serverDeploy: "none",
|
|
264
|
+
yolo: "false",
|
|
265
|
+
rustWebFramework: "none",
|
|
266
|
+
rustFrontend: "none",
|
|
267
|
+
rustOrm: "none",
|
|
268
|
+
rustApi: "none",
|
|
269
|
+
rustCli: "none",
|
|
270
|
+
rustLibraries: [],
|
|
271
|
+
rustLogging: "none",
|
|
272
|
+
rustErrorHandling: "none",
|
|
273
|
+
rustCaching: "none",
|
|
274
|
+
rustAuth: "none",
|
|
275
|
+
rustRealtime: "none",
|
|
276
|
+
rustMessageQueue: "none",
|
|
277
|
+
rustObservability: "none",
|
|
278
|
+
rustTemplating: "none",
|
|
279
|
+
pythonWebFramework: "none",
|
|
280
|
+
pythonOrm: "none",
|
|
281
|
+
pythonValidation: "none",
|
|
282
|
+
pythonAi: [],
|
|
283
|
+
pythonAuth: "none",
|
|
284
|
+
pythonApi: "none",
|
|
285
|
+
pythonTaskQueue: "none",
|
|
286
|
+
pythonGraphql: "none",
|
|
287
|
+
pythonQuality: "none",
|
|
288
|
+
pythonTesting: [],
|
|
289
|
+
pythonCaching: "none",
|
|
290
|
+
pythonRealtime: "none",
|
|
291
|
+
pythonObservability: "none",
|
|
292
|
+
pythonCli: [],
|
|
293
|
+
goWebFramework: "none",
|
|
294
|
+
goOrm: "none",
|
|
295
|
+
goApi: "none",
|
|
296
|
+
goCli: "none",
|
|
297
|
+
goLogging: "none",
|
|
298
|
+
goAuth: "none",
|
|
299
|
+
goTesting: [],
|
|
300
|
+
goRealtime: "none",
|
|
301
|
+
goMessageQueue: "none",
|
|
302
|
+
goCaching: "none",
|
|
303
|
+
goConfig: "none",
|
|
304
|
+
goObservability: "none",
|
|
305
|
+
javaWebFramework: "spring-boot",
|
|
306
|
+
javaBuildTool: "maven",
|
|
307
|
+
javaOrm: "none",
|
|
308
|
+
javaAuth: "none",
|
|
309
|
+
javaApi: "none",
|
|
310
|
+
javaLogging: "none",
|
|
311
|
+
javaLibraries: [],
|
|
312
|
+
javaTestingLibraries: ["junit5"],
|
|
313
|
+
dotnetWebFramework: "aspnet-minimal",
|
|
314
|
+
dotnetOrm: "ef-core",
|
|
315
|
+
dotnetAuth: "aspnet-identity",
|
|
316
|
+
dotnetApi: "minimal-api",
|
|
317
|
+
dotnetTesting: ["xunit"],
|
|
318
|
+
dotnetJobQueue: "none",
|
|
319
|
+
dotnetRealtime: "signalr",
|
|
320
|
+
dotnetObservability: ["serilog"],
|
|
321
|
+
dotnetValidation: "none",
|
|
322
|
+
dotnetCaching: "none",
|
|
323
|
+
dotnetDeploy: "docker",
|
|
324
|
+
elixirWebFramework: "phoenix",
|
|
325
|
+
elixirOrm: "ecto-sql",
|
|
326
|
+
elixirAuth: "none",
|
|
327
|
+
elixirApi: "rest",
|
|
328
|
+
elixirRealtime: "channels",
|
|
329
|
+
elixirJobs: "none",
|
|
330
|
+
elixirValidation: "ecto-changesets",
|
|
331
|
+
elixirHttp: "req",
|
|
332
|
+
elixirJson: "jason",
|
|
333
|
+
elixirEmail: "none",
|
|
334
|
+
elixirCaching: "none",
|
|
335
|
+
elixirObservability: "telemetry",
|
|
336
|
+
elixirTesting: "ex_unit",
|
|
337
|
+
elixirQuality: "credo",
|
|
338
|
+
elixirDeploy: "none",
|
|
339
|
+
elixirLibraries: []
|
|
340
|
+
};
|
|
341
|
+
const { backendLibraries: _backendLibrariesDefault, aiSdk: _aiSdkDefault, git: _compatibilityGitDefault, install: _compatibilityInstallDefault, yolo: _yoloDefault, ...MCP_PROJECT_COMPATIBILITY_DEFAULTS } = MCP_COMPATIBILITY_DEFAULTS;
|
|
342
|
+
const MCP_PROJECT_CONFIG_DEFAULTS = {
|
|
343
|
+
...MCP_PROJECT_COMPATIBILITY_DEFAULTS,
|
|
344
|
+
addons: [],
|
|
345
|
+
effect: "none",
|
|
346
|
+
ai: "none"
|
|
347
|
+
};
|
|
348
|
+
function cloneMcpInputDefault(value) {
|
|
349
|
+
return Array.isArray(value) ? [...value] : value;
|
|
350
|
+
}
|
|
351
|
+
function applyMcpInputDefaults(defaults, input) {
|
|
352
|
+
return Object.fromEntries(Object.entries(defaults).map(([key, fallback]) => [key, input[key] ?? cloneMcpInputDefault(fallback)]));
|
|
353
|
+
}
|
|
354
|
+
function getMcpCompatibilityDefaults(input) {
|
|
355
|
+
return applyMcpInputDefaults(MCP_COMPATIBILITY_DEFAULTS, input);
|
|
356
|
+
}
|
|
357
|
+
function getMcpProjectConfigDefaults(input) {
|
|
358
|
+
return applyMcpInputDefaults(MCP_PROJECT_CONFIG_DEFAULTS, input);
|
|
359
|
+
}
|
|
363
360
|
function buildProjectConfig(input, overrides) {
|
|
364
361
|
const projectName = input.projectName ?? "my-project";
|
|
365
362
|
const ecosystem = input.ecosystem ?? "typescript";
|
|
366
|
-
const frontend = input.frontend ?? (ecosystem === "react-native" ? ["native-bare"] : ["tanstack-router"]);
|
|
363
|
+
const frontend = input.frontend ?? (ecosystem === "react-native" ? ["native-bare"] : ecosystem === "typescript" ? ["tanstack-router"] : ["none"]);
|
|
367
364
|
const hasNativeFrontend = frontend.some((item) => item.startsWith("native-"));
|
|
368
365
|
const hasMobileProject = ecosystem === "react-native" || hasNativeFrontend;
|
|
366
|
+
const defaults = getMcpProjectConfigDefaults(input);
|
|
369
367
|
return {
|
|
370
368
|
projectName,
|
|
371
369
|
projectDir: overrides?.projectDir ?? "/virtual",
|
|
372
370
|
relativePath: overrides ? `./${projectName}` : "./virtual",
|
|
373
371
|
ecosystem,
|
|
374
372
|
frontend,
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
fileUpload: input.fileUpload ?? "none",
|
|
384
|
-
effect: input.effect ?? "none",
|
|
385
|
-
ai: input.ai ?? "none",
|
|
386
|
-
stateManagement: input.stateManagement ?? "none",
|
|
387
|
-
forms: input.forms ?? "none",
|
|
388
|
-
validation: input.validation ?? "none",
|
|
389
|
-
testing: input.testing ?? "none",
|
|
390
|
-
cssFramework: input.cssFramework ?? (ecosystem === "react-native" ? "none" : "tailwind"),
|
|
391
|
-
uiLibrary: input.uiLibrary ?? "none",
|
|
373
|
+
...defaults,
|
|
374
|
+
backend: input.backend ?? (ecosystem === "react-native" ? "none" : defaults.backend),
|
|
375
|
+
runtime: input.runtime ?? (ecosystem === "react-native" ? "none" : defaults.runtime),
|
|
376
|
+
cssFramework: input.cssFramework ?? (ecosystem === "react-native" ? "none" : defaults.cssFramework),
|
|
377
|
+
mobileNavigation: input.mobileNavigation ?? (hasMobileProject ? "expo-router" : "none"),
|
|
378
|
+
mobileDeepLinking: input.mobileDeepLinking ?? (hasMobileProject ? "expo-linking" : "none"),
|
|
379
|
+
astroIntegration: "none",
|
|
380
|
+
versionChannel: "stable",
|
|
392
381
|
shadcnBase: "radix",
|
|
393
382
|
shadcnStyle: "nova",
|
|
394
383
|
shadcnIconLibrary: "lucide",
|
|
@@ -396,82 +385,9 @@ function buildProjectConfig(input, overrides) {
|
|
|
396
385
|
shadcnBaseColor: "neutral",
|
|
397
386
|
shadcnFont: "inter",
|
|
398
387
|
shadcnRadius: "default",
|
|
399
|
-
realtime: input.realtime ?? "none",
|
|
400
|
-
jobQueue: input.jobQueue ?? "none",
|
|
401
|
-
animation: input.animation ?? "none",
|
|
402
|
-
logging: input.logging ?? "none",
|
|
403
|
-
observability: input.observability ?? "none",
|
|
404
|
-
featureFlags: input.featureFlags ?? "none",
|
|
405
|
-
analytics: input.analytics ?? "none",
|
|
406
|
-
mobileNavigation: input.mobileNavigation ?? (hasMobileProject ? "expo-router" : "none"),
|
|
407
|
-
mobileUI: input.mobileUI ?? "none",
|
|
408
|
-
mobileStorage: input.mobileStorage ?? "none",
|
|
409
|
-
mobileTesting: input.mobileTesting ?? "none",
|
|
410
|
-
mobilePush: input.mobilePush ?? "none",
|
|
411
|
-
mobileOTA: input.mobileOTA ?? "none",
|
|
412
|
-
mobileDeepLinking: input.mobileDeepLinking ?? (hasMobileProject ? "expo-linking" : "none"),
|
|
413
|
-
cms: input.cms ?? "none",
|
|
414
|
-
caching: input.caching ?? "none",
|
|
415
|
-
i18n: input.i18n ?? "none",
|
|
416
|
-
search: input.search ?? "none",
|
|
417
|
-
fileStorage: input.fileStorage ?? "none",
|
|
418
|
-
addons: input.addons ?? [],
|
|
419
|
-
examples: input.examples ?? [],
|
|
420
|
-
packageManager: input.packageManager ?? "bun",
|
|
421
|
-
versionChannel: "stable",
|
|
422
|
-
webDeploy: input.webDeploy ?? "none",
|
|
423
|
-
serverDeploy: input.serverDeploy ?? "none",
|
|
424
|
-
dbSetup: input.dbSetup ?? "none",
|
|
425
|
-
astroIntegration: "none",
|
|
426
|
-
git: !!overrides,
|
|
427
|
-
install: false,
|
|
428
388
|
aiDocs: ["claude-md"],
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
rustOrm: input.rustOrm ?? "none",
|
|
432
|
-
rustApi: input.rustApi ?? "none",
|
|
433
|
-
rustCli: input.rustCli ?? "none",
|
|
434
|
-
rustLibraries: input.rustLibraries ?? [],
|
|
435
|
-
rustLogging: input.rustLogging ?? "none",
|
|
436
|
-
rustErrorHandling: input.rustErrorHandling ?? "none",
|
|
437
|
-
rustCaching: input.rustCaching ?? "none",
|
|
438
|
-
rustAuth: input.rustAuth ?? "none",
|
|
439
|
-
pythonWebFramework: input.pythonWebFramework ?? "none",
|
|
440
|
-
pythonOrm: input.pythonOrm ?? "none",
|
|
441
|
-
pythonValidation: input.pythonValidation ?? "none",
|
|
442
|
-
pythonAi: input.pythonAi ?? [],
|
|
443
|
-
pythonAuth: input.pythonAuth ?? "none",
|
|
444
|
-
pythonApi: input.pythonApi ?? "none",
|
|
445
|
-
pythonTaskQueue: input.pythonTaskQueue ?? "none",
|
|
446
|
-
pythonGraphql: input.pythonGraphql ?? "none",
|
|
447
|
-
pythonQuality: input.pythonQuality ?? "none",
|
|
448
|
-
goWebFramework: input.goWebFramework ?? "none",
|
|
449
|
-
goOrm: input.goOrm ?? "none",
|
|
450
|
-
goApi: input.goApi ?? "none",
|
|
451
|
-
goCli: input.goCli ?? "none",
|
|
452
|
-
goLogging: input.goLogging ?? "none",
|
|
453
|
-
goAuth: input.goAuth ?? "none",
|
|
454
|
-
javaWebFramework: input.javaWebFramework ?? "spring-boot",
|
|
455
|
-
javaBuildTool: input.javaBuildTool ?? "maven",
|
|
456
|
-
javaOrm: input.javaOrm ?? "none",
|
|
457
|
-
javaAuth: input.javaAuth ?? "none",
|
|
458
|
-
javaLibraries: input.javaLibraries ?? [],
|
|
459
|
-
javaTestingLibraries: input.javaTestingLibraries ?? ["junit5"],
|
|
460
|
-
elixirWebFramework: input.elixirWebFramework ?? "phoenix",
|
|
461
|
-
elixirOrm: input.elixirOrm ?? "ecto-sql",
|
|
462
|
-
elixirAuth: input.elixirAuth ?? "none",
|
|
463
|
-
elixirApi: input.elixirApi ?? "rest",
|
|
464
|
-
elixirRealtime: input.elixirRealtime ?? "channels",
|
|
465
|
-
elixirJobs: input.elixirJobs ?? "none",
|
|
466
|
-
elixirValidation: input.elixirValidation ?? "ecto-changesets",
|
|
467
|
-
elixirHttp: input.elixirHttp ?? "req",
|
|
468
|
-
elixirJson: input.elixirJson ?? "jason",
|
|
469
|
-
elixirEmail: input.elixirEmail ?? "none",
|
|
470
|
-
elixirCaching: input.elixirCaching ?? "none",
|
|
471
|
-
elixirObservability: input.elixirObservability ?? "telemetry",
|
|
472
|
-
elixirTesting: input.elixirTesting ?? "ex_unit",
|
|
473
|
-
elixirQuality: input.elixirQuality ?? "credo",
|
|
474
|
-
elixirDeploy: input.elixirDeploy ?? "none"
|
|
389
|
+
git: !!overrides,
|
|
390
|
+
install: false
|
|
475
391
|
};
|
|
476
392
|
}
|
|
477
393
|
function sanitizePath(input) {
|
|
@@ -486,15 +402,9 @@ function buildCompatibilityInput(input) {
|
|
|
486
402
|
const addons = input.addons ?? [];
|
|
487
403
|
const ecosystem = input.ecosystem ?? "typescript";
|
|
488
404
|
const hasMobileProject = ecosystem === "react-native" || nativeFrontend.length > 0;
|
|
489
|
-
const
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
"ultracite",
|
|
493
|
-
"lefthook",
|
|
494
|
-
"husky",
|
|
495
|
-
"ruler"
|
|
496
|
-
].includes(a));
|
|
497
|
-
const documentation = addons.filter((a) => ["starlight", "fumadocs"].includes(a));
|
|
405
|
+
const defaults = getMcpCompatibilityDefaults(input);
|
|
406
|
+
const codeQuality = addons.filter((a) => MCP_CODE_QUALITY_ADDONS.has(a));
|
|
407
|
+
const documentation = addons.filter((a) => MCP_DOCUMENTATION_ADDONS.has(a));
|
|
498
408
|
const appPlatforms = addons.filter((a) => ![
|
|
499
409
|
...codeQuality,
|
|
500
410
|
...documentation,
|
|
@@ -505,109 +415,13 @@ function buildCompatibilityInput(input) {
|
|
|
505
415
|
projectName: input.projectName ?? null,
|
|
506
416
|
webFrontend,
|
|
507
417
|
nativeFrontend,
|
|
508
|
-
|
|
509
|
-
runtime: input.runtime ?? "bun",
|
|
510
|
-
backend: input.backend ?? "hono",
|
|
511
|
-
database: input.database ?? "none",
|
|
512
|
-
orm: input.orm ?? "none",
|
|
513
|
-
dbSetup: input.dbSetup ?? "none",
|
|
514
|
-
auth: input.auth ?? "none",
|
|
515
|
-
payments: input.payments ?? "none",
|
|
516
|
-
email: input.email ?? "none",
|
|
517
|
-
fileUpload: input.fileUpload ?? "none",
|
|
518
|
-
logging: input.logging ?? "none",
|
|
519
|
-
observability: input.observability ?? "none",
|
|
520
|
-
featureFlags: input.featureFlags ?? "none",
|
|
521
|
-
analytics: input.analytics ?? "none",
|
|
522
|
-
backendLibraries: "none",
|
|
523
|
-
stateManagement: input.stateManagement ?? "none",
|
|
524
|
-
forms: input.forms ?? "none",
|
|
525
|
-
validation: input.validation ?? "none",
|
|
526
|
-
testing: input.testing ?? "none",
|
|
527
|
-
realtime: input.realtime ?? "none",
|
|
528
|
-
jobQueue: input.jobQueue ?? "none",
|
|
529
|
-
caching: input.caching ?? "none",
|
|
530
|
-
i18n: input.i18n ?? "none",
|
|
531
|
-
animation: input.animation ?? "none",
|
|
532
|
-
cssFramework: input.cssFramework ?? "tailwind",
|
|
533
|
-
uiLibrary: input.uiLibrary ?? "none",
|
|
534
|
-
shadcnBase: input.shadcnBase ?? "radix",
|
|
535
|
-
shadcnStyle: input.shadcnStyle ?? "nova",
|
|
536
|
-
shadcnIconLibrary: input.shadcnIconLibrary ?? "lucide",
|
|
537
|
-
shadcnColorTheme: input.shadcnColorTheme ?? "neutral",
|
|
538
|
-
shadcnBaseColor: input.shadcnBaseColor ?? "neutral",
|
|
539
|
-
shadcnFont: input.shadcnFont ?? "inter",
|
|
540
|
-
shadcnRadius: input.shadcnRadius ?? "default",
|
|
541
|
-
cms: input.cms ?? "none",
|
|
542
|
-
search: input.search ?? "none",
|
|
543
|
-
fileStorage: input.fileStorage ?? "none",
|
|
418
|
+
...defaults,
|
|
544
419
|
mobileNavigation: input.mobileNavigation ?? (hasMobileProject ? "expo-router" : "none"),
|
|
545
|
-
mobileUI: input.mobileUI ?? "none",
|
|
546
|
-
mobileStorage: input.mobileStorage ?? "none",
|
|
547
|
-
mobileTesting: input.mobileTesting ?? "none",
|
|
548
|
-
mobilePush: input.mobilePush ?? "none",
|
|
549
|
-
mobileOTA: input.mobileOTA ?? "none",
|
|
550
420
|
mobileDeepLinking: input.mobileDeepLinking ?? (hasMobileProject ? "expo-linking" : "none"),
|
|
551
421
|
codeQuality,
|
|
552
422
|
documentation,
|
|
553
423
|
appPlatforms,
|
|
554
|
-
|
|
555
|
-
versionChannel: "stable",
|
|
556
|
-
examples: input.examples ?? [],
|
|
557
|
-
aiSdk: input.ai ?? "none",
|
|
558
|
-
aiDocs: input.aiDocs ?? ["claude-md"],
|
|
559
|
-
git: "true",
|
|
560
|
-
install: "false",
|
|
561
|
-
api: input.api ?? "none",
|
|
562
|
-
webDeploy: input.webDeploy ?? "none",
|
|
563
|
-
serverDeploy: input.serverDeploy ?? "none",
|
|
564
|
-
yolo: "false",
|
|
565
|
-
rustWebFramework: input.rustWebFramework ?? "none",
|
|
566
|
-
rustFrontend: input.rustFrontend ?? "none",
|
|
567
|
-
rustOrm: input.rustOrm ?? "none",
|
|
568
|
-
rustApi: input.rustApi ?? "none",
|
|
569
|
-
rustCli: input.rustCli ?? "none",
|
|
570
|
-
rustLibraries: input.rustLibraries ?? [],
|
|
571
|
-
rustLogging: input.rustLogging ?? "none",
|
|
572
|
-
rustErrorHandling: input.rustErrorHandling ?? "none",
|
|
573
|
-
rustCaching: input.rustCaching ?? "none",
|
|
574
|
-
rustAuth: input.rustAuth ?? "none",
|
|
575
|
-
pythonWebFramework: input.pythonWebFramework ?? "none",
|
|
576
|
-
pythonOrm: input.pythonOrm ?? "none",
|
|
577
|
-
pythonValidation: input.pythonValidation ?? "none",
|
|
578
|
-
pythonAi: input.pythonAi ?? [],
|
|
579
|
-
pythonAuth: input.pythonAuth ?? "none",
|
|
580
|
-
pythonApi: input.pythonApi ?? "none",
|
|
581
|
-
pythonTaskQueue: input.pythonTaskQueue ?? "none",
|
|
582
|
-
pythonGraphql: input.pythonGraphql ?? "none",
|
|
583
|
-
pythonQuality: input.pythonQuality ?? "none",
|
|
584
|
-
goWebFramework: input.goWebFramework ?? "none",
|
|
585
|
-
goOrm: input.goOrm ?? "none",
|
|
586
|
-
goApi: input.goApi ?? "none",
|
|
587
|
-
goCli: input.goCli ?? "none",
|
|
588
|
-
goLogging: input.goLogging ?? "none",
|
|
589
|
-
goAuth: input.goAuth ?? "none",
|
|
590
|
-
javaWebFramework: input.javaWebFramework ?? "spring-boot",
|
|
591
|
-
javaBuildTool: input.javaBuildTool ?? "maven",
|
|
592
|
-
javaOrm: input.javaOrm ?? "none",
|
|
593
|
-
javaAuth: input.javaAuth ?? "none",
|
|
594
|
-
javaLibraries: input.javaLibraries ?? [],
|
|
595
|
-
javaTestingLibraries: input.javaTestingLibraries ?? ["junit5"],
|
|
596
|
-
elixirWebFramework: input.elixirWebFramework ?? "phoenix",
|
|
597
|
-
elixirOrm: input.elixirOrm ?? "ecto-sql",
|
|
598
|
-
elixirAuth: input.elixirAuth ?? "none",
|
|
599
|
-
elixirApi: input.elixirApi ?? "rest",
|
|
600
|
-
elixirRealtime: input.elixirRealtime ?? "channels",
|
|
601
|
-
elixirJobs: input.elixirJobs ?? "none",
|
|
602
|
-
elixirValidation: input.elixirValidation ?? "ecto-changesets",
|
|
603
|
-
elixirHttp: input.elixirHttp ?? "req",
|
|
604
|
-
elixirJson: input.elixirJson ?? "jason",
|
|
605
|
-
elixirEmail: input.elixirEmail ?? "none",
|
|
606
|
-
elixirCaching: input.elixirCaching ?? "none",
|
|
607
|
-
elixirObservability: input.elixirObservability ?? "telemetry",
|
|
608
|
-
elixirTesting: input.elixirTesting ?? "ex_unit",
|
|
609
|
-
elixirQuality: input.elixirQuality ?? "credo",
|
|
610
|
-
elixirDeploy: input.elixirDeploy ?? "none"
|
|
424
|
+
aiSdk: input.ai ?? defaults.aiSdk
|
|
611
425
|
};
|
|
612
426
|
}
|
|
613
427
|
function summarizeTree(tree) {
|
|
@@ -626,6 +440,19 @@ function summarizeTree(tree) {
|
|
|
626
440
|
files: paths
|
|
627
441
|
};
|
|
628
442
|
}
|
|
443
|
+
function getMcpGraphPreview(config) {
|
|
444
|
+
const stackParts = config.stackParts?.length ? config.stackParts : legacyProjectConfigToStackParts(config);
|
|
445
|
+
const graphSummary = stackParts.length > 0 ? getGraphSummary({ stackParts }) : void 0;
|
|
446
|
+
const effectiveStack = stackParts.length > 0 ? getEffectiveStack({ stackParts }) : void 0;
|
|
447
|
+
const stackPartSpecs = stackParts.filter((part) => part.source !== "provided").map((part) => formatStackPartSpec(part, stackParts));
|
|
448
|
+
return {
|
|
449
|
+
...graphSummary ? {
|
|
450
|
+
graphSummary,
|
|
451
|
+
effectiveStack
|
|
452
|
+
} : {},
|
|
453
|
+
stackPartSpecs
|
|
454
|
+
};
|
|
455
|
+
}
|
|
629
456
|
const COMPATIBILITY_RULES_MD = `# Better-Fullstack Compatibility Rules
|
|
630
457
|
|
|
631
458
|
## Backend Constraints
|
|
@@ -764,51 +591,21 @@ async function startMcpServer() {
|
|
|
764
591
|
text: JSON.stringify(result, null, 2)
|
|
765
592
|
}] };
|
|
766
593
|
});
|
|
767
|
-
|
|
768
|
-
ecosystem: EcosystemSchema.describe("Language ecosystem"),
|
|
769
|
-
frontend: z.array(z.string()).optional().describe("Web frontend frameworks (TypeScript only)"),
|
|
770
|
-
backend: z.string().optional().describe("Backend framework"),
|
|
771
|
-
runtime: z.string().optional().describe("JavaScript runtime"),
|
|
772
|
-
database: z.string().optional().describe("Database type"),
|
|
773
|
-
orm: z.string().optional().describe("ORM"),
|
|
774
|
-
api: z.string().optional().describe("API layer"),
|
|
775
|
-
auth: z.string().optional().describe("Auth provider"),
|
|
776
|
-
payments: z.string().optional().describe("Payments provider"),
|
|
777
|
-
email: EmailSchema.optional().describe("Email provider"),
|
|
778
|
-
fileUpload: FileUploadSchema.optional().describe("File upload provider"),
|
|
779
|
-
ai: AISchema.optional().describe("AI SDK"),
|
|
780
|
-
stateManagement: StateManagementSchema.optional().describe("State management"),
|
|
781
|
-
forms: FormsSchema.optional().describe("Forms library"),
|
|
782
|
-
validation: ValidationSchema.optional().describe("Validation library"),
|
|
783
|
-
testing: TestingSchema.optional().describe("Testing framework"),
|
|
784
|
-
realtime: RealtimeSchema.optional().describe("Realtime library"),
|
|
785
|
-
jobQueue: JobQueueSchema.optional().describe("Job queue"),
|
|
786
|
-
animation: AnimationSchema.optional().describe("Animation library"),
|
|
787
|
-
logging: LoggingSchema.optional().describe("Logging library"),
|
|
788
|
-
observability: ObservabilitySchema.optional().describe("Observability provider"),
|
|
789
|
-
featureFlags: FeatureFlagsSchema.optional().describe("Feature flags provider"),
|
|
790
|
-
analytics: AnalyticsSchema.optional().describe("Analytics provider"),
|
|
791
|
-
cms: CMSSchema.optional().describe("CMS"),
|
|
792
|
-
caching: CachingSchema.optional().describe("Caching solution"),
|
|
793
|
-
i18n: I18nSchema.optional().describe("Internationalization library"),
|
|
794
|
-
search: SearchSchema.optional().describe("Search engine"),
|
|
795
|
-
fileStorage: FileStorageSchema.optional().describe("File storage"),
|
|
594
|
+
const mobileInputSchema = {
|
|
796
595
|
mobileNavigation: MobileNavigationSchema.optional().describe("Mobile navigation"),
|
|
797
596
|
mobileUI: MobileUISchema.optional().describe("Mobile UI"),
|
|
798
597
|
mobileStorage: MobileStorageSchema.optional().describe("Mobile storage"),
|
|
799
598
|
mobileTesting: MobileTestingSchema.optional().describe("Mobile testing"),
|
|
800
599
|
mobilePush: MobilePushSchema.optional().describe("Mobile push notifications"),
|
|
801
600
|
mobileOTA: MobileOTASchema.optional().describe("Mobile OTA updates"),
|
|
802
|
-
mobileDeepLinking: MobileDeepLinkingSchema.optional().describe("Mobile deep linking")
|
|
601
|
+
mobileDeepLinking: MobileDeepLinkingSchema.optional().describe("Mobile deep linking")
|
|
602
|
+
};
|
|
603
|
+
const deploymentInputSchema = {
|
|
803
604
|
dbSetup: DatabaseSetupSchema.optional().describe("Database hosting provider"),
|
|
804
605
|
webDeploy: WebDeploySchema.optional().describe("Web deployment target"),
|
|
805
|
-
serverDeploy: ServerDeploySchema.optional().describe("Server deployment target")
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
cssFramework: z.string().optional().describe("CSS framework"),
|
|
809
|
-
addons: z.array(AddonsSchema).optional().describe("Addon list"),
|
|
810
|
-
examples: z.array(ExamplesSchema).optional().describe("Example templates"),
|
|
811
|
-
packageManager: PackageManagerSchema.optional().describe("Package manager"),
|
|
606
|
+
serverDeploy: ServerDeploySchema.optional().describe("Server deployment target")
|
|
607
|
+
};
|
|
608
|
+
const crossEcosystemInputSchema = {
|
|
812
609
|
rustWebFramework: RustWebFrameworkSchema.optional().describe("Rust web framework"),
|
|
813
610
|
rustFrontend: RustFrontendSchema.optional().describe("Rust frontend (WASM)"),
|
|
814
611
|
rustOrm: RustOrmSchema.optional().describe("Rust ORM"),
|
|
@@ -819,6 +616,10 @@ async function startMcpServer() {
|
|
|
819
616
|
rustErrorHandling: RustErrorHandlingSchema.optional().describe("Rust error handling library"),
|
|
820
617
|
rustCaching: RustCachingSchema.optional().describe("Rust caching library"),
|
|
821
618
|
rustAuth: RustAuthSchema.optional().describe("Rust authentication library"),
|
|
619
|
+
rustRealtime: RustRealtimeSchema.optional().describe("Rust realtime library"),
|
|
620
|
+
rustMessageQueue: RustMessageQueueSchema.optional().describe("Rust message queue"),
|
|
621
|
+
rustObservability: RustObservabilitySchema.optional().describe("Rust observability"),
|
|
622
|
+
rustTemplating: RustTemplatingSchema.optional().describe("Rust template engine"),
|
|
822
623
|
pythonWebFramework: PythonWebFrameworkSchema.optional().describe("Python web framework"),
|
|
823
624
|
pythonOrm: PythonOrmSchema.optional().describe("Python ORM"),
|
|
824
625
|
pythonValidation: PythonValidationSchema.optional().describe("Python validation"),
|
|
@@ -828,18 +629,42 @@ async function startMcpServer() {
|
|
|
828
629
|
pythonTaskQueue: PythonTaskQueueSchema.optional().describe("Python task queue"),
|
|
829
630
|
pythonGraphql: PythonGraphqlSchema.optional().describe("Python GraphQL framework"),
|
|
830
631
|
pythonQuality: PythonQualitySchema.optional().describe("Python code quality"),
|
|
632
|
+
pythonTesting: z.array(PythonTestingSchema).optional().describe("Python testing libraries"),
|
|
633
|
+
pythonCaching: PythonCachingSchema.optional().describe("Python caching library"),
|
|
634
|
+
pythonRealtime: PythonRealtimeSchema.optional().describe("Python realtime library"),
|
|
635
|
+
pythonObservability: PythonObservabilitySchema.optional().describe("Python observability"),
|
|
636
|
+
pythonCli: z.array(PythonCliSchema).optional().describe("Python CLI tooling"),
|
|
831
637
|
goWebFramework: GoWebFrameworkSchema.optional().describe("Go web framework"),
|
|
832
638
|
goOrm: GoOrmSchema.optional().describe("Go ORM"),
|
|
833
639
|
goApi: GoApiSchema.optional().describe("Go API layer"),
|
|
834
640
|
goCli: GoCliSchema.optional().describe("Go CLI framework"),
|
|
835
641
|
goLogging: GoLoggingSchema.optional().describe("Go logging library"),
|
|
836
642
|
goAuth: GoAuthSchema.optional().describe("Go authentication library"),
|
|
643
|
+
goTesting: z.array(GoTestingSchema).optional().describe("Go testing libraries"),
|
|
644
|
+
goRealtime: GoRealtimeSchema.optional().describe("Go realtime/WebSocket library"),
|
|
645
|
+
goMessageQueue: GoMessageQueueSchema.optional().describe("Go message queue"),
|
|
646
|
+
goCaching: GoCachingSchema.optional().describe("Go caching library"),
|
|
647
|
+
goConfig: GoConfigSchema.optional().describe("Go config management"),
|
|
648
|
+
goObservability: GoObservabilitySchema.optional().describe("Go observability"),
|
|
837
649
|
javaWebFramework: JavaWebFrameworkSchema.optional().describe("Java web framework"),
|
|
838
650
|
javaBuildTool: JavaBuildToolSchema.optional().describe("Java build tool"),
|
|
839
651
|
javaOrm: JavaOrmSchema.optional().describe("Java ORM"),
|
|
840
652
|
javaAuth: JavaAuthSchema.optional().describe("Java authentication library"),
|
|
653
|
+
javaApi: JavaApiSchema.optional().describe("Java API layer"),
|
|
654
|
+
javaLogging: JavaLoggingSchema.optional().describe("Java logging configuration"),
|
|
841
655
|
javaLibraries: z.array(JavaLibrariesSchema).optional().describe("Java application libraries"),
|
|
842
656
|
javaTestingLibraries: z.array(JavaTestingLibrariesSchema).optional().describe("Java testing libraries"),
|
|
657
|
+
dotnetWebFramework: DotnetWebFrameworkSchema.optional().describe(".NET web framework"),
|
|
658
|
+
dotnetOrm: DotnetOrmSchema.optional().describe(".NET ORM/data access"),
|
|
659
|
+
dotnetAuth: DotnetAuthSchema.optional().describe(".NET authentication library"),
|
|
660
|
+
dotnetApi: DotnetApiSchema.optional().describe(".NET API style"),
|
|
661
|
+
dotnetTesting: z.array(DotnetTestingSchema).optional().describe(".NET testing libraries"),
|
|
662
|
+
dotnetJobQueue: DotnetJobQueueSchema.optional().describe(".NET jobs and scheduling"),
|
|
663
|
+
dotnetRealtime: DotnetRealtimeSchema.optional().describe(".NET realtime feature"),
|
|
664
|
+
dotnetObservability: z.array(DotnetObservabilitySchema).optional().describe(".NET observability/logging libraries"),
|
|
665
|
+
dotnetValidation: DotnetValidationSchema.optional().describe(".NET validation"),
|
|
666
|
+
dotnetCaching: DotnetCachingSchema.optional().describe(".NET caching library"),
|
|
667
|
+
dotnetDeploy: DotnetDeploySchema.optional().describe(".NET deployment target"),
|
|
843
668
|
elixirWebFramework: ElixirWebFrameworkSchema.optional().describe("Elixir web framework"),
|
|
844
669
|
elixirOrm: ElixirOrmSchema.optional().describe("Elixir persistence layer"),
|
|
845
670
|
elixirAuth: ElixirAuthSchema.optional().describe("Elixir authentication"),
|
|
@@ -854,7 +679,48 @@ async function startMcpServer() {
|
|
|
854
679
|
elixirObservability: ElixirObservabilitySchema.optional().describe("Elixir observability"),
|
|
855
680
|
elixirTesting: ElixirTestingSchema.optional().describe("Elixir testing library"),
|
|
856
681
|
elixirQuality: ElixirQualitySchema.optional().describe("Elixir code quality/security"),
|
|
857
|
-
elixirDeploy: ElixirDeploySchema.optional().describe("Elixir deployment target")
|
|
682
|
+
elixirDeploy: ElixirDeploySchema.optional().describe("Elixir deployment target"),
|
|
683
|
+
elixirLibraries: z.array(ElixirLibrariesSchema).optional().describe("Elixir libraries")
|
|
684
|
+
};
|
|
685
|
+
registerTool("bfs_check_compatibility", "Validates a stack combination and returns auto-adjusted selections with warnings. Call BEFORE creating a project to avoid invalid combinations.", mcpInputSchema({
|
|
686
|
+
ecosystem: EcosystemSchema.describe("Language ecosystem"),
|
|
687
|
+
frontend: z.array(z.string()).optional().describe("Web frontend frameworks (TypeScript only)"),
|
|
688
|
+
backend: z.string().optional().describe("Backend framework"),
|
|
689
|
+
runtime: z.string().optional().describe("JavaScript runtime"),
|
|
690
|
+
database: z.string().optional().describe("Database type"),
|
|
691
|
+
orm: z.string().optional().describe("ORM"),
|
|
692
|
+
api: z.string().optional().describe("API layer"),
|
|
693
|
+
auth: z.string().optional().describe("Auth provider"),
|
|
694
|
+
payments: z.string().optional().describe("Payments provider"),
|
|
695
|
+
email: EmailSchema.optional().describe("Email provider"),
|
|
696
|
+
fileUpload: FileUploadSchema.optional().describe("File upload provider"),
|
|
697
|
+
ai: AISchema.optional().describe("AI SDK"),
|
|
698
|
+
stateManagement: StateManagementSchema.optional().describe("State management"),
|
|
699
|
+
forms: FormsSchema.optional().describe("Forms library"),
|
|
700
|
+
validation: ValidationSchema.optional().describe("Validation library"),
|
|
701
|
+
testing: TestingSchema.optional().describe("Testing framework"),
|
|
702
|
+
realtime: RealtimeSchema.optional().describe("Realtime library"),
|
|
703
|
+
jobQueue: JobQueueSchema.optional().describe("Job queue"),
|
|
704
|
+
animation: AnimationSchema.optional().describe("Animation library"),
|
|
705
|
+
logging: LoggingSchema.optional().describe("Logging library"),
|
|
706
|
+
observability: ObservabilitySchema.optional().describe("Observability provider"),
|
|
707
|
+
featureFlags: FeatureFlagsSchema.optional().describe("Feature flags provider"),
|
|
708
|
+
analytics: AnalyticsSchema.optional().describe("Analytics provider"),
|
|
709
|
+
cms: CMSSchema.optional().describe("CMS"),
|
|
710
|
+
caching: CachingSchema.optional().describe("Caching solution"),
|
|
711
|
+
rateLimit: RateLimitSchema.optional().describe("Rate limiting solution"),
|
|
712
|
+
i18n: I18nSchema.optional().describe("Internationalization library"),
|
|
713
|
+
search: SearchSchema.optional().describe("Search engine"),
|
|
714
|
+
fileStorage: FileStorageSchema.optional().describe("File storage"),
|
|
715
|
+
...mobileInputSchema,
|
|
716
|
+
...deploymentInputSchema,
|
|
717
|
+
astroIntegration: AstroIntegrationSchema.optional().describe("Astro UI framework integration"),
|
|
718
|
+
uiLibrary: z.string().optional().describe("UI component library"),
|
|
719
|
+
cssFramework: z.string().optional().describe("CSS framework"),
|
|
720
|
+
addons: z.array(AddonsSchema).optional().describe("Addon list"),
|
|
721
|
+
examples: z.array(ExamplesSchema).optional().describe("Example templates"),
|
|
722
|
+
packageManager: PackageManagerSchema.optional().describe("Package manager"),
|
|
723
|
+
...crossEcosystemInputSchema
|
|
858
724
|
}), async (input) => {
|
|
859
725
|
try {
|
|
860
726
|
const filtered = filterCompatibilityResult(analyzeStackCompatibility(buildCompatibilityInput(input)), input.ecosystem);
|
|
@@ -902,81 +768,32 @@ async function startMcpServer() {
|
|
|
902
768
|
featureFlags: FeatureFlagsSchema.optional().describe("Feature flag provider"),
|
|
903
769
|
search: SearchSchema.optional().describe("Search engine"),
|
|
904
770
|
caching: CachingSchema.optional().describe("Caching solution"),
|
|
771
|
+
rateLimit: RateLimitSchema.optional().describe("Rate limiting solution"),
|
|
905
772
|
i18n: I18nSchema.optional().describe("Internationalization (i18n) library"),
|
|
906
773
|
cms: CMSSchema.optional().describe("CMS"),
|
|
907
774
|
fileStorage: FileStorageSchema.optional().describe("File storage"),
|
|
908
|
-
|
|
909
|
-
mobileUI: MobileUISchema.optional().describe("Mobile UI"),
|
|
910
|
-
mobileStorage: MobileStorageSchema.optional().describe("Mobile storage"),
|
|
911
|
-
mobileTesting: MobileTestingSchema.optional().describe("Mobile testing"),
|
|
912
|
-
mobilePush: MobilePushSchema.optional().describe("Mobile push notifications"),
|
|
913
|
-
mobileOTA: MobileOTASchema.optional().describe("Mobile OTA updates"),
|
|
914
|
-
mobileDeepLinking: MobileDeepLinkingSchema.optional().describe("Mobile deep linking"),
|
|
775
|
+
...mobileInputSchema,
|
|
915
776
|
fileUpload: FileUploadSchema.optional().describe("File upload"),
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
dbSetup: DatabaseSetupSchema.optional().describe("Database hosting provider"),
|
|
919
|
-
rustWebFramework: RustWebFrameworkSchema.optional().describe("Rust web framework"),
|
|
920
|
-
rustFrontend: RustFrontendSchema.optional().describe("Rust frontend (WASM)"),
|
|
921
|
-
rustOrm: RustOrmSchema.optional().describe("Rust ORM"),
|
|
922
|
-
rustApi: RustApiSchema.optional().describe("Rust API layer"),
|
|
923
|
-
rustCli: RustCliSchema.optional().describe("Rust CLI framework"),
|
|
924
|
-
rustLibraries: z.array(RustLibrariesSchema).optional().describe("Rust libraries"),
|
|
925
|
-
rustLogging: RustLoggingSchema.optional().describe("Rust logging library"),
|
|
926
|
-
rustErrorHandling: RustErrorHandlingSchema.optional().describe("Rust error handling library"),
|
|
927
|
-
rustCaching: RustCachingSchema.optional().describe("Rust caching library"),
|
|
928
|
-
rustAuth: RustAuthSchema.optional().describe("Rust authentication library"),
|
|
929
|
-
pythonWebFramework: PythonWebFrameworkSchema.optional().describe("Python web framework"),
|
|
930
|
-
pythonOrm: PythonOrmSchema.optional().describe("Python ORM"),
|
|
931
|
-
pythonValidation: PythonValidationSchema.optional().describe("Python validation"),
|
|
932
|
-
pythonAi: z.array(PythonAiSchema).optional().describe("Python AI libraries"),
|
|
933
|
-
pythonAuth: PythonAuthSchema.optional().describe("Python auth library"),
|
|
934
|
-
pythonApi: PythonApiSchema.optional().describe("Python API framework"),
|
|
935
|
-
pythonTaskQueue: PythonTaskQueueSchema.optional().describe("Python task queue"),
|
|
936
|
-
pythonGraphql: PythonGraphqlSchema.optional().describe("Python GraphQL framework"),
|
|
937
|
-
pythonQuality: PythonQualitySchema.optional().describe("Python code quality"),
|
|
938
|
-
goWebFramework: GoWebFrameworkSchema.optional().describe("Go web framework"),
|
|
939
|
-
goOrm: GoOrmSchema.optional().describe("Go ORM"),
|
|
940
|
-
goApi: GoApiSchema.optional().describe("Go API layer"),
|
|
941
|
-
goCli: GoCliSchema.optional().describe("Go CLI framework"),
|
|
942
|
-
goLogging: GoLoggingSchema.optional().describe("Go logging library"),
|
|
943
|
-
goAuth: GoAuthSchema.optional().describe("Go authentication library"),
|
|
944
|
-
javaWebFramework: JavaWebFrameworkSchema.optional().describe("Java web framework"),
|
|
945
|
-
javaBuildTool: JavaBuildToolSchema.optional().describe("Java build tool"),
|
|
946
|
-
javaOrm: JavaOrmSchema.optional().describe("Java ORM"),
|
|
947
|
-
javaAuth: JavaAuthSchema.optional().describe("Java authentication library"),
|
|
948
|
-
javaLibraries: z.array(JavaLibrariesSchema).optional().describe("Java application libraries"),
|
|
949
|
-
javaTestingLibraries: z.array(JavaTestingLibrariesSchema).optional().describe("Java testing libraries"),
|
|
950
|
-
elixirWebFramework: ElixirWebFrameworkSchema.optional().describe("Elixir web framework"),
|
|
951
|
-
elixirOrm: ElixirOrmSchema.optional().describe("Elixir persistence layer"),
|
|
952
|
-
elixirAuth: ElixirAuthSchema.optional().describe("Elixir authentication"),
|
|
953
|
-
elixirApi: ElixirApiSchema.optional().describe("Elixir API layer"),
|
|
954
|
-
elixirRealtime: ElixirRealtimeSchema.optional().describe("Elixir realtime feature"),
|
|
955
|
-
elixirJobs: ElixirJobsSchema.optional().describe("Elixir jobs and scheduling"),
|
|
956
|
-
elixirValidation: ElixirValidationSchema.optional().describe("Elixir validation/data"),
|
|
957
|
-
elixirHttp: ElixirHttpSchema.optional().describe("Elixir HTTP client"),
|
|
958
|
-
elixirJson: ElixirJsonSchema.optional().describe("Elixir JSON library"),
|
|
959
|
-
elixirEmail: ElixirEmailSchema.optional().describe("Elixir email library"),
|
|
960
|
-
elixirCaching: ElixirCachingSchema.optional().describe("Elixir caching library"),
|
|
961
|
-
elixirObservability: ElixirObservabilitySchema.optional().describe("Elixir observability"),
|
|
962
|
-
elixirTesting: ElixirTestingSchema.optional().describe("Elixir testing library"),
|
|
963
|
-
elixirQuality: ElixirQualitySchema.optional().describe("Elixir code quality/security"),
|
|
964
|
-
elixirDeploy: ElixirDeploySchema.optional().describe("Elixir deployment target")
|
|
777
|
+
...deploymentInputSchema,
|
|
778
|
+
...crossEcosystemInputSchema
|
|
965
779
|
};
|
|
966
780
|
registerTool("bfs_plan_project", "Dry-run: generates a project in-memory and returns the file tree WITHOUT writing to disk. Use this to preview what would be created.", mcpInputSchema(planCreateSchema), async (input) => {
|
|
967
781
|
try {
|
|
968
782
|
const { generateVirtualProject, EMBEDDED_TEMPLATES } = await import("@better-fullstack/template-generator");
|
|
783
|
+
const config = buildProjectConfig(input);
|
|
969
784
|
const result = await generateVirtualProject({
|
|
970
|
-
config
|
|
785
|
+
config,
|
|
971
786
|
templates: EMBEDDED_TEMPLATES
|
|
972
787
|
});
|
|
973
788
|
if (result.success && result.tree) {
|
|
974
789
|
const summary = summarizeTree(result.tree);
|
|
790
|
+
const graphPreview = getMcpGraphPreview(config);
|
|
975
791
|
return { content: [{
|
|
976
792
|
type: "text",
|
|
977
793
|
text: JSON.stringify({
|
|
978
794
|
success: true,
|
|
979
|
-
...summary
|
|
795
|
+
...summary,
|
|
796
|
+
...graphPreview
|
|
980
797
|
}, null, 2)
|
|
981
798
|
}] };
|
|
982
799
|
}
|
|
@@ -1028,9 +845,10 @@ async function startMcpServer() {
|
|
|
1028
845
|
};
|
|
1029
846
|
await writeTreeToFilesystem(result.tree, projectDir);
|
|
1030
847
|
await writeBtsConfig(config);
|
|
848
|
+
const graphPreview = getMcpGraphPreview(config);
|
|
1031
849
|
let addonWarnings = [];
|
|
1032
850
|
if (config.addons.length > 0 && config.addons[0] !== "none") {
|
|
1033
|
-
const { setupAddons } = await import("./addons-setup-
|
|
851
|
+
const { setupAddons } = await import("./addons-setup-CV5uZyhH.mjs");
|
|
1034
852
|
addonWarnings = await setupAddons(config);
|
|
1035
853
|
}
|
|
1036
854
|
const installCmd = getInstallCommand(input.ecosystem ?? "typescript", projectName, input.packageManager, input.javaBuildTool, input.javaWebFramework);
|
|
@@ -1040,6 +858,7 @@ async function startMcpServer() {
|
|
|
1040
858
|
success: true,
|
|
1041
859
|
projectDirectory: projectDir,
|
|
1042
860
|
fileCount: result.tree.fileCount,
|
|
861
|
+
...graphPreview,
|
|
1043
862
|
...addonWarnings.length > 0 ? { addonWarnings } : {},
|
|
1044
863
|
message: `Project created at ${projectDir}. Tell the user to run: ${installCmd}`
|
|
1045
864
|
}, null, 2)
|
|
@@ -1076,6 +895,13 @@ async function startMcpServer() {
|
|
|
1076
895
|
const existingAddons = new Set(config.addons ?? []);
|
|
1077
896
|
const newAddons = (addons ?? []).filter((a) => a !== "none" && !existingAddons.has(a));
|
|
1078
897
|
const mergedAddons = [...new Set([...config.addons ?? [], ...newAddons])];
|
|
898
|
+
const updatePreview = previewBtsConfigUpdate(config, {
|
|
899
|
+
addons: mergedAddons,
|
|
900
|
+
webDeploy: webDeploy ?? config.webDeploy,
|
|
901
|
+
serverDeploy: serverDeploy ?? config.serverDeploy
|
|
902
|
+
});
|
|
903
|
+
const existingGraphPreview = getMcpGraphPreview(config);
|
|
904
|
+
const proposedGraphPreview = getMcpGraphPreview(updatePreview);
|
|
1079
905
|
const compatResult = analyzeStackCompatibility(buildCompatibilityInput({
|
|
1080
906
|
...config,
|
|
1081
907
|
addons: mergedAddons,
|
|
@@ -1091,12 +917,18 @@ async function startMcpServer() {
|
|
|
1091
917
|
ecosystem: config.ecosystem,
|
|
1092
918
|
frontend: config.frontend,
|
|
1093
919
|
backend: config.backend,
|
|
1094
|
-
addons: config.addons
|
|
920
|
+
addons: config.addons,
|
|
921
|
+
graphSummary: existingGraphPreview.graphSummary,
|
|
922
|
+
effectiveStack: existingGraphPreview.effectiveStack,
|
|
923
|
+
stackPartSpecs: existingGraphPreview.stackPartSpecs
|
|
1095
924
|
},
|
|
1096
925
|
proposedAdditions: {
|
|
1097
926
|
newAddons,
|
|
1098
927
|
webDeploy: webDeploy ?? null,
|
|
1099
|
-
serverDeploy: serverDeploy ?? null
|
|
928
|
+
serverDeploy: serverDeploy ?? null,
|
|
929
|
+
graphSummary: proposedGraphPreview.graphSummary,
|
|
930
|
+
effectiveStack: proposedGraphPreview.effectiveStack,
|
|
931
|
+
stackPartSpecs: proposedGraphPreview.stackPartSpecs
|
|
1100
932
|
},
|
|
1101
933
|
alreadyPresent: (addons ?? []).filter((a) => existingAddons.has(a)),
|
|
1102
934
|
...compatibilityWarnings ? { compatibilityWarnings } : {}
|
|
@@ -1132,6 +964,7 @@ async function startMcpServer() {
|
|
|
1132
964
|
});
|
|
1133
965
|
if (result?.success) {
|
|
1134
966
|
const existingConfig = await readBtsConfig(safePath);
|
|
967
|
+
const graphPreview = existingConfig ? getMcpGraphPreview(existingConfig) : void 0;
|
|
1135
968
|
const installCmd = getInstallCommand(existingConfig?.ecosystem ?? "typescript", safePath.split("/").pop() ?? "project", input.packageManager, existingConfig?.javaBuildTool, existingConfig?.javaWebFramework);
|
|
1136
969
|
return { content: [{
|
|
1137
970
|
type: "text",
|
|
@@ -1139,6 +972,7 @@ async function startMcpServer() {
|
|
|
1139
972
|
success: true,
|
|
1140
973
|
addedAddons: result.addedAddons,
|
|
1141
974
|
projectDir: result.projectDir,
|
|
975
|
+
...graphPreview,
|
|
1142
976
|
message: `Added ${result.addedAddons.join(", ")} to project. Tell the user to run: ${installCmd}`
|
|
1143
977
|
}, null, 2)
|
|
1144
978
|
}] };
|
|
@@ -1193,4 +1027,4 @@ async function startMcpServer() {
|
|
|
1193
1027
|
startMcpServer();
|
|
1194
1028
|
|
|
1195
1029
|
//#endregion
|
|
1196
|
-
export { startMcpServer as t };
|
|
1030
|
+
export { startMcpServer as n, getMcpGraphPreview as t };
|