@sebastienrousseau/dotfiles 0.2.481 → 0.2.500

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (546) hide show
  1. package/CHANGELOG.md +122 -32
  2. package/LICENSE +1 -1
  3. package/README.md +211 -242
  4. package/docs/.vitepress/reports/localization-readability-audit.md +69 -0
  5. package/docs/AI.md +102 -0
  6. package/docs/COPYRIGHT +2 -2
  7. package/docs/NAMING_CONVENTIONS.md +95 -0
  8. package/docs/README.md +58 -249
  9. package/docs/adr/ADR-004-cli-architecture.md +2 -2
  10. package/docs/adr/ADR-006-shell-selection.md +2 -2
  11. package/docs/adr/ADR-007-multi-shell-parity.md +53 -0
  12. package/docs/adr/ADR-008-alias-system-architecture.md +85 -0
  13. package/docs/adr/README.md +2 -3
  14. package/docs/architecture/ARCHITECTURE.md +113 -0
  15. package/docs/architecture/INTEROP.md +36 -0
  16. package/docs/architecture/REPO_LAYOUT.md +237 -0
  17. package/docs/architecture/WALKTHROUGH.md +82 -0
  18. package/docs/architecture/fleet-deployment.md +73 -0
  19. package/docs/archive/EUXIS_2026_REVIEW.md +119 -0
  20. package/docs/archive/MILESTONE_v0.2.493.md +43 -0
  21. package/docs/{PLAN.md → archive/PLAN.md} +1 -1
  22. package/docs/guides/INSTALL.md +140 -0
  23. package/docs/{NEOVIM_IDE_GUIDE.md → guides/NEOVIM_IDE_GUIDE.md} +12 -12
  24. package/docs/guides/THEMING.md +222 -0
  25. package/docs/{TROUBLESHOOTING.md → guides/TROUBLESHOOTING.md} +36 -0
  26. package/docs/{WSL2_NIX_TROUBLESHOOTING.md → guides/WSL2_NIX_TROUBLESHOOTING.md} +8 -8
  27. package/docs/index.md +39 -0
  28. package/docs/interop/A2A.md +32 -0
  29. package/docs/manual/00-introduction.md +85 -0
  30. package/docs/manual/01-concepts/01-architecture.md +134 -0
  31. package/docs/manual/01-concepts/02-trust-model.md +178 -0
  32. package/docs/manual/01-concepts/03-theme-engine.md +182 -0
  33. package/docs/manual/01-concepts/04-fleet.md +142 -0
  34. package/docs/manual/01-concepts/05-self-healing.md +197 -0
  35. package/docs/manual/02-tutorials/01-first-install.md +192 -0
  36. package/docs/manual/02-tutorials/02-add-wallpaper.md +211 -0
  37. package/docs/manual/02-tutorials/03-create-profile.md +238 -0
  38. package/docs/manual/02-tutorials/04-encrypt-secret.md +275 -0
  39. package/docs/manual/02-tutorials/05-deploy-fleet.md +279 -0
  40. package/docs/manual/03-reference/01-dot-cli.md +413 -0
  41. package/docs/manual/03-reference/02-config-files.md +259 -0
  42. package/docs/manual/03-reference/03-environment.md +120 -0
  43. package/docs/manual/03-reference/04-templates.md +184 -0
  44. package/docs/manual/03-reference/05-feature-flags.md +118 -0
  45. package/docs/manual/04-cookbook/01-recipes.md +281 -0
  46. package/docs/manual/04-cookbook/02-troubleshooting.md +319 -0
  47. package/docs/manual/04-cookbook/03-faq.md +167 -0
  48. package/docs/manual/05-appendices/A-platform-matrix.md +97 -0
  49. package/docs/manual/05-appendices/B-security-checklist.md +78 -0
  50. package/docs/manual/05-appendices/C-glossary.md +36 -0
  51. package/docs/manual/05-appendices/D-bibliography.md +54 -0
  52. package/docs/manual/05-appendices/E-license.md +34 -0
  53. package/docs/manual/_toc.yml +58 -0
  54. package/docs/manual/command-index.md +58 -0
  55. package/docs/manual/concept-index.md +164 -0
  56. package/docs/operations/ATTESTATION.md +39 -0
  57. package/docs/operations/MAINTENANCE.md +59 -0
  58. package/docs/operations/MIGRATION.md +101 -0
  59. package/docs/operations/OPERATIONS.md +164 -0
  60. package/docs/operations/RELIABILITY.md +116 -0
  61. package/docs/{ROADMAP.md → operations/ROADMAP.md} +11 -11
  62. package/docs/operations/TESTING.md +195 -0
  63. package/docs/operations/TRACEABILITY.md +31 -0
  64. package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +61 -0
  65. package/docs/operations/VERSION_SYNC.md +344 -0
  66. package/docs/{ALIASES.md → reference/ALIASES.md} +2 -6
  67. package/docs/reference/ALIASES_CHEATSHEET.md +28 -0
  68. package/docs/reference/ALIASES_DEPRECATIONS.md +9 -0
  69. package/docs/reference/FEATURES.md +62 -0
  70. package/docs/reference/FONTS.md +108 -0
  71. package/docs/reference/PROFILES.md +65 -0
  72. package/docs/{SCREENSHOTS.md → reference/SCREENSHOTS.md} +26 -25
  73. package/docs/reference/SCRIPTS.md +67 -0
  74. package/docs/reference/SUPPORT_MATRIX.md +74 -0
  75. package/docs/reference/THEMES.md +113 -0
  76. package/docs/reference/TOOLS.md +105 -0
  77. package/docs/reference/UTILS.md +151 -0
  78. package/docs/security/AI_ACT_COMPLIANCE.md +90 -0
  79. package/docs/security/AUTOMATION_SECRETS.md +22 -0
  80. package/docs/security/COMPLIANCE.md +453 -0
  81. package/docs/security/ENCRYPTION.md +52 -0
  82. package/docs/security/FMEA.md +155 -0
  83. package/docs/security/INCIDENT_RESPONSE.md +575 -0
  84. package/docs/security/KEYS.md +45 -0
  85. package/docs/security/MCP_POLICY.md +69 -0
  86. package/docs/security/POLICY_RELEASES.md +33 -0
  87. package/docs/security/README.md +24 -0
  88. package/docs/security/SECRETS.md +146 -0
  89. package/docs/security/SECURITY.md +41 -0
  90. package/docs/security/SECURITY_CHECKLIST.md +44 -0
  91. package/docs/security/SOUP_REGISTER.md +32 -0
  92. package/docs/security/THREAT_MODEL.md +120 -0
  93. package/docs/security/VERIFICATION_VALIDATION.md +224 -0
  94. package/docs/themes/README.md +3 -17
  95. package/docs/themes/VISUAL_INTEGRITY_REPORT.md +26 -0
  96. package/docs/themes/hero-shot.svg +78 -0
  97. package/dot_config/.module-manifest.json +69 -0
  98. package/dot_config/ai/identity.md +20 -0
  99. package/dot_config/ai/patterns/architect.md +14 -0
  100. package/dot_config/ai/patterns/hardener.md +13 -0
  101. package/dot_config/ai/patterns/refactor.md +13 -0
  102. package/dot_config/aider/aider.conf.yml +1 -1
  103. package/dot_config/alacritty/alacritty.toml.tmpl +41 -469
  104. package/dot_config/atuin/config.toml +18 -1
  105. package/dot_config/bat/config +16 -1
  106. package/dot_config/claude/mcp_servers.json +3 -32
  107. package/dot_config/dotfiles/agent-card.json +29 -0
  108. package/dot_config/dotfiles/agent-profiles.json +92 -0
  109. package/dot_config/dotfiles/boot/README.md +1 -1
  110. package/dot_config/dotfiles/grub/README.md +1 -1
  111. package/dot_config/dotfiles/lock/README.md +1 -1
  112. package/dot_config/dotfiles/mcp-lock.json +33 -0
  113. package/dot_config/dotfiles/mcp-policy.json +52 -0
  114. package/dot_config/dotfiles/mcp-registry.json +47 -0
  115. package/dot_config/dotfiles/model-registry.json +20 -0
  116. package/dot_config/dotfiles/policy-bundles.json +38 -0
  117. package/dot_config/dotfiles/prompt-registry.json +16 -0
  118. package/dot_config/dotfiles/versions.env +18 -0
  119. package/dot_config/environment.d/50-ssh-agent.conf +2 -0
  120. package/dot_config/environment.d/90-wayland.conf +19 -0
  121. package/dot_config/firefox/user.js.tmpl +58 -0
  122. package/dot_config/fish/completions/dot-theme-sync.fish.tmpl +9 -0
  123. package/dot_config/fish/completions/dot.fish.tmpl +115 -0
  124. package/dot_config/fish/conf.d/000-perf-cache.fish +56 -0
  125. package/dot_config/fish/conf.d/aliases.fish.tmpl +77 -0
  126. package/dot_config/fish/conf.d/env.fish.tmpl +48 -0
  127. package/dot_config/fish/conf.d/functions.fish.tmpl +22 -0
  128. package/dot_config/fish/conf.d/init.fish.tmpl +151 -0
  129. package/dot_config/fish/config.fish.tmpl +44 -0
  130. package/dot_config/fish/fish_plugins +1 -0
  131. package/dot_config/fish/functions/_.fish +3 -0
  132. package/dot_config/fish/functions/_cached_eval.fish +58 -0
  133. package/dot_config/fish/functions/als.fish +46 -0
  134. package/dot_config/fish/functions/bg-upgrade.fish +7 -0
  135. package/dot_config/fish/functions/c.fish +3 -0
  136. package/dot_config/fish/functions/cat.fish +9 -0
  137. package/dot_config/fish/functions/d.fish +7 -0
  138. package/dot_config/fish/functions/dot.fish +34 -0
  139. package/dot_config/fish/functions/h.fish +3 -0
  140. package/dot_config/fish/functions/l.fish +7 -0
  141. package/dot_config/fish/functions/la.fish +7 -0
  142. package/dot_config/fish/functions/ll.fish +7 -0
  143. package/dot_config/fish/functions/log_error.fish +13 -0
  144. package/dot_config/fish/functions/log_info.fish +13 -0
  145. package/dot_config/fish/functions/lr.fish +7 -0
  146. package/dot_config/fish/functions/lra.fish +7 -0
  147. package/dot_config/fish/functions/ls.fish +7 -0
  148. package/dot_config/fish/functions/lt.fish +7 -0
  149. package/dot_config/fish/functions/lta.fish +7 -0
  150. package/dot_config/fish/functions/notify-run.fish +11 -0
  151. package/dot_config/fish/functions/q.fish +3 -0
  152. package/dot_config/fish/functions/silent-run.fish +7 -0
  153. package/dot_config/fish/functions/yy.fish +8 -0
  154. package/dot_config/fontconfig/fonts.conf.tmpl +13 -0
  155. package/dot_config/foot/foot.ini.tmpl +33 -0
  156. package/dot_config/fuzzel/fuzzel.ini.tmpl +18 -0
  157. package/dot_config/fzf/fzf.zsh +48 -0
  158. package/dot_config/ghostty/config.tmpl +69 -565
  159. package/dot_config/git/allowed_signers.tmpl +18 -0
  160. package/dot_config/git/commit-template +10 -0
  161. package/dot_config/gnupg/{gpg-agent.conf.tmpl → gpg-agent.conf} +3 -3
  162. package/dot_config/goose/config.yaml +2 -2
  163. package/dot_config/gtk-3.0/gtk.css.tmpl +59 -180
  164. package/dot_config/gtk-3.0/settings.ini.tmpl +5 -44
  165. package/dot_config/gtk-4.0/gtk.css.tmpl +79 -136
  166. package/dot_config/gtk-4.0/settings.ini.tmpl +5 -8
  167. package/dot_config/ipython/profile_default/ipython_config.py +19 -0
  168. package/dot_config/just/justfile +18 -0
  169. package/dot_config/kanshi/config.tmpl +22 -0
  170. package/dot_config/kitty/kitty.conf.tmpl +44 -508
  171. package/dot_config/lazygit/config.yml +18 -6
  172. package/dot_config/mako/config +47 -0
  173. package/dot_config/micro/settings.json +3 -0
  174. package/dot_config/mimeapps.list +77 -0
  175. package/dot_config/mise/config.toml +63 -5
  176. package/dot_config/mongosh/mongoshrc.js +1 -0
  177. package/dot_config/mpv/input.conf +47 -0
  178. package/dot_config/mpv/mpv.conf +47 -0
  179. package/dot_config/niri/config.kdl.tmpl +327 -0
  180. package/dot_config/nushell/aliases.nu +18 -0
  181. package/dot_config/nushell/completions.nu.tmpl +52 -0
  182. package/dot_config/nushell/config.nu.tmpl +86 -0
  183. package/dot_config/nushell/env.nu.tmpl +94 -0
  184. package/dot_config/nushell/functions.nu.tmpl +17 -0
  185. package/dot_config/nvim/init.lua +14 -0
  186. package/dot_config/nvim/lazy-lock.json +45 -14
  187. package/dot_config/nvim/lua/config/autocmds.lua +45 -1
  188. package/dot_config/nvim/lua/config/keymaps.lua +13 -8
  189. package/dot_config/nvim/lua/config/lazy.lua +22 -12
  190. package/dot_config/nvim/lua/config/options.lua +1 -0
  191. package/dot_config/nvim/lua/plugins/ai.lua +75 -0
  192. package/dot_config/nvim/lua/plugins/coding.lua +11 -29
  193. package/dot_config/nvim/lua/plugins/completion.lua +60 -0
  194. package/dot_config/nvim/lua/plugins/dap.lua +215 -4
  195. package/dot_config/nvim/lua/plugins/editor.lua +6 -10
  196. package/dot_config/nvim/lua/plugins/git.lua +1 -0
  197. package/dot_config/nvim/lua/plugins/lsp.lua +16 -81
  198. package/dot_config/nvim/lua/plugins/markdown.lua +1 -0
  199. package/dot_config/nvim/lua/plugins/rust.lua +1 -0
  200. package/dot_config/nvim/lua/plugins/sessions.lua +1 -0
  201. package/dot_config/nvim/lua/plugins/ui.lua +23 -51
  202. package/dot_config/paru/paru.conf +10 -0
  203. package/dot_config/powershell/Microsoft.PowerShell_profile.ps1.tmpl +81 -0
  204. package/dot_config/pueue/pueue.yml +34 -0
  205. package/dot_config/raycast/README.md +1 -1
  206. package/dot_config/ripgrep/ripgreprc +21 -0
  207. package/dot_config/shell/00-core-paths.sh.tmpl +62 -24
  208. package/dot_config/shell/05-core-safety.sh +47 -0
  209. package/dot_config/shell/10-secrets.sh +40 -0
  210. package/dot_config/shell/40-fzf-defaults.sh.tmpl +16 -0
  211. package/dot_config/shell/40-ls-colors.sh +48 -0
  212. package/dot_config/shell/50-logic-functions-core.sh.tmpl +10 -0
  213. package/dot_config/shell/51-logic-functions-extra.sh.tmpl +64 -0
  214. package/dot_config/shell/90-ux-aliases.sh.tmpl +90 -5
  215. package/dot_config/shell/91-ux-aliases-lazy.sh.tmpl +33 -2
  216. package/dot_config/shell/Brewfile.cli +8 -0
  217. package/dot_config/shell/README.md +9 -9
  218. package/dot_config/shell/als_data.txt.tmpl +65 -0
  219. package/dot_config/shell/custom/auto_ls.zsh +20 -0
  220. package/dot_config/shell/custom/context_suggest.zsh +50 -50
  221. package/dot_config/shell/custom/error_analysis.zsh +29 -29
  222. package/dot_config/starship.toml.tmpl +85 -7
  223. package/dot_config/swaylock/config +43 -0
  224. package/dot_config/systemd/user/dotfiles-maintenance.service +8 -0
  225. package/dot_config/systemd/user/dotfiles-maintenance.timer +11 -0
  226. package/dot_config/systemd/user/pueued.service +12 -0
  227. package/dot_config/systemd/user/ssh-agent.service +12 -0
  228. package/dot_config/tmux/tmux.conf.tmpl +80 -38
  229. package/dot_config/topgrade.toml.tmpl +54 -0
  230. package/dot_config/user-dirs.dirs +9 -0
  231. package/dot_config/vscode/settings.json.tmpl +9 -50
  232. package/dot_config/waybar/config.jsonc.tmpl +90 -0
  233. package/dot_config/waybar/style.css.tmpl +211 -0
  234. package/dot_config/wezterm/wezterm.lua.tmpl +31 -203
  235. package/dot_config/xdg-desktop-portal/niri-portals.conf +5 -0
  236. package/dot_config/yazi/keymap.toml +67 -0
  237. package/dot_config/yazi/theme.toml +102 -0
  238. package/dot_config/zathura/zathurarc +52 -0
  239. package/dot_config/zellij/{config.kdl → config.kdl.tmpl} +1 -1
  240. package/dot_config/zsh/dot_zprofile +1 -7
  241. package/dot_config/zsh/dot_zshenv +2 -3
  242. package/dot_config/zsh/dot_zshrc.tmpl +368 -69
  243. package/dot_config/zsh/rc.d/00-alias-shims.zsh +77 -0
  244. package/dot_config/zsh/rc.d/05-ssh-agent.zsh +17 -4
  245. package/dot_config/zsh/rc.d/10-env.zsh.tmpl +4 -4
  246. package/dot_config/zsh/rc.d/20-zinit.zsh +65 -0
  247. package/dot_config/zsh/rc.d/30-options.zsh.tmpl +101 -30
  248. package/dot_config/zsh/rc.d/99-alias-wrapper.zsh +32 -0
  249. package/dot_local/bin/__pycache__/executable_dot-load-benchmark-ptycpython-312.pyc +0 -0
  250. package/dot_local/bin/executable_ai-update +195 -0
  251. package/dot_local/bin/executable_ai_core +113 -91
  252. package/dot_local/bin/executable_antigravity +11 -0
  253. package/dot_local/bin/executable_b64 +61 -36
  254. package/dot_local/bin/executable_bm +77 -0
  255. package/dot_local/bin/executable_cb +39 -0
  256. package/dot_local/bin/executable_dot +543 -132
  257. package/dot_local/bin/executable_dot-ai +36 -0
  258. package/dot_local/bin/executable_dot-bootstrap +77 -0
  259. package/dot_local/bin/executable_dot-launch-or-focus +52 -0
  260. package/dot_local/bin/executable_dot-load-benchmark +31 -0
  261. package/dot_local/bin/executable_dot-load-benchmark-pty +77 -0
  262. package/dot_local/bin/executable_dot-theme-sync +952 -0
  263. package/dot_local/bin/executable_dot_completion +2 -0
  264. package/dot_local/bin/executable_dtags +28 -0
  265. package/dot_local/bin/executable_epoch +43 -38
  266. package/dot_local/bin/executable_extract +32 -99
  267. package/dot_local/bin/executable_gbd +52 -0
  268. package/dot_local/bin/executable_gd +42 -0
  269. package/dot_local/bin/executable_git-ai-commit +35 -20
  270. package/dot_local/bin/executable_git-ai-diff +33 -18
  271. package/dot_local/bin/executable_gl +101 -0
  272. package/dot_local/bin/executable_hash +56 -18
  273. package/dot_local/bin/executable_hashsum +160 -0
  274. package/dot_local/bin/executable_hex +44 -8
  275. package/dot_local/bin/executable_jsonv +34 -10
  276. package/dot_local/bin/executable_jwt +22 -6
  277. package/dot_local/bin/executable_kill-port +18 -2
  278. package/dot_local/bin/executable_lorem +21 -6
  279. package/dot_local/bin/executable_mkscript +35 -0
  280. package/dot_local/bin/executable_monitor +56 -0
  281. package/dot_local/bin/{executable_ip → executable_myip} +16 -2
  282. package/dot_local/bin/executable_notify +22 -0
  283. package/dot_local/bin/executable_open +36 -0
  284. package/dot_local/bin/executable_pw +27 -0
  285. package/dot_local/bin/executable_rec-start +46 -0
  286. package/dot_local/bin/executable_rec-stop +35 -0
  287. package/dot_local/bin/executable_regex +49 -13
  288. package/dot_local/bin/executable_start-niri +8 -0
  289. package/dot_local/bin/executable_tmux-sessionizer +276 -149
  290. package/dot_local/bin/executable_tour +112 -74
  291. package/dot_local/bin/executable_up +21 -0
  292. package/dot_local/bin/executable_update +45 -11
  293. package/dot_local/bin/executable_uuid +37 -7
  294. package/dot_local/bin/executable_win +32 -0
  295. package/dot_local/bin/executable_yamlv +25 -7
  296. package/dot_local/share/bash-completion/completions/dot +62 -44
  297. package/dot_local/share/icons/hicolor/128x128/apps/rousseau.png +0 -0
  298. package/dot_local/share/icons/hicolor/16x16/apps/rousseau.png +0 -0
  299. package/dot_local/share/icons/hicolor/24x24/apps/rousseau.png +0 -0
  300. package/dot_local/share/icons/hicolor/256x256/apps/rousseau.png +0 -0
  301. package/dot_local/share/icons/hicolor/32x32/apps/rousseau.png +0 -0
  302. package/dot_local/share/icons/hicolor/48x48/apps/rousseau.png +0 -0
  303. package/dot_local/share/icons/hicolor/512x512/apps/rousseau.png +0 -0
  304. package/dot_local/share/icons/hicolor/64x64/apps/rousseau.png +0 -0
  305. package/dot_local/share/icons/hicolor/96x96/apps/rousseau.png +0 -0
  306. package/dot_local/share/icons/hicolor/scalable/apps/rousseau.png +0 -0
  307. package/dot_local/share/man/man1/dot.1 +149 -0
  308. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_download +64 -0
  309. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_install +18 -0
  310. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_list-all +13 -0
  311. package/dot_local/share/wayland-sessions/niri.desktop.tmpl +6 -0
  312. package/dot_local/share/zsh/completions/_dot +283 -0
  313. package/install.sh +297 -210
  314. package/package.json +17 -5
  315. package/scripts/ci/check-copyright-headers.sh +96 -0
  316. package/scripts/ci/guard-gitleaks-checkout.sh +57 -0
  317. package/scripts/ci/install-chezmoi-verified.sh +64 -0
  318. package/scripts/ci/validate-ci-config.sh +41 -39
  319. package/scripts/demo/record.sh +3 -2
  320. package/scripts/diagnostics/a2a-conformance.sh +162 -0
  321. package/scripts/diagnostics/alias-governance.sh +137 -0
  322. package/scripts/diagnostics/aliases-cheatsheet.sh +73 -0
  323. package/scripts/diagnostics/aliases-manifest.sh +31 -0
  324. package/scripts/diagnostics/benchmark.sh +209 -29
  325. package/scripts/diagnostics/conflicts.sh +72 -0
  326. package/scripts/diagnostics/doctor-unified.sh +38 -0
  327. package/scripts/diagnostics/doctor.sh +491 -65
  328. package/scripts/diagnostics/drift-dashboard.sh +17 -6
  329. package/scripts/diagnostics/health.sh +351 -110
  330. package/scripts/diagnostics/history-analysis.sh +12 -4
  331. package/scripts/diagnostics/mcp-doctor.sh +575 -0
  332. package/scripts/diagnostics/perf.sh +225 -0
  333. package/scripts/diagnostics/scorecard.sh +118 -0
  334. package/scripts/diagnostics/secret-governance.sh +58 -0
  335. package/scripts/diagnostics/security-score.sh +139 -93
  336. package/scripts/diagnostics/smoke-test.sh +87 -0
  337. package/scripts/diagnostics/snapshot.sh +89 -0
  338. package/scripts/diagnostics/verify.sh +107 -0
  339. package/scripts/diagnostics/verify_state.sh +2 -2
  340. package/scripts/diagnostics/version-locks.sh +79 -0
  341. package/scripts/diagnostics/workstation-attestation.sh +181 -0
  342. package/scripts/docs/build-manual.sh +883 -0
  343. package/scripts/docs/check-manual.sh +213 -0
  344. package/scripts/dot/commands/agent.sh +465 -0
  345. package/scripts/dot/commands/ai.sh +416 -0
  346. package/scripts/dot/commands/aliases.sh +250 -0
  347. package/scripts/dot/commands/appearance.sh +21 -4
  348. package/scripts/dot/commands/core.sh +59 -4
  349. package/scripts/dot/commands/diagnostics.sh +132 -3
  350. package/scripts/dot/commands/fleet.sh +399 -0
  351. package/scripts/dot/commands/lint.sh +177 -0
  352. package/scripts/dot/commands/manual.sh +168 -0
  353. package/scripts/dot/commands/meta.sh +148 -17
  354. package/scripts/dot/commands/patterns.sh +54 -0
  355. package/scripts/dot/commands/restore.sh +57 -35
  356. package/scripts/dot/commands/secrets.sh +151 -9
  357. package/scripts/dot/commands/security.sh +3 -0
  358. package/scripts/dot/commands/tools.sh +268 -27
  359. package/scripts/dot/data/alias-deprecations.tsv +2 -0
  360. package/scripts/dot/lib/bento.sh +49 -0
  361. package/scripts/dot/lib/log.sh +194 -0
  362. package/scripts/dot/lib/platform.sh +98 -0
  363. package/scripts/dot/lib/ui.sh +507 -0
  364. package/scripts/dot/lib/utils.sh +318 -18
  365. package/scripts/fonts/install-nerd-fonts.sh +19 -10
  366. package/scripts/fonts/patch-fonts.sh +1 -0
  367. package/scripts/git-hooks/install.sh +11 -0
  368. package/scripts/git-hooks/pre-commit +12 -0
  369. package/scripts/git-hooks/pre-commit-audit.sh +145 -0
  370. package/scripts/git-hooks/pre-push +29 -0
  371. package/scripts/git-hooks/prepare-commit-msg +29 -0
  372. package/scripts/lib/secrets_provider.sh +158 -0
  373. package/scripts/maintenance/check-updates.sh +131 -0
  374. package/scripts/ops/ai-setup.sh +55 -0
  375. package/scripts/ops/bundle.sh +77 -0
  376. package/scripts/ops/chaos.sh +49 -0
  377. package/scripts/ops/chezmoi-apply.sh +245 -17
  378. package/scripts/ops/chezmoi-diff.sh +1 -0
  379. package/scripts/ops/chezmoi-remove.sh +2 -0
  380. package/scripts/ops/chezmoi-update.sh +34 -2
  381. package/scripts/ops/heal-chezmoi.sh +51 -0
  382. package/scripts/ops/heal-system.sh +128 -0
  383. package/scripts/ops/heal-tools.sh +340 -0
  384. package/scripts/ops/heal.sh +98 -342
  385. package/scripts/ops/post-apply-repair.sh +106 -0
  386. package/scripts/ops/prewarm.sh +127 -0
  387. package/scripts/ops/release.sh +252 -0
  388. package/scripts/ops/rollback.sh +86 -28
  389. package/scripts/ops/setup.sh +137 -0
  390. package/scripts/ops/teleport.sh +2 -1
  391. package/scripts/qa/coverage-baseline.sh +60 -0
  392. package/scripts/qa/docs-coverage.sh +111 -0
  393. package/scripts/qa/reliability-audit.sh +138 -0
  394. package/scripts/qa/traceability-coverage.sh +116 -0
  395. package/scripts/qa/validate-examples.sh +26 -0
  396. package/scripts/qa/wsl-contract.sh +11 -0
  397. package/scripts/release/package-policy-bundles.sh +125 -0
  398. package/scripts/secrets/age-init.sh +1 -0
  399. package/scripts/secrets/create-secrets-file.sh +1 -0
  400. package/scripts/secrets/encrypt-ssh-key.sh +1 -0
  401. package/scripts/security/backup.sh +44 -4
  402. package/scripts/security/dns-doh.sh +36 -14
  403. package/scripts/security/encryption-check.sh +27 -12
  404. package/scripts/security/enforce-policies.sh +11 -16
  405. package/scripts/security/firewall.sh +76 -20
  406. package/scripts/security/lock-configs.sh +2 -2
  407. package/scripts/security/lock-screen.sh +40 -18
  408. package/scripts/security/manage-secrets.sh +42 -29
  409. package/scripts/security/ssh-cert.sh +203 -0
  410. package/scripts/security/telemetry-kill.sh +40 -18
  411. package/scripts/security/usb-safety.sh +37 -15
  412. package/scripts/theme/apply-gnome-theme.sh +87 -56
  413. package/scripts/theme/extract-theme.py +677 -0
  414. package/scripts/theme/install-boot-logo.sh +1 -0
  415. package/scripts/theme/install-catppuccin-themes.sh +57 -33
  416. package/scripts/theme/install-cursors.sh +1 -0
  417. package/scripts/theme/install-file-icons.sh +1 -0
  418. package/scripts/theme/install-grub-theme.sh +11 -1
  419. package/scripts/theme/install-lock-icon.sh +1 -0
  420. package/scripts/theme/merge-wallpaper.sh +141 -0
  421. package/scripts/theme/rebuild-themes.sh +309 -0
  422. package/scripts/theme/switch.sh +308 -137
  423. package/scripts/theme/wallpaper-rotate.sh +66 -12
  424. package/scripts/theme/wallpaper-sync.sh +386 -31
  425. package/scripts/tools/cmatrix.sh +1 -0
  426. package/scripts/tools/detect-collisions.py +1 -1
  427. package/scripts/tools/emoji-picker.sh +4 -1
  428. package/scripts/tools/figlet-banner.sh +1 -0
  429. package/scripts/tools/log-rotate.sh +2 -1
  430. package/scripts/tools/lolcat-wrap.sh +1 -0
  431. package/scripts/tools/pipes.sh +1 -0
  432. package/scripts/tuning/linux.sh +23 -13
  433. package/scripts/tuning/macos.sh +13 -4
  434. package/scripts/uninstall.sh +85 -0
  435. package/scripts/version-sync.sh +487 -0
  436. package/templates/chezmoi-data/geekom-a9.toml.example +21 -0
  437. package/templates/chezmoi-data/mac-m1.toml.example +16 -0
  438. package/templates/chezmoi-data/mac-t2-linux.toml.example +21 -0
  439. package/templates/chezmoi-data/surface-pro-7p.toml.example +21 -0
  440. package/templates/projects/go/.github/workflows/ci.yml +31 -0
  441. package/templates/projects/go/README.md +1 -1
  442. package/templates/projects/go/cmd/__PROJECT_NAME__/main.go +1 -0
  443. package/templates/projects/go/go.sum +0 -0
  444. package/templates/projects/molecule/README.md +1 -1
  445. package/templates/projects/node/.github/workflows/ci.yml +30 -0
  446. package/templates/projects/node/README.md +1 -1
  447. package/templates/projects/node/package-lock.json +12 -0
  448. package/templates/projects/node/src/index.js +1 -0
  449. package/templates/projects/packer/README.md +1 -1
  450. package/templates/projects/python/.github/workflows/ci.yml +34 -0
  451. package/templates/projects/python/README.md +1 -1
  452. package/templates/projects/python/src/__PROJECT_NAME__/__init__.py +1 -0
  453. package/templates/projects/python/tests/test_basic.py +1 -0
  454. package/docs/ARCHITECTURE.md +0 -229
  455. package/docs/COMPLIANCE.md +0 -47
  456. package/docs/FEATURES.md +0 -166
  457. package/docs/FONTS.md +0 -147
  458. package/docs/INSTALL.md +0 -119
  459. package/docs/KEYS.md +0 -40
  460. package/docs/OPERATIONS.md +0 -130
  461. package/docs/PR_DESCRIPTION.md +0 -149
  462. package/docs/SECRETS.md +0 -76
  463. package/docs/SECURITY.md +0 -30
  464. package/docs/SECURITY_CHECKLIST.md +0 -25
  465. package/docs/TASK.md +0 -99
  466. package/docs/TESTING.md +0 -190
  467. package/docs/TOOLS.md +0 -146
  468. package/docs/UTILS.md +0 -105
  469. package/docs/WALKTHROUGH.md +0 -165
  470. package/dot_config/clippy.toml +0 -55
  471. package/dot_config/dotfiles/versions.env.tmpl +0 -19
  472. package/dot_config/firefox/user.js +0 -8
  473. package/dot_config/git/config.tmpl +0 -77
  474. package/dot_config/go/aliases.sh +0 -61
  475. package/dot_config/go/env.sh +0 -24
  476. package/dot_config/ice/README.md +0 -13
  477. package/dot_config/ipython/profile_default/ipython_config.py.tmpl +0 -5
  478. package/dot_config/lsd/config.yaml +0 -19
  479. package/dot_config/nvim/snippets/all.lua +0 -9
  480. package/dot_config/nvim/snippets/python.lua +0 -16
  481. package/dot_config/shell/00-container-detect.sh +0 -53
  482. package/dot_config/shell/05-core-safety.sh.tmpl +0 -13
  483. package/dot_config/shell/40-ls-colors.sh.tmpl +0 -31
  484. package/dot_config/shell/90-theme-switch.sh +0 -70
  485. package/dot_config/topgrade/topgrade.toml.tmpl +0 -42
  486. package/dot_config/waybar/style.css +0 -8
  487. package/dot_config/zsh/rc.d/20-zinit.zsh.tmpl +0 -22
  488. package/dot_local/bin/executable_zig-install +0 -89
  489. package/dot_local/bin/voice_ops +0 -7
  490. package/scripts/ops/health-check.sh +0 -380
  491. package/scripts/tests/README.md +0 -241
  492. package/scripts/tests/benchmark.sh +0 -91
  493. package/scripts/tests/framework/assertions.sh +0 -283
  494. package/scripts/tests/framework/mocks.sh +0 -201
  495. package/scripts/tests/framework/test_runner.sh +0 -189
  496. package/scripts/tests/integration/test_install.sh +0 -237
  497. package/scripts/tests/performance/benchmark_runner.sh +0 -156
  498. package/scripts/tests/performance/regression_check.sh +0 -73
  499. package/scripts/tests/performance/stress_test.sh +0 -65
  500. package/scripts/tests/test-aliases.sh +0 -25
  501. package/scripts/tests/test-docker.sh +0 -48
  502. package/scripts/tests/unit/test_ai_aliases.sh +0 -158
  503. package/scripts/tests/unit/test_ai_cli_checks.sh +0 -47
  504. package/scripts/tests/unit/test_backup.sh +0 -227
  505. package/scripts/tests/unit/test_case_functions.sh +0 -238
  506. package/scripts/tests/unit/test_cd_aliases.sh +0 -367
  507. package/scripts/tests/unit/test_dot_cli.sh +0 -217
  508. package/scripts/tests/unit/test_encode64.sh +0 -67
  509. package/scripts/tests/unit/test_environment.sh +0 -78
  510. package/scripts/tests/unit/test_extract.sh +0 -163
  511. package/scripts/tests/unit/test_framework_edge_cases.sh +0 -113
  512. package/scripts/tests/unit/test_genpass.sh +0 -298
  513. package/scripts/tests/unit/test_install_edge_cases.sh +0 -167
  514. package/scripts/tests/unit/test_installers.sh +0 -172
  515. package/scripts/tests/unit/test_keygen.sh +0 -68
  516. package/scripts/tests/unit/test_logging.sh +0 -96
  517. package/scripts/tests/unit/test_os_detection_comprehensive.sh +0 -388
  518. package/scripts/tests/unit/test_package_managers_comprehensive.sh +0 -321
  519. package/scripts/tests/unit/test_prependpath.sh +0 -66
  520. package/scripts/tests/unit/test_prependpath_refactored.sh +0 -89
  521. package/scripts/tests/unit/test_rd.sh +0 -230
  522. package/scripts/tests/unit/test_security_fixes.sh +0 -130
  523. package/scripts/tests/unit/test_security_scripts.sh +0 -87
  524. package/scripts/tests/unit/test_template_validation.sh +0 -238
  525. package/scripts/tests/unit/test_utility_functions.sh +0 -144
  526. package/scripts/tests/unit/test_wave1_alias_split.sh +0 -132
  527. package/scripts/tests/unit/test_wave1_ci_pinning.sh +0 -61
  528. package/scripts/tests/unit/test_wave1_gitleaks_config.sh +0 -52
  529. package/scripts/tests/unit/test_wave1_heal_fixes.sh +0 -97
  530. package/scripts/tests/unit/test_wave1_install_gpg.sh +0 -35
  531. package/scripts/tests/unit/test_wave1_zshenv_path.sh +0 -89
  532. package/scripts/tests/unit/test_wave1_zshrc_lazy_hook.sh +0 -115
  533. package/scripts/tests/unit/test_wave2_dot_new_guard.sh +0 -75
  534. package/scripts/tests/unit/test_zipf.sh +0 -76
  535. /package/docs/{LEGACY_ROADMAP.md → archive/LEGACY_ROADMAP.md} +0 -0
  536. /package/docs/{REPO_AUDIT.md → archive/REPO_AUDIT.md} +0 -0
  537. /package/docs/{KEY_ROTATION.md → security/KEY_ROTATION.md} +0 -0
  538. /package/dot_config/ansible/{ansible.cfg.tmpl → ansible.cfg} +0 -0
  539. /package/dot_config/docker/{config.json.tmpl → config.json} +0 -0
  540. /package/dot_config/k9s/{config.yaml.tmpl → config.yaml} +0 -0
  541. /package/dot_config/pypoetry/{config.toml.tmpl → config.toml} +0 -0
  542. /package/dot_config/{pyrightconfig.json.tmpl → pyrightconfig.json} +0 -0
  543. /package/dot_config/tflint/{tflint.hcl.tmpl → tflint.hcl} +0 -0
  544. /package/dot_config/yarn/{yarnrc.yml.tmpl → yarnrc.yml} +0 -0
  545. /package/dot_config/zsh/rc.d/{40-bell.zsh.tmpl → 40-bell.zsh} +0 -0
  546. /package/dot_config/zsh/rc.d/{50-login-fortune.zsh.tmpl → 50-login-fortune.zsh} +0 -0
