@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
@@ -1,9 +1,11 @@
1
1
  Place your Linux boot logo image here.
2
2
 
3
3
  Default path used by the script:
4
+
4
5
  - ~/.config/dotfiles/boot/logo.png
5
6
 
6
7
  Run:
8
+
7
9
  - sudo ~/.dotfiles/scripts/theme/install-boot-logo.sh --apply
8
10
 
9
11
  ---
@@ -1,9 +1,11 @@
1
1
  Place your GRUB theme files here.
2
2
 
3
3
  Default path used by the script:
4
+
4
5
  - ~/.config/dotfiles/grub/theme
5
6
 
6
7
  Run:
8
+
7
9
  - sudo ~/.dotfiles/scripts/theme/install-grub-theme.sh --apply
8
10
 
9
11
  ---
@@ -1,9 +1,11 @@
1
1
  Place your lock screen icon here.
2
2
 
3
3
  Default path used by the script:
4
+
4
5
  - ~/.config/dotfiles/lock/icon.png
5
6
 
6
7
  Example:
8
+
7
9
  - swaylock --image ~/.config/dotfiles/lock/icon.png
8
10
 
9
11
  ---
@@ -0,0 +1,4 @@
1
+ # Shadow vendor `/opt/homebrew/share/fish/vendor_conf.d/direnv.fish`.
2
+ # fish dedupes conf.d files by basename β€” user conf.d wins. Direnv is
3
+ # loaded lazily by `_dotfiles_async_init` in init.fish via `_cached_eval
4
+ # direnv hook fish`, avoiding the unconditional cost on every shell start.
@@ -55,6 +55,11 @@ if test "$DOTFILES_ARTIFACT_MODE" = "0"; and command -v starship >/dev/null
55
55
  if not _dotfiles_source_cached_init starship starship-init.fish
56
56
  starship init fish | source
57
57
  end
58
+ # Transient Prompt: collapse past prompts to the [character] glyph
59
+ # after Enter, reducing scrollback noise.
60
+ if functions -q enable_transience
61
+ enable_transience
62
+ end
58
63
  end
59
64
 
60
65
  # ── Lazy Hydration (deferred to first prompt) ────────────────────
@@ -124,6 +129,7 @@ end
124
129
 
125
130
  function _dotfiles_trigger_hydration --on-event fish_prompt
126
131
  functions -e _dotfiles_trigger_hydration
132
+ functions -e _dotfiles_trigger_hydration_on_missing
127
133
  _dotfiles_async_init
128
134
  if test "$DOTFILES_ARTIFACT_MODE" = "1"
129
135
  begin
@@ -133,6 +139,21 @@ function _dotfiles_trigger_hydration --on-event fish_prompt
133
139
  end
134
140
  end
135
141
 
142
+ # Belt-and-braces: if the user types an unknown command BEFORE the
143
+ # first prompt fires (e.g. `fish -ic 'foo'` from a script that
144
+ # doesn't render a prompt), trigger the same lazy-layer load via
145
+ # fish_command_not_found. The hydration function may already have
146
+ # fired and removed itself β€” guard against double-load. (Closes
147
+ # AC#2 of #880; fish's analogue to zsh's function_not_found.)
148
+ function _dotfiles_trigger_hydration_on_missing --on-event fish_command_not_found
149
+ functions -e _dotfiles_trigger_hydration_on_missing
150
+ functions -e _dotfiles_trigger_hydration
151
+ _dotfiles_async_init
152
+ # After hydration, the command may now resolve; let fish's default
153
+ # not-found handler print the standard message for whatever the
154
+ # user typed.
155
+ end
156
+
136
157
  # ── Keybindings (Fish 4.x enhanced) ─────────────────────────────
137
158
  bind ctrl-backspace backward-kill-word
138
159
  bind alt-enter 'commandline -f accept-autosuggestion; commandline -f execute'
