@sebastienrousseau/dotfiles 0.2.505 → 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.
@@ -14,43 +14,51 @@ ui_header "Universal AI Toolchain Setup"
14
14
  setup_tool() {
15
15
  local name="$1"
16
16
  local cmd="$2"
17
- local auth_cmd="$3"
17
+ shift 2
18
+ # Remaining args are the auth command — passed as an array to avoid eval.
19
+ local -a auth_argv=("$@")
18
20
 
19
21
  ui_section "Setting up $name"
20
22
  if command -v "$cmd" >/dev/null 2>&1; then
21
23
  ui_info "Tool found, initiating authentication..."
22
- eval "$auth_cmd" || ui_warn "$name" "Setup/Auth skipped or failed."
24
+ "${auth_argv[@]}" || ui_warn "$name" "Setup/Auth skipped or failed."
23
25
  else
24
26
  ui_err "$name" "Binary not found. Run 'dot apply' or install via mise first."
25
27
  fi
26
28
  }
27
29
 
28
30
  # 1. Claude
29
- setup_tool "Claude CLI" "claude" "claude --version" # Claude handles auth via web flow or env
31
+ setup_tool "Claude CLI" "claude" claude --version # Claude handles auth via web flow or env
30
32
 
31
- # 2. Gemini
32
- setup_tool "Gemini CLI" "gemini" "gemini info"
33
+ # 2. Antigravity CLI
34
+ setup_tool "Antigravity CLI" "agy" agy --version
33
35
 
34
- # 3. Copilot
35
- setup_tool "Copilot CLI" "copilot" "copilot --version"
36
+ # 3. Codex
37
+ setup_tool "Codex CLI" "codex" codex --version
36
38
 
37
- # 4. Kiro
38
- setup_tool "Kiro CLI" "kiro-cli" "kiro-cli auth login"
39
+ # 4. Copilot
40
+ setup_tool "Copilot CLI" "copilot" copilot --version
39
41
 
40
- # 6. Aider
41
- setup_tool "Aider" "aider" "aider --version"
42
+ # 5. Goose
43
+ setup_tool "Goose" "goose" goose --version
44
+
45
+ # 6. Kiro
46
+ setup_tool "Kiro CLI" "kiro-cli" kiro-cli auth login
47
+
48
+ # 7. Aider
49
+ setup_tool "Aider" "aider" aider --version
42
50
 
43
51
  # 7. Autohand Code
44
- setup_tool "Autohand Code" "autohand" "autohand --version"
52
+ setup_tool "Autohand Code" "autohand" autohand --version
45
53
 
46
54
  # 8. Mistral Vibe
47
- setup_tool "Mistral Vibe" "vibe" "vibe --version"
55
+ setup_tool "Mistral Vibe" "vibe" vibe --version
48
56
 
49
57
  # 9. Qwen Code
50
- setup_tool "Qwen Code" "qwen" "qwen --version"
58
+ setup_tool "Qwen Code" "qwen" qwen --version
51
59
 
52
60
  # 10. ZAI
53
- setup_tool "ZAI" "zai" "zai --version"
61
+ setup_tool "ZAI" "zai" zai --version
54
62
 
55
63
  ui_header "AI Setup Complete"
56
64
  ui_info "All tools are ready. Use 'dot ai' to check status."
@@ -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() {
@@ -161,8 +195,10 @@ ui_header "AI provider CLI checks (optional)"
161
195
  # binary|mise_package|label (claude uses the native installer, not mise)
162
196
  _AI_PROVIDERS=(
163
197
  "claude|native|Claude Code"
198
+ "codex|npm:@openai/codex|Codex CLI"
164
199
  "copilot|npm:@github/copilot|Copilot CLI"
165
- "gemini|npm:@google/gemini-cli|Gemini CLI"
200
+ "goose|native|Goose"
201
+ "agy|native|Antigravity CLI"
166
202
  "sgpt|pipx:shell-gpt|Shell-GPT"
167
203
  "ollama|aqua:ollama/ollama|Ollama"
168
204
  "opencode|npm:opencode-ai|OpenCode"
@@ -185,7 +221,7 @@ for _entry in "${_AI_PROVIDERS[@]}"; do
185
221
  fi
186
222
  done
187
223
 
188
- if [[ ${#_ai_missing[@]} -gt 0 ]] && [[ "${DOTFILES_NONINTERACTIVE:-0}" != "1" ]]; then
224
+ if [[ ${#_ai_missing[@]} -gt 0 ]] && [[ "$INTERACTIVE" == "1" ]]; then
189
225
  if command -v mise &>/dev/null; then
190
226
  echo ""
191
227
  _ai_install_action=""
@@ -232,6 +268,14 @@ if [[ ${#_ai_missing[@]} -gt 0 ]] && [[ "${DOTFILES_NONINTERACTIVE:-0}" != "1" ]
232
268
  install_claude_native "$_label"
233
269
  continue
234
270
  fi
271
+ if [[ "$_bin" == "goose" ]]; then
272
+ install_goose_native "$_label"
273
+ continue
274
+ fi
275
+ if [[ "$_bin" == "agy" ]]; then
276
+ install_agy_native "$_label"
277
+ continue
278
+ fi
235
279
  if command -v gum &>/dev/null; then
236
280
  if gum spin --spinner dot --title "Installing $_label ($_pkg)" -- \
237
281
  mise use -g "$_pkg@latest" 2>&1; then
@@ -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
@@ -284,7 +284,7 @@ $drift
284
284
 
285
285
  Analyze why the environment may have reached a state requiring rollback and suggest architectural hardening steps."
286
286
 
287
- dot cl --pattern hardener "$ai_prompt" || true
287
+ dot ai claude --style hardener "$ai_prompt" || true
288
288
  fi
289
289
  fi
290
290
  }
@@ -54,7 +54,7 @@ check_dot_command_docs() {
54
54
  check_ai_provider_docs() {
55
55
  local provider=""
56
56
 
57
- for provider in cl copilot gemini kiro sgpt ollama opencode aider; do
57
+ for provider in cl copilot agy kiro sgpt ollama opencode aider; do
58
58
  record_doc_check "dot $provider in AI.md" "\`dot $provider\`" "$AI_DOC"
59
59
  done
60
60
  }
@@ -196,12 +196,12 @@ system_wallpaper_for_theme() {
196
196
  local sys_wp=""
197
197
  case "$family" in
198
198
  "macos - sonoma") sys_wp="$SYS_MAC/Sonoma.heic" ;;
199
- "macos - blue") sys_wp="$SYS_MAC/Mac Blue.heic" ;;
200
- "macos - pink") sys_wp="$SYS_MAC/Mac Pink.heic" ;;
199
+ "macos - blue") sys_wp="$SYS_MAC/Mac Blue.heic" ;;
200
+ "macos - pink") sys_wp="$SYS_MAC/Mac Pink.heic" ;;
201
201
  "macos - purple") sys_wp="$SYS_MAC/Mac Purple.heic" ;;
202
202
  "macos - yellow") sys_wp="$SYS_MAC/Mac Yellow.heic" ;;
203
203
  "macos - orange") sys_wp="$SYS_MAC/iMac Orange.heic" ;;
204
- "macos - green") sys_wp="$SYS_MAC/iMac Green.heic" ;;
204
+ "macos - green") sys_wp="$SYS_MAC/iMac Green.heic" ;;
205
205
  "macos - silver") sys_wp="$SYS_MAC/iMac Silver.heic" ;;
206
206
  esac
207
207
  if [[ -n "$sys_wp" && -f "$sys_wp" ]]; then