@sebastienrousseau/dotfiles 0.2.499 → 0.2.501

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 (567) hide show
  1. package/CHANGELOG.md +452 -0
  2. package/LICENSE +1283 -0
  3. package/README.md +322 -0
  4. package/docs/.vitepress/reports/localization-readability-audit.md +73 -0
  5. package/docs/AI.md +108 -0
  6. package/docs/CNAME +1 -0
  7. package/docs/COPYRIGHT +4 -3
  8. package/docs/NAMING_CONVENTIONS.md +102 -0
  9. package/docs/README.md +82 -0
  10. package/docs/_config.yml +59 -0
  11. package/docs/adr/ADR-001-ci-cd-pipeline.md +118 -0
  12. package/docs/adr/ADR-002-shell-performance.md +130 -0
  13. package/docs/adr/ADR-003-security-first.md +158 -0
  14. package/docs/adr/ADR-004-cli-architecture.md +171 -0
  15. package/docs/adr/ADR-005-chezmoi-choice.md +99 -0
  16. package/docs/adr/ADR-006-shell-selection.md +124 -0
  17. package/docs/adr/ADR-007-multi-shell-parity.md +62 -0
  18. package/docs/adr/ADR-008-alias-system-architecture.md +95 -0
  19. package/docs/adr/ADR-009-wallpaper-driven-theming.md +131 -0
  20. package/docs/adr/ADR-010-starship-transient-prompt.md +144 -0
  21. package/docs/adr/ADR-011-nushell-tier3-keep.md +144 -0
  22. package/docs/adr/README.md +39 -0
  23. package/docs/architecture/ARCHITECTURE.md +117 -0
  24. package/docs/architecture/INTEROP.md +44 -0
  25. package/docs/architecture/REPO_LAYOUT.md +241 -0
  26. package/docs/architecture/WALKTHROUGH.md +86 -0
  27. package/docs/architecture/fleet-deployment.md +77 -0
  28. package/docs/archive/EUXIS_2026_REVIEW.md +127 -0
  29. package/docs/archive/LEGACY_ROADMAP.md +160 -0
  30. package/docs/archive/MILESTONE_v0.2.493.md +47 -0
  31. package/docs/{PLAN.md → archive/PLAN.md} +50 -12
  32. package/docs/archive/REPO_AUDIT.md +31 -0
  33. package/docs/guides/INSTALL.md +144 -0
  34. package/docs/guides/NEOVIM_IDE_GUIDE.md +61 -0
  35. package/docs/guides/THEMING.md +230 -0
  36. package/docs/guides/TROUBLESHOOTING.md +176 -0
  37. package/docs/guides/WSL2_NIX_TROUBLESHOOTING.md +792 -0
  38. package/docs/index.md +43 -0
  39. package/docs/interop/A2A.md +39 -0
  40. package/docs/interop/POWERSHELL.md +102 -0
  41. package/docs/manual/00-introduction.md +89 -0
  42. package/docs/manual/01-concepts/01-architecture.md +138 -0
  43. package/docs/manual/01-concepts/02-trust-model.md +182 -0
  44. package/docs/manual/01-concepts/03-theme-engine.md +186 -0
  45. package/docs/manual/01-concepts/04-fleet.md +148 -0
  46. package/docs/manual/01-concepts/05-self-healing.md +204 -0
  47. package/docs/manual/02-tutorials/01-first-install.md +197 -0
  48. package/docs/manual/02-tutorials/02-add-wallpaper.md +216 -0
  49. package/docs/manual/02-tutorials/03-create-profile.md +244 -0
  50. package/docs/manual/02-tutorials/04-encrypt-secret.md +281 -0
  51. package/docs/manual/02-tutorials/05-deploy-fleet.md +283 -0
  52. package/docs/manual/03-reference/01-dot-cli.md +417 -0
  53. package/docs/manual/03-reference/02-config-files.md +265 -0
  54. package/docs/manual/03-reference/03-environment.md +124 -0
  55. package/docs/manual/03-reference/04-templates.md +190 -0
  56. package/docs/manual/03-reference/05-feature-flags.md +128 -0
  57. package/docs/manual/04-cookbook/01-recipes.md +285 -0
  58. package/docs/manual/04-cookbook/02-troubleshooting.md +351 -0
  59. package/docs/manual/04-cookbook/03-faq.md +175 -0
  60. package/docs/manual/05-appendices/A-platform-matrix.md +101 -0
  61. package/docs/manual/05-appendices/B-security-checklist.md +84 -0
  62. package/docs/manual/05-appendices/C-glossary.md +40 -0
  63. package/docs/manual/05-appendices/D-bibliography.md +58 -0
  64. package/docs/manual/05-appendices/E-license.md +38 -0
  65. package/docs/manual/_toc.yml +58 -0
  66. package/docs/manual/command-index.md +62 -0
  67. package/docs/manual/concept-index.md +168 -0
  68. package/docs/operations/ATTESTATION.md +44 -0
  69. package/docs/operations/CI_CADENCE.md +107 -0
  70. package/docs/operations/CI_COMPOSITES.md +156 -0
  71. package/docs/operations/COMPLETIONS.md +123 -0
  72. package/docs/operations/COVERAGE.md +148 -0
  73. package/docs/operations/DRIFT.md +107 -0
  74. package/docs/operations/MAINTENANCE.md +63 -0
  75. package/docs/operations/MIGRATION.md +109 -0
  76. package/docs/operations/OPERATIONS.md +188 -0
  77. package/docs/operations/PERFORMANCE.md +133 -0
  78. package/docs/operations/RELIABILITY.md +122 -0
  79. package/docs/{ROADMAP.md → operations/ROADMAP.md} +57 -39
  80. package/docs/operations/TESTING.md +199 -0
  81. package/docs/operations/TRACEABILITY.md +35 -0
  82. package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +65 -0
  83. package/docs/operations/VERSION_SYNC.md +393 -0
  84. package/docs/reference/ALIASES.md +131 -0
  85. package/docs/reference/ALIASES_CHEATSHEET.md +32 -0
  86. package/docs/reference/ALIASES_DEPRECATIONS.md +13 -0
  87. package/docs/reference/FEATURES.md +66 -0
  88. package/docs/reference/FONTS.md +112 -0
  89. package/docs/reference/PROFILES.md +69 -0
  90. package/docs/reference/SCREENSHOTS.md +121 -0
  91. package/docs/reference/SCRIPTS.md +71 -0
  92. package/docs/reference/SUPPORT_MATRIX.md +80 -0
  93. package/docs/reference/THEMES.md +117 -0
  94. package/docs/reference/TOOLS.md +109 -0
  95. package/docs/reference/UTILS.md +155 -0
  96. package/docs/security/AI_ACT_COMPLIANCE.md +94 -0
  97. package/docs/security/AUDIT_BYPASS.md +103 -0
  98. package/docs/security/AUTOMATION_SECRETS.md +26 -0
  99. package/docs/security/CI_EGRESS_ALLOWLIST.md +127 -0
  100. package/docs/security/COMPLIANCE.md +458 -0
  101. package/docs/security/DEPS_DEV_EXCEPTIONS.md +86 -0
  102. package/docs/security/ENCRYPTION.md +57 -0
  103. package/docs/security/FMEA.md +159 -0
  104. package/docs/security/HISTORY_FILTERING.md +132 -0
  105. package/docs/security/INCIDENT_RESPONSE.md +579 -0
  106. package/docs/security/INSTALL_VERIFICATION.md +122 -0
  107. package/docs/security/KEYS.md +49 -0
  108. package/docs/security/KEY_ROTATION.md +223 -0
  109. package/docs/security/MCP_POLICY.md +78 -0
  110. package/docs/security/POLICY_RELEASES.md +37 -0
  111. package/docs/security/README.md +28 -0
  112. package/docs/security/SCORECARD.md +80 -0
  113. package/docs/security/SECRETS.md +158 -0
  114. package/docs/security/SECURITY.md +45 -0
  115. package/docs/security/SECURITY_CHECKLIST.md +55 -0
  116. package/docs/security/SHELL_EXEMPTIONS.md +145 -0
  117. package/docs/security/SOUP_REGISTER.md +36 -0
  118. package/docs/security/THREAT_MODEL.md +130 -0
  119. package/docs/security/VERIFICATION_VALIDATION.md +228 -0
  120. package/docs/themes/README.md +10 -0
  121. package/docs/themes/VISUAL_INTEGRITY_REPORT.md +30 -0
  122. package/docs/themes/hero-shot.svg +78 -0
  123. package/dot_config/.module-manifest.json +69 -0
  124. package/dot_config/ai/identity.md +23 -0
  125. package/dot_config/ai/patterns/architect.md +16 -0
  126. package/dot_config/ai/patterns/hardener.md +15 -0
  127. package/dot_config/ai/patterns/refactor.md +15 -0
  128. package/dot_config/aider/aider.conf.yml +32 -0
  129. package/dot_config/alacritty/alacritty.toml.tmpl +55 -0
  130. package/dot_config/ansible/ansible.cfg +11 -0
  131. package/dot_config/atuin/config.toml.tmpl +47 -0
  132. package/dot_config/bat/config +23 -0
  133. package/dot_config/brave-flags.conf.tmpl +7 -0
  134. package/dot_config/btop/btop.conf +16 -0
  135. package/dot_config/btop/themes/tokyonight.theme +34 -0
  136. package/dot_config/bun/bunfig.toml.tmpl +33 -0
  137. package/dot_config/claude/mcp_servers.json +20 -0
  138. package/dot_config/containers/containers.conf +14 -0
  139. package/dot_config/curl/dot_curlrc +18 -0
  140. package/dot_config/dlv/config.yml +39 -0
  141. package/dot_config/docker/config.json +15 -0
  142. package/dot_config/dotfiles/agent-card.json +29 -0
  143. package/dot_config/dotfiles/agent-profiles.json +92 -0
  144. package/dot_config/dotfiles/boot/README.md +13 -0
  145. package/dot_config/dotfiles/grub/README.md +13 -0
  146. package/dot_config/dotfiles/lock/README.md +13 -0
  147. package/dot_config/dotfiles/mcp-lock.json +33 -0
  148. package/dot_config/dotfiles/mcp-policy.json +52 -0
  149. package/dot_config/dotfiles/mcp-registry.json +47 -0
  150. package/dot_config/dotfiles/model-registry.json +20 -0
  151. package/dot_config/dotfiles/policy-bundles.json +38 -0
  152. package/dot_config/dotfiles/prompt-registry.json +16 -0
  153. package/dot_config/dotfiles/versions.env +18 -0
  154. package/dot_config/duf/duf.conf +6 -0
  155. package/dot_config/duti/defaults.duti +5 -0
  156. package/dot_config/emoji/emoji.txt +34 -0
  157. package/dot_config/environment.d/50-ssh-agent.conf +2 -0
  158. package/dot_config/environment.d/90-wayland.conf +19 -0
  159. package/dot_config/fastfetch/config.jsonc +28 -0
  160. package/dot_config/firefox/user.js.tmpl +58 -0
  161. package/dot_config/fish/completions/dot-theme-sync.fish.tmpl +9 -0
  162. package/dot_config/fish/completions/dot.fish.tmpl +115 -0
  163. package/dot_config/fish/conf.d/000-perf-cache.fish +56 -0
  164. package/dot_config/fish/conf.d/aliases.fish.tmpl +77 -0
  165. package/dot_config/fish/conf.d/env.fish.tmpl +48 -0
  166. package/dot_config/fish/conf.d/functions.fish.tmpl +22 -0
  167. package/dot_config/fish/conf.d/init.fish.tmpl +172 -0
  168. package/dot_config/fish/config.fish.tmpl +44 -0
  169. package/dot_config/fish/fish_plugins +1 -0
  170. package/dot_config/fish/functions/_.fish +3 -0
  171. package/dot_config/fish/functions/_cached_eval.fish +131 -0
  172. package/dot_config/fish/functions/_cached_eval_clear.fish +17 -0
  173. package/dot_config/fish/functions/als.fish +46 -0
  174. package/dot_config/fish/functions/bg-upgrade.fish +7 -0
  175. package/dot_config/fish/functions/c.fish +3 -0
  176. package/dot_config/fish/functions/cat.fish +9 -0
  177. package/dot_config/fish/functions/d.fish +7 -0
  178. package/dot_config/fish/functions/dot.fish +34 -0
  179. package/dot_config/fish/functions/h.fish +3 -0
  180. package/dot_config/fish/functions/l.fish +7 -0
  181. package/dot_config/fish/functions/la.fish +7 -0
  182. package/dot_config/fish/functions/ll.fish +7 -0
  183. package/dot_config/fish/functions/log_error.fish +13 -0
  184. package/dot_config/fish/functions/log_info.fish +13 -0
  185. package/dot_config/fish/functions/lr.fish +7 -0
  186. package/dot_config/fish/functions/lra.fish +7 -0
  187. package/dot_config/fish/functions/ls.fish +7 -0
  188. package/dot_config/fish/functions/lt.fish +7 -0
  189. package/dot_config/fish/functions/lta.fish +7 -0
  190. package/dot_config/fish/functions/notify-run.fish +11 -0
  191. package/dot_config/fish/functions/q.fish +3 -0
  192. package/dot_config/fish/functions/silent-run.fish +7 -0
  193. package/dot_config/fish/functions/yy.fish +8 -0
  194. package/dot_config/flatpak/flatpak.list +4 -0
  195. package/dot_config/fontconfig/fonts.conf.tmpl +57 -0
  196. package/dot_config/foot/foot.ini.tmpl +33 -0
  197. package/dot_config/fuzzel/fuzzel.ini.tmpl +18 -0
  198. package/dot_config/fzf/fzf.zsh +48 -0
  199. package/dot_config/gem/gemrc +9 -0
  200. package/dot_config/gh/config.yml +12 -0
  201. package/dot_config/ghostty/config.tmpl +165 -0
  202. package/dot_config/git/allowed_signers.tmpl +18 -0
  203. package/dot_config/git/attributes +12 -0
  204. package/dot_config/git/commit-template +10 -0
  205. package/dot_config/git/hooks/executable_commit-msg +146 -0
  206. package/dot_config/git/ignore +27 -0
  207. package/dot_config/gnupg/gpg-agent.conf +11 -0
  208. package/dot_config/go/golangci.yml +118 -0
  209. package/dot_config/go/gopls.json +30 -0
  210. package/dot_config/goose/config.yaml +29 -0
  211. package/dot_config/gtk-3.0/gtk.css.tmpl +184 -0
  212. package/dot_config/gtk-3.0/settings.ini.tmpl +27 -0
  213. package/dot_config/gtk-4.0/gtk.css.tmpl +252 -0
  214. package/dot_config/gtk-4.0/settings.ini.tmpl +18 -0
  215. package/dot_config/htop/htoprc +20 -0
  216. package/dot_config/inputrc +2 -0
  217. package/dot_config/ipython/profile_default/ipython_config.py +19 -0
  218. package/dot_config/just/justfile +122 -0
  219. package/dot_config/k9s/config.yaml +65 -0
  220. package/dot_config/k9s/skins/catppuccin-mocha.yaml +116 -0
  221. package/dot_config/kanshi/config.tmpl +22 -0
  222. package/dot_config/karabiner/karabiner.json +14 -0
  223. package/dot_config/kitty/kitty.conf.tmpl +53 -0
  224. package/dot_config/lazydocker/config.yml +186 -0
  225. package/dot_config/lazygit/config.yml +35 -0
  226. package/dot_config/mako/config +47 -0
  227. package/dot_config/mas/masapps.txt +5 -0
  228. package/dot_config/micro/settings.json +3 -0
  229. package/dot_config/mimeapps.list +77 -0
  230. package/dot_config/minikube/config.json +13 -0
  231. package/dot_config/mise/config.toml +99 -0
  232. package/dot_config/mongosh/mongoshrc.js +68 -0
  233. package/dot_config/mpv/input.conf +47 -0
  234. package/dot_config/mpv/mpv.conf +47 -0
  235. package/dot_config/mycli/myclirc +67 -0
  236. package/dot_config/nano/nanorc +28 -0
  237. package/dot_config/ncdu/config +12 -0
  238. package/dot_config/niri/config.kdl.tmpl +327 -0
  239. package/dot_config/nushell/aliases.nu +18 -0
  240. package/dot_config/nushell/cached_eval.nu +80 -0
  241. package/dot_config/nushell/completions.nu.tmpl +52 -0
  242. package/dot_config/nushell/config.nu.tmpl +86 -0
  243. package/dot_config/nushell/env.nu.tmpl +102 -0
  244. package/dot_config/nushell/functions.nu.tmpl +17 -0
  245. package/dot_config/nvim/init.lua +18 -0
  246. package/dot_config/nvim/lazy-lock.json +58 -0
  247. package/dot_config/nvim/lua/config/autocmds.lua +107 -0
  248. package/dot_config/nvim/lua/config/keymaps.lua +92 -0
  249. package/dot_config/nvim/lua/config/lazy.lua +44 -0
  250. package/dot_config/nvim/lua/config/options.lua +49 -0
  251. package/dot_config/nvim/lua/plugins/ai.lua +75 -0
  252. package/dot_config/nvim/lua/plugins/coding.lua +216 -0
  253. package/dot_config/nvim/lua/plugins/completion.lua +60 -0
  254. package/dot_config/nvim/lua/plugins/dap.lua +412 -0
  255. package/dot_config/nvim/lua/plugins/editor.lua +55 -0
  256. package/dot_config/nvim/lua/plugins/git.lua +10 -0
  257. package/dot_config/nvim/lua/plugins/lsp.lua +156 -0
  258. package/dot_config/nvim/lua/plugins/markdown.lua +18 -0
  259. package/dot_config/nvim/lua/plugins/rust.lua +34 -0
  260. package/dot_config/nvim/lua/plugins/sessions.lua +33 -0
  261. package/dot_config/nvim/lua/plugins/ui.lua +509 -0
  262. package/dot_config/paru/paru.conf +10 -0
  263. package/dot_config/pip/pip.conf.tmpl +32 -0
  264. package/dot_config/powershell/Microsoft.PowerShell_profile.ps1.tmpl +81 -0
  265. package/dot_config/pueue/pueue.yml +34 -0
  266. package/dot_config/pypoetry/config.toml +6 -0
  267. package/dot_config/pyrightconfig.json +5 -0
  268. package/dot_config/raycast/README.md +13 -0
  269. package/dot_config/redis/redisclirc +41 -0
  270. package/dot_config/ripgrep/ripgreprc +21 -0
  271. package/dot_config/shell/00-core-paths.sh.tmpl +134 -0
  272. package/dot_config/shell/05-core-safety.sh +48 -0
  273. package/dot_config/shell/10-secrets.sh +41 -0
  274. package/dot_config/shell/40-fzf-defaults.sh.tmpl +17 -0
  275. package/dot_config/shell/40-ls-colors.sh +49 -0
  276. package/dot_config/shell/50-logic-functions-core.sh.tmpl +11 -0
  277. package/dot_config/shell/50-logic-functions.sh.tmpl +11 -0
  278. package/dot_config/shell/51-logic-functions-extra.sh.tmpl +65 -0
  279. package/dot_config/shell/90-ux-aliases.sh.tmpl +121 -0
  280. package/dot_config/shell/91-ux-aliases-lazy.sh.tmpl +55 -0
  281. package/dot_config/shell/Brewfile +207 -0
  282. package/dot_config/shell/Brewfile.cask +92 -0
  283. package/dot_config/shell/Brewfile.cli +127 -0
  284. package/dot_config/shell/README.md +284 -0
  285. package/dot_config/shell/als_data.txt.tmpl +65 -0
  286. package/dot_config/shell/custom/auto_ls.zsh +20 -0
  287. package/dot_config/shell/custom/context_suggest.zsh +68 -0
  288. package/dot_config/shell/custom/error_analysis.zsh +45 -0
  289. package/dot_config/sops/dot_sops.yaml +23 -0
  290. package/dot_config/starship.toml.tmpl +202 -0
  291. package/dot_config/swaylock/config +43 -0
  292. package/dot_config/systemd/user/dotfiles-maintenance.service +8 -0
  293. package/dot_config/systemd/user/dotfiles-maintenance.timer +11 -0
  294. package/dot_config/systemd/user/pueued.service +12 -0
  295. package/dot_config/systemd/user/ssh-agent.service +12 -0
  296. package/dot_config/task/Taskfile.yml +86 -0
  297. package/dot_config/tflint/tflint.hcl +9 -0
  298. package/dot_config/tmux/tmux.conf.tmpl +223 -0
  299. package/dot_config/topgrade.toml.tmpl +54 -0
  300. package/dot_config/user-dirs.dirs +10 -0
  301. package/dot_config/vscode/extensions.txt +11 -0
  302. package/dot_config/vscode/settings.json.tmpl +82 -0
  303. package/dot_config/waybar/config.jsonc.tmpl +90 -0
  304. package/dot_config/waybar/style.css.tmpl +211 -0
  305. package/dot_config/wezterm/wezterm.lua.tmpl +64 -0
  306. package/dot_config/wget/wgetrc +12 -0
  307. package/dot_config/xdg-desktop-portal/niri-portals.conf +5 -0
  308. package/dot_config/yarn/yarnrc.yml +36 -0
  309. package/dot_config/yazi/keymap.toml +67 -0
  310. package/dot_config/yazi/theme.toml +102 -0
  311. package/dot_config/yazi/yazi.toml +40 -0
  312. package/dot_config/zathura/zathurarc +52 -0
  313. package/dot_config/zellij/config.kdl.tmpl +79 -0
  314. package/dot_config/zsh/dot_zprofile +7 -0
  315. package/dot_config/zsh/dot_zshenv +5 -0
  316. package/dot_config/zsh/dot_zshrc.tmpl +635 -0
  317. package/dot_config/zsh/rc.d/00-alias-shims.zsh +99 -0
  318. package/dot_config/zsh/rc.d/05-ssh-agent.zsh +18 -0
  319. package/dot_config/zsh/rc.d/10-env.zsh.tmpl +28 -0
  320. package/dot_config/zsh/rc.d/20-zinit.zsh +65 -0
  321. package/dot_config/zsh/rc.d/30-options.zsh.tmpl +214 -0
  322. package/dot_config/zsh/rc.d/40-bell.zsh +20 -0
  323. package/dot_config/zsh/rc.d/50-login-fortune.zsh +9 -0
  324. package/dot_config/zsh/rc.d/99-alias-wrapper.zsh +32 -0
  325. package/dot_local/bin/executable_ai-update +195 -0
  326. package/dot_local/bin/executable_ai_core +152 -0
  327. package/dot_local/bin/executable_antigravity +11 -0
  328. package/dot_local/bin/executable_b64 +84 -0
  329. package/dot_local/bin/executable_bm +79 -0
  330. package/dot_local/bin/executable_cb +39 -0
  331. package/dot_local/bin/executable_dot +596 -0
  332. package/dot_local/bin/executable_dot-ai +36 -0
  333. package/dot_local/bin/executable_dot-bootstrap +77 -0
  334. package/dot_local/bin/executable_dot-launch-or-focus +52 -0
  335. package/dot_local/bin/executable_dot-load-benchmark +31 -0
  336. package/dot_local/bin/executable_dot-load-benchmark-pty +77 -0
  337. package/dot_local/bin/executable_dot-theme-sync +952 -0
  338. package/dot_local/bin/executable_dot_completion +57 -0
  339. package/dot_local/bin/executable_dtags +28 -0
  340. package/dot_local/bin/executable_epoch +67 -0
  341. package/dot_local/bin/executable_extract +41 -0
  342. package/dot_local/bin/executable_gbd +52 -0
  343. package/dot_local/bin/executable_gd +42 -0
  344. package/dot_local/bin/executable_git-ai-commit +175 -0
  345. package/dot_local/bin/executable_git-ai-diff +169 -0
  346. package/dot_local/bin/executable_gl +101 -0
  347. package/dot_local/bin/executable_hash +161 -0
  348. package/dot_local/bin/executable_hashsum +160 -0
  349. package/dot_local/bin/executable_hex +115 -0
  350. package/dot_local/bin/executable_jsonv +78 -0
  351. package/dot_local/bin/executable_jwt +94 -0
  352. package/dot_local/bin/executable_kill-port +75 -0
  353. package/dot_local/bin/executable_lorem +118 -0
  354. package/dot_local/bin/executable_mkscript +35 -0
  355. package/dot_local/bin/executable_monitor +56 -0
  356. package/dot_local/bin/executable_myip +51 -0
  357. package/dot_local/bin/executable_notify +24 -0
  358. package/dot_local/bin/executable_open +38 -0
  359. package/dot_local/bin/executable_pw +27 -0
  360. package/dot_local/bin/executable_rec-start +46 -0
  361. package/dot_local/bin/executable_rec-stop +35 -0
  362. package/dot_local/bin/executable_regex +132 -0
  363. package/dot_local/bin/executable_start-niri +8 -0
  364. package/dot_local/bin/executable_tmux-sessionizer +314 -0
  365. package/dot_local/bin/executable_tour +177 -0
  366. package/dot_local/bin/executable_up +23 -0
  367. package/dot_local/bin/executable_update +142 -0
  368. package/dot_local/bin/executable_uuid +87 -0
  369. package/dot_local/bin/executable_win +32 -0
  370. package/dot_local/bin/executable_yamlv +57 -0
  371. package/dot_local/share/bash-completion/completions/dot +72 -0
  372. package/dot_local/share/icons/hicolor/128x128/apps/rousseau.png +0 -0
  373. package/dot_local/share/icons/hicolor/16x16/apps/rousseau.png +0 -0
  374. package/dot_local/share/icons/hicolor/24x24/apps/rousseau.png +0 -0
  375. package/dot_local/share/icons/hicolor/256x256/apps/rousseau.png +0 -0
  376. package/dot_local/share/icons/hicolor/32x32/apps/rousseau.png +0 -0
  377. package/dot_local/share/icons/hicolor/48x48/apps/rousseau.png +0 -0
  378. package/dot_local/share/icons/hicolor/512x512/apps/rousseau.png +0 -0
  379. package/dot_local/share/icons/hicolor/64x64/apps/rousseau.png +0 -0
  380. package/dot_local/share/icons/hicolor/96x96/apps/rousseau.png +0 -0
  381. package/dot_local/share/icons/hicolor/scalable/apps/rousseau.png +0 -0
  382. package/dot_local/share/man/man1/dot.1 +149 -0
  383. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_download +64 -0
  384. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_install +18 -0
  385. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_list-all +13 -0
  386. package/dot_local/share/wayland-sessions/niri.desktop.tmpl +6 -0
  387. package/dot_local/share/zsh/completions/.keep +0 -0
  388. package/dot_local/share/zsh/completions/_dot +283 -0
  389. package/install.sh +350 -0
  390. package/package.json +1 -1
  391. package/scripts/ci/check-copyright-headers.sh +96 -0
  392. package/scripts/ci/check-dangerous-chmod.sh +19 -0
  393. package/scripts/ci/check-deps-dev.sh +236 -0
  394. package/scripts/ci/check-insecure-tls.sh +61 -0
  395. package/scripts/ci/check-regression-traceability.sh +67 -0
  396. package/scripts/ci/check-shell-preamble.sh +106 -0
  397. package/scripts/ci/guard-gitleaks-checkout.sh +57 -0
  398. package/scripts/ci/install-chezmoi-verified.sh +64 -0
  399. package/scripts/ci/run-coverage.sh +362 -0
  400. package/scripts/ci/validate-chezmoidata.sh +25 -0
  401. package/scripts/ci/validate-ci-config.sh +224 -0
  402. package/scripts/demo/record.sh +42 -0
  403. package/scripts/diagnostics/a2a-conformance.sh +162 -0
  404. package/scripts/diagnostics/alias-governance.sh +137 -0
  405. package/scripts/diagnostics/aliases-cheatsheet.sh +73 -0
  406. package/scripts/diagnostics/aliases-manifest.sh +31 -0
  407. package/scripts/diagnostics/benchmark.sh +381 -0
  408. package/scripts/diagnostics/conflicts.sh +72 -0
  409. package/scripts/diagnostics/doctor-unified.sh +38 -0
  410. package/scripts/diagnostics/doctor.sh +709 -0
  411. package/scripts/diagnostics/drift-dashboard.sh +201 -0
  412. package/scripts/diagnostics/health.sh +614 -0
  413. package/scripts/diagnostics/history-analysis.sh +85 -0
  414. package/scripts/diagnostics/mcp-doctor.sh +575 -0
  415. package/scripts/diagnostics/perf.sh +452 -0
  416. package/scripts/diagnostics/scorecard.sh +118 -0
  417. package/scripts/diagnostics/secret-governance.sh +58 -0
  418. package/scripts/diagnostics/security-score.sh +438 -0
  419. package/scripts/diagnostics/smoke-test.sh +87 -0
  420. package/scripts/diagnostics/snapshot.sh +89 -0
  421. package/scripts/diagnostics/verify.sh +107 -0
  422. package/scripts/{verify_state.sh → diagnostics/verify_state.sh} +22 -22
  423. package/scripts/diagnostics/version-locks.sh +79 -0
  424. package/scripts/diagnostics/workstation-attestation.sh +186 -0
  425. package/scripts/docs/build-manual.sh +883 -0
  426. package/scripts/docs/check-manual.sh +213 -0
  427. package/scripts/dot/commands/agent.sh +474 -0
  428. package/scripts/dot/commands/ai.sh +481 -0
  429. package/scripts/dot/commands/aliases.sh +250 -0
  430. package/scripts/dot/commands/appearance.sh +80 -0
  431. package/scripts/dot/commands/core.sh +185 -0
  432. package/scripts/dot/commands/diagnostics.sh +229 -0
  433. package/scripts/dot/commands/fleet.sh +399 -0
  434. package/scripts/dot/commands/lint.sh +177 -0
  435. package/scripts/dot/commands/manual.sh +168 -0
  436. package/scripts/dot/commands/meta.sh +248 -0
  437. package/scripts/dot/commands/patterns.sh +54 -0
  438. package/scripts/dot/commands/restore.sh +231 -0
  439. package/scripts/dot/commands/secrets.sh +223 -0
  440. package/scripts/dot/commands/security.sh +76 -0
  441. package/scripts/dot/commands/tools.sh +469 -0
  442. package/scripts/dot/data/alias-deprecations.tsv +2 -0
  443. package/scripts/dot/lib/bento.sh +50 -0
  444. package/scripts/dot/lib/log.sh +200 -0
  445. package/scripts/dot/lib/platform.sh +99 -0
  446. package/scripts/dot/lib/ui.sh +518 -0
  447. package/scripts/dot/lib/utils.sh +377 -0
  448. package/scripts/fonts/install-nerd-fonts.sh +68 -0
  449. package/scripts/fonts/patch-fonts.sh +35 -0
  450. package/scripts/git-hooks/install.sh +11 -0
  451. package/scripts/git-hooks/pre-commit +12 -0
  452. package/scripts/git-hooks/pre-commit-audit.sh +145 -0
  453. package/scripts/git-hooks/pre-push +92 -0
  454. package/scripts/git-hooks/prepare-commit-msg +29 -0
  455. package/scripts/lib/secrets_provider.sh +158 -0
  456. package/scripts/maintenance/check-updates.sh +131 -0
  457. package/scripts/ops/ai-setup.sh +55 -0
  458. package/scripts/ops/bundle.sh +77 -0
  459. package/scripts/ops/chaos.sh +49 -0
  460. package/scripts/ops/chezmoi-apply.sh +270 -0
  461. package/scripts/ops/chezmoi-diff.sh +15 -0
  462. package/scripts/ops/chezmoi-remove.sh +45 -0
  463. package/scripts/ops/chezmoi-update.sh +48 -0
  464. package/scripts/ops/heal-chezmoi.sh +86 -0
  465. package/scripts/ops/heal-system.sh +128 -0
  466. package/scripts/ops/heal-tools.sh +340 -0
  467. package/scripts/ops/heal.sh +222 -0
  468. package/scripts/ops/post-apply-repair.sh +106 -0
  469. package/scripts/ops/prewarm.sh +127 -0
  470. package/scripts/ops/release.sh +252 -0
  471. package/scripts/ops/rollback.sh +589 -0
  472. package/scripts/ops/setup.sh +137 -0
  473. package/scripts/ops/teleport.sh +33 -0
  474. package/scripts/qa/coverage-baseline.sh +60 -0
  475. package/scripts/qa/docs-coverage.sh +111 -0
  476. package/scripts/qa/powershell-contract.ps1 +95 -0
  477. package/scripts/qa/reliability-audit.sh +138 -0
  478. package/scripts/qa/traceability-coverage.sh +116 -0
  479. package/scripts/qa/validate-examples.sh +26 -0
  480. package/scripts/qa/wsl-contract.sh +11 -0
  481. package/scripts/release/package-policy-bundles.sh +125 -0
  482. package/scripts/secrets/age-init.sh +70 -0
  483. package/scripts/secrets/create-secrets-file.sh +45 -0
  484. package/scripts/secrets/encrypt-ssh-key.sh +43 -0
  485. package/scripts/security/backup.sh +57 -0
  486. package/scripts/security/dns-doh.sh +51 -0
  487. package/scripts/security/encryption-check.sh +54 -0
  488. package/scripts/security/enforce-policies.sh +334 -0
  489. package/scripts/security/firewall.sh +90 -0
  490. package/scripts/security/lock-configs.sh +57 -0
  491. package/scripts/security/lock-screen.sh +55 -0
  492. package/scripts/security/manage-secrets.sh +428 -0
  493. package/scripts/security/ssh-cert.sh +203 -0
  494. package/scripts/security/telemetry-kill.sh +50 -0
  495. package/scripts/security/usb-safety.sh +51 -0
  496. package/scripts/theme/apply-gnome-theme.sh +328 -0
  497. package/scripts/theme/extract-theme.py +677 -0
  498. package/scripts/theme/install-boot-logo.sh +62 -0
  499. package/scripts/theme/install-catppuccin-themes.sh +370 -0
  500. package/scripts/theme/install-cursors.sh +25 -0
  501. package/scripts/theme/install-file-icons.sh +26 -0
  502. package/scripts/theme/install-grub-theme.sh +61 -0
  503. package/scripts/theme/install-lock-icon.sh +30 -0
  504. package/scripts/theme/merge-wallpaper.sh +145 -0
  505. package/scripts/theme/rebuild-themes.sh +309 -0
  506. package/scripts/theme/switch.sh +431 -0
  507. package/scripts/theme/wallpaper-rotate.sh +136 -0
  508. package/scripts/theme/wallpaper-sync.sh +397 -0
  509. package/scripts/tools/cmatrix.sh +21 -0
  510. package/scripts/{detect-collisions.py → tools/detect-collisions.py} +2 -2
  511. package/scripts/tools/emoji-picker.sh +48 -0
  512. package/scripts/tools/figlet-banner.sh +18 -0
  513. package/scripts/tools/log-rotate.sh +30 -0
  514. package/scripts/tools/lolcat-wrap.sh +19 -0
  515. package/scripts/tools/pipes.sh +48 -0
  516. package/scripts/tuning/linux.sh +185 -0
  517. package/scripts/tuning/macos.sh +55 -0
  518. package/scripts/uninstall.sh +85 -0
  519. package/scripts/version-sync.sh +487 -0
  520. package/templates/chezmoi-data/geekom-a9.toml.example +21 -0
  521. package/templates/chezmoi-data/mac-m1.toml.example +16 -0
  522. package/templates/chezmoi-data/mac-t2-linux.toml.example +21 -0
  523. package/templates/chezmoi-data/surface-pro-7p.toml.example +21 -0
  524. package/templates/projects/go/.github/workflows/ci.yml +31 -0
  525. package/templates/projects/go/README.md +4 -0
  526. package/templates/projects/go/cmd/__PROJECT_NAME__/main.go +1 -0
  527. package/templates/projects/go/go.sum +0 -0
  528. package/templates/projects/molecule/README.md +7 -0
  529. package/templates/projects/molecule/converge.yml +7 -0
  530. package/templates/projects/molecule/molecule.yml +16 -0
  531. package/templates/projects/node/.github/workflows/ci.yml +30 -0
  532. package/templates/projects/node/README.md +4 -0
  533. package/templates/projects/node/package-lock.json +12 -0
  534. package/templates/projects/node/src/index.js +1 -0
  535. package/templates/projects/packer/README.md +15 -0
  536. package/templates/projects/packer/main.pkr.hcl +15 -0
  537. package/templates/projects/python/.github/workflows/ci.yml +34 -0
  538. package/templates/projects/python/README.md +4 -0
  539. package/templates/projects/python/pyproject.toml +15 -0
  540. package/templates/projects/python/src/__PROJECT_NAME__/__init__.py +1 -0
  541. package/templates/projects/python/tests/test_basic.py +1 -0
  542. package/docs/ARCHITECTURE.md +0 -62
  543. package/docs/COMPLIANCE.md +0 -47
  544. package/docs/OPERATIONS.md +0 -103
  545. package/docs/PR_DESCRIPTION.md +0 -150
  546. package/docs/ROADMAP_legacy.md +0 -556
  547. package/docs/SECURITY_CHECKLIST.md +0 -25
  548. package/docs/TASK.md +0 -99
  549. package/docs/WALKTHROUGH.md +0 -46
  550. package/scripts/backup.sh +0 -142
  551. package/scripts/banner.sh +0 -20
  552. package/scripts/benchmark.sh +0 -20
  553. package/scripts/build.sh +0 -41
  554. package/scripts/clean.sh +0 -31
  555. package/scripts/compile.sh +0 -54
  556. package/scripts/copy.sh +0 -108
  557. package/scripts/doctor.sh +0 -79
  558. package/scripts/dotfiles.sh +0 -63
  559. package/scripts/download.sh +0 -35
  560. package/scripts/help.sh +0 -57
  561. package/scripts/lock-configs.sh +0 -57
  562. package/scripts/package.sh +0 -46
  563. package/scripts/ssh.sh +0 -55
  564. package/scripts/teleport.sh +0 -23
  565. package/scripts/test-aliases.sh +0 -25
  566. package/scripts/test_smoke.sh +0 -88
  567. package/scripts/unpack.sh +0 -28
