Skip to content

t1262: Fix symlink SCRIPT_DIR resolution for launchd agents#1977

Merged
marcusquinn merged 1 commit intomainfrom
bugfix/t1262-symlink-script-dir
Feb 19, 2026
Merged

t1262: Fix symlink SCRIPT_DIR resolution for launchd agents#1977
marcusquinn merged 1 commit intomainfrom
bugfix/t1262-symlink-script-dir

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Feb 19, 2026

Summary

  • Fix supervisor-helper.sh and auto-update-helper.sh failing when invoked via symlinks in ~/.aidevops/bin/
  • Add _resolve_script_path() that follows symlink chain before determining SCRIPT_DIR
  • Both launchd agents (com.aidevops.aidevops-supervisor-pulse and com.aidevops.aidevops-auto-update) were exit code 1 due to shared-constants.sh: No such file or directory

Root Cause

The t1260 launchd setup creates symlinks in ~/.aidevops/bin/ for nice display names in macOS System Settings:

~/.aidevops/bin/aidevops-supervisor-pulse -> ~/.aidevops/agents/scripts/supervisor-helper.sh
~/.aidevops/bin/aidevops-auto-update -> ~/.aidevops/agents/scripts/auto-update-helper.sh

Both scripts use BASH_SOURCE[0] to determine SCRIPT_DIR, but when invoked via symlink, BASH_SOURCE[0] is the symlink path (~/.aidevops/bin/), not the target. So source "${SCRIPT_DIR}/shared-constants.sh" looks for ~/.aidevops/bin/shared-constants.sh which doesn't exist.

Fix

Added a portable symlink resolution function that follows the symlink chain:

_resolve_script_path() {
    local src="${BASH_SOURCE[0]}"
    while [[ -L "$src" ]]; do
        local dir
        dir="$(cd "$(dirname "$src")" && pwd)" || return 1
        src="$(readlink "$src")"
        [[ "$src" != /* ]] && src="$dir/$src"
    done
    cd "$(dirname "$src")" && pwd
}

Testing

  • ShellCheck: zero errors on both files
  • Symlink invocation: verified via /tmp/test-symlink-* → both scripts show help output correctly
  • Direct invocation: verified still works (no regression)

Closes #1976

Summary by CodeRabbit

  • Chores
    • Enhanced internal script path resolution for improved reliability across helper scripts.

When supervisor-helper.sh and auto-update-helper.sh are invoked via
symlinks in ~/.aidevops/bin/ (created by t1260 launchd setup),
BASH_SOURCE[0] resolves to the symlink path, not the target. This
causes SCRIPT_DIR to be ~/.aidevops/bin/ instead of the actual scripts
directory, breaking shared-constants.sh sourcing (exit code 1).

Fix: add _resolve_script_path() that follows symlink chain before
determining SCRIPT_DIR. Works for both direct invocation and symlinks.
@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 resolves a critical issue where supervisor-helper.sh and auto-update-helper.sh scripts failed to execute correctly when invoked through symlinks, particularly in macOS launchd agents. The core problem stemmed from BASH_SOURCE[0] returning the symlink path instead of the target script's actual location, leading to missing file errors. The solution introduces a portable bash function to accurately resolve the true script path by following symlinks, thereby ensuring proper script operation regardless of invocation method.

Highlights

  • Symlink Resolution: Implemented a robust _resolve_script_path() function to correctly determine the script's real location, even when invoked via symlinks.
  • Launchd Agent Fix: Fixed supervisor-helper.sh and auto-update-helper.sh scripts that were failing with exit code 1 when used as launchd agents due to incorrect SCRIPT_DIR resolution.
  • Script Invocation: Ensured both direct and symlink invocations of helper scripts now correctly resolve dependencies like shared-constants.sh.
Changelog
  • .agents/scripts/auto-update-helper.sh
    • Added _resolve_script_path function to correctly determine the script's directory, handling symlinks.
    • Updated SCRIPT_DIR assignment to use the new resolution function.
  • .agents/scripts/supervisor-helper.sh
    • Added _resolve_script_path function to correctly determine the script's directory, handling symlinks.
    • Updated SCRIPT_DIR assignment to use the new resolution function.
Activity
  • Verified that supervisor-helper.sh and auto-update-helper.sh now function correctly when invoked via symlinks, using temporary test symlinks.
  • Confirmed no regressions were introduced for direct script invocations.
  • Ensured both modified files pass ShellCheck with zero errors.
  • Closed issue t1262: Fix symlink SCRIPT_DIR resolution for launchd agents #1976.
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

This PR fixes symlink resolution for SCRIPT_DIR in two launchd agent helper scripts. It introduces a _resolve_script_path function that correctly resolves the actual script location by traversing symlinks, ensuring scripts function properly when invoked indirectly through symbolic links.

Changes

Cohort / File(s) Summary
Symlink Resolution Implementation
\.agents/scripts/auto-update-helper.sh, \.agents/scripts/supervisor-helper.sh
Added _resolve_script_path internal function to resolve real script paths, replacing direct SCRIPT_DIR assignment. Both scripts now correctly handle symlinks; supervisor-helper additionally marks SCRIPT_DIR as readonly and unsets the helper function after use.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🔗 Symlinks no longer lead astray,
SCRIPT_DIR finds the real way,
Launchd agents stand tall and true,
Following paths both old and new,
DevOps quality shines through! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: fixing symlink SCRIPT_DIR resolution for launchd agents, which directly matches the changeset modifications in both helper scripts.
Linked Issues check ✅ Passed The pull request successfully addresses issue #1976 by implementing _resolve_script_path() function in both scripts to resolve symlinks before determining SCRIPT_DIR, meeting the core objective to fix launchd agent helper script invocation via symlinks.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing symlink resolution in auto-update-helper.sh and supervisor-helper.sh; no unrelated modifications or scope creep detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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/t1262-symlink-script-dir

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 21:34:24 UTC 2026: Code review monitoring started
Thu Feb 19 21:34:25 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 21:34:27 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link

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

The pull request addresses a critical issue where scripts invoked via symlinks fail to locate shared-constants.sh. The fix introduces a robust _resolve_script_path function to correctly determine the script's real location by following symlinks. This ensures that SCRIPT_DIR is always accurate, allowing dependent scripts to be sourced correctly. The changes are well-tested and adhere to the repository's shell scripting standards.

@marcusquinn marcusquinn merged commit 54e63f6 into main Feb 19, 2026
10 of 11 checks passed
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.

🧹 Nitpick comments (1)
.agents/scripts/auto-update-helper.sh (1)

29-43: Two minor gaps vs supervisor-helper.sh: missing readonly and silent failure path.

  1. supervisor-helper.sh marks SCRIPT_DIR as readonly (line 183) immediately after assignment; auto-update-helper.sh does not. The AI summary claims it does, but the code disagrees — worth keeping consistent.
  2. || exit is silent: when launchd invokes this script via the symlink and path resolution fails, the process exits with no stderr/log entry, making the failure invisible in ~/.aidevops/logs/auto-update.log.

Per coding guidelines: .agents/scripts/*.sh must provide clear logging and feedback.

✨ Proposed fix — add `readonly` and a diagnostic message on failure
-SCRIPT_DIR="$(_resolve_script_path)" || exit
+SCRIPT_DIR="$(_resolve_script_path)" || { echo "[auto-update-helper] ERROR: failed to resolve script path" >&2; exit 1; }
 unset -f _resolve_script_path
+readonly SCRIPT_DIR
 source "${SCRIPT_DIR}/shared-constants.sh"
🤖 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 29 - 43, The SCRIPT_DIR
assignment in _resolve_script_path lacks the readonly qualifier and exits
silently on failure; update the assignment to capture the result of
_resolve_script_path into SCRIPT_DIR, mark SCRIPT_DIR readonly (like
supervisor-helper.sh), and replace the silent "|| exit" with explicit failure
logging (write a diagnostic to stderr or the auto-update.log explaining path
resolution failed and include any error context) before exiting non-zero so
failures are visible; refer to the _resolve_script_path function and the
SCRIPT_DIR variable when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.agents/scripts/auto-update-helper.sh:
- Around line 29-43: The SCRIPT_DIR assignment in _resolve_script_path lacks the
readonly qualifier and exits silently on failure; update the assignment to
capture the result of _resolve_script_path into SCRIPT_DIR, mark SCRIPT_DIR
readonly (like supervisor-helper.sh), and replace the silent "|| exit" with
explicit failure logging (write a diagnostic to stderr or the auto-update.log
explaining path resolution failed and include any error context) before exiting
non-zero so failures are visible; refer to the _resolve_script_path function and
the SCRIPT_DIR variable when making the change.

@marcusquinn marcusquinn deleted the bugfix/t1262-symlink-script-dir branch February 21, 2026 01:59
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.

t1262: Fix symlink SCRIPT_DIR resolution for launchd agents

1 participant