@decaf-ts/mcp-server 0.0.3 → 0.2.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 +18 -2
- package/dist/mcp-server.cjs +1989 -341
- package/dist/mcp-server.esm.cjs +1963 -338
- package/lib/McpWrapper.cjs +12 -10
- package/lib/McpWrapper.d.ts +1 -1
- package/lib/bin/validate-modules.cjs +24 -0
- package/lib/bin/validate-modules.d.ts +2 -0
- package/lib/constants.cjs +22 -2
- package/lib/constants.d.ts +16 -0
- package/lib/esm/McpWrapper.d.ts +1 -1
- package/lib/esm/McpWrapper.js +12 -10
- package/lib/esm/bin/validate-modules.d.ts +2 -0
- package/lib/esm/bin/validate-modules.js +22 -0
- package/lib/esm/constants.d.ts +16 -0
- package/lib/esm/constants.js +21 -1
- package/lib/esm/mcp/aggregateModules.d.ts +26 -0
- package/lib/esm/mcp/aggregateModules.js +185 -0
- package/lib/esm/mcp/code.d.ts +23 -0
- package/lib/esm/mcp/code.js +70 -0
- package/lib/esm/mcp/decorator-tools.js +237 -0
- package/lib/esm/mcp/fastmcp-wiring.d.ts +14 -0
- package/lib/esm/mcp/fastmcp-wiring.js +56 -0
- package/lib/esm/mcp/index.d.ts +7 -1
- package/lib/esm/mcp/index.js +26 -2
- package/lib/esm/mcp/mcp-module.d.ts +11 -0
- package/lib/esm/mcp/mcp-module.js +31 -0
- package/lib/esm/mcp/moduleRegistry.d.ts +12 -0
- package/lib/esm/mcp/moduleRegistry.js +46 -0
- package/lib/esm/mcp/prompts/index.d.ts +4 -0
- package/lib/esm/mcp/prompts/index.js +7 -0
- package/lib/esm/mcp/prompts/prompts.d.ts +22 -0
- package/lib/esm/mcp/prompts/prompts.js +197 -0
- package/lib/esm/mcp/resources/index.d.ts +1 -0
- package/lib/esm/mcp/resources/index.js +2 -0
- package/lib/esm/mcp/resources/resources.d.ts +2 -0
- package/lib/esm/mcp/resources/resources.js +69 -0
- package/lib/esm/mcp/schemas.d.ts +53 -0
- package/lib/esm/mcp/schemas.js +97 -0
- package/lib/esm/mcp/templates/codex-templates.d.ts +3 -0
- package/lib/esm/mcp/templates/codex-templates.js +33 -0
- package/lib/esm/mcp/templates/index.d.ts +71 -0
- package/lib/esm/mcp/templates/index.js +66 -0
- package/lib/esm/mcp/templates/resource-templates.d.ts +3 -0
- package/lib/esm/mcp/templates/resource-templates.js +60 -0
- package/lib/esm/mcp/templates/workspace-templates.d.ts +3 -0
- package/lib/esm/mcp/templates/workspace-templates.js +66 -0
- package/lib/esm/mcp/tools/codex-tools.d.ts +5 -0
- package/lib/esm/mcp/tools/codex-tools.js +244 -0
- package/lib/esm/mcp/tools/generateMcpModule.d.ts +9 -0
- package/lib/esm/mcp/tools/generateMcpModule.js +133 -0
- package/lib/esm/mcp/tools/index.d.ts +321 -0
- package/lib/esm/mcp/tools/index.js +29 -0
- package/lib/esm/mcp/tools/tools.d.ts +10 -0
- package/lib/esm/mcp/tools/tools.js +273 -0
- package/lib/esm/mcp/types.d.ts +66 -0
- package/lib/esm/mcp/types.js +2 -0
- package/lib/esm/mcp/utils.d.ts +4 -0
- package/lib/esm/mcp/utils.js +46 -0
- package/lib/esm/mcp/validation/index.d.ts +13 -0
- package/lib/esm/mcp/validation/index.js +116 -0
- package/lib/esm/mcp/validation/scaffoldModule.d.ts +9 -0
- package/lib/esm/mcp/validation/scaffoldModule.js +88 -0
- package/lib/esm/mcp/workspace.d.ts +9 -0
- package/lib/esm/mcp/workspace.js +73 -0
- package/lib/esm/metadata.d.ts +1 -1
- package/lib/esm/metadata.js +1 -1
- package/lib/esm/modules/_template/index.d.ts +32 -0
- package/lib/esm/modules/_template/index.js +16 -0
- package/lib/esm/modules/_template/prompts/index.d.ts +6 -0
- package/lib/esm/modules/_template/prompts/index.js +9 -0
- package/lib/esm/modules/_template/resources/index.d.ts +6 -0
- package/lib/esm/modules/_template/resources/index.js +9 -0
- package/lib/esm/modules/_template/templates/index.d.ts +7 -0
- package/lib/esm/modules/_template/templates/index.js +10 -0
- package/lib/esm/modules/_template/tools/index.d.ts +6 -0
- package/lib/esm/modules/_template/tools/index.js +15 -0
- package/lib/esm/modules/decoration/index.d.ts +46 -0
- package/lib/esm/modules/decoration/index.js +10 -2
- package/lib/esm/modules/decoration/prompts/index.d.ts +1 -0
- package/lib/esm/modules/decoration/prompts/index.js +2 -0
- package/lib/esm/modules/decoration/resources/index.d.ts +7 -0
- package/lib/esm/modules/decoration/resources/index.js +10 -0
- package/lib/esm/modules/decoration/templates/index.d.ts +6 -0
- package/lib/esm/modules/decoration/templates/index.js +9 -0
- package/lib/esm/modules/decoration/tools/index.d.ts +26 -0
- package/lib/esm/modules/decoration/tools/index.js +7 -0
- package/lib/esm/modules/index.d.ts +2 -0
- package/lib/esm/modules/index.js +10 -0
- package/lib/esm/modules/mcp/decoration-assist.d.ts +4 -0
- package/lib/esm/modules/mcp/decoration-assist.js +6 -0
- package/lib/esm/modules/mcp/index.d.ts +6 -2
- package/lib/esm/modules/mcp/index.js +16 -3
- package/lib/esm/modules/mcp/prompts/index.d.ts +2 -0
- package/lib/esm/modules/mcp/prompts/index.js +9 -0
- package/lib/esm/modules/mcp/resources/index.d.ts +2 -0
- package/lib/esm/modules/mcp/resources/index.js +24 -0
- package/lib/esm/modules/mcp/templates/index.d.ts +2 -0
- package/lib/esm/modules/mcp/templates/index.js +28 -0
- package/lib/esm/modules/mcp/tools/index.d.ts +6 -0
- package/lib/esm/modules/mcp/tools/index.js +15 -0
- package/lib/esm/types.d.ts +41 -1
- package/lib/esm/types.js +1 -1
- package/lib/esm/utils/modulePaths.d.ts +6 -0
- package/lib/esm/utils/modulePaths.js +33 -0
- package/lib/esm/utils/moduleValidator.d.ts +14 -0
- package/lib/esm/utils/moduleValidator.js +176 -0
- package/lib/esm/utils.d.ts +1 -0
- package/lib/esm/utils.js +2 -1
- package/lib/mcp/aggregateModules.cjs +225 -0
- package/lib/mcp/aggregateModules.d.ts +26 -0
- package/lib/mcp/code.cjs +81 -0
- package/lib/mcp/code.d.ts +23 -0
- package/lib/mcp/decorator-tools.cjs +243 -0
- package/lib/mcp/fastmcp-wiring.cjs +59 -0
- package/lib/mcp/fastmcp-wiring.d.ts +14 -0
- package/lib/mcp/index.cjs +47 -12
- package/lib/mcp/index.d.ts +7 -1
- package/lib/mcp/mcp-module.cjs +53 -0
- package/lib/mcp/mcp-module.d.ts +11 -0
- package/lib/mcp/moduleRegistry.cjs +50 -0
- package/lib/mcp/moduleRegistry.d.ts +12 -0
- package/lib/mcp/prompts/index.cjs +25 -0
- package/lib/mcp/prompts/index.d.ts +4 -0
- package/lib/mcp/prompts/prompts.cjs +211 -0
- package/lib/mcp/prompts/prompts.d.ts +22 -0
- package/lib/mcp/resources/index.cjs +18 -0
- package/lib/mcp/resources/index.d.ts +1 -0
- package/lib/mcp/resources/resources.cjs +72 -0
- package/lib/mcp/resources/resources.d.ts +2 -0
- package/lib/mcp/schemas.cjs +100 -0
- package/lib/mcp/schemas.d.ts +53 -0
- package/lib/mcp/templates/codex-templates.cjs +40 -0
- package/lib/mcp/templates/codex-templates.d.ts +3 -0
- package/lib/mcp/templates/index.cjs +76 -0
- package/lib/mcp/templates/index.d.ts +71 -0
- package/lib/mcp/templates/resource-templates.cjs +67 -0
- package/lib/mcp/templates/resource-templates.d.ts +3 -0
- package/lib/mcp/templates/workspace-templates.cjs +70 -0
- package/lib/mcp/templates/workspace-templates.d.ts +3 -0
- package/lib/mcp/tools/codex-tools.cjs +250 -0
- package/lib/mcp/tools/codex-tools.d.ts +5 -0
- package/lib/mcp/tools/generateMcpModule.cjs +139 -0
- package/lib/mcp/tools/generateMcpModule.d.ts +9 -0
- package/lib/mcp/tools/index.cjs +46 -0
- package/lib/mcp/tools/index.d.ts +321 -0
- package/lib/mcp/tools/tools.cjs +282 -0
- package/lib/mcp/tools/tools.d.ts +10 -0
- package/lib/mcp/types.cjs +3 -0
- package/lib/mcp/types.d.ts +66 -0
- package/lib/mcp/utils.cjs +54 -0
- package/lib/mcp/utils.d.ts +4 -0
- package/lib/mcp/validation/index.cjs +123 -0
- package/lib/mcp/validation/index.d.ts +13 -0
- package/lib/mcp/validation/scaffoldModule.cjs +94 -0
- package/lib/mcp/validation/scaffoldModule.d.ts +9 -0
- package/lib/mcp/workspace.cjs +119 -0
- package/lib/mcp/workspace.d.ts +9 -0
- package/lib/metadata.cjs +1 -1
- package/lib/metadata.d.ts +1 -1
- package/lib/modules/_template/index.cjs +23 -0
- package/lib/modules/_template/index.d.ts +32 -0
- package/lib/modules/_template/prompts/index.cjs +12 -0
- package/lib/modules/_template/prompts/index.d.ts +6 -0
- package/lib/modules/_template/resources/index.cjs +12 -0
- package/lib/modules/_template/resources/index.d.ts +6 -0
- package/lib/modules/_template/templates/index.cjs +13 -0
- package/lib/modules/_template/templates/index.d.ts +7 -0
- package/lib/modules/_template/tools/index.cjs +18 -0
- package/lib/modules/_template/tools/index.d.ts +6 -0
- package/lib/modules/decoration/index.cjs +16 -1
- package/lib/modules/decoration/index.d.ts +46 -0
- package/lib/modules/decoration/prompts/index.cjs +5 -0
- package/lib/modules/decoration/prompts/index.d.ts +1 -0
- package/lib/modules/decoration/resources/index.cjs +13 -0
- package/lib/modules/decoration/resources/index.d.ts +7 -0
- package/lib/modules/decoration/templates/index.cjs +12 -0
- package/lib/modules/decoration/templates/index.d.ts +6 -0
- package/lib/modules/decoration/tools/index.cjs +10 -0
- package/lib/modules/decoration/tools/index.d.ts +26 -0
- package/lib/modules/index.cjs +13 -0
- package/lib/modules/index.d.ts +2 -0
- package/lib/modules/mcp/decoration-assist.cjs +13 -0
- package/lib/modules/mcp/decoration-assist.d.ts +4 -0
- package/lib/modules/mcp/index.cjs +21 -22
- package/lib/modules/mcp/index.d.ts +6 -2
- package/lib/modules/mcp/prompts/index.cjs +12 -0
- package/lib/modules/mcp/prompts/index.d.ts +2 -0
- package/lib/modules/mcp/resources/index.cjs +27 -0
- package/lib/modules/mcp/resources/index.d.ts +2 -0
- package/lib/modules/mcp/templates/index.cjs +31 -0
- package/lib/modules/mcp/templates/index.d.ts +2 -0
- package/lib/modules/mcp/tools/index.cjs +18 -0
- package/lib/modules/mcp/tools/index.d.ts +6 -0
- package/lib/types.cjs +1 -1
- package/lib/types.d.ts +41 -1
- package/lib/utils/modulePaths.cjs +43 -0
- package/lib/utils/modulePaths.d.ts +6 -0
- package/lib/utils/moduleValidator.cjs +184 -0
- package/lib/utils/moduleValidator.d.ts +14 -0
- package/lib/utils.cjs +5 -1
- package/lib/utils.d.ts +1 -0
- package/package.json +18 -12
- package/lib/esm/modules/decoration-assist/index.d.ts +0 -39
- package/lib/esm/modules/decoration-assist/index.js +0 -353
- package/lib/esm/modules/mcp/decorator-tools.js +0 -237
- package/lib/esm/modules/mcp/mcp-module.d.ts +0 -230
- package/lib/esm/modules/mcp/mcp-module.js +0 -406
- package/lib/modules/decoration-assist/index.cjs +0 -360
- package/lib/modules/decoration-assist/index.d.ts +0 -39
- package/lib/modules/mcp/decorator-tools.cjs +0 -243
- package/lib/modules/mcp/mcp-module.cjs +0 -452
- package/lib/modules/mcp/mcp-module.d.ts +0 -230
- /package/lib/esm/{modules/mcp → mcp}/decorator-tools.d.ts +0 -0
- /package/lib/{modules/mcp → mcp}/decorator-tools.d.ts +0 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { spawnSync } from "child_process";
|
|
4
|
+
import { documentObjectSchema, coverageTaskSchema, readmeImprovementSchema, } from "../schemas";
|
|
5
|
+
import { getWorkspaceRoot, resolveInWorkspace, throwUserError, WorkspaceError, } from "../workspace";
|
|
6
|
+
import { discoverDocPrompts, getObjectPromptDependencies, } from "../prompts/prompts";
|
|
7
|
+
import { listFilesRecursive, readFileSafe } from "../utils";
|
|
8
|
+
import { analyzeRepo, isSourceFile, isTestFile } from "../code";
|
|
9
|
+
function relativeFiles(root, files) {
|
|
10
|
+
return files.map((file) => path.relative(root, file)).sort();
|
|
11
|
+
}
|
|
12
|
+
function collectPromptSections(names) {
|
|
13
|
+
const root = getWorkspaceRoot();
|
|
14
|
+
const promptIndex = new Map(discoverDocPrompts(root).map((prompt) => [prompt.name, prompt]));
|
|
15
|
+
return names
|
|
16
|
+
.map((name) => promptIndex.get(name))
|
|
17
|
+
.filter((prompt) => Boolean(prompt))
|
|
18
|
+
.map((prompt) => ({
|
|
19
|
+
name: prompt.name,
|
|
20
|
+
title: prompt.title,
|
|
21
|
+
description: prompt.description,
|
|
22
|
+
content: prompt.content,
|
|
23
|
+
absolutePath: prompt.absolutePath,
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
function parseTaskLines(content) {
|
|
27
|
+
return content
|
|
28
|
+
.split(/\r?\n/)
|
|
29
|
+
.map((line) => line.trim())
|
|
30
|
+
.filter((line) => /^task\s+\d+/i.test(line));
|
|
31
|
+
}
|
|
32
|
+
function computeCoverageFromFinal(coveragePath) {
|
|
33
|
+
const payload = JSON.parse(fs.readFileSync(coveragePath, "utf8"));
|
|
34
|
+
const totals = {
|
|
35
|
+
statements: { covered: 0, total: 0 },
|
|
36
|
+
functions: { covered: 0, total: 0 },
|
|
37
|
+
branches: { covered: 0, total: 0 },
|
|
38
|
+
};
|
|
39
|
+
const files = Object.entries(payload).map(([filePath, info]) => {
|
|
40
|
+
const statementCounts = Object.values(info.s);
|
|
41
|
+
const functionCounts = Object.values(info.f);
|
|
42
|
+
const branchCounts = Object.values(info.b).flatMap((value) => Array.isArray(value) ? value : [value]);
|
|
43
|
+
const statementTotal = statementCounts.length;
|
|
44
|
+
const functionTotal = functionCounts.length;
|
|
45
|
+
const branchTotal = branchCounts.length;
|
|
46
|
+
const statementCovered = statementCounts.filter((count) => count > 0).length;
|
|
47
|
+
const functionCovered = functionCounts.filter((count) => count > 0).length;
|
|
48
|
+
const branchCovered = branchCounts.filter((count) => count > 0).length;
|
|
49
|
+
totals.statements.covered += statementCovered;
|
|
50
|
+
totals.statements.total += statementTotal;
|
|
51
|
+
totals.functions.covered += functionCovered;
|
|
52
|
+
totals.functions.total += functionTotal;
|
|
53
|
+
totals.branches.covered += branchCovered;
|
|
54
|
+
totals.branches.total += branchTotal;
|
|
55
|
+
const pct = (covered, total) => total === 0 ? 100 : Number(((covered / total) * 100).toFixed(2));
|
|
56
|
+
return {
|
|
57
|
+
path: filePath,
|
|
58
|
+
statements: pct(statementCovered, statementTotal),
|
|
59
|
+
functions: pct(functionCovered, functionTotal),
|
|
60
|
+
branches: pct(branchCovered, branchTotal),
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
const pct = (covered, total) => total === 0 ? 100 : Number(((covered / total) * 100).toFixed(2));
|
|
64
|
+
return {
|
|
65
|
+
totals: {
|
|
66
|
+
statements: {
|
|
67
|
+
...totals.statements,
|
|
68
|
+
pct: pct(totals.statements.covered, totals.statements.total),
|
|
69
|
+
},
|
|
70
|
+
functions: {
|
|
71
|
+
...totals.functions,
|
|
72
|
+
pct: pct(totals.functions.covered, totals.functions.total),
|
|
73
|
+
},
|
|
74
|
+
branches: {
|
|
75
|
+
...totals.branches,
|
|
76
|
+
pct: pct(totals.branches.covered, totals.branches.total),
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
files,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function normalizePromptSections(sections) {
|
|
83
|
+
return sections.map((section) => ({
|
|
84
|
+
name: section.name,
|
|
85
|
+
title: section.title,
|
|
86
|
+
tasks: parseTaskLines(section.content),
|
|
87
|
+
content: section.content,
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
async function resolveRepoRoot(basePath) {
|
|
91
|
+
const root = getWorkspaceRoot();
|
|
92
|
+
try {
|
|
93
|
+
return resolveInWorkspace(root, basePath);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
if (error instanceof WorkspaceError) {
|
|
97
|
+
await throwUserError(error.message);
|
|
98
|
+
}
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export const documentObjectTool = {
|
|
103
|
+
name: "document-object",
|
|
104
|
+
description: "Create a documentation plan for a specific object type using .codex prompts and repository analysis.",
|
|
105
|
+
parameters: documentObjectSchema,
|
|
106
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
107
|
+
execute: async (input, _context) => {
|
|
108
|
+
const args = documentObjectSchema.parse(input);
|
|
109
|
+
const repoRoot = await resolveRepoRoot(args.basePath);
|
|
110
|
+
const dependencies = getObjectPromptDependencies()[args.objectType] ?? [];
|
|
111
|
+
if (!dependencies.length) {
|
|
112
|
+
await throwUserError(`No prompt guidance configured for object type ${args.objectType}`);
|
|
113
|
+
}
|
|
114
|
+
const sections = normalizePromptSections(collectPromptSections(dependencies));
|
|
115
|
+
const srcDir = path.join(repoRoot, "src");
|
|
116
|
+
const testDir = path.join(repoRoot, "tests");
|
|
117
|
+
const sourceFiles = fs.existsSync(srcDir)
|
|
118
|
+
? listFilesRecursive(srcDir, isSourceFile)
|
|
119
|
+
: [];
|
|
120
|
+
const testFiles = fs.existsSync(testDir)
|
|
121
|
+
? listFilesRecursive(testDir, (file) => isSourceFile(file) && isTestFile(file))
|
|
122
|
+
: [];
|
|
123
|
+
let targetFileContent;
|
|
124
|
+
if (args.targetFile) {
|
|
125
|
+
try {
|
|
126
|
+
const absolute = resolveInWorkspace(repoRoot, args.targetFile);
|
|
127
|
+
targetFileContent = readFileSafe(absolute) ?? undefined;
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
if (error instanceof WorkspaceError) {
|
|
131
|
+
await throwUserError(error.message);
|
|
132
|
+
}
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const payload = {
|
|
137
|
+
basePath: path.relative(getWorkspaceRoot(), repoRoot) || ".",
|
|
138
|
+
objectType: args.objectType,
|
|
139
|
+
targetFile: args.targetFile,
|
|
140
|
+
guidance: sections,
|
|
141
|
+
files: {
|
|
142
|
+
source: relativeFiles(repoRoot, sourceFiles),
|
|
143
|
+
tests: relativeFiles(repoRoot, testFiles),
|
|
144
|
+
},
|
|
145
|
+
targetFileContent: args.includeContent ? targetFileContent : undefined,
|
|
146
|
+
};
|
|
147
|
+
return {
|
|
148
|
+
content: [
|
|
149
|
+
{
|
|
150
|
+
type: "text",
|
|
151
|
+
text: JSON.stringify(payload, null, 2),
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
};
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
export const coverageEnforcerTool = {
|
|
158
|
+
name: "ensure-test-coverage",
|
|
159
|
+
description: "Run the configured coverage command and report whether the target percentage is met, highlighting weak files.",
|
|
160
|
+
parameters: coverageTaskSchema,
|
|
161
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
162
|
+
execute: async (input, _context) => {
|
|
163
|
+
const args = coverageTaskSchema.parse(input);
|
|
164
|
+
const repoRoot = await resolveRepoRoot(args.basePath);
|
|
165
|
+
if (!args.dryRun) {
|
|
166
|
+
const env = {
|
|
167
|
+
...process.env,
|
|
168
|
+
USE_WATCHMAN: "false",
|
|
169
|
+
WATCHMAN_DISABLE: "1",
|
|
170
|
+
JEST_DISABLE_WATCHMAN: "1",
|
|
171
|
+
};
|
|
172
|
+
const result = spawnSync("npm", ["run", "coverage", "--", "--watchman=false", "--runInBand"], { cwd: repoRoot, env, encoding: "utf8" });
|
|
173
|
+
if (result.status !== 0) {
|
|
174
|
+
const message = result.stderr || result.stdout || "Coverage command failed";
|
|
175
|
+
await throwUserError(message.trim());
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const coveragePath = path.join(repoRoot, "workdocs", "reports", "coverage", "coverage-final.json");
|
|
179
|
+
if (!fs.existsSync(coveragePath)) {
|
|
180
|
+
await throwUserError(`Coverage report not found at ${path.relative(repoRoot, coveragePath)}`);
|
|
181
|
+
}
|
|
182
|
+
const summary = computeCoverageFromFinal(coveragePath);
|
|
183
|
+
const meetsThreshold = summary.totals.statements.pct >= args.coverage &&
|
|
184
|
+
summary.totals.functions.pct >= args.coverage &&
|
|
185
|
+
summary.totals.branches.pct >= args.coverage;
|
|
186
|
+
const weakest = [...summary.files]
|
|
187
|
+
.sort((a, b) => a.statements - b.statements)
|
|
188
|
+
.slice(0, 10);
|
|
189
|
+
const guidance = normalizePromptSections(collectPromptSections(["bulk-tests"]));
|
|
190
|
+
const payload = {
|
|
191
|
+
basePath: path.relative(getWorkspaceRoot(), repoRoot) || ".",
|
|
192
|
+
target: args.coverage,
|
|
193
|
+
meetsThreshold,
|
|
194
|
+
totals: summary.totals,
|
|
195
|
+
weakest,
|
|
196
|
+
guidance,
|
|
197
|
+
};
|
|
198
|
+
return {
|
|
199
|
+
content: [
|
|
200
|
+
{
|
|
201
|
+
type: "text",
|
|
202
|
+
text: JSON.stringify(payload, null, 2),
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
};
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
export const readmeImprovementTool = {
|
|
209
|
+
name: "improve-readme",
|
|
210
|
+
description: "Summarize required steps to refresh README and workdocs content using .codex guidance and repository analysis.",
|
|
211
|
+
parameters: readmeImprovementSchema,
|
|
212
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
213
|
+
execute: async (input, _context) => {
|
|
214
|
+
const args = readmeImprovementSchema.parse(input);
|
|
215
|
+
const repoRoot = await resolveRepoRoot(args.basePath);
|
|
216
|
+
const analysis = analyzeRepo(repoRoot);
|
|
217
|
+
const modules = analysis.files
|
|
218
|
+
.filter((file) => /index\.ts$/.test(file))
|
|
219
|
+
.map((file) => path.relative(repoRoot, file));
|
|
220
|
+
const promptSections = normalizePromptSections(collectPromptSections(["update-readme", "doc", "module"]));
|
|
221
|
+
const testExamples = Object.keys(analysis.tests ?? {});
|
|
222
|
+
const examples = args.includeExamples ? testExamples.slice(0, 20) : [];
|
|
223
|
+
const payload = {
|
|
224
|
+
basePath: path.relative(getWorkspaceRoot(), repoRoot) || ".",
|
|
225
|
+
summary: {
|
|
226
|
+
modules,
|
|
227
|
+
totalSourceFiles: analysis.files.length,
|
|
228
|
+
totalTestFiles: analysis.testFiles.length,
|
|
229
|
+
hasReadme: Boolean(analysis.readme),
|
|
230
|
+
},
|
|
231
|
+
guidance: promptSections,
|
|
232
|
+
suggestedExamples: examples,
|
|
233
|
+
};
|
|
234
|
+
return {
|
|
235
|
+
content: [
|
|
236
|
+
{
|
|
237
|
+
type: "text",
|
|
238
|
+
text: JSON.stringify(payload, null, 2),
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
};
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZXgtdG9vbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbWNwL3Rvb2xzL2NvZGV4LXRvb2xzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQztBQUNwQixPQUFPLElBQUksTUFBTSxNQUFNLENBQUM7QUFDeEIsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUxQyxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLGtCQUFrQixFQUNsQix1QkFBdUIsR0FDeEIsTUFBTSxZQUFZLENBQUM7QUFNcEIsT0FBTyxFQUNMLGdCQUFnQixFQUNoQixrQkFBa0IsRUFDbEIsY0FBYyxFQUNkLGNBQWMsR0FDZixNQUFNLGNBQWMsQ0FBQztBQUN0QixPQUFPLEVBRUwsa0JBQWtCLEVBQ2xCLDJCQUEyQixHQUM1QixNQUFNLG9CQUFvQixDQUFDO0FBRTVCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxZQUFZLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDNUQsT0FBTyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBVWhFLFNBQVMsYUFBYSxDQUFDLElBQVksRUFBRSxLQUFlO0lBQ2xELE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUMvRCxDQUFDO0FBRUQsU0FBUyxxQkFBcUIsQ0FBQyxLQUF3QjtJQUNyRCxNQUFNLElBQUksR0FBRyxnQkFBZ0IsRUFBRSxDQUFDO0lBQ2hDLE1BQU0sV0FBVyxHQUFHLElBQUksR0FBRyxDQUN6QixrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFD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Y0FBYyxHQUFHLHVCQUF1QixDQUM1QyxxQkFBcUIsQ0FBQyxDQUFDLGVBQWUsRUFBRSxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FDMUQsQ0FBQztRQUVGLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN2RCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRXZFLE1BQU0sT0FBTyxHQUFHO1lBQ2QsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxRQUFRLENBQUMsSUFBSSxHQUFHO1lBQzVELE9BQU8sRUFBRTtnQkFDUCxPQUFPO2dCQUNQLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTTtnQkFDdkMsY0FBYyxFQUFFLFFBQVEsQ0FBQyxTQUFTLENBQUMsTUFBTTtnQkFDekMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO2FBQ3BDO1lBQ0QsUUFBUSxFQUFFLGNBQWM7WUFDeEIsaUJBQWlCLEVBQUUsUUFBUTtTQUM1QixDQUFDO1FBRUYsT0FBTztZQUNMLE9BQU8sRUFBRTtnQkFDUDtvQkFDRSxJQUFJLEVBQUUsTUFBTTtvQkFDWixJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztpQkFDdkM7YUFDRjtTQUNzQixDQUFDO0lBQzVCLENBQUM7Q0FDRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IHNwYXduU3luYyB9IGZyb20gXCJjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgdHlwZSB7IENvbnRlbnRSZXN1bHQsIFRvb2wgfSBmcm9tIFwiZmFzdG1jcFwiO1xuaW1wb3J0IHtcbiAgZG9jdW1lbnRPYmplY3RTY2hlbWEsXG4gIGNvdmVyYWdlVGFza1NjaGVtYSxcbiAgcmVhZG1lSW1wcm92ZW1lbnRTY2hlbWEsXG59IGZyb20gXCIuLi9zY2hlbWFzXCI7XG5pbXBvcnQge1xuICBEb2N1bWVudE9iamVjdEFyZ3MsXG4gIENvdmVyYWdlVGFza0FyZ3MsXG4gIFJlYWRtZUltcHJvdmVtZW50QXJncyxcbn0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQge1xuICBnZXRXb3Jrc3BhY2VSb290LFxuICByZXNvbHZlSW5Xb3Jrc3BhY2UsXG4gIHRocm93VXNlckVycm9yLFxuICBXb3Jrc3BhY2VFcnJvcixcbn0gZnJvbSBcIi4uL3dvcmtzcGFjZVwiO1xuaW1wb3J0IHtcbiAgYnVpbGRPYmplY3RQcm9tcHRzLFxuICBkaXNjb3ZlckRvY1Byb21wdHMsXG4gIGdldE9iamVjdFByb21wdERlcGVuZGVuY2llcyxcbn0gZnJvbSBcIi4uL3Byb21wdHMvcHJvbXB0c1wiO1xuaW1wb3J0IHR5cGUgeyBEb2NQcm9tcHQgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IGxpc3RGaWxlc1JlY3Vyc2l2ZSwgcmVhZEZpbGVTYWZlIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgeyBhbmFseXplUmVwbywgaXNTb3VyY2VGaWxlLCBpc1Rlc3RGaWxlIH0gZnJvbSBcIi4uL2NvZGVcIjtcblxudHlwZSBQcm9tcHRTZWN0aW9uID0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGNvbnRlbnQ6IHN0cmluZztcbiAgYWJzb2x1dGVQYXRoPzogc3RyaW5nO1xufTtcblxuZnVuY3Rpb24gcmVsYXRpdmVGaWxlcyhyb290OiBzdHJpbmcsIGZpbGVzOiBzdHJpbmdbXSk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIGZpbGVzLm1hcCgoZmlsZSkgPT4gcGF0aC5yZWxhdGl2ZShyb290LCBmaWxlKSkuc29ydCgpO1xufVxuXG5mdW5jdGlvbiBjb2xsZWN0UHJvbXB0U2VjdGlvbnMobmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdKTogUHJvbXB0U2VjdGlvbltdIHtcbiAgY29uc3Qgcm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKTtcbiAgY29uc3QgcHJvbXB0SW5kZXggPSBuZXcgTWFwPHN0cmluZywgRG9jUHJvbXB0PihcbiAgICBkaXNjb3ZlckRvY1Byb21wdHMocm9vdCkubWFwKChwcm9tcHQpID0+IFtwcm9tcHQubmFtZSwgcHJvbXB0XSlcbiAgKTtcbiAgcmV0dXJuIG5hbWVzXG4gICAgLm1hcCgobmFtZSkgPT4gcHJvbXB0SW5kZXguZ2V0KG5hbWUpKVxuICAgIC5maWx0ZXIoKHByb21wdCk6IHByb21wdCBpcyBEb2NQcm9tcHQgPT4gQm9vbGVhbihwcm9tcHQpKVxuICAgIC5tYXAoKHByb21wdCkgPT4gKHtcbiAgICAgIG5hbWU6IHByb21wdC5uYW1lLFxuICAgICAgdGl0bGU6IHByb21wdC50aXRsZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBwcm9tcHQuZGVzY3JpcHRpb24sXG4gICAgICBjb250ZW50OiBwcm9tcHQuY29udGVudCxcbiAgICAgIGFic29sdXRlUGF0aDogcHJvbXB0LmFic29sdXRlUGF0aCxcbiAgICB9KSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlVGFza0xpbmVzKGNvbnRlbnQ6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIGNvbnRlbnRcbiAgICAuc3BsaXQoL1xccj9cXG4vKVxuICAgIC5tYXAoKGxpbmUpID0+IGxpbmUudHJpbSgpKVxuICAgIC5maWx0ZXIoKGxpbmUpID0+IC9edGFza1xccytcXGQrL2kudGVzdChsaW5lKSk7XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVDb3ZlcmFnZUZyb21GaW5hbChjb3ZlcmFnZVBhdGg6IHN0cmluZykge1xuICBjb25zdCBwYXlsb2FkID0gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMoY292ZXJhZ2VQYXRoLCBcInV0ZjhcIikpIGFzIFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAge1xuICAgICAgczogUmVjb3JkPHN0cmluZywgbnVtYmVyPjtcbiAgICAgIGY6IFJlY29yZDxzdHJpbmcsIG51bWJlcj47XG4gICAgICBiOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBudW1iZXJbXT47XG4gICAgfVxuICA+O1xuXG4gIGNvbnN0IHRvdGFscyA9IHtcbiAgICBzdGF0ZW1lbnRzOiB7IGNvdmVyZWQ6IDAsIHRvdGFsOiAwIH0sXG4gICAgZnVuY3Rpb25zOiB7IGNvdmVyZWQ6IDAsIHRvdGFsOiAwIH0sXG4gICAgYnJhbmNoZXM6IHsgY292ZXJlZDogMCwgdG90YWw6IDAgfSxcbiAgfTtcblxuICBjb25zdCBmaWxlcyA9IE9iamVjdC5lbnRyaWVzKHBheWxvYWQpLm1hcCgoW2ZpbGVQYXRoLCBpbmZvXSkgPT4ge1xuICAgIGNvbnN0IHN0YXRlbWVudENvdW50cyA9IE9iamVjdC52YWx1ZXMoaW5mby5zKTtcbiAgICBjb25zdCBmdW5jdGlvbkNvdW50cyA9IE9iamVjdC52YWx1ZXMoaW5mby5mKTtcbiAgICBjb25zdCBicmFuY2hDb3VudHMgPSBPYmplY3QudmFsdWVzKGluZm8uYikuZmxhdE1hcCgodmFsdWUpID0+XG4gICAgICBBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW3ZhbHVlXVxuICAgICk7XG5cbiAgICBjb25zdCBzdGF0ZW1lbnRUb3RhbCA9IHN0YXRlbWVudENvdW50cy5sZW5ndGg7XG4gICAgY29uc3QgZnVuY3Rpb25Ub3RhbCA9IGZ1bmN0aW9uQ291bnRzLmxlbmd0aDtcbiAgICBjb25zdCBicmFuY2hUb3RhbCA9IGJyYW5jaENvdW50cy5sZW5ndGg7XG5cbiAgICBjb25zdCBzdGF0ZW1lbnRDb3ZlcmVkID0gc3RhdGVtZW50Q291bnRzLmZpbHRlcihcbiAgICAgIChjb3VudCkgPT4gY291bnQgPiAwXG4gICAgKS5sZW5ndGg7XG4gICAgY29uc3QgZnVuY3Rpb25Db3ZlcmVkID0gZnVuY3Rpb25Db3VudHMuZmlsdGVyKChjb3VudCkgPT4gY291bnQgPiAwKS5sZW5ndGg7XG4gICAgY29uc3QgYnJhbmNoQ292ZXJlZCA9IGJyYW5jaENvdW50cy5maWx0ZXIoKGNvdW50KSA9PiBjb3VudCA+IDApLmxlbmd0aDtcblxuICAgIHRvdGFscy5zdGF0ZW1lbnRzLmNvdmVyZWQgKz0gc3RhdGVtZW50Q292ZXJlZDtcbiAgICB0b3RhbHMuc3RhdGVtZW50cy50b3RhbCArPSBzdGF0ZW1lbnRUb3RhbDtcbiAgICB0b3RhbHMuZnVuY3Rpb25zLmNvdmVyZWQgKz0gZnVuY3Rpb25Db3ZlcmVkO1xuICAgIHRvdGFscy5mdW5jdGlvbnMudG90YWwgKz0gZnVuY3Rpb25Ub3RhbDtcbiAgICB0b3RhbHMuYnJhbmNoZXMuY292ZXJlZCArPSBicmFuY2hDb3ZlcmVkO1xuICAgIHRvdGFscy5icmFuY2hlcy50b3RhbCArPSBicmFuY2hUb3RhbDtcblxuICAgIGNvbnN0IHBjdCA9IChjb3ZlcmVkOiBudW1iZXIsIHRvdGFsOiBudW1iZXIpID0+XG4gICAgICB0b3RhbCA9PT0gMCA/IDEwMCA6IE51bWJlcigoKGNvdmVyZWQgLyB0b3RhbCkgKiAxMDApLnRvRml4ZWQoMikpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHBhdGg6IGZpbGVQYXRoLFxuICAgICAgc3RhdGVtZW50czogcGN0KHN0YXRlbWVudENvdmVyZWQsIHN0YXRlbWVudFRvdGFsKSxcbiAgICAgIGZ1bmN0aW9uczogcGN0KGZ1bmN0aW9uQ292ZXJlZCwgZnVuY3Rpb25Ub3RhbCksXG4gICAgICBicmFuY2hlczogcGN0KGJyYW5jaENvdmVyZWQsIGJyYW5jaFRvdGFsKSxcbiAgICB9O1xuICB9KTtcblxuICBjb25zdCBwY3QgPSAoY292ZXJlZDogbnVtYmVyLCB0b3RhbDogbnVtYmVyKSA9PlxuICAgIHRvdGFsID09PSAwID8gMTAwIDogTnVtYmVyKCgoY292ZXJlZCAvIHRvdGFsKSAqIDEwMCkudG9GaXhlZCgyKSk7XG5cbiAgcmV0dXJuIHtcbiAgICB0b3RhbHM6IHtcbiAgICAgIHN0YXRlbWVudHM6IHtcbiAgICAgICAgLi4udG90YWxzLnN0YXRlbWVudHMsXG4gICAgICAgIHBjdDogcGN0KHRvdGFscy5zdGF0ZW1lbnRzLmNvdmVyZWQsIHRvdGFscy5zdGF0ZW1lbnRzLnRvdGFsKSxcbiAgICAgIH0sXG4gICAgICBmdW5jdGlvbnM6IHtcbiAgICAgICAgLi4udG90YWxzLmZ1bmN0aW9ucyxcbiAgICAgICAgcGN0OiBwY3QodG90YWxzLmZ1bmN0aW9ucy5jb3ZlcmVkLCB0b3RhbHMuZnVuY3Rpb25zLnRvdGFsKSxcbiAgICAgIH0sXG4gICAgICBicmFuY2hlczoge1xuICAgICAgICAuLi50b3RhbHMuYnJhbmNoZXMsXG4gICAgICAgIHBjdDogcGN0KHRvdGFscy5icmFuY2hlcy5jb3ZlcmVkLCB0b3RhbHMuYnJhbmNoZXMudG90YWwpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIGZpbGVzLFxuICB9O1xufVxuXG5mdW5jdGlvbiBub3JtYWxpemVQcm9tcHRTZWN0aW9ucyhzZWN0aW9uczogUHJvbXB0U2VjdGlvbltdKSB7XG4gIHJldHVybiBzZWN0aW9ucy5tYXAoKHNlY3Rpb24pID0+ICh7XG4gICAgbmFtZTogc2VjdGlvbi5uYW1lLFxuICAgIHRpdGxlOiBzZWN0aW9uLnRpdGxlLFxuICAgIHRhc2tzOiBwYXJzZVRhc2tMaW5lcyhzZWN0aW9uLmNvbnRlbnQpLFxuICAgIGNvbnRlbnQ6IHNlY3Rpb24uY29udGVudCxcbiAgfSkpO1xufVxuXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlUmVwb1Jvb3QoYmFzZVBhdGg6IHN0cmluZykge1xuICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICB0cnkge1xuICAgIHJldHVybiByZXNvbHZlSW5Xb3Jrc3BhY2Uocm9vdCwgYmFzZVBhdGgpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtzcGFjZUVycm9yKSB7XG4gICAgICBhd2FpdCB0aHJvd1VzZXJFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGRvY3VtZW50T2JqZWN0VG9vbDogVG9vbDx1bmRlZmluZWQsIHR5cGVvZiBkb2N1bWVudE9iamVjdFNjaGVtYT4gPVxuICB7XG4gICAgbmFtZTogXCJkb2N1bWVudC1vYmplY3RcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiQ3JlYXRlIGEgZG9jdW1lbnRhdGlvbiBwbGFuIGZvciBhIHNwZWNpZmljIG9iamVjdCB0eXBlIHVzaW5nIC5jb2RleCBwcm9tcHRzIGFuZCByZXBvc2l0b3J5IGFuYWx5c2lzLlwiLFxuICAgIHBhcmFtZXRlcnM6IGRvY3VtZW50T2JqZWN0U2NoZW1hLFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBleGVjdXRlOiBhc3luYyAoaW5wdXQsIF9jb250ZXh0KTogUHJvbWlzZTxDb250ZW50UmVzdWx0PiA9PiB7XG4gICAgICBjb25zdCBhcmdzID0gZG9jdW1lbnRPYmplY3RTY2hlbWEucGFyc2UoaW5wdXQgYXMgRG9jdW1lbnRPYmplY3RBcmdzKTtcbiAgICAgIGNvbnN0IHJlcG9Sb290ID0gYXdhaXQgcmVzb2x2ZVJlcG9Sb290KGFyZ3MuYmFzZVBhdGgpO1xuXG4gICAgICBjb25zdCBkZXBlbmRlbmNpZXMgPSBnZXRPYmplY3RQcm9tcHREZXBlbmRlbmNpZXMoKVthcmdzLm9iamVjdFR5cGVdID8/IFtdO1xuICAgICAgaWYgKCFkZXBlbmRlbmNpZXMubGVuZ3RoKSB7XG4gICAgICAgIGF3YWl0IHRocm93VXNlckVycm9yKFxuICAgICAgICAgIGBObyBwcm9tcHQgZ3VpZGFuY2UgY29uZmlndXJlZCBmb3Igb2JqZWN0IHR5cGUgJHthcmdzLm9iamVjdFR5cGV9YFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzZWN0aW9ucyA9IG5vcm1hbGl6ZVByb21wdFNlY3Rpb25zKFxuICAgICAgICBjb2xsZWN0UHJvbXB0U2VjdGlvbnMoZGVwZW5kZW5jaWVzKVxuICAgICAgKTtcblxuICAgICAgY29uc3Qgc3JjRGlyID0gcGF0aC5qb2luKHJlcG9Sb290LCBcInNyY1wiKTtcbiAgICAgIGNvbnN0IHRlc3REaXIgPSBwYXRoLmpvaW4ocmVwb1Jvb3QsIFwidGVzdHNcIik7XG5cbiAgICAgIGNvbnN0IHNvdXJjZUZpbGVzID0gZnMuZXhpc3RzU3luYyhzcmNEaXIpXG4gICAgICAgID8gbGlzdEZpbGVzUmVjdXJzaXZlKHNyY0RpciwgaXNTb3VyY2VGaWxlKVxuICAgICAgICA6IFtdO1xuICAgICAgY29uc3QgdGVzdEZpbGVzID0gZnMuZXhpc3RzU3luYyh0ZXN0RGlyKVxuICAgICAgICA/IGxpc3RGaWxlc1JlY3Vyc2l2ZShcbiAgICAgICAgICAgIHRlc3REaXIsXG4gICAgICAgICAgICAoZmlsZSkgPT4gaXNTb3VyY2VGaWxlKGZpbGUpICYmIGlzVGVzdEZpbGUoZmlsZSlcbiAgICAgICAgICApXG4gICAgICAgIDogW107XG5cbiAgICAgIGxldCB0YXJnZXRGaWxlQ29udGVudDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKGFyZ3MudGFyZ2V0RmlsZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGFic29sdXRlID0gcmVzb2x2ZUluV29ya3NwYWNlKHJlcG9Sb290LCBhcmdzLnRhcmdldEZpbGUpO1xuICAgICAgICAgIHRhcmdldEZpbGVDb250ZW50ID0gcmVhZEZpbGVTYWZlKGFic29sdXRlKSA/PyB1bmRlZmluZWQ7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV29ya3NwYWNlRXJyb3IpIHtcbiAgICAgICAgICAgIGF3YWl0IHRocm93VXNlckVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICBiYXNlUGF0aDogcGF0aC5yZWxhdGl2ZShnZXRXb3Jrc3BhY2VSb290KCksIHJlcG9Sb290KSB8fCBcIi5cIixcbiAgICAgICAgb2JqZWN0VHlwZTogYXJncy5vYmplY3RUeXBlLFxuICAgICAgICB0YXJnZXRGaWxlOiBhcmdzLnRhcmdldEZpbGUsXG4gICAgICAgIGd1aWRhbmNlOiBzZWN0aW9ucyxcbiAgICAgICAgZmlsZXM6IHtcbiAgICAgICAgICBzb3VyY2U6IHJlbGF0aXZlRmlsZXMocmVwb1Jvb3QsIHNvdXJjZUZpbGVzKSxcbiAgICAgICAgICB0ZXN0czogcmVsYXRpdmVGaWxlcyhyZXBvUm9vdCwgdGVzdEZpbGVzKSxcbiAgICAgICAgfSxcbiAgICAgICAgdGFyZ2V0RmlsZUNvbnRlbnQ6IGFyZ3MuaW5jbHVkZUNvbnRlbnQgPyB0YXJnZXRGaWxlQ29udGVudCA6IHVuZGVmaW5lZCxcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IEpTT04uc3RyaW5naWZ5KHBheWxvYWQsIG51bGwsIDIpLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9IHNhdGlzZmllcyBDb250ZW50UmVzdWx0O1xuICAgIH0sXG4gIH07XG5cbmV4cG9ydCBjb25zdCBjb3ZlcmFnZUVuZm9yY2VyVG9vbDogVG9vbDx1bmRlZmluZWQsIHR5cGVvZiBjb3ZlcmFnZVRhc2tTY2hlbWE+ID1cbiAge1xuICAgIG5hbWU6IFwiZW5zdXJlLXRlc3QtY292ZXJhZ2VcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiUnVuIHRoZSBjb25maWd1cmVkIGNvdmVyYWdlIGNvbW1hbmQgYW5kIHJlcG9ydCB3aGV0aGVyIHRoZSB0YXJnZXQgcGVyY2VudGFnZSBpcyBtZXQsIGhpZ2hsaWdodGluZyB3ZWFrIGZpbGVzLlwiLFxuICAgIHBhcmFtZXRlcnM6IGNvdmVyYWdlVGFza1NjaGVtYSxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgZXhlY3V0ZTogYXN5bmMgKGlucHV0LCBfY29udGV4dCk6IFByb21pc2U8Q29udGVudFJlc3VsdD4gPT4ge1xuICAgICAgY29uc3QgYXJncyA9IGNvdmVyYWdlVGFza1NjaGVtYS5wYXJzZShpbnB1dCBhcyBDb3ZlcmFnZVRhc2tBcmdzKTtcbiAgICAgIGNvbnN0IHJlcG9Sb290ID0gYXdhaXQgcmVzb2x2ZVJlcG9Sb290KGFyZ3MuYmFzZVBhdGgpO1xuXG4gICAgICBpZiAoIWFyZ3MuZHJ5UnVuKSB7XG4gICAgICAgIGNvbnN0IGVudiA9IHtcbiAgICAgICAgICAuLi5wcm9jZXNzLmVudixcbiAgICAgICAgICBVU0VfV0FUQ0hNQU46IFwiZmFsc2VcIixcbiAgICAgICAgICBXQVRDSE1BTl9ESVNBQkxFOiBcIjFcIixcbiAgICAgICAgICBKRVNUX0RJU0FCTEVfV0FUQ0hNQU46IFwiMVwiLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCByZXN1bHQgPSBzcGF3blN5bmMoXG4gICAgICAgICAgXCJucG1cIixcbiAgICAgICAgICBbXCJydW5cIiwgXCJjb3ZlcmFnZVwiLCBcIi0tXCIsIFwiLS13YXRjaG1hbj1mYWxzZVwiLCBcIi0tcnVuSW5CYW5kXCJdLFxuICAgICAgICAgIHsgY3dkOiByZXBvUm9vdCwgZW52LCBlbmNvZGluZzogXCJ1dGY4XCIgfVxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChyZXN1bHQuc3RhdHVzICE9PSAwKSB7XG4gICAgICAgICAgY29uc3QgbWVzc2FnZSA9XG4gICAgICAgICAgICByZXN1bHQuc3RkZXJyIHx8IHJlc3VsdC5zdGRvdXQgfHwgXCJDb3ZlcmFnZSBjb21tYW5kIGZhaWxlZFwiO1xuICAgICAgICAgIGF3YWl0IHRocm93VXNlckVycm9yKG1lc3NhZ2UudHJpbSgpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBjb3ZlcmFnZVBhdGggPSBwYXRoLmpvaW4oXG4gICAgICAgIHJlcG9Sb290LFxuICAgICAgICBcIndvcmtkb2NzXCIsXG4gICAgICAgIFwicmVwb3J0c1wiLFxuICAgICAgICBcImNvdmVyYWdlXCIsXG4gICAgICAgIFwiY292ZXJhZ2UtZmluYWwuanNvblwiXG4gICAgICApO1xuXG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoY292ZXJhZ2VQYXRoKSkge1xuICAgICAgICBhd2FpdCB0aHJvd1VzZXJFcnJvcihcbiAgICAgICAgICBgQ292ZXJhZ2UgcmVwb3J0IG5vdCBmb3VuZCBhdCAke3BhdGgucmVsYXRpdmUocmVwb1Jvb3QsIGNvdmVyYWdlUGF0aCl9YFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdW1tYXJ5ID0gY29tcHV0ZUNvdmVyYWdlRnJvbUZpbmFsKGNvdmVyYWdlUGF0aCk7XG4gICAgICBjb25zdCBtZWV0c1RocmVzaG9sZCA9XG4gICAgICAgIHN1bW1hcnkudG90YWxzLnN0YXRlbWVudHMucGN0ID49IGFyZ3MuY292ZXJhZ2UgJiZcbiAgICAgICAgc3VtbWFyeS50b3RhbHMuZnVuY3Rpb25zLnBjdCA+PSBhcmdzLmNvdmVyYWdlICYmXG4gICAgICAgIHN1bW1hcnkudG90YWxzLmJyYW5jaGVzLnBjdCA+PSBhcmdzLmNvdmVyYWdlO1xuXG4gICAgICBjb25zdCB3ZWFrZXN0ID0gWy4uLnN1bW1hcnkuZmlsZXNdXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiBhLnN0YXRlbWVudHMgLSBiLnN0YXRlbWVudHMpXG4gICAgICAgIC5zbGljZSgwLCAxMCk7XG5cbiAgICAgIGNvbnN0IGd1aWRhbmNlID0gbm9ybWFsaXplUHJvbXB0U2VjdGlvbnMoXG4gICAgICAgIGNvbGxlY3RQcm9tcHRTZWN0aW9ucyhbXCJidWxrLXRlc3RzXCJdKVxuICAgICAgKTtcblxuICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgYmFzZVBhdGg6IHBhdGgucmVsYXRpdmUoZ2V0V29ya3NwYWNlUm9vdCgpLCByZXBvUm9vdCkgfHwgXCIuXCIsXG4gICAgICAgIHRhcmdldDogYXJncy5jb3ZlcmFnZSxcbiAgICAgICAgbWVldHNUaHJlc2hvbGQsXG4gICAgICAgIHRvdGFsczogc3VtbWFyeS50b3RhbHMsXG4gICAgICAgIHdlYWtlc3QsXG4gICAgICAgIGd1aWRhbmNlLFxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkocGF5bG9hZCwgbnVsbCwgMiksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0gc2F0aXNmaWVzIENvbnRlbnRSZXN1bHQ7XG4gICAgfSxcbiAgfTtcblxuZXhwb3J0IGNvbnN0IHJlYWRtZUltcHJvdmVtZW50VG9vbDogVG9vbDxcbiAgdW5kZWZpbmVkLFxuICB0eXBlb2YgcmVhZG1lSW1wcm92ZW1lbnRTY2hlbWFcbj4gPSB7XG4gIG5hbWU6IFwiaW1wcm92ZS1yZWFkbWVcIixcbiAgZGVzY3JpcHRpb246XG4gICAgXCJTdW1tYXJpemUgcmVxdWlyZWQgc3RlcHMgdG8gcmVmcmVzaCBSRUFETUUgYW5kIHdvcmtkb2NzIGNvbnRlbnQgdXNpbmcgLmNvZGV4IGd1aWRhbmNlIGFuZCByZXBvc2l0b3J5IGFuYWx5c2lzLlwiLFxuICBwYXJhbWV0ZXJzOiByZWFkbWVJbXByb3ZlbWVudFNjaGVtYSxcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBleGVjdXRlOiBhc3luYyAoaW5wdXQsIF9jb250ZXh0KTogUHJvbWlzZTxDb250ZW50UmVzdWx0PiA9PiB7XG4gICAgY29uc3QgYXJncyA9IHJlYWRtZUltcHJvdmVtZW50U2NoZW1hLnBhcnNlKGlucHV0IGFzIFJlYWRtZUltcHJvdmVtZW50QXJncyk7XG4gICAgY29uc3QgcmVwb1Jvb3QgPSBhd2FpdCByZXNvbHZlUmVwb1Jvb3QoYXJncy5iYXNlUGF0aCk7XG5cbiAgICBjb25zdCBhbmFseXNpcyA9IGFuYWx5emVSZXBvKHJlcG9Sb290KTtcbiAgICBjb25zdCBtb2R1bGVzID0gYW5hbHlzaXMuZmlsZXNcbiAgICAgIC5maWx0ZXIoKGZpbGUpID0+IC9pbmRleFxcLnRzJC8udGVzdChmaWxlKSlcbiAgICAgIC5tYXAoKGZpbGUpID0+IHBhdGgucmVsYXRpdmUocmVwb1Jvb3QsIGZpbGUpKTtcblxuICAgIGNvbnN0IHByb21wdFNlY3Rpb25zID0gbm9ybWFsaXplUHJvbXB0U2VjdGlvbnMoXG4gICAgICBjb2xsZWN0UHJvbXB0U2VjdGlvbnMoW1widXBkYXRlLXJlYWRtZVwiLCBcImRvY1wiLCBcIm1vZHVsZVwiXSlcbiAgICApO1xuXG4gICAgY29uc3QgdGVzdEV4YW1wbGVzID0gT2JqZWN0LmtleXMoYW5hbHlzaXMudGVzdHMgPz8ge30pO1xuICAgIGNvbnN0IGV4YW1wbGVzID0gYXJncy5pbmNsdWRlRXhhbXBsZXMgPyB0ZXN0RXhhbXBsZXMuc2xpY2UoMCwgMjApIDogW107XG5cbiAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgYmFzZVBhdGg6IHBhdGgucmVsYXRpdmUoZ2V0V29ya3NwYWNlUm9vdCgpLCByZXBvUm9vdCkgfHwgXCIuXCIsXG4gICAgICBzdW1tYXJ5OiB7XG4gICAgICAgIG1vZHVsZXMsXG4gICAgICAgIHRvdGFsU291cmNlRmlsZXM6IGFuYWx5c2lzLmZpbGVzLmxlbmd0aCxcbiAgICAgICAgdG90YWxUZXN0RmlsZXM6IGFuYWx5c2lzLnRlc3RGaWxlcy5sZW5ndGgsXG4gICAgICAgIGhhc1JlYWRtZTogQm9vbGVhbihhbmFseXNpcy5yZWFkbWUpLFxuICAgICAgfSxcbiAgICAgIGd1aWRhbmNlOiBwcm9tcHRTZWN0aW9ucyxcbiAgICAgIHN1Z2dlc3RlZEV4YW1wbGVzOiBleGFtcGxlcyxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IEpTT04uc3RyaW5naWZ5KHBheWxvYWQsIG51bGwsIDIpLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9IHNhdGlzZmllcyBDb250ZW50UmVzdWx0O1xuICB9LFxufTtcbiJdfQ==
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Tool } from "fastmcp";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
declare const generateSchema: z.ZodObject<{
|
|
4
|
+
repoPath: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
5
|
+
moduleName: z.ZodOptional<z.ZodString>;
|
|
6
|
+
includeDocs: z.ZodDefault<z.ZodBoolean>;
|
|
7
|
+
}, z.core.$strip>;
|
|
8
|
+
export declare const generateMcpModuleTool: Tool<undefined, typeof generateSchema>;
|
|
9
|
+
export default generateMcpModuleTool;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// New tool: generate-mcp-module
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { getWorkspaceRoot } from "../workspace";
|
|
6
|
+
import { analyzeRepo } from "../code";
|
|
7
|
+
import { scaffoldModule } from "../validation/scaffoldModule";
|
|
8
|
+
const generateSchema = z.object({
|
|
9
|
+
repoPath: z.string().optional().default("."),
|
|
10
|
+
moduleName: z.string().optional(),
|
|
11
|
+
includeDocs: z.boolean().default(true),
|
|
12
|
+
});
|
|
13
|
+
export const generateMcpModuleTool = {
|
|
14
|
+
name: "generate-mcp-module",
|
|
15
|
+
description: "Generate a minimal MCP module under src/modules/<name> by analyzing a target repository and exporting prompts, resources, templates and tools.",
|
|
16
|
+
parameters: generateSchema,
|
|
17
|
+
execute: async (input) => {
|
|
18
|
+
const args = generateSchema.parse(input);
|
|
19
|
+
const root = getWorkspaceRoot();
|
|
20
|
+
let repoRoot = path.resolve(process.cwd(), args.repoPath || ".");
|
|
21
|
+
if (!fs.existsSync(repoRoot)) {
|
|
22
|
+
const alt = path.resolve(process.cwd(), "..", args.repoPath);
|
|
23
|
+
if (fs.existsSync(alt))
|
|
24
|
+
repoRoot = alt;
|
|
25
|
+
}
|
|
26
|
+
if (!fs.existsSync(repoRoot)) {
|
|
27
|
+
const alt2 = path.resolve(process.cwd(), "..", path.basename(args.repoPath));
|
|
28
|
+
if (fs.existsSync(alt2))
|
|
29
|
+
repoRoot = alt2;
|
|
30
|
+
}
|
|
31
|
+
if (!fs.existsSync(repoRoot))
|
|
32
|
+
throw new Error(`Repository not found at ${repoRoot}`);
|
|
33
|
+
const analysis = analyzeRepo(repoRoot);
|
|
34
|
+
const inferredName = args.moduleName ?? path.basename(path.resolve(repoRoot));
|
|
35
|
+
const moduleRoot = path.join(root, "src", "modules", inferredName);
|
|
36
|
+
// Use existing scaffold to create folders
|
|
37
|
+
scaffoldModule(root, inferredName);
|
|
38
|
+
// populate prompts: copy markdown prompts from README.md and docs/
|
|
39
|
+
const promptsDir = path.join(moduleRoot, "prompts");
|
|
40
|
+
const resourcesDir = path.join(moduleRoot, "resources");
|
|
41
|
+
const templatesDir = path.join(moduleRoot, "templates");
|
|
42
|
+
const toolsDir = path.join(moduleRoot, "tools");
|
|
43
|
+
// helper to write an index.ts that exports arrays
|
|
44
|
+
function writeIndex(dir, varName, items) {
|
|
45
|
+
const p = path.join(dir, "index.ts");
|
|
46
|
+
const content = `export const ${varName} = ${items} as const;\n`;
|
|
47
|
+
fs.writeFileSync(p, content, { encoding: "utf8" });
|
|
48
|
+
}
|
|
49
|
+
// Prompts: create a simple prompt from README and any .md in docs
|
|
50
|
+
const promptAssets = [];
|
|
51
|
+
if (args.includeDocs) {
|
|
52
|
+
const readme = path.join(repoRoot, "README.md");
|
|
53
|
+
if (fs.existsSync(readme)) {
|
|
54
|
+
const content = fs.readFileSync(readme, "utf8");
|
|
55
|
+
const id = "readme";
|
|
56
|
+
const promptPath = path.join(promptsDir, `${id}.md`);
|
|
57
|
+
fs.writeFileSync(promptPath, content, { encoding: "utf8" });
|
|
58
|
+
promptAssets.push({
|
|
59
|
+
id,
|
|
60
|
+
title: "README",
|
|
61
|
+
description: "Repository README",
|
|
62
|
+
absolutePath: promptPath,
|
|
63
|
+
load: () => content,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
const docsDir = path.join(repoRoot, "docs");
|
|
67
|
+
if (fs.existsSync(docsDir) && fs.statSync(docsDir).isDirectory()) {
|
|
68
|
+
for (const f of fs.readdirSync(docsDir)) {
|
|
69
|
+
if (!f.endsWith(".md"))
|
|
70
|
+
continue;
|
|
71
|
+
const content = fs.readFileSync(path.join(docsDir, f), "utf8");
|
|
72
|
+
const id = path.parse(f).name;
|
|
73
|
+
const promptPath = path.join(promptsDir, `${id}.md`);
|
|
74
|
+
fs.writeFileSync(promptPath, content, { encoding: "utf8" });
|
|
75
|
+
promptAssets.push({
|
|
76
|
+
id,
|
|
77
|
+
title: id,
|
|
78
|
+
description: content.split(/\r?\n/)[0] || "",
|
|
79
|
+
absolutePath: promptPath,
|
|
80
|
+
load: () => content,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
writeIndex(promptsDir, "prompts", JSON.stringify(promptAssets, null, 2));
|
|
86
|
+
// Resources: reference the repo root and docs
|
|
87
|
+
const resourceAssets = [
|
|
88
|
+
{
|
|
89
|
+
id: `${inferredName}.repo`,
|
|
90
|
+
name: `${inferredName} repository`,
|
|
91
|
+
description: "Source repository",
|
|
92
|
+
uri: `file://${repoRoot}`,
|
|
93
|
+
absolutePath: repoRoot,
|
|
94
|
+
},
|
|
95
|
+
];
|
|
96
|
+
writeIndex(resourcesDir, "resources", JSON.stringify(resourceAssets, null, 2));
|
|
97
|
+
// Templates: create a placeholder template that references README
|
|
98
|
+
const templateAssets = [
|
|
99
|
+
{
|
|
100
|
+
name: "readme-template",
|
|
101
|
+
description: "README as guidance",
|
|
102
|
+
uriTemplate: `file://${path.join(repoRoot, "README.md")}`,
|
|
103
|
+
mimeType: "text/markdown",
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
writeIndex(templatesDir, "templates", JSON.stringify(templateAssets, null, 2));
|
|
107
|
+
// Tools: create a wrapper tool that exposes analyze/enumerate for the module
|
|
108
|
+
const toolIndexPath = path.join(toolsDir, "index.ts");
|
|
109
|
+
const toolContent = `import type { Tool } from 'fastmcp';\nimport { buildAnalyzeRepositoryTool, buildEnumerateCapabilitiesTool, buildPlanFeatureTool } from '../../../mcp/tools/tools';\nexport const tools = [\n { id: '${inferredName}.analyze', title: 'Analyze ${inferredName}', description: 'Analyze the target repository', tool: buildAnalyzeRepositoryTool() },\n { id: '${inferredName}.enumerate', title: 'Enumerate capabilities for ${inferredName}', description: 'Enumerate capabilities', tool: buildEnumerateCapabilitiesTool() },\n { id: '${inferredName}.plan', title: 'Plan features for ${inferredName}', description: 'Plan feature implementation', tool: buildPlanFeatureTool() },\n] as const;\n`;
|
|
110
|
+
fs.writeFileSync(toolIndexPath, toolContent, { encoding: "utf8" });
|
|
111
|
+
// Write module index.ts
|
|
112
|
+
const moduleIndex = path.join(moduleRoot, "index.ts");
|
|
113
|
+
const moduleIndexContent = `import { prompts } from './prompts';\nimport { resources } from './resources';\nimport { templates } from './templates';\nimport { tools } from './tools';\nexport { prompts } from './prompts';\nexport { resources } from './resources';\nexport { templates } from './templates';\nexport { tools } from './tools';\nexport const modulePackage = { name: '${inferredName}', prompts, resources, templates, tools } as const;\n`;
|
|
114
|
+
fs.writeFileSync(moduleIndex, moduleIndexContent, { encoding: "utf8" });
|
|
115
|
+
return {
|
|
116
|
+
content: [
|
|
117
|
+
{
|
|
118
|
+
type: "text",
|
|
119
|
+
text: JSON.stringify({
|
|
120
|
+
moduleRoot,
|
|
121
|
+
inferredName,
|
|
122
|
+
analysisSummary: {
|
|
123
|
+
files: analysis.files.length,
|
|
124
|
+
testFiles: analysis.testFiles.length,
|
|
125
|
+
},
|
|
126
|
+
}, null, 2),
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
};
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
export default generateMcpModuleTool;
|
|
133
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVNY3BNb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbWNwL3Rvb2xzL2dlbmVyYXRlTWNwTW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGdDQUFnQztBQUNoQyxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDcEIsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBRXhCLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDeEIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ2hELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDdEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRTlELE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDOUIsUUFBUSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDO0lBQzVDLFVBQVUsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ2pDLFdBQVcsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztDQUN2QyxDQUFDLENBQUM7QUFJSCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBMkM7SUFDM0UsSUFBSSxFQUFFLHFCQUFxQjtJQUMzQixXQUFXLEVBQ1QsZ0pBQWdKO0lBQ2xKLFVBQVUsRUFBRSxjQUFjO0lBQzFCLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7UUFDdkIsTUFBTSxJQUFJLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxLQUFZLENBQUMsQ0FBQztRQUNoRCxNQUFNLElBQUksR0FBRyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ2hDLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLElBQUksQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFDLENBQUM7UUFDakUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUM3QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzdELElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUM7Z0JBQUUsUUFBUSxHQUFHLEdBQUcsQ0FBQztRQUN6QyxDQUFDO1FBQ0QsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUM3QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUN2QixPQUFPLENBQUMsR0FBRyxFQUFFLEVBQ2IsSUFBSSxFQUNKLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUM3QixDQUFDO1lBQ0YsSUFBSSxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztnQkFBRSxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQzNDLENBQUM7UUFDRCxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUM7WUFDMUIsTUFBTSxJQUFJLEtBQUssQ0FBQywyQkFBMkIsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUV6RCxNQUFNLFFBQVEsR0FBRyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdkMsTUFBTSxZQUFZLEdBQ2hCLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDM0QsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUVuRSwwQ0FBMEM7UUFDMUMsY0FBYyxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQztRQUVuQyxtRUFBbUU7UUFDbkUsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDcEQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDeEQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDeEQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFaEQsa0RBQWtEO1FBQ2xELFNBQVMsVUFBVSxDQUFDLEdBQVcsRUFBRSxPQUFlLEVBQUUsS0FBYTtZQUM3RCxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUNyQyxNQUFNLE9BQU8sR0FBRyxnQkFBZ0IsT0FBTyxNQUFNLEtBQUssY0FBYyxDQUFDO1lBQ2pFLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3JELENBQUM7UUFFRCxrRUFBa0U7UUFDbEUsTUFBTSxZQUFZLEdBQVUsRUFBRSxDQUFDO1FBQy9CLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3JCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQ2hELElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO2dCQUMxQixNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDaEQsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDO2dCQUNwQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQ3JELEVBQUUsQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO2dCQUM1RCxZQUFZLENBQUMsSUFBSSxDQUFDO29CQUNoQixFQUFFO29CQUNGLEtBQUssRUFBRSxRQUFRO29CQUNmLFdBQVcsRUFBRSxtQkFBbUI7b0JBQ2hDLFlBQVksRUFBRSxVQUFVO29CQUN4QixJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsT0FBTztpQkFDcEIsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUNELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzVDLElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7Z0JBQ2pFLEtBQUssTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO29CQUN4QyxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7d0JBQUUsU0FBUztvQkFDakMsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztvQkFDL0QsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQzlCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDckQsRUFBRSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsT0FBTyxFQUFFLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7b0JBQzVELFlBQVksQ0FBQyxJQUFJLENBQUM7d0JBQ2hCLEVBQUU7d0JBQ0YsS0FBSyxFQUFFLEVBQUU7d0JBQ1QsV0FBVyxFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRTt3QkFDNUMsWUFBWSxFQUFFLFVBQVU7d0JBQ3hCLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPO3FCQUNwQixDQUFDLENBQUM7Z0JBQ0wsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsVUFBVSxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFekUsOENBQThDO1FBQzlDLE1BQU0sY0FBYyxHQUFHO1lBQ3JCO2dCQUNFLEVBQUUsRUFBRSxHQUFHLFlBQVksT0FBTztnQkFDMUIsSUFBSSxFQUFFLEdBQUcsWUFBWSxhQUFhO2dCQUNsQyxXQUFXLEVBQUUsbUJBQW1CO2dCQUNoQyxHQUFHLEVBQUUsVUFBVSxRQUFRLEVBQUU7Z0JBQ3pCLFlBQVksRUFBRSxRQUFRO2FBQ3ZCO1NBQ0YsQ0FBQztRQUNGLFVBQVUsQ0FDUixZQUFZLEVBQ1osV0FBVyxFQUNYLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FDeEMsQ0FBQztRQUVGLGtFQUFrRTtRQUNsRSxNQUFNLGNBQWMsR0FBRztZQUNyQjtnQkFDRSxJQUFJLEVBQUUsaUJBQWlCO2dCQUN2QixXQUFXLEVBQUUsb0JBQW9CO2dCQUNqQyxXQUFXLEVBQUUsVUFBVSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxXQUFXLENBQUMsRUFBRTtnQkFDekQsUUFBUSxFQUFFLGVBQWU7YUFDMUI7U0FDRixDQUFDO1FBQ0YsVUFBVSxDQUNSLFlBQVksRUFDWixXQUFXLEVBQ1gsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUN4QyxDQUFDO1FBRUYsNkVBQTZFO1FBQzdFLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ3RELE1BQU0sV0FBVyxHQUFHLHdNQUF3TSxZQUFZLDhCQUE4QixZQUFZLG9HQUFvRyxZQUFZLG1EQUFtRCxZQUFZLGlHQUFpRyxZQUFZLHFDQUFxQyxZQUFZLCtGQUErRixDQUFDO1FBQy9yQixFQUFFLENBQUMsYUFBYSxDQUFDLGFBQWEsRUFBRSxXQUFXLEVBQUUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUVuRSx3QkFBd0I7UUFDeEIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDdEQsTUFBTSxrQkFBa0IsR0FBRyxpV0FBaVcsWUFBWSx1REFBdUQsQ0FBQztRQUNoYyxFQUFFLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxrQkFBa0IsRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBRXhFLE9BQU87WUFDTCxPQUFPLEVBQUU7Z0JBQ1A7b0JBQ0UsSUFBSSxFQUFFLE1BQU07b0JBQ1osSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQ2xCO3dCQUNFLFVBQVU7d0JBQ1YsWUFBWTt3QkFDWixlQUFlLEVBQUU7NEJBQ2YsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTTs0QkFDNUIsU0FBUyxFQUFFLFFBQVEsQ0FBQyxTQUFTLENBQUMsTUFBTTt5QkFDckM7cUJBQ0YsRUFDRCxJQUFJLEVBQ0osQ0FBQyxDQUNGO2lCQUNGO2FBQ0Y7U0FDRixDQUFDO0lBQ0osQ0FBQztDQUNGLENBQUM7QUFFRixlQUFlLHFCQUFxQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gTmV3IHRvb2w6IGdlbmVyYXRlLW1jcC1tb2R1bGVcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgdHlwZSB7IFRvb2wgfSBmcm9tIFwiZmFzdG1jcFwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB7IGdldFdvcmtzcGFjZVJvb3QgfSBmcm9tIFwiLi4vd29ya3NwYWNlXCI7XG5pbXBvcnQgeyBhbmFseXplUmVwbyB9IGZyb20gXCIuLi9jb2RlXCI7XG5pbXBvcnQgeyBzY2FmZm9sZE1vZHVsZSB9IGZyb20gXCIuLi92YWxpZGF0aW9uL3NjYWZmb2xkTW9kdWxlXCI7XG5cbmNvbnN0IGdlbmVyYXRlU2NoZW1hID0gei5vYmplY3Qoe1xuICByZXBvUGF0aDogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlZmF1bHQoXCIuXCIpLFxuICBtb2R1bGVOYW1lOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gIGluY2x1ZGVEb2NzOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxufSk7XG5cbnR5cGUgR2VuZXJhdGVBcmdzID0gei5pbmZlcjx0eXBlb2YgZ2VuZXJhdGVTY2hlbWE+O1xuXG5leHBvcnQgY29uc3QgZ2VuZXJhdGVNY3BNb2R1bGVUb29sOiBUb29sPHVuZGVmaW5lZCwgdHlwZW9mIGdlbmVyYXRlU2NoZW1hPiA9IHtcbiAgbmFtZTogXCJnZW5lcmF0ZS1tY3AtbW9kdWxlXCIsXG4gIGRlc2NyaXB0aW9uOlxuICAgIFwiR2VuZXJhdGUgYSBtaW5pbWFsIE1DUCBtb2R1bGUgdW5kZXIgc3JjL21vZHVsZXMvPG5hbWU+IGJ5IGFuYWx5emluZyBhIHRhcmdldCByZXBvc2l0b3J5IGFuZCBleHBvcnRpbmcgcHJvbXB0cywgcmVzb3VyY2VzLCB0ZW1wbGF0ZXMgYW5kIHRvb2xzLlwiLFxuICBwYXJhbWV0ZXJzOiBnZW5lcmF0ZVNjaGVtYSxcbiAgZXhlY3V0ZTogYXN5bmMgKGlucHV0KSA9PiB7XG4gICAgY29uc3QgYXJncyA9IGdlbmVyYXRlU2NoZW1hLnBhcnNlKGlucHV0IGFzIGFueSk7XG4gICAgY29uc3Qgcm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKTtcbiAgICBsZXQgcmVwb1Jvb3QgPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgYXJncy5yZXBvUGF0aCB8fCBcIi5cIik7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHJlcG9Sb290KSkge1xuICAgICAgY29uc3QgYWx0ID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIFwiLi5cIiwgYXJncy5yZXBvUGF0aCk7XG4gICAgICBpZiAoZnMuZXhpc3RzU3luYyhhbHQpKSByZXBvUm9vdCA9IGFsdDtcbiAgICB9XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHJlcG9Sb290KSkge1xuICAgICAgY29uc3QgYWx0MiA9IHBhdGgucmVzb2x2ZShcbiAgICAgICAgcHJvY2Vzcy5jd2QoKSxcbiAgICAgICAgXCIuLlwiLFxuICAgICAgICBwYXRoLmJhc2VuYW1lKGFyZ3MucmVwb1BhdGgpXG4gICAgICApO1xuICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoYWx0MikpIHJlcG9Sb290ID0gYWx0MjtcbiAgICB9XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHJlcG9Sb290KSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUmVwb3NpdG9yeSBub3QgZm91bmQgYXQgJHtyZXBvUm9vdH1gKTtcblxuICAgIGNvbnN0IGFuYWx5c2lzID0gYW5hbHl6ZVJlcG8ocmVwb1Jvb3QpO1xuICAgIGNvbnN0IGluZmVycmVkTmFtZSA9XG4gICAgICBhcmdzLm1vZHVsZU5hbWUgPz8gcGF0aC5iYXNlbmFtZShwYXRoLnJlc29sdmUocmVwb1Jvb3QpKTtcbiAgICBjb25zdCBtb2R1bGVSb290ID0gcGF0aC5qb2luKHJvb3QsIFwic3JjXCIsIFwibW9kdWxlc1wiLCBpbmZlcnJlZE5hbWUpO1xuXG4gICAgLy8gVXNlIGV4aXN0aW5nIHNjYWZmb2xkIHRvIGNyZWF0ZSBmb2xkZXJzXG4gICAgc2NhZmZvbGRNb2R1bGUocm9vdCwgaW5mZXJyZWROYW1lKTtcblxuICAgIC8vIHBvcHVsYXRlIHByb21wdHM6IGNvcHkgbWFya2Rvd24gcHJvbXB0cyBmcm9tIFJFQURNRS5tZCBhbmQgZG9jcy9cbiAgICBjb25zdCBwcm9tcHRzRGlyID0gcGF0aC5qb2luKG1vZHVsZVJvb3QsIFwicHJvbXB0c1wiKTtcbiAgICBjb25zdCByZXNvdXJjZXNEaXIgPSBwYXRoLmpvaW4obW9kdWxlUm9vdCwgXCJyZXNvdXJjZXNcIik7XG4gICAgY29uc3QgdGVtcGxhdGVzRGlyID0gcGF0aC5qb2luKG1vZHVsZVJvb3QsIFwidGVtcGxhdGVzXCIpO1xuICAgIGNvbnN0IHRvb2xzRGlyID0gcGF0aC5qb2luKG1vZHVsZVJvb3QsIFwidG9vbHNcIik7XG5cbiAgICAvLyBoZWxwZXIgdG8gd3JpdGUgYW4gaW5kZXgudHMgdGhhdCBleHBvcnRzIGFycmF5c1xuICAgIGZ1bmN0aW9uIHdyaXRlSW5kZXgoZGlyOiBzdHJpbmcsIHZhck5hbWU6IHN0cmluZywgaXRlbXM6IHN0cmluZykge1xuICAgICAgY29uc3QgcCA9IHBhdGguam9pbihkaXIsIFwiaW5kZXgudHNcIik7XG4gICAgICBjb25zdCBjb250ZW50ID0gYGV4cG9ydCBjb25zdCAke3Zhck5hbWV9ID0gJHtpdGVtc30gYXMgY29uc3Q7XFxuYDtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMocCwgY29udGVudCwgeyBlbmNvZGluZzogXCJ1dGY4XCIgfSk7XG4gICAgfVxuXG4gICAgLy8gUHJvbXB0czogY3JlYXRlIGEgc2ltcGxlIHByb21wdCBmcm9tIFJFQURNRSBhbmQgYW55IC5tZCBpbiBkb2NzXG4gICAgY29uc3QgcHJvbXB0QXNzZXRzOiBhbnlbXSA9IFtdO1xuICAgIGlmIChhcmdzLmluY2x1ZGVEb2NzKSB7XG4gICAgICBjb25zdCByZWFkbWUgPSBwYXRoLmpvaW4ocmVwb1Jvb3QsIFwiUkVBRE1FLm1kXCIpO1xuICAgICAgaWYgKGZzLmV4aXN0c1N5bmMocmVhZG1lKSkge1xuICAgICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKHJlYWRtZSwgXCJ1dGY4XCIpO1xuICAgICAgICBjb25zdCBpZCA9IFwicmVhZG1lXCI7XG4gICAgICAgIGNvbnN0IHByb21wdFBhdGggPSBwYXRoLmpvaW4ocHJvbXB0c0RpciwgYCR7aWR9Lm1kYCk7XG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMocHJvbXB0UGF0aCwgY29udGVudCwgeyBlbmNvZGluZzogXCJ1dGY4XCIgfSk7XG4gICAgICAgIHByb21wdEFzc2V0cy5wdXNoKHtcbiAgICAgICAgICBpZCxcbiAgICAgICAgICB0aXRsZTogXCJSRUFETUVcIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjogXCJSZXBvc2l0b3J5IFJFQURNRVwiLFxuICAgICAgICAgIGFic29sdXRlUGF0aDogcHJvbXB0UGF0aCxcbiAgICAgICAgICBsb2FkOiAoKSA9PiBjb250ZW50LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRvY3NEaXIgPSBwYXRoLmpvaW4ocmVwb1Jvb3QsIFwiZG9jc1wiKTtcbiAgICAgIGlmIChmcy5leGlzdHNTeW5jKGRvY3NEaXIpICYmIGZzLnN0YXRTeW5jKGRvY3NEaXIpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgZm9yIChjb25zdCBmIG9mIGZzLnJlYWRkaXJTeW5jKGRvY3NEaXIpKSB7XG4gICAgICAgICAgaWYgKCFmLmVuZHNXaXRoKFwiLm1kXCIpKSBjb250aW51ZTtcbiAgICAgICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKHBhdGguam9pbihkb2NzRGlyLCBmKSwgXCJ1dGY4XCIpO1xuICAgICAgICAgIGNvbnN0IGlkID0gcGF0aC5wYXJzZShmKS5uYW1lO1xuICAgICAgICAgIGNvbnN0IHByb21wdFBhdGggPSBwYXRoLmpvaW4ocHJvbXB0c0RpciwgYCR7aWR9Lm1kYCk7XG4gICAgICAgICAgZnMud3JpdGVGaWxlU3luYyhwcm9tcHRQYXRoLCBjb250ZW50LCB7IGVuY29kaW5nOiBcInV0ZjhcIiB9KTtcbiAgICAgICAgICBwcm9tcHRBc3NldHMucHVzaCh7XG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIHRpdGxlOiBpZCxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBjb250ZW50LnNwbGl0KC9cXHI/XFxuLylbMF0gfHwgXCJcIixcbiAgICAgICAgICAgIGFic29sdXRlUGF0aDogcHJvbXB0UGF0aCxcbiAgICAgICAgICAgIGxvYWQ6ICgpID0+IGNvbnRlbnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICB3cml0ZUluZGV4KHByb21wdHNEaXIsIFwicHJvbXB0c1wiLCBKU09OLnN0cmluZ2lmeShwcm9tcHRBc3NldHMsIG51bGwsIDIpKTtcblxuICAgIC8vIFJlc291cmNlczogcmVmZXJlbmNlIHRoZSByZXBvIHJvb3QgYW5kIGRvY3NcbiAgICBjb25zdCByZXNvdXJjZUFzc2V0cyA9IFtcbiAgICAgIHtcbiAgICAgICAgaWQ6IGAke2luZmVycmVkTmFtZX0ucmVwb2AsXG4gICAgICAgIG5hbWU6IGAke2luZmVycmVkTmFtZX0gcmVwb3NpdG9yeWAsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlNvdXJjZSByZXBvc2l0b3J5XCIsXG4gICAgICAgIHVyaTogYGZpbGU6Ly8ke3JlcG9Sb290fWAsXG4gICAgICAgIGFic29sdXRlUGF0aDogcmVwb1Jvb3QsXG4gICAgICB9LFxuICAgIF07XG4gICAgd3JpdGVJbmRleChcbiAgICAgIHJlc291cmNlc0RpcixcbiAgICAgIFwicmVzb3VyY2VzXCIsXG4gICAgICBKU09OLnN0cmluZ2lmeShyZXNvdXJjZUFzc2V0cywgbnVsbCwgMilcbiAgICApO1xuXG4gICAgLy8gVGVtcGxhdGVzOiBjcmVhdGUgYSBwbGFjZWhvbGRlciB0ZW1wbGF0ZSB0aGF0IHJlZmVyZW5jZXMgUkVBRE1FXG4gICAgY29uc3QgdGVtcGxhdGVBc3NldHMgPSBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6IFwicmVhZG1lLXRlbXBsYXRlXCIsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlJFQURNRSBhcyBndWlkYW5jZVwiLFxuICAgICAgICB1cmlUZW1wbGF0ZTogYGZpbGU6Ly8ke3BhdGguam9pbihyZXBvUm9vdCwgXCJSRUFETUUubWRcIil9YCxcbiAgICAgICAgbWltZVR5cGU6IFwidGV4dC9tYXJrZG93blwiLFxuICAgICAgfSxcbiAgICBdO1xuICAgIHdyaXRlSW5kZXgoXG4gICAgICB0ZW1wbGF0ZXNEaXIsXG4gICAgICBcInRlbXBsYXRlc1wiLFxuICAgICAgSlNPTi5zdHJpbmdpZnkodGVtcGxhdGVBc3NldHMsIG51bGwsIDIpXG4gICAgKTtcblxuICAgIC8vIFRvb2xzOiBjcmVhdGUgYSB3cmFwcGVyIHRvb2wgdGhhdCBleHBvc2VzIGFuYWx5emUvZW51bWVyYXRlIGZvciB0aGUgbW9kdWxlXG4gICAgY29uc3QgdG9vbEluZGV4UGF0aCA9IHBhdGguam9pbih0b29sc0RpciwgXCJpbmRleC50c1wiKTtcbiAgICBjb25zdCB0b29sQ29udGVudCA9IGBpbXBvcnQgdHlwZSB7IFRvb2wgfSBmcm9tICdmYXN0bWNwJztcXG5pbXBvcnQgeyBidWlsZEFuYWx5emVSZXBvc2l0b3J5VG9vbCwgYnVpbGRFbnVtZXJhdGVDYXBhYmlsaXRpZXNUb29sLCBidWlsZFBsYW5GZWF0dXJlVG9vbCB9IGZyb20gJy4uLy4uLy4uL21jcC90b29scy90b29scyc7XFxuZXhwb3J0IGNvbnN0IHRvb2xzID0gW1xcbiAgeyBpZDogJyR7aW5mZXJyZWROYW1lfS5hbmFseXplJywgdGl0bGU6ICdBbmFseXplICR7aW5mZXJyZWROYW1lfScsIGRlc2NyaXB0aW9uOiAnQW5hbHl6ZSB0aGUgdGFyZ2V0IHJlcG9zaXRvcnknLCB0b29sOiBidWlsZEFuYWx5emVSZXBvc2l0b3J5VG9vbCgpIH0sXFxuICB7IGlkOiAnJHtpbmZlcnJlZE5hbWV9LmVudW1lcmF0ZScsIHRpdGxlOiAnRW51bWVyYXRlIGNhcGFiaWxpdGllcyBmb3IgJHtpbmZlcnJlZE5hbWV9JywgZGVzY3JpcHRpb246ICdFbnVtZXJhdGUgY2FwYWJpbGl0aWVzJywgdG9vbDogYnVpbGRFbnVtZXJhdGVDYXBhYmlsaXRpZXNUb29sKCkgfSxcXG4gIHsgaWQ6ICcke2luZmVycmVkTmFtZX0ucGxhbicsIHRpdGxlOiAnUGxhbiBmZWF0dXJlcyBmb3IgJHtpbmZlcnJlZE5hbWV9JywgZGVzY3JpcHRpb246ICdQbGFuIGZlYXR1cmUgaW1wbGVtZW50YXRpb24nLCB0b29sOiBidWlsZFBsYW5GZWF0dXJlVG9vbCgpIH0sXFxuXSBhcyBjb25zdDtcXG5gO1xuICAgIGZzLndyaXRlRmlsZVN5bmModG9vbEluZGV4UGF0aCwgdG9vbENvbnRlbnQsIHsgZW5jb2Rpbmc6IFwidXRmOFwiIH0pO1xuXG4gICAgLy8gV3JpdGUgbW9kdWxlIGluZGV4LnRzXG4gICAgY29uc3QgbW9kdWxlSW5kZXggPSBwYXRoLmpvaW4obW9kdWxlUm9vdCwgXCJpbmRleC50c1wiKTtcbiAgICBjb25zdCBtb2R1bGVJbmRleENvbnRlbnQgPSBgaW1wb3J0IHsgcHJvbXB0cyB9IGZyb20gJy4vcHJvbXB0cyc7XFxuaW1wb3J0IHsgcmVzb3VyY2VzIH0gZnJvbSAnLi9yZXNvdXJjZXMnO1xcbmltcG9ydCB7IHRlbXBsYXRlcyB9IGZyb20gJy4vdGVtcGxhdGVzJztcXG5pbXBvcnQgeyB0b29scyB9IGZyb20gJy4vdG9vbHMnO1xcbmV4cG9ydCB7IHByb21wdHMgfSBmcm9tICcuL3Byb21wdHMnO1xcbmV4cG9ydCB7IHJlc291cmNlcyB9IGZyb20gJy4vcmVzb3VyY2VzJztcXG5leHBvcnQgeyB0ZW1wbGF0ZXMgfSBmcm9tICcuL3RlbXBsYXRlcyc7XFxuZXhwb3J0IHsgdG9vbHMgfSBmcm9tICcuL3Rvb2xzJztcXG5leHBvcnQgY29uc3QgbW9kdWxlUGFja2FnZSA9IHsgbmFtZTogJyR7aW5mZXJyZWROYW1lfScsIHByb21wdHMsIHJlc291cmNlcywgdGVtcGxhdGVzLCB0b29scyB9IGFzIGNvbnN0O1xcbmA7XG4gICAgZnMud3JpdGVGaWxlU3luYyhtb2R1bGVJbmRleCwgbW9kdWxlSW5kZXhDb250ZW50LCB7IGVuY29kaW5nOiBcInV0ZjhcIiB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbW9kdWxlUm9vdCxcbiAgICAgICAgICAgICAgaW5mZXJyZWROYW1lLFxuICAgICAgICAgICAgICBhbmFseXNpc1N1bW1hcnk6IHtcbiAgICAgICAgICAgICAgICBmaWxlczogYW5hbHlzaXMuZmlsZXMubGVuZ3RoLFxuICAgICAgICAgICAgICAgIHRlc3RGaWxlczogYW5hbHlzaXMudGVzdEZpbGVzLmxlbmd0aCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgMlxuICAgICAgICAgICksXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG4gIH0sXG59O1xuXG5leHBvcnQgZGVmYXVsdCBnZW5lcmF0ZU1jcE1vZHVsZVRvb2w7XG4iXX0=
|