diff --git a/SIDEBAR_1_TO_1_MIGRATION.md b/SIDEBAR_1_TO_1_MIGRATION.md new file mode 100644 index 0000000..93ddb97 --- /dev/null +++ b/SIDEBAR_1_TO_1_MIGRATION.md @@ -0,0 +1,768 @@ +# WP Agentic Writer Sidebar 1:1 Migration Plan + +**Source of truth:** `assets/js/sidebar.js` +**Source length:** 12,363 lines +**Scope:** planning/audit document only. No implementation code, no build step, no inferred behavior. + +This document exists to make the migration match `sidebar.js` exactly. If this file, `MIGRATION_GUIDE.md`, comments, or memory disagree with `assets/js/sidebar.js`, `assets/js/sidebar.js` wins. + +## Non-Negotiable Rules + +1. Preserve every behavior from `assets/js/sidebar.js` before extracting or improving anything. +2. Convert `wp.element.createElement(...)` to JSX mechanically only after copying the same source range. +3. Preserve hook order, state names, ref names, default values, dependency arrays, effect cleanups, and callback boundaries. +4. Preserve all `wpAgenticWriter` globals, endpoint paths, request bodies, headers, nonces, stream handling, abort handling, and error formatting. +5. Preserve all Gutenberg APIs: `registerPlugin`, `PluginSidebarMoreMenuItem`, `PluginSidebar`, `Panel`, `TextareaControl`, `TextControl`, `CheckboxControl`, `Button`, `RawHTML`, `dispatch`, `select`, and `wp.data.withSelect`. +6. Preserve all DOM tags, component tags, `className` values, dynamic class branches, `role`, `aria-*`, `title`, `placeholder`, `style`, `dangerouslySetInnerHTML`, button labels, visible text, icons, SVG markup, and conditional render gates. +7. Preserve editor block attribute class mutations, especially `wpaw-diff-added` and `wpaw-diff-removed`; these are migration-critical even though they are not sidebar wrapper classes. +8. Do not rename functions, split files, normalize copy, deduplicate logic, replace SVGs, replace `RawHTML`, or change UX flow during the first migration pass. +9. Extraction is allowed only after a monolithic JSX port can be checked against this document line range by line range. + +## File-Level Boundaries + +| Lines | Required migration unit | +| --- | --- | +| 1-6 | File header comment. Preserve package context if the migrated file keeps source banner comments. | +| 7-15 | IIFE argument and WordPress dependency destructuring. New module imports may replace destructuring only if every dependency maps 1:1. | +| 16-30 | Debug logger and `isDebug` behavior. | +| 31-35 | `pluginIcon` image element with `wpAgenticWriter.pluginUrl + "/assets/img/icon.svg"`, alt text, and 20px style. | +| 37-12347 | `AgenticWriterSidebar` component. | +| 12349-12352 | `mapSelectToProps`, selecting `core/editor`. | +| 12355-12356 | `ConnectedSidebar = wp.data.withSelect(mapSelectToProps)(AgenticWriterSidebar)`. | +| 12358-12362 | `registerPlugin("wp-agentic-writer", { icon: pluginIcon, render: ConnectedSidebar })`. | +| 12363 | IIFE close with `window.wp`. | + +## Migration Method + +1. Create the new JSX target as a monolith first. +2. Copy ranges in the same order as the coverage table below. +3. Convert element calls mechanically: + - tag/component name stays the same + - prop names stay the same + - children order stays the same + - conditional gates stay in the same location + - spread/rest behavior is not introduced unless already present in the source range +4. After the monolith is complete, compare it against this document: + - every range is present + - every function exists + - every state/ref/effect exists in the same hook order + - every class in the class inventory exists + - every endpoint in the endpoint inventory exists + - every render surface exists with the same branches +5. Only after the monolith is proven equivalent, optional extraction may start. Extraction must move code, not rewrite behavior. + +## Component-Level Coverage + +### State and Refs, Lines 40-366 + +| Lines | Kind | Name | +| --- | --- | --- | +| 40-41 | const | `settings` | +| 42-138 | const | `formatAiErrorMessage` | +| 139-141 | state | `[activeTab, setActiveTab]` | +| 142-142 | state | `[messages, setMessages]` | +| 143-143 | state | `[input, setInput]` | +| 144-144 | state | `[isLoading, setIsLoading]` | +| 145-145 | state | `[currentSessionId, setCurrentSessionId]` | +| 146-146 | state | `[availableSessions, setAvailableSessions]` | +| 147-148 | state | `[isSessionActionLoading, setIsSessionActionLoading]` | +| 149-151 | state | `[agentMode, setAgentMode]` | +| 152-154 | const/ref | `tabIdRef` | +| 155-159 | state | `[sessionLock, setSessionLock]` | +| 160-162 | const/ref | `lockHeartbeatRef` | +| 163-181 | const/memo | `defaultPostConfig` | +| 182-182 | state | `[postConfig, setPostConfig]` | +| 183-183 | state | `[isConfigLoading, setIsConfigLoading]` | +| 184-184 | state | `[isConfigSaving, setIsConfigSaving]` | +| 185-185 | state | `[configError, setConfigError]` | +| 186-186 | const/ref | `configHydratedRef` | +| 187-187 | const/ref | `lastSavedConfigRef` | +| 188-190 | const/ref | `configSaveTimeoutRef` | +| 191-195 | state | `[cost, setCost]` | +| 196-200 | state | `[monthlyBudget, setMonthlyBudget]` | +| 201-203 | state | `[providerInfo, setProviderInfo]` | +| 204-223 | const | `applyProviderMetadata` | +| 224-224 | state | `[isEditorLocked, setIsEditorLocked]` | +| 225-225 | state | `[isRefinementLocked, setIsRefinementLocked]` | +| 226-226 | state | `[refiningBlockIds, setRefiningBlockIds]` | +| 227-227 | const/ref | `refinementDecoratedIdsRef` | +| 228-228 | const/ref | `lockedEditableNodesRef` | +| 229-229 | const/ref | `lockedBlockIdsRef` | +| 230-230 | const | `REFINEMENT_ALL_CONFIRM_THRESHOLD` | +| 231-235 | state | `[refineAllConfirm, setRefineAllConfirm]` | +| 236-236 | const/ref | `refineAllConfirmResolverRef` | +| 237-239 | const/ref | `skipRefineAllConfirmRef` | +| 240-240 | state | `[seoAudit, setSeoAudit]` | +| 241-241 | state | `[isSeoAuditing, setIsSeoAuditing]` | +| 242-242 | state | `[isGeneratingMeta, setIsGeneratingMeta]` | +| 243-245 | state | `[activeSeoFixKey, setActiveSeoFixKey]` | +| 246-246 | state | `[inClarification, setInClarification]` | +| 247-247 | state | `[questions, setQuestions]` | +| 248-248 | state | `[currentQuestionIndex, setCurrentQuestionIndex]` | +| 249-249 | state | `[answers, setAnswers]` | +| 250-250 | state | `[detectedLanguage, setDetectedLanguage]` | +| 251-252 | state | `[clarificationMode, setClarificationMode]` | +| 253-253 | state | `[pendingRefinement, setPendingRefinement]` | +| 254-254 | state | `[pendingEditPlan, setPendingEditPlan]` | +| 255-255 | state | `[pendingDiffBlockIds, setPendingDiffBlockIds]` | +| 256-256 | const/ref | `lastGenerationRequestRef` | +| 257-257 | const/ref | `currentPlanRef` | +| 258-258 | const/ref | `lastExecuteRequestRef` | +| 259-259 | const/ref | `sectionInsertIndexRef` | +| 260-260 | const/ref | `activeSectionIdRef` | +| 261-261 | const/ref | `sectionBlocksRef` | +| 262-262 | const/ref | `blockSectionRef` | +| 263-263 | const/ref | `markdownRendererRef` | +| 264-264 | const/ref | `lastRefineRequestRef` | +| 265-265 | const/ref | `lastChatRequestRef` | +| 266-266 | const/ref | `stopExecutionRef` | +| 267-267 | const/ref | `activeAbortControllerRef` | +| 268-268 | const/ref | `activeReaderRef` | +| 269-273 | const/ref | `activeOperationRef` | +| 274-274 | state | `[executionStopped, setExecutionStopped]` | +| 275-279 | state | `[activeOperation, setActiveOperation]` | +| 280-287 | state | `[writingState, setWritingState]` | +| 288-289 | state | `[isWritingStateLoading, setIsWritingStateLoading]` | +| 290-295 | state | `[workspaceSnapshot, setWorkspaceSnapshot]` | +| 296-307 | state | `[isWorkspaceCollapsed, setIsWorkspaceCollapsed]` | +| 308-323 | const | `toggleAgentWorkspace` | +| 324-325 | state | `[showMentionAutocomplete, setShowMentionAutocomplete]` | +| 326-326 | state | `[mentionQuery, setMentionQuery]` | +| 327-327 | state | `[mentionOptions, setMentionOptions]` | +| 328-328 | state | `[mentionCursorIndex, setMentionCursorIndex]` | +| 329-330 | state | `[showSlashAutocomplete, setShowSlashAutocomplete]` | +| 331-331 | state | `[slashQuery, setSlashQuery]` | +| 332-332 | state | `[slashOptions, setSlashOptions]` | +| 333-333 | state | `[slashCursorIndex, setSlashCursorIndex]` | +| 334-334 | state | `[isTextareaExpanded, setIsTextareaExpanded]` | +| 335-335 | const/ref | `inputRef` | +| 336-338 | const/ref | `streamTargetRef` | +| 339-340 | state | `[focusKeywordSuggestions, setFocusKeywordSuggestions]` | +| 341-341 | state | `[selectedFocusKeyword, setSelectedFocusKeyword]` | +| 342-343 | state | `[showCustomKeywordInput, setShowCustomKeywordInput]` | +| 344-344 | state | `[customKeywordInput, setCustomKeywordInput]` | +| 345-345 | const/ref | `messagesSaveTimeoutRef` | +| 346-346 | const/ref | `lastPersistedMessagesRef` | +| 347-349 | const/ref | `isHydratingSessionRef` | +| 350-350 | state | `[showWelcome, setShowWelcome]` | +| 351-351 | state | `[welcomeKeywordInput, setWelcomeKeywordInput]` | +| 352-354 | state | `[welcomeStartMode, setWelcomeStartMode]` | +| 355-355 | state | `[aiUndoStack, setAiUndoStack]` | +| 356-358 | const | `MAX_UNDO_STACK` | +| 359-365 | state | `[memantoRestore, setMemantoRestore]` | +| 366-366 | const/ref | `memantoRestoreFetchedRef` | + +### Effects, Timeline, Editor Locking, Config Helpers, Lines 367-1194 + +| Lines | Kind | Name | +| --- | --- | --- | +| 367-372 | effect | `useEffect@367` | +| 373-401 | effect | `useEffect@373` | +| 402-448 | const | `savePostConfig` | +| 449-473 | effect | `useEffect@449` | +| 474-499 | effect | `useEffect@474` | +| 500-510 | const | `normalizeWritingState` | +| 511-539 | const | `saveWritingState` | +| 540-550 | const | `persistWritingStatePatch` | +| 551-585 | effect | `useEffect@551` | +| 586-586 | const/ref | `messagesEndRef` | +| 587-589 | const/ref | `messagesContainerRef` | +| 590-595 | effect | `useEffect@590` | +| 596-597 | const | `progressRegex` | +| 598-608 | const | `activeTimelineStatuses` | +| 609-609 | const | `writingTimelineStatuses` | +| 610-621 | const | `findLastActiveTimelineIndex` | +| 622-636 | const | `deactivateActiveTimelineEntries` | +| 637-659 | const | `updateOrCreateTimelineEntry` | +| 660-673 | const | `addActivityTimeline` | +| 674-682 | const | `setActiveOperationState` | +| 683-691 | const | `beginAgentOperation` | +| 692-700 | const | `finishAgentOperation` | +| 701-721 | const | `markActiveOperationStopping` | +| 722-724 | const | `isAbortError` | +| 725-728 | const | `registerActiveReader` | +| 729-742 | callback | `requestRefineAllConfirmation` | +| 743-752 | callback | `resolveRefineAllConfirmation` | +| 753-764 | const | `captureEditorSnapshot` | +| 765-775 | const | `pushUndoSnapshot` | +| 776-812 | const | `undoLastAiOperation` | +| 813-832 | effect | `useEffect@813` | +| 833-841 | effect | `useEffect@833` | +| 842-889 | effect | `useEffect@842` | +| 890-921 | effect | `useEffect@890` | +| 922-981 | effect | `useEffect@922` | +| 982-1019 | effect | `useEffect@982` | +| 1020-1028 | const | `toTextValue` | +| 1029-1031 | const | `updatePostConfig` | +| 1032-1071 | const | `buildPostConfigFromAnswers` | +| 1072-1079 | const | `handleFocusKeywordChange` | +| 1080-1089 | const | `handleKeywordSelect` | +| 1090-1137 | const | `extractFocusKeywordSuggestions` | +| 1138-1142 | const | `extractFocusKeywordSuggestion` | +| 1143-1153 | const | `addFocusKeywordSuggestion` | +| 1154-1159 | const | `addFocusKeywordSuggestions` | +| 1160-1168 | effect | `useEffect@1160` | +| 1169-1175 | effect | `useEffect@1169` | +| 1176-1194 | const | `handleWelcomeStart` | + +### SEO, Workspace, Session, Locking, Lines 1195-2515 + +| Lines | Kind | Name | +| --- | --- | --- | +| 1195-1269 | const | `runSeoAudit` | +| 1270-1308 | const | `buildSeoAuditFixInstruction` | +| 1309-1310 | const | `getSeoFixKey` | +| 1311-1318 | const | `getSeoAuditPatternCount` | +| 1319-1322 | const | `formatCountLabel` | +| 1323-1328 | const | `formatAuditPatternLabel` | +| 1329-1348 | const | `buildAuditRefinementContext` | +| 1349-1459 | const | `handleSeoAuditFix` | +| 1460-1563 | const | `generateMetaDescription` | +| 1564-1587 | const | `extractBlockPreview` | +| 1588-1599 | const | `getBlockPreviewById` | +| 1600-1638 | callback | `buildWorkspaceSnapshot` | +| 1639-1661 | effect | `useEffect@1639` | +| 1662-1668 | effect | `useEffect@1662` | +| 1669-1682 | effect | `useEffect@1669` | +| 1683-1686 | effect | `useEffect@1683` | +| 1687-1702 | effect | `useEffect@1687` | +| 1703-1716 | effect | `useEffect@1703` | +| 1717-1754 | callback | `sanitizeMessagesForStorage` | +| 1755-1781 | callback | `hydrateSessionStateFromMessages` | +| 1782-1839 | callback | `persistSessionMessages` | +| 1840-1840 | const/ref | `messagesRef` | +| 1841-1845 | effect | `useEffect@1841` | +| 1846-1889 | effect | `useEffect@1846` | +| 1890-1926 | callback | `acquireSessionLock` | +| 1927-1947 | callback | `releaseSessionLock` | +| 1948-1961 | callback | `startLockHeartbeat` | +| 1962-1969 | callback | `stopLockHeartbeat` | +| 1970-1994 | effect | `useEffect@1970` | +| 1995-2026 | callback | `takeOverSession` | +| 2027-2072 | effect | `useEffect@2027` | +| 2073-2213 | effect | `useEffect@2073` | +| 2214-2241 | effect | `useEffect@2214` | +| 2242-2300 | effect | `useEffect@2242` | +| 2301-2397 | const | `loadPostSessions` | +| 2398-2515 | const | `openSessionById` | + +### Mentions, Commands, Planning, Agent Decisions, Lines 2516-4320 + +| Lines | Kind | Name | +| --- | --- | --- | +| 2516-2526 | const | `resolveStreamTarget` | +| 2527-2536 | const | `normalizeMentionToken` | +| 2537-2550 | const | `extractMentionsFromText` | +| 2551-2560 | const | `stripMentionsFromText` | +| 2561-2569 | const | `hasTitleMention` | +| 2570-2689 | const | `handleTitleRefinement` | +| 2690-2712 | const | `parseInsertCommand` | +| 2713-2747 | const | `getSlashOptions` | +| 2748-2758 | const | `getBlockIndex` | +| 2759-2777 | const | `resolveTargetBlockId` | +| 2778-2870 | const | `insertRefinementBlock` | +| 2871-3188 | const | `streamGeneratePlan` | +| 3189-3213 | const | `retryLastGeneration` | +| 3214-3228 | const | `retryLastExecute` | +| 3229-3257 | const | `retryLastRefinement` | +| 3258-3473 | const | `retryLastChat` | +| 3474-3534 | const | `createBlockFromPlan` | +| 3535-3543 | const | `normalizePlanActions` | +| 3544-3604 | const | `buildPlanPreviewItem` | +| 3605-3611 | const | `normalizePlanSectionTitle` | +| 3612-3622 | const | `upsertSectionBlock` | +| 3623-3632 | const | `removeSectionBlock` | +| 3633-3673 | const | `loadSectionBlocks` | +| 3674-3696 | const | `saveSectionBlocks` | +| 3697-3709 | const | `ensurePlanTasks` | +| 3710-3743 | const | `getTargetedRefinementBlocks` | +| 3744-3828 | const | `findBestPlanSectionMatch` | +| 3829-3851 | const | `updatePlanSectionStatus` | +| 3852-3893 | const | `findSectionInsertIndex` | +| 3894-3906 | const | `shouldShowWritingEmptyState` | +| 3907-3956 | const | `summarizeChatHistory` | +| 3957-4007 | const | `detectUserIntent` | +| 4008-4027 | const | `buildOptimizedContext` | +| 4028-4067 | const | `handleResetCommand` | +| 4068-4096 | const | `updateOrCreatePlanMessage` | +| 4097-4156 | const | `suggestKeywordsFromPlan` | +| 4157-4172 | callback | `buildChatHistoryPayload` | +| 4173-4186 | callback | `getLastUserMessageText` | +| 4187-4198 | const | `shouldSkipPlanningCompletion` | +| 4199-4218 | const | `getPlanRuntimeSummary` | +| 4219-4221 | const | `getPlanId` | +| 4222-4260 | const | `classifyAgentIntent` | +| 4261-4320 | const | `decideAgentAction` | + +### Execution, Refinement, Block Context, Lines 4321-6388 + +| Lines | Kind | Name | +| --- | --- | --- | +| 4321-4768 | const | `executePlanFromCard` | +| 4769-4794 | const | `handleStopExecution` | +| 4795-4870 | const | `clearChatContext` | +| 4871-4953 | const | `createBlocksFromSerialized` | +| 4954-5056 | const | `reformatBlocks` | +| 5057-5142 | const | `revisePlanFromPrompt` | +| 5143-5240 | const | `applyEditPlan` | +| 5241-5280 | const | `cancelEditPlan` | +| 5281-5304 | const | `formatClarificationContext` | +| 5305-5327 | effect | `useEffect@5305` | +| 5328-5362 | const | `removeDuplicateHeadings` | +| 5363-5390 | const | `getRefineableBlocks` | +| 5391-5420 | const | `getListItemBlocks` | +| 5421-5426 | const | `resolveExplicitListItem` | +| 5427-5442 | const | `getParentListId` | +| 5443-5453 | const | `getBlockContentForContext` | +| 5454-5470 | const | `getHeadingContextForBlock` | +| 5471-5494 | const | `getNearbyParagraphContext` | +| 5495-5503 | const | `getContextFromMentions` | +| 5504-5518 | const | `extractQuotedTermsFromMessage` | +| 5519-5520 | const | `getAllTextRefineableBlocks` | +| 5521-5533 | const | `selectLikelySlangBlocks` | +| 5534-5537 | const | `isAiSlopRequest` | +| 5538-5589 | const | `getAiSlopFindingsForBlock` | +| 5590-5606 | const | `selectLikelyAiSlopBlocks` | +| 5607-5622 | const | `buildContextBlocksForRefinement` | +| 5623-5704 | const | `buildRefinementDiagnosis` | +| 5705-5799 | const | `resolveBlockMentions` | +| 5800-6388 | const | `handleChatRefinement` | + +### Chat Input, Send, Clarification, Welcome, Workspace, Lines 6389-9996 + +| Lines | Kind | Name | +| --- | --- | --- | +| 6389-6455 | render | `renderRefineAllConfirmModal` | +| 6456-6579 | const | `getMentionOptions` | +| 6580-6612 | effect | `useEffect@6580` | +| 6613-6652 | const | `handleInputChange` | +| 6653-6701 | const | `handleKeyDown` | +| 6702-6726 | const | `insertMention` | +| 6727-6758 | const | `insertSlashCommand` | +| 6759-8056 | const | `sendMessage` | +| 8057-8476 | const | `submitAnswers` | +| 8477-8829 | render | `renderClarification` | +| 8830-8916 | const | `startNewConversation` | +| 8917-8959 | const | `deleteConversationSession` | +| 8960-8983 | const | `getSessionDisplayTitle` | +| 8984-8993 | const | `getSessionContinuityLabel` | +| 8994-9004 | const | `getSessionDebugMeta` | +| 9005-9184 | render | `renderWelcomeScreen` | +| 9185-9253 | render | `renderWritingEmptyState` | +| 9254-9459 | render | `renderFocusKeywordBar` | +| 9460-9629 | render | `renderAgentWorkspaceCard` | +| 9630-9632 | alias | `renderContextIndicator = renderAgentWorkspaceCard` | +| 9633-9996 | render/action | `renderContextualAction` | + +### Messages, Tabs, Cost, Final Shell, Lines 9997-12363 + +| Lines | Kind | Name | +| --- | --- | --- | +| 9997-10917 | render | `renderMessages` | +| 10918-11434 | render | `renderConfigTab` | +| 11435-11448 | const | `getAgentStatus` | +| 11449-11585 | render | `renderGlobalStatusBar` | +| 11586-12020 | render | `renderChatTab` | +| 12021-12022 | state | `[costHistory, setCostHistory]` | +| 12023-12050 | const | `refreshCostData` | +| 12051-12057 | effect | `useEffect@12051` | +| 12058-12306 | render | `renderCostTab` | +| 12307-12346 | return | component `Fragment` with menu item, sidebar, panel, and active tab renderer | +| 12347 | close | `AgenticWriterSidebar` close | +| 12349-12363 | boot | `mapSelectToProps`, `ConnectedSidebar`, `registerPlugin`, IIFE close | + +## Render Surface Checklist + +Each render surface must be migrated as an element tree, not summarized. + +| Render surface | Lines | Required branches/elements | +| --- | --- | --- | +| `renderRefineAllConfirmModal` | 6389-6455 | Null when closed; dialog overlay; modal; title; body; `CheckboxControl`; cancel and continue `Button`s; session skip flag behavior. | +| `renderClarification` | 8477-8829 | Null guard; `renderSingleChoice`; custom option textarea; `renderMultipleChoice`; `renderOpenText`; `renderConfigForm`; answer switch; quiz wrapper; progress bar; previous/skip/next-finish buttons. | +| `renderWelcomeScreen` | 9005-9184 | Recent session button; older sessions details list; session open/delete buttons; focus keyword input; chat/planning mode pills; start button. | +| `renderWritingEmptyState` | 9185-9253 | Empty state wrapper; SVG icon; title; paragraph; create outline button with inline SVG; hint paragraph. | +| `renderFocusKeywordBar` | 9254-9459 | Expanded mode branch; compact mode branch; keyword input behavior; suggestions; selected state; cost/provider indicators; expand/collapse controls. | +| `renderAgentWorkspaceCard` | 9460-9629 | Workspace status; collapsed state; context grid; keyword field; conversation/provider summaries; resume card. | +| `renderContextIndicator` | 9630-9632 | Alias to `renderAgentWorkspaceCard`, not a new implementation. | +| `renderContextualAction` | 9633-9996 | Null guard; `create_outline` action object; clarity check; plan generation stream; contextual action card. | +| `renderMessages` | 9997-10917 | Markdown helpers; grouping logic; user messages; AI group; timeline entries; plan cards; edit-plan cards; structured errors; normal response; resume actions. | +| `renderConfigTab` | 10918-11434 | Configuration wrapper; article length; language; tone; experience; image/search toggles; SEO section; meta generation; SEO audit result/fix UI; status descriptions. | +| `renderGlobalStatusBar` | 11449-11585 | Status dot/label; memory badge; undo; sessions; chat; workspace toggle; config; cost icon buttons. | +| `renderChatTab` | 11586-12020 | Lock banners; health notices; welcome/empty/workspace/activity-log gates; command area; hint; textarea; mention/slash autocomplete; search toggle; stop/send buttons; keyboard hints; refine modal. | +| `renderCostTab` | 12058-12306 | Cost header; refresh; cost cards; budget section; warning; action summary table; history table; settings footer link. | +| Main return | 12307-12346 | `Fragment`; `PluginSidebarMoreMenuItem`; `PluginSidebar`; icon title; `Panel`; `wpaw-tab-content-wrapper`; active tab switch. | + +## Nested Function Checklist + +These nested helpers are easy to lose during component extraction. + +| Parent | Lines | Nested item | +| --- | --- | --- | +| `renderClarification` | 8486-8547 | `renderSingleChoice` | +| `renderClarification` | 8550-8577 | `renderMultipleChoice` | +| `renderClarification` | 8580-8597 | `renderOpenText` | +| `renderClarification` | 8600-8723 | `renderConfigForm` | +| `renderClarification` | 8725-8742 | `answerInput` switch | +| `renderContextualAction` | 9636-9966 | `actions.create_outline` object and async `onClick` | +| `renderMessages` | 9998-10006 | `normalizeMessageContent` | +| `renderMessages` | 10007-10014 | `escapeHtml` | +| `renderMessages` | 10015-10031 | `inlineMarkdownToHtml` | +| `renderMessages` | 10032-10270 | `markdownToHtml` | +| `markdownToHtml` | 10112-10117 | `flushParagraph` | +| `markdownToHtml` | 10118-10140 | `flushList` | +| `markdownToHtml` | 10141-10144 | `addListItem` | +| `markdownToHtml` | 10145-10156 | `addDetailToLastItem` | +| `markdownToHtml` | 10158-10166 | `getListType` | +| `renderMessages` | 10271-10276 | `renderMessageContent` | +| `renderMessages` | 10278-10312 | group building and user message branch | +| `renderMessages` | 10313-10482 | AI group and timeline branch | +| `renderMessages` | 10485-10645 | `message.type === "plan"` branch | +| `renderMessages` | 10647-10767 | `message.type === "edit_plan"` branch | +| `renderMessages` | 10769-10848 | `message.type === "error"` branch | +| `renderMessages` | 10850-10909 | default AI response branch | +| `renderConfigTab` | 10989-10990 | language list merging | +| `renderCostTab` | 12059-12079 | budget percent/status and action summary locals | + +## Endpoint Inventory + +Every endpoint path below is used by `sidebar.js` and must remain present with its existing method, headers, body shape, and response handling. + +| Lines | Endpoint | +| --- | --- | +| 379, 411-412 | `/post-config/${postId}` | +| 479, 12026-12027 | `/cost-tracking/${postId}` | +| 519-520, 558 | `/writing-state/${postId}` | +| 1200-1201 | `/seo-audit/${postId}` | +| 1468-1469 | `/generate-meta` | +| 1813-1814, 1874, 1893-1894, 1931-1932, 1979, 1999-2000, 2122-2123, 2308-2309, 2335-2336, 2413-2414, 2479-2480, 4808-4809, 8836-8837, 8926-8927 | conversation endpoints | +| 2143-2144, 2448-2449 | `/conversation/${postId}` and `/conversation/${data.post_id}` | +| 2167-2168 | `/chat-history/${postId}` | +| 2220 | `/memanto/restore?post_id=${postId}` | +| 2612 | `/refine-title` | +| 2897-2898, 7354-7355, 7762-7763, 8158-8159, 9809-9810 | `/generate-plan` | +| 3288, 6922 | `/chat` | +| 3638-3639, 3680 | `/section-blocks/${postId}` and `/section-blocks` | +| 3915-3916 | `/summarize-context` | +| 3963-3964 | `/detect-intent` | +| 4039 | `/clear-context` | +| 4103-4104 | `/suggest-keywords` | +| 4431-4432 | `/execute-article` | +| 4984-4985 | `/reformat-blocks` | +| 5087 | `/revise-plan` | +| 5969-5970 | `/refine-from-chat` | +| 7251-7252, 9681-9682 | `/check-clarity` | + +## Editor and Browser Side Effects + +Preserve these integrations exactly. + +| Lines | Side effect | +| --- | --- | +| 300-314 | `localStorage` key `wpaw_agent_workspace_collapsed`. | +| 449-473 | Debounced config save via `configSaveTimeoutRef`. | +| 683-700, 4769-4794 | `AbortController` lifecycle and active operation state. | +| 813-841 | Post saving lock/unlock for writing and refining. | +| 842-981 | Editor input lock, block decoration, and global key/paste/drop/cut blockers. | +| 1651-1653 | `wp.data.subscribe` workspace snapshot update. | +| 1678-1680, 1846-1889, 1970-1994 | `beforeunload` handlers. | +| 1692, 1708, 2095 | `localStorage` session keys. | +| 1948-1969 | Session lock heartbeat interval. | +| 2871-3188, 3258-3473, 4321-4768, 5800-6388, 6759-8056, 8057-8476, 9633-9996 | Stream readers, `TextDecoder`, timeout cleanup, and abort checks. | +| 6580-6612 | Window event `wpaw:insert-mention`. | +| 9400-9404, 9563-9567 | Focus keyword debounce saves. | +| 12349-12356 | `wp.data.withSelect` connection to current post ID. | + +## Class Inventory + +All classes below are present in `sidebar.js`; preserve spelling and combinations. First column is the first line where the class appears. + +```text +6075 wpaw-diff-removed +6088 wpaw-diff-added +6129 wpaw-diff-added +6397 wpaw-refine-confirm-overlay +6404 wpaw-refine-confirm-modal +6407 wpaw-refine-confirm-title +6412 wpaw-refine-confirm-body +6428 wpaw-refine-confirm-actions +8493 wpaw-answer-options +8515 wpaw-custom-answer-wrapper +8533 wpaw-custom-text-input +8631 wpaw-config-form +8646 wpaw-config-field +8653 wpaw-config-label +8656 wpaw-config-label-text +8662 wpaw-config-description +8668 wpaw-config-toggle +8682 wpaw-toggle-slider +8706 wpaw-config-text-input +8746 wpaw-clarification-quiz +8746 dark-theme +8749 wpaw-quiz-header +8753 wpaw-progress-bar +8755 wpaw-progress-fill +8770 wpaw-question-card +8775 wpaw-quiz-actions +9011 wpaw-welcome-screen +9014 wpaw-welcome-content +9016 wpaw-welcome-icon +9024 wpaw-welcome-title +9029 wpaw-welcome-subtitle +9037 wpaw-welcome-pill +9065 wpaw-session-list +9086 wpaw-session-open-btn +9135 wpaw-welcome-input +9148 wpaw-welcome-pills +9176 wpaw-welcome-start-btn +9188 wpaw-writing-empty-state +9191 wpaw-empty-state-content +9193 wpaw-empty-state-icon +9210 wpaw-empty-state-button +9244 wpaw-empty-state-hint +9262 wpaw-focus-keyword-bar +9262 wpaw-expanded +9266 wpaw-fk-header +9271 wpaw-fk-collapse +9281 wpaw-fk-main-input +9284 wpaw-fk-custom-input +9311 wpaw-fk-suggestions +9314 wpaw-fk-suggestions-label +9322 wpaw-fk-suggestion-item +9324 selected +9329 wpaw-fk-radio +9334 wpaw-fk-suggestion-text +9339 wpaw-fk-suggestion-source +9348 wpaw-fk-stats +9358 wpaw-provider-info +9370 wpaw-fk-divider +9385 wpaw-compact +9388 wpaw-fk-left +9389 wpaw-fk-icon +9392 wpaw-fk-input +9417 wpaw-fk-cost +9423 wpaw-provider-badge +9435 wpaw-fk-expand +9489 wpaw-agent-workspace-card +9489 is-collapsed +9493 wpaw-agent-workspace-header +9496 wpaw-agent-workspace-heading +9499 wpaw-agent-workspace-kicker +9504 wpaw-agent-workspace-title +9510 wpaw-agent-workspace-actions +9514 wpaw-agent-workspace-status +9514 status-${activeWorkspaceStatus} +9523 wpaw-agent-context-grid +9526 wpaw-agent-context-item +9556 wpaw-agent-keyword-input +9598 wpaw-agent-resume-card +9973 wpaw-contextual-action +9976 wpaw-action-icon +9981 wpaw-action-content +10303 wpaw-message +10303 wpaw-message-user +10307 wpaw-message-content +10343 wpaw-ai-response +10352 complete +10355 inactive +10356 active +10372 wpaw-ai-item +10372 wpaw-timeline-entry +10375 is-current +10378 wpaw-timeline-dot +10383 wpaw-timeline-content +10386 wpaw-timeline-message +10393 wpaw-timeline-complete-row +10402 wpaw-timeline-complete +10407 wpaw-timeline-elapsed +10421 wpaw-inline-undo-btn +10452 wpaw-processing-indicator +10454 wpaw-dots-loader +10469 wpaw-typing-indicator +10475 wpaw-typing-dots +10555 wpaw-plan-card +10559 wpaw-plan-title +10564 wpaw-plan-config-summary +10568 wpaw-config-summary-item +10576 wpaw-plan-sections +10582 wpaw-plan-section +10582 pending +10582 done +10582 in_progress +10586 wpaw-plan-section-row +10588 wpaw-plan-section-check +10596 wpaw-plan-section-body +10599 wpaw-plan-section-title +10607 wpaw-plan-section-desc +10613 wpaw-plan-section-status +10633 wpaw-plan-actions +10676 wpaw-edit-plan +10680 wpaw-edit-plan-title +10685 wpaw-edit-plan-summary +10691 wpaw-edit-plan-preview-label +10697 wpaw-edit-plan-list +10703 wpaw-edit-plan-item +10708 wpaw-edit-plan-item-title +10718 wpaw-edit-plan-item-target +10746 wpaw-edit-plan-actions +10797 wpaw-message-error +10805 wpaw-error-title +10812 wpaw-error-detail +10854 wpaw-response +10858 wpaw-response-content +10884 wpaw-resume-actions +10923 wpaw-tab-content +10923 wpaw-config-tab +10927 wpaw-tab-header +10933 wpaw-config-section +10937 description +10952 wpaw-select +11093 wpaw-config-divider +11161 wpaw-meta-info +11168 good +11169 warning +11192 wpaw-spinning-icon +11210 wpaw-svg-wrapper +11226 wpaw-seo-audit +11229 wpaw-seo-audit-header +11285 wpaw-seo-audit-results +11289 wpaw-seo-score +11295 poor +11299 score-value +11304 score-label +11310 wpaw-seo-stats +11313 wpaw-seo-stat +11316 stat-label +11321 stat-value +11343 wpaw-seo-checks +11352 wpaw-seo-check +11354 passed +11354 failed +11358 check-icon +11363 check-label +11372 wpaw-seo-fix-button +11374 is-fixing +11465 wpaw-status-bar +11471 wpaw-status-indicator +11473 wpaw-status-dot +11477 wpaw-status-label +11486 wpaw-memanto-badge +11495 wpaw-status-actions +11499 wpaw-status-icon-btn +11499 wpaw-undo-btn +11499 has-undo +11512 is-active +11544 wpaw-workspace-toggle-btn +11592 wpaw-chat-tab +11596 wpaw-chat-container +11596 is-dimmed +11603 wpaw-editor-lock-banner +11609 wpaw-refinement-lock-banner +11616 wpaw-session-lock-banner +11627 wpaw-session-lock-takeover +11639 wpaw-health-notice +11670 wpaw-messages +11670 wpaw-activity-log +11674 wpaw-messages-inner +11687 wpaw-command-area +11695 wpaw-input-hint +11695 is-hidden +11707 wpaw-command-input-wrapper +11709 expanded +11713 wpaw-command-prefix +11718 wpaw-input +11758 wpaw-mention-autocomplete +11777 wpaw-mention-option +11877 wpaw-command-actions +11881 wpaw-command-actions-group +11903 wpaw-web-search-toggle +11905 wpaw-search-blocked +11931 wpaw-web-search-icon +11939 wpaw-web-search-label +11953 wpaw-command-circle-btn +11954 wpaw-stop-circle-btn +11955 is-stopping +11964 wpaw-stop-spinner +11972 wpaw-send-circle-btn +11986 wpaw-keyboard-hints +11989 wpaw-kbd +12062 ok +12062 danger +12083 wpaw-cost-tab +12089 wpaw-refresh-btn +12100 wpaw-cost-card +12103 wpaw-cost-stat +12107 wpaw-cost-value +12125 wpaw-cost-remaining +12137 wpaw-budget-section +12140 wpaw-budget-label +12156 wpaw-budget-bar +12158 wpaw-budget-fill +12167 wpaw-budget-warning +12176 wpaw-cost-history +12181 wpaw-cost-table-wrapper +12186 wpaw-cost-table +12285 wpaw-cost-footer +12293 wpaw-cost-settings-link +12338 wpaw-tab-content-wrapper +``` + +## Non-Render Class and Selector Inventory + +These names are not all sidebar `className` props, but they are still source-of-truth migration items. + +| Lines | Name | Required preservation | +| --- | --- | --- | +| 824, 828 | `wpaw-writing` | WordPress post-saving lock key. | +| 825, 829 | `wpaw-editor-locked` | Body class added/removed while writing lock is active. | +| 835, 838 | `wpaw-refining` | WordPress post-saving lock key. | +| 836, 839 | `wpaw-refining-locked` | Body class added/removed while refinement lock is active. | +| 895, 903, 916 | `wpaw-block-refining` | Editor block DOM class added/removed for refining blocks. | +| 933 | `.wpaw-sidebar` | Selector allowlist for editor input blocking. Preserve alongside `.wpaw-command-area` and `.wpaw-messages`. | +| 5262 | `wpaw-diff-removed` | Removed from block `className` during diff cleanup. | + +## Dynamic Class Expressions + +These expressions must be migrated as expressions, not flattened. + +| Lines | Expression behavior | +| --- | --- | +| 6075-6078, 6111-6114 | Append `wpaw-diff-removed` to editor block `className`. | +| 6085-6089, 6128-6129 | Append `wpaw-diff-added` to generated diff blocks. | +| 9152-9154 | Welcome chat pill adds `active`. | +| 9162-9164 | Welcome planning pill adds `active`. | +| 9322-9324 | Focus keyword suggestion item adds `selected`. | +| 9489 | Workspace card adds `is-collapsed`. | +| 9514 | Workspace status uses `status-${activeWorkspaceStatus}`. | +| 10372-10375 | Timeline entry combines `wpaw-ai-item wpaw-timeline-entry`, `statusClass`, and `is-current`. | +| 10582 | Plan section uses `section.status || "pending"`. | +| 11165-11169 | Meta character count uses `good` or `warning`. | +| 11289-11295 | SEO score uses `good`, `warning`, or `poor`. | +| 11352-11354 | SEO check uses `passed` or `failed`. | +| 11372-11374 | SEO fix button adds `is-fixing`. | +| 11473 | Status dot appends `agentStatus`. | +| 11510-11512 | Sessions icon button adds `is-active`. | +| 11527-11529 | Chat icon button adds `is-active`. | +| 11556-11558 | Config icon button adds `is-active`. | +| 11570-11572 | Cost icon button adds `is-active`. | +| 11596 | Chat container adds `is-dimmed`. | +| 11695 | Input hint adds `is-hidden`. | +| 11707-11709 | Command input wrapper adds `expanded`. | +| 11777-11779 | Mention autocomplete option adds `selected`. | +| 11838-11840 | Slash autocomplete option adds `selected`. | +| 11903-11905 | Web search toggle adds `wpaw-search-blocked`. | +| 11953-11955 | Stop button adds `is-stopping`. | +| 12129, 12158, 12167 | Cost/budget UI appends `budgetStatus`. | + +## Migration Acceptance Checklist + +- [ ] `sidebar.js` line ranges 1-12363 are represented in the migrated plan or monolith. +- [ ] The component starts from `AgenticWriterSidebar` line 38 and closes at line 12347. +- [ ] Final HOC/plugin registration lines 12349-12363 are represented separately. +- [ ] Every state/ref/effect in the coverage table exists in the same order. +- [ ] Every function in the coverage table exists under the same name. +- [ ] Every nested helper in the nested checklist exists. +- [ ] Every render surface in the render checklist exists with the same branch gates. +- [ ] Every class in the class inventory exists, including dynamic and editor block classes. +- [ ] Every endpoint in the endpoint inventory exists with the same request semantics. +- [ ] Every editor/browser side effect in the side-effect inventory exists. +- [ ] No refactor-only cleanup has been mixed into the first migration pass. diff --git a/SIDEBAR_1_TO_1_TASKLIST.md b/SIDEBAR_1_TO_1_TASKLIST.md new file mode 100644 index 0000000..ecdd64c --- /dev/null +++ b/SIDEBAR_1_TO_1_TASKLIST.md @@ -0,0 +1,296 @@ +# WP Agentic Writer Sidebar 1:1 Migration Tasklist + +**Source task plan:** `SIDEBAR_1_TO_1_MIGRATION.md` +**Source of truth:** `assets/js/sidebar.js` +**Mode:** planning/tasklist only. No implementation code, no build step, no inferred behavior. + +Use this tasklist to execute the migration described in `SIDEBAR_1_TO_1_MIGRATION.md`. Every checkbox must be completed against `assets/js/sidebar.js`, not memory. + +**Current status:** planning docs are in place and the abandoned React rebuild scaffold has been removed from `assets/js`. No build was run, no enqueue switch was made, and implementation now needs to restart from the migration plan rather than from a preexisting React target. + +## Ground Rules + +- [x] Confirm `assets/js/sidebar.js` is the current source of truth before starting. +- [x] Confirm `SIDEBAR_1_TO_1_MIGRATION.md` is open beside `assets/js/sidebar.js`. +- [x] Do not use `MIGRATION_GUIDE.md` as authority when it differs from `assets/js/sidebar.js`. +- [x] Do not rename functions during the first migration pass. +- [x] Do not extract helper files during the first migration pass. +- [x] Do not change visible text, labels, placeholders, icons, SVG markup, classes, inline styles, aria attributes, roles, or conditional render gates. +- [x] Do not replace `RawHTML`, markdown logic, stream handling, abort handling, localStorage keys, endpoint paths, request bodies, or Gutenberg APIs. +- [ ] Keep the first target as a monolithic JSX port. + +## Definition of Done for Each Range + +- [ ] Source range is copied or represented completely. +- [ ] `createElement` conversion keeps the same tag/component. +- [ ] Props are preserved 1:1. +- [ ] Children order is preserved 1:1. +- [ ] Conditional gates are preserved in the same branch position. +- [ ] State/ref/effect ordering is preserved. +- [ ] Callback boundaries and dependency arrays are preserved. +- [ ] Inline styles, string literals, titles, placeholders, labels, and SVG strings are preserved. +- [ ] Any migrated range is checked against the original source lines before moving on. + +## Phase 0 - Source Lock and Boundaries + +- [x] Verify `sidebar.js` has 12,363 lines. +- [x] Verify file header and IIFE boundary: lines 1-7 and 12363. +- [x] Verify dependency destructuring: lines 8-15. +- [x] Verify debug logger and `pluginIcon`: lines 16-35. +- [x] Verify `AgenticWriterSidebar` starts at line 38. +- [x] Verify `AgenticWriterSidebar` closes at line 12347. +- [x] Verify HOC/plugin boot remains separate: lines 12349-12363. +- [x] Verify main return starts at line 12307. +- [x] Record any source drift before implementation. If line numbers changed, regenerate this tasklist from the updated source. + +## Phase 1 - Monolith Skeleton + +- [ ] Create the migrated target as one monolithic sidebar component. +- [ ] Map every WordPress dependency from lines 8-15. +- [ ] Preserve `pluginIcon` behavior from lines 31-35. +- [ ] Preserve component prop shape: `AgenticWriterSidebar = ({ postId })`. +- [ ] Preserve `mapSelectToProps` behavior from lines 12349-12352. +- [ ] Preserve `ConnectedSidebar` behavior from lines 12355-12356. +- [ ] Preserve `registerPlugin("wp-agentic-writer")` behavior from lines 12358-12362. +- [ ] Do not split files yet. + +## Phase 2 - State, Refs, and Constants + +- [ ] Migrate settings and error formatting: lines 40-138. +- [ ] Migrate chat/top-level state: lines 139-149. +- [ ] Migrate session lock state and refs: lines 152-160. +- [ ] Migrate config defaults, config state, and config refs: lines 163-188. +- [ ] Migrate cost/provider state and provider metadata helper: lines 191-223. +- [ ] Migrate editor/refinement lock state and refs: lines 224-237. +- [ ] Migrate SEO audit state: lines 240-243. +- [ ] Migrate clarification, pending plan, and request refs: lines 246-268. +- [ ] Migrate active operation refs/state: lines 269-279. +- [ ] Migrate writing state: lines 280-289. +- [ ] Migrate workspace snapshot/collapse state and toggle: lines 290-321. +- [ ] Migrate mention/slash/input refs and state: lines 323-336. +- [ ] Migrate focus keyword state and persistence refs: lines 338-347. +- [ ] Migrate welcome state: lines 349-352. +- [ ] Migrate undo stack and max size: lines 354-356. +- [ ] Migrate Memanto restore state/ref: lines 358-366. +- [ ] Verify state/ref/hook order matches `sidebar.js` exactly. + +## Phase 3 - Effects, Saving, Timeline, and Editor Locks + +- [ ] Migrate agent mode reset effect: lines 367-371. +- [ ] Migrate post config load effect: lines 373-400. +- [ ] Migrate `savePostConfig`: lines 402-448. +- [ ] Migrate debounced post config effect: lines 449-473. +- [ ] Migrate cost tracking effect: lines 474-499. +- [ ] Migrate `normalizeWritingState`: lines 500-510. +- [ ] Migrate `saveWritingState`: lines 511-539. +- [ ] Migrate `persistWritingStatePatch`: lines 540-550. +- [ ] Migrate writing state load effect: lines 551-585. +- [ ] Migrate scroll refs/effect: lines 586-595. +- [ ] Migrate timeline regex/status constants and helpers: lines 596-673. +- [ ] Migrate active operation helpers: lines 674-728. +- [ ] Migrate refine-all confirmation callbacks: lines 729-752. +- [ ] Migrate undo snapshot helpers: lines 753-812. +- [ ] Migrate post saving lock effects: lines 813-841. +- [ ] Migrate editor input lock and DOM blocker effect: lines 842-981. +- [ ] Migrate text/config/keyword helpers and welcome start: lines 1020-1194. + +## Phase 4 - SEO, Workspace, Sessions, and Locks + +- [ ] Migrate `runSeoAudit`: lines 1195-1269. +- [ ] Migrate SEO fix instruction helpers: lines 1270-1348. +- [ ] Migrate `handleSeoAuditFix`: lines 1349-1459. +- [ ] Migrate `generateMetaDescription`: lines 1460-1563. +- [ ] Migrate block preview helpers: lines 1564-1599. +- [ ] Migrate workspace snapshot helper/effects: lines 1600-1668. +- [ ] Migrate beforeunload/session restore effects: lines 1669-1716. +- [ ] Migrate session storage sanitizing and hydration: lines 1717-1781. +- [ ] Migrate session message persistence: lines 1782-1889. +- [ ] Migrate session lock acquire/release/heartbeat/takeover: lines 1890-2026. +- [ ] Migrate lock/chat-history/post-session effects: lines 2027-2300. +- [ ] Migrate `loadPostSessions`: lines 2301-2397. +- [ ] Migrate `openSessionById`: lines 2398-2515. + +## Phase 5 - Mentions, Commands, Plans, and Agent Decisions + +- [ ] Migrate stream target and mention token helpers: lines 2516-2569. +- [ ] Migrate title refinement: lines 2570-2689. +- [ ] Migrate slash command parsing/options/block index: lines 2690-2758. +- [ ] Migrate target block resolution and insert refinement block: lines 2759-2870. +- [ ] Migrate plan streaming: lines 2871-3188. +- [ ] Migrate retry helpers: lines 3189-3473. +- [ ] Migrate plan block/preview helpers: lines 3474-3604. +- [ ] Migrate section block helpers and persistence: lines 3605-3696. +- [ ] Migrate plan task/target/matching/status/index helpers: lines 3697-3906. +- [ ] Migrate chat summary, intent detection, context, reset, plan message, keyword suggestion, and runtime helpers: lines 3907-4218. +- [ ] Migrate plan ID, intent classifier, and action decider: lines 4219-4320. + +## Phase 6 - Execution, Refinement, and Block Context + +- [ ] Migrate `executePlanFromCard`: lines 4321-4768. +- [ ] Migrate stop execution: lines 4769-4794. +- [ ] Migrate clear chat context: lines 4795-4870. +- [ ] Migrate serialized block creation: lines 4871-4953. +- [ ] Migrate block reformatting: lines 4954-5056. +- [ ] Migrate plan revision: lines 5057-5142. +- [ ] Migrate edit plan apply/cancel: lines 5143-5280. +- [ ] Migrate clarification context effect/helper: lines 5281-5327. +- [ ] Migrate duplicate heading removal: lines 5328-5362. +- [ ] Migrate refineable block/list helpers: lines 5363-5442. +- [ ] Migrate context block helpers: lines 5443-5520. +- [ ] Migrate slang/AI-slop detection helpers: lines 5521-5606. +- [ ] Migrate refinement diagnosis and block mention resolution: lines 5607-5799. +- [ ] Migrate `handleChatRefinement`: lines 5800-6388. +- [ ] Verify `wpaw-diff-added` and `wpaw-diff-removed` behavior survives unchanged. + +## Phase 7 - Chat Input and Main Async Flows + +- [ ] Migrate refine-all modal: lines 6389-6455. +- [ ] Migrate mention options: lines 6456-6579. +- [ ] Migrate custom insert-mention event effect: lines 6580-6612. +- [ ] Migrate input change/key handling: lines 6613-6701. +- [ ] Migrate mention and slash insertion helpers: lines 6702-6758. +- [ ] Migrate `sendMessage`: lines 6759-8056. +- [ ] Migrate `submitAnswers`: lines 8057-8476. +- [ ] Verify all stream readers, decoders, timeouts, active readers, and abort branches match the source. + +## Phase 8 - Render Surfaces + +- [ ] Migrate `renderClarification`: lines 8477-8829. +- [ ] Verify `renderSingleChoice`: lines 8486-8547. +- [ ] Verify `renderMultipleChoice`: lines 8550-8577. +- [ ] Verify `renderOpenText`: lines 8580-8597. +- [ ] Verify `renderConfigForm`: lines 8600-8723. +- [ ] Verify answer input switch: lines 8725-8742. +- [ ] Migrate conversation session actions: lines 8830-9004. +- [ ] Migrate `renderWelcomeScreen`: lines 9005-9184. +- [ ] Migrate `renderWritingEmptyState`: lines 9185-9253. +- [ ] Migrate `renderFocusKeywordBar`: lines 9254-9459. +- [ ] Migrate `renderAgentWorkspaceCard`: lines 9460-9629. +- [ ] Preserve `renderContextIndicator = renderAgentWorkspaceCard`: lines 9630-9632. +- [ ] Migrate `renderContextualAction`: lines 9633-9996. +- [ ] Migrate `renderMessages`: lines 9997-10917. +- [ ] Migrate `renderConfigTab`: lines 10918-11434. +- [ ] Migrate `getAgentStatus`: lines 11435-11448. +- [ ] Migrate `renderGlobalStatusBar`: lines 11449-11585. +- [ ] Migrate `renderChatTab`: lines 11586-12020. +- [ ] Migrate cost state/effect/helpers: lines 12021-12057. +- [ ] Migrate `renderCostTab`: lines 12058-12306. +- [ ] Migrate main component return tree: lines 12307-12346. + +## Phase 9 - Render Surface Element Audit + +- [ ] Refine modal: confirm dialog role, aria modal/label, overlay, modal, title, body, checkbox, cancel, continue. +- [ ] Clarification UI: confirm all question types, custom answer field, config fields, progress bar, previous/skip/next/finish behavior. +- [ ] Welcome UI: confirm recent session, older session details, open/delete buttons, keyword input, mode pills, start button. +- [ ] Writing empty state: confirm SVG icon, copy, create outline button, hint text. +- [ ] Focus keyword bar: confirm expanded/compact branches, suggestions, selected state, provider/cost display, expand/collapse. +- [ ] Workspace card: confirm collapsed state, status, context grid, keyword field, conversation/provider summary, resume card. +- [ ] Contextual action: confirm `create_outline` action, clarity check branch, generate-plan stream branch, action card. +- [ ] Messages: confirm markdown helpers, grouping, timeline, plan, edit plan, structured errors, retry buttons, default response, resume actions. +- [ ] Config tab: confirm every section, control, description, SEO controls, meta generation, audit score, check list, fix buttons. +- [ ] Status bar: confirm status dot, memory badge, undo, sessions, chat, workspace toggle, config, cost buttons. +- [ ] Chat tab: confirm lock banners, health notices, welcome/empty/workspace/activity gates, command area, hint, textarea, autocompletes, search toggle, stop/send, keyboard hints, modal. +- [ ] Cost tab: confirm header, refresh, cards, budget section, warning, action summary table, history table, footer link. +- [ ] Final shell: confirm menu item, sidebar title, icon, panel, tab wrapper, active tab branch. + +## Phase 10 - Class Inventory Audit + +- [ ] Verify every literal `className` token from `SIDEBAR_1_TO_1_MIGRATION.md` exists in the migrated target. +- [ ] Verify dynamic classes remain dynamic expressions. +- [ ] Verify `wpaw-diff-removed` append branch: lines 6075-6078 and 6111-6114. +- [ ] Verify `wpaw-diff-added` append branches: lines 6085-6089 and 6128-6129. +- [ ] Verify welcome pill `active` branches: lines 9152-9154 and 9162-9164. +- [ ] Verify focus suggestion `selected`: lines 9322-9324. +- [ ] Verify workspace `is-collapsed` and `status-${activeWorkspaceStatus}`: lines 9489 and 9514. +- [ ] Verify timeline `statusClass` and `is-current`: lines 10351-10375. +- [ ] Verify plan section `section.status || "pending"`: line 10582. +- [ ] Verify SEO/meta status classes: lines 11165-11374. +- [ ] Verify status-bar `is-active` branches: lines 11510-11572. +- [ ] Verify chat input classes: lines 11596-11955. +- [ ] Verify budget status classes: lines 12129, 12158, and 12167. + +## Phase 11 - Non-Render Class and Selector Audit + +- [ ] Preserve WordPress lock key `wpaw-writing`: lines 824 and 828. +- [ ] Preserve body class `wpaw-editor-locked`: lines 825 and 829. +- [ ] Preserve WordPress lock key `wpaw-refining`: lines 835 and 838. +- [ ] Preserve body class `wpaw-refining-locked`: lines 836 and 839. +- [ ] Preserve editor block class `wpaw-block-refining`: lines 895, 903, and 916. +- [ ] Preserve input-blocking selector `.wpaw-sidebar, .wpaw-command-area, .wpaw-messages`: line 933. +- [ ] Preserve diff cleanup removal of `wpaw-diff-removed`: line 5262. + +## Phase 12 - Endpoint and Integration Audit + +- [ ] Verify `/post-config/${postId}` calls. +- [ ] Verify `/cost-tracking/${postId}` calls. +- [ ] Verify `/writing-state/${postId}` calls. +- [ ] Verify `/seo-audit/${postId}` call. +- [ ] Verify `/generate-meta` call. +- [ ] Verify all conversation endpoints. +- [ ] Verify `/conversation/${postId}` and `/conversation/${data.post_id}` calls. +- [ ] Verify `/chat-history/${postId}` call. +- [ ] Verify `/memanto/restore?post_id=${postId}` call. +- [ ] Verify `/refine-title` call. +- [ ] Verify all `/generate-plan` calls. +- [ ] Verify all `/chat` calls. +- [ ] Verify `/section-blocks/${postId}` and `/section-blocks` calls. +- [ ] Verify `/summarize-context` call. +- [ ] Verify `/detect-intent` call. +- [ ] Verify `/clear-context` call. +- [ ] Verify `/suggest-keywords` call. +- [ ] Verify `/execute-article` call. +- [ ] Verify `/reformat-blocks` call. +- [ ] Verify `/revise-plan` call. +- [ ] Verify `/refine-from-chat` call. +- [ ] Verify `/check-clarity` calls. +- [ ] For every endpoint, verify method, nonce header, content type, body shape, stream/non-stream handling, provider metadata, cost updates, and error handling. + +## Phase 13 - Gutenberg and Browser Side Effects Audit + +- [ ] Verify all `select("core/block-editor")` calls. +- [ ] Verify all `dispatch("core/block-editor")` calls. +- [ ] Verify all `select("core/editor")` calls. +- [ ] Verify all `dispatch("core/editor")` calls. +- [ ] Verify `wp.data.subscribe` behavior. +- [ ] Verify `wp.data.withSelect` behavior. +- [ ] Verify localStorage keys: `wpaw_agent_workspace_collapsed` and `wpawSessionId_${postId}`. +- [ ] Verify beforeunload handlers. +- [ ] Verify global document event listeners and cleanups. +- [ ] Verify window `wpaw:insert-mention` listener and cleanup. +- [ ] Verify lock heartbeat interval setup and cleanup. +- [ ] Verify debounced config/message/keyword saves. +- [ ] Verify `AbortController` lifecycle. +- [ ] Verify stream reader lifecycle and active reader cancellation. +- [ ] Verify `TextDecoder` usage. + +## Phase 14 - Final Parity Audit + +- [ ] Confirm no functions are missing from `SIDEBAR_1_TO_1_MIGRATION.md`. +- [ ] Confirm no state/ref/effect entries are missing. +- [ ] Confirm no render surface entries are missing. +- [ ] Confirm no class inventory entries are missing. +- [ ] Confirm no dynamic class expressions were flattened. +- [ ] Confirm no endpoint inventory entries are missing. +- [ ] Confirm no editor/browser side effects are missing. +- [ ] Confirm final plugin registration still renders `ConnectedSidebar`. +- [ ] Confirm no optional extraction was performed before monolith parity. +- [ ] Confirm any future extraction task references the source line range it moves. + +## Optional Phase 15 - Extraction After Monolith Parity Only + +- [ ] Extract only one helper group at a time. +- [ ] Before extraction, record source range and destination file. +- [ ] Move code without renaming public/internal symbols. +- [ ] Preserve imports/dependencies exactly. +- [ ] Re-run the same parity checks for the moved range. +- [ ] Do not extract render surfaces until all behavior helpers are proven equivalent. +- [ ] Do not delete the monolith source range until the moved range is checked line-by-line. + +## Stop Conditions + +- [ ] Stop if `sidebar.js` changes and this tasklist has not been regenerated. +- [ ] Stop if a migrated range requires guessing. +- [ ] Stop if a function seems unused but exists in `sidebar.js`. +- [ ] Stop if a class appears styling-only but exists in `sidebar.js`. +- [ ] Stop if an endpoint or request body differs from `sidebar.js`. +- [ ] Stop if hook order would change. diff --git a/views/settings/tab-general.php b/views/settings/tab-general.php index faefa1b..f8940b0 100644 --- a/views/settings/tab-general.php +++ b/views/settings/tab-general.php @@ -66,7 +66,15 @@ if ( $ai_client_available ) { *
- OpenRouter ', 'wp-agentic-writer' ) ), 'https://openrouter.ai/keys' ); ?> + OpenRouter ', + "wp-agentic-writer", + ), + ), + "https://openrouter.ai/keys", + ); ?>