aidevops 3.13.95 → 3.14.1
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 +0 -1
- package/VERSION +1 -1
- package/aidevops.sh +44 -26
- package/package.json +1 -1
- package/setup.sh +25 -21
- package/aidevops-init-lib.sh +0 -1411
- package/aidevops-repos-lib.sh +0 -700
- package/aidevops-skills-plugin-lib.sh +0 -697
- package/aidevops-status-lib.sh +0 -141
- package/aidevops-update-lib.sh +0 -512
- package/aidevops-upgrade-planning-lib.sh +0 -370
- package/setup-modules/agent-deploy.sh +0 -1035
- package/setup-modules/agent-runtime.sh +0 -287
- package/setup-modules/config.sh +0 -478
- package/setup-modules/core.sh +0 -736
- package/setup-modules/mcp-setup.sh +0 -947
- package/setup-modules/migrations.sh +0 -1688
- package/setup-modules/plugins.sh +0 -728
- package/setup-modules/post-setup.sh +0 -301
- package/setup-modules/schedulers-linux.sh +0 -386
- package/setup-modules/schedulers-platform.sh +0 -1072
- package/setup-modules/schedulers-pulse.sh +0 -978
- package/setup-modules/schedulers.sh +0 -565
- package/setup-modules/shell-env.sh +0 -1240
- package/setup-modules/tool-beads.sh +0 -324
- package/setup-modules/tool-install.sh +0 -2134
|
@@ -1,565 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# SPDX-FileCopyrightText: 2025-2026 Marcus Quinn
|
|
4
|
-
# Scheduler setup orchestrator: sources sub-libraries and provides the
|
|
5
|
-
# monitoring-tier setup functions (stats wrapper, failure miner, process
|
|
6
|
-
# guard, memory pressure monitor, screen time snapshot).
|
|
7
|
-
# Part of aidevops setup.sh modularization (GH#5793)
|
|
8
|
-
#
|
|
9
|
-
# Split from a 2754-line monolith (GH#21052) into three focused sub-libraries:
|
|
10
|
-
# - schedulers-pulse.sh (pulse resolution, supervisor, plist, watchdog)
|
|
11
|
-
# - schedulers-linux.sh (systemd/cron scheduler install/uninstall)
|
|
12
|
-
# - schedulers-platform.sh (contribution watch, complexity scan, profile
|
|
13
|
-
# README, token refresh, DB maintenance, repo
|
|
14
|
-
# health, peer productivity monitor)
|
|
15
|
-
#
|
|
16
|
-
# Functions that remain here (setup_failure_miner is >100 lines; identity-key
|
|
17
|
-
# rule from reference/large-file-split.md §3 requires it stays in this file):
|
|
18
|
-
# setup_stats_wrapper, setup_failure_miner, setup_process_guard,
|
|
19
|
-
# setup_memory_pressure_monitor, setup_screen_time_snapshot
|
|
20
|
-
|
|
21
|
-
# Keep pulse workers alive long enough for opus-tier dispatches.
|
|
22
|
-
PULSE_STALE_THRESHOLD_SECONDS=1800
|
|
23
|
-
|
|
24
|
-
# Cron expression: top of every hour. Shared by stats-wrapper,
|
|
25
|
-
# contribution-watch, and profile-readme schedulers — keep DRY so a
|
|
26
|
-
# future cadence shift only touches one place.
|
|
27
|
-
CRON_HOURLY="0 * * * *"
|
|
28
|
-
|
|
29
|
-
# Cron expression: every minute. Shared by process-guard, memory-pressure
|
|
30
|
-
# monitor, and pulse-watchdog schedulers (cron's minimum granularity).
|
|
31
|
-
# Kept DRY for the same reason as CRON_HOURLY.
|
|
32
|
-
CRON_EVERY_MINUTE="* * * * *"
|
|
33
|
-
|
|
34
|
-
# Direct unit tests source this module without setup.sh's later
|
|
35
|
-
# shared-constants.sh load. Provide a small fallback; the shared helper
|
|
36
|
-
# overwrites this when setup.sh sources shared-constants.sh.
|
|
37
|
-
if ! declare -F aidevops_launchd_sanitized_path >/dev/null 2>&1; then
|
|
38
|
-
aidevops_launchd_sanitized_path() {
|
|
39
|
-
local input_path="${1:-${PATH:-}}"
|
|
40
|
-
local default_path="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
|
|
41
|
-
local result=""
|
|
42
|
-
local seen=""
|
|
43
|
-
local dir=""
|
|
44
|
-
local old_ifs="$IFS"
|
|
45
|
-
IFS=':'
|
|
46
|
-
for dir in $default_path:$input_path; do
|
|
47
|
-
[[ -n "$dir" && -d "$dir" ]] || continue
|
|
48
|
-
case ":$seen:" in
|
|
49
|
-
*":${dir}:"*) continue ;;
|
|
50
|
-
esac
|
|
51
|
-
seen="${seen:+${seen}:}${dir}"
|
|
52
|
-
result="${result:+${result}:}${dir}"
|
|
53
|
-
done
|
|
54
|
-
IFS="$old_ifs"
|
|
55
|
-
printf '%s' "$result"
|
|
56
|
-
return 0
|
|
57
|
-
}
|
|
58
|
-
fi
|
|
59
|
-
|
|
60
|
-
# Shell safety baseline
|
|
61
|
-
set -Eeuo pipefail
|
|
62
|
-
IFS=$'\n\t'
|
|
63
|
-
# shellcheck disable=SC2154 # rc is assigned by $? in the trap string
|
|
64
|
-
trap 'rc=$?; echo "[ERROR] ${BASH_SOURCE[0]}:${LINENO} exit $rc" >&2' ERR
|
|
65
|
-
shopt -s inherit_errexit 2>/dev/null || true
|
|
66
|
-
|
|
67
|
-
# SCRIPT_DIR — resolves to the setup-modules/ directory so sub-library
|
|
68
|
-
# source calls work regardless of the caller's working directory or any
|
|
69
|
-
# inherited SCRIPT_DIR from parent scripts. Always derive from ${BASH_SOURCE[0]}
|
|
70
|
-
# to ensure sub-libraries load from the correct location.
|
|
71
|
-
_sched_orch_lib_path="${BASH_SOURCE[0]%/*}"
|
|
72
|
-
[[ "$_sched_orch_lib_path" == "${BASH_SOURCE[0]}" ]] && _sched_orch_lib_path="."
|
|
73
|
-
SCRIPT_DIR="$(cd "$_sched_orch_lib_path" && pwd)"
|
|
74
|
-
unset _sched_orch_lib_path
|
|
75
|
-
|
|
76
|
-
# Source sub-libraries. Each carries its own include guard so double-sourcing
|
|
77
|
-
# is safe. SC1091 suppressed per reference/large-file-split.md §5.1 — paths
|
|
78
|
-
# are computed at runtime via $SCRIPT_DIR and cannot be statically resolved.
|
|
79
|
-
|
|
80
|
-
# shellcheck source=./schedulers-pulse.sh
|
|
81
|
-
# shellcheck disable=SC1091 # sub-library resolved at runtime via $SCRIPT_DIR
|
|
82
|
-
source "${SCRIPT_DIR}/schedulers-pulse.sh"
|
|
83
|
-
|
|
84
|
-
# shellcheck source=./schedulers-linux.sh
|
|
85
|
-
# shellcheck disable=SC1091 # sub-library resolved at runtime via $SCRIPT_DIR
|
|
86
|
-
source "${SCRIPT_DIR}/schedulers-linux.sh"
|
|
87
|
-
|
|
88
|
-
# shellcheck source=./schedulers-platform.sh
|
|
89
|
-
# shellcheck disable=SC1091 # sub-library resolved at runtime via $SCRIPT_DIR
|
|
90
|
-
source "${SCRIPT_DIR}/schedulers-platform.sh"
|
|
91
|
-
|
|
92
|
-
# Setup stats-wrapper scheduler — runs quality sweep and health issue updates
|
|
93
|
-
# separately from the pulse (t1429). Only installed when the supervisor
|
|
94
|
-
# pulse is enabled (stats are useless without it).
|
|
95
|
-
# macOS: launchd plist (hourly) | Linux: systemd timer or cron (hourly)
|
|
96
|
-
# t2744: interval raised from 15 min → hourly. Stats UI is not realtime,
|
|
97
|
-
# the four-times-an-hour cadence drove ~200-400 GraphQL points/hr of pure
|
|
98
|
-
# overhead on multi-repo setups.
|
|
99
|
-
setup_stats_wrapper() {
|
|
100
|
-
local _pulse_lower="$1"
|
|
101
|
-
# Use effective pulse state (PULSE_ENABLED) if available; fall back to consent string.
|
|
102
|
-
# PULSE_ENABLED reflects the actual install decision (e.g., false when wrapper is missing).
|
|
103
|
-
local _pulse_effective="${PULSE_ENABLED:-$_pulse_lower}"
|
|
104
|
-
local stats_script="$HOME/.aidevops/agents/scripts/stats-wrapper.sh"
|
|
105
|
-
local stats_label="com.aidevops.aidevops-stats-wrapper"
|
|
106
|
-
local stats_systemd="aidevops-stats-wrapper"
|
|
107
|
-
local stats_log="$HOME/.aidevops/logs/stats.log"
|
|
108
|
-
if [[ -x "$stats_script" ]] && [[ "$_pulse_effective" == "true" ]]; then
|
|
109
|
-
# Always regenerate to pick up config/format changes (matches pulse behavior)
|
|
110
|
-
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
111
|
-
local stats_plist="$HOME/Library/LaunchAgents/${stats_label}.plist"
|
|
112
|
-
|
|
113
|
-
local _xml_stats_script _xml_stats_home _xml_stats_path
|
|
114
|
-
_xml_stats_script=$(_xml_escape "$stats_script")
|
|
115
|
-
_xml_stats_home=$(_xml_escape "$HOME")
|
|
116
|
-
_xml_stats_path=$(_xml_escape "$(aidevops_launchd_sanitized_path "$PATH")")
|
|
117
|
-
local stats_plist_content
|
|
118
|
-
stats_plist_content=$(
|
|
119
|
-
cat <<PLIST
|
|
120
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
121
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
122
|
-
<plist version="1.0">
|
|
123
|
-
<dict>
|
|
124
|
-
<key>Label</key>
|
|
125
|
-
<string>${stats_label}</string>
|
|
126
|
-
<key>ProgramArguments</key>
|
|
127
|
-
<array>
|
|
128
|
-
<string>$(_xml_escape "$(_resolve_modern_bash)")</string>
|
|
129
|
-
<string>${_xml_stats_script}</string>
|
|
130
|
-
</array>
|
|
131
|
-
<key>StartInterval</key>
|
|
132
|
-
<integer>3600</integer>
|
|
133
|
-
<key>StandardOutPath</key>
|
|
134
|
-
<string>${_xml_stats_home}/.aidevops/logs/stats.log</string>
|
|
135
|
-
<key>StandardErrorPath</key>
|
|
136
|
-
<string>${_xml_stats_home}/.aidevops/logs/stats.log</string>
|
|
137
|
-
<key>EnvironmentVariables</key>
|
|
138
|
-
<dict>
|
|
139
|
-
<key>PATH</key>
|
|
140
|
-
<string>${_xml_stats_path}</string>
|
|
141
|
-
<key>HOME</key>
|
|
142
|
-
<string>${_xml_stats_home}</string>
|
|
143
|
-
</dict>
|
|
144
|
-
<key>RunAtLoad</key>
|
|
145
|
-
<true/>
|
|
146
|
-
<key>KeepAlive</key>
|
|
147
|
-
<false/>
|
|
148
|
-
</dict>
|
|
149
|
-
</plist>
|
|
150
|
-
PLIST
|
|
151
|
-
)
|
|
152
|
-
if _launchd_install_if_changed "$stats_label" "$stats_plist" "$stats_plist_content"; then
|
|
153
|
-
print_info "Stats wrapper enabled (launchd, every hour)"
|
|
154
|
-
else
|
|
155
|
-
print_warning "Failed to load stats wrapper LaunchAgent"
|
|
156
|
-
fi
|
|
157
|
-
else
|
|
158
|
-
_install_scheduler_linux \
|
|
159
|
-
"$stats_systemd" \
|
|
160
|
-
"aidevops: stats-wrapper" \
|
|
161
|
-
"$CRON_HOURLY" \
|
|
162
|
-
"\"${stats_script}\"" \
|
|
163
|
-
"3600" \
|
|
164
|
-
"$stats_log" \
|
|
165
|
-
"" \
|
|
166
|
-
"Stats wrapper enabled (every hour)" \
|
|
167
|
-
"Failed to install stats wrapper scheduler" \
|
|
168
|
-
"true" \
|
|
169
|
-
"false"
|
|
170
|
-
fi
|
|
171
|
-
elif [[ "$_pulse_effective" == "false" ]]; then
|
|
172
|
-
# Remove stats scheduler if pulse is disabled
|
|
173
|
-
_uninstall_scheduler \
|
|
174
|
-
"$(uname -s)" \
|
|
175
|
-
"$stats_label" \
|
|
176
|
-
"$stats_systemd" \
|
|
177
|
-
"aidevops: stats-wrapper" \
|
|
178
|
-
"Stats wrapper disabled (pulse is off)"
|
|
179
|
-
fi
|
|
180
|
-
return 0
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
# Setup failure miner — mines GitHub CI failure notifications for systemic patterns
|
|
184
|
-
# and auto-files root-cause issues. Runs as a pure bash script (no LLM needed).
|
|
185
|
-
# Installed when pulse is enabled and the helper script exists.
|
|
186
|
-
# macOS: launchd plist (hourly at :15) | Linux: systemd timer or cron (hourly at :15)
|
|
187
|
-
#
|
|
188
|
-
# NOTE: This function is 105 lines and must remain in this file (schedulers.sh) to
|
|
189
|
-
# preserve its (file, fname) identity key for the function-complexity CI scanner.
|
|
190
|
-
# Moving it to a sub-library would register it as a new violation.
|
|
191
|
-
# See reference/large-file-split.md §3 "Identity-Key Preservation Rules".
|
|
192
|
-
setup_failure_miner() {
|
|
193
|
-
local _pulse_lower="$1"
|
|
194
|
-
local _pulse_effective="${PULSE_ENABLED:-$_pulse_lower}"
|
|
195
|
-
local miner_script="$HOME/.aidevops/agents/scripts/gh-failure-miner-helper.sh"
|
|
196
|
-
local miner_label="sh.aidevops.routine-gh-failure-miner"
|
|
197
|
-
local miner_systemd="aidevops-gh-failure-miner"
|
|
198
|
-
local miner_log="$HOME/.aidevops/logs/routine-gh-failure-miner.log"
|
|
199
|
-
if [[ ! -x "$miner_script" ]] || [[ "$_pulse_effective" != "true" ]]; then
|
|
200
|
-
# Remove scheduler if pulse is disabled or script missing
|
|
201
|
-
_uninstall_scheduler \
|
|
202
|
-
"$(uname -s)" \
|
|
203
|
-
"$miner_label" \
|
|
204
|
-
"$miner_systemd" \
|
|
205
|
-
"aidevops: gh-failure-miner" \
|
|
206
|
-
"Failure miner disabled (pulse is off or script missing)"
|
|
207
|
-
return 0
|
|
208
|
-
fi
|
|
209
|
-
|
|
210
|
-
mkdir -p "$HOME/.aidevops/logs"
|
|
211
|
-
|
|
212
|
-
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
213
|
-
local miner_plist="$HOME/Library/LaunchAgents/${miner_label}.plist"
|
|
214
|
-
|
|
215
|
-
local _xml_miner_script _xml_miner_home _xml_miner_path _xml_miner_log
|
|
216
|
-
_xml_miner_script=$(_xml_escape "$miner_script")
|
|
217
|
-
_xml_miner_home=$(_xml_escape "$HOME")
|
|
218
|
-
_xml_miner_path=$(_xml_escape "$(aidevops_launchd_sanitized_path "/bin:/usr/bin:/usr/local/bin:/opt/homebrew/bin:${PATH}")")
|
|
219
|
-
_xml_miner_log=$(_xml_escape "$miner_log")
|
|
220
|
-
|
|
221
|
-
local miner_plist_content
|
|
222
|
-
miner_plist_content=$(
|
|
223
|
-
cat <<MINER_PLIST
|
|
224
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
225
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
226
|
-
<plist version="1.0">
|
|
227
|
-
<dict>
|
|
228
|
-
<key>Label</key>
|
|
229
|
-
<string>${miner_label}</string>
|
|
230
|
-
<key>ProgramArguments</key>
|
|
231
|
-
<array>
|
|
232
|
-
<string>$(_xml_escape "$(_resolve_modern_bash)")</string>
|
|
233
|
-
<string>${_xml_miner_script}</string>
|
|
234
|
-
<string>create-issues</string>
|
|
235
|
-
<string>--since-hours</string>
|
|
236
|
-
<string>24</string>
|
|
237
|
-
<string>--pulse-repos</string>
|
|
238
|
-
<string>--systemic-threshold</string>
|
|
239
|
-
<string>2</string>
|
|
240
|
-
<string>--max-issues</string>
|
|
241
|
-
<string>3</string>
|
|
242
|
-
<string>--label</string>
|
|
243
|
-
<string>auto-dispatch</string>
|
|
244
|
-
</array>
|
|
245
|
-
<key>EnvironmentVariables</key>
|
|
246
|
-
<dict>
|
|
247
|
-
<key>HOME</key>
|
|
248
|
-
<string>${_xml_miner_home}</string>
|
|
249
|
-
<key>PATH</key>
|
|
250
|
-
<string>${_xml_miner_path}</string>
|
|
251
|
-
</dict>
|
|
252
|
-
<key>StartCalendarInterval</key>
|
|
253
|
-
<array>
|
|
254
|
-
<dict>
|
|
255
|
-
<key>Minute</key>
|
|
256
|
-
<integer>15</integer>
|
|
257
|
-
</dict>
|
|
258
|
-
</array>
|
|
259
|
-
<key>StandardOutPath</key>
|
|
260
|
-
<string>${_xml_miner_log}</string>
|
|
261
|
-
<key>StandardErrorPath</key>
|
|
262
|
-
<string>${_xml_miner_log}</string>
|
|
263
|
-
<key>RunAtLoad</key>
|
|
264
|
-
<false/>
|
|
265
|
-
</dict>
|
|
266
|
-
</plist>
|
|
267
|
-
MINER_PLIST
|
|
268
|
-
)
|
|
269
|
-
|
|
270
|
-
if _launchd_install_if_changed "$miner_label" "$miner_plist" "$miner_plist_content"; then
|
|
271
|
-
print_info "Failure miner enabled (launchd, hourly at :15)"
|
|
272
|
-
else
|
|
273
|
-
print_warning "Failed to load failure miner LaunchAgent"
|
|
274
|
-
fi
|
|
275
|
-
else
|
|
276
|
-
_install_scheduler_linux \
|
|
277
|
-
"$miner_systemd" \
|
|
278
|
-
"aidevops: gh-failure-miner" \
|
|
279
|
-
"15 * * * *" \
|
|
280
|
-
"\"${miner_script}\" create-issues --since-hours 24 --pulse-repos --systemic-threshold 2 --max-issues 3 --label auto-dispatch" \
|
|
281
|
-
"3600" \
|
|
282
|
-
"$miner_log" \
|
|
283
|
-
"" \
|
|
284
|
-
"Failure miner enabled (hourly at :15)" \
|
|
285
|
-
"Failed to install failure miner scheduler" \
|
|
286
|
-
"false" \
|
|
287
|
-
"false" \
|
|
288
|
-
"*-*-* *:15:00"
|
|
289
|
-
fi
|
|
290
|
-
return 0
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
# Setup process guard — kills runaway AI processes (ShellCheck bloat, stuck workers)
|
|
294
|
-
# before they exhaust memory and cause kernel panics. Always installed when the
|
|
295
|
-
# script exists; no consent needed (safety net, not autonomous action).
|
|
296
|
-
# macOS: launchd plist (30s interval, RunAtLoad=true) | Linux: systemd timer or cron (every minute)
|
|
297
|
-
setup_process_guard() {
|
|
298
|
-
local guard_script="$HOME/.aidevops/agents/scripts/process-guard-helper.sh"
|
|
299
|
-
local guard_label="sh.aidevops.process-guard"
|
|
300
|
-
local guard_systemd="aidevops-process-guard"
|
|
301
|
-
local guard_log="$HOME/.aidevops/logs/process-guard.log"
|
|
302
|
-
if [[ ! -x "$guard_script" ]]; then
|
|
303
|
-
return 0
|
|
304
|
-
fi
|
|
305
|
-
|
|
306
|
-
mkdir -p "$HOME/.aidevops/logs"
|
|
307
|
-
|
|
308
|
-
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
309
|
-
local guard_plist="$HOME/Library/LaunchAgents/${guard_label}.plist"
|
|
310
|
-
|
|
311
|
-
# XML-escape paths for safe plist embedding (prevents injection
|
|
312
|
-
# if $HOME or paths contain &, <, > characters)
|
|
313
|
-
local _xml_guard_script _xml_guard_home _xml_guard_path
|
|
314
|
-
_xml_guard_script=$(_xml_escape "$guard_script")
|
|
315
|
-
_xml_guard_home=$(_xml_escape "$HOME")
|
|
316
|
-
_xml_guard_path=$(_xml_escape "$(aidevops_launchd_sanitized_path "$PATH")")
|
|
317
|
-
|
|
318
|
-
local guard_plist_content
|
|
319
|
-
guard_plist_content=$(
|
|
320
|
-
cat <<GUARD_PLIST
|
|
321
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
322
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
323
|
-
<plist version="1.0">
|
|
324
|
-
<dict>
|
|
325
|
-
<key>Label</key>
|
|
326
|
-
<string>${guard_label}</string>
|
|
327
|
-
<key>ProgramArguments</key>
|
|
328
|
-
<array>
|
|
329
|
-
<string>$(_xml_escape "$(_resolve_modern_bash)")</string>
|
|
330
|
-
<string>${_xml_guard_script}</string>
|
|
331
|
-
<string>kill-runaways</string>
|
|
332
|
-
</array>
|
|
333
|
-
<key>StartInterval</key>
|
|
334
|
-
<integer>30</integer>
|
|
335
|
-
<key>StandardOutPath</key>
|
|
336
|
-
<string>${_xml_guard_home}/.aidevops/logs/process-guard.log</string>
|
|
337
|
-
<key>StandardErrorPath</key>
|
|
338
|
-
<string>${_xml_guard_home}/.aidevops/logs/process-guard.log</string>
|
|
339
|
-
<key>EnvironmentVariables</key>
|
|
340
|
-
<dict>
|
|
341
|
-
<key>PATH</key>
|
|
342
|
-
<string>${_xml_guard_path}</string>
|
|
343
|
-
<key>HOME</key>
|
|
344
|
-
<string>${_xml_guard_home}</string>
|
|
345
|
-
<key>SHELLCHECK_RSS_LIMIT_KB</key>
|
|
346
|
-
<string>524288</string>
|
|
347
|
-
<key>SHELLCHECK_RUNTIME_LIMIT</key>
|
|
348
|
-
<string>120</string>
|
|
349
|
-
<key>CHILD_RSS_LIMIT_KB</key>
|
|
350
|
-
<string>8388608</string>
|
|
351
|
-
<key>CHILD_RUNTIME_LIMIT</key>
|
|
352
|
-
<string>7200</string>
|
|
353
|
-
</dict>
|
|
354
|
-
<key>RunAtLoad</key>
|
|
355
|
-
<true/>
|
|
356
|
-
<key>KeepAlive</key>
|
|
357
|
-
<false/>
|
|
358
|
-
</dict>
|
|
359
|
-
</plist>
|
|
360
|
-
GUARD_PLIST
|
|
361
|
-
)
|
|
362
|
-
|
|
363
|
-
if _launchd_install_if_changed "$guard_label" "$guard_plist" "$guard_plist_content"; then
|
|
364
|
-
print_info "Process guard enabled (launchd, every 30s, survives reboot)"
|
|
365
|
-
else
|
|
366
|
-
print_warning "Failed to load process guard LaunchAgent"
|
|
367
|
-
fi
|
|
368
|
-
else
|
|
369
|
-
# Linux: systemd timer (30s) or cron fallback (every minute — cron minimum granularity)
|
|
370
|
-
_install_scheduler_linux \
|
|
371
|
-
"$guard_systemd" \
|
|
372
|
-
"aidevops: process-guard" \
|
|
373
|
-
"$CRON_EVERY_MINUTE" \
|
|
374
|
-
"\"${guard_script}\" kill-runaways" \
|
|
375
|
-
"30" \
|
|
376
|
-
"$guard_log" \
|
|
377
|
-
"SHELLCHECK_RSS_LIMIT_KB=524288
|
|
378
|
-
SHELLCHECK_RUNTIME_LIMIT=120
|
|
379
|
-
CHILD_RSS_LIMIT_KB=8388608
|
|
380
|
-
CHILD_RUNTIME_LIMIT=7200" \
|
|
381
|
-
"Process guard enabled (every 30s)" \
|
|
382
|
-
"Failed to install process guard scheduler" \
|
|
383
|
-
"true" \
|
|
384
|
-
"false"
|
|
385
|
-
fi
|
|
386
|
-
return 0
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
# Setup memory pressure monitor — process-focused memory watchdog (t1398.5, GH#2915).
|
|
390
|
-
# Monitors individual process RSS, runtime, session count, and aggregate memory.
|
|
391
|
-
# Auto-kills runaway ShellCheck (language server respawns them). Always installed
|
|
392
|
-
# when the script exists; no consent needed (safety net, not autonomous action).
|
|
393
|
-
# macOS: launchd plist (60s interval, RunAtLoad=true) | Linux: systemd timer or cron (every minute)
|
|
394
|
-
setup_memory_pressure_monitor() {
|
|
395
|
-
local monitor_script="$HOME/.aidevops/agents/scripts/memory-pressure-monitor.sh"
|
|
396
|
-
local monitor_label="sh.aidevops.memory-pressure-monitor"
|
|
397
|
-
local monitor_systemd="aidevops-memory-pressure-monitor"
|
|
398
|
-
local monitor_log="$HOME/.aidevops/logs/memory-pressure-launchd.log"
|
|
399
|
-
if [[ ! -x "$monitor_script" ]]; then
|
|
400
|
-
return 0
|
|
401
|
-
fi
|
|
402
|
-
|
|
403
|
-
mkdir -p "$HOME/.aidevops/logs"
|
|
404
|
-
|
|
405
|
-
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
406
|
-
local monitor_plist="$HOME/Library/LaunchAgents/${monitor_label}.plist"
|
|
407
|
-
|
|
408
|
-
# XML-escape paths for safe plist embedding
|
|
409
|
-
local _xml_monitor_script _xml_monitor_home
|
|
410
|
-
_xml_monitor_script=$(_xml_escape "$monitor_script")
|
|
411
|
-
_xml_monitor_home=$(_xml_escape "$HOME")
|
|
412
|
-
|
|
413
|
-
local monitor_plist_content
|
|
414
|
-
monitor_plist_content=$(
|
|
415
|
-
cat <<MONITOR_PLIST
|
|
416
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
417
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
418
|
-
<plist version="1.0">
|
|
419
|
-
<dict>
|
|
420
|
-
<key>Label</key>
|
|
421
|
-
<string>${monitor_label}</string>
|
|
422
|
-
<key>ProgramArguments</key>
|
|
423
|
-
<array>
|
|
424
|
-
<string>$(_xml_escape "$(_resolve_modern_bash)")</string>
|
|
425
|
-
<string>${_xml_monitor_script}</string>
|
|
426
|
-
</array>
|
|
427
|
-
<key>StartInterval</key>
|
|
428
|
-
<integer>60</integer>
|
|
429
|
-
<key>StandardOutPath</key>
|
|
430
|
-
<string>${_xml_monitor_home}/.aidevops/logs/memory-pressure-launchd.log</string>
|
|
431
|
-
<key>StandardErrorPath</key>
|
|
432
|
-
<string>${_xml_monitor_home}/.aidevops/logs/memory-pressure-launchd.log</string>
|
|
433
|
-
<key>EnvironmentVariables</key>
|
|
434
|
-
<dict>
|
|
435
|
-
<key>PATH</key>
|
|
436
|
-
<string>$(aidevops_launchd_sanitized_path)</string>
|
|
437
|
-
<key>HOME</key>
|
|
438
|
-
<string>${_xml_monitor_home}</string>
|
|
439
|
-
</dict>
|
|
440
|
-
<key>RunAtLoad</key>
|
|
441
|
-
<true/>
|
|
442
|
-
<key>KeepAlive</key>
|
|
443
|
-
<false/>
|
|
444
|
-
<key>ProcessType</key>
|
|
445
|
-
<string>Background</string>
|
|
446
|
-
<key>LowPriorityBackgroundIO</key>
|
|
447
|
-
<true/>
|
|
448
|
-
<key>Nice</key>
|
|
449
|
-
<integer>10</integer>
|
|
450
|
-
</dict>
|
|
451
|
-
</plist>
|
|
452
|
-
MONITOR_PLIST
|
|
453
|
-
)
|
|
454
|
-
|
|
455
|
-
if _launchd_install_if_changed "$monitor_label" "$monitor_plist" "$monitor_plist_content"; then
|
|
456
|
-
print_info "Memory pressure monitor enabled (launchd, every 60s, survives reboot)"
|
|
457
|
-
else
|
|
458
|
-
print_warning "Failed to load memory pressure monitor LaunchAgent"
|
|
459
|
-
fi
|
|
460
|
-
else
|
|
461
|
-
# Linux: systemd timer (60s) or cron fallback (every minute — cron minimum granularity)
|
|
462
|
-
_install_scheduler_linux \
|
|
463
|
-
"$monitor_systemd" \
|
|
464
|
-
"aidevops: memory-pressure-monitor" \
|
|
465
|
-
"$CRON_EVERY_MINUTE" \
|
|
466
|
-
"\"${monitor_script}\"" \
|
|
467
|
-
"60" \
|
|
468
|
-
"$monitor_log" \
|
|
469
|
-
"" \
|
|
470
|
-
"Memory pressure monitor enabled (every 60s)" \
|
|
471
|
-
"Failed to install memory pressure monitor scheduler" \
|
|
472
|
-
"true" \
|
|
473
|
-
"true"
|
|
474
|
-
fi
|
|
475
|
-
return 0
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
# Setup screen time snapshot — captures daily screen time for contributor stats.
|
|
479
|
-
# Accumulates data in screen-time.jsonl (macOS Knowledge DB retains only ~28 days).
|
|
480
|
-
# Always installed when the script exists; no consent needed (data collection only).
|
|
481
|
-
# macOS: launchd plist (every 6h, RunAtLoad=true) | Linux: systemd timer or cron (every 6h)
|
|
482
|
-
setup_screen_time_snapshot() {
|
|
483
|
-
local st_script="$HOME/.aidevops/agents/scripts/screen-time-helper.sh"
|
|
484
|
-
local st_label="sh.aidevops.screen-time-snapshot"
|
|
485
|
-
local st_systemd="aidevops-screen-time-snapshot"
|
|
486
|
-
local st_log="$HOME/.aidevops/.agent-workspace/logs/screen-time-snapshot.log"
|
|
487
|
-
if [[ ! -x "$st_script" ]]; then
|
|
488
|
-
return 0
|
|
489
|
-
fi
|
|
490
|
-
|
|
491
|
-
mkdir -p "$HOME/.aidevops/.agent-workspace/logs"
|
|
492
|
-
|
|
493
|
-
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
494
|
-
local st_plist="$HOME/Library/LaunchAgents/${st_label}.plist"
|
|
495
|
-
|
|
496
|
-
# XML-escape paths for safe plist embedding
|
|
497
|
-
local _xml_st_script _xml_st_home
|
|
498
|
-
_xml_st_script=$(_xml_escape "$st_script")
|
|
499
|
-
_xml_st_home=$(_xml_escape "$HOME")
|
|
500
|
-
|
|
501
|
-
local st_plist_content
|
|
502
|
-
st_plist_content=$(
|
|
503
|
-
cat <<ST_PLIST
|
|
504
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
505
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
506
|
-
<plist version="1.0">
|
|
507
|
-
<dict>
|
|
508
|
-
<key>Label</key>
|
|
509
|
-
<string>${st_label}</string>
|
|
510
|
-
<key>ProgramArguments</key>
|
|
511
|
-
<array>
|
|
512
|
-
<string>$(_xml_escape "$(_resolve_modern_bash)")</string>
|
|
513
|
-
<string>${_xml_st_script}</string>
|
|
514
|
-
<string>snapshot</string>
|
|
515
|
-
</array>
|
|
516
|
-
<key>StartInterval</key>
|
|
517
|
-
<integer>21600</integer>
|
|
518
|
-
<key>StandardOutPath</key>
|
|
519
|
-
<string>${_xml_st_home}/.aidevops/.agent-workspace/logs/screen-time-snapshot.log</string>
|
|
520
|
-
<key>StandardErrorPath</key>
|
|
521
|
-
<string>${_xml_st_home}/.aidevops/.agent-workspace/logs/screen-time-snapshot.log</string>
|
|
522
|
-
<key>EnvironmentVariables</key>
|
|
523
|
-
<dict>
|
|
524
|
-
<key>PATH</key>
|
|
525
|
-
<string>$(aidevops_launchd_sanitized_path)</string>
|
|
526
|
-
<key>HOME</key>
|
|
527
|
-
<string>${_xml_st_home}</string>
|
|
528
|
-
</dict>
|
|
529
|
-
<key>RunAtLoad</key>
|
|
530
|
-
<true/>
|
|
531
|
-
<key>KeepAlive</key>
|
|
532
|
-
<false/>
|
|
533
|
-
<key>ProcessType</key>
|
|
534
|
-
<string>Background</string>
|
|
535
|
-
<key>LowPriorityBackgroundIO</key>
|
|
536
|
-
<true/>
|
|
537
|
-
<key>Nice</key>
|
|
538
|
-
<integer>10</integer>
|
|
539
|
-
</dict>
|
|
540
|
-
</plist>
|
|
541
|
-
ST_PLIST
|
|
542
|
-
)
|
|
543
|
-
|
|
544
|
-
if _launchd_install_if_changed "$st_label" "$st_plist" "$st_plist_content"; then
|
|
545
|
-
print_info "Screen time snapshot enabled (launchd, every 6h, survives reboot)"
|
|
546
|
-
else
|
|
547
|
-
print_warning "Failed to load screen time snapshot LaunchAgent"
|
|
548
|
-
fi
|
|
549
|
-
else
|
|
550
|
-
# Linux: systemd timer (every 6h) or cron fallback
|
|
551
|
-
_install_scheduler_linux \
|
|
552
|
-
"$st_systemd" \
|
|
553
|
-
"aidevops: screen-time-snapshot" \
|
|
554
|
-
"0 */6 * * *" \
|
|
555
|
-
"\"${st_script}\" snapshot" \
|
|
556
|
-
"21600" \
|
|
557
|
-
"$st_log" \
|
|
558
|
-
"" \
|
|
559
|
-
"Screen time snapshot enabled (every 6h)" \
|
|
560
|
-
"Failed to install screen time snapshot scheduler" \
|
|
561
|
-
"true" \
|
|
562
|
-
"true"
|
|
563
|
-
fi
|
|
564
|
-
return 0
|
|
565
|
-
}
|