Skip to content

Commit 6731076

Browse files
jonathanlabclaude
andcommitted
feat: remove default clone location and set unified diff view
Remove the unused default clone location feature and update diff editor defaults. Changes: - Remove default clone location UI from auth and settings screens - Remove defaultWorkspace from authStore state and persistence - Remove fallback logic that derived repo paths from defaultWorkspace - Change default diff view from split to unified - Workspace storage functionality for worktrees remains intact 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent c77b91d commit 6731076

File tree

8 files changed

+15
-387
lines changed

8 files changed

+15
-387
lines changed

apps/array/src/renderer/features/auth/components/AuthScreen.tsx

Lines changed: 4 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { AsciiArt } from "@components/AsciiArt";
22
import { useAuthStore } from "@features/auth/stores/authStore";
3-
import { FolderPicker } from "@features/folder-picker/components/FolderPicker";
43
import {
54
Box,
65
Button,
@@ -13,14 +12,11 @@ import {
1312
Spinner,
1413
Text,
1514
} from "@radix-ui/themes";
16-
import { logger } from "@renderer/lib/logger";
1715
import type { CloudRegion } from "@shared/types/oauth";
1816
import { useMutation } from "@tanstack/react-query";
19-
import { useEffect, useState } from "react";
17+
import { useState } from "react";
2018
import { IS_DEV } from "@/constants/environment";
2119

22-
const log = logger.scope("auth");
23-
2420
export const getErrorMessage = (error: unknown) => {
2521
if (!(error instanceof Error)) {
2622
return "Failed to authenticate";
@@ -38,53 +34,14 @@ export const getErrorMessage = (error: unknown) => {
3834
return message;
3935
};
4036

41-
const detectWorkspacePath = async () => {
42-
try {
43-
const detectedPath = await window.electronAPI.findReposDirectory();
44-
if (detectedPath) {
45-
return detectedPath;
46-
}
47-
} catch (error) {
48-
log.error("Failed to detect repos directory:", error);
49-
}
50-
51-
return null;
52-
};
53-
5437
export function AuthScreen() {
5538
const [region, setRegion] = useState<CloudRegion>("us");
56-
const [workspace, setWorkspace] = useState("~/workspace");
57-
const [workspaceError, setWorkspaceError] = useState<string | null>(null);
58-
59-
const { loginWithOAuth, setDefaultWorkspace } = useAuthStore();
6039

61-
useEffect(() => {
62-
detectWorkspacePath().then((path) => {
63-
if (path) {
64-
setWorkspace(path);
65-
}
66-
});
67-
}, []);
40+
const { loginWithOAuth } = useAuthStore();
6841

6942
const authMutation = useMutation({
70-
mutationFn: async ({
71-
selectedRegion,
72-
workspace,
73-
}: {
74-
selectedRegion: CloudRegion;
75-
workspace: string;
76-
}) => {
77-
if (!workspace || !workspace.trim()) {
78-
setWorkspaceError("Please select a clone location");
79-
throw new Error("Clone location is required");
80-
}
81-
82-
// Login with OAuth first
43+
mutationFn: async (selectedRegion: CloudRegion) => {
8344
await loginWithOAuth(selectedRegion);
84-
85-
// Then save workspace
86-
setDefaultWorkspace(workspace.trim());
87-
setWorkspaceError(null);
8845
},
8946
});
9047

@@ -93,8 +50,7 @@ export function AuthScreen() {
9350
authMutation.reset();
9451
await window.electronAPI.oauthCancelFlow();
9552
} else {
96-
setWorkspaceError(null);
97-
authMutation.mutate({ selectedRegion: region, workspace });
53+
authMutation.mutate(region);
9854
}
9955
};
10056

@@ -144,28 +100,6 @@ export function AuthScreen() {
144100
</Select.Root>
145101
</Flex>
146102

147-
<Flex direction="column" gap="2">
148-
<Text as="label" size="2" weight="medium" color="gray">
149-
Default clone location
150-
</Text>
151-
<FolderPicker
152-
value={workspace}
153-
onChange={setWorkspace}
154-
placeholder="~/repos"
155-
size="2"
156-
/>
157-
<Text size="1" color="gray">
158-
Where repositories will be cloned. This should be the
159-
folder where you usually store your projects.
160-
</Text>
161-
</Flex>
162-
163-
{workspaceError && (
164-
<Callout.Root color="red">
165-
<Callout.Text>{workspaceError}</Callout.Text>
166-
</Callout.Root>
167-
)}
168-
169103
{authMutation.isError && (
170104
<Callout.Root color="red">
171105
<Callout.Text>
@@ -184,7 +118,6 @@ export function AuthScreen() {
184118

185119
<Button
186120
onClick={handleSignIn}
187-
disabled={!workspace}
188121
variant={"classic"}
189122
size="3"
190123
mt="2"

apps/array/src/renderer/features/auth/stores/authStore.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ interface AuthState {
3838
// OpenAI API key (separate concern, kept for now)
3939
openaiApiKey: string | null;
4040
encryptedOpenaiKey: string | null;
41-
defaultWorkspace: string | null;
4241

4342
// OAuth methods
4443
loginWithOAuth: (region: CloudRegion) => Promise<void>;
@@ -48,7 +47,6 @@ interface AuthState {
4847

4948
// Other methods
5049
setOpenAIKey: (apiKey: string) => Promise<void>;
51-
setDefaultWorkspace: (workspace: string) => void;
5250
logout: () => void;
5351
}
5452

@@ -72,7 +70,6 @@ export const useAuthStore = create<AuthState>()(
7270
// OpenAI key
7371
openaiApiKey: null,
7472
encryptedOpenaiKey: null,
75-
defaultWorkspace: null,
7673

7774
loginWithOAuth: async (region: CloudRegion) => {
7875
const result = await window.electronAPI.oauthStartFlow(region);
@@ -355,9 +352,6 @@ export const useAuthStore = create<AuthState>()(
355352
});
356353
},
357354

358-
setDefaultWorkspace: (workspace: string) => {
359-
set({ defaultWorkspace: workspace });
360-
},
361355
logout: () => {
362356
track(ANALYTICS_EVENTS.USER_LOGGED_OUT);
363357
resetUser();
@@ -390,7 +384,6 @@ export const useAuthStore = create<AuthState>()(
390384
cloudRegion: state.cloudRegion,
391385
storedTokens: state.storedTokens,
392386
encryptedOpenaiKey: state.encryptedOpenaiKey,
393-
defaultWorkspace: state.defaultWorkspace,
394387
projectId: state.projectId,
395388
}),
396389
},

apps/array/src/renderer/features/code-editor/components/CodeMirrorDiffEditor.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export function CodeMirrorDiffEditor({
1818
filePath,
1919
onContentChange,
2020
}: CodeMirrorDiffEditorProps) {
21-
const [viewMode, setViewMode] = useState<ViewMode>("split");
21+
const [viewMode, setViewMode] = useState<ViewMode>("unified");
2222
const extensions = useEditorExtensions(filePath, true);
2323
const options = useMemo(
2424
() => ({

apps/array/src/renderer/features/settings/components/SettingsView.tsx

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,8 @@ const REGION_URLS: Record<CloudRegion, string> = {
4343
export function SettingsView() {
4444
useSetHeaderContent(null);
4545

46-
const {
47-
isAuthenticated,
48-
defaultWorkspace,
49-
setDefaultWorkspace,
50-
cloudRegion,
51-
loginWithOAuth,
52-
logout,
53-
} = useAuthStore();
46+
const { isAuthenticated, cloudRegion, loginWithOAuth, logout } =
47+
useAuthStore();
5448
const isDarkMode = useThemeStore((state) => state.isDarkMode);
5549
const toggleDarkMode = useThemeStore((state) => state.toggleDarkMode);
5650
const {
@@ -234,32 +228,6 @@ export function SettingsView() {
234228

235229
<Box className="border-gray-6 border-t" />
236230

237-
{/* Clone Location Section */}
238-
<Flex direction="column" gap="3">
239-
<Heading size="3">Clone location</Heading>
240-
<Card>
241-
<Flex direction="column" gap="3">
242-
<Flex direction="column" gap="2">
243-
<Text size="1" weight="medium">
244-
Default clone location
245-
</Text>
246-
<FolderPicker
247-
value={defaultWorkspace || ""}
248-
onChange={setDefaultWorkspace}
249-
placeholder="~/repos"
250-
size="1"
251-
/>
252-
<Text size="1" color="gray">
253-
Default directory where repositories will be cloned. This
254-
should be the folder where you usually store your projects.
255-
</Text>
256-
</Flex>
257-
</Flex>
258-
</Card>
259-
</Flex>
260-
261-
<Box className="border-gray-6 border-t" />
262-
263231
{/* Workspace Storage Section */}
264232
<Flex direction="column" gap="3">
265233
<Heading size="3">Workspace storage</Heading>

apps/array/src/renderer/features/task-detail/hooks/useTaskData.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import { useAuthStore } from "@features/auth/stores/authStore";
21
import { useTaskExecutionStore } from "@features/task-detail/stores/taskExecutionStore";
32
import { useTasks } from "@features/tasks/hooks/useTasks";
43
import type { Task } from "@shared/types";
54
import { cloneStore } from "@stores/cloneStore";
6-
import { expandTildePath } from "@utils/path";
75
import { getTaskRepository } from "@utils/repository";
86
import { useEffect, useMemo } from "react";
97

@@ -14,7 +12,6 @@ interface UseTaskDataParams {
1412

1513
export function useTaskData({ taskId, initialTask }: UseTaskDataParams) {
1614
const { data: tasks = [] } = useTasks();
17-
const { defaultWorkspace } = useAuthStore();
1815
const initializeRepoPath = useTaskExecutionStore(
1916
(state) => state.initializeRepoPath,
2017
);
@@ -39,18 +36,10 @@ export function useTaskData({ taskId, initialTask }: UseTaskDataParams) {
3936

4037
const repository = getTaskRepository(task);
4138

42-
// Use the stored repoPath if available, otherwise fall back to derived path
39+
// Use the stored repoPath
4340
const derivedPath = useMemo(() => {
44-
// Prioritize the stored repoPath
45-
if (repoPath) {
46-
return repoPath;
47-
}
48-
49-
// Fall back to deriving from workspace + repository (legacy behavior)
50-
if (!repository || !defaultWorkspace) return null;
51-
const expandedWorkspace = expandTildePath(defaultWorkspace);
52-
return `${expandedWorkspace}/${repository.split("/")[1]}`;
53-
}, [repoPath, repository, defaultWorkspace]);
41+
return repoPath;
42+
}, [repoPath]);
5443

5544
const isCloning = cloneStore((state) =>
5645
repository ? state.isCloning(repository) : false,
@@ -80,6 +69,5 @@ export function useTaskData({ taskId, initialTask }: UseTaskDataParams) {
8069
derivedPath,
8170
isCloning,
8271
cloneProgress,
83-
defaultWorkspace,
8472
};
8573
}

apps/array/src/renderer/features/task-detail/stores/taskExecutionStore.ts

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
1-
import { useAuthStore } from "@features/auth/stores/authStore";
21
import { useSettingsStore } from "@features/settings/stores/settingsStore";
32
import type { Task, WorkspaceMode } from "@shared/types";
43
import { repositoryWorkspaceStore } from "@stores/repositoryWorkspaceStore";
54
import { useTaskDirectoryStore } from "@stores/taskDirectoryStore";
6-
import { expandTildePath } from "@utils/path";
75
import { getTaskRepository } from "@utils/repository";
86
import { create } from "zustand";
97
import { persist } from "zustand/middleware";
108

11-
const derivePath = (workspace: string, repo: string) =>
12-
`${expandTildePath(workspace)}/${repo}`;
13-
149
interface TaskExecutionState {
1510
repoPath: string | null;
1611
repoExists: boolean | null;
@@ -127,33 +122,7 @@ export const useTaskExecutionStore = create<TaskExecutionStore>()(
127122
.catch(() => {
128123
store.updateTaskState(taskId, { repoExists: false });
129124
});
130-
return;
131125
}
132-
133-
if (!repository) {
134-
return;
135-
}
136-
137-
const { defaultWorkspace } = useAuthStore.getState();
138-
139-
if (!defaultWorkspace) {
140-
return;
141-
}
142-
143-
const path = derivePath(defaultWorkspace, repository.split("/")[1]);
144-
145-
void store.setRepoPath(taskId, path);
146-
147-
repositoryWorkspaceStore.getState().selectRepository(repository);
148-
149-
window.electronAPI
150-
?.validateRepo(path)
151-
.then((exists) => {
152-
store.updateTaskState(taskId, { repoExists: exists });
153-
})
154-
.catch(() => {
155-
store.updateTaskState(taskId, { repoExists: false });
156-
});
157126
},
158127

159128
revalidateRepo: async (taskId: string) => {

apps/array/src/renderer/stores/navigationStore.ts

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import { useAuthStore } from "@features/auth/stores/authStore";
21
import { useTaskExecutionStore } from "@features/task-detail/stores/taskExecutionStore";
32
import { useWorkspaceStore } from "@features/workspace/stores/workspaceStore";
43
import { track } from "@renderer/lib/analytics";
54
import { logger } from "@renderer/lib/logger";
65
import type { Task, WorkspaceMode } from "@shared/types";
76
import { useRegisteredFoldersStore } from "@stores/registeredFoldersStore";
87
import { useTaskDirectoryStore } from "@stores/taskDirectoryStore";
9-
import { expandTildePath } from "@utils/path";
108
import { getTaskRepository } from "@utils/repository";
119
import { create } from "zustand";
1210
import { ANALYTICS_EVENTS } from "@/types/analytics";
@@ -77,24 +75,10 @@ export const useNavigationStore = create<NavigationStore>((set, get) => {
7775
});
7876

7977
const repoKey = getTaskRepository(task) ?? undefined;
80-
let directory = useTaskDirectoryStore
78+
const directory = useTaskDirectoryStore
8179
.getState()
8280
.getTaskDirectory(task.id, repoKey);
8381

84-
// If no directory found, try to derive from defaultWorkspace
85-
if (!directory && repoKey) {
86-
const { defaultWorkspace } = useAuthStore.getState();
87-
if (defaultWorkspace) {
88-
const repoName = repoKey.split("/")[1];
89-
const derivedPath = `${expandTildePath(defaultWorkspace)}/${repoName}`;
90-
// Validate that this path exists
91-
const exists = await window.electronAPI?.validateRepo(derivedPath);
92-
if (exists) {
93-
directory = derivedPath;
94-
}
95-
}
96-
}
97-
9882
if (directory) {
9983
try {
10084
await useRegisteredFoldersStore.getState().addFolder(directory);

0 commit comments

Comments
 (0)