Skip to content

t1260: Fix setup.sh to install launchd schedulers on macOS for all users#1971

Merged
marcusquinn merged 4 commits intomainfrom
bugfix/t1260-setup-launchd-schedulers
Feb 19, 2026
Merged

t1260: Fix setup.sh to install launchd schedulers on macOS for all users#1971
marcusquinn merged 4 commits intomainfrom
bugfix/t1260-setup-launchd-schedulers

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Feb 19, 2026

Summary

  • setup.sh (run by aidevops update) now installs both schedulers on macOS using launchd
  • Existing cron entries are auto-migrated to launchd during setup
  • Fixes the gap where t1219 added launchd support but setup never activated it

Problem

PR #1864 (t1219) added launchd LaunchAgent support for macOS, but:

  1. setup.sh only checked cron for auto-update (line 524: crontab -l | grep "aidevops-auto-update") — missed launchd plist detection entirely
  2. Supervisor pulse was never installed by setup — users had to manually run supervisor-helper.sh cron install, which most wouldn't know to do
  3. No migration path during update — macOS users with existing cron entries were never migrated to launchd

Result: the supervisor pulse scheduler was not running for any user, meaning autonomous task dispatch, PR merging, and worker evaluation were all inactive.

Changes

setup.sh — 3 fixes

1. Auto-update detection — now checks launchctl list for com.aidevops.auto-update first, falls back to crontab -l. On macOS, if cron entry exists but no launchd plist, re-runs enable to migrate.

2. Supervisor pulse install — new section after auto-update that installs the supervisor pulse scheduler. Interactive mode asks the user; non-interactive enables silently. Checks both launchd and cron to avoid duplicate installation.

3. Cron-to-launchd migration — on macOS, when cron entries exist but launchd plists don't, both schedulers are silently migrated during setup. The enable and cron install commands handle the actual migration (remove cron entry, install plist).

Behaviour Matrix

Platform Existing State Action
macOS Nothing installed Install both via launchd (ask in interactive)
macOS Cron entries only Migrate to launchd silently
macOS Launchd plists Skip (already installed)
Linux Nothing installed Install both via cron (ask in interactive)
Linux Cron entries Skip (already installed)

Verification

  • ShellCheck: zero new violations
  • Syntax: bash -n passes
  • Idempotent: re-running setup with existing schedulers skips installation

Ref #1970

Summary by CodeRabbit

  • New Features
    • Supervisor pulse scheduler can be enabled automatically during setup (silent in non-interactive, prompt in interactive).
  • Migration
    • Existing scheduler installations and older macOS entries are detected and migrated to the new installer-managed scheduler; migrated items are logged.
  • Behavior Changes
    • macOS scheduler display names and status messages updated for clarity in System Settings.
    • Credentials (tokens) are resolved at runtime for scheduled runs instead of being injected into schedule entries.

- Auto-update check now detects launchd plist OR cron entry (was cron-only)
- Add supervisor pulse scheduler install during setup (was completely missing)
- Auto-migrate cron entries to launchd on macOS during setup/update
- Both interactive and non-interactive modes supported
- Existing launchd installations are detected and skipped (idempotent)
@gemini-code-assist
Copy link

Summary of Changes

Hello @marcusquinn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the setup.sh script to ensure robust and correct installation of system schedulers on macOS. It resolves a critical issue where launchd support, previously introduced, was not being properly activated, leading to inactive autonomous operations. The changes include intelligent detection of existing schedulers, prioritization of launchd on macOS, and automatic migration of older cron entries to launchd, thereby streamlining the setup experience and ensuring essential background tasks run as intended.

Highlights

  • macOS Scheduler Installation: The setup.sh script now correctly installs both auto-update and supervisor pulse schedulers on macOS using launchd.
  • Cron to Launchd Migration: Existing cron entries for schedulers on macOS are automatically migrated to launchd during the setup process.
  • Supervisor Pulse Activation: The supervisor pulse scheduler, crucial for autonomous task orchestration, is now properly installed by setup.sh, addressing a previous gap where it was not activated.
Changelog
  • setup.sh
    • Improved auto-update scheduler detection to first check launchd on macOS, then cron, and added logic to migrate existing cron entries to launchd.
    • Implemented installation of the supervisor pulse scheduler, including checks for existing launchd or cron entries and migration from cron to launchd on macOS.
    • Added interactive and non-interactive installation options for the supervisor pulse scheduler.
