@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.
Files changed (420) hide show
  1. package/CHANGELOG.md +155 -4
  2. package/LICENSE +21 -1283
  3. package/README.md +40 -8
  4. package/docs/CONFIG_STRATEGY.md +124 -0
  5. package/docs/COPYRIGHT +1 -1
  6. package/docs/GOVERNANCE.md +98 -0
  7. package/docs/MAINTAINERS.md +41 -0
  8. package/docs/OPENCODE.md +127 -0
  9. package/docs/README.md +2 -0
  10. package/docs/STRUCTURE.md +102 -0
  11. package/docs/adr/ADR-011-nushell-tier3-keep.md +2 -2
  12. package/docs/architecture/AI_COST_OPTIMIZATION.md +143 -0
  13. package/docs/architecture/REPO_LAYOUT.md +8 -8
  14. package/docs/archive/MILESTONE_v0.2.493.md +1 -1
  15. package/docs/index.md +2 -2
  16. package/docs/interop/POWERSHELL.md +1 -1
  17. package/docs/manual/00-introduction.md +1 -1
  18. package/docs/manual/01-concepts/02-trust-model.md +1 -1
  19. package/docs/manual/03-reference/01-dot-cli.md +63 -45
  20. package/docs/manual/03-reference/02-config-files.md +2 -2
  21. package/docs/manual/03-reference/05-feature-flags.md +62 -3
  22. package/docs/manual/_toc.yml +1 -1
  23. package/docs/manual/command-index.md +72 -55
  24. package/docs/manual/index.md +66 -0
  25. package/docs/operations/CI_COMPOSITES.md +2 -2
  26. package/docs/operations/COMPLETIONS.md +2 -2
  27. package/docs/operations/COVERAGE.md +40 -6
  28. package/docs/operations/HARD_AUDIT_2026.md +631 -0
  29. package/docs/operations/MAINTENANCE.md +3 -3
  30. package/docs/operations/MANIFEST.md +127 -0
  31. package/docs/operations/REGISTRY.md +89 -0
  32. package/docs/operations/RELEASE_PIPELINE.md +130 -0
  33. package/docs/operations/RFC_v0_2_503_reorganization.md +280 -0
  34. package/docs/operations/ROADMAP_2026.md +665 -0
  35. package/docs/operations/ROADMAP_V0_2_503.md +134 -0
  36. package/docs/operations/TESTING.md +17 -0
  37. package/docs/operations/TRACEABILITY.md +9 -3
  38. package/docs/operations/VERSION_SYNC.md +4 -4
  39. package/docs/reference/POWERSHELL_PARITY.md +81 -0
  40. package/docs/registry.json +6 -0
  41. package/docs/schema/dot-env-v1.json +110 -0
  42. package/docs/security/CI_EGRESS_ALLOWLIST.md +1 -1
  43. package/docs/security/CI_PINNING.md +121 -0
  44. package/docs/security/COMMIT_SIGNING.md +138 -0
  45. package/docs/security/DEPS_DEV_EXCEPTIONS.md +2 -2
  46. package/docs/security/DISCLOSURE.md +130 -0
  47. package/docs/security/FUZZING.md +114 -0
  48. package/docs/security/INSTALL_VERIFICATION.md +2 -2
  49. package/docs/security/KEY_ROTATION.md +81 -1
  50. package/docs/security/POLICY_RELEASES.md +2 -2
  51. package/docs/security/SCORECARD.md +130 -15
  52. package/docs/security/SHELL_EXEMPTIONS.md +4 -4
  53. package/docs/security/VERIFY_RELEASE.md +201 -0
  54. package/docs/security/security-pubkey.asc +15 -0
  55. package/install.sh +67 -38
  56. package/package.json +1 -1
  57. package/scripts/README.md +123 -0
  58. package/scripts/ci/check-copyright-headers.sh +4 -93
  59. package/scripts/ci/check-shell-preamble.sh +4 -103
  60. package/scripts/ci/guard-gitleaks-checkout.sh +4 -54
  61. package/scripts/diagnostics/a2a-conformance.sh +4 -4
  62. package/scripts/diagnostics/alias-governance.sh +1 -1
  63. package/scripts/diagnostics/aliases-cheatsheet.sh +2 -2
  64. package/scripts/diagnostics/benchmark.sh +4 -4
  65. package/scripts/diagnostics/conflicts.sh +2 -2
  66. package/scripts/diagnostics/doctor-unified.sh +2 -2
  67. package/scripts/diagnostics/doctor.sh +45 -15
  68. package/scripts/diagnostics/drift-dashboard.sh +2 -2
  69. package/scripts/diagnostics/health.sh +4 -4
  70. package/scripts/diagnostics/history-analysis.sh +2 -2
  71. package/scripts/diagnostics/mcp-doctor.sh +10 -7
  72. package/scripts/diagnostics/perf.sh +4 -4
  73. package/scripts/diagnostics/scorecard.sh +4 -4
  74. package/scripts/diagnostics/security-score.sh +2 -2
  75. package/scripts/diagnostics/smoke-test.sh +2 -2
  76. package/scripts/diagnostics/snapshot.sh +2 -2
  77. package/scripts/diagnostics/verify.sh +4 -4
  78. package/scripts/diagnostics/version-locks.sh +2 -2
  79. package/scripts/diagnostics/workstation-attestation.sh +14 -14
  80. package/scripts/dot/commands/agent.sh +27 -22
  81. package/scripts/dot/commands/agents.sh +335 -0
  82. package/scripts/dot/commands/ai.sh +144 -25
  83. package/scripts/dot/commands/aliases.sh +10 -8
  84. package/scripts/dot/commands/appearance.sh +2 -2
  85. package/scripts/dot/commands/core.sh +12 -6
  86. package/scripts/dot/commands/diagnostics.sh +5 -5
  87. package/scripts/dot/commands/env-emit.sh +202 -0
  88. package/scripts/dot/commands/fleet.sh +290 -14
  89. package/scripts/dot/commands/init.sh +184 -0
  90. package/scripts/dot/commands/lint.sh +9 -4
  91. package/scripts/dot/commands/manual.sh +3 -3
  92. package/scripts/dot/commands/meta.sh +19 -10
  93. package/scripts/dot/commands/patterns.sh +2 -2
  94. package/scripts/dot/commands/registry.sh +263 -0
  95. package/scripts/dot/commands/restore.sh +4 -4
  96. package/scripts/dot/commands/secrets.sh +4 -3
  97. package/scripts/dot/commands/security.sh +2 -2
  98. package/scripts/dot/commands/tools.sh +62 -4
  99. package/scripts/dot/powershell/Dot.psm1 +199 -0
  100. package/scripts/fonts/install-nerd-fonts.sh +2 -2
  101. package/scripts/git-hooks/pre-commit-audit.sh +2 -2
  102. package/scripts/git-hooks/pre-push +13 -0
  103. package/scripts/lib/secrets_provider.sh +32 -6
  104. package/scripts/ops/ai-setup.sh +1 -1
  105. package/scripts/ops/bundle.sh +2 -2
  106. package/scripts/ops/chaos.sh +2 -2
  107. package/scripts/ops/chezmoi-apply.sh +4 -4
  108. package/scripts/ops/heal.sh +4 -4
  109. package/scripts/ops/post-apply-repair.sh +2 -2
  110. package/scripts/ops/prewarm.sh +2 -2
  111. package/scripts/ops/release.sh +4 -4
  112. package/scripts/ops/rollback.sh +18 -4
  113. package/scripts/ops/setup.sh +2 -2
  114. package/scripts/qa/check-version-consistency.sh +123 -0
  115. package/scripts/qa/coverage-baseline.sh +1 -1
  116. package/scripts/qa/docs-coverage.sh +2 -2
  117. package/scripts/qa/powershell-contract.ps1 +1 -1
  118. package/scripts/qa/scorecard-snapshot.sh +127 -0
  119. package/scripts/security/backup.sh +2 -2
  120. package/scripts/security/check-disclosure-key-expiry.sh +110 -0
  121. package/scripts/security/dns-doh.sh +4 -4
  122. package/scripts/security/encryption-check.sh +4 -4
  123. package/scripts/security/enforce-policies.sh +2 -2
  124. package/scripts/security/firewall.sh +4 -4
  125. package/scripts/security/lock-configs.sh +11 -2
  126. package/scripts/security/lock-screen.sh +4 -4
  127. package/scripts/security/manage-secrets.sh +2 -2
  128. package/scripts/security/ssh-cert.sh +2 -2
  129. package/scripts/security/telemetry-kill.sh +4 -4
  130. package/scripts/security/usb-safety.sh +4 -4
  131. package/scripts/theme/extract-heic-frames.sh +114 -0
  132. package/scripts/theme/rebuild-themes.sh +8 -1
  133. package/scripts/theme/switch.sh +13 -6
  134. package/scripts/theme/wallpaper-sync.sh +297 -93
  135. package/scripts/tuning/linux.sh +2 -2
  136. package/scripts/tuning/macos.sh +2 -2
  137. package/scripts/version-sync.sh +58 -7
  138. package/dot_config/.module-manifest.json +0 -69
  139. package/dot_config/ai/identity.md +0 -23
  140. package/dot_config/ai/patterns/architect.md +0 -16
  141. package/dot_config/ai/patterns/hardener.md +0 -15
  142. package/dot_config/ai/patterns/refactor.md +0 -15
  143. package/dot_config/aider/aider.conf.yml +0 -32
  144. package/dot_config/alacritty/alacritty.toml.tmpl +0 -55
  145. package/dot_config/ansible/ansible.cfg +0 -11
  146. package/dot_config/atuin/config.toml.tmpl +0 -47
  147. package/dot_config/bat/config +0 -23
  148. package/dot_config/brave-flags.conf.tmpl +0 -7
  149. package/dot_config/btop/btop.conf +0 -16
  150. package/dot_config/btop/themes/tokyonight.theme +0 -34
  151. package/dot_config/bun/bunfig.toml.tmpl +0 -33
  152. package/dot_config/claude/mcp_servers.json +0 -20
  153. package/dot_config/containers/containers.conf +0 -14
  154. package/dot_config/curl/dot_curlrc +0 -18
  155. package/dot_config/dlv/config.yml +0 -39
  156. package/dot_config/docker/config.json +0 -15
  157. package/dot_config/dotfiles/agent-card.json +0 -29
  158. package/dot_config/dotfiles/agent-profiles.json +0 -92
  159. package/dot_config/dotfiles/boot/README.md +0 -13
  160. package/dot_config/dotfiles/grub/README.md +0 -13
  161. package/dot_config/dotfiles/lock/README.md +0 -13
  162. package/dot_config/dotfiles/mcp-lock.json +0 -33
  163. package/dot_config/dotfiles/mcp-policy.json +0 -52
  164. package/dot_config/dotfiles/mcp-registry.json +0 -47
  165. package/dot_config/dotfiles/model-registry.json +0 -20
  166. package/dot_config/dotfiles/policy-bundles.json +0 -38
  167. package/dot_config/dotfiles/prompt-registry.json +0 -16
  168. package/dot_config/dotfiles/versions.env +0 -18
  169. package/dot_config/duf/duf.conf +0 -6
  170. package/dot_config/duti/defaults.duti +0 -5
  171. package/dot_config/emoji/emoji.txt +0 -34
  172. package/dot_config/environment.d/50-ssh-agent.conf +0 -2
  173. package/dot_config/environment.d/90-wayland.conf +0 -19
  174. package/dot_config/fastfetch/config.jsonc +0 -28
  175. package/dot_config/firefox/user.js.tmpl +0 -58
  176. package/dot_config/fish/completions/dot-theme-sync.fish.tmpl +0 -9
  177. package/dot_config/fish/completions/dot.fish.tmpl +0 -115
  178. package/dot_config/fish/conf.d/000-perf-cache.fish +0 -56
  179. package/dot_config/fish/conf.d/aliases.fish.tmpl +0 -77
  180. package/dot_config/fish/conf.d/env.fish.tmpl +0 -48
  181. package/dot_config/fish/conf.d/functions.fish.tmpl +0 -22
  182. package/dot_config/fish/conf.d/init.fish.tmpl +0 -172
  183. package/dot_config/fish/config.fish.tmpl +0 -44
  184. package/dot_config/fish/fish_plugins +0 -1
  185. package/dot_config/fish/functions/_.fish +0 -3
  186. package/dot_config/fish/functions/_cached_eval.fish +0 -131
  187. package/dot_config/fish/functions/_cached_eval_clear.fish +0 -17
  188. package/dot_config/fish/functions/als.fish +0 -46
  189. package/dot_config/fish/functions/bg-upgrade.fish +0 -7
  190. package/dot_config/fish/functions/c.fish +0 -3
  191. package/dot_config/fish/functions/cat.fish +0 -9
  192. package/dot_config/fish/functions/d.fish +0 -7
  193. package/dot_config/fish/functions/dot.fish +0 -34
  194. package/dot_config/fish/functions/h.fish +0 -3
  195. package/dot_config/fish/functions/l.fish +0 -7
  196. package/dot_config/fish/functions/la.fish +0 -7
  197. package/dot_config/fish/functions/ll.fish +0 -7
  198. package/dot_config/fish/functions/log_error.fish +0 -13
  199. package/dot_config/fish/functions/log_info.fish +0 -13
  200. package/dot_config/fish/functions/lr.fish +0 -7
  201. package/dot_config/fish/functions/lra.fish +0 -7
  202. package/dot_config/fish/functions/ls.fish +0 -7
  203. package/dot_config/fish/functions/lt.fish +0 -7
  204. package/dot_config/fish/functions/lta.fish +0 -7
  205. package/dot_config/fish/functions/notify-run.fish +0 -11
  206. package/dot_config/fish/functions/q.fish +0 -3
  207. package/dot_config/fish/functions/silent-run.fish +0 -7
  208. package/dot_config/fish/functions/yy.fish +0 -8
  209. package/dot_config/flatpak/flatpak.list +0 -4
  210. package/dot_config/fontconfig/fonts.conf.tmpl +0 -57
  211. package/dot_config/foot/foot.ini.tmpl +0 -33
  212. package/dot_config/fuzzel/fuzzel.ini.tmpl +0 -18
  213. package/dot_config/fzf/fzf.zsh +0 -48
  214. package/dot_config/gem/gemrc +0 -9
  215. package/dot_config/gh/config.yml +0 -12
  216. package/dot_config/ghostty/config.tmpl +0 -165
  217. package/dot_config/git/allowed_signers.tmpl +0 -18
  218. package/dot_config/git/attributes +0 -12
  219. package/dot_config/git/commit-template +0 -10
  220. package/dot_config/git/hooks/executable_commit-msg +0 -146
  221. package/dot_config/git/ignore +0 -27
  222. package/dot_config/gnupg/gpg-agent.conf +0 -11
  223. package/dot_config/go/golangci.yml +0 -118
  224. package/dot_config/go/gopls.json +0 -30
  225. package/dot_config/goose/config.yaml +0 -29
  226. package/dot_config/gtk-3.0/gtk.css.tmpl +0 -184
  227. package/dot_config/gtk-3.0/settings.ini.tmpl +0 -27
  228. package/dot_config/gtk-4.0/gtk.css.tmpl +0 -252
  229. package/dot_config/gtk-4.0/settings.ini.tmpl +0 -18
  230. package/dot_config/htop/htoprc +0 -20
  231. package/dot_config/inputrc +0 -2
  232. package/dot_config/ipython/profile_default/ipython_config.py +0 -19
  233. package/dot_config/just/justfile +0 -122
  234. package/dot_config/k9s/config.yaml +0 -65
  235. package/dot_config/k9s/skins/catppuccin-mocha.yaml +0 -116
  236. package/dot_config/kanshi/config.tmpl +0 -22
  237. package/dot_config/karabiner/karabiner.json +0 -14
  238. package/dot_config/kitty/kitty.conf.tmpl +0 -53
  239. package/dot_config/lazydocker/config.yml +0 -186
  240. package/dot_config/lazygit/config.yml +0 -35
  241. package/dot_config/mako/config +0 -47
  242. package/dot_config/mas/masapps.txt +0 -5
  243. package/dot_config/micro/settings.json +0 -3
  244. package/dot_config/mimeapps.list +0 -77
  245. package/dot_config/minikube/config.json +0 -13
  246. package/dot_config/mise/config.toml +0 -99
  247. package/dot_config/mongosh/mongoshrc.js +0 -68
  248. package/dot_config/mpv/input.conf +0 -47
  249. package/dot_config/mpv/mpv.conf +0 -47
  250. package/dot_config/mycli/myclirc +0 -67
  251. package/dot_config/nano/nanorc +0 -28
  252. package/dot_config/ncdu/config +0 -12
  253. package/dot_config/niri/config.kdl.tmpl +0 -327
  254. package/dot_config/nushell/aliases.nu +0 -18
  255. package/dot_config/nushell/cached_eval.nu +0 -80
  256. package/dot_config/nushell/completions.nu.tmpl +0 -52
  257. package/dot_config/nushell/config.nu.tmpl +0 -86
  258. package/dot_config/nushell/env.nu.tmpl +0 -102
  259. package/dot_config/nushell/functions.nu.tmpl +0 -17
  260. package/dot_config/nvim/init.lua +0 -18
  261. package/dot_config/nvim/lazy-lock.json +0 -58
  262. package/dot_config/nvim/lua/config/autocmds.lua +0 -107
  263. package/dot_config/nvim/lua/config/keymaps.lua +0 -92
  264. package/dot_config/nvim/lua/config/lazy.lua +0 -44
  265. package/dot_config/nvim/lua/config/options.lua +0 -49
  266. package/dot_config/nvim/lua/plugins/ai.lua +0 -75
  267. package/dot_config/nvim/lua/plugins/coding.lua +0 -216
  268. package/dot_config/nvim/lua/plugins/completion.lua +0 -60
  269. package/dot_config/nvim/lua/plugins/dap.lua +0 -412
  270. package/dot_config/nvim/lua/plugins/editor.lua +0 -55
  271. package/dot_config/nvim/lua/plugins/git.lua +0 -10
  272. package/dot_config/nvim/lua/plugins/lsp.lua +0 -156
  273. package/dot_config/nvim/lua/plugins/markdown.lua +0 -18
  274. package/dot_config/nvim/lua/plugins/rust.lua +0 -34
  275. package/dot_config/nvim/lua/plugins/sessions.lua +0 -33
  276. package/dot_config/nvim/lua/plugins/ui.lua +0 -509
  277. package/dot_config/paru/paru.conf +0 -10
  278. package/dot_config/pip/pip.conf.tmpl +0 -32
  279. package/dot_config/powershell/Microsoft.PowerShell_profile.ps1.tmpl +0 -81
  280. package/dot_config/pueue/pueue.yml +0 -34
  281. package/dot_config/pypoetry/config.toml +0 -6
  282. package/dot_config/pyrightconfig.json +0 -5
  283. package/dot_config/raycast/README.md +0 -13
  284. package/dot_config/redis/redisclirc +0 -41
  285. package/dot_config/ripgrep/ripgreprc +0 -21
  286. package/dot_config/shell/00-core-paths.sh.tmpl +0 -134
  287. package/dot_config/shell/05-core-safety.sh +0 -48
  288. package/dot_config/shell/10-secrets.sh +0 -41
  289. package/dot_config/shell/40-fzf-defaults.sh.tmpl +0 -17
  290. package/dot_config/shell/40-ls-colors.sh +0 -49
  291. package/dot_config/shell/50-logic-functions-core.sh.tmpl +0 -11
  292. package/dot_config/shell/50-logic-functions.sh.tmpl +0 -11
  293. package/dot_config/shell/51-logic-functions-extra.sh.tmpl +0 -65
  294. package/dot_config/shell/90-ux-aliases.sh.tmpl +0 -121
  295. package/dot_config/shell/91-ux-aliases-lazy.sh.tmpl +0 -55
  296. package/dot_config/shell/Brewfile +0 -207
  297. package/dot_config/shell/Brewfile.cask +0 -92
  298. package/dot_config/shell/Brewfile.cli +0 -127
  299. package/dot_config/shell/README.md +0 -284
  300. package/dot_config/shell/als_data.txt.tmpl +0 -65
  301. package/dot_config/shell/custom/auto_ls.zsh +0 -20
  302. package/dot_config/shell/custom/context_suggest.zsh +0 -68
  303. package/dot_config/shell/custom/error_analysis.zsh +0 -45
  304. package/dot_config/sops/dot_sops.yaml +0 -23
  305. package/dot_config/starship.toml.tmpl +0 -202
  306. package/dot_config/swaylock/config +0 -43
  307. package/dot_config/systemd/user/dotfiles-maintenance.service +0 -8
  308. package/dot_config/systemd/user/dotfiles-maintenance.timer +0 -11
  309. package/dot_config/systemd/user/pueued.service +0 -12
  310. package/dot_config/systemd/user/ssh-agent.service +0 -12
  311. package/dot_config/task/Taskfile.yml +0 -86
  312. package/dot_config/tflint/tflint.hcl +0 -9
  313. package/dot_config/tmux/tmux.conf.tmpl +0 -223
  314. package/dot_config/topgrade.toml.tmpl +0 -54
  315. package/dot_config/user-dirs.dirs +0 -10
  316. package/dot_config/vscode/extensions.txt +0 -11
  317. package/dot_config/vscode/settings.json.tmpl +0 -82
  318. package/dot_config/waybar/config.jsonc.tmpl +0 -90
  319. package/dot_config/waybar/style.css.tmpl +0 -211
  320. package/dot_config/wezterm/wezterm.lua.tmpl +0 -64
  321. package/dot_config/wget/wgetrc +0 -12
  322. package/dot_config/xdg-desktop-portal/niri-portals.conf +0 -5
  323. package/dot_config/yarn/yarnrc.yml +0 -36
  324. package/dot_config/yazi/keymap.toml +0 -67
  325. package/dot_config/yazi/theme.toml +0 -102
  326. package/dot_config/yazi/yazi.toml +0 -40
  327. package/dot_config/zathura/zathurarc +0 -52
  328. package/dot_config/zellij/config.kdl.tmpl +0 -79
  329. package/dot_config/zsh/dot_zprofile +0 -7
  330. package/dot_config/zsh/dot_zshenv +0 -5
  331. package/dot_config/zsh/dot_zshrc.tmpl +0 -635
  332. package/dot_config/zsh/rc.d/00-alias-shims.zsh +0 -99
  333. package/dot_config/zsh/rc.d/05-ssh-agent.zsh +0 -18
  334. package/dot_config/zsh/rc.d/10-env.zsh.tmpl +0 -28
  335. package/dot_config/zsh/rc.d/20-zinit.zsh +0 -65
  336. package/dot_config/zsh/rc.d/30-options.zsh.tmpl +0 -214
  337. package/dot_config/zsh/rc.d/40-bell.zsh +0 -20
  338. package/dot_config/zsh/rc.d/50-login-fortune.zsh +0 -9
  339. package/dot_config/zsh/rc.d/99-alias-wrapper.zsh +0 -32
  340. package/dot_local/bin/executable_ai-update +0 -195
  341. package/dot_local/bin/executable_ai_core +0 -152
  342. package/dot_local/bin/executable_antigravity +0 -11
  343. package/dot_local/bin/executable_b64 +0 -84
  344. package/dot_local/bin/executable_bm +0 -79
  345. package/dot_local/bin/executable_cb +0 -39
  346. package/dot_local/bin/executable_dot +0 -596
  347. package/dot_local/bin/executable_dot-ai +0 -36
  348. package/dot_local/bin/executable_dot-bootstrap +0 -77
  349. package/dot_local/bin/executable_dot-launch-or-focus +0 -52
  350. package/dot_local/bin/executable_dot-load-benchmark +0 -31
  351. package/dot_local/bin/executable_dot-load-benchmark-pty +0 -77
  352. package/dot_local/bin/executable_dot-theme-sync +0 -952
  353. package/dot_local/bin/executable_dot_completion +0 -57
  354. package/dot_local/bin/executable_dtags +0 -28
  355. package/dot_local/bin/executable_epoch +0 -67
  356. package/dot_local/bin/executable_extract +0 -41
  357. package/dot_local/bin/executable_gbd +0 -52
  358. package/dot_local/bin/executable_gd +0 -42
  359. package/dot_local/bin/executable_git-ai-commit +0 -175
  360. package/dot_local/bin/executable_git-ai-diff +0 -169
  361. package/dot_local/bin/executable_gl +0 -101
  362. package/dot_local/bin/executable_hash +0 -161
  363. package/dot_local/bin/executable_hashsum +0 -160
  364. package/dot_local/bin/executable_hex +0 -115
  365. package/dot_local/bin/executable_jsonv +0 -78
  366. package/dot_local/bin/executable_jwt +0 -94
  367. package/dot_local/bin/executable_kill-port +0 -75
  368. package/dot_local/bin/executable_lorem +0 -118
  369. package/dot_local/bin/executable_mkscript +0 -35
  370. package/dot_local/bin/executable_monitor +0 -56
  371. package/dot_local/bin/executable_myip +0 -51
  372. package/dot_local/bin/executable_notify +0 -24
  373. package/dot_local/bin/executable_open +0 -38
  374. package/dot_local/bin/executable_pw +0 -27
  375. package/dot_local/bin/executable_rec-start +0 -46
  376. package/dot_local/bin/executable_rec-stop +0 -35
  377. package/dot_local/bin/executable_regex +0 -132
  378. package/dot_local/bin/executable_start-niri +0 -8
  379. package/dot_local/bin/executable_tmux-sessionizer +0 -314
  380. package/dot_local/bin/executable_tour +0 -177
  381. package/dot_local/bin/executable_up +0 -23
  382. package/dot_local/bin/executable_update +0 -142
  383. package/dot_local/bin/executable_uuid +0 -87
  384. package/dot_local/bin/executable_win +0 -32
  385. package/dot_local/bin/executable_yamlv +0 -57
  386. package/dot_local/share/bash-completion/completions/dot +0 -72
  387. package/dot_local/share/icons/hicolor/128x128/apps/rousseau.png +0 -0
  388. package/dot_local/share/icons/hicolor/16x16/apps/rousseau.png +0 -0
  389. package/dot_local/share/icons/hicolor/24x24/apps/rousseau.png +0 -0
  390. package/dot_local/share/icons/hicolor/256x256/apps/rousseau.png +0 -0
  391. package/dot_local/share/icons/hicolor/32x32/apps/rousseau.png +0 -0
  392. package/dot_local/share/icons/hicolor/48x48/apps/rousseau.png +0 -0
  393. package/dot_local/share/icons/hicolor/512x512/apps/rousseau.png +0 -0
  394. package/dot_local/share/icons/hicolor/64x64/apps/rousseau.png +0 -0
  395. package/dot_local/share/icons/hicolor/96x96/apps/rousseau.png +0 -0
  396. package/dot_local/share/icons/hicolor/scalable/apps/rousseau.png +0 -0
  397. package/dot_local/share/man/man1/dot.1 +0 -149
  398. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_download +0 -64
  399. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_install +0 -18
  400. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_list-all +0 -13
  401. package/dot_local/share/wayland-sessions/niri.desktop.tmpl +0 -6
  402. package/dot_local/share/zsh/completions/.keep +0 -0
  403. package/dot_local/share/zsh/completions/_dot +0 -283
  404. package/scripts/ci/check-dangerous-chmod.sh +0 -19
  405. package/scripts/ci/check-deps-dev.sh +0 -236
  406. package/scripts/ci/check-insecure-tls.sh +0 -61
  407. package/scripts/ci/check-regression-traceability.sh +0 -67
  408. package/scripts/ci/install-chezmoi-verified.sh +0 -64
  409. package/scripts/ci/run-coverage.sh +0 -362
  410. package/scripts/ci/validate-chezmoidata.sh +0 -25
  411. package/scripts/ci/validate-ci-config.sh +0 -224
  412. package/scripts/docs/build-manual.sh +0 -883
  413. package/scripts/docs/check-manual.sh +0 -213
  414. package/scripts/dot/lib/bento.sh +0 -50
  415. package/scripts/dot/lib/log.sh +0 -200
  416. package/scripts/dot/lib/platform.sh +0 -99
  417. package/scripts/dot/lib/ui.sh +0 -518
  418. package/scripts/dot/lib/utils.sh +0 -377
  419. package/scripts/maintenance/check-updates.sh +0 -131
  420. package/scripts/release/package-policy-bundles.sh +0 -125
