feat: flag vendored clones and make the repo filter navigable

Two Repos-tab quality-of-life changes:

- External/vendored clones (repos with zero of your own commits — e.g. an
  upstream cloned for reference and never pushed to) are measured on
  refresh, cached in stats_cache (RepoStatsEntry.authored), shown with a
  dim ⧉ marker prefixed to the name, and hidden by the persistent
  hide_external_clones config toggle (key `x`, the `S` menu, or
  `vulp list --external|--no-external`). A fork you do commit to stays
  yours, so only true reference clones are flagged.

- Inside the `/` filter box, ↑↓ now move through the live-filtered
  results and Enter opens the highlighted repo/project directly, instead
  of the filter only "locking" on Enter with no way to scroll or select.
This commit is contained in:
dualfroz committed 2026-07-08 16:15:02 +02:00
1 parent 2ccf69f64c
commit 212c55d138
16 files changed
+120 -10

No files matched your search

+6
View File
@@ -10,6 +10,7 @@ pub fn list(
cfg: &AppConfig, json: bool,
dirty: bool, behind: bool, ahead: bool,
lang: Option<String>, project: Option<String>, alerts: bool, stale_deploy: bool,
no_external: bool, external: bool,
) -> Result<()> {
let mut repos = scan_repos(cfg);
@@ -17,6 +18,11 @@ pub fn list(
if behind { repos.retain(|r| r.behind > 0); }
if ahead { repos.retain(|r| r.ahead > 0); }
if alerts { repos.retain(|r| r.dependabot_open.unwrap_or(0) > 0); }
if no_external || external {
let ext = crate::stats::cache::load().external_repo_names();
if external { repos.retain(|r| ext.contains(&r.name)); }
if no_external { repos.retain(|r| !ext.contains(&r.name)); }
}
if stale_deploy {
repos.retain(|r| {
!matches!(