Skip to content

Conversation

@alex-solovyev
Copy link
Collaborator

@alex-solovyev alex-solovyev commented Jan 14, 2026

Summary

  • Fix bug where setup_opencode_plugins overwrites the plugin array instead of appending to it
  • The jq -e command outputs JSON to stdout, which concatenates with echo "true", causing the condition to fail

Problem

When running setup.sh with existing plugins in opencode.json:

"plugin": ["oh-my-opencode"]

After setup_opencode_plugins, only the last plugin remained:

"plugin": ["opencode-anthropic-auth@latest"]

Root Cause

# Bug: jq outputs JSON before && runs
has_plugin_array=$(jq -e '.plugin' "$config" 2>/dev/null && echo "true" || echo "false")
# Result: '["oh-my-opencode"]\ntrue' — not equal to "true"

The condition [[ "$has_plugin_array" == "true" ]] failed, falling through to the else branch which creates a new array.

Fix

Added >/dev/null to suppress jq stdout while preserving exit code:

has_plugin_array=$(jq -e '.plugin' "$config" >/dev/null 2>&1 && echo "true" || echo "false")
# Result: 'true' — correct

Changes

  • setup.sh: Fixed 4 occurrences in add_opencode_plugin() and setup_oh_my_opencode() functions

Testing

After fix, running setup_opencode_plugins correctly appends plugins:

"plugin": [
  "oh-my-opencode",
  "opencode-antigravity-auth@latest",
  "opencode-anthropic-auth@latest"
]

Summary by CodeRabbit

  • Chores
    • Enhanced error output handling in the setup script to reduce console noise during plugin installation checks.

✏️ Tip: You can customize this high-level summary in your review settings.

@gemini-code-assist
Copy link

Summary of Changes

Hello @alex-solovyev, 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 addresses a critical bug in the setup.sh script that prevented new OpenCode plugins from being correctly added to the opencode.json configuration. Previously, existing plugin arrays were being overwritten due to an unintended interaction between jq's output and shell conditional logic. The changes ensure that jq's output is properly suppressed, allowing the script to accurately determine the presence of plugin arrays and append new plugins as intended, thereby preserving existing configurations.

Highlights

  • Bug Fix: Resolved an issue where the setup_opencode_plugins function would incorrectly overwrite the plugin array in opencode.json instead of appending new plugins.
  • Root Cause Identified: The bug stemmed from the jq -e command outputting JSON to stdout, which then concatenated with echo "true", causing the shell condition [[ "$has_plugin_array" == "true" ]] to fail unexpectedly.
  • Solution Implemented: The fix involves redirecting the stdout of jq -e to /dev/null using >/dev/null 2>&1 to prevent its output from interfering with the shell variable assignment, while still preserving its exit code for conditional logic.
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 Jan 14, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

The setup.sh script's error suppression patterns were standardized across multiple functions. Redirection syntax changed from 2>/dev/null to >/dev/null 2>&1 in add_opencode_plugin and setup_oh_my_opencode functions, ensuring both stdout and stderr are silenced consistently.

Changes

Cohort / File(s) Summary
Shell Script Error Handling
setup.sh
Standardized output redirection in error suppression from 2>/dev/null to >/dev/null 2>&1 across jq command checks in add_opencode_plugin, has_plugin_array, and plugin_exists functions for comprehensive stream silencing

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Poem

✨ Quiet streams, both out and err,
Redirected with perfect flair,
Zero debt maintained so clear,
DevOps polish, beyond compare! 🚀

🚥 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 describes the main bug fix—correcting jq output suppression to prevent plugin array overwrites in setup.sh.
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


📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a1099d7 and e47d92a.

📒 Files selected for processing (1)
  • setup.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • setup.sh
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


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, 260 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Wed Jan 14 16:13:07 UTC 2026: Code review monitoring started
Wed Jan 14 16:13:07 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 260
Wed Jan 14 16:13:07 UTC 2026: Qlty - 0 issues found, auto-formatting applied
Wed Jan 14 16:13:09 UTC 2026: Codacy analysis completed with auto-fixes

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 260
  • VULNERABILITIES: 0

