From 82f3ba75d8c85210df4d65e793d0aa9070f8c389 Mon Sep 17 00:00:00 2001 From: marcusquinn <6428977+marcusquinn@users.noreply.github.com> Date: Mon, 9 Mar 2026 01:47:48 +0000 Subject: [PATCH 1/2] feat: auto-install screen-time and profile-readme scheduled jobs in setup.sh Add two new scheduled job installations to setup.sh so they deploy automatically on 'aidevops setup' and 'aidevops update': - Screen time snapshot (always-install): captures daily screen time every 6h to accumulate data beyond macOS Knowledge DB's ~28 day retention. macOS: launchd plist. Linux: cron entry. - Profile README update (conditional): updates GitHub profile README with contributor stats daily at 06:00. Only installed when user has a profile repo (priority: "profile") in repos.json. Includes PATH env for git/gh access. MacOS: launchd plist. Linux: cron entry. Both follow existing setup.sh patterns: _xml_escape for plists, _cron_escape for cron, _launchd_has_agent for idempotent upgrades, unload-before-reload for plist updates. --- setup.sh | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) diff --git a/setup.sh b/setup.sh index a6341a0398..6239289e37 100755 --- a/setup.sh +++ b/setup.sh @@ -1185,6 +1185,181 @@ MONITOR_PLIST fi fi + # Screen time snapshot — captures daily screen time for contributor stats. + # Accumulates data in screen-time.jsonl (macOS Knowledge DB retains only ~28 days). + # Always installed when the script exists; no consent needed (data collection only). + # macOS: launchd plist (every 6h, RunAtLoad=true) | Linux: cron (every 6h) + local st_script="$HOME/.aidevops/agents/scripts/screen-time-helper.sh" + local st_label="sh.aidevops.screen-time-snapshot" + if [[ -x "$st_script" ]]; then + mkdir -p "$HOME/.aidevops/.agent-workspace/logs" + + if [[ "$(uname -s)" == "Darwin" ]]; then + local st_plist="$HOME/Library/LaunchAgents/${st_label}.plist" + + # Unload old plist if upgrading + if _launchd_has_agent "$st_label"; then + launchctl unload "$st_plist" 2>/dev/null || true + fi + + # XML-escape paths for safe plist embedding + local _xml_st_script _xml_st_home + _xml_st_script=$(_xml_escape "$st_script") + _xml_st_home=$(_xml_escape "$HOME") + + cat >"$st_plist" < + + + + Label + ${st_label} + ProgramArguments + + /bin/bash + ${_xml_st_script} + snapshot + + StartInterval + 21600 + StandardOutPath + ${_xml_st_home}/.aidevops/.agent-workspace/logs/screen-time-snapshot.log + StandardErrorPath + ${_xml_st_home}/.aidevops/.agent-workspace/logs/screen-time-snapshot.log + EnvironmentVariables + + HOME + ${_xml_st_home} + + RunAtLoad + + KeepAlive + + ProcessType + Background + LowPriorityBackgroundIO + + Nice + 10 + + +ST_PLIST + + if launchctl load "$st_plist" 2>/dev/null; then + print_info "Screen time snapshot enabled (launchd, every 6h, survives reboot)" + else + print_warning "Failed to load screen time snapshot LaunchAgent" + fi + else + # Linux: cron entry (every 6 hours) + local _cron_st_script + _cron_st_script=$(_cron_escape "$st_script") + ( + crontab -l 2>/dev/null | grep -v 'aidevops: screen-time-snapshot' + echo "0 */6 * * * /bin/bash ${_cron_st_script} snapshot >> \"\$HOME/.aidevops/.agent-workspace/logs/screen-time-snapshot.log\" 2>&1 # aidevops: screen-time-snapshot" + ) | crontab - 2>/dev/null || true + if crontab -l 2>/dev/null | grep -qF "aidevops: screen-time-snapshot" 2>/dev/null; then + print_info "Screen time snapshot enabled (cron, every 6h)" + else + print_warning "Failed to install screen time snapshot cron entry" + fi + fi + fi + + # Profile README auto-update — updates GitHub profile README with contributor stats. + # Only installed if user has a profile repo (priority: "profile") in repos.json. + # macOS: launchd plist (daily at 06:00) | Linux: cron (daily at 06:00) + local pr_script="$HOME/.aidevops/agents/scripts/profile-readme-helper.sh" + local pr_label="sh.aidevops.profile-readme-update" + local repos_json="$HOME/.config/aidevops/repos.json" + local has_profile_repo="false" + if [[ -f "$repos_json" ]] && command -v jq &>/dev/null; then + if jq -e '.initialized_repos[]? | select(.priority == "profile")' "$repos_json" >/dev/null 2>&1; then + has_profile_repo="true" + fi + fi + if [[ -x "$pr_script" ]] && [[ "$has_profile_repo" == "true" ]]; then + mkdir -p "$HOME/.aidevops/.agent-workspace/logs" + + if [[ "$(uname -s)" == "Darwin" ]]; then + local pr_plist="$HOME/Library/LaunchAgents/${pr_label}.plist" + + # Unload old plist if upgrading + if _launchd_has_agent "$pr_label"; then + launchctl unload "$pr_plist" 2>/dev/null || true + fi + + # XML-escape paths for safe plist embedding + local _xml_pr_script _xml_pr_home + _xml_pr_script=$(_xml_escape "$pr_script") + _xml_pr_home=$(_xml_escape "$HOME") + + cat >"$pr_plist" < + + + + Label + ${pr_label} + ProgramArguments + + /bin/bash + ${_xml_pr_script} + update + + StartCalendarInterval + + Hour + 6 + Minute + 0 + + StandardOutPath + ${_xml_pr_home}/.aidevops/.agent-workspace/logs/profile-readme-update.log + StandardErrorPath + ${_xml_pr_home}/.aidevops/.agent-workspace/logs/profile-readme-update.log + EnvironmentVariables + + PATH + /opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin + HOME + ${_xml_pr_home} + + RunAtLoad + + KeepAlive + + ProcessType + Background + LowPriorityBackgroundIO + + Nice + 10 + + +PR_PLIST + + if launchctl load "$pr_plist" 2>/dev/null; then + print_info "Profile README update enabled (launchd, daily at 06:00)" + else + print_warning "Failed to load profile README update LaunchAgent" + fi + else + # Linux: cron entry (daily at 06:00) + local _cron_pr_script + _cron_pr_script=$(_cron_escape "$pr_script") + ( + crontab -l 2>/dev/null | grep -v 'aidevops: profile-readme-update' + echo "0 6 * * * PATH=\"/usr/local/bin:/usr/bin:/bin\" /bin/bash ${_cron_pr_script} update >> \"\$HOME/.aidevops/.agent-workspace/logs/profile-readme-update.log\" 2>&1 # aidevops: profile-readme-update" + ) | crontab - 2>/dev/null || true + if crontab -l 2>/dev/null | grep -qF "aidevops: profile-readme-update" 2>/dev/null; then + print_info "Profile README update enabled (cron, daily at 06:00)" + else + print_warning "Failed to install profile README update cron entry" + fi + fi + fi + echo "" echo "CLI Command:" echo " aidevops init - Initialize aidevops in a project" From 138f2fdab0937bcc379cd5f71284a007a7a04deb Mon Sep 17 00:00:00 2001 From: marcusquinn <6428977+marcusquinn@users.noreply.github.com> Date: Mon, 9 Mar 2026 01:54:12 +0000 Subject: [PATCH 2/2] fix: add PATH to screen-time snapshot env for consistency Address CodeRabbit review: add PATH to both the launchd plist EnvironmentVariables and the Linux cron entry for screen-time-snapshot, matching the pattern used by profile-readme-update and memory-pressure-monitor. Ensures sqlite3 and other tools are findable in the launchd environment. --- setup.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/setup.sh b/setup.sh index 6239289e37..22f2aea252 100755 --- a/setup.sh +++ b/setup.sh @@ -1228,6 +1228,8 @@ MONITOR_PLIST ${_xml_st_home}/.aidevops/.agent-workspace/logs/screen-time-snapshot.log EnvironmentVariables + PATH + /opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin HOME ${_xml_st_home} @@ -1256,7 +1258,7 @@ ST_PLIST _cron_st_script=$(_cron_escape "$st_script") ( crontab -l 2>/dev/null | grep -v 'aidevops: screen-time-snapshot' - echo "0 */6 * * * /bin/bash ${_cron_st_script} snapshot >> \"\$HOME/.aidevops/.agent-workspace/logs/screen-time-snapshot.log\" 2>&1 # aidevops: screen-time-snapshot" + echo "0 */6 * * * PATH=\"/usr/local/bin:/usr/bin:/bin\" /bin/bash ${_cron_st_script} snapshot >> \"\$HOME/.aidevops/.agent-workspace/logs/screen-time-snapshot.log\" 2>&1 # aidevops: screen-time-snapshot" ) | crontab - 2>/dev/null || true if crontab -l 2>/dev/null | grep -qF "aidevops: screen-time-snapshot" 2>/dev/null; then print_info "Screen time snapshot enabled (cron, every 6h)"