{"id":"f1cce9e6-ab14-44a6-afbc-35f2cb453915","shortId":"X5zN3F","kind":"skill","title":"chezmoi","tagline":"Manage dotfiles via chezmoi — apply safely, destroy files, manage LaunchAgents and externals, config and template gotchas","description":"`chezmoi apply` may trigger an opencode server restart if plist files change (via `run_onchange_after_ensure-launchagents.sh`). The current session loses its WebSocket connection and appears to hang indefinitely.\n\n**You are running inside that server.** When `chezmoi apply` restarts it, this session will go silent.\n\n## Triggers that cause a restart\n\n| Trigger | What causes it | Effect |\n|---------|---------------|--------|\n| `run_onchange_after_ensure-launchagents.sh` | `Library/LaunchAgents/*.plist.tmpl` content changed | Reloads all managed LaunchAgents, including opencode-web |\n\nSkills, capabilities, and AGENTS.md are read fresh per-session — editing those does **not** trigger a restart. opencode handles config reloads itself.\n\n## Safe Workflow\n\n### Option A — Apply in a PTY, then reconnect (recommended)\n\nRun `chezmoi apply` in a background PTY so you can observe it complete, then reload the browser tab to reconnect to the new server:\n\n```sh\n# 1. Run apply in a PTY session — this avoids blocking the current session\n#    (Use the pty_spawn tool, command=\"chezmoi\", args=[\"apply\"])\n\n# 2. Read PTY output — wait for completion\n\n# 3. Reload the browser tab / reconnect the TUI — the new server is up on port 4096\n```\n\n### Option B — Apply and accept the hang\n\nIf you don't need to observe the output:\n1. Note any in-progress work (the session transcript survives in the DB)\n2. Run `chezmoi apply` directly\n3. The session will go silent — this is expected, not a bug\n4. Reload the browser tab to reconnect\n\n## Diagnosing a Stuck/Hung State\n\nIf apply completed but the session is unresponsive and browser reload doesn't help:\n\n```sh\n# Check if the new server is running\nlaunchctl print gui/$(id -u)/com.athal.opencode-web\n\n# Check the server log for startup errors\ntail -50 ~/Library/Logs/opencode-web.log\ntail -50 ~/Library/Logs/opencode-web.error.log\n```\n\n## Notes\n\n- Session transcript data is persisted in `~/.local/share/opencode/opencode.db` — the session is not lost, just disconnected\n- The LaunchAgent `KeepAlive: true` means the server will always restart; the only failure mode is a crash loop from bad config\n- **Adding a new `[data]` key to `.chezmoi.toml.tmpl` requires `chezmoi init` before `chezmoi apply`** — `apply` alone does not regenerate `~/.config/chezmoi/chezmoi.toml`\n- **`chezmoi init` is destructive to the live config** — it re-renders the template from scratch. The \"config file template has changed\" warning from `chezmoi apply` is cosmetic when scripts are already deployed; do not run `chezmoi init` to silence it.\n- **Machine-specific config lives in `.chezmoidata/local.yaml`** in the source directory — secrets manifest, calendar config, reminders, per-org config. This file is gitignored. Copy `local.yaml.example` from the repo root to `~/.local/share/chezmoi/.chezmoidata/local.yaml` to get started. The example must NOT live under `.chezmoidata/` itself — files there get merged into `chezmoi data` and would leak placeholder values into runtime.\n\n## Gotchas\n\n- **`.chezmoidata` values are plain data** — template expressions like `{{ .chezmoi.arch }}` inside YAML string values are not evaluated. Arch/OS logic must live in the `.tmpl` file itself.\n- **`.app` bundles via `chezmoiexternal`** — use `type = \"archive\"` with target `\"Applications/<AppName>.app\"` (unique TOML key per app) and `stripComponents = 1` to strip the archive's root directory. Without `stripComponents = 1` the app ends up double-nested inside the archive's root directory. TOML does not allow duplicate keys, so each app needs its own unique target path.\n- **LaunchAgent binary path changes** — after moving a binary (e.g., brew → `~/.local/bin`), `launchctl bootout` + `bootstrap` is required to pick up the new plist; `kickstart` alone is not sufficient if the service is crash-looping.\n- **Updating a plist** — `chezmoi apply` only bootstraps agents that aren't loaded. To pick up plist changes on a running agent: `launchctl kickstart -k gui/$(id -u)/<label>`\n- **Deleting a managed file** — `chezmoi apply` does not remove files whose source entry was deleted. Use `chezmoi destroy <target>` *before* removing the source entry — it removes both in one step. **Order matters:** if you `git rm` the source first, `chezmoi destroy` returns `not managed` and you must `rm` the deployed file manually. Note: files managed via `.chezmoiexternal.toml.tmpl` cannot be destroyed this way — chezmoi owns them; remove the external entry instead.\n- **Deleting a skill** — skills in `skills/` are synced to `~/.agents/skills/` by the `run_onchange_after_sync-and-validate-skills` script, which replaces local skills wholesale. Removing a skill from `skills/` is sufficient — no `chezmoi destroy` needed. External skills (in `packages.skills`) must be removed from the list; they will be gone on the next apply.\n- **\"X has changed since chezmoi last wrote it\" prompt** — chezmoi's persistent state SHA for that target drifted from the live file (often after an external tool rewrote it, after a template edit between sessions, or after picking `s`kip in a previous prompt). If `chezmoi diff` is empty after the prompt, the live and rendered content actually match — pick `o`verwrite (or rerun with `--force`) to resync state. Picking `s`kip leaves state stale and the prompt will reappear next apply. Recurring offender: `~/.zshrc`, occasionally rewritten by tool installers (bun, mise) at session startup.","tags":["chezmoi","dotfiles","athal7","agent-skills"],"capabilities":["skill","source-athal7","skill-chezmoi","topic-agent-skills"],"categories":["dotfiles"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/athal7/dotfiles/chezmoi","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add athal7/dotfiles","source_repo":"https://github.com/athal7/dotfiles","install_from":"skills.sh"}},"qualityScore":"0.453","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 6 github stars · SKILL.md body (5,425 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:14:34.099Z","embedding":null,"createdAt":"2026-05-18T13:22:28.603Z","updatedAt":"2026-05-18T19:14:34.099Z","lastSeenAt":"2026-05-18T19:14:34.099Z","tsv":"'-50':280,283 '/.agents/skills':660 '/.config/chezmoi/chezmoi.toml':339 '/.local/bin':531 '/.local/share/chezmoi/.chezmoidata/local.yaml':412 '/.local/share/opencode/opencode.db':292 '/.zshrc':790 '/com.athal.opencode-web':271 '/library/logs/opencode-web.error.log':284 '/library/logs/opencode-web.log':281 '1':141,202,482,492 '2':163,216 '3':170,221 '4':233 '4096':185 'accept':190 'actual':763 'ad':321 'agent':562,575 'agents.md':86 'allow':509 'alon':335,544 'alreadi':371 'alway':308 'app':464,474,479,494,514 'appear':40 'appli':6,19,52,109,118,143,162,188,219,245,333,334,365,559,587,705,787 'applic':473 'arch/os':455 'archiv':470,486,502 'aren':564 'arg':161 'avoid':149 'b':187 'background':121 'bad':319 'binari':522,528 'block':150 'bootout':533 'bootstrap':534,561 'brew':530 'browser':132,173,236,253 'bug':232 'bun':796 'bundl':465 'calendar':394 'cannot':638 'capabl':84 'caus':62,67 'chang':29,74,361,524,571,708 'check':259,272 'chezmoi':1,5,18,51,117,160,218,329,332,340,364,376,429,558,586,598,620,643,685,710,715,751 'chezmoi.arch':447 'chezmoi.toml.tmpl':327 'chezmoidata':422,439 'chezmoidata/local.yaml':387 'chezmoiextern':467 'chezmoiexternal.toml.tmpl':637 'command':159 'complet':128,169,246 'config':14,102,320,347,357,384,395,400 'connect':38 'content':73,762 'copi':405 'cosmet':367 'crash':316,553 'crash-loop':552 'current':33,152 'data':288,324,430,443 'db':215 'delet':582,596,651 'deploy':372,630 'destroy':8,599,621,640,686 'destruct':343 'diagnos':240 'diff':752 'direct':220 'directori':391,489,505 'disconnect':299 'doesn':255 'dotfil':3 'doubl':498 'double-nest':497 'drift':723 'duplic':510 'e.g':529 'edit':93,738 'effect':69 'empti':754 'end':495 'entri':594,604,649 'error':278 'evalu':454 'exampl':417 'expect':229 'express':445 'extern':13,648,688,731 'failur':312 'file':9,28,358,402,424,462,585,591,631,634,727 'first':619 'forc':771 'fresh':89 'get':414,426 'git':615 'gitignor':404 'go':58,225 'gone':701 'gotcha':17,438 'gui':268,579 'handl':101 'hang':42,192 'help':257 'id':269,580 'in-progress':205 'includ':79 'indefinit':43 'init':330,341,377 'insid':47,448,500 'instal':795 'instead':650 'k':578 'keepal':302 'key':325,477,511 'kickstart':543,577 'kip':745,777 'last':711 'launchag':11,78,301,521 'launchctl':266,532,576 'leak':433 'leav':778 'library/launchagents':71 'like':446 'list':697 'live':346,385,420,458,726,759 'load':566 'local':674 'local.yaml.example':406 'log':275 'logic':456 'loop':317,554 'lose':35 'lost':297 'machin':382 'machine-specif':381 'manag':2,10,77,584,624,635 'manifest':393 'manual':632 'match':764 'matter':612 'may':20 'mean':304 'merg':427 'mise':797 'mode':313 'move':526 'must':418,457,627,692 'need':197,515,687 'nest':499 'new':138,179,262,323,541 'next':704,786 'note':203,285,633 'o':766 'observ':126,199 'occasion':791 'offend':789 'often':728 'onchang':664 'one':609 'opencod':23,81,100 'opencode-web':80 'option':107,186 'order':611 'org':399 'output':166,201 'own':644 'packages.skills':691 'path':520,523 'per':91,398,478 'per-org':397 'per-sess':90 'persist':290,717 'pick':538,568,743,765,775 'placehold':434 'plain':442 'plist':27,542,557,570 'plist.tmpl':72 'port':184 'previous':748 'print':267 'progress':207 'prompt':714,749,757,783 'pti':112,122,146,156,165 're':350 're-rend':349 'read':88,164 'reappear':785 'recommend':115 'reconnect':114,135,175,239 'recur':788 'regener':338 'reload':75,103,130,171,234,254 'remind':396 'remov':590,601,606,646,677,694 'render':351,761 'replac':673 'repo':409 'requir':328,536 'rerun':769 'restart':25,53,64,99,309 'resync':773 'return':622 'rewritten':792 'rewrot':733 'rm':616,628 'root':410,488,504 'run':46,116,142,217,265,375,574,663 'run_onchange_after_ensure-launchagents.sh':31,70 'runtim':437 'safe':7,105 'scratch':355 'script':369,671 'secret':392 'server':24,49,139,180,263,274,306 'servic':550 'session':34,56,92,147,153,210,223,249,286,294,740,799 'sh':140,258 'sha':719 'silenc':379 'silent':59,226 'sinc':709 'skill':83,653,654,656,670,675,679,681,689 'skill-chezmoi' 'sourc':390,593,603,618 'source-athal7' 'spawn':157 'specif':383 'stale':780 'start':415 'startup':277,800 'state':243,718,774,779 'step':610 'string':450 'strip':484 'stripcompon':481,491 'stuck/hung':242 'suffici':547,683 'surviv':212 'sync':658,667 'sync-and-validate-skil':666 'tab':133,174,237 'tail':279,282 'target':472,519,722 'templat':16,353,359,444,737 'tmpl':461 'toml':476,506 'tool':158,732,794 'topic-agent-skills' 'transcript':211,287 'trigger':21,60,65,97 'true':303 'tui':177 'type':469 'u':270,581 'uniqu':475,518 'unrespons':251 'updat':555 'use':154,468,597 'valid':669 'valu':435,440,451 'verwrit':767 'via':4,30,466,636 'wait':167 'warn':362 'way':642 'web':82 'websocket':37 'wholesal':676 'whose':592 'without':490 'work':208 'workflow':106 'would':432 'wrote':712 'x':706 'yaml':449","prices":[{"id":"1ea52151-3fb6-4dda-b782-0bb1d2a3d9a2","listingId":"f1cce9e6-ab14-44a6-afbc-35f2cb453915","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"athal7","category":"dotfiles","install_from":"skills.sh"},"createdAt":"2026-05-18T13:22:28.603Z"}],"sources":[{"listingId":"f1cce9e6-ab14-44a6-afbc-35f2cb453915","source":"github","sourceId":"athal7/dotfiles/chezmoi","sourceUrl":"https://github.com/athal7/dotfiles/tree/main/skills/chezmoi","isPrimary":false,"firstSeenAt":"2026-05-18T13:22:28.603Z","lastSeenAt":"2026-05-18T19:14:34.099Z"}],"details":{"listingId":"f1cce9e6-ab14-44a6-afbc-35f2cb453915","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"athal7","slug":"chezmoi","github":{"repo":"athal7/dotfiles","stars":6,"topics":["agent-skills"],"license":null,"html_url":"https://github.com/athal7/dotfiles","pushed_at":"2026-05-18T18:53:57Z","description":null,"skill_md_sha":"b34c8e7e822fc1602ad968337723387c90fdf476","skill_md_path":"skills/chezmoi/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/athal7/dotfiles/tree/main/skills/chezmoi"},"layout":"multi","source":"github","category":"dotfiles","frontmatter":{"name":"chezmoi","license":"MIT","description":"Manage dotfiles via chezmoi — apply safely, destroy files, manage LaunchAgents and externals, config and template gotchas","compatibility":"opencode"},"skills_sh_url":"https://skills.sh/athal7/dotfiles/chezmoi"},"updatedAt":"2026-05-18T19:14:34.099Z"}}