@sebastienrousseau/dotfiles 0.2.481 → 0.2.500

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (546) hide show
  1. package/CHANGELOG.md +122 -32
  2. package/LICENSE +1 -1
  3. package/README.md +211 -242
  4. package/docs/.vitepress/reports/localization-readability-audit.md +69 -0
  5. package/docs/AI.md +102 -0
  6. package/docs/COPYRIGHT +2 -2
  7. package/docs/NAMING_CONVENTIONS.md +95 -0
  8. package/docs/README.md +58 -249
  9. package/docs/adr/ADR-004-cli-architecture.md +2 -2
  10. package/docs/adr/ADR-006-shell-selection.md +2 -2
  11. package/docs/adr/ADR-007-multi-shell-parity.md +53 -0
  12. package/docs/adr/ADR-008-alias-system-architecture.md +85 -0
  13. package/docs/adr/README.md +2 -3
  14. package/docs/architecture/ARCHITECTURE.md +113 -0
  15. package/docs/architecture/INTEROP.md +36 -0
  16. package/docs/architecture/REPO_LAYOUT.md +237 -0
  17. package/docs/architecture/WALKTHROUGH.md +82 -0
  18. package/docs/architecture/fleet-deployment.md +73 -0
  19. package/docs/archive/EUXIS_2026_REVIEW.md +119 -0
  20. package/docs/archive/MILESTONE_v0.2.493.md +43 -0
  21. package/docs/{PLAN.md → archive/PLAN.md} +1 -1
  22. package/docs/guides/INSTALL.md +140 -0
  23. package/docs/{NEOVIM_IDE_GUIDE.md → guides/NEOVIM_IDE_GUIDE.md} +12 -12
  24. package/docs/guides/THEMING.md +222 -0
  25. package/docs/{TROUBLESHOOTING.md → guides/TROUBLESHOOTING.md} +36 -0
  26. package/docs/{WSL2_NIX_TROUBLESHOOTING.md → guides/WSL2_NIX_TROUBLESHOOTING.md} +8 -8
  27. package/docs/index.md +39 -0
  28. package/docs/interop/A2A.md +32 -0
  29. package/docs/manual/00-introduction.md +85 -0
  30. package/docs/manual/01-concepts/01-architecture.md +134 -0
  31. package/docs/manual/01-concepts/02-trust-model.md +178 -0
  32. package/docs/manual/01-concepts/03-theme-engine.md +182 -0
  33. package/docs/manual/01-concepts/04-fleet.md +142 -0
  34. package/docs/manual/01-concepts/05-self-healing.md +197 -0
  35. package/docs/manual/02-tutorials/01-first-install.md +192 -0
  36. package/docs/manual/02-tutorials/02-add-wallpaper.md +211 -0
  37. package/docs/manual/02-tutorials/03-create-profile.md +238 -0
  38. package/docs/manual/02-tutorials/04-encrypt-secret.md +275 -0
  39. package/docs/manual/02-tutorials/05-deploy-fleet.md +279 -0
  40. package/docs/manual/03-reference/01-dot-cli.md +413 -0
  41. package/docs/manual/03-reference/02-config-files.md +259 -0
  42. package/docs/manual/03-reference/03-environment.md +120 -0
  43. package/docs/manual/03-reference/04-templates.md +184 -0
  44. package/docs/manual/03-reference/05-feature-flags.md +118 -0
  45. package/docs/manual/04-cookbook/01-recipes.md +281 -0
  46. package/docs/manual/04-cookbook/02-troubleshooting.md +319 -0
  47. package/docs/manual/04-cookbook/03-faq.md +167 -0
  48. package/docs/manual/05-appendices/A-platform-matrix.md +97 -0
  49. package/docs/manual/05-appendices/B-security-checklist.md +78 -0
  50. package/docs/manual/05-appendices/C-glossary.md +36 -0
  51. package/docs/manual/05-appendices/D-bibliography.md +54 -0
  52. package/docs/manual/05-appendices/E-license.md +34 -0
  53. package/docs/manual/_toc.yml +58 -0
  54. package/docs/manual/command-index.md +58 -0
  55. package/docs/manual/concept-index.md +164 -0
  56. package/docs/operations/ATTESTATION.md +39 -0
  57. package/docs/operations/MAINTENANCE.md +59 -0
  58. package/docs/operations/MIGRATION.md +101 -0
  59. package/docs/operations/OPERATIONS.md +164 -0
  60. package/docs/operations/RELIABILITY.md +116 -0
  61. package/docs/{ROADMAP.md → operations/ROADMAP.md} +11 -11
  62. package/docs/operations/TESTING.md +195 -0
  63. package/docs/operations/TRACEABILITY.md +31 -0
  64. package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +61 -0
  65. package/docs/operations/VERSION_SYNC.md +344 -0
  66. package/docs/{ALIASES.md → reference/ALIASES.md} +2 -6
  67. package/docs/reference/ALIASES_CHEATSHEET.md +28 -0
  68. package/docs/reference/ALIASES_DEPRECATIONS.md +9 -0
  69. package/docs/reference/FEATURES.md +62 -0
  70. package/docs/reference/FONTS.md +108 -0
  71. package/docs/reference/PROFILES.md +65 -0
  72. package/docs/{SCREENSHOTS.md → reference/SCREENSHOTS.md} +26 -25
  73. package/docs/reference/SCRIPTS.md +67 -0
  74. package/docs/reference/SUPPORT_MATRIX.md +74 -0
  75. package/docs/reference/THEMES.md +113 -0
  76. package/docs/reference/TOOLS.md +105 -0
  77. package/docs/reference/UTILS.md +151 -0
  78. package/docs/security/AI_ACT_COMPLIANCE.md +90 -0
  79. package/docs/security/AUTOMATION_SECRETS.md +22 -0
  80. package/docs/security/COMPLIANCE.md +453 -0
  81. package/docs/security/ENCRYPTION.md +52 -0
  82. package/docs/security/FMEA.md +155 -0
  83. package/docs/security/INCIDENT_RESPONSE.md +575 -0
  84. package/docs/security/KEYS.md +45 -0
  85. package/docs/security/MCP_POLICY.md +69 -0
  86. package/docs/security/POLICY_RELEASES.md +33 -0
  87. package/docs/security/README.md +24 -0
  88. package/docs/security/SECRETS.md +146 -0
  89. package/docs/security/SECURITY.md +41 -0
  90. package/docs/security/SECURITY_CHECKLIST.md +44 -0
  91. package/docs/security/SOUP_REGISTER.md +32 -0
  92. package/docs/security/THREAT_MODEL.md +120 -0
  93. package/docs/security/VERIFICATION_VALIDATION.md +224 -0
  94. package/docs/themes/README.md +3 -17
  95. package/docs/themes/VISUAL_INTEGRITY_REPORT.md +26 -0
  96. package/docs/themes/hero-shot.svg +78 -0
  97. package/dot_config/.module-manifest.json +69 -0
  98. package/dot_config/ai/identity.md +20 -0
  99. package/dot_config/ai/patterns/architect.md +14 -0
  100. package/dot_config/ai/patterns/hardener.md +13 -0
  101. package/dot_config/ai/patterns/refactor.md +13 -0
  102. package/dot_config/aider/aider.conf.yml +1 -1
  103. package/dot_config/alacritty/alacritty.toml.tmpl +41 -469
  104. package/dot_config/atuin/config.toml +18 -1
  105. package/dot_config/bat/config +16 -1
  106. package/dot_config/claude/mcp_servers.json +3 -32
  107. package/dot_config/dotfiles/agent-card.json +29 -0
  108. package/dot_config/dotfiles/agent-profiles.json +92 -0
  109. package/dot_config/dotfiles/boot/README.md +1 -1
  110. package/dot_config/dotfiles/grub/README.md +1 -1
  111. package/dot_config/dotfiles/lock/README.md +1 -1
  112. package/dot_config/dotfiles/mcp-lock.json +33 -0
  113. package/dot_config/dotfiles/mcp-policy.json +52 -0
  114. package/dot_config/dotfiles/mcp-registry.json +47 -0
  115. package/dot_config/dotfiles/model-registry.json +20 -0
  116. package/dot_config/dotfiles/policy-bundles.json +38 -0
  117. package/dot_config/dotfiles/prompt-registry.json +16 -0
  118. package/dot_config/dotfiles/versions.env +18 -0
  119. package/dot_config/environment.d/50-ssh-agent.conf +2 -0
  120. package/dot_config/environment.d/90-wayland.conf +19 -0
  121. package/dot_config/firefox/user.js.tmpl +58 -0
  122. package/dot_config/fish/completions/dot-theme-sync.fish.tmpl +9 -0
  123. package/dot_config/fish/completions/dot.fish.tmpl +115 -0
  124. package/dot_config/fish/conf.d/000-perf-cache.fish +56 -0
  125. package/dot_config/fish/conf.d/aliases.fish.tmpl +77 -0
  126. package/dot_config/fish/conf.d/env.fish.tmpl +48 -0
  127. package/dot_config/fish/conf.d/functions.fish.tmpl +22 -0
  128. package/dot_config/fish/conf.d/init.fish.tmpl +151 -0
  129. package/dot_config/fish/config.fish.tmpl +44 -0
  130. package/dot_config/fish/fish_plugins +1 -0
  131. package/dot_config/fish/functions/_.fish +3 -0
  132. package/dot_config/fish/functions/_cached_eval.fish +58 -0
  133. package/dot_config/fish/functions/als.fish +46 -0
  134. package/dot_config/fish/functions/bg-upgrade.fish +7 -0
  135. package/dot_config/fish/functions/c.fish +3 -0
  136. package/dot_config/fish/functions/cat.fish +9 -0
  137. package/dot_config/fish/functions/d.fish +7 -0
  138. package/dot_config/fish/functions/dot.fish +34 -0
  139. package/dot_config/fish/functions/h.fish +3 -0
  140. package/dot_config/fish/functions/l.fish +7 -0
  141. package/dot_config/fish/functions/la.fish +7 -0
  142. package/dot_config/fish/functions/ll.fish +7 -0
  143. package/dot_config/fish/functions/log_error.fish +13 -0
  144. package/dot_config/fish/functions/log_info.fish +13 -0
  145. package/dot_config/fish/functions/lr.fish +7 -0
  146. package/dot_config/fish/functions/lra.fish +7 -0
  147. package/dot_config/fish/functions/ls.fish +7 -0
  148. package/dot_config/fish/functions/lt.fish +7 -0
  149. package/dot_config/fish/functions/lta.fish +7 -0
  150. package/dot_config/fish/functions/notify-run.fish +11 -0
  151. package/dot_config/fish/functions/q.fish +3 -0
  152. package/dot_config/fish/functions/silent-run.fish +7 -0
  153. package/dot_config/fish/functions/yy.fish +8 -0
  154. package/dot_config/fontconfig/fonts.conf.tmpl +13 -0
  155. package/dot_config/foot/foot.ini.tmpl +33 -0
  156. package/dot_config/fuzzel/fuzzel.ini.tmpl +18 -0
  157. package/dot_config/fzf/fzf.zsh +48 -0
  158. package/dot_config/ghostty/config.tmpl +69 -565
  159. package/dot_config/git/allowed_signers.tmpl +18 -0
  160. package/dot_config/git/commit-template +10 -0
  161. package/dot_config/gnupg/{gpg-agent.conf.tmpl → gpg-agent.conf} +3 -3
  162. package/dot_config/goose/config.yaml +2 -2
  163. package/dot_config/gtk-3.0/gtk.css.tmpl +59 -180
  164. package/dot_config/gtk-3.0/settings.ini.tmpl +5 -44
  165. package/dot_config/gtk-4.0/gtk.css.tmpl +79 -136
  166. package/dot_config/gtk-4.0/settings.ini.tmpl +5 -8
  167. package/dot_config/ipython/profile_default/ipython_config.py +19 -0
  168. package/dot_config/just/justfile +18 -0
  169. package/dot_config/kanshi/config.tmpl +22 -0
  170. package/dot_config/kitty/kitty.conf.tmpl +44 -508
  171. package/dot_config/lazygit/config.yml +18 -6
  172. package/dot_config/mako/config +47 -0
  173. package/dot_config/micro/settings.json +3 -0
  174. package/dot_config/mimeapps.list +77 -0
  175. package/dot_config/mise/config.toml +63 -5
  176. package/dot_config/mongosh/mongoshrc.js +1 -0
  177. package/dot_config/mpv/input.conf +47 -0
  178. package/dot_config/mpv/mpv.conf +47 -0
  179. package/dot_config/niri/config.kdl.tmpl +327 -0
  180. package/dot_config/nushell/aliases.nu +18 -0
  181. package/dot_config/nushell/completions.nu.tmpl +52 -0
  182. package/dot_config/nushell/config.nu.tmpl +86 -0
  183. package/dot_config/nushell/env.nu.tmpl +94 -0
  184. package/dot_config/nushell/functions.nu.tmpl +17 -0
  185. package/dot_config/nvim/init.lua +14 -0
  186. package/dot_config/nvim/lazy-lock.json +45 -14
  187. package/dot_config/nvim/lua/config/autocmds.lua +45 -1
  188. package/dot_config/nvim/lua/config/keymaps.lua +13 -8
  189. package/dot_config/nvim/lua/config/lazy.lua +22 -12
  190. package/dot_config/nvim/lua/config/options.lua +1 -0
  191. package/dot_config/nvim/lua/plugins/ai.lua +75 -0
  192. package/dot_config/nvim/lua/plugins/coding.lua +11 -29
  193. package/dot_config/nvim/lua/plugins/completion.lua +60 -0
  194. package/dot_config/nvim/lua/plugins/dap.lua +215 -4
  195. package/dot_config/nvim/lua/plugins/editor.lua +6 -10
  196. package/dot_config/nvim/lua/plugins/git.lua +1 -0
  197. package/dot_config/nvim/lua/plugins/lsp.lua +16 -81
  198. package/dot_config/nvim/lua/plugins/markdown.lua +1 -0
  199. package/dot_config/nvim/lua/plugins/rust.lua +1 -0
  200. package/dot_config/nvim/lua/plugins/sessions.lua +1 -0
  201. package/dot_config/nvim/lua/plugins/ui.lua +23 -51
  202. package/dot_config/paru/paru.conf +10 -0
  203. package/dot_config/powershell/Microsoft.PowerShell_profile.ps1.tmpl +81 -0
  204. package/dot_config/pueue/pueue.yml +34 -0
  205. package/dot_config/raycast/README.md +1 -1
  206. package/dot_config/ripgrep/ripgreprc +21 -0
  207. package/dot_config/shell/00-core-paths.sh.tmpl +62 -24
  208. package/dot_config/shell/05-core-safety.sh +47 -0
  209. package/dot_config/shell/10-secrets.sh +40 -0
  210. package/dot_config/shell/40-fzf-defaults.sh.tmpl +16 -0
  211. package/dot_config/shell/40-ls-colors.sh +48 -0
  212. package/dot_config/shell/50-logic-functions-core.sh.tmpl +10 -0
  213. package/dot_config/shell/51-logic-functions-extra.sh.tmpl +64 -0
  214. package/dot_config/shell/90-ux-aliases.sh.tmpl +90 -5
  215. package/dot_config/shell/91-ux-aliases-lazy.sh.tmpl +33 -2
  216. package/dot_config/shell/Brewfile.cli +8 -0
  217. package/dot_config/shell/README.md +9 -9
  218. package/dot_config/shell/als_data.txt.tmpl +65 -0
  219. package/dot_config/shell/custom/auto_ls.zsh +20 -0
  220. package/dot_config/shell/custom/context_suggest.zsh +50 -50
  221. package/dot_config/shell/custom/error_analysis.zsh +29 -29
  222. package/dot_config/starship.toml.tmpl +85 -7
  223. package/dot_config/swaylock/config +43 -0
  224. package/dot_config/systemd/user/dotfiles-maintenance.service +8 -0
  225. package/dot_config/systemd/user/dotfiles-maintenance.timer +11 -0
  226. package/dot_config/systemd/user/pueued.service +12 -0
  227. package/dot_config/systemd/user/ssh-agent.service +12 -0
  228. package/dot_config/tmux/tmux.conf.tmpl +80 -38
  229. package/dot_config/topgrade.toml.tmpl +54 -0
  230. package/dot_config/user-dirs.dirs +9 -0
  231. package/dot_config/vscode/settings.json.tmpl +9 -50
  232. package/dot_config/waybar/config.jsonc.tmpl +90 -0
  233. package/dot_config/waybar/style.css.tmpl +211 -0
  234. package/dot_config/wezterm/wezterm.lua.tmpl +31 -203
  235. package/dot_config/xdg-desktop-portal/niri-portals.conf +5 -0
  236. package/dot_config/yazi/keymap.toml +67 -0
  237. package/dot_config/yazi/theme.toml +102 -0
  238. package/dot_config/zathura/zathurarc +52 -0
  239. package/dot_config/zellij/{config.kdl → config.kdl.tmpl} +1 -1
  240. package/dot_config/zsh/dot_zprofile +1 -7
  241. package/dot_config/zsh/dot_zshenv +2 -3
  242. package/dot_config/zsh/dot_zshrc.tmpl +368 -69
  243. package/dot_config/zsh/rc.d/00-alias-shims.zsh +77 -0
  244. package/dot_config/zsh/rc.d/05-ssh-agent.zsh +17 -4
  245. package/dot_config/zsh/rc.d/10-env.zsh.tmpl +4 -4
  246. package/dot_config/zsh/rc.d/20-zinit.zsh +65 -0
  247. package/dot_config/zsh/rc.d/30-options.zsh.tmpl +101 -30
  248. package/dot_config/zsh/rc.d/99-alias-wrapper.zsh +32 -0
  249. package/dot_local/bin/__pycache__/executable_dot-load-benchmark-ptycpython-312.pyc +0 -0
  250. package/dot_local/bin/executable_ai-update +195 -0
  251. package/dot_local/bin/executable_ai_core +113 -91
  252. package/dot_local/bin/executable_antigravity +11 -0
  253. package/dot_local/bin/executable_b64 +61 -36
  254. package/dot_local/bin/executable_bm +77 -0
  255. package/dot_local/bin/executable_cb +39 -0
  256. package/dot_local/bin/executable_dot +543 -132
  257. package/dot_local/bin/executable_dot-ai +36 -0
  258. package/dot_local/bin/executable_dot-bootstrap +77 -0
  259. package/dot_local/bin/executable_dot-launch-or-focus +52 -0
  260. package/dot_local/bin/executable_dot-load-benchmark +31 -0
  261. package/dot_local/bin/executable_dot-load-benchmark-pty +77 -0
  262. package/dot_local/bin/executable_dot-theme-sync +952 -0
  263. package/dot_local/bin/executable_dot_completion +2 -0
  264. package/dot_local/bin/executable_dtags +28 -0
  265. package/dot_local/bin/executable_epoch +43 -38
  266. package/dot_local/bin/executable_extract +32 -99
  267. package/dot_local/bin/executable_gbd +52 -0
  268. package/dot_local/bin/executable_gd +42 -0
  269. package/dot_local/bin/executable_git-ai-commit +35 -20
  270. package/dot_local/bin/executable_git-ai-diff +33 -18
  271. package/dot_local/bin/executable_gl +101 -0
  272. package/dot_local/bin/executable_hash +56 -18
  273. package/dot_local/bin/executable_hashsum +160 -0
  274. package/dot_local/bin/executable_hex +44 -8
  275. package/dot_local/bin/executable_jsonv +34 -10
  276. package/dot_local/bin/executable_jwt +22 -6
  277. package/dot_local/bin/executable_kill-port +18 -2
  278. package/dot_local/bin/executable_lorem +21 -6
  279. package/dot_local/bin/executable_mkscript +35 -0
  280. package/dot_local/bin/executable_monitor +56 -0
  281. package/dot_local/bin/{executable_ip → executable_myip} +16 -2
  282. package/dot_local/bin/executable_notify +22 -0
  283. package/dot_local/bin/executable_open +36 -0
  284. package/dot_local/bin/executable_pw +27 -0
  285. package/dot_local/bin/executable_rec-start +46 -0
  286. package/dot_local/bin/executable_rec-stop +35 -0
  287. package/dot_local/bin/executable_regex +49 -13
  288. package/dot_local/bin/executable_start-niri +8 -0
  289. package/dot_local/bin/executable_tmux-sessionizer +276 -149
  290. package/dot_local/bin/executable_tour +112 -74
  291. package/dot_local/bin/executable_up +21 -0
  292. package/dot_local/bin/executable_update +45 -11
  293. package/dot_local/bin/executable_uuid +37 -7
  294. package/dot_local/bin/executable_win +32 -0
  295. package/dot_local/bin/executable_yamlv +25 -7
  296. package/dot_local/share/bash-completion/completions/dot +62 -44
  297. package/dot_local/share/icons/hicolor/128x128/apps/rousseau.png +0 -0
  298. package/dot_local/share/icons/hicolor/16x16/apps/rousseau.png +0 -0
  299. package/dot_local/share/icons/hicolor/24x24/apps/rousseau.png +0 -0
  300. package/dot_local/share/icons/hicolor/256x256/apps/rousseau.png +0 -0
  301. package/dot_local/share/icons/hicolor/32x32/apps/rousseau.png +0 -0
  302. package/dot_local/share/icons/hicolor/48x48/apps/rousseau.png +0 -0
  303. package/dot_local/share/icons/hicolor/512x512/apps/rousseau.png +0 -0
  304. package/dot_local/share/icons/hicolor/64x64/apps/rousseau.png +0 -0
  305. package/dot_local/share/icons/hicolor/96x96/apps/rousseau.png +0 -0
  306. package/dot_local/share/icons/hicolor/scalable/apps/rousseau.png +0 -0
  307. package/dot_local/share/man/man1/dot.1 +149 -0
  308. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_download +64 -0
  309. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_install +18 -0
  310. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_list-all +13 -0
  311. package/dot_local/share/wayland-sessions/niri.desktop.tmpl +6 -0
  312. package/dot_local/share/zsh/completions/_dot +283 -0
  313. package/install.sh +297 -210
  314. package/package.json +17 -5
  315. package/scripts/ci/check-copyright-headers.sh +96 -0
  316. package/scripts/ci/guard-gitleaks-checkout.sh +57 -0
  317. package/scripts/ci/install-chezmoi-verified.sh +64 -0
  318. package/scripts/ci/validate-ci-config.sh +41 -39
  319. package/scripts/demo/record.sh +3 -2
  320. package/scripts/diagnostics/a2a-conformance.sh +162 -0
  321. package/scripts/diagnostics/alias-governance.sh +137 -0
  322. package/scripts/diagnostics/aliases-cheatsheet.sh +73 -0
  323. package/scripts/diagnostics/aliases-manifest.sh +31 -0
  324. package/scripts/diagnostics/benchmark.sh +209 -29
  325. package/scripts/diagnostics/conflicts.sh +72 -0
  326. package/scripts/diagnostics/doctor-unified.sh +38 -0
  327. package/scripts/diagnostics/doctor.sh +491 -65
  328. package/scripts/diagnostics/drift-dashboard.sh +17 -6
  329. package/scripts/diagnostics/health.sh +351 -110
  330. package/scripts/diagnostics/history-analysis.sh +12 -4
  331. package/scripts/diagnostics/mcp-doctor.sh +575 -0
  332. package/scripts/diagnostics/perf.sh +225 -0
  333. package/scripts/diagnostics/scorecard.sh +118 -0
  334. package/scripts/diagnostics/secret-governance.sh +58 -0
  335. package/scripts/diagnostics/security-score.sh +139 -93
  336. package/scripts/diagnostics/smoke-test.sh +87 -0
  337. package/scripts/diagnostics/snapshot.sh +89 -0
  338. package/scripts/diagnostics/verify.sh +107 -0
  339. package/scripts/diagnostics/verify_state.sh +2 -2
  340. package/scripts/diagnostics/version-locks.sh +79 -0
  341. package/scripts/diagnostics/workstation-attestation.sh +181 -0
  342. package/scripts/docs/build-manual.sh +883 -0
  343. package/scripts/docs/check-manual.sh +213 -0
  344. package/scripts/dot/commands/agent.sh +465 -0
  345. package/scripts/dot/commands/ai.sh +416 -0
  346. package/scripts/dot/commands/aliases.sh +250 -0
  347. package/scripts/dot/commands/appearance.sh +21 -4
  348. package/scripts/dot/commands/core.sh +59 -4
  349. package/scripts/dot/commands/diagnostics.sh +132 -3
  350. package/scripts/dot/commands/fleet.sh +399 -0
  351. package/scripts/dot/commands/lint.sh +177 -0
  352. package/scripts/dot/commands/manual.sh +168 -0
  353. package/scripts/dot/commands/meta.sh +148 -17
  354. package/scripts/dot/commands/patterns.sh +54 -0
  355. package/scripts/dot/commands/restore.sh +57 -35
  356. package/scripts/dot/commands/secrets.sh +151 -9
  357. package/scripts/dot/commands/security.sh +3 -0
  358. package/scripts/dot/commands/tools.sh +268 -27
  359. package/scripts/dot/data/alias-deprecations.tsv +2 -0
  360. package/scripts/dot/lib/bento.sh +49 -0
  361. package/scripts/dot/lib/log.sh +194 -0
  362. package/scripts/dot/lib/platform.sh +98 -0
  363. package/scripts/dot/lib/ui.sh +507 -0
  364. package/scripts/dot/lib/utils.sh +318 -18
  365. package/scripts/fonts/install-nerd-fonts.sh +19 -10
  366. package/scripts/fonts/patch-fonts.sh +1 -0
  367. package/scripts/git-hooks/install.sh +11 -0
  368. package/scripts/git-hooks/pre-commit +12 -0
  369. package/scripts/git-hooks/pre-commit-audit.sh +145 -0
  370. package/scripts/git-hooks/pre-push +29 -0
  371. package/scripts/git-hooks/prepare-commit-msg +29 -0
  372. package/scripts/lib/secrets_provider.sh +158 -0
  373. package/scripts/maintenance/check-updates.sh +131 -0
  374. package/scripts/ops/ai-setup.sh +55 -0
  375. package/scripts/ops/bundle.sh +77 -0
  376. package/scripts/ops/chaos.sh +49 -0
  377. package/scripts/ops/chezmoi-apply.sh +245 -17
  378. package/scripts/ops/chezmoi-diff.sh +1 -0
  379. package/scripts/ops/chezmoi-remove.sh +2 -0
  380. package/scripts/ops/chezmoi-update.sh +34 -2
  381. package/scripts/ops/heal-chezmoi.sh +51 -0
  382. package/scripts/ops/heal-system.sh +128 -0
  383. package/scripts/ops/heal-tools.sh +340 -0
  384. package/scripts/ops/heal.sh +98 -342
  385. package/scripts/ops/post-apply-repair.sh +106 -0
  386. package/scripts/ops/prewarm.sh +127 -0
  387. package/scripts/ops/release.sh +252 -0
  388. package/scripts/ops/rollback.sh +86 -28
  389. package/scripts/ops/setup.sh +137 -0
  390. package/scripts/ops/teleport.sh +2 -1
  391. package/scripts/qa/coverage-baseline.sh +60 -0
  392. package/scripts/qa/docs-coverage.sh +111 -0
  393. package/scripts/qa/reliability-audit.sh +138 -0
  394. package/scripts/qa/traceability-coverage.sh +116 -0
  395. package/scripts/qa/validate-examples.sh +26 -0
  396. package/scripts/qa/wsl-contract.sh +11 -0
  397. package/scripts/release/package-policy-bundles.sh +125 -0
  398. package/scripts/secrets/age-init.sh +1 -0
  399. package/scripts/secrets/create-secrets-file.sh +1 -0
  400. package/scripts/secrets/encrypt-ssh-key.sh +1 -0
  401. package/scripts/security/backup.sh +44 -4
  402. package/scripts/security/dns-doh.sh +36 -14
  403. package/scripts/security/encryption-check.sh +27 -12
  404. package/scripts/security/enforce-policies.sh +11 -16
  405. package/scripts/security/firewall.sh +76 -20
  406. package/scripts/security/lock-configs.sh +2 -2
  407. package/scripts/security/lock-screen.sh +40 -18
  408. package/scripts/security/manage-secrets.sh +42 -29
  409. package/scripts/security/ssh-cert.sh +203 -0
  410. package/scripts/security/telemetry-kill.sh +40 -18
  411. package/scripts/security/usb-safety.sh +37 -15
  412. package/scripts/theme/apply-gnome-theme.sh +87 -56
  413. package/scripts/theme/extract-theme.py +677 -0
  414. package/scripts/theme/install-boot-logo.sh +1 -0
  415. package/scripts/theme/install-catppuccin-themes.sh +57 -33
  416. package/scripts/theme/install-cursors.sh +1 -0
  417. package/scripts/theme/install-file-icons.sh +1 -0
  418. package/scripts/theme/install-grub-theme.sh +11 -1
  419. package/scripts/theme/install-lock-icon.sh +1 -0
  420. package/scripts/theme/merge-wallpaper.sh +141 -0
  421. package/scripts/theme/rebuild-themes.sh +309 -0
  422. package/scripts/theme/switch.sh +308 -137
  423. package/scripts/theme/wallpaper-rotate.sh +66 -12
  424. package/scripts/theme/wallpaper-sync.sh +386 -31
  425. package/scripts/tools/cmatrix.sh +1 -0
  426. package/scripts/tools/detect-collisions.py +1 -1
  427. package/scripts/tools/emoji-picker.sh +4 -1
  428. package/scripts/tools/figlet-banner.sh +1 -0
  429. package/scripts/tools/log-rotate.sh +2 -1
  430. package/scripts/tools/lolcat-wrap.sh +1 -0
  431. package/scripts/tools/pipes.sh +1 -0
  432. package/scripts/tuning/linux.sh +23 -13
  433. package/scripts/tuning/macos.sh +13 -4
  434. package/scripts/uninstall.sh +85 -0
  435. package/scripts/version-sync.sh +487 -0
  436. package/templates/chezmoi-data/geekom-a9.toml.example +21 -0
  437. package/templates/chezmoi-data/mac-m1.toml.example +16 -0
  438. package/templates/chezmoi-data/mac-t2-linux.toml.example +21 -0
  439. package/templates/chezmoi-data/surface-pro-7p.toml.example +21 -0
  440. package/templates/projects/go/.github/workflows/ci.yml +31 -0
  441. package/templates/projects/go/README.md +1 -1
  442. package/templates/projects/go/cmd/__PROJECT_NAME__/main.go +1 -0
  443. package/templates/projects/go/go.sum +0 -0
  444. package/templates/projects/molecule/README.md +1 -1
  445. package/templates/projects/node/.github/workflows/ci.yml +30 -0
  446. package/templates/projects/node/README.md +1 -1
  447. package/templates/projects/node/package-lock.json +12 -0
  448. package/templates/projects/node/src/index.js +1 -0
  449. package/templates/projects/packer/README.md +1 -1
  450. package/templates/projects/python/.github/workflows/ci.yml +34 -0
  451. package/templates/projects/python/README.md +1 -1
  452. package/templates/projects/python/src/__PROJECT_NAME__/__init__.py +1 -0
  453. package/templates/projects/python/tests/test_basic.py +1 -0
  454. package/docs/ARCHITECTURE.md +0 -229
  455. package/docs/COMPLIANCE.md +0 -47
  456. package/docs/FEATURES.md +0 -166
  457. package/docs/FONTS.md +0 -147
  458. package/docs/INSTALL.md +0 -119
  459. package/docs/KEYS.md +0 -40
  460. package/docs/OPERATIONS.md +0 -130
  461. package/docs/PR_DESCRIPTION.md +0 -149
  462. package/docs/SECRETS.md +0 -76
  463. package/docs/SECURITY.md +0 -30
  464. package/docs/SECURITY_CHECKLIST.md +0 -25
  465. package/docs/TASK.md +0 -99
  466. package/docs/TESTING.md +0 -190
  467. package/docs/TOOLS.md +0 -146
  468. package/docs/UTILS.md +0 -105
  469. package/docs/WALKTHROUGH.md +0 -165
  470. package/dot_config/clippy.toml +0 -55
  471. package/dot_config/dotfiles/versions.env.tmpl +0 -19
  472. package/dot_config/firefox/user.js +0 -8
  473. package/dot_config/git/config.tmpl +0 -77
  474. package/dot_config/go/aliases.sh +0 -61
  475. package/dot_config/go/env.sh +0 -24
  476. package/dot_config/ice/README.md +0 -13
  477. package/dot_config/ipython/profile_default/ipython_config.py.tmpl +0 -5
  478. package/dot_config/lsd/config.yaml +0 -19
  479. package/dot_config/nvim/snippets/all.lua +0 -9
  480. package/dot_config/nvim/snippets/python.lua +0 -16
  481. package/dot_config/shell/00-container-detect.sh +0 -53
  482. package/dot_config/shell/05-core-safety.sh.tmpl +0 -13
  483. package/dot_config/shell/40-ls-colors.sh.tmpl +0 -31
  484. package/dot_config/shell/90-theme-switch.sh +0 -70
  485. package/dot_config/topgrade/topgrade.toml.tmpl +0 -42
  486. package/dot_config/waybar/style.css +0 -8
  487. package/dot_config/zsh/rc.d/20-zinit.zsh.tmpl +0 -22
  488. package/dot_local/bin/executable_zig-install +0 -89
  489. package/dot_local/bin/voice_ops +0 -7
  490. package/scripts/ops/health-check.sh +0 -380
  491. package/scripts/tests/README.md +0 -241
  492. package/scripts/tests/benchmark.sh +0 -91
  493. package/scripts/tests/framework/assertions.sh +0 -283
  494. package/scripts/tests/framework/mocks.sh +0 -201
  495. package/scripts/tests/framework/test_runner.sh +0 -189
  496. package/scripts/tests/integration/test_install.sh +0 -237
  497. package/scripts/tests/performance/benchmark_runner.sh +0 -156
  498. package/scripts/tests/performance/regression_check.sh +0 -73
  499. package/scripts/tests/performance/stress_test.sh +0 -65
  500. package/scripts/tests/test-aliases.sh +0 -25
  501. package/scripts/tests/test-docker.sh +0 -48
  502. package/scripts/tests/unit/test_ai_aliases.sh +0 -158
  503. package/scripts/tests/unit/test_ai_cli_checks.sh +0 -47
  504. package/scripts/tests/unit/test_backup.sh +0 -227
  505. package/scripts/tests/unit/test_case_functions.sh +0 -238
  506. package/scripts/tests/unit/test_cd_aliases.sh +0 -367
  507. package/scripts/tests/unit/test_dot_cli.sh +0 -217
  508. package/scripts/tests/unit/test_encode64.sh +0 -67
  509. package/scripts/tests/unit/test_environment.sh +0 -78
  510. package/scripts/tests/unit/test_extract.sh +0 -163
  511. package/scripts/tests/unit/test_framework_edge_cases.sh +0 -113
  512. package/scripts/tests/unit/test_genpass.sh +0 -298
  513. package/scripts/tests/unit/test_install_edge_cases.sh +0 -167
  514. package/scripts/tests/unit/test_installers.sh +0 -172
  515. package/scripts/tests/unit/test_keygen.sh +0 -68
  516. package/scripts/tests/unit/test_logging.sh +0 -96
  517. package/scripts/tests/unit/test_os_detection_comprehensive.sh +0 -388
  518. package/scripts/tests/unit/test_package_managers_comprehensive.sh +0 -321
  519. package/scripts/tests/unit/test_prependpath.sh +0 -66
  520. package/scripts/tests/unit/test_prependpath_refactored.sh +0 -89
  521. package/scripts/tests/unit/test_rd.sh +0 -230
  522. package/scripts/tests/unit/test_security_fixes.sh +0 -130
  523. package/scripts/tests/unit/test_security_scripts.sh +0 -87
  524. package/scripts/tests/unit/test_template_validation.sh +0 -238
  525. package/scripts/tests/unit/test_utility_functions.sh +0 -144
  526. package/scripts/tests/unit/test_wave1_alias_split.sh +0 -132
  527. package/scripts/tests/unit/test_wave1_ci_pinning.sh +0 -61
  528. package/scripts/tests/unit/test_wave1_gitleaks_config.sh +0 -52
  529. package/scripts/tests/unit/test_wave1_heal_fixes.sh +0 -97
  530. package/scripts/tests/unit/test_wave1_install_gpg.sh +0 -35
  531. package/scripts/tests/unit/test_wave1_zshenv_path.sh +0 -89
  532. package/scripts/tests/unit/test_wave1_zshrc_lazy_hook.sh +0 -115
  533. package/scripts/tests/unit/test_wave2_dot_new_guard.sh +0 -75
  534. package/scripts/tests/unit/test_zipf.sh +0 -76
  535. /package/docs/{LEGACY_ROADMAP.md → archive/LEGACY_ROADMAP.md} +0 -0
  536. /package/docs/{REPO_AUDIT.md → archive/REPO_AUDIT.md} +0 -0
  537. /package/docs/{KEY_ROTATION.md → security/KEY_ROTATION.md} +0 -0
  538. /package/dot_config/ansible/{ansible.cfg.tmpl → ansible.cfg} +0 -0
  539. /package/dot_config/docker/{config.json.tmpl → config.json} +0 -0
  540. /package/dot_config/k9s/{config.yaml.tmpl → config.yaml} +0 -0
  541. /package/dot_config/pypoetry/{config.toml.tmpl → config.toml} +0 -0
  542. /package/dot_config/{pyrightconfig.json.tmpl → pyrightconfig.json} +0 -0
  543. /package/dot_config/tflint/{tflint.hcl.tmpl → tflint.hcl} +0 -0
  544. /package/dot_config/yarn/{yarnrc.yml.tmpl → yarnrc.yml} +0 -0
  545. /package/dot_config/zsh/rc.d/{40-bell.zsh.tmpl → 40-bell.zsh} +0 -0
  546. /package/dot_config/zsh/rc.d/{50-login-fortune.zsh.tmpl → 50-login-fortune.zsh} +0 -0
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bash
2
+ # Copyright (c) 2015-2026 Dotfiles. All rights reserved.
2
3
  # shellcheck disable=SC2034
