@agiflowai/scaffold-mcp 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,7 +13,7 @@ A Model Context Protocol (MCP) server for scaffolding applications with boilerpl
13
13
  - **Template management**: Initialize templates folder and add templates from remote repositories
14
14
  - **Multiple frameworks**: Support for Next.js, Vite React, and custom boilerplates
15
15
  - **Multiple modes**: MCP server mode (stdio/HTTP/SSE) and standalone CLI mode
16
- - **MCP integration**: Seamlessly works with Claude Desktop and other MCP-compatible clients
16
+ - **MCP integration**: Seamlessly works with Claude Code and other MCP-compatible clients
17
17
 
18
18
  ## Installation
19
19
 
@@ -25,12 +25,12 @@ pnpm install @agiflowai/scaffold-mcp
25
25
 
26
26
  ### 1. MCP Server
27
27
 
28
- Run scaffold-mcp as an MCP server to integrate with Claude Desktop or other MCP clients.
28
+ Run scaffold-mcp as an MCP server to integrate with Claude Code or other MCP clients.
29
29
 
30
30
  #### Starting the Server
31
31
 
32
32
  ```bash
33
- # stdio transport (default) - for Claude Desktop
33
+ # stdio transport (default) - for Claude Code
34
34
  npx @agiflowai/scaffold-mcp mcp-serve
35
35
 
36
36
  # HTTP transport - for web applications
@@ -49,9 +49,9 @@ npx @agiflowai/scaffold-mcp mcp-serve --admin-enable
49
49
  - `--host <host>`: Host to bind to for HTTP/SSE (default: `localhost`)
50
50
  - `--admin-enable`: Enable admin tools for template generation
51
51
 
52
- #### Claude Desktop Configuration
52
+ #### Claude Code Configuration
53
53
 
54
- Add to your Claude Desktop config:
54
+ Add to your Claude Code config:
55
55
 
56
56
  ```json
