Skip to content

feat: add WordPress config templates and wp-helper.sh script#263

Merged
marcusquinn merged 4 commits intomainfrom
feature/fix-wordpress-config-templates-260-261-262
Jan 30, 2026
Merged

feat: add WordPress config templates and wp-helper.sh script#263
marcusquinn merged 4 commits intomainfrom
feature/fix-wordpress-config-templates-260-261-262

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Jan 30, 2026

Summary

Changes

New Files

File Purpose
.agent/configs/mainwp-config.json.txt Template for MainWP API configuration
.agent/configs/wordpress-sites.json.txt Template for WordPress sites registry
.agent/scripts/wp-helper.sh WP-CLI helper for multi-site operations

Modified Files

File Changes
.agent/tools/wordpress/wp-admin.md Added setup instructions, wp-helper.sh reference

wp-helper.sh Features

The new script reads from ~/.config/aidevops/wordpress-sites.json and supports:

  • Multiple hosting types: LocalWP, Hostinger, Hetzner, Cloudways, Closte, Cloudron
  • Site categories: Run commands on sites by category
  • Bulk operations: Run WP-CLI commands on all configured sites

Usage Examples

# List all sites
wp-helper.sh --list

# Run on specific site
wp-helper.sh production plugin list

# Run on category
wp-helper.sh --category client core version

# Run on ALL sites
wp-helper.sh --all plugin update --all

Testing

  • ShellCheck passes on wp-helper.sh
  • JSON templates validate with jq
  • Documentation updated

Closes #260, #261, #262

Summary by CodeRabbit

  • New Features

    • Added MainWP Dashboard configuration templates for production and staging.
    • Added a centralized WordPress Sites registry with hosting-type descriptors and site categories.
    • Added a command-line helper to list sites and run WP-CLI commands per-site, by category, or across all sites.
  • Documentation

    • Updated admin guides with setup steps, usage examples, and configuration templates for the new tools.

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

