# External WP-CLI Testing Setup Guide

Complete step-by-step guide to set up External WP-CLI Testing for PluginCompass. This system uses an externally hosted WordPress **Multisite** installation with WP-CLI to verify plugin functionality in isolated subsite environments, supporting 20+ concurrent tests.

---

## Table of Contents

1. [Overview](#overview)
2. [Architecture](#architecture)
3. [Prerequisites](#prerequisites)
4. [Part 1: Setting Up WordPress Multisite](#part-1-setting-up-wordpress-multisite)
5. [Part 2: Installing and Configuring WP-CLI](#part-2-installing-and-configuring-wp-cli)
6. [Part 3: Configuring SSH Access](#part-3-configuring-ssh-access)
7. [Part 4: Configuring Environment Variables](#part-4-configuring-environment-variables)
8. [Part 5: Testing the Connection](#part-5-testing-the-connection)
9. [Part 6: Enabling in Builder](#part-6-enabling-in-builder)
10. [Part 7: Using the Tools](#part-7-using-the-tools)
11. [Troubleshooting](#troubleshooting)

---

## Overview

### What This System Does

- **Isolated Testing**: Each test session runs in its own WordPress subsite (no cross-contamination)
- **High Concurrency**: Supports 20+ simultaneous tests via multisite subsites
- **Automated Provisioning**: Automatically creates/deletes test subsites
- **CLI Testing Mode**: Fast, deterministic WP-CLI based verification
- **Gated Tools**: Tools only load in OpenCode when Builder toggle is enabled

### Architecture Diagram

```
┌─────────────────────────────────────────────────────────────────┐
│               PluginCompass Chat Server (Your Server)          │
│  - Runs Node.js chat app                                       │
│  - Spawns OpenCode with env vars when toggle enabled           │
└─────────────────────────────────────────────────────────────────┘
                              │ SSH + WP-CLI commands
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│          External WordPress Multisite Test Server               │
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐            │
│  │  Session 1   │ │  Session 2   │ │  Session N   │            │
│  │  Subsite     │ │  Subsite     │ │  Subsite     │            │
│  │  /test-abc   │ │  /test-def   │ │  /test-xyz   │            │
│  └──────────────┘ └──────────────┘ └──────────────┘            │
│                                                                 │
│  Shared: Core WP, WP-CLI (isolated content/options per subsite)│
└─────────────────────────────────────────────────────────────────┘
```

### How It Works

1. User enables "External WP CLI testing" toggle in Builder
2. Chat server sets `OPENCODE_EXTRA_MCP_SERVERS` env var when spawning OpenCode
3. OpenCode loads the `wp-cli-testing` MCP server with tools:
   - `test_plugin_external_wp` - Runs tests on external WP
   - `external_wp_testing_config` - Validates configuration
4. When AI calls the tool:
   - SSH connection established to WordPress server
   - New subsite created via WP-CLI (`wp site create`)
   - Plugin uploaded and activated
   - Test scenarios executed via WP-CLI
   - Results returned to AI
   - Subsite cleaned up after delay

---

## Prerequisites

### Required Infrastructure

1. **A Linux server** (Ubuntu 20.04+ or Debian 11+ recommended)
   - Minimum: 2GB RAM, 20GB disk, 2 CPU cores
   - Recommended for production: 4GB RAM, 50GB disk, 4 CPU cores
2. **SSH access** with sudo privileges
3. **Domain or subdomain** pointing to the server
4. **LAMP/LEMP stack** installed (Linux, Apache/Nginx, MySQL, PHP)

### Software Requirements

- **PHP 7.4+** (PHP 8.0+ recommended)
- **MySQL 5.7+** or **MariaDB 10.3+**
- **WP-CLI** 2.6+ 
- **WordPress 6.0+**
- **SSH server** (OpenSSH)

---

## Part 1: Setting Up WordPress Multisite

### Step 1.1: Install Base WordPress

If you don't have WordPress installed yet:

```bash
# SSH into your test server
ssh user@wp-test.example.com

# Navigate to web root
cd /var/www/html

# Download WordPress
sudo wget https://wordpress.org/latest.tar.gz
sudo tar -xzf latest.tar.gz
sudo mv wordpress/* .
sudo rm -rf wordpress latest.tar.gz

# Set permissions
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html

# Create database
sudo mysql -u root -p
```

In MySQL:
```sql
CREATE DATABASE wordpress_test DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'strong_password_here';
GRANT ALL PRIVILEGES ON wordpress_test.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
```

Complete WordPress installation via browser at `http://your-domain.com/wp-admin/install.php`

### Step 1.2: Enable WordPress Multisite

**Important**: Backup your site before enabling multisite.

```bash
# SSH into server
ssh user@wp-test.example.com

# Edit wp-config.php
sudo nano /var/www/html/wp-config.php
```

Add these lines **before** `/* That's all, stop editing! */`:

```php
/* Multisite */
define('WP_ALLOW_MULTISITE', true);
```

Save and exit (`Ctrl+X`, `Y`, `Enter`).

### Step 1.3: Run Multisite Setup

1. Go to `http://your-domain.com/wp-admin/network-setup.php` in your browser
2. Choose **Subdirectories** (recommended for easier setup)
3. Fill in:
   - **Network Title**: `PluginCompass Test Network`
   - **Admin Email**: Your email
4. Click **Install**

### Step 1.4: Complete Network Configuration

WordPress will show you code to add. Follow these steps:

**A. Update wp-config.php:**

```bash
sudo nano /var/www/html/wp-config.php
```

Add the provided multisite configuration (it will look like this):

```php
define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', false);
define('DOMAIN_CURRENT_SITE', 'wp-test.example.com');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);
```

**B. Update .htaccess:**

```bash
sudo nano /var/www/html/.htaccess
```

Replace contents with the provided rewrite rules (similar to):

```apache
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]
```

**C. Set Permissions:**

```bash
sudo chown www-data:www-data /var/www/html/.htaccess
sudo chmod 644 /var/www/html/.htaccess
```

### Step 1.5: Verify Multisite Installation

1. Log out and log back in to WordPress admin
2. You should now see **"My Sites"** in the admin bar
3. Navigate to **Network Admin → Sites** to see your network

**Test subsite creation manually:**

```bash
# You'll configure WP-CLI next, but this is the command pattern we'll use
wp site create --slug=test-manual --title="Test Site" --email="admin@example.com"
```

---

## Part 2: Installing and Configuring WP-CLI

### Step 2.1: Install WP-CLI

```bash
# SSH into server
ssh user@wp-test.example.com

# Download WP-CLI
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar

# Test it works
php wp-cli.phar --info

# Make it executable and move to system path
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

# Verify installation
wp --info
```

Expected output:
```
OS:     Linux 5.4.0-100-generic #113-Ubuntu SMP ...
Shell:  /bin/bash
PHP binary:     /usr/bin/php7.4
PHP version:    7.4.28
php.ini used:   /etc/php/7.4/cli/php.ini
MySQL binary:   /usr/bin/mysql
MySQL version:  mysql  Ver 15.1 Distrib 10.3.32-MariaDB
SQL modes:
WP-CLI root dir:        phar://wp-cli.phar/vendor/wp-cli/wp-cli
WP-CLI vendor dir:      phar://wp-cli.phar/vendor
WP_CLI phar path:       /home/user
WP-CLI packages dir:
WP-CLI global config:
WP-CLI project config:
WP-CLI version: 2.8.1
```

### Step 2.2: Configure WP-CLI for Web Server User

The chat server will run WP-CLI commands as the SSH user. We need to ensure it works:

```bash
# Test basic WP-CLI command
cd /var/www/html
wp --path=/var/www/html option get siteurl

# If you get permission errors, fix ownership
sudo chown -R www-data:www-data /var/www/html

# Add your SSH user to www-data group (replace 'wordpress' with your username)
sudo usermod -a -G www-data wordpress

# Set proper directory permissions
sudo find /var/www/html -type d -exec chmod 755 {} \;
sudo find /var/www/html -type f -exec chmod 644 {} \;

# Log out and back in for group changes to take effect
exit
ssh user@wp-test.example.com
```

### Step 2.3: Test Multisite Operations with WP-CLI

```bash
cd /var/www/html

# Test creating a subsite
wp site create --slug=test-cli-check --title="Test Subsite" --email="admin@example.com"

# Verify it was created
wp site list

# Test plugin operations on the subsite
wp --url=https://wp-test.example.com/test-cli-check plugin list

# Delete the test subsite
wp site delete --slug=test-cli-check --yes

# Confirm deletion
wp site list
```

If all commands succeed, WP-CLI is configured correctly.

---

## Part 3: Configuring SSH Access

### Step 3.1: Create SSH User for Testing

For security, create a dedicated user for the testing system:

```bash
# On the WordPress test server
sudo adduser wordpress
# Set a strong password when prompted

# Add to www-data group for file access
sudo usermod -a -G www-data wordpress

# Grant sudo privileges for WP-CLI (if needed)
sudo usermod -a -G sudo wordpress
```

**Alternative:** Use an existing user with appropriate permissions.

### Step 3.2: Generate SSH Key Pair

On your **PluginCompass chat server** (not the WordPress server):

```bash
# Generate SSH key pair
ssh-keygen -t ed25519 -C "plugincompass-wp-testing" -f ~/.ssh/wp-test-key

# This creates:
# - ~/.ssh/wp-test-key (private key - KEEP SECRET)
# - ~/.ssh/wp-test-key.pub (public key - safe to share)

# Set correct permissions
chmod 600 ~/.ssh/wp-test-key
chmod 644 ~/.ssh/wp-test-key.pub

# Display the public key (you'll need this for the next step)
cat ~/.ssh/wp-test-key.pub
```

**On Windows:**

```powershell
# Using PowerShell
ssh-keygen -t ed25519 -C "plugincompass-wp-testing" -f C:\keys\wp-test-key

# Set permissions
icacls "C:\keys\wp-test-key" /inheritance:r
icacls "C:\keys\wp-test-key" /grant:r "%USERNAME%:F"

# Display public key
type C:\keys\wp-test-key.pub
```

### Step 3.3: Install Public Key on WordPress Server

Copy the public key content, then on the **WordPress server**:

```bash
# Switch to the wordpress user (or your SSH user)
sudo su - wordpress

# Create .ssh directory if it doesn't exist
mkdir -p ~/.ssh
chmod 700 ~/.ssh

# Add the public key
nano ~/.ssh/authorized_keys

# Paste the public key (from wp-test-key.pub)
# Save and exit (Ctrl+X, Y, Enter)

# Set correct permissions
chmod 600 ~/.ssh/authorized_keys

# Exit back to your original user
exit
```

### Step 3.4: Test SSH Connection

From your **PluginCompass chat server**:

```bash
# Test SSH connection with the key
ssh -i ~/.ssh/wp-test-key wordpress@wp-test.example.com

# If successful, you should be logged in without a password
# Test WP-CLI works over SSH
cd /var/www/html && wp site list

# Exit
exit
```

**On Windows:**

```powershell
ssh -i C:\keys\wp-test-key wordpress@wp-test.example.com
```

### Step 3.5: Disable Strict Host Key Checking (Optional, for Testing)

For automated testing, you may want to disable strict host key checking:

On your **PluginCompass chat server**, create/edit SSH config:

```bash
nano ~/.ssh/config
```

Add:

```
Host wp-test.example.com
    HostName wp-test.example.com
    User wordpress
    IdentityFile ~/.ssh/wp-test-key
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null
```

**Security Note:** Only do this on trusted networks. For production, keep strict checking enabled and add the host to known_hosts properly.

---

## Part 4: Configuring Environment Variables

### Step 4.1: Locate Your Environment Configuration

Environment variables should be set where your **chat server** runs. Options:

**A. Using .env file (development):**

```bash
# In your chat server directory
nano .env
```

**B. Using systemd service (production):**

```bash
sudo nano /etc/systemd/system/plugincompass-chat.service
```

Add under `[Service]` section:
```
Environment="TEST_WP_HOST=wp-test.example.com"
Environment="TEST_WP_SSH_USER=wordpress"
...
```

**C. Using PM2 ecosystem file:**

```bash
nano ecosystem.config.js
```

Add to `env`:
```javascript
env: {
  TEST_WP_HOST: 'wp-test.example.com',
  TEST_WP_SSH_USER: 'wordpress',
  ...
}
```

### Step 4.2: Required Environment Variables

Add these variables (adjust paths for your setup):

```bash
# Core Connection Settings
TEST_WP_HOST=wp-test.example.com
TEST_WP_SSH_USER=wordpress
TEST_WP_SSH_KEY=/home/user/.ssh/wp-test-key
TEST_WP_PATH=/var/www/html

# Base URL (must match your WordPress installation)
TEST_WP_BASE_URL=https://wp-test.example.com

# Multisite Configuration
TEST_WP_MULTISITE=true
TEST_WP_SUBSITE_MODE=subdirectory
TEST_WP_SUBSITE_PREFIX=test
TEST_WP_SUBSITE_DOMAIN=wp-test.example.com

# Testing Configuration
TEST_MAX_CONCURRENT=20
TEST_TIMEOUT=600000
TEST_QUEUE_TIMEOUT=300000

# Cleanup Settings
TEST_AUTO_CLEANUP=true
TEST_CLEANUP_DELAY=3600000

# Error Logging (adjust to your log location)
TEST_WP_ERROR_LOG=/var/log/wp-errors.log

# SSH Settings
TEST_SSH_STRICT=false
```

**Windows paths example:**

```bash
TEST_WP_SSH_KEY=C:\\keys\\wp-test-key
```

### Step 4.3: Alternative Environment Variable Names

The system supports alternative names (useful if you have existing vars):

- `TEST_WP_HOST` or `EXTERNAL_WP_HOST`
- `TEST_WP_SSH_USER` or `EXTERNAL_WP_SSH_USER`
- `TEST_WP_SSH_KEY` or `EXTERNAL_WP_SSH_KEY` or `TEST_WP_SSH_KEY_PATH`
- `TEST_WP_PATH` or `EXTERNAL_WP_PATH`
- `TEST_WP_BASE_URL` or `EXTERNAL_WP_BASE_URL`
- etc.

### Step 4.4: Apply Environment Variables

**If using .env:**
```bash
# Restart your chat server
npm run restart
# or
pm2 restart chat-server
```

**If using systemd:**
```bash
sudo systemctl daemon-reload
sudo systemctl restart plugincompass-chat
```

---

## Part 5: Testing the Connection

### Step 5.1: Verify Environment Variables

Check that variables are loaded:

```bash
# If using Node.js directly
node -e "console.log(process.env.TEST_WP_HOST)"
# Should output: wp-test.example.com

# If using PM2
pm2 env 0 | grep TEST_WP
```

### Step 5.2: Test SSH Connection from Chat Server

From your chat server, verify SSH works:

```bash
ssh -i $TEST_WP_SSH_KEY $TEST_WP_SSH_USER@$TEST_WP_HOST "wp site list"
```

Expected output: List of sites in your multisite network.

### Step 5.3: Test Direct Tool Invocation

Create a test script to verify the external-wp-testing module:

```javascript
// test-wp-connection.js
const { createExternalWpTester, getExternalTestingConfig } = require('./chat/external-wp-testing.js');

async function test() {
  // 1. Check config
  console.log('1. Checking configuration...');
  const config = getExternalTestingConfig();
  console.log('Config:', JSON.stringify(config, null, 2));
  
  const missing = [];
  if (!config.wpHost) missing.push('TEST_WP_HOST');
  if (!config.wpSshUser) missing.push('TEST_WP_SSH_USER');
  if (!config.wpSshKey) missing.push('TEST_WP_SSH_KEY');
  
  if (missing.length > 0) {
    console.error('❌ Missing required environment variables:', missing);
    process.exit(1);
  }
  
  console.log('✅ Configuration valid\n');
  
  // 2. Test connection by running a simple WP-CLI command
  console.log('2. Testing SSH + WP-CLI connection...');
  const tester = createExternalWpTester({});
  
  // This would normally upload a plugin, but we'll just test the infrastructure
  console.log('Configuration loaded successfully. SSH credentials are set.');
  console.log('✅ Ready for testing\n');
}

test().catch(console.error);
```

Run it:

```bash
node test-wp-connection.js
```

### Step 5.4: Test Subsite Creation (Manual)

SSH into your WordPress server and manually test the subsite flow:

```bash
ssh -i ~/.ssh/wp-test-key wordpress@wp-test.example.com

cd /var/www/html

# Create test subsite
wp site create --slug=test-manual-abc --title="Manual Test" --email="admin@example.com"

# Verify it exists
wp site list | grep test-manual-abc

# Check URL is accessible
curl -I https://wp-test.example.com/test-manual-abc/

# Clean up
wp site delete --slug=test-manual-abc --yes

exit
```

If all steps succeed, your infrastructure is ready!

---

## Part 6: Enabling in Builder

### Step 6.1: Access Builder Settings

1. Open PluginCompass Builder in your browser
2. Look for the **"External WP CLI testing"** toggle
3. It may show usage information (e.g., "0 / 10 tests used")

### Step 6.2: Enable the Toggle

1. Click the toggle to enable it
2. You may see a confirmation: "External WP tests run a series of WP-CLI checks on an external WordPress site. Tests are counted against your monthly allowance."
3. Click **OK** or **Confirm**

### Step 6.3: Verify Toggle State

The toggle should:
- Show as **ON/enabled** (blue/green indicator)
- Display current usage stats
- Be persistent across page refreshes

**Behind the scenes**: When enabled:
- `builderState.externalTestingEnabled = true`
- When a message is sent, `externalTestingEnabled: true` is included in the payload
- Chat server sets `OPENCODE_EXTRA_MCP_SERVERS` env var when spawning OpenCode
- OpenCode loads the `wp-cli-testing` MCP server
- Tools `test_plugin_external_wp` and `external_wp_testing_config` become available to AI

**When disabled**: Tools are NOT loaded into OpenCode (gated at the environment variable level).

---

## Part 7: Using the Tools

### How Tests Work

1. **User Request**: User asks AI to create a plugin in Builder
2. **AI Generates Code**: AI creates plugin files in the workspace
3. **AI Calls Test Tool**: AI invokes `test_plugin_external_wp` with plugin path
4. **Automated Flow**:
   - Subsite created: `wp site create --slug=test-<sessionid>`
   - Plugin uploaded via SSH/SFTP
   - Plugin activated: `wp plugin activate <plugin-slug>`
   - Test scenarios executed via WP-CLI
   - Results returned to AI
   - Subsite scheduled for cleanup (after 1 hour by default)

### Tool 1: test_plugin_external_wp

**Purpose**: Run automated CLI tests on a real WordPress installation

**Example AI Usage**:

```javascript
{
  "plugin_path": "/workspace/session-abc/my-custom-plugin",
  "plugin_slug": "my-custom-plugin",
  "test_mode": "cli",
  "required_plugins": [
    {
      "plugin_slug": "woocommerce",
      "activate": true
    }
  ],
  "test_scenarios": [
    {
      "name": "Plugin activates without errors",
      "type": "custom",
      "wp_cli_command": "plugin activate my-custom-plugin",
      "assertions": {
        "wp_cli_success": true,
        "not_contains": ["Fatal error", "Parse error"]
      }
    },
    {
      "name": "Custom endpoint responds",
      "type": "endpoint",
      "url": "/custom-endpoint",
      "assertions": {
        "status_code": 200,
        "contains": ["success"]
      }
    }
  ]
}
```

**Return Value**:

```json
{
  "ok": true,
  "session_id": "abc123",
  "subsite_url": "https://wp-test.example.com/test-abc123",
  "test_results": {
    "mode": "cli",
    "cli_tests": {
      "passed": 2,
      "failed": 0,
      "results": [
        {
          "name": "Plugin activates without errors",
          "status": "passed",
          "command": "wp plugin activate my-custom-plugin",
          "output": "Success: Activated 1 of 1 plugins.",
          "duration": 1234
        }
      ]
    }
  },
  "installed_plugins": [
    { "slug": "woocommerce", "status": "active" },
    { "slug": "my-custom-plugin", "status": "active" }
  ],
  "errors": [],
  "warnings": [],
  "duration": 15230,
  "cleanup_scheduled": "2026-02-08T11:30:00Z"
}
```

### Tool 2: external_wp_testing_config

**Purpose**: Validate configuration without running tests

**Example AI Usage**:

```javascript
{}
// or
{ "config_overrides": {} }
```

**Return Value**:

```json
{
  "ok": true,
  "missing": [],
  "config": {
    "wpHost": "wp-test.example.com",
    "wpSshUser": "wordpress",
    "wpSshKey": "/home/user/.ssh/wp-test-key",
    "wpPath": "/var/www/html",
    "wpBaseUrl": "https://wp-test.example.com",
    "enableMultisite": true,
    "subsiteMode": "subdirectory",
    "subsitePrefix": "test",
    "maxConcurrentTests": 20
  }
}
```

**If configuration is invalid**:

```json
{
  "ok": false,
  "missing": ["TEST_WP_HOST", "TEST_WP_SSH_KEY"],
  "config": { ... }
}
```

### Default Test Scenarios

If `test_scenarios` is not provided, the system generates default tests:

1. **Plugin Activation Test**
   - Command: `wp plugin activate <plugin-slug>`
   - Asserts: No fatal errors, no parse errors

2. **Plugin Status Check**
   - Command: `wp plugin status <plugin-slug>`
   - Asserts: Plugin listed as "Active"

3. **Error Log Scan**
   - Command: `tail -n 200 /var/log/wp-errors.log | grep <plugin-slug>`
   - Asserts: No fatal/parse errors related to plugin

### Example Builder Workflow

1. User: "Create a plugin that adds a custom /vendor-login endpoint"
2. AI generates plugin code
3. Builder shows "Proceed with Build" button
4. User clicks → AI calls OpenCode
5. OpenCode processes build, then:
   ```javascript
   // AI calls test tool
   test_plugin_external_wp({
     plugin_path: "/workspace/vendor-login-plugin",
     plugin_slug: "vendor-login",
     test_scenarios: [
       {
         name: "Login endpoint accessible",
         type: "endpoint",
         url: "/vendor-login",
         assertions: {
           status_code: 200,
           contains: ["<form", "name=\"log\""]
         }
       }
     ]
   })
   ```
6. Results shown to user:
   ```
   ✅ External WP CLI Testing
   Status: Passed
   CLI Tests: 3 passed, 0 failed
   Subsite: https://wp-test.example.com/test-a3f7d2
   ```

---

## Troubleshooting

### Issue: "SSH key not found"

**Error**: `External WordPress test host SSH key is missing or invalid`

**Solutions**:
1. Check environment variable path:
   ```bash
   echo $TEST_WP_SSH_KEY
   ls -la $TEST_WP_SSH_KEY
   ```
2. Ensure file permissions:
   ```bash
   chmod 600 ~/.ssh/wp-test-key
   ```
3. Use absolute path in env var (not `~`)

### Issue: "Permission denied (publickey)"

**Error**: SSH connection fails

**Solutions**:
1. Verify public key is in `authorized_keys`:
   ```bash
   ssh wordpress@wp-test.example.com
   cat ~/.ssh/authorized_keys | grep "plugincompass"
   ```
2. Check SSH key permissions on client:
   ```bash
   ls -la ~/.ssh/wp-test-key
   # Should show: -rw------- (600)
   ```
3. Test connection manually:
   ```bash
   ssh -i ~/.ssh/wp-test-key -v wordpress@wp-test.example.com
   # -v flag shows verbose debug info
   ```

### Issue: "WP-CLI command not found"

**Error**: `wp: command not found` over SSH

**Solutions**:
1. Verify WP-CLI installed:
   ```bash
   ssh wordpress@wp-test.example.com "which wp"
   # Should output: /usr/local/bin/wp
   ```
2. Add to PATH in .bashrc:
   ```bash
   echo 'export PATH=$PATH:/usr/local/bin' >> ~/.bashrc
   source ~/.bashrc
   ```
3. Use full path in commands:
   ```bash
   /usr/local/bin/wp site list
   ```

### Issue: "Error establishing database connection"

**Error**: Subsites show database error

**Solutions**:
1. Check WordPress database credentials in `wp-config.php`
2. Verify MySQL/MariaDB is running:
   ```bash
   sudo systemctl status mysql
   ```
3. Test database connection:
   ```bash
   wp db check
   ```

### Issue: "Subsite creation fails"

**Error**: `wp site create` returns error

**Solutions**:
1. Verify multisite is enabled:
   ```bash
   wp eval "echo MULTISITE ? 'yes' : 'no';"
   # Should output: yes
   ```
2. Check network setup:
   ```bash
   wp site list
   ```
3. Ensure `.htaccess` has correct rewrite rules (see Part 1.4)
4. Check Apache mod_rewrite is enabled:
   ```bash
   sudo a2enmod rewrite
   sudo systemctl restart apache2
   ```

### Issue: "Plugin upload fails"

**Error**: Cannot copy plugin files to server

**Solutions**:
1. Check directory permissions:
   ```bash
   ls -la /var/www/html/wp-content/plugins/
   # Should be writable by SSH user or www-data
   ```
2. Fix ownership:
   ```bash
   sudo chown -R www-data:www-data /var/www/html/wp-content/plugins
   sudo chmod -R 755 /var/www/html/wp-content/plugins
   ```
3. Add SSH user to www-data group:
   ```bash
   sudo usermod -a -G www-data wordpress
   ```

### Issue: "Tools not appearing in OpenCode"

**Error**: AI says tools are not available

**Solutions**:
1. **Check Builder toggle is enabled**
   - Open Builder settings
   - Verify "External WP CLI testing" is ON
2. **Verify environment variables in chat server**:
   ```bash
   # Check if vars are set
   node -e "console.log(process.env.TEST_WP_HOST)"
   ```
3. **Check server logs**:
   ```bash
   # Look for "Enabling WP CLI Testing MCP server"
   tail -f logs/chat-server.log
   ```
4. **Restart chat server**:
   ```bash
   pm2 restart chat-server
   # or
   npm run restart
   ```
5. **Verify MCP server file exists**:
   ```bash
   ls -la opencode/mcp-servers/wp-cli-testing/index.js
   ```

### Issue: "Tests timeout"

**Error**: Tests take too long and fail

**Solutions**:
1. Increase timeout in env vars:
   ```bash
   TEST_TIMEOUT=900000  # 15 minutes
   ```
2. Check network latency:
   ```bash
   ping wp-test.example.com
   ```
3. Verify WordPress server resources:
   ```bash
   ssh wordpress@wp-test.example.com "free -h && df -h"
   ```

### Issue: "Subsites not cleaning up"

**Error**: Old test subsites accumulate

**Solutions**:
1. Check cleanup is enabled:
   ```bash
   TEST_AUTO_CLEANUP=true
   TEST_CLEANUP_DELAY=3600000  # 1 hour
   ```
2. Manually list and delete:
   ```bash
   ssh wordpress@wp-test.example.com
   wp site list | grep "test-"
   # Delete old subsites
   wp site delete --slug=test-abc123 --yes
   ```
3. Create cleanup cron job:
   ```bash
   # On WordPress server
   crontab -e
   # Add line to run daily cleanup:
   0 2 * * * cd /var/www/html && wp site list --field=url | grep "/test-" | xargs -I {} wp site delete --url={} --yes
   ```

### Getting Help

If issues persist:

1. **Check logs**:
   - Chat server logs: `tail -f logs/chat-server.log`
   - WordPress error log: `tail -f /var/log/wp-errors.log`
   - Apache/Nginx error log: `tail -f /var/log/apache2/error.log`

2. **Test components individually**:
   - SSH: `ssh -v -i <key> user@host`
   - WP-CLI: `wp site list`
   - Subsite: `curl -I https://wp-test.example.com/test-abc/`

3. **Verify configuration**:
   - Run `external_wp_testing_config` tool via AI
   - Check all required env vars are set
   - Confirm SSH key has correct permissions

---

## Summary

You've now set up:

✅ **WordPress Multisite** with subdirectory subsites  
✅ **WP-CLI** for command-line control  
✅ **SSH key authentication** for secure access  
✅ **Environment variables** configured in chat server  
✅ **Gated MCP tools** that only load when Builder toggle is enabled  
✅ **Isolated testing** via automatic subsite provisioning

**Next Steps**:
- Enable toggle in Builder
- Ask AI to create a plugin
- Watch as it automatically tests on your external WordPress installation
- Review test results in the chat

The system supports **20+ concurrent tests** through multisite subsite isolation, with automatic cleanup and comprehensive CLI-based verification.
