agent-master-devsecops 0.0.0-stage → 5.1.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 +204 -2
- package/agents/AGENT_DEVSECOPS.md +32 -0
- package/agents/AGENT_INFRA.md +31 -0
- package/agents/AGENT_ORCHESTRATOR.md +39 -0
- package/agents/AGENT_QA.md +58 -0
- package/agents/AGENT_SCRUM.md +23 -0
- package/agents/AGENT_SRE.md +22 -0
- package/agents/AGENT_UIUX.md +26 -0
- package/docs/ARCHITECTURE.md +152 -0
- package/docs/CALCULATIONS.md +17 -0
- package/docs/CHANGELOG.md +112 -0
- package/docs/ENGINEERING_RULES.md +56 -0
- package/docs/IDEAS.md +17 -0
- package/docs/LOCAL_BACKLOG.md +20 -0
- package/docs/STATE.md +111 -0
- package/docs/playbooks/PLAYBOOK_CIRCUIT_BREAKER_LLM.md +58 -0
- package/docs/playbooks/PLAYBOOK_OPENTELEMETRY_TRACING.md +58 -0
- package/package.json +57 -4
- package/scripts/auditors/a11y_auditor.js +462 -0
- package/scripts/auditors/code_quality_auditor.js +444 -0
- package/scripts/auditors/contract_test_validator.js +396 -0
- package/scripts/auditors/eval_harness.js +213 -0
- package/scripts/auditors/git_hygiene_linter.js +391 -0
- package/scripts/auditors/pr_reviewer.js +627 -0
- package/scripts/auditors/sast_scanner.js +442 -0
- package/scripts/auditors/sca_dependency_auditor.js +673 -0
- package/scripts/bin/bootstrap_cli.js +597 -0
- package/scripts/bin/domain_idea_miner.js +658 -0
- package/scripts/bin/smart_onboarding.js +905 -0
- package/scripts/bin/web_inspector.js +578 -0
- package/scripts/core/architecture_advisor.js +378 -0
- package/scripts/core/ast_skeletonizer.js +413 -0
- package/scripts/core/autonomous_remediation_engine.js +305 -0
- package/scripts/core/circuit_breaker.js +546 -0
- package/scripts/core/context_compressor.js +237 -0
- package/scripts/core/fast_feature_scaffold.js +840 -0
- package/scripts/core/hot_state_cache.js +238 -0
- package/scripts/core/knowledge_gateway.js +888 -0
- package/scripts/core/magic_prompt_generator.js +250 -0
- package/scripts/core/multi_agent_orchestrator.js +421 -0
- package/scripts/core/otel_tracer.js +335 -0
- package/scripts/core/perf_benchmark.js +212 -0
- package/scripts/core/sarif_engine.js +299 -0
- package/scripts/core/sre_remediation_engine.js +236 -0
- package/scripts/core/universal_packager.js +357 -0
- package/scripts/integrations/atlassian_client.js +600 -0
- package/scripts/integrations/atlassian_sync_action.js +576 -0
- package/scripts/integrations/confluence_sync.js +684 -0
- package/scripts/integrations/credentials_guard.js +500 -0
- package/scripts/integrations/jira_manager.js +722 -0
- package/scripts/mcp/handlers/atlassian_handlers.js +300 -0
- package/scripts/mcp/handlers/core_handlers.js +419 -0
- package/scripts/mcp/handlers/qa_handlers.js +502 -0
- package/scripts/mcp/handlers/rules_handlers.js +379 -0
- package/scripts/mcp/handlers/scaffold_handlers.js +334 -0
- package/scripts/mcp/handlers/sre_handlers.js +443 -0
- package/scripts/mcp/resources_registry.js +453 -0
- package/scripts/mcp/server.js +408 -0
- package/scripts/mcp/tool_handlers.js +444 -0
- package/scripts/mcp/tools_registry.js +1123 -0
- package/scripts/mcp_server.js +236 -0
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* scripts/bin/bootstrap_cli.js
|
|
4
|
+
*
|
|
5
|
+
* Universal One-Line Bootstrap CLI (v5.1 Enterprise).
|
|
6
|
+
* Ponto de entrada executável principal do pacote npm (agent-master-devsecops / agent-master-init).
|
|
7
|
+
* Auto-detecta IDEs instaladas (Cursor, Windsurf, VS Code, Claude Desktop, Antigravity, Ollama)
|
|
8
|
+
* e provisiona o ecossistema multiagente, governança e servidor MCP com zero configuração em < 2 segundos.
|
|
9
|
+
*/
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
const fs = require('node:fs');
|
|
13
|
+
const path = require('node:path');
|
|
14
|
+
const { execFileSync } = require('node:child_process');
|
|
15
|
+
const { UniversalPackager } = require('../core/universal_packager.js');
|
|
16
|
+
const { runCredentialHealthcheck } = require('../integrations/credentials_guard.js');
|
|
17
|
+
const { detectProjectMode, inspectProjectContext } = require('./smart_onboarding.js');
|
|
18
|
+
|
|
19
|
+
// Catálogo imutável de arquivos canônicos da suíte
|
|
20
|
+
const CANONICAL_FILES = Object.freeze([
|
|
21
|
+
'agents/AGENT_ORCHESTRATOR.md',
|
|
22
|
+
'agents/AGENT_UIUX.md',
|
|
23
|
+
'agents/AGENT_DEVSECOPS.md',
|
|
24
|
+
'agents/AGENT_SCRUM.md',
|
|
25
|
+
'agents/AGENT_SRE.md',
|
|
26
|
+
'agents/AGENT_QA.md',
|
|
27
|
+
'agents/AGENT_INFRA.md',
|
|
28
|
+
'docs/ENGINEERING_RULES.md',
|
|
29
|
+
'docs/ARCHITECTURE.md',
|
|
30
|
+
'docs/IDEAS.md'
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Executa checagem de existência de comando no PATH de forma protegida contra travamentos.
|
|
35
|
+
* @param {string} cmd
|
|
36
|
+
* @returns {boolean}
|
|
37
|
+
*/
|
|
38
|
+
function commandExists(cmd) {
|
|
39
|
+
if (!cmd || typeof cmd !== 'string') return false;
|
|
40
|
+
try {
|
|
41
|
+
const bin = process.platform === 'win32' ? 'where' : 'which';
|
|
42
|
+
execFileSync(bin, [cmd], {
|
|
43
|
+
stdio: 'ignore',
|
|
44
|
+
timeout: 3000,
|
|
45
|
+
windowsHide: true
|
|
46
|
+
});
|
|
47
|
+
return true;
|
|
48
|
+
} catch (_) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Auto-detecta ambientes e IDEs suportadas para o projeto alvo.
|
|
55
|
+
* @param {string} [targetDir=process.cwd()]
|
|
56
|
+
* @param {object} [options={}]
|
|
57
|
+
* @returns {object}
|
|
58
|
+
*/
|
|
59
|
+
function detectEnvironments(targetDir = process.cwd(), options = {}) {
|
|
60
|
+
const safeTargetDir = typeof targetDir === 'string' && targetDir ? targetDir : process.cwd();
|
|
61
|
+
const safeOptions = (options && typeof options === 'object') ? options : {};
|
|
62
|
+
|
|
63
|
+
const detected = {
|
|
64
|
+
cursor: false,
|
|
65
|
+
windsurf: false,
|
|
66
|
+
vscode: false,
|
|
67
|
+
claude_desktop: false,
|
|
68
|
+
ollama: false,
|
|
69
|
+
antigravity: false,
|
|
70
|
+
generic: true
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '';
|
|
74
|
+
|
|
75
|
+
// 0. Se plataformas foram especificadas expressamente (options.platforms), honrar estritamente
|
|
76
|
+
if (Array.isArray(safeOptions.platforms) && safeOptions.platforms.length > 0) {
|
|
77
|
+
for (const p of safeOptions.platforms) {
|
|
78
|
+
const clean = String(p).toLowerCase().trim();
|
|
79
|
+
if (clean === 'all' || clean === 'universal') {
|
|
80
|
+
detected.cursor = true;
|
|
81
|
+
detected.windsurf = true;
|
|
82
|
+
detected.vscode = true;
|
|
83
|
+
detected.claude_desktop = true;
|
|
84
|
+
detected.antigravity = true;
|
|
85
|
+
} else if (clean === 'vscode' || clean === 'code') {
|
|
86
|
+
detected.vscode = true;
|
|
87
|
+
} else if (clean === 'antigravity' || clean === 'gemini') {
|
|
88
|
+
detected.antigravity = true;
|
|
89
|
+
} else if (clean === 'cursor') {
|
|
90
|
+
detected.cursor = true;
|
|
91
|
+
} else if (clean === 'windsurf') {
|
|
92
|
+
detected.windsurf = true;
|
|
93
|
+
} else if (clean === 'claude_desktop' || clean === 'claude') {
|
|
94
|
+
detected.claude_desktop = true;
|
|
95
|
+
} else if (clean === 'ollama') {
|
|
96
|
+
detected.ollama = true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return detected;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// 1. Detectar Antigravity no targetDir ou processo ativo
|
|
103
|
+
const isRunningInAntigravity = Boolean(process.env.ANTIGRAVITY_AGENT || process.env.ANTIGRAVITY_APP_DATA_DIR);
|
|
104
|
+
if (
|
|
105
|
+
isRunningInAntigravity ||
|
|
106
|
+
fs.existsSync(path.join(safeTargetDir, '.antigravity')) ||
|
|
107
|
+
fs.existsSync(path.join(safeTargetDir, '.gemini'))
|
|
108
|
+
) {
|
|
109
|
+
detected.antigravity = true;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 2. Detectar Cursor no targetDir
|
|
113
|
+
if (
|
|
114
|
+
fs.existsSync(path.join(safeTargetDir, '.cursor')) ||
|
|
115
|
+
fs.existsSync(path.join(safeTargetDir, '.cursorrules'))
|
|
116
|
+
) {
|
|
117
|
+
detected.cursor = true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 3. Detectar Windsurf no targetDir
|
|
121
|
+
if (
|
|
122
|
+
fs.existsSync(path.join(safeTargetDir, '.windsurf')) ||
|
|
123
|
+
fs.existsSync(path.join(safeTargetDir, '.windsurfrules'))
|
|
124
|
+
) {
|
|
125
|
+
detected.windsurf = true;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 4. Detectar VS Code SOMENTE se houver diretório .vscode existente no targetDir
|
|
129
|
+
if (fs.existsSync(path.join(safeTargetDir, '.vscode'))) {
|
|
130
|
+
detected.vscode = true;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// 5. Detectar Claude Desktop no targetDir
|
|
134
|
+
if (
|
|
135
|
+
fs.existsSync(path.join(safeTargetDir, '.claude')) ||
|
|
136
|
+
fs.existsSync(path.join(safeTargetDir, 'claude_desktop_config.json'))
|
|
137
|
+
) {
|
|
138
|
+
detected.claude_desktop = true;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// 6. Detectar Ollama no targetDir
|
|
142
|
+
if (fs.existsSync(path.join(safeTargetDir, 'Modelfile'))) {
|
|
143
|
+
detected.ollama = true;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Se nenhum arquivo de IDE foi encontrado no diretório do projeto:
|
|
147
|
+
const hasProjectLevelIde = detected.antigravity || detected.cursor || detected.windsurf || detected.vscode || detected.claude_desktop || detected.ollama;
|
|
148
|
+
if (!hasProjectLevelIde) {
|
|
149
|
+
// Se há Antigravity no ambiente do usuário, assume Antigravity por padrão
|
|
150
|
+
if (
|
|
151
|
+
(homeDir && fs.existsSync(path.join(homeDir, '.gemini', 'antigravity'))) ||
|
|
152
|
+
commandExists('antigravity') ||
|
|
153
|
+
commandExists('agy')
|
|
154
|
+
) {
|
|
155
|
+
detected.antigravity = true;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return detected;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Provisiona o ecossistema Agent Master DevSecOps e o servidor MCP no diretório alvo.
|
|
164
|
+
* @param {string} [targetDir=process.cwd()]
|
|
165
|
+
* @param {object} [options={}]
|
|
166
|
+
* @returns {object}
|
|
167
|
+
*/
|
|
168
|
+
function bootstrapEnvironment(targetDir = process.cwd(), options = {}) {
|
|
169
|
+
const startTime = Date.now();
|
|
170
|
+
const safeTargetDir = typeof targetDir === 'string' && targetDir ? targetDir : process.cwd();
|
|
171
|
+
const safeOptions = (options && typeof options === 'object') ? options : {};
|
|
172
|
+
const rootSource = path.resolve(__dirname, '../..');
|
|
173
|
+
const dryRun = Boolean(safeOptions.dryRun);
|
|
174
|
+
|
|
175
|
+
// 1. Auto-detectar ambientes
|
|
176
|
+
const detected = safeOptions.platforms
|
|
177
|
+
? detectEnvironments(safeTargetDir, { platforms: safeOptions.platforms })
|
|
178
|
+
: detectEnvironments(safeTargetDir, safeOptions);
|
|
179
|
+
|
|
180
|
+
const activePlatforms = Object.keys(detected).filter(k => detected[k]);
|
|
181
|
+
const credentialHealth = runCredentialHealthcheck(safeTargetDir);
|
|
182
|
+
const projectMode = detectProjectMode(safeTargetDir);
|
|
183
|
+
const projectContext = inspectProjectContext(safeTargetDir);
|
|
184
|
+
|
|
185
|
+
const results = {
|
|
186
|
+
onboardingMode: projectMode.mode,
|
|
187
|
+
projectContext,
|
|
188
|
+
status: 'SUCCESS',
|
|
189
|
+
targetDir: safeTargetDir,
|
|
190
|
+
dryRun,
|
|
191
|
+
detectedEnvironments: detected,
|
|
192
|
+
activePlatforms,
|
|
193
|
+
credentials: {
|
|
194
|
+
allReady: credentialHealth.allReady,
|
|
195
|
+
github: credentialHealth.github,
|
|
196
|
+
atlassian: credentialHealth.atlassian,
|
|
197
|
+
missing: credentialHealth.missing,
|
|
198
|
+
promptGuidance: credentialHealth.promptGuidance
|
|
199
|
+
},
|
|
200
|
+
copiedFiles: [],
|
|
201
|
+
configuredPlatforms: [],
|
|
202
|
+
mcpServerPath: path.resolve(rootSource, 'scripts', 'mcp_server.js'),
|
|
203
|
+
durationMs: 0
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// 2. Provisionar arquivos canônicos do agente no safeTargetDir (Modo Limpo de Submódulo)
|
|
207
|
+
const isSubmoduleMode = Boolean(
|
|
208
|
+
!safeOptions.forceCopy &&
|
|
209
|
+
(
|
|
210
|
+
path.resolve(safeTargetDir, 'agent-master-devsecops') === rootSource ||
|
|
211
|
+
(fs.existsSync(path.join(safeTargetDir, '.gitmodules')) && fs.existsSync(path.join(safeTargetDir, 'agent-master-devsecops')))
|
|
212
|
+
)
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
results.isSubmoduleMode = isSubmoduleMode;
|
|
216
|
+
|
|
217
|
+
if (!isSubmoduleMode) {
|
|
218
|
+
const agentDir = path.join(safeTargetDir, 'agents');
|
|
219
|
+
const docDir = path.join(safeTargetDir, 'docs');
|
|
220
|
+
|
|
221
|
+
if (!dryRun) {
|
|
222
|
+
if (!fs.existsSync(agentDir)) fs.mkdirSync(agentDir, { recursive: true });
|
|
223
|
+
if (!fs.existsSync(docDir)) fs.mkdirSync(docDir, { recursive: true });
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
for (const relFile of CANONICAL_FILES) {
|
|
227
|
+
const src = path.join(rootSource, relFile);
|
|
228
|
+
const actualSrc = src;
|
|
229
|
+
const dest = path.join(safeTargetDir, relFile);
|
|
230
|
+
|
|
231
|
+
if (fs.existsSync(actualSrc)) {
|
|
232
|
+
if (!dryRun) {
|
|
233
|
+
const destParent = path.dirname(dest);
|
|
234
|
+
if (!fs.existsSync(destParent)) fs.mkdirSync(destParent, { recursive: true });
|
|
235
|
+
fs.copyFileSync(actualSrc, dest);
|
|
236
|
+
}
|
|
237
|
+
results.copiedFiles.push(relFile);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
results.submoduleNotice = 'Submódulo detectado. Cópia redundante de agents/ e docs/ na raiz suprimida com sucesso (Modo Limpo - Regra 16).';
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// 3. Gerar configurações das plataformas detectadas
|
|
245
|
+
const packager = new UniversalPackager(rootSource);
|
|
246
|
+
|
|
247
|
+
if (detected.cursor) {
|
|
248
|
+
const res = packager.generateCursorProfile(safeTargetDir, { dryRun, mcpServerPath: results.mcpServerPath });
|
|
249
|
+
results.configuredPlatforms.push({ platform: 'cursor', files: res.filesCount });
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (detected.windsurf) {
|
|
253
|
+
const res = packager.generateWindsurfProfile(safeTargetDir, { dryRun });
|
|
254
|
+
results.configuredPlatforms.push({ platform: 'windsurf', files: res.filesCount });
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (detected.vscode) {
|
|
258
|
+
const res = packager.generateVsCodeProfile(safeTargetDir, { dryRun, mcpServerPath: results.mcpServerPath });
|
|
259
|
+
results.configuredPlatforms.push({ platform: 'vscode', files: res.filesCount });
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (detected.claude_desktop) {
|
|
263
|
+
const res = packager.generateClaudeDesktopProfile(safeTargetDir, { dryRun, mcpServerPath: results.mcpServerPath });
|
|
264
|
+
results.configuredPlatforms.push({ platform: 'claude_desktop', files: res.filesCount });
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (detected.antigravity) {
|
|
268
|
+
const res = packager.generateAntigravityConfig(safeTargetDir, { dryRun, mcpServerPath: results.mcpServerPath });
|
|
269
|
+
results.configuredPlatforms.push({ platform: 'antigravity', files: res.filesCount });
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (detected.ollama) {
|
|
273
|
+
const res = packager.generateOllamaProfile(safeTargetDir, { dryRun });
|
|
274
|
+
results.configuredPlatforms.push({ platform: 'ollama', files: res.filesCount });
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Se nenhuma IDE especializada foi detectada, gera o bundle universal genérico
|
|
278
|
+
if (results.configuredPlatforms.length === 0) {
|
|
279
|
+
const res = packager.generateCursorProfile(safeTargetDir, { dryRun, mcpServerPath: results.mcpServerPath });
|
|
280
|
+
results.configuredPlatforms.push({ platform: 'universal_fallback_cursor', files: res.filesCount });
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
results.durationMs = Date.now() - startTime;
|
|
284
|
+
return results;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Validação de integridade estrutural modular.
|
|
289
|
+
* @param {string} baseDir
|
|
290
|
+
* @returns {object}
|
|
291
|
+
*/
|
|
292
|
+
function validateModularStructure(baseDir) {
|
|
293
|
+
const safeBaseDir = typeof baseDir === 'string' && baseDir ? baseDir : process.cwd();
|
|
294
|
+
const missing = [];
|
|
295
|
+
const present = [];
|
|
296
|
+
|
|
297
|
+
for (const relPath of CANONICAL_FILES) {
|
|
298
|
+
const fullPath = path.join(safeBaseDir, relPath);
|
|
299
|
+
if (fs.existsSync(fullPath)) {
|
|
300
|
+
present.push(relPath);
|
|
301
|
+
} else {
|
|
302
|
+
missing.push(relPath);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return {
|
|
307
|
+
valid: missing.length === 0,
|
|
308
|
+
total: CANONICAL_FILES.length,
|
|
309
|
+
present,
|
|
310
|
+
missing
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Função de inicialização universal com contrato do init_cli.
|
|
316
|
+
* @param {string} [targetDir=process.cwd()]
|
|
317
|
+
* @param {object} [options={}]
|
|
318
|
+
* @returns {object}
|
|
319
|
+
*/
|
|
320
|
+
function initProject(targetDir = process.cwd(), options = {}) {
|
|
321
|
+
const res = bootstrapEnvironment(targetDir, options);
|
|
322
|
+
res.rulesConfigured = res.copiedFiles.length > 0 || Boolean(options && options.dryRun) || Boolean(res.isSubmoduleMode);
|
|
323
|
+
res.mcpConfigured = true;
|
|
324
|
+
return res;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Renderiza o prompt canônico customizado com metadados do projeto.
|
|
329
|
+
* @param {object} [meta={}]
|
|
330
|
+
* @returns {string}
|
|
331
|
+
*/
|
|
332
|
+
function renderCanonicalPrompt(meta = {}) {
|
|
333
|
+
const projectName = meta.projectName || 'Enterprise Software System';
|
|
334
|
+
const techStack = meta.techStack || 'Polyglot / Universal Multi-Stack';
|
|
335
|
+
const ticketSystem = meta.ticketSystem || 'Jira Cloud / GitHub Issues';
|
|
336
|
+
|
|
337
|
+
return `Você é o AGENT ORCHESTRATOR DE ENGENHARIA DE SOFTWARE, ARQUITETURA, DEVSECOPS E GOVERNANÇA do projeto "${projectName}".
|
|
338
|
+
Stack Tecnológica: ${techStack}
|
|
339
|
+
Sistema de Governança & Rastreabilidade: ${ticketSystem}
|
|
340
|
+
|
|
341
|
+
Você opera sob a estrutura modular soberana das pastas /agents e /docs com contratos de engenharia catalogados:
|
|
342
|
+
- agents/AGENT_ORCHESTRATOR.md (Orquestrador multi-persona)
|
|
343
|
+
- agents/AGENT_UIUX.md (Product Designer, UX/UI, Heurísticas & WCAG 2.1 AA)
|
|
344
|
+
- agents/AGENT_DEVSECOPS.md (Staff Engineer & DevSecOps Lead)
|
|
345
|
+
- agents/AGENT_QA.md (Auditor adversário independente)
|
|
346
|
+
- agents/AGENT_INFRA.md (Engenharia de infraestrutura, Docker & redes reais)
|
|
347
|
+
- agents/AGENT_SCRUM.md (Gestão ágil, melhoria contínua e PDCA)
|
|
348
|
+
- agents/AGENT_SRE.md (SRE Lead, observabilidade e telemetria)
|
|
349
|
+
- docs/ENGINEERING_RULES.md (10 Princípios Canônicos de Engenharia de Software & Governança / 14 Regras Fundamentais de Engenharia)
|
|
350
|
+
- README.md (Manual mestre, catálogo e MCP)
|
|
351
|
+
- docs/ARCHITECTURE.md (Topologia cooperativa e matriz de handovers)
|
|
352
|
+
|
|
353
|
+
Modos de Operação Disponíveis:
|
|
354
|
+
- modo: orchestrator
|
|
355
|
+
- modo: uiux
|
|
356
|
+
- modo: devsecops
|
|
357
|
+
- modo: qa
|
|
358
|
+
- modo: infra
|
|
359
|
+
- modo: scrum
|
|
360
|
+
- modo: sre
|
|
361
|
+
- modo: full-dev (loop ininterrupto de implementação autônoma)
|
|
362
|
+
|
|
363
|
+
Protocolo Obrigatório: Protocolo de Resposta em Duas Camadas (relatórios densos de 15 seções externalizados no Jira/Confluence/PRs e respostas curtas com links e dupla quebra de linha (\\n\\n) no chat). Declare prontidão para atuar.`;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Formata relatório executivo em Markdown do processo de bootstrapping.
|
|
368
|
+
* @param {object} result
|
|
369
|
+
* @returns {string}
|
|
370
|
+
*/
|
|
371
|
+
function formatReport(result) {
|
|
372
|
+
if (!result || typeof result !== 'object') {
|
|
373
|
+
return '# 🚀 Agent-Master DevSecOps — Bootstrap Report\n\nRelatório de bootstrapping indisponível.';
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
let output = '# 🚀 Agent-Master DevSecOps — Bootstrap Report\n\n';
|
|
377
|
+
output += `**Status:** ${result.status || 'SUCCESS'}\n`;
|
|
378
|
+
output += `**Diretório Alvo:** \`${result.targetDir || 'N/A'}\`\n`;
|
|
379
|
+
output += `**Modo de Onboarding (Regra 16):** \`${result.onboardingMode || 'UNKNOWN'}\`\n`;
|
|
380
|
+
output += `**Duração:** ${result.durationMs || 0}ms\n`;
|
|
381
|
+
output += `**Modo Simulado (dryRun):** ${result.dryRun ? 'SIM' : 'NÃO'}\n\n`;
|
|
382
|
+
|
|
383
|
+
output += '### 🛠️ Plataformas Configuradas\n';
|
|
384
|
+
const platforms = Array.isArray(result.configuredPlatforms) ? result.configuredPlatforms : [];
|
|
385
|
+
if (platforms.length === 0) {
|
|
386
|
+
output += '- Nenhuma plataforma especializada configurada.\n';
|
|
387
|
+
} else {
|
|
388
|
+
platforms.forEach(p => {
|
|
389
|
+
output += `- \`${p.platform}\`: ${p.files || 0} arquivos gerados (${p.configPath || 'configurado'})\n`;
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
output += '\n';
|
|
393
|
+
|
|
394
|
+
output += '### 📄 Arquivos Canônicos Injetados\n';
|
|
395
|
+
if (result.isSubmoduleMode) {
|
|
396
|
+
output += `- **Modo Submódulo Limpo:** ${result.submoduleNotice || 'Arquivos compartilhados sem duplicação na raiz'}\n`;
|
|
397
|
+
} else {
|
|
398
|
+
const copied = Array.isArray(result.copiedFiles) ? result.copiedFiles : (Array.isArray(result.filesCreated) ? result.filesCreated : []);
|
|
399
|
+
output += `- **Total de Arquivos:** ${copied.length}\n`;
|
|
400
|
+
copied.forEach(f => { output += ` - \`${f}\`\n`; });
|
|
401
|
+
}
|
|
402
|
+
output += '\n';
|
|
403
|
+
|
|
404
|
+
output += '### 🔐 Integridade de Credenciais\n';
|
|
405
|
+
if (result.credentials || result.credentialStatus) {
|
|
406
|
+
const cred = result.credentials || result.credentialStatus;
|
|
407
|
+
const isReady = cred.allReady || cred.isConfigured;
|
|
408
|
+
output += `- **Tríade Pronta:** ${isReady ? 'SIM (100% Autenticada)' : 'PENDENTE'}\n`;
|
|
409
|
+
if (cred.github) output += `- **GitHub CLI:** ${cred.github.authenticated ? 'OK' : 'Não autenticado'}\n`;
|
|
410
|
+
if (cred.atlassian) output += `- **Atlassian:** ${cred.atlassian.configured ? 'OK' : 'Pendente'}\n`;
|
|
411
|
+
}
|
|
412
|
+
return output;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Classe canônica do Universal Bootstrap CLI.
|
|
417
|
+
*/
|
|
418
|
+
class BootstrapCli {
|
|
419
|
+
static get CANONICAL_FILES() {
|
|
420
|
+
return CANONICAL_FILES;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
constructor(options = {}) {
|
|
424
|
+
this.options = Object.freeze({ ...options });
|
|
425
|
+
this.canonicalFiles = CANONICAL_FILES;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
commandExists(cmd) {
|
|
429
|
+
return commandExists(cmd);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
detectEnvironments(targetDir = process.cwd(), options = {}) {
|
|
433
|
+
return detectEnvironments(targetDir, { ...this.options, ...options });
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
bootstrap(targetDir = process.cwd(), options = {}) {
|
|
437
|
+
return bootstrapEnvironment(targetDir, { ...this.options, ...options });
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
bootstrapEnvironment(targetDir = process.cwd(), options = {}) {
|
|
441
|
+
return bootstrapEnvironment(targetDir, { ...this.options, ...options });
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
initProject(targetDir = process.cwd(), options = {}) {
|
|
445
|
+
return initProject(targetDir, { ...this.options, ...options });
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
validateModularStructure(baseDir = process.cwd()) {
|
|
449
|
+
return validateModularStructure(baseDir);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
renderCanonicalPrompt(meta = {}) {
|
|
453
|
+
return renderCanonicalPrompt(meta);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
formatReport(result) {
|
|
457
|
+
return formatReport(result);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
if (require.main === module) {
|
|
462
|
+
(async () => {
|
|
463
|
+
const args = process.argv.slice(2);
|
|
464
|
+
const dryRun = args.includes('--dryRun') || args.includes('-d');
|
|
465
|
+
const detectOnly = args.includes('--detectOnly');
|
|
466
|
+
const nonInteractive = args.includes('--non-interactive') || args.includes('--yes') || args.includes('-y');
|
|
467
|
+
let targetDir = process.cwd();
|
|
468
|
+
|
|
469
|
+
const targetIdx = args.findIndex(a => a === '--targetDir' || a === '-t');
|
|
470
|
+
if (targetIdx !== -1 && args[targetIdx + 1]) {
|
|
471
|
+
targetDir = path.resolve(args[targetIdx + 1]);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
let requestedPlatform = null;
|
|
475
|
+
const platformIdx = args.findIndex(a => a === '--platform' || a === '-p');
|
|
476
|
+
if (platformIdx !== -1 && args[platformIdx + 1]) {
|
|
477
|
+
requestedPlatform = args[platformIdx + 1].toLowerCase().trim();
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
console.log('\n============================================================');
|
|
481
|
+
console.log('⚡ Agent Master DevSecOps — Universal One-Line Bootstrap CLI');
|
|
482
|
+
console.log('============================================================\n');
|
|
483
|
+
|
|
484
|
+
if (detectOnly) {
|
|
485
|
+
const detected = detectEnvironments(targetDir, { platforms: requestedPlatform ? [requestedPlatform] : undefined });
|
|
486
|
+
console.log('🔍 Ambientes Detectados em:', targetDir);
|
|
487
|
+
console.log(JSON.stringify(detected, null, 2));
|
|
488
|
+
process.exit(0);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
let selectedPlatforms = requestedPlatform ? [requestedPlatform] : null;
|
|
492
|
+
|
|
493
|
+
// Se nenhuma plataforma foi passada via flag e o terminal é interativo (TTY), exibe menu de seleção
|
|
494
|
+
if (!selectedPlatforms && process.stdin.isTTY && !nonInteractive && !dryRun) {
|
|
495
|
+
const initialDetected = detectEnvironments(targetDir);
|
|
496
|
+
const hasExplicitProjectConfig = initialDetected.cursor || initialDetected.windsurf || initialDetected.vscode || initialDetected.claude_desktop;
|
|
497
|
+
|
|
498
|
+
if (!hasExplicitProjectConfig) {
|
|
499
|
+
const readline = require('node:readline/promises');
|
|
500
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
501
|
+
|
|
502
|
+
console.log('🛠️ Selecione a IDE / Plataforma para este projeto:');
|
|
503
|
+
console.log(' 1) Google Antigravity (Padrão)');
|
|
504
|
+
console.log(' 2) Cursor IDE (.cursorrules + .cursor/mcp.json)');
|
|
505
|
+
console.log(' 3) Windsurf IDE (.windsurfrules)');
|
|
506
|
+
console.log(' 4) VS Code (.vscode/mcp.json)');
|
|
507
|
+
console.log(' 5) Claude Desktop (claude_desktop_config.json)');
|
|
508
|
+
console.log(' 6) Universal (Configurar todas as plataformas)\n');
|
|
509
|
+
|
|
510
|
+
try {
|
|
511
|
+
const answer = await rl.question('👉 Escolha uma opção (1-6) [1]: ');
|
|
512
|
+
const choice = answer.trim();
|
|
513
|
+
switch (choice) {
|
|
514
|
+
case '2': selectedPlatforms = ['cursor']; break;
|
|
515
|
+
case '3': selectedPlatforms = ['windsurf']; break;
|
|
516
|
+
case '4': selectedPlatforms = ['vscode']; break;
|
|
517
|
+
case '5': selectedPlatforms = ['claude_desktop']; break;
|
|
518
|
+
case '6': selectedPlatforms = ['all']; break;
|
|
519
|
+
case '1':
|
|
520
|
+
case '':
|
|
521
|
+
default:
|
|
522
|
+
selectedPlatforms = ['antigravity']; break;
|
|
523
|
+
}
|
|
524
|
+
} catch (_) {
|
|
525
|
+
selectedPlatforms = ['antigravity'];
|
|
526
|
+
} finally {
|
|
527
|
+
rl.close();
|
|
528
|
+
}
|
|
529
|
+
console.log();
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
const bootOptions = { dryRun };
|
|
534
|
+
if (selectedPlatforms) {
|
|
535
|
+
bootOptions.platforms = selectedPlatforms;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
const result = bootstrapEnvironment(targetDir, bootOptions);
|
|
539
|
+
console.log(`✅ Bootstrapping concluído com sucesso em ${result.durationMs}ms!`);
|
|
540
|
+
console.log(`📂 Diretório Alvo: ${result.targetDir}`);
|
|
541
|
+
console.log(`🔍 Modo de Projeto (Regra 16): [${result.onboardingMode}] (${result.onboardingMode === 'BROWNFIELD' ? 'Projeto existente mapeado' : 'Projeto novo do zero'})`);
|
|
542
|
+
if (result.projectContext && result.projectContext.stack && result.projectContext.stack.length > 0) {
|
|
543
|
+
console.log(`🛠️ Stack Mapeada: ${result.projectContext.stack.join(', ')}`);
|
|
544
|
+
}
|
|
545
|
+
if (result.isSubmoduleMode) {
|
|
546
|
+
console.log(`✨ Modo Submódulo Limpo: Os arquivos canônicos residem em 'agent-master-devsecops/'. Nenhuma pasta duplicada criada na raiz!`);
|
|
547
|
+
} else {
|
|
548
|
+
console.log(`📄 Arquivos Canônicos Injetados: ${result.copiedFiles.length}`);
|
|
549
|
+
}
|
|
550
|
+
console.log(`🛠️ Plataformas Configuradas:`, result.configuredPlatforms.map(p => p.platform).join(', '));
|
|
551
|
+
console.log(`🔌 Servidor MCP Vinculado: ${result.mcpServerPath}`);
|
|
552
|
+
|
|
553
|
+
if (!result.credentials.allReady) {
|
|
554
|
+
console.log('\n------------------------------------------------------------');
|
|
555
|
+
console.log(result.credentials.promptGuidance);
|
|
556
|
+
console.log('------------------------------------------------------------\n');
|
|
557
|
+
|
|
558
|
+
if (process.stdin.isTTY && !nonInteractive) {
|
|
559
|
+
const readline = require('node:readline/promises');
|
|
560
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
561
|
+
try {
|
|
562
|
+
const ans = await rl.question('🔑 Deseja cadastrar as credenciais da Atlassian agora no .env? (s/n): ');
|
|
563
|
+
if (ans.trim().toLowerCase() === 's') {
|
|
564
|
+
const domain = await rl.question('Domínio Atlassian (ex: empresa.atlassian.net): ');
|
|
565
|
+
const email = await rl.question('Email da conta Atlassian: ');
|
|
566
|
+
const token = await rl.question('API Token Atlassian: ');
|
|
567
|
+
const jiraKey = await rl.question('Chave do Projeto no Jira (ex: AGDEV ou PROJ): ');
|
|
568
|
+
const confluenceSpace = await rl.question('Chave do Espaço no Confluence (ex: AGDEV ou DOCS): ');
|
|
569
|
+
const { configureCredentials } = require('../integrations/credentials_guard.js');
|
|
570
|
+
configureCredentials(targetDir, { domain, email, token, jiraKey, confluenceSpace });
|
|
571
|
+
console.log('\n✅ Credenciais salvas com sucesso em .env (protegido pelo .gitignore)!\n');
|
|
572
|
+
}
|
|
573
|
+
} catch (err) {
|
|
574
|
+
void err;
|
|
575
|
+
} finally {
|
|
576
|
+
rl.close();
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
} else {
|
|
580
|
+
console.log('🩺 Credenciais Atlassian & GitHub: 100% Autenticadas e Prontas!\n');
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
console.log('O Agent Master está pronto para uso na sua IDE e LLM!\n');
|
|
584
|
+
})();
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
module.exports = {
|
|
588
|
+
BootstrapCli,
|
|
589
|
+
detectEnvironments,
|
|
590
|
+
bootstrapEnvironment,
|
|
591
|
+
CANONICAL_FILES,
|
|
592
|
+
initProject,
|
|
593
|
+
validateModularStructure,
|
|
594
|
+
renderCanonicalPrompt,
|
|
595
|
+
formatReport,
|
|
596
|
+
commandExists
|
|
597
|
+
};
|