@delegance/claude-autopilot 5.0.0 → 5.0.2
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/presets/go/rules/go-sql-injection.d.ts +4 -0
- package/dist/presets/nextjs-supabase/rules/supabase-rls-bypass.d.ts +4 -0
- package/dist/presets/python-fastapi/rules/fastapi-missing-auth.d.ts +4 -0
- package/dist/presets/rails-postgres/rules/rails-sql-injection.d.ts +4 -0
- package/dist/presets/t3/rules/t3-server-only.d.ts +4 -0
- package/dist/src/adapters/base.d.ts +11 -0
- package/dist/src/adapters/council/claude.d.ts +3 -0
- package/dist/src/adapters/council/openai.d.ts +3 -0
- package/dist/src/adapters/council/types.d.ts +5 -0
- package/dist/src/adapters/loader.d.ts +11 -0
- package/dist/src/adapters/migration-runner/supabase.d.ts +4 -0
- package/dist/src/adapters/migration-runner/types.d.ts +31 -0
- package/dist/src/adapters/review-bot-parser/cursor.d.ts +3 -0
- package/dist/src/adapters/review-bot-parser/declarative-base.d.ts +13 -0
- package/{src/adapters/review-bot-parser/types.ts → dist/src/adapters/review-bot-parser/types.d.ts} +4 -4
- package/dist/src/adapters/review-engine/auto.d.ts +4 -0
- package/dist/src/adapters/review-engine/claude.d.ts +4 -0
- package/dist/src/adapters/review-engine/codex.d.ts +4 -0
- package/dist/src/adapters/review-engine/gemini.d.ts +4 -0
- package/dist/src/adapters/review-engine/openai-compatible.d.ts +4 -0
- package/dist/src/adapters/review-engine/parse-output.d.ts +13 -0
- package/dist/src/adapters/review-engine/prompt-builder.d.ts +4 -0
- package/dist/src/adapters/review-engine/types.d.ts +28 -0
- package/dist/src/adapters/vcs-host/commit-status.d.ts +12 -0
- package/dist/src/adapters/vcs-host/github.d.ts +4 -0
- package/dist/src/adapters/vcs-host/types.d.ts +42 -0
- package/{src/cli/_pkg-root.ts → dist/src/cli/_pkg-root.d.ts} +4 -42
- package/dist/src/cli/autoregress-bridge.d.ts +3 -0
- package/dist/src/cli/baseline.d.ts +7 -0
- package/dist/src/cli/ci.d.ts +23 -0
- package/dist/src/cli/costs.d.ts +2 -0
- package/dist/src/cli/council.d.ts +8 -0
- package/dist/src/cli/detector.d.ts +8 -0
- package/dist/src/cli/explain.d.ts +8 -0
- package/dist/src/cli/fix.d.ts +10 -0
- package/dist/src/cli/hook.d.ts +9 -0
- package/dist/src/cli/ignore-helper.d.ts +7 -0
- package/dist/src/cli/index.d.ts +3 -0
- package/dist/src/cli/index.js +39 -1
- package/dist/src/cli/lsp.d.ts +29 -0
- package/dist/src/cli/mcp.d.ts +5 -0
- package/dist/src/cli/migrate-v4.d.ts +28 -0
- package/dist/src/cli/pr-comment.d.ts +13 -0
- package/dist/src/cli/pr-desc.d.ts +31 -0
- package/dist/src/cli/pr-review-comments.d.ts +12 -0
- package/dist/src/cli/pr.d.ts +9 -0
- package/dist/src/cli/preflight.d.ts +8 -0
- package/dist/src/cli/preflight.js +17 -4
- package/dist/src/cli/report.d.ts +7 -0
- package/dist/src/cli/run.d.ts +23 -0
- package/dist/src/cli/scan.d.ts +11 -0
- package/dist/src/cli/setup.d.ts +9 -0
- package/dist/src/cli/test-gen.d.ts +10 -0
- package/dist/src/cli/triage.d.ts +5 -0
- package/dist/src/cli/watch.d.ts +18 -0
- package/dist/src/cli/worker.d.ts +5 -0
- package/dist/src/core/cache/cached-engine.d.ts +8 -0
- package/dist/src/core/cache/review-cache.d.ts +21 -0
- package/dist/src/core/chunking/index.d.ts +18 -0
- package/dist/src/core/chunking/risk-ranker.d.ts +10 -0
- package/dist/src/core/config/loader.d.ts +3 -0
- package/dist/src/core/config/preset-resolver.d.ts +9 -0
- package/dist/src/core/config/schema.d.ts +342 -0
- package/dist/src/core/config/types.d.ts +115 -0
- package/dist/src/core/council/config.d.ts +3 -0
- package/dist/src/core/council/context.d.ts +2 -0
- package/dist/src/core/council/runner.d.ts +4 -0
- package/dist/src/core/council/types.d.ts +36 -0
- package/dist/src/core/detect/git-context.d.ts +12 -0
- package/dist/src/core/detect/llm-key.d.ts +38 -0
- package/dist/src/core/detect/protected-paths.d.ts +6 -0
- package/dist/src/core/detect/provider-usage.d.ts +17 -0
- package/dist/src/core/detect/stack.d.ts +6 -0
- package/dist/src/core/detect/workspaces.d.ts +11 -0
- package/dist/src/core/errors.d.ts +17 -0
- package/dist/src/core/findings/dedup.d.ts +4 -0
- package/dist/src/core/findings/types.d.ts +33 -0
- package/dist/src/core/fix/generator.d.ts +17 -0
- package/dist/src/core/git/diff-hunks.d.ts +22 -0
- package/dist/src/core/git/touched-files.d.ts +11 -0
- package/dist/src/core/ignore/index.d.ts +11 -0
- package/dist/src/core/index.d.ts +2 -0
- package/dist/src/core/logging/ndjson-writer.d.ts +16 -0
- package/dist/src/core/logging/redaction.d.ts +4 -0
- package/dist/src/core/mcp/concurrency.d.ts +2 -0
- package/dist/src/core/mcp/handlers/fix-finding.d.ts +17 -0
- package/dist/src/core/mcp/handlers/get-capabilities.d.ts +14 -0
- package/dist/src/core/mcp/handlers/get-findings.d.ts +13 -0
- package/dist/src/core/mcp/handlers/review-diff.d.ts +18 -0
- package/dist/src/core/mcp/handlers/scan-files.d.ts +15 -0
- package/dist/src/core/mcp/handlers/validate-fix.d.ts +12 -0
- package/dist/src/core/mcp/run-store.d.ts +12 -0
- package/dist/src/core/mcp/workspace.d.ts +3 -0
- package/dist/src/core/persist/baseline.d.ts +39 -0
- package/dist/src/core/persist/cost-log.d.ts +11 -0
- package/dist/src/core/persist/findings-cache.d.ts +9 -0
- package/dist/src/core/persist/triage.d.ts +30 -0
- package/dist/src/core/phases/static-rules.d.ts +24 -0
- package/dist/src/core/phases/tests.d.ts +15 -0
- package/dist/src/core/pipeline/review-phase.d.ts +27 -0
- package/dist/src/core/pipeline/run.d.ts +27 -0
- package/dist/src/core/runtime/idempotency.d.ts +2 -0
- package/dist/src/core/runtime/lock.d.ts +5 -0
- package/dist/src/core/runtime/state.d.ts +39 -0
- package/dist/src/core/schema-alignment/detector.d.ts +3 -0
- package/dist/src/core/schema-alignment/extractor/index.d.ts +3 -0
- package/dist/src/core/schema-alignment/extractor/prisma.d.ts +3 -0
- package/dist/src/core/schema-alignment/extractor/sql.d.ts +3 -0
- package/dist/src/core/schema-alignment/llm-check.d.ts +4 -0
- package/dist/src/core/schema-alignment/scanner.d.ts +3 -0
- package/dist/src/core/schema-alignment/types.d.ts +38 -0
- package/dist/src/core/shell.d.ts +15 -0
- package/dist/src/core/static-rules/registry.d.ts +5 -0
- package/dist/src/core/static-rules/rules/brand-tokens.d.ts +3 -0
- package/dist/src/core/static-rules/rules/console-log.d.ts +3 -0
- package/dist/src/core/static-rules/rules/hardcoded-secrets.d.ts +3 -0
- package/dist/src/core/static-rules/rules/insecure-redirect.d.ts +3 -0
- package/dist/src/core/static-rules/rules/large-file.d.ts +3 -0
- package/dist/src/core/static-rules/rules/missing-auth.d.ts +3 -0
- package/dist/src/core/static-rules/rules/missing-tests.d.ts +3 -0
- package/dist/src/core/static-rules/rules/npm-audit.d.ts +3 -0
- package/dist/src/core/static-rules/rules/package-lock-sync.d.ts +3 -0
- package/dist/src/core/static-rules/rules/schema-alignment.d.ts +3 -0
- package/dist/src/core/static-rules/rules/sql-injection.d.ts +3 -0
- package/dist/src/core/static-rules/rules/ssrf.d.ts +3 -0
- package/dist/src/core/static-rules/rules/todo-fixme.d.ts +3 -0
- package/dist/src/core/static-rules/tailwind-extractor.d.ts +7 -0
- package/dist/src/core/test-gen/coverage-analyzer.d.ts +7 -0
- package/dist/src/core/test-gen/framework-detector.d.ts +3 -0
- package/dist/src/core/test-gen/test-writer.d.ts +4 -0
- package/dist/src/core/ui/design-context-loader.d.ts +7 -0
- package/dist/src/core/worker/client.d.ts +23 -0
- package/dist/src/core/worker/lockfile.d.ts +12 -0
- package/dist/src/core/worker/server.d.ts +17 -0
- package/dist/src/formatters/github-annotations.d.ts +5 -0
- package/{src/formatters/index.ts → dist/src/formatters/index.d.ts} +1 -0
- package/dist/src/formatters/junit.d.ts +5 -0
- package/dist/src/formatters/sarif.d.ts +56 -0
- package/{src/index.ts → dist/src/index.d.ts} +1 -0
- package/package.json +7 -6
- package/dist/presets/go/rules/go-sql-injection.js.map +0 -1
- package/dist/presets/nextjs-supabase/rules/supabase-rls-bypass.js.map +0 -1
- package/dist/presets/python-fastapi/rules/fastapi-missing-auth.js.map +0 -1
- package/dist/presets/rails-postgres/rules/rails-sql-injection.js.map +0 -1
- package/dist/presets/t3/rules/t3-server-only.js.map +0 -1
- package/dist/src/adapters/base.js.map +0 -1
- package/dist/src/adapters/council/claude.js.map +0 -1
- package/dist/src/adapters/council/openai.js.map +0 -1
- package/dist/src/adapters/council/types.js.map +0 -1
- package/dist/src/adapters/loader.js.map +0 -1
- package/dist/src/adapters/migration-runner/supabase.js.map +0 -1
- package/dist/src/adapters/migration-runner/types.js.map +0 -1
- package/dist/src/adapters/review-bot-parser/cursor.js.map +0 -1
- package/dist/src/adapters/review-bot-parser/declarative-base.js.map +0 -1
- package/dist/src/adapters/review-bot-parser/types.js.map +0 -1
- package/dist/src/adapters/review-engine/auto.js.map +0 -1
- package/dist/src/adapters/review-engine/claude.js.map +0 -1
- package/dist/src/adapters/review-engine/codex.js.map +0 -1
- package/dist/src/adapters/review-engine/gemini.js.map +0 -1
- package/dist/src/adapters/review-engine/openai-compatible.js.map +0 -1
- package/dist/src/adapters/review-engine/parse-output.js.map +0 -1
- package/dist/src/adapters/review-engine/prompt-builder.js.map +0 -1
- package/dist/src/adapters/review-engine/types.js.map +0 -1
- package/dist/src/adapters/vcs-host/commit-status.js.map +0 -1
- package/dist/src/adapters/vcs-host/github.js.map +0 -1
- package/dist/src/adapters/vcs-host/types.js.map +0 -1
- package/dist/src/cli/_pkg-root.js.map +0 -1
- package/dist/src/cli/autoregress-bridge.js.map +0 -1
- package/dist/src/cli/baseline.js.map +0 -1
- package/dist/src/cli/ci.js.map +0 -1
- package/dist/src/cli/costs.js.map +0 -1
- package/dist/src/cli/council.js.map +0 -1
- package/dist/src/cli/detector.js.map +0 -1
- package/dist/src/cli/explain.js.map +0 -1
- package/dist/src/cli/fix.js.map +0 -1
- package/dist/src/cli/hook.js.map +0 -1
- package/dist/src/cli/ignore-helper.js.map +0 -1
- package/dist/src/cli/index.js.map +0 -1
- package/dist/src/cli/lsp.js.map +0 -1
- package/dist/src/cli/mcp.js.map +0 -1
- package/dist/src/cli/migrate-v4.js.map +0 -1
- package/dist/src/cli/pr-comment.js.map +0 -1
- package/dist/src/cli/pr-desc.js.map +0 -1
- package/dist/src/cli/pr-review-comments.js.map +0 -1
- package/dist/src/cli/pr.js.map +0 -1
- package/dist/src/cli/preflight.js.map +0 -1
- package/dist/src/cli/report.js.map +0 -1
- package/dist/src/cli/run.js.map +0 -1
- package/dist/src/cli/scan.js.map +0 -1
- package/dist/src/cli/setup.js.map +0 -1
- package/dist/src/cli/test-gen.js.map +0 -1
- package/dist/src/cli/triage.js.map +0 -1
- package/dist/src/cli/watch.js.map +0 -1
- package/dist/src/cli/worker.js.map +0 -1
- package/dist/src/core/cache/cached-engine.js.map +0 -1
- package/dist/src/core/cache/review-cache.js.map +0 -1
- package/dist/src/core/chunking/index.js.map +0 -1
- package/dist/src/core/chunking/risk-ranker.js.map +0 -1
- package/dist/src/core/config/loader.js.map +0 -1
- package/dist/src/core/config/preset-resolver.js.map +0 -1
- package/dist/src/core/config/schema.js.map +0 -1
- package/dist/src/core/config/types.js.map +0 -1
- package/dist/src/core/council/config.js.map +0 -1
- package/dist/src/core/council/context.js.map +0 -1
- package/dist/src/core/council/runner.js.map +0 -1
- package/dist/src/core/council/types.js.map +0 -1
- package/dist/src/core/detect/git-context.js.map +0 -1
- package/dist/src/core/detect/llm-key.js.map +0 -1
- package/dist/src/core/detect/protected-paths.js.map +0 -1
- package/dist/src/core/detect/provider-usage.js.map +0 -1
- package/dist/src/core/detect/stack.js.map +0 -1
- package/dist/src/core/detect/workspaces.js.map +0 -1
- package/dist/src/core/errors.js.map +0 -1
- package/dist/src/core/findings/dedup.js.map +0 -1
- package/dist/src/core/findings/types.js.map +0 -1
- package/dist/src/core/fix/generator.js.map +0 -1
- package/dist/src/core/git/diff-hunks.js.map +0 -1
- package/dist/src/core/git/touched-files.js.map +0 -1
- package/dist/src/core/ignore/index.js.map +0 -1
- package/dist/src/core/index.js.map +0 -1
- package/dist/src/core/logging/ndjson-writer.js.map +0 -1
- package/dist/src/core/logging/redaction.js.map +0 -1
- package/dist/src/core/mcp/concurrency.js.map +0 -1
- package/dist/src/core/mcp/handlers/fix-finding.js.map +0 -1
- package/dist/src/core/mcp/handlers/get-capabilities.js.map +0 -1
- package/dist/src/core/mcp/handlers/get-findings.js.map +0 -1
- package/dist/src/core/mcp/handlers/review-diff.js.map +0 -1
- package/dist/src/core/mcp/handlers/scan-files.js.map +0 -1
- package/dist/src/core/mcp/handlers/validate-fix.js.map +0 -1
- package/dist/src/core/mcp/run-store.js.map +0 -1
- package/dist/src/core/mcp/workspace.js.map +0 -1
- package/dist/src/core/persist/baseline.js.map +0 -1
- package/dist/src/core/persist/cost-log.js.map +0 -1
- package/dist/src/core/persist/findings-cache.js.map +0 -1
- package/dist/src/core/persist/triage.js.map +0 -1
- package/dist/src/core/phases/static-rules.js.map +0 -1
- package/dist/src/core/phases/tests.js.map +0 -1
- package/dist/src/core/pipeline/review-phase.js.map +0 -1
- package/dist/src/core/pipeline/run.js.map +0 -1
- package/dist/src/core/runtime/idempotency.js.map +0 -1
- package/dist/src/core/runtime/lock.js.map +0 -1
- package/dist/src/core/runtime/state.js.map +0 -1
- package/dist/src/core/schema-alignment/detector.js.map +0 -1
- package/dist/src/core/schema-alignment/extractor/index.js.map +0 -1
- package/dist/src/core/schema-alignment/extractor/prisma.js.map +0 -1
- package/dist/src/core/schema-alignment/extractor/sql.js.map +0 -1
- package/dist/src/core/schema-alignment/llm-check.js.map +0 -1
- package/dist/src/core/schema-alignment/scanner.js.map +0 -1
- package/dist/src/core/schema-alignment/types.js.map +0 -1
- package/dist/src/core/shell.js.map +0 -1
- package/dist/src/core/static-rules/registry.js.map +0 -1
- package/dist/src/core/static-rules/rules/brand-tokens.js.map +0 -1
- package/dist/src/core/static-rules/rules/console-log.js.map +0 -1
- package/dist/src/core/static-rules/rules/hardcoded-secrets.js.map +0 -1
- package/dist/src/core/static-rules/rules/insecure-redirect.js.map +0 -1
- package/dist/src/core/static-rules/rules/large-file.js.map +0 -1
- package/dist/src/core/static-rules/rules/missing-auth.js.map +0 -1
- package/dist/src/core/static-rules/rules/missing-tests.js.map +0 -1
- package/dist/src/core/static-rules/rules/npm-audit.js.map +0 -1
- package/dist/src/core/static-rules/rules/package-lock-sync.js.map +0 -1
- package/dist/src/core/static-rules/rules/schema-alignment.js.map +0 -1
- package/dist/src/core/static-rules/rules/sql-injection.js.map +0 -1
- package/dist/src/core/static-rules/rules/ssrf.js.map +0 -1
- package/dist/src/core/static-rules/rules/todo-fixme.js.map +0 -1
- package/dist/src/core/static-rules/tailwind-extractor.js.map +0 -1
- package/dist/src/core/test-gen/coverage-analyzer.js.map +0 -1
- package/dist/src/core/test-gen/framework-detector.js.map +0 -1
- package/dist/src/core/test-gen/test-writer.js.map +0 -1
- package/dist/src/core/ui/design-context-loader.js.map +0 -1
- package/dist/src/core/worker/client.js.map +0 -1
- package/dist/src/core/worker/lockfile.js.map +0 -1
- package/dist/src/core/worker/server.js.map +0 -1
- package/dist/src/formatters/github-annotations.js.map +0 -1
- package/dist/src/formatters/index.js.map +0 -1
- package/dist/src/formatters/junit.js.map +0 -1
- package/dist/src/formatters/sarif.js.map +0 -1
- package/dist/src/index.js.map +0 -1
- package/src/adapters/base.ts +0 -19
- package/src/adapters/council/claude.ts +0 -41
- package/src/adapters/council/openai.ts +0 -40
- package/src/adapters/council/types.ts +0 -7
- package/src/adapters/loader.ts +0 -108
- package/src/adapters/migration-runner/supabase.ts +0 -56
- package/src/adapters/migration-runner/types.ts +0 -36
- package/src/adapters/review-bot-parser/cursor.ts +0 -13
- package/src/adapters/review-bot-parser/declarative-base.ts +0 -64
- package/src/adapters/review-engine/auto.ts +0 -94
- package/src/adapters/review-engine/claude.ts +0 -100
- package/src/adapters/review-engine/codex.ts +0 -82
- package/src/adapters/review-engine/gemini.ts +0 -105
- package/src/adapters/review-engine/openai-compatible.ts +0 -100
- package/src/adapters/review-engine/parse-output.ts +0 -74
- package/src/adapters/review-engine/prompt-builder.ts +0 -19
- package/src/adapters/review-engine/types.ts +0 -19
- package/src/adapters/vcs-host/commit-status.ts +0 -39
- package/src/adapters/vcs-host/github.ts +0 -77
- package/src/adapters/vcs-host/types.ts +0 -44
- package/src/cli/autoregress-bridge.ts +0 -30
- package/src/cli/baseline.ts +0 -125
- package/src/cli/ci.ts +0 -45
- package/src/cli/costs.ts +0 -80
- package/src/cli/council.ts +0 -96
- package/src/cli/detector.ts +0 -92
- package/src/cli/explain.ts +0 -197
- package/src/cli/fix.ts +0 -249
- package/src/cli/hook.ts +0 -124
- package/src/cli/ignore-helper.ts +0 -116
- package/src/cli/index.ts +0 -612
- package/src/cli/lsp.ts +0 -200
- package/src/cli/mcp.ts +0 -206
- package/src/cli/migrate-v4.ts +0 -388
- package/src/cli/pr-comment.ts +0 -139
- package/src/cli/pr-desc.ts +0 -168
- package/src/cli/pr-review-comments.ts +0 -92
- package/src/cli/pr.ts +0 -76
- package/src/cli/preflight.ts +0 -235
- package/src/cli/report.ts +0 -186
- package/src/cli/run.ts +0 -425
- package/src/cli/scan.ts +0 -233
- package/src/cli/setup.ts +0 -191
- package/src/cli/test-gen.ts +0 -125
- package/src/cli/triage.ts +0 -137
- package/src/cli/watch.ts +0 -190
- package/src/cli/worker.ts +0 -109
- package/src/core/.gitkeep +0 -0
- package/src/core/cache/cached-engine.ts +0 -32
- package/src/core/cache/review-cache.ts +0 -70
- package/src/core/chunking/index.ts +0 -113
- package/src/core/chunking/risk-ranker.ts +0 -56
- package/src/core/config/loader.ts +0 -53
- package/src/core/config/preset-resolver.ts +0 -46
- package/src/core/config/schema.ts +0 -181
- package/src/core/config/types.ts +0 -98
- package/src/core/council/config.ts +0 -71
- package/src/core/council/context.ts +0 -17
- package/src/core/council/runner.ts +0 -83
- package/src/core/council/types.ts +0 -45
- package/src/core/detect/git-context.ts +0 -27
- package/src/core/detect/llm-key.ts +0 -89
- package/src/core/detect/protected-paths.ts +0 -63
- package/src/core/detect/provider-usage.ts +0 -74
- package/src/core/detect/stack.ts +0 -153
- package/src/core/detect/workspaces.ts +0 -103
- package/src/core/errors.ts +0 -37
- package/src/core/findings/dedup.ts +0 -14
- package/src/core/findings/types.ts +0 -39
- package/src/core/fix/generator.ts +0 -149
- package/src/core/git/diff-hunks.ts +0 -86
- package/src/core/git/touched-files.ts +0 -73
- package/src/core/ignore/index.ts +0 -54
- package/src/core/index.ts +0 -1
- package/src/core/logging/ndjson-writer.ts +0 -37
- package/src/core/logging/redaction.ts +0 -19
- package/src/core/mcp/concurrency.ts +0 -16
- package/src/core/mcp/handlers/fix-finding.ts +0 -126
- package/src/core/mcp/handlers/get-capabilities.ts +0 -62
- package/src/core/mcp/handlers/get-findings.ts +0 -36
- package/src/core/mcp/handlers/review-diff.ts +0 -65
- package/src/core/mcp/handlers/scan-files.ts +0 -65
- package/src/core/mcp/handlers/validate-fix.ts +0 -41
- package/src/core/mcp/run-store.ts +0 -85
- package/src/core/mcp/workspace.ts +0 -35
- package/src/core/persist/baseline.ts +0 -112
- package/src/core/persist/cost-log.ts +0 -30
- package/src/core/persist/findings-cache.ts +0 -43
- package/src/core/persist/triage.ts +0 -112
- package/src/core/phases/static-rules.ts +0 -93
- package/src/core/phases/tests.ts +0 -51
- package/src/core/pipeline/review-phase.ts +0 -182
- package/src/core/pipeline/run.ts +0 -116
- package/src/core/runtime/idempotency.ts +0 -6
- package/src/core/runtime/lock.ts +0 -29
- package/src/core/runtime/state.ts +0 -97
- package/src/core/schema-alignment/detector.ts +0 -59
- package/src/core/schema-alignment/extractor/index.ts +0 -24
- package/src/core/schema-alignment/extractor/prisma.ts +0 -21
- package/src/core/schema-alignment/extractor/sql.ts +0 -99
- package/src/core/schema-alignment/llm-check.ts +0 -91
- package/src/core/schema-alignment/scanner.ts +0 -107
- package/src/core/schema-alignment/types.ts +0 -43
- package/src/core/shell.ts +0 -48
- package/src/core/static-rules/registry.ts +0 -59
- package/src/core/static-rules/rules/brand-tokens.ts +0 -145
- package/src/core/static-rules/rules/console-log.ts +0 -42
- package/src/core/static-rules/rules/hardcoded-secrets.ts +0 -83
- package/src/core/static-rules/rules/insecure-redirect.ts +0 -67
- package/src/core/static-rules/rules/large-file.ts +0 -37
- package/src/core/static-rules/rules/missing-auth.ts +0 -70
- package/src/core/static-rules/rules/missing-tests.ts +0 -57
- package/src/core/static-rules/rules/npm-audit.ts +0 -38
- package/src/core/static-rules/rules/package-lock-sync.ts +0 -54
- package/src/core/static-rules/rules/schema-alignment.ts +0 -132
- package/src/core/static-rules/rules/sql-injection.ts +0 -71
- package/src/core/static-rules/rules/ssrf.ts +0 -63
- package/src/core/static-rules/rules/todo-fixme.ts +0 -40
- package/src/core/static-rules/tailwind-extractor.ts +0 -38
- package/src/core/test-gen/coverage-analyzer.ts +0 -93
- package/src/core/test-gen/framework-detector.ts +0 -21
- package/src/core/test-gen/test-writer.ts +0 -33
- package/src/core/ui/design-context-loader.ts +0 -87
- package/src/core/worker/client.ts +0 -46
- package/src/core/worker/lockfile.ts +0 -38
- package/src/core/worker/server.ts +0 -81
- package/src/formatters/github-annotations.ts +0 -36
- package/src/formatters/junit.ts +0 -52
- package/src/formatters/sarif.ts +0 -103
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
-
import { GuardrailError } from '../../core/errors.ts';
|
|
3
|
-
import type { Capabilities } from '../base.ts';
|
|
4
|
-
import type { ReviewEngine, ReviewInput, ReviewOutput } from './types.ts';
|
|
5
|
-
import { parseReviewOutput } from './parse-output.ts';
|
|
6
|
-
import { buildSystemPrompt, classifyError } from './prompt-builder.ts';
|
|
7
|
-
|
|
8
|
-
const DEFAULT_MODEL = 'claude-opus-4-7';
|
|
9
|
-
const MAX_OUTPUT_TOKENS = 4096;
|
|
10
|
-
|
|
11
|
-
// Cost per million tokens (USD) — opus-4-7 pricing
|
|
12
|
-
const COST_PER_M_INPUT = 15.0;
|
|
13
|
-
const COST_PER_M_OUTPUT = 75.0;
|
|
14
|
-
|
|
15
|
-
const SYSTEM_PROMPT_TEMPLATE = `You are a senior software architect reviewing code changes for quality, security, and correctness.
|
|
16
|
-
|
|
17
|
-
The codebase context:
|
|
18
|
-
{STACK}{GIT_CONTEXT}{DESIGN_SCHEMA}
|
|
19
|
-
|
|
20
|
-
Provide structured feedback in exactly this format:
|
|
21
|
-
|
|
22
|
-
## Review Summary
|
|
23
|
-
One paragraph overall assessment.
|
|
24
|
-
|
|
25
|
-
## Findings
|
|
26
|
-
|
|
27
|
-
For each finding, use this format:
|
|
28
|
-
### [CRITICAL|WARNING|NOTE] <short title>
|
|
29
|
-
<explanation>
|
|
30
|
-
**Suggestion:** <actionable fix>
|
|
31
|
-
|
|
32
|
-
Rules:
|
|
33
|
-
- CRITICAL: Blocks merge (security issues, data loss risks, broken contracts)
|
|
34
|
-
- WARNING: Should address before merging (logic errors, missing error handling, test gaps)
|
|
35
|
-
- NOTE: Improvement suggestion (style, performance, clarity)
|
|
36
|
-
- Maximum 10 findings, ranked by severity
|
|
37
|
-
- Be specific and constructive
|
|
38
|
-
- Reference the file and line when possible`;
|
|
39
|
-
|
|
40
|
-
export const claudeAdapter: ReviewEngine = {
|
|
41
|
-
name: 'claude',
|
|
42
|
-
apiVersion: '1.0.0',
|
|
43
|
-
|
|
44
|
-
getCapabilities(): Capabilities {
|
|
45
|
-
return { structuredOutput: false, streaming: false, maxContextTokens: 200000, inlineComments: false };
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
estimateTokens(content: string): number {
|
|
49
|
-
return Math.ceil(content.length / 3.5);
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
async review(input: ReviewInput): Promise<ReviewOutput> {
|
|
53
|
-
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
54
|
-
if (!apiKey) {
|
|
55
|
-
throw new GuardrailError('ANTHROPIC_API_KEY not set', { code: 'auth', provider: 'claude' });
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const model = (input.context as Record<string, unknown> | undefined)?.['model'] as string | undefined ?? DEFAULT_MODEL;
|
|
59
|
-
const systemPrompt = buildSystemPrompt(input, SYSTEM_PROMPT_TEMPLATE);
|
|
60
|
-
|
|
61
|
-
const client = new Anthropic({ apiKey });
|
|
62
|
-
let response: Anthropic.Message;
|
|
63
|
-
try {
|
|
64
|
-
response = await client.messages.create({
|
|
65
|
-
model,
|
|
66
|
-
max_tokens: MAX_OUTPUT_TOKENS,
|
|
67
|
-
system: systemPrompt,
|
|
68
|
-
messages: [{ role: 'user', content: `Please review the following:\n\n---\n\n${input.content}` }],
|
|
69
|
-
});
|
|
70
|
-
} catch (err) {
|
|
71
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
72
|
-
const code = classifyError(message);
|
|
73
|
-
throw new GuardrailError(`Claude review call failed: ${message}`, {
|
|
74
|
-
code,
|
|
75
|
-
provider: 'claude',
|
|
76
|
-
retryable: code === 'rate_limit',
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const rawOutput = response.content
|
|
81
|
-
.filter(b => b.type === 'text')
|
|
82
|
-
.map(b => (b as Anthropic.TextBlock).text)
|
|
83
|
-
.join('');
|
|
84
|
-
|
|
85
|
-
const costUSD = response.usage
|
|
86
|
-
? (response.usage.input_tokens / 1_000_000) * COST_PER_M_INPUT +
|
|
87
|
-
(response.usage.output_tokens / 1_000_000) * COST_PER_M_OUTPUT
|
|
88
|
-
: undefined;
|
|
89
|
-
|
|
90
|
-
return {
|
|
91
|
-
findings: parseReviewOutput(rawOutput, 'claude'),
|
|
92
|
-
rawOutput,
|
|
93
|
-
usage: response.usage
|
|
94
|
-
? { input: response.usage.input_tokens, output: response.usage.output_tokens, costUSD }
|
|
95
|
-
: undefined,
|
|
96
|
-
};
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
export default claudeAdapter;
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import OpenAI from 'openai';
|
|
2
|
-
import { parseReviewOutput } from './parse-output.ts';
|
|
3
|
-
import { GuardrailError } from '../../core/errors.ts';
|
|
4
|
-
import type { Capabilities } from '../base.ts';
|
|
5
|
-
import type { ReviewEngine, ReviewInput, ReviewOutput } from './types.ts';
|
|
6
|
-
import { buildSystemPrompt, classifyError } from './prompt-builder.ts';
|
|
7
|
-
|
|
8
|
-
const DEFAULT_MODEL = process.env.CODEX_MODEL ?? 'gpt-5.3-codex';
|
|
9
|
-
const MAX_OUTPUT_TOKENS = 4096;
|
|
10
|
-
|
|
11
|
-
const SYSTEM_PROMPT_TEMPLATE = `You are a senior software architect providing feedback on designs, proposals, and ideas.
|
|
12
|
-
|
|
13
|
-
The codebase context:
|
|
14
|
-
{STACK}{GIT_CONTEXT}{DESIGN_SCHEMA}
|
|
15
|
-
|
|
16
|
-
Provide structured feedback in exactly this format:
|
|
17
|
-
|
|
18
|
-
## Review Summary
|
|
19
|
-
One paragraph overall assessment.
|
|
20
|
-
|
|
21
|
-
## Findings
|
|
22
|
-
|
|
23
|
-
For each finding, use this format:
|
|
24
|
-
### [CRITICAL|WARNING|NOTE] <short title>
|
|
25
|
-
<explanation>
|
|
26
|
-
**Suggestion:** <actionable fix>
|
|
27
|
-
|
|
28
|
-
Rules:
|
|
29
|
-
- CRITICAL: Blocks implementation
|
|
30
|
-
- WARNING: Should address before implementing
|
|
31
|
-
- NOTE: Improvement suggestion
|
|
32
|
-
- Maximum 10 findings, ranked by severity
|
|
33
|
-
- Be specific and constructive`;
|
|
34
|
-
|
|
35
|
-
export const codexAdapter: ReviewEngine = {
|
|
36
|
-
name: 'codex',
|
|
37
|
-
apiVersion: '1.0.0',
|
|
38
|
-
|
|
39
|
-
getCapabilities(): Capabilities {
|
|
40
|
-
return { structuredOutput: false, streaming: false, maxContextTokens: 128000, inlineComments: false };
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
estimateTokens(content: string): number {
|
|
44
|
-
return Math.ceil(content.length / 4);
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
async review(input: ReviewInput): Promise<ReviewOutput> {
|
|
48
|
-
const apiKey = process.env.OPENAI_API_KEY;
|
|
49
|
-
if (!apiKey) {
|
|
50
|
-
throw new GuardrailError('OPENAI_API_KEY not set', { code: 'auth', provider: 'codex' });
|
|
51
|
-
}
|
|
52
|
-
const systemPrompt = buildSystemPrompt(input, SYSTEM_PROMPT_TEMPLATE);
|
|
53
|
-
|
|
54
|
-
const client = new OpenAI({ apiKey });
|
|
55
|
-
let response;
|
|
56
|
-
try {
|
|
57
|
-
response = await client.responses.create({
|
|
58
|
-
model: DEFAULT_MODEL,
|
|
59
|
-
instructions: systemPrompt,
|
|
60
|
-
input: `Please review the following:\n\n---\n\n${input.content}`,
|
|
61
|
-
max_output_tokens: MAX_OUTPUT_TOKENS,
|
|
62
|
-
});
|
|
63
|
-
} catch (err) {
|
|
64
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
65
|
-
const code = classifyError(message);
|
|
66
|
-
throw new GuardrailError(`Codex review call failed: ${message}`, {
|
|
67
|
-
code,
|
|
68
|
-
provider: 'codex',
|
|
69
|
-
retryable: code === 'rate_limit',
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const rawOutput = response.output_text ?? '';
|
|
74
|
-
return {
|
|
75
|
-
findings: parseReviewOutput(rawOutput, 'codex'),
|
|
76
|
-
rawOutput,
|
|
77
|
-
usage: response.usage ? { input: response.usage.input_tokens, output: response.usage.output_tokens } : undefined,
|
|
78
|
-
};
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export default codexAdapter;
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { GoogleGenerativeAI } from '@google/generative-ai';
|
|
2
|
-
import { parseReviewOutput } from './parse-output.ts';
|
|
3
|
-
import { GuardrailError } from '../../core/errors.ts';
|
|
4
|
-
import type { Capabilities } from '../base.ts';
|
|
5
|
-
import type { ReviewEngine, ReviewInput, ReviewOutput } from './types.ts';
|
|
6
|
-
import { buildSystemPrompt, classifyError } from './prompt-builder.ts';
|
|
7
|
-
|
|
8
|
-
const DEFAULT_MODEL = 'gemini-2.5-pro-preview-05-06';
|
|
9
|
-
const MAX_OUTPUT_TOKENS = 4096;
|
|
10
|
-
|
|
11
|
-
// Cost per million tokens (USD) — gemini-2.5-pro pricing (<200k context)
|
|
12
|
-
const COST_PER_M_INPUT = 1.25;
|
|
13
|
-
const COST_PER_M_OUTPUT = 10.0;
|
|
14
|
-
|
|
15
|
-
const PROMPT_TEMPLATE = `You are a senior software architect reviewing code changes for quality, security, and correctness.
|
|
16
|
-
|
|
17
|
-
The codebase context:
|
|
18
|
-
{STACK}{GIT_CONTEXT}{DESIGN_SCHEMA}
|
|
19
|
-
|
|
20
|
-
Please review the following:
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
{CONTENT}
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
Provide structured feedback in exactly this format:
|
|
29
|
-
|
|
30
|
-
## Review Summary
|
|
31
|
-
One paragraph overall assessment.
|
|
32
|
-
|
|
33
|
-
## Findings
|
|
34
|
-
|
|
35
|
-
For each finding, use this format:
|
|
36
|
-
### [CRITICAL|WARNING|NOTE] <short title>
|
|
37
|
-
<explanation>
|
|
38
|
-
**Suggestion:** <actionable fix>
|
|
39
|
-
|
|
40
|
-
Rules:
|
|
41
|
-
- CRITICAL: Blocks merge (security issues, data loss risks, broken contracts)
|
|
42
|
-
- WARNING: Should address before merging (logic errors, missing error handling, test gaps)
|
|
43
|
-
- NOTE: Improvement suggestion (style, performance, clarity)
|
|
44
|
-
- Maximum 10 findings, ranked by severity
|
|
45
|
-
- Be specific and constructive
|
|
46
|
-
- Reference the file and line when possible`;
|
|
47
|
-
|
|
48
|
-
export const geminiAdapter: ReviewEngine = {
|
|
49
|
-
name: 'gemini',
|
|
50
|
-
apiVersion: '1.0.0',
|
|
51
|
-
|
|
52
|
-
getCapabilities(): Capabilities {
|
|
53
|
-
return { structuredOutput: false, streaming: false, maxContextTokens: 1000000, inlineComments: false };
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
estimateTokens(content: string): number {
|
|
57
|
-
return Math.ceil(content.length / 4);
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
async review(input: ReviewInput): Promise<ReviewOutput> {
|
|
61
|
-
const apiKey = process.env.GEMINI_API_KEY ?? process.env.GOOGLE_API_KEY;
|
|
62
|
-
if (!apiKey) {
|
|
63
|
-
throw new GuardrailError('GEMINI_API_KEY (or GOOGLE_API_KEY) not set', { code: 'auth', provider: 'gemini' });
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const model = (input.context as Record<string, unknown> | undefined)?.['model'] as string | undefined ?? DEFAULT_MODEL;
|
|
67
|
-
const prompt = buildSystemPrompt(input, PROMPT_TEMPLATE).replace('{CONTENT}', input.content);
|
|
68
|
-
|
|
69
|
-
const genAI = new GoogleGenerativeAI(apiKey);
|
|
70
|
-
const genModel = genAI.getGenerativeModel({
|
|
71
|
-
model,
|
|
72
|
-
generationConfig: { maxOutputTokens: MAX_OUTPUT_TOKENS },
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
let result: Awaited<ReturnType<typeof genModel.generateContent>>;
|
|
76
|
-
try {
|
|
77
|
-
result = await genModel.generateContent(prompt);
|
|
78
|
-
} catch (err) {
|
|
79
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
80
|
-
const code = classifyError(message);
|
|
81
|
-
throw new GuardrailError(`Gemini review call failed: ${message}`, {
|
|
82
|
-
code,
|
|
83
|
-
provider: 'gemini',
|
|
84
|
-
retryable: code === 'rate_limit',
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const rawOutput = result.response.text();
|
|
89
|
-
const usage = result.response.usageMetadata;
|
|
90
|
-
const costUSD = usage
|
|
91
|
-
? (usage.promptTokenCount / 1_000_000) * COST_PER_M_INPUT +
|
|
92
|
-
(usage.candidatesTokenCount / 1_000_000) * COST_PER_M_OUTPUT
|
|
93
|
-
: undefined;
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
findings: parseReviewOutput(rawOutput, 'gemini'),
|
|
97
|
-
rawOutput,
|
|
98
|
-
usage: usage
|
|
99
|
-
? { input: usage.promptTokenCount, output: usage.candidatesTokenCount, costUSD }
|
|
100
|
-
: undefined,
|
|
101
|
-
};
|
|
102
|
-
},
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
export default geminiAdapter;
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import OpenAI from 'openai';
|
|
2
|
-
import { parseReviewOutput } from './parse-output.ts';
|
|
3
|
-
import { GuardrailError } from '../../core/errors.ts';
|
|
4
|
-
import type { Capabilities } from '../base.ts';
|
|
5
|
-
import type { ReviewEngine, ReviewInput, ReviewOutput } from './types.ts';
|
|
6
|
-
import { buildSystemPrompt, classifyError } from './prompt-builder.ts';
|
|
7
|
-
|
|
8
|
-
const MAX_OUTPUT_TOKENS = 4096;
|
|
9
|
-
|
|
10
|
-
const SYSTEM_PROMPT_TEMPLATE = `You are a senior software architect reviewing code changes for quality, security, and correctness.
|
|
11
|
-
|
|
12
|
-
The codebase context:
|
|
13
|
-
{STACK}{GIT_CONTEXT}{DESIGN_SCHEMA}
|
|
14
|
-
|
|
15
|
-
Provide structured feedback in exactly this format:
|
|
16
|
-
|
|
17
|
-
## Review Summary
|
|
18
|
-
One paragraph overall assessment.
|
|
19
|
-
|
|
20
|
-
## Findings
|
|
21
|
-
|
|
22
|
-
For each finding, use this format:
|
|
23
|
-
### [CRITICAL|WARNING|NOTE] <short title>
|
|
24
|
-
<explanation>
|
|
25
|
-
**Suggestion:** <actionable fix>
|
|
26
|
-
|
|
27
|
-
Rules:
|
|
28
|
-
- CRITICAL: Blocks merge (security issues, data loss risks, broken contracts)
|
|
29
|
-
- WARNING: Should address before merging (logic errors, missing error handling, test gaps)
|
|
30
|
-
- NOTE: Improvement suggestion (style, performance, clarity)
|
|
31
|
-
- Maximum 10 findings, ranked by severity
|
|
32
|
-
- Be specific and constructive
|
|
33
|
-
- Reference the file and line when possible`;
|
|
34
|
-
|
|
35
|
-
export const openaiCompatibleAdapter: ReviewEngine = {
|
|
36
|
-
name: 'openai-compatible',
|
|
37
|
-
apiVersion: '1.0.0',
|
|
38
|
-
|
|
39
|
-
getCapabilities(): Capabilities {
|
|
40
|
-
return { structuredOutput: false, streaming: false, maxContextTokens: 128000, inlineComments: false };
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
estimateTokens(content: string): number {
|
|
44
|
-
return Math.ceil(content.length / 4);
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
async review(input: ReviewInput): Promise<ReviewOutput> {
|
|
48
|
-
const opts = (input.context as Record<string, unknown> | undefined) ?? {};
|
|
49
|
-
|
|
50
|
-
// API key: options.apiKey → named env var → OPENAI_API_KEY
|
|
51
|
-
const apiKeyEnv = (opts['apiKeyEnv'] as string | undefined) ?? 'OPENAI_API_KEY';
|
|
52
|
-
const apiKey = (opts['apiKey'] as string | undefined) ?? process.env[apiKeyEnv] ?? 'ollama';
|
|
53
|
-
|
|
54
|
-
const baseURL = (opts['baseUrl'] as string | undefined) ??
|
|
55
|
-
process.env.OPENAI_BASE_URL ??
|
|
56
|
-
undefined;
|
|
57
|
-
|
|
58
|
-
const model = opts['model'] as string | undefined;
|
|
59
|
-
if (!model) {
|
|
60
|
-
throw new GuardrailError(
|
|
61
|
-
'openai-compatible adapter requires options.model to be set in guardrail.config.yaml',
|
|
62
|
-
{ code: 'invalid_config', provider: 'openai-compatible' },
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const systemPrompt = buildSystemPrompt(input, SYSTEM_PROMPT_TEMPLATE);
|
|
67
|
-
const client = new OpenAI({ apiKey, ...(baseURL ? { baseURL } : {}) });
|
|
68
|
-
|
|
69
|
-
let response: OpenAI.Chat.ChatCompletion;
|
|
70
|
-
try {
|
|
71
|
-
response = await client.chat.completions.create({
|
|
72
|
-
model,
|
|
73
|
-
max_tokens: MAX_OUTPUT_TOKENS,
|
|
74
|
-
messages: [
|
|
75
|
-
{ role: 'system', content: systemPrompt },
|
|
76
|
-
{ role: 'user', content: `Please review the following:\n\n---\n\n${input.content}` },
|
|
77
|
-
],
|
|
78
|
-
});
|
|
79
|
-
} catch (err) {
|
|
80
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
81
|
-
const code = classifyError(message);
|
|
82
|
-
throw new GuardrailError(`openai-compatible review call failed: ${message}`, {
|
|
83
|
-
code,
|
|
84
|
-
provider: 'openai-compatible',
|
|
85
|
-
retryable: code === 'rate_limit',
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const rawOutput = response.choices[0]?.message.content ?? '';
|
|
90
|
-
return {
|
|
91
|
-
findings: parseReviewOutput(rawOutput, 'openai-compatible'),
|
|
92
|
-
rawOutput,
|
|
93
|
-
usage: response.usage
|
|
94
|
-
? { input: response.usage.prompt_tokens, output: response.usage.completion_tokens }
|
|
95
|
-
: undefined,
|
|
96
|
-
};
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
export default openaiCompatibleAdapter;
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import type { Finding } from '../../core/findings/types.ts';
|
|
2
|
-
|
|
3
|
-
// Matches "path/to/file.ts:42", "`path/to/file.ts`", or bare filenames with common extensions
|
|
4
|
-
const FILE_REF = /(?:`([^`]+\.[a-z]{1,6})`|(\b[\w./\-]+\.[a-z]{1,6})(?::(\d+))?)/;
|
|
5
|
-
|
|
6
|
-
function extractFileRef(text: string): { file: string; line?: number } {
|
|
7
|
-
const m = text.match(FILE_REF);
|
|
8
|
-
if (!m) return { file: '<unspecified>' };
|
|
9
|
-
const raw = (m[1] ?? m[2])!;
|
|
10
|
-
// Skip version strings (v1.2.3) and bare dotfile extensions with no path separator
|
|
11
|
-
if (/^v?\d/.test(raw) || (!raw.includes('/') && raw.startsWith('.') && raw.split('.').length === 2)) {
|
|
12
|
-
return { file: '<unspecified>' };
|
|
13
|
-
}
|
|
14
|
-
const line = m[3] ? parseInt(m[3], 10) : undefined;
|
|
15
|
-
return { file: raw, line };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Accepts any of: `### [CRITICAL] title`, `### CRITICAL title`, `### **CRITICAL** title`,
|
|
19
|
-
// `### **[CRITICAL]** title`. Severity capture works across variants.
|
|
20
|
-
const FINDING_REGEX =
|
|
21
|
-
/### (?:\*\*)?\[?(CRITICAL|WARNING|NOTE)\]?(?:\*\*)?\s*(.+?)(?=\n### (?:\*\*)?\[?(?:CRITICAL|WARNING|NOTE)\]?|## Review Summary|$)/gs;
|
|
22
|
-
|
|
23
|
-
// "Substantive" output = enough non-whitespace chars to be a real LLM response, not
|
|
24
|
-
// an empty/placeholder string. Anything past this with zero parsed findings is likely
|
|
25
|
-
// format drift we should warn about.
|
|
26
|
-
const NONTRIVIAL_OUTPUT_THRESHOLD = 40;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Parses the structured CRITICAL|WARNING|NOTE markdown format produced by all review
|
|
30
|
-
* engine adapters. Extracts file:line references from the finding body when present.
|
|
31
|
-
*
|
|
32
|
-
* Tolerates common LLM format drift (missing brackets, bold wrappers) because the prompt
|
|
33
|
-
* alone doesn't guarantee literal `### [CRITICAL]` — models routinely emit
|
|
34
|
-
* `### CRITICAL` or `### **CRITICAL**`. A strict parser silently returns zero findings
|
|
35
|
-
* on otherwise-valid output, which is exactly the silent-failure mode this file exists to
|
|
36
|
-
* prevent.
|
|
37
|
-
*/
|
|
38
|
-
export function parseReviewOutput(output: string, idPrefix: string): Finding[] {
|
|
39
|
-
const findings: Finding[] = [];
|
|
40
|
-
for (const match of output.matchAll(FINDING_REGEX)) {
|
|
41
|
-
const severity = match[1]!.toLowerCase() as Finding['severity'];
|
|
42
|
-
const body = match[2]!.trim();
|
|
43
|
-
const titleEnd = body.indexOf('\n');
|
|
44
|
-
const title = (titleEnd > 0 ? body.slice(0, titleEnd) : body).trim();
|
|
45
|
-
const suggestion = body.match(/\*\*Suggestion:\*\*\s*(.+)/s)?.[1]?.trim();
|
|
46
|
-
const { file, line } = extractFileRef(body);
|
|
47
|
-
findings.push({
|
|
48
|
-
id: `${idPrefix}-${findings.length}`,
|
|
49
|
-
source: 'review-engine',
|
|
50
|
-
severity,
|
|
51
|
-
category: 'review-engine',
|
|
52
|
-
file,
|
|
53
|
-
line,
|
|
54
|
-
message: title,
|
|
55
|
-
suggestion,
|
|
56
|
-
protectedPath: false,
|
|
57
|
-
createdAt: new Date().toISOString(),
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (findings.length === 0) {
|
|
62
|
-
const nonWhitespace = output.replace(/\s/g, '').length;
|
|
63
|
-
if (nonWhitespace >= NONTRIVIAL_OUTPUT_THRESHOLD) {
|
|
64
|
-
const preview = output.slice(0, 200).replace(/\s+/g, ' ').trim();
|
|
65
|
-
// eslint-disable-next-line no-console
|
|
66
|
-
console.warn(
|
|
67
|
-
`[parseReviewOutput] LLM returned ${output.length} chars but no findings parsed. ` +
|
|
68
|
-
`Expected '### [CRITICAL|WARNING|NOTE] …'. Preview: ${preview}${output.length > 200 ? '…' : ''}`,
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return findings;
|
|
74
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { ReviewInput } from './types.ts';
|
|
2
|
-
|
|
3
|
-
const DEFAULT_STACK = 'A web application — stack details unspecified.';
|
|
4
|
-
|
|
5
|
-
export function buildSystemPrompt(input: ReviewInput, template: string): string {
|
|
6
|
-
const stack = input.context?.stack ?? DEFAULT_STACK;
|
|
7
|
-
const gitCtx = input.context?.gitSummary ? `\n\nChange context: ${input.context.gitSummary}` : '';
|
|
8
|
-
const designBlock = input.context?.designSchema ? `\n\n${input.context.designSchema}` : '';
|
|
9
|
-
return template
|
|
10
|
-
.replace('{STACK}', stack)
|
|
11
|
-
.replace('{GIT_CONTEXT}', gitCtx)
|
|
12
|
-
.replace('{DESIGN_SCHEMA}', designBlock);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function classifyError(message: string): 'auth' | 'rate_limit' | 'transient_network' {
|
|
16
|
-
if (/unauthorized|401|invalid.api.key|authentication|api.key|403/i.test(message)) return 'auth';
|
|
17
|
-
if (/rate.limit|429|overloaded|quota/i.test(message)) return 'rate_limit';
|
|
18
|
-
return 'transient_network';
|
|
19
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { AdapterBase } from '../base.ts';
|
|
2
|
-
import type { Finding } from '../../core/findings/types.ts';
|
|
3
|
-
|
|
4
|
-
export interface ReviewInput {
|
|
5
|
-
content: string;
|
|
6
|
-
kind: 'spec' | 'pr-diff' | 'file-batch';
|
|
7
|
-
context?: { spec?: string; plan?: string; stack?: string; cwd?: string; gitSummary?: string; designSchema?: string };
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface ReviewOutput {
|
|
11
|
-
findings: Finding[];
|
|
12
|
-
rawOutput: string;
|
|
13
|
-
usage?: { input: number; output: number; costUSD?: number };
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface ReviewEngine extends AdapterBase {
|
|
17
|
-
review(input: ReviewInput): Promise<ReviewOutput>;
|
|
18
|
-
estimateTokens(content: string): number;
|
|
19
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { runSafe } from '../../core/shell.ts';
|
|
2
|
-
|
|
3
|
-
export type CommitState = 'pending' | 'success' | 'failure' | 'error';
|
|
4
|
-
|
|
5
|
-
export interface CommitStatusOptions {
|
|
6
|
-
sha: string;
|
|
7
|
-
state: CommitState;
|
|
8
|
-
description?: string;
|
|
9
|
-
context?: string;
|
|
10
|
-
targetUrl?: string;
|
|
11
|
-
cwd?: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function getCurrentSha(cwd: string): string | null {
|
|
15
|
-
return runSafe('git', ['rev-parse', 'HEAD'], { cwd })?.trim() ?? null;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function resolveCommitSha(cwd: string, envSha?: string): string | null {
|
|
19
|
-
return envSha
|
|
20
|
-
?? process.env.GITHUB_SHA
|
|
21
|
-
?? getCurrentSha(cwd);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function postCommitStatus(opts: CommitStatusOptions): boolean {
|
|
25
|
-
const payload = JSON.stringify({
|
|
26
|
-
state: opts.state,
|
|
27
|
-
description: (opts.description ?? '').slice(0, 140),
|
|
28
|
-
context: opts.context ?? 'guardrail',
|
|
29
|
-
...(opts.targetUrl ? { target_url: opts.targetUrl } : {}),
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
const result = runSafe('gh', [
|
|
33
|
-
'api', `repos/{owner}/{repo}/statuses/${opts.sha}`,
|
|
34
|
-
'--method', 'POST',
|
|
35
|
-
'--input', '-',
|
|
36
|
-
], { cwd: opts.cwd, input: payload });
|
|
37
|
-
|
|
38
|
-
return result !== null;
|
|
39
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { runSafe, runThrowing } from '../../core/shell.ts';
|
|
2
|
-
import { GuardrailError } from '../../core/errors.ts';
|
|
3
|
-
import type { Capabilities } from '../base.ts';
|
|
4
|
-
import type { VcsHost, GenericComment, PrMetadata, CreatePrOptions, CreatePrResult } from './types.ts';
|
|
5
|
-
|
|
6
|
-
export const githubAdapter: VcsHost = {
|
|
7
|
-
name: 'github',
|
|
8
|
-
apiVersion: '1.0.0',
|
|
9
|
-
|
|
10
|
-
getCapabilities(): Capabilities {
|
|
11
|
-
return { structuredOutput: true, streaming: false, maxContextTokens: 0, inlineComments: true };
|
|
12
|
-
},
|
|
13
|
-
|
|
14
|
-
async getPrDiff(pr: number | string): Promise<string> {
|
|
15
|
-
const result = runSafe('gh', ['pr', 'diff', String(pr)]);
|
|
16
|
-
if (result === null) throw new GuardrailError(`Failed to get diff for PR ${pr}`, { code: 'transient_network' });
|
|
17
|
-
return result;
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
async getPrMetadata(pr: number | string): Promise<PrMetadata> {
|
|
21
|
-
const raw = runThrowing('gh', ['pr', 'view', String(pr), '--json', 'title,body,files,headRefOid,baseRefName,headRefName'], { errorCode: 'transient_network' });
|
|
22
|
-
const data = JSON.parse(raw) as { title: string; body: string; files: { path: string }[]; headRefOid: string; baseRefName: string; headRefName: string };
|
|
23
|
-
return {
|
|
24
|
-
title: data.title,
|
|
25
|
-
body: data.body ?? '',
|
|
26
|
-
files: (data.files ?? []).map((f: { path: string }) => f.path),
|
|
27
|
-
headSha: data.headRefOid,
|
|
28
|
-
baseRef: data.baseRefName,
|
|
29
|
-
headRef: data.headRefName,
|
|
30
|
-
};
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
async postComment(pr: number | string, body: string): Promise<void> {
|
|
34
|
-
runThrowing('gh', ['pr', 'comment', String(pr), '--body', body], { errorCode: 'transient_network' });
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
async getReviewComments(pr: number | string): Promise<GenericComment[]> {
|
|
38
|
-
const raw = runSafe('gh', ['api', `repos/{owner}/{repo}/pulls/${pr}/comments`, '--paginate']);
|
|
39
|
-
if (!raw) return [];
|
|
40
|
-
try {
|
|
41
|
-
const parsed = JSON.parse(raw) as Array<{ id: number; user: { login: string }; body: string; path: string; line?: number; html_url: string }>;
|
|
42
|
-
return parsed.map(c => ({ id: c.id, author: c.user.login, body: c.body, path: c.path, line: c.line, url: c.html_url }));
|
|
43
|
-
} catch { return []; }
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
async replyToComment(pr: number | string, commentId: string | number, body: string): Promise<void> {
|
|
47
|
-
runThrowing('gh', ['api', `repos/{owner}/{repo}/pulls/${pr}/comments/${commentId}/replies`, '--method', 'POST', '--field', `body=${body}`], { errorCode: 'transient_network' });
|
|
48
|
-
},
|
|
49
|
-
|
|
50
|
-
async createPr(opts: CreatePrOptions): Promise<CreatePrResult> {
|
|
51
|
-
const existing = runSafe('gh', ['pr', 'list', '--head', opts.head, '--json', 'number,url', '--limit', '1']);
|
|
52
|
-
if (existing) {
|
|
53
|
-
try {
|
|
54
|
-
const parsed = JSON.parse(existing) as Array<{ number: number; url: string }>;
|
|
55
|
-
if (parsed.length > 0 && parsed[0]) {
|
|
56
|
-
return { number: parsed[0].number, url: parsed[0].url, alreadyExisted: true };
|
|
57
|
-
}
|
|
58
|
-
} catch { /* fall through to create */ }
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const args = ['pr', 'create', '--title', opts.title, '--body', opts.body, '--base', opts.base, '--head', opts.head];
|
|
62
|
-
if (opts.draft) args.push('--draft');
|
|
63
|
-
const raw = runThrowing('gh', args, { errorCode: 'transient_network' });
|
|
64
|
-
const url = raw.trim();
|
|
65
|
-
const match = url.match(/\/pull\/(\d+)$/);
|
|
66
|
-
const number = match ? parseInt(match[1]!, 10) : 0;
|
|
67
|
-
return { number, url, alreadyExisted: false };
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
async push(branch: string, opts?: { setUpstream?: boolean }): Promise<void> {
|
|
71
|
-
const args = ['push', 'origin', branch];
|
|
72
|
-
if (opts?.setUpstream) args.splice(1, 0, '-u');
|
|
73
|
-
runThrowing('git', args, { errorCode: 'transient_network' });
|
|
74
|
-
},
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export default githubAdapter;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type { AdapterBase } from '../base.ts';
|
|
2
|
-
|
|
3
|
-
export interface GenericComment {
|
|
4
|
-
id: string | number;
|
|
5
|
-
author: string;
|
|
6
|
-
body: string;
|
|
7
|
-
path?: string;
|
|
8
|
-
line?: number;
|
|
9
|
-
url?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface PrMetadata {
|
|
13
|
-
title: string;
|
|
14
|
-
body: string;
|
|
15
|
-
files: string[];
|
|
16
|
-
headSha: string;
|
|
17
|
-
baseRef: string;
|
|
18
|
-
headRef: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface CreatePrOptions {
|
|
22
|
-
title: string;
|
|
23
|
-
body: string;
|
|
24
|
-
base: string;
|
|
25
|
-
head: string;
|
|
26
|
-
draft?: boolean;
|
|
27
|
-
idempotencyKey?: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface CreatePrResult {
|
|
31
|
-
number: number;
|
|
32
|
-
url: string;
|
|
33
|
-
alreadyExisted: boolean;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface VcsHost extends AdapterBase {
|
|
37
|
-
getPrDiff(pr: number | string): Promise<string>;
|
|
38
|
-
getPrMetadata(pr: number | string): Promise<PrMetadata>;
|
|
39
|
-
postComment(pr: number | string, body: string, idempotencyKey?: string): Promise<void>;
|
|
40
|
-
getReviewComments(pr: number | string): Promise<GenericComment[]>;
|
|
41
|
-
replyToComment(pr: number | string, commentId: string | number, body: string, idempotencyKey?: string): Promise<void>;
|
|
42
|
-
createPr(opts: CreatePrOptions): Promise<CreatePrResult>;
|
|
43
|
-
push(branch: string, opts?: { setUpstream?: boolean }): Promise<void>;
|
|
44
|
-
}
|