@agiflowai/scaffold-mcp 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/{ScaffoldConfigLoader-DQMCLVGD.cjs → ScaffoldConfigLoader-B-NLy6VP.cjs} +1 -1
  2. package/dist/{ScaffoldConfigLoader-CI0T6zdG.js → ScaffoldConfigLoader-BDMJNI1o.mjs} +1 -1
  3. package/dist/ScaffoldConfigLoader-SHk-KEje.mjs +3 -0
  4. package/dist/{ScaffoldConfigLoader-BrmvENTo.cjs → ScaffoldConfigLoader-Y_SBLPg7.cjs} +0 -1
  5. package/dist/ScaffoldService-BNOyoqSb.cjs +3 -0
  6. package/dist/ScaffoldService-BNdfC21Z.mjs +3 -0
  7. package/dist/{ScaffoldService-DB7-Cyod.js → ScaffoldService-BNuN00Fm.mjs} +8 -8
  8. package/dist/{ScaffoldService-BwDmXt83.cjs → ScaffoldService-ChzxM0Yc.cjs} +1 -3
  9. package/dist/TemplateService-BRfzfaZs.mjs +3 -0
  10. package/dist/{TemplateService-CiZJA06s.js → TemplateService-Cg5QV29n.mjs} +1 -1
  11. package/dist/{TemplateService-DRubcvS9.cjs → TemplateService-D3ydJR_R.cjs} +0 -2
  12. package/dist/TemplateService-DqieT1Tq.cjs +3 -0
  13. package/dist/VariableReplacementService-BWCd-z7X.mjs +3 -0
  14. package/dist/{VariableReplacementService-D0QnWKUW.cjs → VariableReplacementService-CAjesAYq.cjs} +1 -2
  15. package/dist/{VariableReplacementService-DRxd9ILB.js → VariableReplacementService-DHIINRnJ.mjs} +5 -5
  16. package/dist/{VariableReplacementService-CroHkMha.cjs → VariableReplacementService-DKaF2C9l.cjs} +1 -1
  17. package/dist/cli.cjs +74 -138
  18. package/dist/{cli.js → cli.mjs} +74 -134
  19. package/dist/index.cjs +14 -18
  20. package/dist/index.d.cts +20 -6
  21. package/dist/{index.d.ts → index.d.mts} +21 -7
  22. package/dist/{index.js → index.mjs} +14 -16
  23. package/dist/{stdio-TGsG8akc.cjs → stdio-BGj_FLky.cjs} +471 -414
  24. package/dist/{stdio-Bxn4A1IU.js → stdio-wAlpLC6l.mjs} +474 -409
  25. package/package.json +6 -8
  26. package/dist/ScaffoldConfigLoader-DhthV6xq.js +0 -3
  27. package/dist/ScaffoldService-B3En_m4t.cjs +0 -3
  28. package/dist/ScaffoldService-CJ3vNmAj.js +0 -3
  29. package/dist/TemplateService-BZRt3NI8.cjs +0 -3
  30. package/dist/TemplateService-DropYdp8.js +0 -3
  31. package/dist/VariableReplacementService-BAwTGv_R.js +0 -3
  32. /package/dist/{cli.d.ts → cli.d.mts} +0 -0
@@ -1,48 +1,256 @@
1
- import { ScaffoldConfigLoader } from "./ScaffoldConfigLoader-CI0T6zdG.js";
2
- import { ScaffoldService } from "./ScaffoldService-DB7-Cyod.js";
3
- import { TemplateService } from "./TemplateService-CiZJA06s.js";
4
- import { VariableReplacementService } from "./VariableReplacementService-DRxd9ILB.js";
5
- import { ProjectConfigResolver, log } from "@agiflowai/aicode-utils";
1
+ import { t as ScaffoldConfigLoader } from "./ScaffoldConfigLoader-BDMJNI1o.mjs";
2
+ import { t as ScaffoldService } from "./ScaffoldService-BNuN00Fm.mjs";
3
+ import { t as TemplateService } from "./TemplateService-Cg5QV29n.mjs";
4
+ import { t as VariableReplacementService } from "./VariableReplacementService-DHIINRnJ.mjs";
6
5
  import * as path$1 from "node:path";
7
6
  import path from "node:path";
8
- import { jsonSchemaToZod } from "@composio/json-schema-to-zod";
9
- import * as fs$1 from "fs-extra";
10
- import fs from "fs-extra";
7
+ import { ProjectConfigResolver, copy, ensureDir, log, pathExists, pathExistsSync, readFile, readFileSync, readJson, readdir, stat, statSync, writeFile } from "@agiflowai/aicode-utils";
11
8
  import * as yaml$1 from "js-yaml";
12
9
  import yaml from "js-yaml";
10
+ import { readdirSync } from "node:fs";
11
+ import { jsonSchemaToZod } from "@composio/json-schema-to-zod";
13
12
  import { z } from "zod";
14
- import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
15
13
  import { randomUUID } from "node:crypto";
16
14
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
15
+ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
17
16
  import express from "express";
18
17
  import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
19
18
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
20
19
 
