agent-master-devsecops 0.0.0-stage → 3.9.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/.cursorignore +23 -0
- package/README.md +371 -3
- package/agents/AGENT_DEVSECOPS.md +417 -0
- package/agents/AGENT_ORCHESTRATOR.md +264 -0
- package/agents/AGENT_QA.md +186 -0
- package/agents/AGENT_SCRUM.md +190 -0
- package/agents/AGENT_SRE.md +173 -0
- package/agents/AGENT_UIUX.md +162 -0
- package/agents/compact/AGENT_ORCHESTRATOR_COMPACTO.md +53 -0
- package/docs/ARCHITECTURE.md +148 -0
- package/docs/CALCULATIONS.md +17 -0
- package/docs/CHANGELOG.md +49 -0
- package/docs/ENGINEERING_RULES.md +252 -0
- package/docs/IDEAS.md +17 -0
- package/docs/STATE.md +43 -0
- package/docs/playbooks/PLAYBOOK_CIRCUIT_BREAKER_LLM.md +58 -0
- package/docs/playbooks/PLAYBOOK_OPENTELEMETRY_TRACING.md +58 -0
- package/package.json +47 -6
- package/scripts/a11y_auditor.js +187 -0
- package/scripts/ast_skeletonizer.js +220 -0
- package/scripts/atlassian_client.js +238 -0
- package/scripts/atlassian_sync_action.js +269 -0
- package/scripts/bootstrap_cli.js +468 -0
- package/scripts/circuit_breaker.js +330 -0
- package/scripts/code_quality_auditor.js +142 -0
- package/scripts/confluence_sync.js +337 -0
- package/scripts/context_compressor.js +139 -0
- package/scripts/contract_test_validator.js +166 -0
- package/scripts/credentials_guard.js +216 -0
- package/scripts/domain_idea_miner.js +364 -0
- package/scripts/eval_harness.js +100 -0
- package/scripts/fast_feature_scaffold.js +338 -0
- package/scripts/git_hygiene_linter.js +186 -0
- package/scripts/hot_state_cache.js +95 -0
- package/scripts/jira_manager.js +408 -0
- package/scripts/magic_prompt_generator.js +205 -0
- package/scripts/mcp_server.js +1884 -0
- package/scripts/multi_agent_orchestrator.js +258 -0
- package/scripts/otel_tracer.js +228 -0
- package/scripts/perf_benchmark.js +153 -0
- package/scripts/pr_reviewer.js +373 -0
- package/scripts/sast_scanner.js +180 -0
- package/scripts/sca_dependency_auditor.js +167 -0
- package/scripts/smart_onboarding.js +610 -0
- package/scripts/sre_remediation_engine.js +174 -0
- package/scripts/universal_packager.js +313 -0
- package/scripts/web_inspector.js +355 -0
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* scripts/bootstrap_cli.js
|
|
4
|
+
*
|
|
5
|
+
* Universal One-Line Bootstrap CLI (AGDEV-26 / I-12).
|
|
6
|
+
* Auto-detecta IDEs instaladas (Cursor, Windsurf, VS Code, Claude Desktop, Ollama)
|
|
7
|
+
* e provisiona o Agent Master DevSecOps e servidor MCP com zero configuração em < 2 segundos.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('node:fs');
|
|
11
|
+
const path = require('node:path');
|
|
12
|
+
const { execSync, execFileSync } = require('node:child_process');
|
|
13
|
+
const { UniversalPackager } = require('./universal_packager.js');
|
|
14
|
+
const { runCredentialHealthcheck } = require('./credentials_guard.js');
|
|
15
|
+
const { detectProjectMode, inspectProjectContext } = require('./smart_onboarding.js');
|
|
16
|
+
|
|
17
|
+
const CANONICAL_FILES = [
|
|
18
|
+
'agents/AGENT_ORCHESTRATOR.md',
|
|
19
|
+
'agents/AGENT_UIUX.md',
|
|
20
|
+
'agents/AGENT_DEVSECOPS.md',
|
|
21
|
+
'agents/AGENT_SCRUM.md',
|
|
22
|
+
'agents/AGENT_SRE.md',
|
|
23
|
+
'agents/AGENT_QA.md',
|
|
24
|
+
'docs/ENGINEERING_RULES.md',
|
|
25
|
+
'docs/ARCHITECTURE.md',
|
|
26
|
+
'docs/IDEAS.md'
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
function commandExists(cmd) {
|
|
30
|
+
try {
|
|
31
|
+
const isWindows = process.platform === 'win32';
|
|
32
|
+
const testCmd = isWindows ? `where ${cmd}` : `which ${cmd}`;
|
|
33
|
+
execSync(testCmd, { stdio: 'ignore' });
|
|
34
|
+
return true;
|
|
35
|
+
} catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function detectEnvironments(targetDir = process.cwd(), options = {}) {
|
|
41
|
+
const detected = {
|
|
42
|
+
cursor: false,
|
|
43
|
+
windsurf: false,
|
|
44
|
+
vscode: false,
|
|
45
|
+
claude_desktop: false,
|
|
46
|
+
ollama: false,
|
|
47
|
+
antigravity: false,
|
|
48
|
+
generic: true
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const isWindows = process.platform === 'win32';
|
|
52
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '';
|
|
53
|
+
const appData = process.env.APPDATA || '';
|
|
54
|
+
|
|
55
|
+
// 0. Se plataformas foram especificadas expressamente (options.platforms), honrar estritamente
|
|
56
|
+
if (options.platforms && options.platforms.length > 0) {
|
|
57
|
+
for (const p of options.platforms) {
|
|
58
|
+
const clean = String(p).toLowerCase().trim();
|
|
59
|
+
if (clean === 'all' || clean === 'universal') {
|
|
60
|
+
detected.cursor = true;
|
|
61
|
+
detected.windsurf = true;
|
|
62
|
+
detected.vscode = true;
|
|
63
|
+
detected.claude_desktop = true;
|
|
64
|
+
detected.antigravity = true;
|
|
65
|
+
} else if (clean === 'vscode' || clean === 'code') {
|
|
66
|
+
detected.vscode = true;
|
|
67
|
+
} else if (clean === 'antigravity' || clean === 'gemini') {
|
|
68
|
+
detected.antigravity = true;
|
|
69
|
+
} else if (clean === 'cursor') {
|
|
70
|
+
detected.cursor = true;
|
|
71
|
+
} else if (clean === 'windsurf') {
|
|
72
|
+
detected.windsurf = true;
|
|
73
|
+
} else if (clean === 'claude_desktop' || clean === 'claude') {
|
|
74
|
+
detected.claude_desktop = true;
|
|
75
|
+
} else if (clean === 'ollama') {
|
|
76
|
+
detected.ollama = true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return detected;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 1. Detectar Antigravity no targetDir ou processo ativo
|
|
83
|
+
const isRunningInAntigravity = Boolean(process.env.ANTIGRAVITY_AGENT || process.env.ANTIGRAVITY_APP_DATA_DIR);
|
|
84
|
+
if (
|
|
85
|
+
isRunningInAntigravity ||
|
|
86
|
+
fs.existsSync(path.join(targetDir, '.antigravity')) ||
|
|
87
|
+
fs.existsSync(path.join(targetDir, '.gemini'))
|
|
88
|
+
) {
|
|
89
|
+
detected.antigravity = true;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 2. Detectar Cursor no targetDir
|
|
93
|
+
if (
|
|
94
|
+
fs.existsSync(path.join(targetDir, '.cursor')) ||
|
|
95
|
+
fs.existsSync(path.join(targetDir, '.cursorrules'))
|
|
96
|
+
) {
|
|
97
|
+
detected.cursor = true;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 3. Detectar Windsurf no targetDir
|
|
101
|
+
if (
|
|
102
|
+
fs.existsSync(path.join(targetDir, '.windsurf')) ||
|
|
103
|
+
fs.existsSync(path.join(targetDir, '.windsurfrules'))
|
|
104
|
+
) {
|
|
105
|
+
detected.windsurf = true;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 4. Detectar VS Code SOMENTE se houver diretório .vscode existente no targetDir
|
|
109
|
+
// Evita poluir o projeto com .vscode/ apenas por ter a IDE instalada no sistema operacional
|
|
110
|
+
if (fs.existsSync(path.join(targetDir, '.vscode'))) {
|
|
111
|
+
detected.vscode = true;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 5. Detectar Claude Desktop no targetDir
|
|
115
|
+
if (
|
|
116
|
+
fs.existsSync(path.join(targetDir, '.claude')) ||
|
|
117
|
+
fs.existsSync(path.join(targetDir, 'claude_desktop_config.json'))
|
|
118
|
+
) {
|
|
119
|
+
detected.claude_desktop = true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// 6. Detectar Ollama no targetDir
|
|
123
|
+
if (fs.existsSync(path.join(targetDir, 'Modelfile'))) {
|
|
124
|
+
detected.ollama = true;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Se nenhum arquivo de IDE foi encontrado no diretório do projeto:
|
|
128
|
+
const hasProjectLevelIde = detected.antigravity || detected.cursor || detected.windsurf || detected.vscode || detected.claude_desktop || detected.ollama;
|
|
129
|
+
if (!hasProjectLevelIde) {
|
|
130
|
+
// Se há Antigravity no ambiente do usuário, assume Antigravity por padrão
|
|
131
|
+
if (
|
|
132
|
+
(homeDir && fs.existsSync(path.join(homeDir, '.gemini', 'antigravity'))) ||
|
|
133
|
+
commandExists('antigravity') ||
|
|
134
|
+
commandExists('agy')
|
|
135
|
+
) {
|
|
136
|
+
detected.antigravity = true;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return detected;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function bootstrapEnvironment(targetDir = process.cwd(), options = {}) {
|
|
144
|
+
const startTime = Date.now();
|
|
145
|
+
const rootSource = path.resolve(__dirname, '..');
|
|
146
|
+
const dryRun = Boolean(options.dryRun);
|
|
147
|
+
|
|
148
|
+
// 1. Auto-detectar ambientes
|
|
149
|
+
const detected = options.platforms
|
|
150
|
+
? detectEnvironments(targetDir, { platforms: options.platforms })
|
|
151
|
+
: detectEnvironments(targetDir, options);
|
|
152
|
+
|
|
153
|
+
const activePlatforms = Object.keys(detected).filter(k => detected[k]);
|
|
154
|
+
const credentialHealth = runCredentialHealthcheck(targetDir);
|
|
155
|
+
const projectMode = detectProjectMode(targetDir);
|
|
156
|
+
const projectContext = inspectProjectContext(targetDir);
|
|
157
|
+
|
|
158
|
+
const results = {
|
|
159
|
+
onboardingMode: projectMode.mode,
|
|
160
|
+
projectContext,
|
|
161
|
+
status: 'SUCCESS',
|
|
162
|
+
targetDir,
|
|
163
|
+
dryRun,
|
|
164
|
+
detectedEnvironments: detected,
|
|
165
|
+
activePlatforms,
|
|
166
|
+
credentials: {
|
|
167
|
+
allReady: credentialHealth.allReady,
|
|
168
|
+
github: credentialHealth.github,
|
|
169
|
+
atlassian: credentialHealth.atlassian,
|
|
170
|
+
missing: credentialHealth.missing,
|
|
171
|
+
promptGuidance: credentialHealth.promptGuidance
|
|
172
|
+
},
|
|
173
|
+
copiedFiles: [],
|
|
174
|
+
configuredPlatforms: [],
|
|
175
|
+
mcpServerPath: path.resolve(rootSource, 'scripts', 'mcp_server.js'),
|
|
176
|
+
durationMs: 0
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// 2. Provisionar arquivos canônicos do agente no targetDir (Modo Limpo de Submódulo)
|
|
180
|
+
const isSubmoduleMode = Boolean(
|
|
181
|
+
!options.forceCopy &&
|
|
182
|
+
(
|
|
183
|
+
path.resolve(targetDir, 'agent-master-devsecops') === rootSource ||
|
|
184
|
+
(fs.existsSync(path.join(targetDir, '.gitmodules')) && fs.existsSync(path.join(targetDir, 'agent-master-devsecops')))
|
|
185
|
+
)
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
results.isSubmoduleMode = isSubmoduleMode;
|
|
189
|
+
|
|
190
|
+
if (!isSubmoduleMode) {
|
|
191
|
+
const agentDir = path.join(targetDir, 'agents');
|
|
192
|
+
const docDir = path.join(targetDir, 'docs');
|
|
193
|
+
|
|
194
|
+
if (!dryRun) {
|
|
195
|
+
if (!fs.existsSync(agentDir)) fs.mkdirSync(agentDir, { recursive: true });
|
|
196
|
+
if (!fs.existsSync(docDir)) fs.mkdirSync(docDir, { recursive: true });
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
for (const relFile of CANONICAL_FILES) {
|
|
200
|
+
const src = path.join(rootSource, relFile);
|
|
201
|
+
const actualSrc = src;
|
|
202
|
+
const dest = path.join(targetDir, relFile);
|
|
203
|
+
|
|
204
|
+
if (fs.existsSync(actualSrc)) {
|
|
205
|
+
if (!dryRun) {
|
|
206
|
+
const destParent = path.dirname(dest);
|
|
207
|
+
if (!fs.existsSync(destParent)) fs.mkdirSync(destParent, { recursive: true });
|
|
208
|
+
fs.copyFileSync(actualSrc, dest);
|
|
209
|
+
}
|
|
210
|
+
results.copiedFiles.push(relFile);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
} else {
|
|
214
|
+
results.submoduleNotice = 'Submódulo detectado. Cópia redundante de agents/ e docs/ na raiz suprimida com sucesso (Modo Limpo - Regra 16).';
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// 3. Gerar configurações das plataformas detectadas
|
|
218
|
+
const packager = new UniversalPackager(rootSource);
|
|
219
|
+
|
|
220
|
+
if (detected.cursor) {
|
|
221
|
+
const res = packager.generateCursorProfile(targetDir, { dryRun, mcpServerPath: results.mcpServerPath });
|
|
222
|
+
results.configuredPlatforms.push({ platform: 'cursor', files: res.filesCount });
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (detected.windsurf) {
|
|
226
|
+
const res = packager.generateWindsurfProfile(targetDir, { dryRun });
|
|
227
|
+
results.configuredPlatforms.push({ platform: 'windsurf', files: res.filesCount });
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (detected.vscode) {
|
|
231
|
+
const res = packager.generateVsCodeProfile(targetDir, { dryRun, mcpServerPath: results.mcpServerPath });
|
|
232
|
+
results.configuredPlatforms.push({ platform: 'vscode', files: res.filesCount });
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (detected.claude_desktop) {
|
|
236
|
+
const res = packager.generateClaudeDesktopConfig(targetDir, { dryRun, mcpServerPath: results.mcpServerPath });
|
|
237
|
+
results.configuredPlatforms.push({ platform: 'claude_desktop', files: res.filesCount });
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (detected.antigravity) {
|
|
241
|
+
const res = packager.generateAntigravityConfig(targetDir, { dryRun, mcpServerPath: results.mcpServerPath });
|
|
242
|
+
results.configuredPlatforms.push({ platform: 'antigravity', files: res.filesCount });
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (detected.ollama) {
|
|
246
|
+
const res = packager.generateOllamaModelfile(targetDir, { dryRun });
|
|
247
|
+
results.configuredPlatforms.push({ platform: 'ollama', files: res.filesCount });
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Se nenhuma IDE especializada foi detectada, gera o bundle universal genérico
|
|
251
|
+
if (results.configuredPlatforms.length === 0) {
|
|
252
|
+
const res = packager.generateCursorProfile(targetDir, { dryRun, mcpServerPath: results.mcpServerPath });
|
|
253
|
+
results.configuredPlatforms.push({ platform: 'universal_fallback_cursor', files: res.filesCount });
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
results.durationMs = Date.now() - startTime;
|
|
257
|
+
return results;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (require.main === module) {
|
|
261
|
+
(async () => {
|
|
262
|
+
const args = process.argv.slice(2);
|
|
263
|
+
const dryRun = args.includes('--dryRun') || args.includes('-d');
|
|
264
|
+
const detectOnly = args.includes('--detectOnly');
|
|
265
|
+
const nonInteractive = args.includes('--non-interactive') || args.includes('--yes') || args.includes('-y');
|
|
266
|
+
let targetDir = process.cwd();
|
|
267
|
+
|
|
268
|
+
const targetIdx = args.findIndex(a => a === '--targetDir' || a === '-t');
|
|
269
|
+
if (targetIdx !== -1 && args[targetIdx + 1]) {
|
|
270
|
+
targetDir = path.resolve(args[targetIdx + 1]);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
let requestedPlatform = null;
|
|
274
|
+
const platformIdx = args.findIndex(a => a === '--platform' || a === '-p');
|
|
275
|
+
if (platformIdx !== -1 && args[platformIdx + 1]) {
|
|
276
|
+
requestedPlatform = args[platformIdx + 1].toLowerCase().trim();
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
console.log('\n============================================================');
|
|
280
|
+
console.log('⚡ Agent Master DevSecOps — Universal One-Line Bootstrap CLI');
|
|
281
|
+
console.log('============================================================\n');
|
|
282
|
+
|
|
283
|
+
// Auto-diagnóstico de integridade do executável (Prevenção de links órfãos)
|
|
284
|
+
try {
|
|
285
|
+
if (!fs.existsSync(__filename)) {
|
|
286
|
+
console.warn('⚠️ AVISO: Executável rodando a partir de um link simbólico quebrado ou desatualizado.\n');
|
|
287
|
+
}
|
|
288
|
+
} catch (_) {}
|
|
289
|
+
|
|
290
|
+
if (detectOnly) {
|
|
291
|
+
const detected = detectEnvironments(targetDir, { platforms: requestedPlatform ? [requestedPlatform] : undefined });
|
|
292
|
+
console.log('🔍 Ambientes Detectados em:', targetDir);
|
|
293
|
+
console.log(JSON.stringify(detected, null, 2));
|
|
294
|
+
process.exit(0);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
let selectedPlatforms = requestedPlatform ? [requestedPlatform] : null;
|
|
298
|
+
|
|
299
|
+
// Se nenhuma plataforma foi passada via flag e o terminal é interativo (TTY), exibe menu de seleção
|
|
300
|
+
if (!selectedPlatforms && process.stdin.isTTY && !nonInteractive && !dryRun) {
|
|
301
|
+
const initialDetected = detectEnvironments(targetDir);
|
|
302
|
+
const hasExplicitProjectConfig = initialDetected.cursor || initialDetected.windsurf || initialDetected.vscode || initialDetected.claude_desktop;
|
|
303
|
+
|
|
304
|
+
if (!hasExplicitProjectConfig) {
|
|
305
|
+
const readline = require('node:readline/promises');
|
|
306
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
307
|
+
|
|
308
|
+
console.log('🛠️ Selecione a IDE / Plataforma para este projeto:');
|
|
309
|
+
console.log(' 1) Google Antigravity (Padrão)');
|
|
310
|
+
console.log(' 2) Cursor IDE (.cursorrules + .cursor/mcp.json)');
|
|
311
|
+
console.log(' 3) Windsurf IDE (.windsurfrules)');
|
|
312
|
+
console.log(' 4) VS Code (.vscode/mcp.json)');
|
|
313
|
+
console.log(' 5) Claude Desktop (claude_desktop_config.json)');
|
|
314
|
+
console.log(' 6) Universal (Configurar todas as plataformas)\n');
|
|
315
|
+
|
|
316
|
+
try {
|
|
317
|
+
const answer = await rl.question('👉 Escolha uma opção (1-6) [1]: ');
|
|
318
|
+
const choice = answer.trim();
|
|
319
|
+
switch (choice) {
|
|
320
|
+
case '2': selectedPlatforms = ['cursor']; break;
|
|
321
|
+
case '3': selectedPlatforms = ['windsurf']; break;
|
|
322
|
+
case '4': selectedPlatforms = ['vscode']; break;
|
|
323
|
+
case '5': selectedPlatforms = ['claude_desktop']; break;
|
|
324
|
+
case '6': selectedPlatforms = ['all']; break;
|
|
325
|
+
case '1':
|
|
326
|
+
case '':
|
|
327
|
+
default:
|
|
328
|
+
selectedPlatforms = ['antigravity']; break;
|
|
329
|
+
}
|
|
330
|
+
} catch (_) {
|
|
331
|
+
selectedPlatforms = ['antigravity'];
|
|
332
|
+
} finally {
|
|
333
|
+
rl.close();
|
|
334
|
+
}
|
|
335
|
+
console.log();
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const bootOptions = { dryRun };
|
|
340
|
+
if (selectedPlatforms) {
|
|
341
|
+
bootOptions.platforms = selectedPlatforms;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const result = bootstrapEnvironment(targetDir, bootOptions);
|
|
345
|
+
console.log(`✅ Bootstrapping concluído com sucesso em ${result.durationMs}ms!`);
|
|
346
|
+
console.log(`📂 Diretório Alvo: ${result.targetDir}`);
|
|
347
|
+
console.log(`🔍 Modo de Projeto (Regra 16): [${result.onboardingMode}] (${result.onboardingMode === 'BROWNFIELD' ? 'Projeto existente mapeado' : 'Projeto novo do zero'})`);
|
|
348
|
+
if (result.projectContext && result.projectContext.stack && result.projectContext.stack.length > 0) {
|
|
349
|
+
console.log(`🛠️ Stack Mapeada: ${result.projectContext.stack.join(', ')}`);
|
|
350
|
+
}
|
|
351
|
+
if (result.isSubmoduleMode) {
|
|
352
|
+
console.log(`✨ Modo Submódulo Limpo: Os arquivos canônicos residem em 'agent-master-devsecops/'. Nenhuma pasta duplicada criada na raiz!`);
|
|
353
|
+
} else {
|
|
354
|
+
console.log(`📄 Arquivos Canônicos Injetados: ${result.copiedFiles.length}`);
|
|
355
|
+
}
|
|
356
|
+
console.log(`🛠️ Plataformas Configuradas:`, result.configuredPlatforms.map(p => p.platform).join(', '));
|
|
357
|
+
console.log(`🔌 Servidor MCP Vinculado: ${result.mcpServerPath}`);
|
|
358
|
+
|
|
359
|
+
if (!result.credentials.allReady) {
|
|
360
|
+
console.log('\n------------------------------------------------------------');
|
|
361
|
+
console.log(result.credentials.promptGuidance);
|
|
362
|
+
console.log('------------------------------------------------------------\n');
|
|
363
|
+
|
|
364
|
+
if (process.stdin.isTTY && !nonInteractive) {
|
|
365
|
+
const readline = require('node:readline/promises');
|
|
366
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
367
|
+
try {
|
|
368
|
+
const ans = await rl.question('🔑 Deseja cadastrar as credenciais da Atlassian agora no .env? (s/n): ');
|
|
369
|
+
if (ans.trim().toLowerCase() === 's') {
|
|
370
|
+
const domain = await rl.question('Domínio Atlassian (ex: empresa.atlassian.net): ');
|
|
371
|
+
const email = await rl.question('Email da conta Atlassian: ');
|
|
372
|
+
const token = await rl.question('API Token Atlassian: ');
|
|
373
|
+
const jiraKey = await rl.question('Chave do Projeto no Jira (ex: AGDEV ou PROJ): ');
|
|
374
|
+
const confluenceSpace = await rl.question('Chave do Espaço no Confluence (ex: AGDEV ou DOCS): ');
|
|
375
|
+
const { configureCredentials } = require('./credentials_guard.js');
|
|
376
|
+
configureCredentials(targetDir, { domain, email, token, jiraKey, confluenceSpace });
|
|
377
|
+
console.log('\n✅ Credenciais salvas com sucesso em .env (protegido pelo .gitignore)!\n');
|
|
378
|
+
}
|
|
379
|
+
} catch (_) {}
|
|
380
|
+
finally {
|
|
381
|
+
rl.close();
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
} else {
|
|
385
|
+
console.log('🩺 Credenciais Atlassian & GitHub: 100% Autenticadas e Prontas!\n');
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
console.log('O Agent Master está pronto para uso na sua IDE e LLM!\n');
|
|
389
|
+
})();
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Validação de integridade estrutural modular
|
|
394
|
+
*/
|
|
395
|
+
function validateModularStructure(baseDir) {
|
|
396
|
+
const missing = [];
|
|
397
|
+
const present = [];
|
|
398
|
+
|
|
399
|
+
for (const relPath of CANONICAL_FILES) {
|
|
400
|
+
const fullPath = path.join(baseDir, relPath);
|
|
401
|
+
if (fs.existsSync(fullPath)) {
|
|
402
|
+
present.push(relPath);
|
|
403
|
+
} else {
|
|
404
|
+
missing.push(relPath);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return {
|
|
409
|
+
valid: missing.length === 0,
|
|
410
|
+
total: CANONICAL_FILES.length,
|
|
411
|
+
present,
|
|
412
|
+
missing
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Função de inicialização universal com contrato do init_cli
|
|
418
|
+
*/
|
|
419
|
+
function initProject(targetDir = process.cwd(), options = {}) {
|
|
420
|
+
const res = bootstrapEnvironment(targetDir, options);
|
|
421
|
+
res.rulesConfigured = res.copiedFiles.length > 0 || Boolean(options.dryRun) || Boolean(res.isSubmoduleMode);
|
|
422
|
+
res.mcpConfigured = true;
|
|
423
|
+
return res;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Renderiza o prompt canônico customizado com metadados do projeto.
|
|
428
|
+
*/
|
|
429
|
+
function renderCanonicalPrompt(meta = {}) {
|
|
430
|
+
const projectName = meta.projectName || 'Enterprise Software System';
|
|
431
|
+
const techStack = meta.techStack || 'Polyglot / Universal Multi-Stack';
|
|
432
|
+
const ticketSystem = meta.ticketSystem || 'Jira Cloud / GitHub Issues';
|
|
433
|
+
|
|
434
|
+
return `Você é o AGENT ORCHESTRATOR DE ENGENHARIA DE SOFTWARE, ARQUITETURA, DEVSECOPS E GOVERNANÇA do projeto "${projectName}".
|
|
435
|
+
Stack Tecnológica: ${techStack}
|
|
436
|
+
Sistema de Governança & Rastreabilidade: ${ticketSystem}
|
|
437
|
+
|
|
438
|
+
Você opera sob a estrutura modular soberana das pastas /agents e /docs com contratos de engenharia catalogados:
|
|
439
|
+
- agents/AGENT_ORCHESTRATOR.md (Orquestrador multi-persona)
|
|
440
|
+
- agents/AGENT_UIUX.md (Product Designer, UX/UI, Heurísticas & WCAG 2.1 AA)
|
|
441
|
+
- agents/AGENT_DEVSECOPS.md (Staff Engineer & DevSecOps Lead)
|
|
442
|
+
- agents/AGENT_QA.md (Auditor adversário independente)
|
|
443
|
+
- agents/AGENT_SCRUM.md (Gestão ágil, melhoria contínua e PDCA)
|
|
444
|
+
- agents/AGENT_SRE.md (SRE Lead, observabilidade e telemetria)
|
|
445
|
+
- docs/ENGINEERING_RULES.md (14 Regras Fundamentais de Engenharia)
|
|
446
|
+
- README.md (Manual mestre, catálogo e MCP)
|
|
447
|
+
- docs/ARCHITECTURE.md (Topologia cooperativa e matriz de handovers)
|
|
448
|
+
|
|
449
|
+
Modos de Operação Disponíveis:
|
|
450
|
+
- modo: orchestrator
|
|
451
|
+
- modo: uiux
|
|
452
|
+
- modo: devsecops
|
|
453
|
+
- modo: qa
|
|
454
|
+
- modo: scrum
|
|
455
|
+
- modo: sre
|
|
456
|
+
- modo: full-dev (loop ininterrupto de implementação autônoma)
|
|
457
|
+
|
|
458
|
+
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.`;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
module.exports = {
|
|
462
|
+
detectEnvironments,
|
|
463
|
+
bootstrapEnvironment,
|
|
464
|
+
CANONICAL_FILES,
|
|
465
|
+
initProject,
|
|
466
|
+
validateModularStructure,
|
|
467
|
+
renderCanonicalPrompt
|
|
468
|
+
};
|