-
Notifications
You must be signed in to change notification settings - Fork 6
Fix OpenCode plugin array overwrite bug #92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Summary of ChangesHello @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 Highlights
Using Gemini Code AssistThe 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
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 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
|
|
Note Other AI code review bot(s) detectedCodeRabbit 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. WalkthroughThe Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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)
✏️ Tip: You can disable this entire section by setting 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. Comment |
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Wed Jan 14 16:13:43 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
🤖 Augment PR SummarySummary: Fixes OpenCode plugin setup logic so existing plugin arrays are preserved and new plugins are appended instead of overwriting. 🤖 Was this summary useful? React with 👍 or 👎 |
There was a problem hiding this 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.
There was a problem hiding this 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") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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") |
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Wed Jan 14 17:37:01 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
There was a problem hiding this 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
📒 Files selected for processing (3)
.agent/scripts/linters-local.sh.secretlintignoreTODO.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
.secretlintignorepatterns reducing the scan scope to ~230 files (per t063), this timeout should be more than sufficient while still catching runaway scans.The message,
gtimeout, andtimeoutvalues are all consistently updated.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
TODO.md
Outdated
| - [ ] 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). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 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.shRepository: 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' .gitignoreRepository: 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.
d4fee93 to
a4e927b
Compare
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Wed Jan 14 19:25:15 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
a4e927b to
809f384
Compare
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Wed Jan 14 20:25:26 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Thu Jan 15 00:22:01 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
There was a problem hiding this 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
📒 Files selected for processing (7)
.claude-plugin/marketplace.jsonCHANGELOG.mdREADME.mdVERSIONaidevops.shsetup.shsonar-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.mdCHANGELOG.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:
- Version was bumped twice for the same fix
- 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 inadd_opencode_plugin().The redirection change from
2>/dev/nullto>/dev/null 2>&1on lines 1839 and 1844 correctly addresses the root cause. Thejq -ecommand outputs JSON to stdout on success, which was being captured alongsideecho "true", producing values like["oh-my-opencode"]\ntrueinstead of justtrue. 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 tosetup_oh_my_opencode().The same redirection pattern
>/dev/null 2>&1correctly 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-opencodevs[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
| - suppress jq output in plugin array checks | ||
| ## [2.55.1] - 2026-01-14 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| - 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
a1099d7 to
e47d92a
Compare
|
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Thu Jan 15 00:32:40 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |



Summary
setup_opencode_pluginsoverwrites the plugin array instead of appending to itjq -ecommand outputs JSON to stdout, which concatenates withecho "true", causing the condition to failProblem
When running
setup.shwith existing plugins inopencode.json:After
setup_opencode_plugins, only the last plugin remained:Root Cause
The condition
[[ "$has_plugin_array" == "true" ]]failed, falling through to theelsebranch which creates a new array.Fix
Added
>/dev/nullto suppress jq stdout while preserving exit code:Changes
setup.sh: Fixed 4 occurrences inadd_opencode_plugin()andsetup_oh_my_opencode()functionsTesting
After fix, running
setup_opencode_pluginscorrectly appends plugins:Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.