@shiftleftpt/sbd-toe-mcp 0.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 (93) hide show
  1. package/.env.example +35 -0
  2. package/LICENSE +201 -0
  3. package/README.md +323 -0
  4. package/data/publish/algolia_docs_records.json +148847 -0
  5. package/data/publish/algolia_docs_records_enriched.json +194004 -0
  6. package/data/publish/algolia_entities_records.json +74715 -0
  7. package/data/publish/algolia_entities_records_enriched.json +177587 -0
  8. package/data/publish/algolia_index_settings.json +102 -0
  9. package/data/publish/sbd-toe-index-compact.json +111 -0
  10. package/data/reports/run_manifest.json +10 -0
  11. package/dist/backend/semantic-index-gateway.d.ts +25 -0
  12. package/dist/backend/semantic-index-gateway.js +555 -0
  13. package/dist/backend/semantic-index-gateway.js.map +1 -0
  14. package/dist/backend/semantic-index-gateway.test.d.ts +1 -0
  15. package/dist/backend/semantic-index-gateway.test.js +384 -0
  16. package/dist/backend/semantic-index-gateway.test.js.map +1 -0
  17. package/dist/bootstrap/checkout-backend.d.ts +31 -0
  18. package/dist/bootstrap/checkout-backend.js +136 -0
  19. package/dist/bootstrap/checkout-backend.js.map +1 -0
  20. package/dist/bootstrap/checkout-backend.test.d.ts +1 -0
  21. package/dist/bootstrap/checkout-backend.test.js +158 -0
  22. package/dist/bootstrap/checkout-backend.test.js.map +1 -0
  23. package/dist/bootstrap/release-checkout.d.ts +8 -0
  24. package/dist/bootstrap/release-checkout.js +168 -0
  25. package/dist/bootstrap/release-checkout.js.map +1 -0
  26. package/dist/bootstrap/release-checkout.test.d.ts +1 -0
  27. package/dist/bootstrap/release-checkout.test.js +137 -0
  28. package/dist/bootstrap/release-checkout.test.js.map +1 -0
  29. package/dist/config.d.ts +4 -0
  30. package/dist/config.js +81 -0
  31. package/dist/config.js.map +1 -0
  32. package/dist/index.d.ts +2 -0
  33. package/dist/index.js +1063 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/orchestrator/ask-manual.d.ts +13 -0
  36. package/dist/orchestrator/ask-manual.js +202 -0
  37. package/dist/orchestrator/ask-manual.js.map +1 -0
  38. package/dist/prompt/build-answer-prompt.d.ts +2 -0
  39. package/dist/prompt/build-answer-prompt.js +51 -0
  40. package/dist/prompt/build-answer-prompt.js.map +1 -0
  41. package/dist/prompt/system-prompt.d.ts +1 -0
  42. package/dist/prompt/system-prompt.js +94 -0
  43. package/dist/prompt/system-prompt.js.map +1 -0
  44. package/dist/resources/sbd-toe-resources.d.ts +18 -0
  45. package/dist/resources/sbd-toe-resources.js +164 -0
  46. package/dist/resources/sbd-toe-resources.js.map +1 -0
  47. package/dist/resources/sbd-toe-resources.test.d.ts +1 -0
  48. package/dist/resources/sbd-toe-resources.test.js +134 -0
  49. package/dist/resources/sbd-toe-resources.test.js.map +1 -0
  50. package/dist/test-utils.d.ts +153 -0
  51. package/dist/test-utils.js +176 -0
  52. package/dist/test-utils.js.map +1 -0
  53. package/dist/tools/generate-document.d.ts +22 -0
  54. package/dist/tools/generate-document.js +392 -0
  55. package/dist/tools/generate-document.js.map +1 -0
  56. package/dist/tools/generate-document.test.d.ts +1 -0
  57. package/dist/tools/generate-document.test.js +189 -0
  58. package/dist/tools/generate-document.test.js.map +1 -0
  59. package/dist/tools/map-review-scope.d.ts +20 -0
  60. package/dist/tools/map-review-scope.js +299 -0
  61. package/dist/tools/map-review-scope.js.map +1 -0
  62. package/dist/tools/map-review-scope.test.d.ts +1 -0
  63. package/dist/tools/map-review-scope.test.js +204 -0
  64. package/dist/tools/map-review-scope.test.js.map +1 -0
  65. package/dist/tools/plan-repo-governance.d.ts +41 -0
  66. package/dist/tools/plan-repo-governance.js +509 -0
  67. package/dist/tools/plan-repo-governance.js.map +1 -0
  68. package/dist/tools/plan-repo-governance.test.d.ts +1 -0
  69. package/dist/tools/plan-repo-governance.test.js +237 -0
  70. package/dist/tools/plan-repo-governance.test.js.map +1 -0
  71. package/dist/tools/structured-tools.d.ts +5 -0
  72. package/dist/tools/structured-tools.js +310 -0
  73. package/dist/tools/structured-tools.js.map +1 -0
  74. package/dist/tools/structured-tools.test.d.ts +1 -0
  75. package/dist/tools/structured-tools.test.js +459 -0
  76. package/dist/tools/structured-tools.test.js.map +1 -0
  77. package/dist/types.d.ts +160 -0
  78. package/dist/types.js +2 -0
  79. package/dist/types.js.map +1 -0
  80. package/dist/upstream/backend-contract.d.ts +3 -0
  81. package/dist/upstream/backend-contract.js +37 -0
  82. package/dist/upstream/backend-contract.js.map +1 -0
  83. package/dist/validators/ai-disclosure.d.ts +39 -0
  84. package/dist/validators/ai-disclosure.js +183 -0
  85. package/dist/validators/ai-disclosure.js.map +1 -0
  86. package/dist/validators/ai-disclosure.test.d.ts +1 -0
  87. package/dist/validators/ai-disclosure.test.js +244 -0
  88. package/dist/validators/ai-disclosure.test.js.map +1 -0
  89. package/examples/claude-desktop.json +8 -0
  90. package/examples/vscode.mcp.json +9 -0
  91. package/package.json +50 -0
  92. package/prompts/sbd-toe-chat-system.md +71 -0
  93. package/smithery.yaml +44 -0