@@ -0,0 +1,614 @@
1
+ #!/usr/bin/env bash
2
+ # Copyright (c) 2015-2026 Dotfiles. All rights reserved.
3
+ # Dotfiles Health Check Dashboard
4
+ # Usage: dot health [--verbose|-v] [--json|-j] [--fix|-f] [--force|-F]
5
+
6
+ set -euo pipefail
7
+
8
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
+ # shellcheck source=../dot/lib/ui.sh
10
+ # shellcheck disable=SC1091
11
+ source "$SCRIPT_DIR/../dot/lib/ui.sh"
12
+ # shellcheck source=../dot/lib/log.sh
13
+ # shellcheck disable=SC1091
14
+ source "$SCRIPT_DIR/../dot/lib/log.sh"
15
+
16
+ # Portable has_command (self-contained; no dependency on utils.sh)
17
+ has_command() { command -v "$1" >/dev/null 2>&1; }
18
+
19
+ # Colors (fallback when gum is unavailable; respect NO_COLOR)
20
+ if [[ -z "${NO_COLOR:-}" ]] && [[ -t 1 ]]; then
21
+ RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m'
22
+ BLUE='\033[0;34m' CYAN='\033[0;36m' GRAY='\033[0;90m' NC='\033[0m'
23
+ else
24
+ RED='' GREEN='' YELLOW='' BLUE='' CYAN='' GRAY='' NC=''
25
+ fi
26
+
27
+ # Parse arguments (VERBOSE exported for potential use by sourced scripts)
28
+ export VERBOSE=false
29
+ JSON_OUTPUT=false
30
+ APPLY_FIX=false
31
+ FORCE_FIX=false
32
+ while [[ $# -gt 0 ]]; do
33
+ case "$1" in
34
+ --verbose | -v)
35
+ VERBOSE=true
36
+ shift
37
+ ;;
38
+ --fix | -f)
39
+ APPLY_FIX=true
40
+ shift
41
+ ;;
42
+ --force | -F)
43
+ FORCE_FIX=true
44
+ shift
45
+ ;;
46
+ --json | -j)
47
+ JSON_OUTPUT=true
48
+ shift
49
+ ;;
50
+ *) shift ;;
51
+ esac
52
+ done
53
+
54
+ reset_stats() {
55
+ TOTAL_CHECKS=0
56
+ PASSED_CHECKS=0
57
+ WARNINGS=0
58
+ FAILURES=0
59
+ }
60
+
61
+ # Health check results
62
+ TOTAL_CHECKS=0
63
+ PASSED_CHECKS=0
64
+ WARNINGS=0
65
+ FAILURES=0
66
+ declare -a RESULTS=()
67
+ ui_init
68
+ use_ui="$UI_ENABLED"
69
+
70
+ header() {
71
+ local text="$1"
72
+ if $JSON_OUTPUT; then
73
+ return
74
+ fi
75
+ if [[ "$use_ui" = "1" ]]; then
76
+ ui_header "$text"
77
+ else
78
+ printf '%b\n' "${CYAN}${text}${NC}"
79
+ fi
80
+ }
81
+
82
+ section() {
83
+ local text="$1"
84
+ if $JSON_OUTPUT; then
85
+ return
86
+ fi
87
+ if [[ "$use_ui" = "1" ]]; then
88
+ ui_section "$text"
89
+ else
90
+ printf '%b\n' "\n${BLUE}▸ $text${NC}"
91
+ fi
92
+ }
93
+
94
+ check() {
95
+ local name="$1"
96
+ local status="$2"
97
+ local message="${3:-}"
98
+
99
+ TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
100
+
101
+ # Collect structured result for JSON output (escape quotes for valid JSON)
102
+ local _j_name="${name//\"/\\\"}"
103
+ local _j_status="${status//\"/\\\"}"
104
+ local _j_message="${message//\"/\\\"}"
105
+ RESULTS+=("{\"check\":\"${_j_name}\",\"status\":\"${_j_status}\",\"message\":\"${_j_message}\"}")
106
+
107
+ case "$status" in
108
+ pass)
109
+ PASSED_CHECKS=$((PASSED_CHECKS + 1))
110
+ # shellcheck disable=SC2034
111
+ if ! $JSON_OUTPUT; then
112
+ if [[ "$use_ui" = "1" ]]; then
113
+ ui_ok "$name"
114
+ else
115
+ printf "${GREEN}✓${NC} %-35s ${GREEN}OK${NC}\n" "$name"
116
+ fi
117
+ fi
118
+ ;;
119
+ warn)
120
+ WARNINGS=$((WARNINGS + 1))
121
+ # shellcheck disable=SC2034
122
+ if ! $JSON_OUTPUT; then
123
+ if [[ "$use_ui" = "1" ]]; then
124
+ ui_warn "$name" "$message"
125
+ else
126
+ printf "${YELLOW}⚠${NC} %-35s ${YELLOW}WARNING${NC}"
127
+ [[ -n "$message" ]] && printf " ${GRAY}%s${NC}" "$message"
128
+ printf "\n"
129
+ fi
130
+ fi
131
+ ;;
132
+ fail)
133
+ FAILURES=$((FAILURES + 1))
134
+ # shellcheck disable=SC2034
135
+ if ! $JSON_OUTPUT; then
136
+ if [[ "$use_ui" = "1" ]]; then
137
+ ui_err "$name" "$message"
138
+ else
139
+ printf "${RED}✗${NC} %-35s ${RED}FAILED${NC}"
140
+ [[ -n "$message" ]] && printf " ${GRAY}%s${NC}" "$message"
141
+ printf "\n"
142
+ fi
143
+ fi
144
+ ;;
145
+ esac
146
+ }
147
+
148
+ print_header() {
149
+ if ! $JSON_OUTPUT; then
150
+ echo ""
151
+ ui_dot_banner "Diagnostics"
152
+ header "Dotfiles Health Dashboard"
153
+ echo ""
154
+ fi
155
+ }
156
+
157
+ check_section() {
158
+ if ! $JSON_OUTPUT; then
159
+ echo ""
160
+ section "$1"
161
+ if [[ "$use_ui" = "1" ]]; then
162
+ :
163
+ else
164
+ echo "───────────────────────────────────────────────"
165
+ fi
166
+ fi
167
+ }
168
+
169
+ # === Focused check sub-functions ===
170
+
171
+ check_dotfiles_core() {
172
+ check_section "Dotfiles Core"
173
+
174
+ if has_command chezmoi; then
175
+ check "Chezmoi installed" "pass"
176
+ if [[ -d "${HOME}/.local/share/chezmoi" ]] || [[ -d "${HOME}/.dotfiles" ]]; then
177
+ check "Chezmoi source directory" "pass"
178
+ else
179
+ check "Chezmoi source directory" "fail" "Not found"
180
+ fi
181
+ else
182
+ check "Chezmoi installed" "fail" "Not installed"
183
+ fi
184
+
185
+ if has_command git; then
186
+ check "Git installed" "pass"
187
+ if git config user.email >/dev/null 2>&1; then
188
+ check "Git user configured" "pass"
189
+ else
190
+ check "Git user configured" "warn" "Email not set"
191
+ fi
192
+ else
193
+ check "Git installed" "fail"
194
+ fi
195
+ }
196
+
197
+ check_shell_env() {
198
+ check_section "Shell Environment"
199
+ local current_shell="${SHELL##*/}"
200
+
201
+ if has_command zsh; then
202
+ check "Zsh installed" "pass"
203
+ if [[ "$current_shell" =~ ^(zsh|fish|bash|nu|nushell)$ ]]; then
204
+ check "Active shell" "pass" "$current_shell"
205
+ else
206
+ check "Active shell" "warn" "Current: $SHELL"
207
+ fi
208
+ else
209
+ check "Zsh installed" "fail"
210
+ fi
211
+
212
+ if [[ -d "${ZINIT_HOME:-$HOME/.local/share/zinit}" ]]; then
213
+ check "Zinit plugin manager" "pass"
214
+ elif [[ "$current_shell" == "zsh" ]]; then
215
+ check "Zinit plugin manager" "warn" "Not found"
216
+ else
217
+ check "Zinit plugin manager" "pass" "Not required for $current_shell"
218
+ fi
219
+
220
+ if has_command starship; then
221
+ check "Starship prompt" "pass"
222
+ else
223
+ check "Starship prompt" "warn" "Not installed"
224
+ fi
225
+ }
226
+
227
+ check_dev_tools() {
228
+ check_section "Development Tools"
229
+
230
+ if has_command node; then
231
+ local node_version
232
+ node_version=$(node --version 2>/dev/null)
233
+ check "Node.js ($node_version)" "pass"
234
+ else
235
+ check "Node.js" "warn" "Not installed"
236
+ fi
237
+
238
+ if has_command fnm; then
239
+ check "fnm (Node version manager)" "pass"
240
+ elif has_command mise && has_command node; then
241
+ check "Node version manager" "pass" "mise"
242
+ else
243
+ check "fnm" "warn" "Not installed"
244
+ fi
245
+
246
+ if has_command python3; then
247
+ local py_version
248
+ py_version=$(python3 --version 2>/dev/null | cut -d' ' -f2)
249
+ check "Python ($py_version)" "pass"
250
+ else
251
+ check "Python" "warn" "Not installed"
252
+ fi
253
+
254
+ if has_command rustc; then
255
+ check "Rust toolchain" "pass"
256
+ else
257
+ check "Rust toolchain" "warn" "Not installed"
258
+ fi
259
+
260
+ if has_command go; then
261
+ check "Go" "pass"
262
+ else
263
+ check "Go" "warn" "Not installed"
264
+ fi
265
+ }
266
+
267
+ check_cli_tools() {
268
+ check_section "CLI Tools"
269
+
270
+ local tools=("fzf" "ripgrep:rg" "fd" "bat" "eza" "zoxide" "atuin" "delta" "jq" "yq" "sops" "mise" "just" "zellij" "hyperfine")
271
+ for tool in "${tools[@]}"; do
272
+ local name="${tool%%:*}"
273
+ local cmd="${tool##*:}"
274
+ if has_command "$cmd"; then
275
+ check "$name" "pass"
276
+ else
277
+ check "$name" "warn" "Not installed"
278
+ fi
279
+ done
280
+ }
281
+
282
+ check_editors() {
283
+ check_section "Editors"
284
+
285
+ if has_command nvim; then
286
+ check "Neovim" "pass"
287
+ if [[ -d "${XDG_DATA_HOME:-$HOME/.local/share}/nvim/lazy" ]]; then
288
+ check "Neovim plugins (lazy.nvim)" "pass"
289
+ else
290
+ check "Neovim plugins" "warn" "Lazy.nvim not found"
291
+ fi
292
+ else
293
+ check "Neovim" "warn" "Not installed"
294
+ fi
295
+ }
296
+
297
+ check_terminal() {
298
+ check_section "Terminal"
299
+
300
+ if has_command ghostty || [[ -d "/Applications/Ghostty.app" ]]; then
301
+ check "Ghostty terminal" "pass"
302
+ else
303
+ check "Ghostty terminal" "warn" "Not installed"
304
+ fi
305
+
306
+ local font_found=false
307
+ if command -v fc-list >/dev/null 2>&1; then
308
+ local fc_list_output=""
309
+ fc_list_output="$(fc-list 2>/dev/null || true)"
310
+ if [[ "$fc_list_output" == *"Nerd Font"* ]]; then
311
+ font_found=true
312
+ fi
313
+ fi
314
+ if [[ "$font_found" != true ]] && [[ -d "$HOME/Library/Fonts" ]] && compgen -G "$HOME/Library/Fonts/"'*Nerd*' >/dev/null 2>&1; then
315
+ font_found=true
316
+ elif [[ "$font_found" != true ]] && [[ -d "$HOME/.local/share/fonts" ]] && compgen -G "$HOME/.local/share/fonts/"'*Nerd*' >/dev/null 2>&1; then
317
+ font_found=true
318
+ fi
319
+
320
+ if $font_found; then
321
+ check "Nerd Font available" "pass"
322
+ else
323
+ check "Nerd Font available" "warn" "Not installed"
324
+ fi
325
+ }
326
+
327
+ check_security() {
328
+ check_section "Security"
329
+
330
+ if has_command age; then
331
+ check "Age encryption" "pass"
332
+ if [[ -f "${HOME}/.config/chezmoi/key.txt" ]]; then
333
+ check "Age key configured" "pass"
334
+ else
335
+ check "Age key configured" "warn" "Key not found"
336
+ fi
337
+ else
338
+ check "Age encryption" "warn" "Not installed"
339
+ fi
340
+
341
+ if [[ -f "${HOME}/.ssh/id_ed25519" ]] || [[ -f "${HOME}/.ssh/id_rsa" ]]; then
342
+ check "SSH keys present" "pass"
343
+ else
344
+ check "SSH keys present" "warn" "No keys found"
345
+ fi
346
+
347
+ # Check SSH key permissions
348
+ for key in "$HOME/.ssh/id_ed25519" "$HOME/.ssh/id_rsa" "$HOME/.ssh/id_ed25519_sk"; do
349
+ if [[ -f "$key" ]]; then
350
+ local perms
351
+ perms=$(stat -c '%a' "$key" 2>/dev/null || stat -f '%Lp' "$key" 2>/dev/null)
352
+ if [[ "$perms" != "600" && "$perms" != "400" ]]; then
353
+ check "SSH key perms (${key##*/})" "warn" "mode $perms (should be 600)"
354
+ else
355
+ check "SSH key perms (${key##*/})" "pass"
356
+ fi
357
+ fi
358
+ done
359
+
360
+ if has_command gpg; then
361
+ local signing_format signing_key allowed_signers
362
+ signing_format="$(git config --global gpg.format 2>/dev/null || true)"
363
+ signing_key="$(git config --global user.signingkey 2>/dev/null || true)"
364
+ allowed_signers="$(git config --global gpg.ssh.allowedSignersFile 2>/dev/null || echo "$HOME/.config/git/allowed_signers")"
365
+
366
+ if [[ "$signing_format" == "ssh" ]] && [[ -n "$signing_key" ]] && [[ -f "${signing_key/#\~/$HOME}" ]] && [[ -f "${allowed_signers/#\~/$HOME}" ]]; then
367
+ check "Git signing" "pass" "ssh"
368
+ elif gpg --list-secret-keys 2>/dev/null | grep -q sec; then
369
+ check "GPG keys" "pass"
370
+ else
371
+ check "GPG keys" "warn" "No secret keys"
372
+ fi
373
+ else
374
+ check "GPG" "warn" "Not installed"
375
+ fi
376
+ }
377
+
378
+ check_performance() {
379
+ check_section "Performance"
380
+
381
+ if has_command zsh; then
382
+ local startup_time
383
+ startup_time=$({ time zsh -i -c exit; } 2>&1 | grep real | awk '{print $2}' | sed 's/[ms]//g')
384
+ if [[ -n "$startup_time" ]]; then
385
+ check "Shell startup time" "pass"
386
+ else
387
+ check "Shell startup time" "warn" "Could not measure"
388
+ fi
389
+ fi
390
+ }
391
+
392
+ check_config_directories() {
393
+ check_section "Config Directories"
394
+
395
+ local config_dirs=(
396
+ "$HOME/.config/shell"
397
+ "$HOME/.config/nvim"
398
+ "$HOME/.config/git"
399
+ )
400
+ local found=0 total=${#config_dirs[@]}
401
+
402
+ for dir in "${config_dirs[@]}"; do
403
+ if [[ -d "$dir" ]]; then
404
+ check "Config: ${dir##*/}" "pass"
405
+ found=$((found + 1))
406
+ else
407
+ check "Config: ${dir##*/}" "warn" "Not found"
408
+ fi
409
+ done
410
+
411
+ if [[ $found -eq $total ]]; then
412
+ check "Config directories" "pass"
413
+ elif [[ $found -gt 0 ]]; then
414
+ check "Config directories" "warn" "$found/$total present"
415
+ else
416
+ check "Config directories" "fail" "None found"
417
+ fi
418
+ }
419
+
420
+ check_sync_status() {
421
+ check_section "Sync Status"
422
+
423
+ # Chezmoi status. The two-character prefix encodes both directions:
424
+ # col 1 = last-applied state vs actual (was the file edited in
425
+ # place since last apply?)
426
+ # col 2 = actual state vs target (what `chezmoi apply`
427
+ # would still change)
428
+ # Only col 2 matters for "is $HOME out of sync with the source" —
429
+ # col 1 alone just means the source repo has uncommitted edits,
430
+ # which is normal during development and not something the user
431
+ # needs warned about via the health dashboard.
432
+ if has_command chezmoi; then
433
+ local status_output
434
+ status_output=$(chezmoi status 2>/dev/null || echo "")
435
+ if [[ -z "$status_output" ]]; then
436
+ check "Chezmoi sync" "pass"
437
+ else
438
+ # Count only entries where column 2 is non-space (apply would do something).
439
+ local applicable
440
+ applicable=$(printf '%s\n' "$status_output" | awk 'substr($0,2,1)!=" "' | wc -l | tr -d ' ')
441
+ if [[ "$applicable" -eq 0 ]]; then
442
+ # All drift is source-only (unstaged edits in the source repo).
443
+ # That's not a sync issue; mention it but pass.
444
+ local source_only
445
+ source_only=$(printf '%s\n' "$status_output" | wc -l | tr -d ' ')
446
+ check "Chezmoi sync" "pass" "$source_only source-only edit(s) (run 'chezmoi diff' to inspect)"
447
+ else
448
+ check "Chezmoi sync" "warn" "$applicable file(s) out of sync"
449
+ fi
450
+ fi
451
+ else
452
+ check "Chezmoi sync" "warn" "Not installed, skipped"
453
+ fi
454
+
455
+ # Git status
456
+ local dotfiles_dir="${HOME}/.dotfiles"
457
+ if [[ -d "$dotfiles_dir/.git" ]]; then
458
+ local git_status=""
459
+ git_status=$(git -C "$dotfiles_dir" status --porcelain 2>/dev/null || echo "")
460
+ if [[ -z "$git_status" ]]; then
461
+ check "Git working tree" "pass"
462
+ else
463
+ local changes
464
+ changes=$(printf '%s\n' "$git_status" | wc -l | tr -d ' ')
465
+ check "Git working tree" "pass" "$changes local change(s)"
466
+ fi
467
+ else
468
+ check "Git working tree" "warn" "Not a git repo"
469
+ fi
470
+ }
471
+
472
+ # === Orchestrator ===
473
+ run_checks() {
474
+ check_dotfiles_core
475
+ check_shell_env
476
+ check_dev_tools
477
+ check_cli_tools
478
+ check_editors
479
+ check_terminal
480
+ check_security
481
+ check_config_directories
482
+ check_sync_status
483
+ check_performance
484
+ }
485
+
486
+ print_summary() {
487
+ local score=$((PASSED_CHECKS * 100 / TOTAL_CHECKS))
488
+
489
+ if $JSON_OUTPUT; then
490
+ printf '{\n'
491
+ printf ' "total": %d,\n' "$TOTAL_CHECKS"
492
+ printf ' "passed": %d,\n' "$PASSED_CHECKS"
493
+ printf ' "warnings": %d,\n' "$WARNINGS"
494
+ printf ' "failures": %d,\n' "$FAILURES"
495
+ printf ' "score": %d,\n' "$score"
496
+ printf ' "results": [\n'
497
+ local i=0
498
+ for result in "${RESULTS[@]}"; do
499
+ if [[ $i -gt 0 ]]; then
500
+ printf ',\n'
501
+ fi
502
+ printf ' %s' "$result"
503
+ i=$((i + 1))
504
+ done
505
+ printf '\n ]\n'
506
+ printf '}\n'
507
+ dot_log info "health_complete" "score=$score" "total=$TOTAL_CHECKS"
508
+ dot_metric "health_score" "$score" "percent"
509
+ return
510
+ fi
511
+
512
+ echo ""
513
+ header "Summary"
514
+ echo ""
515
+
516
+ if [[ "$use_ui" = "1" ]]; then
517
+ printf " %-12s %s\n" "Total checks:" "${TOTAL_CHECKS}"
518
+ printf " %-12s %s\n" "Passed:" "$(gum style --foreground 2 "$PASSED_CHECKS")"
519
+ printf " %-12s %s\n" "Warnings:" "$(gum style --foreground 3 "$WARNINGS")"
520
+ printf " %-12s %s\n" "Failures:" "$(gum style --foreground 1 "$FAILURES")"
521
+ else
522
+ printf '%b\n' " Total checks: ${TOTAL_CHECKS}"
523
+ printf '%b\n' " ${GREEN}Passed:${NC} ${PASSED_CHECKS}"
524
+ printf '%b\n' " ${YELLOW}Warnings:${NC} ${WARNINGS}"
525
+ printf '%b\n' " ${RED}Failures:${NC} ${FAILURES}"
526
+ fi
527
+ echo ""
528
+
529
+ # Health score bar
530
+ local bar_width=30
531
+ local filled=$((score * bar_width / 100))
532
+ local empty=$((bar_width - filled))
533
+ local filled_bar="" empty_bar="" i
534
+
535
+ for ((i = 0; i < filled; i++)); do
536
+ filled_bar+="${_GL_BAR_FILL}"
537
+ done
538
+ for ((i = 0; i < empty; i++)); do
539
+ empty_bar+="${_GL_BAR_EMPTY}"
540
+ done
541
+
542
+ if [[ "$use_ui" = "1" ]]; then
543
+ local bar_color
544
+ if [[ $score -ge 80 ]]; then
545
+ bar_color=2
546
+ elif [[ $score -ge 60 ]]; then
547
+ bar_color=3
548
+ else
549
+ bar_color=1
550
+ fi
551
+ printf " Health Score: [%s%s] %s%%\n\n" \
552
+ "$(gum style --foreground "$bar_color" "$filled_bar")" \
553
+ "$empty_bar" \
554
+ "$score"
555
+ else
556
+ printf " Health Score: ["
557
+ if [[ $score -ge 80 ]]; then
558
+ printf '%s' "${GREEN}"
559
+ elif [[ $score -ge 60 ]]; then
560
+ printf '%s' "${YELLOW}"
561
+ else
562
+ printf '%s' "${RED}"
563
+ fi
564
+ printf '%s' "$filled_bar"
565
+ printf '%s' "${NC}"
566
+ printf '%s' "$empty_bar"
567
+ printf "] %s%%\n\n" "${score}"
568
+ fi
569
+
570
+ if [[ $score -ge 90 ]]; then
571
+ printf '%b\n' " ${GREEN}⚡ Excellent! Your dotfiles are in great shape.${NC}"
572
+ elif [[ $score -ge 70 ]]; then
573
+ printf '%b\n' " ${GREEN}✓ Good! Minor improvements possible.${NC}"
574
+ elif [[ $score -ge 50 ]]; then
575
+ printf '%b\n' " ${YELLOW}⚠ Fair. Consider addressing warnings.${NC}"
576
+ else
577
+ printf '%b\n' " ${RED}✗ Needs attention. Multiple issues found.${NC}"
578
+ fi
579
+
580
+ echo ""
581
+ if [[ $WARNINGS -gt 0 || $FAILURES -gt 0 ]]; then
582
+ printf '%b\n' " ${CYAN}Tip:${NC} Run 'dot health --fix' to auto-repair common issues."
583
+ echo ""
584
+ fi
585
+
586
+ dot_log info "health_complete" "score=$score" "total=$TOTAL_CHECKS"
587
+ dot_metric "health_score" "$score" "percent"
588
+ }
589
+
590
+ # Main
591
+ export DOT_COMMAND="health"
592
+ print_header
593
+ run_checks
594
+ if $APPLY_FIX; then
595
+ if ! $JSON_OUTPUT; then
596
+ header "Auto-Remediation"
597
+ echo ""
598
+ fi
599
+ heal_script="$SCRIPT_DIR/../ops/heal.sh"
600
+ if [[ -f "$heal_script" ]]; then
601
+ if $FORCE_FIX; then
602
+ bash "$heal_script" --force || true
603
+ else
604
+ bash "$heal_script" || true
605
+ fi
606
+ else
607
+ if ! $JSON_OUTPUT; then
608
+ printf '%b\n' "${YELLOW}⚠${NC} heal.sh not found, skipping auto-fix."
609
+ fi
610
+ fi
611
+ reset_stats
612
+ run_checks
613
+ fi
614
+ print_summary
@@ -0,0 +1,85 @@
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
+ histfile="${HISTFILE:-$HOME/.zsh_history}"
11
+ db="${DOTFILES_HISTORY_DB:-$HOME/.local/share/dotfiles/history.sqlite}"
12
+
13
+ ui_init
14
+
15
+ if [[ ! -f "$histfile" ]]; then
16
+ ui_err "History file" "not found: $histfile" >&2
17
+ exit 1
18
+ fi
19
+
20
+ if ! command -v python3 >/dev/null; then
21
+ ui_warn "python3" "not found; falling back to hstats if available" >&2
22
+ if command -v hstats >/dev/null; then
23
+ hstats
24
+ exit 0
25
+ fi
26
+ exit 1
27
+ fi
28
+
29
+ mkdir -p "$(dirname "$db")"
30
+
31
+ ui_header "History Analysis"
32
+
33
+ python3 - "$histfile" "$db" <<'PY'
34
+ import sys
35
+ import sqlite3
36
+ import re
37
+ from pathlib import Path
38
+
39
+ histfile = Path(sys.argv[1])
40
+ db = Path(sys.argv[2])
41
+
42
+ conn = sqlite3.connect(db)
43
+ cur = conn.cursor()
44
+ cur.execute("CREATE TABLE IF NOT EXISTS history (ts INTEGER, cmd TEXT)")
45
+ cur.execute("DELETE FROM history")
46
+
47
+ pattern = re.compile(r"^: (\d+):\d+;(.*)$")
48
+
49
+ with histfile.open("r", encoding="utf-8", errors="ignore") as f:
50
+ for line in f:
51
+ line = line.rstrip("\n")
52
+ m = pattern.match(line)
53
+ if not m:
54
+ continue
55
+ ts = int(m.group(1))
56
+ cmd = m.group(2).strip()
57
+ if not cmd:
58
+ continue
59
+ cur.execute("INSERT INTO history (ts, cmd) VALUES (?, ?)", (ts, cmd))
60
+
61
+ conn.commit()
62
+
63
+ print("\nTop commands:")
64
+ for row in cur.execute("""
65
+ SELECT substr(cmd, 1, instr(cmd || ' ', ' ') - 1) AS base, COUNT(*)
66
+ FROM history
67
+ GROUP BY base
68
+ ORDER BY COUNT(*) DESC
69
+ LIMIT 15
70
+ """):
71
+ print(f"{row[1]:>6} {row[0]}")
72
+
73
+ print("\nTop directories (cd):")
74
+ for row in cur.execute("""
75
+ SELECT trim(substr(cmd, 4)) AS dir, COUNT(*)
76
+ FROM history
77
+ WHERE cmd LIKE 'cd %'
78
+ GROUP BY dir
79
+ ORDER BY COUNT(*) DESC
80
+ LIMIT 10
81
+ """):
82
+ print(f"{row[1]:>6} {row[0]}")
83
+
84
+ conn.close()
85
+ PY