@sebastienrousseau/dotfiles 0.2.507 → 0.2.508

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 CHANGED
@@ -2,6 +2,69 @@
2
2
 
3
3
  This file documents all notable changes to this project.
4
4
 
5
+ ## v0.2.508 — 2026-06-30
6
+
7
+ Makes `dot apply` / `dot update` behave like an OS package-manager update —
8
+ unattended and reliable on macOS — and converts the cross-platform required
9
+ check into an always-runs gate so documentation-only PRs are mergeable.
10
+
11
+ ### Fixed
12
+
13
+ - **`dot apply` / `dot update` run unattended** (#946). They no longer stall on
14
+ chezmoi's "file changed since chezmoi last wrote it" prompt, which could not
15
+ be answered because chezmoi always runs under `gum spin`/captured output (no
16
+ controlling TTY) and aborted with "could not open a new TTY". They now apply
17
+ the canonical source with `--force` by default, like `apt`/system updates;
18
+ local drift to *managed* files yields to the source. Opt back into prompts
19
+ with `DOTFILES_INTERACTIVE_APPLY=1`, and keep machine-local tweaks in the
20
+ unmanaged `~/.zshrc.local` or `~/.config/zsh/rc.d.local/*.zsh`.
21
+ - **macOS apply no-op** (#946). The concurrency lock used `flock(1)`, which does
22
+ not exist on macOS — `! flock` took the "already running" branch and made
23
+ `dot apply` exit 0 without applying anything. It now falls back to an atomic
24
+ `mkdir` lock when `flock` is absent (portable to macOS/BSD). The optional
25
+ AI-provider installer menu is also gated on real interactivity (TTY + not CI).
26
+
27
+ ### Changed
28
+
29
+ - **CI required check** (#944). `Test on ubuntu-latest` (path-filtered, so it
30
+ never ran on docs-only PRs and left them unmergeable) is replaced by an
31
+ always-runs `Cross-Platform Tests` gate that reports success when the OS
32
+ matrix is skipped and failure when it fails.
33
+
34
+ ## v0.2.507 — 2026-06-30
35
+
36
+ This release ships the **`dot ai` cockpit** — an interactive Bubble Tea TUI for
37
+ the 18-agent AI fleet with a local Claude gateway — grows the bundled theme
38
+ collection from 150 to 173, and repairs the AI provider install path
39
+ end-to-end.
40
+
41
+ ### Added
42
+
43
+ - **`dot ai` cockpit** — bare `dot ai` now opens an interactive Bubble Tea TUI
44
+ to browse, launch, install, and monitor the AI fleet, backed by a local Claude
45
+ gateway and an 18-agent provider roster (#936).
46
+ - **Floral theme collection** — grew the bundled themes from 150 to 173 (#940).
47
+
48
+ ### Fixed
49
+
50
+ - **AI installs (`dot ai install`):** three reproducible failures (#942).
51
+ - *Duplicate banner* — the cockpit shells out to `dot ai install <tool>` once
52
+ per tool, and each subprocess reprinted the full command banner. `dotExec`
53
+ now sets `DOT_AI_RAW=1`, matching the streaming path.
54
+ - *amp* — `@sourcegraph/amp` publishes only prerelease-tagged npm versions,
55
+ which mise filters out (`@latest` resolves to nothing). Routed to amp's
56
+ native installer, pre-resolving `AMP_VERSION` to dodge an upstream bug where
57
+ amp's own version fetch builds a malformed checksum URL.
58
+ - *Cursor* — `cursor.com/install` User-Agent-sniffs and served marketing HTML
59
+ to curl (failing the shebang check); now sends a browser UA to fetch the
60
+ real install script.
61
+ - Also unified the `dot ai tools` fallback install loop (amp/cursor/goose/grok
62
+ were silently skipped there) and added an `ai` command summary line.
63
+ - **CI / release reliability:** theme nil-guard and shfmt-absent skip (#939);
64
+ repinned a stale reusable shell-lint workflow and hardened pin-bumping (#937);
65
+ the distribute workflows now poll for the release asset before consuming it
66
+ (#931).
67
+
5
68
  ## v0.2.505 — 2026-06-04
6
69
 
7
70
  Claude Code is no longer installed through mise/npm. npm 11 silently drops
package/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  <p align="center">
12
12
  <a href="https://github.com/sebastienrousseau/dotfiles/actions"><img src="https://img.shields.io/github/actions/workflow/status/sebastienrousseau/dotfiles/ci.yml?style=for-the-badge&logo=githubactions&logoColor=white" alt="Build" /></a>
13
- <a href="https://github.com/sebastienrousseau/dotfiles/releases/latest"><img src="https://img.shields.io/badge/Version-v0.2.507-blue?style=for-the-badge&logo=semanticrelease&logoColor=white" alt="Version" /></a>
13
+ <a href="https://github.com/sebastienrousseau/dotfiles/releases/latest"><img src="https://img.shields.io/badge/Version-v0.2.508-blue?style=for-the-badge&logo=semanticrelease&logoColor=white" alt="Version" /></a>
14
14
  <a href="https://github.com/sebastienrousseau/dotfiles/releases"><img src="https://img.shields.io/github/downloads/sebastienrousseau/dotfiles/total?style=for-the-badge&logo=github&logoColor=white" alt="Downloads" /></a>
15
15
  <a href="https://codespaces.new/sebastienrousseau/dotfiles"><img src="https://img.shields.io/badge/Open%20in-Codespaces-blue?style=for-the-badge&logo=github&logoColor=white" alt="Open in GitHub Codespaces" /></a>
16
16
  <a href="https://scorecard.dev/viewer/?uri=github.com/sebastienrousseau/dotfiles"><img src="https://img.shields.io/ossf-scorecard/github.com/sebastienrousseau/dotfiles?style=for-the-badge&logo=linuxfoundation&logoColor=white&label=OpenSSF%20Scorecard" alt="OpenSSF Scorecard" /></a>
@@ -52,7 +52,7 @@
52
52
 
53
53
  ```bash
54
54
  curl -fsSL -o /tmp/dotfiles-install.sh \
55
- https://raw.githubusercontent.com/sebastienrousseau/dotfiles/v0.2.507/install.sh
55
+ https://raw.githubusercontent.com/sebastienrousseau/dotfiles/v0.2.508/install.sh
56
56
  echo "d5a04c5e2813a93a63c8ecce9655cf3d107f6068862c6eba84a92cf22f801c7e /tmp/dotfiles-install.sh" \
57
57
  | shasum -a 256 -c
58
58
  bash /tmp/dotfiles-install.sh
package/docs/COPYRIGHT CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * 🅳🅾🆃🅵🅸🅻🅴🆂 (v0.2.507) - <https://github.com/sebastienrousseau/dotfiles>
2
+ * 🅳🅾🆃🅵🅸🅻🅴🆂 (v0.2.508) - <https://github.com/sebastienrousseau/dotfiles>
3
3
  * Made With ❤️ in London, United Kingdom
4
4
  * Designed by
5
5
  * Copyright (c) 2015-2026. All rights reserved.
package/docs/index.md CHANGED
@@ -7,7 +7,7 @@ render_with_liquid: false
7
7
  Cross-platform, signed, local-first dotfiles for macOS, Linux, and WSL.
8
8
 
9
9
  [![Build](https://img.shields.io/github/actions/workflow/status/sebastienrousseau/dotfiles/ci.yml?style=for-the-badge&logo=github)](https://github.com/sebastienrousseau/dotfiles/actions)
10
- [![Version](https://img.shields.io/badge/Version-v0.2.507-blue?style=for-the-badge)](https://github.com/sebastienrousseau/dotfiles/releases/tag/v0.2.507)
10
+ [![Version](https://img.shields.io/badge/Version-v0.2.508-blue?style=for-the-badge)](https://github.com/sebastienrousseau/dotfiles/releases/tag/v0.2.508)
11
11
  [![Downloads](https://img.shields.io/github/downloads/sebastienrousseau/dotfiles/total?style=for-the-badge)](https://github.com/sebastienrousseau/dotfiles/releases)
12
12
 
13
13
  This site is published from the `docs/` directory on `master` and tracks the current workstation baseline, operational guidance, and security material for the repository.
@@ -38,6 +38,6 @@ This site is published from the `docs/` directory on `master` and tracks the cur
38
38
 
39
39
  ## Current Release
40
40
 
41
- - Current tagged release: [`v0.2.507`](https://github.com/sebastienrousseau/dotfiles/releases/tag/v0.2.507)
41
+ - Current tagged release: [`v0.2.508`](https://github.com/sebastienrousseau/dotfiles/releases/tag/v0.2.508)
42
42
  - Latest release feed: [GitHub releases](https://github.com/sebastienrousseau/dotfiles/releases/latest)
43
43
  - Source repository: [sebastienrousseau/dotfiles](https://github.com/sebastienrousseau/dotfiles)
@@ -4,7 +4,7 @@ render_with_liquid: false
4
4
 
5
5
  # Introduction
6
6
 
7
- This manual describes `.dotfiles` v0.2.507 — a trusted agent workstation baseline for macOS, Linux, and WSL.
7
+ This manual describes `.dotfiles` v0.2.508 — 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
 
package/install.sh CHANGED
@@ -60,7 +60,7 @@ show_help() {
60
60
  Usage: install.sh [version] [options]
61
61
 
62
62
  Arguments:
63
- version The version (tag or branch) to install (default: v0.2.507)
63
+ version The version (tag or branch) to install (default: v0.2.508)
64
64
 
65
65
  Options:
66
66
  --help Show this help message
@@ -76,7 +76,7 @@ EOF
76
76
  }
77
77
 
78
78
  main() {
79
- local version="v0.2.507"
79
+ local version="v0.2.508"
80
80
  local version_set=0
81
81
  local minimal=0
82
82
  local provision="${DOTFILES_PROVISION:-0}"
@@ -106,7 +106,7 @@ main() {
106
106
  # like `foobar` doesn't trigger a 30s+ network download attempt.
107
107
  # Caught by the install.sh fuzz harness (#881).
108
108
  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)."
109
+ error "Unrecognized positional argument '$arg' — expected a semver version (e.g. v0.2.508)."
110
110
  fi
111
111
  version="$arg"
112
112
  version_set=1
@@ -351,7 +351,7 @@ main() {
351
351
  # 6. Initialize & Apply
352
352
  step "Applying Configuration..."
353
353
 
354
- # ── Auto-migration for v0.2.507 reorg ─────────────────────────────────
354
+ # ── Auto-migration for v0.2.508 reorg ─────────────────────────────────
355
355
  # If the user is upgrading from a pre-0.2.503 install, run the
356
356
  # migration script BEFORE `chezmoi apply` so the reorg's source-
357
357
  # path moves don't cause chezmoi to delete deployed files.
@@ -360,7 +360,7 @@ main() {
360
360
  for migrate_src in "$SOURCE_DIR" "$LEGACY_SOURCE_DIR"; do
361
361
  migrate_script="$migrate_src/install/migrate/migrate-v0_2-to-v0_2_503.sh"
362
362
  if [[ -x "$migrate_script" ]]; then
363
- echo " Running v0.2.507 migration (idempotent; safe on fresh installs)..."
363
+ echo " Running v0.2.508 migration (idempotent; safe on fresh installs)..."
364
364
  "$migrate_script" || echo " migration exited non-zero — continuing apply"
365
365
  break
366
366
  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.508",
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": {
@@ -141,6 +141,6 @@ if [[ $FAILED -eq 1 ]]; then
141
141
  printf '%b\\n' " (Use --no-verify to bypass if absolutely necessary)"
142
142
  exit 1
143
143
  else
144
- printf '%b\n' "${GREEN}${BOLD}✅ Audit passed.${NC} v0.2.507 standards maintained."
144
+ printf '%b\n' "${GREEN}${BOLD}✅ Audit passed.${NC} v0.2.508 standards maintained."
145
145
  exit 0
146
146
  fi
@@ -19,9 +19,11 @@ export DOT_COMMAND="apply"
19
19
  # (macOS) expanding an empty array under `set -u` is an "unbound
20
20
  # variable" error, which would fire on every clean `dot sync`.
21
21
  _TMPFILES=()
22
+ _LOCK_DIR=""
22
23
  cleanup() {
23
24
  set +u
24
25
  rm -f "${_TMPFILES[@]}" 2>/dev/null
26
+ [[ -n "$_LOCK_DIR" ]] && rmdir "$_LOCK_DIR" 2>/dev/null
25
27
  set -u
26
28
  }
27
29
  trap cleanup EXIT
@@ -39,7 +41,9 @@ Environment Variables:
39
41
  DOTFILES_CHEZMOI_APPLY_FLAGS Extra flags for chezmoi apply
40
42
  DOTFILES_CHEZMOI_VERBOSE=1 Enable verbose output
41
43
  DOTFILES_CHEZMOI_KEEP_GOING=1 Continue on errors
42
- DOTFILES_NONINTERACTIVE=1 Force non-interactive mode
44
+ DOTFILES_NONINTERACTIVE=1 Skip interactive menus (AI provider installer)
45
+ DOTFILES_INTERACTIVE_APPLY=1 Re-enable chezmoi overwrite prompts
46
+ (apply is unattended/--force by default)
43
47
  DOTFILES_ALIAS_STRICT_MODE=1 Run alias governance checks
44
48
  DOTFILES_SNAPSHOT_ON_APPLY=1 Create baseline snapshot (default)
45
49
  DOTFILES_POST_APPLY_REPAIR=1 Run post-apply repairs (default)
@@ -67,25 +71,55 @@ fi
67
71
  has_flag() {
68
72
  local needle="$1"
69
73
  local arg
74
+ # Guard the expansion: on bash 3.2 (macOS) iterating an empty array
75
+ # under `set -u` is an unbound-variable error.
76
+ [[ ${#args[@]} -eq 0 ]] && return 1
70
77
  for arg in "${args[@]}"; do
71
78
  [[ "$arg" == "$needle" ]] && return 0
72
79
  done
73
80
  return 1
74
81
  }
75
82
 
76
- # In non-interactive runs, prevent TTY prompts from blocking apply.
77
- if [[ "${DOTFILES_NONINTERACTIVE:-0}" == "1" ]] && ! has_flag "--force"; then
83
+ # Apply unattended by default, like an OS package manager. chezmoi is
84
+ # always run below under `gum spin` or with its output captured, so it
85
+ # never has a controlling TTY; its "<file> has changed since chezmoi last
86
+ # wrote it" confirmation prompt therefore cannot be answered and aborts
87
+ # the run with "could not open a new TTY". Passing --force applies the
88
+ # canonical source without prompting, so local drift to *managed* files
89
+ # yields to the source — exactly how `apt`/system updates behave. Keep
90
+ # machine-specific tweaks in the unmanaged ~/.zshrc.local or
91
+ # ~/.config/zsh/rc.d.local/*.zsh, which chezmoi never overwrites.
92
+ # Opt back into chezmoi's prompts with DOTFILES_INTERACTIVE_APPLY=1.
93
+ if [[ "${DOTFILES_INTERACTIVE_APPLY:-0}" != "1" ]] && ! has_flag "--force"; then
78
94
  args+=("--force")
79
95
  fi
80
96
 
97
+ # Whether interactive menus (the optional AI-provider installer below) may
98
+ # prompt. Suppressed without a TTY, under CI, or when non-interactive is
99
+ # requested — so unattended runs never hang waiting on input.
100
+ INTERACTIVE=1
101
+ if [[ "${DOTFILES_NONINTERACTIVE:-0}" == "1" ]] || [[ -n "${CI:-}" ]] || [[ ! -t 0 ]] || [[ ! -t 1 ]]; then
102
+ INTERACTIVE=0
103
+ fi
104
+
81
105
  ui_init
82
106
 
83
- # Prevent concurrent execution
84
- LOCK_FILE="${XDG_RUNTIME_DIR:-/tmp}/dotfiles-chezmoi-apply.lock"
85
- exec 9>"$LOCK_FILE"
86
- if ! flock -n 9; then
107
+ # Prevent concurrent execution. flock(1) is Linux-only — it does not exist
108
+ # on macOS, where `! flock` previously took the "already running" branch and
109
+ # made `dot apply` a silent no-op. Use flock where present, otherwise fall
110
+ # back to an atomic mkdir lock (portable to macOS/BSD).
111
+ _lock_base="${XDG_RUNTIME_DIR:-${TMPDIR:-/tmp}}/dotfiles-chezmoi-apply"
112
+ if command -v flock >/dev/null 2>&1; then
113
+ exec 9>"${_lock_base}.lock"
114
+ if ! flock -n 9; then
115
+ ui_warn "Already running" "Another instance is active"
116
+ exit 0
117
+ fi
118
+ elif ! mkdir "${_lock_base}.lock.d" 2>/dev/null; then
87
119
  ui_warn "Already running" "Another instance is active"
88
120
  exit 0
121
+ else
122
+ _LOCK_DIR="${_lock_base}.lock.d" # removed by cleanup() on exit
89
123
  fi
90
124
 
91
125
  run_step() {
@@ -187,7 +221,7 @@ for _entry in "${_AI_PROVIDERS[@]}"; do
187
221
  fi
188
222
  done
189
223
 
190
- if [[ ${#_ai_missing[@]} -gt 0 ]] && [[ "${DOTFILES_NONINTERACTIVE:-0}" != "1" ]]; then
224
+ if [[ ${#_ai_missing[@]} -gt 0 ]] && [[ "$INTERACTIVE" == "1" ]]; then
191
225
  if command -v mise &>/dev/null; then
192
226
  echo ""
193
227
  _ai_install_action=""
@@ -14,6 +14,20 @@ if [[ "${DOTFILES_CHEZMOI_VERBOSE:-0}" = "1" ]]; then
14
14
  args+=("--verbose")
15
15
  fi
16
16
 
17
+ # Apply unattended by default (see chezmoi-apply.sh). `chezmoi update` runs
18
+ # `apply` internally, so without --force it blocks on the "<file> has
19
+ # changed since chezmoi last wrote it" prompt — and `dot update` is often
20
+ # run from cron/CI/--async with no TTY, where that prompt aborts the run.
21
+ # --force makes updates land like an OS package-manager update; opt back
22
+ # into prompting with DOTFILES_INTERACTIVE_APPLY=1.
23
+ if [[ "${DOTFILES_INTERACTIVE_APPLY:-0}" != "1" ]]; then
24
+ _has_force=0
25
+ if [[ ${#args[@]} -gt 0 ]]; then
26
+ for _a in "${args[@]}"; do [[ "$_a" == "--force" ]] && _has_force=1; done
27
+ fi
28
+ [[ "$_has_force" == "0" ]] && args+=("--force")
29
+ fi
30
+
17
31
  ASYNC=false
18
32
  if [[ "${DOTFILES_ASYNC_UPDATE:-0}" = "1" ]]; then
19
33
  ASYNC=true