sshkeeper

← Все публичные проекты

Консольный менеджер SSH-подключений, маршрутов, секретов, туннелей и постоянных сессий.

sshkeeper не заменяет OpenSSH и не пытается быть Ansible. Это локальный менеджер подключений: он хранит профили серверов в SQLite, пароли и passphrase — в зашифрованном vault, умеет собирать маршруты через bastion/jump-host’ы и запускает системный ssh с нужными параметрами.

Основной интерфейс — клавиатурный TUI на Bubble Tea. Те же данные и операции доступны через CLI, поэтому sshkeeper подходит и для интерактивной работы, и для скриптов.

Главный экран sshkeeper v0.7

Основные возможности

  • профили SSH-серверов, группы, теги и заметки;
  • авторизация по ключу, через ssh-agent, по паролю и с passphrase;
  • зашифрованный локальный vault для паролей и passphrase;
  • маршруты / ProxyJump и цепочки bastion-host’ов со стабильными ссылками на профили;
  • Local, Remote и SOCKS port forwarding;
  • запуск, просмотр и остановка фоновых SSH-туннелей;
  • постоянные SSH-сессии через tmux — можно держать несколько подключений живыми и переключаться между ними;
  • шаблоны команд и запуск команд на выбранных серверах;
  • живой fuzzy-поиск по имени, alias, host, пользователю, группе, тегам, заметкам, маршрутам и портам;
  • сортировка по имени, последнему использованию или группам, сворачиваемые группы и индикаторы тестов, туннелей и сессий;
  • массовая проверка доступности видимых или отмеченных серверов;
  • импорт существующего ~/.ssh/config, экспорт и генерация OpenSSH-конфигурации;
  • русский и английский интерфейс;
  • полноценный CLI для автоматизации.

Зашифрованная синхронизация между устройствами

Начиная с v0.7.0, sshkeeper умеет синхронизировать между несколькими компьютерами профили, маршруты, port-forward правила, группы, теги, шаблоны команд, секреты vault и используемые профилями приватные ключи.

Настройки синхронизации sshkeeper

Хранилищем может быть:

  • общая папка — например Syncthing, Nextcloud, Dropbox или сетевой диск;
  • Git-репозиторий на отдельной ветке.

Все синхронизируемые данные передаются внутри одного зашифрованного файла. Для добавления нового устройства используется шестизначный код с ограниченным сроком действия и мастер-пароль уже подключённого устройства. При создании sync-space выдаётся recovery key на случай потери всех устройств.

Локальные состояния — последний вход, результаты тестов, запущенные туннели, язык интерфейса и сортировка — между машинами не переносятся.

Маршруты, туннели и сессии

Маршруты хранятся как упорядоченная цепочка переходов. Если hop ссылается на профиль sshkeeper, связь идёт по стабильному ID: переименование bastion-профиля не ломает зависимые подключения. Для сессии sshkeeper сам формирует временный OpenSSH config, поэтому имя профиля не обязано дублироваться в ~/.ssh/config.

Port forward в sshkeeper — это сохранённое правило, а tunnel — уже запущенный SSH-процесс, который активирует такие правила. Отдельно доступен опциональный режим Sessions: если установлен tmux, SSH-подключения можно оставлять работающими и возвращаться к ним позже.

Состояние проекта

Статус: активная разработка; текущий стабильный релиз — v0.7.0.
Платформы: Linux amd64/arm64 и macOS amd64/arm64 — основные цели; Windows amd64 — экспериментально.
Пакеты: для Linux выпускаются .deb, .rpm и tar.gz; для macOS — tar.gz; для Windows — ZIP.
Зависимости: системный OpenSSH; tmux необязателен и нужен только для постоянных Sessions; git нужен только при выборе Git-хранилища синхронизации.
Технологии: Go, Bubble Tea, Cobra, SQLite, OpenSSH.
Лицензия: MIT.

Установка

Debian / Ubuntu, amd64:

sudo apt install ./sshkeeper_0.7.0-1_amd64.deb

Fedora / RHEL family, x86_64:

sudo dnf install ./sshkeeper-0.7.0-1.x86_64.rpm

После установки проверить реально запускаемый бинарник и версию можно так:

