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