@sebastienrousseau/dotfiles 0.2.520 → 0.2.521

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 (323) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/LICENSE-APACHE +190 -0
  3. package/LICENSE-MIT +21 -0
  4. package/README.md +43 -37
  5. package/install.sh +76 -10
  6. package/package.json +7 -7
  7. package/tools/README.md +49 -0
  8. package/tools/ci/install-chezmoi-verified.sh +68 -0
  9. package/docs/.vitepress/reports/localization-readability-audit.md +0 -73
  10. package/docs/AI.md +0 -179
  11. package/docs/ARCHITECTURE.md +0 -117
  12. package/docs/CNAME +0 -1
  13. package/docs/CONFIG_STRATEGY.md +0 -124
  14. package/docs/COPYRIGHT +0 -7
  15. package/docs/ECOSYSTEM.md +0 -220
  16. package/docs/GOLD-STANDARD-AUDIT.md +0 -352
  17. package/docs/GOVERNANCE.md +0 -98
  18. package/docs/MAINTAINERS.md +0 -41
  19. package/docs/MINIMUM-TOOLCHAIN.md +0 -100
  20. package/docs/NAMING_CONVENTIONS.md +0 -102
  21. package/docs/OPENCODE.md +0 -127
  22. package/docs/README.md +0 -84
  23. package/docs/STRUCTURE.md +0 -102
  24. package/docs/adr/ADR-001-ci-cd-pipeline.md +0 -118
  25. package/docs/adr/ADR-002-shell-performance.md +0 -130
  26. package/docs/adr/ADR-003-security-first.md +0 -158
  27. package/docs/adr/ADR-004-cli-architecture.md +0 -171
  28. package/docs/adr/ADR-005-chezmoi-choice.md +0 -99
  29. package/docs/adr/ADR-006-shell-selection.md +0 -124
  30. package/docs/adr/ADR-007-multi-shell-parity.md +0 -62
  31. package/docs/adr/ADR-008-alias-system-architecture.md +0 -95
  32. package/docs/adr/ADR-009-wallpaper-driven-theming.md +0 -131
  33. package/docs/adr/ADR-010-starship-transient-prompt.md +0 -144
  34. package/docs/adr/ADR-011-nushell-tier3-keep.md +0 -144
  35. package/docs/adr/ADR-012-ai-fleet-local-proxy.md +0 -79
  36. package/docs/adr/README.md +0 -40
  37. package/docs/architecture/AI_COST_OPTIMIZATION.md +0 -144
  38. package/docs/architecture/ARCHITECTURE.md +0 -20
  39. package/docs/architecture/INTEROP.md +0 -44
  40. package/docs/architecture/REPO_LAYOUT.md +0 -241
  41. package/docs/architecture/WALKTHROUGH.md +0 -86
  42. package/docs/architecture/fleet-deployment.md +0 -77
  43. package/docs/archive/EUXIS_2026_REVIEW.md +0 -127
  44. package/docs/archive/LEGACY_ROADMAP.md +0 -6
  45. package/docs/archive/MILESTONE_v0.2.493.md +0 -47
  46. package/docs/archive/PLAN.md +0 -199
  47. package/docs/archive/REPO_AUDIT.md +0 -31
  48. package/docs/articles/.pages +0 -6
  49. package/docs/articles/2026-07-05-custom-mkdocs-material-dark-theme.md +0 -216
  50. package/docs/articles/2026-07-05-fish-startup-abbr.md +0 -153
  51. package/docs/articles/2026-07-05-master-to-main-rename-runbook.md +0 -128
  52. package/docs/articles/index.md +0 -36
  53. package/docs/guides/INSTALL.md +0 -144
  54. package/docs/guides/MACOS_ICLOUD_SYMLINKS.md +0 -121
  55. package/docs/guides/NEOVIM_IDE_GUIDE.md +0 -61
  56. package/docs/guides/THEMING.md +0 -230
  57. package/docs/guides/TROUBLESHOOTING.md +0 -176
  58. package/docs/guides/WSL2_NIX_TROUBLESHOOTING.md +0 -792
  59. package/docs/index.md +0 -132
  60. package/docs/interop/A2A.md +0 -39
  61. package/docs/interop/POWERSHELL.md +0 -102
  62. package/docs/manual/00-introduction.md +0 -89
  63. package/docs/manual/01-concepts/01-architecture.md +0 -138
  64. package/docs/manual/01-concepts/02-trust-model.md +0 -183
  65. package/docs/manual/01-concepts/03-theme-engine.md +0 -186
  66. package/docs/manual/01-concepts/04-fleet.md +0 -148
  67. package/docs/manual/01-concepts/05-self-healing.md +0 -204
  68. package/docs/manual/02-tutorials/01-first-install.md +0 -197
  69. package/docs/manual/02-tutorials/02-add-wallpaper.md +0 -216
  70. package/docs/manual/02-tutorials/03-create-profile.md +0 -244
  71. package/docs/manual/02-tutorials/04-encrypt-secret.md +0 -281
  72. package/docs/manual/02-tutorials/05-deploy-fleet.md +0 -283
  73. package/docs/manual/03-reference/01-dot-cli.md +0 -475
  74. package/docs/manual/03-reference/02-config-files.md +0 -265
  75. package/docs/manual/03-reference/03-environment.md +0 -124
  76. package/docs/manual/03-reference/04-templates.md +0 -190
  77. package/docs/manual/03-reference/05-feature-flags.md +0 -187
  78. package/docs/manual/04-cookbook/01-recipes.md +0 -285
  79. package/docs/manual/04-cookbook/02-troubleshooting.md +0 -351
  80. package/docs/manual/04-cookbook/03-faq.md +0 -175
  81. package/docs/manual/05-appendices/A-platform-matrix.md +0 -101
  82. package/docs/manual/05-appendices/B-security-checklist.md +0 -85
  83. package/docs/manual/05-appendices/C-glossary.md +0 -40
  84. package/docs/manual/05-appendices/D-bibliography.md +0 -58
  85. package/docs/manual/05-appendices/E-license.md +0 -38
  86. package/docs/manual/_toc.yml +0 -58
  87. package/docs/manual/command-index.md +0 -175
  88. package/docs/manual/concept-index.md +0 -170
  89. package/docs/manual/index.md +0 -66
  90. package/docs/migration/README.md +0 -81
  91. package/docs/migration/from-bare-git-repo.md +0 -156
  92. package/docs/migration/from-gnu-stow.md +0 -165
  93. package/docs/migration/from-plain-chezmoi.md +0 -148
  94. package/docs/migration/from-yadm.md +0 -187
  95. package/docs/operations/ARCHITECTURE_ROADMAP.md +0 -7
  96. package/docs/operations/ATTESTATION.md +0 -44
  97. package/docs/operations/CI_CADENCE.md +0 -107
  98. package/docs/operations/CI_COMPOSITES.md +0 -156
  99. package/docs/operations/COMPLETIONS.md +0 -123
  100. package/docs/operations/COVERAGE.md +0 -204
  101. package/docs/operations/DRIFT.md +0 -107
  102. package/docs/operations/HARD_AUDIT_2026.md +0 -631
  103. package/docs/operations/MAINTENANCE.md +0 -63
  104. package/docs/operations/MANIFEST.md +0 -127
  105. package/docs/operations/MIGRATION.md +0 -109
  106. package/docs/operations/OPERATIONS.md +0 -188
  107. package/docs/operations/PERFORMANCE.md +0 -133
  108. package/docs/operations/PERFORMANCE_BUDGETS.md +0 -196
  109. package/docs/operations/REGISTRY.md +0 -90
  110. package/docs/operations/RELEASE_PIPELINE.md +0 -128
  111. package/docs/operations/RELIABILITY.md +0 -122
  112. package/docs/operations/RFC_v0_2_503_reorganization.md +0 -280
  113. package/docs/operations/ROADMAP.md +0 -10
  114. package/docs/operations/ROADMAP_2026.md +0 -7
  115. package/docs/operations/ROADMAP_V0_2_503.md +0 -10
  116. package/docs/operations/TESTING.md +0 -216
  117. package/docs/operations/TRACEABILITY.md +0 -44
  118. package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +0 -65
  119. package/docs/operations/VERSION_SYNC.md +0 -393
  120. package/docs/packaging.md +0 -222
  121. package/docs/reference/ALIASES.md +0 -131
  122. package/docs/reference/ALIASES_CHEATSHEET.md +0 -32
  123. package/docs/reference/ALIASES_DEPRECATIONS.md +0 -13
  124. package/docs/reference/FEATURE-MATRIX.md +0 -646
  125. package/docs/reference/FEATURES.md +0 -66
  126. package/docs/reference/FONTS.md +0 -112
  127. package/docs/reference/POWERSHELL_PARITY.md +0 -82
  128. package/docs/reference/PROFILES.md +0 -69
  129. package/docs/reference/SCREENSHOTS.md +0 -121
  130. package/docs/reference/SCRIPTS.md +0 -71
  131. package/docs/reference/SUPPORT_MATRIX.md +0 -80
  132. package/docs/reference/THEMES.md +0 -117
  133. package/docs/reference/TOOLS.md +0 -110
  134. package/docs/reference/UTILS.md +0 -243
  135. package/docs/registry.json +0 -6
  136. package/docs/schema/dot-env-v1.json +0 -110
  137. package/docs/schema/dot-registry-v1.json +0 -33
  138. package/docs/security/AI_ACT_COMPLIANCE.md +0 -94
  139. package/docs/security/AUDIT_BYPASS.md +0 -103
  140. package/docs/security/AUTOMATION_SECRETS.md +0 -26
  141. package/docs/security/CI_EGRESS_ALLOWLIST.md +0 -127
  142. package/docs/security/CI_PINNING.md +0 -129
  143. package/docs/security/COMMIT_SIGNING.md +0 -138
  144. package/docs/security/COMPLIANCE.md +0 -458
  145. package/docs/security/DEPS_DEV_EXCEPTIONS.md +0 -86
  146. package/docs/security/DISCLOSURE.md +0 -130
  147. package/docs/security/ENCRYPTION.md +0 -57
  148. package/docs/security/FMEA.md +0 -159
  149. package/docs/security/FUZZING.md +0 -209
  150. package/docs/security/HISTORY_FILTERING.md +0 -132
  151. package/docs/security/INCIDENT_RESPONSE.md +0 -579
  152. package/docs/security/INSTALL_VERIFICATION.md +0 -122
  153. package/docs/security/KEYS.md +0 -49
  154. package/docs/security/KEY_ROTATION.md +0 -303
  155. package/docs/security/MCP_POLICY.md +0 -78
  156. package/docs/security/POLICY_RELEASES.md +0 -37
  157. package/docs/security/README.md +0 -28
  158. package/docs/security/SCORECARD.md +0 -195
  159. package/docs/security/SECRETS.md +0 -158
  160. package/docs/security/SECURITY.md +0 -45
  161. package/docs/security/SECURITY_CHECKLIST.md +0 -55
  162. package/docs/security/SHELL_EXEMPTIONS.md +0 -145
  163. package/docs/security/SOUP_REGISTER.md +0 -36
  164. package/docs/security/THREAT_MODEL.md +0 -130
  165. package/docs/security/VERIFICATION_VALIDATION.md +0 -228
  166. package/docs/security/VERIFY_RELEASE.md +0 -201
  167. package/docs/security/security-pubkey.asc +0 -15
  168. package/docs/stylesheets/extra.css +0 -444
  169. package/docs/themes/README.md +0 -10
  170. package/docs/themes/VISUAL_INTEGRITY_REPORT.md +0 -30
  171. package/docs/themes/hero-shot.svg +0 -78
  172. package/scripts/README.md +0 -123
  173. package/scripts/ci/check-copyright-headers.sh +0 -8
  174. package/scripts/ci/check-shell-preamble.sh +0 -8
  175. package/scripts/ci/guard-gitleaks-checkout.sh +0 -8
  176. package/scripts/demo/record.sh +0 -43
  177. package/scripts/diagnostics/a2a-conformance.sh +0 -163
  178. package/scripts/diagnostics/alias-governance.sh +0 -165
  179. package/scripts/diagnostics/aliases-cheatsheet.sh +0 -74
  180. package/scripts/diagnostics/aliases-manifest.sh +0 -77
  181. package/scripts/diagnostics/attest-verify.sh +0 -147
  182. package/scripts/diagnostics/benchmark.sh +0 -408
  183. package/scripts/diagnostics/conflicts.sh +0 -73
  184. package/scripts/diagnostics/doctor-unified.sh +0 -43
  185. package/scripts/diagnostics/doctor.sh +0 -797
  186. package/scripts/diagnostics/drift-dashboard.sh +0 -203
  187. package/scripts/diagnostics/health.sh +0 -656
  188. package/scripts/diagnostics/history-analysis.sh +0 -86
  189. package/scripts/diagnostics/mcp-doctor.sh +0 -582
  190. package/scripts/diagnostics/perf.sh +0 -453
  191. package/scripts/diagnostics/scorecard.sh +0 -120
  192. package/scripts/diagnostics/secret-governance.sh +0 -65
  193. package/scripts/diagnostics/security-score.sh +0 -467
  194. package/scripts/diagnostics/smoke-test.sh +0 -88
  195. package/scripts/diagnostics/snapshot.sh +0 -90
  196. package/scripts/diagnostics/verify.sh +0 -108
  197. package/scripts/diagnostics/verify_state.sh +0 -73
  198. package/scripts/diagnostics/version-locks.sh +0 -94
  199. package/scripts/diagnostics/workstation-attestation.sh +0 -212
  200. package/scripts/dot/commands/agent.sh +0 -535
  201. package/scripts/dot/commands/agents.sh +0 -352
  202. package/scripts/dot/commands/ai.sh +0 -600
  203. package/scripts/dot/commands/aliases.sh +0 -277
  204. package/scripts/dot/commands/appearance.sh +0 -110
  205. package/scripts/dot/commands/completion.sh +0 -171
  206. package/scripts/dot/commands/core.sh +0 -217
  207. package/scripts/dot/commands/diagnostics.sh +0 -265
  208. package/scripts/dot/commands/env-emit.sh +0 -203
  209. package/scripts/dot/commands/fleet.sh +0 -711
  210. package/scripts/dot/commands/init.sh +0 -185
  211. package/scripts/dot/commands/lint.sh +0 -208
  212. package/scripts/dot/commands/manual.sh +0 -169
  213. package/scripts/dot/commands/meta.sh +0 -438
  214. package/scripts/dot/commands/patterns.sh +0 -55
  215. package/scripts/dot/commands/registry.sh +0 -455
  216. package/scripts/dot/commands/restore.sh +0 -232
  217. package/scripts/dot/commands/secrets.sh +0 -296
  218. package/scripts/dot/commands/security.sh +0 -102
  219. package/scripts/dot/commands/tools.sh +0 -570
  220. package/scripts/dot/data/alias-deprecations.tsv +0 -2
  221. package/scripts/dot/powershell/Dot.psm1 +0 -319
  222. package/scripts/fonts/install-nerd-fonts.sh +0 -75
  223. package/scripts/fonts/patch-fonts.sh +0 -36
  224. package/scripts/git-hooks/install.sh +0 -12
  225. package/scripts/git-hooks/pre-commit +0 -12
  226. package/scripts/git-hooks/pre-commit-audit.sh +0 -146
  227. package/scripts/git-hooks/pre-push +0 -105
  228. package/scripts/git-hooks/prepare-commit-msg +0 -29
  229. package/scripts/lib/secrets_provider.sh +0 -200
  230. package/scripts/nvim/headless-upgrade.lua +0 -81
  231. package/scripts/ops/ai-setup.sh +0 -71
  232. package/scripts/ops/bundle.sh +0 -104
  233. package/scripts/ops/chaos.sh +0 -50
  234. package/scripts/ops/chezmoi-apply.sh +0 -333
  235. package/scripts/ops/chezmoi-diff.sh +0 -16
  236. package/scripts/ops/chezmoi-remove.sh +0 -46
  237. package/scripts/ops/chezmoi-update.sh +0 -67
  238. package/scripts/ops/heal-chezmoi.sh +0 -87
  239. package/scripts/ops/heal-system.sh +0 -129
  240. package/scripts/ops/heal-tools.sh +0 -297
  241. package/scripts/ops/heal.sh +0 -223
  242. package/scripts/ops/post-apply-repair.sh +0 -107
  243. package/scripts/ops/prewarm.sh +0 -128
  244. package/scripts/ops/release.sh +0 -262
  245. package/scripts/ops/rollback.sh +0 -613
  246. package/scripts/ops/setup.sh +0 -138
  247. package/scripts/ops/teleport.sh +0 -34
  248. package/scripts/qa/check-feature-matrix.sh +0 -296
  249. package/scripts/qa/check-version-consistency.sh +0 -12
  250. package/scripts/qa/coverage-baseline.sh +0 -61
  251. package/scripts/qa/docs-coverage.sh +0 -118
  252. package/scripts/qa/examples-coverage.sh +0 -94
  253. package/scripts/qa/powershell-contract.ps1 +0 -95
  254. package/scripts/qa/reliability-audit.sh +0 -139
  255. package/scripts/qa/scorecard-snapshot.sh +0 -128
  256. package/scripts/qa/traceability-coverage.sh +0 -124
  257. package/scripts/qa/validate-examples.sh +0 -90
  258. package/scripts/qa/wsl-contract.sh +0 -12
  259. package/scripts/secrets/age-init.sh +0 -82
  260. package/scripts/secrets/create-secrets-file.sh +0 -46
  261. package/scripts/secrets/encrypt-ssh-key.sh +0 -44
  262. package/scripts/security/backup.sh +0 -58
  263. package/scripts/security/check-disclosure-key-expiry.sh +0 -111
  264. package/scripts/security/dns-doh.sh +0 -52
  265. package/scripts/security/encryption-check.sh +0 -55
  266. package/scripts/security/enforce-policies.sh +0 -552
  267. package/scripts/security/firewall.sh +0 -91
  268. package/scripts/security/lock-configs.sh +0 -67
  269. package/scripts/security/lock-screen.sh +0 -56
  270. package/scripts/security/manage-secrets.sh +0 -429
  271. package/scripts/security/ssh-cert.sh +0 -204
  272. package/scripts/security/telemetry-kill.sh +0 -51
  273. package/scripts/security/usb-safety.sh +0 -52
  274. package/scripts/theme/apply-gnome-theme.sh +0 -333
  275. package/scripts/theme/extract-heic-frames.sh +0 -115
  276. package/scripts/theme/extract-theme.py +0 -1020
  277. package/scripts/theme/install-boot-logo.sh +0 -63
  278. package/scripts/theme/install-catppuccin-themes.sh +0 -371
  279. package/scripts/theme/install-cursors.sh +0 -26
  280. package/scripts/theme/install-file-icons.sh +0 -27
  281. package/scripts/theme/install-grub-theme.sh +0 -62
  282. package/scripts/theme/install-lock-icon.sh +0 -31
  283. package/scripts/theme/merge-wallpaper.sh +0 -146
  284. package/scripts/theme/rebuild-themes.sh +0 -603
  285. package/scripts/theme/switch.sh +0 -476
  286. package/scripts/theme/wallpaper-rotate.sh +0 -137
  287. package/scripts/theme/wallpaper-sync.sh +0 -690
  288. package/scripts/tools/cmatrix.sh +0 -22
  289. package/scripts/tools/detect-collisions.py +0 -103
  290. package/scripts/tools/emoji-picker.sh +0 -49
  291. package/scripts/tools/figlet-banner.sh +0 -19
  292. package/scripts/tools/log-rotate.sh +0 -31
  293. package/scripts/tools/lolcat-wrap.sh +0 -20
  294. package/scripts/tools/pipes.sh +0 -49
  295. package/scripts/tuning/linux.sh +0 -186
  296. package/scripts/tuning/macos.sh +0 -56
  297. package/scripts/uninstall.sh +0 -86
  298. package/scripts/verify-release-versions +0 -156
  299. package/scripts/version-sync.sh +0 -714
  300. package/templates/chezmoi-data/geekom-a9.toml.example +0 -21
  301. package/templates/chezmoi-data/mac-m1.toml.example +0 -16
  302. package/templates/chezmoi-data/mac-t2-linux.toml.example +0 -21
  303. package/templates/chezmoi-data/surface-pro-7p.toml.example +0 -21
  304. package/templates/projects/go/.github/workflows/ci.yml +0 -31
  305. package/templates/projects/go/README.md +0 -7
  306. package/templates/projects/go/cmd/__PROJECT_NAME__/main.go +0 -8
  307. package/templates/projects/go/go.mod +0 -3
  308. package/templates/projects/go/go.sum +0 -0
  309. package/templates/projects/molecule/README.md +0 -7
  310. package/templates/projects/molecule/converge.yml +0 -7
  311. package/templates/projects/molecule/molecule.yml +0 -16
  312. package/templates/projects/node/.github/workflows/ci.yml +0 -30
  313. package/templates/projects/node/README.md +0 -7
  314. package/templates/projects/node/package-lock.json +0 -12
  315. package/templates/projects/node/package.json +0 -10
  316. package/templates/projects/node/src/index.js +0 -3
  317. package/templates/projects/packer/README.md +0 -15
  318. package/templates/projects/packer/main.pkr.hcl +0 -15
  319. package/templates/projects/python/.github/workflows/ci.yml +0 -34
  320. package/templates/projects/python/README.md +0 -7
  321. package/templates/projects/python/pyproject.toml +0 -25
  322. package/templates/projects/python/src/__PROJECT_NAME__/__init__.py +0 -2
  323. package/templates/projects/python/tests/test_basic.py +0 -3
