@sebastienrousseau/dotfiles 0.2.499 → 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 (538) hide show
  1. package/CHANGELOG.md +375 -0
  2. package/LICENSE +1283 -0
  3. package/README.md +284 -0
  4. package/docs/.vitepress/reports/localization-readability-audit.md +69 -0
  5. package/docs/AI.md +102 -0
  6. package/docs/COPYRIGHT +4 -3
  7. package/docs/NAMING_CONVENTIONS.md +95 -0
  8. package/docs/README.md +78 -0
  9. package/docs/adr/ADR-001-ci-cd-pipeline.md +101 -0
  10. package/docs/adr/ADR-002-shell-performance.md +121 -0
  11. package/docs/adr/ADR-003-security-first.md +140 -0
  12. package/docs/adr/ADR-004-cli-architecture.md +157 -0
  13. package/docs/adr/ADR-005-chezmoi-choice.md +89 -0
  14. package/docs/adr/ADR-006-shell-selection.md +115 -0
  15. package/docs/adr/ADR-007-multi-shell-parity.md +53 -0
  16. package/docs/adr/ADR-008-alias-system-architecture.md +85 -0
  17. package/docs/adr/README.md +32 -0
  18. package/docs/architecture/ARCHITECTURE.md +113 -0
  19. package/docs/architecture/INTEROP.md +36 -0
  20. package/docs/architecture/REPO_LAYOUT.md +237 -0
  21. package/docs/architecture/WALKTHROUGH.md +82 -0
  22. package/docs/architecture/fleet-deployment.md +73 -0
  23. package/docs/archive/EUXIS_2026_REVIEW.md +119 -0
  24. package/docs/archive/LEGACY_ROADMAP.md +142 -0
  25. package/docs/archive/MILESTONE_v0.2.493.md +43 -0
  26. package/docs/{PLAN.md → archive/PLAN.md} +4 -4
  27. package/docs/archive/REPO_AUDIT.md +23 -0
  28. package/docs/guides/INSTALL.md +140 -0
  29. package/docs/guides/NEOVIM_IDE_GUIDE.md +52 -0
  30. package/docs/guides/THEMING.md +222 -0
  31. package/docs/guides/TROUBLESHOOTING.md +148 -0
  32. package/docs/guides/WSL2_NIX_TROUBLESHOOTING.md +723 -0
  33. package/docs/index.md +39 -0
  34. package/docs/interop/A2A.md +32 -0
  35. package/docs/manual/00-introduction.md +85 -0
  36. package/docs/manual/01-concepts/01-architecture.md +134 -0
  37. package/docs/manual/01-concepts/02-trust-model.md +178 -0
  38. package/docs/manual/01-concepts/03-theme-engine.md +182 -0
  39. package/docs/manual/01-concepts/04-fleet.md +142 -0
  40. package/docs/manual/01-concepts/05-self-healing.md +197 -0
  41. package/docs/manual/02-tutorials/01-first-install.md +192 -0
  42. package/docs/manual/02-tutorials/02-add-wallpaper.md +211 -0
  43. package/docs/manual/02-tutorials/03-create-profile.md +238 -0
  44. package/docs/manual/02-tutorials/04-encrypt-secret.md +275 -0
  45. package/docs/manual/02-tutorials/05-deploy-fleet.md +279 -0
  46. package/docs/manual/03-reference/01-dot-cli.md +413 -0
  47. package/docs/manual/03-reference/02-config-files.md +259 -0
  48. package/docs/manual/03-reference/03-environment.md +120 -0
  49. package/docs/manual/03-reference/04-templates.md +184 -0
  50. package/docs/manual/03-reference/05-feature-flags.md +118 -0
  51. package/docs/manual/04-cookbook/01-recipes.md +281 -0
  52. package/docs/manual/04-cookbook/02-troubleshooting.md +319 -0
  53. package/docs/manual/04-cookbook/03-faq.md +167 -0
  54. package/docs/manual/05-appendices/A-platform-matrix.md +97 -0
  55. package/docs/manual/05-appendices/B-security-checklist.md +78 -0
  56. package/docs/manual/05-appendices/C-glossary.md +36 -0
  57. package/docs/manual/05-appendices/D-bibliography.md +54 -0
  58. package/docs/manual/05-appendices/E-license.md +34 -0
  59. package/docs/manual/_toc.yml +58 -0
  60. package/docs/manual/command-index.md +58 -0
  61. package/docs/manual/concept-index.md +164 -0
  62. package/docs/operations/ATTESTATION.md +39 -0
  63. package/docs/operations/MAINTENANCE.md +59 -0
  64. package/docs/operations/MIGRATION.md +101 -0
  65. package/docs/operations/OPERATIONS.md +164 -0
  66. package/docs/operations/RELIABILITY.md +116 -0
  67. package/docs/{ROADMAP.md → operations/ROADMAP.md} +22 -22
  68. package/docs/operations/TESTING.md +195 -0
  69. package/docs/operations/TRACEABILITY.md +31 -0
  70. package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +61 -0
  71. package/docs/operations/VERSION_SYNC.md +344 -0
  72. package/docs/reference/ALIASES.md +124 -0
  73. package/docs/reference/ALIASES_CHEATSHEET.md +28 -0
  74. package/docs/reference/ALIASES_DEPRECATIONS.md +9 -0
  75. package/docs/reference/FEATURES.md +62 -0
  76. package/docs/reference/FONTS.md +108 -0
  77. package/docs/reference/PROFILES.md +65 -0
  78. package/docs/reference/SCREENSHOTS.md +117 -0
  79. package/docs/reference/SCRIPTS.md +67 -0
  80. package/docs/reference/SUPPORT_MATRIX.md +74 -0
  81. package/docs/reference/THEMES.md +113 -0
  82. package/docs/reference/TOOLS.md +105 -0
  83. package/docs/reference/UTILS.md +151 -0
  84. package/docs/security/AI_ACT_COMPLIANCE.md +90 -0
  85. package/docs/security/AUTOMATION_SECRETS.md +22 -0
  86. package/docs/security/COMPLIANCE.md +453 -0
  87. package/docs/security/ENCRYPTION.md +52 -0
  88. package/docs/security/FMEA.md +155 -0
  89. package/docs/security/INCIDENT_RESPONSE.md +575 -0
  90. package/docs/security/KEYS.md +45 -0
  91. package/docs/security/KEY_ROTATION.md +219 -0
  92. package/docs/security/MCP_POLICY.md +69 -0
  93. package/docs/security/POLICY_RELEASES.md +33 -0
  94. package/docs/security/README.md +24 -0
  95. package/docs/security/SECRETS.md +146 -0
  96. package/docs/security/SECURITY.md +41 -0
  97. package/docs/security/SECURITY_CHECKLIST.md +44 -0
  98. package/docs/security/SOUP_REGISTER.md +32 -0
  99. package/docs/security/THREAT_MODEL.md +120 -0
  100. package/docs/security/VERIFICATION_VALIDATION.md +224 -0
  101. package/docs/themes/README.md +6 -0
  102. package/docs/themes/VISUAL_INTEGRITY_REPORT.md +26 -0
  103. package/docs/themes/hero-shot.svg +78 -0
  104. package/dot_config/.module-manifest.json +69 -0
  105. package/dot_config/ai/identity.md +20 -0
  106. package/dot_config/ai/patterns/architect.md +14 -0
  107. package/dot_config/ai/patterns/hardener.md +13 -0
  108. package/dot_config/ai/patterns/refactor.md +13 -0
  109. package/dot_config/aider/aider.conf.yml +32 -0
  110. package/dot_config/alacritty/alacritty.toml.tmpl +55 -0
  111. package/dot_config/ansible/ansible.cfg +11 -0
  112. package/dot_config/atuin/config.toml +40 -0
  113. package/dot_config/bat/config +23 -0
  114. package/dot_config/brave-flags.conf.tmpl +7 -0
  115. package/dot_config/btop/btop.conf +16 -0
  116. package/dot_config/btop/themes/tokyonight.theme +34 -0
  117. package/dot_config/bun/bunfig.toml.tmpl +33 -0
  118. package/dot_config/claude/mcp_servers.json +20 -0
  119. package/dot_config/containers/containers.conf +14 -0
  120. package/dot_config/curl/dot_curlrc +18 -0
  121. package/dot_config/dlv/config.yml +39 -0
  122. package/dot_config/docker/config.json +15 -0
  123. package/dot_config/dotfiles/agent-card.json +29 -0
  124. package/dot_config/dotfiles/agent-profiles.json +92 -0
  125. package/dot_config/dotfiles/boot/README.md +11 -0
  126. package/dot_config/dotfiles/grub/README.md +11 -0
  127. package/dot_config/dotfiles/lock/README.md +11 -0
  128. package/dot_config/dotfiles/mcp-lock.json +33 -0
  129. package/dot_config/dotfiles/mcp-policy.json +52 -0
  130. package/dot_config/dotfiles/mcp-registry.json +47 -0
  131. package/dot_config/dotfiles/model-registry.json +20 -0
  132. package/dot_config/dotfiles/policy-bundles.json +38 -0
  133. package/dot_config/dotfiles/prompt-registry.json +16 -0
  134. package/dot_config/dotfiles/versions.env +18 -0
  135. package/dot_config/duf/duf.conf +6 -0
  136. package/dot_config/duti/defaults.duti +5 -0
  137. package/dot_config/emoji/emoji.txt +34 -0
  138. package/dot_config/environment.d/50-ssh-agent.conf +2 -0
  139. package/dot_config/environment.d/90-wayland.conf +19 -0
  140. package/dot_config/fastfetch/config.jsonc +28 -0
  141. package/dot_config/firefox/user.js.tmpl +58 -0
  142. package/dot_config/fish/completions/dot-theme-sync.fish.tmpl +9 -0
  143. package/dot_config/fish/completions/dot.fish.tmpl +115 -0
  144. package/dot_config/fish/conf.d/000-perf-cache.fish +56 -0
  145. package/dot_config/fish/conf.d/aliases.fish.tmpl +77 -0
  146. package/dot_config/fish/conf.d/env.fish.tmpl +48 -0
  147. package/dot_config/fish/conf.d/functions.fish.tmpl +22 -0
  148. package/dot_config/fish/conf.d/init.fish.tmpl +151 -0
  149. package/dot_config/fish/config.fish.tmpl +44 -0
  150. package/dot_config/fish/fish_plugins +1 -0
  151. package/dot_config/fish/functions/_.fish +3 -0
  152. package/dot_config/fish/functions/_cached_eval.fish +58 -0
  153. package/dot_config/fish/functions/als.fish +46 -0
  154. package/dot_config/fish/functions/bg-upgrade.fish +7 -0
  155. package/dot_config/fish/functions/c.fish +3 -0
  156. package/dot_config/fish/functions/cat.fish +9 -0
  157. package/dot_config/fish/functions/d.fish +7 -0
  158. package/dot_config/fish/functions/dot.fish +34 -0
  159. package/dot_config/fish/functions/h.fish +3 -0
  160. package/dot_config/fish/functions/l.fish +7 -0
  161. package/dot_config/fish/functions/la.fish +7 -0
  162. package/dot_config/fish/functions/ll.fish +7 -0
  163. package/dot_config/fish/functions/log_error.fish +13 -0
  164. package/dot_config/fish/functions/log_info.fish +13 -0
  165. package/dot_config/fish/functions/lr.fish +7 -0
  166. package/dot_config/fish/functions/lra.fish +7 -0
  167. package/dot_config/fish/functions/ls.fish +7 -0
  168. package/dot_config/fish/functions/lt.fish +7 -0
  169. package/dot_config/fish/functions/lta.fish +7 -0
  170. package/dot_config/fish/functions/notify-run.fish +11 -0
  171. package/dot_config/fish/functions/q.fish +3 -0
  172. package/dot_config/fish/functions/silent-run.fish +7 -0
  173. package/dot_config/fish/functions/yy.fish +8 -0
  174. package/dot_config/flatpak/flatpak.list +4 -0
  175. package/dot_config/fontconfig/fonts.conf.tmpl +57 -0
  176. package/dot_config/foot/foot.ini.tmpl +33 -0
  177. package/dot_config/fuzzel/fuzzel.ini.tmpl +18 -0
  178. package/dot_config/fzf/fzf.zsh +48 -0
  179. package/dot_config/gem/gemrc +9 -0
  180. package/dot_config/gh/config.yml +12 -0
  181. package/dot_config/ghostty/config.tmpl +165 -0
  182. package/dot_config/git/allowed_signers.tmpl +18 -0
  183. package/dot_config/git/attributes +12 -0
  184. package/dot_config/git/commit-template +10 -0
  185. package/dot_config/git/ignore +27 -0
  186. package/dot_config/gnupg/gpg-agent.conf +11 -0
  187. package/dot_config/go/golangci.yml +118 -0
  188. package/dot_config/go/gopls.json +30 -0
  189. package/dot_config/goose/config.yaml +29 -0
  190. package/dot_config/gtk-3.0/gtk.css.tmpl +184 -0
  191. package/dot_config/gtk-3.0/settings.ini.tmpl +27 -0
  192. package/dot_config/gtk-4.0/gtk.css.tmpl +252 -0
  193. package/dot_config/gtk-4.0/settings.ini.tmpl +18 -0
  194. package/dot_config/htop/htoprc +20 -0
  195. package/dot_config/inputrc +2 -0
  196. package/dot_config/ipython/profile_default/ipython_config.py +19 -0
  197. package/dot_config/just/justfile +122 -0
  198. package/dot_config/k9s/config.yaml +65 -0
  199. package/dot_config/k9s/skins/catppuccin-mocha.yaml +116 -0
  200. package/dot_config/kanshi/config.tmpl +22 -0
  201. package/dot_config/karabiner/karabiner.json +14 -0
  202. package/dot_config/kitty/kitty.conf.tmpl +53 -0
  203. package/dot_config/lazydocker/config.yml +186 -0
  204. package/dot_config/lazygit/config.yml +35 -0
  205. package/dot_config/mako/config +47 -0
  206. package/dot_config/mas/masapps.txt +5 -0
  207. package/dot_config/micro/settings.json +3 -0
  208. package/dot_config/mimeapps.list +77 -0
  209. package/dot_config/minikube/config.json +13 -0
  210. package/dot_config/mise/config.toml +99 -0
  211. package/dot_config/mongosh/mongoshrc.js +68 -0
  212. package/dot_config/mpv/input.conf +47 -0
  213. package/dot_config/mpv/mpv.conf +47 -0
  214. package/dot_config/mycli/myclirc +67 -0
  215. package/dot_config/nano/nanorc +28 -0
  216. package/dot_config/ncdu/config +12 -0
  217. package/dot_config/niri/config.kdl.tmpl +327 -0
  218. package/dot_config/nushell/aliases.nu +18 -0
  219. package/dot_config/nushell/completions.nu.tmpl +52 -0
  220. package/dot_config/nushell/config.nu.tmpl +86 -0
  221. package/dot_config/nushell/env.nu.tmpl +94 -0
  222. package/dot_config/nushell/functions.nu.tmpl +17 -0
  223. package/dot_config/nvim/init.lua +18 -0
  224. package/dot_config/nvim/lazy-lock.json +58 -0
  225. package/dot_config/nvim/lua/config/autocmds.lua +107 -0
  226. package/dot_config/nvim/lua/config/keymaps.lua +92 -0
  227. package/dot_config/nvim/lua/config/lazy.lua +44 -0
  228. package/dot_config/nvim/lua/config/options.lua +49 -0
  229. package/dot_config/nvim/lua/plugins/ai.lua +75 -0
  230. package/dot_config/nvim/lua/plugins/coding.lua +216 -0
  231. package/dot_config/nvim/lua/plugins/completion.lua +60 -0
  232. package/dot_config/nvim/lua/plugins/dap.lua +412 -0
  233. package/dot_config/nvim/lua/plugins/editor.lua +55 -0
  234. package/dot_config/nvim/lua/plugins/git.lua +10 -0
  235. package/dot_config/nvim/lua/plugins/lsp.lua +156 -0
  236. package/dot_config/nvim/lua/plugins/markdown.lua +18 -0
  237. package/dot_config/nvim/lua/plugins/rust.lua +34 -0
  238. package/dot_config/nvim/lua/plugins/sessions.lua +33 -0
  239. package/dot_config/nvim/lua/plugins/ui.lua +509 -0
  240. package/dot_config/paru/paru.conf +10 -0
  241. package/dot_config/pip/pip.conf.tmpl +32 -0
  242. package/dot_config/powershell/Microsoft.PowerShell_profile.ps1.tmpl +81 -0
  243. package/dot_config/pueue/pueue.yml +34 -0
  244. package/dot_config/pypoetry/config.toml +6 -0
  245. package/dot_config/pyrightconfig.json +5 -0
  246. package/dot_config/raycast/README.md +13 -0
  247. package/dot_config/redis/redisclirc +41 -0
  248. package/dot_config/ripgrep/ripgreprc +21 -0
  249. package/dot_config/shell/00-core-paths.sh.tmpl +133 -0
  250. package/dot_config/shell/05-core-safety.sh +47 -0
  251. package/dot_config/shell/10-secrets.sh +40 -0
  252. package/dot_config/shell/40-fzf-defaults.sh.tmpl +16 -0
  253. package/dot_config/shell/40-ls-colors.sh +48 -0
  254. package/dot_config/shell/50-logic-functions-core.sh.tmpl +10 -0
  255. package/dot_config/shell/50-logic-functions.sh.tmpl +10 -0
  256. package/dot_config/shell/51-logic-functions-extra.sh.tmpl +64 -0
  257. package/dot_config/shell/90-ux-aliases.sh.tmpl +120 -0
  258. package/dot_config/shell/91-ux-aliases-lazy.sh.tmpl +54 -0
  259. package/dot_config/shell/Brewfile +207 -0
  260. package/dot_config/shell/Brewfile.cask +92 -0
  261. package/dot_config/shell/Brewfile.cli +127 -0
  262. package/dot_config/shell/README.md +267 -0
  263. package/dot_config/shell/als_data.txt.tmpl +65 -0
  264. package/dot_config/shell/custom/auto_ls.zsh +20 -0
  265. package/dot_config/shell/custom/context_suggest.zsh +68 -0
  266. package/dot_config/shell/custom/error_analysis.zsh +45 -0
  267. package/dot_config/sops/dot_sops.yaml +23 -0
  268. package/dot_config/starship.toml.tmpl +202 -0
  269. package/dot_config/swaylock/config +43 -0
  270. package/dot_config/systemd/user/dotfiles-maintenance.service +8 -0
  271. package/dot_config/systemd/user/dotfiles-maintenance.timer +11 -0
  272. package/dot_config/systemd/user/pueued.service +12 -0
  273. package/dot_config/systemd/user/ssh-agent.service +12 -0
  274. package/dot_config/task/Taskfile.yml +86 -0
  275. package/dot_config/tflint/tflint.hcl +9 -0
  276. package/dot_config/tmux/tmux.conf.tmpl +223 -0
  277. package/dot_config/topgrade.toml.tmpl +54 -0
  278. package/dot_config/user-dirs.dirs +9 -0
  279. package/dot_config/vscode/extensions.txt +11 -0
  280. package/dot_config/vscode/settings.json.tmpl +82 -0
  281. package/dot_config/waybar/config.jsonc.tmpl +90 -0
  282. package/dot_config/waybar/style.css.tmpl +211 -0
  283. package/dot_config/wezterm/wezterm.lua.tmpl +64 -0
  284. package/dot_config/wget/wgetrc +12 -0
  285. package/dot_config/xdg-desktop-portal/niri-portals.conf +5 -0
  286. package/dot_config/yarn/yarnrc.yml +36 -0
  287. package/dot_config/yazi/keymap.toml +67 -0
  288. package/dot_config/yazi/theme.toml +102 -0
  289. package/dot_config/yazi/yazi.toml +40 -0
  290. package/dot_config/zathura/zathurarc +52 -0
  291. package/dot_config/zellij/config.kdl.tmpl +79 -0
  292. package/dot_config/zsh/dot_zprofile +7 -0
  293. package/dot_config/zsh/dot_zshenv +5 -0
  294. package/dot_config/zsh/dot_zshrc.tmpl +498 -0
  295. package/dot_config/zsh/rc.d/00-alias-shims.zsh +77 -0
  296. package/dot_config/zsh/rc.d/05-ssh-agent.zsh +18 -0
  297. package/dot_config/zsh/rc.d/10-env.zsh.tmpl +28 -0
  298. package/dot_config/zsh/rc.d/20-zinit.zsh +65 -0
  299. package/dot_config/zsh/rc.d/30-options.zsh.tmpl +194 -0
  300. package/dot_config/zsh/rc.d/40-bell.zsh +20 -0
  301. package/dot_config/zsh/rc.d/50-login-fortune.zsh +9 -0
  302. package/dot_config/zsh/rc.d/99-alias-wrapper.zsh +32 -0
  303. package/dot_local/bin/__pycache__/executable_dot-load-benchmark-ptycpython-312.pyc +0 -0
  304. package/dot_local/bin/executable_ai-update +195 -0
  305. package/dot_local/bin/executable_ai_core +152 -0
  306. package/dot_local/bin/executable_antigravity +11 -0
  307. package/dot_local/bin/executable_b64 +84 -0
  308. package/dot_local/bin/executable_bm +77 -0
  309. package/dot_local/bin/executable_cb +39 -0
  310. package/dot_local/bin/executable_dot +589 -0
  311. package/dot_local/bin/executable_dot-ai +36 -0
  312. package/dot_local/bin/executable_dot-bootstrap +77 -0
  313. package/dot_local/bin/executable_dot-launch-or-focus +52 -0
  314. package/dot_local/bin/executable_dot-load-benchmark +31 -0
  315. package/dot_local/bin/executable_dot-load-benchmark-pty +77 -0
  316. package/dot_local/bin/executable_dot-theme-sync +952 -0
  317. package/dot_local/bin/executable_dot_completion +57 -0
  318. package/dot_local/bin/executable_dtags +28 -0
  319. package/dot_local/bin/executable_epoch +67 -0
  320. package/dot_local/bin/executable_extract +41 -0
  321. package/dot_local/bin/executable_gbd +52 -0
  322. package/dot_local/bin/executable_gd +42 -0
  323. package/dot_local/bin/executable_git-ai-commit +175 -0
  324. package/dot_local/bin/executable_git-ai-diff +169 -0
  325. package/dot_local/bin/executable_gl +101 -0
  326. package/dot_local/bin/executable_hash +161 -0
  327. package/dot_local/bin/executable_hashsum +160 -0
  328. package/dot_local/bin/executable_hex +115 -0
  329. package/dot_local/bin/executable_jsonv +78 -0
  330. package/dot_local/bin/executable_jwt +94 -0
  331. package/dot_local/bin/executable_kill-port +75 -0
  332. package/dot_local/bin/executable_lorem +118 -0
  333. package/dot_local/bin/executable_mkscript +35 -0
  334. package/dot_local/bin/executable_monitor +56 -0
  335. package/dot_local/bin/executable_myip +51 -0
  336. package/dot_local/bin/executable_notify +22 -0
  337. package/dot_local/bin/executable_open +36 -0
  338. package/dot_local/bin/executable_pw +27 -0
  339. package/dot_local/bin/executable_rec-start +46 -0
  340. package/dot_local/bin/executable_rec-stop +35 -0
  341. package/dot_local/bin/executable_regex +132 -0
  342. package/dot_local/bin/executable_start-niri +8 -0
  343. package/dot_local/bin/executable_tmux-sessionizer +314 -0
  344. package/dot_local/bin/executable_tour +175 -0
  345. package/dot_local/bin/executable_up +21 -0
  346. package/dot_local/bin/executable_update +142 -0
  347. package/dot_local/bin/executable_uuid +87 -0
  348. package/dot_local/bin/executable_win +32 -0
  349. package/dot_local/bin/executable_yamlv +57 -0
  350. package/dot_local/share/bash-completion/completions/dot +72 -0
  351. package/dot_local/share/icons/hicolor/128x128/apps/rousseau.png +0 -0
  352. package/dot_local/share/icons/hicolor/16x16/apps/rousseau.png +0 -0
  353. package/dot_local/share/icons/hicolor/24x24/apps/rousseau.png +0 -0
  354. package/dot_local/share/icons/hicolor/256x256/apps/rousseau.png +0 -0
  355. package/dot_local/share/icons/hicolor/32x32/apps/rousseau.png +0 -0
  356. package/dot_local/share/icons/hicolor/48x48/apps/rousseau.png +0 -0
  357. package/dot_local/share/icons/hicolor/512x512/apps/rousseau.png +0 -0
  358. package/dot_local/share/icons/hicolor/64x64/apps/rousseau.png +0 -0
  359. package/dot_local/share/icons/hicolor/96x96/apps/rousseau.png +0 -0
  360. package/dot_local/share/icons/hicolor/scalable/apps/rousseau.png +0 -0
  361. package/dot_local/share/man/man1/dot.1 +149 -0
  362. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_download +64 -0
  363. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_install +18 -0
  364. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_list-all +13 -0
  365. package/dot_local/share/wayland-sessions/niri.desktop.tmpl +6 -0
  366. package/dot_local/share/zsh/completions/.keep +0 -0
  367. package/dot_local/share/zsh/completions/_dot +283 -0
  368. package/install.sh +342 -0
  369. package/package.json +1 -1
  370. package/scripts/ci/check-copyright-headers.sh +96 -0
  371. package/scripts/ci/guard-gitleaks-checkout.sh +57 -0
  372. package/scripts/ci/install-chezmoi-verified.sh +64 -0
  373. package/scripts/ci/validate-ci-config.sh +224 -0
  374. package/scripts/demo/record.sh +42 -0
  375. package/scripts/diagnostics/a2a-conformance.sh +162 -0
  376. package/scripts/diagnostics/alias-governance.sh +137 -0
  377. package/scripts/diagnostics/aliases-cheatsheet.sh +73 -0
  378. package/scripts/diagnostics/aliases-manifest.sh +31 -0
  379. package/scripts/diagnostics/benchmark.sh +381 -0
  380. package/scripts/diagnostics/conflicts.sh +72 -0
  381. package/scripts/diagnostics/doctor-unified.sh +38 -0
  382. package/scripts/diagnostics/doctor.sh +541 -0
  383. package/scripts/diagnostics/drift-dashboard.sh +37 -0
  384. package/scripts/diagnostics/health.sh +597 -0
  385. package/scripts/diagnostics/history-analysis.sh +85 -0
  386. package/scripts/diagnostics/mcp-doctor.sh +575 -0
  387. package/scripts/diagnostics/perf.sh +225 -0
  388. package/scripts/diagnostics/scorecard.sh +118 -0
  389. package/scripts/diagnostics/secret-governance.sh +58 -0
  390. package/scripts/diagnostics/security-score.sh +438 -0
  391. package/scripts/diagnostics/smoke-test.sh +87 -0
  392. package/scripts/diagnostics/snapshot.sh +89 -0
  393. package/scripts/diagnostics/verify.sh +107 -0
  394. package/scripts/{verify_state.sh → diagnostics/verify_state.sh} +22 -22
  395. package/scripts/diagnostics/version-locks.sh +79 -0
  396. package/scripts/diagnostics/workstation-attestation.sh +181 -0
  397. package/scripts/docs/build-manual.sh +883 -0
  398. package/scripts/docs/check-manual.sh +213 -0
  399. package/scripts/dot/commands/agent.sh +465 -0
  400. package/scripts/dot/commands/ai.sh +416 -0
  401. package/scripts/dot/commands/aliases.sh +250 -0
  402. package/scripts/dot/commands/appearance.sh +80 -0
  403. package/scripts/dot/commands/core.sh +185 -0
  404. package/scripts/dot/commands/diagnostics.sh +229 -0
  405. package/scripts/dot/commands/fleet.sh +399 -0
  406. package/scripts/dot/commands/lint.sh +177 -0
  407. package/scripts/dot/commands/manual.sh +168 -0
  408. package/scripts/dot/commands/meta.sh +248 -0
  409. package/scripts/dot/commands/patterns.sh +54 -0
  410. package/scripts/dot/commands/restore.sh +231 -0
  411. package/scripts/dot/commands/secrets.sh +223 -0
  412. package/scripts/dot/commands/security.sh +76 -0
  413. package/scripts/dot/commands/tools.sh +469 -0
  414. package/scripts/dot/data/alias-deprecations.tsv +2 -0
  415. package/scripts/dot/lib/bento.sh +49 -0
  416. package/scripts/dot/lib/log.sh +194 -0
  417. package/scripts/dot/lib/platform.sh +98 -0
  418. package/scripts/dot/lib/ui.sh +507 -0
  419. package/scripts/dot/lib/utils.sh +372 -0
  420. package/scripts/fonts/install-nerd-fonts.sh +68 -0
  421. package/scripts/fonts/patch-fonts.sh +35 -0
  422. package/scripts/git-hooks/install.sh +11 -0
  423. package/scripts/git-hooks/pre-commit +12 -0
  424. package/scripts/git-hooks/pre-commit-audit.sh +145 -0
  425. package/scripts/git-hooks/pre-push +29 -0
  426. package/scripts/git-hooks/prepare-commit-msg +29 -0
  427. package/scripts/lib/secrets_provider.sh +158 -0
  428. package/scripts/maintenance/check-updates.sh +131 -0
  429. package/scripts/ops/ai-setup.sh +55 -0
  430. package/scripts/ops/bundle.sh +77 -0
  431. package/scripts/ops/chaos.sh +49 -0
  432. package/scripts/ops/chezmoi-apply.sh +270 -0
  433. package/scripts/ops/chezmoi-diff.sh +15 -0
  434. package/scripts/ops/chezmoi-remove.sh +45 -0
  435. package/scripts/ops/chezmoi-update.sh +48 -0
  436. package/scripts/ops/heal-chezmoi.sh +51 -0
  437. package/scripts/ops/heal-system.sh +128 -0
  438. package/scripts/ops/heal-tools.sh +340 -0
  439. package/scripts/ops/heal.sh +222 -0
  440. package/scripts/ops/post-apply-repair.sh +106 -0
  441. package/scripts/ops/prewarm.sh +127 -0
  442. package/scripts/ops/release.sh +252 -0
  443. package/scripts/ops/rollback.sh +589 -0
  444. package/scripts/ops/setup.sh +137 -0
  445. package/scripts/ops/teleport.sh +33 -0
  446. package/scripts/qa/coverage-baseline.sh +60 -0
  447. package/scripts/qa/docs-coverage.sh +111 -0
  448. package/scripts/qa/reliability-audit.sh +138 -0
  449. package/scripts/qa/traceability-coverage.sh +116 -0
  450. package/scripts/qa/validate-examples.sh +26 -0
  451. package/scripts/qa/wsl-contract.sh +11 -0
  452. package/scripts/release/package-policy-bundles.sh +125 -0
  453. package/scripts/secrets/age-init.sh +70 -0
  454. package/scripts/secrets/create-secrets-file.sh +45 -0
  455. package/scripts/secrets/encrypt-ssh-key.sh +43 -0
  456. package/scripts/security/backup.sh +57 -0
  457. package/scripts/security/dns-doh.sh +51 -0
  458. package/scripts/security/encryption-check.sh +54 -0
  459. package/scripts/security/enforce-policies.sh +334 -0
  460. package/scripts/security/firewall.sh +90 -0
  461. package/scripts/security/lock-configs.sh +57 -0
  462. package/scripts/security/lock-screen.sh +55 -0
  463. package/scripts/security/manage-secrets.sh +428 -0
  464. package/scripts/security/ssh-cert.sh +203 -0
  465. package/scripts/security/telemetry-kill.sh +50 -0
  466. package/scripts/security/usb-safety.sh +51 -0
  467. package/scripts/theme/apply-gnome-theme.sh +328 -0
  468. package/scripts/theme/extract-theme.py +677 -0
  469. package/scripts/theme/install-boot-logo.sh +62 -0
  470. package/scripts/theme/install-catppuccin-themes.sh +370 -0
  471. package/scripts/theme/install-cursors.sh +25 -0
  472. package/scripts/theme/install-file-icons.sh +26 -0
  473. package/scripts/theme/install-grub-theme.sh +61 -0
  474. package/scripts/theme/install-lock-icon.sh +30 -0
  475. package/scripts/theme/merge-wallpaper.sh +141 -0
  476. package/scripts/theme/rebuild-themes.sh +309 -0
  477. package/scripts/theme/switch.sh +421 -0
  478. package/scripts/theme/wallpaper-rotate.sh +136 -0
  479. package/scripts/theme/wallpaper-sync.sh +397 -0
  480. package/scripts/tools/cmatrix.sh +21 -0
  481. package/scripts/{detect-collisions.py → tools/detect-collisions.py} +2 -2
  482. package/scripts/tools/emoji-picker.sh +48 -0
  483. package/scripts/tools/figlet-banner.sh +18 -0
  484. package/scripts/tools/log-rotate.sh +30 -0
  485. package/scripts/tools/lolcat-wrap.sh +19 -0
  486. package/scripts/tools/pipes.sh +48 -0
  487. package/scripts/tuning/linux.sh +185 -0
  488. package/scripts/tuning/macos.sh +55 -0
  489. package/scripts/uninstall.sh +85 -0
  490. package/scripts/version-sync.sh +487 -0
  491. package/templates/chezmoi-data/geekom-a9.toml.example +21 -0
  492. package/templates/chezmoi-data/mac-m1.toml.example +16 -0
  493. package/templates/chezmoi-data/mac-t2-linux.toml.example +21 -0
  494. package/templates/chezmoi-data/surface-pro-7p.toml.example +21 -0
  495. package/templates/projects/go/.github/workflows/ci.yml +31 -0
  496. package/templates/projects/go/README.md +4 -0
  497. package/templates/projects/go/cmd/__PROJECT_NAME__/main.go +1 -0
  498. package/templates/projects/go/go.sum +0 -0
  499. package/templates/projects/molecule/README.md +7 -0
  500. package/templates/projects/molecule/converge.yml +7 -0
  501. package/templates/projects/molecule/molecule.yml +16 -0
  502. package/templates/projects/node/.github/workflows/ci.yml +30 -0
  503. package/templates/projects/node/README.md +4 -0
  504. package/templates/projects/node/package-lock.json +12 -0
  505. package/templates/projects/node/src/index.js +1 -0
  506. package/templates/projects/packer/README.md +15 -0
  507. package/templates/projects/packer/main.pkr.hcl +15 -0
  508. package/templates/projects/python/.github/workflows/ci.yml +34 -0
  509. package/templates/projects/python/README.md +4 -0
  510. package/templates/projects/python/pyproject.toml +15 -0
  511. package/templates/projects/python/src/__PROJECT_NAME__/__init__.py +1 -0
  512. package/templates/projects/python/tests/test_basic.py +1 -0
  513. package/docs/ARCHITECTURE.md +0 -62
  514. package/docs/COMPLIANCE.md +0 -47
  515. package/docs/OPERATIONS.md +0 -103
  516. package/docs/PR_DESCRIPTION.md +0 -150
  517. package/docs/ROADMAP_legacy.md +0 -556
  518. package/docs/SECURITY_CHECKLIST.md +0 -25
  519. package/docs/TASK.md +0 -99
  520. package/docs/WALKTHROUGH.md +0 -46
  521. package/scripts/backup.sh +0 -142
  522. package/scripts/banner.sh +0 -20
  523. package/scripts/benchmark.sh +0 -20
  524. package/scripts/build.sh +0 -41
  525. package/scripts/clean.sh +0 -31
  526. package/scripts/compile.sh +0 -54
  527. package/scripts/copy.sh +0 -108
  528. package/scripts/doctor.sh +0 -79
  529. package/scripts/dotfiles.sh +0 -63
  530. package/scripts/download.sh +0 -35
  531. package/scripts/help.sh +0 -57
  532. package/scripts/lock-configs.sh +0 -57
  533. package/scripts/package.sh +0 -46
  534. package/scripts/ssh.sh +0 -55
  535. package/scripts/teleport.sh +0 -23
  536. package/scripts/test-aliases.sh +0 -25
  537. package/scripts/test_smoke.sh +0 -88
  538. package/scripts/unpack.sh +0 -28
