LBYPatrick/warden

Describe the system you live in

★ 0Forks 0GoGitHub ↗Compare

README

Warden

Describe the system you live in

Go Version License Platform

Warden captures Git identities, SSH configuration, packages, and developer tools in a portable JSON5 file. A native Go executable provides both a CLI and an interactive dashboard, with the sidebar navigation, rounded detail panels, and configurable appearance used by Ashley.

Install

Install a published binary release:

curl -fsSL https://raw.githubusercontent.com/LBYPatrick/warden/main/scripts/remote-install.sh | bash

Pin a specific published version:

curl -fsSL https://raw.githubusercontent.com/LBYPatrick/warden/main/scripts/remote-install.sh \
  | bash -s -- --version 2.1.0

Version 2.0.0 is the first native Go release. The installer supports macOS and Linux on ARM64 and x86-64, verifies SHA-256 and the executable's version, and atomically installs to ~/.local/bin/warden. It also installs the man page and Bash/Zsh completions. Target computers need Bash, curl, tar, and a SHA-256 utility; they do not need Go, Python, uv, a checkout, or a virtual environment.

Use --install-dir DIR, WARDEN_INSTALL_DIR, or WARDEN_VERSION to customize installation. Ensure ~/.local/bin is on PATH.

Migration from Python: the normal remote installer automatically detects and migrates old installations:

curl -fsSL https://raw.githubusercontent.com/LBYPatrick/warden/main/scripts/remote-install.sh \
  | bash -s -- --version 2.1.0

The binary installer detects legacy checkout symlinks, backs up replaced launchers under ~/.warden/migrations/python-to-go-*, and atomically installs the native binary. It also redirects recognized Python or Go wrappers earlier on PATH, whether copied or symlinked. Protected launchers cause an error before replacement with instructions to put the install directory first on PATH. It never executes the old launcher or needs Python, uv, Go, or git.

The standalone helper remains available for offline or explicit-source migrations. Run bash scripts/migrate-python.sh --binary /path/to/warden. Optional --source CHECKOUT records an explicit legacy source directory; --install-dir DIR changes the destination. --binary and --version are mutually exclusive. The release-download route installs current completions and the man page; --binary replaces only the launcher.

Configs, keys, archives, the checkout, and shared runtimes are retained. No config conversion is required. A checkout-local warden.jsonc remains in place: use -c /path/to/checkout/warden.jsonc if that was your active config. The backup's origin.txt records original launcher paths; warden and optional path-warden preserve replaced files or symlinks. Start a new shell or run hash -r after migration. The script reports unrelated PATH launchers and stops before replacement if a recognized shadowing launcher's directory is not writable.

To build and install from a source checkout, use make install.

Quick start

warden                              # interactive dashboard when attached to a terminal
warden tui                          # explicitly open the dashboard
warden id list
warden id switch personal
warden pkg scan
warden pkg apply --dry-run
warden backup -o ~/warden.tar.gz
warden restore ~/warden.tar.gz

With redirected input/output, bare warden prints help. warden tui requires an interactive terminal.

Dashboard

The TUI has Overview, Identities, Packages, Archives, Maintenance, and Settings sections. Wide terminals show selection details beside the list; narrow terminals use a compact layout.

Key Action
← / →, Tab / Shift-Tab Change section
1–6 Jump to a section
↑ / ↓, j / k Move through entries
Enter Open or review selected action
/ Filter entries
t Open appearance settings
r Reload configuration
s in Packages Scan installed packages
a in Packages Review and apply configuration
b Review a full backup
Esc Cancel, clear filter, or return from a result
q / Ctrl-C Quit

Identity switches, package application, restores, backups, updates, and maintenance actions have a review screen. Restore accepts an archive path, including spaces. Operations show their result or error in a scrollable panel. Start with warden --dry-run to preview actions.

Press t (or 6) to choose Clear (default), Dark, or Light mode and an accent: blue, green, purple, orange, rose, cyan, ocean, sunset, grape, or forest. Use ↑/↓ and Enter to apply a choice immediately. Preferences are saved in ~/.warden/theme.json, independently of your portable system configuration. NO_COLOR and WARDEN_NO_COLOR suppress styling; --dry-run previews appearance without saving it.

Configuration

Warden searches for warden.jsonc in this order:

  1. ~/.warden/warden.jsonc
  2. ~/.ssh/warden.jsonc
  3. ~/warden.jsonc
  4. ./warden.jsonc

-c PATH takes precedence, including when creating a new config. Paths are resolved from your current directory. Reading a missing config does not create files; scans and saves create it when needed. Malformed existing configs cause an error and are preserved.

{
  identities: {
    personal: {
      name: 'Your Name',
      email: '[email protected]',
      signing_key: '~/.ssh/id_ed25519.pub',
    },
  },
  packages: {
    brew: {formulae: ['git', 'ripgrep'], casks: ['firefox']},
    cargo: {packages: ['bat']},
    npm: {packages: ['typescript']},
  },
  tools: ['rustup', 'node', 'pnpm'],
}

Comments, unquoted keys, single quotes, trailing commas, and legacy identity-only configs are supported. Writes use formatted JSON, which is valid JSON5; comments are not retained.

Commands

Identities

warden id list                     # aligned identity summary
warden id list --names             # one name per line, for completions/scripts
warden id list --json
warden id show                     # current global Git settings
warden id show personal --json
warden id switch personal          # case-insensitive lookup

Switching sets supplied name/email/signing-key fields, derives core.sshCommand, enables SSH signing, and sets commit.gpgsign=true. The default ~/.ssh/id_ed25519 unsets a custom SSH command. Key paths with spaces or shell metacharacters are quoted.

Packages

