@sebastienrousseau/dotfiles 0.2.519 → 0.2.521

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 (306) hide show
  1. package/CHANGELOG.md +200 -0
  2. package/LICENSE-APACHE +190 -0
  3. package/{LICENSE → LICENSE-MIT} +1 -1
  4. package/README.md +1172 -166
  5. package/install.sh +77 -11
  6. package/package.json +8 -8
  7. package/tools/README.md +49 -0
  8. package/tools/ci/install-chezmoi-verified.sh +68 -0
  9. package/docs/.vitepress/reports/localization-readability-audit.md +0 -73
  10. package/docs/AI.md +0 -179
  11. package/docs/CNAME +0 -1
  12. package/docs/CONFIG_STRATEGY.md +0 -124
  13. package/docs/COPYRIGHT +0 -7
  14. package/docs/GOVERNANCE.md +0 -98
  15. package/docs/MAINTAINERS.md +0 -41
  16. package/docs/NAMING_CONVENTIONS.md +0 -102
  17. package/docs/OPENCODE.md +0 -127
  18. package/docs/README.md +0 -84
  19. package/docs/STRUCTURE.md +0 -102
  20. package/docs/adr/ADR-001-ci-cd-pipeline.md +0 -118
  21. package/docs/adr/ADR-002-shell-performance.md +0 -130
  22. package/docs/adr/ADR-003-security-first.md +0 -158
  23. package/docs/adr/ADR-004-cli-architecture.md +0 -171
  24. package/docs/adr/ADR-005-chezmoi-choice.md +0 -99
  25. package/docs/adr/ADR-006-shell-selection.md +0 -124
  26. package/docs/adr/ADR-007-multi-shell-parity.md +0 -62
  27. package/docs/adr/ADR-008-alias-system-architecture.md +0 -95
  28. package/docs/adr/ADR-009-wallpaper-driven-theming.md +0 -131
  29. package/docs/adr/ADR-010-starship-transient-prompt.md +0 -144
  30. package/docs/adr/ADR-011-nushell-tier3-keep.md +0 -144
  31. package/docs/adr/ADR-012-ai-fleet-local-proxy.md +0 -79
  32. package/docs/adr/README.md +0 -40
  33. package/docs/architecture/AI_COST_OPTIMIZATION.md +0 -144
  34. package/docs/architecture/ARCHITECTURE.md +0 -117
  35. package/docs/architecture/INTEROP.md +0 -44
  36. package/docs/architecture/REPO_LAYOUT.md +0 -241
  37. package/docs/architecture/WALKTHROUGH.md +0 -86
  38. package/docs/architecture/fleet-deployment.md +0 -77
  39. package/docs/archive/EUXIS_2026_REVIEW.md +0 -127
  40. package/docs/archive/LEGACY_ROADMAP.md +0 -6
  41. package/docs/archive/MILESTONE_v0.2.493.md +0 -47
  42. package/docs/archive/PLAN.md +0 -199
  43. package/docs/archive/REPO_AUDIT.md +0 -31
  44. package/docs/articles/.pages +0 -6
  45. package/docs/articles/2026-07-05-custom-mkdocs-material-dark-theme.md +0 -216
  46. package/docs/articles/2026-07-05-fish-startup-abbr.md +0 -153
  47. package/docs/articles/2026-07-05-master-to-main-rename-runbook.md +0 -128
  48. package/docs/articles/index.md +0 -36
  49. package/docs/guides/INSTALL.md +0 -144
  50. package/docs/guides/NEOVIM_IDE_GUIDE.md +0 -61
  51. package/docs/guides/THEMING.md +0 -230
  52. package/docs/guides/TROUBLESHOOTING.md +0 -176
  53. package/docs/guides/WSL2_NIX_TROUBLESHOOTING.md +0 -792
  54. package/docs/index.md +0 -132
  55. package/docs/interop/A2A.md +0 -39
  56. package/docs/interop/POWERSHELL.md +0 -102
  57. package/docs/manual/00-introduction.md +0 -89
  58. package/docs/manual/01-concepts/01-architecture.md +0 -138
  59. package/docs/manual/01-concepts/02-trust-model.md +0 -183
  60. package/docs/manual/01-concepts/03-theme-engine.md +0 -186
  61. package/docs/manual/01-concepts/04-fleet.md +0 -148
  62. package/docs/manual/01-concepts/05-self-healing.md +0 -204
  63. package/docs/manual/02-tutorials/01-first-install.md +0 -197
  64. package/docs/manual/02-tutorials/02-add-wallpaper.md +0 -216
  65. package/docs/manual/02-tutorials/03-create-profile.md +0 -244
  66. package/docs/manual/02-tutorials/04-encrypt-secret.md +0 -281
  67. package/docs/manual/02-tutorials/05-deploy-fleet.md +0 -283
  68. package/docs/manual/03-reference/01-dot-cli.md +0 -450
  69. package/docs/manual/03-reference/02-config-files.md +0 -265
  70. package/docs/manual/03-reference/03-environment.md +0 -124
  71. package/docs/manual/03-reference/04-templates.md +0 -190
  72. package/docs/manual/03-reference/05-feature-flags.md +0 -187
  73. package/docs/manual/04-cookbook/01-recipes.md +0 -285
  74. package/docs/manual/04-cookbook/02-troubleshooting.md +0 -351
  75. package/docs/manual/04-cookbook/03-faq.md +0 -175
  76. package/docs/manual/05-appendices/A-platform-matrix.md +0 -101
  77. package/docs/manual/05-appendices/B-security-checklist.md +0 -85
  78. package/docs/manual/05-appendices/C-glossary.md +0 -40
  79. package/docs/manual/05-appendices/D-bibliography.md +0 -58
  80. package/docs/manual/05-appendices/E-license.md +0 -38
  81. package/docs/manual/_toc.yml +0 -58
  82. package/docs/manual/command-index.md +0 -155
  83. package/docs/manual/concept-index.md +0 -168
  84. package/docs/manual/index.md +0 -66
  85. package/docs/operations/ARCHITECTURE_ROADMAP.md +0 -7
  86. package/docs/operations/ATTESTATION.md +0 -44
  87. package/docs/operations/CI_CADENCE.md +0 -107
  88. package/docs/operations/CI_COMPOSITES.md +0 -156
  89. package/docs/operations/COMPLETIONS.md +0 -123
  90. package/docs/operations/COVERAGE.md +0 -204
  91. package/docs/operations/DRIFT.md +0 -107
  92. package/docs/operations/HARD_AUDIT_2026.md +0 -631
  93. package/docs/operations/MAINTENANCE.md +0 -63
  94. package/docs/operations/MANIFEST.md +0 -127
  95. package/docs/operations/MIGRATION.md +0 -109
  96. package/docs/operations/OPERATIONS.md +0 -188
  97. package/docs/operations/PERFORMANCE.md +0 -133
  98. package/docs/operations/REGISTRY.md +0 -90
  99. package/docs/operations/RELEASE_PIPELINE.md +0 -128
  100. package/docs/operations/RELIABILITY.md +0 -122
  101. package/docs/operations/RFC_v0_2_503_reorganization.md +0 -280
  102. package/docs/operations/ROADMAP.md +0 -10
  103. package/docs/operations/ROADMAP_2026.md +0 -7
  104. package/docs/operations/ROADMAP_V0_2_503.md +0 -10
  105. package/docs/operations/TESTING.md +0 -216
  106. package/docs/operations/TRACEABILITY.md +0 -43
  107. package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +0 -65
  108. package/docs/operations/VERSION_SYNC.md +0 -393
  109. package/docs/reference/ALIASES.md +0 -131
  110. package/docs/reference/ALIASES_CHEATSHEET.md +0 -32
  111. package/docs/reference/ALIASES_DEPRECATIONS.md +0 -13
  112. package/docs/reference/FEATURES.md +0 -66
  113. package/docs/reference/FONTS.md +0 -112
  114. package/docs/reference/POWERSHELL_PARITY.md +0 -82
  115. package/docs/reference/PROFILES.md +0 -69
  116. package/docs/reference/SCREENSHOTS.md +0 -121
  117. package/docs/reference/SCRIPTS.md +0 -71
  118. package/docs/reference/SUPPORT_MATRIX.md +0 -80
  119. package/docs/reference/THEMES.md +0 -117
  120. package/docs/reference/TOOLS.md +0 -110
  121. package/docs/reference/UTILS.md +0 -242
  122. package/docs/registry.json +0 -6
  123. package/docs/schema/dot-env-v1.json +0 -110
  124. package/docs/schema/dot-registry-v1.json +0 -33
  125. package/docs/security/AI_ACT_COMPLIANCE.md +0 -94
  126. package/docs/security/AUDIT_BYPASS.md +0 -103
  127. package/docs/security/AUTOMATION_SECRETS.md +0 -26
  128. package/docs/security/CI_EGRESS_ALLOWLIST.md +0 -127
  129. package/docs/security/CI_PINNING.md +0 -129
  130. package/docs/security/COMMIT_SIGNING.md +0 -138
  131. package/docs/security/COMPLIANCE.md +0 -458
  132. package/docs/security/DEPS_DEV_EXCEPTIONS.md +0 -86
  133. package/docs/security/DISCLOSURE.md +0 -130
  134. package/docs/security/ENCRYPTION.md +0 -57
  135. package/docs/security/FMEA.md +0 -159
  136. package/docs/security/FUZZING.md +0 -114
  137. package/docs/security/HISTORY_FILTERING.md +0 -132
  138. package/docs/security/INCIDENT_RESPONSE.md +0 -579
  139. package/docs/security/INSTALL_VERIFICATION.md +0 -122
  140. package/docs/security/KEYS.md +0 -49
  141. package/docs/security/KEY_ROTATION.md +0 -303
  142. package/docs/security/MCP_POLICY.md +0 -78
  143. package/docs/security/POLICY_RELEASES.md +0 -37
  144. package/docs/security/README.md +0 -28
  145. package/docs/security/SCORECARD.md +0 -195
  146. package/docs/security/SECRETS.md +0 -158
  147. package/docs/security/SECURITY.md +0 -45
  148. package/docs/security/SECURITY_CHECKLIST.md +0 -55
  149. package/docs/security/SHELL_EXEMPTIONS.md +0 -145
  150. package/docs/security/SOUP_REGISTER.md +0 -36
  151. package/docs/security/THREAT_MODEL.md +0 -130
  152. package/docs/security/VERIFICATION_VALIDATION.md +0 -228
  153. package/docs/security/VERIFY_RELEASE.md +0 -201
  154. package/docs/security/security-pubkey.asc +0 -15
  155. package/docs/stylesheets/extra.css +0 -444
  156. package/docs/themes/README.md +0 -10
  157. package/docs/themes/VISUAL_INTEGRITY_REPORT.md +0 -30
  158. package/docs/themes/hero-shot.svg +0 -78
  159. package/scripts/README.md +0 -123
  160. package/scripts/ci/check-copyright-headers.sh +0 -8
  161. package/scripts/ci/check-shell-preamble.sh +0 -8
  162. package/scripts/ci/guard-gitleaks-checkout.sh +0 -8
  163. package/scripts/demo/record.sh +0 -43
  164. package/scripts/diagnostics/a2a-conformance.sh +0 -163
  165. package/scripts/diagnostics/alias-governance.sh +0 -138
  166. package/scripts/diagnostics/aliases-cheatsheet.sh +0 -74
  167. package/scripts/diagnostics/aliases-manifest.sh +0 -77
  168. package/scripts/diagnostics/benchmark.sh +0 -408
  169. package/scripts/diagnostics/conflicts.sh +0 -73
  170. package/scripts/diagnostics/doctor-unified.sh +0 -39
  171. package/scripts/diagnostics/doctor.sh +0 -751
  172. package/scripts/diagnostics/drift-dashboard.sh +0 -202
  173. package/scripts/diagnostics/health.sh +0 -623
  174. package/scripts/diagnostics/history-analysis.sh +0 -86
  175. package/scripts/diagnostics/mcp-doctor.sh +0 -582
  176. package/scripts/diagnostics/perf.sh +0 -453
  177. package/scripts/diagnostics/scorecard.sh +0 -119
  178. package/scripts/diagnostics/secret-governance.sh +0 -65
  179. package/scripts/diagnostics/security-score.sh +0 -467
  180. package/scripts/diagnostics/smoke-test.sh +0 -88
  181. package/scripts/diagnostics/snapshot.sh +0 -90
  182. package/scripts/diagnostics/verify.sh +0 -108
  183. package/scripts/diagnostics/verify_state.sh +0 -73
  184. package/scripts/diagnostics/version-locks.sh +0 -94
  185. package/scripts/diagnostics/workstation-attestation.sh +0 -187
  186. package/scripts/dot/commands/agent.sh +0 -485
  187. package/scripts/dot/commands/agents.sh +0 -336
  188. package/scripts/dot/commands/ai.sh +0 -587
  189. package/scripts/dot/commands/aliases.sh +0 -277
  190. package/scripts/dot/commands/appearance.sh +0 -110
  191. package/scripts/dot/commands/completion.sh +0 -134
  192. package/scripts/dot/commands/core.sh +0 -217
  193. package/scripts/dot/commands/diagnostics.sh +0 -265
  194. package/scripts/dot/commands/env-emit.sh +0 -203
  195. package/scripts/dot/commands/fleet.sh +0 -688
  196. package/scripts/dot/commands/init.sh +0 -185
  197. package/scripts/dot/commands/lint.sh +0 -208
  198. package/scripts/dot/commands/manual.sh +0 -169
  199. package/scripts/dot/commands/meta.sh +0 -333
  200. package/scripts/dot/commands/patterns.sh +0 -55
  201. package/scripts/dot/commands/registry.sh +0 -419
  202. package/scripts/dot/commands/restore.sh +0 -232
  203. package/scripts/dot/commands/secrets.sh +0 -296
  204. package/scripts/dot/commands/security.sh +0 -102
  205. package/scripts/dot/commands/tools.sh +0 -556
  206. package/scripts/dot/data/alias-deprecations.tsv +0 -2
  207. package/scripts/dot/powershell/Dot.psm1 +0 -319
  208. package/scripts/fonts/install-nerd-fonts.sh +0 -75
  209. package/scripts/fonts/patch-fonts.sh +0 -36
  210. package/scripts/git-hooks/install.sh +0 -12
  211. package/scripts/git-hooks/pre-commit +0 -12
  212. package/scripts/git-hooks/pre-commit-audit.sh +0 -146
  213. package/scripts/git-hooks/pre-push +0 -105
  214. package/scripts/git-hooks/prepare-commit-msg +0 -29
  215. package/scripts/lib/secrets_provider.sh +0 -185
  216. package/scripts/ops/ai-setup.sh +0 -71
  217. package/scripts/ops/bundle.sh +0 -104
  218. package/scripts/ops/chaos.sh +0 -50
  219. package/scripts/ops/chezmoi-apply.sh +0 -333
  220. package/scripts/ops/chezmoi-diff.sh +0 -16
  221. package/scripts/ops/chezmoi-remove.sh +0 -46
  222. package/scripts/ops/chezmoi-update.sh +0 -63
  223. package/scripts/ops/heal-chezmoi.sh +0 -87
  224. package/scripts/ops/heal-system.sh +0 -129
  225. package/scripts/ops/heal-tools.sh +0 -297
  226. package/scripts/ops/heal.sh +0 -223
  227. package/scripts/ops/post-apply-repair.sh +0 -107
  228. package/scripts/ops/prewarm.sh +0 -128
  229. package/scripts/ops/release.sh +0 -262
  230. package/scripts/ops/rollback.sh +0 -604
  231. package/scripts/ops/setup.sh +0 -138
  232. package/scripts/ops/teleport.sh +0 -34
  233. package/scripts/qa/check-version-consistency.sh +0 -124
  234. package/scripts/qa/coverage-baseline.sh +0 -61
  235. package/scripts/qa/docs-coverage.sh +0 -112
  236. package/scripts/qa/examples-coverage.sh +0 -94
  237. package/scripts/qa/powershell-contract.ps1 +0 -95
  238. package/scripts/qa/reliability-audit.sh +0 -139
  239. package/scripts/qa/scorecard-snapshot.sh +0 -128
  240. package/scripts/qa/traceability-coverage.sh +0 -117
  241. package/scripts/qa/validate-examples.sh +0 -27
  242. package/scripts/qa/wsl-contract.sh +0 -12
  243. package/scripts/secrets/age-init.sh +0 -82
  244. package/scripts/secrets/create-secrets-file.sh +0 -46
  245. package/scripts/secrets/encrypt-ssh-key.sh +0 -44
  246. package/scripts/security/backup.sh +0 -58
  247. package/scripts/security/check-disclosure-key-expiry.sh +0 -111
  248. package/scripts/security/dns-doh.sh +0 -52
  249. package/scripts/security/encryption-check.sh +0 -55
  250. package/scripts/security/enforce-policies.sh +0 -335
  251. package/scripts/security/firewall.sh +0 -91
  252. package/scripts/security/lock-configs.sh +0 -67
  253. package/scripts/security/lock-screen.sh +0 -56
  254. package/scripts/security/manage-secrets.sh +0 -429
  255. package/scripts/security/ssh-cert.sh +0 -204
  256. package/scripts/security/telemetry-kill.sh +0 -51
  257. package/scripts/security/usb-safety.sh +0 -52
  258. package/scripts/theme/apply-gnome-theme.sh +0 -333
  259. package/scripts/theme/extract-heic-frames.sh +0 -115
  260. package/scripts/theme/extract-theme.py +0 -742
  261. package/scripts/theme/install-boot-logo.sh +0 -63
  262. package/scripts/theme/install-catppuccin-themes.sh +0 -371
  263. package/scripts/theme/install-cursors.sh +0 -26
  264. package/scripts/theme/install-file-icons.sh +0 -27
  265. package/scripts/theme/install-grub-theme.sh +0 -62
  266. package/scripts/theme/install-lock-icon.sh +0 -31
  267. package/scripts/theme/merge-wallpaper.sh +0 -146
  268. package/scripts/theme/rebuild-themes.sh +0 -544
  269. package/scripts/theme/switch.sh +0 -449
  270. package/scripts/theme/wallpaper-rotate.sh +0 -137
  271. package/scripts/theme/wallpaper-sync.sh +0 -690
  272. package/scripts/tools/cmatrix.sh +0 -22
  273. package/scripts/tools/detect-collisions.py +0 -103
  274. package/scripts/tools/emoji-picker.sh +0 -49
  275. package/scripts/tools/figlet-banner.sh +0 -19
  276. package/scripts/tools/log-rotate.sh +0 -31
  277. package/scripts/tools/lolcat-wrap.sh +0 -20
  278. package/scripts/tools/pipes.sh +0 -49
  279. package/scripts/tuning/linux.sh +0 -186
  280. package/scripts/tuning/macos.sh +0 -56
  281. package/scripts/uninstall.sh +0 -86
  282. package/scripts/version-sync.sh +0 -654
  283. package/templates/chezmoi-data/geekom-a9.toml.example +0 -21
  284. package/templates/chezmoi-data/mac-m1.toml.example +0 -16
  285. package/templates/chezmoi-data/mac-t2-linux.toml.example +0 -21
  286. package/templates/chezmoi-data/surface-pro-7p.toml.example +0 -21
  287. package/templates/projects/go/.github/workflows/ci.yml +0 -31
  288. package/templates/projects/go/README.md +0 -7
  289. package/templates/projects/go/cmd/__PROJECT_NAME__/main.go +0 -8
  290. package/templates/projects/go/go.mod +0 -3
  291. package/templates/projects/go/go.sum +0 -0
  292. package/templates/projects/molecule/README.md +0 -7
  293. package/templates/projects/molecule/converge.yml +0 -7
  294. package/templates/projects/molecule/molecule.yml +0 -16
  295. package/templates/projects/node/.github/workflows/ci.yml +0 -30
  296. package/templates/projects/node/README.md +0 -7
  297. package/templates/projects/node/package-lock.json +0 -12
  298. package/templates/projects/node/package.json +0 -10
  299. package/templates/projects/node/src/index.js +0 -3
  300. package/templates/projects/packer/README.md +0 -15
  301. package/templates/projects/packer/main.pkr.hcl +0 -15
  302. package/templates/projects/python/.github/workflows/ci.yml +0 -34
  303. package/templates/projects/python/README.md +0 -7
  304. package/templates/projects/python/pyproject.toml +0 -25
  305. package/templates/projects/python/src/__PROJECT_NAME__/__init__.py +0 -2
  306. package/templates/projects/python/tests/test_basic.py +0 -3
