@agiflowai/scaffold-mcp 1.0.0 → 1.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/cli.js CHANGED
@@ -1,22 +1,19 @@
1
1
  #!/usr/bin/env node
2
- import { BoilerplateService, FileSystemService, GenerateBoilerplateFileTool, GenerateBoilerplateTool, GenerateFeatureScaffoldTool, HttpTransportHandler, ListBoilerplatesTool, ListScaffoldingMethodsTool, ScaffoldingMethodsService, SseTransportHandler, StdioTransportHandler, UseBoilerplateTool, UseScaffoldMethodTool, WriteToFileTool, cloneRepository, cloneSubdirectory, fetchGitHubDirectoryContents, findWorkspaceRoot, parseGitHubUrl } from "./stdio-Dmpwju2k.js";
2
+ import { BoilerplateService, FileSystemService, GenerateBoilerplateFileTool, GenerateBoilerplateTool, GenerateFeatureScaffoldTool, HttpTransportHandler, ListBoilerplatesTool, ListScaffoldingMethodsTool, ScaffoldingMethodsService, SseTransportHandler, StdioTransportHandler, UseBoilerplateTool, UseScaffoldMethodTool, WriteToFileTool } from "./stdio-Bxn4A1IU.js";
3
3
  import "./ScaffoldConfigLoader-CI0T6zdG.js";
4
- import "./ScaffoldService-QgQKHMM-.js";
5
- import "./TemplateService-CiZJA06s.js";
6
- import "./VariableReplacementService-B3qARIC9.js";
4
+ import "./ScaffoldService-DB7-Cyod.js";
5
+ import { TemplateService } from "./TemplateService-CiZJA06s.js";
6
+ import "./VariableReplacementService-DRxd9ILB.js";
7
7
  import { Command } from "commander";
8
+ import { ProjectConfigResolver, TemplatesManagerService, icons, messages, print, sections } from "@agiflowai/aicode-utils";
8
9
  import path from "node:path";