command -v sshkeeper
sshkeeper --version

Безопасность

Vault использует XChaCha20-Poly1305, а мастер-пароль проходит через Argon2id. Секреты не передаются через аргументы командной строки. Синхронизация также шифруется до помещения данных в общую папку или Git-репозиторий.

Независимого аудита безопасности проект пока не проходил, поэтому для особо критичных сред стоит отдельно изучить реализацию и модель угроз.

Ссылки

Релизы ·
Руководство ·
Скриншоты ·
Исходный код ·
Сообщить об ошибке

История релизов

v0.7.0 — sshkeeper v0.7.0

sshkeeper v0.7.0 — encrypted sync between devices

v0.7.0 keeps your devices in step: profiles, port forwards, command

templates, groups and tags, vault secrets, and the private keys your profiles

use travel end-to-end encrypted through a folder or a git repository.

Added

  • Sync between devices. m → Settings → Synchronization chooses the

storage — a shared folder (Syncthing, Nextcloud, Dropbox, a network drive)

or a git repository — and the form shows only the fields that storage

needs. The first device creates the sync space; others join with a

six-digit code.

  • Six-digit pairing. "Add device" shows a code valid for ten minutes.

The new device enters it together with the master password of the device

showing it. The code alone is worthless and is deleted after use; in git it

lives on a temporary branch that never enters the history.

  • Recovery key. Shown when the sync space is created, for the case when

every device is lost. It also works in place of a pairing code.

  • Automatic sync. With auto sync on, the TUI syncs at start and three

seconds after each change. The dashboard header shows ⇅ with the time

since the last sync, and changes from other devices refresh the list.

  • sshkeeper sync commands: setup, init, add-device, join,

status, recovery-key, leave, and plain sync.

How secrets stay secret

  • Everything travels in one file sealed with XChaCha20-Poly1305 under a

random 256-bit key. The storage sees a format tag and a key fingerprint —

no names, hosts, or even how many secrets exist.

  • The sync key lives only in each device's vault; a stolen sync file has no

password to guess.

  • Sync refuses to run while the vault is locked, so missing secrets are never

mistaken for deletions.

  • Existing key files are never overwritten, and a device's own different key

at the same path never travels to other devices.

  • Changes merge per item by the latest edit; deletions travel too. Device-local

facts — last connection, last test, running tunnels, language, sort order —

stay on each device.

Changed

  • Manage → Settings is now a menu with Language and Synchronization.

Fixed

  • Esc in the identity-file, tags, startup-command, or route picker of the

server form left the whole form instead of closing the picker. With a filter

typed in a picker, the first Esc now clears the filter.

  • Groups, Tags, Command templates, Sessions, and Running tunnels opened from

the Manage menu return to it on Esc.

  • The vault no longer prints "Deriving key..." when saving, which could draw

over the TUI.

To install on Debian/Ubuntu x86-64, download the release asset and run

sudo apt install ./sshkeeper_0.7.0-1_amd64.deb (use the arm64 package on

ARM64). Git sync needs the system git; folder sync needs nothing extra.

v0.6.0 — sshkeeper v0.6.0

sshkeeper v0.6.0 — a faster, more recognizable dashboard

v0.6.0 reworks the TUI dashboard around the everyday path: find a server,

connect, come back. Everything stays keyboard-first and fits the same

60x16 minimum.

Added

  • Live filter. / (or Ctrl+F) filters the list as you type and

highlights the matched letters. Names rank first, then aliases, then fuzzy

name matches (bst finds Bastion), then host, user, group, tags, notes,

route hops, and forward names or ports. Enter connects, Tab keeps the

filter, Esc clears it.

  • Sort by recent use or group. s cycles between name, most recent

connection, and group, and saves the choice as ui.sort. A new SEEN column

shows the time since the last connection. In group order, group headings

fold with Enter, Space, ←, or →.

  • State column. ● / ✗ for the last test, ◌ while testing, ⇄ when a

background tunnel for the server is running, ▣ when a tmux session is

open. Tunnels and sessions refresh every 10 seconds, including tunnels

started by another sshkeeper process.

  • Test all. T tests every visible (or marked) server, six at a time,

and summarizes the result.

  • Single-key shortcuts on the server list: a add, e edit, d delete,

