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
package/dist/cli.js
ADDED
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execFile, execFileSync } from 'node:child_process';
|
|
3
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
4
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
5
|
+
// ── tiny ANSI helpers (degrade gracefully when not a TTY) ──────────────────
|
|
6
|
+
const useColor = process.stdout.isTTY && process.env.NO_COLOR === undefined;
|
|
7
|
+
const paint = (code, s) => useColor ? `[${code}m${s}[0m` : s;
|
|
8
|
+
const cyan = (s) => paint('36', s);
|
|
9
|
+
const dim = (s) => paint('2', s);
|
|
10
|
+
const bold = (s) => paint('1', s);
|
|
11
|
+
function parseArgs(argv) {
|
|
12
|
+
const opts = { open: true, cloud: false, help: false };
|
|
13
|
+
for (let i = 0; i < argv.length; i++) {
|
|
14
|
+
const arg = argv[i];
|
|
15
|
+
switch (arg) {
|
|
16
|
+
case '--no-open':
|
|
17
|
+
opts.open = false;
|
|
18
|
+
break;
|
|
19
|
+
case '--cloud':
|
|
20
|
+
opts.cloud = true;
|
|
21
|
+
break;
|
|
22
|
+
case '--mode': {
|
|
23
|
+
const v = argv[++i];
|
|
24
|
+
if (v !== 'local' && v !== 'cloud') {
|
|
25
|
+
console.error('--mode requires `local` or `cloud`');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
opts.cloud = v === 'cloud';
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
case '--port': {
|
|
32
|
+
const v = argv[++i];
|
|
33
|
+
const n = v ? Number.parseInt(v, 10) : NaN;
|
|
34
|
+
if (!Number.isFinite(n)) {
|
|
35
|
+
console.error('--port requires a number');
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
opts.port = n;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
case '--db': {
|
|
42
|
+
const v = argv[++i];
|
|
43
|
+
if (!v) {
|
|
44
|
+
console.error('--db requires a path');
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
opts.db = v;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
case '--help':
|
|
51
|
+
case '-h':
|
|
52
|
+
opts.help = true;
|
|
53
|
+
break;
|
|
54
|
+
default:
|
|
55
|
+
console.error(`Unknown argument: ${arg}`);
|
|
56
|
+
console.error('Run `limn --help` for usage.');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return opts;
|
|
61
|
+
}
|
|
62
|
+
function printUsage() {
|
|
63
|
+
console.log(`limn — ${'local-only GitHub PR activity dashboard'}
|
|
64
|
+
|
|
65
|
+
Usage:
|
|
66
|
+
limn [options]
|
|
67
|
+
limn status [options]
|
|
68
|
+
limn ai install
|
|
69
|
+
|
|
70
|
+
Commands:
|
|
71
|
+
status Your cross-repo "my turn" queue in the terminal, with
|
|
72
|
+
clickable links (see \`limn status --help\`)
|
|
73
|
+
ai install Download the AI runtime Claude Review and AI Fix run on
|
|
74
|
+
(one time, about 110 MB). The app offers the same button.
|
|
75
|
+
ai status Say whether the AI runtime is set up
|
|
76
|
+
|
|
77
|
+
Options:
|
|
78
|
+
--no-open Don't open the browser (also honours NO_OPEN env)
|
|
79
|
+
--port <n> Port to listen on (also PORT env, default 4000)
|
|
80
|
+
--db <path> SQLite DB path (also DATABASE_URL env)
|
|
81
|
+
--cloud Run the deployed (cloud) experience: Postgres + landing page
|
|
82
|
+
+ GitHub-App OAuth. Requires cloud env (see docs). Equivalent
|
|
83
|
+
to DEPLOYMENT_MODE=cloud. Skips the gh-auth pre-check.
|
|
84
|
+
--mode <m> 'local' (default) or 'cloud'
|
|
85
|
+
-h, --help Show this help
|
|
86
|
+
|
|
87
|
+
The old \`pierre-review\` package now only forwards to this one; it will be removed.
|
|
88
|
+
|
|
89
|
+
Your data lives in ~/.limn (LIMN_DATA_DIR overrides). An existing ~/.pierre-review
|
|
90
|
+
is moved there once, on first start.
|
|
91
|
+
|
|
92
|
+
Prerequisite (local mode):
|
|
93
|
+
Requires the GitHub CLI (https://cli.github.com), authenticated via
|
|
94
|
+
\`gh auth login\`. The dashboard reads your activity using your gh token.
|
|
95
|
+
|
|
96
|
+
Prerequisite (--cloud):
|
|
97
|
+
Postgres + a GitHub sign-in method (an OAuth App and/or a GitHub App). See
|
|
98
|
+
docs/GITHUB-AUTH-SETUP.md. Provide DATABASE_URL, APP_BASE_URL, SESSION_SECRET,
|
|
99
|
+
ENCRYPTION_KEY, and at least one of GITHUB_OAUTH_CLIENT_ID+SECRET or
|
|
100
|
+
GITHUB_APP_CLIENT_ID+SECRET.
|
|
101
|
+
`);
|
|
102
|
+
}
|
|
103
|
+
// Cross-platform browser open — no extra dependency.
|
|
104
|
+
function openBrowser(url) {
|
|
105
|
+
const platform = process.platform;
|
|
106
|
+
const cmd = platform === 'darwin' ? 'open' : platform === 'win32' ? 'cmd' : 'xdg-open';
|
|
107
|
+
const args = platform === 'win32' ? ['/c', 'start', '""', url] : [url];
|
|
108
|
+
// Swallow failures — headless / no-DE environments are fine.
|
|
109
|
+
execFile(cmd, args, () => {
|
|
110
|
+
/* ignore */
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
// The default local SQLite location — a user-writable home dir, never the (possibly
|
|
114
|
+
// read-only) install dir. Shared by the server boot and `limn status`. The FILE keeps its
|
|
115
|
+
// pre-rename name on purpose: the one-time move of ~/.pierre-review → ~/.limn carries it (and its
|
|
116
|
+
// WAL files) across untouched, and renaming a live SQLite file is a second migration for nothing.
|
|
117
|
+
async function defaultLocalDbPath() {
|
|
118
|
+
const { resolveDataDir } = await import('./data-dir.js');
|
|
119
|
+
return join(resolveDataDir(), 'pierre-review.sqlite');
|
|
120
|
+
}
|
|
121
|
+
// Move a pre-rename ~/.pierre-review to ~/.limn, once, before anything reads a path inside it.
|
|
122
|
+
// Never clobbers an existing ~/.limn; never moves into an explicit LIMN_DATA_DIR.
|
|
123
|
+
async function migrateDataDir() {
|
|
124
|
+
const { migrateLegacyDataDir } = await import('./data-dir.js');
|
|
125
|
+
migrateLegacyDataDir({ log: (msg) => console.log(` ${dim(msg)}`) });
|
|
126
|
+
}
|
|
127
|
+
// Fail fast with a friendly message when the GitHub CLI isn't installed / authed.
|
|
128
|
+
// Both the local server boot and `limn status` need a working `gh` token.
|
|
129
|
+
function ghAuthPreCheck() {
|
|
130
|
+
try {
|
|
131
|
+
execFileSync('gh', ['auth', 'token'], { stdio: 'ignore' });
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
console.error('');
|
|
135
|
+
console.error(bold('GitHub CLI not found or not authenticated.'));
|
|
136
|
+
console.error('Install the GitHub CLI (https://cli.github.com) and run `gh auth login`.');
|
|
137
|
+
console.error('');
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function parseStatusArgs(argv) {
|
|
142
|
+
const opts = {
|
|
143
|
+
watch: false,
|
|
144
|
+
sync: false,
|
|
145
|
+
intervalSeconds: 60,
|
|
146
|
+
help: false,
|
|
147
|
+
};
|
|
148
|
+
for (let i = 0; i < argv.length; i++) {
|
|
149
|
+
const arg = argv[i];
|
|
150
|
+
switch (arg) {
|
|
151
|
+
case '--watch':
|
|
152
|
+
opts.watch = true;
|
|
153
|
+
break;
|
|
154
|
+
case '--sync':
|
|
155
|
+
opts.sync = true;
|
|
156
|
+
break;
|
|
157
|
+
case '--interval': {
|
|
158
|
+
const v = argv[++i];
|
|
159
|
+
const n = v ? Number.parseInt(v, 10) : NaN;
|
|
160
|
+
if (!Number.isFinite(n)) {
|
|
161
|
+
console.error('--interval requires a number of seconds');
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
opts.intervalSeconds = Math.max(10, n);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
case '--db': {
|
|
168
|
+
const v = argv[++i];
|
|
169
|
+
if (!v) {
|
|
170
|
+
console.error('--db requires a path');
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
opts.db = v;
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
case '--help':
|
|
177
|
+
case '-h':
|
|
178
|
+
opts.help = true;
|
|
179
|
+
break;
|
|
180
|
+
default:
|
|
181
|
+
console.error(`Unknown argument: ${arg}`);
|
|
182
|
+
console.error('Run `limn status --help` for usage.');
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return opts;
|
|
187
|
+
}
|
|
188
|
+
function printStatusUsage() {
|
|
189
|
+
console.log(`limn status — your cross-repo "my turn" queue in the terminal
|
|
190
|
+
|
|
191
|
+
Usage:
|
|
192
|
+
limn status [options]
|
|
193
|
+
|
|
194
|
+
Options:
|
|
195
|
+
--sync Fetch fresh state from GitHub first (otherwise shows data as of
|
|
196
|
+
the last sync). Under --watch, re-syncs at most every 5 minutes.
|
|
197
|
+
--watch Repaint on an interval until you quit (Ctrl-C)
|
|
198
|
+
--interval <n> Seconds between repaints under --watch (default 60, min 10)
|
|
199
|
+
--db <path> SQLite DB path (also DATABASE_URL env)
|
|
200
|
+
-h, --help Show this help
|
|
201
|
+
|
|
202
|
+
Reads the local Limn database. Without --sync it shows data as of the last sync
|
|
203
|
+
— run it alongside \`limn\`, or pass --sync to fetch fresh state first. Links are
|
|
204
|
+
clickable in terminals that support OSC-8 hyperlinks.
|
|
205
|
+
`);
|
|
206
|
+
}
|
|
207
|
+
async function runStatusCommand(argv) {
|
|
208
|
+
const opts = parseStatusArgs(argv);
|
|
209
|
+
if (opts.help) {
|
|
210
|
+
printStatusUsage();
|
|
211
|
+
process.exit(0);
|
|
212
|
+
}
|
|
213
|
+
// status is LOCAL-only — it reads your on-disk SQLite database directly.
|
|
214
|
+
if (process.env.DEPLOYMENT_MODE === 'cloud') {
|
|
215
|
+
console.error('`limn status` is local-only — it reads your local SQLite database.');
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
// Pin local BEFORE the dynamic import: config.ts loads .env files on import, and
|
|
219
|
+
// process.loadEnvFile never overrides an already-set var — so an .env-declared
|
|
220
|
+
// DEPLOYMENT_MODE=cloud can't flip status onto the Postgres driver after the guard.
|
|
221
|
+
process.env.DEPLOYMENT_MODE = 'local';
|
|
222
|
+
// ── map flags → env BEFORE any dynamic import (config/db snapshot env on load) ──
|
|
223
|
+
// resolve() the --db flag against the CWD (what the user means by a relative path);
|
|
224
|
+
// config.ts resolves relative paths against the INSTALL dir, so an unresolved value
|
|
225
|
+
// would make this guard check one file while the DB opens another.
|
|
226
|
+
process.env.NODE_ENV ??= 'production';
|
|
227
|
+
if (opts.db !== undefined)
|
|
228
|
+
process.env.DATABASE_URL = resolve(opts.db);
|
|
229
|
+
await migrateDataDir();
|
|
230
|
+
if (!process.env.DATABASE_URL)
|
|
231
|
+
process.env.DATABASE_URL = await defaultLocalDbPath();
|
|
232
|
+
try {
|
|
233
|
+
mkdirSync(dirname(process.env.DATABASE_URL), { recursive: true });
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
/* best-effort; client.ts also mkdirs */
|
|
237
|
+
}
|
|
238
|
+
// Friendlier than the server path: don't silently create an empty DB just to show
|
|
239
|
+
// an empty queue. --sync legitimately bootstraps a fresh DB, so skip the guard then.
|
|
240
|
+
if (!opts.sync && !existsSync(process.env.DATABASE_URL)) {
|
|
241
|
+
console.error(`No Limn database found at ${process.env.DATABASE_URL} — run \`limn\` first to sync, or pass --db.`);
|
|
242
|
+
process.exit(1);
|
|
243
|
+
}
|
|
244
|
+
// ensureLocalAccount (`gh api user`) and --sync both need a working gh token.
|
|
245
|
+
ghAuthPreCheck();
|
|
246
|
+
const { runStatus } = await import('./status.js');
|
|
247
|
+
await runStatus({
|
|
248
|
+
watch: opts.watch,
|
|
249
|
+
sync: opts.sync,
|
|
250
|
+
intervalSeconds: opts.intervalSeconds,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
// ── `limn ai install` / `limn ai status` — the AI runtime, from the terminal ──────
|
|
254
|
+
// The same download the app's "Set up AI" button runs (ai/runtime.ts): the pinned Agent SDK and
|
|
255
|
+
// its three peers into ~/.limn/ai-runtime via `npm install --prefix`. Local only.
|
|
256
|
+
async function runAiCommand(argv) {
|
|
257
|
+
const sub = argv[0];
|
|
258
|
+
if (sub !== 'install' && sub !== 'status') {
|
|
259
|
+
console.log(`limn ai — the AI runtime Claude Review and AI Fix run on
|
|
260
|
+
|
|
261
|
+
Usage:
|
|
262
|
+
limn ai install Download it (one time, about 110 MB) into ~/.limn/ai-runtime
|
|
263
|
+
limn ai status Say whether it is set up
|
|
264
|
+
|
|
265
|
+
Claude Review and AI Fix are free. They run on your own Claude Code or
|
|
266
|
+
Anthropic API key: sign in to Claude Code, or set ANTHROPIC_API_KEY.
|
|
267
|
+
Set LIMN_CLAUDE_PATH to use your installed \`claude\` and skip its bundled copy.
|
|
268
|
+
`);
|
|
269
|
+
process.exit(sub === undefined || sub === '--help' || sub === '-h' ? 0 : 1);
|
|
270
|
+
}
|
|
271
|
+
if (process.env.DEPLOYMENT_MODE === 'cloud') {
|
|
272
|
+
console.error('AI review and fix run on your machine only: npx limn-review');
|
|
273
|
+
process.exit(1);
|
|
274
|
+
}
|
|
275
|
+
if (process.env.LIMN_AI_DISABLED === 'true') {
|
|
276
|
+
console.error('AI is turned off here (LIMN_AI_DISABLED=true).');
|
|
277
|
+
process.exit(1);
|
|
278
|
+
}
|
|
279
|
+
await migrateDataDir();
|
|
280
|
+
const { getAiRuntimeStatus, installAiRuntime, aiRuntimePins } = await import('./ai/runtime.js');
|
|
281
|
+
if (sub === 'status') {
|
|
282
|
+
const s = getAiRuntimeStatus();
|
|
283
|
+
const words = s.runtime === 'ready' ? 'AI is set up.' : 'AI is not set up. Run: limn ai install';
|
|
284
|
+
console.log(s.runtimeMessage ? `${words} ${s.runtimeMessage}` : words);
|
|
285
|
+
process.exit(s.runtime === 'ready' ? 0 : 1);
|
|
286
|
+
}
|
|
287
|
+
const pins = aiRuntimePins();
|
|
288
|
+
if (pins) {
|
|
289
|
+
console.log(bold('Setting up AI (one-time download, about 110 MB):'));
|
|
290
|
+
for (const [name, version] of Object.entries(pins))
|
|
291
|
+
console.log(` ${dim(`${name}@${version}`)}`);
|
|
292
|
+
}
|
|
293
|
+
const result = await installAiRuntime((p) => {
|
|
294
|
+
if (p.phase === 'downloading')
|
|
295
|
+
console.log(` ${dim(p.message)}`);
|
|
296
|
+
else if (p.phase !== 'failed')
|
|
297
|
+
console.log(`${cyan('▸')} ${p.message}`);
|
|
298
|
+
});
|
|
299
|
+
if (!result.ok) {
|
|
300
|
+
console.error(bold(result.message));
|
|
301
|
+
process.exit(1);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
async function main() {
|
|
305
|
+
const argv = process.argv.slice(2);
|
|
306
|
+
// The package was renamed `pierre-review` → `limn-review` (bin `limn`). The old name survives as
|
|
307
|
+
// the forwarding stub's bin (scripts/deprecated-pierre-review/, never limn-review's own — that
|
|
308
|
+
// collides with an old global install); say so, once per start, on stderr so piped output is clean.
|
|
309
|
+
if (/^pierre(-review)?(\.(c?js|cmd|ps1))?$/.test(basename(process.argv[1] ?? ''))) {
|
|
310
|
+
console.error(dim('`pierre-review` is now `limn` (npm package: limn-review). The old name will be removed.'));
|
|
311
|
+
}
|
|
312
|
+
// `limn status` — a read-only subcommand with its own parser, usage, and env
|
|
313
|
+
// mapping. Peeled off BEFORE parseArgs (whose default case rejects any bare token),
|
|
314
|
+
// and it never reaches the server boot below.
|
|
315
|
+
if (argv[0] === 'status') {
|
|
316
|
+
await runStatusCommand(argv.slice(1));
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
if (argv[0] === 'ai') {
|
|
320
|
+
await runAiCommand(argv.slice(1));
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const opts = parseArgs(argv);
|
|
324
|
+
if (opts.help) {
|
|
325
|
+
printUsage();
|
|
326
|
+
process.exit(0);
|
|
327
|
+
}
|
|
328
|
+
// ── map flags → env BEFORE importing config/app (config reads these) ──────
|
|
329
|
+
// --db is resolved against the CWD (config.ts resolves relative paths against the
|
|
330
|
+
// install dir, which is never what a user typing a relative path means).
|
|
331
|
+
if (opts.port !== undefined)
|
|
332
|
+
process.env.PORT = String(opts.port);
|
|
333
|
+
if (opts.db !== undefined)
|
|
334
|
+
process.env.DATABASE_URL = resolve(opts.db);
|
|
335
|
+
if (opts.open === false)
|
|
336
|
+
process.env.NO_OPEN = '1';
|
|
337
|
+
if (opts.cloud)
|
|
338
|
+
process.env.DEPLOYMENT_MODE = 'cloud';
|
|
339
|
+
const isCloud = process.env.DEPLOYMENT_MODE === 'cloud';
|
|
340
|
+
// Production mode: skip pino-pretty (not shipped) and enable static serving.
|
|
341
|
+
process.env.NODE_ENV ??= 'production';
|
|
342
|
+
if (!isCloud) {
|
|
343
|
+
// ── local: default the DB to a user-writable home location (mkdir -p) ────
|
|
344
|
+
// The package dir is read-only for global installs, so never write there.
|
|
345
|
+
await migrateDataDir();
|
|
346
|
+
if (!process.env.DATABASE_URL) {
|
|
347
|
+
process.env.DATABASE_URL = await defaultLocalDbPath();
|
|
348
|
+
}
|
|
349
|
+
try {
|
|
350
|
+
mkdirSync(dirname(process.env.DATABASE_URL), { recursive: true });
|
|
351
|
+
}
|
|
352
|
+
catch {
|
|
353
|
+
/* best-effort; client.ts also mkdirs */
|
|
354
|
+
}
|
|
355
|
+
// ── pre-check gh auth with a friendly message (contract §6) ─────────────
|
|
356
|
+
ghAuthPreCheck();
|
|
357
|
+
}
|
|
358
|
+
// Cloud mode: no gh pre-check (each account brings its own OAuth token) and no
|
|
359
|
+
// SQLite home default (DATABASE_URL must be a Postgres URL). config.ts /
|
|
360
|
+
// assertCloudConfig validate the required cloud env at boot.
|
|
361
|
+
const port = process.env.PORT ? Number.parseInt(process.env.PORT, 10) : 4000;
|
|
362
|
+
const base = `http://localhost:${port}`;
|
|
363
|
+
// Local goes straight to the app; cloud opens the public landing page.
|
|
364
|
+
const url = isCloud ? `${base}/` : `${base}/app`;
|
|
365
|
+
// ── banner ────────────────────────────────────────────────────────────────
|
|
366
|
+
const { LIMN_ASCII, TAGLINE } = await import('./ascii.js');
|
|
367
|
+
console.log(cyan(LIMN_ASCII));
|
|
368
|
+
console.log(` ${dim(isCloud ? 'cloud mode — multi-tenant' : TAGLINE)}`);
|
|
369
|
+
console.log('');
|
|
370
|
+
console.log(` ${cyan('▸')} ${bold(url)}`);
|
|
371
|
+
console.log('');
|
|
372
|
+
// ── boot the server (migrate → account → app → scheduler → listen) ────────
|
|
373
|
+
const { start } = await import('./index.js');
|
|
374
|
+
await start();
|
|
375
|
+
// ── open the browser once we're listening ─────────────────────────────────
|
|
376
|
+
const skipOpen = opts.open === false || process.env.NO_OPEN !== undefined;
|
|
377
|
+
if (!skipOpen)
|
|
378
|
+
openBrowser(url);
|
|
379
|
+
}
|
|
380
|
+
main().catch((err) => {
|
|
381
|
+
// The product NAME, not the command — the banner above already says Limn. A literal rather
|
|
382
|
+
// than shared's PRODUCT_NAME on purpose: this module has no top-level imports outside
|
|
383
|
+
// `node:*` (everything else is a dynamic import, to keep `npx` startup lean) and one word is
|
|
384
|
+
// not worth loading shared before the failure can be printed.
|
|
385
|
+
console.error('Failed to start Limn:', err);
|
|
386
|
+
process.exit(1);
|
|
387
|
+
});
|
|
388
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Live progress derivation for the coding agent — turns each assistant turn into a
|
|
2
|
+
// few short, human-readable lines (tool labels + clipped text). Mirrors the private
|
|
3
|
+
// helpers in review/agent.ts but understands the WRITE tools (Write/Edit/MultiEdit)
|
|
4
|
+
// the fixer uses. Defensive throughout: the SDK content/tool-input shapes vary, so
|
|
5
|
+
// every access is guarded and this never throws.
|
|
6
|
+
const TEXT_SNIPPET_CAP = 120;
|
|
7
|
+
const ARG_CAP = 80;
|
|
8
|
+
export function describeAssistantBlocks(message) {
|
|
9
|
+
const lines = [];
|
|
10
|
+
const content = message?.message
|
|
11
|
+
?.content;
|
|
12
|
+
if (!Array.isArray(content))
|
|
13
|
+
return lines;
|
|
14
|
+
for (const raw of content) {
|
|
15
|
+
if (!raw || typeof raw !== 'object')
|
|
16
|
+
continue;
|
|
17
|
+
const block = raw;
|
|
18
|
+
if (block.type === 'tool_use') {
|
|
19
|
+
const name = typeof block.name === 'string' ? block.name : 'Tool';
|
|
20
|
+
const input = block.input && typeof block.input === 'object'
|
|
21
|
+
? block.input
|
|
22
|
+
: {};
|
|
23
|
+
lines.push(labelToolUse(name, input));
|
|
24
|
+
}
|
|
25
|
+
else if (block.type === 'text' && typeof block.text === 'string') {
|
|
26
|
+
const snippet = clip(block.text.replace(/\s+/g, ' ').trim(), TEXT_SNIPPET_CAP);
|
|
27
|
+
if (snippet)
|
|
28
|
+
lines.push(snippet);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return lines;
|
|
32
|
+
}
|
|
33
|
+
function labelToolUse(name, input) {
|
|
34
|
+
const str = (v) => typeof v === 'string' && v.trim().length > 0 ? v.trim() : null;
|
|
35
|
+
switch (name) {
|
|
36
|
+
case 'Read': {
|
|
37
|
+
const p = str(input.file_path) ?? str(input.path);
|
|
38
|
+
return p ? `Read ${p}` : 'Read …';
|
|
39
|
+
}
|
|
40
|
+
case 'Write': {
|
|
41
|
+
const p = str(input.file_path) ?? str(input.path);
|
|
42
|
+
return p ? `Write ${p}` : 'Write …';
|
|
43
|
+
}
|
|
44
|
+
case 'Edit':
|
|
45
|
+
case 'MultiEdit': {
|
|
46
|
+
const p = str(input.file_path) ?? str(input.path);
|
|
47
|
+
return p ? `Edit ${p}` : 'Edit …';
|
|
48
|
+
}
|
|
49
|
+
case 'Glob': {
|
|
50
|
+
const p = str(input.pattern);
|
|
51
|
+
return p ? `Glob ${p}` : 'Glob …';
|
|
52
|
+
}
|
|
53
|
+
case 'Grep': {
|
|
54
|
+
const p = str(input.pattern);
|
|
55
|
+
return p ? `Grep "${clip(p, ARG_CAP)}"` : 'Grep …';
|
|
56
|
+
}
|
|
57
|
+
// Unreachable as things stand — the fixer does not allow Bash (coding/agent.ts denies it
|
|
58
|
+
// outright), so no such block arrives and the panel simply shows fewer lines. Kept because
|
|
59
|
+
// this function's contract is "label whatever the SDK hands me", and the default branch
|
|
60
|
+
// below would render this one worse.
|
|
61
|
+
case 'Bash': {
|
|
62
|
+
const c = str(input.command);
|
|
63
|
+
return c ? `Bash ${clip(c, ARG_CAP)}` : 'Bash …';
|
|
64
|
+
}
|
|
65
|
+
case 'mcp__fix__submit_fix':
|
|
66
|
+
return 'Recording fix summary…';
|
|
67
|
+
default: {
|
|
68
|
+
for (const key of Object.keys(input)) {
|
|
69
|
+
const v = str(input[key]);
|
|
70
|
+
if (v)
|
|
71
|
+
return `${name} ${clip(v, ARG_CAP)}`;
|
|
72
|
+
}
|
|
73
|
+
return `${name} …`;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function clip(s, max) {
|
|
78
|
+
return s.length > max ? `${s.slice(0, max)}…` : s;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=activity.js.map
|