@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,7 +1,40 @@
1
- #!/bin/sh
2
- # Theme Switcher - Supports Tokyo Night and Catppuccin theme families
3
- # Usage: dot theme [list|set <name>|toggle|family]
4
- set -e
1
+ #!/usr/bin/env bash
2
+ # Copyright (c) 2015-2026 Dotfiles. All rights reserved.
3
+ ## Theme Switcher — Switch between theme families and light/dark modes.
4
+ ##
5
+ ## Supports Tokyo Night, Catppuccin, Rose Pine, Kanagawa, and other
6
+ ## popular theme families. Updates chezmoi data and applies changes.
7
+ ##
8
+ ## # Requirements
9
+ ## - chezmoi: Dotfiles manager
10
+ ## - sed: For updating theme configuration
11
+ ##
12
+ ## # Usage
13
+ ## dot theme list # Show all available themes
14
+ ## dot theme set NAME # Set theme to NAME
15
+ ## dot theme toggle # Toggle light/dark within family
16
+ ## dot theme family # Switch between theme families
17
+ ## dot theme current # Show current theme info
18
+ ##
19
+ ## # Platform Notes
20
+ ## - All platforms: Updates chezmoi configuration
21
+
22
+ set -euo pipefail
23
+
24
+ # Cleanup function for temp files
25
+ cleanup() {
26
+ if [[ -n "${tmp_file:-}" ]] && [[ -f "$tmp_file" ]]; then
27
+ rm -f "$tmp_file"
28
+ fi
29
+ }
30
+ trap cleanup EXIT
31
+
32
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
33
+ # shellcheck source=../dot/lib/ui.sh
34
+ # shellcheck disable=SC1091
35
+ source "$SCRIPT_DIR/../dot/lib/ui.sh"
36
+
37
+ ui_init
5
38
 
