@@ -221,6 +221,7 @@ async function loadAndPopulateBranches(
221221 selectedBranch ?: string
222222) : Promise < void > {
223223 const branches = await ipcRenderer . invoke ( "get-branches" , directory ) ;
224+ existingBranches = branches ;
224225 parentBranchSelect . innerHTML = "" ;
225226
226227 if ( branches . length === 0 ) {
@@ -758,6 +759,13 @@ ipcRenderer.on("session-created", (_event, sessionId: string, persistedSession:
758759 if ( setupCommandsTextarea ) {
759760 setupCommandsTextarea . value = "" ;
760761 }
762+
763+ // Reset validation state
764+ const branchNameError = document . getElementById ( "branch-name-error" ) ;
765+ const branchNameHelp = document . getElementById ( "branch-name-help" ) ;
766+ branchNameError ?. classList . add ( "hidden" ) ;
767+ branchNameHelp ?. classList . remove ( "hidden" ) ;
768+ existingBranches = [ ] ;
761769} ) ;
762770
763771// Handle session reopened
@@ -808,8 +816,44 @@ const localDescription = document.getElementById("local-description");
808816const browseDirBtn = document . getElementById ( "browse-dir" ) ;
809817const cancelBtn = document . getElementById ( "cancel-session" ) ;
810818const createBtn = document . getElementById ( "create-session" ) as HTMLButtonElement ;
819+ const branchNameInput = document . getElementById ( "branch-name" ) as HTMLInputElement ;
820+ const branchNameError = document . getElementById ( "branch-name-error" ) ;
821+ const branchNameHelp = document . getElementById ( "branch-name-help" ) ;
811822
812823let selectedDirectory = "" ;
824+ let existingBranches : string [ ] = [ ] ;
825+
826+ // Validate branch name
827+ function validateBranchName ( ) : boolean {
828+ const branchName = branchNameInput ?. value . trim ( ) ;
829+
830+ if ( ! branchName ) {
831+ // Empty branch name is allowed (it's optional)
832+ branchNameError ?. classList . add ( "hidden" ) ;
833+ branchNameHelp ?. classList . remove ( "hidden" ) ;
834+ return true ;
835+ }
836+
837+ // Check if branch already exists
838+ const branchExists = existingBranches . some ( branch =>
839+ branch === branchName || branch === `origin/${ branchName } `
840+ ) ;
841+
842+ if ( branchExists ) {
843+ branchNameError ?. classList . remove ( "hidden" ) ;
844+ branchNameHelp ?. classList . add ( "hidden" ) ;
845+ return false ;
846+ } else {
847+ branchNameError ?. classList . add ( "hidden" ) ;
848+ branchNameHelp ?. classList . remove ( "hidden" ) ;
849+ return true ;
850+ }
851+ }
852+
853+ // Add input event listener for branch name validation
854+ branchNameInput ?. addEventListener ( "input" , ( ) => {
855+ validateBranchName ( ) ;
856+ } ) ;
813857
814858// Toggle skip permissions checkbox visibility based on coding agent
815859codingAgentSelect ?. addEventListener ( "change" , ( ) => {
@@ -914,6 +958,10 @@ cancelBtn?.addEventListener("click", () => {
914958 projectDirInput . value = "" ;
915959 selectedDirectory = "" ;
916960 parentBranchSelect . innerHTML = '<option value="">Loading branches...</option>' ;
961+ branchNameInput . value = "" ;
962+ branchNameError ?. classList . add ( "hidden" ) ;
963+ branchNameHelp ?. classList . remove ( "hidden" ) ;
964+ existingBranches = [ ] ;
917965} ) ;
918966
919967// Create session button
@@ -931,6 +979,12 @@ createBtn?.addEventListener("click", () => {
931979 return ;
932980 }
933981
982+ // Validate branch name doesn't already exist for worktree sessions
983+ if ( sessionType === SessionType . WORKTREE && ! validateBranchName ( ) ) {
984+ alert ( "Cannot create worktree: branch already exists" ) ;
985+ return ;
986+ }
987+
934988 const setupCommandsTextarea = document . getElementById ( "setup-commands" ) as HTMLTextAreaElement ;
935989 const setupCommandsText = setupCommandsTextarea ?. value . trim ( ) ;
936990 const setupCommands = setupCommandsText
0 commit comments