aidevops 3.13.79 → 3.13.81

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/VERSION CHANGED
@@ -1 +1 @@
1
- 3.13.79
1
+ 3.13.81
package/aidevops.sh CHANGED
@@ -5,7 +5,7 @@
5
5
  # AI DevOps Framework CLI
6
6
  # Usage: aidevops <command> [options]
7
7
  #
8
- # Version: 3.13.79
8
+ # Version: 3.13.81
9
9
 
10
10
  set -euo pipefail
11
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aidevops",
3
- "version": "3.13.79",
3
+ "version": "3.13.81",
4
4
  "description": "AI DevOps Framework - AI-assisted development workflows, code quality, and deployment automation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -143,7 +143,12 @@ _deploy_agents_copy() {
143
143
  for pns in "$@"; do
144
144
  rsync_excludes+=("--exclude=${pns}/")
145
145
  done
146
- if rsync -a "${rsync_excludes[@]}" "$source_dir/" "$target_dir/"; then
146
+ local rsync_timeout="${AIDEVOPS_RSYNC_TIMEOUT:-120}"
147
+ [[ "$rsync_timeout" =~ ^[0-9]+$ && "$rsync_timeout" -gt 0 ]] || rsync_timeout=120
148
+ # GH#22086: bound rsync I/O stalls so setup.sh --non-interactive can
149
+ # unwind via its EXIT trap instead of leaving a long-running setup owner
150
+ # and stale setup-noninteractive.lock.d behind.
151
+ if rsync -a --timeout="$rsync_timeout" "${rsync_excludes[@]}" "$source_dir/" "$target_dir/"; then
147
152
  deploy_ok=true
148
153
  fi
149
154
  else
@@ -304,6 +304,36 @@ cleanup_stale_bun_opencode() {
304
304
  return 0
305
305
  }
306
306
 
