feat(web): add toggleable confirmation before unpinning a thread - #7313
UI Consistency: No issues found
All clear
Details
Note
Your check run agent prompt is: .macroscope/check-run-agents/ui-consistency.md
More information about how Check Run Agents work can be found in our Help Center.
Reviewed the in-scope web UI changes (apps/web/src/hooks/useThreadActions.ts, useThreadActionMenu.ts, components/Sidebar.tsx, components/ChatView.tsx, components/settings/SettingsPanels.tsx, components/settings/settingsSearch.ts).
Both findings from earlier runs are resolved at head 08c0935:
requestThreadUnpinConfirmationnow degrades likeconfirmAndDeleteThread— it falls back toresolved?.thread.title ?? "this thread"and skips only the dialog when the local api is unavailable, so the preference can no longer produce a dead click.- "Unpin confirmation" is included in
changedSettingLabels(and its dependency array) alongside the reset inrestoreDefaults, and theunpin-confirmationcatalog entry now precedesarchive-confirmation/delete-confirmation, matching the rendered panel order.
Other checks: all web unpin dispatch sites (sidebar pin marker, sidebar context menu, chat header action menu, mod+shift+p shortcut) route through confirmAndUnpinThread; the new settings row composes the shared SettingsRow/Switch/SettingResetButton primitives with an aria-label consistent with its neighbors; no Tailwind/global CSS, scroll/mask, or environment-routing surfaces were touched.
🔍 Agent activity — 15 tool calls
💭 I'm checking the current PR state at commit 08c0935 to see if prior review findings were addressed, looking specifically at the settings search test ordering and the catalog entry placement, plus whether the thread unpin confirmation now degrades gracefully.
1. browse_code — apps/web/src/components/settings/settingsSearch.ts
2. browse_code — apps/web/src/hooks/useThreadActions.ts
💭 I want to confirm the row ordering matches between the catalog and settings panels, so I'm checking SettingsPanels around lines 2300-2400 to verify unpin sits above archive/delete there too.
3. browse_code — apps/web/src/components/settings/SettingsPanels.tsx
4. browse_code — apps/web/src/components/settings/SettingsPanels.tsx
💭 With both prior findings resolved, I want to compare confirmAndUnpinThread against the confirmAndDeleteThread pattern around line 600-680, and verify the ChatView keyboard shortcut path handles cancellation correctly by returning success(undefined) with no toast, matching the Sidebar's unpin behavior. I should also check whether the dialog uses a "destructive" variant and whether it relies on a shared confirmation helper like localApi.dialogs.confirm, plus whether there's a separate inline "confirmThreadArchive" pattern that uses a second-click instead of a dialog. I'll scan useThreadActions from lines 400-780 to compare these approaches.
5. browse_code — apps/web/src/hooks/useThreadActions.ts
💭 The delete pattern now matches, so I'm moving on to check other call sites for consistency—like the mod+shift+p shortcut in ChatView, which uses confirmAndUnpinThread correctly, and now I want to check the sidebar's unpin control to see if it's an inline hover action or something else, plus look for any other unpinThread call sites that might've been missed. I should grep for unpinThread across apps/web to catch any pinned section headers, drag-out gestures, or context menus that might not be migrated, which would create inconsistent confirmation behavior.
6. git_tools — unpinThread|confirmAndUnpinThread|unpin
💭 I noticed the sidebar has a pin marker button that can unpin threads when the server supports pinning, so I should check the relevant sidebar code sections around lines 700-780, 2600-2730, and 3190-3210 to trace all the unpin paths.
7. browse_code — apps/web/src/components/Sidebar.tsx
8. browse_code — apps/web/src/components/Sidebar.tsx
💭 I'm checking the pin marker button in SidebarThreadRow to see if it shows a pending state, then looking at the bulk unpin case in the multi-select actions to see how that path handles it.
9. browse_code — apps/web/src/components/Sidebar.tsx
10. browse_code — apps/web/src/hooks/useThreadActionMenu.ts
💭 I notice the unpin case now calls confirmAndUnpinThread from the native context menu, and the added braces around that case are harmless. The archive/delete confirmations still use the native dialog API separately, which seems fine. Now I'm checking consistency questions: delete uses a destructive variant while archive and unpin don't, which seems intentional given their severity. I want to verify whether there's a bulk unpin action in the sidebar's multi-select toolbar, and whether the keyboard shortcut for toggling pin interacts correctly with the new confirmation dialog. I'm also confirming the settings row order matches the catalog and checking whether the ChatView header has a separate pin button (beyond the keyboard shortcut) that might not have been migrated to use the same confirmation flow.
11. git_tools — pinThread|pinned|togglePin
💭 With all the unpin call sites migrated, I'm double-checking the confirmation logic — verifying that both
confirmAndUnpinThreadand the delete flow correctly call the local API before confirming, and examining an edge case whererequestThreadUnpinConfirmationreturns success even whenconfirmis null. This mirrors delete's fallthrough behavior when confirmation is skipped, so it's consistent. I'm also confirming the settings row description text, aria-label, and that the unpin/archive/delete ordering matches the searchable settings catalog for the search feature, checking if keyword matching like "confirmation" or "quit" resolves correctly against titles.
12. browse_code — apps/web/src/components/settings/settingsSearch.ts
13. browse_code — apps/web/src/components/settings/settingsSearch.ts
💭 Everything looks consistent, so I'm checking if there's anything else in scope, like the sidebar pin marker's unpin path and whether the confirmation dialog interacts oddly with thread activation clicks—nothing new there. I'm now considering drag interactions next. I'm checking whether the module-scope imports and hook dependencies for the unpin confirmation flow are all correctly wired—
settlePromise,AsyncResult, and theconfirmAndUnpinThreaddependency array all look complete. I notice the rawunpinThreadexport is no longer consumed externally after migration, but that's a minor dead-API concern rather than a UI consistency issue. Having both raw and confirming variants (unpinThread/confirmAndUnpinThread) actually mirrors the existing deleteThread/confirmAndDeleteThread pattern, where deleteThread is still used raw elsewhere, so this isn't worth flagging. The new SettingsRow uses SettingsRow, Switch, and SettingResetButton consistently with its neighbors, and the documentedmod+shift+pshortcut matches ChatView's actual behavior. I'm now checking whether there's a separate pin toggle button in the chat header that might call a different, inconsistent handler. I should search more broadly for "Unpin" usage across other components like ThreadHeader, CommandPalette, or the keybindings registry, since my earlier grep only surfaced the context menu.
14. git_tools — [Uu]npin
15. git_tools — threadEnvironment.unpin
💭 All web call sites are covered, and mobile is out of scope. I checked the sidebar pin marker button code and confirmed it's unchanged, so no interaction regression there. Both prior findings were addressed, so I'm confident there's nothing new to report. Since the response requires the JSON schema, I'll set the status to success and put "All clear" in the summary field with a plain title, rather than trying to make the whole response just those two words.
Agent Credits: 88 credits
Token usage: 20 uncached input · 424,848 cache-read input · 70,728 cache-write input · 7,089 output
Agent Credits may also include non-token charges from external tools such as web research.