- Add mainwp-config.json.txt template (fixes #260)
- Add wordpress-sites.json.txt template (fixes #261)
- Add wp-helper.sh script for multi-site WP-CLI operations (fixes #262)
- Update wp-admin.md with setup instructions and wp-helper.sh reference

The wp-helper.sh script reads from ~/.config/aidevops/wordpress-sites.json
and supports multiple hosting types: LocalWP, Hostinger, Hetzner, Cloudways,
Closte, and Cloudron. It can run WP-CLI commands on individual sites,
by category, or on all configured sites.
@gemini-code-assist
Copy link

Summary of Changes

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

This pull request significantly enhances WordPress management capabilities by providing structured configuration templates and a powerful command-line utility. The new templates offer a standardized way to define MainWP and individual WordPress site settings, while the wp-helper.sh script enables efficient execution of WP-CLI commands across diverse hosting environments, either individually, by category, or in bulk. These additions aim to simplify and automate common WordPress administration tasks.

Highlights

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 30, 2026

Warning

Rate limit exceeded

@marcusquinn has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 17 minutes and 43 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

Adds two JSON config templates for MainWP and WordPress sites, a new wp-helper.sh Bash script to run WP‑CLI across configured sites/hosting types, and updates WordPress docs with setup and usage examples. No runtime library/API changes.

Changes

Cohort / File(s) Summary
Configuration Templates
.agent/configs/mainwp-config.json.txt, .agent/configs/wordpress-sites.json.txt
Add JSON template files: MainWP dashboard config and a WordPress sites registry with metadata, hosting-type mappings, site entries, and categories. Templates only; no code behavior changes.
WP-CLI Helper Script
.agent/scripts/wp-helper.sh
Add Bash wp-helper.sh that reads the sites registry, validates dependencies (jq, ssh), lists/filters sites, builds SSH/local commands for multiple hosting types (localwp, hostinger, closte, hetzner, cloudways, cloudron), and executes WP‑CLI per-site/category/all. Includes help, colorized output, and error handling.
Documentation Update
.agent/tools/wordpress/wp-admin.md
Document new templates and wp-helper.sh usage, provide setup instructions and example commands to copy templates into the config path.

Sequence Diagram(s)

sequenceDiagram
  participant User as User
  participant Helper as wp-helper.sh
  participant Config as ~/.config/aidevops/wordpress-sites.json
  participant Remote as Remote Host (SSH / Local)

  User->>Helper: invoke command (--list / <site> <wp-cli> / --all)
  Helper->>Config: read & parse registry
  Helper-->>Helper: select targets (single / category / all)
  Helper->>Remote: run (local exec or SSH + WP‑CLI)
  Remote-->>Helper: return output/status
  Helper-->>User: aggregate & print results
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

✨ Templates land, the helpers hum,
SSH and local tasks now run,
Commands flow out, results come in,
Small files shift—big workflows begin,
Devs sip coffee, smiles slowly win.

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main changes: adding WordPress config templates and the wp-helper.sh script, which are the primary deliverables addressing issues #260, #261, and #262.
Linked Issues check ✅ Passed All coding requirements from issues #260, #261, and #262 are met: mainwp-config.json.txt template with correct schema [#260], wordpress-sites.json.txt template with hosting types and site registry [#261], and wp-helper.sh script with multi-hosting support and bulk operations [#262].
Out of Scope Changes check ✅ Passed All changes are directly aligned with the three linked issues; the documentation update to wp-admin.md is an in-scope supporting change that documents the new templates and script usage.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/fix-wordpress-config-templates-260-261-262

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

�[0;34m[INFO]�[0m Recent monitoring activity:
Fri Jan 30 20:59:30 UTC 2026: Code review monitoring started
Fri Jan 30 20:59:30 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 408
Fri Jan 30 20:59:30 UTC 2026: Qlty - 0 issues found, auto-formatting applied
Fri Jan 30 20:59:32 UTC 2026: Codacy analysis completed with auto-fixes
Fri Jan 30 20:59:33 UTC 2026: Applied 1 automatic fixes

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 408
  • VULNERABILITIES: 0

Generated on: Fri Jan 30 21:00:59 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

Copy link

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

Choose a reason for hiding this comment

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

Code Review

This pull request introduces two new JSON configuration templates for MainWP and WordPress sites, along with a wp-helper.sh script to streamline WP-CLI operations across multiple WordPress installations. The documentation (wp-admin.md) has been updated to reflect these new tools and their usage. The wp-helper.sh script is a valuable addition, offering multi-site WP-CLI capabilities and supporting various hosting types. However, the script contains critical command injection vulnerabilities that must be addressed before merging. Additionally, there are opportunities to improve code clarity and security best practices.

Comment on lines 147 to 148
echo "cd \"$expanded_path\" && wp $wp_command"
;;

Choose a reason for hiding this comment

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

critical

The use of eval echo "$local_path" is a critical command injection vulnerability. If the path value in wordpress-sites.json contains malicious shell commands (e.g., ~/Local Sites/my-site/app/public; rm -rf /), they will be executed on the local machine. It's crucial to avoid eval with untrusted input.

Additionally, the wp_command should be explicitly quoted when passed to wp to prevent shell injection if wp_command itself contains shell metacharacters.

Suggested change
echo "cd \"$expanded_path\" && wp $wp_command"
;;
local expanded_path="${local_path/#\~/$HOME}"
local quoted_local_path
quoted_local_path=$(printf %q "$expanded_path")
echo "cd $quoted_local_path && wp \"$wp_command\""

Comment on lines 150 to 169
# Hostinger/Closte - sshpass with password file
local expanded_password_file
if [[ -n "$password_file" ]]; then
expanded_password_file=$(eval echo "$password_file")
else
# Default password file locations
if [[ "$site_type" == "hostinger" ]]; then
expanded_password_file="${HOME}/.ssh/hostinger_password"
else
expanded_password_file="${HOME}/.ssh/closte_password"
fi
fi

if [[ ! -f "$expanded_password_file" ]]; then
print_error "Password file not found: $expanded_password_file"
print_info "Create the password file with your SSH password"
exit 1
fi

echo "sshpass -f \"$expanded_password_file\" ssh -p $ssh_port $ssh_user@$ssh_host \"cd $wp_path && wp $wp_command\""

Choose a reason for hiding this comment

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

critical

The use of sshpass for Hostinger and Closte sites, while functional, is generally discouraged due to security concerns. Passwords can be exposed in memory or in process lists, making them vulnerable. SSH key-based authentication is a more secure alternative. If sshpass is absolutely necessary due to hosting provider limitations, ensure the password files have strict permissions (e.g., chmod 600).

Furthermore, there is a critical command injection vulnerability here. The wp_path and wp_command are directly interpolated into the remote SSH command string without proper quoting for the remote shell. This allows for arbitrary command execution on the remote server if these values in wordpress-sites.json or the CLI arguments contain shell metacharacters.

            # Hostinger/Closte - sshpass with password file
            local expanded_password_file
            if [[ -n "$password_file" ]]; then
                expanded_password_file=$(eval echo "$password_file")
            else
                # Default password file locations
                if [[ "$site_type" == "hostinger" ]]; then
                    expanded_password_file="${HOME}/.ssh/hostinger_password"
                else
                    expanded_password_file="${HOME}/.ssh/closte_password"
                fi
            fi
            
            if [[ ! -f "$expanded_password_file" ]]; then
                print_error "Password file not found: $expanded_password_file"
                print_info "Create the password file with your SSH password"
                exit 1
            fi
            
            local quoted_wp_path
            quoted_wp_path=$(printf %q "$wp_path")
            echo "sshpass -f \"$expanded_password_file\" ssh -p $ssh_port $ssh_user@$ssh_host \"cd $quoted_wp_path && wp \\\"$wp_command\\\"\""

;;
hetzner|cloudways|cloudron)
# SSH key-based authentication
echo "ssh -p $ssh_port $ssh_user@$ssh_host \"cd $wp_path && wp $wp_command\""

Choose a reason for hiding this comment

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

critical

Similar to the hostinger|closte case, there is a critical command injection vulnerability here. The wp_path and wp_command are directly interpolated into the remote SSH command string without proper quoting for the remote shell. This allows for arbitrary command execution on the remote server if these values in wordpress-sites.json or the CLI arguments contain shell metacharacters.

Suggested change
echo "ssh -p $ssh_port $ssh_user@$ssh_host \"cd $wp_path && wp $wp_command\""
local quoted_wp_path
quoted_wp_path=$(printf %q "$wp_path")
echo "ssh -p $ssh_port $ssh_user@$ssh_host \"cd $quoted_wp_path && wp \\\"$wp_command\\\"\""

@@ -0,0 +1,445 @@
#!/bin/bash
# shellcheck disable=SC2034,SC2155

Choose a reason for hiding this comment

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

medium

The shellcheck disable=SC2034 directive is used, but the HELP_SHOW_MESSAGE variable (line 25) is indeed unused. It's better to remove unused variables to keep the code clean and avoid unnecessary disables, or ensure they are used if intended.

Suggested change
# shellcheck disable=SC2034,SC2155
#!/bin/bash
# shellcheck disable=SC2155

readonly ERROR_SITE_NOT_FOUND="Site not found in configuration"
readonly ERROR_SITE_REQUIRED="Site identifier is required"
readonly ERROR_COMMAND_REQUIRED="WP-CLI command is required"
readonly HELP_SHOW_MESSAGE="Show this help"

Choose a reason for hiding this comment

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

medium

The HELP_SHOW_MESSAGE variable is defined but not used anywhere in the script. It should be removed to avoid dead code and improve maintainability.

@augmentcode
Copy link

augmentcode bot commented Jan 30, 2026

🤖 Augment PR Summary

Summary: This PR adds WordPress admin configuration templates and a multi-site WP-CLI helper script to simplify repeated maintenance tasks across multiple WordPress installs.

Changes:

  • Added .agent/configs/mainwp-config.json.txt as a committed template for MainWP API credentials/instances.
  • Added .agent/configs/wordpress-sites.json.txt as a committed registry template for local + SSH-hosted WordPress sites and categories.
  • Introduced .agent/scripts/wp-helper.sh to run WP-CLI commands against a single site, a category of sites, or all sites using the JSON registry.
  • Supported hosting modes include LocalWP (local path), sshpass-based SSH (Hostinger/Closte), and key-based SSH (Hetzner/Cloudways/Cloudron).
  • Updated .agent/tools/wordpress/wp-admin.md with setup instructions and quick usage examples for wp-helper.sh.

Technical Notes: The helper script reads ~/.config/aidevops/wordpress-sites.json, builds the appropriate local/SSH command per site type, and provides bulk execution modes with per-site success/failure reporting.

🤖 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. 5 suggestions posted.

Fix All in Augment

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

localwp)
# LocalWP - direct local access
local expanded_path
expanded_path=$(eval echo "$local_path")
Copy link

Choose a reason for hiding this comment

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

eval is used to expand values sourced from wordpress-sites.json (e.g., path/password_file), which can execute arbitrary shell code if those fields contain substitutions; this is a risky footgun even for local tooling.

Other Locations
  • .agent/scripts/wp-helper.sh:153
  • .agent/scripts/wp-helper.sh:208

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

run_wp_command() {
local site_key="$1"
shift
local wp_command="$*"
Copy link

Choose a reason for hiding this comment

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

local wp_command="$*" collapses the original argument boundaries, so WP-CLI args containing spaces/quotes can’t be passed reliably and the invoked command may differ from what the user typed.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

}

# Check dependencies
check_dependencies() {
Copy link

Choose a reason for hiding this comment

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

check_dependencies validates jq only, but this script also relies on ssh and (for hostinger|closte) sshpass; missing those will fail later in a less user-friendly way.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

exit 1
fi

echo "sshpass -f \"$expanded_password_file\" ssh -p $ssh_port $ssh_user@$ssh_host \"cd $wp_path && wp $wp_command\""
Copy link

Choose a reason for hiding this comment

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

For SSH-based site types, there’s no validation that required fields like ssh_host, ssh_user, and wp_path are present; if any are empty, the constructed ssh ... "cd ..." command will be malformed or run in an unexpected directory.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

print_info "Available categories:"
jq -r '.sites[].category // "uncategorized"' "$CONFIG_FILE" | sort -u | while read -r cat; do
local count
count=$(jq -r "[.sites[] | select(.category == \"$cat\")] | length" "$CONFIG_FILE")
Copy link

Choose a reason for hiding this comment

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

list_categories derives "uncategorized" for missing categories, but the count query only selects .category == "uncategorized" (not missing/null), so the displayed count for uncategorized sites will be incorrect.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

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 @.agent/scripts/wp-helper.sh:
- Around line 237-248: The post-increment arithmetic ((success_count++)) and
((fail_count++)) can return 0 and trigger a set -e exit; change these to use
pre-increment or explicit addition so the expression returns a non-zero
value—e.g., replace ((success_count++)) with ((++success_count)) or
((success_count+=1)) and do the same for fail_count; also apply the identical
fix to the increments inside the run_on_all loop (the other occurrence
referenced) so both success_count and fail_count updates never evaluate to zero.
🧹 Nitpick comments (3)
.agent/scripts/wp-helper.sh (2)

84-86: Consider using jq's --arg for safer variable interpolation.

Embedding shell variables directly in jq filters (e.g., .sites.\"$site_key\") can behave unexpectedly if the variable contains special characters. While this is a local CLI tool with limited attack surface, using --arg is more robust.

♻️ Safer jq pattern
-    site_config=$(jq -r ".sites.\"$site_key\"" "$CONFIG_FILE")
+    site_config=$(jq -r --arg key "$site_key" '.sites[$key]' "$CONFIG_FILE")

Similar changes would apply to lines 101, 115, 230, 273, 311, and 313.


144-147: Consider safer tilde expansion without eval.

Using eval echo for tilde expansion works but can be risky if the path contains unexpected shell metacharacters. A safer alternative is parameter expansion.

♻️ Safer tilde expansion
-            local expanded_path
-            expanded_path=$(eval echo "$local_path")
+            local expanded_path="${local_path/#\~/$HOME}"

Apply similarly to line 153 for password_file expansion.

.agent/configs/mainwp-config.json.txt (1)

4-4: Setup instruction could include the full destination path.

For consistency with the wordpress-sites.json.txt template and to provide clearer guidance, consider specifying the full path in the _setup field.

📝 Suggested improvement
-  "_setup": "Copy to mainwp-config.json and fill in your credentials",
+  "_setup": "Copy to ~/.config/aidevops/mainwp-config.json and fill in your credentials (chmod 600)",

Based on learnings: "Store Service Configurations in ~/Git/aidevops/configs/[service]-config.json with file permissions set to 600"

- Remove eval usage to prevent command injection
- Use safe tilde expansion with parameter substitution
- Quote paths with printf %q for safe shell execution
- Remove unused HELP_SHOW_MESSAGE constant
- Add note about sshpass security and chmod 600 recommendation

Addresses CodeRabbit security review feedback.
@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, 408 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Fri Jan 30 21:03:35 UTC 2026: Code review monitoring started
Fri Jan 30 21:03:36 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 408
Fri Jan 30 21:03:36 UTC 2026: Qlty - 0 issues found, auto-formatting applied
Fri Jan 30 21:03:38 UTC 2026: Codacy analysis completed with auto-fixes
Fri Jan 30 21:03:39 UTC 2026: Applied 1 automatic fixes

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 408
  • VULNERABILITIES: 0

Generated on: Fri Jan 30 21:05:04 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 @.agent/scripts/wp-helper.sh:
- Around line 218-220: The eval "$ssh_command" call still allows command
injection; replace it by building the SSH invocation as a Bash array and
executing it without eval (e.g., construct ssh_command as an array variable and
run it as "${ssh_command[@]}"), and ensure the wp_command pieces are properly
escaped or passed as separate array elements instead of interpolating into a
single string; update any code that sets ssh_command or wp_command so they push
safe, quoted tokens into the array rather than concatenating raw strings.
- Around line 121-192: The build_ssh_command function embeds the unescaped
parameter wp_command directly into constructed shell strings (used later with
eval), creating a command injection risk; fix by shell-quoting/escaping
wp_command the same way paths are handled (use printf %q "$wp_command" and
reference the resulting variable) in every branch that constructs a command
(localwp, hostinger|closte, hetzner|cloudways|cloudron) so the echoed strings
use the quoted wp_command variable rather than raw $wp_command.
🧹 Nitpick comments (4)
.agent/scripts/wp-helper.sh (4)

78-89: Use jq --arg to safely pass user-provided site keys.

The current jq query interpolates $site_key directly into the filter string. If a site key contains characters like " or \, the query could malfunction or produce unexpected results. Using --arg is the robust approach for passing external variables to jq.

♻️ Proposed fix using --arg for safe variable passing
     local site_config
-    site_config=$(jq -r ".sites.\"$site_key\"" "$CONFIG_FILE")
+    site_config=$(jq -r --arg key "$site_key" '.sites[$key]' "$CONFIG_FILE")
     if [[ "$site_config" == "null" ]]; then

107-119: Apply --arg pattern for category filtering as well.

Similar to the site key issue, the $category variable is interpolated directly into the jq filter at line 114. For consistency and robustness, use --arg.

♻️ Proposed fix
-    jq -r ".sites | to_entries[] | select(.value.category == \"$category\") | \"\(.key)|\(.value.name)|\(.value.type)|\(.value.url // .value.path)\"" "$CONFIG_FILE" | \
+    jq -r --arg cat "$category" '.sites | to_entries[] | select(.value.category == $cat) | "\(.key)|\(.value.name)|\(.value.type)|\(.value.url // .value.path)"' "$CONFIG_FILE" | \

240-241: Apply --arg pattern for category in jq query.

♻️ Proposed fix
     local site_keys
-    site_keys=$(jq -r ".sites | to_entries[] | select(.value.category == \"$category\") | .key" "$CONFIG_FILE")
+    site_keys=$(jq -r --arg cat "$category" '.sites | to_entries[] | select(.value.category == $cat) | .key' "$CONFIG_FILE")

318-328: Apply --arg in list_categories count query.

Line 324 interpolates $cat into the jq filter. Use --arg for consistency.

♻️ Proposed fix
     jq -r '.sites[].category // "uncategorized"' "$CONFIG_FILE" | sort -u | while read -r cat; do
         local count
-        count=$(jq -r "[.sites[] | select(.category == \"$cat\")] | length" "$CONFIG_FILE")
+        count=$(jq -r --arg c "$cat" '[.sites[] | select(.category == $c)] | length' "$CONFIG_FILE")
         echo "  - $cat ($count sites)"
     done

Comment on lines +218 to +220
# Execute the command
eval "$ssh_command"
return $?
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 | 🟠 Major

eval usage persists despite commit message claiming removal.

The commit messages summary states "removed use of eval to prevent command injection," but eval "$ssh_command" remains at line 219. Combined with the unescaped wp_command noted above, this creates the injection pathway.

Consider refactoring to avoid eval entirely by using Bash arrays for command construction, or at minimum ensure all interpolated values are properly escaped before the eval.

🤖 Prompt for AI Agents
In @.agent/scripts/wp-helper.sh around lines 218 - 220, The eval "$ssh_command"
call still allows command injection; replace it by building the SSH invocation
as a Bash array and executing it without eval (e.g., construct ssh_command as an
array variable and run it as "${ssh_command[@]}"), and ensure the wp_command
pieces are properly escaped or passed as separate array elements instead of
interpolating into a single string; update any code that sets ssh_command or
wp_command so they push safe, quoted tokens into the array rather than
concatenating raw strings.

- Use pre-increment ((++count)) to avoid set -e exit on zero
- Add sshpass dependency check for Hostinger/Closte sites
- Add ssh dependency check
- Use jq --arg for safer variable interpolation
- Fix uncategorized count in list_categories

Addresses CodeRabbit and Augment review feedback.
@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, 408 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Fri Jan 30 21:08:13 UTC 2026: Code review monitoring started
Fri Jan 30 21:08:13 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 408
Fri Jan 30 21:08:13 UTC 2026: Qlty - 0 issues found, auto-formatting applied
Fri Jan 30 21:08:15 UTC 2026: Codacy analysis completed with auto-fixes
Fri Jan 30 21:08:17 UTC 2026: Applied 1 automatic fixes

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 408
  • VULNERABILITIES: 0

Generated on: Fri Jan 30 21:09:42 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

- Add printf %q quoting for wp_command in build_ssh_command
- Apply to all hosting types (localwp, hostinger, closte, hetzner, cloudways, cloudron)

Addresses final CodeRabbit security feedback.
@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, 408 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Fri Jan 30 21:11:23 UTC 2026: Code review monitoring started
Fri Jan 30 21:11:24 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 408
Fri Jan 30 21:11:24 UTC 2026: Qlty - 0 issues found, auto-formatting applied
Fri Jan 30 21:11:26 UTC 2026: Codacy analysis completed with auto-fixes
Fri Jan 30 21:11:27 UTC 2026: Applied 1 automatic fixes

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 408
  • VULNERABILITIES: 0

Generated on: Fri Jan 30 21:12:54 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@marcusquinn marcusquinn merged commit f7b0f15 into main Jan 30, 2026
9 checks passed
@marcusquinn marcusquinn deleted the feature/fix-wordpress-config-templates-260-261-262 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

1 participant