@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/migrate-v4.ts
DELETED
|
@@ -1,388 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `claude-autopilot migrate-v4` — codemod for v4 → v5 rename.
|
|
3
|
-
*
|
|
4
|
-
* Scans a repo for @delegance/guardrail + guardrail CLI references and proposes
|
|
5
|
-
* replacements. Writes with `--write`, restores from manifest with `--undo`.
|
|
6
|
-
*
|
|
7
|
-
* Mutation rules (per codex review of alpha.3 spec):
|
|
8
|
-
* - package.json: updates dependencies, devDependencies, optionalDependencies,
|
|
9
|
-
* peerDependencies. Preserves key ordering within each section. Preserves
|
|
10
|
-
* semver operator shape (^/~/>=/exact) — only rewrites the package name and
|
|
11
|
-
* bumps to ^5.0.0-alpha.
|
|
12
|
-
* - Shell scripts, Makefiles, workflow yaml, Dockerfiles: word-boundary match
|
|
13
|
-
* on `guardrail <verb>` → `claude-autopilot <verb>`, and
|
|
14
|
-
* `@delegance/guardrail` → `@delegance/claude-autopilot`.
|
|
15
|
-
* - package-lock.json: NOT touched (regenerated by npm install).
|
|
16
|
-
*
|
|
17
|
-
* --undo reads `.claude-autopilot/migrate-v4-manifest.json` and restores files
|
|
18
|
-
* by sha256 match. Rejects restoration if the current file differs from the
|
|
19
|
-
* backup's post-write hash, preventing clobber of user edits.
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import * as fs from 'node:fs';
|
|
23
|
-
import * as path from 'node:path';
|
|
24
|
-
import * as crypto from 'node:crypto';
|
|
25
|
-
|
|
26
|
-
export interface MigrateV4Options {
|
|
27
|
-
cwd?: string;
|
|
28
|
-
write?: boolean;
|
|
29
|
-
undo?: boolean;
|
|
30
|
-
path?: string;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
interface Replacement {
|
|
34
|
-
pattern: RegExp;
|
|
35
|
-
replace: (match: string, ...groups: string[]) => string;
|
|
36
|
-
description: string;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
interface FileResult {
|
|
40
|
-
path: string;
|
|
41
|
-
relPath: string;
|
|
42
|
-
replacements: number;
|
|
43
|
-
preview: string[];
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
interface ManifestEntry {
|
|
47
|
-
path: string;
|
|
48
|
-
beforeSha256: string;
|
|
49
|
-
afterSha256: string;
|
|
50
|
-
backupPath: string;
|
|
51
|
-
timestamp: string;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const MANIFEST_DIR = '.claude-autopilot';
|
|
55
|
-
const MANIFEST_NAME = 'migrate-v4-manifest.json';
|
|
56
|
-
|
|
57
|
-
// File patterns to scan. Glob-like but hand-rolled — no dep on minimatch for this path.
|
|
58
|
-
const INCLUDE_EXTENSIONS = new Set([
|
|
59
|
-
'.sh', '.bash', '.zsh', '.fish', '.mk', '.yml', '.yaml', '.json', '.toml', '.md',
|
|
60
|
-
]);
|
|
61
|
-
const INCLUDE_FILENAMES = new Set([
|
|
62
|
-
'Makefile', 'Dockerfile', 'dockerfile', 'package.json',
|
|
63
|
-
'.pre-commit-config.yaml', '.pre-commit-hooks.yaml', '.husky',
|
|
64
|
-
]);
|
|
65
|
-
|
|
66
|
-
// Lockfiles are explicitly skipped — text substitution would corrupt their
|
|
67
|
-
// internal structure (resolved URLs, integrity hashes, peer-dep graphs).
|
|
68
|
-
// Users regenerate them via `npm install` after the migrate completes.
|
|
69
|
-
const SKIP_FILENAMES = new Set([
|
|
70
|
-
'package-lock.json',
|
|
71
|
-
'npm-shrinkwrap.json',
|
|
72
|
-
'pnpm-lock.yaml',
|
|
73
|
-
'yarn.lock',
|
|
74
|
-
'bun.lockb',
|
|
75
|
-
'bun.lock',
|
|
76
|
-
]);
|
|
77
|
-
|
|
78
|
-
const SKIP_DIRS = new Set([
|
|
79
|
-
'node_modules', '.git', 'dist', 'build', '.next', '.nuxt', 'out',
|
|
80
|
-
'coverage', '__pycache__', '.venv', 'venv', '.turbo',
|
|
81
|
-
MANIFEST_DIR, // don't mutate our own manifest
|
|
82
|
-
]);
|
|
83
|
-
|
|
84
|
-
const VERBS = 'run|scan|ci|setup|doctor|init|fix|baseline|explain|ignore|costs|watch|hook|autoregress|triage|pr-desc|council|report|test-gen|mcp|lsp|worker|pr|preflight';
|
|
85
|
-
|
|
86
|
-
const TEXT_REPLACEMENTS: Replacement[] = [
|
|
87
|
-
// Package name with version suffix (`@delegance/guardrail@^4`, `@delegance/guardrail@4.3.1`)
|
|
88
|
-
// MUST run before the bare-name rule. Replaces the entire spec with
|
|
89
|
-
// `@delegance/claude-autopilot@alpha` — the old `^4` / `4.3.1` ranges don't
|
|
90
|
-
// resolve against the new package (it starts at 5.0.0).
|
|
91
|
-
{
|
|
92
|
-
pattern: /@delegance\/guardrail@[^\s"'`,)\]}]+/g,
|
|
93
|
-
replace: () => '@delegance/claude-autopilot@alpha',
|
|
94
|
-
description: '@delegance/guardrail@<version> → @delegance/claude-autopilot@alpha',
|
|
95
|
-
},
|
|
96
|
-
// Bare package name (no version suffix) — used in imports, package.json keys,
|
|
97
|
-
// prose references. Preserves surrounding context.
|
|
98
|
-
{
|
|
99
|
-
pattern: /@delegance\/guardrail\b/g,
|
|
100
|
-
replace: () => '@delegance/claude-autopilot',
|
|
101
|
-
description: '@delegance/guardrail → @delegance/claude-autopilot',
|
|
102
|
-
},
|
|
103
|
-
// `npx guardrail <verb>` / `pnpm dlx guardrail <verb>` / `yarn dlx guardrail <verb>`.
|
|
104
|
-
// These must run BEFORE the bare `guardrail <verb>` pattern below so the package-
|
|
105
|
-
// name `guardrail` inside `npx` is replaced as a unit with its wrapper tool.
|
|
106
|
-
{
|
|
107
|
-
pattern: new RegExp(
|
|
108
|
-
`((?:^|\\s)(?:npx|pnpm\\s+dlx|yarn\\s+dlx|bunx)\\s+)guardrail(\\s+)(${VERBS})\\b`,
|
|
109
|
-
'g',
|
|
110
|
-
),
|
|
111
|
-
replace: (_m, wrapper, ws, verb) => `${wrapper}@delegance/claude-autopilot@alpha${ws}${verb}`,
|
|
112
|
-
description: 'npx/pnpm dlx/yarn dlx guardrail <verb> → ... @delegance/claude-autopilot@alpha <verb>',
|
|
113
|
-
},
|
|
114
|
-
// `guardrail <verb>` on its own line or after whitespace/punctuation
|
|
115
|
-
{
|
|
116
|
-
pattern: new RegExp(`(^|[\\s\`"'(])guardrail(\\s+)(${VERBS})\\b`, 'g'),
|
|
117
|
-
replace: (_m, lead, ws, verb) => `${lead}claude-autopilot${ws}${verb}`,
|
|
118
|
-
description: '`guardrail <verb>` → `claude-autopilot <verb>`',
|
|
119
|
-
},
|
|
120
|
-
// Quoted `"guardrail"` in argv-style arrays — Dockerfile CMD, exec args, etc.
|
|
121
|
-
{
|
|
122
|
-
pattern: new RegExp(
|
|
123
|
-
`(["'])guardrail(["'])(\\s*,\\s*)(["'])(${VERBS})\\b`,
|
|
124
|
-
'g',
|
|
125
|
-
),
|
|
126
|
-
replace: (_m, q1, q2, sep, q3, verb) => `${q1}claude-autopilot${q2}${sep}${q3}${verb}`,
|
|
127
|
-
description: '`"guardrail", "<verb>"` → `"claude-autopilot", "<verb>"`',
|
|
128
|
-
},
|
|
129
|
-
];
|
|
130
|
-
|
|
131
|
-
// package.json needs JSON-aware handling for the dependency keys (to preserve
|
|
132
|
-
// semver operators and section structure), plus text replacements on the rest
|
|
133
|
-
// of the file (for scripts, bin references, etc).
|
|
134
|
-
function migratePackageJson(content: string): { updated: string; count: number } {
|
|
135
|
-
let pkg: Record<string, unknown>;
|
|
136
|
-
try {
|
|
137
|
-
pkg = JSON.parse(content) as Record<string, unknown>;
|
|
138
|
-
} catch {
|
|
139
|
-
return applyTextReplacements(content);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
let count = 0;
|
|
143
|
-
for (const section of ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies']) {
|
|
144
|
-
const deps = pkg[section] as Record<string, string> | undefined;
|
|
145
|
-
if (deps && typeof deps === 'object' && '@delegance/guardrail' in deps) {
|
|
146
|
-
const oldRange = deps['@delegance/guardrail']!;
|
|
147
|
-
const m = oldRange.match(/^(\^|~|>=|<=|>|<|=)?/);
|
|
148
|
-
const operator = (m && m[1]) ?? '';
|
|
149
|
-
// Rebuild the deps object preserving key order — substitute the old key
|
|
150
|
-
// in place with the new one. Straight `delete` + reassign would append
|
|
151
|
-
// the renamed dep at the end of its section, producing noisy diffs.
|
|
152
|
-
const rebuilt: Record<string, string> = {};
|
|
153
|
-
for (const [key, value] of Object.entries(deps)) {
|
|
154
|
-
if (key === '@delegance/guardrail') {
|
|
155
|
-
rebuilt['@delegance/claude-autopilot'] = `${operator}5.0.0-alpha`;
|
|
156
|
-
} else {
|
|
157
|
-
rebuilt[key] = value;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
pkg[section] = rebuilt;
|
|
161
|
-
count++;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const indent = detectJsonIndent(content);
|
|
166
|
-
const newline = content.endsWith('\n') ? '\n' : '';
|
|
167
|
-
const rewritten = JSON.stringify(pkg, null, indent) + newline;
|
|
168
|
-
|
|
169
|
-
// Text replacements on the stringified form — catches `guardrail <verb>` in
|
|
170
|
-
// scripts, bin paths, and any other embedded CLI invocation.
|
|
171
|
-
const { updated, count: textCount } = applyTextReplacements(rewritten);
|
|
172
|
-
return { updated, count: count + textCount };
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function detectJsonIndent(source: string): number | string {
|
|
176
|
-
const m = source.match(/\n( +)"/);
|
|
177
|
-
if (m && m[1]) return m[1].length;
|
|
178
|
-
return 2;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function applyTextReplacements(content: string): { updated: string; count: number } {
|
|
182
|
-
let updated = content;
|
|
183
|
-
let count = 0;
|
|
184
|
-
for (const r of TEXT_REPLACEMENTS) {
|
|
185
|
-
updated = updated.replace(r.pattern, (...args) => {
|
|
186
|
-
count++;
|
|
187
|
-
return r.replace(args[0], ...args.slice(1, args.length - 2));
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
return { updated, count };
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function shouldProcessFile(filePath: string): boolean {
|
|
194
|
-
const base = path.basename(filePath);
|
|
195
|
-
if (SKIP_FILENAMES.has(base)) return false;
|
|
196
|
-
const ext = path.extname(filePath);
|
|
197
|
-
if (INCLUDE_FILENAMES.has(base)) return true;
|
|
198
|
-
if (INCLUDE_EXTENSIONS.has(ext)) return true;
|
|
199
|
-
return false;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function collectFiles(root: string): string[] {
|
|
203
|
-
const out: string[] = [];
|
|
204
|
-
function walk(dir: string): void {
|
|
205
|
-
let entries: fs.Dirent[];
|
|
206
|
-
try {
|
|
207
|
-
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
208
|
-
} catch { return; }
|
|
209
|
-
for (const entry of entries) {
|
|
210
|
-
const full = path.join(dir, entry.name);
|
|
211
|
-
if (entry.isDirectory()) {
|
|
212
|
-
if (SKIP_DIRS.has(entry.name)) continue;
|
|
213
|
-
walk(full);
|
|
214
|
-
} else if (entry.isFile() && shouldProcessFile(full)) {
|
|
215
|
-
out.push(full);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
walk(root);
|
|
220
|
-
return out;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
function sha256(content: string): string {
|
|
224
|
-
return crypto.createHash('sha256').update(content).digest('hex');
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function processFile(file: string): { replacements: number; original: string; updated: string; preview: string[] } {
|
|
228
|
-
const original = fs.readFileSync(file, 'utf8');
|
|
229
|
-
const { updated, count } = path.basename(file) === 'package.json'
|
|
230
|
-
? migratePackageJson(original)
|
|
231
|
-
: applyTextReplacements(original);
|
|
232
|
-
if (count === 0) return { replacements: 0, original, updated: original, preview: [] };
|
|
233
|
-
const preview = diffPreview(original, updated);
|
|
234
|
-
return { replacements: count, original, updated, preview };
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
function diffPreview(before: string, after: string): string[] {
|
|
238
|
-
const preview: string[] = [];
|
|
239
|
-
const beforeLines = before.split('\n');
|
|
240
|
-
const afterLines = after.split('\n');
|
|
241
|
-
const maxLines = Math.max(beforeLines.length, afterLines.length);
|
|
242
|
-
for (let i = 0; i < maxLines && preview.length < 10; i++) {
|
|
243
|
-
const b = beforeLines[i] ?? '';
|
|
244
|
-
const a = afterLines[i] ?? '';
|
|
245
|
-
if (b !== a) {
|
|
246
|
-
if (b) preview.push(` - ${b.trim().slice(0, 100)}`);
|
|
247
|
-
if (a) preview.push(` + ${a.trim().slice(0, 100)}`);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
return preview;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
export async function runMigrateV4(options: MigrateV4Options = {}): Promise<number> {
|
|
254
|
-
const cwd = options.cwd ?? options.path ?? process.cwd();
|
|
255
|
-
|
|
256
|
-
if (options.undo) return runUndo(cwd);
|
|
257
|
-
|
|
258
|
-
const files = collectFiles(cwd);
|
|
259
|
-
const results: FileResult[] = [];
|
|
260
|
-
let totalReplacements = 0;
|
|
261
|
-
|
|
262
|
-
const manifest: ManifestEntry[] = [];
|
|
263
|
-
|
|
264
|
-
for (const file of files) {
|
|
265
|
-
const { replacements, original, updated, preview } = processFile(file);
|
|
266
|
-
if (replacements === 0) continue;
|
|
267
|
-
results.push({
|
|
268
|
-
path: file,
|
|
269
|
-
relPath: path.relative(cwd, file),
|
|
270
|
-
replacements,
|
|
271
|
-
preview,
|
|
272
|
-
});
|
|
273
|
-
totalReplacements += replacements;
|
|
274
|
-
|
|
275
|
-
if (options.write) {
|
|
276
|
-
// Reuse `original` from processFile — avoids a second read + prevents any
|
|
277
|
-
// chance of `beforeSha256` diverging from what the transformation actually
|
|
278
|
-
// consumed if the file changed mid-scan.
|
|
279
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
280
|
-
const backupPath = `${file}.v4-backup.${timestamp}`;
|
|
281
|
-
fs.writeFileSync(backupPath, original);
|
|
282
|
-
fs.writeFileSync(file, updated);
|
|
283
|
-
manifest.push({
|
|
284
|
-
path: file,
|
|
285
|
-
beforeSha256: sha256(original),
|
|
286
|
-
afterSha256: sha256(updated),
|
|
287
|
-
backupPath,
|
|
288
|
-
timestamp,
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// Emit report
|
|
294
|
-
console.log(`\n\x1b[1m[migrate-v4] ${options.write ? 'Writing' : 'Dry-run — scanning'} ${cwd}\x1b[0m\n`);
|
|
295
|
-
if (results.length === 0) {
|
|
296
|
-
console.log(' No v4 references found.');
|
|
297
|
-
return 0;
|
|
298
|
-
}
|
|
299
|
-
for (const r of results) {
|
|
300
|
-
console.log(` \x1b[32m${r.replacements}\x1b[0m ${r.relPath}`);
|
|
301
|
-
for (const line of r.preview.slice(0, 4)) console.log(` \x1b[2m${line}\x1b[0m`);
|
|
302
|
-
}
|
|
303
|
-
console.log(`\n ─────────────────────────────`);
|
|
304
|
-
console.log(` ${totalReplacements} replacements across ${results.length} files`);
|
|
305
|
-
|
|
306
|
-
if (options.write) {
|
|
307
|
-
const manifestDir = path.join(cwd, MANIFEST_DIR);
|
|
308
|
-
fs.mkdirSync(manifestDir, { recursive: true });
|
|
309
|
-
const manifestPath = path.join(manifestDir, MANIFEST_NAME);
|
|
310
|
-
fs.writeFileSync(manifestPath, JSON.stringify({
|
|
311
|
-
migratedAt: new Date().toISOString(),
|
|
312
|
-
from: '@delegance/guardrail',
|
|
313
|
-
to: '@delegance/claude-autopilot',
|
|
314
|
-
entries: manifest,
|
|
315
|
-
}, null, 2));
|
|
316
|
-
console.log(`\n \x1b[32m✓\x1b[0m Applied. Manifest: ${path.relative(cwd, manifestPath)}`);
|
|
317
|
-
console.log(` Backup files suffix: .v4-backup.<timestamp>`);
|
|
318
|
-
console.log(` Restore: claude-autopilot migrate-v4 --undo`);
|
|
319
|
-
console.log(`\n Next: run \`npm install\` to sync package-lock.json.`);
|
|
320
|
-
} else {
|
|
321
|
-
console.log(`\n Run with \x1b[36m--write\x1b[0m to apply (with .v4-backup files + restore manifest).`);
|
|
322
|
-
}
|
|
323
|
-
return 0;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
function runUndo(cwd: string): number {
|
|
327
|
-
const manifestPath = path.join(cwd, MANIFEST_DIR, MANIFEST_NAME);
|
|
328
|
-
if (!fs.existsSync(manifestPath)) {
|
|
329
|
-
console.error(`[migrate-v4] No manifest at ${manifestPath}. Nothing to undo.`);
|
|
330
|
-
return 1;
|
|
331
|
-
}
|
|
332
|
-
const raw = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as {
|
|
333
|
-
migratedAt: string;
|
|
334
|
-
from: string;
|
|
335
|
-
to: string;
|
|
336
|
-
entries: ManifestEntry[];
|
|
337
|
-
};
|
|
338
|
-
const restored: ManifestEntry[] = [];
|
|
339
|
-
const pending: ManifestEntry[] = [];
|
|
340
|
-
|
|
341
|
-
for (const entry of raw.entries) {
|
|
342
|
-
if (!fs.existsSync(entry.path)) {
|
|
343
|
-
console.error(` \x1b[33m!\x1b[0m ${path.relative(cwd, entry.path)} missing — skipping`);
|
|
344
|
-
pending.push(entry);
|
|
345
|
-
continue;
|
|
346
|
-
}
|
|
347
|
-
if (!fs.existsSync(entry.backupPath)) {
|
|
348
|
-
console.error(` \x1b[33m!\x1b[0m backup missing for ${path.relative(cwd, entry.path)} — skipping`);
|
|
349
|
-
pending.push(entry);
|
|
350
|
-
continue;
|
|
351
|
-
}
|
|
352
|
-
const currentHash = sha256(fs.readFileSync(entry.path, 'utf8'));
|
|
353
|
-
if (currentHash !== entry.afterSha256) {
|
|
354
|
-
console.error(` \x1b[33m!\x1b[0m ${path.relative(cwd, entry.path)} modified since migrate — refusing to overwrite`);
|
|
355
|
-
console.error(` expected sha256=${entry.afterSha256.slice(0, 8)}, got ${currentHash.slice(0, 8)}`);
|
|
356
|
-
pending.push(entry);
|
|
357
|
-
continue;
|
|
358
|
-
}
|
|
359
|
-
const backup = fs.readFileSync(entry.backupPath, 'utf8');
|
|
360
|
-
if (sha256(backup) !== entry.beforeSha256) {
|
|
361
|
-
console.error(` \x1b[33m!\x1b[0m backup ${path.relative(cwd, entry.backupPath)} tampered — skipping`);
|
|
362
|
-
pending.push(entry);
|
|
363
|
-
continue;
|
|
364
|
-
}
|
|
365
|
-
fs.writeFileSync(entry.path, backup);
|
|
366
|
-
fs.unlinkSync(entry.backupPath);
|
|
367
|
-
console.log(` \x1b[32m✓\x1b[0m ${path.relative(cwd, entry.path)}`);
|
|
368
|
-
restored.push(entry);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
// Preserve manifest when any entries remain pending so --undo can be re-run
|
|
372
|
-
// after the user resolves the blocker (restored their edits, fixed backup, etc).
|
|
373
|
-
if (pending.length > 0) {
|
|
374
|
-
fs.writeFileSync(manifestPath, JSON.stringify({
|
|
375
|
-
...raw,
|
|
376
|
-
entries: pending,
|
|
377
|
-
}, null, 2));
|
|
378
|
-
console.log(
|
|
379
|
-
`\n Restored ${restored.length}, ${pending.length} pending. ` +
|
|
380
|
-
`Manifest retained at ${path.relative(cwd, manifestPath)} — re-run --undo after resolving issues.`,
|
|
381
|
-
);
|
|
382
|
-
return 1;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
fs.unlinkSync(manifestPath);
|
|
386
|
-
console.log(`\n Restored ${restored.length}, skipped 0.`);
|
|
387
|
-
return 0;
|
|
388
|
-
}
|
package/src/cli/pr-comment.ts
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { runSafe } from '../core/shell.ts';
|
|
2
|
-
import type { RunResult } from '../core/pipeline/run.ts';
|
|
3
|
-
import type { GuardrailConfig } from '../core/config/types.ts';
|
|
4
|
-
import type { GitContext } from '../core/detect/git-context.ts';
|
|
5
|
-
import { readFileSync } from 'node:fs';
|
|
6
|
-
import { join } from 'node:path';
|
|
7
|
-
import { findPackageRoot } from './_pkg-root.ts';
|
|
8
|
-
|
|
9
|
-
const COMMENT_MARKER = '<!-- guardrail-review -->';
|
|
10
|
-
|
|
11
|
-
function readVersion(): string {
|
|
12
|
-
try {
|
|
13
|
-
const root = findPackageRoot(import.meta.url);
|
|
14
|
-
if (!root) return 'unknown';
|
|
15
|
-
const pkgPath = join(root, 'package.json');
|
|
16
|
-
return (JSON.parse(readFileSync(pkgPath, 'utf8')) as { version: string }).version;
|
|
17
|
-
} catch { return 'unknown'; }
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** Detect the current open PR number via gh CLI or CI env vars. */
|
|
21
|
-
export function detectPrNumber(cwd: string): number | null {
|
|
22
|
-
// CI env vars set by GitHub Actions
|
|
23
|
-
const fromEnv = process.env.PR_NUMBER ?? process.env.GH_PR_NUMBER ?? process.env.GITHUB_PR_NUMBER;
|
|
24
|
-
if (fromEnv && /^\d+$/.test(fromEnv)) return parseInt(fromEnv, 10);
|
|
25
|
-
|
|
26
|
-
// gh CLI — works locally and in CI when gh is authenticated
|
|
27
|
-
const raw = runSafe('gh', ['pr', 'view', '--json', 'number', '--jq', '.number'], { cwd });
|
|
28
|
-
if (raw) {
|
|
29
|
-
const n = parseInt(raw.trim(), 10);
|
|
30
|
-
if (!isNaN(n)) return n;
|
|
31
|
-
}
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/** Find the ID of a previously-posted autopilot comment, if any. */
|
|
36
|
-
function findExistingCommentId(pr: number, cwd: string): number | null {
|
|
37
|
-
const raw = runSafe('gh', ['api', `repos/{owner}/{repo}/issues/${pr}/comments`,
|
|
38
|
-
'--jq', `[.[] | select(.body | startswith("${COMMENT_MARKER}")) | .id] | first`], { cwd });
|
|
39
|
-
if (!raw) return null;
|
|
40
|
-
const n = parseInt(raw.trim(), 10);
|
|
41
|
-
return isNaN(n) ? null : n;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** Format a RunResult into a markdown PR comment. */
|
|
45
|
-
export function formatComment(
|
|
46
|
-
result: RunResult,
|
|
47
|
-
config: GuardrailConfig,
|
|
48
|
-
gitCtx: GitContext,
|
|
49
|
-
touchedFileCount: number,
|
|
50
|
-
): string {
|
|
51
|
-
const statusIcon = result.status === 'pass' ? '✅' : result.status === 'warn' ? '⚠️' : '❌';
|
|
52
|
-
const statusLabel = result.status === 'pass' ? 'Passed' : result.status === 'warn' ? 'Passed with warnings' : 'Failed';
|
|
53
|
-
|
|
54
|
-
const lines: string[] = [
|
|
55
|
-
COMMENT_MARKER,
|
|
56
|
-
`## ${statusIcon} Autopilot Review — ${statusLabel}`,
|
|
57
|
-
'',
|
|
58
|
-
];
|
|
59
|
-
|
|
60
|
-
// Context line
|
|
61
|
-
const ctx: string[] = [];
|
|
62
|
-
if (config.stack) ctx.push(`**Stack:** ${config.stack}`);
|
|
63
|
-
if (gitCtx.branch) ctx.push(`**Branch:** \`${gitCtx.branch}\``);
|
|
64
|
-
if (gitCtx.commitMessage) ctx.push(`**Commit:** ${gitCtx.commitMessage}`);
|
|
65
|
-
ctx.push(`**Files reviewed:** ${touchedFileCount}`);
|
|
66
|
-
lines.push(ctx.join(' · '), '');
|
|
67
|
-
|
|
68
|
-
// Phase table
|
|
69
|
-
lines.push('| Phase | Status | Findings |');
|
|
70
|
-
lines.push('|---|:---:|:---:|');
|
|
71
|
-
for (const phase of result.phases) {
|
|
72
|
-
const icon = phase.status === 'pass' ? '✅' : phase.status === 'skip' ? '—' :
|
|
73
|
-
phase.status === 'warn' ? '⚠️' : '❌';
|
|
74
|
-
lines.push(`| ${phase.phase} | ${icon} | ${phase.findings.length} |`);
|
|
75
|
-
}
|
|
76
|
-
lines.push('');
|
|
77
|
-
|
|
78
|
-
// Findings by severity
|
|
79
|
-
const critical = result.allFindings.filter(f => f.severity === 'critical');
|
|
80
|
-
const warnings = result.allFindings.filter(f => f.severity === 'warning');
|
|
81
|
-
const notes = result.allFindings.filter(f => f.severity === 'note');
|
|
82
|
-
|
|
83
|
-
if (critical.length > 0) {
|
|
84
|
-
lines.push('### 🚨 Critical');
|
|
85
|
-
for (const f of critical) {
|
|
86
|
-
const loc = f.file !== '<unspecified>' ? `\`${f.file}${f.line ? `:${f.line}` : ''}\` — ` : '';
|
|
87
|
-
lines.push(`- ${loc}${f.message}`);
|
|
88
|
-
if (f.suggestion) lines.push(` > ${f.suggestion}`);
|
|
89
|
-
}
|
|
90
|
-
lines.push('');
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (warnings.length > 0) {
|
|
94
|
-
lines.push('### ⚠️ Warnings');
|
|
95
|
-
for (const f of warnings) {
|
|
96
|
-
const loc = f.file !== '<unspecified>' ? `\`${f.file}${f.line ? `:${f.line}` : ''}\` — ` : '';
|
|
97
|
-
lines.push(`- ${loc}${f.message}`);
|
|
98
|
-
if (f.suggestion) lines.push(` > ${f.suggestion}`);
|
|
99
|
-
}
|
|
100
|
-
lines.push('');
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (notes.length > 0) {
|
|
104
|
-
lines.push('<details><summary>Notes</summary>\n');
|
|
105
|
-
for (const f of notes) {
|
|
106
|
-
const loc = f.file !== '<unspecified>' ? `\`${f.file}${f.line ? `:${f.line}` : ''}\` — ` : '';
|
|
107
|
-
lines.push(`- ${loc}${f.message}`);
|
|
108
|
-
}
|
|
109
|
-
lines.push('\n</details>\n');
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (result.totalCostUSD !== undefined) {
|
|
113
|
-
lines.push(`*Cost: $${result.totalCostUSD.toFixed(4)} · ${result.durationMs}ms · [@delegance/guardrail](https://github.com/axledbetter/guardrail) v${readVersion()}*`);
|
|
114
|
-
} else {
|
|
115
|
-
lines.push(`*${result.durationMs}ms · [@delegance/guardrail](https://github.com/axledbetter/guardrail) v${readVersion()}*`);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return lines.join('\n');
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/** Post or update the autopilot comment on the given PR. */
|
|
122
|
-
export async function postPrComment(
|
|
123
|
-
pr: number,
|
|
124
|
-
body: string,
|
|
125
|
-
cwd: string,
|
|
126
|
-
): Promise<{ action: 'created' | 'updated'; url: string | null }> {
|
|
127
|
-
const existingId = findExistingCommentId(pr, cwd);
|
|
128
|
-
|
|
129
|
-
if (existingId) {
|
|
130
|
-
runSafe('gh', ['api', `repos/{owner}/{repo}/issues/comments/${existingId}`,
|
|
131
|
-
'--method', 'PATCH', '--field', `body=${body}`], { cwd });
|
|
132
|
-
return { action: 'updated', url: null };
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const raw = runSafe('gh', ['pr', 'comment', String(pr), '--body', body], { cwd });
|
|
136
|
-
// gh outputs the comment URL on success
|
|
137
|
-
const url = raw?.trim() ?? null;
|
|
138
|
-
return { action: 'created', url };
|
|
139
|
-
}
|
package/src/cli/pr-desc.ts
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import type { Finding } from '../core/findings/types.ts';
|
|
2
|
-
import * as fs from 'node:fs';
|
|
3
|
-
import { execSync, spawnSync } from 'node:child_process';
|
|
4
|
-
|
|
5
|
-
export interface PrDescOptions {
|
|
6
|
-
base?: string;
|
|
7
|
-
post?: boolean;
|
|
8
|
-
yes?: boolean;
|
|
9
|
-
output?: string;
|
|
10
|
-
_gitDiff?: string;
|
|
11
|
-
_branchName?: string;
|
|
12
|
-
_cachedFindings?: Finding[];
|
|
13
|
-
_reviewEngine?: {
|
|
14
|
-
review(input: { content: string; kind: string }): Promise<{ rawOutput: string }>;
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface PrDescResult {
|
|
19
|
-
title: string;
|
|
20
|
-
body: string;
|
|
21
|
-
prUrl?: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function truncateDiff(diff: string, charLimit = 6000): string {
|
|
25
|
-
if (diff.length <= charLimit) return diff;
|
|
26
|
-
const remaining = diff.length - charLimit;
|
|
27
|
-
return `${diff.slice(0, charLimit)}[...truncated ${remaining} chars]`;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function summarizeFindings(findings: Finding[], max = 10): string {
|
|
31
|
-
if (findings.length === 0) return 'None';
|
|
32
|
-
const order: Record<string, number> = { critical: 0, error: 1, warning: 2, info: 3 };
|
|
33
|
-
const sorted = [...findings].sort(
|
|
34
|
-
(a, b) => (order[a.severity] ?? 9) - (order[b.severity] ?? 9),
|
|
35
|
-
);
|
|
36
|
-
return sorted
|
|
37
|
-
.slice(0, max)
|
|
38
|
-
.map(f => `- [${f.severity.toUpperCase()}] ${f.file}:${f.line ?? '?'} — ${f.message}`)
|
|
39
|
-
.join('\n');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function parseDescription(raw: string): { title: string; body: string } {
|
|
43
|
-
const titleMatch = raw.match(/^Title:\s*(.+)$/m);
|
|
44
|
-
const title = titleMatch ? titleMatch[1]!.trim() : 'chore: update';
|
|
45
|
-
const sepIdx = raw.indexOf('\n\n---\n');
|
|
46
|
-
const body = sepIdx !== -1 ? raw.slice(sepIdx + 5).trim() : raw.replace(/^Title:.*\n?/m, '').trim();
|
|
47
|
-
return { title, body };
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export async function runPrDesc(options: PrDescOptions): Promise<PrDescResult> {
|
|
51
|
-
const branchName = options._branchName ?? getBranchName();
|
|
52
|
-
const diff = options._gitDiff ?? getGitDiff(options.base);
|
|
53
|
-
|
|
54
|
-
if (!diff.trim()) {
|
|
55
|
-
process.stdout.write('No changes detected\n');
|
|
56
|
-
return { title: 'No changes detected', body: '' };
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const findings = options._cachedFindings ?? loadCachedFindings();
|
|
60
|
-
const prompt = buildPrompt(branchName, truncateDiff(diff), summarizeFindings(findings));
|
|
61
|
-
|
|
62
|
-
const engine = options._reviewEngine ?? (await resolveEngine() as unknown as { review(input: { content: string; kind: string }): Promise<{ rawOutput: string }> });
|
|
63
|
-
const { rawOutput } = await engine.review({ content: prompt, kind: 'pr-diff' });
|
|
64
|
-
const { title, body } = parseDescription(rawOutput);
|
|
65
|
-
|
|
66
|
-
const formatted = `Title: ${title}\n\n---\n${body}`;
|
|
67
|
-
|
|
68
|
-
if (options.output) {
|
|
69
|
-
fs.writeFileSync(options.output, formatted, 'utf8');
|
|
70
|
-
} else {
|
|
71
|
-
process.stdout.write(formatted + '\n');
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (options.post) {
|
|
75
|
-
return createPr(title, body, options.yes ?? false);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return { title, body };
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function getBranchName(): string {
|
|
82
|
-
try {
|
|
83
|
-
return execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();
|
|
84
|
-
} catch {
|
|
85
|
-
return 'unknown';
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function getGitDiff(base?: string): string {
|
|
90
|
-
try {
|
|
91
|
-
const ref = base ?? getUpstreamBase();
|
|
92
|
-
return execSync(`git diff ${ref}...HEAD`, { encoding: 'utf8' });
|
|
93
|
-
} catch {
|
|
94
|
-
return '';
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function getUpstreamBase(): string {
|
|
99
|
-
try {
|
|
100
|
-
return execSync(
|
|
101
|
-
'git rev-parse --abbrev-ref --symbolic-full-name @{u}',
|
|
102
|
-
{ encoding: 'utf8' },
|
|
103
|
-
).trim();
|
|
104
|
-
} catch {
|
|
105
|
-
return 'HEAD~1';
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function loadCachedFindings(): Finding[] {
|
|
110
|
-
try {
|
|
111
|
-
return JSON.parse(fs.readFileSync('.guardrail-cache/findings.json', 'utf8')) as Finding[];
|
|
112
|
-
} catch {
|
|
113
|
-
return [];
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function buildPrompt(branch: string, diff: string, findingsSummary: string): string {
|
|
118
|
-
return `Generate a pull request description with three sections:
|
|
119
|
-
|
|
120
|
-
## Summary
|
|
121
|
-
<3-5 bullet points describing what changed and why>
|
|
122
|
-
|
|
123
|
-
## Changes
|
|
124
|
-
<grouped by file/area, concise>
|
|
125
|
-
|
|
126
|
-
## Test Plan
|
|
127
|
-
<checklist of what to verify before merging>
|
|
128
|
-
|
|
129
|
-
Branch: ${branch}
|
|
130
|
-
Diff:
|
|
131
|
-
${diff}
|
|
132
|
-
|
|
133
|
-
Guardrail findings in this diff:
|
|
134
|
-
${findingsSummary}`;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
async function resolveEngine() {
|
|
138
|
-
const { loadAdapter } = await import('../adapters/loader.ts');
|
|
139
|
-
const { loadConfig } = await import('../core/config/loader.ts');
|
|
140
|
-
const configPath = process.env.GUARDRAIL_CONFIG ?? 'guardrail.config.yaml';
|
|
141
|
-
let engineRef = 'auto';
|
|
142
|
-
try {
|
|
143
|
-
const cfg = await loadConfig(configPath);
|
|
144
|
-
const rev = (cfg as { reviewEngine?: unknown }).reviewEngine;
|
|
145
|
-
if (rev) engineRef = typeof rev === 'string' ? rev : (rev as { adapter: string }).adapter;
|
|
146
|
-
} catch {
|
|
147
|
-
// no config file — fall back to auto
|
|
148
|
-
}
|
|
149
|
-
return loadAdapter({ point: 'review-engine', ref: engineRef });
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
async function createPr(title: string, body: string, yes: boolean): Promise<PrDescResult> {
|
|
153
|
-
if (!yes) {
|
|
154
|
-
process.stdout.write('\nCreate PR with this description? [y/N] ');
|
|
155
|
-
const answer = await new Promise<string>(resolve => {
|
|
156
|
-
process.stdin.setEncoding('utf8');
|
|
157
|
-
process.stdin.once('data', (chunk: string) => resolve(chunk.split('\n')[0] ?? ''));
|
|
158
|
-
});
|
|
159
|
-
if (!answer.toLowerCase().startsWith('y')) return { title, body };
|
|
160
|
-
}
|
|
161
|
-
const result = spawnSync('gh', ['pr', 'create', '--title', title, '--body', body], { encoding: 'utf8' });
|
|
162
|
-
if (result.status !== 0) {
|
|
163
|
-
throw new Error(`gh pr create failed: ${result.stderr?.trim() || result.error?.message || 'unknown error'}`);
|
|
164
|
-
}
|
|
165
|
-
const prUrl = result.stdout.trim();
|
|
166
|
-
process.stdout.write(`\nPR created: ${prUrl}\n`);
|
|
167
|
-
return { title, body, prUrl };
|
|
168
|
-
}
|