ui/goose2/ui_improvements/state_management/phase-1-selector-cleanup.md
Phase 1: Remove Whole-Store Subscriptions
Status
Goal
Scope
ui/goose2/src/app/AppShell.tsxui/goose2/src/features/sidebar/ui/Sidebar.tsxui/goose2/src/features/agents/hooks/usePersonas.tsui/goose2/src/features/chat/hooks/useChat.tsOut Of Scope
persist.Execution Steps
Establish the current baseline.
rg "use[A-Za-z0-9]+Store\\(\\)" ui/goose2/src.Refactor AppShell.tsx.
useChatStore() with selectors for only the used fields/actions.useChatSessionStore() with selectors for only the used fields/actions.useAgentStore() with selectors for only the used fields/actions.useProjectStore() with selectors for only the used fields/actions.useStore.getState() inside async callbacks where the code intentionally needs latest state at call time.Refactor Sidebar.tsx.
useChatStore() with selectors for messagesBySession and any action/helper actually needed during render.useChatSessionStore() broad destructuring with selectors.useAgentStore() and useProjectStore() broad reads with targeted selectors or narrow getState() usage in callbacks.Refactor usePersonas.ts.
const store = useAgentStore() with selected actions/state.useAgentStore.getState() explicitly.Refactor useChat.ts.
const store = useChatStore() with selectors for session-specific messages/runtime and selected actions.getState() where callbacks intentionally read current runtime state.Validation
rg "use[A-Za-z0-9]+Store\\(\\)" ui/goose2/srccd ui/goose2 && pnpm test -- useChat usePersonas SidebarSuccess Criteria