t test, x actions, f forwards, r run template, Space mark, q quit,

and j/k/g/G navigation. The Ctrl shortcuts still work.

  • Welcome screen on the first run, with i to import hosts from

~/.ssh/config.

  • ASCII mode for terminals and fonts without box drawing:

glyphs = "ascii" under [ui], or SSHKEEPER_ASCII=1.

Changed

  • New look: adaptive light/dark palette with one amber accent, a key logo in

every header, rounded panels with titles in the border, an accent cursor

bar, and shorter key action · key action footers. NO_COLOR is honored.

  • The details panel shows the route as a chain (you → bastion → host), the

last test with its reason, saved forwards with their state, open sessions,

and notes, instead of repeating host, port, and user.

  • A clean ssh exit returns straight to the dashboard, with the cursor on the

same server and a ← Back from <server> · 42m notice. A failed connection

still waits for Enter so ssh's output stays readable.

  • Confirmations open as a centered dialog over the dimmed screen.
  • The auth method in the server form is a selector: ←/→ cycle

password ‹key› key+pass agent.

  • Success notices fade after five seconds; errors stay until the next key.
  • The list drops the AUTH column (it is in the details panel) to give names

room.

Fixed

  • A connection test result could be recorded on whichever server the cursor

had moved to by the time the test finished.

  • Fast typing or key repeat delivered as one event (jjj, /prod) is now

handled key by key.

To install on Debian/Ubuntu x86-64, download the release asset and run

sudo apt install ./sshkeeper_0.6.0-1_amd64.deb (use the arm64 package on

ARM64). Linux and macOS are the primary targets; the Windows build remains

experimental.

nightly — sshkeeper nightly (v0.6.0-7-ge65d591)pre-release

Automated build from the tip of main, rebuilt on every push.

This is not a stable release. It is untagged, unannounced and may be

broken. The Latest badge stays on the newest v* release, which is

what you want for normal use.

| | |

|---|---|

| Version | v0.6.0-7-ge65d591 |

| Commit | e65d5913d02c65d90a83da18fefa8cd7aac3da48 |

| Built | 2026-09-29 18:30 UTC |

Verify downloads against checksums.txt.

v0.5.3 — sshkeeper v0.5.3

sshkeeper v0.5.3 — Russian and English interface

v0.5.3 adds Russian and English localization to the TUI and CLI.

Changed

  • Interface language follows the system locale by default. On Unix, detection

checks LC_ALL, then LC_MESSAGES, then LANG; unsupported locales use English.

  • The TUI management menu (m) now has a Settings screen for choosing System,

Russian, or English. The choice is saved in ui.language in the config file.

  • TUI screens, tunnel actions, help, prompts, and CLI messages are translated.

Command names, flags, server aliases, and SSH parameters are unchanged.

This release also includes the clearer tunnel-starting flow introduced in

v0.5.2. To install on Debian/Ubuntu x86-64, download the release asset and run

sudo apt install ./sshkeeper_0.5.3-1_amd64.deb (use the arm64 package on ARM64).

v0.5.2 — sshkeeper v0.5.2

sshkeeper v0.5.2 — Tunnel TUI usability

v0.5.2 makes the path from a saved port-forward rule to a running tunnel clearer.

Changed

  • The port-forwards screen now offers Ctrl+B to start a background tunnel and

Ctrl+X to choose any tunnel mode; saving a rule points to these actions.

  • Server actions show the selected server, enabled-forward count, and why a

tunnel mode is unavailable. TUI tunnel modes require an enabled rule.

  • Background startup keeps the TUI open and leaves its PID acknowledgement or

error visible. Running tunnels has an empty-state start hint.

  • Foreground no-shell mode tells you to stop with Ctrl+C and return with Enter.
  • CLI --forward-only now rejects configurations with no enabled forwards.

Background mode still requires key or SSH-agent authentication. Password and

key-passphrase authentication remain available in foreground modes.

For Debian/Ubuntu on x86-64, install the release asset with

sudo apt install ./sshkeeper_0.5.2-1_amd64.deb (use the arm64 package on ARM64).

v0.5.1 — sshkeeper v0.5.1

sshkeeper v0.5.1 — Package Migration Fix

