Skip to content

Commit 2e88696

Browse files
committed
Add configurable worktree root directory setting
Users can now configure where worktrees are stored via the settings modal. The setting is persisted and applies to all new sessions created after the change. Changes: - Added worktreeDir field to TerminalSettings interface - Added UI controls in settings modal for selecting worktree directory - Updated worktree creation logic to use configured directory - Defaults to ~/worktrees for backward compatibility
1 parent 17b7e81 commit 2e88696

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

index.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,15 @@ <h2 class="modal-title">Terminal Settings</h2>
225225
</label>
226226
</div>
227227

228+
<div class="form-group">
229+
<label class="form-label">Worktree Root Directory</label>
230+
<div class="directory-input-group">
231+
<input type="text" id="settings-worktree-dir" class="form-input" readonly placeholder="~/worktrees" />
232+
<button id="browse-worktree-dir" class="btn-icon">Browse</button>
233+
</div>
234+
<span class="text-xs text-gray-400 mt-1 block">Directory where session worktrees will be stored</span>
235+
</div>
236+
228237
<div class="btn-group">
229238
<button id="cancel-settings" class="btn-secondary">Cancel</button>
230239
<button id="reset-settings" class="btn-secondary">Reset to Default</button>

main.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ function getPersistedSessions(): PersistedSession[] {
2222
return (store as any).get("sessions", []);
2323
}
2424

25+
function getWorktreeBaseDir(): string {
26+
const settings = (store as any).get("terminalSettings");
27+
if (settings && settings.worktreeDir) {
28+
return settings.worktreeDir;
29+
}
30+
return path.join(os.homedir(), "worktrees");
31+
}
32+
2533
function isTerminalReady(buffer: string, startPos: number = 0): boolean {
2634
const searchBuffer = buffer.slice(startPos);
2735

@@ -63,7 +71,7 @@ function extractProjectMcpConfig(projectDir: string): any {
6371
// Get a safe directory name from project path, with collision handling
6472
function getProjectWorktreeDirName(projectDir: string): string {
6573
const baseName = path.basename(projectDir);
66-
const worktreesBaseDir = path.join(os.homedir(), "worktrees");
74+
const worktreesBaseDir = getWorktreeBaseDir();
6775
const candidatePath = path.join(worktreesBaseDir, baseName);
6876

6977
// If directory doesn't exist or points to the same project, use base name
@@ -90,7 +98,7 @@ function getProjectWorktreeDirName(projectDir: string): string {
9098
function writeMcpConfigFile(projectDir: string, mcpServers: any): string | null {
9199
try {
92100
const projectDirName = getProjectWorktreeDirName(projectDir);
93-
const worktreesDir = path.join(os.homedir(), "worktrees");
101+
const worktreesDir = getWorktreeBaseDir();
94102
if (!fs.existsSync(worktreesDir)) {
95103
fs.mkdirSync(worktreesDir, { recursive: true });
96104
}
@@ -303,7 +311,7 @@ async function createWorktree(projectDir: string, parentBranch: string, sessionN
303311
const git = simpleGit(projectDir);
304312

305313
const projectDirName = getProjectWorktreeDirName(projectDir);
306-
const worktreesBaseDir = path.join(os.homedir(), "worktrees");
314+
const worktreesBaseDir = getWorktreeBaseDir();
307315
const projectWorktreeDir = path.join(worktreesBaseDir, projectDirName);
308316
const worktreeName = customBranchName || `session${sessionNumber}`;
309317
const worktreePath = path.join(projectWorktreeDir, worktreeName);

renderer.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ interface TerminalSettings {
3030
fontSize: number;
3131
theme: string; // Theme preset name
3232
cursorBlink: boolean;
33+
worktreeDir: string;
3334
}
3435

3536
interface ThemeColors {
@@ -203,6 +204,7 @@ const DEFAULT_SETTINGS: TerminalSettings = {
203204
fontSize: 11,
204205
theme: getSystemTheme() === "dark" ? "macos-dark" : "macos-light",
205206
cursorBlink: false,
207+
worktreeDir: require("path").join(require("os").homedir(), "worktrees"),
206208
};
207209

208210
const sessions = new Map<string, Session>();
@@ -1217,6 +1219,8 @@ const settingsTheme = document.getElementById("settings-theme") as HTMLSelectEle
12171219
const settingsFontFamily = document.getElementById("settings-font-family") as HTMLSelectElement;
12181220
const settingsFontSize = document.getElementById("settings-font-size") as HTMLInputElement;
12191221
const settingsCursorBlink = document.getElementById("settings-cursor-blink") as HTMLInputElement;
1222+
const settingsWorktreeDir = document.getElementById("settings-worktree-dir") as HTMLInputElement;
1223+
const browseWorktreeDirBtn = document.getElementById("browse-worktree-dir");
12201224

12211225
// Load saved settings on startup
12221226
async function loadSettings() {
@@ -1243,6 +1247,7 @@ function populateSettingsForm() {
12431247

12441248
settingsFontSize.value = terminalSettings.fontSize.toString();
12451249
settingsCursorBlink.checked = terminalSettings.cursorBlink;
1250+
settingsWorktreeDir.value = terminalSettings.worktreeDir;
12461251
}
12471252

12481253
// Apply settings to all existing terminals
@@ -1281,13 +1286,22 @@ resetSettingsBtn?.addEventListener("click", () => {
12811286
populateSettingsForm();
12821287
});
12831288

1289+
// Browse worktree directory
1290+
browseWorktreeDirBtn?.addEventListener("click", async () => {
1291+
const dir = await ipcRenderer.invoke("select-directory");
1292+
if (dir) {
1293+
settingsWorktreeDir.value = dir;
1294+
}
1295+
});
1296+
12841297
// Save settings
12851298
saveSettingsBtn?.addEventListener("click", async () => {
12861299
// Read values from form
12871300
terminalSettings.theme = settingsTheme.value;
12881301
terminalSettings.fontFamily = settingsFontFamily.value || DEFAULT_SETTINGS.fontFamily;
12891302
terminalSettings.fontSize = parseInt(settingsFontSize.value) || DEFAULT_SETTINGS.fontSize;
12901303
terminalSettings.cursorBlink = settingsCursorBlink.checked;
1304+
terminalSettings.worktreeDir = settingsWorktreeDir.value || DEFAULT_SETTINGS.worktreeDir;
12911305

12921306
// Save to electron-store
12931307
await ipcRenderer.invoke("save-terminal-settings", terminalSettings);

0 commit comments

Comments
 (0)