@sebastienrousseau/dotfiles 0.2.500 → 0.2.502

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/CHANGELOG.md +154 -0
  2. package/README.md +113 -45
  3. package/docs/.vitepress/reports/localization-readability-audit.md +4 -0
  4. package/docs/AI.md +8 -2
  5. package/docs/CNAME +1 -0
  6. package/docs/COPYRIGHT +1 -1
  7. package/docs/NAMING_CONVENTIONS.md +7 -0
  8. package/docs/README.md +4 -0
  9. package/docs/_config.yml +59 -0
  10. package/docs/adr/ADR-001-ci-cd-pipeline.md +17 -0
  11. package/docs/adr/ADR-002-shell-performance.md +9 -0
  12. package/docs/adr/ADR-003-security-first.md +18 -0
  13. package/docs/adr/ADR-004-cli-architecture.md +14 -0
  14. package/docs/adr/ADR-005-chezmoi-choice.md +10 -0
  15. package/docs/adr/ADR-006-shell-selection.md +9 -0
  16. package/docs/adr/ADR-007-multi-shell-parity.md +10 -1
  17. package/docs/adr/ADR-008-alias-system-architecture.md +10 -0
  18. package/docs/adr/ADR-009-wallpaper-driven-theming.md +131 -0
  19. package/docs/adr/ADR-010-starship-transient-prompt.md +144 -0
  20. package/docs/adr/ADR-011-nushell-tier3-keep.md +144 -0
  21. package/docs/adr/README.md +7 -0
  22. package/docs/architecture/ARCHITECTURE.md +4 -0
  23. package/docs/architecture/INTEROP.md +8 -0
  24. package/docs/architecture/REPO_LAYOUT.md +5 -1
  25. package/docs/architecture/WALKTHROUGH.md +4 -0
  26. package/docs/architecture/fleet-deployment.md +4 -0
  27. package/docs/archive/EUXIS_2026_REVIEW.md +11 -3
  28. package/docs/archive/LEGACY_ROADMAP.md +45 -27
  29. package/docs/archive/MILESTONE_v0.2.493.md +4 -0
  30. package/docs/archive/PLAN.md +46 -8
  31. package/docs/archive/REPO_AUDIT.md +8 -0
  32. package/docs/guides/INSTALL.md +4 -0
  33. package/docs/guides/NEOVIM_IDE_GUIDE.md +9 -0
  34. package/docs/guides/THEMING.md +8 -0
  35. package/docs/guides/TROUBLESHOOTING.md +28 -0
  36. package/docs/guides/WSL2_NIX_TROUBLESHOOTING.md +70 -1
  37. package/docs/index.md +6 -2
  38. package/docs/interop/A2A.md +7 -0
  39. package/docs/interop/POWERSHELL.md +102 -0
  40. package/docs/manual/00-introduction.md +5 -1
  41. package/docs/manual/01-concepts/01-architecture.md +4 -0
  42. package/docs/manual/01-concepts/02-trust-model.md +6 -2
  43. package/docs/manual/01-concepts/03-theme-engine.md +4 -0
  44. package/docs/manual/01-concepts/04-fleet.md +7 -1
  45. package/docs/manual/01-concepts/05-self-healing.md +8 -1
  46. package/docs/manual/02-tutorials/01-first-install.md +5 -0
  47. package/docs/manual/02-tutorials/02-add-wallpaper.md +5 -0
  48. package/docs/manual/02-tutorials/03-create-profile.md +6 -0
  49. package/docs/manual/02-tutorials/04-encrypt-secret.md +6 -0
  50. package/docs/manual/02-tutorials/05-deploy-fleet.md +5 -1
  51. package/docs/manual/03-reference/01-dot-cli.md +67 -45
  52. package/docs/manual/03-reference/02-config-files.md +8 -2
  53. package/docs/manual/03-reference/03-environment.md +4 -0
  54. package/docs/manual/03-reference/04-templates.md +7 -1
  55. package/docs/manual/03-reference/05-feature-flags.md +72 -3
  56. package/docs/manual/04-cookbook/01-recipes.md +4 -0
  57. package/docs/manual/04-cookbook/02-troubleshooting.md +32 -0
  58. package/docs/manual/04-cookbook/03-faq.md +8 -0
  59. package/docs/manual/05-appendices/A-platform-matrix.md +4 -0
  60. package/docs/manual/05-appendices/B-security-checklist.md +6 -0
  61. package/docs/manual/05-appendices/C-glossary.md +4 -0
  62. package/docs/manual/05-appendices/D-bibliography.md +5 -1
  63. package/docs/manual/05-appendices/E-license.md +4 -0
  64. package/docs/manual/_toc.yml +1 -1
  65. package/docs/manual/command-index.md +16 -8
  66. package/docs/manual/concept-index.md +4 -0
  67. package/docs/manual/index.md +66 -0
  68. package/docs/operations/ATTESTATION.md +5 -0
  69. package/docs/operations/CI_CADENCE.md +107 -0
  70. package/docs/operations/CI_COMPOSITES.md +156 -0
  71. package/docs/operations/COMPLETIONS.md +123 -0
  72. package/docs/operations/COVERAGE.md +182 -0
  73. package/docs/operations/DRIFT.md +107 -0
  74. package/docs/operations/HARD_AUDIT_2026.md +631 -0
  75. package/docs/operations/MAINTENANCE.md +5 -1
  76. package/docs/operations/MIGRATION.md +14 -6
  77. package/docs/operations/OPERATIONS.md +24 -0
  78. package/docs/operations/PERFORMANCE.md +133 -0
  79. package/docs/operations/REGISTRY.md +89 -0
  80. package/docs/operations/RELIABILITY.md +6 -0
  81. package/docs/operations/ROADMAP.md +36 -18
  82. package/docs/operations/ROADMAP_2026.md +665 -0
  83. package/docs/operations/TESTING.md +4 -0
  84. package/docs/operations/TRACEABILITY.md +7 -0
  85. package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +4 -0
  86. package/docs/operations/VERSION_SYNC.md +54 -5
  87. package/docs/reference/ALIASES.md +7 -0
  88. package/docs/reference/ALIASES_CHEATSHEET.md +5 -1
  89. package/docs/reference/ALIASES_DEPRECATIONS.md +5 -1
  90. package/docs/reference/FEATURES.md +4 -0
  91. package/docs/reference/FONTS.md +4 -0
  92. package/docs/reference/POWERSHELL_PARITY.md +80 -0
  93. package/docs/reference/PROFILES.md +4 -0
  94. package/docs/reference/SCREENSHOTS.md +4 -0
  95. package/docs/reference/SCRIPTS.md +4 -0
  96. package/docs/reference/SUPPORT_MATRIX.md +10 -4
  97. package/docs/reference/THEMES.md +4 -0
  98. package/docs/reference/TOOLS.md +4 -0
  99. package/docs/reference/UTILS.md +16 -12
  100. package/docs/registry.json +6 -0
  101. package/docs/security/AI_ACT_COMPLIANCE.md +4 -0
  102. package/docs/security/AUDIT_BYPASS.md +103 -0
  103. package/docs/security/AUTOMATION_SECRETS.md +4 -0
  104. package/docs/security/CI_EGRESS_ALLOWLIST.md +127 -0
  105. package/docs/security/CI_PINNING.md +113 -0
  106. package/docs/security/COMMIT_SIGNING.md +138 -0
  107. package/docs/security/COMPLIANCE.md +5 -0
  108. package/docs/security/DEPS_DEV_EXCEPTIONS.md +86 -0
  109. package/docs/security/DISCLOSURE.md +130 -0
  110. package/docs/security/ENCRYPTION.md +5 -0
  111. package/docs/security/FMEA.md +4 -0
  112. package/docs/security/HISTORY_FILTERING.md +132 -0
  113. package/docs/security/INCIDENT_RESPONSE.md +4 -0
  114. package/docs/security/INSTALL_VERIFICATION.md +122 -0
  115. package/docs/security/KEYS.md +4 -0
  116. package/docs/security/KEY_ROTATION.md +85 -1
  117. package/docs/security/MCP_POLICY.md +9 -0
  118. package/docs/security/POLICY_RELEASES.md +4 -0
  119. package/docs/security/README.md +4 -0
  120. package/docs/security/SCORECARD.md +140 -0
  121. package/docs/security/SECRETS.md +12 -0
  122. package/docs/security/SECURITY.md +4 -0
  123. package/docs/security/SECURITY_CHECKLIST.md +11 -0
  124. package/docs/security/SHELL_EXEMPTIONS.md +145 -0
  125. package/docs/security/SOUP_REGISTER.md +4 -0
  126. package/docs/security/THREAT_MODEL.md +10 -0
  127. package/docs/security/VERIFICATION_VALIDATION.md +5 -1
  128. package/docs/security/security-pubkey.asc +15 -0
  129. package/docs/themes/README.md +4 -0
  130. package/docs/themes/VISUAL_INTEGRITY_REPORT.md +4 -0
  131. package/dot_config/ai/identity.md +3 -0
  132. package/dot_config/ai/patterns/architect.md +2 -0
  133. package/dot_config/ai/patterns/hardener.md +2 -0
  134. package/dot_config/ai/patterns/refactor.md +2 -0
  135. package/dot_config/alacritty/alacritty.toml.tmpl +3 -3
  136. package/dot_config/atuin/config.toml.tmpl +47 -0
  137. package/dot_config/dotfiles/agent-card.json +1 -1
  138. package/dot_config/dotfiles/boot/README.md +2 -0
  139. package/dot_config/dotfiles/grub/README.md +2 -0
  140. package/dot_config/dotfiles/lock/README.md +2 -0
  141. package/dot_config/fish/conf.d/direnv.fish +4 -0
  142. package/dot_config/fish/conf.d/init.fish.tmpl +21 -0
  143. package/dot_config/fish/conf.d/mise-activate.fish +5 -0
  144. package/dot_config/fish/functions/_cached_eval.fish +84 -11
  145. package/dot_config/fish/functions/_cached_eval_clear.fish +17 -0
  146. package/dot_config/foot/foot.ini.tmpl +3 -3
  147. package/dot_config/fuzzel/fuzzel.ini.tmpl +2 -2
  148. package/dot_config/ghostty/config.tmpl +3 -3
  149. package/dot_config/git/hooks/executable_commit-msg +146 -0
  150. package/dot_config/goose/config.yaml +2 -2
  151. package/dot_config/gtk-3.0/gtk.css.tmpl +2 -2
  152. package/dot_config/gtk-3.0/settings.ini.tmpl +2 -2
  153. package/dot_config/gtk-4.0/gtk.css.tmpl +2 -2
  154. package/dot_config/gtk-4.0/settings.ini.tmpl +2 -2
  155. package/dot_config/kitty/kitty.conf.tmpl +3 -3
  156. package/dot_config/mise/config.toml +1 -1
  157. package/dot_config/niri/config.kdl.tmpl +2 -2
  158. package/dot_config/nushell/cached_eval.nu +80 -0
  159. package/dot_config/nushell/env.nu.tmpl +21 -13
  160. package/dot_config/shell/00-core-paths.sh.tmpl +9 -1
  161. package/dot_config/shell/05-core-safety.sh +1 -0
  162. package/dot_config/shell/10-secrets.sh +1 -0
  163. package/dot_config/shell/40-fzf-defaults.sh.tmpl +1 -0
  164. package/dot_config/shell/40-ls-colors.sh +1 -0
  165. package/dot_config/shell/50-logic-functions-core.sh.tmpl +1 -0
  166. package/dot_config/shell/50-logic-functions.sh.tmpl +1 -0
  167. package/dot_config/shell/51-logic-functions-extra.sh.tmpl +1 -0
  168. package/dot_config/shell/90-ux-aliases.sh.tmpl +1 -0
  169. package/dot_config/shell/91-ux-aliases-lazy.sh.tmpl +1 -0
  170. package/dot_config/shell/README.md +25 -8
  171. package/dot_config/starship.toml.tmpl +2 -2
  172. package/dot_config/tmux/tmux.conf.tmpl +3 -3
  173. package/dot_config/user-dirs.dirs +1 -0
  174. package/dot_config/vscode/settings.json.tmpl +2 -2
  175. package/dot_config/waybar/config.jsonc.tmpl +2 -2
  176. package/dot_config/waybar/style.css.tmpl +2 -2
  177. package/dot_config/wezterm/wezterm.lua.tmpl +3 -3
  178. package/dot_config/zsh/dot_zshrc.tmpl +207 -17
  179. package/dot_config/zsh/rc.d/00-alias-shims.zsh +28 -6
  180. package/dot_config/zsh/rc.d/30-options.zsh.tmpl +27 -7
  181. package/dot_local/bin/executable_bm +2 -0
  182. package/dot_local/bin/executable_dot +56 -9
  183. package/dot_local/bin/executable_dot-bootstrap +0 -1
  184. package/dot_local/bin/executable_dot-load-benchmark +1 -1
  185. package/dot_local/bin/executable_dot-theme-sync +8 -8
  186. package/dot_local/bin/executable_notify +2 -0
  187. package/dot_local/bin/executable_open +2 -0
  188. package/dot_local/bin/executable_tour +4 -2
  189. package/dot_local/bin/executable_up +3 -1
  190. package/dot_local/share/man/man1/dot.1 +1 -1
  191. package/dot_local/share/zsh/completions/_dot +4 -0
  192. package/install.sh +53 -38
  193. package/package.json +1 -1
  194. package/scripts/ci/check-dangerous-chmod.sh +19 -0
  195. package/scripts/ci/check-deps-dev.sh +236 -0
  196. package/scripts/ci/check-insecure-tls.sh +61 -0
  197. package/scripts/ci/check-regression-traceability.sh +67 -0
  198. package/scripts/ci/check-shell-preamble.sh +106 -0
  199. package/scripts/ci/dot-cli-startup-bench.sh +126 -0
  200. package/scripts/ci/install-chezmoi-verified.sh +4 -1
  201. package/scripts/ci/lint-reusable-pins.sh +78 -0
  202. package/scripts/ci/run-coverage.sh +451 -0
  203. package/scripts/ci/validate-chezmoidata.sh +25 -0
  204. package/scripts/ci/windows-smoke-test.ps1 +136 -0
  205. package/scripts/diagnostics/doctor.sh +203 -5
  206. package/scripts/diagnostics/drift-dashboard.sh +177 -13
  207. package/scripts/diagnostics/health.sh +21 -4
  208. package/scripts/diagnostics/perf.sh +304 -77
  209. package/scripts/diagnostics/workstation-attestation.sh +6 -1
  210. package/scripts/dot/commands/agent.sh +33 -27
  211. package/scripts/dot/commands/agents.sh +325 -0
  212. package/scripts/dot/commands/ai.sh +75 -10
  213. package/scripts/dot/commands/aliases.sh +10 -8
  214. package/scripts/dot/commands/core.sh +10 -4
  215. package/scripts/dot/commands/fleet.sh +278 -3
  216. package/scripts/dot/commands/init.sh +184 -0
  217. package/scripts/dot/commands/meta.sh +7 -4
  218. package/scripts/dot/commands/registry.sh +263 -0
  219. package/scripts/dot/commands/tools.sh +49 -1
  220. package/scripts/dot/lib/bento.sh +2 -1
  221. package/scripts/dot/lib/log.sh +6 -0
  222. package/scripts/dot/lib/platform.sh +22 -8
  223. package/scripts/dot/lib/ui.sh +145 -2
  224. package/scripts/dot/lib/utils.sh +6 -1
  225. package/scripts/git-hooks/pre-commit-audit.sh +1 -1
  226. package/scripts/git-hooks/pre-push +66 -3
  227. package/scripts/lib/secrets_provider.sh +32 -6
  228. package/scripts/ops/heal-chezmoi.sh +41 -6
  229. package/scripts/ops/rollback.sh +14 -0
  230. package/scripts/qa/powershell-contract.ps1 +95 -0
  231. package/scripts/security/check-disclosure-key-expiry.sh +110 -0
  232. package/scripts/security/lock-configs.sh +11 -2
  233. package/scripts/theme/merge-wallpaper.sh +4 -0
  234. package/scripts/theme/switch.sh +20 -10
  235. package/scripts/version-sync.sh +3 -0
  236. package/dot_config/atuin/config.toml +0 -40
  237. package/dot_local/bin/__pycache__/executable_dot-load-benchmark-ptycpython-312.pyc +0 -0
