React.memo blocks root.render() re-renders when props are unchanged,
so storeState task updates were invisible to the memoized component.
Switch useStore mock to a subscription model (useState + useEffect)
so notifyStoreUpdate() forces a proper re-render in the expansion test.
- Guard `run.progress` before calling `retainProvisioningProgress` in
`TeamProvisioningService.cleanupRun` — test mocks omit the field,
causing 4 crashes with "Cannot read properties of undefined (reading
'warnings')".
- Invalidate the `TeamConfigReader` list-teams cache immediately after a
successful team launch so `GET /api/teams` returns the fully-created
team (no `pendingCreate`) rather than a 5-second-stale entry from
before `config.json` was written.
- Gate TeamListView dialogs with showCreateDialog/launchDialogOpen
- Gate SchedulesView and ScheduleSection lazy dialogs with dialogOpen
- Fix import order in SchedulesView (import type before lazy constant)
- Add Show raw toggle button to MarkdownViewer rendered view
- Fix react/display-name in DisplayItemList, MarkdownViewer, SessionItem,
SidebarTaskItem, TeamDetailView, TeamListView, KanbanBoard, GlobalTaskList,
MemberCard, TaskRow — all anonymous arrows inside memo() replaced with
named function form
- Fix simple-import-sort violations in TeamDetailView, TeamListView,
SchedulesView, ScheduleSection — static imports moved before lazy() consts
- Gate all lazy dialogs in TeamDetailView by their open flag so dynamic
import() only fires when the dialog is actually opened:
launchDialogOpen, createTaskDialog.open, sendDialogOpen,
selectedTask !== null, reviewDialogState.open
These are the most expensive render components (syntax highlighting, diff
computation) — memoizing them prevents re-renders when parent tool items
toggle expand/collapse or parent chat group updates.
Wraps BaseItem, StatusDot, MetricsPill, LinkedToolItem, TeammateMessageItem,
SlashItem, all linkedTool viewers (Default/Edit/Read/Skill/Write/ToolError,
CollapsibleOutputSection), CollapsibleTeamSection, and TaskTooltip in
React.memo to prevent unnecessary re-renders when chat history updates.
Extract per-member rendering into a memo'd MemberCardRow component with
useCallback handlers, so MemberCard never re-renders from new inline
lambda references when MemberList re-renders for an unrelated member.
Move toggleSidebarSessionSelection into SessionItem's own store
subscription, eliminating the inline arrow function prop that was
breaking its memo on every sidebar render.
Lazy-load LaunchTeamDialog (2918L) and CreateTeamDialog (2208L) in all
four host components (TeamDetailView, TeamListView, SchedulesView,
ScheduleSection). These dialogs are never needed at initial mount — they
only open on user action. Deferring their parse/compile saves ~175KB of
JS from the initial render path.
Wrap SessionItem, SubagentItem, ExecutionTrace, TextItem, ThinkingItem,
and DisplayItemList in React.memo. These components render repeatedly in
virtualized lists and AI chat groups — memoizing them eliminates redundant
renders when their props have not changed, reducing CPU work in active
sessions with many messages or long session sidebars.
TeamDetailView (3166L), TeamListView (1180L), DateGroupedSessions (1117L),
and MarkdownViewer (1198L) were re-rendering on every parent render cycle.
Wrapping them in memo() prevents cascading re-renders when their props and
store subscriptions have not changed, targeting VSCode-level UI responsiveness.
- TeamProvisioningServiceRelay: add missing stat fields (mode, dev, ino,
mtimeMs, ctimeMs, birthtimeMs) to fs mock so new fingerprint-based
TeamConfigReader cache can read config in tests
- TeamMcpConfigBuilder: export clearResolvedNodePathForTests() to reset
module-level node path cache between tests; restore execFileMock
implementation in beforeEach after vi.restoreAllMocks() clears it;
broaden node binary regex to accept versioned names (node-22, node-20)
common on Fedora/RHEL systems
- ScheduledTaskExecutor: strip CLAUDECODE at spawn site as last defence
so nested-session detection is prevented even when buildProviderAwareCliEnv
merges it back in from the outer process environment