@sebastienrousseau/dotfiles 0.2.507 → 0.2.510

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 (73) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +5 -5
  3. package/docs/COPYRIGHT +1 -1
  4. package/docs/GOVERNANCE.md +2 -2
  5. package/docs/adr/ADR-011-nushell-tier3-keep.md +2 -2
  6. package/docs/guides/INSTALL.md +3 -3
  7. package/docs/index.md +116 -27
  8. package/docs/interop/A2A.md +2 -2
  9. package/docs/interop/POWERSHELL.md +4 -4
  10. package/docs/manual/00-introduction.md +3 -3
  11. package/docs/manual/01-concepts/02-trust-model.md +3 -3
  12. package/docs/manual/01-concepts/04-fleet.md +1 -1
  13. package/docs/manual/02-tutorials/01-first-install.md +1 -1
  14. package/docs/manual/02-tutorials/05-deploy-fleet.md +2 -2
  15. package/docs/manual/03-reference/02-config-files.md +1 -1
  16. package/docs/manual/03-reference/04-templates.md +1 -1
  17. package/docs/manual/04-cookbook/01-recipes.md +1 -1
  18. package/docs/manual/04-cookbook/02-troubleshooting.md +1 -1
  19. package/docs/manual/05-appendices/B-security-checklist.md +1 -1
  20. package/docs/manual/command-index.md +76 -1
  21. package/docs/manual/index.md +1 -1
  22. package/docs/operations/ARCHITECTURE_ROADMAP.md +145 -0
  23. package/docs/operations/CI_CADENCE.md +2 -2
  24. package/docs/operations/COMPLETIONS.md +2 -2
  25. package/docs/operations/COVERAGE.md +4 -4
  26. package/docs/operations/DRIFT.md +1 -1
  27. package/docs/operations/MAINTENANCE.md +6 -6
  28. package/docs/operations/PERFORMANCE.md +6 -6
  29. package/docs/operations/RELIABILITY.md +1 -1
  30. package/docs/operations/ROADMAP_V0_2_503.md +1 -1
  31. package/docs/operations/TRACEABILITY.md +2 -0
  32. package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +6 -6
  33. package/docs/operations/VERSION_SYNC.md +3 -3
  34. package/docs/reference/UTILS.md +82 -0
  35. package/docs/security/AUDIT_BYPASS.md +3 -3
  36. package/docs/security/AUTOMATION_SECRETS.md +1 -1
  37. package/docs/security/CI_PINNING.md +10 -10
  38. package/docs/security/COMMIT_SIGNING.md +10 -10
  39. package/docs/security/DEPS_DEV_EXCEPTIONS.md +4 -4
  40. package/docs/security/DISCLOSURE.md +3 -3
  41. package/docs/security/INCIDENT_RESPONSE.md +1 -1
  42. package/docs/security/INSTALL_VERIFICATION.md +2 -2
  43. package/docs/security/MCP_POLICY.md +4 -4
  44. package/docs/security/SCORECARD.md +7 -7
  45. package/docs/security/SECURITY_CHECKLIST.md +1 -1
  46. package/docs/security/SHELL_EXEMPTIONS.md +2 -2
  47. package/docs/security/SOUP_REGISTER.md +4 -4
  48. package/docs/stylesheets/extra.css +444 -0
  49. package/docs/themes/hero-shot.svg +1 -1
  50. package/install.sh +17 -6
  51. package/package.json +1 -1
  52. package/scripts/ci/check-copyright-headers.sh +1 -1
  53. package/scripts/ci/check-shell-preamble.sh +1 -1
  54. package/scripts/ci/guard-gitleaks-checkout.sh +1 -1
  55. package/scripts/dot/commands/agent.sh +7 -6
  56. package/scripts/dot/commands/ai.sh +8 -5
  57. package/scripts/dot/commands/appearance.sh +14 -1
  58. package/scripts/dot/commands/completion.sh +134 -0
  59. package/scripts/dot/commands/core.sh +8 -0
  60. package/scripts/dot/commands/diagnostics.sh +16 -0
  61. package/scripts/dot/commands/fleet.sh +7 -3
  62. package/scripts/dot/commands/lint.sh +55 -30
  63. package/scripts/dot/commands/secrets.sh +61 -7
  64. package/scripts/dot/commands/security.sh +8 -0
  65. package/scripts/dot/powershell/Dot.psm1 +1 -1
  66. package/scripts/git-hooks/pre-commit-audit.sh +1 -1
  67. package/scripts/ops/chezmoi-apply.sh +42 -8
  68. package/scripts/ops/chezmoi-update.sh +14 -0
  69. package/scripts/ops/heal-tools.sh +28 -0
  70. package/scripts/ops/teleport.sh +2 -2
  71. package/scripts/qa/examples-coverage.sh +94 -0
  72. package/scripts/version-sync.sh +29 -2
  73. package/docs/_config.yml +0 -59