@@ -1,535 +0,0 @@
1
- #!/usr/bin/env bash
2
- # SPDX-License-Identifier: Apache-2.0 OR MIT
3
- # Copyright (c) 2015-2026 Sebastien Rousseau
4
- # Dotfiles CLI - Agent Mode Commands (extracted from meta.sh)
5
- # mode list|current|show|set|run|doctor|card|log|checkpoint|conformance
6
-
7
- set -euo pipefail
8
-
9
- # Guard: only define functions, do not execute on source.
10
- # These functions are sourced by meta.sh for dispatch.
11
-
12
- _agent_repo_root() {
13
- # Post-Phase-4b: agent profile/card JSON ships under defaults/dot_config/.
14
- # Prefer the chezmoi source dir so callers can append dot_config/... directly.
15
- local dir
16
- dir="$(resolve_chezmoi_source_dir)"
17
- [[ -n "$dir" ]] && {
18
- printf '%s\n' "$dir"
19
- return
20
- }
21
- require_source_dir
22
- }
23
-
24
- ## _agent_run_bounded <seconds> <command…> — run a command under a wall-clock
25
- ## limit on every platform we ship to.
26
- ##
27
- ## `timeout` is GNU coreutils. Stock macOS has neither it nor `gtimeout`
28
- ## (that one arrives with `brew install coreutils`), so the delegate arm's
29
- ## former `timeout "$t" "$@"` meant the delegated command never ran at all on
30
- ## a clean Mac — it died 127, "command not found". perl is present on both
31
- ## macOS and the CI runners and gives us fork + alarm, which is what timeout(1)
32
- ## does. tests/framework/assertions.sh solves the same problem the same way.
33
- ##
34
- ## Exit codes follow GNU timeout: 124 on expiry, 128+N when signalled,
35
- ## otherwise the command's own status.
36
- _agent_run_bounded() {
37
- local seconds="$1"
38
- shift
39
- local bin
40
- bin="$(type -P timeout || true)"
41
- [[ -n "$bin" ]] || bin="$(type -P gtimeout || true)"
42
- if [[ -n "$bin" ]]; then
43
- "$bin" "$seconds" "$@"
44
- return
45
- fi
46
- if command -v perl >/dev/null 2>&1; then
47
- perl -e '
48
- my $secs = shift @ARGV;
49
- my $pid = fork();
50
- die "dot: fork failed: $!\n" unless defined $pid;
51
- if ($pid == 0) {
52
- exec { $ARGV[0] } @ARGV;
53
- exit 127;
54
- }
55
- my $timed_out = 0;
56
- $SIG{ALRM} = sub { $timed_out = 1; kill("TERM", $pid); kill("KILL", $pid); };
57
- alarm($secs);
58
- my $reaped;
59
- do { $reaped = waitpid($pid, 0); } while ($reaped == -1 && $!{EINTR});
60
- my $status = $?;
61
- alarm(0);
62
- exit(124) if $timed_out;
63
- exit($status & 127 ? 128 + ($status & 127) : $status >> 8);
64
- ' "$seconds" "$@"
65
- return
66
- fi
67
- # Neither available: running the command is still better than refusing to,
68
- # but the lost guarantee is said out loud rather than assumed.
69
- ui_warn "Delegate" "no timeout(1) or perl on PATH — running without a time limit"
70
- "$@"
71
- }
72
-
73
- _agent_profiles_file() {
74
- local repo_root
75
- repo_root="$(_agent_repo_root)"
76
- echo "${AGENT_PROFILE_CONFIG:-$repo_root/dot_config/dotfiles/agent-profiles.json}"
77
- }
78
-
79
- _agent_state_file() {
80
- echo "${AGENT_STATE_FILE:-$HOME/.config/dotfiles/agent-mode.env}"
81
- }
82
-
83
- _agent_default_profile() {
84
- local file
85
- file="$(_agent_profiles_file)"
86
- jq -r '.defaultProfile' "$file"
87
- }
88
-
89
- _agent_current_profile() {
90
- local state_file current
91
- state_file="$(_agent_state_file)"
92
- if [[ -f "$state_file" ]]; then
93
- current="$(sed -n 's/^DOT_AGENT_PROFILE=//p' "$state_file" | tail -n 1)"
94
- if [[ -n "$current" ]]; then
95
- echo "$current"
96
- return 0
97
- fi
98
- fi
99
- _agent_default_profile
100
- }
101
-
102
- _agent_profile_exists() {
103
- local name="$1"
104
- jq -e --arg name "$name" '.profiles[$name]' "$(_agent_profiles_file)" >/dev/null 2>&1
105
- }
106
-
107
- _agent_profile_field() {
108
- local name="$1" field="$2"
109
- jq -r --arg name "$name" --arg field "$field" '.profiles[$name][$field]' "$(_agent_profiles_file)"
110
- }
111
-
112
- _agent_assert_dependencies() {
113
- local file
114
- file="$(_agent_profiles_file)"
115
- if [[ ! -f "$file" ]]; then
116
- die "Agent profile config not found: $file"
117
- fi
118
- if ! command -v jq >/dev/null 2>&1; then
119
- die "jq is required for dot mode"
120
- fi
121
- }
122
-
123
- _agent_card_file() {
124
- local repo_root
125
- repo_root="$(_agent_repo_root)"
126
- echo "${AGENT_CARD_CONFIG:-$repo_root/dot_config/dotfiles/agent-card.json}"
127
- }
128
-
129
- _agent_checkpoint_file() {
130
- local checkpoint_id="$1"
131
- echo "$(dot_agent_checkpoint_dir)/${checkpoint_id}.json"
132
- }
133
-
134
- _agent_apply_profile_env() {
135
- local name="$1"
136
- export DOT_AGENT_PROFILE="$name"
137
- # Split declare-and-assign to avoid masking the field-getter's exit
138
- # code (SC2155). If the profile JSON is malformed, the assignment
139
- # now fails the function instead of silently exporting an empty value.
140
- local approval filesystem network mcp_profile max_steps tuple
141
- # One jq read of all five policy fields (was five separate jq processes on
142
- # every profile application). `|| return 1` preserves fail-on-malformed.
143
- tuple="$(jq -r --arg name "$name" \
144
- '.profiles[$name] | [.approval, .filesystem, .network, .mcpProfile, .maxSteps] | @tsv' \
145
- "$(_agent_profiles_file)")" || return 1
146
- IFS=$'\t' read -r approval filesystem network mcp_profile max_steps <<<"$tuple"
147
- export DOT_AGENT_APPROVAL="$approval"
148
- export DOT_AGENT_FILESYSTEM="$filesystem"
149
- export DOT_AGENT_NETWORK="$network"
150
- export DOT_AGENT_MCP_PROFILE="$mcp_profile"
151
- export DOT_AGENT_MAX_STEPS="$max_steps"
152
- }
153
-
154
- _agent_rbac_enforcement() {
155
- local file
156
- file="$(_agent_profiles_file)"
157
- jq -r '.rbac.enforcement // "advisory"' "$file"
158
- }
159
-
160
- _agent_current_role() {
161
- local state_file role
162
- state_file="$(_agent_state_file)"
163
- if [[ -f "$state_file" ]]; then
164
- role="$(sed -n 's/^DOT_AGENT_ROLE=//p' "$state_file" | tail -n 1)"
165
- if [[ -n "$role" ]]; then
166
- echo "$role"
167
- return 0
168
- fi
169
- fi
170
- jq -r '.rbac.defaultRole // "developer"' "$(_agent_profiles_file)"
171
- }
172
-
173
- _agent_role_allows_profile() {
174
- local role="$1" profile="$2"
175
- local file
176
- file="$(_agent_profiles_file)"
177
- jq -e --arg role "$role" --arg profile "$profile" '
178
- .rbac.roles[$role].allowedProfiles // [] | index($profile)
179
- ' "$file" >/dev/null 2>&1
180
- }
181
-
182
- _agent_enforce_rbac() {
183
- local target_profile="$1"
184
- local enforcement role
185
- enforcement="$(_agent_rbac_enforcement)"
186
- role="$(_agent_current_role)"
187
- if _agent_role_allows_profile "$role" "$target_profile"; then
188
- return 0
189
- fi
190
- if [[ "$enforcement" == "strict" ]]; then
191
- die "RBAC: role '$role' is not allowed to use profile '$target_profile' (enforcement: strict)"
192
- else
193
- ui_warn "RBAC" "role '$role' is not recommended for profile '$target_profile' (enforcement: advisory)"
194
- fi
195
- }
196
-
197
- cmd_mode() {
198
- _agent_assert_dependencies
199
-
200
- local subcommand="${1:-current}"
201
- if [[ -z "${1:-}" ]] || [[ "${1:-}" == --* ]]; then
202
- subcommand="current"
203
- else
204
- shift || true
205
- fi
206
-
207
- case "$subcommand" in
208
- list)
209
- local current
210
- current="$(_agent_current_profile)"
211
- dot_agent_session_log "list" "$current" "ok"
212
- ui_header "Agent Modes"
213
- jq -r '.profiles | to_entries[] | "\(.key)\t\(.value.description)"' "$(_agent_profiles_file)" |
214
- while IFS=$'\t' read -r name description; do
215
- if [[ "$name" == "$current" ]]; then
216
- ui_ok "$name" "$description [current]"
217
- else
218
- ui_info "$name" "$description"
219
- fi
220
- done
221
- ;;
222
- current)
223
- local current
224
- current="$(_agent_current_profile)"
225
- dot_agent_session_log "current" "$current" "ok"
226
- ui_header "Agent Mode"
227
- ui_ok "Profile" "$current"
228
- ui_ok "Approval" "$(_agent_profile_field "$current" "approval")"
229
- ui_ok "Filesystem" "$(_agent_profile_field "$current" "filesystem")"
230
- ui_ok "Network" "$(_agent_profile_field "$current" "network")"
231
- ui_ok "MCP" "$(_agent_profile_field "$current" "mcpProfile")"
232
- ;;
233
- show)
234
- local name="${1:-}"
235
- [[ -n "$name" ]] || die "Usage: dot mode show <profile>"
236
- _agent_profile_exists "$name" || die "Unknown agent profile: $name"
237
- dot_agent_session_log "show" "$name" "ok"
238
- ui_header "Agent Mode"
239
- ui_ok "Profile" "$name"
240
- ui_ok "Description" "$(_agent_profile_field "$name" "description")"
241
- ui_ok "Approval" "$(_agent_profile_field "$name" "approval")"
242
- ui_ok "Filesystem" "$(_agent_profile_field "$name" "filesystem")"
243
- ui_ok "Network" "$(_agent_profile_field "$name" "network")"
244
- ui_ok "Max steps" "$(_agent_profile_field "$name" "maxSteps")"
245
- ui_ok "MCP" "$(_agent_profile_field "$name" "mcpProfile")"
246
- ;;
247
- set)
248
- local name="${1:-}" state_file
249
- [[ -n "$name" ]] || die "Usage: dot mode set <profile>"
250
- _agent_profile_exists "$name" || die "Unknown agent profile: $name"
251
- _agent_enforce_rbac "$name"
252
- state_file="$(_agent_state_file)"
253
- mkdir -p "$(dirname "$state_file")"
254
- cat >"$state_file" <<EOF
255
- DOT_AGENT_PROFILE=$name
256
- DOT_AGENT_APPROVAL=$(_agent_profile_field "$name" "approval")
257
- DOT_AGENT_FILESYSTEM=$(_agent_profile_field "$name" "filesystem")
258
- DOT_AGENT_NETWORK=$(_agent_profile_field "$name" "network")
259
- DOT_AGENT_MCP_PROFILE=$(_agent_profile_field "$name" "mcpProfile")
260
- DOT_AGENT_MAX_STEPS=$(_agent_profile_field "$name" "maxSteps")
261
- EOF
262
- dot_agent_session_log "set" "$name" "ok" "state_file=$state_file"
263
- ui_ok "Agent mode" "$name"
264
- ui_info "State file" "$state_file"
265
- ;;
266
- run)
267
- local name="${1:-}" current
268
- if [[ -n "$name" ]] && _agent_profile_exists "$name"; then
269
- shift || true
270
- else
271
- name="$(_agent_current_profile)"
272
- fi
273
- [[ $# -gt 0 ]] || die "Usage: dot mode run [profile] <command> [args...]"
274
- _agent_apply_profile_env "$name"
275
- local checkpoint_file checkpoint_id
276
- checkpoint_file="$(dot_agent_checkpoint_create "$name" "ready" "$@")"
277
- checkpoint_id="$(basename "$checkpoint_file" .json)"
278
- ui_info "Agent mode" "$name"
279
- dot_agent_session_log "run_start" "$name" "running" "argv=$*" "checkpoint_id=$checkpoint_id"
280
- # Run inside the `if` condition (errexit is suspended there) and
281
- # read `$?` in the else-branch: it holds the command's own status.
282
- # `if ! cmd; then exit_code=$?` reads the negation's status (0) and
283
- # silently reported every failure as exit 0.
284
- local exit_code=0
285
- if "$@"; then
286
- dot_agent_session_log "run_finish" "$name" "ok" "exit_code=$exit_code" "checkpoint_id=$checkpoint_id"
287
- else
288
- exit_code=$?
289
- dot_agent_session_log "run_finish" "$name" "failed" "exit_code=$exit_code" "checkpoint_id=$checkpoint_id"
290
- fi
291
- return "$exit_code"
292
- ;;
293
- doctor)
294
- local file
295
- file="$(_agent_profiles_file)"
296
- dot_agent_session_log "doctor" "$(_agent_current_profile)" "ok"
297
- ui_header "Agent Mode Doctor"
298
- if jq empty "$file" >/dev/null 2>&1; then
299
- ui_ok "Profile config" "$file"
300
- else
301
- die "Invalid JSON: $file"
302
- fi
303
- jq -e '.profiles[.defaultProfile]' "$file" >/dev/null 2>&1 || die "Default profile missing"
304
- ui_ok "Default profile" "$(_agent_default_profile)"
305
- ;;
306
- card)
307
- local card_file json_mode=0
308
- card_file="$(_agent_card_file)"
309
- [[ -f "$card_file" ]] || die "Agent card not found: $card_file"
310
- if [[ "${1:-}" == "--json" ]]; then
311
- json_mode=1
312
- fi
313
- dot_agent_session_log "card" "$(_agent_current_profile)" "ok"
314
- if [[ "$json_mode" -eq 1 ]] || ! command -v jq >/dev/null 2>&1; then
315
- exec cat "$card_file"
316
- fi
317
- ui_header "Agent Card"
318
- jq -r '
319
- "Name\t\(.name)",
320
- "Version\t\(.version)",
321
- "Protocols\t\(.protocols | join(", "))",
322
- "Default mode\t\(.defaultProfile)",
323
- "Support\t\(.platforms | join(", "))"
324
- ' "$card_file" | while IFS=$'\t' read -r key value; do
325
- ui_ok "$key" "$value"
326
- done
327
- ;;
328
- log)
329
- dot_agent_session_log "log" "$(_agent_current_profile)" "ok"
330
- dot_agent_session_tail "${1:-20}"
331
- ;;
332
- checkpoint)
333
- local action="${1:-list}"
334
- shift || true
335
- case "$action" in
336
- save)
337
- local name="${1:-}" checkpoint_file checkpoint_id
338
- if [[ -n "$name" ]] && _agent_profile_exists "$name"; then
339
- shift || true
340
- else
341
- name="$(_agent_current_profile)"
342
- fi
343
- [[ $# -gt 0 ]] || die "Usage: dot agent checkpoint save [profile] <command> [args...]"
344
- _agent_apply_profile_env "$name"
345
- checkpoint_file="$(dot_agent_checkpoint_create "$name" "saved" "$@")"
346
- checkpoint_id="$(basename "$checkpoint_file" .json)"
347
- dot_agent_session_log "checkpoint_save" "$name" "ok" "checkpoint_id=$checkpoint_id"
348
- ui_header "Agent Checkpoint"
349
- ui_ok "ID" "$checkpoint_id"
350
- ui_ok "Profile" "$name"
351
- ui_ok "Command" "$*"
352
- ui_ok "File" "$checkpoint_file"
353
- ;;
354
- list)
355
- local count="${1:-20}"
356
- dot_agent_session_log "checkpoint_list" "$(_agent_current_profile)" "ok"
357
- if ! command -v jq >/dev/null 2>&1; then
358
- dot_agent_checkpoint_tail "$count"
359
- return 0
360
- fi
361
- ui_header "Agent Checkpoints"
362
- dot_agent_checkpoint_tail "$count" | jq -r '"\(.id)\t\(.profile)\t\(.status)\t\(.created_at)\t\(.argv | join(" "))"' | while IFS=$'\t' read -r id profile status created_at argv; do
363
- ui_ok "$id" "$profile / $status / $created_at / $argv"
364
- done
365
- ;;
366
- show)
367
- local checkpoint_id="${1:-}" checkpoint_file json_mode=0
368
- [[ -n "$checkpoint_id" ]] || die "Usage: dot agent checkpoint show <id> [--json]"
369
- shift || true
370
- [[ "${1:-}" == "--json" || "${1:-}" == "-j" ]] && json_mode=1
371
- checkpoint_file="$(_agent_checkpoint_file "$checkpoint_id")"
372
- [[ -f "$checkpoint_file" ]] || die "Checkpoint not found: $checkpoint_id"
373
- dot_agent_session_log "checkpoint_show" "$(_agent_current_profile)" "ok" "checkpoint_id=$checkpoint_id"
374
- if [[ "$json_mode" -eq 1 ]] || ! command -v jq >/dev/null 2>&1; then
375
- exec cat "$checkpoint_file"
376
- fi
377
- ui_header "Agent Checkpoint"
378
- jq -r '"ID\t\(.id)",
379
- "Profile\t\(.profile)",
380
- "Status\t\(.status)",
381
- "Created\t\(.created_at)",
382
- "Command\t\(.argv | join(" "))"' "$checkpoint_file" | while IFS=$'\t' read -r key value; do
383
- ui_ok "$key" "$value"
384
- done
385
- ;;
386
- replay)
387
- local checkpoint_id="${1:-}" checkpoint_file replay_profile
388
- local -a replay_argv=()
389
- [[ -n "$checkpoint_id" ]] || die "Usage: dot agent checkpoint replay <id>"
390
- checkpoint_file="$(_agent_checkpoint_file "$checkpoint_id")"
391
- [[ -f "$checkpoint_file" ]] || die "Checkpoint not found: $checkpoint_id"
392
- replay_profile="$(jq -r '.profile' "$checkpoint_file")"
393
- while IFS= read -r item; do
394
- replay_argv+=("$item")
395
- done < <(jq -r '.argv[]' "$checkpoint_file")
396
- [[ "${#replay_argv[@]}" -gt 0 ]] || die "Checkpoint has no replayable command: $checkpoint_id"
397
- _agent_apply_profile_env "$replay_profile"
398
- dot_agent_session_log "checkpoint_replay" "$replay_profile" "running" "checkpoint_id=$checkpoint_id"
399
- local exit_code=0
400
- if "${replay_argv[@]}"; then
401
- dot_agent_session_log "checkpoint_replay_finish" "$replay_profile" "ok" "checkpoint_id=$checkpoint_id" "exit_code=$exit_code"
402
- else
403
- exit_code=$?
404
- dot_agent_session_log "checkpoint_replay_finish" "$replay_profile" "failed" "checkpoint_id=$checkpoint_id" "exit_code=$exit_code"
405
- fi
406
- return "$exit_code"
407
- ;;
408
- *)
409
- echo "Usage: dot agent checkpoint [save|list|show|replay]" >&2
410
- exit 1
411
- ;;
412
- esac
413
- ;;
414
- delegate)
415
- local delegate_name="${1:-}"
416
- [[ -n "$delegate_name" ]] || die "Usage: dot agent delegate <name> <command> [args...]"
417
- shift || true
418
- [[ $# -gt 0 ]] || die "Usage: dot agent delegate <name> <command> [args...]"
419
- local profiles_file current_profile
420
- profiles_file="$(_agent_profiles_file)"
421
- current_profile="$(_agent_current_profile)"
422
- # Check delegation is enabled
423
- local delegation_enabled
424
- delegation_enabled="$(jq -r '.delegation.enabled // false' "$profiles_file")"
425
- [[ "$delegation_enabled" == "true" ]] || die "Delegation is not enabled in agent-profiles.json"
426
- # Check current profile can delegate
427
- local can_delegate
428
- can_delegate="$(jq -r --arg p "$current_profile" '.profiles[$p].canDelegate // false' "$profiles_file")"
429
- [[ "$can_delegate" == "true" ]] || die "Profile '$current_profile' cannot delegate"
430
- # Check delegate name exists
431
- jq -e --arg d "$delegate_name" '.delegation.allowedDelegates[$d]' "$profiles_file" >/dev/null 2>&1 || die "Unknown delegate: $delegate_name"
432
- # Read delegate config
433
- local delegate_profile delegate_timeout delegate_max_steps
434
- delegate_profile="$(jq -r --arg d "$delegate_name" '.delegation.allowedDelegates[$d].profile' "$profiles_file")"
435
- delegate_timeout="$(jq -r --arg d "$delegate_name" '.delegation.allowedDelegates[$d].timeout // 300' "$profiles_file")"
436
- delegate_max_steps="$(jq -r --arg d "$delegate_name" '.delegation.allowedDelegates[$d].maxSteps // 4' "$profiles_file")"
437
- # Apply delegate profile env
438
- _agent_apply_profile_env "$delegate_profile"
439
- export DOT_AGENT_MAX_STEPS="$delegate_max_steps"
440
- export DOT_AGENT_DELEGATE="$delegate_name"
441
- export DOT_AGENT_PARENT_PROFILE="$current_profile"
442
- dot_agent_session_log "delegate_start" "$delegate_profile" "running" "delegate=$delegate_name" "parent=$current_profile" "timeout=$delegate_timeout"
443
- ui_info "Delegating" "$delegate_name (profile: $delegate_profile, timeout: ${delegate_timeout}s)"
444
- local exit_code=0
445
- if _agent_run_bounded "$delegate_timeout" "$@"; then
446
- dot_agent_session_log "delegate_finish" "$delegate_profile" "ok" "delegate=$delegate_name" "exit_code=$exit_code"
447
- ui_ok "Delegate" "$delegate_name completed"
448
- else
449
- exit_code=$?
450
- dot_agent_session_log "delegate_finish" "$delegate_profile" "failed" "delegate=$delegate_name" "exit_code=$exit_code"
451
- ui_err "Delegate" "$delegate_name failed (exit $exit_code)"
452
- fi
453
- return "$exit_code"
454
- ;;
455
- a2a-card)
456
- local a2a_card_file json_mode=0 validate_mode=0 strict_mode=0
457
- local repo_root
458
- # `.well-known/` is NOT chezmoi-tracked — it lives at the
459
- # actual repo root, not the descended `defaults/` subdir.
460
- # Bypass `_agent_repo_root` (which descends) and read the
461
- # true root directly.
462
- repo_root="$(require_source_dir)"
463
- a2a_card_file="$repo_root/.well-known/agent-card.json"
464
- while [[ $# -gt 0 ]]; do
465
- case "$1" in
466
- --json | -j)
467
- json_mode=1
468
- shift
469
- ;;
470
- --validate | --strict | -s)
471
- validate_mode=1
472
- strict_mode=1
473
- shift
474
- ;;
475
- *) shift ;;
476
- esac
477
- done
478
- [[ -f "$a2a_card_file" ]] || die "A2A v0.3 card not found: $a2a_card_file"
479
- dot_agent_session_log "a2a-card" "$(_agent_current_profile)" "ok"
480
- if [[ "$json_mode" -eq 1 ]]; then
481
- exec cat "$a2a_card_file"
482
- fi
483
- if [[ "$validate_mode" -eq 1 ]]; then
484
- local v_issues=0
485
- jq empty "$a2a_card_file" >/dev/null 2>&1 || {
486
- ui_err "JSON" "invalid"
487
- exit 1
488
- }
489
- ui_header "A2A v0.3 Card Validation"
490
- local sv
491
- sv="$(jq -r '.specVersion // empty' "$a2a_card_file")"
492
- if [[ "$sv" == "0.3" ]]; then ui_ok "specVersion" "$sv"; else
493
- ui_err "specVersion" "expected 0.3, got $sv"
494
- v_issues=$((v_issues + 1))
495
- fi
496
- if jq -e '.skills | type == "array" and length > 0' "$a2a_card_file" >/dev/null 2>&1; then
497
- ui_ok "skills" "$(jq '.skills | length' "$a2a_card_file") skills"
498
- else
499
- ui_err "skills" "missing or empty"
500
- v_issues=$((v_issues + 1))
501
- fi
502
- if jq -e '.authentication' "$a2a_card_file" >/dev/null 2>&1; then ui_ok "authentication" "present"; else
503
- ui_err "authentication" "missing"
504
- v_issues=$((v_issues + 1))
505
- fi
506
- if jq -e '.signing.method' "$a2a_card_file" >/dev/null 2>&1; then ui_ok "signing" "$(jq -r '.signing.method' "$a2a_card_file")"; else
507
- ui_err "signing" "missing method"
508
- v_issues=$((v_issues + 1))
509
- fi
510
- if [[ "$v_issues" -gt 0 && "$strict_mode" -eq 1 ]]; then exit 1; fi
511
- return 0
512
- fi
513
- ui_header "A2A v0.3 Agent Card"
514
- jq -r '
515
- "Name\t\(.name)",
516
- "Version\t\(.version)",
517
- "Spec\t\(.specVersion)",
518
- "Protocols\t\(.protocols | join(", "))",
519
- "Skills\t\(.skills | length) defined",
520
- "Auth\t\(.authentication.schemes | join(", "))",
521
- "Signing\t\(.signing.method)"
522
- ' "$a2a_card_file" | while IFS=$'\t' read -r key value; do
523
- ui_ok "$key" "$value"
524
- done
525
- ;;
526
- conformance)
527
- dot_agent_session_log "conformance" "$(_agent_current_profile)" "ok"
528
- run_script "scripts/diagnostics/a2a-conformance.sh" "A2A conformance script" "$@"
529
- ;;
530
- *)
531
- echo "Usage: dot mode [list|current|show|set|run|doctor|card|log|checkpoint|conformance|a2a-card]" >&2
532
- exit 1
533
- ;;
534
- esac
535
- }