Skip to content

Commit 097cde0

Browse files
AyushKaithwasclaude
andcommitted
fix(settings): a configured base always applies when leaving the checkout
Leaving Current checkout for New worktree guessed whether the draft's branch was synced or picked: web read environmentSelection, which machine picks also set, and mobile compared branch names, which a checked-out pick also matches. In Current checkout the picker checks a branch out rather than choosing a worktree base, so with a base configured the switch now always starts from it, shown in the picker before sending. Re-selecting New worktree keeps a base already picked there. Co-Authored-By: Claude Opus 5.5 <[email protected]>
1 parent 48d2c04 commit 097cde0

6 files changed

Lines changed: 34 additions & 36 deletions

File tree

‎apps/mobile/src/features/threads/new-task-context-presentation.test.ts‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -202,14 +202,15 @@ describe("fillNewTaskWorkspaceBranch", () => {
202202
});
203203

204204
describe("resolveWorktreeSwitchBranch", () => {
205-
const input = { selectedBranch: "feature", checkoutBranch: "feature", worktreeBaseBranch: "dev" };
206-
207-
it("drops the checkout branch so the configured base applies", () => {
208-
expect(resolveWorktreeSwitchBranch(input)).toBeNull();
205+
it("starts a new worktree from the configured base, not the checkout's branch", () => {
206+
expect(
207+
resolveWorktreeSwitchBranch({ selectedBranch: "release", worktreeBaseBranch: "dev" }),
208+
).toBeNull();
209209
});
210210

211-
it("keeps another branch the user chose, and today's behavior without a base", () => {
212-
expect(resolveWorktreeSwitchBranch({ ...input, selectedBranch: "release" })).toBe("release");
213-
expect(resolveWorktreeSwitchBranch({ ...input, worktreeBaseBranch: "" })).toBe("feature");
211+
it("keeps today's behavior without a configured base", () => {
212+
expect(resolveWorktreeSwitchBranch({ selectedBranch: "release", worktreeBaseBranch: "" })).toBe(
213+
"release",
214+
);
214215
});
215216
});

‎apps/mobile/src/features/threads/new-task-context-presentation.ts‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,12 @@ export function resolveNewTaskLocalWorkspaceSelection(input: {
7272
};
7373
}
7474

75-
/** Leaving the checkout for a new worktree drops the checkout's branch when a base is configured. */
75+
/** A checkout's branch is not a worktree base, so leaving it for a new worktree starts from the configured base. */
7676
export function resolveWorktreeSwitchBranch(input: {
7777
readonly selectedBranch: string | null;
78-
readonly checkoutBranch: string | null;
7978
readonly worktreeBaseBranch: string;
8079
}): string | null {
81-
return input.worktreeBaseBranch !== "" && input.selectedBranch === input.checkoutBranch
82-
? null
83-
: input.selectedBranch;
80+
return input.worktreeBaseBranch === "" ? input.selectedBranch : null;
8481
}
8582

8683
export function resolveNewTaskBranchLabel(input: {

‎apps/mobile/src/features/threads/new-task-flow-provider.tsx‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,6 @@ export function NewTaskFlowProvider(
695695
: workspaceMode === "local"
696696
? resolveWorktreeSwitchBranch({
697697
selectedBranch: selectedBranchName,
698-
checkoutBranch: localSelection.branch,
699698
worktreeBaseBranch: projectSettings.settings.newWorktreesBaseBranch,
700699
})
701700
: selectedBranchName,

‎apps/web/src/components/chat/useComposerSelection.ts‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { toastManager } from "../ui/toast";
2020
import { resolveAppModelSelectionForInstance } from "../../modelSelection";
2121
import {
2222
resolveNewDraftStartFromOrigin,
23-
shouldClearSyncedDraftBranch,
23+
shouldResetBranchForNewWorktree,
2424
} from "../../lib/chatThreadActions";
2525
import { type DraftThreadEnvMode, useComposerDraftStore } from "../../composerDraftStore";
2626
import {
@@ -237,11 +237,10 @@ export function useComposerSelection(input: ComposerSelectionInput) {
237237
newWorktreesStartFromOrigin: activeProjectSettings.settings.newWorktreesStartFromOrigin,
238238
}),
239239
...(mode === "worktree" && draftThread?.worktreePath ? { worktreePath: null } : {}),
240-
...(shouldClearSyncedDraftBranch({
240+
...(shouldResetBranchForNewWorktree({
241+
currentEnvMode: draftThread?.envMode,
241242
nextEnvMode: mode,
242243
worktreeBaseBranch: activeProjectSettings.settings.newWorktreesBaseBranch,
243-
draftBranch: draftThread?.branch ?? null,
244-
environmentSelection: draftThread?.environmentSelection,
245244
})
246245
? { branch: null }
247246
: {}),

‎apps/web/src/lib/chatThreadActions.test.ts‎

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ProviderInstanceId, type ModelSelection } from "@t3tools/contracts";
22
import { describe, expect, it } from "vite-plus/test";
33
import {
44
resolveNewThreadModelSelectionOverride,
5-
shouldClearSyncedDraftBranch,
5+
shouldResetBranchForNewWorktree,
66
} from "./chatThreadActions";
77

88
const PROJECT_DEFAULT_SELECTION: ModelSelection = {
@@ -38,25 +38,29 @@ describe("chatThreadActions", () => {
3838
});
3939
});
4040

41-
describe("shouldClearSyncedDraftBranch", () => {
41+
describe("shouldResetBranchForNewWorktree", () => {
4242
const input = {
43+
currentEnvMode: "local",
4344
nextEnvMode: "worktree",
4445
worktreeBaseBranch: "dev",
45-
draftBranch: "feature/checked-out",
46-
environmentSelection: "auto",
4746
} as const;
4847

49-
it("drops the checkout branch so a new worktree starts from the configured base", () => {
50-
expect(shouldClearSyncedDraftBranch(input)).toBe(true);
51-
expect(shouldClearSyncedDraftBranch({ ...input, environmentSelection: undefined })).toBe(true);
48+
it("starts a new worktree from the configured base instead of the checkout's branch", () => {
49+
expect(shouldResetBranchForNewWorktree(input)).toBe(true);
5250
});
5351

54-
it("keeps a branch the user picked", () => {
55-
expect(shouldClearSyncedDraftBranch({ ...input, environmentSelection: "manual" })).toBe(false);
52+
it("keeps a base already picked in worktree mode", () => {
53+
expect(shouldResetBranchForNewWorktree({ ...input, currentEnvMode: "worktree" })).toBe(false);
5654
});
5755

58-
it("keeps today's behavior without a configured base or outside worktree mode", () => {
59-
expect(shouldClearSyncedDraftBranch({ ...input, worktreeBaseBranch: "" })).toBe(false);
60-
expect(shouldClearSyncedDraftBranch({ ...input, nextEnvMode: "local" })).toBe(false);
56+
it("keeps today's behavior without a configured base or when leaving worktree mode", () => {
57+
expect(shouldResetBranchForNewWorktree({ ...input, worktreeBaseBranch: "" })).toBe(false);
58+
expect(
59+
shouldResetBranchForNewWorktree({
60+
currentEnvMode: "worktree",
61+
nextEnvMode: "local",
62+
worktreeBaseBranch: "dev",
63+
}),
64+
).toBe(false);
6165
});
6266
});

‎apps/web/src/lib/chatThreadActions.ts‎

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,16 @@ export function resolveNewDraftStartFromOrigin(input: {
4343
return input.envMode === "worktree" && input.newWorktreesStartFromOrigin;
4444
}
4545

46-
/** A configured base replaces the branch a draft synced from its checkout, never one the user picked. */
47-
export function shouldClearSyncedDraftBranch(input: {
46+
/** A checkout's branch is not a worktree base, so leaving it for a new worktree starts from the configured base. */
47+
export function shouldResetBranchForNewWorktree(input: {
48+
currentEnvMode: DraftThreadEnvMode | undefined;
4849
nextEnvMode: DraftThreadEnvMode;
4950
worktreeBaseBranch: string;
50-
draftBranch: string | null;
51-
environmentSelection: "auto" | "manual" | undefined;
5251
}): boolean {
5352
return (
53+
input.currentEnvMode === "local" &&
5454
input.nextEnvMode === "worktree" &&
55-
input.worktreeBaseBranch !== "" &&
56-
input.draftBranch !== null &&
57-
input.environmentSelection !== "manual"
55+
input.worktreeBaseBranch !== ""
5856
);
5957
}
6058

0 commit comments

Comments
 (0)