* Generates a unique fork name by checking for collisions with existing session names. * If "baseName (Branch)" already exists, tries "baseName (Branch 2)", "baseName (Branch 3)", etc.
(baseName: string)
| 177 | * If "baseName (Branch)" already exists, tries "baseName (Branch 2)", "baseName (Branch 3)", etc. |
| 178 | */ |
| 179 | async function getUniqueForkName(baseName: string): Promise<string> { |
| 180 | const candidateName = `${baseName} (Branch)` |
| 181 | |
| 182 | // Check if this exact name already exists |
| 183 | const existingWithExactName = await searchSessionsByCustomTitle( |
| 184 | candidateName, |
| 185 | { exact: true }, |
| 186 | ) |
| 187 | |
| 188 | if (existingWithExactName.length === 0) { |
| 189 | return candidateName |
| 190 | } |
| 191 | |
| 192 | // Name collision - find a unique numbered suffix |
| 193 | // Search for all sessions that start with the base pattern |
| 194 | const existingForks = await searchSessionsByCustomTitle(`${baseName} (Branch`) |
| 195 | |
| 196 | // Extract existing fork numbers to find the next available |
| 197 | const usedNumbers = new Set<number>([1]) // Consider " (Branch)" as number 1 |
| 198 | const forkNumberPattern = new RegExp( |
| 199 | `^${escapeRegExp(baseName)} \\(Branch(?: (\\d+))?\\)$`, |
| 200 | ) |
| 201 | |
| 202 | for (const session of existingForks) { |
| 203 | const match = session.customTitle?.match(forkNumberPattern) |
| 204 | if (match) { |
| 205 | if (match[1]) { |
| 206 | usedNumbers.add(parseInt(match[1], 10)) |
| 207 | } else { |
| 208 | usedNumbers.add(1) // " (Branch)" without number is treated as 1 |
| 209 | } |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | // Find the next available number |
| 214 | let nextNumber = 2 |
| 215 | while (usedNumbers.has(nextNumber)) { |
| 216 | nextNumber++ |
| 217 | } |
| 218 | |
| 219 | return `${baseName} (Branch ${nextNumber})` |
| 220 | } |
| 221 | |
| 222 | export async function call( |
| 223 | onDone: LocalJSXCommandOnDone, |
no test coverage detected