Activity
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 19, 2026

Walkthrough

Adds supervisor pulse scheduler enablement and migration to setup.sh: detects existing launchd (macOS) or crontab (Linux), migrates legacy entries where found, and enables the scheduler automatically in non-interactive contexts or with a prompt when interactive.

Changes

Cohort / File(s) Summary
Setup / Scheduler
setup.sh
Adds post-setup supervisor pulse scheduler enablement: checks macOS launchd and Linux crontab, performs interactive/non-interactive enablement, and invokes migration logic for legacy entries.
Auto-update helper
.agents/scripts/auto-update-helper.sh
Renamed LaunchAgent label to com.aidevops.aidevops-auto-update, added migration/unload of old plist, created display symlink under ~/.aidevops/bin, and updated plist generation and status messaging.
Supervisor cron
.agents/scripts/supervisor/cron.sh
Updated launchd plist path/label to new com.aidevops.aidevops-supervisor-pulse; removed baked-in GH_TOKEN from cron entries so token is resolved at runtime.
Supervisor launchd
.agents/scripts/supervisor/launchd.sh
Standardized LaunchAgent labels to com.aidevops.aidevops-*, added migration/unload of old plists, introduced display symlink usage in plist ProgramArguments, omitted GH_TOKEN from plist env, and removed old plist files after migration.
Supervisor runtime
.agents/scripts/supervisor/pulse.sh
Adds runtime GH_TOKEN resolution (gh CLI, then gopass) before acquiring pulse lock and exports token when found so pulses run authenticated without baking token into schedulers.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Setup as setup.sh
  participant Helper as auto-update-helper / launchd.sh
  participant macLaunchd as macOS Launchd
  participant Cron as crontab (Linux)
  participant Pulse as supervisor/pulse.sh

  User->>Setup: run installer
  Setup->>Helper: check existing schedulers (launchd / crontab)
  alt macOS: existing launchd
    Helper->>macLaunchd: inspect / unload old plist (migrate)
    Helper->>macLaunchd: install new plist (use display symlink)
    macLaunchd-->>Helper: loaded
  else Linux or cron present
    Helper->>Cron: inspect crontab entries (migrate or create)
    Cron-->>Helper: updated
  end
  Setup->>Pulse: enable scheduler (silent if non-interactive / prompt if interactive)
  Pulse->>Pulse: resolve GH_TOKEN at runtime (gh -> gopass)
  Pulse-->>macLaunchd/Cron: scheduled runs invoke pulse.sh
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

Poem

🌱 A scheduler born from setup's light,

cron migrations dawn in flight,
symlinks point where pulses start,
tokens found to play their part,
quiet installs keep systems bright.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: enabling launchd scheduler installation in setup.sh on macOS, which is the core objective of this PR addressing the t1260 gap.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bugfix/t1260-setup-launchd-schedulers

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 30 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Thu Feb 19 16:35:39 UTC 2026: Code review monitoring started
Thu Feb 19 16:35:40 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 30

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 30
  • VULNERABILITIES: 0

Generated on: Thu Feb 19 16:35:43 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request correctly addresses the issue of launchd schedulers not being installed on macOS by setup.sh. The logic to detect existing cron jobs and migrate them to launchd is a great addition.

I've noticed significant code duplication between the setup logic for the auto-update scheduler and the supervisor pulse scheduler. To improve maintainability and adhere to the project's rule of extracting repeated logic, I've suggested refactoring this into a single helper function. This will make the code cleaner and easier to manage in the future.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
setup.sh (2)

563-563: Add -F to cron grep for consistency with the launchd checks above.

Both launchd lookups (lines 526, 561) use grep -qF (fixed-string), but the cron fallback checks on lines 528 and 563 use plain grep -q. The strings are safe for regex today, but -F makes intent explicit and is consistent with the pair above it.

♻️ Proposed fix
-		elif crontab -l 2>/dev/null | grep -q "aidevops-supervisor-pulse"; then
+		elif crontab -l 2>/dev/null | grep -qF "aidevops-supervisor-pulse"; then