@@ -4,13 +4,13 @@
4
4
  ##
5
5
  ## Provides AI CLI status, setup, RAG query, and bridge commands.
6
6
  ## Wraps AI CLI tools with contextual patterns and system metadata.
7
- ## Usage: dot ai|ai-setup|ai-query|cl|copilot|gemini|kiro|sgpt|ollama|opencode|aider|autohand|vibe|qwen|zai
7
+ ## Usage: dot ai [delegate|cost|status]|ai-setup|ai-query|cl|copilot|gemini|kiro|sgpt|ollama|opencode|aider|autohand|vibe|qwen|zai
8
8
 
9
9
  set -euo pipefail
10
10
 
11
11
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
- # shellcheck source=../lib/utils.sh
13
- source "$SCRIPT_DIR/../lib/utils.sh"
12
+ # shellcheck source=../../../lib/dot/utils.sh
13
+ source "$SCRIPT_DIR/../../../lib/dot/utils.sh"
14
14
 
15
15
  dot_ui_command_banner "AI and Agents" "${1:-}"
16
16
 
@@ -82,16 +82,18 @@ _ai_refresh_status_cache() {
82
82
  indexed+=("$i|$entry")
83
83
  i=$((i + 1))
84
84
  done
85
+ # Probe is non-interactive: </dev/null is a clean EOF for tools that
86
+ # prompt for an API key on first run; `timeout 3` caps the wait.
85
87
  # shellcheck disable=SC2016
88
+ local _TO=""
89
+ command -v timeout >/dev/null 2>&1 && _TO="timeout 3 "
86
90
  local probe_script='
87
- payload="$1"
88
- out_dir="$2"
89
- i="${payload%%|*}"
90
- entry="${payload#*|}"
91
+ payload="$1"; out_dir="$2"; to="$3"
92
+ i="${payload%%|*}"; entry="${payload#*|}"
91
93
  IFS="|" read -r category role name bin desc <<<"$entry"
92
94
  if command -v "$bin" >/dev/null 2>&1; then
93
- output=$("$bin" --version 2>/dev/null | head -1) || true
94
- version=$(printf "%s" "$output" | sed "s/^[^0-9]*//" | sed "s/[[:space:]]*$//" | sed "s/\.$//")
95
+ output=$($to "$bin" --version </dev/null 2>/dev/null | head -1) || true
96
+ version=$(printf "%s" "$output" | sed "s/^[^0-9]*//;s/[[:space:]]*$//;s/\.$//")
95
97
  printf "%s\t1\t%s\n" "$bin" "$version" >"$out_dir/$i"
96
98
  else
97
99
  printf "%s\t0\t\n" "$bin" >"$out_dir/$i"
@@ -107,7 +109,7 @@ _ai_refresh_status_cache() {
107
109
  # agent") don't trigger xargs's "unterminated quote" parser.
108
110
  printf '%s\0' "${indexed[@]}" |
109
111
  xargs -0 -I{} -P"$jobs" \
110
- bash -c "$probe_script" _ {} "$probe_dir" \
112
+ bash -c "$probe_script" _ {} "$probe_dir" "$_TO" \
111
113
  2>/dev/null || true
112
114
 
113
115
  # Re-assemble in original entry order.
@@ -312,6 +314,94 @@ cmd_ai_query() {
312
314
  run_script "dot_local/bin/executable_dot-ai" "AI RAG script" "$@"
313
315
  }
314
316
 
317
+ # Locate the vibe-delegate / delegate-report tools deployed by the
318
+ # /vibe Claude Code skill. Path stays in sync with
319
+ # defaults/dot_claude/skills/vibe/tools/.
320
+ _ai_delegate_tool() {
321
+ local tool="$1" # vibe-delegate | delegate-report
322
+ local path="${HOME}/.claude/skills/vibe/tools/${tool}"
323
+ if [[ ! -x "$path" ]]; then
324
+ # Errors to stderr so callers capturing stdout via $() get just the path.
325
+ ui_err "$tool" "not found at $path" >&2
326
+ ui_info "Hint" "Run 'chezmoi apply' to deploy the /vibe skill" >&2
327
+ return 1
328
+ fi
329
+ printf '%s\n' "$path"
330
+ }
331
+
332
+ cmd_ai_delegate() {
333
+ # Front-door to the same delegator the /vibe slash command uses.
334
+ # Usage: dot ai delegate "<prompt>" [max-turns] [agent] [timeout]
335
+ if [[ $# -lt 1 ]]; then
336
+ ui_err "Usage" "dot ai delegate \"<prompt>\" [max-turns] [agent] [timeout-secs]"
337
+ ui_info "Example" "dot ai delegate \"add a CHANGELOG entry for v0.2.504\""
338
+ return 1
339
+ fi
340
+ local prompt="$1"
341
+ shift
342
+ local max_turns="${1:-10}"
343
+ local agent="${2:-}"
344
+ local timeout="${3:-180}"
345
+ local tool
346
+ tool="$(_ai_delegate_tool vibe-delegate)" || return 1
347
+ if ! has_command vibe; then
348
+ ui_warn "vibe" "not installed"
349
+ ui_info "Install" "mise use -g pipx:mistral-vibe"
350
+ return 1
351
+ fi
352
+ "$tool" "$(pwd)" "$prompt" "$max_turns" "$agent" "$timeout"
353
+ }
354
+
355
+ cmd_ai_cost() {
356
+ # Unified AI spend report. Wraps delegate-report (vibe runs) and is
357
+ # the documented interface for users: path may move later.
358
+ local tool
359
+ tool="$(_ai_delegate_tool delegate-report)" || return 1
360
+ "$tool" "$@"
361
+ }
362
+
363
+ # Append a best-effort run entry to the unified AI log read by
364
+ # delegate-report. Token/cost fields are left blank when the provider
365
+ # CLI does not surface them — the report tolerates missing fields and
366
+ # groups by `model`. This gives users one place to see invocations
367
+ # across Claude, Gemini, Aider, Vibe, etc., not just Vibe.
368
+ _ai_log_run() {
369
+ local provider="$1" exit_code="$2" duration_secs="$3" prompt_words="$4"
370
+ local log_file="${HOME}/.local/share/delegate-runs.jsonl"
371
+ mkdir -p "$(dirname "$log_file")"
372
+ local project ts
373
+ project="$(basename "$PWD")"
374
+ ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
375
+ # python3 keeps the encoding boring; jq would also work but isn't
376
+ # guaranteed present everywhere this script runs.
377
+ python3 - "$log_file" "$provider" "$project" "$exit_code" "$duration_secs" "$prompt_words" "$ts" <<'PY'
378
+ import json, sys
379
+ log, provider, project, ec, dur, pw, ts = sys.argv[1:8]
380
+ entry = {
381
+ "ts": ts,
382
+ "delegate": provider,
383
+ "model": provider,
384
+ "project": project,
385
+ "exit_code": int(ec),
386
+ "duration_secs": float(dur),
387
+ "prompt_words": int(pw),
388
+ "tool_calls": 0,
389
+ "files_changed": 0,
390
+ "wrote_nothing": False,
391
+ "warn_count": 0,
392
+ "search_replace_fails": 0,
393
+ "syntax_errors": 0,
394
+ "tokens_in": 0,
395
+ "tokens_out": 0,
396
+ "tokens_total": 0,
397
+ "cost_usd": 0,
398
+ "cost_claude_eq": 0,
399
+ }
400
+ with open(log, "a") as fh:
401
+ fh.write(json.dumps(entry) + "\n")
402
+ PY
403
+ }
404
+
315
405
  run_ai_with_context() {
316
406
  local tool="$1"
317
407
  shift
@@ -405,61 +495,90 @@ ${prompt}"
405
495
 
406
496
  ui_info "Executing $tool with pattern: ${pattern_name:-none}"
407
497
 
498
+ # Wrap the provider invocation so we can log it to the unified AI run
499
+ # log. Each entry feeds `dot ai cost` so users see spend across every
500
+ # provider, not just vibe. Token-level fields are zero for providers
501
+ # that don't surface them — the report tolerates missing data.
502
+ local _ai_start_ts _ai_exit _ai_end_ts _ai_dur _ai_prompt_words
503
+ _ai_start_ts=$(date +%s)
504
+ _ai_prompt_words=$(printf '%s' "$prompt" | wc -w | tr -d ' ')
505
+ _ai_exit=0
408
506
  case "$tool" in
409
507
  cl | claude)
410
- printf "%s" "$full_prompt" | claude
508
+ printf "%s" "$full_prompt" | claude || _ai_exit=$?
411
509
  ;;
412
510
  codex)
413
- printf "%s" "$full_prompt" | codex
511
+ printf "%s" "$full_prompt" | codex || _ai_exit=$?
414
512
  ;;
415
513
  copilot)
416
- copilot -sp "$full_prompt"
514
+ copilot -sp "$full_prompt" || _ai_exit=$?
417
515
  ;;
418
516
  gemini)
419
- printf "%s" "$full_prompt" | gemini chat
517
+ printf "%s" "$full_prompt" | gemini chat || _ai_exit=$?
420
518
  ;;
421
519
  goose)
