Files
vulp/src/hub/state_bg.rs
T
dualfroz 14ef7fb06c Sprint C: author-filtered stats scan, release cadence + repo size, weekly digest
- src/stats/: OwnEmailMatcher (config emails + GH no-reply per account) +
  git-side --author filtering (cheap even on the pterodactyl fork's 4700+
  commits); streak (current/longest, midnight-grace rule), 52-week heatmap,
  day/hour histograms — one scan feeds all of them, data layer only for now
  (visual Stats-tab redesign stays in Sprint D's mockup-first cycle)
- src/stats/cadence.rs: release cadence (median tag gap, local tags, Tier A)
- src/stats/size.rs + cache.rs: git-object vs working-tree size, persisted
  in new ~/.vulp/stats_cache.toml (max 1 sample/day), recorded only during
  [R]/vulp refresh — confirms vulp's own filter-repo cleanup (539MB->834KB)
- src/digest.rs: WeeklyDigest struct + 3 renderers (Discord embed/markdown
  archive/plaintext); vulp digest [send discord|webhook <url>] CLI, webhook
  stored via existing auth token store (~/.vulp/.tokens, 0600), never logged;
  send respects --dry-run
- TUI: [d] on Stats previews the digest in a Modal::Info before anything is
  ever sent
- fix: list_contributors used --all (double-counts after fetching remotes),
  now --branches
- config: stats_author_emails field (TUI-editable)
- verified: streak/delta/top-repo/release math against a hand-built commit
  history, webhook validation+permissions, dry-run, real refresh (51 repos,
  vulp's own entry confirms the filter-repo win), TUI preview via pyte
2026-07-06 16:47:19 +02:00

85 lines
3.7 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Messages and snapshots produced by hub background threads: aggregated
//! workspace stats, the result of long-running repo-creation / settings-sync
//! / code-intelligence jobs, and the loop-control signal (`PhaseResult`) that
//! `tui_phase` uses to know when it needs to hand control back to its caller.
use std::path::PathBuf;
/// Workspace-wide numbers for the Stats and Overview tabs, computed once in
/// the background (scanning every repo's git history) rather than recomputed
/// every frame.
pub struct GlobalStats {
pub activity: Vec<(String, usize)>, // date → aggregated commits
pub lang_dist: Vec<(String, usize)>, // lang → repo count
pub top_repos: Vec<(String, usize)>, // name → commit count, top 5
pub repo_commits: Vec<(String, usize)>, // name → commit count, every repo (sorted desc)
pub total_commits: usize,
pub dirty_count: usize,
pub behind_count: usize,
pub day_pattern: [usize; 7], // Mon–Sun commit totals
}
/// Progress/result of the background API refresh ([R]): per-repo metadata,
/// PR/issue lists and workspace-wide closed counters, fetched off-thread so
/// the UI keeps drawing.
pub enum RefreshMsg {
Progress(String),
Done {
metas: Vec<(String, crate::cache::RepoMeta)>,
prs: Vec<(String, Vec<crate::providers::PrDetail>)>,
issues: Vec<(String, Vec<crate::providers::IssueDetail>)>,
closed_counts: Option<(u64, u64, u64)>,
},
}
/// What `tui_phase` should do once the current event-loop iteration ends.
/// Most keys are handled in place and report `None`; the rest need the
/// caller to take control away from the raw-mode TUI loop (e.g. to shell out
/// for a sync, or to switch into the repo detail sub-view).
#[derive(PartialEq)]
pub enum PhaseResult {
None,
OpenDetail,
ExecSync,
ExecRelease,
ExecClone(String),
ExecOpenEditor(PathBuf),
}
/// Progress/result of a background "create repo" job (git init, commit,
/// push, create-on-provider). `Progress` lines accumulate in a `Modal::Info`
/// while the job runs; `Done` replaces the modal with the final outcome.
pub enum CreateRepoMsg {
Progress(String),
Done { success: bool, name: String, detail: String },
}
// ── settings-profile pull-from-repo background messages ─────────────────────
// Separate from CreateRepoMsg because a successful pull needs to hand the
// fetched snapshot back to the main thread to be applied.
/// Progress/result of pulling a settings snapshot from the profile-sync repo.
pub enum ProfilePullMsg {
Done(Result<crate::profile::SettingsSnapshot, String>),
}
// ── code intelligence background messages ───────────────────────────────────
// Tree-sitter parsing a whole repo is CPU-bound, not I/O — runs on a plain
// std::thread (no tokio runtime needed) and reports back over this channel.
/// Result of a background code-intelligence job (list functions / find
/// usages / build a rename plan / repo stats).
pub enum CodeIntelMsg {
/// Read-only result: rendered as a `Modal::Info` (function list, usages, stats).
Info { title: String, lines: Vec<String> },
/// A rename/convention-conversion dry-run: rendered as `Modal::RenamePreview`,
/// which requires an explicit Enter/y before `apply_rename_plan` ever runs.
Preview { title: String, lines: Vec<String>, plan: crate::codeintel::RenamePlan },
}
/// Result of building the weekly digest in the background (`[d]` on Stats)
/// — a content preview before anything is ever posted to Discord.
pub struct DigestMsg {
pub lines: Vec<String>,
}