57
57
  {
@@ -1,4 +1,4 @@
1
- const require_chunk = require('./chunk-nOFOJqeH.js');
1
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
2
2
  let node_path = require("node:path");
3
3
  node_path = require_chunk.__toESM(node_path);
4
4
  let js_yaml = require("js-yaml");
@@ -1,3 +1,3 @@
1
- const require_ScaffoldConfigLoader = require('./ScaffoldConfigLoader-CvIJEFcI.js');
1
+ const require_ScaffoldConfigLoader = require('./ScaffoldConfigLoader-1Pcv9cxm.cjs');
2
2
 
3
3
  exports.ScaffoldConfigLoader = require_ScaffoldConfigLoader.ScaffoldConfigLoader;
@@ -1,5 +1,4 @@
1
- const require_chunk = require('./chunk-nOFOJqeH.js');
2
- const require_logger = require('./logger-qztMS7ET.js');
1
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
3
2
  let node_path = require("node:path");
4
3
  node_path = require_chunk.__toESM(node_path);
5
4
  let __agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
@@ -66,7 +65,7 @@ var ScaffoldProcessingService = class {
66
65
  try {
67
66
  items = await this.fileSystem.readdir(dirPath);
68
67
  } catch (error) {
69
- require_logger.log.warn(`Cannot read directory ${dirPath}: ${error}`);
68
+ __agiflowai_aicode_utils.log.warn(`Cannot read directory ${dirPath}: ${error}`);
70
69
  return;
71
70
  }
72
71
  for (const item of items) {
@@ -77,7 +76,7 @@ var ScaffoldProcessingService = class {
77
76
  if (stat.isDirectory()) await this.trackCreatedFilesRecursive(itemPath, createdFiles);
78
77
  else if (stat.isFile()) createdFiles.push(itemPath);
79
78
  } catch (error) {
80
- require_logger.log.warn(`Cannot stat ${itemPath}: ${error}`);
79
+ __agiflowai_aicode_utils.log.warn(`Cannot stat ${itemPath}: ${error}`);
81
80
  }
82
81
  }
83
82
  }
@@ -89,7 +88,7 @@ var ScaffoldProcessingService = class {
89
88
  try {
90
89
  items = await this.fileSystem.readdir(dirPath);
91
90
  } catch (error) {
92
- require_logger.log.warn(`Cannot read directory ${dirPath}: ${error}`);
91
+ __agiflowai_aicode_utils.log.warn(`Cannot read directory ${dirPath}: ${error}`);
93
92
  return;
94
93
  }
95
94
  for (const item of items) {
@@ -100,7 +99,7 @@ var ScaffoldProcessingService = class {
100
99
  if (stat.isDirectory()) await this.trackExistingFilesRecursive(itemPath, existingFiles);
101
100
  else if (stat.isFile()) existingFiles.push(itemPath);
102
101
  } catch (error) {
103
- require_logger.log.warn(`Cannot stat ${itemPath}: ${error}`);
102
+ __agiflowai_aicode_utils.log.warn(`Cannot stat ${itemPath}: ${error}`);
104
103
  }
105
104
  }
106
105
  }
@@ -225,10 +224,10 @@ var ScaffoldService = class {
225
224
  */
226
225
  async processScaffold(params) {
227
226
  const { config, targetPath, templatePath, allVariables, scaffoldType } = params;
228
- require_logger.log.debug("Config generator:", config.generator);
229
- require_logger.log.debug("Config:", JSON.stringify(config, null, 2));
227
+ __agiflowai_aicode_utils.log.debug("Config generator:", config.generator);
228
+ __agiflowai_aicode_utils.log.debug("Config:", JSON.stringify(config, null, 2));
230
229
  if (config.generator) {
231
- require_logger.log.info("Using custom generator:", config.generator);
230
+ __agiflowai_aicode_utils.log.info("Using custom generator:", config.generator);
232
231
  try {
233
232
  const generator = (await import(node_path.default.join(templatePath, "generators", config.generator))).default;
234
233
  if (typeof generator !== "function") return {
@@ -0,0 +1,3 @@
1
+ const require_ScaffoldService = require('./ScaffoldService-BgFWAOLQ.cjs');
2
+
3
+ exports.ScaffoldService = require_ScaffoldService.ScaffoldService;
@@ -0,0 +1,3 @@
1
+ const require_TemplateService = require('./TemplateService-_KpkoLfZ.cjs');
2
+
3
+ exports.TemplateService = require_TemplateService.TemplateService;
@@ -1,5 +1,6 @@
1
- const require_chunk = require('./chunk-nOFOJqeH.js');
2
- const require_logger = require('./logger-qztMS7ET.js');
1
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
2
+ let __agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
3
+ __agiflowai_aicode_utils = require_chunk.__toESM(__agiflowai_aicode_utils);
3
4
  let liquidjs = require("liquidjs");
4
5
  liquidjs = require_chunk.__toESM(liquidjs);
5
6
 
@@ -12,7 +13,7 @@ var TemplateService = class {
12
13
  strictVariables: false
13
14
  });
14
15
  this.setupCustomFilters();
15
- require_logger.log.info("TemplateService initialized");
16
+ __agiflowai_aicode_utils.log.info("TemplateService initialized");
16
17
  }
17
18
  toPascalCase(str) {
18
19
  const camelCase = str.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : "");
@@ -56,15 +57,15 @@ var TemplateService = class {
56
57
  }
57
58
  renderString(template, variables) {
58
59
  try {
59
- require_logger.log.debug("Rendering template", {
60
+ __agiflowai_aicode_utils.log.debug("Rendering template", {
60
61
  variables,
61
62
  templatePreview: template.substring(0, 100)
62
63
  });
63
64
  const result = this.liquid.parseAndRenderSync(template, variables);
64
- require_logger.log.debug("Rendered template", { resultPreview: result.substring(0, 100) });
65
+ __agiflowai_aicode_utils.log.debug("Rendered template", { resultPreview: result.substring(0, 100) });
65
66
  return result;
66
67
  } catch (error) {
67
- require_logger.log.error("LiquidJS rendering error", {
68
+ __agiflowai_aicode_utils.log.error("LiquidJS rendering error", {
68
69
  error: error instanceof Error ? error.message : String(error),
69
70
  templatePreview: template.substring(0, 200),
70
71
  variables
@@ -1,7 +1,8 @@
1
- const require_chunk = require('./chunk-nOFOJqeH.js');
2
- const require_logger = require('./logger-qztMS7ET.js');
1
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
3
2
  let node_path = require("node:path");
4
3
  node_path = require_chunk.__toESM(node_path);
4
+ let __agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
5
+ __agiflowai_aicode_utils = require_chunk.__toESM(__agiflowai_aicode_utils);
5
6
 
6
7
  //#region src/services/VariableReplacementService.ts
7
8
  var VariableReplacementService = class {
@@ -33,7 +34,7 @@ var VariableReplacementService = class {
33
34
  try {
34
35
  items = await this.fileSystem.readdir(dirPath);
35
36
  } catch (error) {
36
- require_logger.log.warn(`Skipping directory ${dirPath}: ${error}`);
37
+ __agiflowai_aicode_utils.log.warn(`Skipping directory ${dirPath}: ${error}`);
37
38
  return;
38
39
  }
39
40
  for (const item of items) {
@@ -44,7 +45,7 @@ var VariableReplacementService = class {
44
45
  if (stat.isDirectory()) await this.processFilesForVariableReplacement(itemPath, variables);
45
46
  else if (stat.isFile()) await this.replaceVariablesInFile(itemPath, variables);
46
47
  } catch (error) {
47
- require_logger.log.warn(`Skipping item ${itemPath}: ${error}`);
48
+ __agiflowai_aicode_utils.log.warn(`Skipping item ${itemPath}: ${error}`);
48
49
  }
49
50
  }
50
51
  }
@@ -55,7 +56,7 @@ var VariableReplacementService = class {
55
56
  const renderedContent = this.templateService.renderString(content, variables);
56
57
  await this.fileSystem.writeFile(filePath, renderedContent, "utf8");
57
58
  } catch (error) {
58
- require_logger.log.warn(`Skipping file ${filePath}: ${error}`);
59
+ __agiflowai_aicode_utils.log.warn(`Skipping file ${filePath}: ${error}`);
59
60
  }
60
61
  }
61
62
  isBinaryFile(filePath) {
@@ -1,4 +1,3 @@
1
- require('./logger-qztMS7ET.js');
2
- const require_VariableReplacementService = require('./VariableReplacementService-UjRQY5JS.js');
1
+ const require_VariableReplacementService = require('./VariableReplacementService-ClshNY_C.cjs');
3
2
 
4
3
  exports.VariableReplacementService = require_VariableReplacementService.VariableReplacementService;
@@ -1,24 +1,21 @@
1
1
  #!/usr/bin/env node
2
- const require_chunk = require('./chunk-nOFOJqeH.js');
3
- const require_logger = require('./logger-qztMS7ET.js');
4
- const require_ScaffoldConfigLoader = require('./ScaffoldConfigLoader-CvIJEFcI.js');
5
- const require_ScaffoldService = require('./ScaffoldService-BVYY-WWY.js');
6
- const require_TemplateService = require('./TemplateService-wsvfwvRN.js');
7
- const require_VariableReplacementService = require('./VariableReplacementService-UjRQY5JS.js');
2
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
3
+ const require_ScaffoldConfigLoader = require('./ScaffoldConfigLoader-1Pcv9cxm.cjs');
4
+ const require_ScaffoldService = require('./ScaffoldService-BgFWAOLQ.cjs');
5
+ const require_TemplateService = require('./TemplateService-_KpkoLfZ.cjs');
6
+ const require_VariableReplacementService = require('./VariableReplacementService-ClshNY_C.cjs');
8
7
  let commander = require("commander");
9
8
  commander = require_chunk.__toESM(commander);
10
9
  let node_path = require("node:path");
11
10
  node_path = require_chunk.__toESM(node_path);
12
11
  let fs_extra = require("fs-extra");
13
12
  fs_extra = require_chunk.__toESM(fs_extra);
13
+ let __agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
14
+ __agiflowai_aicode_utils = require_chunk.__toESM(__agiflowai_aicode_utils);
14
15
  let node_child_process = require("node:child_process");
15
16
  node_child_process = require_chunk.__toESM(node_child_process);
16
17
  let node_util = require("node:util");
17
18
  node_util = require_chunk.__toESM(node_util);
18
- let chalk = require("chalk");
19
- chalk = require_chunk.__toESM(chalk);
20
- let __agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
21
- __agiflowai_aicode_utils = require_chunk.__toESM(__agiflowai_aicode_utils);
22
19
  let __composio_json_schema_to_zod = require("@composio/json-schema-to-zod");
23
20
  __composio_json_schema_to_zod = require_chunk.__toESM(__composio_json_schema_to_zod);
24
21
  let js_yaml = require("js-yaml");
@@ -123,119 +120,6 @@ async function fetchGitHubDirectoryContents(owner, repo, path$6, branch = "main"
123
120
  }));
124
121
  }
125
122
 
126
- //#endregion
127
- //#region src/utils/print.ts
128
- /**
129
- * Themed console utilities for consistent CLI output
130
- */
131
- const print = {
132
- info: (message) => {
133
- console.log(chalk.default.cyan(message));
134
- },
135
- success: (message) => {
136
- console.log(chalk.default.green(message));
137
- },
138
- warning: (message) => {
139
- console.log(chalk.default.yellow(message));
140
- },
141
- error: (message, error) => {
142
- if (error) {
143
- const errorMsg = error instanceof Error ? error.message : error;
144
- console.error(chalk.default.red(message), errorMsg);
145
- } else console.error(chalk.default.red(message));
146
- },
147
- debug: (message) => {
148
- console.log(chalk.default.gray(message));
149
- },
150
- header: (message) => {
151
- console.log(chalk.default.bold.cyan(message));
152
- },
153
- item: (message) => {
154
- console.log(chalk.default.gray(` - ${message}`));
155
- },
156
- indent: (message) => {
157
- console.log(chalk.default.gray(` ${message}`));
158
- },
159
- highlight: (message) => {
160
- console.log(chalk.default.bold.green(message));
161
- },
162
- newline: () => {
163
- console.log();
164
- }
165
- };
166
- /**
167
- * Emoji icons for consistent visual markers
168
- */
169
- const icons = {
170
- rocket: "=�",
171
- check: "",
172
- cross: "L",
173
- warning: "�",
174
- info: "9",
175
- package: "=�",
176
- folder: "=�",
177
- file: "📄",
178
- config: "📝",
179
- wrench: "🔧",
180
- chart: "📊",
181
- bulb: "💡",
182
- download: "=�",
183
- upload: "=�",
184
- gear: "�",
185
- clipboard: "=�",
186
- skip: "⏭"
187
- };
188
- /**
189
- * Themed message helpers
190
- */
191
- const messages = {
192
- info: (message) => {
193
- print.info(`${icons.info} ${message}`);
194
- },
195
- success: (message) => {
196
- print.success(`${icons.check} ${message}`);
197
- },
198
- error: (message, error) => {
199
- print.error(`${icons.cross} ${message}`, error);
200
- },
201
- warning: (message) => {
202
- print.warning(`${icons.warning} ${message}`);
203
- },
204
- hint: (message) => {
205
- print.warning(`${icons.bulb} ${message}`);
206
- },
207
- loading: (message) => {
208
- print.info(`${icons.rocket} ${message}`);
209
- }
210
- };
211
- /**
212
- * Section formatters
213
- */
214
- const sections = {
215
- header: (title) => {
216
- print.newline();
217
- print.header(`${title}`);
218
- print.newline();
219
- },
220
- list: (title, items) => {
221
- print.header(`\n${title}\n`);
222
- items.forEach((item) => print.item(item));
223
- },
224
- nextSteps: (steps) => {
225
- print.header(`\n${icons.clipboard} Next steps:`);
226
- steps.forEach((step) => print.indent(step));
227
- },
228
- createdFiles: (files, maxShow = 10) => {
229
- print.header(`\n${icons.folder} Created files:`);
230
- files.slice(0, maxShow).forEach((file) => print.item(file));
231
- if (files.length > maxShow) print.indent(`... and ${files.length - maxShow} more files`);
232
- },
233
- warnings: (warnings) => {
234
- print.warning(`\n${icons.warning} Warnings:`);
235
- warnings.forEach((warning) => print.item(warning));
236
- }
237
- };
238
-
239
123
  //#endregion
240
124
  //#region src/cli/add.ts
241
125
  /**
@@ -248,47 +132,47 @@ const addCommand = new commander.Command("add").description("Add a template to t
248
132
  const templateName = options.name;
249
133
  const templateUrl = options.url;
250
134
  if (templateType !== "boilerplate" && templateType !== "scaffold") {
251
- messages.error("Invalid template type. Use: boilerplate or scaffold");
135
+ __agiflowai_aicode_utils.messages.error("Invalid template type. Use: boilerplate or scaffold");
252
136
  process.exit(1);
253
137
  }
254
138
  const targetFolder = node_path.default.join(templatesPath, `${templateType}s`, templateName);
255
139
  if (await fs_extra.pathExists(targetFolder)) {
256
- messages.error(`Template '${templateName}' already exists at ${targetFolder}`);
140
+ __agiflowai_aicode_utils.messages.error(`Template '${templateName}' already exists at ${targetFolder}`);
257
141
  process.exit(1);
258
142
  }
259
- print.info(`${icons.download} Downloading template '${templateName}' from ${templateUrl}...`);
143
+ __agiflowai_aicode_utils.print.info(`${__agiflowai_aicode_utils.icons.download} Downloading template '${templateName}' from ${templateUrl}...`);
260
144
  await fs_extra.ensureDir(node_path.default.dirname(targetFolder));
261
145
  const parsedUrl = parseGitHubUrl(templateUrl);
262
146
  try {
263
147
  if (parsedUrl.isSubdirectory && parsedUrl.branch && parsedUrl.subdirectory) {
264
- print.info(`${icons.folder} Detected subdirectory: ${parsedUrl.subdirectory} (branch: ${parsedUrl.branch})`);
148
+ __agiflowai_aicode_utils.print.info(`${__agiflowai_aicode_utils.icons.folder} Detected subdirectory: ${parsedUrl.subdirectory} (branch: ${parsedUrl.branch})`);
265
149
  await cloneSubdirectory(parsedUrl.repoUrl, parsedUrl.branch, parsedUrl.subdirectory, targetFolder);
266
150
  } else await cloneRepository(parsedUrl.repoUrl, targetFolder);
267
- messages.success(`Template '${templateName}' added successfully!`);
268
- print.header(`\n${icons.folder} Template location:`);
269
- print.indent(targetFolder);
151
+ __agiflowai_aicode_utils.messages.success(`Template '${templateName}' added successfully!`);
152
+ __agiflowai_aicode_utils.print.header(`\n${__agiflowai_aicode_utils.icons.folder} Template location:`);
153
+ __agiflowai_aicode_utils.print.indent(targetFolder);
270
154
  const configFiles = [node_path.default.join(targetFolder, "boilerplate.yaml"), node_path.default.join(targetFolder, "scaffold.yaml")];
271
155
  let hasConfig = false;
272
156
  for (const configFile of configFiles) if (await fs_extra.pathExists(configFile)) {
273
- print.header(`\n${icons.config} Configuration file found:`);
274
- print.indent(node_path.default.basename(configFile));
157
+ __agiflowai_aicode_utils.print.header(`\n${__agiflowai_aicode_utils.icons.config} Configuration file found:`);
158
+ __agiflowai_aicode_utils.print.indent(node_path.default.basename(configFile));
275
159
  hasConfig = true;
276
160
  break;
277
161
  }
278
162
  if (!hasConfig) {
279
- messages.warning("Warning: No configuration file found (boilerplate.yaml or scaffold.yaml)");
280
- print.indent("You may need to create one manually.");
163
+ __agiflowai_aicode_utils.messages.warning("Warning: No configuration file found (boilerplate.yaml or scaffold.yaml)");
164
+ __agiflowai_aicode_utils.print.indent("You may need to create one manually.");
281
165
  }
282
- sections.nextSteps([`Review the template in ${targetFolder}`, `Test it with: scaffold-mcp ${templateType} list`]);
166
+ __agiflowai_aicode_utils.sections.nextSteps([`Review the template in ${targetFolder}`, `Test it with: scaffold-mcp ${templateType} list`]);
283
167
  } catch (error) {
284
- if (error.message.includes("not found") || error.message.includes("command not found")) messages.error("git command not found. Please install git first.");
285
- else if (error.message.includes("Authentication failed")) messages.error("Authentication failed. Make sure you have access to the repository.");
286
- else if (error.message.includes("Repository not found")) messages.error("Repository not found. Check the URL and try again.");
287
- else messages.error("Failed to clone repository:", error);
168
+ if (error.message.includes("not found") || error.message.includes("command not found")) __agiflowai_aicode_utils.messages.error("git command not found. Please install git first.");
169
+ else if (error.message.includes("Authentication failed")) __agiflowai_aicode_utils.messages.error("Authentication failed. Make sure you have access to the repository.");
170
+ else if (error.message.includes("Repository not found")) __agiflowai_aicode_utils.messages.error("Repository not found. Check the URL and try again.");
171
+ else __agiflowai_aicode_utils.messages.error("Failed to clone repository:", error);
288
172
  process.exit(1);
289
173
  }
290
174
  } catch (error) {
291
- messages.error("Error adding template:", error);
175
+ __agiflowai_aicode_utils.messages.error("Error adding template:", error);
292
176
  process.exit(1);
293
177
  }
294
178
  });
@@ -347,7 +231,7 @@ var BoilerplateService = class {
347
231
  const scaffoldConfig = js_yaml.load(scaffoldContent);
348
232
  if (scaffoldConfig.boilerplate) for (const boilerplate of scaffoldConfig.boilerplate) {
349
233
  if (!boilerplate.targetFolder) {
350
- require_logger.log.warn(`Skipping boilerplate '${boilerplate.name}' in ${templatePath}: targetFolder is required in scaffold.yaml`);
234
+ __agiflowai_aicode_utils.log.warn(`Skipping boilerplate '${boilerplate.name}' in ${templatePath}: targetFolder is required in scaffold.yaml`);
351
235
  continue;
352
236
  }
353
237
  boilerplates.push({
@@ -361,7 +245,7 @@ var BoilerplateService = class {
361
245
  });
362
246
  }
363
247
  } catch (error) {
364
- require_logger.log.warn(`Failed to load scaffold.yaml for ${templatePath}:`, error);
248
+ __agiflowai_aicode_utils.log.warn(`Failed to load scaffold.yaml for ${templatePath}:`, error);
365
249
  }
366
250
  }
367
251
  return { boilerplates };
@@ -390,7 +274,7 @@ var BoilerplateService = class {
390
274
  * Executes a specific boilerplate with provided variables
391
275
  */
392
276
  async useBoilerplate(request) {
393
- const { boilerplateName, variables } = request;
277
+ const { boilerplateName, variables, monolith = false, targetFolderOverride } = request;
394
278
  const boilerplateList = await this.listBoilerplates();
395
279
  const boilerplate = boilerplateList.boilerplates.find((b) => b.name === boilerplateName);
396
280
  if (!boilerplate) return {
@@ -408,11 +292,12 @@ var BoilerplateService = class {
408
292
  message: "Missing required parameter: packageName or appName"
409
293
  };
410
294
  const folderName = packageName.includes("/") ? packageName.split("/")[1] : packageName;
295
+ const targetFolder = targetFolderOverride || (monolith ? "." : boilerplate.target_folder);
411
296
  try {
412
297
  const result = await this.scaffoldService.useBoilerplate({
413
298
  projectName: folderName,
414
299
  packageName,
415
- targetFolder: boilerplate.target_folder,
300
+ targetFolder,
416
301
  templateFolder: boilerplate.template_path,
417
302
  boilerplateName,
418
303
  variables: {
@@ -423,7 +308,11 @@ var BoilerplateService = class {
423
308
  }
424
309
  });
425
310
  if (!result.success) return result;
426
- this.ensureProjectJsonSourceTemplate(boilerplate.target_folder, folderName, boilerplate.template_path);
311
+ if (monolith) await __agiflowai_aicode_utils.ProjectConfigResolver.createToolkitYaml(boilerplate.template_path);
312
+ else {
313
+ const projectPath = node_path.join(targetFolder, folderName);
314
+ await __agiflowai_aicode_utils.ProjectConfigResolver.createProjectJson(projectPath, folderName, boilerplate.template_path);
315
+ }
427
316
  return {
428
317
  success: result.success,
429
318
  message: result.message,
@@ -481,29 +370,6 @@ var BoilerplateService = class {
481
370
  };
482
371
  }
483
372
  }
484
- /**
485
- * Ensures project.json has sourceTemplate field
486
- * If project.json exists, updates it; otherwise creates a new one
487
- */
488
- ensureProjectJsonSourceTemplate(targetFolder, projectName, sourceTemplate) {
489
- const projectJsonPath = node_path.join(targetFolder, projectName, "project.json");
490
- try {
491
- let projectJson;
492
- if (fs_extra.existsSync(projectJsonPath)) {
493
- const content = fs_extra.readFileSync(projectJsonPath, "utf8");
494
- projectJson = JSON.parse(content);
495
- } else projectJson = {
496
- name: projectName,
497
- $schema: "../../node_modules/nx/schemas/project-schema.json",
498
- sourceRoot: `${targetFolder}/${projectName}`,
499
- projectType: "application"
500
- };
501
- projectJson.sourceTemplate = sourceTemplate;
502
- fs_extra.writeFileSync(projectJsonPath, `${JSON.stringify(projectJson, null, 2)}\n`, "utf8");
503
- } catch (error) {
504
- require_logger.log.warn(`Failed to update project.json with sourceTemplate: ${error}`);
505
- }
506
- }
507
373
  };
508
374
 
509
375
  //#endregion
@@ -516,78 +382,85 @@ boilerplateCommand.command("list").description("List all available boilerplate t
516
382
  try {
517
383
  const { boilerplates } = await new BoilerplateService(await __agiflowai_aicode_utils.TemplatesManagerService.findTemplatesPath()).listBoilerplates();
518
384
  if (boilerplates.length === 0) {
519
- messages.warning("No boilerplate templates found.");
385
+ __agiflowai_aicode_utils.messages.warning("No boilerplate templates found.");
520
386
  return;
521
387
  }
522
- print.header(`\n${icons.package} Available Boilerplate Templates:\n`);
388
+ __agiflowai_aicode_utils.print.header(`\n${__agiflowai_aicode_utils.icons.package} Available Boilerplate Templates:\n`);
523
389
  for (const bp of boilerplates) {
524
- print.highlight(` ${bp.name}`);
525
- print.debug(` ${bp.description}`);
526
- print.debug(` Target: ${bp.target_folder}`);
390
+ __agiflowai_aicode_utils.print.highlight(` ${bp.name}`);
391
+ __agiflowai_aicode_utils.print.debug(` ${bp.description}`);
392
+ __agiflowai_aicode_utils.print.debug(` Target: ${bp.target_folder}`);
527
393
  const required = typeof bp.variables_schema === "object" && bp.variables_schema !== null && "required" in bp.variables_schema ? bp.variables_schema.required : [];
528
- if (required && required.length > 0) print.debug(` Required: ${required.join(", ")}`);
529
- print.newline();
394
+ if (required && required.length > 0) __agiflowai_aicode_utils.print.debug(` Required: ${required.join(", ")}`);
395
+ __agiflowai_aicode_utils.print.newline();
530
396
  }
531
397
  } catch (error) {
532
- messages.error("Error listing boilerplates:", error);
398
+ __agiflowai_aicode_utils.messages.error("Error listing boilerplates:", error);
533
399
  process.exit(1);
534
400
  }
535
401
  });
536
- boilerplateCommand.command("create <boilerplateName>").description("Create a new project from a boilerplate template").option("-v, --vars <json>", "JSON string containing variables for the boilerplate").option("--verbose", "Enable verbose logging").action(async (boilerplateName, options) => {
402
+ boilerplateCommand.command("create <boilerplateName>").description("Create a new project from a boilerplate template").option("-v, --vars <json>", "JSON string containing variables for the boilerplate").option("-m, --monolith", "Create as monolith project at workspace root with toolkit.yaml (default: false, creates as monorepo with project.json)").option("-t, --target-folder <path>", "Override target folder (defaults to boilerplate targetFolder for monorepo, workspace root for monolith)").option("--verbose", "Enable verbose logging").action(async (boilerplateName, options) => {
537
403
  try {
538
404
  const boilerplateService = new BoilerplateService(await __agiflowai_aicode_utils.TemplatesManagerService.findTemplatesPath());
539
405
  let variables = {};
540
406
  if (options.vars) try {
541
407
  variables = JSON.parse(options.vars);
542
408
  } catch (error) {
543
- messages.error("Error parsing variables JSON:", error);
544
- messages.hint("Example: --vars '{\"appName\": \"my-app\", \"description\": \"My application\"}'");
409
+ __agiflowai_aicode_utils.messages.error("Error parsing variables JSON:", error);
410
+ __agiflowai_aicode_utils.messages.hint("Example: --vars '{\"appName\": \"my-app\", \"description\": \"My application\"}'");
545
411
  process.exit(1);
546
412
  }
547
413
  const boilerplate = await boilerplateService.getBoilerplate(boilerplateName);
548
414
  if (!boilerplate) {
549
415
  const { boilerplates } = await boilerplateService.listBoilerplates();
550
- messages.error(`Boilerplate '${boilerplateName}' not found.`);
551
- print.warning(`Available boilerplates: ${boilerplates.map((b) => b.name).join(", ")}`);
416
+ __agiflowai_aicode_utils.messages.error(`Boilerplate '${boilerplateName}' not found.`);
417
+ __agiflowai_aicode_utils.print.warning(`Available boilerplates: ${boilerplates.map((b) => b.name).join(", ")}`);
552
418
  process.exit(1);
553
419
  }
554
420
  const required = typeof boilerplate.variables_schema === "object" && boilerplate.variables_schema !== null && "required" in boilerplate.variables_schema ? boilerplate.variables_schema.required : [];
555
421
  const missing = required.filter((key) => !variables[key]);
556
422
  if (missing.length > 0) {
557
- messages.error(`Missing required variables: ${missing.join(", ")}`);
558
- messages.hint(`Use --vars with a JSON object containing: ${missing.join(", ")}`);
423
+ __agiflowai_aicode_utils.messages.error(`Missing required variables: ${missing.join(", ")}`);
424
+ __agiflowai_aicode_utils.messages.hint(`Use --vars with a JSON object containing: ${missing.join(", ")}`);
559
425
  const exampleVars = {};
560
426
  for (const key of required) if (key === "appName" || key === "packageName") exampleVars[key] = "my-app";
561
427
  else if (key === "description") exampleVars[key] = "My application description";
562
428
  else exampleVars[key] = `<${key}>`;
563
- print.debug(`Example: scaffold-mcp boilerplate create ${boilerplateName} --vars '${JSON.stringify(exampleVars)}'`);
429
+ __agiflowai_aicode_utils.print.debug(`Example: scaffold-mcp boilerplate create ${boilerplateName} --vars '${JSON.stringify(exampleVars)}'`);
564
430
  process.exit(1);
565
431
  }
566
432
  if (options.verbose) {
567
- print.info(`${icons.wrench} Boilerplate: ${boilerplateName}`);
568
- print.info(`${icons.chart} Variables: ${JSON.stringify(variables, null, 2)}`);
433
+ __agiflowai_aicode_utils.print.info(`${__agiflowai_aicode_utils.icons.wrench} Boilerplate: ${boilerplateName}`);
434
+ __agiflowai_aicode_utils.print.info(`${__agiflowai_aicode_utils.icons.chart} Variables: ${JSON.stringify(variables, null, 2)}`);
569
435
  }
570
- messages.loading(`Creating project from boilerplate '${boilerplateName}'...`);
436
+ __agiflowai_aicode_utils.messages.loading(`Creating project from boilerplate '${boilerplateName}'...`);
571
437
  const result = await boilerplateService.useBoilerplate({
572
438
  boilerplateName,
573
- variables
439
+ variables,
440
+ monolith: options.monolith,
441
+ targetFolderOverride: options.targetFolder
574
442
  });
575
443
  if (result.success) {
576
- messages.success("Project created successfully!");
577
- print.info(result.message);
578
- if (result.createdFiles && result.createdFiles.length > 0) sections.createdFiles(result.createdFiles);
444
+ __agiflowai_aicode_utils.messages.success("Project created successfully!");
445
+ __agiflowai_aicode_utils.print.info(result.message);
446
+ if (result.createdFiles && result.createdFiles.length > 0) __agiflowai_aicode_utils.sections.createdFiles(result.createdFiles);
579
447
  const projectName = variables.appName || variables.packageName;
580
- if (projectName) sections.nextSteps([
581
- `cd ${boilerplate.target_folder}/${projectName}`,
582
- "pnpm install",
583
- "pnpm dev"
584
- ]);
448
+ if (projectName) {
449
+ const targetFolder = options.targetFolder || (options.monolith ? "." : boilerplate.target_folder);
450
+ const projectPath = options.monolith ? "." : `${targetFolder}/${projectName}`;
451
+ const steps = projectPath === "." ? ["pnpm install", "pnpm dev"] : [
452
+ `cd ${projectPath}`,
453
+ "pnpm install",
454
+ "pnpm dev"
455
+ ];
456
+ __agiflowai_aicode_utils.sections.nextSteps(steps);
457
+ }
585
458
  } else {
586
- messages.error(`Failed to create project: ${result.message}`);
459
+ __agiflowai_aicode_utils.messages.error(`Failed to create project: ${result.message}`);
587
460
  process.exit(1);
588
461
  }
589
462
  } catch (error) {
590
- messages.error("Error creating project:", error);
463
+ __agiflowai_aicode_utils.messages.error("Error creating project:", error);
591
464
  if (options.verbose) console.error("Stack trace:", error.stack);
592
465
  process.exit(1);
593
466
  }
@@ -596,18 +469,18 @@ boilerplateCommand.command("info <boilerplateName>").description("Show detailed
596
469
  try {
597
470
  const bp = await new BoilerplateService(await __agiflowai_aicode_utils.TemplatesManagerService.findTemplatesPath()).getBoilerplate(boilerplateName);
598
471
  if (!bp) {
599
- messages.error(`Boilerplate '${boilerplateName}' not found.`);
472
+ __agiflowai_aicode_utils.messages.error(`Boilerplate '${boilerplateName}' not found.`);
600
473
  process.exit(1);
601
474
  }
602
- print.header(`\n${icons.package} Boilerplate: ${bp.name}\n`);
603
- print.debug(`Description: ${bp.description}`);
604
- print.debug(`Template Path: ${bp.template_path}`);
605
- print.debug(`Target Folder: ${bp.target_folder}`);
606
- print.header(`\n${icons.config} Variables Schema:`);
475
+ __agiflowai_aicode_utils.print.header(`\n${__agiflowai_aicode_utils.icons.package} Boilerplate: ${bp.name}\n`);
476
+ __agiflowai_aicode_utils.print.debug(`Description: ${bp.description}`);
477
+ __agiflowai_aicode_utils.print.debug(`Template Path: ${bp.template_path}`);
478
+ __agiflowai_aicode_utils.print.debug(`Target Folder: ${bp.target_folder}`);
479
+ __agiflowai_aicode_utils.print.header(`\n${__agiflowai_aicode_utils.icons.config} Variables Schema:`);
607
480
  console.log(JSON.stringify(bp.variables_schema, null, 2));
608
- if (bp.includes && bp.includes.length > 0) sections.list(`${icons.folder} Included Files:`, bp.includes);
481
+ if (bp.includes && bp.includes.length > 0) __agiflowai_aicode_utils.sections.list(`${__agiflowai_aicode_utils.icons.folder} Included Files:`, bp.includes);
609
482
  } catch (error) {
610
- messages.error("Error getting boilerplate info:", error);
483
+ __agiflowai_aicode_utils.messages.error("Error getting boilerplate info:", error);
611
484
  process.exit(1);
612
485
  }
613
486
  });
@@ -638,24 +511,24 @@ const DEFAULT_TEMPLATE_REPO = {
638
511
  */
639
512
  async function downloadTemplates(templatesPath) {
640
513
  try {
641
- print.info(`${icons.download} Fetching templates from ${DEFAULT_TEMPLATE_REPO.owner}/${DEFAULT_TEMPLATE_REPO.repo}...`);
514
+ __agiflowai_aicode_utils.print.info(`${__agiflowai_aicode_utils.icons.download} Fetching templates from ${DEFAULT_TEMPLATE_REPO.owner}/${DEFAULT_TEMPLATE_REPO.repo}...`);
642
515
  const templateDirs = (await fetchGitHubDirectoryContents(DEFAULT_TEMPLATE_REPO.owner, DEFAULT_TEMPLATE_REPO.repo, DEFAULT_TEMPLATE_REPO.path, DEFAULT_TEMPLATE_REPO.branch)).filter((item) => item.type === "dir");
643
516
  if (templateDirs.length === 0) {
644
- messages.warning("No templates found in repository");
517
+ __agiflowai_aicode_utils.messages.warning("No templates found in repository");
645
518
  return;
646
519
  }
647
- print.info(`${icons.folder} Found ${templateDirs.length} template(s)`);
520
+ __agiflowai_aicode_utils.print.info(`${__agiflowai_aicode_utils.icons.folder} Found ${templateDirs.length} template(s)`);
648
521
  for (const template of templateDirs) {
649
522
  const targetFolder = node_path.default.join(templatesPath, template.name);
650
523
  if (await fs_extra.pathExists(targetFolder)) {
651
- print.info(`${icons.skip} Skipping ${template.name} (already exists)`);
524
+ __agiflowai_aicode_utils.print.info(`${__agiflowai_aicode_utils.icons.skip} Skipping ${template.name} (already exists)`);
652
525
  continue;
653
526
  }
654
- print.info(`${icons.download} Downloading ${template.name}...`);
527
+ __agiflowai_aicode_utils.print.info(`${__agiflowai_aicode_utils.icons.download} Downloading ${template.name}...`);
655
528
  await cloneSubdirectory(`https://github.com/${DEFAULT_TEMPLATE_REPO.owner}/${DEFAULT_TEMPLATE_REPO.repo}.git`, DEFAULT_TEMPLATE_REPO.branch, template.path, targetFolder);
656
- print.success(`${icons.check} Downloaded ${template.name}`);
529
+ __agiflowai_aicode_utils.print.success(`${__agiflowai_aicode_utils.icons.check} Downloaded ${template.name}`);
657
530
  }
658
- print.success(`\n${icons.check} All templates downloaded successfully!`);
531
+ __agiflowai_aicode_utils.print.success(`\n${__agiflowai_aicode_utils.icons.check} All templates downloaded successfully!`);
659
532
  } catch (error) {
660
533
  throw new Error(`Failed to download templates: ${error.message}`);
661
534
  }
@@ -667,7 +540,7 @@ const initCommand = new commander.Command("init").description("Initialize templa
667
540
  try {
668
541
  const workspaceRoot = await findWorkspaceRoot();
669
542
  const templatesPath = options.path ? node_path.default.join(workspaceRoot, options.path) : node_path.default.join(workspaceRoot, "templates");
670
- print.info(`${icons.rocket} Initializing templates folder at: ${templatesPath}`);
543
+ __agiflowai_aicode_utils.print.info(`${__agiflowai_aicode_utils.icons.rocket} Initializing templates folder at: ${templatesPath}`);
671
544
  await fs_extra.ensureDir(templatesPath);
672
545
  await fs_extra.writeFile(node_path.default.join(templatesPath, "README.md"), `# Templates
673
546
 
@@ -703,11 +576,11 @@ Template files use Liquid syntax for variable placeholders: \`{{ variableName }}
703
576
 
704
577
  See existing templates for examples and documentation for more details.
705
578
  `);
706
- print.success(`${icons.check} Templates folder created!`);
579
+ __agiflowai_aicode_utils.print.success(`${__agiflowai_aicode_utils.icons.check} Templates folder created!`);
707
580
  if (options.download !== false) await downloadTemplates(templatesPath);
708
- else print.info(`${icons.skip} Skipping template download (use --download to enable)`);
709
- print.header(`\n${icons.folder} Templates location:`);
710
- print.indent(templatesPath);
581
+ else __agiflowai_aicode_utils.print.info(`${__agiflowai_aicode_utils.icons.skip} Skipping template download (use --download to enable)`);
582
+ __agiflowai_aicode_utils.print.header(`\n${__agiflowai_aicode_utils.icons.folder} Templates location:`);
583
+ __agiflowai_aicode_utils.print.indent(templatesPath);
711
584
  const nextSteps = [];
712
585
  if (options.download === false) {
713
586
  nextSteps.push(`Download templates: scaffold-mcp init --download`);
@@ -716,9 +589,9 @@ See existing templates for examples and documentation for more details.
716
589
  nextSteps.push(`List available boilerplates: scaffold-mcp boilerplate list`);
717
590
  nextSteps.push(`Add more templates: scaffold-mcp add --name <name> --url <url>`);
718
591
  }
719
- sections.nextSteps(nextSteps);
592
+ __agiflowai_aicode_utils.sections.nextSteps(nextSteps);
720
593
  } catch (error) {
721
- messages.error(`Error initializing templates folder: ${error.message}`);
594
+ __agiflowai_aicode_utils.messages.error(`Error initializing templates folder: ${error.message}`);
722
595
  process.exit(1);
723
596
  }
724
597
  });
@@ -2110,11 +1983,7 @@ var ScaffoldingMethodsService = class {
2110
1983
  }
2111
1984
  async listScaffoldingMethods(projectPath) {
2112
1985
  const absoluteProjectPath = node_path.default.resolve(projectPath);
2113
- const projectJsonPath = node_path.default.join(absoluteProjectPath, "project.json");
2114
- if (!await this.fileSystem.pathExists(projectJsonPath)) throw new Error(`project.json not found at ${projectJsonPath}`);
2115
- const projectConfig = await this.fileSystem.readJson(projectJsonPath);
2116
- if (!projectConfig.sourceTemplate) throw new Error(`sourceTemplate not specified in project.json at ${projectJsonPath}`);
2117
- const sourceTemplate = projectConfig.sourceTemplate;
1986
+ const sourceTemplate = (await __agiflowai_aicode_utils.ProjectConfigResolver.resolveProjectConfig(absoluteProjectPath)).sourceTemplate;
2118
1987
  const templatePath = await this.findTemplatePath(sourceTemplate);
2119
1988
  if (!templatePath) throw new Error(`Template not found for sourceTemplate: ${sourceTemplate}`);
2120
1989
  const fullTemplatePath = node_path.default.join(this.templatesRootPath, templatePath);
@@ -2177,7 +2046,7 @@ var ScaffoldingMethodsService = class {
2177
2046
  for (const boilerplate of architectConfig.boilerplate) if (boilerplate.name?.includes(sourceTemplate)) return templateDir;
2178
2047
  }
2179
2048
  } catch (error) {
2180
- require_logger.log.warn(`Failed to read scaffold.yaml at ${scaffoldYamlPath}:`, error);
2049
+ __agiflowai_aicode_utils.log.warn(`Failed to read scaffold.yaml at ${scaffoldYamlPath}:`, error);
2181
2050
  }
2182
2051
  }
2183
2052
  return null;
@@ -2210,11 +2079,11 @@ var ScaffoldingMethodsService = class {
2210
2079
  }
2211
2080
  }
2212
2081
  } catch (error) {
2213
- require_logger.log.warn(`Failed to read subdirectories in ${itemPath}:`, error);
2082
+ __agiflowai_aicode_utils.log.warn(`Failed to read subdirectories in ${itemPath}:`, error);
2214
2083
  }
2215
2084
  }
2216
2085
  } catch (error) {
2217
- require_logger.log.warn(`Failed to read templates root directory ${this.templatesRootPath}:`, error);
2086
+ __agiflowai_aicode_utils.log.warn(`Failed to read templates root directory ${this.templatesRootPath}:`, error);
2218
2087
  }
2219
2088
  return templateDirs;
2220
2089
  }
@@ -2226,10 +2095,10 @@ var ScaffoldingMethodsService = class {
2226
2095
  const availableMethods = scaffoldingMethods.methods.map((m) => m.name).join(", ");
2227
2096
  throw new Error(`Scaffold method '${scaffold_feature_name}' not found. Available methods: ${availableMethods}`);
2228
2097
  }
2229
- const ScaffoldService$1 = (await Promise.resolve().then(() => require("./ScaffoldService-47JkJe7N.js"))).ScaffoldService;
2230
- const ScaffoldConfigLoader$1 = (await Promise.resolve().then(() => require("./ScaffoldConfigLoader-BhrrsLya.js"))).ScaffoldConfigLoader;
2231
- const VariableReplacementService$1 = (await Promise.resolve().then(() => require("./VariableReplacementService-C0BdOUm6.js"))).VariableReplacementService;
2232
- const TemplateService$1 = (await Promise.resolve().then(() => require("./TemplateService-lGQxhofk.js"))).TemplateService;
2098
+ const ScaffoldService$1 = (await Promise.resolve().then(() => require("./ScaffoldService-BvD9WvRi.cjs"))).ScaffoldService;
2099
+ const ScaffoldConfigLoader$1 = (await Promise.resolve().then(() => require("./ScaffoldConfigLoader-DzcV5a_c.cjs"))).ScaffoldConfigLoader;
2100
+ const VariableReplacementService$1 = (await Promise.resolve().then(() => require("./VariableReplacementService-YUpL5nAC.cjs"))).VariableReplacementService;
2101
+ const TemplateService$1 = (await Promise.resolve().then(() => require("./TemplateService-B5EZjPB0.cjs"))).TemplateService;
2233
2102
  const templateService = new TemplateService$1();
2234
2103
  const scaffoldConfigLoader = new ScaffoldConfigLoader$1(this.fileSystem, templateService);
2235
2104
  const variableReplacer = new VariableReplacementService$1(this.fileSystem, templateService);
@@ -2280,7 +2149,7 @@ var ListScaffoldingMethodsTool = class ListScaffoldingMethodsTool {
2280
2149
  description: `Lists all available scaffolding methods (features) that can be added to an existing project.
2281
2150
 
2282
2151
  This tool:
2283
- - Reads the project's sourceTemplate from project.json
2152
+ - Reads the project's sourceTemplate from project.json (monorepo) or toolkit.yaml (monolith)
2284
2153
  - Returns available features for that template type
2285
2154
  - Provides variable schemas for each scaffolding method
2286
2155
  - Shows descriptions of what each method creates
@@ -2299,7 +2168,7 @@ Example methods might include:
2299
2168
  type: "object",
2300
2169
  properties: { projectPath: {
2301
2170
  type: "string",
2302
- description: "Absolute path to the project directory containing project.json (e.g., \"apps/my-app\", \"backend/apis/my-api\", \"packages/my-package\")"
2171
+ description: "Absolute path to the project directory (for monorepo: containing project.json; for monolith: workspace root with toolkit.yaml)"
2303
2172
  } },
2304
2173
  required: ["projectPath"],
2305
2174
  additionalProperties: false
@@ -2349,14 +2218,17 @@ var UseBoilerplateTool = class UseBoilerplateTool {
2349
2218
  This tool will:
2350
2219
  - Generate all necessary files from the template
2351
2220
  - Replace template variables with provided values
2352
- - Create the project in the appropriate monorepo directory
2221
+ - Create the project in the appropriate directory (monorepo or monolith)
2353
2222
  - Set up initial configuration files (package.json, tsconfig.json, etc.)
2223
+ - Create toolkit.yaml (monolith) or project.json (monorepo) with sourceTemplate
2354
2224
 
2355
2225
  IMPORTANT:
2356
2226
  - Always call \`list-boilerplates\` first to get the exact variable schema
2357
2227
  - Follow the schema exactly - required fields must be provided
2358
2228
  - Use kebab-case for project names (e.g., "my-new-app", not "MyNewApp")
2359
- - The tool will validate all variables against the schema before proceeding`,
2229
+ - The tool will validate all variables against the schema before proceeding
2230
+ - For monolith projects, use monolith: true to create at workspace root
2231
+ - For monorepo projects, files are created in targetFolder/projectName`,
2360
2232
  inputSchema: {
2361
2233
  type: "object",
2362
2234
  properties: {
@@ -2367,6 +2239,14 @@ IMPORTANT:
2367
2239
  variables: {
2368
2240
  type: "object",
2369
2241
  description: "Variables object matching the boilerplate's variables_schema exactly"
2242
+ },
2243
+ monolith: {
2244
+ type: "boolean",
2245
+ description: "If true, creates project at workspace root with toolkit.yaml. If false or omitted, creates in targetFolder/projectName with project.json (monorepo mode)"
2246
+ },
2247
+ targetFolderOverride: {
2248
+ type: "string",
2249
+ description: "Optional override for target folder. If not provided, uses boilerplate targetFolder (monorepo) or workspace root (monolith)"
2370
2250
  }
2371
2251
  },
2372
2252
  required: ["boilerplateName", "variables"],
@@ -2379,12 +2259,14 @@ IMPORTANT:
2379
2259
  */
2380
2260
  async execute(args) {
2381
2261
  try {
2382
- const { boilerplateName, variables } = args;
2262
+ const { boilerplateName, variables, monolith, targetFolderOverride } = args;
2383
2263
  if (!boilerplateName) throw new Error("Missing required parameter: boilerplateName");
2384
2264
  if (!variables) throw new Error("Missing required parameter: variables");
2385
2265
  const request = {
2386
2266
  boilerplateName,
2387
- variables
2267
+ variables,
2268
+ monolith,
2269
+ targetFolderOverride
2388
2270
  };
2389
2271
  return { content: [{
2390
2272
  type: "text",
@@ -2447,7 +2329,7 @@ IMPORTANT:
2447
2329
  properties: {
2448
2330
  projectPath: {
2449
2331
  type: "string",
2450
- description: "Absolute path to the project directory containing project.json"
2332
+ description: "Absolute path to the project directory (for monorepo: containing project.json; for monolith: workspace root with toolkit.yaml)"
2451
2333
  },
2452
2334
  scaffold_feature_name: {
2453
2335
  type: "string",
@@ -2594,7 +2476,7 @@ function createServer(options = {}) {
2594
2476
  const scaffoldFeaturePrompt = new ScaffoldFeaturePrompt();
2595
2477
  const server = new __modelcontextprotocol_sdk_server_index_js.Server({
2596
2478
  name: "scaffold-mcp",
2597
- version: "1.0.0"
2479
+ version: "0.4.0"
2598
2480
  }, {
2599
2481
  instructions: `Use this MCP server to create new project and adding a new feature (pages, component, services, etc...).
2600
2482
 
@@ -3112,43 +2994,43 @@ const scaffoldCommand = new commander.Command("scaffold").description("Add featu
3112
2994
  scaffoldCommand.command("list <projectPath>").description("List available scaffolding methods for a project").action(async (projectPath) => {
3113
2995
  try {
3114
2996
  const absolutePath = node_path.default.resolve(projectPath);
3115
- if (!fs_extra.existsSync(node_path.default.join(absolutePath, "project.json"))) {
3116
- messages.error(`No project.json found in ${absolutePath}`);
3117
- messages.hint("Make sure you are in a valid project directory");
2997
+ if (!await __agiflowai_aicode_utils.ProjectConfigResolver.hasConfiguration(absolutePath)) {
2998
+ __agiflowai_aicode_utils.messages.error(`No project configuration found in ${absolutePath}`);
2999
+ __agiflowai_aicode_utils.messages.hint("For monorepo: ensure project.json exists with sourceTemplate field\nFor monolith: ensure toolkit.yaml exists at workspace root");
3118
3000
  process.exit(1);
3119
3001
  }
3120
3002
  const templatesDir = await __agiflowai_aicode_utils.TemplatesManagerService.findTemplatesPath();
3121
3003
  const methods = (await new ScaffoldingMethodsService(new FileSystemService(), templatesDir).listScaffoldingMethods(absolutePath)).methods;
3122
3004
  if (methods.length === 0) {
3123
- messages.warning("No scaffolding methods available for this project.");
3005
+ __agiflowai_aicode_utils.messages.warning("No scaffolding methods available for this project.");
3124
3006
  return;
3125
3007
  }
3126
- print.header(`\n${icons.wrench} Available Scaffolding Methods for ${projectPath}:\n`);
3008
+ __agiflowai_aicode_utils.print.header(`\n${__agiflowai_aicode_utils.icons.wrench} Available Scaffolding Methods for ${projectPath}:\n`);
3127
3009
  for (const method of methods) {
3128
- print.highlight(` ${method.name}`);
3129
- print.debug(` ${method.instruction || method.description || "No description available"}`);
3130
- if (method.variables_schema.required && method.variables_schema.required.length > 0) print.debug(` Required: ${method.variables_schema.required.join(", ")}`);
3131
- print.newline();
3010
+ __agiflowai_aicode_utils.print.highlight(` ${method.name}`);
3011
+ __agiflowai_aicode_utils.print.debug(` ${method.instruction || method.description || "No description available"}`);
3012
+ if (method.variables_schema.required && method.variables_schema.required.length > 0) __agiflowai_aicode_utils.print.debug(` Required: ${method.variables_schema.required.join(", ")}`);
3013
+ __agiflowai_aicode_utils.print.newline();
3132
3014
  }
3133
3015
  } catch (error) {
3134
- messages.error("Error listing scaffolding methods:", error);
3016
+ __agiflowai_aicode_utils.messages.error("Error listing scaffolding methods:", error);
3135
3017
  process.exit(1);
3136
3018
  }
3137
3019
  });
3138
3020
  scaffoldCommand.command("add <featureName>").description("Add a feature to an existing project").option("-p, --project <path>", "Project path", process.cwd()).option("-v, --vars <json>", "JSON string containing variables for the feature").option("--verbose", "Enable verbose logging").action(async (featureName, options) => {
3139
3021
  try {
3140
3022
  const projectPath = node_path.default.resolve(options.project);
3141
- if (!fs_extra.existsSync(node_path.default.join(projectPath, "project.json"))) {
3142
- messages.error(`No project.json found in ${projectPath}`);
3143
- messages.hint("Make sure you are in a valid project directory");
3023
+ if (!await __agiflowai_aicode_utils.ProjectConfigResolver.hasConfiguration(projectPath)) {
3024
+ __agiflowai_aicode_utils.messages.error(`No project configuration found in ${projectPath}`);
3025
+ __agiflowai_aicode_utils.messages.hint("For monorepo: ensure project.json exists with sourceTemplate field\nFor monolith: ensure toolkit.yaml exists at workspace root");
3144
3026
  process.exit(1);
3145
3027
  }
3146
3028
  let variables = {};
3147
3029
  if (options.vars) try {
3148
3030
  variables = JSON.parse(options.vars);
3149
3031
  } catch (error) {
3150
- messages.error("Error parsing variables JSON:", error);
3151
- messages.hint("Example: --vars '{\"componentName\": \"UserProfile\", \"description\": \"User profile component\"}'");
3032
+ __agiflowai_aicode_utils.messages.error("Error parsing variables JSON:", error);
3033
+ __agiflowai_aicode_utils.messages.hint("Example: --vars '{\"componentName\": \"UserProfile\", \"description\": \"User profile component\"}'");
3152
3034
  process.exit(1);
3153
3035
  }
3154
3036
  const templatesDir = await __agiflowai_aicode_utils.TemplatesManagerService.findTemplatesPath();
@@ -3156,55 +3038,55 @@ scaffoldCommand.command("add <featureName>").description("Add a feature to an ex
3156
3038
  const methods = (await scaffoldingMethodsService.listScaffoldingMethods(projectPath)).methods;
3157
3039
  const method = methods.find((m) => m.name === featureName);
3158
3040
  if (!method) {
3159
- messages.error(`Scaffold method '${featureName}' not found.`);
3160
- print.warning(`Available methods: ${methods.map((m) => m.name).join(", ")}`);
3161
- print.debug(`Run 'scaffold-mcp scaffold list ${options.project}' to see all available methods`);
3041
+ __agiflowai_aicode_utils.messages.error(`Scaffold method '${featureName}' not found.`);
3042
+ __agiflowai_aicode_utils.print.warning(`Available methods: ${methods.map((m) => m.name).join(", ")}`);
3043
+ __agiflowai_aicode_utils.print.debug(`Run 'scaffold-mcp scaffold list ${options.project}' to see all available methods`);
3162
3044
  process.exit(1);
3163
3045
  }
3164
3046
  const required = typeof method.variables_schema === "object" && method.variables_schema !== null && "required" in method.variables_schema ? method.variables_schema.required : [];
3165
3047
  const missing = required.filter((key) => !variables[key]);
3166
3048
  if (missing.length > 0) {
3167
- messages.error(`❌ Missing required variables: ${missing.join(", ")}`);
3168
- messages.hint(`💡 Use --vars with a JSON object containing: ${missing.join(", ")}`);
3049
+ __agiflowai_aicode_utils.messages.error(`❌ Missing required variables: ${missing.join(", ")}`);
3050
+ __agiflowai_aicode_utils.messages.hint(`💡 Use --vars with a JSON object containing: ${missing.join(", ")}`);
3169
3051
  const exampleVars = {};
3170
3052
  for (const key of required) if (key.includes("Name")) exampleVars[key] = "MyFeature";
3171
3053
  else if (key === "description") exampleVars[key] = "Feature description";
3172
3054
  else exampleVars[key] = `<${key}>`;
3173
- print.debug(`Example: scaffold-mcp scaffold add ${featureName} --project ${options.project} --vars '${JSON.stringify(exampleVars)}'`);
3055
+ __agiflowai_aicode_utils.print.debug(`Example: scaffold-mcp scaffold add ${featureName} --project ${options.project} --vars '${JSON.stringify(exampleVars)}'`);
3174
3056
  process.exit(1);
3175
3057
  }
3176
3058
  if (options.verbose) {
3177
- print.info(`🔧 Feature: ${featureName}`);
3178
- print.info(`📊 Variables: ${JSON.stringify(variables, null, 2)}`);
3179
- print.info(`📁 Project Path: ${projectPath}`);
3059
+ __agiflowai_aicode_utils.print.info(`🔧 Feature: ${featureName}`);
3060
+ __agiflowai_aicode_utils.print.info(`📊 Variables: ${JSON.stringify(variables, null, 2)}`);
3061
+ __agiflowai_aicode_utils.print.info(`📁 Project Path: ${projectPath}`);
3180
3062
  }
3181
- print.info(`🚀 Adding '${featureName}' to project...`);
3063
+ __agiflowai_aicode_utils.print.info(`🚀 Adding '${featureName}' to project...`);
3182
3064
  const result = await scaffoldingMethodsService.useScaffoldMethod({
3183
3065
  projectPath,
3184
3066
  scaffold_feature_name: featureName,
3185
3067
  variables
3186
3068
  });
3187
3069
  if (result.success) {
3188
- messages.success("✅ Feature added successfully!");
3070
+ __agiflowai_aicode_utils.messages.success("✅ Feature added successfully!");
3189
3071
  console.log(result.message);
3190
3072
  if (result.createdFiles && result.createdFiles.length > 0) {
3191
- print.header("\n📁 Created files:");
3192
- result.createdFiles.forEach((file) => print.debug(` - ${file}`));
3073
+ __agiflowai_aicode_utils.print.header("\n📁 Created files:");
3074
+ result.createdFiles.forEach((file) => __agiflowai_aicode_utils.print.debug(` - ${file}`));
3193
3075
  }
3194
3076
  if (result.warnings && result.warnings.length > 0) {
3195
- messages.warning("\n⚠️ Warnings:");
3196
- result.warnings.forEach((warning) => print.debug(` - ${warning}`));
3077
+ __agiflowai_aicode_utils.messages.warning("\n⚠️ Warnings:");
3078
+ result.warnings.forEach((warning) => __agiflowai_aicode_utils.print.debug(` - ${warning}`));
3197
3079
  }
3198
- print.header("\n📋 Next steps:");
3199
- print.debug(" - Review the generated files");
3200
- print.debug(" - Update imports if necessary");
3201
- print.debug(" - Run tests to ensure everything works");
3080
+ __agiflowai_aicode_utils.print.header("\n📋 Next steps:");
3081
+ __agiflowai_aicode_utils.print.debug(" - Review the generated files");
3082
+ __agiflowai_aicode_utils.print.debug(" - Update imports if necessary");
3083
+ __agiflowai_aicode_utils.print.debug(" - Run tests to ensure everything works");
3202
3084
  } else {
3203
- messages.error(`❌ Failed to add feature: ${result.message}`);
3085
+ __agiflowai_aicode_utils.messages.error(`❌ Failed to add feature: ${result.message}`);
3204
3086
  process.exit(1);
3205
3087
  }
3206
3088
  } catch (error) {
3207
- messages.error(`❌ Error adding feature: ${error.message}`);
3089
+ __agiflowai_aicode_utils.messages.error(`❌ Error adding feature: ${error.message}`);
3208
3090
  if (options.verbose) console.error("Stack trace:", error.stack);
3209
3091
  process.exit(1);
3210
3092
  }
@@ -3212,31 +3094,32 @@ scaffoldCommand.command("add <featureName>").description("Add a feature to an ex
3212
3094
  scaffoldCommand.command("info <featureName>").description("Show detailed information about a scaffold method").option("-p, --project <path>", "Project path", process.cwd()).action(async (featureName, options) => {
3213
3095
  try {
3214
3096
  const projectPath = node_path.default.resolve(options.project);
3215
- if (!fs_extra.existsSync(node_path.default.join(projectPath, "project.json"))) {
3216
- messages.error(`❌ No project.json found in ${projectPath}`);
3097
+ if (!await __agiflowai_aicode_utils.ProjectConfigResolver.hasConfiguration(projectPath)) {
3098
+ __agiflowai_aicode_utils.messages.error(`No project configuration found in ${projectPath}`);
3099
+ __agiflowai_aicode_utils.messages.hint("For monorepo: ensure project.json exists with sourceTemplate field\nFor monolith: ensure toolkit.yaml exists at workspace root");
3217
3100
  process.exit(1);
3218
3101
  }
3219
3102
  const templatesDir = await __agiflowai_aicode_utils.TemplatesManagerService.findTemplatesPath();
3220
3103
  const method = (await new ScaffoldingMethodsService(new FileSystemService(), templatesDir).listScaffoldingMethods(projectPath)).methods.find((m) => m.name === featureName);
3221
3104
  if (!method) {
3222
- messages.error(`❌ Scaffold method '${featureName}' not found.`);
3105
+ __agiflowai_aicode_utils.messages.error(`❌ Scaffold method '${featureName}' not found.`);
3223
3106
  process.exit(1);
3224
3107
  }
3225
- print.header(`\n🔧 Scaffold Method: ${method.name}\n`);
3226
- print.debug(`Description: ${method.description}`);
3227
- print.header("\n📝 Variables Schema:");
3108
+ __agiflowai_aicode_utils.print.header(`\n🔧 Scaffold Method: ${method.name}\n`);
3109
+ __agiflowai_aicode_utils.print.debug(`Description: ${method.description}`);
3110
+ __agiflowai_aicode_utils.print.header("\n📝 Variables Schema:");
3228
3111
  console.log(JSON.stringify(method.variables_schema, null, 2));
3229
3112
  const includes = "includes" in method ? method.includes : [];
3230
3113
  if (includes && includes.length > 0) {
3231
- print.header("\n📁 Files to be created:");
3114
+ __agiflowai_aicode_utils.print.header("\n📁 Files to be created:");
3232
3115
  includes.forEach((include) => {
3233
3116
  const parts = include.split(">>");
3234
- if (parts.length === 2) print.debug(` - ${parts[1].trim()}`);
3235
- else print.debug(` - ${include}`);
3117
+ if (parts.length === 2) __agiflowai_aicode_utils.print.debug(` - ${parts[1].trim()}`);
3118
+ else __agiflowai_aicode_utils.print.debug(` - ${include}`);
3236
3119
  });
3237
3120
  }
3238
3121
  } catch (error) {
3239
- messages.error(`❌ Error getting scaffold info: ${error.message}`);
3122
+ __agiflowai_aicode_utils.messages.error(`❌ Error getting scaffold info: ${error.message}`);
3240
3123
  process.exit(1);
3241
3124
  }
3242
3125
  });
@@ -3248,7 +3131,7 @@ scaffoldCommand.command("info <featureName>").description("Show detailed informa
3248
3131
  */
3249
3132
  async function main() {
3250
3133
  const program = new commander.Command();
3251
- program.name("scaffold-mcp").description("MCP server for scaffolding applications with boilerplate templates").version("1.0.0");
3134
+ program.name("scaffold-mcp").description("MCP server for scaffolding applications with boilerplate templates").version("0.4.0");
3252
3135
  program.addCommand(mcpServeCommand);
3253
3136
  program.addCommand(boilerplateCommand);
3254
3137
  program.addCommand(scaffoldCommand);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agiflowai/scaffold-mcp",
3
3
  "description": "MCP server for scaffolding applications with boilerplate templates",
4
- "version": "0.4.0",
4
+ "version": "0.5.0",
5
5
  "license": "AGPL-3.0",
6
6
  "author": "AgiflowIO",
7
7
  "repository": {
@@ -25,9 +25,9 @@
25
25
  "vite"
26
26
  ],
27
27
  "bin": {
28
- "scaffold-mcp": "./dist/index.js"
28
+ "scaffold-mcp": "./dist/index.cjs"
29
29
  },
30
- "main": "./dist/index.js",
30
+ "main": "./dist/index.cjs",
31
31
  "files": [
32
32
  "dist",
33
33
  "README.md"
@@ -44,7 +44,7 @@
44
44
  "pino": "^10.0.0",
45
45
  "pino-pretty": "^13.1.1",
46
46
  "zod": "3.25.76",
47
- "@agiflowai/aicode-utils": "0.4.0"
47
+ "@agiflowai/aicode-utils": "0.5.0"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/express": "^5.0.0",
@@ -57,6 +57,7 @@
57
57
  "publishConfig": {
58
58
  "access": "public"
59
59
  },
60
+ "type": "module",
60
61
  "scripts": {
61
62
  "dev": "node --loader ts-node/esm src/index.ts",
62
63
  "build": "tsdown",
@@ -1,4 +0,0 @@
1
- require('./logger-qztMS7ET.js');
2
- const require_ScaffoldService = require('./ScaffoldService-BVYY-WWY.js');
3
-
4
- exports.ScaffoldService = require_ScaffoldService.ScaffoldService;
@@ -1,4 +0,0 @@
1
- require('./logger-qztMS7ET.js');
2
- const require_TemplateService = require('./TemplateService-wsvfwvRN.js');
3
-
4
- exports.TemplateService = require_TemplateService.TemplateService;
@@ -1,32 +0,0 @@
1
- const require_chunk = require('./chunk-nOFOJqeH.js');
2
- let node_path = require("node:path");
3
- node_path = require_chunk.__toESM(node_path);
4
- let node_os = require("node:os");
5
- node_os = require_chunk.__toESM(node_os);
6
- let pino = require("pino");
7
- pino = require_chunk.__toESM(pino);
8
-
9
- //#region src/utils/logger.ts
10
- const logsDir = node_path.join(node_os.tmpdir(), "scaffold-mcp-logs");
11
- const logger = (0, pino.default)({
12
- level: process.env.LOG_LEVEL || "debug",
13
- timestamp: pino.default.stdTimeFunctions.isoTime
14
- }, pino.default.destination({
15
- dest: node_path.join(logsDir, "scaffold-mcp.log"),
16
- mkdir: true,
17
- sync: true
18
- }));
19
- const log = {
20
- debug: (msg, ...args) => logger.debug({ args }, msg),
21
- info: (msg, ...args) => logger.info({ args }, msg),
22
- warn: (msg, ...args) => logger.warn({ args }, msg),
23
- error: (msg, ...args) => logger.error({ args }, msg)
24
- };
25
-
26
- //#endregion
27
- Object.defineProperty(exports, 'log', {
28
- enumerable: true,
29
- get: function () {
30
- return log;
31
- }
32
- });
File without changes