422
- printf "%s" "$full_prompt" | goose session start
520
+ printf "%s" "$full_prompt" | goose session start || _ai_exit=$?
423
521
  ;;
424
522
  kiro | kiro-cli)
425
- printf "%s" "$full_prompt" | kiro-cli chat
523
+ printf "%s" "$full_prompt" | kiro-cli chat || _ai_exit=$?
426
524
  ;;
427
525
  sgpt)
428
- printf "%s" "$full_prompt" | sgpt --chat shell-gpt
526
+ printf "%s" "$full_prompt" | sgpt --chat shell-gpt || _ai_exit=$?
429
527
  ;;
430
528
  ollama)
431
- printf "%s" "$full_prompt" | ollama run llama3.2
529
+ printf "%s" "$full_prompt" | ollama run llama3.2 || _ai_exit=$?
432
530
  ;;
433
531
  opencode)
434
- printf "%s" "$full_prompt" | opencode query
532
+ printf "%s" "$full_prompt" | opencode query || _ai_exit=$?
435
533
  ;;
436
534
  aider)
437
- printf "%s" "$full_prompt" | aider --msg "-"
535
+ printf "%s" "$full_prompt" | aider --msg "-" || _ai_exit=$?
438
536
  ;;
439
537
  autohand)
440
- printf "%s" "$full_prompt" | autohand chat
538
+ printf "%s" "$full_prompt" | autohand chat || _ai_exit=$?
441
539
  ;;