@@ -64,7 +64,7 @@ fi
64
64
  {{- end }}
65
65
  {{- /* When node_manager = "mise", Node.js is handled by mise activate in dot_zshrc.tmpl */}}
66
66
 
67
- # Completions: pre-warmed by `dot prewarm`, generated on-demand as fallback
67
+ # Completions: generated on-demand on first interactive shell and cached
68
68
  if [[ "${DOTFILES_FAST:-0}" != "1" ]] && [[ "${DOTFILES_ULTRA_FAST:-0}" != "1" ]]; then
69
69
  [[ ! -f "${ZSH_COMPLETIONS_DIR}/_gh" ]] && command -v gh >/dev/null &&
70
70
  command gh completion -s zsh >| "${ZSH_COMPLETIONS_DIR}/_gh"
@@ -112,24 +112,44 @@ if [[ "${DOTFILES_FAST:-0}" != "1" ]] && [[ "${DOTFILES_ULTRA_FAST:-0}" != "1" ]
112
112
  }
113
113
  sdk() { _lazy_load_sdkman; sdk "$@"; }
114
114
  fi
115
- # Defer compinit to first prompt — opt-in for max performance
115
+ # Defer compinit to first prompt — opt-in for max performance.
116
+ #
117
+ # Cache lifecycle (closes #864):
118
+ # * dump path lives at $XDG_CACHE_HOME/zsh/zcompdump-$ZSH_VERSION so
119
+ # the user-state directory is clean (and zsh's own search picks up
120
+ # `.zwc` siblings automatically — non-laptop profiles get the
121
+ # benefit even without re-running compinit).
122
+ # * `compinit -C` (skip security-check, use the cached dump) is used
123
+ # when the dump is fresh (< 24 h); full `compinit` rebuilds when
124
+ # the dump is older.
125
+ # * The dump is `zcompile`d in the background after each rebuild so
126
+ # subsequent shells load the bytecode form directly.
127
+ # * The fpath corpus itself is precompiled at chezmoi-apply time by
128
+ # `run_onchange_after_zcompile-completions.sh.tmpl` — that runs
129
+ # once per fpath change, not per shell start.
116
130
  : ${DOTFILES_ENABLE_COMPINIT:=0}
