@agiflowai/scaffold-mcp 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ScaffoldService-B3En_m4t.cjs +3 -0
- package/dist/{ScaffoldService-B-L4gwHt.cjs → ScaffoldService-BwDmXt83.cjs} +11 -8
- package/dist/ScaffoldService-CJ3vNmAj.js +3 -0
- package/dist/{ScaffoldService-QgQKHMM-.js → ScaffoldService-DB7-Cyod.js} +10 -7
- package/dist/{VariableReplacementService-D8C-IsP-.js → VariableReplacementService-BAwTGv_R.js} +1 -1
- package/dist/{VariableReplacementService-BrJ1PdKm.cjs → VariableReplacementService-CroHkMha.cjs} +1 -1
- package/dist/{VariableReplacementService-BL84vnKk.cjs → VariableReplacementService-D0QnWKUW.cjs} +2 -2
- package/dist/{VariableReplacementService-B3qARIC9.js → VariableReplacementService-DRxd9ILB.js} +1 -1
- package/dist/cli.cjs +147 -731
- package/dist/cli.js +146 -727
- package/dist/index.cjs +142 -8
- package/dist/index.d.cts +28 -12
- package/dist/index.d.ts +28 -12
- package/dist/index.js +133 -3
- package/dist/{stdio-Dmpwju2k.js → stdio-Bxn4A1IU.js} +455 -456
- package/dist/{stdio-Cz5aRdvr.cjs → stdio-TGsG8akc.cjs} +470 -502
- package/package.json +4 -3
- package/dist/ScaffoldService-Cx4ZonaT.cjs +0 -3
- package/dist/ScaffoldService-DVsusUh5.js +0 -3
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,143 @@
|
|
|
1
|
-
const
|
|
1
|
+
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
+
const require_stdio = require('./stdio-TGsG8akc.cjs');
|
|
2
3
|
const require_ScaffoldConfigLoader = require('./ScaffoldConfigLoader-BrmvENTo.cjs');
|
|
3
|
-
const require_ScaffoldService = require('./ScaffoldService-
|
|
4
|
+
const require_ScaffoldService = require('./ScaffoldService-BwDmXt83.cjs');
|
|
4
5
|
const require_TemplateService = require('./TemplateService-DRubcvS9.cjs');
|
|
5
|
-
const require_VariableReplacementService = require('./VariableReplacementService-
|
|
6
|
+
const require_VariableReplacementService = require('./VariableReplacementService-D0QnWKUW.cjs');
|
|
7
|
+
let node_path = require("node:path");
|
|
8
|
+
node_path = require_chunk.__toESM(node_path);
|
|
9
|
+
let fs_extra = require("fs-extra");
|
|
10
|
+
fs_extra = require_chunk.__toESM(fs_extra);
|
|
11
|
+
let execa = require("execa");
|
|
12
|
+
execa = require_chunk.__toESM(execa);
|
|
6
13
|
|
|
14
|
+
//#region src/utils/git.ts
|
|
15
|
+
/**
|
|
16
|
+
* Execute a git command safely using execa to prevent command injection
|
|
17
|
+
*/
|
|
18
|
+
async function execGit(args, cwd) {
|
|
19
|
+
try {
|
|
20
|
+
await (0, execa.execa)("git", args, { cwd });
|
|
21
|
+
} catch (error) {
|
|
22
|
+
const execaError = error;
|
|
23
|
+
throw new Error(`Git command failed: ${execaError.stderr || execaError.message}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Find the workspace root by searching upwards for .git folder
|
|
28
|
+
* Returns null if no .git folder is found (indicating a new project setup is needed)
|
|
29
|
+
*/
|
|
30
|
+
async function findWorkspaceRoot(startPath = process.cwd()) {
|
|
31
|
+
let currentPath = node_path.default.resolve(startPath);
|
|
32
|
+
const rootPath = node_path.default.parse(currentPath).root;
|
|
33
|
+
while (true) {
|
|
34
|
+
const gitPath = node_path.default.join(currentPath, ".git");
|
|
35
|
+
if (await fs_extra.pathExists(gitPath)) return currentPath;
|
|
36
|
+
if (currentPath === rootPath) return null;
|
|
37
|
+
currentPath = node_path.default.dirname(currentPath);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse GitHub URL to detect if it's a subdirectory
|
|
42
|
+
* Supports formats:
|
|
43
|
+
* - https://github.com/user/repo
|
|
44
|
+
* - https://github.com/user/repo/tree/branch/path/to/dir
|
|
45
|
+
* - https://github.com/user/repo/tree/main/path/to/dir
|
|
46
|
+
*/
|
|
47
|
+
function parseGitHubUrl(url) {
|
|
48
|
+
const treeMatch = url.match(/^https?:\/\/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)$/);
|
|
49
|
+
const blobMatch = url.match(/^https?:\/\/github\.com\/([^/]+)\/([^/]+)\/blob\/([^/]+)\/(.+)$/);
|
|
50
|
+
const rootMatch = url.match(/^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?$/);
|
|
51
|
+
if (treeMatch || blobMatch) {
|
|
52
|
+
const match = treeMatch || blobMatch;
|
|
53
|
+
return {
|
|
54
|
+
owner: match?.[1],
|
|
55
|
+
repo: match?.[2],
|
|
56
|
+
repoUrl: `https://github.com/${match?.[1]}/${match?.[2]}.git`,
|
|
57
|
+
branch: match?.[3],
|
|
58
|
+
subdirectory: match?.[4],
|
|
59
|
+
isSubdirectory: true
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (rootMatch) return {
|
|
63
|
+
owner: rootMatch[1],
|
|
64
|
+
repo: rootMatch[2],
|
|
65
|
+
repoUrl: `https://github.com/${rootMatch[1]}/${rootMatch[2]}.git`,
|
|
66
|
+
isSubdirectory: false
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
repoUrl: url,
|
|
70
|
+
isSubdirectory: false
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Clone a subdirectory from a git repository using sparse checkout
|
|
75
|
+
*/
|
|
76
|
+
async function cloneSubdirectory(repoUrl, branch, subdirectory, targetFolder) {
|
|
77
|
+
const tempFolder = `${targetFolder}.tmp`;
|
|
78
|
+
try {
|
|
79
|
+
await execGit(["init", tempFolder]);
|
|
80
|
+
await execGit([
|
|
81
|
+
"remote",
|
|
82
|
+
"add",
|
|
83
|
+
"origin",
|
|
84
|
+
repoUrl
|
|
85
|
+
], tempFolder);
|
|
86
|
+
await execGit([
|
|
87
|
+
"config",
|
|
88
|
+
"core.sparseCheckout",
|
|
89
|
+
"true"
|
|
90
|
+
], tempFolder);
|
|
91
|
+
const sparseCheckoutFile = node_path.default.join(tempFolder, ".git", "info", "sparse-checkout");
|
|
92
|
+
await fs_extra.writeFile(sparseCheckoutFile, `${subdirectory}\n`);
|
|
93
|
+
await execGit([
|
|
94
|
+
"pull",
|
|
95
|
+
"--depth=1",
|
|
96
|
+
"origin",
|
|
97
|
+
branch
|
|
98
|
+
], tempFolder);
|
|
99
|
+
const sourceDir = node_path.default.join(tempFolder, subdirectory);
|
|
100
|
+
if (!await fs_extra.pathExists(sourceDir)) throw new Error(`Subdirectory '${subdirectory}' not found in repository at branch '${branch}'`);
|
|
101
|
+
if (await fs_extra.pathExists(targetFolder)) throw new Error(`Target folder already exists: ${targetFolder}`);
|
|
102
|
+
await fs_extra.move(sourceDir, targetFolder);
|
|
103
|
+
await fs_extra.remove(tempFolder);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
if (await fs_extra.pathExists(tempFolder)) await fs_extra.remove(tempFolder);
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Clone entire repository
|
|
111
|
+
*/
|
|
112
|
+
async function cloneRepository(repoUrl, targetFolder) {
|
|
113
|
+
await execGit([
|
|
114
|
+
"clone",
|
|
115
|
+
repoUrl,
|
|
116
|
+
targetFolder
|
|
117
|
+
]);
|
|
118
|
+
const gitFolder = node_path.default.join(targetFolder, ".git");
|
|
119
|
+
if (await fs_extra.pathExists(gitFolder)) await fs_extra.remove(gitFolder);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Fetch directory listing from GitHub API
|
|
123
|
+
*/
|
|
124
|
+
async function fetchGitHubDirectoryContents(owner, repo, path$1, branch = "main") {
|
|
125
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/contents/${path$1}?ref=${branch}`;
|
|
126
|
+
const response = await fetch(url, { headers: {
|
|
127
|
+
Accept: "application/vnd.github.v3+json",
|
|
128
|
+
"User-Agent": "scaffold-mcp"
|
|
129
|
+
} });
|
|
130
|
+
if (!response.ok) throw new Error(`Failed to fetch directory contents: ${response.statusText}`);
|
|
131
|
+
const data = await response.json();
|
|
132
|
+
if (!Array.isArray(data)) throw new Error("Expected directory but got file");
|
|
133
|
+
return data.map((item) => ({
|
|
134
|
+
name: item.name,
|
|
135
|
+
type: item.type,
|
|
136
|
+
path: item.path
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
//#endregion
|
|
7
141
|
exports.BoilerplateGeneratorService = require_stdio.BoilerplateGeneratorService;
|
|
8
142
|
exports.BoilerplateService = require_stdio.BoilerplateService;
|
|
9
143
|
exports.FileSystemService = require_stdio.FileSystemService;
|
|
@@ -25,8 +159,8 @@ exports.UseBoilerplateTool = require_stdio.UseBoilerplateTool;
|
|
|
25
159
|
exports.UseScaffoldMethodTool = require_stdio.UseScaffoldMethodTool;
|
|
26
160
|
exports.VariableReplacementService = require_VariableReplacementService.VariableReplacementService;
|
|
27
161
|
exports.WriteToFileTool = require_stdio.WriteToFileTool;
|
|
28
|
-
exports.cloneRepository =
|
|
29
|
-
exports.cloneSubdirectory =
|
|
30
|
-
exports.fetchGitHubDirectoryContents =
|
|
31
|
-
exports.findWorkspaceRoot =
|
|
32
|
-
exports.parseGitHubUrl =
|
|
162
|
+
exports.cloneRepository = cloneRepository;
|
|
163
|
+
exports.cloneSubdirectory = cloneSubdirectory;
|
|
164
|
+
exports.fetchGitHubDirectoryContents = fetchGitHubDirectoryContents;
|
|
165
|
+
exports.findWorkspaceRoot = findWorkspaceRoot;
|
|
166
|
+
exports.parseGitHubUrl = parseGitHubUrl;
|
package/dist/index.d.cts
CHANGED
|
@@ -101,7 +101,7 @@ interface BoilerplateInfo {
|
|
|
101
101
|
includes: string[];
|
|
102
102
|
}
|
|
103
103
|
interface UseBoilerplateRequest {
|
|
104
|
-
boilerplateName
|
|
104
|
+
boilerplateName?: string;
|
|
105
105
|
variables: Record<string, any>;
|
|
106
106
|
monolith?: boolean;
|
|
107
107
|
targetFolderOverride?: string;
|
|
@@ -365,6 +365,7 @@ declare class ScaffoldingMethodsService {
|
|
|
365
365
|
private templateService;
|
|
366
366
|
constructor(fileSystem: IFileSystemService, templatesRootPath: string);
|
|
367
367
|
listScaffoldingMethods(projectPath: string): Promise<ListScaffoldingMethodsResult>;
|
|
368
|
+
listScaffoldingMethodsByTemplate(templateName: string): Promise<ListScaffoldingMethodsResult>;
|
|
368
369
|
/**
|
|
369
370
|
* Gets scaffolding methods with instructions rendered using provided variables
|
|
370
371
|
*/
|
|
@@ -374,6 +375,11 @@ declare class ScaffoldingMethodsService {
|
|
|
374
375
|
*/
|
|
375
376
|
processScaffoldInstruction(instruction: string, variables: Record<string, any>): string;
|
|
376
377
|
private findTemplatePath;
|
|
378
|
+
/**
|
|
379
|
+
* Resolves the project path, handling both monorepo and monolith cases
|
|
380
|
+
* Uses ProjectConfigResolver to find the correct workspace/project root
|
|
381
|
+
*/
|
|
382
|
+
private resolveProjectPath;
|
|
377
383
|
/**
|
|
378
384
|
* Dynamically discovers all template directories
|
|
379
385
|
* Supports both flat structure (templates/nextjs-15) and nested structure (templates/apps/nextjs-15)
|
|
@@ -487,7 +493,8 @@ interface ToolDefinition {
|
|
|
487
493
|
declare class GenerateBoilerplateFileTool {
|
|
488
494
|
static readonly TOOL_NAME = "generate-boilerplate-file";
|
|
489
495
|
private boilerplateGeneratorService;
|
|
490
|
-
|
|
496
|
+
private isMonolith;
|
|
497
|
+
constructor(templatesPath: string, isMonolith?: boolean);
|
|
491
498
|
/**
|
|
492
499
|
* Get the tool definition for MCP
|
|
493
500
|
*/
|
|
@@ -496,7 +503,7 @@ declare class GenerateBoilerplateFileTool {
|
|
|
496
503
|
* Execute the tool
|
|
497
504
|
*/
|
|
498
505
|
execute(args: {
|
|
499
|
-
templateName
|
|
506
|
+
templateName?: string;
|
|
500
507
|
filePath: string;
|
|
501
508
|
content?: string;
|
|
502
509
|
sourceFile?: string;
|
|
@@ -511,7 +518,8 @@ declare class GenerateBoilerplateFileTool {
|
|
|
511
518
|
declare class GenerateBoilerplateTool {
|
|
512
519
|
static readonly TOOL_NAME = "generate-boilerplate";
|
|
513
520
|
private boilerplateGeneratorService;
|
|
514
|
-
|
|
521
|
+
private isMonolith;
|
|
522
|
+
constructor(templatesPath: string, isMonolith?: boolean);
|
|
515
523
|
/**
|
|
516
524
|
* Get the tool definition for MCP
|
|
517
525
|
*/
|
|
@@ -520,11 +528,11 @@ declare class GenerateBoilerplateTool {
|
|
|
520
528
|
* Execute the tool
|
|
521
529
|
*/
|
|
522
530
|
execute(args: {
|
|
523
|
-
templateName
|
|
531
|
+
templateName?: string;
|
|
524
532
|
boilerplateName: string;
|
|
525
533
|
description: string;
|
|
526
534
|
instruction?: string;
|
|
527
|
-
targetFolder
|
|
535
|
+
targetFolder?: string;
|
|
528
536
|
variables: Array<{
|
|
529
537
|
name: string;
|
|
530
538
|
description: string;
|
|
@@ -543,7 +551,8 @@ declare class GenerateBoilerplateTool {
|
|
|
543
551
|
declare class GenerateFeatureScaffoldTool {
|
|
544
552
|
static readonly TOOL_NAME = "generate-feature-scaffold";
|
|
545
553
|
private scaffoldGeneratorService;
|
|
546
|
-
|
|
554
|
+
private isMonolith;
|
|
555
|
+
constructor(templatesPath: string, isMonolith?: boolean);
|
|
547
556
|
/**
|
|
548
557
|
* Get the tool definition for MCP
|
|
549
558
|
*/
|
|
@@ -552,7 +561,7 @@ declare class GenerateFeatureScaffoldTool {
|
|
|
552
561
|
* Execute the tool
|
|
553
562
|
*/
|
|
554
563
|
execute(args: {
|
|
555
|
-
templateName
|
|
564
|
+
templateName?: string;
|
|
556
565
|
featureName: string;
|
|
557
566
|
description: string;
|
|
558
567
|
instruction?: string;
|
|
@@ -572,7 +581,9 @@ declare class GenerateFeatureScaffoldTool {
|
|
|
572
581
|
declare class ListBoilerplatesTool {
|
|
573
582
|
static readonly TOOL_NAME = "list-boilerplates";
|
|
574
583
|
private boilerplateService;
|
|
575
|
-
|
|
584
|
+
private templateService;
|
|
585
|
+
private isMonolith;
|
|
586
|
+
constructor(templatesPath: string, isMonolith?: boolean);
|
|
576
587
|
/**
|
|
577
588
|
* Get the tool definition for MCP
|
|
578
589
|
*/
|
|
@@ -588,7 +599,9 @@ declare class ListScaffoldingMethodsTool {
|
|
|
588
599
|
static readonly TOOL_NAME = "list-scaffolding-methods";
|
|
589
600
|
private fileSystemService;
|
|
590
601
|
private scaffoldingMethodsService;
|
|
591
|
-
|
|
602
|
+
private templateService;
|
|
603
|
+
private isMonolith;
|
|
604
|
+
constructor(templatesPath: string, isMonolith?: boolean);
|
|
592
605
|
/**
|
|
593
606
|
* Get the tool definition for MCP
|
|
594
607
|
*/
|
|
@@ -603,7 +616,9 @@ declare class ListScaffoldingMethodsTool {
|
|
|
603
616
|
declare class UseBoilerplateTool {
|
|
604
617
|
static readonly TOOL_NAME = "use-boilerplate";
|
|
605
618
|
private boilerplateService;
|
|
606
|
-
|
|
619
|
+
private templateService;
|
|
620
|
+
private isMonolith;
|
|
621
|
+
constructor(templatesPath: string, isMonolith?: boolean);
|
|
607
622
|
/**
|
|
608
623
|
* Get the tool definition for MCP
|
|
609
624
|
*/
|
|
@@ -619,7 +634,8 @@ declare class UseScaffoldMethodTool {
|
|
|
619
634
|
static readonly TOOL_NAME = "use-scaffold-method";
|
|
620
635
|
private fileSystemService;
|
|
621
636
|
private scaffoldingMethodsService;
|
|
622
|
-
|
|
637
|
+
private isMonolith;
|
|
638
|
+
constructor(templatesPath: string, isMonolith?: boolean);
|
|
623
639
|
/**
|
|
624
640
|
* Get the tool definition for MCP
|
|
625
641
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -102,7 +102,7 @@ interface BoilerplateInfo {
|
|
|
102
102
|
includes: string[];
|
|
103
103
|
}
|
|
104
104
|
interface UseBoilerplateRequest {
|
|
105
|
-
boilerplateName
|
|
105
|
+
boilerplateName?: string;
|
|
106
106
|
variables: Record<string, any>;
|
|
107
107
|
monolith?: boolean;
|
|
108
108
|
targetFolderOverride?: string;
|
|
@@ -366,6 +366,7 @@ declare class ScaffoldingMethodsService {
|
|
|
366
366
|
private templateService;
|
|
367
367
|
constructor(fileSystem: IFileSystemService, templatesRootPath: string);
|
|
368
368
|
listScaffoldingMethods(projectPath: string): Promise<ListScaffoldingMethodsResult>;
|
|
369
|
+
listScaffoldingMethodsByTemplate(templateName: string): Promise<ListScaffoldingMethodsResult>;
|
|
369
370
|
/**
|
|
370
371
|
* Gets scaffolding methods with instructions rendered using provided variables
|
|
371
372
|
*/
|
|
@@ -375,6 +376,11 @@ declare class ScaffoldingMethodsService {
|
|
|
375
376
|
*/
|
|
376
377
|
processScaffoldInstruction(instruction: string, variables: Record<string, any>): string;
|
|
377
378
|
private findTemplatePath;
|
|
379
|
+
/**
|
|
380
|
+
* Resolves the project path, handling both monorepo and monolith cases
|
|
381
|
+
* Uses ProjectConfigResolver to find the correct workspace/project root
|
|
382
|
+
*/
|
|
383
|
+
private resolveProjectPath;
|
|
378
384
|
/**
|
|
379
385
|
* Dynamically discovers all template directories
|
|
380
386
|
* Supports both flat structure (templates/nextjs-15) and nested structure (templates/apps/nextjs-15)
|
|
@@ -488,7 +494,8 @@ interface ToolDefinition {
|
|
|
488
494
|
declare class GenerateBoilerplateFileTool {
|
|
489
495
|
static readonly TOOL_NAME = "generate-boilerplate-file";
|
|
490
496
|
private boilerplateGeneratorService;
|
|
491
|
-
|
|
497
|
+
private isMonolith;
|
|
498
|
+
constructor(templatesPath: string, isMonolith?: boolean);
|
|
492
499
|
/**
|
|
493
500
|
* Get the tool definition for MCP
|
|
494
501
|
*/
|
|
@@ -497,7 +504,7 @@ declare class GenerateBoilerplateFileTool {
|
|
|
497
504
|
* Execute the tool
|
|
498
505
|
*/
|
|
499
506
|
execute(args: {
|
|
500
|
-
templateName
|
|
507
|
+
templateName?: string;
|
|
501
508
|
filePath: string;
|
|
502
509
|
content?: string;
|
|
503
510
|
sourceFile?: string;
|
|
@@ -512,7 +519,8 @@ declare class GenerateBoilerplateFileTool {
|
|
|
512
519
|
declare class GenerateBoilerplateTool {
|
|
513
520
|
static readonly TOOL_NAME = "generate-boilerplate";
|
|
514
521
|
private boilerplateGeneratorService;
|
|
515
|
-
|
|
522
|
+
private isMonolith;
|
|
523
|
+
constructor(templatesPath: string, isMonolith?: boolean);
|
|
516
524
|
/**
|
|
517
525
|
* Get the tool definition for MCP
|
|
518
526
|
*/
|
|
@@ -521,11 +529,11 @@ declare class GenerateBoilerplateTool {
|
|
|
521
529
|
* Execute the tool
|
|
522
530
|
*/
|
|
523
531
|
execute(args: {
|
|
524
|
-
templateName
|
|
532
|
+
templateName?: string;
|
|
525
533
|
boilerplateName: string;
|
|
526
534
|
description: string;
|
|
527
535
|
instruction?: string;
|
|
528
|
-
targetFolder
|
|
536
|
+
targetFolder?: string;
|
|
529
537
|
variables: Array<{
|
|
530
538
|
name: string;
|
|
531
539
|
description: string;
|
|
@@ -544,7 +552,8 @@ declare class GenerateBoilerplateTool {
|
|
|
544
552
|
declare class GenerateFeatureScaffoldTool {
|
|
545
553
|
static readonly TOOL_NAME = "generate-feature-scaffold";
|
|
546
554
|
private scaffoldGeneratorService;
|
|
547
|
-
|
|
555
|
+
private isMonolith;
|
|
556
|
+
constructor(templatesPath: string, isMonolith?: boolean);
|
|
548
557
|
/**
|
|
549
558
|
* Get the tool definition for MCP
|
|
550
559
|
*/
|
|
@@ -553,7 +562,7 @@ declare class GenerateFeatureScaffoldTool {
|
|
|
553
562
|
* Execute the tool
|
|
554
563
|
*/
|
|
555
564
|
execute(args: {
|
|
556
|
-
templateName
|
|
565
|
+
templateName?: string;
|
|
557
566
|
featureName: string;
|
|
558
567
|
description: string;
|
|
559
568
|
instruction?: string;
|
|
@@ -573,7 +582,9 @@ declare class GenerateFeatureScaffoldTool {
|
|
|
573
582
|
declare class ListBoilerplatesTool {
|
|
574
583
|
static readonly TOOL_NAME = "list-boilerplates";
|
|
575
584
|
private boilerplateService;
|
|
576
|
-
|
|
585
|
+
private templateService;
|
|
586
|
+
private isMonolith;
|
|
587
|
+
constructor(templatesPath: string, isMonolith?: boolean);
|
|
577
588
|
/**
|
|
578
589
|
* Get the tool definition for MCP
|
|
579
590
|
*/
|
|
@@ -589,7 +600,9 @@ declare class ListScaffoldingMethodsTool {
|
|
|
589
600
|
static readonly TOOL_NAME = "list-scaffolding-methods";
|
|
590
601
|
private fileSystemService;
|
|
591
602
|
private scaffoldingMethodsService;
|
|
592
|
-
|
|
603
|
+
private templateService;
|
|
604
|
+
private isMonolith;
|
|
605
|
+
constructor(templatesPath: string, isMonolith?: boolean);
|
|
593
606
|
/**
|
|
594
607
|
* Get the tool definition for MCP
|
|
595
608
|
*/
|
|
@@ -604,7 +617,9 @@ declare class ListScaffoldingMethodsTool {
|
|
|
604
617
|
declare class UseBoilerplateTool {
|
|
605
618
|
static readonly TOOL_NAME = "use-boilerplate";
|
|
606
619
|
private boilerplateService;
|
|
607
|
-
|
|
620
|
+
private templateService;
|
|
621
|
+
private isMonolith;
|
|
622
|
+
constructor(templatesPath: string, isMonolith?: boolean);
|
|
608
623
|
/**
|
|
609
624
|
* Get the tool definition for MCP
|
|
610
625
|
*/
|
|
@@ -620,7 +635,8 @@ declare class UseScaffoldMethodTool {
|
|
|
620
635
|
static readonly TOOL_NAME = "use-scaffold-method";
|
|
621
636
|
private fileSystemService;
|
|
622
637
|
private scaffoldingMethodsService;
|
|
623
|
-
|
|
638
|
+
private isMonolith;
|
|
639
|
+
constructor(templatesPath: string, isMonolith?: boolean);
|
|
624
640
|
/**
|
|
625
641
|
* Get the tool definition for MCP
|
|
626
642
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,137 @@
|
|
|
1
|
-
import { BoilerplateGeneratorService, BoilerplateService, FileSystemService, GenerateBoilerplateFileTool, GenerateBoilerplateTool, GenerateFeatureScaffoldTool, HttpTransportHandler, ListBoilerplatesTool, ListScaffoldingMethodsTool, ScaffoldGeneratorService, ScaffoldingMethodsService, SseTransportHandler, StdioTransportHandler, UseBoilerplateTool, UseScaffoldMethodTool, WriteToFileTool
|
|
1
|
+
import { BoilerplateGeneratorService, BoilerplateService, FileSystemService, GenerateBoilerplateFileTool, GenerateBoilerplateTool, GenerateFeatureScaffoldTool, HttpTransportHandler, ListBoilerplatesTool, ListScaffoldingMethodsTool, ScaffoldGeneratorService, ScaffoldingMethodsService, SseTransportHandler, StdioTransportHandler, UseBoilerplateTool, UseScaffoldMethodTool, WriteToFileTool } from "./stdio-Bxn4A1IU.js";
|
|
2
2
|
import { ScaffoldConfigLoader } from "./ScaffoldConfigLoader-CI0T6zdG.js";
|
|
3
|
-
import { ScaffoldProcessingService, ScaffoldService } from "./ScaffoldService-
|
|
3
|
+
import { ScaffoldProcessingService, ScaffoldService } from "./ScaffoldService-DB7-Cyod.js";
|
|
4
4
|
import { TemplateService } from "./TemplateService-CiZJA06s.js";
|
|
5
|
-
import { VariableReplacementService } from "./VariableReplacementService-
|
|
5
|
+
import { VariableReplacementService } from "./VariableReplacementService-DRxd9ILB.js";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import * as fs$1 from "fs-extra";
|
|
8
|
+
import { execa } from "execa";
|
|
6
9
|
|
|
10
|
+
//#region src/utils/git.ts
|
|
11
|
+
/**
|
|
12
|
+
* Execute a git command safely using execa to prevent command injection
|
|
13
|
+
*/
|
|
14
|
+
async function execGit(args, cwd) {
|
|
15
|
+
try {
|
|
16
|
+
await execa("git", args, { cwd });
|
|
17
|
+
} catch (error) {
|
|
18
|
+
const execaError = error;
|
|
19
|
+
throw new Error(`Git command failed: ${execaError.stderr || execaError.message}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Find the workspace root by searching upwards for .git folder
|
|
24
|
+
* Returns null if no .git folder is found (indicating a new project setup is needed)
|
|
25
|
+
*/
|
|
26
|
+
async function findWorkspaceRoot(startPath = process.cwd()) {
|
|
27
|
+
let currentPath = path.resolve(startPath);
|
|
28
|
+
const rootPath = path.parse(currentPath).root;
|
|
29
|
+
while (true) {
|
|
30
|
+
const gitPath = path.join(currentPath, ".git");
|
|
31
|
+
if (await fs$1.pathExists(gitPath)) return currentPath;
|
|
32
|
+
if (currentPath === rootPath) return null;
|
|
33
|
+
currentPath = path.dirname(currentPath);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Parse GitHub URL to detect if it's a subdirectory
|
|
38
|
+
* Supports formats:
|
|
39
|
+
* - https://github.com/user/repo
|
|
40
|
+
* - https://github.com/user/repo/tree/branch/path/to/dir
|
|
41
|
+
* - https://github.com/user/repo/tree/main/path/to/dir
|
|
42
|
+
*/
|
|
43
|
+
function parseGitHubUrl(url) {
|
|
44
|
+
const treeMatch = url.match(/^https?:\/\/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)$/);
|
|
45
|
+
const blobMatch = url.match(/^https?:\/\/github\.com\/([^/]+)\/([^/]+)\/blob\/([^/]+)\/(.+)$/);
|
|
46
|
+
const rootMatch = url.match(/^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?$/);
|
|
47
|
+
if (treeMatch || blobMatch) {
|
|
48
|
+
const match = treeMatch || blobMatch;
|
|
49
|
+
return {
|
|
50
|
+
owner: match?.[1],
|
|
51
|
+
repo: match?.[2],
|
|
52
|
+
repoUrl: `https://github.com/${match?.[1]}/${match?.[2]}.git`,
|
|
53
|
+
branch: match?.[3],
|
|
54
|
+
subdirectory: match?.[4],
|
|
55
|
+
isSubdirectory: true
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (rootMatch) return {
|
|
59
|
+
owner: rootMatch[1],
|
|
60
|
+
repo: rootMatch[2],
|
|
61
|
+
repoUrl: `https://github.com/${rootMatch[1]}/${rootMatch[2]}.git`,
|
|
62
|
+
isSubdirectory: false
|
|
63
|
+
};
|
|
64
|
+
return {
|
|
65
|
+
repoUrl: url,
|
|
66
|
+
isSubdirectory: false
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Clone a subdirectory from a git repository using sparse checkout
|
|
71
|
+
*/
|
|
72
|
+
async function cloneSubdirectory(repoUrl, branch, subdirectory, targetFolder) {
|
|
73
|
+
const tempFolder = `${targetFolder}.tmp`;
|
|
74
|
+
try {
|
|
75
|
+
await execGit(["init", tempFolder]);
|
|
76
|
+
await execGit([
|
|
77
|
+
"remote",
|
|
78
|
+
"add",
|
|
79
|
+
"origin",
|
|
80
|
+
repoUrl
|
|
81
|
+
], tempFolder);
|
|
82
|
+
await execGit([
|
|
83
|
+
"config",
|
|
84
|
+
"core.sparseCheckout",
|
|
85
|
+
"true"
|
|
86
|
+
], tempFolder);
|
|
87
|
+
const sparseCheckoutFile = path.join(tempFolder, ".git", "info", "sparse-checkout");
|
|
88
|
+
await fs$1.writeFile(sparseCheckoutFile, `${subdirectory}\n`);
|
|
89
|
+
await execGit([
|
|
90
|
+
"pull",
|
|
91
|
+
"--depth=1",
|
|
92
|
+
"origin",
|
|
93
|
+
branch
|
|
94
|
+
], tempFolder);
|
|
95
|
+
const sourceDir = path.join(tempFolder, subdirectory);
|
|
96
|
+
if (!await fs$1.pathExists(sourceDir)) throw new Error(`Subdirectory '${subdirectory}' not found in repository at branch '${branch}'`);
|
|
97
|
+
if (await fs$1.pathExists(targetFolder)) throw new Error(`Target folder already exists: ${targetFolder}`);
|
|
98
|
+
await fs$1.move(sourceDir, targetFolder);
|
|
99
|
+
await fs$1.remove(tempFolder);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
if (await fs$1.pathExists(tempFolder)) await fs$1.remove(tempFolder);
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Clone entire repository
|
|
107
|
+
*/
|
|
108
|
+
async function cloneRepository(repoUrl, targetFolder) {
|
|
109
|
+
await execGit([
|
|
110
|
+
"clone",
|
|
111
|
+
repoUrl,
|
|
112
|
+
targetFolder
|
|
113
|
+
]);
|
|
114
|
+
const gitFolder = path.join(targetFolder, ".git");
|
|
115
|
+
if (await fs$1.pathExists(gitFolder)) await fs$1.remove(gitFolder);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Fetch directory listing from GitHub API
|
|
119
|
+
*/
|
|
120
|
+
async function fetchGitHubDirectoryContents(owner, repo, path$1, branch = "main") {
|
|
121
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/contents/${path$1}?ref=${branch}`;
|
|
122
|
+
const response = await fetch(url, { headers: {
|
|
123
|
+
Accept: "application/vnd.github.v3+json",
|
|
124
|
+
"User-Agent": "scaffold-mcp"
|
|
125
|
+
} });
|
|
126
|
+
if (!response.ok) throw new Error(`Failed to fetch directory contents: ${response.statusText}`);
|
|
127
|
+
const data = await response.json();
|
|
128
|
+
if (!Array.isArray(data)) throw new Error("Expected directory but got file");
|
|
129
|
+
return data.map((item) => ({
|
|
130
|
+
name: item.name,
|
|
131
|
+
type: item.type,
|
|
132
|
+
path: item.path
|
|
133
|
+
}));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
//#endregion
|
|
7
137
|
export { BoilerplateGeneratorService, BoilerplateService, FileSystemService, GenerateBoilerplateFileTool, GenerateBoilerplateTool, GenerateFeatureScaffoldTool, HttpTransportHandler, ListBoilerplatesTool, ListScaffoldingMethodsTool, ScaffoldConfigLoader, ScaffoldGeneratorService, ScaffoldProcessingService, ScaffoldService, ScaffoldingMethodsService, SseTransportHandler, StdioTransportHandler, TemplateService, UseBoilerplateTool, UseScaffoldMethodTool, VariableReplacementService, WriteToFileTool, cloneRepository, cloneSubdirectory, fetchGitHubDirectoryContents, findWorkspaceRoot, parseGitHubUrl };
|