6
39
  resolve_source_dir() {
7
40
  if [ -n "${CHEZMOI_SOURCE_DIR:-}" ] && [ -d "$CHEZMOI_SOURCE_DIR" ]; then
@@ -21,13 +54,15 @@ resolve_source_dir() {
21
54
 
22
55
  SRC_DIR="$(resolve_source_dir)"
23
56
  if [ -z "$SRC_DIR" ]; then
24
- echo "Dotfiles source not found."
57
+ ui_err "Dotfiles source" "not found"
25
58
  exit 1
26
59
  fi
27
60
 
28
61
  DATA_FILE="$SRC_DIR/.chezmoidata.toml"
62
+ THEMES_FILE="$SRC_DIR/.chezmoidata/themes.toml"
63
+ WALLPAPER_DIR="${DOTFILES_WALLPAPER_DIR:-$HOME/Pictures/Wallpapers}"
29
64
  if [ ! -f "$DATA_FILE" ]; then
30
- echo "Missing $DATA_FILE"
65
+ ui_err "Missing" "$DATA_FILE"
31
66
  exit 1
32
67
  fi
33
68
 
@@ -36,12 +71,8 @@ fi
36
71
  # =============================================================================
37
72
 
38
73
  # Default preferences
39
- DEFAULT_DARK="catppuccin-mocha"
40
- DEFAULT_LIGHT="catppuccin-latte"
41
- TOKYO_DARK="tokyonight-night"
42
- TOKYO_LIGHT="tokyonight-day"
43
- CATPPUCCIN_DARK="catppuccin-mocha"
44
- CATPPUCCIN_LIGHT="catppuccin-latte"
74
+ DEFAULT_DARK="macos-monterey-dark"
75
+ DEFAULT_LIGHT="macos-monterey-light"
45
76
 
46
77
  # =============================================================================
47
78
  # Theme Functions
@@ -51,24 +82,82 @@ current_theme() {
51
82
  awk -F'"' '/^theme =/ {print $2}' "$DATA_FILE" | head -n 1
52
83
  }
53
84
 
85
+ theme_mode() {
86
+ local name="${1:-}"
87
+ awk -v n="$name" '
88
+ $0 == "[themes." n "]" { found=1; next }
89
+ /^\[/ { found=0 }
90
+ found && /^mode/ { sub(/.*= *"/, ""); sub(/".*/, ""); print; exit }
91
+ ' "$THEMES_FILE"
92
+ }
93
+
94
+ theme_exists() {
95
+ local name="${1:-}"
96
+ grep -q "^\[themes\.${name}\]$" "$THEMES_FILE" 2>/dev/null
97
+ }
98
+
99
+ all_theme_names() {
100
+ sed -n 's/^\[themes\.\([a-z0-9-]*\)\]$/\1/p' "$THEMES_FILE" | sort -u
101
+ }
102
+
103
+ # List wallpaper families that have BOTH dark and light variants in themes.toml.
104
+ # Only these are presented to users — unpaired wallpapers are hidden.
105
+ paired_families() {
106
+ local -A has_dark has_light
107
+ local name family
108
+ while IFS= read -r name; do
109
+ if [[ "$name" == *-dark ]]; then
110
+ family="${name%-dark}"
111
+ has_dark["$family"]=1
112
+ elif [[ "$name" == *-light ]]; then
113
+ family="${name%-light}"
114
+ has_light["$family"]=1
115
+ fi
116
+ done < <(all_theme_names)
117
+
118
+ for family in $(printf '%s\n' "${!has_dark[@]}" | sort); do
119
+ [[ -n "${has_light[$family]+x}" ]] && echo "$family"
120
+ done
121
+ }
122
+
123
+ # Determine source type (system/custom) for a wallpaper family.
124
+ wallpaper_source() {
125
+ local family="${1:-}"
126
+ # Check for custom wallpapers: dynamic (family.heic) or split (family-dark/light.ext)
127
+ for ext in heic jpg png; do
128
+ if [[ -f "$WALLPAPER_DIR/${family}.${ext}" || -f "$WALLPAPER_DIR/${family}-dark.${ext}" || -f "$WALLPAPER_DIR/${family}-light.${ext}" ]]; then
129
+ echo "Custom"
130
+ return
131
+ fi
132
+ done
133
+ echo "System"
134
+ }
135
+
54
136
  get_theme_family() {
55
- theme="$1"
56
- case "$theme" in
57
- tokyonight-*) echo "tokyonight" ;;
58
- catppuccin-*) echo "catppuccin" ;;
59
- rose-pine*) echo "rose-pine" ;;
60
- kanagawa-*) echo "kanagawa" ;;
61
- gruvbox-*) echo "gruvbox" ;;
62
- solarized-*) echo "solarized" ;;
63
- everforest-*) echo "everforest" ;;
64
- *) echo "other" ;;
65
- esac
137
+ local theme="${1:-}"
138
+ # Read family from themes.toml if available
139
+ if [[ -f "$THEMES_FILE" ]]; then
140
+ local family
141
+ family="$(awk -v n="$theme" '
142
+ $0 == "[themes." n "]" { found=1; next }
143
+ /^\[/ { found=0 }
144
+ found && /^family/ { sub(/.*= *"/, ""); sub(/".*/, ""); print; exit }
145
+ ' "$THEMES_FILE")"
146
+ if [[ -n "$family" ]]; then
147
+ echo "$family"
148
+ return
149
+ fi
150
+ fi
151
+ # Fallback: strip -dark/-light suffix
152
+ local family="${theme%-dark}"
153
+ [[ "$family" != "$theme" ]] || family="${theme%-light}"
154
+ echo "$family"
66
155
  }
67
156
 
68
157
  is_dark_theme() {
69
- theme="$1"
158
+ local theme="${1:-}"
70
159
  case "$theme" in
71
- *-night | *-storm | *-moon | *-mocha | *-frappe | *-macchiato | *-dark | *-wave | *-dragon | dracula | nord | onedark)
160
+ *-dark)
72
161
  return 0
73
162
  ;;
74
163
  *)
@@ -78,135 +167,198 @@ is_dark_theme() {
78
167
  }
79
168
 