117
131
  : ${DOTFILES_DEFER_COMPINIT:=1}
132
+
133
+ _DOTFILES_ZCOMPDUMP="${XDG_CACHE_HOME:-${HOME}/.cache}/zsh/zcompdump-${ZSH_VERSION:-${ZSH_NAME:-unknown}}"
134
+
118
135
  if [[ "${DOTFILES_ENABLE_COMPINIT}" == "1" ]] && [[ "${DOTFILES_FAST:-0}" != "1" ]] && [[ "${DOTFILES_ULTRA_FAST:-0}" != "1" ]]; then
119
136
  autoload -Uz compinit
137
+ [[ -d "${_DOTFILES_ZCOMPDUMP:h}" ]] || mkdir -p "${_DOTFILES_ZCOMPDUMP:h}"
138
+
120
139
  _deferred_compinit() {
121
140
  if [[ "${DOTFILES_DEFER_COMPINIT}" == "1" ]]; then
122
141
  _dotfiles_del_preexec _deferred_compinit
123
142
  else
124
143
  _dotfiles_del_precmd _deferred_compinit
125
144
  fi
126
- if [[ -n ${ZDOTDIR}/.zcompdump(#qN.mh+24) ]]; then
127
- compinit
145
+ # Fresh dump (< 24 h) → use cached fast path; otherwise rebuild.
146
+ if [[ -n ${_DOTFILES_ZCOMPDUMP}(#qN.mh+24) ]]; then
147
+ compinit -d "${_DOTFILES_ZCOMPDUMP}"
128
148
  else
129
- compinit -C
149
+ compinit -C -d "${_DOTFILES_ZCOMPDUMP}"
130
150
  fi
131
- # Compile zcompdump to bytecode in background for faster subsequent loads
132
- { [[ ! -f "${ZDOTDIR}/.zcompdump.zwc" || "${ZDOTDIR}/.zcompdump" -nt "${ZDOTDIR}/.zcompdump.zwc" ]] && zcompile "${ZDOTDIR}/.zcompdump" } &!
151
+ # Compile to bytecode in background for faster subsequent loads
152
+ { [[ ! -f "${_DOTFILES_ZCOMPDUMP}.zwc" || "${_DOTFILES_ZCOMPDUMP}" -nt "${_DOTFILES_ZCOMPDUMP}.zwc" ]] && zcompile "${_DOTFILES_ZCOMPDUMP}" } &!
133
153
  }
134
154
  if [[ "${DOTFILES_DEFER_COMPINIT}" == "1" ]]; then
135
155
  _dotfiles_add_preexec _deferred_compinit
@@ -2,6 +2,8 @@
2
2
  # Universal directory bookmarking with history support
3
3
  # Works across Bash, Zsh, and Fish
4
4
 
5
+ set -eu
6
+
5
7
  # Cross-platform sed in-place (BSD vs GNU)
6
8
  _sed_i() {
7
9
  if sed --version >/dev/null 2>&1; then
@@ -3,7 +3,7 @@
3
3
  # Copyright (c) 2015-2026 Dotfiles. All rights reserved.
4
4
  set -euo pipefail
5
5
 
6
- # Dotfiles CLI Entry Point - v0.2.500
6
+ # Dotfiles CLI Entry Point - v0.2.502
7
7
 
8
8
  # Ensure XDG Base Directory variables are set
9
9
  export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
@@ -21,7 +21,7 @@ if [ -e "${HOME}/.nix-profile/etc/profile.d/nix.sh" ]; then
21
21
  . "${HOME}/.nix-profile/etc/profile.d/nix.sh"
22
22
  fi
23
23
 
24
- VERSION="0.2.500"
24
+ VERSION="0.2.502"
25
25
 
26
26
  COMMAND="${1:-}"
27
27
  if [ -n "${1:-}" ]; then
@@ -160,6 +160,7 @@ Start Here|sync|Apply dotfiles to this machine.|Use after clone or after changes
160
160
  Start Here|doctor|Check the environment and surface issues.|Use when something feels off.
161
161
  Start Here|learn|Open the guided tour.|Best first stop for new users.
162
162
  Start Here|help|Show the overview or help for one command.|Use `dot help <command>` for detail.
163
+ Daily Use|init|Bootstrap a foreign dotfiles repo through chezmoi + dot.|Usage: `dot init <github-user>`.
163
164
  Daily Use|status|Show local drift.|See what changed since the last apply.
164
165
  Daily Use|diff|Preview pending changes.|Safe way to inspect before applying.
165
166
  Daily Use|edit|Open the source directory.|Use the configured editor.
@@ -172,6 +173,8 @@ AI and Agents|ai|Show installed AI tools.|Launches the AI status view.
172
173
  AI and Agents|mcp|Inspect MCP policy and registry.|Supports `--strict|-s` and `--json|-j`.
173
174
  AI and Agents|mode|Show or set the agent profile.|Profiles: ask, plan, apply, audit.
174
175
  AI and Agents|agent|Show agent metadata, logs, checkpoints, and conformance.|Use for card, log, checkpoint, and conformance.
176
+ AI and Agents|agents|Multi-harness agent context (AGENTS.md sync, Cursor/Codex stubs).|Subcommands: list, check, render.
177
+ Fleet|registry|Browse reusable dotfile modules from the dot registry.|Subcommands: list, search, info, install, url, set-url.
175
178
  Fleet|fleet|Show fleet node status, drift, and namespace.|Enterprise fleet management.
176
179
  Configuration|env|Show managed tool versions.|Backed by mise.
177
180
  Configuration|profile|Show or switch the active profile.|Use for machine-specific behavior.
@@ -269,7 +272,6 @@ health|Run the health dashboard with optional fixes.|dot health -v\ndot health -
269
272
  perf|Measure shell performance and emit structured timing.|dot perf -j -r 1\ndot perf -p\ndot perf -t 200
270
273
  security-score|Assess workstation security posture.|dot security-score -j\ndot security-score -q
271
274
  snapshot|Capture the current workstation snapshot.|dot snapshot -b\ndot snapshot -b -f
272
- verify|Run post-change verification checks.|dot verify\ndot verify -s
273
275
  restore|Restore from a backup or git ref.|dot restore -l\ndot restore -L\ndot restore -g HEAD~1
274
276
  rollback|Restore a previous configuration snapshot.|dot rollback
275
277
  lint|Run shell quality checks for the repo.|dot lint\ndot lint -c\ndot lint -f
@@ -304,15 +306,14 @@ _dot_command_routes() {
304
306
  cat <<'EOF'
305
307
  sync|core
306
308
  apply|core
309
+ init|init
307
310
  update|core
308
311
  add|core
309
312
  diff|core
310
313
  status|core
311
- remove|core
312
314
  cd|core
313
315
  edit|core
314
316
  commit|core
315
- clean-cache|core
316
317
  doctor|diagnostics
317
318
  scorecard|diagnostics
318
319
  score|diagnostics
@@ -328,12 +329,10 @@ heal|diagnostics
328
329
  health|diagnostics
329
330
  health-check|diagnostics
330
331
  smoke-test|diagnostics
331
- verify|diagnostics
332
332
  attest|diagnostics
333
333
  attestation|diagnostics
334
334
  security-score|diagnostics
335
335
  drift|diagnostics
336
- benchmark|diagnostics
337
336
  intelligence|diagnostics
338
337
  conflicts|diagnostics
339
338
  locks|diagnostics
@@ -344,12 +343,19 @@ ai-setup|ai
344
343
  ai-query|ai
345
344
  cl|ai
346
345
  claude|ai
346
+ codex|ai
347
+ copilot|ai
347
348
  gemini|ai
349
+ goose|ai
348
350
  kiro|ai
349
351
  sgpt|ai
350
352
  ollama|ai
351
353
  opencode|ai
352
354
  aider|ai
355
+ autohand|ai
356
+ vibe|ai
357
+ qwen|ai
358
+ zai|ai
353
359
  env|tools
354
360
  profile|tools
355
361
  tools|tools
@@ -378,7 +384,6 @@ lock-screen|security
378
384
  usb-safety|security
379
385
  upgrade|meta
380
386
  cache-refresh|meta
381
- prewarm|meta
382
387
  docs|meta
383
388
  learn|meta
384
389
  keys|meta
@@ -386,7 +391,9 @@ sandbox|meta
386
391
  mcp|meta
387
392
  mode|meta
388
393
  agent|meta
394
+ agents|agents
389
395
  fleet|fleet
396
+ registry|registry
390
397
  patterns|patterns
391
398
  manual|manual
392
399
  search|search
@@ -532,6 +539,8 @@ if [[ -z "$COMMAND" ]]; then
532
539
  exit 0
533
540
  fi
534
541
 
542
+ # `|| true` is intentional: an unknown command yields an empty route, which falls
543
+ # through the case below into the user-command path that emits the proper error.
535
544
  route="$(_dot_command_route "$COMMAND" || true)"
536
545
 
537
546
  case "$route" in
@@ -539,6 +548,42 @@ case "$route" in
539
548
  _dispatch "$route" "$@"
540
549
  ;;
541
550
 
551
+ agents)
552
+ if [[ -n "$_SOURCE_DIR" ]] && [[ -f "$_SOURCE_DIR/scripts/dot/commands/agents.sh" ]]; then
553
+ # shellcheck disable=SC1091
554
+ source "$_SOURCE_DIR/scripts/dot/commands/agents.sh"
555
+ cmd_agents "$@"
556
+ exit $?
557
+ else
558
+ ui_fail "agents.sh not found"
559
+ exit 1
560
+ fi
561
+ ;;
562
+
563
+ init)
564
+ if [[ -n "$_SOURCE_DIR" ]] && [[ -f "$_SOURCE_DIR/scripts/dot/commands/init.sh" ]]; then
565
+ # shellcheck disable=SC1091
566
+ source "$_SOURCE_DIR/scripts/dot/commands/init.sh"
567
+ cmd_init "$@"
568
+ exit $?
569
+ else
570
+ ui_fail "init.sh not found"
571
+ exit 1
572
+ fi
573
+ ;;
574
+
575
+ registry)
576
+ if [[ -n "$_SOURCE_DIR" ]] && [[ -f "$_SOURCE_DIR/scripts/dot/commands/registry.sh" ]]; then
577
+ # shellcheck disable=SC1091
578
+ source "$_SOURCE_DIR/scripts/dot/commands/registry.sh"
579
+ cmd_registry "$@"
580
+ exit $?
581
+ else
582
+ ui_fail "registry.sh not found"
583
+ exit 1
584
+ fi
585
+ ;;
586
+
542
587
  manual)
543
588
  if [[ -n "$_SOURCE_DIR" ]] && [[ -f "$_SOURCE_DIR/scripts/dot/commands/manual.sh" ]]; then
544
589
  exec bash "$_SOURCE_DIR/scripts/dot/commands/manual.sh" "$@"
@@ -579,7 +624,9 @@ case "$route" in
579
624
  *)
580
625
  _user_cmd="${XDG_CONFIG_HOME:-$HOME/.config}/dotfiles/commands/${COMMAND}.sh"
581
626
  if [[ -f "$_user_cmd" ]]; then
582
- source "$_user_cmd" "$@"
627
+ # Run in a subshell so a user `exit` doesn't kill the dot CLI.
628
+ (source "$_user_cmd" "$@")
629
+ exit $?
583
630
  else
584
631
  echo "Unknown command: ${COMMAND:-}" >&2
585
632
  echo "Run 'dot help' for available commands." >&2
@@ -30,7 +30,6 @@ step "Starting Deterministic Bootstrap (v0.2.493 Frontier)"
30
30
  # 1. Install Nix (if not present)
31
31
  if ! command -v nix >/dev/null 2>&1; then
32
32
  step "Installing Nix Package Manager..."
33
- local nix_installer
34
33
  nix_installer=$(umask 077 && mktemp)
35
34
  if ! curl -fsSL -o "$nix_installer" https://nixos.org/nix/install; then
36
35
  rm -f "$nix_installer"
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- set -e
2
+ set -euo pipefail
3
3
 
4
4
  # Measure time to load heavy layers in a fresh interactive shell
5
5
  # Usage: dot-load-benchmark [runs]
@@ -466,14 +466,14 @@ reload_desktop() {
466
466
  local highlight_color
467
467
  case "$accent" in
468
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" ;;
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
477
  esac
478
478
 
479
479
  if defaults write -g AppleAccentColor -int "$accent" >/dev/null 2>&1 &&
@@ -2,6 +2,8 @@
2
2
  # Universal desktop notification (notify)
3
3
  # Supports macOS (osascript), Linux (notify-send), and WSL (powershell)
4
4
 
5
+ set -eu
6
+
5
7
  title="${1:-Notification}"
6
8
  message="${2:-}"
7
9
 
@@ -2,6 +2,8 @@
2
2
  # Universal file opener (open)
3
3
  # Maps to open (macOS), xdg-open (Linux), and explorer.exe (WSL)
4
4
 
5
+ set -eu
6
+
5
7
  target="${1:-.}"
6
8
 
7
9
  # Helper for rich feedback if TTY is present
@@ -1,6 +1,8 @@
1
1
  #!/bin/sh
2
2
  # Interactive Tour using Gum
3
- # Part of Dotfiles v0.2.500
3
+ # Part of Dotfiles v0.2.502
4
+
5
+ set -eu
4
6
 
5
7
  if ! command -v gum >/dev/null; then
6
8
  echo "Error: 'gum' is not installed."
@@ -37,7 +39,7 @@ banner='██████╗ ██████╗ ████████╗
37
39
  ██████╔╝╚██████╔╝ ██║ ██║ ██║███████╗███████╗███████║
38
40
  ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝
39
41
 
40
- v0.2.500 · Infrastructure‑grade shell environment'
42
+ v0.2.502 · Infrastructure‑grade shell environment'
41
43
 
42
44
  gum style \
43
45
  --foreground 212 --border-foreground 212 --border double \
@@ -2,7 +2,9 @@
2
2
  # Universal directory navigation with history support
3
3
  # Works across Bash, Zsh, and Fish
4
4
 
5
- levels=$1
5
+ set -eu
6
+
7
+ levels=${1:-1}
6
8
  target=".."
7
9
 
8
10
  case "$levels" in
@@ -1,4 +1,4 @@
1
- .TH DOT 1 "April 2026" "dotfiles v0.2.500" "User Commands"
1
+ .TH DOT 1 "May 2026" "dotfiles v0.2.502" "User Commands"
2
2
  .SH NAME
3
3
  dot \- dotfiles management CLI
4
4
  .SH SYNOPSIS
@@ -29,6 +29,10 @@ _dot() {
29
29
  'edit:Open chezmoi source in \$EDITOR'
30
30
  'commit:AI-powered conventional commit'
31
31
  'patterns:Manage AI steering patterns'
32
+ 'init:Bootstrap a foreign dotfiles repo through chezmoi + dot'
33
+ 'agents:Multi-harness agent context (AGENTS.md sync, Cursor/Codex stubs)'
34
+ 'manual:Open or download the multi-format manual'
35
+ 'search:Find commands by keyword'
32
36
 
33
37
  # Diagnostics
34
38
  'doctor:Check system health and configuration'
package/install.sh CHANGED
@@ -52,7 +52,7 @@ show_help() {
52
52
  Usage: install.sh [version] [options]
53
53
 
54
54
  Arguments:
55
- version The version (tag or branch) to install (default: v0.2.500)
55
+ version The version (tag or branch) to install (default: v0.2.502)
56
56
 
57
57
  Options:
58
58
  --help Show this help message
@@ -64,7 +64,7 @@ EOF
64
64
  }
65
65
 
66
66
  main() {
67
- local version="v0.2.500"
67
+ local version="v0.2.502"
68
68
  local version_set=0
69
69
  local minimal=0
70
70
  local _cleanup_files=()
@@ -72,20 +72,28 @@ main() {
72
72
 
73
73
  for arg in "$@"; do
74
74
  case "$arg" in
75
- --help)
75
+ -h | --help)
76
76
  show_help
77
77
  exit 0
78
78
  ;;
79
79
  --silent) export DOTFILES_SILENT=1 ;;
80
80
  --force) export DOTFILES_NONINTERACTIVE=1 ;;
81
81
  --minimal) minimal=1 ;;
82
- --*)
82
+ -*)
83
+ # Catch single-dash and double-dash unknowns the same way.
83
84
  error "Unknown option: $arg"
