diff --git a/index.html b/index.html
index 8a23804..719345a 100644
--- a/index.html
+++ b/index.html
@@ -86,7 +86,8 @@
New Session Configuration
Branch Name (optional)
- Custom branch name for worktree (will also be used as session name)
+ Branch already exists
+ Custom branch name for worktree (will also be used as session name)
diff --git a/renderer.ts b/renderer.ts
index 8f14100..950bf5f 100644
--- a/renderer.ts
+++ b/renderer.ts
@@ -221,6 +221,7 @@ async function loadAndPopulateBranches(
selectedBranch?: string
): Promise {
const branches = await ipcRenderer.invoke("get-branches", directory);
+ existingBranches = branches;
parentBranchSelect.innerHTML = "";
if (branches.length === 0) {
@@ -758,6 +759,13 @@ ipcRenderer.on("session-created", (_event, sessionId: string, persistedSession:
if (setupCommandsTextarea) {
setupCommandsTextarea.value = "";
}
+
+ // Reset validation state
+ const branchNameError = document.getElementById("branch-name-error");
+ const branchNameHelp = document.getElementById("branch-name-help");
+ branchNameError?.classList.add("hidden");
+ branchNameHelp?.classList.remove("hidden");
+ existingBranches = [];
});
// Handle session reopened
@@ -808,8 +816,44 @@ const localDescription = document.getElementById("local-description");
const browseDirBtn = document.getElementById("browse-dir");
const cancelBtn = document.getElementById("cancel-session");
const createBtn = document.getElementById("create-session") as HTMLButtonElement;
+const branchNameInput = document.getElementById("branch-name") as HTMLInputElement;
+const branchNameError = document.getElementById("branch-name-error");
+const branchNameHelp = document.getElementById("branch-name-help");
let selectedDirectory = "";
+let existingBranches: string[] = [];
+
+// Validate branch name
+function validateBranchName(): boolean {
+ const branchName = branchNameInput?.value.trim();
+
+ if (!branchName) {
+ // Empty branch name is allowed (it's optional)
+ branchNameError?.classList.add("hidden");
+ branchNameHelp?.classList.remove("hidden");
+ return true;
+ }
+
+ // Check if branch already exists
+ const branchExists = existingBranches.some(branch =>
+ branch === branchName || branch === `origin/${branchName}`
+ );
+
+ if (branchExists) {
+ branchNameError?.classList.remove("hidden");
+ branchNameHelp?.classList.add("hidden");
+ return false;
+ } else {
+ branchNameError?.classList.add("hidden");
+ branchNameHelp?.classList.remove("hidden");
+ return true;
+ }
+}
+
+// Add input event listener for branch name validation
+branchNameInput?.addEventListener("input", () => {
+ validateBranchName();
+});
// Toggle skip permissions checkbox visibility based on coding agent
codingAgentSelect?.addEventListener("change", () => {
@@ -914,6 +958,10 @@ cancelBtn?.addEventListener("click", () => {
projectDirInput.value = "";
selectedDirectory = "";
parentBranchSelect.innerHTML = 'Loading branches... ';
+ branchNameInput.value = "";
+ branchNameError?.classList.add("hidden");
+ branchNameHelp?.classList.remove("hidden");
+ existingBranches = [];
});
// Create session button
@@ -931,6 +979,12 @@ createBtn?.addEventListener("click", () => {
return;
}
+ // Validate branch name doesn't already exist for worktree sessions
+ if (sessionType === SessionType.WORKTREE && !validateBranchName()) {
+ alert("Cannot create worktree: branch already exists");
+ return;
+ }
+
const setupCommandsTextarea = document.getElementById("setup-commands") as HTMLTextAreaElement;
const setupCommandsText = setupCommandsTextarea?.value.trim();
const setupCommands = setupCommandsText