v0.5.1 is a patch release on top of v0.5.0 Persistent SSH Sessions.

Fixed

  • Fixed DEB/RPM post-install discovery of legacy per-user binaries at ~/.local/bin/sshkeeper.
  • Package installation now correctly backs up a legacy binary and replaces its old path with a symlink to /usr/bin/sshkeeper.
  • Added a regression test that discovers the user path through passwd data, matching the real package-install path.
  • sshkeeper --version and sshkeeper version continue to report the embedded release version.

No session functionality from v0.5.0 is removed or rolled back.

v0.5.0 — sshkeeper v0.5.0

sshkeeper v0.5.0 — Persistent SSH Sessions

v0.5.0 adds an optional multi-session workflow backed by tmux. It lets

sshkeeper keep several interactive SSH connections alive in one terminal

workspace without turning sshkeeper itself into a terminal emulator.

tmux is intentionally optional. If it is not available, Sessions are not

shown anywhere in the TUI and ordinary Connect/Tunnel workflows behave exactly

as they did in v0.4.1.

Persistent sessions

When tmux is available in PATH:

  • Server Actions → Open in session opens the selected server in a persistent

tmux window;

  • Manage → Sessions lists SSH windows created by sshkeeper;
  • Enter attaches to the selected session;
  • Ctrl+D closes it after confirmation;
  • Ctrl+R refreshes the list.

If sshkeeper runs outside tmux, it uses a dedicated tmux workspace named

sshkeeper. If it is already running inside tmux, new SSH windows are created

inside the current tmux session rather than starting a nested client.

Vault and authentication

Sessions continue to use the existing sshkeeper/OpenSSH connection planner,

including routes, bastions, identity files and startup commands.

Key and SSH-agent sessions do not need a vault unlock. Password and

key-passphrase sessions ask for the vault master password inside their own tmux

window. Secrets are not copied through command-line arguments, environment

variables or temporary shell scripts.

Platform behavior

Linux and macOS support Sessions when tmux is installed. On macOS it can be

installed with Homebrew using brew install tmux.

Native Windows builds keep Sessions hidden because upstream tmux is not a native

Windows backend for this workflow. Windows users can use Sessions by running the

Linux build inside WSL with tmux installed there.

Linux native packages do not require tmux. Package metadata keeps OpenSSH as

the hard dependency and marks tmux only as Recommends, so the application

remains fully usable without the Sessions feature.

Validation

The release is covered by normal unit tests plus a real tmux lifecycle test that

creates a temporary workspace/window, verifies sshkeeper can discover its

metadata, closes it, and confirms it disappears.

The release gate also runs go vet, Linux package migration tests and release

cross-builds for Linux amd64/arm64, macOS amd64/arm64 and Windows amd64. GitHub

CI additionally runs the test suite natively on both Ubuntu and macOS.

Install

Debian/Ubuntu (amd64):

sudo apt install ./sshkeeper_0.5.0-1_amd64.deb

Fedora/RHEL-family (x86_64):

sudo dnf install ./sshkeeper-0.5.0-1.x86_64.rpm

ARM64 packages and tar/zip archives are published alongside them. Verify

downloads against checksums.txt.

v0.4.1 — sshkeeper v0.4.1

sshkeeper v0.4.1 — Package Install & Version Fixes

This patch release makes native Linux packages authoritative after installation

and exposes the version embedded in the executable.

Package installation now wins over legacy binaries

DEB and RPM installs detect older sshkeeper copies at known legacy paths:

  • /usr/local/bin/sshkeeper;
  • per-user ~/.local/bin/sshkeeper paths discovered from the system account database.

A detected legacy entry is preserved as *.legacy-backup, then its old path is

replaced by a symlink to /usr/bin/sshkeeper. This deliberately handles both

PATH precedence and shells that have already cached the previous executable

path. No database, vault, configuration, SSH key, or other user data is touched.

The migration is idempotent across package upgrades. Removing the package restores

the preserved legacy binary when the redirect is still package-managed; if the

user changed that path while the package was installed, the package leaves the

user's replacement alone and keeps the backup rather than overwriting it.

Version reporting

Both forms are now supported without initializing the database or vault:

