@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
package/src/cli/fix.ts
DELETED
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import * as fs from 'node:fs';
|
|
2
|
-
import * as path from 'node:path';
|
|
3
|
-
import * as readline from 'node:readline';
|
|
4
|
-
import { execSync } from 'node:child_process';
|
|
5
|
-
import { loadCachedFindings } from '../core/persist/findings-cache.ts';
|
|
6
|
-
import { loadConfig } from '../core/config/loader.ts';
|
|
7
|
-
import { loadAdapter } from '../adapters/loader.ts';
|
|
8
|
-
import type { ReviewEngine } from '../adapters/review-engine/types.ts';
|
|
9
|
-
import type { Finding } from '../core/findings/types.ts';
|
|
10
|
-
import type { GuardrailConfig } from '../core/config/types.ts';
|
|
11
|
-
import { generateFix, buildUnifiedDiff, type GenerateResult } from '../core/fix/generator.ts';
|
|
12
|
-
|
|
13
|
-
const C = {
|
|
14
|
-
reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
|
|
15
|
-
green: '\x1b[32m', yellow: '\x1b[33m', red: '\x1b[31m', cyan: '\x1b[36m',
|
|
16
|
-
};
|
|
17
|
-
const fmt = (c: keyof typeof C, t: string) => `${C[c]}${t}${C.reset}`;
|
|
18
|
-
|
|
19
|
-
export interface FixCommandOptions {
|
|
20
|
-
cwd?: string;
|
|
21
|
-
configPath?: string;
|
|
22
|
-
severity?: 'critical' | 'warning' | 'all';
|
|
23
|
-
dryRun?: boolean;
|
|
24
|
-
yes?: boolean; // skip per-fix confirmation prompts
|
|
25
|
-
noVerify?: boolean; // skip test verification after applying fix
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
interface FixResult {
|
|
29
|
-
file: string;
|
|
30
|
-
line: number;
|
|
31
|
-
findingMessage: string;
|
|
32
|
-
status: 'fixed' | 'skipped' | 'rejected' | 'failed';
|
|
33
|
-
reason?: string;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async function confirmFix(diff: string, finding: Finding): Promise<'yes' | 'no' | 'quit'> {
|
|
37
|
-
console.log('');
|
|
38
|
-
console.log(diff);
|
|
39
|
-
console.log('');
|
|
40
|
-
|
|
41
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
42
|
-
return new Promise(resolve => {
|
|
43
|
-
rl.question(fmt('bold', ' Apply this fix? [y]es / [n]o / [q]uit '), answer => {
|
|
44
|
-
rl.close();
|
|
45
|
-
const a = answer.trim().toLowerCase();
|
|
46
|
-
if (a === 'q') resolve('quit');
|
|
47
|
-
else if (a === 'y' || a === '') resolve('yes');
|
|
48
|
-
else resolve('no');
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export async function runFix(options: FixCommandOptions = {}): Promise<number> {
|
|
54
|
-
const cwd = options.cwd ?? process.cwd();
|
|
55
|
-
const configPath = options.configPath ?? path.join(cwd, 'guardrail.config.yaml');
|
|
56
|
-
const severityFilter = options.severity ?? 'critical';
|
|
57
|
-
|
|
58
|
-
const findings = loadCachedFindings(cwd);
|
|
59
|
-
if (findings.length === 0) {
|
|
60
|
-
console.log(fmt('yellow', '[fix] No cached findings — run `guardrail scan <path>` or `guardrail run` first.'));
|
|
61
|
-
return 0;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const fixable = findings.filter(f => {
|
|
65
|
-
if (!f.line || !f.file || f.file === '<unspecified>' || f.file === '<pipeline>') return false;
|
|
66
|
-
if (severityFilter === 'all') return true;
|
|
67
|
-
if (severityFilter === 'critical') return f.severity === 'critical';
|
|
68
|
-
return f.severity === 'critical' || f.severity === 'warning';
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
if (fixable.length === 0) {
|
|
72
|
-
console.log(fmt('yellow', `[fix] No fixable findings (severity=${severityFilter}, need file+line).`));
|
|
73
|
-
return 0;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const modeNote = options.dryRun ? ' (dry run)' : options.yes ? '' : ' (interactive — use --yes to skip prompts)';
|
|
77
|
-
console.log(`\n${fmt('bold', '[fix]')} ${fixable.length} finding${fixable.length !== 1 ? 's' : ''} to attempt${modeNote}\n`);
|
|
78
|
-
|
|
79
|
-
// Print upfront summary of all fixable findings before prompting
|
|
80
|
-
for (const f of fixable) {
|
|
81
|
-
const sev = f.severity === 'critical' ? fmt('red', 'CRITICAL') : fmt('yellow', 'WARNING ');
|
|
82
|
-
const loc = fmt('dim', `${f.file}:${f.line}`);
|
|
83
|
-
console.log(` [${sev}] ${loc} ${f.message}`);
|
|
84
|
-
if (f.suggestion) console.log(fmt('dim', ` → ${f.suggestion}`));
|
|
85
|
-
}
|
|
86
|
-
console.log('');
|
|
87
|
-
|
|
88
|
-
// Dry-run: listing the findings is sufficient — no LLM needed
|
|
89
|
-
if (options.dryRun) {
|
|
90
|
-
console.log(fmt('yellow', `[fix] Dry run — ${fixable.length} finding${fixable.length !== 1 ? 's' : ''} listed above, no files modified.\n`));
|
|
91
|
-
return 0;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Load config + review engine (config optional — defaults to auto adapter)
|
|
95
|
-
let engine: ReviewEngine;
|
|
96
|
-
let loadedConfig: GuardrailConfig | null = null;
|
|
97
|
-
try {
|
|
98
|
-
loadedConfig = fs.existsSync(configPath) ? await loadConfig(configPath) : null;
|
|
99
|
-
const ref = loadedConfig
|
|
100
|
-
? (typeof loadedConfig.reviewEngine === 'string' ? loadedConfig.reviewEngine : (loadedConfig.reviewEngine?.adapter ?? 'auto'))
|
|
101
|
-
: 'auto';
|
|
102
|
-
engine = await loadAdapter<ReviewEngine>({
|
|
103
|
-
point: 'review-engine',
|
|
104
|
-
ref,
|
|
105
|
-
options: loadedConfig && typeof loadedConfig.reviewEngine === 'object' ? loadedConfig.reviewEngine.options : undefined,
|
|
106
|
-
});
|
|
107
|
-
} catch (err) {
|
|
108
|
-
console.error(fmt('red', `[fix] Could not load review engine: ${err instanceof Error ? err.message : String(err)}`));
|
|
109
|
-
return 1;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const testCommand = loadedConfig?.testCommand ?? null;
|
|
113
|
-
const shouldVerify = !options.noVerify && !!testCommand;
|
|
114
|
-
if (shouldVerify) {
|
|
115
|
-
console.log(fmt('dim', `[fix] Verified mode — running "${testCommand}" after each fix\n`));
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const results: FixResult[] = [];
|
|
119
|
-
let quit = false;
|
|
120
|
-
|
|
121
|
-
for (const finding of fixable) {
|
|
122
|
-
if (quit) {
|
|
123
|
-
results.push({ file: finding.file, line: finding.line!, findingMessage: finding.message, status: 'skipped', reason: 'user quit' });
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const sev = finding.severity === 'critical' ? fmt('red', 'CRITICAL') : fmt('yellow', 'WARNING');
|
|
128
|
-
console.log(`\n [${sev}] ${fmt('dim', `${finding.file}:${finding.line}`)} ${finding.message}`);
|
|
129
|
-
|
|
130
|
-
const result = await generateFix(finding, engine, cwd);
|
|
131
|
-
|
|
132
|
-
if (result.status === 'cannot_fix') {
|
|
133
|
-
console.log(fmt('dim', ` → skipped: ${result.reason}`));
|
|
134
|
-
results.push({ file: finding.file, line: finding.line!, findingMessage: finding.message, status: 'skipped', reason: result.reason });
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (result.status === 'rejected') {
|
|
139
|
-
console.log(fmt('yellow', ` → rejected: ${result.reason}`));
|
|
140
|
-
results.push({ file: finding.file, line: finding.line!, findingMessage: finding.message, status: 'rejected', reason: result.reason });
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (result.status === 'error') {
|
|
145
|
-
console.log(fmt('red', ` → error: ${result.reason}`));
|
|
146
|
-
results.push({ file: finding.file, line: finding.line!, findingMessage: finding.message, status: 'failed', reason: result.reason });
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Show diff
|
|
151
|
-
const diff = buildUnifiedDiff(result.originalLines!, result.replacementLines!, finding.file, result.startLine!);
|
|
152
|
-
|
|
153
|
-
if (options.dryRun) {
|
|
154
|
-
console.log('');
|
|
155
|
-
console.log(diff);
|
|
156
|
-
console.log(fmt('dim', ' (dry run — not applied)'));
|
|
157
|
-
results.push({ file: finding.file, line: finding.line!, findingMessage: finding.message, status: 'skipped', reason: 'dry run' });
|
|
158
|
-
continue;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Interactive confirmation (unless --yes)
|
|
162
|
-
if (!options.yes) {
|
|
163
|
-
const answer = await confirmFix(diff, finding);
|
|
164
|
-
if (answer === 'quit') {
|
|
165
|
-
quit = true;
|
|
166
|
-
results.push({ file: finding.file, line: finding.line!, findingMessage: finding.message, status: 'skipped', reason: 'user quit' });
|
|
167
|
-
continue;
|
|
168
|
-
}
|
|
169
|
-
if (answer === 'no') {
|
|
170
|
-
results.push({ file: finding.file, line: finding.line!, findingMessage: finding.message, status: 'skipped', reason: 'user declined' });
|
|
171
|
-
continue;
|
|
172
|
-
}
|
|
173
|
-
} else {
|
|
174
|
-
// --yes mode: still print the diff so there's a record
|
|
175
|
-
console.log('');
|
|
176
|
-
console.log(diff);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Apply fix atomically
|
|
180
|
-
try {
|
|
181
|
-
const absPath = path.resolve(cwd, finding.file);
|
|
182
|
-
const originalContent = fs.readFileSync(absPath, 'utf8');
|
|
183
|
-
const allLines = originalContent.split('\n');
|
|
184
|
-
const newLines = [
|
|
185
|
-
...allLines.slice(0, result.startLine! - 1),
|
|
186
|
-
...result.replacementLines!,
|
|
187
|
-
...allLines.slice(result.endLine!),
|
|
188
|
-
];
|
|
189
|
-
const tmp = absPath + '.guardrail.tmp';
|
|
190
|
-
fs.writeFileSync(tmp, newLines.join('\n'), 'utf8');
|
|
191
|
-
fs.renameSync(tmp, absPath);
|
|
192
|
-
|
|
193
|
-
if (shouldVerify) {
|
|
194
|
-
// Verified mode — same shell invocation pattern as phases/tests.ts
|
|
195
|
-
console.log(fmt('dim', ` ↻ verifying…`));
|
|
196
|
-
const passed = runTestCommand(testCommand!, cwd);
|
|
197
|
-
if (passed) {
|
|
198
|
-
console.log(fmt('green', ` ✓ applied + tests pass`));
|
|
199
|
-
results.push({ file: finding.file, line: finding.line!, findingMessage: finding.message, status: 'fixed' });
|
|
200
|
-
} else {
|
|
201
|
-
fs.writeFileSync(absPath, originalContent, 'utf8');
|
|
202
|
-
console.log(fmt('yellow', ` ⚠ reverted — tests failed after fix`));
|
|
203
|
-
results.push({ file: finding.file, line: finding.line!, findingMessage: finding.message, status: 'rejected', reason: 'tests failed after fix — reverted' });
|
|
204
|
-
}
|
|
205
|
-
} else {
|
|
206
|
-
console.log(fmt('green', ` ✓ applied`));
|
|
207
|
-
results.push({ file: finding.file, line: finding.line!, findingMessage: finding.message, status: 'fixed' });
|
|
208
|
-
}
|
|
209
|
-
} catch (err) {
|
|
210
|
-
console.log(fmt('red', ` ✗ write failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
211
|
-
results.push({ file: finding.file, line: finding.line!, findingMessage: finding.message, status: 'failed', reason: String(err) });
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const fixed = results.filter(r => r.status === 'fixed').length;
|
|
216
|
-
const rejected = results.filter(r => r.status === 'rejected').length;
|
|
217
|
-
const failed = results.filter(r => r.status === 'failed').length;
|
|
218
|
-
const skipped = results.filter(r => r.status === 'skipped').length;
|
|
219
|
-
|
|
220
|
-
console.log('');
|
|
221
|
-
if (options.dryRun) {
|
|
222
|
-
console.log(fmt('yellow', `[fix] Dry run complete — ${fixable.length} finding${fixable.length !== 1 ? 's' : ''} previewed, no files modified.\n`));
|
|
223
|
-
} else {
|
|
224
|
-
const parts = [
|
|
225
|
-
fixed > 0 ? fmt('green', `${fixed} fixed`) : null,
|
|
226
|
-
rejected > 0 ? fmt('yellow', `${rejected} rejected`) : null,
|
|
227
|
-
failed > 0 ? fmt('red', `${failed} failed`) : null,
|
|
228
|
-
skipped > 0 ? fmt('dim', `${skipped} skipped`) : null,
|
|
229
|
-
].filter(Boolean).join(fmt('dim', ' · '));
|
|
230
|
-
console.log(`[fix] ${parts}\n`);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return failed > 0 ? 1 : 0;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
function runTestCommand(cmd: string, cwd: string): boolean {
|
|
237
|
-
try {
|
|
238
|
-
execSync(cmd, {
|
|
239
|
-
cwd,
|
|
240
|
-
stdio: 'ignore',
|
|
241
|
-
timeout: 120000,
|
|
242
|
-
shell: process.env.SHELL ?? '/bin/sh',
|
|
243
|
-
});
|
|
244
|
-
return true;
|
|
245
|
-
} catch {
|
|
246
|
-
return false;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
package/src/cli/hook.ts
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import * as fs from 'node:fs';
|
|
2
|
-
import * as path from 'node:path';
|
|
3
|
-
|
|
4
|
-
export const GUARDRAIL_MARKER = '# guardrail-managed';
|
|
5
|
-
|
|
6
|
-
const PRE_COMMIT_TEMPLATE = `#!/bin/sh
|
|
7
|
-
${GUARDRAIL_MARKER}
|
|
8
|
-
# guardrail pre-commit hook — runs static rules only (<1s, no LLM)
|
|
9
|
-
# --files accepts comma-separated paths; quoting prevents shell word-splitting
|
|
10
|
-
STAGED=$(git diff --cached --name-only --diff-filter=ACM | tr '\\n' ',')
|
|
11
|
-
STAGED=\${STAGED%,}
|
|
12
|
-
if [ -z "$STAGED" ]; then exit 0; fi
|
|
13
|
-
npx guardrail run --static-only --files "$STAGED"
|
|
14
|
-
`;
|
|
15
|
-
|
|
16
|
-
const PRE_PUSH_TEMPLATE = `#!/bin/sh
|
|
17
|
-
${GUARDRAIL_MARKER}
|
|
18
|
-
# guardrail pre-push hook — full LLM review against upstream
|
|
19
|
-
BASE=$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null || echo "HEAD~1")
|
|
20
|
-
npx guardrail run --base "$BASE"
|
|
21
|
-
`;
|
|
22
|
-
|
|
23
|
-
function findGitDir(cwd: string): string | null {
|
|
24
|
-
let dir = path.resolve(cwd);
|
|
25
|
-
for (let i = 0; i < 10; i++) {
|
|
26
|
-
const candidate = path.join(dir, '.git');
|
|
27
|
-
if (fs.existsSync(candidate)) {
|
|
28
|
-
const stat = fs.statSync(candidate);
|
|
29
|
-
if (stat.isDirectory()) return candidate;
|
|
30
|
-
if (stat.isFile()) {
|
|
31
|
-
const content = fs.readFileSync(candidate, 'utf8');
|
|
32
|
-
const match = content.match(/^gitdir:\s*(.+)/m);
|
|
33
|
-
if (match) return path.resolve(dir, match[1]!.trim());
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
const parent = path.dirname(dir);
|
|
37
|
-
if (parent === dir) return null;
|
|
38
|
-
dir = parent;
|
|
39
|
-
}
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function isGuardrailHook(hookPath: string): boolean {
|
|
44
|
-
try {
|
|
45
|
-
return fs.readFileSync(hookPath, 'utf8').includes(GUARDRAIL_MARKER);
|
|
46
|
-
} catch {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function writeHook(hookPath: string, content: string, force: boolean): boolean {
|
|
52
|
-
if (fs.existsSync(hookPath) && !force && !isGuardrailHook(hookPath)) {
|
|
53
|
-
console.error(`[hook] hook already exists at ${hookPath} (not guardrail-managed)`);
|
|
54
|
-
console.error(' Use --force to overwrite.');
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
fs.mkdirSync(path.dirname(hookPath), { recursive: true });
|
|
58
|
-
fs.writeFileSync(hookPath, content, 'utf8');
|
|
59
|
-
fs.chmodSync(hookPath, 0o755);
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function removeHook(hookPath: string): void {
|
|
64
|
-
if (!fs.existsSync(hookPath)) return;
|
|
65
|
-
if (isGuardrailHook(hookPath)) {
|
|
66
|
-
fs.rmSync(hookPath);
|
|
67
|
-
console.log(`[hook] removed ${hookPath}`);
|
|
68
|
-
} else {
|
|
69
|
-
console.log(`[hook] skipping ${hookPath} — not guardrail-managed`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export async function runHook(
|
|
74
|
-
sub: string,
|
|
75
|
-
options: { cwd?: string; force?: boolean; silent?: boolean; preCommitOnly?: boolean; prePushOnly?: boolean } = {},
|
|
76
|
-
): Promise<number> {
|
|
77
|
-
const cwd = options.cwd ?? process.cwd();
|
|
78
|
-
const gitDir = findGitDir(cwd);
|
|
79
|
-
|
|
80
|
-
if (!gitDir) {
|
|
81
|
-
if (!options.silent) console.error('[hook] not inside a git repository');
|
|
82
|
-
return 1;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const hooksDir = path.join(gitDir, 'hooks');
|
|
86
|
-
const preCommitPath = path.join(hooksDir, 'pre-commit');
|
|
87
|
-
const prePushPath = path.join(hooksDir, 'pre-push');
|
|
88
|
-
const force = options.force ?? false;
|
|
89
|
-
|
|
90
|
-
switch (sub) {
|
|
91
|
-
case 'install': {
|
|
92
|
-
const installPreCommit = !options.prePushOnly;
|
|
93
|
-
const installPrePush = !options.preCommitOnly;
|
|
94
|
-
let ok = true;
|
|
95
|
-
if (installPreCommit) {
|
|
96
|
-
const written = writeHook(preCommitPath, PRE_COMMIT_TEMPLATE, force);
|
|
97
|
-
if (written) console.log(`[hook] installed pre-commit hook at ${preCommitPath}`);
|
|
98
|
-
else ok = false;
|
|
99
|
-
}
|
|
100
|
-
if (installPrePush) {
|
|
101
|
-
const written = writeHook(prePushPath, PRE_PUSH_TEMPLATE, force);
|
|
102
|
-
if (written) console.log(`[hook] installed pre-push hook at ${prePushPath}`);
|
|
103
|
-
else ok = false;
|
|
104
|
-
}
|
|
105
|
-
return ok ? 0 : 1;
|
|
106
|
-
}
|
|
107
|
-
case 'uninstall': {
|
|
108
|
-
removeHook(preCommitPath);
|
|
109
|
-
removeHook(prePushPath);
|
|
110
|
-
return 0;
|
|
111
|
-
}
|
|
112
|
-
case 'status': {
|
|
113
|
-
const pcInstalled = fs.existsSync(preCommitPath) && isGuardrailHook(preCommitPath);
|
|
114
|
-
const ppInstalled = fs.existsSync(prePushPath) && isGuardrailHook(prePushPath);
|
|
115
|
-
console.log(`[hook] pre-commit: ${pcInstalled ? 'installed (guardrail-managed)' : 'not installed'}`);
|
|
116
|
-
console.log(`[hook] pre-push: ${ppInstalled ? 'installed (guardrail-managed)' : 'not installed'}`);
|
|
117
|
-
return 0;
|
|
118
|
-
}
|
|
119
|
-
default:
|
|
120
|
-
console.error(`[hook] unknown subcommand: ${sub}`);
|
|
121
|
-
console.error('Usage: guardrail hook <install|uninstall|status> [--force] [--pre-commit-only] [--pre-push-only]');
|
|
122
|
-
return 1;
|
|
123
|
-
}
|
|
124
|
-
}
|
package/src/cli/ignore-helper.ts
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import * as fs from 'node:fs';
|
|
2
|
-
import * as path from 'node:path';
|
|
3
|
-
import * as readline from 'node:readline';
|
|
4
|
-
import { loadCachedFindings } from '../core/persist/findings-cache.ts';
|
|
5
|
-
import type { Finding } from '../core/findings/types.ts';
|
|
6
|
-
|
|
7
|
-
const C = {
|
|
8
|
-
reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
|
|
9
|
-
green: '\x1b[32m', yellow: '\x1b[33m', red: '\x1b[31m',
|
|
10
|
-
};
|
|
11
|
-
const fmt = (c: keyof typeof C, t: string) => `${C[c]}${t}${C.reset}`;
|
|
12
|
-
|
|
13
|
-
const IGNORE_FILE = '.guardrail-ignore';
|
|
14
|
-
|
|
15
|
-
function readIgnoreFile(cwd: string): string {
|
|
16
|
-
const p = path.join(cwd, IGNORE_FILE);
|
|
17
|
-
return fs.existsSync(p) ? fs.readFileSync(p, 'utf8') : '';
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function appendIgnoreRule(cwd: string, rule: string): void {
|
|
21
|
-
const p = path.join(cwd, IGNORE_FILE);
|
|
22
|
-
const existing = readIgnoreFile(cwd);
|
|
23
|
-
const separator = existing && !existing.endsWith('\n') ? '\n' : '';
|
|
24
|
-
fs.appendFileSync(p, `${separator}${rule}\n`, 'utf8');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function isAlreadyIgnored(existing: string, rule: string): boolean {
|
|
28
|
-
return existing.split('\n').some(l => l.trim() === rule);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function buildRule(finding: Finding, scope: 'path' | 'rule+path' | 'rule'): string {
|
|
32
|
-
if (scope === 'path') {
|
|
33
|
-
const dir = path.dirname(finding.file);
|
|
34
|
-
return dir === '.' ? finding.file : `${dir}/**`;
|
|
35
|
-
}
|
|
36
|
-
if (scope === 'rule') return `${finding.id} **`;
|
|
37
|
-
// rule+path: most specific
|
|
38
|
-
const dir = path.dirname(finding.file);
|
|
39
|
-
const glob = dir === '.' ? finding.file : `${dir}/**`;
|
|
40
|
-
return `${finding.id} ${glob}`;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async function prompt(question: string): Promise<string> {
|
|
44
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
45
|
-
return new Promise(resolve => {
|
|
46
|
-
rl.question(question, answer => { rl.close(); resolve(answer.trim()); });
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface IgnoreCommandOptions {
|
|
51
|
-
cwd?: string;
|
|
52
|
-
all?: boolean; // suppress all findings without prompting
|
|
53
|
-
dryRun?: boolean;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export async function runIgnore(options: IgnoreCommandOptions = {}): Promise<number> {
|
|
57
|
-
const cwd = options.cwd ?? process.cwd();
|
|
58
|
-
const findings = loadCachedFindings(cwd);
|
|
59
|
-
|
|
60
|
-
if (findings.length === 0) {
|
|
61
|
-
console.log(fmt('yellow', '[ignore] No cached findings — run `guardrail run` or `guardrail scan` first.'));
|
|
62
|
-
return 0;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const existing = readIgnoreFile(cwd);
|
|
66
|
-
let added = 0;
|
|
67
|
-
|
|
68
|
-
console.log(`\n${fmt('bold', '[ignore]')} ${findings.length} finding${findings.length !== 1 ? 's' : ''} to review\n`);
|
|
69
|
-
|
|
70
|
-
for (const [i, f] of findings.entries()) {
|
|
71
|
-
const sev = f.severity === 'critical' ? fmt('red', 'CRITICAL')
|
|
72
|
-
: f.severity === 'warning' ? fmt('yellow', 'WARNING ')
|
|
73
|
-
: fmt('dim', 'NOTE ');
|
|
74
|
-
const loc = f.file !== '<unspecified>' ? `${f.file}${f.line ? `:${f.line}` : ''}` : '<pipeline>';
|
|
75
|
-
|
|
76
|
-
console.log(`\n${fmt('bold', `${i + 1}/${findings.length}`)} [${sev}] ${f.message}`);
|
|
77
|
-
console.log(fmt('dim', ` ${loc} (rule: ${f.id})`));
|
|
78
|
-
|
|
79
|
-
let scope: string;
|
|
80
|
-
if (options.all) {
|
|
81
|
-
scope = 'r'; // rule+path
|
|
82
|
-
} else {
|
|
83
|
-
console.log(fmt('dim', ' [s] skip [p] suppress path [r] suppress rule+path [R] suppress rule everywhere [q] quit'));
|
|
84
|
-
scope = await prompt(' > ');
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (scope === 'q') break;
|
|
88
|
-
if (scope === 's' || scope === '') continue;
|
|
89
|
-
|
|
90
|
-
const ruleScope = scope === 'p' ? 'path' : scope === 'R' ? 'rule' : 'rule+path';
|
|
91
|
-
const rule = buildRule(f, ruleScope);
|
|
92
|
-
|
|
93
|
-
if (isAlreadyIgnored(existing, rule)) {
|
|
94
|
-
console.log(fmt('dim', ` (already in ${IGNORE_FILE}: ${rule})`));
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (options.dryRun) {
|
|
99
|
-
console.log(fmt('dim', ` (dry run) would add: ${rule}`));
|
|
100
|
-
} else {
|
|
101
|
-
appendIgnoreRule(cwd, rule);
|
|
102
|
-
console.log(fmt('green', ` + added: ${rule}`));
|
|
103
|
-
}
|
|
104
|
-
added++;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
console.log('');
|
|
108
|
-
if (options.dryRun) {
|
|
109
|
-
console.log(fmt('yellow', `[ignore] Dry run — ${added} rule${added !== 1 ? 's' : ''} would be added to ${IGNORE_FILE}\n`));
|
|
110
|
-
} else if (added > 0) {
|
|
111
|
-
console.log(fmt('green', `[ignore] ${added} rule${added !== 1 ? 's' : ''} added to ${IGNORE_FILE}\n`));
|
|
112
|
-
} else {
|
|
113
|
-
console.log(fmt('dim', `[ignore] No rules added\n`));
|
|
114
|
-
}
|
|
115
|
-
return 0;
|
|
116
|
-
}
|