aidevops 3.0.11 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.11
1
+ 3.1.0
package/aidevops.sh CHANGED
@@ -3,7 +3,7 @@
3
3
  # AI DevOps Framework CLI
4
4
  # Usage: aidevops <command> [options]
5
5
  #
6
- # Version: 3.0.11
6
+ # Version: 3.1.0
7
7
 
8
8
  set -euo pipefail
9
9
 
@@ -102,6 +102,14 @@ check_file() {
102
102
  [[ -f "$1" ]]
103
103
  }
104
104
 
105
+ # Ensure file ends with a trailing newline (prevents malformed appends)
106
+ ensure_trailing_newline() {
107
+ local file="$1"
108
+ local last
109
+ last="$(tail -c 1 "$file"; printf x)"
110
+ [[ -s "$file" ]] && [[ "$last" != $'\n'x ]] && printf '\n' >>"$file"
111
+ }
112
+
105
113
  # Initialize repos.json if it doesn't exist
106
114
  init_repos_file() {
107
115
  if [[ ! -f "$REPOS_FILE" ]]; then
@@ -1936,7 +1944,7 @@ SOPSEOF
1936
1944
  # Add runtime artifact ignores
1937
1945
  if ! grep -q "^\.agents/loop-state/" "$gitignore" 2>/dev/null; then
1938
1946
  # Ensure trailing newline before appending (prevents malformed entries like *.zip.agents/loop-state/)
1939
- [[ -s "$gitignore" && $(tail -c1 "$gitignore" | wc -l) -eq 0 ]] && printf '\n' >>"$gitignore"
1947
+ ensure_trailing_newline "$gitignore"
1940
1948
  {
1941
1949
  echo ""
1942
1950
  echo "# aidevops runtime artifacts"
@@ -1958,7 +1966,7 @@ SOPSEOF
1958
1966
  print_info "Untracked .aidevops.json from git (was committed by older version)"
1959
1967
  fi
1960
1968
  # Ensure trailing newline before appending
1961
- [[ -s "$gitignore" && $(tail -c1 "$gitignore" | wc -l) -eq 0 ]] && printf '\n' >>"$gitignore"
1969
+ ensure_trailing_newline "$gitignore"
1962
1970
  echo ".aidevops.json" >>"$gitignore"
1963
1971
  gitignore_updated=true
1964
1972
  fi
@@ -1967,7 +1975,7 @@ SOPSEOF
1967
1975
  if [[ "$enable_beads" == "true" ]]; then
1968
1976
  if ! grep -q "^\.beads$" "$gitignore" 2>/dev/null; then
1969
1977
  # Ensure trailing newline before appending
1970
- [[ -s "$gitignore" && $(tail -c1 "$gitignore" | wc -l) -eq 0 ]] && printf '\n' >>"$gitignore"
1978
+ ensure_trailing_newline "$gitignore"
1971
1979
  echo ".beads" >>"$gitignore"
1972
1980
  print_success "Added .beads to .gitignore"
1973
1981
  gitignore_updated=true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aidevops",
3
- "version": "3.0.11",
3
+ "version": "3.1.0",
4
4
  "description": "AI DevOps Framework - AI-assisted development workflows, code quality, and deployment automation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -37,6 +37,22 @@ cleanup_deprecated_paths() {
37
37
  "$agents_dir/youtube"
38
38
  # osgrep removed — disproportionate CPU/disk cost vs rg + LLM comprehension
39
39
  "$agents_dir/tools/context/osgrep.md"
40
+ # GH#5155: scripts archived upstream but orphaned in deployed installs
41
+ # (rsync only adds/overwrites, doesn't delete removed files)
42
+ "$agents_dir/scripts/pattern-tracker-helper.sh"
43
+ "$agents_dir/scripts/quality-sweep-helper.sh"
44
+ "$agents_dir/scripts/quality-loop-helper.sh"
45
+ "$agents_dir/scripts/review-pulse-helper.sh"
46
+ "$agents_dir/scripts/self-improve-helper.sh"
47
+ "$agents_dir/scripts/coderabbit-pulse-helper.sh"
48
+ "$agents_dir/scripts/coderabbit-task-creator-helper.sh"
49
+ "$agents_dir/scripts/audit-task-creator-helper.sh"
50
+ "$agents_dir/scripts/batch-cleanup-helper.sh"
51
+ "$agents_dir/scripts/coordinator-helper.sh"
52
+ "$agents_dir/scripts/finding-to-task-helper.sh"
53
+ "$agents_dir/scripts/objective-runner-helper.sh"
54
+ "$agents_dir/scripts/ralph-loop-helper.sh"
55
+ "$agents_dir/scripts/stale-pr-helper.sh"
40
56
  )
41
57
 
42
58
  for path in "${deprecated_paths[@]}"; do
@@ -963,3 +979,88 @@ migrate_pulse_repos_to_repos_json() {
963
979
 
964
980
  return 0
965
981
  }
982
+
983
+ # Migrate orphaned supervisor-helper.sh and supervisor/ modules (GH#5147)
984
+ # After the supervisor-to-pulse-wrapper migration (PR #2291, PR #2475), the
985
+ # upstream repo moved supervisor files to supervisor-archived/. But aidevops
986
+ # update (rsync) only adds/overwrites — it doesn't delete files that no longer
987
+ # exist in the source. Users who installed before the migration retain:
988
+ # - ~/.aidevops/agents/scripts/supervisor-helper.sh (old entry point)
989
+ # - ~/.aidevops/agents/scripts/supervisor/ (old module directory)
990
+ # - cron/launchd entries invoking supervisor-helper.sh pulse
991
+ # These orphaned files shadow the new pulse-wrapper.sh architecture.
992
+ # This migration removes the orphaned files and rewrites scheduler entries.
993
+ migrate_orphaned_supervisor() {
994
+ local agents_dir="$HOME/.aidevops/agents"
995
+ local scripts_dir="$agents_dir/scripts"
996
+ local cleaned=0
997
+
998
+ # 1. Remove orphaned supervisor-helper.sh from deployed scripts
999
+ # The canonical location is now supervisor-archived/supervisor-helper.sh
1000
+ # (shipped for reference/tests only, not as an active entry point)
1001
+ if [[ -f "$scripts_dir/supervisor-helper.sh" ]]; then
1002
+ rm -f "$scripts_dir/supervisor-helper.sh"
1003
+ print_info "Removed orphaned supervisor-helper.sh from deployed scripts"
1004
+ ((++cleaned))
1005
+ fi
1006
+
1007
+ # 2. Remove orphaned supervisor/ module directory
1008
+ # The canonical location is now supervisor-archived/ (shipped by rsync)
1009
+ # Only remove if it's the old modules dir (contains pulse.sh, dispatch.sh, etc.)
1010
+ # Do NOT remove supervisor-archived/ — that's the intentional archive
1011
+ if [[ -d "$scripts_dir/supervisor" && ! -L "$scripts_dir/supervisor" ]]; then
1012
+ # Verify it's the old module directory (not something user-created)
1013
+ if [[ -f "$scripts_dir/supervisor/pulse.sh" ]] ||
1014
+ [[ -f "$scripts_dir/supervisor/dispatch.sh" ]] ||
1015
+ [[ -f "$scripts_dir/supervisor/_common.sh" ]]; then
1016
+ rm -rf "$scripts_dir/supervisor"
1017
+ print_info "Removed orphaned supervisor/ module directory from deployed scripts"
1018
+ ((++cleaned))
1019
+ fi
1020
+ fi
1021
+
1022
+ # 3. Migrate cron entries from supervisor-helper.sh to pulse-wrapper.sh
1023
+ # Old pattern: */2 * * * * ... supervisor-helper.sh pulse ...
1024
+ # New pattern: already installed by setup.sh's pulse section
1025
+ # Strategy: remove old entries; setup.sh will install the new one if pulse is enabled
1026
+ local current_crontab
1027
+ current_crontab=$(crontab -l 2>/dev/null) || current_crontab=""
1028
+ if echo "$current_crontab" | grep -qF "supervisor-helper.sh"; then
1029
+ # Remove all cron lines referencing supervisor-helper.sh
1030
+ local new_crontab
1031
+ new_crontab=$(echo "$current_crontab" | grep -v "supervisor-helper.sh")
1032
+ if [[ -n "$new_crontab" ]]; then
1033
+ printf '%s\n' "$new_crontab" | crontab - || true
1034
+ else
1035
+ # All entries were supervisor-helper.sh — remove crontab entirely
1036
+ crontab -r || true
1037
+ fi
1038
+ print_info "Removed orphaned supervisor-helper.sh cron entries"
1039
+ print_info " pulse-wrapper.sh will be installed by setup.sh if supervisor pulse is enabled"
1040
+ ((++cleaned))
1041
+ fi
1042
+
1043
+ # 4. Migrate launchd entries from old supervisor label (macOS only)
1044
+ # Old label: com.aidevops.supervisor-pulse (from cron.sh/launchd.sh)
1045
+ # New label: com.aidevops.aidevops-supervisor-pulse (from setup.sh)
1046
+ # setup.sh already handles the new label cleanup at line ~1000, but
1047
+ # the old label from cron.sh may also be present
1048
+ if [[ "$(uname -s)" == "Darwin" ]]; then
1049
+ local old_label="com.aidevops.supervisor-pulse"
1050
+ local old_plist="$HOME/Library/LaunchAgents/${old_label}.plist"
1051
+ if _launchd_has_agent "$old_label" || [[ -f "$old_plist" ]]; then
1052
+ # Use launchctl remove by label — works even when the plist file is
1053
+ # missing (orphaned agent loaded without a backing file on disk)
1054
+ launchctl remove "$old_label" || true
1055
+ rm -f "$old_plist"
1056
+ print_info "Removed orphaned supervisor-pulse LaunchAgent ($old_label)"
1057
+ ((++cleaned))
1058
+ fi
1059
+ fi
1060
+
1061
+ if [[ $cleaned -gt 0 ]]; then
1062
+ print_success "Cleaned up $cleaned orphaned supervisor artifact(s) — pulse-wrapper.sh is the active system"
1063
+ fi
1064
+
1065
+ return 0
1066
+ }
@@ -57,7 +57,7 @@ setup_git_clis() {
57
57
  echo "📋 Next steps - authenticate each CLI:"
58
58
  for pkg in "${missing_packages[@]}"; do
59
59
  case "$pkg" in
60
- gh) echo " • gh auth login" ;;
60
+ gh) echo " • gh auth login -s workflow (workflow scope required for CI PRs)" ;;
61
61
  glab) echo " • glab auth login" ;;
