@agiflowai/scaffold-mcp 1.0.6 → 1.0.8
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 +202 -164
- package/dist/ListScaffoldingMethodsTool-BLTCwsd1.mjs +350 -0
- package/dist/ListScaffoldingMethodsTool-BuxKRbwi.cjs +376 -0
- package/dist/{ScaffoldConfigLoader-B-NLy6VP.cjs → ScaffoldConfigLoader-BB4_YUFL.cjs} +1 -1
- package/dist/{ScaffoldConfigLoader-SHk-KEje.mjs → ScaffoldConfigLoader-DKJtnrWT.mjs} +1 -1
- package/dist/ScaffoldService-BCjJE9yK.mjs +3 -0
- package/dist/ScaffoldService-Bhzxp5-C.cjs +3 -0
- package/dist/TemplateService-B1bd6iHw.mjs +3 -0
- package/dist/TemplateService-BrJGDvQt.cjs +3 -0
- package/dist/VariableReplacementService-BO-UYgcf.mjs +3 -0
- package/dist/{VariableReplacementService-DKaF2C9l.cjs → VariableReplacementService-CNimgwaq.cjs} +1 -1
- package/dist/cli.cjs +89 -11
- package/dist/cli.mjs +84 -6
- package/dist/index.cjs +9 -8
- package/dist/index.d.cts +7 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.mjs +6 -5
- package/dist/{stdio-BGj_FLky.cjs → stdio-BcTSxlVH.cjs} +47 -367
- package/dist/{stdio-wAlpLC6l.mjs → stdio-DovjJsGY.mjs} +42 -347
- package/dist/useScaffoldMethod-Btc_9iCj.cjs +237 -0
- package/dist/useScaffoldMethod-C1hQdBVD.cjs +267 -0
- package/dist/useScaffoldMethod-CHJAsgA2.mjs +236 -0
- package/dist/useScaffoldMethod-CsBTssSw.mjs +263 -0
- package/package.json +6 -2
- package/dist/ScaffoldService-BNOyoqSb.cjs +0 -3
- package/dist/ScaffoldService-BNdfC21Z.mjs +0 -3
- package/dist/TemplateService-BRfzfaZs.mjs +0 -3
- package/dist/TemplateService-DqieT1Tq.cjs +0 -3
- package/dist/VariableReplacementService-BWCd-z7X.mjs +0 -3
- /package/dist/{ScaffoldConfigLoader-BDMJNI1o.mjs → ScaffoldConfigLoader-8YI7v2GJ.mjs} +0 -0
- /package/dist/{ScaffoldConfigLoader-Y_SBLPg7.cjs → ScaffoldConfigLoader-CQlXVksz.cjs} +0 -0
- /package/dist/{ScaffoldService-ChzxM0Yc.cjs → ScaffoldService-BPyiY_0B.cjs} +0 -0
- /package/dist/{ScaffoldService-BNuN00Fm.mjs → ScaffoldService-CgYunbKN.mjs} +0 -0
- /package/dist/{TemplateService-D3ydJR_R.cjs → TemplateService-CAD8jkoO.cjs} +0 -0
- /package/dist/{TemplateService-Cg5QV29n.mjs → TemplateService-CVDL2uqt.mjs} +0 -0
- /package/dist/{VariableReplacementService-DHIINRnJ.mjs → VariableReplacementService-B9RA8D0a.mjs} +0 -0
- /package/dist/{VariableReplacementService-CAjesAYq.cjs → VariableReplacementService-DDG5KZpb.cjs} +0 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
+
const require_TemplateService = require('./TemplateService-CAD8jkoO.cjs');
|
|
3
|
+
let node_path = require("node:path");
|
|
4
|
+
node_path = require_chunk.__toESM(node_path);
|
|
5
|
+
let __agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
|
|
6
|
+
let js_yaml = require("js-yaml");
|
|
7
|
+
js_yaml = require_chunk.__toESM(js_yaml);
|
|
8
|
+
|
|
9
|
+
//#region src/utils/pagination.ts
|
|
10
|
+
var PaginationHelper = class PaginationHelper {
|
|
11
|
+
/**
|
|
12
|
+
* Default page size for pagination
|
|
13
|
+
*/
|
|
14
|
+
static DEFAULT_PAGE_SIZE = 10;
|
|
15
|
+
/**
|
|
16
|
+
* Decodes a cursor string to extract the start index
|
|
17
|
+
* @param cursor - String representing the start index (e.g., "10")
|
|
18
|
+
* @returns Start index or 0 if invalid/undefined
|
|
19
|
+
*/
|
|
20
|
+
static decodeCursor(cursor) {
|
|
21
|
+
if (!cursor) return 0;
|
|
22
|
+
const index = Number.parseInt(cursor, 10);
|
|
23
|
+
if (Number.isNaN(index) || index < 0) return 0;
|
|
24
|
+
return index;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Encodes an index into a cursor string
|
|
28
|
+
* @param index - Start index to encode
|
|
29
|
+
* @returns Cursor string (e.g., "10")
|
|
30
|
+
*/
|
|
31
|
+
static encodeCursor(index) {
|
|
32
|
+
return index.toString();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Paginates an array of items
|
|
36
|
+
* @param items - All items to paginate
|
|
37
|
+
* @param cursor - Optional cursor representing the start index
|
|
38
|
+
* @param pageSize - Number of items per page (default: 10)
|
|
39
|
+
* @param includeMeta - Whether to include metadata in response (default: true)
|
|
40
|
+
* @returns Paginated result with items and optional nextCursor
|
|
41
|
+
*/
|
|
42
|
+
static paginate(items, cursor, pageSize = PaginationHelper.DEFAULT_PAGE_SIZE, includeMeta = true) {
|
|
43
|
+
const startIndex = PaginationHelper.decodeCursor(cursor);
|
|
44
|
+
const endIndex = startIndex + pageSize;
|
|
45
|
+
const result = {
|
|
46
|
+
items: items.slice(startIndex, endIndex),
|
|
47
|
+
nextCursor: endIndex < items.length ? PaginationHelper.encodeCursor(endIndex) : void 0
|
|
48
|
+
};
|
|
49
|
+
if (includeMeta) result._meta = {
|
|
50
|
+
total: items.length,
|
|
51
|
+
offset: startIndex,
|
|
52
|
+
limit: pageSize
|
|
53
|
+
};
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/services/FileSystemService.ts
|
|
60
|
+
var FileSystemService = class {
|
|
61
|
+
async pathExists(path$1) {
|
|
62
|
+
return (0, __agiflowai_aicode_utils.pathExists)(path$1);
|
|
63
|
+
}
|
|
64
|
+
async readFile(path$1, encoding = "utf8") {
|
|
65
|
+
return (0, __agiflowai_aicode_utils.readFile)(path$1, encoding);
|
|
66
|
+
}
|
|
67
|
+
async readJson(path$1) {
|
|
68
|
+
return (0, __agiflowai_aicode_utils.readJson)(path$1);
|
|
69
|
+
}
|
|
70
|
+
async writeFile(path$1, content, encoding = "utf8") {
|
|
71
|
+
return (0, __agiflowai_aicode_utils.writeFile)(path$1, content, encoding);
|
|
72
|
+
}
|
|
73
|
+
async ensureDir(path$1) {
|
|
74
|
+
return (0, __agiflowai_aicode_utils.ensureDir)(path$1);
|
|
75
|
+
}
|
|
76
|
+
async copy(src, dest) {
|
|
77
|
+
return (0, __agiflowai_aicode_utils.copy)(src, dest);
|
|
78
|
+
}
|
|
79
|
+
async readdir(path$1) {
|
|
80
|
+
return (0, __agiflowai_aicode_utils.readdir)(path$1);
|
|
81
|
+
}
|
|
82
|
+
async stat(path$1) {
|
|
83
|
+
return (0, __agiflowai_aicode_utils.stat)(path$1);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/services/ScaffoldingMethodsService.ts
|
|
89
|
+
var ScaffoldingMethodsService = class {
|
|
90
|
+
templateService;
|
|
91
|
+
constructor(fileSystem, templatesRootPath) {
|
|
92
|
+
this.fileSystem = fileSystem;
|
|
93
|
+
this.templatesRootPath = templatesRootPath;
|
|
94
|
+
this.templateService = new require_TemplateService.TemplateService();
|
|
95
|
+
}
|
|
96
|
+
async listScaffoldingMethods(projectPath, cursor) {
|
|
97
|
+
const absoluteProjectPath = node_path.default.resolve(projectPath);
|
|
98
|
+
const sourceTemplate = (await __agiflowai_aicode_utils.ProjectConfigResolver.resolveProjectConfig(absoluteProjectPath)).sourceTemplate;
|
|
99
|
+
return this.listScaffoldingMethodsByTemplate(sourceTemplate, cursor);
|
|
100
|
+
}
|
|
101
|
+
async listScaffoldingMethodsByTemplate(templateName, cursor) {
|
|
102
|
+
const templatePath = await this.findTemplatePath(templateName);
|
|
103
|
+
if (!templatePath) throw new Error(`Template not found for sourceTemplate: ${templateName}`);
|
|
104
|
+
const fullTemplatePath = node_path.default.join(this.templatesRootPath, templatePath);
|
|
105
|
+
const scaffoldYamlPath = node_path.default.join(fullTemplatePath, "scaffold.yaml");
|
|
106
|
+
if (!await this.fileSystem.pathExists(scaffoldYamlPath)) throw new Error(`scaffold.yaml not found at ${scaffoldYamlPath}`);
|
|
107
|
+
const scaffoldContent = await this.fileSystem.readFile(scaffoldYamlPath, "utf8");
|
|
108
|
+
const architectConfig = js_yaml.default.load(scaffoldContent);
|
|
109
|
+
const methods = [];
|
|
110
|
+
if (architectConfig.features && Array.isArray(architectConfig.features)) architectConfig.features.forEach((feature) => {
|
|
111
|
+
const featureName = feature.name || `scaffold-${templateName}`;
|
|
112
|
+
methods.push({
|
|
113
|
+
name: featureName,
|
|
114
|
+
description: feature.description || "",
|
|
115
|
+
instruction: feature.instruction || "",
|
|
116
|
+
variables_schema: feature.variables_schema || {
|
|
117
|
+
type: "object",
|
|
118
|
+
properties: {},
|
|
119
|
+
required: [],
|
|
120
|
+
additionalProperties: false
|
|
121
|
+
},
|
|
122
|
+
generator: feature.generator
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
const paginatedResult = PaginationHelper.paginate(methods, cursor);
|
|
126
|
+
return {
|
|
127
|
+
sourceTemplate: templateName,
|
|
128
|
+
templatePath,
|
|
129
|
+
methods: paginatedResult.items,
|
|
130
|
+
nextCursor: paginatedResult.nextCursor,
|
|
131
|
+
_meta: paginatedResult._meta
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Gets scaffolding methods with instructions rendered using provided variables
|
|
136
|
+
*/
|
|
137
|
+
async listScaffoldingMethodsWithVariables(projectPath, variables, cursor) {
|
|
138
|
+
const result = await this.listScaffoldingMethods(projectPath, cursor);
|
|
139
|
+
const processedMethods = result.methods.map((method) => ({
|
|
140
|
+
...method,
|
|
141
|
+
instruction: method.instruction ? this.processScaffoldInstruction(method.instruction, variables) : void 0
|
|
142
|
+
}));
|
|
143
|
+
return {
|
|
144
|
+
...result,
|
|
145
|
+
methods: processedMethods
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Processes scaffold instruction with template service
|
|
150
|
+
*/
|
|
151
|
+
processScaffoldInstruction(instruction, variables) {
|
|
152
|
+
if (this.templateService.containsTemplateVariables(instruction)) return this.templateService.renderString(instruction, variables);
|
|
153
|
+
return instruction;
|
|
154
|
+
}
|
|
155
|
+
async findTemplatePath(sourceTemplate) {
|
|
156
|
+
const templateDirs = await this.discoverTemplateDirs();
|
|
157
|
+
if (templateDirs.includes(sourceTemplate)) return sourceTemplate;
|
|
158
|
+
for (const templateDir of templateDirs) {
|
|
159
|
+
const templatePath = node_path.default.join(this.templatesRootPath, templateDir);
|
|
160
|
+
const scaffoldYamlPath = node_path.default.join(templatePath, "scaffold.yaml");
|
|
161
|
+
if (await this.fileSystem.pathExists(scaffoldYamlPath)) try {
|
|
162
|
+
const scaffoldContent = await this.fileSystem.readFile(scaffoldYamlPath, "utf8");
|
|
163
|
+
const architectConfig = js_yaml.default.load(scaffoldContent);
|
|
164
|
+
if (architectConfig.boilerplate && Array.isArray(architectConfig.boilerplate)) {
|
|
165
|
+
for (const boilerplate of architectConfig.boilerplate) if (boilerplate.name?.includes(sourceTemplate)) return templateDir;
|
|
166
|
+
}
|
|
167
|
+
} catch (error) {
|
|
168
|
+
__agiflowai_aicode_utils.log.warn(`Failed to read scaffold.yaml at ${scaffoldYamlPath}:`, error);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Resolves the project path, handling both monorepo and monolith cases
|
|
175
|
+
* Uses ProjectConfigResolver to find the correct workspace/project root
|
|
176
|
+
*/
|
|
177
|
+
async resolveProjectPath(projectPath) {
|
|
178
|
+
const absolutePath = node_path.default.resolve(projectPath);
|
|
179
|
+
return (await __agiflowai_aicode_utils.ProjectConfigResolver.resolveProjectConfig(absolutePath)).workspaceRoot || absolutePath;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Dynamically discovers all template directories
|
|
183
|
+
* Supports both flat structure (templates/nextjs-15) and nested structure (templates/apps/nextjs-15)
|
|
184
|
+
**/
|
|
185
|
+
async discoverTemplateDirs() {
|
|
186
|
+
const templateDirs = [];
|
|
187
|
+
try {
|
|
188
|
+
const items = await this.fileSystem.readdir(this.templatesRootPath);
|
|
189
|
+
for (const item of items) {
|
|
190
|
+
const itemPath = node_path.default.join(this.templatesRootPath, item);
|
|
191
|
+
if (!(await this.fileSystem.stat(itemPath)).isDirectory()) continue;
|
|
192
|
+
const scaffoldYamlPath = node_path.default.join(itemPath, "scaffold.yaml");
|
|
193
|
+
if (await this.fileSystem.pathExists(scaffoldYamlPath)) {
|
|
194
|
+
templateDirs.push(item);
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
const subItems = await this.fileSystem.readdir(itemPath);
|
|
199
|
+
for (const subItem of subItems) {
|
|
200
|
+
const subItemPath = node_path.default.join(itemPath, subItem);
|
|
201
|
+
if (!(await this.fileSystem.stat(subItemPath)).isDirectory()) continue;
|
|
202
|
+
const subScaffoldYamlPath = node_path.default.join(subItemPath, "scaffold.yaml");
|
|
203
|
+
if (await this.fileSystem.pathExists(subScaffoldYamlPath)) {
|
|
204
|
+
const relativePath = node_path.default.join(item, subItem);
|
|
205
|
+
templateDirs.push(relativePath);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
} catch (error) {
|
|
209
|
+
__agiflowai_aicode_utils.log.warn(`Failed to read subdirectories in ${itemPath}:`, error);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
} catch (error) {
|
|
213
|
+
__agiflowai_aicode_utils.log.warn(`Failed to read templates root directory ${this.templatesRootPath}:`, error);
|
|
214
|
+
}
|
|
215
|
+
return templateDirs;
|
|
216
|
+
}
|
|
217
|
+
async useScaffoldMethod(request) {
|
|
218
|
+
const { projectPath, scaffold_feature_name, variables, sessionId } = request;
|
|
219
|
+
const absoluteProjectPath = await this.resolveProjectPath(projectPath);
|
|
220
|
+
const scaffoldingMethods = await this.listScaffoldingMethods(absoluteProjectPath);
|
|
221
|
+
const method = scaffoldingMethods.methods.find((m) => m.name === scaffold_feature_name);
|
|
222
|
+
if (!method) {
|
|
223
|
+
const availableMethods = scaffoldingMethods.methods.map((m) => m.name).join(", ");
|
|
224
|
+
throw new Error(`Scaffold method '${scaffold_feature_name}' not found. Available methods: ${availableMethods}`);
|
|
225
|
+
}
|
|
226
|
+
const ScaffoldService = (await Promise.resolve().then(() => require("./ScaffoldService-Bhzxp5-C.cjs"))).ScaffoldService;
|
|
227
|
+
const ScaffoldConfigLoader = (await Promise.resolve().then(() => require("./ScaffoldConfigLoader-BB4_YUFL.cjs"))).ScaffoldConfigLoader;
|
|
228
|
+
const VariableReplacementService = (await Promise.resolve().then(() => require("./VariableReplacementService-CNimgwaq.cjs"))).VariableReplacementService;
|
|
229
|
+
const TemplateService$1 = (await Promise.resolve().then(() => require("./TemplateService-BrJGDvQt.cjs"))).TemplateService;
|
|
230
|
+
const templateService = new TemplateService$1();
|
|
231
|
+
const scaffoldConfigLoader = new ScaffoldConfigLoader(this.fileSystem, templateService);
|
|
232
|
+
const variableReplacer = new VariableReplacementService(this.fileSystem, templateService);
|
|
233
|
+
const scaffoldService = new ScaffoldService(this.fileSystem, scaffoldConfigLoader, variableReplacer, this.templatesRootPath);
|
|
234
|
+
const projectName = node_path.default.basename(absoluteProjectPath);
|
|
235
|
+
const result = await scaffoldService.useFeature({
|
|
236
|
+
projectPath: absoluteProjectPath,
|
|
237
|
+
templateFolder: scaffoldingMethods.templatePath,
|
|
238
|
+
featureName: scaffold_feature_name,
|
|
239
|
+
variables: {
|
|
240
|
+
...variables,
|
|
241
|
+
appPath: absoluteProjectPath,
|
|
242
|
+
appName: projectName
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
if (!result.success) throw new Error(result.message);
|
|
246
|
+
if (sessionId && result.createdFiles && result.createdFiles.length > 0) try {
|
|
247
|
+
const { ExecutionLogService, DECISION_ALLOW } = await import("@agiflowai/hooks-adapter");
|
|
248
|
+
await new ExecutionLogService(sessionId).logExecution({
|
|
249
|
+
filePath: absoluteProjectPath,
|
|
250
|
+
operation: "scaffold",
|
|
251
|
+
decision: DECISION_ALLOW,
|
|
252
|
+
generatedFiles: result.createdFiles
|
|
253
|
+
});
|
|
254
|
+
} catch (error) {
|
|
255
|
+
__agiflowai_aicode_utils.log.warn("Failed to log scaffold execution:", error);
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
success: true,
|
|
259
|
+
message: `
|
|
260
|
+
Successfully scaffolded ${scaffold_feature_name} in ${projectPath}.
|
|
261
|
+
Please follow this **instruction**: \n ${method.instruction ? this.processScaffoldInstruction(method.instruction, variables) : ""}.
|
|
262
|
+
-> Create or update the plan based on the instruction.
|
|
263
|
+
`,
|
|
264
|
+
warnings: result.warnings,
|
|
265
|
+
createdFiles: result.createdFiles,
|
|
266
|
+
existingFiles: result.existingFiles
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
//#endregion
|
|
272
|
+
//#region src/instructions/tools/list-scaffolding-methods/description.md?raw
|
|
273
|
+
var description_default = "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";
|
|
274
|
+
|
|
275
|
+
//#endregion
|
|
276
|
+
//#region src/tools/ListScaffoldingMethodsTool.ts
|
|
277
|
+
var ListScaffoldingMethodsTool = class ListScaffoldingMethodsTool {
|
|
278
|
+
static TOOL_NAME = "list-scaffolding-methods";
|
|
279
|
+
fileSystemService;
|
|
280
|
+
scaffoldingMethodsService;
|
|
281
|
+
templateService;
|
|
282
|
+
isMonolith;
|
|
283
|
+
constructor(templatesPath, isMonolith = false) {
|
|
284
|
+
this.fileSystemService = new FileSystemService();
|
|
285
|
+
this.scaffoldingMethodsService = new ScaffoldingMethodsService(this.fileSystemService, templatesPath);
|
|
286
|
+
this.templateService = new require_TemplateService.TemplateService();
|
|
287
|
+
this.isMonolith = isMonolith;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Get the tool definition for MCP
|
|
291
|
+
*/
|
|
292
|
+
getDefinition() {
|
|
293
|
+
const description = this.templateService.renderString(description_default, { isMonolith: this.isMonolith });
|
|
294
|
+
const properties = { cursor: {
|
|
295
|
+
type: "string",
|
|
296
|
+
description: "Optional pagination cursor to fetch the next page of results. Omit to fetch the first page."
|
|
297
|
+
} };
|
|
298
|
+
if (!this.isMonolith) {
|
|
299
|
+
properties.projectPath = {
|
|
300
|
+
type: "string",
|
|
301
|
+
description: "Absolute path to the project directory (for monorepo: containing project.json; for monolith: workspace root with toolkit.yaml). Either projectPath or templateName is required."
|
|
302
|
+
};
|
|
303
|
+
properties.templateName = {
|
|
304
|
+
type: "string",
|
|
305
|
+
description: "Name of the template to list scaffolding methods for (e.g., \"nextjs-15\", \"typescript-mcp-package\"). Either projectPath or templateName is required."
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
return {
|
|
309
|
+
name: ListScaffoldingMethodsTool.TOOL_NAME,
|
|
310
|
+
description: description.trim(),
|
|
311
|
+
inputSchema: {
|
|
312
|
+
type: "object",
|
|
313
|
+
properties,
|
|
314
|
+
additionalProperties: false
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Execute the tool
|
|
320
|
+
*/
|
|
321
|
+
async execute(args) {
|
|
322
|
+
try {
|
|
323
|
+
const { projectPath, templateName, cursor } = args;
|
|
324
|
+
let result;
|
|
325
|
+
if (this.isMonolith) try {
|
|
326
|
+
const resolvedTemplateName = (await __agiflowai_aicode_utils.ProjectConfigResolver.resolveProjectConfig(process.cwd())).sourceTemplate;
|
|
327
|
+
result = await this.scaffoldingMethodsService.listScaffoldingMethodsByTemplate(resolvedTemplateName, cursor);
|
|
328
|
+
} catch (error) {
|
|
329
|
+
throw new Error(`Failed to read template name from configuration: ${error instanceof Error ? error.message : String(error)}`);
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
if (!projectPath && !templateName) throw new Error("Either projectPath or templateName must be provided");
|
|
333
|
+
if (projectPath) result = await this.scaffoldingMethodsService.listScaffoldingMethods(projectPath, cursor);
|
|
334
|
+
else result = await this.scaffoldingMethodsService.listScaffoldingMethodsByTemplate(templateName, cursor);
|
|
335
|
+
}
|
|
336
|
+
return { content: [{
|
|
337
|
+
type: "text",
|
|
338
|
+
text: JSON.stringify(result, null, 2)
|
|
339
|
+
}] };
|
|
340
|
+
} catch (error) {
|
|
341
|
+
return {
|
|
342
|
+
content: [{
|
|
343
|
+
type: "text",
|
|
344
|
+
text: `Error listing scaffolding methods: ${error instanceof Error ? error.message : String(error)}`
|
|
345
|
+
}],
|
|
346
|
+
isError: true
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
//#endregion
|
|
353
|
+
Object.defineProperty(exports, 'FileSystemService', {
|
|
354
|
+
enumerable: true,
|
|
355
|
+
get: function () {
|
|
356
|
+
return FileSystemService;
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
Object.defineProperty(exports, 'ListScaffoldingMethodsTool', {
|
|
360
|
+
enumerable: true,
|
|
361
|
+
get: function () {
|
|
362
|
+
return ListScaffoldingMethodsTool;
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
Object.defineProperty(exports, 'PaginationHelper', {
|
|
366
|
+
enumerable: true,
|
|
367
|
+
get: function () {
|
|
368
|
+
return PaginationHelper;
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
Object.defineProperty(exports, 'ScaffoldingMethodsService', {
|
|
372
|
+
enumerable: true,
|
|
373
|
+
get: function () {
|
|
374
|
+
return ScaffoldingMethodsService;
|
|
375
|
+
}
|
|
376
|
+
});
|
package/dist/{VariableReplacementService-DKaF2C9l.cjs → VariableReplacementService-CNimgwaq.cjs}
RENAMED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
const require_VariableReplacementService = require('./VariableReplacementService-
|
|
1
|
+
const require_VariableReplacementService = require('./VariableReplacementService-DDG5KZpb.cjs');
|
|
2
2
|
|
|
3
3
|
exports.VariableReplacementService = require_VariableReplacementService.VariableReplacementService;
|
package/dist/cli.cjs
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
3
|
-
const require_stdio = require('./stdio-
|
|
4
|
-
require('./
|
|
5
|
-
require('./
|
|
6
|
-
|
|
7
|
-
require('./
|
|
3
|
+
const require_stdio = require('./stdio-BcTSxlVH.cjs');
|
|
4
|
+
const require_ListScaffoldingMethodsTool = require('./ListScaffoldingMethodsTool-BuxKRbwi.cjs');
|
|
5
|
+
require('./ScaffoldConfigLoader-CQlXVksz.cjs');
|
|
6
|
+
require('./ScaffoldService-BPyiY_0B.cjs');
|
|
7
|
+
const require_TemplateService = require('./TemplateService-CAD8jkoO.cjs');
|
|
8
|
+
require('./VariableReplacementService-DDG5KZpb.cjs');
|
|
8
9
|
let node_path = require("node:path");
|
|
9
10
|
node_path = require_chunk.__toESM(node_path);
|
|
10
11
|
let __agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
|
|
11
12
|
let __modelcontextprotocol_sdk_types_js = require("@modelcontextprotocol/sdk/types.js");
|
|
12
13
|
let commander = require("commander");
|
|
13
14
|
let __modelcontextprotocol_sdk_server_index_js = require("@modelcontextprotocol/sdk/server/index.js");
|
|
15
|
+
let __agiflowai_coding_agent_bridge = require("@agiflowai/coding-agent-bridge");
|
|
16
|
+
let __agiflowai_hooks_adapter = require("@agiflowai/hooks-adapter");
|
|
14
17
|
|
|
15
18
|
//#region package.json
|
|
16
|
-
var version = "1.0.
|
|
19
|
+
var version = "1.0.7";
|
|
17
20
|
|
|
18
21
|
//#endregion
|
|
19
22
|
//#region src/commands/boilerplate.ts
|
|
@@ -344,7 +347,7 @@ function createServer(options = {}) {
|
|
|
344
347
|
const templatesPath = __agiflowai_aicode_utils.TemplatesManagerService.findTemplatesPathSync();
|
|
345
348
|
const listBoilerplatesTool = !isMonolith ? new require_stdio.ListBoilerplatesTool(templatesPath, isMonolith) : null;
|
|
346
349
|
const useBoilerplateTool = !isMonolith ? new require_stdio.UseBoilerplateTool(templatesPath, isMonolith) : null;
|
|
347
|
-
const listScaffoldingMethodsTool = new
|
|
350
|
+
const listScaffoldingMethodsTool = new require_ListScaffoldingMethodsTool.ListScaffoldingMethodsTool(templatesPath, isMonolith);
|
|
348
351
|
const useScaffoldMethodTool = new require_stdio.UseScaffoldMethodTool(templatesPath, isMonolith);
|
|
349
352
|
const writeToFileTool = new require_stdio.WriteToFileTool();
|
|
350
353
|
const generateBoilerplateTool = adminEnabled ? new require_stdio.GenerateBoilerplateTool(templatesPath, isMonolith) : null;
|
|
@@ -395,7 +398,7 @@ function createServer(options = {}) {
|
|
|
395
398
|
if (isMonolith || !useBoilerplateTool) throw new Error("Boilerplate tools are not available for monolith projects");
|
|
396
399
|
return await useBoilerplateTool.execute(args || {});
|
|
397
400
|
}
|
|
398
|
-
if (name ===
|
|
401
|
+
if (name === require_ListScaffoldingMethodsTool.ListScaffoldingMethodsTool.TOOL_NAME) return await listScaffoldingMethodsTool.execute(args || {});
|
|
399
402
|
if (name === require_stdio.UseScaffoldMethodTool.TOOL_NAME) return await useScaffoldMethodTool.execute(args || {});
|
|
400
403
|
if (name === require_stdio.WriteToFileTool.TOOL_NAME) return await writeToFileTool.execute(args || {});
|
|
401
404
|
if (name === require_stdio.GenerateBoilerplateTool.TOOL_NAME) {
|
|
@@ -525,7 +528,7 @@ scaffoldCommand.command("list [projectPath]").description("List available scaffo
|
|
|
525
528
|
process.exit(1);
|
|
526
529
|
}
|
|
527
530
|
const templatesDir = await __agiflowai_aicode_utils.TemplatesManagerService.findTemplatesPath();
|
|
528
|
-
const scaffoldingMethodsService = new
|
|
531
|
+
const scaffoldingMethodsService = new require_ListScaffoldingMethodsTool.ScaffoldingMethodsService(new require_ListScaffoldingMethodsTool.FileSystemService(), templatesDir);
|
|
529
532
|
let result;
|
|
530
533
|
let displayName;
|
|
531
534
|
if (projectPath) {
|
|
@@ -582,7 +585,7 @@ scaffoldCommand.command("add <featureName>").description("Add a feature to an ex
|
|
|
582
585
|
process.exit(1);
|
|
583
586
|
}
|
|
584
587
|
const templatesDir = await __agiflowai_aicode_utils.TemplatesManagerService.findTemplatesPath();
|
|
585
|
-
const scaffoldingMethodsService = new
|
|
588
|
+
const scaffoldingMethodsService = new require_ListScaffoldingMethodsTool.ScaffoldingMethodsService(new require_ListScaffoldingMethodsTool.FileSystemService(), templatesDir);
|
|
586
589
|
let allMethods = [];
|
|
587
590
|
let cursor;
|
|
588
591
|
do {
|
|
@@ -653,7 +656,7 @@ scaffoldCommand.command("info <featureName>").description("Show detailed informa
|
|
|
653
656
|
process.exit(1);
|
|
654
657
|
}
|
|
655
658
|
const templatesDir = await __agiflowai_aicode_utils.TemplatesManagerService.findTemplatesPath();
|
|
656
|
-
const scaffoldingMethodsService = new
|
|
659
|
+
const scaffoldingMethodsService = new require_ListScaffoldingMethodsTool.ScaffoldingMethodsService(new require_ListScaffoldingMethodsTool.FileSystemService(), templatesDir);
|
|
657
660
|
let allMethods = [];
|
|
658
661
|
let cursor;
|
|
659
662
|
if (options.project) {
|
|
@@ -697,6 +700,80 @@ scaffoldCommand.command("info <featureName>").description("Show detailed informa
|
|
|
697
700
|
}
|
|
698
701
|
});
|
|
699
702
|
|
|
703
|
+
//#endregion
|
|
704
|
+
//#region src/commands/hook.ts
|
|
705
|
+
/**
|
|
706
|
+
* Hook Command
|
|
707
|
+
*
|
|
708
|
+
* DESIGN PATTERNS:
|
|
709
|
+
* - Command pattern with Commander for CLI argument parsing
|
|
710
|
+
* - Async/await pattern for asynchronous operations
|
|
711
|
+
* - Error handling pattern with try-catch and proper exit codes
|
|
712
|
+
*
|
|
713
|
+
* CODING STANDARDS:
|
|
714
|
+
* - Use async action handlers for asynchronous operations
|
|
715
|
+
* - Provide clear option descriptions and default values
|
|
716
|
+
* - Handle errors gracefully with process.exit()
|
|
717
|
+
* - Log progress and errors to console
|
|
718
|
+
* - Use Commander's .option() for inputs
|
|
719
|
+
*
|
|
720
|
+
* AVOID:
|
|
721
|
+
* - Synchronous blocking operations in action handlers
|
|
722
|
+
* - Missing error handling (always use try-catch)
|
|
723
|
+
* - Hardcoded values (use options or environment variables)
|
|
724
|
+
* - Not exiting with appropriate exit codes on errors
|
|
725
|
+
*/
|
|
726
|
+
/**
|
|
727
|
+
* Hook command for executing scaffold hooks
|
|
728
|
+
*/
|
|
729
|
+
const hookCommand = new commander.Command("hook").description("Execute scaffold hooks for AI agent integrations").option("--type <agentAndMethod>", "Hook type: <agent>.<method> (e.g., claude-code.postToolUse, gemini-cli.afterTool)").action(async (options) => {
|
|
730
|
+
try {
|
|
731
|
+
if (!options.type) {
|
|
732
|
+
__agiflowai_aicode_utils.print.error("--type option is required");
|
|
733
|
+
__agiflowai_aicode_utils.print.info("Examples:");
|
|
734
|
+
__agiflowai_aicode_utils.print.info(" scaffold hook --type claude-code.preToolUse");
|
|
735
|
+
__agiflowai_aicode_utils.print.info(" scaffold hook --type claude-code.postToolUse");
|
|
736
|
+
__agiflowai_aicode_utils.print.info(" scaffold hook --type gemini-cli.beforeTool");
|
|
737
|
+
__agiflowai_aicode_utils.print.info(" scaffold hook --type gemini-cli.afterTool");
|
|
738
|
+
process.exit(1);
|
|
739
|
+
}
|
|
740
|
+
const { agent, hookMethod } = (0, __agiflowai_hooks_adapter.parseHookType)(options.type);
|
|
741
|
+
if (agent === __agiflowai_coding_agent_bridge.CLAUDE_CODE) {
|
|
742
|
+
const useScaffoldMethodModule = await Promise.resolve().then(() => require("./useScaffoldMethod-C1hQdBVD.cjs"));
|
|
743
|
+
const claudeCallbacks = [];
|
|
744
|
+
if (useScaffoldMethodModule.UseScaffoldMethodHook) {
|
|
745
|
+
const hookInstance = new useScaffoldMethodModule.UseScaffoldMethodHook();
|
|
746
|
+
const hookFn = hookInstance[hookMethod];
|
|
747
|
+
if (hookFn) claudeCallbacks.push(hookFn.bind(hookInstance));
|
|
748
|
+
}
|
|
749
|
+
if (claudeCallbacks.length === 0) {
|
|
750
|
+
__agiflowai_aicode_utils.print.error(`Hook not found: ${hookMethod} in Claude Code hooks`);
|
|
751
|
+
process.exit(1);
|
|
752
|
+
}
|
|
753
|
+
await new __agiflowai_hooks_adapter.ClaudeCodeAdapter().executeMultiple(claudeCallbacks);
|
|
754
|
+
} else if (agent === __agiflowai_coding_agent_bridge.GEMINI_CLI) {
|
|
755
|
+
const useScaffoldMethodModule = await Promise.resolve().then(() => require("./useScaffoldMethod-Btc_9iCj.cjs"));
|
|
756
|
+
const geminiCallbacks = [];
|
|
757
|
+
if (useScaffoldMethodModule.UseScaffoldMethodHook) {
|
|
758
|
+
const hookInstance = new useScaffoldMethodModule.UseScaffoldMethodHook();
|
|
759
|
+
const hookFn = hookInstance[hookMethod];
|
|
760
|
+
if (hookFn) geminiCallbacks.push(hookFn.bind(hookInstance));
|
|
761
|
+
}
|
|
762
|
+
if (geminiCallbacks.length === 0) {
|
|
763
|
+
__agiflowai_aicode_utils.print.error(`Hook not found: ${hookMethod} in Gemini CLI hooks`);
|
|
764
|
+
process.exit(1);
|
|
765
|
+
}
|
|
766
|
+
await new __agiflowai_hooks_adapter.GeminiCliAdapter().executeMultiple(geminiCallbacks);
|
|
767
|
+
} else {
|
|
768
|
+
__agiflowai_aicode_utils.print.error(`Unsupported agent: ${agent}. Supported: ${__agiflowai_coding_agent_bridge.CLAUDE_CODE}, ${__agiflowai_coding_agent_bridge.GEMINI_CLI}`);
|
|
769
|
+
process.exit(1);
|
|
770
|
+
}
|
|
771
|
+
} catch (error) {
|
|
772
|
+
__agiflowai_aicode_utils.print.error(`Hook error: ${error.message}`);
|
|
773
|
+
process.exit(1);
|
|
774
|
+
}
|
|
775
|
+
});
|
|
776
|
+
|
|
700
777
|
//#endregion
|
|
701
778
|
//#region src/cli.ts
|
|
702
779
|
/**
|
|
@@ -708,6 +785,7 @@ async function main() {
|
|
|
708
785
|
program.addCommand(mcpServeCommand);
|
|
709
786
|
program.addCommand(boilerplateCommand);
|
|
710
787
|
program.addCommand(scaffoldCommand);
|
|
788
|
+
program.addCommand(hookCommand);
|
|
711
789
|
await program.parseAsync(process.argv);
|
|
712
790
|
}
|
|
713
791
|
main();
|