Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.

Commit c56f0f4

Browse files
authored
ux: improve worktree selector and creation UX (#10940)
* Delete modal * Restructured * Much more prominent * UI * i18n * Fixes i18n * Remove mergeresultmodel * i18n * tests * knip * code review
1 parent c7910a9 commit c56f0f4

97 files changed

Lines changed: 1189 additions & 380 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/types/src/global-settings.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,11 @@ export const globalSettingsSchema = z.object({
203203
* Used by the worktree feature to open the Roo Code sidebar in a new window.
204204
*/
205205
worktreeAutoOpenPath: z.string().optional(),
206+
/**
207+
* Whether to show the worktree selector in the home screen.
208+
* @default true
209+
*/
210+
showWorktreesInHomeScreen: z.boolean().optional(),
206211
})
207212

208213
export type GlobalSettings = z.infer<typeof globalSettingsSchema>

packages/types/src/vscode-extension-host.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ export interface ExtensionMessage {
107107
| "worktreeDefaults"
108108
| "worktreeIncludeStatus"
109109
| "branchWorktreeIncludeResult"
110+
| "folderSelected"
110111
text?: string
111112
payload?: any // eslint-disable-line @typescript-eslint/no-explicit-any
112113
checkpointWarning?: {
@@ -119,7 +120,6 @@ export interface ExtensionMessage {
119120
| "historyButtonClicked"
120121
| "marketplaceButtonClicked"
121122
| "cloudButtonClicked"
122-
| "worktreesButtonClicked"
123123
| "didBecomeVisible"
124124
| "focusInput"
125125
| "switchTab"
@@ -257,6 +257,8 @@ export interface ExtensionMessage {
257257
copyProgressBytesCopied?: number
258258
copyProgressTotalBytes?: number
259259
copyProgressItemName?: string
260+
// folderSelected
261+
path?: string
260262
}
261263

262264
export interface OpenAiCodexRateLimitsMessage {
@@ -332,6 +334,7 @@ export type ExtensionState = Pick<
332334
| "includeCurrentCost"
333335
| "maxGitStatusFiles"
334336
| "requestDelaySeconds"
337+
| "showWorktreesInHomeScreen"
335338
> & {
336339
version: string
337340
clineMessages: ClineMessage[]
@@ -600,6 +603,7 @@ export interface WebviewMessage {
600603
| "checkBranchWorktreeInclude"
601604
| "createWorktreeInclude"
602605
| "checkoutBranch"
606+
| "browseForWorktreePath"
603607
text?: string
604608
editedMessageContent?: string
605609
tab?: "settings" | "history" | "mcp" | "modes" | "chat" | "marketplace" | "cloud"

packages/types/src/vscode.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ export const commandIds = [
3535
"popoutButtonClicked",
3636
"cloudButtonClicked",
3737
"settingsButtonClicked",
38-
"worktreesButtonClicked",
3938

4039
"openInNewTab",
4140

src/activate/registerCommands.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,6 @@ const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOpt
134134
if (!visibleProvider) return
135135
visibleProvider.postMessageToWebview({ type: "action", action: "marketplaceButtonClicked" })
136136
},
137-
worktreesButtonClicked: () => {
138-
const visibleProvider = getVisibleProviderOrLog(outputChannel)
139-
if (!visibleProvider) return
140-
TelemetryService.instance.captureTitleButtonClicked("worktrees")
141-
visibleProvider.postMessageToWebview({ type: "action", action: "worktreesButtonClicked" })
142-
},
143137
newTask: handleNewTask,
144138
setCustomStoragePath: async () => {
145139
const { promptForCustomStoragePath } = await import("../utils/storage")

src/core/webview/webviewMessageHandler.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3556,6 +3556,34 @@ export const webviewMessageHandler = async (
35563556
break
35573557
}
35583558

3559+
case "browseForWorktreePath": {
3560+
try {
3561+
const options: vscode.OpenDialogOptions = {
3562+
canSelectFiles: false,
3563+
canSelectFolders: true,
3564+
canSelectMany: false,
3565+
openLabel: t("worktrees:selectWorktreeLocation"),
3566+
title: t("worktrees:selectFolderForWorktree"),
3567+
defaultUri: vscode.workspace.workspaceFolders?.[0]?.uri
3568+
? vscode.Uri.joinPath(vscode.workspace.workspaceFolders[0].uri, "..")
3569+
: undefined,
3570+
}
3571+
3572+
const result = await vscode.window.showOpenDialog(options)
3573+
if (result && result[0]) {
3574+
await provider.postMessageToWebview({
3575+
type: "folderSelected",
3576+
path: result[0].fsPath,
3577+
})
3578+
}
3579+
} catch (error) {
3580+
const errorMessage = error instanceof Error ? error.message : String(error)
3581+
provider.log(`Error opening folder picker: ${errorMessage}`)
3582+
}
3583+
3584+
break
3585+
}
3586+
35593587
default: {
35603588
// console.log(`Unhandled message type: ${message.type}`)
35613589
//

src/i18n/locales/ca/worktrees.json

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/i18n/locales/de/worktrees.json

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/i18n/locales/en/worktrees.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"selectWorktreeLocation": "Select Worktree Location",
3+
"selectFolderForWorktree": "Select folder for new worktree"
4+
}

src/i18n/locales/es/worktrees.json

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/i18n/locales/fr/worktrees.json

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)