307
+ # Register the setup caller's linked worktree as owned before setup performs
308
+ # deployment work that may restart the pulse or trigger cleanup routines.
309
+ protect_current_setup_worktree() {
310
+ command -v git &>/dev/null || return 0
311
+ declare -F register_worktree >/dev/null 2>&1 || return 0
312
+
313
+ local current_root=""
314
+ local git_dir=""
315
+ local common_dir=""
316
+ local branch=""
317
+
318
+ current_root=$(git -C "${INSTALL_DIR:-.}" rev-parse --show-toplevel 2>/dev/null || true)
319
+ [[ -n "$current_root" ]] || return 0
320
+ current_root=$(cd "$current_root" 2>/dev/null && pwd -P) || return 0
321
+
322
+ git_dir=$(git -C "$current_root" rev-parse --git-dir 2>/dev/null) || return 0
323
+ common_dir=$(git -C "$current_root" rev-parse --git-common-dir 2>/dev/null) || return 0
324
+ [[ "$git_dir" = /* ]] || git_dir="$current_root/$git_dir"
325
+ [[ "$common_dir" = /* ]] || common_dir="$current_root/$common_dir"
326
+ git_dir=$(cd "$git_dir" 2>/dev/null && pwd -P) || git_dir=""
327
+ common_dir=$(cd "$common_dir" 2>/dev/null && pwd -P) || common_dir=""
328
+ [[ -n "$git_dir" && -n "$common_dir" && "$git_dir" != "$common_dir" ]] || return 0
329
+
330
+ branch=$(git -C "$current_root" rev-parse --abbrev-ref HEAD 2>/dev/null || true)
331
+ [[ -n "$branch" ]] || branch="HEAD"
332
+ register_worktree "$current_root" "$branch" --task "setup-noninteractive" --session "setup:${OPENCODE_SESSION_ID:-${CLAUDE_SESSION_ID:-manual}}" >/dev/null 2>&1 || true
333
+ print_info "Protected current setup worktree from cleanup: $current_root"
334
+ return 0
335
+ }
336
+
307
337
  # t1929: Remove stale contributor/legacy health issue cache files and close
308
338
  # the corresponding GitHub issues. One-time migration — the root cause
309
339
  # (API failure in _get_runner_role defaulting to "contributor") is fixed
@@ -331,10 +361,20 @@ cleanup_worktree_entries_in_repos_json() {
331
361
  command -v git &>/dev/null || return 0
332
362
 
333
363
  local stale_paths=()
334
- local path git_dir common_dir
364
+ local skipped_current_paths=()
365
+ local current_worktree=""
366
+ local current_physical_dir=""
367
+ local path git_dir common_dir resolved_path
368
+
369
+ current_physical_dir=$(pwd -P 2>/dev/null || pwd)
370
+ current_worktree=$(git rev-parse --show-toplevel 2>/dev/null || true)
371
+ if [[ -n "$current_worktree" ]]; then
372
+ current_worktree=$(cd "$current_worktree" 2>/dev/null && pwd -P) || current_worktree=""
373
+ fi
335
374
 
336
375
  while IFS= read -r path; do
337
376
  [[ -n "$path" && -d "$path" ]] || continue
377
+ resolved_path=$(cd "$path" 2>/dev/null && pwd -P) || resolved_path=""
338
378
  git_dir=$(git -C "$path" rev-parse --git-dir 2>/dev/null) || continue
339
379
  common_dir=$(git -C "$path" rev-parse --git-common-dir 2>/dev/null) || continue
340
380
  # Normalise to absolute paths for comparison.
@@ -343,6 +383,11 @@ cleanup_worktree_entries_in_repos_json() {
343
383
  git_dir=$(cd "$git_dir" 2>/dev/null && pwd -P) || git_dir=""
344
384
  common_dir=$(cd "$common_dir" 2>/dev/null && pwd -P) || common_dir=""
345
385
  if [[ -n "$git_dir" && -n "$common_dir" && "$git_dir" != "$common_dir" ]]; then
386
+ if [[ -n "$current_worktree" && -n "$resolved_path" && "$resolved_path" == "$current_worktree" ]] \
387
+ || [[ -n "$resolved_path" && "$current_physical_dir" == "$resolved_path"/* ]]; then
388
+ skipped_current_paths+=("$path")
389
+ continue
390
+ fi
346
391
  stale_paths+=("$path")
347
392
  fi
348
393
  done < <(jq -r '.initialized_repos[].path // empty' "$repos_json" 2>/dev/null)
@@ -361,6 +406,16 @@ cleanup_worktree_entries_in_repos_json() {
361
406
  done
362
407
  fi
363
408
 
409
+ if [[ ${#skipped_current_paths[@]} -gt 0 ]]; then
410
+ print_warning "Skipped ${#skipped_current_paths[@]} active current worktree entry/entries in repos.json (t2250):"
411
+ local skipped_path
412
+ for skipped_path in "${skipped_current_paths[@]}"; do
413
+ print_warning " - $skipped_path"
414
+ done
415
+ print_warning "Run setup.sh from the canonical worktree later to finish the one-shot cleanup."
416
+ return 0
417
+ fi
418
+
364
419
  mkdir -p "$(dirname "$flag_file")"
365
420
  date -u +"%Y-%m-%dT%H:%M:%SZ" >"$flag_file"
366
421
  return 0
@@ -104,7 +104,7 @@ _install_cw_launchd() {
104
104
  <key>EnvironmentVariables</key>
105
105
  <dict>
106
106
  <key>PATH</key>
107
- <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
107
+ <string>$(aidevops_launchd_sanitized_path)</string>
108
108
  <key>HOME</key>
109
109
  <string>${_xml_cw_home}</string>
110
110
  </dict>
@@ -229,7 +229,7 @@ _install_complexity_scan_launchd() {
229
229
  <key>EnvironmentVariables</key>
230
230
  <dict>
231
231
  <key>PATH</key>
232
- <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
232
+ <string>$(aidevops_launchd_sanitized_path)</string>
233
233
  <key>HOME</key>
234
234
  <string>${_xml_cs_home}</string>
235
235
  </dict>
@@ -363,7 +363,7 @@ _install_pulse_merge_routine_launchd() {
363
363
  <key>EnvironmentVariables</key>
364
364
  <dict>
365
365
  <key>PATH</key>
366
- <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
366
+ <string>$(aidevops_launchd_sanitized_path)</string>
367
367
  <key>HOME</key>
368
368
  <string>${_xml_pmr_home}</string>
369
369
  </dict>
@@ -534,7 +534,7 @@ _install_profile_readme_launchd() {
534
534
  <key>EnvironmentVariables</key>
535
535
  <dict>
536
536
  <key>PATH</key>
537
- <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
537
+ <string>$(aidevops_launchd_sanitized_path)</string>
538
538
  <key>HOME</key>
539
539
  <string>${_xml_pr_home}</string>
540
540
  </dict>
@@ -740,7 +740,7 @@ _install_token_refresh_launchd() {
740
740
  <key>EnvironmentVariables</key>
741
741
  <dict>
742
742
  <key>PATH</key>
743
- <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
743
+ <string>$(aidevops_launchd_sanitized_path)</string>
744
744
  <key>HOME</key>
745
745
  <string>${_xml_tr_home}</string>
746
746
  </dict>
@@ -992,7 +992,7 @@ _install_peer_productivity_monitor_launchd() {
992
992
  <key>EnvironmentVariables</key>
993
993
  <dict>
994
994
  <key>PATH</key>
995
- <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
995
+ <string>$(aidevops_launchd_sanitized_path)</string>
996
996
  <key>HOME</key>
997
997
  <string>${_xml_ppm_home}</string>
998
998
  </dict>
@@ -693,7 +693,7 @@ _generate_pulse_plist_content() {
693
693
  # Use neutral workspace path for PULSE_DIR so supervisor sessions
694
694
  # are not associated with any specific managed repo (GH#5136).
695
695
  _xml_pulse_dir=$(_xml_escape "${HOME}/.aidevops/.agent-workspace")
696
- _xml_path=$(_xml_escape "$PATH")
696
+ _xml_path=$(_xml_escape "$(aidevops_launchd_sanitized_path "$PATH")")
697
697
 
698
698
  local _headless_xml_env
699
699
  _headless_xml_env=$(_build_pulse_headless_env_xml)
@@ -842,7 +842,7 @@ _generate_pulse_watchdog_plist_content() {
842
842
  _xml_tick=$(_xml_escape "$tick_script")
843
843
  _xml_bash=$(_xml_escape "$bash_bin")
844
844
  _xml_home=$(_xml_escape "$HOME")
845
- _xml_path=$(_xml_escape "$PATH")
845
+ _xml_path=$(_xml_escape "$(aidevops_launchd_sanitized_path "$PATH")")
846
846
 
847
847
  cat <<PLIST
848
848
  <?xml version="1.0" encoding="UTF-8"?>
@@ -31,6 +31,32 @@ CRON_HOURLY="0 * * * *"
31
31
  # Kept DRY for the same reason as CRON_HOURLY.
32
32
  CRON_EVERY_MINUTE="* * * * *"
33
33
 
34
+ # Direct unit tests source this module without setup.sh's later
35
+ # shared-constants.sh load. Provide a small fallback; the shared helper
36
+ # overwrites this when setup.sh sources shared-constants.sh.
37
+ if ! declare -F aidevops_launchd_sanitized_path >/dev/null 2>&1; then
38
+ aidevops_launchd_sanitized_path() {
39
+ local input_path="${1:-${PATH:-}}"
40
+ local default_path="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
41
+ local result=""
42
+ local seen=""
43
+ local dir=""
44
+ local old_ifs="$IFS"
45
+ IFS=':'
46
+ for dir in $default_path:$input_path; do
47
+ [[ -n "$dir" && -d "$dir" ]] || continue
48
+ case ":$seen:" in
49
+ *":${dir}:"*) continue ;;
50
+ esac
51
+ seen="${seen:+${seen}:}${dir}"
52
+ result="${result:+${result}:}${dir}"
53
+ done
54
+ IFS="$old_ifs"
55
+ printf '%s' "$result"
56
+ return 0
57
+ }
58
+ fi
59
+
34
60
  # Shell safety baseline
35
61
  set -Eeuo pipefail
36
62
  IFS=$'\n\t'
@@ -87,7 +113,7 @@ setup_stats_wrapper() {
87
113
  local _xml_stats_script _xml_stats_home _xml_stats_path
88
114
  _xml_stats_script=$(_xml_escape "$stats_script")
89
115
  _xml_stats_home=$(_xml_escape "$HOME")
90
- _xml_stats_path=$(_xml_escape "$PATH")
116
+ _xml_stats_path=$(_xml_escape "$(aidevops_launchd_sanitized_path "$PATH")")
91
117
  local stats_plist_content
92
118
  stats_plist_content=$(
93
119
  cat <<PLIST
@@ -189,7 +215,7 @@ setup_failure_miner() {
189
215
  local _xml_miner_script _xml_miner_home _xml_miner_path _xml_miner_log
190
216
  _xml_miner_script=$(_xml_escape "$miner_script")
191
217
  _xml_miner_home=$(_xml_escape "$HOME")
192
- _xml_miner_path=$(_xml_escape "/bin:/usr/bin:/usr/local/bin:/opt/homebrew/bin:${PATH}")
218
+ _xml_miner_path=$(_xml_escape "$(aidevops_launchd_sanitized_path "/bin:/usr/bin:/usr/local/bin:/opt/homebrew/bin:${PATH}")")
193
219
  _xml_miner_log=$(_xml_escape "$miner_log")
194
220
 
195
221
  local miner_plist_content
@@ -287,7 +313,7 @@ setup_process_guard() {
287
313
  local _xml_guard_script _xml_guard_home _xml_guard_path
288
314
  _xml_guard_script=$(_xml_escape "$guard_script")
289
315
  _xml_guard_home=$(_xml_escape "$HOME")
290
- _xml_guard_path=$(_xml_escape "$PATH")
316
+ _xml_guard_path=$(_xml_escape "$(aidevops_launchd_sanitized_path "$PATH")")
291
317
 
292
318
  local guard_plist_content
293
319
  guard_plist_content=$(
@@ -407,7 +433,7 @@ setup_memory_pressure_monitor() {
407
433
  <key>EnvironmentVariables</key>
408
434
  <dict>
409
435
  <key>PATH</key>
410
- <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
436
+ <string>$(aidevops_launchd_sanitized_path)</string>
411
437
  <key>HOME</key>
412
438
  <string>${_xml_monitor_home}</string>
413
439
  </dict>
@@ -496,7 +522,7 @@ setup_screen_time_snapshot() {
496
522
  <key>EnvironmentVariables</key>
497
523
  <dict>
498
524
  <key>PATH</key>
499
- <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
525
+ <string>$(aidevops_launchd_sanitized_path)</string>
500
526
  <key>HOME</key>
501
527
  <string>${_xml_st_home}</string>
502
528
  </dict>
package/setup.sh CHANGED
@@ -12,7 +12,7 @@ shopt -s inherit_errexit 2>/dev/null || true
12
12
  # AI Assistant Server Access Framework Setup Script
13
13
  # Helps developers set up the framework for their infrastructure
14
14
  #
15
- # Version: 3.13.79
15
+ # Version: 3.13.81
16
16
  #
17
17
  # Quick Install:
18
18
  # npm install -g aidevops && aidevops update (recommended)
@@ -1517,6 +1517,7 @@ _setup_run_non_interactive() {
1517
1517
  fi
1518
1518
  fi
1519
1519
 
1520
+ _time_step "protect_current_setup_worktree" protect_current_setup_worktree
1520
1521
  _time_step "verify_location" verify_location
1521
1522
  _time_step "check_requirements" check_requirements
1522
1523
  # Run quality tool detection in non-interactive mode too (warn-only path).