@@ -0,0 +1,5 @@
1
+ # Shadow vendor `/opt/homebrew/share/fish/vendor_conf.d/mise-activate.fish`.
2
+ # fish dedupes conf.d files by basename β€” user conf.d wins. Mise is loaded
3
+ # lazily by `_dotfiles_async_init` in init.fish via `_cached_eval mise
4
+ # activate fish`, which is ~10Γ— faster than the vendor's eager hook-env
5
+ # call on every shell start (saves ~140ms in fish startup).
@@ -1,14 +1,43 @@
1
- # _cached_eval β€” Cache tool init output with binary mtime invalidation
2
- # Mirrors the bash/zsh _cached_eval pattern for Fish
1
+ # _cached_eval β€” Cache tool init output with binary mtime invalidation.
2
+ # Mirrors the bash/zsh _cached_eval pattern for Fish.
3
3
  #
4
4
  # Usage: _cached_eval <tool_binary> <init_args...>
5
5
  # Example: _cached_eval starship init fish
6
6
  # _cached_eval zoxide init fish
7
7
  #
8
8
  # Cache files stored in $XDG_CACHE_HOME/fish/ (or ~/.cache/fish/)
9
- # Cache invalidated when binary mtime changes (e.g. after upgrade)
9
+ # Cache invalidated when binary mtime, realpath, or any file-path arg
10
+ # changes (e.g. after upgrade or PATH-shadow swap).
11
+ #
12
+ # Env knobs:
13
+ # EVALCACHE_DISABLE=true bypass cache read AND write (debug aid)
14
+ # EVALCACHE_TIMING=1 log per-call timing for `dot perf --by-tool`
10
15
 
11
- function _cached_eval --description 'Cache and source tool init output'
16
+ function _cached_eval_log_timing --description 'Append a timing event for dot perf --by-tool'
17
+ set -l label $argv[1]
18
+ set -l t0 $argv[2]
19
+ set -l t1 $argv[3]
20
+ set -l rc $argv[4]
21
+ set -l shell fish
22
+ if test (count $argv) -ge 5
23
+ set shell $argv[5]
24
+ end
25
+ set -l log_dir (set -q XDG_STATE_HOME; and echo $XDG_STATE_HOME; or echo "$HOME/.local/state")/dotfiles
26
+ mkdir -p "$log_dir" 2>/dev/null; or return 0
27
+ set -l logfile "$log_dir/eval-timings.jsonl"
28
+ test -f "$logfile"; or touch "$logfile" 2>/dev/null; or return 0
29
+ # nanoseconds -> milliseconds
30
+ set -l ms 0
31
+ if test -n "$t0"; and test -n "$t1"
32
+ set ms (math --scale=0 "($t1 - $t0) / 1000000") 2>/dev/null; or set ms 0
33
+ end
34
+ set -l ts (date -u +%Y-%m-%dT%H:%M:%SZ)
35
+ printf '{"ts":"%s","shell":"%s","label":"%s","ms":%s,"rc":%s}\n' \
36
+ "$ts" "$shell" "$label" "$ms" "$rc" \
37
+ >>"$logfile" 2>/dev/null; or true
38
+ end
39
+
40
+ function _cached_eval_impl
12
41
  set -l tool_name $argv[1]
13
42
  if test -z "$tool_name"
14
43
  echo "_cached_eval: usage: _cached_eval <tool> <init args...>" >&2
@@ -21,34 +50,61 @@ function _cached_eval --description 'Cache and source tool init output'
21
50
  return 1
22
51
  end
23
52
 
53
+ # Debug bypass: skip cache read AND write entirely.
54
+ if test "$EVALCACHE_DISABLE" = true
55
+ command $argv 2>/dev/null | source
56
+ return $status
57
+ end
58
+
24
59
  set -l cache_dir (set -q XDG_CACHE_HOME; and echo $XDG_CACHE_HOME; or echo "$HOME/.cache")/fish
25
60
  set -l cache_file "$cache_dir/$tool_name-init.fish"
26
- set -l mtime_file "$cache_dir/$tool_name-init.mtime"
61
+ set -l pin_file "$cache_dir/$tool_name-init.bin"
27
62
 
28
63
  mkdir -p "$cache_dir"
29
64
 