3
4
  # =============================================================================
4
5
  # Dotfiles Heal Script - Auto-repair common dotfiles issues
@@ -8,39 +9,48 @@
8
9
 
9
10
  set -euo pipefail
10
11
 
12
+ _cleanup_files=()
13
+ LOCK_DIR=""
14
+ cleanup() {
15
+ rm -f "${_cleanup_files[@]:-}"
16
+ if [[ -n "$LOCK_DIR" ]]; then
17
+ rmdir "$LOCK_DIR" 2>/dev/null || true
18
+ fi
19
+ }
20
+ trap cleanup EXIT
21
+
11
22
  # Configuration
12
23
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
24
+ # shellcheck source=../dot/lib/ui.sh
25
+ # shellcheck disable=SC1091
26
+ source "$SCRIPT_DIR/../dot/lib/ui.sh"
27
+ # shellcheck source=../dot/lib/log.sh
28
+ # shellcheck disable=SC1091
29
+ source "$SCRIPT_DIR/../dot/lib/log.sh"
30
+ DOT_COMMAND="heal"
13
31
  REPO_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
14
32
  DOTFILES_SOURCE="$REPO_ROOT"
15
33
  BACKUP_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/dotfiles/backups"
16
34
  STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/dotfiles"
17
35
  HEAL_LOG="$STATE_DIR/heal.log"