442
540
  vibe)
443
- printf "%s" "$full_prompt" | vibe chat
541
+ printf "%s" "$full_prompt" | vibe chat || _ai_exit=$?
444
542
  ;;
445
543
  qwen)
446
- printf "%s" "$full_prompt" | qwen chat
544
+ printf "%s" "$full_prompt" | qwen chat || _ai_exit=$?
447
545
  ;;
448
546
  zai)
449
- printf "%s" "$full_prompt" | zai chat
547
+ printf "%s" "$full_prompt" | zai chat || _ai_exit=$?
450
548
  ;;
451
549
  *)
452
550
  ui_err "Unsupported tool" "$tool"
453
551
  exit 1
454
552
  ;;
455
553
  esac
554
+ _ai_end_ts=$(date +%s)
555
+ _ai_dur=$((_ai_end_ts - _ai_start_ts))
556
+ _ai_log_run "$tool_bin" "$_ai_exit" "$_ai_dur" "$_ai_prompt_words" 2>/dev/null || true
557
+ return "$_ai_exit"
456
558
  }
457
559
 
458
560
  # Dispatch
459
561
  case "${1:-}" in
460
562
  ai)
461
563
  shift
462
- cmd_ai_status "$@"
564
+ # Subcommands first: `dot ai delegate`, `dot ai cost`. Fall through
565
+ # to status if no subcommand or unknown one.
566
+ case "${1:-}" in
567
+ delegate)
568
+ shift
569
+ cmd_ai_delegate "$@"
570
+ ;;
571
+ cost)
572
+ shift
573
+ cmd_ai_cost "$@"
574
+ ;;
575
+ "" | status)
576
+ cmd_ai_status "$@"
577
+ ;;
578
+ *)
579
+ cmd_ai_status "$@"
580
+ ;;
581
+ esac
463
582
  ;;