84
85
  ;;
85
86
  *)
86
87
  if [[ $version_set -eq 1 ]]; then
87
88
  error "Multiple versions specified: $version and $arg"
88
89
  fi
90
+ # Validate the positional looks like a semver (with or without
91
+ # leading v). Reject garbage early so an unknown positional
92
+ # like `foobar` doesn't trigger a 30s+ network download attempt.
93
+ # Caught by the install.sh fuzz harness (#881).
94
+ if [[ ! "$arg" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+([-+][a-zA-Z0-9.-]+)?$ ]]; then
95
+ error "Unrecognized positional argument '$arg' — expected a semver version (e.g. v0.2.502)."
96
+ fi
89
97
  version="$arg"
90
98
  version_set=1
91
99
  ;;
@@ -127,10 +135,29 @@ main() {
127
135
  sudo mkdir -p /etc/apt/keyrings
128
136
  curl -fsSL https://repo.charm.sh/apt/gpg.key |
129
137
  sudo gpg --batch --yes --dearmor -o /etc/apt/keyrings/charm.gpg
130
- # Verify Charm GPG key fingerprint
131
- if ! gpg --no-default-keyring --keyring /etc/apt/keyrings/charm.gpg \
132
- --list-keys --with-colons 2>/dev/null | grep -q "fid:"; then
133
- echo "Warning: Could not verify Charm GPG key" >&2
138
+ # Pin the Charm GPG key fingerprint — a DNS attacker swapping
139
+ # repo.charm.sh/apt/gpg.key for a forged key with the same uid
140
+ # would otherwise pass the prior "any fid: present" check.
141
+ # Pinned value taken from https://repo.charm.sh/apt/gpg.key on
142
+ # 2026-05-16. If Charm rotates, update this and call it out in
143
+ # CHANGELOG.md.
144
+ CHARM_GPG_EXPECTED_FPR="C026D31B92F9BBE91D5DB75AB07AE17C9E0A6585"
145
+ charm_actual_fpr="$(gpg --no-default-keyring \
146
+ --keyring /etc/apt/keyrings/charm.gpg \
147
+ --with-colons --fingerprint 2>/dev/null |
148
+ awk -F: '/^fpr:/{print $10; exit}')"
149
+ if [[ -z "$charm_actual_fpr" ]]; then
150
+ echo "Error: Could not extract Charm GPG fingerprint — aborting" >&2
151
+ sudo rm -f /etc/apt/keyrings/charm.gpg
152
+ return 1
153
+ fi
154
+ if [[ "$charm_actual_fpr" != "$CHARM_GPG_EXPECTED_FPR" ]]; then
155
+ echo "Error: Charm GPG fingerprint mismatch" >&2
156
+ echo " expected: $CHARM_GPG_EXPECTED_FPR" >&2
157
+ echo " got: $charm_actual_fpr" >&2
158
+ echo " aborting (possible DNS / keyserver hijack)" >&2
159
+ sudo rm -f /etc/apt/keyrings/charm.gpg
160
+ return 1
134
161
  fi
