aidevops 3.32.158 → 3.32.160

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 CHANGED
@@ -60,7 +60,7 @@ The result: an AI operations platform that manages projects across every busines
60
60
  [![Copyright](https://img.shields.io/badge/Copyright-Marcus%20Quinn%202025--2026-blue.svg)](https://github.com/marcusquinn)
61
61
 
62
62
  <!-- Release & Version Info -->
63
- [![Version](https://img.shields.io/badge/Version-3.32.158-blue.svg)](https://github.com/marcusquinn/aidevops/releases)
63
+ [![Version](https://img.shields.io/badge/Version-3.32.160-blue.svg)](https://github.com/marcusquinn/aidevops/releases)
64
64
  [![npm version](https://img.shields.io/npm/v/aidevops)](https://www.npmjs.com/package/aidevops)
65
65
  [![Homebrew](https://img.shields.io/badge/homebrew-marcusquinn%2Ftap-orange)](https://github.com/marcusquinn/homebrew-tap)
66
66
  [![GitHub repository](https://img.shields.io/badge/github-repository-181717.svg?logo=github)](https://github.com/marcusquinn/aidevops)
package/VERSION CHANGED
@@ -1 +1 @@
1
- 3.32.158
1
+ 3.32.160
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.32.158
8
+ # Version: 3.32.160
9
9
 
10
10
  set -euo pipefail
11
11
 
@@ -337,12 +337,12 @@ cmd_update() {
337
337
  return 1
338
338
  fi
339
339
  fi
340
- if ! git fetch origin main --tags --quiet; then
340
+ local local_hash
341
+ local_hash=$(git rev-parse HEAD) || return 1
342
+ if ! _update_fetch_main main; then
341
343
  print_error "Failed to fetch origin/main; no update was applied."
342
344
  return 1
343
345
  fi
344
- local local_hash
345
- local_hash=$(git rev-parse HEAD) || return 1
346
346
  local remote_hash
347
347
  remote_hash=$(git rev-parse origin/main) || return 1
348
348
  if [[ "$local_hash" != "$remote_hash" ]] && git merge-base --is-ancestor "$remote_hash" "$local_hash" 2>/dev/null; then
@@ -396,8 +396,10 @@ cmd_update() {
396
396
  else
397
397
  print_info "Applying latest changes..."
398
398
  local old_hash
399
- old_hash=$(git rev-parse HEAD)
400
- if git merge --ff-only "$remote_hash" --quiet; then
399
+ old_hash="$local_hash"
400
+ if [[ "${_AIDEVOPS_UPDATE_CANONICAL_FAST_FORWARDED:-false}" == "true" ]]; then
401
+ :
402
+ elif git merge --ff-only "$remote_hash" --quiet; then
401
403
  :
402
404
  else
403
405
  print_error "Fast-forward update failed; preserving local history."
@@ -1587,6 +1589,7 @@ _cmd_email() {
1587
1589
 
1588
1590
  # Route 'aidevops client-format [subcommand]' to appropriate helpers
1589
1591
  _cmd_client_format() {
1592
+ local canary_helper="cch-canary.sh"
1590
1593
  case "${1:-status}" in
1591
1594
  extract | refresh)
1592
1595
  _dispatch_helper "cch-extract.sh" "cch-extract.sh" --cache
@@ -1596,14 +1599,14 @@ _cmd_client_format() {
1596
1599
  ;;
1597
1600
  canary | test)
1598
1601
  shift || true
1599
- _dispatch_helper "cch-canary.sh" "cch-canary.sh" --verbose "$@"
1602
+ _dispatch_helper "$canary_helper" "$canary_helper" --verbose "$@"
1600
1603
  ;;
1601
1604
  monitor)
1602
1605
  shift || true
1603
1606
  _dispatch_helper "cch-traffic-monitor.sh" "cch-traffic-monitor.sh" "$@"
1604
1607
  ;;
1605
1608
  install-canary)
1606
- _dispatch_helper "cch-canary.sh" "cch-canary.sh" --install
1609
+ _dispatch_helper "$canary_helper" "$canary_helper" --install
1607
1610
  ;;
1608
1611
  status | "")
1609
1612
  echo ""
@@ -1817,15 +1820,17 @@ main() {
1817
1820
  # P4 asset binary: asset → campaign-asset-helper.sh
1818
1821
  # P2+P6: all other subcommands → campaign-helper.sh
1819
1822
  local _camp_cmd="${1:-help}"
1823
+ local _camp_helper="campaign-helper.sh"
1824
+ local _camp_provision_helper="campaigns-provision-helper.sh"
1820
1825
  case "$_camp_cmd" in
1821
1826
  init | provision | ls)
1822
- _dispatch_helper "campaigns-provision-helper.sh" "campaigns-provision-helper.sh" "$@"
1827
+ _dispatch_helper "$_camp_provision_helper" "$_camp_provision_helper" "$@"
1823
1828
  ;;
1824
1829
  status)
1825
1830
  if [[ $# -le 1 || -d "${2:-}" || "${2:-}" == .* || "${2:-}" == /* || "${2:-}" == ~* ]]; then
1826
- _dispatch_helper "campaigns-provision-helper.sh" "campaigns-provision-helper.sh" "$@"
1831
+ _dispatch_helper "$_camp_provision_helper" "$_camp_provision_helper" "$@"
1827
1832
  else
1828
- _dispatch_helper "campaign-helper.sh" "campaign-helper.sh" "$@"
1833
+ _dispatch_helper "$_camp_helper" "$_camp_helper" "$@"
1829
1834
  fi
1830
1835
  ;;
1831
1836
  asset | assets)
@@ -1833,7 +1838,7 @@ main() {
1833
1838
  _dispatch_helper "campaign-asset-helper.sh" "campaign-asset-helper.sh" "$@"
1834
1839
  ;;
1835
1840
  *)
1836
- _dispatch_helper "campaign-helper.sh" "campaign-helper.sh" "$@"
1841
+ _dispatch_helper "$_camp_helper" "$_camp_helper" "$@"
1837
1842
  ;;
1838
1843
  esac
1839
1844
  ;;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aidevops",
3
- "version": "3.32.158",
3
+ "version": "3.32.160",
4
4
  "description": "AI DevOps Framework - AI-assisted development workflows, code quality, and deployment automation",
5
5
  "type": "module",
6
6
  "workspaces": [
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.32.158
20
+ # Version: 3.32.160
21
21
  #
22
22
  # Quick Install:
23
23
  # npm install -g aidevops && aidevops update (recommended)
@@ -122,10 +122,26 @@ if [[ -d "$SETUP_MODULES_DIR" ]]; then
122
122
  source "$SETUP_MODULES_DIR/_worktree_exclusions.sh"
123
123
  fi
124
124
 
125
- print_info() { local _m="$1"; echo -e "${BLUE}[INFO]${NC} $_m"; return 0; }
126
- print_success() { local _m="$1"; echo -e "${GREEN}[SUCCESS]${NC} $_m"; return 0; }
127
- print_warning() { local _m="$1"; echo -e "${YELLOW}[WARNING]${NC} $_m"; return 0; }
128
- print_error() { local _m="$1"; echo -e "${RED}[ERROR]${NC} $_m"; return 0; }
125
+ print_info() {
126
+ local _m="$1"
127
+ echo -e "${BLUE}[INFO]${NC} $_m"
128
+ return 0
129
+ }
130
+ print_success() {
131
+ local _m="$1"
132
+ echo -e "${GREEN}[SUCCESS]${NC} $_m"
133
+ return 0
134
+ }
135
+ print_warning() {
136
+ local _m="$1"
137
+ echo -e "${YELLOW}[WARNING]${NC} $_m"
138
+ return 0
139
+ }
140
+ print_error() {
141
+ local _m="$1"
142
+ echo -e "${RED}[ERROR]${NC} $_m"
143
+ return 0
144
+ }
129
145
 
130
146
  # Source shared-constants for config support (is_feature_enabled / config_enabled)
131
147
  # Try repo-local first, then deployed location
@@ -333,6 +349,8 @@ unset _setup_script_dir
333
349
  # helpers loaded early by the root entrypoint; normal setup implementation
334
350
  # modules live under modules/ so the repository root has no module directory.
335
351
  SETUP_IMPL_MODULES_DIR="${SETUP_MODULES_DIR}/modules"
352
+ # shellcheck source=.agents/scripts/runtime-bundle-verifier.sh
353
+ source "${INSTALL_DIR}/.agents/scripts/runtime-bundle-verifier.sh"
336
354
  # shellcheck disable=SC1091 # Dynamic path via $SETUP_IMPL_MODULES_DIR
337
355
  source "${SETUP_IMPL_MODULES_DIR}/core.sh"
338
356
  # shellcheck disable=SC1091
@@ -802,7 +820,7 @@ _setup_lock_pid_is_noninteractive_setup() {
802
820
  [[ "$pid" =~ ^[0-9]+$ ]] || return 1
803
821
  owner_args=$(ps -p "$pid" -o args= 2>/dev/null || true)
804
822
  [[ -n "$owner_args" ]] || return 0
805
- [[ "$owner_args" == *"setup.sh"* && ( "$owner_args" == *"--non-interactive"* || "$owner_args" == *"--stage"* ) ]]
823
+ [[ "$owner_args" == *"setup.sh"* && ("$owner_args" == *"--non-interactive"* || "$owner_args" == *"--stage"*) ]]
806
824
  return $?
807
825
  }
808
826
 
@@ -837,7 +855,7 @@ _setup_lock_started_age_seconds() {
837
855
  local now_epoch=""
838
856
  if [[ -r "$lock_dir/started_at" ]]; then
839
857
  started_str=$(tr -d '[:space:]' <"$lock_dir/started_at" 2>/dev/null || true)
840
- started_epoch=$(date -d "$started_str" +%s 2>/dev/null || \
858
+ started_epoch=$(date -d "$started_str" +%s 2>/dev/null ||
841
859
  date -u -jf '%Y-%m-%dT%H:%M:%SZ' "$started_str" +%s 2>/dev/null || true)
842
860
  now_epoch=$(date +%s 2>/dev/null || true)
843
861
  if [[ "$started_epoch" =~ ^[0-9]+$ && "$now_epoch" =~ ^[0-9]+$ && "$now_epoch" -ge "$started_epoch" ]]; then
@@ -954,7 +972,7 @@ _setup_run_noncritical_stage_bounded() {
954
972
  pid=$!
955
973
  _setup_register_child_pid "$pid"
956
974
  while _setup_lock_pid_alive "$pid"; do
957
- if (( SECONDS - start_s >= timeout_s )); then
975
+ if ((SECONDS - start_s >= timeout_s)); then
958
976
  _setup_kill_pid_tree TERM "$pid"
959
977
  sleep "${AIDEVOPS_SETUP_CHILD_TERM_GRACE_S:-2}" 2>/dev/null || true
960
978
  _setup_kill_pid_tree KILL "$pid"
@@ -1032,9 +1050,9 @@ _setup_command_key_looks_secret() {
1032
1050
  key="${key#--}"
1033
1051
  key="${key#-}"
1034
1052
  case "$key" in
1035
- *password*|*passwd*|*secret*|*token*|*credential*|*api-key*|*api_key*|*apikey*|*access-key*|*access_key*|*private-key*|*private_key*|bearer)
1036
- return 0
1037
- ;;
1053
+ *password* | *passwd* | *secret* | *token* | *credential* | *api-key* | *api_key* | *apikey* | *access-key* | *access_key* | *private-key* | *private_key* | bearer)
1054
+ return 0
1055
+ ;;
1038
1056
  esac
1039
1057
  return 1
1040
1058
  }
@@ -1177,7 +1195,7 @@ _setup_acquire_noninteractive_setup_lock() {
1177
1195
  # Emit diagnostics on first block and every diagnostic interval thereafter.
1178
1196
  if [[ "$waited" -eq 0 ]]; then
1179
1197
  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}"
1180
- elif [[ $(( waited % _diag_interval_s )) -eq 0 ]]; then
1198
+ elif [[ $((waited % _diag_interval_s)) -eq 0 ]]; then
1181
1199
  print_info "Still waiting for setup lock (owner pid ${owner_pid}, age ${owner_age}s${_diag_stage}${owner_cmd:+, command: ${owner_cmd}}, waited ${waited}s of ${wait_ceiling}s max). Diagnose: ${_diag_stl}"
1182
1200
  fi
1183
1201
 
@@ -1331,68 +1349,14 @@ _setup_git_checkout_available() {
1331
1349
  return 0
1332
1350
  }
1333
1351
 
1334
- _setup_bundle_manifest_value() {
1335
- local manifest_file="$1"
1336
- local key="$2"
1337
- local value=""
1338
- value=$(grep -m 1 "^${key}=" "$manifest_file" 2>/dev/null) || return 1
1339
- printf '%s' "${value#*=}"
1340
- return 0
1341
- }
1342
-
1343
1352
  _setup_ai_session_verify_deploy() {
1344
1353
  local expected_sha="$1"
1345
- local active_link="$HOME/.aidevops/agents"
1346
- local active_root=""
1347
- local manifest_file=""
1348
- local manifest_status=""
1349
- local manifest_version=""
1350
- local manifest_sha=""
1351
- local repo_version=""
1352
- local deployed_version=""
1353
- local deployed_sha=""
1354
-
1355
- if [[ ! -L "$active_link" ]]; then
1356
- print_warning "AI-session incremental verification failed: active agents path is not an activation symlink"
1357
- return 1
1358
- fi
1359
- active_root=$(resolve_aidevops_runtime_bundle_root "$active_link") || {
1360
- print_warning "AI-session incremental verification failed: active agents symlink cannot be resolved"
1361
- return 1
1362
- }
1363
- manifest_file="$active_root/.bundle-manifest"
1364
- if [[ ! -r "$manifest_file" ]]; then
1365
- print_warning "AI-session incremental verification failed: active bundle manifest is missing"
1366
- return 1
1367
- fi
1368
- manifest_status=$(_setup_bundle_manifest_value "$manifest_file" status) || manifest_status=""
1369
- manifest_version=$(_setup_bundle_manifest_value "$manifest_file" framework_version) || manifest_version=""
1370
- manifest_sha=$(_setup_bundle_manifest_value "$manifest_file" git_sha) || manifest_sha=""
1371
-
1372
- if [[ -f "$INSTALL_DIR/VERSION" ]]; then
1373
- repo_version=$(tr -d '[:space:]' <"$INSTALL_DIR/VERSION" 2>/dev/null) || repo_version=""
1374
- fi
1375
- if [[ -f "$active_root/VERSION" ]]; then
1376
- deployed_version=$(tr -d '[:space:]' <"$active_root/VERSION" 2>/dev/null) || deployed_version=""
1377
- fi
1378
- if [[ -f "$HOME/.aidevops/.deployed-sha" ]]; then
1379
- deployed_sha=$(tr -d '[:space:]' <"$HOME/.aidevops/.deployed-sha" 2>/dev/null) || deployed_sha=""
1380
- fi
1381
-
1382
- if [[ "$manifest_status" != "validated" ]]; then
1383
- print_warning "AI-session incremental verification failed: active bundle manifest status=${manifest_status:-missing}"
1384
- return 1
1385
- fi
1386
- if [[ -z "$repo_version" || "$repo_version" != "$deployed_version" || "$repo_version" != "$manifest_version" ]]; then
1387
- print_warning "AI-session incremental verification failed: repo version=${repo_version:-unknown}, active=${deployed_version:-none}, manifest=${manifest_version:-none}"
1388
- return 1
1389
- fi
1390
- if [[ -z "$deployed_sha" || "$deployed_sha" != "$expected_sha" || "$manifest_sha" != "$expected_sha" ]]; then
1391
- print_warning "AI-session incremental verification failed: stamp SHA=${deployed_sha:-none}, manifest SHA=${manifest_sha:-none}, expected=${expected_sha:0:12}"
1392
- return 1
1393
- fi
1394
-
1395
- return 0
1354
+ verify_aidevops_runtime_bundle_convergence \
1355
+ "$INSTALL_DIR" \
1356
+ "$expected_sha" \
1357
+ "$HOME/.aidevops/agents" \
1358
+ "$HOME/.aidevops/.deployed-sha"
1359
+ return $?
1396
1360
  }
1397
1361
 
1398
1362
  _setup_run_ai_session_incremental() {
@@ -1543,7 +1507,8 @@ _setup_run_non_interactive() {
1543
1507
  _time_step "backfill_issue_relationships" backfill_issue_relationships
1544
1508
  _time_step "cleanup_deprecated_mcps" cleanup_deprecated_mcps
1545
1509
  _time_step "cleanup_stale_bun_opencode" cleanup_stale_bun_opencode
1546
- _time_step "cleanup_stale_health_issue_caches" cleanup_stale_health_issue_caches; _time_step "cleanup_legacy_aidevops_temp_artifacts" cleanup_legacy_aidevops_temp_artifacts
1510
+ _time_step "cleanup_stale_health_issue_caches" cleanup_stale_health_issue_caches
1511
+ _time_step "cleanup_legacy_aidevops_temp_artifacts" cleanup_legacy_aidevops_temp_artifacts
1547
1512
  _time_step "cleanup_worktree_entries_in_repos_json" cleanup_worktree_entries_in_repos_json
1548
1513
  _time_step "_cleanup_legacy_model_config" _cleanup_legacy_model_config
1549
1514
  _time_step "cleanup_legacy_dashboard_launchagent" cleanup_legacy_dashboard_launchagent
@@ -1719,11 +1684,18 @@ _setup_run_interactive() {
1719
1684
  confirm_step "Cleanup deprecated MCP entries (hetzner, serper, etc.)" && cleanup_deprecated_mcps
1720
1685
  confirm_step "Cleanup stale bun opencode install" && cleanup_stale_bun_opencode
1721
1686
  # Silent one-shot migrations (idempotent, flag-guarded — no prompt needed).
1722
- cleanup_stale_health_issue_caches; cleanup_legacy_aidevops_temp_artifacts; cleanup_worktree_entries_in_repos_json; _cleanup_legacy_model_config; cleanup_legacy_dashboard_launchagent
1687
+ cleanup_stale_health_issue_caches
1688
+ cleanup_legacy_aidevops_temp_artifacts
1689
+ cleanup_worktree_entries_in_repos_json
1690
+ _cleanup_legacy_model_config
1691
+ cleanup_legacy_dashboard_launchagent
1723
1692
  confirm_step "Validate and repair OpenCode config schema" && validate_opencode_config
1724
1693
  confirm_step "Extract OpenCode prompts" && extract_opencode_prompts
1725
1694
  confirm_step "Check OpenCode prompt drift" && check_opencode_prompt_drift
1726
- confirm_step "Deploy aidevops agents to ~/.aidevops/agents/" && { deploy_aidevops_agents; _deploy_hotfix_config; }
1695
+ confirm_step "Deploy aidevops agents to ~/.aidevops/agents/" && {
1696
+ deploy_aidevops_agents
1697
+ _deploy_hotfix_config
1698
+ }
1727
1699
  # Launcher verification reads the deployed VERSION, so it must follow agent
1728
1700
  # deployment on first-run interactive setup as it already does non-interactively.
1729
1701
  confirm_step "Install and verify aidevops CLI command" && install_aidevops_cli