Merge pull request #4 from built-by-as/configure-worktree-dir

Add configurable worktree root directory
This commit is contained in:
built-by-as 2025-10-07 14:59:32 -04:00 committed by GitHub
commit 5d02ec3359
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 3 deletions

View file

@ -225,6 +225,15 @@
</label> </label>
</div> </div>
<div class="form-group">
<label class="form-label">Worktree Root Directory</label>
<div class="directory-input-group">
<input type="text" id="settings-worktree-dir" class="form-input" readonly placeholder="~/worktrees" />
<button id="browse-worktree-dir" class="btn-icon">Browse</button>
</div>
<span class="text-xs text-gray-400 mt-1 block">Directory where session worktrees will be stored</span>
</div>
<div class="btn-group"> <div class="btn-group">
<button id="cancel-settings" class="btn-secondary">Cancel</button> <button id="cancel-settings" class="btn-secondary">Cancel</button>
<button id="reset-settings" class="btn-secondary">Reset to Default</button> <button id="reset-settings" class="btn-secondary">Reset to Default</button>

14
main.ts
View file

@ -22,6 +22,14 @@ function getPersistedSessions(): PersistedSession[] {
return (store as any).get("sessions", []); return (store as any).get("sessions", []);
} }
function getWorktreeBaseDir(): string {
const settings = (store as any).get("terminalSettings");
if (settings && settings.worktreeDir) {
return settings.worktreeDir;
}
return path.join(os.homedir(), "worktrees");
}
function isTerminalReady(buffer: string, startPos: number = 0): boolean { function isTerminalReady(buffer: string, startPos: number = 0): boolean {
const searchBuffer = buffer.slice(startPos); const searchBuffer = buffer.slice(startPos);
@ -63,7 +71,7 @@ function extractProjectMcpConfig(projectDir: string): any {
// Get a safe directory name from project path, with collision handling // Get a safe directory name from project path, with collision handling
function getProjectWorktreeDirName(projectDir: string): string { function getProjectWorktreeDirName(projectDir: string): string {
const baseName = path.basename(projectDir); const baseName = path.basename(projectDir);
const worktreesBaseDir = path.join(os.homedir(), "worktrees"); const worktreesBaseDir = getWorktreeBaseDir();
const candidatePath = path.join(worktreesBaseDir, baseName); const candidatePath = path.join(worktreesBaseDir, baseName);
// If directory doesn't exist or points to the same project, use base name // If directory doesn't exist or points to the same project, use base name
@ -90,7 +98,7 @@ function getProjectWorktreeDirName(projectDir: string): string {
function writeMcpConfigFile(projectDir: string, mcpServers: any): string | null { function writeMcpConfigFile(projectDir: string, mcpServers: any): string | null {
try { try {
const projectDirName = getProjectWorktreeDirName(projectDir); const projectDirName = getProjectWorktreeDirName(projectDir);
const worktreesDir = path.join(os.homedir(), "worktrees"); const worktreesDir = getWorktreeBaseDir();
if (!fs.existsSync(worktreesDir)) { if (!fs.existsSync(worktreesDir)) {
fs.mkdirSync(worktreesDir, { recursive: true }); fs.mkdirSync(worktreesDir, { recursive: true });
} }
@ -303,7 +311,7 @@ async function createWorktree(projectDir: string, parentBranch: string, sessionN
const git = simpleGit(projectDir); const git = simpleGit(projectDir);
const projectDirName = getProjectWorktreeDirName(projectDir); const projectDirName = getProjectWorktreeDirName(projectDir);
const worktreesBaseDir = path.join(os.homedir(), "worktrees"); const worktreesBaseDir = getWorktreeBaseDir();
const projectWorktreeDir = path.join(worktreesBaseDir, projectDirName); const projectWorktreeDir = path.join(worktreesBaseDir, projectDirName);
const worktreeName = customBranchName || `session${sessionNumber}`; const worktreeName = customBranchName || `session${sessionNumber}`;
const worktreePath = path.join(projectWorktreeDir, worktreeName); const worktreePath = path.join(projectWorktreeDir, worktreeName);

View file

@ -30,6 +30,7 @@ interface TerminalSettings {
fontSize: number; fontSize: number;
theme: string; // Theme preset name theme: string; // Theme preset name
cursorBlink: boolean; cursorBlink: boolean;
worktreeDir: string;
} }
interface ThemeColors { interface ThemeColors {
@ -203,6 +204,7 @@ const DEFAULT_SETTINGS: TerminalSettings = {
fontSize: 11, fontSize: 11,
theme: getSystemTheme() === "dark" ? "macos-dark" : "macos-light", theme: getSystemTheme() === "dark" ? "macos-dark" : "macos-light",
cursorBlink: false, cursorBlink: false,
worktreeDir: require("path").join(require("os").homedir(), "worktrees"),
}; };
const sessions = new Map<string, Session>(); const sessions = new Map<string, Session>();
@ -1217,6 +1219,8 @@ const settingsTheme = document.getElementById("settings-theme") as HTMLSelectEle
const settingsFontFamily = document.getElementById("settings-font-family") as HTMLSelectElement; const settingsFontFamily = document.getElementById("settings-font-family") as HTMLSelectElement;
const settingsFontSize = document.getElementById("settings-font-size") as HTMLInputElement; const settingsFontSize = document.getElementById("settings-font-size") as HTMLInputElement;
const settingsCursorBlink = document.getElementById("settings-cursor-blink") as HTMLInputElement; const settingsCursorBlink = document.getElementById("settings-cursor-blink") as HTMLInputElement;
const settingsWorktreeDir = document.getElementById("settings-worktree-dir") as HTMLInputElement;
const browseWorktreeDirBtn = document.getElementById("browse-worktree-dir");
// Load saved settings on startup // Load saved settings on startup
async function loadSettings() { async function loadSettings() {
@ -1243,6 +1247,7 @@ function populateSettingsForm() {
settingsFontSize.value = terminalSettings.fontSize.toString(); settingsFontSize.value = terminalSettings.fontSize.toString();
settingsCursorBlink.checked = terminalSettings.cursorBlink; settingsCursorBlink.checked = terminalSettings.cursorBlink;
settingsWorktreeDir.value = terminalSettings.worktreeDir;
} }
// Apply settings to all existing terminals // Apply settings to all existing terminals
@ -1281,6 +1286,14 @@ resetSettingsBtn?.addEventListener("click", () => {
populateSettingsForm(); populateSettingsForm();
}); });
// Browse worktree directory
browseWorktreeDirBtn?.addEventListener("click", async () => {
const dir = await ipcRenderer.invoke("select-directory");
if (dir) {
settingsWorktreeDir.value = dir;
}
});
// Save settings // Save settings
saveSettingsBtn?.addEventListener("click", async () => { saveSettingsBtn?.addEventListener("click", async () => {
// Read values from form // Read values from form
@ -1288,6 +1301,7 @@ saveSettingsBtn?.addEventListener("click", async () => {
terminalSettings.fontFamily = settingsFontFamily.value || DEFAULT_SETTINGS.fontFamily; terminalSettings.fontFamily = settingsFontFamily.value || DEFAULT_SETTINGS.fontFamily;
terminalSettings.fontSize = parseInt(settingsFontSize.value) || DEFAULT_SETTINGS.fontSize; terminalSettings.fontSize = parseInt(settingsFontSize.value) || DEFAULT_SETTINGS.fontSize;
terminalSettings.cursorBlink = settingsCursorBlink.checked; terminalSettings.cursorBlink = settingsCursorBlink.checked;
terminalSettings.worktreeDir = settingsWorktreeDir.value || DEFAULT_SETTINGS.worktreeDir;
// Save to electron-store // Save to electron-store
await ipcRenderer.invoke("save-terminal-settings", terminalSettings); await ipcRenderer.invoke("save-terminal-settings", terminalSettings);