Something went wrong. Try again.
🏠 sweet ~/
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211#!/bin/bash## script/doctor# Check dotfiles health and report any issues
# Only emit ANSI color when stdout is a TTY; otherwise a piped or# redirected invocation (e.g. `./script/doctor > doctor.log`) would# embed raw escape codes.if [ -t 1 ]; then RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' NC='\033[0m' # No Colorelse RED='' GREEN='' YELLOW='' NC=''fi
passed=0failed=0warned=0
ok() { printf " ${GREEN}[OK]${NC} %s\n" "$1" passed=$((passed + 1))}
missing() { printf " ${RED}[MISSING]${NC} %s\n" "$1" failed=$((failed + 1))}
warn() { printf " ${YELLOW}[WARN]${NC} %s\n" "$1" warned=$((warned + 1))}
check_cmd() { if command -v "$1" &>/dev/null; then ok "$1" return 0 else missing "$1" return 1 fi}
echo "=== Dotfiles Health Check ==="echo
# -------------------------echo "Core tools:"check_cmd nvimcheck_cmd fishcheck_cmd tmuxcheck_cmd gitcheck_cmd starshipecho
# -------------------------echo "Development tools:"check_cmd misecheck_cmd fzfcheck_cmd rgcheck_cmd batcheck_cmd lazygitcheck_cmd jqcheck_cmd ghecho
# -------------------------# Mason is disabled in the Neovim config, so these come from mise# (common/.config/mise/config.toml) — `make mise` installs them.echo "Language servers:"check_cmd lua-language-servercheck_cmd harper-lscheck_cmd bash-language-servercheck_cmd ruby-lspcheck_cmd goplsecho
# -------------------------echo "Linters & formatters:"check_cmd shellcheckcheck_cmd styluacheck_cmd gofumptcheck_cmd goimportsecho
# -------------------------echo "Shell configuration:"if [[ "$SHELL" == *"fish"* ]]; then ok "Default shell is Fish"else warn "Default shell is not Fish ($SHELL)"fi
if [[ -f "$HOME/.config/fish/local_env.fish" ]]; then ok "local_env.fish exists"else warn "local_env.fish not found (copy from local_env.fish.example)"fiecho
# -------------------------echo "Git configuration:"if git config user.name &>/dev/null; then ok "user.name: $(git config user.name)"else missing "git user.name not set"fi
if git config user.email &>/dev/null; then ok "user.email: $(git config user.email)"else missing "git user.email not set"fi
if [[ "$(git config commit.gpgsign)" == "true" ]] \ && [[ "$(git config gpg.format)" == "ssh" ]]; then signing_program=$(git config gpg.ssh.program) if [[ -x "$signing_program" ]]; then ok "SSH commit signing enabled via 1Password" else warn "SSH signing program unavailable ($signing_program)" fielse warn "SSH commit signing not enabled"fi
# Drift check: setup-git-config owns rendering and can compare its expected# output with the live file without changing it.REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"IDENTITY_FILE="$HOME/.config/local/git/identity.gitconfig"LIVE_CONFIG="$HOME/.config/git/config"if [[ -f "$LIVE_CONFIG" ]] \ && [[ -n "${CODESPACES:-}" || -f "$IDENTITY_FILE" ]]; then if "$REPO_ROOT/script/setup-git-config" --check; then # shellcheck disable=SC2088 # tilde is intentionally literal in display text ok '~/.config/git/config matches template' else # shellcheck disable=SC2088 warn '~/.config/git/config drifted from template (run: make regen-git-config)' fifiecho
# -------------------------echo "Runtime versions (mise):"if command -v mise &>/dev/null; then mise list 2>/dev/null | while read -r line; do echo " $line" done if [[ -z "$(mise list 2>/dev/null)" ]]; then warn "No runtimes installed (run: mise install)" fielse warn "mise not available"fiecho
# -------------------------echo "Neovim:"if command -v nvim &>/dev/null; then nvim_version=$(nvim --version | head -1) ok "$nvim_version"
# Check if LazyVim is bootstrapped if [[ -d "$HOME/.local/share/nvim/lazy/LazyVim" ]]; then ok "LazyVim installed" else warn "LazyVim not installed (open nvim to bootstrap)" fifiecho
# -------------------------echo "Tmux:"if command -v tmux &>/dev/null; then tmux_version=$(tmux -V) ok "$tmux_version"
if [[ -d "$HOME/.tmux/plugins/tpm" ]]; then ok "TPM installed" else warn "TPM not installed (run: git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm)" fifiecho
# -------------------------echo "=== Summary ==="printf " ${GREEN}Passed:${NC} %d\n" "$passed"printf " ${YELLOW}Warnings:${NC} %d\n" "$warned"printf " ${RED}Failed:${NC} %d\n" "$failed"echo
if [[ $failed -gt 0 ]]; then echo "Run 'make brew' for shell/terminal tools, 'make mise' for runtimes," echo "language servers, linters, and formatters." exit 1elif [[ $warned -gt 0 ]]; then echo "Some optional items need attention." exit 0else echo "Everything looks good!" exit 0fi