aidevops 3.5.892 → 3.8.2

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/setup.sh CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env bash
2
+ # SPDX-License-Identifier: MIT
3
+ # SPDX-FileCopyrightText: 2025-2026 Marcus Quinn
2
4
 
3
5
  # Shell safety baseline
4
6
  set -Eeuo pipefail
@@ -10,7 +12,7 @@ shopt -s inherit_errexit 2>/dev/null || true
10
12
  # AI Assistant Server Access Framework Setup Script
11
13
  # Helps developers set up the framework for their infrastructure
12
14
  #
13
- # Version: 3.5.892
15
+ # Version: 3.8.2
14
16
  #
15
17
  # Quick Install:
16
18
  # npm install -g aidevops && aidevops update (recommended)
@@ -83,6 +85,12 @@ if [[ -d "$SETUP_MODULES_DIR" ]]; then
83
85
  source "$SETUP_MODULES_DIR/_services.sh"
84
86
  # shellcheck disable=SC1091
85
87
  source "$SETUP_MODULES_DIR/_bootstrap.sh"
88
+ # shellcheck disable=SC1091
89
+ source "$SETUP_MODULES_DIR/_routines.sh"
90
+ # shellcheck disable=SC1091
91
+ source "$SETUP_MODULES_DIR/_privacy_guard.sh"
92
+ # shellcheck disable=SC1091
93
+ source "$SETUP_MODULES_DIR/_canonical_guard.sh"
86
94
  fi
87
95
 
88
96
  print_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
@@ -233,8 +241,11 @@ _launchd_install_if_changed() {
233
241
  return 0
234
242
  }
235
243
 
236
- # Detect whether a scheduler is already installed via launchd or cron.
244
+ # Detect whether a scheduler is already installed via launchd, cron, or systemd.
237
245
  # Optionally migrates legacy launchd labels / cron entries to launchd on macOS.