Generated on: Wed Jan 14 16:13:43 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@augmentcode
Copy link

augmentcode bot commented Jan 14, 2026

🤖 Augment PR Summary

Summary: Fixes OpenCode plugin setup logic so existing plugin arrays are preserved and new plugins are appended instead of overwriting.
Changes: Suppresses jq -e stdout/stderr in boolean checks within add_opencode_plugin() and setup_oh_my_opencode() to ensure the true/false conditionals work reliably.

🤖 Was this summary useful? React with 👍 or 👎

Copy link

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

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

Review completed. No suggestions at this time.

Comment augment review to trigger a new review at any time.

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 effectively addresses a critical bug related to jq output handling in shell scripts, which was causing plugin arrays to be overwritten instead of appended. The solution correctly redirects jq's standard output to /dev/null while preserving its exit code, ensuring the conditional logic functions as intended. This is a good fix for a subtle but impactful issue.

# Check if plugin array exists and if plugin is already configured
local has_plugin_array
has_plugin_array=$(jq -e '.plugin' "$opencode_config" 2>/dev/null && echo "true" || echo "false")
has_plugin_array=$(jq -e '.plugin' "$opencode_config" >/dev/null 2>&1 && echo "true" || echo "false")

Choose a reason for hiding this comment

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

high

This change correctly redirects jq's standard output to /dev/null while preserving its exit code. The original 2>/dev/null only suppressed stderr, allowing jq's successful JSON output to be captured by the variable, leading to incorrect conditional evaluation. This fix directly addresses the root cause of the plugin array overwrite bug.

Suggested change
has_plugin_array=$(jq -e '.plugin' "$opencode_config" >/dev/null 2>&1 && echo "true" || echo "false")
has_plugin_array=$(jq -e '.plugin' "$opencode_config" >/dev/null 2>&1 && echo "true" || echo "false")

# Check if plugin is already in the array
local plugin_exists
plugin_exists=$(jq -e --arg p "$plugin_name" '.plugin | map(select(startswith($p))) | length > 0' "$opencode_config" 2>/dev/null && echo "true" || echo "false")
plugin_exists=$(jq -e --arg p "$plugin_name" '.plugin | map(select(startswith($p))) | length > 0' "$opencode_config" >/dev/null 2>&1 && echo "true" || echo "false")

Choose a reason for hiding this comment

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

high

Similar to the previous instance, redirecting both stdout and stderr (>/dev/null 2>&1) ensures that the jq command's output does not interfere with the shell variable assignment, which was causing the plugin_exists check to fail incorrectly. This is a crucial fix for the logic.

Suggested change
plugin_exists=$(jq -e --arg p "$plugin_name" '.plugin | map(select(startswith($p))) | length > 0' "$opencode_config" >/dev/null 2>&1 && echo "true" || echo "false")
plugin_exists=$(jq -e --arg p "$plugin_name" '.plugin | map(select(startswith($p))) | length > 0' "$opencode_config" >/dev/null 2>&1 && echo "true" || echo "false")

# Check if plugin array exists
local has_plugin_array
has_plugin_array=$(jq -e '.plugin' "$opencode_config" 2>/dev/null && echo "true" || echo "false")
has_plugin_array=$(jq -e '.plugin' "$opencode_config" >/dev/null 2>&1 && echo "true" || echo "false")

Choose a reason for hiding this comment

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

high

This modification correctly handles the jq command's output by redirecting both stdout and stderr to /dev/null. This prevents the JSON output from jq -e from being concatenated with echo "true", which was causing the has_plugin_array variable to hold an unexpected value and leading to incorrect conditional logic.

Suggested change
has_plugin_array=$(jq -e '.plugin' "$opencode_config" >/dev/null 2>&1 && echo "true" || echo "false")
has_plugin_array=$(jq -e '.plugin' "$opencode_config" >/dev/null 2>&1 && echo "true" || echo "false")