@@ -0,0 +1,444 @@
1
+ /* ──────────────────────────────────────────────────────────────────────────
2
+ * doc.dotfiles.io — custom theme
3
+ * Dark + terminal-green palette on MkDocs Material.
4
+ * Inspired by the polish of docs.n8n.io / GitHub docs dark, adapted to
5
+ * Material's structure.
6
+ * ────────────────────────────────────────────────────────────────────── */
7
+
8
+ /* -- font stack ------------------------------------------------------------ */
9
+ @import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap");
10
+
11
+ :root {
12
+ --dot-font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
13
+ "Helvetica Neue", Arial, sans-serif;
14
+ --dot-font-code: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono",
15
+ Menlo, Consolas, monospace;
16
+
17
+ --dot-green: #7ee787; /* terminal green */
18
+ --dot-green-bright: #b0f5b7; /* hover / focused */
19
+ --dot-green-dim: #4a9153; /* muted / secondary */
20
+ --dot-green-rgb: 126, 231, 135;
21
+
22
+ --dot-bg: #0b0e14; /* base */
23
+ --dot-bg-elev: #111621; /* elevated card */
24
+ --dot-bg-elev-2: #161b26; /* higher elevation */
25
+ --dot-border: #1f2937;
26
+ --dot-border-strong: #2b3646;
27
+
28
+ --dot-fg: #e4e7ec;
29
+ --dot-fg-muted: #94a3b8;
30
+ --dot-fg-subtle: #64748b;
31
+ }
32
+
33
+ /* -- global typography ----------------------------------------------------- */
34
+ body,
35
+ .md-typeset {
36
+ font-family: var(--dot-font-body);
37
+ font-feature-settings: "ss01", "cv11";
38
+ -webkit-font-smoothing: antialiased;
39
+ -moz-osx-font-smoothing: grayscale;
40
+ }
41
+
42
+ .md-typeset code,
43
+ .md-typeset kbd,
44
+ .md-typeset pre,
45
+ code {
46
+ font-family: var(--dot-font-code);
47
+ font-feature-settings: "calt", "ss20";
48
+ }
49
+
50
+ /* -- dark palette override (slate) ---------------------------------------- */
51
+ [data-md-color-scheme="slate"] {
52
+ --md-hue: 210;
53
+ --md-default-bg-color: var(--dot-bg);
54
+ --md-default-fg-color: var(--dot-fg);
55
+ --md-default-fg-color--light: var(--dot-fg-muted);
56
+ --md-default-fg-color--lighter: var(--dot-fg-subtle);
57
+ --md-default-fg-color--lightest: hsla(210, 20%, 40%, 0.3);
58
+
59
+ --md-primary-fg-color: var(--dot-green);
60
+ --md-primary-fg-color--light: var(--dot-green-bright);
61
+ --md-primary-fg-color--dark: var(--dot-green-dim);
62
+ --md-primary-bg-color: var(--dot-bg);
63
+ --md-primary-bg-color--light: var(--dot-bg-elev);
64
+
65
+ --md-accent-fg-color: var(--dot-green-bright);
66
+ --md-accent-fg-color--transparent: rgba(126, 231, 135, 0.1);
67
+ --md-accent-bg-color: var(--dot-bg);
68
+ --md-accent-bg-color--light: var(--dot-bg-elev);
69
+
70
+ --md-typeset-a-color: var(--dot-green);
71
+
72
+ --md-code-bg-color: var(--dot-bg-elev-2);
73
+ --md-code-fg-color: var(--dot-fg);
74
+ --md-code-hl-color: rgba(126, 231, 135, 0.12);
75
+ --md-code-hl-color--light: rgba(126, 231, 135, 0.08);
76
+
77
+ /* Admonitions */
78
+ --md-admonition-bg-color: var(--dot-bg-elev);
79
+ --md-admonition-fg-color: var(--dot-fg);
80
+
81
+ /* Footer */
82
+ --md-footer-bg-color: #050710;
83
+ --md-footer-bg-color--dark: #030509;
84
+ }
85
+
86
+ /* -- header --------------------------------------------------------------- */
87
+ .md-header {
88
+ background-color: rgba(11, 14, 20, 0.92);
89
+ backdrop-filter: saturate(180%) blur(12px);
90
+ -webkit-backdrop-filter: saturate(180%) blur(12px);
91
+ border-bottom: 1px solid var(--dot-border);
92
+ box-shadow: none;
93
+ }
94
+
95
+ .md-header[data-md-state="shadow"] {
96
+ box-shadow: 0 1px 0 var(--dot-border);
97
+ }
98
+
99
+ .md-header__title {
100
+ font-weight: 600;
101
+ letter-spacing: -0.01em;
102
+ }
103
+
104
+ .md-header__button.md-logo :is(img, svg) {
105
+ color: var(--dot-green);
106
+ fill: var(--dot-green);
107
+ height: 1.6rem;
108
+ width: 1.6rem;
109
+ }
110
+
111
+ /* -- tabs --------------------------------------------------------------- */
112
+ .md-tabs {
113
+ background-color: rgba(11, 14, 20, 0.85);
114
+ border-bottom: 1px solid var(--dot-border);
115
+ }
116
+
117
+ .md-tabs__link {
118
+ color: var(--dot-fg-muted);
119
+ opacity: 1;
120
+ font-size: 0.75rem;
121
+ font-weight: 500;
122
+ transition: color 120ms ease;
123
+ }
124
+
125
+ .md-tabs__link:hover,
126
+ .md-tabs__link--active {
127
+ color: var(--dot-green-bright);
128
+ }
129
+
130
+ .md-tabs__link--active {
131
+ position: relative;
132
+ }
133
+ .md-tabs__link--active::after {
134
+ content: "";
135
+ position: absolute;
136
+ left: 0;
137
+ right: 0;
138
+ bottom: -2px;
139
+ height: 2px;
140
+ background: linear-gradient(90deg, transparent, var(--dot-green), transparent);
141
+ }
142
+
143
+ /* -- sidebar (left nav) --------------------------------------------------- */
144
+ .md-nav__title {
145
+ font-size: 0.68rem;
146
+ font-weight: 700;
147
+ text-transform: uppercase;
148
+ letter-spacing: 0.05em;
149
+ color: var(--dot-fg-subtle);
150
+ padding-top: 1.2rem;
151
+ }
152
+
153
+ .md-nav__link {
154
+ color: var(--dot-fg-muted);
155
+ transition: color 120ms ease, background-color 120ms ease;
156
+ border-radius: 6px;
157
+ padding: 4px 8px;
158
+ margin: 1px 0;
159
+ }
160
+ .md-nav__link:hover {
161
+ color: var(--dot-fg);
162
+ background: rgba(126, 231, 135, 0.06);
163
+ }
164
+ .md-nav__link--active,
165
+ .md-nav__link.md-nav__link--active {
166
+ color: var(--dot-green-bright);
167
+ background: rgba(126, 231, 135, 0.1);
168
+ font-weight: 500;
169
+ }
170
+
171
+ /* -- right TOC ------------------------------------------------------------ */
172
+ .md-nav--secondary .md-nav__title {
173
+ border-left: 2px solid var(--dot-border);
174
+ background: transparent;
175
+ }
176
+ .md-nav--secondary .md-nav__link--active {
177
+ border-left: 2px solid var(--dot-green);
178
+ color: var(--dot-green-bright);
179
+ background: transparent;
180
+ }
181
+
182
+ /* -- content -------------------------------------------------------------- */
183
+ .md-typeset h1,
184
+ .md-typeset h2,
185
+ .md-typeset h3,
186
+ .md-typeset h4 {
187
+ font-family: var(--dot-font-body);
188
+ letter-spacing: -0.02em;
189
+ color: var(--dot-fg);
190
+ }
191
+
192
+ .md-typeset h1 {
193
+ font-weight: 700;
194
+ font-size: 2.2rem;
195
+ line-height: 1.15;
196
+ margin-bottom: 0.6em;
197
+ background: linear-gradient(180deg, #ffffff 0%, #cbd5e1 100%);
198
+ -webkit-background-clip: text;
199
+ background-clip: text;
200
+ color: transparent;
201
+ }
202
+
203
+ .md-typeset h2 {
204
+ font-weight: 600;
205
+ font-size: 1.6rem;
206
+ margin-top: 2.4em;
207
+ padding-top: 0.4em;
208
+ border-top: 1px solid var(--dot-border);
209
+ }
210
+
211
+ .md-typeset h3 {
212
+ font-weight: 600;
213
+ font-size: 1.2rem;
214
+ color: var(--dot-green-bright);
215
+ }
216
+
217
+ .md-typeset a {
218
+ text-decoration: none;
219
+ border-bottom: 1px solid transparent;
220
+ transition: border-color 120ms ease, color 120ms ease;
221
+ }
222
+ .md-typeset a:hover {
223
+ border-bottom-color: var(--dot-green-bright);
224
+ color: var(--dot-green-bright);
225
+ }
226
+
227
+ /* -- code blocks ---------------------------------------------------------- */
228
+ .md-typeset pre > code,
229
+ .md-typeset .highlight pre {
230
+ background-color: var(--dot-bg-elev-2);
231
+ border: 1px solid var(--dot-border);
232
+ border-radius: 8px;
233
+ }
234
+ .md-typeset code {
235
+ background-color: rgba(126, 231, 135, 0.08);
236
+ border: 1px solid rgba(126, 231, 135, 0.15);
237
+ color: var(--dot-green-bright);
238
+ border-radius: 4px;
239
+ padding: 0.1em 0.35em;
240
+ font-size: 0.88em;
241
+ }
242
+ .md-typeset pre > code {
243
+ background: transparent;
244
+ border: none;
245
+ color: var(--dot-fg);
246
+ padding: 0;
247
+ }
248
+
249
+ /* -- tables --------------------------------------------------------------- */
250
+ .md-typeset table:not([class]) {
251
+ border: 1px solid var(--dot-border);
252
+ border-radius: 8px;
253
+ overflow: hidden;
254
+ font-size: 0.8rem;
255
+ }
256
+ .md-typeset table:not([class]) th {
257
+ background: var(--dot-bg-elev);
258
+ color: var(--dot-fg);
259
+ font-weight: 600;
260
+ border-bottom: 1px solid var(--dot-border-strong);
261
+ }
262
+ .md-typeset table:not([class]) tr:hover {
263
+ background: rgba(126, 231, 135, 0.03);
264
+ }
265
+
266
+ /* -- admonitions ---------------------------------------------------------- */
267
+ .md-typeset .admonition,
268
+ .md-typeset details {
269
+ background: var(--dot-bg-elev);
270
+ border: 1px solid var(--dot-border);
271
+ border-left: 3px solid var(--dot-green);
272
+ border-radius: 8px;
273
+ box-shadow: none;
274
+ }
275
+ .md-typeset .admonition-title,
276
+ .md-typeset summary {
277
+ background: transparent;
278
+ border-bottom: 1px solid var(--dot-border);
279
+ font-weight: 600;
280
+ }
281
+
282
+ /* -- grid cards ----------------------------------------------------------- */
283
+ .md-typeset .grid.cards > :is(ul, ol) > li,
284
+ .md-typeset .grid.cards > .card {
285
+ background: var(--dot-bg-elev);
286
+ border: 1px solid var(--dot-border);
287
+ border-radius: 12px;
288
+ padding: 1.2rem;
289
+ transition: transform 180ms ease, border-color 180ms ease,
290
+ box-shadow 180ms ease, background 180ms ease;
291
+ position: relative;
292
+ overflow: hidden;
293
+ }
294
+ .md-typeset .grid.cards > :is(ul, ol) > li::before {
295
+ content: "";
296
+ position: absolute;
297
+ inset: 0;
298
+ background: radial-gradient(
299
+ circle at top left,
300
+ rgba(126, 231, 135, 0.06),
301
+ transparent 60%
302
+ );
303
+ opacity: 0;
304
+ transition: opacity 220ms ease;
305
+ pointer-events: none;
306
+ }
307
+ .md-typeset .grid.cards > :is(ul, ol) > li:hover {
308
+ transform: translateY(-2px);
309
+ border-color: rgba(126, 231, 135, 0.35);
310
+ background: var(--dot-bg-elev-2);
311
+ box-shadow: 0 8px 24px -8px rgba(0, 0, 0, 0.5),
312
+ 0 0 0 1px rgba(126, 231, 135, 0.08) inset;
313
+ }
314
+ .md-typeset .grid.cards > :is(ul, ol) > li:hover::before {
315
+ opacity: 1;
316
+ }
317
+ .md-typeset .grid.cards > :is(ul, ol) > li > :first-child {
318
+ margin-top: 0;
319
+ }
320
+ .md-typeset .grid.cards > :is(ul, ol) > li strong {
321
+ color: var(--dot-green-bright);
322
+ font-weight: 600;
323
+ font-size: 1rem;
324
+ display: block;
325
+ margin-bottom: 0.4rem;
326
+ }
327
+ .md-typeset .grid.cards > :is(ul, ol) > li .twemoji,
328
+ .md-typeset .grid.cards > :is(ul, ol) > li svg {
329
+ color: var(--dot-green);
330
+ fill: var(--dot-green);
331
+ height: 1.4rem;
332
+ width: 1.4rem;
333
+ margin-bottom: 0.6rem;
334
+ }
335
+
336
+ /* -- hero banner (used by landing page) ----------------------------------- */
337
+ .dot-hero {
338
+ padding: 3rem 0 2.4rem;
339
+ margin: -1.6rem -0.8rem 2.4rem;
340
+ text-align: center;
341
+ border-bottom: 1px solid var(--dot-border);
342
+ position: relative;
343
+ background: radial-gradient(
344
+ ellipse 60% 100% at 50% 0%,
345
+ rgba(126, 231, 135, 0.08),
346
+ transparent 70%
347
+ );
348
+ }
349
+ .dot-hero h1 {
350
+ font-size: 3rem;
351
+ line-height: 1.05;
352
+ margin-bottom: 0.4em;
353
+ padding: 0;
354
+ border: none;
355
+ }
356
+ .dot-hero .tagline {
357
+ font-size: 1.1rem;
358
+ color: var(--dot-fg-muted);
359
+ max-width: 40rem;
360
+ margin: 0 auto 1.4rem;
361
+ }
362
+ .dot-hero .buttons {
363
+ display: flex;
364
+ gap: 0.6rem;
365
+ justify-content: center;
366
+ flex-wrap: wrap;
367
+ }
368
+ .dot-hero .buttons a {
369
+ display: inline-flex;
370
+ align-items: center;
371
+ gap: 0.4rem;
372
+ padding: 0.6rem 1.1rem;
373
+ border-radius: 8px;
374
+ font-weight: 500;
375
+ font-size: 0.9rem;
376
+ text-decoration: none;
377
+ border: 1px solid var(--dot-border-strong);
378
+ color: var(--dot-fg);
379
+ transition: all 160ms ease;
380
+ }
381
+ .dot-hero .buttons a.primary {
382
+ background: var(--dot-green);
383
+ color: var(--dot-bg);
384
+ border-color: var(--dot-green);
385
+ font-weight: 600;
386
+ }
387
+ .dot-hero .buttons a.primary:hover {
388
+ background: var(--dot-green-bright);
389
+ border-color: var(--dot-green-bright);
390
+ transform: translateY(-1px);
391
+ }
392
+ .dot-hero .buttons a:not(.primary):hover {
393
+ border-color: var(--dot-green);
394
+ color: var(--dot-green-bright);
395
+ }
396
+
397
+ /* -- search --------------------------------------------------------------- */
398
+ .md-search__form {
399
+ background: var(--dot-bg-elev);
400
+ border: 1px solid var(--dot-border);
401
+ border-radius: 8px;
402
+ }
403
+ .md-search__form:hover,
404
+ .md-search__input:focus + .md-search__icon,
405
+ .md-search__form:focus-within {
406
+ border-color: var(--dot-green);
407
+ background: var(--dot-bg-elev-2);
408
+ }
409
+ .md-search__input {
410
+ color: var(--dot-fg);
411
+ }
412
+ .md-search__input::placeholder {
413
+ color: var(--dot-fg-subtle);
414
+ }
415
+
416
+ /* -- footer --------------------------------------------------------------- */
417
+ .md-footer {
418
+ border-top: 1px solid var(--dot-border);
419
+ }
420
+ .md-footer-meta {
421
+ background: var(--dot-bg);
422
+ border-top: 1px solid var(--dot-border);
423
+ }
424
+ .md-copyright {
425
+ color: var(--dot-fg-subtle);
426
+ font-size: 0.72rem;
427
+ }
428
+
429
+ /* -- scrollbar (webkit) --------------------------------------------------- */
430
+ ::-webkit-scrollbar {
431
+ width: 10px;
432
+ height: 10px;
433
+ }
434
+ ::-webkit-scrollbar-track {
435
+ background: transparent;
436
+ }
437
+ ::-webkit-scrollbar-thumb {
438
+ background: var(--dot-border-strong);
439
+ border-radius: 8px;
440
+ border: 2px solid var(--dot-bg);
441
+ }
442
+ ::-webkit-scrollbar-thumb:hover {
443
+ background: var(--dot-green-dim);
444
+ }
@@ -70,7 +70,7 @@
70
70
  <!-- New prompt -->
71
71
  <text x="40" y="405" fill="#a6e3a1">&#10148;</text>
72
72
  <text x="60" y="405" fill="#cdd6f4">~/.dotfiles</text>
73
- <text x="170" y="405" fill="#f5c2e7">on master</text>
73
+ <text x="170" y="405" fill="#f5c2e7">on main</text>
74
74
  <rect x="275" y="393" width="8" height="16" fill="#cdd6f4">
75
75
  <animate attributeName="opacity" values="1;0;1" dur="1s" repeatCount="indefinite" />
76
76
  </rect>
package/install.sh CHANGED
@@ -2,9 +2,20 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  # Universal Dotfiles Installer (Zero-Dependency)
5
- # Usage: bash -c "$(curl -fsSL https://raw.githubusercontent.com/sebastienrousseau/dotfiles/master/install.sh)"
5
+ # Usage: bash -c "$(curl -fsSL https://raw.githubusercontent.com/sebastienrousseau/dotfiles/main/install.sh)"
6
6
  # (or ./install.sh locally)
7
7
 
8
+ # This installer uses bash features (set -o pipefail, arrays, [[ ]]). If it is
9
+ # run under a POSIX/other shell — e.g. `sh install.sh` or piped to `sh` where
10
+ # /bin/sh is dash — fail fast with a clear message instead of the cryptic
11
+ # "set: Illegal option -o pipefail" from the next line. Kept strictly POSIX so
12
+ # it parses in any shell before bash takes over.
13
+ if [ -z "${BASH_VERSION:-}" ]; then
14
+ echo "install.sh requires bash. Run: bash install.sh" >&2
15
+ echo " or: bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/sebastienrousseau/dotfiles/main/install.sh)\"" >&2
16
+ exit 1
17
+ fi
18
+
8
19
  set -euo pipefail
9
20
 
10
21
  # Restrict the permissions of any file/dir we create during bootstrap.
@@ -60,7 +71,7 @@ show_help() {
60
71
  Usage: install.sh [version] [options]
61
72
 
62
73
  Arguments:
63
- version The version (tag or branch) to install (default: v0.2.507)
74
+ version The version (tag or branch) to install (default: v0.2.510)
64
75
 
65
76
  Options:
66
77
  --help Show this help message
@@ -76,7 +87,7 @@ EOF
76
87
  }
77
88
 
78
89
  main() {
79
- local version="v0.2.507"
90
+ local version="v0.2.510"
80
91
  local version_set=0
81
92
  local minimal=0
82
93
  local provision="${DOTFILES_PROVISION:-0}"
@@ -106,7 +117,7 @@ main() {
106
117
  # like `foobar` doesn't trigger a 30s+ network download attempt.
107
118
  # Caught by the install.sh fuzz harness (#881).
108
119
  if [[ ! "$arg" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+([-+][a-zA-Z0-9.-]+)?$ ]]; then
109
- error "Unrecognized positional argument '$arg' — expected a semver version (e.g. v0.2.507)."
120
+ error "Unrecognized positional argument '$arg' — expected a semver version (e.g. v0.2.510)."
110
121
  fi
111
122
  version="$arg"
112
123
  version_set=1
@@ -351,7 +362,7 @@ main() {
351
362
  # 6. Initialize & Apply
352
363
  step "Applying Configuration..."
353
364
 
354
- # ── Auto-migration for v0.2.507 reorg ─────────────────────────────────
365
+ # ── Auto-migration for v0.2.510 reorg ─────────────────────────────────
355
366
  # If the user is upgrading from a pre-0.2.503 install, run the
356
367
  # migration script BEFORE `chezmoi apply` so the reorg's source-
357
368
  # path moves don't cause chezmoi to delete deployed files.
@@ -360,7 +371,7 @@ main() {
360
371
  for migrate_src in "$SOURCE_DIR" "$LEGACY_SOURCE_DIR"; do
361
372
  migrate_script="$migrate_src/install/migrate/migrate-v0_2-to-v0_2_503.sh"
362
373
  if [[ -x "$migrate_script" ]]; then
363
- echo " Running v0.2.507 migration (idempotent; safe on fresh installs)..."
374
+ echo " Running v0.2.510 migration (idempotent; safe on fresh installs)..."
364
375
  "$migrate_script" || echo " migration exited non-zero — continuing apply"
365
376
  break
366
377
  fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sebastienrousseau/dotfiles",
3
- "version": "0.2.507",
3
+ "version": "0.2.510",
4
4
  "description": "The Trusted Shell Platform — Universal dotfiles managed by Chezmoi. Features Bash & Zsh for macOS, Linux & WSL. Rust modern tooling & enterprise-grade security.",
5
5
  "main": "install.sh",
6
6
  "bin": {
@@ -2,7 +2,7 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  # Compat shim: the canonical script moved to tools/ci/ during the repo reorg.
5
- # Pinned reusable workflows on master still reference the old path;
5
+ # Pinned reusable workflows on main still reference the old path;
6
6
  # this delegates so they keep working until the next pin bump.
7
7
  set -euo pipefail
8
8
  exec bash "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/tools/ci/check-copyright-headers.sh" "$@"
@@ -2,7 +2,7 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  # Compat shim: the canonical script moved to tools/ci/ during the repo reorg.
5
- # Pinned reusable workflows on master still reference the old path;
5
+ # Pinned reusable workflows on main still reference the old path;
6
6
  # this delegates so they keep working until the next pin bump.
7
7
  set -euo pipefail
8
8
  exec bash "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/tools/ci/check-shell-preamble.sh" "$@"
@@ -2,7 +2,7 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  # Compat shim: the canonical script moved to tools/ci/ during the repo reorg.
5
- # Pinned reusable workflows on master still reference the old path;
5
+ # Pinned reusable workflows on main still reference the old path;
6
6
  # this delegates so they keep working until the next pin bump.
7
7
  set -euo pipefail
8
8
  exec bash "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/tools/ci/guard-gitleaks-checkout.sh" "$@"
@@ -88,12 +88,13 @@ _agent_apply_profile_env() {
88
88
  # Split declare-and-assign to avoid masking the field-getter's exit
89
89
  # code (SC2155). If the profile JSON is malformed, the assignment
90
90
  # now fails the function instead of silently exporting an empty value.
91
- local approval filesystem network mcp_profile max_steps
92
- approval="$(_agent_profile_field "$name" "approval")"
93
- filesystem="$(_agent_profile_field "$name" "filesystem")"
94
- network="$(_agent_profile_field "$name" "network")"
95
- mcp_profile="$(_agent_profile_field "$name" "mcpProfile")"
96
- max_steps="$(_agent_profile_field "$name" "maxSteps")"
91
+ local approval filesystem network mcp_profile max_steps tuple
92
+ # One jq read of all five policy fields (was five separate jq processes on
93
+ # every profile application). `|| return 1` preserves fail-on-malformed.
94
+ tuple="$(jq -r --arg name "$name" \
95
+ '.profiles[$name] | [.approval, .filesystem, .network, .mcpProfile, .maxSteps] | @tsv' \
96
+ "$(_agent_profiles_file)")" || return 1
97
+ IFS=$'\t' read -r approval filesystem network mcp_profile max_steps <<<"$tuple"
97
98
  export DOT_AGENT_APPROVAL="$approval"
98
99
  export DOT_AGENT_FILESYSTEM="$filesystem"
99
100
  export DOT_AGENT_NETWORK="$network"
@@ -147,9 +147,7 @@ _ai_get_cached_status() {
147
147
 
148
148
  # Look up field $2 (2=present 0/1, 3=version) for binary $1 from the
149
149
  # cached TSV. Replaces a bash-4 associative array for macOS bash 3.2.
150
- _ai_status_field() {
151
- awk -F'\t' -v b="$1" -v f="$2" '$1==b{print $f;exit}' "$AI_STATUS_CACHE_FILE" 2>/dev/null
152
- }
150
+ # (Removed _ai_status_field — cmd_ai_status now reads both fields in one awk.)
153
151
 
154
152
  # _ai_mise_pkg (binary -> mise package map) is defined in lib/dot/ai-install.sh.
155
153
 
@@ -193,8 +191,13 @@ cmd_ai_status() {
193
191
  ui_section "$category"
194
192
  current_category="$category"
195
193
  fi
196
- if [[ "$(_ai_status_field "$bin" 2)" == "1" ]]; then
197
- ver="$(_ai_status_field "$bin" 3)"
194
+ # One awk over the cache line for this tool (was two: field 2 and field 3).
195
+ local _st_installed _st_ver
196
+ IFS=$'\t' read -r _st_installed _st_ver < <(
197
+ awk -F'\t' -v b="$bin" '$1==b{print $2"\t"$3;exit}' "$AI_STATUS_CACHE_FILE" 2>/dev/null
198
+ )
199
+ if [[ "$_st_installed" == "1" ]]; then
200
+ ver="$_st_ver"
198
201
  [[ -z "$ver" ]] && ver="installed"
199
202
  [[ "$bin" == "claude" ]] && ver="${ver%% *}"
200
203
  ui_ok "$name" "$ver — $desc"
@@ -33,7 +33,20 @@ cmd_wallpaper() {
33
33
  }
34
34
 
35
35
  cmd_fonts() {
36
- run_script "scripts/fonts/install-nerd-fonts.sh" "Font install script" "$@"
36
+ local sub="${1:-install}"
37
+ case "$sub" in
38
+ patch)
39
+ shift
40
+ run_script "scripts/fonts/patch-fonts.sh" "Font patch helper" "$@"
41
+ ;;
42
+ install | "")
43
+ [[ "$sub" == install ]] && shift || true
44
+ run_script "scripts/fonts/install-nerd-fonts.sh" "Font install script" "$@"
45
+ ;;
46
+ *)
47
+ run_script "scripts/fonts/install-nerd-fonts.sh" "Font install script" "$@"
48
+ ;;
49
+ esac
37
50
  }
38
51
 
39
52
  cmd_tune() {