The same applies to line 528: grep -q "aidevops-auto-update"grep -qF "aidevops-auto-update".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@setup.sh` at line 563, Update the two cron fallback grep calls to use
fixed-string matching like the launchd checks: change the checks that call
crontab -l | grep -q "aidevops-auto-update" and crontab -l | grep -q
"aidevops-supervisor-pulse" to use grep -qF with the same quoted search strings
so the intent is explicit and consistent with the launchd grep -qF checks.

556-559: Consider adding an env-var opt-out for the supervisor pulse, consistent with the auto-update guard.

The auto-update block (line 524) is gated by [[ "${AIDEVOPS_AUTO_UPDATE:-true}" != "false" ]], which lets CI/CD or power users suppress auto-installation via an environment variable. The supervisor pulse block has no equivalent, so there is no non-destructive way to skip it in automated environments.

♻️ Suggested guard for parity
-	if [[ -x "$supervisor_script" ]]; then
+	if [[ -x "$supervisor_script" ]] && [[ "${AIDEVOPS_SUPERVISOR_PULSE:-true}" != "false" ]]; then
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@setup.sh` around lines 556 - 559, Add an opt-out env var guard for the
supervisor pulse block similar to the auto-update guard: introduce and check
something like AIDEVOPS_SUPERVISOR_PULSE (defaulting to "true") before using the
supervisor_script variable and running supervisor-helper.sh; update the
conditional that currently tests [[ -x "$supervisor_script" ]] to also require
[[ "${AIDEVOPS_SUPERVISOR_PULSE:-true}" != "false" ]] so CI/users can set
AIDEVOPS_SUPERVISOR_PULSE="false" to skip the supervisor pulse installation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@setup.sh`:
- Around line 563-570: The migration currently suppresses errors from invoking
the cron installer (bash "$supervisor_script" cron install >/dev/null 2>&1 ||
true) and then unconditionally sets _pulse_installed=true, which hides failures;
change the logic so you capture the exit status of the cron install call and
only set _pulse_installed=true when that call succeeds (or when a launchd plist
is detected/created), and if it fails emit a visible warning or error via
print_error/print_warn instead of silently swallowing the failure; update the
macOS migration branch that calls supervisor-helper.sh (the invocation using
"$supervisor_script" cron install) to perform this check and conditional
assignment.

---

Nitpick comments:
In `@setup.sh`:
- Line 563: Update the two cron fallback grep calls to use fixed-string matching
like the launchd checks: change the checks that call crontab -l | grep -q
"aidevops-auto-update" and crontab -l | grep -q "aidevops-supervisor-pulse" to
use grep -qF with the same quoted search strings so the intent is explicit and
consistent with the launchd grep -qF checks.
- Around line 556-559: Add an opt-out env var guard for the supervisor pulse
block similar to the auto-update guard: introduce and check something like
AIDEVOPS_SUPERVISOR_PULSE (defaulting to "true") before using the
supervisor_script variable and running supervisor-helper.sh; update the
conditional that currently tests [[ -x "$supervisor_script" ]] to also require
[[ "${AIDEVOPS_SUPERVISOR_PULSE:-true}" != "false" ]] so CI/users can set
AIDEVOPS_SUPERVISOR_PULSE="false" to skip the supervisor pulse installation.

setup.sh Outdated
Comment on lines +563 to +570
elif crontab -l 2>/dev/null | grep -q "aidevops-supervisor-pulse"; then
if [[ "$(uname -s)" == "Darwin" ]]; then
# macOS: cron entry exists but no launchd plist — migrate silently
bash "$supervisor_script" cron install >/dev/null 2>&1 || true
print_info "Supervisor pulse migrated from cron to launchd"
fi
_pulse_installed=true
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Silent migration failure leaves _pulse_installed=true set, permanently skipping re-installation.

If supervisor-helper.sh cron install fails (line 566), || true suppresses the error and execution falls through to line 569 where _pulse_installed=true is set unconditionally. The scheduler ends up neither installed nor re-attempted, with no user-visible signal. The same pattern exists in the auto-update migration (lines 531/534) but is being repeated here in new code.

Consider checking migration success and only suppressing on macOS when a launchd plist is actually created, or at minimum emit a warning on failure:

🛡️ Proposed fix
 		elif crontab -l 2>/dev/null | grep -q "aidevops-supervisor-pulse"; then
 			if [[ "$(uname -s)" == "Darwin" ]]; then
 				# macOS: cron entry exists but no launchd plist — migrate silently
-				bash "$supervisor_script" cron install >/dev/null 2>&1 || true
-				print_info "Supervisor pulse migrated from cron to launchd"
+				if bash "$supervisor_script" cron install >/dev/null 2>&1; then
+					print_info "Supervisor pulse migrated from cron to launchd"
+				else
+					print_warning "Supervisor pulse cron-to-launchd migration failed; will re-attempt install"
+					_pulse_installed=false
+				fi
 			fi
-			_pulse_installed=true
+			[[ "$_pulse_installed" != "false" ]] && _pulse_installed=true
 		fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@setup.sh` around lines 563 - 570, The migration currently suppresses errors