30
- # Check if cache is stale (binary newer than cache)
65
+ set -l real_bin (realpath -- "$tool_path" 2>/dev/null; or echo "$tool_path")
66
+
67
+ # Cache valid when: present non-empty, binary not newer, recorded realpath
68
+ # still matches, and no file-path argument modified since cache write.
31
69
  set -l stale 0
32
- if not test -f "$cache_file"
33
- set stale 1
34
- else if not test -f "$mtime_file"
70
+ if not test -s "$cache_file"
35
71
  set stale 1
36
72
  else if test "$tool_path" -nt "$cache_file"
37
73
  set stale 1
74
+ else if test -f "$pin_file"
75
+ set -l pinned (cat "$pin_file" 2>/dev/null)
76
+ if test -n "$pinned"; and test "$pinned" != "$real_bin"
77
+ set stale 1
78
+ end
79
+ end
80
+ if test "$stale" = 0
81
+ for arg in $argv[2..]
82
+ if test -f "$arg"; and test "$arg" -nt "$cache_file"
83
+ set stale 1
84
+ break
85
+ end
86
+ end
38
87
  end
39
88
 
40
89
  # Regenerate cache if stale
41
90
  if test "$stale" = 1
42
91
  set -l init_output (command $argv 2>/dev/null)
92
+ set -l rc $status
93
+ if test "$rc" -ne 0
94
+ echo "[WARN] $tool_name init exited $rc; not caching" >&2
95
+ return $rc
96
+ end
43
97
  # Reject suspicious patterns indicating malicious payloads
44
98
  if string match -rq 'curl\s.*\|\s*(ba)?sh|wget\s.*\|\s*(ba)?sh|nc\s+-e|/dev/tcp/|base64\s+-d\s*\|' -- "$init_output"
45
99
  echo "[WARN] Suspicious output from $tool_name init, skipping" >&2
46
100
  return 1
47
101
  end
48
- set -l tmp_cache "$cache_file.tmp.%self"
102
+ set -l tmp_cache "$cache_file.tmp.$fish_pid"
49
103
  printf '%s\n' $init_output >"$tmp_cache"
50
104
  mv "$tmp_cache" "$cache_file" # atomic rename
51
- echo "$tool_path" >"$mtime_file"
105
+ set -l tmp_pin "$pin_file.tmp.$fish_pid"
106
+ printf '%s\n' "$real_bin" >"$tmp_pin"
107
+ mv "$tmp_pin" "$pin_file"
52
108
  end
53
109
 
54
110
  # Source cached output
@@ -56,3 +112,20 @@ function _cached_eval --description 'Cache and source tool init output'
56
112
  source "$cache_file"
57
113
  end
58
114
  end
