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,156 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="theme-color" content="#FAFAF8" />
|
|
7
|
+
|
|
8
|
+
<!-- Primary SEO. Everything between the seo:start/seo:end markers is REPLACED
|
|
9
|
+
per route at build time by prerender.mjs, from the ROUTE_SEO table in
|
|
10
|
+
src/lib/routes.ts — so /pricing ships its own title, description and
|
|
11
|
+
canonical in the HTML rather than inheriting the home page's. What is
|
|
12
|
+
written here is the home-page copy and the dev-server fallback; keep the
|
|
13
|
+
markers, and keep the copy in sync with ROUTE_SEO['/']. -->
|
|
14
|
+
<title>Cookie policy — Limn</title>
|
|
15
|
+
<meta name="description" content="Every cookie Limn sets, what it does, how long it lasts, and a one-click control to change your analytics choice." />
|
|
16
|
+
<meta name="robots" content="index, follow" />
|
|
17
|
+
<link rel="canonical" href="https://pierre-review.com/cookies" />
|
|
18
|
+
<meta property="og:type" content="website" />
|
|
19
|
+
<meta property="og:site_name" content="Limn" />
|
|
20
|
+
<meta property="og:title" content="Cookie policy — Limn" />
|
|
21
|
+
<meta property="og:description" content="Every cookie Limn sets, what it does, how long it lasts, and a one-click control to change your analytics choice." />
|
|
22
|
+
<meta property="og:url" content="https://pierre-review.com/cookies" />
|
|
23
|
+
<meta property="og:image" content="https://pierre-review.com/og-image.png" />
|
|
24
|
+
<meta property="og:image:width" content="1200" />
|
|
25
|
+
<meta property="og:image:height" content="630" />
|
|
26
|
+
<meta property="og:image:alt" content="The Limn board showing everything waiting across a team’s repositories, ranked most actionable first." />
|
|
27
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
28
|
+
<meta name="twitter:title" content="Cookie policy — Limn" />
|
|
29
|
+
<meta name="twitter:description" content="Every cookie Limn sets, what it does, how long it lasts, and a one-click control to change your analytics choice." />
|
|
30
|
+
<meta name="twitter:image" content="https://pierre-review.com/og-image.png" />
|
|
31
|
+
<meta name="twitter:image:alt" content="The Limn board showing everything waiting across a team’s repositories, ranked most actionable first." />
|
|
32
|
+
|
|
33
|
+
<!-- Favicons: the Limn mark, rendered from apps/landing/src/lib/sprites.ts by
|
|
34
|
+
`node scripts/make-favicons.mjs`. Regenerate there, never by hand. -->
|
|
35
|
+
<!-- ⚠ THE SVG MUST STAY FIRST AND KEEP ITS `type`. A tab slot is 16 CSS px — 32 device px
|
|
36
|
+
at DPR 2 — and Chrome picks ONE of these and scales it, so any pick but an exact 1:1
|
|
37
|
+
raster resamples a grid whose features are one pixel wide and reads as blur. Declared
|
|
38
|
+
this way Chrome takes the SVG and `shape-rendering: crispEdges` snaps it to the device
|
|
39
|
+
grid at every DPR. The PNGs remain for Safari < 16.4 and the big-raster surfaces. -->
|
|
40
|
+
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
|
41
|
+
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" />
|
|
42
|
+
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16.png" />
|
|
43
|
+
<link rel="icon" type="image/png" sizes="48x48" href="/favicon-48.png" />
|
|
44
|
+
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
|
45
|
+
<link rel="manifest" href="/site.webmanifest" />
|
|
46
|
+
|
|
47
|
+
<!-- Structured data: helps search engines understand what Limn is.
|
|
48
|
+
LANDMINE: this block sits OUTSIDE the seo:start/end markers, so the
|
|
49
|
+
prerenderer copies it verbatim into EVERY route — /privacy and /terms ship
|
|
50
|
+
this price too. It is a second, site-wide copy of both the product name
|
|
51
|
+
and the price; when either changes it must change here as well as in
|
|
52
|
+
src/lib/routes.ts, src/lib/site.ts and src/components/feint/TierTable.tsx.
|
|
53
|
+
⚠ IT WENT STALE ONCE ALREADY: it advertised Pro at $15 and a Pro+ tier at
|
|
54
|
+
$29 for as long as those were true on a pricing page that no longer
|
|
55
|
+
exists, which is exactly the failure a second copy invites.
|
|
56
|
+
Claude Review and AI Fix are FREE and local-only — they belong in the Free
|
|
57
|
+
offer, never the Pro one (they were "Pro+" once; that tier is gone).
|
|
58
|
+
The $25 stays because it is the real LIST price and the tier table says so;
|
|
59
|
+
the free month is described in the offer text rather than by writing "0",
|
|
60
|
+
which would be a different and wrong claim about what Pro costs. -->
|
|
61
|
+
<script type="application/ld+json">
|
|
62
|
+
{
|
|
63
|
+
"@context": "https://schema.org",
|
|
64
|
+
"@graph": [
|
|
65
|
+
{
|
|
66
|
+
"@type": "Organization",
|
|
67
|
+
"@id": "https://pierre-review.com/#org",
|
|
68
|
+
"name": "Limn",
|
|
69
|
+
"url": "https://pierre-review.com/",
|
|
70
|
+
"logo": "https://pierre-review.com/icon-512.png",
|
|
71
|
+
"sameAs": ["https://github.com/alexwakeman/pierre-review"]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"@type": "WebSite",
|
|
75
|
+
"@id": "https://pierre-review.com/#site",
|
|
76
|
+
"name": "Limn",
|
|
77
|
+
"url": "https://pierre-review.com/",
|
|
78
|
+
"publisher": { "@id": "https://pierre-review.com/#org" }
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"@type": "SoftwareApplication",
|
|
82
|
+
"name": "Limn",
|
|
83
|
+
"applicationCategory": "DeveloperApplication",
|
|
84
|
+
"operatingSystem": "Web, macOS, Linux, Windows",
|
|
85
|
+
"description": "Plans your day across every repository a team works in: one ranked board of what is waiting and on whom, by rules each person sets — plus how the work moved over a sprint, and an independent grade on every AI review bot comment.",
|
|
86
|
+
"url": "https://pierre-review.com/",
|
|
87
|
+
"publisher": { "@id": "https://pierre-review.com/#org" },
|
|
88
|
+
"offers": {
|
|
89
|
+
"@type": "AggregateOffer",
|
|
90
|
+
"priceCurrency": "USD",
|
|
91
|
+
"lowPrice": "0",
|
|
92
|
+
"highPrice": "25",
|
|
93
|
+
"offerCount": "2",
|
|
94
|
+
"offers": [
|
|
95
|
+
{
|
|
96
|
+
"@type": "Offer",
|
|
97
|
+
"name": "Free",
|
|
98
|
+
"description": "The open-core product: the ranked cross-repo Pending board and every setting behind it, triaged review threads, merge and conflict resolution in place, flow metrics per workspace, an independent grade on every bot comment, and — run locally — Claude Review and AI Fix on your own Claude Code or Anthropic API key, with no charge from Limn. No repository limit, no user limit, no expiry.",
|
|
99
|
+
"price": "0",
|
|
100
|
+
"priceCurrency": "USD"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"@type": "Offer",
|
|
104
|
+
"name": "Pro",
|
|
105
|
+
"description": "The roll-up across repositories, people and periods: a forwardable report per sprint, Chronology, the per-bot keep / tune / noisy scoreboard and the peer benchmark, plus written summaries on pull requests, a read on a failed build and a written plan for the day. Claude Review and AI Fix are not part of it: they are free. Lists at $25 per user per month; currently free for a month to anyone who asks via the contact form.",
|
|
106
|
+
"price": "25",
|
|
107
|
+
"priceCurrency": "USD",
|
|
108
|
+
"priceSpecification": {
|
|
109
|
+
"@type": "UnitPriceSpecification",
|
|
110
|
+
"price": "25",
|
|
111
|
+
"priceCurrency": "USD",
|
|
112
|
+
"billingIncrement": 1,
|
|
113
|
+
"unitText": "MONTH"
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
"softwareHelp": "https://github.com/alexwakeman/pierre-review"
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
</script>
|
|
123
|
+
|
|
124
|
+
<!-- The three typefaces (Archivo, Newsreader, JetBrains Mono) are SELF-HOSTED:
|
|
125
|
+
the @font-face blocks live in src/index.css and the .woff2 files ship from
|
|
126
|
+
src/fonts/. They are never fetched from Google, for three independent
|
|
127
|
+
reasons — `font-src 'self'` in the landing CSP blocks fonts.gstatic.com,
|
|
128
|
+
`style-src 'self' 'unsafe-inline'` does not permit a <link> to
|
|
129
|
+
fonts.googleapis.com, and a test pins that directive so it fails CI before
|
|
130
|
+
a browser ever sees it. On top of that it is a GDPR requirement: a gstatic
|
|
131
|
+
request discloses every visitor's IP to Google before consent, and Google
|
|
132
|
+
Fonts' recommended <link ... onload="this.media='all'"> would force
|
|
133
|
+
script-src 'unsafe-inline'. Same-origin + font-display:swap keeps them off
|
|
134
|
+
the critical path with no inline handler.
|
|
135
|
+
See apps/backend/src/api/plugins/security.ts. -->
|
|
136
|
+
<script type="module" crossorigin src="/assets/index-CA3eEGXO.js"></script>
|
|
137
|
+
<link rel="stylesheet" crossorigin href="/assets/index-naQrQ6Fe.css">
|
|
138
|
+
</head>
|
|
139
|
+
<body>
|
|
140
|
+
<!-- Everything between app:start/app:end is REPLACED at build time by
|
|
141
|
+
prerender.mjs with the route's fully-rendered markup, so the page has real,
|
|
142
|
+
readable content before a single byte of JS executes — for no-JS visitors,
|
|
143
|
+
for AI agents and crawlers that do not run scripts, and as the first paint
|
|
144
|
+
for everyone else. React's createRoot() replaces it on mount exactly as it
|
|
145
|
+
replaced the splash below.
|
|
146
|
+
|
|
147
|
+
What survives here is the DEV-server fallback (prerender.mjs only rewrites
|
|
148
|
+
the built dist/): a plain wordmark on paper, so the first paint is already
|
|
149
|
+
the right colour instead of a white flash. It is set in system-ui rather
|
|
150
|
+
than Archivo because the bundled font has not loaded at this point — and it
|
|
151
|
+
carries no animation, because the site does not move. -->
|
|
152
|
+
<div id="root">
|
|
153
|
+
<div class="mx-auto min-h-screen max-w-canvas"><header class="border-b border-rule px-gutter py-[26px]"><nav aria-label="Primary" class="flex flex-wrap items-baseline justify-between gap-x-6 gap-y-4"><a href="/" aria-label="Home" class="focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink"><span class="inline-flex items-center gap-2.5 font-display font-semibold tracking-[-0.02em] text-ink text-[21px]"><svg width="22" height="18" viewBox="0 0 11 9" shape-rendering="crispEdges" aria-hidden="true" focusable="false" class="shrink-0"><rect x="0" y="0" width="6" height="1" fill="#16161A"></rect><rect x="0" y="1" width="1" height="1" fill="#16161A"></rect><rect x="2" y="1" width="2" height="1" fill="#16161A"></rect><rect x="5" y="1" width="1" height="1" fill="#16161A"></rect><rect x="0" y="2" width="6" height="1" fill="#16161A"></rect><rect x="1" y="3" width="1" height="1" fill="#16161A"></rect><rect x="3" y="4" width="7" height="1" fill="#16161A"></rect><rect x="3" y="5" width="1" height="1" fill="#16161A"></rect><rect x="9" y="5" width="1" height="1" fill="#16161A"></rect><rect x="3" y="6" width="1" height="1" fill="#16161A"></rect><rect x="5" y="6" width="3" height="1" fill="#C13A20"></rect><rect x="9" y="6" width="1" height="1" fill="#16161A"></rect><rect x="3" y="7" width="7" height="1" fill="#16161A"></rect><rect x="5" y="8" width="1" height="1" fill="#16161A"></rect></svg><span>Limn<span class="text-signal-text">.</span></span></span></a><div class="flex flex-wrap items-baseline gap-x-5 gap-y-2 font-mono text-mono-nav text-nav-idle type:gap-x-[30px]"><a href="/for-developers" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">For developers</a><a href="/for-managers" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">For managers</a><a href="/how-we-measure" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">How we measure</a><a href="/contact" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Contact</a><a href="/api/auth/login" class="text-ink border-b-2 border-signal-fill pb-0.5 text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Sign in</a></div></nav></header><main><div class="max-w-[78ch] px-gutter py-16"><h1 class="font-display text-h2-sm font-semibold text-ink type:text-h2-minor">Cookie policy</h1><p class="mt-3.5 font-mono text-mono-label uppercase text-secondary">Last updated 13 September 2026</p><div class="mt-6 space-y-3.5 text-body-sm"><p>Limn sets four cookies in total. Two are needed to keep you signed in, one exists for ten minutes during a GitHub sign-in, and one is analytics — which only ever appears if you agreed to it.</p><div class="mt-5"><div class="border-t border-ink bg-paper-alt px-5 py-4"><p class="font-mono text-mono-label uppercase text-secondary">Your current choice</p><div class="mt-2.5 space-y-2 text-list"><p>You have not made a choice yet, so no analytics cookies are set.</p><button type="button" class="mt-2 border border-ink px-4 py-2 font-display text-[15px] font-semibold text-ink transition-colors duration-hover ease-standard hover:bg-ink hover:text-paper focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Change my choice</button></div></div></div></div><div class="mt-10 space-y-10"><section id="list" class="scroll-mt-16 border-t border-rule pt-7"><h2 class="font-display text-h4 font-semibold text-ink">Every cookie, in full</h2><div class="mt-3.5 space-y-3.5 text-body-sm"><div class="overflow-x-auto border border-rule"><table class="w-full min-w-[36rem] border-collapse text-left text-list"><thead><tr class="border-b border-rule bg-paper-alt"><th class="px-3.5 py-3 font-mono text-mono-label uppercase text-secondary">Name</th><th class="px-3.5 py-3 font-mono text-mono-label uppercase text-secondary">Type</th><th class="px-3.5 py-3 font-mono text-mono-label uppercase text-secondary">Purpose</th><th class="px-3.5 py-3 font-mono text-mono-label uppercase text-secondary">Lifetime</th></tr></thead><tbody><tr class="border-b border-rule-hair align-top last:border-0"><td class="px-3.5 py-3"><span class="font-mono text-xs">pierre_session</span></td><td class="px-3.5 py-3">Strictly necessary</td><td class="px-3.5 py-3">Keeps you signed in to the hosted app. Cryptographically sealed and HTTP-only, so page scripts cannot read it. Contains only your internal account id.</td><td class="px-3.5 py-3">30 days</td></tr><tr class="border-b border-rule-hair align-top last:border-0"><td class="px-3.5 py-3"><span class="font-mono text-xs">pierre_oauth_state</span></td><td class="px-3.5 py-3">Strictly necessary</td><td class="px-3.5 py-3">A one-time random value that proves a GitHub sign-in was started by you and not by another site. Set when you click Sign in, deleted the moment you come back.</td><td class="px-3.5 py-3">10 minutes</td></tr><tr class="border-b border-rule-hair align-top last:border-0"><td class="px-3.5 py-3"><span class="font-mono text-xs">_ga</span></td><td class="px-3.5 py-3">Analytics — consent required</td><td class="px-3.5 py-3">Google Analytics: distinguishes one visitor from another so page views can be counted.</td><td class="px-3.5 py-3">2 years</td></tr><tr class="border-b border-rule-hair align-top last:border-0"><td class="px-3.5 py-3"><span class="font-mono text-xs">_ga_<ID></span></td><td class="px-3.5 py-3">Analytics — consent required</td><td class="px-3.5 py-3">Google Analytics: keeps session state for this specific property.</td><td class="px-3.5 py-3">2 years</td></tr></tbody></table></div><p>Limn also uses your browser's <span class="font-display font-semibold text-ink">local storage</span> — not cookies — to remember interface preferences (which rows you collapsed, how tall the detail pane is, your cookie choice itself) and to cache pull-request detail so the app feels fast. None of it is transmitted anywhere and it never leaves your device.</p></div></section><section id="necessary" class="scroll-mt-16 border-t border-rule pt-7"><h2 class="font-display text-h4 font-semibold text-ink">Why two of them can't be declined</h2><div class="mt-3.5 space-y-3.5 text-body-sm"><p>The two <span class="font-mono text-xs">pierre_*</span> cookies are what the law calls strictly necessary: they exist solely to deliver something you explicitly asked for (being signed in, and being signed in <em>safely</em>). There is no version of the hosted app that works without them, and they carry no tracking value — one holds an account number, the other a random string that is thrown away seconds later. That is why they are set without asking.</p><p>If you would rather not have them at all, run Limn locally instead. There is no session, no sign-in and no server.</p></div></section><section id="analytics" class="scroll-mt-16 border-t border-rule pt-7"><h2 class="font-display text-h4 font-semibold text-ink">The analytics cookies, and how they behave</h2><div class="mt-3.5 space-y-3.5 text-body-sm"><ul class="ml-5 list-disc space-y-2 text-body-sm"><li><span class="font-display font-semibold text-ink">Nothing loads before you agree.</span> Decline, and the Google Analytics script is never downloaded — so Google is not contacted at all, not even to be told you refused.</li><li><span class="font-display font-semibold text-ink">Declining costs you nothing.</span> Every feature works identically. There is no nag, no reduced functionality, and the banner does not come back.</li><li><span class="font-display font-semibold text-ink">Advertising signals are off.</span> Google Signals and ad personalisation are explicitly disabled, so the data cannot be joined to an advertising profile or used for remarketing.</li><li><span class="font-display font-semibold text-ink">Changing your mind deletes the cookies.</span> Withdrawing consent expires <span class="font-mono text-xs">_ga</span> and <span class="font-mono text-xs">_ga_<ID></span> on your device immediately and stops all further measurement.</li></ul><p>Google is the recipient of this data and acts as our processor; the transfer is to the United States. See §§2 and 5 of the <a href="/privacy" class="border-b border-signal-fill text-ink transition-colors duration-hover ease-standard hover:text-signal-text">privacy policy</a> for the legal detail.</p></div></section><section id="self-hosted" class="scroll-mt-16 border-t border-rule pt-7"><h2 class="font-display text-h4 font-semibold text-ink">Self-hosted and local installs</h2><div class="mt-3.5 space-y-3.5 text-body-sm"><p>If you run Limn yourself, analytics is not configured at all unless you supply your own measurement id at build time — so the banner never appears and no analytics cookie is ever set. The local desktop mode has no sign-in, so it sets neither session cookie either. A local install sets <span class="font-display font-semibold text-ink">no cookies whatsoever</span>.</p></div></section><section id="browser" class="scroll-mt-16 border-t border-rule pt-7"><h2 class="font-display text-h4 font-semibold text-ink">Browser-level controls</h2><div class="mt-3.5 space-y-3.5 text-body-sm"><p>You can also block or delete cookies in your browser's settings, or use Google's own <a href="https://tools.google.com/dlpage/gaoptout" target="_blank" rel="noreferrer noopener" class="border-b border-signal-fill text-ink transition-colors duration-hover ease-standard hover:text-signal-text">Analytics opt-out extension</a>. Blocking the two necessary cookies will sign you out of the hosted app.</p><p>Questions about any of this: <a href="mailto:wakemana@gmail.com" class="border-b border-signal-fill text-ink transition-colors duration-hover ease-standard hover:text-signal-text focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">wakemana@gmail.com</a>.</p></div></section></div></div></main><footer class="border-t border-rule px-gutter py-[26px] font-mono text-mono-caption text-secondary"><div class="flex flex-wrap items-baseline justify-between gap-x-8 gap-y-3"><span>© 2026 Limn. Built for sprint situational awareness.</span><span class="flex flex-wrap items-baseline gap-x-5 gap-y-2"><a href="/for-developers" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">For developers</a><a href="/for-managers" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">For managers</a><a href="/how-we-measure" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">How we measure</a><a href="/contact" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Contact</a><a href="https://github.com/alexwakeman/pierre-review" target="_blank" rel="noreferrer noopener" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">GitHub</a><a href="/privacy" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Privacy</a><a href="/cookies" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Cookies</a><a href="/terms" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Terms</a></span></div><p class="mt-4 max-w-caption">Limn is a desktop experience today. A phone-friendly build is planned.</p></footer></div>
|
|
154
|
+
</div>
|
|
155
|
+
</body>
|
|
156
|
+
</html>
|
|
Binary file
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "feed",
|
|
4
|
+
"startMs": 0,
|
|
5
|
+
"endMs": 4375,
|
|
6
|
+
"title": "Feed",
|
|
7
|
+
"text": "Every repository in one stream: pull requests, reviews, comments and builds."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": "timeline",
|
|
11
|
+
"startMs": 4375,
|
|
12
|
+
"endMs": 8875,
|
|
13
|
+
"title": "Timeline",
|
|
14
|
+
"text": "The same work on a clock. Who opened what, when a review landed, what has been sitting."
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "pr-detail",
|
|
18
|
+
"startMs": 8875,
|
|
19
|
+
"endMs": 13374,
|
|
20
|
+
"title": "One pull request",
|
|
21
|
+
"text": "Review standing, every bot that has looked at it, and whether it can land."
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "addressed",
|
|
25
|
+
"startMs": 13374,
|
|
26
|
+
"endMs": 18208,
|
|
27
|
+
"title": "Was it dealt with?",
|
|
28
|
+
"text": "A bot raised a concern and the branch moved on. This reads the diff since, and says what is still open."
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "bots",
|
|
32
|
+
"startMs": 18208,
|
|
33
|
+
"endMs": 23625,
|
|
34
|
+
"title": "Bots",
|
|
35
|
+
"text": "Every review bot: how much it says, how much your team acts on, and how often it overstated a finding."
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"id": "reports",
|
|
39
|
+
"startMs": 23625,
|
|
40
|
+
"endMs": 28123,
|
|
41
|
+
"title": "Reports",
|
|
42
|
+
"text": "Throughput, lead time and review load, with people counted apart from automation."
|
|
43
|
+
}
|
|
44
|
+
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" shape-rendering="crispEdges">
|
|
2
|
+
<rect width="16" height="16" fill="#020711"/>
|
|
3
|
+
<g fill="#f3f4f6"><rect x="2" y="3" width="6" height="1"/><rect x="2" y="4" width="1" height="1"/><rect x="4" y="4" width="2" height="1"/><rect x="7" y="4" width="1" height="1"/><rect x="2" y="5" width="6" height="1"/><rect x="3" y="6" width="1" height="1"/><rect x="5" y="7" width="7" height="1"/><rect x="5" y="8" width="1" height="1"/><rect x="11" y="8" width="1" height="1"/><rect x="5" y="9" width="1" height="1"/><rect x="11" y="9" width="1" height="1"/><rect x="5" y="10" width="7" height="1"/><rect x="7" y="11" width="1" height="1"/></g>
|
|
4
|
+
<g fill="#f26b4e"><rect x="7" y="9" width="3" height="1"/></g>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="theme-color" content="#FAFAF8" />
|
|
7
|
+
|
|
8
|
+
<!-- Primary SEO. Everything between the seo:start/seo:end markers is REPLACED
|
|
9
|
+
per route at build time by prerender.mjs, from the ROUTE_SEO table in
|
|
10
|
+
src/lib/routes.ts — so /pricing ships its own title, description and
|
|
11
|
+
canonical in the HTML rather than inheriting the home page's. What is
|
|
12
|
+
written here is the home-page copy and the dev-server fallback; keep the
|
|
13
|
+
markers, and keep the copy in sync with ROUTE_SEO['/']. -->
|
|
14
|
+
<title>For developers — plan your day, by your own rules</title>
|
|
15
|
+
<meta name="description" content="A red build, two reviews waiting, a reply on a thread you had moved on from, a conflict that appeared overnight. Limn puts all of it on one board across every repository, ranked, with what to do next at the top. You decide what counts as your turn and how it is ordered, then finish the work in place — reply, approve, merge, resolve the conflict. Claude reviews and fixes pull requests on your own Claude Code or Anthropic API key, on your machine. Free, with no repository limit." />
|
|
16
|
+
<meta name="robots" content="index, follow" />
|
|
17
|
+
<link rel="canonical" href="https://pierre-review.com/for-developers" />
|
|
18
|
+
<meta property="og:type" content="website" />
|
|
19
|
+
<meta property="og:site_name" content="Limn" />
|
|
20
|
+
<meta property="og:title" content="For developers — plan your day, by your own rules" />
|
|
21
|
+
<meta property="og:description" content="A red build, two reviews waiting, a reply on a thread you had moved on from, a conflict that appeared overnight. Limn puts all of it on one board across every repository, ranked, with what to do next at the top. You decide what counts as your turn and how it is ordered, then finish the work in place — reply, approve, merge, resolve the conflict. Claude reviews and fixes pull requests on your own Claude Code or Anthropic API key, on your machine. Free, with no repository limit." />
|
|
22
|
+
<meta property="og:url" content="https://pierre-review.com/for-developers" />
|
|
23
|
+
<meta property="og:image" content="https://pierre-review.com/og-image.png" />
|
|
24
|
+
<meta property="og:image:width" content="1200" />
|
|
25
|
+
<meta property="og:image:height" content="630" />
|
|
26
|
+
<meta property="og:image:alt" content="The Limn board showing everything waiting across a team’s repositories, ranked most actionable first." />
|
|
27
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
28
|
+
<meta name="twitter:title" content="For developers — plan your day, by your own rules" />
|
|
29
|
+
<meta name="twitter:description" content="A red build, two reviews waiting, a reply on a thread you had moved on from, a conflict that appeared overnight. Limn puts all of it on one board across every repository, ranked, with what to do next at the top. You decide what counts as your turn and how it is ordered, then finish the work in place — reply, approve, merge, resolve the conflict. Claude reviews and fixes pull requests on your own Claude Code or Anthropic API key, on your machine. Free, with no repository limit." />
|
|
30
|
+
<meta name="twitter:image" content="https://pierre-review.com/og-image.png" />
|
|
31
|
+
<meta name="twitter:image:alt" content="The Limn board showing everything waiting across a team’s repositories, ranked most actionable first." />
|
|
32
|
+
|
|
33
|
+
<!-- Favicons: the Limn mark, rendered from apps/landing/src/lib/sprites.ts by
|
|
34
|
+
`node scripts/make-favicons.mjs`. Regenerate there, never by hand. -->
|
|
35
|
+
<!-- ⚠ THE SVG MUST STAY FIRST AND KEEP ITS `type`. A tab slot is 16 CSS px — 32 device px
|
|
36
|
+
at DPR 2 — and Chrome picks ONE of these and scales it, so any pick but an exact 1:1
|
|
37
|
+
raster resamples a grid whose features are one pixel wide and reads as blur. Declared
|
|
38
|
+
this way Chrome takes the SVG and `shape-rendering: crispEdges` snaps it to the device
|
|
39
|
+
grid at every DPR. The PNGs remain for Safari < 16.4 and the big-raster surfaces. -->
|
|
40
|
+
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
|
41
|
+
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" />
|
|
42
|
+
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16.png" />
|
|
43
|
+
<link rel="icon" type="image/png" sizes="48x48" href="/favicon-48.png" />
|
|
44
|
+
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
|
45
|
+
<link rel="manifest" href="/site.webmanifest" />
|
|
46
|
+
|
|
47
|
+
<!-- Structured data: helps search engines understand what Limn is.
|
|
48
|
+
LANDMINE: this block sits OUTSIDE the seo:start/end markers, so the
|
|
49
|
+
prerenderer copies it verbatim into EVERY route — /privacy and /terms ship
|
|
50
|
+
this price too. It is a second, site-wide copy of both the product name
|
|
51
|
+
and the price; when either changes it must change here as well as in
|
|
52
|
+
src/lib/routes.ts, src/lib/site.ts and src/components/feint/TierTable.tsx.
|
|
53
|
+
⚠ IT WENT STALE ONCE ALREADY: it advertised Pro at $15 and a Pro+ tier at
|
|
54
|
+
$29 for as long as those were true on a pricing page that no longer
|
|
55
|
+
exists, which is exactly the failure a second copy invites.
|
|
56
|
+
Claude Review and AI Fix are FREE and local-only — they belong in the Free
|
|
57
|
+
offer, never the Pro one (they were "Pro+" once; that tier is gone).
|
|
58
|
+
The $25 stays because it is the real LIST price and the tier table says so;
|
|
59
|
+
the free month is described in the offer text rather than by writing "0",
|
|
60
|
+
which would be a different and wrong claim about what Pro costs. -->
|
|
61
|
+
<script type="application/ld+json">
|
|
62
|
+
{
|
|
63
|
+
"@context": "https://schema.org",
|
|
64
|
+
"@graph": [
|
|
65
|
+
{
|
|
66
|
+
"@type": "Organization",
|
|
67
|
+
"@id": "https://pierre-review.com/#org",
|
|
68
|
+
"name": "Limn",
|
|
69
|
+
"url": "https://pierre-review.com/",
|
|
70
|
+
"logo": "https://pierre-review.com/icon-512.png",
|
|
71
|
+
"sameAs": ["https://github.com/alexwakeman/pierre-review"]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"@type": "WebSite",
|
|
75
|
+
"@id": "https://pierre-review.com/#site",
|
|
76
|
+
"name": "Limn",
|
|
77
|
+
"url": "https://pierre-review.com/",
|
|
78
|
+
"publisher": { "@id": "https://pierre-review.com/#org" }
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"@type": "SoftwareApplication",
|
|
82
|
+
"name": "Limn",
|
|
83
|
+
"applicationCategory": "DeveloperApplication",
|
|
84
|
+
"operatingSystem": "Web, macOS, Linux, Windows",
|
|
85
|
+
"description": "Plans your day across every repository a team works in: one ranked board of what is waiting and on whom, by rules each person sets — plus how the work moved over a sprint, and an independent grade on every AI review bot comment.",
|
|
86
|
+
"url": "https://pierre-review.com/",
|
|
87
|
+
"publisher": { "@id": "https://pierre-review.com/#org" },
|
|
88
|
+
"offers": {
|
|
89
|
+
"@type": "AggregateOffer",
|
|
90
|
+
"priceCurrency": "USD",
|
|
91
|
+
"lowPrice": "0",
|
|
92
|
+
"highPrice": "25",
|
|
93
|
+
"offerCount": "2",
|
|
94
|
+
"offers": [
|
|
95
|
+
{
|
|
96
|
+
"@type": "Offer",
|
|
97
|
+
"name": "Free",
|
|
98
|
+
"description": "The open-core product: the ranked cross-repo Pending board and every setting behind it, triaged review threads, merge and conflict resolution in place, flow metrics per workspace, an independent grade on every bot comment, and — run locally — Claude Review and AI Fix on your own Claude Code or Anthropic API key, with no charge from Limn. No repository limit, no user limit, no expiry.",
|
|
99
|
+
"price": "0",
|
|
100
|
+
"priceCurrency": "USD"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"@type": "Offer",
|
|
104
|
+
"name": "Pro",
|
|
105
|
+
"description": "The roll-up across repositories, people and periods: a forwardable report per sprint, Chronology, the per-bot keep / tune / noisy scoreboard and the peer benchmark, plus written summaries on pull requests, a read on a failed build and a written plan for the day. Claude Review and AI Fix are not part of it: they are free. Lists at $25 per user per month; currently free for a month to anyone who asks via the contact form.",
|
|
106
|
+
"price": "25",
|
|
107
|
+
"priceCurrency": "USD",
|
|
108
|
+
"priceSpecification": {
|
|
109
|
+
"@type": "UnitPriceSpecification",
|
|
110
|
+
"price": "25",
|
|
111
|
+
"priceCurrency": "USD",
|
|
112
|
+
"billingIncrement": 1,
|
|
113
|
+
"unitText": "MONTH"
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
"softwareHelp": "https://github.com/alexwakeman/pierre-review"
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
</script>
|
|
123
|
+
|
|
124
|
+
<!-- The three typefaces (Archivo, Newsreader, JetBrains Mono) are SELF-HOSTED:
|
|
125
|
+
the @font-face blocks live in src/index.css and the .woff2 files ship from
|
|
126
|
+
src/fonts/. They are never fetched from Google, for three independent
|
|
127
|
+
reasons — `font-src 'self'` in the landing CSP blocks fonts.gstatic.com,
|
|
128
|
+
`style-src 'self' 'unsafe-inline'` does not permit a <link> to
|
|
129
|
+
fonts.googleapis.com, and a test pins that directive so it fails CI before
|
|
130
|
+
a browser ever sees it. On top of that it is a GDPR requirement: a gstatic
|
|
131
|
+
request discloses every visitor's IP to Google before consent, and Google
|
|
132
|
+
Fonts' recommended <link ... onload="this.media='all'"> would force
|
|
133
|
+
script-src 'unsafe-inline'. Same-origin + font-display:swap keeps them off
|
|
134
|
+
the critical path with no inline handler.
|
|
135
|
+
See apps/backend/src/api/plugins/security.ts. -->
|
|
136
|
+
<script type="module" crossorigin src="/assets/index-CA3eEGXO.js"></script>
|
|
137
|
+
<link rel="stylesheet" crossorigin href="/assets/index-naQrQ6Fe.css">
|
|
138
|
+
</head>
|
|
139
|
+
<body>
|
|
140
|
+
<!-- Everything between app:start/app:end is REPLACED at build time by
|
|
141
|
+
prerender.mjs with the route's fully-rendered markup, so the page has real,
|
|
142
|
+
readable content before a single byte of JS executes — for no-JS visitors,
|
|
143
|
+
for AI agents and crawlers that do not run scripts, and as the first paint
|
|
144
|
+
for everyone else. React's createRoot() replaces it on mount exactly as it
|
|
145
|
+
replaced the splash below.
|
|
146
|
+
|
|
147
|
+
What survives here is the DEV-server fallback (prerender.mjs only rewrites
|
|
148
|
+
the built dist/): a plain wordmark on paper, so the first paint is already
|
|
149
|
+
the right colour instead of a white flash. It is set in system-ui rather
|
|
150
|
+
than Archivo because the bundled font has not loaded at this point — and it
|
|
151
|
+
carries no animation, because the site does not move. -->
|
|
152
|
+
<div id="root">
|
|
153
|
+
<div class="mx-auto min-h-screen max-w-canvas"><header class="border-b border-rule px-gutter py-[26px]"><nav aria-label="Primary" class="flex flex-wrap items-baseline justify-between gap-x-6 gap-y-4"><a href="/" aria-label="Home" class="focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink"><span class="inline-flex items-center gap-2.5 font-display font-semibold tracking-[-0.02em] text-ink text-[21px]"><svg width="22" height="18" viewBox="0 0 11 9" shape-rendering="crispEdges" aria-hidden="true" focusable="false" class="shrink-0"><rect x="0" y="0" width="6" height="1" fill="#16161A"></rect><rect x="0" y="1" width="1" height="1" fill="#16161A"></rect><rect x="2" y="1" width="2" height="1" fill="#16161A"></rect><rect x="5" y="1" width="1" height="1" fill="#16161A"></rect><rect x="0" y="2" width="6" height="1" fill="#16161A"></rect><rect x="1" y="3" width="1" height="1" fill="#16161A"></rect><rect x="3" y="4" width="7" height="1" fill="#16161A"></rect><rect x="3" y="5" width="1" height="1" fill="#16161A"></rect><rect x="9" y="5" width="1" height="1" fill="#16161A"></rect><rect x="3" y="6" width="1" height="1" fill="#16161A"></rect><rect x="5" y="6" width="3" height="1" fill="#C13A20"></rect><rect x="9" y="6" width="1" height="1" fill="#16161A"></rect><rect x="3" y="7" width="7" height="1" fill="#16161A"></rect><rect x="5" y="8" width="1" height="1" fill="#16161A"></rect></svg><span>Limn<span class="text-signal-text">.</span></span></span></a><div class="flex flex-wrap items-baseline gap-x-5 gap-y-2 font-mono text-mono-nav text-nav-idle type:gap-x-[30px]"><a href="/for-developers" aria-current="page" class="border-b-2 border-signal-fill pb-0.5 text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">For developers</a><a href="/for-managers" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">For managers</a><a href="/how-we-measure" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">How we measure</a><a href="/contact" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Contact</a><a href="/api/auth/login" class="text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Sign in</a></div></nav></header><main><header class="px-gutter pt-hero-y"><span class="block font-mono uppercase text-mono-label-wide mb-[26px] text-secondary">For developers</span><h1 class="mb-7 max-w-[20ch] text-pretty font-display text-hero-sm font-semibold text-ink type:text-hero">Plan your day, by your own rules.</h1><p class="mb-[34px] max-w-lede text-pretty text-lede text-ink-soft">A red build on one branch. Two reviews waiting on another. A reply on a thread you had moved on from, and a conflict that appeared overnight on the one that was ready to land. Limn puts all of it on one board across every repository you work in, ranked, with what to do next at the top. You decide what counts as your turn and how it is ordered — and you finish the work without leaving the page. Claude reviews and fixes pull requests too, on your own Claude, free.</p><div class="mb-4 flex flex-wrap items-center gap-3.5"><a href="/api/auth/login" class="inline-block bg-ink px-6 py-[15px] font-display text-[16px] font-semibold text-paper hover:bg-[#08080A] transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink ">Sign in with GitHub</a><a href="/for-managers" class="inline-block border-b border-ink px-1.5 py-[15px] font-display text-[16px] font-medium text-ink hover:text-signal-text transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink ">If you run the team →</a></div><p class="mb-11 max-w-reassure font-mono text-mono-nav text-secondary">Everything in the next eight sections is free, with no repository limit. Run it on your own machine with <span class="text-ink">npx limn-review</span> and it keeps no credentials at all. Review and fix run only there.</p></header><section class="px-gutter py-section-y border-t border-ink "><div class="grid items-start gap-grid-gutter rail:grid-cols-rail "><div class="mb-6 font-mono text-mono-label uppercase text-secondary rail:mb-0 rail:pt-[10px]"><span class="rail:block">01<span class="rail:hidden"> / </span></span>The day</div><div class="rail:col-span-2"><h2 class="mb-[30px] max-w-[28ch] text-pretty font-display text-h2-sm font-semibold text-ink type:text-h2-major">Your day arrives out of order.</h2><div class="grid gap-grid-gutter rail:grid-cols-2"><div><p class="mb-6">At any moment five different jobs want five different things from you — a build to fix, a review to answer, a thread to reply to, a conflict to clear, one sitting green and ready to land. They are all open, they all have your name on them, and nothing puts them in a sequence.</p><p class="mb-6">Spread that across six repositories — a reviewer on some, an author on others, a maintainer on a couple you rarely open — and layer three or four review bots reading every pull request on top. The volume is not the problem on its own. The problem is that none of it arrives sorted by how much it has to do with you, today.</p><p>GitHub will tell you that something happened. It will not tell you what to do first.</p></div><div><ul class="flex flex-col gap-3.5"><li class="flex gap-3.5 text-body-sm"><span aria-hidden="true" class="pt-1.5 font-mono text-mono-caption text-signal-text">—</span><span>A build went red on the branch you pushed before you logged off.</span></li><li class="flex gap-3.5 text-body-sm"><span aria-hidden="true" class="pt-1.5 font-mono text-mono-caption text-signal-text">—</span><span>Someone answered a thread on a pull request you had already moved on from.</span></li><li class="flex gap-3.5 text-body-sm"><span aria-hidden="true" class="pt-1.5 font-mono text-mono-caption text-signal-text">—</span><span>Two reviews are waiting on you in a repository you only maintain.</span></li><li class="flex gap-3.5 text-body-sm"><span aria-hidden="true" class="pt-1.5 font-mono text-mono-caption text-signal-text">—</span><span>One of yours is ready to land and has been green since yesterday.</span></li><li class="flex gap-3.5 text-body-sm"><span aria-hidden="true" class="pt-1.5 font-mono text-mono-caption text-signal-text">—</span><span>And a conflict appeared overnight on the one you most wanted to finish.</span></li></ul><p class="mt-7 flex items-baseline gap-3.5 border-t border-rule pt-4 font-mono text-mono-nav text-secondary"><span aria-hidden="true" class="text-signal-text">—</span><span><span class="text-ink">Free, always</span> · everything in sections 01 to 08 is in the open-core tier.</span></p></div></div></div></div></section><section class="px-gutter py-section-y border-t border-rule bg-paper-alt "><div class="grid items-start gap-grid-gutter rail:grid-cols-rail-1 "><div class="mb-6 font-mono text-mono-label uppercase text-secondary rail:mb-0 rail:pt-[10px]"><span class="rail:block">02<span class="rail:hidden"> / </span></span>Pending</div><div><h2 class="mb-6 max-w-[30ch] text-pretty font-display text-h2-sm font-semibold text-ink type:text-h2">Your day, planned on one board.</h2><div class="max-w-[68ch]"><p class="mb-6">Pending is the first screen. Six tabs — My turn, Needs fixing, Waiting on review, Unanswered threads, Ready to land and Dependencies — from every repository in the workspace. Each tab is ranked, and its top five are <span class="text-ink">Do next</span>.</p><p class="mb-6">The ordering is code rather than a model: three numbers, added up. By default, half the weight is how close the job is to <em>finished</em> — a two-file change outranks a forty-file one, and a conflict or three unanswered threads pushes a job down rather than up. Three tenths is how long it has been sitting, in fixed steps at one, two and four days. The last fifth is how directly it is tied to you: your name on it, a repository you maintain, or neither. Every card shows its working, and a <span class="text-ink">How Pending works</span> guide explains the rest.</p><p class="mb-6">An approved pull request that can land comes out top. The same one with nobody’s approval on it ranks below a plain review request, deliberately: ranked the other way, the head of the board filled with unreviewed dependency bumps.</p><p class="mb-6">A card exists only while you genuinely owe an action and have not taken it. There is nothing to tick off, because the list is worked out fresh on every read rather than stored: act, and the card leaves on its own. One you can’t act on, you dismiss — it stays gone until something new happens on it.</p><p class="mb-6">The labels are careful about what they claim. <span class="text-ink">Your turn</span> means the work is tied to you. <span class="text-ink">In your repos</span> means somebody opened something on ground you maintain — orbit, not ownership. A card will not tell you a stranger’s pull request is yours.</p><p>The tabs and the order are free on every tier. The <span class="text-ink">Plan my day</span> button in the corner is Pro: it adds the written sentences on top (§09).</p><p class="mt-7 flex items-baseline gap-3.5 border-t border-rule pt-4 font-mono text-mono-nav text-secondary"><span aria-hidden="true" class="text-signal-text">—</span><span><span class="text-ink">09:04</span> · sixty-one items across five repositories, and the first three are the ones you can finish before standup.</span></p></div></div></div><div class="mt-10"><figure class="border border-rule-strong"><figcaption class="flex items-center justify-between border-b border-rule px-4 py-[11px] font-mono text-mono-caption text-secondary"><span>limn · pending</span><button type="button" class="text-signal-text transition-colors duration-hover ease-standard hover:text-ink focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Enlarge</button></figcaption><button type="button" aria-label="Enlarge screenshot: The Pending board across four repositories: ready-to-merge, your-turn and in-your-repos cards, each with its CI state, file counts, reach chip and merge actions" class="block w-full cursor-zoom-in focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ink"><span style="height:640px" class="block w-full overflow-hidden bg-paper"><img src="/shots/pending-board.png" alt="The Pending board across four repositories: ready-to-merge, your-turn and in-your-repos cards, each with its CI state, file counts, reach chip and merge actions" loading="lazy" decoding="async" class="h-full w-full object-cover object-top"/></span></button></figure></div></section><section class="px-gutter py-section-y border-t border-rule "><div class="grid items-start gap-grid-gutter rail:grid-cols-rail "><div class="mb-6 font-mono text-mono-label uppercase text-secondary rail:mb-0 rail:pt-[10px]"><span class="rail:block">03<span class="rail:hidden"> / </span></span>Your rules</div><div class="rail:col-span-2"><h2 class="mb-6 max-w-[28ch] text-pretty font-display text-h2-sm font-semibold text-ink type:text-h2">You decide what counts as your turn, and in what order.</h2><p class="mb-[30px] max-w-[62ch] text-pretty">The rules behind the board are settings. The tabs, the counts and the notifications follow them, and the board explains its order with them. The <span class="text-ink">Customise</span> link on My turn opens them.</p><div class="grid gap-grid-gutter rail:grid-cols-2"><div><h3 class="mb-3 font-display text-h4 font-semibold text-ink">What counts</h3><p class="text-list text-ink-body">Each kind of card has its own switch: review requests, @mentions, replies in threads you started, replies to your comments elsewhere, new commits since you reviewed, approvals and activity on your own pull requests. Switch one off and it leaves My turn, its counts and its notifications together. New pull requests nobody asked you about start off.</p></div><div><h3 class="mb-3 font-display text-h4 font-semibold text-ink">What joins it</h3><p class="text-list text-ink-body">Your own red builds, merge conflicts, pull requests ready to land and unanswered threads can move out of their own tabs into My turn. So can a red default branch, in the repositories you maintain or in all of them. Each of these starts off.</p></div><div><h3 class="mb-3 font-display text-h4 font-semibold text-ink">In what order</h3><p class="text-list text-ink-body">Put My turn’s card types in the order you work through them. Then choose how every tab ranks: <span class="text-ink">Balanced</span>, <span class="text-ink">Mine first</span>, <span class="text-ink">Oldest first</span> or <span class="text-ink">Quick wins</span> — or set the three weights yourself.</p></div><div><h3 class="mb-3 font-display text-h4 font-semibold text-ink">What may interrupt you</h3><p class="text-list text-ink-body">Mute a repository, or a whole workspace. Its cards stay on the board, but they stop saying <span class="text-ink">Your turn</span> and stop notifying you. Notifications only ever fire for work that is yours.</p></div></div><p class="mt-7 flex items-baseline gap-3.5 border-t border-rule pt-4 font-mono text-mono-nav text-secondary"><span aria-hidden="true" class="text-signal-text">—</span><span><span class="text-ink">Free</span> · every one of these, on every tier, running locally or hosted.</span></p></div></div></section><section class="px-gutter py-section-y border-t border-rule "><div class="grid items-start gap-grid-gutter rail:grid-cols-rail "><div class="mb-6 font-mono text-mono-label uppercase text-secondary rail:mb-0 rail:pt-[10px]"><span class="rail:block">04<span class="rail:hidden"> / </span></span>Review and fix</div><div class="rail:col-span-2"><h2 class="mb-6 max-w-[28ch] text-pretty font-display text-h2-sm font-semibold text-ink type:text-h2">Claude reviews it and fixes it. On your own Claude, free.</h2><p class="mb-[30px] max-w-[62ch] text-pretty">Every pull request has a Claude tab. Claude reads the change and writes up what it finds; you decide what reaches GitHub.</p><div class="grid gap-grid-gutter rail:grid-cols-3"><div><h3 class="mb-3 font-display text-h4 font-semibold text-ink">Claude Review</h3><p class="text-list text-ink-body">Findings on the change, each tied to a line. Tick the ones worth keeping and post them as one GitHub review. Paste in the story and it checks the change against it. Switch on auto review for a workspace and new pull requests are reviewed as they arrive.</p></div><div><h3 class="mb-3 font-display text-h4 font-semibold text-ink">Ask Claude</h3><p class="text-list text-ink-body">A chat on the review, and on each finding. Ask why a line was flagged, or whether it matters here. It reads the same code the review did.</p></div><div><h3 class="mb-3 font-display text-h4 font-semibold text-ink">AI Fix</h3><p class="text-list text-ink-body">Pick the review comments you want fixed. It edits a copy of the branch and shows you the diff. It pushes only when you click Push.</p></div></div><div class="mt-10 grid gap-grid-gutter rail:grid-cols-2"><div><h3 class="mb-3 font-display text-h4 font-semibold text-ink">Your Claude, not ours</h3><p class="text-list text-ink-body">It runs on your own Claude Code or Anthropic API key: the Claude Code session you are signed in to, or <span class="text-ink">ANTHROPIC_API_KEY</span>. Limn stores no key and charges nothing for it. The first time, it asks for a one-time download of about 110 MB. It runs on your machine, with <span class="text-ink">npx limn-review</span>.</p></div><div><h3 class="mb-3 font-display text-h4 font-semibold text-ink">What it can do</h3><ul class="flex flex-col gap-3.5"><li class="flex gap-3.5 text-body-sm"><span aria-hidden="true" class="pt-1.5 font-mono text-mono-caption text-signal-text">—</span><span>The reviewer reads the code. It cannot edit files, run commands or reach the web.</span></li><li class="flex gap-3.5 text-body-sm"><span aria-hidden="true" class="pt-1.5 font-mono text-mono-caption text-signal-text">—</span><span>The fixer edits files. It has no shell, so it builds and tests nothing.</span></li><li class="flex gap-3.5 text-body-sm"><span aria-hidden="true" class="pt-1.5 font-mono text-mono-caption text-signal-text">—</span><span>Nothing is posted or pushed until you press the button.</span></li></ul></div></div><p class="mt-7 flex items-baseline gap-3.5 border-t border-rule pt-4 font-mono text-mono-nav text-secondary"><span aria-hidden="true" class="text-signal-text">—</span><span><span class="text-ink">09:07</span> · a review on the pull request you were about to approve; two findings posted, one fixed.</span></p></div></div></section><section class="px-gutter py-section-y border-t border-rule bg-paper-alt "><div class="grid items-start gap-grid-gutter rail:grid-cols-rail-1 "><div class="mb-6 font-mono text-mono-label uppercase text-secondary rail:mb-0 rail:pt-[10px]"><span class="rail:block">05<span class="rail:hidden"> / </span></span>Act in place</div><div><h2 class="mb-6 max-w-[30ch] text-pretty font-display text-h2-sm font-semibold text-ink type:text-h2">Reply, approve, merge — from the board.</h2><div class="max-w-[68ch]"><p class="mb-6">One verdict answers “can this land?” and the action sits on the same row. Merge, or arm <span class="text-ink">merge when ready</span> and it lands the moment checks go green — pinned to the exact commit you looked at, so a new push disarms it rather than merging code you never saw.</p><p class="mb-6">When GitHub refuses and will not say why, the pull request carries a ranked list of what is actually holding it, each line marked <span class="text-ink">proven</span> or <span class="text-ink">inferred</span> — because only some of it is knowable from what GitHub returns, and pretending otherwise is how a tool loses your trust.</p><p class="mb-6">Conflicts are resolved in the app, hunk by hunk: take a side, or edit the result yourself. Free, running locally or hosted.</p><p>The header carries how far the change reaches — low, medium or high, with the reasons written out. It refuses rather than guesses: where GitHub truncated the file list it will assert “high” but never “low”, because a truncated list is always a floor.</p><p class="mt-7 flex items-baseline gap-3.5 border-t border-rule pt-4 font-mono text-mono-nav text-secondary"><span aria-hidden="true" class="text-signal-text">—</span><span><span class="text-ink">09:11</span> · two merged, one armed for when the build finishes, one conflict cleared.</span></p></div></div></div><div class="mt-10"><figure class="border border-rule-strong"><figcaption class="flex items-center justify-between border-b border-rule px-4 py-[11px] font-mono text-mono-caption text-secondary"><span>limn · pull request</span><button type="button" class="text-signal-text transition-colors duration-hover ease-standard hover:text-ink focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Enlarge</button></figcaption><button type="button" aria-label="Enlarge screenshot: A pull request in detail: the merge verdict and its blockers, the reach chip, approve and merge controls, the bot triage grade and the review threads" class="block w-full cursor-zoom-in focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ink"><span style="height:640px" class="block w-full overflow-hidden bg-paper"><img src="/shots/pr-detail.png" alt="A pull request in detail: the merge verdict and its blockers, the reach chip, approve and merge controls, the bot triage grade and the review threads" loading="lazy" decoding="async" class="h-full w-full object-cover object-top"/></span></button></figure></div></section><section class="px-gutter py-section-y border-t border-rule "><div class="grid items-start gap-grid-gutter rail:grid-cols-rail-1 "><div class="mb-6 font-mono text-mono-label uppercase text-secondary rail:mb-0 rail:pt-[10px]"><span class="rail:block">06<span class="rail:hidden"> / </span></span>The threads</div><div><h2 class="mb-6 max-w-[30ch] text-pretty font-display text-h2-sm font-semibold text-ink type:text-h2">Every review thread already triaged.</h2><div class="max-w-[68ch]"><p class="mb-6">Each review thread carries a state worked out from the repository itself: resolved, replied but still open, untouched — or <span class="text-ink">likely addressed</span>, which means a commit touched that file after the comment landed.</p><p class="mb-6">That last one is a heuristic and the interface says so wherever it appears. A rename or an unrelated edit can trip it. It is offered as a shortcut through forty bot threads, never as a verdict.</p><p>Bot comments also arrive already graded for severity, by a classifier trained for this one job — free, and never the vendor’s own badge, which is stored to be shown and not to be believed.</p><p class="mt-7 flex items-baseline gap-3.5 border-t border-rule pt-4 font-mono text-mono-nav text-secondary"><span aria-hidden="true" class="text-signal-text">—</span><span><span class="text-ink">09:19</span> · fifteen threads on one pull request; three still need you, and one button clears the rest.</span></p></div></div></div><div class="mt-10"><figure class="border border-rule"><figcaption class="flex items-center justify-between border-b border-rule px-4 py-[11px] font-mono text-mono-caption text-secondary"><span>limn · threads</span><button type="button" class="text-signal-text transition-colors duration-hover ease-standard hover:text-ink focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Enlarge</button></figcaption><button type="button" aria-label="Enlarge screenshot: A pull request's thread list: each thread carrying a derived state, the vendor that opened it and a severity badge" class="block w-full cursor-zoom-in focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ink"><span style="height:640px" class="block w-full overflow-hidden bg-paper"><img src="/shots/pr-threads.png" alt="A pull request's thread list: each thread carrying a derived state, the vendor that opened it and a severity badge" loading="lazy" decoding="async" class="h-full w-full object-cover object-top"/></span></button></figure></div></section><section class="px-gutter py-section-y border-t border-rule bg-paper-alt "><div class="grid items-start gap-grid-gutter rail:grid-cols-rail-1 "><div class="mb-6 font-mono text-mono-label uppercase text-secondary rail:mb-0 rail:pt-[10px]"><span class="rail:block">07<span class="rail:hidden"> / </span></span>The bots</div><div><h2 class="mb-6 max-w-[30ch] text-pretty font-display text-h2-sm font-semibold text-ink type:text-h2">And the bot comments, graded before you read them.</h2><div class="max-w-[68ch]"><p class="mb-6">Every bot-written comment is graded for severity — nit, minor, major, critical — by a purpose-trained ModernBERT classifier, served as an int8 ONNX artifact. It runs on the CPU you already have: no GPU, no API call, no comment leaving the machine, and nothing metered. Its eight categories come from a separate deterministic pass, so a category is reproducible rather than sampled.</p><p class="mb-6">It is measured, not asserted. We hid every label a batch of real bot comments already carried and had them graded from scratch by a human expert. The model picked the same severity <strong>seven times in ten</strong> — which is exactly how often two human experts agreed with <em>each other</em> on the same comments, so it is reading them about as well as the job allows. CodeRabbit’s own badge matched the expert fewer than five times in ten.</p><p class="mb-6">Which is why the vendor’s badge is stored and shown beside ours and never used as an input. Tuning towards agreement with it measurably moves the model away from ground truth, so the two are drawn apart rather than reconciled.</p><p>Where two bots flagged the same lines, the pull request says so, so you read the finding once.</p><p class="mt-7 flex items-baseline gap-3.5 border-t border-rule pt-4 font-mono text-mono-nav text-secondary"><span aria-hidden="true" class="text-signal-text">—</span><span><span class="text-ink">Nothing auto-acts</span> · on a grade. Critical is under-recalled, so the product buckets major and critical together as “high” and leaves the decision with you.</span></p></div></div></div><div class="mt-10"><figure class="border border-rule-strong"><figcaption class="flex items-center justify-between border-b border-rule px-4 py-[11px] font-mono text-mono-caption text-secondary"><span>limn · what the bots are flagging</span><button type="button" class="text-signal-text transition-colors duration-hover ease-standard hover:text-ink focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Enlarge</button></figcaption><button type="button" aria-label="Enlarge screenshot: What the bots are flagging across the workspace: total findings, the share graded high severity, the share that are nits, and the top categories" class="block w-full cursor-zoom-in focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ink"><span style="height:520px" class="block w-full overflow-hidden bg-paper"><img src="/shots/severity-strip.png" alt="What the bots are flagging across the workspace: total findings, the share graded high severity, the share that are nits, and the top categories" loading="lazy" decoding="async" class="h-full w-full object-contain"/></span></button></figure></div></section><section class="px-gutter py-section-y border-t border-rule "><div class="grid items-start gap-grid-gutter rail:grid-cols-rail "><div class="mb-6 font-mono text-mono-label uppercase text-secondary rail:mb-0 rail:pt-[10px]"><span class="rail:block">08<span class="rail:hidden"> / </span></span>Also free</div><div class="rail:col-span-2"><h2 class="mb-[30px] max-w-[30ch] text-pretty font-display text-h2-sm font-semibold text-ink type:text-h2">And the rest of it, still without paying.</h2><div class="grid gap-grid-gutter rail:grid-cols-3"><div><h3 class="mb-3 font-display text-h4 font-semibold text-ink">The stream</h3><p class="text-list text-ink-body">One chronological feed across every repository in the workspace. Automated accounts are left out until you ask for them, with lenses for red builds and for the kinds of pull-request event you care about.</p></div><div><h3 class="mb-3 font-display text-h4 font-semibold text-ink">Search and the timeline</h3><p class="text-list text-ink-body">Full-text search over titles, bodies and comments in every repository you track, and a timeline that plots a fortnight of work per person per repository so a catch-up is one picture.</p></div><div><h3 class="mb-3 font-display text-h4 font-semibold text-ink">Trunk health</h3><p class="text-list text-ink-body">Whether each repository’s default branch is green, the checks that are failing on it, and what landed there last, for every repository in the workspace.</p></div></div></div></div><div class="mt-10"><figure class="border border-rule"><figcaption class="flex items-center justify-between border-b border-rule px-4 py-[11px] font-mono text-mono-caption text-secondary"><span>limn · feed</span><button type="button" class="text-signal-text transition-colors duration-hover ease-standard hover:text-ink focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Enlarge</button></figcaption><button type="button" aria-label="Enlarge screenshot: The cross-repository activity feed: one chronological stream of opens, reviews, merges and comments across every repository in the workspace" class="block w-full cursor-zoom-in focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ink"><span style="height:520px" class="block w-full overflow-hidden bg-paper"><img src="/shots/feed.png" alt="The cross-repository activity feed: one chronological stream of opens, reviews, merges and comments across every repository in the workspace" loading="lazy" decoding="async" class="h-full w-full object-cover object-top"/></span></button></figure></div></section><section class="px-gutter py-section-y border-t border-ink bg-paper-alt "><div class="grid items-start gap-grid-gutter rail:grid-cols-rail "><div class="mb-6 font-mono text-mono-label uppercase text-secondary rail:mb-0 rail:pt-[10px]"><span class="rail:block">09<span class="rail:hidden"> / </span></span>Pro</div><div><span class="block font-mono uppercase text-mono-label mb-4 text-signal-text">Pro · $25 per user</span><h2 class="mb-6 max-w-[26ch] text-pretty font-display text-h2-sm font-semibold text-ink type:text-h2">The reading, when the list gets long.</h2><p class="mb-6 max-w-[58ch] text-pretty">Pro does not unlock an action. Everything you can do to a pull request, Claude’s review and fix included, and every rule behind Pending, you already get for nothing, and that is deliberate — a tool that held back the merge button would be holding your work hostage.</p><p class="mb-6 max-w-[58ch] text-pretty">What it adds is writing. On Pending, <span class="text-ink">Plan my day</span> writes a headline for the day, a line on what can wait, and one line on each planned card saying why it comes now — it never changes the order. A short summary at the top of a long pull request. A read on what a red build actually broke, rather than a link to a log. A check on whether a review comment was really addressed, judged from the commits since the thread started rather than from whether somebody clicked resolve.</p><p class="max-w-[58ch] text-pretty">On a quiet week you will not miss it. On the week you come back to two hundred threads, it is the difference between reading them and triaging them.</p></div><div class=""><figure class="border border-rule-strong"><figcaption class="flex items-center justify-between border-b border-rule px-4 py-[11px] font-mono text-mono-caption text-secondary"><span>limn · one card</span><button type="button" class="text-signal-text transition-colors duration-hover ease-standard hover:text-ink focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Enlarge</button></figcaption><button type="button" aria-label="Enlarge screenshot: A single Pending card showing its kind, the review standing, the merge verdict and the actions available on it" class="block w-full cursor-zoom-in focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ink"><span style="height:300px" class="block w-full overflow-hidden bg-paper"><img src="/shots/pending-card.png" alt="A single Pending card showing its kind, the review standing, the merge verdict and the actions available on it" loading="lazy" decoding="async" class="h-full w-full object-contain"/></span></button></figure><p class="mt-[18px] max-w-caption text-list text-muted">Free ranks the list. Pro writes the reason on it.</p></div></div></section><section id="pricing" class="px-gutter border-t border-ink py-14"><div class="grid items-start gap-grid-gutter rail:grid-cols-rail-1 "><div class="mb-6 font-mono text-mono-label uppercase text-secondary rail:mb-0 rail:pt-[10px]">Free vs Pro</div><div><h2 class="mb-6 max-w-[30ch] text-pretty font-display text-h2-sm font-semibold text-ink type:text-h2">Free answers one pull request. Pro answers the fortnight.</h2><p class="mb-10 max-w-[62ch] text-pretty text-lede text-ink-soft">Limn is open core. The free tier is the product, not a trial — it has no repository limit, no user limit and no expiry, and every action you take on a pull request lives in it. Pro is what happens when you need the same truth one grain up: across repositories, across people, across a period.</p><div class="border-t border-ink"><div class="hidden gap-grid-gutter border-b border-rule-strong py-3 rail:grid rail:grid-cols-[1.1fr_1.3fr_1.3fr]"><span class="block font-mono uppercase text-mono-label text-secondary">Question</span><span class="block font-mono uppercase text-mono-label text-secondary">Free · open core</span><span class="block font-mono uppercase text-mono-label text-signal-text">Pro · free for a month</span></div><div class="grid gap-x-grid-gutter gap-y-2 border-b border-rule-hair py-[18px] rail:grid-cols-[1.1fr_1.3fr_1.3fr]"><p class="font-display text-list font-semibold text-ink">What should I work on today?</p><div><span class="block font-mono uppercase text-mono-label mb-1 text-secondary rail:hidden">Free</span><p class="text-list text-ink-body">Pending: everything waiting on you or your workspace, across every repository, in six ranked tabs — the top five of each marked Do next.</p></div><div><span class="block font-mono uppercase text-mono-label mb-1 text-signal-text rail:hidden">Pro</span><p class="text-list text-ink-body">Plan my day: a written headline, a line on what can wait, and a reason on each planned card. The order stays the free one.</p></div></div><div class="grid gap-x-grid-gutter gap-y-2 border-b border-rule-hair py-[18px] rail:grid-cols-[1.1fr_1.3fr_1.3fr]"><p class="font-display text-list font-semibold text-ink">Can I change what counts as my turn?</p><div><span class="block font-mono uppercase text-mono-label mb-1 text-secondary rail:hidden">Free</span><p class="text-list text-ink-body">Yes. Switch card types on or off, move your own work into My turn, set the order, choose how every tab ranks, and mute a repository or a workspace.</p></div><div><span class="block font-mono uppercase text-mono-label mb-1 text-signal-text rail:hidden">Pro</span><p class="text-list text-ink-body">Everything free does. Your rules are never the paid part.</p></div></div><div class="grid gap-x-grid-gutter gap-y-2 border-b border-rule-hair py-[18px] rail:grid-cols-[1.1fr_1.3fr_1.3fr]"><p class="font-display text-list font-semibold text-ink">What happened on this pull request?</p><div><span class="block font-mono uppercase text-mono-label mb-1 text-secondary rail:hidden">Free</span><p class="text-list text-ink-body">Every thread triaged — untouched, replied, likely addressed, resolved. Blast radius, blockers, merge verdict.</p></div><div><span class="block font-mono uppercase text-mono-label mb-1 text-signal-text rail:hidden">Pro</span><p class="text-list text-ink-body">A short written summary, a read on what a red build means, and a check on whether a comment was really addressed.</p></div></div><div class="grid gap-x-grid-gutter gap-y-2 border-b border-rule-hair py-[18px] rail:grid-cols-[1.1fr_1.3fr_1.3fr]"><p class="font-display text-list font-semibold text-ink">Can I act without leaving?</p><div><span class="block font-mono uppercase text-mono-label mb-1 text-secondary rail:hidden">Free</span><p class="text-list text-ink-body">Reply, resolve, approve, merge, merge-when-ready, update from trunk, resolve conflicts hunk by hunk.</p></div><div><span class="block font-mono uppercase text-mono-label mb-1 text-signal-text rail:hidden">Pro</span><p class="text-list text-ink-body">Everything free does. Acting on a pull request is never the paid part.</p></div></div><div class="grid gap-x-grid-gutter gap-y-2 border-b border-rule-hair py-[18px] rail:grid-cols-[1.1fr_1.3fr_1.3fr]"><p class="font-display text-list font-semibold text-ink">Can Claude review or fix this?</p><div><span class="block font-mono uppercase text-mono-label mb-1 text-secondary rail:hidden">Free</span><p class="text-list text-ink-body">Yes, on your machine, on your own Claude: a review you tick and post, a chat on it, and a fix that is pushed only when you click.</p></div><div><span class="block font-mono uppercase text-mono-label mb-1 text-signal-text rail:hidden">Pro</span><p class="text-list text-ink-body">Everything free does. The agents are never the paid part.</p></div></div><div class="grid gap-x-grid-gutter gap-y-2 border-b border-rule-hair py-[18px] rail:grid-cols-[1.1fr_1.3fr_1.3fr]"><p class="font-display text-list font-semibold text-ink">Which review bots are worth their seat?</p><div><span class="block font-mono uppercase text-mono-label mb-1 text-secondary rail:hidden">Free</span><p class="text-list text-ink-body">Detect every bot, name it, set its role and record what it costs — and an independent severity grade on every comment it leaves.</p></div><div><span class="block font-mono uppercase text-mono-label mb-1 text-signal-text rail:hidden">Pro</span><p class="text-list text-ink-body">The per-bot scoreboard: keep / tune / noisy, dollars per comment your team acted on, over-calling as a weekly line.</p></div></div><div class="grid gap-x-grid-gutter gap-y-2 border-b border-rule-hair py-[18px] rail:grid-cols-[1.1fr_1.3fr_1.3fr]"><p class="font-display text-list font-semibold text-ink">How does that compare to other teams?</p><div><span class="block font-mono uppercase text-mono-label mb-1 text-secondary rail:hidden">Free</span><p class="text-list text-ink-body">—</p></div><div><span class="block font-mono uppercase text-mono-label mb-1 text-signal-text rail:hidden">Pro</span><p class="text-list text-ink-body">Your bots placed against a 2,204-repository cohort, with a written refusal wherever the cohort is too thin to answer.</p></div></div><div class="grid gap-x-grid-gutter gap-y-2 border-b border-rule-hair py-[18px] rail:grid-cols-[1.1fr_1.3fr_1.3fr]"><p class="font-display text-list font-semibold text-ink">How is the team doing?</p><div><span class="block font-mono uppercase text-mono-label mb-1 text-secondary rail:hidden">Free</span><p class="text-list text-ink-body">Flow metrics for the workspace, activity and reach by repository, open pull requests and trunk health.</p></div><div><span class="block font-mono uppercase text-mono-label mb-1 text-signal-text rail:hidden">Pro</span><p class="text-list text-ink-body">A stored report per sprint or month, compared like-for-like against the last one, with the coverage stated.</p></div></div><div class="grid gap-x-grid-gutter gap-y-2 border-b border-rule-hair py-[18px] rail:grid-cols-[1.1fr_1.3fr_1.3fr]"><p class="font-display text-list font-semibold text-ink">Is a repository about to bite us?</p><div><span class="block font-mono uppercase text-mono-label mb-1 text-secondary rail:hidden">Free</span><p class="text-list text-ink-body">Default-branch health across every repository, the checks failing on it, and the pull request that landed its latest commit.</p></div><div><span class="block font-mono uppercase text-mono-label mb-1 text-signal-text rail:hidden">Pro</span><p class="text-list text-ink-body">Everything free does. Trunk health is never the paid part — it is the thing you need at the worst moment.</p></div></div><div class="grid gap-x-grid-gutter gap-y-2 border-b border-rule-hair py-[18px] rail:grid-cols-[1.1fr_1.3fr_1.3fr]"><p class="font-display text-list font-semibold text-ink">Where is the time actually going?</p><div><span class="block font-mono uppercase text-mono-label mb-1 text-secondary rail:hidden">Free</span><p class="text-list text-ink-body">—</p></div><div><span class="block font-mono uppercase text-mono-label mb-1 text-signal-text rail:hidden">Pro</span><p class="text-list text-ink-body">Chronology: every open hour attributed to a reviewer, an author, or waiting to land. Nobody is named.</p></div></div><div class="grid gap-x-grid-gutter gap-y-2 border-b border-rule-hair py-[18px] rail:grid-cols-[1.1fr_1.3fr_1.3fr]"><p class="font-display text-list font-semibold text-ink">What do I take into a one-to-one?</p><div><span class="block font-mono uppercase text-mono-label mb-1 text-secondary rail:hidden">Free</span><p class="text-list text-ink-body">—</p></div><div><span class="block font-mono uppercase text-mono-label mb-1 text-signal-text rail:hidden">Pro</span><p class="text-list text-ink-body">A report with a section per person you pick. Preparation, not a ranking — there is no leaderboard anywhere in it.</p></div></div><div class="grid gap-x-grid-gutter gap-y-2 border-b border-rule-hair py-[18px] rail:grid-cols-[1.1fr_1.3fr_1.3fr]"><p class="font-display text-list font-semibold text-ink">Can I keep the noise down?</p><div><span class="block font-mono uppercase text-mono-label mb-1 text-secondary rail:hidden">Free</span><p class="text-list text-ink-body">Bots hidden by default, notifications only for work that is yours, and a mute per repository or per workspace.</p></div><div><span class="block font-mono uppercase text-mono-label mb-1 text-signal-text rail:hidden">Pro</span><p class="text-list text-ink-body">Everything free does, plus a Slack digest per workspace if you would rather read it there.</p></div></div><div class="grid gap-x-grid-gutter gap-y-2 border-b border-rule-hair py-[18px] rail:grid-cols-[1.1fr_1.3fr_1.3fr]"><p class="font-display text-list font-semibold text-ink">Where does it run?</p><div><span class="block font-mono uppercase text-mono-label mb-1 text-secondary rail:hidden">Free</span><p class="text-list text-ink-body">npx limn-review on your machine, or the hosted service. No repository limit, no user limit. Claude review and fix run on your machine only.</p></div><div><span class="block font-mono uppercase text-mono-label mb-1 text-signal-text rail:hidden">Pro</span><p class="text-list text-ink-body">The same two places. Pro unlocks on whichever one you already use.</p></div></div></div><p class="mt-6 max-w-[62ch] font-mono text-mono-caption text-secondary">Pro lists at $25 per user, and is free for a month to anyone who asks for it. A user is someone who signs in — bots never count, and there is no per-repository charge.</p><p class="mt-2 max-w-[62ch] font-mono text-mono-caption text-secondary">Review and fix run locally only, on your own Claude Code or Anthropic API key. Limn stores no key and charges nothing for it.</p><div class="mt-10"><figure class="border border-rule"><figcaption class="flex items-center justify-between border-b border-rule px-4 py-[11px] font-mono text-mono-caption text-secondary"><span>limn · reports, free account</span><button type="button" class="text-signal-text transition-colors duration-hover ease-standard hover:text-ink focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Enlarge</button></figcaption><button type="button" aria-label="Enlarge screenshot: The Reports pane on a free account: the flow metrics render in full, and the paid period-report panel below them is listed, badged and locked rather than hidden" class="block w-full cursor-zoom-in focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ink"><span style="height:460px" class="block w-full overflow-hidden bg-paper"><img src="/shots/free-reports.png" alt="The Reports pane on a free account: the flow metrics render in full, and the paid period-report panel below them is listed, badged and locked rather than hidden" loading="lazy" decoding="async" class="h-full w-full object-cover object-top"/></span></button></figure><p class="mt-[18px] max-w-caption text-list text-muted">What a free account actually sees. The paid panes are listed and locked rather than hidden, so you can tell what you are not buying before you buy it — and the free metrics above them are the ones that moved here off another tab.</p></div></div></div></section><section class="px-gutter py-section-y-lg "><div class="grid items-start gap-grid-gutter rail:grid-cols-rail-1 "><div class="mb-6 font-mono text-mono-label uppercase text-secondary rail:mb-0 rail:pt-[10px]">Start</div><div><h2 class="mb-5 max-w-[24ch] text-pretty font-display text-h2-sm font-semibold text-ink type:text-h2-major">Start free. Every repository, nothing missed.</h2><p class="mb-9 max-w-[56ch] text-pretty text-lede text-ink-soft">Sign in with GitHub and the first repositories are on screen in a couple of minutes, or run the whole free tier on your own machine and keep the data there. For Pro, send a message — it is free for a month, for asking.</p><div class="mb-5 flex flex-wrap items-center gap-3.5"><a href="/api/auth/login" class="inline-block bg-ink px-6 py-[15px] font-display text-[16px] font-semibold text-paper hover:bg-[#08080A] transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink ">Sign in with GitHub</a><a href="/contact?topic=pro" class="inline-block bg-signal-text px-6 py-[15px] font-display text-[16px] font-semibold text-paper hover:bg-[#A6301A] transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink ">Ask for a free month of Pro</a></div><p class="max-w-reassure font-mono text-mono-nav text-secondary">Card payments are not switched on yet, so Pro is not sold from this page — it is given, a month at a time, to anyone who asks. No card, nothing to cancel. Or run the free tier locally: <span class="text-ink">npx limn-review</span></p></div></div></section></main><footer class="border-t border-rule px-gutter py-[26px] font-mono text-mono-caption text-secondary"><div class="flex flex-wrap items-baseline justify-between gap-x-8 gap-y-3"><span>© 2026 Limn. Built for sprint situational awareness.</span><span class="flex flex-wrap items-baseline gap-x-5 gap-y-2"><a href="/for-developers" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">For developers</a><a href="/for-managers" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">For managers</a><a href="/how-we-measure" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">How we measure</a><a href="/contact" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Contact</a><a href="https://github.com/alexwakeman/pierre-review" target="_blank" rel="noreferrer noopener" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">GitHub</a><a href="/privacy" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Privacy</a><a href="/cookies" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Cookies</a><a href="/terms" class="hover:text-ink transition-colors duration-hover ease-standard focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink">Terms</a></span></div><p class="mt-4 max-w-caption">Limn is a desktop experience today. A phone-friendly build is planned.</p></footer></div>
|
|
154
|
+
</div>
|
|
155
|
+
</body>
|
|
156
|
+
</html>
|