- GNU Stow packages: kitty, fish, nvim, btop, fastfetch, starship, git, claude - install.sh with modular install, template rendering, fish plugins setup - uninstall.sh (stow -D) and scripts/doctor.sh for health checks - Brewfile (macOS) + Aptfile (Linux servers) - Claude Code hooks pipeline: settings.json.tpl, Obsidian session logging scripts - memory-compiler inline copy with env-var-based paths - Python scripts patched: os.environ.get() for OBSIDIAN_VAULT + PROJECTS_ROOT - fish/config.fish: platform-aware Homebrew PATH (macOS + Linuxbrew) - .env.example template for ~/.dotfiles.env Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
87 lines
3.4 KiB
Bash
Executable file
87 lines
3.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# scripts/doctor.sh — Verify dotfiles installation health
|
|
|
|
set -uo pipefail
|
|
|
|
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
source "$REPO_DIR/lib/helpers.sh"
|
|
|
|
PASS=0; FAIL=0
|
|
|
|
check() {
|
|
local label="$1"; local result="$2"
|
|
if [[ "$result" == "ok" ]]; then
|
|
echo -e " ${GREEN}✓${RESET} $label"
|
|
((PASS++))
|
|
else
|
|
echo -e " ${RED}✗${RESET} $label ${RED}($result)${RESET}"
|
|
((FAIL++))
|
|
fi
|
|
}
|
|
|
|
check_symlink() {
|
|
local label="$1"; local path="$2"; local expected_target="$3"
|
|
if [[ -L "$path" ]]; then
|
|
local actual
|
|
actual="$(readlink "$path")"
|
|
if [[ "$actual" == "$expected_target"* ]]; then
|
|
check "$label" "ok"
|
|
else
|
|
check "$label" "symlink points to $actual (expected under $expected_target)"
|
|
fi
|
|
elif [[ -f "$path" || -d "$path" ]]; then
|
|
check "$label" "exists but is NOT a symlink — may be a real file (run stow)"
|
|
else
|
|
check "$label" "missing"
|
|
fi
|
|
}
|
|
|
|
check_cmd() {
|
|
local cmd="$1"
|
|
has_cmd "$cmd" && check "$cmd in PATH" "ok" || check "$cmd in PATH" "not found"
|
|
}
|
|
|
|
echo ""
|
|
step "Dotfiles symlinks"
|
|
check_symlink "kitty.conf" "$HOME/.config/kitty/kitty.conf" "$REPO_DIR"
|
|
check_symlink "fish/config.fish" "$HOME/.config/fish/config.fish" "$REPO_DIR"
|
|
check_symlink "fish_plugins" "$HOME/.config/fish/fish_plugins" "$REPO_DIR"
|
|
check_symlink "nvim/init.lua" "$HOME/.config/nvim/init.lua" "$REPO_DIR"
|
|
check_symlink "btop.conf" "$HOME/.config/btop/btop.conf" "$REPO_DIR"
|
|
check_symlink "fastfetch.jsonc" "$HOME/.config/fastfetch/config.jsonc" "$REPO_DIR"
|
|
check_symlink ".gitignore_global" "$HOME/.gitignore_global" "$REPO_DIR"
|
|
check_symlink "settings.json" "$HOME/.claude/settings.json" "$REPO_DIR"
|
|
|
|
echo ""
|
|
step "Required binaries"
|
|
for cmd in fish kitty nvim bat lsd fd rg fzf zoxide uv stow git lazygit; do
|
|
check_cmd "$cmd"
|
|
done
|
|
|
|
echo ""
|
|
step "Claude Code hooks"
|
|
check_symlink "obsidian-session-start.py" "$HOME/.claude/obsidian-session-start.py" "$REPO_DIR"
|
|
check_symlink "obsidian-session-log.py" "$HOME/.claude/obsidian-session-log.py" "$REPO_DIR"
|
|
check_symlink "obsidian-postcompact.py" "$HOME/.claude/obsidian-postcompact.py" "$REPO_DIR"
|
|
check_symlink "cc-collector.py" "$HOME/.claude/cc-collector.py" "$REPO_DIR"
|
|
check_symlink "create-periodic-note.py" "$HOME/.claude/create-periodic-note.py" "$REPO_DIR"
|
|
|
|
echo ""
|
|
step "Memory-compiler"
|
|
MC_DIR="$HOME/.claude/memory-compiler"
|
|
[[ -d "$MC_DIR" ]] && check "memory-compiler directory" "ok" || check "memory-compiler directory" "missing"
|
|
[[ -L "$MC_DIR/knowledge" ]] && check "knowledge/ symlink" "ok" || check "knowledge/ symlink" "missing — run install.sh --module claude"
|
|
[[ -d "$MC_DIR/.venv" ]] && check "uv venv" "ok" || check "uv venv" "missing — run: cd $MC_DIR && uv sync"
|
|
|
|
echo ""
|
|
step "Environment"
|
|
load_env 2>/dev/null && check "~/.dotfiles.env loaded" "ok" || check "~/.dotfiles.env" "missing or incomplete"
|
|
[[ -d "${OBSIDIAN_VAULT:-}" ]] \
|
|
&& check "OBSIDIAN_VAULT exists" "ok" \
|
|
|| check "OBSIDIAN_VAULT" "not found at ${OBSIDIAN_VAULT:-unset} (clone SamoilenkoVadym/obsidian)"
|
|
|
|
echo ""
|
|
echo "────────────────────────────────────────"
|
|
echo -e " ${GREEN}Passed: $PASS${RESET} ${RED}Failed: $FAIL${RESET}"
|
|
[[ $FAIL -eq 0 ]] && echo -e " ${GREEN}All good!${RESET}" || echo -e " ${YELLOW}Fix the issues above and re-run.${RESET}"
|
|
echo ""
|