@@ -1,16 +1,24 @@
1
1
  #!/usr/bin/env bash
2
+ # Copyright (c) 2015-2026 Dotfiles. All rights reserved.
2
3
  set -euo pipefail
3
4
 
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ # shellcheck source=../dot/lib/ui.sh
7
+ # shellcheck disable=SC1091
8
+ source "$SCRIPT_DIR/../dot/lib/ui.sh"
9
+
4
10
  histfile="${HISTFILE:-$HOME/.zsh_history}"
5
11
  db="${DOTFILES_HISTORY_DB:-$HOME/.local/share/dotfiles/history.sqlite}"
6
12
 
13
+ ui_init
14
+
7
15
  if [[ ! -f "$histfile" ]]; then
8
- echo "History file not found: $histfile" >&2
16
+ ui_err "History file" "not found: $histfile" >&2
9
17
  exit 1
10
18
  fi
11
19
 
12
20
  if ! command -v python3 >/dev/null; then
13
- echo "python3 not found. Falling back to hstats if available." >&2
21
+ ui_warn "python3" "not found; falling back to hstats if available" >&2
14
22
  if command -v hstats >/dev/null; then
15
23
  hstats
16
24
  exit 0
@@ -20,6 +28,8 @@ fi
20
28
 
21
29
  mkdir -p "$(dirname "$db")"
