aidevops 3.34.8 → 3.34.10
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/README.md +1 -1
- package/VERSION +1 -1
- package/aidevops.sh +287 -318
- package/package.json +1 -1
- package/setup.sh +43 -51
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ token efficiency, and quality control built in.**
|
|
|
25
25
|
[](https://qlty.sh/gh/marcusquinn/projects/aidevops)
|
|
26
26
|
[](https://app.codacy.com/gh/marcusquinn/aidevops/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
|
|
27
27
|
[](https://opensource.org/licenses/MIT)
|
|
28
|
-
[](https://github.com/marcusquinn/aidevops/releases)
|
|
29
29
|
[](https://www.npmjs.com/package/aidevops)
|
|
30
30
|
[](https://github.com/marcusquinn/homebrew-tap)
|
|
31
31
|
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.34.
|
|
1
|
+
3.34.10
|
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.34.
|
|
8
|
+
# Version: 3.34.10
|
|
9
9
|
|
|
10
10
|
set -euo pipefail
|
|
11
11
|
|
|
@@ -310,7 +310,17 @@ _run_update_source_access_reconciliation() {
|
|
|
310
310
|
return 0
|
|
311
311
|
fi
|
|
312
312
|
|
|
313
|
-
|
|
313
|
+
if [[ -t 0 && -t 1 ]]; then
|
|
314
|
+
print_info "Reconciling the protected source-access broker..."
|
|
315
|
+
if AIDEVOPS_SOURCE_ACCESS_INTERACTIVE=true bash "$INSTALL_DIR/setup.sh" --stage source-access; then
|
|
316
|
+
print_success "Protected source-access broker reconciled"
|
|
317
|
+
return 0
|
|
318
|
+
fi
|
|
319
|
+
print_warning "Source-access broker maintenance was blocked; it will retry during the next interactive update"
|
|
320
|
+
return 0
|
|
321
|
+
fi
|
|
322
|
+
|
|
323
|
+
print_warning "Source-access broker maintenance requires an attached terminal for privilege confirmation; the next interactive update will retry automatically"
|
|
314
324
|
return 0
|
|
315
325
|
}
|
|
316
326
|
|
|
@@ -347,19 +357,10 @@ cmd_update_help() {
|
|
|
347
357
|
}
|
|
348
358
|
|
|
349
359
|
cmd_update() {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
# Local declarations restore the caller's environment when this function exits.
|
|
353
|
-
local EDITOR=/usr/bin/false
|
|
354
|
-
local VISUAL=/usr/bin/false
|
|
355
|
-
local GIT_EDITOR=/usr/bin/false
|
|
356
|
-
local GIT_SEQUENCE_EDITOR=/usr/bin/false
|
|
357
|
-
local GIT_PAGER=cat
|
|
358
|
-
local PAGER=cat
|
|
359
|
-
local GIT_TERMINAL_PROMPT=0
|
|
360
|
+
local EDITOR=/usr/bin/false VISUAL=/usr/bin/false GIT_EDITOR=/usr/bin/false
|
|
361
|
+
local GIT_SEQUENCE_EDITOR=/usr/bin/false GIT_PAGER="cat" PAGER="cat" GIT_TERMINAL_PROMPT=0
|
|
360
362
|
export EDITOR VISUAL GIT_EDITOR GIT_SEQUENCE_EDITOR GIT_PAGER PAGER GIT_TERMINAL_PROMPT
|
|
361
363
|
local skip_project_sync=false
|
|
362
|
-
local reconcile_repo_verify=false
|
|
363
364
|
local update_output_mode="${AIDEVOPS_OUTPUT_MODE:-auto}"
|
|
364
365
|
local arg
|
|
365
366
|
for arg in "$@"; do
|
|
@@ -375,122 +376,128 @@ cmd_update() {
|
|
|
375
376
|
current_version=$(get_version)
|
|
376
377
|
print_info "Current version: $current_version"
|
|
377
378
|
print_info "Fetching latest version..."
|
|
379
|
+
_AIDEVOPS_UPDATE_RECONCILE_REPO_VERIFY=false
|
|
380
|
+
_update_install_framework "$current_version" "$update_output_mode" || return 1
|
|
381
|
+
_update_finish "$skip_project_sync"
|
|
382
|
+
return 0
|
|
383
|
+
}
|
|
378
384
|
|
|
385
|
+
_update_install_framework() {
|
|
386
|
+
local current_version="$1" update_output_mode="$2"
|
|
379
387
|
if check_dir "$INSTALL_DIR/.git"; then
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
local remote_hash
|
|
403
|
-
remote_hash=$(git rev-parse origin/main) || return 1
|
|
404
|
-
if [[ "$local_hash" != "$remote_hash" ]] && git merge-base --is-ancestor "$remote_hash" "$local_hash" 2>/dev/null; then
|
|
405
|
-
print_error "Refusing to update: local commits exist on main."
|
|
406
|
-
print_info "Preserve or reconcile the local history in $INSTALL_DIR, then rerun aidevops update."
|
|
388
|
+
_update_existing_install "$current_version" "$update_output_mode" || return 1
|
|
389
|
+
else
|
|
390
|
+
_update_fresh_install || return 1
|
|
391
|
+
fi
|
|
392
|
+
return 0
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
_update_existing_install() {
|
|
396
|
+
local current_version="$1" update_output_mode="$2"
|
|
397
|
+
cd "$INSTALL_DIR" || exit 1
|
|
398
|
+
if ! git diff --quiet 2>/dev/null || ! git diff --cached --quiet 2>/dev/null; then
|
|
399
|
+
print_error "Refusing to update: tracked local changes exist in $INSTALL_DIR"
|
|
400
|
+
git status --short
|
|
401
|
+
print_info "Commit or stash these changes, then rerun aidevops update."
|
|
402
|
+
return 1
|
|
403
|
+
fi
|
|
404
|
+
local current_branch
|
|
405
|
+
current_branch=$(git branch --show-current 2>/dev/null || echo "")
|
|
406
|
+
if [[ "$current_branch" != "main" ]]; then
|
|
407
|
+
print_info "Switching to main branch..."
|
|
408
|
+
if ! git checkout main --quiet 2>/dev/null && ! git checkout -b main origin/main --quiet 2>/dev/null; then
|
|
409
|
+
print_error "Failed to switch to main; refusing to update the active '$current_branch' branch."
|
|
407
410
|
return 1
|
|
408
411
|
fi
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
local stamp_file="$HOME/.aidevops/.deployed-sha"
|
|
425
|
-
if [[ -f "$stamp_file" ]]; then
|
|
426
|
-
local deployed_sha has_code_drift=0
|
|
427
|
-
deployed_sha=$(tr -d '[:space:]' <"$stamp_file" 2>/dev/null) || deployed_sha=""
|
|
428
|
-
if [[ -n "$deployed_sha" && "$deployed_sha" != "$local_hash" ]]; then
|
|
429
|
-
if _update_repo_verify_files_changed "$deployed_sha" "$local_hash"; then reconcile_repo_verify=true; fi
|
|
430
|
-
# Per Gemini code-review on PR #20342: use git's path filter +
|
|
431
|
-
# `grep -q .` to detect drift across the full set of deploy-affecting
|
|
432
|
-
# paths (not just .agents/ subdirs — also setup.sh, .agents/scripts/setup/modules/,
|
|
433
|
-
# and aidevops.sh itself, which are deployed/sourced by setup).
|
|
434
|
-
if git -C "$INSTALL_DIR" diff --name-only "$deployed_sha" "$local_hash" -- \
|
|
435
|
-
.agents/scripts/ .agents/agents/ .agents/workflows/ .agents/prompts/ .agents/hooks/ \
|
|
436
|
-
setup.sh .agents/scripts/setup/modules/ aidevops.sh 2>/dev/null | grep -q .; then
|
|
437
|
-
has_code_drift=1
|
|
438
|
-
fi
|
|
439
|
-
if [[ "$has_code_drift" -eq 1 ]]; then
|
|
440
|
-
print_warning "Deployed scripts drifted (${deployed_sha:0:7}→${local_hash:0:7})"
|
|
441
|
-
print_info "Re-running incremental setup to deploy latest scripts..."
|
|
442
|
-
_run_update_setup_transaction "$update_output_mode" "$local_hash" || return 1
|
|
443
|
-
fi
|
|
444
|
-
# GH#21735: workflow templates can change between
|
|
445
|
-
# releases without triggering has_code_drift (templates
|
|
446
|
-
# live outside the deploy-affecting paths). Check the
|
|
447
|
-
# template subset separately and surface drift.
|
|
448
|
-
_update_check_workflow_drift "$deployed_sha" "$local_hash"
|
|
449
|
-
fi
|
|
450
|
-
fi
|
|
451
|
-
fi
|
|
452
|
-
else
|
|
453
|
-
print_info "Applying latest changes..."
|
|
454
|
-
local old_hash
|
|
455
|
-
old_hash="$local_hash"
|
|
456
|
-
if [[ "${_AIDEVOPS_UPDATE_CANONICAL_FAST_FORWARDED:-false}" == "true" ]]; then
|
|
457
|
-
:
|
|
458
|
-
elif git merge --ff-only "$remote_hash" --quiet; then
|
|
459
|
-
:
|
|
460
|
-
else
|
|
461
|
-
print_error "Fast-forward update failed; preserving local history."
|
|
462
|
-
print_info "Review $INSTALL_DIR, resolve the divergence, then rerun aidevops update."
|
|
463
|
-
return 1
|
|
464
|
-
fi
|
|
465
|
-
local new_version new_hash
|
|
466
|
-
new_version=$(get_version)
|
|
467
|
-
new_hash=$(git rev-parse HEAD)
|
|
468
|
-
if [[ "$new_hash" != "$remote_hash" ]]; then
|
|
469
|
-
print_error "Updated HEAD does not match the fetched origin/main commit; refusing to run setup."
|
|
470
|
-
return 1
|
|
471
|
-
fi
|
|
472
|
-
if [[ "$old_hash" != "$new_hash" ]]; then
|
|
473
|
-
if _update_repo_verify_files_changed "$old_hash" "$new_hash"; then reconcile_repo_verify=true; fi
|
|
474
|
-
_update_render_changelog "$old_hash" "$new_hash" "$current_version"
|
|
475
|
-
# GH#21735: surface workflow template drift so the
|
|
476
|
-
# operator can resync downstream callers before CI bites.
|
|
477
|
-
_update_check_workflow_drift "$old_hash" "$new_hash"
|
|
478
|
-
fi
|
|
479
|
-
echo ""
|
|
480
|
-
# Verify supply chain integrity before applying changes
|
|
481
|
-
_update_verify_signature
|
|
482
|
-
echo ""
|
|
483
|
-
print_info "Running incremental setup to apply changes (falls back to full setup if needed)..."
|
|
484
|
-
_run_update_setup_transaction "$update_output_mode" "$new_hash" || return 1
|
|
485
|
-
print_success "Updated to version $new_version (agents deployed)"
|
|
486
|
-
fi
|
|
412
|
+
fi
|
|
413
|
+
local local_hash remote_hash
|
|
414
|
+
local_hash=$(git rev-parse HEAD) || return 1
|
|
415
|
+
if ! _update_fetch_main main; then
|
|
416
|
+
print_error "Failed to fetch origin/main; no update was applied."
|
|
417
|
+
return 1
|
|
418
|
+
fi
|
|
419
|
+
remote_hash=$(git rev-parse origin/main) || return 1
|
|
420
|
+
if [[ "$local_hash" != "$remote_hash" ]] && git merge-base --is-ancestor "$remote_hash" "$local_hash" 2>/dev/null; then
|
|
421
|
+
print_error "Refusing to update: local commits exist on main."
|
|
422
|
+
print_info "Preserve or reconcile the local history in $INSTALL_DIR, then rerun aidevops update."
|
|
423
|
+
return 1
|
|
424
|
+
fi
|
|
425
|
+
if [[ "$local_hash" == "$remote_hash" ]]; then
|
|
426
|
+
_update_already_current "$local_hash" "$update_output_mode"
|
|
487
427
|
else
|
|
488
|
-
|
|
428
|
+
_update_apply_remote "$local_hash" "$remote_hash" "$current_version" "$update_output_mode"
|
|
489
429
|
fi
|
|
430
|
+
return 0
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
_update_already_current() {
|
|
434
|
+
local local_hash="$1" update_output_mode="$2"
|
|
435
|
+
print_success "Framework already up to date!"
|
|
436
|
+
local repo_version deployed_version
|
|
437
|
+
repo_version=$(cat "$INSTALL_DIR/VERSION" 2>/dev/null || echo "unknown")
|
|
438
|
+
deployed_version=$(cat "$HOME/.aidevops/agents/VERSION" 2>/dev/null || echo "none")
|
|
439
|
+
if [[ "$repo_version" != "$deployed_version" ]]; then
|
|
440
|
+
print_warning "Deployed agents ($deployed_version) don't match repo ($repo_version)"
|
|
441
|
+
print_info "Re-running incremental setup to sync agents..."
|
|
442
|
+
_run_update_setup_transaction "$update_output_mode" "$local_hash"
|
|
443
|
+
return $?
|
|
444
|
+
fi
|
|
445
|
+
local stamp_file="$HOME/.aidevops/.deployed-sha" deployed_sha=""
|
|
446
|
+
[[ -f "$stamp_file" ]] || return 0
|
|
447
|
+
deployed_sha=$(tr -d '[:space:]' <"$stamp_file" 2>/dev/null) || deployed_sha=""
|
|
448
|
+
[[ -n "$deployed_sha" && "$deployed_sha" != "$local_hash" ]] || return 0
|
|
449
|
+
if _update_repo_verify_files_changed "$deployed_sha" "$local_hash"; then _AIDEVOPS_UPDATE_RECONCILE_REPO_VERIFY=true; fi
|
|
450
|
+
if git -C "$INSTALL_DIR" diff --name-only "$deployed_sha" "$local_hash" -- .agents/scripts/ .agents/agents/ .agents/workflows/ .agents/prompts/ .agents/hooks/ setup.sh .agents/scripts/setup/modules/ aidevops.sh 2>/dev/null | grep -q .; then
|
|
451
|
+
print_warning "Deployed scripts drifted (${deployed_sha:0:7}→${local_hash:0:7})"
|
|
452
|
+
print_info "Re-running incremental setup to deploy latest scripts..."
|
|
453
|
+
_run_update_setup_transaction "$update_output_mode" "$local_hash" || return 1
|
|
454
|
+
fi
|
|
455
|
+
_update_check_workflow_drift "$deployed_sha" "$local_hash"
|
|
456
|
+
return 0
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
_update_apply_remote() {
|
|
460
|
+
local old_hash="$1" remote_hash="$2" current_version="$3" update_output_mode="$4"
|
|
461
|
+
print_info "Applying latest changes..."
|
|
462
|
+
if [[ "${_AIDEVOPS_UPDATE_CANONICAL_FAST_FORWARDED:-false}" != "true" ]] && ! git merge --ff-only "$remote_hash" --quiet; then
|
|
463
|
+
print_error "Fast-forward update failed; preserving local history."
|
|
464
|
+
print_info "Review $INSTALL_DIR, resolve the divergence, then rerun aidevops update."
|
|
465
|
+
return 1
|
|
466
|
+
fi
|
|
467
|
+
local new_version new_hash
|
|
468
|
+
new_version=$(get_version)
|
|
469
|
+
new_hash=$(git rev-parse HEAD)
|
|
470
|
+
if [[ "$new_hash" != "$remote_hash" ]]; then
|
|
471
|
+
print_error "Updated HEAD does not match the fetched origin/main commit; refusing to run setup."
|
|
472
|
+
return 1
|
|
473
|
+
fi
|
|
474
|
+
if [[ "$old_hash" != "$new_hash" ]]; then
|
|
475
|
+
if _update_repo_verify_files_changed "$old_hash" "$new_hash"; then _AIDEVOPS_UPDATE_RECONCILE_REPO_VERIFY=true; fi
|
|
476
|
+
_update_render_changelog "$old_hash" "$new_hash" "$current_version"
|
|
477
|
+
_update_check_workflow_drift "$old_hash" "$new_hash"
|
|
478
|
+
fi
|
|
479
|
+
echo ""
|
|
480
|
+
_update_verify_signature
|
|
481
|
+
echo ""
|
|
482
|
+
print_info "Running incremental setup to apply changes (falls back to full setup if needed)..."
|
|
483
|
+
_run_update_setup_transaction "$update_output_mode" "$new_hash" || return 1
|
|
484
|
+
print_success "Updated to version $new_version (agents deployed)"
|
|
485
|
+
return 0
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
_update_start_pulse() {
|
|
489
|
+
[[ "${AIDEVOPS_SKIP_PULSE_RESTART:-0}" != "1" ]] || return 0
|
|
490
|
+
local pulse_helper="${AGENTS_DIR}/scripts/pulse-lifecycle-helper.sh"
|
|
491
|
+
[[ -x "$pulse_helper" ]] && "$pulse_helper" start >/dev/null 2>&1 || print_warning "Pulse start failed (non-fatal)"
|
|
492
|
+
return 0
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
_update_finish() {
|
|
496
|
+
local skip_project_sync="$1"
|
|
490
497
|
|
|
491
498
|
_run_update_source_access_reconciliation
|
|
492
499
|
_update_sync_projects "$skip_project_sync" "$(get_version)"
|
|
493
|
-
if [[ "$skip_project_sync" != "$_AIDEVOPS_UPDATE_TRUE" && "$
|
|
500
|
+
if [[ "$skip_project_sync" != "$_AIDEVOPS_UPDATE_TRUE" && "${_AIDEVOPS_UPDATE_RECONCILE_REPO_VERIFY:-false}" == "$_AIDEVOPS_UPDATE_TRUE" ]]; then
|
|
494
501
|
_update_reconcile_repo_verify
|
|
495
502
|
fi
|
|
496
503
|
_update_check_homebrew
|
|
@@ -532,13 +539,7 @@ cmd_update() {
|
|
|
532
539
|
# 'start' subcommand does not check it directly — only 'restart' and
|
|
533
540
|
# 'restart-if-running' do). Non-fatal: a pulse start failure should
|
|
534
541
|
# not fail the update.
|
|
535
|
-
|
|
536
|
-
local _pulse_helper="${AGENTS_DIR}/scripts/pulse-lifecycle-helper.sh"
|
|
537
|
-
if [[ -x "$_pulse_helper" ]]; then
|
|
538
|
-
"$_pulse_helper" start >/dev/null 2>&1 || print_warning "Pulse start failed (non-fatal)"
|
|
539
|
-
fi
|
|
540
|
-
fi
|
|
541
|
-
|
|
542
|
+
_update_start_pulse
|
|
542
543
|
return 0
|
|
543
544
|
}
|
|
544
545
|
|
|
@@ -1180,7 +1181,7 @@ _help_commands() {
|
|
|
1180
1181
|
return 0
|
|
1181
1182
|
}
|
|
1182
1183
|
|
|
1183
|
-
|
|
1184
|
+
_help_security_sections() {
|
|
1184
1185
|
echo "Security:"
|
|
1185
1186
|
echo " aidevops security # Run ALL checks (posture + hygiene + supply chain)"
|
|
1186
1187
|
echo " aidevops security posture # Interactive security posture setup (gopass, gh, SSH)"
|
|
@@ -1241,6 +1242,11 @@ _help_detailed_sections() {
|
|
|
1241
1242
|
echo " aidevops client-format extract # 1. Re-extract constants"
|
|
1242
1243
|
echo " aidevops client-format canary # 2. Verify against real CLI"
|
|
1243
1244
|
echo ""
|
|
1245
|
+
return 0
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
_help_detailed_sections_content() {
|
|
1249
|
+
_help_security_sections
|
|
1244
1250
|
echo "Secrets:"
|
|
1245
1251
|
echo " aidevops secret set NAME # Store a secret (hidden input)"
|
|
1246
1252
|
echo " aidevops secret list # List secret names (never values)"
|
|
@@ -1249,26 +1255,7 @@ _help_detailed_sections() {
|
|
|
1249
1255
|
echo " aidevops secret import # Import from credentials.sh to gopass"
|
|
1250
1256
|
echo " aidevops secret status # Show backend status"
|
|
1251
1257
|
echo ""
|
|
1252
|
-
|
|
1253
|
-
echo " aidevops vault init # Create local encrypted Vault metadata"
|
|
1254
|
-
echo " aidevops vault status # Show uninitialized/locked/unlocked/corrupted"
|
|
1255
|
-
echo " aidevops vault unlock # Unlock into an in-memory local broker"
|
|
1256
|
-
echo " aidevops vault lock # Stop broker and forget in-memory keys"
|
|
1257
|
-
echo " aidevops vault read NAME # Read protected data through broker"
|
|
1258
|
-
echo " aidevops vault update NAME # Encrypt stdin value through broker"
|
|
1259
|
-
echo ""
|
|
1260
|
-
echo "GitHub App Auth:"
|
|
1261
|
-
echo " aidevops github-app-auth status --json # Show active auth mode and budgets"
|
|
1262
|
-
echo " aidevops github-app-auth route issue-list # Explain route decision"
|
|
1263
|
-
echo " aidevops github-app-auth rate-limit --json # Show cached per-pool budgets"
|
|
1264
|
-
echo ""
|
|
1265
|
-
echo "Feature Toggles:"
|
|
1266
|
-
echo " aidevops config list # List all toggles with current values"
|
|
1267
|
-
echo " aidevops config get <key> # Get a toggle value"
|
|
1268
|
-
echo " aidevops config set <k> <v> # Set a toggle (true/false)"
|
|
1269
|
-
echo " aidevops config reset [key] # Reset toggle(s) to defaults"
|
|
1270
|
-
echo " aidevops config path # Show config file path"
|
|
1271
|
-
echo ""
|
|
1258
|
+
_help_vault_and_config_sections
|
|
1272
1259
|
echo "Knowledge Plane:"
|
|
1273
1260
|
echo " aidevops knowledge init repo # Provision _knowledge/ in current repo"
|
|
1274
1261
|
echo " aidevops knowledge init personal # Provision at ~/.aidevops/.agent-workspace/knowledge/"
|
|
@@ -1343,6 +1330,11 @@ _help_detailed_sections() {
|
|
|
1343
1330
|
return 0
|
|
1344
1331
|
}
|
|
1345
1332
|
|
|
1333
|
+
_help_detailed_sections() {
|
|
1334
|
+
_help_detailed_sections_content
|
|
1335
|
+
return 0
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1346
1338
|
_help_management_sections() {
|
|
1347
1339
|
echo "Auto-Update:"
|
|
1348
1340
|
echo " aidevops auto-update enable # Poll for updates every 10 min"
|
|
@@ -1830,48 +1822,81 @@ _cmd_client_format() {
|
|
|
1830
1822
|
}
|
|
1831
1823
|
|
|
1832
1824
|
# Main entry point
|
|
1825
|
+
_main_badges() {
|
|
1826
|
+
local subcommand="${1:-}"
|
|
1827
|
+
local sync_helper="badges-sync-helper.sh"
|
|
1828
|
+
case "$subcommand" in
|
|
1829
|
+
render)
|
|
1830
|
+
shift
|
|
1831
|
+
local helper="$HOME/.aidevops/agents/scripts/readme-badges-helper.sh"
|
|
1832
|
+
[[ -f "$helper" ]] || helper="$AGENTS_DIR/scripts/readme-badges-helper.sh"
|
|
1833
|
+
if [[ -f "$helper" ]]; then bash "$helper" render "$@"; else print_error "readme-badges-helper.sh not found. Run: aidevops update"; return 1; fi
|
|
1834
|
+
;;
|
|
1835
|
+
check) shift; _dispatch_helper "badges-check-helper.sh" "badges-check-helper.sh" "$@" ;;
|
|
1836
|
+
sync) shift; _dispatch_helper "$sync_helper" "$sync_helper" "$@" ;;
|
|
1837
|
+
install) shift; _dispatch_helper "$sync_helper" "$sync_helper" --workflow-only "$@" ;;
|
|
1838
|
+
help | --help | -h | "")
|
|
1839
|
+
echo ""
|
|
1840
|
+
echo "aidevops badges — README badge block and repo metrics workflow management (t2975)"
|
|
1841
|
+
echo ""
|
|
1842
|
+
echo "Subcommands:"
|
|
1843
|
+
echo " render <slug> Print canonical badge block for a repo"
|
|
1844
|
+
echo " check [--repo SLUG] [--json] Detect badge drift across managed repos"
|
|
1845
|
+
echo " sync [--repo SLUG] [--apply] Inject badge block + generate metrics + install workflow"
|
|
1846
|
+
echo " install [--repo SLUG] [--apply] Install repo metrics refresh workflow only"
|
|
1847
|
+
echo ""
|
|
1848
|
+
echo "Options (check/sync/install):"
|
|
1849
|
+
echo " --repo SLUG Limit to a single repo"
|
|
1850
|
+
echo " --apply Actually perform the sync (default: dry-run)"
|
|
1851
|
+
echo " --json Machine-readable output"
|
|
1852
|
+
echo " --verbose Show diff summaries (check only)"
|
|
1853
|
+
echo ""
|
|
1854
|
+
echo "Examples:"
|
|
1855
|
+
echo " aidevops badges check # scan all repos for badge drift"
|
|
1856
|
+
echo " aidevops badges check --json | jq '.[]' # machine-readable output"
|
|
1857
|
+
echo " aidevops badges render owner/repo # print badge block"
|
|
1858
|
+
echo " aidevops badges sync # dry-run sync across all repos"
|
|
1859
|
+
echo " aidevops badges sync --repo owner/r --apply # apply to a single repo"
|
|
1860
|
+
echo " aidevops metrics generate [PATH] # generate local docs/metrics artifacts"
|
|
1861
|
+
echo ""
|
|
1862
|
+
;;
|
|
1863
|
+
*) print_error "Unknown badges subcommand: $subcommand (try render|check|sync|install|help)"; return 1 ;;
|
|
1864
|
+
esac
|
|
1865
|
+
return 0
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1833
1868
|
main() {
|
|
1834
1869
|
local command="${1:-help}"
|
|
1835
1870
|
local check_workflows_helper="check-workflows-helper.sh"
|
|
1871
|
+
local update_help="help"
|
|
1836
1872
|
shift || true
|
|
1837
|
-
|
|
1838
|
-
# Help for inventory commands must bypass repository auto-detection and
|
|
1839
|
-
# version checks. Those startup checks may read the repository registry,
|
|
1840
|
-
# while help must remain bounded and side-effect-free.
|
|
1841
|
-
if [[ "$command" == "check-workflows" || "$command" == "workflows" ]]; then
|
|
1842
|
-
local arg
|
|
1843
|
-
for arg in "$@"; do
|
|
1844
|
-
case "$arg" in
|
|
1845
|
-
-h | --help)
|
|
1846
|
-
_dispatch_helper "$check_workflows_helper" "$check_workflows_helper" "$@"
|
|
1847
|
-
return $?
|
|
1848
|
-
;;
|
|
1849
|
-
esac
|
|
1850
|
-
done
|
|
1851
|
-
fi
|
|
1852
|
-
|
|
1853
|
-
# Update help must return before startup checks or cmd_update(), which can
|
|
1854
|
-
# inspect repositories, fetch remotes, deploy agents, and synchronize projects.
|
|
1855
1873
|
if [[ "$command" == "update" || "$command" == "upgrade" || "$command" == "u" ]]; then
|
|
1856
1874
|
local arg
|
|
1857
1875
|
for arg in "$@"; do
|
|
1858
|
-
|
|
1859
|
-
help | -h | --help)
|
|
1860
|
-
cmd_update_help
|
|
1861
|
-
return $?
|
|
1862
|
-
;;
|
|
1863
|
-
esac
|
|
1876
|
+
if [[ "$arg" == "$update_help" || "$arg" == "-h" || "$arg" == "--help" ]]; then cmd_update_help; return $?; fi
|
|
1864
1877
|
done
|
|
1878
|
+
_main_check_unregistered "$command"
|
|
1879
|
+
cmd_update "$@"
|
|
1880
|
+
return $?
|
|
1865
1881
|
fi
|
|
1866
|
-
|
|
1867
|
-
# Auto-detect unregistered repo on any command (silent check)
|
|
1882
|
+
_main_early_help "$command" "$check_workflows_helper" "$@" && return 0
|
|
1868
1883
|
_main_check_unregistered "$command"
|
|
1884
|
+
_main_check_version
|
|
1885
|
+
_main_dispatch "$command" "$check_workflows_helper" "$@"
|
|
1886
|
+
}
|
|
1869
1887
|
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1888
|
+
_main_early_help() {
|
|
1889
|
+
local command="$1" check_workflows_helper="$2" arg
|
|
1890
|
+
shift 2
|
|
1891
|
+
for arg in "$@"; do
|
|
1892
|
+
if [[ "$command" == "check-workflows" || "$command" == "workflows" ]] && [[ "$arg" == "-h" || "$arg" == "--help" ]]; then _dispatch_helper "$check_workflows_helper" "$check_workflows_helper" "$@"; return $?; fi
|
|
1893
|
+
done
|
|
1894
|
+
return 1
|
|
1895
|
+
}
|
|
1874
1896
|
|
|
1897
|
+
_main_dispatch() {
|
|
1898
|
+
local command="$1" check_workflows_helper="$2"
|
|
1899
|
+
shift 2
|
|
1875
1900
|
case "$command" in
|
|
1876
1901
|
init | i) cmd_init "$@" ;;
|
|
1877
1902
|
setup) cmd_setup "$@" ;;
|
|
@@ -1897,76 +1922,7 @@ main() {
|
|
|
1897
1922
|
check-workflows | workflows) _dispatch_helper "$check_workflows_helper" "$check_workflows_helper" "$@" ;;
|
|
1898
1923
|
sync-workflows) _dispatch_helper "sync-workflows-helper.sh" "sync-workflows-helper.sh" "$@" ;;
|
|
1899
1924
|
metrics) _dispatch_helper "repo-metrics-helper.sh" "repo-metrics-helper.sh" "$@" ;;
|
|
1900
|
-
badges)
|
|
1901
|
-
# Badge management: render | check | sync | install (t2975)
|
|
1902
|
-
# Bare 'aidevops badges' with no subcommand shows a usage summary.
|
|
1903
|
-
# Subcommands:
|
|
1904
|
-
# render <slug> — render canonical badge block for a repo
|
|
1905
|
-
# check [--repo SLUG] [--json] [--verbose] — cross-repo drift check
|
|
1906
|
-
# sync [--repo SLUG] [--apply] — inject badge block + generate metrics + install workflow
|
|
1907
|
-
# install [--repo SLUG] [--apply] — install repo metrics refresh workflow only
|
|
1908
|
-
local _badges_sub="${1:-help}"
|
|
1909
|
-
local _badges_check_h="badges-check-helper.sh"
|
|
1910
|
-
local _badges_sync_h="badges-sync-helper.sh"
|
|
1911
|
-
case "$_badges_sub" in
|
|
1912
|
-
render)
|
|
1913
|
-
shift
|
|
1914
|
-
local _render_helper
|
|
1915
|
-
_render_helper=$(bash -c '
|
|
1916
|
-
d="$HOME/.aidevops/agents/scripts/readme-badges-helper.sh"
|
|
1917
|
-
l="'"$AGENTS_DIR"'/scripts/readme-badges-helper.sh"
|
|
1918
|
-
[[ -f "$d" ]] && echo "$d" || echo "$l"
|
|
1919
|
-
')
|
|
1920
|
-
if [[ -f "$_render_helper" ]]; then
|
|
1921
|
-
bash "$_render_helper" render "$@"
|
|
1922
|
-
else
|
|
1923
|
-
print_error "readme-badges-helper.sh not found. Run: aidevops update"
|
|
1924
|
-
exit 1
|
|
1925
|
-
fi
|
|
1926
|
-
;;
|
|
1927
|
-
check)
|
|
1928
|
-
shift
|
|
1929
|
-
_dispatch_helper "$_badges_check_h" "$_badges_check_h" "$@"
|
|
1930
|
-
;;
|
|
1931
|
-
sync)
|
|
1932
|
-
shift
|
|
1933
|
-
_dispatch_helper "$_badges_sync_h" "$_badges_sync_h" "$@"
|
|
1934
|
-
;;
|
|
1935
|
-
install)
|
|
1936
|
-
shift
|
|
1937
|
-
_dispatch_helper "$_badges_sync_h" "$_badges_sync_h" --workflow-only "$@"
|
|
1938
|
-
;;
|
|
1939
|
-
help | --help | -h | "")
|
|
1940
|
-
echo ""
|
|
1941
|
-
echo "aidevops badges — README badge block and repo metrics workflow management (t2975)"
|
|
1942
|
-
echo ""
|
|
1943
|
-
echo "Subcommands:"
|
|
1944
|
-
echo " render <slug> Print canonical badge block for a repo"
|
|
1945
|
-
echo " check [--repo SLUG] [--json] Detect badge drift across managed repos"
|
|
1946
|
-
echo " sync [--repo SLUG] [--apply] Inject badge block + generate metrics + install workflow"
|
|
1947
|
-
echo " install [--repo SLUG] [--apply] Install repo metrics refresh workflow only"
|
|
1948
|
-
echo ""
|
|
1949
|
-
echo "Options (check/sync/install):"
|
|
1950
|
-
echo " --repo SLUG Limit to a single repo"
|
|
1951
|
-
echo " --apply Actually perform the sync (default: dry-run)"
|
|
1952
|
-
echo " --json Machine-readable output"
|
|
1953
|
-
echo " --verbose Show diff summaries (check only)"
|
|
1954
|
-
echo ""
|
|
1955
|
-
echo "Examples:"
|
|
1956
|
-
echo " aidevops badges check # scan all repos for badge drift"
|
|
1957
|
-
echo " aidevops badges check --json | jq '.[]' # machine-readable output"
|
|
1958
|
-
echo " aidevops badges render owner/repo # print badge block"
|
|
1959
|
-
echo " aidevops badges sync # dry-run sync across all repos"
|
|
1960
|
-
echo " aidevops badges sync --repo owner/r --apply # apply to a single repo"
|
|
1961
|
-
echo " aidevops metrics generate [PATH] # generate local docs/metrics artifacts"
|
|
1962
|
-
echo ""
|
|
1963
|
-
;;
|
|
1964
|
-
*)
|
|
1965
|
-
print_error "Unknown badges subcommand: $_badges_sub (try render|check|sync|install|help)"
|
|
1966
|
-
exit 1
|
|
1967
|
-
;;
|
|
1968
|
-
esac
|
|
1969
|
-
;;
|
|
1925
|
+
badges) _main_badges "$@" ;;
|
|
1970
1926
|
security) _cmd_security "$@" ;;
|
|
1971
1927
|
doctor | doc) _dispatch_helper "doctor-helper.sh" "doctor-helper.sh" "$@" ;;
|
|
1972
1928
|
detect | scan) cmd_detect ;;
|
|
@@ -1974,32 +1930,7 @@ main() {
|
|
|
1974
1930
|
model-accounts-pool | map) _dispatch_helper "oauth-pool-helper.sh" "oauth-pool-helper.sh" "$@" ;;
|
|
1975
1931
|
gpt56-context | gpt56_context) _dispatch_helper "gpt56-context-helper.sh" "gpt56-context-helper.sh" "$@" ;;
|
|
1976
1932
|
astra-context | astra_context) _dispatch_helper "astra-context-helper.sh" "astra-context-helper.sh" "$@" ;;
|
|
1977
|
-
cleanup)
|
|
1978
|
-
local _cleanup_sub="${1:-help}"
|
|
1979
|
-
case "$_cleanup_sub" in
|
|
1980
|
-
branches | remote-branches)
|
|
1981
|
-
shift || true
|
|
1982
|
-
_dispatch_helper "remote-branch-cleanup-helper.sh" "remote-branch-cleanup-helper.sh" "$_cleanup_sub" "$@"
|
|
1983
|
-
;;
|
|
1984
|
-
help | --help | -h | "")
|
|
1985
|
-
echo "Usage: aidevops cleanup <branches|remote-branches> [options]"
|
|
1986
|
-
echo ""
|
|
1987
|
-
echo "Cleanup commands:"
|
|
1988
|
-
echo " branches Audit stale remote branches (dry-run default)"
|
|
1989
|
-
echo " remote-branches Alias for branches"
|
|
1990
|
-
echo ""
|
|
1991
|
-
echo "Options:"
|
|
1992
|
-
echo " --repo PATH Repository path (default: current directory)"
|
|
1993
|
-
echo " --remote NAME Remote to audit (default: origin)"
|
|
1994
|
-
echo " --apply Delete safe candidates"
|
|
1995
|
-
echo ""
|
|
1996
|
-
;;
|
|
1997
|
-
*)
|
|
1998
|
-
print_error "Unknown cleanup subcommand: $_cleanup_sub (try branches|remote-branches|help)"
|
|
1999
|
-
exit 1
|
|
2000
|
-
;;
|
|
2001
|
-
esac
|
|
2002
|
-
;;
|
|
1933
|
+
cleanup) _main_dispatch_cleanup "$@" ;;
|
|
2003
1934
|
client-format) _cmd_client_format "$@" ;;
|
|
2004
1935
|
github-app-auth | github-app | gh-auth) _dispatch_helper "github-app-auth-helper.sh" "github-app-auth-helper.sh" "$@" ;;
|
|
2005
1936
|
opencode-db | oc-db) _dispatch_helper "opencode-db-maintenance-helper.sh" "opencode-db-maintenance-helper.sh" "$@" ;;
|
|
@@ -2021,12 +1952,7 @@ main() {
|
|
|
2021
1952
|
worktree | wt) _dispatch_helper "worktree-helper.sh" "worktree-helper.sh" "$@" ;;
|
|
2022
1953
|
issue) _dispatch_helper "interactive-session-helper.sh" "interactive-session-helper.sh" "$@" ;;
|
|
2023
1954
|
signing) _dispatch_helper "signing-setup.sh" "signing-setup.sh" "$@" ;;
|
|
2024
|
-
contributions | contrib)
|
|
2025
|
-
# Bare `aidevops contributions` defaults to status (most common use).
|
|
2026
|
-
# Other subcommands (seed, scan, stop, restart, install, uninstall) forward verbatim.
|
|
2027
|
-
[[ $# -eq 0 ]] && set -- status
|
|
2028
|
-
_dispatch_helper "contribution-watch-helper.sh" "contribution-watch-helper.sh" "$@"
|
|
2029
|
-
;;
|
|
1955
|
+
contributions | contrib) _main_dispatch_contributions "$@" ;;
|
|
2030
1956
|
inbox)
|
|
2031
1957
|
# Bare `aidevops inbox` defaults to status (most common use).
|
|
2032
1958
|
[[ $# -eq 0 ]] && set -- status
|
|
@@ -2050,44 +1976,7 @@ main() {
|
|
|
2050
1976
|
init-routines) _dispatch_helper "init-routines-helper.sh" "init-routines-helper.sh" "$@" ;;
|
|
2051
1977
|
parent-status | ps) _dispatch_helper "parent-status-helper.sh" "parent-status-helper.sh" "$@" ;;
|
|
2052
1978
|
knowledge) _dispatch_helper "knowledge-helper.sh" "knowledge-helper.sh" "$@" ;;
|
|
2053
|
-
campaign | campaigns)
|
|
2054
|
-
# P1 provisioning: init/provision/status/ls → campaigns-provision-helper.sh
|
|
2055
|
-
# P4 asset binary: asset → campaign-asset-helper.sh
|
|
2056
|
-
# P2+P6: all other subcommands → campaign-helper.sh
|
|
2057
|
-
local _camp_cmd="${1:-help}"
|
|
2058
|
-
local _camp_helper="campaign-helper.sh"
|
|
2059
|
-
local _camp_provision_helper="campaigns-provision-helper.sh"
|
|
2060
|
-
case "$_camp_cmd" in
|
|
2061
|
-
init | provision | ls)
|
|
2062
|
-
_dispatch_helper "$_camp_provision_helper" "$_camp_provision_helper" "$@"
|
|
2063
|
-
;;
|
|
2064
|
-
status)
|
|
2065
|
-
if [[ $# -le 1 || -d "${2:-}" || "${2:-}" == .* || "${2:-}" == /* || "${2:-}" == ~* ]]; then
|
|
2066
|
-
_dispatch_helper "$_camp_provision_helper" "$_camp_provision_helper" "$@"
|
|
2067
|
-
else
|
|
2068
|
-
_dispatch_helper "$_camp_helper" "$_camp_helper" "$@"
|
|
2069
|
-
fi
|
|
2070
|
-
;;
|
|
2071
|
-
asset | assets)
|
|
2072
|
-
shift
|
|
2073
|
-
_dispatch_helper "campaign-asset-helper.sh" "campaign-asset-helper.sh" "$@"
|
|
2074
|
-
;;
|
|
2075
|
-
grow | growth)
|
|
2076
|
-
shift
|
|
2077
|
-
local _growth_helper="${AIDEVOPS_CLI_MODULES_DIR%/aidevops-cli}/campaign-growth-helper.py"
|
|
2078
|
-
[[ ! -f "$_growth_helper" ]] && _growth_helper="$AGENTS_DIR/scripts/campaign-growth-helper.py"
|
|
2079
|
-
if [[ -f "$_growth_helper" ]]; then
|
|
2080
|
-
python3 "$_growth_helper" "$@"
|
|
2081
|
-
else
|
|
2082
|
-
print_error "campaign-growth-helper.py not found. Run: aidevops update"
|
|
2083
|
-
return 1
|
|
2084
|
-
fi
|
|
2085
|
-
;;
|
|
2086
|
-
*)
|
|
2087
|
-
_dispatch_helper "$_camp_helper" "$_camp_helper" "$@"
|
|
2088
|
-
;;
|
|
2089
|
-
esac
|
|
2090
|
-
;;
|
|
1979
|
+
campaign | campaigns) _main_dispatch_campaign "$@" ;;
|
|
2091
1980
|
performance) _dispatch_helper "performance-helper.sh" "performance-helper.sh" "$@" ;;
|
|
2092
1981
|
reach) _dispatch_helper "reach-helper.sh" "reach-helper.sh" "$@" ;;
|
|
2093
1982
|
config | configure) _dispatch_config "$@" ;;
|
|
@@ -2103,4 +1992,84 @@ main() {
|
|
|
2103
1992
|
esac
|
|
2104
1993
|
}
|
|
2105
1994
|
|
|
1995
|
+
_main_dispatch_cleanup() {
|
|
1996
|
+
local cleanup_subcommand="${1:-help}"
|
|
1997
|
+
case "$cleanup_subcommand" in
|
|
1998
|
+
branches | remote-branches)
|
|
1999
|
+
shift || true
|
|
2000
|
+
_dispatch_helper "remote-branch-cleanup-helper.sh" "remote-branch-cleanup-helper.sh" "$cleanup_subcommand" "$@"
|
|
2001
|
+
;;
|
|
2002
|
+
help | --help | -h | "")
|
|
2003
|
+
echo "Usage: aidevops cleanup <branches|remote-branches> [options]"
|
|
2004
|
+
echo ""
|
|
2005
|
+
echo "Cleanup commands:"
|
|
2006
|
+
echo " branches Audit stale remote branches (dry-run default)"
|
|
2007
|
+
echo " remote-branches Alias for branches"
|
|
2008
|
+
echo ""
|
|
2009
|
+
echo "Options:"
|
|
2010
|
+
echo " --repo PATH Repository path (default: current directory)"
|
|
2011
|
+
echo " --remote NAME Remote to audit (default: origin)"
|
|
2012
|
+
echo " --apply Delete safe candidates"
|
|
2013
|
+
echo ""
|
|
2014
|
+
;;
|
|
2015
|
+
*) print_error "Unknown cleanup subcommand: $cleanup_subcommand (try branches|remote-branches|help)"; return 1 ;;
|
|
2016
|
+
esac
|
|
2017
|
+
return 0
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
_help_vault_and_config_sections() {
|
|
2021
|
+
echo "Vault:"
|
|
2022
|
+
echo " aidevops vault init # Create local encrypted Vault metadata"
|
|
2023
|
+
echo " aidevops vault status # Show uninitialized/locked/unlocked/corrupted"
|
|
2024
|
+
echo " aidevops vault unlock # Unlock into an in-memory local broker"
|
|
2025
|
+
echo " aidevops vault lock # Stop broker and forget in-memory keys"
|
|
2026
|
+
echo " aidevops vault read NAME # Read protected data through broker"
|
|
2027
|
+
echo " aidevops vault update NAME # Encrypt stdin value through broker"
|
|
2028
|
+
echo ""
|
|
2029
|
+
echo "GitHub App Auth:"
|
|
2030
|
+
echo " aidevops github-app-auth status --json # Show active auth mode and budgets"
|
|
2031
|
+
echo " aidevops github-app-auth route issue-list # Explain route decision"
|
|
2032
|
+
echo " aidevops github-app-auth rate-limit --json # Show cached per-pool budgets"
|
|
2033
|
+
echo ""
|
|
2034
|
+
echo "Feature Toggles:"
|
|
2035
|
+
echo " aidevops config list # List all toggles with current values"
|
|
2036
|
+
echo " aidevops config get <key> # Get a toggle value"
|
|
2037
|
+
echo " aidevops config set <k> <v> # Set a toggle (true/false)"
|
|
2038
|
+
echo " aidevops config reset [key] # Reset toggle(s) to defaults"
|
|
2039
|
+
echo " aidevops config path # Show config file path"
|
|
2040
|
+
echo ""
|
|
2041
|
+
return 0
|
|
2042
|
+
}
|
|
2043
|
+
|
|
2044
|
+
_main_dispatch_contributions() {
|
|
2045
|
+
[[ $# -eq 0 ]] && set -- status
|
|
2046
|
+
_dispatch_helper "contribution-watch-helper.sh" "contribution-watch-helper.sh" "$@"
|
|
2047
|
+
return $?
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
_main_dispatch_campaign() {
|
|
2051
|
+
local campaign_command="${1:-help}" campaign_helper="campaign-helper.sh"
|
|
2052
|
+
local provision_helper="campaigns-provision-helper.sh"
|
|
2053
|
+
case "$campaign_command" in
|
|
2054
|
+
init | provision | ls) _dispatch_helper "$provision_helper" "$provision_helper" "$@" ;;
|
|
2055
|
+
status)
|
|
2056
|
+
if [[ $# -le 1 || -d "${2:-}" || "${2:-}" == .* || "${2:-}" == /* || "${2:-}" == ~* ]]; then
|
|
2057
|
+
_dispatch_helper "$provision_helper" "$provision_helper" "$@"
|
|
2058
|
+
else
|
|
2059
|
+
_dispatch_helper "$campaign_helper" "$campaign_helper" "$@"
|
|
2060
|
+
fi
|
|
2061
|
+
;;
|
|
2062
|
+
asset | assets) shift; _dispatch_helper "campaign-asset-helper.sh" "campaign-asset-helper.sh" "$@" ;;
|
|
2063
|
+
grow | growth)
|
|
2064
|
+
shift
|
|
2065
|
+
local growth_helper="${AIDEVOPS_CLI_MODULES_DIR%/aidevops-cli}/campaign-growth-helper.py"
|
|
2066
|
+
[[ ! -f "$growth_helper" ]] && growth_helper="$AGENTS_DIR/scripts/campaign-growth-helper.py"
|
|
2067
|
+
[[ -f "$growth_helper" ]] || { print_error "campaign-growth-helper.py not found. Run: aidevops update"; return 1; }
|
|
2068
|
+
python3 "$growth_helper" "$@"
|
|
2069
|
+
;;
|
|
2070
|
+
*) _dispatch_helper "$campaign_helper" "$campaign_helper" "$@" ;;
|
|
2071
|
+
esac
|
|
2072
|
+
return 0
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2106
2075
|
main "$@"
|
package/package.json
CHANGED
package/setup.sh
CHANGED
|
@@ -17,7 +17,7 @@ fi
|
|
|
17
17
|
# AI Assistant Server Access Framework Setup Script
|
|
18
18
|
# Helps developers set up the framework for their infrastructure
|
|
19
19
|
#
|
|
20
|
-
# Version: 3.34.
|
|
20
|
+
# Version: 3.34.10
|
|
21
21
|
#
|
|
22
22
|
# Quick Install:
|
|
23
23
|
# npm install -g aidevops && aidevops update (recommended)
|
|
@@ -1116,16 +1116,34 @@ _setup_redact_secret_like_command_values() {
|
|
|
1116
1116
|
return 0
|
|
1117
1117
|
}
|
|
1118
1118
|
|
|
1119
|
+
_setup_claim_noninteractive_setup_lock() {
|
|
1120
|
+
local lock_dir="$1"
|
|
1121
|
+
shift
|
|
1122
|
+
local lane_rc=0
|
|
1123
|
+
|
|
1124
|
+
SETUP_NONINTERACTIVE_LOCK_DIR="$lock_dir"
|
|
1125
|
+
SETUP_NONINTERACTIVE_LOCK_HELD=true
|
|
1126
|
+
printf '%s\n' "$$" >"$lock_dir/owner.pid" 2>/dev/null || true
|
|
1127
|
+
printf '%s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" >"$lock_dir/started_at" 2>/dev/null || true
|
|
1128
|
+
printf '%s\n' "$(date +%s 2>/dev/null || printf '0')" >"$lock_dir/started_at_epoch" 2>/dev/null || true
|
|
1129
|
+
printf '%s\n' "$0 $*" >"$lock_dir/command" 2>/dev/null || true
|
|
1130
|
+
_setup_guard_active_release_lane || lane_rc=$?
|
|
1131
|
+
if [[ "$lane_rc" -ne 0 ]]; then
|
|
1132
|
+
_setup_release_noninteractive_setup_lock
|
|
1133
|
+
return "$lane_rc"
|
|
1134
|
+
fi
|
|
1135
|
+
trap '_setup_cleanup_noninteractive_children; _setup_release_noninteractive_setup_lock' EXIT
|
|
1136
|
+
trap '_setup_noninteractive_signal_exit TERM' TERM
|
|
1137
|
+
trap '_setup_noninteractive_signal_exit INT' INT
|
|
1138
|
+
return 0
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1119
1141
|
_setup_acquire_noninteractive_setup_lock() {
|
|
1120
1142
|
local lock_dir="${AIDEVOPS_SETUP_LOCK_DIR:-$HOME/.aidevops/locks/setup-noninteractive.lock.d}"
|
|
1121
|
-
# Max seconds to wait for a live, non-stale owner before timing out.
|
|
1122
1143
|
local wait_ceiling="${AIDEVOPS_SETUP_WAIT_TIMEOUT_S:-900}"
|
|
1123
|
-
# Max seconds a live owner may hold the lock before it is treated as
|
|
1124
|
-
# stale and reclaimed (0 disables stale-live reclaim).
|
|
1125
1144
|
local stale_ceiling="${AIDEVOPS_SETUP_STALE_TIMEOUT_S:-1800}"
|
|
1126
1145
|
local owner_pid="" owner_cmd="" owner_age=0
|
|
1127
1146
|
local reclaim_attempts=0 waited=0
|
|
1128
|
-
local lane_rc=0
|
|
1129
1147
|
local _diag_stl="$HOME/.aidevops/logs/setup-stage-timings.log"
|
|
1130
1148
|
local _diag_interval_s="${AIDEVOPS_SETUP_LOCK_DIAG_INTERVAL_S:-60}"
|
|
1131
1149
|
_setup_guard_active_release_lane || return $?
|
|
@@ -1133,24 +1151,10 @@ _setup_acquire_noninteractive_setup_lock() {
|
|
|
1133
1151
|
mkdir -p "$(dirname "$lock_dir")" 2>/dev/null || true
|
|
1134
1152
|
while true; do
|
|
1135
1153
|
if mkdir "$lock_dir" 2>/dev/null; then
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
printf '%s\n' "$$" >"$lock_dir/owner.pid" 2>/dev/null || true
|
|
1139
|
-
printf '%s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" >"$lock_dir/started_at" 2>/dev/null || true
|
|
1140
|
-
printf '%s\n' "$(date +%s 2>/dev/null || printf '0')" >"$lock_dir/started_at_epoch" 2>/dev/null || true
|
|
1141
|
-
printf '%s\n' "$0 $*" >"$lock_dir/command" 2>/dev/null || true
|
|
1142
|
-
_setup_guard_active_release_lane || lane_rc=$?
|
|
1143
|
-
if [[ "$lane_rc" -ne 0 ]]; then
|
|
1144
|
-
_setup_release_noninteractive_setup_lock
|
|
1145
|
-
return "$lane_rc"
|
|
1146
|
-
fi
|
|
1147
|
-
trap '_setup_cleanup_noninteractive_children; _setup_release_noninteractive_setup_lock' EXIT
|
|
1148
|
-
trap '_setup_noninteractive_signal_exit TERM' TERM
|
|
1149
|
-
trap '_setup_noninteractive_signal_exit INT' INT
|
|
1150
|
-
return 0
|
|
1154
|
+
_setup_claim_noninteractive_setup_lock "$lock_dir" "$@"
|
|
1155
|
+
return $?
|
|
1151
1156
|
fi
|
|
1152
1157
|
|
|
1153
|
-
# Lock exists — inspect owner.
|
|
1154
1158
|
owner_pid=""
|
|
1155
1159
|
if [[ -r "$lock_dir/owner.pid" ]]; then
|
|
1156
1160
|
owner_pid=$(tr -d '[:space:]' <"$lock_dir/owner.pid" 2>/dev/null || true)
|
|
@@ -1174,7 +1178,6 @@ _setup_acquire_noninteractive_setup_lock() {
|
|
|
1174
1178
|
fi
|
|
1175
1179
|
|
|
1176
1180
|
if ! _setup_lock_pid_alive "$owner_pid"; then
|
|
1177
|
-
# Dead owner — reclaim the stale lock.
|
|
1178
1181
|
if [[ "$reclaim_attempts" -ge 2 ]]; then
|
|
1179
1182
|
print_error "Unable to acquire setup.sh --non-interactive lock at ${lock_dir} after ${reclaim_attempts} stale-lock removals"
|
|
1180
1183
|
return 75
|
|
@@ -1198,7 +1201,6 @@ _setup_acquire_noninteractive_setup_lock() {
|
|
|
1198
1201
|
continue
|
|
1199
1202
|
fi
|
|
1200
1203
|
|
|
1201
|
-
# Owner is alive — compute age and read current setup stage.
|
|
1202
1204
|
owner_age=$(_setup_lock_owner_age "$lock_dir" "$owner_pid")
|
|
1203
1205
|
owner_cmd=""
|
|
1204
1206
|
[[ -r "$lock_dir/command" ]] && owner_cmd=$(tr '\n' ' ' <"$lock_dir/command" 2>/dev/null || true)
|
|
@@ -1210,7 +1212,6 @@ _setup_acquire_noninteractive_setup_lock() {
|
|
|
1210
1212
|
[[ -n "$_diag_cur_stage" ]] && _diag_stage=", stage: ${_diag_cur_stage}"
|
|
1211
1213
|
fi
|
|
1212
1214
|
|
|
1213
|
-
# Stale-live reclaim: owner alive but running far too long.
|
|
1214
1215
|
if [[ "$stale_ceiling" -gt 0 && "$owner_age" -ge "$stale_ceiling" ]]; then
|
|
1215
1216
|
if [[ "$reclaim_attempts" -ge 2 ]]; then
|
|
1216
1217
|
print_error "Unable to acquire setup.sh --non-interactive lock: owner (pid ${owner_pid}, age ${owner_age}s) exceeds stale ceiling but reclaim limit reached. Diagnose: ${_diag_stl}"
|
|
@@ -1222,13 +1223,11 @@ _setup_acquire_noninteractive_setup_lock() {
|
|
|
1222
1223
|
continue
|
|
1223
1224
|
fi
|
|
1224
1225
|
|
|
1225
|
-
# Live non-stale owner — check wait ceiling before sleeping.
|
|
1226
1226
|
if [[ "$waited" -ge "$wait_ceiling" ]]; then
|
|
1227
1227
|
print_error "Timed out waiting ${waited}s for setup.sh --non-interactive lock (owner pid ${owner_pid}, age ${owner_age}s${_diag_stage}${owner_cmd:+, command: ${owner_cmd}}). Increase AIDEVOPS_SETUP_WAIT_TIMEOUT_S (current: ${wait_ceiling}s) or kill pid ${owner_pid} to unblock. Diagnose: ${_diag_stl}"
|
|
1228
1228
|
return 75
|
|
1229
1229
|
fi
|
|
1230
1230
|
|
|
1231
|
-
# Emit diagnostics on first block and every diagnostic interval thereafter.
|
|
1232
1231
|
if [[ "$waited" -eq 0 ]]; then
|
|
1233
1232
|
print_info "Another setup.sh --non-interactive is running (pid ${owner_pid}, age ${owner_age}s${_diag_stage}${owner_cmd:+, command: ${owner_cmd}}). Waiting up to ${wait_ceiling}s (AIDEVOPS_SETUP_WAIT_TIMEOUT_S). Diagnose: ${_diag_stl}"
|
|
1234
1233
|
elif [[ $((waited % _diag_interval_s)) -eq 0 ]]; then
|
|
@@ -1543,22 +1542,7 @@ reconcile_buzz_desktop_compatibility() {
|
|
|
1543
1542
|
esac
|
|
1544
1543
|
}
|
|
1545
1544
|
|
|
1546
|
-
|
|
1547
|
-
print_info "Non-interactive mode: deploying agents and running safe migrations only"
|
|
1548
|
-
|
|
1549
|
-
_setup_init_stage_timing_log
|
|
1550
|
-
|
|
1551
|
-
_time_step "protect_current_setup_worktree" protect_current_setup_worktree
|
|
1552
|
-
_time_step "verify_location" verify_location
|
|
1553
|
-
_time_step "check_requirements" check_requirements
|
|
1554
|
-
# Run quality tool detection in non-interactive mode too (warn-only path).
|
|
1555
|
-
_time_step "check_quality_tools" check_quality_tools
|
|
1556
|
-
# Check setsid availability; auto-install util-linux on macOS if missing
|
|
1557
|
-
# (GH#21102 / t2926: missing setsid kills workers on every pulse restart).
|
|
1558
|
-
_time_step "setup_setsid_advisory" setup_setsid_advisory
|
|
1559
|
-
_time_step "check_python_upgrade_available" check_python_upgrade_available
|
|
1560
|
-
_time_step "setup_vault_python_env" setup_vault_python_env || print_warning "Vault crypto runtime setup encountered issues; Vault status remains metadata-only"
|
|
1561
|
-
_time_step "set_permissions" set_permissions
|
|
1545
|
+
_setup_run_noninteractive_migrations() {
|
|
1562
1546
|
_time_step "migrate_old_backups" migrate_old_backups
|
|
1563
1547
|
_time_step "migrate_loop_state_directories" migrate_loop_state_directories
|
|
1564
1548
|
_time_step "migrate_agent_to_agents_folder" migrate_agent_to_agents_folder
|
|
@@ -1576,12 +1560,23 @@ _setup_run_non_interactive() {
|
|
|
1576
1560
|
_time_step "cleanup_worktree_entries_in_repos_json" cleanup_worktree_entries_in_repos_json
|
|
1577
1561
|
_time_step "_cleanup_legacy_model_config" _cleanup_legacy_model_config
|
|
1578
1562
|
_time_step "cleanup_legacy_dashboard_launchagent" cleanup_legacy_dashboard_launchagent
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1563
|
+
return 0
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
_setup_run_non_interactive() {
|
|
1567
|
+
print_info "Non-interactive mode: deploying agents and running safe migrations only"
|
|
1568
|
+
|
|
1569
|
+
_setup_init_stage_timing_log
|
|
1570
|
+
|
|
1571
|
+
_time_step "protect_current_setup_worktree" protect_current_setup_worktree
|
|
1572
|
+
_time_step "verify_location" verify_location
|
|
1573
|
+
_time_step "check_requirements" check_requirements
|
|
1574
|
+
_time_step "check_quality_tools" check_quality_tools
|
|
1575
|
+
_time_step "setup_setsid_advisory" setup_setsid_advisory
|
|
1576
|
+
_time_step "check_python_upgrade_available" check_python_upgrade_available
|
|
1577
|
+
_time_step "setup_vault_python_env" setup_vault_python_env || print_warning "Vault crypto runtime setup encountered issues; Vault status remains metadata-only"
|
|
1578
|
+
_time_step "set_permissions" set_permissions
|
|
1579
|
+
_setup_run_noninteractive_migrations
|
|
1585
1580
|
_time_step "$SETUP_STAGE_OPENCODE" setup_opencode_runtimes
|
|
1586
1581
|
_time_step "validate_opencode_config" validate_opencode_config
|
|
1587
1582
|
_time_step "$SETUP_STAGE_AGENTS" deploy_aidevops_agents
|
|
@@ -1599,9 +1594,6 @@ _setup_run_non_interactive() {
|
|
|
1599
1594
|
fi
|
|
1600
1595
|
_time_step "init_settings_json" init_settings_json
|
|
1601
1596
|
|
|
1602
|
-
# Parallelise independent skill operations (t1356: ~84s serial -> ~18s parallel)
|
|
1603
|
-
# generate_agent_skills must complete before create_skill_symlinks (symlinks
|
|
1604
|
-
# depend on generated SKILL.md files). scan_imported_skills is independent.
|
|
1605
1597
|
local _pid_symlinks=""
|
|
1606
1598
|
if _time_step "generate_agent_skills" generate_agent_skills; then
|
|
1607
1599
|
_time_step "create_skill_symlinks" create_skill_symlinks &
|