Files
wp-agentic-writer/FRONTEND-REFACTOR-PHASE2.md
Dwindi Ramadhana d3f142222c feat: Add connection test caching and reasoning content support
Backend improvements:
- Add cache auto-clear on settings save (class-settings-v2.php)
  - Hooks updated_option action
  - Clears connection test transients when local backend settings change
- Add reasoning_content streaming support (class-local-backend-provider.php)
  - Handles thinking models like Claude extended thinking
  - Captures chunk['choices'][0]['delta']['reasoning_content']

Documentation:
- Add FRONTEND_AND_CHAT_FIX_SUMMARY.md with all fixes
- Add FRONTEND-REFACTOR-PHASE2.md with modularization plan

Note: Splitting effort deferred - will continue iterating on monolith
Next: Fix session history not appearing bug
2026-06-17 05:26:12 +07:00

8.4 KiB

Frontend Refactor Phase 2: Modularization Plan

Date: 2026-06-17
Status: 📋 IN PROGRESS
Author: Agent
Reference: FRONTEND_AND_CHAT_FIX_SUMMARY.md


Session Summary (2026-06-17)

Completed Backend Improvements

Task File Status
Connection test caching class-provider-manager.php Already existed
Cache auto-clear on settings save class-settings-v2.php Added
Reasoning content parsing class-local-backend-provider.php Added

Files Modified This Session

  1. includes/class-settings-v2.php

    • Added clear_local_backend_cache_on_settings_change() method
    • Hooked to updated_option action
    • Clears connection test transients when local backend settings change
  2. includes/class-local-backend-provider.php

    • Added reasoning_content streaming support (lines ~494-520)
    • Handles thinking models like Claude extended thinking
    • Debug logging included

Validation Results

Check Result
npm run build Passes
PHP syntax (all modified files) Passes
Build output dist/sidebar.js (169 KB)

Overview

This document outlines the approach for splitting the monolithic assets/js/src/index.jsx (11,793 lines) into modular React components, hooks, and utilities while maintaining the existing build pipeline.

Key Principle

The build pipeline (scripts/build.jsassets/js/dist/sidebar.js) already works correctly. We are refactoring the source for maintainability, NOT fixing a broken build.

Important: Two sidebar.js Files

File Source of Truth? Loaded by PHP?
assets/js/sidebar.js Legacy (webpack, 438KB) No
assets/js/dist/sidebar.js Current (esbuild, 169KB) Yes

Do NOT confuse the two files. The legacy sidebar.js (438KB) is the original monolithic file that was never modularized. The dist/sidebar.js (169KB) is the esbuild-compiled output from src/index.jsx.


Current State

Build Pipeline (Working )

assets/js/src/index.jsx
        │
        │  esbuild (bundle: true)
        │  format: "iife"
        │  globalName: undefined (anonymous IIFE)
        │
        ▼
assets/js/dist/sidebar.js (compiled, served to WordPress) ✅

Source & Output Files

Path Lines/Size Purpose Status
src/index.jsx 11,793 React source (to be split) Active
dist/sidebar.js 169 KB Compiled output (loaded by PHP) Active
sidebar.js 438 KB Legacy file (NOT loaded) ⚠️ Archived

Build Validation (2026-06-17)

Check Result
npm run build Passes (165.8kb output)
PHP syntax (settings) Passes
PHP syntax (provider) Passes
PHP syntax (provider manager) Passes
PHP syntax (local backend) Passes
PHP loads dist/sidebar.js Confirmed in class-gutenberg-sidebar.php:217

esbuild Configuration

The scripts/build.js uses bundle: true, which means:

  • All local imports are resolved automatically
  • No need for separate bundler config
  • Extracted files will compile seamlessly

Proposed Directory Structure