115
+
116
+ function _cached_eval --description 'Cache and source tool init output'
117
+ if test "$EVALCACHE_TIMING" != 1
118
+ _cached_eval_impl $argv
119
+ return $status
120
+ end
121
+ set -l _ce_t0 (date +%s%N 2>/dev/null; or echo 0)
122
+ _cached_eval_impl $argv
123
+ set -l _ce_rc $status
124
+ set -l _ce_t1 (date +%s%N 2>/dev/null; or echo 0)
125
+ set -l label unknown
126
+ if test (count $argv) -ge 1
127
+ set label $argv[1]
128
+ end
129
+ _cached_eval_log_timing "$label" "$_ce_t0" "$_ce_t1" "$_ce_rc" fish
130
+ return $_ce_rc
131
+ end
@@ -0,0 +1,17 @@
1
+ # _cached_eval_clear β€” Remove cache files written by _cached_eval.
2
+ # Safe: only removes *-init.fish and *-init.bin in $XDG_CACHE_HOME/fish.
3
+
4
+ function _cached_eval_clear --description 'Clear caches written by _cached_eval'
5
+ set -l cache_dir (set -q XDG_CACHE_HOME; and echo $XDG_CACHE_HOME; or echo "$HOME/.cache")/fish
6
+ if not test -d "$cache_dir"
7
+ printf 'Cleared 0 cached eval file(s) from %s\n' "$cache_dir"
8
+ return 0
9
+ end
10
+ set -l count 0
11
+ for f in $cache_dir/*-init.fish $cache_dir/*-init.bin
12
+ if test -f "$f"
13
+ rm -f -- "$f"; and set count (math $count + 1)
14
+ end
15
+ end
16
+ printf 'Cleared %d cached eval file(s) from %s\n' $count "$cache_dir"
17
+ end
@@ -1,7 +1,7 @@
1
- {{- $t := index .themes (default "macos-monterey-dark" .theme) -}}
2
- {{- if not $t -}}{{- $t = index .themes "macos-monterey-dark" -}}{{- end }}
1
+ {{- $t := index .themes (default "big-sur-dark" .theme) -}}
2
+ {{- if not $t -}}{{- $t = index .themes "big-sur-dark" -}}{{- end }}
3
3
  {{- $tt := $t -}}
4
- {{- $themeName := default "macos-monterey-dark" .theme -}}
4
+ {{- $themeName := default "big-sur-dark" .theme -}}
5
5
  {{- if hasSuffix "-light" $themeName -}}
6
6
  {{- $darkTheme := index .themes (printf "%s-dark" (trimSuffix "-light" $themeName)) -}}
7
7
  {{- if $darkTheme -}}{{- $tt = $darkTheme -}}{{- end -}}
@@ -1,5 +1,5 @@
1
- {{- $t := index .themes (default "macos-monterey-dark" .theme) -}}
2
- {{- if not $t -}}{{- $t = index .themes "macos-monterey-dark" -}}{{- end }}
1
+ {{- $t := index .themes (default "big-sur-dark" .theme) -}}
2
+ {{- if not $t -}}{{- $t = index .themes "big-sur-dark" -}}{{- end }}
3
3
  [main]
4
4
  font={{ .terminal_font_family }}:size={{ .terminal_font_size }}
5
5
  terminal=ghostty
@@ -133,10 +133,10 @@ keybind = ctrl+k=clear_screen
133
133
  ################
134
134
  # Colors #
135
135
  ################
136
- {{- $t := index .themes (default "macos-monterey-dark" .theme) -}}
137
- {{- if not $t -}}{{- $t = index .themes "macos-monterey-dark" -}}{{- end }}
136
+ {{- $t := index .themes (default "big-sur-dark" .theme) -}}
137
+ {{- if not $t -}}{{- $t = index .themes "big-sur-dark" -}}{{- end }}
138
138
  {{- $tt := $t -}}
139
- {{- $themeName := default "macos-monterey-dark" .theme -}}
139
+ {{- $themeName := default "big-sur-dark" .theme -}}
140
140
  {{- if hasSuffix "-light" $themeName -}}
141
141
  {{- $darkTheme := index .themes (printf "%s-dark" (trimSuffix "-light" $themeName)) -}}
142
142
  {{- if $darkTheme -}}{{- $tt = $darkTheme -}}{{- end -}}
@@ -0,0 +1,146 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # ── AI Attribution (Linux kernel coding-assistants standard) ──────────
5
+ # Appends "Assisted-by:" trailer to commit messages when authored during
6
+ # an AI coding assistant session. Detects the active tool automatically.
7
+ #
8
+ # Reference: https://github.com/torvalds/linux/blob/master/Documentation/process/coding-assistants.rst
9
+ # Format: Assisted-by: AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2]
10
+
11
+ detect_ai_agent() {
12
+ # Default model when running under Claude Code. Override at any time
13
+ # without editing this hook by exporting CLAUDE_MODEL in your shell
14
+ # rc, e.g. `export CLAUDE_MODEL=claude-opus-4-7`. Kept current with
15
+ # the latest generally-available Opus at time of last hook update.
16
+ local claude_default="${CLAUDE_MODEL:-claude-opus-4-7}"
17
+
18
+ # Claude Code (Anthropic). The CLI actually sets CLAUDECODE=1 (no
19
+ # underscore); the other vars are kept as historical aliases and for
20
+ # API-key-only sessions.
21
+ if [[ -n "${CLAUDECODE:-}" \
22
+ || -n "${CLAUDE_CODE:-}" \
23
+ || -n "${CLAUDE_SESSION_ID:-}" \
24
+ || -n "${CLAUDE_CODE_ENTRYPOINT:-}" \
25
+ || -n "${ANTHROPIC_API_KEY:-}" ]]; then
26
+ echo "Claude:${claude_default}"
27
+ return
28
+ fi
29
+
30
+ # GitHub Copilot CLI
31
+ if [[ -n "${GITHUB_COPILOT_CLI:-}" || -n "${COPILOT_SESSION:-}" ]]; then
32
+ echo "Copilot:copilot-cli"
33
+ return
34
+ fi
35
+
36
+ # Aider
37
+ if [[ -n "${AIDER_SESSION:-}" || -n "${AIDER_MODEL:-}" ]]; then
38
+ echo "Aider:${AIDER_MODEL:-unknown}"
39
+ return
40
+ fi
41
+
42
+ # OpenCode
43
+ if [[ -n "${OPENCODE_SESSION:-}" ]]; then
44
+ echo "OpenCode:${OPENCODE_MODEL:-unknown}"
45
+ return
46
+ fi
47
+
48
+ # Gemini CLI (Google)
49
+ if [[ -n "${GEMINI_API_KEY:-}" && -n "${GEMINI_SESSION:-}" ]]; then
50
+ echo "Gemini:gemini-cli"
51
+ return
52
+ fi
53
+
54
+ # Mistral Vibe
55
+ if [[ -n "${MISTRAL_API_KEY:-}" && -n "${MISTRAL_SESSION:-}" ]]; then
56
+ echo "Mistral:mistral-vibe"
57
+ return
58
+ fi
59
+
60
+ # Qwen Code
61
+ if [[ -n "${QWEN_SESSION:-}" ]]; then
62
+ echo "Qwen:qwen-code"
63
+ return
64
+ fi
65
+
66
+ # Kiro (AWS)
67
+ if [[ -n "${KIRO_SESSION:-}" || -n "${KIRO_CLI:-}" ]]; then
68
+ echo "Kiro:kiro-cli"
69
+ return
70
+ fi
71
+
72
+ # Autohand Code
73
+ if [[ -n "${AUTOHAND_SESSION:-}" ]]; then
74
+ echo "Autohand:autohand-code"
75
+ return
76
+ fi
77
+
78
+ # ZAI (Zhipu)
79
+ if [[ -n "${ZAI_SESSION:-}" ]]; then
80
+ echo "ZAI:zai-cli"
81
+ return
82
+ fi
83
+
84
+ # Shell-GPT
85
+ if [[ -n "${SHELL_GPT_SESSION:-}" ]]; then
86
+ echo "ShellGPT:shell-gpt"
87
+ return
88
+ fi
89
+
90
+ # Ollama (local)
91
+ if [[ -n "${OLLAMA_SESSION:-}" ]]; then
92
+ echo "Ollama:${OLLAMA_MODEL:-local}"
93
+ return
94
+ fi
95
+
96
+ # Fallback: check if any known AI process is in the tree.
97
+ # Uses the same overridable default as the env-var path above so a
98
+ # single export keeps both sites in sync.
99
+ if pgrep -q "claude" 2>/dev/null; then
100
+ echo "Claude:${claude_default}"
101
+ return
102
+ fi
103
+
104
+ # No AI detected
105
+ echo ""
106
+ }
107
+
108
+ # ── Branding Signature ────────────────────────────────────────────────
109
+ sig_file="${HOME}/.euxis/data/config/branding/signature.txt"
110
+ msg_file="${1:-}"
111
+
112
+ [[ -n "$msg_file" && -f "$msg_file" ]] || exit 0
113
+
114
+ # Skip merge commits, fixups, and squashes
115
+ first_line="$(head -1 "$msg_file")"
116
+ if [[ "$first_line" =~ ^Merge\ |^fixup!\ |^squash!\ ]]; then
117
+ exit 0
118
+ fi
119
+
120
+ # ── Inject AI attribution if not already present ──────────────────────
121
+ # Line-anchored: a literal mention of `Assisted-by:` inside the commit
122
+ # body (e.g. when the commit message *describes* the trailer) must not
123
+ # fool the hook into skipping injection. Trailers always start at col 1.
124
+ if ! grep -Eq "^Assisted-by:" "$msg_file"; then
125
+ ai_agent="$(detect_ai_agent)"
126
+ if [[ -n "$ai_agent" ]]; then
127
+ printf '\nAssisted-by: %s\n' "$ai_agent" >> "$msg_file"
128
+ fi
129
+ fi
130
+
131
+ # ── Inject branding signature if not already present ──────────────────
132
+ [[ -f "$sig_file" ]] || exit 0
133
+
134
+ first_sig_line="$(sed -n '1p' "$sig_file")"
135
+ [[ -n "$first_sig_line" ]] || exit 0
136
+
137
+ if grep -Fqx -- "$first_sig_line" "$msg_file"; then
138
+ exit 0
139
+ fi
140
+
141
+ if [[ -s "$msg_file" ]]; then
142
+ printf '\n' >> "$msg_file"
143
+ fi
144
+
145
+ cat "$sig_file" >> "$msg_file"
146
+ printf '\n' >> "$msg_file"
@@ -9,11 +9,11 @@ providers:
9
9
  anthropic:
10
10
  model: claude-opus-4-6
11
11
  max_tokens: 8192
12
-
12
+
13
13
  openai:
14
14
  model: gpt-4o
15
15
  max_tokens: 4096
16
-
16
+
17
17
  ollama:
18
18
  model: llama3.2
19
19
  host: http://localhost:11434
@@ -1,6 +1,6 @@
1
1
  {{- /* GTK-3.0 custom CSS β€” colors from SSOT theme manifest */ -}}