# Check if plugin is already in the array
local plugin_exists
plugin_exists=$(jq -e --arg p "$plugin_name" '.plugin | map(select(. == $p or startswith($p + "@"))) | length > 0' "$opencode_config" 2>/dev/null && echo "true" || echo "false")
plugin_exists=$(jq -e --arg p "$plugin_name" '.plugin | map(select(. == $p or startswith($p + "@"))) | length > 0' "$opencode_config" >/dev/null 2>&1 && echo "true" || echo "false")

Choose a reason for hiding this comment

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

high

The change from 2>/dev/null to >/dev/null 2>&1 is essential here. It ensures that the jq command's output is completely suppressed, allowing the plugin_exists variable to accurately reflect the success or failure of the jq expression based solely on its exit code. This resolves the bug where existing plugins were not correctly detected.

Suggested change
plugin_exists=$(jq -e --arg p "$plugin_name" '.plugin | map(select(. == $p or startswith($p + "@"))) | length > 0' "$opencode_config" >/dev/null 2>&1 && echo "true" || echo "false")
plugin_exists=$(jq -e --arg p "$plugin_name" '.plugin | map(select(. == $p or startswith($p + "@"))) | length > 0' "$opencode_config" >/dev/null 2>&1 && echo "true" || echo "false")

@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, 261 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Wed Jan 14 17:36:19 UTC 2026: Code review monitoring started
Wed Jan 14 17:36:20 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 261
Wed Jan 14 17:36:20 UTC 2026: Qlty - 0 issues found, auto-formatting applied
Wed Jan 14 17:36:22 UTC 2026: Codacy analysis completed with auto-fixes

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 261
  • VULNERABILITIES: 0

Generated on: Wed Jan 14 17:37:01 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

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: 2

🤖 Fix all issues with AI agents
In @.secretlintignore:
- Around line 108-118: The .secretlintignore contains the pattern "**/bun.lock"
which is not present in .gitignore, violating the subset rule; to fix, either
add the equivalent pattern "**/bun.lock" (or a matching glob like "bun.lock" or
"**/bun.lock*") to .gitignore so both files mirror each other, or remove the
"**/bun.lock" entry from .secretlintignore if bun.lock should not be ignored in
git; update the pattern in the file that needs changing and commit the matching
change so .secretlintignore remains a subset of .gitignore.

In `@TODO.md`:
- Around line 138-139: The script still passes the broad glob "**/*" to the
secretlint/file-glob calls, causing huge binary scans; locate each occurrence of
the literal "**/*" used as the file glob (three spots where the linter is
invoked) and replace it with the whitelist glob
"**/*.{sh,json,yaml,yml,js,ts,py,toml,ini,cfg,conf}" so only relevant text files
are scanned; ensure you update all three occurrences where the glob is passed to
the linter invocation so the change fully closes t063.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f232483 and d4fee93.

📒 Files selected for processing (3)
  • .agent/scripts/linters-local.sh
  • .secretlintignore
  • TODO.md
🧰 Additional context used
📓 Path-based instructions (3)
**/.agent/scripts/linters-local.sh

📄 CodeRabbit inference engine (AGENTS.md)

Run quality checks before committing using .agent/scripts/linters-local.sh

Files:

  • .agent/scripts/linters-local.sh
.agent/scripts/*.sh

⚙️ CodeRabbit configuration file

.agent/scripts/*.sh: Automation scripts - focus on:

  • Reliability and robustness
  • Clear logging and feedback
  • Proper exit codes
  • Error recovery mechanisms

Files:

  • .agent/scripts/linters-local.sh
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Use placeholders in examples and note secure storage location in documentation

Files:

  • TODO.md
🧠 Learnings (1)
📚 Learning: 2026-01-06T15:57:56.027Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-06T15:57:56.027Z
Learning: Applies to **/AGENTS.md : Limit root AGENTS.md to ~50-100 max instructions with universal applicability to >80% of tasks

Applied to files:

  • TODO.md
🧬 Code graph analysis (1)
.agent/scripts/linters-local.sh (6)
.agent/scripts/version-manager.sh (1)
  • print_info (17-17)
.agent/scripts/fix-s131-default-cases.sh (1)
  • print_info (18-18)
.agent/scripts/postflight-check.sh (1)
  • print_info (75-79)