@@ -0,0 +1,597 @@
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
424
+ if has_command chezmoi; then
425
+ local status_output
426
+ status_output=$(chezmoi status 2>/dev/null || echo "")
427
+ if [[ -z "$status_output" ]]; then
428
+ check "Chezmoi sync" "pass"
429
+ else
430
+ local changes
431
+ changes=$(printf '%s\n' "$status_output" | wc -l | tr -d ' ')
432
+ check "Chezmoi sync" "warn" "$changes file(s) out of sync"
433
+ fi
434
+ else
435
+ check "Chezmoi sync" "warn" "Not installed, skipped"
436
+ fi
437
+
438
+ # Git status
439
+ local dotfiles_dir="${HOME}/.dotfiles"
440
+ if [[ -d "$dotfiles_dir/.git" ]]; then
441
+ local git_status=""
442
+ git_status=$(git -C "$dotfiles_dir" status --porcelain 2>/dev/null || echo "")
443
+ if [[ -z "$git_status" ]]; then
444
+ check "Git working tree" "pass"
445
+ else
446
+ local changes
447
+ changes=$(printf '%s\n' "$git_status" | wc -l | tr -d ' ')
448
+ check "Git working tree" "pass" "$changes local change(s)"
449
+ fi
450
+ else
451
+ check "Git working tree" "warn" "Not a git repo"
452
+ fi
453
+ }
454
+
455
+ # === Orchestrator ===
456
+ run_checks() {
457
+ check_dotfiles_core
458
+ check_shell_env
459
+ check_dev_tools
460
+ check_cli_tools
461
+ check_editors
462
+ check_terminal
463
+ check_security
464
+ check_config_directories
465
+ check_sync_status
466
+ check_performance
467
+ }
468
+
469
+ print_summary() {
470
+ local score=$((PASSED_CHECKS * 100 / TOTAL_CHECKS))
471
+
472
+ if $JSON_OUTPUT; then
473
+ printf '{\n'
474
+ printf ' "total": %d,\n' "$TOTAL_CHECKS"
475
+ printf ' "passed": %d,\n' "$PASSED_CHECKS"
476
+ printf ' "warnings": %d,\n' "$WARNINGS"
477
+ printf ' "failures": %d,\n' "$FAILURES"
478
+ printf ' "score": %d,\n' "$score"
479
+ printf ' "results": [\n'
480
+ local i=0
481
+ for result in "${RESULTS[@]}"; do
482
+ if [[ $i -gt 0 ]]; then
483
+ printf ',\n'
484
+ fi
485
+ printf ' %s' "$result"
486
+ i=$((i + 1))
487
+ done
488
+ printf '\n ]\n'
489
+ printf '}\n'
490
+ dot_log info "health_complete" "score=$score" "total=$TOTAL_CHECKS"
491
+ dot_metric "health_score" "$score" "percent"
492
+ return
493
+ fi
494
+
495
+ echo ""
496
+ header "Summary"
497
+ echo ""
498
+
499
+ if [[ "$use_ui" = "1" ]]; then
500
+ printf " %-12s %s\n" "Total checks:" "${TOTAL_CHECKS}"
501
+ printf " %-12s %s\n" "Passed:" "$(gum style --foreground 2 "$PASSED_CHECKS")"
502
+ printf " %-12s %s\n" "Warnings:" "$(gum style --foreground 3 "$WARNINGS")"
503
+ printf " %-12s %s\n" "Failures:" "$(gum style --foreground 1 "$FAILURES")"
504
+ else
505
+ printf '%b\n' " Total checks: ${TOTAL_CHECKS}"
506
+ printf '%b\n' " ${GREEN}Passed:${NC} ${PASSED_CHECKS}"
507
+ printf '%b\n' " ${YELLOW}Warnings:${NC} ${WARNINGS}"
508
+ printf '%b\n' " ${RED}Failures:${NC} ${FAILURES}"
509
+ fi
510
+ echo ""
511
+
512
+ # Health score bar
513
+ local bar_width=30
514
+ local filled=$((score * bar_width / 100))
515
+ local empty=$((bar_width - filled))
516
+ local filled_bar="" empty_bar="" i
517
+
518
+ for ((i = 0; i < filled; i++)); do
519
+ filled_bar+="${_GL_BAR_FILL}"
520
+ done
521
+ for ((i = 0; i < empty; i++)); do
522
+ empty_bar+="${_GL_BAR_EMPTY}"
523
+ done
524
+
525
+ if [[ "$use_ui" = "1" ]]; then
526
+ local bar_color
527
+ if [[ $score -ge 80 ]]; then
528
+ bar_color=2
529
+ elif [[ $score -ge 60 ]]; then
530
+ bar_color=3
531
+ else
532
+ bar_color=1
533
+ fi
534
+ printf " Health Score: [%s%s] %s%%\n\n" \
535
+ "$(gum style --foreground "$bar_color" "$filled_bar")" \
536
+ "$empty_bar" \
537
+ "$score"
538
+ else
539
+ printf " Health Score: ["
540
+ if [[ $score -ge 80 ]]; then
541
+ printf '%s' "${GREEN}"
542
+ elif [[ $score -ge 60 ]]; then
543
+ printf '%s' "${YELLOW}"
544
+ else
545
+ printf '%s' "${RED}"
546
+ fi
547
+ printf '%s' "$filled_bar"
548
+ printf '%s' "${NC}"
549
+ printf '%s' "$empty_bar"
550
+ printf "] %s%%\n\n" "${score}"
551
+ fi
552
+
553
+ if [[ $score -ge 90 ]]; then
554
+ printf '%b\n' " ${GREEN}⚡ Excellent! Your dotfiles are in great shape.${NC}"
555
+ elif [[ $score -ge 70 ]]; then
556
+ printf '%b\n' " ${GREEN}✓ Good! Minor improvements possible.${NC}"
557
+ elif [[ $score -ge 50 ]]; then
558
+ printf '%b\n' " ${YELLOW}⚠ Fair. Consider addressing warnings.${NC}"
559
+ else
560
+ printf '%b\n' " ${RED}✗ Needs attention. Multiple issues found.${NC}"
561
+ fi
562
+
563
+ echo ""
564
+ if [[ $WARNINGS -gt 0 || $FAILURES -gt 0 ]]; then
565
+ printf '%b\n' " ${CYAN}Tip:${NC} Run 'dot health --fix' to auto-repair common issues."
566
+ echo ""
567
+ fi
568
+
569
+ dot_log info "health_complete" "score=$score" "total=$TOTAL_CHECKS"
570
+ dot_metric "health_score" "$score" "percent"
571
+ }
572
+
573
+ # Main
574
+ export DOT_COMMAND="health"
575
+ print_header
576
+ run_checks
577
+ if $APPLY_FIX; then
578
+ if ! $JSON_OUTPUT; then
579
+ header "Auto-Remediation"
580
+ echo ""
581
+ fi
582
+ heal_script="$SCRIPT_DIR/../ops/heal.sh"
583
+ if [[ -f "$heal_script" ]]; then
584
+ if $FORCE_FIX; then
585
+ bash "$heal_script" --force || true
586
+ else
587
+ bash "$heal_script" || true
588
+ fi
589
+ else
590
+ if ! $JSON_OUTPUT; then
591
+ printf '%b\n' "${YELLOW}⚠${NC} heal.sh not found, skipping auto-fix."
592
+ fi
593
+ fi
594
+ reset_stats
595
+ run_checks
596
+ fi
597
+ 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