2
- {{- $t := index .themes (default "macos-monterey-dark" .theme) -}}
3
- {{- if not $t -}}{{- $t = index .themes "macos-monterey-dark" -}}{{- end -}}
2
+ {{- $t := index .themes (default "big-sur-dark" .theme) -}}
3
+ {{- if not $t -}}{{- $t = index .themes "big-sur-dark" -}}{{- end -}}
4
4
  {{- $is_dark := eq $t.mode "dark" -}}
5
5
 
6
6
  /* GTK3 Custom Styling for {{ .theme }} */
@@ -1,5 +1,5 @@
1
- {{- $t := index .themes (default "macos-monterey-dark" .theme) -}}
2
- {{- if not $t -}}{{- $t = index .themes "macos-monterey-dark" -}}{{- end -}}
1
+ {{- $t := index .themes (default "big-sur-dark" .theme) -}}
2
+ {{- if not $t -}}{{- $t = index .themes "big-sur-dark" -}}{{- end -}}
3
3
  {{- $is_dark := eq $t.mode "dark" -}}
4
4
  {{- $gtk_theme := $t.app.gtk_theme -}}
5
5
  {{- $icon_theme := $t.app.gtk_icon -}}
@@ -1,6 +1,6 @@
1
1
  {{- /* GTK-4.0 custom CSS β€” colors from SSOT theme manifest */ -}}
