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.
Files changed (61) hide show
  1. package/README.md +204 -2
  2. package/agents/AGENT_DEVSECOPS.md +32 -0
  3. package/agents/AGENT_INFRA.md +31 -0
  4. package/agents/AGENT_ORCHESTRATOR.md +39 -0
  5. package/agents/AGENT_QA.md +58 -0
  6. package/agents/AGENT_SCRUM.md +23 -0
  7. package/agents/AGENT_SRE.md +22 -0
  8. package/agents/AGENT_UIUX.md +26 -0
  9. package/docs/ARCHITECTURE.md +152 -0
  10. package/docs/CALCULATIONS.md +17 -0
  11. package/docs/CHANGELOG.md +112 -0
  12. package/docs/ENGINEERING_RULES.md +56 -0
  13. package/docs/IDEAS.md +17 -0
  14. package/docs/LOCAL_BACKLOG.md +20 -0
  15. package/docs/STATE.md +111 -0
  16. package/docs/playbooks/PLAYBOOK_CIRCUIT_BREAKER_LLM.md +58 -0
  17. package/docs/playbooks/PLAYBOOK_OPENTELEMETRY_TRACING.md +58 -0
  18. package/package.json +57 -4
  19. package/scripts/auditors/a11y_auditor.js +462 -0
  20. package/scripts/auditors/code_quality_auditor.js +444 -0
  21. package/scripts/auditors/contract_test_validator.js +396 -0
  22. package/scripts/auditors/eval_harness.js +213 -0
  23. package/scripts/auditors/git_hygiene_linter.js +391 -0
  24. package/scripts/auditors/pr_reviewer.js +627 -0
  25. package/scripts/auditors/sast_scanner.js +442 -0
  26. package/scripts/auditors/sca_dependency_auditor.js +673 -0
  27. package/scripts/bin/bootstrap_cli.js +597 -0
  28. package/scripts/bin/domain_idea_miner.js +658 -0
  29. package/scripts/bin/smart_onboarding.js +905 -0
  30. package/scripts/bin/web_inspector.js +578 -0
  31. package/scripts/core/architecture_advisor.js +378 -0
  32. package/scripts/core/ast_skeletonizer.js +413 -0
  33. package/scripts/core/autonomous_remediation_engine.js +305 -0
  34. package/scripts/core/circuit_breaker.js +546 -0
  35. package/scripts/core/context_compressor.js +237 -0
  36. package/scripts/core/fast_feature_scaffold.js +840 -0
  37. package/scripts/core/hot_state_cache.js +238 -0
  38. package/scripts/core/knowledge_gateway.js +888 -0
  39. package/scripts/core/magic_prompt_generator.js +250 -0
  40. package/scripts/core/multi_agent_orchestrator.js +421 -0
  41. package/scripts/core/otel_tracer.js +335 -0
  42. package/scripts/core/perf_benchmark.js +212 -0
  43. package/scripts/core/sarif_engine.js +299 -0
  44. package/scripts/core/sre_remediation_engine.js +236 -0
  45. package/scripts/core/universal_packager.js +357 -0
  46. package/scripts/integrations/atlassian_client.js +600 -0
  47. package/scripts/integrations/atlassian_sync_action.js +576 -0
  48. package/scripts/integrations/confluence_sync.js +684 -0
  49. package/scripts/integrations/credentials_guard.js +500 -0
  50. package/scripts/integrations/jira_manager.js +722 -0
  51. package/scripts/mcp/handlers/atlassian_handlers.js +300 -0
  52. package/scripts/mcp/handlers/core_handlers.js +419 -0
  53. package/scripts/mcp/handlers/qa_handlers.js +502 -0
  54. package/scripts/mcp/handlers/rules_handlers.js +379 -0
  55. package/scripts/mcp/handlers/scaffold_handlers.js +334 -0
  56. package/scripts/mcp/handlers/sre_handlers.js +443 -0
  57. package/scripts/mcp/resources_registry.js +453 -0
  58. package/scripts/mcp/server.js +408 -0
  59. package/scripts/mcp/tool_handlers.js +444 -0
  60. package/scripts/mcp/tools_registry.js +1123 -0
  61. package/scripts/mcp_server.js +236 -0
