Step 4 of phase 2 of the `App.tsx` decomposition — see #2129 for the phase, #2126 for the whole effort. **This is a stacked PR.** Its branch is cut from step 3's and its PR targets that branch, not `v2/main`. Do not land it before step 3. ## Scope — `useServerCommands(session, oauth, stores)`, ~530 lines - `onCallTool`, `onClearToolResult`, `onToolsUiChange` - `onGetPrompt`, `onReadResource`, `onReadResourceContents`, `onSubscribeResource`, `onUnsubscribeResource`, `onCompleteArgument` - `onCancelTask`, `onCancelToolCall`, `onClearCompletedTasks`, `onSetLogLevel`, `onSetModernLogLevel` - the refresh and load-more callbacks - `onTogglePaginatedLists` (~135 lines on its own) - `toolCallState`, `getPromptState`, `readResourceState` Every one of these routes through `runWithCommandAuthRecovery` from step 2. That wrapper is the reason this cluster cannot precede the OAuth one. ## Constraints carried from #2129 - ⚠️ **#2095's pagination-toggle behavior lives in `onTogglePaginatedLists` / `paginatedListsOverride`. Do not change it here.** Land the move inert; anything further goes on top, because a behavior change buried in a 135-line relocation is unreviewable. - No behavior change. ## Done when - [ ] `useServerCommands` is its own hook - [ ] ≥90% on all four coverage dimensions - [ ] `npm run ci` green, all three web smokes included
Activity
chore(web): address Copilot review on #2155
chore(web): extract App.tsx's server commands into useServerCommands