Personal development environment configuration managed with Chezmoi and Pixi.
One-liner that handles cache permissions and installs everything:
DevContainers/DevPod:
curl -fsSL https://raw.githubusercontent.com/blooop/dotfiles/main/install.sh | DEVPOD=1 bashFull (personal machines):
curl -fsSL https://raw.githubusercontent.com/blooop/dotfiles/main/install.sh | bashFor more control, choose the installation level based on your use case:
Minimal (shared/untrusted machines - tools only, no git config):
sudo apt update && sudo apt install -y curl && \
curl -fsSL https://pixi.sh/install.sh | bash && \
export PATH="$HOME/.pixi/bin:$PATH" && \
pixi global install chezmoi && \
chezmoi init --apply --exclude .gitconfig git@github.com:blooop/dotfiles.git && \
pixi global syncDevContainers (development containers - tools + git config):
sudo apt update && sudo apt install -y curl && \
curl -fsSL https://pixi.sh/install.sh | bash && \
export PATH="$HOME/.pixi/bin:$PATH" && \
pixi global install chezmoi && \
DEVPOD=1 chezmoi init --apply git@github.com:blooop/dotfiles.git && \
pixi global syncFull (personal laptop - complete setup):
sudo apt update && sudo apt install -y curl && \
curl -fsSL https://pixi.sh/install.sh | bash && \
export PATH="$HOME/.pixi/bin:$PATH" && \
pixi global install chezmoi && \
chezmoi init --apply git@github.com:blooop/dotfiles.git && \
pixi global syncNote: Always inspect scripts before running. You can review files at github.com/blooop/dotfiles
For development containers, you have two options:
DevPod (automated):
First-time setup - add the Docker provider and configure automatic dotfiles:
devpod provider add docker
devpod context set-options -o DOTFILES_URL=https://github.com/blooop/dotfilesThis configures devpod to automatically install dotfiles for all new workspaces.
Alternatively, use the --dotfiles argument for individual workspaces:
devpod up <project-repo> --dotfiles https://github.com/blooop/dotfilesDevPod will automatically detect and run the install.sh script to configure your environment.
Manual (any devcontainer):
Use the DevContainers installation command above, or add to your devcontainer configuration.
- Essential CLI tools - fzf, fd, ripgrep, htop, nvtop, btop
- Navigation & display - zoxide (smart cd), broot (tree browser), zellij (multiplexer)
- Development tools - chezmoi, lazygit, lazydocker, ccache
- Editors - Neovim with full configuration, vim
- Utilities - curl, unzip
Minimal setup optimized for development containers:
- Excludes git, git-lfs, openssh (provided by container)
- Focuses on productivity tools and editors
Complete setup for host machines:
- Git tools - git, git-lfs for full version control
- SSH tools - openssh suite for secure connections
- All core tools - Everything from DevPod profile plus host-specific tools
- Rust development - Can be enabled during interactive setup
The git configuration (included in DevContainers and Full installations) provides:
- Useful aliases -
com(checkout main),pom(pull origin main),cam(commit -am),pomp(pull and push),pushf(push --force-with-lease) - Sensible defaults - Auto-setup remotes,
push.default = simple - Stacked-PR friendly -
rebase.updateRefs(rewrite stacked refs in one rebase) andrerere(remember conflict resolutions across restacks) - Personal credentials - Uses Austin Gregg-Smith's git user info, except in
agsinstalls where identity is omitted (safe on shared machines)
fzf- Fuzzy file finderfd- Fast file searchripgrep- Fast text searchzoxide- Smart directory jumpingbroot- Interactive tree browserzellij- Terminal multiplexerforgit- fzf-powered git commandsnvim- Neovim editorlazygit- Terminal git UIchezmoi- Dotfiles managementhtop,nvtop- System monitoringccache- Compiler cachingcurl,unzip- Essential utilities
git- Git version controlgit-lfs- Git Large File Storageopenssh- SSH client and server tools
You can customize which profile is used by editing dot_chezmoi.toml:
[data]
profile = "devpod" # or "full"
tools = { rust = false } # or true to include Rust tools| Alias | Command |
|---|---|
.. |
cd .. |
... |
cd ../.. |
.... |
cd ../../.. |
br |
broot: browse with type-to-filter; →/Enter goes into a dir, ← goes up. Press alt-t (or type :t) to cd the terminal to the selected dir and quit. Default search is token-based: type comma-separated fragments in any order, e.g. kin,ros matches kinisi_ros. Prefix f/ for fuzzy, |/&/! for or/and/not |
z <name> |
zoxide: jump to most-used dir matching name |
Alt+C |
fzf: fuzzy-pick a subdirectory and cd into it |
| Alias | Command |
|---|---|
ll |
ls -alF |
la |
ls -A |
l |
ls -CF |
| Alias | Command |
|---|---|
gs |
git status |
gp |
git push |
lg |
lazygit |
gg |
glo --all — fuzzy all-branches commit graph (forgit log) |
ga |
forgit: interactive add |
gd |
forgit: interactive diff |
glo |
forgit: interactive log |
gcb |
forgit: checkout branch |
gss |
forgit: stash show |
pushf |
git push --force-with-lease (safe force-push for restacks) |
A stack is a chain of branches/PRs from main up to your top branch. The agent commits each change onto the branch it belongs to; /stack sync does the bookkeeping. GitHub PRs are the source of truth for topology. Two commands:
| Command | Purpose |
|---|---|
/stack create <N> |
Slice the current branch into an N-PR stack (N−1 interior branches + the original kept as top). Shows the proposed split first. |
/stack sync |
Idempotent bookkeeping from any state: restack each branch onto its parent (bottom→top, onto latest main), reconcile/create/retarget PRs, prune merged branches, push --force-with-lease. |
Commit each change onto whichever branch it belongs to, then run /stack sync; descendants restack and every PR updates. gh pr checkout <n> jumps to any PR's branch natively.
| Alias | Command |
|---|---|
grep |
grep --color=auto |
mkdir |
mkdir -pv |
df / du / free |
-h (human-readable sizes) |
rm / cp / mv |
-i (prompt before overwrite) |
| Alias | Command |
|---|---|
cld |
claude --dangerously-skip-permissions |
cldr |
claude --dangerously-skip-permissions --resume |
Attaches VS Code windows to existing dev containers, local or on another machine over SSH — no F1 menu, no manual ssh. Candidates come from VS Code's own history (every container you've attached to before, with its workspace path) plus any currently running containers; live status is checked with docker ps locally and over ssh. Stopped containers are started automatically before attaching. Container creation is dl's job; va only re-attaches.
| Command | Purpose |
|---|---|
va |
fzf picker — TAB to multi-select, Enter to launch all selected |
va <token> ... |
batch launch every workspace whose container@host matches a token (e.g. va k1ci k2ci); exact container names win over substring matches |
va -a [token ...] |
launch everything (optionally filtered) without the picker |
va -l |
list known workspaces with live container status |
va -H <host> |
also scan an ssh host with no attach history (repeatable) |
va -n ... |
dry-run — print the docker start / code --folder-uri commands only |
| Command | Purpose |
|---|---|
ags |
Enter an isolated shell with full dotfiles (bootstraps into ~/.local/share/ags on first run, never touches the real HOME) |
ags <container> |
Same, inside a running docker container — injects itself and bootstraps there |
ags update |
Re-run the dotfiles install in the isolated environment |
ags uninstall |
Remove ags and its cached environment |
Install on a remote machine or container (one time, then just type ags in any later login shell):
mkdir -p ~/.local/bin && curl -fsSL https://raw.githubusercontent.com/blooop/dotfiles/main/private_dot_local/private_bin/executable_ags -o ~/.local/bin/ags && chmod +x ~/.local/bin/ags && ~/.local/bin/agsSafe on shared machines (robots, lab PCs): the entire footprint is ~/.local/bin/ags plus the ~/.local/share/ags cache — no rc files or other shared state are modified, and ags installs exclude personal info (git identity is omitted, so commits made by others on the account can't impersonate you; set GIT_AUTHOR_*/GIT_COMMITTER_* per-session when you need to commit). The dotfiles repo is public and contains no credentials.
For containers you launch yourself (rocker with user mapping), mount the host cache to skip the bootstrap entirely: -v ~/.local/share/ags:/home/$USER/.local/share/ags. Requires matching username/home path and a glibc-based image.
This dotfiles repository is compatible with:
- DevPod & DevContainers - Automated or manual setup in development containers
- Traditional Chezmoi workflow - Manual installation and management
- Any Unix-like system - Linux, macOS, WSL
After initial setup, use Chezmoi commands to manage your configuration:
chezmoi update # Pull and apply latest changes
chezmoi edit # Edit configuration files
chezmoi apply # Apply pending changesFor settings you want on one machine but not committed to this (public) repo,
use the untracked local override files. They are sourced/included automatically
and chezmoi never manages or overwrites them, so they survive chezmoi apply and /sync:
~/.bash_env.local— sourced at the end of~/.bash_env(per-machine env vars, e.g.WS_EXCLUDE)~/.gitconfig.local— included from~/.gitconfig(per-machine git config, e.g. theghcredential helper)
Symptom: manually-added Host blocks disappear from ~/.ssh/config, seemingly around the time you ran chezmoi apply / /sync.
Cause: not chezmoi. This repo does not manage ~/.ssh/config (chezmoi managed lists no ssh files, and the file has never been in git history), and chezmoi apply never touches unmanaged files. The real culprit is DevPod, which rewrites ~/.ssh/config in place every time a workspace is created, recreated, or deleted. It inserts/prunes blocks between # DevPod Start <ws> / # DevPod End <ws> markers, and when those markers get unbalanced (e.g. an orphaned Start with no matching End) a prune can delete everything down to the next marker — taking your hand-written entries with it. The chezmoi correlation is indirect: run_once_configure-devpod.sh and dl/devpod activity tend to happen right after a sync, and that's what rewrites the file.
Fix — move your personal entries out of DevPod's blast radius. DevPod only edits ~/.ssh/config itself, never files it Includes:
# ~/.ssh/config — keep this near the top (or end); leave the rest for DevPod
Include config.d/*Put your own Host entries in ~/.ssh/config.d/personal. DevPod keeps churning config; your entries live in a file it never opens.
Hardening:
- Delete any orphaned
# DevPod Start …line that has no matching# DevPod End— those are what make a prune over-delete. - To sync personal SSH entries across machines, manage
~/.ssh/config.d/personalwith chezmoi. This repo is public, so only do this with age encryption (encrypted_prefix) — the file contains internal hostnames/IPs that should not be committed in plaintext.