9
- import { ProjectConfigResolver, ProjectType, TemplatesManagerService, icons, messages, print, sections } from "@agiflowai/aicode-utils";
10
- import * as fs$1 from "fs-extra";
11
- import { execa } from "execa";
12
- import { confirm, input, select } from "@inquirer/prompts";
13
10
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
14
11
  import { CallToolRequestSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
15
12
 
16
13
  //#region package.json
17
14
  var name = "@agiflowai/scaffold-mcp";
18
15
  var description = "MCP server for scaffolding applications with boilerplate templates";
19
- var version = "0.6.0";
16
+ var version = "1.0.1";
20
17
  var license = "AGPL-3.0";
21
18
  var author = "AgiflowIO";
22
19
  var repository = {
@@ -70,7 +67,8 @@ var devDependencies = {
70
67
  "@types/js-yaml": "^4.0.9",
71
68
  "@types/node": "^22.0.0",
72
69
  "tsdown": "^0.15.6",
73
- "typescript": "5.9.3"
70
+ "typescript": "5.9.3",
71
+ "unplugin-raw": "^0.6.3"
74
72
  };
75
73
  var publishConfig = { "access": "public" };
76
74
  var type = "module";
@@ -108,63 +106,6 @@ var package_default = {
108
106
  exports
109
107
  };
110
108
 
111
- //#endregion
112
- //#region src/commands/add.ts
113
- /**
114
- * Add command - add a template to templates folder
115
- */
116
- const addCommand = new Command("add").description("Add a template to templates folder").requiredOption("--name <name>", "Template name").requiredOption("--url <url>", "URL of the template repository to download").option("--path <path>", "Override templates folder path (uses toolkit.yaml config by default)").option("--type <type>", "Template type: boilerplate or scaffold", "boilerplate").action(async (options) => {
117
- try {
118
- const templatesPath = options.path ? path.resolve(options.path) : await TemplatesManagerService.findTemplatesPath();
119
- const templateType = options.type.toLowerCase();
120
- const templateName = options.name;
121
- const templateUrl = options.url;
122
- if (templateType !== "boilerplate" && templateType !== "scaffold") {
123
- messages.error("Invalid template type. Use: boilerplate or scaffold");
124
- process.exit(1);
125
- }
126
- const targetFolder = path.join(templatesPath, `${templateType}s`, templateName);
127
- if (await fs$1.pathExists(targetFolder)) {
128
- messages.error(`Template '${templateName}' already exists at ${targetFolder}`);
129
- process.exit(1);
130
- }
131
- print.info(`${icons.download} Downloading template '${templateName}' from ${templateUrl}...`);
132
- await fs$1.ensureDir(path.dirname(targetFolder));
133
- const parsedUrl = parseGitHubUrl(templateUrl);
134
- try {
135
- if (parsedUrl.isSubdirectory && parsedUrl.branch && parsedUrl.subdirectory) {
136
- print.info(`${icons.folder} Detected subdirectory: ${parsedUrl.subdirectory} (branch: ${parsedUrl.branch})`);
137
- await cloneSubdirectory(parsedUrl.repoUrl, parsedUrl.branch, parsedUrl.subdirectory, targetFolder);
138
- } else await cloneRepository(parsedUrl.repoUrl, targetFolder);
139
- messages.success(`Template '${templateName}' added successfully!`);
140
- print.header(`\n${icons.folder} Template location:`);
141
- print.indent(targetFolder);
142
- const configFiles = [path.join(targetFolder, "boilerplate.yaml"), path.join(targetFolder, "scaffold.yaml")];
143
- let hasConfig = false;
144
- for (const configFile of configFiles) if (await fs$1.pathExists(configFile)) {
145
- print.header(`\n${icons.config} Configuration file found:`);
146
- print.indent(path.basename(configFile));
147
- hasConfig = true;
148
- break;
149
- }
150
- if (!hasConfig) {
151
- messages.warning("Warning: No configuration file found (boilerplate.yaml or scaffold.yaml)");
152
- print.indent("You may need to create one manually.");
153
- }
154
- sections.nextSteps([`Review the template in ${targetFolder}`, `Test it with: scaffold-mcp ${templateType} list`]);
155
- } catch (error) {
156
- if (error.message.includes("not found") || error.message.includes("command not found")) messages.error("git command not found. Please install git first.");
157
- else if (error.message.includes("Authentication failed")) messages.error("Authentication failed. Make sure you have access to the repository.");
158
- else if (error.message.includes("Repository not found")) messages.error("Repository not found. Check the URL and try again.");
159
- else messages.error("Failed to clone repository:", error);
160
- process.exit(1);
161
- }
162
- } catch (error) {
163
- messages.error("Error adding template:", error);
164
- process.exit(1);
165
- }
166
- });
167
-
168
109
  //#endregion
169
110
  //#region src/commands/boilerplate.ts
170
111
  /**
@@ -279,262 +220,12 @@ boilerplateCommand.command("info <boilerplateName>").description("Show detailed
279
220
  });
280
221
 
281
222
  //#endregion
282
- //#region src/commands/init.ts
283
- /**
284
- * Execute git init safely using execa to prevent command injection
285
- */
286
- async function gitInit(projectPath) {
287
- try {
288
- await execa("git", ["init", projectPath]);
289
- } catch (error) {
290
- const execaError = error;
291
- throw new Error(`Git init failed: ${execaError.stderr || execaError.message}`);
292
- }
293
- }
294
- const DEFAULT_TEMPLATE_REPO = {
295
- owner: "AgiFlow",
296
- repo: "aicode-toolkit",
297
- branch: "main",
298
- path: "templates"
299
- };
300
- /**
301
- * Interactive setup for new projects
302
- * Prompts user for project details when no .git folder is found
303
- * @param providedName - Optional project name from CLI argument
304
- * @param providedProjectType - Optional project type from CLI argument
305
- */
306
- async function setupNewProject(providedName, providedProjectType) {
307
- print.header(`\n${icons.rocket} New Project Setup`);
308
- print.info("No Git repository detected. Let's set up a new project!\n");
309
- let projectName;
310
- const reservedNames = [
311
- ".",
312
- "..",
313
- "CON",
314
- "PRN",
315
- "AUX",
316
- "NUL",
317
- "COM1",
318
- "COM2",
319
- "COM3",
320
- "COM4",
321
- "COM5",
322
- "COM6",
323
- "COM7",
324
- "COM8",
325
- "COM9",
326
- "LPT1",
327
- "LPT2",
328
- "LPT3",
329
- "LPT4",
330
- "LPT5",
331
- "LPT6",
332
- "LPT7",
333
- "LPT8",
334
- "LPT9"
335
- ];
336
- const validateProjectName = (value) => {
337
- const trimmed = value.trim();
338
- if (!trimmed) return "Project name is required";
339
- if (!/^[a-zA-Z0-9]/.test(trimmed)) return "Project name must start with a letter or number";
340
- if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(trimmed)) return "Project name can only contain letters, numbers, hyphens, and underscores";
341
- if (reservedNames.includes(trimmed.toUpperCase())) return "Project name uses a reserved name";
342
- return true;
343
- };
344
- if (providedName) {
345
- const trimmedName = providedName.trim();
346
- const validationResult = validateProjectName(trimmedName);
347
- if (validationResult !== true) throw new Error(validationResult);
348
- projectName = trimmedName;
349
- print.info(`Project name: ${projectName}`);
350
- } else projectName = await input({
351
- message: "Enter your project name:",
352
- validate: validateProjectName
353
- });
354
- let projectType;
355
- if (providedProjectType) {
356
- if (providedProjectType !== ProjectType.MONOLITH && providedProjectType !== ProjectType.MONOREPO) throw new Error(`Invalid project type '${providedProjectType}'. Must be '${ProjectType.MONOLITH}' or '${ProjectType.MONOREPO}'`);
357
- projectType = providedProjectType;
358
- print.info(`Project type: ${projectType}`);
359
- } else projectType = await select({
360
- message: "Select project type:",
361
- choices: [{
362
- name: "Monolith - Single application structure",
363
- value: ProjectType.MONOLITH,
364
- description: "Traditional single-application project structure"
365
- }, {
366
- name: "Monorepo - Multiple packages/apps in one repository",
367
- value: ProjectType.MONOREPO,
368
- description: "Multiple packages managed together (uses workspaces)"
369
- }]
370
- });
371
- const hasExistingRepo = await confirm({
372
- message: "Do you have an existing Git repository you want to use?",
373
- default: false
374
- });
375
- const projectPath = path.join(process.cwd(), projectName.trim());
376
- try {
377
- await fs$1.mkdir(projectPath, { recursive: false });
378
- print.success(`${icons.check} Created project directory: ${projectPath}`);
379
- } catch (error) {
380
- if (error.code === "EEXIST") throw new Error(`Directory '${projectName}' already exists. Please choose a different name.`);
381
- throw error;
382
- }
383
- if (hasExistingRepo) {
384
- const repoUrl = await input({
385
- message: "Enter Git repository URL:",
386
- validate: (value) => {
387
- if (!value.trim()) return "Repository URL is required";
388
- if (!value.match(/^(https?:\/\/|git@)/)) return "Please enter a valid Git repository URL";
389
- return true;
390
- }
391
- });
392
- print.info(`${icons.download} Cloning repository...`);
393
- try {
394
- const parsed = parseGitHubUrl(repoUrl.trim());
395
- if (parsed.isSubdirectory && parsed.branch && parsed.subdirectory) await cloneSubdirectory(parsed.repoUrl, parsed.branch, parsed.subdirectory, projectPath);
396
- else await cloneRepository(parsed.repoUrl, projectPath);
397
- print.success(`${icons.check} Repository cloned successfully`);
398
- } catch (error) {
399
- await fs$1.remove(projectPath);
400
- throw new Error(`Failed to clone repository: ${error.message}`);
401
- }
402
- } else if (await confirm({
403
- message: "Initialize a new Git repository?",
404
- default: true
405
- })) {
406
- print.info(`${icons.rocket} Initializing Git repository...`);
407
- try {
408
- await gitInit(projectPath);
409
- print.success(`${icons.check} Git repository initialized`);
410
- } catch (error) {
411
- messages.warning(`Failed to initialize Git: ${error.message}`);
412
- }
413
- }
414
- return {
415
- projectPath,
416
- projectType
417
- };
418
- }
419
- /**
420
- * Download templates from GitHub repository
421
- */
422
- async function downloadTemplates(templatesPath) {
423
- try {
424
- print.info(`${icons.download} Fetching templates from ${DEFAULT_TEMPLATE_REPO.owner}/${DEFAULT_TEMPLATE_REPO.repo}...`);
425
- const templateDirs = (await fetchGitHubDirectoryContents(DEFAULT_TEMPLATE_REPO.owner, DEFAULT_TEMPLATE_REPO.repo, DEFAULT_TEMPLATE_REPO.path, DEFAULT_TEMPLATE_REPO.branch)).filter((item) => item.type === "dir");
426
- if (templateDirs.length === 0) {
427
- messages.warning("No templates found in repository");
428
- return;
429
- }
430
- print.info(`${icons.folder} Found ${templateDirs.length} template(s)`);
431
- for (const template of templateDirs) {
432
- const targetFolder = path.join(templatesPath, template.name);
433
- if (await fs$1.pathExists(targetFolder)) {
434
- print.info(`${icons.skip} Skipping ${template.name} (already exists)`);
435
- continue;
436
- }
437
- print.info(`${icons.download} Downloading ${template.name}...`);
438
- await cloneSubdirectory(`https://github.com/${DEFAULT_TEMPLATE_REPO.owner}/${DEFAULT_TEMPLATE_REPO.repo}.git`, DEFAULT_TEMPLATE_REPO.branch, template.path, targetFolder);
439
- print.success(`${icons.check} Downloaded ${template.name}`);
440
- }
441
- print.success(`\n${icons.check} All templates downloaded successfully!`);
442
- } catch (error) {
443
- throw new Error(`Failed to download templates: ${error.message}`);
444
- }
445
- }
446
- /**
447
- * Init command - initialize templates folder
448
- */
449
- const initCommand = new Command("init").description("Initialize templates folder structure at workspace root or create new project").option("--no-download", "Skip downloading templates from repository").option("--path <path>", "Custom path for templates folder (relative to workspace root)").option("--name <name>", "Project name (for new projects)").option("--project-type <type>", "Project type: monolith or monorepo (for new projects)").action(async (options) => {
450
- try {
451
- let workspaceRoot = await findWorkspaceRoot();
452
- let projectType;
453
- if (!workspaceRoot) {
454
- const projectSetup = await setupNewProject(options.name, options.projectType);
455
- workspaceRoot = projectSetup.projectPath;
456
- projectType = projectSetup.projectType;
457
- print.info(`\n${icons.folder} Project type: ${projectType}`);
458
- }
459
- let templatesPath = options.path ? path.join(workspaceRoot, options.path) : path.join(workspaceRoot, "templates");
460
- if (await fs$1.pathExists(templatesPath)) {
461
- messages.warning(`\n⚠️ Templates folder already exists at: ${templatesPath}`);
462
- if (await confirm({
463
- message: "Do you want to use a different folder for templates?",
464
- default: false
465
- })) {
466
- const alternateFolder = await input({
467
- message: "Enter alternate folder name for templates:",
468
- default: "my-templates",
469
- validate: (value) => {
470
- if (!value.trim()) return "Folder name is required";
471
- if (!/^[a-zA-Z0-9_\-/]+$/.test(value)) return "Folder name can only contain letters, numbers, hyphens, underscores, and slashes";
472
- return true;
473
- }
474
- });
475
- templatesPath = path.join(workspaceRoot, alternateFolder.trim());
476
- const toolkitConfig = {
477
- templatesPath: alternateFolder.trim(),
478
- projectType
479
- };
480
- print.info(`\n${icons.config} Creating toolkit.yaml with custom templates path...`);
481
- await TemplatesManagerService.writeToolkitConfig(toolkitConfig, workspaceRoot);
482
- print.success(`${icons.check} toolkit.yaml created`);
483
- } else print.info(`\n${icons.info} Using existing templates folder`);
484
- }
485
- print.info(`\n${icons.rocket} Initializing templates folder at: ${templatesPath}`);
486
- await fs$1.ensureDir(templatesPath);
487
- await fs$1.writeFile(path.join(templatesPath, "README.md"), `# Templates
488
-
489
- This folder contains boilerplate templates and scaffolding methods for your projects.
490
-
491
- ## Templates
492
-
493
- Templates are organized by framework/technology and include configuration files (\`scaffold.yaml\`) that define:
494
- - Boilerplates: Full project starter templates
495
- - Features: Code scaffolding methods for adding new features to existing projects
496
-
497
- ## Adding More Templates
223
+ //#region src/instructions/server.md?raw
224
+ var server_default = "Use this MCP server to {% if isMonolith %}create your monolith project and add features (pages, components, services, etc.){% else %}create new projects and add features (pages, components, services, etc.){% endif %}.\n\n## Workflow:\n{% if not isMonolith %}\n1. **Creating New Project**: Use `list-boilerplates` → `use-boilerplate`\n2. **Adding Features**: Use `list-scaffolding-methods` → `use-scaffold-method`\n{% else %}\n1. **Creating Project**: Use `use-boilerplate` (boilerplateName auto-detected from toolkit.yaml)\n2. **Adding Features**: Use `list-scaffolding-methods` → `use-scaffold-method`\n{% endif %}\n\n## AI Usage Guidelines:\n{% if not isMonolith %}\n- Always call `list-boilerplates` first when creating new projects to see available options\n{% endif %}\n- Always call `list-scaffolding-methods` first when adding features to understand what's available\n- Follow the exact variable schema provided - validation will fail if required fields are missing\n{% if not isMonolith %}\n- Use kebab-case for project names (e.g., \"my-new-app\")\n{% else %}\n- In monolith mode, parameters like `boilerplateName` and `templateName` are auto-detected from toolkit.yaml\n- You only need to provide `variables` when calling `use-boilerplate` or `use-scaffold-method`\n{% endif %}\n- The tools automatically handle file placement, imports, and code generation\n- Check the returned JSON schemas to understand required vs optional variables\n{% if adminEnabled %}\n\n## Admin Mode (Template Generation):\n\nWhen creating custom boilerplate templates for frameworks not yet supported:\n\n1. **Create Boilerplate Configuration**: Use `generate-boilerplate` to add a new boilerplate entry to a template's scaffold.yaml\n - Specify template name, boilerplate name, description, target folder, and variable schema\n - This creates the scaffold.yaml structure following the nextjs-15 pattern\n - Optional: Add detailed instruction about file purposes and design patterns\n\n2. **Create Feature Configuration**: Use `generate-feature-scaffold` to add a new feature entry to a template's scaffold.yaml\n - Specify template name, feature name, generator, description, and variable schema\n - This creates the scaffold.yaml structure for feature scaffolds (pages, components, etc.)\n - Optional: Add detailed instruction about file purposes and design patterns\n - Optional: Specify patterns to match existing files this feature works with\n\n3. **Create Template Files**: Use `generate-boilerplate-file` to create the actual template files\n - Create files referenced in the boilerplate's or feature's includes array\n - Use {{ variableName }} syntax for Liquid variable placeholders\n - Can copy from existing source files or provide content directly\n - Files automatically get .liquid extension\n\n4. **Test the Template**: Use `list-boilerplates`/`list-scaffolding-methods` and `use-boilerplate`/`use-scaffold-method` to verify your template works\n\nExample workflow for boilerplate:\n```\n1. generate-boilerplate { templateName: \"react-vite\", boilerplateName: \"scaffold-vite-app\", ... }\n2. generate-boilerplate-file { templateName: \"react-vite\", filePath: \"package.json\", content: \"...\" }\n3. generate-boilerplate-file { templateName: \"react-vite\", filePath: \"src/App.tsx\", content: \"...\" }\n4. list-boilerplates (verify it appears)\n5. use-boilerplate { boilerplateName: \"scaffold-vite-app\", variables: {...} }\n```\n\nExample workflow for feature:\n```\n1. generate-feature-scaffold { templateName: \"nextjs-15\", featureName: \"scaffold-nextjs-component\", generator: \"componentGenerator.ts\", ... }\n2. generate-boilerplate-file { templateName: \"nextjs-15\", filePath: \"src/components/Component.tsx\", content: \"...\" }\n3. list-scaffolding-methods (verify it appears)\n4. use-scaffold-method { scaffoldName: \"scaffold-nextjs-component\", variables: {...} }\n```\n{% endif %}\n";
498
225
 
499
- Use the \`aicode-toolkit\` CLI to add templates from remote repositories:
500
-
501
- \`\`\`bash
502
- npx @agiflowai/aicode-toolkit add --name my-template --url https://github.com/user/template
503
- \`\`\`
504
-
505
- Or add templates from subdirectories:
506
-
507
- \`\`\`bash
508
- npx @agiflowai/aicode-toolkit add --name nextjs-template --url https://github.com/user/repo/tree/main/templates/nextjs
509
- \`\`\`
510
-
511
- ## Creating Custom Templates
512
-
513
- Each template should have a \`scaffold.yaml\` configuration file defining:
514
- - \`boilerplate\`: Array of boilerplate configurations
515
- - \`features\`: Array of feature scaffold configurations
516
-
517
- Template files use Liquid syntax for variable placeholders: \`{{ variableName }}\`
518
-
519
- See existing templates for examples and documentation for more details.
520
- `);
521
- print.success(`${icons.check} Templates folder created!`);
522
- if (options.download !== false) await downloadTemplates(templatesPath);
523
- else print.info(`${icons.skip} Skipping template download (use --download to enable)`);
524
- print.header(`\n${icons.folder} Templates location:`);
525
- print.indent(templatesPath);
526
- const nextSteps = [];
527
- if (options.download === false) nextSteps.push(`Add templates: npx @agiflowai/aicode-toolkit add --name <name> --url <url>`);
528
- else {
529
- nextSteps.push(`List available boilerplates: scaffold-mcp boilerplate list`);
530
- nextSteps.push(`Add more templates: npx @agiflowai/aicode-toolkit add --name <name> --url <url>`);
531
- }
532
- sections.nextSteps(nextSteps);
533
- } catch (error) {
534
- messages.error(`Error initializing templates folder: ${error.message}`);
535
- process.exit(1);
536
- }
537
- });
226
+ //#endregion
227
+ //#region src/instructions/prompts/generate-boilerplate.md?raw
228
+ var generate_boilerplate_default = "You are helping create a new boilerplate template configuration using the scaffold-mcp MCP tools.\n\n{% if request %}User request: {{ request }}\n{% endif %}\nYour task:\n\n1. **Gather Information**: Ask for any missing details:\n - Framework/technology (e.g., \"React Vite\", \"Express API\", \"Next.js 15\")\n - Template name (kebab-case, e.g., \"react-vite\", \"nextjs-15\")\n - Boilerplate name (prefixed with \"scaffold-\", e.g., \"scaffold-vite-app\")\n {% if not isMonolith %}- Target folder (e.g., \"apps\", \"packages\"){% else %}- Target folder (defaults to \".\" for monolith mode){% endif %}\n - Project type (app, library, service, etc.)\n - Required variables (at minimum: appName or packageName)\n - Files to include in the template\n\n2. **Use MCP Tools** in order:\n - `generate-boilerplate` - Creates the boilerplate configuration\n - `generate-boilerplate-file` - Creates each template file\n {% if not isMonolith %}- `list-boilerplates` - Verify it appears{% endif %}\n - `use-boilerplate` - Test the boilerplate\n\nImportant:\n- Template naming: Use kebab-case (e.g., \"react-vite\", \"express-api\")\n- Boilerplate naming: Prefix with \"scaffold-\" (e.g., \"scaffold-vite-app\")\n{% if not isMonolith %}- Target folder: \"apps\" for applications, \"packages\" for libraries{% else %}- Target folder: \".\" for monolith projects (creates files at workspace root){% endif %}\n- Include files explicitly - avoid wildcards\n- Template syntax: use {{ variableName }}\n\n**Description Field Guidelines (CRITICAL)**:\nThe description should be a comprehensive multi-paragraph overview (3-5 sentences):\n- Paragraph 1: Core technology stack and primary value proposition\n- Paragraph 2: Target use cases and ideal project types\n- Paragraph 3: Key integrations or special features (if applicable)\n\nExample:\n\"A modern React SPA template powered by Vite for lightning-fast HMR, featuring TanStack Router for type-safe routing and TanStack Query for server state management.\nPerfect for building data-driven dashboards, admin panels, and interactive web applications requiring client-side routing and real-time data synchronization.\n\nIncludes Agiflow Config Management System integration with systematic environment variable naming (VITE_{CATEGORY}_{SUBCATEGORY}_{PROPERTY}) and auto-generated configuration templates for cloud deployment.\"\n\n**Instruction Field Guidelines (CRITICAL)**:\nThe instruction should be a detailed multi-section guide that helps AI understand the codebase:\n\n1. **File purposes** section: List each major file/directory with its purpose\n Format: \"- path/to/file: Description of what this file does\"\n\n2. **How to use the scaffolded code** section: Step-by-step workflows\n Format: Numbered list with specific examples\n - How to add routes/pages\n - How to fetch data\n - How to handle authentication\n - How to configure environment variables\n\n3. **Design patterns to follow** section: Key architectural decisions\n Format: \"- Pattern Name: Explanation and when to use it\"\n - Routing patterns\n - State management patterns\n - Data fetching patterns\n - Error handling patterns\n - Performance optimization patterns\n\nExample structure:\n\"[Framework] application template with [key technologies].\n\nFile purposes:\n- package.json: NPM package configuration with [framework] and dependencies\n- src/main.tsx: Application entry point with [setup details]\n- src/routes/: Route definitions following [pattern]\n[... list all major files ...]\n\nHow to use the scaffolded code:\n1. Routes: Create new routes by [specific instructions with example]\n2. Data Fetching: Use [specific pattern] for [use case]\n3. Authentication: Use [specific components/modules] for user management\n[... numbered steps for common tasks ...]\n\nDesign patterns to follow:\n- File-based Routing: Use directory structure in src/routes/ to define URL paths\n- Type-safe Routes: Leverage [framework] type inference for params\n- State Management: Use [library] for server state, [library] for client state\n[... list key patterns with explanations ...]\"\n\nTemplate File Content Guidelines:\n- Keep content MINIMAL and business-agnostic\n- Focus on structure and patterns, not business logic\n- Use placeholder/generic examples only\n- Include essential boilerplate code only\n- Let AI fill in specific logic later\n- Add clear headers with design patterns and coding standards\n";
538
229
 
539
230
  //#endregion
540
231
  //#region src/prompts/GenerateBoilerplatePrompt.ts
@@ -543,6 +234,10 @@ See existing templates for examples and documentation for more details.
543
234
  */
544
235
  var GenerateBoilerplatePrompt = class GenerateBoilerplatePrompt {
545
236
  static PROMPT_NAME = "generate-boilerplate";
237
+ templateService = new TemplateService();
238
+ constructor(isMonolith = false) {
239
+ this.isMonolith = isMonolith;
240
+ }
546
241
  /**
547
242
  * Get the prompt definition for MCP
548
243
  */
@@ -561,104 +256,24 @@ var GenerateBoilerplatePrompt = class GenerateBoilerplatePrompt {
561
256
  * Get the prompt messages
562
257
  */
563
258
  getMessages(args) {
564
- const userRequest = args?.request || "";
259
+ const request = args?.request || "";
565
260
  return [{
566
261
  role: "user",
567
262
  content: {
568
263
  type: "text",
569
- text: `You are helping create a new boilerplate template configuration using the scaffold-mcp MCP tools.
570
-
571
- ${userRequest ? `User request: ${userRequest}\n` : ""}
572
- Your task:
573
-
574
- 1. **Gather Information**: Ask for any missing details:
575
- - Framework/technology (e.g., "React Vite", "Express API", "Next.js 15")
576
- - Template name (kebab-case, e.g., "react-vite", "nextjs-15")
577
- - Boilerplate name (prefixed with "scaffold-", e.g., "scaffold-vite-app")
578
- - Target folder (e.g., "apps", "packages")
579
- - Project type (app, library, service, etc.)
580
- - Required variables (at minimum: appName or packageName)
581
- - Files to include in the template
582
-
583
- 2. **Use MCP Tools** in order:
584
- - \`generate-boilerplate\` - Creates the boilerplate configuration
585
- - \`generate-boilerplate-file\` - Creates each template file
586
- - \`list-boilerplates\` - Verify it appears
587
- - \`use-boilerplate\` - Test the boilerplate
588
-
589
- Important:
590
- - Template naming: Use kebab-case (e.g., "react-vite", "express-api")
591
- - Boilerplate naming: Prefix with "scaffold-" (e.g., "scaffold-vite-app")
592
- - Target folder: "apps" for applications, "packages" for libraries
593
- - Include files explicitly - avoid wildcards
594
- - Template syntax: use {{ variableName }}
595
-
596
- **Description Field Guidelines (CRITICAL)**:
597
- The description should be a comprehensive multi-paragraph overview (3-5 sentences):
598
- - Paragraph 1: Core technology stack and primary value proposition
599
- - Paragraph 2: Target use cases and ideal project types
600
- - Paragraph 3: Key integrations or special features (if applicable)
601
-
602
- Example:
603
- "A modern React SPA template powered by Vite for lightning-fast HMR, featuring TanStack Router for type-safe routing and TanStack Query for server state management.
604
- Perfect for building data-driven dashboards, admin panels, and interactive web applications requiring client-side routing and real-time data synchronization.
605
-
606
- Includes Agiflow Config Management System integration with systematic environment variable naming (VITE_{CATEGORY}_{SUBCATEGORY}_{PROPERTY}) and auto-generated configuration templates for cloud deployment."
607
-
608
- **Instruction Field Guidelines (CRITICAL)**:
609
- The instruction should be a detailed multi-section guide that helps AI understand the codebase:
610
-
611
- 1. **File purposes** section: List each major file/directory with its purpose
612
- Format: "- path/to/file: Description of what this file does"
613
-
614
- 2. **How to use the scaffolded code** section: Step-by-step workflows
615
- Format: Numbered list with specific examples
616
- - How to add routes/pages
617
- - How to fetch data
618
- - How to handle authentication
619
- - How to configure environment variables
620
-
621
- 3. **Design patterns to follow** section: Key architectural decisions
622
- Format: "- Pattern Name: Explanation and when to use it"
623
- - Routing patterns
624
- - State management patterns
625
- - Data fetching patterns
626
- - Error handling patterns
627
- - Performance optimization patterns
628
-
629
- Example structure:
630
- "[Framework] application template with [key technologies].
631
-
632
- File purposes:
633
- - package.json: NPM package configuration with [framework] and dependencies
634
- - src/main.tsx: Application entry point with [setup details]
635
- - src/routes/: Route definitions following [pattern]
636
- [... list all major files ...]
637
-
638
- How to use the scaffolded code:
639
- 1. Routes: Create new routes by [specific instructions with example]
640
- 2. Data Fetching: Use [specific pattern] for [use case]
641
- 3. Authentication: Use [specific components/modules] for user management
642
- [... numbered steps for common tasks ...]
643
-
644
- Design patterns to follow:
645
- - File-based Routing: Use directory structure in src/routes/ to define URL paths
646
- - Type-safe Routes: Leverage [framework] type inference for params
647
- - State Management: Use [library] for server state, [library] for client state
648
- [... list key patterns with explanations ...]"
649
-
650
- Template File Content Guidelines:
651
- - Keep content MINIMAL and business-agnostic
652
- - Focus on structure and patterns, not business logic
653
- - Use placeholder/generic examples only
654
- - Include essential boilerplate code only
655
- - Let AI fill in specific logic later
656
- - Add clear headers with design patterns and coding standards`
264
+ text: this.templateService.renderString(generate_boilerplate_default, {
265
+ request,
266
+ isMonolith: this.isMonolith
267
+ })
657
268
  }
658
269
  }];
659
270
  }
660
271
  };
661
272
 
273
+ //#endregion
274
+ //#region src/instructions/prompts/generate-feature-scaffold.md?raw
275
+ var generate_feature_scaffold_default = "You are helping create a new feature scaffold configuration using the scaffold-mcp MCP tools.\n\n{% if request %}User request: {{ request }}\n{% endif %}\nYour task:\n\n1. **Gather Information**: Ask for any missing details:\n {% if not isMonolith %}- Template name (e.g., \"nextjs-15\", \"react-vite\"){% else %}- Template name (will be auto-detected from toolkit.yaml){% endif %}\n - Feature name (prefixed with \"scaffold-\", e.g., \"scaffold-nextjs-page\")\n - Feature type (page, component, service, etc.)\n - Variables needed\n - Files to include\n\n2. **Use MCP Tools** in order:\n - `generate-feature-scaffold` - Creates the feature configuration\n - `generate-boilerplate-file` - Creates each template file\n - `list-scaffolding-methods` - Verify it appears\n - `use-scaffold-method` - Test the feature\n\nImportant:\n- Feature names: prefix with \"scaffold-\"\n- Conditional includes: use \"file.tsx?withLayout=true\"\n- Template syntax: use {{ variableName }}\n{% if isMonolith %}- Template name will be auto-detected from toolkit.yaml{% endif %}\n\n**Description Field Guidelines (CRITICAL)**:\nThe description should explain what the feature scaffold generates (2-3 sentences):\n- Sentence 1: What type of code it generates (component, page, service, etc.)\n- Sentence 2: Key features or capabilities included\n- Sentence 3: Primary use cases or when to use it\n\nExample:\n\"Generate a new service class for TypeScript libraries following best practices. Creates a service class with interface, implementation, and unit tests. Perfect for creating reusable service modules with dependency injection patterns.\"\n\n**Instruction Field Guidelines (CRITICAL)**:\nThe instruction should provide specific guidance for using the generated feature:\n\n1. **Pattern explanation**: Describe the architectural pattern used\n2. **File organization**: Where files should be placed\n3. **Naming conventions**: How to name things (PascalCase, camelCase, etc.)\n4. **Usage guidelines**: How to use the generated code\n5. **Testing approach**: How to test the feature\n\nExample structure:\n\"[Feature type] follow a [pattern name] pattern with [key characteristics].\n[Explanation of how it works and integrates with the project].\nPlace [files] in [directory].\nFor [features with X], define [Y] in [Z] for better separation of concerns.\n[Feature names] should be [case style] and [suffix/prefix rules].\nWrite comprehensive [tests/docs] for all [public methods/exports].\"\n\nKeep it concise but informative - focus on the patterns and conventions that AI needs to understand to work with the generated code effectively.\n\nTemplate File Content Guidelines:\n- Keep content MINIMAL and business-agnostic\n- Focus on structure and patterns, not business logic\n- Use placeholder/generic examples only\n- Include essential boilerplate code only\n- Let AI fill in specific logic later\n- Add clear headers with design patterns and coding standards\n";
276
+
662
277
  //#endregion
663
278
  //#region src/prompts/GenerateFeatureScaffoldPrompt.ts
664
279
  /**
@@ -666,6 +281,10 @@ Template File Content Guidelines:
666
281
  */
667
282
  var GenerateFeatureScaffoldPrompt = class GenerateFeatureScaffoldPrompt {
668
283
  static PROMPT_NAME = "generate-feature-scaffold";
284
+ templateService = new TemplateService();
285
+ constructor(isMonolith = false) {
286
+ this.isMonolith = isMonolith;
287
+ }
669
288
  /**
670
289
  * Get the prompt definition for MCP
671
290
  */
@@ -684,74 +303,24 @@ var GenerateFeatureScaffoldPrompt = class GenerateFeatureScaffoldPrompt {
684
303
  * Get the prompt messages
685
304
  */
686
305
  getMessages(args) {
687
- const userRequest = args?.request || "";
306
+ const request = args?.request || "";
688
307
  return [{
689
308
  role: "user",
690
309
  content: {
691
310
  type: "text",
692
- text: `You are helping create a new feature scaffold configuration using the scaffold-mcp MCP tools.
693
-
694
- ${userRequest ? `User request: ${userRequest}\n` : ""}
695
- Your task:
696
-
697
- 1. **Gather Information**: Ask for any missing details:
698
- - Template name (e.g., "nextjs-15", "react-vite")
699
- - Feature name (prefixed with "scaffold-", e.g., "scaffold-nextjs-page")
700
- - Feature type (page, component, service, etc.)
701
- - Variables needed
702
- - Files to include
703
-
704
- 2. **Use MCP Tools** in order:
705
- - \`generate-feature-scaffold\` - Creates the feature configuration
706
- - \`generate-boilerplate-file\` - Creates each template file
707
- - \`list-scaffolding-methods\` - Verify it appears
708
- - \`use-scaffold-method\` - Test the feature
709
-
710
- Important:
711
- - Feature names: prefix with "scaffold-"
712
- - Conditional includes: use "file.tsx?withLayout=true"
713
- - Template syntax: use {{ variableName }}
714
-
715
- **Description Field Guidelines (CRITICAL)**:
716
- The description should explain what the feature scaffold generates (2-3 sentences):
717
- - Sentence 1: What type of code it generates (component, page, service, etc.)
718
- - Sentence 2: Key features or capabilities included
719
- - Sentence 3: Primary use cases or when to use it
720
-
721
- Example:
722
- "Generate a new service class for TypeScript libraries following best practices. Creates a service class with interface, implementation, and unit tests. Perfect for creating reusable service modules with dependency injection patterns."
723
-
724
- **Instruction Field Guidelines (CRITICAL)**:
725
- The instruction should provide specific guidance for using the generated feature:
726
-
727
- 1. **Pattern explanation**: Describe the architectural pattern used
728
- 2. **File organization**: Where files should be placed
729
- 3. **Naming conventions**: How to name things (PascalCase, camelCase, etc.)
730
- 4. **Usage guidelines**: How to use the generated code
731
- 5. **Testing approach**: How to test the feature
732
-
733
- Example structure:
734
- "[Feature type] follow a [pattern name] pattern with [key characteristics].
735
- [Explanation of how it works and integrates with the project].
736
- Place [files] in [directory].
737
- For [features with X], define [Y] in [Z] for better separation of concerns.
738
- [Feature names] should be [case style] and [suffix/prefix rules].
739
- Write comprehensive [tests/docs] for all [public methods/exports]."
740
-
741
- Keep it concise but informative - focus on the patterns and conventions that AI needs to understand to work with the generated code effectively.
742
-
743
- Template File Content Guidelines:
744
- - Keep content MINIMAL and business-agnostic
745
- - Focus on structure and patterns, not business logic
746
- - Use placeholder/generic examples only
747
- - Include essential boilerplate code only
748
- - Let AI fill in specific logic later
749
- - Add clear headers with design patterns and coding standards`
311
+ text: this.templateService.renderString(generate_feature_scaffold_default, {
312
+ request,
313
+ isMonolith: this.isMonolith
314
+ })
750
315
  }
751
316
  }];
752
317
  }
753
318
  };
754
319
 
320
+ //#endregion
321
+ //#region src/instructions/prompts/scaffold-application.md?raw
322
+ var scaffold_application_default = "You are helping create a new {% if isMonolith %}monolith application{% else %}application{% endif %} using the scaffold-mcp MCP tools.\n\n{% if request %}User request: {{ request }}\n{% endif %}\nYour task is to scaffold a new application by following this workflow:\n\n## Step 1: {% if isMonolith %}Prepare to Create Application{% else %}List Available Boilerplates{% endif %}\n{% if isMonolith %}You will use the `use-boilerplate` tool to create your monolith application. The boilerplate name will be auto-detected from your toolkit.yaml file.{% else %}Use the `list-boilerplates` tool to see all available project templates.\n\n**What to look for:**\n- Boilerplate name (e.g., \"scaffold-nextjs-app\", \"scaffold-vite-app\")\n- Description of what the boilerplate creates\n- Target folder where projects will be created (e.g., \"apps\", \"packages\")\n- Required and optional variables in the variables_schema{% endif %}\n\n## Step 2: Gather Required Information\nBased on the {% if isMonolith %}toolkit.yaml{% else %}selected boilerplate's variables_schema{% endif %}, collect:\n{% if not isMonolith %}- **Project name**: Must be kebab-case (e.g., \"my-new-app\", not \"MyNewApp\")\n{% endif %}- **Required variables**: All variables marked as required: true\n- **Optional variables**: Variables with required: false (ask user if needed)\n\nCommon variables:\n- `appName` or `packageName`: The project name (kebab-case)\n- `description`: Brief description of what the project does\n- `author`: Author name\n\n## Step 3: Execute the Boilerplate\nUse the `use-boilerplate` tool with:\n{% if not isMonolith %}- `boilerplateName`: Exact name from list-boilerplates response\n{% endif %}- `variables`: Object matching the variables_schema exactly\n\n**Example:**\n```json\n{\n{% if not isMonolith %} \"boilerplateName\": \"scaffold-nextjs-app\",\n{% endif %} \"variables\": {\n \"appName\": \"my-dashboard\",\n \"description\": \"Admin dashboard for managing users\",\n \"author\": \"John Doe\"\n }\n}\n```\n\n## Important Guidelines:\n{% if not isMonolith %}- **Always call `list-boilerplates` first** to see available options and their schemas{% else %}- The boilerplate name is auto-detected from toolkit.yaml{% endif %}\n- **Use exact variable names** from the schema (case-sensitive)\n- **Provide all required variables** - the tool will fail if any are missing\n{% if not isMonolith %}- **Use kebab-case for project names** (e.g., \"user-dashboard\", not \"UserDashboard\")\n- The tool will create the project in the appropriate directory automatically{% else %}- The tool will create files at the workspace root{% endif %}\n- After creation, inform the user {% if isMonolith %}what files were created{% else %}where the project was created{% endif %}\n\n## Step 4: Review and Add Features (If Needed)\nAfter the boilerplate is created, **consider if additional features are needed**:\n1. **READ** the generated {% if isMonolith %}application{% else %}project{% endif %} structure to understand what was created\n2. **REVIEW** the user's request to see if they asked for specific features (e.g., \"with tool for X\", \"with prompt for Y\")\n3. **If features are needed**:\n - Use `list-scaffolding-methods`{% if not isMonolith %} with the new project path{% endif %}\n - Use `use-scaffold-method` to add tools, services, prompts, etc.\n - **IMPLEMENT** the actual logic in the scaffolded feature files\n - **REGISTER** the features in `src/server/index.ts`\n4. **Install dependencies**: Remind user to run `pnpm install`\n5. **Report** the complete setup including any features added\n\n## Example Workflow:\n{% if not isMonolith %}1. Call `list-boilerplates` → See available templates\n2. Ask user which template to use (or infer from request)\n3. Collect required variables based on schema\n4. Call `use-boilerplate` with boilerplateName and variables{% else %}1. Collect required variables based on toolkit.yaml variables_schema\n2. Call `use-boilerplate` with variables (boilerplateName auto-detected){% endif %}\n5. **Review if user requested specific features (tools, prompts, etc.)**\n6. **If features needed**: Add them using `list-scaffolding-methods` and `use-scaffold-method`\n7. **READ and IMPLEMENT** the scaffolded feature files with actual logic\n8. Report success and next steps to the user\n";
323
+
755
324
  //#endregion
756
325
  //#region src/prompts/ScaffoldApplicationPrompt.ts
757
326
  /**
@@ -759,6 +328,10 @@ Template File Content Guidelines:
759
328
  */
760
329
  var ScaffoldApplicationPrompt = class ScaffoldApplicationPrompt {
761
330
  static PROMPT_NAME = "scaffold-application";
331
+ templateService = new TemplateService();
332
+ constructor(isMonolith = false) {
333
+ this.isMonolith = isMonolith;
334
+ }
762
335
  /**
763
336
  * Get the prompt definition for MCP
764
337
  */
@@ -777,87 +350,24 @@ var ScaffoldApplicationPrompt = class ScaffoldApplicationPrompt {
777
350
  * Get the prompt messages
778
351
  */
779
352
  getMessages(args) {
780
- const userRequest = args?.request || "";
353
+ const request = args?.request || "";
781
354
  return [{
782
355
  role: "user",
783
356
  content: {
784
357
  type: "text",
785
- text: `You are helping create a new application using the scaffold-mcp MCP tools.
786
-
787
- ${userRequest ? `User request: ${userRequest}\n` : ""}
788
- Your task is to scaffold a new application by following this workflow:
789
-
790
- ## Step 1: List Available Boilerplates
791
- Use the \`list-boilerplates\` tool to see all available project templates.
792
-
793
- **What to look for:**
794
- - Boilerplate name (e.g., "scaffold-nextjs-app", "scaffold-vite-app")
795
- - Description of what the boilerplate creates
796
- - Target folder where projects will be created (e.g., "apps", "packages")
797
- - Required and optional variables in the variables_schema
798
-
799
- ## Step 2: Gather Required Information
800
- Based on the selected boilerplate's variables_schema, collect:
801
- - **Project name**: Must be kebab-case (e.g., "my-new-app", not "MyNewApp")
802
- - **Required variables**: All variables marked as required: true
803
- - **Optional variables**: Variables with required: false (ask user if needed)
804
-
805
- Common variables:
806
- - \`appName\` or \`packageName\`: The project name (kebab-case)
807
- - \`description\`: Brief description of what the project does
808
- - \`author\`: Author name
809
-
810
- ## Step 3: Execute the Boilerplate
811
- Use the \`use-boilerplate\` tool with:
812
- - \`boilerplateName\`: Exact name from list-boilerplates response
813
- - \`variables\`: Object matching the variables_schema exactly
814
-
815
- **Example:**
816
- \`\`\`json
817
- {
818
- "boilerplateName": "scaffold-nextjs-app",
819
- "variables": {
820
- "appName": "my-dashboard",
821
- "description": "Admin dashboard for managing users",
822
- "author": "John Doe"
823
- }
824
- }
825
- \`\`\`
826
-
827
- ## Important Guidelines:
828
- - **Always call \`list-boilerplates\` first** to see available options and their schemas
829
- - **Use exact variable names** from the schema (case-sensitive)
830
- - **Provide all required variables** - the tool will fail if any are missing
831
- - **Use kebab-case for project names** (e.g., "user-dashboard", not "UserDashboard")
832
- - The tool will create the project in the appropriate directory automatically
833
- - After creation, inform the user where the project was created
834
-
835
- ## Step 4: Review and Add Features (If Needed)
836
- After the boilerplate is created, **consider if additional features are needed**:
837
- 1. **READ** the generated project structure to understand what was created
838
- 2. **REVIEW** the user's request to see if they asked for specific features (e.g., "with tool for X", "with prompt for Y")
839
- 3. **If features are needed**:
840
- - Use \`list-scaffolding-methods\` with the new project path
841
- - Use \`use-scaffold-method\` to add tools, services, prompts, etc.
842
- - **IMPLEMENT** the actual logic in the scaffolded feature files
843
- - **REGISTER** the features in \`src/server/index.ts\`
844
- 4. **Install dependencies**: Remind user to run \`pnpm install\`
845
- 5. **Report** the complete setup including any features added
846
-
847
- ## Example Workflow:
848
- 1. Call \`list-boilerplates\` → See available templates
849
- 2. Ask user which template to use (or infer from request)
850
- 3. Collect required variables based on schema
851
- 4. Call \`use-boilerplate\` with boilerplateName and variables
852
- 5. **Review if user requested specific features (tools, prompts, etc.)**
853
- 6. **If features needed**: Add them using \`list-scaffolding-methods\` and \`use-scaffold-method\`
854
- 7. **READ and IMPLEMENT** the scaffolded feature files with actual logic
855
- 8. Report success and next steps to the user`
358
+ text: this.templateService.renderString(scaffold_application_default, {
359
+ request,
360
+ isMonolith: this.isMonolith
361
+ })
856
362
  }
857
363
  }];
858
364
  }
859
365
  };
860
366
 
367
+ //#endregion
368
+ //#region src/instructions/prompts/scaffold-feature.md?raw
369
+ var scaffold_feature_default = "You are helping add a new feature to an existing project using the scaffold-mcp MCP tools.\n\n{% if request %}User request: {{ request }}\n{% endif %}{% if projectPath %}Project path: {{ projectPath }}\n{% endif %}\nYour task is to scaffold a new feature by following this workflow:\n\n## Step 1: Identify the Project\nDetermine the project path where the feature will be added:\n- If projectPath is provided, use it\n- Otherwise, ask the user or infer from context (e.g., \"apps/my-app\", \"packages/my-lib\")\n{% if isMonolith %}- In monolith mode, you can use the current working directory (no projectPath needed){% else %}- The path should point to a directory containing a `project.json` file{% endif %}\n\n## Step 2: List Available Scaffolding Methods\nUse the `list-scaffolding-methods` tool{% if not isMonolith %} with the projectPath{% endif %}.\n\n**What to look for:**\n- Feature name (e.g., \"scaffold-nextjs-page\", \"scaffold-react-component\")\n- Description of what files/code it generates\n- Required and optional variables in the variables_schema\n- The template type (derived from project's sourceTemplate)\n\n**Example:**\n```json\n{% if isMonolith %}{}{% else %}{\n \"projectPath\": \"apps/my-dashboard\"\n}{% endif %}\n```\n\n## Step 3: Gather Required Information\nBased on the selected scaffolding method's variables_schema, collect:\n- **Feature-specific variables**: Name, path, type, etc.\n- **Required variables**: All variables marked as required: true\n- **Optional variables**: Variables with required: false (ask user if needed)\n\nCommon variables:\n- `componentName` / `pageName` / `serviceName`: Name in PascalCase\n- `componentPath` / `pagePath`: Where to place the file (may use kebab-case)\n- Boolean flags: `withTests`, `withLayout`, `withStyles`, etc.\n\n## Step 4: Execute the Scaffolding Method\nUse the `use-scaffold-method` tool with:\n{% if not isMonolith %}- `projectPath`: Same path from step 1\n{% endif %}- `scaffold_feature_name`: Exact name from list-scaffolding-methods response\n- `variables`: Object matching the variables_schema exactly\n\n**Example:**\n```json\n{\n{% if not isMonolith %} \"projectPath\": \"apps/my-dashboard\",\n{% endif %} \"scaffold_feature_name\": \"scaffold-nextjs-page\",\n \"variables\": {\n \"pageName\": \"UserProfile\",\n \"pagePath\": \"user/profile\",\n \"withLayout\": true,\n \"withTests\": false\n }\n}\n```\n\n## Important Guidelines:\n- **Always call `list-scaffolding-methods` first**{% if not isMonolith %} with the projectPath{% endif %}\n- **Use exact variable names** from the schema (case-sensitive)\n- **Provide all required variables** - the tool will fail if any are missing\n- **Follow naming conventions**:\n - Component/Page/Service names: PascalCase (e.g., \"UserProfile\")\n - File paths: kebab-case or as specified in schema (e.g., \"user/profile\")\n- **Conditional files**: Files with `?condition=true` are only included when the variable is true\n- The tool will create files in the appropriate locations automatically\n- After creation, inform the user what files were created\n\n## Step 5: Review and Implement Generated Files\nAfter scaffolding completes, **you MUST**:\n1. **READ** all generated files to understand their structure\n2. **IMPLEMENT** the actual business logic:\n - Replace TODO comments with real code\n - Replace template placeholders with actual implementation\n - Add the specific functionality described in the user's request\n3. **REGISTER** the feature in appropriate files:\n - Import and register tools in `src/server/index.ts`\n - Export new modules from `index.ts` files\n - Update any necessary configuration files\n4. **TEST** to ensure the implementation works correctly\n5. **DO NOT SKIP** this step - scaffolded files are templates that need actual code\n\n## Example Workflow:\n1. Identify project path (provided or ask user){% if not isMonolith %}\n2. Call `list-scaffolding-methods` → See available features for this project{% else %}\n2. Call `list-scaffolding-methods` → See available features for your template{% endif %}\n3. Ask user which feature to add (or infer from request)\n4. Collect required variables based on schema\n5. Call `use-scaffold-method` with {% if not isMonolith %}projectPath, {% endif %}scaffold_feature_name, and variables\n6. **READ the generated files and IMPLEMENT the actual logic**\n7. **REGISTER the feature in server/index.ts and other config files**\n8. Report success and list created files with implementation details\n";
370
+
861
371
  //#endregion
862
372
  //#region src/prompts/ScaffoldFeaturePrompt.ts
863
373
  /**
@@ -865,6 +375,10 @@ After the boilerplate is created, **consider if additional features are needed**
865
375
  */
866
376
  var ScaffoldFeaturePrompt = class ScaffoldFeaturePrompt {
867
377
  static PROMPT_NAME = "scaffold-feature";
378
+ templateService = new TemplateService();
379
+ constructor(isMonolith = false) {
380
+ this.isMonolith = isMonolith;
381
+ }
868
382
  /**
869
383
  * Get the prompt definition for MCP
870
384
  */
@@ -887,104 +401,17 @@ var ScaffoldFeaturePrompt = class ScaffoldFeaturePrompt {
887
401
  * Get the prompt messages
888
402
  */
889
403
  getMessages(args) {
890
- const userRequest = args?.request || "";
404
+ const request = args?.request || "";
891
405
  const projectPath = args?.projectPath || "";
892
406
  return [{
893
407
  role: "user",
894
408
  content: {
895
409
  type: "text",
896
- text: `You are helping add a new feature to an existing project using the scaffold-mcp MCP tools.
897
-
898
- ${userRequest ? `User request: ${userRequest}\n` : ""}${projectPath ? `Project path: ${projectPath}\n` : ""}
899
- Your task is to scaffold a new feature by following this workflow:
900
-
901
- ## Step 1: Identify the Project
902
- Determine the project path where the feature will be added:
903
- - If projectPath is provided, use it
904
- - Otherwise, ask the user or infer from context (e.g., "apps/my-app", "packages/my-lib")
905
- - The path should point to a directory containing a \`project.json\` file
906
-
907
- ## Step 2: List Available Scaffolding Methods
908
- Use the \`list-scaffolding-methods\` tool with the projectPath.
909
-
910
- **What to look for:**
911
- - Feature name (e.g., "scaffold-nextjs-page", "scaffold-react-component")
912
- - Description of what files/code it generates
913
- - Required and optional variables in the variables_schema
914
- - The template type (derived from project's sourceTemplate)
915
-
916
- **Example:**
917
- \`\`\`json
918
- {
919
- "projectPath": "apps/my-dashboard"
920
- }
921
- \`\`\`
922
-
923
- ## Step 3: Gather Required Information
924
- Based on the selected scaffolding method's variables_schema, collect:
925
- - **Feature-specific variables**: Name, path, type, etc.
926
- - **Required variables**: All variables marked as required: true
927
- - **Optional variables**: Variables with required: false (ask user if needed)
928
-
929
- Common variables:
930
- - \`componentName\` / \`pageName\` / \`serviceName\`: Name in PascalCase
931
- - \`componentPath\` / \`pagePath\`: Where to place the file (may use kebab-case)
932
- - Boolean flags: \`withTests\`, \`withLayout\`, \`withStyles\`, etc.
933
-
934
- ## Step 4: Execute the Scaffolding Method
935
- Use the \`use-scaffold-method\` tool with:
936
- - \`projectPath\`: Same path from step 1
937
- - \`scaffold_feature_name\`: Exact name from list-scaffolding-methods response
938
- - \`variables\`: Object matching the variables_schema exactly
939
-
940
- **Example:**
941
- \`\`\`json
942
- {
943
- "projectPath": "apps/my-dashboard",
944
- "scaffold_feature_name": "scaffold-nextjs-page",
945
- "variables": {
946
- "pageName": "UserProfile",
947
- "pagePath": "user/profile",
948
- "withLayout": true,
949
- "withTests": false
950
- }
951
- }
952
- \`\`\`
953
-
954
- ## Important Guidelines:
955
- - **Always call \`list-scaffolding-methods\` first** with the projectPath
956
- - **Use exact variable names** from the schema (case-sensitive)
957
- - **Provide all required variables** - the tool will fail if any are missing
958
- - **Follow naming conventions**:
959
- - Component/Page/Service names: PascalCase (e.g., "UserProfile")
960
- - File paths: kebab-case or as specified in schema (e.g., "user/profile")
961
- - **Conditional files**: Files with \`?condition=true\` are only included when the variable is true
962
- - The tool will create files in the appropriate locations automatically
963
- - After creation, inform the user what files were created
964
-
965
- ## Step 5: Review and Implement Generated Files
966
- After scaffolding completes, **you MUST**:
967
- 1. **READ** all generated files to understand their structure
968
- 2. **IMPLEMENT** the actual business logic:
969
- - Replace TODO comments with real code
970
- - Replace template placeholders with actual implementation
971
- - Add the specific functionality described in the user's request
972
- 3. **REGISTER** the feature in appropriate files:
973
- - Import and register tools in \`src/server/index.ts\`
974
- - Export new modules from \`index.ts\` files
975
- - Update any necessary configuration files
976
- 4. **TEST** to ensure the implementation works correctly
977
- 5. **DO NOT SKIP** this step - scaffolded files are templates that need actual code
978
-
979
- ## Example Workflow:
980
- 1. Identify project path (provided or ask user)
981
- 2. Call \`list-scaffolding-methods\` → See available features for this project
982
- 3. Ask user which feature to add (or infer from request)
983
- 4. Collect required variables based on schema
984
- 5. Call \`use-scaffold-method\` with projectPath, scaffold_feature_name, and variables
985
- 6. **READ the generated files and IMPLEMENT the actual logic**
986
- 7. **REGISTER the feature in server/index.ts and other config files**
987
- 8. Report success and list created files with implementation details`
410
+ text: this.templateService.renderString(scaffold_feature_default, {
411
+ request,
412
+ projectPath,
413
+ isMonolith: this.isMonolith
414
+ })
988
415
  }
989
416
  }];
990
417
  }
@@ -993,79 +420,29 @@ After scaffolding completes, **you MUST**:
993
420
  //#endregion
994
421
  //#region src/server/index.ts
995
422
  function createServer(options = {}) {
996
- const { adminEnabled = false } = options;
423
+ const { adminEnabled = false, isMonolith = false } = options;
997
424
  const templatesPath = TemplatesManagerService.findTemplatesPathSync();
998
- const listBoilerplatesTool = new ListBoilerplatesTool(templatesPath);
999
- const useBoilerplateTool = new UseBoilerplateTool(templatesPath);
1000
- const listScaffoldingMethodsTool = new ListScaffoldingMethodsTool(templatesPath);
1001
- const useScaffoldMethodTool = new UseScaffoldMethodTool(templatesPath);
425
+ const listBoilerplatesTool = !isMonolith ? new ListBoilerplatesTool(templatesPath, isMonolith) : null;
426
+ const useBoilerplateTool = !isMonolith ? new UseBoilerplateTool(templatesPath, isMonolith) : null;
427
+ const listScaffoldingMethodsTool = new ListScaffoldingMethodsTool(templatesPath, isMonolith);
428
+ const useScaffoldMethodTool = new UseScaffoldMethodTool(templatesPath, isMonolith);
1002
429
  const writeToFileTool = new WriteToFileTool();
1003
- const generateBoilerplateTool = adminEnabled ? new GenerateBoilerplateTool(templatesPath) : null;
1004
- const generateBoilerplateFileTool = adminEnabled ? new GenerateBoilerplateFileTool(templatesPath) : null;
1005
- const generateFeatureScaffoldTool = adminEnabled ? new GenerateFeatureScaffoldTool(templatesPath) : null;
1006
- const generateBoilerplatePrompt = adminEnabled ? new GenerateBoilerplatePrompt() : null;
1007
- const generateFeatureScaffoldPrompt = adminEnabled ? new GenerateFeatureScaffoldPrompt() : null;
1008
- const scaffoldApplicationPrompt = new ScaffoldApplicationPrompt();
1009
- const scaffoldFeaturePrompt = new ScaffoldFeaturePrompt();
430
+ const generateBoilerplateTool = adminEnabled ? new GenerateBoilerplateTool(templatesPath, isMonolith) : null;
431
+ const generateBoilerplateFileTool = adminEnabled ? new GenerateBoilerplateFileTool(templatesPath, isMonolith) : null;
432
+ const generateFeatureScaffoldTool = adminEnabled ? new GenerateFeatureScaffoldTool(templatesPath, isMonolith) : null;
433
+ const generateBoilerplatePrompt = adminEnabled ? new GenerateBoilerplatePrompt(isMonolith) : null;
434
+ const generateFeatureScaffoldPrompt = adminEnabled ? new GenerateFeatureScaffoldPrompt(isMonolith) : null;
435
+ const scaffoldApplicationPrompt = new ScaffoldApplicationPrompt(isMonolith);
436
+ const scaffoldFeaturePrompt = new ScaffoldFeaturePrompt(isMonolith);
437
+ const instructions = new TemplateService().renderString(server_default, {
438
+ adminEnabled,
439
+ isMonolith
440
+ });
1010
441
  const server = new Server({
1011
442
  name: "scaffold-mcp",
1012
- version: "0.4.0"
443
+ version: package_default.version
1013
444
  }, {
1014
- instructions: `Use this MCP server to create new project and adding a new feature (pages, component, services, etc...).
1015
-
1016
- ## Workflow:
1017
-
1018
- 1. **Creating New Project**: Use \`list-boilerplates\` → \`use-boilerplate\`
1019
- 2. **Adding Features**: Use \`list-scaffolding-methods\` → \`use-scaffold-method\`
1020
-
1021
- ## AI Usage Guidelines:
1022
-
1023
- - Always call \`list-boilerplates\` first when creating new projects to see available options
1024
- - Always call \`list-scaffolding-methods\` first when adding features to understand what's available
1025
- - Follow the exact variable schema provided - validation will fail if required fields are missing
1026
- - Use kebab-case for project names (e.g., "my-new-app")
1027
- - The tools automatically handle file placement, imports, and code generation
1028
- - Check the returned JSON schemas to understand required vs optional variables` + (adminEnabled ? `
1029
-
1030
- ## Admin Mode (Template Generation):
1031
-
1032
- When creating custom boilerplate templates for frameworks not yet supported:
1033
-
1034
- 1. **Create Boilerplate Configuration**: Use \`generate-boilerplate\` to add a new boilerplate entry to a template's scaffold.yaml
1035
- - Specify template name, boilerplate name, description, target folder, and variable schema
1036
- - This creates the scaffold.yaml structure following the nextjs-15 pattern
1037
- - Optional: Add detailed instruction about file purposes and design patterns
1038
-
1039
- 2. **Create Feature Configuration**: Use \`generate-feature-scaffold\` to add a new feature entry to a template's scaffold.yaml
1040
- - Specify template name, feature name, generator, description, and variable schema
1041
- - This creates the scaffold.yaml structure for feature scaffolds (pages, components, etc.)
1042
- - Optional: Add detailed instruction about file purposes and design patterns
1043
- - Optional: Specify patterns to match existing files this feature works with
1044
-
1045
- 3. **Create Template Files**: Use \`generate-boilerplate-file\` to create the actual template files
1046
- - Create files referenced in the boilerplate's or feature's includes array
1047
- - Use {{ variableName }} syntax for Liquid variable placeholders
1048
- - Can copy from existing source files or provide content directly
1049
- - Files automatically get .liquid extension
1050
-
1051
- 4. **Test the Template**: Use \`list-boilerplates\`/\`list-scaffolding-methods\` and \`use-boilerplate\`/\`use-scaffold-method\` to verify your template works
1052
-
1053
- Example workflow for boilerplate:
1054
- \`\`\`
1055
- 1. generate-boilerplate { templateName: "react-vite", boilerplateName: "scaffold-vite-app", ... }
1056
- 2. generate-boilerplate-file { templateName: "react-vite", filePath: "package.json", content: "..." }
1057
- 3. generate-boilerplate-file { templateName: "react-vite", filePath: "src/App.tsx", content: "..." }
1058
- 4. list-boilerplates (verify it appears)
1059
- 5. use-boilerplate { boilerplateName: "scaffold-vite-app", variables: {...} }
1060
- \`\`\`
1061
-
1062
- Example workflow for feature:
1063
- \`\`\`
1064
- 1. generate-feature-scaffold { templateName: "nextjs-15", featureName: "scaffold-nextjs-component", generator: "componentGenerator.ts", ... }
1065
- 2. generate-boilerplate-file { templateName: "nextjs-15", filePath: "src/components/Component.tsx", content: "..." }
1066
- 3. list-scaffolding-methods (verify it appears)
1067
- 4. use-scaffold-method { scaffoldName: "scaffold-nextjs-component", variables: {...} }
1068
- \`\`\`` : ""),
445
+ instructions,
1069
446
  capabilities: {
1070
447
  tools: {},
1071
448
  prompts: {}
@@ -1073,12 +450,14 @@ Example workflow for feature:
1073
450
  });
1074
451
  server.setRequestHandler(ListToolsRequestSchema, async () => {
1075
452
  const tools = [
1076
- listBoilerplatesTool.getDefinition(),
1077
- useBoilerplateTool.getDefinition(),
1078
453
  listScaffoldingMethodsTool.getDefinition(),
1079
454
  useScaffoldMethodTool.getDefinition(),
1080
455
  writeToFileTool.getDefinition()
1081
456
  ];
457
+ if (!isMonolith) {
458
+ if (listBoilerplatesTool) tools.unshift(listBoilerplatesTool.getDefinition());
459
+ if (useBoilerplateTool) tools.splice(1, 0, useBoilerplateTool.getDefinition());
460
+ }
1082
461
  if (adminEnabled) {
1083
462
  if (generateBoilerplateTool) tools.push(generateBoilerplateTool.getDefinition());
1084
463
  if (generateBoilerplateFileTool) tools.push(generateBoilerplateFileTool.getDefinition());
@@ -1088,8 +467,14 @@ Example workflow for feature:
1088
467
  });
1089
468
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
1090
469
  const { name: name$1, arguments: args } = request.params;
1091
- if (name$1 === ListBoilerplatesTool.TOOL_NAME) return await listBoilerplatesTool.execute(args || {});
1092
- if (name$1 === UseBoilerplateTool.TOOL_NAME) return await useBoilerplateTool.execute(args || {});
470
+ if (name$1 === ListBoilerplatesTool.TOOL_NAME) {
471
+ if (isMonolith || !listBoilerplatesTool) throw new Error("Boilerplate tools are not available for monolith projects");
472
+ return await listBoilerplatesTool.execute(args || {});
473
+ }
474
+ if (name$1 === UseBoilerplateTool.TOOL_NAME) {
475
+ if (isMonolith || !useBoilerplateTool) throw new Error("Boilerplate tools are not available for monolith projects");
476
+ return await useBoilerplateTool.execute(args || {});
477
+ }
1093
478
  if (name$1 === ListScaffoldingMethodsTool.TOOL_NAME) return await listScaffoldingMethodsTool.execute(args || {});
1094
479
  if (name$1 === UseScaffoldMethodTool.TOOL_NAME) return await useScaffoldMethodTool.execute(args || {});
1095
480
  if (name$1 === WriteToFileTool.TOOL_NAME) return await writeToFileTool.execute(args || {});
@@ -1173,7 +558,16 @@ async function startServer(handler) {
1173
558
  const mcpServeCommand = new Command("mcp-serve").description("Start MCP server with specified transport").option("-t, --type <type>", "Transport type: stdio, http, or sse", "stdio").option("-p, --port <port>", "Port to listen on (http/sse only)", (val) => parseInt(val, 10), 3e3).option("--host <host>", "Host to bind to (http/sse only)", "localhost").option("--admin-enable", "Enable admin tools (generate-boilerplate)", false).action(async (options) => {
1174
559
  try {
1175
560
  const transportType = options.type.toLowerCase();
1176
- const serverOptions = { adminEnabled: options.adminEnable };
561
+ let isMonolith = false;
562
+ try {
563
+ isMonolith = (await ProjectConfigResolver.resolveProjectConfig(process.cwd())).type === "monolith";
564
+ } catch {
565
+ isMonolith = false;
566
+ }
567
+ const serverOptions = {
568
+ adminEnabled: options.adminEnable,
569
+ isMonolith
570
+ };
1177
571
  if (transportType === "stdio") await startServer(new StdioTransportHandler(createServer(serverOptions)));
1178
572
  else if (transportType === "http") await startServer(new HttpTransportHandler(() => createServer(serverOptions), {
1179
573
  mode: TransportMode.HTTP,
@@ -1201,21 +595,38 @@ const mcpServeCommand = new Command("mcp-serve").description("Start MCP server w
1201
595
  * Scaffold CLI command
1202
596
  */
1203
597
  const scaffoldCommand = new Command("scaffold").description("Add features to existing projects");
1204
- scaffoldCommand.command("list <projectPath>").description("List available scaffolding methods for a project").action(async (projectPath) => {
598
+ scaffoldCommand.command("list [projectPath]").description("List available scaffolding methods for a project or template").option("-t, --template <name>", "Template name (e.g., nextjs-15, typescript-mcp-package)").action(async (projectPath, options) => {
1205
599
  try {
1206
- const absolutePath = path.resolve(projectPath);
1207
- if (!await ProjectConfigResolver.hasConfiguration(absolutePath)) {
1208
- messages.error(`No project configuration found in ${absolutePath}`);
1209
- messages.hint("For monorepo: ensure project.json exists with sourceTemplate field\nFor monolith: ensure toolkit.yaml exists at workspace root");
600
+ if (!projectPath && !options.template) {
601
+ messages.error("Either projectPath or --template option must be provided");
602
+ messages.hint("Examples:");
603
+ print.debug(" scaffold-mcp scaffold list ./my-project");
604
+ print.debug(" scaffold-mcp scaffold list --template nextjs-15");
1210
605
  process.exit(1);
1211
606
  }
1212
607
  const templatesDir = await TemplatesManagerService.findTemplatesPath();
1213
- const methods = (await new ScaffoldingMethodsService(new FileSystemService(), templatesDir).listScaffoldingMethods(absolutePath)).methods;
608
+ const scaffoldingMethodsService = new ScaffoldingMethodsService(new FileSystemService(), templatesDir);
609
+ let result;
610
+ let displayName;
611
+ if (projectPath) {
612
+ const absolutePath = path.resolve(projectPath);
613
+ if (!await ProjectConfigResolver.hasConfiguration(absolutePath)) {
614
+ messages.error(`No project configuration found in ${absolutePath}`);
615
+ messages.hint("For monorepo: ensure project.json exists with sourceTemplate field\nFor monolith: ensure toolkit.yaml exists at workspace root\nOr use --template option to list methods for a specific template");
616
+ process.exit(1);
617
+ }
618
+ result = await scaffoldingMethodsService.listScaffoldingMethods(absolutePath);
619
+ displayName = projectPath;
620
+ } else {
621
+ result = await scaffoldingMethodsService.listScaffoldingMethodsByTemplate(options.template);
622
+ displayName = `template: ${options.template}`;
623
+ }
624
+ const methods = result.methods;
1214
625
  if (methods.length === 0) {
1215
- messages.warning("No scaffolding methods available for this project.");
626
+ messages.warning(`No scaffolding methods available for ${displayName}.`);
1216
627
  return;
1217
628
  }
1218
- print.header(`\n${icons.wrench} Available Scaffolding Methods for ${projectPath}:\n`);
629
+ print.header(`\n${icons.wrench} Available Scaffolding Methods for ${displayName}:\n`);
1219
630
  for (const method of methods) {
1220
631
  print.highlight(` ${method.name}`);
1221
632
  print.debug(` ${method.instruction || method.description || "No description available"}`);
@@ -1278,7 +689,6 @@ scaffoldCommand.command("add <featureName>").description("Add a feature to an ex
1278
689
  });
1279
690
  if (result.success) {
1280
691
  messages.success("✅ Feature added successfully!");
1281
- console.log(result.message);
1282
692
  if (result.createdFiles && result.createdFiles.length > 0) {
1283
693
  print.header("\n📁 Created files:");
1284
694
  result.createdFiles.forEach((file) => print.debug(` - ${file}`));
@@ -1297,20 +707,31 @@ scaffoldCommand.command("add <featureName>").description("Add a feature to an ex
1297
707
  }
1298
708
  } catch (error) {
1299
709
  messages.error(`❌ Error adding feature: ${error.message}`);
1300
- if (options.verbose) console.error("Stack trace:", error.stack);
1301
710
  process.exit(1);
1302
711
  }
1303
712
  });
1304
- scaffoldCommand.command("info <featureName>").description("Show detailed information about a scaffold method").option("-p, --project <path>", "Project path", process.cwd()).action(async (featureName, options) => {
713
+ scaffoldCommand.command("info <featureName>").description("Show detailed information about a scaffold method").option("-p, --project <path>", "Project path").option("-t, --template <name>", "Template name (e.g., nextjs-15, typescript-mcp-package)").action(async (featureName, options) => {
1305
714
  try {
1306
- const projectPath = path.resolve(options.project);
1307
- if (!await ProjectConfigResolver.hasConfiguration(projectPath)) {
1308
- messages.error(`No project configuration found in ${projectPath}`);
1309
- messages.hint("For monorepo: ensure project.json exists with sourceTemplate field\nFor monolith: ensure toolkit.yaml exists at workspace root");
715
+ if (!options.project && !options.template) {
716
+ messages.error("Either --project or --template option must be provided");
717
+ messages.hint("Examples:");
718
+ print.debug(" scaffold-mcp scaffold info scaffold-route --project ./my-app");
719
+ print.debug(" scaffold-mcp scaffold info scaffold-route --template nextjs-15");
1310
720
  process.exit(1);
1311
721
  }
1312
722
  const templatesDir = await TemplatesManagerService.findTemplatesPath();
1313
- const method = (await new ScaffoldingMethodsService(new FileSystemService(), templatesDir).listScaffoldingMethods(projectPath)).methods.find((m) => m.name === featureName);
723
+ const scaffoldingMethodsService = new ScaffoldingMethodsService(new FileSystemService(), templatesDir);
724
+ let result;
725
+ if (options.project) {
726
+ const projectPath = path.resolve(options.project);
727
+ if (!await ProjectConfigResolver.hasConfiguration(projectPath)) {
728
+ messages.error(`No project configuration found in ${projectPath}`);
729
+ messages.hint("For monorepo: ensure project.json exists with sourceTemplate field\nFor monolith: ensure toolkit.yaml exists at workspace root\nOr use --template option to view info for a specific template");
730
+ process.exit(1);
731
+ }
732
+ result = await scaffoldingMethodsService.listScaffoldingMethods(projectPath);
733
+ } else result = await scaffoldingMethodsService.listScaffoldingMethodsByTemplate(options.template);
734
+ const method = result.methods.find((m) => m.name === featureName);
1314
735
  if (!method) {
1315
736
  messages.error(`❌ Scaffold method '${featureName}' not found.`);
1316
737
  process.exit(1);
@@ -1318,7 +739,7 @@ scaffoldCommand.command("info <featureName>").description("Show detailed informa
1318
739
  print.header(`\n🔧 Scaffold Method: ${method.name}\n`);
1319
740
  print.debug(`Description: ${method.description}`);
1320
741
  print.header("\n📝 Variables Schema:");
1321
- console.log(JSON.stringify(method.variables_schema, null, 2));
742
+ print.debug(JSON.stringify(method.variables_schema, null, 2));
1322
743
  const includes = "includes" in method ? method.includes : [];
1323
744
  if (includes && includes.length > 0) {
1324
745
  print.header("\n📁 Files to be created:");
@@ -1345,8 +766,6 @@ async function main() {
1345
766
  program.addCommand(mcpServeCommand);
1346
767
  program.addCommand(boilerplateCommand);
1347
768
  program.addCommand(scaffoldCommand);
1348
- program.addCommand(initCommand);
1349
- program.addCommand(addCommand);
1350
769
  await program.parseAsync(process.argv);
1351
770
  }
1352
771
  main();