Files
vulp/docs/cross-platform.md
dualfroz 0468c032c6 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)
2026-07-06 14:42:52 +02:00

283 lines
8.6 KiB
Markdown
Raw Permalink 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.
# vulp — strategia cross-platform
> Cel: jedna binarka, trzy systemy, instalacja w 30 sekund, zero wiedzy technicznej wymaganej.
---
## Stan obecny
Rust kompiluje się do natywnych binarek bez zewnętrznych zależności runtime. To dobra podstawa — nie trzeba instalować Pythona, Node.js ani JVM. Ale dziś jedynym sposobem instalacji jest `cargo install --path .`, co wymaga zainstalowanego Rusta i środowiska build. Dla grafika — nierealne.
Obecny problem z `keyring`: na Linuksie wymaga `libdbus` lub `libsecret`. Do rozwiązania przy pakowaniu.
---
## Cel UX instalacji
**Windows:** Pobierasz plik `.exe`. Klikasz go dwukrotnie. Otwiera się terminal z konfiguratorem. Po 2 minutach piszesz `vulp status` i to działa.
**Linux:** Wklejasz jedną linię w terminal. Po 10 sekundach piszesz `vulp status` i to działa.
**macOS:** `brew install`. Jedna komenda.
---
## Strategia dystrybucji — GitHub Releases + CI
### GitHub Actions — automatyczne buildowanie binarek
Przy każdym tagu (`v*.*.*`) CI buduje binarkę na 4 targety:
```yaml
# .github/workflows/release.yml
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-musl # statyczna binarka — działa na każdym Linuksie
artifact: vulp-linux-x64
- os: ubuntu-latest
target: aarch64-unknown-linux-musl # ARM (np. Raspberry Pi, nowe serwery)
artifact: vulp-linux-arm64
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact: vulp-windows-x64.exe
- os: macos-latest
target: x86_64-apple-darwin
artifact: vulp-macos-x64
- os: macos-latest
target: aarch64-apple-darwin # Apple Silicon (M1/M2/M3)
artifact: vulp-macos-arm64
```
> Używamy `x86_64-unknown-linux-musl` zamiast `gnu` — binarka statyczna, nie wymaga żadnych systemowych `.so`. Keyring na Linuksie fallback do pliku szyfrowanego (jeśli brak dbus).
Pliki lądują w GitHub Releases jako Assets. Użytkownik pobiera odpowiedni plik dla swojego systemu.
---
## Linux — instalacja
### Skrypt jednolinijkowy (docelowy UX)
```bash
curl -fsSL https://github.com/twoj-user/vulp/releases/latest/download/install.sh | bash
```
Skrypt robi:
1. Wykrywa architekturę (`uname -m`)
2. Pobiera odpowiednią binarkę z GitHub Releases
3. Umieszcza ją w `~/.local/bin/vulp`
4. Dodaje `~/.local/bin` do `$PATH` w `.bashrc`/`.zshrc` jeśli jeszcze nie ma
5. Jeśli brak konfiguracji → uruchamia `vulp setup` (first-run wizard)
```bash
#!/bin/bash
set -e
ARCH=$(uname -m)
OS=linux
case $ARCH in
x86_64) FILE="vulp-linux-x64" ;;
aarch64) FILE="vulp-linux-arm64" ;;
*) echo "Nieobsługiwana architektura: $ARCH"; exit 1 ;;
esac
LATEST=$(curl -s https://api.github.com/repos/twoj-user/vulp/releases/latest | grep tag_name | cut -d '"' -f 4)
URL="https://github.com/twoj-user/vulp/releases/download/${LATEST}/${FILE}"
mkdir -p ~/.local/bin
curl -fsSL "$URL" -o ~/.local/bin/vulp
chmod +x ~/.local/bin/vulp
# Dodaj do PATH jeśli brak
if ! echo "$PATH" | grep -q "$HOME/.local/bin"; then
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
export PATH="$HOME/.local/bin:$PATH"
fi
echo "vulp zainstalowany. Uruchamianie konfiguracji..."
vulp setup
```
### Opcjonalnie: pakiety .deb i .rpm
Generowane przez `cargo-deb` i `cargo-rpm` w CI — przydatne dla systemów zarządzanych przez IT.
```bash
# Ubuntu/Debian
sudo dpkg -i vulp_0.1.0_amd64.deb
# Fedora/RHEL/CentOS
sudo rpm -i vulp-0.1.0.x86_64.rpm
```
---
## Windows — instalacja
### Opcja A: Kliknięcie `.exe` (docelowy UX dla grafika)
Gdy użytkownik dwukrotnie kliknie `vulp-windows-x64.exe` bez żadnych argumentów i brak konfiguracji, zamiast wyświetlić help i zamknąć okno — **otwiera PowerShell z konfiguratorem**.
Implementacja w `src/main.rs`:
```rust
#[cfg(windows)]
fn ensure_console() {
// Jeśli uruchomiono przez dwuklik (nie z terminala), otwórz nowe okno konsoli
// i uruchom vulp setup w nim
use std::os::windows::process::CommandExt;
if !is_launched_from_terminal() {
std::process::Command::new("cmd")
.args(["/k", "vulp.exe", "setup"])
.creation_flags(0x00000010) // CREATE_NEW_CONSOLE
.spawn().ok();
std::process::exit(0);
}
}
```
### Opcja B: Skrypt PowerShell (instalacja systemowa)
```powershell
# Wklej w PowerShell jako Administrator:
iwr https://github.com/twoj-user/vulp/releases/latest/download/install.ps1 | iex
```
Skrypt:
1. Pobiera `vulp-windows-x64.exe`
2. Umieszcza w `%USERPROFILE%\AppData\Local\vulp\`
3. Dodaje ten folder do `$PATH` (przez `[Environment]::SetEnvironmentVariable`)
4. Uruchamia `vulp setup` w nowym oknie terminalu
### Opcja C: WinGet (Microsoft Store CLI) — przyszłość
```
winget install vulp
```
Wymaga zgłoszenia pakietu do repozytorium `winget-pkgs`.
---
## macOS — instalacja
### Homebrew (docelowy UX)
```bash
brew install twoj-user/tap/vulp
```
Wymaga stworzenia własnego "tap" (repozytorium z formularzem Homebrew):
```ruby
# Formula/vulp.rb
class Vulp < Formula
desc "Multi-repository git workflow manager"
homepage "https://github.com/twoj-user/vulp"
version "0.1.0"
on_macos do
if Hardware::CPU.arm?
url "https://github.com/twoj-user/vulp/releases/download/v0.1.0/vulp-macos-arm64"
sha256 "..."
else
url "https://github.com/twoj-user/vulp/releases/download/v0.1.0/vulp-macos-x64"
sha256 "..."
end
end
def install
bin.install "vulp-macos-arm64" => "vulp"
end
end
```
---
## First-run wizard
Kluczowy element UX. Gdy użytkownik uruchamia **dowolną komendę** po raz pierwszy (brak `~/.vulp/config.toml`), zamiast error'a dostaje automatyczny setup.
Implementacja w `src/app.rs`, przed każdym `match cli.command`:
```rust
// src/app.rs
pub async fn run(cli: Cli) -> Result<()> {
// Jeśli brak konfiguracji → uruchom first-run setup
if !config::config_path().exists() {
println!("Wygląda na to, że uruchamiasz vulp po raz pierwszy.");
println!("Przeprowadźmy krótką konfigurację (zajmie ~2 minuty).\n");
first_run_setup().await?;
}
let cfg = config::load_config()?;
// ... reszta
}
async fn first_run_setup() -> Result<()> {
// 1. Uruchom config TUI
let cfg = config::run_first_time().await?;
// 2. Zapytaj o dodanie konta
if inquire::Confirm::new("Czy chcesz teraz podłączyć konto GitHub/GitLab?")
.with_default(true).prompt()? {
// Uruchom auth add wizard
auth::run_add_wizard(&cfg).await?;
}
println!("\nGotowe! Wpisz 'vulp status' żeby zobaczyć swoje projekty.");
Ok(())
}
```
---
## Systemowe zależności — problemy i rozwiązania
| Zależność | Problem | Rozwiązanie |
|---|---|---|
| `libgit2` | Wymagana na Linuksie przy dynamicznym linkowaniu | Używamy `git2` z feature `vendored` — kompiluje libgit2 statycznie |
| `keyring` / `libsecret` | Wymaga `dbus` na Linuksie headless | Fallback do zaszyfrowanego pliku `~/.vulp/credentials.enc` gdy brak dbus |
| `openssl` | Różne wersje na różnych systemach | Feature `native-tls` → `rustls` — TLS w całości wbudowany w Rust |
```toml
# Cargo.toml — docelowa konfiguracja dla statycznych binarek
[dependencies]
git2 = { version = "0.19", features = ["vendored"] }
reqwest = { version = "0.12", features = ["json", "rustls-tls"], default-features = false }
keyring = { version = "3", features = ["sync-secret-service"] }
```
---
## O nazwie
Aktualna nazwa `vulp` ("finally executable git") to placeholder — dobra jako codename, ale przed publicznym wydaniem warto rozważyć zmianę.
Kryteria dobrej nazwy narzędzia CLI:
- Krótka (2–4 znaki idealne, max 6)
- Łatwa do wymówienia i zapamiętania
- Nie koliduje z istniejącymi komendami systemowymi
- Nawiązuje do funkcji (opcjonalnie)
Kilka luźnych kierunków (bez rekomendacji — ostateczna decyzja należy do Ciebie):
- Coś od "workspace" / "repos" / "git"
- Coś sugerującego "wielość" lub "hub"
- Akronim który znaczy coś po polsku, a po angielsku brzmi jak komenda
Niezależnie od wyboru nazwy — warto go podjąć przed stworzeniem Homebrew tap i pierwszym publicznym Release, bo zmiana nazwy binarki po publikacji jest uciążliwa.
---
## Roadmap dystrybucji
```
v0.1 (teraz) cargo install — tylko dla developerów
v0.2 GitHub Releases z binaries (Linux + Windows + macOS)
Skrypt instalacyjny curl | bash
v0.3 First-run wizard (bez potrzeby wpisywania komend setup)
PowerShell install script dla Windows
v0.4 Homebrew tap dla macOS
v1.0 Stabilny API, binarka klikalna na Windows
WinGet (opcjonalnie)
Pakiety .deb/.rpm (opcjonalnie)
```