@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,709 @@
1
+ #!/usr/bin/env bash
2
+ # Copyright (c) 2015-2026 Dotfiles. All rights reserved.
3
+ ## Dotfiles Doctor.
4
+ ##
5
+ ## Diagnoses dotfiles environment health by checking dependencies, paths,
6
+ ## and configuration integrity. Reports errors, warnings, and suggests
7
+ ## remediation steps.
8
+ ##
9
+ ## # Usage
10
+ ## dot doctor
11
+ ##
12
+ ## # Exit Codes
13
+ ## - 0: All checks passed (may have warnings)
14
+ ## - 1: Critical errors detected
15
+ ##
16
+ ## # Idempotency
17
+ ## Safe to run repeatedly. Read-only checks.
18
+
19
+ set -euo pipefail
20
+
21
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22
+ # shellcheck source=../dot/lib/ui.sh
23
+ # shellcheck disable=SC1091
24
+ source "$SCRIPT_DIR/../dot/lib/ui.sh"
25
+ # shellcheck source=../dot/lib/platform.sh
26
+ # shellcheck disable=SC1091
27
+ source "$SCRIPT_DIR/../dot/lib/platform.sh"
28
+ # shellcheck source=../dot/lib/log.sh
29
+ # shellcheck disable=SC1091
30
+ source "$SCRIPT_DIR/../dot/lib/log.sh"
31
+ export DOT_COMMAND="doctor"
32
+
33
+ ui_init
34
+
35
+ # Extend PATH to include common non-standard install locations
36
+ export PATH="$HOME/.atuin/bin:$HOME/.local/bin:$PATH"
37
+
38
+ Errors=0
39
+ Warnings=0
40
+ AI_DEBUG=0
41
+
42
+ for arg in "$@"; do
43
+ case "$arg" in
44
+ --ai) AI_DEBUG=1 ;;
45
+ esac
46
+ done
47
+
48
+ # --- Output helpers (delegate to shared ui.sh) ---
49
+ _ok() { ui_ok "$1" "${2:-}"; }
50
+ _fail() {
51
+ ui_err "$1" "${2:-}"
52
+ Errors=$((Errors + 1))
53
+ }
54
+ _warn() {
55
+ ui_warn "$1" "${2:-}"
56
+ Warnings=$((Warnings + 1))
57
+ }
58
+ _section() {
59
+ echo ""
60
+ ui_section "$1"
61
+ }
62
+
63
+ pretty_path() {
64
+ local value="${1:-}"
65
+ if [[ -n "$value" ]]; then
66
+ printf '%s' "${value/#$HOME/\~}"
67
+ fi
68
+ }
69
+
70
+ tool_source() {
71
+ local path="${1:-}"
72
+ if [[ "$path" == "$HOME/.local/share/mise/"* ]]; then
73
+ echo "mise"
74
+ elif [[ "$path" == /usr/bin/* || "$path" == /bin/* || "$path" == /usr/sbin/* || "$path" == /sbin/* ]]; then
75
+ echo "system"
76
+ else
77
+ echo "custom"
78
+ fi
79
+ }
80
+
81
+ check_cmd() {
82
+ local cmd="$1"
83
+ if command -v "$cmd" &>/dev/null; then return 0; fi
84
+ if command -v mise &>/dev/null; then
85
+ if mise ls --installed 2>/dev/null | grep -qE "($cmd|aqua:.*$cmd)"; then
86
+ return 0
87
+ fi
88
+ fi
89
+ return 1
90
+ }
91
+
92
+ get_cmd_path() {
93
+ local cmd="$1"
94
+ if command -v "$cmd" &>/dev/null; then
95
+ command -v "$cmd"
96
+ elif command -v mise &>/dev/null; then
97
+ local bin_path
98
+ bin_path=$(mise bin-paths 2>/dev/null | grep -E "/$cmd(/|$)" | head -n 1)
99
+ if [ -n "$bin_path" ]; then
100
+ echo "$bin_path/$cmd"
101
+ else
102
+ echo "$cmd"
103
+ fi
104
+ else
105
+ echo "$cmd"
106
+ fi
107
+ }
108
+
109
+ # --- Header ---
110
+ ui_header "Dotfiles Doctor"
111
+
112
+ # --- Core Shells ---
113
+ _section "Core Shells"
114
+ for cmd in zsh fish starship; do
115
+ if check_cmd "$cmd"; then
116
+ cmd_path="$(get_cmd_path "$cmd")"
117
+ _ok "$cmd" "$(pretty_path "$cmd_path") ($(tool_source "$cmd_path"))"
118
+ elif [[ "$cmd" == "fish" ]]; then
119
+ _warn "$cmd" "optional"
120
+ else
121
+ _fail "$cmd" "missing"
122
+ fi
123
+ done
124
+
125
+ if check_cmd "nu"; then
126
+ cmd_path="$(get_cmd_path "nu")"
127
+ _ok "nu" "$(pretty_path "$cmd_path") ($(tool_source "$cmd_path"))"
128
+ elif check_cmd "nushell"; then
129
+ cmd_path="$(get_cmd_path "nushell")"
130
+ _ok "nu" "$(pretty_path "$cmd_path") ($(tool_source "$cmd_path"))"
131
+ else
132
+ _warn "nu" "optional"
133
+ fi
134
+
135
+ # --- Modern CLI Tools ---
136
+ _section "Modern CLI Tools"
137
+ for cmd in rg bat chezmoi fzf zoxide atuin yazi zellij; do
138
+ if check_cmd "$cmd"; then
139
+ _ok "$cmd" "$(pretty_path "$(get_cmd_path "$cmd")")"
140
+ elif [[ "$cmd" == "bat" ]] && check_cmd "batcat"; then
141
+ _ok "$cmd" "$(pretty_path "$(get_cmd_path "batcat")") (batcat)"
142
+ else
143
+ _fail "$cmd" "missing"
144
+ fi
145
+ done
146
+
147
+ # --- Infrastructure ---
148
+ _section "Infrastructure"
149
+ for cmd in pueue wasmtime nix sops age hyperfine; do
150
+ if check_cmd "$cmd"; then
151
+ _ok "$cmd" "$(pretty_path "$(get_cmd_path "$cmd")")"
152
+ elif [[ "$cmd" == "nix" ]]; then
153
+ _ok "$cmd" "optional (not installed)"
154
+ else
155
+ _fail "$cmd" "missing"
156
+ fi
157
+ done
158
+
159
+ if check_cmd pueue; then
160
+ if "$(get_cmd_path pueue)" status >/dev/null 2>&1; then
161
+ _ok "pueue daemon" "running"
162
+ elif command -v pueued >/dev/null 2>&1 && pueued -d >/dev/null 2>&1 && "$(get_cmd_path pueue)" status >/dev/null 2>&1; then
163
+ _ok "pueue daemon" "started"
164
+ else
165
+ _warn "pueue daemon" "not running (pueued -d)"
166
+ fi
167
+ fi
168
+
169
+ # --- AI CLIs ---
170
+ _section "AI CLIs"
171
+ for cmd in claude copilot gemini sgpt ollama opencode aider kiro-cli; do
172
+ if check_cmd "$cmd"; then
173
+ _ok "$cmd" "$(pretty_path "$(get_cmd_path "$cmd")")"
174
+ else
175
+ _warn "$cmd" "optional"
176
+ fi
177
+ done
178
+
179
+ # --- Environment ---
180
+ _section "Environment"
181
+ if [[ -n "${XDG_CONFIG_HOME:-}" ]]; then
182
+ _ok "XDG_CONFIG_HOME" "$(pretty_path "$XDG_CONFIG_HOME")"
183
+ else
184
+ _warn "XDG_CONFIG_HOME" "defaulting to ~/.config"
185
+ fi
186
+
187
+ # Validate XDG paths are absolute
188
+ for var in XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME XDG_STATE_HOME; do
189
+ val="${!var:-}"
190
+ if [[ -n "$val" ]] && [[ "$val" != /* ]]; then
191
+ _warn "$var" "not absolute: $val"
192
+ fi
193
+ done
194
+
195
+ if [[ -n "${PIPX_HOME:-}" ]]; then
196
+ _ok "PIPX_HOME" "$(pretty_path "$PIPX_HOME")"
197
+ else
198
+ _warn "PIPX_HOME" "not set"
199
+ fi
200
+
201
+ # --- Platform ---
202
+ _section "Platform"
203
+
204
+ platform_id="$(dot_platform_id)"
205
+ _os_name="$(uname -s)"
206
+ _kernel="$(uname -sr)"
207
+ _arch="$(uname -m)"
208
+ _user="$(whoami 2>/dev/null || echo "${USER:-unknown}")"
209
+ _hostname_val="$(hostname -s 2>/dev/null || hostname 2>/dev/null || echo "unknown")"
210
+
211
+ # Shell version
212
+ _shell_name="${SHELL##*/}"
213
+ _shell_ver="$("$SHELL" --version 2>&1 | head -1 | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -1 || true)"
214
+ _shell="${_shell_name}${_shell_ver:+ $_shell_ver}"
215
+
216
+ # Terminal
217
+ _terminal="${TERM_PROGRAM:-${TERM:-unknown}}"
218
+
219
+ # Uptime (portable)
220
+ if uptime -p >/dev/null 2>&1; then
221
+ _uptime="$(uptime -p 2>/dev/null | sed 's/^up //')"
222
+ else
223
+ _uptime="$(uptime 2>/dev/null | sed -E 's/^.* up ([^,]+(, [^,]+){0,2}), [0-9]+ users?.*$/\1/' || true)"
224
+ fi
225
+
226
+ # --- OS-specific detection ---
227
+ _os="" _host="" _cpu="" _cpu_cores="" _gpu="" _mem="" _resolution="" _packages="" _de=""
228
+
229
+ if [[ "$_os_name" == "Darwin" ]]; then
230
+ # macOS
231
+ _os="macOS $(sw_vers -productVersion 2>/dev/null || echo "unknown")"
232
+ _host="$(/usr/sbin/system_profiler SPHardwareDataType 2>/dev/null | awk -F': ' '/Model Name/{print $2}' || sysctl -n hw.model 2>/dev/null || echo "Mac")"
233
+ _cpu="$(sysctl -n machdep.cpu.brand_string 2>/dev/null || echo "$_arch")"
234
+ _cpu_cores="$(sysctl -n hw.ncpu 2>/dev/null || echo "?")"
235
+ _gpu="$(system_profiler SPDisplaysDataType 2>/dev/null | awk -F': ' '/Chipset Model|Chip/{print $2; exit}' || echo "n/a")"
236
+ _mem_total="$(sysctl -n hw.memsize 2>/dev/null || echo 0)"
237
+ _mem_total_gb="$(awk "BEGIN{printf \"%.2f\", ${_mem_total}/1073741824}")"
238
+ _mem_pages="$(vm_stat 2>/dev/null | awk '/Pages active/{gsub(/\./,"",$3); print $3}')"
239
+ _mem_used_gb="$(awk "BEGIN{printf \"%.2f\", ${_mem_pages:-0}*4096/1073741824}")"
240
+ _mem="${_mem_used_gb} GiB / ${_mem_total_gb} GiB"
241
+ _resolution="$(system_profiler SPDisplaysDataType 2>/dev/null | awk '/Resolution/{gsub(/^ +/,""); print; exit}' | sed 's/Resolution: //' || echo "n/a")"
242
+ _packages="$(brew list --formula 2>/dev/null | wc -l | tr -d ' ') (brew)"
243
+ _de="Aqua"
244
+
245
+ elif [[ -r /etc/os-release ]]; then
246
+ # Linux (Debian, Ubuntu, Arch, Fedora, RHEL, etc.)
247
+ # shellcheck disable=SC1091
248
+ . /etc/os-release
249
+ _os="${PRETTY_NAME:-$ID}"
250
+
251
+ _host="$(cat /sys/devices/virtual/dmi/id/product_name 2>/dev/null || cat /sys/firmware/devicetree/base/model 2>/dev/null || echo "Linux")"
252
+
253
+ if command -v lscpu >/dev/null 2>&1; then
254
+ _cpu="$(lscpu | awk -F': +' '/Model name/{print $2}')"
255
+ _cpu_cores="$(lscpu | awk -F': +' '/^CPU\(s\):/{print $2}')"
256
+ else
257
+ _cpu="$(grep -m1 'model name' /proc/cpuinfo 2>/dev/null | cut -d: -f2 | sed 's/^ //' || uname -p)"
258
+ _cpu_cores="$(grep -c '^processor' /proc/cpuinfo 2>/dev/null || echo "?")"
259
+ fi
260
+
261
+ if command -v lspci >/dev/null 2>&1; then
262
+ _gpu="$(lspci 2>/dev/null | grep -iE 'vga|3d|display' | head -1 | sed 's/.*: //')"
263
+ else
264
+ _gpu="n/a"
265
+ fi
266
+
267
+ if command -v free >/dev/null 2>&1; then
268
+ _mem="$(free -b | awk '/Mem:/{printf "%.2f GiB / %.2f GiB", $3/1073741824, $2/1073741824}')"
269
+ elif [[ -r /proc/meminfo ]]; then
270
+ _mem_total_kb="$(awk '/MemTotal/{print $2}' /proc/meminfo)"
271
+ _mem_avail_kb="$(awk '/MemAvailable/{print $2}' /proc/meminfo)"
272
+ _mem_used_kb=$((_mem_total_kb - _mem_avail_kb))
273
+ _mem="$(awk "BEGIN{printf \"%.2f GiB / %.2f GiB\", ${_mem_used_kb}/1048576, ${_mem_total_kb}/1048576}")"
274
+ else
275
+ _mem="n/a"
276
+ fi
277
+
278
+ # Resolution (Wayland or X11)
279
+ if command -v wlr-randr >/dev/null 2>&1; then
280
+ _resolution="$(wlr-randr 2>/dev/null | awk '/current/{print $1; exit}' || echo "n/a")"
281
+ elif command -v xrandr >/dev/null 2>&1; then
282
+ _resolution="$(xrandr 2>/dev/null | awk '/\*/{print $1; exit}' || echo "n/a")"
283
+ elif command -v xdpyinfo >/dev/null 2>&1; then
284
+ _resolution="$(xdpyinfo 2>/dev/null | awk '/dimensions/{print $2}' || echo "n/a")"
285
+ else
286
+ _resolution="n/a"
287
+ fi
288
+
289
+ # Packages (multi-distro)
290
+ _pkg_count=0
291
+ _pkg_mgr="pkg"
292
+ if command -v dpkg >/dev/null 2>&1; then
293
+ _pkg_count="$(dpkg --get-selections 2>/dev/null | wc -l | tr -d ' ')"
294
+ _pkg_mgr="dpkg"
295
+ elif command -v rpm >/dev/null 2>&1; then
296
+ _pkg_count="$(rpm -qa 2>/dev/null | wc -l | tr -d ' ')"
297
+ _pkg_mgr="rpm"
298
+ elif command -v pacman >/dev/null 2>&1; then
299
+ _pkg_count="$(pacman -Q 2>/dev/null | wc -l | tr -d ' ')"
300
+ _pkg_mgr="pacman"
301
+ fi
302
+ _packages="${_pkg_count} (${_pkg_mgr})"
303
+
304
+ _de="${XDG_CURRENT_DESKTOP:-${DESKTOP_SESSION:-n/a}}"
305
+
306
+ else
307
+ # Fallback (unknown OS)
308
+ _os="$(uname -sr)"
309
+ _host="unknown"
310
+ _cpu="$(uname -p 2>/dev/null || echo "unknown")"
311
+ _cpu_cores="?"
312
+ _gpu="n/a"
313
+ _mem="n/a"
314
+ _resolution="n/a"
315
+ _packages="n/a"
316
+ _de="n/a"
317
+ fi
318
+
319
+ # WSL detection and overrides
320
+ _wsl=""
321
+ if [[ -f /proc/version ]] && grep -qi microsoft /proc/version 2>/dev/null; then
322
+ _wsl="yes"
323
+ _os="${_os} (WSL)"
324
+ _de="Windows Desktop (WSL)"
325
+ _terminal="${TERM_PROGRAM:-Windows Terminal}"
326
+ fi
327
+
328
+ # Print platform info
329
+ _C='\033[0;36m'
330
+ _W='\033[1;37m'
331
+ _N='\033[0m'
332
+ _D='\033[2m'
333
+
334
+ printf '\n'
335
+ printf ' %b%s%b@%b%s%b\n' "$_C" "$_user" "$_N" "$_C" "$_hostname_val" "$_N"
336
+ printf ' %b%s%b\n' "$_D" "$(printf '%*s' "$((${#_user} + 1 + ${#_hostname_val}))" '' | tr ' ' '-')" "$_N"
337
+ printf ' %bOS:%b %s\n' "$_W" "$_N" "$_os"
338
+ printf ' %bHost:%b %s\n' "$_W" "$_N" "$_host"
339
+ printf ' %bKernel:%b %s\n' "$_W" "$_N" "$_kernel"
340
+ printf ' %bUptime:%b %s\n' "$_W" "$_N" "${_uptime:-n/a}"
341
+ printf ' %bPackages:%b %s\n' "$_W" "$_N" "$_packages"
342
+ printf ' %bShell:%b %s\n' "$_W" "$_N" "$_shell"
343
+ printf ' %bResolution:%b %s\n' "$_W" "$_N" "$_resolution"
344
+ printf ' %bDE:%b %s\n' "$_W" "$_N" "$_de"
345
+ printf ' %bTerminal:%b %s\n' "$_W" "$_N" "$_terminal"
346
+ printf ' %bCPU:%b %s (%s)\n' "$_W" "$_N" "$_cpu" "$_cpu_cores"
347
+ printf ' %bGPU:%b %s\n' "$_W" "$_N" "${_gpu:-n/a}"
348
+ printf ' %bMemory:%b %s\n' "$_W" "$_N" "$_mem"
349
+ printf ' %bArch:%b %s\n' "$_W" "$_N" "$_arch"
350
+
351
+ if [[ -n "$_wsl" ]]; then
352
+ echo ""
353
+ if command -v wslpath >/dev/null 2>&1; then
354
+ _ok "WSL bridge" "wslpath available"
355
+ else
356
+ _warn "WSL bridge" "wslpath missing"
357
+ fi
358
+ if [[ "$PWD" == /mnt/* ]]; then
359
+ _warn "WSL filesystem" "/mnt causes IO latency"
360
+ else
361
+ _ok "WSL filesystem" "native"
362
+ fi
363
+ fi
364
+
365
+ # --- State ---
366
+ _section "State"
367
+ if chezmoi verify &>/dev/null; then
368
+ _ok "chezmoi" "synchronized"
369
+ else
370
+ _fail "chezmoi" "drifted (run dot drift)"
371
+ fi
372
+
373
+ if [[ -f "$HOME/.zshrc" ]]; then
374
+ _ok ".zshrc" "present"
375
+ else
376
+ _fail ".zshrc" "missing"
377
+ fi
378
+
379
+ if command -v dot >/dev/null 2>&1; then
380
+ dot_path="$(command -v dot)"
381
+ if [[ "$dot_path" == "$HOME/.local/bin/dot" ]]; then
382
+ _ok "dot" "$(pretty_path "$dot_path")"
383
+ else
384
+ _warn "dot" "$(pretty_path "$dot_path") (expected ~/.local/bin/dot)"
385
+ fi
386
+ else
387
+ _fail "dot" "not found in PATH"
388
+ fi
389
+
390
+ # --- Pre-push audit bypass log (closes #871) ---
391
+ _section "Pre-Push Audit Bypass"
392
+
393
+ bypass_log="${XDG_STATE_HOME:-$HOME/.local/state}/dotfiles/audit-bypass.log"
394
+ if [[ -s "$bypass_log" ]]; then
395
+ # Count entries in the last 7 days (timestamps are ISO-8601 UTC).
396
+ seven_days_ago=$(date -u -v-7d +%Y-%m-%dT00:00:00Z 2>/dev/null ||
397
+ date -u -d '7 days ago' +%Y-%m-%dT00:00:00Z 2>/dev/null ||
398
+ echo "1970-01-01T00:00:00Z")
399
+ recent=$(awk -v cutoff="$seven_days_ago" '$1 >= cutoff' "$bypass_log" | wc -l | tr -d ' ')
400
+ if ((recent > 0)); then
401
+ _warn "audit bypass" "$recent push(es) bypassed in last 7 days — see $(pretty_path "$bypass_log")"
402
+ else
403
+ _ok "audit bypass" "log exists; no recent entries (last 7d)"
404
+ fi
405
+ else
406
+ _ok "audit bypass" "clean — no pre-push audits bypassed"
407
+ fi
408
+
409
+ # --- Atuin history-filter (closes #872) ---
410
+ _section "Atuin History Filter"
411
+
412
+ atuin_cfg="$HOME/.config/atuin/config.toml"
413
+ if [[ ! -f "$atuin_cfg" ]]; then
414
+ _warn "atuin config" "not found at $(pretty_path "$atuin_cfg")"
415
+ else
416
+ if grep -Eq "^history_filter[[:space:]]*=" "$atuin_cfg"; then
417
+ pattern_count=$(awk '
418
+ /^history_filter[[:space:]]*=[[:space:]]*\[/ { inside = 1; next }
419
+ inside && /^\]/ { inside = 0 }
420
+ inside && /^[[:space:]]*"/ { count++ }
421
+ END { print count + 0 }
422
+ ' "$atuin_cfg")
423
+ if ((pattern_count >= 10)); then
424
+ _ok "history_filter" "$pattern_count patterns (chezmoi-managed)"
425
+ else
426
+ _warn "history_filter" "$pattern_count patterns (expected ≥10 from secrets-patterns.toml)"
427
+ fi
428
+ else
429
+ _fail "history_filter" "no history_filter block in $(pretty_path "$atuin_cfg") — secrets may leak into shell history"
430
+ fi
431
+ fi
432
+
433
+ # --- Topgrade Integration ---
434
+ _section "Topgrade Integration"
435
+
436
+ if command -v antigravity >/dev/null 2>&1; then
437
+ ag_path="$(command -v antigravity)"
438
+ if [[ "$ag_path" == "$HOME/.local/bin/antigravity" ]]; then
439
+ _ok "antigravity wrapper" "$(pretty_path "$ag_path")"
440
+ else
441
+ _warn "antigravity wrapper" "$(pretty_path "$ag_path") (expected ~/.local/bin/antigravity)"
442
+ fi
443
+ else
444
+ _warn "antigravity" "optional"
445
+ fi
446
+
447
+ if [[ -f "$HOME/.config/fish/fish_plugins" ]]; then
448
+ if grep -qx "jorgebucaran/fisher" "$HOME/.config/fish/fish_plugins"; then
449
+ _ok "fish_plugins" "contains jorgebucaran/fisher"
450
+ else
451
+ _warn "fish_plugins" "present but missing jorgebucaran/fisher"
452
+ fi
453
+ else
454
+ _fail "fish_plugins" "missing (~/.config/fish/fish_plugins)"
455
+ fi
456
+
457
+ if command -v cargo-install-update >/dev/null 2>&1; then
458
+ _ok "cargo-install-update" "$(pretty_path "$(command -v cargo-install-update)")"
459
+ else
460
+ _warn "cargo-install-update" "missing (install: cargo install cargo-update)"
461
+ fi
462
+
463
+ # --- Symlinks ---
464
+ broken_links=0
465
+ for root in "$HOME/.config" "$HOME/.local/bin" "$HOME/.local/share" "$HOME/.ssh"; do
466
+ [[ -d "$root" ]] || continue
467
+ while IFS= read -r -d '' link; do
468
+ link_name="$(basename "$link")"
469
+ [[ "$link" == *"google-chrome-backup"* ]] && continue
470
+ [[ "$link_name" == SingletonLock || "$link_name" == SingletonCookie || "$link_name" == SingletonSocket ]] && continue
471
+ [[ -e "$link" ]] || broken_links=$((broken_links + 1))
472
+ done < <(find "$root" -maxdepth 3 -type l -print0 2>/dev/null)
473
+ done
474
+
475
+ if [[ $broken_links -eq 0 ]]; then
476
+ _ok "symlinks" "none broken"
477
+ else
478
+ _warn "symlinks" "$broken_links broken"
479
+ fi
480
+
481
+ # --- Portability ---
482
+ ghost_paths=0
483
+ if command -v chezmoi >/dev/null 2>&1; then
484
+ while IFS= read -r managed_path; do
485
+ [[ "$managed_path" == "$HOME/.config/"* ]] || continue
486
+ [[ -f "$managed_path" ]] || continue
487
+ grep -Iq . "$managed_path" 2>/dev/null || continue
488
+
489
+ match_count=$(
490
+ grep -nE '"/home/(linuxbrew)?[^$]|/Users/[^$]' "$managed_path" 2>/dev/null |
491
+ grep -v "linuxbrew" |
492
+ grep -v "/mozilla/firefox" |
493
+ grep -v "/google-chrome" |
494
+ grep -v "/chromium" |
495
+ grep -v "/chezmoi/chezmoi.toml" |
496
+ grep -v "/bun/" |
497
+ grep -v "/.bun/" |
498
+ grep -v "/noctalia/" |
499
+ grep -c -v -- "-backup/" ||
500
+ true
501
+ )
502
+
503
+ ghost_paths=$((ghost_paths + ${match_count:-0}))
504
+ done < <(chezmoi managed --path-style=absolute 2>/dev/null || true)
505
+
506
+ if [[ $ghost_paths -gt 0 ]]; then
507
+ _warn "portability" "$ghost_paths hardcoded paths in managed ~/.config files"
508
+ else
509
+ _ok "portability" "no hardcoded paths in managed ~/.config files"
510
+ fi
511
+ else
512
+ _warn "portability" "chezmoi not found (scan skipped)"
513
+ fi
514
+
515
+ # --- Performance ---
516
+ _section "Performance"
517
+
518
+ cache_base="${XDG_CACHE_HOME:-$HOME/.cache}"
519
+
520
+ # 1. Shell cache freshness for tools the project already wraps in _cached_eval.
521
+ # Stale caches force runtime regeneration on next shell start.
522
+ stale_caches=0
523
+ stale_tools=""
524
+ for tool in mise starship zoxide atuin fzf direnv; do
525
+ tool_bin="$(command -v "$tool" 2>/dev/null || true)"
526
+ [[ -n "$tool_bin" ]] || continue
527
+ for shell_dir in zsh bash fish; do
528
+ case "$shell_dir" in
529
+ fish) cache_file="$cache_base/$shell_dir/${tool}-init.fish" ;;
530
+ *) cache_file="$cache_base/$shell_dir/${tool}-init.$shell_dir" ;;
531
+ esac
532
+ if [[ ! -f "$cache_file" ]] || [[ "$tool_bin" -nt "$cache_file" ]]; then
533
+ stale_caches=$((stale_caches + 1))
534
+ case "$stale_tools" in
535
+ *"$tool"*) ;;
536
+ *) stale_tools="${stale_tools:+$stale_tools, }$tool" ;;
537
+ esac
538
+ break
539
+ fi
540
+ done
541
+ done
542
+ if [[ $stale_caches -eq 0 ]]; then
543
+ _ok "shell caches" "fresh"
544
+ else
545
+ _warn "shell caches" "stale ($stale_tools) — run dot prewarm"
546
+ fi
547
+
548
+ # 2. Slow-init tools that are present but NOT wrapped in _cached_eval.
549
+ # Each of these runs uncached on every shell start; common offenders eat
550
+ # 100-500ms apiece on a populated dev machine.
551
+ unwrapped=""
552
+ for tool in nvm fnm pyenv rbenv jenv asdf sdkman conda kubectl helm gh cargo pnpm yarn thefuck broot mcfly; do
553
+ command -v "$tool" >/dev/null 2>&1 || continue
554
+ found=0
555
+ for shell_dir in zsh bash fish; do
556
+ case "$shell_dir" in
557
+ fish) [[ -f "$cache_base/$shell_dir/${tool}-init.fish" ]] && found=1 ;;
558
+ *) [[ -f "$cache_base/$shell_dir/${tool}-init.$shell_dir" ]] && found=1 ;;
559
+ esac
560
+ ((found == 1)) && break
561
+ done
562
+ ((found == 0)) && unwrapped="${unwrapped:+$unwrapped, }$tool"
563
+ done
564
+ if [[ -z "$unwrapped" ]]; then
565
+ _ok "uncached slow-init tools" "none detected"
566
+ else
567
+ _warn "uncached slow-init tools" "$unwrapped — consider wrapping in _cached_eval"
568
+ fi
569
+
570
+ # 3. Zsh completion dump health. compinit is usually the single biggest
571
+ # cost on a zsh startup; a stale or uncompiled .zcompdump compounds it.
572
+ if command -v zsh >/dev/null 2>&1; then
573
+ zcompdump="${HOME}/.zcompdump"
574
+ if [[ -f "$zcompdump" ]]; then
575
+ dump_mtime=$(stat -c %Y "$zcompdump" 2>/dev/null || stat -f %m "$zcompdump" 2>/dev/null || echo 0)
576
+ age_days=$((($(date +%s) - dump_mtime) / 86400))
577
+ if ((age_days > 7)); then
578
+ _warn ".zcompdump" "${age_days}d old — refresh: rm ~/.zcompdump* && zsh -ic exit"
579
+ else
580
+ _ok ".zcompdump" "fresh (${age_days}d)"
581
+ fi
582
+ if [[ ! -f "${zcompdump}.zwc" ]]; then
583
+ _warn ".zcompdump.zwc" "missing — completion init slower than necessary"
584
+ fi
585
+ fi
586
+ fi
587
+
588
+ # 4. PATH length. Each entry is searched on every command resolution;
589
+ # >40 entries is noticeably slow on cold-cache filesystems.
590
+ path_count=$(printf '%s' "${PATH:-}" | tr ':' '\n' | grep -c . || true)
591
+ if [[ "$path_count" -le 40 ]]; then
592
+ _ok "PATH length" "$path_count entries"
593
+ elif [[ "$path_count" -le 80 ]]; then
594
+ _warn "PATH length" "$path_count entries — consider pruning"
595
+ else
596
+ _fail "PATH length" "$path_count entries — likely slowing every command"
597
+ fi
598
+
599
+ # 5. Shell coverage. Surface installed shells that the project's caching
600
+ # infrastructure (zsh/bash/fish) doesn't currently maintain caches for.
601
+ shells_unmanaged=""
602
+ for sh in nu pwsh; do
603
+ command -v "$sh" >/dev/null 2>&1 && shells_unmanaged="${shells_unmanaged:+$shells_unmanaged, }$sh"
604
+ done
605
+ if [[ -z "$shells_unmanaged" ]]; then
606
+ _ok "shell coverage" "all installed shells (zsh/bash/fish) are managed"
607
+ else
608
+ _warn "shell coverage" "$shells_unmanaged installed — startup not measured by dot perf"
609
+ fi
610
+
611
+ # 6. Zsh hook count. Heavy precmd/preexec functions compound per-prompt.
612
+ # Probe an interactive zsh with a hard timeout so a broken zshrc doesn't
613
+ # stall doctor; skip cleanly if the probe fails.
614
+ if command -v zsh >/dev/null 2>&1 && command -v timeout >/dev/null 2>&1; then
615
+ hook_counts=$(timeout 5 zsh -i -c 'echo "$#precmd_functions $#preexec_functions"' 2>/dev/null || echo "")
616
+ if [[ -n "$hook_counts" ]]; then
617
+ read -r precmd_n preexec_n <<<"$hook_counts"
618
+ if [[ "${precmd_n:-0}" -le 5 && "${preexec_n:-0}" -le 5 ]]; then
619
+ _ok "zsh hooks" "precmd=$precmd_n preexec=$preexec_n"
620
+ else
621
+ _warn "zsh hooks" "precmd=$precmd_n preexec=$preexec_n — heavy per-prompt work"
622
+ fi
623
+ fi
624
+ fi
625
+
626
+ if command -v hyperfine >/dev/null 2>&1; then
627
+ if bash "$SCRIPT_DIR/../../tests/performance/bench.sh" 2>/dev/null; then
628
+ _ok "startup latency" "within target thresholds"
629
+ else
630
+ _warn "startup latency" "threshold exceeded (run dot prewarm)"
631
+ fi
632
+ else
633
+ _warn "hyperfine" "missing (benchmark skipped)"
634
+ fi
635
+
636
+ # 7. Baseline check + top-3 slowest tools from EVALCACHE_TIMING.
637
+ # Closes part of #863. Reads the same baseline file `dot perf` writes,
638
+ # and the same eval-timings.jsonl _cached_eval populates. Skipped
639
+ # silently when either file is absent (first-run state).
640
+ baseline_file="$cache_base/dotfiles/perf-baseline.json"
641
+ if [[ -s "$baseline_file" ]] && command -v python3 >/dev/null 2>&1; then
642
+ baseline_age_days=$(python3 -c '
643
+ import json, sys, datetime
644
+ try:
645
+ d = json.load(open(sys.argv[1]))
646
+ rec = d.get("recorded_at", "")
647
+ if not rec: print(-1); sys.exit(0)
648
+ rec = rec.replace("Z", "+00:00")
649
+ age = (datetime.datetime.now(datetime.timezone.utc) - datetime.datetime.fromisoformat(rec)).days
650
+ print(age)
651
+ except Exception:
652
+ print(-1)
653
+ ' "$baseline_file" 2>/dev/null)
654
+ if [[ "$baseline_age_days" -ge 0 ]]; then
655
+ _ok "perf baseline" "recorded ${baseline_age_days}d ago — run \`dot perf\` to compare"
656
+ fi
657
+ fi
658
+
659
+ timings_file="${XDG_STATE_HOME:-$HOME/.local/state}/dotfiles/eval-timings.jsonl"
660
+ if [[ -s "$timings_file" ]] && command -v python3 >/dev/null 2>&1; then
661
+ top_tools=$(python3 -c '
662
+ import json, sys
663
+ from collections import defaultdict
664
+ samples = defaultdict(list)
665
+ try:
666
+ for line in open(sys.argv[1]):
667
+ try:
668
+ ev = json.loads(line)
669
+ ms = int(ev.get("ms", 0) or 0)
670
+ samples[ev.get("label", "?")].append(ms)
671
+ except Exception:
672
+ pass
673
+ rows = sorted(samples.items(), key=lambda kv: sum(kv[1]) // max(len(kv[1]), 1), reverse=True)[:3]
674
+ print(", ".join(f"{lbl}({sum(v)//max(len(v),1)}ms)" for lbl, v in rows))
675
+ except Exception:
676
+ pass
677
+ ' "$timings_file" 2>/dev/null)
678
+ if [[ -n "$top_tools" ]]; then
679
+ _ok "perf top-tools" "$top_tools"
680
+ fi
681
+ fi
682
+
683
+ # --- Summary ---
684
+ dot_log info "doctor_complete" "errors=$Errors" "warnings=$Warnings"
685
+ dot_metric "doctor_errors" "$Errors" "count"
686
+ dot_metric "doctor_warnings" "$Warnings" "count"
687
+ echo ""
688
+ if [[ $Errors -eq 0 ]]; then
689
+ if [[ $Warnings -eq 0 ]]; then
690
+ ui_ok "Healthy" "All checks passed."
691
+ else
692
+ ui_ok "Healthy" "$Warnings warning(s)."
693
+ fi
694
+ else
695
+ ui_err "$Errors error(s)" "$Warnings warning(s). Run 'dot heal' to repair."
696
+
697
+ if [[ $AI_DEBUG -eq 1 ]]; then
698
+ _section "AI Problem Analysis"
699
+ doctor_report=$(~/.local/bin/dot doctor | grep -E "(✗|⚠)")
700
+ ai_prompt="The dotfiles diagnostic 'dot doctor' found the following issues:
701
+ ---
702
+ $doctor_report
703
+ ---
704
+ Suggest specific shell commands to fix these issues according to our architectural standards."
705
+ dot cl --pattern hardener "$ai_prompt"
706
+ fi
707
+ exit 1
708
+ fi
709
+ echo ""