135
162
  echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" | sudo tee /etc/apt/sources.list.d/charm.list
136
163
  sudo apt-get update && sudo apt-get install gum -y >/dev/null 2>&1
@@ -152,43 +179,31 @@ main() {
152
179
  mkdir -p "$bin_dir"
153
180
  echo " Installing chezmoi via binary download..."
154
181
 
155
- # Prefer verified installer with SHA256 checksum when available
182
+ # Prefer verified installer with SHA256 checksum when available.
183
+ # When verification fails or the verified installer isn't present
184
+ # we refuse to bootstrap rather than silently downloading and
185
+ # executing an unverified script (the previous fall-back to
186
+ # `get.chezmoi.io` was an unsigned bootstrap and a security hole).
156
187
  local verified_installer
157
188
  verified_installer="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/ci/install-chezmoi-verified.sh"
158
189
  if [[ -x "$verified_installer" ]] || [[ -f "$verified_installer" ]]; then
159
190
  echo " Using checksum-verified installer..."
160
191
  if ! bash "$verified_installer" "${CHEZMOI_VERSION:-2.47.1}" "$bin_dir"; then
161
- echo " Verified installer failed, falling back to get.chezmoi.io" >&2
162
- else
163
- return 0
192
+ echo "" >&2
193
+ echo " The verified chezmoi installer failed." >&2
194
+ echo " Refusing to fall back to an unverified bootstrap path." >&2
195
+ echo " Install chezmoi manually from a trusted source, then re-run install.sh:" >&2
196
+ echo " macOS: brew install chezmoi" >&2
197
+ echo " Linux: see https://www.chezmoi.io/install/" >&2
198
+ return 1
164
199
  fi
200
+ return 0
165
201
  fi
166
-
167
- # Fallback: download installer with size/shebang validation
168
- local installer
169
- installer=$(umask 077 && mktemp)
170
- if ! curl -fsSL -o "$installer" https://get.chezmoi.io; then
171
- rm -f "$installer"
172
- echo " Failed to download chezmoi installer" >&2
173
- return 1
174
- fi
175
- # Validate: must be a shell script and not suspiciously large
176
- if [[ "$(wc -c <"$installer")" -gt 102400 ]]; then
177
- rm -f "$installer"
178
- echo " Chezmoi installer suspiciously large. Aborting." >&2
179
- return 1
180
- fi
181
- if ! head -1 "$installer" | grep -q '^#!/'; then
182
- rm -f "$installer"
183
- echo " Chezmoi installer doesn't look like a shell script. Aborting." >&2
184
- return 1
185
- fi
186
- if ! BINDIR="$bin_dir" sh "$installer"; then
187
- rm -f "$installer"
188
- echo " chezmoi binary installer failed" >&2
189
- return 1
190
- fi
191
- rm -f "$installer"
202
+ echo "" >&2
203
+ echo " scripts/ci/install-chezmoi-verified.sh is missing; cannot verify chezmoi bootstrap." >&2
204
+ echo " Install chezmoi manually (brew install chezmoi / official binary)" >&2
205
+ echo " and re-run install.sh." >&2
206
+ return 1
192
207
  fi
193
208
  }