18
36
 
19
- # Colors (respect NO_COLOR: https://no-color.org)
20
- if [[ -z "${NO_COLOR:-}" ]] && [[ -t 1 ]]; then
21
- RED='\033[0;31m'
22
- GREEN='\033[0;32m'
23
- YELLOW='\033[0;33m'
24
- BLUE='\033[0;34m'
25
- BOLD='\033[1m'
26
- NC='\033[0m'
27
- else
28
- RED='' GREEN='' YELLOW='' BLUE='' BOLD='' NC=''
29
- fi
30
-
31
- # Logging
32
- log() { echo -e "$*"; }
33
- log_info() { log "${BLUE}[INFO]${NC} $*"; }
34
- log_success() { log "${GREEN}[OK]${NC} $*"; }
35
- log_warn() { log "${YELLOW}[WARN]${NC} $*"; }
36
- log_error() { log "${RED}[ERROR]${NC} $*"; }
37
- log_step() { log "\n${BOLD}==> $*${NC}"; }
38
- log_dry() { log "${YELLOW}[DRY-RUN]${NC} Would: $*"; }
37
+ # Logging delegates to shared ui.sh primitives
38
+ ui_init
39
+ log() { printf '%b\n' "$*"; }
40
+ log_info() { ui_info "$@"; }
41
+ log_success() { ui_ok "$@"; }
42
+ log_warn() { ui_warn "$@"; }
43
+ log_error() { ui_err "$@"; }
44
+ log_step() {
45
+ echo ""
46
+ ui_section "$*"
47
+ }
48
+ log_dry() { ui_warn "DRY-RUN" "Would: $*"; }
39
49
 