62
62
  esac
63
63
  done
package/setup.sh CHANGED
@@ -10,7 +10,7 @@ shopt -s inherit_errexit 2>/dev/null || true
10
10
  # AI Assistant Server Access Framework Setup Script
11
11
  # Helps developers set up the framework for their infrastructure
12
12
  #
13
- # Version: 3.0.11
13
+ # Version: 3.1.0
14
14
  #
15
15
  # Quick Install:
16
16
  # npm install -g aidevops && aidevops update (recommended)
@@ -716,6 +716,7 @@ main() {
716
716
  migrate_mcp_env_to_credentials
717
717
  migrate_pulse_repos_to_repos_json
718
718
  cleanup_deprecated_paths
719
+ migrate_orphaned_supervisor
719
720
  cleanup_deprecated_mcps
720
721
  cleanup_stale_bun_opencode
721
722
  validate_opencode_config
@@ -795,6 +796,7 @@ main() {
795
796
  confirm_step "Migrate mcp-env.sh -> credentials.sh" && migrate_mcp_env_to_credentials
796
797
  confirm_step "Migrate pulse-repos.json into repos.json" && migrate_pulse_repos_to_repos_json
797
798
  confirm_step "Cleanup deprecated agent paths" && cleanup_deprecated_paths
799
+ confirm_step "Migrate orphaned supervisor to pulse-wrapper" && migrate_orphaned_supervisor
798
800
  confirm_step "Cleanup deprecated MCP entries (hetzner, serper, etc.)" && cleanup_deprecated_mcps
799
801
  confirm_step "Cleanup stale bun opencode install" && cleanup_stale_bun_opencode
800
802
  confirm_step "Validate and repair OpenCode config schema" && validate_opencode_config
@@ -892,10 +894,6 @@ main() {
892
894
  # - Non-interactive: only installs if config explicitly says true
893
895
  local wrapper_script="$HOME/.aidevops/agents/scripts/pulse-wrapper.sh"
894
896
  local pulse_label="com.aidevops.aidevops-supervisor-pulse"
895
- local _aidevops_dir _pulse_repo_dir
896
- _aidevops_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
897
- _pulse_repo_dir=$(_resolve_main_worktree_dir "$_aidevops_dir")
898
-
899
897
  # Read explicit user consent from config.jsonc (not merged defaults).
900
898
  # Empty = user never configured this; "true"/"false" = explicit choice.
901
899
  local _pulse_user_config=""
@@ -1009,12 +1007,14 @@ main() {
1009
1007
 
1010
1008
  # XML-escape paths for safe plist embedding (prevents injection
1011
1009
  # if $HOME or paths contain &, <, > characters)
1012
- local _xml_wrapper_script _xml_home _xml_opencode_bin _xml_aidevops_dir _xml_path
1010
+ local _xml_wrapper_script _xml_home _xml_opencode_bin _xml_pulse_dir _xml_path
1013
1011
  local _headless_xml_env=""
1014
1012
  _xml_wrapper_script=$(_xml_escape "$wrapper_script")
1015
1013
  _xml_home=$(_xml_escape "$HOME")
1016
1014
  _xml_opencode_bin=$(_xml_escape "$opencode_bin")
1017
- _xml_aidevops_dir=$(_xml_escape "$_pulse_repo_dir")
1015
+ # Use neutral workspace path for PULSE_DIR so supervisor sessions
1016
+ # are not associated with any specific managed repo (GH#5136).
1017
+ _xml_pulse_dir=$(_xml_escape "${HOME}/.aidevops/.agent-workspace")
1018
1018
  _xml_path=$(_xml_escape "$PATH")
1019
1019
  if [[ -n "${AIDEVOPS_HEADLESS_MODELS:-}" ]]; then
1020
1020
  local _xml_headless_models
@@ -1061,7 +1061,7 @@ main() {
1061
1061
  <key>OPENCODE_BIN</key>
1062
1062
  <string>${_xml_opencode_bin}</string>
1063
1063
  <key>PULSE_DIR</key>
1064
- <string>${_xml_aidevops_dir}</string>
1064
+ <string>${_xml_pulse_dir}</string>
1065
1065
  <key>PULSE_STALE_THRESHOLD</key>
1066
1066
  <string>1800</string>
1067
1067
  ${_headless_xml_env}
@@ -1092,8 +1092,9 @@ PLIST
1092
1092
  # PATH= here, it overrides the global line and breaks nvm/bun/cargo.
1093
1093
  # OPENCODE_BIN removed — resolved from PATH at runtime via command -v.
1094
1094
  # See #4099 and #4240 for history.
1095
- local _cron_aidevops_dir _cron_wrapper_script _cron_headless_env=""
1096
- _cron_aidevops_dir=$(_cron_escape "$_pulse_repo_dir")
1095
+ local _cron_pulse_dir _cron_wrapper_script _cron_headless_env=""
1096
+ # Use neutral workspace path for PULSE_DIR (GH#5136)
1097
+ _cron_pulse_dir=$(_cron_escape "${HOME}/.aidevops/.agent-workspace")
1097
1098
  _cron_wrapper_script=$(_cron_escape "$wrapper_script")
1098
1099
  if [[ -n "${AIDEVOPS_HEADLESS_MODELS:-}" ]]; then
1099
1100
  local _cron_headless_models
@@ -1107,7 +1108,7 @@ PLIST
1107
1108
  fi
1108
1109
  (
1109
1110
  crontab -l 2>/dev/null | grep -v 'aidevops: supervisor-pulse'
1110
- echo "*/2 * * * * PULSE_DIR=${_cron_aidevops_dir}${_cron_headless_env} /bin/bash ${_cron_wrapper_script} >> \"\$HOME/.aidevops/logs/pulse-wrapper.log\" 2>&1 # aidevops: supervisor-pulse"
1111
+ echo "*/2 * * * * PULSE_DIR=${_cron_pulse_dir}${_cron_headless_env} /bin/bash ${_cron_wrapper_script} >> \"\$HOME/.aidevops/logs/pulse-wrapper.log\" 2>&1 # aidevops: supervisor-pulse"
1111
1112
  ) | crontab - || true
1112
1113
  if crontab -l 2>/dev/null | grep -qF "aidevops: supervisor-pulse"; then
1113
1114
  print_info "Supervisor pulse enabled (cron, every 2 min). Disable: crontab -e and remove the supervisor-pulse line"