464
583
  ai-setup)
465
584
  shift
@@ -40,11 +40,11 @@ cmd_aliases() {
40
40
  list)
41
41
  ui_header "Aliases"
42
42
  echo ""
43
- printf " %-18s %-42s %s\n" "Name" "Value" "Source"
44
- echo " $(printf '%.18s' '------------------') $(printf '%.42s' '------------------------------------------') -------------------------"
45
- emit_alias_manifest | sort -t $'\t' -k1,1 | while IFS=$'\t' read -r name value file line; do
46
- printf " %-18s %-42s %s:%s\n" "$name" "${value:0:42}" "${file##*/}" "$line"
47
- done
43
+ ui_table_begin "Name" "Value" "Source"
44
+ while IFS=$'\t' read -r name value file line; do
45
+ ui_table_add "$name" "${value:0:60}" "${file##*/}:$line"
46
+ done < <(emit_alias_manifest | sort -t $'\t' -k1,1)
47
+ ui_table_end
48
48
  ;;
49
49
  search)
50
50
  local query="${1:-}"
@@ -60,9 +60,11 @@ cmd_aliases() {
60
60
  ui_warn "No matches" "$query"
61
61
  return 1
62
62
  fi
63
- printf "%s\n" "$results" | while IFS=$'\t' read -r name value file line; do
64
- printf " %-18s %-42s %s:%s\n" "$name" "${value:0:42}" "$file" "$line"
65
- done
63
+ ui_table_begin "Name" "Value" "Source"
64
+ while IFS=$'\t' read -r name value file line; do
65
+ ui_table_add "$name" "${value:0:60}" "$file:$line"
66
+ done <<<"$results"
67
+ ui_table_end
66
68
  ;;
67
69
  why)