warden pkg scan
warden pkg apply --force
warden pkg install brew:ripgrep cask:firefox cargo:bat
warden pkg install --save npm:typescript
warden pkg install --any apt:curl
warden pkg install                 # manager and developer-tool list
warden pkg deps -o dependencies.json
Manager Platform Config section
brew / cask macOS, Linux brew.formulae / brew.casks
mas macOS mas.apps (id:name)
apt, dnf, pacman, apk, snap, flatpak Linux <manager>.packages
cargo, npm, pnpm, pipx macOS, Linux <manager>.packages
tool macOS, Linux top-level tools

Developer tools: xcode (macOS), rustup, conda, node, pnpm, flutter, gcloud, aws, wrangler, android-tools. Tool installers may require additional system utilities or privileges.

Scans replace the package/tool snapshot while preserving identities, and stop on a scan failure rather than saving incomplete results. Install/apply skips already-present entries unless forced. --save records successful and already-present packages; failed installations return a nonzero exit status. Homebrew installs in bulk with live CLI output and retries individual packages on failure. APT scans manual packages, falls back to dpkg, refreshes its index, filters unavailable packages, and uses bulk installation with individual retries. macOS operations that need Homebrew bootstrap it when missing. pkg deps emits JSON without decorative output.

Backup and restore

warden backup -m git,ssh -o ~/identities.tar.gz
warden backup --skip-scan
warden restore ~/identities.tar.gz
warden restore ~/full.tar.gz -m pkg
warden restore ~/full.tar.gz --dry-run

Modules are git (identities/signing keys), ssh (SSH config/keys), and pkg (packages/tools and Linux APT sources). Backup defaults to all and scans packages unless --skip-scan is supplied. Restore defaults to modules recorded in the archive. Only selected modules and their referenced keys are restored. Missing SSH config is backed up as an empty config. SSH hosts with missing key files are omitted by default; --include-missing retains those hosts and their original references with a notice.

Identities merge by name, package/tool lists by sorted union, and SSH Host/Match blocks by name. Existing SSH config is copied to ~/.ssh/config.bak. The -c override also controls restore's destination config. Linux APT sources use their original /etc/apt paths and can require sudo.

Key deduplication: Git and SSH share a content-based key collector. Identical pairs under different names are archived once. Restore searches ~/.ssh, ~/.warden/keys, configured signing keys, and SSH identity paths, reuses matching key pairs, and rewrites references. Public-key comments and supported private-key encodings do not affect identity. Encrypted private keys that cannot be parsed without a passphrase are compared by contents. Existing different keys are preserved under their original names; incoming collisions receive a new name. Repeated restores do not add copies, including duplicate pairs in older Python archives.

Archives contain private keys and are not encrypted. Archives, configs, and restored keys are written with private permissions. Restore rejects traversal, links, duplicate members, invalid metadata, and oversized archives before applying changes. Writes are atomic per file, not a transaction across the whole restore.

Maintenance and updates

warden mole clean                  # macOS, via tw93/mole
warden mole optimize
warden mole analyze /Volumes
warden mole status --json
warden update                      # latest published binary release
warden update X.Y.Z                # select an exact release
warden update X.Y.Z --dry-run

Mole is installed through Homebrew if needed. mole clean --dry-run and mole optimize --dry-run invoke the installed Mole’s native preview; dry runs never install missing Mole. Updates download the platform archive, verify its SHA-256 and version, and atomically replace the executable. Branch/source updates such as warden update main are no longer supported. An explicit version chooses that release; a later bare update chooses latest.

Global options and mirrors

-c PATH, --dry-run, and --no-color work before or after subcommands. --version reports the embedded binary version. Piped CLI output is plain text; NO_COLOR and truthy WARDEN_NO_COLOR disable color.

WARDEN_USE_CN=1 enables the existing Homebrew, Rust, Node/npm, PyPI, and GitHub mirror mappings for downloads and installations. Truthy flags accept 1, true, or yes in Go. Pass environment settings to the installer side of a pipe:

curl -fsSL https://raw.githubusercontent.com/LBYPatrick/warden/main/scripts/remote-install.sh \
  | WARDEN_USE_CN=1 bash

Development and releases

Go 1.25+ is required only to build from source.

make format        # gofmt + shell syntax checks
make test          # race-enabled Go tests + vet
make build         # build/warden with VERSION embedded
make install       # install locally compiled binary and shell integrations
make uninstall     # preserve configuration, keys, and archives
make release       # four platform archives + per-archive SHA-256 files
bash tests/install.sh  # offline installer test after make build
bash tests/cli.sh      # compiled CLI and isolated Git/archive integration
bash tests/migrate.sh  # offline Python-to-Go migration integration

cmd/warden contains the entry point; internal/app owns config, identity, packages, archives, and updates; internal/tui owns the Bubble Tea dashboard. scripts/release/package.sh builds one self-contained archive. Runtime assets are the executable, license, man page, and completions.

To publish, update VERSION and the README badge, commit the release, and push the matching vX.Y.Z tag. The release workflow verifies the tag/version match, runs tests, builds all four archives, and publishes a GitHub release. CI runs tests on macOS and Linux. Generated binaries and archives are ignored by Git.

For Zsh completions, add fpath=(~/.zsh/completions $fpath) before autoload -Uz compinit && compinit. Bash completions live in ~/.local/share/bash-completion/completions/warden; the man page is in ~/.local/share/man/man1/warden.1.

See the feature-parity audit for the Python baseline, regression coverage, and intentional migration changes.

License

LGPL-3.0-or-later.

Clear mode uses your terminal’s background and foreground, so configured transparency or blur remains visible. It does not enable terminal transparency itself. Existing saved Dark or Light preferences are preserved; choose Clear in Settings to switch.

Contributors

LBYPatrick

Issues