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