.agent/scripts/pre-commit-hook.sh (1)
  • print_info (33-37)
.agent/scripts/find-missing-returns.sh (1)
  • print_info (15-19)
.agent/scripts/quality-fix.sh (1)
  • print_info (39-43)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (1)
.agent/scripts/linters-local.sh (1)

310-317: LGTM! Timeout increase is appropriate alongside the ignore pattern updates.

The doubling from 30s to 60s provides headroom for Docker startup overhead plus the scan itself. With the updated .secretlintignore patterns reducing the scan scope to ~230 files (per t063), this timeout should be more than sufficient while still catching runaway scans.

The message, gtimeout, and timeout values are all consistently updated.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

TODO.md Outdated
Comment on lines 138 to 139
- [ ] t063 Fix secretlint scanning performance #bugfix #secretlint #performance ~30m (ai:15m test:10m read:5m) logged:2026-01-14
- Notes: Secretlint scans 19,790 files (572MB) including python-env binaries, causing 60+ min hangs. Fix: 1) Add missing patterns to .secretlintignore (python-env, .osgrep, .scannerwork) - must mirror .gitignore to avoid security gaps. 2) Change glob in linters-local.sh:298 and :321 from "**/*" to whitelist "**/*.{sh,json,yaml,yml,js,ts,py,toml,ini,cfg,conf}". Result: ~230 files scanned in seconds. Principle: .secretlintignore ⊆ .gitignore (subset only).
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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find and display the linters-local.sh file
echo "Locating linters-local.sh:"
find . -name "linters-local.sh" -type f

echo -e "\n--- Content around line 298 ---"
sed -n '290,310p' .agent/scripts/linters-local.sh

echo -e "\n--- Content around line 321 ---"
sed -n '313,330p' .agent/scripts/linters-local.sh

echo -e "\n--- All lines with **/* pattern in linters-local.sh ---"
rg -n '\*\*/\*' .agent/scripts/linters-local.sh

Repository: marcusquinn/aidevops

Length of output: 2525


🏁 Script executed:

#!/bin/bash
# Check .secretlintignore existence and content
echo "=== .secretlintignore status ==="
if [[ -f ".secretlintignore" ]]; then
    echo ".secretlintignore EXISTS:"
    cat -n .secretlintignore
else
    echo ".secretlintignore DOES NOT EXIST"
fi

echo -e "\n=== Timeout configuration in linters-local.sh ==="
rg -n 'timeout' .agent/scripts/linters-local.sh | head -20

echo -e "\n=== Check .gitignore for comparison ==="
rg -n 'python-env|\.osgrep|\.scannerwork' .gitignore

Repository: marcusquinn/aidevops

Length of output: 3605


Only the glob whitelist change in t063 remains incomplete.

Task t063 has been partially implemented: the .secretlintignore patterns (python-env, .osgrep, .scannerwork) are correctly configured and the 60-second timeout is in place (lines 310-316 in linters-local.sh). However, the glob pattern whitelist change remains pending—lines 298, 321, and 324 still use "**/*" instead of the documented whitelist: "**/*.{sh,json,yaml,yml,js,ts,py,toml,ini,cfg,conf}".

Include the glob whitelist changes in this PR to fully close t063 and avoid scanning unnecessary binaries that .secretlintignore cannot exclude.

🤖 Prompt for AI Agents
In `@TODO.md` around lines 138 - 139, The script still passes the broad glob
"**/*" to the secretlint/file-glob calls, causing huge binary scans; locate each
occurrence of the literal "**/*" used as the file glob (three spots where the
linter is invoked) and replace it with the whitelist glob
"**/*.{sh,json,yaml,yml,js,ts,py,toml,ini,cfg,conf}" so only relevant text files
are scanned; ensure you update all three occurrences where the glob is passed to
the linter invocation so the change fully closes t063.

@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, 261 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Wed Jan 14 19:24:32 UTC 2026: Code review monitoring started
Wed Jan 14 19:24:32 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 261
Wed Jan 14 19:24:32 UTC 2026: Qlty - 0 issues found, auto-formatting applied
Wed Jan 14 19:24:34 UTC 2026: Codacy analysis completed with auto-fixes

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 261
  • VULNERABILITIES: 0

