@oddessentials/odd-ai-reviewers 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +190 -0
- package/dist/__tests__/hermetic-setup.d.ts +55 -0
- package/dist/__tests__/hermetic-setup.d.ts.map +1 -0
- package/dist/__tests__/hermetic-setup.js +62 -0
- package/dist/__tests__/hermetic-setup.js.map +1 -0
- package/dist/__tests__/test-utils/hermetic.d.ts +84 -0
- package/dist/__tests__/test-utils/hermetic.d.ts.map +1 -0
- package/dist/__tests__/test-utils/hermetic.js +147 -0
- package/dist/__tests__/test-utils/hermetic.js.map +1 -0
- package/dist/agents/ai_semantic_review.d.ts +12 -0
- package/dist/agents/ai_semantic_review.d.ts.map +1 -0
- package/dist/agents/ai_semantic_review.js +317 -0
- package/dist/agents/ai_semantic_review.js.map +1 -0
- package/dist/agents/control_flow/budget.d.ts +162 -0
- package/dist/agents/control_flow/budget.d.ts.map +1 -0
- package/dist/agents/control_flow/budget.js +331 -0
- package/dist/agents/control_flow/budget.js.map +1 -0
- package/dist/agents/control_flow/cfg-builder.d.ts +26 -0
- package/dist/agents/control_flow/cfg-builder.d.ts.map +1 -0
- package/dist/agents/control_flow/cfg-builder.js +776 -0
- package/dist/agents/control_flow/cfg-builder.js.map +1 -0
- package/dist/agents/control_flow/cfg-types.d.ts +186 -0
- package/dist/agents/control_flow/cfg-types.d.ts.map +1 -0
- package/dist/agents/control_flow/cfg-types.js +114 -0
- package/dist/agents/control_flow/cfg-types.js.map +1 -0
- package/dist/agents/control_flow/finding-generator.d.ts +118 -0
- package/dist/agents/control_flow/finding-generator.d.ts.map +1 -0
- package/dist/agents/control_flow/finding-generator.js +354 -0
- package/dist/agents/control_flow/finding-generator.js.map +1 -0
- package/dist/agents/control_flow/index.d.ts +39 -0
- package/dist/agents/control_flow/index.d.ts.map +1 -0
- package/dist/agents/control_flow/index.js +270 -0
- package/dist/agents/control_flow/index.js.map +1 -0
- package/dist/agents/control_flow/logger.d.ts +333 -0
- package/dist/agents/control_flow/logger.d.ts.map +1 -0
- package/dist/agents/control_flow/logger.js +607 -0
- package/dist/agents/control_flow/logger.js.map +1 -0
- package/dist/agents/control_flow/mitigation-detector.d.ts +207 -0
- package/dist/agents/control_flow/mitigation-detector.d.ts.map +1 -0
- package/dist/agents/control_flow/mitigation-detector.js +625 -0
- package/dist/agents/control_flow/mitigation-detector.js.map +1 -0
- package/dist/agents/control_flow/mitigation-patterns.d.ts +53 -0
- package/dist/agents/control_flow/mitigation-patterns.d.ts.map +1 -0
- package/dist/agents/control_flow/mitigation-patterns.js +620 -0
- package/dist/agents/control_flow/mitigation-patterns.js.map +1 -0
- package/dist/agents/control_flow/path-analyzer.d.ts +287 -0
- package/dist/agents/control_flow/path-analyzer.d.ts.map +1 -0
- package/dist/agents/control_flow/path-analyzer.js +695 -0
- package/dist/agents/control_flow/path-analyzer.js.map +1 -0
- package/dist/agents/control_flow/pattern-validator.d.ts +132 -0
- package/dist/agents/control_flow/pattern-validator.d.ts.map +1 -0
- package/dist/agents/control_flow/pattern-validator.js +420 -0
- package/dist/agents/control_flow/pattern-validator.js.map +1 -0
- package/dist/agents/control_flow/timeout-regex.d.ts +144 -0
- package/dist/agents/control_flow/timeout-regex.d.ts.map +1 -0
- package/dist/agents/control_flow/timeout-regex.js +339 -0
- package/dist/agents/control_flow/timeout-regex.js.map +1 -0
- package/dist/agents/control_flow/types.d.ts +782 -0
- package/dist/agents/control_flow/types.d.ts.map +1 -0
- package/dist/agents/control_flow/types.js +428 -0
- package/dist/agents/control_flow/types.js.map +1 -0
- package/dist/agents/control_flow/vulnerability-detector.d.ts +85 -0
- package/dist/agents/control_flow/vulnerability-detector.d.ts.map +1 -0
- package/dist/agents/control_flow/vulnerability-detector.js +493 -0
- package/dist/agents/control_flow/vulnerability-detector.js.map +1 -0
- package/dist/agents/date-utils.d.ts +19 -0
- package/dist/agents/date-utils.d.ts.map +1 -0
- package/dist/agents/date-utils.js +29 -0
- package/dist/agents/date-utils.js.map +1 -0
- package/dist/agents/index.d.ts +25 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +50 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/json-utils.d.ts +34 -0
- package/dist/agents/json-utils.d.ts.map +1 -0
- package/dist/agents/json-utils.js +62 -0
- package/dist/agents/json-utils.js.map +1 -0
- package/dist/agents/local_llm.d.ts +24 -0
- package/dist/agents/local_llm.d.ts.map +1 -0
- package/dist/agents/local_llm.js +566 -0
- package/dist/agents/local_llm.js.map +1 -0
- package/dist/agents/metadata.d.ts +57 -0
- package/dist/agents/metadata.d.ts.map +1 -0
- package/dist/agents/metadata.js +45 -0
- package/dist/agents/metadata.js.map +1 -0
- package/dist/agents/opencode.d.ts +18 -0
- package/dist/agents/opencode.d.ts.map +1 -0
- package/dist/agents/opencode.js +364 -0
- package/dist/agents/opencode.js.map +1 -0
- package/dist/agents/path-filter.d.ts +25 -0
- package/dist/agents/path-filter.d.ts.map +1 -0
- package/dist/agents/path-filter.js +43 -0
- package/dist/agents/path-filter.js.map +1 -0
- package/dist/agents/pr_agent.d.ts +3 -0
- package/dist/agents/pr_agent.d.ts.map +1 -0
- package/dist/agents/pr_agent.js +312 -0
- package/dist/agents/pr_agent.js.map +1 -0
- package/dist/agents/retry.d.ts +12 -0
- package/dist/agents/retry.d.ts.map +1 -0
- package/dist/agents/retry.js +65 -0
- package/dist/agents/retry.js.map +1 -0
- package/dist/agents/reviewdog.d.ts +24 -0
- package/dist/agents/reviewdog.d.ts.map +1 -0
- package/dist/agents/reviewdog.js +259 -0
- package/dist/agents/reviewdog.js.map +1 -0
- package/dist/agents/security.d.ts +49 -0
- package/dist/agents/security.d.ts.map +1 -0
- package/dist/agents/security.js +302 -0
- package/dist/agents/security.js.map +1 -0
- package/dist/agents/semgrep.d.ts +8 -0
- package/dist/agents/semgrep.d.ts.map +1 -0
- package/dist/agents/semgrep.js +157 -0
- package/dist/agents/semgrep.js.map +1 -0
- package/dist/agents/types.d.ts +450 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +127 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/budget.d.ts +59 -0
- package/dist/budget.d.ts.map +1 -0
- package/dist/budget.js +82 -0
- package/dist/budget.js.map +1 -0
- package/dist/cache/key.d.ts +49 -0
- package/dist/cache/key.d.ts.map +1 -0
- package/dist/cache/key.js +71 -0
- package/dist/cache/key.js.map +1 -0
- package/dist/cache/store.d.ts +47 -0
- package/dist/cache/store.d.ts.map +1 -0
- package/dist/cache/store.js +328 -0
- package/dist/cache/store.js.map +1 -0
- package/dist/cli/commands/check.d.ts +60 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +163 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/commands/index.d.ts +12 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +12 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/local-review.d.ts +149 -0
- package/dist/cli/commands/local-review.d.ts.map +1 -0
- package/dist/cli/commands/local-review.js +755 -0
- package/dist/cli/commands/local-review.js.map +1 -0
- package/dist/cli/config-wizard.d.ts +87 -0
- package/dist/cli/config-wizard.d.ts.map +1 -0
- package/dist/cli/config-wizard.js +240 -0
- package/dist/cli/config-wizard.js.map +1 -0
- package/dist/cli/dependencies/catalog.d.ts +44 -0
- package/dist/cli/dependencies/catalog.d.ts.map +1 -0
- package/dist/cli/dependencies/catalog.js +89 -0
- package/dist/cli/dependencies/catalog.js.map +1 -0
- package/dist/cli/dependencies/checker.d.ts +42 -0
- package/dist/cli/dependencies/checker.d.ts.map +1 -0
- package/dist/cli/dependencies/checker.js +240 -0
- package/dist/cli/dependencies/checker.js.map +1 -0
- package/dist/cli/dependencies/index.d.ts +16 -0
- package/dist/cli/dependencies/index.d.ts.map +1 -0
- package/dist/cli/dependencies/index.js +16 -0
- package/dist/cli/dependencies/index.js.map +1 -0
- package/dist/cli/dependencies/messages.d.ts +58 -0
- package/dist/cli/dependencies/messages.d.ts.map +1 -0
- package/dist/cli/dependencies/messages.js +183 -0
- package/dist/cli/dependencies/messages.js.map +1 -0
- package/dist/cli/dependencies/platform.d.ts +25 -0
- package/dist/cli/dependencies/platform.d.ts.map +1 -0
- package/dist/cli/dependencies/platform.js +42 -0
- package/dist/cli/dependencies/platform.js.map +1 -0
- package/dist/cli/dependencies/schemas.d.ts +65 -0
- package/dist/cli/dependencies/schemas.d.ts.map +1 -0
- package/dist/cli/dependencies/schemas.js +42 -0
- package/dist/cli/dependencies/schemas.js.map +1 -0
- package/dist/cli/dependencies/types.d.ts +112 -0
- package/dist/cli/dependencies/types.d.ts.map +1 -0
- package/dist/cli/dependencies/types.js +6 -0
- package/dist/cli/dependencies/types.js.map +1 -0
- package/dist/cli/dependencies/version.d.ts +67 -0
- package/dist/cli/dependencies/version.d.ts.map +1 -0
- package/dist/cli/dependencies/version.js +125 -0
- package/dist/cli/dependencies/version.js.map +1 -0
- package/dist/cli/git-context.d.ts +105 -0
- package/dist/cli/git-context.d.ts.map +1 -0
- package/dist/cli/git-context.js +313 -0
- package/dist/cli/git-context.js.map +1 -0
- package/dist/cli/interactive-prompts.d.ts +126 -0
- package/dist/cli/interactive-prompts.d.ts.map +1 -0
- package/dist/cli/interactive-prompts.js +128 -0
- package/dist/cli/interactive-prompts.js.map +1 -0
- package/dist/cli/options/index.d.ts +7 -0
- package/dist/cli/options/index.d.ts.map +1 -0
- package/dist/cli/options/index.js +11 -0
- package/dist/cli/options/index.js.map +1 -0
- package/dist/cli/options/local-review-options.d.ts +221 -0
- package/dist/cli/options/local-review-options.d.ts.map +1 -0
- package/dist/cli/options/local-review-options.js +332 -0
- package/dist/cli/options/local-review-options.js.map +1 -0
- package/dist/cli/output/colors.d.ts +154 -0
- package/dist/cli/output/colors.d.ts.map +1 -0
- package/dist/cli/output/colors.js +255 -0
- package/dist/cli/output/colors.js.map +1 -0
- package/dist/cli/output/errors.d.ts +157 -0
- package/dist/cli/output/errors.d.ts.map +1 -0
- package/dist/cli/output/errors.js +266 -0
- package/dist/cli/output/errors.js.map +1 -0
- package/dist/cli/output/index.d.ts +12 -0
- package/dist/cli/output/index.d.ts.map +1 -0
- package/dist/cli/output/index.js +15 -0
- package/dist/cli/output/index.js.map +1 -0
- package/dist/cli/output/progress.d.ts +237 -0
- package/dist/cli/output/progress.d.ts.map +1 -0
- package/dist/cli/output/progress.js +405 -0
- package/dist/cli/output/progress.js.map +1 -0
- package/dist/cli/signals.d.ts +145 -0
- package/dist/cli/signals.d.ts.map +1 -0
- package/dist/cli/signals.js +223 -0
- package/dist/cli/signals.js.map +1 -0
- package/dist/cli/validation-report.d.ts +106 -0
- package/dist/cli/validation-report.d.ts.map +1 -0
- package/dist/cli/validation-report.js +108 -0
- package/dist/cli/validation-report.js.map +1 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +12 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/mitigation-config.d.ts +94 -0
- package/dist/config/mitigation-config.d.ts.map +1 -0
- package/dist/config/mitigation-config.js +430 -0
- package/dist/config/mitigation-config.js.map +1 -0
- package/dist/config/providers.d.ts +118 -0
- package/dist/config/providers.d.ts.map +1 -0
- package/dist/config/providers.js +229 -0
- package/dist/config/providers.js.map +1 -0
- package/dist/config/schemas.d.ts +278 -0
- package/dist/config/schemas.d.ts.map +1 -0
- package/dist/config/schemas.js +111 -0
- package/dist/config/schemas.js.map +1 -0
- package/dist/config/zero-config.d.ts +126 -0
- package/dist/config/zero-config.d.ts.map +1 -0
- package/dist/config/zero-config.js +243 -0
- package/dist/config/zero-config.js.map +1 -0
- package/dist/config.d.ts +110 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +302 -0
- package/dist/config.js.map +1 -0
- package/dist/diff.d.ts +224 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +832 -0
- package/dist/diff.js.map +1 -0
- package/dist/git-validators.d.ts +106 -0
- package/dist/git-validators.d.ts.map +1 -0
- package/dist/git-validators.js +224 -0
- package/dist/git-validators.js.map +1 -0
- package/dist/main.d.ts +61 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +704 -0
- package/dist/main.js.map +1 -0
- package/dist/phases/execute.d.ts +60 -0
- package/dist/phases/execute.d.ts.map +1 -0
- package/dist/phases/execute.js +168 -0
- package/dist/phases/execute.js.map +1 -0
- package/dist/phases/index.d.ts +9 -0
- package/dist/phases/index.d.ts.map +1 -0
- package/dist/phases/index.js +9 -0
- package/dist/phases/index.js.map +1 -0
- package/dist/phases/preflight.d.ts +40 -0
- package/dist/phases/preflight.d.ts.map +1 -0
- package/dist/phases/preflight.js +122 -0
- package/dist/phases/preflight.js.map +1 -0
- package/dist/phases/report.d.ts +51 -0
- package/dist/phases/report.d.ts.map +1 -0
- package/dist/phases/report.js +152 -0
- package/dist/phases/report.js.map +1 -0
- package/dist/policy.d.ts +33 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +34 -0
- package/dist/policy.js.map +1 -0
- package/dist/preflight.d.ts +181 -0
- package/dist/preflight.d.ts.map +1 -0
- package/dist/preflight.js +627 -0
- package/dist/preflight.js.map +1 -0
- package/dist/report/ado.d.ts +53 -0
- package/dist/report/ado.d.ts.map +1 -0
- package/dist/report/ado.js +411 -0
- package/dist/report/ado.js.map +1 -0
- package/dist/report/agent-icons.d.ts +36 -0
- package/dist/report/agent-icons.d.ts.map +1 -0
- package/dist/report/agent-icons.js +46 -0
- package/dist/report/agent-icons.js.map +1 -0
- package/dist/report/base.d.ts +30 -0
- package/dist/report/base.d.ts.map +1 -0
- package/dist/report/base.js +64 -0
- package/dist/report/base.js.map +1 -0
- package/dist/report/formats.d.ts +206 -0
- package/dist/report/formats.d.ts.map +1 -0
- package/dist/report/formats.js +481 -0
- package/dist/report/formats.js.map +1 -0
- package/dist/report/github.d.ts +44 -0
- package/dist/report/github.d.ts.map +1 -0
- package/dist/report/github.js +409 -0
- package/dist/report/github.js.map +1 -0
- package/dist/report/line-resolver.d.ts +208 -0
- package/dist/report/line-resolver.d.ts.map +1 -0
- package/dist/report/line-resolver.js +578 -0
- package/dist/report/line-resolver.js.map +1 -0
- package/dist/report/resolution.d.ts +158 -0
- package/dist/report/resolution.d.ts.map +1 -0
- package/dist/report/resolution.js +272 -0
- package/dist/report/resolution.js.map +1 -0
- package/dist/report/sanitize.d.ts +32 -0
- package/dist/report/sanitize.d.ts.map +1 -0
- package/dist/report/sanitize.js +84 -0
- package/dist/report/sanitize.js.map +1 -0
- package/dist/report/terminal.d.ts +440 -0
- package/dist/report/terminal.d.ts.map +1 -0
- package/dist/report/terminal.js +840 -0
- package/dist/report/terminal.js.map +1 -0
- package/dist/reviewignore.d.ts +125 -0
- package/dist/reviewignore.d.ts.map +1 -0
- package/dist/reviewignore.js +335 -0
- package/dist/reviewignore.js.map +1 -0
- package/dist/security-logger.d.ts +178 -0
- package/dist/security-logger.d.ts.map +1 -0
- package/dist/security-logger.js +256 -0
- package/dist/security-logger.js.map +1 -0
- package/dist/telemetry/backends/console.d.ts +24 -0
- package/dist/telemetry/backends/console.d.ts.map +1 -0
- package/dist/telemetry/backends/console.js +54 -0
- package/dist/telemetry/backends/console.js.map +1 -0
- package/dist/telemetry/backends/jsonl.d.ts +31 -0
- package/dist/telemetry/backends/jsonl.d.ts.map +1 -0
- package/dist/telemetry/backends/jsonl.js +121 -0
- package/dist/telemetry/backends/jsonl.js.map +1 -0
- package/dist/telemetry/emitter.d.ts +43 -0
- package/dist/telemetry/emitter.d.ts.map +1 -0
- package/dist/telemetry/emitter.js +83 -0
- package/dist/telemetry/emitter.js.map +1 -0
- package/dist/telemetry/hook.d.ts +53 -0
- package/dist/telemetry/hook.d.ts.map +1 -0
- package/dist/telemetry/hook.js +118 -0
- package/dist/telemetry/hook.js.map +1 -0
- package/dist/telemetry/index.d.ts +58 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +143 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/types.d.ts +139 -0
- package/dist/telemetry/types.d.ts.map +1 -0
- package/dist/telemetry/types.js +133 -0
- package/dist/telemetry/types.js.map +1 -0
- package/dist/trust.d.ts +65 -0
- package/dist/trust.d.ts.map +1 -0
- package/dist/trust.js +78 -0
- package/dist/trust.js.map +1 -0
- package/dist/types/assert-never.d.ts +30 -0
- package/dist/types/assert-never.d.ts.map +1 -0
- package/dist/types/assert-never.js +32 -0
- package/dist/types/assert-never.js.map +1 -0
- package/dist/types/branded.d.ts +172 -0
- package/dist/types/branded.d.ts.map +1 -0
- package/dist/types/branded.js +262 -0
- package/dist/types/branded.js.map +1 -0
- package/dist/types/errors.d.ts +320 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +551 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +37 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +77 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/result.d.ts +323 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +423 -0
- package/dist/types/result.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reviewdog Agent
|
|
3
|
+
*
|
|
4
|
+
* ROUTER MONOPOLY RULE COMPLIANCE (INVARIANTS.md #1):
|
|
5
|
+
* - This agent runs reviewdog in LOCAL mode only (-reporter=local)
|
|
6
|
+
* - NO GitHub tokens are passed to subprocess
|
|
7
|
+
* - Returns structured findings for router to post
|
|
8
|
+
* - Never posts directly to GitHub
|
|
9
|
+
*/
|
|
10
|
+
import { spawn, execFileSync } from 'child_process';
|
|
11
|
+
import { createReadStream, writeFileSync, unlinkSync, existsSync } from 'fs';
|
|
12
|
+
import { tmpdir } from 'os';
|
|
13
|
+
import { join } from 'path';
|
|
14
|
+
import { filterSafePaths } from './path-filter.js';
|
|
15
|
+
import { AgentSuccess, AgentFailure, AgentSkipped } from './types.js';
|
|
16
|
+
import { buildAgentEnv } from './security.js';
|
|
17
|
+
import { generateFingerprint } from '../report/formats.js';
|
|
18
|
+
/**
|
|
19
|
+
* Check if reviewdog binary is available
|
|
20
|
+
*/
|
|
21
|
+
export function isReviewdogAvailable() {
|
|
22
|
+
try {
|
|
23
|
+
execFileSync('reviewdog', ['--version'], { stdio: 'ignore', shell: false });
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Check if semgrep binary is available
|
|
32
|
+
*/
|
|
33
|
+
export function isSemgrepAvailable() {
|
|
34
|
+
try {
|
|
35
|
+
execFileSync('semgrep', ['--version'], { stdio: 'ignore', shell: false });
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Map semgrep severity to Finding severity
|
|
44
|
+
*/
|
|
45
|
+
export function mapSeverity(semgrepSeverity) {
|
|
46
|
+
switch (semgrepSeverity.toUpperCase()) {
|
|
47
|
+
case 'ERROR':
|
|
48
|
+
return 'error';
|
|
49
|
+
case 'WARNING':
|
|
50
|
+
return 'warning';
|
|
51
|
+
case 'INFO':
|
|
52
|
+
default:
|
|
53
|
+
return 'info';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Run semgrep and parse results into structured findings
|
|
58
|
+
* This is the primary path - no GitHub posting
|
|
59
|
+
*/
|
|
60
|
+
async function runSemgrepStructured(repoPath, filePaths, _env) {
|
|
61
|
+
// Filter paths for safe execution (defense-in-depth)
|
|
62
|
+
const { safePaths } = filterSafePaths(filePaths, 'reviewdog');
|
|
63
|
+
if (safePaths.length === 0) {
|
|
64
|
+
return { success: true, findings: [], error: 'No valid file paths to scan' };
|
|
65
|
+
}
|
|
66
|
+
// Run semgrep with JSON output - shell-free execution
|
|
67
|
+
let semgrepOutput;
|
|
68
|
+
try {
|
|
69
|
+
semgrepOutput = execFileSync('semgrep', ['scan', '--config=auto', '--json', ...safePaths], {
|
|
70
|
+
cwd: repoPath,
|
|
71
|
+
encoding: 'utf-8',
|
|
72
|
+
shell: false, // Critical: no shell interpretation
|
|
73
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
74
|
+
timeout: 300000, // 5 minute timeout
|
|
75
|
+
env: _env, // Clean env, no tokens
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
// Semgrep returns non-zero exit code when it finds issues
|
|
80
|
+
// The JSON output is still in stdout
|
|
81
|
+
if (error && typeof error === 'object' && 'stdout' in error) {
|
|
82
|
+
semgrepOutput = error.stdout;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
return {
|
|
86
|
+
success: false,
|
|
87
|
+
findings: [],
|
|
88
|
+
error: `Semgrep failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Parse semgrep JSON output
|
|
93
|
+
let parsed;
|
|
94
|
+
try {
|
|
95
|
+
parsed = JSON.parse(semgrepOutput);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return {
|
|
99
|
+
success: false,
|
|
100
|
+
findings: [],
|
|
101
|
+
error: 'Failed to parse semgrep JSON output',
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// Convert to structured findings
|
|
105
|
+
const findings = parsed.results.map((result) => {
|
|
106
|
+
const finding = {
|
|
107
|
+
severity: mapSeverity(result.extra.severity),
|
|
108
|
+
file: result.path,
|
|
109
|
+
line: result.start.line,
|
|
110
|
+
endLine: result.end.line,
|
|
111
|
+
message: result.extra.message,
|
|
112
|
+
ruleId: result.check_id,
|
|
113
|
+
sourceAgent: 'reviewdog',
|
|
114
|
+
suggestion: result.extra.fix,
|
|
115
|
+
metadata: result.extra.metadata,
|
|
116
|
+
};
|
|
117
|
+
// Generate stable fingerprint
|
|
118
|
+
finding.fingerprint = generateFingerprint(finding);
|
|
119
|
+
return finding;
|
|
120
|
+
});
|
|
121
|
+
return { success: true, findings };
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Run reviewdog in local mode (for validation/format checking only)
|
|
125
|
+
* This does NOT post to GitHub - purely for local validation
|
|
126
|
+
*/
|
|
127
|
+
async function runReviewdogLocal(repoPath, semgrepJsonPath, cleanEnv) {
|
|
128
|
+
return new Promise((resolve) => {
|
|
129
|
+
// CRITICAL: -reporter=local means no GitHub posting
|
|
130
|
+
// No REVIEWDOG_GITHUB_API_TOKEN in environment
|
|
131
|
+
const reviewdog = spawn('reviewdog', ['-f=semgrep', '-reporter=local', '-fail-level=none'], {
|
|
132
|
+
cwd: repoPath,
|
|
133
|
+
env: cleanEnv, // Clean env, no tokens
|
|
134
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
135
|
+
});
|
|
136
|
+
const input = createReadStream(semgrepJsonPath);
|
|
137
|
+
if (reviewdog.stdin) {
|
|
138
|
+
input.pipe(reviewdog.stdin);
|
|
139
|
+
}
|
|
140
|
+
let stderr = '';
|
|
141
|
+
reviewdog.stderr?.on('data', (data) => {
|
|
142
|
+
stderr += data.toString();
|
|
143
|
+
});
|
|
144
|
+
reviewdog.once('close', (code) => {
|
|
145
|
+
if (code === 0 || code === 1) {
|
|
146
|
+
// Exit code 1 means findings were found, which is expected
|
|
147
|
+
resolve({ success: true });
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
resolve({ success: false, error: `reviewdog exited with code ${code}: ${stderr}` });
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
reviewdog.once('error', (err) => {
|
|
154
|
+
resolve({ success: false, error: err.message });
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
export const reviewdogAgent = {
|
|
159
|
+
id: 'reviewdog',
|
|
160
|
+
name: 'Reviewdog',
|
|
161
|
+
usesLlm: false,
|
|
162
|
+
supports(file) {
|
|
163
|
+
// Reviewdog works with any file that semgrep supports
|
|
164
|
+
return file.status !== 'deleted';
|
|
165
|
+
},
|
|
166
|
+
async run(context) {
|
|
167
|
+
const startTime = Date.now();
|
|
168
|
+
// Check if semgrep is available (primary requirement)
|
|
169
|
+
if (!isSemgrepAvailable()) {
|
|
170
|
+
console.log('[reviewdog] Semgrep binary not found, skipping');
|
|
171
|
+
return AgentSkipped({
|
|
172
|
+
agentId: 'reviewdog',
|
|
173
|
+
reason: 'Semgrep binary not found',
|
|
174
|
+
metrics: {
|
|
175
|
+
durationMs: Date.now() - startTime,
|
|
176
|
+
filesProcessed: 0,
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
// Get file paths
|
|
181
|
+
const filePaths = context.files.filter((f) => this.supports(f)).map((f) => f.path);
|
|
182
|
+
if (filePaths.length === 0) {
|
|
183
|
+
return AgentSkipped({
|
|
184
|
+
agentId: 'reviewdog',
|
|
185
|
+
reason: 'No files to process',
|
|
186
|
+
metrics: {
|
|
187
|
+
durationMs: Date.now() - startTime,
|
|
188
|
+
filesProcessed: 0,
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
console.log(`[reviewdog] Processing ${filePaths.length} files via semgrep`);
|
|
193
|
+
// ROUTER MONOPOLY RULE: Strip ALL tokens from environment
|
|
194
|
+
// Agents must NOT have access to posting credentials
|
|
195
|
+
const cleanEnv = buildAgentEnv('reviewdog', context.env);
|
|
196
|
+
// Primary path: Run semgrep directly and parse structured output
|
|
197
|
+
const result = await runSemgrepStructured(context.repoPath, filePaths, cleanEnv);
|
|
198
|
+
if (!result.success) {
|
|
199
|
+
return AgentFailure({
|
|
200
|
+
agentId: 'reviewdog',
|
|
201
|
+
error: result.error ?? 'Unknown semgrep error',
|
|
202
|
+
failureStage: 'exec',
|
|
203
|
+
partialFindings: [],
|
|
204
|
+
metrics: {
|
|
205
|
+
durationMs: Date.now() - startTime,
|
|
206
|
+
filesProcessed: 0,
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
// Optional: If reviewdog is available, run it in local mode for validation
|
|
211
|
+
// This verifies the output format but does NOT post to GitHub
|
|
212
|
+
if (isReviewdogAvailable() && result.findings.length > 0) {
|
|
213
|
+
const tempFile = join(tmpdir(), `semgrep-${Date.now()}.json`);
|
|
214
|
+
try {
|
|
215
|
+
// Re-run semgrep to get raw JSON for reviewdog validation
|
|
216
|
+
// Use same safe paths from earlier filtering
|
|
217
|
+
const { safePaths: validationPaths } = filterSafePaths(filePaths, 'reviewdog');
|
|
218
|
+
const semgrepOutput = execFileSync('semgrep', ['scan', '--config=auto', '--json', ...validationPaths], {
|
|
219
|
+
cwd: context.repoPath,
|
|
220
|
+
encoding: 'utf-8',
|
|
221
|
+
shell: false,
|
|
222
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
223
|
+
timeout: 300000,
|
|
224
|
+
env: cleanEnv,
|
|
225
|
+
});
|
|
226
|
+
writeFileSync(tempFile, semgrepOutput);
|
|
227
|
+
const validation = await runReviewdogLocal(context.repoPath, tempFile, cleanEnv);
|
|
228
|
+
if (!validation.success) {
|
|
229
|
+
console.warn(`[reviewdog] Local validation warning: ${validation.error}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
// Semgrep may throw on findings - ignore for validation
|
|
234
|
+
}
|
|
235
|
+
finally {
|
|
236
|
+
try {
|
|
237
|
+
if (existsSync(tempFile)) {
|
|
238
|
+
unlinkSync(tempFile);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
// Ignore cleanup errors
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
console.log(`[reviewdog] Found ${result.findings.length} findings`);
|
|
247
|
+
// Return structured findings for router to post
|
|
248
|
+
// Router owns all GitHub API interactions per INVARIANTS.md #1
|
|
249
|
+
return AgentSuccess({
|
|
250
|
+
agentId: 'reviewdog',
|
|
251
|
+
findings: result.findings,
|
|
252
|
+
metrics: {
|
|
253
|
+
durationMs: Date.now() - startTime,
|
|
254
|
+
filesProcessed: filePaths.length,
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
//# sourceMappingURL=reviewdog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewdog.js","sourceRoot":"","sources":["../../src/agents/reviewdog.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,EAAE,YAAY,EAAqB,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEtE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAyB3D;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,IAAI,CAAC;QACH,YAAY,CAAC,WAAW,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,IAAI,CAAC;QACH,YAAY,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1E,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,eAAuB;IACjD,QAAQ,eAAe,CAAC,WAAW,EAAE,EAAE,CAAC;QACtC,KAAK,OAAO;YACV,OAAO,OAAO,CAAC;QACjB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,MAAM,CAAC;QACZ;YACE,OAAO,MAAM,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,oBAAoB,CACjC,QAAgB,EAChB,SAAmB,EACnB,IAA4B;IAE5B,qDAAqD;IACrD,MAAM,EAAE,SAAS,EAAE,GAAG,eAAe,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC9D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC;IAC/E,CAAC;IAED,sDAAsD;IACtD,IAAI,aAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,aAAa,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC,EAAE;YACzF,GAAG,EAAE,QAAQ;YACb,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,KAAK,EAAE,oCAAoC;YAClD,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;YAC3B,OAAO,EAAE,MAAM,EAAE,mBAAmB;YACpC,GAAG,EAAE,IAAI,EAAE,uBAAuB;SACnC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,0DAA0D;QAC1D,qCAAqC;QACrC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;YAC5D,aAAa,GAAI,KAA4B,CAAC,MAAM,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,EAAE;gBACZ,KAAK,EAAE,mBAAmB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE;aACrF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,4BAA4B;IAC5B,IAAI,MAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAkB,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,OAAO,EAAE,KAAK;YACd,QAAQ,EAAE,EAAE;YACZ,KAAK,EAAE,qCAAqC;SAC7C,CAAC;IACJ,CAAC;IAED,iCAAiC;IACjC,MAAM,QAAQ,GAAc,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACxD,MAAM,OAAO,GAAY;YACvB,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;YAC5C,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI;YACvB,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI;YACxB,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO;YAC7B,MAAM,EAAE,MAAM,CAAC,QAAQ;YACvB,WAAW,EAAE,WAAW;YACxB,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG;YAC5B,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ;SAChC,CAAC;QAEF,8BAA8B;QAC9B,OAAO,CAAC,WAAW,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAEnD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,iBAAiB,CAC9B,QAAgB,EAChB,eAAuB,EACvB,QAAgC;IAEhC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,oDAAoD;QACpD,+CAA+C;QAC/C,MAAM,SAAS,GAAiB,KAAK,CACnC,WAAW,EACX,CAAC,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,CAAC,EACrD;YACE,GAAG,EAAE,QAAQ;YACb,GAAG,EAAE,QAAQ,EAAE,uBAAuB;YACtC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CACF,CAAC;QAEF,MAAM,KAAK,GAAG,gBAAgB,CAAC,eAAe,CAAC,CAAC;QAChD,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;QAED,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACpC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAC/B,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC7B,2DAA2D;gBAC3D,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,IAAI,KAAK,MAAM,EAAE,EAAE,CAAC,CAAC;YACtF,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YAC9B,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAgB;IACzC,EAAE,EAAE,WAAW;IACf,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,KAAK;IAEd,QAAQ,CAAC,IAAc;QACrB,sDAAsD;QACtD,OAAO,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAqB;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,sDAAsD;QACtD,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;YAC9D,OAAO,YAAY,CAAC;gBAClB,OAAO,EAAE,WAAW;gBACpB,MAAM,EAAE,0BAA0B;gBAClC,OAAO,EAAE;oBACP,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;oBAClC,cAAc,EAAE,CAAC;iBAClB;aACF,CAAC,CAAC;QACL,CAAC;QAED,iBAAiB;QACjB,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEnF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,YAAY,CAAC;gBAClB,OAAO,EAAE,WAAW;gBACpB,MAAM,EAAE,qBAAqB;gBAC7B,OAAO,EAAE;oBACP,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;oBAClC,cAAc,EAAE,CAAC;iBAClB;aACF,CAAC,CAAC;QACL,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,0BAA0B,SAAS,CAAC,MAAM,oBAAoB,CAAC,CAAC;QAE5E,0DAA0D;QAC1D,qDAAqD;QACrD,MAAM,QAAQ,GAAG,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QAEzD,iEAAiE;QACjE,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QAEjF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,YAAY,CAAC;gBAClB,OAAO,EAAE,WAAW;gBACpB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,uBAAuB;gBAC9C,YAAY,EAAE,MAAM;gBACpB,eAAe,EAAE,EAAE;gBACnB,OAAO,EAAE;oBACP,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;oBAClC,cAAc,EAAE,CAAC;iBAClB;aACF,CAAC,CAAC;QACL,CAAC;QAED,2EAA2E;QAC3E,8DAA8D;QAC9D,IAAI,oBAAoB,EAAE,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,WAAW,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC9D,IAAI,CAAC;gBACH,0DAA0D;gBAC1D,6CAA6C;gBAC7C,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,eAAe,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;gBAC/E,MAAM,aAAa,GAAG,YAAY,CAChC,SAAS,EACT,CAAC,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAC,EACvD;oBACE,GAAG,EAAE,OAAO,CAAC,QAAQ;oBACrB,QAAQ,EAAE,OAAO;oBACjB,KAAK,EAAE,KAAK;oBACZ,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;oBAC3B,OAAO,EAAE,MAAM;oBACf,GAAG,EAAE,QAAQ;iBACd,CACF,CAAC;gBACF,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;gBAEvC,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBACjF,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;oBACxB,OAAO,CAAC,IAAI,CAAC,yCAAyC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC5E,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,wDAAwD;YAC1D,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC;oBACH,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;wBACzB,UAAU,CAAC,QAAQ,CAAC,CAAC;oBACvB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,wBAAwB;gBAC1B,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,qBAAqB,MAAM,CAAC,QAAQ,CAAC,MAAM,WAAW,CAAC,CAAC;QAEpE,gDAAgD;QAChD,+DAA+D;QAC/D,OAAO,YAAY,CAAC;YAClB,OAAO,EAAE,WAAW;YACpB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,OAAO,EAAE;gBACP,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;gBAClC,cAAc,EAAE,SAAS,CAAC,MAAM;aACjC;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Security Module
|
|
3
|
+
*
|
|
4
|
+
* Provides security utilities for agent subprocess execution:
|
|
5
|
+
* - Token stripping (Router Monopoly Rule enforcement)
|
|
6
|
+
* - Network listener detection (CVE-2026-22812 mitigation)
|
|
7
|
+
*
|
|
8
|
+
* INVARIANTS ENFORCED:
|
|
9
|
+
* - No Direct Secrets to Agents (Invariant 7)
|
|
10
|
+
* - No Network Listeners in Agent Execution (Invariant 10)
|
|
11
|
+
*/
|
|
12
|
+
export type AgentId = 'semgrep' | 'reviewdog' | 'opencode' | 'pr_agent' | 'ai_semantic_review' | 'local_llm';
|
|
13
|
+
/**
|
|
14
|
+
* Strip all posting tokens from environment variables.
|
|
15
|
+
* Returns a clean environment safe for agent subprocesses.
|
|
16
|
+
*
|
|
17
|
+
* SECURITY: This enforces the Router Monopoly Rule - agents must not have
|
|
18
|
+
* access to tokens that would allow them to post directly to GitHub/ADO.
|
|
19
|
+
*/
|
|
20
|
+
export declare function stripTokensFromEnv(env: Record<string, string | undefined>): Record<string, string>;
|
|
21
|
+
export declare function buildRouterEnv(env: Record<string, string | undefined>): Record<string, string | undefined>;
|
|
22
|
+
export declare function buildAgentEnv(agentId: AgentId, env: Record<string, string | undefined>): Record<string, string>;
|
|
23
|
+
export declare function isKnownAgentId(agentId: string): agentId is AgentId;
|
|
24
|
+
/**
|
|
25
|
+
* Check if a specific token exists in the environment.
|
|
26
|
+
* Used for testing that tokens were properly stripped.
|
|
27
|
+
*/
|
|
28
|
+
export declare function hasTokenInEnv(env: Record<string, string | undefined>): {
|
|
29
|
+
hasToken: boolean;
|
|
30
|
+
tokens: string[];
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Validate that no process is listening on network ports.
|
|
34
|
+
* Used to detect if an agent has started an HTTP server (CVE mitigation).
|
|
35
|
+
*
|
|
36
|
+
* @param processName - Optional process name to filter by
|
|
37
|
+
* @returns Object indicating if the check passed and any error message
|
|
38
|
+
*/
|
|
39
|
+
export declare function validateNoListeningSockets(processName?: string): Promise<{
|
|
40
|
+
safe: boolean;
|
|
41
|
+
error?: string;
|
|
42
|
+
listeners?: string[];
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* Create a sanitized subprocess environment.
|
|
46
|
+
* Removes tokens and sets security-hardening variables.
|
|
47
|
+
*/
|
|
48
|
+
export declare function createSafeAgentEnv(baseEnv: Record<string, string | undefined>, allowedKeys?: string[]): Record<string, string>;
|
|
49
|
+
//# sourceMappingURL=security.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/agents/security.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,MAAM,OAAO,GACf,SAAS,GACT,WAAW,GACX,UAAU,GACV,UAAU,GACV,oBAAoB,GACpB,WAAW,CAAC;AAuIhB;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACtC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqBxB;AAiBD,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACtC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAEpC;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACtC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIxB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,IAAI,OAAO,CAElE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG;IACtE,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAUA;AAED;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9E,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC,CA+DD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAC3C,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmCxB"}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Security Module
|
|
3
|
+
*
|
|
4
|
+
* Provides security utilities for agent subprocess execution:
|
|
5
|
+
* - Token stripping (Router Monopoly Rule enforcement)
|
|
6
|
+
* - Network listener detection (CVE-2026-22812 mitigation)
|
|
7
|
+
*
|
|
8
|
+
* INVARIANTS ENFORCED:
|
|
9
|
+
* - No Direct Secrets to Agents (Invariant 7)
|
|
10
|
+
* - No Network Listeners in Agent Execution (Invariant 10)
|
|
11
|
+
*/
|
|
12
|
+
import { execFileSync, execSync } from 'child_process';
|
|
13
|
+
const COMMON_AGENT_ENV_ALLOWLIST = [
|
|
14
|
+
'PATH',
|
|
15
|
+
'HOME',
|
|
16
|
+
'TMPDIR',
|
|
17
|
+
'TMP',
|
|
18
|
+
'TEMP',
|
|
19
|
+
'LANG',
|
|
20
|
+
'LC_ALL',
|
|
21
|
+
'TERM',
|
|
22
|
+
'NO_COLOR',
|
|
23
|
+
'NODE_ENV',
|
|
24
|
+
];
|
|
25
|
+
const AGENT_ENV_ALLOWLIST = {
|
|
26
|
+
semgrep: [],
|
|
27
|
+
reviewdog: [],
|
|
28
|
+
opencode: ['OPENAI_API_KEY', 'ANTHROPIC_API_KEY', 'MODEL'],
|
|
29
|
+
pr_agent: [
|
|
30
|
+
'OPENAI_API_KEY',
|
|
31
|
+
'ANTHROPIC_API_KEY',
|
|
32
|
+
'AZURE_OPENAI_API_KEY',
|
|
33
|
+
'AZURE_OPENAI_ENDPOINT',
|
|
34
|
+
'AZURE_OPENAI_DEPLOYMENT',
|
|
35
|
+
'MODEL',
|
|
36
|
+
],
|
|
37
|
+
ai_semantic_review: [
|
|
38
|
+
'OPENAI_API_KEY',
|
|
39
|
+
'ANTHROPIC_API_KEY',
|
|
40
|
+
'AZURE_OPENAI_API_KEY',
|
|
41
|
+
'AZURE_OPENAI_ENDPOINT',
|
|
42
|
+
'AZURE_OPENAI_DEPLOYMENT',
|
|
43
|
+
'MODEL',
|
|
44
|
+
],
|
|
45
|
+
local_llm: [
|
|
46
|
+
'OLLAMA_BASE_URL',
|
|
47
|
+
'OLLAMA_MODEL',
|
|
48
|
+
'LOCAL_LLM_OPTIONAL',
|
|
49
|
+
'LOCAL_LLM_NUM_CTX',
|
|
50
|
+
'LOCAL_LLM_NUM_PREDICT',
|
|
51
|
+
'LOCAL_LLM_TIMEOUT',
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
const ROUTER_ENV_ALLOWLIST = [
|
|
55
|
+
// GitHub CI context (router-only, NOT passed to agents)
|
|
56
|
+
'GITHUB_TOKEN',
|
|
57
|
+
'GITHUB_ACTOR',
|
|
58
|
+
'GITHUB_HEAD_REPO',
|
|
59
|
+
'GITHUB_REPOSITORY',
|
|
60
|
+
'GITHUB_EVENT_NAME',
|
|
61
|
+
'GITHUB_EVENT_PULL_REQUEST_DRAFT',
|
|
62
|
+
'GITHUB_REF',
|
|
63
|
+
'GITHUB_REF_NAME',
|
|
64
|
+
'GITHUB_BASE_REF',
|
|
65
|
+
'GITHUB_WORKSPACE',
|
|
66
|
+
'GITHUB_ACTIONS',
|
|
67
|
+
// Azure DevOps CI context (router-only, NOT passed to agents)
|
|
68
|
+
'SYSTEM_ACCESSTOKEN', // ADO pipeline token
|
|
69
|
+
'AZURE_DEVOPS_PAT', // PAT fallback for local testing/cross-org
|
|
70
|
+
'SYSTEM_TEAMFOUNDATIONCOLLECTIONURI',
|
|
71
|
+
'SYSTEM_TEAMPROJECT',
|
|
72
|
+
'BUILD_REPOSITORY_URI',
|
|
73
|
+
'BUILD_REPOSITORY_NAME',
|
|
74
|
+
'BUILD_SOURCEVERSION',
|
|
75
|
+
'BUILD_REASON',
|
|
76
|
+
'SYSTEM_PULLREQUEST_PULLREQUESTID',
|
|
77
|
+
'SYSTEM_PULLREQUEST_SOURCEBRANCH',
|
|
78
|
+
'SYSTEM_PULLREQUEST_TARGETBRANCH',
|
|
79
|
+
'SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI',
|
|
80
|
+
'BUILD_REQUESTEDFOR',
|
|
81
|
+
'TF_BUILD',
|
|
82
|
+
// Cross-platform
|
|
83
|
+
'CI',
|
|
84
|
+
// System
|
|
85
|
+
'PATH',
|
|
86
|
+
'HOME',
|
|
87
|
+
'TMPDIR',
|
|
88
|
+
'TMP',
|
|
89
|
+
'TEMP',
|
|
90
|
+
'LANG',
|
|
91
|
+
'LC_ALL',
|
|
92
|
+
'TERM',
|
|
93
|
+
'NODE_ENV',
|
|
94
|
+
// AI Provider Keys (canonical only)
|
|
95
|
+
'OPENAI_API_KEY',
|
|
96
|
+
'ANTHROPIC_API_KEY',
|
|
97
|
+
'AZURE_OPENAI_API_KEY',
|
|
98
|
+
'AZURE_OPENAI_ENDPOINT',
|
|
99
|
+
'AZURE_OPENAI_DEPLOYMENT',
|
|
100
|
+
'OLLAMA_BASE_URL',
|
|
101
|
+
'OLLAMA_MODEL',
|
|
102
|
+
// Local LLM tuning
|
|
103
|
+
'LOCAL_LLM_OPTIONAL',
|
|
104
|
+
'LOCAL_LLM_NUM_CTX',
|
|
105
|
+
'LOCAL_LLM_NUM_PREDICT',
|
|
106
|
+
'LOCAL_LLM_TIMEOUT',
|
|
107
|
+
// Model selection (canonical)
|
|
108
|
+
'MODEL',
|
|
109
|
+
];
|
|
110
|
+
/**
|
|
111
|
+
* List of environment variable patterns that should be stripped from agent subprocesses.
|
|
112
|
+
* These are tokens that would allow agents to post to GitHub/ADO directly.
|
|
113
|
+
*/
|
|
114
|
+
const TOKEN_PATTERNS = [
|
|
115
|
+
// GitHub tokens
|
|
116
|
+
'GITHUB_TOKEN',
|
|
117
|
+
'GH_TOKEN',
|
|
118
|
+
'GITHUB_PAT',
|
|
119
|
+
'GH_PAT',
|
|
120
|
+
// Azure DevOps tokens
|
|
121
|
+
'AZURE_DEVOPS_PAT',
|
|
122
|
+
'ADO_TOKEN',
|
|
123
|
+
'SYSTEM_ACCESSTOKEN',
|
|
124
|
+
// Generic posting tokens
|
|
125
|
+
'REVIEWDOG_GITHUB_API_TOKEN',
|
|
126
|
+
// Any variable containing TOKEN (case-insensitive)
|
|
127
|
+
/^.*_TOKEN$/i,
|
|
128
|
+
/^.*_PAT$/i,
|
|
129
|
+
];
|
|
130
|
+
/**
|
|
131
|
+
* Check if an environment variable name matches a token pattern
|
|
132
|
+
*/
|
|
133
|
+
function isTokenVariable(name) {
|
|
134
|
+
return TOKEN_PATTERNS.some((pattern) => {
|
|
135
|
+
if (typeof pattern === 'string') {
|
|
136
|
+
return name === pattern;
|
|
137
|
+
}
|
|
138
|
+
return pattern.test(name);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Strip all posting tokens from environment variables.
|
|
143
|
+
* Returns a clean environment safe for agent subprocesses.
|
|
144
|
+
*
|
|
145
|
+
* SECURITY: This enforces the Router Monopoly Rule - agents must not have
|
|
146
|
+
* access to tokens that would allow them to post directly to GitHub/ADO.
|
|
147
|
+
*/
|
|
148
|
+
export function stripTokensFromEnv(env) {
|
|
149
|
+
const clean = {};
|
|
150
|
+
const stripped = [];
|
|
151
|
+
for (const [key, value] of Object.entries(env)) {
|
|
152
|
+
if (value === undefined)
|
|
153
|
+
continue;
|
|
154
|
+
if (isTokenVariable(key)) {
|
|
155
|
+
stripped.push(key);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
clean[key] = value;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (stripped.length > 0) {
|
|
162
|
+
console.log(`[security] Stripped ${stripped.length} tokens from agent environment: ${stripped.join(', ')}`);
|
|
163
|
+
}
|
|
164
|
+
return clean;
|
|
165
|
+
}
|
|
166
|
+
function pickEnv(env, allowlist) {
|
|
167
|
+
const picked = {};
|
|
168
|
+
for (const key of allowlist) {
|
|
169
|
+
if (env[key] !== undefined) {
|
|
170
|
+
picked[key] = env[key];
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return picked;
|
|
174
|
+
}
|
|
175
|
+
export function buildRouterEnv(env) {
|
|
176
|
+
return pickEnv(env, ROUTER_ENV_ALLOWLIST);
|
|
177
|
+
}
|
|
178
|
+
export function buildAgentEnv(agentId, env) {
|
|
179
|
+
const allowlist = new Set([...COMMON_AGENT_ENV_ALLOWLIST, ...AGENT_ENV_ALLOWLIST[agentId]]);
|
|
180
|
+
const picked = pickEnv(env, [...allowlist]);
|
|
181
|
+
return createSafeAgentEnv(picked, Object.keys(picked));
|
|
182
|
+
}
|
|
183
|
+
export function isKnownAgentId(agentId) {
|
|
184
|
+
return Object.prototype.hasOwnProperty.call(AGENT_ENV_ALLOWLIST, agentId);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Check if a specific token exists in the environment.
|
|
188
|
+
* Used for testing that tokens were properly stripped.
|
|
189
|
+
*/
|
|
190
|
+
export function hasTokenInEnv(env) {
|
|
191
|
+
const tokens = [];
|
|
192
|
+
for (const key of Object.keys(env)) {
|
|
193
|
+
if (env[key] !== undefined && isTokenVariable(key)) {
|
|
194
|
+
tokens.push(key);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return { hasToken: tokens.length > 0, tokens };
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Validate that no process is listening on network ports.
|
|
201
|
+
* Used to detect if an agent has started an HTTP server (CVE mitigation).
|
|
202
|
+
*
|
|
203
|
+
* @param processName - Optional process name to filter by
|
|
204
|
+
* @returns Object indicating if the check passed and any error message
|
|
205
|
+
*/
|
|
206
|
+
export async function validateNoListeningSockets(processName) {
|
|
207
|
+
try {
|
|
208
|
+
try {
|
|
209
|
+
// Use 'which' instead of 'command -v' because command is a shell builtin
|
|
210
|
+
// and execSync doesn't use a shell by default
|
|
211
|
+
execSync('which lsof', { encoding: 'utf-8', stdio: 'ignore', timeout: 2000 });
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
return { safe: false, error: 'Listener detection unavailable: lsof not installed' };
|
|
215
|
+
}
|
|
216
|
+
// Use lsof to find listening TCP sockets
|
|
217
|
+
// -i TCP -sTCP:LISTEN shows only listening TCP connections
|
|
218
|
+
// -n -P prevents hostname and port name resolution for speed
|
|
219
|
+
let output = '';
|
|
220
|
+
try {
|
|
221
|
+
output = execFileSync('lsof', ['-i', 'TCP', '-sTCP:LISTEN', '-n', '-P'], {
|
|
222
|
+
encoding: 'utf-8',
|
|
223
|
+
timeout: 5000,
|
|
224
|
+
stdio: ['pipe', 'pipe', 'ignore'], // ignore stderr
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// lsof returns non-zero if no listeners found, which is fine
|
|
229
|
+
output = '';
|
|
230
|
+
}
|
|
231
|
+
if (!output.trim()) {
|
|
232
|
+
return { safe: true };
|
|
233
|
+
}
|
|
234
|
+
// Parse lsof output
|
|
235
|
+
const lines = output.trim().split('\n');
|
|
236
|
+
const listeners = [];
|
|
237
|
+
for (const line of lines.slice(1)) {
|
|
238
|
+
// Skip header line
|
|
239
|
+
const parts = line.split(/\s+/);
|
|
240
|
+
const command = parts[0] ?? '';
|
|
241
|
+
const pid = parts[1] ?? '';
|
|
242
|
+
const name = parts[8] ?? '';
|
|
243
|
+
// If processName specified, only flag matching processes
|
|
244
|
+
if (processName && !command.toLowerCase().includes(processName.toLowerCase())) {
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
listeners.push(`${command}(${pid}) listening on ${name}`);
|
|
248
|
+
}
|
|
249
|
+
if (listeners.length > 0) {
|
|
250
|
+
return {
|
|
251
|
+
safe: false,
|
|
252
|
+
error: `Detected ${listeners.length} listening socket(s): ${listeners.join('; ')}`,
|
|
253
|
+
listeners,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
return { safe: true };
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
return {
|
|
260
|
+
safe: false,
|
|
261
|
+
error: `Listener detection failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Create a sanitized subprocess environment.
|
|
267
|
+
* Removes tokens and sets security-hardening variables.
|
|
268
|
+
*/
|
|
269
|
+
export function createSafeAgentEnv(baseEnv, allowedKeys) {
|
|
270
|
+
// Start with stripped environment
|
|
271
|
+
const clean = stripTokensFromEnv(baseEnv);
|
|
272
|
+
// Add security-hardening defaults
|
|
273
|
+
const safeEnv = {
|
|
274
|
+
// Preserve PATH for subprocess execution
|
|
275
|
+
PATH: clean['PATH'] ?? '/usr/local/bin:/usr/bin:/bin',
|
|
276
|
+
// Preserve locale settings
|
|
277
|
+
LANG: clean['LANG'] ?? 'en_US.UTF-8',
|
|
278
|
+
LC_ALL: clean['LC_ALL'] ?? 'en_US.UTF-8',
|
|
279
|
+
// Disable color output for consistent parsing
|
|
280
|
+
NO_COLOR: '1',
|
|
281
|
+
// PEP 540 UTF-8 Mode: Forces Python to use UTF-8 for all I/O, preventing
|
|
282
|
+
// Windows cp1252 encoding crashes in Python-based tools (Semgrep, etc.).
|
|
283
|
+
// Harmless no-op for non-Python subprocesses - the env var is simply ignored.
|
|
284
|
+
// We intentionally override any user-provided value as a safety invariant.
|
|
285
|
+
// See: https://peps.python.org/pep-0540/
|
|
286
|
+
PYTHONUTF8: '1',
|
|
287
|
+
// Set HOME for tools that need it
|
|
288
|
+
HOME: clean['HOME'] ?? '/tmp',
|
|
289
|
+
// Preserve TERM for proper output handling
|
|
290
|
+
TERM: clean['TERM'] ?? 'dumb',
|
|
291
|
+
};
|
|
292
|
+
// Add allowed keys from original environment
|
|
293
|
+
if (allowedKeys) {
|
|
294
|
+
for (const key of allowedKeys) {
|
|
295
|
+
if (clean[key] !== undefined) {
|
|
296
|
+
safeEnv[key] = clean[key];
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return safeEnv;
|
|
301
|
+
}
|
|
302
|
+
//# sourceMappingURL=security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/agents/security.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semgrep Agent
|
|
3
|
+
* Static analysis using Semgrep for security and bug patterns
|
|
4
|
+
*/
|
|
5
|
+
import type { ReviewAgent, Severity } from './types.js';
|
|
6
|
+
export declare const semgrepAgent: ReviewAgent;
|
|
7
|
+
export declare function mapSeverity(semgrepSeverity: string): Severity;
|
|
8
|
+
//# sourceMappingURL=semgrep.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semgrep.d.ts","sourceRoot":"","sources":["../../src/agents/semgrep.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAsC,QAAQ,EAAE,MAAM,YAAY,CAAC;AAgD5F,eAAO,MAAM,YAAY,EAAE,WAwI1B,CAAC;AAEF,wBAAgB,WAAW,CAAC,eAAe,EAAE,MAAM,GAAG,QAAQ,CAS7D"}
|