@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,452 @@
1
+ #!/usr/bin/env bash
2
+ # Copyright (c) 2015-2026 Dotfiles. All rights reserved.
3
+ # Shell Performance Profiling
4
+ # Usage: dot perf [--json|-j] [--profile|-p] [--runs|-r N] [--target|-t MS]
5
+
6
+ set -euo pipefail
7
+
8
+ _cleanup_files=()
9
+ trap 'rm -f "${_cleanup_files[@]}"' EXIT
10
+
11
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+ # shellcheck source=../dot/lib/ui.sh
13
+ # shellcheck disable=SC1091
14
+ source "$SCRIPT_DIR/../dot/lib/ui.sh"
15
+ # shellcheck source=../dot/lib/log.sh
16
+ # shellcheck disable=SC1091
17
+ source "$SCRIPT_DIR/../dot/lib/log.sh"
18
+ export DOT_COMMAND="perf"
19
+
20
+ ui_init
21
+
22
+ if ! command -v python3 >/dev/null 2>&1; then
23
+ ui_err "python3" "required for perf timing"
24
+ exit 1
25
+ fi
26
+
27
+ JSON_OUTPUT=false
28
+ PROFILE=false
29
+ RUNS=3
30
+ TARGET_MS="${DOTFILES_PERF_TARGET_MS:-250}"
31
+ MAX_MS="${DOTFILES_PERF_MAX_MS:-1000}"
32
+ SHELL_FILTER=""
33
+ BY_TOOL=false
34
+ RESET_TIMINGS=false
35
+
36
+ while [[ $# -gt 0 ]]; do
37
+ case "$1" in
38
+ --json | -j)
39
+ JSON_OUTPUT=true
40
+ shift
41
+ ;;
42
+ --profile | -p)
43
+ PROFILE=true
44
+ shift
45
+ ;;
46
+ --runs | -r)
47
+ RUNS="${2:-3}"
48
+ shift 2
49
+ ;;
50
+ --target | -t)
51
+ TARGET_MS="${2:-$TARGET_MS}"
52
+ shift 2
53
+ ;;
54
+ --shell | -s)
55
+ SHELL_FILTER="${2:-}"
56
+ shift 2
57
+ ;;
58
+ --by-tool)
59
+ BY_TOOL=true
60
+ shift
61
+ ;;
62
+ --reset)
63
+ RESET_TIMINGS=true
64
+ shift
65
+ ;;
66
+ --baseline)
67
+ # Write the current per-shell means to the baseline file so
68
+ # subsequent runs can warn on regression. Closes part of #863.
69
+ WRITE_BASELINE=true
70
+ shift
71
+ ;;
72
+ --no-baseline-check)
73
+ # Skip the baseline-vs-current comparison entirely. Useful for
74
+ # the very first run on a machine, or for short-lived CI.
75
+ NO_BASELINE_CHECK=true
76
+ shift
77
+ ;;
78
+ *)
79
+ shift
80
+ ;;
81
+ esac
82
+ done
83
+
84
+ WRITE_BASELINE="${WRITE_BASELINE:-false}"
85
+ NO_BASELINE_CHECK="${NO_BASELINE_CHECK:-false}"
86
+ BASELINE_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/dotfiles/perf-baseline.json"
87
+ BASELINE_REGRESSION_PCT="${DOTFILES_PERF_REGRESSION_PCT:-10}"
88
+
89
+ # --by-tool reader: aggregate $XDG_STATE_HOME/dotfiles/eval-timings.jsonl
90
+ # (populated by _cached_eval when EVALCACHE_TIMING=1) and report which
91
+ # tools dominate startup time. Independent of the runtime measurement
92
+ # loop above, so it returns immediately.
93
+ if $BY_TOOL || $RESET_TIMINGS; then
94
+ log_dir="${XDG_STATE_HOME:-$HOME/.local/state}/dotfiles"
95
+ log_file="$log_dir/eval-timings.jsonl"
96
+ if $RESET_TIMINGS; then
97
+ : >"$log_file" 2>/dev/null || rm -f "$log_file" 2>/dev/null || true
98
+ ui_ok "eval timings" "cleared $log_file"
99
+ $BY_TOOL || exit 0
100
+ fi
101
+ if [[ ! -s "$log_file" ]]; then
102
+ ui_warn "eval timings" "no data at $log_file"
103
+ echo " Hint: open a new shell with EVALCACHE_TIMING=1 to start collecting." >&2
104
+ exit 0
105
+ fi
106
+ ui_dot_banner "Diagnostics"
107
+ ui_header "Per-tool timing breakdown"
108
+ ui_section "$log_file"
109
+ python3 - "$log_file" <<'PY'
110
+ import json, sys
111
+ from collections import defaultdict
112
+
113
+ def percentile(sorted_vals, p):
114
+ """Linear-interpolation percentile, matching numpy.percentile defaults."""
115
+ if not sorted_vals:
116
+ return 0
117
+ if len(sorted_vals) == 1:
118
+ return sorted_vals[0]
119
+ k = (len(sorted_vals) - 1) * (p / 100.0)
120
+ f = int(k)
121
+ c = min(f + 1, len(sorted_vals) - 1)
122
+ if f == c:
123
+ return sorted_vals[f]
124
+ return sorted_vals[f] + (sorted_vals[c] - sorted_vals[f]) * (k - f)
125
+
126
+ samples = defaultdict(list) # label -> [ms, ms, ...]
127
+ shells_by_label = defaultdict(set) # label -> {shell, ...}
128
+
129
+ with open(sys.argv[1]) as f:
130
+ for line in f:
131
+ line = line.strip()
132
+ if not line:
133
+ continue
134
+ try:
135
+ ev = json.loads(line)
136
+ except Exception:
137
+ continue
138
+ label = ev.get("label", "?")
139
+ try:
140
+ ms = int(ev.get("ms", 0) or 0)
141
+ except (TypeError, ValueError):
142
+ continue
143
+ samples[label].append(ms)
144
+ shells_by_label[label].add(ev.get("shell", "?"))
145
+
146
+ rows = []
147
+ for label, vals in samples.items():
148
+ vals_sorted = sorted(vals)
149
+ rows.append({
150
+ "label": label,
151
+ "count": len(vals_sorted),
152
+ "total": sum(vals_sorted),
153
+ "mean": sum(vals_sorted) // max(len(vals_sorted), 1),
154
+ "min": vals_sorted[0],
155
+ "max": vals_sorted[-1],
156
+ "p50": int(percentile(vals_sorted, 50)),
157
+ "p95": int(percentile(vals_sorted, 95)),
158
+ "p99": int(percentile(vals_sorted, 99)),
159
+ "shells": ",".join(sorted(shells_by_label[label])),
160
+ })
161
+
162
+ rows.sort(key=lambda r: r["total"], reverse=True)
163
+ header = (f" {'label':<20} {'calls':>5} {'total':>8} "
164
+ f"{'mean':>7} {'p50':>5} {'p95':>5} {'p99':>5} shells")
165
+ print(header)
166
+ print(" " + "-" * (len(header) - 2))
167
+ for r in rows:
168
+ print(f" {r['label']:<20} {r['count']:>5} {r['total']:>6}ms "
169
+ f"{r['mean']:>5}ms {r['p50']:>3}ms {r['p95']:>3}ms {r['p99']:>3}ms {r['shells']}")
170
+ PY
171
+ exit 0
172
+ fi
173
+
174
+ # Per-shell defaults. nu and pwsh are genuinely slower than POSIX shells;
175
+ # bash should be quickest. Override via DOTFILES_PERF_TARGET_<SHELL>_MS.
176
+ shell_target_for() {
177
+ case "$1" in
178
+ zsh) echo "${DOTFILES_PERF_TARGET_ZSH_MS:-$TARGET_MS}" ;;
179
+ bash) echo "${DOTFILES_PERF_TARGET_BASH_MS:-60}" ;;
180
+ fish) echo "${DOTFILES_PERF_TARGET_FISH_MS:-200}" ;;
181
+ nu) echo "${DOTFILES_PERF_TARGET_NU_MS:-500}" ;;
182
+ pwsh) echo "${DOTFILES_PERF_TARGET_PWSH_MS:-600}" ;;
183
+ *) echo "$TARGET_MS" ;;
184
+ esac
185
+ }
186
+
187
+ # Invoke a near-empty session for the named shell, picking flags that
188
+ # load the user's interactive profile (matches what a fresh terminal does).
189
+ invoke_shell() {
190
+ case "$1" in
191
+ zsh) zsh -i -c exit </dev/null ;;
192
+ bash) bash -i -c exit </dev/null ;;
193
+ fish) fish -i -c exit </dev/null ;;
194
+ nu) nu -c exit </dev/null ;;
195
+ pwsh) pwsh -Command exit </dev/null ;;
196
+ *) return 1 ;;
197
+ esac
198
+ }
199
+
200
+ time_one_run() {
201
+ local shell_name="$1" start end
202
+ start=$(python3 -c 'import time; print(int(time.time() * 1000))')
203
+ invoke_shell "$shell_name" >/dev/null 2>&1 || true
204
+ end=$(python3 -c 'import time; print(int(time.time() * 1000))')
205
+ echo $((end - start))
206
+ }
207
+
208
+ # Existing single-shell helper retained for backward compatibility with
209
+ # callers/tests that reference time_shell_startup; routes to time_one_run.
210
+ time_shell_startup() { time_one_run zsh; }
211
+
212
+ # Measure a shell across $RUNS iterations, return "mean min max".
213
+ measure_shell() {
214
+ local shell_name="$1" sum=0 min=999999 max=0 t
215
+ local times=()
216
+ # One warm-up run discarded — caches a $_SHELL_CACHE on first invocation.
217
+ invoke_shell "$shell_name" >/dev/null 2>&1 || true
218
+ for _ in $(seq 1 "$RUNS"); do
219
+ t=$(time_one_run "$shell_name")
220
+ times+=("$t")
221
+ sum=$((sum + t))
222
+ [[ "$t" -lt "$min" ]] && min="$t"
223
+ [[ "$t" -gt "$max" ]] && max="$t"
224
+ done
225
+ echo "$((sum / RUNS)) $min $max"
226
+ }
227
+
228
+ calc_score() {
229
+ local mean_ms="$1"
230
+ if [[ "$mean_ms" -le "$TARGET_MS" ]]; then
231
+ echo 100
232
+ return
233
+ fi
234
+ if [[ "$mean_ms" -ge "$MAX_MS" ]]; then
235
+ echo 0
236
+ return
237
+ fi
238
+ echo $((100 - (mean_ms - TARGET_MS) * 100 / (MAX_MS - TARGET_MS)))
239
+ }
240
+
241
+ run_profile() {
242
+ zsh -c '
243
+ zmodload zsh/zprof
244
+ # shellcheck disable=SC1091
245
+ source ~/.zshenv 2>/dev/null
246
+ # shellcheck disable=SC1091
247
+ source ~/.config/zsh/.zshrc 2>/dev/null
248
+ zprof
249
+ ' 2>/dev/null | head -20
250
+ }
251
+
252
+ # Discover installed shells. SHELL_FILTER (--shell <name>) restricts to one.
253
+ all_shells=(zsh bash fish nu pwsh)
254
+ shells_to_measure=()
255
+ for s in "${all_shells[@]}"; do
256
+ command -v "$s" >/dev/null 2>&1 || continue
257
+ if [[ -n "$SHELL_FILTER" && "$s" != "$SHELL_FILTER" ]]; then
258
+ continue
259
+ fi
260
+ shells_to_measure+=("$s")
261
+ done
262
+ if ((${#shells_to_measure[@]} == 0)); then
263
+ ui_err "perf" "no measurable shells found${SHELL_FILTER:+ (filter: $SHELL_FILTER)}"
264
+ exit 1
265
+ fi
266
+
267
+ # Measure each shell once into parallel arrays.
268
+ declare -a shell_names shell_means shell_mins shell_maxs shell_targets shell_passes
269
+ for s in "${shells_to_measure[@]}"; do
270
+ read -r m mn mx <<<"$(measure_shell "$s")"
271
+ t=$(shell_target_for "$s")
272
+ shell_names+=("$s")
273
+ shell_means+=("$m")
274
+ shell_mins+=("$mn")
275
+ shell_maxs+=("$mx")
276
+ shell_targets+=("$t")
277
+ if [[ "$m" -le "$t" ]]; then
278
+ shell_passes+=("1")
279
+ else
280
+ shell_passes+=("0")
281
+ fi
282
+ done
283
+
284
+ # Primary "score" continues to use the zsh measurement (when available)
285
+ # so existing dashboards / JSON consumers keep their reference number.
286
+ mean=0
287
+ for i in "${!shell_names[@]}"; do
288
+ if [[ "${shell_names[$i]}" == "zsh" ]]; then
289
+ mean="${shell_means[$i]}"
290
+ break
291
+ fi
292
+ done
293
+ [[ "$mean" -eq 0 && "${#shell_means[@]}" -gt 0 ]] && mean="${shell_means[0]}"
294
+ score=$(calc_score "$mean")
295
+
296
+ # -----------------------------------------------------------------------------
297
+ # Baseline persistence + regression detection (closes part of #863).
298
+ # Stored at $XDG_CACHE_HOME/dotfiles/perf-baseline.json. The file is a
299
+ # JSON object mapping shell name → recorded mean (ms). `--baseline`
300
+ # overwrites it with the current measurement; default behavior reads
301
+ # it (if present) and warns when any shell regresses by more than
302
+ # DOTFILES_PERF_REGRESSION_PCT (default 10%).
303
+ # -----------------------------------------------------------------------------
304
+
305
+ declare -a baseline_warnings=()
306
+ if $WRITE_BASELINE; then
307
+ mkdir -p "$(dirname "$BASELINE_FILE")"
308
+ {
309
+ printf '{\n "recorded_at": "%s",\n "regression_pct": %d,\n "shells": {' \
310
+ "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$BASELINE_REGRESSION_PCT"
311
+ for i in "${!shell_names[@]}"; do
312
+ [[ "$i" -gt 0 ]] && printf ','
313
+ printf '\n "%s": %d' "${shell_names[$i]}" "${shell_means[$i]}"
314
+ done
315
+ printf '\n }\n}\n'
316
+ } >"$BASELINE_FILE"
317
+ fi
318
+
319
+ if ! $NO_BASELINE_CHECK && [[ -s "$BASELINE_FILE" ]]; then
320
+ # Read the baseline and compare each measured shell.
321
+ for i in "${!shell_names[@]}"; do
322
+ name="${shell_names[$i]}"
323
+ m="${shell_means[$i]}"
324
+ baseline_ms=$(python3 -c '
325
+ import json, sys
326
+ try:
327
+ d = json.load(open(sys.argv[1]))
328
+ print(d.get("shells", {}).get(sys.argv[2], 0))
329
+ except Exception:
330
+ print(0)
331
+ ' "$BASELINE_FILE" "$name" 2>/dev/null)
332
+ [[ -z "$baseline_ms" || "$baseline_ms" -eq 0 ]] && continue
333
+ # Threshold: current > baseline * (1 + pct/100)
334
+ threshold=$((baseline_ms * (100 + BASELINE_REGRESSION_PCT) / 100))
335
+ if ((m > threshold)); then
336
+ delta_pct=$((((m - baseline_ms) * 100) / baseline_ms))
337
+ baseline_warnings+=("$name: $m ms vs baseline $baseline_ms ms (+${delta_pct}%, threshold +${BASELINE_REGRESSION_PCT}%)")
338
+ fi
339
+ done
340
+ fi
341
+
342
+ if $JSON_OUTPUT; then
343
+ printf '{\n "runs": %d,\n "target_ms": %d,\n "max_ms_target": %d,\n "score": %d,\n "mean_ms": %d,\n "regression_count": %d,\n "shells": {' \
344
+ "$RUNS" "$TARGET_MS" "$MAX_MS" "$score" "$mean" "${#baseline_warnings[@]}"
345
+ for i in "${!shell_names[@]}"; do
346
+ [[ "$i" -gt 0 ]] && printf ','
347
+ printf '\n "%s": {"mean_ms": %d, "min_ms": %d, "max_ms": %d, "target_ms": %d, "pass": %s}' \
348
+ "${shell_names[$i]}" "${shell_means[$i]}" "${shell_mins[$i]}" "${shell_maxs[$i]}" \
349
+ "${shell_targets[$i]}" "$([[ ${shell_passes[$i]} == 1 ]] && echo true || echo false)"
350
+ done
351
+ printf '\n }'
352
+ if [[ "${#baseline_warnings[@]}" -gt 0 ]]; then
353
+ printf ',\n "regressions": ['
354
+ for i in "${!baseline_warnings[@]}"; do
355
+ [[ "$i" -gt 0 ]] && printf ','
356
+ # JSON-escape the warning text minimally (no embedded quotes expected).
357
+ printf '\n "%s"' "${baseline_warnings[$i]}"
358
+ done
359
+ printf '\n ]'
360
+ fi
361
+ printf '\n}\n'
362
+ exit 0
363
+ fi
364
+
365
+ ui_dot_banner "Diagnostics"
366
+ ui_header "Shell Performance"
367
+
368
+ ui_section "Per-shell startup ($RUNS runs each, after one warm-up)"
369
+
370
+ # Aligned table: name (6) | mean (8) | min/max (16) | target (12) | status
371
+ for i in "${!shell_names[@]}"; do
372
+ name="${shell_names[$i]}"
373
+ m="${shell_means[$i]}"
374
+ mn="${shell_mins[$i]}"
375
+ mx="${shell_maxs[$i]}"
376
+ t="${shell_targets[$i]}"
377
+ if [[ "${shell_passes[$i]}" == "1" ]]; then
378
+ status_marker="✓"
379
+ detail=""
380
+ else
381
+ status_marker="✗"
382
+ detail=" — over by $((m - t))ms"
383
+ fi
384
+ printf ' %s %-6s mean %4dms (min %3dms, max %3dms) target %4dms%s\n' \
385
+ "$status_marker" "$name" "$m" "$mn" "$mx" "$t" "$detail"
386
+ done
387
+
388
+ # Baseline comparison summary
389
+ if [[ "${#baseline_warnings[@]}" -gt 0 ]]; then
390
+ ui_section "Baseline regressions"
391
+ for w in "${baseline_warnings[@]}"; do
392
+ printf ' ✗ %s\n' "$w"
393
+ done
394
+ printf ' (threshold: >%s%% over the recorded baseline at %s)\n' \
395
+ "$BASELINE_REGRESSION_PCT" "$BASELINE_FILE"
396
+ elif [[ -s "$BASELINE_FILE" ]] && ! $NO_BASELINE_CHECK; then
397
+ ui_section "Baseline"
398
+ printf ' ✓ all measured shells within %s%% of baseline (%s)\n' \
399
+ "$BASELINE_REGRESSION_PCT" "$BASELINE_FILE"
400
+ elif $WRITE_BASELINE; then
401
+ ui_section "Baseline"
402
+ printf ' ✓ wrote baseline to %s\n' "$BASELINE_FILE"
403
+ fi
404
+
405
+ # Per-component breakdown (Zsh only, uses DOTFILES_DEBUG timing)
406
+ ui_section "Component breakdown (estimated)"
407
+ for component in "bare zsh" "paths+env" "aliases" "functions" "tools"; do
408
+ case "$component" in
409
+ "bare zsh")
410
+ c_start=$(python3 -c 'import time; print(int(time.time() * 1000))')
411
+ zsh --no-rcs -c exit >/dev/null 2>&1 || true
412
+ c_end=$(python3 -c 'import time; print(int(time.time() * 1000))')
413
+ ;;
414
+ "paths+env")
415
+ c_start=$(python3 -c 'import time; print(int(time.time() * 1000))')
416
+ DOTFILES_ULTRA_FAST=1 zsh -i -c exit >/dev/null 2>&1 || true
417
+ c_end=$(python3 -c 'import time; print(int(time.time() * 1000))')
418
+ ;;
419
+ *)
420
+ # Approximate — full minus ultra gives the delta
421
+ c_start=0
422
+ c_end=0
423
+ ;;
424
+ esac
425
+ c_time=$((c_end - c_start))
426
+ if [[ "$c_time" -gt 0 ]]; then
427
+ if [[ "$UI_ENABLED" = "1" ]]; then
428
+ ui_kv "$component" "${c_time}ms"
429
+ else
430
+ echo " $component: ${c_time}ms"
431
+ fi
432
+ fi
433
+ done
434
+
435
+ if $PROFILE; then
436
+ echo ""
437
+ ui_section "Top contributors (zprof)"
438
+ run_profile
439
+ echo ""
440
+ fi
441
+
442
+ dot_log info "perf_complete" "mean_ms=$mean" "score=$score"
443
+ dot_metric "shell_startup_mean" "$mean" "ms"
444
+ dot_metric "perf_score" "$score" "percent"
445
+
446
+ if [[ "$score" -eq 100 ]]; then
447
+ ui_ok "Performance" "Excellent"
448
+ elif [[ "$score" -ge 80 ]]; then
449
+ ui_warn "Performance" "Good (tune to reach 100)"
450
+ else
451
+ ui_err "Performance" "Needs attention"
452
+ fi
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env bash
2
+ # Copyright (c) 2015-2026 Dotfiles. All rights reserved.
3
+ # Dotfiles Scorecard
4
+ # Usage: dot scorecard [--json|-j]
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
+ export DOT_COMMAND="scorecard"
16
+
17
+ ui_init
18
+ set +x
19
+
20
+ if ! command -v python3 >/dev/null 2>&1; then
21
+ ui_err "python3" "required for scorecard"
22
+ exit 1
23
+ fi
24
+
25
+ JSON_OUTPUT=false
26
+ if [[ "${1:-}" == "--json" || "${1:-}" == "-j" ]]; then
27
+ JSON_OUTPUT=true
28
+ fi
29
+
30
+ extract_json() {
31
+ # strip any leading noise before the JSON payload
32
+ awk 'BEGIN{p=0} /^[[:space:]]*[{]/{p=1} p{print}'
33
+ }
34
+
35
+ health_json=$(env -u SHELLOPTS bash "$SCRIPT_DIR/health.sh" --json 2>/dev/null | extract_json)
36
+ security_json=$(env -u SHELLOPTS bash "$SCRIPT_DIR/security-score.sh" --json 2>/dev/null | extract_json)
37
+ perf_json=$(env -u SHELLOPTS bash "$SCRIPT_DIR/perf.sh" --json 2>/dev/null | extract_json)
38
+
39
+ if [[ -z "$health_json" || -z "$security_json" || -z "$perf_json" ]]; then
40
+ ui_err "scorecard" "failed to collect JSON metrics"
41
+ exit 1
42
+ fi
43
+
44
+ health_score=$(python3 -c 'import json,sys; j=json.loads(sys.stdin.read()); print(j.get("score",0))' <<<"$health_json")
45
+ health_warnings=$(python3 -c 'import json,sys; j=json.loads(sys.stdin.read()); print(j.get("warnings",0))' <<<"$health_json")
46
+ health_failures=$(python3 -c 'import json,sys; j=json.loads(sys.stdin.read()); print(j.get("failures",0))' <<<"$health_json")
47
+ security_score=$(python3 -c 'import json,sys; j=json.loads(sys.stdin.read()); print(j.get("score",0))' <<<"$security_json")
48
+ perf_score=$(python3 -c 'import json,sys; j=json.loads(sys.stdin.read()); print(j.get("score",0))' <<<"$perf_json")
49
+ perf_mean=$(python3 -c 'import json,sys; j=json.loads(sys.stdin.read()); print(j.get("mean_ms",0))' <<<"$perf_json")
50
+ perf_target=$(python3 -c 'import json,sys; j=json.loads(sys.stdin.read()); print(j.get("target_ms",0))' <<<"$perf_json")
51
+
52
+ # Drift count
53
+ if command -v chezmoi >/dev/null 2>&1; then
54
+ drift_count=$(chezmoi status 2>/dev/null | wc -l | tr -d ' ')
55
+ else
56
+ drift_count=0
57
+ fi
58
+
59
+ dot_log info "scorecard_complete" "health=$health_score" "security=$security_score" "perf=$perf_score"
60
+ dot_metric "scorecard_health" "$health_score" "percent"
61
+ dot_metric "scorecard_security" "$security_score" "percent"
62
+ dot_metric "scorecard_perf" "$perf_score" "percent"
63
+
64
+ if $JSON_OUTPUT; then
65
+ cat <<JSON
66
+ {
67
+ "health": {"score": $health_score, "warnings": $health_warnings, "failures": $health_failures},
68
+ "security": {"score": $security_score},
69
+ "performance": {"score": $perf_score, "mean_ms": $perf_mean, "target_ms": $perf_target},
70
+ "drift": {"count": $drift_count}
71
+ }
72
+ JSON
73
+ exit 0
74
+ fi
75
+
76
+ ui_dot_banner "Diagnostics"
77
+ ui_header "Dotfiles Scorecard"
78
+
79
+ ui_section "Scores"
80
+ ui_kv "Health" "${health_score}/100"
81
+ ui_kv "Security" "${security_score}/100"
82
+ ui_kv "Performance" "${perf_score}/100 (avg ${perf_mean}ms, target ${perf_target}ms)"
83
+ ui_kv "Drift" "${drift_count} file(s)"
84
+
85
+ if [[ "$security_score" -lt 100 ]]; then
86
+ ui_warn "Security" "Run 'dot security-score' to reach 100/100"
87
+ else
88
+ ui_ok "Security" "100/100"
89
+ fi
90
+
91
+ if [[ "$perf_score" -lt 100 ]]; then
92
+ ui_warn "Performance" "Tune startup to reach 100/100"
93
+ else
94
+ ui_ok "Performance" "100/100"
95
+ fi
96
+
97
+ if [[ "$health_failures" -gt 0 ]]; then
98
+ ui_err "Health" "Failures detected (run 'dot heal')"
99
+ elif [[ "$health_warnings" -gt 0 ]]; then
100
+ ui_warn "Health" "Warnings detected (run 'dot heal')"
101
+ else
102
+ ui_ok "Health" "All checks passing"
103
+ fi
104
+
105
+ ui_section "Tips"
106
+ ui_info "Fix" "dot heal"
107
+ ui_info "Profile" "dot perf --profile"
108
+ ui_info "Security" "dot security-score"
109
+ ui_info "Drift" "dot drift"
110
+
111
+ exit_code=0
112
+ if [[ "$security_score" -lt 100 ]]; then
113
+ exit_code=1
114
+ fi
115
+ if [[ "$perf_score" -lt 100 ]]; then
116
+ exit_code=1
117
+ fi
118
+ exit "$exit_code"
@@ -0,0 +1,58 @@
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
+ REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
7
+ # shellcheck source=../lib/secrets_provider.sh
8
+ # shellcheck disable=SC1091
9
+ source "$REPO_ROOT/scripts/lib/secrets_provider.sh"
10
+
11
+ STRICT="${DOTFILES_ALIAS_STRICT_MODE:-${DOTFILES_SECRETS_STRICT_MODE:-0}}"
12
+
13
+ cd "$REPO_ROOT"
14
+
15
+ mapfile -t staged_files < <(git diff --cached --name-only --diff-filter=ACM || true)
16
+ if [[ "${#staged_files[@]}" -eq 0 ]]; then
17
+ echo "Secret governance: no staged files."
18
+ exit 0
19
+ fi
20
+
21
+ staged_content() {
22
+ local f
23
+ for f in "${staged_files[@]}"; do
24
+ git show -- ":$f" 2>/dev/null || true
25
+ done
26
+ }
27
+
28
+ violations=0
29
+ tmp_content="$(umask 077 && mktemp)"
30
+ trap 'rm -f "$tmp_content"' EXIT
31
+ staged_content >"$tmp_content"
32
+
33
+ scan_patterns="(api[_-]?key|api[_-]?secret|token|password)[[:space:]]*[:=][[:space:]]*[\"'][^\"']{8,}[\"']"
34
+ if grep -Eqi "$scan_patterns" "$tmp_content"; then
35
+ echo "Secret governance: potential plaintext secret pattern detected in staged content."
36
+ violations=$((violations + 1))
37
+ fi
38
+
39
+ if [[ "$STRICT" == "1" ]]; then
40
+ while IFS= read -r key; do
41
+ [[ -n "$key" ]] || continue
42
+ value="$(dot_secrets_get "$key" || true)"
43
+ [[ -n "$value" ]] || continue
44
+ [[ "${#value}" -ge 8 ]] || continue
45
+
46
+ if grep -Fq "$value" "$tmp_content"; then
47
+ echo "Secret governance: exact managed secret value leaked for key: $key"
48
+ violations=$((violations + 1))
49
+ fi
50
+ done < <(dot_secrets_index_list)
51
+ fi
52
+
53
+ if [[ "$violations" -gt 0 ]]; then
54
+ echo "Secret governance failed: $violations violation(s)."
55
+ exit 1
56
+ fi
57
+
58
+ echo "Secret governance passed."