assets/js/
├── src/
│   ├── index.jsx                 # Main entry, imports all modules
│   ├── components/
│   │   ├── ChatTab.jsx          # Chat tab content
│   │   ├── ConfigTab.jsx        # Configuration tab
│   │   ├── CostTab.jsx          # Cost tracking tab
│   │   ├── WelcomeScreen.jsx    # Welcome/home screen
│   │   ├── Clarification.jsx    # Clarification quiz UI
│   │   ├── AgentWorkspaceCard.jsx
│   │   ├── ContextualAction.jsx
│   │   ├── FocusKeywordBar.jsx
│   │   ├── Messages.jsx         # Message rendering
│   │   ├── GlobalStatusBar.jsx
│   │   └── RefineAllModal.jsx
│   ├── hooks/
│   │   ├── useChatHistory.js
│   │   ├── useSessionLock.js
│   │   ├── usePostConfig.js
│   │   ├── useWritingState.js
│   │   └── useStreaming.js
│   ├── utils/
│   │   ├── api.js               # REST API helpers
│   │   ├── blockUtils.js        # Block manipulation
│   │   ├── planUtils.js         # Plan parsing/building
│   │   ├── streamUtils.js       # Streaming utilities
│   │   ├── markdownUtils.js     # Markdown rendering
│   │   └── formatUtils.js       # Formatting helpers
│   └── styles/
│       └── components.css       # Component-specific styles
└── dist/
    └── sidebar.js               # Compiled output (auto-generated)

Extraction Strategy

Phase 1: Extract Utilities (Low Risk)

Begin with pure functions that have no React dependencies:

  1. formatAiErrorMessage (lines 42-136)

    • Pure function, no side effects
    • Easy to extract and test
  2. markdownToHtml / inlineMarkdownToHtml (lines 10015-10270)

    • Large but isolated
    • No state dependencies
  3. Block utility functions

    • createBlocksFromSerialized
    • getBlockContentForContext
    • getHeadingContextForBlock

Phase 2: Extract Custom Hooks

  1. useChatHistory

    • Session loading, saving, message persistence
    • Isolated state management
  2. useSessionLock

    • Tab locking mechanism
    • Heartbeat management
  3. useStreaming

    • SSE parsing
    • Chunk accumulation
    • Error handling

Phase 3: Extract UI Components

  1. Tabs (Chat, Config, Cost)

    • Each tab can be its own component
    • Share state via props or context
  2. WelcomeScreen

    • Self-contained, minimal dependencies
  3. Clarification Quiz

    • Complex but isolated UI

Phase 4: Extract Editor Integration

The most complex part - interactions with WordPress block editor:

  • Block mutation observation
  • Input blocking
  • Undo/redo integration

Migration Pattern

Before (in index.jsx)

const AgenticWriterSidebar = ({ postId }) => {
  const formatAiErrorMessage = (error) => { /* ... */ };
  
  const sendMessage = async (msg) => { /* ... */ };
  
  return <div>...</div>;
};

After (modular)

src/utils/formatUtils.js

export const formatAiErrorMessage = (error, fallback, settings) => {
  // ...
};

src/hooks/useChatApi.js

export const useChatApi = () => {
  const sendMessage = async (msg) => { /* ... */ };
  return { sendMessage };
};

src/index.jsx

import { formatAiErrorMessage } from './utils/formatUtils';
import { useChatApi } from './hooks/useChatApi';
import { ChatTab } from './components/ChatTab';

const AgenticWriterSidebar = ({ postId }) => {
  const { sendMessage } = useChatApi();
  
  return <ChatTab onSend={sendMessage} />;
};

Verification Checklist

After each extraction:

  • npm run build completes without errors
  • Compiled sidebar.js matches expected size (±5%)
  • Chat functionality works (send message, receive response)
  • Planning functionality works (generate plan)
  • Refinement works (refine blocks)
  • Tab switching works
  • Session persistence works
  • No console errors in browser

Rollback Plan

If extraction causes issues:

  1. Revert the specific extracted file
  2. Keep extracted utilities (safe to keep)
  3. Re-run npm run build
  4. Verify functionality

Next Action

  1. Create src/utils/ directory
  2. Extract formatAiErrorMessage as the first migration
  3. Verify build and functionality
  4. Iterate with next extraction

Dependencies

Tool Status
esbuild Configured
npm Available
WordPress environment Local by Flywheel

Questions to Resolve Before Starting

  1. Should extracted components use TypeScript or remain JSX?
  2. Should we add PropTypes for component prop validation?
  3. Should we maintain backward compatibility with wpAgenticWriter global?

References

  • FRONTEND_AND_CHAT_FIX_SUMMARY.md - Original fix documentation
  • scripts/build.js - Current esbuild configuration
  • assets/js/dist/sidebar.js - Compiled output (loaded by PHP, 169KB)
  • assets/js/sidebar.js - Legacy file (archived, 438KB, NOT loaded)
  • assets/js/src/index.jsx - Current source (to be split, 11,793 lines)