fix(app): reduce workspace screen re-renders and fix archived agent handling

Replace greedy agents Map subscription with a Zustand selector that
derives workspace agent visibility (ID sets only) with custom equality,
so the workspace screen only re-renders when agents are added, removed,
or archived — not on every status/activity update.

Fix tab pruning to check against all known agents (including archived)
instead of only active agents, so archived agent tabs survive
reconciliation. Remove the auto-unarchive effect that called
refreshAgent() as a workaround. Hide input area for archived agents.
This commit is contained in:
Mohamed Boudra
2026-03-20 21:07:51 +07:00
parent 72ea9b7a72
commit 48924626df
4 changed files with 95 additions and 152 deletions
@@ -1,4 +1,5 @@
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useStoreWithEqualityFn } from "zustand/traditional";
import { useIsFocused } from "@react-navigation/native";
import {
ActivityIndicator,
@@ -96,6 +97,7 @@ import {
import {
deriveWorkspaceAgentVisibility,
shouldPruneWorkspaceAgentTab,
workspaceAgentVisibilityEqual,
} from "@/screens/workspace/workspace-agent-visibility";
import {
deriveWorkspacePaneState,
@@ -582,18 +584,15 @@ function WorkspaceScreenContent({
const client = useHostRuntimeClient(normalizedServerId);
const isConnected = useHostRuntimeIsConnected(normalizedServerId);
const sessionAgents = useSessionStore(
(state) => state.sessions[normalizedServerId]?.agents
);
const workspaceAgentVisibility = useMemo(
() =>
const workspaceAgentVisibility = useStoreWithEqualityFn(
useSessionStore,
(state) =>
deriveWorkspaceAgentVisibility({
sessionAgents,
sessionAgents: state.sessions[normalizedServerId]?.agents,
workspaceId: normalizedWorkspaceId,
}),
[normalizedWorkspaceId, sessionAgents]
workspaceAgentVisibilityEqual,
);
const workspaceAgents = workspaceAgentVisibility.visibleAgents;
const terminalsQueryKey = useMemo(
() => ["terminals", normalizedServerId, normalizedWorkspaceId] as const,
@@ -823,8 +822,6 @@ function WorkspaceScreenContent({
return () => handler.remove();
}, [closeToAgent, isExplorerOpen]);
const agentsById = workspaceAgentVisibility.lookupById;
const persistenceKey = useMemo(
() =>
buildWorkspaceTabPersistenceKey({
@@ -853,7 +850,6 @@ function WorkspaceScreenContent({
const reorderWorkspaceTabsInPane = useWorkspaceLayoutStore((state) => state.reorderTabsInPane);
const pendingByDraftId = useCreateFlowStore((state) => state.pendingByDraftId);
const consumedOpenIntentsRef = useRef(new Set<string>());
const reopenedArchivedOpenIntentsRef = useRef(new Set<string>());
const pendingCloseTabIdsRef = useRef(new Set<string>());
const [resolvedOpenIntentKey, setResolvedOpenIntentKey] = useState<string | null>(null);
const currentOpenIntentKey = useMemo(
@@ -957,43 +953,6 @@ function WorkspaceScreenContent({
}
}, [currentOpenIntentKey, resolvedOpenIntentKey]);
useEffect(() => {
if (!client || !isConnected || openIntent?.kind !== "agent" || !currentOpenIntentKey) {
return;
}
const agentId = openIntent.agentId.trim();
if (!agentId) {
return;
}
if (reopenedArchivedOpenIntentsRef.current.has(currentOpenIntentKey)) {
return;
}
const agent = agentsById.get(agentId) ?? null;
if (!agent?.archivedAt) {
return;
}
reopenedArchivedOpenIntentsRef.current.add(currentOpenIntentKey);
void client.refreshAgent(agentId).catch((error) => {
console.warn("[WorkspaceScreen] Failed to reopen archived agent", {
serverId: normalizedServerId,
workspaceId: normalizedWorkspaceId,
agentId,
error,
});
});
}, [
agentsById,
client,
currentOpenIntentKey,
isConnected,
normalizedServerId,
normalizedWorkspaceId,
openIntent,
]);
useEffect(() => {
if (!openIntent || !persistenceKey) {
return;
@@ -1075,12 +1034,12 @@ function WorkspaceScreenContent({
return pending?.serverId === normalizedServerId && pending.lifecycle === "active";
});
for (const agent of workspaceAgents) {
for (const agentId of workspaceAgentVisibility.activeAgentIds) {
const representedByTarget = uiTabs.some(
(tab) => tab.target.kind === "agent" && tab.target.agentId === agent.id
(tab) => tab.target.kind === "agent" && tab.target.agentId === agentId
);
const representedByDeterministicTabId = uiTabs.some(
(tab) => tab.tabId === `agent_${agent.id}`
(tab) => tab.tabId === `agent_${agentId}`
);
if (
hasActivePendingDraftCreateInWorkspace &&
@@ -1089,7 +1048,7 @@ function WorkspaceScreenContent({
) {
continue;
}
ensureWorkspaceTab({ kind: "agent", agentId: agent.id });
ensureWorkspaceTab({ kind: "agent", agentId });
}
for (const terminal of terminals) {
ensureWorkspaceTab({ kind: "terminal", terminalId: terminal.id });
@@ -1104,7 +1063,7 @@ function WorkspaceScreenContent({
shouldPruneWorkspaceAgentTab({
agentId: tab.target.agentId,
agentsHydrated: hasHydratedAgents,
workspaceAgentLookup: agentsById,
knownAgentIds: workspaceAgentVisibility.knownAgentIds,
})
) {
closeWorkspaceTab(persistenceKey, tab.tabId);
@@ -1126,7 +1085,7 @@ function WorkspaceScreenContent({
terminals,
terminalsQuery.isSuccess,
uiTabs,
workspaceAgents,
workspaceAgentVisibility,
]);
const activeTabId = resolvedPaneTabState.activeTabId;
@@ -1180,7 +1139,7 @@ function WorkspaceScreenContent({
emptyWorkspaceSeedRef.current = null;
return;
}
if (workspaceAgents.length > 0 || terminals.length > 0) {
if (workspaceAgentVisibility.activeAgentIds.size > 0 || terminals.length > 0) {
emptyWorkspaceSeedRef.current = null;
return;
}
@@ -1202,7 +1161,7 @@ function WorkspaceScreenContent({
persistenceKey,
terminals.length,
tabs.length,
workspaceAgents.length,
workspaceAgentVisibility.activeAgentIds.size,
]);
const handleOpenFileFromExplorer = useCallback(
@@ -1485,7 +1444,7 @@ function WorkspaceScreenContent({
const handleCopyResumeCommand = useCallback(
async (agentId: string) => {
if (!agentId) return;
const agent = sessionAgents?.get(agentId) ?? null;
const agent = useSessionStore.getState().sessions[normalizedServerId]?.agents?.get(agentId) ?? null;
const providerSessionId =
agent?.runtimeInfo?.sessionId ?? agent?.persistence?.sessionId ?? null;
if (!agent || !providerSessionId) {
@@ -1510,7 +1469,7 @@ function WorkspaceScreenContent({
toast.error("Copy failed");
}
},
[sessionAgents, toast]
[normalizedServerId, toast]
);
const handleCopyWorkspacePath = useCallback(async () => {