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:
1 parent
5787b14880
commit
0468c032c6
100 files changed
+11614
-9840
No files matched your search
+115
@@ -0,0 +1,115 @@
|
||||
# vulp CLI — reference
|
||||
|
||||
Complete non-interactive surface. Written for machine consumers (AI agents,
|
||||
scripts) as much as humans: every read command supports `--json`, nothing
|
||||
ever prompts, and exit codes are meaningful.
|
||||
|
||||
```
|
||||
vulp # no args → interactive TUI (humans)
|
||||
vulp <command> [--json] # non-interactive (scripts/AI)
|
||||
```
|
||||
|
||||
## Contract
|
||||
|
||||
- **`--json`** (global flag): machine-readable JSON on stdout. Available on:
|
||||
`list`, `status`, `scan`, `stats`, `activity`, `todo list`, `pr list`,
|
||||
`issue list`, `project list`, `accounts`, `refresh`.
|
||||
- **No prompts, ever.** Missing input = error + non-zero exit.
|
||||
- **stdout** = results only. **stderr** = progress and errors.
|
||||
- **Exit codes:** `0` ok · `1` execution error · `2` bad usage ·
|
||||
`3` auth missing/invalid · `4` not found (repo/todo/project).
|
||||
- Repo arguments match the display label **or** the directory basename,
|
||||
case-insensitively (e.g. `vulp status vulp` matches "Vulp - Open Source!").
|
||||
- Mutating commands write to the same `~/.vulp/activity.log` as the TUI,
|
||||
so CLI actions appear in the TUI's Overview feed.
|
||||
|
||||
## Workspace (local, no network)
|
||||
|
||||
```
|
||||
vulp scan # repo count + dirty/behind/ahead summary
|
||||
vulp list [--dirty] [--behind] [--ahead] [--lang ts] [--project NAME]
|
||||
vulp status <repo> # branch, dirty, ahead/behind, last commit...
|
||||
vulp stats [--period 1d|7d|30d|90d|1y|all] # commits per repo in period
|
||||
vulp activity [--limit N] [--kind push|pull|release|"new repo"|todo|pr|issue|commit]
|
||||
```
|
||||
|
||||
`vulp list --json` returns an array of repo objects:
|
||||
```json
|
||||
[{ "name": "...", "path": "...", "branch": "main", "ahead": 0, "behind": 0,
|
||||
"is_dirty": true, "last_commit_msg": "...", "last_commit_age": "2h ago",
|
||||
"last_commit_ts": 1780000000, "last_tag": null, "visibility": null,
|
||||
"owner": "dualfroz", "has_license": false, "lang": "TypeScript 96%",
|
||||
"bookmarked": false, "stars": null, "open_issues": null, "open_prs": null }]
|
||||
```
|
||||
|
||||
## Git operations
|
||||
|
||||
```
|
||||
vulp sync <repo>... [--action pull|push|commit-push] [-m MSG]
|
||||
vulp sync --all --action pull
|
||||
vulp sync --project NAME --action push
|
||||
vulp release <repo> --tag v1.2.0 [--notes "..."] # git tag + push + provider release
|
||||
```
|
||||
|
||||
`commit-push` requires `-m/--message`. `sync` exits 1 if any target failed
|
||||
(per-repo progress on stderr).
|
||||
|
||||
## Todos
|
||||
|
||||
```
|
||||
vulp todo list [--status open|in-progress|done|cancelled] [--json]
|
||||
vulp todo add "Title" [--desc "..."] [--project NAME]
|
||||
vulp todo start|done|cancel|rm <id>
|
||||
```
|
||||
|
||||
## Projects (repo groupings)
|
||||
|
||||
```
|
||||
vulp project list [--json]
|
||||
vulp project create NAME [--color "#e74c3c"]
|
||||
vulp project assign NAME <repo>...
|
||||
vulp project rm NAME
|
||||
```
|
||||
|
||||
## Provider API (needs `vulp auth import` first)
|
||||
|
||||
```
|
||||
vulp pr list [--repo R] [--json] # cached — run `vulp refresh` for fresh
|
||||
vulp pr create --repo R --title T --head BRANCH [--base main]
|
||||
vulp issue list [--repo R] [--json]
|
||||
vulp issue create --repo R --title T [--body "..."]
|
||||
vulp refresh # re-fetch meta + PRs + issues into cache
|
||||
vulp init NAME [--private] [--description "..."] # local init + create remote + push
|
||||
vulp accounts [--json]
|
||||
```
|
||||
|
||||
`pr/issue list` read the on-disk cache (`~/.vulp/`) — the same one the TUI
|
||||
uses; run `vulp refresh` first when freshness matters.
|
||||
|
||||
## Per-repo utilities
|
||||
|
||||
```
|
||||
vulp repo url <repo> # print origin URL
|
||||
vulp repo path <repo> # print absolute path
|
||||
vulp repo open <repo> # open provider page in browser
|
||||
vulp repo label <repo> "Display Name" # empty name clears the label
|
||||
vulp repo bookmark <repo> # toggle
|
||||
vulp repo pin <repo> # toggle
|
||||
vulp repo collab <repo> <user> [--role pull|push|admin]
|
||||
```
|
||||
|
||||
## Recipes for AI agents
|
||||
|
||||
```bash
|
||||
# What needs attention right now?
|
||||
vulp list --dirty --json
|
||||
|
||||
# Commit and push everything in one project
|
||||
vulp sync --project client-panel --action commit-push -m "chore: batch update"
|
||||
|
||||
# Fresh cross-repo picture (meta + PRs + issues), then read it
|
||||
vulp refresh --json && vulp pr list --json
|
||||
|
||||
# Weekly activity summary
|
||||
vulp stats --period 7d --json
|
||||
```
|
||||
+41
-41
@@ -1,4 +1,4 @@
|
||||
# fxg — strategia cross-platform
|
||||
# vulp — strategia cross-platform
|
||||
|
||||
> Cel: jedna binarka, trzy systemy, instalacja w 30 sekund, zero wiedzy technicznej wymaganej.
|
||||
|
||||
@@ -14,9 +14,9 @@ Obecny problem z `keyring`: na Linuksie wymaga `libdbus` lub `libsecret`. Do roz
|
||||
|
||||
## Cel UX instalacji
|
||||
|
||||
**Windows:** Pobierasz plik `.exe`. Klikasz go dwukrotnie. Otwiera się terminal z konfiguratorem. Po 2 minutach piszesz `fxg status` i to działa.
|
||||
**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 `fxg 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.
|
||||
|
||||
@@ -35,19 +35,19 @@ strategy:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: x86_64-unknown-linux-musl # statyczna binarka — działa na każdym Linuksie
|
||||
artifact: fxg-linux-x64
|
||||
artifact: vulp-linux-x64
|
||||
- os: ubuntu-latest
|
||||
target: aarch64-unknown-linux-musl # ARM (np. Raspberry Pi, nowe serwery)
|
||||
artifact: fxg-linux-arm64
|
||||
artifact: vulp-linux-arm64
|
||||
- os: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
artifact: fxg-windows-x64.exe
|
||||
artifact: vulp-windows-x64.exe
|
||||
- os: macos-latest
|
||||
target: x86_64-apple-darwin
|
||||
artifact: fxg-macos-x64
|
||||
artifact: vulp-macos-x64
|
||||
- os: macos-latest
|
||||
target: aarch64-apple-darwin # Apple Silicon (M1/M2/M3)
|
||||
artifact: fxg-macos-arm64
|
||||
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).
|
||||
@@ -61,15 +61,15 @@ Pliki lądują w GitHub Releases jako Assets. Użytkownik pobiera odpowiedni pli
|
||||
### Skrypt jednolinijkowy (docelowy UX)
|
||||
|
||||
```bash
|
||||
curl -fsSL https://github.com/twoj-user/fxg/releases/latest/download/install.sh | 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/fxg`
|
||||
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 `fxg setup` (first-run wizard)
|
||||
5. Jeśli brak konfiguracji → uruchamia `vulp setup` (first-run wizard)
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
@@ -77,17 +77,17 @@ set -e
|
||||
ARCH=$(uname -m)
|
||||
OS=linux
|
||||
case $ARCH in
|
||||
x86_64) FILE="fxg-linux-x64" ;;
|
||||
aarch64) FILE="fxg-linux-arm64" ;;
|
||||
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/fxg/releases/latest | grep tag_name | cut -d '"' -f 4)
|
||||
URL="https://github.com/twoj-user/fxg/releases/download/${LATEST}/${FILE}"
|
||||
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/fxg
|
||||
chmod +x ~/.local/bin/fxg
|
||||
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
|
||||
@@ -95,8 +95,8 @@ if ! echo "$PATH" | grep -q "$HOME/.local/bin"; then
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
fi
|
||||
|
||||
echo "fxg zainstalowany. Uruchamianie konfiguracji..."
|
||||
fxg setup
|
||||
echo "vulp zainstalowany. Uruchamianie konfiguracji..."
|
||||
vulp setup
|
||||
```
|
||||
|
||||
### Opcjonalnie: pakiety .deb i .rpm
|
||||
@@ -105,10 +105,10 @@ Generowane przez `cargo-deb` i `cargo-rpm` w CI — przydatne dla systemów zarz
|
||||
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo dpkg -i fxg_0.1.0_amd64.deb
|
||||
sudo dpkg -i vulp_0.1.0_amd64.deb
|
||||
|
||||
# Fedora/RHEL/CentOS
|
||||
sudo rpm -i fxg-0.1.0.x86_64.rpm
|
||||
sudo rpm -i vulp-0.1.0.x86_64.rpm
|
||||
```
|
||||
|
||||
---
|
||||
@@ -117,18 +117,18 @@ sudo rpm -i fxg-0.1.0.x86_64.rpm
|
||||
|
||||
### Opcja A: Kliknięcie `.exe` (docelowy UX dla grafika)
|
||||
|
||||
Gdy użytkownik dwukrotnie kliknie `fxg-windows-x64.exe` bez żadnych argumentów i brak konfiguracji, zamiast wyświetlić help i zamknąć okno — **otwiera PowerShell z konfiguratorem**.
|
||||
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 fxg setup w nim
|
||||
// i uruchom vulp setup w nim
|
||||
use std::os::windows::process::CommandExt;
|
||||
if !is_launched_from_terminal() {
|
||||
std::process::Command::new("cmd")
|
||||
.args(["/k", "fxg.exe", "setup"])
|
||||
.args(["/k", "vulp.exe", "setup"])
|
||||
.creation_flags(0x00000010) // CREATE_NEW_CONSOLE
|
||||
.spawn().ok();
|
||||
std::process::exit(0);
|
||||
@@ -140,19 +140,19 @@ fn ensure_console() {
|
||||
|
||||
```powershell
|
||||
# Wklej w PowerShell jako Administrator:
|
||||
iwr https://github.com/twoj-user/fxg/releases/latest/download/install.ps1 | iex
|
||||
iwr https://github.com/twoj-user/vulp/releases/latest/download/install.ps1 | iex
|
||||
```
|
||||
|
||||
Skrypt:
|
||||
1. Pobiera `fxg-windows-x64.exe`
|
||||
2. Umieszcza w `%USERPROFILE%\AppData\Local\fxg\`
|
||||
1. Pobiera `vulp-windows-x64.exe`
|
||||
2. Umieszcza w `%USERPROFILE%\AppData\Local\vulp\`
|
||||
3. Dodaje ten folder do `$PATH` (przez `[Environment]::SetEnvironmentVariable`)
|
||||
4. Uruchamia `fxg setup` w nowym oknie terminalu
|
||||
4. Uruchamia `vulp setup` w nowym oknie terminalu
|
||||
|
||||
### Opcja C: WinGet (Microsoft Store CLI) — przyszłość
|
||||
|
||||
```
|
||||
winget install fxg
|
||||
winget install vulp
|
||||
```
|
||||
|
||||
Wymaga zgłoszenia pakietu do repozytorium `winget-pkgs`.
|
||||
@@ -164,30 +164,30 @@ Wymaga zgłoszenia pakietu do repozytorium `winget-pkgs`.
|
||||
### Homebrew (docelowy UX)
|
||||
|
||||
```bash
|
||||
brew install twoj-user/tap/fxg
|
||||
brew install twoj-user/tap/vulp
|
||||
```
|
||||
|
||||
Wymaga stworzenia własnego "tap" (repozytorium z formularzem Homebrew):
|
||||
|
||||
```ruby
|
||||
# Formula/fxg.rb
|
||||
class Fxg < Formula
|
||||
# Formula/vulp.rb
|
||||
class Vulp < Formula
|
||||
desc "Multi-repository git workflow manager"
|
||||
homepage "https://github.com/twoj-user/fxg"
|
||||
homepage "https://github.com/twoj-user/vulp"
|
||||
version "0.1.0"
|
||||
|
||||
on_macos do
|
||||
if Hardware::CPU.arm?
|
||||
url "https://github.com/twoj-user/fxg/releases/download/v0.1.0/fxg-macos-arm64"
|
||||
url "https://github.com/twoj-user/vulp/releases/download/v0.1.0/vulp-macos-arm64"
|
||||
sha256 "..."
|
||||
else
|
||||
url "https://github.com/twoj-user/fxg/releases/download/v0.1.0/fxg-macos-x64"
|
||||
url "https://github.com/twoj-user/vulp/releases/download/v0.1.0/vulp-macos-x64"
|
||||
sha256 "..."
|
||||
end
|
||||
end
|
||||
|
||||
def install
|
||||
bin.install "fxg-macos-arm64" => "fxg"
|
||||
bin.install "vulp-macos-arm64" => "vulp"
|
||||
end
|
||||
end
|
||||
```
|
||||
@@ -196,7 +196,7 @@ end
|
||||
|
||||
## First-run wizard
|
||||
|
||||
Kluczowy element UX. Gdy użytkownik uruchamia **dowolną komendę** po raz pierwszy (brak `~/.fxg/config.toml`), zamiast error'a dostaje automatyczny setup.
|
||||
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`:
|
||||
|
||||
@@ -205,7 +205,7 @@ Implementacja w `src/app.rs`, przed każdym `match cli.command`:
|
||||
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 fxg po raz pierwszy.");
|
||||
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?;
|
||||
}
|
||||
@@ -223,7 +223,7 @@ async fn first_run_setup() -> Result<()> {
|
||||
// Uruchom auth add wizard
|
||||
auth::run_add_wizard(&cfg).await?;
|
||||
}
|
||||
println!("\nGotowe! Wpisz 'fxg status' żeby zobaczyć swoje projekty.");
|
||||
println!("\nGotowe! Wpisz 'vulp status' żeby zobaczyć swoje projekty.");
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
@@ -235,7 +235,7 @@ async fn first_run_setup() -> Result<()> {
|
||||
| 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 `~/.fxg/credentials.enc` gdy brak dbus |
|
||||
| `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
|
||||
@@ -250,7 +250,7 @@ keyring = { version = "3", features = ["sync-secret-service"] }
|
||||
|
||||
## O nazwie
|
||||
|
||||
Aktualna nazwa `fxg` ("finally executable git") to placeholder — dobra jako codename, ale przed publicznym wydaniem warto rozważyć zmianę.
|
||||
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)
|
||||
|
||||
+28
-28
@@ -1,4 +1,4 @@
|
||||
# Poradnik dla grafika — jak używać fxg
|
||||
# Poradnik dla grafika — jak używać vulp
|
||||
|
||||
> Ten poradnik zakłada, że nigdy wcześniej nie używałeś terminalu do pracy z kodem. Spokojnie — to jest prostsze niż myślisz.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## Co to jest i po co to komuś?
|
||||
|
||||
Wyobraź sobie, że każdy projekt (strona, aplikacja, assets) mieszka w osobnym folderze na GitHubie. `fxg` to program, który pozwala ci zarządzać tymi wszystkimi folderami jednocześnie — zobaczyć co się zmieniło, wysłać zmiany na serwer, pobrać najnowszą wersję — wszystko bez klikania po interfejsie GitHuba.
|
||||
Wyobraź sobie, że każdy projekt (strona, aplikacja, assets) mieszka w osobnym folderze na GitHubie. `vulp` to program, który pozwala ci zarządzać tymi wszystkimi folderami jednocześnie — zobaczyć co się zmieniło, wysłać zmiany na serwer, pobrać najnowszą wersję — wszystko bez klikania po interfejsie GitHuba.
|
||||
|
||||
**Dla Ciebie oznacza to:** zamiast wchodzić na stronę GitHuba i klikać w każde repozytorium osobno, wpisujesz jedną komendę i widzisz status wszystkiego.
|
||||
|
||||
@@ -16,10 +16,10 @@ Wyobraź sobie, że każdy projekt (strona, aplikacja, assets) mieszka w osobnym
|
||||
|
||||
### Windows
|
||||
|
||||
1. Pobierz plik `fxg.exe` z sekcji [Releases](https://github.com/twoj-team/fxg/releases) (zakładka "Assets")
|
||||
1. Pobierz plik `vulp.exe` z sekcji [Releases](https://github.com/twoj-team/vulp/releases) (zakładka "Assets")
|
||||
2. Przenieś plik do folderu `C:\Users\TwojeImie\` (czyli do swojego folderu domowego)
|
||||
3. Otwórz **Terminal** (wyszukaj "Terminal" w menu Start, lub `Windows + R` → wpisz `cmd` → Enter)
|
||||
4. Wpisz `fxg --version` i naciśnij Enter — jeśli widzisz numer wersji, instalacja się udała
|
||||
4. Wpisz `vulp --version` i naciśnij Enter — jeśli widzisz numer wersji, instalacja się udała
|
||||
|
||||
> Jeśli system pyta "Czy chcesz uruchomić ten plik?" — kliknij "Tak" / "Uruchom mimo to".
|
||||
|
||||
@@ -27,14 +27,14 @@ Wyobraź sobie, że każdy projekt (strona, aplikacja, assets) mieszka w osobnym
|
||||
|
||||
Otwórz terminal i wklej:
|
||||
```
|
||||
curl -fsSL https://github.com/twoj-team/fxg/install.sh | bash
|
||||
curl -fsSL https://github.com/twoj-team/vulp/install.sh | bash
|
||||
```
|
||||
Gotowe.
|
||||
|
||||
### macOS
|
||||
|
||||
```
|
||||
brew install twoj-team/tap/fxg
|
||||
brew install twoj-team/tap/vulp
|
||||
```
|
||||
(wymaga Homebrew — jeśli nie masz, zapytaj kolegę programistę)
|
||||
|
||||
@@ -45,7 +45,7 @@ brew install twoj-team/tap/fxg
|
||||
Otwórz terminal i wpisz:
|
||||
|
||||
```
|
||||
fxg config
|
||||
vulp config
|
||||
```
|
||||
|
||||
Pojawi się ekran konfiguracji. Ustaw:
|
||||
@@ -66,7 +66,7 @@ Potrzebujesz **tokenu dostępu** z GitHuba. Oto jak go zdobyć:
|
||||
|
||||
1. Wejdź na [github.com/settings/tokens](https://github.com/settings/tokens)
|
||||
2. Kliknij **"Generate new token (classic)"**
|
||||
3. Wpisz nazwę (np. "fxg na moim laptopie")
|
||||
3. Wpisz nazwę (np. "vulp na moim laptopie")
|
||||
4. Zaznacz: `repo` (cały zakres)
|
||||
5. Kliknij **"Generate token"** na dole
|
||||
6. **Skopiuj token** — zobaczysz go tylko raz!
|
||||
@@ -74,7 +74,7 @@ Potrzebujesz **tokenu dostępu** z GitHuba. Oto jak go zdobyć:
|
||||
Teraz wróć do terminalu i wpisz (zamień `TWOJ_TOKEN` na skopiowany token):
|
||||
|
||||
```
|
||||
fxg auth add --provider github --token TWOJ_TOKEN
|
||||
vulp auth add --provider github --token TWOJ_TOKEN
|
||||
```
|
||||
|
||||
Gotowe. Token jest bezpiecznie zapisany na Twoim komputerze.
|
||||
@@ -86,7 +86,7 @@ Gotowe. Token jest bezpiecznie zapisany na Twoim komputerze.
|
||||
### Sprawdź co się dzieje we wszystkich projektach
|
||||
|
||||
```
|
||||
fxg status
|
||||
vulp status
|
||||
```
|
||||
|
||||
Zobaczysz tabelę z projektami. Co oznaczają kolumny:
|
||||
@@ -112,7 +112,7 @@ Zobaczysz tabelę z projektami. Co oznaczają kolumny:
|
||||
Jeśli `BEHIND` pokazuje liczbę większą od 0, ktoś dodał zmiany na serwerze. Pobierz je:
|
||||
|
||||
```
|
||||
fxg sync pull --all
|
||||
vulp sync pull --all
|
||||
```
|
||||
|
||||
To pobierze najnowszą wersję **wszystkich** projektów naraz.
|
||||
@@ -124,7 +124,7 @@ To pobierze najnowszą wersję **wszystkich** projektów naraz.
|
||||
Masz nowe pliki (np. nowe grafiki, zaktualizowane assets)? Użyj interaktywnego trybu:
|
||||
|
||||
```
|
||||
fxg sync
|
||||
vulp sync
|
||||
```
|
||||
|
||||
Pojawi się ekran z listą projektów. Obsługa:
|
||||
@@ -142,7 +142,7 @@ Pojawi się ekran z listą projektów. Obsługa:
|
||||
### Szybki push z linii komend (jeśli wiesz co robisz)
|
||||
|
||||
```
|
||||
fxg sync push --all -m "aktualizacja grafik landing page"
|
||||
vulp sync push --all -m "aktualizacja grafik landing page"
|
||||
```
|
||||
|
||||
To jednocześnie commita (z wiadomością po `-m`) i pushuje wszystkie zmienione projekty.
|
||||
@@ -165,23 +165,23 @@ To jednocześnie commita (z wiadomością po `-m`) i pushuje wszystkie zmienione
|
||||
|
||||
## Coś nie działa?
|
||||
|
||||
**Terminal nie zna komendy `fxg`**
|
||||
- Windows: sprawdź czy plik `fxg.exe` jest w folderze który jest w PATH. Najprostsze rozwiązanie: przenieś plik do `C:\Windows\System32\`
|
||||
- Linux/Mac: sprawdź czy `~/.cargo/bin` jest w PATH, lub uruchom ręcznie: `./fxg`
|
||||
**Terminal nie zna komendy `vulp`**
|
||||
- Windows: sprawdź czy plik `vulp.exe` jest w folderze który jest w PATH. Najprostsze rozwiązanie: przenieś plik do `C:\Windows\System32\`
|
||||
- Linux/Mac: sprawdź czy `~/.cargo/bin` jest w PATH, lub uruchom ręcznie: `./vulp`
|
||||
|
||||
**"Permission denied" lub "access denied"**
|
||||
- Linux/Mac: wpisz `chmod +x fxg` przed pierwszym uruchomieniem
|
||||
- Linux/Mac: wpisz `chmod +x vulp` przed pierwszym uruchomieniem
|
||||
|
||||
**"Authentication failed" przy push/pull**
|
||||
- Token prawdopodobnie wygasł lub nie ma uprawnień do `repo`
|
||||
- Wygeneruj nowy token i dodaj: `fxg auth add --provider github --token NOWY_TOKEN`
|
||||
- Wygeneruj nowy token i dodaj: `vulp auth add --provider github --token NOWY_TOKEN`
|
||||
|
||||
**Nie widzę swoich projektów w `fxg status`**
|
||||
- Sprawdź czy `workspace_root` w `fxg config` wskazuje na właściwy folder
|
||||
**Nie widzę swoich projektów w `vulp status`**
|
||||
- Sprawdź czy `workspace_root` w `vulp config` wskazuje na właściwy folder
|
||||
- Folder musi zawierać podfoldery z projektami (każdy projekt to osobny podfolder z `.git` w środku)
|
||||
|
||||
**Zmiany się nie wysyłają, `fxg sync push` nic nie robi**
|
||||
- Najpierw sprawdź `fxg status` — kolumna `DIRTY` musi być `✓` żeby był co wysyłać
|
||||
**Zmiany się nie wysyłają, `vulp sync push` nic nie robi**
|
||||
- Najpierw sprawdź `vulp status` — kolumna `DIRTY` musi być `✓` żeby był co wysyłać
|
||||
- Jeśli `DIRTY` jest `✗`, ale `AHEAD` > 0 — wystarczy sam push bez commita
|
||||
|
||||
---
|
||||
@@ -189,10 +189,10 @@ To jednocześnie commita (z wiadomością po `-m`) i pushuje wszystkie zmienione
|
||||
## Szybka ściąga
|
||||
|
||||
```
|
||||
fxg status # sprawdź co się dzieje
|
||||
fxg sync pull --all # pobierz najnowsze wersje
|
||||
fxg sync # interaktywny ekran: commit + push
|
||||
fxg sync push --all -m "opis zmian" # szybki commit + push
|
||||
fxg auth add --provider github --token TOKEN # dodaj konto
|
||||
fxg config # zmień ustawienia
|
||||
vulp status # sprawdź co się dzieje
|
||||
vulp sync pull --all # pobierz najnowsze wersje
|
||||
vulp sync # interaktywny ekran: commit + push
|
||||
vulp sync push --all -m "opis zmian" # szybki commit + push
|
||||
vulp auth add --provider github --token TOKEN # dodaj konto
|
||||
vulp config # zmień ustawienia
|
||||
```
|
||||
+58
-58
@@ -1,4 +1,4 @@
|
||||
# fxg — pomysły na QoL (Quality of Life)
|
||||
# vulp — pomysły na QoL (Quality of Life)
|
||||
|
||||
> Dokument roboczy. Każdy pomysł ma tytuł, opis, przykład użycia i szacunkową trudność implementacji.
|
||||
|
||||
@@ -6,21 +6,21 @@
|
||||
|
||||
## Wysoki priorytet
|
||||
|
||||
### 1. `fxg clone` — pobierz wszystkie repozytoria jedną komendą
|
||||
### 1. `vulp clone` — pobierz wszystkie repozytoria jedną komendą
|
||||
|
||||
**Problem:** Na nowym laptopie masz 50 repo na GitHubie. Musisz je klonować jedno po drugim. Żmudne.
|
||||
|
||||
**Rozwiązanie:** Komenda pobierająca listę repo z API i klonująca je do `workspace_root`.
|
||||
|
||||
```bash
|
||||
fxg clone --mine # repo których jesteś właścicielem
|
||||
fxg clone --contributed # repo w których robiłeś commity (contributor)
|
||||
fxg clone --org mojaFirma # wszystkie repo organizacji
|
||||
fxg clone --starred # repo które oznaczyłeś gwiazdką
|
||||
vulp clone --mine # repo których jesteś właścicielem
|
||||
vulp clone --contributed # repo w których robiłeś commity (contributor)
|
||||
vulp clone --org mojaFirma # wszystkie repo organizacji
|
||||
vulp clone --starred # repo które oznaczyłeś gwiazdką
|
||||
|
||||
# z filtrowaniem
|
||||
fxg clone --mine --filter "frontend" # tylko repo z "frontend" w nazwie
|
||||
fxg clone --mine --limit 20 # max 20 repo
|
||||
vulp clone --mine --filter "frontend" # tylko repo z "frontend" w nazwie
|
||||
vulp clone --mine --limit 20 # max 20 repo
|
||||
```
|
||||
|
||||
**Implementacja:** Wywołać `provider.list_repos()` (nowa metoda w trait `Provider`), przefiltrować, wywołać `git clone` dla każdego. Wyświetlić progress w TUI podobny do `sync`.
|
||||
@@ -37,15 +37,15 @@ fxg clone --mine --limit 20 # max 20 repo
|
||||
|
||||
```bash
|
||||
# przy tworzeniu repo
|
||||
fxg init moj-projekt --tags dev,frontend
|
||||
vulp init moj-projekt --tags dev,frontend
|
||||
|
||||
# retroaktywnie
|
||||
fxg tag moj-projekt add client-acme
|
||||
fxg tag moj-projekt remove dev
|
||||
vulp tag moj-projekt add client-acme
|
||||
vulp tag moj-projekt remove dev
|
||||
|
||||
# reorganizacja lokalna — przenieś foldery według tagów
|
||||
fxg workspace organize # pyta o potwierdzenie przed każdym przeniesieniem
|
||||
fxg workspace organize --dry-run # pokaż co by się przeniosło, bez wykonania
|
||||
vulp workspace organize # pyta o potwierdzenie przed każdym przeniesieniem
|
||||
vulp workspace organize --dry-run # pokaż co by się przeniosło, bez wykonania
|
||||
```
|
||||
|
||||
**Wynikowa struktura:**
|
||||
@@ -67,21 +67,21 @@ fxg workspace organize --dry-run # pokaż co by się przeniosło, bez wykonani
|
||||
|
||||
---
|
||||
|
||||
### 3. Domyślna paczka plików przy `fxg init`
|
||||
### 3. Domyślna paczka plików przy `vulp init`
|
||||
|
||||
**Problem:** Przy tworzeniu repo trzeba pamiętać o zaznaczeniu README, CHANGELOG, .env.example w wizardzie. Zawsze się o czymś zapomni.
|
||||
|
||||
**Rozwiązanie:** Konfigurowalna lista plików tworzonych domyślnie (bez pytania), z możliwością wyłączenia.
|
||||
|
||||
```toml
|
||||
# ~/.fxg/config.toml
|
||||
# ~/.vulp/config.toml
|
||||
default_init_files = ["README.md", "CHANGELOG.md", ".env.example", ".gitignore"]
|
||||
```
|
||||
|
||||
```bash
|
||||
fxg init moj-projekt # tworzy domyślny zestaw
|
||||
fxg init moj-projekt --no-defaults # tworzy puste repo
|
||||
fxg init moj-projekt --files readme,license # tylko te dwa
|
||||
vulp init moj-projekt # tworzy domyślny zestaw
|
||||
vulp init moj-projekt --no-defaults # tworzy puste repo
|
||||
vulp init moj-projekt --files readme,license # tylko te dwa
|
||||
```
|
||||
|
||||
Dodatkowo: **szablony zawartości pliku README** konfigurowalne w `config.toml` (`readme_template = "heartbyte-default"` już istnieje w konfigu, ale nie jest zaimplementowane).
|
||||
@@ -90,15 +90,15 @@ Dodatkowo: **szablony zawartości pliku README** konfigurowalne w `config.toml`
|
||||
|
||||
---
|
||||
|
||||
### 4. `fxg sync branch cleanup` — sprzątanie zmergowanych gałęzi
|
||||
### 4. `vulp sync branch cleanup` — sprzątanie zmergowanych gałęzi
|
||||
|
||||
**Problem:** Po miesiącach pracy masz 30 lokalnych gałęzi, z których 25 jest już zmergowanych do main. Zajmują miejsce, mylą.
|
||||
|
||||
**Rozwiązanie:**
|
||||
```bash
|
||||
fxg sync branch cleanup # interaktywny wybór (TUI lista)
|
||||
fxg sync branch cleanup --all # usuń wszystkie zmergowane bez pytania
|
||||
fxg sync branch cleanup --dry-run # pokaż co by się usunęło
|
||||
vulp sync branch cleanup # interaktywny wybór (TUI lista)
|
||||
vulp sync branch cleanup --all # usuń wszystkie zmergowane bez pytania
|
||||
vulp sync branch cleanup --dry-run # pokaż co by się usunęło
|
||||
```
|
||||
|
||||
Usuwa gałęzie które są już zmergowane do `main`/`master` — lokalnie i opcjonalnie zdalnie.
|
||||
@@ -113,30 +113,30 @@ Usuwa gałęzie które są już zmergowane do `main`/`master` — lokalnie i opc
|
||||
|
||||
### 5. Shell completions (bash / zsh / fish / PowerShell)
|
||||
|
||||
Wpisanie `fxg <Tab>` podpowiada:
|
||||
Wpisanie `vulp <Tab>` podpowiada:
|
||||
- subkomendy (`status`, `sync`, `init`...)
|
||||
- nazwy repo dla `fxg status <Tab>` → lista repo z workspace_root
|
||||
- nazwy repo dla `vulp status <Tab>` → lista repo z workspace_root
|
||||
- nazwy workspace dla `--workspace <Tab>`
|
||||
- aliasy kont dla `fxg auth switch <Tab>`
|
||||
- aliasy kont dla `vulp auth switch <Tab>`
|
||||
|
||||
```bash
|
||||
fxg completions bash >> ~/.bashrc
|
||||
fxg completions zsh >> ~/.zshrc
|
||||
fxg completions fish > ~/.config/fish/completions/fxg.fish
|
||||
fxg completions powershell >> $PROFILE
|
||||
vulp completions bash >> ~/.bashrc
|
||||
vulp completions zsh >> ~/.zshrc
|
||||
vulp completions fish > ~/.config/fish/completions/vulp.fish
|
||||
vulp completions powershell >> $PROFILE
|
||||
```
|
||||
|
||||
**Implementacja:** `clap` ma wbudowany generator completion przez crate `clap_complete`. Dynamiczne uzupełnianie nazw repo wymaga osobnego skryptu który wywołuje `fxg --list-repos` (nowa ukryta flaga).
|
||||
**Implementacja:** `clap` ma wbudowany generator completion przez crate `clap_complete`. Dynamiczne uzupełnianie nazw repo wymaga osobnego skryptu który wywołuje `vulp --list-repos` (nowa ukryta flaga).
|
||||
|
||||
**Trudność:** niska (statyczne) / średnia (dynamiczne nazwy repo).
|
||||
|
||||
---
|
||||
|
||||
### 6. `fxg status --watch` — live monitoring workspace
|
||||
### 6. `vulp status --watch` — live monitoring workspace
|
||||
|
||||
```bash
|
||||
fxg status --watch # odświeża TUI co 30 sekund
|
||||
fxg status --watch --interval 10 # co 10 sekund
|
||||
vulp status --watch # odświeża TUI co 30 sekund
|
||||
vulp status --watch --interval 10 # co 10 sekund
|
||||
```
|
||||
|
||||
TUI pokazuje kiedy ostatnio odświeżono. Przy zmianie statusu (np. nowy commit na serwerze) wiersz miga przez chwilę na żółto.
|
||||
@@ -147,13 +147,13 @@ TUI pokazuje kiedy ostatnio odświeżono. Przy zmianie statusu (np. nowy commit
|
||||
|
||||
---
|
||||
|
||||
### 7. Szablony projektów (`fxg init --template`)
|
||||
### 7. Szablony projektów (`vulp init --template`)
|
||||
|
||||
```bash
|
||||
fxg init moj-projekt --template react-app
|
||||
fxg init moj-projekt --template rust-cli
|
||||
fxg init moj-projekt --template python-fastapi
|
||||
fxg init moj-projekt --template node-express
|
||||
vulp init moj-projekt --template react-app
|
||||
vulp init moj-projekt --template rust-cli
|
||||
vulp init moj-projekt --template python-fastapi
|
||||
vulp init moj-projekt --template node-express
|
||||
```
|
||||
|
||||
Każdy szablon tworzy kompletną strukturę katalogów i pliki startowe:
|
||||
@@ -161,18 +161,18 @@ Każdy szablon tworzy kompletną strukturę katalogów i pliki startowe:
|
||||
- `rust-cli` → `src/main.rs`, `Cargo.toml` z clap+anyhow, `README.md`
|
||||
- `python-fastapi` → `main.py`, `requirements.txt`, `.env.example`, `Dockerfile`
|
||||
|
||||
Szablony przechowywane w `~/.fxg/templates/` jako foldery — użytkownik może dodać własne.
|
||||
Szablony przechowywane w `~/.vulp/templates/` jako foldery — użytkownik może dodać własne.
|
||||
|
||||
**Trudność:** średnia — logika tworzenia plików jest już w `init/mod.rs`, potrzebny nowy system szablonów.
|
||||
|
||||
---
|
||||
|
||||
### 8. `fxg pr list` — przegląd otwartych PR
|
||||
### 8. `vulp pr list` — przegląd otwartych PR
|
||||
|
||||
```bash
|
||||
fxg pr list # wszystkie PR we wszystkich repo workspace
|
||||
fxg pr list --repo moj-projekt # tylko jedno repo
|
||||
fxg pr list --mine # tylko PR gdzie jesteś autorem lub reviewerem
|
||||
vulp pr list # wszystkie PR we wszystkich repo workspace
|
||||
vulp pr list --repo moj-projekt # tylko jedno repo
|
||||
vulp pr list --mine # tylko PR gdzie jesteś autorem lub reviewerem
|
||||
```
|
||||
|
||||
Wyświetla TUI tabelę: repo | numer | tytuł | autor | data | etykiety.
|
||||
@@ -185,10 +185,10 @@ Enter na PR otwiera URL w przeglądarce.
|
||||
|
||||
---
|
||||
|
||||
### 9. Globalny `.fxgignore` — repo do pominięcia
|
||||
### 9. Globalny `.vulpignore` — repo do pominięcia
|
||||
|
||||
```
|
||||
# ~/.fxg/ignore
|
||||
# ~/.vulp/ignore
|
||||
archived-* # wszystkie repo zaczynające się od "archived-"
|
||||
old-monorepo # konkretne repo po nazwie
|
||||
```
|
||||
@@ -201,12 +201,12 @@ old-monorepo # konkretne repo po nazwie
|
||||
|
||||
---
|
||||
|
||||
### 10. `fxg stats --trend` — wykres aktywności w czasie
|
||||
### 10. `vulp stats --trend` — wykres aktywności w czasie
|
||||
|
||||
```bash
|
||||
fxg stats --trend # ostatnie 30 dni
|
||||
fxg stats --trend --days 90
|
||||
fxg stats --trend --repo api-backend
|
||||
vulp stats --trend # ostatnie 30 dni
|
||||
vulp stats --trend --days 90
|
||||
vulp stats --trend --repo api-backend
|
||||
```
|
||||
|
||||
ASCII wykres słupkowy commitów per dzień:
|
||||
@@ -230,12 +230,12 @@ May 22 ██████████████████░░░ 18
|
||||
|
||||
### 11. VSCode Extension — automatyczne time tracking
|
||||
|
||||
Aktualnie `fxg stats time` czyta pliki JSON z `~/.fxg/vsc-data/`. Trzeba je tworzyć ręcznie lub osobnym narzędziem.
|
||||
Aktualnie `vulp stats time` czyta pliki JSON z `~/.vulp/vsc-data/`. Trzeba je tworzyć ręcznie lub osobnym narzędziem.
|
||||
|
||||
**Rozwiązanie:** Towarzyszące rozszerzenie VS Code które automatycznie zapisuje czas spędzony na plikach w formacie rozumianym przez `fxg`.
|
||||
**Rozwiązanie:** Towarzyszące rozszerzenie VS Code które automatycznie zapisuje czas spędzony na plikach w formacie rozumianym przez `vulp`.
|
||||
|
||||
```
|
||||
fxg stats time # pokazuje automatycznie zbierane dane
|
||||
vulp stats time # pokazuje automatycznie zbierane dane
|
||||
```
|
||||
|
||||
---
|
||||
@@ -257,8 +257,8 @@ Identyczny mechanizm jak audit log w innych projektach z tego zespołu.
|
||||
### 13. AI-assisted commit messages
|
||||
|
||||
```bash
|
||||
fxg sync commit --ai # generuje wiadomość z diff za pomocą AI API
|
||||
fxg sync commit --ai --edit # generuje, ale otwiera edytor do poprawki przed commitem
|
||||
vulp sync commit --ai # generuje wiadomość z diff za pomocą AI API
|
||||
vulp sync commit --ai --edit # generuje, ale otwiera edytor do poprawki przed commitem
|
||||
```
|
||||
|
||||
Wysyła `git diff --staged` do API (np. Claude lub OpenAI), dostaje propozycję wiadomości w stylu conventional commits.
|
||||
@@ -267,7 +267,7 @@ Wymaga klucza API w konfiguracji.
|
||||
|
||||
---
|
||||
|
||||
### 14. `fxg release` multi-platform publish
|
||||
### 14. `vulp release` multi-platform publish
|
||||
|
||||
Po stworzeniu release tagu — automatyczne wyzwolenie publishu na:
|
||||
- `crates.io` (dla Rust)
|
||||
@@ -280,7 +280,7 @@ Wykrywa typ projektu przez `detect_project_type()` (już istnieje w `summary/mod
|
||||
|
||||
### 15. Interaktywny diff viewer
|
||||
|
||||
W widoku szczegółowym repo (`fxg status <repo>`) — klawisz `d` otwiera inlinowy diff zmienionych plików z kolorowym podświetleniem:
|
||||
W widoku szczegółowym repo (`vulp status <repo>`) — klawisz `d` otwiera inlinowy diff zmienionych plików z kolorowym podświetleniem:
|
||||
|
||||
```
|
||||
M src/components/Nav.tsx [d] diff [s] stage [r] revert
|
||||
@@ -297,7 +297,7 @@ W widoku szczegółowym repo (`fxg status <repo>`) — klawisz `d` otwiera inlin
|
||||
|
||||
| # | Pomysł | Priorytet | Trudność |
|
||||
|---|---|---|---|
|
||||
| 1 | `fxg clone --mine/--contributed` | Wysoki | Średnia |
|
||||
| 1 | `vulp clone --mine/--contributed` | Wysoki | Średnia |
|
||||
| 2 | Tagi → organizacja folderów | Wysoki | Średnia |
|
||||
| 3 | Domyślna paczka plików przy init | Wysoki | Niska |
|
||||
| 4 | `branch cleanup` | Wysoki | Niska |
|
||||
@@ -305,7 +305,7 @@ W widoku szczegółowym repo (`fxg status <repo>`) — klawisz `d` otwiera inlin
|
||||
| 6 | `status --watch` | Średni | Niska |
|
||||
| 7 | Szablony projektów | Średni | Średnia |
|
||||
| 8 | `pr list` | Średni | Średnia |
|
||||
| 9 | `.fxgignore` | Średni | Niska |
|
||||
| 9 | `.vulpignore` | Średni | Niska |
|
||||
| 10 | `stats --trend` | Średni | Niska |
|
||||
| 11 | VSCode extension | Przyszłość | Wysoka |
|
||||
| 12 | Webhook przy sync | Przyszłość | Niska |
|
||||
|
||||
Reference in new issue
Block a user