Shows Claude's output tokens per second in the status line

Opinionated, curated dotfiles for the discerning developer
A comprehensive cross-platform dotfiles repository that makes strong choices about your development environment. Supporting macOS, Linux (Ubuntu, Fedora, Arch), and WSL with both personal and work configurations, it's designed for developers who want a thoughtfully curated setup without the decision fatigue.
[!TIP] The system automatically detects your platform and environment, making installation straightforward across different setups.
curl -fsSL https://jordangarcia.me/dotfiles/boot.sh | bash
This will automatically clone/update the repo, fetch latest changes, and run interactive setup.
git clone https://github.com/whoisjordangarcia/dotfiles.git
cd dotfiles
./bin/dot -i # Interactive setup
./bin/dot --system mac --work # Direct installation
./bin/dot --system linux_ubuntu --personal
For lightweight servers (no desktop, bash instead of zsh), use the standalone bootstrap — it installs git curl vim neovim tmux htop + Claude Code and symlinks the bash config. See server/README.md.
bash <(curl -fsSL https://raw.githubusercontent.com/whoisjordangarcia/dotfiles/main/server-init.sh)
configs/zshrc/)Modular Z shell configuration with organized .zshrc-modules/:
| Module | Purpose |
|---|---|
.zshrc.history | 50k command history with smart duplicate filtering, ignores mundane commands |
.zshrc.aliases | reload, vim→nvim, ls→eza, cat→bat, top→btop, git shortcuts |
.zshrc.functions | encode64/decode64, compress/decompress, web2app launcher creator |
.zshrc.plugins | Completions + plugins: zsh-syntax-highlighting, zsh-autosuggestions, nx-completion |
.zshrc.envvars | EDITOR, pyenv, colored man pages via bat |
.zshrc.vim-mode | Vi keybindings in shell |
.zshrc.work | Work-specific environment config |
Key Aliases:
gcm - checkout main, gpo - pull origin, gpf - push --force-with-leasewt-auto, wt-list, wt-remove - git worktree managementdotfiles - quick access to this repoconfigs/tmux/)Terminal multiplexer with extensive customization:
Ctrl+a (changed from default Ctrl+b)vim-tmux-navigator (Ctrl+h/j/k/l seamless pane switching)tmux-resurrect + tmux-continuum for persistenceCustom Scripts (~/.tmux/scripts/):
| Script | Function |
|---|---|
pane_title.sh | Gradient-colored pane borders by command (Claude=purple, nvim=green, nx=orange) |
session_picker.sh | Process-aware session selection with zoxide integration |
cpu_usage.sh | CPU monitoring for statusline |
memory_usage.sh | RAM usage display |
Plugins via TPM:
vim-tmux-navigator, tmux-yank, tmux-resurrect, tmux-continuumtmux-sessionx, tmux-floax, tmux-prefix-highlight, tmux-cpu, tmux-batteryconfigs/ghostty/)Fast, GPU-accelerated terminal emulator:
configs/starship/)Minimal, fast shell prompt:
configs/nvim/)LazyVim distribution with 27+ extras enabled:
AI & Coding:
claudecode - Claude Code integrationyanky - Enhanced clipboard managerLanguages:
Editor Enhancements:
aerial - Code outline/symbolsharpoon2 - Quick file navigationilluminate - Highlight word referencesmini-diff - Inline git diffsoutline - Symbol explorertreesitter-context - Shows code context at topAdditional:
configs/lazygit/)Terminal Git UI with custom commands:
c key: Create draft PR via gh pr create --web --draftn key: New branch with type menu (feature/fix/hotfix/chore/docs/refactor)jordan/{type}-{name}configs/rift/) - macOSTiling window manager with integrated SketchyBar:
SketchyBar Integration:
configs/hypr/) - Arch LinuxModern Wayland compositor:
| Config | Purpose |
|---|---|
hyprland.conf | Main entry, sources modular configs |
monitors.conf | Display setup for retina 2x (5K/6K) |
input.conf | Keyboard (US), touchpad settings |
looknfeel.conf | Window rounding (12px), gaps, dwindle layout |
HyDE Integration: Uses HyDE distribution for theming and extended configs.
configs/gtk-3.0/, gtk-4.0/, kvantum/, qt6ct/) - Arch LinuxLinux apps use two different UI toolkits, each with their own theming stack. These configs lock in a readable dark theme and prevent HyDE's wallbash auto-theming from generating unreadable color combinations.
GTK apps (themed by gtk-3.0/settings.ini + gtk-4.0/settings.ini + gsettings):
| App | What it is |
|---|---|
| Brave | Web browser |
| Firefox | Web browser |
| Ghostty | Terminal emulator |
| Spotify | Music |
| Lutris | Game launcher |
| Nautilus | GNOME file manager |
| Pavucontrol | Volume control |
| Waybar | Status bar |
| File picker dialogs | xdg-desktop-portal-gtk |
Qt apps (themed by qt6ct/qt6ct.conf + kvantum/kvantum.kvconfig):
| App | What it is |
|---|---|
| Dolphin | KDE file manager |
| Ark | Archive manager |
| Claude Desktop | AppImage |
| Steam | Uses Qt underneath |
Current theme choices:
Gruvbox-Retro (dark) with Gruvbox-Plus-Dark iconsKvGnomeDark enginedarker.conf color schemecatppuccin-mocha-green-cursors[!NOTE] HyDE's wallbash system dynamically generates a
Wallbash-Gtktheme from wallpaper colors and sets it via gsettings. Thetheming/linuxsetup script overrides this back toGruvbox-Retrofor consistent readability.
configs/waybar/) - Wayland Status BarCustomizable panel for Hyprland:
Modules:
Styling:
configs/dolphin/) - KDE File ManagerFeature-rich file manager for Arch Linux:
View Settings:
Service Menus (right-click actions):
.desktop actionsconfigs/claude/)Claude Code IDE settings and configuration.
| Directory | Purpose |
|---|---|
configs/ssh/ | SSH config with global defaults + Include ~/.ssh/hosts.local for per-machine host aliases |
configs/git/ | .gitconfig.template, .gitignore_global, work.gitconfig |
configs/bat/ | Syntax highlighting for cat replacement |
configs/brave/ | Browser customization |
configs/codex/ | Codex AI integration |
configs/opencode/ | OpenCode settings |
configs/fastfetch/ | System info display |
configs/pyright/ | Python type checking |
configs/i3/ | i3 window manager (Fedora) |
configs/sway/ | Sway compositor |
configs/glazeWM/ | GlazeWM (Windows) |
configs/man/ | Custom man pages for dotfiles |
mac)./bin/dot --system mac
Installs: Homebrew + macOS defaults, 1Password, Git/SSH/GitHub CLI, Zsh, Neovim, Node, Tmux, Starship, Rift (tiling WM) + Ghostty, cmux, LazyGit, Claude/Codex/OpenCode + Agents, Fastfetch, Brave, Sunshine
Work variant (--work): Same installer, same component list — script/mac_components.sh is the single source of truth. WORK_ENV=1 only changes environment-specific config (work git email, etc.), not which components install.
linux_arch)./bin/dot --system linux_arch
Installs: Pacman packages, Git/SSH/GitHub CLI, Node, LazyGit, Zsh, Vim, Tmux, Bat, Ghostty, Fonts, Starship, Fastfetch, Brave, Podman, Claude/Codex + Agents, Dolphin, HyDE theming (Hyprland/Rofi/Btop), VPN split-tunnel, UFW
Pacman packages: zsh, starship, tmux, ripgrep, eza, zoxide, wl-clipboard, fzf, jq, bat, dysk, htop, btop, ttf-jetbrains-mono-nerd, mangohud, darktable, podman, yubikey-manager, github-cli
linux_ubuntu)./bin/dot --system linux_ubuntu
Installs: Core dev tools via apt, Git/SSH, Zsh, Vim, Tmux, Node, LazyGit, Starship, Fastfetch, Brave
linux_fedora)./bin/dot --system linux_fedora
Installs: Git/Zsh/Vim/Tmux, i3wm, Polybar, LazyGit, Fonts, Starship, Fastfetch, Brave
server/)Standalone, bash-based — not part of the bin/dot flow. No desktop, no zsh.
bash <(curl -fsSL https://raw.githubusercontent.com/whoisjordangarcia/dotfiles/main/server-init.sh)
Installs: git, curl, vim, neovim, tmux, htop (apt) + Claude Code (native installer). Symlinks bashrc, bash_profile, aliases, tmux.conf, plus the shared functions/ and gitconfig. Details + how to extend: server/README.md.
dotfiles/
├── bin/
│ └── dot # Shell management CLI
├── boot.sh # Remote bootstrap script
├── server-init.sh # Headless server one-liner bootstrap
├── server/ # Bash config for servers/Proxmox/LXC (see server/README.md)
├── script/
│ ├── common/
│ │ ├── log.sh # Logging utilities (section, step, info, success, fail)
│ │ └── symlink.sh # Symlink with conflict resolution ([O]verride/[B]ackup/[S]kip)
│ ├── *_installation.sh # Platform installers (mac, linux_arch, etc.)
│ └── {component}/ # Component setup scripts
│ └── {platform}/setup.sh
├── configs/ # Configuration files (symlinked to home)
│ ├── rift/ # macOS tiling WM + SketchyBar
│ ├── nvim/ # Neovim + LazyVim
│ ├── tmux/ # Tmux + custom scripts
│ ├── zshrc/ # Zsh + modular configs
│ ├── hypr/ # Hyprland (Arch)
│ ├── waybar/ # Wayland status bar
│ ├── dolphin/ # KDE file manager
│ ├── ghostty/ # Terminal emulator
│ ├── starship/ # Shell prompt
│ ├── lazygit/ # Git TUI
│ └── ...
└── .dotconfig # User preferences (auto-generated)
User preferences stored in .dotconfig:
DOT_NAME="Jordan Garcia"
DOT_EMAIL="user@example.com"
DOT_ENVIRONMENT="work|personal"
DOT_SYSTEM="mac|linux_arch|..."
DOT_YUBIKEY="ABC123..." # Optional GPG key for git signing
./bin/dot -h # Show help
./bin/dot -i # Interactive setup
./bin/dot -l # List available profiles
./bin/dot -m # Select modules interactively
./bin/dot -s # Show system detection
./bin/dot -c # View current config
./bin/dot -e # Open dotfiles in $EDITOR
./bin/dot --reset-config # Clear config and start fresh
./bin/dot --reconfigure # Re-run interactive setup
tmux source ~/.tmux.conf # Reload config
# Inside tmux: <prefix> + I to install plugins
Plugins are sourced directly from ~/.zsh/plugins/. Install via git clone:
git clone https://github.com/zsh-users/zsh-syntax-highlighting ~/.zsh/plugins/zsh-syntax-highlighting
git clone https://github.com/zsh-users/zsh-autosuggestions ~/.zsh/plugins/zsh-autosuggestions
gpg --list-secret-keys --keyid-format=long # Find key ID
# Provide during ./bin/dot -i or set manually
script/{component}/{platform}/setup.shscript/{platform}_installation.shscript/common/log.shconfigs/{component}/bin/dot detect_system()script/{platform}_installation.sh| Issue | Solution |
|---|---|
| Permission denied | Don't run with sudo - scripts handle elevation |
| Missing dependencies | Run platform installation script first |
| Config conflicts | ./bin/dot --reset-config to start fresh |
| Tmux plugins missing | Inside tmux: <prefix> + I |
Tested across macOS, Arch Linux, Ubuntu, Fedora, and WSL. Fork and adapt for your needs.
hooks/register.ts 33 lines1import type { Register } from 'claude-code'
2
3// Rate is measured first chunk → last chunk, so time-to-first-token (queueing,
4// prompt processing) doesn't drag it down. Subagent steps are left out.
5export const register: Register = on => {
6 let tokens = 0
7 let ms = 0 // ponytail: session totals live in module vars, reset on hot reload; move to $.state if that matters
8
9 on('turn.step', async function* ($, e, next) {
10 if (e.agentId) return yield* next(e)
11
12 let first: number | undefined
13 const stream = next(e)
14 let step = await stream.next()
15 while (!step.done) {
16 first ??= await $.clock.now()
17 yield step.value
18 step = await stream.next()
19 }
20 const result = step.value
21 const out = result.usage?.output_tokens ?? 0
22 const elapsed = first === undefined ? 0 : (await $.clock.now()) - first
23
24 if (out > 0 && elapsed > 0) {
25 tokens += out
26 ms += elapsed
27 const rate = (n: number, t: number) => Math.round((n * 1000) / t)
28 $.ui.status(`⚡ ${rate(out, elapsed)} tok/s · avg ${rate(tokens, ms)}`)
29 }
30 return result
31 })
32}
33