80
169
  set_theme() {
81
- new_theme="$1"
170
+ local new_theme="$1"
82
171
  if [ -z "$new_theme" ]; then
83
- echo "Theme name required."
172
+ pick_theme
173
+ return
174
+ fi
175
+ dot-theme-sync "$new_theme"
176
+ }
177
+
178
+ # Interactive theme picker
179
+ pick_theme() {
180
+ if ! command -v fzf &>/dev/null; then
181
+ ui_err "fzf" "required for interactive picker"
182
+ ui_info "Usage" "dot theme set <name>"
84
183
  exit 1
85
184
  fi
86
- # Validate theme name: only allow alphanumeric, hyphens, underscores
87
- case "$new_theme" in
88
- *[!a-zA-Z0-9_-]*)
89
- echo "Invalid theme name: $new_theme" >&2
90
- echo "Theme names may only contain letters, digits, hyphens, and underscores." >&2
91
- exit 1
92
- ;;
93
- esac
94
185
 
95
- tmp_file="$(mktemp)"
96
- if grep -q '^theme = ' "$DATA_FILE"; then
97
- sed "s/^theme = .*/theme = \"$new_theme\"/" "$DATA_FILE" >"$tmp_file"
98
- else
99
- cat "$DATA_FILE" >"$tmp_file"
100
- echo "theme = \"$new_theme\"" >>"$tmp_file"
186
+ local current
187
+ local current="$(current_theme)"
188
+
189
+ if [[ ! -f "$THEMES_FILE" ]]; then
190
+ ui_err "Missing" "$THEMES_FILE"
191
+ exit 1
192
+ fi
193
+
194
+ local current_family="${current%-dark}"
195
+ [[ "$current_family" != "$current" ]] || current_family="${current%-light}"
196
+ local current_mode="dark"
197
+ is_dark_theme "$current" 2>/dev/null || current_mode="light"
198
+
199
+ # Build theme list: one row per family, shows active mode
200
+ local theme_list=""
201
+ local family source marker active_mode
202
+ while IFS= read -r family; do
203
+ [[ -n "$family" ]] || continue
204
+ source="$(wallpaper_source "$family")"
205
+ marker="○"
206
+ active_mode=""
207
+ if [[ "$family" == "$current_family" ]]; then
208
+ marker="✓"
209
+ active_mode="$current_mode"
210
+ fi
211
+ theme_list+="$(printf '%s %-35s %-8s %s' "$marker" "$family" "$source" "$active_mode")"$'\n'
212
+ done < <(paired_families)
213
+
214
+ local selected_family
215
+ selected_family="$(echo "$theme_list" | fzf \
216
+ --header "Select wallpaper theme (current: $current_family [$current_mode])" \
217
+ --prompt "Theme > " \
218
+ --height 30 \
219
+ --reverse \
220
+ --no-sort \
221
+ --no-preview \
222
+ --ansi |
223
+ awk '$1 !~ /^#/ && NF >= 2 {print $2}')" || return 0
224
+
225
+ if [[ -n "$selected_family" ]]; then
226
+ # Apply with current appearance mode (dark/light)
227
+ local new_theme="${selected_family}-${current_mode}"
228
+ if [[ "$new_theme" != "$current" ]]; then
229
+ dot-theme-sync "$new_theme"
230
+ else
231
+ ui_info "Theme" "already on $current"
232
+ fi
101
233
  fi
102
- mv "$tmp_file" "$DATA_FILE"
103
- echo "Theme set to: $new_theme"
104
- echo "Applying dotfiles..."
105
- chezmoi apply --force 2>/dev/null || chezmoi apply
106
234
  }
107
235
 
