agent-master-devsecops 3.9.0 → 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 (82) hide show
  1. package/README.md +205 -371
  2. package/agents/AGENT_DEVSECOPS.md +32 -417
  3. package/agents/AGENT_INFRA.md +31 -0
  4. package/agents/AGENT_ORCHESTRATOR.md +39 -264
  5. package/agents/AGENT_QA.md +58 -186
  6. package/agents/AGENT_SCRUM.md +23 -190
  7. package/agents/AGENT_SRE.md +22 -173
  8. package/agents/AGENT_UIUX.md +26 -162
  9. package/docs/ARCHITECTURE.md +152 -148
  10. package/docs/CALCULATIONS.md +17 -17
  11. package/docs/CHANGELOG.md +112 -49
  12. package/docs/ENGINEERING_RULES.md +56 -252
  13. package/docs/IDEAS.md +17 -17
  14. package/docs/LOCAL_BACKLOG.md +20 -0
  15. package/docs/STATE.md +111 -43
  16. package/docs/playbooks/PLAYBOOK_CIRCUIT_BREAKER_LLM.md +58 -58
  17. package/docs/playbooks/PLAYBOOK_OPENTELEMETRY_TRACING.md +58 -58
  18. package/package.json +59 -47
  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/{bootstrap_cli.js → bin/bootstrap_cli.js} +597 -468
  28. package/scripts/bin/domain_idea_miner.js +658 -0
  29. package/scripts/bin/smart_onboarding.js +905 -0
  30. package/scripts/{web_inspector.js → bin/web_inspector.js} +578 -355
  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/{circuit_breaker.js → core/circuit_breaker.js} +546 -330
  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/{magic_prompt_generator.js → core/magic_prompt_generator.js} +250 -205
  40. package/scripts/{multi_agent_orchestrator.js → core/multi_agent_orchestrator.js} +421 -258
  41. package/scripts/{otel_tracer.js → core/otel_tracer.js} +335 -228
  42. package/scripts/{perf_benchmark.js → core/perf_benchmark.js} +212 -153
  43. package/scripts/core/sarif_engine.js +299 -0
  44. package/scripts/{sre_remediation_engine.js → core/sre_remediation_engine.js} +236 -174
  45. package/scripts/{universal_packager.js → core/universal_packager.js} +357 -313
  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 -1884
  62. package/.cursorignore +0 -23
  63. package/agents/compact/AGENT_ORCHESTRATOR_COMPACTO.md +0 -53
  64. package/scripts/a11y_auditor.js +0 -187
  65. package/scripts/ast_skeletonizer.js +0 -220
  66. package/scripts/atlassian_client.js +0 -238
  67. package/scripts/atlassian_sync_action.js +0 -269
  68. package/scripts/code_quality_auditor.js +0 -142
  69. package/scripts/confluence_sync.js +0 -337
  70. package/scripts/context_compressor.js +0 -139
  71. package/scripts/contract_test_validator.js +0 -166
  72. package/scripts/credentials_guard.js +0 -216
  73. package/scripts/domain_idea_miner.js +0 -364
  74. package/scripts/eval_harness.js +0 -100
  75. package/scripts/fast_feature_scaffold.js +0 -338
  76. package/scripts/git_hygiene_linter.js +0 -186
  77. package/scripts/hot_state_cache.js +0 -95
  78. package/scripts/jira_manager.js +0 -408
  79. package/scripts/pr_reviewer.js +0 -373
  80. package/scripts/sast_scanner.js +0 -180
  81. package/scripts/sca_dependency_auditor.js +0 -167
  82. package/scripts/smart_onboarding.js +0 -610
