limn-review 0.1.123
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/LICENSE +110 -0
- package/README.md +133 -0
- package/dist/ai/runtime.js +535 -0
- package/dist/api/plugins/auth.js +169 -0
- package/dist/api/plugins/error-handler.js +114 -0
- package/dist/api/plugins/rate-limit.js +855 -0
- package/dist/api/plugins/security.js +321 -0
- package/dist/api/routes/activity.js +103 -0
- package/dist/api/routes/ai-runtime.js +67 -0
- package/dist/api/routes/auth.js +194 -0
- package/dist/api/routes/billing.js +209 -0
- package/dist/api/routes/bot-triage.js +1289 -0
- package/dist/api/routes/conflicts.js +730 -0
- package/dist/api/routes/contact.js +318 -0
- package/dist/api/routes/daily-brief.js +58 -0
- package/dist/api/routes/flow.js +71 -0
- package/dist/api/routes/health.js +7 -0
- package/dist/api/routes/insights.js +200 -0
- package/dist/api/routes/me.js +458 -0
- package/dist/api/routes/mentions.js +22 -0
- package/dist/api/routes/mergers.js +8 -0
- package/dist/api/routes/ml-labels.js +109 -0
- package/dist/api/routes/open-prs.js +35 -0
- package/dist/api/routes/prs.js +1633 -0
- package/dist/api/routes/reactions.js +217 -0
- package/dist/api/routes/repos.js +563 -0
- package/dist/api/routes/search.js +41 -0
- package/dist/api/routes/threads.js +118 -0
- package/dist/api/routes/timeline.js +150 -0
- package/dist/api/routes/users.js +67 -0
- package/dist/api/routes/webhooks.js +181 -0
- package/dist/api/routes/workspaces.js +322 -0
- package/dist/app.js +274 -0
- package/dist/ascii.js +19 -0
- package/dist/auth/account.js +482 -0
- package/dist/auth/crypto.js +46 -0
- package/dist/bot-triage/resolve.js +59 -0
- package/dist/cli.js +388 -0
- package/dist/coding/activity.js +80 -0
- package/dist/coding/agent.js +288 -0
- package/dist/coding/ai-fix/auto-fix.js +212 -0
- package/dist/coding/ai-fix/manager.js +370 -0
- package/dist/coding/ai-fix/persist.js +213 -0
- package/dist/coding/ai-fix/pr-context.js +58 -0
- package/dist/coding/ai-fix/prompts.js +138 -0
- package/dist/coding/ai-fix/review-seed.js +357 -0
- package/dist/coding/ai-fix/routes.js +425 -0
- package/dist/coding/git-ops.js +321 -0
- package/dist/coding/git.js +184 -0
- package/dist/coding/merge.js +262 -0
- package/dist/coding/safe-path.js +75 -0
- package/dist/coding/schema.js +43 -0
- package/dist/config.js +648 -0
- package/dist/conflict/diff.js +304 -0
- package/dist/conflict/git.js +118 -0
- package/dist/conflict/hash.js +73 -0
- package/dist/conflict/janitor.js +218 -0
- package/dist/conflict/land.js +675 -0
- package/dist/conflict/model-types.js +2 -0
- package/dist/conflict/model.js +1081 -0
- package/dist/conflict/parse.js +142 -0
- package/dist/conflict/seam.js +136 -0
- package/dist/conflict/session.js +532 -0
- package/dist/conflict/suggestion.js +398 -0
- package/dist/conflict/tokens.js +72 -0
- package/dist/data-dir.js +112 -0
- package/dist/db/actor-lanes.js +213 -0
- package/dist/db/automation-ids.js +97 -0
- package/dist/db/automation-output.js +349 -0
- package/dist/db/blast-radius-query.js +36 -0
- package/dist/db/blast-radius.js +226 -0
- package/dist/db/bot-dormancy.js +115 -0
- package/dist/db/bot-overlap.js +579 -0
- package/dist/db/bot-volume.js +722 -0
- package/dist/db/bot-window.js +35 -0
- package/dist/db/branch-queries.js +310 -0
- package/dist/db/change-shape.js +243 -0
- package/dist/db/changepoint.js +75 -0
- package/dist/db/cleanup.js +36 -0
- package/dist/db/client.js +102 -0
- package/dist/db/code-loc.js +388 -0
- package/dist/db/credits.js +79 -0
- package/dist/db/daily-brief.js +406 -0
- package/dist/db/dependency-cards.js +145 -0
- package/dist/db/erase-account.js +255 -0
- package/dist/db/export-account.js +189 -0
- package/dist/db/failing-checks.js +124 -0
- package/dist/db/file-coupling.js +197 -0
- package/dist/db/flow-detail.js +661 -0
- package/dist/db/flow-pointers.js +197 -0
- package/dist/db/flow-settings.js +67 -0
- package/dist/db/forecast.js +114 -0
- package/dist/db/line-overlap.js +81 -0
- package/dist/db/merge-queue.js +189 -0
- package/dist/db/migrate.js +17 -0
- package/dist/db/migrations/0000_purple_ben_grimm.sql +155 -0
- package/dist/db/migrations/0001_colorful_ozymandias.sql +31 -0
- package/dist/db/migrations/0002_famous_sersi.sql +9 -0
- package/dist/db/migrations/0003_clever_shinobi_shaw.sql +3 -0
- package/dist/db/migrations/0004_pale_scalphunter.sql +1 -0
- package/dist/db/migrations/0005_daffy_guardian.sql +2 -0
- package/dist/db/migrations/0006_cute_violations.sql +45 -0
- package/dist/db/migrations/0007_dark_anthem.sql +2 -0
- package/dist/db/migrations/0008_multitenant_accounts.sql +44 -0
- package/dist/db/migrations/0009_lean_bodies.sql +13 -0
- package/dist/db/migrations/0010_lean_bodies_nullable.sql +56 -0
- package/dist/db/migrations/0011_pr_diff_size.sql +10 -0
- package/dist/db/migrations/0012_findings_included_default.sql +7 -0
- package/dist/db/migrations/0013_review_routing.sql +9 -0
- package/dist/db/migrations/0014_account_last_active.sql +6 -0
- package/dist/db/migrations/0015_repos_inbox_watch.sql +9 -0
- package/dist/db/migrations/0016_repo_viewer_permission.sql +7 -0
- package/dist/db/migrations/0017_account_display_name.sql +7 -0
- package/dist/db/migrations/0018_finding_comment_kind.sql +7 -0
- package/dist/db/migrations/0019_finding_file_in_diff.sql +7 -0
- package/dist/db/migrations/0020_claude_review_cost_telemetry.sql +11 -0
- package/dist/db/migrations/0021_account_feed_last_seen.sql +7 -0
- package/dist/db/migrations/0022_ci_status_events.sql +21 -0
- package/dist/db/migrations/0023_ai_usage.sql +21 -0
- package/dist/db/migrations/0024_pr_head_ref_name.sql +6 -0
- package/dist/db/migrations/0025_account_billing.sql +7 -0
- package/dist/db/migrations/0026_ai_credit_allowance.sql +5 -0
- package/dist/db/migrations/0027_user_github_type.sql +6 -0
- package/dist/db/migrations/0028_bot_review_classification.sql +21 -0
- package/dist/db/migrations/0029_bot_mute_rules.sql +19 -0
- package/dist/db/migrations/0030_teams.sql +32 -0
- package/dist/db/migrations/0031_events_pr_idx.sql +7 -0
- package/dist/db/migrations/0032_benchmark_contributions.sql +29 -0
- package/dist/db/migrations/0033_thread_addressed_confidence.sql +9 -0
- package/dist/db/migrations/0034_thread_resolved_at.sql +6 -0
- package/dist/db/migrations/0035_pr_first_review_requested_at.sql +5 -0
- package/dist/db/migrations/0036_search_index.sql +25 -0
- package/dist/db/migrations/0037_author_indexes.sql +15 -0
- package/dist/db/migrations/0038_auto_merge_requests.sql +37 -0
- package/dist/db/migrations/0039_branch_status.sql +44 -0
- package/dist/db/migrations/0040_pr_review_decision.sql +10 -0
- package/dist/db/migrations/0041_branch_commit_detail.sql +38 -0
- package/dist/db/migrations/0042_repo_reviewers.sql +176 -0
- package/dist/db/migrations/0043_account_reviewers.sql +131 -0
- package/dist/db/migrations/0044_workspaces.sql +138 -0
- package/dist/db/migrations/0045_workspace_reviewers.sql +180 -0
- package/dist/db/migrations/0046_drop_inbox_watch.sql +25 -0
- package/dist/db/migrations/0047_ml_comment_labels.sql +40 -0
- package/dist/db/migrations/0048_ml_vendor_severity.sql +31 -0
- package/dist/db/migrations/0049_seat_pricing_repo_description.sql +21 -0
- package/dist/db/migrations/0050_users_app_slug.sql +12 -0
- package/dist/db/migrations/0051_auto_merge_queue.sql +17 -0
- package/dist/db/migrations/0052_trunk_ci_status_events.sql +43 -0
- package/dist/db/migrations/0053_automation_roles.sql +79 -0
- package/dist/db/migrations/0054_automation_vendor_kinds.sql +514 -0
- package/dist/db/migrations/0055_auto_merge_phase.sql +12 -0
- package/dist/db/migrations/0056_pr_mentions.sql +22 -0
- package/dist/db/migrations/0057_large_pr_threshold.sql +14 -0
- package/dist/db/migrations/0058_pending_mute.sql +53 -0
- package/dist/db/migrations/0059_merge_queue_state.sql +33 -0
- package/dist/db/migrations/0060_drop_my_turn_dismissals.sql +33 -0
- package/dist/db/migrations/0061_auto_merge_durable_anchors.sql +27 -0
- package/dist/db/migrations/0062_blast_radius_config.sql +21 -0
- package/dist/db/migrations/0063_repo_file_coupling.sql +33 -0
- package/dist/db/migrations/0064_pr_content_kind.sql +21 -0
- package/dist/db/migrations/0065_workspace_flow_settings.sql +13 -0
- package/dist/db/migrations/0066_review_request_events.sql +31 -0
- package/dist/db/migrations/0067_pr_security_signals.sql +86 -0
- package/dist/db/migrations/0068_my_turn_settings.sql +18 -0
- package/dist/db/migrations/0069_my_turn_dismissals.sql +41 -0
- package/dist/db/migrations/0070_claude_review_follow_up_ticket.sql +22 -0
- package/dist/db/migrations/0071_claude_review_trigger.sql +11 -0
- package/dist/db/migrations/0072_commit_message_headline.sql +13 -0
- package/dist/db/migrations/0073_claude_review_chat.sql +31 -0
- package/dist/db/migrations/0074_adopt_agentic_tables.sql +98 -0
- package/dist/db/migrations/0075_review_lens_drop_learnings.sql +15 -0
- package/dist/db/migrations/0076_claude_review_threads.sql +17 -0
- package/dist/db/migrations/0077_claude_review_ci_failures.sql +10 -0
- package/dist/db/migrations/0078_ai_fix_change_report.sql +17 -0
- package/dist/db/migrations/0079_claude_finding_story.sql +16 -0
- package/dist/db/migrations/meta/0000_snapshot.json +1116 -0
- package/dist/db/migrations/meta/0001_snapshot.json +1321 -0
- package/dist/db/migrations/meta/0002_snapshot.json +1375 -0
- package/dist/db/migrations/meta/0003_snapshot.json +1396 -0
- package/dist/db/migrations/meta/0004_snapshot.json +1416 -0
- package/dist/db/migrations/meta/0005_snapshot.json +1430 -0
- package/dist/db/migrations/meta/0006_snapshot.json +1745 -0
- package/dist/db/migrations/meta/0007_snapshot.json +1759 -0
- package/dist/db/migrations/meta/_journal.json +566 -0
- package/dist/db/migrations-pg/0000_tired_alex_power.sql +268 -0
- package/dist/db/migrations-pg/0001_dizzy_mockingbird.sql +3 -0
- package/dist/db/migrations-pg/0002_glorious_ikaris.sql +4 -0
- package/dist/db/migrations-pg/0003_melted_secret_warriors.sql +2 -0
- package/dist/db/migrations-pg/0004_numerous_triton.sql +1 -0
- package/dist/db/migrations-pg/0005_thick_blockbuster.sql +2 -0
- package/dist/db/migrations-pg/0006_majestic_dracula.sql +1 -0
- package/dist/db/migrations-pg/0007_same_human_torch.sql +2 -0
- package/dist/db/migrations-pg/0008_slimy_toxin.sql +1 -0
- package/dist/db/migrations-pg/0009_fuzzy_jubilee.sql +4 -0
- package/dist/db/migrations-pg/0010_late_hammerhead.sql +1 -0
- package/dist/db/migrations-pg/0011_happy_leech.sql +16 -0
- package/dist/db/migrations-pg/0012_woozy_captain_midlands.sql +16 -0
- package/dist/db/migrations-pg/0013_yielding_nicolaos.sql +1 -0
- package/dist/db/migrations-pg/0014_wakeful_bill_hollister.sql +2 -0
- package/dist/db/migrations-pg/0015_aspiring_black_tom.sql +1 -0
- package/dist/db/migrations-pg/0016_cute_ghost_rider.sql +30 -0
- package/dist/db/migrations-pg/0017_far_changeling.sql +24 -0
- package/dist/db/migrations-pg/0018_fancy_miss_america.sql +1 -0
- package/dist/db/migrations-pg/0019_benchmark_contributions.sql +22 -0
- package/dist/db/migrations-pg/0020_majestic_edwin_jarvis.sql +3 -0
- package/dist/db/migrations-pg/0021_green_salo.sql +1 -0
- package/dist/db/migrations-pg/0022_wise_baron_strucker.sql +1 -0
- package/dist/db/migrations-pg/0023_search_index.sql +19 -0
- package/dist/db/migrations-pg/0024_author_indexes.sql +9 -0
- package/dist/db/migrations-pg/0025_auto_merge_requests.sql +26 -0
- package/dist/db/migrations-pg/0026_branch_status.sql +32 -0
- package/dist/db/migrations-pg/0027_pr_review_decision.sql +5 -0
- package/dist/db/migrations-pg/0028_branch_commit_detail.sql +9 -0
- package/dist/db/migrations-pg/0029_repo_reviewers.sql +127 -0
- package/dist/db/migrations-pg/0030_account_reviewers.sql +77 -0
- package/dist/db/migrations-pg/0031_workspaces.sql +131 -0
- package/dist/db/migrations-pg/0032_workspace_reviewers.sql +165 -0
- package/dist/db/migrations-pg/0033_drop_inbox_watch.sql +14 -0
- package/dist/db/migrations-pg/0034_ml_comment_labels.sql +33 -0
- package/dist/db/migrations-pg/0035_ml_vendor_severity.sql +16 -0
- package/dist/db/migrations-pg/0036_seat_pricing_repo_description.sql +12 -0
- package/dist/db/migrations-pg/0037_users_app_slug.sql +9 -0
- package/dist/db/migrations-pg/0038_auto_merge_queue.sql +10 -0
- package/dist/db/migrations-pg/0039_trunk_ci_status_events.sql +27 -0
- package/dist/db/migrations-pg/0040_automation_roles.sql +63 -0
- package/dist/db/migrations-pg/0041_automation_vendor_kinds.sql +488 -0
- package/dist/db/migrations-pg/0042_auto_merge_phase.sql +8 -0
- package/dist/db/migrations-pg/0043_pr_mentions.sql +19 -0
- package/dist/db/migrations-pg/0044_large_pr_threshold.sql +6 -0
- package/dist/db/migrations-pg/0045_pending_mute.sql +26 -0
- package/dist/db/migrations-pg/0046_merge_queue_state.sql +18 -0
- package/dist/db/migrations-pg/0047_drop_my_turn_dismissals.sql +21 -0
- package/dist/db/migrations-pg/0048_auto_merge_durable_anchors.sql +27 -0
- package/dist/db/migrations-pg/0049_blast_radius_config.sql +8 -0
- package/dist/db/migrations-pg/0050_repo_file_coupling.sql +13 -0
- package/dist/db/migrations-pg/0051_pr_content_kind.sql +6 -0
- package/dist/db/migrations-pg/0052_workspace_flow_settings.sql +4 -0
- package/dist/db/migrations-pg/0053_review_request_events.sql +18 -0
- package/dist/db/migrations-pg/0054_pr_security_signals.sql +59 -0
- package/dist/db/migrations-pg/0055_my_turn_settings.sql +6 -0
- package/dist/db/migrations-pg/0056_my_turn_dismissals.sql +21 -0
- package/dist/db/migrations-pg/0057_claude_review_follow_up_ticket.sql +8 -0
- package/dist/db/migrations-pg/0058_claude_review_trigger.sql +4 -0
- package/dist/db/migrations-pg/0059_commit_message_headline.sql +3 -0
- package/dist/db/migrations-pg/0060_claude_review_chat.sql +24 -0
- package/dist/db/migrations-pg/0061_adopt_agentic_tables.sql +79 -0
- package/dist/db/migrations-pg/0062_review_lens_drop_learnings.sql +5 -0
- package/dist/db/migrations-pg/0063_claude_review_threads.sql +7 -0
- package/dist/db/migrations-pg/0064_claude_review_ci_failures.sql +4 -0
- package/dist/db/migrations-pg/0065_ai_fix_change_report.sql +9 -0
- package/dist/db/migrations-pg/0066_claude_finding_story.sql +7 -0
- package/dist/db/migrations-pg/meta/0000_snapshot.json +2137 -0
- package/dist/db/migrations-pg/meta/0001_snapshot.json +2143 -0
- package/dist/db/migrations-pg/meta/0002_snapshot.json +2170 -0
- package/dist/db/migrations-pg/meta/0003_snapshot.json +2182 -0
- package/dist/db/migrations-pg/meta/0004_snapshot.json +2188 -0
- package/dist/db/migrations-pg/meta/0005_snapshot.json +2201 -0
- package/dist/db/migrations-pg/meta/0006_snapshot.json +2207 -0
- package/dist/db/migrations-pg/meta/0007_snapshot.json +2219 -0
- package/dist/db/migrations-pg/meta/0008_snapshot.json +2226 -0
- package/dist/db/migrations-pg/meta/0009_snapshot.json +2250 -0
- package/dist/db/migrations-pg/meta/0010_snapshot.json +2256 -0
- package/dist/db/migrations-pg/meta/0011_snapshot.json +2412 -0
- package/dist/db/migrations-pg/meta/0012_snapshot.json +2528 -0
- package/dist/db/migrations-pg/meta/0013_snapshot.json +2534 -0
- package/dist/db/migrations-pg/meta/0014_snapshot.json +2547 -0
- package/dist/db/migrations-pg/meta/0015_snapshot.json +2553 -0
- package/dist/db/migrations-pg/meta/0016_snapshot.json +2774 -0
- package/dist/db/migrations-pg/meta/0017_snapshot.json +2999 -0
- package/dist/db/migrations-pg/meta/0018_snapshot.json +3020 -0
- package/dist/db/migrations-pg/meta/0020_snapshot.json +3228 -0
- package/dist/db/migrations-pg/meta/0021_snapshot.json +3234 -0
- package/dist/db/migrations-pg/meta/0022_snapshot.json +3240 -0
- package/dist/db/migrations-pg/meta/_journal.json +475 -0
- package/dist/db/ml-labels.js +1666 -0
- package/dist/db/my-turn-dismissals.js +343 -0
- package/dist/db/my-turn-settings.js +34 -0
- package/dist/db/pending-classify.js +46 -0
- package/dist/db/pending-mute.js +171 -0
- package/dist/db/pending-tabs.js +238 -0
- package/dist/db/period-metrics.js +820 -0
- package/dist/db/person-period.js +763 -0
- package/dist/db/pr-intervals.js +930 -0
- package/dist/db/pr-liveness.js +240 -0
- package/dist/db/pr-mentions.js +279 -0
- package/dist/db/pr-merge-queue-stamp.js +91 -0
- package/dist/db/queries.js +14631 -0
- package/dist/db/reaction-targets.js +94 -0
- package/dist/db/repo-activity.js +171 -0
- package/dist/db/retention.js +138 -0
- package/dist/db/review-threads-for-review.js +240 -0
- package/dist/db/run-migrations.js +24 -0
- package/dist/db/schema.pg.js +1220 -0
- package/dist/db/schema.sqlite.js +1801 -0
- package/dist/db/search.js +317 -0
- package/dist/db/security-alerts.js +218 -0
- package/dist/db/synthesis-input.js +565 -0
- package/dist/db/triage.js +320 -0
- package/dist/db/usage.js +63 -0
- package/dist/db/work-plan.js +1086 -0
- package/dist/db/working-hours.js +161 -0
- package/dist/feed/my-turn.js +122 -0
- package/dist/github/actions-logs.js +397 -0
- package/dist/github/auth.js +86 -0
- package/dist/github/branch-queries.js +229 -0
- package/dist/github/client.js +454 -0
- package/dist/github/codeowners.js +221 -0
- package/dist/github/commit-checks.js +105 -0
- package/dist/github/compare.js +110 -0
- package/dist/github/diff-anchor.js +227 -0
- package/dist/github/mutations.js +706 -0
- package/dist/github/pr-file-content.js +254 -0
- package/dist/github/pr-liveness.js +161 -0
- package/dist/github/queries.js +875 -0
- package/dist/github/rate-budget.js +129 -0
- package/dist/github/reactions.js +161 -0
- package/dist/github/reviewer-suggest.js +104 -0
- package/dist/github/team-reviewers.js +96 -0
- package/dist/index.js +184 -0
- package/dist/merge/auto-merge-runner.js +960 -0
- package/dist/ml/severity-client.js +218 -0
- package/dist/pr/detail-enricher.js +26 -0
- package/dist/pro/bind.js +302 -0
- package/dist/pro/contract.js +37 -0
- package/dist/pro/migrate.js +64 -0
- package/dist/review/agent-context.js +127 -0
- package/dist/review/agent.js +385 -0
- package/dist/review/agentic.js +59 -0
- package/dist/review/auth.js +94 -0
- package/dist/review/chat-agent.js +179 -0
- package/dist/review/claude-review/ai-ready.js +16 -0
- package/dist/review/claude-review/auto-settings.js +139 -0
- package/dist/review/claude-review/auto.js +244 -0
- package/dist/review/claude-review/chat.js +489 -0
- package/dist/review/claude-review/ci-failures.js +350 -0
- package/dist/review/claude-review/follow-up.js +310 -0
- package/dist/review/claude-review/manager.js +686 -0
- package/dist/review/claude-review/persist.js +996 -0
- package/dist/review/claude-review/prompts.js +357 -0
- package/dist/review/claude-review/routes.js +518 -0
- package/dist/review/claude-review/routing.js +61 -0
- package/dist/review/claude-review/specialists.js +190 -0
- package/dist/review/claude-review/threads.js +265 -0
- package/dist/review/claude-review/ticket.js +282 -0
- package/dist/review/clone-hygiene.js +380 -0
- package/dist/review/clone-manager.js +367 -0
- package/dist/review/llm.js +113 -0
- package/dist/review/model-options.js +48 -0
- package/dist/review/plugin-providers.js +12 -0
- package/dist/review/post-review.js +216 -0
- package/dist/review/post-seam.js +161 -0
- package/dist/review/prepare.js +168 -0
- package/dist/review/pricing.js +17 -0
- package/dist/review/schema.js +156 -0
- package/dist/review/submit-map.js +41 -0
- package/dist/review/usage.js +90 -0
- package/dist/shared/claude-review.js +335 -0
- package/dist/shared/conflict-fold.js +151 -0
- package/dist/shared/conflicts.js +30 -0
- package/dist/shared/flow-settings.js +191 -0
- package/dist/shared/index.js +8 -0
- package/dist/shared/my-turn-settings.js +238 -0
- package/dist/shared/pending-rules.js +281 -0
- package/dist/shared/product.js +54 -0
- package/dist/shared/types.js +896 -0
- package/dist/status.js +386 -0
- package/dist/sync/adaptive.js +185 -0
- package/dist/sync/app-attribution.js +66 -0
- package/dist/sync/auth-notices.js +36 -0
- package/dist/sync/backfill-ci-history.js +315 -0
- package/dist/sync/backfill-commit-headlines.js +136 -0
- package/dist/sync/backfill-pr-security.js +175 -0
- package/dist/sync/backfill-review-requests.js +97 -0
- package/dist/sync/benchmark-rollup.js +50 -0
- package/dist/sync/bot-detection.js +309 -0
- package/dist/sync/bot-resolution-markers.js +30 -0
- package/dist/sync/branch-status.js +634 -0
- package/dist/sync/classify-change-shape.js +150 -0
- package/dist/sync/commit-files.js +74 -0
- package/dist/sync/derive-thread-state.js +99 -0
- package/dist/sync/drain-review-threads.js +212 -0
- package/dist/sync/hydrate-detail.js +482 -0
- package/dist/sync/mention-scan.js +89 -0
- package/dist/sync/ml-enrichment.js +478 -0
- package/dist/sync/pr-change-signal.js +96 -0
- package/dist/sync/pr-liveness-sweep.js +139 -0
- package/dist/sync/pr-settle.js +381 -0
- package/dist/sync/refresh-pr.js +163 -0
- package/dist/sync/reparse-vendor-badges.js +495 -0
- package/dist/sync/resync-after-write.js +280 -0
- package/dist/sync/review-fingerprint.js +117 -0
- package/dist/sync/reviewer-behavior.js +103 -0
- package/dist/sync/reviewer-classify.js +503 -0
- package/dist/sync/routing-files.js +97 -0
- package/dist/sync/scheduled-jobs.js +12 -0
- package/dist/sync/scheduler.js +159 -0
- package/dist/sync/security-detect.js +521 -0
- package/dist/sync/sync-manager.js +750 -0
- package/dist/sync/sync-one-pr.js +205 -0
- package/dist/sync/sync-repo.js +400 -0
- package/dist/sync/unsettled-prs.js +506 -0
- package/dist/sync/upsert.js +1190 -0
- package/package.json +56 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/assets/AiFixTab-CQP6PT5u.js +2 -0
- package/public/assets/ClaudeReviewTab-DQJ-58ZA.js +8 -0
- package/public/assets/PrBotBehaviourTab-CCnFrWbC.js +1 -0
- package/public/assets/archivo-latin-600-BN-JkNrl.woff2 +0 -0
- package/public/assets/highlight-BEHUn5zE.css +10 -0
- package/public/assets/highlight-CIIZLa6Z.js +12 -0
- package/public/assets/index-BDnYs6zg.js +73 -0
- package/public/assets/index-mCuI--RC.css +1 -0
- package/public/assets/markdown-I_JLLVAZ.js +32 -0
- package/public/assets/perfProbe-Da13EhTE.js +1 -0
- package/public/assets/tanstack-5qsxxaLe.js +17 -0
- package/public/assets/vis-C3BCkP5U.js +1280 -0
- package/public/assets/vis-ziCVehMy.css +1 -0
- package/public/favicon-16.png +0 -0
- package/public/favicon-32.png +0 -0
- package/public/favicon-48.png +0 -0
- package/public/favicon.svg +5 -0
- package/public/index.html +41 -0
- package/public-landing/apple-touch-icon.png +0 -0
- package/public-landing/assets/archivo-latin-500-BWmvx2Mg.woff2 +0 -0
- package/public-landing/assets/archivo-latin-600-BN-JkNrl.woff2 +0 -0
- package/public-landing/assets/index-CA3eEGXO.js +40 -0
- package/public-landing/assets/index-naQrQ6Fe.css +1 -0
- package/public-landing/assets/jetbrains-mono-latin-400-RruCX7RW.woff2 +0 -0
- package/public-landing/assets/newsreader-latin-400-DExrRRrN.woff2 +0 -0
- package/public-landing/assets/newsreader-latin-400-italic-b0I-AwbV.woff2 +0 -0
- package/public-landing/bots/index.html +156 -0
- package/public-landing/contact/index.html +156 -0
- package/public-landing/cookies/index.html +156 -0
- package/public-landing/demo/limn-walkthrough-poster.jpg +0 -0
- package/public-landing/demo/limn-walkthrough.cues.json +44 -0
- package/public-landing/demo/limn-walkthrough.mp4 +0 -0
- package/public-landing/favicon-16.png +0 -0
- package/public-landing/favicon-32.png +0 -0
- package/public-landing/favicon-48.png +0 -0
- package/public-landing/favicon.svg +5 -0
- package/public-landing/features/index.html +156 -0
- package/public-landing/for-developers/index.html +156 -0
- package/public-landing/for-managers/index.html +156 -0
- package/public-landing/how-it-works/index.html +156 -0
- package/public-landing/how-we-measure/index.html +156 -0
- package/public-landing/icon-192.png +0 -0
- package/public-landing/icon-512.png +0 -0
- package/public-landing/index.html +156 -0
- package/public-landing/insights/index.html +156 -0
- package/public-landing/og-image.png +0 -0
- package/public-landing/pricing/index.html +156 -0
- package/public-landing/privacy/index.html +156 -0
- package/public-landing/pro/index.html +156 -0
- package/public-landing/reviews/index.html +156 -0
- package/public-landing/robots.txt +8 -0
- package/public-landing/shots/benchmark.png +0 -0
- package/public-landing/shots/bot-roi.png +0 -0
- package/public-landing/shots/bot-settings.png +0 -0
- package/public-landing/shots/chronology.png +0 -0
- package/public-landing/shots/feed.png +0 -0
- package/public-landing/shots/flow-metrics.png +0 -0
- package/public-landing/shots/free-reports.png +0 -0
- package/public-landing/shots/pending-board.png +0 -0
- package/public-landing/shots/pending-card.png +0 -0
- package/public-landing/shots/period-report.png +0 -0
- package/public-landing/shots/pr-detail.png +0 -0
- package/public-landing/shots/pr-threads.png +0 -0
- package/public-landing/shots/reach.png +0 -0
- package/public-landing/shots/repo-rows.png +0 -0
- package/public-landing/shots/severity-findings.png +0 -0
- package/public-landing/shots/severity-strip.png +0 -0
- package/public-landing/site.webmanifest +14 -0
- package/public-landing/sitemap.xml +51 -0
- package/public-landing/terms/index.html +156 -0
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
import { AI_FIX_MAX_INSTRUCTION_CHARS, CLAUDE_REVIEW_MODELS, DEFAULT_AI_FIX_MODEL, PRODUCT_NAME, } from '../../shared/index.js';
|
|
2
|
+
import { config } from '../../config.js';
|
|
3
|
+
import { getFixPrContext, getViewerCanPush } from './pr-context.js';
|
|
4
|
+
import { getFixStatus, requestFixCancel, startFix, subscribeFixStream, } from './manager.js';
|
|
5
|
+
import { getFixById, getLatestFix, listFixHistory, markFixPushed, parseChangeReport, parseFilesChanged, parseReviewItems, parseTrigger, } from './persist.js';
|
|
6
|
+
// AI Fix's agentic-fixer routes (CORE, free, LOCAL ONLY — the fixer left the plugin with Claude
|
|
7
|
+
// Review). ⚠ THE PATHS KEEP THEIR HISTORICAL `/api/pro/` PREFIX (`/api/pro/prs/:id/ai-fix*`,
|
|
8
|
+
// `/api/pro/ai-fixes/:fixId*`) so the SPA client did not move; nothing about them is paid. They
|
|
9
|
+
// are registered only by `registerAgenticRoutes` (review/agentic.ts), which refuses in cloud and
|
|
10
|
+
// under LIMN_AI_DISABLED — and in cloud the auth plugin's `isProPath` 402 is a second guard on the
|
|
11
|
+
// prefix anyway. The PR summary (`/api/pro/prs/:id/summary*`) is Pro and STAYED in the plugin.
|
|
12
|
+
// Every handler resolves accountId =
|
|
13
|
+
// ctx.accountIdOf(req) and verifies PR ownership.
|
|
14
|
+
const AIFIX_ENABLED = config.aiEnabled;
|
|
15
|
+
function tsToIso(v) {
|
|
16
|
+
if (v == null)
|
|
17
|
+
return null;
|
|
18
|
+
const d = v instanceof Date ? v : new Date(Number(v));
|
|
19
|
+
return d.toISOString();
|
|
20
|
+
}
|
|
21
|
+
// The model a fix run uses. Validated HERE, in the handler, and not by an ajv body schema:
|
|
22
|
+
// Fastify's ajv runs with `removeAdditional`, so a schema that did not declare every key would
|
|
23
|
+
// silently strip `seed` / `instruction` / `sourceReviewId` (the contact-form honeypot landmine).
|
|
24
|
+
// The body has no schema at all, so `model` may be any JSON value — hence the `typeof`.
|
|
25
|
+
// absent / null → DEFAULT_AI_FIX_MODEL
|
|
26
|
+
// a string on the offered list → that model
|
|
27
|
+
// anything else (a retired id such as the old Opus, a typo, a number) → null ⇒ 400
|
|
28
|
+
function resolveFixModel(raw) {
|
|
29
|
+
if (raw == null)
|
|
30
|
+
return DEFAULT_AI_FIX_MODEL;
|
|
31
|
+
if (typeof raw !== 'string')
|
|
32
|
+
return null;
|
|
33
|
+
return CLAUDE_REVIEW_MODELS.includes(raw)
|
|
34
|
+
? raw
|
|
35
|
+
: null;
|
|
36
|
+
}
|
|
37
|
+
function rowToAiFix(row) {
|
|
38
|
+
return {
|
|
39
|
+
id: row.id,
|
|
40
|
+
prId: row.prId,
|
|
41
|
+
status: row.status,
|
|
42
|
+
model: row.model,
|
|
43
|
+
seed: row.seed,
|
|
44
|
+
summary: row.summary,
|
|
45
|
+
commitMessage: row.commitMessage,
|
|
46
|
+
patch: row.patch,
|
|
47
|
+
filesChanged: parseFilesChanged(row.filesChanged),
|
|
48
|
+
baseSha: row.baseSha,
|
|
49
|
+
// Null on an unparseable blob too: this getter loads the whole AI Fix tab and must not throw.
|
|
50
|
+
// A row from a REMOVED seed ('comments' / 'ci_analysis') reads like any other, as history.
|
|
51
|
+
trigger: parseTrigger(row.trigger),
|
|
52
|
+
reviewItems: parseReviewItems(row.reviewItems),
|
|
53
|
+
changeReport: parseChangeReport(row.changeReport),
|
|
54
|
+
sourceReviewId: row.sourceReviewId,
|
|
55
|
+
costUsd: row.costUsd,
|
|
56
|
+
numTurns: row.numTurns,
|
|
57
|
+
error: row.error,
|
|
58
|
+
pushedBranch: row.pushedBranch,
|
|
59
|
+
pushedPrNumber: row.pushedPrNumber,
|
|
60
|
+
pushedPrUrl: row.pushedPrUrl,
|
|
61
|
+
pushedAt: tsToIso(row.pushedAt),
|
|
62
|
+
createdAt: tsToIso(row.createdAt) ?? new Date(0).toISOString(),
|
|
63
|
+
finishedAt: tsToIso(row.finishedAt),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function rowToSummary(row) {
|
|
67
|
+
return {
|
|
68
|
+
id: row.id,
|
|
69
|
+
status: row.status,
|
|
70
|
+
model: row.model,
|
|
71
|
+
seed: row.seed,
|
|
72
|
+
commitMessage: row.commitMessage,
|
|
73
|
+
filesChanged: parseFilesChanged(row.filesChanged),
|
|
74
|
+
pushedBranch: row.pushedBranch,
|
|
75
|
+
pushedPrNumber: row.pushedPrNumber,
|
|
76
|
+
pushedPrUrl: row.pushedPrUrl,
|
|
77
|
+
pushedAt: tsToIso(row.pushedAt),
|
|
78
|
+
createdAt: tsToIso(row.createdAt) ?? new Date(0).toISOString(),
|
|
79
|
+
finishedAt: tsToIso(row.finishedAt),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
// A safe git branch name derived from the PR's head ref.
|
|
83
|
+
function suggestBranch(headRef) {
|
|
84
|
+
const base = headRef.replace(/[^A-Za-z0-9._/-]/g, '-').replace(/^-+|-+$/g, '');
|
|
85
|
+
return `${base || 'pr'}-ai-fix`;
|
|
86
|
+
}
|
|
87
|
+
export function registerAiFixRoutes(app, ctx) {
|
|
88
|
+
const parseId = (raw) => {
|
|
89
|
+
const n = Number.parseInt(raw, 10);
|
|
90
|
+
return Number.isInteger(n) ? n : null;
|
|
91
|
+
};
|
|
92
|
+
// ---- The agentic fixer (aiFix) ----
|
|
93
|
+
// GET latest fix + history + auth + write access + live head/fork info.
|
|
94
|
+
app.get('/api/pro/prs/:id/ai-fix', async (req, reply) => {
|
|
95
|
+
const accountId = ctx.accountIdOf(req);
|
|
96
|
+
const prId = parseId(req.params.id);
|
|
97
|
+
if (prId == null)
|
|
98
|
+
return reply.code(404).send({ error: 'not found' });
|
|
99
|
+
const pr = await getFixPrContext(ctx, accountId, prId);
|
|
100
|
+
if (!pr)
|
|
101
|
+
return reply.code(404).send({ error: 'not found' });
|
|
102
|
+
if (!AIFIX_ENABLED) {
|
|
103
|
+
const resp = {
|
|
104
|
+
enabled: false,
|
|
105
|
+
auth: 'none',
|
|
106
|
+
viewerCanPush: false,
|
|
107
|
+
headInfo: null,
|
|
108
|
+
fix: null,
|
|
109
|
+
history: [],
|
|
110
|
+
};
|
|
111
|
+
return reply.send(resp);
|
|
112
|
+
}
|
|
113
|
+
const auth = ctx.llm.detectAuth();
|
|
114
|
+
const viewerCanPush = await getViewerCanPush(ctx, accountId, pr.repoId);
|
|
115
|
+
const latest = await getLatestFix(ctx, accountId, prId);
|
|
116
|
+
const history = await listFixHistory(ctx, accountId, prId);
|
|
117
|
+
let headInfo = null;
|
|
118
|
+
try {
|
|
119
|
+
const h = await ctx.github.fetchPrHeadInfo(accountId, pr.owner, pr.name, pr.number);
|
|
120
|
+
headInfo = {
|
|
121
|
+
...h,
|
|
122
|
+
canPushSameBranch: viewerCanPush && (!h.isFork || h.maintainerCanModify),
|
|
123
|
+
suggestedBranch: suggestBranch(h.headRef),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
headInfo = null;
|
|
128
|
+
}
|
|
129
|
+
const resp = {
|
|
130
|
+
enabled: true,
|
|
131
|
+
auth: auth.status,
|
|
132
|
+
authMessage: auth.status === 'none' ? auth.message : undefined,
|
|
133
|
+
viewerCanPush,
|
|
134
|
+
headInfo,
|
|
135
|
+
fix: latest ? rowToAiFix(latest) : null,
|
|
136
|
+
history: history.map(rowToSummary),
|
|
137
|
+
};
|
|
138
|
+
return reply.send(resp);
|
|
139
|
+
});
|
|
140
|
+
// Start a fix run.
|
|
141
|
+
app.post('/api/pro/prs/:id/ai-fix', async (req, reply) => {
|
|
142
|
+
const accountId = ctx.accountIdOf(req);
|
|
143
|
+
const prId = parseId(req.params.id);
|
|
144
|
+
if (prId == null)
|
|
145
|
+
return reply.code(404).send({ error: 'not found' });
|
|
146
|
+
if (!AIFIX_ENABLED)
|
|
147
|
+
return reply.code(404).send({ error: 'AiFixDisabled' });
|
|
148
|
+
const body = req.body ?? {};
|
|
149
|
+
const model = resolveFixModel(body.model);
|
|
150
|
+
if (model == null) {
|
|
151
|
+
return reply.code(400).send({
|
|
152
|
+
error: 'ModelNotOffered',
|
|
153
|
+
message: 'That model is no longer offered.',
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
// Two entry points. The removed ones get a sentence a stale tab can show, not a run.
|
|
157
|
+
const rawSeed = body.seed ?? 'plain';
|
|
158
|
+
if (rawSeed === 'comments' || rawSeed === 'ci_analysis') {
|
|
159
|
+
return reply.code(400).send({
|
|
160
|
+
error: 'SeedRemoved',
|
|
161
|
+
message: 'That kind of fix is no longer offered. Reload the page.',
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
if (rawSeed !== 'review' && rawSeed !== 'plain') {
|
|
165
|
+
return reply.code(400).send({ error: 'UnknownSeed', message: 'Unknown fix type.' });
|
|
166
|
+
}
|
|
167
|
+
const seed = rawSeed;
|
|
168
|
+
let instruction;
|
|
169
|
+
let sourceReviewId = null;
|
|
170
|
+
if (seed === 'plain') {
|
|
171
|
+
const raw = body.instruction;
|
|
172
|
+
instruction = typeof raw === 'string' ? raw.trim() : '';
|
|
173
|
+
if (instruction === '') {
|
|
174
|
+
return reply.code(400).send({
|
|
175
|
+
error: 'InstructionRequired',
|
|
176
|
+
message: 'Say what to fix.',
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
if (instruction.length > AI_FIX_MAX_INSTRUCTION_CHARS) {
|
|
180
|
+
return reply.code(400).send({
|
|
181
|
+
error: 'InstructionTooLong',
|
|
182
|
+
message: `Keep the instruction under ${AI_FIX_MAX_INSTRUCTION_CHARS.toLocaleString('en-US')} characters.`,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
const raw = body.sourceReviewId;
|
|
188
|
+
if (typeof raw !== 'number' || !Number.isInteger(raw) || raw <= 0) {
|
|
189
|
+
return reply.code(400).send({
|
|
190
|
+
error: 'ReviewRequired',
|
|
191
|
+
message: 'Pick a Claude review to fix from.',
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
sourceReviewId = raw;
|
|
195
|
+
}
|
|
196
|
+
const res = await startFix(ctx, {
|
|
197
|
+
accountId,
|
|
198
|
+
prId,
|
|
199
|
+
model,
|
|
200
|
+
seed,
|
|
201
|
+
instruction,
|
|
202
|
+
// The SERVER builds the review seed from the stored run (manager.ts `loadReviewSeed`,
|
|
203
|
+
// which also checks it is THIS PR's succeeded review). No review text travels in the body.
|
|
204
|
+
sourceReviewId,
|
|
205
|
+
trigger: 'manual',
|
|
206
|
+
});
|
|
207
|
+
switch (res.status) {
|
|
208
|
+
case 'queued':
|
|
209
|
+
return reply.code(202).send({ fixId: res.fixId, status: 'queued' });
|
|
210
|
+
case 'already_running':
|
|
211
|
+
return reply.code(409).send({ error: 'AlreadyRunning' });
|
|
212
|
+
case 'busy':
|
|
213
|
+
return reply.code(409).send({ error: 'Busy' });
|
|
214
|
+
case 'no_auth':
|
|
215
|
+
return reply
|
|
216
|
+
.code(400)
|
|
217
|
+
.send({ error: 'NoClaudeAuth', message: res.message });
|
|
218
|
+
case 'credits_exhausted':
|
|
219
|
+
return reply.code(402).send({
|
|
220
|
+
error: 'CreditsExhausted',
|
|
221
|
+
message: 'Out of monthly agentic AI credits — resets on the 1st.',
|
|
222
|
+
});
|
|
223
|
+
case 'no_head':
|
|
224
|
+
return reply.code(400).send({ error: 'NoHead' });
|
|
225
|
+
case 'no_instruction':
|
|
226
|
+
return reply.code(400).send({ error: 'InstructionRequired', message: 'Say what to fix.' });
|
|
227
|
+
case 'review_unavailable':
|
|
228
|
+
return reply.code(409).send({
|
|
229
|
+
error: 'ReviewUnavailable',
|
|
230
|
+
message: 'That review is not available. Run a Claude review on this PR first.',
|
|
231
|
+
});
|
|
232
|
+
case 'nothing_to_fix':
|
|
233
|
+
return reply.code(409).send({
|
|
234
|
+
error: 'NothingToFix',
|
|
235
|
+
message: 'The review found nothing to fix.',
|
|
236
|
+
});
|
|
237
|
+
default:
|
|
238
|
+
return reply.code(404).send({ error: 'not found' });
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
// Poll status.
|
|
242
|
+
app.get('/api/pro/prs/:id/ai-fix/status', async (req, reply) => {
|
|
243
|
+
const accountId = ctx.accountIdOf(req);
|
|
244
|
+
const prId = parseId(req.params.id);
|
|
245
|
+
if (prId == null)
|
|
246
|
+
return reply.code(404).send({ error: 'not found' });
|
|
247
|
+
const status = await getFixStatus(ctx, accountId, prId);
|
|
248
|
+
return reply.send(status);
|
|
249
|
+
});
|
|
250
|
+
// SSE progress stream.
|
|
251
|
+
app.get('/api/pro/prs/:id/ai-fix/stream', async (req, reply) => {
|
|
252
|
+
const accountId = ctx.accountIdOf(req);
|
|
253
|
+
const prId = parseId(req.params.id);
|
|
254
|
+
if (prId == null)
|
|
255
|
+
return reply.code(404).send({ error: 'not found' });
|
|
256
|
+
// Ownership BEFORE hijack (can't 404 cleanly after).
|
|
257
|
+
const pr = await getFixPrContext(ctx, accountId, prId);
|
|
258
|
+
if (!pr)
|
|
259
|
+
return reply.code(404).send({ error: 'not found' });
|
|
260
|
+
reply.hijack();
|
|
261
|
+
const raw = reply.raw;
|
|
262
|
+
raw.writeHead(200, {
|
|
263
|
+
'Content-Type': 'text/event-stream',
|
|
264
|
+
'Cache-Control': 'no-cache, no-transform',
|
|
265
|
+
Connection: 'keep-alive',
|
|
266
|
+
'X-Accel-Buffering': 'no',
|
|
267
|
+
});
|
|
268
|
+
const send = (e) => {
|
|
269
|
+
if (!raw.writableEnded)
|
|
270
|
+
raw.write(`data: ${JSON.stringify(e)}\n\n`);
|
|
271
|
+
};
|
|
272
|
+
let closed = false;
|
|
273
|
+
const hb = setInterval(() => {
|
|
274
|
+
if (!raw.writableEnded)
|
|
275
|
+
raw.write(': hb\n\n');
|
|
276
|
+
}, 15000);
|
|
277
|
+
const cleanup = () => {
|
|
278
|
+
if (closed)
|
|
279
|
+
return;
|
|
280
|
+
closed = true;
|
|
281
|
+
clearInterval(hb);
|
|
282
|
+
unsub();
|
|
283
|
+
if (!raw.writableEnded)
|
|
284
|
+
raw.end();
|
|
285
|
+
};
|
|
286
|
+
// Subscribe BEFORE the snapshot so a terminal 'done' can't slip through the gap.
|
|
287
|
+
const unsub = subscribeFixStream(prId, (e) => {
|
|
288
|
+
send(e);
|
|
289
|
+
if (e.type === 'done')
|
|
290
|
+
cleanup();
|
|
291
|
+
});
|
|
292
|
+
req.raw.on('close', cleanup);
|
|
293
|
+
const snap = await getFixStatus(ctx, accountId, prId);
|
|
294
|
+
send({
|
|
295
|
+
type: 'snapshot',
|
|
296
|
+
status: snap.status,
|
|
297
|
+
fixId: snap.fixId,
|
|
298
|
+
progress: snap.progress,
|
|
299
|
+
});
|
|
300
|
+
if (snap.status !== 'running' && snap.status !== 'queued') {
|
|
301
|
+
send({ type: 'done', status: snap.status, fixId: snap.fixId });
|
|
302
|
+
cleanup();
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
// Cancel a running/queued fix.
|
|
306
|
+
app.post('/api/pro/prs/:id/ai-fix/cancel', async (req, reply) => {
|
|
307
|
+
const accountId = ctx.accountIdOf(req);
|
|
308
|
+
const prId = parseId(req.params.id);
|
|
309
|
+
if (prId == null)
|
|
310
|
+
return reply.code(404).send({ error: 'not found' });
|
|
311
|
+
// Ownership.
|
|
312
|
+
const pr = await getFixPrContext(ctx, accountId, prId);
|
|
313
|
+
if (!pr)
|
|
314
|
+
return reply.code(404).send({ error: 'not found' });
|
|
315
|
+
const cancelled = requestFixCancel(ctx, prId);
|
|
316
|
+
return reply.send({ status: cancelled ? 'cancelling' : 'idle' });
|
|
317
|
+
});
|
|
318
|
+
// Get a specific fix (scoped).
|
|
319
|
+
app.get('/api/pro/ai-fixes/:fixId', async (req, reply) => {
|
|
320
|
+
const accountId = ctx.accountIdOf(req);
|
|
321
|
+
const fixId = parseId(req.params.fixId);
|
|
322
|
+
if (fixId == null)
|
|
323
|
+
return reply.code(404).send({ error: 'not found' });
|
|
324
|
+
const row = await getFixById(ctx, accountId, fixId);
|
|
325
|
+
if (!row)
|
|
326
|
+
return reply.code(404).send({ error: 'not found' });
|
|
327
|
+
const pr = await getFixPrContext(ctx, accountId, row.prId);
|
|
328
|
+
if (!pr)
|
|
329
|
+
return reply.code(404).send({ error: 'not found' });
|
|
330
|
+
return reply.send(rowToAiFix(row));
|
|
331
|
+
});
|
|
332
|
+
// Push a completed fix, as-is. Synchronous, never force-pushes: onto the PR's own head branch
|
|
333
|
+
// (refused with HeadMoved if that branch moved since the fix was generated) or onto a NEW
|
|
334
|
+
// branch with a PR opened against the base. There is no trunk step before it — the rebase /
|
|
335
|
+
// merge / "let Claude resolve conflicts" paths and the on-mount trunk check were removed, and
|
|
336
|
+
// a fix that conflicts with the trunk pushes as it is and shows as conflicted on GitHub.
|
|
337
|
+
app.post('/api/pro/ai-fixes/:fixId/push', async (req, reply) => {
|
|
338
|
+
const accountId = ctx.accountIdOf(req);
|
|
339
|
+
const fixId = parseId(req.params.fixId);
|
|
340
|
+
if (fixId == null)
|
|
341
|
+
return reply.code(404).send({ error: 'not found' });
|
|
342
|
+
if (!AIFIX_ENABLED)
|
|
343
|
+
return reply.code(404).send({ error: 'AiFixDisabled' });
|
|
344
|
+
const body = req.body ?? { target: 'new' };
|
|
345
|
+
// A tab still running the OLD bundle sends `strategy: 'merge' | 'rebase'` from buttons that
|
|
346
|
+
// no longer exist. Refuse it loudly instead of quietly doing a plain push the reader did not
|
|
347
|
+
// click. `strategy: 'plain'` (the old bundle's Push button) and no strategy both push as-is;
|
|
348
|
+
// an old `autoResolve` / `model` is ignored.
|
|
349
|
+
const strategy = body.strategy;
|
|
350
|
+
if (strategy != null && strategy !== 'plain') {
|
|
351
|
+
return reply.code(400).send({
|
|
352
|
+
error: 'UnsupportedStrategy',
|
|
353
|
+
message: 'Reload the page to push this fix.',
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
const row = await getFixById(ctx, accountId, fixId);
|
|
357
|
+
if (!row)
|
|
358
|
+
return reply.code(404).send({ error: 'not found' });
|
|
359
|
+
if (row.status !== 'succeeded' || !row.patch || !row.baseSha)
|
|
360
|
+
return reply.code(409).send({ error: 'NotPushable' });
|
|
361
|
+
const pr = await getFixPrContext(ctx, accountId, row.prId);
|
|
362
|
+
if (!pr)
|
|
363
|
+
return reply.code(404).send({ error: 'not found' });
|
|
364
|
+
const viewerCanPush = await getViewerCanPush(ctx, accountId, pr.repoId);
|
|
365
|
+
if (!viewerCanPush)
|
|
366
|
+
return reply.code(403).send({ error: 'NoWriteAccess' });
|
|
367
|
+
const commitMessage = row.commitMessage ?? 'AI fix';
|
|
368
|
+
// Build the push target (the PR's head branch, or a new branch + PR).
|
|
369
|
+
let target;
|
|
370
|
+
if (body.target === 'existing') {
|
|
371
|
+
const head = await ctx.github
|
|
372
|
+
.fetchPrHeadInfo(accountId, pr.owner, pr.name, pr.number)
|
|
373
|
+
.catch(() => null);
|
|
374
|
+
if (!head)
|
|
375
|
+
return reply.code(400).send({ error: 'HeadUnavailable' });
|
|
376
|
+
target = { kind: 'existing', headRef: head.headRef };
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
const branch = (body.branch ?? '').trim();
|
|
380
|
+
if (!branch)
|
|
381
|
+
return reply.code(400).send({ error: 'BranchRequired' });
|
|
382
|
+
// This body lands on GitHub, where it is read by people who have never seen this app —
|
|
383
|
+
// so it names the PRODUCT, not the npm package. Nothing detects on this string (the
|
|
384
|
+
// provenance marker is `review/post-seam.ts`'s hidden comment, on reviews, not PRs).
|
|
385
|
+
const prBody = `${row.summary ?? ''}\n\n---\nAutomated fix for #${pr.number}, generated by ${PRODUCT_NAME} AI Fix.`;
|
|
386
|
+
target = {
|
|
387
|
+
kind: 'new',
|
|
388
|
+
branch,
|
|
389
|
+
base: pr.baseRefName ?? pr.defaultBranch ?? 'main',
|
|
390
|
+
title: commitMessage,
|
|
391
|
+
body: prBody,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
try {
|
|
395
|
+
const result = await ctx.coding.applyAndPush({
|
|
396
|
+
accountId,
|
|
397
|
+
owner: pr.owner,
|
|
398
|
+
name: pr.name,
|
|
399
|
+
prNumber: pr.number,
|
|
400
|
+
baseSha: row.baseSha,
|
|
401
|
+
patch: row.patch,
|
|
402
|
+
commitMessage,
|
|
403
|
+
target,
|
|
404
|
+
});
|
|
405
|
+
await markFixPushed(ctx, fixId, {
|
|
406
|
+
pushedBranch: result.pushedBranch,
|
|
407
|
+
pushedPrNumber: result.prNumber,
|
|
408
|
+
pushedPrUrl: result.prUrl,
|
|
409
|
+
});
|
|
410
|
+
const resp = result;
|
|
411
|
+
return reply.send(resp);
|
|
412
|
+
}
|
|
413
|
+
catch (err) {
|
|
414
|
+
const code = err?.code;
|
|
415
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
416
|
+
if (code === 'HEAD_MOVED')
|
|
417
|
+
return reply.code(409).send({ error: 'HeadMoved', message });
|
|
418
|
+
if (code === 'PUSH_DENIED' || code === 'APPLY_FAILED')
|
|
419
|
+
return reply.code(422).send({ error: code, message });
|
|
420
|
+
ctx.log.warn({ err }, 'ai-fix push failed');
|
|
421
|
+
return reply.code(500).send({ error: 'PushFailed', message });
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
//# sourceMappingURL=routes.js.map
|