246
+ # Args: $1=scheduler_name, $2=launchd_label, $3=legacy_launchd_label,
247
+ # $4=cron_marker, $5=migrate_script, $6=migrate_arg, $7=migrate_hint
248
+ # $8=systemd_unit (optional — base name without .timer suffix, e.g. "aidevops-supervisor-pulse")
238
249
  _scheduler_detect_installed() {
239
250
  local scheduler_name="$1"
240
251
  local launchd_label="$2"
@@ -243,6 +254,7 @@ _scheduler_detect_installed() {
243
254
  local migrate_script="$5"
244
255
  local migrate_arg="$6"
245
256
  local migrate_hint="$7"
257
+ local systemd_unit="${8:-}"
246
258
  local installed=false
247
259
 
248
260
  if _launchd_has_agent "$launchd_label"; then
@@ -265,6 +277,10 @@ _scheduler_detect_installed() {
265
277
  fi
266
278
  fi
267
279
  installed=true
280
+ elif [[ -n "$systemd_unit" ]] && command -v systemctl >/dev/null 2>&1 &&
281
+ systemctl --user is-enabled "${systemd_unit}.timer" >/dev/null 2>&1; then
282
+ # Systemd user timer detected (GH#17381 — Linux systemd path was missing)
283
+ installed=true
268
284
  fi
269
285
 
270
286
  if [[ "$installed" == "true" ]]; then
@@ -273,6 +289,54 @@ _scheduler_detect_installed() {
273
289
 
274
290
  return 1
275
291
  }
292
+
293
+ _should_setup_noninteractive_supervisor_pulse() {
294
+ local pulse_label="com.aidevops.aidevops-supervisor-pulse"
295
+
296
+ if _scheduler_detect_installed \
297
+ "Supervisor pulse" \
298
+ "$pulse_label" \
299
+ "" \
300
+ "pulse-wrapper" \
301
+ "" \
302
+ "" \
303
+ "" \
304
+ "aidevops-supervisor-pulse"; then
305
+ return 0
306
+ fi
307
+
308
+ if type config_enabled &>/dev/null && config_enabled "orchestration.supervisor_pulse"; then
309
+ return 0
310
+ fi
311
+
312
+ return 1
313
+ }
314
+
315
+ # Generic non-interactive scheduler detection (GH#17695 Finding B).
316
+ # Returns 0 if the named scheduler is already installed on any backend,
317
+ # meaning it should be regenerated during non-interactive setup.
318
+ # Args: $1=name $2=launchd_label $3=cron_marker $4=systemd_unit
319
+ _should_setup_noninteractive_scheduler() {
320
+ local name="$1"
321
+ local launchd_label="$2"
322
+ local cron_marker="$3"
323
+ local systemd_unit="${4:-}"
324
+
325
+ if _scheduler_detect_installed \
326
+ "$name" \
327
+ "$launchd_label" \
328
+ "" \
329
+ "$cron_marker" \
330
+ "" \
331
+ "" \
332
+ "" \
333
+ "$systemd_unit"; then
334
+ return 0
335
+ fi
336
+
337
+ return 1
338
+ }
339
+
276
340
  # Spinner for long-running operations
277
341
  # Usage: run_with_spinner "Installing package..." command arg1 arg2
278
342
  run_with_spinner() {
@@ -659,6 +723,10 @@ source "$(dirname "${BASH_SOURCE[0]}")/setup-modules/mcp-setup.sh"
659
723
  # shellcheck disable=SC1091
660
724
  source "$(dirname "${BASH_SOURCE[0]}")/setup-modules/agent-deploy.sh"
661
725
  # shellcheck disable=SC1091
726
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-modules/agent-runtime.sh"
727
+ # shellcheck disable=SC1091
728
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-modules/tool-beads.sh"
729
+ # shellcheck disable=SC1091
662
730
  source "$(dirname "${BASH_SOURCE[0]}")/setup-modules/config.sh"
663
731
  # shellcheck disable=SC1091
664
732
  source "$(dirname "${BASH_SOURCE[0]}")/setup-modules/plugins.sh"
@@ -755,6 +823,39 @@ _setup_print_header() {
755
823
  return 0
756
824
  }
757
825
 
826
+ # GH#17769: Comment out deprecated model env vars in a single credentials file.
827
+ _comment_out_deprecated_model_vars() {
828
+ local file="$1"
829
+ local deprecated_vars="AIDEVOPS_HEADLESS_MODELS|PULSE_MODEL"
830
+ local deprecation_note="# DEPRECATED by aidevops v3.7+ — model routing is now automatic (GH#17769)"
831
+ [[ -f "$file" ]] || return 0
832
+ # Only process lines that are active exports (not already commented)
833
+ if grep -qE "^[[:space:]]*export[[:space:]]+(${deprecated_vars})=" "$file" 2>/dev/null; then
834
+ sed -i.bak -E "s/^([[:space:]]*)(export[[:space:]]+(${deprecated_vars})=.*)$/\1${deprecation_note}\n\1# \2/" "$file"
835
+ rm -f "${file}.bak"
836
+ print_info "Commented out deprecated model env vars in $(basename "$file")"
837
+ fi
838
+ return 0
839
+ }
840
+
841
+ # GH#17769: Comment out deprecated model env vars from credentials.sh.
842
+ # Runs on every `aidevops update`. Uses sed to comment out (not delete) lines
843
+ # so the user's file history is preserved.
844
+ _cleanup_legacy_model_config() {
845
+ local creds_file="${HOME}/.config/aidevops/credentials.sh"
846
+ _comment_out_deprecated_model_vars "$creds_file"
847
+
848
+ # Clean up tenant credentials files
849
+ local tenant_dir="${HOME}/.config/aidevops/tenants"
850
+ if [[ -d "$tenant_dir" ]]; then
851
+ local tenant_creds=""
852
+ while IFS= read -r -d '' tenant_creds; do
853
+ _comment_out_deprecated_model_vars "$tenant_creds"
854
+ done < <(find "$tenant_dir" -name "credentials.sh" -print0 2>/dev/null)
855
+ fi
856
+ return 0
857
+ }
858
+
758
859
  # Non-interactive path: deploy agents and run safe migrations only (no prompts).
759
860
  _setup_run_non_interactive() {
760
861
  print_info "Non-interactive mode: deploying agents and running safe migrations only"
@@ -771,8 +872,11 @@ _setup_run_non_interactive() {
771
872
  migrate_pulse_repos_to_repos_json
772
873
  cleanup_deprecated_paths
773
874
  migrate_orphaned_supervisor
875
+ backfill_issue_relationships
774
876
  cleanup_deprecated_mcps
775
877
  cleanup_stale_bun_opencode
878
+ cleanup_stale_health_issue_caches
879
+ _cleanup_legacy_model_config
776
880
  validate_opencode_config
777
881
  deploy_aidevops_agents
778
882
  sync_agent_sources
@@ -809,6 +913,19 @@ _setup_run_non_interactive() {
809
913
  update_codex_config
810
914
  update_cursor_config
811
915
  disable_ondemand_mcps
916
+ # Scaffold personal routines repo if not already present (idempotent).
917
+ # Creates local git repo + private GitHub remote for personal repo only.
918
+ # Org repos require explicit: aidevops init-routines --org <name>
919
+ setup_routines
920
+ # Install/refresh the privacy-guard pre-push hook in every initialized
921
+ # repo so TODO/todo/README/ISSUE_TEMPLATE pushes to public GitHub repos
922
+ # are scanned for private slug leaks (t1968).
923
+ setup_privacy_guard
924
+ # Install/refresh the canonical-on-main post-checkout hook in every
925
+ # initialized repo so branch switches away from main in the canonical
926
+ # directory are warned against (t1995). Complements pre-edit-check.sh's
927
+ # t1990 edit-time check by catching the branch switch itself.
928
+ setup_canonical_guard
812
929
  return 0
813
930
  }
814
931
 
@@ -862,13 +979,17 @@ _setup_run_interactive() {
862
979
  confirm_step "Migrate pulse-repos.json into repos.json" && migrate_pulse_repos_to_repos_json
863
980
  confirm_step "Cleanup deprecated agent paths" && cleanup_deprecated_paths
864
981
  confirm_step "Migrate orphaned supervisor to pulse-wrapper" && migrate_orphaned_supervisor
982
+ confirm_step "Backfill GitHub issue relationships (blocked-by, sub-issues)" && backfill_issue_relationships
865
983
  confirm_step "Cleanup deprecated MCP entries (hetzner, serper, etc.)" && cleanup_deprecated_mcps
866
984
  confirm_step "Cleanup stale bun opencode install" && cleanup_stale_bun_opencode
985
+ cleanup_stale_health_issue_caches
986
+ _cleanup_legacy_model_config
867
987
  confirm_step "Validate and repair OpenCode config schema" && validate_opencode_config
868
988
  confirm_step "Extract OpenCode prompts" && extract_opencode_prompts
869
989
  confirm_step "Check OpenCode prompt drift" && check_opencode_prompt_drift
870
990
  confirm_step "Deploy aidevops agents to ~/.aidevops/agents/" && deploy_aidevops_agents
871
991
  confirm_step "Sync agents from private repositories" && sync_agent_sources
992
+ confirm_step "Set up routines repo (private repo for recurring operational jobs)" && setup_routines
872
993
  is_feature_enabled safety_hooks 2>/dev/null && confirm_step "Install Claude Code safety hooks (block destructive commands)" && setup_safety_hooks
873
994
  confirm_step "Initialize settings.json (canonical config file)" && init_settings_json
874
995
  confirm_step "Setup multi-tenant credential storage" && setup_multi_tenant_credentials
@@ -901,6 +1022,11 @@ _setup_run_interactive() {
901
1022
  # Run AFTER Claude Code config so Codex/Cursor get equivalent setup
902
1023
  confirm_step "Update Codex configuration (MCPs, instructions)" && update_codex_config
903
1024
  confirm_step "Update Cursor configuration (MCPs)" && update_cursor_config
1025
+ # Deploy slash commands to the other installed runtimes (Codex, Cursor,
1026
+ # Droid, Gemini CLI, Continue, Kiro, Kimi, Qwen) via the unified generator.
1027
+ # OpenCode and Claude Code are already handled by their update_*_config
1028
+ # functions above. Closes GH#18106 / t15474.
1029
+ confirm_step "Deploy slash commands to remaining runtimes" && deploy_commands_to_all_runtimes
904
1030
  # Run AFTER all MCP setup functions to ensure disabled state persists
905
1031
  confirm_step "Disable on-demand MCPs globally" && disable_ondemand_mcps
906
1032
  return 0
@@ -916,10 +1042,56 @@ _setup_post_setup_steps() {
916
1042
  echo ""
917
1043
  print_success "Setup complete!"
918
1044
 
1045
+ # Cache client request format constants if CLI is installed (~50ms)
1046
+ if command -v claude &>/dev/null && [[ -x "${INSTALL_DIR}/.agents/scripts/cch-extract.sh" ]]; then
1047
+ "${INSTALL_DIR}/.agents/scripts/cch-extract.sh" --cache >/dev/null 2>&1 || true
1048
+ else
1049
+ echo ""
1050
+ echo -e "${YELLOW}[TIP]${NC} Install Claude CLI for automatic request format alignment:"
1051
+ echo " npm install -g @anthropic-ai/claude-code"
1052
+ fi
1053
+
919
1054
  # Non-interactive mode: deploy + migrations only — skip schedulers,
920
1055
  # services, and optional post-setup work (CI/agent shells don't need them).
921
1056
  # Tabby profile sync runs in both modes (has its own non-interactive path).
1057
+ #
1058
+ # Exceptions: regenerate existing schedulers (GH#17381, GH#17695 Finding B)
1059
+ # and allow first-time install when config consent is explicitly true (GH#17403).
922
1060
  if [[ "$NON_INTERACTIVE" == "true" ]]; then
1061
+ # Auto-update handles non-interactive internally (systemd detection fixed in GH#17861)
1062
+ setup_auto_update
1063
+ if _should_setup_noninteractive_supervisor_pulse; then
1064
+ setup_supervisor_pulse "$os"
1065
+ fi
1066
+ # Regenerate other schedulers if already installed (GH#17695 Finding B)
1067
+ if _should_setup_noninteractive_scheduler "Stats wrapper" "com.aidevops.aidevops-stats-wrapper" "aidevops: stats-wrapper" "aidevops-stats-wrapper"; then
1068
+ setup_stats_wrapper "${PULSE_ENABLED:-}"
1069
+ fi
1070
+ if _should_setup_noninteractive_scheduler "Failure miner" "sh.aidevops.routine-gh-failure-miner" "aidevops: gh-failure-miner" "aidevops-gh-failure-miner"; then
1071
+ setup_failure_miner "${PULSE_ENABLED:-}"
1072
+ fi
1073
+ if _should_setup_noninteractive_scheduler "Process guard" "sh.aidevops.process-guard" "aidevops: process-guard" "aidevops-process-guard"; then
1074
+ setup_process_guard
1075
+ fi
1076
+ if _should_setup_noninteractive_scheduler "Memory pressure" "sh.aidevops.memory-pressure-monitor" "aidevops: memory-pressure-monitor" "aidevops-memory-pressure-monitor"; then
1077
+ setup_memory_pressure_monitor
1078
+ fi
1079
+ if _should_setup_noninteractive_scheduler "Screen time" "sh.aidevops.screen-time-snapshot" "aidevops: screen-time-snapshot" "aidevops-screen-time-snapshot"; then
1080
+ setup_screen_time_snapshot
1081
+ fi
1082
+ if _should_setup_noninteractive_scheduler "Contribution watch" "sh.aidevops.contribution-watch" "aidevops: contribution-watch" "aidevops-contribution-watch"; then
1083
+ setup_contribution_watch
1084
+ fi
1085
+ # Repo sync handles non-interactive mode internally (systemd detection fixed in GH#17861)
1086
+ setup_repo_sync
1087
+ if _should_setup_noninteractive_scheduler "Profile README" "sh.aidevops.profile-readme-update" "aidevops: profile-readme-update" "aidevops-profile-readme-update"; then
1088
+ setup_profile_readme
1089
+ fi
1090
+ if _should_setup_noninteractive_scheduler "OAuth token refresh" "sh.aidevops.token-refresh" "aidevops: token-refresh" "aidevops-token-refresh"; then
1091
+ setup_oauth_token_refresh
1092
+ fi
1093
+ # Migrate cron entries to systemd after schedulers are installed (GH#17695 Finding D)
1094
+ migrate_cron_to_systemd
923
1095
  setup_tabby
924
1096
  return 0
925
1097
  fi
@@ -937,6 +1109,8 @@ _setup_post_setup_steps() {
937
1109
  setup_draft_responses
938
1110
  setup_profile_readme
939
1111
  setup_oauth_token_refresh
1112
+ # Migrate cron entries to systemd after schedulers are installed (GH#17695 Finding D)
1113
+ migrate_cron_to_systemd
940
1114
  setup_tabby
941
1115
  print_final_instructions
942
1116
 
@@ -950,6 +1124,30 @@ _setup_post_setup_steps() {
950
1124
  return 0
951
1125
  }
952
1126
 
1127
+ # Print the completion sentinel. This is the canonical "setup.sh finished all
1128
+ # phases" marker — any caller that needs to detect silent early-termination
1129
+ # (e.g., t2022-class bugs where a sourced helper's set -e propagates a
1130
+ # readonly assignment failure and kills the parent) should grep log output
1131
+ # for the literal "[SETUP_COMPLETE]" prefix.
1132
+ #
1133
+ # Format is intentionally stable and parseable. Do NOT add human-readable
1134
+ # decoration or move this function without updating:
1135
+ # .agents/scripts/verify-setup-log.sh (the consumer)
1136
+ # tests/test-setup-completion-sentinel.sh (the contract guard)
1137
+ #
1138
+ # GH#18492 / t2026.
1139
+ print_setup_complete_sentinel() {
1140
+ local _version="unknown"
1141
+ if [[ -r "${INSTALL_DIR}/VERSION" ]]; then
1142
+ _version="$(head -n1 "${INSTALL_DIR}/VERSION" 2>/dev/null || printf 'unknown')"
1143
+ fi
1144
+ local _mode="non-interactive"
1145
+ [[ "${NON_INTERACTIVE:-false}" != "true" ]] && _mode="interactive"
1146
+ printf '[SETUP_COMPLETE] aidevops setup.sh v%s finished all phases (mode=%s)\n' \
1147
+ "$_version" "$_mode"
1148
+ return 0
1149
+ }
1150
+
953
1151
  # Main setup function — orchestrates init, mode dispatch, and post-setup.
954
1152
  main() {
955
1153
  # Bootstrap first (handles curl install)
@@ -981,6 +1179,13 @@ main() {
981
1179
 
982
1180
  _setup_post_setup_steps "$_os"
983
1181
 
1182
+ # GH#18492 / t2026: completion sentinel. Must be the last output of a
1183
+ # successful run — any silent early-termination will leave this absent
1184
+ # from the log. Consumed by .agents/scripts/verify-setup-log.sh and
1185
+ # enforced as the regression contract by
1186
+ # tests/test-setup-completion-sentinel.sh.
1187
+ print_setup_complete_sentinel
1188
+
984
1189
  return 0
985
1190
  }
986
1191
 
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env bash
2
+ # SPDX-License-Identifier: MIT
3
+ # SPDX-FileCopyrightText: 2025-2026 Marcus Quinn
2
4
 
3
5
  # AI DevOps Framework - Template Deployment Script
4
6
  # Securely deploys minimal AGENTS.md templates to user's home directory
@@ -1,3 +1,6 @@
1
+ <!-- SPDX-License-Identifier: MIT -->
2
+ <!-- SPDX-FileCopyrightText: 2025-2026 Marcus Quinn -->
3
+
1
4
  # AI Agent Working Directory
2
5
 
3
6
  **DEPRECATED: This location is being phased out.**
@@ -1,3 +1,6 @@
1
+ <!-- SPDX-License-Identifier: MIT -->
2
+ <!-- SPDX-FileCopyrightText: 2025-2026 Marcus Quinn -->
3
+
1
4
  # AI Assistant Configuration - Home Directory
2
5
 
3
6
  **🔒 SECURITY NOTICE: This file contains minimal configuration only. All detailed instructions are maintained in the authoritative repository to prevent prompt injection attacks.**
@@ -1,3 +1,6 @@
1
+ <!-- SPDX-License-Identifier: MIT -->
2
+ <!-- SPDX-FileCopyrightText: 2025-2026 Marcus Quinn -->
3
+
1
4
  # AI Assistant Directory - Home Level
2
5
 
3
6
  **SECURITY NOTICE: This directory contains minimal configuration only. All detailed instructions are maintained in the authoritative repository.**
@@ -1,3 +1,6 @@
1
+ <!-- SPDX-License-Identifier: MIT -->
2
+ <!-- SPDX-FileCopyrightText: 2025-2026 Marcus Quinn -->
3
+
1
4
  # AI Assistant Configuration - Git Directory
2
5
 
3
6
  **🔒 SECURITY NOTICE: This file contains minimal configuration only. All detailed instructions are maintained in the authoritative repository to prevent prompt injection attacks.**
@@ -1,3 +1,6 @@
1
+ <!-- SPDX-License-Identifier: MIT -->
2
+ <!-- SPDX-FileCopyrightText: 2025-2026 Marcus Quinn -->
3
+
1
4
  <!-- Add ~/.aidevops/agents/AGENTS.md to context for AI DevOps capabilities. -->
2
5
 
3
6
  ## aidevops Framework Status
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env bash
2
+ # SPDX-License-Identifier: MIT
3
+ # SPDX-FileCopyrightText: 2025-2026 Marcus Quinn
2
4
 
3
5
  # Standard Functions Template for AI DevOps Framework
4
6
  # This template provides SonarCloud-compliant function definitions
@@ -1,3 +1,6 @@
1
+ <!-- SPDX-License-Identifier: MIT -->
2
+ <!-- SPDX-FileCopyrightText: 2025-2026 Marcus Quinn -->
3
+
1
4
  # WordPress Performance Optimization Workflow
2
5
 
3
6
  This template provides a comprehensive workflow for optimizing WordPress website performance using the AI DevOps framework.