# 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.js` → `assets/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) ```javascript const AgenticWriterSidebar = ({ postId }) => { const formatAiErrorMessage = (error) => { /* ... */ }; const sendMessage = async (msg) => { /* ... */ }; return
...
; }; ``` ### After (modular) **`src/utils/formatUtils.js`** ```javascript export const formatAiErrorMessage = (error, fallback, settings) => { // ... }; ``` **`src/hooks/useChatApi.js`** ```javascript export const useChatApi = () => { const sendMessage = async (msg) => { /* ... */ }; return { sendMessage }; }; ``` **`src/index.jsx`** ```javascript import { formatAiErrorMessage } from './utils/formatUtils'; import { useChatApi } from './hooks/useChatApi'; import { ChatTab } from './components/ChatTab'; const AgenticWriterSidebar = ({ postId }) => { const { sendMessage } = useChatApi(); return ; }; ``` --- ## 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)