20
+ //#region src/services/BoilerplateGeneratorService.ts
21
+ /**
22
+ * Service for generating boilerplate configurations in scaffold.yaml files
23
+ */
24
+ var BoilerplateGeneratorService = class {
25
+ templatesPath;
26
+ constructor(templatesPath) {
27
+ this.templatesPath = templatesPath;
28
+ }
29
+ /**
30
+ * Custom YAML dumper that forces literal block style (|) for description and instruction fields
31
+ */
32
+ dumpYamlWithLiteralBlocks(config) {
33
+ const LiteralBlockType = new yaml$1.Type("tag:yaml.org,2002:str", {
34
+ kind: "scalar",
35
+ construct: (data) => data,
36
+ represent: (data) => {
37
+ return data;
38
+ },
39
+ defaultStyle: "|"
40
+ });
41
+ const LITERAL_SCHEMA = yaml$1.DEFAULT_SCHEMA.extend([LiteralBlockType]);
42
+ const processedConfig = this.processConfigForLiteralBlocks(config);
43
+ return yaml$1.dump(processedConfig, {
44
+ schema: LITERAL_SCHEMA,
45
+ indent: 2,
46
+ lineWidth: -1,
47
+ noRefs: true,
48
+ sortKeys: false,
49
+ styles: { "!!str": "literal" },
50
+ replacer: (key, value) => {
51
+ if ((key === "description" || key === "instruction") && typeof value === "string") return value;
52
+ return value;
53
+ }
54
+ });
55
+ }
56
+ /**
57
+ * Process config to ensure description and instruction use literal block style
58
+ */
59
+ processConfigForLiteralBlocks(config) {
60
+ const processed = JSON.parse(JSON.stringify(config));
61
+ if (processed.boilerplate) processed.boilerplate = processed.boilerplate.map((bp) => {
62
+ const newBp = { ...bp };
63
+ if (newBp.description && typeof newBp.description === "string") newBp.description = this.ensureMultilineFormat(newBp.description);
64
+ if (newBp.instruction && typeof newBp.instruction === "string") newBp.instruction = this.ensureMultilineFormat(newBp.instruction);
65
+ return newBp;
66
+ });
67
+ if (processed.features) processed.features = processed.features.map((feature) => {
68
+ const newFeature = { ...feature };
69
+ if (newFeature.description && typeof newFeature.description === "string") newFeature.description = this.ensureMultilineFormat(newFeature.description);
70
+ if (newFeature.instruction && typeof newFeature.instruction === "string") newFeature.instruction = this.ensureMultilineFormat(newFeature.instruction);
71
+ return newFeature;
72
+ });
73
+ return processed;
74
+ }
75
+ /**
76
+ * Ensure string is properly formatted for YAML literal blocks
77
+ */
78
+ ensureMultilineFormat(text) {
79
+ return text.trim();
80
+ }
81
+ /**
82
+ * Generate or update a boilerplate configuration in scaffold.yaml
83
+ */
84
+ async generateBoilerplate(options) {
85
+ const { templateName, boilerplateName, description, instruction, targetFolder, variables, includes = [] } = options;
86
+ const templatePath = path$1.join(this.templatesPath, templateName);
87
+ await ensureDir(templatePath);
88
+ const scaffoldYamlPath = path$1.join(templatePath, "scaffold.yaml");
89
+ let scaffoldConfig = {};
90
+ if (await pathExists(scaffoldYamlPath)) {
91
+ const yamlContent = await readFile(scaffoldYamlPath, "utf-8");
92
+ scaffoldConfig = yaml$1.load(yamlContent);
93
+ }
94
+ if (!scaffoldConfig.boilerplate) scaffoldConfig.boilerplate = [];
95
+ if (scaffoldConfig.boilerplate.findIndex((b) => b.name === boilerplateName) !== -1) return {
96
+ success: false,
97
+ message: `Boilerplate '${boilerplateName}' already exists in ${scaffoldYamlPath}`
98
+ };
99
+ const requiredVars = variables.filter((v) => v.required).map((v) => v.name);
100
+ const boilerplateDefinition = {
101
+ name: boilerplateName,
102
+ targetFolder,
103
+ description,
104
+ variables_schema: {
105
+ type: "object",
106
+ properties: variables.reduce((acc, v) => {
107
+ acc[v.name] = {
108
+ type: v.type,
109
+ description: v.description
110
+ };
111
+ if (v.default !== void 0) acc[v.name].default = v.default;
112
+ return acc;
113
+ }, {}),
114
+ required: requiredVars,
115
+ additionalProperties: false
116
+ },
117
+ includes: includes.length > 0 ? includes : []
118
+ };
119
+ if (instruction) boilerplateDefinition.instruction = instruction;
120
+ scaffoldConfig.boilerplate.push(boilerplateDefinition);
121
+ await writeFile(scaffoldYamlPath, this.dumpYamlWithLiteralBlocks(scaffoldConfig), "utf-8");
122
+ return {
123
+ success: true,
124
+ message: `Boilerplate '${boilerplateName}' added to ${scaffoldYamlPath}`,
125
+ templatePath,
126
+ scaffoldYamlPath
127
+ };
128
+ }
129
+ /**
130
+ * List all templates (directories in templates folder)
131
+ */
132
+ async listTemplates() {
133
+ return (await readdir(this.templatesPath, { withFileTypes: true })).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
134
+ }
135
+ /**
136
+ * Check if a template exists
137
+ */
138
+ async templateExists(templateName) {
139
+ return pathExists(path$1.join(this.templatesPath, templateName));
140
+ }
141
+ /**
142
+ * Create or update a template file for a boilerplate
143
+ */
144
+ async createTemplateFile(options) {
145
+ const { templateName, filePath, content, sourceFile, header } = options;
146
+ const templatePath = path$1.join(this.templatesPath, templateName);
147
+ if (!await pathExists(templatePath)) return {
148
+ success: false,
149
+ message: `Template directory '${templateName}' does not exist at ${templatePath}`
150
+ };
151
+ let fileContent = content || "";
152
+ if (sourceFile) {
153
+ if (!await pathExists(sourceFile)) return {
154
+ success: false,
155
+ message: `Source file '${sourceFile}' does not exist`
156
+ };
157
+ fileContent = await readFile(sourceFile, "utf-8");
158
+ }
159
+ if (!fileContent && !sourceFile) return {
160
+ success: false,
161
+ message: "Either content or sourceFile must be provided"
162
+ };
163
+ const templateFilePath = filePath.endsWith(".liquid") ? filePath : `${filePath}.liquid`;
164
+ const fullPath = path$1.join(templatePath, templateFilePath);
165
+ await ensureDir(path$1.dirname(fullPath));
166
+ let finalContent = fileContent;
167
+ if (header) finalContent = `${header}\n\n${fileContent}`;
168
+ await writeFile(fullPath, finalContent, "utf-8");
169
+ return {
170
+ success: true,
171
+ message: "Template file created successfully",
172
+ filePath: templateFilePath,
173
+ fullPath
174
+ };
175
+ }
176
+ };
177
+
178
+ //#endregion
179
+ //#region src/utils/pagination.ts
180
+ var PaginationHelper = class PaginationHelper {
181
+ /**
182
+ * Default page size for pagination
183
+ */
184
+ static DEFAULT_PAGE_SIZE = 10;
185
+ /**
186
+ * Decodes a cursor string to extract the start index
187
+ * @param cursor - String representing the start index (e.g., "10")
188
+ * @returns Start index or 0 if invalid/undefined
189
+ */
190
+ static decodeCursor(cursor) {
191
+ if (!cursor) return 0;
192
+ const index = Number.parseInt(cursor, 10);
193
+ if (Number.isNaN(index) || index < 0) return 0;
194
+ return index;
195
+ }
196
+ /**
197
+ * Encodes an index into a cursor string
198
+ * @param index - Start index to encode
199
+ * @returns Cursor string (e.g., "10")
200
+ */
201
+ static encodeCursor(index) {
202
+ return index.toString();
203
+ }
204
+ /**
205
+ * Paginates an array of items
206
+ * @param items - All items to paginate
207
+ * @param cursor - Optional cursor representing the start index
208
+ * @param pageSize - Number of items per page (default: 10)
209
+ * @param includeMeta - Whether to include metadata in response (default: true)
210
+ * @returns Paginated result with items and optional nextCursor
211
+ */
212
+ static paginate(items, cursor, pageSize = PaginationHelper.DEFAULT_PAGE_SIZE, includeMeta = true) {
213
+ const startIndex = PaginationHelper.decodeCursor(cursor);
214
+ const endIndex = startIndex + pageSize;
215
+ const result = {
216
+ items: items.slice(startIndex, endIndex),
217
+ nextCursor: endIndex < items.length ? PaginationHelper.encodeCursor(endIndex) : void 0
218
+ };
219
+ if (includeMeta) result._meta = {
220
+ total: items.length,
221
+ offset: startIndex,
222
+ limit: pageSize
223
+ };
224
+ return result;
225
+ }
226
+ };
227
+
228
+ //#endregion
21
229
  //#region src/services/FileSystemService.ts
