@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.10 → 0.1.12
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/bin/adl +2 -2
- package/bin/git +1 -1
- package/bin/git-ado +2 -2
- package/bin/lib/bun-compile-build.sh +1 -1
- package/bin/lib/fleet-host.sh +59 -0
- package/bin/lib/lean-ctx-observe-hooks.sh +9 -9
- package/bin/reconcile +222 -249
- package/bin/reconcile-host +111 -0
- package/bin/setup +216 -0
- package/bin/sync-and-reconcile +52 -39
- package/bin/validate-manifest +15 -44
- package/package.json +1 -3
- package/packages/agent-hooks/package.json +1 -2
- package/packages/agent-hooks/src/rules/impl/fs-trash.ts +2 -2
- package/packages/agent-settings/assets/GLOBAL-AGENTS.md +4 -2
- package/packages/agent-settings/src/global-surface-sweep.ts +5 -15
- package/packages/agent-skills/package.json +1 -1
- package/packages/azdo/package.json +1 -2
- package/packages/fleet/manifest.json +5 -24
- package/packages/fleet/manifest.schema.json +8 -58
- package/packages/fleet/src/install-embedding-model.ts +1 -1
- package/packages/fleet/src/repo-maintain.ts +403 -0
- package/packages/fleet/src/scratch-reap.ts +1 -1
- package/packages/repo-controls/package.json +0 -1
- package/packages/fleet/jobs/git-maintain/src/main.ts +0 -848
- package/packages/fleet/systemd/adl-azure-agent-update.service +0 -13
- package/packages/fleet/systemd/adl-azure-agent-update.timer +0 -10
package/bin/reconcile
CHANGED
|
@@ -44,7 +44,7 @@ if [[ -z "${RECONCILE_REEXEC_BASH:-}" ]]; then
|
|
|
44
44
|
export RECONCILE_REEXEC_BASH=1
|
|
45
45
|
exec "$reconcile_newer_bash" "$0" "$@"
|
|
46
46
|
fi
|
|
47
|
-
echo "bin/reconcile requires bash >= 4.4 (this run is bash ${BASH_VERSION:-unknown} -- empty-array expansions are unsafe under set -u before 4.4). No newer bash was found at: $reconcile_bash_candidates. Install one (e.g. 'brew install bash') and re-run, or put a newer bash earlier on PATH -- refusing to start rather than risk an 'unbound variable' abort mid-run after state has already changed." >&2
|
|
47
|
+
echo "ERROR bin/reconcile requires bash >= 4.4 (this run is bash ${BASH_VERSION:-unknown} -- empty-array expansions are unsafe under set -u before 4.4). No newer bash was found at: $reconcile_bash_candidates. Install one (e.g. 'brew install bash') and re-run, or put a newer bash earlier on PATH -- refusing to start rather than risk an 'unbound variable' abort mid-run after state has already changed." >&2
|
|
48
48
|
exit 1
|
|
49
49
|
fi
|
|
50
50
|
fi
|
|
@@ -54,7 +54,7 @@ set -euo pipefail
|
|
|
54
54
|
export PATH="/usr/local/bin:/opt/homebrew/bin:/home/linuxbrew/.linuxbrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"
|
|
55
55
|
|
|
56
56
|
usage() {
|
|
57
|
-
echo "usage: reconcile --device NAME [--source npm|checkout] [--mode audit|plan|apply] [--manifest PATH] [--state-dir PATH] [--platform mac|linux]" >&2
|
|
57
|
+
echo "ERROR usage: reconcile --device NAME [--source npm|checkout] [--mode audit|plan|apply] [--manifest PATH] [--state-dir PATH] [--platform mac|linux]" >&2
|
|
58
58
|
exit 2
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -68,8 +68,9 @@ source_mode="npm"
|
|
|
68
68
|
# remove_one_repo_dir themselves, so packages/fleet/tests/test-manifest.sh
|
|
69
69
|
# can point it at a disposable test_root directory (RECONCILE_SOURCE_ONLY=1)
|
|
70
70
|
# and exercise the real sync/removal mechanics without root or a real
|
|
71
|
-
# /usr/local.
|
|
72
|
-
#
|
|
71
|
+
# /usr/local. The production value is the libexec dir the apps/cli
|
|
72
|
+
# commands (repo-controls, skills, hooks, settings) resolve the projected
|
|
73
|
+
# payload from.
|
|
73
74
|
repo_dir_libexec_root="/usr/local/libexec/adl"
|
|
74
75
|
# Test-only escape hatch for default-agent-file.ts / managed-settings.ts's own
|
|
75
76
|
# `--root` (both already accept it; see their headers). Unset in every real
|
|
@@ -225,11 +226,11 @@ source "$script_dir/lib/bun-compile-build.sh"
|
|
|
225
226
|
"$script_dir/validate-manifest" "$manifest" >/dev/null
|
|
226
227
|
if [[ "${RECONCILE_SOURCE_ONLY:-0}" != "1" ]]; then
|
|
227
228
|
if [[ "$source_mode" == npm && -e "$repo_root/.git" ]]; then
|
|
228
|
-
echo "npm source mode requires an installed package root; use --source checkout for a Git checkout" >&2
|
|
229
|
+
echo "ERROR npm source mode requires an installed package root; use --source checkout for a Git checkout" >&2
|
|
229
230
|
exit 2
|
|
230
231
|
fi
|
|
231
232
|
if [[ "$source_mode" == checkout && ! -e "$repo_root/.git" ]]; then
|
|
232
|
-
echo "checkout source mode requires a Git checkout" >&2
|
|
233
|
+
echo "ERROR checkout source mode requires a Git checkout" >&2
|
|
233
234
|
exit 2
|
|
234
235
|
fi
|
|
235
236
|
fi
|
|
@@ -237,7 +238,7 @@ fi
|
|
|
237
238
|
case "$(uname -s)" in
|
|
238
239
|
Darwin) platform=mac; sha256_cmd=(shasum -a 256) ;;
|
|
239
240
|
Linux) platform=linux; sha256_cmd=(sha256sum) ;;
|
|
240
|
-
*) echo "unsupported operating system: $(uname -s)" >&2; exit 1 ;;
|
|
241
|
+
*) echo "ERROR unsupported operating system: $(uname -s)" >&2; exit 1 ;;
|
|
241
242
|
esac
|
|
242
243
|
if [[ -n "$platform_override" ]]; then
|
|
243
244
|
# Applying as a foreign platform would install the wrong platform's tools, so
|
|
@@ -248,7 +249,7 @@ if [[ -n "$platform_override" ]]; then
|
|
|
248
249
|
# agents of the mixed CI pool it dies with "device m3 is not declared under
|
|
249
250
|
# linux" (build 4226).
|
|
250
251
|
if [[ "$mode" == apply && "${RECONCILE_SOURCE_ONLY:-0}" != "1" ]]; then
|
|
251
|
-
echo "--platform cannot override the host in apply mode" >&2
|
|
252
|
+
echo "ERROR --platform cannot override the host in apply mode" >&2
|
|
252
253
|
exit 2
|
|
253
254
|
fi
|
|
254
255
|
[[ "$platform_override" == mac || "$platform_override" == linux ]] || usage
|
|
@@ -256,7 +257,7 @@ if [[ -n "$platform_override" ]]; then
|
|
|
256
257
|
fi
|
|
257
258
|
|
|
258
259
|
jq -e --arg platform "$platform" --arg device "$device" '.[$platform].devices[$device]' "$manifest" >/dev/null || {
|
|
259
|
-
echo "device $device is not declared under $platform" >&2
|
|
260
|
+
echo "ERROR device $device is not declared under $platform" >&2
|
|
260
261
|
exit 1
|
|
261
262
|
}
|
|
262
263
|
|
|
@@ -292,7 +293,7 @@ path_owner() {
|
|
|
292
293
|
elif owner="$(stat -c '%U' "$path" 2>/dev/null)"; then
|
|
293
294
|
printf '%s\n' "$owner"
|
|
294
295
|
else
|
|
295
|
-
echo "cannot determine owner of Homebrew prefix: $path" >&2
|
|
296
|
+
echo "ERROR cannot determine owner of Homebrew prefix: $path" >&2
|
|
296
297
|
return 1
|
|
297
298
|
fi
|
|
298
299
|
}
|
|
@@ -305,7 +306,7 @@ resolve_brew_owner() {
|
|
|
305
306
|
fi
|
|
306
307
|
if [[ ! -d "$prefix" ]]; then
|
|
307
308
|
if [[ "$target_mode" == apply ]]; then
|
|
308
|
-
echo "Homebrew prefix missing: $prefix" >&2
|
|
309
|
+
echo "ERROR Homebrew prefix missing: $prefix" >&2
|
|
309
310
|
return 1
|
|
310
311
|
fi
|
|
311
312
|
printf '%s\n' '<unresolved-linuxbrew-owner>'
|
|
@@ -313,7 +314,7 @@ resolve_brew_owner() {
|
|
|
313
314
|
fi
|
|
314
315
|
owner="$(path_owner "$prefix")" || return 1
|
|
315
316
|
if [[ "$owner" == root ]]; then
|
|
316
|
-
echo "Homebrew prefix must be owned by a non-root account: $prefix" >&2
|
|
317
|
+
echo "ERROR Homebrew prefix must be owned by a non-root account: $prefix" >&2
|
|
317
318
|
return 1
|
|
318
319
|
fi
|
|
319
320
|
printf '%s\n' "$owner"
|
|
@@ -329,7 +330,7 @@ run_brew() {
|
|
|
329
330
|
printf '\n'
|
|
330
331
|
return 0
|
|
331
332
|
fi
|
|
332
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
333
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
333
334
|
(cd /tmp && sudo -u "$brew_owner" -H env NONINTERACTIVE=1 PATH="${brew_bin%/*}:/usr/bin:/bin" "$brew_bin" "$@" </dev/null)
|
|
334
335
|
}
|
|
335
336
|
|
|
@@ -395,14 +396,14 @@ run_brew_upgrade_all() {
|
|
|
395
396
|
echo "would run: brew upgrade (all outdated formulae and casks)"
|
|
396
397
|
return 0
|
|
397
398
|
fi
|
|
398
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
399
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
399
400
|
local outdated_formulae outdated_casks formulae_count casks_count
|
|
400
401
|
outdated_formulae="$(brew_query outdated --formula --quiet)" || {
|
|
401
|
-
echo "brew outdated --formula check failed" >&2
|
|
402
|
+
echo "ERROR brew outdated --formula check failed" >&2
|
|
402
403
|
return 1
|
|
403
404
|
}
|
|
404
405
|
outdated_casks="$(brew_query outdated --cask --quiet)" || {
|
|
405
|
-
echo "brew outdated --cask check failed" >&2
|
|
406
|
+
echo "ERROR brew outdated --cask check failed" >&2
|
|
406
407
|
return 1
|
|
407
408
|
}
|
|
408
409
|
formulae_count=0
|
|
@@ -422,10 +423,10 @@ run_brew_upgrade_all() {
|
|
|
422
423
|
echo "brew upgrade: $formulae_count formulae, $casks_count casks outdated; upgrading (timeout ${BREW_UPGRADE_ALL_TIMEOUT_SECONDS}s)"
|
|
423
424
|
run_with_timeout "$BREW_UPGRADE_ALL_TIMEOUT_SECONDS" run_brew upgrade 2>&1 || upgrade_status=$?
|
|
424
425
|
if [[ "$upgrade_status" -eq 124 ]]; then
|
|
425
|
-
echo "brew upgrade timed out after ${BREW_UPGRADE_ALL_TIMEOUT_SECONDS}s" >&2
|
|
426
|
+
echo "ERROR brew upgrade timed out after ${BREW_UPGRADE_ALL_TIMEOUT_SECONDS}s" >&2
|
|
426
427
|
return 1
|
|
427
428
|
elif [[ "$upgrade_status" -ne 0 ]]; then
|
|
428
|
-
echo "brew upgrade failed (exit $upgrade_status)" >&2
|
|
429
|
+
echo "ERROR brew upgrade failed (exit $upgrade_status)" >&2
|
|
429
430
|
return 1
|
|
430
431
|
fi
|
|
431
432
|
echo "brew upgrade: $formulae_count formulae, $casks_count casks were outdated before upgrade"
|
|
@@ -439,7 +440,7 @@ run_apt() {
|
|
|
439
440
|
printf '\n'
|
|
440
441
|
return 0
|
|
441
442
|
fi
|
|
442
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
443
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
443
444
|
env DEBIAN_FRONTEND=noninteractive apt-get "$@" </dev/null
|
|
444
445
|
}
|
|
445
446
|
|
|
@@ -454,7 +455,7 @@ run_npm() {
|
|
|
454
455
|
printf '\n'
|
|
455
456
|
return 0
|
|
456
457
|
fi
|
|
457
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
458
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
458
459
|
if [[ "$platform" == linux ]]; then
|
|
459
460
|
(cd /tmp && sudo -u "$administrator" -H env npm_config_prefix=/usr/local PATH="${brew_bin%/*}:/usr/bin:/bin" npm "$@" </dev/null)
|
|
460
461
|
else
|
|
@@ -538,12 +539,12 @@ canonical_parent_path() {
|
|
|
538
539
|
npm_package_owns_executable() {
|
|
539
540
|
local package="$1" executable="$2" npm_root package_manifest bin_relative actual_path actual_link expected_target actual_target
|
|
540
541
|
npm_root="$(npm_global_root)" || {
|
|
541
|
-
echo "could not resolve npm global root for $package" >&2
|
|
542
|
+
echo "ERROR could not resolve npm global root for $package" >&2
|
|
542
543
|
return 1
|
|
543
544
|
}
|
|
544
545
|
package_manifest="$npm_root/$package/package.json"
|
|
545
546
|
[[ -f "$package_manifest" ]] || {
|
|
546
|
-
echo "npm package metadata missing: $package_manifest" >&2
|
|
547
|
+
echo "ERROR npm package metadata missing: $package_manifest" >&2
|
|
547
548
|
return 1
|
|
548
549
|
}
|
|
549
550
|
bin_relative="$(jq -r --arg executable "$executable" '
|
|
@@ -553,20 +554,20 @@ npm_package_owns_executable() {
|
|
|
553
554
|
end
|
|
554
555
|
' "$package_manifest")"
|
|
555
556
|
[[ -n "$bin_relative" && "$bin_relative" != /* && "$bin_relative" != .. && "$bin_relative" != ../* && "$bin_relative" != */../* && "$bin_relative" != */.. ]] || {
|
|
556
|
-
echo "npm package $package does not declare a safe bin target for $executable" >&2
|
|
557
|
+
echo "ERROR npm package $package does not declare a safe bin target for $executable" >&2
|
|
557
558
|
return 1
|
|
558
559
|
}
|
|
559
560
|
actual_path="$(npm_global_executable_path "$executable")" || {
|
|
560
|
-
echo "npm executable missing from global PATH: $executable" >&2
|
|
561
|
+
echo "ERROR npm executable missing from global PATH: $executable" >&2
|
|
561
562
|
return 1
|
|
562
563
|
}
|
|
563
564
|
[[ -L "$actual_path" ]] || {
|
|
564
|
-
echo "npm executable is not an npm-managed symlink: $actual_path" >&2
|
|
565
|
+
echo "ERROR npm executable is not an npm-managed symlink: $actual_path" >&2
|
|
565
566
|
return 1
|
|
566
567
|
}
|
|
567
568
|
expected_target="$(canonical_parent_path "$npm_root/$package/$bin_relative")" || return 1
|
|
568
569
|
[[ -f "$expected_target" && -x "$expected_target" ]] || {
|
|
569
|
-
echo "npm package $package bin target is not an executable file: $expected_target" >&2
|
|
570
|
+
echo "ERROR npm package $package bin target is not an executable file: $expected_target" >&2
|
|
570
571
|
return 1
|
|
571
572
|
}
|
|
572
573
|
actual_link="$(readlink "$actual_path")" || return 1
|
|
@@ -576,7 +577,7 @@ npm_package_owns_executable() {
|
|
|
576
577
|
actual_target="$(canonical_parent_path "${actual_path%/*}/$actual_link")" || return 1
|
|
577
578
|
fi
|
|
578
579
|
[[ "$actual_target" == "$expected_target" ]] || {
|
|
579
|
-
echo "npm executable $executable is not owned by $package" >&2
|
|
580
|
+
echo "ERROR npm executable $executable is not owned by $package" >&2
|
|
580
581
|
return 1
|
|
581
582
|
}
|
|
582
583
|
}
|
|
@@ -588,21 +589,21 @@ run_pip() {
|
|
|
588
589
|
printf '\n'
|
|
589
590
|
return 0
|
|
590
591
|
fi
|
|
591
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
592
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
592
593
|
(cd /tmp && sudo -u "$administrator" -H env PATH="${brew_bin%/*}:/usr/bin:/bin" python3 -m pip "$@" </dev/null)
|
|
593
594
|
}
|
|
594
595
|
|
|
595
596
|
pip_user_executable() {
|
|
596
597
|
local executable="$1"
|
|
597
598
|
[[ "$executable" != */* ]] || {
|
|
598
|
-
echo "pip executable must be a command name, not a path: $executable" >&2
|
|
599
|
+
echo "ERROR pip executable must be a command name, not a path: $executable" >&2
|
|
599
600
|
exit 1
|
|
600
601
|
}
|
|
601
602
|
local user_base user_home
|
|
602
603
|
user_home="$(cd /tmp && sudo -u "$administrator" -H /bin/sh -c 'printf "%s\n" "$HOME"')"
|
|
603
604
|
user_base="$(cd /tmp && sudo -u "$administrator" -H env PATH="${brew_bin%/*}:/usr/bin:/bin" python3 -m site --user-base)"
|
|
604
605
|
[[ "$user_base" == "$user_home" || "$user_base" == "$user_home"/* ]] || {
|
|
605
|
-
echo "pip user base is outside the declared administrator home: $user_base" >&2
|
|
606
|
+
echo "ERROR pip user base is outside the declared administrator home: $user_base" >&2
|
|
606
607
|
exit 1
|
|
607
608
|
}
|
|
608
609
|
printf '%s/bin/%s\n' "${user_base%/}" "$executable"
|
|
@@ -615,11 +616,11 @@ ensure_global_pip_executable() {
|
|
|
615
616
|
echo "would expose pip executable globally: $target"
|
|
616
617
|
return 0
|
|
617
618
|
fi
|
|
618
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
619
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
619
620
|
local source existing_source user_home
|
|
620
621
|
source="$(pip_user_executable "$executable")"
|
|
621
622
|
user_home="$(cd /tmp && sudo -u "$administrator" -H /bin/sh -c 'printf "%s\n" "$HOME"')"
|
|
622
|
-
[[ -x "$source" ]] || { echo "pip executable missing after install: $source" >&2; exit 1; }
|
|
623
|
+
[[ -x "$source" ]] || { echo "ERROR pip executable missing after install: $source" >&2; exit 1; }
|
|
623
624
|
if [[ -L "$target" ]]; then
|
|
624
625
|
existing_source="$(readlink "$target")"
|
|
625
626
|
if [[ "$existing_source" == "$source" ]]; then
|
|
@@ -628,10 +629,10 @@ ensure_global_pip_executable() {
|
|
|
628
629
|
fi
|
|
629
630
|
case "$existing_source" in
|
|
630
631
|
"$user_home"/*/bin/"$executable") ;;
|
|
631
|
-
*) echo "refusing to replace unrelated symlink: $target -> $existing_source" >&2; exit 1 ;;
|
|
632
|
+
*) echo "ERROR refusing to replace unrelated symlink: $target -> $existing_source" >&2; exit 1 ;;
|
|
632
633
|
esac
|
|
633
634
|
elif [[ -e "$target" ]]; then
|
|
634
|
-
echo "refusing to replace unrelated global executable: $target" >&2
|
|
635
|
+
echo "ERROR refusing to replace unrelated global executable: $target" >&2
|
|
635
636
|
exit 1
|
|
636
637
|
fi
|
|
637
638
|
ln -sfn "$source" "$target"
|
|
@@ -645,17 +646,17 @@ remove_global_pip_executable() {
|
|
|
645
646
|
echo "would remove global pip executable: $target"
|
|
646
647
|
return 0
|
|
647
648
|
fi
|
|
648
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
649
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
649
650
|
if [[ ! -e "$target" && ! -L "$target" ]]; then
|
|
650
651
|
return 0
|
|
651
652
|
fi
|
|
652
|
-
[[ -L "$target" ]] || { echo "refusing to remove unrelated global executable: $target" >&2; exit 1; }
|
|
653
|
+
[[ -L "$target" ]] || { echo "ERROR refusing to remove unrelated global executable: $target" >&2; exit 1; }
|
|
653
654
|
local source user_home
|
|
654
655
|
source="$(readlink "$target")"
|
|
655
656
|
user_home="$(cd /tmp && sudo -u "$administrator" -H /bin/sh -c 'printf "%s\n" "$HOME"')"
|
|
656
657
|
case "$source" in
|
|
657
658
|
"$user_home"/*/bin/"$executable") rm -f -- "$target" ;;
|
|
658
|
-
*) echo "refusing to remove unrelated symlink: $target -> $source" >&2; exit 1 ;;
|
|
659
|
+
*) echo "ERROR refusing to remove unrelated symlink: $target -> $source" >&2; exit 1 ;;
|
|
659
660
|
esac
|
|
660
661
|
}
|
|
661
662
|
|
|
@@ -705,12 +706,12 @@ bun_source_hash() {
|
|
|
705
706
|
local source_dir="$1" hash
|
|
706
707
|
if repo_root_is_git; then
|
|
707
708
|
hash="$(repo_git rev-parse --verify --quiet "HEAD:$source_dir")" || {
|
|
708
|
-
echo "bun-compile source is not tracked at HEAD: $source_dir" >&2
|
|
709
|
+
echo "ERROR bun-compile source is not tracked at HEAD: $source_dir" >&2
|
|
709
710
|
return 1
|
|
710
711
|
}
|
|
711
712
|
else
|
|
712
713
|
[[ -d "$repo_root/$source_dir" ]] || {
|
|
713
|
-
echo "bun-compile source missing from installed package: $repo_root/$source_dir" >&2
|
|
714
|
+
echo "ERROR bun-compile source missing from installed package: $repo_root/$source_dir" >&2
|
|
714
715
|
return 1
|
|
715
716
|
}
|
|
716
717
|
hash="$(content_tree_hash "$repo_root/$source_dir")"
|
|
@@ -732,17 +733,17 @@ run_bun_compile() {
|
|
|
732
733
|
printf 'would build and install bun binary: %s -> %s (source %s)\n' "$package" "$target" "$source_hash"
|
|
733
734
|
return 0
|
|
734
735
|
fi
|
|
735
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
736
|
-
[[ "$target" == /usr/local/bin/* ]] || { echo "bun-compile target must be under /usr/local/bin: $target" >&2; exit 1; }
|
|
736
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
737
|
+
[[ "$target" == /usr/local/bin/* ]] || { echo "ERROR bun-compile target must be under /usr/local/bin: $target" >&2; exit 1; }
|
|
737
738
|
[[ "$source_dir" != /* && "$source_dir" != *..* ]] || {
|
|
738
|
-
echo "unsafe bun-compile source path: $source_dir" >&2
|
|
739
|
+
echo "ERROR unsafe bun-compile source path: $source_dir" >&2
|
|
739
740
|
exit 1
|
|
740
741
|
}
|
|
741
742
|
local project_dir="$repo_root/$source_dir"
|
|
742
|
-
[[ -d "$project_dir" ]] || { echo "bun-compile source missing: $project_dir" >&2; exit 1; }
|
|
743
|
+
[[ -d "$project_dir" ]] || { echo "ERROR bun-compile source missing: $project_dir" >&2; exit 1; }
|
|
743
744
|
local bun_bin
|
|
744
745
|
bun_bin="$(command -v bun || true)"
|
|
745
|
-
[[ -n "$bun_bin" ]] || { echo "bun-compile requires bun on PATH; ensure bun installs before this tool" >&2; exit 1; }
|
|
746
|
+
[[ -n "$bun_bin" ]] || { echo "ERROR bun-compile requires bun on PATH; ensure bun installs before this tool" >&2; exit 1; }
|
|
746
747
|
(cd "$project_dir" && "$bun_bin" install --frozen-lockfile)
|
|
747
748
|
bun_compile_build "$bun_bin" "$project_dir/$entry" "$target"
|
|
748
749
|
}
|
|
@@ -754,8 +755,8 @@ run_embedding_model() {
|
|
|
754
755
|
printf 'would install embedding model: %s as %s -> ~/.cache/adl-embedding/model\n' "$package" "$administrator"
|
|
755
756
|
return 0
|
|
756
757
|
fi
|
|
757
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
758
|
-
command -v bun >/dev/null 2>&1 || { echo "embedding-model requires bun; ensure bun installs before this tool" >&2; exit 1; }
|
|
758
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
759
|
+
command -v bun >/dev/null 2>&1 || { echo "ERROR embedding-model requires bun; ensure bun installs before this tool" >&2; exit 1; }
|
|
759
760
|
(cd /tmp && sudo -u "$administrator" -H env PATH="${brew_bin%/*}:/usr/bin:/bin" \
|
|
760
761
|
bun "$repo_root/packages/fleet/src/install-embedding-model.ts" install --spec "$spec_json" </dev/null)
|
|
761
762
|
}
|
|
@@ -782,9 +783,9 @@ install_surface_policy_file() {
|
|
|
782
783
|
echo "would install required surface policy: $source -> $target"
|
|
783
784
|
return 0
|
|
784
785
|
fi
|
|
785
|
-
[[ -f "$source" ]] || { echo "surface policy source missing: $source" >&2; return 1; }
|
|
786
|
+
[[ -f "$source" ]] || { echo "ERROR surface policy source missing: $source" >&2; return 1; }
|
|
786
787
|
jq -e '(.deny.paths | arrays) and (.deny.nativeTools | arrays)' "$source" >/dev/null || {
|
|
787
|
-
echo "surface policy source is invalid: $source" >&2
|
|
788
|
+
echo "ERROR surface policy source is invalid: $source" >&2
|
|
788
789
|
return 1
|
|
789
790
|
}
|
|
790
791
|
mkdir -p /etc/adl
|
|
@@ -823,7 +824,7 @@ resolve_latest_release_tag() {
|
|
|
823
824
|
local repo="$1"
|
|
824
825
|
local location
|
|
825
826
|
location="$(curl --proto '=https' --proto-redir '=https' -fsS -o /dev/null -w '%{redirect_url}' "https://github.com/$repo/releases/latest")"
|
|
826
|
-
[[ -n "$location" ]] || { echo "could not resolve latest release tag for $repo" >&2; exit 1; }
|
|
827
|
+
[[ -n "$location" ]] || { echo "ERROR could not resolve latest release tag for $repo" >&2; exit 1; }
|
|
827
828
|
basename "$location"
|
|
828
829
|
}
|
|
829
830
|
|
|
@@ -854,10 +855,10 @@ run_release_archive_latest() {
|
|
|
854
855
|
local checksums_asset="$5"
|
|
855
856
|
local archive_executable="$6"
|
|
856
857
|
local target="$7"
|
|
857
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
858
|
-
[[ "$target" == /usr/local/bin/* ]] || { echo "release archive target must be under /usr/local/bin: $target" >&2; exit 1; }
|
|
858
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
859
|
+
[[ "$target" == /usr/local/bin/* ]] || { echo "ERROR release archive target must be under /usr/local/bin: $target" >&2; exit 1; }
|
|
859
860
|
[[ "$archive_executable" != /* && "$archive_executable" != *..* ]] || {
|
|
860
|
-
echo "unsafe archive executable path: $archive_executable" >&2
|
|
861
|
+
echo "ERROR unsafe archive executable path: $archive_executable" >&2
|
|
861
862
|
exit 1
|
|
862
863
|
}
|
|
863
864
|
|
|
@@ -872,7 +873,7 @@ run_release_archive_latest() {
|
|
|
872
873
|
curl --proto '=https' --proto-redir '=https' -fsSL --retry 3 \
|
|
873
874
|
-o "$checksums_file" "https://github.com/$repo/releases/download/$tag/$checksums_asset"
|
|
874
875
|
expected_sha256="$(awk -v want="$asset" '$2 == want { print $1; found = 1 } END { exit !found }' "$checksums_file")" || {
|
|
875
|
-
echo "no published checksum for $asset in $repo's $checksums_asset -- refusing to install unverified bytes" >&2
|
|
876
|
+
echo "ERROR no published checksum for $asset in $repo's $checksums_asset -- refusing to install unverified bytes" >&2
|
|
876
877
|
exit 1
|
|
877
878
|
}
|
|
878
879
|
curl --proto '=https' --proto-redir '=https' -fsSL --retry 3 \
|
|
@@ -880,15 +881,15 @@ run_release_archive_latest() {
|
|
|
880
881
|
case "$(uname -s)" in
|
|
881
882
|
Darwin) actual_sha256="$(shasum -a 256 "$archive_file" | awk '{print $1}')" ;;
|
|
882
883
|
Linux) actual_sha256="$(sha256sum "$archive_file" | awk '{print $1}')" ;;
|
|
883
|
-
*) echo "unsupported operating system for release archive" >&2; exit 1 ;;
|
|
884
|
+
*) echo "ERROR unsupported operating system for release archive" >&2; exit 1 ;;
|
|
884
885
|
esac
|
|
885
886
|
[[ "$actual_sha256" == "$expected_sha256" ]] || {
|
|
886
|
-
echo "checksum mismatch for $package (latest): expected $expected_sha256 from published $checksums_asset, got $actual_sha256" >&2
|
|
887
|
+
echo "ERROR checksum mismatch for $package (latest): expected $expected_sha256 from published $checksums_asset, got $actual_sha256" >&2
|
|
887
888
|
exit 1
|
|
888
889
|
}
|
|
889
890
|
tar -xzf "$archive_file" -C "$extract_dir" "$archive_executable"
|
|
890
891
|
[[ -f "$extract_dir/$archive_executable" ]] || {
|
|
891
|
-
echo "archive executable missing: $archive_executable" >&2
|
|
892
|
+
echo "ERROR archive executable missing: $archive_executable" >&2
|
|
892
893
|
exit 1
|
|
893
894
|
}
|
|
894
895
|
atomic_install_executable "$extract_dir/$archive_executable" "$target"
|
|
@@ -934,7 +935,7 @@ install_one_tool() {
|
|
|
934
935
|
echo "ensure Adl from explicit checkout source: $repo_root"
|
|
935
936
|
build_checkout_adl || rc=1
|
|
936
937
|
if [[ "$mode" == apply && "$rc" -eq 0 ]]; then
|
|
937
|
-
command -v "$executable" >/dev/null 2>&1 || { echo "checkout Adl executable missing from PATH: $executable" >&2; rc=1; }
|
|
938
|
+
command -v "$executable" >/dev/null 2>&1 || { echo "ERROR checkout Adl executable missing from PATH: $executable" >&2; rc=1; }
|
|
938
939
|
fi
|
|
939
940
|
return "$rc"
|
|
940
941
|
fi
|
|
@@ -971,7 +972,7 @@ install_one_tool() {
|
|
|
971
972
|
run_brew upgrade "$package" || rc=1
|
|
972
973
|
fi
|
|
973
974
|
else
|
|
974
|
-
echo "$tool_id: brew outdated check failed for $package" >&2
|
|
975
|
+
echo "ERROR $tool_id: brew outdated check failed for $package" >&2
|
|
975
976
|
rc=1
|
|
976
977
|
fi
|
|
977
978
|
else
|
|
@@ -1012,12 +1013,12 @@ install_one_tool() {
|
|
|
1012
1013
|
prepare_in_place_bun_to_npm_migration "$tool_id" || rc=1
|
|
1013
1014
|
fi
|
|
1014
1015
|
if [[ "$rc" -eq 0 ]] && ! npm_target_version="$(npm_latest_version "$package")"; then
|
|
1015
|
-
echo "$tool_id: npm view could not resolve the latest version of $package" >&2
|
|
1016
|
+
echo "ERROR $tool_id: npm view could not resolve the latest version of $package" >&2
|
|
1016
1017
|
rc=1
|
|
1017
1018
|
fi
|
|
1018
1019
|
if [[ "$rc" -eq 0 ]]; then
|
|
1019
1020
|
if ! npm_installed_ver="$(npm_installed_version "$package")"; then
|
|
1020
|
-
echo "$tool_id: npm ls -g could not inspect the global install of $package" >&2
|
|
1021
|
+
echo "ERROR $tool_id: npm ls -g could not inspect the global install of $package" >&2
|
|
1021
1022
|
rc=1
|
|
1022
1023
|
elif [[ -n "$npm_installed_ver" && "$npm_installed_ver" == "$npm_target_version" ]]; then
|
|
1023
1024
|
echo "already latest: $tool_id (npm:$package@$npm_installed_ver)"
|
|
@@ -1068,15 +1069,15 @@ install_one_tool() {
|
|
|
1068
1069
|
fi
|
|
1069
1070
|
fi
|
|
1070
1071
|
;;
|
|
1071
|
-
*) echo "unsupported manager: $manager" >&2; rc=1 ;;
|
|
1072
|
+
*) echo "ERROR unsupported manager: $manager" >&2; rc=1 ;;
|
|
1072
1073
|
esac
|
|
1073
1074
|
if [[ "$mode" == apply && "$rc" -eq 0 ]]; then
|
|
1074
1075
|
if [[ "$executable" == /* ]]; then
|
|
1075
|
-
[[ -x "$executable" ]] || { echo "$tool_id executable missing: $executable" >&2; rc=1; }
|
|
1076
|
+
[[ -x "$executable" ]] || { echo "ERROR $tool_id executable missing: $executable" >&2; rc=1; }
|
|
1076
1077
|
else
|
|
1077
1078
|
local executable_path
|
|
1078
1079
|
executable_path="$(sudo -u "$administrator" -H env PATH="/opt/homebrew/bin:/home/linuxbrew/.linuxbrew/bin:/usr/local/bin:/usr/bin:/bin" /bin/sh -c "command -v '$executable'" 2>/dev/null || true)"
|
|
1079
|
-
[[ -n "$executable_path" ]] || { echo "$tool_id executable missing from global PATH: $executable" >&2; rc=1; }
|
|
1080
|
+
[[ -n "$executable_path" ]] || { echo "ERROR $tool_id executable missing from global PATH: $executable" >&2; rc=1; }
|
|
1080
1081
|
fi
|
|
1081
1082
|
fi
|
|
1082
1083
|
return "$rc"
|
|
@@ -1102,11 +1103,11 @@ is_in_place_bun_to_npm_migration() {
|
|
|
1102
1103
|
remove_retired_bun_compilation() {
|
|
1103
1104
|
local tool_id="$1" executable="$2" hash_file
|
|
1104
1105
|
[[ "$tool_id" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*$ ]] || {
|
|
1105
|
-
echo "unsafe retired Bun compilation tool id: $tool_id" >&2
|
|
1106
|
+
echo "ERROR unsafe retired Bun compilation tool id: $tool_id" >&2
|
|
1106
1107
|
return 1
|
|
1107
1108
|
}
|
|
1108
1109
|
[[ "$executable" =~ ^/usr/local/bin/[A-Za-z0-9][A-Za-z0-9._-]*$ ]] || {
|
|
1109
|
-
echo "refusing unsafe retired Bun binary removal target: $executable" >&2
|
|
1110
|
+
echo "ERROR refusing unsafe retired Bun binary removal target: $executable" >&2
|
|
1110
1111
|
return 1
|
|
1111
1112
|
}
|
|
1112
1113
|
hash_file="$(bun_source_hash_file "$tool_id")"
|
|
@@ -1129,7 +1130,7 @@ prepare_in_place_bun_to_npm_migration() {
|
|
|
1129
1130
|
package="$(jq -r --arg id "$tool_id" '.[$id].package' "$resolved_file")"
|
|
1130
1131
|
executable="$(jq -r --arg id "$tool_id" '.[$id].executable' "$resolved_file")"
|
|
1131
1132
|
npm_package_owns_executable "$package" "$executable" || {
|
|
1132
|
-
echo "refusing to remove an executable symlink not owned by npm: $previous_executable" >&2
|
|
1133
|
+
echo "ERROR refusing to remove an executable symlink not owned by npm: $previous_executable" >&2
|
|
1133
1134
|
return 1
|
|
1134
1135
|
}
|
|
1135
1136
|
hash_file="$(bun_source_hash_file "$tool_id")"
|
|
@@ -1144,7 +1145,7 @@ failed_in_place_npm_migration() {
|
|
|
1144
1145
|
local tool_id
|
|
1145
1146
|
for tool_id in ${failed_tools[@]+"${failed_tools[@]}"}; do
|
|
1146
1147
|
if is_in_place_bun_to_npm_migration "$tool_id"; then
|
|
1147
|
-
echo "global-tools: npm migration failed for $tool_id; retired Bun command was removed and reconciliation must stop" >&2
|
|
1148
|
+
echo "ERROR global-tools: npm migration failed for $tool_id; retired Bun command was removed and reconciliation must stop" >&2
|
|
1148
1149
|
return 0
|
|
1149
1150
|
fi
|
|
1150
1151
|
done
|
|
@@ -1181,7 +1182,7 @@ build_one_bun_tool() {
|
|
|
1181
1182
|
fi
|
|
1182
1183
|
run_bun_compile "$package" "$source_hash" "$source_dir" "$entry" "$executable" || rc=1
|
|
1183
1184
|
if [[ "$mode" == apply && "$rc" -eq 0 ]]; then
|
|
1184
|
-
[[ -x "$executable" ]] || { echo "$tool_id executable missing: $executable" >&2; rc=1; }
|
|
1185
|
+
[[ -x "$executable" ]] || { echo "ERROR $tool_id executable missing: $executable" >&2; rc=1; }
|
|
1185
1186
|
fi
|
|
1186
1187
|
if [[ "$mode" == apply && "$rc" -eq 0 ]]; then
|
|
1187
1188
|
mkdir -p "${hash_file%/*}"
|
|
@@ -1202,7 +1203,7 @@ build_checkout_adl() {
|
|
|
1202
1203
|
fi
|
|
1203
1204
|
run_bun_compile adl "$source_hash" "$source_dir" "$entry" "$target" || rc=1
|
|
1204
1205
|
if [[ "$mode" == apply && "$rc" -eq 0 ]]; then
|
|
1205
|
-
[[ -x "$target" ]] || { echo "checkout Adl executable missing: $target" >&2; rc=1; }
|
|
1206
|
+
[[ -x "$target" ]] || { echo "ERROR checkout Adl executable missing: $target" >&2; rc=1; }
|
|
1206
1207
|
if [[ "$rc" -eq 0 ]]; then
|
|
1207
1208
|
mkdir -p "${hash_file%/*}"
|
|
1208
1209
|
printf '%s\n' "$source_hash" >"$hash_file.new"
|
|
@@ -1243,16 +1244,16 @@ write_one_shim() {
|
|
|
1243
1244
|
executable="$(jq -r --arg id "$tool_id" '.[$id].executable' "$resolved_file")"
|
|
1244
1245
|
echo "ensure shim: $tool_id (shim:$package -> $executable)"
|
|
1245
1246
|
[[ "$executable" == /usr/local/bin/* ]] || {
|
|
1246
|
-
echo "refusing unsafe shim target: $executable" >&2
|
|
1247
|
+
echo "ERROR refusing unsafe shim target: $executable" >&2
|
|
1247
1248
|
return 1
|
|
1248
1249
|
}
|
|
1249
1250
|
if [[ "$mode" != apply ]]; then
|
|
1250
1251
|
echo "would write shim: $executable -> $package"
|
|
1251
1252
|
return 0
|
|
1252
1253
|
fi
|
|
1253
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
1254
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
1254
1255
|
target_path="$(sudo -u "$administrator" -H env PATH="/opt/homebrew/bin:/home/linuxbrew/.linuxbrew/bin:/usr/local/bin:/usr/bin:/bin" /bin/sh -c "command -v '$package'" 2>/dev/null || true)"
|
|
1255
|
-
[[ -n "$target_path" ]] || { echo "shim target not yet on PATH: $package" >&2; return 1; }
|
|
1256
|
+
[[ -n "$target_path" ]] || { echo "ERROR shim target not yet on PATH: $package" >&2; return 1; }
|
|
1256
1257
|
content="#!/bin/sh
|
|
1257
1258
|
# Generated by global-tools -- do not edit.
|
|
1258
1259
|
exec '$target_path' \"\$@\"
|
|
@@ -1270,7 +1271,7 @@ exec '$target_path' \"\$@\"
|
|
|
1270
1271
|
alias_name="$(basename "$executable")"
|
|
1271
1272
|
resolved_alias="$(sudo -u "$administrator" -H env PATH="/opt/homebrew/bin:/home/linuxbrew/.linuxbrew/bin:/usr/local/bin:/usr/bin:/bin" /bin/sh -c "command -v '$alias_name'" 2>/dev/null || true)"
|
|
1272
1273
|
[[ "$resolved_alias" == "$executable" ]] || {
|
|
1273
|
-
echo "$tool_id shim written but not resolving from global PATH as '$alias_name' (got: ${resolved_alias:-nothing})" >&2
|
|
1274
|
+
echo "ERROR $tool_id shim written but not resolving from global PATH as '$alias_name' (got: ${resolved_alias:-nothing})" >&2
|
|
1274
1275
|
rc=1
|
|
1275
1276
|
}
|
|
1276
1277
|
return "$rc"
|
|
@@ -1316,16 +1317,16 @@ write_one_repo_script() {
|
|
|
1316
1317
|
source="$(jq -r --arg id "$tool_id" '.[$id].source' "$resolved_file")"
|
|
1317
1318
|
echo "ensure managed repo script: $tool_id (repo-script:$package -> $executable)"
|
|
1318
1319
|
[[ "$executable" =~ ^/usr/local/bin/[A-Za-z0-9][A-Za-z0-9._-]*$ ]] || {
|
|
1319
|
-
echo "unsafe managed script target: $executable" >&2
|
|
1320
|
+
echo "ERROR unsafe managed script target: $executable" >&2
|
|
1320
1321
|
return 1
|
|
1321
1322
|
}
|
|
1322
1323
|
[[ "$source" != /* && "$source" != *..* ]] || {
|
|
1323
|
-
echo "unsafe managed script source: $source" >&2
|
|
1324
|
+
echo "ERROR unsafe managed script source: $source" >&2
|
|
1324
1325
|
return 1
|
|
1325
1326
|
}
|
|
1326
1327
|
source_path="$repo_root/$source"
|
|
1327
1328
|
[[ -f "$source_path" && ! -L "$source_path" && -x "$source_path" ]] || {
|
|
1328
|
-
echo "managed script source must be an executable regular non-symlink file: $source_path" >&2
|
|
1329
|
+
echo "ERROR managed script source must be an executable regular non-symlink file: $source_path" >&2
|
|
1329
1330
|
return 1
|
|
1330
1331
|
}
|
|
1331
1332
|
if [[ "$mode" != apply ]]; then
|
|
@@ -1339,10 +1340,10 @@ write_one_repo_script() {
|
|
|
1339
1340
|
fi
|
|
1340
1341
|
return 0
|
|
1341
1342
|
fi
|
|
1342
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
1343
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
1343
1344
|
if [[ -e "$executable" || -L "$executable" ]]; then
|
|
1344
1345
|
is_managed_repo_script "$executable" || {
|
|
1345
|
-
echo "refusing to replace unmanaged or symlinked managed script target: $executable" >&2
|
|
1346
|
+
echo "ERROR refusing to replace unmanaged or symlinked managed script target: $executable" >&2
|
|
1346
1347
|
return 1
|
|
1347
1348
|
}
|
|
1348
1349
|
fi
|
|
@@ -1361,7 +1362,7 @@ write_one_repo_script() {
|
|
|
1361
1362
|
echo "backed up previous managed repo script to $repo_script_backup"
|
|
1362
1363
|
record_backup "$executable" "$repo_script_backup"
|
|
1363
1364
|
else
|
|
1364
|
-
echo "could not back up managed repo script before replacing it: $executable" >&2
|
|
1365
|
+
echo "ERROR could not back up managed repo script before replacing it: $executable" >&2
|
|
1365
1366
|
return 1
|
|
1366
1367
|
fi
|
|
1367
1368
|
fi
|
|
@@ -1371,7 +1372,7 @@ write_one_repo_script() {
|
|
|
1371
1372
|
alias_name="$(basename "$executable")"
|
|
1372
1373
|
resolved_alias="$(sudo -u "$administrator" -H env PATH="/usr/local/bin:/opt/homebrew/bin:/home/linuxbrew/.linuxbrew/bin:/usr/bin:/bin" /bin/sh -c 'command -v "$1"' sh "$alias_name" 2>/dev/null || true)"
|
|
1373
1374
|
[[ "$resolved_alias" == "$executable" ]] || {
|
|
1374
|
-
echo "$tool_id managed script installed but not resolving from global PATH as '$alias_name' (got: ${resolved_alias:-nothing})" >&2
|
|
1375
|
+
echo "ERROR $tool_id managed script installed but not resolving from global PATH as '$alias_name' (got: ${resolved_alias:-nothing})" >&2
|
|
1375
1376
|
rc=1
|
|
1376
1377
|
}
|
|
1377
1378
|
return "$rc"
|
|
@@ -1380,14 +1381,14 @@ write_one_repo_script() {
|
|
|
1380
1381
|
remove_one_repo_script() {
|
|
1381
1382
|
local executable="$1"
|
|
1382
1383
|
[[ "$executable" =~ ^/usr/local/bin/[A-Za-z0-9][A-Za-z0-9._-]*$ ]] || {
|
|
1383
|
-
echo "refusing unsafe managed script removal target: $executable" >&2
|
|
1384
|
+
echo "ERROR refusing unsafe managed script removal target: $executable" >&2
|
|
1384
1385
|
return 1
|
|
1385
1386
|
}
|
|
1386
1387
|
if [[ ! -e "$executable" && ! -L "$executable" ]]; then
|
|
1387
1388
|
return 0
|
|
1388
1389
|
fi
|
|
1389
1390
|
is_managed_repo_script "$executable" || {
|
|
1390
|
-
echo "refusing to remove unmanaged or symlinked managed script target: $executable" >&2
|
|
1391
|
+
echo "ERROR refusing to remove unmanaged or symlinked managed script target: $executable" >&2
|
|
1391
1392
|
return 1
|
|
1392
1393
|
}
|
|
1393
1394
|
rm -f -- "$executable"
|
|
@@ -1400,7 +1401,7 @@ repo_dir_source_hash() {
|
|
|
1400
1401
|
local source_dir="$1" hash
|
|
1401
1402
|
if repo_root_is_git; then
|
|
1402
1403
|
hash="$(repo_git rev-parse --verify --quiet "HEAD:$source_dir")" || {
|
|
1403
|
-
echo "repo-dir source is not tracked at HEAD: $source_dir" >&2
|
|
1404
|
+
echo "ERROR repo-dir source is not tracked at HEAD: $source_dir" >&2
|
|
1404
1405
|
return 1
|
|
1405
1406
|
}
|
|
1406
1407
|
else
|
|
@@ -1452,7 +1453,7 @@ managed_repo_dir_marker='.adl-managed-repo-dir'
|
|
|
1452
1453
|
# have to provide.
|
|
1453
1454
|
run_repo_dir_sync() {
|
|
1454
1455
|
local tool_id="$1" source="$2" build_dir="$3" npm_install="$4" bun_bin
|
|
1455
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
1456
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
1456
1457
|
if repo_root_is_git; then
|
|
1457
1458
|
repo_git archive "HEAD:$source" | tar -x -C "$build_dir"
|
|
1458
1459
|
else
|
|
@@ -1463,8 +1464,8 @@ run_repo_dir_sync() {
|
|
|
1463
1464
|
fi
|
|
1464
1465
|
if [[ "$npm_install" == true ]]; then
|
|
1465
1466
|
bun_bin="$(command -v bun || true)"
|
|
1466
|
-
[[ -n "$bun_bin" ]] || { echo "repo-dir $tool_id requires bun on PATH for npmInstall; ensure bun installs before this tool" >&2; return 1; }
|
|
1467
|
-
(cd "$build_dir" && "$bun_bin" install) || { echo "repo-dir $tool_id: bun install failed" >&2; return 1; }
|
|
1467
|
+
[[ -n "$bun_bin" ]] || { echo "ERROR repo-dir $tool_id requires bun on PATH for npmInstall; ensure bun installs before this tool" >&2; return 1; }
|
|
1468
|
+
(cd "$build_dir" && "$bun_bin" install) || { echo "ERROR repo-dir $tool_id: bun install failed" >&2; return 1; }
|
|
1468
1469
|
# agent-skills (the only npmInstall:true source today) ships no `dist/`
|
|
1469
1470
|
# in git -- every one of its script entry points imports from
|
|
1470
1471
|
# `../../dist/index.js` (confirmed empirically, all four: run-sync,
|
|
@@ -1474,7 +1475,7 @@ run_repo_dir_sync() {
|
|
|
1474
1475
|
# the package's own declared `build` script, exactly as a developer
|
|
1475
1476
|
# would, whenever the synced package.json has one.
|
|
1476
1477
|
if [[ "$(jq -r '.scripts.build // empty' "$build_dir/package.json" 2>/dev/null)" != "" ]]; then
|
|
1477
|
-
(cd "$build_dir" && "$bun_bin" run build) || { echo "repo-dir $tool_id: bun run build failed" >&2; return 1; }
|
|
1478
|
+
(cd "$build_dir" && "$bun_bin" run build) || { echo "ERROR repo-dir $tool_id: bun run build failed" >&2; return 1; }
|
|
1478
1479
|
fi
|
|
1479
1480
|
fi
|
|
1480
1481
|
}
|
|
@@ -1535,16 +1536,16 @@ write_one_repo_dir() {
|
|
|
1535
1536
|
npm_install="$(jq -r --arg id "$tool_id" '.[$id].npmInstall // false' "$resolved_file")"
|
|
1536
1537
|
echo "ensure repo dir: $tool_id (repo-dir:$package -> $target)"
|
|
1537
1538
|
[[ "$target" == "$repo_dir_libexec_root"/* ]] || {
|
|
1538
|
-
echo "unsafe repo-dir target: $target" >&2
|
|
1539
|
+
echo "ERROR unsafe repo-dir target: $target" >&2
|
|
1539
1540
|
return 1
|
|
1540
1541
|
}
|
|
1541
1542
|
[[ "$source" != /* && "$source" != *..* ]] || {
|
|
1542
|
-
echo "unsafe repo-dir source: $source" >&2
|
|
1543
|
+
echo "ERROR unsafe repo-dir source: $source" >&2
|
|
1543
1544
|
return 1
|
|
1544
1545
|
}
|
|
1545
1546
|
source_path="$repo_root/$source"
|
|
1546
1547
|
[[ -d "$source_path" ]] || {
|
|
1547
|
-
echo "repo-dir source missing: $source_path" >&2
|
|
1548
|
+
echo "ERROR repo-dir source missing: $source_path" >&2
|
|
1548
1549
|
return 1
|
|
1549
1550
|
}
|
|
1550
1551
|
source_hash="$(repo_dir_source_hash "$source")" || return 1
|
|
@@ -1588,7 +1589,7 @@ write_one_repo_dir() {
|
|
|
1588
1589
|
fi
|
|
1589
1590
|
fi
|
|
1590
1591
|
[[ -e "$target/$executable" ]] || {
|
|
1591
|
-
echo "$tool_id repo dir installed but entry missing: $target/$executable" >&2
|
|
1592
|
+
echo "ERROR $tool_id repo dir installed but entry missing: $target/$executable" >&2
|
|
1592
1593
|
rc=1
|
|
1593
1594
|
}
|
|
1594
1595
|
return "$rc"
|
|
@@ -1597,12 +1598,12 @@ write_one_repo_dir() {
|
|
|
1597
1598
|
remove_one_repo_dir() {
|
|
1598
1599
|
local target="$1"
|
|
1599
1600
|
[[ "$target" == "$repo_dir_libexec_root"/* ]] || {
|
|
1600
|
-
echo "refusing unsafe repo-dir removal target: $target" >&2
|
|
1601
|
+
echo "ERROR refusing unsafe repo-dir removal target: $target" >&2
|
|
1601
1602
|
return 1
|
|
1602
1603
|
}
|
|
1603
1604
|
[[ -e "$target" ]] || return 0
|
|
1604
1605
|
[[ -f "$target/$managed_repo_dir_marker" ]] || {
|
|
1605
|
-
echo "refusing to remove unmanaged repo dir: $target" >&2
|
|
1606
|
+
echo "ERROR refusing to remove unmanaged repo dir: $target" >&2
|
|
1606
1607
|
return 1
|
|
1607
1608
|
}
|
|
1608
1609
|
rm -rf -- "$target"
|
|
@@ -1683,7 +1684,7 @@ executable_claimed_by_current_manifest() {
|
|
|
1683
1684
|
remove_one_manifest_entry() {
|
|
1684
1685
|
local tool_id="$1" manager package executable removed_repo_dir_target
|
|
1685
1686
|
if jq -e --arg id "$tool_id" '.config.protected_tools | index($id)' "$manifest" >/dev/null; then
|
|
1686
|
-
echo "refusing to remove protected bootstrap tool: $tool_id" >&2
|
|
1687
|
+
echo "ERROR refusing to remove protected bootstrap tool: $tool_id" >&2
|
|
1687
1688
|
exit 1
|
|
1688
1689
|
fi
|
|
1689
1690
|
manager="$(jq -r --arg id "$tool_id" '.[$id].manager' "$previous_resolved_file")"
|
|
@@ -1735,7 +1736,7 @@ remove_one_manifest_entry() {
|
|
|
1735
1736
|
# state is read straight from disk, never re-validated.
|
|
1736
1737
|
release-archive)
|
|
1737
1738
|
[[ "$executable" == /usr/local/bin/* ]] || {
|
|
1738
|
-
echo "refusing unsafe release archive removal target: $executable" >&2
|
|
1739
|
+
echo "ERROR refusing unsafe release archive removal target: $executable" >&2
|
|
1739
1740
|
exit 1
|
|
1740
1741
|
}
|
|
1741
1742
|
if [[ "$mode" == apply ]]; then
|
|
@@ -1746,7 +1747,7 @@ remove_one_manifest_entry() {
|
|
|
1746
1747
|
;;
|
|
1747
1748
|
release-archive-latest)
|
|
1748
1749
|
[[ "$executable" == /usr/local/bin/* ]] || {
|
|
1749
|
-
echo "refusing unsafe release archive removal target: $executable" >&2
|
|
1750
|
+
echo "ERROR refusing unsafe release archive removal target: $executable" >&2
|
|
1750
1751
|
exit 1
|
|
1751
1752
|
}
|
|
1752
1753
|
if [[ "$mode" == apply ]]; then
|
|
@@ -1757,7 +1758,7 @@ remove_one_manifest_entry() {
|
|
|
1757
1758
|
;;
|
|
1758
1759
|
shim)
|
|
1759
1760
|
[[ "$executable" == /usr/local/bin/* ]] || {
|
|
1760
|
-
echo "refusing unsafe shim removal target: $executable" >&2
|
|
1761
|
+
echo "ERROR refusing unsafe shim removal target: $executable" >&2
|
|
1761
1762
|
exit 1
|
|
1762
1763
|
}
|
|
1763
1764
|
if [[ "$mode" == apply ]]; then
|
|
@@ -1771,7 +1772,7 @@ remove_one_manifest_entry() {
|
|
|
1771
1772
|
remove_one_repo_script "$executable"
|
|
1772
1773
|
else
|
|
1773
1774
|
[[ "$executable" =~ ^/usr/local/bin/[A-Za-z0-9][A-Za-z0-9._-]*$ ]] || {
|
|
1774
|
-
echo "refusing unsafe managed script removal target: $executable" >&2
|
|
1775
|
+
echo "ERROR refusing unsafe managed script removal target: $executable" >&2
|
|
1775
1776
|
exit 1
|
|
1776
1777
|
}
|
|
1777
1778
|
echo "would remove managed repo script: $executable"
|
|
@@ -1783,7 +1784,7 @@ remove_one_manifest_entry() {
|
|
|
1783
1784
|
remove_one_repo_dir "$removed_repo_dir_target"
|
|
1784
1785
|
else
|
|
1785
1786
|
[[ "$removed_repo_dir_target" == "$repo_dir_libexec_root"/* ]] || {
|
|
1786
|
-
echo "refusing unsafe repo-dir removal target: $removed_repo_dir_target" >&2
|
|
1787
|
+
echo "ERROR refusing unsafe repo-dir removal target: $removed_repo_dir_target" >&2
|
|
1787
1788
|
exit 1
|
|
1788
1789
|
}
|
|
1789
1790
|
echo "would remove repo dir: $removed_repo_dir_target"
|
|
@@ -1791,7 +1792,7 @@ remove_one_manifest_entry() {
|
|
|
1791
1792
|
;;
|
|
1792
1793
|
bun-compile)
|
|
1793
1794
|
[[ "$executable" == /usr/local/bin/* ]] || {
|
|
1794
|
-
echo "refusing unsafe bun binary removal target: $executable" >&2
|
|
1795
|
+
echo "ERROR refusing unsafe bun binary removal target: $executable" >&2
|
|
1795
1796
|
exit 1
|
|
1796
1797
|
}
|
|
1797
1798
|
if [[ "$mode" == apply ]]; then
|
|
@@ -1802,15 +1803,15 @@ remove_one_manifest_entry() {
|
|
|
1802
1803
|
;;
|
|
1803
1804
|
embedding-model)
|
|
1804
1805
|
if [[ "$mode" == apply ]]; then
|
|
1805
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
1806
|
-
command -v bun >/dev/null 2>&1 || { echo "embedding-model requires bun; ensure bun installs before this tool" >&2; exit 1; }
|
|
1806
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
1807
|
+
command -v bun >/dev/null 2>&1 || { echo "ERROR embedding-model requires bun; ensure bun installs before this tool" >&2; exit 1; }
|
|
1807
1808
|
(cd /tmp && sudo -u "$administrator" -H env PATH="${brew_bin%/*}:/usr/bin:/bin" \
|
|
1808
1809
|
bun "$repo_root/packages/fleet/src/install-embedding-model.ts" uninstall </dev/null)
|
|
1809
1810
|
else
|
|
1810
1811
|
echo "would remove embedding model cache: ~/.cache/adl-embedding/model (as $administrator)"
|
|
1811
1812
|
fi
|
|
1812
1813
|
;;
|
|
1813
|
-
*) echo "unsupported manager in previous manifest: $manager" >&2; exit 1 ;;
|
|
1814
|
+
*) echo "ERROR unsupported manager in previous manifest: $manager" >&2; exit 1 ;;
|
|
1814
1815
|
esac
|
|
1815
1816
|
}
|
|
1816
1817
|
|
|
@@ -1823,7 +1824,7 @@ remove_one_manifest_entry() {
|
|
|
1823
1824
|
# the LFS pre-push hook.
|
|
1824
1825
|
run_git_config_global() {
|
|
1825
1826
|
if [[ "$mode" == apply ]]; then
|
|
1826
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
1827
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
1827
1828
|
(cd /tmp && sudo -u "$git_config_user" -H git config --global "$@" </dev/null)
|
|
1828
1829
|
else
|
|
1829
1830
|
git config --global "$@" </dev/null
|
|
@@ -1848,7 +1849,7 @@ cleanup_legacy_linux_git_config() {
|
|
|
1848
1849
|
legacy_home="$(jq -r --arg device "$device" '.linux.devices[$device].brew_user_home // empty' "$applied_manifest")"
|
|
1849
1850
|
[[ -n "$legacy_user" && -n "$legacy_home" ]] || return 0
|
|
1850
1851
|
[[ "$legacy_home" == /* && "$legacy_home" != / ]] || {
|
|
1851
|
-
echo "invalid legacy per-user home in applied manifest: $legacy_home" >&2
|
|
1852
|
+
echo "ERROR invalid legacy per-user home in applied manifest: $legacy_home" >&2
|
|
1852
1853
|
return 1
|
|
1853
1854
|
}
|
|
1854
1855
|
config_file="$legacy_home/.gitconfig"
|
|
@@ -1862,7 +1863,7 @@ cleanup_legacy_linux_git_config() {
|
|
|
1862
1863
|
continue
|
|
1863
1864
|
fi
|
|
1864
1865
|
[[ "$rc" -eq 0 ]] || {
|
|
1865
|
-
echo "failed to inspect legacy global git config: $key in $config_file (exit $rc)" >&2
|
|
1866
|
+
echo "ERROR failed to inspect legacy global git config: $key in $config_file (exit $rc)" >&2
|
|
1866
1867
|
return "$rc"
|
|
1867
1868
|
}
|
|
1868
1869
|
if [[ "$mode" != apply ]]; then
|
|
@@ -1882,7 +1883,7 @@ git_global_config_value() {
|
|
|
1882
1883
|
if [[ "$rc" -eq 1 ]]; then
|
|
1883
1884
|
return 0
|
|
1884
1885
|
fi
|
|
1885
|
-
[[ "$rc" -eq 0 ]] || { echo "git config --global --get $key failed (exit $rc)" >&2; return "$rc"; }
|
|
1886
|
+
[[ "$rc" -eq 0 ]] || { echo "ERROR git config --global --get $key failed (exit $rc)" >&2; return "$rc"; }
|
|
1886
1887
|
printf '%s\n' "$value"
|
|
1887
1888
|
}
|
|
1888
1889
|
|
|
@@ -1931,7 +1932,7 @@ reconcile_git_global_config() {
|
|
|
1931
1932
|
# "bun: command not found" abort with no explanation.
|
|
1932
1933
|
require_bun_for_identity_files() {
|
|
1933
1934
|
command -v bun >/dev/null 2>&1 || {
|
|
1934
|
-
echo "global-tools: bun is required before default-agent-file/managed-settings; install bun first, then re-run reconcile" >&2
|
|
1935
|
+
echo "ERROR global-tools: bun is required before default-agent-file/managed-settings; install bun first, then re-run reconcile" >&2
|
|
1935
1936
|
return 1
|
|
1936
1937
|
}
|
|
1937
1938
|
}
|
|
@@ -2032,12 +2033,12 @@ reconcile_one_surface_cli() {
|
|
|
2032
2033
|
echo "would ensure Homebrew cask: $name (brew install --cask $name; brew upgrade --cask $name)"
|
|
2033
2034
|
return 0
|
|
2034
2035
|
fi
|
|
2035
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
2036
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
2036
2037
|
local installed_casks query_status=0 cask_action=() update_output update_status=0
|
|
2037
2038
|
installed_casks="$(brew_query list --cask --versions 2>&1)" || query_status=$?
|
|
2038
2039
|
if [[ "$query_status" -ne 0 ]]; then
|
|
2039
|
-
printf '%s\n' "$installed_casks" >&2
|
|
2040
|
-
echo "brew list --cask --versions failed for surface $name (exit $query_status)" >&2
|
|
2040
|
+
printf 'ERROR brew list --cask --versions output: %s\n' "$installed_casks" >&2
|
|
2041
|
+
echo "ERROR brew list --cask --versions failed for surface $name (exit $query_status)" >&2
|
|
2041
2042
|
return 1
|
|
2042
2043
|
fi
|
|
2043
2044
|
if awk -v cask="$name" '$1 == cask { found = 1 } END { exit !found }' <<<"$installed_casks"; then
|
|
@@ -2048,10 +2049,10 @@ reconcile_one_surface_cli() {
|
|
|
2048
2049
|
update_output="$(run_with_timeout "$SURFACE_UPDATE_TIMEOUT_SECONDS" run_brew ${cask_action[@]+"${cask_action[@]}"} 2>&1)" || update_status=$?
|
|
2049
2050
|
printf '%s\n' "$update_output"
|
|
2050
2051
|
if [[ "$update_status" -eq 124 ]]; then
|
|
2051
|
-
echo "surface update timed out: $name" >&2
|
|
2052
|
+
echo "ERROR surface update timed out: $name" >&2
|
|
2052
2053
|
return 1
|
|
2053
2054
|
elif [[ "$update_status" -ne 0 ]]; then
|
|
2054
|
-
echo "surface update failed: $name (exit $update_status)" >&2
|
|
2055
|
+
echo "ERROR surface update failed: $name (exit $update_status)" >&2
|
|
2055
2056
|
return 1
|
|
2056
2057
|
fi
|
|
2057
2058
|
# Same broadened check as the native/npm path below (independent
|
|
@@ -2068,9 +2069,9 @@ reconcile_one_surface_cli() {
|
|
|
2068
2069
|
# coordinator pass, 2026-09-30): the same `cask_action[0]` that already
|
|
2069
2070
|
# picks the real brew argv above also names which one failed.
|
|
2070
2071
|
if [[ "${cask_action[0]}" == install ]]; then
|
|
2071
|
-
echo "surface $name: cask install failed ($update_error_line)" >&2
|
|
2072
|
+
echo "ERROR surface $name: cask install failed ($update_error_line)" >&2
|
|
2072
2073
|
else
|
|
2073
|
-
echo "surface $name: cask upgrade failed ($update_error_line)" >&2
|
|
2074
|
+
echo "ERROR surface $name: cask upgrade failed ($update_error_line)" >&2
|
|
2074
2075
|
fi
|
|
2075
2076
|
return 1
|
|
2076
2077
|
fi
|
|
@@ -2089,7 +2090,7 @@ reconcile_one_surface_cli() {
|
|
|
2089
2090
|
fi
|
|
2090
2091
|
return 0
|
|
2091
2092
|
fi
|
|
2092
|
-
[[ "$(id -u)" -eq 0 ]] || { echo "apply mode must run as root" >&2; exit 1; }
|
|
2093
|
+
[[ "$(id -u)" -eq 0 ]] || { echo "ERROR apply mode must run as root" >&2; exit 1; }
|
|
2093
2094
|
local resolved
|
|
2094
2095
|
resolved="$(resolve_surface_executable "$command_name" "$executable_override")"
|
|
2095
2096
|
if [[ -z "$resolved" ]]; then
|
|
@@ -2107,10 +2108,10 @@ reconcile_one_surface_cli() {
|
|
|
2107
2108
|
update_output="$(run_with_timeout "$SURFACE_UPDATE_TIMEOUT_SECONDS" run_surface_update "$resolved" ${update_args[@]+"${update_args[@]}"} 2>&1)" || update_status=$?
|
|
2108
2109
|
printf '%s\n' "$update_output"
|
|
2109
2110
|
if [[ "$update_status" -eq 124 ]]; then
|
|
2110
|
-
echo "surface update timed out: $name" >&2
|
|
2111
|
+
echo "ERROR surface update timed out: $name" >&2
|
|
2111
2112
|
return 1
|
|
2112
2113
|
elif [[ "$update_status" -ne 0 ]]; then
|
|
2113
|
-
echo "surface update failed: $name (exit $update_status)" >&2
|
|
2114
|
+
echo "ERROR surface update failed: $name (exit $update_status)" >&2
|
|
2114
2115
|
return 1
|
|
2115
2116
|
fi
|
|
2116
2117
|
# A surface's update command can exit 0 while its own output says the
|
|
@@ -2139,7 +2140,7 @@ reconcile_one_surface_cli() {
|
|
|
2139
2140
|
new_version="$(surface_cli_version "$resolved")"
|
|
2140
2141
|
update_error_line="$(surface_update_error_reason "$update_output")"
|
|
2141
2142
|
if [[ -z "$new_version" ]]; then
|
|
2142
|
-
echo "surface $name: update ran but version unreadable (${update_error_line:-"--version produced no output"}); was ${old_version:-unknown}" >&2
|
|
2143
|
+
echo "WARN surface $name: update ran but version unreadable (${update_error_line:-"--version produced no output"}); was ${old_version:-unknown}" >&2
|
|
2143
2144
|
return 1
|
|
2144
2145
|
fi
|
|
2145
2146
|
if [[ "$old_version" != "$new_version" ]]; then
|
|
@@ -2151,7 +2152,7 @@ reconcile_one_surface_cli() {
|
|
|
2151
2152
|
return 0
|
|
2152
2153
|
fi
|
|
2153
2154
|
if [[ -n "$update_error_line" ]]; then
|
|
2154
|
-
echo "surface $name: update check failed ($update_error_line); kept ${old_version:-unknown}" >&2
|
|
2155
|
+
echo "WARN surface $name: update check failed ($update_error_line); kept ${old_version:-unknown}" >&2
|
|
2155
2156
|
return 1
|
|
2156
2157
|
fi
|
|
2157
2158
|
echo "surface $name: already latest ($new_version)"
|
|
@@ -2159,7 +2160,7 @@ reconcile_one_surface_cli() {
|
|
|
2159
2160
|
}
|
|
2160
2161
|
|
|
2161
2162
|
# Loops over this device's declared surface_clis (absent or empty -> silently
|
|
2162
|
-
# does nothing, same convention as
|
|
2163
|
+
# does nothing, same convention as scratch_repos). A failure is
|
|
2163
2164
|
# collected into failed_tools by id "surface-<name>", exactly like every other
|
|
2164
2165
|
# apply-mode step's continue-on-failure contract in this file.
|
|
2165
2166
|
reconcile_surface_clis() {
|
|
@@ -2185,12 +2186,78 @@ reconcile_surface_clis() {
|
|
|
2185
2186
|
done < <(jq -r --argjson i "$i" --arg platform "$platform" --arg device "$device" \
|
|
2186
2187
|
'.[$platform].devices[$device].surface_clis[$i].update_args // [] | .[]' "$manifest")
|
|
2187
2188
|
if ! reconcile_one_surface_cli "$name" "$command_name" "$executable_override" "$report_only" "$manager" ${update_args[@]+"${update_args[@]}"}; then
|
|
2188
|
-
echo "global-tools: TOOL INSTALL FAILED: surface-$name" >&2
|
|
2189
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: surface-$name" >&2
|
|
2189
2190
|
failed_tools+=("surface-$name")
|
|
2190
2191
|
fi
|
|
2191
2192
|
done
|
|
2192
2193
|
}
|
|
2193
2194
|
|
|
2195
|
+
# retire_git_maintain (2026-09-30, Tarun: "one binary controlling everything"):
|
|
2196
|
+
# the git-maintain user LaunchAgent (com.adl.git-maintain) and its compiled
|
|
2197
|
+
# binary are retired; repository maintenance is `adl reconcile`'s own step
|
|
2198
|
+
# (bin/reconcile-host -> `adl maintain`). M3 and M5 already have the agent
|
|
2199
|
+
# installed and loaded, so this cleans it up actively rather than leaving a
|
|
2200
|
+
# job that scans ~/Documents on its own timer:
|
|
2201
|
+
# - boot out gui/<administrator uid>/com.adl.git-maintain if loaded, and fail
|
|
2202
|
+
# loud if it is still loaded afterwards (nothing is moved in that case);
|
|
2203
|
+
# - move the plist, the compiled binary and its source-hash marker ASIDE
|
|
2204
|
+
# (never deleted) under <state dir>/retired-git-maintain/<UTC stamp>/,
|
|
2205
|
+
# logging each one.
|
|
2206
|
+
# Already gone means no change and no output; plan/audit only list what they
|
|
2207
|
+
# would do; Linux never had it. Returns non-zero (after an ERROR line) on a
|
|
2208
|
+
# failure; the caller records it like any other failed step.
|
|
2209
|
+
retire_git_maintain() {
|
|
2210
|
+
[[ "$platform" == mac ]] || return 0
|
|
2211
|
+
local label=com.adl.git-maintain uid loaded=0 path aside
|
|
2212
|
+
local leftovers=()
|
|
2213
|
+
local agent_plist="$administrator_home/Library/LaunchAgents/$label.plist"
|
|
2214
|
+
local binary="$repo_dir_libexec_root/git-maintain"
|
|
2215
|
+
local hash_marker="$state_dir/launch-agents/git-maintain.source-hash"
|
|
2216
|
+
|
|
2217
|
+
if uid="$(id -u "$administrator" 2>/dev/null)"; then
|
|
2218
|
+
if launchctl print "gui/$uid/$label" >/dev/null 2>&1; then loaded=1; fi
|
|
2219
|
+
elif [[ "$mode" == apply ]]; then
|
|
2220
|
+
echo "ERROR global-tools: cannot resolve the uid of $administrator to retire git-maintain" >&2
|
|
2221
|
+
return 1
|
|
2222
|
+
else
|
|
2223
|
+
# plan/audit on a machine without that account (a test, a preview): the
|
|
2224
|
+
# leftover files can still be listed, but there is nothing to ask launchd.
|
|
2225
|
+
uid="<uid of $administrator>"
|
|
2226
|
+
fi
|
|
2227
|
+
for path in "$agent_plist" "$binary" "$hash_marker"; do
|
|
2228
|
+
if [[ -e "$path" || -L "$path" ]]; then leftovers+=("$path"); fi
|
|
2229
|
+
done
|
|
2230
|
+
if [[ "$loaded" -eq 0 && "${#leftovers[@]}" -eq 0 ]]; then return 0; fi
|
|
2231
|
+
|
|
2232
|
+
if [[ "$mode" != apply ]]; then
|
|
2233
|
+
if [[ "$loaded" -eq 1 ]]; then echo "global-tools: would retire git-maintain: boot out gui/$uid/$label"; fi
|
|
2234
|
+
for path in ${leftovers[@]+"${leftovers[@]}"}; do
|
|
2235
|
+
echo "global-tools: would retire git-maintain: move $path aside"
|
|
2236
|
+
done
|
|
2237
|
+
return 0
|
|
2238
|
+
fi
|
|
2239
|
+
|
|
2240
|
+
if [[ "$loaded" -eq 1 ]]; then
|
|
2241
|
+
if ! launchctl bootout "gui/$uid/$label"; then
|
|
2242
|
+
echo "ERROR global-tools: could not boot out gui/$uid/$label; git-maintain is not retired" >&2
|
|
2243
|
+
return 1
|
|
2244
|
+
fi
|
|
2245
|
+
if launchctl print "gui/$uid/$label" >/dev/null 2>&1; then
|
|
2246
|
+
echo "ERROR global-tools: gui/$uid/$label is still loaded after bootout; git-maintain is not retired" >&2
|
|
2247
|
+
return 1
|
|
2248
|
+
fi
|
|
2249
|
+
echo "global-tools: retiring git-maintain: booted out gui/$uid/$label"
|
|
2250
|
+
fi
|
|
2251
|
+
if [[ "${#leftovers[@]}" -gt 0 ]]; then
|
|
2252
|
+
aside="$state_dir/retired-git-maintain/$(date -u +%Y%m%dT%H%M%SZ)"
|
|
2253
|
+
mkdir -p -- "$aside"
|
|
2254
|
+
for path in "${leftovers[@]}"; do
|
|
2255
|
+
mv -- "$path" "$aside/" || { echo "ERROR global-tools: could not move $path aside to $aside" >&2; return 1; }
|
|
2256
|
+
echo "global-tools: retiring git-maintain: moved $path aside to $aside"
|
|
2257
|
+
done
|
|
2258
|
+
fi
|
|
2259
|
+
}
|
|
2260
|
+
|
|
2194
2261
|
# Test-only escape hatch: source this script with RECONCILE_SOURCE_ONLY=1 to
|
|
2195
2262
|
# load every function definition above (and the arg-parsing / manifest
|
|
2196
2263
|
# validation / platform-and-tool-resolution state already computed by this
|
|
@@ -2215,7 +2282,7 @@ scratch_reap_failed=0
|
|
|
2215
2282
|
available_kib="$(df -Pk / | awk 'NR == 2 {print $4}')"
|
|
2216
2283
|
required_kib="$((minimum_free_gib * 1024 * 1024))"
|
|
2217
2284
|
if [[ "$available_kib" -lt "$required_kib" ]]; then
|
|
2218
|
-
echo "global-tools: only $((available_kib / 1024 / 1024)) GiB free; $minimum_free_gib GiB required" >&2
|
|
2285
|
+
echo "ERROR global-tools: only $((available_kib / 1024 / 1024)) GiB free; $minimum_free_gib GiB required" >&2
|
|
2219
2286
|
[[ "$mode" != apply ]] || exit 1
|
|
2220
2287
|
fi
|
|
2221
2288
|
|
|
@@ -2224,7 +2291,7 @@ if [[ "$mode" == apply ]]; then
|
|
|
2224
2291
|
fi
|
|
2225
2292
|
|
|
2226
2293
|
if ! install_surface_policy_file; then
|
|
2227
|
-
echo "global-tools: TOOL INSTALL FAILED: surface-policy-file" >&2
|
|
2294
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: surface-policy-file" >&2
|
|
2228
2295
|
failed_tools+=("surface-policy-file")
|
|
2229
2296
|
fi
|
|
2230
2297
|
|
|
@@ -2235,7 +2302,7 @@ require_bun_for_identity_files || exit 1
|
|
|
2235
2302
|
# below that could read it (kimi-hooks resolves adl the same way; this
|
|
2236
2303
|
# is the identity every consumer -- `adl run`, the managed-settings render
|
|
2237
2304
|
# below, and host automation's git-ado call -- reads instead of its own
|
|
2238
|
-
# copy). Runs for real in plan mode too (like
|
|
2305
|
+
# copy). Runs for real in plan mode too (like the other plan-safe steps): default-agent-file.ts's
|
|
2239
2306
|
# own --mode plan never writes, so this is safe to run unconditionally.
|
|
2240
2307
|
default_agent="$(jq -r --arg platform "$platform" --arg device "$device" '.[$platform].devices[$device].default_agent' "$manifest")"
|
|
2241
2308
|
if [[ "$mode" != apply ]]; then
|
|
@@ -2244,7 +2311,7 @@ if [[ "$mode" != apply ]]; then
|
|
|
2244
2311
|
else
|
|
2245
2312
|
echo "global-tools: default-agent file mode=apply device=$device -> $default_agent"
|
|
2246
2313
|
if ! bun "$repo_root/packages/fleet/src/default-agent-file.ts" --agent "$default_agent" --platform "$platform" --mode apply ${reconcile_test_system_root_args[@]+"${reconcile_test_system_root_args[@]}"}; then
|
|
2247
|
-
echo "global-tools: TOOL INSTALL FAILED: default-agent-file" >&2
|
|
2314
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: default-agent-file" >&2
|
|
2248
2315
|
failed_tools+=("default-agent-file")
|
|
2249
2316
|
fi
|
|
2250
2317
|
fi
|
|
@@ -2261,7 +2328,7 @@ if [[ "$mode" != apply ]]; then
|
|
|
2261
2328
|
else
|
|
2262
2329
|
echo "global-tools: managed settings mode=apply device=$device -> $default_agent"
|
|
2263
2330
|
if ! bun "$repo_root/packages/fleet/src/managed-settings.ts" --agent "$default_agent" --platform "$platform" --mode apply ${reconcile_test_system_root_args[@]+"${reconcile_test_system_root_args[@]}"}; then
|
|
2264
|
-
echo "global-tools: TOOL INSTALL FAILED: managed-settings" >&2
|
|
2331
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: managed-settings" >&2
|
|
2265
2332
|
failed_tools+=("managed-settings")
|
|
2266
2333
|
fi
|
|
2267
2334
|
fi
|
|
@@ -2282,7 +2349,7 @@ if jq -e 'to_entries | any(.value.manager == "brew")' "$resolved_file" >/dev/nul
|
|
|
2282
2349
|
brew_upgrade_all="$(jq -r --arg platform "$platform" --arg device "$device" '.[$platform].devices[$device].brew_upgrade_all // false' "$manifest")"
|
|
2283
2350
|
if [[ "$brew_upgrade_all" == true ]]; then
|
|
2284
2351
|
if ! run_brew_upgrade_all; then
|
|
2285
|
-
echo "global-tools: TOOL INSTALL FAILED: brew-upgrade-all" >&2
|
|
2352
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: brew-upgrade-all" >&2
|
|
2286
2353
|
failed_tools+=("brew-upgrade-all")
|
|
2287
2354
|
fi
|
|
2288
2355
|
fi
|
|
@@ -2295,7 +2362,7 @@ fi
|
|
|
2295
2362
|
|
|
2296
2363
|
while IFS= read -r tool_id; do
|
|
2297
2364
|
if ! install_one_tool "$tool_id"; then
|
|
2298
|
-
echo "global-tools: TOOL INSTALL FAILED: $tool_id" >&2
|
|
2365
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: $tool_id" >&2
|
|
2299
2366
|
failed_tools+=("$tool_id")
|
|
2300
2367
|
fi
|
|
2301
2368
|
done < <(jq -r 'to_entries[] | select(.value.manager != "shim" and .value.manager != "repo-script" and .value.manager != "repo-dir" and .value.manager != "bun-compile" and .value.manager != "embedding-model") | .key' "$resolved_file")
|
|
@@ -2310,28 +2377,28 @@ fi
|
|
|
2310
2377
|
|
|
2311
2378
|
while IFS= read -r tool_id; do
|
|
2312
2379
|
if ! build_one_bun_tool "$tool_id"; then
|
|
2313
|
-
echo "global-tools: TOOL INSTALL FAILED: $tool_id" >&2
|
|
2380
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: $tool_id" >&2
|
|
2314
2381
|
failed_tools+=("$tool_id")
|
|
2315
2382
|
fi
|
|
2316
2383
|
done < <(jq -r 'to_entries[] | select(.value.manager == "bun-compile") | .key' "$resolved_file")
|
|
2317
2384
|
|
|
2318
2385
|
while IFS= read -r tool_id; do
|
|
2319
2386
|
if ! install_one_embedding_model_tool "$tool_id"; then
|
|
2320
|
-
echo "global-tools: TOOL INSTALL FAILED: $tool_id" >&2
|
|
2387
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: $tool_id" >&2
|
|
2321
2388
|
failed_tools+=("$tool_id")
|
|
2322
2389
|
fi
|
|
2323
2390
|
done < <(jq -r 'to_entries[] | select(.value.manager == "embedding-model") | .key' "$resolved_file")
|
|
2324
2391
|
|
|
2325
2392
|
while IFS= read -r tool_id; do
|
|
2326
2393
|
if ! write_one_shim "$tool_id"; then
|
|
2327
|
-
echo "global-tools: TOOL INSTALL FAILED: $tool_id" >&2
|
|
2394
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: $tool_id" >&2
|
|
2328
2395
|
failed_tools+=("$tool_id")
|
|
2329
2396
|
fi
|
|
2330
2397
|
done < <(jq -r 'to_entries[] | select(.value.manager == "shim") | .key' "$resolved_file")
|
|
2331
2398
|
|
|
2332
2399
|
while IFS= read -r tool_id; do
|
|
2333
2400
|
if ! write_one_repo_script "$tool_id"; then
|
|
2334
|
-
echo "global-tools: TOOL INSTALL FAILED: $tool_id" >&2
|
|
2401
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: $tool_id" >&2
|
|
2335
2402
|
failed_tools+=("$tool_id")
|
|
2336
2403
|
fi
|
|
2337
2404
|
done < <(jq -r 'to_entries[] | select(.value.manager == "repo-script") | .key' "$resolved_file")
|
|
@@ -2426,7 +2493,7 @@ fi
|
|
|
2426
2493
|
|
|
2427
2494
|
while IFS= read -r tool_id; do
|
|
2428
2495
|
if ! write_one_repo_dir "$tool_id"; then
|
|
2429
|
-
echo "global-tools: TOOL INSTALL FAILED: $tool_id" >&2
|
|
2496
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: $tool_id" >&2
|
|
2430
2497
|
failed_tools+=("$tool_id")
|
|
2431
2498
|
fi
|
|
2432
2499
|
done < <(jq -r 'to_entries[] | select(.value.manager == "repo-dir") | .key' "$resolved_file")
|
|
@@ -2466,12 +2533,12 @@ project_adl_package_payload() {
|
|
|
2466
2533
|
local adl_package bun_bin
|
|
2467
2534
|
adl_package="$(jq -r '.adl.package // empty' "$resolved_file")"
|
|
2468
2535
|
[[ "$adl_package" == @amsterdamdatalabs/adl-agent-control ]] || {
|
|
2469
|
-
echo "Adl package projection requires the published wrapper entry" >&2
|
|
2536
|
+
echo "ERROR Adl package projection requires the published wrapper entry" >&2
|
|
2470
2537
|
return 1
|
|
2471
2538
|
}
|
|
2472
2539
|
for failed_tool in ${failed_tools[@]+"${failed_tools[@]}"}; do
|
|
2473
2540
|
if [[ "$failed_tool" == adl ]]; then
|
|
2474
|
-
echo "skipping Adl payload projection because Adl source verification failed" >&2
|
|
2541
|
+
echo "WARN skipping Adl payload projection because Adl source verification failed" >&2
|
|
2475
2542
|
return 1
|
|
2476
2543
|
fi
|
|
2477
2544
|
done
|
|
@@ -2483,10 +2550,10 @@ project_adl_package_payload() {
|
|
|
2483
2550
|
return 0
|
|
2484
2551
|
fi
|
|
2485
2552
|
bun_bin="$(command -v bun || true)"
|
|
2486
|
-
[[ -n "$bun_bin" ]] || { echo "Adl package projection requires bun on PATH" >&2; return 1; }
|
|
2553
|
+
[[ -n "$bun_bin" ]] || { echo "ERROR Adl package projection requires bun on PATH" >&2; return 1; }
|
|
2487
2554
|
if [[ "$source_mode" == checkout ]]; then
|
|
2488
2555
|
(cd "$repo_root/packages/agent-skills" && "$bun_bin" run build) || {
|
|
2489
|
-
echo "could not build agent-skills payload from checkout" >&2
|
|
2556
|
+
echo "ERROR could not build agent-skills payload from checkout" >&2
|
|
2490
2557
|
return 1
|
|
2491
2558
|
}
|
|
2492
2559
|
fi
|
|
@@ -2499,50 +2566,33 @@ project_adl_package_payload() {
|
|
|
2499
2566
|
}
|
|
2500
2567
|
|
|
2501
2568
|
if ! project_adl_package_payload; then
|
|
2502
|
-
echo "global-tools: TOOL INSTALL FAILED: adl-package-projection" >&2
|
|
2569
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: adl-package-projection" >&2
|
|
2503
2570
|
failed_tools+=("adl-package-projection")
|
|
2504
2571
|
fi
|
|
2505
2572
|
|
|
2506
2573
|
# Same continue-on-failure contract as the tool passes above: runs after git
|
|
2507
2574
|
# itself is installed/upgraded, and a failure is recorded, not fatal.
|
|
2508
2575
|
if ! "$repo_root/bin/shell-path-policy" --home "$administrator_home" --platform "$platform" --mode "$mode" --owner "$administrator"; then
|
|
2509
|
-
echo "global-tools: TOOL INSTALL FAILED: shell-path-policy" >&2
|
|
2576
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: shell-path-policy" >&2
|
|
2510
2577
|
failed_tools+=("shell-path-policy")
|
|
2511
2578
|
fi
|
|
2512
2579
|
|
|
2513
2580
|
if ! reconcile_git_global_config; then
|
|
2514
|
-
echo "global-tools: TOOL INSTALL FAILED: git-global-config" >&2
|
|
2581
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: git-global-config" >&2
|
|
2515
2582
|
failed_tools+=("git-global-config")
|
|
2516
2583
|
fi
|
|
2517
2584
|
cleanup_legacy_linux_git_config || {
|
|
2518
|
-
echo "global-tools: legacy Linux git config cleanup failed" >&2
|
|
2585
|
+
echo "ERROR global-tools: legacy Linux git config cleanup failed" >&2
|
|
2519
2586
|
exit 1
|
|
2520
2587
|
}
|
|
2521
2588
|
|
|
2522
|
-
#
|
|
2523
|
-
#
|
|
2524
|
-
#
|
|
2525
|
-
#
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
# continue-on-failure contract as the tool passes above.
|
|
2530
|
-
if [[ "$platform" == mac ]] && jq -e --arg device "$device" \
|
|
2531
|
-
'((.mac.common.launch_agents // {}) + (.mac.devices[$device].launch_agents // {})) | length > 0' "$manifest" >/dev/null; then
|
|
2532
|
-
launch_agents_args=(--manifest "$manifest" --platform "$platform" --device "$device" --home "$administrator_home" --state-dir "$state_dir")
|
|
2533
|
-
if [[ "$have_previous" -eq 1 ]]; then
|
|
2534
|
-
launch_agents_args+=(--previous-manifest "$applied_manifest")
|
|
2535
|
-
fi
|
|
2536
|
-
if [[ "$mode" == apply ]]; then
|
|
2537
|
-
echo "global-tools: launch agents mode=apply home=$administrator_home (for $administrator)"
|
|
2538
|
-
if ! bun "$repo_root/packages/fleet/src/launch-agents.ts" --mode apply "${launch_agents_args[@]}"; then
|
|
2539
|
-
echo "global-tools: TOOL INSTALL FAILED: launch-agents" >&2
|
|
2540
|
-
failed_tools+=("launch-agents")
|
|
2541
|
-
fi
|
|
2542
|
-
else
|
|
2543
|
-
echo "global-tools: launch agents mode=plan home=$administrator_home"
|
|
2544
|
-
bun "$repo_root/packages/fleet/src/launch-agents.ts" --mode plan "${launch_agents_args[@]}"
|
|
2545
|
-
fi
|
|
2589
|
+
# git-maintain is retired: clean it up where it is still installed (mac), ahead
|
|
2590
|
+
# of the global surface sweep, which would otherwise see its leftover
|
|
2591
|
+
# LaunchAgent as an approval-gated candidate. Same continue-on-failure
|
|
2592
|
+
# contract as the tool passes above.
|
|
2593
|
+
if ! retire_git_maintain; then
|
|
2594
|
+
echo "ERROR global-tools: TOOL INSTALL FAILED: git-maintain-retire" >&2
|
|
2595
|
+
failed_tools+=("git-maintain-retire")
|
|
2546
2596
|
fi
|
|
2547
2597
|
|
|
2548
2598
|
if [[ "$mode" == apply ]]; then
|
|
@@ -2608,11 +2658,11 @@ if [[ "$kimi_hooks_enabled" == true ]]; then
|
|
|
2608
2658
|
# shim: there is no standalone hook executable to resolve any more.
|
|
2609
2659
|
adl_executable="$(jq -r '."adl".executable' "$resolved_file")"
|
|
2610
2660
|
if ! adl_resolved="$(sudo -u "$administrator" -H env PATH="/opt/homebrew/bin:/home/linuxbrew/.linuxbrew/bin:/usr/local/bin:/usr/bin:/bin" /bin/sh -c "command -v '$adl_executable'" 2>/dev/null)"; then
|
|
2611
|
-
echo "global-tools: could not resolve adl from the administrator PATH" >&2
|
|
2661
|
+
echo "ERROR global-tools: could not resolve adl from the administrator PATH" >&2
|
|
2612
2662
|
exit 1
|
|
2613
2663
|
fi
|
|
2614
2664
|
[[ -n "$adl_resolved" && -x "$adl_resolved" ]] || {
|
|
2615
|
-
echo "global-tools: kimi-hooks requires adl on PATH ($adl_executable); bun-compile installation must succeed first" >&2
|
|
2665
|
+
echo "ERROR global-tools: kimi-hooks requires adl on PATH ($adl_executable); bun-compile installation must succeed first" >&2
|
|
2616
2666
|
exit 1
|
|
2617
2667
|
}
|
|
2618
2668
|
echo "global-tools: kimi hooks mode=apply home=$administrator_home (as $administrator)"
|
|
@@ -2764,14 +2814,14 @@ fi
|
|
|
2764
2814
|
if [[ "$mode" == apply ]]; then
|
|
2765
2815
|
if repo_root_is_git; then
|
|
2766
2816
|
applied_commit="$(sudo -u "$administrator" -H git -C "$repo_root" rev-parse HEAD)" || {
|
|
2767
|
-
echo "could not resolve checkout commit for applied manifest identity" >&2
|
|
2817
|
+
echo "ERROR could not resolve checkout commit for applied manifest identity" >&2
|
|
2768
2818
|
exit 1
|
|
2769
2819
|
}
|
|
2770
2820
|
else
|
|
2771
2821
|
# az374: the installed npm package's own version is the identity of what
|
|
2772
2822
|
# was applied -- there is no commit to ask for.
|
|
2773
2823
|
applied_npm_version="$(jq -er '.version | select(type == "string" and length > 0)' "$repo_root/package.json")" || {
|
|
2774
|
-
echo "installed Adl package has no valid version: $repo_root/package.json" >&2
|
|
2824
|
+
echo "ERROR installed Adl package has no valid version: $repo_root/package.json" >&2
|
|
2775
2825
|
exit 1
|
|
2776
2826
|
}
|
|
2777
2827
|
applied_commit="npm:$applied_npm_version"
|
|
@@ -2785,83 +2835,6 @@ else
|
|
|
2785
2835
|
echo "global-tools: $mode complete; no state changed"
|
|
2786
2836
|
fi
|
|
2787
2837
|
|
|
2788
|
-
# git_maintain_repos (2026-09-30, arm-only decision the same day): an
|
|
2789
|
-
# explicit, closed list of repositories this device's own checkout lives
|
|
2790
|
-
# at OUTSIDE any recursively-scanned home directory -- the Linux VPSes'
|
|
2791
|
-
# root-owned /opt/adl-azdo is the confirmed case for both strato-vps-1 and
|
|
2792
|
-
# hostinger-vps-1 (STATUS.md's 2026-09-29 first-deployment record;
|
|
2793
|
-
# hostinger's own fleet-cutover --apply landed 2026-09-29T23:43Z, confirmed
|
|
2794
|
-
# the same day). git-maintain's own scheduling (packages/fleet/src/
|
|
2795
|
-
# launch-agents.ts: a dedicated compiled binary, ad-hoc signed, run by a
|
|
2796
|
-
# launchd LaunchAgent under TCC) is macOS-only by construction, so it never
|
|
2797
|
-
# reaches these checkouts on its own. This runs the job directly, on
|
|
2798
|
-
# reconcile's own schedule (every platform this script runs on already has
|
|
2799
|
-
# one), passing each declared path as `--repo` argv -- never a recursive
|
|
2800
|
-
# scan of a shared parent like `/opt` (which also holds unrelated,
|
|
2801
|
-
# explicitly off-limits directories), and never a new environment
|
|
2802
|
-
# variable: the list itself comes only from the manifest, and
|
|
2803
|
-
# GIT_MAINTAIN_DRY below is this job's own pre-existing dry/real contract,
|
|
2804
|
-
# driven by reconcile's own --mode exactly like every other step in this
|
|
2805
|
-
# file, not a knob an operator sets by hand. Absent or empty (every mac
|
|
2806
|
-
# device today) is a silent no-op, the same convention
|
|
2807
|
-
# launch_agents/scratch_repos/surface_clis already use.
|
|
2808
|
-
#
|
|
2809
|
-
# ARM-ONLY, always, on this path (independent review, 2026-09-30): the full
|
|
2810
|
-
# job on this SAME checkout `bin/reconcile` runs from turned out to be new,
|
|
2811
|
-
# unapproved, root-run behaviour once actually reasoned through, not merely
|
|
2812
|
-
# a self-checkout read/write ordering hazard -- see the `--arm-only`
|
|
2813
|
-
# decision recorded in jobs/git-maintain/src/main.ts's own header comment
|
|
2814
|
-
# for the full list (a silent fast-forward-driven auto-deploy of
|
|
2815
|
-
# `origin/integration`/main with no approval gate, colliding with
|
|
2816
|
-
# fleet-cutover.sh re-reading fleet-retire-list.json from this same
|
|
2817
|
-
# checkout after reconcile runs, `git branch -D` as root, and a fetch that
|
|
2818
|
-
# still runs even in dry/plan/audit mode and exits 0 on its own failure).
|
|
2819
|
-
# `--arm-only` narrows this call to ONLY `armHooks`: no fetch, no
|
|
2820
|
-
# fast-forward, no branch prune, no bundle-refresh installer, no network,
|
|
2821
|
-
# and no Azure DevOps identity resolution. The only remaining write is
|
|
2822
|
-
# `.git/config`'s `core.hooksPath`, real only in apply mode
|
|
2823
|
-
# (GIT_MAINTAIN_DRY=1 below makes it a `[dry] would arm ...` log line and
|
|
2824
|
-
# nothing else, in both plan AND audit mode). That is never a tracked file
|
|
2825
|
-
# this script (or anything downstream of it) reads, so arm-only has no
|
|
2826
|
-
# self-checkout read/write ordering hazard left to avoid -- this step stays
|
|
2827
|
-
# in this late position anyway, unchanged from the full-job version: it is
|
|
2828
|
-
# still the simplest place for it, and there is no reason to special-case
|
|
2829
|
-
# arm-only's position just because its own hazard is gone.
|
|
2830
|
-
git_maintain_repos=()
|
|
2831
|
-
while IFS= read -r repo; do
|
|
2832
|
-
[[ -n "$repo" ]] && git_maintain_repos+=("$repo")
|
|
2833
|
-
done < <(jq -r --arg platform "$platform" --arg device "$device" \
|
|
2834
|
-
'.[$platform].devices[$device].git_maintain_repos // [] | .[]' "$manifest")
|
|
2835
|
-
if [[ "${#git_maintain_repos[@]}" -gt 0 ]]; then
|
|
2836
|
-
git_maintain_repo_args=(--arm-only)
|
|
2837
|
-
for repo in "${git_maintain_repos[@]}"; do
|
|
2838
|
-
git_maintain_repo_args+=(--repo "$repo")
|
|
2839
|
-
done
|
|
2840
|
-
# Unlike default-agent-file.ts/managed-settings.ts's plan branches earlier
|
|
2841
|
-
# in this file (which never fail, by construction, so they run
|
|
2842
|
-
# unguarded), this job's dry pass still validates each declared path is a
|
|
2843
|
-
# real repo -- a genuine failure mode even in a non-apply mode, e.g. a
|
|
2844
|
-
# declared checkout that has not been cloned yet. So every non-apply mode
|
|
2845
|
-
# is guarded exactly like apply mode here, deliberately deviating from
|
|
2846
|
-
# those sibling steps: report it, collect it, never let it abort the rest
|
|
2847
|
-
# of this script under this file's own `set -e`. `$mode` (plan OR audit)
|
|
2848
|
-
# is reported verbatim -- audit is a real, distinct reconcile mode, never
|
|
2849
|
-
# relabeled "plan".
|
|
2850
|
-
if [[ "$mode" != apply ]]; then
|
|
2851
|
-
echo "global-tools: git-maintain (declared repos, arm-only) mode=$mode device=$device -> ${git_maintain_repos[*]}"
|
|
2852
|
-
if ! GIT_MAINTAIN_DRY=1 bun "$repo_root/packages/fleet/jobs/git-maintain/src/main.ts" "${git_maintain_repo_args[@]}"; then
|
|
2853
|
-
echo "global-tools: TOOL INSTALL FAILED: git-maintain-repos" >&2
|
|
2854
|
-
failed_tools+=("git-maintain-repos")
|
|
2855
|
-
fi
|
|
2856
|
-
else
|
|
2857
|
-
echo "global-tools: git-maintain (declared repos, arm-only) mode=apply device=$device -> ${git_maintain_repos[*]}"
|
|
2858
|
-
if ! bun "$repo_root/packages/fleet/jobs/git-maintain/src/main.ts" "${git_maintain_repo_args[@]}"; then
|
|
2859
|
-
echo "global-tools: TOOL INSTALL FAILED: git-maintain-repos" >&2
|
|
2860
|
-
failed_tools+=("git-maintain-repos")
|
|
2861
|
-
fi
|
|
2862
|
-
fi
|
|
2863
|
-
fi
|
|
2864
|
-
|
|
2865
2838
|
# A recorded, continued-past tool failure (install_one_tool /
|
|
2866
2839
|
# build_one_bun_tool / install_one_embedding_model_tool / write_one_shim)
|
|
2867
2840
|
# still lets every post-pass above run -- sweep, kimi-hooks, global-agents,
|
|
@@ -2869,11 +2842,11 @@ fi
|
|
|
2869
2842
|
# this point. The non-zero exit here is the only signal a caller (cron,
|
|
2870
2843
|
# systemd, CI) needs that something needs attention.
|
|
2871
2844
|
if [[ "${#failed_tools[@]}" -gt 0 ]]; then
|
|
2872
|
-
echo "global-tools: FAILED to install/build ${#failed_tools[@]} tool(s): ${failed_tools[*]}" >&2
|
|
2845
|
+
echo "ERROR global-tools: FAILED to install/build ${#failed_tools[@]} tool(s): ${failed_tools[*]}" >&2
|
|
2873
2846
|
exit 1
|
|
2874
2847
|
fi
|
|
2875
2848
|
|
|
2876
2849
|
if [[ "$scratch_reap_failed" -eq 1 ]]; then
|
|
2877
|
-
echo "global-tools: scratch reap could not verify remotes; worktree removal was refused" >&2
|
|
2850
|
+
echo "ERROR global-tools: scratch reap could not verify remotes; worktree removal was refused" >&2
|
|
2878
2851
|
exit 1
|
|
2879
2852
|
fi
|