Surface workspace changes from agent panes (#3682)

* feat(app): refine workspace pane actions

Prioritize Changes when available, keep Files useful before a selection, and reserve desktop diff clicks for selection so comments require the explicit affordance. Move the Changes shortcut to Shift+G to avoid consuming a likely copy variant.

* feat(app): improve access to workspace changes
This commit is contained in:
Mohamed Boudra
2026-08-22 12:20:21 +02:00
committed by GitHub
parent b1455fb4b3
commit 3029b5991a
31 changed files with 527 additions and 66 deletions
+42 -15
View File
@@ -1,6 +1,6 @@
import { Text, View } from "react-native";
import { FolderTree } from "lucide-react-native";
import { withUnistyles } from "react-native-unistyles";
import { StyleSheet, withUnistyles } from "react-native-unistyles";
import { useCallback } from "react";
import { useTranslation } from "react-i18next";
import invariant from "tiny-invariant";
@@ -9,14 +9,11 @@ import { usePaneContext } from "@/panels/pane-context";
import type { PanelRegistration } from "@/panels/panel-registry";
import { useAddFileToChat } from "@/panels/use-add-file-to-chat";
import { useWorkspaceDirectory } from "@/stores/session-store-hooks";
import { TreeRail } from "@/components/tree-rail";
import { useIsCompactFormFactor } from "@/constants/layout";
const ThemedFolderTree = withUnistyles(FolderTree);
const CENTERED_PADDED_STYLE = {
flex: 1,
alignItems: "center",
justifyContent: "center",
padding: 16,
} as const;
const FILE_TREE_WIDTH = 220;
function useFilesPanelDescriptor() {
const { t } = useTranslation();
@@ -35,6 +32,7 @@ function FilesPanel() {
const { serverId, workspaceId, target, retargetCurrentTab } = usePaneContext();
const workspaceRoot = useWorkspaceDirectory(serverId, workspaceId);
const { addFile, canAddToChat } = useAddFileToChat({ serverId, workspaceId });
const isCompact = useIsCompactFormFactor();
invariant(target.kind === "files", "FilesPanel requires files target");
const onOpenFile = useCallback(
(path: string) => retargetCurrentTab({ kind: "file", path }),
@@ -42,19 +40,35 @@ function FilesPanel() {
);
if (!workspaceRoot) {
return (
<View style={CENTERED_PADDED_STYLE}>
<View style={styles.centerState}>
<Text>{t("panels.file.directoryMissing")}</Text>
</View>
);
}
if (isCompact) {
return (
<FileExplorerPane
serverId={serverId}
workspaceId={workspaceId}
workspaceRoot={workspaceRoot}
onOpenFile={onOpenFile}
onAddToChat={canAddToChat ? addFile : undefined}
/>
);
}
return (
<FileExplorerPane
serverId={serverId}
workspaceId={workspaceId}
workspaceRoot={workspaceRoot}
onOpenFile={onOpenFile}
onAddToChat={canAddToChat ? addFile : undefined}
/>
<TreeRail testID="files-tree-rail" width={FILE_TREE_WIDTH}>
<View style={styles.centerState}>
<Text style={styles.emptyText}>{t("panels.files.chooseFile")}</Text>
</View>
<FileExplorerPane
serverId={serverId}
workspaceId={workspaceId}
workspaceRoot={workspaceRoot}
onOpenFile={onOpenFile}
onAddToChat={canAddToChat ? addFile : undefined}
/>
</TreeRail>
);
}
@@ -64,3 +78,16 @@ export const filesPanelRegistration: PanelRegistration<"files"> = {
component: FilesPanel,
useDescriptor: useFilesPanelDescriptor,
};
const styles = StyleSheet.create((theme) => ({
centerState: {
flex: 1,
alignItems: "center",
justifyContent: "center",
padding: theme.spacing[4],
},
emptyText: {
color: theme.colors.foregroundMuted,
fontSize: theme.fontSize.base,
},
}));