Use this skill when managing packages, external dependencies, binaries, or CLI tools in a chezmoi dotfiles repository. Handles adding/updating/removing packages in .chezmoidata/packages.yaml, creating .chezmoiexternals/ organized files, pinning versions with Renovate automation, and selecting the correct package ecosystem (Homebrew, mise, Python, Docker, chezmoi externals).
68
83%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
This skill handles all aspects of package and dependency management in chezmoi dotfiles repositories, with emphasis on security, reproducibility, and automated updates.
.chezmoiexternals/ directoryInvoke this skill when the user requests:
Determine what the user wants:
.chezmoiexternals/ structureChoose the appropriate package manager (see ./ecosystem-guide.md for details):
| Use Case | Ecosystem | Location |
|---|---|---|
| macOS packages (Homebrew) | brew/cask/mas | home/.chezmoidata/packages.yaml |
| CLI developer tools | mise (Aqua) | .mise.toml or home/dot_config/mise/config.toml |
| Python tools | pip | home/dot_config/dotfiles/requirements.txt |
| Docker/devcontainer | docker | home/dot_config/docker-compose/*.yml, .devcontainer/ |
| External files/repos | chezmoi externals | home/.chezmoiexternals/*.toml[.tmpl] |
| Install script CLIs | cli-versions | home/dot_config/dotfiles/cli-versions.toml |
IMPORTANT: Organize externals by primary program using the .chezmoiexternals/ directory structure.
home/.chezmoiexternals/
├── zsh.externals.toml # Zsh plugins and tools
├── bat.externals.toml # Bat themes and syntaxes
├── tmux.externals.toml # Tmux configurations
└── nvim.externals.toml # Neovim pluginshome/.chezmoiexternals/ are treated as .chezmoiexternal.<format> files.tmpl suffix for templating support (OS conditionals, variables){{ if lookPath "zsh" }}
# Zsh plugins and tools
[".zsh/znap/zsh-snap"]
type = "git-repo"
url = "https://github.com/marlonrichert/zsh-snap.git"
revision = "25754a45d9ceafe6d7d082c9ebe40a08cb85a4f0"
refreshPeriod = "168h"
[".zsh/plugins/zsh-autosuggestions"]
{{ end }}type = "git-repo"
url = "https://github.com/zsh-users/zsh-autosuggestions.git"
revision = "85919cd1ffa7d2d5412f6d3fe437ebdbeeec4fc5"
refreshPeriod = "168h"Chezmoi supports four external types (detailed in ./externals-reference.md):
For complete Git repositories (plugins, frameworks):
[".zsh/plugins/plugin-name"]
type = "git-repo"
url = "https://github.com/user/repo.git"
revision = "<commit-sha>" # MUST pin to SHA
refreshPeriod = "168h"For single files (themes, configs):
[".config/tool/theme.tmTheme"]
type = "file"
url = "https://github.com/user/repo/raw/<commit-sha>/file.ext"
refreshPeriod = "168h"For extracting single binary from release archive:
[".local/bin/tool"]
type = "archive-file"
url = "https://github.com/user/repo/releases/download/v1.2.3/tool.tar.gz"
executable = true
path = "tool"
checksum = "sha256:abc123..."For extracting entire archive into directory:
[".config/tool"]
type = "archive"
url = "https://github.com/user/repo/archive/<commit-sha>.tar.gz"
exact = true
stripComponents = 1
refreshPeriod = "168h"CRITICAL: Always use immutable references:
| Type | Pinning Method | Example |
|---|---|---|
| Git repo | Commit SHA in revision | revision = "abc123..." |
| GitHub file | Commit SHA in URL path | raw/<sha>/file.ext |
| Release binary | Version tag + checksum | v1.2.3 + checksum = "sha256:..." |
| Docker image | Digest | image:tag@sha256:... |
NEVER use:
latest tagsFor each external dependency, verify or add corresponding Renovate rule in renovate.json5.
See ./renovate-integration.md for detailed patterns.
Quick reference:
{
customType: 'regex',
fileMatch: ['^home/\\.chezmoiexternals/.*\\.toml(\\.tmpl)?$'],
matchStrings: [
'revision = "(?<currentDigest>[a-f0-9]{40})".*?# renovate: repo=(?<depName>.*?) branch=(?<currentValue>.*?)\\n',
],
datasourceTemplate: 'git-refs',
}.externals.toml file# renovate: repo=user/repo branch=main
[".path/to/dependency"]
type = "git-repo"
url = "https://github.com/user/repo.git"
revision = "<commit-sha>"home/.chezmoidata/packages.yamlPreview changes:
chezmoi diffCheck external URLs:
# Verify latest commit SHA
gh api repos/USER/REPO/commits/BRANCH --jq .sha
# Check latest release tag
gh api repos/USER/REPO/releases/latest --jq .tag_name
# Verify file exists at SHA
curl -fsSL https://github.com/USER/REPO/raw/SHA/path/to/fileApply changes:
chezmoi applyTest external updates:
chezmoi update --force# 1. Get latest commit SHA
gh api repos/zsh-users/zsh-history-substring-search/commits/master --jq .sha
# 2. Add to home/.chezmoiexternals/zsh.externals.toml
# 3. Add Renovate rule to renovate.json5
# 4. Preview and apply
chezmoi diff
chezmoi apply# 1. Edit home/.chezmoidata/packages.yaml
# 2. Add to appropriate section (brews/casks)
# 3. Renovate will track automatically (homebrew datasource)home/.chezmoiexternal.tomlgrep -r "\.chezmoiexternal\.toml\.tmpl" home/{{ include ".chezmoiexternal.toml" }} for hashinghome/.chezmoiexternals/.chezmoiexternals/bat.externals.toml){{ if lookPath "zsh" }})chezmoi diff (will error if references are broken)chezmoi diff succeeds# 1. Fetch current SHA
gh api repos/USER/REPO/commits/BRANCH --jq .sha
# 2. Update revision in .chezmoiexternals/*.toml
# 3. Apply
chezmoi applyWhen making changes, provide:
Decision:
- Ecosystem: <brew|mise|python|docker|chezmoi-external|cli-versions>
- Rationale: <1-2 sentences>
- Organization: <which .chezmoiexternals/ file or other manifest>
Files To Edit:
- <path1>
- <path2>
Proposed Changes:
<concise diff-like hunks showing additions/modifications>
Renovate Integration:
- Rule Status: <exists|needs-addition|needs-update>
- Pattern: <brief description of regex or datasource>
Verification Commands:
- chezmoi diff
- <optional gh api commands to verify versions>
Next Steps:
- [ ] Review proposed changes
- [ ] Preview with chezmoi diff
- [ ] Apply with chezmoi applychezmoi diff before applyingUse Go templates for platform-specific externals:
{{ if eq .chezmoi.os "darwin" }}
[".local/bin/tool-mac"]
{{ else if eq .chezmoi.os "linux" }}
type = "archive-file"
url = "https://github.com/user/tool/releases/download/v1.0.0/tool-darwin-{{ .chezmoi.arch }}.tar.gz"
executable = true
[".local/bin/tool-linux"]
{{ end }}type = "archive-file"
url = "https://github.com/user/tool/releases/download/v1.0.0/tool-linux-{{ .chezmoi.arch }}.tar.gz"
executable = trueExternal fails to download:
curl -fsSL <url>gh api repos/USER/REPO/commits/SHAchezmoi apply -vRenovate not detecting dependency:
Checksum mismatch:
curl -fsSL <url> | shasum -a 256.chezmoiexternals/PROGRAM.externals.toml# renovate: comments{{ if }} for conditional installsNEVER use mutable references (latest, branch names, version ranges) in externals. WHY: Mutable refs make reproductions non-deterministic — the same chezmoi apply produces different results on different days, breaking machine parity.
NEVER execute package managers (brew install, mise use, chezmoi apply) without explicit user permission. WHY: Package installs modify system state; the agent's role is to propose changes, not apply them unilaterally.
NEVER create a new .chezmoiexternal.toml at the repo root when .chezmoiexternals/ already exists. WHY: Mixing the legacy single-file format with the directory-based format confuses chezmoi and leads to duplicate or shadowed external definitions.
NEVER add a new external ecosystem when an existing one already covers the use case. WHY: Every additional ecosystem (Homebrew + mise + pip + externals + cli-versions) multiplies maintenance burden; always consult ./references/ecosystem-guide.md before introducing a new one.
NEVER omit a Renovate rule when adding a pinned external. WHY: A pinned dependency with no automation becomes stale immediately — security vulnerabilities and breaking changes accumulate silently until someone notices.
NEVER skip chezmoi diff before proposing chezmoi apply. WHY: Externals can overwrite local modifications; showing the diff first lets the user confirm no unexpected files will be changed.
references/externals-reference.md — Complete external type specificationsreferences/renovate-integration.md — Renovate automation patternsreferences/ecosystem-guide.md — Package manager selection guidea1083f4
Also appears in
since Apr 24, 2026
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.