2
- {{- $t := index .themes (default "macos-monterey-dark" .theme) -}}
3
- {{- if not $t -}}{{- $t = index .themes "macos-monterey-dark" -}}{{- end -}}
2
+ {{- $t := index .themes (default "big-sur-dark" .theme) -}}
3
+ {{- if not $t -}}{{- $t = index .themes "big-sur-dark" -}}{{- end -}}
4
4
  {{- $is_dark := eq $t.mode "dark" -}}
5
5
 
6
6
  /* GTK4 Custom Styling for {{ .theme }} */
@@ -1,5 +1,5 @@
1
- {{- $t := index .themes (default "macos-monterey-dark" .theme) -}}
2
- {{- if not $t -}}{{- $t = index .themes "macos-monterey-dark" -}}{{- end -}}
1
+ {{- $t := index .themes (default "big-sur-dark" .theme) -}}
2
+ {{- if not $t -}}{{- $t = index .themes "big-sur-dark" -}}{{- end -}}
3
3
  {{- $is_dark := eq $t.mode "dark" -}}
4
4
 
5
5
  [Settings]
@@ -21,10 +21,10 @@ cursor_trail 0
21
21
  linux_display_server wayland
22
22
  {{- end }}
23
23
 
24
- {{- $t := index .themes (default "macos-monterey-dark" .theme) -}}
25
- {{- if not $t -}}{{- $t = index .themes "macos-monterey-dark" -}}{{- end }}
24
+ {{- $t := index .themes (default "big-sur-dark" .theme) -}}
25
+ {{- if not $t -}}{{- $t = index .themes "big-sur-dark" -}}{{- end }}
26
26
  {{- $tt := $t -}}