from invoking the cron installer (bash "$supervisor_script" cron install
>/dev/null 2>&1 || true) and then unconditionally sets _pulse_installed=true,
which hides failures; change the logic so you capture the exit status of the
cron install call and only set _pulse_installed=true when that call succeeds (or
when a launchd plist is detected/created), and if it fails emit a visible
warning or error via print_error/print_warn instead of silently swallowing the
failure; update the macOS migration branch that calls supervisor-helper.sh (the
invocation using "$supervisor_script" cron install) to perform this check and
conditional assignment.

…intext GH_TOKEN (t1260)

- Rename labels: com.aidevops.X -> com.aidevops.aidevops-X for all 3 LaunchAgents
  Shows as 'aidevops-supervisor-pulse' etc in macOS System Settings Login Items
- Auto-migrate old labels to new on install/enable (unload old, install new)
- Remove GH_TOKEN from plist and crontab — was stored in plaintext
- Add runtime GH_TOKEN resolution in pulse.sh (gh auth token -> gopass fallback)
- setup.sh detects both old and new labels, migrates old ones during update
@github-actions
Copy link

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 30 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Thu Feb 19 16:46:39 UTC 2026: Code review monitoring started
Thu Feb 19 16:46:39 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 30

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 30
  • VULNERABILITIES: 0

Generated on: Thu Feb 19 16:46:41 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

macOS derives the Login Items display name from ProgramArguments[0] filename,
not the Label. Create symlinks at ~/.aidevops/bin/aidevops-{supervisor-pulse,
auto-update,todo-watcher} pointing to the real scripts, and use those in the
plist ProgramArguments. System Settings now shows 'aidevops-supervisor-pulse'
and 'aidevops-auto-update' instead of 'bash' and 'auto-update-helper.sh'.
…rror handling (t1260)

- Use grep -qF (fixed-string) for cron checks, consistent with launchd checks
- Add AIDEVOPS_SUPERVISOR_PULSE env var opt-out, matching AIDEVOPS_AUTO_UPDATE
- Surface migration failures as warnings instead of silently swallowing them
@github-actions
Copy link

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 30 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Thu Feb 19 16:56:36 UTC 2026: Code review monitoring started
Thu Feb 19 16:56:37 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 30

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 30
  • VULNERABILITIES: 0

Generated on: Thu Feb 19 16:56:39 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
.agents/scripts/auto-update-helper.sh (1)

576-606: ⚠️ Potential issue | 🟡 Minor

Migration path skips the display symlink (Login Items name stays raw).
Because _migrate_cron_to_launchd runs at Line 585 before the display symlink is created at Line 597, migrated entries will keep the raw script path in ProgramArguments[0]. That defeats the new friendly name goal for users coming from cron. Move symlink creation earlier and pass display_link into migration.

🔧 Suggested fix
-		# Auto-migrate existing cron entry if present
-		_migrate_cron_to_launchd "$script_path" "$interval_seconds"
-
-		# Install if not already loaded
-		if _launchd_is_loaded; then
+		# Create named symlink so macOS System Settings shows "aidevops-auto-update"
+		# instead of the raw script name (t1260)
+		local bin_dir="$HOME/.aidevops/bin"
+		mkdir -p "$bin_dir"
+		local display_link="$bin_dir/aidevops-auto-update"
+		ln -sf "$script_path" "$display_link"
+
+		# Auto-migrate existing cron entry if present (use display link)
+		_migrate_cron_to_launchd "$display_link" "$interval_seconds"
+
+		# Install if not already loaded
+		if _launchd_is_loaded; then
 			print_info "Auto-update LaunchAgent already loaded ($LAUNCHD_LABEL)"
 			update_state "enable" "$(get_local_version)" "enabled"
 			return 0
 		fi