Generated on: Wed Jan 14 19:25:15 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@alex-solovyev alex-solovyev force-pushed the bugfix/opencode-plugin-array-overwrite branch from a4e927b to 809f384 Compare January 14, 2026 20:24
@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, 261 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Wed Jan 14 20:24:49 UTC 2026: Code review monitoring started
Wed Jan 14 20:24:49 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 261
Wed Jan 14 20:24:49 UTC 2026: Qlty - 0 issues found, auto-formatting applied
Wed Jan 14 20:24:51 UTC 2026: Codacy analysis completed with auto-fixes

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 261
  • VULNERABILITIES: 0

Generated on: Wed Jan 14 20:25:26 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@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, 261 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Thu Jan 15 00:21:23 UTC 2026: Code review monitoring started
Thu Jan 15 00:21:24 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 261
Thu Jan 15 00:21:24 UTC 2026: Qlty - 0 issues found, auto-formatting applied
Thu Jan 15 00:21:26 UTC 2026: Codacy analysis completed with auto-fixes

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 261
  • VULNERABILITIES: 0

Generated on: Thu Jan 15 00:22:01 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

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

🤖 Fix all issues with AI agents
In `@CHANGELOG.md`:
- Around line 14-15: Add a single blank line before the Markdown heading "##
[2.55.1]" so there is an empty line separating the previous paragraph ("suppress
jq output in plugin array checks") from the heading; update the block containing
the "suppress jq output in plugin array checks" line and the "## [2.55.1]"
heading to include one blank line between them to satisfy MD022.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a4e927b and a1099d7.

📒 Files selected for processing (7)
  • .claude-plugin/marketplace.json
  • CHANGELOG.md
  • README.md
  • VERSION
  • aidevops.sh
  • setup.sh
  • sonar-project.properties
✅ Files skipped from review due to trivial changes (1)
  • aidevops.sh
🧰 Additional context used
📓 Path-based instructions (3)
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Use placeholders in examples and note secure storage location in documentation

Files:

  • README.md
  • CHANGELOG.md
**/setup.sh

📄 CodeRabbit inference engine (AGENTS.md)

Deploy agents locally using ./setup.sh script

Files:

  • setup.sh
**/*.sh

📄 CodeRabbit inference engine (AGENTS.md)

**/*.sh: Use local var="$1" pattern for shell variable assignments
Use explicit returns in shell scripts
Run ShellCheck on all scripts with zero violations required

Files:

  • setup.sh
🧠 Learnings (2)
📚 Learning: 2025-12-22T01:24:53.937Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: templates/home/AGENTS.md:0-0
Timestamp: 2025-12-22T01:24:53.937Z
Learning: Reference the authoritative repository at ~/Git/aidevops/ for all detailed AI assistant instructions and configurations

Applied to files:

  • setup.sh
📚 Learning: 2025-12-22T01:24:53.937Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: templates/home/AGENTS.md:0-0
Timestamp: 2025-12-22T01:24:53.937Z
Learning: Use the helper script at ~/Git/aidevops/.agent/scripts/setup-local-api-keys.sh to manage secure storage of API keys rather than manual configuration

Applied to files:

  • setup.sh
🪛 GitHub Check: Codacy Static Code Analysis
CHANGELOG.md

[notice] 15-15: CHANGELOG.md#L15
Expected: 1; Actual: 0; Above

🪛 markdownlint-cli2 (0.18.1)
CHANGELOG.md

15-15: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (8)
CHANGELOG.md (1)

10-19: Duplicate changelog entries with identical descriptions.

Both 2.55.1 and 2.55.2 contain the same fix: "suppress jq output in plugin array checks". This suggests either:

  1. Version was bumped twice for the same fix
  2. Copy-paste error when adding the new entry

If 2.55.1 was a partial fix and 2.55.2 completes it, consider differentiating the descriptions. Otherwise, this may indicate an unnecessary version bump.

VERSION (1)

1-1: LGTM!

Version bump to 2.55.2 is consistent with the changelog and other metadata files in this PR.

