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,169 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { config } from '../../config.js';
|
|
3
|
+
import { getAccountById, getLocalAccountCached, stampAccountActive, LOCAL_ACCOUNT_ID, } from '../../auth/account.js';
|
|
4
|
+
// Attaches `request.account` to every request. Registered once on the root app
|
|
5
|
+
// (so it covers all routes, including static/health which simply ignore it).
|
|
6
|
+
//
|
|
7
|
+
// Local mode: always the synthesized local account (id 1).
|
|
8
|
+
// Cloud mode: resolved from the sealed session cookie (set up in registerCloudAuth,
|
|
9
|
+
// Phase 1). Unauthenticated requests get `null`; the requireAuth preHandler
|
|
10
|
+
// then 401s the data routes.
|
|
11
|
+
export function registerAccountContext(app) {
|
|
12
|
+
app.decorateRequest('account', null);
|
|
13
|
+
app.addHook('onRequest', async (req) => {
|
|
14
|
+
if (config.isCloud) {
|
|
15
|
+
const accountId = readSessionAccountId(req);
|
|
16
|
+
req.account = accountId != null ? await getAccountById(accountId) : null;
|
|
17
|
+
// A request from a signed-in account on a real data route means that tenant
|
|
18
|
+
// has a loaded frontend — stamp activity (throttled) so the scheduler keeps
|
|
19
|
+
// syncing their repos. Skips static/landing assets and the health/auth probes.
|
|
20
|
+
if (req.account && req.url.startsWith('/api/')) {
|
|
21
|
+
stampAccountActive(req.account.id);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
req.account =
|
|
26
|
+
getLocalAccountCached() ?? {
|
|
27
|
+
id: LOCAL_ACCOUNT_ID,
|
|
28
|
+
githubUserId: '',
|
|
29
|
+
githubLogin: '',
|
|
30
|
+
displayName: null,
|
|
31
|
+
avatarUrl: null,
|
|
32
|
+
isLocal: true,
|
|
33
|
+
plan: 'free',
|
|
34
|
+
stripeCustomerId: null,
|
|
35
|
+
aiCreditAllowance: null,
|
|
36
|
+
benchmarkOptIn: false,
|
|
37
|
+
largePrCodeLocThreshold: null,
|
|
38
|
+
blastRadiusConfig: null,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
// Reads {accountId} from the sealed session cookie. @fastify/secure-session is
|
|
44
|
+
// only registered in cloud mode (Phase 1); guarded so this is safe pre-registration.
|
|
45
|
+
function readSessionAccountId(req) {
|
|
46
|
+
const session = req
|
|
47
|
+
.session;
|
|
48
|
+
if (!session)
|
|
49
|
+
return null;
|
|
50
|
+
const raw = session.get('accountId');
|
|
51
|
+
return typeof raw === 'number' ? raw : null;
|
|
52
|
+
}
|
|
53
|
+
// Cloud only: register the cookie + sealed-session plugins. MUST run before
|
|
54
|
+
// registerAccountContext so the session cookie is parsed by the time the
|
|
55
|
+
// account-context onRequest hook reads it. The session key is derived from
|
|
56
|
+
// SESSION_SECRET (sha256 → 32 bytes, the size secure-session needs).
|
|
57
|
+
export async function registerSession(app) {
|
|
58
|
+
const cookie = await import('@fastify/cookie');
|
|
59
|
+
const secureSession = await import('@fastify/secure-session');
|
|
60
|
+
await app.register(cookie.default, { secret: config.sessionSecret });
|
|
61
|
+
const key = createHash('sha256').update(config.sessionSecret).digest();
|
|
62
|
+
await app.register(secureSession.default, {
|
|
63
|
+
key,
|
|
64
|
+
cookieName: 'pierre_session',
|
|
65
|
+
cookie: {
|
|
66
|
+
path: '/',
|
|
67
|
+
httpOnly: true,
|
|
68
|
+
sameSite: 'lax',
|
|
69
|
+
secure: config.appBaseUrl.startsWith('https://'),
|
|
70
|
+
maxAge: 30 * 24 * 60 * 60, // 30 days
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
// Cloud only: 401 any unauthenticated /api data route. Skips /api/health,
|
|
75
|
+
// /api/auth/* (sign-in itself), /api/billing/webhook (Stripe posts
|
|
76
|
+
// unauthenticated — verified by signature instead), /api/contact* (the public
|
|
77
|
+
// contact form, whose visitors have no account by definition) and all non-/api requests
|
|
78
|
+
// (the SPA + landing are served openly; the frontend gate handles the signed-out
|
|
79
|
+
// UI). MUST be registered AFTER registerAccountContext so req.account is already
|
|
80
|
+
// resolved. Also the cloud-only ENTITLEMENT gate: an authenticated free-plan
|
|
81
|
+
// account gets 402 on the Pro plugin's /api/pro/* routes (local accounts are
|
|
82
|
+
// always entitled — isLocal never reaches the cloud gate anyway).
|
|
83
|
+
export function registerAuthGate(app) {
|
|
84
|
+
app.addHook('onRequest', async (req, reply) => {
|
|
85
|
+
const path = req.url.split('?')[0] ?? req.url;
|
|
86
|
+
if (!path.startsWith('/api/'))
|
|
87
|
+
return;
|
|
88
|
+
if (path === '/api/health')
|
|
89
|
+
return;
|
|
90
|
+
if (path.startsWith('/api/auth/'))
|
|
91
|
+
return;
|
|
92
|
+
if (path === '/api/billing/webhook')
|
|
93
|
+
return;
|
|
94
|
+
// GitHub App webhook: GitHub posts unauthenticated — authenticity is the
|
|
95
|
+
// X-Hub-Signature-256 HMAC, verified in the route (see api/routes/webhooks.ts).
|
|
96
|
+
if (path === '/api/webhooks/github')
|
|
97
|
+
return;
|
|
98
|
+
// The pricing page's "Get Pro" is a plain browser navigation from the public
|
|
99
|
+
// landing; the route itself bounces anonymous visitors to sign-in instead of
|
|
100
|
+
// dead-ending them on a JSON 401.
|
|
101
|
+
if (path === '/api/billing/checkout')
|
|
102
|
+
return;
|
|
103
|
+
// The public contact form. It exists FOR people who are not signed in — someone
|
|
104
|
+
// asking for a Pro trial does not have an account yet, and someone reporting that
|
|
105
|
+
// sign-in is broken cannot sign in to say so. Spam control is the honeypot, the
|
|
106
|
+
// signed fill-time ticket and the IP-keyed `contact` rate-limit tier, all in
|
|
107
|
+
// api/routes/contact.ts; authentication was never the control here.
|
|
108
|
+
if (path === '/api/contact' || path === '/api/contact/ticket')
|
|
109
|
+
return;
|
|
110
|
+
if (!req.account) {
|
|
111
|
+
await reply.code(401).send({
|
|
112
|
+
error: 'Unauthorized',
|
|
113
|
+
message: 'Sign in with GitHub to continue.',
|
|
114
|
+
});
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (isProPath(path) && !req.account.isLocal && req.account.plan === 'free') {
|
|
118
|
+
await reply.code(402).send({ error: 'pro required' });
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
// Which paths the free-plan 402 gate covers.
|
|
123
|
+
//
|
|
124
|
+
// `/api/pro/*` is the convention, but it is NOT the whole surface: Claude Review has always kept
|
|
125
|
+
// its pre-plugin URLs — `/api/prs/:id/claude-review*`, `/api/claude-reviews/*`,
|
|
126
|
+
// `/api/claude-findings/*`, `/api/claude-review/*` — and AI Fix's fixer kept its
|
|
127
|
+
// `/api/pro/prs/:id/ai-fix*` / `/api/pro/ai-fixes/*` paths when both moved to core.
|
|
128
|
+
//
|
|
129
|
+
// ⚠ THIS IS NOW THE SECOND GUARD, NOT THE FIRST. Claude Review, review memory and AI Fix are core,
|
|
130
|
+
// free and LOCAL ONLY: `registerAgenticRoutes` (review/agentic.ts) registers none of them in cloud
|
|
131
|
+
// — an explicit `isCloud` check — so in cloud they 404 before this matters. The entries stay so a
|
|
132
|
+
// future change that registers one in cloud does not hand it to every free account by default.
|
|
133
|
+
// Enumerated explicitly so adding a route outside /api/pro/ is a visible decision.
|
|
134
|
+
function isProPath(path) {
|
|
135
|
+
if (path.startsWith('/api/pro/'))
|
|
136
|
+
return true;
|
|
137
|
+
if (path.startsWith('/api/claude-reviews'))
|
|
138
|
+
return true;
|
|
139
|
+
if (path.startsWith('/api/claude-findings/'))
|
|
140
|
+
return true;
|
|
141
|
+
if (path.startsWith('/api/claude-review/'))
|
|
142
|
+
return true;
|
|
143
|
+
// /api/prs/<id>/claude-review, …/status, …/stream, …/cancel
|
|
144
|
+
if (/^\/api\/prs\/\d+\/claude-review/.test(path))
|
|
145
|
+
return true;
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
// preHandler that rejects unauthenticated requests in cloud mode. A no-op in
|
|
149
|
+
// local mode (the account is always present). Kept for any route that wants an
|
|
150
|
+
// explicit per-route guard in addition to the global gate above.
|
|
151
|
+
export async function requireAuth(req, reply) {
|
|
152
|
+
if (!config.isCloud)
|
|
153
|
+
return;
|
|
154
|
+
if (!req.account) {
|
|
155
|
+
await reply
|
|
156
|
+
.code(401)
|
|
157
|
+
.send({ error: 'Unauthorized', message: 'Sign in with GitHub to continue.' });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// The request's account id, for scoping queries. Always present in local mode;
|
|
161
|
+
// in cloud mode requireAuth has already guaranteed it on data routes.
|
|
162
|
+
export function accountIdOf(req) {
|
|
163
|
+
if (req.account)
|
|
164
|
+
return req.account.id;
|
|
165
|
+
if (!config.isCloud)
|
|
166
|
+
return LOCAL_ACCOUNT_ID;
|
|
167
|
+
throw new Error('no account on request (requireAuth missing?)');
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { config } from '../../config.js';
|
|
4
|
+
/**
|
|
5
|
+
* The landing routes that shipped as prerendered HTML, discovered once at boot.
|
|
6
|
+
*
|
|
7
|
+
* The marketing site is built to `<route>/index.html` per route (apps/landing/
|
|
8
|
+
* prerender.mjs) so that a crawler, an AI agent or a no-JS visitor receives real
|
|
9
|
+
* content instead of an empty SPA shell. @fastify/static — registered with
|
|
10
|
+
* `wildcard: false` — already answers `/pricing/` from its directory-index scan,
|
|
11
|
+
* but NOT `/pricing`, which is the canonical, link-shaped form. Those land here.
|
|
12
|
+
*
|
|
13
|
+
* Resolved into a fixed Set at startup rather than stat-ing per request: it costs
|
|
14
|
+
* one readdir instead of a filesystem hit on every 404, and — the reason that
|
|
15
|
+
* matters — a URL can only ever select an entry that was found on disk at boot,
|
|
16
|
+
* so no request-supplied path is ever joined onto a filesystem root. Traversal
|
|
17
|
+
* is not defended against here; it is unrepresentable.
|
|
18
|
+
*/
|
|
19
|
+
function prerenderedRoutes(landingDir) {
|
|
20
|
+
const routes = new Set();
|
|
21
|
+
if (!existsSync(landingDir))
|
|
22
|
+
return routes;
|
|
23
|
+
for (const entry of readdirSync(landingDir, { withFileTypes: true })) {
|
|
24
|
+
if (!entry.isDirectory())
|
|
25
|
+
continue;
|
|
26
|
+
if (existsSync(join(landingDir, entry.name, 'index.html'))) {
|
|
27
|
+
routes.add(`/${entry.name}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return routes;
|
|
31
|
+
}
|
|
32
|
+
// Centralised error handling + the single not-found handler (Fastify allows one
|
|
33
|
+
// per context). The not-found handler doubles as the SPA/landing router:
|
|
34
|
+
// /api/* unknown → JSON 404 (both modes)
|
|
35
|
+
// /app, /app/* (GET) → the timeline SPA index (client routing / reload)
|
|
36
|
+
// /, other non-/api (GET) → cloud: the landing page; local: 302 → /app
|
|
37
|
+
export function registerErrorHandler(app, opts) {
|
|
38
|
+
const landingRoutes = opts.serveLanding
|
|
39
|
+
? prerenderedRoutes(opts.publicLandingDir)
|
|
40
|
+
: new Set();
|
|
41
|
+
app.setErrorHandler((err, req, reply) => {
|
|
42
|
+
if (err.validation) {
|
|
43
|
+
reply.status(400).send({
|
|
44
|
+
error: 'ValidationError',
|
|
45
|
+
message: err.message,
|
|
46
|
+
details: err.validation,
|
|
47
|
+
});
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const status = err.statusCode ?? 500;
|
|
51
|
+
if (status >= 500) {
|
|
52
|
+
req.log.error({ err }, 'request failed');
|
|
53
|
+
}
|
|
54
|
+
// 5xx bodies are GENERIC. A 500 is an unhandled throw, so `err.message` is whatever the
|
|
55
|
+
// failing layer happened to say — and the layers under these routes talk to Postgres,
|
|
56
|
+
// SQLite, the GitHub GraphQL/REST APIs, Stripe and Anthropic. Their error text routinely
|
|
57
|
+
// carries query fragments and column names, absolute filesystem paths, connection
|
|
58
|
+
// strings, and upstream response bodies. None of that helps a caller (there is nothing
|
|
59
|
+
// they can do about it) and all of it helps an attacker map the internals, so it goes to
|
|
60
|
+
// the log — which the operator can read, and which redacts credentials — and not to the
|
|
61
|
+
// wire. 4xx messages are deliberate, author-written text (validation detail, "PR not
|
|
62
|
+
// found", "already running") and stay as-is, because they are the API's contract.
|
|
63
|
+
//
|
|
64
|
+
// In local mode the operator IS the caller, so the real message is passed through: there
|
|
65
|
+
// is no attacker to withhold it from, and a developer debugging their own instance should
|
|
66
|
+
// not have to go and read the terminal.
|
|
67
|
+
const expose = status < 500 || !config.isCloud;
|
|
68
|
+
reply.status(status).send({
|
|
69
|
+
error: expose ? err.name || 'Error' : 'InternalServerError',
|
|
70
|
+
message: expose
|
|
71
|
+
? err.message
|
|
72
|
+
: 'Something went wrong on our end. The error has been logged.',
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
app.setNotFoundHandler((req, reply) => {
|
|
76
|
+
const path = req.url.split('?')[0] ?? req.url;
|
|
77
|
+
// Unknown API routes always return a JSON 404 (never an HTML page).
|
|
78
|
+
if (path.startsWith('/api')) {
|
|
79
|
+
return reply.status(404).send({
|
|
80
|
+
error: 'NotFound',
|
|
81
|
+
message: `Route ${req.method} ${req.url} not found`,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
if (req.method === 'GET') {
|
|
85
|
+
// The SPA lives under /app — serve its index for any unmatched /app path so
|
|
86
|
+
// deep-links and reloads work.
|
|
87
|
+
if (opts.serveSpa && (path === '/app' || path.startsWith('/app/'))) {
|
|
88
|
+
return reply.sendFile('index.html', opts.publicDir);
|
|
89
|
+
}
|
|
90
|
+
// Root + other non-/api paths: cloud serves the public landing page; local
|
|
91
|
+
// sends the user straight into the app (never shows a landing).
|
|
92
|
+
if (opts.serveLanding) {
|
|
93
|
+
// Prefer the route's own prerendered file, so /pricing answers with the
|
|
94
|
+
// pricing copy and its own <title>/canonical rather than the generic shell
|
|
95
|
+
// (which only becomes the pricing page once JavaScript runs). Trailing
|
|
96
|
+
// slash tolerated; '/' and anything unknown fall back to the shell, which
|
|
97
|
+
// still client-routes correctly for a browser.
|
|
98
|
+
const clean = path.length > 1 ? path.replace(/\/+$/, '') : path;
|
|
99
|
+
if (landingRoutes.has(clean)) {
|
|
100
|
+
return reply.sendFile(`${clean.slice(1)}/index.html`, opts.publicLandingDir);
|
|
101
|
+
}
|
|
102
|
+
return reply.sendFile('index.html', opts.publicLandingDir);
|
|
103
|
+
}
|
|
104
|
+
if (opts.serveSpa) {
|
|
105
|
+
return reply.redirect('/app/');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return reply.status(404).send({
|
|
109
|
+
error: 'NotFound',
|
|
110
|
+
message: `Route ${req.method} ${req.url} not found`,
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=error-handler.js.map
|