-
-		# Create named symlink so macOS System Settings shows "aidevops-auto-update"
-		# instead of the raw script name (t1260)
-		local bin_dir="$HOME/.aidevops/bin"
-		mkdir -p "$bin_dir"
-		local display_link="$bin_dir/aidevops-auto-update"
-		ln -sf "$script_path" "$display_link"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/scripts/auto-update-helper.sh around lines 576 - 606, The migration
runs before creating the user-friendly symlink so migrated LaunchAgents keep the
raw script path; move creation of the display symlink (the ln -sf that sets
display_link="$bin_dir/aidevops-auto-update") to before calling
_migrate_cron_to_launchd and change the _migrate_cron_to_launchd invocation to
pass display_link instead of script_path (or accept an extra display_path
parameter) so migrated entries use display_link as ProgramArguments[0]; ensure
_generate_auto_update_plist still receives display_link and interval_seconds
unchanged.
setup.sh (2)

559-561: ⚠️ Potential issue | 🟡 Minor

set -euo pipefail will exit the entire script if these optional installs fail.

setup.sh has set -euo pipefail (line 2). A bare command in the then body of an if statement is subject to set -e. If bash "$auto_update_script" enable (line 559) or bash "$supervisor_script" cron install (line 604) returns non-zero, the script terminates mid-setup — poor UX for what are explicitly optional, post-setup steps.

🛡️ Proposed fix for both interactive paths
 			if [[ "$enable_auto" =~ ^[Yy]?$ || -z "$enable_auto" ]]; then
-				bash "$auto_update_script" enable
+				bash "$auto_update_script" enable || print_warning "Auto-update enable failed. Run: aidevops auto-update enable"
 			else
 			if [[ "$enable_pulse" =~ ^[Yy]?$ || -z "$enable_pulse" ]]; then
-				bash "$supervisor_script" cron install
+				bash "$supervisor_script" cron install || print_warning "Supervisor pulse enable failed. Run: supervisor-helper.sh cron install"
 			else

