Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ <h2 class="modal-title">New Session Configuration</h2>
<div class="form-group" id="branch-name-group">
<label class="form-label">Branch Name (optional)</label>
<input type="text" id="branch-name" class="form-input" placeholder="e.g., feature/add-login" />
<span class="text-xs text-gray-400 mt-1 block">Custom branch name for worktree (will also be used as session name)</span>
<span id="branch-name-error" class="text-xs text-red-400 mt-1 hidden">Branch already exists</span>
<span id="branch-name-help" class="text-xs text-gray-400 mt-1 block">Custom branch name for worktree (will also be used as session name)</span>
</div>

<div class="form-group">
Expand Down
54 changes: 54 additions & 0 deletions renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ async function loadAndPopulateBranches(
selectedBranch?: string
): Promise<void> {
const branches = await ipcRenderer.invoke("get-branches", directory);
existingBranches = branches;
parentBranchSelect.innerHTML = "";

if (branches.length === 0) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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", () => {
Expand Down Expand Up @@ -914,6 +958,10 @@ cancelBtn?.addEventListener("click", () => {
projectDirInput.value = "";
selectedDirectory = "";
parentBranchSelect.innerHTML = '<option value="">Loading branches...</option>';
branchNameInput.value = "";
branchNameError?.classList.add("hidden");
branchNameHelp?.classList.remove("hidden");
existingBranches = [];
});

// Create session button
Expand All @@ -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
Expand Down