27
- {{- $themeName := default "macos-monterey-dark" .theme -}}
27
+ {{- $themeName := default "big-sur-dark" .theme -}}
28
28
  {{- if hasSuffix "-light" $themeName -}}
29
29
  {{- $darkTheme := index .themes (printf "%s-dark" (trimSuffix "-light" $themeName)) -}}
30
30
  {{- if $darkTheme -}}{{- $tt = $darkTheme -}}{{- end -}}
@@ -80,7 +80,7 @@ kiro-cli = "latest"
80
80
  "npm:autohand-cli" = "latest"
81
81
  "npm:@qwen-code/qwen-code" = "latest"
82
82
  "npm:@guizmo-ai/zai-cli" = "latest"
83
- "pipx:mistral-vibe" = "latest"
83
+ # "pipx:mistral-vibe" = "latest" # disabled 2026-05-12: dep `mistralai` quarantined on PyPI; re-enable when restored
84
84
 
85
85
  # Task runners
86
86
  task = "latest"
@@ -9,8 +9,8 @@
9
9
  {{- $hw = $m -}}
10
10
  {{- end -}}
11
11
  {{- end -}}
12
- {{- $t := index .themes (default "macos-monterey-dark" .theme) -}}
13
- {{- if not $t -}}{{- $t = index .themes "macos-monterey-dark" -}}{{- end }}
12
+ {{- $t := index .themes (default "big-sur-dark" .theme) -}}
13
+ {{- if not $t -}}{{- $t = index .themes "big-sur-dark" -}}{{- end }}
14
14
  config-notification {
15
15
  disable-failed
16
16
  }
