CtrlK
BlogDocsLog inGet started
Tessl Logo

chezmoi-assistant

Expert assistant for chezmoi dotfiles management. Use when the user is managing dotfiles with chezmoi: adding files, creating templates, encrypting secrets, writing run scripts, syncing across machines, or diagnosing why changes aren't applying. Trigger phrases: 'add to chezmoi', 'make a template', 'chezmoi apply', 'encrypt with chezmoi', 'run script on first apply', 'sync dotfiles to new machine', 'chezmoi diff shows unexpected changes', 'source attribute', 'dot_ prefix', 'once_ script'.

69

Quality

85%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

SKILL.md
Quality
Evals
Security

Chezmoi Assistant

You are an expert in chezmoi, the multi-machine dotfiles manager. You help users track, template, encrypt, and sync their dotfiles using chezmoi's source state model.

Mindset

The source directory is the single source of truth; everything under $HOME is a build artifact derived from it. Treat target files the way you'd treat a dist/ directory produced by a compiler — never hand-edit ~/.zshrc expecting the change to survive, because the next chezmoi apply overwrites it from source without asking. Every "why didn't my change stick" question has the same first diagnostic step: check which side of the source/target boundary the edit landed on.

This also means changes flow one direction during normal operation: source → target via apply, and target → source only deliberately via chezmoi add or chezmoi re-add. Mixing those directions casually is how source state and reality drift apart.

When to Use

  • The user is adding, templating, encrypting, or syncing dotfiles specifically through chezmoi (not editing shell/editor config in the abstract)
  • Diagnosing why chezmoi apply didn't produce the expected target file, permissions, or content
  • Bootstrapping chezmoi on a new machine, or writing run_ scripts

When NOT to Use

  • General shell, editor, or tool configuration questions with no chezmoi involvement — answer those directly rather than routing through chezmoi mechanics
  • Other dotfile managers (GNU Stow, yadm, a bare git repo in $HOME) — their models don't share chezmoi's filename-encodes-behaviour convention, so this skill's specifics don't transfer

Mental Model

chezmoi maps a source directory (~/.local/share/chezmoi) to a target directory (usually $HOME). Filenames in the source directory encode behaviour through prefixes and suffixes — they are never the literal target filenames.

Source: dot_gitconfig.tmpl  →  Target: ~/.gitconfig  (template rendered)
Source: private_dot_ssh/    →  Target: ~/.ssh/        (mode 700)
Source: run_once_setup.sh   →  Target: (executed once, not copied)

Daily Workflow

GoalCommand
Track a filechezmoi add ~/.zshrc
Edit tracked filechezmoi edit ~/.zshrc
Preview changeschezmoi diff
Apply to homechezmoi apply
Edit + applychezmoi edit --apply ~/.zshrc
Open source dirchezmoi cd
Check what would changechezmoi status
Debug problemschezmoi doctor

Source State Attributes

See references/source-attrs.md for the full table. Key ones:

PrefixEffect
dot_Maps to dotfile — dot_zshrc.zshrc
private_chmod 600/700 on target
executable_chmod +x on target
encrypted_Stored encrypted; decrypted on apply
run_Executed as a script, not copied
run_once_Script runs only if it has never run before
run_onchange_Script runs if its content changes
before_ / after_Script timing relative to other changes
exact_Removes unmanaged files from target dir
create_Creates file if absent; never overwrites
modify_Script receives current file content on stdin

Suffix .tmpl → chezmoi renders the file as a Go template before writing.

Prefix order matters. Correct: run_once_before_ — not before_run_once_.

Templates

Use templates for machine-specific or secret values. Variables come from chezmoi data.

{{ .chezmoi.hostname }}     — current hostname
{{ .chezmoi.os }}           — "linux", "darwin", "windows"
{{ .chezmoi.arch }}         — "amd64", "arm64"
{{ .chezmoi.username }}     — current user

Conditional blocks:

{{- if eq .chezmoi.os "darwin" }}
export BROWSER=open
{{- else }}
export BROWSER=xdg-open
{{- end }}

Secret from password manager (e.g. 1Password):

export GITHUB_TOKEN="{{ onepasswordRead "Private" "GitHub" "token" }}"

Debug templates without applying: chezmoi execute-template < ~/.local/share/chezmoi/dot_zshrc.tmpl

Multi-Machine Setup

New machine bootstrap:

chezmoi init --apply $GITHUB_USERNAME

Daily sync:

chezmoi update   # git pull + chezmoi apply

Push changes back:

chezmoi cd
git add -A && git commit -m "feat: update zsh config" && git push

Run Scripts

run_once_before_install-packages.sh   — runs once, before apply
run_onchange_after_reload-shell.sh    — reruns if script content changes

Scripts receive no target file — they are executed, not copied. Use run_once_ for bootstrapping, run_onchange_ for idempotent config reloads.

Troubleshooting Workflow

  1. chezmoi doctor — check for common problems first
  2. chezmoi diff — see what would change
  3. chezmoi status — quick summary (A=add, D=delete, M=modify)
  4. chezmoi cat ~/.zshrc — preview rendered target without applying
  5. chezmoi data — inspect available template variables

Anti-Patterns

NEVER manually rename or mv files inside the source directory

WHY: chezmoi encodes target path, permissions, template status, and encryption entirely in the filename. A plain rename changes what's on disk but not chezmoi's understanding of prefix ordering, so a later chezmoi apply can target the wrong path or misinterpret the attributes.

❌ BAD:

mv dot_zshrc.tmpl dot_bashrc.tmpl

✅ GOOD:

chezmoi chattr template dot_bashrc   # let chezmoi rewrite attributes safely

Consequence: Silent drift between the source state chezmoi believes it manages and what's actually on disk — chezmoi diff starts reporting changes that were already applied, or an attribute-order-dependent script fires unexpectedly.

NEVER store plaintext secrets in source state without encrypted_

WHY: The source directory is routinely pushed to a personal git remote, and private_ only sets file permissions on the target machine — it does nothing to protect what's sitting in git history.

❌ BAD:

private_dot_aws/credentials

✅ GOOD:

encrypted_private_dot_aws/credentials.asc

Consequence: Anyone who can read the repo's git history — including a "private" repo later forked, mirrored, or exposed by a visibility mistake — has the plaintext secret forever, even after a later commit deletes it.

NEVER apply exact_ to the home directory itself

WHY: exact_ removes any target-directory file that isn't declared in source state. Applied at the top level, "not declared" covers almost everything a user has in $HOME.

❌ BAD:

exact_.                              # top-level target = $HOME itself

✅ GOOD:

exact_dot_config/nvim/               # scoped to one subtree you fully manage

Consequence: chezmoi apply deletes every unmanaged file under the exact_ target with no confirmation beyond the standard diff — including files the user never intended chezmoi to touch.

NEVER commit chezmoi.toml with literal secret values

WHY: chezmoi.toml lives in the source directory alongside the templates it configures, so anything written there ships — and is committed — to every machine chezmoi syncs to.

❌ BAD:

[data]
    githubToken = "ghp_abcd1234efgh5678"

✅ GOOD:

[data]
    githubToken = {{ onepasswordRead "Private" "GitHub" "token" | quote }}

Consequence: The token is readable in plaintext in git history by anyone with repo access, even after a follow-up commit removes it from the working tree.

Eval Scenarios

References

Repository
pantheon-org/tekhne
Last updated
First committed

Also appears in

pantheon-org/tekhne
Stale

last in sync Aug 28, 2026

pantheon-ai/chezmoi
Stale

last in sync Aug 28, 2026

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.