sonar-project.properties (1)

8-8: LGTM!

SonarCloud project version updated to 2.55.2, maintaining consistency across all version metadata files.

README.md (1)

60-60: LGTM!

Version badge updated to 2.55.2. Maintains consistency with VERSION, CHANGELOG.md, and other metadata files across the repository.

.claude-plugin/marketplace.json (1)

9-9: LGTM!

Plugin marketplace version updated to 2.55.2. All version metadata files in this PR are now consistent.

setup.sh (3)

6-6: LGTM!

Version bump to 2.55.2 aligns with the bug fix release across all manifest files.


1832-1868: Solid bug fix in add_opencode_plugin().

The redirection change from 2>/dev/null to >/dev/null 2>&1 on lines 1839 and 1844 correctly addresses the root cause. The jq -e command outputs JSON to stdout on success, which was being captured alongside echo "true", producing values like ["oh-my-opencode"]\ntrue instead of just true. This broke the string equality check and caused the else branch to recreate the array.

The fix preserves jq's exit code semantics (which &&/|| depend on) while suppressing all output. Clean solution that maintains zero technical debt standards.


1964-1991: Consistent fix applied to setup_oh_my_opencode().

The same redirection pattern >/dev/null 2>&1 correctly applied on lines 1968 and 1973. The jq filter on line 1973 appropriately handles both exact plugin name matches and version-suffixed entries (oh-my-opencode vs [email protected]), ensuring existing Oh-My-OpenCode installations are detected regardless of versioning format.

Both functions now handle plugin array detection reliably, maintaining the A-grade shell script quality this framework targets.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

CHANGELOG.md Outdated
Comment on lines 14 to 15
- suppress jq output in plugin array checks
## [2.55.1] - 2026-01-14
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

Missing blank line before heading (MD022).

Static analysis flagged this: the ## [2.55.1] heading on line 15 needs a blank line above it for proper markdown formatting per Keep a Changelog conventions.

📝 Proposed fix
 - suppress jq output in plugin array checks
+
 ## [2.55.1] - 2026-01-14
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- suppress jq output in plugin array checks
## [2.55.1] - 2026-01-14
- suppress jq output in plugin array checks
## [2.55.1] - 2026-01-14
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 15-15: CHANGELOG.md#L15
Expected: 1; Actual: 0; Above

🪛 markdownlint-cli2 (0.18.1)

15-15: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)

🤖 Prompt for AI Agents
In `@CHANGELOG.md` around lines 14 - 15, Add a single blank line before the
Markdown heading "## [2.55.1]" so there is an empty line separating the previous
paragraph ("suppress jq output in plugin array checks") from the heading; update
the block containing the "suppress jq output in plugin array checks" line and
the "## [2.55.1]" heading to include one blank line between them to satisfy
MD022.

The jq -e command outputs the result to stdout before the && echo "true"
runs, causing has_plugin_array to contain the JSON output concatenated
with "true" instead of just "true". This caused the condition to fail
and fall through to the else branch which overwrites the plugin array.

Fixed by adding >/dev/null to suppress jq output while still using its
exit code for the conditional.

Fixes: OpenCode plugin array being overwritten when adding multiple plugins
@alex-solovyev alex-solovyev force-pushed the bugfix/opencode-plugin-array-overwrite branch from a1099d7 to e47d92a Compare January 15, 2026 00:31
@sonarqubecloud
Copy link

@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, 261 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Thu Jan 15 00:31:57 UTC 2026: Code review monitoring started
Thu Jan 15 00:31:57 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 261
Thu Jan 15 00:31:57 UTC 2026: Qlty - 0 issues found, auto-formatting applied
Thu Jan 15 00:31:59 UTC 2026: Codacy analysis completed with auto-fixes

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 261
  • VULNERABILITIES: 0

Generated on: Thu Jan 15 00:32:40 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@alex-solovyev alex-solovyev merged commit 8ca33fc into main Jan 15, 2026
9 checks passed
@alex-solovyev alex-solovyev deleted the bugfix/opencode-plugin-array-overwrite branch January 15, 2026 01:00
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