Files
wp-agentic-writer/docs/CONTRIBUTING.md
Dwindi Ramadhana 690991c526 refactor: Cleanup git state - commit all staged changes
Major refactoring cleanup:
- Add new controller architecture (class-controller-*.php)
- Add new settings-v2 UI (views/settings-v2/)
- Add new CSS architecture (agentic-sidebar.css, tokens)
- Add esbuild build pipeline (scripts/build.js, package.json)
- Add composer dependencies (vendor/)
- Add frontend src directory (assets/js/src/index.jsx)
- Add documentation files
- Remove old/obsolete files (class-settings.php, old CSS)

This commits all pending changes from previous refactoring efforts.
2026-06-17 05:27:58 +07:00

10 KiB

Contributing to WP Agentic Writer

Thank you for your interest in contributing to WP Agentic Writer!

Project Overview

WP Agentic Writer is a WordPress plugin that integrates AI-powered writing assistance directly into the Gutenberg editor. It helps writers create better content through plan-first workflows, real-time chat, SEO analysis, and image generation.

Architecture

Component Overview

┌─────────────────────────────────────────────────────────────────┐
│                        Gutenberg Sidebar                         │
│                  (class-gutenberg-sidebar.php)                   │
│                                                                  │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐           │
│  │ Chat Tab     │  │ Plan Tab     │  │ Image Tab    │           │
│  └──────────────┘  └──────────────┘  └──────────────┘           │
└────────────────────────────┬────────────────────────────────────┘
                             │ REST API
     ┌───────────────────────┼───────────────────────┐
     │                       │                       │
     ▼                       ▼                       ▼
┌─────────────┐      ┌─────────────┐      ┌─────────────┐
│Controller_  │      │Controller_  │      │Controller_  │
│Chat         │      │Session      │      │Cost         │
└──────┬──────┘      └──────┬──────┘      └──────┬──────┘
       │                    │                    │
       └────────────────────┼────────────────────┘
                           ▼
               ┌───────────────────────┐
               │   Provider Manager    │
               │ (class-provider-      │
               │  manager.php)         │
               └───────────┬───────────┘
                           │
       ┌───────────────────┼───────────────────┐
       │                   │                   │
       ▼                   ▼                   ▼
┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│ OpenRouter  │    │  Local     │    │  Codex      │
│ Provider    │    │  Backend    │    │  Provider   │
└─────────────┘    └─────────────┘    └─────────────┘

Key Classes

Class File Purpose
Gutenberg_Sidebar class-gutenberg-sidebar.php Main plugin class, registers REST routes, enqueues assets
Controller_Chat class-controller-chat.php Chat messaging, streaming, search, research
Controller_Session class-controller-session.php Session locking for multi-tab safety
Controller_Cost class-controller-cost.php Cost tracking data
Controller_Models class-controller-models.php AI model listing and refresh
Provider_Manager class-provider-manager.php Provider selection and fallback logic
AI_Provider (interface) interface-ai-provider.php Contract for AI provider implementations
Context_Builder class-context-builder.php Builds context for AI requests
Conversation_Manager class-conversation-manager.php Manages conversation sessions
Rate_Limiter class-rate-limiter.php Rate limiting for REST endpoints

Adding a New REST Endpoint

1. Add the route registration

In class-gutenberg-sidebar.php, add to register_rest_routes():

register_rest_route('wp-agentic-writer/v1', '/my-endpoint', [
    'methods'             => 'POST',
    'callback'            => [$this, 'handle_my_endpoint'],
    'permission_callback' => [$this, 'check_permissions'],
]);

2. Add the handler method

/**
 * Handle my custom endpoint.
 *
 * @param WP_REST_Request $request REST request.
 * @return WP_REST_Response|WP_Error
 */
public function handle_my_endpoint($request)
{
    // Get parameters
    $params = $request->get_json_params();
    $post_id = $request->get_param('post_id');

    // Check post permission if post_id is provided
    if ($post_id > 0 && !$this->check_post_permission($post_id)) {
        return new WP_Error(
            'forbidden',
            __('You do not have permission to access this post.'),
            ['status' => 403]
        );
    }

    // Your logic here...

    return new WP_REST_Response(['result' => 'success'], 200);
}

3. Add rate limiting (optional)

// Check rate limit
$rate_limit = WPAW_Rate_Limiter::check('my_endpoint');
if (is_wp_error($rate_limit)) {
    return $rate_limit;
}

4. Document the endpoint

