@delegance/claude-autopilot 5.0.1 → 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/src/cli/index.js +39 -1
- package/dist/src/cli/preflight.js +17 -4
- 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
|
@@ -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
|
-
}
|
package/src/cli/_pkg-root.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Resolves the canonical package root directory from the perspective of any
|
|
3
|
-
* source file in the package. Robust under both source (`src/cli/foo.ts` →
|
|
4
|
-
* `<root>`) and compiled (`dist/src/cli/foo.js` → `<root>`) layouts.
|
|
5
|
-
*
|
|
6
|
-
* Background: every site that hardcoded `path.resolve(dirname(fileURLToPath(...)), '..', '..')`
|
|
7
|
-
* worked when called from the source layout but resolved one level shallow under
|
|
8
|
-
* the compiled output (landing in `dist/` instead of the package root). The
|
|
9
|
-
* real-world soak against `npx @delegance/claude-autopilot@alpha init` surfaced
|
|
10
|
-
* this — `init` couldn't find `presets/<name>/guardrail.config.yaml` because it
|
|
11
|
-
* was looking at `dist/presets/...` (which doesn't exist; presets ship at the
|
|
12
|
-
* package root).
|
|
13
|
-
*
|
|
14
|
-
* This helper walks up from the caller's `import.meta.url` looking for the
|
|
15
|
-
* `@delegance/claude-autopilot` package.json. Both source and compiled callers
|
|
16
|
-
* land in the same place.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import * as fs from 'node:fs';
|
|
20
|
-
import * as path from 'node:path';
|
|
21
|
-
import { fileURLToPath } from 'node:url';
|
|
22
|
-
|
|
23
|
-
const PACKAGE_NAME = '@delegance/claude-autopilot';
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Walks up from the caller's location looking for the package.json that
|
|
27
|
-
* declares `name === '@delegance/claude-autopilot'`. Returns the directory
|
|
28
|
-
* containing that package.json, or null if not found within `maxDepth` levels.
|
|
29
|
-
*/
|
|
30
|
-
export function findPackageRoot(callerImportMetaUrl: string, maxDepth = 10): string | null {
|
|
31
|
-
let dir = path.dirname(fileURLToPath(callerImportMetaUrl));
|
|
32
|
-
for (let i = 0; i < maxDepth; i++) {
|
|
33
|
-
const candidate = path.join(dir, 'package.json');
|
|
34
|
-
if (fs.existsSync(candidate)) {
|
|
35
|
-
try {
|
|
36
|
-
const pkg = JSON.parse(fs.readFileSync(candidate, 'utf8')) as { name?: string };
|
|
37
|
-
if (pkg.name === PACKAGE_NAME) return dir;
|
|
38
|
-
} catch {
|
|
39
|
-
/* keep walking */
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
const parent = path.dirname(dir);
|
|
43
|
-
if (parent === dir) break;
|
|
44
|
-
dir = parent;
|
|
45
|
-
}
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Throws a clear error if the package root can't be located. Use at sites that
|
|
51
|
-
* absolutely require the root (e.g. preset config lookup).
|
|
52
|
-
*/
|
|
53
|
-
export function requirePackageRoot(callerImportMetaUrl: string): string {
|
|
54
|
-
const root = findPackageRoot(callerImportMetaUrl);
|
|
55
|
-
if (!root) {
|
|
56
|
-
throw new Error(
|
|
57
|
-
`[claude-autopilot] Could not locate package root from ${fileURLToPath(callerImportMetaUrl)}. ` +
|
|
58
|
-
`Reinstall: npm install -g @delegance/claude-autopilot@alpha`,
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
return root;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Resolve a sibling-module path for dynamic `import()` that works under both
|
|
66
|
-
* source (caller is `.ts`) and compiled (caller is `.js`) layouts.
|
|
67
|
-
*
|
|
68
|
-
* Background: `import('./rules/foo.ts')` and `import('./review-engine/auto.ts')`
|
|
69
|
-
* are dynamic-import string literals — TS's `rewriteRelativeImportExtensions`
|
|
70
|
-
* only rewrites STATIC imports, leaving these string refs as `.ts` post-compile.
|
|
71
|
-
* Under compiled output, the actual module is `.js`, so the import fails with
|
|
72
|
-
* `Failed to import adapter from .../auto.ts`.
|
|
73
|
-
*
|
|
74
|
-
* This helper detects whether the caller is itself compiled (`.js`/`.mjs`) and
|
|
75
|
-
* rewrites the ref's extension to match.
|
|
76
|
-
*
|
|
77
|
-
* @param ref Sibling-module ref ending in `.ts` (e.g. `./review-engine/auto.ts`).
|
|
78
|
-
* @param callerImportMetaUrl Caller's `import.meta.url`.
|
|
79
|
-
* @returns Absolute filesystem path suitable for `import()`.
|
|
80
|
-
*/
|
|
81
|
-
export function resolveSiblingModule(ref: string, callerImportMetaUrl: string): string {
|
|
82
|
-
const callerIsCompiled = callerImportMetaUrl.endsWith('.js') || callerImportMetaUrl.endsWith('.mjs');
|
|
83
|
-
const adjustedRef = callerIsCompiled ? ref.replace(/\.ts$/, '.js') : ref;
|
|
84
|
-
return fileURLToPath(new URL(adjustedRef, callerImportMetaUrl));
|
|
85
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// src/cli/autoregress-bridge.ts
|
|
2
|
-
import * as path from 'node:path';
|
|
3
|
-
import { spawnSync } from 'node:child_process';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
|
|
6
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const SCRIPT = path.resolve(__dirname, '../../scripts/autoregress.ts');
|
|
8
|
-
|
|
9
|
-
const VALID_MODES = ['run', 'update', 'generate', 'diff'];
|
|
10
|
-
|
|
11
|
-
export function buildAutoregressArgs(args: string[]): string[] {
|
|
12
|
-
const mode = args[0] && VALID_MODES.includes(args[0]) ? args[0] : 'run';
|
|
13
|
-
const rest = args[0] && VALID_MODES.includes(args[0]) ? args.slice(1) : args;
|
|
14
|
-
return [mode, ...rest];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function runAutoregress(args: string[]): number {
|
|
18
|
-
const resolvedArgs = buildAutoregressArgs(args);
|
|
19
|
-
const result = spawnSync(
|
|
20
|
-
process.execPath,
|
|
21
|
-
['--import', 'tsx', SCRIPT, ...resolvedArgs],
|
|
22
|
-
{ stdio: 'inherit', cwd: process.cwd() },
|
|
23
|
-
);
|
|
24
|
-
if (result.error) {
|
|
25
|
-
console.error(`[autoregress] failed to launch: ${result.error.message}`);
|
|
26
|
-
console.error(` script: ${SCRIPT}`);
|
|
27
|
-
return 1;
|
|
28
|
-
}
|
|
29
|
-
return result.status ?? 1;
|
|
30
|
-
}
|
package/src/cli/baseline.ts
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import * as path from 'node:path';
|
|
2
|
-
import * as fs from 'node:fs';
|
|
3
|
-
import {
|
|
4
|
-
loadBaseline, saveBaseline, clearBaseline, diffAgainstBaseline,
|
|
5
|
-
baselineFilePath,
|
|
6
|
-
} from '../core/persist/baseline.ts';
|
|
7
|
-
import { loadCachedFindings } from '../core/persist/findings-cache.ts';
|
|
8
|
-
|
|
9
|
-
const C = {
|
|
10
|
-
reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
|
|
11
|
-
green: '\x1b[32m', yellow: '\x1b[33m', red: '\x1b[31m', cyan: '\x1b[36m',
|
|
12
|
-
};
|
|
13
|
-
const fmt = (c: keyof typeof C, t: string) => `${C[c]}${t}${C.reset}`;
|
|
14
|
-
|
|
15
|
-
export interface BaselineCommandOptions {
|
|
16
|
-
cwd?: string;
|
|
17
|
-
note?: string;
|
|
18
|
-
baselinePath?: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export async function runBaseline(sub: string, options: BaselineCommandOptions = {}): Promise<number> {
|
|
22
|
-
const cwd = options.cwd ?? process.cwd();
|
|
23
|
-
const bPath = baselineFilePath(cwd, options.baselinePath);
|
|
24
|
-
const relPath = path.relative(cwd, bPath);
|
|
25
|
-
|
|
26
|
-
switch (sub) {
|
|
27
|
-
case 'create': {
|
|
28
|
-
if (fs.existsSync(bPath)) {
|
|
29
|
-
console.log(fmt('yellow', `[baseline] ${relPath} already exists — use \`guardrail baseline update\` to refresh, or \`guardrail baseline clear\` to reset`));
|
|
30
|
-
return 1;
|
|
31
|
-
}
|
|
32
|
-
return createOrUpdate(cwd, bPath, relPath, options.note, 'Created');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
case 'update': {
|
|
36
|
-
return createOrUpdate(cwd, bPath, relPath, options.note, 'Updated');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
case 'show': {
|
|
40
|
-
const baseline = loadBaseline(cwd, options.baselinePath);
|
|
41
|
-
if (!baseline) {
|
|
42
|
-
console.log(fmt('yellow', `[baseline] No baseline found at ${relPath}`));
|
|
43
|
-
console.log(fmt('dim', ' Run: guardrail baseline create'));
|
|
44
|
-
return 0;
|
|
45
|
-
}
|
|
46
|
-
console.log(`\n${fmt('bold', '[baseline]')} ${fmt('dim', relPath)}`);
|
|
47
|
-
console.log(fmt('dim', ` Created: ${baseline.createdAt} Updated: ${baseline.updatedAt}`));
|
|
48
|
-
if (baseline.note) console.log(fmt('dim', ` Note: ${baseline.note}`));
|
|
49
|
-
console.log(` ${baseline.entries.length} pinned finding${baseline.entries.length !== 1 ? 's' : ''}\n`);
|
|
50
|
-
for (const e of baseline.entries) {
|
|
51
|
-
const sev = e.severity === 'critical' ? fmt('red', 'CRIT') : e.severity === 'warning' ? fmt('yellow', 'WARN') : fmt('dim', 'NOTE');
|
|
52
|
-
console.log(` [${sev}] ${fmt('dim', `${e.file}${e.line ? `:${e.line}` : ''}`)} ${e.message.slice(0, 70)}`);
|
|
53
|
-
}
|
|
54
|
-
console.log('');
|
|
55
|
-
return 0;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
case 'diff': {
|
|
59
|
-
const baseline = loadBaseline(cwd, options.baselinePath);
|
|
60
|
-
if (!baseline) {
|
|
61
|
-
console.log(fmt('yellow', `[baseline] No baseline found — run: guardrail baseline create`));
|
|
62
|
-
return 1;
|
|
63
|
-
}
|
|
64
|
-
const current = loadCachedFindings(cwd);
|
|
65
|
-
if (current.length === 0) {
|
|
66
|
-
console.log(fmt('yellow', '[baseline] No cached findings — run `guardrail run` or `guardrail scan` first'));
|
|
67
|
-
return 1;
|
|
68
|
-
}
|
|
69
|
-
const diff = diffAgainstBaseline(current, baseline);
|
|
70
|
-
console.log(`\n${fmt('bold', '[guardrail baseline diff]')} vs ${fmt('dim', relPath)}\n`);
|
|
71
|
-
|
|
72
|
-
if (diff.added.length > 0) {
|
|
73
|
-
console.log(fmt('red', ` ${diff.added.length} new finding${diff.added.length !== 1 ? 's' : ''} (not in baseline):`));
|
|
74
|
-
for (const f of diff.added) {
|
|
75
|
-
const sev = f.severity === 'critical' ? fmt('red', 'CRIT') : f.severity === 'warning' ? fmt('yellow', 'WARN') : fmt('dim', 'NOTE');
|
|
76
|
-
console.log(` [${sev}] ${fmt('dim', `${f.file}${f.line ? `:${f.line}` : ''}`)} ${f.message.slice(0, 70)}`);
|
|
77
|
-
}
|
|
78
|
-
console.log('');
|
|
79
|
-
}
|
|
80
|
-
if (diff.resolved.length > 0) {
|
|
81
|
-
console.log(fmt('green', ` ${diff.resolved.length} resolved (in baseline but not in current):`));
|
|
82
|
-
for (const e of diff.resolved) {
|
|
83
|
-
console.log(` ${fmt('dim', `${e.file}${e.line ? `:${e.line}` : ''}`)} ${e.message.slice(0, 70)}`);
|
|
84
|
-
}
|
|
85
|
-
console.log('');
|
|
86
|
-
}
|
|
87
|
-
if (diff.added.length === 0 && diff.resolved.length === 0) {
|
|
88
|
-
console.log(fmt('green', ` ✓ No changes vs baseline (${diff.unchanged.length} pinned findings unchanged)\n`));
|
|
89
|
-
} else {
|
|
90
|
-
console.log(fmt('dim', ` ${diff.unchanged.length} unchanged · run \`guardrail baseline update\` to pin new state\n`));
|
|
91
|
-
}
|
|
92
|
-
return diff.added.some(f => f.severity === 'critical') ? 1 : 0;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
case 'clear': {
|
|
96
|
-
if (!fs.existsSync(bPath)) {
|
|
97
|
-
console.log(fmt('dim', `[baseline] No baseline at ${relPath} — nothing to clear`));
|
|
98
|
-
return 0;
|
|
99
|
-
}
|
|
100
|
-
clearBaseline(cwd, options.baselinePath);
|
|
101
|
-
console.log(fmt('green', `[baseline] Cleared ${relPath}`));
|
|
102
|
-
return 0;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
default:
|
|
106
|
-
console.error(fmt('red', `[baseline] Unknown subcommand: "${sub}"`));
|
|
107
|
-
console.error(fmt('dim', ' Usage: guardrail baseline <create|update|show|diff|clear> [--note "..."]'));
|
|
108
|
-
return 1;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function createOrUpdate(cwd: string, bPath: string, relPath: string, note: string | undefined, verb: string): number {
|
|
113
|
-
const findings = loadCachedFindings(cwd);
|
|
114
|
-
if (findings.length === 0) {
|
|
115
|
-
console.log(fmt('yellow', '[baseline] No cached findings to snapshot — run `guardrail run` or `guardrail scan` first'));
|
|
116
|
-
return 1;
|
|
117
|
-
}
|
|
118
|
-
const baseline = saveBaseline(cwd, findings, { note, overridePath: bPath === path.join(cwd, '.guardrail-baseline.json') ? undefined : bPath });
|
|
119
|
-
console.log(`\n${fmt('green', `[baseline] ${verb}`)} ${fmt('dim', relPath)}`);
|
|
120
|
-
console.log(` ${baseline.entries.length} finding${baseline.entries.length !== 1 ? 's' : ''} pinned as accepted baseline`);
|
|
121
|
-
if (note) console.log(` Note: ${note}`);
|
|
122
|
-
console.log(fmt('dim', `\n Commit this file to share the baseline with your team:`));
|
|
123
|
-
console.log(fmt('cyan', ` git add ${relPath} && git commit -m "chore: update guardrail baseline"\n`));
|
|
124
|
-
return 0;
|
|
125
|
-
}
|
package/src/cli/ci.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { runCommand } from './run.ts';
|
|
2
|
-
|
|
3
|
-
export interface CiCommandOptions {
|
|
4
|
-
cwd?: string;
|
|
5
|
-
configPath?: string;
|
|
6
|
-
base?: string;
|
|
7
|
-
postComments?: boolean;
|
|
8
|
-
sarifOutput?: string;
|
|
9
|
-
diff?: boolean;
|
|
10
|
-
inlineComments?: boolean;
|
|
11
|
-
newOnly?: boolean;
|
|
12
|
-
failOn?: 'critical' | 'warning' | 'note' | 'none';
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* `guardrail ci` — opinionated single-command CI entrypoint.
|
|
17
|
-
*
|
|
18
|
-
* Defaults:
|
|
19
|
-
* base GITHUB_BASE_REF → HEAD~1
|
|
20
|
-
* output guardrail.sarif
|
|
21
|
-
* post-comments true
|
|
22
|
-
* fail-on critical (or policy.failOn from config)
|
|
23
|
-
* new-only false (or policy.newOnly from config)
|
|
24
|
-
*/
|
|
25
|
-
export async function runCi(options: CiCommandOptions = {}): Promise<number> {
|
|
26
|
-
const base = options.base
|
|
27
|
-
?? process.env.GITHUB_BASE_REF
|
|
28
|
-
?? process.env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME // GitLab
|
|
29
|
-
?? 'HEAD~1';
|
|
30
|
-
|
|
31
|
-
const sarifOutput = options.sarifOutput ?? 'guardrail.sarif';
|
|
32
|
-
|
|
33
|
-
return runCommand({
|
|
34
|
-
cwd: options.cwd,
|
|
35
|
-
configPath: options.configPath,
|
|
36
|
-
base,
|
|
37
|
-
postComments: options.postComments ?? true,
|
|
38
|
-
format: 'sarif',
|
|
39
|
-
outputPath: sarifOutput,
|
|
40
|
-
diff: options.diff,
|
|
41
|
-
inlineComments: options.inlineComments ?? true,
|
|
42
|
-
newOnly: options.newOnly,
|
|
43
|
-
failOn: options.failOn,
|
|
44
|
-
});
|
|
45
|
-
}
|