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.
Files changed (474) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +133 -0
  3. package/dist/ai/runtime.js +535 -0
  4. package/dist/api/plugins/auth.js +169 -0
  5. package/dist/api/plugins/error-handler.js +114 -0
  6. package/dist/api/plugins/rate-limit.js +855 -0
  7. package/dist/api/plugins/security.js +321 -0
  8. package/dist/api/routes/activity.js +103 -0
  9. package/dist/api/routes/ai-runtime.js +67 -0
  10. package/dist/api/routes/auth.js +194 -0
  11. package/dist/api/routes/billing.js +209 -0
  12. package/dist/api/routes/bot-triage.js +1289 -0
  13. package/dist/api/routes/conflicts.js +730 -0
  14. package/dist/api/routes/contact.js +318 -0
  15. package/dist/api/routes/daily-brief.js +58 -0
  16. package/dist/api/routes/flow.js +71 -0
  17. package/dist/api/routes/health.js +7 -0
  18. package/dist/api/routes/insights.js +200 -0
  19. package/dist/api/routes/me.js +458 -0
  20. package/dist/api/routes/mentions.js +22 -0
  21. package/dist/api/routes/mergers.js +8 -0
  22. package/dist/api/routes/ml-labels.js +109 -0
  23. package/dist/api/routes/open-prs.js +35 -0
  24. package/dist/api/routes/prs.js +1633 -0
  25. package/dist/api/routes/reactions.js +217 -0
  26. package/dist/api/routes/repos.js +563 -0
  27. package/dist/api/routes/search.js +41 -0
  28. package/dist/api/routes/threads.js +118 -0
  29. package/dist/api/routes/timeline.js +150 -0
  30. package/dist/api/routes/users.js +67 -0
  31. package/dist/api/routes/webhooks.js +181 -0
  32. package/dist/api/routes/workspaces.js +322 -0
  33. package/dist/app.js +274 -0
  34. package/dist/ascii.js +19 -0
  35. package/dist/auth/account.js +482 -0
  36. package/dist/auth/crypto.js +46 -0
  37. package/dist/bot-triage/resolve.js +59 -0
  38. package/dist/cli.js +388 -0
  39. package/dist/coding/activity.js +80 -0
  40. package/dist/coding/agent.js +288 -0
  41. package/dist/coding/ai-fix/auto-fix.js +212 -0
  42. package/dist/coding/ai-fix/manager.js +370 -0
  43. package/dist/coding/ai-fix/persist.js +213 -0
  44. package/dist/coding/ai-fix/pr-context.js +58 -0
  45. package/dist/coding/ai-fix/prompts.js +138 -0
  46. package/dist/coding/ai-fix/review-seed.js +357 -0
  47. package/dist/coding/ai-fix/routes.js +425 -0
  48. package/dist/coding/git-ops.js +321 -0
  49. package/dist/coding/git.js +184 -0
  50. package/dist/coding/merge.js +262 -0
  51. package/dist/coding/safe-path.js +75 -0
  52. package/dist/coding/schema.js +43 -0
  53. package/dist/config.js +648 -0
  54. package/dist/conflict/diff.js +304 -0
  55. package/dist/conflict/git.js +118 -0
  56. package/dist/conflict/hash.js +73 -0
  57. package/dist/conflict/janitor.js +218 -0
  58. package/dist/conflict/land.js +675 -0
  59. package/dist/conflict/model-types.js +2 -0
  60. package/dist/conflict/model.js +1081 -0
  61. package/dist/conflict/parse.js +142 -0
  62. package/dist/conflict/seam.js +136 -0
  63. package/dist/conflict/session.js +532 -0
  64. package/dist/conflict/suggestion.js +398 -0
  65. package/dist/conflict/tokens.js +72 -0
  66. package/dist/data-dir.js +112 -0
  67. package/dist/db/actor-lanes.js +213 -0
  68. package/dist/db/automation-ids.js +97 -0
  69. package/dist/db/automation-output.js +349 -0
  70. package/dist/db/blast-radius-query.js +36 -0
  71. package/dist/db/blast-radius.js +226 -0
  72. package/dist/db/bot-dormancy.js +115 -0
  73. package/dist/db/bot-overlap.js +579 -0
  74. package/dist/db/bot-volume.js +722 -0
  75. package/dist/db/bot-window.js +35 -0
  76. package/dist/db/branch-queries.js +310 -0
  77. package/dist/db/change-shape.js +243 -0
  78. package/dist/db/changepoint.js +75 -0
  79. package/dist/db/cleanup.js +36 -0
  80. package/dist/db/client.js +102 -0
  81. package/dist/db/code-loc.js +388 -0
  82. package/dist/db/credits.js +79 -0
  83. package/dist/db/daily-brief.js +406 -0
  84. package/dist/db/dependency-cards.js +145 -0
  85. package/dist/db/erase-account.js +255 -0
  86. package/dist/db/export-account.js +189 -0
  87. package/dist/db/failing-checks.js +124 -0
  88. package/dist/db/file-coupling.js +197 -0
  89. package/dist/db/flow-detail.js +661 -0
  90. package/dist/db/flow-pointers.js +197 -0
  91. package/dist/db/flow-settings.js +67 -0
  92. package/dist/db/forecast.js +114 -0
  93. package/dist/db/line-overlap.js +81 -0
  94. package/dist/db/merge-queue.js +189 -0
  95. package/dist/db/migrate.js +17 -0
  96. package/dist/db/migrations/0000_purple_ben_grimm.sql +155 -0
  97. package/dist/db/migrations/0001_colorful_ozymandias.sql +31 -0
  98. package/dist/db/migrations/0002_famous_sersi.sql +9 -0
  99. package/dist/db/migrations/0003_clever_shinobi_shaw.sql +3 -0
  100. package/dist/db/migrations/0004_pale_scalphunter.sql +1 -0
  101. package/dist/db/migrations/0005_daffy_guardian.sql +2 -0
  102. package/dist/db/migrations/0006_cute_violations.sql +45 -0
  103. package/dist/db/migrations/0007_dark_anthem.sql +2 -0
  104. package/dist/db/migrations/0008_multitenant_accounts.sql +44 -0
  105. package/dist/db/migrations/0009_lean_bodies.sql +13 -0
  106. package/dist/db/migrations/0010_lean_bodies_nullable.sql +56 -0
  107. package/dist/db/migrations/0011_pr_diff_size.sql +10 -0
  108. package/dist/db/migrations/0012_findings_included_default.sql +7 -0
  109. package/dist/db/migrations/0013_review_routing.sql +9 -0
  110. package/dist/db/migrations/0014_account_last_active.sql +6 -0
  111. package/dist/db/migrations/0015_repos_inbox_watch.sql +9 -0
  112. package/dist/db/migrations/0016_repo_viewer_permission.sql +7 -0
  113. package/dist/db/migrations/0017_account_display_name.sql +7 -0
  114. package/dist/db/migrations/0018_finding_comment_kind.sql +7 -0
  115. package/dist/db/migrations/0019_finding_file_in_diff.sql +7 -0
  116. package/dist/db/migrations/0020_claude_review_cost_telemetry.sql +11 -0
  117. package/dist/db/migrations/0021_account_feed_last_seen.sql +7 -0
  118. package/dist/db/migrations/0022_ci_status_events.sql +21 -0
  119. package/dist/db/migrations/0023_ai_usage.sql +21 -0
  120. package/dist/db/migrations/0024_pr_head_ref_name.sql +6 -0
  121. package/dist/db/migrations/0025_account_billing.sql +7 -0
  122. package/dist/db/migrations/0026_ai_credit_allowance.sql +5 -0
  123. package/dist/db/migrations/0027_user_github_type.sql +6 -0
  124. package/dist/db/migrations/0028_bot_review_classification.sql +21 -0
  125. package/dist/db/migrations/0029_bot_mute_rules.sql +19 -0
  126. package/dist/db/migrations/0030_teams.sql +32 -0
  127. package/dist/db/migrations/0031_events_pr_idx.sql +7 -0
  128. package/dist/db/migrations/0032_benchmark_contributions.sql +29 -0
  129. package/dist/db/migrations/0033_thread_addressed_confidence.sql +9 -0
  130. package/dist/db/migrations/0034_thread_resolved_at.sql +6 -0
  131. package/dist/db/migrations/0035_pr_first_review_requested_at.sql +5 -0
  132. package/dist/db/migrations/0036_search_index.sql +25 -0
  133. package/dist/db/migrations/0037_author_indexes.sql +15 -0
  134. package/dist/db/migrations/0038_auto_merge_requests.sql +37 -0
  135. package/dist/db/migrations/0039_branch_status.sql +44 -0
  136. package/dist/db/migrations/0040_pr_review_decision.sql +10 -0
  137. package/dist/db/migrations/0041_branch_commit_detail.sql +38 -0
  138. package/dist/db/migrations/0042_repo_reviewers.sql +176 -0
  139. package/dist/db/migrations/0043_account_reviewers.sql +131 -0
  140. package/dist/db/migrations/0044_workspaces.sql +138 -0
  141. package/dist/db/migrations/0045_workspace_reviewers.sql +180 -0
  142. package/dist/db/migrations/0046_drop_inbox_watch.sql +25 -0
  143. package/dist/db/migrations/0047_ml_comment_labels.sql +40 -0
  144. package/dist/db/migrations/0048_ml_vendor_severity.sql +31 -0
  145. package/dist/db/migrations/0049_seat_pricing_repo_description.sql +21 -0
  146. package/dist/db/migrations/0050_users_app_slug.sql +12 -0
  147. package/dist/db/migrations/0051_auto_merge_queue.sql +17 -0
  148. package/dist/db/migrations/0052_trunk_ci_status_events.sql +43 -0
  149. package/dist/db/migrations/0053_automation_roles.sql +79 -0
  150. package/dist/db/migrations/0054_automation_vendor_kinds.sql +514 -0
  151. package/dist/db/migrations/0055_auto_merge_phase.sql +12 -0
  152. package/dist/db/migrations/0056_pr_mentions.sql +22 -0
  153. package/dist/db/migrations/0057_large_pr_threshold.sql +14 -0
  154. package/dist/db/migrations/0058_pending_mute.sql +53 -0
  155. package/dist/db/migrations/0059_merge_queue_state.sql +33 -0
  156. package/dist/db/migrations/0060_drop_my_turn_dismissals.sql +33 -0
  157. package/dist/db/migrations/0061_auto_merge_durable_anchors.sql +27 -0
  158. package/dist/db/migrations/0062_blast_radius_config.sql +21 -0
  159. package/dist/db/migrations/0063_repo_file_coupling.sql +33 -0
  160. package/dist/db/migrations/0064_pr_content_kind.sql +21 -0
  161. package/dist/db/migrations/0065_workspace_flow_settings.sql +13 -0
  162. package/dist/db/migrations/0066_review_request_events.sql +31 -0
  163. package/dist/db/migrations/0067_pr_security_signals.sql +86 -0
  164. package/dist/db/migrations/0068_my_turn_settings.sql +18 -0
  165. package/dist/db/migrations/0069_my_turn_dismissals.sql +41 -0
  166. package/dist/db/migrations/0070_claude_review_follow_up_ticket.sql +22 -0
  167. package/dist/db/migrations/0071_claude_review_trigger.sql +11 -0
  168. package/dist/db/migrations/0072_commit_message_headline.sql +13 -0
  169. package/dist/db/migrations/0073_claude_review_chat.sql +31 -0
  170. package/dist/db/migrations/0074_adopt_agentic_tables.sql +98 -0
  171. package/dist/db/migrations/0075_review_lens_drop_learnings.sql +15 -0
  172. package/dist/db/migrations/0076_claude_review_threads.sql +17 -0
  173. package/dist/db/migrations/0077_claude_review_ci_failures.sql +10 -0
  174. package/dist/db/migrations/0078_ai_fix_change_report.sql +17 -0
  175. package/dist/db/migrations/0079_claude_finding_story.sql +16 -0
  176. package/dist/db/migrations/meta/0000_snapshot.json +1116 -0
  177. package/dist/db/migrations/meta/0001_snapshot.json +1321 -0
  178. package/dist/db/migrations/meta/0002_snapshot.json +1375 -0
  179. package/dist/db/migrations/meta/0003_snapshot.json +1396 -0
  180. package/dist/db/migrations/meta/0004_snapshot.json +1416 -0
  181. package/dist/db/migrations/meta/0005_snapshot.json +1430 -0
  182. package/dist/db/migrations/meta/0006_snapshot.json +1745 -0
  183. package/dist/db/migrations/meta/0007_snapshot.json +1759 -0
  184. package/dist/db/migrations/meta/_journal.json +566 -0
  185. package/dist/db/migrations-pg/0000_tired_alex_power.sql +268 -0
  186. package/dist/db/migrations-pg/0001_dizzy_mockingbird.sql +3 -0
  187. package/dist/db/migrations-pg/0002_glorious_ikaris.sql +4 -0
  188. package/dist/db/migrations-pg/0003_melted_secret_warriors.sql +2 -0
  189. package/dist/db/migrations-pg/0004_numerous_triton.sql +1 -0
  190. package/dist/db/migrations-pg/0005_thick_blockbuster.sql +2 -0
  191. package/dist/db/migrations-pg/0006_majestic_dracula.sql +1 -0
  192. package/dist/db/migrations-pg/0007_same_human_torch.sql +2 -0
  193. package/dist/db/migrations-pg/0008_slimy_toxin.sql +1 -0
  194. package/dist/db/migrations-pg/0009_fuzzy_jubilee.sql +4 -0
  195. package/dist/db/migrations-pg/0010_late_hammerhead.sql +1 -0
  196. package/dist/db/migrations-pg/0011_happy_leech.sql +16 -0
  197. package/dist/db/migrations-pg/0012_woozy_captain_midlands.sql +16 -0
  198. package/dist/db/migrations-pg/0013_yielding_nicolaos.sql +1 -0
  199. package/dist/db/migrations-pg/0014_wakeful_bill_hollister.sql +2 -0
  200. package/dist/db/migrations-pg/0015_aspiring_black_tom.sql +1 -0
  201. package/dist/db/migrations-pg/0016_cute_ghost_rider.sql +30 -0
  202. package/dist/db/migrations-pg/0017_far_changeling.sql +24 -0
  203. package/dist/db/migrations-pg/0018_fancy_miss_america.sql +1 -0
  204. package/dist/db/migrations-pg/0019_benchmark_contributions.sql +22 -0
  205. package/dist/db/migrations-pg/0020_majestic_edwin_jarvis.sql +3 -0
  206. package/dist/db/migrations-pg/0021_green_salo.sql +1 -0
  207. package/dist/db/migrations-pg/0022_wise_baron_strucker.sql +1 -0
  208. package/dist/db/migrations-pg/0023_search_index.sql +19 -0
  209. package/dist/db/migrations-pg/0024_author_indexes.sql +9 -0
  210. package/dist/db/migrations-pg/0025_auto_merge_requests.sql +26 -0
  211. package/dist/db/migrations-pg/0026_branch_status.sql +32 -0
  212. package/dist/db/migrations-pg/0027_pr_review_decision.sql +5 -0
  213. package/dist/db/migrations-pg/0028_branch_commit_detail.sql +9 -0
  214. package/dist/db/migrations-pg/0029_repo_reviewers.sql +127 -0
  215. package/dist/db/migrations-pg/0030_account_reviewers.sql +77 -0
  216. package/dist/db/migrations-pg/0031_workspaces.sql +131 -0
  217. package/dist/db/migrations-pg/0032_workspace_reviewers.sql +165 -0
  218. package/dist/db/migrations-pg/0033_drop_inbox_watch.sql +14 -0
  219. package/dist/db/migrations-pg/0034_ml_comment_labels.sql +33 -0
  220. package/dist/db/migrations-pg/0035_ml_vendor_severity.sql +16 -0
  221. package/dist/db/migrations-pg/0036_seat_pricing_repo_description.sql +12 -0
  222. package/dist/db/migrations-pg/0037_users_app_slug.sql +9 -0
  223. package/dist/db/migrations-pg/0038_auto_merge_queue.sql +10 -0
  224. package/dist/db/migrations-pg/0039_trunk_ci_status_events.sql +27 -0
  225. package/dist/db/migrations-pg/0040_automation_roles.sql +63 -0
  226. package/dist/db/migrations-pg/0041_automation_vendor_kinds.sql +488 -0
  227. package/dist/db/migrations-pg/0042_auto_merge_phase.sql +8 -0
  228. package/dist/db/migrations-pg/0043_pr_mentions.sql +19 -0
  229. package/dist/db/migrations-pg/0044_large_pr_threshold.sql +6 -0
  230. package/dist/db/migrations-pg/0045_pending_mute.sql +26 -0
  231. package/dist/db/migrations-pg/0046_merge_queue_state.sql +18 -0
  232. package/dist/db/migrations-pg/0047_drop_my_turn_dismissals.sql +21 -0
  233. package/dist/db/migrations-pg/0048_auto_merge_durable_anchors.sql +27 -0
  234. package/dist/db/migrations-pg/0049_blast_radius_config.sql +8 -0
  235. package/dist/db/migrations-pg/0050_repo_file_coupling.sql +13 -0
  236. package/dist/db/migrations-pg/0051_pr_content_kind.sql +6 -0
  237. package/dist/db/migrations-pg/0052_workspace_flow_settings.sql +4 -0
  238. package/dist/db/migrations-pg/0053_review_request_events.sql +18 -0
  239. package/dist/db/migrations-pg/0054_pr_security_signals.sql +59 -0
  240. package/dist/db/migrations-pg/0055_my_turn_settings.sql +6 -0
  241. package/dist/db/migrations-pg/0056_my_turn_dismissals.sql +21 -0
  242. package/dist/db/migrations-pg/0057_claude_review_follow_up_ticket.sql +8 -0
  243. package/dist/db/migrations-pg/0058_claude_review_trigger.sql +4 -0
  244. package/dist/db/migrations-pg/0059_commit_message_headline.sql +3 -0
  245. package/dist/db/migrations-pg/0060_claude_review_chat.sql +24 -0
  246. package/dist/db/migrations-pg/0061_adopt_agentic_tables.sql +79 -0
  247. package/dist/db/migrations-pg/0062_review_lens_drop_learnings.sql +5 -0
  248. package/dist/db/migrations-pg/0063_claude_review_threads.sql +7 -0
  249. package/dist/db/migrations-pg/0064_claude_review_ci_failures.sql +4 -0
  250. package/dist/db/migrations-pg/0065_ai_fix_change_report.sql +9 -0
  251. package/dist/db/migrations-pg/0066_claude_finding_story.sql +7 -0
  252. package/dist/db/migrations-pg/meta/0000_snapshot.json +2137 -0
  253. package/dist/db/migrations-pg/meta/0001_snapshot.json +2143 -0
  254. package/dist/db/migrations-pg/meta/0002_snapshot.json +2170 -0
  255. package/dist/db/migrations-pg/meta/0003_snapshot.json +2182 -0
  256. package/dist/db/migrations-pg/meta/0004_snapshot.json +2188 -0
  257. package/dist/db/migrations-pg/meta/0005_snapshot.json +2201 -0
  258. package/dist/db/migrations-pg/meta/0006_snapshot.json +2207 -0
  259. package/dist/db/migrations-pg/meta/0007_snapshot.json +2219 -0
  260. package/dist/db/migrations-pg/meta/0008_snapshot.json +2226 -0
  261. package/dist/db/migrations-pg/meta/0009_snapshot.json +2250 -0
  262. package/dist/db/migrations-pg/meta/0010_snapshot.json +2256 -0
  263. package/dist/db/migrations-pg/meta/0011_snapshot.json +2412 -0
  264. package/dist/db/migrations-pg/meta/0012_snapshot.json +2528 -0
  265. package/dist/db/migrations-pg/meta/0013_snapshot.json +2534 -0
  266. package/dist/db/migrations-pg/meta/0014_snapshot.json +2547 -0
  267. package/dist/db/migrations-pg/meta/0015_snapshot.json +2553 -0
  268. package/dist/db/migrations-pg/meta/0016_snapshot.json +2774 -0
  269. package/dist/db/migrations-pg/meta/0017_snapshot.json +2999 -0
  270. package/dist/db/migrations-pg/meta/0018_snapshot.json +3020 -0
  271. package/dist/db/migrations-pg/meta/0020_snapshot.json +3228 -0
  272. package/dist/db/migrations-pg/meta/0021_snapshot.json +3234 -0
  273. package/dist/db/migrations-pg/meta/0022_snapshot.json +3240 -0
  274. package/dist/db/migrations-pg/meta/_journal.json +475 -0
  275. package/dist/db/ml-labels.js +1666 -0
  276. package/dist/db/my-turn-dismissals.js +343 -0
  277. package/dist/db/my-turn-settings.js +34 -0
  278. package/dist/db/pending-classify.js +46 -0
  279. package/dist/db/pending-mute.js +171 -0
  280. package/dist/db/pending-tabs.js +238 -0
  281. package/dist/db/period-metrics.js +820 -0
  282. package/dist/db/person-period.js +763 -0
  283. package/dist/db/pr-intervals.js +930 -0
  284. package/dist/db/pr-liveness.js +240 -0
  285. package/dist/db/pr-mentions.js +279 -0
  286. package/dist/db/pr-merge-queue-stamp.js +91 -0
  287. package/dist/db/queries.js +14631 -0
  288. package/dist/db/reaction-targets.js +94 -0
  289. package/dist/db/repo-activity.js +171 -0
  290. package/dist/db/retention.js +138 -0
  291. package/dist/db/review-threads-for-review.js +240 -0
  292. package/dist/db/run-migrations.js +24 -0
  293. package/dist/db/schema.pg.js +1220 -0
  294. package/dist/db/schema.sqlite.js +1801 -0
  295. package/dist/db/search.js +317 -0
  296. package/dist/db/security-alerts.js +218 -0
  297. package/dist/db/synthesis-input.js +565 -0
  298. package/dist/db/triage.js +320 -0
  299. package/dist/db/usage.js +63 -0
  300. package/dist/db/work-plan.js +1086 -0
  301. package/dist/db/working-hours.js +161 -0
  302. package/dist/feed/my-turn.js +122 -0
  303. package/dist/github/actions-logs.js +397 -0
  304. package/dist/github/auth.js +86 -0
  305. package/dist/github/branch-queries.js +229 -0
  306. package/dist/github/client.js +454 -0
  307. package/dist/github/codeowners.js +221 -0
  308. package/dist/github/commit-checks.js +105 -0
  309. package/dist/github/compare.js +110 -0
  310. package/dist/github/diff-anchor.js +227 -0
  311. package/dist/github/mutations.js +706 -0
  312. package/dist/github/pr-file-content.js +254 -0
  313. package/dist/github/pr-liveness.js +161 -0
  314. package/dist/github/queries.js +875 -0
  315. package/dist/github/rate-budget.js +129 -0
  316. package/dist/github/reactions.js +161 -0
  317. package/dist/github/reviewer-suggest.js +104 -0
  318. package/dist/github/team-reviewers.js +96 -0
  319. package/dist/index.js +184 -0
  320. package/dist/merge/auto-merge-runner.js +960 -0
  321. package/dist/ml/severity-client.js +218 -0
  322. package/dist/pr/detail-enricher.js +26 -0
  323. package/dist/pro/bind.js +302 -0
  324. package/dist/pro/contract.js +37 -0
  325. package/dist/pro/migrate.js +64 -0
  326. package/dist/review/agent-context.js +127 -0
  327. package/dist/review/agent.js +385 -0
  328. package/dist/review/agentic.js +59 -0
  329. package/dist/review/auth.js +94 -0
  330. package/dist/review/chat-agent.js +179 -0
  331. package/dist/review/claude-review/ai-ready.js +16 -0
  332. package/dist/review/claude-review/auto-settings.js +139 -0
  333. package/dist/review/claude-review/auto.js +244 -0
  334. package/dist/review/claude-review/chat.js +489 -0
  335. package/dist/review/claude-review/ci-failures.js +350 -0
  336. package/dist/review/claude-review/follow-up.js +310 -0
  337. package/dist/review/claude-review/manager.js +686 -0
  338. package/dist/review/claude-review/persist.js +996 -0
  339. package/dist/review/claude-review/prompts.js +357 -0
  340. package/dist/review/claude-review/routes.js +518 -0
  341. package/dist/review/claude-review/routing.js +61 -0
  342. package/dist/review/claude-review/specialists.js +190 -0
  343. package/dist/review/claude-review/threads.js +265 -0
  344. package/dist/review/claude-review/ticket.js +282 -0
  345. package/dist/review/clone-hygiene.js +380 -0
  346. package/dist/review/clone-manager.js +367 -0
  347. package/dist/review/llm.js +113 -0
  348. package/dist/review/model-options.js +48 -0
  349. package/dist/review/plugin-providers.js +12 -0
  350. package/dist/review/post-review.js +216 -0
  351. package/dist/review/post-seam.js +161 -0
  352. package/dist/review/prepare.js +168 -0
  353. package/dist/review/pricing.js +17 -0
  354. package/dist/review/schema.js +156 -0
  355. package/dist/review/submit-map.js +41 -0
  356. package/dist/review/usage.js +90 -0
  357. package/dist/shared/claude-review.js +335 -0
  358. package/dist/shared/conflict-fold.js +151 -0
  359. package/dist/shared/conflicts.js +30 -0
  360. package/dist/shared/flow-settings.js +191 -0
  361. package/dist/shared/index.js +8 -0
  362. package/dist/shared/my-turn-settings.js +238 -0
  363. package/dist/shared/pending-rules.js +281 -0
  364. package/dist/shared/product.js +54 -0
  365. package/dist/shared/types.js +896 -0
  366. package/dist/status.js +386 -0
  367. package/dist/sync/adaptive.js +185 -0
  368. package/dist/sync/app-attribution.js +66 -0
  369. package/dist/sync/auth-notices.js +36 -0
  370. package/dist/sync/backfill-ci-history.js +315 -0
  371. package/dist/sync/backfill-commit-headlines.js +136 -0
  372. package/dist/sync/backfill-pr-security.js +175 -0
  373. package/dist/sync/backfill-review-requests.js +97 -0
  374. package/dist/sync/benchmark-rollup.js +50 -0
  375. package/dist/sync/bot-detection.js +309 -0
  376. package/dist/sync/bot-resolution-markers.js +30 -0
  377. package/dist/sync/branch-status.js +634 -0
  378. package/dist/sync/classify-change-shape.js +150 -0
  379. package/dist/sync/commit-files.js +74 -0
  380. package/dist/sync/derive-thread-state.js +99 -0
  381. package/dist/sync/drain-review-threads.js +212 -0
  382. package/dist/sync/hydrate-detail.js +482 -0
  383. package/dist/sync/mention-scan.js +89 -0
  384. package/dist/sync/ml-enrichment.js +478 -0
  385. package/dist/sync/pr-change-signal.js +96 -0
  386. package/dist/sync/pr-liveness-sweep.js +139 -0
  387. package/dist/sync/pr-settle.js +381 -0
  388. package/dist/sync/refresh-pr.js +163 -0
  389. package/dist/sync/reparse-vendor-badges.js +495 -0
  390. package/dist/sync/resync-after-write.js +280 -0
  391. package/dist/sync/review-fingerprint.js +117 -0
  392. package/dist/sync/reviewer-behavior.js +103 -0
  393. package/dist/sync/reviewer-classify.js +503 -0
  394. package/dist/sync/routing-files.js +97 -0
  395. package/dist/sync/scheduled-jobs.js +12 -0
  396. package/dist/sync/scheduler.js +159 -0
  397. package/dist/sync/security-detect.js +521 -0
  398. package/dist/sync/sync-manager.js +750 -0
  399. package/dist/sync/sync-one-pr.js +205 -0
  400. package/dist/sync/sync-repo.js +400 -0
  401. package/dist/sync/unsettled-prs.js +506 -0
  402. package/dist/sync/upsert.js +1190 -0
  403. package/package.json +56 -0
  404. package/public/apple-touch-icon.png +0 -0
  405. package/public/assets/AiFixTab-CQP6PT5u.js +2 -0
  406. package/public/assets/ClaudeReviewTab-DQJ-58ZA.js +8 -0
  407. package/public/assets/PrBotBehaviourTab-CCnFrWbC.js +1 -0
  408. package/public/assets/archivo-latin-600-BN-JkNrl.woff2 +0 -0
  409. package/public/assets/highlight-BEHUn5zE.css +10 -0
  410. package/public/assets/highlight-CIIZLa6Z.js +12 -0
  411. package/public/assets/index-BDnYs6zg.js +73 -0
  412. package/public/assets/index-mCuI--RC.css +1 -0
  413. package/public/assets/markdown-I_JLLVAZ.js +32 -0
  414. package/public/assets/perfProbe-Da13EhTE.js +1 -0
  415. package/public/assets/tanstack-5qsxxaLe.js +17 -0
  416. package/public/assets/vis-C3BCkP5U.js +1280 -0
  417. package/public/assets/vis-ziCVehMy.css +1 -0
  418. package/public/favicon-16.png +0 -0
  419. package/public/favicon-32.png +0 -0
  420. package/public/favicon-48.png +0 -0
  421. package/public/favicon.svg +5 -0
  422. package/public/index.html +41 -0
  423. package/public-landing/apple-touch-icon.png +0 -0
  424. package/public-landing/assets/archivo-latin-500-BWmvx2Mg.woff2 +0 -0
  425. package/public-landing/assets/archivo-latin-600-BN-JkNrl.woff2 +0 -0
  426. package/public-landing/assets/index-CA3eEGXO.js +40 -0
  427. package/public-landing/assets/index-naQrQ6Fe.css +1 -0
  428. package/public-landing/assets/jetbrains-mono-latin-400-RruCX7RW.woff2 +0 -0
  429. package/public-landing/assets/newsreader-latin-400-DExrRRrN.woff2 +0 -0
  430. package/public-landing/assets/newsreader-latin-400-italic-b0I-AwbV.woff2 +0 -0
  431. package/public-landing/bots/index.html +156 -0
  432. package/public-landing/contact/index.html +156 -0
  433. package/public-landing/cookies/index.html +156 -0
  434. package/public-landing/demo/limn-walkthrough-poster.jpg +0 -0
  435. package/public-landing/demo/limn-walkthrough.cues.json +44 -0
  436. package/public-landing/demo/limn-walkthrough.mp4 +0 -0
  437. package/public-landing/favicon-16.png +0 -0
  438. package/public-landing/favicon-32.png +0 -0
  439. package/public-landing/favicon-48.png +0 -0
  440. package/public-landing/favicon.svg +5 -0
  441. package/public-landing/features/index.html +156 -0
  442. package/public-landing/for-developers/index.html +156 -0
  443. package/public-landing/for-managers/index.html +156 -0
  444. package/public-landing/how-it-works/index.html +156 -0
  445. package/public-landing/how-we-measure/index.html +156 -0
  446. package/public-landing/icon-192.png +0 -0
  447. package/public-landing/icon-512.png +0 -0
  448. package/public-landing/index.html +156 -0
  449. package/public-landing/insights/index.html +156 -0
  450. package/public-landing/og-image.png +0 -0
  451. package/public-landing/pricing/index.html +156 -0
  452. package/public-landing/privacy/index.html +156 -0
  453. package/public-landing/pro/index.html +156 -0
  454. package/public-landing/reviews/index.html +156 -0
  455. package/public-landing/robots.txt +8 -0
  456. package/public-landing/shots/benchmark.png +0 -0
  457. package/public-landing/shots/bot-roi.png +0 -0
  458. package/public-landing/shots/bot-settings.png +0 -0
  459. package/public-landing/shots/chronology.png +0 -0
  460. package/public-landing/shots/feed.png +0 -0
  461. package/public-landing/shots/flow-metrics.png +0 -0
  462. package/public-landing/shots/free-reports.png +0 -0
  463. package/public-landing/shots/pending-board.png +0 -0
  464. package/public-landing/shots/pending-card.png +0 -0
  465. package/public-landing/shots/period-report.png +0 -0
  466. package/public-landing/shots/pr-detail.png +0 -0
  467. package/public-landing/shots/pr-threads.png +0 -0
  468. package/public-landing/shots/reach.png +0 -0
  469. package/public-landing/shots/repo-rows.png +0 -0
  470. package/public-landing/shots/severity-findings.png +0 -0
  471. package/public-landing/shots/severity-strip.png +0 -0
  472. package/public-landing/site.webmanifest +14 -0
  473. package/public-landing/sitemap.xml +51 -0
  474. package/public-landing/terms/index.html +156 -0