68
70
  local alias_name="${1:-}"
@@ -6,8 +6,8 @@
6
6
  set -euo pipefail
7
7
 
8
8
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
- # shellcheck source=../lib/utils.sh
10
- source "$SCRIPT_DIR/../lib/utils.sh"
9
+ # shellcheck source=../../../lib/dot/utils.sh
10
+ source "$SCRIPT_DIR/../../../lib/dot/utils.sh"
11
11
 
12
12
  dot_ui_command_banner "Appearance" "${1:-}"
13
13
 
@@ -26,8 +26,8 @@
26
26
  set -euo pipefail
27
27
 
28
28
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
29
- # shellcheck source=../lib/utils.sh
30
- source "$SCRIPT_DIR/../lib/utils.sh"
29
+ # shellcheck source=../../../lib/dot/utils.sh
30
+ source "$SCRIPT_DIR/../../../lib/dot/utils.sh"
31
31
 
32
32
  if [[ "${1:-}" != "cd" ]]; then
33
33
  dot_ui_command_banner "Core" "${1:-}"
@@ -77,13 +77,19 @@ cmd_diff() {
77
77
  }
78
78
 
79
79
  cmd_status() {
80
- local out
81
- out="$(chezmoi status "$@" || true)"
80
+ local out rc=0
81
+ # Capture chezmoi's stderr too so an actual tool failure surfaces
82
+ # to the user instead of being indistinguishable from a clean tree.
83
+ out="$(chezmoi status "$@" 2>&1)" || rc=$?
84
+ ui_header "Dotfiles Status"
85
+ if [[ "$rc" -ne 0 ]]; then
86
+ ui_err "chezmoi" "exited $rc"
87
+ [[ -n "$out" ]] && printf "%s\n" "$out"
88
+ return "$rc"
89
+ fi
82
90
  if [[ -z "$out" ]]; then
83
- ui_header "Dotfiles Status"
84
91
  ui_ok "Clean" "no local drift detected"
85
92
  else
86
- ui_header "Dotfiles Status"
87
93
  printf "%s\n" "$out"
88
94
  fi
89
95
  }
