-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Summary
Build @virtualian/dotfiles-cli — a TypeScript + Bun CLI that syncs shell and application configuration across machines using a bare git repository. Replaces the previous Bash script approach with a cross-platform npm package.
Technique origin: StreakyCobra on Hacker News (2016), popularized by Atlassian's Git tutorial
Architecture
@virtualian/dotfiles-cli
src/
cli.ts ← entry point + dispatcher
commands/
init.ts
sync.ts
audit.ts
bootstrap.ts
add.ts
ls.ts
help.ts
git.ts ← git wrapper (--git-dir, --work-tree)
bin/
dotfiles ← shim: #!/usr/bin/env bun
package.json
Pass-through dispatcher: known subcommands are handled in src/commands/, everything else forwards to git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME. All git commands work — unknown input goes straight through.
~/.dotfiles/ ← bare git repo (history only, no working tree)
$HOME ← working tree (where actual config files live)
Custom Commands
| Command | What It Does |
|---|---|
dotfiles help |
Show all commands |
dotfiles init |
Create bare repo at ~/.dotfiles with default ignore rules |
dotfiles sync [message] |
Stage tracked changes + commit + push. Default message: sync YYYY-MM-DD |
dotfiles ls |
List all tracked files |
dotfiles audit |
Scan tracked files for secrets (private keys, .env, API tokens) |
dotfiles bootstrap <repo-url> |
Full new-machine setup: clone, backup conflicts, checkout, configure |
dotfiles add <path> |
Add file to tracking (warns on directories, shows dry-run first) |
Git Pass-Through
Every git command works as you'd expect — the CLI forwards anything it doesn't recognize:
dotfiles status # → git status
dotfiles diff # → git diff
dotfiles log --oneline # → git log --oneline
dotfiles stash # → git stash
dotfiles branch -a # → git branch -aTechnical Details
- Language: TypeScript + Bun (not Bash — cross-platform, testable, proper error handling)
- Runtime: Bun (~25ms startup, built-in testing via
bun test) - Git calls:
Bun.$for shell execution (quiet mode for capturing, passthrough for interactive) - Ignore rules:
$GIT_DIR/info/exclude(avoids polluting$HOMEwith.gitignore) - Directory add protection:
dotfiles add <dir>shows dry-run preview viagit add -n, requires confirmation - Audit: File-level patterns (
.pem,.key,.env) + content-level regex (api_key=,secret:,token=,password=)
Sensitive Data Protection
Three layers:
- Default ignore rules —
dotfiles initconfigures exclusions for private keys,.envfiles, known sensitive paths - Directory warnings —
dotfiles add <dir>shows dry-run preview, asks for confirmation - Audit command —
dotfiles auditscans tracked files for secrets, returns non-zero if found
Distribution
# npm registry (primary)
bun add -g @virtualian/dotfiles-cli
# Standalone binary (no runtime needed)
bun build --compile --target=bun-darwin-arm64 src/cli.ts --outfile dotfiles-macos
bun build --compile --target=bun-linux-x64 src/cli.ts --outfile dotfiles-linux
# Direct from repo
bun install -g github:virtualian/dotfiles-cliAcceptance Criteria
-
dotfiles helpshows all custom and pass-through commands -
dotfiles initcreates bare repo at~/.dotfileswith default ignore rules -
dotfiles initsetsstatus.showUntrackedFiles no -
dotfiles syncstages tracked changes, commits, and pushes in one command -
dotfiles sync "custom msg"uses custom commit message -
dotfiles syncwith no changes prints clean message, exits 0 -
dotfiles lslists tracked files -
dotfiles auditdetects secret files, returns non-zero -
dotfiles auditpasses on clean repo -
dotfiles add <dir>warns and shows dry-run before proceeding -
dotfiles add <file>works without prompting -
dotfiles bootstrap <url>clones, backs up conflicts, checks out, configures -
dotfiles bootstrapwith existing~/.dotfilesfails with clear error - All unknown subcommands pass through to git correctly
-
dotfiles status,dotfiles log,dotfiles diffall work - Published to npm as
@virtualian/dotfiles-cli -
bun testpasses all tests - No dependencies beyond Bun + git
Reference
Full design document: Plans/dotfiles-bare-repo-guide.md
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels