Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions packages/ui/src/features/task-detail/components/TaskInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import {
type AgentAdapter,
useSettingsStore,
} from "../../settings/settingsStore";
import { useInitialDirectoryFromFolderId } from "../hooks/useInitialDirectoryFromFolderId";
import { useInitialRepoSelectionFromFolderId } from "../hooks/useInitialRepoSelectionFromFolderId";
import { usePreviewConfig } from "../hooks/usePreviewConfig";
import { useTaskCreation } from "../hooks/useTaskCreation";
import { CloudGithubMissingNotice } from "./CloudGithubMissingNotice";
Expand Down Expand Up @@ -110,6 +110,7 @@ export function TaskInput({
);
const {
setLastUsedLocalWorkspaceMode,
lastUsedLocalWorkspaceMode,
lastUsedWorkspaceMode,
setLastUsedWorkspaceMode,
lastUsedAdapter,
Expand Down Expand Up @@ -466,7 +467,25 @@ export function TaskInput({
setLastUsedCloudRepository,
]);

useInitialDirectoryFromFolderId(view.folderId, folders, setSelectedDirectory);
// Switch mode for a folder-scoped prefill ("+" in the sidebar) without persisting it as
// the user's mode preference. Marks the mode as resolved so the last-used resolver above
// doesn't override the explicit pick.
const switchWorkspaceModeForFolder = useCallback((mode: WorkspaceMode) => {
didResolveWorkspaceModeRef.current = true;
setWorkspaceModeState(mode);
}, []);

useInitialRepoSelectionFromFolderId({
folderId: view.folderId,
folders,
repositories,
reposLoaded: !isLoadingRepos && repositories.length > 0,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 The repositories.length > 0 guard conflates "the fetch has finished" with "the fetch returned results." When a user has no connected GitHub integrations the list finishes loading empty, so reposLoaded stays false permanently. The effect's repoModeInitRef block is therefore never entered, and a user in Cloud mode who clicks "+" on a local-only folder will never be switched to Local — the whole mode-switch branch this PR adds is silently skipped for that cohort.

Suggested change
reposLoaded: !isLoadingRepos && repositories.length > 0,
reposLoaded: !isLoadingRepos,
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/ui/src/features/task-detail/components/TaskInput.tsx
Line: 482

Comment:
The `repositories.length > 0` guard conflates "the fetch has finished" with "the fetch returned results." When a user has no connected GitHub integrations the list finishes loading empty, so `reposLoaded` stays `false` permanently. The effect's `repoModeInitRef` block is therefore never entered, and a user in Cloud mode who clicks "+" on a local-only folder will never be switched to Local — the whole mode-switch branch this PR adds is silently skipped for that cohort.

```suggestion
    reposLoaded: !isLoadingRepos,
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid catch on the diagnosis — a user can be in Cloud mode with zero GitHub integrations (the mode toggle gates on the twig-cloud-mode-toggle flag, not hasGithubIntegration, and lastUsedWorkspaceMode: cloud persists after disconnecting). For that cohort repositories.length > 0 never becomes true, so the Cloud→Local switch never fires and "+" on a local-only folder silently does nothing.

The proposed fix (!isLoadingRepos alone) isn't quite right though — it reintroduces the transient-empty race the length check guarded: right after the integrations query resolves there's a window where isLoadingRepos === false while repositories is still [] (per-installation repo queries freshly spawned, same window the validation effect documents). A user with integrations clicking a cloud-capable repo in that window would be wrongly judged not-cloud-capable and switched to Local on the common path.

Fixed by distinguishing settled-empty from transiently-empty: extracted a pure areReposReady({ isLoadingRepos, repositoriesCount, hasGithubIntegration }) → ready when !isLoadingRepos && (repositoriesCount > 0 || !hasGithubIntegration). Fixes the no-integration cohort, keeps the window guard for the common path. Done in #2712 (this branch is locked to further commits).

currentMode: workspaceMode,
lastUsedLocalMode: lastUsedLocalWorkspaceMode,
setSelectedDirectory,
setSelectedRepository,
switchWorkspaceMode: switchWorkspaceModeForFolder,
});

useEffect(() => {
setCloudBranchSearchQuery("");
Expand Down

This file was deleted.

This file was deleted.

Loading
Loading