aidevops 3.13.58 → 3.13.59
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 +1 -1
- package/aidevops.sh +1 -1
- package/package.json +1 -1
- package/setup-modules/agent-deploy.sh +84 -7
- package/setup.sh +37 -1
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.13.
|
|
1
|
+
3.13.59
|
package/aidevops.sh
CHANGED
package/package.json
CHANGED
|
@@ -57,8 +57,13 @@ _restart_pulse_if_running() {
|
|
|
57
57
|
fi
|
|
58
58
|
fi
|
|
59
59
|
|
|
60
|
-
# No auto-restart — start it manually
|
|
61
|
-
|
|
60
|
+
# No auto-restart — start it manually. Prefer the canonical repo source so a
|
|
61
|
+
# background launch never depends on a path inside ~/.aidevops/agents/scripts/
|
|
62
|
+
# that may be in the middle of a future deploy swap (must-not-be-wiped-during-deploy).
|
|
63
|
+
local pulse_script="${INSTALL_DIR:-.}/.agents/scripts/pulse-wrapper.sh"
|
|
64
|
+
if [[ ! -x "$pulse_script" ]]; then
|
|
65
|
+
pulse_script="${HOME}/.aidevops/agents/scripts/pulse-wrapper.sh"
|
|
66
|
+
fi
|
|
62
67
|
if [[ -x "$pulse_script" ]]; then
|
|
63
68
|
nohup "$pulse_script" >>"${HOME}/.aidevops/logs/pulse-wrapper.log" 2>&1 &
|
|
64
69
|
print_success "Pulse started manually (PID $!)"
|
|
@@ -307,6 +312,76 @@ _set_script_permissions_and_report() {
|
|
|
307
312
|
return 0
|
|
308
313
|
}
|
|
309
314
|
|
|
315
|
+
# _count_deployed_agent_files target_dir
|
|
316
|
+
# Prints the number of files in the deployed agents tree. Non-numeric output is
|
|
317
|
+
# normalised to 0 so deploy verification never compares an empty string.
|
|
318
|
+
_count_deployed_agent_files() {
|
|
319
|
+
local target_dir="$1"
|
|
320
|
+
local file_count="0"
|
|
321
|
+
if [[ -d "$target_dir" ]]; then
|
|
322
|
+
file_count=$(find "$target_dir" -type f 2>/dev/null | wc -l | tr -d '[:space:]')
|
|
323
|
+
fi
|
|
324
|
+
[[ "$file_count" =~ ^[0-9]+$ ]] || file_count=0
|
|
325
|
+
printf '%s\n' "$file_count"
|
|
326
|
+
return 0
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
# _restore_latest_agents_backup target_dir
|
|
330
|
+
# Restores the newest agents backup after a failed deploy verification. Backups
|
|
331
|
+
# are created by create_backup_with_rotation as ~/.aidevops/agents-backups/<ts>/agents.
|
|
332
|
+
_restore_latest_agents_backup() {
|
|
333
|
+
local target_dir="$1"
|
|
334
|
+
local backup_base="$HOME/.aidevops/agents-backups"
|
|
335
|
+
local latest_backup=""
|
|
336
|
+
|
|
337
|
+
if [[ ! -d "$backup_base" ]]; then
|
|
338
|
+
print_warning "No agents backup directory found for restore: $backup_base"
|
|
339
|
+
return 1
|
|
340
|
+
fi
|
|
341
|
+
|
|
342
|
+
latest_backup=$(find "$backup_base" -maxdepth 2 -type d -name agents 2>/dev/null | sort | tail -n 1)
|
|
343
|
+
if [[ -z "$latest_backup" || ! -d "$latest_backup" ]]; then
|
|
344
|
+
print_warning "No restorable agents backup found under $backup_base"
|
|
345
|
+
return 1
|
|
346
|
+
fi
|
|
347
|
+
|
|
348
|
+
print_warning "Restoring agents from latest backup: $latest_backup"
|
|
349
|
+
rm -rf "$target_dir"
|
|
350
|
+
mkdir -p "$(dirname "$target_dir")"
|
|
351
|
+
if cp -a "$latest_backup" "$target_dir"; then
|
|
352
|
+
print_success "Restored agents directory from backup"
|
|
353
|
+
return 0
|
|
354
|
+
fi
|
|
355
|
+
|
|
356
|
+
print_error "Failed to restore agents directory from backup: $latest_backup"
|
|
357
|
+
return 1
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
# _verify_deployed_agents_tree target_dir
|
|
361
|
+
# Verifies the deployed agents tree is plausibly complete before .deployed-sha is
|
|
362
|
+
# written. This catches empty/partial deploys that would otherwise suppress the
|
|
363
|
+
# next auto-update retry by stamping the new SHA.
|
|
364
|
+
_verify_deployed_agents_tree() {
|
|
365
|
+
local target_dir="$1"
|
|
366
|
+
local min_files="${AIDEVOPS_AGENT_DEPLOY_MIN_FILES:-100}"
|
|
367
|
+
local file_count="0"
|
|
368
|
+
|
|
369
|
+
[[ "$min_files" =~ ^[0-9]+$ ]] || min_files=100
|
|
370
|
+
|
|
371
|
+
if [[ ! -d "$target_dir/scripts" ]]; then
|
|
372
|
+
print_error "Deploy verification failed: $target_dir/scripts missing after swap"
|
|
373
|
+
return 1
|
|
374
|
+
fi
|
|
375
|
+
|
|
376
|
+
file_count=$(_count_deployed_agent_files "$target_dir")
|
|
377
|
+
if [[ "$file_count" -lt "$min_files" ]]; then
|
|
378
|
+
print_error "Deploy verification failed: $target_dir has $file_count files (< $min_files)"
|
|
379
|
+
return 1
|
|
380
|
+
fi
|
|
381
|
+
|
|
382
|
+
return 0
|
|
383
|
+
}
|
|
384
|
+
|
|
310
385
|
# _install_opencode_plugin_deps target_dir
|
|
311
386
|
# Installs node_modules for the opencode-aidevops plugin.
|
|
312
387
|
# GH#17829: @bufbuild/protobuf was missing; GH#17891: only symlink on first run.
|
|
@@ -651,12 +726,14 @@ deploy_aidevops_agents() {
|
|
|
651
726
|
fi
|
|
652
727
|
|
|
653
728
|
# Postcondition: verify the swap actually produced a functional agents dir.
|
|
654
|
-
# _atomic_stage_and_deploy_agents returns 0 on success, but
|
|
655
|
-
# suspenders check
|
|
656
|
-
#
|
|
657
|
-
|
|
658
|
-
|
|
729
|
+
# _atomic_stage_and_deploy_agents returns 0 on success, but this belt-and-
|
|
730
|
+
# suspenders check catches future regressions where the function returns early
|
|
731
|
+
# without correctly populating $target_dir (GH#22014/GH#21973). Do not write
|
|
732
|
+
# .deployed-sha unless this passes; otherwise auto-update would suppress the
|
|
733
|
+
# next retry even though agents/ is empty or partial.
|
|
734
|
+
if ! _verify_deployed_agents_tree "$target_dir"; then
|
|
659
735
|
print_error "The agents directory was not correctly deployed — setup cannot continue"
|
|
736
|
+
_restore_latest_agents_backup "$target_dir" || true
|
|
660
737
|
return 1
|
|
661
738
|
fi
|
|
662
739
|
|
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.
|
|
15
|
+
# Version: 3.13.59
|
|
16
16
|
#
|
|
17
17
|
# Quick Install:
|
|
18
18
|
# npm install -g aidevops && aidevops update (recommended)
|
|
@@ -1144,6 +1144,30 @@ _setup_lock_pid_alive() {
|
|
|
1144
1144
|
return $?
|
|
1145
1145
|
}
|
|
1146
1146
|
|
|
1147
|
+
_setup_lock_dir_age_seconds() {
|
|
1148
|
+
local lock_dir="$1"
|
|
1149
|
+
local lock_mtime=""
|
|
1150
|
+
local now=""
|
|
1151
|
+
if ! [[ -d "$lock_dir" ]]; then
|
|
1152
|
+
printf '%s\n' 0
|
|
1153
|
+
return 0
|
|
1154
|
+
fi
|
|
1155
|
+
if type _file_mtime_epoch >/dev/null 2>&1; then
|
|
1156
|
+
lock_mtime=$(_file_mtime_epoch "$lock_dir" 2>/dev/null || true)
|
|
1157
|
+
elif [[ "$(uname -s 2>/dev/null || true)" == "Darwin" || "$(uname -s 2>/dev/null || true)" == "FreeBSD" ]]; then
|
|
1158
|
+
lock_mtime=$(stat -f %m "$lock_dir" 2>/dev/null || true)
|
|
1159
|
+
else
|
|
1160
|
+
lock_mtime=$(stat -c %Y "$lock_dir" 2>/dev/null || true)
|
|
1161
|
+
fi
|
|
1162
|
+
now=$(date +%s 2>/dev/null || true)
|
|
1163
|
+
if [[ "$lock_mtime" =~ ^[0-9]+$ && "$now" =~ ^[0-9]+$ && "$now" -ge "$lock_mtime" ]]; then
|
|
1164
|
+
printf '%s\n' $((now - lock_mtime))
|
|
1165
|
+
return 0
|
|
1166
|
+
fi
|
|
1167
|
+
printf '%s\n' 0
|
|
1168
|
+
return 0
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1147
1171
|
_setup_register_child_pid() {
|
|
1148
1172
|
local pid="$1"
|
|
1149
1173
|
[[ -n "$pid" ]] || return 0
|
|
@@ -1216,6 +1240,18 @@ _setup_acquire_noninteractive_setup_lock() {
|
|
|
1216
1240
|
if [[ -r "$lock_dir/owner.pid" ]]; then
|
|
1217
1241
|
owner_pid=$(tr -d '[:space:]' <"$lock_dir/owner.pid" 2>/dev/null || true)
|
|
1218
1242
|
fi
|
|
1243
|
+
if [[ -z "$owner_pid" ]]; then
|
|
1244
|
+
local _lock_age="0"
|
|
1245
|
+
_lock_age=$(_setup_lock_dir_age_seconds "$lock_dir")
|
|
1246
|
+
if [[ "$_lock_age" -le 300 ]]; then
|
|
1247
|
+
print_error "Another setup.sh --non-interactive process is acquiring the deploy lock (lock: ${lock_dir}, age ${_lock_age}s). Exiting to avoid overlapping deployments."
|
|
1248
|
+
return 75
|
|
1249
|
+
fi
|
|
1250
|
+
print_warning "Removing stale setup.sh --non-interactive lock with no owner at ${lock_dir} (age ${_lock_age}s)"
|
|
1251
|
+
rm -rf "$lock_dir" 2>/dev/null || true
|
|
1252
|
+
attempts=$((attempts + 1))
|
|
1253
|
+
continue
|
|
1254
|
+
fi
|
|
1219
1255
|
if _setup_lock_pid_alive "$owner_pid"; then
|
|
1220
1256
|
[[ -r "$lock_dir/command" ]] && owner_cmd=$(tr '\n' ' ' <"$lock_dir/command" 2>/dev/null || true)
|
|
1221
1257
|
# Build actionable diagnostics: elapsed time since lock was acquired
|