End users install from the release tarball:
tar xzf engineering-loadout-v*.tar.gz
cd engineering-loadout-v*/
./loadout install @engineering-loadoutRepo developers can also git clone and run ./loadout from a checkout --
the script resolves the repo from its own path and works from any cwd.
./loadout is a POSIX-sh shim (~80 lines) that resolves a Python 3.14
interpreter (~/.local/bin/python3.14 -> <repo>/.loadout-bootstrap/bin/python3.14
-> cold-bootstrap from payload/<platform>/portable-python-*.tar.bz2) and
execs loadout_main.py under it. No system Python is required -- bzip2 +
tar (always present on EL8/Suse/Debian) are the only host prerequisites.
loadout_main.py enforces Python >= 3.14 via a sys.version_info gate.
./loadout install @engineering-loadout # install the curated bundled set
./loadout list # show all packages
./loadout list --groups # show all @groups
./loadout list --tag editor # filter packages by tag
./loadout search vim # case-insensitive substring search
./loadout info gvim # full package metadata + reverse-deps
./loadout info @core-cli # group membership
./loadout resolve gvim # dry-run resolver, prints set by kind
./loadout doctor # platform + registry integrity check
./loadout snapshot list
./loadout snapshot restore loadout_backups/backup.1.tar.bz2
./loadout install @engineering-loadout --dest-dir /tmp/test-home
./loadout install @engineering-loadout --no-backup
./loadout install @engineering-loadout --post-install-hook ~/corp/install.sh
./loadout install octave # single package; deps auto-pulled
./loadout install @gui-suite # group; expands recursively
./loadout install @engineering-loadout --skip @fonts-all # curated set minus fonts
./loadout install @engineering-loadout --skip tldr-data
./loadout install @engineering-loadout --skip gnuplot,micro
./loadout install vim nvim rg tmux # install exactly this set
./loadout install gvim --no-deps # install gvim verbatim, no dep walk
./loadout install gvim --dry-run # resolve + print; no writes| Destination | Source |
|---|---|
~/.bashrc, ~/.bash_profile, ~/.bash_login, ~/.profile |
-> envs/bash/bashrc |
~/.config/bash/ |
Layered bash config |
~/.vimrc |
envs/vim/vimrc |
~/.vim/ |
envs/vim/vim/ |
~/.tmux.conf |
envs/tmux/tmux.conf |
~/.tmux/ |
envs/tmux/vendor/plugins/ |
~/.editorconfig |
envs/editorconfig/editorconfig |
~/.config/nvim/ |
envs/nvim/ |
~/.config/starship/starship.toml |
envs/starship/starship.linux.toml + envs/starship/config-schema.json |
~/.config/helix/runtime/ |
payload/<platform>/runtime/helix.tar.bz2 |
~/.local/share/vim/vim92/ |
payload/<platform>/runtime/vim92.tar.bz2 |
~/.local/share/nvim/runtime/ |
payload/<platform>/runtime/nvim.tar.bz2 |
~/.local/bin/ |
payload/<platform>/bin/*.bz2 (decompressed) |
~/.local/lib64/ |
payload/<platform>/lib64/*.bz2 (decompressed) |
~/.local/bin/python3.14 |
payload/<platform>/portable-python-*.tar.bz2 |
~/.local/share/fonts/ |
payload/fonts/*.zip (Nerd Font archives) |
~/.local/share/nvim/tree-sitter-parsers/ |
326 prebuilt Tree-sitter parsers |
~/.local/share/tealdeer/cache/tldr-pages/ |
payload/tldr/tldr-pages.tar.bz2 |
After install, reload your shell:
exec bashSimulate a completely fresh user environment:
./tests/install-linux-tmp-homeFor a single install shared by many users, do not mutate the live tree in
place. Install only the shared artifacts -- every package except the
per-user env config bundles -- with the synthetic @shared group:
./loadout install @shared \
--dest-dir /opt/engineering-loadout/releases/2026-06-04.2@shared = all non-env, non-optional packages (binaries, libs,
runtimes, fonts, data, python tools); @shared-all = the same with the
optional: true packages folded back in (surfer, cicwave, rust,
rust-crate-store) -- the full shared tree in one name. @envs = Bash
configuration only (plus its normal recommends), installed into each user's
$HOME with ./loadout install @envs. Install other config bundles by
name, or use @envs-all when every shell and editor config is intentional.
Tools and config bundles are fully decoupled (no cross-recommends), so
@shared and @envs need no extra --skip / --no-deps flags. Preview
any set with ./loadout resolve @shared / @shared-all / @envs.
Install each release into a versioned directory and atomically move a stable symlink only after the new tree is complete:
/opt/engineering-loadout/releases/2026-06-04.1/
/opt/engineering-loadout/releases/2026-06-04.2/
/opt/engineering-loadout/current -> /opt/engineering-loadout/releases/2026-06-04.2
ln -s /opt/engineering-loadout/releases/2026-06-04.2 /opt/engineering-loadout/.current.new
mv -Tf /opt/engineering-loadout/.current.new /opt/engineering-loadout/currentThis avoids Text file busy failures from users running old binaries while
an update is unpacked. Existing processes keep their old inodes; new shells
resolve the new current target. Keep the previous release for rollback
and delete old releases only after no users still need them. tmux is a
special case -- clients and the server must agree on protocol / version, so
restart the tmux server before switching users to a tmux update.
The Neovim plugin stash (bare git mirrors of every bundled plugin) lives
in the shared tree, read-only, and each user's lazy/ is cloned from it. It
is a GitHub release asset, not part of the release tarball -- fetch it once
into the checkout before staging the shared tree:
./tools/fetch-stash # from the latest release, verified
./loadout install @shared-all --dest-dir /opt/engineering-loadout/releases/...Refresh plugins later without a new loadout release with ./tools/refresh-stash, and
override the stash location with LOADOUT_CFG_NVIM_PLUGIN_STASH_DIR if needed.
Neovim itself needs git to clone from the stash; git-nvim (in @shared-all)
provides a private one for boxes with no system git. See the full behavior in
CLAUDE.md -> "nvim plugin stash delivery".
Deploying to a farm or an air-gapped site -- where the network policy varies
and a shared filesystem is read-only on the secure side -- is documented
step-by-step, per network state, in
docs/DEPLOYMENT-RUNBOOK.md. That is the canonical ops
guide; this section is only the shared-tree mechanics.
Archive extraction and env config copying intentionally handle symlinks differently:
- Runtime/archive extraction uses
--install-follows-symlinks. The default (auto) follows an existing directory symlink only when its target is writable; otherwise it removes the symlink and creates a real directory. Use--install-follows-symlinks=yesto always write into symlink targets, or=noto always replace them with real directories. - Env config installs (including
@envsfor Bash and explicitly named bundles such asenv-nvim) always copy config into the target HOME and replace symlinked config subdirectories with real directories. This is deliberate: stale links such as~/.config/nvim/lsp -> ~/dotfiles/nvim/lspmust not let delete-style config sync mutate the repository checkout.
Backups/snapshots can restore displaced user files when backups are enabled.
./loadout install @engineering-loadout \
--post-install-hook ~/corp-dotfiles/install.sh \
--post-install-hook ~/site-dotfiles/install.shHooks receive these environment variables: LOADOUT_REPO, LOADOUT_HOME,
LOADOUT_BACKUP_DIR, LOADOUT_DEST_DIR, LOADOUT_NO_BACKUP.
./loadout snapshot restore loadout_backups/backup.1.tar.bz2
./loadout snapshot list # browse existing snapshots
./loadout snapshot create my-baseline # take a snapshot without installingNumbered backups are created in loadout_backups/backup.N/ before each
install (numbering always starts at .1). At the end of a successful run
the backup dir is compressed to loadout_backups/backup.N.tar.bz2 and
the uncompressed dir is removed. snapshot restore accepts either the
uncompressed dir or the .tar.bz2 archive. Font files are excluded from
snapshots (large and reproducible).
Recommended:
.\loadout.cmd
# or: pwsh -NoProfile -ExecutionPolicy Bypass -File .\loadout.ps1.\loadout.cmd prefers %USERPROFILE%\.local\opt\powershell\7\pwsh.exe.
If it is missing and no pwsh.exe is already on PATH, it uses Windows
PowerShell 5.1 to extract the bundled PowerShell ZIP and then re-runs the
installer under that user-local pwsh.exe.
Explicit Windows PowerShell 5.1 bootstrap:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\loadout-pwsh-bootstrap.ps1
.\loadout.cmdNo elevation required. Files are copied, not symlinked -- re-run
.\loadout.cmd or .\loadout.ps1 after repo updates.
| Destination | Source |
|---|---|
%LOCALAPPDATA%\nvim\ |
envs/nvim/ |
%USERPROFILE%\.config\wezterm\wezterm.lua |
envs/wezterm/wezterm.lua |
%USERPROFILE%\.config\starship\starship.toml |
envs/starship/starship.windows.toml |
%USERPROFILE%\.editorconfig |
envs/editorconfig/editorconfig |
%USERPROFILE%\autohotkey\hotkeys.ahk |
envs/autohotkey/hotkeys.ahk (feature-patched) |
%USERPROFILE%\loadout_keys.toml |
Created if missing -- choose AHK features |
%USERPROFILE%\.local\opt\powershell\7\ |
Bundled PowerShell ZIP from payload/windows.x86_64/powershell/ |
%LOCALAPPDATA%\Microsoft\Windows Terminal\Fragments\engineering-loadout\powershell.json |
Windows Terminal profile for bundled PowerShell |
| PowerShell profile (5.1 + 7+) | envs/powershell/Microsoft.PowerShell_profile.ps1 |
Edit %USERPROFILE%\loadout_keys.toml:
| Feature | Description |
|---|---|
corp-logins |
Corp credential entry hotkeys |
mouse-wiggle |
Idle mouse nudge to prevent lock screens |
cisco-secure-client-vpn |
Cisco Secure Client auto-reconnect |
password-manager |
Password manager quick-type hotkey |
tmux-hotkeys |
RAlt/RWin zoom toggle, Ctrl+; last-pane toggle |
f1f2f3-as-mouse-buttons |
F1/F2/F3 mouse remaps for mspaint/etxc/wezterm-gui |
thinlinc-reconnect |
Auto-dismiss ThinLinc errors and reconnect |
The Cisco Secure Client automation can skip VPN login attempts on named Wi-Fi
networks. Add exact SSID names under %USERPROFILE%\loadout_keys.toml:
[autohotkey.features.cisco-secure-client-vpn]
skip_wifi_ssids = [
"Home WiFi",
"Phone Hotspot",
]