sshkeeper --version
sshkeeper version

A v0.4.1 release binary prints:

sshkeeper v0.4.1

The build and release scripts now link the discovered version into the real

cmd.Version symbol instead of the stale main.version target.

Packaging verification

The release gate now tests legacy-path migration and restoration in addition to

the existing Go tests, vet, and cross-platform builds. DEB/RPM packages continue

to contain the exact Linux binary produced for the matching tarball.

v0.4.0 — sshkeeper v0.4.0

sshkeeper v0.4.0 — Model & Workflow Cleanup

v0.4.0 is a structural release. The main goal is to make sshkeeper's data model

match what the user sees: server profiles are real reusable objects, routes

reference those objects instead of mutable text, and the TUI offers pickers for

things that already exist instead of asking you to retype them.

Existing databases and vaults are migrated automatically. No manual conversion

is required.

Routes are now real relationships

The old implementation stored both ProxyJump text and a second route

representation. Different commands wrote different fields, and runtime SSH used

one in preference to the other. That made it possible for edit --proxy-jump to

say "Saved" while the old structured route was still used.

v0.4.0 makes Route canonical and stores profile hops in a normalized

server_route_hops table with foreign keys to stable server IDs.

  • Renaming a bastion no longer breaks dependent routes.
  • Deleting a profile that is still used as a route hop is rejected and names

the dependent profiles.

  • Self references, duplicate hops and route cycles are rejected.
  • proxy_jump and legacy route_hops remain compatibility projections for old

databases/tools, not competing sources of truth.

  • Existing group_name strings are likewise migrated to first-class groups

with stable IDs.

Profile hops no longer depend on ~/.ssh/config

A route hop that references a sshkeeper profile now resolves that profile's real

host, user, port and identity file from SQLite. sshkeeper generates a temporary

OpenSSH config for the connection and passes it with ssh -F.

This fixes the old accidental requirement that a sshkeeper alias such as

bastion-prod also had to exist as a matching Host in the user's OpenSSH

config.

CLI route syntax is explicit when needed:

# exact known aliases are profile references
sshkeeper route set prod --jumps bastion,dmz-gw

# force the interpretation
sshkeeper route set prod --jumps profile:bastion,raw:ops@external-gw:2222

An unprefixed value matching an existing sshkeeper alias becomes a profile hop;

an unknown value remains a raw OpenSSH target.

Password or key-passphrase authentication on an *intermediate* profile hop is

rejected with a clear error for now. The current PTY secret flow can safely feed

the target profile, but it cannot reliably route different vault secrets to

multiple OpenSSH prompts in a jump chain. Key/agent bastions are supported.

Route editor in the TUI

Ctrl+X → Route, or / while the Route field is focused, opens an ordered

route editor.

  • Enter adds an existing server profile as a hop.
  • x / Delete removes a hop.
  • [ / ] moves a hop up/down in the chain.
  • / filters the available profiles.
  • raw:<target> remains available in the editable field for arbitrary OpenSSH

targets.

The server form no longer claims that a picker exists while still requiring a

comma-separated string.

Server Actions vs Manage

Ctrl+X is now strictly about the selected server:

  • Connect
  • Connect with tunnels
  • Start tunnels only / in background
  • Port forwards
  • Route
  • Test connection
  • Edit
  • Delete

Press m for global management:

  • Groups
  • Tags
  • Command templates
  • Running tunnels
  • Import SSH config
  • Export
  • Vault lock / password change

Groups now have their own manager with server counts, create/rename/delete

operations, and safe delete consequences.

Context-aware server form

The form now exposes only authentication fields that matter:

| Auth | Fields |

|------|--------|

| password | Password |

| key | Identity File |

| key_passphrase | Identity File + Key passphrase |

| agent | no credential fields |

/ opens context-specific pickers:

  • Auth method → auth list
  • Identity File → detected private keys in ~/.ssh
  • Route → profile/chain editor
  • Group → existing groups
  • Startup Command → global command templates (the command is copied, not linked)
  • Tags → multi-select existing tags; new tags can still be typed manually

CLI consistency fixes

All writers now go through the same route semantics.

  • add, edit, route set, TUI save and SSH config import all create the same