Also applies to: 604-606

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@setup.sh` around lines 559 - 561, Optional post-setup commands (bash
"$auto_update_script" enable and bash "$supervisor_script" cron install) are
currently subject to set -e and will abort the whole script on failure; change
each bare invocation so failures are caught and reported without exiting (e.g.,
run the command in an if or append a || handler that calls
print_warning/print_info), use the unique command references bash
"$auto_update_script" enable and bash "$supervisor_script" cron install to
locate the spots, and ensure the else branch prints the existing “Skipped.
Enable later…” message or a warning including the child command's exit status.

549-551: ⚠️ Potential issue | 🟡 Minor

Non-interactive path prints unconditional success even on installation failure.

Both the auto-update (lines 549–551) and supervisor pulse (lines 594–596) non-interactive paths use || true to suppress failure, then unconditionally print a success message. A user or CI log will always read "enabled" regardless of whether the underlying enable/cron install actually succeeded.

🛡️ Proposed fix for both blocks
-			bash "$auto_update_script" enable >/dev/null 2>&1 || true
-			print_info "Auto-update enabled (every 10 min). Disable: aidevops auto-update disable"
+			if bash "$auto_update_script" enable >/dev/null 2>&1; then
+				print_info "Auto-update enabled (every 10 min). Disable: aidevops auto-update disable"
+			else
+				print_warning "Auto-update enable failed. Run: aidevops auto-update enable"
+			fi
-			bash "$supervisor_script" cron install >/dev/null 2>&1 || true
-			print_info "Supervisor pulse enabled (every 2 min). Disable: supervisor-helper.sh cron uninstall"
+			if bash "$supervisor_script" cron install >/dev/null 2>&1; then
+				print_info "Supervisor pulse enabled (every 2 min). Disable: supervisor-helper.sh cron uninstall"
+			else
+				print_warning "Supervisor pulse enable failed. Run: supervisor-helper.sh cron install"
+			fi

Also applies to: 594-596

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@setup.sh` around lines 549 - 551, The non-interactive calls that run the
auto-update enable and the supervisor pulse cron install (invoked via the
variable auto_update_script and the cron install command for supervisor pulse)
swallow failures via "|| true" and then always call print_info "Auto-update
enabled..." (and the equivalent print_info for supervisor pulse); change both
blocks to capture the command exit status instead of masking it (remove "||
true"), run the enable/install command redirecting output to a temp log variable
or file, and only call print_info when the exit code is zero; on non-zero exit,
call print_error (or print_info with a failure message) including the captured
error output so logs reflect real success/failure of auto_update_script enable
and the supervisor pulse cron install.
🧹 Nitpick comments (1)
setup.sh (1)

537-537: Cache uname -s rather than forking a subshell twice.

$(uname -s) spawns a subshell each call. Both invocations are in the same main function and always evaluate to the same value. A single cached variable at the top of the block avoids the repeated fork.

♻️ Proposed refactor
+	local _os
+	_os="$(uname -s)"
 	...
-			if [[ "$(uname -s)" == "Darwin" ]]; then
+			if [[ "$_os" == "Darwin" ]]; then
 	...
-			if [[ "$(uname -s)" == "Darwin" ]]; then
+			if [[ "$_os" == "Darwin" ]]; then

Also applies to: 583-583

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@setup.sh` at line 537, Cache the output of uname -s into a local variable
(e.g., kernel or uname_s) at the start of the main block and replace both
occurrences of "$(uname -s)" in the if checks (the conditional that starts with
if [[ "$(uname -s)" == "Darwin" ]] and the similar check around the later
occurrence) with that variable to avoid forking a subshell twice; ensure the
variable is declared once in the same scope as the checks so both references use
the cached value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In @.agents/scripts/auto-update-helper.sh:
- Around line 576-606: The migration runs before creating the user-friendly
symlink so migrated LaunchAgents keep the raw script path; move creation of the
display symlink (the ln -sf that sets
display_link="$bin_dir/aidevops-auto-update") to before calling
_migrate_cron_to_launchd and change the _migrate_cron_to_launchd invocation to
pass display_link instead of script_path (or accept an extra display_path
parameter) so migrated entries use display_link as ProgramArguments[0]; ensure
_generate_auto_update_plist still receives display_link and interval_seconds
unchanged.

In `@setup.sh`:
- Around line 559-561: Optional post-setup commands (bash "$auto_update_script"
enable and bash "$supervisor_script" cron install) are currently subject to set
-e and will abort the whole script on failure; change each bare invocation so
failures are caught and reported without exiting (e.g., run the command in an if
or append a || handler that calls print_warning/print_info), use the unique
command references bash "$auto_update_script" enable and bash
"$supervisor_script" cron install to locate the spots, and ensure the else
branch prints the existing “Skipped. Enable later…” message or a warning
including the child command's exit status.
- Around line 549-551: The non-interactive calls that run the auto-update enable
and the supervisor pulse cron install (invoked via the variable
auto_update_script and the cron install command for supervisor pulse) swallow
failures via "|| true" and then always call print_info "Auto-update enabled..."
(and the equivalent print_info for supervisor pulse); change both blocks to
capture the command exit status instead of masking it (remove "|| true"), run
the enable/install command redirecting output to a temp log variable or file,
and only call print_info when the exit code is zero; on non-zero exit, call
print_error (or print_info with a failure message) including the captured error
output so logs reflect real success/failure of auto_update_script enable and the
supervisor pulse cron install.

---

Duplicate comments:
In `@setup.sh`:
- Around line 582-591: The assignment _pulse_installed=true is currently
unconditional after detecting an existing cron entry; change it so the flag is
set only when the supervisor is actually installed/running in the target system:
for macOS (uname -s == "Darwin") move _pulse_installed=true into the success
branch of the bash "$supervisor_script" cron install check (the branch that
calls print_info) so it is set only when migration to launchd succeeded, and for
non-macOS keep/set _pulse_installed=true in the existing cron-detected path; use
the existing symbols _pulse_installed, supervisor_script, the bash
"$supervisor_script" cron install result, print_info and print_warning to locate
and implement the conditional placement.

---

Nitpick comments:
In `@setup.sh`:
- Line 537: Cache the output of uname -s into a local variable (e.g., kernel or
uname_s) at the start of the main block and replace both occurrences of "$(uname
-s)" in the if checks (the conditional that starts with if [[ "$(uname -s)" ==
"Darwin" ]] and the similar check around the later occurrence) with that
variable to avoid forking a subshell twice; ensure the variable is declared once
in the same scope as the checks so both references use the cached value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant