Skip to content

Commit b0e3bd9

Browse files
jonathanlabclaude
andauthored
Remove default clone location and set unified diff view (#198)
Co-authored-by: Claude <[email protected]>
1 parent e237de2 commit b0e3bd9

File tree

7 files changed

+14
-387
lines changed

7 files changed

+14
-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
@@ -39,7 +39,6 @@ interface AuthState {
3939
// OpenAI API key (separate concern, kept for now)
4040
openaiApiKey: string | null;
4141
encryptedOpenaiKey: string | null;
42-
defaultWorkspace: string | null;
4342

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

5049
// Other methods
5150
setOpenAIKey: (apiKey: string) => Promise<void>;
52-
setDefaultWorkspace: (workspace: string) => void;
5351
logout: () => void;
5452
}
5553

@@ -74,7 +72,6 @@ export const useAuthStore = create<AuthState>()(
7472
// OpenAI key
7573
openaiApiKey: null,
7674
encryptedOpenaiKey: null,
77-
defaultWorkspace: null,
7875

7976
loginWithOAuth: async (region: CloudRegion) => {
8077
const result = await window.electronAPI.oauthStartFlow(region);
@@ -357,9 +354,6 @@ export const useAuthStore = create<AuthState>()(
357354
});
358355
},
359356

360-
setDefaultWorkspace: (workspace: string) => {
361-
set({ defaultWorkspace: workspace });
362-
},
363357
logout: () => {
364358
track(ANALYTICS_EVENTS.USER_LOGGED_OUT);
365359
resetUser();
@@ -394,7 +388,6 @@ export const useAuthStore = create<AuthState>()(
394388
cloudRegion: state.cloudRegion,
395389
storedTokens: state.storedTokens,
396390
encryptedOpenaiKey: state.encryptedOpenaiKey,
397-
defaultWorkspace: state.defaultWorkspace,
398391
projectId: state.projectId,
399392
}),
400393
},

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

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

48-
const {
49-
isAuthenticated,
50-
defaultWorkspace,
51-
setDefaultWorkspace,
52-
cloudRegion,
53-
loginWithOAuth,
54-
logout,
55-
} = useAuthStore();
48+
const { isAuthenticated, cloudRegion, loginWithOAuth, logout } =
49+
useAuthStore();
5650
const isDarkMode = useThemeStore((state) => state.isDarkMode);
5751
const toggleDarkMode = useThemeStore((state) => state.toggleDarkMode);
5852
const {
@@ -292,32 +286,6 @@ export function SettingsView() {
292286

293287
<Box className="border-gray-6 border-t" />
294288

295-
{/* Clone Location Section */}
296-
<Flex direction="column" gap="3">
297-
<Heading size="3">Clone location</Heading>
298-
<Card>
299-
<Flex direction="column" gap="3">
300-
<Flex direction="column" gap="2">
301-
<Text size="1" weight="medium">
302-
Default clone location
303-
</Text>
304-
<FolderPicker
305-
value={defaultWorkspace || ""}
306-
onChange={setDefaultWorkspace}
307-
placeholder="~/repos"
308-
size="1"
309-
/>
310-
<Text size="1" color="gray">
311-
Default directory where repositories will be cloned. This
312-
should be the folder where you usually store your projects.
313-
</Text>
314-
</Flex>
315-
</Flex>
316-
</Card>
317-
</Flex>
318-
319-
<Box className="border-gray-6 border-t" />
320-
321289
{/* Workspace Storage Section */}
322290
<Flex direction="column" gap="3">
323291
<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)