@@ -0,0 +1,80 @@
1
+ # πŸ…³πŸ…ΎπŸ†ƒπŸ…΅πŸ…ΈπŸ…»πŸ…΄πŸ†‚ β€” Nushell _cached_eval equivalent
2
+ # <https://dotfiles.io>
3
+ #
4
+ # Minimum-viable port of the zsh/fish `_cached_eval` primitive. Caches
5
+ # the output of tool-init commands (e.g. `starship init nu`, `mise
6
+ # activate nu`) so subsequent shells source the cached file instead of
7
+ # spawning a subprocess. Cache invalidates on binary mtime change.
8
+ #
9
+ # Closes the Nushell-parity AC of #880. Tier-3 by design: not as
10
+ # feature-rich as the zsh implementation (no malware-pattern screening,
11
+ # no per-tool timing telemetry, no atomic write under concurrent
12
+ # shells) β€” those layers are not yet worth Nushell's parse-time
13
+ # constraints. See ADR-011.
14
+
15
+ # Path resolution helpers β€” Nushell's parse-time evaluator means we
16
+ # can't compute these at import time as cleanly as fish/zsh do.
17
+ export def --env _cached_eval_cache_dir [] {
18
+ let xdg = ($env | get -i XDG_CACHE_HOME)
19
+ if $xdg != null and ($xdg | str length) > 0 {
20
+ $"($xdg)/nushell"
21
+ } else {
22
+ $"($env.HOME)/.cache/nushell"
23
+ }
24
+ }
25
+
26
+ # _cached_eval β€” cache the output of `<tool> <args...>` to disk and
27
+ # print the cached path. The caller is responsible for `source`-ing
28
+ # the result (Nushell `source` is parse-time, so this can't be
29
+ # wrapped further without losing the parse-time semantics).
30
+ #
31
+ # Returns: the path to the cached file (string), or empty string when
32
+ # the tool is unavailable / the eval failed.
33
+ export def _cached_eval [tool: string, ...args: string] {
34
+ let cache_dir = (_cached_eval_cache_dir)
35
+ mkdir $cache_dir
36
+ let label = ($tool + "-" + ($args | str join "-") | str replace --all "/" "_" | str replace --all " " "-")
37
+ let cache_file = $"($cache_dir)/($label).nu"
38
+
39
+ # Check binary mtime against cache mtime for invalidation.
40
+ let tool_path = (which $tool | get -i 0.path)
41
+ if $tool_path == null {
42
+ return ""
43
+ }
44
+
45
+ let fresh = if ($cache_file | path exists) {
46
+ let tool_mtime = (ls $tool_path | get -i 0.modified)
47
+ let cache_mtime = (ls $cache_file | get -i 0.modified)
48
+ if $tool_mtime != null and $cache_mtime != null {
49
+ $cache_mtime > $tool_mtime
50
+ } else {
51
+ false
52
+ }
53
+ } else {
54
+ false
55
+ }
56
+
57
+ if not $fresh {
58
+ let output = (try { run-external $tool ...$args | complete } catch { { stdout: "", exit_code: 1 } })
59
+ if $output.exit_code == 0 and ($output.stdout | str length) > 0 {
60
+ $output.stdout | save -f $cache_file
61
+ } else {
62
+ return ""
63
+ }
64
+ }
65
+
66
+ $cache_file
67
+ }
68
+
69
+ # Convenience wrapper for the common case: caller wants the source
70
+ # path, falls back to silent no-op if the tool is absent.
71
+ export def _cached_eval_path_or_skip [tool: string, ...args: string] {
72
+ let p = (_cached_eval $tool ...$args)
73
+ if ($p | str length) == 0 {
74
+ ""
75
+ } else if ($p | path exists) {
76
+ $p
77
+ } else {
78
+ ""
79
+ }
80
+ }
@@ -28,28 +28,36 @@ let paths = [
28
28
 
29
29
  $env.PATH = ($env.PATH | split row (char esep) | append $paths | uniq)
30
30
 
31
- # Setup shell tool integrations
31
+ # Setup shell tool integrations.
32
+ #
33
+ # The `_cached_eval` module (loaded via dot_config/nushell/cached_eval.nu)
34
+ # adds mtime-based cache invalidation so we don't spawn `starship init
35
+ # nu` / `mise activate nu` / etc. on every shell start. Closes the
36
+ # Nushell parity AC of #880.
32
37
  mkdir ~/.cache/nushell
33
38
 
34
- # Starship prompt
35
- if (which starship | length) > 0 {
36
- starship init nu | save -f ~/.cache/nushell/starship.nu
37
- } else {
39
+ use ~/.config/nushell/cached_eval.nu *
40
+
41
+ # The empty-file fallbacks preserve the `source` targets in
42
+ # config.nu.tmpl β€” Nushell parses sources at parse time and refuses
43
+ # to start if any source path is missing.
44
+
45
+ if (_cached_eval_path_or_skip starship init nu | str length) == 0 {
38
46
  "" | save -f ~/.cache/nushell/starship.nu
47
+ } else {
48
+ cp (_cached_eval starship init nu) ~/.cache/nushell/starship.nu
39
49
  }
40
50
 
41
- # Zoxide directory jumper
42
- if (which zoxide | length) > 0 {
43
- zoxide init nushell | save -f ~/.cache/nushell/zoxide.nu
44
- } else {
51
+ if (_cached_eval_path_or_skip zoxide init nushell | str length) == 0 {
45
52
  "" | save -f ~/.cache/nushell/zoxide.nu
53
+ } else {
54
+ cp (_cached_eval zoxide init nushell) ~/.cache/nushell/zoxide.nu
46
55
  }
47
56
 
48
- # Atuin shell history
49
- if (which atuin | length) > 0 {
50
- atuin init nu | save -f ~/.cache/nushell/atuin.nu
51
- } else {
57
+ if (_cached_eval_path_or_skip atuin init nu | str length) == 0 {
52
58
  "" | save -f ~/.cache/nushell/atuin.nu
59
+ } else {
60
+ cp (_cached_eval atuin init nu) ~/.cache/nushell/atuin.nu
53
61
  }
54
62
 
55
63
  # Generate Nushell alias cache from bash alias library