@oculum/scanner 1.0.9 → 1.0.11
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/dist/baseline/diff.d.ts +32 -0
- package/dist/baseline/diff.d.ts.map +1 -0
- package/dist/baseline/diff.js +119 -0
- package/dist/baseline/diff.js.map +1 -0
- package/dist/baseline/index.d.ts +9 -0
- package/dist/baseline/index.d.ts.map +1 -0
- package/dist/baseline/index.js +19 -0
- package/dist/baseline/index.js.map +1 -0
- package/dist/baseline/manager.d.ts +67 -0
- package/dist/baseline/manager.d.ts.map +1 -0
- package/dist/baseline/manager.js +180 -0
- package/dist/baseline/manager.js.map +1 -0
- package/dist/baseline/types.d.ts +91 -0
- package/dist/baseline/types.d.ts.map +1 -0
- package/dist/baseline/types.js +12 -0
- package/dist/baseline/types.js.map +1 -0
- package/dist/formatters/cli-terminal.d.ts +38 -0
- package/dist/formatters/cli-terminal.d.ts.map +1 -1
- package/dist/formatters/cli-terminal.js +365 -42
- package/dist/formatters/cli-terminal.js.map +1 -1
- package/dist/formatters/github-comment.d.ts +1 -1
- package/dist/formatters/github-comment.d.ts.map +1 -1
- package/dist/formatters/github-comment.js +75 -11
- package/dist/formatters/github-comment.js.map +1 -1
- package/dist/formatters/index.d.ts +1 -1
- package/dist/formatters/index.d.ts.map +1 -1
- package/dist/formatters/index.js +4 -1
- package/dist/formatters/index.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +155 -16
- package/dist/index.js.map +1 -1
- package/dist/layer1/config-audit.d.ts.map +1 -1
- package/dist/layer1/config-audit.js +20 -3
- package/dist/layer1/config-audit.js.map +1 -1
- package/dist/layer1/config-mcp-audit.d.ts +20 -0
- package/dist/layer1/config-mcp-audit.d.ts.map +1 -0
- package/dist/layer1/config-mcp-audit.js +239 -0
- package/dist/layer1/config-mcp-audit.js.map +1 -0
- package/dist/layer1/index.d.ts +1 -0
- package/dist/layer1/index.d.ts.map +1 -1
- package/dist/layer1/index.js +9 -1
- package/dist/layer1/index.js.map +1 -1
- package/dist/layer2/ai-agent-tools.d.ts.map +1 -1
- package/dist/layer2/ai-agent-tools.js +303 -0
- package/dist/layer2/ai-agent-tools.js.map +1 -1
- package/dist/layer2/ai-endpoint-protection.d.ts.map +1 -1
- package/dist/layer2/ai-endpoint-protection.js +17 -3
- package/dist/layer2/ai-endpoint-protection.js.map +1 -1
- package/dist/layer2/ai-execution-sinks.d.ts.map +1 -1
- package/dist/layer2/ai-execution-sinks.js +462 -12
- package/dist/layer2/ai-execution-sinks.js.map +1 -1
- package/dist/layer2/ai-fingerprinting.d.ts.map +1 -1
- package/dist/layer2/ai-fingerprinting.js +3 -0
- package/dist/layer2/ai-fingerprinting.js.map +1 -1
- package/dist/layer2/ai-mcp-security.d.ts +17 -0
- package/dist/layer2/ai-mcp-security.d.ts.map +1 -0
- package/dist/layer2/ai-mcp-security.js +679 -0
- package/dist/layer2/ai-mcp-security.js.map +1 -0
- package/dist/layer2/ai-package-hallucination.d.ts +19 -0
- package/dist/layer2/ai-package-hallucination.d.ts.map +1 -0
- package/dist/layer2/ai-package-hallucination.js +696 -0
- package/dist/layer2/ai-package-hallucination.js.map +1 -0
- package/dist/layer2/ai-prompt-hygiene.d.ts.map +1 -1
- package/dist/layer2/ai-prompt-hygiene.js +495 -9
- package/dist/layer2/ai-prompt-hygiene.js.map +1 -1
- package/dist/layer2/ai-rag-safety.d.ts.map +1 -1
- package/dist/layer2/ai-rag-safety.js +372 -1
- package/dist/layer2/ai-rag-safety.js.map +1 -1
- package/dist/layer2/auth-antipatterns.d.ts.map +1 -1
- package/dist/layer2/auth-antipatterns.js +4 -0
- package/dist/layer2/auth-antipatterns.js.map +1 -1
- package/dist/layer2/byok-patterns.d.ts.map +1 -1
- package/dist/layer2/byok-patterns.js +3 -0
- package/dist/layer2/byok-patterns.js.map +1 -1
- package/dist/layer2/dangerous-functions/child-process.d.ts +16 -0
- package/dist/layer2/dangerous-functions/child-process.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/child-process.js +74 -0
- package/dist/layer2/dangerous-functions/child-process.js.map +1 -0
- package/dist/layer2/dangerous-functions/dom-xss.d.ts +29 -0
- package/dist/layer2/dangerous-functions/dom-xss.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/dom-xss.js +179 -0
- package/dist/layer2/dangerous-functions/dom-xss.js.map +1 -0
- package/dist/layer2/dangerous-functions/index.d.ts +13 -0
- package/dist/layer2/dangerous-functions/index.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/index.js +621 -0
- package/dist/layer2/dangerous-functions/index.js.map +1 -0
- package/dist/layer2/dangerous-functions/json-parse.d.ts +31 -0
- package/dist/layer2/dangerous-functions/json-parse.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/json-parse.js +319 -0
- package/dist/layer2/dangerous-functions/json-parse.js.map +1 -0
- package/dist/layer2/dangerous-functions/math-random.d.ts +61 -0
- package/dist/layer2/dangerous-functions/math-random.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/math-random.js +459 -0
- package/dist/layer2/dangerous-functions/math-random.js.map +1 -0
- package/dist/layer2/dangerous-functions/patterns.d.ts +21 -0
- package/dist/layer2/dangerous-functions/patterns.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/patterns.js +161 -0
- package/dist/layer2/dangerous-functions/patterns.js.map +1 -0
- package/dist/layer2/dangerous-functions/request-validation.d.ts +13 -0
- package/dist/layer2/dangerous-functions/request-validation.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/request-validation.js +119 -0
- package/dist/layer2/dangerous-functions/request-validation.js.map +1 -0
- package/dist/layer2/dangerous-functions/utils/control-flow.d.ts +23 -0
- package/dist/layer2/dangerous-functions/utils/control-flow.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/utils/control-flow.js +149 -0
- package/dist/layer2/dangerous-functions/utils/control-flow.js.map +1 -0
- package/dist/layer2/dangerous-functions/utils/helpers.d.ts +31 -0
- package/dist/layer2/dangerous-functions/utils/helpers.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/utils/helpers.js +124 -0
- package/dist/layer2/dangerous-functions/utils/helpers.js.map +1 -0
- package/dist/layer2/dangerous-functions/utils/index.d.ts +9 -0
- package/dist/layer2/dangerous-functions/utils/index.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/utils/index.js +23 -0
- package/dist/layer2/dangerous-functions/utils/index.js.map +1 -0
- package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts +22 -0
- package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/utils/schema-validation.js +89 -0
- package/dist/layer2/dangerous-functions/utils/schema-validation.js.map +1 -0
- package/dist/layer2/data-exposure.d.ts.map +1 -1
- package/dist/layer2/data-exposure.js +3 -0
- package/dist/layer2/data-exposure.js.map +1 -1
- package/dist/layer2/framework-checks.d.ts.map +1 -1
- package/dist/layer2/framework-checks.js +3 -0
- package/dist/layer2/framework-checks.js.map +1 -1
- package/dist/layer2/index.d.ts +3 -0
- package/dist/layer2/index.d.ts.map +1 -1
- package/dist/layer2/index.js +61 -2
- package/dist/layer2/index.js.map +1 -1
- package/dist/layer2/logic-gates.d.ts.map +1 -1
- package/dist/layer2/logic-gates.js +4 -0
- package/dist/layer2/logic-gates.js.map +1 -1
- package/dist/layer2/model-supply-chain.d.ts +20 -0
- package/dist/layer2/model-supply-chain.d.ts.map +1 -0
- package/dist/layer2/model-supply-chain.js +376 -0
- package/dist/layer2/model-supply-chain.js.map +1 -0
- package/dist/layer2/risky-imports.d.ts.map +1 -1
- package/dist/layer2/risky-imports.js +4 -0
- package/dist/layer2/risky-imports.js.map +1 -1
- package/dist/layer2/variables.d.ts.map +1 -1
- package/dist/layer2/variables.js +4 -0
- package/dist/layer2/variables.js.map +1 -1
- package/dist/layer3/anthropic/auto-dismiss.d.ts +24 -0
- package/dist/layer3/anthropic/auto-dismiss.d.ts.map +1 -0
- package/dist/layer3/anthropic/auto-dismiss.js +188 -0
- package/dist/layer3/anthropic/auto-dismiss.js.map +1 -0
- package/dist/layer3/anthropic/clients.d.ts +44 -0
- package/dist/layer3/anthropic/clients.d.ts.map +1 -0
- package/dist/layer3/anthropic/clients.js +81 -0
- package/dist/layer3/anthropic/clients.js.map +1 -0
- package/dist/layer3/anthropic/index.d.ts +41 -0
- package/dist/layer3/anthropic/index.d.ts.map +1 -0
- package/dist/layer3/anthropic/index.js +141 -0
- package/dist/layer3/anthropic/index.js.map +1 -0
- package/dist/layer3/anthropic/prompts/index.d.ts +8 -0
- package/dist/layer3/anthropic/prompts/index.d.ts.map +1 -0
- package/dist/layer3/anthropic/prompts/index.js +14 -0
- package/dist/layer3/anthropic/prompts/index.js.map +1 -0
- package/dist/layer3/anthropic/prompts/semantic-analysis.d.ts +15 -0
- package/dist/layer3/anthropic/prompts/semantic-analysis.d.ts.map +1 -0
- package/dist/layer3/anthropic/prompts/semantic-analysis.js +169 -0
- package/dist/layer3/anthropic/prompts/semantic-analysis.js.map +1 -0
- package/dist/layer3/anthropic/prompts/validation.d.ts +12 -0
- package/dist/layer3/anthropic/prompts/validation.d.ts.map +1 -0
- package/dist/layer3/anthropic/prompts/validation.js +421 -0
- package/dist/layer3/anthropic/prompts/validation.js.map +1 -0
- package/dist/layer3/anthropic/providers/anthropic.d.ts +21 -0
- package/dist/layer3/anthropic/providers/anthropic.d.ts.map +1 -0
- package/dist/layer3/anthropic/providers/anthropic.js +266 -0
- package/dist/layer3/anthropic/providers/anthropic.js.map +1 -0
- package/dist/layer3/anthropic/providers/index.d.ts +8 -0
- package/dist/layer3/anthropic/providers/index.d.ts.map +1 -0
- package/dist/layer3/anthropic/providers/index.js +15 -0
- package/dist/layer3/anthropic/providers/index.js.map +1 -0
- package/dist/layer3/anthropic/providers/openai.d.ts +18 -0
- package/dist/layer3/anthropic/providers/openai.d.ts.map +1 -0
- package/dist/layer3/anthropic/providers/openai.js +340 -0
- package/dist/layer3/anthropic/providers/openai.js.map +1 -0
- package/dist/layer3/anthropic/request-builder.d.ts +20 -0
- package/dist/layer3/anthropic/request-builder.d.ts.map +1 -0
- package/dist/layer3/anthropic/request-builder.js +134 -0
- package/dist/layer3/anthropic/request-builder.js.map +1 -0
- package/dist/layer3/anthropic/types.d.ts +88 -0
- package/dist/layer3/anthropic/types.d.ts.map +1 -0
- package/dist/layer3/anthropic/types.js +38 -0
- package/dist/layer3/anthropic/types.js.map +1 -0
- package/dist/layer3/anthropic/utils/index.d.ts +9 -0
- package/dist/layer3/anthropic/utils/index.d.ts.map +1 -0
- package/dist/layer3/anthropic/utils/index.js +24 -0
- package/dist/layer3/anthropic/utils/index.js.map +1 -0
- package/dist/layer3/anthropic/utils/path-helpers.d.ts +21 -0
- package/dist/layer3/anthropic/utils/path-helpers.d.ts.map +1 -0
- package/dist/layer3/anthropic/utils/path-helpers.js +69 -0
- package/dist/layer3/anthropic/utils/path-helpers.js.map +1 -0
- package/dist/layer3/anthropic/utils/response-parser.d.ts +40 -0
- package/dist/layer3/anthropic/utils/response-parser.d.ts.map +1 -0
- package/dist/layer3/anthropic/utils/response-parser.js +285 -0
- package/dist/layer3/anthropic/utils/response-parser.js.map +1 -0
- package/dist/layer3/anthropic/utils/retry.d.ts +15 -0
- package/dist/layer3/anthropic/utils/retry.d.ts.map +1 -0
- package/dist/layer3/anthropic/utils/retry.js +62 -0
- package/dist/layer3/anthropic/utils/retry.js.map +1 -0
- package/dist/layer3/index.d.ts +1 -0
- package/dist/layer3/index.d.ts.map +1 -1
- package/dist/layer3/index.js +16 -6
- package/dist/layer3/index.js.map +1 -1
- package/dist/layer3/osv-check.d.ts +75 -0
- package/dist/layer3/osv-check.d.ts.map +1 -0
- package/dist/layer3/osv-check.js +308 -0
- package/dist/layer3/osv-check.js.map +1 -0
- package/dist/rules/framework-fixes.d.ts +48 -0
- package/dist/rules/framework-fixes.d.ts.map +1 -0
- package/dist/rules/framework-fixes.js +439 -0
- package/dist/rules/framework-fixes.js.map +1 -0
- package/dist/rules/index.d.ts +8 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +18 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/metadata.d.ts +43 -0
- package/dist/rules/metadata.d.ts.map +1 -0
- package/dist/rules/metadata.js +734 -0
- package/dist/rules/metadata.js.map +1 -0
- package/dist/suppression/config-loader.d.ts +74 -0
- package/dist/suppression/config-loader.d.ts.map +1 -0
- package/dist/suppression/config-loader.js +424 -0
- package/dist/suppression/config-loader.js.map +1 -0
- package/dist/suppression/hash.d.ts +48 -0
- package/dist/suppression/hash.d.ts.map +1 -0
- package/dist/suppression/hash.js +88 -0
- package/dist/suppression/hash.js.map +1 -0
- package/dist/suppression/index.d.ts +11 -0
- package/dist/suppression/index.d.ts.map +1 -0
- package/dist/suppression/index.js +39 -0
- package/dist/suppression/index.js.map +1 -0
- package/dist/suppression/inline-parser.d.ts +39 -0
- package/dist/suppression/inline-parser.d.ts.map +1 -0
- package/dist/suppression/inline-parser.js +218 -0
- package/dist/suppression/inline-parser.js.map +1 -0
- package/dist/suppression/manager.d.ts +94 -0
- package/dist/suppression/manager.d.ts.map +1 -0
- package/dist/suppression/manager.js +292 -0
- package/dist/suppression/manager.js.map +1 -0
- package/dist/suppression/types.d.ts +151 -0
- package/dist/suppression/types.d.ts.map +1 -0
- package/dist/suppression/types.js +28 -0
- package/dist/suppression/types.js.map +1 -0
- package/dist/tiers.d.ts +1 -1
- package/dist/tiers.d.ts.map +1 -1
- package/dist/tiers.js +27 -0
- package/dist/tiers.js.map +1 -1
- package/dist/types.d.ts +62 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/context-helpers.d.ts +4 -0
- package/dist/utils/context-helpers.d.ts.map +1 -1
- package/dist/utils/context-helpers.js +13 -9
- package/dist/utils/context-helpers.js.map +1 -1
- package/package.json +4 -2
- package/src/__tests__/benchmark/fixtures/layer1/mcp-config-audit.json +31 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-execution-sinks.ts +1489 -82
- package/src/__tests__/benchmark/fixtures/layer2/ai-mcp-security.ts +495 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-package-hallucination.ts +255 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-prompt-hygiene.ts +300 -1
- package/src/__tests__/benchmark/fixtures/layer2/ai-rag-safety.ts +139 -0
- package/src/__tests__/benchmark/fixtures/layer2/byok-patterns.ts +7 -0
- package/src/__tests__/benchmark/fixtures/layer2/data-exposure.ts +63 -0
- package/src/__tests__/benchmark/fixtures/layer2/excessive-agency.ts +221 -0
- package/src/__tests__/benchmark/fixtures/layer2/index.ts +18 -0
- package/src/__tests__/benchmark/fixtures/layer2/model-supply-chain.ts +204 -0
- package/src/__tests__/benchmark/fixtures/layer2/phase1-enhancements.ts +157 -0
- package/src/__tests__/snapshots/__snapshots__/anthropic-validation-refactor.test.ts.snap +758 -0
- package/src/__tests__/snapshots/__snapshots__/dangerous-functions-refactor.test.ts.snap +503 -0
- package/src/__tests__/snapshots/anthropic-validation-refactor.test.ts +321 -0
- package/src/__tests__/snapshots/dangerous-functions-refactor.test.ts +439 -0
- package/src/baseline/__tests__/diff.test.ts +261 -0
- package/src/baseline/__tests__/manager.test.ts +225 -0
- package/src/baseline/diff.ts +135 -0
- package/src/baseline/index.ts +29 -0
- package/src/baseline/manager.ts +230 -0
- package/src/baseline/types.ts +97 -0
- package/src/formatters/cli-terminal.ts +444 -41
- package/src/formatters/github-comment.ts +79 -11
- package/src/formatters/index.ts +4 -0
- package/src/index.ts +197 -14
- package/src/layer1/config-audit.ts +24 -3
- package/src/layer1/config-mcp-audit.ts +276 -0
- package/src/layer1/index.ts +16 -6
- package/src/layer2/ai-agent-tools.ts +336 -0
- package/src/layer2/ai-endpoint-protection.ts +16 -3
- package/src/layer2/ai-execution-sinks.ts +516 -12
- package/src/layer2/ai-fingerprinting.ts +5 -1
- package/src/layer2/ai-mcp-security.ts +730 -0
- package/src/layer2/ai-package-hallucination.ts +791 -0
- package/src/layer2/ai-prompt-hygiene.ts +547 -9
- package/src/layer2/ai-rag-safety.ts +382 -3
- package/src/layer2/auth-antipatterns.ts +5 -0
- package/src/layer2/byok-patterns.ts +5 -1
- package/src/layer2/dangerous-functions/child-process.ts +98 -0
- package/src/layer2/dangerous-functions/dom-xss.ts +220 -0
- package/src/layer2/dangerous-functions/index.ts +949 -0
- package/src/layer2/dangerous-functions/json-parse.ts +385 -0
- package/src/layer2/dangerous-functions/math-random.ts +537 -0
- package/src/layer2/dangerous-functions/patterns.ts +174 -0
- package/src/layer2/dangerous-functions/request-validation.ts +145 -0
- package/src/layer2/dangerous-functions/utils/control-flow.ts +162 -0
- package/src/layer2/dangerous-functions/utils/helpers.ts +170 -0
- package/src/layer2/dangerous-functions/utils/index.ts +25 -0
- package/src/layer2/dangerous-functions/utils/schema-validation.ts +91 -0
- package/src/layer2/data-exposure.ts +5 -1
- package/src/layer2/framework-checks.ts +5 -0
- package/src/layer2/index.ts +63 -1
- package/src/layer2/logic-gates.ts +5 -0
- package/src/layer2/model-supply-chain.ts +456 -0
- package/src/layer2/risky-imports.ts +5 -0
- package/src/layer2/variables.ts +5 -0
- package/src/layer3/__tests__/osv-check.test.ts +384 -0
- package/src/layer3/anthropic/auto-dismiss.ts +212 -0
- package/src/layer3/anthropic/clients.ts +84 -0
- package/src/layer3/anthropic/index.ts +170 -0
- package/src/layer3/anthropic/prompts/index.ts +14 -0
- package/src/layer3/anthropic/prompts/semantic-analysis.ts +173 -0
- package/src/layer3/anthropic/prompts/validation.ts +419 -0
- package/src/layer3/anthropic/providers/anthropic.ts +310 -0
- package/src/layer3/anthropic/providers/index.ts +8 -0
- package/src/layer3/anthropic/providers/openai.ts +384 -0
- package/src/layer3/anthropic/request-builder.ts +150 -0
- package/src/layer3/anthropic/types.ts +148 -0
- package/src/layer3/anthropic/utils/index.ts +26 -0
- package/src/layer3/anthropic/utils/path-helpers.ts +68 -0
- package/src/layer3/anthropic/utils/response-parser.ts +322 -0
- package/src/layer3/anthropic/utils/retry.ts +75 -0
- package/src/layer3/index.ts +18 -5
- package/src/layer3/osv-check.ts +420 -0
- package/src/rules/__tests__/framework-fixes.test.ts +689 -0
- package/src/rules/__tests__/metadata.test.ts +218 -0
- package/src/rules/framework-fixes.ts +470 -0
- package/src/rules/index.ts +21 -0
- package/src/rules/metadata.ts +831 -0
- package/src/suppression/__tests__/config-loader.test.ts +382 -0
- package/src/suppression/__tests__/hash.test.ts +166 -0
- package/src/suppression/__tests__/inline-parser.test.ts +212 -0
- package/src/suppression/__tests__/manager.test.ts +415 -0
- package/src/suppression/config-loader.ts +462 -0
- package/src/suppression/hash.ts +95 -0
- package/src/suppression/index.ts +51 -0
- package/src/suppression/inline-parser.ts +273 -0
- package/src/suppression/manager.ts +379 -0
- package/src/suppression/types.ts +174 -0
- package/src/tiers.ts +36 -0
- package/src/types.ts +90 -0
- package/src/utils/context-helpers.ts +13 -9
- package/dist/layer2/dangerous-functions.d.ts +0 -7
- package/dist/layer2/dangerous-functions.d.ts.map +0 -1
- package/dist/layer2/dangerous-functions.js +0 -1701
- package/dist/layer2/dangerous-functions.js.map +0 -1
- package/dist/layer3/anthropic.d.ts +0 -87
- package/dist/layer3/anthropic.d.ts.map +0 -1
- package/dist/layer3/anthropic.js +0 -1948
- package/dist/layer3/anthropic.js.map +0 -1
- package/dist/layer3/openai.d.ts +0 -25
- package/dist/layer3/openai.d.ts.map +0 -1
- package/dist/layer3/openai.js +0 -238
- package/dist/layer3/openai.js.map +0 -1
- package/src/layer2/dangerous-functions.ts +0 -1940
- package/src/layer3/anthropic.ts +0 -2257
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OpenAI Provider Implementation
|
|
4
|
+
*
|
|
5
|
+
* Validation using OpenAI GPT-5-mini model.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.validateWithOpenAI = validateWithOpenAI;
|
|
9
|
+
exports.clearOpenAICache = clearOpenAICache;
|
|
10
|
+
const project_context_builder_1 = require("../../../utils/project-context-builder");
|
|
11
|
+
const types_1 = require("../types");
|
|
12
|
+
const clients_1 = require("../clients");
|
|
13
|
+
const retry_1 = require("../utils/retry");
|
|
14
|
+
const response_parser_1 = require("../utils/response-parser");
|
|
15
|
+
const request_builder_1 = require("../request-builder");
|
|
16
|
+
const validation_1 = require("../prompts/validation");
|
|
17
|
+
// Cache for project context (built once per scan)
|
|
18
|
+
let cachedProjectContext = null;
|
|
19
|
+
/**
|
|
20
|
+
* Validate findings using OpenAI GPT-5-mini
|
|
21
|
+
* This mirrors the Anthropic validation flow but uses OpenAI's API
|
|
22
|
+
*/
|
|
23
|
+
async function validateWithOpenAI(findings, files, projectContext, stats) {
|
|
24
|
+
const client = (0, clients_1.getOpenAIClient)();
|
|
25
|
+
// Build or use cached project context
|
|
26
|
+
const context = projectContext || cachedProjectContext || (0, project_context_builder_1.buildProjectContext)(files);
|
|
27
|
+
if (!projectContext && !cachedProjectContext) {
|
|
28
|
+
cachedProjectContext = context;
|
|
29
|
+
console.log('[OpenAI Validation] Built project context:', {
|
|
30
|
+
hasAuthMiddleware: context.auth.hasGlobalMiddleware,
|
|
31
|
+
authProvider: context.auth.authProvider,
|
|
32
|
+
orm: context.dataAccess.orm,
|
|
33
|
+
framework: context.frameworks.primary,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
// Group findings by file for efficient validation
|
|
37
|
+
const findingsByFile = new Map();
|
|
38
|
+
for (const finding of findings) {
|
|
39
|
+
const existing = findingsByFile.get(finding.filePath) || [];
|
|
40
|
+
existing.push(finding);
|
|
41
|
+
findingsByFile.set(finding.filePath, existing);
|
|
42
|
+
}
|
|
43
|
+
const validatedFindings = [];
|
|
44
|
+
const fileEntries = Array.from(findingsByFile.entries());
|
|
45
|
+
// Track metrics (thread-safe accumulator)
|
|
46
|
+
let totalApiBatches = 0;
|
|
47
|
+
const statsLock = (0, types_1.createStatsAccumulator)();
|
|
48
|
+
const totalFileBatches = Math.ceil(fileEntries.length / clients_1.FILES_PER_API_BATCH);
|
|
49
|
+
console.log(`[OpenAI Validation] Processing ${fileEntries.length} files in ${totalFileBatches} API batch(es) (${clients_1.PARALLEL_API_BATCHES} parallel)`);
|
|
50
|
+
// Create all batch definitions
|
|
51
|
+
const allBatches = [];
|
|
52
|
+
for (let batchStart = 0; batchStart < fileEntries.length; batchStart += clients_1.FILES_PER_API_BATCH) {
|
|
53
|
+
const fileBatch = fileEntries.slice(batchStart, batchStart + clients_1.FILES_PER_API_BATCH);
|
|
54
|
+
const batchNum = Math.floor(batchStart / clients_1.FILES_PER_API_BATCH) + 1;
|
|
55
|
+
allBatches.push({ batchNum, fileBatch });
|
|
56
|
+
}
|
|
57
|
+
// Process a single batch - returns validated findings for that batch
|
|
58
|
+
const processBatch = async (batchDef) => {
|
|
59
|
+
const { batchNum, fileBatch } = batchDef;
|
|
60
|
+
const batchFindings = [];
|
|
61
|
+
// Prepare file data for batch request
|
|
62
|
+
const fileDataList = [];
|
|
63
|
+
const filesWithoutContent = [];
|
|
64
|
+
for (const [filePath, fileFindings] of fileBatch) {
|
|
65
|
+
const file = files.find(f => f.path === filePath);
|
|
66
|
+
if (!file) {
|
|
67
|
+
filesWithoutContent.push({ filePath, findings: fileFindings });
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
fileDataList.push({ file, findings: fileFindings, filePath });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Handle files without content
|
|
74
|
+
for (const { findings: fileFindings } of filesWithoutContent) {
|
|
75
|
+
for (const f of fileFindings) {
|
|
76
|
+
batchFindings.push({
|
|
77
|
+
...f,
|
|
78
|
+
validatedByAI: false,
|
|
79
|
+
validationStatus: 'not_validated',
|
|
80
|
+
validationNotes: 'File content not available for validation',
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (fileDataList.length === 0) {
|
|
85
|
+
return batchFindings;
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
// Build multi-file validation request
|
|
89
|
+
const validationRequest = (0, request_builder_1.buildMultiFileValidationRequest)(fileDataList.map(({ file, findings: fileFindings }) => ({ file, findings: fileFindings })), context);
|
|
90
|
+
// Call OpenAI GPT-5-mini with retry logic
|
|
91
|
+
const response = await (0, retry_1.makeOpenAIRequestWithRetry)(async () => client.chat.completions.create({
|
|
92
|
+
model: 'gpt-5-mini-2025-08-07',
|
|
93
|
+
messages: [
|
|
94
|
+
{ role: 'system', content: validation_1.HIGH_CONTEXT_VALIDATION_PROMPT },
|
|
95
|
+
{ role: 'user', content: validationRequest },
|
|
96
|
+
],
|
|
97
|
+
max_completion_tokens: 4096, // Sufficient for larger batches with many findings
|
|
98
|
+
response_format: {
|
|
99
|
+
type: 'json_schema',
|
|
100
|
+
json_schema: {
|
|
101
|
+
name: 'validation_response',
|
|
102
|
+
strict: true,
|
|
103
|
+
schema: {
|
|
104
|
+
type: 'object',
|
|
105
|
+
properties: {
|
|
106
|
+
validations: {
|
|
107
|
+
type: 'array',
|
|
108
|
+
items: {
|
|
109
|
+
type: 'object',
|
|
110
|
+
properties: {
|
|
111
|
+
file: { type: 'string' },
|
|
112
|
+
validations: {
|
|
113
|
+
type: 'array',
|
|
114
|
+
items: {
|
|
115
|
+
type: 'object',
|
|
116
|
+
properties: {
|
|
117
|
+
index: { type: 'number' },
|
|
118
|
+
keep: { type: 'boolean' },
|
|
119
|
+
notes: {
|
|
120
|
+
type: ['string', 'null'],
|
|
121
|
+
default: null
|
|
122
|
+
},
|
|
123
|
+
adjustedSeverity: {
|
|
124
|
+
type: ['string', 'null'],
|
|
125
|
+
enum: ['critical', 'high', 'medium', 'low', 'info', null],
|
|
126
|
+
default: null
|
|
127
|
+
},
|
|
128
|
+
impact: {
|
|
129
|
+
type: ['string', 'null'],
|
|
130
|
+
description: 'Context-aware explanation of why this matters (1-2 sentences)',
|
|
131
|
+
default: null
|
|
132
|
+
},
|
|
133
|
+
fixSuggestion: {
|
|
134
|
+
type: ['string', 'null'],
|
|
135
|
+
description: 'Specific, actionable fix for this code context',
|
|
136
|
+
default: null
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
required: ['index', 'keep', 'notes', 'adjustedSeverity', 'impact', 'fixSuggestion'],
|
|
140
|
+
additionalProperties: false
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
required: ['file', 'validations'],
|
|
145
|
+
additionalProperties: false
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
required: ['validations'],
|
|
150
|
+
additionalProperties: false
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}));
|
|
155
|
+
// Track API call stats (accumulate to shared stats)
|
|
156
|
+
statsLock.apiCalls++;
|
|
157
|
+
// Extract token usage from OpenAI response
|
|
158
|
+
const usage = response.usage;
|
|
159
|
+
if (usage) {
|
|
160
|
+
const promptTokens = usage.prompt_tokens || 0;
|
|
161
|
+
const completionTokens = usage.completion_tokens || 0;
|
|
162
|
+
const cachedTokens = usage.prompt_tokens_details?.cached_tokens || 0;
|
|
163
|
+
const freshInputTokens = promptTokens - cachedTokens;
|
|
164
|
+
statsLock.estimatedInputTokens += freshInputTokens;
|
|
165
|
+
statsLock.estimatedOutputTokens += completionTokens;
|
|
166
|
+
statsLock.cacheReadTokens += cachedTokens;
|
|
167
|
+
console.log(`[OpenAI] Batch ${batchNum} tokens: ${promptTokens} input (${cachedTokens} cached), ${completionTokens} output`);
|
|
168
|
+
const freshCost = (freshInputTokens * clients_1.GPT5_MINI_PRICING.input) / 1000000;
|
|
169
|
+
const cachedCost = (cachedTokens * clients_1.GPT5_MINI_PRICING.cached) / 1000000;
|
|
170
|
+
const outputCost = (completionTokens * clients_1.GPT5_MINI_PRICING.output) / 1000000;
|
|
171
|
+
statsLock.estimatedCost += freshCost + cachedCost + outputCost;
|
|
172
|
+
}
|
|
173
|
+
// Parse response content
|
|
174
|
+
const content = response.choices[0]?.message?.content;
|
|
175
|
+
if (!content) {
|
|
176
|
+
for (const { findings: fileFindings } of fileDataList) {
|
|
177
|
+
for (const f of fileFindings) {
|
|
178
|
+
batchFindings.push({
|
|
179
|
+
...f,
|
|
180
|
+
validatedByAI: false,
|
|
181
|
+
validationStatus: 'not_validated',
|
|
182
|
+
validationNotes: 'No valid response from OpenAI',
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return batchFindings;
|
|
187
|
+
}
|
|
188
|
+
// Parse structured JSON response (with validations wrapper from response_format)
|
|
189
|
+
let parsedContent;
|
|
190
|
+
try {
|
|
191
|
+
parsedContent = JSON.parse(content);
|
|
192
|
+
console.log(`[OpenAI Debug] Raw parsed content keys:`, Object.keys(parsedContent));
|
|
193
|
+
// Unwrap the validations array if present (from structured output)
|
|
194
|
+
if (parsedContent.validations && Array.isArray(parsedContent.validations)) {
|
|
195
|
+
console.log(`[OpenAI Debug] Unwrapping 'validations' array with ${parsedContent.validations.length} items`);
|
|
196
|
+
parsedContent = parsedContent.validations;
|
|
197
|
+
}
|
|
198
|
+
else if (Array.isArray(parsedContent)) {
|
|
199
|
+
console.log(`[OpenAI Debug] Content is already an array with ${parsedContent.length} items`);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
console.log(`[OpenAI Debug] Content structure:`, typeof parsedContent, Array.isArray(parsedContent));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch (e) {
|
|
206
|
+
console.warn('[OpenAI] Failed to parse JSON response:', e);
|
|
207
|
+
parsedContent = content;
|
|
208
|
+
}
|
|
209
|
+
// Parse multi-file response
|
|
210
|
+
const expectedFiles = fileDataList.map(({ filePath }) => filePath);
|
|
211
|
+
const validationResultsMap = (0, response_parser_1.parseMultiFileValidationResponse)(typeof parsedContent === 'string' ? parsedContent : JSON.stringify(parsedContent), expectedFiles);
|
|
212
|
+
console.log(`[OpenAI] Batch ${batchNum} parsed ${validationResultsMap.size} file results from ${fileDataList.length} files`);
|
|
213
|
+
if (validationResultsMap.size === 0) {
|
|
214
|
+
console.warn(`[OpenAI] WARNING: No file results parsed! Content type: ${typeof parsedContent}, isArray: ${Array.isArray(parsedContent)}`);
|
|
215
|
+
if (Array.isArray(parsedContent) && parsedContent.length > 0) {
|
|
216
|
+
console.log(`[OpenAI] First item structure:`, Object.keys(parsedContent[0]));
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// Log any missing files from the response (these will be REJECTED)
|
|
220
|
+
if (validationResultsMap.size !== fileDataList.length) {
|
|
221
|
+
const missing = fileDataList
|
|
222
|
+
.filter(({ filePath }) => !validationResultsMap.has(filePath))
|
|
223
|
+
.map(({ filePath }) => filePath);
|
|
224
|
+
if (missing.length > 0) {
|
|
225
|
+
console.warn(`[OpenAI] Missing ${missing.length} files from response (will be REJECTED): ${missing.join(', ')}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// Apply results per file
|
|
229
|
+
for (const { filePath, findings: fileFindings } of fileDataList) {
|
|
230
|
+
const fileResults = validationResultsMap.get(filePath);
|
|
231
|
+
console.log(`[OpenAI] File ${filePath}: ${fileResults?.length || 0} validation results for ${fileFindings.length} findings`);
|
|
232
|
+
if (!fileResults || fileResults.length === 0) {
|
|
233
|
+
const singleFileResults = (0, response_parser_1.parseValidationResponse)(content);
|
|
234
|
+
if (singleFileResults.length > 0 && fileDataList.length === 1) {
|
|
235
|
+
const { processed: processedFindings, dismissedCount } = (0, response_parser_1.applyValidationResults)(fileFindings, singleFileResults);
|
|
236
|
+
statsLock.validatedFindings += processedFindings.length + dismissedCount;
|
|
237
|
+
statsLock.dismissedFindings += dismissedCount;
|
|
238
|
+
for (const processed of processedFindings) {
|
|
239
|
+
if (processed.validationStatus === 'confirmed')
|
|
240
|
+
statsLock.confirmedFindings++;
|
|
241
|
+
else if (processed.validationStatus === 'downgraded')
|
|
242
|
+
statsLock.downgradedFindings++;
|
|
243
|
+
batchFindings.push(processed);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
// No validation results - REJECT all findings for this file (conservative approach)
|
|
248
|
+
console.warn(`[OpenAI] No validation results for ${filePath} - REJECTING ${fileFindings.length} findings`);
|
|
249
|
+
statsLock.validatedFindings += fileFindings.length;
|
|
250
|
+
statsLock.dismissedFindings += fileFindings.length;
|
|
251
|
+
// Don't add to batchFindings - findings are rejected
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
const { processed: processedFindings, dismissedCount } = (0, response_parser_1.applyValidationResults)(fileFindings, fileResults);
|
|
256
|
+
statsLock.validatedFindings += processedFindings.length + dismissedCount;
|
|
257
|
+
statsLock.dismissedFindings += dismissedCount;
|
|
258
|
+
for (const processed of processedFindings) {
|
|
259
|
+
if (processed.validationStatus === 'confirmed')
|
|
260
|
+
statsLock.confirmedFindings++;
|
|
261
|
+
else if (processed.validationStatus === 'downgraded')
|
|
262
|
+
statsLock.downgradedFindings++;
|
|
263
|
+
batchFindings.push(processed);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
console.error(`[OpenAI Validation] Error in batch ${batchNum}:`, error);
|
|
270
|
+
for (const { findings: fileFindings } of fileDataList) {
|
|
271
|
+
for (const f of fileFindings) {
|
|
272
|
+
batchFindings.push({
|
|
273
|
+
...f,
|
|
274
|
+
validatedByAI: false,
|
|
275
|
+
validationStatus: 'not_validated',
|
|
276
|
+
validationNotes: 'Validation failed due to API error',
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return batchFindings;
|
|
282
|
+
};
|
|
283
|
+
// Process batches in parallel groups
|
|
284
|
+
const startTime = Date.now();
|
|
285
|
+
for (let i = 0; i < allBatches.length; i += clients_1.PARALLEL_API_BATCHES) {
|
|
286
|
+
const parallelGroup = allBatches.slice(i, i + clients_1.PARALLEL_API_BATCHES);
|
|
287
|
+
const batchNums = parallelGroup.map(b => b.batchNum).join(', ');
|
|
288
|
+
console.log(`[OpenAI Validation] Processing batches ${batchNums} in parallel`);
|
|
289
|
+
const results = await Promise.all(parallelGroup.map(processBatch));
|
|
290
|
+
for (const batchResults of results) {
|
|
291
|
+
validatedFindings.push(...batchResults);
|
|
292
|
+
}
|
|
293
|
+
totalApiBatches += parallelGroup.length;
|
|
294
|
+
}
|
|
295
|
+
const totalDuration = Date.now() - startTime;
|
|
296
|
+
// Copy accumulated stats back
|
|
297
|
+
stats.apiCalls = statsLock.apiCalls;
|
|
298
|
+
stats.estimatedInputTokens = statsLock.estimatedInputTokens;
|
|
299
|
+
stats.estimatedOutputTokens = statsLock.estimatedOutputTokens;
|
|
300
|
+
stats.cacheReadTokens = statsLock.cacheReadTokens;
|
|
301
|
+
stats.estimatedCost = statsLock.estimatedCost;
|
|
302
|
+
stats.validatedFindings = statsLock.validatedFindings;
|
|
303
|
+
stats.confirmedFindings = statsLock.confirmedFindings;
|
|
304
|
+
stats.dismissedFindings = statsLock.dismissedFindings;
|
|
305
|
+
stats.downgradedFindings = statsLock.downgradedFindings;
|
|
306
|
+
// Calculate cache hit rate
|
|
307
|
+
const totalCacheableTokens = stats.cacheCreationTokens + stats.cacheReadTokens;
|
|
308
|
+
stats.cacheHitRate = totalCacheableTokens > 0
|
|
309
|
+
? stats.cacheReadTokens / totalCacheableTokens
|
|
310
|
+
: 0;
|
|
311
|
+
// Log validation stats
|
|
312
|
+
const avgTimePerFileMs = fileEntries.length > 0
|
|
313
|
+
? (totalDuration / fileEntries.length).toFixed(0)
|
|
314
|
+
: '0';
|
|
315
|
+
const totalDurationSec = (totalDuration / 1000).toFixed(1);
|
|
316
|
+
console.log(`[OpenAI Validation] Stats:`);
|
|
317
|
+
console.log(` - Total findings: ${stats.totalFindings}`);
|
|
318
|
+
console.log(` - AI validated: ${stats.validatedFindings}`);
|
|
319
|
+
console.log(` - Confirmed: ${stats.confirmedFindings}`);
|
|
320
|
+
console.log(` - Dismissed: ${stats.dismissedFindings}`);
|
|
321
|
+
console.log(` - Downgraded: ${stats.downgradedFindings}`);
|
|
322
|
+
console.log(` - API calls: ${stats.apiCalls}`);
|
|
323
|
+
console.log(` - Performance:`);
|
|
324
|
+
console.log(` - Total duration: ${totalDurationSec}s`);
|
|
325
|
+
console.log(` - Total API batches: ${totalApiBatches}`);
|
|
326
|
+
console.log(` - Avg time per file: ${avgTimePerFileMs}ms`);
|
|
327
|
+
console.log(` - Token usage:`);
|
|
328
|
+
console.log(` - Input (fresh): ${stats.estimatedInputTokens} tokens`);
|
|
329
|
+
console.log(` - Cached: ${stats.cacheReadTokens} tokens`);
|
|
330
|
+
console.log(` - Output: ${stats.estimatedOutputTokens} tokens`);
|
|
331
|
+
console.log(` - Estimated cost: $${stats.estimatedCost.toFixed(4)}`);
|
|
332
|
+
return { vulnerabilities: validatedFindings, stats };
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Clear cached project context (called after validation complete)
|
|
336
|
+
*/
|
|
337
|
+
function clearOpenAICache() {
|
|
338
|
+
cachedProjectContext = null;
|
|
339
|
+
}
|
|
340
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../../src/layer3/anthropic/providers/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request Builders for AI Validation
|
|
3
|
+
*
|
|
4
|
+
* Functions for building validation requests with full file context.
|
|
5
|
+
*/
|
|
6
|
+
import type { Vulnerability, ScanFile } from '../../types';
|
|
7
|
+
import type { ProjectContext } from '../../utils/project-context-builder';
|
|
8
|
+
/**
|
|
9
|
+
* Build a high-context validation request with full file content
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildHighContextValidationRequest(file: ScanFile, findings: Vulnerability[], projectContext: ProjectContext): string;
|
|
12
|
+
/**
|
|
13
|
+
* Build a multi-file validation request (Phase 2 optimization)
|
|
14
|
+
* Batches multiple files into a single API call to reduce overhead
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildMultiFileValidationRequest(fileDataList: Array<{
|
|
17
|
+
file: ScanFile;
|
|
18
|
+
findings: Vulnerability[];
|
|
19
|
+
}>, projectContext: ProjectContext): string;
|
|
20
|
+
//# sourceMappingURL=request-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-builder.d.ts","sourceRoot":"","sources":["../../../src/layer3/anthropic/request-builder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAA;AAQzE;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,aAAa,EAAE,EACzB,cAAc,EAAE,cAAc,GAC7B,MAAM,CAwCR;AAMD;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,YAAY,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;CAAE,CAAC,EAClE,cAAc,EAAE,cAAc,GAC7B,MAAM,CA0ER"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Request Builders for AI Validation
|
|
4
|
+
*
|
|
5
|
+
* Functions for building validation requests with full file context.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.buildHighContextValidationRequest = buildHighContextValidationRequest;
|
|
9
|
+
exports.buildMultiFileValidationRequest = buildMultiFileValidationRequest;
|
|
10
|
+
const project_context_builder_1 = require("../../utils/project-context-builder");
|
|
11
|
+
const path_helpers_1 = require("./utils/path-helpers");
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Single-File Request Builder
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Build a high-context validation request with full file content
|
|
17
|
+
*/
|
|
18
|
+
function buildHighContextValidationRequest(file, findings, projectContext) {
|
|
19
|
+
// Add line numbers to full file content
|
|
20
|
+
const numberedContent = file.content
|
|
21
|
+
.split('\n')
|
|
22
|
+
.map((line, i) => `${String(i + 1).padStart(4, ' ')} | ${line}`)
|
|
23
|
+
.join('\n');
|
|
24
|
+
// Build candidate findings list
|
|
25
|
+
const candidatesText = findings.map((f, idx) => {
|
|
26
|
+
return `### Candidate ${idx}
|
|
27
|
+
- **Rule**: ${f.title}
|
|
28
|
+
- **Category**: ${f.category}
|
|
29
|
+
- **Original Severity**: ${f.severity}
|
|
30
|
+
- **Line**: ${f.lineNumber}
|
|
31
|
+
- **Detection Layer**: ${f.layer}
|
|
32
|
+
- **Description**: ${f.description}
|
|
33
|
+
- **Flagged Code**: \`${f.lineContent.trim()}\``;
|
|
34
|
+
}).join('\n\n');
|
|
35
|
+
// Get file-specific context
|
|
36
|
+
const fileContext = (0, project_context_builder_1.getFileValidationContext)(file, projectContext);
|
|
37
|
+
return `## Project Context
|
|
38
|
+
${projectContext.summary}
|
|
39
|
+
|
|
40
|
+
${fileContext}
|
|
41
|
+
|
|
42
|
+
## Full File Content
|
|
43
|
+
\`\`\`${file.language || (0, path_helpers_1.getLanguageFromPath)(file.path)}
|
|
44
|
+
${numberedContent}
|
|
45
|
+
\`\`\`
|
|
46
|
+
|
|
47
|
+
## Candidate Findings to Validate (${findings.length} total)
|
|
48
|
+
|
|
49
|
+
${candidatesText}
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
Please validate each candidate finding. Return a JSON array with your decision for each.
|
|
54
|
+
Remember: Be AGGRESSIVE in rejecting false positives. Use the full file context and project architecture to make informed decisions.`;
|
|
55
|
+
}
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// Multi-File Request Builder (Phase 2 Optimization)
|
|
58
|
+
// ============================================================================
|
|
59
|
+
/**
|
|
60
|
+
* Build a multi-file validation request (Phase 2 optimization)
|
|
61
|
+
* Batches multiple files into a single API call to reduce overhead
|
|
62
|
+
*/
|
|
63
|
+
function buildMultiFileValidationRequest(fileDataList, projectContext) {
|
|
64
|
+
const filesContent = fileDataList.map(({ file, findings }, fileIndex) => {
|
|
65
|
+
// Add line numbers to full file content
|
|
66
|
+
const numberedContent = file.content
|
|
67
|
+
.split('\n')
|
|
68
|
+
.map((line, i) => `${String(i + 1).padStart(4, ' ')} | ${line}`)
|
|
69
|
+
.join('\n');
|
|
70
|
+
// Build candidate findings list with file-specific indices
|
|
71
|
+
const candidatesText = findings.map((f, idx) => {
|
|
72
|
+
return `### Candidate ${idx}
|
|
73
|
+
- **Rule**: ${f.title}
|
|
74
|
+
- **Category**: ${f.category}
|
|
75
|
+
- **Original Severity**: ${f.severity}
|
|
76
|
+
- **Line**: ${f.lineNumber}
|
|
77
|
+
- **Detection Layer**: ${f.layer}
|
|
78
|
+
- **Description**: ${f.description}
|
|
79
|
+
- **Flagged Code**: \`${f.lineContent.trim()}\``;
|
|
80
|
+
}).join('\n\n');
|
|
81
|
+
// Get file-specific context
|
|
82
|
+
const fileContext = (0, project_context_builder_1.getFileValidationContext)(file, projectContext);
|
|
83
|
+
return `
|
|
84
|
+
================================================================================
|
|
85
|
+
FILE ${fileIndex + 1}: ${file.path}
|
|
86
|
+
================================================================================
|
|
87
|
+
|
|
88
|
+
${fileContext}
|
|
89
|
+
|
|
90
|
+
### Full File Content
|
|
91
|
+
\`\`\`${file.language || (0, path_helpers_1.getLanguageFromPath)(file.path)}
|
|
92
|
+
${numberedContent}
|
|
93
|
+
\`\`\`
|
|
94
|
+
|
|
95
|
+
### Candidate Findings to Validate (${findings.length} total)
|
|
96
|
+
|
|
97
|
+
${candidatesText}`;
|
|
98
|
+
}).join('\n\n');
|
|
99
|
+
return `## Project Context
|
|
100
|
+
${projectContext.summary}
|
|
101
|
+
|
|
102
|
+
${filesContent}
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Response Format
|
|
107
|
+
|
|
108
|
+
For EACH file, provide a JSON object with the file path and validation results.
|
|
109
|
+
Return a JSON array where each element has:
|
|
110
|
+
- "file": the file path (e.g., "${fileDataList[0]?.file.path || 'path/to/file.ts'}")
|
|
111
|
+
- "validations": array of validation results for that file's candidates
|
|
112
|
+
|
|
113
|
+
Example response format:
|
|
114
|
+
\`\`\`json
|
|
115
|
+
[
|
|
116
|
+
{
|
|
117
|
+
"file": "src/auth.ts",
|
|
118
|
+
"validations": [
|
|
119
|
+
{ "index": 0, "keep": true, "adjustedSeverity": "medium", "notes": "Protected by middleware" },
|
|
120
|
+
{ "index": 1, "keep": false }
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"file": "src/api.ts",
|
|
125
|
+
"validations": [
|
|
126
|
+
{ "index": 0, "keep": true, "notes": "User input flows to SQL query" }
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
\`\`\`
|
|
131
|
+
|
|
132
|
+
Remember: Be AGGRESSIVE in rejecting false positives. Use the full file context and project architecture to make informed decisions.`;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=request-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-builder.js","sourceRoot":"","sources":["../../../src/layer3/anthropic/request-builder.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAcH,8EA4CC;AAUD,0EA6EC;AA7ID,iFAA8E;AAC9E,uDAA0D;AAE1D,+EAA+E;AAC/E,8BAA8B;AAC9B,+EAA+E;AAE/E;;GAEG;AACH,SAAgB,iCAAiC,CAC/C,IAAc,EACd,QAAyB,EACzB,cAA8B;IAE9B,wCAAwC;IACxC,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO;SACjC,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC;SAC/D,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,gCAAgC;IAChC,MAAM,cAAc,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;QAC7C,OAAO,iBAAiB,GAAG;cACjB,CAAC,CAAC,KAAK;kBACH,CAAC,CAAC,QAAQ;2BACD,CAAC,CAAC,QAAQ;cACvB,CAAC,CAAC,UAAU;yBACD,CAAC,CAAC,KAAK;qBACX,CAAC,CAAC,WAAW;wBACV,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAA;IAC9C,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAEf,4BAA4B;IAC5B,MAAM,WAAW,GAAG,IAAA,kDAAwB,EAAC,IAAI,EAAE,cAAc,CAAC,CAAA;IAElE,OAAO;EACP,cAAc,CAAC,OAAO;;EAEtB,WAAW;;;QAGL,IAAI,CAAC,QAAQ,IAAI,IAAA,kCAAmB,EAAC,IAAI,CAAC,IAAI,CAAC;EACrD,eAAe;;;qCAGoB,QAAQ,CAAC,MAAM;;EAElD,cAAc;;;;;qIAKqH,CAAA;AACrI,CAAC;AAED,+EAA+E;AAC/E,oDAAoD;AACpD,+EAA+E;AAE/E;;;GAGG;AACH,SAAgB,+BAA+B,CAC7C,YAAkE,EAClE,cAA8B;IAE9B,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,EAAE;QACtE,wCAAwC;QACxC,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO;aACjC,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC;aAC/D,IAAI,CAAC,IAAI,CAAC,CAAA;QAEb,2DAA2D;QAC3D,MAAM,cAAc,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;YAC7C,OAAO,iBAAiB,GAAG;cACnB,CAAC,CAAC,KAAK;kBACH,CAAC,CAAC,QAAQ;2BACD,CAAC,CAAC,QAAQ;cACvB,CAAC,CAAC,UAAU;yBACD,CAAC,CAAC,KAAK;qBACX,CAAC,CAAC,WAAW;wBACV,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAA;QAC5C,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAEf,4BAA4B;QAC5B,MAAM,WAAW,GAAG,IAAA,kDAAwB,EAAC,IAAI,EAAE,cAAc,CAAC,CAAA;QAElE,OAAO;;OAEJ,SAAS,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI;;;EAGhC,WAAW;;;QAGL,IAAI,CAAC,QAAQ,IAAI,IAAA,kCAAmB,EAAC,IAAI,CAAC,IAAI,CAAC;EACrD,eAAe;;;sCAGqB,QAAQ,CAAC,MAAM;;EAEnD,cAAc,EAAE,CAAA;IAChB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAEf,OAAO;EACP,cAAc,CAAC,OAAO;;EAEtB,YAAY;;;;;;;;kCAQoB,YAAY,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,iBAAiB;;;;;;;;;;;;;;;;;;;;;;qIAsBoD,CAAA;AACrI,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for AI validation module
|
|
3
|
+
*/
|
|
4
|
+
import type { Vulnerability, VulnerabilitySeverity, VulnerabilityCategory } from '../../types';
|
|
5
|
+
export interface ValidationStats {
|
|
6
|
+
/** Total findings processed (input) */
|
|
7
|
+
totalFindings: number;
|
|
8
|
+
/** Findings that went through AI validation */
|
|
9
|
+
validatedFindings: number;
|
|
10
|
+
/** Findings confirmed as true positives */
|
|
11
|
+
confirmedFindings: number;
|
|
12
|
+
/** Findings dismissed as false positives */
|
|
13
|
+
dismissedFindings: number;
|
|
14
|
+
/** Findings with severity adjusted down */
|
|
15
|
+
downgradedFindings: number;
|
|
16
|
+
/** Findings auto-dismissed before AI (test files, etc.) */
|
|
17
|
+
autoDismissedFindings: number;
|
|
18
|
+
/** Estimated input tokens used */
|
|
19
|
+
estimatedInputTokens: number;
|
|
20
|
+
/** Estimated output tokens used */
|
|
21
|
+
estimatedOutputTokens: number;
|
|
22
|
+
/** Estimated cost in USD (based on Haiku pricing) */
|
|
23
|
+
estimatedCost: number;
|
|
24
|
+
/** Number of API calls made */
|
|
25
|
+
apiCalls: number;
|
|
26
|
+
/** Cache creation tokens (first write to cache) */
|
|
27
|
+
cacheCreationTokens: number;
|
|
28
|
+
/** Cache read tokens (subsequent reads from cache) */
|
|
29
|
+
cacheReadTokens: number;
|
|
30
|
+
/** Cache hit rate (0-1) */
|
|
31
|
+
cacheHitRate: number;
|
|
32
|
+
}
|
|
33
|
+
export interface AIValidationResult {
|
|
34
|
+
vulnerabilities: Vulnerability[];
|
|
35
|
+
stats: ValidationStats;
|
|
36
|
+
}
|
|
37
|
+
export interface ValidationResult {
|
|
38
|
+
index: number;
|
|
39
|
+
keep: boolean;
|
|
40
|
+
notes?: string;
|
|
41
|
+
adjustedSeverity?: VulnerabilitySeverity | null;
|
|
42
|
+
reason?: string;
|
|
43
|
+
validationNotes?: string;
|
|
44
|
+
impact?: string;
|
|
45
|
+
fixSuggestion?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface AIFinding {
|
|
48
|
+
lineNumber: number;
|
|
49
|
+
severity: VulnerabilitySeverity;
|
|
50
|
+
category: VulnerabilityCategory;
|
|
51
|
+
title: string;
|
|
52
|
+
description: string;
|
|
53
|
+
suggestedFix: string;
|
|
54
|
+
}
|
|
55
|
+
export interface Layer3Context {
|
|
56
|
+
/** Middleware configuration from project scan */
|
|
57
|
+
middlewareConfig?: {
|
|
58
|
+
hasAuthMiddleware: boolean;
|
|
59
|
+
authType?: string;
|
|
60
|
+
protectedPaths: string[];
|
|
61
|
+
};
|
|
62
|
+
/** Auth helper context */
|
|
63
|
+
authHelpers?: {
|
|
64
|
+
hasThrowingHelpers: boolean;
|
|
65
|
+
summary: string;
|
|
66
|
+
};
|
|
67
|
+
/** Additional context string */
|
|
68
|
+
additionalContext?: string;
|
|
69
|
+
}
|
|
70
|
+
export interface AutoDismissRule {
|
|
71
|
+
name: string;
|
|
72
|
+
check: (finding: Vulnerability, fileContent?: string) => boolean;
|
|
73
|
+
reason: string;
|
|
74
|
+
}
|
|
75
|
+
export interface StatsAccumulator {
|
|
76
|
+
apiCalls: number;
|
|
77
|
+
estimatedInputTokens: number;
|
|
78
|
+
estimatedOutputTokens: number;
|
|
79
|
+
cacheReadTokens: number;
|
|
80
|
+
estimatedCost: number;
|
|
81
|
+
validatedFindings: number;
|
|
82
|
+
confirmedFindings: number;
|
|
83
|
+
dismissedFindings: number;
|
|
84
|
+
downgradedFindings: number;
|
|
85
|
+
}
|
|
86
|
+
export declare function createStatsAccumulator(): StatsAccumulator;
|
|
87
|
+
export declare function createInitialStats(totalFindings: number): ValidationStats;
|
|
88
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/layer3/anthropic/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,qBAAqB,EAAE,qBAAqB,EAAoB,MAAM,aAAa,CAAA;AAMhH,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,aAAa,EAAE,MAAM,CAAA;IACrB,+CAA+C;IAC/C,iBAAiB,EAAE,MAAM,CAAA;IACzB,2CAA2C;IAC3C,iBAAiB,EAAE,MAAM,CAAA;IACzB,4CAA4C;IAC5C,iBAAiB,EAAE,MAAM,CAAA;IACzB,2CAA2C;IAC3C,kBAAkB,EAAE,MAAM,CAAA;IAC1B,2DAA2D;IAC3D,qBAAqB,EAAE,MAAM,CAAA;IAC7B,kCAAkC;IAClC,oBAAoB,EAAE,MAAM,CAAA;IAC5B,mCAAmC;IACnC,qBAAqB,EAAE,MAAM,CAAA;IAC7B,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAA;IACrB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,mDAAmD;IACnD,mBAAmB,EAAE,MAAM,CAAA;IAC3B,sDAAsD;IACtD,eAAe,EAAE,MAAM,CAAA;IACvB,2BAA2B;IAC3B,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,aAAa,EAAE,CAAA;IAChC,KAAK,EAAE,eAAe,CAAA;CACvB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,OAAO,CAAA;IAEb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,gBAAgB,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAA;IAE/C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,qBAAqB,CAAA;IAC/B,QAAQ,EAAE,qBAAqB,CAAA;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;CACrB;AAMD,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,gBAAgB,CAAC,EAAE;QACjB,iBAAiB,EAAE,OAAO,CAAA;QAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,cAAc,EAAE,MAAM,EAAE,CAAA;KACzB,CAAA;IACD,0BAA0B;IAC1B,WAAW,CAAC,EAAE;QACZ,kBAAkB,EAAE,OAAO,CAAA;QAC3B,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,gCAAgC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAMD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;IAChE,MAAM,EAAE,MAAM,CAAA;CACf;AAMD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,qBAAqB,EAAE,MAAM,CAAA;IAC7B,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;IACzB,iBAAiB,EAAE,MAAM,CAAA;IACzB,iBAAiB,EAAE,MAAM,CAAA;IACzB,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AAED,wBAAgB,sBAAsB,IAAI,gBAAgB,CAYzD;AAED,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe,CAgBzE"}
|