diff --git a/desktop/src/components/shared/RepositoryLaunchControls.tsx b/desktop/src/components/shared/RepositoryLaunchControls.tsx index d2da78af..7e40fde3 100644 --- a/desktop/src/components/shared/RepositoryLaunchControls.tsx +++ b/desktop/src/components/shared/RepositoryLaunchControls.tsx @@ -37,7 +37,7 @@ const VIEWPORT_GUTTER = 12 function stateMessage(context: RepositoryContextResult | null, error: string | null) { if (error) return error if (!context) return null - if (context.state === 'not_git_repo') return 'not_git' + if (context.state === 'not_git_repo') return null if (context.state === 'missing_workdir') return 'missing' if (context.state === 'error') return context.error || 'error' return null @@ -370,9 +370,7 @@ export function RepositoryLaunchControls({
- {message === 'not_git' - ? t('repoLaunch.notGit') - : message === 'missing' + {message === 'missing' ? t('repoLaunch.missingWorkdir') : message} diff --git a/desktop/src/i18n/locales/en.ts b/desktop/src/i18n/locales/en.ts index f85b59eb..4dc942b2 100644 --- a/desktop/src/i18n/locales/en.ts +++ b/desktop/src/i18n/locales/en.ts @@ -706,7 +706,6 @@ export const en = { 'repoLaunch.worktreeCurrent': 'Current worktree', 'repoLaunch.worktreeIsolated': 'Isolated worktree', 'repoLaunch.selectWorktree': 'Select worktree mode', - 'repoLaunch.notGit': 'Current project is not a Git repository.', 'repoLaunch.missingWorkdir': 'Working directory is missing.', 'repoLaunch.dirtyWarning': 'Uncommitted changes detected. Direct switching will be blocked; enable isolated worktree to continue without touching this folder.', 'repoLaunch.checkedOutWarning': 'This branch is already checked out elsewhere. Enable isolated worktree or choose another branch.', diff --git a/desktop/src/i18n/locales/zh.ts b/desktop/src/i18n/locales/zh.ts index 154b64a4..0c8e205b 100644 --- a/desktop/src/i18n/locales/zh.ts +++ b/desktop/src/i18n/locales/zh.ts @@ -708,7 +708,6 @@ export const zh: Record = { 'repoLaunch.worktreeCurrent': '当前工作树', 'repoLaunch.worktreeIsolated': '独立工作树', 'repoLaunch.selectWorktree': '选择工作树模式', - 'repoLaunch.notGit': '当前项目不是 Git 仓库。', 'repoLaunch.missingWorkdir': '工作目录不存在。', 'repoLaunch.dirtyWarning': '检测到未提交变更,直接切换会被阻止。开启独立工作树即可继续,且不会改动当前目录。', 'repoLaunch.checkedOutWarning': '这个分支已在其他工作树中检出。请开启独立工作树或选择其他分支。', diff --git a/desktop/src/pages/EmptySession.test.tsx b/desktop/src/pages/EmptySession.test.tsx index 52fdcf34..780da8b5 100644 --- a/desktop/src/pages/EmptySession.test.tsx +++ b/desktop/src/pages/EmptySession.test.tsx @@ -103,6 +103,20 @@ function okRepositoryContext(overrides: Partial = {}): } } +function notGitRepositoryContext(): RepositoryContextResult { + return { + state: 'not_git_repo', + workDir: '/workspace/project', + repoRoot: null, + repoName: null, + currentBranch: null, + defaultBranch: null, + dirty: false, + branches: [], + worktrees: [], + } +} + describe('EmptySession', () => { const initialSessionState = useSessionStore.getInitialState() const initialChatState = useChatStore.getInitialState() @@ -199,6 +213,33 @@ describe('EmptySession', () => { expect(mocks.wsConnect).toHaveBeenCalledWith('draft-session') }) + it('starts in a selected non-Git project without showing a repository warning', async () => { + mocks.getRepositoryContext.mockResolvedValueOnce(notGitRepositoryContext()) + + render() + + fireEvent.change(screen.getByRole('textbox'), { + target: { value: 'draft question', selectionStart: 14 }, + }) + fireEvent.click(screen.getByRole('button', { name: 'Pick project' })) + + await waitFor(() => { + expect(screen.getByRole('button', { name: /Run/i })).not.toBeDisabled() + }) + + expect(screen.queryByText('Current project is not a Git repository.')).not.toBeInTheDocument() + expect(screen.queryByRole('button', { name: /Select branch:/ })).not.toBeInTheDocument() + expect(screen.queryByText('Current worktree')).not.toBeInTheDocument() + + fireEvent.click(screen.getByRole('button', { name: /Run/i })) + + await waitFor(() => { + expect(mocks.createSession).toHaveBeenCalledWith({ + workDir: '/workspace/project', + }) + }) + }) + it('shows an actionable repository error when direct branch switching is blocked', async () => { mocks.createSession.mockRejectedValueOnce(new ApiError(400, { error: 'REPOSITORY_DIRTY_WORKTREE',