108
236
  list_themes() {
109
- echo "=== Catppuccin (Recommended) ==="
110
- echo " catppuccin-latte (light)"
111
- echo " catppuccin-frappe (dark - muted)"
112
- echo " catppuccin-macchiato (dark - balanced)"
113
- echo " catppuccin-mocha (dark - rich)"
114
- echo ""
115
- echo "=== Tokyo Night ==="
116
- echo " tokyonight-day (light)"
117
- echo " tokyonight-storm (dark - muted)"
118
- echo " tokyonight-night (dark - default)"
119
- echo " tokyonight-moon (dark - softer)"
120
- echo ""
121
- echo "=== Rose Pine ==="
122
- echo " rose-pine (dark)"
123
- echo " rose-pine-moon (dark - softer)"
124
- echo " rose-pine-dawn (light)"
125
- echo ""
126
- echo "=== Kanagawa ==="
127
- echo " kanagawa-wave (dark - default)"
128
- echo " kanagawa-dragon (dark - vibrant)"
129
- echo " kanagawa-lotus (light)"
130
- echo ""
131
- echo "=== Other ==="
132
- echo " dracula (dark)"
133
- echo " gruvbox-light (light)"
134
- echo " gruvbox-dark (dark)"
135
- echo " nord (dark)"
136
- echo " onelight (light)"
137
- echo " onedark (dark)"
138
- echo " solarized-light (light)"
139
- echo " solarized-dark (dark)"
140
- echo " everforest-light (light)"
141
- echo " everforest-dark (dark)"
237
+ local current="$(current_theme)"
238
+ local current_family="${current%-dark}"
239
+ [[ "$current_family" != "$current" ]] || current_family="${current%-light}"
240
+
241
+ local count=0
242
+ local family source
243
+
244
+ printf ' %-35s %s\n' "WALLPAPER" "SOURCE"
245
+ printf ' %-35s %s\n' "---------" "------"
246
+ while IFS= read -r family; do
247
+ [[ -n "$family" ]] || continue
248
+ source="$(wallpaper_source "$family")"
249
+ if [[ "$family" == "$current_family" ]]; then
250
+ ui_ok "$family" "$source ◀"
251
+ else
252
+ printf ' %-35s %s\n' "$family" "$source"
253
+ fi
254
+ count=$((count + 1))
255
+ done < <(paired_families)
256
+
142
257
  echo ""
143
- echo "Current theme: $(current_theme)"
258
+ ui_info "Current" "$(current_theme) ($count wallpaper themes available)"
144
259
  }
145
260
 
146
261
  # Toggle between light and dark within the same family, or switch families
147
262
  toggle_theme() {
148
- current="$(current_theme)"
149
- family="$(get_theme_family "$current")"
263
+ local current="$(current_theme)"
150
264
 
151
265
  if is_dark_theme "$current"; then
152
- # Currently dark, switch to light variant
153
- case "$family" in
154
- tokyonight) set_theme "$TOKYO_LIGHT" ;;
155
- catppuccin) set_theme "$CATPPUCCIN_LIGHT" ;;
156
- rose-pine) set_theme "rose-pine-dawn" ;;
157
- kanagawa) set_theme "kanagawa-lotus" ;;
158
- gruvbox) set_theme "gruvbox-light" ;;
159
- solarized) set_theme "solarized-light" ;;
160
- everforest) set_theme "everforest-light" ;;
161
- *) set_theme "$DEFAULT_LIGHT" ;;
162
- esac
266
+ if [[ "$current" == *-dark ]]; then
267
+ set_theme "${current%-dark}-light"
268
+ else
269
+ set_theme "$DEFAULT_LIGHT"
270
+ fi
163
271
  else
164
- # Currently light, switch to dark variant
165
- case "$family" in
166
- tokyonight) set_theme "$TOKYO_DARK" ;;
167
- catppuccin) set_theme "$CATPPUCCIN_DARK" ;;
168
- rose-pine) set_theme "rose-pine" ;;
169
- kanagawa) set_theme "kanagawa-wave" ;;
170
- gruvbox) set_theme "gruvbox-dark" ;;
171
- solarized) set_theme "solarized-dark" ;;
172
- everforest) set_theme "everforest-dark" ;;
173
- *) set_theme "$DEFAULT_DARK" ;;
174
- esac
272
+ if [[ "$current" == *-light ]]; then
273
+ set_theme "${current%-light}-dark"
274
+ else
275
+ set_theme "$DEFAULT_DARK"
276
+ fi
175
277
  fi
176
278
  }
177
279
 
