@delegance/claude-autopilot 5.0.1 → 5.0.3
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/src/adapters/review-engine/codex.js +13 -1
- package/dist/src/cli/index.js +39 -1
- package/dist/src/cli/preflight.js +17 -4
- package/dist/src/cli/scan.js +12 -0
- package/package.json +4 -3
- package/dist/presets/go/rules/go-sql-injection.d.ts.map +0 -1
- package/dist/presets/go/rules/go-sql-injection.js.map +0 -1
- package/dist/presets/nextjs-supabase/rules/supabase-rls-bypass.d.ts.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.d.ts.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.d.ts.map +0 -1
- package/dist/presets/rails-postgres/rules/rails-sql-injection.js.map +0 -1
- package/dist/presets/t3/rules/t3-server-only.d.ts.map +0 -1
- package/dist/presets/t3/rules/t3-server-only.js.map +0 -1
- package/dist/src/adapters/base.d.ts.map +0 -1
- package/dist/src/adapters/base.js.map +0 -1
- package/dist/src/adapters/council/claude.d.ts.map +0 -1
- package/dist/src/adapters/council/claude.js.map +0 -1
- package/dist/src/adapters/council/openai.d.ts.map +0 -1
- package/dist/src/adapters/council/openai.js.map +0 -1
- package/dist/src/adapters/council/types.d.ts.map +0 -1
- package/dist/src/adapters/council/types.js.map +0 -1
- package/dist/src/adapters/loader.d.ts.map +0 -1
- package/dist/src/adapters/loader.js.map +0 -1
- package/dist/src/adapters/migration-runner/supabase.d.ts.map +0 -1
- package/dist/src/adapters/migration-runner/supabase.js.map +0 -1
- package/dist/src/adapters/migration-runner/types.d.ts.map +0 -1
- package/dist/src/adapters/migration-runner/types.js.map +0 -1
- package/dist/src/adapters/review-bot-parser/cursor.d.ts.map +0 -1
- package/dist/src/adapters/review-bot-parser/cursor.js.map +0 -1
- package/dist/src/adapters/review-bot-parser/declarative-base.d.ts.map +0 -1
- package/dist/src/adapters/review-bot-parser/declarative-base.js.map +0 -1
- package/dist/src/adapters/review-bot-parser/types.d.ts.map +0 -1
- package/dist/src/adapters/review-bot-parser/types.js.map +0 -1
- package/dist/src/adapters/review-engine/auto.d.ts.map +0 -1
- package/dist/src/adapters/review-engine/auto.js.map +0 -1
- package/dist/src/adapters/review-engine/claude.d.ts.map +0 -1
- package/dist/src/adapters/review-engine/claude.js.map +0 -1
- package/dist/src/adapters/review-engine/codex.d.ts.map +0 -1
- package/dist/src/adapters/review-engine/codex.js.map +0 -1
- package/dist/src/adapters/review-engine/gemini.d.ts.map +0 -1
- package/dist/src/adapters/review-engine/gemini.js.map +0 -1
- package/dist/src/adapters/review-engine/openai-compatible.d.ts.map +0 -1
- package/dist/src/adapters/review-engine/openai-compatible.js.map +0 -1
- package/dist/src/adapters/review-engine/parse-output.d.ts.map +0 -1
- package/dist/src/adapters/review-engine/parse-output.js.map +0 -1
- package/dist/src/adapters/review-engine/prompt-builder.d.ts.map +0 -1
- package/dist/src/adapters/review-engine/prompt-builder.js.map +0 -1
- package/dist/src/adapters/review-engine/types.d.ts.map +0 -1
- package/dist/src/adapters/review-engine/types.js.map +0 -1
- package/dist/src/adapters/vcs-host/commit-status.d.ts.map +0 -1
- package/dist/src/adapters/vcs-host/commit-status.js.map +0 -1
- package/dist/src/adapters/vcs-host/github.d.ts.map +0 -1
- package/dist/src/adapters/vcs-host/github.js.map +0 -1
- package/dist/src/adapters/vcs-host/types.d.ts.map +0 -1
- package/dist/src/adapters/vcs-host/types.js.map +0 -1
- package/dist/src/cli/_pkg-root.d.ts.map +0 -1
- package/dist/src/cli/_pkg-root.js.map +0 -1
- package/dist/src/cli/autoregress-bridge.d.ts.map +0 -1
- package/dist/src/cli/autoregress-bridge.js.map +0 -1
- package/dist/src/cli/baseline.d.ts.map +0 -1
- package/dist/src/cli/baseline.js.map +0 -1
- package/dist/src/cli/ci.d.ts.map +0 -1
- package/dist/src/cli/ci.js.map +0 -1
- package/dist/src/cli/costs.d.ts.map +0 -1
- package/dist/src/cli/costs.js.map +0 -1
- package/dist/src/cli/council.d.ts.map +0 -1
- package/dist/src/cli/council.js.map +0 -1
- package/dist/src/cli/detector.d.ts.map +0 -1
- package/dist/src/cli/detector.js.map +0 -1
- package/dist/src/cli/explain.d.ts.map +0 -1
- package/dist/src/cli/explain.js.map +0 -1
- package/dist/src/cli/fix.d.ts.map +0 -1
- package/dist/src/cli/fix.js.map +0 -1
- package/dist/src/cli/hook.d.ts.map +0 -1
- package/dist/src/cli/hook.js.map +0 -1
- package/dist/src/cli/ignore-helper.d.ts.map +0 -1
- package/dist/src/cli/ignore-helper.js.map +0 -1
- package/dist/src/cli/index.d.ts.map +0 -1
- package/dist/src/cli/index.js.map +0 -1
- package/dist/src/cli/lsp.d.ts.map +0 -1
- package/dist/src/cli/lsp.js.map +0 -1
- package/dist/src/cli/mcp.d.ts.map +0 -1
- package/dist/src/cli/mcp.js.map +0 -1
- package/dist/src/cli/migrate-v4.d.ts.map +0 -1
- package/dist/src/cli/migrate-v4.js.map +0 -1
- package/dist/src/cli/pr-comment.d.ts.map +0 -1
- package/dist/src/cli/pr-comment.js.map +0 -1
- package/dist/src/cli/pr-desc.d.ts.map +0 -1
- package/dist/src/cli/pr-desc.js.map +0 -1
- package/dist/src/cli/pr-review-comments.d.ts.map +0 -1
- package/dist/src/cli/pr-review-comments.js.map +0 -1
- package/dist/src/cli/pr.d.ts.map +0 -1
- package/dist/src/cli/pr.js.map +0 -1
- package/dist/src/cli/preflight.d.ts.map +0 -1
- package/dist/src/cli/preflight.js.map +0 -1
- package/dist/src/cli/report.d.ts.map +0 -1
- package/dist/src/cli/report.js.map +0 -1
- package/dist/src/cli/run.d.ts.map +0 -1
- package/dist/src/cli/run.js.map +0 -1
- package/dist/src/cli/scan.d.ts.map +0 -1
- package/dist/src/cli/scan.js.map +0 -1
- package/dist/src/cli/setup.d.ts.map +0 -1
- package/dist/src/cli/setup.js.map +0 -1
- package/dist/src/cli/test-gen.d.ts.map +0 -1
- package/dist/src/cli/test-gen.js.map +0 -1
- package/dist/src/cli/triage.d.ts.map +0 -1
- package/dist/src/cli/triage.js.map +0 -1
- package/dist/src/cli/watch.d.ts.map +0 -1
- package/dist/src/cli/watch.js.map +0 -1
- package/dist/src/cli/worker.d.ts.map +0 -1
- package/dist/src/cli/worker.js.map +0 -1
- package/dist/src/core/cache/cached-engine.d.ts.map +0 -1
- package/dist/src/core/cache/cached-engine.js.map +0 -1
- package/dist/src/core/cache/review-cache.d.ts.map +0 -1
- package/dist/src/core/cache/review-cache.js.map +0 -1
- package/dist/src/core/chunking/index.d.ts.map +0 -1
- package/dist/src/core/chunking/index.js.map +0 -1
- package/dist/src/core/chunking/risk-ranker.d.ts.map +0 -1
- package/dist/src/core/chunking/risk-ranker.js.map +0 -1
- package/dist/src/core/config/loader.d.ts.map +0 -1
- package/dist/src/core/config/loader.js.map +0 -1
- package/dist/src/core/config/preset-resolver.d.ts.map +0 -1
- package/dist/src/core/config/preset-resolver.js.map +0 -1
- package/dist/src/core/config/schema.d.ts.map +0 -1
- package/dist/src/core/config/schema.js.map +0 -1
- package/dist/src/core/config/types.d.ts.map +0 -1
- package/dist/src/core/config/types.js.map +0 -1
- package/dist/src/core/council/config.d.ts.map +0 -1
- package/dist/src/core/council/config.js.map +0 -1
- package/dist/src/core/council/context.d.ts.map +0 -1
- package/dist/src/core/council/context.js.map +0 -1
- package/dist/src/core/council/runner.d.ts.map +0 -1
- package/dist/src/core/council/runner.js.map +0 -1
- package/dist/src/core/council/types.d.ts.map +0 -1
- package/dist/src/core/council/types.js.map +0 -1
- package/dist/src/core/detect/git-context.d.ts.map +0 -1
- package/dist/src/core/detect/git-context.js.map +0 -1
- package/dist/src/core/detect/llm-key.d.ts.map +0 -1
- package/dist/src/core/detect/llm-key.js.map +0 -1
- package/dist/src/core/detect/protected-paths.d.ts.map +0 -1
- package/dist/src/core/detect/protected-paths.js.map +0 -1
- package/dist/src/core/detect/provider-usage.d.ts.map +0 -1
- package/dist/src/core/detect/provider-usage.js.map +0 -1
- package/dist/src/core/detect/stack.d.ts.map +0 -1
- package/dist/src/core/detect/stack.js.map +0 -1
- package/dist/src/core/detect/workspaces.d.ts.map +0 -1
- package/dist/src/core/detect/workspaces.js.map +0 -1
- package/dist/src/core/errors.d.ts.map +0 -1
- package/dist/src/core/errors.js.map +0 -1
- package/dist/src/core/findings/dedup.d.ts.map +0 -1
- package/dist/src/core/findings/dedup.js.map +0 -1
- package/dist/src/core/findings/types.d.ts.map +0 -1
- package/dist/src/core/findings/types.js.map +0 -1
- package/dist/src/core/fix/generator.d.ts.map +0 -1
- package/dist/src/core/fix/generator.js.map +0 -1
- package/dist/src/core/git/diff-hunks.d.ts.map +0 -1
- package/dist/src/core/git/diff-hunks.js.map +0 -1
- package/dist/src/core/git/touched-files.d.ts.map +0 -1
- package/dist/src/core/git/touched-files.js.map +0 -1
- package/dist/src/core/ignore/index.d.ts.map +0 -1
- package/dist/src/core/ignore/index.js.map +0 -1
- package/dist/src/core/index.d.ts.map +0 -1
- package/dist/src/core/index.js.map +0 -1
- package/dist/src/core/logging/ndjson-writer.d.ts.map +0 -1
- package/dist/src/core/logging/ndjson-writer.js.map +0 -1
- package/dist/src/core/logging/redaction.d.ts.map +0 -1
- package/dist/src/core/logging/redaction.js.map +0 -1
- package/dist/src/core/mcp/concurrency.d.ts.map +0 -1
- package/dist/src/core/mcp/concurrency.js.map +0 -1
- package/dist/src/core/mcp/handlers/fix-finding.d.ts.map +0 -1
- package/dist/src/core/mcp/handlers/fix-finding.js.map +0 -1
- package/dist/src/core/mcp/handlers/get-capabilities.d.ts.map +0 -1
- package/dist/src/core/mcp/handlers/get-capabilities.js.map +0 -1
- package/dist/src/core/mcp/handlers/get-findings.d.ts.map +0 -1
- package/dist/src/core/mcp/handlers/get-findings.js.map +0 -1
- package/dist/src/core/mcp/handlers/review-diff.d.ts.map +0 -1
- package/dist/src/core/mcp/handlers/review-diff.js.map +0 -1
- package/dist/src/core/mcp/handlers/scan-files.d.ts.map +0 -1
- package/dist/src/core/mcp/handlers/scan-files.js.map +0 -1
- package/dist/src/core/mcp/handlers/validate-fix.d.ts.map +0 -1
- package/dist/src/core/mcp/handlers/validate-fix.js.map +0 -1
- package/dist/src/core/mcp/run-store.d.ts.map +0 -1
- package/dist/src/core/mcp/run-store.js.map +0 -1
- package/dist/src/core/mcp/workspace.d.ts.map +0 -1
- package/dist/src/core/mcp/workspace.js.map +0 -1
- package/dist/src/core/persist/baseline.d.ts.map +0 -1
- package/dist/src/core/persist/baseline.js.map +0 -1
- package/dist/src/core/persist/cost-log.d.ts.map +0 -1
- package/dist/src/core/persist/cost-log.js.map +0 -1
- package/dist/src/core/persist/findings-cache.d.ts.map +0 -1
- package/dist/src/core/persist/findings-cache.js.map +0 -1
- package/dist/src/core/persist/triage.d.ts.map +0 -1
- package/dist/src/core/persist/triage.js.map +0 -1
- package/dist/src/core/phases/static-rules.d.ts.map +0 -1
- package/dist/src/core/phases/static-rules.js.map +0 -1
- package/dist/src/core/phases/tests.d.ts.map +0 -1
- package/dist/src/core/phases/tests.js.map +0 -1
- package/dist/src/core/pipeline/review-phase.d.ts.map +0 -1
- package/dist/src/core/pipeline/review-phase.js.map +0 -1
- package/dist/src/core/pipeline/run.d.ts.map +0 -1
- package/dist/src/core/pipeline/run.js.map +0 -1
- package/dist/src/core/runtime/idempotency.d.ts.map +0 -1
- package/dist/src/core/runtime/idempotency.js.map +0 -1
- package/dist/src/core/runtime/lock.d.ts.map +0 -1
- package/dist/src/core/runtime/lock.js.map +0 -1
- package/dist/src/core/runtime/state.d.ts.map +0 -1
- package/dist/src/core/runtime/state.js.map +0 -1
- package/dist/src/core/schema-alignment/detector.d.ts.map +0 -1
- package/dist/src/core/schema-alignment/detector.js.map +0 -1
- package/dist/src/core/schema-alignment/extractor/index.d.ts.map +0 -1
- package/dist/src/core/schema-alignment/extractor/index.js.map +0 -1
- package/dist/src/core/schema-alignment/extractor/prisma.d.ts.map +0 -1
- package/dist/src/core/schema-alignment/extractor/prisma.js.map +0 -1
- package/dist/src/core/schema-alignment/extractor/sql.d.ts.map +0 -1
- package/dist/src/core/schema-alignment/extractor/sql.js.map +0 -1
- package/dist/src/core/schema-alignment/llm-check.d.ts.map +0 -1
- package/dist/src/core/schema-alignment/llm-check.js.map +0 -1
- package/dist/src/core/schema-alignment/scanner.d.ts.map +0 -1
- package/dist/src/core/schema-alignment/scanner.js.map +0 -1
- package/dist/src/core/schema-alignment/types.d.ts.map +0 -1
- package/dist/src/core/schema-alignment/types.js.map +0 -1
- package/dist/src/core/shell.d.ts.map +0 -1
- package/dist/src/core/shell.js.map +0 -1
- package/dist/src/core/static-rules/registry.d.ts.map +0 -1
- package/dist/src/core/static-rules/registry.js.map +0 -1
- package/dist/src/core/static-rules/rules/brand-tokens.d.ts.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.d.ts.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.d.ts.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.d.ts.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.d.ts.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.d.ts.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.d.ts.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.d.ts.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.d.ts.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.d.ts.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.d.ts.map +0 -1
- package/dist/src/core/static-rules/rules/sql-injection.js.map +0 -1
- package/dist/src/core/static-rules/rules/ssrf.d.ts.map +0 -1
- package/dist/src/core/static-rules/rules/ssrf.js.map +0 -1
- package/dist/src/core/static-rules/rules/todo-fixme.d.ts.map +0 -1
- package/dist/src/core/static-rules/rules/todo-fixme.js.map +0 -1
- package/dist/src/core/static-rules/tailwind-extractor.d.ts.map +0 -1
- package/dist/src/core/static-rules/tailwind-extractor.js.map +0 -1
- package/dist/src/core/test-gen/coverage-analyzer.d.ts.map +0 -1
- package/dist/src/core/test-gen/coverage-analyzer.js.map +0 -1
- package/dist/src/core/test-gen/framework-detector.d.ts.map +0 -1
- package/dist/src/core/test-gen/framework-detector.js.map +0 -1
- package/dist/src/core/test-gen/test-writer.d.ts.map +0 -1
- package/dist/src/core/test-gen/test-writer.js.map +0 -1
- package/dist/src/core/ui/design-context-loader.d.ts.map +0 -1
- package/dist/src/core/ui/design-context-loader.js.map +0 -1
- package/dist/src/core/worker/client.d.ts.map +0 -1
- package/dist/src/core/worker/client.js.map +0 -1
- package/dist/src/core/worker/lockfile.d.ts.map +0 -1
- package/dist/src/core/worker/lockfile.js.map +0 -1
- package/dist/src/core/worker/server.d.ts.map +0 -1
- package/dist/src/core/worker/server.js.map +0 -1
- package/dist/src/formatters/github-annotations.d.ts.map +0 -1
- package/dist/src/formatters/github-annotations.js.map +0 -1
- package/dist/src/formatters/index.d.ts.map +0 -1
- package/dist/src/formatters/index.js.map +0 -1
- package/dist/src/formatters/junit.d.ts.map +0 -1
- package/dist/src/formatters/junit.js.map +0 -1
- package/dist/src/formatters/sarif.d.ts.map +0 -1
- package/dist/src/formatters/sarif.js.map +0 -1
- package/dist/src/index.d.ts.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-bot-parser/types.ts +0 -9
- 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/_pkg-root.ts +0 -85
- 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/index.ts +0 -3
- package/src/formatters/junit.ts +0 -52
- package/src/formatters/sarif.ts +0 -103
- package/src/index.ts +0 -3
package/src/adapters/loader.ts
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import * as path from 'node:path';
|
|
2
|
-
import { GuardrailError } from '../core/errors.ts';
|
|
3
|
-
import { checkApiVersionCompatibility, type AdapterBase } from './base.ts';
|
|
4
|
-
import { resolveSiblingModule } from '../cli/_pkg-root.ts';
|
|
5
|
-
|
|
6
|
-
export type IntegrationPoint = 'review-engine' | 'vcs-host' | 'migration-runner' | 'review-bot-parser';
|
|
7
|
-
|
|
8
|
-
export interface LoadAdapterOptions {
|
|
9
|
-
point: IntegrationPoint;
|
|
10
|
-
ref: string;
|
|
11
|
-
options?: Record<string, unknown>;
|
|
12
|
-
/** Allow loading adapters from arbitrary local paths. Off by default for security. */
|
|
13
|
-
unsafeAllowLocalAdapters?: boolean;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const BUILTIN_PATHS: Record<IntegrationPoint, Record<string, string>> = {
|
|
17
|
-
'review-engine': {
|
|
18
|
-
codex: './review-engine/codex.ts',
|
|
19
|
-
claude: './review-engine/claude.ts',
|
|
20
|
-
gemini: './review-engine/gemini.ts',
|
|
21
|
-
'openai-compatible': './review-engine/openai-compatible.ts',
|
|
22
|
-
auto: './review-engine/auto.ts',
|
|
23
|
-
},
|
|
24
|
-
'vcs-host': { github: './vcs-host/github.ts' },
|
|
25
|
-
'migration-runner': { supabase: './migration-runner/supabase.ts' },
|
|
26
|
-
'review-bot-parser': { cursor: './review-bot-parser/cursor.ts' },
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const REQUIRED_BY_POINT: Record<IntegrationPoint, string[]> = {
|
|
30
|
-
'review-engine': ['review', 'estimateTokens'],
|
|
31
|
-
'vcs-host': ['getPrDiff', 'getPrMetadata', 'postComment', 'getReviewComments', 'replyToComment', 'createPr', 'push'],
|
|
32
|
-
'migration-runner': ['discover', 'dryRun', 'apply', 'ledger', 'alreadyApplied'],
|
|
33
|
-
'review-bot-parser': ['detect', 'fetchFindings', 'detectDismissal'],
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
function isPathRef(ref: string): boolean {
|
|
37
|
-
return ref.startsWith('./') || ref.startsWith('/') || ref.startsWith('../') || ref.endsWith('.ts') || ref.endsWith('.js');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export async function loadAdapter<T extends AdapterBase>(options: LoadAdapterOptions): Promise<T> {
|
|
41
|
-
const { point, ref } = options;
|
|
42
|
-
let modulePath: string;
|
|
43
|
-
|
|
44
|
-
if (isPathRef(ref)) {
|
|
45
|
-
if (!options.unsafeAllowLocalAdapters) {
|
|
46
|
-
throw new GuardrailError(
|
|
47
|
-
`Path-based adapter refs require unsafeAllowLocalAdapters:true — set this only for trusted local adapters`,
|
|
48
|
-
{ code: 'invalid_config', details: { point, ref } }
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
modulePath = path.resolve(ref);
|
|
52
|
-
} else {
|
|
53
|
-
const builtin = BUILTIN_PATHS[point]?.[ref];
|
|
54
|
-
if (!builtin) {
|
|
55
|
-
throw new GuardrailError(`Unknown built-in ${point} adapter: "${ref}"`, {
|
|
56
|
-
code: 'invalid_config',
|
|
57
|
-
details: { point, ref, available: Object.keys(BUILTIN_PATHS[point] ?? {}) },
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
modulePath = resolveSiblingModule(builtin, import.meta.url);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
let mod: { default?: T } | T;
|
|
64
|
-
try {
|
|
65
|
-
mod = (await import(modulePath)) as { default?: T } | T;
|
|
66
|
-
} catch (err) {
|
|
67
|
-
throw new GuardrailError(`Failed to import adapter from ${modulePath}`, {
|
|
68
|
-
code: 'invalid_config',
|
|
69
|
-
details: { point, ref, modulePath, cause: err instanceof Error ? err.message : String(err) },
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const adapter = ('default' in mod ? mod.default : mod) as T;
|
|
74
|
-
if (!adapter || typeof adapter !== 'object') {
|
|
75
|
-
throw new GuardrailError(`Adapter module did not export a valid adapter object`, {
|
|
76
|
-
code: 'invalid_config',
|
|
77
|
-
details: { point, ref, modulePath },
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
validateShape(adapter, point, modulePath);
|
|
82
|
-
|
|
83
|
-
if (!checkApiVersionCompatibility(adapter.apiVersion)) {
|
|
84
|
-
throw new GuardrailError(`Adapter apiVersion ${adapter.apiVersion} incompatible with core`, {
|
|
85
|
-
code: 'invalid_config',
|
|
86
|
-
details: { point, ref, adapterApiVersion: adapter.apiVersion },
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return adapter;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function validateShape(adapter: AdapterBase, point: IntegrationPoint, modulePath: string): void {
|
|
94
|
-
const missing: string[] = [];
|
|
95
|
-
const required = ['getCapabilities', ...REQUIRED_BY_POINT[point]];
|
|
96
|
-
for (const method of required) {
|
|
97
|
-
if (typeof (adapter as unknown as Record<string, unknown>)[method] !== 'function') missing.push(method);
|
|
98
|
-
}
|
|
99
|
-
if (typeof adapter.name !== 'string' || typeof adapter.apiVersion !== 'string') {
|
|
100
|
-
missing.push('name/apiVersion');
|
|
101
|
-
}
|
|
102
|
-
if (missing.length > 0) {
|
|
103
|
-
throw new GuardrailError(
|
|
104
|
-
`Adapter at ${modulePath} missing required methods: ${missing.join(', ')}`,
|
|
105
|
-
{ code: 'invalid_config', details: { point, modulePath, missing } }
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import * as fs from 'node:fs';
|
|
2
|
-
import * as path from 'node:path';
|
|
3
|
-
import { runSafe } from '../../core/shell.ts';
|
|
4
|
-
import type { Capabilities } from '../base.ts';
|
|
5
|
-
import type { MigrationRunner, Migration, MigrationEnv, DryRunResult, ApplyResult, LedgerEntry } from './types.ts';
|
|
6
|
-
|
|
7
|
-
export const supabaseAdapter: MigrationRunner = {
|
|
8
|
-
name: 'supabase',
|
|
9
|
-
apiVersion: '1.0.0',
|
|
10
|
-
|
|
11
|
-
getCapabilities(): Capabilities {
|
|
12
|
-
return { structuredOutput: false, streaming: false, maxContextTokens: 0, inlineComments: false };
|
|
13
|
-
},
|
|
14
|
-
|
|
15
|
-
discover(touchedFiles: string[]): Migration[] {
|
|
16
|
-
const sqlFiles = touchedFiles.filter(f => f.match(/data\/deltas\/[^/]+\.sql$/));
|
|
17
|
-
return sqlFiles.map(p => ({
|
|
18
|
-
name: path.basename(p, '.sql'),
|
|
19
|
-
path: p,
|
|
20
|
-
}));
|
|
21
|
-
},
|
|
22
|
-
|
|
23
|
-
async dryRun(migration: Migration): Promise<DryRunResult> {
|
|
24
|
-
try {
|
|
25
|
-
const content = migration.content ?? fs.readFileSync(migration.path, 'utf8');
|
|
26
|
-
if (!content.trim()) return { ok: false, errors: ['Migration file is empty'] };
|
|
27
|
-
return { ok: true };
|
|
28
|
-
} catch (err) {
|
|
29
|
-
return { ok: false, errors: [err instanceof Error ? err.message : String(err)] };
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
async apply(migration: Migration, env: MigrationEnv): Promise<ApplyResult> {
|
|
34
|
-
const start = Date.now();
|
|
35
|
-
const envFlag = env === 'prod' ? '--prod' : env === 'qa' ? '--qa' : '';
|
|
36
|
-
const args = ['tsx', 'scripts/supabase/migrate.ts', migration.path];
|
|
37
|
-
if (envFlag) args.push(envFlag);
|
|
38
|
-
const result = runSafe('npx', args);
|
|
39
|
-
if (result === null) {
|
|
40
|
-
return { ok: false, errors: [`Migration apply failed for ${migration.name} on ${env}`] };
|
|
41
|
-
}
|
|
42
|
-
return { ok: true, durationMs: Date.now() - start };
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
async ledger(_env: MigrationEnv): Promise<LedgerEntry[]> {
|
|
46
|
-
// alpha.1: full ledger query lands in alpha.2
|
|
47
|
-
return [];
|
|
48
|
-
},
|
|
49
|
-
|
|
50
|
-
async alreadyApplied(migration: Migration, _env: MigrationEnv): Promise<boolean> {
|
|
51
|
-
const result = runSafe('npx', ['tsx', 'scripts/supabase/migrate.ts', migration.path, '--inspect']);
|
|
52
|
-
return result !== null && result.includes('already applied');
|
|
53
|
-
},
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export default supabaseAdapter;
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { AdapterBase } from '../base.ts';
|
|
2
|
-
|
|
3
|
-
export type MigrationEnv = 'dev' | 'qa' | 'prod';
|
|
4
|
-
|
|
5
|
-
export interface Migration {
|
|
6
|
-
name: string;
|
|
7
|
-
path: string;
|
|
8
|
-
content?: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface DryRunResult {
|
|
12
|
-
ok: boolean;
|
|
13
|
-
errors?: string[];
|
|
14
|
-
warnings?: string[];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface ApplyResult {
|
|
18
|
-
ok: boolean;
|
|
19
|
-
appliedSha?: string;
|
|
20
|
-
durationMs?: number;
|
|
21
|
-
errors?: string[];
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface LedgerEntry {
|
|
25
|
-
name: string;
|
|
26
|
-
appliedAt: string;
|
|
27
|
-
sha?: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface MigrationRunner extends AdapterBase {
|
|
31
|
-
discover(touchedFiles: string[]): Migration[];
|
|
32
|
-
dryRun(migration: Migration): Promise<DryRunResult>;
|
|
33
|
-
apply(migration: Migration, env: MigrationEnv): Promise<ApplyResult>;
|
|
34
|
-
ledger(env: MigrationEnv): Promise<LedgerEntry[]>;
|
|
35
|
-
alreadyApplied(migration: Migration, env: MigrationEnv): Promise<boolean>;
|
|
36
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { makeDeclarativeParser } from './declarative-base.ts';
|
|
2
|
-
|
|
3
|
-
export const cursorAdapter = makeDeclarativeParser({
|
|
4
|
-
name: 'cursor',
|
|
5
|
-
author: 'cursor[bot]',
|
|
6
|
-
severityMap: {
|
|
7
|
-
critical: /\bhigh\b|\bcritical\b/i,
|
|
8
|
-
warning: /\bmedium\b|\bwarning\b/i,
|
|
9
|
-
},
|
|
10
|
-
dismissalKeywords: ['false positive', 'not an issue', 'intentional', 'wontfix'],
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
export default cursorAdapter;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import type { Finding } from '../../core/findings/types.ts';
|
|
2
|
-
import type { GenericComment, VcsHost } from '../vcs-host/types.ts';
|
|
3
|
-
import type { Capabilities } from '../base.ts';
|
|
4
|
-
import type { ReviewBotParser } from './types.ts';
|
|
5
|
-
|
|
6
|
-
export interface DeclarativeParserConfig {
|
|
7
|
-
name: string;
|
|
8
|
-
author: string | RegExp;
|
|
9
|
-
severityMap: { critical?: RegExp; warning?: RegExp; note?: RegExp };
|
|
10
|
-
dismissalKeywords: string[];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function makeDeclarativeParser(config: DeclarativeParserConfig): ReviewBotParser {
|
|
14
|
-
const authorTest = typeof config.author === 'string'
|
|
15
|
-
? (a: string) => a === config.author
|
|
16
|
-
: (a: string) => (config.author as RegExp).test(a);
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
name: config.name,
|
|
20
|
-
apiVersion: '1.0.0',
|
|
21
|
-
|
|
22
|
-
getCapabilities(): Capabilities {
|
|
23
|
-
return { structuredOutput: false, streaming: false, maxContextTokens: 0, inlineComments: true };
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
detect(comment: GenericComment): boolean {
|
|
27
|
-
return authorTest(comment.author);
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
async fetchFindings(vcs: VcsHost, pr: number | string): Promise<Finding[]> {
|
|
31
|
-
const comments = await vcs.getReviewComments(pr);
|
|
32
|
-
const botComments = comments.filter(c => authorTest(c.author));
|
|
33
|
-
return botComments.map((c, idx) => {
|
|
34
|
-
const body = c.body ?? '';
|
|
35
|
-
const severity = matchSeverity(body, config.severityMap);
|
|
36
|
-
return {
|
|
37
|
-
id: `${config.name}-${idx}-${c.id}`,
|
|
38
|
-
source: `review-bot:${config.name}` as const,
|
|
39
|
-
severity,
|
|
40
|
-
category: `${config.name}-finding`,
|
|
41
|
-
file: c.path ?? '<unspecified>',
|
|
42
|
-
line: c.line,
|
|
43
|
-
message: body.split('\n')[0]?.trim() ?? body,
|
|
44
|
-
protectedPath: false,
|
|
45
|
-
createdAt: new Date().toISOString(),
|
|
46
|
-
};
|
|
47
|
-
});
|
|
48
|
-
},
|
|
49
|
-
|
|
50
|
-
detectDismissal(reply: string): boolean {
|
|
51
|
-
const lower = reply.toLowerCase();
|
|
52
|
-
return config.dismissalKeywords.some(kw => lower.includes(kw));
|
|
53
|
-
},
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function matchSeverity(
|
|
58
|
-
body: string,
|
|
59
|
-
map: DeclarativeParserConfig['severityMap']
|
|
60
|
-
): Finding['severity'] {
|
|
61
|
-
if (map.critical && map.critical.test(body)) return 'critical';
|
|
62
|
-
if (map.warning && map.warning.test(body)) return 'warning';
|
|
63
|
-
return 'note';
|
|
64
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { AdapterBase } from '../base.ts';
|
|
2
|
-
import type { Finding } from '../../core/findings/types.ts';
|
|
3
|
-
import type { GenericComment, VcsHost } from '../vcs-host/types.ts';
|
|
4
|
-
|
|
5
|
-
export interface ReviewBotParser extends AdapterBase {
|
|
6
|
-
detect(comment: GenericComment): boolean;
|
|
7
|
-
fetchFindings(vcs: VcsHost, pr: number | string): Promise<Finding[]>;
|
|
8
|
-
detectDismissal(reply: string): boolean;
|
|
9
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import type { Capabilities } from '../base.ts';
|
|
2
|
-
import type { ReviewEngine, ReviewInput, ReviewOutput } from './types.ts';
|
|
3
|
-
import { GuardrailError } from '../../core/errors.ts';
|
|
4
|
-
import { detectProviderUsage, dominantProvider, type Provider } from '../../core/detect/provider-usage.ts';
|
|
5
|
-
|
|
6
|
-
interface AvailableProvider {
|
|
7
|
-
provider: Provider;
|
|
8
|
-
load: () => Promise<ReviewEngine>;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function buildGroqAdapter(base: ReviewEngine): ReviewEngine {
|
|
12
|
-
return {
|
|
13
|
-
...base,
|
|
14
|
-
name: 'auto',
|
|
15
|
-
review(input: ReviewInput) {
|
|
16
|
-
return base.review({
|
|
17
|
-
...input,
|
|
18
|
-
context: {
|
|
19
|
-
...input.context,
|
|
20
|
-
model: 'llama-3.3-70b-versatile',
|
|
21
|
-
baseUrl: 'https://api.groq.com/openai/v1',
|
|
22
|
-
apiKeyEnv: 'GROQ_API_KEY',
|
|
23
|
-
} as typeof input.context,
|
|
24
|
-
});
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function getAvailableProviders(): AvailableProvider[] {
|
|
30
|
-
const available: AvailableProvider[] = [];
|
|
31
|
-
if (process.env.ANTHROPIC_API_KEY) {
|
|
32
|
-
available.push({ provider: 'anthropic', load: async () => (await import('./claude.ts')).claudeAdapter });
|
|
33
|
-
}
|
|
34
|
-
if (process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY) {
|
|
35
|
-
available.push({ provider: 'gemini', load: async () => (await import('./gemini.ts')).geminiAdapter });
|
|
36
|
-
}
|
|
37
|
-
if (process.env.OPENAI_API_KEY) {
|
|
38
|
-
available.push({ provider: 'openai', load: async () => (await import('./codex.ts')).codexAdapter });
|
|
39
|
-
}
|
|
40
|
-
if (process.env.GROQ_API_KEY) {
|
|
41
|
-
available.push({
|
|
42
|
-
provider: 'groq',
|
|
43
|
-
load: async () => buildGroqAdapter((await import('./openai-compatible.ts')).openaiCompatibleAdapter),
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
return available;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async function resolveAdapter(cwd: string): Promise<ReviewEngine> {
|
|
50
|
-
const available = getAvailableProviders();
|
|
51
|
-
|
|
52
|
-
if (available.length === 0) {
|
|
53
|
-
throw new GuardrailError(
|
|
54
|
-
'No LLM API key found. Set one of: ANTHROPIC_API_KEY, GEMINI_API_KEY, OPENAI_API_KEY, GROQ_API_KEY',
|
|
55
|
-
{ code: 'auth', provider: 'auto' },
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Single provider — no need to scan
|
|
60
|
-
if (available.length === 1) return available[0]!.load();
|
|
61
|
-
|
|
62
|
-
// Multiple keys present — prefer the provider most referenced in source code
|
|
63
|
-
const counts = detectProviderUsage(cwd);
|
|
64
|
-
const dominant = dominantProvider(counts);
|
|
65
|
-
if (dominant) {
|
|
66
|
-
const match = available.find(p => p.provider === dominant);
|
|
67
|
-
if (match) return match.load();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Fallback to first available (env-key priority order)
|
|
71
|
-
return available[0]!.load();
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export const autoAdapter: ReviewEngine = {
|
|
75
|
-
name: 'auto',
|
|
76
|
-
apiVersion: '1.0.0',
|
|
77
|
-
|
|
78
|
-
getCapabilities(): Capabilities {
|
|
79
|
-
return { structuredOutput: false, streaming: false, maxContextTokens: 200000, inlineComments: false };
|
|
80
|
-
},
|
|
81
|
-
|
|
82
|
-
estimateTokens(content: string): number {
|
|
83
|
-
return Math.ceil(content.length / 3.5);
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
async review(input: ReviewInput): Promise<ReviewOutput> {
|
|
87
|
-
const cwd = (input.context as Record<string, unknown> | undefined)?.['cwd'] as string | undefined
|
|
88
|
-
?? process.cwd();
|
|
89
|
-
const adapter = await resolveAdapter(cwd);
|
|
90
|
-
return adapter.review(input);
|
|
91
|
-
},
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
export default autoAdapter;
|
|
@@ -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;
|