From 09e289deff1447019c6c73cd1d19525e3a3a1c8e Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Fri, 29 May 2026 06:37:15 -0700 Subject: [PATCH] Remove add repo clone destination effect --- .../src/components/sidebar/AddRepoDialog.tsx | 35 +++++------ .../components/sidebar/clone-defaults.test.ts | 61 ++++++++++++++++++- .../src/components/sidebar/clone-defaults.ts | 22 +++++++ 3 files changed, 97 insertions(+), 21 deletions(-) diff --git a/src/renderer/src/components/sidebar/AddRepoDialog.tsx b/src/renderer/src/components/sidebar/AddRepoDialog.tsx index a4ca6fecd14..4d57a57fb99 100644 --- a/src/renderer/src/components/sidebar/AddRepoDialog.tsx +++ b/src/renderer/src/components/sidebar/AddRepoDialog.tsx @@ -17,7 +17,7 @@ import { track } from '@/lib/telemetry' import { RemoteStep, CloneStep, useRemoteRepo } from './AddRepoSteps' import { CreateStep, useCreateRepo } from './AddRepoCreateStep' import { getProjectAddedPrimaryBranchName, SetupStep } from './AddRepoSetupStep' -import { getDefaultCloneParent } from './clone-defaults' +import { getCloneDestinationAutoFill } from './clone-defaults' import { callRuntimeRpc, getActiveRuntimeTarget } from '@/runtime/runtime-rpc-client' import { activateAndRevealWorktree } from '@/lib/worktree-activation' import { isGitRepoKind } from '../../../../shared/repo-kind' @@ -175,26 +175,21 @@ const AddRepoDialog = React.memo(function AddRepoDialog() { return window.api.repos.onCloneProgress(setCloneProgress) }, [isCloning]) - useEffect(() => { - if (step !== 'clone') { - cloneStepAutoFilledRef.current = false - return - } - if (cloneStepAutoFilledRef.current) { - return - } - if (cloneDestination) { - return - } - if (settings?.activeRuntimeEnvironmentId?.trim()) { - return - } - if (!settings?.workspaceDir) { - return - } + const cloneDestinationAutoFill = getCloneDestinationAutoFill({ + step, + cloneDestination, + activeRuntimeEnvironmentId: settings?.activeRuntimeEnvironmentId, + workspaceDir: settings?.workspaceDir, + cloneStepAutoFilled: cloneStepAutoFilledRef.current + }) + if (step !== 'clone') { + cloneStepAutoFilledRef.current = false + } else if (cloneDestinationAutoFill) { + // Why: late settings hydration should still seed the local clone path, + // but runtime/server clone flows must keep their destination user-entered. cloneStepAutoFilledRef.current = true - setCloneDestination(getDefaultCloneParent(settings.workspaceDir)) - }, [step, cloneDestination, settings?.activeRuntimeEnvironmentId, settings?.workspaceDir]) + setCloneDestination(cloneDestinationAutoFill.destination) + } const isOpen = activeModal === 'add-repo' const projectId = addedRepo?.id ?? '' diff --git a/src/renderer/src/components/sidebar/clone-defaults.test.ts b/src/renderer/src/components/sidebar/clone-defaults.test.ts index d4cfcff01f5..9ec5f6ea3c4 100644 --- a/src/renderer/src/components/sidebar/clone-defaults.test.ts +++ b/src/renderer/src/components/sidebar/clone-defaults.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { getDefaultCloneParent } from './clone-defaults' +import { getCloneDestinationAutoFill, getDefaultCloneParent } from './clone-defaults' describe('getDefaultCloneParent', () => { it('strips a POSIX workspaces suffix', () => { @@ -46,3 +46,62 @@ describe('getDefaultCloneParent', () => { ) }) }) + +describe('getCloneDestinationAutoFill', () => { + it('fills the local clone destination from the workspace directory', () => { + expect( + getCloneDestinationAutoFill({ + step: 'clone', + cloneDestination: '', + activeRuntimeEnvironmentId: null, + workspaceDir: '/Users/mvanhorn/orca/workspaces', + cloneStepAutoFilled: false + }) + ).toEqual({ destination: '/Users/mvanhorn/orca' }) + }) + + it('waits for a workspace directory before filling', () => { + expect( + getCloneDestinationAutoFill({ + step: 'clone', + cloneDestination: '', + activeRuntimeEnvironmentId: null, + workspaceDir: null, + cloneStepAutoFilled: false + }) + ).toBeNull() + }) + + it('does not overwrite typed destinations or repeat an auto-fill', () => { + expect( + getCloneDestinationAutoFill({ + step: 'clone', + cloneDestination: '/tmp/project', + activeRuntimeEnvironmentId: null, + workspaceDir: '/Users/mvanhorn/orca/workspaces', + cloneStepAutoFilled: false + }) + ).toBeNull() + expect( + getCloneDestinationAutoFill({ + step: 'clone', + cloneDestination: '', + activeRuntimeEnvironmentId: null, + workspaceDir: '/Users/mvanhorn/orca/workspaces', + cloneStepAutoFilled: true + }) + ).toBeNull() + }) + + it('does not fill server clone destinations for runtime environments', () => { + expect( + getCloneDestinationAutoFill({ + step: 'clone', + cloneDestination: '', + activeRuntimeEnvironmentId: 'env-local-linux', + workspaceDir: '/Users/mvanhorn/orca/workspaces', + cloneStepAutoFilled: false + }) + ).toBeNull() + }) +}) diff --git a/src/renderer/src/components/sidebar/clone-defaults.ts b/src/renderer/src/components/sidebar/clone-defaults.ts index e5218c7e987..6a720a33a6c 100644 --- a/src/renderer/src/components/sidebar/clone-defaults.ts +++ b/src/renderer/src/components/sidebar/clone-defaults.ts @@ -25,3 +25,25 @@ export function getDefaultCloneParent(workspaceDir: string): string { } return parent } + +export function getCloneDestinationAutoFill({ + step, + cloneDestination, + activeRuntimeEnvironmentId, + workspaceDir, + cloneStepAutoFilled +}: { + step: string + cloneDestination: string + activeRuntimeEnvironmentId: string | null | undefined + workspaceDir: string | null | undefined + cloneStepAutoFilled: boolean +}): { destination: string } | null { + if (step !== 'clone' || cloneStepAutoFilled || cloneDestination) { + return null + } + if (activeRuntimeEnvironmentId?.trim() || !workspaceDir) { + return null + } + return { destination: getDefaultCloneParent(workspaceDir) } +}