@@ -7,8 +7,8 @@
7
7
  set -euo pipefail
8
8
 
9
9
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10
- # shellcheck source=../lib/utils.sh
11
- source "$SCRIPT_DIR/../lib/utils.sh"
10
+ # shellcheck source=../../../lib/dot/utils.sh
11
+ source "$SCRIPT_DIR/../../../lib/dot/utils.sh"
12
12
 
13
13
  dot_ui_command_banner "Diagnostics" "${1:-}" "$@"
14
14
 
@@ -29,7 +29,7 @@ cmd_smoke_test() {
29
29
  }
30
30
 
31
31
  cmd_intelligence() {
32
- run_script "scripts/dot/lib/bento.sh" "Intelligence Surface" "$@"
32
+ run_script "lib/dot/bento.sh" "Intelligence Surface" "$@"
33
33
  }
34
34
 
35
35
  cmd_heal() {
@@ -120,9 +120,9 @@ cmd_metrics() {
120
120
  echo "Dotfiles source not found." >&2
121
121
  exit 1
122
122
  fi
123
- # shellcheck source=../lib/log.sh
123
+ # shellcheck source=../../../lib/dot/log.sh
124
124
  # shellcheck disable=SC1091
125
- source "$src_dir/scripts/dot/lib/log.sh"
125
+ source "$src_dir/lib/dot/log.sh"
126
126
  ui_header "Recent Metrics"
127
127
  echo ""
128
128
  dot_metrics_summary "${1:-20}"
@@ -0,0 +1,202 @@
1
+ #!/usr/bin/env bash
2
+ # Copyright (c) 2015-2026 Dotfiles. All rights reserved.
3
+ #
4
+ # `dot env emit` — render a portable workstation-environment
5
+ # manifest. The output is the canonical "what is installed on this
6
+ # machine + at what version + from which source" record that
7
+ # downstream tooling (CycloneDX SBOM aggregators, AgentSpec /
8
+ # AAIF agents, EU CRA compliance reports) consumes.
9
+ #
10
+ # v1 schema at docs/schema/dot-env-v1.json. Conforming to a fixed
11
+ # schema lets us re-render this manifest into any downstream format
12
+ # (AGENTS.md, devcontainer-feature.json, Brewfile, mise.toml) from
13
+ # a single source of truth — see docs/operations/MANIFEST.md.
14
+ #
15
+ # Usage:
16
+ # dot env emit # default: json
17
+ # dot env emit --format json
18
+ # dot env emit --output env.json
19
+ # dot env emit --pretty # default; --compact for one-line
20
+ #
21
+ # Exit codes:
22
+ # 0 manifest written / printed
23
+ # 1 bad usage
24
+ # 2 jq or mise missing
25
+ # 3 mise call failed
26
+
27
+ set -euo pipefail
28
+
29
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
30
+ # shellcheck source=../../../lib/dot/utils.sh
31
+ source "$SCRIPT_DIR/../../../lib/dot/utils.sh"
32
+
33
+ dot_env_emit() {
34
+ local format="json"
35
+ local output=""
36
+ local pretty=1
37
+
38
+ while (($#)); do
39
+ case "$1" in
40
+ --format)
41
+ format="${2:-}"
42
+ shift 2 || {
43
+ ui_err "--format needs a value"
44
+ return 1
45
+ }
46
+ ;;
47
+ --format=*)
48
+ format="${1#*=}"
49
+ shift
50
+ ;;
51
+ --output | -o)
52
+ output="${2:-}"
53
+ shift 2 || {
54
+ ui_err "--output needs a value"
55
+ return 1
56
+ }
57
+ ;;
58
+ --output=*)
59
+ output="${1#*=}"
60
+ shift
61
+ ;;
62
+ --pretty)
63
+ pretty=1
64
+ shift
65
+ ;;
66
+ --compact)
67
+ pretty=0
68
+ shift
69
+ ;;
70
+ -h | --help)
71
+ cat <<-EOF
72
+ Usage: dot env emit [--format <fmt>] [--output <path>] [--pretty|--compact]
73
+
74
+ Render the workstation-environment manifest (v1 schema).
75
+
76
+ Formats:
77
+ json (default) v1 canonical form per docs/schema/dot-env-v1.json
78
+ ndjson one JSON object per tool — easier to grep / pipe
79
+
80
+ Output:
81
+ --output FILE write to FILE (atomic mktemp + mv)
82
+ default stdout
83
+
84
+ Examples:
85
+ dot env emit # print to stdout
86
+ dot env emit --output env.json # write atomically
87
+ dot env emit --format ndjson | grep '^{"name":"node"'
88
+ EOF
89
+ return 0
90
+ ;;
91
+ *)
92
+ ui_err "unknown flag: $1"
93
+ return 1
94
+ ;;
95
+ esac
96
+ done
97
+
98
+ case "$format" in
99
+ json | ndjson) ;;
100
+ *)
101
+ ui_err "unsupported format: $format (json, ndjson)"
102
+ return 1
103
+ ;;
104
+ esac
105
+
106
+ has_command jq || {
107
+ ui_err "jq required (brew install jq / apt install jq)"
108
+ return 2
109
+ }
110
+ has_command mise || {
111
+ ui_err "mise required (the manifest's source of truth)"
112
+ return 2
113
+ }
114
+
115
+ local mise_raw
116
+ mise_raw="$(mise ls --json 2>/dev/null)" || {
117
+ ui_err "mise ls --json failed"
118
+ return 3
119
+ }
120
+
121
+ # Static fields we want in every manifest: schema version + emit
122
+ # timestamp + emitter version + repo URL + the host fingerprint
123
+ # bits chezmoi already records (os, machine).
124
+ local emitter_version
125
+ emitter_version="$(grep -E '^dotfiles_version[[:space:]]*=' \
126
+ "$(resolve_chezmoi_source_dir)/.chezmoidata.toml" 2>/dev/null |
127
+ head -1 | sed -E 's/.*"([^"]+)".*/\1/' || echo "unknown")"
128
+ local timestamp
129
+ timestamp="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
130
+ local os_type machine_arch
131
+ os_type="$(uname -s 2>/dev/null || echo unknown)"
132
+ machine_arch="$(uname -m 2>/dev/null || echo unknown)"
133
+ local hostname
134
+ hostname="$(uname -n 2>/dev/null || echo unknown)"
135
+
136
+ # Build the manifest. jq does the heavy lifting: take the raw
137
+ # `mise ls --json` shape (an object keyed by tool name → array of
138
+ # installed versions) and flatten to a normalised array of tool
139
+ # records. Each record carries: name, version, source (config
140
+ # file or "orphan"), requested (semver/range/latest spec), and
141
+ # install_path (auditable absolute path).
142
+ local body
143
+ body="$(printf '%s' "$mise_raw" | jq --arg ev "$emitter_version" \
144
+ --arg ts "$timestamp" \
145
+ --arg os "$os_type" \
146
+ --arg arch "$machine_arch" \
147
+ --arg host "$hostname" '
148
+ {
149
+ schema_version: "https://sebastienrousseau.github.io/dotfiles/schema/dot-env-v1.json",
150
+ manifest_version: "1.0.0",
151
+ emitted_at: $ts,
152
+ emitter: {
153
+ name: "dot env emit",
154
+ version: $ev,
155
+ repo: "github.com/sebastienrousseau/dotfiles"
156
+ },
157
+ host: {
158
+ hostname: $host,
159
+ os: $os,
160
+ arch: $arch
161
+ },
162
+ tools: [
163
+ to_entries[] as $t
164
+ | $t.value[]
165
+ | {
166
+ name: $t.key,
167
+ version: (.version // null),
168
+ source: (.source.path // "orphan"),
169
+ source_type: (.source.type // null),
170
+ requested_version: (.requested_version // null),
171
+ install_path: (.install_path // null),
172
+ active: (.active // false)
173
+ }
174
+ ]
175
+ }
176
+ ')"
177
+
178
+ local rendered
179
+ if [[ "$format" == "ndjson" ]]; then
180
+ # NDJSON: header object on line 1, one tool per subsequent line.
181
+ rendered="$(
182
+ printf '%s' "$body" |
183
+ jq -c '
184
+ ({schema_version, manifest_version, emitted_at, emitter, host}),
185
+ (.tools[])'
186
+ )"
187
+ elif ((pretty)); then
188
+ rendered="$(printf '%s' "$body" | jq '.')"
189
+ else
190
+ rendered="$(printf '%s' "$body" | jq -c '.')"
191
+ fi
192
+
193
+ if [[ -n "$output" ]]; then
194
+ local tmp
195
+ tmp="$(mktemp "${output}.XXXXXX")"
196
+ printf '%s\n' "$rendered" >|"$tmp"
197
+ mv "$tmp" "$output"
198
+ ui_ok "manifest" "wrote $(printf '%s' "$rendered" | jq -r '.tools | length' 2>/dev/null || echo '?') tools → $output"
199
+ else
200
+ printf '%s\n' "$rendered"
201
+ fi
202
+ }