Getting Started
This guide covers how to create .tool.ts configuration files for your CLI tools.
Prerequisites
Section titled “Prerequisites”Set up your project configuration first. See Project Configuration for instructions.
Bootstrap Install
Section titled “Bootstrap Install”To bootstrap a dotfiles project in the current directory, run:
curl -fsSL https://alexgorbatchev.github.io/dotfiles/install.sh | bashThe hosted installer uses Bun from PATH when available. Otherwise it checks for curl and unzip before prompting, bootstraps a temporary Bun, adds @alexgorbatchev/dotfiles to the local package.json without running your project’s lifecycle scripts, creates a minimal dotfiles.config.ts when needed, installs managed Bun, and runs dotfiles generate for you. Generated dotfiles shell output resolves Bun at runtime instead of pinning the temporary bootstrap Bun path, and the temporary bootstrap directory is cleaned up before exit even if a later step fails.
Generated shell output includes # /path/to/tool.tool.ts attribution comments before emitted blocks, including generated .once/* helper scripts created from .once(...) shell configuration.
Load Generated Config
Section titled “Load Generated Config”With the default project layout, the generated zsh config lives at .generated/shell-scripts/main.zsh inside your dotfiles directory.
Add it to ~/.zshrc:
source "$HOME/.dotfiles/.generated/shell-scripts/main.zsh"[!IMPORTANT] Configure bash even if your interactive shell is zsh. AI harnesses and other automation often start bash and rely on
~/.bashrcor~/.profileto load the same environment.
if [ -f "$HOME/.dotfiles/.generated/shell-scripts/main.bash" ]; then # shellcheck disable=SC1090 . "$HOME/.dotfiles/.generated/shell-scripts/main.bash"fi
# ~/.profileif [ -n "${BASH_VERSION:-}" ] && [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc"fiThen reload zsh:
source ~/.zshrcFile Structure
Section titled “File Structure”Tool configurations are placed in your toolConfigsDir (default: ~/.dotfiles/tools):
tools/├── fzf.tool.ts├── ripgrep.tool.ts└── dev/ ├── node.tool.ts └── rust.tool.tsFiles must be named {tool-name}.tool.ts and export a default using defineTool.
Minimal Configuration
Section titled “Minimal Configuration”import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) => install("github-release", { repo: "junegunn/fzf", }).bin("fzf"),);Complete Example
Section titled “Complete Example”import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) => install("github-release", { repo: "BurntSushi/ripgrep", }) .bin("rg") .dependsOn("pcre2") .symlink("./ripgreprc", "~/.ripgreprc") .zsh((shell) => shell.env({ RIPGREP_CONFIG_PATH: "~/.ripgreprc" }).aliases({ rgi: "rg -i" })),);Available Methods
Section titled “Available Methods”After calling install(), these methods are available:
| Method | Purpose |
|---|---|
.bin(name) | Define binary name(s) to expose |
.version(v) | Set version ('latest' or specific) |
.dependsOn(bin) | Declare binary dependencies |
.symlink(src, dest) | Create config file symlinks |
.hook(event, fn) | Lifecycle hooks |
.zsh(fn) / .bash(fn) | Shell-specific configuration |
.platform(p, fn) | Platform-specific overrides |
.sudo() | Require an interactive sudo step |
.disable() | Skip tool during generation |
.hostname(pattern) | Restrict tool to specific hostname(s) |
TypeScript Setup
Section titled “TypeScript Setup”Imports
Section titled “Imports”import { Architecture, defineTool, Platform } from "@alexgorbatchev/dotfiles";| Export | Description |
|---|---|
defineTool | Factory function to create tool configurations |
Platform | Enum: Darwin, Linux, Windows, MacOS |
Architecture | Enum: X86_64, Arm64 |
Configuration-Only Tools
Section titled “Configuration-Only Tools”Tools that only contribute shell configuration (no binary installation):
export default defineTool((install) => install().zsh((shell) => shell.env({ FOO: "bar" })));Orphaned Artifact Cleanup
Section titled “Orphaned Artifact Cleanup”When a .tool.ts configuration file is removed, dotfiles generate automatically cleans up the corresponding generated shims and completions on the next run. Removing a .bin() declaration from an existing tool also removes that tool’s stale shim on the next dotfiles generate. No manual cleanup is needed.
Auto-Generated Types
Section titled “Auto-Generated Types”Running dotfiles generate creates .generated/tool-types.d.ts with type-safe dependsOn() autocomplete for all your tool binaries. Standalone compiled-binary installs may generate additional supporting declaration files in .generated/, but you should still include only .generated/tool-types.d.ts in tsconfig.json.
In standalone-binary projects, dotfiles generate writes the supporting authoring declaration file automatically and wires it in for you. That means:
- imports from the public authoring package typecheck without a local handwritten shim
- nested helper modules that import those packages are supported too
- your
tsconfig.jsonstill only needs.generated/tool-types.d.ts
Add to your tsconfig.json:
{ "include": ["tools/**/*.tool.ts", ".generated/tool-types.d.ts"]}Common Type Errors
Section titled “Common Type Errors”// ❌ Missing required parameterinstall('github-release', {}) // Error: 'repo' is required
// ❌ Invalid parameter for methodinstall('brew', { repo: 'owner/tool' }) // Error: 'repo' not valid for brew
// ❌ String instead of enum.platform('macos', ...) // Error: use Platform.MacOS