22
230
  var FileSystemService = class {
23
231
  async pathExists(path$2) {
24
- return fs.pathExists(path$2);
232
+ return pathExists(path$2);
25
233
  }
26
234
  async readFile(path$2, encoding = "utf8") {
27
- return fs.readFile(path$2, encoding);
235
+ return readFile(path$2, encoding);
28
236
  }
29
237
  async readJson(path$2) {
30
- return fs.readJson(path$2);
238
+ return readJson(path$2);
31
239
  }
32
240
  async writeFile(path$2, content, encoding = "utf8") {
33
- return fs.writeFile(path$2, content, encoding);
241
+ return writeFile(path$2, content, encoding);
34
242
  }
35
243
  async ensureDir(path$2) {
36
- return fs.ensureDir(path$2);
244
+ return ensureDir(path$2);
37
245
  }
38
246
  async copy(src, dest) {
39
- return fs.copy(src, dest);
247
+ return copy(src, dest);
40
248
  }
41
249
  async readdir(path$2) {
42
- return fs.readdir(path$2);
250
+ return readdir(path$2);
43
251
  }
44
252
  async stat(path$2) {
45
- return fs.stat(path$2);
253
+ return stat(path$2);
46
254
  }
47
255
  };
48
256
 
@@ -59,15 +267,17 @@ var BoilerplateService = class {
59
267
  this.scaffoldService = new ScaffoldService(fileSystemService, new ScaffoldConfigLoader(fileSystemService, this.templateService), new VariableReplacementService(fileSystemService, this.templateService), templatesPath);
60
268
  }
61
269
  /**
62
- * Scans all scaffold.yaml files and returns available boilerplates
270
+ * Scans all scaffold.yaml files and returns available boilerplates with pagination
271
+ * @param cursor - Optional pagination cursor
272
+ * @returns Paginated list of boilerplates
63
273
  */
64
- async listBoilerplates() {
274
+ async listBoilerplates(cursor) {
65
275
  const boilerplates = [];
66
276
  const templateDirs = await this.discoverTemplateDirectories();
67
277
  for (const templatePath of templateDirs) {
68
278
  const scaffoldYamlPath = path$1.join(this.templatesPath, templatePath, "scaffold.yaml");
69
- if (fs$1.existsSync(scaffoldYamlPath)) try {
70
- const scaffoldContent = fs$1.readFileSync(scaffoldYamlPath, "utf8");
279
+ if (pathExistsSync(scaffoldYamlPath)) try {
280
+ const scaffoldContent = readFileSync(scaffoldYamlPath, "utf8");
71
281
  const scaffoldConfig = yaml$1.load(scaffoldContent);
72
282
  if (scaffoldConfig.boilerplate) for (const boilerplate of scaffoldConfig.boilerplate) {
73
283
  if (!boilerplate.targetFolder) {
@@ -88,7 +298,12 @@ var BoilerplateService = class {
88
298
  log.warn(`Failed to load scaffold.yaml for ${templatePath}:`, error);
89
299
  }
90
300
  }
91
- return { boilerplates };
301
+ const paginatedResult = PaginationHelper.paginate(boilerplates, cursor);
302
+ return {
303
+ boilerplates: paginatedResult.items,
304
+ nextCursor: paginatedResult.nextCursor,
305
+ _meta: paginatedResult._meta
306
+ };
92
307
  }
93
308
  /**
94
309
  * Dynamically discovers template directories by finding all directories
@@ -97,14 +312,14 @@ var BoilerplateService = class {
97
312
  async discoverTemplateDirectories() {
98
313
  const templateDirs = [];
99
314
  const findTemplates = (dir, baseDir = "") => {
100
- if (!fs$1.existsSync(dir)) return;
101
- const items = fs$1.readdirSync(dir);
315
+ if (!pathExistsSync(dir)) return;
316
+ const items = readdirSync(dir);
102
317
  const hasPackageJson = items.includes("package.json") || items.includes("package.json.liquid");
103
318
  const hasScaffoldYaml = items.includes("scaffold.yaml");
104
319
  if (hasPackageJson && hasScaffoldYaml) templateDirs.push(baseDir);
105
320
  for (const item of items) {
106
321
  const itemPath = path$1.join(dir, item);
107
- if (fs$1.statSync(itemPath).isDirectory() && !item.startsWith(".") && item !== "node_modules") findTemplates(itemPath, baseDir ? path$1.join(baseDir, item) : item);
322
+ if (statSync(itemPath).isDirectory() && !item.startsWith(".") && item !== "node_modules") findTemplates(itemPath, baseDir ? path$1.join(baseDir, item) : item);
108
323
  }
109
324
  };
110
325
  findTemplates(this.templatesPath);
@@ -175,9 +390,12 @@ var BoilerplateService = class {
175
390
  const projectPath = path$1.join(targetFolder, folderName);
176
391
  await ProjectConfigResolver.createProjectJson(projectPath, folderName, boilerplate.template_path);
177
392
  }
393
+ const processedInstruction = boilerplate.instruction ? this.processBoilerplateInstruction(boilerplate.instruction, variables) : "";
394
+ let enhancedMessage = result.message;
395
+ if (processedInstruction) enhancedMessage += `\n\nPlease follow this **instruction**:\n${processedInstruction}`;
178
396
  return {
179
397
  success: result.success,
180
- message: result.message,
398
+ message: enhancedMessage,
181
399
  warnings: result.warnings,
182
400
  createdFiles: result.createdFiles,
183
401
  existingFiles: result.existingFiles
@@ -235,11 +453,11 @@ var BoilerplateService = class {
235
453
  };
236
454
 
237
455
  //#endregion
238
- //#region src/services/BoilerplateGeneratorService.ts
456
+ //#region src/services/ScaffoldGeneratorService.ts
239
457
  /**
240
- * Service for generating boilerplate configurations in scaffold.yaml files
458
+ * Service for generating feature scaffold configurations in scaffold.yaml files
241
459
  */
242
- var BoilerplateGeneratorService = class {
460
+ var ScaffoldGeneratorService = class {
243
461
  templatesPath;
244
462
  constructor(templatesPath) {
245
463
  this.templatesPath = templatesPath;
@@ -297,27 +515,26 @@ var BoilerplateGeneratorService = class {
297
515
  return text.trim();
298
516
  }
299
517
  /**
300
- * Generate or update a boilerplate configuration in scaffold.yaml
518
+ * Generate or update a feature configuration in scaffold.yaml
301
519
  */
302
- async generateBoilerplate(options) {
303
- const { templateName, boilerplateName, description, instruction, targetFolder, variables, includes = [] } = options;
520
+ async generateFeatureScaffold(options) {
521
+ const { templateName, featureName, description, instruction, variables, includes = [], patterns = [] } = options;
304
522
  const templatePath = path$1.join(this.templatesPath, templateName);
305
- await fs$1.ensureDir(templatePath);
523
+ await ensureDir(templatePath);
306
524
  const scaffoldYamlPath = path$1.join(templatePath, "scaffold.yaml");
307
525
  let scaffoldConfig = {};
308
- if (await fs$1.pathExists(scaffoldYamlPath)) {
309
- const yamlContent$1 = await fs$1.readFile(scaffoldYamlPath, "utf-8");
310
- scaffoldConfig = yaml$1.load(yamlContent$1);
526
+ if (await pathExists(scaffoldYamlPath)) {
527
+ const yamlContent = await readFile(scaffoldYamlPath, "utf-8");
528
+ scaffoldConfig = yaml$1.load(yamlContent);
311
529
  }
312
- if (!scaffoldConfig.boilerplate) scaffoldConfig.boilerplate = [];
313
- if (scaffoldConfig.boilerplate.findIndex((b) => b.name === boilerplateName) !== -1) return {
530
+ if (!scaffoldConfig.features) scaffoldConfig.features = [];
531
+ if (scaffoldConfig.features.findIndex((f) => f.name === featureName) !== -1) return {
314
532
  success: false,
315
- message: `Boilerplate '${boilerplateName}' already exists in ${scaffoldYamlPath}`
533
+ message: `Feature '${featureName}' already exists in ${scaffoldYamlPath}`
316
534
  };
317
535
  const requiredVars = variables.filter((v) => v.required).map((v) => v.name);
318
- const boilerplateDefinition = {
319
- name: boilerplateName,
320
- targetFolder,
536
+ const featureDefinition = {
537
+ name: featureName,
321
538
  description,
322
539
  variables_schema: {
323
540
  type: "object",
@@ -334,13 +551,13 @@ var BoilerplateGeneratorService = class {
334
551
  },
335
552
  includes: includes.length > 0 ? includes : []
336
553
  };
337
- if (instruction) boilerplateDefinition.instruction = instruction;
338
- scaffoldConfig.boilerplate.push(boilerplateDefinition);
339
- const yamlContent = this.dumpYamlWithLiteralBlocks(scaffoldConfig);
340
- await fs$1.writeFile(scaffoldYamlPath, yamlContent, "utf-8");
554
+ if (instruction) featureDefinition.instruction = instruction;
555
+ if (patterns && patterns.length > 0) featureDefinition.patterns = patterns;
556
+ scaffoldConfig.features.push(featureDefinition);
557
+ await writeFile(scaffoldYamlPath, this.dumpYamlWithLiteralBlocks(scaffoldConfig), "utf-8");
341
558
  return {
342
559
  success: true,
343
- message: `Boilerplate '${boilerplateName}' added to ${scaffoldYamlPath}`,
560
+ message: `Feature '${featureName}' added to ${scaffoldYamlPath}`,
344
561
  templatePath,
345
562
  scaffoldYamlPath
346
563
  };
@@ -349,73 +566,210 @@ var BoilerplateGeneratorService = class {
349
566
  * List all templates (directories in templates folder)
350
567
  */
351
568
  async listTemplates() {
352
- return (await fs$1.readdir(this.templatesPath, { withFileTypes: true })).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
569
+ return (await readdir(this.templatesPath, { withFileTypes: true })).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
353
570
  }
354
571
  /**
355
572
  * Check if a template exists
356
573
  */
357
574
  async templateExists(templateName) {
358
- const templatePath = path$1.join(this.templatesPath, templateName);
359
- return fs$1.pathExists(templatePath);
360
- }
361
- /**
362
- * Create or update a template file for a boilerplate
363
- */
364
- async createTemplateFile(options) {
365
- const { templateName, filePath, content, sourceFile, header } = options;
366
- const templatePath = path$1.join(this.templatesPath, templateName);
367
- if (!await fs$1.pathExists(templatePath)) return {
368
- success: false,
369
- message: `Template directory '${templateName}' does not exist at ${templatePath}`
370
- };
371
- let fileContent = content || "";
372
- if (sourceFile) {
373
- if (!await fs$1.pathExists(sourceFile)) return {
374
- success: false,
375
- message: `Source file '${sourceFile}' does not exist`
376
- };
377
- fileContent = await fs$1.readFile(sourceFile, "utf-8");
378
- }
379
- if (!fileContent && !sourceFile) return {
380
- success: false,
381
- message: "Either content or sourceFile must be provided"
382
- };
383
- const templateFilePath = filePath.endsWith(".liquid") ? filePath : `${filePath}.liquid`;
384
- const fullPath = path$1.join(templatePath, templateFilePath);
385
- await fs$1.ensureDir(path$1.dirname(fullPath));
386
- let finalContent = fileContent;
387
- if (header) finalContent = `${header}\n\n${fileContent}`;
388
- await fs$1.writeFile(fullPath, finalContent, "utf-8");
389
- return {
390
- success: true,
391
- message: "Template file created successfully",
392
- filePath: templateFilePath,
393
- fullPath
394
- };
575
+ return pathExists(path$1.join(this.templatesPath, templateName));
395
576
  }
396
577
  };
397
578
 
398
579
  //#endregion
399
- //#region src/tools/GenerateBoilerplateFileTool.ts
400
- /**
401
- * Tool to generate template files for boilerplates and features
402
- */
403
- var GenerateBoilerplateFileTool = class GenerateBoilerplateFileTool {
404
- static TOOL_NAME = "generate-boilerplate-file";
405
- boilerplateGeneratorService;
406
- isMonolith;
407
- constructor(templatesPath, isMonolith = false) {
408
- this.boilerplateGeneratorService = new BoilerplateGeneratorService(templatesPath);
409
- this.isMonolith = isMonolith;
580
+ //#region src/services/ScaffoldingMethodsService.ts
581
+ var ScaffoldingMethodsService = class {
582
+ templateService;
583
+ constructor(fileSystem, templatesRootPath) {
584
+ this.fileSystem = fileSystem;
585
+ this.templatesRootPath = templatesRootPath;
586
+ this.templateService = new TemplateService();
410
587
  }
411
- /**
412
- * Get the tool definition for MCP
413
- */
414
- getDefinition() {
415
- const properties = {};
416
- if (!this.isMonolith) properties.templateName = {
417
- type: "string",
418
- description: "Name of the template folder (must already exist)"
588
+ async listScaffoldingMethods(projectPath, cursor) {
589
+ const absoluteProjectPath = path.resolve(projectPath);
590
+ const sourceTemplate = (await ProjectConfigResolver.resolveProjectConfig(absoluteProjectPath)).sourceTemplate;
591
+ return this.listScaffoldingMethodsByTemplate(sourceTemplate, cursor);
592
+ }
593
+ async listScaffoldingMethodsByTemplate(templateName, cursor) {
594
+ const templatePath = await this.findTemplatePath(templateName);
595
+ if (!templatePath) throw new Error(`Template not found for sourceTemplate: ${templateName}`);
596
+ const fullTemplatePath = path.join(this.templatesRootPath, templatePath);
597
+ const scaffoldYamlPath = path.join(fullTemplatePath, "scaffold.yaml");
598
+ if (!await this.fileSystem.pathExists(scaffoldYamlPath)) throw new Error(`scaffold.yaml not found at ${scaffoldYamlPath}`);
599
+ const scaffoldContent = await this.fileSystem.readFile(scaffoldYamlPath, "utf8");
600
+ const architectConfig = yaml.load(scaffoldContent);
601
+ const methods = [];
602
+ if (architectConfig.features && Array.isArray(architectConfig.features)) architectConfig.features.forEach((feature) => {
603
+ const featureName = feature.name || `scaffold-${templateName}`;
604
+ methods.push({
605
+ name: featureName,
606
+ description: feature.description || "",
607
+ instruction: feature.instruction || "",
608
+ variables_schema: feature.variables_schema || {
609
+ type: "object",
610
+ properties: {},
611
+ required: [],
612
+ additionalProperties: false
613
+ },
614
+ generator: feature.generator
615
+ });
616
+ });
617
+ const paginatedResult = PaginationHelper.paginate(methods, cursor);
618
+ return {
619
+ sourceTemplate: templateName,
620
+ templatePath,
621
+ methods: paginatedResult.items,
622
+ nextCursor: paginatedResult.nextCursor,
623
+ _meta: paginatedResult._meta
624
+ };
625
+ }
626
+ /**
627
+ * Gets scaffolding methods with instructions rendered using provided variables
628
+ */
629
+ async listScaffoldingMethodsWithVariables(projectPath, variables, cursor) {
630
+ const result = await this.listScaffoldingMethods(projectPath, cursor);
631
+ const processedMethods = result.methods.map((method) => ({
632
+ ...method,
633
+ instruction: method.instruction ? this.processScaffoldInstruction(method.instruction, variables) : void 0
634
+ }));
635
+ return {
636
+ ...result,
637
+ methods: processedMethods
638
+ };
639
+ }
640
+ /**
641
+ * Processes scaffold instruction with template service
642
+ */
643
+ processScaffoldInstruction(instruction, variables) {
644
+ if (this.templateService.containsTemplateVariables(instruction)) return this.templateService.renderString(instruction, variables);
645
+ return instruction;
646
+ }
647
+ async findTemplatePath(sourceTemplate) {
648
+ const templateDirs = await this.discoverTemplateDirs();
649
+ if (templateDirs.includes(sourceTemplate)) return sourceTemplate;
650
+ for (const templateDir of templateDirs) {
651
+ const templatePath = path.join(this.templatesRootPath, templateDir);
652
+ const scaffoldYamlPath = path.join(templatePath, "scaffold.yaml");
653
+ if (await this.fileSystem.pathExists(scaffoldYamlPath)) try {
654
+ const scaffoldContent = await this.fileSystem.readFile(scaffoldYamlPath, "utf8");
655
+ const architectConfig = yaml.load(scaffoldContent);
656
+ if (architectConfig.boilerplate && Array.isArray(architectConfig.boilerplate)) {
657
+ for (const boilerplate of architectConfig.boilerplate) if (boilerplate.name?.includes(sourceTemplate)) return templateDir;
658
+ }
659
+ } catch (error) {
660
+ log.warn(`Failed to read scaffold.yaml at ${scaffoldYamlPath}:`, error);
661
+ }
662
+ }
663
+ return null;
664
+ }
665
+ /**
666
+ * Resolves the project path, handling both monorepo and monolith cases
667
+ * Uses ProjectConfigResolver to find the correct workspace/project root
668
+ */
669
+ async resolveProjectPath(projectPath) {
670
+ const absolutePath = path.resolve(projectPath);
671
+ return (await ProjectConfigResolver.resolveProjectConfig(absolutePath)).workspaceRoot || absolutePath;
672
+ }
673
+ /**
674
+ * Dynamically discovers all template directories
675
+ * Supports both flat structure (templates/nextjs-15) and nested structure (templates/apps/nextjs-15)
676
+ **/
677
+ async discoverTemplateDirs() {
678
+ const templateDirs = [];
679
+ try {
680
+ const items = await this.fileSystem.readdir(this.templatesRootPath);
681
+ for (const item of items) {
682
+ const itemPath = path.join(this.templatesRootPath, item);
683
+ if (!(await this.fileSystem.stat(itemPath)).isDirectory()) continue;
684
+ const scaffoldYamlPath = path.join(itemPath, "scaffold.yaml");
685
+ if (await this.fileSystem.pathExists(scaffoldYamlPath)) {
686
+ templateDirs.push(item);
687
+ continue;
688
+ }
689
+ try {
690
+ const subItems = await this.fileSystem.readdir(itemPath);
691
+ for (const subItem of subItems) {
692
+ const subItemPath = path.join(itemPath, subItem);
693
+ if (!(await this.fileSystem.stat(subItemPath)).isDirectory()) continue;
694
+ const subScaffoldYamlPath = path.join(subItemPath, "scaffold.yaml");
695
+ if (await this.fileSystem.pathExists(subScaffoldYamlPath)) {
696
+ const relativePath = path.join(item, subItem);
697
+ templateDirs.push(relativePath);
698
+ }
699
+ }
700
+ } catch (error) {
701
+ log.warn(`Failed to read subdirectories in ${itemPath}:`, error);
702
+ }
703
+ }
704
+ } catch (error) {
705
+ log.warn(`Failed to read templates root directory ${this.templatesRootPath}:`, error);
706
+ }
707
+ return templateDirs;
708
+ }
709
+ async useScaffoldMethod(request) {
710
+ const { projectPath, scaffold_feature_name, variables } = request;
711
+ const absoluteProjectPath = await this.resolveProjectPath(projectPath);
712
+ const scaffoldingMethods = await this.listScaffoldingMethods(absoluteProjectPath);
713
+ const method = scaffoldingMethods.methods.find((m) => m.name === scaffold_feature_name);
714
+ if (!method) {
715
+ const availableMethods = scaffoldingMethods.methods.map((m) => m.name).join(", ");
716
+ throw new Error(`Scaffold method '${scaffold_feature_name}' not found. Available methods: ${availableMethods}`);
717
+ }
718
+ const ScaffoldService$1 = (await import("./ScaffoldService-BNdfC21Z.mjs")).ScaffoldService;
719
+ const ScaffoldConfigLoader$1 = (await import("./ScaffoldConfigLoader-SHk-KEje.mjs")).ScaffoldConfigLoader;
720
+ const VariableReplacementService$1 = (await import("./VariableReplacementService-BWCd-z7X.mjs")).VariableReplacementService;
721
+ const TemplateService$1 = (await import("./TemplateService-BRfzfaZs.mjs")).TemplateService;
722
+ const templateService = new TemplateService$1();
723
+ const scaffoldConfigLoader = new ScaffoldConfigLoader$1(this.fileSystem, templateService);
724
+ const variableReplacer = new VariableReplacementService$1(this.fileSystem, templateService);
725
+ const scaffoldService = new ScaffoldService$1(this.fileSystem, scaffoldConfigLoader, variableReplacer, this.templatesRootPath);
726
+ const projectName = path.basename(absoluteProjectPath);
727
+ const result = await scaffoldService.useFeature({
728
+ projectPath: absoluteProjectPath,
729
+ templateFolder: scaffoldingMethods.templatePath,
730
+ featureName: scaffold_feature_name,
731
+ variables: {
732
+ ...variables,
733
+ appPath: absoluteProjectPath,
734
+ appName: projectName
735
+ }
736
+ });
737
+ if (!result.success) throw new Error(result.message);
738
+ return {
739
+ success: true,
740
+ message: `
741
+ Successfully scaffolded ${scaffold_feature_name} in ${projectPath}.
742
+ Please follow this **instruction**: \n ${method.instruction ? this.processScaffoldInstruction(method.instruction, variables) : ""}.
743
+ -> Create or update the plan based on the instruction.
744
+ `,
745
+ warnings: result.warnings,
746
+ createdFiles: result.createdFiles,
747
+ existingFiles: result.existingFiles
748
+ };
749
+ }
750
+ };
751
+
752
+ //#endregion
753
+ //#region src/tools/GenerateBoilerplateFileTool.ts
754
+ /**
755
+ * Tool to generate template files for boilerplates and features
756
+ */
757
+ var GenerateBoilerplateFileTool = class GenerateBoilerplateFileTool {
758
+ static TOOL_NAME = "generate-boilerplate-file";
759
+ boilerplateGeneratorService;
760
+ isMonolith;
761
+ constructor(templatesPath, isMonolith = false) {
762
+ this.boilerplateGeneratorService = new BoilerplateGeneratorService(templatesPath);
763
+ this.isMonolith = isMonolith;
764
+ }
765
+ /**
766
+ * Get the tool definition for MCP
767
+ */
768
+ getDefinition() {
769
+ const properties = {};
770
+ if (!this.isMonolith) properties.templateName = {
771
+ type: "string",
772
+ description: "Name of the template folder (must already exist)"
419
773
  };
420
774
  Object.assign(properties, {
421
775
  filePath: {
@@ -852,132 +1206,6 @@ Use this to add custom boilerplate configurations for frameworks not yet support
852
1206
  }
853
1207
  };
854
1208
 
855
- //#endregion
856
- //#region src/services/ScaffoldGeneratorService.ts
857
- /**
858
- * Service for generating feature scaffold configurations in scaffold.yaml files
859
- */
860
- var ScaffoldGeneratorService = class {
861
- templatesPath;
862
- constructor(templatesPath) {
863
- this.templatesPath = templatesPath;
864
- }
865
- /**
866
- * Custom YAML dumper that forces literal block style (|) for description and instruction fields
867
- */
868
- dumpYamlWithLiteralBlocks(config) {
869
- const LiteralBlockType = new yaml$1.Type("tag:yaml.org,2002:str", {
870
- kind: "scalar",
871
- construct: (data) => data,
872
- represent: (data) => {
873
- return data;
874
- },
875
- defaultStyle: "|"
876
- });
877
- const LITERAL_SCHEMA = yaml$1.DEFAULT_SCHEMA.extend([LiteralBlockType]);
878
- const processedConfig = this.processConfigForLiteralBlocks(config);
879
- return yaml$1.dump(processedConfig, {
880
- schema: LITERAL_SCHEMA,
881
- indent: 2,
882
- lineWidth: -1,
883
- noRefs: true,
884
- sortKeys: false,
885
- styles: { "!!str": "literal" },
886
- replacer: (key, value) => {
887
- if ((key === "description" || key === "instruction") && typeof value === "string") return value;
888
- return value;
889
- }
890
- });
891
- }
892
- /**
893
- * Process config to ensure description and instruction use literal block style
894
- */
895
- processConfigForLiteralBlocks(config) {
896
- const processed = JSON.parse(JSON.stringify(config));
897
- if (processed.boilerplate) processed.boilerplate = processed.boilerplate.map((bp) => {
898
- const newBp = { ...bp };
899
- if (newBp.description && typeof newBp.description === "string") newBp.description = this.ensureMultilineFormat(newBp.description);
900
- if (newBp.instruction && typeof newBp.instruction === "string") newBp.instruction = this.ensureMultilineFormat(newBp.instruction);
901
- return newBp;
902
- });
903
- if (processed.features) processed.features = processed.features.map((feature) => {
904
- const newFeature = { ...feature };
905
- if (newFeature.description && typeof newFeature.description === "string") newFeature.description = this.ensureMultilineFormat(newFeature.description);
906
- if (newFeature.instruction && typeof newFeature.instruction === "string") newFeature.instruction = this.ensureMultilineFormat(newFeature.instruction);
907
- return newFeature;
908
- });
909
- return processed;
910
- }
911
- /**
912
- * Ensure string is properly formatted for YAML literal blocks
913
- */
914
- ensureMultilineFormat(text) {
915
- return text.trim();
916
- }
917
- /**
918
- * Generate or update a feature configuration in scaffold.yaml
919
- */
920
- async generateFeatureScaffold(options) {
921
- const { templateName, featureName, description, instruction, variables, includes = [], patterns = [] } = options;
922
- const templatePath = path$1.join(this.templatesPath, templateName);
923
- await fs$1.ensureDir(templatePath);
924
- const scaffoldYamlPath = path$1.join(templatePath, "scaffold.yaml");
925
- let scaffoldConfig = {};
926
- if (await fs$1.pathExists(scaffoldYamlPath)) {
927
- const yamlContent$1 = await fs$1.readFile(scaffoldYamlPath, "utf-8");
928
- scaffoldConfig = yaml$1.load(yamlContent$1);
929
- }
930
- if (!scaffoldConfig.features) scaffoldConfig.features = [];
931
- if (scaffoldConfig.features.findIndex((f) => f.name === featureName) !== -1) return {
932
- success: false,
933
- message: `Feature '${featureName}' already exists in ${scaffoldYamlPath}`
934
- };
935
- const requiredVars = variables.filter((v) => v.required).map((v) => v.name);
936
- const featureDefinition = {
937
- name: featureName,
938
- description,
939
- variables_schema: {
940
- type: "object",
941
- properties: variables.reduce((acc, v) => {
942
- acc[v.name] = {
943
- type: v.type,
944
- description: v.description
945
- };
946
- if (v.default !== void 0) acc[v.name].default = v.default;
947
- return acc;
948
- }, {}),
949
- required: requiredVars,
950
- additionalProperties: false
951
- },
952
- includes: includes.length > 0 ? includes : []
953
- };
954
- if (instruction) featureDefinition.instruction = instruction;
955
- if (patterns && patterns.length > 0) featureDefinition.patterns = patterns;
956
- scaffoldConfig.features.push(featureDefinition);
957
- const yamlContent = this.dumpYamlWithLiteralBlocks(scaffoldConfig);
958
- await fs$1.writeFile(scaffoldYamlPath, yamlContent, "utf-8");
959
- return {
960
- success: true,
961
- message: `Feature '${featureName}' added to ${scaffoldYamlPath}`,
962
- templatePath,
963
- scaffoldYamlPath
964
- };
965
- }
966
- /**
967
- * List all templates (directories in templates folder)
968
- */
969
- async listTemplates() {
970
- return (await fs$1.readdir(this.templatesPath, { withFileTypes: true })).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
971
- }
972
- /**
973
- * Check if a template exists
974
- */
975
- async templateExists(templateName) {
976
- const templatePath = path$1.join(this.templatesPath, templateName);
977
- return fs$1.pathExists(templatePath);
978
- }
979
- };
980
-
981
1209
  //#endregion
982
1210
  //#region src/tools/GenerateFeatureScaffoldTool.ts
983
1211
  /**
@@ -1223,7 +1451,10 @@ var ListBoilerplatesTool = class ListBoilerplatesTool {
1223
1451
  description: description.trim(),
1224
1452
  inputSchema: {
1225
1453
  type: "object",
1226
- properties: {},
1454
+ properties: { cursor: {
1455
+ type: "string",
1456
+ description: "Optional pagination cursor to fetch the next page of results. Omit to fetch the first page."
1457
+ } },
1227
1458
  additionalProperties: false
1228
1459
  }
1229
1460
  };
@@ -1231,9 +1462,10 @@ var ListBoilerplatesTool = class ListBoilerplatesTool {
1231
1462
  /**
1232
1463
  * Execute the tool
1233
1464
  */
1234
- async execute(_args = {}) {
1465
+ async execute(args = {}) {
1235
1466
  try {
1236
- const result = await this.boilerplateService.listBoilerplates();
1467
+ const { cursor } = args;
1468
+ const result = await this.boilerplateService.listBoilerplates(cursor);
1237
1469
  return { content: [{
1238
1470
  type: "text",
1239
1471
  text: JSON.stringify(result, null, 2)
@@ -1254,176 +1486,6 @@ var ListBoilerplatesTool = class ListBoilerplatesTool {
1254
1486
  //#region src/instructions/tools/list-scaffolding-methods/description.md?raw
1255
1487
  var description_default$1 = "Lists all available scaffolding methods (features) that can be added to an existing project{% if not isMonolith %} or for a specific template{% endif %}.\n\nThis tool:\n{% if isMonolith %}\n- Reads your project's sourceTemplate from toolkit.yaml at workspace root\n{% else %}\n- Reads the project's sourceTemplate from project.json (monorepo) or toolkit.yaml (monolith), OR\n- Directly uses the provided templateName to list available features\n{% endif %}\n- Returns available features for that template type\n- Provides variable schemas for each scaffolding method\n- Shows descriptions of what each method creates\n\nUse this FIRST when adding features to understand:\n- What scaffolding methods are available\n- What variables each method requires\n- What files/features will be generated\n\nExample methods might include:\n- Adding new React routes (for React apps)\n- Creating API endpoints (for backend projects)\n- Adding new components (for frontend projects)\n- Setting up database models (for API projects)\n";
1256
1488
 
1257
- //#endregion
1258
- //#region src/services/ScaffoldingMethodsService.ts
1259
- var ScaffoldingMethodsService = class {
1260
- templateService;
1261
- constructor(fileSystem, templatesRootPath) {
1262
- this.fileSystem = fileSystem;
1263
- this.templatesRootPath = templatesRootPath;
1264
- this.templateService = new TemplateService();
1265
- }
1266
- async listScaffoldingMethods(projectPath) {
1267
- const absoluteProjectPath = path.resolve(projectPath);
1268
- const sourceTemplate = (await ProjectConfigResolver.resolveProjectConfig(absoluteProjectPath)).sourceTemplate;
1269
- return this.listScaffoldingMethodsByTemplate(sourceTemplate);
1270
- }
1271
- async listScaffoldingMethodsByTemplate(templateName) {
1272
- const templatePath = await this.findTemplatePath(templateName);
1273
- if (!templatePath) throw new Error(`Template not found for sourceTemplate: ${templateName}`);
1274
- const fullTemplatePath = path.join(this.templatesRootPath, templatePath);
1275
- const scaffoldYamlPath = path.join(fullTemplatePath, "scaffold.yaml");
1276
- if (!await this.fileSystem.pathExists(scaffoldYamlPath)) throw new Error(`scaffold.yaml not found at ${scaffoldYamlPath}`);
1277
- const scaffoldContent = await this.fileSystem.readFile(scaffoldYamlPath, "utf8");
1278
- const architectConfig = yaml.load(scaffoldContent);
1279
- const methods = [];
1280
- if (architectConfig.features && Array.isArray(architectConfig.features)) architectConfig.features.forEach((feature) => {
1281
- const featureName = feature.name || `scaffold-${templateName}`;
1282
- methods.push({
1283
- name: featureName,
1284
- description: feature.description || "",
1285
- instruction: feature.instruction || "",
1286
- variables_schema: feature.variables_schema || {
1287
- type: "object",
1288
- properties: {},
1289
- required: [],
1290
- additionalProperties: false
1291
- },
1292
- generator: feature.generator
1293
- });
1294
- });
1295
- return {
1296
- sourceTemplate: templateName,
1297
- templatePath,
1298
- methods
1299
- };
1300
- }
1301
- /**
1302
- * Gets scaffolding methods with instructions rendered using provided variables
1303
- */
1304
- async listScaffoldingMethodsWithVariables(projectPath, variables) {
1305
- const result = await this.listScaffoldingMethods(projectPath);
1306
- const processedMethods = result.methods.map((method) => ({
1307
- ...method,
1308
- instruction: method.instruction ? this.processScaffoldInstruction(method.instruction, variables) : void 0
1309
- }));
1310
- return {
1311
- ...result,
1312
- methods: processedMethods
1313
- };
1314
- }
1315
- /**
1316
- * Processes scaffold instruction with template service
1317
- */
1318
- processScaffoldInstruction(instruction, variables) {
1319
- if (this.templateService.containsTemplateVariables(instruction)) return this.templateService.renderString(instruction, variables);
1320
- return instruction;
1321
- }
1322
- async findTemplatePath(sourceTemplate) {
1323
- const templateDirs = await this.discoverTemplateDirs();
1324
- if (templateDirs.includes(sourceTemplate)) return sourceTemplate;
1325
- for (const templateDir of templateDirs) {
1326
- const templatePath = path.join(this.templatesRootPath, templateDir);
1327
- const scaffoldYamlPath = path.join(templatePath, "scaffold.yaml");
1328
- if (await this.fileSystem.pathExists(scaffoldYamlPath)) try {
1329
- const scaffoldContent = await this.fileSystem.readFile(scaffoldYamlPath, "utf8");
1330
- const architectConfig = yaml.load(scaffoldContent);
1331
- if (architectConfig.boilerplate && Array.isArray(architectConfig.boilerplate)) {
1332
- for (const boilerplate of architectConfig.boilerplate) if (boilerplate.name?.includes(sourceTemplate)) return templateDir;
1333
- }
1334
- } catch (error) {
1335
- log.warn(`Failed to read scaffold.yaml at ${scaffoldYamlPath}:`, error);
1336
- }
1337
- }
1338
- return null;
1339
- }
1340
- /**
1341
- * Resolves the project path, handling both monorepo and monolith cases
1342
- * Uses ProjectConfigResolver to find the correct workspace/project root
1343
- */
1344
- async resolveProjectPath(projectPath) {
1345
- const absolutePath = path.resolve(projectPath);
1346
- return (await ProjectConfigResolver.resolveProjectConfig(absolutePath)).workspaceRoot || absolutePath;
1347
- }
1348
- /**
1349
- * Dynamically discovers all template directories
1350
- * Supports both flat structure (templates/nextjs-15) and nested structure (templates/apps/nextjs-15)
1351
- **/
1352
- async discoverTemplateDirs() {
1353
- const templateDirs = [];
1354
- try {
1355
- const items = await this.fileSystem.readdir(this.templatesRootPath);
1356
- for (const item of items) {
1357
- const itemPath = path.join(this.templatesRootPath, item);
1358
- if (!(await this.fileSystem.stat(itemPath)).isDirectory()) continue;
1359
- const scaffoldYamlPath = path.join(itemPath, "scaffold.yaml");
1360
- if (await this.fileSystem.pathExists(scaffoldYamlPath)) {
1361
- templateDirs.push(item);
1362
- continue;
1363
- }
1364
- try {
1365
- const subItems = await this.fileSystem.readdir(itemPath);
1366
- for (const subItem of subItems) {
1367
- const subItemPath = path.join(itemPath, subItem);
1368
- if (!(await this.fileSystem.stat(subItemPath)).isDirectory()) continue;
1369
- const subScaffoldYamlPath = path.join(subItemPath, "scaffold.yaml");
1370
- if (await this.fileSystem.pathExists(subScaffoldYamlPath)) {
1371
- const relativePath = path.join(item, subItem);
1372
- templateDirs.push(relativePath);
1373
- }
1374
- }
1375
- } catch (error) {
1376
- log.warn(`Failed to read subdirectories in ${itemPath}:`, error);
1377
- }
1378
- }
1379
- } catch (error) {
1380
- log.warn(`Failed to read templates root directory ${this.templatesRootPath}:`, error);
1381
- }
1382
- return templateDirs;
1383
- }
1384
- async useScaffoldMethod(request) {
1385
- const { projectPath, scaffold_feature_name, variables } = request;
1386
- const absoluteProjectPath = await this.resolveProjectPath(projectPath);
1387
- const scaffoldingMethods = await this.listScaffoldingMethods(absoluteProjectPath);
1388
- const method = scaffoldingMethods.methods.find((m) => m.name === scaffold_feature_name);
1389
- if (!method) {
1390
- const availableMethods = scaffoldingMethods.methods.map((m) => m.name).join(", ");
1391
- throw new Error(`Scaffold method '${scaffold_feature_name}' not found. Available methods: ${availableMethods}`);
1392
- }
1393
- const ScaffoldService$1 = (await import("./ScaffoldService-CJ3vNmAj.js")).ScaffoldService;
1394
- const ScaffoldConfigLoader$1 = (await import("./ScaffoldConfigLoader-DhthV6xq.js")).ScaffoldConfigLoader;
1395
- const VariableReplacementService$1 = (await import("./VariableReplacementService-BAwTGv_R.js")).VariableReplacementService;
1396
- const TemplateService$1 = (await import("./TemplateService-DropYdp8.js")).TemplateService;
1397
- const templateService = new TemplateService$1();
1398
- const scaffoldConfigLoader = new ScaffoldConfigLoader$1(this.fileSystem, templateService);
1399
- const variableReplacer = new VariableReplacementService$1(this.fileSystem, templateService);
1400
- const scaffoldService = new ScaffoldService$1(this.fileSystem, scaffoldConfigLoader, variableReplacer, this.templatesRootPath);
1401
- const projectName = path.basename(absoluteProjectPath);
1402
- const result = await scaffoldService.useFeature({
1403
- projectPath: absoluteProjectPath,
1404
- templateFolder: scaffoldingMethods.templatePath,
1405
- featureName: scaffold_feature_name,
1406
- variables: {
1407
- ...variables,
1408
- appPath: absoluteProjectPath,
1409
- appName: projectName
1410
- }
1411
- });
1412
- if (!result.success) throw new Error(result.message);
1413
- return {
1414
- success: true,
1415
- message: `
1416
- Successfully scaffolded ${scaffold_feature_name} in ${projectPath}.
1417
- Please follow this **instruction**: \n ${method.instruction}.
1418
- -> Create or update the plan based on the instruction.
1419
- `,
1420
- warnings: result.warnings,
1421
- createdFiles: result.createdFiles,
1422
- existingFiles: result.existingFiles
1423
- };
1424
- }
1425
- };
1426
-
1427
1489
  //#endregion
1428
1490
  //#region src/tools/ListScaffoldingMethodsTool.ts
1429
1491
  var ListScaffoldingMethodsTool = class ListScaffoldingMethodsTool {
@@ -1443,7 +1505,10 @@ var ListScaffoldingMethodsTool = class ListScaffoldingMethodsTool {
1443
1505
  */
1444
1506
  getDefinition() {
1445
1507
  const description = this.templateService.renderString(description_default$1, { isMonolith: this.isMonolith });
1446
- const properties = {};
1508
+ const properties = { cursor: {
1509
+ type: "string",
1510
+ description: "Optional pagination cursor to fetch the next page of results. Omit to fetch the first page."
1511
+ } };
1447
1512
  if (!this.isMonolith) {
1448
1513
  properties.projectPath = {
1449
1514
  type: "string",
@@ -1469,18 +1534,18 @@ var ListScaffoldingMethodsTool = class ListScaffoldingMethodsTool {
1469
1534
  */
1470
1535
  async execute(args) {
1471
1536
  try {
1472
- const { projectPath, templateName } = args;
1537
+ const { projectPath, templateName, cursor } = args;
1473
1538
  let result;
1474
1539
  if (this.isMonolith) try {
1475
1540
  const resolvedTemplateName = (await ProjectConfigResolver.resolveProjectConfig(process.cwd())).sourceTemplate;
1476
- result = await this.scaffoldingMethodsService.listScaffoldingMethodsByTemplate(resolvedTemplateName);
1541
+ result = await this.scaffoldingMethodsService.listScaffoldingMethodsByTemplate(resolvedTemplateName, cursor);
1477
1542
  } catch (error) {
1478
1543
  throw new Error(`Failed to read template name from configuration: ${error instanceof Error ? error.message : String(error)}`);
1479
1544
  }
1480
1545
  else {
1481
1546
  if (!projectPath && !templateName) throw new Error("Either projectPath or templateName must be provided");
1482
- if (projectPath) result = await this.scaffoldingMethodsService.listScaffoldingMethods(projectPath);
1483
- else result = await this.scaffoldingMethodsService.listScaffoldingMethodsByTemplate(templateName);
1547
+ if (projectPath) result = await this.scaffoldingMethodsService.listScaffoldingMethods(projectPath, cursor);
1548
+ else result = await this.scaffoldingMethodsService.listScaffoldingMethodsByTemplate(templateName, cursor);
1484
1549
  }
1485
1550
  return { content: [{
1486
1551
  type: "text",
@@ -2070,4 +2135,4 @@ var StdioTransportHandler = class {
2070
2135
  };
2071
2136
 
2072
2137
  //#endregion
2073
- export { BoilerplateGeneratorService, BoilerplateService, FileSystemService, GenerateBoilerplateFileTool, GenerateBoilerplateTool, GenerateFeatureScaffoldTool, HttpTransportHandler, ListBoilerplatesTool, ListScaffoldingMethodsTool, ScaffoldGeneratorService, ScaffoldingMethodsService, SseTransportHandler, StdioTransportHandler, UseBoilerplateTool, UseScaffoldMethodTool, WriteToFileTool };
2138
+ export { UseScaffoldMethodTool as a, ListBoilerplatesTool as c, GenerateBoilerplateFileTool as d, ScaffoldingMethodsService as f, BoilerplateGeneratorService as g, FileSystemService as h, WriteToFileTool as i, GenerateFeatureScaffoldTool as l, BoilerplateService as m, SseTransportHandler as n, UseBoilerplateTool as o, ScaffoldGeneratorService as p, HttpTransportHandler as r, ListScaffoldingMethodsTool as s, StdioTransportHandler as t, GenerateBoilerplateTool as u };