canonical route model.

  • SSH config import is two-pass: profiles are created first, then ProxyJump

aliases are resolved against the complete imported/existing profile set.

  • edit uses Cobra's Changed() state, so --group '', --notes '',

--startup-command '', --identity-file '', --proxy-jump '' and

--tags '' can actually clear values.

  • An empty server User no longer produces the invalid target @host; OpenSSH

is allowed to choose its configured/current user.

  • Shared server/auth/route validation replaced duplicated partial checks.

Vault identity follows the server, not its alias

New and migrated server secrets are stored under stable server IDs. Renaming a

profile no longer requires a risky copy/delete of secrets keyed by alias.

Legacy server:<alias>:<type> records remain readable and are lazily migrated

when used. vault list understands both legacy and stable-ID records and

resolves stable IDs back to current aliases when the database is available.

TUI server save now commits the database change before rewriting vault state;

if the vault step fails, the profile/tags are rolled back instead of leaving the

database and vault disagreeing.

Port forward fixes

Two concrete TUI bugs are fixed:

  • Editing a disabled forward no longer silently re-enables it.
  • Remote-forward preview now uses the same semantic builder as validation/save,

so listen/target endpoints cannot be shown reversed.

The editor has an explicit Enabled toggle and the forward list supports Space

to enable/disable a rule quickly.

Tunnel fixes

Profile routes work consistently for foreground and background tunnels.

Background tunnels keep their generated temporary SSH config for the lifetime of

the process and remove it on stop/stop-all.

Tunnel Manager now reports running separately from tracked; stale tracked

state is no longer counted as a running process.

Cleanup

  • Removed the stale per-server CommandTemplate.ServerID field; command

templates are global.

  • Removed an unused legacy model.Secret type; the encrypted vault has its own

actual storage model.

  • Added regression coverage for stable route references, deletion protection,

cycle detection, stable-ID vault metadata, contextual auth fields, Manage,

route/identity/tag/startup pickers, and forward semantics.

Upgrade notes

On first start, v0.4.0 automatically creates groups and

server_route_hops, links existing group names, and converts existing route

text/JSON. The old columns are retained for compatibility.

As always, keep a copy of ~/.local/share/sshkeeper/ before a major upgrade if

the data matters to you.

Install

Debian/Ubuntu (amd64):

sudo apt install ./sshkeeper_0.4.0-1_amd64.deb

Fedora/RHEL-family (x86_64):

sudo dnf install ./sshkeeper-0.4.0-1.x86_64.rpm

ARM64 packages (arm64.deb / aarch64.rpm) and the original tar.gz archives

are published alongside them. Package dependencies pull in the distro OpenSSH

client; user config, database and vault files are not owned or modified by the

package.

Verify downloads against checksums.txt. Linux and macOS are the primary

release targets. Windows remains experimental and requires OpenSSH Client

(ssh.exe) in PATH.

v0.3.2 — sshkeeper v0.3.2

Release automation and reproducible packaging. sshkeeper itself behaves exactly

as in v0.3.1 — no functional changes to the TUI or the CLI.

This is also the first release published by GitHub Actions rather than by hand.

In this release

Archives are now reproducible. Rebuilding a tag on a different machine used

to produce different checksums even when every packaged file was byte-identical,

because three host properties leaked into the archives:

| Leak | Effect |

|------|--------|

| File modes followed the builder's umask | umask 002 packaged 664/775, umask 022 packaged 644/755 |

| sort orders entries by locale | a ru_RU.UTF-8 host emitted docs/ before LICENSE, a C locale the reverse |

| zip stores DOS local time with no zone | the same commit embedded 19:06 at UTC+08 and 11:06 at UTC |

All three are pinned now. A build on ubuntu-latest and one on a workstation

with a different umask, locale and timezone produce identical checksums for all

five archives. The binaries were always reproducible; only the packaging varied.

CI. The repository previously had no automation. It now runs gofmt,

go vet and go test on Linux *and* macOS for every push and pull request,

plus a cross-build of all five release targets. macOS is a stated release

target that until now was only ever cross-compiled, never tested.

Releases are automated. Pushing a v* tag runs the release checks, builds

through the same release.sh used locally, and publishes. Nightly builds from