40
50
  # Persistent logging
41
51
  persist_log() {
42
52
  mkdir -p "$STATE_DIR"
43
- echo "[$(date -Iseconds)] $*" >>"$HEAL_LOG"
53
+ echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*" >>"$HEAL_LOG"
44
54
  }
45
55
 
46
56
  # Options
@@ -49,6 +59,7 @@ FORCE=0
49
59
  FIXES_APPLIED=0
50
60
  ISSUES_FOUND=0
51
61
  CHEZMOI_APPLIED=0
62
+ MISSING_DEPS_FOUND=0
52
63
 
53
64
  usage() {
54
65
  cat <<EOF
@@ -61,8 +72,12 @@ Options:
61
72
  -f, --force Skip confirmation prompts
62
73
  -h, --help Show this help message
63
74
 
75
+ Environment:
76
+ DOTFILES_NONINTERACTIVE=1 Skip all interactive prompts (same as --force)
77
+
64
78
  Repairs:
65
- - Missing core dependencies (chezmoi, starship, rg, bat)
79
+ - Missing tools (zsh, starship, rg, bat, fzf, zoxide, atuin, yazi, zellij,
80
+ nushell, pueue, wasmtime, sops, age, hyperfine)
66
81
  - Broken symlinks in \$HOME (depth 3)
67
82
  - Chezmoi drift (re-applies dotfiles)
68
83
  - Missing critical files (.zshrc, .bashrc, .profile)
@@ -94,313 +109,46 @@ while [[ $# -gt 0 ]]; do
94
109
  esac
95
110
  done
96
111
 
97
- # =============================================================================
98
- # Backup before making changes
99
- # =============================================================================
100
-
101
- create_pre_heal_backup() {
102
- local rollback_script="$REPO_ROOT/scripts/ops/rollback.sh"
103
- if [[ -f "$rollback_script" ]]; then
104
- log_info "Creating backup before heal..."
105
- bash "$rollback_script" backup --force 2>/dev/null || true
106
- else
107
- # Minimal inline backup
108
- local timestamp
109
- timestamp=$(date +"%Y%m%d_%H%M%S")
110
- local backup_path="$BACKUP_DIR/backup_${timestamp}_pre_heal"
111
- mkdir -p "$backup_path"
112
- for f in "$HOME/.bashrc" "$HOME/.zshrc" "$HOME/.profile"; do
113
- if [[ -f "$f" ]]; then
114
- cp -a "$f" "$backup_path/" 2>/dev/null || true
115
- fi
116
- done
117
- log_info "Backup created at $backup_path"
118
- fi
119
- }
120
-
121
- # =============================================================================
122
- # Repair Functions
123
- # =============================================================================
124
-
125
- detect_pkg_manager() {
126
- if command -v brew >/dev/null 2>&1; then
127
- echo "brew"
128
- elif command -v apt-get >/dev/null 2>&1; then
129
- echo "apt"
130
- elif command -v dnf >/dev/null 2>&1; then
131
- echo "dnf"
132
- elif command -v pacman >/dev/null 2>&1; then
133
- echo "pacman"
134
- elif command -v nix-env >/dev/null 2>&1; then
135
- echo "nix"
136
- else
137
- echo ""
138
- fi
139
- }
140
-
141
- install_package() {
142
- local pkg="$1"
143
- local pkg_mgr
144
- pkg_mgr=$(detect_pkg_manager)
145
-
146
- case "$pkg_mgr" in
147
- brew) brew install "$pkg" ;;
148
- apt) sudo apt-get install -y "$pkg" ;;
149
- dnf) sudo dnf install -y "$pkg" ;;
150
- pacman) sudo pacman -S --noconfirm "$pkg" ;;
151
- nix) nix-env -iA "nixpkgs.$pkg" ;;
152
- *)
153
- log_error "No supported package manager found. Install '$pkg' manually."
154
- return 1
155
- ;;
156
- esac
157
- }
158
-
159
- # Map command names to package names per package manager
160
- get_package_name() {
161
- local cmd="$1"
162
- local pkg_mgr
163
- pkg_mgr=$(detect_pkg_manager)
164
-
165
- case "$cmd" in
166
- rg)
167
- case "$pkg_mgr" in
168
- apt | dnf) echo "ripgrep" ;;
169
- *) echo "ripgrep" ;;
170
- esac
171
- ;;
172
- bat)
173
- case "$pkg_mgr" in
174
- apt) echo "bat" ;;
175
- *) echo "bat" ;;
176
- esac
177
- ;;
178
- *) echo "$cmd" ;;
179
- esac
180
- }
181
-
182
- heal_missing_dependencies() {
183
- log_step "Checking core dependencies"
184
- local deps=(chezmoi starship rg bat)
185
- local missing=()
186
-
187
- for cmd in "${deps[@]}"; do
188
- if ! command -v "$cmd" >/dev/null 2>&1; then
189
- missing+=("$cmd")
190
- ISSUES_FOUND=$((ISSUES_FOUND + 1))
191
- fi
192
- done
193
-
194
- if [[ ${#missing[@]} -eq 0 ]]; then
195
- log_success "All core dependencies present"
196
- return 0
197
- fi
198
-
199
- log_warn "Missing dependencies: ${missing[*]}"
200
-
201
- local pkg_mgr
202
- pkg_mgr=$(detect_pkg_manager)
203
-
204
- if [[ -z "$pkg_mgr" ]]; then
205
- log_error "No supported package manager detected. Install manually: ${missing[*]}"
206
- return 1
207
- fi
208
-
209
- for cmd in "${missing[@]}"; do
210
- local pkg
211
- pkg=$(get_package_name "$cmd")
212
-
213
- if [[ "$DRY_RUN" == "1" ]]; then
214
- log_dry "install '$pkg' via $pkg_mgr"
215
- else
216
- log_info "Installing $pkg via $pkg_mgr..."
217
- if install_package "$pkg"; then
218
- log_success "Installed $pkg"
219
- FIXES_APPLIED=$((FIXES_APPLIED + 1))
220
- persist_log "HEAL: installed $pkg via $pkg_mgr"
221
- else
222
- log_error "Failed to install $pkg"
223
- fi
224
- fi
225
- done
226
- }
227
-
228
- heal_broken_symlinks() {
229
- log_step "Checking for broken symlinks"
230
- local broken=()
231
-
232
- while IFS= read -r -d '' link; do
233
- if [[ ! -e "$link" ]]; then
234
- broken+=("$link")
235
- fi
236
- done < <(find "$HOME" -maxdepth 3 -type l -print0 2>/dev/null)
237
-
238
- if [[ ${#broken[@]} -eq 0 ]]; then
239
- log_success "No broken symlinks found"
240
- return 0
241
- fi
242
-
243
- ISSUES_FOUND=$((ISSUES_FOUND + ${#broken[@]}))
244
- log_warn "${#broken[@]} broken symlink(s) found"
245
-
246
- for link in "${broken[@]}"; do
247
- local target
248
- target=$(readlink "$link" 2>/dev/null || echo "unknown")
249
- if [[ "$DRY_RUN" == "1" ]]; then
250
- log_dry "remove broken symlink: $link -> $target"
251
- else
252
- if [[ "$FORCE" != "1" ]]; then
253
- read -rp "Remove broken symlink $link -> $target? [y/N] " response
254
- if [[ ! "$response" =~ ^[Yy]$ ]]; then
255
- log_info "Skipped: $link"
256
- continue
257
- fi
258
- fi
259
- rm -f "$link"
260
- log_success "Removed broken symlink: $link -> $target"
261
- FIXES_APPLIED=$((FIXES_APPLIED + 1))
262
- persist_log "HEAL: removed broken symlink $link"
263
- fi
264
- done
265
- }
266
-
267
- heal_chezmoi_drift() {
268
- log_step "Checking chezmoi state"
269
-
270
- if ! command -v chezmoi >/dev/null 2>&1; then
271
- log_warn "chezmoi not installed, skipping drift check"
272
- return 0
273
- fi
274
-
275
- local status_output
276
- status_output=$(chezmoi status 2>/dev/null || echo "")
277
-
278
- if [[ -z "$status_output" ]]; then
279
- log_success "Chezmoi state is synchronized"
280
- return 0
281
- fi
282
-
283
- local drift_count
284
- drift_count=$(echo "$status_output" | wc -l | tr -d ' ')
285
- ISSUES_FOUND=$((ISSUES_FOUND + 1))
286
- log_warn "$drift_count file(s) out of sync"
287
-
288
- if [[ "$DRY_RUN" == "1" ]]; then
289
- log_dry "run 'chezmoi apply --force' to re-sync"
290
- echo "$status_output" | while read -r line; do
291
- log_info " $line"
292
- done
293
- else
294
- log_info "Re-applying dotfiles with chezmoi..."
295
- if chezmoi apply --force; then
296
- log_success "Chezmoi re-applied successfully"
297
- FIXES_APPLIED=$((FIXES_APPLIED + 1))
298
- CHEZMOI_APPLIED=1
299
- persist_log "HEAL: chezmoi apply --force ($drift_count files drifted)"
300
- else
301
- log_error "Chezmoi apply failed"
302
- fi
303
- fi
304
- }
305
-
306
- heal_missing_critical_files() {
307
- log_step "Checking critical files"
308
- local critical_files=(
309
- "$HOME/.zshrc"
310
- "$HOME/.bashrc"
311
- "$HOME/.profile"
312
- )
313
- local missing=()
314
-
315
- for file in "${critical_files[@]}"; do
316
- if [[ ! -f "$file" ]] && [[ ! -L "$file" ]]; then
317
- missing+=("$file")
318
- ISSUES_FOUND=$((ISSUES_FOUND + 1))
112
+ # Prevent concurrent execution
113
+ # Prefer XDG runtime dir when it exists and is writable; fallback to /tmp.
114
+ LOCK_BASE="/tmp"
115
+ if [[ -n "${XDG_RUNTIME_DIR:-}" ]] && [[ -d "${XDG_RUNTIME_DIR}" ]] && [[ -w "${XDG_RUNTIME_DIR}" ]]; then
116
+ LOCK_BASE="${XDG_RUNTIME_DIR}"
117
+ fi
118
+ LOCK_FILE="${LOCK_BASE}/dotfiles-heal.lock"
119
+ LOCK_DIR="${LOCK_FILE}.d"
120
+ if command -v flock >/dev/null 2>&1; then
121
+ exec 9>"$LOCK_FILE"
122
+ if ! flock -n 9; then
123
+ # Fallback path for systems where flock exists but cannot lock reliably.
124
+ if ! mkdir "$LOCK_DIR" 2>/dev/null; then
125
+ ui_warn "Already running" "Another instance is active"
126
+ exit 0
319
127
  fi
320
- done
321
-
322
- if [[ ${#missing[@]} -eq 0 ]]; then
323
- log_success "All critical shell configs present"
324
- return 0
325
128
  fi
326
-
327
- log_warn "Missing critical files: ${missing[*]}"
328
-
329
- if ! command -v chezmoi >/dev/null 2>&1; then
330
- log_error "chezmoi not available to regenerate files"
331
- return 1
332
- fi
333
-
334
- if [[ "$DRY_RUN" == "1" ]]; then
335
- log_dry "run 'chezmoi apply --force' to regenerate missing files"
336
- elif [[ "$CHEZMOI_APPLIED" == "1" ]]; then
337
- log_info "chezmoi already re-applied during drift repair, verifying files..."
338
- local restored=0
339
- for file in "${missing[@]}"; do
340
- if [[ -f "$file" ]] || [[ -L "$file" ]]; then
341
- log_success "Restored (via earlier apply): $file"
342
- restored=$((restored + 1))
343
- else
344
- log_warn "Still missing after apply: $file"
345
- fi
346
- done
347
- FIXES_APPLIED=$((FIXES_APPLIED + restored))
348
- else
349
- log_info "Re-applying chezmoi to regenerate missing files..."
350
- if chezmoi apply --force; then
351
- CHEZMOI_APPLIED=1
352
- # Verify files were restored
353
- local restored=0
354
- for file in "${missing[@]}"; do
355
- if [[ -f "$file" ]] || [[ -L "$file" ]]; then
356
- log_success "Restored: $file"
357
- restored=$((restored + 1))
358
- else
359
- log_warn "Still missing after apply: $file"
360
- fi
361
- done
362
- FIXES_APPLIED=$((FIXES_APPLIED + restored))
363
- persist_log "HEAL: regenerated $restored critical file(s)"
364
- else
365
- log_error "Chezmoi apply failed"
366
- fi
129
+ else
130
+ # Portable fallback when flock is unavailable (e.g. default macOS envs).
131
+ if ! mkdir "$LOCK_DIR" 2>/dev/null; then
132
+ ui_warn "Already running" "Another instance is active"
133
+ exit 0
367
134
  fi
368
- }
369
-
370
- heal_missing_xdg_dirs() {
371
- log_step "Checking XDG config directories"
372
- local xdg_dirs=(
373
- "$HOME/.config/shell"
374
- "$HOME/.config/nvim"
375
- "$HOME/.config/git"
376
- )
377
- local missing=()
135
+ fi
378
136
 
379
- for dir in "${xdg_dirs[@]}"; do
380
- if [[ ! -d "$dir" ]]; then
381
- missing+=("$dir")
382
- ISSUES_FOUND=$((ISSUES_FOUND + 1))
383
- fi
384
- done
137
+ # =============================================================================
138
+ # Load modules (inherit scope: set -euo pipefail, ui.sh, and all variables)
139
+ # =============================================================================
385
140
 
386
- if [[ ${#missing[@]} -eq 0 ]]; then
387
- log_success "All XDG config directories present"
388
- return 0
389
- fi
141
+ # shellcheck source=heal-tools.sh
142
+ # shellcheck disable=SC1091
143
+ source "$SCRIPT_DIR/heal-tools.sh"
390
144
 
391
- log_warn "Missing XDG directories: ${missing[*]}"
145
+ # shellcheck source=heal-system.sh
146
+ # shellcheck disable=SC1091
147
+ source "$SCRIPT_DIR/heal-system.sh"
392
148
 
393
- for dir in "${missing[@]}"; do
394
- if [[ "$DRY_RUN" == "1" ]]; then
395
- log_dry "create directory: $dir"
396
- else
397
- mkdir -p "$dir"
398
- log_success "Created: $dir"
399
- FIXES_APPLIED=$((FIXES_APPLIED + 1))
400
- persist_log "HEAL: created directory $dir"
401
- fi
402
- done
403
- }
149
+ # shellcheck source=heal-chezmoi.sh
150
+ # shellcheck disable=SC1091
151
+ source "$SCRIPT_DIR/heal-chezmoi.sh"
404
152
 
405
153
  # =============================================================================
406
154
  # Main
@@ -408,59 +156,67 @@ heal_missing_xdg_dirs() {
408
156
 
409
157
  main() {
410
158
  echo ""
411
- echo "=========================================="
412
- echo " Dotfiles Heal - Auto-Repair"
413
- echo "=========================================="
159
+ printf ' \033[1mDotfiles Heal\033[0m\n'
160
+ echo ""
414
161
 
415
162
  if [[ "$DRY_RUN" == "1" ]]; then
416
- log_info "Running in dry-run mode (no changes will be made)"
163
+ log_info "Dry-run mode (no changes will be made)"
417
164
  fi
418
165
 
419
- # Confirm before making changes (unless --force or --dry-run)
420
- if [[ "$DRY_RUN" != "1" ]] && [[ "$FORCE" != "1" ]]; then
421
- echo ""
422
- log_warn "This will attempt to auto-repair your dotfiles environment."
423
- log_info "A backup will be created before any changes are made."
424
- read -rp "Continue? [y/N] " response
166
+ # Confirm before making changes (unless --force, --dry-run, or non-interactive)
167
+ if [[ "$DRY_RUN" != "1" ]] && [[ "$FORCE" != "1" ]] && [[ "${DOTFILES_NONINTERACTIVE:-0}" != "1" ]]; then
168
+ log_warn "This will auto-repair your dotfiles environment."
169
+ read -rp " Continue? [y/N] " response
425
170
  if [[ ! "$response" =~ ^[Yy]$ ]]; then
426
171
  log_info "Aborted."
427
172
  exit 0
428
173
  fi
174
+ echo ""
429
175
  fi
430
176
 
431
177
  # Create backup before making changes
432
178
  if [[ "$DRY_RUN" != "1" ]]; then
433
- create_pre_heal_backup
179
+ _pkg_install "backup" 0 1 create_pre_heal_backup 2>/dev/null || true
434
180
  fi
435
181
 
436
182
  # Run all repairs
437
183
  heal_missing_dependencies || true
438
- heal_broken_symlinks || true
184
+ heal_mise_tools || true
185
+
186
+ # Quick checks (no animation needed)
439
187
  heal_chezmoi_drift || true
188
+ heal_broken_symlinks || true
440
189
  heal_missing_critical_files || true
441
190
  heal_missing_xdg_dirs || true
442
191
 
192
+ # Pre-warm shell caches for fast startup (< 50ms target)
193
+ local prewarm_script="$SCRIPT_DIR/prewarm.sh"
194
+ if [[ -f "$prewarm_script" ]] && [[ "$DRY_RUN" != "1" ]]; then
195
+ log_step "Performance"
196
+ _pkg_install "shell cache pre-warm" 0 1 bash "$prewarm_script" || true
197
+ fi
198
+
443
199
  # Summary
444
200
  echo ""
445
- echo "=========================================="
446
201
  if [[ "$DRY_RUN" == "1" ]]; then
447
202
  if [[ $ISSUES_FOUND -eq 0 ]]; then
448
- log_success "No issues found. System is healthy."
203
+ printf ' \033[1;38;5;42mHealthy.\033[0m No issues found.\n'
449
204
  else
450
- log_info "Found $ISSUES_FOUND issue(s). Run without --dry-run to apply fixes."
205
+ printf ' Found %d issue(s). Run without --dry-run to apply fixes.\n' "$ISSUES_FOUND"
451
206
  fi
452
207
  else
453
208
  if [[ $ISSUES_FOUND -eq 0 ]]; then
454
- log_success "No issues found. System is healthy."
209
+ printf ' \033[1;38;5;42mHealthy.\033[0m No issues found.\n'
455
210
  elif [[ $FIXES_APPLIED -gt 0 ]]; then
456
- log_success "Applied $FIXES_APPLIED fix(es) for $ISSUES_FOUND issue(s) found."
211
+ printf ' \033[1;38;5;42mDone!\033[0m Applied %d fix(es) for %d issue(s).\n' "$FIXES_APPLIED" "$ISSUES_FOUND"
457
212
  persist_log "HEAL_COMPLETE: $FIXES_APPLIED fixes applied"
213
+ dot_log info "heal_complete" "fixes=$FIXES_APPLIED" "issues=$ISSUES_FOUND"
458
214
  else
459
- log_warn "Found $ISSUES_FOUND issue(s) but no fixes could be applied."
460
- log_info "Try running 'dot doctor' for detailed diagnostics."
215
+ printf ' Found %d issue(s) but no fixes could be applied.\n' "$ISSUES_FOUND"
216
+ printf ' Run \033[38;5;211mdot doctor\033[0m for diagnostics.\n'
461
217
  fi
462
218
  fi
463
- echo "=========================================="
219
+ echo ""
464
220
  }
465
221
 
466
222
  main
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env bash
2
+ # Copyright (c) 2015-2026 Dotfiles. All rights reserved.
3
+ set -euo pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ # shellcheck source=../dot/lib/ui.sh
7
+ # shellcheck disable=SC1091
8
+ source "$SCRIPT_DIR/../dot/lib/ui.sh"
9
+
10
+ ZWC_CACHE_DIRS_DEFAULT=("$HOME/.config/shell" "$HOME/.config/zsh")
11
+
12
+ repair_zwc_cache() {
13
+ local repaired=0
14
+ local failed=0
15
+ local file
16
+ local dirs=()
17
+ local raw_dirs="${DOTFILES_ZWC_CACHE_DIRS:-}"
18
+
19
+ if [[ -n "$raw_dirs" ]]; then
20
+ # shellcheck disable=SC2206
21
+ dirs=($raw_dirs)
22
+ else
23
+ dirs=("${ZWC_CACHE_DIRS_DEFAULT[@]}")
24
+ fi
25
+
26
+ while IFS= read -r -d '' file; do
27
+ if [[ ! -w "$file" ]]; then
28
+ if rm -f "$file" >/dev/null 2>&1; then
29
+ ((repaired++)) || true
30
+ else
31
+ ((failed++)) || true
32
+ fi
33
+ fi
34
+ done < <(find "${dirs[@]}" -type f -name '*.zwc' -print0 2>/dev/null || true)
35
+
36
+ if ((failed > 0)); then
37
+ ui_err "Zsh cache repair" "failed to remove ${failed} stale .zwc file(s)"
38
+ return
39
+ fi
40
+
41
+ if ((repaired > 0)); then
42
+ ui_warn "Zsh cache repair" "removed ${repaired} stale read-only .zwc file(s)"
43
+ else
44
+ ui_ok "Zsh cache repair" "no stale .zwc permissions detected"
45
+ fi
46
+ }
47
+
48
+ resolve_zsh_bin() {
49
+ if [[ -n "${DOTFILES_ZSH_BIN:-}" ]]; then
50
+ printf "%s\n" "${DOTFILES_ZSH_BIN}"
51
+ return
52
+ fi
53
+ if command -v zsh >/dev/null 2>&1; then
54
+ command -v zsh
55
+ return
56
+ fi
57
+ printf "%s\n" ""
58
+ }
59
+
60
+ validate_dot_cli() {
61
+ local dot_bin="${HOME}/.local/bin/dot"
62
+ local zsh_out dot_alias dot_path
63
+ local zsh_bin
64
+
65
+ if [[ ! -x "$dot_bin" ]]; then
66
+ ui_err "dot CLI binary" "missing executable at ${dot_bin}"
67
+ return
68
+ fi
69
+ ui_ok "dot CLI binary" "$dot_bin"
70
+
71
+ zsh_bin="$(resolve_zsh_bin)"
72
+ if [[ -z "$zsh_bin" || ! -x "$zsh_bin" ]]; then
73
+ ui_warn "dot CLI resolution" "zsh not available; skipping shell validation"
74
+ return
75
+ fi
76
+
77
+ zsh_out="$("$zsh_bin" -lic '
78
+ alias dot 2>/dev/null || true
79
+ whence -p dot 2>/dev/null || true
80
+ ' 2>/dev/null || true)"
81
+ dot_alias="$(printf "%s\n" "$zsh_out" | head -n 1)"
82
+ dot_path="$(printf "%s\n" "$zsh_out" | tail -n 1)"
83
+
84
+ if [[ "$dot_alias" == *"cd_with_history"* ]]; then
85
+ ui_warn "dot alias collision" "legacy sessions may still map dot to navigation; run: unalias dot && exec zsh"
86
+ fi
87
+
88
+ if [[ "$dot_path" == "$dot_bin" ]]; then
89
+ ui_ok "dot CLI resolution" "$dot_path"
90
+ elif [[ -n "$dot_path" ]]; then
91
+ ui_warn "dot CLI resolution" "resolved to ${dot_path} (expected ${dot_bin})"
92
+ else
93
+ ui_err "dot CLI resolution" "dot not found in a fresh zsh login shell"
94
+ fi
95
+ }
96
+
97
+ main() {
98
+ ui_init
99
+ ui_header "Post-apply checks"
100
+ repair_zwc_cache
101
+ validate_dot_cli
102
+ }
103
+
104
+ if [[ "${DOTFILES_POST_APPLY_TESTING:-0}" != "1" ]]; then
105
+ main
106
+ fi