@sebastienrousseau/dotfiles 0.2.502 → 0.2.504
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.
- package/CHANGELOG.md +109 -9
- package/LICENSE +21 -1283
- package/README.md +6 -4
- package/docs/CONFIG_STRATEGY.md +124 -0
- package/docs/COPYRIGHT +1 -1
- package/docs/GOVERNANCE.md +98 -0
- package/docs/MAINTAINERS.md +41 -0
- package/docs/OPENCODE.md +127 -0
- package/docs/README.md +2 -0
- package/docs/STRUCTURE.md +102 -0
- package/docs/adr/ADR-011-nushell-tier3-keep.md +2 -2
- package/docs/architecture/AI_COST_OPTIMIZATION.md +143 -0
- package/docs/architecture/REPO_LAYOUT.md +8 -8
- package/docs/archive/MILESTONE_v0.2.493.md +1 -1
- package/docs/index.md +2 -2
- package/docs/interop/POWERSHELL.md +1 -1
- package/docs/manual/00-introduction.md +1 -1
- package/docs/manual/01-concepts/02-trust-model.md +1 -1
- package/docs/manual/03-reference/02-config-files.md +2 -2
- package/docs/manual/_toc.yml +1 -1
- package/docs/manual/command-index.md +72 -59
- package/docs/operations/CI_COMPOSITES.md +2 -2
- package/docs/operations/COMPLETIONS.md +2 -2
- package/docs/operations/COVERAGE.md +5 -5
- package/docs/operations/HARD_AUDIT_2026.md +11 -11
- package/docs/operations/MAINTENANCE.md +3 -3
- package/docs/operations/MANIFEST.md +127 -0
- package/docs/operations/RELEASE_PIPELINE.md +130 -0
- package/docs/operations/RFC_v0_2_503_reorganization.md +280 -0
- package/docs/operations/ROADMAP_2026.md +6 -6
- package/docs/operations/ROADMAP_V0_2_503.md +134 -0
- package/docs/operations/TESTING.md +17 -0
- package/docs/operations/TRACEABILITY.md +6 -3
- package/docs/operations/VERSION_SYNC.md +4 -4
- package/docs/reference/POWERSHELL_PARITY.md +8 -7
- package/docs/schema/dot-env-v1.json +110 -0
- package/docs/security/CI_EGRESS_ALLOWLIST.md +1 -1
- package/docs/security/CI_PINNING.md +17 -9
- package/docs/security/DEPS_DEV_EXCEPTIONS.md +2 -2
- package/docs/security/FUZZING.md +114 -0
- package/docs/security/INSTALL_VERIFICATION.md +2 -2
- package/docs/security/POLICY_RELEASES.md +2 -2
- package/docs/security/SCORECARD.md +58 -3
- package/docs/security/SHELL_EXEMPTIONS.md +4 -4
- package/docs/security/VERIFY_RELEASE.md +201 -0
- package/install.sh +118 -5
- package/package.json +1 -1
- package/scripts/README.md +123 -0
- package/scripts/ci/check-copyright-headers.sh +4 -93
- package/scripts/ci/check-shell-preamble.sh +4 -103
- package/scripts/ci/guard-gitleaks-checkout.sh +4 -54
- package/scripts/diagnostics/a2a-conformance.sh +4 -4
- package/scripts/diagnostics/alias-governance.sh +1 -1
- package/scripts/diagnostics/aliases-cheatsheet.sh +2 -2
- package/scripts/diagnostics/benchmark.sh +5 -5
- package/scripts/diagnostics/conflicts.sh +2 -2
- package/scripts/diagnostics/doctor-unified.sh +3 -3
- package/scripts/diagnostics/doctor.sh +10 -10
- package/scripts/diagnostics/drift-dashboard.sh +2 -2
- package/scripts/diagnostics/health.sh +4 -4
- package/scripts/diagnostics/history-analysis.sh +2 -2
- package/scripts/diagnostics/mcp-doctor.sh +10 -7
- package/scripts/diagnostics/perf.sh +5 -5
- package/scripts/diagnostics/scorecard.sh +4 -4
- package/scripts/diagnostics/security-score.sh +25 -6
- package/scripts/diagnostics/smoke-test.sh +2 -2
- package/scripts/diagnostics/snapshot.sh +2 -2
- package/scripts/diagnostics/verify.sh +4 -4
- package/scripts/diagnostics/version-locks.sh +13 -3
- package/scripts/diagnostics/workstation-attestation.sh +14 -14
- package/scripts/dot/commands/agent.sh +8 -0
- package/scripts/dot/commands/agents.sh +14 -4
- package/scripts/dot/commands/ai.sh +156 -37
- package/scripts/dot/commands/appearance.sh +2 -2
- package/scripts/dot/commands/core.sh +2 -2
- package/scripts/dot/commands/diagnostics.sh +5 -5
- package/scripts/dot/commands/env-emit.sh +202 -0
- package/scripts/dot/commands/fleet.sh +22 -16
- package/scripts/dot/commands/init.sh +4 -4
- package/scripts/dot/commands/lint.sh +9 -4
- package/scripts/dot/commands/manual.sh +3 -3
- package/scripts/dot/commands/meta.sh +12 -6
- package/scripts/dot/commands/patterns.sh +2 -2
- package/scripts/dot/commands/registry.sh +4 -4
- package/scripts/dot/commands/restore.sh +4 -4
- package/scripts/dot/commands/secrets.sh +4 -3
- package/scripts/dot/commands/security.sh +2 -2
- package/scripts/dot/commands/tools.sh +13 -3
- package/scripts/dot/powershell/Dot.psm1 +199 -0
- package/scripts/fonts/install-nerd-fonts.sh +2 -2
- package/scripts/git-hooks/pre-commit-audit.sh +3 -3
- package/scripts/git-hooks/pre-push +13 -0
- package/scripts/ops/ai-setup.sh +1 -1
- package/scripts/ops/bundle.sh +3 -3
- package/scripts/ops/chaos.sh +2 -2
- package/scripts/ops/chezmoi-apply.sh +12 -6
- package/scripts/ops/heal.sh +4 -4
- package/scripts/ops/post-apply-repair.sh +2 -2
- package/scripts/ops/prewarm.sh +2 -2
- package/scripts/ops/release.sh +4 -4
- package/scripts/ops/rollback.sh +4 -4
- package/scripts/ops/setup.sh +2 -2
- package/scripts/qa/check-version-consistency.sh +123 -0
- package/scripts/qa/coverage-baseline.sh +1 -1
- package/scripts/qa/docs-coverage.sh +2 -2
- package/scripts/qa/powershell-contract.ps1 +1 -1
- package/scripts/qa/scorecard-snapshot.sh +127 -0
- package/scripts/security/backup.sh +2 -2
- package/scripts/security/dns-doh.sh +4 -4
- package/scripts/security/encryption-check.sh +4 -4
- package/scripts/security/enforce-policies.sh +2 -2
- package/scripts/security/firewall.sh +4 -4
- package/scripts/security/lock-screen.sh +4 -4
- package/scripts/security/manage-secrets.sh +2 -2
- package/scripts/security/ssh-cert.sh +2 -2
- package/scripts/security/telemetry-kill.sh +4 -4
- package/scripts/security/usb-safety.sh +4 -4
- package/scripts/theme/extract-heic-frames.sh +114 -0
- package/scripts/theme/rebuild-themes.sh +31 -2
- package/scripts/theme/switch.sh +13 -6
- package/scripts/theme/wallpaper-sync.sh +297 -93
- package/scripts/tuning/linux.sh +2 -2
- package/scripts/tuning/macos.sh +2 -2
- package/scripts/version-sync.sh +74 -10
- package/dot_config/.module-manifest.json +0 -69
- package/dot_config/ai/identity.md +0 -23
- package/dot_config/ai/patterns/architect.md +0 -16
- package/dot_config/ai/patterns/hardener.md +0 -15
- package/dot_config/ai/patterns/refactor.md +0 -15
- package/dot_config/aider/aider.conf.yml +0 -32
- package/dot_config/alacritty/alacritty.toml.tmpl +0 -55
- package/dot_config/ansible/ansible.cfg +0 -11
- package/dot_config/atuin/config.toml.tmpl +0 -47
- package/dot_config/bat/config +0 -23
- package/dot_config/brave-flags.conf.tmpl +0 -7
- package/dot_config/btop/btop.conf +0 -16
- package/dot_config/btop/themes/tokyonight.theme +0 -34
- package/dot_config/bun/bunfig.toml.tmpl +0 -33
- package/dot_config/claude/mcp_servers.json +0 -20
- package/dot_config/containers/containers.conf +0 -14
- package/dot_config/curl/dot_curlrc +0 -18
- package/dot_config/dlv/config.yml +0 -39
- package/dot_config/docker/config.json +0 -15
- package/dot_config/dotfiles/agent-card.json +0 -29
- package/dot_config/dotfiles/agent-profiles.json +0 -92
- package/dot_config/dotfiles/boot/README.md +0 -13
- package/dot_config/dotfiles/grub/README.md +0 -13
- package/dot_config/dotfiles/lock/README.md +0 -13
- package/dot_config/dotfiles/mcp-lock.json +0 -33
- package/dot_config/dotfiles/mcp-policy.json +0 -52
- package/dot_config/dotfiles/mcp-registry.json +0 -47
- package/dot_config/dotfiles/model-registry.json +0 -20
- package/dot_config/dotfiles/policy-bundles.json +0 -38
- package/dot_config/dotfiles/prompt-registry.json +0 -16
- package/dot_config/dotfiles/versions.env +0 -18
- package/dot_config/duf/duf.conf +0 -6
- package/dot_config/duti/defaults.duti +0 -5
- package/dot_config/emoji/emoji.txt +0 -34
- package/dot_config/environment.d/50-ssh-agent.conf +0 -2
- package/dot_config/environment.d/90-wayland.conf +0 -19
- package/dot_config/fastfetch/config.jsonc +0 -28
- package/dot_config/firefox/user.js.tmpl +0 -58
- package/dot_config/fish/completions/dot-theme-sync.fish.tmpl +0 -9
- package/dot_config/fish/completions/dot.fish.tmpl +0 -115
- package/dot_config/fish/conf.d/000-perf-cache.fish +0 -56
- package/dot_config/fish/conf.d/aliases.fish.tmpl +0 -77
- package/dot_config/fish/conf.d/direnv.fish +0 -4
- package/dot_config/fish/conf.d/env.fish.tmpl +0 -48
- package/dot_config/fish/conf.d/functions.fish.tmpl +0 -22
- package/dot_config/fish/conf.d/init.fish.tmpl +0 -172
- package/dot_config/fish/conf.d/mise-activate.fish +0 -5
- package/dot_config/fish/config.fish.tmpl +0 -44
- package/dot_config/fish/fish_plugins +0 -1
- package/dot_config/fish/functions/_.fish +0 -3
- package/dot_config/fish/functions/_cached_eval.fish +0 -131
- package/dot_config/fish/functions/_cached_eval_clear.fish +0 -17
- package/dot_config/fish/functions/als.fish +0 -46
- package/dot_config/fish/functions/bg-upgrade.fish +0 -7
- package/dot_config/fish/functions/c.fish +0 -3
- package/dot_config/fish/functions/cat.fish +0 -9
- package/dot_config/fish/functions/d.fish +0 -7
- package/dot_config/fish/functions/dot.fish +0 -34
- package/dot_config/fish/functions/h.fish +0 -3
- package/dot_config/fish/functions/l.fish +0 -7
- package/dot_config/fish/functions/la.fish +0 -7
- package/dot_config/fish/functions/ll.fish +0 -7
- package/dot_config/fish/functions/log_error.fish +0 -13
- package/dot_config/fish/functions/log_info.fish +0 -13
- package/dot_config/fish/functions/lr.fish +0 -7
- package/dot_config/fish/functions/lra.fish +0 -7
- package/dot_config/fish/functions/ls.fish +0 -7
- package/dot_config/fish/functions/lt.fish +0 -7
- package/dot_config/fish/functions/lta.fish +0 -7
- package/dot_config/fish/functions/notify-run.fish +0 -11
- package/dot_config/fish/functions/q.fish +0 -3
- package/dot_config/fish/functions/silent-run.fish +0 -7
- package/dot_config/fish/functions/yy.fish +0 -8
- package/dot_config/flatpak/flatpak.list +0 -4
- package/dot_config/fontconfig/fonts.conf.tmpl +0 -57
- package/dot_config/foot/foot.ini.tmpl +0 -33
- package/dot_config/fuzzel/fuzzel.ini.tmpl +0 -18
- package/dot_config/fzf/fzf.zsh +0 -48
- package/dot_config/gem/gemrc +0 -9
- package/dot_config/gh/config.yml +0 -12
- package/dot_config/ghostty/config.tmpl +0 -165
- package/dot_config/git/allowed_signers.tmpl +0 -18
- package/dot_config/git/attributes +0 -12
- package/dot_config/git/commit-template +0 -10
- package/dot_config/git/hooks/executable_commit-msg +0 -146
- package/dot_config/git/ignore +0 -27
- package/dot_config/gnupg/gpg-agent.conf +0 -11
- package/dot_config/go/golangci.yml +0 -118
- package/dot_config/go/gopls.json +0 -30
- package/dot_config/goose/config.yaml +0 -29
- package/dot_config/gtk-3.0/gtk.css.tmpl +0 -184
- package/dot_config/gtk-3.0/settings.ini.tmpl +0 -27
- package/dot_config/gtk-4.0/gtk.css.tmpl +0 -252
- package/dot_config/gtk-4.0/settings.ini.tmpl +0 -18
- package/dot_config/htop/htoprc +0 -20
- package/dot_config/inputrc +0 -2
- package/dot_config/ipython/profile_default/ipython_config.py +0 -19
- package/dot_config/just/justfile +0 -122
- package/dot_config/k9s/config.yaml +0 -65
- package/dot_config/k9s/skins/catppuccin-mocha.yaml +0 -116
- package/dot_config/kanshi/config.tmpl +0 -22
- package/dot_config/karabiner/karabiner.json +0 -14
- package/dot_config/kitty/kitty.conf.tmpl +0 -53
- package/dot_config/lazydocker/config.yml +0 -186
- package/dot_config/lazygit/config.yml +0 -35
- package/dot_config/mako/config +0 -47
- package/dot_config/mas/masapps.txt +0 -5
- package/dot_config/micro/settings.json +0 -3
- package/dot_config/mimeapps.list +0 -77
- package/dot_config/minikube/config.json +0 -13
- package/dot_config/mise/config.toml +0 -99
- package/dot_config/mongosh/mongoshrc.js +0 -68
- package/dot_config/mpv/input.conf +0 -47
- package/dot_config/mpv/mpv.conf +0 -47
- package/dot_config/mycli/myclirc +0 -67
- package/dot_config/nano/nanorc +0 -28
- package/dot_config/ncdu/config +0 -12
- package/dot_config/niri/config.kdl.tmpl +0 -327
- package/dot_config/nushell/aliases.nu +0 -18
- package/dot_config/nushell/cached_eval.nu +0 -80
- package/dot_config/nushell/completions.nu.tmpl +0 -52
- package/dot_config/nushell/config.nu.tmpl +0 -86
- package/dot_config/nushell/env.nu.tmpl +0 -102
- package/dot_config/nushell/functions.nu.tmpl +0 -17
- package/dot_config/nvim/init.lua +0 -18
- package/dot_config/nvim/lazy-lock.json +0 -58
- package/dot_config/nvim/lua/config/autocmds.lua +0 -107
- package/dot_config/nvim/lua/config/keymaps.lua +0 -92
- package/dot_config/nvim/lua/config/lazy.lua +0 -44
- package/dot_config/nvim/lua/config/options.lua +0 -49
- package/dot_config/nvim/lua/plugins/ai.lua +0 -75
- package/dot_config/nvim/lua/plugins/coding.lua +0 -216
- package/dot_config/nvim/lua/plugins/completion.lua +0 -60
- package/dot_config/nvim/lua/plugins/dap.lua +0 -412
- package/dot_config/nvim/lua/plugins/editor.lua +0 -55
- package/dot_config/nvim/lua/plugins/git.lua +0 -10
- package/dot_config/nvim/lua/plugins/lsp.lua +0 -156
- package/dot_config/nvim/lua/plugins/markdown.lua +0 -18
- package/dot_config/nvim/lua/plugins/rust.lua +0 -34
- package/dot_config/nvim/lua/plugins/sessions.lua +0 -33
- package/dot_config/nvim/lua/plugins/ui.lua +0 -509
- package/dot_config/paru/paru.conf +0 -10
- package/dot_config/pip/pip.conf.tmpl +0 -32
- package/dot_config/powershell/Microsoft.PowerShell_profile.ps1.tmpl +0 -81
- package/dot_config/pueue/pueue.yml +0 -34
- package/dot_config/pypoetry/config.toml +0 -6
- package/dot_config/pyrightconfig.json +0 -5
- package/dot_config/raycast/README.md +0 -13
- package/dot_config/redis/redisclirc +0 -41
- package/dot_config/ripgrep/ripgreprc +0 -21
- package/dot_config/shell/00-core-paths.sh.tmpl +0 -141
- package/dot_config/shell/05-core-safety.sh +0 -48
- package/dot_config/shell/10-secrets.sh +0 -41
- package/dot_config/shell/40-fzf-defaults.sh.tmpl +0 -17
- package/dot_config/shell/40-ls-colors.sh +0 -49
- package/dot_config/shell/50-logic-functions-core.sh.tmpl +0 -11
- package/dot_config/shell/50-logic-functions.sh.tmpl +0 -11
- package/dot_config/shell/51-logic-functions-extra.sh.tmpl +0 -65
- package/dot_config/shell/90-ux-aliases.sh.tmpl +0 -121
- package/dot_config/shell/91-ux-aliases-lazy.sh.tmpl +0 -55
- package/dot_config/shell/Brewfile +0 -207
- package/dot_config/shell/Brewfile.cask +0 -92
- package/dot_config/shell/Brewfile.cli +0 -127
- package/dot_config/shell/README.md +0 -284
- package/dot_config/shell/als_data.txt.tmpl +0 -65
- package/dot_config/shell/custom/auto_ls.zsh +0 -20
- package/dot_config/shell/custom/context_suggest.zsh +0 -68
- package/dot_config/shell/custom/error_analysis.zsh +0 -45
- package/dot_config/sops/dot_sops.yaml +0 -23
- package/dot_config/starship.toml.tmpl +0 -202
- package/dot_config/swaylock/config +0 -43
- package/dot_config/systemd/user/dotfiles-maintenance.service +0 -8
- package/dot_config/systemd/user/dotfiles-maintenance.timer +0 -11
- package/dot_config/systemd/user/pueued.service +0 -12
- package/dot_config/systemd/user/ssh-agent.service +0 -12
- package/dot_config/task/Taskfile.yml +0 -86
- package/dot_config/tflint/tflint.hcl +0 -9
- package/dot_config/tmux/tmux.conf.tmpl +0 -223
- package/dot_config/topgrade.toml.tmpl +0 -54
- package/dot_config/user-dirs.dirs +0 -10
- package/dot_config/vscode/extensions.txt +0 -11
- package/dot_config/vscode/settings.json.tmpl +0 -82
- package/dot_config/waybar/config.jsonc.tmpl +0 -90
- package/dot_config/waybar/style.css.tmpl +0 -211
- package/dot_config/wezterm/wezterm.lua.tmpl +0 -64
- package/dot_config/wget/wgetrc +0 -12
- package/dot_config/xdg-desktop-portal/niri-portals.conf +0 -5
- package/dot_config/yarn/yarnrc.yml +0 -36
- package/dot_config/yazi/keymap.toml +0 -67
- package/dot_config/yazi/theme.toml +0 -102
- package/dot_config/yazi/yazi.toml +0 -40
- package/dot_config/zathura/zathurarc +0 -52
- package/dot_config/zellij/config.kdl.tmpl +0 -79
- package/dot_config/zsh/dot_zprofile +0 -7
- package/dot_config/zsh/dot_zshenv +0 -5
- package/dot_config/zsh/dot_zshrc.tmpl +0 -688
- package/dot_config/zsh/rc.d/00-alias-shims.zsh +0 -99
- package/dot_config/zsh/rc.d/05-ssh-agent.zsh +0 -18
- package/dot_config/zsh/rc.d/10-env.zsh.tmpl +0 -28
- package/dot_config/zsh/rc.d/20-zinit.zsh +0 -65
- package/dot_config/zsh/rc.d/30-options.zsh.tmpl +0 -214
- package/dot_config/zsh/rc.d/40-bell.zsh +0 -20
- package/dot_config/zsh/rc.d/50-login-fortune.zsh +0 -9
- package/dot_config/zsh/rc.d/99-alias-wrapper.zsh +0 -32
- package/dot_local/bin/executable_ai-update +0 -195
- package/dot_local/bin/executable_ai_core +0 -152
- package/dot_local/bin/executable_antigravity +0 -11
- package/dot_local/bin/executable_b64 +0 -84
- package/dot_local/bin/executable_bm +0 -79
- package/dot_local/bin/executable_cb +0 -39
- package/dot_local/bin/executable_dot +0 -636
- package/dot_local/bin/executable_dot-ai +0 -36
- package/dot_local/bin/executable_dot-bootstrap +0 -76
- package/dot_local/bin/executable_dot-launch-or-focus +0 -52
- package/dot_local/bin/executable_dot-load-benchmark +0 -31
- package/dot_local/bin/executable_dot-load-benchmark-pty +0 -77
- package/dot_local/bin/executable_dot-theme-sync +0 -952
- package/dot_local/bin/executable_dot_completion +0 -57
- package/dot_local/bin/executable_dtags +0 -28
- package/dot_local/bin/executable_epoch +0 -67
- package/dot_local/bin/executable_extract +0 -41
- package/dot_local/bin/executable_gbd +0 -52
- package/dot_local/bin/executable_gd +0 -42
- package/dot_local/bin/executable_git-ai-commit +0 -175
- package/dot_local/bin/executable_git-ai-diff +0 -169
- package/dot_local/bin/executable_gl +0 -101
- package/dot_local/bin/executable_hash +0 -161
- package/dot_local/bin/executable_hashsum +0 -160
- package/dot_local/bin/executable_hex +0 -115
- package/dot_local/bin/executable_jsonv +0 -78
- package/dot_local/bin/executable_jwt +0 -94
- package/dot_local/bin/executable_kill-port +0 -75
- package/dot_local/bin/executable_lorem +0 -118
- package/dot_local/bin/executable_mkscript +0 -35
- package/dot_local/bin/executable_monitor +0 -56
- package/dot_local/bin/executable_myip +0 -51
- package/dot_local/bin/executable_notify +0 -24
- package/dot_local/bin/executable_open +0 -38
- package/dot_local/bin/executable_pw +0 -27
- package/dot_local/bin/executable_rec-start +0 -46
- package/dot_local/bin/executable_rec-stop +0 -35
- package/dot_local/bin/executable_regex +0 -132
- package/dot_local/bin/executable_start-niri +0 -8
- package/dot_local/bin/executable_tmux-sessionizer +0 -314
- package/dot_local/bin/executable_tour +0 -177
- package/dot_local/bin/executable_up +0 -23
- package/dot_local/bin/executable_update +0 -142
- package/dot_local/bin/executable_uuid +0 -87
- package/dot_local/bin/executable_win +0 -32
- package/dot_local/bin/executable_yamlv +0 -57
- package/dot_local/share/bash-completion/completions/dot +0 -72
- package/dot_local/share/icons/hicolor/128x128/apps/rousseau.png +0 -0
- package/dot_local/share/icons/hicolor/16x16/apps/rousseau.png +0 -0
- package/dot_local/share/icons/hicolor/24x24/apps/rousseau.png +0 -0
- package/dot_local/share/icons/hicolor/256x256/apps/rousseau.png +0 -0
- package/dot_local/share/icons/hicolor/32x32/apps/rousseau.png +0 -0
- package/dot_local/share/icons/hicolor/48x48/apps/rousseau.png +0 -0
- package/dot_local/share/icons/hicolor/512x512/apps/rousseau.png +0 -0
- package/dot_local/share/icons/hicolor/64x64/apps/rousseau.png +0 -0
- package/dot_local/share/icons/hicolor/96x96/apps/rousseau.png +0 -0
- package/dot_local/share/icons/hicolor/scalable/apps/rousseau.png +0 -0
- package/dot_local/share/man/man1/dot.1 +0 -149
- package/dot_local/share/mise/plugins/kiro-cli/bin/executable_download +0 -64
- package/dot_local/share/mise/plugins/kiro-cli/bin/executable_install +0 -18
- package/dot_local/share/mise/plugins/kiro-cli/bin/executable_list-all +0 -13
- package/dot_local/share/wayland-sessions/niri.desktop.tmpl +0 -6
- package/dot_local/share/zsh/completions/.keep +0 -0
- package/dot_local/share/zsh/completions/_dot +0 -287
- package/scripts/ci/check-dangerous-chmod.sh +0 -19
- package/scripts/ci/check-deps-dev.sh +0 -236
- package/scripts/ci/check-insecure-tls.sh +0 -61
- package/scripts/ci/check-regression-traceability.sh +0 -67
- package/scripts/ci/dot-cli-startup-bench.sh +0 -126
- package/scripts/ci/install-chezmoi-verified.sh +0 -67
- package/scripts/ci/lint-reusable-pins.sh +0 -78
- package/scripts/ci/run-coverage.sh +0 -451
- package/scripts/ci/validate-chezmoidata.sh +0 -25
- package/scripts/ci/validate-ci-config.sh +0 -224
- package/scripts/ci/windows-smoke-test.ps1 +0 -136
- package/scripts/docs/build-manual.sh +0 -883
- package/scripts/docs/check-manual.sh +0 -213
- package/scripts/dot/lib/bento.sh +0 -50
- package/scripts/dot/lib/log.sh +0 -200
- package/scripts/dot/lib/platform.sh +0 -112
- package/scripts/dot/lib/ui.sh +0 -650
- package/scripts/dot/lib/utils.sh +0 -377
- package/scripts/maintenance/check-updates.sh +0 -131
- package/scripts/release/package-policy-bundles.sh +0 -125
|
@@ -1,952 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Copyright (c) 2015-2026 Dotfiles. All rights reserved.
|
|
3
|
-
## dot-theme-sync — Fast theme switching with config regeneration + IPC reload.
|
|
4
|
-
##
|
|
5
|
-
## Sets the active theme in .chezmoidata.toml, regenerates config files via
|
|
6
|
-
## targeted chezmoi apply, then signals running applications to reload.
|
|
7
|
-
##
|
|
8
|
-
## # Usage
|
|
9
|
-
## dot-theme-sync # Regenerate configs + reload running apps
|
|
10
|
-
## dot-theme-sync macos-monterey-light # Set theme + regenerate + reload
|
|
11
|
-
## dot-theme-sync --full # Full chezmoi apply + reload
|
|
12
|
-
## dot-theme-sync --help # Show this help
|
|
13
|
-
##
|
|
14
|
-
## # Supported Applications
|
|
15
|
-
## Ghostty — chezmoi apply + runtime config reload
|
|
16
|
-
## Tmux — chezmoi apply + source-file reload
|
|
17
|
-
## Niri — screen transition
|
|
18
|
-
## Neovim — --remote-expr colorscheme switch (direct IPC, no file needed)
|
|
19
|
-
## Browsers — desktop color-scheme sync + Firefox content preference
|
|
20
|
-
|
|
21
|
-
set -euo pipefail
|
|
22
|
-
|
|
23
|
-
# =============================================================================
|
|
24
|
-
# Constants & Colors
|
|
25
|
-
# =============================================================================
|
|
26
|
-
|
|
27
|
-
readonly RESET=$'\033[0m'
|
|
28
|
-
readonly BOLD=$'\033[1m'
|
|
29
|
-
readonly DIM=$'\033[2m'
|
|
30
|
-
readonly GREEN=$'\033[32m'
|
|
31
|
-
readonly YELLOW=$'\033[33m'
|
|
32
|
-
readonly BLUE=$'\033[34m'
|
|
33
|
-
readonly RED=$'\033[31m'
|
|
34
|
-
readonly CYAN=$'\033[36m'
|
|
35
|
-
|
|
36
|
-
# Platform detection (R10: declare and assign separately)
|
|
37
|
-
PLATFORM="$(uname -s)"
|
|
38
|
-
readonly PLATFORM
|
|
39
|
-
|
|
40
|
-
# Portable sed -i (GNU vs BSD/macOS)
|
|
41
|
-
_sed_i() {
|
|
42
|
-
[[ $# -ge 2 ]] || return 1 # R5: validate args
|
|
43
|
-
if [[ "$PLATFORM" == "Darwin" ]]; then
|
|
44
|
-
sed -i '' "$@"
|
|
45
|
-
else
|
|
46
|
-
sed -i "$@"
|
|
47
|
-
fi
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
# Timing — record start in nanoseconds (fallback to seconds * 1000)
|
|
51
|
-
if date +%s%N &>/dev/null && [[ "$(date +%s%N)" != *N ]]; then
|
|
52
|
-
START_NS=$(date +%s%N)
|
|
53
|
-
_elapsed_ms() { echo $((($(date +%s%N) - START_NS) / 1000000)); }
|
|
54
|
-
else
|
|
55
|
-
START_S=$(date +%s)
|
|
56
|
-
_elapsed_ms() { echo $((($(date +%s) - START_S) * 1000)); }
|
|
57
|
-
fi
|
|
58
|
-
|
|
59
|
-
# =============================================================================
|
|
60
|
-
# Source Directory Resolution
|
|
61
|
-
# =============================================================================
|
|
62
|
-
|
|
63
|
-
resolve_source_dir() {
|
|
64
|
-
if [[ -n "${CHEZMOI_SOURCE_DIR:-}" && -d "$CHEZMOI_SOURCE_DIR" ]]; then
|
|
65
|
-
echo "$CHEZMOI_SOURCE_DIR"
|
|
66
|
-
elif [[ -d "$HOME/.dotfiles" ]]; then
|
|
67
|
-
echo "$HOME/.dotfiles"
|
|
68
|
-
elif [[ -d "$HOME/.local/share/chezmoi" ]]; then
|
|
69
|
-
echo "$HOME/.local/share/chezmoi"
|
|
70
|
-
else
|
|
71
|
-
echo ""
|
|
72
|
-
fi
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
SRC_DIR="$(resolve_source_dir)"
|
|
76
|
-
if [[ -z "$SRC_DIR" ]]; then
|
|
77
|
-
printf '%s\n' "${RED}error${RESET}: dotfiles source directory not found"
|
|
78
|
-
exit 1
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
readonly DATA_FILE="$SRC_DIR/.chezmoidata.toml"
|
|
82
|
-
readonly THEMES_FILE="$SRC_DIR/.chezmoidata/themes.toml"
|
|
83
|
-
readonly CHEZMOI_CFG="${XDG_CONFIG_HOME:-$HOME/.config}/chezmoi/chezmoi.toml"
|
|
84
|
-
|
|
85
|
-
# =============================================================================
|
|
86
|
-
# Output Helpers
|
|
87
|
-
# =============================================================================
|
|
88
|
-
|
|
89
|
-
_ok() { printf ' %s✓%s %-12s %s%s%s\n' "$GREEN" "$RESET" "$1" "$DIM" "$2" "$RESET"; }
|
|
90
|
-
_skip() { printf ' %s·%s %-12s %s%s%s\n' "$DIM" "$RESET" "$1" "$DIM" "$2" "$RESET"; }
|
|
91
|
-
_err() { printf ' %s✗%s %-12s %s%s%s\n' "$RED" "$RESET" "$1" "$DIM" "$2" "$RESET"; }
|
|
92
|
-
_info() { printf ' %s→%s %-12s %s%s%s\n' "$BLUE" "$RESET" "$1" "$DIM" "$2" "$RESET"; }
|
|
93
|
-
|
|
94
|
-
join_lines() {
|
|
95
|
-
local delimiter="$1"
|
|
96
|
-
awk -v d="$delimiter" '
|
|
97
|
-
NF {
|
|
98
|
-
if (seen++) {
|
|
99
|
-
printf "%s", d
|
|
100
|
-
}
|
|
101
|
-
printf "%s", $0
|
|
102
|
-
}
|
|
103
|
-
END {
|
|
104
|
-
if (seen) {
|
|
105
|
-
printf "\n"
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
'
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
# =============================================================================
|
|
112
|
-
# Theme Parsing
|
|
113
|
-
# =============================================================================
|
|
114
|
-
|
|
115
|
-
# Read the current theme from .chezmoidata.toml
|
|
116
|
-
current_theme() {
|
|
117
|
-
if [[ -f "$CHEZMOI_CFG" ]]; then
|
|
118
|
-
local chezmoi_theme
|
|
119
|
-
chezmoi_theme="$(awk -F'"' '/^theme =/ {print $2}' "$CHEZMOI_CFG" | head -n 1)"
|
|
120
|
-
if [[ -n "$chezmoi_theme" ]]; then
|
|
121
|
-
echo "$chezmoi_theme"
|
|
122
|
-
return 0
|
|
123
|
-
fi
|
|
124
|
-
fi
|
|
125
|
-
awk -F'"' '/^theme =/ {print $2}' "$DATA_FILE" | head -n 1
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
# Write a new theme into .chezmoidata.toml AND chezmoi.toml [data] section.
|
|
129
|
-
# Both must be updated: chezmoi.toml [data] takes precedence over .chezmoidata.toml.
|
|
130
|
-
write_theme() {
|
|
131
|
-
local new_theme="${1:-}"
|
|
132
|
-
# R5: validate input
|
|
133
|
-
if [[ -z "$new_theme" ]]; then
|
|
134
|
-
_err "Invalid" "theme name required"
|
|
135
|
-
exit 1
|
|
136
|
-
fi
|
|
137
|
-
if [[ "$new_theme" =~ [^a-zA-Z0-9_-] ]]; then
|
|
138
|
-
_err "Invalid" "theme name: $new_theme"
|
|
139
|
-
exit 1
|
|
140
|
-
fi
|
|
141
|
-
|
|
142
|
-
# Update .chezmoidata.toml (source of truth for templates)
|
|
143
|
-
local tmp_file
|
|
144
|
-
tmp_file="$(umask 077 && mktemp)"
|
|
145
|
-
if grep -q '^theme = ' "$DATA_FILE"; then
|
|
146
|
-
sed "s/^theme = .*/theme = \"$new_theme\"/" "$DATA_FILE" >"$tmp_file"
|
|
147
|
-
else
|
|
148
|
-
cat "$DATA_FILE" >"$tmp_file"
|
|
149
|
-
printf 'theme = "%s"\n' "$new_theme" >>"$tmp_file"
|
|
150
|
-
fi
|
|
151
|
-
# R7: check mv return, restore on failure
|
|
152
|
-
if ! mv "$tmp_file" "$DATA_FILE"; then
|
|
153
|
-
_err "Write" "failed to update $DATA_FILE"
|
|
154
|
-
rm -f "$tmp_file"
|
|
155
|
-
return 1
|
|
156
|
-
fi
|
|
157
|
-
|
|
158
|
-
# Update chezmoi.toml [data] section (overrides .chezmoidata.toml)
|
|
159
|
-
if [[ -f "$CHEZMOI_CFG" ]] && grep -q '^theme = ' "$CHEZMOI_CFG"; then
|
|
160
|
-
tmp_file="$(umask 077 && mktemp)"
|
|
161
|
-
sed "s/^theme = .*/theme = \"$new_theme\"/" "$CHEZMOI_CFG" >"$tmp_file"
|
|
162
|
-
if ! mv "$tmp_file" "$CHEZMOI_CFG"; then
|
|
163
|
-
_err "Write" "failed to update $CHEZMOI_CFG"
|
|
164
|
-
rm -f "$tmp_file"
|
|
165
|
-
fi
|
|
166
|
-
fi
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
sync_theme_state() {
|
|
170
|
-
[[ -f "$DATA_FILE" ]] || return 0
|
|
171
|
-
[[ -f "$CHEZMOI_CFG" ]] || return 0
|
|
172
|
-
grep -q '^theme = ' "$CHEZMOI_CFG" || return 0
|
|
173
|
-
|
|
174
|
-
local data_theme chezmoi_theme
|
|
175
|
-
data_theme="$(awk -F'"' '/^theme =/ {print $2}' "$DATA_FILE" | head -n 1)"
|
|
176
|
-
chezmoi_theme="$(awk -F'"' '/^theme =/ {print $2}' "$CHEZMOI_CFG" | head -n 1)"
|
|
177
|
-
|
|
178
|
-
if [[ -n "$chezmoi_theme" && -n "$data_theme" && "$data_theme" != "$chezmoi_theme" ]]; then
|
|
179
|
-
write_theme "$chezmoi_theme"
|
|
180
|
-
_info "Theme" "synced data files to chezmoi override ($chezmoi_theme)"
|
|
181
|
-
fi
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
# Extract a value from [themes.<name>.app] section in themes.toml
|
|
185
|
-
# Usage: theme_app_value <theme> <key>
|
|
186
|
-
theme_app_value() {
|
|
187
|
-
local theme="$1" key="$2"
|
|
188
|
-
if [[ ! -f "$THEMES_FILE" ]]; then
|
|
189
|
-
return 1
|
|
190
|
-
fi
|
|
191
|
-
# Parse the TOML: find the [themes.<theme>.app] section and extract key
|
|
192
|
-
awk -v section="[themes.${theme}.app]" -v key="$key" '
|
|
193
|
-
BEGIN { in_section = 0 }
|
|
194
|
-
/^\[/ { in_section = ($0 == section) ? 1 : 0; next }
|
|
195
|
-
in_section && $0 ~ "^" key " *= *" {
|
|
196
|
-
gsub(/^[^"]*"/, ""); gsub(/".*$/, ""); print; exit
|
|
197
|
-
}
|
|
198
|
-
' "$THEMES_FILE"
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
# Extract a top-level value from [themes.<name>] section in themes.toml
|
|
202
|
-
# Usage: theme_value <theme> <key>
|
|
203
|
-
theme_value() {
|
|
204
|
-
local theme="$1" key="$2"
|
|
205
|
-
if [[ ! -f "$THEMES_FILE" ]]; then
|
|
206
|
-
return 1
|
|
207
|
-
fi
|
|
208
|
-
awk -v section="[themes.${theme}]" -v key="$key" '
|
|
209
|
-
BEGIN { in_section = 0 }
|
|
210
|
-
/^\[/ { in_section = ($0 == section) ? 1 : 0; next }
|
|
211
|
-
in_section && $0 ~ "^" key " *= *" {
|
|
212
|
-
gsub(/^[^"]*"/, ""); gsub(/".*$/, ""); print; exit
|
|
213
|
-
}
|
|
214
|
-
' "$THEMES_FILE"
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
# =============================================================================
|
|
218
|
-
# Targeted Config Regeneration
|
|
219
|
-
# =============================================================================
|
|
220
|
-
|
|
221
|
-
# Regenerate only theme-dependent config files via chezmoi.
|
|
222
|
-
# Much faster than a full apply — just renders the templates that use $t.
|
|
223
|
-
apply_theme_configs() {
|
|
224
|
-
if ! command -v chezmoi &>/dev/null; then
|
|
225
|
-
_err "Chezmoi" "not installed"
|
|
226
|
-
return 1
|
|
227
|
-
fi
|
|
228
|
-
|
|
229
|
-
local targets=(
|
|
230
|
-
"$HOME/.config/ghostty/config"
|
|
231
|
-
"$HOME/.config/tmux/tmux.conf"
|
|
232
|
-
"$HOME/.config/alacritty/alacritty.toml"
|
|
233
|
-
"$HOME/.config/kitty/kitty.conf"
|
|
234
|
-
"$HOME/.config/wezterm/wezterm.lua"
|
|
235
|
-
"$HOME/.config/firefox/user.js"
|
|
236
|
-
"$HOME/.config/niri/config.kdl"
|
|
237
|
-
"$HOME/.config/gtk-3.0/gtk.css"
|
|
238
|
-
"$HOME/.config/gtk-3.0/settings.ini"
|
|
239
|
-
"$HOME/.config/gtk-4.0/gtk.css"
|
|
240
|
-
"$HOME/.config/gtk-4.0/settings.ini"
|
|
241
|
-
"$HOME/.config/waybar/config.jsonc"
|
|
242
|
-
"$HOME/.config/waybar/style.css"
|
|
243
|
-
)
|
|
244
|
-
|
|
245
|
-
local applied=()
|
|
246
|
-
local target tmp_file
|
|
247
|
-
for target in "${targets[@]}"; do
|
|
248
|
-
[[ -f "$target" ]] || continue
|
|
249
|
-
|
|
250
|
-
if chezmoi apply "$target" 2>/dev/null; then
|
|
251
|
-
applied+=("${target##*/}")
|
|
252
|
-
continue
|
|
253
|
-
fi
|
|
254
|
-
|
|
255
|
-
# Some local Niri setups keep ~/.config/niri/config.kdl outside direct
|
|
256
|
-
# chezmoi management. Fall back to rendering the managed template so theme
|
|
257
|
-
# switches still update active border colors and other palette values.
|
|
258
|
-
if [[ "$target" == "$HOME/.config/niri/config.kdl" ]]; then
|
|
259
|
-
local niri_template="$SRC_DIR/dot_config/niri/config.kdl.tmpl"
|
|
260
|
-
if [[ -f "$niri_template" ]]; then
|
|
261
|
-
tmp_file="$(umask 077 && mktemp)"
|
|
262
|
-
if chezmoi execute-template <"$niri_template" >"$tmp_file" 2>/dev/null && mv "$tmp_file" "$target"; then
|
|
263
|
-
applied+=("${target##*/}")
|
|
264
|
-
continue
|
|
265
|
-
fi
|
|
266
|
-
rm -f "$tmp_file"
|
|
267
|
-
fi
|
|
268
|
-
fi
|
|
269
|
-
done
|
|
270
|
-
|
|
271
|
-
if [[ ${#applied[@]} -gt 0 ]]; then
|
|
272
|
-
_ok "Chezmoi" "regenerated ${#applied[@]} configs"
|
|
273
|
-
else
|
|
274
|
-
_skip "Chezmoi" "no managed configs found"
|
|
275
|
-
fi
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
sync_ghostty_macos_config() {
|
|
279
|
-
[[ "$PLATFORM" == "Darwin" ]] || return 0
|
|
280
|
-
|
|
281
|
-
local xdg_config="$HOME/.config/ghostty/config"
|
|
282
|
-
local macos_config="$HOME/Library/Application Support/com.mitchellh.ghostty/config"
|
|
283
|
-
local macos_dir
|
|
284
|
-
macos_dir="$(dirname "$macos_config")"
|
|
285
|
-
|
|
286
|
-
[[ -f "$xdg_config" ]] || return 0
|
|
287
|
-
[[ -d "$macos_dir" ]] || return 0
|
|
288
|
-
|
|
289
|
-
if [[ -f "$macos_config" ]] && cmp -s "$xdg_config" "$macos_config"; then
|
|
290
|
-
return 0
|
|
291
|
-
fi
|
|
292
|
-
|
|
293
|
-
if cp "$xdg_config" "$macos_config" 2>/dev/null; then
|
|
294
|
-
_ok "Ghostty" "mirrored config to macOS app support"
|
|
295
|
-
else
|
|
296
|
-
_skip "Ghostty" "macOS app support config could not be updated"
|
|
297
|
-
fi
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
# =============================================================================
|
|
301
|
-
# Application Reload Functions
|
|
302
|
-
# =============================================================================
|
|
303
|
-
|
|
304
|
-
# Track results for summary
|
|
305
|
-
declare -a RELOADED=()
|
|
306
|
-
declare -a SKIPPED=()
|
|
307
|
-
|
|
308
|
-
reload_ghostty() {
|
|
309
|
-
# Ghostty GTK exposes reload-config via DBus (org.gtk.Actions).
|
|
310
|
-
# This is the most reliable method — SIGUSR1 isn't caught by all builds,
|
|
311
|
-
# and chezmoi's atomic writes bypass inotify file watches.
|
|
312
|
-
local dbus_name="com.mitchellh.ghostty"
|
|
313
|
-
local dbus_path="/com/mitchellh/ghostty"
|
|
314
|
-
|
|
315
|
-
if busctl --user call "${dbus_name}" "${dbus_path}" \
|
|
316
|
-
org.gtk.Actions Activate "sava{sv}" "reload-config" 0 0 2>/dev/null; then
|
|
317
|
-
RELOADED+=("ghostty")
|
|
318
|
-
_ok "Ghostty" "DBus reload-config"
|
|
319
|
-
return
|
|
320
|
-
fi
|
|
321
|
-
|
|
322
|
-
# Fallback: signal the main process directly.
|
|
323
|
-
# Ghostty's documented runtime reload path maps to SIGUSR2.
|
|
324
|
-
local main_pid
|
|
325
|
-
# -o (oldest) is GNU pgrep only; fall back to first match.
|
|
326
|
-
# On macOS app bundles can expose Ghostty under different process labels,
|
|
327
|
-
# so match both the executable name and bundle path.
|
|
328
|
-
main_pid="$(
|
|
329
|
-
pgrep -x -o ghostty 2>/dev/null ||
|
|
330
|
-
pgrep -x -o Ghostty 2>/dev/null ||
|
|
331
|
-
pgrep -f -o '/Applications/Ghostty\.app/Contents/MacOS/ghostty' 2>/dev/null ||
|
|
332
|
-
pgrep -f -o '/Applications/ghostty\.app/Contents/MacOS/ghostty' 2>/dev/null ||
|
|
333
|
-
pgrep -f -o 'com\.mitchellh\.ghostty' 2>/dev/null ||
|
|
334
|
-
pgrep -x ghostty 2>/dev/null | head -1 ||
|
|
335
|
-
pgrep -x Ghostty 2>/dev/null | head -1 ||
|
|
336
|
-
true
|
|
337
|
-
)"
|
|
338
|
-
if [[ -n "$main_pid" ]]; then
|
|
339
|
-
# macOS: direct signal is the only reliable non-interactive path.
|
|
340
|
-
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
341
|
-
if kill -SIGUSR2 "$main_pid" 2>/dev/null; then
|
|
342
|
-
RELOADED+=("ghostty")
|
|
343
|
-
_ok "Ghostty" "SIGUSR2 → PID $main_pid"
|
|
344
|
-
return
|
|
345
|
-
fi
|
|
346
|
-
fi
|
|
347
|
-
# Linux: verify signal handler before sending
|
|
348
|
-
if [[ -r "/proc/$main_pid/status" ]]; then
|
|
349
|
-
local sigcgt
|
|
350
|
-
sigcgt="$(awk '/^SigCgt:/{print $2}' "/proc/$main_pid/status" 2>/dev/null || true)"
|
|
351
|
-
if [[ -n "$sigcgt" ]] && ((16#$sigcgt & 0x400)); then
|
|
352
|
-
if kill -SIGUSR2 "$main_pid" 2>/dev/null; then
|
|
353
|
-
RELOADED+=("ghostty")
|
|
354
|
-
_ok "Ghostty" "SIGUSR2 → PID $main_pid"
|
|
355
|
-
return
|
|
356
|
-
fi
|
|
357
|
-
fi
|
|
358
|
-
fi
|
|
359
|
-
fi
|
|
360
|
-
|
|
361
|
-
SKIPPED+=("ghostty")
|
|
362
|
-
_skip "Ghostty" "config regenerated but no runtime reload target was found"
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
reload_tmux() {
|
|
366
|
-
if ! command -v tmux &>/dev/null; then
|
|
367
|
-
SKIPPED+=("tmux")
|
|
368
|
-
_skip "Tmux" "not installed"
|
|
369
|
-
return
|
|
370
|
-
fi
|
|
371
|
-
if ! tmux list-sessions &>/dev/null; then
|
|
372
|
-
SKIPPED+=("tmux")
|
|
373
|
-
_skip "Tmux" "no active sessions"
|
|
374
|
-
return
|
|
375
|
-
fi
|
|
376
|
-
local conf="$HOME/.config/tmux/tmux.conf"
|
|
377
|
-
if [[ ! -f "$conf" ]]; then
|
|
378
|
-
conf="$HOME/.tmux.conf"
|
|
379
|
-
fi
|
|
380
|
-
if [[ ! -f "$conf" ]]; then
|
|
381
|
-
SKIPPED+=("tmux")
|
|
382
|
-
_skip "Tmux" "config not found"
|
|
383
|
-
return
|
|
384
|
-
fi
|
|
385
|
-
# source-file may return non-zero if plugins (TPM) aren't installed,
|
|
386
|
-
# but the theme/colors still reload successfully — treat as success.
|
|
387
|
-
local out
|
|
388
|
-
out="$(tmux source-file "$conf" 2>&1)" || true
|
|
389
|
-
RELOADED+=("tmux")
|
|
390
|
-
if [[ -n "$out" ]]; then
|
|
391
|
-
_ok "Tmux" "source-file (warnings: ${out##*: })"
|
|
392
|
-
else
|
|
393
|
-
_ok "Tmux" "source-file $conf"
|
|
394
|
-
fi
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
reload_niri() {
|
|
398
|
-
if ! command -v niri &>/dev/null; then
|
|
399
|
-
SKIPPED+=("niri")
|
|
400
|
-
_skip "Niri" "not installed"
|
|
401
|
-
return
|
|
402
|
-
fi
|
|
403
|
-
if ! pgrep -x niri &>/dev/null; then
|
|
404
|
-
SKIPPED+=("niri")
|
|
405
|
-
_skip "Niri" "not running"
|
|
406
|
-
return
|
|
407
|
-
fi
|
|
408
|
-
# Reload config (picks up new colors) then trigger visual transition
|
|
409
|
-
niri msg action load-config-file 2>/dev/null || true
|
|
410
|
-
if niri msg action do-screen-transition 2>/dev/null; then
|
|
411
|
-
RELOADED+=("niri")
|
|
412
|
-
_ok "Niri" "config reloaded + transition"
|
|
413
|
-
else
|
|
414
|
-
SKIPPED+=("niri")
|
|
415
|
-
_skip "Niri" "IPC unavailable"
|
|
416
|
-
fi
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
reload_desktop() {
|
|
420
|
-
local theme="$1"
|
|
421
|
-
local mode gtk_theme gtk_icon color_scheme
|
|
422
|
-
mode="$(theme_value "$theme" "mode" 2>/dev/null || echo "dark")"
|
|
423
|
-
gtk_theme="$(theme_app_value "$theme" "gtk_theme" 2>/dev/null || true)"
|
|
424
|
-
gtk_icon="$(theme_app_value "$theme" "gtk_icon" 2>/dev/null || true)"
|
|
425
|
-
|
|
426
|
-
# macOS desktop integration: apply dark/light appearance and accent color.
|
|
427
|
-
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
428
|
-
if ! command -v osascript &>/dev/null; then
|
|
429
|
-
SKIPPED+=("desktop")
|
|
430
|
-
_skip "Desktop" "osascript not available"
|
|
431
|
-
return
|
|
432
|
-
fi
|
|
433
|
-
|
|
434
|
-
local dark_bool
|
|
435
|
-
local accent="-1" # Graphite fallback
|
|
436
|
-
local changed=0
|
|
437
|
-
|
|
438
|
-
if [[ "$mode" == "light" ]]; then
|
|
439
|
-
dark_bool="false"
|
|
440
|
-
color_scheme="light"
|
|
441
|
-
else
|
|
442
|
-
dark_bool="true"
|
|
443
|
-
color_scheme="dark"
|
|
444
|
-
fi
|
|
445
|
-
|
|
446
|
-
# Read macos_accent from themes.toml (set by extract-theme.py from wallpaper hue)
|
|
447
|
-
local themes_file="$SRC_DIR/.chezmoidata/themes.toml"
|
|
448
|
-
if [[ -f "$themes_file" ]]; then
|
|
449
|
-
local toml_accent
|
|
450
|
-
toml_accent="$(awk -v n="$theme" '
|
|
451
|
-
$0 == "[themes." n "]" { found=1; next }
|
|
452
|
-
/^\[/ { found=0 }
|
|
453
|
-
found && /^macos_accent/ { sub(/.*= */, ""); print; exit }
|
|
454
|
-
' "$themes_file")"
|
|
455
|
-
if [[ -n "$toml_accent" ]]; then
|
|
456
|
-
accent="$toml_accent"
|
|
457
|
-
fi
|
|
458
|
-
fi
|
|
459
|
-
|
|
460
|
-
if osascript -e "tell application \"System Events\" to tell appearance preferences to set dark mode to $dark_bool" >/dev/null 2>&1; then
|
|
461
|
-
changed=1
|
|
462
|
-
fi
|
|
463
|
-
|
|
464
|
-
# Accent/highlight for consistency with selected theme family.
|
|
465
|
-
# Map accent to matching highlight color (RGB + name)
|
|
466
|
-
local highlight_color
|
|
467
|
-
case "$accent" in
|
|
468
|
-
-1) highlight_color="0.847059 0.847059 0.862745 Graphite" ;;
|
|
469
|
-
0) highlight_color="0.968627 0.831373 0.792157 Red" ;;
|
|
470
|
-
1) highlight_color="0.968627 0.890196 0.745098 Orange" ;;
|
|
471
|
-
2) highlight_color="1.000000 0.937255 0.690196 Yellow" ;;
|
|
472
|
-
3) highlight_color="0.752941 0.964706 0.678431 Green" ;;
|
|
473
|
-
4) highlight_color="0.698039 0.843137 1.000000 Blue" ;;
|
|
474
|
-
5) highlight_color="0.968627 0.831373 1.000000 Purple" ;;
|
|
475
|
-
6) highlight_color="1.000000 0.749020 0.823529 Pink" ;;
|
|
476
|
-
*) highlight_color="0.698039 0.843137 1.000000 Blue" ;;
|
|
477
|
-
esac
|
|
478
|
-
|
|
479
|
-
if defaults write -g AppleAccentColor -int "$accent" >/dev/null 2>&1 &&
|
|
480
|
-
defaults write -g AppleHighlightColor -string "$highlight_color" >/dev/null 2>&1; then
|
|
481
|
-
changed=1
|
|
482
|
-
fi
|
|
483
|
-
|
|
484
|
-
if [[ $changed -gt 0 ]]; then
|
|
485
|
-
# Force running apps to pick up the new accent/highlight preferences
|
|
486
|
-
killall -HUP cfprefsd 2>/dev/null || true
|
|
487
|
-
killall SystemUIServer 2>/dev/null || true
|
|
488
|
-
killall Dock 2>/dev/null || true
|
|
489
|
-
killall "System Settings" 2>/dev/null || true
|
|
490
|
-
RELOADED+=("desktop")
|
|
491
|
-
_ok "Desktop" "macOS ${color_scheme}, accent ${accent}"
|
|
492
|
-
else
|
|
493
|
-
SKIPPED+=("desktop")
|
|
494
|
-
_skip "Desktop" "macOS appearance unchanged"
|
|
495
|
-
fi
|
|
496
|
-
return
|
|
497
|
-
fi
|
|
498
|
-
|
|
499
|
-
if ! command -v gsettings &>/dev/null; then
|
|
500
|
-
SKIPPED+=("desktop")
|
|
501
|
-
_skip "Desktop" "gsettings not available"
|
|
502
|
-
return
|
|
503
|
-
fi
|
|
504
|
-
|
|
505
|
-
if [[ "$mode" == "light" ]]; then
|
|
506
|
-
color_scheme="prefer-light"
|
|
507
|
-
else
|
|
508
|
-
color_scheme="prefer-dark"
|
|
509
|
-
fi
|
|
510
|
-
|
|
511
|
-
local changed=0
|
|
512
|
-
|
|
513
|
-
# Set dark/light mode preference
|
|
514
|
-
if gsettings set org.gnome.desktop.interface color-scheme "$color_scheme" 2>/dev/null; then
|
|
515
|
-
changed=1
|
|
516
|
-
fi
|
|
517
|
-
|
|
518
|
-
# Set GTK theme
|
|
519
|
-
if [[ -n "$gtk_theme" ]]; then
|
|
520
|
-
gsettings set org.gnome.desktop.interface gtk-theme "$gtk_theme" 2>/dev/null && changed=1
|
|
521
|
-
fi
|
|
522
|
-
|
|
523
|
-
# Set icon theme
|
|
524
|
-
if [[ -n "$gtk_icon" ]]; then
|
|
525
|
-
gsettings set org.gnome.desktop.interface icon-theme "$gtk_icon" 2>/dev/null && changed=1
|
|
526
|
-
fi
|
|
527
|
-
|
|
528
|
-
# DMS (Dank Material Shell) — prefer dynamic theme colors generated from the
|
|
529
|
-
# current wallpaper instead of forcing a stock palette in settings.
|
|
530
|
-
if command -v dms &>/dev/null; then
|
|
531
|
-
# DMS theme switch: write to settings.json in-place.
|
|
532
|
-
# DMS FileView watches the file and triggers onLoaded → applyStoredTheme.
|
|
533
|
-
# NOTE: mv (atomic write) breaks the inotify watch — must use sed -i.
|
|
534
|
-
local dms_settings="${XDG_CONFIG_HOME:-$HOME/.config}/DankMaterialShell/settings.json"
|
|
535
|
-
if [[ -f "$dms_settings" ]]; then
|
|
536
|
-
_sed_i \
|
|
537
|
-
-e 's/"currentThemeName": *"[^"]*"/"currentThemeName": "dynamic"/' \
|
|
538
|
-
-e 's/"currentThemeCategory": *"[^"]*"/"currentThemeCategory": "dynamic"/' \
|
|
539
|
-
"$dms_settings"
|
|
540
|
-
changed=1
|
|
541
|
-
fi
|
|
542
|
-
|
|
543
|
-
# Keep DMS theme mode in automatic mode across restarts. The shell's
|
|
544
|
-
# session state owns light/dark automation, so avoid forcing manual mode
|
|
545
|
-
# here via `dms ipc theme light|dark`.
|
|
546
|
-
local dms_session="${XDG_STATE_HOME:-$HOME/.local/state}/DankMaterialShell/session.json"
|
|
547
|
-
if [[ -f "$dms_session" ]]; then
|
|
548
|
-
_sed_i \
|
|
549
|
-
-e 's/"themeModeAutoEnabled": *false/"themeModeAutoEnabled": true/' \
|
|
550
|
-
-e 's/"themeModeAutoMode": *"[^"]*"/"themeModeAutoMode": "time"/' \
|
|
551
|
-
"$dms_session"
|
|
552
|
-
fi
|
|
553
|
-
fi
|
|
554
|
-
|
|
555
|
-
if [[ $changed -gt 0 ]]; then
|
|
556
|
-
RELOADED+=("desktop")
|
|
557
|
-
_ok "Desktop" "$color_scheme, ${gtk_theme:-default}"
|
|
558
|
-
else
|
|
559
|
-
SKIPPED+=("desktop")
|
|
560
|
-
_skip "Desktop" "gsettings failed"
|
|
561
|
-
fi
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
firefox_profile_roots() {
|
|
565
|
-
if [[ "$PLATFORM" == "Darwin" ]]; then
|
|
566
|
-
printf '%s\n' "$HOME/Library/Application Support/Firefox/Profiles"
|
|
567
|
-
else
|
|
568
|
-
printf '%s\n' "$HOME/.mozilla/firefox"
|
|
569
|
-
fi
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
reload_browsers() {
|
|
573
|
-
local theme="$1"
|
|
574
|
-
local mode browser_scope
|
|
575
|
-
mode="$(theme_value "$theme" "mode" 2>/dev/null || echo "dark")"
|
|
576
|
-
|
|
577
|
-
if [[ "$PLATFORM" == "Darwin" ]]; then
|
|
578
|
-
browser_scope="macOS appearance"
|
|
579
|
-
else
|
|
580
|
-
browser_scope="desktop color-scheme"
|
|
581
|
-
fi
|
|
582
|
-
|
|
583
|
-
local coordinated=()
|
|
584
|
-
local managed_firefox="${XDG_CONFIG_HOME:-$HOME/.config}/firefox/user.js"
|
|
585
|
-
local firefox_roots=()
|
|
586
|
-
local firefox_profiles=()
|
|
587
|
-
local root profile
|
|
588
|
-
|
|
589
|
-
if [[ "$PLATFORM" == "Darwin" ]]; then
|
|
590
|
-
[[ -d "/Applications/Safari.app" ]] && coordinated+=("Safari")
|
|
591
|
-
[[ -d "/Applications/Google Chrome.app" ]] && coordinated+=("Chrome")
|
|
592
|
-
[[ -d "/Applications/Microsoft Edge.app" ]] && coordinated+=("Edge")
|
|
593
|
-
else
|
|
594
|
-
command -v google-chrome &>/dev/null && coordinated+=("Chrome")
|
|
595
|
-
command -v google-chrome-stable &>/dev/null && coordinated+=("Chrome")
|
|
596
|
-
command -v chromium &>/dev/null && coordinated+=("Chromium")
|
|
597
|
-
command -v chromium-browser &>/dev/null && coordinated+=("Chromium")
|
|
598
|
-
command -v microsoft-edge &>/dev/null && coordinated+=("Edge")
|
|
599
|
-
command -v microsoft-edge-stable &>/dev/null && coordinated+=("Edge")
|
|
600
|
-
fi
|
|
601
|
-
|
|
602
|
-
while IFS= read -r root; do
|
|
603
|
-
[[ -d "$root" ]] && firefox_roots+=("$root")
|
|
604
|
-
done < <(firefox_profile_roots)
|
|
605
|
-
|
|
606
|
-
for root in "${firefox_roots[@]}"; do
|
|
607
|
-
for profile in "$root"/*; do
|
|
608
|
-
[[ -d "$profile" ]] || continue
|
|
609
|
-
firefox_profiles+=("$profile")
|
|
610
|
-
done
|
|
611
|
-
done
|
|
612
|
-
|
|
613
|
-
local synced_firefox_profiles=0
|
|
614
|
-
if [[ -f "$managed_firefox" ]]; then
|
|
615
|
-
for profile in "${firefox_profiles[@]}"; do
|
|
616
|
-
if [[ -f "$profile/user.js" ]] && cmp -s "$managed_firefox" "$profile/user.js"; then
|
|
617
|
-
synced_firefox_profiles=$((synced_firefox_profiles + 1))
|
|
618
|
-
fi
|
|
619
|
-
done
|
|
620
|
-
fi
|
|
621
|
-
|
|
622
|
-
local summary_parts=()
|
|
623
|
-
if [[ ${#coordinated[@]} -gt 0 ]]; then
|
|
624
|
-
local native
|
|
625
|
-
native="$(
|
|
626
|
-
printf '%s\n' "${coordinated[@]}" | awk '!seen[$0]++' | join_lines ", "
|
|
627
|
-
)"
|
|
628
|
-
summary_parts+=("${native} follow ${browser_scope}")
|
|
629
|
-
fi
|
|
630
|
-
|
|
631
|
-
if [[ -f "$managed_firefox" ]]; then
|
|
632
|
-
if [[ $synced_firefox_profiles -gt 0 ]]; then
|
|
633
|
-
summary_parts+=("Firefox content mode synced for ${synced_firefox_profiles} profile(s)")
|
|
634
|
-
elif [[ ${#firefox_profiles[@]} -gt 0 ]]; then
|
|
635
|
-
summary_parts+=("Firefox content mode ready; link ~/.config/firefox/user.js into a profile to enforce it")
|
|
636
|
-
else
|
|
637
|
-
summary_parts+=("Firefox content mode regenerated")
|
|
638
|
-
fi
|
|
639
|
-
fi
|
|
640
|
-
|
|
641
|
-
if [[ ${#summary_parts[@]} -eq 0 ]]; then
|
|
642
|
-
SKIPPED+=("browsers")
|
|
643
|
-
_skip "Browsers" "no supported browsers detected"
|
|
644
|
-
return
|
|
645
|
-
fi
|
|
646
|
-
|
|
647
|
-
local detail
|
|
648
|
-
detail="$(
|
|
649
|
-
printf '%s\n' "${summary_parts[@]}" | join_lines "; "
|
|
650
|
-
)"
|
|
651
|
-
RELOADED+=("browsers")
|
|
652
|
-
_ok "Browsers" "${mode} via ${detail}"
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
reload_nvim() {
|
|
656
|
-
local theme="$1"
|
|
657
|
-
local nvim_colorscheme nvim_style
|
|
658
|
-
nvim_colorscheme="$(theme_app_value "$theme" "nvim" 2>/dev/null || true)"
|
|
659
|
-
nvim_style="$(theme_app_value "$theme" "nvim_style" 2>/dev/null || true)"
|
|
660
|
-
|
|
661
|
-
if [[ -z "$nvim_colorscheme" ]]; then
|
|
662
|
-
SKIPPED+=("nvim")
|
|
663
|
-
_skip "Neovim" "no nvim colorscheme for theme '$theme'"
|
|
664
|
-
return
|
|
665
|
-
fi
|
|
666
|
-
|
|
667
|
-
# Build the Lua expression for runtime colorscheme switching.
|
|
668
|
-
# This mirrors the logic in dot_config/nvim/lua/plugins/ui.lua.
|
|
669
|
-
local lua_cmd
|
|
670
|
-
case "$nvim_colorscheme" in
|
|
671
|
-
catppuccin)
|
|
672
|
-
local flavour="${nvim_style:-mocha}"
|
|
673
|
-
lua_cmd="require('catppuccin').setup({flavour='${flavour}'}) vim.cmd.colorscheme('catppuccin')"
|
|
674
|
-
;;
|
|
675
|
-
tokyonight-*)
|
|
676
|
-
lua_cmd="require('tokyonight').setup({style='${nvim_style:-night}'}) vim.cmd.colorscheme('${nvim_colorscheme}')"
|
|
677
|
-
;;
|
|
678
|
-
kanagawa)
|
|
679
|
-
local variant="${nvim_style:-wave}"
|
|
680
|
-
lua_cmd="require('kanagawa').setup({theme='${variant}'}) vim.cmd.colorscheme('kanagawa')"
|
|
681
|
-
;;
|
|
682
|
-
gruvbox)
|
|
683
|
-
local bg="dark"
|
|
684
|
-
[[ "$nvim_style" == "light" ]] && bg="light"
|
|
685
|
-
lua_cmd="vim.o.background='${bg}' require('gruvbox').setup({contrast='hard'}) vim.cmd.colorscheme('gruvbox')"
|
|
686
|
-
;;
|
|
687
|
-
everforest)
|
|
688
|
-
local bg="dark"
|
|
689
|
-
[[ "$nvim_style" == "light" ]] && bg="light"
|
|
690
|
-
lua_cmd="vim.o.background='${bg}' vim.cmd.colorscheme('everforest')"
|
|
691
|
-
;;
|
|
692
|
-
solarized)
|
|
693
|
-
local bg="dark"
|
|
694
|
-
[[ "$nvim_style" == "light" ]] && bg="light"
|
|
695
|
-
lua_cmd="vim.o.background='${bg}' require('solarized').setup({}) vim.cmd.colorscheme('solarized')"
|
|
696
|
-
;;
|
|
697
|
-
onedark)
|
|
698
|
-
local style="dark"
|
|
699
|
-
[[ "$nvim_style" == "light" ]] && style="light"
|
|
700
|
-
lua_cmd="require('onedark').setup({style='${style}'}) vim.cmd.colorscheme('onedark')"
|
|
701
|
-
;;
|
|
702
|
-
rose-pine*)
|
|
703
|
-
lua_cmd="vim.cmd.colorscheme('${nvim_colorscheme}')"
|
|
704
|
-
;;
|
|
705
|
-
dracula)
|
|
706
|
-
lua_cmd="vim.cmd.colorscheme('dracula')"
|
|
707
|
-
;;
|
|
708
|
-
nord)
|
|
709
|
-
lua_cmd="require('nord').set()"
|
|
710
|
-
;;
|
|
711
|
-
*)
|
|
712
|
-
lua_cmd="vim.cmd.colorscheme('${nvim_colorscheme}')"
|
|
713
|
-
;;
|
|
714
|
-
esac
|
|
715
|
-
|
|
716
|
-
# Find all running nvim server sockets.
|
|
717
|
-
# Neovim versions use different socket paths:
|
|
718
|
-
# 0.9-: /tmp/nvimXXXXXX/0 (random suffix, no dot)
|
|
719
|
-
# 0.10+: $XDG_RUNTIME_DIR/nvim.PID.0
|
|
720
|
-
local sockets=()
|
|
721
|
-
local runtime_dir="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
|
|
722
|
-
|
|
723
|
-
# Collect candidate sockets from known locations
|
|
724
|
-
local sock
|
|
725
|
-
for sock in /tmp/nvim*/0; do
|
|
726
|
-
[[ -S "$sock" ]] && sockets+=("$sock")
|
|
727
|
-
done
|
|
728
|
-
for sock in /run/user/*/nvim.*.0; do
|
|
729
|
-
[[ -S "$sock" ]] && sockets+=("$sock")
|
|
730
|
-
done
|
|
731
|
-
if [[ -d "$runtime_dir" ]]; then
|
|
732
|
-
for sock in "$runtime_dir"/nvim.*.0; do
|
|
733
|
-
[[ -S "$sock" ]] && sockets+=("$sock")
|
|
734
|
-
done
|
|
735
|
-
fi
|
|
736
|
-
|
|
737
|
-
# Deduplicate sockets
|
|
738
|
-
if [[ ${#sockets[@]} -gt 0 ]]; then
|
|
739
|
-
local -A seen=()
|
|
740
|
-
local unique_sockets=()
|
|
741
|
-
local s
|
|
742
|
-
for s in "${sockets[@]}"; do
|
|
743
|
-
if [[ -z "${seen[$s]:-}" ]]; then
|
|
744
|
-
seen[$s]=1
|
|
745
|
-
unique_sockets+=("$s")
|
|
746
|
-
fi
|
|
747
|
-
done
|
|
748
|
-
sockets=("${unique_sockets[@]}")
|
|
749
|
-
fi
|
|
750
|
-
|
|
751
|
-
if [[ ${#sockets[@]} -eq 0 ]]; then
|
|
752
|
-
SKIPPED+=("nvim")
|
|
753
|
-
_skip "Neovim" "no server sockets found"
|
|
754
|
-
return
|
|
755
|
-
fi
|
|
756
|
-
|
|
757
|
-
local count=0
|
|
758
|
-
local failed=0
|
|
759
|
-
for sock in "${sockets[@]}"; do
|
|
760
|
-
if nvim --server "$sock" --remote-expr "luaeval(\"(function() ${lua_cmd} return 'ok' end)()\")" &>/dev/null; then
|
|
761
|
-
count=$((count + 1))
|
|
762
|
-
else
|
|
763
|
-
failed=$((failed + 1))
|
|
764
|
-
fi
|
|
765
|
-
done
|
|
766
|
-
|
|
767
|
-
if [[ $count -gt 0 ]]; then
|
|
768
|
-
RELOADED+=("nvim")
|
|
769
|
-
_ok "Neovim" "${nvim_colorscheme} → ${count} instance(s)${failed:+, ${failed} failed}"
|
|
770
|
-
else
|
|
771
|
-
_err "Neovim" "all ${failed} instance(s) failed"
|
|
772
|
-
fi
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
reload_wallpaper() {
|
|
776
|
-
local script="$SRC_DIR/scripts/theme/wallpaper-sync.sh"
|
|
777
|
-
|
|
778
|
-
if [[ ! -x "$script" ]] && [[ ! -f "$script" ]]; then
|
|
779
|
-
SKIPPED+=("wallpaper")
|
|
780
|
-
_skip "Wallpaper" "sync script not found"
|
|
781
|
-
return
|
|
782
|
-
fi
|
|
783
|
-
|
|
784
|
-
local wp_output
|
|
785
|
-
wp_output="$(bash "$script" 2>&1)" || true
|
|
786
|
-
|
|
787
|
-
if echo "$wp_output" | grep -q "Applied via\|Applied wallpaper\|matched"; then
|
|
788
|
-
RELOADED+=("wallpaper")
|
|
789
|
-
_ok "Wallpaper" "matched active theme"
|
|
790
|
-
elif echo "$wp_output" | grep -q "skipping\|not found\|no "; then
|
|
791
|
-
SKIPPED+=("wallpaper")
|
|
792
|
-
_skip "Wallpaper" "no custom wallpaper (add to ~/Pictures/Wallpapers/)"
|
|
793
|
-
else
|
|
794
|
-
SKIPPED+=("wallpaper")
|
|
795
|
-
_skip "Wallpaper" "sync unavailable"
|
|
796
|
-
fi
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
reload_dms() {
|
|
800
|
-
if [[ "$PLATFORM" != "Linux" ]]; then
|
|
801
|
-
SKIPPED+=("dms")
|
|
802
|
-
_skip "DMS" "not Linux"
|
|
803
|
-
return
|
|
804
|
-
fi
|
|
805
|
-
|
|
806
|
-
if ! command -v systemctl &>/dev/null; then
|
|
807
|
-
SKIPPED+=("dms")
|
|
808
|
-
_skip "DMS" "systemctl not available"
|
|
809
|
-
return
|
|
810
|
-
fi
|
|
811
|
-
|
|
812
|
-
if ! systemctl --user is-active --quiet dms.service; then
|
|
813
|
-
SKIPPED+=("dms")
|
|
814
|
-
_skip "DMS" "service not active"
|
|
815
|
-
return
|
|
816
|
-
fi
|
|
817
|
-
|
|
818
|
-
if systemctl --user restart dms.service >/dev/null 2>&1; then
|
|
819
|
-
RELOADED+=("dms")
|
|
820
|
-
_ok "DMS" "service restarted"
|
|
821
|
-
else
|
|
822
|
-
SKIPPED+=("dms")
|
|
823
|
-
_skip "DMS" "restart failed"
|
|
824
|
-
fi
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
# =============================================================================
|
|
828
|
-
# Usage
|
|
829
|
-
# =============================================================================
|
|
830
|
-
|
|
831
|
-
usage() {
|
|
832
|
-
printf '%s\n' "${BOLD}dot-theme-sync${RESET} — fast theme switching"
|
|
833
|
-
echo ""
|
|
834
|
-
printf '%s\n' "${BOLD}USAGE${RESET}"
|
|
835
|
-
printf ' %s\n' "dot-theme-sync Regenerate configs + reload running apps"
|
|
836
|
-
printf ' %s\n' "dot-theme-sync <theme-name> Set theme + regenerate + reload"
|
|
837
|
-
printf ' %s\n' "dot-theme-sync --full Full chezmoi apply + reload"
|
|
838
|
-
printf ' %s\n' "dot-theme-sync --help Show this help"
|
|
839
|
-
echo ""
|
|
840
|
-
printf '%s\n' "${BOLD}APPLICATIONS${RESET}"
|
|
841
|
-
printf ' %s\n' "Ghostty chezmoi apply + runtime reload"
|
|
842
|
-
printf ' %s\n' "Tmux chezmoi apply + source-file reload"
|
|
843
|
-
printf ' %s\n' "Niri screen transition"
|
|
844
|
-
printf ' %s\n' "Browsers desktop sync + Firefox content preference"
|
|
845
|
-
printf ' %s\n' "Neovim remote-expr colorscheme switch (direct IPC)"
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
# =============================================================================
|
|
849
|
-
# Main
|
|
850
|
-
# =============================================================================
|
|
851
|
-
|
|
852
|
-
main() {
|
|
853
|
-
local do_full=false
|
|
854
|
-
local new_theme=""
|
|
855
|
-
|
|
856
|
-
# Parse arguments
|
|
857
|
-
case "${1:-}" in
|
|
858
|
-
--help | -h)
|
|
859
|
-
usage
|
|
860
|
-
exit 0
|
|
861
|
-
;;
|
|
862
|
-
--full)
|
|
863
|
-
do_full=true
|
|
864
|
-
;;
|
|
865
|
-
"")
|
|
866
|
-
# No arguments: use current theme
|
|
867
|
-
;;
|
|
868
|
-
-*)
|
|
869
|
-
printf '%s\n' "${RED}error${RESET}: unknown flag '$1'"
|
|
870
|
-
usage
|
|
871
|
-
exit 1
|
|
872
|
-
;;
|
|
873
|
-
*)
|
|
874
|
-
new_theme="$1"
|
|
875
|
-
;;
|
|
876
|
-
esac
|
|
877
|
-
|
|
878
|
-
# Header
|
|
879
|
-
printf '%s\n' "${BOLD}${CYAN}dot-theme-sync${RESET}"
|
|
880
|
-
echo ""
|
|
881
|
-
|
|
882
|
-
# If a new theme was specified, write it to the data file
|
|
883
|
-
if [[ -n "$new_theme" ]]; then
|
|
884
|
-
write_theme "$new_theme"
|
|
885
|
-
_info "Theme" "set to $new_theme"
|
|
886
|
-
else
|
|
887
|
-
sync_theme_state
|
|
888
|
-
fi
|
|
889
|
-
|
|
890
|
-
# Read the active theme
|
|
891
|
-
local theme
|
|
892
|
-
theme="$(current_theme)"
|
|
893
|
-
if [[ -z "$theme" ]]; then
|
|
894
|
-
_err "Theme" "no theme found in $DATA_FILE"
|
|
895
|
-
exit 1
|
|
896
|
-
fi
|
|
897
|
-
_info "Theme" "$theme"
|
|
898
|
-
echo ""
|
|
899
|
-
|
|
900
|
-
# Regenerate config files with new theme data
|
|
901
|
-
if [[ "$do_full" == true ]]; then
|
|
902
|
-
_info "Chezmoi" "full apply..."
|
|
903
|
-
if chezmoi apply --force 2>/dev/null || chezmoi apply; then
|
|
904
|
-
_ok "Chezmoi" "full apply completed"
|
|
905
|
-
else
|
|
906
|
-
_err "Chezmoi" "apply failed"
|
|
907
|
-
fi
|
|
908
|
-
else
|
|
909
|
-
apply_theme_configs
|
|
910
|
-
fi
|
|
911
|
-
sync_ghostty_macos_config
|
|
912
|
-
echo ""
|
|
913
|
-
|
|
914
|
-
# Signal running applications to reload
|
|
915
|
-
reload_ghostty
|
|
916
|
-
reload_tmux
|
|
917
|
-
reload_niri
|
|
918
|
-
reload_desktop "$theme"
|
|
919
|
-
reload_wallpaper
|
|
920
|
-
reload_dms
|
|
921
|
-
reload_browsers "$theme"
|
|
922
|
-
reload_nvim "$theme"
|
|
923
|
-
|
|
924
|
-
# Summary
|
|
925
|
-
echo ""
|
|
926
|
-
local elapsed
|
|
927
|
-
elapsed="$(_elapsed_ms)"
|
|
928
|
-
local reloaded_count=${#RELOADED[@]}
|
|
929
|
-
local skipped_count=${#SKIPPED[@]}
|
|
930
|
-
|
|
931
|
-
if [[ $reloaded_count -gt 0 ]]; then
|
|
932
|
-
local apps
|
|
933
|
-
apps="$(
|
|
934
|
-
IFS=', '
|
|
935
|
-
echo "${RELOADED[*]}"
|
|
936
|
-
)"
|
|
937
|
-
printf '%s\n' "${GREEN}${BOLD}Done${RESET} ${DIM}in ${elapsed}ms${RESET} — reloaded ${BOLD}${apps}${RESET}"
|
|
938
|
-
else
|
|
939
|
-
printf '%s\n' "${YELLOW}${BOLD}Done${RESET} ${DIM}in ${elapsed}ms${RESET} — no running apps to reload"
|
|
940
|
-
fi
|
|
941
|
-
|
|
942
|
-
if [[ $skipped_count -gt 0 ]]; then
|
|
943
|
-
local skips
|
|
944
|
-
skips="$(
|
|
945
|
-
IFS=', '
|
|
946
|
-
echo "${SKIPPED[*]}"
|
|
947
|
-
)"
|
|
948
|
-
printf '%s\n' "${DIM}Skipped: ${skips}${RESET}"
|
|
949
|
-
fi
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
main "$@"
|