Add the endpoint to docs/architecture/REST_API_ENDPOINTS.md.


Adding a New AI Provider

1. Create the provider class

class WP_Agentic_Writer_My_Provider implements WPAW_AI_Provider {
    // Implement all methods from interface-ai-provider.php
}

2. Register in Provider Manager

In class-provider-manager.php, add to register_providers():

$this->providers['my_provider'] = new WP_Agentic_Writer_My_Provider();

3. Add to selection logic

Update select_provider() if your provider needs special handling.


Adding a New Sidebar Tab

1. Add tab button in JavaScript

In assets/sidebar.js, add to the tab navigation:

const tabButtons = document.querySelectorAll('.wpaw-tab-button');
// Add your tab button

2. Add tab content

<div id="my-tab" class="wpaw-tab-content" style="display: none;">
    <!-- Your tab content -->
</div>

3. Add tab switching logic

function showTab(tabId) {
    // Handle your tab
}

CSS Token System

The plugin uses a three-namespace CSS token system:

Scope Tokens (lowest priority)

.wpaw-sidebar-container {
    --wpaw-color-primary: #2271b1;
}

State Tokens

.wpaw-tab-button.active {
    --wpaw-color-primary: #135e96;
}

Intent Tokens (highest priority)

.wpaw-ai-thinking {
    --wpaw-color-primary: #d63638;
}

CSS Class Hierarchy

.wpaw-sidebar-container      → Base container
├── .wpaw-tab-content         → Tab panels
├── .wpaw-command-area        → Input areas
├── .wpaw-settings-v2-wrap    → Settings pages
├── .wpaw-ai-thinking         → AI processing state
└── .wpaw-error              → Error states

Database Schema

Conversations Table

CREATE TABLE {prefix}wpaw_conversations (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    session_id VARCHAR(36) NOT NULL UNIQUE,
    user_id BIGINT UNSIGNED NOT NULL,
    post_id BIGINT UNSIGNED DEFAULT NULL,
    title VARCHAR(255) DEFAULT '',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_user_id (user_id),
    INDEX idx_post_id (post_id)
)

Messages Table

CREATE TABLE {prefix}wpaw_messages (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    conversation_id BIGINT UNSIGNED NOT NULL,
    role VARCHAR(20) NOT NULL,
    content LONGTEXT NOT NULL,
    metadata JSON DEFAULT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (conversation_id) REFERENCES {prefix}wpaw_conversations(id) ON DELETE CASCADE
)

Cost Tracking Table

CREATE TABLE {prefix}wpaw_cost_tracking (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    provider VARCHAR(50) NOT NULL,
    model VARCHAR(100) NOT NULL,
    input_tokens INT UNSIGNED DEFAULT 0,
    output_tokens INT UNSIGNED DEFAULT 0,
    cost DECIMAL(10,6) DEFAULT 0,
    session_id VARCHAR(36) DEFAULT NULL,
    status VARCHAR(20) DEFAULT 'complete',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)

Testing Locally

Manual Smoke Tests

After making changes, verify:

  1. Sidebar loads: Open a post in Gutenberg, verify sidebar appears
  2. Chat works: Send a message, verify response appears
  3. Settings save: Change settings, refresh, verify persistence
  4. Rate limiting: Rapid requests should return 429 after limit

Debug Mode

Enable debug logging in browser console:

window.wpAgenticWriter = { debug: true };

Database Queries

Use WP-CLI to inspect database:

wp db query "SELECT * FROM wp_wpaw_conversations LIMIT 5"
wp db query "SELECT * FROM wp_wpaw_messages LIMIT 5"

Code Style

  • Follow WordPress PHP Coding Standards
  • Use wp_add_inline_style() for dynamic CSS
  • Prefix all classes/functions with wpaw_ or WP_Agentic_Writer_
  • Document all public methods with docblocks

Security Checklist

  • All post-scoped endpoints check edit_post capability
  • Sanitize all input with sanitize_text_field(), absint(), etc.
  • Escape all output with esc_html(), esc_attr(), etc.
  • Use WordPress nonces for form submissions
  • Rate limit expensive operations

Useful Commands

# Activate plugin
wp plugin activate wp-agentic-writer

# Deactivate plugin
wp plugin deactivate wp-agentic-writer

# View cost tracking
wp db query "SELECT * FROM wp_wpaw_cost_tracking ORDER BY created_at DESC LIMIT 10"

# Clear session locks
wp db query "DELETE FROM wp_wpaw_conversations WHERE 1=1"

Resources