main are published as a separate nightly prerelease, so the Latest badge

always points at a real release.

---

Everything since v0.2.0

Breaking change: full help moved off F1

Ctrl+H opens full help. F1 no longer has any binding. ? still opens

contextual quick help outside text editors. This landed in v0.3.0.

Ctrl+H is the BS control character (0x08). xterm and most modern emulators

send DEL (0x7F) for Backspace, so help and text editing do not collide. A

terminal configured to send BS for Backspace cannot tell them apart; switch it

to DEL (in xterm, backarrowKey: false).

Nothing else requires action when upgrading. Vaults, server profiles and stored

port forwards are unchanged, and no migration runs.

The TUI was rebuilt around one shell (v0.3.0)

In v0.2.0 only the server dashboard had a real layout. Other screens rendered

free-form strings or the default Bubbles list frame, so they had no shared

width budget, no borders, and footers that floated wherever the content ended.

Every full-screen state now shares one contract: a header with breadcrumb and

truthful vault status, a separator, framed content panels, and a contextual

footer anchored to the last terminal row.

  • Actions, search, tag input, confirmations and both help screens render inside

the shell.

  • The port forward manager and editor use framed, width-budgeted layouts. Column

widths derive from the panel's inner width, so no row consumes the terminal's

last column.

  • Tag, command template, template picker/mode/results and tunnel managers use

framed lists with a > selection marker, so selection never depends on colour

alone.

  • Server and template editors use a framed form panel with the title moved into

the breadcrumb. Required markers, validation and dirty-state confirmation are

unchanged.

Responsive layouts. The supported floor is 60x16. Wide (100+ columns)

shows two panels, medium (70–99) stacks them, narrow (60–69) keeps a single

compact panel. Below the floor only the minimum-size message renders. Long

ASCII, Cyrillic, CJK, combining and emoji content truncates by display cells

rather than byte count.

Safety. Destructive actions confirm with Cancel selected first and name the

exact target and its consequence. Status and help context stay truthful to

actual vault and connection state. Form validation prevents silent loss of

edits.

forward add was completely broken (fixed in v0.3.1)

sshkeeper forward add could never succeed in v0.2.0 or v0.3.0. The command

read --local-port and marked it required, but the flag was never registered,

so cobra rejected it as unknown and the value fell back to 0:

$ sshkeeper forward add web --type local --local-port 15432 \
    --remote-addr 127.0.0.1 --remote-port 5432
unknown flag: --local-port

No combination of arguments worked. Both documented forms work now:

$ sshkeeper forward add web --name "Local PostgreSQL" --type local \
    --local-port 15432 --remote-addr db01.internal.example.com --remote-port 5432
✓ Forward added [1]

$ sshkeeper forward add web --name "SOCKS proxy" --type dynamic --local-port 1080
✓ Forward added [2]

Omitting the flag now reports required flag(s) "local-port" not set instead of

a misleading port-range error. The TUI (Ctrl+W) was never affected.

The command's tests had constructed their own throwaway cobra command and

registered the flags by hand, so the real command's registration was never

exercised and the suite passed against a broken command. Coverage now parses

argv into the actual command. An audit of every other command found no further

flag that is read but never registered.

Also fixed since v0.2.0

  • Port forward fields accept digits correctly (10bcc07).
  • Platform and repository status are stated accurately in the docs: Linux and

macOS are primary release targets, Windows is experimental.

Release-by-release

| Version | Contents |

|---------|----------|

| v0.3.0 | Unified TUI shell, responsive layouts, F1 → Ctrl+H |

| v0.3.1 | forward add fix |

| v0.3.2 | Reproducible packaging, CI, automated releases |

Install

tar -xzf sshkeeper_v0.3.2_linux_amd64.tar.gz
sudo install -m 0755 sshkeeper_v0.3.2_linux_amd64/sshkeeper /usr/local/bin/sshkeeper

Verify downloads against checksums.txt. Linux and macOS are the primary

release targets; the Windows build is experimental and needs OpenSSH Client

available as ssh.exe on PATH.

To verify a build yourself, check out the tag and run ./release.sh v0.3.2 —

the checksums should match this release exactly, given the same Go version.

Источник: GitHub Releases · данные кэшируются на сервере.