@@ -0,0 +1,299 @@
1
+ const VALID_RISK_LEVELS = ["L1", "L2", "L3"];
2
+ function isValidRiskLevel(value) {
3
+ return (typeof value === "string" &&
4
+ VALID_RISK_LEVELS.includes(value));
5
+ }
6
+ function makeRpcError(message, data) {
7
+ return Object.assign(new Error(message), {
8
+ rpcError: { code: -32602, message, data: data ?? null }
9
+ });
10
+ }
11
+ // ---------------------------------------------------------------------------
12
+ // Readable titles (consistent with structured-tools.ts READABLE_TITLES)
13
+ // ---------------------------------------------------------------------------
14
+ const READABLE_TITLES = {
15
+ "01-classificacao-aplicacoes": "Classificação de Aplicações",
16
+ "02-requisitos-seguranca": "Requisitos de Segurança",
17
+ "03-threat-modeling": "Threat Modeling",
18
+ "04-arquitetura-segura": "Arquitetura Segura",
19
+ "05-dependencias-sbom-sca": "Dependências, SBOM e SCA",
20
+ "06-desenvolvimento-seguro": "Desenvolvimento Seguro",
21
+ "07-cicd-seguro": "CI/CD Seguro",
22
+ "08-iac-infraestrutura": "IaC e Infraestrutura",
23
+ "09-containers-imagens": "Containers e Imagens",
24
+ "10-testes-seguranca": "Testes de Segurança",
25
+ "11-deploy-seguro": "Deploy Seguro",
26
+ "12-monitorizacao-operacoes": "Monitorização e Operações",
27
+ "13-formacao-onboarding": "Formação e Onboarding",
28
+ "14-governanca-contratacao": "Governança e Contratação"
29
+ };
30
+ const BUNDLE_CATEGORIES = {
31
+ "01-classificacao-aplicacoes": "foundation",
32
+ "02-requisitos-seguranca": "foundation",
33
+ "03-threat-modeling": "foundation",
34
+ "04-arquitetura-segura": "foundation",
35
+ "05-dependencias-sbom-sca": "domain",
36
+ "06-desenvolvimento-seguro": "domain",
37
+ "08-iac-infraestrutura": "domain",
38
+ "09-containers-imagens": "domain",
39
+ "10-testes-seguranca": "domain",
40
+ "07-cicd-seguro": "operational",
41
+ "11-deploy-seguro": "operational",
42
+ "12-monitorizacao-operacoes": "operational",
43
+ "13-formacao-onboarding": "operational",
44
+ "14-governanca-contratacao": "operational"
45
+ };
46
+ const EXPECTED_EVIDENCE = {
47
+ "01-classificacao-aplicacoes": [
48
+ "Classificação da aplicação documentada e actualizada.",
49
+ "Nível de risco revisto face às mudanças introduzidas."
50
+ ],
51
+ "02-requisitos-seguranca": [
52
+ "Requisitos de segurança revistos e actualizados.",
53
+ "Critérios de aceitação de segurança definidos para as mudanças."
54
+ ],
55
+ "03-threat-modeling": [
56
+ "Threat model actualizado para os flows afectados.",
57
+ "Novas ameaças identificadas e endereçadas."
58
+ ],
59
+ "04-arquitetura-segura": [
60
+ "Diagrama de arquitectura actualizado.",
61
+ "Decisões de segurança documentadas nos ADRs."
62
+ ],
63
+ "05-dependencias-sbom-sca": [
64
+ "SBOM actualizado após mudanças de dependências.",
65
+ "Scan de dependências executado sem findings críticos."
66
+ ],
67
+ "06-desenvolvimento-seguro": [
68
+ "Revisão de código com foco em segurança realizada.",
69
+ "Sem hardcoded secrets ou dados sensíveis no código."
70
+ ],
71
+ "07-cicd-seguro": [
72
+ "Pipeline CI/CD com security gates activos.",
73
+ "Secrets em vault — não expostos nos logs do pipeline."
74
+ ],
75
+ "08-iac-infraestrutura": [
76
+ "Configuração de infraestrutura revista com princípio de least privilege.",
77
+ "Drift de configuração verificado e remediado."
78
+ ],
79
+ "09-containers-imagens": [
80
+ "Imagem base actualizada e scanned sem vulnerabilidades críticas.",
81
+ "Dockerfile sem execução como root."
82
+ ],
83
+ "10-testes-seguranca": [
84
+ "SAST/DAST executados sem findings críticos por resolver.",
85
+ "Testes de segurança relevantes para as mudanças adicionados."
86
+ ],
87
+ "11-deploy-seguro": [
88
+ "Processo de release documentado e aprovado.",
89
+ "Rollback plan definido e testado."
90
+ ],
91
+ "12-monitorizacao-operacoes": [
92
+ "Alertas de segurança actualizados para cobrir as mudanças.",
93
+ "Logs de segurança activos e a fluir correctamente."
94
+ ],
95
+ "13-formacao-onboarding": [
96
+ "Equipa informada das mudanças com impacto em processos.",
97
+ "Documentação de onboarding actualizada."
98
+ ],
99
+ "14-governanca-contratacao": [
100
+ "Documentação de governança actualizada.",
101
+ "Aprovações e revisões necessárias obtidas."
102
+ ]
103
+ };
104
+ const PATTERN_RULES = [
105
+ {
106
+ pattern: "src/config.ts",
107
+ bundles: ["02-requisitos-seguranca", "06-desenvolvimento-seguro", "08-iac-infraestrutura", "10-testes-seguranca"],
108
+ matches: (p) => p === "src/config.ts"
109
+ },
110
+ {
111
+ pattern: "src/**",
112
+ bundles: ["02-requisitos-seguranca", "06-desenvolvimento-seguro", "10-testes-seguranca"],
113
+ matches: (p) => p.startsWith("src/")
114
+ },
115
+ {
116
+ pattern: ".github/workflows/**",
117
+ bundles: ["07-cicd-seguro", "10-testes-seguranca", "11-deploy-seguro"],
118
+ matches: (p) => p.startsWith(".github/workflows/")
119
+ },
120
+ {
121
+ pattern: "package.json / *-lock.json / yarn.lock",
122
+ bundles: ["05-dependencias-sbom-sca"],
123
+ matches: (p) => p === "package.json" ||
124
+ p === "package-lock.json" ||
125
+ p === "yarn.lock" ||
126
+ p.endsWith("-lock.json")
127
+ },
128
+ {
129
+ pattern: "release/** / scripts/package-*",
130
+ bundles: ["11-deploy-seguro"],
131
+ matches: (p) => p.startsWith("release/") || p.startsWith("scripts/package-")
132
+ },
133
+ {
134
+ pattern: "docs/**",
135
+ bundles: ["14-governanca-contratacao"],
136
+ matches: (p) => p.startsWith("docs/")
137
+ },
138
+ {
139
+ pattern: "aos/** / .github/skills/**",
140
+ bundles: ["14-governanca-contratacao", "13-formacao-onboarding"],
141
+ matches: (p) => p.startsWith("aos/") || p.startsWith(".github/skills/")
142
+ }
143
+ ];
144
+ const GUARDRAIL_BUNDLES = ["01-classificacao-aplicacoes", "02-requisitos-seguranca"];
145
+ // ---------------------------------------------------------------------------
146
+ // Handler
147
+ // ---------------------------------------------------------------------------
148
+ export function handleMapSbdToeReviewScope(args) {
149
+ // Validate riskLevel
150
+ const riskLevelArg = args["riskLevel"];
151
+ if (!isValidRiskLevel(riskLevelArg)) {
152
+ throw makeRpcError(`riskLevel inválido: "${String(riskLevelArg)}". Valores permitidos: L1, L2, L3.`, { invalidValue: riskLevelArg });
153
+ }
154
+ const riskLevel = riskLevelArg;
155
+ // Validate changedFiles
156
+ const changedFilesArg = args["changedFiles"];
157
+ if (!Array.isArray(changedFilesArg) || changedFilesArg.length === 0) {
158
+ throw makeRpcError('O argumento "changedFiles" é obrigatório e deve conter pelo menos um path.', { receivedValue: changedFilesArg });
159
+ }
160
+ // Normalize and validate each path
161
+ const normalizedPaths = [];
162
+ for (const raw of changedFilesArg) {
163
+ if (typeof raw !== "string") {
164
+ throw makeRpcError(`Path inválido: ${JSON.stringify(raw)}. Todos os paths devem ser strings.`);
165
+ }
166
+ // Normalize separators (cross-platform)
167
+ const normalized = raw.replace(/\\/g, "/");
168
+ // Path traversal check
169
+ if (normalized.includes("..")) {
170
+ throw makeRpcError(`Path inválido (path traversal detectado): "${normalized}". Paths com ".." não são permitidos.`, { invalidPath: normalized });
171
+ }
172
+ normalizedPaths.push(normalized);
173
+ }
174
+ // Truncate diffSummary to 500 chars (no error)
175
+ const rawDiffSummary = args["diffSummary"];
176
+ const _diffSummary = typeof rawDiffSummary === "string"
177
+ ? rawDiffSummary.slice(0, 500)
178
+ : undefined;
179
+ void _diffSummary; // reserved for future use
180
+ // ---------------------------------------------------------------------------
181
+ // Match paths to patterns
182
+ // ---------------------------------------------------------------------------
183
+ // Map: chapterId → { reason paths set, matched by guardrail only }
184
+ const bundlePathsMap = new Map();
185
+ const guardrailFiles = [];
186
+ // Track which patterns matched which files (for pathMapping output)
187
+ const patternMatchedFiles = new Map();
188
+ for (const filePath of normalizedPaths) {
189
+ let matchedAnyPattern = false;
190
+ for (const rule of PATTERN_RULES) {
191
+ if (rule.matches(filePath)) {
192
+ matchedAnyPattern = true;
193
+ if (!patternMatchedFiles.has(rule.pattern)) {
194
+ patternMatchedFiles.set(rule.pattern, []);
195
+ }
196
+ patternMatchedFiles.get(rule.pattern).push(filePath);
197
+ for (const bundleId of rule.bundles) {
198
+ if (!bundlePathsMap.has(bundleId)) {
199
+ bundlePathsMap.set(bundleId, new Set());
200
+ }
201
+ bundlePathsMap.get(bundleId).add(filePath);
202
+ }
203
+ }
204
+ }
205
+ if (!matchedAnyPattern) {
206
+ guardrailFiles.push(filePath);
207
+ }
208
+ }
209
+ // Apply guardrail bundles for unmatched files
210
+ if (guardrailFiles.length > 0) {
211
+ const guardrailPattern = "Guardrail (path não mapeado)";
212
+ patternMatchedFiles.set(guardrailPattern, guardrailFiles);
213
+ for (const bundleId of GUARDRAIL_BUNDLES) {
214
+ if (!bundlePathsMap.has(bundleId)) {
215
+ bundlePathsMap.set(bundleId, new Set());
216
+ }
217
+ for (const f of guardrailFiles) {
218
+ bundlePathsMap.get(bundleId).add(f);
219
+ }
220
+ }
221
+ }
222
+ // ---------------------------------------------------------------------------
223
+ // Build deduplicated bundlesToReview
224
+ // ---------------------------------------------------------------------------
225
+ const bundlesToReview = [];
226
+ for (const [chapterId, filesSet] of bundlePathsMap) {
227
+ const filesList = [...filesSet].sort();
228
+ const readableTitle = READABLE_TITLES[chapterId] ?? chapterId;
229
+ const category = BUNDLE_CATEGORIES[chapterId] ?? "domain";
230
+ const reason = filesList.length === 1
231
+ ? `Ficheiro "${filesList[0]}" despoleta revisão deste bundle.`
232
+ : `Ficheiros ${filesList.map((f) => `"${f}"`).join(", ")} despoletam revisão deste bundle.`;
233
+ const expectedEvidence = EXPECTED_EVIDENCE[chapterId] ?? [
234
+ "Verificar impacto das mudanças neste bundle."
235
+ ];
236
+ bundlesToReview.push({ chapterId, readableTitle, category, reason, expectedEvidence });
237
+ }
238
+ // Sort by category then chapterId for deterministic output
239
+ bundlesToReview.sort((a, b) => {
240
+ const catOrder = { foundation: 0, domain: 1, operational: 2 };
241
+ const catDiff = catOrder[a.category] - catOrder[b.category];
242
+ return catDiff !== 0 ? catDiff : a.chapterId.localeCompare(b.chapterId);
243
+ });
244
+ // ---------------------------------------------------------------------------
245
+ // Build pathMapping
246
+ // ---------------------------------------------------------------------------
247
+ const pathMapping = [];
248
+ for (const [pattern, matchedFiles] of patternMatchedFiles) {
249
+ // Collect bundles for this pattern
250
+ const bundlesForPattern = new Set();
251
+ for (const rule of PATTERN_RULES) {
252
+ if (rule.pattern === pattern) {
253
+ for (const b of rule.bundles)
254
+ bundlesForPattern.add(b);
255
+ }
256
+ }
257
+ // For guardrail pattern
258
+ if (pattern === "Guardrail (path não mapeado)") {
259
+ for (const b of GUARDRAIL_BUNDLES)
260
+ bundlesForPattern.add(b);
261
+ }
262
+ pathMapping.push({
263
+ pattern,
264
+ matchedFiles: [...matchedFiles].sort(),
265
+ bundles: [...bundlesForPattern].sort()
266
+ });
267
+ }
268
+ // ---------------------------------------------------------------------------
269
+ // Build nextSteps
270
+ // ---------------------------------------------------------------------------
271
+ const foundationIds = bundlesToReview
272
+ .filter((b) => b.category === "foundation")
273
+ .map((b) => b.chapterId);
274
+ const domainIds = bundlesToReview
275
+ .filter((b) => b.category === "domain")
276
+ .map((b) => b.chapterId);
277
+ const operationalIds = bundlesToReview
278
+ .filter((b) => b.category === "operational")
279
+ .map((b) => b.chapterId);
280
+ const nextSteps = [];
281
+ if (foundationIds.length > 0) {
282
+ nextSteps.push(`Rever bundles fundacionais: ${foundationIds.join(", ")} — assegurar que a classificação e requisitos de segurança estão actualizados.`);
283
+ }
284
+ if (domainIds.length > 0) {
285
+ nextSteps.push(`Rever bundles de domínio: ${domainIds.join(", ")} — validar que as práticas de segurança específicas foram aplicadas.`);
286
+ }
287
+ if (operationalIds.length > 0) {
288
+ nextSteps.push(`Rever bundles operacionais: ${operationalIds.join(", ")} — confirmar que processos operacionais de segurança estão actualizados.`);
289
+ }
290
+ if (riskLevel === "L2" || riskLevel === "L3") {
291
+ nextSteps.push(`Para nível ${riskLevel}: executar testes de segurança automatizados (SAST/DAST) antes do merge.`);
292
+ }
293
+ if (riskLevel === "L3") {
294
+ nextSteps.push("Para nível L3: obter aprovação formal do responsável de segurança antes do deploy.");
295
+ }
296
+ nextSteps.push(`Usar get_sbd_toe_chapter_brief(chapterId) para obter detalhe de cada bundle activado.`);
297
+ return { bundlesToReview, pathMapping, nextSteps };
298
+ }
299
+ //# sourceMappingURL=map-review-scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map-review-scope.js","sourceRoot":"","sources":["../../src/tools/map-review-scope.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,204 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { handleMapSbdToeReviewScope } from "./map-review-scope.js";
3
+ // ---------------------------------------------------------------------------
4
+ // Helpers
5
+ // ---------------------------------------------------------------------------
6
+ function call(args) {
7
+ return handleMapSbdToeReviewScope(args);
8
+ }
9
+ function bundleIds(result) {
10
+ return result.bundlesToReview.map((b) => b.chapterId);
11
+ }
12
+ // ---------------------------------------------------------------------------
13
+ // Validation — path traversal & input errors
14
+ // ---------------------------------------------------------------------------
15
+ describe("handleMapSbdToeReviewScope — validation", () => {
16
+ it("throws rpcError -32602 for path with '..'", () => {
17
+ let err;
18
+ try {
19
+ call({ changedFiles: ["../etc/passwd"], riskLevel: "L1" });
20
+ }
21
+ catch (e) {
22
+ err = e;
23
+ }
24
+ expect(err).toBeInstanceOf(Error);
25
+ expect(err.rpcError?.code).toBe(-32602);
26
+ expect(err.message).toContain("..");
27
+ });
28
+ it("throws rpcError -32602 for path with embedded '..'", () => {
29
+ let err;
30
+ try {
31
+ call({ changedFiles: ["src/../config.ts"], riskLevel: "L1" });
32
+ }
33
+ catch (e) {
34
+ err = e;
35
+ }
36
+ expect(err).toBeInstanceOf(Error);
37
+ expect(err.rpcError?.code).toBe(-32602);
38
+ });
39
+ it("throws rpcError -32602 for empty changedFiles array", () => {
40
+ let err;
41
+ try {
42
+ call({ changedFiles: [], riskLevel: "L1" });
43
+ }
44
+ catch (e) {
45
+ err = e;
46
+ }
47
+ expect(err).toBeInstanceOf(Error);
48
+ expect(err.rpcError?.code).toBe(-32602);
49
+ });
50
+ it("throws rpcError -32602 for invalid riskLevel", () => {
51
+ let err;
52
+ try {
53
+ call({ changedFiles: ["src/index.ts"], riskLevel: "L9" });
54
+ }
55
+ catch (e) {
56
+ err = e;
57
+ }
58
+ expect(err).toBeInstanceOf(Error);
59
+ expect(err.rpcError?.code).toBe(-32602);
60
+ });
61
+ it("throws rpcError -32602 when changedFiles is missing", () => {
62
+ let err;
63
+ try {
64
+ call({ riskLevel: "L1" });
65
+ }
66
+ catch (e) {
67
+ err = e;
68
+ }
69
+ expect(err).toBeInstanceOf(Error);
70
+ expect(err.rpcError?.code).toBe(-32602);
71
+ });
72
+ });
73
+ // ---------------------------------------------------------------------------
74
+ // Path mapping
75
+ // ---------------------------------------------------------------------------
76
+ describe("handleMapSbdToeReviewScope — path mapping", () => {
77
+ it("src/index.ts + .github/workflows/ci.yml (L2) → 06-desenvolvimento-seguro and 07-cicd-seguro", () => {
78
+ const result = call({
79
+ changedFiles: ["src/index.ts", ".github/workflows/ci.yml"],
80
+ riskLevel: "L2"
81
+ });
82
+ const ids = bundleIds(result);
83
+ expect(ids).toContain("06-desenvolvimento-seguro");
84
+ expect(ids).toContain("07-cicd-seguro");
85
+ });
86
+ it("package.json (L1) → 05-dependencias-sbom-sca", () => {
87
+ const result = call({ changedFiles: ["package.json"], riskLevel: "L1" });
88
+ expect(bundleIds(result)).toContain("05-dependencias-sbom-sca");
89
+ });
90
+ it("src/config.ts → includes 08-iac-infraestrutura (specific rule)", () => {
91
+ const result = call({ changedFiles: ["src/config.ts"], riskLevel: "L1" });
92
+ expect(bundleIds(result)).toContain("08-iac-infraestrutura");
93
+ });
94
+ it("docs/readme.md → 14-governanca-contratacao", () => {
95
+ const result = call({ changedFiles: ["docs/readme.md"], riskLevel: "L1" });
96
+ expect(bundleIds(result)).toContain("14-governanca-contratacao");
97
+ });
98
+ it("yarn.lock → 05-dependencias-sbom-sca", () => {
99
+ const result = call({ changedFiles: ["yarn.lock"], riskLevel: "L1" });
100
+ expect(bundleIds(result)).toContain("05-dependencias-sbom-sca");
101
+ });
102
+ it("release/v1.0.tar.gz → 11-deploy-seguro", () => {
103
+ const result = call({ changedFiles: ["release/v1.0.tar.gz"], riskLevel: "L1" });
104
+ expect(bundleIds(result)).toContain("11-deploy-seguro");
105
+ });
106
+ it(".github/skills/sbd-toe-skill/SKILL.md → 13-formacao-onboarding and 14-governanca-contratacao", () => {
107
+ const result = call({ changedFiles: [".github/skills/sbd-toe-skill/SKILL.md"], riskLevel: "L1" });
108
+ const ids = bundleIds(result);
109
+ expect(ids).toContain("13-formacao-onboarding");
110
+ expect(ids).toContain("14-governanca-contratacao");
111
+ });
112
+ it("unmapped path triggers guardrail bundles", () => {
113
+ const result = call({ changedFiles: ["random/unknown/file.txt"], riskLevel: "L1" });
114
+ const ids = bundleIds(result);
115
+ expect(ids).toContain("01-classificacao-aplicacoes");
116
+ expect(ids).toContain("02-requisitos-seguranca");
117
+ });
118
+ });
119
+ // ---------------------------------------------------------------------------
120
+ // Deduplication
121
+ // ---------------------------------------------------------------------------
122
+ describe("handleMapSbdToeReviewScope — deduplication", () => {
123
+ it("bundle activated by multiple paths appears only once", () => {
124
+ const result = call({
125
+ changedFiles: ["src/index.ts", "src/config.ts", "src/tools/structured-tools.ts"],
126
+ riskLevel: "L1"
127
+ });
128
+ const ids = bundleIds(result);
129
+ const uniqueIds = new Set(ids);
130
+ expect(ids.length).toBe(uniqueIds.size);
131
+ });
132
+ it("reason mentions multiple files when applicable", () => {
133
+ const result = call({
134
+ changedFiles: ["src/index.ts", "src/tools/structured-tools.ts"],
135
+ riskLevel: "L1"
136
+ });
137
+ const devBundle = result.bundlesToReview.find((b) => b.chapterId === "06-desenvolvimento-seguro");
138
+ expect(devBundle).toBeDefined();
139
+ // reason should mention both files
140
+ expect(devBundle?.reason).toContain("src/index.ts");
141
+ expect(devBundle?.reason).toContain("src/tools/structured-tools.ts");
142
+ });
143
+ });
144
+ // ---------------------------------------------------------------------------
145
+ // Output structure
146
+ // ---------------------------------------------------------------------------
147
+ describe("handleMapSbdToeReviewScope — output structure", () => {
148
+ it("each bundle entry has required fields", () => {
149
+ const result = call({
150
+ changedFiles: ["src/index.ts", "package.json"],
151
+ riskLevel: "L2"
152
+ });
153
+ for (const bundle of result.bundlesToReview) {
154
+ expect(typeof bundle.chapterId).toBe("string");
155
+ expect(typeof bundle.readableTitle).toBe("string");
156
+ expect(["foundation", "domain", "operational"]).toContain(bundle.category);
157
+ expect(typeof bundle.reason).toBe("string");
158
+ expect(bundle.expectedEvidence.length).toBeGreaterThan(0);
159
+ }
160
+ });
161
+ it("pathMapping covers matched patterns", () => {
162
+ const result = call({
163
+ changedFiles: ["src/index.ts", ".github/workflows/ci.yml", "package.json"],
164
+ riskLevel: "L1"
165
+ });
166
+ expect(result.pathMapping.length).toBeGreaterThanOrEqual(3);
167
+ });
168
+ it("nextSteps is non-empty", () => {
169
+ const result = call({ changedFiles: ["src/index.ts"], riskLevel: "L1" });
170
+ expect(result.nextSteps.length).toBeGreaterThan(0);
171
+ });
172
+ it("nextSteps mentions L2+ security tests for L2", () => {
173
+ const result = call({ changedFiles: ["src/index.ts"], riskLevel: "L2" });
174
+ const hasL2Step = result.nextSteps.some((s) => s.includes("L2") && s.includes("SAST"));
175
+ expect(hasL2Step).toBe(true);
176
+ });
177
+ it("nextSteps mentions L3 approval for L3", () => {
178
+ const result = call({ changedFiles: ["src/index.ts"], riskLevel: "L3" });
179
+ const hasL3Step = result.nextSteps.some((s) => s.includes("L3") && s.includes("aprovação"));
180
+ expect(hasL3Step).toBe(true);
181
+ });
182
+ });
183
+ // ---------------------------------------------------------------------------
184
+ // Cross-platform paths
185
+ // ---------------------------------------------------------------------------
186
+ describe("handleMapSbdToeReviewScope — cross-platform paths", () => {
187
+ it("normalizes Windows-style backslashes before matching", () => {
188
+ const result = call({
189
+ changedFiles: ["src\\index.ts"],
190
+ riskLevel: "L1"
191
+ });
192
+ expect(bundleIds(result)).toContain("06-desenvolvimento-seguro");
193
+ });
194
+ });
195
+ // ---------------------------------------------------------------------------
196
+ // diffSummary truncation
197
+ // ---------------------------------------------------------------------------
198
+ describe("handleMapSbdToeReviewScope — diffSummary", () => {
199
+ it("accepts diffSummary without error, truncated silently", () => {
200
+ const longSummary = "x".repeat(1000);
201
+ expect(() => call({ changedFiles: ["src/index.ts"], riskLevel: "L1", diffSummary: longSummary })).not.toThrow();
202
+ });
203
+ });
204
+ //# sourceMappingURL=map-review-scope.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map-review-scope.test.js","sourceRoot":"","sources":["../../src/tools/map-review-scope.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ declare const VALID_RISK_LEVELS: readonly ["L1", "L2", "L3"];
2
+ declare const VALID_SCALES: readonly ["startup", "mid-size", "enterprise"];
3
+ declare const VALID_ENFORCEMENT_LEVELS: readonly ["advisory", "enforced", "strict"];
4
+ type RiskLevel = (typeof VALID_RISK_LEVELS)[number];
5
+ type Scale = (typeof VALID_SCALES)[number];
6
+ type EnforcementLevel = (typeof VALID_ENFORCEMENT_LEVELS)[number];
7
+ type ControlCategory = "access" | "code-quality" | "supply-chain" | "secrets" | "ci-cd" | "audit";
8
+ interface Control {
9
+ controlId: string;
10
+ description: string;
11
+ category: ControlCategory;
12
+ rationale: string;
13
+ }
14
+ interface BaselineCheckpoint {
15
+ phase: string;
16
+ actions: string[];
17
+ tooling?: string[];
18
+ }
19
+ interface EvidenceItem {
20
+ item: string;
21
+ category: string;
22
+ requiredFor: RiskLevel[];
23
+ }
24
+ interface Gap {
25
+ area: string;
26
+ risk: string;
27
+ mitigation: string;
28
+ }
29
+ export declare function handlePlanRepoGovernance(args: Record<string, unknown>): {
30
+ applicableControls: Control[];
31
+ mandatoryControls: string[];
32
+ recommendedControls: string[];
33
+ baselineCheckpoints: BaselineCheckpoint[];
34
+ evidenceChecklist: EvidenceItem[];
35
+ gaps: Gap[];
36
+ platformSpecific: {
37
+ recommendations: string;
38
+ };
39
+ };
40
+ export type { Control, BaselineCheckpoint, EvidenceItem, Gap };
41
+ export type { Scale, EnforcementLevel };