@@ -0,0 +1,453 @@
1
+ /**
2
+ * scripts/mcp/resources_registry.js
3
+ *
4
+ * Resources Registry — Catálogo e Leitor de Recursos Canônicos MCP.
5
+ * Fornece acesso à documentação viva (Princípios Canônicos, Arquitetura, Backlog de Ideias,
6
+ * Livro-Razão e Estado Ativo) e barramento de eventos multi-agente.
7
+ * Compatível com o protocolo oficial MCP (Model Context Protocol) resources/list e resources/read.
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
+ const { createSarifReport } = require('../core/sarif_engine.js');
17
+
18
+ const ROOT_DIR = path.resolve(__dirname, '../..');
19
+
20
+ /**
21
+ * Catálogo declarativo imutável de recursos canônicos do Agent Master
22
+ */
23
+ const RESOURCE_DEFINITIONS = Object.freeze({
24
+ 'agent://rules': Object.freeze({
25
+ uri: 'agent://rules',
26
+ name: 'Os 10 Princípios Canônicos de Engenharia de Software & Governança (ENGINEERING_RULES.md)',
27
+ mimeType: 'text/markdown',
28
+ relPath: 'docs/ENGINEERING_RULES.md'
29
+ }),
30
+ 'agent://architecture': Object.freeze({
31
+ uri: 'agent://architecture',
32
+ name: 'Arquitetura Multi-Agente & Handovers (ARCHITECTURE.md)',
33
+ mimeType: 'text/markdown',
34
+ relPath: 'docs/ARCHITECTURE.md'
35
+ }),
36
+ 'agent://ideas': Object.freeze({
37
+ uri: 'agent://ideas',
38
+ name: 'Backlog Vivo de Ideias & Auto-Evolução (IDEAS.md)',
39
+ mimeType: 'text/markdown',
40
+ relPath: 'docs/IDEAS.md'
41
+ }),
42
+ 'agent://events': Object.freeze({
43
+ uri: 'agent://events',
44
+ name: 'Histórico e Barramento de Eventos Multi-Agente',
45
+ mimeType: 'application/json',
46
+ dynamicProvider: () => {
47
+ const { EVENT_TYPES, AGENT_PERSONAS } = require('../core/multi_agent_orchestrator.js');
48
+ return JSON.stringify({
49
+ status: 'ACTIVE',
50
+ busType: 'Mesh-Hierarchical Event Bus',
51
+ supportedEvents: Object.keys(EVENT_TYPES),
52
+ registeredPersonas: Object.keys(AGENT_PERSONAS || {})
53
+ }, null, 2);
54
+ }
55
+ }),
56
+ 'agent://changelog': Object.freeze({
57
+ uri: 'agent://changelog',
58
+ name: 'Livro-Razão Imutável de Entregas (CHANGELOG.md)',
59
+ mimeType: 'text/markdown',
60
+ relPath: 'docs/CHANGELOG.md'
61
+ }),
62
+ 'agent://state': Object.freeze({
63
+ uri: 'agent://state',
64
+ name: 'Quadro de Execução Ativo do Framework (STATE.md)',
65
+ mimeType: 'text/markdown',
66
+ relPath: 'docs/STATE.md'
67
+ })
68
+ });
69
+
70
+ /**
71
+ * Lista de recursos exposta pelo protocolo MCP resources/list (imutável)
72
+ */
73
+ const RESOURCES = Object.freeze(
74
+ Object.values(RESOURCE_DEFINITIONS).map(def => Object.freeze({
75
+ uri: def.uri,
76
+ name: def.name,
77
+ mimeType: def.mimeType
78
+ }))
79
+ );
80
+
81
+ /**
82
+ * Helper puro de resolução de caminho absoluto com proteção contra Path Traversal (CWE-22)
83
+ */
84
+ function resolveDocFile(rootDir, relPath) {
85
+ const safeRoot = path.resolve(rootDir || ROOT_DIR);
86
+ const targetPath = path.resolve(safeRoot, relPath);
87
+ if (!targetPath.startsWith(safeRoot)) {
88
+ throw new Error(`Tentativa de Path Traversal bloqueada: ${relPath}`);
89
+ }
90
+ return targetPath;
91
+ }
92
+
93
+ /**
94
+ * Helpers funcionais puros para envelopes JSON-RPC 2.0 (DRY)
95
+ */
96
+ function buildSuccessResponse(id, result) {
97
+ return {
98
+ jsonrpc: '2.0',
99
+ id: id !== undefined && id !== null ? id : null,
100
+ result
101
+ };
102
+ }
103
+
104
+ function buildErrorResponse(id, code, message, data = null) {
105
+ const error = { code, message };
106
+ if (data !== null && data !== undefined) {
107
+ error.data = data;
108
+ }
109
+ return {
110
+ jsonrpc: '2.0',
111
+ id: id !== undefined && id !== null ? id : null,
112
+ error
113
+ };
114
+ }
115
+
116
+ function buildResourceContentResponse(id, uri, mimeType, text) {
117
+ return buildSuccessResponse(id, {
118
+ contents: [
119
+ {
120
+ uri,
121
+ mimeType,
122
+ text
123
+ }
124
+ ]
125
+ });
126
+ }
127
+
128
+ /**
129
+ * Classe Canônica ResourcesRegistry — Gerenciador de Recursos e Documentação Viva MCP
130
+ */
131
+ class ResourcesRegistry {
132
+ constructor(rootDir = ROOT_DIR, customRegistry = null) {
133
+ this.rootDir = path.resolve(rootDir || ROOT_DIR);
134
+ this.customRegistry = customRegistry ? new Map(Object.entries(customRegistry)) : new Map();
135
+ }
136
+
137
+ static get ROOT_DIR() {
138
+ return ROOT_DIR;
139
+ }
140
+
141
+ static get RESOURCES() {
142
+ return RESOURCES;
143
+ }
144
+
145
+ static get RESOURCE_DEFINITIONS() {
146
+ return RESOURCE_DEFINITIONS;
147
+ }
148
+
149
+ /**
150
+ * Registra dinamicamente um novo recurso no registro em runtime
151
+ */
152
+ registerResource(uri, definition) {
153
+ if (!uri || typeof uri !== 'string') {
154
+ throw new Error('URI do recurso deve ser uma string válida');
155
+ }
156
+ if (!definition || typeof definition !== 'object') {
157
+ throw new Error('Definição do recurso deve ser um objeto válido');
158
+ }
159
+ this.customRegistry.set(uri, Object.freeze({
160
+ uri,
161
+ name: definition.name || uri,
162
+ mimeType: definition.mimeType || 'text/plain',
163
+ relPath: definition.relPath || null,
164
+ dynamicProvider: typeof definition.dynamicProvider === 'function' ? definition.dynamicProvider : null
165
+ }));
166
+ }
167
+
168
+ /**
169
+ * Resolve a definição de um recurso por URI
170
+ */
171
+ getDefinition(uri) {
172
+ if (!uri || typeof uri !== 'string') return null;
173
+ if (this.customRegistry.has(uri)) {
174
+ return this.customRegistry.get(uri);
175
+ }
176
+ return RESOURCE_DEFINITIONS[uri] || null;
177
+ }
178
+
179
+ /**
180
+ * Lista todos os recursos disponíveis (estático e instância)
181
+ */
182
+ listResources() {
183
+ const defaultList = [...RESOURCES];
184
+ const customList = Array.from(this.customRegistry.values()).map(def => ({
185
+ uri: def.uri,
186
+ name: def.name,
187
+ mimeType: def.mimeType
188
+ }));
189
+ return [...defaultList, ...customList];
190
+ }
191
+
192
+ static handleResourcesList(id) {
193
+ return buildSuccessResponse(id, {
194
+ resources: RESOURCES
195
+ });
196
+ }
197
+
198
+ handleResourcesList(id) {
199
+ return buildSuccessResponse(id, {
200
+ resources: this.listResources()
201
+ });
202
+ }
203
+
204
+ /**
205
+ * Resolução síncrona de conteúdo de recurso
206
+ */
207
+ resolveContentSync(uri) {
208
+ const def = this.getDefinition(uri);
209
+ if (!def) return null;
210
+
211
+ if (typeof def.dynamicProvider === 'function') {
212
+ return {
213
+ uri: def.uri,
214
+ mimeType: def.mimeType,
215
+ text: def.dynamicProvider()
216
+ };
217
+ }
218
+
219
+ if (def.relPath) {
220
+ const filePath = resolveDocFile(this.rootDir, def.relPath);
221
+ if (fs.existsSync(filePath)) {
222
+ const text = fs.readFileSync(filePath, 'utf8');
223
+ return {
224
+ uri: def.uri,
225
+ mimeType: def.mimeType,
226
+ text
227
+ };
228
+ }
229
+ }
230
+
231
+ return null;
232
+ }
233
+
234
+ /**
235
+ * Resolução assíncrona de conteúdo de recurso
236
+ */
237
+ async resolveContentAsync(uri) {
238
+ const def = this.getDefinition(uri);
239
+ if (!def) return null;
240
+
241
+ if (typeof def.dynamicProvider === 'function') {
242
+ const res = def.dynamicProvider();
243
+ const text = res instanceof Promise ? await res : res;
244
+ return {
245
+ uri: def.uri,
246
+ mimeType: def.mimeType,
247
+ text
248
+ };
249
+ }
250
+
251
+ if (def.relPath) {
252
+ const filePath = resolveDocFile(this.rootDir, def.relPath);
253
+ try {
254
+ const text = await fs.promises.readFile(filePath, 'utf8');
255
+ return {
256
+ uri: def.uri,
257
+ mimeType: def.mimeType,
258
+ text
259
+ };
260
+ } catch {
261
+ return null;
262
+ }
263
+ }
264
+
265
+ return null;
266
+ }
267
+
268
+ /**
269
+ * Leitura de recurso MCP síncrona (JSON-RPC 2.0)
270
+ */
271
+ handleResourceRead(id, params) {
272
+ try {
273
+ const safeParams = params && typeof params === 'object' ? params : {};
274
+ const uri = safeParams.uri;
275
+ const content = this.resolveContentSync(uri);
276
+
277
+ if (content) {
278
+ return buildResourceContentResponse(id, content.uri, content.mimeType, content.text);
279
+ }
280
+
281
+ return buildErrorResponse(id, -32602, `Recurso não encontrado: ${uri}`);
282
+ } catch (err) {
283
+ return buildErrorResponse(id, -32603, `Falha interna ao ler recurso: ${err.message}`);
284
+ }
285
+ }
286
+
287
+ static handleResourceRead(id, params) {
288
+ const defaultInstance = new ResourcesRegistry(ROOT_DIR);
289
+ return defaultInstance.handleResourceRead(id, params);
290
+ }
291
+
292
+ /**
293
+ * Leitura de recurso MCP assíncrona (JSON-RPC 2.0)
294
+ */
295
+ async handleResourceReadAsync(id, params) {
296
+ try {
297
+ const safeParams = params && typeof params === 'object' ? params : {};
298
+ const uri = safeParams.uri;
299
+ const content = await this.resolveContentAsync(uri);
300
+
301
+ if (content) {
302
+ return buildResourceContentResponse(id, content.uri, content.mimeType, content.text);
303
+ }
304
+
305
+ return buildErrorResponse(id, -32602, `Recurso não encontrado: ${uri}`);
306
+ } catch (err) {
307
+ return buildErrorResponse(id, -32603, `Falha interna ao ler recurso: ${err.message}`);
308
+ }
309
+ }
310
+
311
+ static async handleResourceReadAsync(id, params) {
312
+ const defaultInstance = new ResourcesRegistry(ROOT_DIR);
313
+ return await defaultInstance.handleResourceReadAsync(id, params);
314
+ }
315
+
316
+ /**
317
+ * Auditoria de integridade de todos os recursos no padrão OASIS SARIF v2.1.0
318
+ */
319
+ auditToSarif() {
320
+ const findings = [];
321
+ const allDefs = { ...RESOURCE_DEFINITIONS, ...Object.fromEntries(this.customRegistry) };
322
+
323
+ for (const [uri, def] of Object.entries(allDefs)) {
324
+ if (def.relPath) {
325
+ try {
326
+ const filePath = resolveDocFile(this.rootDir, def.relPath);
327
+ if (!fs.existsSync(filePath)) {
328
+ findings.push({
329
+ ruleId: 'RULE-RES-001',
330
+ severity: 'HIGH',
331
+ filename: def.relPath,
332
+ line: 1,
333
+ column: 1,
334
+ snippet: `URI: ${uri}`,
335
+ message: `Documento de governança '${def.relPath}' não foi encontrado no disco.`,
336
+ remediation: `Restaurar ou provisionar o arquivo '${def.relPath}' para conformidade com a Tríade.`
337
+ });
338
+ }
339
+ } catch (err) {
340
+ findings.push({
341
+ ruleId: 'RULE-RES-001',
342
+ severity: 'HIGH',
343
+ filename: def.relPath,
344
+ line: 1,
345
+ column: 1,
346
+ snippet: `URI: ${uri}`,
347
+ message: `Erro ao validar caminho do recurso: ${err.message}`,
348
+ remediation: 'Verificar integridade estrutural e permissões de acesso ao arquivo.'
349
+ });
350
+ }
351
+ } else if (typeof def.dynamicProvider === 'function') {
352
+ try {
353
+ const res = def.dynamicProvider();
354
+ if (!res) throw new Error('Provider retornou payload nulo');
355
+ } catch (err) {
356
+ findings.push({
357
+ ruleId: 'RULE-RES-002',
358
+ severity: 'HIGH',
359
+ filename: 'multi_agent_orchestrator.js',
360
+ line: 1,
361
+ column: 1,
362
+ snippet: `URI: ${uri}`,
363
+ message: `Falha ao gerar recurso dinâmico '${uri}': ${err.message}`,
364
+ remediation: 'Verificar status do barramento de eventos ou imports no orquestrador multi-agente.'
365
+ });
366
+ }
367
+ }
368
+ }
369
+
370
+ return createSarifReport({
371
+ toolName: 'agent-master-resources-registry',
372
+ toolVersion: '5.1.0',
373
+ findings,
374
+ properties: {
375
+ totalResources: Object.keys(allDefs).length,
376
+ brokenResources: findings.length
377
+ }
378
+ });
379
+ }
380
+
381
+ static auditToSarif() {
382
+ const defaultInstance = new ResourcesRegistry(ROOT_DIR);
383
+ return defaultInstance.auditToSarif();
384
+ }
385
+
386
+ /**
387
+ * Gera relatório executivo em Markdown com status de cada recurso
388
+ */
389
+ formatReport() {
390
+ const allDefs = { ...RESOURCE_DEFINITIONS, ...Object.fromEntries(this.customRegistry) };
391
+ const lines = [
392
+ '# Relatório Executivo: Recursos MCP & Documentação Viva',
393
+ '',
394
+ `| URI | Nome | Tipo MIME | Origem | Status |`,
395
+ `|---|---|---|---|---|`
396
+ ];
397
+
398
+ for (const [uri, def] of Object.entries(allDefs)) {
399
+ let status = 'ONLINE';
400
+ let origem = def.relPath ? `docs (${def.relPath})` : 'Barramento Dinâmico';
401
+
402
+ if (def.relPath) {
403
+ const filePath = resolveDocFile(this.rootDir, def.relPath);
404
+ if (!fs.existsSync(filePath)) {
405
+ status = 'AUSENTE (404)';
406
+ }
407
+ } else if (typeof def.dynamicProvider === 'function') {
408
+ try {
409
+ def.dynamicProvider();
410
+ } catch {
411
+ status = 'FALHA DE EXECUÇÃO';
412
+ }
413
+ }
414
+
415
+ lines.push(`| \`${uri}\` | ${def.name} | \`${def.mimeType}\` | ${origem} | ${status} |`);
416
+ }
417
+
418
+ lines.push('');
419
+ return lines.join('\n');
420
+ }
421
+
422
+ static formatReport() {
423
+ const defaultInstance = new ResourcesRegistry(ROOT_DIR);
424
+ return defaultInstance.formatReport();
425
+ }
426
+ }
427
+
428
+ // Funções stand-alone compatíveis com a API legada
429
+ function handleResourcesList(id) {
430
+ return ResourcesRegistry.handleResourcesList(id);
431
+ }
432
+
433
+ function handleResourceRead(id, params) {
434
+ return ResourcesRegistry.handleResourceRead(id, params);
435
+ }
436
+
437
+ async function handleResourceReadAsync(id, params) {
438
+ return await ResourcesRegistry.handleResourceReadAsync(id, params);
439
+ }
440
+
441
+ module.exports = {
442
+ ResourcesRegistry,
443
+ ROOT_DIR,
444
+ RESOURCES,
445
+ RESOURCE_DEFINITIONS,
446
+ resolveDocFile,
447
+ handleResourcesList,
448
+ handleResourceRead,
449
+ handleResourceReadAsync,
450
+ buildSuccessResponse,
451
+ buildErrorResponse,
452
+ buildResourceContentResponse
453
+ };