Phases 0-1 + Sprint A: module split, CLI layer, org-refresh fix, hygiene

- LICENSE (MIT) + README truth-pass; docs/cli.md CLI contract
- CLI subcommands (src/cli_cmds/) per "TUI for users, CLI for users+AI"
- Hub/detail refactor: keymap dispatch, modal split, action enum, BgMsg bus
- Fix: org repos were never refreshed (owner==username match); refresh now
  parallel — 49 repos in ~11s, surfaced 70 previously invisible PRs
- Fix: 3 date bugs in detail/git.rs (format-local, Local::now, 1y month math)
- Stash indicator + [m] actions, session persistence, gh CLI token fallback
- Legacy UI modules removed; plan/ docs (roadmap, audit, debate, handoff)
This commit is contained in:
dualfroz committed 2026-07-06 14:42:52 +02:00
1 parent 5787b14880
commit 0468c032c6
100 files changed
+11614 -9840

No files matched your search

+14 -24
View File
@@ -1,37 +1,27 @@
//! Top-level command dispatch: loads config, then routes to the TUI hub,
//! one of the setup subcommands, or the non-interactive CLI surface.
use crate::cli::{Cli, Commands};
use anyhow::Result;
const NOT_YET: &str = "\
This CLI command is not yet implemented.
Launch the TUI with: fxg
";
/// Dispatches a parsed `Cli` invocation. With no subcommand, this launches
/// straight into the TUI hub — `vulp` is meant to be used interactively, so
/// the bare command is the primary entry point rather than a help screen.
/// Every other subcommand (besides `config`/`auth`) goes to `cli_cmds`,
/// the machine-friendly non-interactive surface.
pub async fn run(cli: Cli) -> Result<()> {
if cli.debug { crate::debug::enable(); }
let cfg = crate::config::load_config()?;
match cli.command {
// ── no subcommand → TUI hub ──
None => crate::status::run(
crate::cli::StatusArgs { repo: None, workspace: None, filter: None },
&cfg,
).await,
None => crate::status::run(&cfg).await,
// ── always-on: config + auth ──
Some(Commands::Config) => crate::config::run(cfg).await,
Some(Commands::Auth(args)) => crate::auth::run(args, &cfg).await,
// ── setup, needed before the TUI has anything to show ──
Some(Commands::Config) => crate::config::run(cfg).await,
Some(Commands::Auth(args)) => crate::auth::run(args, &cfg).await,
// ── everything else: stub ──
Some(Commands::Init(_)) => { eprintln!("{}", NOT_YET); Ok(()) }
Some(Commands::Status(_)) => { eprintln!("{}", NOT_YET); Ok(()) }
Some(Commands::Sync(_)) => { eprintln!("{}", NOT_YET); Ok(()) }
Some(Commands::Release(_)) => { eprintln!("{}", NOT_YET); Ok(()) }
Some(Commands::Refactor(_)) => { eprintln!("{}", NOT_YET); Ok(()) }
Some(Commands::Stats(_)) => { eprintln!("{}", NOT_YET); Ok(()) }
Some(Commands::Workspace(_)) => { eprintln!("{}", NOT_YET); Ok(()) }
Some(Commands::Summary(_)) => { eprintln!("{}", NOT_YET); Ok(()) }
Some(Commands::Adopt(_)) => { eprintln!("{}", NOT_YET); Ok(()) }
Some(Commands::Manage(_)) => { eprintln!("{}", NOT_YET); Ok(()) }
Some(Commands::Util(_)) => { eprintln!("{}", NOT_YET); Ok(()) }
// ── everything else: non-interactive CLI ──
Some(cmd) => crate::cli_cmds::run(cmd, cli.json, &cfg).await,
}
}