Imported from chrisliu298/dotfiles (
AGENTS.md). Install upstream withnpx skills add chrisliu298/dotfiles. Copyright stays with the author.
Repository Guidelines
Personal dotfiles and AI agent configurations for macOS with zsh, managed by dotfiles.sh (the single entrypoint: initializes submodules, symlinks configs into ~, installs skills, and registers MCP servers + Claude plugins + tmux plugins).
Project-level doc. Global Codex/Grok instructions live in
agents/codex/AGENTS.mdandagents/grok/AGENTS.md. Keep this file aligned with the siblingCLAUDE.md— same facts and section order; only the H1, this pointer, and Claude's<important>wrappers may differ.
Project Structure & Module Organization
Four agents/<name>/ directories target one agent's home each: claude/ → ~/.claude/ (CLAUDE.md, settings.json — copied, not symlinked — keybindings, statusline, themes), codex/ → ~/.codex/, grok/ → ~/.grok/ (relay/prism dispatch target), pi/ → ~/.pi/agent/. The rest are not agent homes:
agents/eval/— instruction-following harness for the shared agent doc (prompts, rubric, runner scripts).agents/hooks/— shared Claude/Codex destructive-command guard and tests.agents/skills/— the single source of truth for repo-owned skills;dotfiles.shsymlinks each into the agent dirs theSKILLStable selects (most to Claude/Codex/Grok/Pi; some are Claude-only). Pi (~/.pi/agent/skills/) mirrors the Codex/Grok set and additionally loads its own native npm extensions declared inagents/pi/settings.json.
Elsewhere:
.claude/skills/holds project-local skills available only when working in this repo..config/ghostty: Ghostty/cmux terminal config — tracked in-repo (not fetched from the standalonechrisliu298/ghostty-configrepo), symlinked like the rest of.config/.- The four global instruction files (
agents/claude/CLAUDE.md+agents/{codex,grok,pi}/AGENTS.md) are one canonical, agent-read text copied to all four paths, identical except the H1 (which just names each file —# CLAUDE.mdvs# AGENTS.md). Edit one, copy to the other three (keeping each H1);./dotfiles.sh lintasserts the bodies match. Behavior parity across models when the text changes is checked by the harness inagents/eval/.
Build, Test, and Development Commands
./dotfiles.sh— initialize submodules, sync skill repos, symlink files, install skills, and register MCP servers + Claude plugins + tmux plugins (TPM)../dotfiles.sh lint— run skill portability checks (universal C/X/G skill mechanical violations), the docmaint/agent-doc identity guards, and the Claude theme drift-guard (asserts every token name andbaseinagents/claude/themes/*.jsonstill exists in the installed Claude Code, since the loader drops unknown ones silently); also runs automatically at the end of a full./dotfiles.sh../dotfiles.sh skills— list manual skills and whether each is enabled../dotfiles.sh enable <name>/./dotfiles.sh disable <name>— toggle a manual skill; rewrites the committedagents/skills/manual-skills.enabledset, so commit +dfsto propagate the change to every machine.
Conventions
- Shell load order:
shell/.zshenv(platform detection, env, PATH) →shell/.zshrc(plugins, sources.aliases+.functions) - Themes: Ghostty, Starship, btop, tmux, Codex, pi, and Claude Code (GitHub Light ↔ GitHub Dark), toggled with
theme light|dark|toggle|status; usetheme --all <mode>to apply the same mode on this host plus every peer in_dotfiles_peers(shell/.functions), the one listtheme --allanddfsshare. The active choice is host-local — a singlemodefile under~/.local/state/dotfiles-theme/(never tracked, so switching never dirties git); definitions stay in-repo.shell/theme-applymaterializes each tool's live config frommode(Ghostty/tmux via optionalconfig-file/source-file -qincludes; btop/Starship as generated files, since neither supports includes; Codex by rewriting only[tui].themein the host-local~/.codex/config.toml), anddotfiles.shseeds/re-applies it per host. Codex Desktop follows macOS through its own user-controlled appearance setting. Codex, pi, and Claude Code need explicit handling because their terminal automatic modes do not reliably follow the host-localmode: Codex's short terminal-background probe can time out over SSH and fall back to its dark theme; pi resolves from terminal background detection rather than frommode; and Claude Code's built-in light palette paints user messagesrgb(240,240,240)— invisible on the#fafafacanvas at 1.09:1. Codex pins the same Catppuccin Latte/Mocha syntax themes it would choose adaptively; pi and Claude Code pin their custom themedotfiles, whose live definitiontheme-applyswaps by copyingagents/{pi,claude}/themes/<mode>.jsonto~/.pi/agent/themes/dotfiles.json/~/.claude/themes/dotfiles.json. The latter two watch that file, so running sessions repaint without a restart; their rationale and Claude's contrast values are inshell/theme-applyandagents/claude/README.md.
Skills, MCP Servers & Plugins
Never edit in ~/.claude/skills/, ~/.codex/skills/, ~/.grok/skills/, or ~/.pi/agent/skills/ — those are symlinks. Check agents/skills/README.md for source.
Wiring details — where each kind of skill is edited, the SKILLS/MCP_SERVERS/PLUGINS tables, manual-skill toggling, and the universal-skill authoring rules — live in the skill-wiring skill in .claude/skills/. Run ./dotfiles.sh after any change to re-sync symlinks.
Testing Guidelines
- Primary validation is functional: run
./dotfiles.shand verify symlinks resolve correctly. - Run
./dotfiles.sh lintwhen editing universal skills or skill-install logic. - For skills with Python scripts, run
uv run pyteston the relevant test file. - If you add scripts, include at least one runnable verification path (a test or a documented command).
Commit & Pull Request Guidelines
- Match existing history: imperative, concise subjects (
Add ...,Update ...,Remove ...,Refactor ...). - Keep commits atomic by logical change (docs vs scripts vs skill content).
- PRs include: purpose, changed paths, verification commands run, and any migration/symlink impact. Link related issues; add screenshots only for UI-facing documentation changes.
- Sync after push: after
git pushsucceeds, rundfs(ashell/.functionshelper) to propagate to peers — concurrentgit pull --ff-only+./dotfiles.shonmacbookpro16,macmini,l40s; the current host is skipped. Do not rundfson hostK65YGWKKWH, which is intentionally outside the peer set. Skipping it elsewhere leaves the other machines on the previous revision. Non-interactive/agent shells:zsh -c 'source ~/dotfiles/shell/.functions && dfs'(self-contained; no TTY or.zshrcneeded).
Maintaining Docs
- Sync root docs: keep root
CLAUDE.mdand rootAGENTS.mdaligned — same facts and section order, diverging only in the H1, the project-level pointer, and Claude's<important>wrappers. - Sync global instructions: edit one of the four global instruction files, copy the body to the other three (keeping each H1), commit together — see Project Structure above for the rule and
agents/eval/for the parity check. - Update docs: after structural changes (adding, removing, or renaming files/directories, skills, or configs), check whether
README.md,CLAUDE.md, orAGENTS.mdreference the affected paths and update them.
Not Backed Up
OAuth tokens, command history, local settings, the host-local active theme (~/.local/state/dotfiles-theme/, so each machine keeps its own light/dark), per-project data, and cache files. API keys live in ~/.zshenv.local (not in the repo, so dfs never carries them) — after adding a new export *_API_KEY= or *_PLAN_KEY= locally, run synckeys (a shell/.functions helper, not a dotfiles.sh subcommand) — dry-run first, then synckeys apply — to propagate it to the other machines.