@sebastienrousseau/dotfiles 0.2.519 → 0.2.520
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.
- package/CHANGELOG.md +182 -0
- package/README.md +1163 -163
- package/docs/ARCHITECTURE.md +117 -0
- package/docs/COPYRIGHT +1 -1
- package/docs/ECOSYSTEM.md +220 -0
- package/docs/GOLD-STANDARD-AUDIT.md +352 -0
- package/docs/GOVERNANCE.md +1 -1
- package/docs/MAINTAINERS.md +1 -1
- package/docs/MINIMUM-TOOLCHAIN.md +100 -0
- package/docs/README.md +1 -1
- package/docs/STRUCTURE.md +1 -1
- package/docs/architecture/ARCHITECTURE.md +11 -108
- package/docs/architecture/REPO_LAYOUT.md +3 -3
- package/docs/guides/MACOS_ICLOUD_SYMLINKS.md +121 -0
- package/docs/index.md +3 -3
- package/docs/manual/00-introduction.md +1 -1
- package/docs/manual/03-reference/01-dot-cli.md +28 -3
- package/docs/manual/command-index.md +24 -4
- package/docs/manual/concept-index.md +2 -0
- package/docs/migration/README.md +81 -0
- package/docs/migration/from-bare-git-repo.md +156 -0
- package/docs/migration/from-gnu-stow.md +165 -0
- package/docs/migration/from-plain-chezmoi.md +148 -0
- package/docs/migration/from-yadm.md +187 -0
- package/docs/operations/PERFORMANCE_BUDGETS.md +196 -0
- package/docs/operations/REGISTRY.md +1 -1
- package/docs/operations/RELEASE_PIPELINE.md +4 -4
- package/docs/operations/TESTING.md +3 -3
- package/docs/operations/TRACEABILITY.md +1 -0
- package/docs/packaging.md +222 -0
- package/docs/reference/FEATURE-MATRIX.md +646 -0
- package/docs/reference/TOOLS.md +1 -1
- package/docs/reference/UTILS.md +1 -0
- package/docs/security/COMPLIANCE.md +1 -1
- package/docs/security/DISCLOSURE.md +4 -4
- package/docs/security/FUZZING.md +113 -18
- package/docs/security/KEY_ROTATION.md +1 -1
- package/docs/security/SCORECARD.md +3 -3
- package/docs/security/VERIFY_RELEASE.md +2 -2
- package/install.sh +6 -6
- package/package.json +2 -2
- package/scripts/ci/check-copyright-headers.sh +1 -1
- package/scripts/ci/check-shell-preamble.sh +1 -1
- package/scripts/ci/guard-gitleaks-checkout.sh +1 -1
- package/scripts/demo/record.sh +1 -1
- package/scripts/diagnostics/a2a-conformance.sh +1 -1
- package/scripts/diagnostics/alias-governance.sh +30 -3
- package/scripts/diagnostics/aliases-cheatsheet.sh +1 -1
- package/scripts/diagnostics/aliases-manifest.sh +1 -1
- package/scripts/diagnostics/attest-verify.sh +147 -0
- package/scripts/diagnostics/benchmark.sh +1 -1
- package/scripts/diagnostics/conflicts.sh +1 -1
- package/scripts/diagnostics/doctor-unified.sh +6 -2
- package/scripts/diagnostics/doctor.sh +56 -10
- package/scripts/diagnostics/drift-dashboard.sh +3 -2
- package/scripts/diagnostics/health.sh +43 -10
- package/scripts/diagnostics/history-analysis.sh +1 -1
- package/scripts/diagnostics/mcp-doctor.sh +2 -2
- package/scripts/diagnostics/perf.sh +1 -1
- package/scripts/diagnostics/scorecard.sh +3 -2
- package/scripts/diagnostics/secret-governance.sh +1 -1
- package/scripts/diagnostics/security-score.sh +1 -1
- package/scripts/diagnostics/smoke-test.sh +1 -1
- package/scripts/diagnostics/snapshot.sh +1 -1
- package/scripts/diagnostics/verify.sh +1 -1
- package/scripts/diagnostics/verify_state.sh +1 -1
- package/scripts/diagnostics/version-locks.sh +1 -1
- package/scripts/diagnostics/workstation-attestation.sh +26 -1
- package/scripts/dot/commands/agent.sh +64 -14
- package/scripts/dot/commands/agents.sh +24 -8
- package/scripts/dot/commands/ai.sh +20 -7
- package/scripts/dot/commands/aliases.sh +1 -1
- package/scripts/dot/commands/appearance.sh +1 -1
- package/scripts/dot/commands/completion.sh +42 -5
- package/scripts/dot/commands/core.sh +1 -1
- package/scripts/dot/commands/diagnostics.sh +1 -1
- package/scripts/dot/commands/env-emit.sh +1 -1
- package/scripts/dot/commands/fleet.sh +41 -18
- package/scripts/dot/commands/init.sh +1 -1
- package/scripts/dot/commands/lint.sh +1 -1
- package/scripts/dot/commands/manual.sh +1 -1
- package/scripts/dot/commands/meta.sh +115 -10
- package/scripts/dot/commands/patterns.sh +1 -1
- package/scripts/dot/commands/registry.sh +43 -7
- package/scripts/dot/commands/restore.sh +1 -1
- package/scripts/dot/commands/secrets.sh +1 -1
- package/scripts/dot/commands/security.sh +1 -1
- package/scripts/dot/commands/tools.sh +21 -7
- package/scripts/fonts/install-nerd-fonts.sh +1 -1
- package/scripts/fonts/patch-fonts.sh +1 -1
- package/scripts/git-hooks/install.sh +1 -1
- package/scripts/git-hooks/pre-commit-audit.sh +2 -2
- package/scripts/lib/secrets_provider.sh +19 -4
- package/scripts/nvim/headless-upgrade.lua +81 -0
- package/scripts/ops/ai-setup.sh +1 -1
- package/scripts/ops/bundle.sh +1 -1
- package/scripts/ops/chaos.sh +1 -1
- package/scripts/ops/chezmoi-apply.sh +1 -1
- package/scripts/ops/chezmoi-diff.sh +1 -1
- package/scripts/ops/chezmoi-remove.sh +3 -3
- package/scripts/ops/chezmoi-update.sh +6 -2
- package/scripts/ops/heal-chezmoi.sh +1 -1
- package/scripts/ops/heal-system.sh +1 -1
- package/scripts/ops/heal-tools.sh +1 -1
- package/scripts/ops/heal.sh +1 -1
- package/scripts/ops/post-apply-repair.sh +1 -1
- package/scripts/ops/prewarm.sh +1 -1
- package/scripts/ops/release.sh +1 -1
- package/scripts/ops/rollback.sh +11 -2
- package/scripts/ops/setup.sh +1 -1
- package/scripts/ops/teleport.sh +1 -1
- package/scripts/qa/check-feature-matrix.sh +296 -0
- package/scripts/qa/check-version-consistency.sh +7 -119
- package/scripts/qa/coverage-baseline.sh +1 -1
- package/scripts/qa/docs-coverage.sh +9 -3
- package/scripts/qa/examples-coverage.sh +1 -1
- package/scripts/qa/reliability-audit.sh +1 -1
- package/scripts/qa/scorecard-snapshot.sh +1 -1
- package/scripts/qa/traceability-coverage.sh +9 -2
- package/scripts/qa/validate-examples.sh +66 -3
- package/scripts/qa/wsl-contract.sh +1 -1
- package/scripts/secrets/age-init.sh +1 -1
- package/scripts/secrets/create-secrets-file.sh +1 -1
- package/scripts/secrets/encrypt-ssh-key.sh +1 -1
- package/scripts/security/backup.sh +1 -1
- package/scripts/security/check-disclosure-key-expiry.sh +1 -1
- package/scripts/security/dns-doh.sh +1 -1
- package/scripts/security/encryption-check.sh +1 -1
- package/scripts/security/enforce-policies.sh +315 -98
- package/scripts/security/firewall.sh +1 -1
- package/scripts/security/lock-configs.sh +1 -1
- package/scripts/security/lock-screen.sh +1 -1
- package/scripts/security/manage-secrets.sh +1 -1
- package/scripts/security/ssh-cert.sh +1 -1
- package/scripts/security/telemetry-kill.sh +1 -1
- package/scripts/security/usb-safety.sh +1 -1
- package/scripts/theme/apply-gnome-theme.sh +1 -1
- package/scripts/theme/extract-heic-frames.sh +1 -1
- package/scripts/theme/extract-theme.py +284 -6
- package/scripts/theme/install-boot-logo.sh +1 -1
- package/scripts/theme/install-catppuccin-themes.sh +1 -1
- package/scripts/theme/install-cursors.sh +1 -1
- package/scripts/theme/install-file-icons.sh +1 -1
- package/scripts/theme/install-grub-theme.sh +1 -1
- package/scripts/theme/install-lock-icon.sh +1 -1
- package/scripts/theme/merge-wallpaper.sh +1 -1
- package/scripts/theme/rebuild-themes.sh +64 -5
- package/scripts/theme/switch.sh +46 -19
- package/scripts/theme/wallpaper-rotate.sh +1 -1
- package/scripts/theme/wallpaper-sync.sh +1 -1
- package/scripts/tools/cmatrix.sh +1 -1
- package/scripts/tools/detect-collisions.py +1 -1
- package/scripts/tools/emoji-picker.sh +1 -1
- package/scripts/tools/figlet-banner.sh +1 -1
- package/scripts/tools/log-rotate.sh +1 -1
- package/scripts/tools/lolcat-wrap.sh +1 -1
- package/scripts/tools/pipes.sh +1 -1
- package/scripts/tuning/linux.sh +1 -1
- package/scripts/tuning/macos.sh +1 -1
- package/scripts/uninstall.sh +1 -1
- package/scripts/verify-release-versions +156 -0
- package/scripts/version-sync.sh +63 -3
- package/LICENSE +0 -21
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
render_with_liquid: false
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# macOS iCloud Drive Symlinks
|
|
6
|
+
|
|
7
|
+
On macOS, this dotfiles setup can (safely) symlink personal directories into iCloud Drive so `~/Desktop`, `~/Documents`, `~/Downloads`, `~/Movies`, `~/Music`, `~/Pictures`, and `~/Public` all live in iCloud and back up automatically.
|
|
8
|
+
|
|
9
|
+
The mechanism is `defaults/run_before_macos-icloud-symlinks.sh.tmpl`, which chezmoi runs before **every** `apply` — not once, and not only when the script changes. That is deliberate: a run-once script gets a single attempt, and on a fresh Mac that attempt lands while iCloud Drive is still syncing the folder tree down, so every candidate would skip and the one chance would be spent. Running each time lets it link whatever has become safe to link since the last apply. Repeat runs are no-ops that cost a few milliseconds.
|
|
10
|
+
|
|
11
|
+
## `~/Desktop` and `~/Documents` are a special case
|
|
12
|
+
|
|
13
|
+
macOS has its own **"Desktop & Documents Folders"** iCloud feature (System Settings -> Apple Account -> iCloud -> iCloud Drive -> Options). When it is on, macOS itself syncs those two folders, and it marks them in the iCloud container by putting symlinks there pointing *back* at your home directory:
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
com~apple~CloudDocs/Desktop -> ~/Desktop
|
|
17
|
+
com~apple~CloudDocs/Documents -> ~/Documents
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Check whether it is on:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
defaults read com.apple.finder FXICloudDriveDesktop # 1 = Desktop sync on
|
|
24
|
+
defaults read com.apple.finder FXICloudDriveDocuments # 1 = Documents sync on
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**If those return `1`, `~/Desktop` and `~/Documents` are already fully synced to iCloud and across your devices — by macOS, not by this script.** They will show as `SKIP ... iCloud source is itself a symlink` in the log. That is the correct outcome, not a failure.
|
|
28
|
+
|
|
29
|
+
Do **not** apply the manual migration recipe below to `~/Desktop` or `~/Documents` while native sync is on: you would be moving data into a symlink that points back at its own source, fighting a feature macOS is already managing. Turn native sync off first if you genuinely want the symlink approach — but for these two folders the native feature is the better mechanism, since Finder, Migration Assistant, and iOS all understand it.
|
|
30
|
+
|
|
31
|
+
The symlink approach in this guide is for the folders macOS does *not* cover natively: `~/Downloads`, `~/Movies`, `~/Music`, `~/Pictures`, `~/Public`.
|
|
32
|
+
|
|
33
|
+
## Safety guarantees
|
|
34
|
+
|
|
35
|
+
This script is the **replacement** for a previous `symlink_*.tmpl` set that had a data-loss bug (see #1018): chezmoi's built-in symlink handling does `rm -rf $target; ln -s $source $target`, which destroys real content if the target directory has data.
|
|
36
|
+
|
|
37
|
+
The current script's contract is:
|
|
38
|
+
|
|
39
|
+
| Situation | What the script does |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `~/$name` is already the correct symlink to iCloud | no-op |
|
|
42
|
+
| `~/$name` is a symlink pointing somewhere else | **skip, log** — never overwrite your own link |
|
|
43
|
+
| `~/$name` is a directory with any content (including `.DS_Store`) | **skip, log** — never delete your data |
|
|
44
|
+
| `~/$name` is an empty directory | `rmdir` (fails safely if non-empty due to a race) + create symlink |
|
|
45
|
+
| `~/$name` is a regular file | **skip, log** — never touch |
|
|
46
|
+
| `~/$name` does not exist | create symlink directly |
|
|
47
|
+
| iCloud source `com~apple~CloudDocs/$name` does not exist | **skip, log** — iCloud may still be syncing |
|
|
48
|
+
| iCloud Drive is not set up on the Mac | **skip everything, log** — no partial state |
|
|
49
|
+
| iCloud source `com~apple~CloudDocs/$name` is itself a symlink | **skip, log** — macOS's native Desktop & Documents sync owns it (see below) |
|
|
50
|
+
|
|
51
|
+
The script has **two kill-switches**:
|
|
52
|
+
|
|
53
|
+
- `touch ~/.dotfiles.icloud-skip` — permanent per-machine opt-out
|
|
54
|
+
- `DOTFILES_ICLOUD_SYMLINKS=0` — env var, one run only
|
|
55
|
+
|
|
56
|
+
And a **dry-run mode**:
|
|
57
|
+
|
|
58
|
+
- `DOTFILES_ICLOUD_DRY_RUN=1` — log every decision, take no action
|
|
59
|
+
|
|
60
|
+
## Rescue: how to link a directory that has content
|
|
61
|
+
|
|
62
|
+
If one of the non-native folders (`~/Downloads`, `~/Movies`, `~/Music`, `~/Pictures`, `~/Public`) already has content and you want it in iCloud — the example uses `Documents`, which applies only if you have turned native Desktop & Documents sync **off**:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# 1. Move your data into iCloud MANUALLY
|
|
66
|
+
mv ~/Documents/* ~/Documents/.* "~/Library/Mobile Documents/com~apple~CloudDocs/Documents/" 2>/dev/null
|
|
67
|
+
|
|
68
|
+
# 2. Verify iCloud has everything
|
|
69
|
+
ls -la "~/Library/Mobile Documents/com~apple~CloudDocs/Documents/"
|
|
70
|
+
|
|
71
|
+
# 3. Now the dir is empty — chezmoi's next apply will do the rmdir + symlink
|
|
72
|
+
rmdir ~/Documents # sanity check: this succeeds only if truly empty
|
|
73
|
+
chezmoi apply
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## After the links exist: what changes
|
|
77
|
+
|
|
78
|
+
Linking a folder into iCloud does exactly what it says, and that has consequences worth understanding *before* you migrate rather than after.
|
|
79
|
+
|
|
80
|
+
**Storage.** Everything saved to a linked folder counts against your iCloud quota, not just local disk. `~/Downloads` is the one that catches people out.
|
|
81
|
+
|
|
82
|
+
**Deletion.** Deleting a file from a linked folder deletes it from iCloud, and therefore from every device signed into that account. There is no local-only copy any more. This is inherent to symlinking and is not something the hook can guard.
|
|
83
|
+
|
|
84
|
+
**Eviction.** macOS may evict a synced file's contents to reclaim disk space, leaving a placeholder behind. Reading it downloads it again — so a script that walks one of these folders can block on the network where it used to return instantly.
|
|
85
|
+
|
|
86
|
+
**Two things in this repository write into these folders.** Neither runs during `chezmoi apply`; both are commands you invoke deliberately:
|
|
87
|
+
|
|
88
|
+
| What | Where | Why it matters after linking |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| `scripts/theme/merge-wallpaper.sh` | `~/Pictures/Wallpapers` (override with `DOTFILES_WALLPAPER_DIR`) | Merges a light/dark pair into one `.heic` and then **deletes both source files**. After linking, that pair is consumed from iCloud. Point `DOTFILES_WALLPAPER_DIR` at a local directory to keep the library off iCloud. |
|
|
91
|
+
| `defaults/dot_config/mpv/mpv.conf` | `~/Pictures/Screenshots` | `screenshot-directory` is set here, so mpv screenshots land in iCloud. |
|
|
92
|
+
|
|
93
|
+
Nothing else in this repository writes into the seven folders, and chezmoi itself never touches them: they are listed in the Darwin block of `.chezmoiignore.tmpl`, and `chezmoi managed` reports none of them among the paths it controls.
|
|
94
|
+
|
|
95
|
+
## Log
|
|
96
|
+
|
|
97
|
+
Every run appends to `$XDG_STATE_HOME/dotfiles/icloud-symlinks.log` (default: `~/.local/state/dotfiles/icloud-symlinks.log`). Grep for `SKIP` to see why a candidate wasn't linked, or `LINK` to see what was created.
|
|
98
|
+
|
|
99
|
+
## Belt-and-braces protection
|
|
100
|
+
|
|
101
|
+
The same directory names are listed in `defaults/.chezmoiignore.tmpl`'s Darwin block, so even if the script never ran, chezmoi's regular `apply` would still refuse to touch these paths on macOS. Two independent layers of protection.
|
|
102
|
+
|
|
103
|
+
## Tests
|
|
104
|
+
|
|
105
|
+
Three suites, 52 assertions, all of them run under `/bin/bash` 3.2 as well as bash 5:
|
|
106
|
+
|
|
107
|
+
- `tests/unit/misc/test_macos_icloud_symlinks.sh` — 29 assertions covering every branch of the refusal matrix.
|
|
108
|
+
- `tests/regression/test_macos_icloud_symlinks_safety.sh` — 12 assertions on the data-loss invariants, checking that named canary files survive.
|
|
109
|
+
- `tests/regression/test_macos_icloud_symlinks_manifest.sh` — 11 assertions that hash the *whole* sandbox tree before and after, so a file lost in a path nobody named still shows up. Verified to drop from 11/11 to 4/11 against a deliberately reintroduced #1018.
|
|
110
|
+
|
|
111
|
+
`tests/regression/test_gate_integrity.sh` adds 10 more asserting those gates fail when they should. If any of them regress, CI blocks the merge.
|
|
112
|
+
|
|
113
|
+
## Manual override: disable entirely
|
|
114
|
+
|
|
115
|
+
If you never want the automation:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
touch ~/.dotfiles.icloud-skip
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The script sees this file in the first 5 lines of execution and exits 0 immediately, without touching the filesystem.
|
package/docs/index.md
CHANGED
|
@@ -17,7 +17,7 @@ render_with_liquid: false
|
|
|
17
17
|
<a class="primary" href="guides/INSTALL/">Install →</a>
|
|
18
18
|
<a href="https://github.com/sebastienrousseau/dotfiles">GitHub</a>
|
|
19
19
|
<a href="reference/UTILS/">Utilities</a>
|
|
20
|
-
<a href="
|
|
20
|
+
<a href="ARCHITECTURE/">Architecture</a>
|
|
21
21
|
</div>
|
|
22
22
|
|
|
23
23
|
</section>
|
|
@@ -88,7 +88,7 @@ render_with_liquid: false
|
|
|
88
88
|
|
|
89
89
|
Deterministic templates, feature flags, profiles, `run_onchange_` hooks. Everything lives in `defaults/` and applies to `$HOME` on-demand.
|
|
90
90
|
|
|
91
|
-
[→ Architecture](
|
|
91
|
+
[→ Architecture](ARCHITECTURE.md)
|
|
92
92
|
|
|
93
93
|
</div>
|
|
94
94
|
|
|
@@ -120,7 +120,7 @@ Once installed:
|
|
|
120
120
|
|
|
121
121
|
- [**Install guide**](guides/INSTALL.md) — full bootstrap walkthrough, per-platform.
|
|
122
122
|
- [**Utilities & `dot` CLI**](reference/UTILS.md) — every subcommand with examples.
|
|
123
|
-
- [**Architecture**](
|
|
123
|
+
- [**Architecture**](ARCHITECTURE.md) — how the layers fit together.
|
|
124
124
|
- [**Trusted agent workstation**](operations/TRUSTED_AGENT_WORKSTATION.md) — hardening + attestation runbook.
|
|
125
125
|
- [**Troubleshooting**](guides/TROUBLESHOOTING.md) — the common gotchas.
|
|
126
126
|
- [**Support matrix**](reference/SUPPORT_MATRIX.md) — OS × shell × package-manager grid.
|
|
@@ -4,7 +4,7 @@ render_with_liquid: false
|
|
|
4
4
|
|
|
5
5
|
# Introduction
|
|
6
6
|
|
|
7
|
-
This manual describes `.dotfiles` v0.2.
|
|
7
|
+
This manual describes `.dotfiles` v0.2.520 — a trusted agent workstation baseline for macOS, Linux, and WSL.
|
|
8
8
|
|
|
9
9
|
The repository is more than a personal dotfiles collection. It ships as workstation infrastructure: signed, attested, multi-platform, AI-aware, and self-healing. Chezmoi handles templating and platform differences. The `dot` CLI sits on top and coordinates lifecycle operations.
|
|
10
10
|
|
|
@@ -212,14 +212,39 @@ still work as deprecated aliases. See [AI.md](../../AI.md) for the full guide.
|
|
|
212
212
|
|
|
213
213
|
### `dot mcp`
|
|
214
214
|
|
|
215
|
-
Inspect MCP policy and registry.
|
|
215
|
+
Inspect MCP policy and registry, or run the MCP server.
|
|
216
216
|
|
|
217
217
|
```
|
|
218
|
-
dot mcp [--strict|-s] [--json|-j]
|
|
218
|
+
dot mcp [--strict|-s] [--json|-j] # audit (default: doctor)
|
|
219
|
+
dot mcp registry [--json|-j] # show the tracked MCP server registry
|
|
220
|
+
dot mcp serve # run the stdio MCP server
|
|
219
221
|
```
|
|
220
222
|
|
|
221
223
|
With `--strict`, validates the active MCP registry matches the policy hash. Exit code 1 on mismatch.
|
|
222
224
|
|
|
225
|
+
#### `dot mcp serve`
|
|
226
|
+
|
|
227
|
+
Runs the Model Context Protocol server described by
|
|
228
|
+
`.well-known/mcp/server-card.json`: JSON-RPC 2.0 over newline-delimited
|
|
229
|
+
frames on stdin/stdout, with stderr reserved for logs. It is meant to be
|
|
230
|
+
launched by an MCP client, not typed at a prompt:
|
|
231
|
+
|
|
232
|
+
```json
|
|
233
|
+
{ "mcpServers": { "dotfiles": { "command": "dot", "args": ["mcp", "serve"] } } }
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
It serves four read-only tools — `mcp-doctor`, `agent-mode`,
|
|
237
|
+
`workstation-attestation` and `fleet-status`, each a fixed `dot` argument
|
|
238
|
+
vector run without a shell — and five resources (the MCP policy, the MCP
|
|
239
|
+
registry, the agent profiles and both discovery cards). Mutating paths
|
|
240
|
+
(`dot mode set`, `dot attest --write`) are deliberately not exposed: a
|
|
241
|
+
client cannot change this workstation through the server.
|
|
242
|
+
|
|
243
|
+
The binary is `~/.local/bin/dot-mcp`, built by chezmoi from
|
|
244
|
+
[`defaults/dot_local/share/dot-mcp`](../../../defaults/dot_local/share/dot-mcp/README.md);
|
|
245
|
+
when it is missing and a Go toolchain is present, `dot mcp serve` builds
|
|
246
|
+
it on demand into the user cache.
|
|
247
|
+
|
|
223
248
|
### `dot mode [<profile>]`
|
|
224
249
|
|
|
225
250
|
Show or set the agent profile.
|
|
@@ -360,7 +385,7 @@ dot registry url # show the active registry URL
|
|
|
360
385
|
dot registry set-url <url> # override the registry URL (HTTPS-only)
|
|
361
386
|
```
|
|
362
387
|
|
|
363
|
-
Default registry: `https://sebastienrousseau.github.io/dotfiles/registry.json`. Cache lives
|
|
388
|
+
Default registry: `https://sebastienrousseau.github.io/dotfiles/registry.json`. Cache lives under `${XDG_CACHE_HOME:-~/.cache}/dotfiles/registry/`, one `index-<digest>.json` per registry URL, with a 6h TTL. One-off override: `DOTFILES_REGISTRY_URL=<url> dot registry list`.
|
|
364
389
|
|
|
365
390
|
The JSON contract + module-contribution flow live in [`docs/operations/REGISTRY.md`](../../operations/REGISTRY.md).
|
|
366
391
|
|
|
@@ -4,9 +4,12 @@ render_with_liquid: false
|
|
|
4
4
|
|
|
5
5
|
# Command Index
|
|
6
6
|
|
|
7
|
-
Generated from `dot help all
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
Generated from `dot help all` plus the `dot help <command>` detail
|
|
8
|
+
registry, so a command that is routable and has help text is listed
|
|
9
|
+
even when it is absent from the compact overview. To refresh after
|
|
10
|
+
adding or renaming a subcommand, run
|
|
11
|
+
`tools/docs/generate-command-index.sh`. The CI job
|
|
12
|
+
`lint/command-index` fails when this file is stale.
|
|
10
13
|
|
|
11
14
|
| Command | Summary |
|
|
12
15
|
|---------|---------|
|
|
@@ -42,13 +45,18 @@ job `lint/command-index` fails when this file is stale.
|
|
|
42
45
|
| `dot aliases` | stats Show alias usage counts from shell history |
|
|
43
46
|
| `dot aliases` | tiers Show which alias tiers/ecosystems are enabled |
|
|
44
47
|
| `dot aliases` | why Show details and deprecation status for a single alias |
|
|
48
|
+
| `dot apply` | Apply the current dotfiles to this machine. |
|
|
45
49
|
| `dot attest` | Export workstation attestation evidence (--json |
|
|
50
|
+
| `dot autohand` | Run the Autohand CLI with dotfiles context patterns. |
|
|
46
51
|
| `dot backup` | Create a compressed backup of your home |
|
|
52
|
+
| `dot benchmark` | Benchmark shell startup with per-component profiling |
|
|
47
53
|
| `dot bundle` | Create offline archive of dotfiles environment |
|
|
48
54
|
| `dot cache-refresh` | Regenerate shell caches for ultra-fast startup |
|
|
49
55
|
| `dot cd` | Print source directory path (use: cd $(dot cd)) |
|
|
50
56
|
| `dot chaos` | Simulate config corruption to test self-healing |
|
|
51
57
|
| `dot cl` | Claude CLI with context patterns |
|
|
58
|
+
| `dot claude` | Run the Claude CLI bridge (alias for cl). |
|
|
59
|
+
| `dot codex` | Run the OpenAI Codex CLI with dotfiles context patterns. |
|
|
52
60
|
| `dot commit` | AI-powered conventional commit |
|
|
53
61
|
| `dot completion` | Generate shell completions (bash/zsh/fish/nu) from the command registry |
|
|
54
62
|
| `dot copilot` | GitHub Copilot CLI with context patterns |
|
|
@@ -73,8 +81,12 @@ job `lint/command-index` fails when this file is stale.
|
|
|
73
81
|
| `dot fleet` | namespace Show or set the active namespace for multi-tenant isolation |
|
|
74
82
|
| `dot fleet` | status Show this node's fleet status: id, namespace, version, OS, drift, last apply |
|
|
75
83
|
| `dot fonts` | Install (default) or patch Nerd Fonts (JetBrainsMono by default) |
|
|
84
|
+
| `dot goose` | Run the Goose CLI with dotfiles context patterns. |
|
|
85
|
+
| `dot heal` | Auto-repair common dotfiles problems (missing files, broken links). |
|
|
86
|
+
| `dot health` | Run the health dashboard with optional fixes. |
|
|
76
87
|
| `dot help` | Show this help message |
|
|
77
88
|
| `dot history` | Shell history analysis |
|
|
89
|
+
| `dot init` | Bootstrap a foreign dotfiles repo through chezmoi + dot. |
|
|
78
90
|
| `dot keys` | Keybindings (sign-check: verify git signing) |
|
|
79
91
|
| `dot keys` | sign-check Verify git commit-signing configuration and key availability |
|
|
80
92
|
| `dot kimi` | Kimi CLI with context patterns |
|
|
@@ -83,9 +95,11 @@ job `lint/command-index` fails when this file is stale.
|
|
|
83
95
|
| `dot lint` | Lint shell scripts (--fix |
|
|
84
96
|
| `dot load-bench` | Measure time to heavy-layer readiness |
|
|
85
97
|
| `dot lock-screen` | Enforce lock screen idle settings [Linux] |
|
|
86
|
-
| `dot
|
|
98
|
+
| `dot manual` | Open or download the dotfiles manual in HTML, PDF, EPUB, or text. |
|
|
99
|
+
| `dot mcp` | Inspect MCP policy, supply chain, and registry; serve MCP over stdio |
|
|
87
100
|
| `dot mcp` | doctor Run the MCP policy/supply-chain/config audit |
|
|
88
101
|
| `dot mcp` | registry Show the configured MCP server registry |
|
|
102
|
+
| `dot mcp` | serve Run the stdio MCP server (JSON-RPC 2.0 on stdin/stdout) |
|
|
89
103
|
| `dot metrics` | Show recent observability metrics (JSONL) |
|
|
90
104
|
| `dot mode` | Set or inspect agent operating profiles (ask/plan/apply/audit) |
|
|
91
105
|
| `dot mode` | current Show the active agent profile and its policy |
|
|
@@ -103,15 +117,18 @@ job `lint/command-index` fails when this file is stale.
|
|
|
103
117
|
| `dot patterns` | view View an AI steering pattern |
|
|
104
118
|
| `dot perf` | Show performance mode and quick timing |
|
|
105
119
|
| `dot policy` | Check and enforce security policies across the environment |
|
|
120
|
+
| `dot prewarm` | Alias of cache-refresh — regenerate shell init caches. |
|
|
106
121
|
| `dot profile` | Show/switch configuration profile |
|
|
107
122
|
| `dot profile` | set Set the active configuration profile (run dot sync to apply) |
|
|
108
123
|
| `dot profile` | show Show the active configuration profile and feature flags |
|
|
124
|
+
| `dot qwen` | Run the Qwen Coder CLI with dotfiles context patterns. |
|
|
109
125
|
| `dot registry` | info Print full metadata for a registry module |
|
|
110
126
|
| `dot registry` | install Install a registry module (scaffold) |
|
|
111
127
|
| `dot registry` | list List modules in the configured module registry |
|
|
112
128
|
| `dot registry` | search Filter registry modules by keyword |
|
|
113
129
|
| `dot registry` | set-url Override the registry URL (https only; persists) |
|
|
114
130
|
| `dot registry` | url Show the active registry URL |
|
|
131
|
+
| `dot restore` | Restore from a backup or git ref. |
|
|
115
132
|
| `dot rollback` | Rollback dotfiles to a previous state |
|
|
116
133
|
| `dot sandbox` | Launch a safe sandbox preview (Docker/Podman) |
|
|
117
134
|
| `dot score` | System health and security scorecard |
|
|
@@ -126,6 +143,7 @@ job `lint/command-index` fails when this file is stale.
|
|
|
126
143
|
| `dot secrets` | set Store a secret value under a key |
|
|
127
144
|
| `dot secrets-create` | Create an encrypted secrets file |
|
|
128
145
|
| `dot secrets-init` | Initialize age key for secrets |
|
|
146
|
+
| `dot security-score` | Assess workstation security posture. |
|
|
129
147
|
| `dot sgpt` | Shell-GPT with context patterns |
|
|
130
148
|
| `dot snapshot` | Capture baseline system snapshot |
|
|
131
149
|
| `dot ssh-cert` | Manage short-lived SSH certificates |
|
|
@@ -150,6 +168,8 @@ job `lint/command-index` fails when this file is stale.
|
|
|
150
168
|
| `dot upgrade` | Update system toolchains, plugins, and dotfiles |
|
|
151
169
|
| `dot usb-safety` | Disable automount for removable media [Linux] |
|
|
152
170
|
| `dot version` | Show version information. |
|
|
171
|
+
| `dot vibe` | Run the Vibe AI CLI with dotfiles context patterns. |
|
|
153
172
|
| `dot wallpaper` | Apply a wallpaper from your library [macOS,Linux] |
|
|
154
173
|
| `dot wallpaper` | rotate Rotate to the next wallpaper in your library |
|
|
155
174
|
| `dot wallpaper` | sync Sync wallpaper from your library |
|
|
175
|
+
| `dot zai` | Run the ZAI CLI with dotfiles context patterns. |
|
|
@@ -9,6 +9,7 @@ Alphabetical list of concepts covered in the manual.
|
|
|
9
9
|
- Accessibility
|
|
10
10
|
- Adding a New Flag
|
|
11
11
|
- Agent Policy Enforcement
|
|
12
|
+
- Agents
|
|
12
13
|
- AI & Agents
|
|
13
14
|
- Algorithms
|
|
14
15
|
- Apply / Sync
|
|
@@ -97,6 +98,7 @@ Alphabetical list of concepts covered in the manual.
|
|
|
97
98
|
- Read by Tools
|
|
98
99
|
- Recovery
|
|
99
100
|
- Reference
|
|
101
|
+
- Registry
|
|
100
102
|
- Required Binaries
|
|
101
103
|
- Scenario
|
|
102
104
|
- Secret-Related
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
render_with_liquid: false
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
<!-- SPDX-License-Identifier: Apache-2.0 OR MIT -->
|
|
6
|
+
<!-- Copyright (c) 2015-2026 Sebastien Rousseau -->
|
|
7
|
+
|
|
8
|
+
# Migration guides
|
|
9
|
+
|
|
10
|
+
Coming from another dotfiles manager. One guide per tool, each with
|
|
11
|
+
real commands, a rollback path, and an honest section on what you lose
|
|
12
|
+
by switching.
|
|
13
|
+
|
|
14
|
+
| You use | Guide | Rough effort |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| [yadm](https://yadm.io/) | [`from-yadm.md`](from-yadm.md) | 30 min — closest model, both wrap git and template |
|
|
17
|
+
| [GNU Stow](https://www.gnu.org/software/stow/) | [`from-gnu-stow.md`](from-gnu-stow.md) | 1–2 h — symlink farm to managed copies is a real change |
|
|
18
|
+
| A bare git repo (`--git-dir=$HOME/.dotfiles`) | [`from-bare-git-repo.md`](from-bare-git-repo.md) | 45 min |
|
|
19
|
+
| Plain chezmoi, no framework | [`from-plain-chezmoi.md`](from-plain-chezmoi.md) | 10 min — same engine underneath |
|
|
20
|
+
|
|
21
|
+
Upgrading between versions of *this* project is a different document:
|
|
22
|
+
[`../operations/MIGRATION.md`](../operations/MIGRATION.md).
|
|
23
|
+
|
|
24
|
+
## Read this first
|
|
25
|
+
|
|
26
|
+
Three facts that apply to every guide.
|
|
27
|
+
|
|
28
|
+
**chezmoi is the engine.** This project is a framework *over*
|
|
29
|
+
[chezmoi](https://www.chezmoi.io/), not a replacement for it. Files
|
|
30
|
+
live in a source tree, `chezmoi apply` renders them into `$HOME`, and
|
|
31
|
+
`dot` is a control plane over that. If you already know chezmoi, you
|
|
32
|
+
already know 80% of this.
|
|
33
|
+
|
|
34
|
+
**Nothing is destroyed without asking.** `chezmoi apply` shows a diff
|
|
35
|
+
first when you run `dot diff`, and `dot sync --check` previews without
|
|
36
|
+
writing. Every guide below tells you to take a backup anyway, because
|
|
37
|
+
"nothing is destroyed" is a claim about the tool, not about your typos.
|
|
38
|
+
|
|
39
|
+
**You can leave.** `scripts/uninstall.sh --force` runs `chezmoi purge`
|
|
40
|
+
and removes the repo, the chezmoi config and state, caches, and logs.
|
|
41
|
+
Your files stay where they were applied; nothing phones home and
|
|
42
|
+
nothing is left behind to reinstall itself. Each guide ends with the
|
|
43
|
+
rollback for that specific migration.
|
|
44
|
+
|
|
45
|
+
## The shape of every migration
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
# 1. Back up. Always.
|
|
49
|
+
tar -czf ~/dotfiles-backup-$(date +%F).tar.gz -C "$HOME" \
|
|
50
|
+
.bashrc .zshrc .config .gitconfig 2>/dev/null || true
|
|
51
|
+
|
|
52
|
+
# 2. Install the framework (does not touch your files yet).
|
|
53
|
+
bash -c "$(curl -fsSL https://raw.githubusercontent.com/sebastienrousseau/dotfiles/main/install.sh)"
|
|
54
|
+
|
|
55
|
+
# 3. Bring your own files under management, one at a time.
|
|
56
|
+
dot add ~/.gitconfig
|
|
57
|
+
dot add ~/.config/nvim
|
|
58
|
+
|
|
59
|
+
# 4. Preview, then apply.
|
|
60
|
+
dot diff
|
|
61
|
+
dot sync
|
|
62
|
+
|
|
63
|
+
# 5. Check the result.
|
|
64
|
+
dot doctor
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Step 3 is where the guides differ, because it depends on how your
|
|
68
|
+
current tool stores things.
|
|
69
|
+
|
|
70
|
+
## Choosing not to switch
|
|
71
|
+
|
|
72
|
+
Genuinely reasonable reasons to stay where you are:
|
|
73
|
+
|
|
74
|
+
- **You only symlink a handful of files and never templated anything.**
|
|
75
|
+
GNU Stow is simpler and does that job well.
|
|
76
|
+
- **You need Windows-native support without WSL or PowerShell 7.**
|
|
77
|
+
- **You do not want a CLI layer.** Plain chezmoi is a smaller surface.
|
|
78
|
+
|
|
79
|
+
The case for switching is multi-machine fleets, per-host templating,
|
|
80
|
+
multi-shell parity, and signed/attested releases. If none of those
|
|
81
|
+
describe you, the migration cost may not repay itself.
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
---
|
|
2
|
+
render_with_liquid: false
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
<!-- SPDX-License-Identifier: Apache-2.0 OR MIT -->
|
|
6
|
+
<!-- Copyright (c) 2015-2026 Sebastien Rousseau -->
|
|
7
|
+
|
|
8
|
+
# Migrating from a bare git repo
|
|
9
|
+
|
|
10
|
+
The `git --git-dir=$HOME/.dotfiles --work-tree=$HOME` pattern, usually
|
|
11
|
+
behind a `config` alias. No dependencies, no symlinks, no templating —
|
|
12
|
+
and `$HOME` is the work tree, which is the part that has to change.
|
|
13
|
+
|
|
14
|
+
## Concept mapping
|
|
15
|
+
|
|
16
|
+
| Bare repo | Here |
|
|
17
|
+
|---|---|
|
|
18
|
+
| `config add ~/.bashrc` | `dot add ~/.bashrc` |
|
|
19
|
+
| `config commit` / `config push` | ordinary `git` inside `$(dot cd)` |
|
|
20
|
+
| `config status` | `dot status` |
|
|
21
|
+
| `config checkout` on a new machine | `dot init <user>` |
|
|
22
|
+
| `.gitignore` with `*` at `$HOME` | not needed — `$HOME` is not a work tree |
|
|
23
|
+
| `showUntrackedFiles = no` | not needed, same reason |
|
|
24
|
+
| Per-host: branches | `.tmpl` files with `{{ if }}` |
|
|
25
|
+
| Nothing | `dot doctor`, `dot heal`, `dot rollback`, secrets, provisioning |
|
|
26
|
+
|
|
27
|
+
## 1. Inventory and back up
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
alias config='git --git-dir=$HOME/.dotfiles --work-tree=$HOME'
|
|
31
|
+
|
|
32
|
+
config ls-files > ~/bare-inventory.txt
|
|
33
|
+
wc -l ~/bare-inventory.txt
|
|
34
|
+
tar -czf ~/bare-backup-$(date +%F).tar.gz -C "$HOME" -T ~/bare-inventory.txt
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Push first if the repo has a remote — the safest rollback is a clone:
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
config status
|
|
41
|
+
config push
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 2. Note your branch layout
|
|
45
|
+
|
|
46
|
+
Per-host branches are the one thing that needs a design decision. List
|
|
47
|
+
them before you start:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
config branch -a
|
|
51
|
+
config log --oneline --graph --all | head -20
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Every branch becomes conditional blocks in one file. Diff two branches
|
|
55
|
+
now, while the context is fresh:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
config diff main work-laptop -- .bashrc
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 3. Install
|
|
62
|
+
|
|
63
|
+
The bare repo is at `$HOME/.dotfiles`, which is also this project's
|
|
64
|
+
default clone location. The installer detects and refuses to clobber
|
|
65
|
+
it, but move it first to avoid the confusion entirely:
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
mv "$HOME/.dotfiles" "$HOME/.dotfiles.bare.bak"
|
|
69
|
+
alias config='git --git-dir=$HOME/.dotfiles.bare.bak --work-tree=$HOME'
|
|
70
|
+
|
|
71
|
+
bash -c "$(curl -fsSL https://raw.githubusercontent.com/sebastienrousseau/dotfiles/main/install.sh)"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Your files in `$HOME` are untouched by the move — only the git
|
|
75
|
+
metadata directory changed name.
|
|
76
|
+
|
|
77
|
+
## 4. Import
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
while read -r f; do
|
|
81
|
+
[ -e "$HOME/$f" ] && dot add "$HOME/$f"
|
|
82
|
+
done < ~/bare-inventory.txt
|
|
83
|
+
|
|
84
|
+
dot status
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 5. Collapse branches into templates
|
|
88
|
+
|
|
89
|
+
Take the differences you diffed in step 2 and express them as
|
|
90
|
+
conditions in a single `.tmpl`:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
export EDITOR=nvim
|
|
94
|
+
{{ if eq .chezmoi.hostname "work-laptop" }}
|
|
95
|
+
export HTTP_PROXY=http://proxy.corp:3128
|
|
96
|
+
export NPM_CONFIG_REGISTRY=https://nexus.corp/repository/npm/
|
|
97
|
+
{{ end }}
|
|
98
|
+
{{ if eq .chezmoi.os "darwin" }}
|
|
99
|
+
export HOMEBREW_NO_ANALYTICS=1
|
|
100
|
+
{{ end }}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Rendering is testable without applying:
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
chezmoi execute-template < defaults/dot_bashrc.tmpl
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## 6. Apply and verify
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
dot diff
|
|
113
|
+
dot sync
|
|
114
|
+
dot doctor
|
|
115
|
+
|
|
116
|
+
while read -r f; do
|
|
117
|
+
[ -e "$HOME/$f" ] || echo "MISSING: $f"
|
|
118
|
+
done < ~/bare-inventory.txt
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## 7. Clean up
|
|
122
|
+
|
|
123
|
+
```sh
|
|
124
|
+
# Only if you had the $HOME/.gitignore containing '*' trick:
|
|
125
|
+
grep -q '^\*$' "$HOME/.gitignore" 2>/dev/null && $EDITOR "$HOME/.gitignore"
|
|
126
|
+
|
|
127
|
+
# Remove the alias from your shell rc, then, once confident:
|
|
128
|
+
rm -rf "$HOME/.dotfiles.bare.bak"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Do not remove the backup until you have pushed the new source tree
|
|
132
|
+
somewhere and used it for a while.
|
|
133
|
+
|
|
134
|
+
## Rolling back
|
|
135
|
+
|
|
136
|
+
```sh
|
|
137
|
+
bash ~/.dotfiles/scripts/uninstall.sh --force
|
|
138
|
+
mv "$HOME/.dotfiles.bare.bak" "$HOME/.dotfiles"
|
|
139
|
+
git --git-dir=$HOME/.dotfiles --work-tree=$HOME checkout -- .
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Or, if you pushed in step 1, clone the remote bare again — which is
|
|
143
|
+
why step 1 says to push.
|
|
144
|
+
|
|
145
|
+
## What you gain, what you lose
|
|
146
|
+
|
|
147
|
+
**Gain:** templating instead of branch-per-host (the bare-repo
|
|
148
|
+
pattern's real weakness: merging a change across five host branches);
|
|
149
|
+
a CLI with diagnostics and repair; secrets; provisioning hooks;
|
|
150
|
+
multi-shell parity; signed releases.
|
|
151
|
+
|
|
152
|
+
**Lose:** zero dependencies. The bare-repo trick needs nothing but
|
|
153
|
+
git, and that is a genuine virtue — especially on a locked-down host.
|
|
154
|
+
You also lose `$HOME` as a work tree, so `git status` there no longer
|
|
155
|
+
tells you what changed; `dot status` does. And the setup no longer
|
|
156
|
+
fits in a three-line shell alias you can retype from memory.
|