fg-tracker-mcp 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +2 -0
- package/dist/docs.d.ts +1 -1
- package/dist/docs.js +11 -1
- package/dist/docs.js.map +1 -1
- package/dist/infra/aws.d.ts +51 -0
- package/dist/infra/aws.js +393 -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 +8 -0
- package/dist/infra/tools.js +620 -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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog — fg-tracker-mcp
|
|
2
2
|
|
|
3
|
+
## 0.5.0 — 2026-09-15
|
|
4
|
+
|
|
5
|
+
- **Infraestrutura AWS** (CONTRATO.md §27.9): tools `infra_connect_account`, `infra_verify_connection`, `infra_discover` (inventário com credenciais locais, somente leitura → snapshot), `infra_analyze_iac` (CDK/SAM/Serverless/Terraform/CI), `infra_assign_resources`, `infra_instrument`, `infra_validate`, `infra_get_diagram`, `infra_plan_handover`, `infra_open_handover_pr` (lock, guard do CI, patch e comandos git/gh — nunca executa push) e `infra_complete_handover`.
|
|
6
|
+
- Prompt `connect-infrastructure` com o roteiro e as regras de segurança (nenhuma mudança na AWS pelo agente; aprovação humana no FG Tracker).
|
|
7
|
+
- Quickstart ganha a seção "Infraestrutura (AWS)". Dependências `@aws-sdk/client-*` e `@aws-sdk/credential-providers`.
|
|
8
|
+
|
|
3
9
|
## 0.4.0 — 2026-09-15
|
|
4
10
|
|
|
5
11
|
- **Renomeado de `stread-track-mcp` — nomes antigos continuam funcionando e serão removidos na 1.0.** Veja "Migração de stread-track-mcp" no README.
|
package/README.md
CHANGED
|
@@ -47,6 +47,8 @@ Os nomes antigos `STREAD_TRACK_*` continuam lidos quando o nome novo está ausen
|
|
|
47
47
|
|
|
48
48
|
Tools `track_*` (nomes inalterados), prompt `instrument-project` e resource `fg-tracker://docs/quickstart`.
|
|
49
49
|
|
|
50
|
+
Infraestrutura AWS (0.5.0): tools `infra_*` e prompt `connect-infrastructure` — conectar conta, descobrir recursos com credenciais locais (somente leitura), analisar o IaC, instrumentar, validar e gerar o PR de transferência de controle. Nenhuma tool altera recursos na AWS. Detalhes em `docs/mcp.md` → Infraestrutura.
|
|
51
|
+
|
|
50
52
|
## Migração de stread-track-mcp
|
|
51
53
|
|
|
52
54
|
O pacote foi renomeado de `stread-track-mcp` (última versão no npm: 0.2.0) para `fg-tracker-mcp` (0.4.0). Nomes antigos continuam funcionando e serão removidos na 1.0.
|
package/dist/docs.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Conteúdo estático: resource `fg-tracker://docs/quickstart` e o prompt
|
|
3
|
-
* `instrument-project
|
|
3
|
+
* `instrument-project` (o prompt `connect-infrastructure` fica em `infra/tools.ts`).
|
|
4
4
|
*/
|
|
5
5
|
export declare const QUICKSTART_URI = "fg-tracker://docs/quickstart";
|
|
6
6
|
/** @deprecated URI do `stread-track-mcp` ≤ 0.3; ainda registrada como alias, removida na 1.0. */
|
package/dist/docs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Conteúdo estático: resource `fg-tracker://docs/quickstart` e o prompt
|
|
3
|
-
* `instrument-project
|
|
3
|
+
* `instrument-project` (o prompt `connect-infrastructure` fica em `infra/tools.ts`).
|
|
4
4
|
*/
|
|
5
5
|
export const QUICKSTART_URI = 'fg-tracker://docs/quickstart';
|
|
6
6
|
/** @deprecated URI do `stread-track-mcp` ≤ 0.3; ainda registrada como alias, removida na 1.0. */
|
|
@@ -79,6 +79,16 @@ Kinds de span: \`http.server\` (raiz por request), \`db.query\` (nome = SQL norm
|
|
|
79
79
|
| SLOW_ENDPOINT | raiz \`http.server\` com \`durationMs > slowThresholdMs\` (default 1000) |
|
|
80
80
|
| ERROR | raiz com status ≥ 500 ou \`error != null\` |
|
|
81
81
|
|
|
82
|
+
## 7. Infraestrutura (AWS)
|
|
83
|
+
Prompt \`connect-infrastructure\` guia o fluxo completo. Nenhuma tool altera recursos na AWS; mudanças de infra só pelo FG Tracker, com aprovação humana.
|
|
84
|
+
1. \`infra_connect_account { projectId, level: 'read'|'operate', regions }\` → link quick-create ou \`./fg-tracker-connection.json\` + \`aws cloudformation deploy\` (o usuário roda) → \`infra_verify_connection { projectId, connectionId }\`.
|
|
85
|
+
2. \`infra_discover { projectId, regions?, profile? }\` — inventário com credenciais locais (Resource Explorer/Tagging API + CloudFormation) enviado como snapshot.
|
|
86
|
+
3. \`infra_analyze_iac { path? }\` — apps CDK, stacks, assets, SAM/Serverless/Terraform e deploys do CI, com viabilidade de handover.
|
|
87
|
+
4. \`infra_assign_resources { projectId, include, exclude? }\` — confirma o que é do projeto.
|
|
88
|
+
5. \`infra_instrument { projectId, path? }\` — plano: \`instrumentAws\`, \`instrumentPgPool\`, \`startInfraReporter({ ecs: true })\`, camada da extensão nas Lambdas, \`wrapLambda\`.
|
|
89
|
+
6. \`infra_validate { projectId }\` (notas dos 4 pilares) e \`infra_get_diagram { projectId }\` (grafo em texto).
|
|
90
|
+
7. \`infra_plan_handover { projectId, stackNames }\` → \`infra_open_handover_pr\` (gera \`infra/fg-tracker.lock.json\`, guard do CI, patch e comandos git/gh) → após o merge \`infra_complete_handover { projectId, stackNames, prUrl }\`.
|
|
91
|
+
|
|
82
92
|
Ranges aceitos: \`15m|1h|6h|24h|7d|30d\`.
|
|
83
93
|
`;
|
|
84
94
|
}
|
package/dist/docs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,8BAA8B,CAAC;AAC7D,iGAAiG;AACjG,MAAM,CAAC,MAAM,qBAAqB,GAAG,gCAAgC,CAAC;AAEtE,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO;;gMAEuL,QAAQ,oBAAoB,QAAQ;;;;;;;;;;oDAUhL,QAAQ;;;;;;;;;;;;;;;;;;;;;wDAqBJ,QAAQ;;;;;;;;;eASjD,QAAQ;;;;;;;;eAQR,QAAQ
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,8BAA8B,CAAC;AAC7D,iGAAiG;AACjG,MAAM,CAAC,MAAM,qBAAqB,GAAG,gCAAgC,CAAC;AAEtE,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO;;gMAEuL,QAAQ,oBAAoB,QAAQ;;;;;;;;;;oDAUhL,QAAQ;;;;;;;;;;;;;;;;;;;;;wDAqBJ,QAAQ;;;;;;;;;eASjD,QAAQ;;;;;;;;eAQR,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCtB,CAAC;AACF,CAAC;AAOD,MAAM,UAAU,uBAAuB,CAAC,IAA0B,EAAE,QAAgB;IAClF,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,mCAAmC,IAAI,CAAC,SAAS,8CAA8C,CAAC,CAAC,CAAC,2CAA2C,CAAC;IAC1K,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW;QAC3B,CAAC,CAAC,qCAAqC,IAAI,CAAC,WAAW,mBAAmB;QAC1E,CAAC,CAAC,0GAA0G,CAAC;IAE/G,OAAO,qEAAqE,QAAQ;;EAEpF,EAAE,IAAI,IAAI;;;;;;;;;;;;;;;;;;;;;;;;wFAwB4E,QAAQ;;;;;;yMAMyG,QAAQ,YAAY,QAAQ;;0GAE3H,CAAC;AAC3G,CAAC;AAED,8EAA8E"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface SnapshotResource {
|
|
2
|
+
arn: string;
|
|
3
|
+
resourceType: string | null;
|
|
4
|
+
region: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
tags?: Record<string, string>;
|
|
7
|
+
stackName?: string;
|
|
8
|
+
stackLogicalId?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface DiscoveryResult {
|
|
11
|
+
accountId: string;
|
|
12
|
+
callerArn: string;
|
|
13
|
+
regions: string[];
|
|
14
|
+
resources: SnapshotResource[];
|
|
15
|
+
sources: Record<string, 'resource-explorer' | 'tagging-api' | 'resource-explorer+tagging-api' | 'error'>;
|
|
16
|
+
stacks: Array<{
|
|
17
|
+
name: string;
|
|
18
|
+
region: string;
|
|
19
|
+
status: string;
|
|
20
|
+
resources: number;
|
|
21
|
+
mapped: number;
|
|
22
|
+
stackId: string;
|
|
23
|
+
}>;
|
|
24
|
+
warnings: string[];
|
|
25
|
+
}
|
|
26
|
+
/** Mensagem amigável para erros do AWS SDK (credenciais ausentes/expiradas, acesso negado). */
|
|
27
|
+
export declare function describeAwsError(err: unknown): string;
|
|
28
|
+
export interface ParsedArn {
|
|
29
|
+
partition: string;
|
|
30
|
+
service: string;
|
|
31
|
+
region: string;
|
|
32
|
+
account: string;
|
|
33
|
+
resource: string;
|
|
34
|
+
resourceType: string;
|
|
35
|
+
resourceId: string;
|
|
36
|
+
}
|
|
37
|
+
export declare function parseArn(arn: string): ParsedArn | null;
|
|
38
|
+
/** ARN → tipo CloudFormation (melhor esforço; null quando desconhecido). */
|
|
39
|
+
export declare function arnToResourceType(arn: string): string | null;
|
|
40
|
+
/** Nome legível a partir do ARN. */
|
|
41
|
+
export declare function nameFromArn(arn: string): string;
|
|
42
|
+
/** Serviço amigável (`lambda`, `ecs.service`…) só para o resumo. */
|
|
43
|
+
export declare function serviceLabel(resourceType: string | null, arn: string): string;
|
|
44
|
+
export interface DiscoverOptions {
|
|
45
|
+
regions: string[];
|
|
46
|
+
profile?: string;
|
|
47
|
+
onProgress?: (message: string) => void;
|
|
48
|
+
}
|
|
49
|
+
export declare function discoverAws(options: DiscoverOptions): Promise<DiscoveryResult>;
|
|
50
|
+
/** Lê os outputs de um stack (DescribeStacks, somente leitura). */
|
|
51
|
+
export declare function readStackOutputs(stackName: string, region: string, profile?: string): Promise<Record<string, string>>;
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Descoberta local de recursos AWS com as credenciais do usuário (CONTRATO.md §27.3, §27.9).
|
|
3
|
+
* Somente chamadas de LEITURA: sts:GetCallerIdentity, resource-explorer-2:GetIndex/Search,
|
|
4
|
+
* tag:GetResources, cloudformation:ListStacks/ListStackResources/DescribeStacks.
|
|
5
|
+
*/
|
|
6
|
+
import { CloudFormationClient, DescribeStacksCommand, ListStackResourcesCommand, ListStacksCommand } from '@aws-sdk/client-cloudformation';
|
|
7
|
+
import { GetIndexCommand, ResourceExplorer2Client, SearchCommand } from '@aws-sdk/client-resource-explorer-2';
|
|
8
|
+
import { GetResourcesCommand, ResourceGroupsTaggingAPIClient } from '@aws-sdk/client-resource-groups-tagging-api';
|
|
9
|
+
import { GetCallerIdentityCommand, STSClient } from '@aws-sdk/client-sts';
|
|
10
|
+
import { fromIni, fromNodeProviderChain } from '@aws-sdk/credential-providers';
|
|
11
|
+
const EXPLORER_CAP = 2000;
|
|
12
|
+
const TAGGING_CAP = 10_000;
|
|
13
|
+
const STACK_RESOURCES_CAP = 5000;
|
|
14
|
+
function awsCredentials(profile) {
|
|
15
|
+
return profile ? fromIni({ profile }) : fromNodeProviderChain();
|
|
16
|
+
}
|
|
17
|
+
/** Mensagem amigável para erros do AWS SDK (credenciais ausentes/expiradas, acesso negado). */
|
|
18
|
+
export function describeAwsError(err) {
|
|
19
|
+
const e = err;
|
|
20
|
+
const name = e?.name ?? e?.Code ?? 'Error';
|
|
21
|
+
const msg = e?.message ?? String(err);
|
|
22
|
+
if (/CredentialsProviderError|Could not load credentials|ExpiredToken|InvalidClientTokenId|UnrecognizedClient|SSO.*(expired|session)/i.test(`${name} ${msg}`)) {
|
|
23
|
+
return `Credenciais AWS locais indisponíveis ou expiradas (${name}: ${msg}). Rode \`aws sso login --profile <perfil>\` ou \`aws configure\`, ou passe \`profile\`.`;
|
|
24
|
+
}
|
|
25
|
+
if (/AccessDenied|UnauthorizedOperation|not authorized/i.test(`${name} ${msg}`)) {
|
|
26
|
+
return `Acesso negado (${name}): ${msg}`;
|
|
27
|
+
}
|
|
28
|
+
return `${name}: ${msg}`;
|
|
29
|
+
}
|
|
30
|
+
export function parseArn(arn) {
|
|
31
|
+
const parts = arn.split(':');
|
|
32
|
+
if (parts.length < 6 || parts[0] !== 'arn')
|
|
33
|
+
return null;
|
|
34
|
+
const [, partition = '', service = '', region = '', account = ''] = parts;
|
|
35
|
+
const resource = parts.slice(5).join(':');
|
|
36
|
+
let resourceType = '';
|
|
37
|
+
let resourceId = resource;
|
|
38
|
+
const slash = resource.indexOf('/');
|
|
39
|
+
const colon = resource.indexOf(':');
|
|
40
|
+
if (service === 'apigateway') {
|
|
41
|
+
const m = /^\/(restapis|apis|domainnames|usageplans|apikeys)\/([^/]+)/.exec(resource);
|
|
42
|
+
if (m) {
|
|
43
|
+
resourceType = m[1] ?? '';
|
|
44
|
+
resourceId = m[2] ?? resource;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else if (slash >= 0 && (colon < 0 || slash < colon)) {
|
|
48
|
+
resourceType = resource.slice(0, slash);
|
|
49
|
+
resourceId = resource.slice(slash + 1);
|
|
50
|
+
}
|
|
51
|
+
else if (colon >= 0) {
|
|
52
|
+
resourceType = resource.slice(0, colon);
|
|
53
|
+
resourceId = resource.slice(colon + 1);
|
|
54
|
+
}
|
|
55
|
+
return { partition, service, region, account, resource, resourceType, resourceId };
|
|
56
|
+
}
|
|
57
|
+
const TYPE_MAP = {
|
|
58
|
+
'lambda:function': 'AWS::Lambda::Function',
|
|
59
|
+
'lambda:layer': 'AWS::Lambda::LayerVersion',
|
|
60
|
+
'lambda:event-source-mapping': 'AWS::Lambda::EventSourceMapping',
|
|
61
|
+
'dynamodb:table': 'AWS::DynamoDB::Table',
|
|
62
|
+
'ecs:cluster': 'AWS::ECS::Cluster',
|
|
63
|
+
'ecs:service': 'AWS::ECS::Service',
|
|
64
|
+
'ecs:task-definition': 'AWS::ECS::TaskDefinition',
|
|
65
|
+
'ec2:instance': 'AWS::EC2::Instance',
|
|
66
|
+
'ec2:vpc': 'AWS::EC2::VPC',
|
|
67
|
+
'ec2:subnet': 'AWS::EC2::Subnet',
|
|
68
|
+
'ec2:security-group': 'AWS::EC2::SecurityGroup',
|
|
69
|
+
'ec2:natgateway': 'AWS::EC2::NatGateway',
|
|
70
|
+
'ec2:internet-gateway': 'AWS::EC2::InternetGateway',
|
|
71
|
+
'ec2:route-table': 'AWS::EC2::RouteTable',
|
|
72
|
+
'ec2:volume': 'AWS::EC2::Volume',
|
|
73
|
+
'ec2:elastic-ip': 'AWS::EC2::EIP',
|
|
74
|
+
'ec2:launch-template': 'AWS::EC2::LaunchTemplate',
|
|
75
|
+
'ec2:vpc-endpoint': 'AWS::EC2::VPCEndpoint',
|
|
76
|
+
'rds:db': 'AWS::RDS::DBInstance',
|
|
77
|
+
'rds:cluster': 'AWS::RDS::DBCluster',
|
|
78
|
+
'rds:subgrp': 'AWS::RDS::DBSubnetGroup',
|
|
79
|
+
'rds:pg': 'AWS::RDS::DBParameterGroup',
|
|
80
|
+
'rds:cluster-pg': 'AWS::RDS::DBClusterParameterGroup',
|
|
81
|
+
'apigateway:restapis': 'AWS::ApiGateway::RestApi',
|
|
82
|
+
'apigateway:apis': 'AWS::ApiGatewayV2::Api',
|
|
83
|
+
'apigateway:domainnames': 'AWS::ApiGateway::DomainName',
|
|
84
|
+
'elasticloadbalancing:loadbalancer': 'AWS::ElasticLoadBalancingV2::LoadBalancer',
|
|
85
|
+
'elasticloadbalancing:targetgroup': 'AWS::ElasticLoadBalancingV2::TargetGroup',
|
|
86
|
+
'elasticloadbalancing:listener': 'AWS::ElasticLoadBalancingV2::Listener',
|
|
87
|
+
'elasticloadbalancing:listener-rule': 'AWS::ElasticLoadBalancingV2::ListenerRule',
|
|
88
|
+
'cloudfront:distribution': 'AWS::CloudFront::Distribution',
|
|
89
|
+
'events:rule': 'AWS::Events::Rule',
|
|
90
|
+
'events:event-bus': 'AWS::Events::EventBus',
|
|
91
|
+
'scheduler:schedule': 'AWS::Scheduler::Schedule',
|
|
92
|
+
'states:stateMachine': 'AWS::StepFunctions::StateMachine',
|
|
93
|
+
'ecr:repository': 'AWS::ECR::Repository',
|
|
94
|
+
'kinesis:stream': 'AWS::Kinesis::Stream',
|
|
95
|
+
'firehose:deliverystream': 'AWS::KinesisFirehose::DeliveryStream',
|
|
96
|
+
'codebuild:project': 'AWS::CodeBuild::Project',
|
|
97
|
+
'cloudformation:stack': 'AWS::CloudFormation::Stack',
|
|
98
|
+
'logs:log-group': 'AWS::Logs::LogGroup',
|
|
99
|
+
'iam:role': 'AWS::IAM::Role',
|
|
100
|
+
'iam:policy': 'AWS::IAM::ManagedPolicy',
|
|
101
|
+
'iam:user': 'AWS::IAM::User',
|
|
102
|
+
'secretsmanager:secret': 'AWS::SecretsManager::Secret',
|
|
103
|
+
'ssm:parameter': 'AWS::SSM::Parameter',
|
|
104
|
+
'kms:key': 'AWS::KMS::Key',
|
|
105
|
+
'autoscaling:autoScalingGroup': 'AWS::AutoScaling::AutoScalingGroup',
|
|
106
|
+
'elasticache:cluster': 'AWS::ElastiCache::CacheCluster',
|
|
107
|
+
'elasticache:replicationgroup': 'AWS::ElastiCache::ReplicationGroup',
|
|
108
|
+
'cognito-idp:userpool': 'AWS::Cognito::UserPool',
|
|
109
|
+
'acm:certificate': 'AWS::CertificateManager::Certificate',
|
|
110
|
+
'route53:hostedzone': 'AWS::Route53::HostedZone',
|
|
111
|
+
'cloudwatch:alarm': 'AWS::CloudWatch::Alarm',
|
|
112
|
+
'appsync:apis': 'AWS::AppSync::GraphQLApi',
|
|
113
|
+
'wafv2:regional': 'AWS::WAFv2::WebACL',
|
|
114
|
+
'wafv2:global': 'AWS::WAFv2::WebACL',
|
|
115
|
+
'efs:file-system': 'AWS::EFS::FileSystem',
|
|
116
|
+
};
|
|
117
|
+
/** ARN → tipo CloudFormation (melhor esforço; null quando desconhecido). */
|
|
118
|
+
export function arnToResourceType(arn) {
|
|
119
|
+
const p = parseArn(arn);
|
|
120
|
+
if (!p)
|
|
121
|
+
return null;
|
|
122
|
+
if (p.service === 's3' && !p.resourceType && !p.resource.includes('/'))
|
|
123
|
+
return 'AWS::S3::Bucket';
|
|
124
|
+
if (p.service === 'sqs')
|
|
125
|
+
return 'AWS::SQS::Queue';
|
|
126
|
+
if (p.service === 'sns')
|
|
127
|
+
return p.resource.includes(':') ? 'AWS::SNS::Subscription' : 'AWS::SNS::Topic';
|
|
128
|
+
if (p.service === 'codepipeline')
|
|
129
|
+
return 'AWS::CodePipeline::Pipeline';
|
|
130
|
+
if (p.service === 'states' && p.resourceType === 'stateMachine')
|
|
131
|
+
return 'AWS::StepFunctions::StateMachine';
|
|
132
|
+
if (p.service === 'autoscaling' && p.resource.startsWith('autoScalingGroup'))
|
|
133
|
+
return 'AWS::AutoScaling::AutoScalingGroup';
|
|
134
|
+
return TYPE_MAP[`${p.service}:${p.resourceType}`] ?? null;
|
|
135
|
+
}
|
|
136
|
+
/** Nome legível a partir do ARN. */
|
|
137
|
+
export function nameFromArn(arn) {
|
|
138
|
+
const p = parseArn(arn);
|
|
139
|
+
if (!p)
|
|
140
|
+
return arn;
|
|
141
|
+
if (p.service === 'cloudformation' && p.resourceType === 'stack')
|
|
142
|
+
return p.resourceId.split('/')[0] ?? p.resourceId;
|
|
143
|
+
if (p.service === 'elasticloadbalancing') {
|
|
144
|
+
const segs = p.resourceId.split('/');
|
|
145
|
+
return (p.resourceType === 'loadbalancer' ? segs[1] : segs[0]) ?? p.resourceId;
|
|
146
|
+
}
|
|
147
|
+
if (p.service === 'autoscaling')
|
|
148
|
+
return /autoScalingGroupName\/(.+)$/.exec(p.resource)?.[1] ?? p.resource;
|
|
149
|
+
if (p.service === 'lambda' && p.resourceType === 'function')
|
|
150
|
+
return p.resourceId.split(':')[0] ?? p.resourceId;
|
|
151
|
+
if (p.service === 'logs' && p.resourceType === 'log-group')
|
|
152
|
+
return p.resourceId.replace(/:\*$/, '');
|
|
153
|
+
if (p.service === 'states')
|
|
154
|
+
return p.resourceId.split(':')[0] ?? p.resourceId;
|
|
155
|
+
const segs = p.resourceId.split(/[/:]/).filter(Boolean);
|
|
156
|
+
return segs[segs.length - 1] ?? p.resourceId;
|
|
157
|
+
}
|
|
158
|
+
/** Serviço amigável (`lambda`, `ecs.service`…) só para o resumo. */
|
|
159
|
+
export function serviceLabel(resourceType, arn) {
|
|
160
|
+
if (resourceType) {
|
|
161
|
+
const [, svc = 'generic', kind = ''] = resourceType.split('::');
|
|
162
|
+
return `${svc.toLowerCase()}${kind ? '.' + kind.toLowerCase() : ''}`;
|
|
163
|
+
}
|
|
164
|
+
return parseArn(arn)?.service ?? 'generic';
|
|
165
|
+
}
|
|
166
|
+
/* ---------------- descoberta ---------------- */
|
|
167
|
+
function tagsFromExplorer(properties) {
|
|
168
|
+
const tagProp = properties?.find((p) => p.Name === 'tags' || p.Name === 'Tags');
|
|
169
|
+
if (!tagProp || !Array.isArray(tagProp.Data))
|
|
170
|
+
return undefined;
|
|
171
|
+
const out = {};
|
|
172
|
+
for (const t of tagProp.Data)
|
|
173
|
+
if (t?.Key)
|
|
174
|
+
out[t.Key] = t.Value ?? '';
|
|
175
|
+
return Object.keys(out).length ? out : undefined;
|
|
176
|
+
}
|
|
177
|
+
async function explorerSearch(region, credentials, budget) {
|
|
178
|
+
const rex = new ResourceExplorer2Client({ region, credentials });
|
|
179
|
+
try {
|
|
180
|
+
const idx = await rex.send(new GetIndexCommand({}));
|
|
181
|
+
if (idx.State !== 'ACTIVE')
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
return null; // sem índice nesta região
|
|
186
|
+
}
|
|
187
|
+
const resources = [];
|
|
188
|
+
let nextToken;
|
|
189
|
+
let complete = true;
|
|
190
|
+
try {
|
|
191
|
+
do {
|
|
192
|
+
const res = await rex.send(new SearchCommand({ QueryString: '*', MaxResults: 1000, NextToken: nextToken }));
|
|
193
|
+
for (const r of res.Resources ?? []) {
|
|
194
|
+
if (!r.Arn)
|
|
195
|
+
continue;
|
|
196
|
+
resources.push({
|
|
197
|
+
arn: r.Arn,
|
|
198
|
+
resourceType: r.CfnResourceType || arnToResourceType(r.Arn),
|
|
199
|
+
region: r.Region || region,
|
|
200
|
+
name: nameFromArn(r.Arn),
|
|
201
|
+
tags: tagsFromExplorer(r.Properties),
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
if (res.Count && res.Count.Complete === false)
|
|
205
|
+
complete = false;
|
|
206
|
+
nextToken = res.NextToken;
|
|
207
|
+
} while (nextToken && resources.length < budget);
|
|
208
|
+
if (nextToken)
|
|
209
|
+
complete = false;
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
const name = err.name ?? '';
|
|
213
|
+
// Sem view padrão: não dá para buscar; cai para o Tagging API.
|
|
214
|
+
if (/UnauthorizedException|ResourceNotFound|ValidationException|AccessDenied/i.test(name))
|
|
215
|
+
return null;
|
|
216
|
+
throw err;
|
|
217
|
+
}
|
|
218
|
+
return { resources: resources.slice(0, budget), complete };
|
|
219
|
+
}
|
|
220
|
+
async function taggingResources(region, credentials) {
|
|
221
|
+
const tagging = new ResourceGroupsTaggingAPIClient({ region, credentials });
|
|
222
|
+
const out = [];
|
|
223
|
+
let token;
|
|
224
|
+
do {
|
|
225
|
+
const res = await tagging.send(new GetResourcesCommand({ PaginationToken: token, ResourcesPerPage: 100 }));
|
|
226
|
+
for (const m of res.ResourceTagMappingList ?? []) {
|
|
227
|
+
if (!m.ResourceARN)
|
|
228
|
+
continue;
|
|
229
|
+
const tags = {};
|
|
230
|
+
for (const t of m.Tags ?? [])
|
|
231
|
+
if (t.Key)
|
|
232
|
+
tags[t.Key] = t.Value ?? '';
|
|
233
|
+
out.push({ arn: m.ResourceARN, resourceType: arnToResourceType(m.ResourceARN), region: parseArn(m.ResourceARN)?.region || region, name: nameFromArn(m.ResourceARN), tags: Object.keys(tags).length ? tags : undefined });
|
|
234
|
+
}
|
|
235
|
+
token = res.PaginationToken || undefined;
|
|
236
|
+
} while (token && out.length < TAGGING_CAP);
|
|
237
|
+
return out;
|
|
238
|
+
}
|
|
239
|
+
const ACTIVE_STACK_STATUSES = [
|
|
240
|
+
'CREATE_IN_PROGRESS', 'CREATE_COMPLETE', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_FAILED', 'ROLLBACK_COMPLETE', 'DELETE_FAILED',
|
|
241
|
+
'UPDATE_IN_PROGRESS', 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS', 'UPDATE_COMPLETE', 'UPDATE_FAILED', 'UPDATE_ROLLBACK_IN_PROGRESS',
|
|
242
|
+
'UPDATE_ROLLBACK_FAILED', 'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS', 'UPDATE_ROLLBACK_COMPLETE', 'REVIEW_IN_PROGRESS',
|
|
243
|
+
'IMPORT_IN_PROGRESS', 'IMPORT_COMPLETE', 'IMPORT_ROLLBACK_IN_PROGRESS', 'IMPORT_ROLLBACK_FAILED', 'IMPORT_ROLLBACK_COMPLETE',
|
|
244
|
+
];
|
|
245
|
+
/** Constrói o ARN a partir do physical id para os tipos em que isso é determinístico. */
|
|
246
|
+
function arnFromPhysicalId(type, physicalId, region, account, partition = 'aws') {
|
|
247
|
+
if (physicalId.startsWith('arn:'))
|
|
248
|
+
return physicalId;
|
|
249
|
+
switch (type) {
|
|
250
|
+
case 'AWS::Lambda::Function': return `arn:${partition}:lambda:${region}:${account}:function:${physicalId}`;
|
|
251
|
+
case 'AWS::SQS::Queue': {
|
|
252
|
+
const name = physicalId.split('/').pop();
|
|
253
|
+
return name ? `arn:${partition}:sqs:${region}:${account}:${name}` : null;
|
|
254
|
+
}
|
|
255
|
+
case 'AWS::DynamoDB::Table': return `arn:${partition}:dynamodb:${region}:${account}:table/${physicalId}`;
|
|
256
|
+
case 'AWS::S3::Bucket': return `arn:${partition}:s3:::${physicalId}`;
|
|
257
|
+
case 'AWS::ECS::Cluster': return `arn:${partition}:ecs:${region}:${account}:cluster/${physicalId}`;
|
|
258
|
+
case 'AWS::Logs::LogGroup': return `arn:${partition}:logs:${region}:${account}:log-group:${physicalId}`;
|
|
259
|
+
case 'AWS::Kinesis::Stream': return `arn:${partition}:kinesis:${region}:${account}:stream/${physicalId}`;
|
|
260
|
+
case 'AWS::ECR::Repository': return `arn:${partition}:ecr:${region}:${account}:repository/${physicalId}`;
|
|
261
|
+
case 'AWS::RDS::DBInstance': return `arn:${partition}:rds:${region}:${account}:db:${physicalId}`;
|
|
262
|
+
case 'AWS::RDS::DBCluster': return `arn:${partition}:rds:${region}:${account}:cluster:${physicalId}`;
|
|
263
|
+
case 'AWS::CodePipeline::Pipeline': return `arn:${partition}:codepipeline:${region}:${account}:${physicalId}`;
|
|
264
|
+
case 'AWS::CodeBuild::Project': return `arn:${partition}:codebuild:${region}:${account}:project/${physicalId}`;
|
|
265
|
+
case 'AWS::Events::Rule': return `arn:${partition}:events:${region}:${account}:rule/${physicalId}`;
|
|
266
|
+
case 'AWS::EC2::VPC': return `arn:${partition}:ec2:${region}:${account}:vpc/${physicalId}`;
|
|
267
|
+
case 'AWS::EC2::Subnet': return `arn:${partition}:ec2:${region}:${account}:subnet/${physicalId}`;
|
|
268
|
+
case 'AWS::EC2::SecurityGroup': return `arn:${partition}:ec2:${region}:${account}:security-group/${physicalId}`;
|
|
269
|
+
case 'AWS::EC2::Instance': return `arn:${partition}:ec2:${region}:${account}:instance/${physicalId}`;
|
|
270
|
+
case 'AWS::EC2::NatGateway': return `arn:${partition}:ec2:${region}:${account}:natgateway/${physicalId}`;
|
|
271
|
+
case 'AWS::CloudFront::Distribution': return `arn:${partition}:cloudfront::${account}:distribution/${physicalId}`;
|
|
272
|
+
case 'AWS::ApiGateway::RestApi': return `arn:${partition}:apigateway:${region}::/restapis/${physicalId}`;
|
|
273
|
+
case 'AWS::ApiGatewayV2::Api': return `arn:${partition}:apigateway:${region}::/apis/${physicalId}`;
|
|
274
|
+
case 'AWS::IAM::Role': return `arn:${partition}:iam::${account}:role/${physicalId}`;
|
|
275
|
+
default: return null;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
export async function discoverAws(options) {
|
|
279
|
+
const credentials = awsCredentials(options.profile);
|
|
280
|
+
const regions = [...new Set(options.regions)];
|
|
281
|
+
const sts = new STSClient({ region: regions[0] ?? 'us-east-1', credentials });
|
|
282
|
+
const identity = await sts.send(new GetCallerIdentityCommand({}));
|
|
283
|
+
const accountId = identity.Account ?? '';
|
|
284
|
+
const partition = parseArn(identity.Arn ?? '')?.partition || 'aws';
|
|
285
|
+
const byArn = new Map();
|
|
286
|
+
const sources = {};
|
|
287
|
+
const stacks = [];
|
|
288
|
+
const warnings = [];
|
|
289
|
+
const add = (r) => {
|
|
290
|
+
const prev = byArn.get(r.arn);
|
|
291
|
+
if (!prev)
|
|
292
|
+
byArn.set(r.arn, r);
|
|
293
|
+
else
|
|
294
|
+
byArn.set(r.arn, { ...prev, ...Object.fromEntries(Object.entries(r).filter(([, v]) => v !== undefined && v !== null)), tags: { ...(prev.tags ?? {}), ...(r.tags ?? {}) } });
|
|
295
|
+
};
|
|
296
|
+
const regionSet = new Set(regions);
|
|
297
|
+
for (const region of regions) {
|
|
298
|
+
options.onProgress?.(`região ${region}`);
|
|
299
|
+
try {
|
|
300
|
+
const budget = Math.max(0, EXPLORER_CAP - byArn.size);
|
|
301
|
+
const explorer = budget > 0 ? await explorerSearch(region, credentials, budget) : null;
|
|
302
|
+
if (explorer) {
|
|
303
|
+
// Índice agregador devolve outras regiões: mantém só as pedidas + globais.
|
|
304
|
+
for (const r of explorer.resources)
|
|
305
|
+
if (!r.region || r.region === 'global' || regionSet.has(r.region))
|
|
306
|
+
add({ ...r, region: r.region && r.region !== 'global' ? r.region : region });
|
|
307
|
+
sources[region] = 'resource-explorer';
|
|
308
|
+
if (!explorer.complete) {
|
|
309
|
+
for (const r of await taggingResources(region, credentials))
|
|
310
|
+
add(r);
|
|
311
|
+
sources[region] = 'resource-explorer+tagging-api';
|
|
312
|
+
warnings.push(`${region}: Resource Explorer devolveu resultado parcial (limite de ${EXPLORER_CAP}); complementado com o Tagging API.`);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
for (const r of await taggingResources(region, credentials))
|
|
317
|
+
add({ ...r, region: r.region || region });
|
|
318
|
+
sources[region] = 'tagging-api';
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
catch (err) {
|
|
322
|
+
sources[region] = 'error';
|
|
323
|
+
warnings.push(`${region}: inventário falhou — ${describeAwsError(err)}`);
|
|
324
|
+
}
|
|
325
|
+
// CloudFormation: stacks e logical ids.
|
|
326
|
+
try {
|
|
327
|
+
const cfn = new CloudFormationClient({ region, credentials });
|
|
328
|
+
const index = new Map(); // `${type}|${name}` → arn
|
|
329
|
+
for (const r of byArn.values())
|
|
330
|
+
if (r.resourceType && r.name)
|
|
331
|
+
index.set(`${r.resourceType}|${r.name}`, r.arn);
|
|
332
|
+
let token;
|
|
333
|
+
const summaries = [];
|
|
334
|
+
do {
|
|
335
|
+
const res = await cfn.send(new ListStacksCommand({ NextToken: token, StackStatusFilter: ACTIVE_STACK_STATUSES }));
|
|
336
|
+
summaries.push(...(res.StackSummaries ?? []));
|
|
337
|
+
token = res.NextToken;
|
|
338
|
+
} while (token);
|
|
339
|
+
let totalStackResources = 0;
|
|
340
|
+
for (const s of summaries) {
|
|
341
|
+
if (!s.StackName || !s.StackId)
|
|
342
|
+
continue;
|
|
343
|
+
add({ arn: s.StackId, resourceType: 'AWS::CloudFormation::Stack', region, name: s.StackName });
|
|
344
|
+
let rtoken;
|
|
345
|
+
let count = 0;
|
|
346
|
+
let mapped = 0;
|
|
347
|
+
do {
|
|
348
|
+
const res = await cfn.send(new ListStackResourcesCommand({ StackName: s.StackName, NextToken: rtoken }));
|
|
349
|
+
for (const sr of res.StackResourceSummaries ?? []) {
|
|
350
|
+
count++;
|
|
351
|
+
totalStackResources++;
|
|
352
|
+
const type = sr.ResourceType ?? '';
|
|
353
|
+
const physical = sr.PhysicalResourceId ?? '';
|
|
354
|
+
if (!physical || type.startsWith('Custom::') || type === 'AWS::CDK::Metadata')
|
|
355
|
+
continue;
|
|
356
|
+
let arn = physical.startsWith('arn:') ? physical : undefined;
|
|
357
|
+
if (!arn) {
|
|
358
|
+
const name = type === 'AWS::SQS::Queue' ? physical.split('/').pop() ?? physical : physical;
|
|
359
|
+
arn = index.get(`${type}|${name}`);
|
|
360
|
+
}
|
|
361
|
+
if (!arn)
|
|
362
|
+
arn = arnFromPhysicalId(type, physical, region, accountId, partition) ?? undefined;
|
|
363
|
+
if (!arn)
|
|
364
|
+
continue;
|
|
365
|
+
mapped++;
|
|
366
|
+
add({ arn, resourceType: type || arnToResourceType(arn), region, name: nameFromArn(arn), stackName: s.StackName, stackLogicalId: sr.LogicalResourceId });
|
|
367
|
+
}
|
|
368
|
+
rtoken = res.NextToken;
|
|
369
|
+
} while (rtoken && totalStackResources < STACK_RESOURCES_CAP);
|
|
370
|
+
stacks.push({ name: s.StackName, region, status: s.StackStatus ?? '', resources: count, mapped, stackId: s.StackId });
|
|
371
|
+
if (totalStackResources >= STACK_RESOURCES_CAP) {
|
|
372
|
+
warnings.push(`${region}: limite de ${STACK_RESOURCES_CAP} recursos de stacks atingido; stacks restantes sem logical ids.`);
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
catch (err) {
|
|
378
|
+
warnings.push(`${region}: CloudFormation falhou — ${describeAwsError(err)}`);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
return { accountId, callerArn: identity.Arn ?? '', regions, resources: [...byArn.values()], sources, stacks, warnings };
|
|
382
|
+
}
|
|
383
|
+
/** Lê os outputs de um stack (DescribeStacks, somente leitura). */
|
|
384
|
+
export async function readStackOutputs(stackName, region, profile) {
|
|
385
|
+
const cfn = new CloudFormationClient({ region, credentials: awsCredentials(profile) });
|
|
386
|
+
const res = await cfn.send(new DescribeStacksCommand({ StackName: stackName }));
|
|
387
|
+
const out = {};
|
|
388
|
+
for (const o of res.Stacks?.[0]?.Outputs ?? [])
|
|
389
|
+
if (o.OutputKey && o.OutputValue)
|
|
390
|
+
out[o.OutputKey] = o.OutputValue;
|
|
391
|
+
return out;
|
|
392
|
+
}
|
|
393
|
+
//# sourceMappingURL=aws.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aws.js","sourceRoot":"","sources":["../../src/infra/aws.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Gerador de unified diff (compatível com `git apply`) a partir de edições por linha. */
|
|
2
|
+
export interface LineEdit {
|
|
3
|
+
/** Índice 0-based da primeira linha afetada no arquivo original. */
|
|
4
|
+
start: number;
|
|
5
|
+
deleteCount: number;
|
|
6
|
+
insert: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function splitLines(content: string): {
|
|
9
|
+
lines: string[];
|
|
10
|
+
trailingNewline: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare function applyEdits(lines: string[], edits: LineEdit[]): string[];
|
|
13
|
+
/** Remove sobreposições (mantém a primeira edição de cada região). */
|
|
14
|
+
export declare function normalizeEdits(edits: LineEdit[]): LineEdit[];
|
|
15
|
+
export declare function unifiedDiff(path: string, content: string | null, rawEdits: LineEdit[], context?: number): string;
|