178
- # Switch between Tokyo Night and Catppuccin families
280
+ # Switch to the next wallpaper family while preserving mode.
179
281
  switch_family() {
180
- current="$(current_theme)"
181
- family="$(get_theme_family "$current")"
282
+ local current="$(current_theme)"
283
+ local family="$(get_theme_family "$current")"
284
+ local mode="dark"
285
+ local families=()
286
+ local idx=0
287
+ local next_family=""
182
288
 
183
- if is_dark_theme "$current"; then
184
- # Stay in dark mode, switch family
185
- case "$family" in
186
- tokyonight) set_theme "$CATPPUCCIN_DARK" ;;
187
- catppuccin) set_theme "$TOKYO_DARK" ;;
188
- *) set_theme "$CATPPUCCIN_DARK" ;;
189
- esac
190
- else
191
- # Stay in light mode, switch family
192
- case "$family" in
193
- tokyonight) set_theme "$CATPPUCCIN_LIGHT" ;;
194
- catppuccin) set_theme "$TOKYO_LIGHT" ;;
195
- *) set_theme "$CATPPUCCIN_LIGHT" ;;
196
- esac
289
+ if [[ "$current" == *-light ]]; then
290
+ mode="light"
291
+ fi
292
+
293
+ while IFS= read -r name; do
294
+ [[ -n "$name" ]] || continue
295
+ families+=("$name")
296
+ done < <(paired_families)
297
+
298
+ if [[ ${#families[@]} -eq 0 ]]; then
299
+ set_theme "$DEFAULT_DARK"
300
+ return
197
301
  fi
302
+
303
+ for idx in "${!families[@]}"; do
304
+ if [[ "${families[$idx]}" == "$family" ]]; then
305
+ next_family="${families[$(((idx + 1) % ${#families[@]}))]}"
306
+ break
307
+ fi
308
+ done
309
+
310
+ if [[ -z "$next_family" ]]; then
311
+ next_family="${families[0]}"
312
+ fi
313
+
314
+ set_theme "${next_family}-${mode}"
198
315
  }
199
316
 
200
317
  # Show current theme info
201
318
  show_current() {
202
- current="$(current_theme)"
203
- family="$(get_theme_family "$current")"
204
- if is_dark_theme "$current"; then
205
- mode="dark"
206
- else
319
+ local current="$(current_theme)"
320
+ local family="$(get_theme_family "$current")"
321
+ local mode="dark"
322
+ if ! is_dark_theme "$current" 2>/dev/null; then
207
323
  mode="light"
208
324
  fi
209
- echo "Current: $current ($family, $mode)"
325
+ ui_info "Current" "$current ($family, $mode)"
326
+ }
327
+
328
+ # Detect system appearance (Dark/Light) and sync dotfiles
329
+ sync_theme() {
330
+ local os_mode="dark" # Default fallback
331
+ case "$(uname -s)" in
332
+ Darwin)
333
+ if defaults read -g AppleInterfaceStyle >/dev/null 2>&1; then
334
+ os_mode="dark"
335
+ else
336
+ os_mode="light"
337
+ fi
338
+ ;;
339
+ Linux)
340
+ if command -v gsettings >/dev/null 2>&1; then
341
+ # Check GNOME color scheme
342
+ local scheme=scheme=$(gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null | tr -d "'")
343
+ if [[ "$scheme" == "prefer-light" ]]; then
344
+ os_mode="light"
345
+ else
346
+ os_mode="dark"
347
+ fi
348
+ fi
349
+ ;;
350
+ esac
351
+
352
+ local current="$(current_theme)"
353
+ if is_dark_theme "$current" && [[ "$os_mode" == "light" ]]; then
354
+ ui_info "Sync" "System is light, switching dotfiles to light..."
355
+ toggle_theme
356
+ elif ! is_dark_theme "$current" && [[ "$os_mode" == "dark" ]]; then
357
+ ui_info "Sync" "System is dark, switching dotfiles to dark..."
358
+ toggle_theme
359
+ else
360
+ ui_ok "Sync" "Dotfiles already match system ($os_mode mode)"
361
+ fi
210
362
  }
