# 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 <div>...</div>;
};
```

### 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 <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)