194
209
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sebastienrousseau/dotfiles",
3
- "version": "0.2.500",
3
+ "version": "0.2.502",
4
4
  "description": "The Trusted Shell Platform — Universal dotfiles managed by Chezmoi. Features Bash & Zsh for macOS, Linux & WSL. Rust modern tooling & enterprise-grade security.",
5
5
  "main": "install.sh",
6
6
  "bin": {
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+ # Copyright (c) 2015-2026 Dotfiles. All rights reserved.
3
+ # =============================================================================
4
+ # check-dangerous-chmod.sh — block `chmod 777` / `chmod 666` patterns
5
+ # from landing in shell scripts.
6
+ #
7
+ # Invoked as a pre-commit local hook (no filename args; scans the repo).
8
+ # Extracted from `config/pre-commit-config.yaml` under #866.
9
+ # =============================================================================
10
+
11
+ set -euo pipefail
12
+
13
+ PATTERN='^[[:space:]]*chmod[[:space:]]+(-R[[:space:]]+)?(777|666)'
14
+
15
+ if grep -rn --include='*.sh' -E "$PATTERN" . 2>/dev/null | grep -v '^Binary'; then
16
+ echo "ERROR: Dangerous chmod patterns found (777 or 666)." >&2
17
+ echo "Use the minimum permissions actually required; document any exception." >&2
18
+ exit 1
19
+ fi