211
363
 
212
364
  # =============================================================================
@@ -224,27 +376,46 @@ case "${1:-}" in
224
376
  toggle)
225
377
  toggle_theme
226
378
  ;;
379
+ sync)
380
+ sync_theme
381
+ ;;
227
382
  family)
228
383
  switch_family
229
384
  ;;
230
385
  current)
231
386
  show_current
232
387
  ;;
233
- "")
234
- echo "Usage: dot theme [command]"
388
+ rebuild)
389
+ shift
390
+ bash "$SCRIPT_DIR/rebuild-themes.sh" "$@"
391
+ ;;
392
+ help | --help | -h)
393
+ ui_header "Usage"
394
+ ui_info "dot theme" "[command]"
235
395
  echo ""
236
- echo "Commands:"
237
- echo " list Show all available themes"
238
- echo " set NAME Set theme to NAME"
239
- echo " toggle Toggle between light/dark within current family"
240
- echo " family Switch between Tokyo Night and Catppuccin families"
241
- echo " current Show current theme info"
396
+ ui_header "Commands"
397
+ ui_ok "(no args)" "Interactive theme picker (fzf)"
398
+ ui_ok "list" "Show all available themes"
399
+ ui_ok "set [NAME]" "Set theme (interactive if no name)"
400
+ ui_ok "toggle" "Toggle between light/dark within current family"
401
+ ui_ok "family" "Cycle between theme families"
402
+ ui_ok "current" "Show current theme info"
403
+ ui_ok "sync" "Sync dotfiles with system dark/light mode"
404
+ ui_ok "rebuild" "Regenerate themes from system + custom wallpapers"
242
405
  echo ""
243
406
  show_current
244
407
  ;;
408
+ "")
409
+ pick_theme
410
+ ;;
245
411
  *)
246
- echo "Unknown theme command: $1"
247
- echo "Usage: dot theme [list|set <name>|toggle|family|current]"
248
- exit 1
412
+ # Treat unknown args as theme names for quick switching: dot theme macos-sequoia-dark
413
+ if grep -q "^\[themes\.${1}\]" "$THEMES_FILE" 2>/dev/null; then
414
+ dot-theme-sync "$1"
415
+ else
416
+ ui_err "Unknown command or theme" "$1"
417
+ ui_info "Usage" "dot theme [list|set <name>|toggle|family|current|help]"
418
+ exit 1
419
+ fi
249
420
  ;;
250
421
  esac
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bash
2
+ # Copyright (c) 2015-2026 Dotfiles. All rights reserved.
2
3
  set -euo pipefail
3
4
 
4
5
  WALLPAPER_DIR="${DOTFILES_WALLPAPER_DIR:-$HOME/Pictures/Wallpapers}"
@@ -15,6 +16,14 @@ while [[ $# -gt 0 ]]; do
15
16
  ONCE=1
16
17
  shift
17
18
  ;;
19
+ --light)
20
+ FORCE_MODE="light"
21
+ shift
22
+ ;;
23
+ --dark)
24
+ FORCE_MODE="dark"
25
+ shift
26
+ ;;
18
27
  *)
19
28
  shift
20
29
  ;;
@@ -26,37 +35,78 @@ if [[ ! -d "$WALLPAPER_DIR" ]]; then
26
35
  exit 1
27
36
  fi
28
37
 
