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 on agent.bairon.eth is a remote path
into that same installer. Neither keeps a copy of the files, 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 |
fonts/optional/ |
Other faces kept here, installed only on request |
nvim/ |
Neovim config: lua/config/ for settings, lua/plugins/ one per plugin |
tabby/config.yaml |
The terminal profile |
shell/ |
bash, readline, and git |
machine/ |
Optional machine layer, applied from a local manifest |
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 runs before them: stock Windows PowerShell, no
dependencies. It installs those two, makes them usable in the running session, 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. Anything else is reported rather than installed
unless you ask for it, and arguments are forwarded, so .\bootstrap.ps1 --machine --install-software reaches install.mjs untouched.
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, and it runs on Node
builtins alone with nothing to install first. Worth running before it writes anything:
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.
Individual layers can be skipped with --no-fonts, --no-tabby, --no-nvim, --no-shell.
This step is off by default: the ones above write config files, while this one writes the registry
and repoints user folders. It applies machine/machine.json, which is per-machine and not tracked
here. Copy the example and edit it for the box you are on:
cp machine/machine.example.json machine/machine.json
node install.mjs --machine --dry-runThe manifest declares the software the setup needs, what launches at login and with which flag,
where the user folders live, and which background collection is switched off. Startup entries and
user folders apply with no elevation. Software is reported as present or missing unless you ask
for it to be installed, and the privacy changes need administrator rights, so --privacy emits a
script to review and run yourself.
A user folder whose current location still holds files is reported [BLOCKED] and left alone
rather than repointed, since repointing it would strand the data. Move the files first, or pass
--force-folders if you mean it.
Neovim 0.10 or later, and a tree-sitter CLI of 0.26 or later plus a C compiler on PATH, since
parsers compile on demand. On Windows without MSVC the config points CC at gcc. lazygit backs
the git float and ripgrep backs live grep. The installer reports every one of these, and
installs them with --install-software.
Cozette, a 6x13 bitmap font, vendored from the-moonwitch/Cozette release v.1.30.0 as
CozetteVector.ttf and CozetteVectorBold.ttf and installed per-user with no elevation. It ships
Nerd Font icon and Powerline glyphs built in, so no separately patched build is needed.
The profile sets it at fontSize: 19. Sizes that land exactly on the pixel grid are 13 and 26;
everything else renders slightly soft.
Two settings in the profile behave differently than they look:
CozetteVectorBoldregisters under its own family name rather than as the bold face ofCozetteVector, so nothing pairs them and Tabby synthesizes bold instead.fontWeightBold: 600keeps that synthesis. Dropping it to400turns it off, by asking for bold at the one weight the family actually has.fontSizeis a baked-in zoom level. Tabby scales zoom by1.1^stepsand never persists it, so pinning the size is the only way to survive a restart, and changing it moves whatreset-zoom(Ctrl+0) returns to.
fonts/optional/ carries faces that belong on the machine but are no part of the setup, so they
travel with the repo and install only when asked for:
node install.mjs --optional-fontsA default run never touches them. They register per-user with no elevation, the same as the
terminal font, and --list shows them separately so a face you have not asked for does not read
as one the installer failed to install.