@@ -0,0 +1,500 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * scripts/integrations/credentials_guard.js
4
+ *
5
+ * Guardião Canônico Unificado de Credenciais, Healthcheck e Imutabilidade de Requisitos (Regras 15 e 17).
6
+ * Consolida o Healthcheck interativo de credenciais Atlassian/GitHub e a validação inviolável da Regra 15.
7
+ * Garante obtenção ativa, pré-validação compulsória, mascaramento de segredos e zero falhas silenciosas em todos os vetores.
8
+ *
9
+ * Versão: 5.1.0 Enterprise
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ const fs = require('node:fs');
15
+ const path = require('node:path');
16
+
17
+ const {
18
+ getAtlassianCredentials,
19
+ checkGithubAuth,
20
+ getGitRepositoryUrl,
21
+ getGitMetadata,
22
+ AtlassianClient,
23
+ auditToSarif: auditAtlassianToSarifBase
24
+ } = require('./atlassian_client.js');
25
+
26
+ const { createSarifReport } = require('../core/sarif_engine.js');
27
+
28
+ class InviolableRuleError extends Error {
29
+ constructor(message, missingRequirements = [], remediationSteps = []) {
30
+ super(message);
31
+ this.name = 'InviolableRuleError';
32
+ this.rule = 'Regra 15 - Imutabilidade de Requisitos & Validação Compulsória de Segredos';
33
+ this.missingRequirements = missingRequirements;
34
+ this.remediationSteps = remediationSteps;
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Utilitário puro de mascaramento defensivo de segredos (evita CWE-798 / CWE-200 em logs e relatórios).
40
+ * @param {string} secret
41
+ * @param {number} [visibleChars=4]
42
+ * @returns {string}
43
+ */
44
+ function maskSecret(secret, visibleChars = 4) {
45
+ if (!secret || typeof secret !== 'string') return '';
46
+ if (secret.length <= visibleChars) return '****';
47
+ const visible = secret.slice(-visibleChars);
48
+ return `${'*'.repeat(Math.min(12, secret.length - visibleChars))}${visible}`;
49
+ }
50
+
51
+ /**
52
+ * Helpers funcionais puros para merge seguro de .env
53
+ */
54
+ function parseEnvLines(content) {
55
+ if (!content || typeof content !== 'string') return [];
56
+ return content.split(/\r?\n/);
57
+ }
58
+
59
+ function mergeEnvUpdates(existingContent, updates = {}) {
60
+ const lines = parseEnvLines(existingContent);
61
+ const updatedKeys = new Set();
62
+ const validUpdates = Object.entries(updates).filter(([_, val]) => val !== undefined && val !== null && val !== '');
63
+
64
+ const newLines = lines.map(line => {
65
+ const trimmed = line.trim();
66
+ if (!trimmed || trimmed.startsWith('#')) return line;
67
+ for (const [key, val] of validUpdates) {
68
+ if (trimmed.startsWith(`${key}=`)) {
69
+ updatedKeys.add(key);
70
+ return `${key}=${val}`;
71
+ }
72
+ }
73
+ return line;
74
+ });
75
+
76
+ for (const [key, val] of validUpdates) {
77
+ if (!updatedKeys.has(key)) {
78
+ newLines.push(`${key}=${val}`);
79
+ }
80
+ }
81
+
82
+ return newLines.filter(line => line !== undefined && line !== null).join('\n').trim() + '\n';
83
+ }
84
+
85
+ function ensureGitignoreProtected(existingContent, entries = ['.env', '.env.local']) {
86
+ const content = typeof existingContent === 'string' ? existingContent : '';
87
+ const lines = content.split(/\r?\n/).map(l => l.trim());
88
+ const missingEntries = entries.filter(entry => !lines.includes(entry));
89
+
90
+ if (missingEntries.length === 0) {
91
+ return { modified: false, content };
92
+ }
93
+
94
+ let updatedContent = content.trimEnd();
95
+ if (updatedContent.length > 0) updatedContent += '\n';
96
+ updatedContent += '\n# Segurança - Credenciais e Segredos (Regra 15)\n';
97
+ updatedContent += missingEntries.join('\n') + '\n';
98
+
99
+ return { modified: true, content: updatedContent };
100
+ }
101
+
102
+ /**
103
+ * Validação rigorosa da Regra 15 com suporte a Fail-Fast.
104
+ */
105
+ function validateRule15({ failFast = true, requireGitHub = true, requireAtlassian = true } = {}) {
106
+ const missing = [];
107
+ const remediation = [];
108
+
109
+ const atlassian = getAtlassianCredentials();
110
+ if (requireAtlassian && !atlassian.isConfigured) {
111
+ if (!atlassian.token) missing.push('ATLASSIAN_API_TOKEN');
112
+ if (!atlassian.email) missing.push('ATLASSIAN_EMAIL');
113
+ if (!atlassian.domain) missing.push('ATLASSIAN_DOMAIN');
114
+
115
+ remediation.push(
116
+ 'Configurar variáveis de ambiente ou secrets no GitHub Actions: gh secret set ATLASSIAN_API_TOKEN / ATLASSIAN_EMAIL / ATLASSIAN_DOMAIN'
117
+ );
118
+ }
119
+
120
+ const github = checkGithubAuth();
121
+ if (requireGitHub && !github.isAuthenticated) {
122
+ missing.push('GITHUB_AUTH (gh CLI ou GITHUB_TOKEN)');
123
+ remediation.push('Autenticar GitHub CLI via "gh auth login" ou exportar GITHUB_TOKEN');
124
+ }
125
+
126
+ const isValid = missing.length === 0;
127
+
128
+ if (!isValid && failFast) {
129
+ const msg = `[REGRA 15 INVIOLÁVEL: PRÉ-REQUISITOS NÃO ATENDIDOS]\n` +
130
+ `Faltam credenciais/ferramentas obrigatórias: ${missing.join(', ')}\n` +
131
+ `Remediação: ${remediation.join(' | ')}`;
132
+ throw new InviolableRuleError(msg, missing, remediation);
133
+ }
134
+
135
+ return {
136
+ valid: isValid,
137
+ missing,
138
+ remediation,
139
+ atlassian,
140
+ github
141
+ };
142
+ }
143
+
144
+ /**
145
+ * Verifica credenciais Atlassian a partir do diretório alvo.
146
+ */
147
+ function checkAtlassianAuth(targetDir = process.cwd()) {
148
+ const creds = getAtlassianCredentials(targetDir);
149
+ const missingFields = [];
150
+ if (!creds.token) missingFields.push('token');
151
+ if (!creds.email) missingFields.push('email');
152
+ if (!creds.domain) missingFields.push('domain');
153
+
154
+ return {
155
+ configured: creds.isConfigured,
156
+ email: creds.email,
157
+ domain: creds.domain,
158
+ tokenPresent: Boolean(creds.token),
159
+ maskedToken: maskSecret(creds.token),
160
+ source: creds.source,
161
+ missingFields
162
+ };
163
+ }
164
+
165
+ /**
166
+ * Configura credenciais no arquivo .env e garante proteção no .gitignore.
167
+ */
168
+ function configureCredentials(targetDir = process.cwd(), credentials = {}) {
169
+ const dir = typeof targetDir === 'string' && targetDir ? targetDir : process.cwd();
170
+ const safeCreds = credentials && typeof credentials === 'object' ? credentials : {};
171
+
172
+ const updates = {
173
+ ATLASSIAN_DOMAIN: safeCreds.domain,
174
+ ATLASSIAN_EMAIL: safeCreds.email,
175
+ ATLASSIAN_API_TOKEN: safeCreds.token,
176
+ JIRA_PROJECT_KEY: safeCreds.jiraKey,
177
+ CONFLUENCE_SPACE_KEY: safeCreds.confluenceSpace,
178
+ GITHUB_TOKEN: safeCreds.githubToken
179
+ };
180
+
181
+ try {
182
+ if (!fs.existsSync(dir)) {
183
+ fs.mkdirSync(dir, { recursive: true });
184
+ }
185
+
186
+ const envPath = path.join(dir, '.env');
187
+ const existingEnv = fs.existsSync(envPath) ? fs.readFileSync(envPath, 'utf8') : '';
188
+ const updatedEnv = mergeEnvUpdates(existingEnv, updates);
189
+ fs.writeFileSync(envPath, updatedEnv, 'utf8');
190
+
191
+ const gitignorePath = path.join(dir, '.gitignore');
192
+ const existingGitignore = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, 'utf8') : '';
193
+ const { modified, content: updatedGitignore } = ensureGitignoreProtected(existingGitignore);
194
+ if (modified || !fs.existsSync(gitignorePath)) {
195
+ fs.writeFileSync(gitignorePath, updatedGitignore, 'utf8');
196
+ }
197
+
198
+ return {
199
+ status: 'SUCCESS',
200
+ success: true,
201
+ envPath,
202
+ configuredKeys: Object.keys(updates).filter(k => updates[k])
203
+ };
204
+ } catch (err) {
205
+ return {
206
+ status: 'ERROR',
207
+ success: false,
208
+ error: err.message,
209
+ configuredKeys: []
210
+ };
211
+ }
212
+ }
213
+
214
+ /**
215
+ * Executa o diagnóstico completo de saúde das credenciais Atlassian e GitHub.
216
+ */
217
+ function runCredentialHealthcheck(targetDir = process.cwd()) {
218
+ const safeDir = typeof targetDir === 'string' && targetDir ? targetDir : process.cwd();
219
+ const gh = checkGithubAuth();
220
+ const atlassian = checkAtlassianAuth(safeDir);
221
+
222
+ const gitignorePath = path.join(safeDir, '.gitignore');
223
+ let envIgnored = false;
224
+ if (fs.existsSync(gitignorePath)) {
225
+ const gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
226
+ envIgnored = gitignoreContent.includes('.env');
227
+ }
228
+
229
+ const missing = [];
230
+ const remediation = [];
231
+
232
+ if (!gh.authenticated) {
233
+ missing.push('GitHub CLI');
234
+ remediation.push({
235
+ tool: 'GitHub CLI',
236
+ command: 'gh auth login',
237
+ instruction: 'Execute "gh auth login" no terminal para autenticar sua conta GitHub no CLI.'
238
+ });
239
+ }
240
+
241
+ if (!atlassian.configured) {
242
+ const missingItems = (atlassian.missingFields || []).join(', ');
243
+ missing.push(`Credenciais Atlassian (${missingItems})`);
244
+ remediation.push({
245
+ tool: 'Atlassian Cloud (Jira & Confluence)',
246
+ instruction: 'Cadastre suas credenciais no arquivo .env ou execute "npx agent-master-init":',
247
+ requiredVariables: {
248
+ ATLASSIAN_DOMAIN: 'seu-subdominio.atlassian.net',
249
+ ATLASSIAN_EMAIL: '<seu_email_corporativo>',
250
+ ATLASSIAN_API_TOKEN: 'https://id.atlassian.com/manage-profile/security/api-tokens'
251
+ }
252
+ });
253
+ }
254
+
255
+ if (!envIgnored && fs.existsSync(path.join(safeDir, '.env'))) {
256
+ remediation.push({
257
+ tool: 'Git Security Guard',
258
+ instruction: 'Adicione ".env" ao seu arquivo .gitignore para evitar o commit acidental de credenciais.'
259
+ });
260
+ }
261
+
262
+ const allReady = gh.authenticated && atlassian.configured;
263
+
264
+ let promptGuidance = '';
265
+ if (!allReady) {
266
+ promptGuidance = `⚠️ [ALERTA DE CONFIGURAÇÃO DE AMBIENTE - REGRA 15]\n` +
267
+ `Faltam credenciais essenciais para o funcionamento autônomo da suíte:\n` +
268
+ remediation.map(r => `- ${r.tool}: ${r.instruction || r.command}`).join('\n') +
269
+ `\nSolicite as credenciais ao usuário ou instrua a execução de "gh auth login" antes de prosseguir com tarefas que exijam Jira/Confluence/Git.`;
270
+ } else {
271
+ promptGuidance = '✅ Todas as integrações (GitHub, Jira e Confluence) estão configuradas e prontas para operação autônoma.';
272
+ }
273
+
274
+ return {
275
+ allReady,
276
+ github: gh,
277
+ atlassian,
278
+ envProtected: envIgnored,
279
+ missing,
280
+ remediation,
281
+ promptGuidance
282
+ };
283
+ }
284
+
285
+ /**
286
+ * Formata relatório executivo em Markdown sobre o status das credenciais e conformidade com a Regra 15.
287
+ * @param {object} [health={}]
288
+ * @returns {string}
289
+ */
290
+ function formatReport(health = {}) {
291
+ const safeHealth = health && typeof health === 'object' ? health : {};
292
+ let md = '# 🛡️ Credentials Guard — Status Report de Credenciais & Regra 15\n\n';
293
+
294
+ const allReady = Boolean(safeHealth.allReady);
295
+ const statusBadge = allReady ? '🟢 **HOMOLOGADO**' : '🔴 **PENDENTE DE CONFIGURAÇÃO**';
296
+
297
+ md += `**Status Global:** ${statusBadge}\n\n`;
298
+ md += '| Componente / Integração | Status | Detalhes | Ação Recomendada |\n';
299
+ md += '| :--- | :---: | :--- | :--- |\n';
300
+
301
+ const gh = safeHealth.github || {};
302
+ const ghStatus = gh.authenticated ? '✅ Conectado' : '❌ Não autenticado';
303
+ const ghDetails = gh.user ? `Usuário: \`${gh.user}\`` : 'Token/CLI ausente';
304
+ const ghAction = gh.authenticated ? 'Nenhuma' : 'Executar `gh auth login`';
305
+ md += `| **GitHub CLI / Token** | ${ghStatus} | ${ghDetails} | ${ghAction} |\n`;
306
+
307
+ const atl = safeHealth.atlassian || {};
308
+ const atlStatus = atl.configured ? '✅ Configurado' : '❌ Incompleto';
309
+ const atlDetails = atl.configured
310
+ ? `Domínio: \`${atl.domain || 'N/A'}\` | Email: \`${atl.email || 'N/A'}\``
311
+ : `Campos faltantes: \`${(atl.missingFields || []).join(', ') || 'todos'}\``;
312
+ const atlAction = atl.configured ? 'Nenhuma' : 'Configurar variáveis no `.env`';
313
+ md += `| **Atlassian Cloud (Jira & Confluence)** | ${atlStatus} | ${atlDetails} | ${atlAction} |\n`;
314
+
315
+ if (safeHealth.envProtected !== undefined) {
316
+ const envStatus = safeHealth.envProtected ? '✅ Protegido' : '⚠️ Desprotegido';
317
+ const envDetails = safeHealth.envProtected ? '`.env` consta no `.gitignore`' : '`.env` ausente do `.gitignore`';
318
+ const envAction = safeHealth.envProtected ? 'Nenhuma' : 'Adicionar `.env` ao `.gitignore`';
319
+ md += `| **Proteção de Segredos (.gitignore)** | ${envStatus} | ${envDetails} | ${envAction} |\n`;
320
+ }
321
+
322
+ md += '\n';
323
+
324
+ if (!allReady && Array.isArray(safeHealth.remediation) && safeHealth.remediation.length > 0) {
325
+ md += '### 🛠️ Ações de Remediação Imediata\n\n';
326
+ for (const r of safeHealth.remediation) {
327
+ md += `- **${r.tool}:** ${r.instruction || r.command}\n`;
328
+ }
329
+ }
330
+
331
+ return md;
332
+ }
333
+
334
+ /**
335
+ * Audita a prontidão de credenciais e integridade emitindo relatório oficial no formato OASIS SARIF v2.1.0.
336
+ * @param {object} [result={}]
337
+ * @returns {object} SARIF v2.1.0 JSON object
338
+ */
339
+ function auditToSarif(result = {}) {
340
+ const safeResult = result && typeof result === 'object' ? result : {};
341
+ const rules = [
342
+ {
343
+ id: 'RULE-SEC-015',
344
+ name: 'MissingRequiredCredentials',
345
+ severity: 'HIGH',
346
+ message: 'Credenciais essenciais da Regra 15 ausentes (Jira, Confluence ou GitHub).'
347
+ },
348
+ {
349
+ id: 'RULE-SEC-016',
350
+ name: 'GitignoreEnvUnprotected',
351
+ severity: 'CRITICAL',
352
+ message: 'Arquivo de ambiente .env desprotegido no .gitignore (Risco de vazamento de segredos).'
353
+ },
354
+ {
355
+ id: 'RULE-SEC-017',
356
+ name: 'GitHubCliUnauthenticated',
357
+ severity: 'MEDIUM',
358
+ message: 'CLI do GitHub (gh) não está autenticado.'
359
+ }
360
+ ];
361
+
362
+ const findings = [];
363
+
364
+ // Avaliação baseada em validateRule15
365
+ if (safeResult.valid === false && Array.isArray(safeResult.missing)) {
366
+ findings.push({
367
+ ruleId: 'RULE-SEC-015',
368
+ message: `Regra 15 violada: Faltam pré-requisitos obrigatórios (${safeResult.missing.join(', ')}).`,
369
+ filePath: '.env',
370
+ line: 1,
371
+ column: 1
372
+ });
373
+ }
374
+
375
+ // Avaliação baseada em runCredentialHealthcheck
376
+ if (safeResult.allReady === false) {
377
+ if (safeResult.atlassian && !safeResult.atlassian.configured) {
378
+ findings.push({
379
+ ruleId: 'RULE-SEC-015',
380
+ message: `Credenciais Atlassian não configuradas (${(safeResult.atlassian.missingFields || []).join(', ')}).`,
381
+ filePath: '.env',
382
+ line: 1,
383
+ column: 1
384
+ });
385
+ }
386
+
387
+ if (safeResult.github && !safeResult.github.authenticated) {
388
+ findings.push({
389
+ ruleId: 'RULE-SEC-017',
390
+ message: 'GitHub CLI não autenticado no ambiente local.',
391
+ filePath: '.git/config',
392
+ line: 1,
393
+ column: 1
394
+ });
395
+ }
396
+ }
397
+
398
+ if (safeResult.envProtected === false) {
399
+ findings.push({
400
+ ruleId: 'RULE-SEC-016',
401
+ message: 'Arquivo .env detectado sem proteção de entrada correspondente no .gitignore (CWE-798).',
402
+ filePath: '.gitignore',
403
+ line: 1,
404
+ column: 1
405
+ });
406
+ }
407
+
408
+ return createSarifReport({
409
+ toolName: 'agent-credentials-guard',
410
+ toolVersion: '5.1.0',
411
+ rules,
412
+ findings,
413
+ properties: {
414
+ category: 'Security & Secret Management',
415
+ rule: 'Regra 15 - Imutabilidade de Requisitos & Validação Compulsória de Segredos'
416
+ }
417
+ });
418
+ }
419
+
420
+ /**
421
+ * Classe Canônica CredentialsGuard
422
+ */
423
+ class CredentialsGuard {
424
+ constructor(options = {}) {
425
+ this.targetDir = typeof options.targetDir === 'string' && options.targetDir ? options.targetDir : process.cwd();
426
+ this.logger = options.logger || console;
427
+ this.dryRun = Boolean(options.dryRun);
428
+ }
429
+
430
+ validateRule15(opts = {}) {
431
+ return CredentialsGuard.validateRule15(opts);
432
+ }
433
+
434
+ checkAtlassianAuth(targetDir = this.targetDir) {
435
+ return CredentialsGuard.checkAtlassianAuth(targetDir);
436
+ }
437
+
438
+ checkGithubAuth() {
439
+ return CredentialsGuard.checkGithubAuth();
440
+ }
441
+
442
+ configureCredentials(targetDir = this.targetDir, credentials = {}) {
443
+ return CredentialsGuard.configureCredentials(targetDir, credentials);
444
+ }
445
+
446
+ runCredentialHealthcheck(targetDir = this.targetDir) {
447
+ return CredentialsGuard.runCredentialHealthcheck(targetDir);
448
+ }
449
+
450
+ formatReport(health) {
451
+ return CredentialsGuard.formatReport(health);
452
+ }
453
+
454
+ auditToSarif(result) {
455
+ return CredentialsGuard.auditToSarif(result);
456
+ }
457
+
458
+ // Métodos estáticos canônicos
459
+ static get InviolableRuleError() { return InviolableRuleError; }
460
+ static validateRule15(opts) { return validateRule15(opts); }
461
+ static checkAtlassianAuth(dir) { return checkAtlassianAuth(dir); }
462
+ static checkGithubAuth() { return checkGithubAuth(); }
463
+ static configureCredentials(dir, creds) { return configureCredentials(dir, creds); }
464
+ static runCredentialHealthcheck(dir) { return runCredentialHealthcheck(dir); }
465
+ static formatReport(health) { return formatReport(health); }
466
+ static auditToSarif(result) { return auditToSarif(result); }
467
+ static maskSecret(str, chars) { return maskSecret(str, chars); }
468
+ static parseEnvLines(str) { return parseEnvLines(str); }
469
+ static mergeEnvUpdates(existing, updates) { return mergeEnvUpdates(existing, updates); }
470
+ static ensureGitignoreProtected(existing, entries) { return ensureGitignoreProtected(existing, entries); }
471
+ }
472
+
473
+ if (require.main === module) {
474
+ const outcome = runCredentialHealthcheck();
475
+ console.log(formatReport(outcome));
476
+ if (!outcome.allReady) {
477
+ process.exitCode = 1;
478
+ }
479
+ }
480
+
481
+ module.exports = {
482
+ CredentialsGuard,
483
+ InviolableRuleError,
484
+ validateRule15,
485
+ getAtlassianConfig: getAtlassianCredentials,
486
+ getGitHubConfig: checkGithubAuth,
487
+ checkGitHubAuth: checkGithubAuth,
488
+ checkGithubAuth,
489
+ getGitRepositoryUrl,
490
+ getGitMetadata,
491
+ checkAtlassianAuth,
492
+ configureCredentials,
493
+ runCredentialHealthcheck,
494
+ formatReport,
495
+ auditToSarif,
496
+ auditCredentialsToSarif: auditToSarif,
497
+ auditAtlassianToSarif: auditAtlassianToSarifBase,
498
+ maskSecret,
499
+ AtlassianClient
500
+ };