Source of truth for my machine: terminal, editor, shell, and the setup around them. The repo
carries its own installer, so a clone provisions a machine on its own, and the
dotfiles-setup skill is the remote path into the same code rather than a second copy of it.
Either way the files here are what gets deployed, so editing this repo is all the next
machine needs.
| Path | Purpose |
|---|---|
bootstrap.ps1 |
Bare-machine entry point: installs git and node, then runs the installer |
install.mjs |
The installer. Deploys every folder below |
fonts/ |
Vendored terminal font, installed per-user |
nvim/ |
Neovim config (lazy.nvim; plugin versions pinned in lazy-lock.json) |
nvim/lua/config/ |
options, theme, keymaps, layout, splash, gitstat |
nvim/lua/plugins/ |
One lazy.nvim spec per plugin |
tabby/config.yaml |
The Tabby profile |
shell/ |
bash, readline, and git |
machine/ |
The machine itself: software, login startup, user folders, privacy |
install.mjs is a node script in a git repository, so it cannot be what puts git and node on
a machine that has neither. bootstrap.ps1 is the piece that runs before them: stock Windows
PowerShell, no dependencies. It installs those two through winget, refreshes PATH in the
running session (winget writes the new PATH to the registry, not to the shell that called
it, which is why a fresh install otherwise stays invisible until a new terminal), clones the
repo, and hands over.
Download it, read it, then run it:
irm https://raw.githubusercontent.com/baairon/dotfiles/main/bootstrap.ps1 -OutFile bootstrap.ps1
notepad bootstrap.ps1
powershell -ExecutionPolicy Bypass -File .\bootstrap.ps1 -DryRun
powershell -ExecutionPolicy Bypass -File .\bootstrap.ps1It installs only what the installer itself needs. Everything else in machine/machine.json
is reported, not installed, unless asked for with --install-software. Arguments are passed
straight through, so .\bootstrap.ps1 --machine works.
One command, from a fresh clone:
git clone https://github.com/baairon/dotfiles
cd dotfiles
node install.mjs # font, terminal, editor, shell
node install.mjs --machine # ...and the machine layerinstall.mjs deploys the checkout it is sitting in, so no flags are needed. It runs on Node
with builtins only, no dependencies to install first. Useful before committing to it:
node install.mjs --dry-run # report every write, perform none
node install.mjs --list # what is already present on this machine
node install.mjs --selftest # the installer's own checksEvery target is backed up to a timestamped .bak-... before it is replaced, and files that
already match are left alone, so a second run is a no-op rather than a pile of backups. The
machine layer is off by default: the steps above write config files, while that one writes
the registry and repoints user folders.
Individual layers can be skipped with --no-fonts, --no-tabby, --no-nvim, --no-shell.
What the installer does, for a machine where running it is not wanted:
-
Neovim: copy or symlink
nvim/into the Neovim config directory (%LOCALAPPDATA%\nvimon Windows,~/.config/nvimelsewhere). First launch bootstraps lazy.nvim and installs the pinned plugins. Needs Neovim 0.10 or later; treesitter parsers compile on demand, which needs thetree-sitterCLI (0.26 or later) and a C compiler on PATH. On a Windows machine without MSVC the config pointsCCat gcc. Optional tools:lazygitfor the git float,ripgrepfor live grep. -
Fonts: install
fonts/CozetteVector.ttfandfonts/CozetteVectorBold.ttfper-user, no elevation. Do this before step 3, since the Tabby profile names the font.-
Windows: copy both files into
%LOCALAPPDATA%\Microsoft\Windows\Fonts, then add one string value per file underHKCU\Software\Microsoft\Windows NT\CurrentVersion\Fonts. The value name is the font's full name plus its format, and the data is the copied file's full path:CozetteVector (TrueType) = %LOCALAPPDATA%\Microsoft\Windows\Fonts\CozetteVector.ttf CozetteVectorBold (TrueType) = %LOCALAPPDATA%\Microsoft\Windows\Fonts\CozetteVectorBold.ttfCalling
AddFontResourceWon each path and broadcastingWM_FONTCHANGEmakes them usable in the current session without a logout. -
Linux: copy into
~/.local/share/fonts, then runfc-cache -f. -
macOS: copy into
~/Library/Fonts.
Verify with the installed-font list rather than assuming: the two families that must appear are
CozetteVectorandCozetteVectorBold. -
-
Tabby: copy
tabby/config.yamlinto Tabby's config directory (%APPDATA%\tabbyon Windows,~/.config/tabbyon Linux,~/Library/Application Support/tabbyon macOS). Tabby holds its config in memory and rewrites the file on exit, so fully quit it (tray icon included, not just the window) before copying, then relaunch. Writing the file while Tabby runs gets silently clobbered on quit.The font is wired under the
terminal:block, and the repo copy already carries both keys:terminal: font: CozetteVector fontSize: 19
-
Shell: copy the files in
shell/to their homes:bashrc,bash_profile,inputrc,gitconfigandgitignore_globalto~/.bashrc,~/.bash_profile,~/.inputrc,~/.gitconfigand~/.gitignore_global, andgit-prompt.shto~/.config/git/git-prompt.sh, which is the path Git for Windows looks for before building its own prompt. Machine-specific settings go in~/.bashrc.localand~/.gitconfig.local, which are sourced last and are never tracked, so a redeploy cannot overwrite them.shell/README.mdcarries the reasoning. -
Machine: apply
machine/machine.json, which declares the software that belongs on the box, what launches at login and with which flag, where the user folders live, and which background collection is off. Startup entries and user folders apply with no elevation. Software is only reported as present or missing unless you ask for it to be installed, and the privacy changes need administrator rights so they are emitted as a script to review and run yourself.machine/README.mdcarries the reasoning, including the manual OneDrive removal sequence that is deliberately never automated.
Every target applies from whatever the files currently hold, never a baked-in snapshot.
- Cozette ships Nerd Font icon and Powerline glyphs built in, so no separately patched Nerd
Font build is needed. Vendored from
the-moonwitch/Cozetterelease v.1.30.0. CozetteVectorBoldregisters under its own family name rather than as the bold face ofCozetteVector, so nothing pairs them automatically and Tabby synthesizes bold instead. The profile pinsfontWeightBold: 600and keeps that synthesis. Dropping it to400is what turns the synthesis off, by asking for bold text at the one weight the family actually has.fontSize: 19is a baked-in zoom level. Tabby scales zoom by1.1^stepsand never persists it, so pinning the size is the only way to make it survive a restart, and it moves whatreset-zoom(Ctrl+0) returns to.- Cozette is a 6x13 bitmap font and these TTFs are the outline conversion, so 13 and 26 are the only sizes that land exactly on its pixel grid. Everything else renders slightly soft.