Skip to content

feat: auto-update opt-out via settings.json#2727

Merged
marcusquinn merged 1 commit intomainfrom
feature/auto-update-config
Mar 2, 2026
Merged

feat: auto-update opt-out via settings.json#2727
marcusquinn merged 1 commit intomainfrom
feature/auto-update-config

Conversation

@marcusquinn
Copy link
Copy Markdown
Owner

@marcusquinn marcusquinn commented Mar 2, 2026

Summary

  • Adds ~/.config/aidevops/settings.json as a persistent config file for user preferences
  • setup.sh reads auto_update, supervisor_pulse, and repo_sync keys before scheduling launchd/cron jobs
  • If auto_update: false, the auto-update scheduler is not installed and checks are skipped
  • Priority chain: environment variable > settings.json > default (true)

Changes

  • shared-constants.sh: New get_setting() utility function. Handles JSON boolean false correctly (jq's // operator treats false as empty — uses has() + tostring instead)
  • setup.sh: All three scheduler sections (auto-update, supervisor pulse, repo sync) now check settings.json before the env var fallback
  • auto-update-helper.sh: cmd_check respects settings.json, cmd_enable warns if disabled, cmd_status shows settings.json state, help text documents the config file
  • services.md: New "User Settings" section with supported keys table, updated Auto-Update and Repo Sync sections

Testing

  • ShellCheck: zero violations on all modified files
  • Markdown lint: zero violations on services.md
  • Functional tests: get_setting() correctly handles boolean false, string "false", missing keys, and missing file
  • jq pattern in setup.sh tested with all value types (boolean false, string false, missing key, boolean true)

Closes #2722

Summary by CodeRabbit

  • New Features
    • Added persistent configuration file support at ~/.config/aidevops/settings.json for managing auto-update, supervisor pulse, and repo-sync features.
    • Configuration supports three settable keys with clear precedence: environment variables override settings file, which overrides built-in defaults.
    • Users can now persistently disable individual features via settings file as an alternative to temporary environment variable overrides.

Add ~/.config/aidevops/settings.json as a persistent config file for user
preferences. setup.sh and auto-update-helper.sh read this config before
scheduling launchd/cron jobs. If auto_update is false, skip scheduling.

- Add get_setting() utility to shared-constants.sh (handles JSON boolean
  false correctly via jq has() instead of // which treats false as empty)
- Gate auto-update, supervisor pulse, and repo sync on settings.json
- Priority: env var > settings.json > default (true)
- Update auto-update-helper.sh help, status, and check commands
- Document settings.json in services.md with supported keys table

Closes #2722
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, 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 introduces a new, persistent configuration mechanism for user preferences through a settings.json file. This allows users to control the behavior of scheduled tasks such as auto-updates, supervisor pulses, and repository synchronization without relying solely on environment variables or manual intervention. The system prioritizes environment variables, then the new settings.json file, and finally sensible defaults, providing a flexible and user-friendly way to manage system automation.

Highlights

  • Persistent User Preferences: Introduced ~/.config/aidevops/settings.json as a persistent configuration file for user preferences, allowing for long-term control over scheduled tasks.
  • Scheduler Opt-Out: Enabled setup.sh to read auto_update, supervisor_pulse, and repo_sync keys from settings.json to determine whether to install or enable their respective scheduled jobs.
  • Auto-Update Control: Setting auto_update: false in settings.json now prevents the auto-update scheduler from being installed and skips checks, providing a clear opt-out mechanism.
  • Configuration Priority: Established a clear priority chain for configuration settings: environment variables take precedence over settings.json, which in turn overrides default values (typically true).
  • Robust Settings Reader: Added a get_setting() utility function in shared-constants.sh to reliably read values from settings.json, correctly handling JSON boolean false and missing keys/files.
Changelog
  • .agents/reference/services.md
    • Added a new "User Settings" section detailing the settings.json file and supported keys.
    • Updated Auto-Update and Repo Sync sections to reference the new settings.json configuration.
  • .agents/scripts/auto-update-helper.sh
    • Updated help text to document the new settings.json configuration options.
    • Modified cmd_check to respect auto_update: false in settings.json.
    • Added a warning in cmd_enable if auto-update is disabled via settings.json.
    • Enhanced cmd_status to display the auto-update state as configured in settings.json.
  • .agents/scripts/shared-constants.sh
    • Added a get_setting() utility function to safely read boolean values from settings.json, handling missing keys and jq availability.
  • setup.sh
    • Modified the auto-update, supervisor pulse, and repo sync scheduler installation logic to check settings.json for opt-out preferences before proceeding.
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
Copy Markdown
Contributor

coderabbitai bot commented Mar 2, 2026

Walkthrough

This PR implements a persistent configuration system for aidevops by introducing ~/.config/aidevops/settings.json support. A new get_setting() function reads configuration keys with fallback defaults, while setup and auto-update scripts now enforce a three-tier precedence: environment variables override settings.json, which overrides built-in defaults. Documentation updated to describe the new User Settings section and configuration priority.

Changes

Cohort / File(s) Summary
Configuration Documentation
.agents/reference/services.md
Added User Settings section documenting persistent settings file location, supported keys (auto_update, supervisor_pulse, repo_sync), JSON format, and three-tier precedence (env vars > settings.json > defaults). Updated Auto-Update and Repo Sync sections with configuration file opt-out notes.
Settings Reader Infrastructure
.agents/scripts/shared-constants.sh
Introduces get_setting(key, default) function that reads JSON keys from ~/.config/aidevops/settings.json with graceful fallback to defaults when file is missing, key absent, or jq unavailable. Returns string values and always exits 0.
Auto-Update Configuration
.agents/scripts/auto-update-helper.sh
Updates cmd_check, cmd_status, and cmd_enable to respect settings.json in addition to env overrides. Adds precedence documentation, surfaces config status in logs/messages, and clarifies that env vars override settings.json configuration.
Setup Script Precedence Logic
setup.sh
Implements three-tier precedence for auto-update, supervisor pulse, and repo-sync features: checks env vars first, falls back to settings.json via get_setting(), then uses built-in defaults (true). Replaces simple env checks with layered configuration resolution.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

📋 Configuration blooms from JSON files so fine,
Environment and settings now in harmony align,
A three-tier dance: env, file, and default too,
Shell scripts respect the precedence they're due,
Auto-updates and syncs now bending to your will. 🎛️

🚥 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 'feat: auto-update opt-out via settings.json' accurately and concisely describes the main feature addition—enabling users to disable auto-updates through a settings file.
Linked Issues check ✅ Passed All acceptance criteria from #2722 are met: config option auto_update: false disables the job, setup.sh reads config before scheduling, and documentation is updated.
Out of Scope Changes check ✅ Passed All changes directly support the auto-update opt-out feature, though supervisor_pulse and repo_sync configuration are included beyond the strict scope of #2722.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% 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 (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/auto-update-config

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
Copy Markdown
Contributor

github-actions bot commented Mar 2, 2026

🔍 Code Quality Report

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

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

�[0;34m[INFO]�[0m Recent monitoring activity:
Mon Mar 2 18:09:42 UTC 2026: Code review monitoring started
Mon Mar 2 18:09:42 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 111

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 111
  • VULNERABILITIES: 0

Generated on: Mon Mar 2 18:09:44 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Mar 2, 2026

@alex-solovyev
Copy link
Copy Markdown
Collaborator

Worker completed — PR has commit ff949d5 and resolves #2722. CI pending. Supervisor pulse killed idle worker process (PID 2711318) after confirming PR was created successfully.

Copy link
Copy Markdown
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)
setup.sh (1)

654-665: Consider extracting repeated jq pattern into a local helper.

The same jq -r 'if has("key") then .key | tostring else "true" end' pattern appears three times. Since setup.sh doesn't source shared-constants.sh (where get_setting() lives), you could either:

  1. Source shared-constants.sh early and use get_setting directly
  2. Add a small local helper at the top of main()

This would reduce the maintenance burden if the settings file path or jq pattern ever changes.

♻️ Option 2: Local helper function

Add near the top of main():

# Local settings reader (shared-constants.sh not sourced in setup.sh)
_get_setting() {
    local key="$1" default="$2"
    if [[ -f "$HOME/.config/aidevops/settings.json" ]] && command -v jq &>/dev/null; then
        jq -r --arg k "$key" 'if has($k) then .[$k] | tostring else "'"$default"'" end' \
            "$HOME/.config/aidevops/settings.json" 2>/dev/null || echo "$default"
    else
        echo "$default"
    fi
}

Then replace the three inline blocks with:

local _auto_update_setting="${AIDEVOPS_AUTO_UPDATE:-$(_get_setting "auto_update" "true")}"
local _pulse_setting="${AIDEVOPS_SUPERVISOR_PULSE:-$(_get_setting "supervisor_pulse" "true")}"
local _repo_sync_setting="${AIDEVOPS_REPO_SYNC:-$(_get_setting "repo_sync" "true")}"

Also applies to: 713-722, 853-863

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

In `@setup.sh` around lines 654 - 665, The repeated jq pattern for reading
settings should be extracted into a small local helper (e.g., _get_setting)
declared near the top of main() so setup.sh doesn't duplicate the jq logic;
implement _get_setting(key, default) to check for the settings.json file and jq
availability, return the key's value as string or the default on error, then
replace the three inline blocks that set _auto_update_setting, _pulse_setting,
and _repo_sync_setting with calls like "${AIDEVOPS_AUTO_UPDATE:-$(_get_setting
"auto_update" "true")}" to centralize behavior and reduce duplication; reference
the helper name _get_setting and main() when making edits.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@setup.sh`:
- Around line 654-665: The repeated jq pattern for reading settings should be
extracted into a small local helper (e.g., _get_setting) declared near the top
of main() so setup.sh doesn't duplicate the jq logic; implement
_get_setting(key, default) to check for the settings.json file and jq
availability, return the key's value as string or the default on error, then
replace the three inline blocks that set _auto_update_setting, _pulse_setting,
and _repo_sync_setting with calls like "${AIDEVOPS_AUTO_UPDATE:-$(_get_setting
"auto_update" "true")}" to centralize behavior and reduce duplication; reference
the helper name _get_setting and main() when making edits.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 76f9e44 and ff949d5.

📒 Files selected for processing (4)
  • .agents/reference/services.md
  • .agents/scripts/auto-update-helper.sh
  • .agents/scripts/shared-constants.sh
  • setup.sh

@marcusquinn marcusquinn merged commit 55211e5 into main Mar 2, 2026
25 checks passed
Copy link
Copy Markdown

@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 introduces a persistent configuration file for user settings, which is a great feature for improving user experience. The implementation is solid, but I've identified a few areas for improvement. My main concerns are around code duplication in setup.sh and some logic in auto-update-helper.sh that doesn't fully respect the new configuration priority, which could lead to confusing behavior. I've also suggested removing stderr suppression from jq calls to improve debuggability, in line with the project's conventions.

Comment on lines +656 to +664
local _auto_update_setting="${AIDEVOPS_AUTO_UPDATE:-}"
if [[ -z "$_auto_update_setting" ]]; then
# No env var — check settings.json (requires jq; defaults to "true")
if [[ -f "$HOME/.config/aidevops/settings.json" ]] && command -v jq &>/dev/null; then
_auto_update_setting=$(jq -r 'if has("auto_update") then .auto_update | tostring else "true" end' "$HOME/.config/aidevops/settings.json" 2>/dev/null) || _auto_update_setting="true"
else
_auto_update_setting="true"
fi
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The logic for reading a setting by checking an environment variable and falling back to settings.json is duplicated three times in this file (for auto_update here, supervisor_pulse at lines 714-721, and repo_sync at lines 855-862). This creates redundancy and makes the script harder to maintain.

Additionally, the jq command used in these blocks suppresses stderr with 2>/dev/null. This hides errors if settings.json is malformed, making it difficult for users to debug configuration problems. This goes against the project's general rule to keep error messages visible.

This logic should be extracted into a local helper function within setup.sh to address both the duplication and the error suppression in one place.

References
  1. In shell scripts, extract repeated logic into an internal helper function to improve maintainability. This applies even for standalone scripts where external source dependencies are avoided.
  2. When reporting errors for failed file operations in shell scripts, such as 'jq' writes, include the file path in the error message. Avoid suppressing stderr with '2>/dev/null' to ensure that diagnostic information about malformed files or write failures is visible.
  3. Avoid using '2>/dev/null' for blanket suppression of command errors in shell scripts to ensure that authentication, syntax, or system issues remain visible for debugging.

Comment on lines 869 to +878
if [[ "${AIDEVOPS_AUTO_UPDATE:-}" == "false" ]]; then
log_info "Auto-update disabled via AIDEVOPS_AUTO_UPDATE=false"
return 0
fi

# Check settings.json (only when env var is not set)
if [[ -z "${AIDEVOPS_AUTO_UPDATE:-}" ]] && [[ "$(get_setting "auto_update" "true")" == "false" ]]; then
log_info "Auto-update disabled via settings.json (auto_update: false)"
return 0
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The logic to check if auto-update is disabled is split across two if statements, which involves checking the AIDEVOPS_AUTO_UPDATE variable twice. This can be made more concise and readable by combining them into a single if/elif structure.

Suggested change
if [[ "${AIDEVOPS_AUTO_UPDATE:-}" == "false" ]]; then
log_info "Auto-update disabled via AIDEVOPS_AUTO_UPDATE=false"
return 0
fi
# Check settings.json (only when env var is not set)
if [[ -z "${AIDEVOPS_AUTO_UPDATE:-}" ]] && [[ "$(get_setting "auto_update" "true")" == "false" ]]; then
log_info "Auto-update disabled via settings.json (auto_update: false)"
return 0
fi
if [[ "${AIDEVOPS_AUTO_UPDATE:-}" == "false" ]]; then
log_info "Auto-update disabled via AIDEVOPS_AUTO_UPDATE=false"
return 0
elif [[ -z "${AIDEVOPS_AUTO_UPDATE:-}" ]] && [[ "$(get_setting "auto_update" "true")" == "false" ]]; then
log_info "Auto-update disabled via settings.json (auto_update: false)"
return 0
fi

Comment on lines +987 to +990
if [[ "$(get_setting "auto_update" "true")" == "false" ]]; then
print_warning "settings.json has auto_update: false — scheduler will install but checks will be skipped"
print_info "To enable: set auto_update to true in ~/.config/aidevops/settings.json"
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The warning logic here is incorrect as it doesn't respect the configuration priority (env var > settings.json). It will show a warning if auto_update: false is in settings.json, even if the user has correctly overridden it with AIDEVOPS_AUTO_UPDATE=true. The check should only trigger if the environment variable is not set.

Suggested change
if [[ "$(get_setting "auto_update" "true")" == "false" ]]; then
print_warning "settings.json has auto_update: false — scheduler will install but checks will be skipped"
print_info "To enable: set auto_update to true in ~/.config/aidevops/settings.json"
fi
if [[ -z "${AIDEVOPS_AUTO_UPDATE:-}" ]] && [[ "$(get_setting "auto_update" "true")" == "false" ]]; then
print_warning "settings.json has auto_update: false — scheduler will install but checks will be skipped"
print_info "To enable: set auto_update to true in ~/.config/aidevops/settings.json or set AIDEVOPS_AUTO_UPDATE=true"
fi

Comment on lines +1287 to 1299
# Check settings.json overrides
local _settings_auto_update
_settings_auto_update="$(get_setting "auto_update" "true")"
if [[ "$_settings_auto_update" == "false" ]]; then
echo ""
echo -e " ${YELLOW}Note: settings.json has auto_update: false (checks will be skipped)${NC}"
fi

# Check env var overrides (env vars take priority over settings.json)
if [[ "${AIDEVOPS_AUTO_UPDATE:-}" == "false" ]]; then
echo ""
echo -e " ${YELLOW}Note: AIDEVOPS_AUTO_UPDATE=false is set (overrides scheduler)${NC}"
echo -e " ${YELLOW}Note: AIDEVOPS_AUTO_UPDATE=false is set (overrides scheduler and settings.json)${NC}"
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The status output can be confusing by showing two separate messages if both settings.json and the environment variable disable auto-updates. To improve clarity, this should be a single message that reflects the effective configuration based on the priority order (env var > settings.json).

Suggested change
# Check settings.json overrides
local _settings_auto_update
_settings_auto_update="$(get_setting "auto_update" "true")"
if [[ "$_settings_auto_update" == "false" ]]; then
echo ""
echo -e " ${YELLOW}Note: settings.json has auto_update: false (checks will be skipped)${NC}"
fi
# Check env var overrides (env vars take priority over settings.json)
if [[ "${AIDEVOPS_AUTO_UPDATE:-}" == "false" ]]; then
echo ""
echo -e " ${YELLOW}Note: AIDEVOPS_AUTO_UPDATE=false is set (overrides scheduler)${NC}"
echo -e " ${YELLOW}Note: AIDEVOPS_AUTO_UPDATE=false is set (overrides scheduler and settings.json)${NC}"
fi
# Check for overrides (env vars take priority over settings.json)
if [[ "${AIDEVOPS_AUTO_UPDATE:-}" == "false" ]]; then
echo ""
echo -e " ${YELLOW}Note: AIDEVOPS_AUTO_UPDATE=false is set (overrides scheduler and settings.json)${NC}"
elif [[ "$(get_setting "auto_update" "true")" == "false" ]]; then
echo ""
echo -e " ${YELLOW}Note: settings.json has auto_update: false (checks will be skipped)${NC}"
fi

local value
value=$(jq -r --arg k "$key" \
'if has($k) then .[$k] | tostring else "___MISSING___" end' \
"$AIDEVOPS_SETTINGS_FILE" 2>/dev/null) || value="___MISSING___"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The jq command suppresses stderr using 2>/dev/null. This prevents visibility of errors if the settings.json file is malformed, making it harder for users to debug their configuration. According to the project's general rules, stderr should not be suppressed for such operations. Removing 2>/dev/null will allow jq to report syntax errors in the JSON file while still allowing the function to fall back to the default value gracefully due to the || value="___MISSING___" part.

Suggested change
"$AIDEVOPS_SETTINGS_FILE" 2>/dev/null) || value="___MISSING___"
"$AIDEVOPS_SETTINGS_FILE") || value="___MISSING___"
References
  1. Avoid suppressing stderr with '2>/dev/null' when sourcing files in shell scripts; syntax errors or missing files should remain visible for debugging even if a fallback is provided.
  2. When reporting errors for failed file operations in shell scripts, such as 'jq' writes, include the file path in the error message. Avoid suppressing stderr with '2>/dev/null' to ensure that diagnostic information about malformed files or write failures is visible.
  3. In shell scripts with 'set -e' enabled, use '|| true' to prevent the script from exiting when a command like 'jq' fails on an optional lookup. Do not suppress stderr with '2>/dev/null' so that actual syntax or system errors remain visible for debugging.
  4. Avoid using '2>/dev/null' for blanket suppression of command errors in shell scripts to ensure that authentication, syntax, or system issues remain visible for debugging.

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

Labels

enhancement Auto-created from TODO.md tag

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: auto-update opt-out and configurable update behaviour

2 participants