Create New Chezmoi Script
Create a new script in home/.chezmoiscripts/ following all project conventions.
Arguments
Parse from $ARGUMENTS:
- •description (required): Kebab-case description (e.g., "install-docker", "setup-github-auth")
- •--frequency:
run_once(default) orrun_onchange - •--timing:
before(default) orafter - •--order: Two-digit number (suggest one if not provided)
Naming Convention
code
{frequency}_{timing}_darwin-{order}-{description}.sh.tmpl
Order Categories
- •00-09: System Foundation (Rosetta 2)
- •10-19: Development Toolchains (Rust, Java/JVM)
- •20-29: Package Management (SDKMAN, Homebrew, SDKs, UV tools)
- •30-39: Environment Managers (uv, nvm, Claude Code)
- •40-49: Environment Setup (GitHub auth, shell plugins)
- •80-89: System Configuration (security, VPN, Defender, GlobalProtect)
- •90-99: Validation & Maintenance (hosts, syncthing, SSH test, system defaults)
If --order is not provided, suggest an appropriate number based on the description and these existing scripts:
!ls home/.chezmoiscripts/
Required Boilerplate
Every script MUST use this structure:
bash
{{- if eq .chezmoi.os "darwin" -}}
#!/bin/bash
source "{{ .chezmoi.sourceDir -}}/scripts/shared-utils.sh"
# Script logic here
{{ end -}}
Conventions
- •Use
print_message "level" "message"for ALL output (info, success, warning, error, skip, tip) - •Use
command_exists "cmd"to check command availability - •Use
require_tools "tool1" "tool2"to validate dependencies at the start - •Use
lookPathin template conditionals (NEVERoutput "command" "-v") - •Handle already-installed/configured cases with
print_message "skip" - •Include proper error handling with meaningful messages
Steps
- •Parse arguments or ask for missing info (description, frequency, timing, order)
- •Verify the order number doesn't conflict with existing scripts
- •Generate the filename following the naming convention
- •Create the script with all required boilerplate
- •Implement the script logic based on the description
- •Validate the template:
chezmoi execute-template < <file>