Personal dev environment. macOS and headless Linux, zsh throughout.
macOS:
curl -fsSL https://raw.githubusercontent.com/radiosilence/dotfiles/main/setup-macos | zshSequential bootstrap (xcode → Touch ID for sudo → brew → 1Password → clone) and then hands off to task converge for everything else — mise, symlinks, completions, fonts, gh auth. Idempotent; re-running skips what's already done.
Linux (Ubuntu/Debian, headless):
curl -fsSL https://raw.githubusercontent.com/radiosilence/dotfiles/main/setup-linux | bashbash, because zsh isn't installed yet. Shorter path — apt base packages → mise → clone → gh device-flow auth → task converge. Same Taskfile, same upd; the darwin-only tasks (brew, casks, Touch ID, 1Password, use-ssh, secrets:populate) skip themselves.
No 1Password on a headless box, so git auth is gh's credential helper over HTTPS and secrets aren't populated. If you want signed commits there, ssh -A in from a machine that has the agent.
Where root is allowed: bootstrap may install system packages; the Taskfile may not. converge runs unattended, so on Linux it stays entirely under $HOME — mise in ~/.local, tools in ~/.local/share/mise, configs symlinked into ~. apt:core, apt:upgrade and dnf:upgrade exist but you run them by hand. brew is the exception that isn't one: it's user-owned and installs formulae without root, so brew:bundle stays in converge.
The apt list is short by design: zsh git curl ca-certificates gh rsync gnupg unzip aria2 lsof libimage-exiftool-perl. Nothing there is in mise's registry, and everything that is comes from mise. core.rb's coreutils/findutils/openssl/make are macOS un-BSD-ing and have no Linux equivalent worth installing.
Run upd (or converge) anytime to update everything. Tasks that need gh auth poll silently until ready.
- Shell configs — Modular zsh setup with 30+ config files, 80+ git aliases, fzf-tab completions
scripts/— System maintenance, git workflow, media processing, file operations, in zsh- Taskfile.yml — DAG-based system management (bootstrap, update, completions, fonts)
- Tool management — mise for runtimes, role-based Brewfile for system packages (
brewfiles.d/) - Terminal configs — zellij, ghostty, starship prompt
- Editor configs — helix (LSP, tree-sitter, formatters for 15+ languages), zed
| Doc | Description |
|---|---|
| cheatsheet.md | Complete reference — all commands, aliases, functions |
| new-tools.md | Modern CLI replacements (dust, procs, delta, xh, oha, tokei) |
| fzf-tab-completions.md | Fuzzy completion setup with previews |
| CHANGELOG.md | Full history from 2018 to present |
System
upd/converge— Converge system to desired state (bootstrap + update in one command)task --list— See all available taskskill-port <port>— Kill process on portprune— Find and delete small directories
Git workflow
git sync— Delete merged local branchesgit squash— Squash commits for clean PRsfm/fr— Fuzzy merge/rebase with fzf
Worktrees (wt*) — git worktree management, as local zsh plugins under zsh-plugins/: wt-core plus a backend per multiplexer (wt-herdr, wt-zellij). Worktrees live in <repo-parent>/worktrees/<repo>/<name>/ — outside the repo so editors don't recurse into them.
wt/wt <name>— Upsert worktree + cd (fzf picker with no args)wtt/wth— Same, opening a Zellij tab / herdr workspace insteadwt -b <name>— Branch from current HEAD instead of origin/mainwtpr <n|url>— Worktree for a GitHub PR or issue (handles forks);wtifor issues only,wtpr-pickto fzf over bothwtrm [name]— Remove the worktree you're in (or a named one) + its branchwtclean [-n]— GC worktrees and branches whose PR is merged or closed, pergh. Keeps anything dirty
Media
to-audio opus|flac— Parallel audio conversionembed-art— Embed cover art into FLACsimp— Download + extract + beets import
Files
vimv— Batch rename in $EDITORclean-dls— Remove scene release garbage
These live in scripts/ as zsh — see there for what each one
does, with examples. Nothing is sourced by path — the shell exports FPATH, so
a script just names the functions it wants. Output helpers live in
scripts/lib/functions/; the interface is declared with
zarg, which derives parsing, --help, --version
and --completions zsh|fish|bash from that one declaration, so a script's
completions cannot drift from the flags it actually accepts.
Git signing — Commit signing via 1Password SSH agent. user.signingkey is per-machine (local git config).
Tool duplication — Some tools exist in both brew and mise intentionally:
sheldon— brew for Intel (no arm64 binary), mise for Apple Siliconuv— official astral standalone installer (system-wide Python tooling)
brew services start syncthingWeb UI at http://localhost:8384. Stop: brew services stop syncthing.
- browser-schedule — Time-based browser switching for macOS