38
+ # Detect current color scheme (light/dark)
39
+ detect_mode() {
40
+ if [[ -n "${FORCE_MODE:-}" ]]; then
41
+ echo "$FORCE_MODE"
42
+ return
43
+ fi
44
+ if command -v gsettings &>/dev/null; then
45
+ local scheme
46
+ scheme="$(gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null || echo "")"
47
+ case "$scheme" in
48
+ *dark*) echo "dark" ;;
49
+ *) echo "light" ;;
50
+ esac
51
+ else
52
+ echo "dark"
53
+ fi
54
+ }
55
+
56
+ # Pick a random wallpaper matching mode, excluding the given path
29
57
  pick_wallpaper() {
30
- local files
31
- files=()
58
+ local mode="$1"
59
+ local exclude="${2:-}"
60
+ local files=()
32
61
  while IFS= read -r line; do
62
+ [[ "$line" == "$exclude" ]] && continue
33
63
  files+=("$line")
34
- done < <(find "$WALLPAPER_DIR" -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' \))
64
+ done < <(find "$WALLPAPER_DIR" -maxdepth 1 -type f -iname "*-${mode}.jpg")
65
+
35
66
  if [[ ${#files[@]} -eq 0 ]]; then
36
67
  return 1
37
68
  fi
69
+
38
70
  if command -v shuf &>/dev/null; then
39
71
  printf '%s\n' "${files[@]}" | shuf -n 1
40
72
  else
41
- # macOS fallback using $RANDOM
42
73
  echo "${files[$RANDOM % ${#files[@]}]}"
43
74
  fi
44
75
  }
45
76
 
46
77
  apply_wallpaper() {
47
78
  local wp="$1"
79
+ local mode="$2"
80
+
48
81
  case "$(uname -s)" in
49
82
  Darwin)
50
83
  osascript -e "tell application \"System Events\" to set picture of every desktop to POSIX file \"$wp\"" || true
51
84
  ;;
52
85
  Linux)
53
- if command -v feh >/dev/null; then
54
- feh --bg-fill "$wp"
55
- elif command -v swaybg >/dev/null; then
86
+ if command -v gsettings &>/dev/null; then
87
+ local light_wp dark_wp
88
+ local base="${wp%-${mode}.jpg}"
89
+ light_wp="${base}-light.jpg"
90
+ dark_wp="${base}-dark.jpg"
91
+
92
+ if [[ -f "$light_wp" ]] && [[ -f "$dark_wp" ]]; then
93
+ gsettings set org.gnome.desktop.background picture-uri "file://${light_wp}"
94
+ gsettings set org.gnome.desktop.background picture-uri-dark "file://${dark_wp}"
95
+ gsettings set org.gnome.desktop.screensaver picture-uri "file://${light_wp}"
96
+ else
97
+ local wp_uri="file://${wp}"
98
+ gsettings set org.gnome.desktop.background picture-uri "$wp_uri"
99
+ gsettings set org.gnome.desktop.background picture-uri-dark "$wp_uri"
100
+ gsettings set org.gnome.desktop.screensaver picture-uri "$wp_uri"
101
+ fi
102
+ gsettings set org.gnome.desktop.background picture-options "zoom"
103
+ elif command -v swaybg &>/dev/null; then
56
104
  pkill swaybg || true
57
105
  swaybg -i "$wp" -m fill &
106
+ elif command -v feh &>/dev/null; then
107
+ feh --bg-fill "$wp"
58
108
  else
59
- echo "No supported wallpaper setter found (feh/swaybg)." >&2
109
+ echo "No supported wallpaper setter found (gsettings/swaybg/feh)." >&2
60
110
  return 1
61
111
  fi
62
112
  ;;
@@ -67,14 +117,18 @@ apply_wallpaper() {
67
117
  esac
68
118
  }
69
119
 
120
+ LAST_WP=""
121
+
70
122
  while true; do
71
- wp=$(pick_wallpaper)
123
+ MODE="$(detect_mode)"
124
+ wp="$(pick_wallpaper "$MODE" "$LAST_WP" || true)"
72
125
  if [[ -z "$wp" ]]; then
73
- echo "No wallpapers found in $WALLPAPER_DIR" >&2
126
+ echo "No ${MODE} wallpapers found in $WALLPAPER_DIR" >&2
74
127
  exit 1
75
128
  fi
76
- apply_wallpaper "$wp"
77
- echo "Wallpaper applied: $wp"
129
+ apply_wallpaper "$wp" "$MODE"
130
+ LAST_WP="$wp"
131
+ echo "Wallpaper applied (${MODE}): $(basename "$wp")"
78
132
  if [[ "$ONCE" -eq 1 ]]; then
79
133
  break
80
134
  fi