@sebastienrousseau/dotfiles 0.2.508 → 0.2.511

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 (82) hide show
  1. package/CHANGELOG.md +42 -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/articles/.pages +6 -0
  7. package/docs/articles/2026-07-05-custom-mkdocs-material-dark-theme.md +216 -0
  8. package/docs/articles/2026-07-05-fish-startup-abbr.md +153 -0
  9. package/docs/articles/2026-07-05-master-to-main-rename-runbook.md +128 -0
  10. package/docs/articles/index.md +36 -0
  11. package/docs/guides/INSTALL.md +3 -3
  12. package/docs/index.md +116 -27
  13. package/docs/interop/A2A.md +2 -2
  14. package/docs/interop/POWERSHELL.md +4 -4
  15. package/docs/manual/00-introduction.md +3 -3
  16. package/docs/manual/01-concepts/02-trust-model.md +3 -3
  17. package/docs/manual/01-concepts/04-fleet.md +1 -1
  18. package/docs/manual/02-tutorials/01-first-install.md +1 -1
  19. package/docs/manual/02-tutorials/05-deploy-fleet.md +2 -2
  20. package/docs/manual/03-reference/02-config-files.md +1 -1
  21. package/docs/manual/03-reference/04-templates.md +1 -1
  22. package/docs/manual/04-cookbook/01-recipes.md +1 -1
  23. package/docs/manual/04-cookbook/02-troubleshooting.md +1 -1
  24. package/docs/manual/05-appendices/B-security-checklist.md +1 -1
  25. package/docs/manual/command-index.md +76 -1
  26. package/docs/manual/index.md +1 -1
  27. package/docs/operations/ARCHITECTURE_ROADMAP.md +145 -0
  28. package/docs/operations/CI_CADENCE.md +2 -2
  29. package/docs/operations/COMPLETIONS.md +2 -2
  30. package/docs/operations/COVERAGE.md +4 -4
  31. package/docs/operations/DRIFT.md +1 -1
  32. package/docs/operations/MAINTENANCE.md +6 -6
  33. package/docs/operations/PERFORMANCE.md +6 -6
  34. package/docs/operations/RELIABILITY.md +1 -1
  35. package/docs/operations/ROADMAP_V0_2_503.md +1 -1
  36. package/docs/operations/TRACEABILITY.md +2 -0
  37. package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +6 -6
  38. package/docs/operations/VERSION_SYNC.md +3 -3
  39. package/docs/reference/UTILS.md +82 -0
  40. package/docs/security/AUDIT_BYPASS.md +3 -3
  41. package/docs/security/AUTOMATION_SECRETS.md +1 -1
  42. package/docs/security/CI_PINNING.md +10 -10
  43. package/docs/security/COMMIT_SIGNING.md +10 -10
  44. package/docs/security/DEPS_DEV_EXCEPTIONS.md +4 -4
  45. package/docs/security/DISCLOSURE.md +3 -3
  46. package/docs/security/INCIDENT_RESPONSE.md +1 -1
  47. package/docs/security/INSTALL_VERIFICATION.md +2 -2
  48. package/docs/security/MCP_POLICY.md +4 -4
  49. package/docs/security/SCORECARD.md +7 -7
  50. package/docs/security/SECURITY_CHECKLIST.md +1 -1
  51. package/docs/security/SHELL_EXEMPTIONS.md +2 -2
  52. package/docs/security/SOUP_REGISTER.md +4 -4
  53. package/docs/stylesheets/extra.css +444 -0
  54. package/docs/themes/hero-shot.svg +1 -1
  55. package/install.sh +17 -6
  56. package/package.json +1 -1
  57. package/scripts/ci/check-copyright-headers.sh +1 -1
  58. package/scripts/ci/check-shell-preamble.sh +1 -1
  59. package/scripts/ci/guard-gitleaks-checkout.sh +1 -1
  60. package/scripts/diagnostics/aliases-manifest.sh +19 -1
  61. package/scripts/diagnostics/verify_state.sh +6 -2
  62. package/scripts/diagnostics/version-locks.sh +10 -6
  63. package/scripts/dot/commands/agent.sh +12 -7
  64. package/scripts/dot/commands/ai.sh +8 -5
  65. package/scripts/dot/commands/appearance.sh +14 -1
  66. package/scripts/dot/commands/completion.sh +134 -0
  67. package/scripts/dot/commands/core.sh +8 -0
  68. package/scripts/dot/commands/diagnostics.sh +16 -0
  69. package/scripts/dot/commands/fleet.sh +11 -4
  70. package/scripts/dot/commands/lint.sh +55 -30
  71. package/scripts/dot/commands/registry.sh +7 -1
  72. package/scripts/dot/commands/secrets.sh +61 -7
  73. package/scripts/dot/commands/security.sh +8 -0
  74. package/scripts/dot/commands/tools.sh +11 -2
  75. package/scripts/dot/powershell/Dot.psm1 +1 -1
  76. package/scripts/git-hooks/pre-commit-audit.sh +1 -1
  77. package/scripts/ops/heal-tools.sh +28 -0
  78. package/scripts/ops/teleport.sh +2 -2
  79. package/scripts/qa/examples-coverage.sh +94 -0
  80. package/scripts/tools/detect-collisions.py +19 -1
  81. package/scripts/version-sync.sh +36 -2
  82. 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.508)
