@sebastienrousseau/dotfiles 0.2.501 → 0.2.503
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 +155 -4
- package/LICENSE +21 -1283
- package/README.md +40 -8
- 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/01-dot-cli.md +63 -45
- package/docs/manual/03-reference/02-config-files.md +2 -2
- package/docs/manual/03-reference/05-feature-flags.md +62 -3
- package/docs/manual/_toc.yml +1 -1
- package/docs/manual/command-index.md +72 -55
- package/docs/manual/index.md +66 -0
- package/docs/operations/CI_COMPOSITES.md +2 -2
- package/docs/operations/COMPLETIONS.md +2 -2
- package/docs/operations/COVERAGE.md +40 -6
- package/docs/operations/HARD_AUDIT_2026.md +631 -0
- package/docs/operations/MAINTENANCE.md +3 -3
- package/docs/operations/MANIFEST.md +127 -0
- package/docs/operations/REGISTRY.md +89 -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 +665 -0
- package/docs/operations/ROADMAP_V0_2_503.md +134 -0
- package/docs/operations/TESTING.md +17 -0
- package/docs/operations/TRACEABILITY.md +9 -3
- package/docs/operations/VERSION_SYNC.md +4 -4
- package/docs/reference/POWERSHELL_PARITY.md +81 -0
- package/docs/registry.json +6 -0
- package/docs/schema/dot-env-v1.json +110 -0
- package/docs/security/CI_EGRESS_ALLOWLIST.md +1 -1
- package/docs/security/CI_PINNING.md +121 -0
- package/docs/security/COMMIT_SIGNING.md +138 -0
- package/docs/security/DEPS_DEV_EXCEPTIONS.md +2 -2
- package/docs/security/DISCLOSURE.md +130 -0
- package/docs/security/FUZZING.md +114 -0
- package/docs/security/INSTALL_VERIFICATION.md +2 -2
- package/docs/security/KEY_ROTATION.md +81 -1
- package/docs/security/POLICY_RELEASES.md +2 -2
- package/docs/security/SCORECARD.md +130 -15
- package/docs/security/SHELL_EXEMPTIONS.md +4 -4
- package/docs/security/VERIFY_RELEASE.md +201 -0
- package/docs/security/security-pubkey.asc +15 -0
- package/install.sh +67 -38
- 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 +4 -4
- package/scripts/diagnostics/conflicts.sh +2 -2
- package/scripts/diagnostics/doctor-unified.sh +2 -2
- package/scripts/diagnostics/doctor.sh +45 -15
- 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 +4 -4
- package/scripts/diagnostics/scorecard.sh +4 -4
- package/scripts/diagnostics/security-score.sh +2 -2
- 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 +2 -2
- package/scripts/diagnostics/workstation-attestation.sh +14 -14
- package/scripts/dot/commands/agent.sh +27 -22
- package/scripts/dot/commands/agents.sh +335 -0
- package/scripts/dot/commands/ai.sh +144 -25
- package/scripts/dot/commands/aliases.sh +10 -8
- package/scripts/dot/commands/appearance.sh +2 -2
- package/scripts/dot/commands/core.sh +12 -6
- package/scripts/dot/commands/diagnostics.sh +5 -5
- package/scripts/dot/commands/env-emit.sh +202 -0
- package/scripts/dot/commands/fleet.sh +290 -14
- package/scripts/dot/commands/init.sh +184 -0
- package/scripts/dot/commands/lint.sh +9 -4
- package/scripts/dot/commands/manual.sh +3 -3
- package/scripts/dot/commands/meta.sh +19 -10
- package/scripts/dot/commands/patterns.sh +2 -2
- package/scripts/dot/commands/registry.sh +263 -0
- 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 +62 -4
- 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 +2 -2
- package/scripts/git-hooks/pre-push +13 -0
- package/scripts/lib/secrets_provider.sh +32 -6
- package/scripts/ops/ai-setup.sh +1 -1
- package/scripts/ops/bundle.sh +2 -2
- package/scripts/ops/chaos.sh +2 -2
- package/scripts/ops/chezmoi-apply.sh +4 -4
- 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 +18 -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/check-disclosure-key-expiry.sh +110 -0
- 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-configs.sh +11 -2
- 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 +8 -1
- 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 +58 -7
- 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/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/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 -134
- 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 -635
- 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 -596
- package/dot_local/bin/executable_dot-ai +0 -36
- package/dot_local/bin/executable_dot-bootstrap +0 -77
- 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 -283
- 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/install-chezmoi-verified.sh +0 -64
- package/scripts/ci/run-coverage.sh +0 -362
- package/scripts/ci/validate-chezmoidata.sh +0 -25
- package/scripts/ci/validate-ci-config.sh +0 -224
- 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 -99
- package/scripts/dot/lib/ui.sh +0 -518
- 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
|
@@ -3,16 +3,26 @@
|
|
|
3
3
|
set -euo pipefail
|
|
4
4
|
|
|
5
5
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
-
# shellcheck source
|
|
6
|
+
# shellcheck source=../../lib/dot/ui.sh
|
|
7
7
|
# shellcheck disable=SC1091
|
|
8
|
-
source "$SCRIPT_DIR
|
|
8
|
+
source "$SCRIPT_DIR/../../lib/dot/ui.sh"
|
|
9
9
|
|
|
10
10
|
ui_init
|
|
11
11
|
ui_header "Wallpaper Sync"
|
|
12
12
|
|
|
13
13
|
WALLPAPER_DIR="${DOTFILES_WALLPAPER_DIR:-$HOME/Pictures/Wallpapers}"
|
|
14
14
|
CHEZMOI_CFG="${XDG_CONFIG_HOME:-$HOME/.config}/chezmoi/chezmoi.toml"
|
|
15
|
-
|
|
15
|
+
|
|
16
|
+
# Resolve dotfiles repo root, then descend into chezmoi source subdir if
|
|
17
|
+
# .chezmoiroot is present (v0.2.503+, where chezmoi files live in defaults/)
|
|
18
|
+
_DOTFILES_ROOT="${HOME}/.dotfiles"
|
|
19
|
+
[[ ! -d "$_DOTFILES_ROOT" && -d "${HOME}/.local/share/chezmoi" ]] && _DOTFILES_ROOT="${HOME}/.local/share/chezmoi"
|
|
20
|
+
_CHEZMOI_SRC="$_DOTFILES_ROOT"
|
|
21
|
+
if [[ -f "$_DOTFILES_ROOT/.chezmoiroot" ]]; then
|
|
22
|
+
_sub="$(head -1 "$_DOTFILES_ROOT/.chezmoiroot" | tr -d '[:space:]')"
|
|
23
|
+
[[ -n "$_sub" && -d "$_DOTFILES_ROOT/$_sub" ]] && _CHEZMOI_SRC="$_DOTFILES_ROOT/$_sub"
|
|
24
|
+
fi
|
|
25
|
+
DATA_FILE="${_CHEZMOI_SRC}/.chezmoidata.toml"
|
|
16
26
|
|
|
17
27
|
WALLPAPER_DIR_EXISTS=true
|
|
18
28
|
if [ ! -d "$WALLPAPER_DIR" ]; then
|
|
@@ -44,8 +54,6 @@ detect_mode() {
|
|
|
44
54
|
fi
|
|
45
55
|
}
|
|
46
56
|
|
|
47
|
-
MODE="$(detect_mode)"
|
|
48
|
-
|
|
49
57
|
current_theme() {
|
|
50
58
|
if [[ -f "$CHEZMOI_CFG" ]]; then
|
|
51
59
|
local chezmoi_theme
|
|
@@ -70,23 +78,26 @@ wallpaper_for_theme() {
|
|
|
70
78
|
[[ -n "$theme" ]] || return 1
|
|
71
79
|
[[ -n "$mode" ]] || return 1
|
|
72
80
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
family="${theme%-dark}"
|
|
82
|
+
if [[ "$family" == "$theme" ]]; then
|
|
83
|
+
family="${theme%-light}"
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# 1. Prefer pre-extracted frames (fast, no conversion needed).
|
|
87
|
+
# Convention: {family}-0.png = light, {family}-1.png = dark.
|
|
88
|
+
# These are created externally (e.g. ImageMagick/ffmpeg from dynamic HEIC).
|
|
89
|
+
local frame_idx=0
|
|
90
|
+
[[ "$mode" == "dark" ]] && frame_idx=1
|
|
91
|
+
for ext in png jpg webp; do
|
|
92
|
+
candidate="$WALLPAPER_DIR/${family}-${frame_idx}.${ext}"
|
|
93
|
+
if [[ -f "$candidate" ]]; then
|
|
94
|
+
printf '%s\n' "$candidate"
|
|
84
95
|
return 0
|
|
85
96
|
fi
|
|
86
|
-
|
|
97
|
+
done
|
|
87
98
|
|
|
88
|
-
# 2. Check
|
|
89
|
-
for ext in
|
|
99
|
+
# 2. Check exact theme name (e.g. hello-dark.png)
|
|
100
|
+
for ext in png jpg webp heic; do
|
|
90
101
|
candidate="$WALLPAPER_DIR/${theme}.${ext}"
|
|
91
102
|
if [[ -f "$candidate" ]]; then
|
|
92
103
|
printf '%s\n' "$candidate"
|
|
@@ -94,11 +105,8 @@ wallpaper_for_theme() {
|
|
|
94
105
|
fi
|
|
95
106
|
done
|
|
96
107
|
|
|
97
|
-
family
|
|
98
|
-
|
|
99
|
-
family="${theme%-light}"
|
|
100
|
-
fi
|
|
101
|
-
for ext in heic jpg png; do
|
|
108
|
+
# 3. Check family-mode variant (e.g. hello-dark.png)
|
|
109
|
+
for ext in png jpg webp heic; do
|
|
102
110
|
candidate="$WALLPAPER_DIR/${family}-${mode}.${ext}"
|
|
103
111
|
if [[ -f "$candidate" ]]; then
|
|
104
112
|
printf '%s\n' "$candidate"
|
|
@@ -106,6 +114,58 @@ wallpaper_for_theme() {
|
|
|
106
114
|
fi
|
|
107
115
|
done
|
|
108
116
|
|
|
117
|
+
# 4. Check themes.toml stored wallpaper path (set by extract-theme.py)
|
|
118
|
+
local themes_file="${_CHEZMOI_SRC}/.chezmoidata/themes.toml"
|
|
119
|
+
if [[ -f "$themes_file" ]]; then
|
|
120
|
+
local stored_wp
|
|
121
|
+
stored_wp="$(awk -v n="$theme" '
|
|
122
|
+
$0 == "[themes." n "]" { found=1; next }
|
|
123
|
+
/^\[/ { found=0 }
|
|
124
|
+
found && /^wallpaper/ { sub(/.*= *"/, ""); sub(/".*/, ""); print; exit }
|
|
125
|
+
' "$themes_file")"
|
|
126
|
+
if [[ -n "$stored_wp" ]]; then
|
|
127
|
+
# Cross-platform: resolve macOS paths on Linux
|
|
128
|
+
if [[ ! -f "$stored_wp" ]]; then
|
|
129
|
+
if [[ "$stored_wp" == /Users/* ]]; then
|
|
130
|
+
# /Users/<user>/Pictures/... → $HOME/Pictures/...
|
|
131
|
+
stored_wp="${HOME}/${stored_wp#/Users/*/}"
|
|
132
|
+
elif [[ "$stored_wp" == /System/* ]]; then
|
|
133
|
+
# macOS system wallpapers don't exist on Linux — skip to next fallback
|
|
134
|
+
stored_wp=""
|
|
135
|
+
fi
|
|
136
|
+
fi
|
|
137
|
+
if [[ -n "$stored_wp" && -f "$stored_wp" ]]; then
|
|
138
|
+
printf '%s\n' "$stored_wp"
|
|
139
|
+
return 0
|
|
140
|
+
fi
|
|
141
|
+
fi
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
# 5. Check family-only file (e.g. hello.heic — dynamic wallpaper).
|
|
145
|
+
# For HEIC on Linux, extract frames first then return the correct one.
|
|
146
|
+
for ext in png jpg webp; do
|
|
147
|
+
candidate="$WALLPAPER_DIR/${family}.${ext}"
|
|
148
|
+
if [[ -f "$candidate" ]]; then
|
|
149
|
+
printf '%s\n' "$candidate"
|
|
150
|
+
return 0
|
|
151
|
+
fi
|
|
152
|
+
done
|
|
153
|
+
candidate="$WALLPAPER_DIR/${family}.heic"
|
|
154
|
+
if [[ -f "$candidate" ]] && [[ "$(uname -s)" == "Linux" ]]; then
|
|
155
|
+
# Extract frames from HEIC then return the mode-appropriate one
|
|
156
|
+
ensure_linux_compatible "$candidate" >/dev/null
|
|
157
|
+
# Re-check for extracted frames
|
|
158
|
+
for fext in png jpg; do
|
|
159
|
+
if [[ -f "$WALLPAPER_DIR/${family}-${frame_idx}.${fext}" ]]; then
|
|
160
|
+
printf '%s\n' "$WALLPAPER_DIR/${family}-${frame_idx}.${fext}"
|
|
161
|
+
return 0
|
|
162
|
+
fi
|
|
163
|
+
done
|
|
164
|
+
elif [[ -f "$candidate" ]]; then
|
|
165
|
+
printf '%s\n' "$candidate"
|
|
166
|
+
return 0
|
|
167
|
+
fi
|
|
168
|
+
|
|
109
169
|
return 1
|
|
110
170
|
}
|
|
111
171
|
|
|
@@ -122,24 +182,27 @@ system_wallpaper_for_theme() {
|
|
|
122
182
|
|
|
123
183
|
[[ -n "$theme" ]] || return 1
|
|
124
184
|
|
|
125
|
-
# macOS: map theme names to Apple system wallpapers
|
|
185
|
+
# macOS: map theme names to Apple system wallpapers.
|
|
186
|
+
# Plain case statement (not `local -A`) because macOS still ships
|
|
187
|
+
# /bin/bash 3.2 which doesn't support associative arrays. Users who
|
|
188
|
+
# have brew bash get the same behaviour; first-run users with stock
|
|
189
|
+
# bash do too.
|
|
126
190
|
if [[ "$(uname -s)" == "Darwin" && -d "$SYS_MAC" ]]; then
|
|
127
|
-
local -A mac_map=(
|
|
128
|
-
[macos - sonoma]="$SYS_MAC/Sonoma.heic"
|
|
129
|
-
[macos - blue]="$SYS_MAC/Mac Blue.heic"
|
|
130
|
-
[macos - pink]="$SYS_MAC/Mac Pink.heic"
|
|
131
|
-
[macos - purple]="$SYS_MAC/Mac Purple.heic"
|
|
132
|
-
[macos - yellow]="$SYS_MAC/Mac Yellow.heic"
|
|
133
|
-
[macos - orange]="$SYS_MAC/iMac Orange.heic"
|
|
134
|
-
[macos - green]="$SYS_MAC/iMac Green.heic"
|
|
135
|
-
[macos - silver]="$SYS_MAC/iMac Silver.heic"
|
|
136
|
-
)
|
|
137
|
-
|
|
138
191
|
# Extract family from theme name (strip -dark/-light)
|
|
139
192
|
local family="${theme%-dark}"
|
|
140
193
|
[[ "$family" == "$theme" ]] && family="${theme%-light}"
|
|
141
194
|
|
|
142
|
-
local sys_wp="
|
|
195
|
+
local sys_wp=""
|
|
196
|
+
case "$family" in
|
|
197
|
+
"macos - sonoma") sys_wp="$SYS_MAC/Sonoma.heic" ;;
|
|
198
|
+
"macos - blue") sys_wp="$SYS_MAC/Mac Blue.heic" ;;
|
|
199
|
+
"macos - pink") sys_wp="$SYS_MAC/Mac Pink.heic" ;;
|
|
200
|
+
"macos - purple") sys_wp="$SYS_MAC/Mac Purple.heic" ;;
|
|
201
|
+
"macos - yellow") sys_wp="$SYS_MAC/Mac Yellow.heic" ;;
|
|
202
|
+
"macos - orange") sys_wp="$SYS_MAC/iMac Orange.heic" ;;
|
|
203
|
+
"macos - green") sys_wp="$SYS_MAC/iMac Green.heic" ;;
|
|
204
|
+
"macos - silver") sys_wp="$SYS_MAC/iMac Silver.heic" ;;
|
|
205
|
+
esac
|
|
143
206
|
if [[ -n "$sys_wp" && -f "$sys_wp" ]]; then
|
|
144
207
|
printf '%s\n' "$sys_wp"
|
|
145
208
|
return 0
|
|
@@ -155,7 +218,7 @@ system_wallpaper_for_theme() {
|
|
|
155
218
|
for dir in "${SYS_LINUX_DIRS[@]}"; do
|
|
156
219
|
[[ -d "$dir" ]] || continue
|
|
157
220
|
local match
|
|
158
|
-
match="$(find "$dir" -maxdepth 3 -type f \( -name "*.jpg" -o -name "*.png" \) \
|
|
221
|
+
match="$(find "$dir" -maxdepth 3 -type f \( -name "*.jpg" -o -name "*.png" -o -name "*.webp" \) \
|
|
159
222
|
-iname "*${keyword}*" 2>/dev/null | head -1)"
|
|
160
223
|
if [[ -n "$match" ]]; then
|
|
161
224
|
printf '%s\n' "$match"
|
|
@@ -208,7 +271,16 @@ pick_wallpaper() {
|
|
|
208
271
|
|
|
209
272
|
while IFS= read -r line; do
|
|
210
273
|
files+=("$line")
|
|
211
|
-
done < <(find "$WALLPAPER_DIR" -maxdepth 1 -type f \( -iname "*-${mode}.jpg" -o -iname "*-${mode}.png" -o -iname "*-${mode}.heic" \) | sort)
|
|
274
|
+
done < <(find "$WALLPAPER_DIR" -maxdepth 1 -type f \( -iname "*-${mode}.jpg" -o -iname "*-${mode}.png" -o -iname "*-${mode}.webp" -o -iname "*-${mode}.heic" \) | sort)
|
|
275
|
+
|
|
276
|
+
# Fallback: search for extracted frames (-0 = light, -1 = dark)
|
|
277
|
+
if [[ ${#files[@]} -eq 0 ]]; then
|
|
278
|
+
local frame_suffix=0
|
|
279
|
+
[[ "$mode" == "dark" ]] && frame_suffix=1
|
|
280
|
+
while IFS= read -r line; do
|
|
281
|
+
files+=("$line")
|
|
282
|
+
done < <(find "$WALLPAPER_DIR" -maxdepth 1 -type f \( -iname "*-${frame_suffix}.jpg" -o -iname "*-${frame_suffix}.png" -o -iname "*-${frame_suffix}.webp" \) | sort)
|
|
283
|
+
fi
|
|
212
284
|
|
|
213
285
|
if [[ ${#files[@]} -eq 0 ]]; then
|
|
214
286
|
return 1
|
|
@@ -223,6 +295,17 @@ pick_wallpaper() {
|
|
|
223
295
|
}
|
|
224
296
|
|
|
225
297
|
THEME="$(current_theme || true)"
|
|
298
|
+
|
|
299
|
+
# Derive mode from theme name (authoritative) instead of querying DMS
|
|
300
|
+
# which may have just restarted and report stale state.
|
|
301
|
+
if [[ "$THEME" == *-dark ]]; then
|
|
302
|
+
MODE="dark"
|
|
303
|
+
elif [[ "$THEME" == *-light ]]; then
|
|
304
|
+
MODE="light"
|
|
305
|
+
else
|
|
306
|
+
MODE="$(detect_mode)"
|
|
307
|
+
fi
|
|
308
|
+
|
|
226
309
|
WALLPAPER=""
|
|
227
310
|
if [[ "$WALLPAPER_DIR_EXISTS" == "true" ]]; then
|
|
228
311
|
WALLPAPER="$(pick_wallpaper "$MODE" "$THEME" || true)"
|
|
@@ -254,28 +337,61 @@ ensure_linux_compatible() {
|
|
|
254
337
|
}
|
|
255
338
|
|
|
256
339
|
local png="${wp%.heic}.png"
|
|
340
|
+
# Use cached PNG only if it exists, is newer than source, and is > 1MB
|
|
341
|
+
# (corrupt/truncated conversions produce tiny files that crash matugen).
|
|
257
342
|
if [[ -f "$png" ]] && [[ "$png" -nt "$wp" ]]; then
|
|
258
|
-
|
|
259
|
-
|
|
343
|
+
local fsize
|
|
344
|
+
fsize="$(stat -c%s "$png" 2>/dev/null || stat -f%z "$png" 2>/dev/null || echo 0)"
|
|
345
|
+
if [[ "$fsize" -gt 1000000 ]]; then
|
|
346
|
+
printf '%s\n' "$png"
|
|
347
|
+
return
|
|
348
|
+
fi
|
|
260
349
|
fi
|
|
261
350
|
|
|
351
|
+
# Write to temp file then atomic move — prevents DMS/matugen from
|
|
352
|
+
# reading a partially-written PNG during multi-frame HEIC extraction.
|
|
353
|
+
local tmp_png
|
|
354
|
+
tmp_png="$(mktemp "${png%.png}.XXXXXX.png")"
|
|
355
|
+
|
|
262
356
|
if command -v magick &>/dev/null; then
|
|
263
|
-
magick "$wp" -quality 95 "$
|
|
264
|
-
|
|
357
|
+
magick "$wp" -quality 95 "$tmp_png" 2>/dev/null && {
|
|
358
|
+
# Multi-frame HEIC: magick creates {name}-0.png, {name}-1.png etc.
|
|
359
|
+
# Move each extracted frame to its final location atomically.
|
|
360
|
+
local tmp_base="${tmp_png%.png}"
|
|
361
|
+
local final_base="${png%.png}"
|
|
362
|
+
if [[ -f "${tmp_base}-0.png" ]]; then
|
|
363
|
+
for f in "${tmp_base}"-*.png; do
|
|
364
|
+
local suffix="${f#"$tmp_base"}"
|
|
365
|
+
mv -f "$f" "${final_base}${suffix}" 2>/dev/null
|
|
366
|
+
done
|
|
367
|
+
rm -f "$tmp_png" 2>/dev/null
|
|
368
|
+
# Return the correct frame: -0 = light, -1 = dark
|
|
369
|
+
if [[ -f "${final_base}-0.png" ]]; then
|
|
370
|
+
printf '%s\n' "${final_base}-0.png"
|
|
371
|
+
else
|
|
372
|
+
printf '%s\n' "$png"
|
|
373
|
+
fi
|
|
374
|
+
else
|
|
375
|
+
mv -f "$tmp_png" "$png" 2>/dev/null
|
|
376
|
+
printf '%s\n' "$png"
|
|
377
|
+
fi
|
|
265
378
|
return
|
|
266
379
|
}
|
|
267
380
|
elif command -v heif-convert &>/dev/null; then
|
|
268
|
-
heif-convert "$wp" "$
|
|
381
|
+
heif-convert "$wp" "$tmp_png" 2>/dev/null && {
|
|
382
|
+
mv -f "$tmp_png" "$png" 2>/dev/null
|
|
269
383
|
printf '%s\n' "$png"
|
|
270
384
|
return
|
|
271
385
|
}
|
|
272
386
|
elif command -v convert &>/dev/null; then
|
|
273
|
-
convert "$wp" "$
|
|
387
|
+
convert "$wp" "$tmp_png" 2>/dev/null && {
|
|
388
|
+
mv -f "$tmp_png" "$png" 2>/dev/null
|
|
274
389
|
printf '%s\n' "$png"
|
|
275
390
|
return
|
|
276
391
|
}
|
|
277
392
|
fi
|
|
278
393
|
|
|
394
|
+
rm -f "$tmp_png" 2>/dev/null
|
|
279
395
|
# Fallback: use original and hope the DE supports it
|
|
280
396
|
printf '%s\n' "$wp"
|
|
281
397
|
}
|
|
@@ -291,72 +407,160 @@ apply_wallpaper() {
|
|
|
291
407
|
|
|
292
408
|
case "$(uname -s)" in
|
|
293
409
|
Darwin)
|
|
294
|
-
|
|
410
|
+
# macOS Sonoma+ moved wallpaper state to ~/Library/Application Support/
|
|
411
|
+
# com.apple.wallpaper/Store/Index.plist, owned by WallpaperAgent. Each
|
|
412
|
+
# Space and Display has its own entry, and AppleScript's `every desktop`
|
|
413
|
+
# only sees the active Space — so the only reliable way to cover all
|
|
414
|
+
# desktops is to rewrite each entry in Index.plist directly.
|
|
415
|
+
#
|
|
416
|
+
# The Configuration field of each choice is itself a nested binary plist
|
|
417
|
+
# of the form: {type: 'imageFile', url: {relative: 'file:///path'}}
|
|
418
|
+
# The store has several shapes: Spaces[uuid].Default.Desktop (per-Space
|
|
419
|
+
# wallpaper), Spaces[uuid].Default.Linked (desktop + screensaver share
|
|
420
|
+
# one image), and per-display nesting under Spaces[uuid].Displays[uuid].
|
|
421
|
+
# Walk the tree and patch any node that holds a wallpaper Choice list.
|
|
422
|
+
# After updating, killall WallpaperAgent so launchd respawns it and it
|
|
423
|
+
# re-reads the store.
|
|
424
|
+
python3 - "$wp" <<'PYEOF' 2>/dev/null || true
|
|
425
|
+
import plistlib, os, sys
|
|
426
|
+
wp = sys.argv[1]
|
|
427
|
+
uri = "file://" + wp
|
|
428
|
+
store = os.path.expanduser(
|
|
429
|
+
"~/Library/Application Support/com.apple.wallpaper/Store/Index.plist"
|
|
430
|
+
)
|
|
431
|
+
if not os.path.exists(store):
|
|
432
|
+
sys.exit(0)
|
|
433
|
+
|
|
434
|
+
def make_config(uri):
|
|
435
|
+
return plistlib.dumps(
|
|
436
|
+
{"type": "imageFile", "url": {"relative": uri}},
|
|
437
|
+
fmt=plistlib.FMT_BINARY,
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
def patch_node(node, uri):
|
|
441
|
+
"""Patch a Desktop/Linked node in-place. Returns 1 if patched."""
|
|
442
|
+
content = node.get("Content")
|
|
443
|
+
if not isinstance(content, dict):
|
|
444
|
+
return 0
|
|
445
|
+
choices = content.get("Choices")
|
|
446
|
+
if not isinstance(choices, list) or not choices:
|
|
447
|
+
return 0
|
|
448
|
+
first = choices[0]
|
|
449
|
+
if not isinstance(first, dict):
|
|
450
|
+
return 0
|
|
451
|
+
first["Configuration"] = make_config(uri)
|
|
452
|
+
first["Provider"] = "com.apple.wallpaper.choice.image"
|
|
453
|
+
first["Files"] = []
|
|
454
|
+
content["Choices"] = [first]
|
|
455
|
+
content["Shuffle"] = "$null"
|
|
456
|
+
# Leave EncodedOptionValues alone — it stores crop/color and is per-image.
|
|
457
|
+
return 1
|
|
458
|
+
|
|
459
|
+
# Recursively patch every wallpaper-bearing node. A node qualifies when it
|
|
460
|
+
# has a Content.Choices list — this matches Desktop and Linked entries
|
|
461
|
+
# wherever they appear (top-level Displays, AllSpacesAndDisplays, Spaces[*]
|
|
462
|
+
# .Default, Spaces[*].Displays[*], etc.) and ignores Idle (screensaver) so
|
|
463
|
+
# we don't clobber the user's lock-screen wallpaper.
|
|
464
|
+
def walk(node, uri, key=None):
|
|
465
|
+
count = 0
|
|
466
|
+
if isinstance(node, dict):
|
|
467
|
+
if key in ("Desktop", "Linked") and "Content" in node:
|
|
468
|
+
count += patch_node(node, uri)
|
|
469
|
+
else:
|
|
470
|
+
for k, v in node.items():
|
|
471
|
+
count += walk(v, uri, k)
|
|
472
|
+
elif isinstance(node, list):
|
|
473
|
+
for item in node:
|
|
474
|
+
count += walk(item, uri)
|
|
475
|
+
return count
|
|
476
|
+
|
|
477
|
+
with open(store, "rb") as f:
|
|
478
|
+
data = plistlib.load(f)
|
|
479
|
+
|
|
480
|
+
# Safety backup before mutating.
|
|
481
|
+
try:
|
|
482
|
+
with open(store + ".dot-bak", "wb") as f:
|
|
483
|
+
plistlib.dump(data, f, fmt=plistlib.FMT_BINARY)
|
|
484
|
+
except Exception:
|
|
485
|
+
pass
|
|
486
|
+
|
|
487
|
+
updated = walk(data, uri)
|
|
488
|
+
|
|
489
|
+
if updated:
|
|
490
|
+
with open(store, "wb") as f:
|
|
491
|
+
plistlib.dump(data, f, fmt=plistlib.FMT_BINARY)
|
|
492
|
+
|
|
493
|
+
print(updated)
|
|
494
|
+
PYEOF
|
|
495
|
+
|
|
496
|
+
# Restart WallpaperAgent so it re-reads the store. launchd respawns it.
|
|
497
|
+
killall WallpaperAgent 2>/dev/null || true
|
|
498
|
+
|
|
499
|
+
# Also nudge the active Space via the public API. This covers the
|
|
500
|
+
# initial render before WallpaperAgent comes back, and handles screens
|
|
501
|
+
# the Index.plist rewrite somehow missed.
|
|
502
|
+
if command -v wallpaper &>/dev/null; then
|
|
503
|
+
wallpaper set "$wp" --screen all 2>/dev/null || true
|
|
504
|
+
else
|
|
505
|
+
osascript -e "
|
|
506
|
+
tell application \"System Events\"
|
|
507
|
+
set theFile to POSIX file \"${wp}\"
|
|
508
|
+
repeat with d in (get every desktop)
|
|
509
|
+
set picture of d to theFile
|
|
510
|
+
end repeat
|
|
511
|
+
end tell" 2>/dev/null || true
|
|
512
|
+
fi
|
|
295
513
|
;;
|
|
296
514
|
Linux)
|
|
297
|
-
#
|
|
515
|
+
# DMS owns wallpaper display and runs matugen for color extraction.
|
|
516
|
+
# Set the wallpaper ONCE for the current mode — DMS handles the rest.
|
|
517
|
+
# Multiple IPC calls (pair-setting, mode switching) cause matugen
|
|
518
|
+
# worker crashes and slow transitions. Keep it simple.
|
|
298
519
|
if command -v dms &>/dev/null; then
|
|
299
|
-
local dms_result current_outputs output
|
|
520
|
+
local dms_result current_outputs output
|
|
300
521
|
dms_result="$(dms ipc wallpaper set "$wp" 2>/dev/null || true)"
|
|
301
522
|
if [[ "$dms_result" == SUCCESS:* ]]; then
|
|
302
|
-
ui_info "Applied via" "dms ipc
|
|
523
|
+
ui_info "Applied via" "dms ipc"
|
|
303
524
|
elif [[ "$dms_result" == ERROR:\ Per-monitor\ mode\ enabled* ]]; then
|
|
304
525
|
current_outputs="$(dms ipc outputs current 2>/dev/null | tr -d '[]"')"
|
|
305
526
|
for output in ${current_outputs//,/ }; do
|
|
306
527
|
[[ -n "$output" ]] || continue
|
|
307
528
|
dms ipc wallpaper setFor "$output" "$wp" >/dev/null 2>&1 || true
|
|
308
529
|
done
|
|
309
|
-
ui_info "Applied via" "dms ipc
|
|
310
|
-
else
|
|
311
|
-
ui_warn "DMS wallpaper" "set failed, falling back"
|
|
312
|
-
fi
|
|
313
|
-
|
|
314
|
-
# Keep DMS light/dark wallpaper slots aligned with the theme family.
|
|
315
|
-
if [[ -n "${THEME:-}" ]] && mapfile -t _pair < <(theme_wallpaper_pair "$THEME"); then
|
|
316
|
-
light_wp="${_pair[0]:-}"
|
|
317
|
-
dark_wp="${_pair[1]:-}"
|
|
318
|
-
current_dms_mode="$(dms ipc theme getMode 2>/dev/null || printf '%s\n' "$mode")"
|
|
319
|
-
|
|
320
|
-
if [[ -n "$light_wp" && -n "$dark_wp" ]]; then
|
|
321
|
-
dms ipc theme light >/dev/null 2>&1 || true
|
|
322
|
-
dms ipc wallpaper set "$light_wp" >/dev/null 2>&1 || true
|
|
323
|
-
|
|
324
|
-
dms ipc theme dark >/dev/null 2>&1 || true
|
|
325
|
-
dms ipc wallpaper set "$dark_wp" >/dev/null 2>&1 || true
|
|
326
|
-
|
|
327
|
-
if [[ "$current_dms_mode" == "light" ]]; then
|
|
328
|
-
dms ipc theme light >/dev/null 2>&1 || true
|
|
329
|
-
else
|
|
330
|
-
dms ipc theme dark >/dev/null 2>&1 || true
|
|
331
|
-
fi
|
|
332
|
-
ui_info "DMS pair" "$(basename "$light_wp"), $(basename "$dark_wp")"
|
|
333
|
-
fi
|
|
530
|
+
ui_info "Applied via" "dms ipc (per-monitor)"
|
|
334
531
|
fi
|
|
335
532
|
fi
|
|
336
533
|
|
|
337
534
|
# gsettings-based desktop state for GTK/freedesktop consumers
|
|
338
535
|
if command -v gsettings &>/dev/null; then
|
|
339
|
-
# Find the matching pair for picture-uri and picture-uri-dark
|
|
340
|
-
|
|
536
|
+
# Find the matching pair for picture-uri and picture-uri-dark.
|
|
537
|
+
# Wallpapers use two naming conventions:
|
|
538
|
+
# -light/-dark (e.g. hello-light.png, hello-dark.png)
|
|
539
|
+
# -0/-1 (e.g. hello-0.png = light, hello-1.png = dark)
|
|
540
|
+
local light_wp="" dark_wp="" base ext family_base
|
|
341
541
|
ext="${wp##*.}"
|
|
542
|
+
# Strip -light/-dark suffix to get family base
|
|
342
543
|
base="${wp%-${mode}.${ext}}"
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
light_wp="${base}-light.jpg"
|
|
351
|
-
dark_wp="${base}-dark.jpg"
|
|
352
|
-
elif [[ -f "${base}-light.png" ]] && [[ -f "${base}-dark.png" ]]; then
|
|
353
|
-
light_wp="${base}-light.png"
|
|
354
|
-
dark_wp="${base}-dark.png"
|
|
355
|
-
else
|
|
356
|
-
light_wp=""
|
|
357
|
-
dark_wp=""
|
|
544
|
+
# Strip -0/-1 suffix to get family base for frame naming
|
|
545
|
+
family_base="${wp%-[01].${ext}}"
|
|
546
|
+
# If neither pattern matched, both equal $wp — derive family from theme
|
|
547
|
+
if [[ "$family_base" == "$wp" && "$base" == "$wp" ]]; then
|
|
548
|
+
family_base="${WALLPAPER_DIR}/${THEME%-dark}"
|
|
549
|
+
[[ "$family_base" == "${WALLPAPER_DIR}/${THEME}" ]] && family_base="${WALLPAPER_DIR}/${THEME%-light}"
|
|
550
|
+
base="$family_base"
|
|
358
551
|
fi
|
|
359
552
|
|
|
553
|
+
for try_ext in "$ext" png jpg webp heic; do
|
|
554
|
+
[[ -z "$light_wp" ]] || break
|
|
555
|
+
if [[ -f "${base}-light.${try_ext}" ]] && [[ -f "${base}-dark.${try_ext}" ]]; then
|
|
556
|
+
light_wp="${base}-light.${try_ext}"
|
|
557
|
+
dark_wp="${base}-dark.${try_ext}"
|
|
558
|
+
elif [[ -f "${family_base}-0.${try_ext}" ]] && [[ -f "${family_base}-1.${try_ext}" ]]; then
|
|
559
|
+
light_wp="${family_base}-0.${try_ext}"
|
|
560
|
+
dark_wp="${family_base}-1.${try_ext}"
|
|
561
|
+
fi
|
|
562
|
+
done
|
|
563
|
+
|
|
360
564
|
if [[ -n "$light_wp" ]] && [[ -n "$dark_wp" ]]; then
|
|
361
565
|
light_wp="$(ensure_linux_compatible "$light_wp")"
|
|
362
566
|
dark_wp="$(ensure_linux_compatible "$dark_wp")"
|
|
@@ -391,7 +595,7 @@ apply_wallpaper() {
|
|
|
391
595
|
|
|
392
596
|
apply_wallpaper "$WALLPAPER" "$MODE"
|
|
393
597
|
if [[ -n "$THEME" ]]; then
|
|
394
|
-
ui_ok "
|
|
598
|
+
ui_ok "Applied wallpaper (${MODE})" "$(basename "$WALLPAPER") ← $THEME"
|
|
395
599
|
else
|
|
396
|
-
ui_ok "
|
|
600
|
+
ui_ok "Applied wallpaper (${MODE})" "$(basename "$WALLPAPER")"
|
|
397
601
|
fi
|
package/scripts/tuning/linux.sh
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
set -euo pipefail
|
|
10
10
|
|
|
11
11
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
|
-
# shellcheck source
|
|
12
|
+
# shellcheck source=../../lib/dot/ui.sh
|
|
13
13
|
# shellcheck disable=SC1091
|
|
14
|
-
source "$SCRIPT_DIR
|
|
14
|
+
source "$SCRIPT_DIR/../../lib/dot/ui.sh"
|
|
15
15
|
|
|
16
16
|
ui_init
|
|
17
17
|
ui_header "Linux Tuning"
|
package/scripts/tuning/macos.sh
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
set -euo pipefail
|
|
6
6
|
|
|
7
7
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
-
# shellcheck source
|
|
8
|
+
# shellcheck source=../../lib/dot/ui.sh
|
|
9
9
|
# shellcheck disable=SC1091
|
|
10
|
-
source "$SCRIPT_DIR
|
|
10
|
+
source "$SCRIPT_DIR/../../lib/dot/ui.sh"
|
|
11
11
|
|
|
12
12
|
ui_init
|
|
13
13
|
ui_header "macOS Tuning"
|
package/scripts/version-sync.sh
CHANGED
|
@@ -16,16 +16,61 @@ VERSION_PATTERN='[0-9]+\.[0-9]+\.[0-9]+'
|
|
|
16
16
|
SED_VERSION_PATTERN='[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*'
|
|
17
17
|
BACKUP_DIR="$PROJECT_ROOT/.version-sync-backup"
|
|
18
18
|
EXCLUDE_FILES=(
|
|
19
|
+
# Historical / referential docs — version refs inside are intentional
|
|
20
|
+
# pointers at prior versions, not "this is the current version" claims.
|
|
19
21
|
"CHANGELOG.md"
|
|
20
22
|
"docs/security/COMPLIANCE.md"
|
|
21
23
|
"docs/reference/FONTS.md"
|
|
22
24
|
"docs/archive/LEGACY_ROADMAP.md"
|
|
23
25
|
"docs/archive/PLAN.md"
|
|
26
|
+
|
|
27
|
+
# Roadmap + audit narratives — describe per-version work; refs to
|
|
28
|
+
# prior versions are intentional and historical.
|
|
29
|
+
"docs/operations/ROADMAP_V0_2_503.md"
|
|
30
|
+
"docs/operations/VERSION_SYNC.md"
|
|
31
|
+
"docs/operations/RFC_v0_2_503_reorganization.md"
|
|
32
|
+
"docs/operations/HARD_AUDIT_2026.md"
|
|
33
|
+
"docs/reference/ALIASES_DEPRECATIONS.md"
|
|
34
|
+
|
|
35
|
+
# Security docs — INSTALL_VERIFICATION + CI_PINNING + SCORECARD
|
|
36
|
+
# carry per-release hash tables / closed-cycle logs. The "current"
|
|
37
|
+
# version inside these is tracked by hand, not by version-sync.
|
|
38
|
+
"docs/security/CI_PINNING.md"
|
|
39
|
+
"docs/security/INSTALL_VERIFICATION.md"
|
|
40
|
+
"docs/security/SCORECARD.md"
|
|
41
|
+
|
|
42
|
+
# Release-verification recipes use an example pinned tag
|
|
43
|
+
# that intentionally stays at a known-published release.
|
|
44
|
+
"docs/security/VERIFY_RELEASE.md"
|
|
45
|
+
|
|
46
|
+
# Example bundles — version refs in README'd examples are illustrative.
|
|
47
|
+
"examples/mise-plugin-dot/README.md"
|
|
48
|
+
|
|
49
|
+
# MANIFEST + MIGRATION docs — describe per-version manifests &
|
|
50
|
+
# cross-version migration paths; intentional references to other tags.
|
|
51
|
+
"docs/operations/MANIFEST.md"
|
|
52
|
+
"docs/operations/MIGRATION.md"
|
|
53
|
+
|
|
54
|
+
# ADR + architecture + manual + operations narratives — every
|
|
55
|
+
# version reference inside is dated context, not a "current version"
|
|
56
|
+
# claim. The single source-of-truth is .chezmoidata.toml (plus
|
|
57
|
+
# README, package.json — which version-sync DOES rewrite).
|
|
58
|
+
"docs/adr/ADR-007-multi-shell-parity.md"
|
|
59
|
+
"docs/architecture/REPO_LAYOUT.md"
|
|
60
|
+
"docs/manual/01-concepts/04-fleet.md"
|
|
61
|
+
"docs/manual/01-concepts/05-self-healing.md"
|
|
62
|
+
"docs/manual/02-tutorials/05-deploy-fleet.md"
|
|
63
|
+
"docs/manual/05-appendices/D-bibliography.md"
|
|
64
|
+
"docs/operations/MAINTENANCE.md"
|
|
65
|
+
|
|
66
|
+
# CI_COMPOSITES.md cites third-party action versions (e.g. v5.0.5),
|
|
67
|
+
# not dotfiles_version. False-positive pattern match.
|
|
68
|
+
"docs/operations/CI_COMPOSITES.md"
|
|
24
69
|
)
|
|
25
70
|
|
|
26
|
-
# shellcheck source
|
|
71
|
+
# shellcheck source=../lib/dot/ui.sh
|
|
27
72
|
# shellcheck disable=SC1091
|
|
28
|
-
source "$SCRIPT_DIR/dot/
|
|
73
|
+
source "$SCRIPT_DIR/../lib/dot/ui.sh"
|
|
29
74
|
ui_init
|
|
30
75
|
|
|
31
76
|
# Functions — delegate to shared ui.sh (redirect to stderr for script output)
|
|
@@ -142,6 +187,8 @@ sed_in_place() {
|
|
|
142
187
|
fi
|
|
143
188
|
}
|
|
144
189
|
|
|
190
|
+
# LCOV_EXCL_START — rm -rf BACKUP_DIR + cp of real release files;
|
|
191
|
+
# only run during a real release flow, not safe under coverage.
|
|
145
192
|
create_backup() {
|
|
146
193
|
local files=("$@")
|
|
147
194
|
|
|
@@ -166,6 +213,7 @@ create_backup() {
|
|
|
166
213
|
|
|
167
214
|
log_success "Backed up $backup_count files"
|
|
168
215
|
}
|
|
216
|
+
# LCOV_EXCL_STOP
|
|
169
217
|
|
|
170
218
|
update_version_references() {
|
|
171
219
|
local target_version="$1"
|
|
@@ -395,21 +443,24 @@ main() {
|
|
|
395
443
|
create_backup "${version_files[@]}"
|
|
396
444
|
fi
|
|
397
445
|
|
|
398
|
-
# Sync chezmoidata.toml (single source of truth for template files)
|
|
399
|
-
|
|
446
|
+
# Sync chezmoidata.toml (single source of truth for template files).
|
|
447
|
+
# Post-Phase-4b lives under defaults/ — kept old root location as a
|
|
448
|
+
# fallback so this script is forward- and backward-compatible.
|
|
449
|
+
local chezmoidata="$PROJECT_ROOT/defaults/.chezmoidata.toml"
|
|
450
|
+
[[ -f "$chezmoidata" ]] || chezmoidata="$PROJECT_ROOT/.chezmoidata.toml"
|
|
400
451
|
if [[ -f "$chezmoidata" ]]; then
|
|
401
452
|
if [[ "$dry_run" == "true" ]]; then
|
|
402
|
-
log_info "Would update
|
|
453
|
+
log_info "Would update ${chezmoidata#"$PROJECT_ROOT/"}: dotfiles_version = \"$target_version\""
|
|
403
454
|
else
|
|
404
455
|
sed_in_place "$chezmoidata" \
|
|
405
456
|
"s|^dotfiles_version = \"$SED_VERSION_PATTERN\"|dotfiles_version = \"$target_version\"|"
|
|
406
|
-
log_success "Updated
|
|
457
|
+
log_success "Updated ${chezmoidata#"$PROJECT_ROOT/"}"
|
|
407
458
|
fi
|
|
408
459
|
fi
|
|
409
460
|
|
|
410
461
|
# Sync non-template script files that embed the version
|
|
411
462
|
local script_files=(
|
|
412
|
-
"
|
|
463
|
+
"bin/dot"
|
|
413
464
|
"dot_local/bin/executable_tour"
|
|
414
465
|
"install.sh"
|
|
415
466
|
)
|