@@ -0,0 +1,27 @@
1
+ -- Default-branch ("trunk") CI transition log — the Postgres twin of sqlite
2
+ -- 0052_trunk_ci_status_events.sql. HAND-WRITTEN ADDITIVE, like every pg migration since 0023:
3
+ -- never regenerate the baseline with `pnpm db:generate:pg`, which squashes it.
4
+ --
5
+ -- See the sqlite twin for the full argument. In short: `branch_commits.ci_status` is updated IN
6
+ -- PLACE, so the moment trunk turned red is otherwise unrecorded; rows are written only on a
7
+ -- TRANSITION and only on a POSITIVE statement from GitHub (an `unknown` rollup — which is also
8
+ -- what a `graphqlTolerant` partial produces — records nothing); `observed_at` is OUR observation
9
+ -- time; `failing_checks` is the BranchCheckRun[] render payload, not ci_status_events' bare
10
+ -- string[]; and the table is bounded by its own per-repo trim, because the retention sweep
11
+ -- anchors to a parent PR's `updated_at` and a trunk row has no PR. That trim is HYBRID (newest
12
+ -- TRUNK_CI_EVENT_WINDOW rows UNION everything inside FEED_WINDOW_DAYS) — a pure count bound
13
+ -- evicted the very failure rows the Feed reads on the most active repos.
14
+ CREATE TABLE IF NOT EXISTS "trunk_ci_status_events" (
15
+ "id" serial PRIMARY KEY NOT NULL,
16
+ "account_id" integer NOT NULL REFERENCES "accounts"("id") ON DELETE cascade,
17
+ "repo_id" integer NOT NULL REFERENCES "repos"("id") ON DELETE cascade,
18
+ "branch_name" text,
19
+ "head_sha" text NOT NULL,
20
+ "status" text NOT NULL,
21
+ "failing_checks" jsonb,
22
+ "observed_at" timestamp with time zone NOT NULL
23
+ );
24
+ --> statement-breakpoint
25
+ CREATE INDEX IF NOT EXISTS "tcse_account_repo_observed" ON "trunk_ci_status_events" ("account_id","repo_id","observed_at");
26
+ --> statement-breakpoint
27
+ CREATE INDEX IF NOT EXISTS "tcse_account_idx" ON "trunk_ci_status_events" ("account_id");
@@ -0,0 +1,63 @@
1
+ -- Postgres twin of sqlite `0053_automation_roles.sql`. Read that file for the full reasoning:
2
+ -- the stored role beats the login seed on read, so widening the vocabularies in code does nothing
3
+ -- for an actor that has already been classified, and `github-actions` would keep sitting in the
4
+ -- AI-reviewer ROI cohort with 385 submitted reviews behind it.
5
+ --
6
+ -- `source <> 'manual'` is the safety condition — a role a person chose is never re-derived.
7
+ --
8
+ -- The only spelling difference from the sqlite file: `regexp_replace(…, '\[bot\]$', '')` instead
9
+ -- of `replace(…, '[bot]', '')`. Same operation — strip the `[bot]` suffix so the two `users` rows
10
+ -- that are the same actor (`dependabot` and `dependabot[bot]` have different GitHub node ids)
11
+ -- cannot land in different roles.
12
+ UPDATE "workspace_reviewers"
13
+ SET "role" = 'dependency'
14
+ WHERE "source" <> 'manual'
15
+ AND "author_user_id" IN (
16
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN (
17
+ 'dependabot', 'dependabot-preview', 'renovate', 'renovate-bot',
18
+ 'snyk-bot', 'pyup-bot', 'greenkeeper', 'depfu'
19
+ )
20
+ );
21
+ UPDATE "workspace_reviewers"
22
+ SET "role" = 'code_agent'
23
+ WHERE "source" <> 'manual'
24
+ AND "author_user_id" IN (
25
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN (
26
+ 'devin-ai-integration', 'sweep-ai', 'codegen-sh', 'deepsource-autofix',
27
+ 'pre-commit-ci', 'restyled-io', 'imgbot', 'imgbotapp',
28
+ 'transifex-integration', 'crowdin-bot', 'mintlify', 'allstar'
29
+ )
30
+ );
31
+ UPDATE "workspace_reviewers"
32
+ SET "role" = 'release'
33
+ WHERE "source" <> 'manual'
34
+ AND "author_user_id" IN (
35
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN (
36
+ 'mergify', 'kodiak', 'kodiakhq', 'bulldozer', 'release-please', 'releaser',
37
+ 'semantic-release', 'semantic-release-bot', 'release-drafter', 'changeset-bot',
38
+ 'changesets', 'autorelease', 'lumberbot-app', 'meeseeksdev', 'backport'
39
+ )
40
+ );
41
+ UPDATE "workspace_reviewers"
42
+ SET "role" = 'housekeeping'
43
+ WHERE "source" <> 'manual'
44
+ AND "author_user_id" IN (
45
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN (
46
+ 'cla-bot', 'cla-assistant', 'claassistant', 'google-cla', 'googlebot',
47
+ 'facebook-github-bot', 'dco', 'stale', 'welcome', 'lock', 'allcontributors',
48
+ 'semantic-pull-request', 'sizebot', 'react-sizebot', 'diffray-bot',
49
+ 'codesandbox-ci', 'netlify', 'vercel', 'gitpod-io'
50
+ )
51
+ );
52
+ -- Supersedes pg 0029's narrower list rather than repeating it.
53
+ UPDATE "workspace_reviewers"
54
+ SET "role" = 'quality_check'
55
+ WHERE "source" <> 'manual'
56
+ AND "author_user_id" IN (
57
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN (
58
+ 'sonarqubecloud', 'sonarcloud', 'codecov', 'codeclimate', 'codefactor-io',
59
+ 'houndci-bot', 'coveralls', 'codacy-bot',
60
+ 'github-actions', 'jit-ci', 'socket-security', 'gitguardian',
61
+ 'semgrep-app', 'trunk-io'
62
+ )
63
+ );
@@ -0,0 +1,488 @@
1
+ -- Postgres twin of sqlite `0054_automation_vendor_kinds.sql`. Read that file for the reasoning:
2
+ -- every non-reviewer integration was stored as `kind: 'in_house'` (the "In-house AI" bucket)
3
+ -- because the classifier had no step between the AI-reviewer login check and the githubType
4
+ -- fallback, and the stored kind wins on read.
5
+ --
6
+ -- Three conditions, each load-bearing: `identity_source <> 'manual'` (never re-derive a vendor a
7
+ -- human named), `kind IN ('in_house','vendor')` (only upgrade the UNBRANDED kinds — a row with a
8
+ -- real brand came from a stronger signal), and `label = NULL` (the label caches the kind's
9
+ -- display name and the old rows hold the literal "In-house AI").
10
+ --
11
+ -- Only spelling difference from the sqlite file: `regexp_replace(…, '\[bot\]$', '')` rather
12
+ -- than `replace(…, '[bot]', '')`.
13
+ UPDATE "workspace_reviewers"
14
+ SET "kind" = 'allcontributors', "label" = NULL
15
+ WHERE "identity_source" <> 'manual'
16
+ AND "kind" IN ('in_house', 'vendor')
17
+ AND "author_user_id" IN (
18
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('allcontributors')
19
+ );
20
+ UPDATE "workspace_reviewers"
21
+ SET "kind" = 'allstar', "label" = NULL
22
+ WHERE "identity_source" <> 'manual'
23
+ AND "kind" IN ('in_house', 'vendor')
24
+ AND "author_user_id" IN (
25
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('allstar')
26
+ );
27
+ UPDATE "workspace_reviewers"
28
+ SET "kind" = 'backport', "label" = NULL
29
+ WHERE "identity_source" <> 'manual'
30
+ AND "kind" IN ('in_house', 'vendor')
31
+ AND "author_user_id" IN (
32
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('backport', 'lumberbot-app', 'meeseeksdev')
33
+ );
34
+ UPDATE "workspace_reviewers"
35
+ SET "kind" = 'baz', "label" = NULL
36
+ WHERE "identity_source" <> 'manual'
37
+ AND "kind" IN ('in_house', 'vendor')
38
+ AND "author_user_id" IN (
39
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('baz-reviewer')
40
+ );
41
+ UPDATE "workspace_reviewers"
42
+ SET "kind" = 'bito', "label" = NULL
43
+ WHERE "identity_source" <> 'manual'
44
+ AND "kind" IN ('in_house', 'vendor')
45
+ AND "author_user_id" IN (
46
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('bito-code-review')
47
+ );
48
+ UPDATE "workspace_reviewers"
49
+ SET "kind" = 'bulldozer', "label" = NULL
50
+ WHERE "identity_source" <> 'manual'
51
+ AND "kind" IN ('in_house', 'vendor')
52
+ AND "author_user_id" IN (
53
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('bulldozer')
54
+ );
55
+ UPDATE "workspace_reviewers"
56
+ SET "kind" = 'changesets', "label" = NULL
57
+ WHERE "identity_source" <> 'manual'
58
+ AND "kind" IN ('in_house', 'vendor')
59
+ AND "author_user_id" IN (
60
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('changeset-bot', 'changesets')
61
+ );
62
+ UPDATE "workspace_reviewers"
63
+ SET "kind" = 'cla_assistant', "label" = NULL
64
+ WHERE "identity_source" <> 'manual'
65
+ AND "kind" IN ('in_house', 'vendor')
66
+ AND "author_user_id" IN (
67
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('cla-assistant', 'cla-bot', 'claassistant')
68
+ );
69
+ UPDATE "workspace_reviewers"
70
+ SET "kind" = 'codacy', "label" = NULL
71
+ WHERE "identity_source" <> 'manual'
72
+ AND "kind" IN ('in_house', 'vendor')
73
+ AND "author_user_id" IN (
74
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('codacy-bot')
75
+ );
76
+ UPDATE "workspace_reviewers"
77
+ SET "kind" = 'codeclimate', "label" = NULL
78
+ WHERE "identity_source" <> 'manual'
79
+ AND "kind" IN ('in_house', 'vendor')
80
+ AND "author_user_id" IN (
81
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('codeclimate')
82
+ );
83
+ UPDATE "workspace_reviewers"
84
+ SET "kind" = 'codecov', "label" = NULL
85
+ WHERE "identity_source" <> 'manual'
86
+ AND "kind" IN ('in_house', 'vendor')
87
+ AND "author_user_id" IN (
88
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('codecov')
89
+ );
90
+ UPDATE "workspace_reviewers"
91
+ SET "kind" = 'codefactor', "label" = NULL
92
+ WHERE "identity_source" <> 'manual'
93
+ AND "kind" IN ('in_house', 'vendor')
94
+ AND "author_user_id" IN (
95
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('codefactor-io')
96
+ );
97
+ UPDATE "workspace_reviewers"
98
+ SET "kind" = 'codegen', "label" = NULL
99
+ WHERE "identity_source" <> 'manual'
100
+ AND "kind" IN ('in_house', 'vendor')
101
+ AND "author_user_id" IN (
102
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('codegen-sh')
103
+ );
104
+ UPDATE "workspace_reviewers"
105
+ SET "kind" = 'coderabbit', "label" = NULL
106
+ WHERE "identity_source" <> 'manual'
107
+ AND "kind" IN ('in_house', 'vendor')
108
+ AND "author_user_id" IN (
109
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('coderabbitai')
110
+ );
111
+ UPDATE "workspace_reviewers"
112
+ SET "kind" = 'codesandbox', "label" = NULL
113
+ WHERE "identity_source" <> 'manual'
114
+ AND "kind" IN ('in_house', 'vendor')
115
+ AND "author_user_id" IN (
116
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('codesandbox-ci')
117
+ );
118
+ UPDATE "workspace_reviewers"
119
+ SET "kind" = 'codex', "label" = NULL
120
+ WHERE "identity_source" <> 'manual'
121
+ AND "kind" IN ('in_house', 'vendor')
122
+ AND "author_user_id" IN (
123
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('chatgpt-codex-connector')
124
+ );
125
+ UPDATE "workspace_reviewers"
126
+ SET "kind" = 'copilot', "label" = NULL
127
+ WHERE "identity_source" <> 'manual'
128
+ AND "kind" IN ('in_house', 'vendor')
129
+ AND "author_user_id" IN (
130
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('copilot-pull-request-reviewer')
131
+ );
132
+ UPDATE "workspace_reviewers"
133
+ SET "kind" = 'coveralls', "label" = NULL
134
+ WHERE "identity_source" <> 'manual'
135
+ AND "kind" IN ('in_house', 'vendor')
136
+ AND "author_user_id" IN (
137
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('coveralls')
138
+ );
139
+ UPDATE "workspace_reviewers"
140
+ SET "kind" = 'crowdin', "label" = NULL
141
+ WHERE "identity_source" <> 'manual'
142
+ AND "kind" IN ('in_house', 'vendor')
143
+ AND "author_user_id" IN (
144
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('crowdin-bot')
145
+ );
146
+ UPDATE "workspace_reviewers"
147
+ SET "kind" = 'cursor', "label" = NULL
148
+ WHERE "identity_source" <> 'manual'
149
+ AND "kind" IN ('in_house', 'vendor')
150
+ AND "author_user_id" IN (
151
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('cursor')
152
+ );
153
+ UPDATE "workspace_reviewers"
154
+ SET "kind" = 'dco', "label" = NULL
155
+ WHERE "identity_source" <> 'manual'
156
+ AND "kind" IN ('in_house', 'vendor')
157
+ AND "author_user_id" IN (
158
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('dco')
159
+ );
160
+ UPDATE "workspace_reviewers"
161
+ SET "kind" = 'deepsource', "label" = NULL
162
+ WHERE "identity_source" <> 'manual'
163
+ AND "kind" IN ('in_house', 'vendor')
164
+ AND "author_user_id" IN (
165
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('deepsource-io', 'deepsourcebot')
166
+ );
167
+ UPDATE "workspace_reviewers"
168
+ SET "kind" = 'deepsource_autofix', "label" = NULL
169
+ WHERE "identity_source" <> 'manual'
170
+ AND "kind" IN ('in_house', 'vendor')
171
+ AND "author_user_id" IN (
172
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('deepsource-autofix')
173
+ );
174
+ UPDATE "workspace_reviewers"
175
+ SET "kind" = 'dependabot', "label" = NULL
176
+ WHERE "identity_source" <> 'manual'
177
+ AND "kind" IN ('in_house', 'vendor')
178
+ AND "author_user_id" IN (
179
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('dependabot', 'dependabot-preview')
180
+ );
181
+ UPDATE "workspace_reviewers"
182
+ SET "kind" = 'depfu', "label" = NULL
183
+ WHERE "identity_source" <> 'manual'
184
+ AND "kind" IN ('in_house', 'vendor')
185
+ AND "author_user_id" IN (
186
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('depfu')
187
+ );
188
+ UPDATE "workspace_reviewers"
189
+ SET "kind" = 'devin', "label" = NULL
190
+ WHERE "identity_source" <> 'manual'
191
+ AND "kind" IN ('in_house', 'vendor')
192
+ AND "author_user_id" IN (
193
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('devin-ai-integration')
194
+ );
195
+ UPDATE "workspace_reviewers"
196
+ SET "kind" = 'ellipsis', "label" = NULL
197
+ WHERE "identity_source" <> 'manual'
198
+ AND "kind" IN ('in_house', 'vendor')
199
+ AND "author_user_id" IN (
200
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('ellipsis-dev')
201
+ );
202
+ UPDATE "workspace_reviewers"
203
+ SET "kind" = 'entelligence', "label" = NULL
204
+ WHERE "identity_source" <> 'manual'
205
+ AND "kind" IN ('in_house', 'vendor')
206
+ AND "author_user_id" IN (
207
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('entelligence-ai-pr-reviews')
208
+ );
209
+ UPDATE "workspace_reviewers"
210
+ SET "kind" = 'gitguardian', "label" = NULL
211
+ WHERE "identity_source" <> 'manual'
212
+ AND "kind" IN ('in_house', 'vendor')
213
+ AND "author_user_id" IN (
214
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('gitguardian')
215
+ );
216
+ UPDATE "workspace_reviewers"
217
+ SET "kind" = 'github_actions', "label" = NULL
218
+ WHERE "identity_source" <> 'manual'
219
+ AND "kind" IN ('in_house', 'vendor')
220
+ AND "author_user_id" IN (
221
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('github-actions')
222
+ );
223
+ UPDATE "workspace_reviewers"
224
+ SET "kind" = 'github_advanced_security', "label" = NULL
225
+ WHERE "identity_source" <> 'manual'
226
+ AND "kind" IN ('in_house', 'vendor')
227
+ AND "author_user_id" IN (
228
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('github-advanced-security')
229
+ );
230
+ UPDATE "workspace_reviewers"
231
+ SET "kind" = 'github_code_quality', "label" = NULL
232
+ WHERE "identity_source" <> 'manual'
233
+ AND "kind" IN ('in_house', 'vendor')
234
+ AND "author_user_id" IN (
235
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('github-code-quality')
236
+ );
237
+ UPDATE "workspace_reviewers"
238
+ SET "kind" = 'gitpod', "label" = NULL
239
+ WHERE "identity_source" <> 'manual'
240
+ AND "kind" IN ('in_house', 'vendor')
241
+ AND "author_user_id" IN (
242
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('gitpod-io')
243
+ );
244
+ UPDATE "workspace_reviewers"
245
+ SET "kind" = 'google_cla', "label" = NULL
246
+ WHERE "identity_source" <> 'manual'
247
+ AND "kind" IN ('in_house', 'vendor')
248
+ AND "author_user_id" IN (
249
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('google-cla', 'googlebot')
250
+ );
251
+ UPDATE "workspace_reviewers"
252
+ SET "kind" = 'graphite', "label" = NULL
253
+ WHERE "identity_source" <> 'manual'
254
+ AND "kind" IN ('in_house', 'vendor')
255
+ AND "author_user_id" IN (
256
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('graphite-app')
257
+ );
258
+ UPDATE "workspace_reviewers"
259
+ SET "kind" = 'greenkeeper', "label" = NULL
260
+ WHERE "identity_source" <> 'manual'
261
+ AND "kind" IN ('in_house', 'vendor')
262
+ AND "author_user_id" IN (
263
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('greenkeeper')
264
+ );
265
+ UPDATE "workspace_reviewers"
266
+ SET "kind" = 'greptile', "label" = NULL
267
+ WHERE "identity_source" <> 'manual'
268
+ AND "kind" IN ('in_house', 'vendor')
269
+ AND "author_user_id" IN (
270
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('greptile-apps')
271
+ );
272
+ UPDATE "workspace_reviewers"
273
+ SET "kind" = 'hound', "label" = NULL
274
+ WHERE "identity_source" <> 'manual'
275
+ AND "kind" IN ('in_house', 'vendor')
276
+ AND "author_user_id" IN (
277
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('houndci-bot')
278
+ );
279
+ UPDATE "workspace_reviewers"
280
+ SET "kind" = 'imgbot', "label" = NULL
281
+ WHERE "identity_source" <> 'manual'
282
+ AND "kind" IN ('in_house', 'vendor')
283
+ AND "author_user_id" IN (
284
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('imgbot', 'imgbotapp')
285
+ );
286
+ UPDATE "workspace_reviewers"
287
+ SET "kind" = 'jit', "label" = NULL
288
+ WHERE "identity_source" <> 'manual'
289
+ AND "kind" IN ('in_house', 'vendor')
290
+ AND "author_user_id" IN (
291
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('jit-ci')
292
+ );
293
+ UPDATE "workspace_reviewers"
294
+ SET "kind" = 'kodiak', "label" = NULL
295
+ WHERE "identity_source" <> 'manual'
296
+ AND "kind" IN ('in_house', 'vendor')
297
+ AND "author_user_id" IN (
298
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('kodiak', 'kodiakhq')
299
+ );
300
+ UPDATE "workspace_reviewers"
301
+ SET "kind" = 'korbit', "label" = NULL
302
+ WHERE "identity_source" <> 'manual'
303
+ AND "kind" IN ('in_house', 'vendor')
304
+ AND "author_user_id" IN (
305
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('korbit-ai')
306
+ );
307
+ UPDATE "workspace_reviewers"
308
+ SET "kind" = 'lock_bot', "label" = NULL
309
+ WHERE "identity_source" <> 'manual'
310
+ AND "kind" IN ('in_house', 'vendor')
311
+ AND "author_user_id" IN (
312
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('lock')
313
+ );
314
+ UPDATE "workspace_reviewers"
315
+ SET "kind" = 'mergify', "label" = NULL
316
+ WHERE "identity_source" <> 'manual'
317
+ AND "kind" IN ('in_house', 'vendor')
318
+ AND "author_user_id" IN (
319
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('mergify')
320
+ );
321
+ UPDATE "workspace_reviewers"
322
+ SET "kind" = 'meta_cla', "label" = NULL
323
+ WHERE "identity_source" <> 'manual'
324
+ AND "kind" IN ('in_house', 'vendor')
325
+ AND "author_user_id" IN (
326
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('facebook-github-bot')
327
+ );
328
+ UPDATE "workspace_reviewers"
329
+ SET "kind" = 'mintlify', "label" = NULL
330
+ WHERE "identity_source" <> 'manual'
331
+ AND "kind" IN ('in_house', 'vendor')
332
+ AND "author_user_id" IN (
333
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('mintlify')
334
+ );
335
+ UPDATE "workspace_reviewers"
336
+ SET "kind" = 'netlify', "label" = NULL
337
+ WHERE "identity_source" <> 'manual'
338
+ AND "kind" IN ('in_house', 'vendor')
339
+ AND "author_user_id" IN (
340
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('netlify')
341
+ );
342
+ UPDATE "workspace_reviewers"
343
+ SET "kind" = 'pre_commit_ci', "label" = NULL
344
+ WHERE "identity_source" <> 'manual'
345
+ AND "kind" IN ('in_house', 'vendor')
346
+ AND "author_user_id" IN (
347
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('pre-commit-ci')
348
+ );
349
+ UPDATE "workspace_reviewers"
350
+ SET "kind" = 'pyup', "label" = NULL
351
+ WHERE "identity_source" <> 'manual'
352
+ AND "kind" IN ('in_house', 'vendor')
353
+ AND "author_user_id" IN (
354
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('pyup-bot')
355
+ );
356
+ UPDATE "workspace_reviewers"
357
+ SET "kind" = 'qodo', "label" = NULL
358
+ WHERE "identity_source" <> 'manual'
359
+ AND "kind" IN ('in_house', 'vendor')
360
+ AND "author_user_id" IN (
361
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('codiumai-pr-agent-free', 'qodo-ai', 'qodo-merge', 'qodo-merge-for-open-source', 'qodo-merge-pro')
362
+ );
363
+ UPDATE "workspace_reviewers"
364
+ SET "kind" = 'release_drafter', "label" = NULL
365
+ WHERE "identity_source" <> 'manual'
366
+ AND "kind" IN ('in_house', 'vendor')
367
+ AND "author_user_id" IN (
368
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('release-drafter')
369
+ );
370
+ UPDATE "workspace_reviewers"
371
+ SET "kind" = 'release_please', "label" = NULL
372
+ WHERE "identity_source" <> 'manual'
373
+ AND "kind" IN ('in_house', 'vendor')
374
+ AND "author_user_id" IN (
375
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('autorelease', 'release-please', 'releaser')
376
+ );
377
+ UPDATE "workspace_reviewers"
378
+ SET "kind" = 'renovate', "label" = NULL
379
+ WHERE "identity_source" <> 'manual'
380
+ AND "kind" IN ('in_house', 'vendor')
381
+ AND "author_user_id" IN (
382
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('renovate', 'renovate-bot')
383
+ );
384
+ UPDATE "workspace_reviewers"
385
+ SET "kind" = 'restyled', "label" = NULL
386
+ WHERE "identity_source" <> 'manual'
387
+ AND "kind" IN ('in_house', 'vendor')
388
+ AND "author_user_id" IN (
389
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('restyled-io')
390
+ );
391
+ UPDATE "workspace_reviewers"
392
+ SET "kind" = 'semantic_pr', "label" = NULL
393
+ WHERE "identity_source" <> 'manual'
394
+ AND "kind" IN ('in_house', 'vendor')
395
+ AND "author_user_id" IN (
396
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('semantic-pull-request')
397
+ );
398
+ UPDATE "workspace_reviewers"
399
+ SET "kind" = 'semantic_release', "label" = NULL
400
+ WHERE "identity_source" <> 'manual'
401
+ AND "kind" IN ('in_house', 'vendor')
402
+ AND "author_user_id" IN (
403
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('semantic-release', 'semantic-release-bot')
404
+ );
405
+ UPDATE "workspace_reviewers"
406
+ SET "kind" = 'semgrep', "label" = NULL
407
+ WHERE "identity_source" <> 'manual'
408
+ AND "kind" IN ('in_house', 'vendor')
409
+ AND "author_user_id" IN (
410
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('semgrep-app')
411
+ );
412
+ UPDATE "workspace_reviewers"
413
+ SET "kind" = 'sizebot', "label" = NULL
414
+ WHERE "identity_source" <> 'manual'
415
+ AND "kind" IN ('in_house', 'vendor')
416
+ AND "author_user_id" IN (
417
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('diffray-bot', 'react-sizebot', 'sizebot')
418
+ );
419
+ UPDATE "workspace_reviewers"
420
+ SET "kind" = 'snyk', "label" = NULL
421
+ WHERE "identity_source" <> 'manual'
422
+ AND "kind" IN ('in_house', 'vendor')
423
+ AND "author_user_id" IN (
424
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('snyk-bot')
425
+ );
426
+ UPDATE "workspace_reviewers"
427
+ SET "kind" = 'socket', "label" = NULL
428
+ WHERE "identity_source" <> 'manual'
429
+ AND "kind" IN ('in_house', 'vendor')
430
+ AND "author_user_id" IN (
431
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('socket-security')
432
+ );
433
+ UPDATE "workspace_reviewers"
434
+ SET "kind" = 'sonarqube', "label" = NULL
435
+ WHERE "identity_source" <> 'manual'
436
+ AND "kind" IN ('in_house', 'vendor')
437
+ AND "author_user_id" IN (
438
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('sonarcloud', 'sonarqubecloud')
439
+ );
440
+ UPDATE "workspace_reviewers"
441
+ SET "kind" = 'sourcery', "label" = NULL
442
+ WHERE "identity_source" <> 'manual'
443
+ AND "kind" IN ('in_house', 'vendor')
444
+ AND "author_user_id" IN (
445
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('sourcery-ai')
446
+ );
447
+ UPDATE "workspace_reviewers"
448
+ SET "kind" = 'stale_bot', "label" = NULL
449
+ WHERE "identity_source" <> 'manual'
450
+ AND "kind" IN ('in_house', 'vendor')
451
+ AND "author_user_id" IN (
452
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('stale')
453
+ );
454
+ UPDATE "workspace_reviewers"
455
+ SET "kind" = 'sweep', "label" = NULL
456
+ WHERE "identity_source" <> 'manual'
457
+ AND "kind" IN ('in_house', 'vendor')
458
+ AND "author_user_id" IN (
459
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('sweep-ai')
460
+ );
461
+ UPDATE "workspace_reviewers"
462
+ SET "kind" = 'transifex', "label" = NULL
463
+ WHERE "identity_source" <> 'manual'
464
+ AND "kind" IN ('in_house', 'vendor')
465
+ AND "author_user_id" IN (
466
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('transifex-integration')
467
+ );
468
+ UPDATE "workspace_reviewers"
469
+ SET "kind" = 'trunk', "label" = NULL
470
+ WHERE "identity_source" <> 'manual'
471
+ AND "kind" IN ('in_house', 'vendor')
472
+ AND "author_user_id" IN (
473
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('trunk-io')
474
+ );
475
+ UPDATE "workspace_reviewers"
476
+ SET "kind" = 'vercel', "label" = NULL
477
+ WHERE "identity_source" <> 'manual'
478
+ AND "kind" IN ('in_house', 'vendor')
479
+ AND "author_user_id" IN (
480
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('vercel')
481
+ );
482
+ UPDATE "workspace_reviewers"
483
+ SET "kind" = 'welcome_bot', "label" = NULL
484
+ WHERE "identity_source" <> 'manual'
485
+ AND "kind" IN ('in_house', 'vendor')
486
+ AND "author_user_id" IN (
487
+ SELECT "id" FROM "users" WHERE regexp_replace(lower("github_login"), '\[bot\]$', '') IN ('welcome')
488
+ );
@@ -0,0 +1,8 @@
1
+ -- Auto-merge ("merge when ready") gets a machine-readable phase — the Postgres twin of sqlite
2
+ -- 0055_auto_merge_phase.sql. HAND-WRITTEN ADDITIVE, like every pg migration since 0023: never
3
+ -- regenerate the baseline with `pnpm db:generate:pg`, which squashes it.
4
+ --
5
+ -- See the sqlite twin for the full argument. In short: `last_reason` is prose for a human (and
6
+ -- is NULL at success), so the cross-PR progress surface needs a field it can switch on; the
7
+ -- watcher writes both in the same call, and terminal outcomes stay on `state`.
8
+ ALTER TABLE "auto_merge_requests" ADD COLUMN IF NOT EXISTS "phase" text;
@@ -0,0 +1,19 @@
1
+ -- Postgres twin of migrations/0056_pr_mentions.sql — "@you" on a PR, the MENTION arm of My
2
+ -- Turn's personal-relevance rule (CORE, no AI). HAND-WRITTEN ADDITIVE, like every pg migration
3
+ -- since 0023: never regenerate the baseline with `pnpm db:generate:pg`, which squashes it.
4
+ -- Index names are byte-identical to the sqlite twin (they are the drizzle index names).
5
+ CREATE TABLE IF NOT EXISTS "pr_mentions" (
6
+ "id" serial PRIMARY KEY NOT NULL,
7
+ "account_id" integer NOT NULL,
8
+ "repo_id" integer NOT NULL,
9
+ "pr_id" integer NOT NULL,
10
+ "login" text NOT NULL,
11
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
12
+ );
13
+ --> statement-breakpoint
14
+ ALTER TABLE "pr_mentions" ADD CONSTRAINT "pr_mentions_account_id_accounts_id_fk" FOREIGN KEY ("account_id") REFERENCES "public"."accounts"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
15
+ ALTER TABLE "pr_mentions" ADD CONSTRAINT "pr_mentions_repo_id_repos_id_fk" FOREIGN KEY ("repo_id") REFERENCES "public"."repos"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
16
+ ALTER TABLE "pr_mentions" ADD CONSTRAINT "pr_mentions_pr_id_pull_requests_id_fk" FOREIGN KEY ("pr_id") REFERENCES "public"."pull_requests"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
17
+ CREATE UNIQUE INDEX IF NOT EXISTS "prm_account_pr" ON "pr_mentions" USING btree ("account_id","pr_id");--> statement-breakpoint
18
+ CREATE INDEX IF NOT EXISTS "prm_account_repo_idx" ON "pr_mentions" USING btree ("account_id","repo_id");--> statement-breakpoint
19
+ CREATE INDEX IF NOT EXISTS "prm_pr_idx" ON "pr_mentions" USING btree ("pr_id");
@@ -0,0 +1,6 @@
1
+ -- Postgres twin of migrations/0057_large_pr_threshold.sql — the LARGE-PR FLAG's per-account
2
+ -- code-churn threshold (CORE, free, no AI). HAND-WRITTEN ADDITIVE, like every pg migration since
3
+ -- 0023: never regenerate the baseline with `pnpm db:generate:pg`, which squashes it.
4
+ -- Nullable, no default, no backfill: NULL = use the 1,500-line product default (see the sqlite
5
+ -- twin for why that is deliberately not a backfilled literal).
6
+ ALTER TABLE "accounts" ADD COLUMN IF NOT EXISTS "large_pr_code_loc_threshold" integer;
@@ -0,0 +1,26 @@
1
+ -- Postgres twin of migrations/0058_pending_mute.sql — THE PENDING MUTE (CORE, free, no AI).
2
+ -- HAND-WRITTEN ADDITIVE, like every pg migration since 0023: never regenerate the baseline with
3
+ -- `pnpm db:generate:pg`, which squashes it. Index and constraint names are byte-identical to the
4
+ -- sqlite twin (they are the drizzle names).
5
+ --
6
+ -- Read the sqlite twin for the full argument. The three things that will otherwise be re-litigated:
7
+ -- • a mute is NOT the `repos.inbox_watch` visibility axis migration 0046 dropped — no screen's
8
+ -- population changes, only whether a row may CLAIM THE READER'S TURN and interrupt them;
9
+ -- • the workspace flag and the repo rows are TWO INDEPENDENT FACTS, OR-ed, never a fallback
10
+ -- chain (`null`-means-inherit is a named bug class here);
11
+ -- • `pending_muted_repos` carries no `workspace_id` on purpose — a repo belongs to exactly one
12
+ -- workspace already, and a fact lives at exactly one grain.
13
+ ALTER TABLE "workspaces" ADD COLUMN IF NOT EXISTS "pending_muted" boolean DEFAULT false NOT NULL;--> statement-breakpoint
14
+ CREATE TABLE IF NOT EXISTS "pending_muted_repos" (
15
+ "id" serial PRIMARY KEY NOT NULL,
16
+ "account_id" integer NOT NULL,
17
+ "repo_id" integer NOT NULL,
18
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
19
+ CONSTRAINT "pending_muted_repos_account_id_accounts_id_fk" FOREIGN KEY ("account_id") REFERENCES "accounts"("id") ON DELETE cascade,
20
+ -- The composite tenancy FK, declared INLINE like workspace_repos' pair in pg 0031: `repo_id`
21
+ -- arrives in a request body, so the PAIR is what must exist. It leans on the
22
+ -- `repos_id_account` unique index, which exists for exactly this purpose.
23
+ CONSTRAINT "pending_muted_repos_repo_account_fk" FOREIGN KEY ("repo_id","account_id") REFERENCES "repos"("id","account_id") ON DELETE cascade
24
+ );
25
+ --> statement-breakpoint
26
+ CREATE UNIQUE INDEX IF NOT EXISTS "pending_muted_repos_account_repo" ON "pending_muted_repos" USING btree ("account_id","repo_id");