22
30
 
31
+ ui_header "History Analysis"
32
+
23
33
  python3 - "$histfile" "$db" <<'PY'
24
34
  import sys
25
35
  import sqlite3
@@ -50,8 +60,6 @@ with histfile.open("r", encoding="utf-8", errors="ignore") as f:
50
60
 
51
61
  conn.commit()
52
62
 
53
- print("=== History Analysis ===")
54
-
55
63
  print("\nTop commands:")
56
64
  for row in cur.execute("""
57
65
  SELECT substr(cmd, 1, instr(cmd || ' ', ' ') - 1) AS base, COUNT(*)
@@ -0,0 +1,575 @@
1
+ #!/usr/bin/env bash
2
+ # Copyright (c) 2015-2026 Dotfiles. All rights reserved.
3
+ ## MCP configuration diagnostics and hardening checks.
4
+ ##
5
+ ## Validates MCP (Model Context Protocol) server configurations for security
6
+ ## policy compliance: launcher allowlist, filesystem scope, token requirements.
7
+ ##
8
+ ## # Usage
9
+ ## dot mcp [--strict|-s] [--json|-j]
10
+ ##
11
+ ## # Options
12
+ ## --strict, -s: Treat policy warnings as errors (for CI enforcement)
13
+ ## --json, -j: Emit a machine-readable summary
14
+ ##
15
+ ## # Dependencies
16
+ ## - jq: JSON parsing (optional but recommended)
17
+ ##
18
+ ## # Checks Performed
19
+ ## | Check | Description |
20
+ ## |-------|-------------|
21
+ ## | Launcher policy | Only npx/node/uvx allowed |
22
+ ## | Filesystem scope | No broad access (/, /home, /Users) |
23
+ ## | Arg policy | No wildcards or --unsafe flags |
24
+ ## | Token check | Required tokens set (GITHUB_TOKEN, BRAVE_API_KEY) |
25
+ ## | Env placeholders | All ${VAR} references resolved |
26
+ ##
27
+ ## # Exit Codes
28
+ ## - 0: All checks passed
29
+ ## - 1: Errors found (or warnings in strict mode)
30
+
31
+ set -euo pipefail
32
+
33
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
34
+ # shellcheck source=../dot/lib/ui.sh
35
+ # shellcheck disable=SC1091
36
+ source "$SCRIPT_DIR/../dot/lib/ui.sh"
37
+
38
+ # Parse arguments
39
+ STRICT_MODE=0
40
+ JSON_MODE=0
41
+ while [[ $# -gt 0 ]]; do
42
+ case "$1" in
43
+ --strict | -s)
44
+ STRICT_MODE=1
45
+ shift
46
+ ;;
47
+ --json | -j)
48
+ JSON_MODE=1
49
+ shift
50
+ ;;
51
+ *) shift ;;
52
+ esac
53
+ done
54
+
55
+ Errors=0
56
+ Warnings=0
57
+ SUMMARY_STATUS="healthy"
58
+ CONFIG_OK=0
59
+ JSON_VALID=0
60
+ SERVER_COUNT=0
61
+ POLICY_WARN_ON_UNPINNED_NPX=0
62
+ REQUIRE_APPROVED_PACKAGE_LOCK=0
63
+ REQUIRE_REGISTRY_ENTRY=0
64
+ REQUIRE_HTTPS_FOR_HTTP=0
65
+ REQUIRE_OAUTH_FOR_HTTP=0
66
+ ALLOWED_LAUNCHERS='["npx","node","uvx"]'
67
+ TRUSTED_TRANSPORTS='["stdio"]'
68
+ BLOCKED_PATHS='["/","/home","/Users"]'
69
+ BLOCKED_ARG_PATTERNS='["^--allow-.*","^--unsafe$","^\\\\*$"]'
70
+ FORBIDDEN_DEFAULT_SERVERS='[]'
71
+ REQUIRED_ENV_RULES='{}'
72
+ APPROVED_PACKAGE_LOCK='{}'
73
+ APPROVED_REGISTRY='{}'
74
+
75
+ log_success() {
76
+ if [[ "$JSON_MODE" -ne 1 ]]; then
77
+ ui_ok "$1" "${2:-}"
78
+ fi
79
+ }
80
+ log_fail() {
81
+ if [[ "$JSON_MODE" -ne 1 ]]; then
82
+ ui_err "$1" "${2:-}"
83
+ fi
84
+ Errors=$((Errors + 1))
85
+ }
86
+ log_warn() {
87
+ if [[ "$JSON_MODE" -ne 1 ]]; then
88
+ ui_warn "$1" "${2:-}"
89
+ fi
90
+ Warnings=$((Warnings + 1))
91
+ # In strict mode, warnings become errors
92
+ [[ "$STRICT_MODE" -eq 1 ]] && Errors=$((Errors + 1))
93
+ }
94
+
95
+ MCP_CONFIG="${MCP_CONFIG:-$HOME/.config/claude/mcp_servers.json}"
96
+ if [[ ! -f "$MCP_CONFIG" && -f "$HOME/.dotfiles/dot_config/claude/mcp_servers.json" ]]; then
97
+ MCP_CONFIG="$HOME/.dotfiles/dot_config/claude/mcp_servers.json"
98
+ fi
99
+
100
+ REPO_ROOT="${REPO_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
101
+ MCP_POLICY_CONFIG="${MCP_POLICY_CONFIG:-$REPO_ROOT/dot_config/dotfiles/mcp-policy.json}"
102
+ MCP_LOCK_CONFIG="${MCP_LOCK_CONFIG:-$REPO_ROOT/dot_config/dotfiles/mcp-lock.json}"
103
+ MCP_REGISTRY_CONFIG="${MCP_REGISTRY_CONFIG:-$REPO_ROOT/dot_config/dotfiles/mcp-registry.json}"
104
+
105
+ if [[ "$JSON_MODE" -ne 1 ]]; then
106
+ ui_init
107
+ ui_dot_banner "AI and Agents"
108
+ ui_header "MCP Doctor"
109
+ echo ""
110
+ fi
111
+
112
+ if command -v jq >/dev/null 2>&1 && [[ -f "$MCP_POLICY_CONFIG" ]] && jq empty "$MCP_POLICY_CONFIG" >/dev/null 2>&1; then
113
+ ALLOWED_LAUNCHERS="$(jq -c '.profiles[.defaultProfile].allowedLaunchers // ["npx","node","uvx"]' "$MCP_POLICY_CONFIG")"
114
+ BLOCKED_PATHS="$(jq -c '.profiles[.defaultProfile].blockedFilesystemRoots // ["/","/home","/Users"]' "$MCP_POLICY_CONFIG")"
115
+ BLOCKED_ARG_PATTERNS="$(jq -c '.profiles[.defaultProfile].blockedArgPatterns // ["^--allow-.*","^--unsafe$","^\\\\*$"]' "$MCP_POLICY_CONFIG")"
116
+ FORBIDDEN_DEFAULT_SERVERS="$(jq -c '.profiles[.defaultProfile].forbidNetworkServersByDefault // []' "$MCP_POLICY_CONFIG")"
117
+ REQUIRED_ENV_RULES="$(jq -c '.profiles[.defaultProfile].requiredEnvByServer // {}' "$MCP_POLICY_CONFIG")"
118
+ TRUSTED_TRANSPORTS="$(jq -c '.profiles[.defaultProfile].trustedTransports // ["stdio"]' "$MCP_POLICY_CONFIG")"
119
+ if [[ "$(jq -r '.profiles[.defaultProfile].warnOnUnpinnedNpx // false' "$MCP_POLICY_CONFIG")" == "true" ]]; then
120
+ POLICY_WARN_ON_UNPINNED_NPX=1
121
+ fi
122
+ if [[ "$(jq -r '.profiles[.defaultProfile].requireApprovedPackageLock // false' "$MCP_POLICY_CONFIG")" == "true" ]]; then
123
+ REQUIRE_APPROVED_PACKAGE_LOCK=1
124
+ fi
125
+ if [[ "$(jq -r '.profiles[.defaultProfile].requireRegistryEntry // false' "$MCP_POLICY_CONFIG")" == "true" ]]; then
126
+ REQUIRE_REGISTRY_ENTRY=1
127
+ fi
128
+ if [[ "$(jq -r '.profiles[.defaultProfile].requireHttpsForHttpTransports // false' "$MCP_POLICY_CONFIG")" == "true" ]]; then
129
+ REQUIRE_HTTPS_FOR_HTTP=1
130
+ fi
131
+ if [[ "$(jq -r '.profiles[.defaultProfile].requireOauthForHttpTransports // false' "$MCP_POLICY_CONFIG")" == "true" ]]; then
132
+ REQUIRE_OAUTH_FOR_HTTP=1
133
+ fi
134
+ fi
135
+
136
+ if command -v jq >/dev/null 2>&1 && [[ -f "$MCP_LOCK_CONFIG" ]] && jq empty "$MCP_LOCK_CONFIG" >/dev/null 2>&1; then
137
+ APPROVED_PACKAGE_LOCK="$(jq -c '.packages // {}' "$MCP_LOCK_CONFIG")"
138
+ fi
139
+
140
+ if command -v jq >/dev/null 2>&1 && [[ -f "$MCP_REGISTRY_CONFIG" ]] && jq empty "$MCP_REGISTRY_CONFIG" >/dev/null 2>&1; then
141
+ APPROVED_REGISTRY="$(jq -c '.servers // {}' "$MCP_REGISTRY_CONFIG")"
142
+ fi
143
+
144
+ [[ "$JSON_MODE" -ne 1 ]] && ui_header "Config File"
145
+ if [[ -f "$MCP_CONFIG" ]]; then
146
+ CONFIG_OK=1
147
+ log_success "MCP config" "$MCP_CONFIG"
148
+ else
149
+ log_fail "MCP config" "not found (expected $MCP_CONFIG)"
150
+ fi
151
+
152
+ if [[ "$JSON_MODE" -ne 1 ]]; then
153
+ echo ""
154
+ ui_header "Policy"
155
+ fi
156
+ if [[ -f "$MCP_POLICY_CONFIG" ]]; then
157
+ log_success "Policy config" "$MCP_POLICY_CONFIG"
158
+ else
159
+ log_warn "Policy config" "not found (using built-in defaults)"
160
+ fi
161
+
162
+ if [[ "$JSON_MODE" -ne 1 ]]; then
163
+ echo ""
164
+ ui_header "Supply Chain"
165
+ fi
166
+ if [[ -f "$MCP_LOCK_CONFIG" ]]; then
167
+ log_success "Package lock" "$MCP_LOCK_CONFIG"
168
+ else
169
+ if [[ "$REQUIRE_APPROVED_PACKAGE_LOCK" -eq 1 ]]; then
170
+ log_warn "Package lock" "not found (strict-local expects a tracked lock file)"
171
+ else
172
+ log_success "Package lock" "not required"
173
+ fi
174
+ fi
175
+ if [[ -f "$MCP_REGISTRY_CONFIG" ]]; then
176
+ log_success "Registry" "$MCP_REGISTRY_CONFIG"
177
+ else
178
+ if [[ "$REQUIRE_REGISTRY_ENTRY" -eq 1 ]]; then
179
+ log_warn "Registry" "not found (strict-local expects a tracked registry file)"
180
+ else
181
+ log_success "Registry" "not required"
182
+ fi
183
+ fi
184
+
185
+ MCP_SERVER_CARD="${MCP_SERVER_CARD:-$REPO_ROOT/.well-known/mcp/server-card.json}"
186
+ if [[ "$JSON_MODE" -ne 1 ]]; then
187
+ echo ""
188
+ ui_header "Server Card (SEP-1649)"
189
+ fi
190
+ if [[ -f "$MCP_SERVER_CARD" ]]; then
191
+ if command -v jq >/dev/null 2>&1 && jq empty "$MCP_SERVER_CARD" >/dev/null 2>&1; then
192
+ log_success "Server card" "$MCP_SERVER_CARD"
193
+ has_card_version="$(jq -r '.cardVersion // empty' "$MCP_SERVER_CARD")"
194
+ has_card_name="$(jq -r '.name // empty' "$MCP_SERVER_CARD")"
195
+ has_card_capabilities="$(jq -e '.capabilities' "$MCP_SERVER_CARD" >/dev/null 2>&1 && echo "yes" || echo "")"
196
+ has_card_transport="$(jq -e '.transport' "$MCP_SERVER_CARD" >/dev/null 2>&1 && echo "yes" || echo "")"
197
+ if [[ -n "$has_card_version" ]]; then
198
+ log_success "Card version" "$has_card_version"
199
+ else
200
+ log_warn "Card version" "missing cardVersion field"
201
+ fi
202
+ if [[ -n "$has_card_name" ]]; then
203
+ log_success "Card name" "$has_card_name"
204
+ else
205
+ log_warn "Card name" "missing name field"
206
+ fi
207
+ if [[ -n "$has_card_capabilities" ]]; then
208
+ log_success "Card capabilities" "present"
209
+ else
210
+ log_warn "Card capabilities" "missing capabilities block"
211
+ fi
212
+ if [[ -n "$has_card_transport" ]]; then
213
+ log_success "Card transport" "present"
214
+ else
215
+ log_warn "Card transport" "missing transport block"
216
+ fi
217
+ else
218
+ log_fail "Server card" "invalid JSON"
219
+ fi
220
+ else
221
+ log_warn "Server card" "not found (expected $MCP_SERVER_CARD)"
222
+ fi
223
+
224
+ if [[ "$JSON_MODE" -ne 1 ]]; then
225
+ echo ""
226
+ ui_header "Validation"
227
+ fi
228
+ if command -v jq >/dev/null 2>&1; then
229
+ if [[ -f "$MCP_CONFIG" ]] && jq empty "$MCP_CONFIG" >/dev/null 2>&1; then
230
+ log_success "JSON syntax" "valid"
231
+ JSON_VALID=1
232
+ else
233
+ log_fail "JSON syntax" "invalid"
234
+ fi
235
+
236
+ if [[ "$JSON_VALID" -eq 1 ]]; then
237
+ SERVER_COUNT="$(jq '.mcpServers | keys | length' "$MCP_CONFIG" 2>/dev/null || echo 0)"
238
+ if [[ "$SERVER_COUNT" -gt 0 ]]; then
239
+ log_success "MCP servers" "$SERVER_COUNT configured"
240
+ else
241
+ log_fail "MCP servers" "none configured"
242
+ fi
243
+
244
+ if jq -e --argjson blocked "$BLOCKED_PATHS" '.mcpServers.filesystem.args[]? as $arg | $blocked[] | select(. == $arg)' "$MCP_CONFIG" >/dev/null 2>&1; then
245
+ log_warn "Filesystem scope" "too broad (use a project-scoped directory)"
246
+ else
247
+ log_success "Filesystem scope" "not globally broad"
248
+ fi
249
+
250
+ # MCP operational policy: allow known launchers only.
251
+ unknown_launchers="$(jq -r --argjson allowed "$ALLOWED_LAUNCHERS" '.mcpServers | to_entries[]? | select((.value.command as $cmd | [$allowed[] | select(. == $cmd)] | length) == 0) | "\(.key):\(.value.command)"' "$MCP_CONFIG" 2>/dev/null || true)"
252
+ if [[ -n "$unknown_launchers" ]]; then
253
+ while IFS= read -r item; do
254
+ [[ -z "$item" ]] && continue
255
+ log_warn "Launcher policy" "review non-standard command $item"
256
+ done <<<"$unknown_launchers"
257
+ else
258
+ log_success "Launcher policy" "all server launchers are allowlisted (npx/node/uvx)"
259
+ fi
260
+
261
+ # MCP policy: flag wildcard/potentially risky args for review.
262
+ risky_args="$(jq -r --argjson blocked "$BLOCKED_ARG_PATTERNS" '
263
+ .mcpServers
264
+ | to_entries[]?
265
+ | .key as $name
266
+ | (.value.args // [])[]?
267
+ | . as $arg
268
+ | select(any($blocked[]; . as $pattern | ($arg | test($pattern))))
269
+ | "\($name):\($arg)"
270
+ ' "$MCP_CONFIG" 2>/dev/null || true)"
271
+ if [[ -n "$risky_args" ]]; then
272
+ while IFS= read -r item; do
273
+ [[ -z "$item" ]] && continue
274
+ log_warn "Arg policy" "review risky argument $item"
275
+ done <<<"$risky_args"
276
+ else
277
+ log_success "Arg policy" "no high-risk wildcard/unsafe args found"
278
+ fi
279
+
280
+ forbidden_default_servers="$(jq -r --argjson forbidden "$FORBIDDEN_DEFAULT_SERVERS" '
281
+ .mcpServers
282
+ | keys[]
283
+ | . as $server
284
+ | select(any($forbidden[]; . == $server))
285
+ ' "$MCP_CONFIG" 2>/dev/null || true)"
286
+ if [[ -n "$forbidden_default_servers" ]]; then
287
+ while IFS= read -r item; do
288
+ [[ -z "$item" ]] && continue
289
+ log_warn "Default server policy" "$item enabled in strict-local profile"
290
+ done <<<"$forbidden_default_servers"
291
+ else
292
+ log_success "Default server policy" "local-only default set"
293
+ fi
294
+
295
+ invalid_transports="$(jq -r --argjson trusted "$TRUSTED_TRANSPORTS" '
296
+ .mcpServers
297
+ | to_entries[]?
298
+ | .key as $name
299
+ | (.value.transport // "stdio") as $transport
300
+ | select(([$trusted[] | select(. == $transport)] | length) == 0)
301
+ | "\($name):\($transport)"
302
+ ' "$MCP_CONFIG" 2>/dev/null || true)"
303
+ if [[ -n "$invalid_transports" ]]; then
304
+ while IFS= read -r item; do
305
+ [[ -z "$item" ]] && continue
306
+ log_warn "Transport policy" "review untrusted transport $item"
307
+ done <<<"$invalid_transports"
308
+ else
309
+ log_success "Transport policy" "all servers use trusted transports"
310
+ fi
311
+
312
+ if [[ "$REQUIRE_HTTPS_FOR_HTTP" -eq 1 ]]; then
313
+ insecure_http_servers="$(jq -r '
314
+ .mcpServers
315
+ | to_entries[]?
316
+ | select((.value.transport // "") == "http")
317
+ | select((.value.url // "") | startswith("https://") | not)
318
+ | .key
319
+ ' "$MCP_CONFIG" 2>/dev/null || true)"
320
+ if [[ -n "$insecure_http_servers" ]]; then
321
+ while IFS= read -r item; do
322
+ [[ -z "$item" ]] && continue
323
+ log_warn "Transport security" "$item uses non-HTTPS HTTP transport"
324
+ done <<<"$insecure_http_servers"
325
+ else
326
+ log_success "Transport security" "HTTP transports are HTTPS"
327
+ fi
328
+ fi
329
+
330
+ # Streamable-HTTP HTTPS validation
331
+ insecure_streamable_servers="$(jq -r '
332
+ .mcpServers
333
+ | to_entries[]?
334
+ | select((.value.transport // "") == "streamable-http")
335
+ | select((.value.url // "") | startswith("https://") | not)
336
+ | .key
337
+ ' "$MCP_CONFIG" 2>/dev/null || true)"
338
+ if [[ -n "$insecure_streamable_servers" ]]; then
339
+ while IFS= read -r item; do
340
+ [[ -z "$item" ]] && continue
341
+ log_warn "Transport security" "$item streamable-http transport must use HTTPS"
342
+ done <<<"$insecure_streamable_servers"
343
+ fi
344
+
345
+ # Auth Profiles validation
346
+ if command -v jq >/dev/null 2>&1 && [[ -f "$MCP_POLICY_CONFIG" ]]; then
347
+ declared_auth="$(jq -c '.profiles[.defaultProfile].authProfiles // []' "$MCP_POLICY_CONFIG" 2>/dev/null)"
348
+ if [[ "$declared_auth" != "[]" ]]; then
349
+ log_success "Auth profiles" "declared: $declared_auth"
350
+ # Check transport/auth compatibility: streamable-http/http servers need more than "none"
351
+ incompatible_auth="$(jq -r --argjson registry "$APPROVED_REGISTRY" --argjson allowed_auth "$declared_auth" '
352
+ .mcpServers
353
+ | to_entries[]?
354
+ | .key as $name
355
+ | (.value.transport // "stdio") as $t
356
+ | select($t == "http" or $t == "streamable-http")
357
+ | select($registry[$name].authProfile // "none" | IN($allowed_auth[]) | not)
358
+ | "\($name):\($registry[$name].authProfile // "none")"
359
+ ' "$MCP_CONFIG" 2>/dev/null || true)"
360
+ if [[ -n "$incompatible_auth" ]]; then
361
+ while IFS= read -r item; do
362
+ [[ -z "$item" ]] && continue
363
+ log_warn "Auth compatibility" "$item uses auth profile not in policy"
364
+ done <<<"$incompatible_auth"
365
+ else
366
+ log_success "Auth compatibility" "all server auth profiles match policy"
367
+ fi
368
+ fi
369
+ fi
370
+
371
+ if [[ "$REQUIRE_OAUTH_FOR_HTTP" -eq 1 ]]; then
372
+ non_oauth_http_servers="$(jq -r --argjson registry "$APPROVED_REGISTRY" '
373
+ .mcpServers
374
+ | to_entries[]?
375
+ | .key as $name
376
+ | select((.value.transport // "") == "http")
377
+ | select(($registry[$name].auth // "") != "oauth2")
378
+ | $name
379
+ ' "$MCP_CONFIG" 2>/dev/null || true)"
380
+ if [[ -n "$non_oauth_http_servers" ]]; then
381
+ while IFS= read -r item; do
382
+ [[ -z "$item" ]] && continue
383
+ log_warn "Auth policy" "$item HTTP transport is not registered for OAuth2"
384
+ done <<<"$non_oauth_http_servers"
385
+ else
386
+ log_success "Auth policy" "HTTP transports are registry-approved for OAuth2"
387
+ fi
388
+ fi
389
+
390
+ env_vars="$(
391
+ {
392
+ jq -r '.mcpServers | to_entries[]? | (.value.env // {}) | to_entries[]?.value' "$MCP_CONFIG"
393
+ jq -r '.mcpServers | to_entries[]? | (.value.args // [])[]?' "$MCP_CONFIG"
394
+ } | sed -n 's/^\${\([A-Z0-9_]\+\)}$/\1/p' | sort -u
395
+ )"
396
+ if [[ -z "$env_vars" ]]; then
397
+ log_success "Server env placeholders" "none declared"
398
+ else
399
+ missing=0
400
+ while IFS= read -r key; do
401
+ [[ -z "$key" ]] && continue
402
+ if [[ -z "${!key:-}" ]]; then
403
+ log_warn "Env variable" "$key is not set"
404
+ missing=$((missing + 1))
405
+ fi
406
+ done <<<"$env_vars"
407
+ if [[ "$missing" -eq 0 ]]; then
408
+ log_success "Env variables" "all referenced placeholders are set"
409
+ fi
410
+ fi
411
+
412
+ while IFS=$'\t' read -r server env_key; do
413
+ [[ -z "${server:-}" ]] && continue
414
+ if ! jq -e --arg server "$server" '.mcpServers[$server]' "$MCP_CONFIG" >/dev/null 2>&1; then
415
+ continue
416
+ fi
417
+ if [[ -n "${!env_key:-}" ]]; then
418
+ log_success "Token check" "$env_key is set for $server MCP server"
419
+ else
420
+ log_warn "Token check" "$env_key missing for $server MCP server"
421
+ fi
422
+ done < <(jq -r '
423
+ to_entries[]
424
+ | .key as $server
425
+ | (.value // [])[]
426
+ | [$server, .]
427
+ | @tsv
428
+ ' <<<"$REQUIRED_ENV_RULES" 2>/dev/null || true)
429
+
430
+ if [[ "$POLICY_WARN_ON_UNPINNED_NPX" -eq 1 ]]; then
431
+ unpinned_npx_servers="$(jq -r '
432
+ .mcpServers
433
+ | to_entries[]?
434
+ | select(.value.command == "npx")
435
+ | select((.value.args // []) | any(
436
+ test("^[A-Za-z0-9@._/-]+$")
437
+ and (startswith("-") | not)
438
+ and (test("^(@[^/]+/[^@]+|[^@]+)@[^@]+$") | not)
439
+ ))
440
+ | .key
441
+ ' "$MCP_CONFIG" 2>/dev/null || true)"
442
+ if [[ -n "$unpinned_npx_servers" ]]; then
443
+ while IFS= read -r item; do
444
+ [[ -z "$item" ]] && continue
445
+ log_warn "Package pinning" "$item uses unpinned npx package"
446
+ done <<<"$unpinned_npx_servers"
447
+ else
448
+ log_success "Package pinning" "no unpinned npx packages found"
449
+ fi
450
+ fi
451
+
452
+ if [[ "$REQUIRE_APPROVED_PACKAGE_LOCK" -eq 1 ]]; then
453
+ approved_package_mismatches="$(jq -r --argjson approved "$APPROVED_PACKAGE_LOCK" '
454
+ .mcpServers
455
+ | to_entries[]?
456
+ | .key as $server
457
+ | .value.command as $command
458
+ | ((.value.args // []) | map(select(test("^[A-Za-z0-9@._/-]+@[A-Za-z0-9._-]+$"))) | .[0] // "") as $pkg
459
+ | select($command == "npx")
460
+ | select(($approved[$server].package // "") != $pkg)
461
+ | "\($server)\t\($pkg)\t\($approved[$server].package // "untracked")"
462
+ ' "$MCP_CONFIG" 2>/dev/null || true)"
463
+ if [[ -n "$approved_package_mismatches" ]]; then
464
+ while IFS=$'\t' read -r server actual expected; do
465
+ [[ -z "${server:-}" ]] && continue
466
+ log_warn "Package lock" "$server uses $actual (approved: $expected)"
467
+ done <<<"$approved_package_mismatches"
468
+ else
469
+ log_success "Package lock" "all active servers match approved package refs"
470
+ fi
471
+ fi
472
+
473
+ if [[ "$REQUIRE_REGISTRY_ENTRY" -eq 1 ]]; then
474
+ registry_mismatches="$(jq -r --argjson registry "$APPROVED_REGISTRY" '
475
+ .mcpServers
476
+ | to_entries[]?
477
+ | .key as $server
478
+ | (.value.command // "") as $command
479
+ | (.value.transport // "stdio") as $transport
480
+ | ((.value.args // []) | map(select(test("^[A-Za-z0-9@._/-]+@[A-Za-z0-9._-]+$"))) | .[0] // "") as $pkg
481
+ | (.value.url // "") as $url
482
+ | select(($registry[$server] | type) != "object"
483
+ or ($registry[$server].transport // "stdio") != $transport
484
+ or ($registry[$server].launcher // "") != $command
485
+ or (($command == "npx") and (($registry[$server].package // "") != $pkg))
486
+ or (($transport == "http") and (($registry[$server].url // "") != $url)))
487
+ | "\($server)\t\($transport)\t\($command)\t\($pkg)\t\($url)"
488
+ ' "$MCP_CONFIG" 2>/dev/null || true)"
489
+ if [[ -n "$registry_mismatches" ]]; then
490
+ while IFS=$'\t' read -r server _transport _command _pkg _url; do
491
+ [[ -z "${server:-}" ]] && continue
492
+ log_warn "Registry policy" "$server is missing or diverges from the tracked MCP registry"
493
+ done <<<"$registry_mismatches"
494
+ else
495
+ log_success "Registry policy" "all active servers match the tracked MCP registry"
496
+ fi
497
+ fi
498
+ fi
499
+ else
500
+ log_warn "jq" "not installed, running limited checks"
501
+ if grep -q '"mcpServers"' "$MCP_CONFIG" 2>/dev/null; then
502
+ log_success "mcpServers key" "present"
503
+ else
504
+ log_fail "mcpServers key" "missing"
505
+ fi
506
+ fi
507
+
508
+ if [[ "$Errors" -eq 0 ]]; then
509
+ if [[ "$Warnings" -eq 0 ]]; then
510
+ SUMMARY_STATUS="healthy"
511
+ else
512
+ if [[ "$STRICT_MODE" -eq 1 ]]; then
513
+ SUMMARY_STATUS="failed"
514
+ else
515
+ SUMMARY_STATUS="warning"
516
+ fi
517
+ fi
518
+ else
519
+ SUMMARY_STATUS="failed"
520
+ fi
521
+
522
+ if [[ "$JSON_MODE" -eq 1 ]]; then
523
+ jq -n \
524
+ --arg status "$SUMMARY_STATUS" \
525
+ --arg config "$MCP_CONFIG" \
526
+ --arg policy "$MCP_POLICY_CONFIG" \
527
+ --argjson strict "$STRICT_MODE" \
528
+ --argjson server_count "$SERVER_COUNT" \
529
+ --argjson errors "$Errors" \
530
+ --argjson warnings "$Warnings" \
531
+ --argjson config_ok "$CONFIG_OK" \
532
+ --argjson json_valid "$JSON_VALID" \
533
+ '{
534
+ status: $status,
535
+ strict: ($strict == 1),
536
+ config_path: $config,
537
+ policy_path: $policy,
538
+ server_count: $server_count,
539
+ checks: {
540
+ config_present: ($config_ok == 1),
541
+ json_valid: ($json_valid == 1)
542
+ },
543
+ summary: {
544
+ errors: $errors,
545
+ warnings: $warnings
546
+ }
547
+ }'
548
+ else
549
+ echo ""
550
+ ui_header "Summary"
551
+ fi
552
+
553
+ if [[ "$Errors" -eq 0 ]]; then
554
+ if [[ "$Warnings" -eq 0 ]]; then
555
+ if [[ "$JSON_MODE" -ne 1 ]]; then
556
+ ui_ok "MCP configuration healthy"
557
+ fi
558
+ else
559
+ if [[ "$STRICT_MODE" -eq 1 ]]; then
560
+ if [[ "$JSON_MODE" -ne 1 ]]; then
561
+ ui_err "MCP issues found" "$Warnings policy warnings (strict mode)"
562
+ fi
563
+ exit 1
564
+ else
565
+ if [[ "$JSON_MODE" -ne 1 ]]; then
566
+ ui_warn "MCP configuration healthy" "$Warnings warnings"
567
+ fi
568
+ fi
569
+ fi
570
+ else
571
+ if [[ "$JSON_MODE" -ne 1 ]]; then
572
+ ui_err "MCP issues found" "$Errors errors, $Warnings warnings"
573
+ fi
574
+ exit 1
575
+ fi