74
+ version The version (tag or branch) to install (default: v0.2.511)
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.508"
90
+ local version="v0.2.511"
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.508)."
120
+ error "Unrecognized positional argument '$arg' — expected a semver version (e.g. v0.2.511)."
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.508 reorg ─────────────────────────────────
365
+ # ── Auto-migration for v0.2.511 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.508 migration (idempotent; safe on fresh installs)..."
374
+ echo " Running v0.2.511 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.508",
3
+ "version": "0.2.511",
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" "$@"
@@ -22,7 +22,25 @@ resolve_source_dir() {
22
22
  return 1
23
23
  }
24
24
 
25
- src_dir="${1:-$(resolve_source_dir)}"
25
+ # Descend into the chezmoi source subdir (per `.chezmoiroot`) if
26
+ # present — post-Phase-4b (v0.2.503) the aliases + functions trees
27
+ # live under `defaults/.chezmoitemplates/`, not at the repo root.
28
+ # See `resolve_chezmoi_source_dir` in lib/dot/utils.sh.
29
+ resolve_chezmoi_source_dir() {
30
+ local root="$1"
31
+ if [[ -f "$root/.chezmoiroot" ]]; then
32
+ local sub
33
+ sub="$(head -1 "$root/.chezmoiroot" | tr -d '[:space:]')"
34
+ if [[ -n "$sub" && -d "$root/$sub" ]]; then
35
+ printf "%s\n" "$root/$sub"
36
+ return
37
+ fi
38
+ fi
39
+ printf "%s\n" "$root"
40
+ }
41
+
42
+ src_root="${1:-$(resolve_source_dir)}"
43
+ src_dir="$(resolve_chezmoi_source_dir "$src_root")"
26
44
 
27
45
  rg -n \
28
46
  -e '^[[:space:]]*alias[[:space:]]+[A-Za-z0-9_.:-]+=' \
@@ -32,8 +32,12 @@ check_alias_in_config() {
32
32
  }
33
33
 
34
34
  # 1. Verify Docs
35
- check_file ".chezmoitemplates/aliases/security/README.md"
36
- check_file ".chezmoitemplates/aliases/legal/README.md"
35
+ # Post-Phase-4b (v0.2.503): chezmoi source is under the subdir
36
+ # named in .chezmoiroot (typically "defaults/"). Paths without the
37
+ # prefix silently return "missing" from any CWD other than
38
+ # ~/.dotfiles/defaults/.
39
+ check_file "defaults/.chezmoitemplates/aliases/security/README.md"
40
+ check_file "defaults/.chezmoitemplates/aliases/legal/README.md"
37
41
 
38
42
  # 2. Verify Scripts
39
43
  check_file "scripts/security/lock-configs.sh"
@@ -67,20 +67,24 @@ else
67
67
  fi
68
68
 
69
69
  ui_section "Node/Python pins"
70
- if [[ -f "$src_dir/dot_node-version" ]]; then
71
- ui_kv "node" "$(cat "$src_dir/dot_node-version")"
70
+ # Chezmoi-tracked files (dot_*) live under $cm_src (defaults/) post-
71
+ # Phase-4b, NOT at repo root. Using $src_dir here silently rendered
72
+ # an empty section on every workstation.
73
+ if [[ -f "$cm_src/dot_node-version" ]]; then
74
+ ui_kv "node" "$(cat "$cm_src/dot_node-version")"
72
75
  fi
73
- if [[ -f "$src_dir/dot_noderc.tmpl" ]]; then
74
- ui_kv "noderc" "$(sed -n '1p' "$src_dir/dot_noderc.tmpl")"
76
+ if [[ -f "$cm_src/dot_noderc.tmpl" ]]; then
77
+ ui_kv "noderc" "$(sed -n '1p' "$cm_src/dot_noderc.tmpl")"
75
78
  fi
76
79
 
77
80
  ui_section "Package manager locks"
78
- if [[ -f "$src_dir/dot_config/shell/Brewfile" ]]; then
81
+ if [[ -f "$cm_src/dot_config/shell/Brewfile" ]]; then
79
82
  ui_kv "brew" "Brewfile present"
80
83
  fi
81
- if [[ -f "$src_dir/dot_config/shell/Brewfile.cli" ]]; then
84
+ if [[ -f "$cm_src/dot_config/shell/Brewfile.cli" ]]; then
82
85
  ui_kv "brew-cli" "Brewfile.cli present"
83
86
  fi
87
+ # package.json (if any) is a repo-root artefact — use $src_dir.
84
88
  if [[ -f "$src_dir/package.json" ]]; then
85
89
  ui_kv "node" "package.json version pinned"
86
90
  fi
@@ -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"
@@ -404,7 +405,11 @@ EOF
404
405
  a2a-card)
405
406
  local a2a_card_file json_mode=0 validate_mode=0 strict_mode=0
406
407
  local repo_root
407
- repo_root="$(_agent_repo_root)"
408
+ # `.well-known/` is NOT chezmoi-tracked — it lives at the
409
+ # actual repo root, not the descended `defaults/` subdir.
410
+ # Bypass `_agent_repo_root` (which descends) and read the
411
+ # true root directly.
412
+ repo_root="$(require_source_dir)"
408
413
  a2a_card_file="$repo_root/.well-known/agent-card.json"
409
414
  while [[ $# -gt 0 ]]; do
410
415
  case "$1" in