{
  "markdown": "# SSHub\n\n[![crates.io](https://img.shields.io/crates/v/sshub.svg)](https://crates.io/crates/sshub)\n[![crates.io downloads](https://img.shields.io/crates/d/sshub.svg?label=crates.io%20downloads)](https://crates.io/crates/sshub)\n[![npm](https://img.shields.io/npm/v/sshub-tui.svg)](https://www.npmjs.com/package/sshub-tui)\n[![npm downloads](https://img.shields.io/npm/dm/sshub-tui.svg?label=npm%20downloads%2Fmonth)](https://www.npmjs.com/package/sshub-tui)\n[![vibecoded](https://img.shields.io/badge/vibecoded-~98.5%25-ff69b4)](#model-credits)\n\nA terminal UI for managing and connecting to SSH hosts. Combines your `~/.ssh/config` with a built-in host database, tunnels, key management, and an audit log -- all in one keyboard-driven interface.\n\n> ⚠️ This project is ~98.5% vibe-coded slop — see [Model credits](#model-credits) for the ever-growing pack of LLMs responsible — the other ~1.5% is real humans (see Contributors). It has — and will keep having — stupid bugs LLMs can't see. Use at your own risk.\n\n![SSHub demo](https://raw.githubusercontent.com/Petyok/SSHub/main/demo/gifs/hero.gif)\n\nNavigating the dashboard — nested host groups, the fuzzy palette (`/`), the group manager (`Shift+G`), and the multi-tag filter (`#`):\n\n![Navigation demo](https://raw.githubusercontent.com/Petyok/SSHub/main/demo/gifs/navigate.gif)\n\nConnecting to a host — the session runs in an embedded PTY right inside the TUI:\n\n![Connect demo](https://raw.githubusercontent.com/Petyok/SSHub/main/demo/gifs/connect.gif)\n\nAdding a managed host and marking it as a favorite:\n\n![Add host demo](https://raw.githubusercontent.com/Petyok/SSHub/main/demo/gifs/add-host.gif)\n\nTransferring files over SFTP — a dual-pane browser (remote / local) with a staged transfer queue:\n\n![SFTP demo](https://raw.githubusercontent.com/Petyok/SSHub/main/demo/gifs/sftp.gif)\n\n## Screenshots\n\nThe hosts dashboard — nested groups on the left; the selected host's card shows its auto-detected OS logo, fact sheet, and per-host latency, with live agent / ping panels alongside:\n\n![Hosts dashboard](https://raw.githubusercontent.com/Petyok/SSHub/main/demo/screenshots/hosts.png)\n\nFuzzy quick-connect palette (`/`) and the multi-tag filter (`#`):\n\n![Quick-connect palette](https://raw.githubusercontent.com/Petyok/SSHub/main/demo/screenshots/palette.png)\n![Tag filter](https://raw.githubusercontent.com/Petyok/SSHub/main/demo/screenshots/tags.png)\n\nAdd/edit host form, the rebindable keybindings editor (`Ctrl+K`), and the scrollable help overlay (`?`):\n\n![Add host form](https://raw.githubusercontent.com/Petyok/SSHub/main/demo/screenshots/add-host.png)\n![Keybindings editor](https://raw.githubusercontent.com/Petyok/SSHub/main/demo/screenshots/keybindings.png)\n![Help overlay](https://raw.githubusercontent.com/Petyok/SSHub/main/demo/screenshots/help.png)\n\nThe settings overlay (`Ctrl+H`) — make SSHub's own surfaces or the remote grid transparent, toggle OS logos, quit confirmation, and the startup animation:\n\n![Settings overlay](https://raw.githubusercontent.com/Petyok/SSHub/main/demo/screenshots/settings.png)\n\n## Features\n\n- **Embedded SSH sessions** — connect opens an in-TUI PTY; detach with Ctrl+D and return to the dashboard while SSH keeps running; multiple session tabs\n- **Hosts** — browse, search, and connect. Fuzzy search with `/`, multi-tag AND filter with `#`, favorites, nested groups, manual sort order\n- **SFTP file transfer** — a dual-pane browser with a staged transfer queue: navigate both sides, queue uploads and downloads (files or whole folders, transferred recursively), and run them with a progress bar. Files can be staged while the queue runs. The left pane is your local filesystem by default, or point it at a **second server** with `o` (`O` sends it back to local) to move files between two hosts — relayed through a local temp file, since SSH has no server-to-server copy. Manage files in place too: delete (`d`), new folder (`n`), rename/move (`R`), and change permissions (`M`, octal chmod)\n- **OS auto-detection** — on first connect a background probe detects the remote distro and the host card renders its logo (Braille art in brand colors), just like Termius\n- **Multiple groups & Favorites** — a host can belong to several groups at once; a reserved Favorites group and a ★ marker in the list, toggled with `f`\n- **Tunnels** — define and manage SSH tunnels (local/remote/dynamic SOCKS). Start, stop, and monitor from the TUI. Per-tunnel **keep alive** auto-starts on launch and reconnects dropped forwards with exponential backoff (configurable in `config.toml`).\n- **Keys** — identity management with ssh-agent integration. Add/remove keys from agent, see loaded status\n- **Ad-hoc connect** - in the fuzzy palette (`/`), typing an unknown `[user@]host[:port]` (IPv6 in brackets supported) that matches no saved host offers a \"connect without saving\" row; Enter opens an embedded ssh session to it. Input is validated and injection-safe (no leading-dash hosts; destination passed after `--`)\n- **Local shell tab** - `Ctrl+Shift+T` opens a session tab running your login shell (`$SHELL`, else `/bin/sh`) with the same detach/close semantics as ssh tabs\n- **Command snippets** — a library of reusable commands (name, command, optional description and tags). Manage them from the dashboard with `Shift+S` (add/edit/delete); inside a live session `Ctrl+N` opens a fuzzy picker where `Enter` runs the selected command in the PTY and `Tab` inserts it without a trailing newline so you can edit before running\n- **Audit** — log of all connection events with filtering by status (ok/fail) and time range (today/week/month); session connect events record the path to the session log when logging is enabled\n- **Session logging** — opt-in capture of PTY session output to `~/.local/share/sshub/profiles/<name>/logs/<host-dir>/` (managed hosts use `{name}-{id}`; pure `~/.ssh/config` aliases without a launcher row may share a directory when sanitized names collide). Enable globally in Settings (`Ctrl+H`) or override per host (`inherit` / `on` / `off`). **Logs capture everything echoed to the terminal, including passwords if they appear on screen.**\n- **Session log browser** (`Shift+L`): read those session logs inside the TUI. Pick a host, pick a rotated segment, and view it with terminal escape codes stripped so the transcript reads as plain text. In the viewer, `/` searches (case-insensitive), `n` / `N` step through matches, and `b` bookmarks the current line by name. `m` lists a host's bookmarks to jump straight back to a saved line. Reads are capped so a large transcript is never loaded whole.\n- **Mosh transport** — per-host `Transport` field in the host form (`ssh` or `mosh`). Embedded sessions use `mosh` when selected; tunnels and SFTP stay ssh-only.\n- **Settings overlay** (`Ctrl+H`) — toggle session logging, let your terminal show through SSHub's own surfaces or through the remote grid (two separate switches, both off by default), toggle OS logos, quit confirmation, and the startup animation\n- **Headless CLI** — the whole inventory without the TUI: hosts, groups, identities, tunnels, one-shot SFTP, the audit log and themes, plus `sshub exec <host> -- <command>` to run a single command on a saved host and get its output and exit code back (with the stored identity, credential and ProxyJump applied). `--format json` on any listing, stable exit codes, completions for bash/zsh/fish — see [Headless CLI](#headless-cli)\n- **Hybrid sources** — hosts from `~/.ssh/config` (read-only) and launcher-managed (full CRUD) merge without duplicates\n- **Import/Export**: import from `~/.ssh/config`, Termius backups, PuTTY (a Windows regedit `.reg` export or a Unix `~/.putty/sessions` directory), or mRemoteNG (`confCons.xml`); export managed hosts back to ssh config format. Only SSH sessions are imported (RDP/VNC/telnet entries are skipped), and encrypted mRemoteNG passwords are not decrypted (imported hosts carry no stored secret)\n- **Hot reload** — edits to `~/.ssh/config` update the host list live via file watcher\n- **Configurable keybindings** — rebind any action via Ctrl+K; stored in `config.toml`\n- **Mouse support** — click tabs, select rows, scroll panels, double-click to connect\n\n## Install\n\nFrom [npm](https://www.npmjs.com/package/sshub-tui), prebuilt, no toolchain required:\n\n```bash\nnpx sshub-tui              # run it without installing\nnpm install -g sshub-tui   # then just: sshub\n```\n\nThe installed command is `sshub`; the package is `sshub-tui` because npm rejects\nthe bare `sshub` name as too close to the existing `ssh2` and `sshpk`.\n\nPrebuilt for Linux x64, macOS arm64 and macOS x64. The binary arrives as a\nplatform-specific optional dependency, so nothing is compiled and nothing is\nfetched from outside the registry. Any other platform builds from source below.\n\nFrom [crates.io](https://crates.io/crates/sshub):\n\n```bash\ncargo install sshub\n```\n\nRequires a Rust toolchain (edition 2021) and `ssh` in `PATH`.\n\nOn Linux, building also needs the D-Bus client library for the keyring\n(Secret Service) backend that stores host passwords and key passphrases:\n\n```bash\n# Debian/Ubuntu\nsudo apt-get install -y libdbus-1-dev pkg-config\n# Fedora\nsudo dnf install -y dbus-devel pkgconf-pkg-config\n# Arch\nsudo pacman -S --needed dbus\n```\n\nPrebuilt binaries for Linux and macOS are attached to each [GitHub release](https://github.com/Petyok/SSHub/releases).\n\nAt runtime, a Secret Service provider (gnome-keyring, KWallet, …) is preferred for secure credential storage. If one is not running or unlocked (e.g. in WSL, Docker, or headless SSH sessions), SSHub will fallback to storing credentials in a local owner-only restricted file (`credentials.json`), notifying you in the status bar.\n\n```bash\ngit clone https://github.com/Petyok/SSHub.git\ncd SSHub\njust install    # builds release binary + desktop entry + ~/.local/bin/sshub\n```\n\nOr build only:\n\n```bash\njust build\ncp target/release/sshub ~/.local/bin/\n```\n\n## Usage\n\n```bash\nsshub              # launch TUI\nsshub --version    # print version\nsshub --dry-run    # exit immediately (CI / scripts)\nsshub --help       # show options\nsshub --profile work                     # launch named profile\nsshub --manage-profiles                 # open profile picker\n```\n\n### Commands\n\n```bash\n# Wipe the launcher database — managed hosts, groups, identities, tunnels and\n# the audit log. Irreversible, so it refuses unless you confirm. Your\n# ~/.ssh/config (and the hosts imported from it) are left untouched.\nsshub db purge --yes-i-am-stupid\n\n# Target a profile from the TUI or any headless command.\nsshub --profile work host list\nsshub --profile personal audit list\nsshub --profile work db purge --yes-i-am-stupid\n```\n\nSSHUB keeps profile-owned data isolated. Each profile can select its own SSH\nconfig source with `[ssh].config_path`; the default remains shared\n`~/.ssh/config`. With one profile, startup remains silent;\nwith multiple profiles, the picker appears after the splash. The picker can\ncreate, rename, and delete profiles, but switching profiles requires restarting\nSSHUB. `--profile NAME` bypasses the picker. `--manage-profiles` opens it even\nwhen only one profile exists. Press `Esc` in the picker to cancel startup.\nHeadless commands without `--profile` use the last-used profile and never open\nthe interactive picker.\n\n## Headless CLI\n\nBeyond the TUI, `sshub` exposes a full command-line interface for scripting and\nautomation: hosts, groups, identities, tunnels, SFTP, and the audit log, no\nterminal UI required. `sshub exec <host> -- <command>` runs a single command on\na saved host and hands back its output and exit code, so a script gets the\nstored identity, credential and ProxyJump without rebuilding the ssh command\nline by hand. Add `--format json` to any listing or show command for\nmachine-readable output (plain text is the default). Exit codes are stable:\n`0` success, `1` operational failure, `2` usage or bad flags, and `124` when\n`exec --timeout` kills the run (as `timeout(1)` does). Destructive commands\nrefuse to run without `--yes`.\n\n```bash\n# Hosts\nsshub list                                  # list hosts (alias for `host list`)\nsshub connect prod-web                       # open an SSH session to a host\nsshub host show prod-web --format json       # host details as JSON\nsshub host search web                        # fuzzy search\nsshub host add --name prod-web --address 10.0.0.5 --port 22 \\\n    --username deploy --group prod --tags web,prod\nsshub host delete --name prod-web --yes      # destructive: needs --yes\n\n# Run a command on a host (scripted; exit code is the remote command's)\nsshub exec prod-web -- systemctl is-active nginx\nsshub exec prod-web -- 'tail -n 200 /var/log/nginx/error.log' > errors.log\necho \"$payload\" | sshub exec db-01 -- 'psql -f -'\nsshub exec prod-web --timeout 30 --format json -- uptime\nsshub exec prod-web -- 'ls && uptime'        # quote it: bare `&&` runs locally\nsshub exec prod-web --tty -- top             # full-screen commands need a PTY\n\n# Groups and identities\nsshub groups                                 # list host groups\nsshub group add --name prod\nsshub identity add --name work --username alice --private-key ~/.ssh/id_ed25519\nsshub identity agent-remove --name work      # ssh-add -d for the identity's key\n\n# Tunnels\nsshub tunnel list\nsshub tunnel create --host prod-web --type local --local-port 8080 \\\n    --remote-host localhost --remote-port 80\nsshub tunnel start 3                          # start detached (by id, label, or port)\nsshub tunnel start 3 --foreground             # run in the foreground with keep-alive\nsshub tunnel stop 3\n\n# SFTP (one-shot, over a direct host)\nsshub sftp ls prod-web /var/log\nsshub sftp get prod-web /var/log/app.log ./app.log\nsshub sftp put prod-web ./deploy.tar.gz /tmp/deploy.tar.gz\nsshub sftp rm prod-web /tmp/deploy.tar.gz --yes\n\n# Themes (see \"Theming\" below)\nsshub theme list\nsshub theme show aqua\nsshub theme check ~/.config/sshub/themes/mine.toml\n\n# Audit log\nsshub audit list --status fail --days 7\nsshub audit stats --days 7\n\n# Inventory sync with ~/.ssh/config\nsshub import                                  # import hosts from ssh config (--from ssh)\nsshub import --from termius ./termius-export  # import a Termius export dir (L00t.csv)\nsshub import --from putty                      # import PuTTY sessions (~/.putty/sessions)\nsshub import --from putty ./sessions.reg       # or a Windows regedit .reg export\nsshub import --from mremoteng ./confCons.xml   # import an mRemoteNG confCons.xml\nsshub import --from putty --dry-run             # preview parsed hosts without writing\nsshub sync                                    # refresh ssh_config rows\nsshub export --stdout                         # print an ssh_config snippet\n\n# Shell completions\nsshub completions zsh > ~/.zsh/completions/_sshub\nsshub completions bash\nsshub completions fish\n```\n\nRun `sshub <command> --help` for a per-command usage block, or `man sshub`\nafter `just install` (preview the page without installing with `just man`). See\n[openwiki/workflows/cli.md](openwiki/workflows/cli.md) for the full command tree.\n\nShell completions are installed automatically by `just install` (bash and fish\ndrop into auto-loaded dirs; zsh gets a sourced line appended to `~/.zshrc`).\nRun `just install-completions` to (re)install only the completions, or generate\none yourself with `sshub completions bash|zsh|fish`.\n\n### Data paths\n\n| Resource   | Default path                          |\n|------------|---------------------------------------|\n| Config     | `~/.local/share/sshub/profiles/<name>/config.toml` |\n| Themes     | `~/.local/share/sshub/profiles/<name>/themes/*.toml` |\n| Databases  | `~/.local/share/sshub/profiles/<name>/{launcher,metadata}.db` |\n| Logs       | `~/.local/share/sshub/profiles/<name>/logs/`       |\n| Tunnels    | `~/.local/share/sshub/profiles/<name>/tunnels/`    |\n| State      | `~/.local/share/sshub/state.toml`                 |\n| SSH config | `~/.ssh/config`                       |\n\nOverride via environment variables: `SSHUB_CONFIG_DIR`, `SSHUB_DATA_DIR`,\n`SSHUB_SSH_CONFIG`. Setting `SSHUB_CONFIG_DIR` or `SSHUB_DATA_DIR` selects\ncompatibility mode, using those directories verbatim and disabling profile\ndiscovery. Legacy `SSH_LAUNCHER_*` variables remain supported.\n\n## Keybindings\n\nDefaults below. Rebind any action with **Ctrl+K** (saved to `config.toml`). Press `?` in-app for the full list.\n\n### Global\n\n| Key              | Action                          |\n|------------------|---------------------------------|\n| `1`..`5`         | Switch tab (hosts/sftp/tunnels/identities/audit) |\n| `Tab`            | Toggle detail panel             |\n| `Esc`            | Back / close overlay            |\n| `Ctrl+K`         | Keybind editor                  |\n| `?`              | Help screen                     |\n| `q`              | Quit                            |\n\n### Session (embedded PTY)\n\n| Key                    | Action                              |\n|------------------------|-------------------------------------|\n| `Ctrl+T`               | New session tab (host picker)         |\n| `Ctrl+Shift+T`         | Local shell tab                     |\n| `Ctrl+W`               | Close session tab                   |\n| `Ctrl+D`               | Detach to dashboard (SSH keeps running) |\n| `Ctrl+[` / `Ctrl+]`   | Previous / next session tab         |\n| `Ctrl+Shift+S`         | Focus session from dashboard        |\n| `Alt+S`                | Switch to an open session (searchable) |\n| `PgUp`/`PgDn`, wheel   | Scroll session history; both go to the remote app while it holds the alternate screen (tmux, vim, less), where the wheel becomes arrow keys |\n| drag                   | Select terminal text, copied on release; `Shift` inverts it when the remote app owns the mouse |\n\n`Ctrl+W` closes a session tab, but inside a form it kills the word before the\ncursor (`Ctrl+U` kills everything before it) — the host, identity and tunnel\nforms take readline's editing chords.\n\nThe wheel inside `tmux` reaches tmux's own scrollback only with\n`set -g mouse on`; without it tmux never asks for the mouse, so the notch\narrives as arrow keys, exactly as in a real terminal.\n\n### Hosts (tab 1)\n\n| Key                | Action                    |\n|--------------------|---------------------------|\n| `j`/`k` or arrows | Navigate                  |\n| `Enter`            | Connect to host           |\n| `a`                | Add host                  |\n| `e`                | Edit host / group identity |\n| `d`                | Delete host               |\n| `D`                | Duplicate host            |\n| `f`                | Toggle favorite           |\n| `s`                | Cycle sort mode           |\n| `Alt`+arrows       | Move dashboard panel focus |\n| `z`                | Zoom focused panel (Esc to exit) |\n| `/`                | Fuzzy search              |\n| `/` + `[user@]host` | Ad-hoc connect (unknown host, no save) |\n| `#`                | Filter by tags (AND)      |\n| `Shift+G`          | Manage groups (nested)    |\n| `Shift+I`          | Import from ssh config    |\n| `Shift+E`          | Export to ssh config      |\n| `Shift+T`          | Import from Termius       |\n| `Shift+P`          | Push public key to host   |\n\n### SFTP (tab 2)\n\n| Key                | Action                                              |\n|--------------------|-----------------------------------------------------|\n| `Enter`            | Connect to host · enter directory (`..` walks up)    |\n| `Tab`              | Switch focus between the panes                       |\n| `Backspace`        | Up one directory                                     |\n| `←` / `→`          | Stage the focused pane's selection toward the other  |\n| `c` / `u`          | Run the queue / unstage the last transfer            |\n| `o` / `O`          | Left pane to a second server / back to local files   |\n| `.`                | Show / hide dotfiles in both panes (remembered)      |\n| `d`                | Delete (recursive)                                   |\n| `n` / `R` / `M`    | New folder / rename / chmod                          |\n| `r`                | Refresh both panes                                   |\n| `s`                | Open an SSH session to this host                     |\n| `/`                | Filter the focused pane                              |\n| `Esc`              | Disconnect, back to the picker                       |\n\n### Tunnels (tab 3)\n\n| Key       | Action                           |\n|-----------|----------------------------------|\n| `a`       | Add tunnel                       |\n| `e`       | Edit tunnel                      |\n| `d`       | Delete tunnel                    |\n| `Enter`   | Start / stop / cancel reconnect  |\n| `R`       | Reconnect settings               |\n| `x`       | Kill tunnel process              |\n\n### Keys (tab 3)\n\n| Key        | Action                   |\n|------------|--------------------------|\n| `a`        | Add identity             |\n| `e`        | Edit identity            |\n| `d`        | Delete identity          |\n| `g`        | Generate SSH key pair    |\n| `r`        | Remove key from agent    |\n| `Shift+A`  | Add key to agent         |\n| `Shift+P`  | Push public key to host  |\n| `H`        | Known hosts manager      |\n\n### Audit (tab 4)\n\n| Key | Action                              |\n|-----|--------------------------------------|\n| `f` | Cycle filter (all / ok / fail)       |\n| `r` | Cycle range (all / today / week / month) |\n\n## Theming\n\nSSHub's colours live in TOML theme files you can copy, edit and switch at\nruntime. Five themes ship built into the binary — **`default`**, **`summer`**,\n**`aqua`**, **`fire`** and **`high-contrast`** — and your own go in the\nselected profile's `themes/*.toml` directory (or `~/.config/sshub/themes/` in\ncompatibility mode), where the file name is the theme's ID.\n\n```bash\nmkdir -p ~/.local/share/sshub/profiles/<name>/themes\nsshub theme show aqua > ~/.local/share/sshub/profiles/<name>/themes/mine.toml\n$EDITOR ~/.local/share/sshub/profiles/<name>/themes/mine.toml\nsshub theme check ~/.local/share/sshub/profiles/<name>/themes/mine.toml\n```\n\nSelect it in the TUI with **Ctrl+H → Theme… → Enter**: moving through the list\npreviews each theme on the whole interface, `Esc` rolls back, and `Enter` saves\n`appearance.active_theme` to `config.toml`. Nothing else is written.\n\nA theme sets any of three layers — your own `[palette]`, the fixed 25-slot\n`[semantic]` core, and per-role `[components]` overrides — plus named static\n`[gradients]`. Everything you leave out is inherited from `default`, so\nchanging one semantic slot recolours everything that uses it. True Color\nterminals get the colours as written. The embedded remote session keeps every\ncolour the remote chose itself; a theme only supplies the ground and the default\nforeground the remote left unset.\n\nThree headless commands, all without a TUI or a database:\n\n| Command | What it does |\n|---------|--------------|\n| `sshub theme list` | Every built-in and user theme with its state |\n| `sshub theme show <id> [--resolved]` | The theme's source, or a fully resolved standalone export |\n| `sshub theme check <file>` | Strict validation with `file:line:column` diagnostics |\n\n**Full guide: [docs/theme-system.md](docs/theme-system.md)** — the file format,\ncolour values and simulated opacity, inheritance and `\"auto\"`, gradient\ndirections and the `perimeter` rule, the complete role catalogue, every picker\nkey, the CLI exit codes, and two copy-pasteable example themes.\n\n## Configuration\n\n`~/.local/share/sshub/profiles/<name>/config.toml` in profile mode\n(`~/.config/sshub/config.toml` in compatibility mode):\n\n```toml\n[session_logging]\nenabled = false\nmax_file_bytes = 10485760   # rotate at 10 MiB\nretention_files = 50        # keep newest 50 logs per host\n\n[tunnel_reconnect]\nmax_attempts = 12           # 0 = unlimited retries\ninitial_delay_ms = 1000     # 1 s (R overlay edits delays in seconds)\nmax_delay_ms = 60000        # 60 s\nstable_secs = 5             # uptime before a spawn counts as up\njitter_ratio = 0.25\n\n[clipboard]\nrelay_from_pty = true       # let apps inside a session copy to your clipboard\n```\n\n## Development\n\n```bash\njust build             # release binary\njust test              # all tests (unit + smoke + e2e + config)\ncargo run -- --dry-run # quick sanity check\n```\n\n### Test levels\n\n| Level    | Command                       | What it checks                       |\n|----------|-------------------------------|--------------------------------------|\n| Unit     | `cargo test`                  | Logic, parsers, fixtures -- no TTY   |\n| Smoke    | `cargo test --test smoke`     | Binary starts, `--help`, `--dry-run` |\n| E2E      | `cargo test --test e2e`       | TUI scenarios via TestBackend        |\n| Config   | `cargo test --test config_load` | Config file creation and loading   |\n\n### Environment variables\n\n| Variable           | Purpose                                    |\n|--------------------|--------------------------------------------|\n| `SSHUB_CONFIG_DIR` | Override config directory                  |\n| `SSHUB_DATA_DIR`   | Override data/SQLite directory             |\n| `SSHUB_SSH_CONFIG`  | Override SSH config file path              |\n| `SSHUB_DRY_RUN`    | Exit immediately without TUI              |\n| `SSHUB_AUTO_QUIT`  | `1` = quit after first draw, `q` = send quit key |\n\n## Tech stack\n\n[Rust](https://www.rust-lang.org/) with [ratatui](https://ratatui.rs/) + [crossterm](https://github.com/crossterm-rs/crossterm) for the TUI, [rusqlite](https://github.com/rusqlite/rusqlite) (bundled SQLite) for storage, [nucleo](https://github.com/helix-editor/nucleo) for fuzzy search, [notify](https://github.com/notify-rs/notify) for file watching. No async runtime -- synchronous event loop with 50ms polling.\n\n## Model credits\n\nMade with dynamic workflows + adversarial-multimodel-reviews + cross-model-reviews. Models with commits, reviews, or blocked merges to their name, in order of appearance:\n\n- Opus 4.8\n- Opus 5\n- Fable 5\n- Composer 2.5\n- Grok 4.5\n- Qwen 3.8 Max\n- GPT-5.6 Luna\n\n## License\n\n[AGPL-3.0-or-later](LICENSE) — a copyleft license: forks and derivatives must\nstay open under the same terms. (Versions ≤ 0.3.1 were released under MIT.)\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md).\n",
  "bytes": 26323,
  "sha": "48cbf7514f032852bae822598fbae0c57af621987bd6c1cd143f3101a606c033",
  "repo_slug": "petyok/sshub",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/okf_petyok_sshub_openwiki_index_md_14561ab3/readme"
}