WIP: workspace execution refactor + notification routing + setup store updates

This commit is contained in:
Mohamed Boudra
2026-04-01 21:28:07 +07:00
parent d8243bfb72
commit a7d5ab2497
29 changed files with 1064 additions and 197 deletions
+29 -15
View File
@@ -1,6 +1,6 @@
import { useQuery } from "@tanstack/react-query";
import { Terminal } from "lucide-react-native";
import { View } from "react-native";
import { Text, View } from "react-native";
import { useIsFocused } from "@react-navigation/native";
import invariant from "tiny-invariant";
import type { ListTerminalsResponse } from "@server/shared/messages";
@@ -8,6 +8,7 @@ import { TerminalPane } from "@/components/terminal-pane";
import { usePaneContext } from "@/panels/pane-context";
import type { PanelDescriptor, PanelRegistration } from "@/panels/panel-registry";
import { useSessionStore } from "@/stores/session-store";
import { getWorkspaceExecutionAuthority } from "@/utils/workspace-execution";
type ListTerminalsPayload = ListTerminalsResponse["payload"];
@@ -24,18 +25,22 @@ function useTerminalPanelDescriptor(
context: { serverId: string; workspaceId: string },
): PanelDescriptor {
const client = useSessionStore((state) => state.sessions[context.serverId]?.client ?? null);
const workspaceDirectory = useSessionStore(
(state) =>
state.sessions[context.serverId]?.workspaces.get(context.workspaceId)?.workspaceDirectory ??
state.sessions[context.serverId]?.workspaces.get(context.workspaceId)?.projectRootPath ??
null,
);
const workspaces = useSessionStore((state) => state.sessions[context.serverId]?.workspaces);
const workspaceAuthority = getWorkspaceExecutionAuthority({
workspaces,
workspaceId: context.workspaceId,
});
const workspaceDirectory = workspaceAuthority.ok
? workspaceAuthority.authority.workspaceDirectory
: null;
const terminalsQuery = useQuery({
queryKey: ["terminals", context.serverId, workspaceDirectory] as const,
enabled: Boolean(client && workspaceDirectory),
queryFn: async (): Promise<ListTerminalsPayload> => {
if (!client || !workspaceDirectory) {
return { cwd: workspaceDirectory ?? "", terminals: [], requestId: "missing-client" };
throw new Error(
workspaceAuthority.ok ? "Workspace execution directory not found" : workspaceAuthority.message,
);
}
return client.listTerminals(workspaceDirectory);
},
@@ -56,18 +61,27 @@ function useTerminalPanelDescriptor(
function TerminalPanel() {
const isFocused = useIsFocused();
const { serverId, workspaceId, target, isPaneFocused } = usePaneContext();
const workspaceDirectory = useSessionStore(
(state) =>
state.sessions[serverId]?.workspaces.get(workspaceId)?.workspaceDirectory ??
state.sessions[serverId]?.workspaces.get(workspaceId)?.projectRootPath ??
null,
);
const workspaces = useSessionStore((state) => state.sessions[serverId]?.workspaces);
const workspaceAuthority = getWorkspaceExecutionAuthority({ workspaces, workspaceId });
const workspaceDirectory = workspaceAuthority.ok
? workspaceAuthority.authority.workspaceDirectory
: null;
invariant(target.kind === "terminal", "TerminalPanel requires terminal target");
if (!isFocused || !workspaceDirectory) {
if (!isFocused) {
return <View style={{ flex: 1 }} />;
}
if (!workspaceDirectory) {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center", padding: 16 }}>
<Text>
{workspaceAuthority.ok ? "Workspace execution directory not found." : workspaceAuthority.message}
</Text>
</View>
);
}
return (
<TerminalPane
serverId={serverId}