@@ -1,449 +0,0 @@
1
- #!/usr/bin/env bash
2
- # SPDX-License-Identifier: MIT
3
- # Copyright (c) 2015-2026 Sebastien Rousseau
4
- ## Theme Switcher — Switch between theme families and light/dark modes.
5
- ##
6
- ## Supports Tokyo Night, Catppuccin, Rose Pine, Kanagawa, and other
7
- ## popular theme families. Updates chezmoi data and applies changes.
8
- ##
9
- ## # Requirements
10
- ## - chezmoi: Dotfiles manager
11
- ## - sed: For updating theme configuration
12
- ##
13
- ## # Usage
14
- ## dot theme list # Show all available themes
15
- ## dot theme set NAME # Set theme to NAME
16
- ## dot theme toggle # Toggle light/dark within family
17
- ## dot theme family # Switch between theme families
18
- ## dot theme current # Show current theme info
19
- ##
20
- ## # Platform Notes
21
- ## - All platforms: Updates chezmoi configuration
22
-
23
- set -euo pipefail
24
-
25
- # Cleanup function for temp files
26
- cleanup() {
27
- if [[ -n "${tmp_file:-}" ]] && [[ -f "$tmp_file" ]]; then
28
- rm -f "$tmp_file"
29
- fi
30
- }
31
- trap cleanup EXIT
32
-
33
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
34
- # shellcheck source=../../lib/dot/ui.sh
35
- # shellcheck disable=SC1091
36
- source "$SCRIPT_DIR/../../lib/dot/ui.sh"
37
-
38
- ui_init
39
-
40
- resolve_source_dir() {
41
- if [ -n "${CHEZMOI_SOURCE_DIR:-}" ] && [ -d "$CHEZMOI_SOURCE_DIR" ]; then
42
- echo "$CHEZMOI_SOURCE_DIR"
43
- return
44
- fi
45
- if [ -d "$HOME/.dotfiles" ]; then
46
- echo "$HOME/.dotfiles"
47
- return
48
- fi
49
- if [ -d "$HOME/.local/share/chezmoi" ]; then
50
- echo "$HOME/.local/share/chezmoi"
51
- return
52
- fi
53
- echo ""
54
- }
55
-
56
- SRC_DIR="$(resolve_source_dir)"
57
- if [ -z "$SRC_DIR" ]; then
58
- ui_err "Dotfiles source" "not found"
59
- exit 1
60
- fi
61
-
62
- # Descend into the chezmoi source subdir when .chezmoiroot is present (post-reorg, chezmoi files under defaults/)
63
- CHEZMOI_SRC="$SRC_DIR"
64
- if [[ -f "$SRC_DIR/.chezmoiroot" ]]; then
65
- _sub="$(head -1 "$SRC_DIR/.chezmoiroot" | tr -d '[:space:]')"
66
- [[ -n "$_sub" && -d "$SRC_DIR/$_sub" ]] && CHEZMOI_SRC="$SRC_DIR/$_sub"
67
- fi
68
-
69
- DATA_FILE="$CHEZMOI_SRC/.chezmoidata.toml"
70
- THEMES_FILE="$CHEZMOI_SRC/.chezmoidata/themes.toml"
71
- WALLPAPER_DIR="${DOTFILES_WALLPAPER_DIR:-$HOME/Pictures/Wallpapers}"
72
- if [ ! -f "$DATA_FILE" ]; then
73
- ui_err "Missing" "$DATA_FILE"
74
- exit 1
75
- fi
76
-
77
- # =============================================================================
78
- # Theme Database
79
- # =============================================================================
80
-
81
- # Default preferences (must be present keys in themes.toml — the theme
82
- # regeneration removed the old macos-monterey-* names; bloom is the current
83
- # default family and always ships a dark+light pair).
84
- DEFAULT_DARK="bloom-dark"
85
- DEFAULT_LIGHT="bloom-light"
86
-
87
- # Machine-local chezmoi override (chezmoi.toml [data] theme) takes precedence
88
- # over .chezmoidata.toml when rendering, so it is the authoritative "current"
89
- # value. Kept in sync by dot-theme-sync's write_theme().
90
- CHEZMOI_CFG="${XDG_CONFIG_HOME:-$HOME/.config}/chezmoi/chezmoi.toml"
91
-
92
- # =============================================================================
93
- # Theme Functions
94
- # =============================================================================
95
-
96
- current_theme() {
97
- # Prefer the machine-local override (what chezmoi actually renders), so
98
- # `dot theme current` never disagrees with the deployed configs. Fall back
99
- # to the repo default in .chezmoidata.toml when no override is set.
100
- if [[ -f "$CHEZMOI_CFG" ]]; then
101
- local override
102
- override="$(awk -F'"' '/^theme =/ {print $2}' "$CHEZMOI_CFG" | head -n 1)"
103
- if [[ -n "$override" ]]; then
104
- echo "$override"
105
- return 0
106
- fi
107
- fi
108
- awk -F'"' '/^theme =/ {print $2}' "$DATA_FILE" | head -n 1
109
- }
110
-
111
- theme_mode() {
112
- local name="${1:-}"
113
- awk -v n="$name" '
114
- $0 == "[themes." n "]" { found=1; next }
115
- /^\[/ { found=0 }
116
- found && /^mode/ { sub(/.*= *"/, ""); sub(/".*/, ""); print; exit }
117
- ' "$THEMES_FILE"
118
- }
119
-
120
- theme_exists() {
121
- local name="${1:-}"
122
- grep -q "^\[themes\.${name}\]$" "$THEMES_FILE" 2>/dev/null
123
- }
124
-
125
- all_theme_names() {
126
- sed -n 's/^\[themes\.\([a-z0-9-]*\)\]$/\1/p' "$THEMES_FILE" | sort -u
127
- }
128
-
129
- # List wallpaper families that have BOTH dark and light variants in themes.toml.
130
- # Only these are presented to users — unpaired wallpapers are hidden.
131
- paired_families() {
132
- local -A has_dark has_light
133
- local name family
134
- while IFS= read -r name; do
135
- if [[ "$name" == *-dark ]]; then
136
- family="${name%-dark}"
137
- has_dark["$family"]=1
138
- elif [[ "$name" == *-light ]]; then
139
- family="${name%-light}"
140
- has_light["$family"]=1
141
- fi
142
- done < <(all_theme_names)
143
-
144
- for family in $(printf '%s\n' "${!has_dark[@]}" | sort); do
145
- # `fallback` is a synthetic safety theme (see themes.toml) that templates
146
- # degrade to when .theme is unset/invalid — never a user-selectable one.
147
- [[ "$family" == "fallback" ]] && continue
148
- [[ -n "${has_light[$family]+x}" ]] && echo "$family"
149
- done
150
- }
151
-
152
- # Determine source type (system/custom) for a wallpaper family.
153
- wallpaper_source() {
154
- local family="${1:-}"
155
- # Check for custom wallpapers: dynamic (family.heic) or split (family-dark/light.ext)
156
- for ext in heic jpg png webp; do
157
- if [[ -f "$WALLPAPER_DIR/${family}.${ext}" || -f "$WALLPAPER_DIR/${family}-dark.${ext}" || -f "$WALLPAPER_DIR/${family}-light.${ext}" || -f "$WALLPAPER_DIR/${family}-0.${ext}" ]]; then
158
- echo "Custom"
159
- return
160
- fi
161
- done
162
- echo "System"
163
- }
164
-
165
- get_theme_family() {
166
- local theme="${1:-}"
167
- # Read family from themes.toml if available
168
- if [[ -f "$THEMES_FILE" ]]; then
169
- local family
170
- family="$(awk -v n="$theme" '
171
- $0 == "[themes." n "]" { found=1; next }
172
- /^\[/ { found=0 }
173
- found && /^family/ { sub(/.*= *"/, ""); sub(/".*/, ""); print; exit }
174
- ' "$THEMES_FILE")"
175
- if [[ -n "$family" ]]; then
176
- echo "$family"
177
- return
178
- fi
179
- fi
180
- # Fallback: strip -dark/-light suffix
181
- local family="${theme%-dark}"
182
- [[ "$family" != "$theme" ]] || family="${theme%-light}"
183
- echo "$family"
184
- }
185
-
186
- is_dark_theme() {
187
- local theme="${1:-}"
188
- case "$theme" in
189
- *-dark)
190
- return 0
191
- ;;
192
- *)
193
- return 1
194
- ;;
195
- esac
196
- }
197
-
198
- set_theme() {
199
- local new_theme="$1"
200
- if [ -z "$new_theme" ]; then
201
- pick_theme
202
- return
203
- fi
204
- dot-theme-sync "$new_theme"
205
- }
206
-
207
- # Interactive theme picker
208
- pick_theme() {
209
- local current
210
- current="$(current_theme)"
211
-
212
- if [[ ! -f "$THEMES_FILE" ]]; then
213
- ui_err "Missing" "$THEMES_FILE"
214
- exit 1
215
- fi
216
-
217
- local current_family="${current%-dark}"
218
- [[ "$current_family" != "$current" ]] || current_family="${current%-light}"
219
- local current_mode="dark"
220
- is_dark_theme "$current" 2>/dev/null || current_mode="light"
221
-
222
- # Build theme list: one row per family, shows active mode
223
- local theme_list=""
224
- local family source marker active_mode
225
- while IFS= read -r family; do
226
- [[ -n "$family" ]] || continue
227
- source="$(wallpaper_source "$family")"
228
- marker="○"
229
- active_mode=""
230
- if [[ "$family" == "$current_family" ]]; then
231
- marker="✓"
232
- active_mode="$current_mode"
233
- fi
234
- theme_list+="$(printf '%s %-35s %-8s %s' "$marker" "$family" "$source" "$active_mode")"$'\n'
235
- done < <(paired_families)
236
-
237
- local selected_family
238
- selected_family="$(printf '%s' "$theme_list" | ui_pick \
239
- --header "Select wallpaper theme (current: $current_family [$current_mode])" \
240
- --prompt "Theme >" |
241
- awk '$1 !~ /^#/ && NF >= 2 {print $2}')" || return 0
242
-
243
- if [[ -n "$selected_family" ]]; then
244
- # Apply with current appearance mode (dark/light)
245
- local new_theme="${selected_family}-${current_mode}"
246
- if [[ "$new_theme" != "$current" ]]; then
247
- dot-theme-sync "$new_theme"
248
- else
249
- ui_info "Theme" "already on $current"
250
- fi
251
- fi
252
- }
253
-
254
- list_themes() {
255
- local current
256
- current="$(current_theme)"
257
- local current_family="${current%-dark}"
258
- [[ "$current_family" != "$current" ]] || current_family="${current%-light}"
259
-
260
- local count=0
261
- local family source
262
-
263
- printf ' %-35s %s\n' "WALLPAPER" "SOURCE"
264
- printf ' %-35s %s\n' "---------" "------"
265
- while IFS= read -r family; do
266
- [[ -n "$family" ]] || continue
267
- source="$(wallpaper_source "$family")"
268
- if [[ "$family" == "$current_family" ]]; then
269
- ui_ok "$family" "$source ◀"
270
- else
271
- printf ' %-35s %s\n' "$family" "$source"
272
- fi
273
- count=$((count + 1))
274
- done < <(paired_families)
275
-
276
- echo ""
277
- ui_info "Current" "$(current_theme) ($count wallpaper themes available)"
278
- }
279
-
280
- # Toggle between light and dark within the same family, or switch families
281
- toggle_theme() {
282
- local current
283
- current="$(current_theme)"
284
-
285
- if is_dark_theme "$current"; then
286
- if [[ "$current" == *-dark ]]; then
287
- set_theme "${current%-dark}-light"
288
- else
289
- set_theme "$DEFAULT_LIGHT"
290
- fi
291
- else
292
- if [[ "$current" == *-light ]]; then
293
- set_theme "${current%-light}-dark"
294
- else
295
- set_theme "$DEFAULT_DARK"
296
- fi
297
- fi
298
- }
299
-
300
- # Switch to the next wallpaper family while preserving mode.
301
- switch_family() {
302
- local current family
303
- current="$(current_theme)"
304
- family="$(get_theme_family "$current")"
305
- local mode="dark"
306
- local families=()
307
- local idx=0
308
- local next_family=""
309
-
310
- if [[ "$current" == *-light ]]; then
311
- mode="light"
312
- fi
313
-
314
- while IFS= read -r name; do
315
- [[ -n "$name" ]] || continue
316
- families+=("$name")
317
- done < <(paired_families)
318
-
319
- if [[ ${#families[@]} -eq 0 ]]; then
320
- set_theme "$DEFAULT_DARK"
321
- return
322
- fi
323
-
324
- for idx in "${!families[@]}"; do
325
- if [[ "${families[$idx]}" == "$family" ]]; then
326
- next_family="${families[$(((idx + 1) % ${#families[@]}))]}"
327
- break
328
- fi
329
- done
330
-
331
- if [[ -z "$next_family" ]]; then
332
- next_family="${families[0]}"
333
- fi
334
-
335
- set_theme "${next_family}-${mode}"
336
- }
337
-
338
- # Show current theme info
339
- show_current() {
340
- local current family
341
- current="$(current_theme)"
342
- family="$(get_theme_family "$current")"
343
- local mode="dark"
344
- if ! is_dark_theme "$current" 2>/dev/null; then
345
- mode="light"
346
- fi
347
- ui_info "Current" "$current ($family, $mode)"
348
- }
349
-
350
- # Detect system appearance (Dark/Light) and sync dotfiles
351
- sync_theme() {
352
- local os_mode="dark" # Default fallback
353
- case "$(uname -s)" in
354
- Darwin)
355
- if defaults read -g AppleInterfaceStyle >/dev/null 2>&1; then
356
- os_mode="dark"
357
- else
358
- os_mode="light"
359
- fi
360
- ;;
361
- Linux)
362
- if command -v gsettings >/dev/null 2>&1; then
363
- # Check GNOME color scheme. Fixes a long-standing bug where the
364
- # variable was declared as `local scheme=scheme=$(...)` — the
365
- # extra `scheme=` prefix made the value always start with that
366
- # literal, so the `prefer-light` test below could never match
367
- # and the system always fell through to the dark branch.
368
- local scheme
369
- scheme=$(gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null | tr -d "'")
370
- if [[ "$scheme" == "prefer-light" ]]; then
371
- os_mode="light"
372
- else
373
- os_mode="dark"
374
- fi
375
- fi
376
- ;;
377
- esac
378
-
379
- local current
380
- current="$(current_theme)"
381
- if is_dark_theme "$current" && [[ "$os_mode" == "light" ]]; then
382
- ui_info "Sync" "System is light, switching dotfiles to light..."
383
- toggle_theme
384
- elif ! is_dark_theme "$current" && [[ "$os_mode" == "dark" ]]; then
385
- ui_info "Sync" "System is dark, switching dotfiles to dark..."
386
- toggle_theme
387
- else
388
- ui_ok "Sync" "Dotfiles already match system ($os_mode mode)"
389
- fi
390
- }
391
-
392
- # =============================================================================
393
- # Main
394
- # =============================================================================
395
-
396
- case "${1:-}" in
397
- list)
398
- list_themes
399
- ;;
400
- set)
401
- shift
402
- set_theme "$1"
403
- ;;
404
- toggle)
405
- toggle_theme
406
- ;;
407
- sync)
408
- sync_theme
409
- ;;
410
- family)
411
- switch_family
412
- ;;
413
- current)
414
- show_current
415
- ;;
416
- rebuild)
417
- shift
418
- bash "$SCRIPT_DIR/rebuild-themes.sh" "$@"
419
- ;;
420
- help | --help | -h)
421
- ui_header "Usage"
422
- ui_info "dot theme" "[command]"
423
- echo ""
424
- ui_header "Commands"
425
- ui_ok "(no args)" "Interactive theme picker (fzf)"
426
- ui_ok "list" "Show all available themes"
427
- ui_ok "set [NAME]" "Set theme (interactive if no name)"
428
- ui_ok "toggle" "Toggle between light/dark within current family"
429
- ui_ok "family" "Cycle between theme families"
430
- ui_ok "current" "Show current theme info"
431
- ui_ok "sync" "Sync dotfiles with system dark/light mode"
432
- ui_ok "rebuild" "Regenerate themes from system + custom wallpapers"
433
- echo ""
434
- show_current
435
- ;;
436
- "")
437
- pick_theme
438
- ;;
439
- *)
440
- # Treat unknown args as theme names for quick switching: dot theme macos-sequoia-dark
441
- if grep -q "^\[themes\.${1}\]" "$THEMES_FILE" 2>/dev/null; then
442
- dot-theme-sync "$1"
443
- else
444
- ui_err "Unknown command or theme" "$1"
445
- ui_info "Usage" "dot theme [list|set <name>|toggle|family|current|help]"
446
- exit 1
447
- fi
448
- ;;
449
- esac
@@ -1,137 +0,0 @@
1
- #!/usr/bin/env bash
2
- # SPDX-License-Identifier: MIT
3
- # Copyright (c) 2015-2026 Sebastien Rousseau
4
- set -euo pipefail
5
-
6
- WALLPAPER_DIR="${DOTFILES_WALLPAPER_DIR:-$HOME/Pictures/Wallpapers}"
7
- INTERVAL="${DOTFILES_WALLPAPER_INTERVAL:-300}"
8
- ONCE=0
9
-
10
- while [[ $# -gt 0 ]]; do
11
- case "$1" in
12
- --interval)
13
- INTERVAL="$2"
14
- shift 2
15
- ;;
16
- --once)
17
- ONCE=1
18
- shift
19
- ;;
20
- --light)
21
- FORCE_MODE="light"
22
- shift
23
- ;;
24
- --dark)
25
- FORCE_MODE="dark"
26
- shift
27
- ;;
28
- *)
29
- shift
30
- ;;
31
- esac
32
- done
33
-
34
- if [[ ! -d "$WALLPAPER_DIR" ]]; then
35
- echo "Wallpaper directory not found: $WALLPAPER_DIR" >&2
36
- exit 1
37
- fi
38
-
39
- # Detect current color scheme (light/dark)
40
- detect_mode() {
41
- if [[ -n "${FORCE_MODE:-}" ]]; then
42
- echo "$FORCE_MODE"
43
- return
44
- fi
45
- if command -v gsettings &>/dev/null; then
46
- local scheme
47
- scheme="$(gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null || echo "")"
48
- case "$scheme" in
49
- *dark*) echo "dark" ;;
50
- *) echo "light" ;;
51
- esac
52
- else
53
- echo "dark"
54
- fi
55
- }
56
-
57
- # Pick a random wallpaper matching mode, excluding the given path
58
- pick_wallpaper() {
59
- local mode="$1"
60
- local exclude="${2:-}"
61
- local files=()
62
- while IFS= read -r line; do
63
- [[ "$line" == "$exclude" ]] && continue
64
- files+=("$line")
65
- done < <(find "$WALLPAPER_DIR" -maxdepth 1 -type f -iname "*-${mode}.jpg")
66
-
67
- if [[ ${#files[@]} -eq 0 ]]; then
68
- return 1
69
- fi
70
-
71
- if command -v shuf &>/dev/null; then
72
- printf '%s\n' "${files[@]}" | shuf -n 1
73
- else
74
- echo "${files[$RANDOM % ${#files[@]}]}"
75
- fi
76
- }
77
-
78
- apply_wallpaper() {
79
- local wp="$1"
80
- local mode="$2"
81
-
82
- case "$(uname -s)" in
83
- Darwin)
84
- osascript -e "tell application \"System Events\" to set picture of every desktop to POSIX file \"$wp\"" || true
85
- ;;
86
- Linux)
87
- if command -v gsettings &>/dev/null; then
88
- local light_wp dark_wp
89
- local base="${wp%-${mode}.jpg}"
90
- light_wp="${base}-light.jpg"
91
- dark_wp="${base}-dark.jpg"
92
-
93
- if [[ -f "$light_wp" ]] && [[ -f "$dark_wp" ]]; then
94
- gsettings set org.gnome.desktop.background picture-uri "file://${light_wp}"
95
- gsettings set org.gnome.desktop.background picture-uri-dark "file://${dark_wp}"
96
- gsettings set org.gnome.desktop.screensaver picture-uri "file://${light_wp}"
97
- else
98
- local wp_uri="file://${wp}"
99
- gsettings set org.gnome.desktop.background picture-uri "$wp_uri"
100
- gsettings set org.gnome.desktop.background picture-uri-dark "$wp_uri"
101
- gsettings set org.gnome.desktop.screensaver picture-uri "$wp_uri"
102
- fi
103
- gsettings set org.gnome.desktop.background picture-options "zoom"
104
- elif command -v swaybg &>/dev/null; then
105
- pkill swaybg || true
106
- swaybg -i "$wp" -m fill &
107
- elif command -v feh &>/dev/null; then
108
- feh --bg-fill "$wp"
109
- else
110
- echo "No supported wallpaper setter found (gsettings/swaybg/feh)." >&2
111
- return 1
112
- fi
113
- ;;
114
- *)
115
- echo "Wallpaper rotation not supported on this OS." >&2
116
- return 1
117
- ;;
118
- esac
119
- }
120
-
121
- LAST_WP=""
122
-
123
- while true; do
124
- MODE="$(detect_mode)"
125
- wp="$(pick_wallpaper "$MODE" "$LAST_WP" || true)"
126
- if [[ -z "$wp" ]]; then
127
- echo "No ${MODE} wallpapers found in $WALLPAPER_DIR" >&2
128
- exit 1
129
- fi
130
- apply_wallpaper "$wp" "$MODE"
131
- LAST_WP="$wp"
132
- echo "Wallpaper applied (${MODE}): $(basename "$wp")"
133
- if [[ "$ONCE" -eq 1 ]]; then
134
- break
135
- fi
136
- sleep "$INTERVAL"
137
- done