fg-tracker-mcp 0.4.0 → 0.6.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/CHANGELOG.md +13 -0
- package/README.md +2 -0
- package/dist/docs.d.ts +1 -1
- package/dist/docs.js +12 -1
- package/dist/docs.js.map +1 -1
- package/dist/infra/aws.d.ts +97 -0
- package/dist/infra/aws.js +557 -0
- package/dist/infra/aws.js.map +1 -0
- package/dist/infra/diff.d.ts +15 -0
- package/dist/infra/diff.js +108 -0
- package/dist/infra/diff.js.map +1 -0
- package/dist/infra/files.d.ts +16 -0
- package/dist/infra/files.js +115 -0
- package/dist/infra/files.js.map +1 -0
- package/dist/infra/handover.d.ts +47 -0
- package/dist/infra/handover.js +437 -0
- package/dist/infra/handover.js.map +1 -0
- package/dist/infra/iac.d.ts +56 -0
- package/dist/infra/iac.js +378 -0
- package/dist/infra/iac.js.map +1 -0
- package/dist/infra/instrument.d.ts +6 -0
- package/dist/infra/instrument.js +140 -0
- package/dist/infra/instrument.js.map +1 -0
- package/dist/infra/tools.d.ts +10 -0
- package/dist/infra/tools.js +700 -0
- package/dist/infra/tools.js.map +1 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +5 -1
- package/dist/server.js.map +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Análise local de IaC (tool `infra_analyze_iac`, plano-infraestrutura.md §5): apps CDK, stacks,
|
|
3
|
+
* constructs, assets, SAM, Serverless, Terraform e comandos de deploy do CI. Baseada em regex —
|
|
4
|
+
* robusta a estilos diferentes, sem executar nada do repositório.
|
|
5
|
+
*/
|
|
6
|
+
import { basename, dirname, join, posix } from 'node:path';
|
|
7
|
+
import { isSourceFile, isTestFile, lineOf, matchParen, readText, walkFiles } from './files.js';
|
|
8
|
+
const STACK_BASE = /^(?:[\w$]+\.)?(Stack)$/;
|
|
9
|
+
const CDK_VALUE_FLAGS = new Set(['--require-approval', '--context', '-c', '--profile', '--outputs-file', '-O', '--app', '-a', '--parameters', '--toolkit-stack-name', '--concurrency', '--method', '-m', '--role-arn', '-r', '--change-set-name', '--build-exclude', '-E', '--notification-arns', '--tags', '-t', '--output', '-o', '--progress', '--asset-parallelism', '--region', '--hotswap-ecs-minimum-healthy-percent', '--hotswap-ecs-maximum-healthy-percent']);
|
|
10
|
+
function lineRange(content, start, end) {
|
|
11
|
+
return [lineOf(content, start), lineOf(content, end)];
|
|
12
|
+
}
|
|
13
|
+
function uniq(xs) {
|
|
14
|
+
return [...new Set(xs)];
|
|
15
|
+
}
|
|
16
|
+
function resolveRelative(fromFile, spec, files) {
|
|
17
|
+
const base = posix.normalize(posix.join(posix.dirname(fromFile), spec));
|
|
18
|
+
const candidates = [base, `${base}.ts`, `${base}.js`, `${base}.mjs`, `${base}/index.ts`, `${base}/index.js`, base.replace(/\.js$/, '.ts')];
|
|
19
|
+
return candidates.find((c) => files.has(c)) ?? null;
|
|
20
|
+
}
|
|
21
|
+
function constructsOf(content) {
|
|
22
|
+
const out = [];
|
|
23
|
+
for (const m of content.matchAll(/from\s+['"](?:aws-cdk-lib\/|@aws-cdk\/)(aws-[\w-]+)(?:\/[\w-]+)?['"]/g))
|
|
24
|
+
if (m[1])
|
|
25
|
+
out.push(m[1]);
|
|
26
|
+
for (const m of content.matchAll(/require\(\s*['"](?:aws-cdk-lib\/|@aws-cdk\/)(aws-[\w-]+)['"]\s*\)/g))
|
|
27
|
+
if (m[1])
|
|
28
|
+
out.push(m[1]);
|
|
29
|
+
return uniq(out);
|
|
30
|
+
}
|
|
31
|
+
const ASSET_PATTERNS = [
|
|
32
|
+
{ kind: 'lambda.Code.fromAsset', re: /\bCode\.fromAsset\s*\(([^)\n]*)/g },
|
|
33
|
+
{ kind: 'lambda.Code.fromDockerBuild', re: /\bCode\.fromDockerBuild\s*\(([^)\n]*)/g },
|
|
34
|
+
{ kind: 'NodejsFunction', re: /new\s+(?:[\w$]+\.)?NodejsFunction\s*\(([^)\n]*)/g },
|
|
35
|
+
{ kind: 'PythonFunction', re: /new\s+(?:[\w$]+\.)?PythonFunction\s*\(([^)\n]*)/g },
|
|
36
|
+
{ kind: 'GoFunction', re: /new\s+(?:[\w$]+\.)?GoFunction\s*\(([^)\n]*)/g },
|
|
37
|
+
{ kind: 'DockerImageFunction', re: /new\s+(?:[\w$]+\.)?DockerImageFunction\s*\(([^)\n]*)/g },
|
|
38
|
+
{ kind: 'DockerImageCode.fromImageAsset', re: /\bDockerImageCode\.fromImageAsset\s*\(([^)\n]*)/g },
|
|
39
|
+
{ kind: 'ContainerImage.fromAsset', re: /\bContainerImage\.fromAsset\s*\(([^)\n]*)/g },
|
|
40
|
+
{ kind: 'DockerImageAsset', re: /new\s+(?:[\w$]+\.)?DockerImageAsset\s*\(([^)\n]*)/g },
|
|
41
|
+
{ kind: 's3deploy.Source.asset', re: /\bSource\.asset\s*\(([^)\n]*)/g },
|
|
42
|
+
{ kind: 's3_assets.Asset', re: /new\s+(?:s3assets\.|assets\.)Asset\s*\(([^)\n]*)/g },
|
|
43
|
+
];
|
|
44
|
+
function assetsOf(file, content) {
|
|
45
|
+
const out = [];
|
|
46
|
+
for (const { kind, re } of ASSET_PATTERNS) {
|
|
47
|
+
for (const m of content.matchAll(re)) {
|
|
48
|
+
let detail = (m[1] ?? '').trim().slice(0, 120);
|
|
49
|
+
if (kind === 'NodejsFunction' || kind === 'PythonFunction' || kind === 'GoFunction') {
|
|
50
|
+
const window = content.slice(m.index ?? 0, (m.index ?? 0) + 600);
|
|
51
|
+
const entry = /entry\s*:\s*([^,\n}]+)/.exec(window);
|
|
52
|
+
if (entry?.[1])
|
|
53
|
+
detail = `entry: ${entry[1].trim()}`;
|
|
54
|
+
}
|
|
55
|
+
out.push({ kind, file, line: lineOf(content, m.index ?? 0), detail });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
/* ---------------- CDK ---------------- */
|
|
61
|
+
async function analyzeCdk(root, files, fileSet, warnings) {
|
|
62
|
+
const apps = [];
|
|
63
|
+
const stacks = [];
|
|
64
|
+
const cdkJsons = files.filter((f) => basename(f) === 'cdk.json');
|
|
65
|
+
const contents = new Map();
|
|
66
|
+
const load = async (f) => {
|
|
67
|
+
if (!contents.has(f))
|
|
68
|
+
contents.set(f, (await readText(join(root, f))) ?? '');
|
|
69
|
+
return contents.get(f) ?? '';
|
|
70
|
+
};
|
|
71
|
+
for (const cdkJson of cdkJsons) {
|
|
72
|
+
const dir = dirname(cdkJson) === '.' ? '' : dirname(cdkJson);
|
|
73
|
+
const prefix = dir ? `${dir}/` : '';
|
|
74
|
+
let appCommand = null;
|
|
75
|
+
let contextKeys = [];
|
|
76
|
+
try {
|
|
77
|
+
const parsed = JSON.parse(await load(cdkJson));
|
|
78
|
+
appCommand = parsed.app ?? null;
|
|
79
|
+
contextKeys = Object.keys(parsed.context ?? {}).filter((k) => !k.startsWith('@aws-cdk') && !k.startsWith('aws-cdk'));
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
warnings.push(`${cdkJson}: JSON inválido.`);
|
|
83
|
+
}
|
|
84
|
+
const entryFromApp = appCommand ? [...appCommand.matchAll(/([\w@./-]+\.(?:ts|js|mjs|cjs))/g)].map((m) => posix.normalize(prefix + (m[1] ?? ''))) : [];
|
|
85
|
+
const binFiles = files.filter((f) => f.startsWith(`${prefix}bin/`) && isSourceFile(f));
|
|
86
|
+
const entryFiles = uniq([...entryFromApp.filter((f) => fileSet.has(f)), ...binFiles]);
|
|
87
|
+
if (appCommand && !entryFiles.length)
|
|
88
|
+
warnings.push(`${cdkJson}: entrada do app (\`${appCommand}\`) não encontrada — o app pode não ser TypeScript/JavaScript.`);
|
|
89
|
+
const appSources = files.filter((f) => f.startsWith(prefix) && isSourceFile(f) && !isTestFile(f));
|
|
90
|
+
// Um app aninhado (outro cdk.json mais profundo) não pertence a este.
|
|
91
|
+
const nested = cdkJsons.filter((c) => c !== cdkJson && c.startsWith(prefix)).map((c) => dirname(c) + '/');
|
|
92
|
+
const scoped = appSources.filter((f) => !nested.some((n) => f.startsWith(n)));
|
|
93
|
+
// Classes de stack (inclui herança indireta).
|
|
94
|
+
const classes = new Map();
|
|
95
|
+
for (const f of scoped) {
|
|
96
|
+
const c = await load(f);
|
|
97
|
+
if (!/\bStack\b/.test(c))
|
|
98
|
+
continue;
|
|
99
|
+
for (const m of c.matchAll(/class\s+([\w$]+)\s+extends\s+([\w$.]+)/g))
|
|
100
|
+
if (m[1] && m[2])
|
|
101
|
+
classes.set(m[1], { file: f, base: m[2] });
|
|
102
|
+
}
|
|
103
|
+
const stackClasses = new Map();
|
|
104
|
+
let changed = true;
|
|
105
|
+
while (changed) {
|
|
106
|
+
changed = false;
|
|
107
|
+
for (const [name, { file, base }] of classes) {
|
|
108
|
+
if (stackClasses.has(name))
|
|
109
|
+
continue;
|
|
110
|
+
const baseName = base.split('.').pop() ?? base;
|
|
111
|
+
if (STACK_BASE.test(base) || stackClasses.has(baseName)) {
|
|
112
|
+
stackClasses.set(name, file);
|
|
113
|
+
changed = true;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const contextFromCode = [];
|
|
118
|
+
for (const f of scoped) {
|
|
119
|
+
const c = await load(f);
|
|
120
|
+
for (const m of c.matchAll(/tryGetContext\(\s*['"]([^'"]+)['"]/g))
|
|
121
|
+
if (m[1])
|
|
122
|
+
contextFromCode.push(m[1]);
|
|
123
|
+
if (!/new\s+[\w$.]+\s*\(/.test(c))
|
|
124
|
+
continue;
|
|
125
|
+
for (const m of c.matchAll(/new\s+(?:[\w$]+\.)?([\w$]+)\s*\(\s*([\w$.]+)\s*,\s*(['"`])((?:(?!\3)[^\n])*)\3/g)) {
|
|
126
|
+
const className = m[1] ?? '';
|
|
127
|
+
const isStackClass = stackClasses.has(className) || (className === 'Stack' && /\bapp\b|App\b/i.test(m[2] ?? '')) || (/Stack$/.test(className) && className !== 'NestedStack' && !classes.has(className));
|
|
128
|
+
if (!isStackClass || /NestedStack$/.test(className))
|
|
129
|
+
continue;
|
|
130
|
+
const scopeArg = m[2] ?? '';
|
|
131
|
+
const start = m.index ?? 0;
|
|
132
|
+
const open = c.indexOf('(', start);
|
|
133
|
+
const close = matchParen(c, open);
|
|
134
|
+
if (close < 0)
|
|
135
|
+
continue;
|
|
136
|
+
let end = close + 1;
|
|
137
|
+
while (c[end] === ' ' || c[end] === '\t')
|
|
138
|
+
end++;
|
|
139
|
+
if (c[end] === ';')
|
|
140
|
+
end++;
|
|
141
|
+
const lineStart = c.lastIndexOf('\n', start) + 1;
|
|
142
|
+
const before = c.slice(lineStart, start);
|
|
143
|
+
if (/^\s*(\/\/|\*|\/\*)/.test(before))
|
|
144
|
+
continue;
|
|
145
|
+
const variable = /(?:const|let|var)\s+([\w$]+)\s*(?::\s*[\w$.<>]+\s*)?=\s*$/.exec(before)?.[1] ?? null;
|
|
146
|
+
const lineEnd = c.indexOf('\n', end);
|
|
147
|
+
const after = c.slice(end, lineEnd < 0 ? c.length : lineEnd);
|
|
148
|
+
const standalone = (before.trim() === '' || /^(?:export\s+)?(?:const|let|var)\s+[\w$]+\s*(?::\s*[\w$.<>]+\s*)?=\s*$/.test(before.trim() + ' ')) && /^\s*(\/\/.*)?$/.test(after);
|
|
149
|
+
const props = c.slice(open, close + 1);
|
|
150
|
+
const constructId = m[4] ?? '';
|
|
151
|
+
const stackNameOverride = /stackName\s*:\s*(['"`])([^'"`\n]+)\1/.exec(props)?.[2] ?? null;
|
|
152
|
+
const envMatch = /\benv\s*:\s*(\{[^}]*\}|[\w$.]+)/.exec(props);
|
|
153
|
+
const name = stackNameOverride ?? constructId;
|
|
154
|
+
const notes = [];
|
|
155
|
+
if (/\$\{/.test(name))
|
|
156
|
+
notes.push('nome dinâmico (template literal): confirme o nome real no CloudFormation.');
|
|
157
|
+
if (scopeArg === 'this')
|
|
158
|
+
notes.push('instanciado dentro de outro construct (Stage?): o nome implantado pode ter prefixo do Stage.');
|
|
159
|
+
const classFile = stackClasses.get(className) ?? null;
|
|
160
|
+
const sourceFiles = uniq([f, ...(classFile ? [classFile] : [])]);
|
|
161
|
+
let constructs = [];
|
|
162
|
+
let assets = [];
|
|
163
|
+
if (classFile) {
|
|
164
|
+
const cc = await load(classFile);
|
|
165
|
+
constructs = constructsOf(cc);
|
|
166
|
+
assets = assetsOf(classFile, cc);
|
|
167
|
+
// Um nível de imports relativos (constructs próprios).
|
|
168
|
+
for (const im of cc.matchAll(/from\s+['"](\.{1,2}\/[^'"]+)['"]/g)) {
|
|
169
|
+
const target = resolveRelative(classFile, im[1] ?? '', fileSet);
|
|
170
|
+
if (!target || target === classFile)
|
|
171
|
+
continue;
|
|
172
|
+
const tc = await load(target);
|
|
173
|
+
if (!/aws-cdk-lib|@aws-cdk|constructs/.test(tc))
|
|
174
|
+
continue;
|
|
175
|
+
sourceFiles.push(target);
|
|
176
|
+
constructs.push(...constructsOf(tc));
|
|
177
|
+
assets.push(...assetsOf(target, tc));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else if (className !== 'Stack') {
|
|
181
|
+
notes.push(`classe ${className} não encontrada no app (importada de pacote?).`);
|
|
182
|
+
}
|
|
183
|
+
stacks.push({
|
|
184
|
+
name,
|
|
185
|
+
constructId,
|
|
186
|
+
className,
|
|
187
|
+
tool: 'cdk',
|
|
188
|
+
appDir: dir || '.',
|
|
189
|
+
entryFile: f,
|
|
190
|
+
entryLines: lineRange(c, lineStart, end),
|
|
191
|
+
variable,
|
|
192
|
+
standalone,
|
|
193
|
+
sourceFiles: uniq(sourceFiles),
|
|
194
|
+
env: envMatch?.[1]?.replace(/\s+/g, ' ').trim() ?? null,
|
|
195
|
+
constructs: uniq(constructs).sort(),
|
|
196
|
+
assets,
|
|
197
|
+
resourceTypes: [],
|
|
198
|
+
handover: assets.length ? 'needs-code-deploy-split' : 'ok',
|
|
199
|
+
notes,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
apps.push({ dir: dir || '.', cdkJson, appCommand, entryFiles, contextKeys: uniq([...contextKeys, ...contextFromCode]) });
|
|
204
|
+
}
|
|
205
|
+
return { apps, stacks };
|
|
206
|
+
}
|
|
207
|
+
/* ---------------- SAM / CloudFormation / Serverless / Terraform ---------------- */
|
|
208
|
+
async function analyzeTemplates(root, files, stacks) {
|
|
209
|
+
const yamlish = files.filter((f) => /\.(ya?ml|json)$/.test(f) && !f.startsWith('.github/') && f.split('/').length <= 5 && !/(^|\/)(package(-lock)?|tsconfig|cdk|composer|manifest)\.json$/.test(f));
|
|
210
|
+
for (const f of yamlish) {
|
|
211
|
+
const base = basename(f);
|
|
212
|
+
const c = await readText(join(root, f));
|
|
213
|
+
if (!c)
|
|
214
|
+
continue;
|
|
215
|
+
if (/^serverless\.ya?ml$/.test(base)) {
|
|
216
|
+
const service = /^service:\s*(?:name:\s*)?['"]?([\w-]+)/m.exec(c)?.[1] ?? basename(dirname(f));
|
|
217
|
+
const stage = /^\s+stage:\s*['"]?([\w-]+)/m.exec(c)?.[1] ?? 'dev';
|
|
218
|
+
const functions = (c.match(/^\s{2}[\w-]+:\s*\n\s{4}handler:/gm) ?? []).length;
|
|
219
|
+
stacks.push({
|
|
220
|
+
name: `${service}-${stage}`, constructId: null, className: null, tool: 'serverless', appDir: dirname(f), entryFile: f, entryLines: null, variable: null, standalone: false,
|
|
221
|
+
sourceFiles: [f], env: `stage ${stage}`, constructs: [], assets: [{ kind: 'serverless-package', file: f, line: 1, detail: `${functions} função(ões) empacotadas pelo Serverless Framework` }],
|
|
222
|
+
resourceTypes: uniq([...c.matchAll(/Type:\s*['"]?(AWS::[\w:]+)/g)].map((m) => m[1] ?? '')), handover: 'needs-code-deploy-split',
|
|
223
|
+
notes: ['Serverless Framework empacota código e infra no mesmo deploy; o stage padrão pode variar por `--stage`.'],
|
|
224
|
+
});
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
const isSam = /Transform:\s*['"]?AWS::Serverless/.test(c) || /"Transform"\s*:\s*"AWS::Serverless/.test(c);
|
|
228
|
+
const isCfn = !isSam && /AWSTemplateFormatVersion/.test(c) && /Resources/.test(c);
|
|
229
|
+
if (!isSam && !isCfn)
|
|
230
|
+
continue;
|
|
231
|
+
const dir = dirname(f);
|
|
232
|
+
let stackName = basename(dir === '.' ? root : dir);
|
|
233
|
+
let nameKnown = false;
|
|
234
|
+
const samconfig = await readText(join(root, dir, 'samconfig.toml'));
|
|
235
|
+
const configured = samconfig ? /stack_name\s*=\s*"([^"]+)"/.exec(samconfig)?.[1] : undefined;
|
|
236
|
+
if (configured) {
|
|
237
|
+
stackName = configured;
|
|
238
|
+
nameKnown = true;
|
|
239
|
+
}
|
|
240
|
+
const assets = [];
|
|
241
|
+
for (const m of c.matchAll(/(CodeUri|ContentUri|ImageUri|DockerContext):\s*['"]?([^\s'"]+)/g)) {
|
|
242
|
+
if (/^s3:\/\//.test(m[2] ?? '') || /^!/.test(m[2] ?? ''))
|
|
243
|
+
continue;
|
|
244
|
+
assets.push({ kind: `sam-${(m[1] ?? '').toLowerCase()}`, file: f, line: lineOf(c, m.index ?? 0), detail: m[2] ?? '' });
|
|
245
|
+
}
|
|
246
|
+
stacks.push({
|
|
247
|
+
name: stackName, constructId: null, className: null, tool: isSam ? 'sam' : 'cloudformation', appDir: dir, entryFile: f, entryLines: null, variable: null, standalone: false,
|
|
248
|
+
sourceFiles: [f], env: null, constructs: [], assets, resourceTypes: uniq([...c.matchAll(/Type:\s*['"]?(AWS::[\w:]+)/g), ...c.matchAll(/"Type"\s*:\s*"(AWS::[\w:]+)"/g)].map((m) => m[1] ?? '')).sort(),
|
|
249
|
+
handover: assets.length ? 'needs-code-deploy-split' : 'ok',
|
|
250
|
+
notes: nameKnown ? [] : ['nome do stack não declarado no repositório (samconfig.toml ausente): confirme o nome real.'],
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
const tfByDir = new Map();
|
|
254
|
+
for (const f of files.filter((x) => x.endsWith('.tf'))) {
|
|
255
|
+
const c = await readText(join(root, f));
|
|
256
|
+
if (!c)
|
|
257
|
+
continue;
|
|
258
|
+
const d = dirname(f);
|
|
259
|
+
const list = tfByDir.get(d) ?? [];
|
|
260
|
+
list.push(...[...c.matchAll(/resource\s+"(aws_\w+)"/g)].map((m) => m[1] ?? ''));
|
|
261
|
+
tfByDir.set(d, list);
|
|
262
|
+
}
|
|
263
|
+
for (const [d, types] of tfByDir) {
|
|
264
|
+
stacks.push({
|
|
265
|
+
name: `terraform:${d}`, constructId: null, className: null, tool: 'terraform', appDir: d, entryFile: null, entryLines: null, variable: null, standalone: false,
|
|
266
|
+
sourceFiles: files.filter((x) => x.endsWith('.tf') && dirname(x) === d), env: null, constructs: [], assets: [], resourceTypes: uniq(types).sort(),
|
|
267
|
+
handover: 'unsupported-terraform', notes: ['Terraform fica somente leitura no FG Tracker (ou adote os recursos pelo IaC generator do CloudFormation).'],
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/* ---------------- CI ---------------- */
|
|
272
|
+
function parseCdkStacks(rest) {
|
|
273
|
+
const tokens = rest.split(/&&|\|\||;|\||#/)[0]?.trim().split(/\s+/).filter(Boolean) ?? [];
|
|
274
|
+
const out = [];
|
|
275
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
276
|
+
const t = (tokens[i] ?? '').replace(/^['"]|['"]$/g, '');
|
|
277
|
+
if (t === '--all')
|
|
278
|
+
return ['*'];
|
|
279
|
+
if (t.startsWith('-')) {
|
|
280
|
+
if (CDK_VALUE_FLAGS.has(t))
|
|
281
|
+
i++;
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
if (t === '\\')
|
|
285
|
+
continue;
|
|
286
|
+
out.push(t);
|
|
287
|
+
}
|
|
288
|
+
return out;
|
|
289
|
+
}
|
|
290
|
+
async function analyzeCi(root, files) {
|
|
291
|
+
const candidates = files.filter((f) => /^\.github\/workflows\/[^/]+\.ya?ml$/.test(f) || /(^|\/)(\.gitlab-ci\.ya?ml|buildspec[\w-]*\.ya?ml|bitbucket-pipelines\.ya?ml|Makefile|package\.json|Justfile|Taskfile\.ya?ml)$/.test(f) || (/(^|\/)scripts\/.+\.(sh|mjs|js|ts)$/.test(f) && f.split('/').length <= 4)).filter((f) => !f.includes('node_modules'));
|
|
292
|
+
const out = [];
|
|
293
|
+
for (const f of candidates) {
|
|
294
|
+
const c = await readText(join(root, f));
|
|
295
|
+
if (!c || !/\b(cdk|sam|serverless|sls|terraform)\b/.test(c))
|
|
296
|
+
continue;
|
|
297
|
+
const lines = c.split('\n');
|
|
298
|
+
lines.forEach((ln, i) => {
|
|
299
|
+
const m = /\b(cdk|sam|serverless|sls|terraform)(?:@[\w.^~-]+)?\s+(deploy|apply)\b(.*)$/.exec(ln);
|
|
300
|
+
if (!m)
|
|
301
|
+
return;
|
|
302
|
+
const tool = m[1] === 'sls' ? 'serverless' : m[1];
|
|
303
|
+
out.push({ file: f, line: i + 1, tool, text: ln.trim().slice(0, 200), stacks: tool === 'cdk' ? parseCdkStacks(m[3] ?? '') : [] });
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
return out;
|
|
307
|
+
}
|
|
308
|
+
/* ---------------- entrada ---------------- */
|
|
309
|
+
export async function analyzeIac(root) {
|
|
310
|
+
const walked = await walkFiles(root);
|
|
311
|
+
const truncated = walked.truncated;
|
|
312
|
+
// Artefatos do próprio FG Tracker (guard, arquivo do handover, espelho) não são IaC do cliente.
|
|
313
|
+
const files = walked.files.filter((f) => !/^infra\/(_handover|fg-tracker-mirror)\//.test(f) && f !== 'scripts/fg-tracker-guard.mjs');
|
|
314
|
+
const fileSet = new Set(files);
|
|
315
|
+
const warnings = [];
|
|
316
|
+
if (truncated)
|
|
317
|
+
warnings.push(`Repositório grande: varredura limitada a ${files.length} arquivos.`);
|
|
318
|
+
const cdk = await analyzeCdk(root, files, fileSet, warnings);
|
|
319
|
+
const stacks = [...cdk.stacks];
|
|
320
|
+
await analyzeTemplates(root, files, stacks);
|
|
321
|
+
const deployCommands = await analyzeCi(root, files);
|
|
322
|
+
// Stacks CDK sem nenhum deploy explícito no CI: só aviso.
|
|
323
|
+
for (const s of stacks) {
|
|
324
|
+
if (s.assets.length && s.tool === 'cdk') {
|
|
325
|
+
s.notes.push(`código implantado pelo CDK (${s.assets.length} asset(s)): a transferência exige separar o deploy de código (\`fg-tracker-release deploy --release <sha>\`).`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
const tools = uniq(stacks.map((s) => s.tool));
|
|
329
|
+
if (!stacks.length)
|
|
330
|
+
warnings.push('Nenhum IaC reconhecido (cdk.json, template SAM/CloudFormation, serverless.yml ou *.tf).');
|
|
331
|
+
return { root, tools, cdkApps: cdk.apps, stacks, deployCommands, warnings, filesScanned: files.length };
|
|
332
|
+
}
|
|
333
|
+
const FEASIBILITY_LABEL = {
|
|
334
|
+
ok: 'ok',
|
|
335
|
+
'needs-code-deploy-split': 'precisa separar deploy de código',
|
|
336
|
+
'unsupported-terraform': 'Terraform (somente leitura)',
|
|
337
|
+
};
|
|
338
|
+
export function formatIac(a) {
|
|
339
|
+
const lines = [`# IaC em ${a.root}`, '', `Ferramentas: ${a.tools.join(', ') || 'nenhuma'} · ${a.stacks.length} stack(s) · ${a.deployCommands.length} comando(s) de deploy · ${a.filesScanned} arquivos lidos.`];
|
|
340
|
+
for (const app of a.cdkApps) {
|
|
341
|
+
lines.push('', `## App CDK \`${app.dir}\``, `- app: \`${app.appCommand ?? '—'}\``, `- entrada: ${app.entryFiles.map((f) => `\`${f}\``).join(', ') || '—'}`);
|
|
342
|
+
if (app.contextKeys.length)
|
|
343
|
+
lines.push(`- contextos: ${app.contextKeys.slice(0, 15).join(', ')}`);
|
|
344
|
+
}
|
|
345
|
+
lines.push('', '## Stacks');
|
|
346
|
+
for (const s of a.stacks) {
|
|
347
|
+
lines.push(`- **${s.name}** (${s.tool}${s.className ? `, ${s.className}` : ''}) — handover: ${FEASIBILITY_LABEL[s.handover]}`);
|
|
348
|
+
if (s.entryFile)
|
|
349
|
+
lines.push(` - definido em \`${s.entryFile}${s.entryLines ? `:${s.entryLines[0]}-${s.entryLines[1]}` : ''}\`${s.sourceFiles.length > 1 ? `; código: ${s.sourceFiles.slice(1, 6).map((f) => `\`${f}\``).join(', ')}` : ''}`);
|
|
350
|
+
if (s.env)
|
|
351
|
+
lines.push(` - env: \`${s.env.slice(0, 120)}\``);
|
|
352
|
+
if (s.constructs.length)
|
|
353
|
+
lines.push(` - constructs: ${s.constructs.slice(0, 20).join(', ')}`);
|
|
354
|
+
if (s.resourceTypes.length)
|
|
355
|
+
lines.push(` - tipos: ${s.resourceTypes.slice(0, 15).join(', ')}${s.resourceTypes.length > 15 ? '…' : ''}`);
|
|
356
|
+
for (const as of s.assets.slice(0, 8))
|
|
357
|
+
lines.push(` - asset ${as.kind} em \`${as.file}:${as.line}\`${as.detail ? ` (${as.detail})` : ''}`);
|
|
358
|
+
if (s.assets.length > 8)
|
|
359
|
+
lines.push(` - … +${s.assets.length - 8} assets`);
|
|
360
|
+
for (const n of s.notes)
|
|
361
|
+
lines.push(` - nota: ${n}`);
|
|
362
|
+
}
|
|
363
|
+
if (a.deployCommands.length) {
|
|
364
|
+
lines.push('', '## Deploys encontrados');
|
|
365
|
+
for (const d of a.deployCommands.slice(0, 30))
|
|
366
|
+
lines.push(`- \`${d.file}:${d.line}\` (${d.tool}${d.stacks.length ? ` → ${d.stacks.join(', ')}` : ''}): \`${d.text}\``);
|
|
367
|
+
}
|
|
368
|
+
const coupled = a.stacks.filter((s) => s.handover === 'needs-code-deploy-split');
|
|
369
|
+
if (coupled.length || a.warnings.length) {
|
|
370
|
+
lines.push('', '## Avisos');
|
|
371
|
+
if (coupled.length)
|
|
372
|
+
lines.push(`- Código implantado junto com a infra em: ${coupled.map((s) => s.name).join(', ')}. No handover, o CI passa a construir artefatos e chamar \`npx fg-tracker-release deploy --release <sha>\`.`);
|
|
373
|
+
for (const w of a.warnings)
|
|
374
|
+
lines.push(`- ${w}`);
|
|
375
|
+
}
|
|
376
|
+
return lines.join('\n');
|
|
377
|
+
}
|
|
378
|
+
//# sourceMappingURL=iac.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iac.js","sourceRoot":"","sources":["../../src/infra/iac.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plano de instrumentação de infra (tool `infra_instrument`, CONTRATO.md §27.8): SDK nos clientes
|
|
3
|
+
* AWS e pools pg, reporter de ECS, camada da extensão nas Lambdas do CDK e `wrapLambda` nos handlers.
|
|
4
|
+
* Só lê o repositório e devolve patches sugeridos — nada é aplicado.
|
|
5
|
+
*/
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import { isSourceFile, isTestFile, lineOf, readText, walkFiles } from './files.js';
|
|
8
|
+
const AWS_CLIENTS = ['SQSClient', 'SNSClient', 'EventBridgeClient', 'DynamoDBClient', 'KinesisClient', 'SFNClient'];
|
|
9
|
+
const ECS_CONSTRUCTS = /\b(FargateService|Ec2Service|FargateTaskDefinition|Ec2TaskDefinition|ApplicationLoadBalancedFargateService|NetworkLoadBalancedFargateService|QueueProcessingFargateService|ScheduledFargateTask)\b/;
|
|
10
|
+
const MAX_ITEMS = 30;
|
|
11
|
+
function varBefore(content, index) {
|
|
12
|
+
const lineStart = content.lastIndexOf('\n', index) + 1;
|
|
13
|
+
return /(?:const|let|var|this\.|readonly\s+|private\s+|public\s+)\s*([\w$]+)\s*(?::\s*[\w$.<>]+\s*)?=\s*$/.exec(content.slice(lineStart, index))?.[1] ?? null;
|
|
14
|
+
}
|
|
15
|
+
function lineText(content, index) {
|
|
16
|
+
const s = content.lastIndexOf('\n', index) + 1;
|
|
17
|
+
const e = content.indexOf('\n', index);
|
|
18
|
+
return content.slice(s, e < 0 ? content.length : e).trim().slice(0, 160);
|
|
19
|
+
}
|
|
20
|
+
function trackerImport(trackerFile, file) {
|
|
21
|
+
if (!trackerFile)
|
|
22
|
+
return "import { tracker } from './tracker'; // crie o tracker uma vez por processo (track_instrumentation_guide)";
|
|
23
|
+
const from = file.split('/').slice(0, -1);
|
|
24
|
+
const to = trackerFile.replace(/\.[cm]?[jt]sx?$/, '').split('/');
|
|
25
|
+
let i = 0;
|
|
26
|
+
while (i < from.length && i < to.length - 1 && from[i] === to[i])
|
|
27
|
+
i++;
|
|
28
|
+
const rel = [...from.slice(i).map(() => '..'), ...to.slice(i)].join('/');
|
|
29
|
+
return `import { tracker } from '${rel.startsWith('.') ? rel : './' + rel}';`;
|
|
30
|
+
}
|
|
31
|
+
export async function buildInstrumentPlan(root, options) {
|
|
32
|
+
const { files, truncated } = await walkFiles(root);
|
|
33
|
+
const sources = files.filter((f) => isSourceFile(f) && !isTestFile(f) && !/^infra\/(_handover|fg-tracker-mirror)\//.test(f) && f !== 'scripts/fg-tracker-guard.mjs');
|
|
34
|
+
const awsHits = [];
|
|
35
|
+
const poolHits = [];
|
|
36
|
+
const lambdaConstructs = [];
|
|
37
|
+
const handlers = [];
|
|
38
|
+
let ecsConstruct = null;
|
|
39
|
+
let trackerFile = null;
|
|
40
|
+
const cdkFiles = new Set();
|
|
41
|
+
for (const f of sources) {
|
|
42
|
+
const c = await readText(join(root, f));
|
|
43
|
+
if (!c)
|
|
44
|
+
continue;
|
|
45
|
+
const isCdk = /aws-cdk-lib|@aws-cdk\//.test(c);
|
|
46
|
+
if (isCdk)
|
|
47
|
+
cdkFiles.add(f);
|
|
48
|
+
if (!trackerFile && /createTracker\s*\(/.test(c))
|
|
49
|
+
trackerFile = f;
|
|
50
|
+
if (!isCdk) {
|
|
51
|
+
for (const m of c.matchAll(new RegExp(`new\\s+(${AWS_CLIENTS.join('|')})\\s*\\(`, 'g'))) {
|
|
52
|
+
const i = m.index ?? 0;
|
|
53
|
+
awsHits.push({ file: f, line: lineOf(c, i), code: lineText(c, i), variable: varBefore(c, i), extra: m[1] });
|
|
54
|
+
}
|
|
55
|
+
if (/from\s+['"]pg['"]|require\(\s*['"]pg['"]\s*\)/.test(c)) {
|
|
56
|
+
for (const m of c.matchAll(/new\s+(?:pg\.)?Pool\s*\(/g)) {
|
|
57
|
+
const i = m.index ?? 0;
|
|
58
|
+
poolHits.push({ file: f, line: lineOf(c, i), code: lineText(c, i), variable: varBefore(c, i) });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
for (const m of c.matchAll(/export\s+(?:const\s+handler\s*(?::\s*[\w$.<>, ]+)?=|async\s+function\s+handler\b|function\s+handler\b)|(?:module\.)?exports\.handler\s*=/g)) {
|
|
62
|
+
const i = m.index ?? 0;
|
|
63
|
+
handlers.push({ file: f, line: lineOf(c, i), code: lineText(c, i), variable: null });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
for (const m of c.matchAll(/new\s+(?:[\w$]+\.)?(Function|NodejsFunction|PythonFunction|GoFunction|DockerImageFunction)\s*\(\s*this\s*,\s*['"`]([^'"`]+)['"`]/g)) {
|
|
68
|
+
const i = m.index ?? 0;
|
|
69
|
+
lambdaConstructs.push({ file: f, line: lineOf(c, i), code: lineText(c, i), variable: varBefore(c, i), extra: `${m[1]}:${m[2]}` });
|
|
70
|
+
}
|
|
71
|
+
if (!ecsConstruct) {
|
|
72
|
+
const m = ECS_CONSTRUCTS.exec(c);
|
|
73
|
+
if (m)
|
|
74
|
+
ecsConstruct = { file: f, line: lineOf(c, m.index), code: lineText(c, m.index), variable: null, extra: m[1] };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const dockerfiles = files.filter((f) => /(^|\/)Dockerfile(\.[\w-]+)?$/.test(f));
|
|
79
|
+
const pkgManager = files.includes('pnpm-lock.yaml') ? 'pnpm add' : files.includes('yarn.lock') ? 'yarn add' : files.includes('bun.lockb') || files.includes('bun.lock') ? 'bun add' : 'npm install';
|
|
80
|
+
const pkg = await readText(join(root, 'package.json'));
|
|
81
|
+
const hasSdk = pkg ? /"fg-tracker-sdk"/.test(pkg) : false;
|
|
82
|
+
const out = [
|
|
83
|
+
`# Plano de instrumentação de infra — ${options.serviceName}`,
|
|
84
|
+
'',
|
|
85
|
+
'Patches sugeridos (NÃO aplicados). Aplique com edits mínimos, rode o app e confirme com `infra_get_diagram` (nós `instrumented`) e `track_verify_ingest`.',
|
|
86
|
+
truncated ? `\n> Repositório grande: varredura limitada a ${files.length} arquivos.` : '',
|
|
87
|
+
'',
|
|
88
|
+
'## 1. SDK',
|
|
89
|
+
hasSdk ? '- `fg-tracker-sdk` já está no package.json (garanta versão com `instrumentAws`/`startInfraReporter`).' : `- \`${pkgManager} fg-tracker-sdk\``,
|
|
90
|
+
trackerFile ? `- Tracker existente em \`${trackerFile}\` — reutilize-o (um por processo).` : '- Nenhum `createTracker(` encontrado: crie `src/tracker.ts` seguindo `track_instrumentation_guide` (use `FG_TRACKER_KEY` e `FG_TRACKER_URL`, nunca a chave no código).',
|
|
91
|
+
'- Env: `FG_TRACKER_KEY=<apiKey do projeto>` (segredo), `FG_TRACKER_URL=' + options.endpoint + '`.',
|
|
92
|
+
];
|
|
93
|
+
out.push('', `## 2. Clientes AWS (${awsHits.length})`);
|
|
94
|
+
if (!awsHits.length)
|
|
95
|
+
out.push('- Nenhum `new SQSClient|SNSClient|EventBridgeClient|DynamoDBClient|KinesisClient|SFNClient(` encontrado.');
|
|
96
|
+
for (const h of awsHits.slice(0, MAX_ITEMS)) {
|
|
97
|
+
out.push(`- \`${h.file}:${h.line}\` — \`${h.code}\``, ' ```ts', ` ${trackerImport(trackerFile, h.file)}`, ` ${h.variable ? `const ${h.variable} = ` : ''}tracker.instrumentAws(new ${h.extra}(/* mesma config */));`, ' ```');
|
|
98
|
+
}
|
|
99
|
+
if (awsHits.length > MAX_ITEMS)
|
|
100
|
+
out.push(`- … +${awsHits.length - MAX_ITEMS} ocorrências (mesmo padrão).`);
|
|
101
|
+
if (awsHits.some((h) => h.extra === 'DynamoDBClient'))
|
|
102
|
+
out.push('- `DynamoDBDocumentClient.from(client)`: instrumente o `DynamoDBClient` base antes do `from`.');
|
|
103
|
+
out.push('', `## 3. Pools pg (${poolHits.length})`);
|
|
104
|
+
if (!poolHits.length)
|
|
105
|
+
out.push('- Nenhum `new Pool(` de `pg` encontrado (outros drivers: `track_detect_databases`).');
|
|
106
|
+
for (const h of poolHits.slice(0, MAX_ITEMS)) {
|
|
107
|
+
const v = h.variable ?? 'pool';
|
|
108
|
+
out.push(`- \`${h.file}:${h.line}\` — \`${h.code}\``, ' ```ts', ` tracker.instrumentPgPool(${v}, { name: '${options.serviceName}-db' }); // agregados db_pool (total/idle/waiting)`, ' ```');
|
|
109
|
+
}
|
|
110
|
+
out.push('', '## 4. Containers (ECS)');
|
|
111
|
+
if (ecsConstruct && dockerfiles.length) {
|
|
112
|
+
out.push(`- ECS detectado (\`${ecsConstruct.extra}\` em \`${ecsConstruct.file}:${ecsConstruct.line}\`) e Dockerfile(s): ${dockerfiles.slice(0, 5).map((d) => `\`${d}\``).join(', ')}.`, `- No ponto de entrada do app do container${trackerFile ? ` (após criar o tracker em \`${trackerFile}\`)` : ''}:`, ' ```ts', ' tracker.startInfraReporter({ ecs: true }); // lê ECS_CONTAINER_METADATA_URI_V4: CPU, memória e rede por task', ' ```', '- Na task definition do CDK, passe `FG_TRACKER_URL` e `FG_TRACKER_KEY` (via `ecs.Secret.fromSecretsManager`).');
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
out.push(`- ${ecsConstruct ? 'Construct ECS encontrado, mas nenhum Dockerfile' : dockerfiles.length ? 'Dockerfile encontrado, mas nenhum construct ECS' : 'Nenhum app ECS detectado'} — reporter de ECS não se aplica${dockerfiles.length && !ecsConstruct ? ' (se roda no ECS fora do CDK, use `tracker.startInfraReporter({ ecs: true })`)' : ''}.`);
|
|
116
|
+
}
|
|
117
|
+
out.push('', `## 5. Lambdas no CDK (${lambdaConstructs.length})`);
|
|
118
|
+
if (!lambdaConstructs.length)
|
|
119
|
+
out.push('- Nenhuma função Lambda declarada no CDK.');
|
|
120
|
+
for (const h of lambdaConstructs.slice(0, MAX_ITEMS)) {
|
|
121
|
+
const [kind, id] = (h.extra ?? ':').split(':');
|
|
122
|
+
const v = h.variable ?? `fn${(id ?? '').replace(/[^\w]/g, '')}`;
|
|
123
|
+
if (kind === 'DockerImageFunction') {
|
|
124
|
+
out.push(`- \`${h.file}:${h.line}\` ${id} (DockerImageFunction): camadas não se aplicam a imagens — copie a extensão para \`/opt/extensions\` no Dockerfile (\`COPY --from=<imagem-da-extensão> /opt/extensions /opt/extensions\`) e defina as envs abaixo.`);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
out.push(`- \`${h.file}:${h.line}\` — ${kind} \`${id}\``, ' ```ts', ` const fgTrackerLayer = lambda.LayerVersion.fromLayerVersionArn(this, 'FgTrackerExtension', '${options.layerArn}'); // uma vez por stack`, ` ${v}.addLayers(fgTrackerLayer);`, ` ${v}.addEnvironment('FG_TRACKER_URL', '${options.endpoint}');`, ` ${v}.addEnvironment('FG_TRACKER_KEY', fgTrackerKey); // ex.: secretsmanager.Secret.fromSecretNameV2(...).secretValue.unsafeUnwrap() ou SSM`, ' ```');
|
|
128
|
+
}
|
|
129
|
+
if (lambdaConstructs.length > MAX_ITEMS)
|
|
130
|
+
out.push(`- … +${lambdaConstructs.length - MAX_ITEMS} funções (mesmo padrão).`);
|
|
131
|
+
out.push('', `## 6. Handlers Lambda (${handlers.length})`);
|
|
132
|
+
if (!handlers.length)
|
|
133
|
+
out.push('- Nenhum `export const handler` / `exports.handler` encontrado.');
|
|
134
|
+
for (const h of handlers.slice(0, MAX_ITEMS)) {
|
|
135
|
+
out.push(`- \`${h.file}:${h.line}\` — \`${h.code}\``, ' ```ts', ` ${trackerImport(trackerFile, h.file)}`, ' export const handler = tracker.wrapLambda(async (event, context) => { /* corpo atual */ });', ' ```');
|
|
136
|
+
}
|
|
137
|
+
out.push('', '## Regras', '- Não altere a infraestrutura na AWS: as mudanças do CDK entram no PR e só são implantadas pelo fluxo normal (ou pelo FG Tracker, após o handover).', '- Nunca commite `FG_TRACKER_KEY`; use Secrets Manager/SSM no CDK e `.env` local fora do git.');
|
|
138
|
+
return out.filter((l, i, arr) => !(l === '' && arr[i - 1] === '')).join('\n');
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=instrument.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrument.js","sourceRoot":"","sources":["../../src/infra/instrument.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { type TrackClient } from '../client.js';
|
|
3
|
+
export declare function registerInfraTools(server: McpServer, client: TrackClient, version: string): void;
|
|
4
|
+
export declare function connectInfrastructurePrompt(args: {
|
|
5
|
+
projectId?: string;
|
|
6
|
+
level?: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
path?: string;
|
|
9
|
+
environment?: string;
|
|
10
|
+
}, endpoint: string): string;
|