sync-worktrees 4.0.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/App.d.ts +4 -6
- package/dist/components/App.d.ts.map +1 -1
- package/dist/components/StatusBar.d.ts +3 -0
- package/dist/components/StatusBar.d.ts.map +1 -1
- package/dist/components/WorktreeStatusView.d.ts +3 -6
- package/dist/components/WorktreeStatusView.d.ts.map +1 -1
- package/dist/index.js +199 -27
- package/dist/index.js.map +3 -3
- package/dist/mcp-server.js +7 -4
- package/dist/mcp-server.js.map +2 -2
- package/dist/services/InteractiveUIService.d.ts +6 -6
- package/dist/services/InteractiveUIService.d.ts.map +1 -1
- package/dist/services/git.service.d.ts +3 -1
- package/dist/services/git.service.d.ts.map +1 -1
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/app-events.d.ts +10 -0
- package/dist/utils/app-events.d.ts.map +1 -1
- package/dist/utils/config-generator.d.ts.map +1 -1
- package/dist/utils/git-progress.d.ts +5 -5
- package/package.json +1 -1
package/dist/mcp-server.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/mcp/index.ts", "../src/mcp/context.ts", "../src/constants.ts", "../src/services/config-loader.service.ts", "../src/errors/index.ts", "../src/utils/branch-filter.ts", "../src/utils/file-exists.ts", "../src/utils/git-url.ts", "../src/utils/path-compare.ts", "../src/utils/repo-mode.ts", "../src/utils/sanitize-name.ts", "../src/services/logger.service.ts", "../src/utils/lfs-error.ts", "../src/utils/retry.ts", "../src/utils/timing.ts", "../src/services/clone-sync.service.ts", "../src/utils/git-progress.ts", "../src/services/file-copy.service.ts", "../src/services/branch-created-actions.service.ts", "../src/utils/clone-skip-format.ts", "../src/services/sync-outcome.ts", "../src/services/git.service.ts", "../src/utils/worktree-list-parser.ts", "../src/services/sparse-checkout.service.ts", "../src/services/worktree-metadata.service.ts", "../src/services/worktree-status.service.ts", "../src/services/progress-emitter.ts", "../src/services/repo-operation-lock.ts", "../src/utils/lock-path.ts", "../src/services/sync-retry-policy.ts", "../src/services/worktree-mode-sync-runner.ts", "../src/utils/date-filter.ts", "../src/services/path-resolution.service.ts", "../src/services/worktree-sync-planner.ts", "../src/services/worktree-sync.service.ts", "../src/mcp/server.ts", "../src/mcp/handlers.ts", "../src/utils/disk-space.ts", "../src/utils/git-validation.ts", "../src/mcp/utils.ts", "../src/mcp/worktree-summary.ts"],
|
|
4
|
-
"sourcesContent": ["import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\n\nimport { RepositoryContext } from \"./context\";\nimport { createServer } from \"./server\";\n\nimport type { DiscoveredRepoContext } from \"./context\";\n\nasync function main(): Promise<void> {\n const context = new RepositoryContext();\n\n const configPath = process.env.SYNC_WORKTREES_CONFIG;\n if (configPath) {\n try {\n await context.loadConfig(configPath);\n process.stderr.write(`[sync-worktrees-mcp] Loaded config: ${configPath}\\n`);\n } catch (err) {\n process.stderr.write(`[sync-worktrees-mcp] Failed to load SYNC_WORKTREES_CONFIG: ${(err as Error).message}\\n`);\n }\n }\n\n let discovered: DiscoveredRepoContext | null = null;\n try {\n discovered = await context.detectFromPath(process.cwd());\n if (discovered.isWorktree) {\n process.stderr.write(\n `[sync-worktrees-mcp] Auto-detected ${discovered.kind} worktree at ${discovered.currentWorktreePath} (branch: ${discovered.currentBranch})\\n`,\n );\n }\n } catch (err) {\n process.stderr.write(`[sync-worktrees-mcp] Auto-detect failed: ${(err as Error).message}\\n`);\n }\n\n const server = createServer(context, {\n discovered,\n configuredRepoCount: context.getConfiguredRepositoryNames().length,\n });\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n process.stderr.write(`[sync-worktrees-mcp] Fatal error: ${(err as Error).message}\\n`);\n process.exit(1);\n});\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport pLimit from \"p-limit\";\nimport simpleGit from \"simple-git\";\n\nimport { DEFAULT_CONFIG, GIT_CONSTANTS } from \"../constants\";\nimport { ConfigLoaderService } from \"../services/config-loader.service\";\nimport { Logger } from \"../services/logger.service\";\nimport { WorktreeSyncService } from \"../services/worktree-sync.service\";\nimport { normalizePathForCompare } from \"../utils/path-compare\";\nimport { REPOSITORY_MODES, resolveMode } from \"../utils/repo-mode\";\nimport { parseWorktreeListPorcelain } from \"../utils/worktree-list-parser\";\n\nimport type { Config, RepositoryConfig } from \"../types\";\nimport type { Divergence, WorktreeLabel } from \"./worktree-summary\";\n\nexport interface CapabilityState {\n available: boolean;\n reason?: string;\n}\n\nexport interface Capabilities {\n listWorktrees: CapabilityState;\n getStatus: CapabilityState;\n createWorktree: CapabilityState;\n removeWorktree: CapabilityState;\n updateWorktree: CapabilityState;\n sync: CapabilityState;\n initialize: CapabilityState;\n}\n\nexport interface DiscoveredWorktree {\n path: string;\n branch: string;\n isCurrent: boolean;\n label?: WorktreeLabel;\n divergence?: Divergence | null;\n staleHint?: boolean;\n}\n\nexport interface SiblingRepository {\n name: string;\n bareRepoPath: string;\n worktreeDir: string | null;\n repoUrl: string | null;\n sparseCheckout?: RepositoryConfig[\"sparseCheckout\"];\n present: boolean;\n configMatched: boolean;\n}\n\ninterface ConfiguredRepositorySummaryBase {\n name: string;\n isCurrent: boolean;\n repoUrl?: string;\n branch?: string;\n sparseCheckout?: RepositoryConfig[\"sparseCheckout\"];\n localReady?: boolean;\n}\n\nexport interface ConfiguredCloneRepositorySummary extends ConfiguredRepositorySummaryBase {\n mode: \"clone\";\n checkoutPath: string;\n}\n\nexport interface ConfiguredWorktreeRepositorySummary extends ConfiguredRepositorySummaryBase {\n mode: \"worktree\";\n worktreeDir: string;\n bareRepoDir?: string;\n}\n\nexport type ConfiguredRepositorySummary = ConfiguredCloneRepositorySummary | ConfiguredWorktreeRepositorySummary;\n\nexport interface DiscoveredRepoContext {\n isWorktree: boolean;\n kind: \"managed\" | \"unmanaged\" | \"unsupported\";\n currentBranch: string | null;\n currentWorktreePath: string | null;\n bareRepoPath: string | null;\n repoUrl: string | null;\n worktreeDir: string | null;\n allWorktrees: DiscoveredWorktree[];\n allWorktreesByRepo?: Record<string, DiscoveredWorktree[]>;\n allWorktreeErrorsByRepo?: Record<string, string>;\n siblingRepositories: SiblingRepository[];\n configPath: string | null;\n repoName: string | null;\n capabilities: Capabilities;\n notes: string[];\n}\n\ninterface RepoEntry {\n name: string;\n config: Config;\n source: \"config\" | \"detected\";\n service?: WorktreeSyncService;\n discovered?: DiscoveredRepoContext;\n}\n\ntype RepositorySelectionDecision =\n | { kind: \"selected\"; repoName: string; source: \"current\" | \"explicit\" | \"single-config\" }\n | { kind: \"ambiguous\"; configured: string[]; detected: string[]; reason: string }\n | { kind: \"missing\"; configured: string[]; detected: string[]; reason: string };\n\ninterface RepositorySelectionState {\n currentRepo: string | null;\n configured: string[];\n detected: string[];\n defaultDecision: RepositorySelectionDecision;\n}\n\ninterface CachedDiscovery {\n result: DiscoveredRepoContext;\n cachedAt: number;\n worktreeAdminDir: string | null;\n worktreeHeadMtimeMs: number | null;\n worktreesDirMtimeMs: number | null;\n}\n\nconst AUTO_DETECT_PREFIX = \"__auto_detected__:\";\nconst DISCOVERY_CACHE_TTL_MS = 5000;\n\nfunction emptyCapabilities(reason?: string): Capabilities {\n const state: CapabilityState = reason ? { available: false, reason } : { available: false };\n return {\n listWorktrees: { ...state },\n getStatus: { ...state },\n createWorktree: { ...state },\n removeWorktree: { ...state },\n updateWorktree: { ...state },\n sync: { ...state },\n initialize: { ...state },\n };\n}\n\nexport function buildUnsupportedContext(currentPath: string, reason: string): DiscoveredRepoContext {\n return {\n isWorktree: false,\n kind: \"unsupported\",\n currentBranch: null,\n currentWorktreePath: currentPath,\n bareRepoPath: null,\n repoUrl: null,\n worktreeDir: null,\n allWorktrees: [],\n siblingRepositories: [],\n configPath: null,\n repoName: null,\n capabilities: emptyCapabilities(reason),\n notes: [reason],\n };\n}\n\nfunction createStderrLogger(repoName?: string): Logger {\n return new Logger({\n repoName,\n outputFn: (msg: string): void => {\n process.stderr.write(msg + \"\\n\");\n },\n });\n}\n\nexport class RepositoryContext {\n private repos = new Map<string, RepoEntry>();\n private currentRepo: string | null = null;\n private configPath: string | null = null;\n private configLoader = new ConfigLoaderService();\n private discoveryCache = new Map<string, CachedDiscovery>();\n private readonly launchCwd: string;\n\n constructor(options: { launchCwd?: string } = {}) {\n this.launchCwd = path.resolve(options.launchCwd ?? process.cwd());\n }\n\n getLaunchCwd(): string {\n return this.launchCwd;\n }\n\n async loadConfig(configPath: string, options: { setDefaultCurrent?: boolean } = {}): Promise<RepositoryConfig[]> {\n const setDefaultCurrent = options.setDefaultCurrent ?? true;\n const absolutePath = path.resolve(configPath);\n const configFile = await this.configLoader.loadConfigFile(absolutePath);\n\n const configDir = path.dirname(absolutePath);\n const globalDefaults = configFile.defaults;\n\n const resolvedAll: RepositoryConfig[] = [];\n for (const repo of configFile.repositories) {\n const resolved = this.configLoader.resolveRepositoryConfig(\n repo,\n globalDefaults,\n configDir,\n configFile.retry,\n configFile.repositories,\n );\n resolvedAll.push(resolved);\n }\n this.configLoader.detectBareRepoDirCollisions(resolvedAll);\n\n for (const [name, entry] of this.repos) {\n if (entry.source === \"config\") {\n this.repos.delete(name);\n }\n }\n\n this.configPath = absolutePath;\n for (const resolved of resolvedAll) {\n this.repos.set(resolved.name, {\n name: resolved.name,\n config: resolved,\n source: \"config\",\n });\n }\n\n if (this.currentRepo && !this.repos.has(this.currentRepo)) {\n this.currentRepo = null;\n }\n\n if (setDefaultCurrent && !this.currentRepo && configFile.repositories.length > 0) {\n this.currentRepo = configFile.repositories[0].name;\n }\n\n this.discoveryCache.clear();\n\n return configFile.repositories;\n }\n\n async detectFromPath(dirPath: string): Promise<DiscoveredRepoContext> {\n const absolutePath = path.resolve(dirPath);\n\n const cached = this.discoveryCache.get(absolutePath);\n if (cached && (await this.isCacheFresh(cached))) {\n return cached.result;\n }\n\n if (this.configPath === null) {\n const found = await this.configLoader.findConfigUpward(absolutePath);\n if (found) {\n try {\n await this.loadConfig(found, { setDefaultCurrent: false });\n } catch (err) {\n process.stderr.write(`[sync-worktrees] auto-loaded config failed: ${(err as Error).message}\\n`);\n }\n }\n }\n\n const { result, adminDir } = await this.detectFromPathUncached(absolutePath);\n\n if (result.isWorktree && result.bareRepoPath && adminDir) {\n const [worktreeHeadMtimeMs, worktreesDirMtimeMs] = await Promise.all([\n safeMtimeMs(path.join(adminDir, \"HEAD\")),\n safeMtimeMs(path.join(result.bareRepoPath, \"worktrees\")),\n ]);\n this.discoveryCache.set(absolutePath, {\n result,\n cachedAt: Date.now(),\n worktreeAdminDir: adminDir,\n worktreeHeadMtimeMs,\n worktreesDirMtimeMs,\n });\n }\n\n return result;\n }\n\n invalidateDiscovered(): void {\n this.discoveryCache.clear();\n }\n\n /** @internal Test-only helper \u2014 registers a repo entry without going through config loading. */\n __registerForTest(name: string, entry: Omit<RepoEntry, \"name\">): void {\n this.repos.set(name, { ...entry, name });\n }\n\n /** @internal Test-only helper \u2014 sets the current repo pointer. */\n __setCurrentRepoForTest(name: string | null): void {\n this.currentRepo = name;\n }\n\n /** @internal Test-only helper \u2014 returns the size of the internal repo map. */\n __repoCountForTest(): number {\n return this.repos.size;\n }\n\n /** @internal Test-only helper \u2014 returns the size of the discovery cache. */\n __discoveryCacheSizeForTest(): number {\n return this.discoveryCache.size;\n }\n\n /** @internal Test-only helper \u2014 exposes the internal selection state. */\n __getRepositorySelectionStateForTest(): unknown {\n return this.getRepositorySelectionState();\n }\n\n private async discoverSiblingRepositories(currentBareRepoPath: string): Promise<SiblingRepository[]> {\n const currentBare = normalizePathForCompare(currentBareRepoPath);\n const results = new Map<string, SiblingRepository>();\n const byName = (a: SiblingRepository, b: SiblingRepository): number => a.name.localeCompare(b.name);\n\n const configCandidates = Array.from(this.repos.values())\n .filter((entry) => entry.source === \"config\" && !!entry.config.bareRepoDir)\n .map((entry) => {\n const bareRepoPath = path.resolve(entry.config.bareRepoDir as string);\n return { entry, bareRepoPath, foldedBare: normalizePathForCompare(bareRepoPath) };\n })\n .filter((c) => c.foldedBare !== currentBare);\n\n const configPresence = await Promise.all(configCandidates.map((c) => isDirectory(c.bareRepoPath)));\n configCandidates.forEach(({ entry, bareRepoPath, foldedBare }, i) => {\n const sibling: SiblingRepository = {\n name: entry.name,\n bareRepoPath,\n worktreeDir: path.resolve(entry.config.worktreeDir),\n repoUrl: entry.config.repoUrl,\n present: configPresence[i],\n configMatched: true,\n };\n if (entry.config.sparseCheckout) {\n sibling.sparseCheckout = entry.config.sparseCheckout;\n }\n results.set(foldedBare, sibling);\n });\n\n const repoDir = path.dirname(currentBareRepoPath);\n const workspaceRoot = path.dirname(repoDir);\n\n if (workspaceRoot === repoDir) {\n return Array.from(results.values()).sort(byName);\n }\n\n let entries: string[];\n try {\n entries = await fs.readdir(workspaceRoot);\n } catch {\n return Array.from(results.values()).sort(byName);\n }\n\n const configBares = new Map(configCandidates.map((c) => [c.foldedBare, c.entry.name]));\n\n await Promise.all(\n entries.map(async (entry) => {\n const candidate = path.join(workspaceRoot, entry);\n const bareCandidate = path.join(candidate, GIT_CONSTANTS.BARE_DIR_NAME);\n if (!(await isDirectory(bareCandidate))) return;\n\n const resolvedBare = path.resolve(bareCandidate);\n const foldedBare = normalizePathForCompare(resolvedBare);\n if (foldedBare === currentBare || results.has(foldedBare)) return;\n\n const matchedName = configBares.get(foldedBare);\n results.set(foldedBare, {\n name: matchedName ?? entry,\n bareRepoPath: resolvedBare,\n worktreeDir: null,\n repoUrl: null,\n present: true,\n configMatched: matchedName !== undefined,\n });\n }),\n );\n\n return Array.from(results.values()).sort(byName);\n }\n\n private bootstrapCurrentRepo(candidate: string, force = false): void {\n if (this.currentRepo !== null) return;\n if (!this.repos.has(candidate)) return;\n if (!force && this.repos.size !== 1) return;\n this.currentRepo = candidate;\n }\n\n private async isCacheFresh(cached: CachedDiscovery): Promise<boolean> {\n if (Date.now() - cached.cachedAt >= DISCOVERY_CACHE_TTL_MS) return false;\n if (!cached.worktreeAdminDir || !cached.result.bareRepoPath) return true;\n\n const [currentHeadMtime, currentWorktreesDirMtime] = await Promise.all([\n safeMtimeMs(path.join(cached.worktreeAdminDir, \"HEAD\")),\n safeMtimeMs(path.join(cached.result.bareRepoPath, \"worktrees\")),\n ]);\n\n return currentHeadMtime === cached.worktreeHeadMtimeMs && currentWorktreesDirMtime === cached.worktreesDirMtimeMs;\n }\n\n private async detectFromPathUncached(\n absolutePath: string,\n ): Promise<{ result: DiscoveredRepoContext; adminDir: string | null }> {\n const notes: string[] = [];\n\n const located = await findWorktreeRoot(absolutePath);\n const worktreeRoot = located?.worktreeRoot ?? absolutePath;\n\n const unsupported = (reason: string): { result: DiscoveredRepoContext; adminDir: string | null } => {\n notes.push(reason);\n return {\n result: {\n isWorktree: false,\n kind: \"unsupported\",\n currentBranch: null,\n currentWorktreePath: worktreeRoot,\n bareRepoPath: null,\n repoUrl: null,\n worktreeDir: null,\n allWorktrees: [],\n siblingRepositories: [],\n configPath: this.configPath,\n repoName: null,\n capabilities: emptyCapabilities(reason),\n notes,\n },\n adminDir: null,\n };\n };\n\n if (!located) {\n return unsupported(\"No .git file found in path or any parent directory\");\n }\n if (located.kind === \"regular-git-dir\") {\n const cloneEntry = this.findConfiguredCloneEntry(worktreeRoot);\n if (cloneEntry) {\n return {\n result: await this.buildCloneModeContext(cloneEntry, worktreeRoot, notes),\n adminDir: null,\n };\n }\n return unsupported(\"Directory has .git folder (regular repo, not a sync-worktrees worktree)\");\n }\n\n const gitFileContent = located.gitFileContent;\n\n const gitdirMatch = gitFileContent.match(/^gitdir:\\s*(.+)$/m);\n if (!gitdirMatch) {\n return unsupported(\"Invalid .git file format (missing gitdir line)\");\n }\n\n const gitdir = gitdirMatch[1].trim();\n const resolvedGitdir = path.isAbsolute(gitdir) ? gitdir : path.resolve(worktreeRoot, gitdir);\n const worktreesMatch = resolvedGitdir.match(/^(.+?)[/\\\\]worktrees[/\\\\][^/\\\\]+$/);\n if (!worktreesMatch) {\n return unsupported(\"gitdir does not follow worktree structure (missing /worktrees/<name>)\");\n }\n\n const bareRepoPath = path.resolve(worktreesMatch[1]);\n const adminDir = path.resolve(resolvedGitdir);\n\n let repoUrl: string | null = null;\n let worktrees: DiscoveredWorktree[] = [];\n let currentBranch: string | null = null;\n\n try {\n const bareGit = simpleGit(bareRepoPath);\n\n try {\n const remoteResult = await bareGit.remote([\"get-url\", \"origin\"]);\n const urlStr = typeof remoteResult === \"string\" ? remoteResult.trim() : \"\";\n repoUrl = urlStr || null;\n } catch {\n notes.push(\"Could not read remote origin URL\");\n }\n\n const listOutput = await bareGit.raw([\"worktree\", \"list\", \"--porcelain\"]);\n worktrees = parseWorktreeList(listOutput, worktreeRoot);\n const current = worktrees.find((w) => w.isCurrent);\n if (current) {\n currentBranch = current.branch;\n }\n } catch (err) {\n const reason = `Failed to read bare repo at ${bareRepoPath}: ${(err as Error).message}`;\n notes.push(reason);\n return {\n result: {\n isWorktree: true,\n kind: \"unsupported\",\n currentBranch: null,\n currentWorktreePath: worktreeRoot,\n bareRepoPath,\n repoUrl: null,\n worktreeDir: null,\n allWorktrees: [],\n siblingRepositories: [],\n configPath: this.configPath,\n repoName: null,\n capabilities: emptyCapabilities(reason),\n notes,\n },\n adminDir,\n };\n }\n\n const worktreeDir = path.dirname(worktreeRoot);\n\n const noUrlReason = \"no remote origin URL detected\";\n const capabilities: Capabilities = {\n listWorktrees: { available: true },\n getStatus: { available: true },\n createWorktree: repoUrl !== null ? { available: true } : { available: false, reason: noUrlReason },\n removeWorktree: { available: true },\n updateWorktree: { available: true },\n sync: { available: false, reason: \"no config and no remote URL\" },\n initialize: { available: false, reason: \"no config and no remote URL\" },\n };\n\n const foldedBare = normalizePathForCompare(bareRepoPath);\n let matchedConfig: RepoEntry | null = null;\n for (const entry of this.repos.values()) {\n if (entry.source === \"config\" && entry.config.bareRepoDir) {\n if (normalizePathForCompare(entry.config.bareRepoDir) === foldedBare) {\n matchedConfig = entry;\n break;\n }\n }\n }\n\n let repoName: string | null = null;\n let kind: DiscoveredRepoContext[\"kind\"] = \"unmanaged\";\n\n if (matchedConfig) {\n repoName = matchedConfig.name;\n kind = \"managed\";\n capabilities.sync = { available: true };\n capabilities.initialize = { available: true };\n } else if (repoUrl) {\n const syntheticConfig: Config = {\n repoUrl,\n worktreeDir,\n bareRepoDir: bareRepoPath,\n cronSchedule: DEFAULT_CONFIG.CRON_SCHEDULE,\n runOnce: true,\n };\n const detectedKey = `${AUTO_DETECT_PREFIX}${path.basename(bareRepoPath)}@${bareRepoPath}`;\n if (!this.repos.has(detectedKey)) {\n this.repos.set(detectedKey, {\n name: detectedKey,\n config: syntheticConfig,\n source: \"detected\",\n });\n }\n repoName = detectedKey;\n const autoReason = \"no config file loaded (running in auto-detect mode)\";\n capabilities.sync = { available: false, reason: autoReason };\n capabilities.initialize = { available: false, reason: autoReason };\n }\n\n if (repoName) {\n this.bootstrapCurrentRepo(repoName, matchedConfig !== null);\n }\n\n const siblingRepositories = await this.discoverSiblingRepositories(bareRepoPath);\n\n const discovered: DiscoveredRepoContext = {\n isWorktree: true,\n kind,\n currentBranch,\n currentWorktreePath: worktreeRoot,\n bareRepoPath,\n repoUrl,\n worktreeDir,\n allWorktrees: worktrees,\n siblingRepositories,\n configPath: this.configPath,\n repoName,\n capabilities,\n notes,\n };\n\n if (repoName) {\n const entry = this.repos.get(repoName);\n if (entry) {\n entry.discovered = discovered;\n }\n }\n\n return { result: discovered, adminDir };\n }\n\n async getService(repoName?: string): Promise<WorktreeSyncService> {\n if (repoName) {\n const explicit = this.selectExplicitRepository(repoName);\n if (explicit.kind !== \"selected\") {\n throw new Error(this.buildRepoNotFoundError(repoName));\n }\n }\n\n const name = repoName ?? this.currentRepo;\n if (!name) {\n throw new Error(this.buildNoRepoSelectedError());\n }\n const entry = this.repos.get(name);\n if (!entry) {\n throw new Error(this.buildRepoNotFoundError(name));\n }\n if (!entry.service) {\n const logger = createStderrLogger(entry.name);\n entry.service = new WorktreeSyncService({\n ...entry.config,\n logger,\n });\n }\n return entry.service;\n }\n\n private getRepositorySelectionState(): RepositorySelectionState {\n const configured = this.getConfiguredRepositoryNames();\n const detected = this.getDetectedRepositoryNames();\n return {\n currentRepo: this.currentRepo,\n configured,\n detected,\n defaultDecision: this.selectDefaultRepository(configured, detected),\n };\n }\n\n private selectExplicitRepository(repoName: string): RepositorySelectionDecision {\n if (this.repos.has(repoName)) {\n return { kind: \"selected\", repoName, source: \"explicit\" };\n }\n return {\n kind: \"missing\",\n configured: this.getConfiguredRepositoryNames(),\n detected: this.getDetectedRepositoryNames(),\n reason: `Repository '${repoName}' not found`,\n };\n }\n\n private selectDefaultRepository(\n configured = this.getConfiguredRepositoryNames(),\n detected = this.getDetectedRepositoryNames(),\n ): RepositorySelectionDecision {\n if (this.currentRepo !== null) {\n return { kind: \"selected\", repoName: this.currentRepo, source: \"current\" };\n }\n if (this.canAutoSelectSingleConfig(configured, detected)) {\n return { kind: \"selected\", repoName: configured[0], source: \"single-config\" };\n }\n if (configured.length === 0 && detected.length === 0) {\n return {\n kind: \"missing\",\n configured,\n detected,\n reason: \"no configured or detected repositories are registered\",\n };\n }\n return {\n kind: \"ambiguous\",\n configured,\n detected,\n reason: \"repository selection is ambiguous without currentRepo or explicit repoName\",\n };\n }\n\n private canAutoSelectSingleConfig(\n configured = this.getConfiguredRepositoryNames(),\n detected = this.getDetectedRepositoryNames(),\n ): boolean {\n return this.currentRepo === null && configured.length === 1 && detected.length === 0;\n }\n\n private getDetectedRepositoryNames(): string[] {\n return Array.from(this.repos.values())\n .filter((entry) => entry.source === \"detected\")\n .map((entry) => entry.name);\n }\n\n private formatDetectedRepositoryNames(): string[] {\n return Array.from(this.repos.values())\n .filter((e) => e.source === \"detected\")\n .map((e) => {\n const location = e.discovered?.currentWorktreePath ?? e.config.bareRepoDir ?? e.config.worktreeDir;\n return location ? `${e.name} (${location})` : e.name;\n });\n }\n\n private formatKnownRepositoryNames(names: string[]): string {\n return names.length === 0 ? \"[]\" : `[${names.join(\", \")}]`;\n }\n\n private buildNoRepoSelectedError(): string {\n const selection = this.getRepositorySelectionState();\n const detected = this.formatDetectedRepositoryNames();\n const parts = [\n \"No repository specified and no current repository set.\",\n `launchCwd=${this.launchCwd}`,\n `configPath=${this.configPath ?? \"none\"}`,\n `loadedRepos=${this.repos.size} (config: ${selection.configured.length}, detected: ${selection.detected.length})`,\n ];\n if (detected.length > 0) {\n parts.push(`Detected repos: ${this.formatKnownRepositoryNames(detected)}.`);\n }\n if (selection.configured.length > 0) {\n parts.push(`Configured repos: ${this.formatKnownRepositoryNames(selection.configured)}.`);\n }\n if (selection.configured.length > 0 || detected.length > 0) {\n parts.push(\"Recovery: call set_current_repository with one of the repo names above or pass repoName explicitly.\");\n } else {\n parts.push(\n \"Recovery: call detect_context {path: <workspace>}, load_config {configPath: <file>}, set SYNC_WORKTREES_CONFIG env var, or pass repoName explicitly.\",\n );\n }\n return parts.join(\" \");\n }\n\n private buildRepoNotFoundError(name: string): string {\n const known = Array.from(this.repos.keys());\n const knownStr = this.formatKnownRepositoryNames(known);\n return `Repository '${name}' not found. Known repos: ${knownStr}. Run load_config or detect_context to register it.`;\n }\n\n getEntry(repoName?: string): RepoEntry | null {\n const name = repoName ?? this.currentRepo;\n if (!name) return null;\n return this.repos.get(name) ?? null;\n }\n\n getDiscoveredContext(repoName?: string): DiscoveredRepoContext | null {\n const entry = this.getEntry(repoName);\n return entry?.discovered ?? null;\n }\n\n getCurrentRepo(): string | null {\n return this.currentRepo;\n }\n\n setCurrentRepo(repoName: string): void {\n if (!this.repos.has(repoName)) {\n throw new Error(`Repository '${repoName}' not found`);\n }\n this.currentRepo = repoName;\n }\n\n getRepositoryList(): Array<{ name: string; repoUrl: string; worktreeDir: string; source: \"config\" | \"detected\" }> {\n return Array.from(this.repos.values()).map((e) => ({\n name: e.name,\n repoUrl: e.config.repoUrl,\n worktreeDir: e.config.worktreeDir,\n source: e.source,\n }));\n }\n\n getConfiguredRepositoryNames(): string[] {\n return Array.from(this.repos.values())\n .filter((entry) => entry.source === \"config\")\n .map((entry) => entry.name);\n }\n\n async getConfiguredRepositorySummaries(options: { detailed?: boolean } = {}): Promise<ConfiguredRepositorySummary[]> {\n const entries = Array.from(this.repos.values()).filter((entry) => entry.source === \"config\");\n const currentRepo = this.currentRepo;\n\n const buildLean = (entry: RepoEntry): ConfiguredRepositorySummary => {\n const mode = resolveMode(entry.config);\n const isCurrent = entry.name === currentRepo;\n if (mode === REPOSITORY_MODES.CLONE) {\n return { name: entry.name, mode: \"clone\", checkoutPath: path.resolve(entry.config.worktreeDir), isCurrent };\n }\n return { name: entry.name, mode: \"worktree\", worktreeDir: path.resolve(entry.config.worktreeDir), isCurrent };\n };\n\n if (!options.detailed) {\n return entries.map(buildLean);\n }\n\n const limit = pLimit(DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\n return Promise.all(\n entries.map((entry) =>\n limit(async () => {\n const summary = buildLean(entry);\n summary.repoUrl = entry.config.repoUrl;\n if (entry.config.branch) summary.branch = entry.config.branch;\n if (entry.config.sparseCheckout) {\n const sc = entry.config.sparseCheckout;\n summary.sparseCheckout = {\n ...sc,\n include: [...sc.include],\n ...(sc.exclude ? { exclude: [...sc.exclude] } : {}),\n };\n }\n\n if (summary.mode === \"clone\") {\n summary.localReady = await isGitCheckout(summary.checkoutPath);\n return summary;\n }\n\n if (entry.config.bareRepoDir) {\n summary.bareRepoDir = path.resolve(entry.config.bareRepoDir);\n summary.localReady = await isDirectory(summary.bareRepoDir);\n } else {\n summary.localReady = false;\n }\n return summary;\n }),\n ),\n );\n }\n\n autoSelectCurrentRepoIfSingleConfig(): string | null {\n const decision = this.selectDefaultRepository();\n if (decision.kind !== \"selected\") return null;\n if (decision.source === \"single-config\") {\n this.currentRepo = decision.repoName;\n }\n return this.currentRepo;\n }\n\n async getAllConfiguredWorktreeDetails(\n currentWorktreePath: string | null = null,\n ): Promise<{ worktreesByRepo: Record<string, DiscoveredWorktree[]>; errorsByRepo: Record<string, string> }> {\n const entries = Array.from(this.repos.values()).filter((entry) => entry.source === \"config\");\n const results = await Promise.all(\n entries.map(async (entry) => ({\n name: entry.name,\n result: await this.readConfiguredWorktrees(entry, currentWorktreePath),\n })),\n );\n\n const worktreesByRepo: Record<string, DiscoveredWorktree[]> = {};\n const errorsByRepo: Record<string, string> = {};\n\n for (const entry of results) {\n worktreesByRepo[entry.name] = entry.result.worktrees;\n if (entry.result.error) {\n errorsByRepo[entry.name] = entry.result.error;\n }\n }\n\n return { worktreesByRepo, errorsByRepo };\n }\n\n getConfigPath(): string | null {\n return this.configPath;\n }\n\n private async readConfiguredWorktrees(\n entry: RepoEntry,\n currentWorktreePath: string | null,\n ): Promise<{ worktrees: DiscoveredWorktree[]; error?: string }> {\n if (entry.source === \"config\" && resolveMode(entry.config) === REPOSITORY_MODES.CLONE) {\n return this.readConfiguredCloneWorktree(entry, currentWorktreePath);\n }\n\n if (entry.source !== \"config\" || !entry.config.bareRepoDir) return { worktrees: [] };\n\n const bareRepoPath = path.resolve(entry.config.bareRepoDir);\n if (!(await isDirectory(bareRepoPath))) return { worktrees: [] };\n\n try {\n const output = await simpleGit(bareRepoPath).raw([\"worktree\", \"list\", \"--porcelain\"]);\n return { worktrees: parseWorktreeList(output, currentWorktreePath) };\n } catch (err) {\n return { worktrees: [], error: err instanceof Error ? err.message : String(err) };\n }\n }\n\n private findConfiguredCloneEntry(worktreeRoot: string): RepoEntry | null {\n const foldedRoot = normalizePathForCompare(path.resolve(worktreeRoot));\n for (const entry of this.repos.values()) {\n if (entry.source !== \"config\" || resolveMode(entry.config) !== REPOSITORY_MODES.CLONE) continue;\n if (normalizePathForCompare(path.resolve(entry.config.worktreeDir)) === foldedRoot) {\n return entry;\n }\n }\n return null;\n }\n\n private async buildCloneModeContext(\n entry: RepoEntry,\n worktreeRoot: string,\n notes: string[],\n ): Promise<DiscoveredRepoContext> {\n const resolvedRoot = path.resolve(worktreeRoot);\n let currentBranch: string | null = null;\n try {\n currentBranch = await readCurrentBranch(resolvedRoot);\n } catch (err) {\n notes.push(`Could not read clone-mode branch: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n const branch = currentBranch ?? \"unknown\";\n const cloneModeReason = \"clone-mode repositories have a single checkout; use sync for clone-mode updates\";\n const capabilities: Capabilities = {\n listWorktrees: { available: true },\n getStatus: { available: true },\n createWorktree: { available: false, reason: cloneModeReason },\n removeWorktree: { available: false, reason: cloneModeReason },\n updateWorktree: { available: false, reason: cloneModeReason },\n sync: { available: true },\n initialize: { available: true },\n };\n\n const discovered: DiscoveredRepoContext = {\n isWorktree: true,\n kind: \"managed\",\n currentBranch,\n currentWorktreePath: resolvedRoot,\n bareRepoPath: null,\n repoUrl: entry.config.repoUrl,\n worktreeDir: resolvedRoot,\n allWorktrees: [{ path: resolvedRoot, branch, isCurrent: true }],\n siblingRepositories: [],\n configPath: this.configPath,\n repoName: entry.name,\n capabilities,\n notes,\n };\n\n entry.discovered = discovered;\n this.bootstrapCurrentRepo(entry.name, true);\n return discovered;\n }\n\n private async readConfiguredCloneWorktree(\n entry: RepoEntry,\n currentWorktreePath: string | null,\n ): Promise<{ worktrees: DiscoveredWorktree[]; error?: string }> {\n const worktreePath = path.resolve(entry.config.worktreeDir);\n if (!(await isDirectory(worktreePath)) || !(await hasGitMetadata(worktreePath))) {\n return { worktrees: [] };\n }\n\n try {\n const branch = await readCurrentBranch(worktreePath);\n return {\n worktrees: [\n {\n path: worktreePath,\n branch,\n isCurrent:\n currentWorktreePath !== null &&\n normalizePathForCompare(worktreePath) === normalizePathForCompare(currentWorktreePath),\n },\n ],\n };\n } catch (err) {\n return { worktrees: [], error: err instanceof Error ? err.message : String(err) };\n }\n }\n}\n\nfunction parseWorktreeList(output: string, currentPath: string | null): DiscoveredWorktree[] {\n const foldedCurrent = currentPath ? normalizePathForCompare(currentPath) : null;\n const results: DiscoveredWorktree[] = [];\n for (const wt of parseWorktreeListPorcelain(output)) {\n const resolved = path.resolve(wt.path);\n const branch = wt.branch ?? (wt.detached ? `(detached ${(wt.head ?? \"\").slice(0, 7)})` : null);\n if (!branch) continue;\n results.push({\n path: resolved,\n branch,\n isCurrent: foldedCurrent !== null && normalizePathForCompare(resolved) === foldedCurrent,\n });\n }\n return results;\n}\n\ntype FindResult =\n | { kind: \"worktree-file\"; worktreeRoot: string; gitFileContent: string }\n | { kind: \"regular-git-dir\"; worktreeRoot: string };\n\nasync function safeMtimeMs(filePath: string): Promise<number | null> {\n try {\n const stat = await fs.stat(filePath);\n return stat.mtimeMs;\n } catch {\n return null;\n }\n}\n\nasync function isDirectory(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath);\n return stat.isDirectory();\n } catch {\n return false;\n }\n}\n\nasync function hasGitMetadata(worktreePath: string): Promise<boolean> {\n try {\n await fs.stat(path.join(worktreePath, \".git\"));\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isGitCheckout(checkoutPath: string): Promise<boolean> {\n if (!(await isDirectory(checkoutPath))) return false;\n try {\n const inside = (await simpleGit(checkoutPath).raw([\"rev-parse\", \"--is-inside-work-tree\"])).trim();\n return inside === \"true\";\n } catch {\n return false;\n }\n}\n\nasync function readCurrentBranch(worktreePath: string): Promise<string> {\n const git = simpleGit(worktreePath);\n const branch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n if (branch && branch !== \"HEAD\") {\n return branch;\n }\n\n const head = (await git.raw([\"rev-parse\", \"--short\", \"HEAD\"])).trim();\n return head ? `(detached ${head})` : \"(detached)\";\n}\n\nasync function findWorktreeRoot(startPath: string): Promise<FindResult | null> {\n let current = path.resolve(startPath);\n const root = path.parse(current).root;\n\n while (true) {\n const gitPath = path.join(current, \".git\");\n try {\n const content = await fs.readFile(gitPath, \"utf-8\");\n return { kind: \"worktree-file\", worktreeRoot: current, gitFileContent: content };\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === \"EISDIR\") {\n return { kind: \"regular-git-dir\", worktreeRoot: current };\n }\n if (code !== \"ENOENT\") {\n return null;\n }\n }\n if (current === root) return null;\n const parent = path.dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n}\n", "export const GIT_CONSTANTS = {\n REMOTE_PREFIX: \"origin/\",\n REMOTE_NAME: \"origin\",\n HEAD_REF: \"/HEAD\",\n DEFAULT_BRANCH: \"main\",\n COMMON_DEFAULT_BRANCHES: [\"main\", \"master\", \"develop\", \"trunk\"],\n BARE_DIR_NAME: \".bare\",\n DIVERGED_DIR_NAME: \".diverged\",\n LFS_HEADER: \"version https://git-lfs.github.com/spec/\",\n SUBMODULE_STATUS_ADDED: \"+\",\n SUBMODULE_STATUS_REMOVED: \"-\",\n GITDIR_PREFIX: \"gitdir:\",\n GIT_CHECK_IGNORE_NO_MATCH: \"exit code: 1\",\n REFS: {\n HEADS: \"refs/heads/\",\n REMOTES: \"refs/remotes/origin\",\n REMOTES_ORIGIN: \"refs/remotes/origin/*\",\n },\n FETCH_CONFIG: \"+refs/heads/*:refs/remotes/origin/*\",\n PROGRESS_BUCKET_PERCENT: 25,\n} as const;\n\nexport const GIT_OPERATIONS = {\n MERGE_HEAD: \"MERGE_HEAD\",\n CHERRY_PICK_HEAD: \"CHERRY_PICK_HEAD\",\n REVERT_HEAD: \"REVERT_HEAD\",\n BISECT_LOG: \"BISECT_LOG\",\n REBASE_MERGE: \"rebase-merge\",\n REBASE_APPLY: \"rebase-apply\",\n} as const;\n\nexport const DEFAULT_CONFIG = {\n CRON_SCHEDULE: \"0 * * * *\",\n RETRY: {\n MAX_ATTEMPTS: 3,\n MAX_LFS_RETRIES: 2,\n INITIAL_DELAY_MS: 1000,\n MAX_DELAY_MS: 30000,\n BACKOFF_MULTIPLIER: 2,\n JITTER_MS: 500,\n },\n PARALLELISM: {\n MAX_REPOSITORIES: 2,\n MAX_WORKTREE_CREATION: 1,\n MAX_WORKTREE_UPDATES: 3,\n MAX_WORKTREE_REMOVAL: 3,\n MAX_STATUS_CHECKS: 20,\n MAX_BRANCH_FETCHES: 3,\n MAX_SAFE_TOTAL_CONCURRENT_OPS: 100,\n },\n UPDATE_EXISTING_WORKTREES: true,\n HOOK_TIMEOUT_MS: 60_000,\n FETCH_TIMEOUT_MS: 300_000,\n CLONE_TIMEOUT_MS: 900_000,\n LOCK_STALE_MS: 600_000,\n LOCK_UPDATE_MS: 30_000,\n} as const;\n\nexport const ERROR_MESSAGES = {\n GIT_NOT_INITIALIZED: \"Git service not initialized. Call initialize() first.\",\n ALREADY_EXISTS: \"already exists\",\n ALREADY_REGISTERED: \"already registered worktree\",\n FAST_FORWARD_FAILED: [\n \"Not possible to fast-forward\",\n \"fatal: Not possible to fast-forward, aborting\",\n \"cannot fast-forward\",\n ],\n NO_UPSTREAM: [\n \"fatal: no upstream configured\",\n \"no upstream configured for branch\",\n \"fatal: ambiguous argument\",\n \"unknown revision or path\",\n ],\n LFS_ERROR: [\"smudge filter lfs failed\", \"git-lfs\", \"LFS\"],\n EXDEV: \"EXDEV\",\n} as const;\n\nexport const TEST_TIMEOUT = {\n DEFAULT: 10000,\n E2E: 60000,\n} as const;\n\nexport const ENV_CONSTANTS = {\n GIT_LFS_SKIP_SMUDGE: \"GIT_LFS_SKIP_SMUDGE\",\n GIT_ATTR_SOURCE: \"GIT_ATTR_SOURCE\",\n NODE_ENV_TEST: \"test\",\n} as const;\n\nexport const PATH_CONSTANTS = {\n GIT_DIR: \".git\",\n README: \"README\",\n CLONE_INIT_MARKER: \".sync-worktrees-clone-init\",\n} as const;\n\nexport const CONFIG_FILE_NAMES = [\n \"sync-worktrees.config.js\",\n \"sync-worktrees.config.mjs\",\n \"sync-worktrees.config.cjs\",\n] as const;\n\nexport const METADATA_CONSTANTS = {\n MAX_HISTORY_ENTRIES: 10,\n METADATA_FILENAME: \"sync-metadata.json\",\n WORKTREE_METADATA_PATH: \".git/worktrees\",\n DIVERGED_INFO_FILE: \".diverged-info.json\",\n DIVERGED_REASON: \"diverged-history-with-changes\",\n ACTION_CREATED: \"created\",\n ACTION_UPDATED: \"updated\",\n ACTION_FETCHED: \"fetched\",\n} as const;\n\nexport const TERMINAL_CONSTANTS = {\n ENV_OVERRIDE: \"SYNC_WORKTREES_TERMINAL\",\n ENV_FALLBACK: \"TERMINAL\",\n LINUX_CANDIDATES: [\"gnome-terminal\", \"konsole\", \"alacritty\", \"kitty\", \"xterm\"],\n} as const;\n\nexport const HOOK_CONSTANTS = {\n ENV_PREFIX: \"SYNC_WORKTREES_\",\n ENV_VARS: {\n BRANCH_NAME: \"SYNC_WORKTREES_BRANCH_NAME\",\n WORKTREE_PATH: \"SYNC_WORKTREES_WORKTREE_PATH\",\n REPO_NAME: \"SYNC_WORKTREES_REPO_NAME\",\n BASE_BRANCH: \"SYNC_WORKTREES_BASE_BRANCH\",\n REPO_URL: \"SYNC_WORKTREES_REPO_URL\",\n },\n PLACEHOLDERS: {\n BRANCH_NAME: \"{BRANCH_NAME}\",\n WORKTREE_PATH: \"{WORKTREE_PATH}\",\n REPO_NAME: \"{REPO_NAME}\",\n BASE_BRANCH: \"{BASE_BRANCH}\",\n REPO_URL: \"{REPO_URL}\",\n },\n} as const;\n", "import * as path from \"path\";\nimport { pathToFileURL } from \"url\";\n\nimport * as cron from \"node-cron\";\n\nimport { CONFIG_FILE_NAMES, DEFAULT_CONFIG } from \"../constants\";\nimport { ConfigFileNotFoundError, ConfigValidationError, SyncWorktreesError } from \"../errors\";\nimport { matchesPattern } from \"../utils/branch-filter\";\nimport { fileExists } from \"../utils/file-exists\";\nimport { getDefaultBareRepoDir } from \"../utils/git-url\";\nimport { normalizePathForCompare } from \"../utils/path-compare\";\nimport { REPOSITORY_MODES, isRepositoryMode } from \"../utils/repo-mode\";\nimport { sanitizeNameForPath } from \"../utils/sanitize-name\";\n\nimport type { Config, ConfigFile, RepositoryConfig, RepositoryMode } from \"../types\";\n\nconst CLONE_MODE_CONFLICTING_FIELDS = [\n \"branchInclude\",\n \"branchExclude\",\n \"branchMaxAge\",\n \"updateExistingWorktrees\",\n \"bareRepoDir\",\n] as const satisfies readonly (keyof RepositoryConfig)[];\n\nexport class ConfigLoaderService {\n async findConfigUpward(startDir: string): Promise<string | null> {\n let current = path.resolve(startDir);\n const root = path.parse(current).root;\n\n while (true) {\n for (const name of CONFIG_FILE_NAMES) {\n const candidate = path.join(current, name);\n if (await fileExists(candidate)) {\n return candidate;\n }\n }\n if (current === root) return null;\n const parent = path.dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n }\n\n async loadConfigFile(configPath: string): Promise<ConfigFile> {\n const absolutePath = path.resolve(configPath);\n\n if (!(await fileExists(absolutePath))) {\n throw new ConfigFileNotFoundError(absolutePath);\n }\n\n try {\n const fileUrl = pathToFileURL(absolutePath);\n fileUrl.searchParams.set(\"t\", Date.now().toString());\n const configModule = await import(fileUrl.href);\n const config = configModule.default;\n\n if (!config) {\n throw new Error(\"Config file must use 'export default' syntax\");\n }\n\n this.validateConfigFile(config);\n\n return config;\n } catch (error) {\n if (error instanceof SyncWorktreesError) {\n throw error;\n }\n throw new Error(`Failed to load config file: ${(error as Error).message}`);\n }\n }\n\n private validateConfigFile(config: unknown): asserts config is ConfigFile {\n if (!config || typeof config !== \"object\") {\n throw new Error(\"Config file must export an object\");\n }\n\n const configObj = config as Record<string, unknown>;\n\n if (!Array.isArray(configObj.repositories)) {\n throw new Error(\"Config file must have a 'repositories' array\");\n }\n\n if (configObj.repositories.length === 0) {\n throw new Error(\"Config file must have at least one repository\");\n }\n\n const seenNames = new Set<string>();\n\n configObj.repositories.forEach((repo: unknown, index: number) => {\n if (!repo || typeof repo !== \"object\") {\n throw new Error(`Repository at index ${index} must be an object`);\n }\n\n const repoObj = repo as Record<string, unknown>;\n\n if (!repoObj.name || typeof repoObj.name !== \"string\") {\n throw new Error(`Repository at index ${index} must have a 'name' property`);\n }\n\n if (seenNames.has(repoObj.name)) {\n throw new Error(`Duplicate repository name: ${repoObj.name}`);\n }\n seenNames.add(repoObj.name);\n\n if (!repoObj.repoUrl || typeof repoObj.repoUrl !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' must have a 'repoUrl' property`);\n }\n\n if (!this.isValidGitUrl(repoObj.repoUrl)) {\n throw new Error(\n `Repository '${repoObj.name}' has invalid 'repoUrl': '${repoObj.repoUrl}'. ` +\n `Expected an HTTP(S), SSH, Git protocol URL, or a local/file path (file://, absolute filesystem path)`,\n );\n }\n\n if (!repoObj.worktreeDir || typeof repoObj.worktreeDir !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' must have a 'worktreeDir' property`);\n }\n\n if (repoObj.bareRepoDir !== undefined && typeof repoObj.bareRepoDir !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'bareRepoDir' property`);\n }\n\n if (repoObj.cronSchedule !== undefined && typeof repoObj.cronSchedule !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'cronSchedule' property`);\n }\n\n if (typeof repoObj.cronSchedule === \"string\" && !cron.validate(repoObj.cronSchedule)) {\n throw new Error(`Repository '${repoObj.name}' has invalid cron expression: '${repoObj.cronSchedule}'`);\n }\n\n if (repoObj.runOnce !== undefined && typeof repoObj.runOnce !== \"boolean\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'runOnce' property`);\n }\n\n if (repoObj.debug !== undefined && typeof repoObj.debug !== \"boolean\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'debug' property`);\n }\n\n if (repoObj.retry !== undefined) {\n this.validateRetryConfig(repoObj.retry, `Repository '${repoObj.name}' retry config`);\n }\n\n if (repoObj.filesToCopyOnBranchCreate !== undefined) {\n this.validateFilesToCopyConfig(repoObj.filesToCopyOnBranchCreate, `Repository '${repoObj.name}'`);\n }\n\n if (repoObj.hooks !== undefined) {\n this.validateHooksConfig(repoObj.hooks, `Repository '${repoObj.name}'`);\n }\n\n if (repoObj.sparseCheckout !== undefined) {\n this.validateSparseCheckoutConfig(repoObj.sparseCheckout, `Repository '${repoObj.name}'`);\n }\n\n this.validateDepth(repoObj.depth, `Repository '${repoObj.name}' depth`);\n this.validateRepositoryMode(repoObj, configObj.defaults as Record<string, unknown> | undefined);\n });\n\n this.warnOnDuplicateRepoUrls(configObj.repositories as Array<Record<string, unknown>>);\n\n if (configObj.defaults) {\n if (typeof configObj.defaults !== \"object\") {\n throw new Error(\"'defaults' must be an object\");\n }\n\n const defaults = configObj.defaults as Record<string, unknown>;\n\n if (defaults.cronSchedule !== undefined && typeof defaults.cronSchedule !== \"string\") {\n throw new Error(\"Invalid 'cronSchedule' in defaults\");\n }\n if (typeof defaults.cronSchedule === \"string\" && !cron.validate(defaults.cronSchedule)) {\n throw new Error(`Invalid cron expression in defaults: '${defaults.cronSchedule}'`);\n }\n if (defaults.runOnce !== undefined && typeof defaults.runOnce !== \"boolean\") {\n throw new Error(\"Invalid 'runOnce' in defaults\");\n }\n if (defaults.debug !== undefined && typeof defaults.debug !== \"boolean\") {\n throw new Error(\"Invalid 'debug' in defaults\");\n }\n if (defaults.retry !== undefined && typeof defaults.retry !== \"object\") {\n throw new Error(\"Invalid 'retry' in defaults\");\n }\n if (defaults.retry !== undefined) {\n this.validateRetryConfig(defaults.retry, \"defaults retry config\");\n }\n if (defaults.filesToCopyOnBranchCreate !== undefined) {\n this.validateFilesToCopyConfig(defaults.filesToCopyOnBranchCreate, \"defaults\");\n }\n\n if (defaults.hooks !== undefined) {\n this.validateHooksConfig(defaults.hooks, \"defaults\");\n }\n\n if (defaults.sparseCheckout !== undefined) {\n this.validateSparseCheckoutConfig(defaults.sparseCheckout, \"defaults\");\n }\n\n this.validateDepth(defaults.depth, \"defaults.depth\");\n\n if (defaults.mode !== undefined && !isRepositoryMode(defaults.mode)) {\n throw new ConfigValidationError(\"defaults.mode\", \"must be 'clone' or 'worktree'\");\n }\n\n if (defaults.branch !== undefined && (typeof defaults.branch !== \"string\" || defaults.branch.trim() === \"\")) {\n throw new ConfigValidationError(\"defaults.branch\", \"must be a non-empty string\");\n }\n }\n\n if (configObj.retry !== undefined) {\n this.validateRetryConfig(configObj.retry, \"retry config\");\n }\n\n if (configObj.parallelism !== undefined) {\n this.validateParallelismConfig(configObj.parallelism, \"global\");\n }\n\n if (configObj.defaults && typeof configObj.defaults === \"object\") {\n const defaults = configObj.defaults as Record<string, unknown>;\n if (defaults.parallelism !== undefined) {\n this.validateParallelismConfig(defaults.parallelism, \"defaults\");\n }\n }\n }\n\n private validateDepth(value: unknown, field: string): void {\n if (value === undefined) return;\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value <= 0) {\n throw new ConfigValidationError(field, \"must be a positive safe integer\");\n }\n }\n\n private validateRetryConfig(value: unknown, context: string): void {\n if (typeof value !== \"object\" || value === null) {\n throw new Error(context === \"retry config\" ? \"'retry' must be an object\" : `Invalid 'retry' in ${context}`);\n }\n\n const retry = value as Record<string, unknown>;\n\n if (retry.maxAttempts !== undefined) {\n if (retry.maxAttempts !== \"unlimited\" && (typeof retry.maxAttempts !== \"number\" || retry.maxAttempts < 1)) {\n throw new Error(\"Invalid 'maxAttempts' in retry config. Must be 'unlimited' or a positive number\");\n }\n }\n\n if (retry.maxLfsRetries !== undefined) {\n if (typeof retry.maxLfsRetries !== \"number\" || retry.maxLfsRetries < 0) {\n throw new Error(\"Invalid 'maxLfsRetries' in retry config. Must be a non-negative number\");\n }\n }\n\n if (retry.initialDelayMs !== undefined && (typeof retry.initialDelayMs !== \"number\" || retry.initialDelayMs < 0)) {\n throw new Error(\"Invalid 'initialDelayMs' in retry config\");\n }\n\n if (retry.maxDelayMs !== undefined && (typeof retry.maxDelayMs !== \"number\" || retry.maxDelayMs < 0)) {\n throw new Error(\"Invalid 'maxDelayMs' in retry config\");\n }\n\n if (\n retry.backoffMultiplier !== undefined &&\n (typeof retry.backoffMultiplier !== \"number\" || retry.backoffMultiplier < 1)\n ) {\n throw new Error(\"Invalid 'backoffMultiplier' in retry config\");\n }\n\n if (retry.jitterMs !== undefined && (typeof retry.jitterMs !== \"number\" || retry.jitterMs < 0)) {\n throw new Error(\"Invalid 'jitterMs' in retry config\");\n }\n\n const initialDelay = (retry.initialDelayMs as number) ?? DEFAULT_CONFIG.RETRY.INITIAL_DELAY_MS;\n const maxDelay = (retry.maxDelayMs as number) ?? DEFAULT_CONFIG.RETRY.MAX_DELAY_MS;\n if (initialDelay > maxDelay) {\n throw new Error(\n `Invalid retry config: 'initialDelayMs' (${initialDelay}) must not exceed 'maxDelayMs' (${maxDelay})`,\n );\n }\n }\n\n private validateParallelismConfig(parallelism: unknown, context: string): void {\n if (typeof parallelism !== \"object\" || parallelism === null) {\n throw new Error(`'parallelism' in ${context} must be an object`);\n }\n\n const config = parallelism as Record<string, unknown>;\n\n const positiveIntFields = [\n \"maxRepositories\",\n \"maxWorktreeCreation\",\n \"maxWorktreeUpdates\",\n \"maxWorktreeRemoval\",\n \"maxStatusChecks\",\n \"maxBranchFetches\",\n ] as const;\n\n for (const field of positiveIntFields) {\n const value = config[field];\n if (value !== undefined && (typeof value !== \"number\" || value < 1)) {\n throw new Error(`Invalid '${field}' in ${context} parallelism config. Must be a positive number`);\n }\n }\n\n const maxRepos = (config.maxRepositories as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_REPOSITORIES;\n const maxCreation = (config.maxWorktreeCreation as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_CREATION;\n const maxUpdates = (config.maxWorktreeUpdates as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_UPDATES;\n const maxRemoval = (config.maxWorktreeRemoval as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_REMOVAL;\n const maxStatus = (config.maxStatusChecks as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n\n const maxPerRepoOps = maxCreation + maxUpdates + maxRemoval + maxStatus;\n const totalMaxConcurrent = maxRepos * maxPerRepoOps;\n\n if (totalMaxConcurrent > DEFAULT_CONFIG.PARALLELISM.MAX_SAFE_TOTAL_CONCURRENT_OPS) {\n const safeMaxRepos = Math.floor(DEFAULT_CONFIG.PARALLELISM.MAX_SAFE_TOTAL_CONCURRENT_OPS / maxPerRepoOps);\n throw new Error(\n `Total concurrent operations (${totalMaxConcurrent}) exceeds safe limit (${DEFAULT_CONFIG.PARALLELISM.MAX_SAFE_TOTAL_CONCURRENT_OPS}). ` +\n `With current per-repository limits (creation: ${maxCreation}, updates: ${maxUpdates}, removal: ${maxRemoval}, status: ${maxStatus}), ` +\n `maximum safe maxRepositories is ${safeMaxRepos}. ` +\n `Consider reducing maxRepositories or lowering per-operation limits.`,\n );\n }\n }\n\n private validateFilesToCopyConfig(filesToCopy: unknown, context: string): void {\n if (!Array.isArray(filesToCopy)) {\n throw new Error(`'filesToCopyOnBranchCreate' in ${context} must be an array`);\n }\n\n for (let i = 0; i < filesToCopy.length; i++) {\n const pattern = filesToCopy[i];\n if (typeof pattern !== \"string\" || pattern.trim() === \"\") {\n throw new Error(\n `'filesToCopyOnBranchCreate' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n }\n\n private validateSparseCheckoutConfig(value: unknown, context: string): void {\n if (typeof value !== \"object\" || value === null) {\n throw new Error(`'sparseCheckout' in ${context} must be an object`);\n }\n\n const cfg = value as Record<string, unknown>;\n\n if (!Array.isArray(cfg.include)) {\n throw new Error(`'sparseCheckout.include' in ${context} must be an array`);\n }\n if (cfg.include.length === 0) {\n throw new Error(`'sparseCheckout.include' in ${context} must contain at least one pattern`);\n }\n for (let i = 0; i < cfg.include.length; i++) {\n const p = cfg.include[i];\n if (typeof p !== \"string\" || p.trim() === \"\") {\n throw new Error(\n `'sparseCheckout.include' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n\n if (cfg.exclude !== undefined) {\n if (!Array.isArray(cfg.exclude)) {\n throw new Error(`'sparseCheckout.exclude' in ${context} must be an array`);\n }\n for (let i = 0; i < cfg.exclude.length; i++) {\n const p = cfg.exclude[i];\n if (typeof p !== \"string\" || p.trim() === \"\") {\n throw new Error(\n `'sparseCheckout.exclude' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n }\n\n if (cfg.mode !== undefined && cfg.mode !== \"cone\" && cfg.mode !== \"no-cone\") {\n throw new Error(`'sparseCheckout.mode' in ${context} must be 'cone' or 'no-cone'`);\n }\n }\n\n private warnOnDuplicateRepoUrls(repositories: Array<Record<string, unknown>>): void {\n const seen = new Map<string, string[]>();\n for (const repo of repositories) {\n const url = typeof repo.repoUrl === \"string\" ? repo.repoUrl : null;\n const name = typeof repo.name === \"string\" ? repo.name : null;\n if (!url || !name) continue;\n const list = seen.get(url) ?? [];\n list.push(name);\n seen.set(url, list);\n }\n for (const [url, names] of seen) {\n if (names.length > 1) {\n console.warn(\n `[sync-worktrees] repoUrl '${url}' appears in multiple entries (${names.join(\", \")}). ` +\n `Pin 'bareRepoDir' on duplicate entries to make config reorder-proof.`,\n );\n }\n }\n }\n\n private validateRepositoryMode(\n repoObj: Record<string, unknown>,\n defaults: Record<string, unknown> | undefined,\n ): void {\n const repoName = repoObj.name as string;\n const repoMode = repoObj.mode;\n\n if (repoMode !== undefined && !isRepositoryMode(repoMode)) {\n throw new ConfigValidationError(`Repository '${repoName}' mode`, \"must be 'clone' or 'worktree'\");\n }\n\n if (\n repoObj.branch !== undefined &&\n (typeof repoObj.branch !== \"string\" || (repoObj.branch as string).trim() === \"\")\n ) {\n throw new ConfigValidationError(`Repository '${repoName}' branch`, \"must be a non-empty string\");\n }\n\n const effectiveMode = (repoMode as RepositoryMode | undefined) ?? (defaults?.mode as RepositoryMode | undefined);\n if (effectiveMode !== REPOSITORY_MODES.CLONE) {\n const depthFromRepo = repoObj.depth;\n const depthFromDefaults = defaults?.depth;\n if (depthFromRepo !== undefined || depthFromDefaults !== undefined) {\n const source = depthFromRepo !== undefined ? \"repository\" : \"defaults\";\n throw new ConfigValidationError(\n `Repository '${repoName}' depth`,\n `only supported when mode is 'clone' (set on ${source})`,\n );\n }\n\n const branchFromRepo = repoObj.branch;\n const branchFromDefaults = defaults?.branch;\n if (branchFromRepo !== undefined || branchFromDefaults !== undefined) {\n const source = branchFromRepo !== undefined ? \"repository\" : \"defaults\";\n throw new ConfigValidationError(\n `Repository '${repoName}' branch`,\n `only supported when mode is 'clone' (set on ${source})`,\n );\n }\n\n return;\n }\n\n for (const field of CLONE_MODE_CONFLICTING_FIELDS) {\n const fromRepo = repoObj[field];\n const fromDefaults = defaults?.[field];\n const present = fromRepo !== undefined || fromDefaults !== undefined;\n if (present) {\n const source = fromRepo !== undefined ? \"repository\" : \"defaults\";\n throw new ConfigValidationError(\n `Repository '${repoName}' ${field}`,\n `not supported when mode is 'clone' (set on ${source})`,\n );\n }\n }\n }\n\n private validateHooksConfig(hooks: unknown, context: string): void {\n if (typeof hooks !== \"object\" || hooks === null) {\n throw new Error(`'hooks' in ${context} must be an object`);\n }\n\n const hooksObj = hooks as Record<string, unknown>;\n\n if (hooksObj.onBranchCreated !== undefined) {\n if (!Array.isArray(hooksObj.onBranchCreated)) {\n throw new Error(`'hooks.onBranchCreated' in ${context} must be an array`);\n }\n\n for (let i = 0; i < hooksObj.onBranchCreated.length; i++) {\n const command = hooksObj.onBranchCreated[i];\n if (typeof command !== \"string\" || command.trim() === \"\") {\n throw new Error(\n `'hooks.onBranchCreated' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n }\n }\n\n resolveRepositoryConfig(\n repo: RepositoryConfig,\n defaults?: Partial<Config>,\n configDir?: string,\n globalRetry?: Config[\"retry\"],\n allRepositories?: RepositoryConfig[],\n ): RepositoryConfig {\n const mode: RepositoryMode = repo.mode ?? defaults?.mode ?? REPOSITORY_MODES.WORKTREE;\n\n const resolved: RepositoryConfig = {\n name: repo.name,\n repoUrl: repo.repoUrl,\n worktreeDir: this.resolvePath(repo.worktreeDir, configDir),\n cronSchedule: repo.cronSchedule ?? defaults?.cronSchedule ?? DEFAULT_CONFIG.CRON_SCHEDULE,\n runOnce: repo.runOnce ?? defaults?.runOnce ?? false,\n debug: repo.debug ?? defaults?.debug,\n mode,\n };\n\n if (configDir) {\n resolved.__configFileDir = configDir;\n }\n\n if (mode === REPOSITORY_MODES.CLONE) {\n if (repo.branch ?? defaults?.branch) {\n resolved.branch = repo.branch ?? defaults?.branch;\n }\n if (repo.depth !== undefined || defaults?.depth !== undefined) {\n resolved.depth = repo.depth ?? defaults?.depth;\n }\n } else {\n if (repo.bareRepoDir) {\n resolved.bareRepoDir = this.resolvePath(repo.bareRepoDir, configDir);\n } else if (allRepositories && this.isDuplicateRepoUrl(repo, allRepositories, defaults)) {\n const sanitized = sanitizeNameForPath(repo.name, `Repository '${repo.name}' name`);\n resolved.bareRepoDir = this.resolvePath(`.bare/${sanitized}`, configDir);\n } else {\n resolved.bareRepoDir = this.resolvePath(getDefaultBareRepoDir(repo.repoUrl), configDir);\n }\n\n if (repo.branchMaxAge || defaults?.branchMaxAge) {\n resolved.branchMaxAge = repo.branchMaxAge ?? defaults?.branchMaxAge;\n }\n\n if (repo.branchInclude || defaults?.branchInclude) {\n resolved.branchInclude = repo.branchInclude ?? defaults?.branchInclude;\n }\n\n if (repo.branchExclude || defaults?.branchExclude) {\n resolved.branchExclude = repo.branchExclude ?? defaults?.branchExclude;\n }\n\n if (repo.updateExistingWorktrees !== undefined || defaults?.updateExistingWorktrees !== undefined) {\n resolved.updateExistingWorktrees = repo.updateExistingWorktrees ?? defaults?.updateExistingWorktrees ?? true;\n }\n }\n\n if (repo.skipLfs !== undefined || defaults?.skipLfs !== undefined) {\n resolved.skipLfs = repo.skipLfs ?? defaults?.skipLfs ?? false;\n }\n\n if (repo.retry || defaults?.retry || globalRetry) {\n resolved.retry = {\n ...(globalRetry || {}),\n ...(defaults?.retry || {}),\n ...(repo.retry || {}),\n };\n }\n\n if (repo.parallelism || defaults?.parallelism) {\n resolved.parallelism = {\n ...(defaults?.parallelism || {}),\n ...(repo.parallelism || {}),\n };\n }\n\n if (repo.filesToCopyOnBranchCreate || defaults?.filesToCopyOnBranchCreate) {\n const files = repo.filesToCopyOnBranchCreate ?? defaults?.filesToCopyOnBranchCreate;\n resolved.filesToCopyOnBranchCreate = files?.map((f) => this.resolvePath(f, configDir));\n }\n\n if (repo.hooks || defaults?.hooks) {\n resolved.hooks = {\n ...(defaults?.hooks || {}),\n ...(repo.hooks || {}),\n };\n }\n\n const sparse = repo.sparseCheckout ?? defaults?.sparseCheckout;\n if (sparse) {\n resolved.sparseCheckout = sparse;\n }\n\n return resolved;\n }\n\n private isDuplicateRepoUrl(repo: RepositoryConfig, all: RepositoryConfig[], defaults?: Partial<Config>): boolean {\n const firstIndex = all.findIndex((r) => {\n const mode = r.mode ?? defaults?.mode ?? REPOSITORY_MODES.WORKTREE;\n return r.repoUrl === repo.repoUrl && mode === REPOSITORY_MODES.WORKTREE;\n });\n const myIndex = all.indexOf(repo);\n return firstIndex !== -1 && myIndex !== -1 && myIndex !== firstIndex;\n }\n\n detectBareRepoDirCollisions(repositories: RepositoryConfig[]): void {\n const seen = new Map<string, { name: string; displayPath: string }>();\n for (const repo of repositories) {\n if (!repo.bareRepoDir) continue;\n const key = normalizePathForCompare(repo.bareRepoDir);\n const displayPath = path.resolve(repo.bareRepoDir);\n const existing = seen.get(key);\n if (existing && existing.name !== repo.name) {\n throw new Error(\n `Repositories '${existing.name}' and '${repo.name}' resolve to the same bareRepoDir '${displayPath}'. ` +\n `Set distinct 'bareRepoDir' values for duplicate repoUrl entries.`,\n );\n }\n seen.set(key, { name: repo.name, displayPath });\n }\n }\n\n private isValidGitUrl(url: string): boolean {\n // HTTP(S) URLs\n if (/^https?:\\/\\/.+/.test(url)) return true;\n // SSH URLs (git@host:path or ssh://...)\n if (/^(ssh:\\/\\/|git@).+/.test(url)) return true;\n // Git protocol\n if (/^git:\\/\\/.+/.test(url)) return true;\n // Local file paths (absolute)\n if (/^(file:\\/\\/|\\/|[A-Za-z]:\\\\)/.test(url)) return true;\n return false;\n }\n\n private resolvePath(inputPath: string, baseDir?: string): string {\n if (path.isAbsolute(inputPath)) {\n return inputPath;\n }\n\n return path.resolve(baseDir || process.cwd(), inputPath);\n }\n\n filterRepositories(repositories: RepositoryConfig[], filter?: string): RepositoryConfig[] {\n if (!filter) {\n return repositories;\n }\n\n const patterns = filter.split(\",\").map((p) => p.trim());\n\n return repositories.filter((repo) => {\n return patterns.some((pattern) => matchesPattern(repo.name, pattern));\n });\n }\n\n async buildRepositories(\n configPath: string,\n overrides?: { filter?: string },\n ): Promise<{ repositories: RepositoryConfig[]; configFile: ConfigFile; configDir: string }> {\n const configFile = await this.loadConfigFile(configPath);\n const configDir = path.dirname(path.resolve(configPath));\n\n let repositories = configFile.repositories.map((repo) =>\n this.resolveRepositoryConfig(repo, configFile.defaults, configDir, configFile.retry, configFile.repositories),\n );\n\n this.detectBareRepoDirCollisions(repositories);\n\n if (overrides?.filter) {\n repositories = this.filterRepositories(repositories, overrides.filter);\n }\n\n return { repositories, configFile, configDir };\n }\n}\n", "import { ERROR_MESSAGES } from \"../constants\";\n\nexport class SyncWorktreesError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly cause?: Error,\n ) {\n super(message);\n this.name = this.constructor.name;\n Object.setPrototypeOf(this, new.target.prototype);\n if (cause && cause.stack) {\n this.stack = `${this.stack}\\nCaused by: ${cause.stack}`;\n }\n }\n}\n\nexport class GitError extends SyncWorktreesError {\n constructor(message: string, code: string, cause?: Error) {\n super(message, `GIT_${code}`, cause);\n }\n}\n\nexport class GitNotInitializedError extends GitError {\n constructor() {\n super(ERROR_MESSAGES.GIT_NOT_INITIALIZED, \"NOT_INITIALIZED\");\n }\n}\n\nexport class GitOperationError extends GitError {\n constructor(operation: string, details: string, cause?: Error) {\n super(`Git operation '${operation}' failed: ${details}`, \"OPERATION_FAILED\", cause);\n }\n}\n\nexport class FastForwardError extends GitError {\n constructor(\n public readonly branchName: string,\n cause?: Error,\n ) {\n super(`Cannot fast-forward branch '${branchName}'`, \"FAST_FORWARD_FAILED\", cause);\n }\n}\n\nexport class WorktreeError extends SyncWorktreesError {\n constructor(message: string, code: string, cause?: Error) {\n super(message, `WORKTREE_${code}`, cause);\n }\n}\n\nexport class WorktreeAlreadyExistsError extends WorktreeError {\n constructor(\n public readonly path: string,\n public readonly branchName: string,\n ) {\n super(`Worktree already exists at '${path}' for branch '${branchName}'`, \"ALREADY_EXISTS\");\n }\n}\n\nexport class WorktreeNotCleanError extends WorktreeError {\n constructor(\n public readonly path: string,\n public readonly reasons: string[],\n ) {\n super(`Worktree at '${path}' is not clean: ${reasons.join(\", \")}`, \"NOT_CLEAN\");\n }\n}\n\nexport class ConfigError extends SyncWorktreesError {\n constructor(message: string, code: string, cause?: Error) {\n super(message, `CONFIG_${code}`, cause);\n }\n}\n\nexport class ConfigValidationError extends ConfigError {\n constructor(\n public readonly field: string,\n public readonly reason: string,\n ) {\n super(`Invalid configuration for '${field}': ${reason}`, \"VALIDATION_FAILED\");\n }\n}\n\nexport class ConfigFileNotFoundError extends ConfigError {\n constructor(public readonly configPath: string) {\n super(`Config file not found: ${configPath}`, \"FILE_NOT_FOUND\");\n }\n}\n\nexport class ConfigFileExistsError extends ConfigError {\n constructor(public readonly configPath: string) {\n super(`Config file already exists: ${configPath}`, \"FILE_EXISTS\");\n }\n}\n\nexport class PathResolutionError extends SyncWorktreesError {\n constructor(\n public readonly path: string,\n public readonly reason: string,\n ) {\n super(`Path resolution failed for '${path}': ${reason}`, \"PATH_RESOLUTION_FAILED\");\n }\n}\n\nexport class LfsError extends GitError {\n constructor(message: string, cause?: Error) {\n super(`LFS operation failed: ${message}`, \"LFS_ERROR\", cause);\n }\n}\n\nexport function isLfsError(error: Error | string): boolean {\n const message = typeof error === \"string\" ? error : error.message;\n return ERROR_MESSAGES.LFS_ERROR.some((pattern) => message.includes(pattern));\n}\n\nexport function isFastForwardError(error: Error | string): boolean {\n const message = typeof error === \"string\" ? error : error.message;\n return ERROR_MESSAGES.FAST_FORWARD_FAILED.some((pattern) => message.includes(pattern));\n}\n\nexport function isNoUpstreamError(error: Error | string): boolean {\n const message = typeof error === \"string\" ? error : error.message;\n return ERROR_MESSAGES.NO_UPSTREAM.some((pattern) => message.includes(pattern));\n}\n", "export function matchesPattern(name: string, pattern: string): boolean {\n if (pattern.includes(\"*\")) {\n const escapedPattern = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n const regex = new RegExp(\"^\" + escapedPattern + \"$\");\n return regex.test(name);\n }\n return name === pattern;\n}\n\nexport function filterBranchesByName(branches: string[], include?: string[], exclude?: string[]): string[] {\n let result = branches;\n\n if (include && include.length > 0) {\n result = result.filter((branch) => include.some((pattern) => matchesPattern(branch, pattern)));\n }\n\n if (exclude && exclude.length > 0) {\n result = result.filter((branch) => !exclude.some((pattern) => matchesPattern(branch, pattern)));\n }\n\n return result;\n}\n", "import * as fs from \"fs/promises\";\n\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await fs.access(path);\n return true;\n } catch {\n return false;\n }\n}\n", "/**\n * Extracts the repository name from a Git URL\n * @param gitUrl - The Git URL (HTTPS or SSH format)\n * @returns The repository name without .git extension\n * @throws Error if the URL format is invalid\n */\nexport function extractRepoNameFromUrl(gitUrl: string): string {\n // Remove trailing spaces\n const url = gitUrl.trim();\n\n // Handle SSH format: git@github.com:user/repo.git or ssh://git@domain/path/repo.git\n const sshMatch = url.match(/^git@[^:]+:(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (sshMatch) {\n return sshMatch[1];\n }\n\n // Handle SSH URL format: ssh://git@domain.com/path/repo.git\n const sshUrlMatch = url.match(/^ssh:\\/\\/[^/]+\\/(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (sshUrlMatch) {\n return sshUrlMatch[1];\n }\n\n // Handle HTTPS format: https://github.com/user/repo.git\n const httpsMatch = url.match(/^https?:\\/\\/[^/]+\\/(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (httpsMatch) {\n return httpsMatch[1];\n }\n\n // Handle file:// URLs for local repositories\n const fileMatch = url.match(/^file:\\/\\/(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (fileMatch) {\n return fileMatch[1];\n }\n\n throw new Error(`Invalid Git URL format: ${gitUrl}`);\n}\n\n/**\n * Generates the default bare repository directory path\n * @param repoUrl - The Git repository URL\n * @param baseDir - The base directory for bare repos (default: .bare)\n * @returns The path to the bare repository\n */\nexport function getDefaultBareRepoDir(repoUrl: string, baseDir: string = \".bare\"): string {\n const repoName = extractRepoNameFromUrl(repoUrl);\n return `${baseDir}/${repoName}`;\n}\n\n/**\n * Normalizes a Git remote URL for equivalence comparison only: trims, lowercases\n * a leading `scheme://host`, and strips a trailing slash and a single trailing\n * `.git`. Intentionally does NOT equate scp-style (git@host:path) with https://\n * forms \u2014 those are left distinct. Use only to decide whether two URLs point at\n * the same remote, never as a canonical URL for git operations.\n */\nexport function normalizeRepoUrlForComparison(url: string): string {\n let normalized = url.trim();\n // Only forge-style remotes (http(s)/ssh/git:// and scp git@host:path) treat a\n // trailing \".git\" as optional/equivalent. For file:// and bare local paths,\n // \"foo.git\" and \"foo\" can be genuinely different directories, so we must NOT\n // strip \".git\" there or we'd hide a real origin mismatch.\n const isForgeUrl = /^(https?|ssh|git):\\/\\//i.test(normalized) || /^[\\w.-]+@[^/]+:/.test(normalized);\n normalized = normalized.replace(/^[a-zA-Z][a-zA-Z0-9+.-]*:\\/\\/[^/]+/, (prefix) => prefix.toLowerCase());\n normalized = normalized.replace(/\\/+$/, \"\");\n if (isForgeUrl) {\n normalized = normalized.replace(/\\.git$/, \"\");\n }\n return normalized;\n}\n", "import * as path from \"path\";\n\n// darwin default filesystem (APFS default, HFS+) is case-insensitive.\n// Case-sensitive APFS volumes on macOS exist but are rare; those will see false-positive\n// matches for case-differing paths. Acceptable tradeoff vs breaking the common case.\nconst CASE_INSENSITIVE_PLATFORMS = new Set([\"darwin\"]);\n\nexport function isCaseInsensitiveFs(platform: NodeJS.Platform = process.platform): boolean {\n return CASE_INSENSITIVE_PLATFORMS.has(platform);\n}\n\n/**\n * Normalizes a path for equality comparison.\n *\n * The `platform` argument is a case-sensitivity hint only: it controls whether\n * the resolved path is lower-cased before comparison.\n */\nexport function normalizePathForCompare(p: string, platform: NodeJS.Platform = process.platform): string {\n const resolved = path.resolve(p);\n return isCaseInsensitiveFs(platform) ? resolved.toLowerCase() : resolved;\n}\n\n/**\n * Compares two paths for equality after host-path resolution and platform-aware case folding.\n *\n * The `platform` argument is a case-sensitivity hint only. See\n * {@link normalizePathForCompare} for the caveats about path.resolve semantics.\n */\nexport function pathsEqual(a: string, b: string, platform: NodeJS.Platform = process.platform): boolean {\n return normalizePathForCompare(a, platform) === normalizePathForCompare(b, platform);\n}\n", "import type { Config, RepositoryMode } from \"../types\";\n\nexport const REPOSITORY_MODES = {\n CLONE: \"clone\",\n WORKTREE: \"worktree\",\n} as const satisfies Record<string, RepositoryMode>;\n\nexport function isRepositoryMode(value: unknown): value is RepositoryMode {\n return value === REPOSITORY_MODES.CLONE || value === REPOSITORY_MODES.WORKTREE;\n}\n\nexport function resolveMode(cfg: Pick<Config, \"mode\">): RepositoryMode {\n return cfg.mode ?? REPOSITORY_MODES.WORKTREE;\n}\n", "import { ConfigValidationError } from \"../errors\";\n\nconst WINDOWS_RESERVED = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;\n// eslint-disable-next-line no-control-regex -- Windows reserves \\x00\u2013\\x1f for path validation; intentional\nconst ILLEGAL_CHARS = /[<>:\"|?*\\x00-\\x1f]/g;\n\nexport function sanitizeNameForPath(name: string, fieldContext = \"name\"): string {\n if (!name || typeof name !== \"string\") {\n throw new ConfigValidationError(fieldContext, \"must be a non-empty string\");\n }\n\n let cleaned = name.trim();\n cleaned = cleaned.replace(/[/\\\\]/g, \"-\");\n cleaned = cleaned.replace(/^\\.+/, \"\");\n cleaned = cleaned.replace(ILLEGAL_CHARS, \"_\");\n cleaned = cleaned.replace(/[. ]+$/, \"\");\n\n if (cleaned.length === 0) {\n throw new ConfigValidationError(fieldContext, `'${name}' produces an empty path segment after sanitization`);\n }\n\n if (WINDOWS_RESERVED.test(cleaned)) {\n throw new ConfigValidationError(fieldContext, `'${cleaned}' is a reserved name on Windows`);\n }\n\n return cleaned;\n}\n", "export type LogLevel = \"info\" | \"warn\" | \"error\" | \"debug\";\nexport type LogOutputFn = (message: string, level: LogLevel) => void;\n\nexport interface LoggerOptions {\n repoName?: string;\n debug?: boolean;\n disableColors?: boolean;\n outputFn?: LogOutputFn;\n}\n\nexport class Logger {\n private repoName?: string;\n private debugEnabled: boolean;\n private outputFn?: LogOutputFn;\n\n constructor(options: LoggerOptions = {}) {\n this.repoName = options.repoName;\n this.debugEnabled = options.debug ?? false;\n this.outputFn = options.outputFn;\n }\n\n private prefix(): string {\n return this.repoName ? `[${this.repoName}] ` : \"\";\n }\n\n debug(message: string, ...args: unknown[]): void {\n if (!this.debugEnabled) return;\n const formattedMessage = this.prefix() + this.formatMessage(message, args);\n if (this.outputFn) {\n this.outputFn(formattedMessage, \"debug\");\n } else {\n console.log(formattedMessage);\n }\n }\n\n info(message: string, ...args: unknown[]): void {\n const formattedMessage = this.prefix() + this.formatMessage(message, args);\n if (this.outputFn) {\n this.outputFn(formattedMessage, \"info\");\n } else {\n console.log(formattedMessage);\n }\n }\n\n warn(message: string, ...args: unknown[]): void {\n const formattedMessage = this.prefix() + this.formatMessage(message, args);\n if (this.outputFn) {\n this.outputFn(formattedMessage, \"warn\");\n } else {\n console.warn(formattedMessage);\n }\n }\n\n error(message: string, error?: Error | unknown): void {\n let formattedMessage = this.prefix() + message;\n if (error instanceof Error) {\n formattedMessage += ` ${error.message}`;\n } else if (error) {\n formattedMessage += ` ${String(error)}`;\n }\n if (this.outputFn) {\n this.outputFn(formattedMessage, \"error\");\n } else {\n if (error instanceof Error) {\n console.error(this.prefix() + message, error);\n } else if (error) {\n console.error(this.prefix() + message, error);\n } else {\n console.error(this.prefix() + message);\n }\n }\n }\n\n table(content: string): void {\n const formattedMessage = \"\\n\" + content + \"\\n\";\n if (this.outputFn) {\n this.outputFn(formattedMessage, \"info\");\n } else {\n console.log(formattedMessage);\n }\n }\n\n private formatMessage(message: string, args: unknown[]): string {\n if (args.length === 0) {\n return message;\n }\n\n return args.reduce((msg, arg) => (msg as string).replace(\"%s\", String(arg)), message) as string;\n }\n\n static createDefault(repoName?: string, debug?: boolean): Logger {\n return new Logger({ repoName, debug });\n }\n\n withPassthrough(passthrough: LogOutputFn): Logger {\n const upstream = this.outputFn;\n return new Logger({\n repoName: this.repoName,\n debug: this.debugEnabled,\n outputFn: (msg: string, level: LogLevel): void => {\n if (upstream) {\n upstream(msg, level);\n } else {\n defaultConsoleOutput(msg, level);\n }\n try {\n passthrough(msg, level);\n } catch {\n // swallow - passthrough must never break primary logging\n }\n },\n });\n }\n}\n\nfunction defaultConsoleOutput(msg: string, level: LogLevel): void {\n if (level === \"warn\") console.warn(msg);\n else if (level === \"error\") console.error(msg);\n else console.log(msg);\n}\n", "/**\n * Extracts error message from unknown error type\n * @param error The error to extract message from\n * @returns The error message string\n */\nexport function getErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (error && typeof error === \"object\" && \"message\" in error) {\n return String((error as { message: unknown }).message);\n }\n return String(error);\n}\n\n/**\n * Common LFS error patterns that indicate Git LFS-related failures\n */\nexport const LFS_ERROR_PATTERNS = Object.freeze([\n \"smudge filter lfs failed\",\n \"Object does not exist on the server\",\n \"external filter 'git-lfs filter-process' failed\",\n] as const);\n\n/**\n * Checks if an error message contains any known LFS error patterns\n * @param errorMessage The error message to check\n * @returns true if the error is related to Git LFS\n */\nexport function isLfsError(errorMessage: string): boolean {\n return LFS_ERROR_PATTERNS.some((pattern) => errorMessage.includes(pattern));\n}\n\n/**\n * Checks if an error object contains any known LFS error patterns\n * @param error The error object to check\n * @returns true if the error is related to Git LFS\n */\nexport function isLfsErrorFromError(error: unknown): boolean {\n return isLfsError(getErrorMessage(error));\n}\n\n/**\n * git stderr fragments that indicate the requested remote ref does not exist\n * (e.g. the tracked branch was deleted on the remote). Matched as substrings;\n * callers force LC_ALL=C so these stay deterministic English.\n */\nexport const MISSING_REMOTE_REF_PATTERNS = Object.freeze([\n \"couldn't find remote ref\",\n \"Couldn't find remote ref\",\n \"not our ref\",\n] as const);\n\n/**\n * Checks if an error message indicates a missing remote ref.\n * @param errorMessage The error message to check\n * @returns true if the message indicates the remote ref is gone\n */\nexport function isMissingRemoteRefError(errorMessage: string): boolean {\n return MISSING_REMOTE_REF_PATTERNS.some((pattern) => errorMessage.includes(pattern));\n}\n", "import { isLfsErrorFromError } from \"./lfs-error\";\n\ninterface ErrorWithCode {\n code?: string;\n message?: string;\n}\n\nexport interface LfsErrorContext {\n isLfsError: boolean;\n}\n\nexport interface RetryOptions {\n maxAttempts?: number | \"unlimited\";\n maxLfsRetries?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n backoffMultiplier?: number;\n /**\n * Add random jitter to retry delays to prevent thundering herd problem\n * in concurrent operations. Jitter is a random value between 0 and jitterMs\n * added to the calculated delay.\n *\n * Recommended for parallel operations to spread out retries.\n * Default: 0 (no jitter)\n */\n jitterMs?: number;\n shouldRetry?: (error: unknown, context?: LfsErrorContext) => boolean;\n onRetry?: (error: unknown, attempt: number, context?: LfsErrorContext) => void;\n lfsRetryHandler?: (context: LfsErrorContext) => void;\n}\n\nconst DEFAULT_OPTIONS: Required<Omit<RetryOptions, \"maxAttempts\">> & { maxAttempts: number | \"unlimited\" } = {\n maxAttempts: \"unlimited\",\n maxLfsRetries: 2,\n initialDelayMs: 1000,\n maxDelayMs: 600000, // 10 minutes\n backoffMultiplier: 2,\n jitterMs: 0,\n shouldRetry: (error, context) => {\n const err = error as ErrorWithCode;\n\n // Check for LFS errors\n if (isLfsErrorFromError(error)) {\n if (context) {\n context.isLfsError = true;\n }\n return true;\n }\n\n if (err.code === \"ENOTFOUND\" || err.code === \"ECONNREFUSED\" || err.code === \"ETIMEDOUT\") {\n return true;\n }\n\n if (err.code === \"EBUSY\" || err.code === \"ENOENT\" || err.code === \"EACCES\") {\n return true;\n }\n\n if (err.message?.includes(\"Could not read from remote repository\")) {\n return true;\n }\n\n if (err.message?.includes(\"fatal: unable to access\")) {\n return true;\n }\n\n return false;\n },\n onRetry: () => {},\n lfsRetryHandler: (_context) => {},\n};\n\nexport async function retry<T>(fn: () => Promise<T>, options: RetryOptions = {}): Promise<T> {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n let attempt = 1;\n let lfsAttempt = 0;\n const lfsContext: LfsErrorContext = { isLfsError: false };\n\n while (true) {\n try {\n return await fn();\n } catch (error) {\n // Reset LFS error flag for each attempt\n lfsContext.isLfsError = false;\n\n // Check if we should retry\n if (!opts.shouldRetry(error, lfsContext)) {\n throw error;\n }\n\n // Track LFS attempts separately\n if (lfsContext.isLfsError) {\n lfsAttempt++;\n\n // Check if we've exceeded LFS retry limit\n if (lfsAttempt > opts.maxLfsRetries) {\n const err = error as Error;\n throw new Error(\n `LFS error retry limit exceeded (${opts.maxLfsRetries} attempts). ` +\n `Consider using --skip-lfs option to bypass LFS downloads.`,\n { cause: err },\n );\n }\n }\n\n const isLastAttempt = opts.maxAttempts !== \"unlimited\" && attempt >= opts.maxAttempts;\n if (isLastAttempt) {\n throw error;\n }\n\n // Handle LFS errors specifically\n if (lfsContext.isLfsError && opts.lfsRetryHandler) {\n opts.lfsRetryHandler(lfsContext);\n }\n\n const baseDelay = Math.min(opts.initialDelayMs * Math.pow(opts.backoffMultiplier, attempt - 1), opts.maxDelayMs);\n\n // Add jitter to prevent thundering herd in concurrent operations\n // Jitter is a random value between 0 and jitterMs\n const jitter = opts.jitterMs > 0 ? Math.random() * opts.jitterMs : 0;\n const delay = baseDelay + jitter;\n\n opts.onRetry(error, attempt, lfsContext);\n\n await new Promise((resolve) => setTimeout(resolve, delay));\n attempt++;\n }\n }\n}\n", "import Table from \"cli-table3\";\n\nexport interface TimingResult {\n name: string;\n duration: number;\n count?: number;\n efficiency?: number;\n}\n\nexport class Timer {\n private startTime: number;\n private endTime?: number;\n\n constructor() {\n this.startTime = Date.now();\n }\n\n stop(): number {\n this.endTime = Date.now();\n return this.getDuration();\n }\n\n getDuration(): number {\n const end = this.endTime ?? Date.now();\n return end - this.startTime;\n }\n}\n\nexport class PhaseTimer {\n private phases: Map<string, { timer: Timer; count?: number; parallelism?: number }> = new Map();\n private currentPhase?: string;\n\n startPhase(name: string, parallelism?: number): void {\n if (this.currentPhase) {\n this.endPhase();\n }\n this.currentPhase = name;\n this.phases.set(name, { timer: new Timer(), parallelism });\n }\n\n endPhase(): void {\n if (this.currentPhase) {\n const phase = this.phases.get(this.currentPhase);\n if (phase) {\n phase.timer.stop();\n }\n this.currentPhase = undefined;\n }\n }\n\n setPhaseCount(name: string, count: number): void {\n const phase = this.phases.get(name);\n if (phase) {\n phase.count = count;\n }\n }\n\n getResults(): TimingResult[] {\n if (this.currentPhase) {\n this.endPhase();\n }\n\n const results: TimingResult[] = [];\n\n for (const [name, { timer, count, parallelism }] of this.phases.entries()) {\n const duration = timer.getDuration();\n const result: TimingResult = {\n name,\n duration,\n count,\n };\n\n if (count && count > 0 && parallelism && parallelism > 1) {\n const batches = Math.ceil(count / parallelism);\n const avgTimePerBatch = duration / batches;\n const theoreticalSequentialTime = count * avgTimePerBatch;\n result.efficiency =\n theoreticalSequentialTime > 0 ? Math.round((theoreticalSequentialTime / duration) * 100) : 100;\n }\n\n results.push(result);\n }\n\n return results;\n }\n}\n\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${minutes}m ${seconds}s`;\n}\n\nexport function formatTimingTable(totalDuration: number, phaseResults: TimingResult[], repoName?: string): string {\n const header = repoName ? `Performance Summary - [${repoName}]` : \"Performance Summary\";\n\n const table = new Table({\n head: [\"Operation\", \"Duration\", \"Efficiency\"],\n colWidths: [35, 12, 12],\n style: {\n head: [\"cyan\", \"bold\"],\n border: [\"gray\"],\n },\n });\n\n table.push([{ colSpan: 3, content: header, hAlign: \"center\" }]);\n\n table.push([\"Total Sync\", formatDuration(totalDuration), \"\"]);\n\n for (let i = 0; i < phaseResults.length; i++) {\n const result = phaseResults[i];\n const isLast = i === phaseResults.length - 1;\n const countStr = result.count ? ` (${result.count})` : \"\";\n const prefix = isLast ? \"\u2514\u2500\" : \"\u251C\u2500\";\n const name = ` ${prefix} ${result.name}${countStr}`;\n const efficiency = result.efficiency ? `${result.efficiency}%` : \"\";\n\n table.push([name, formatDuration(result.duration), efficiency]);\n }\n\n return table.toString();\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { DEFAULT_CONFIG, ENV_CONSTANTS, PATH_CONSTANTS } from \"../constants\";\nimport { ConfigError } from \"../errors\";\nimport { fileExists } from \"../utils/file-exists\";\nimport { makeGitProgressHandler } from \"../utils/git-progress\";\nimport { normalizeRepoUrlForComparison } from \"../utils/git-url\";\nimport { getErrorMessage, isLfsError, isMissingRemoteRefError } from \"../utils/lfs-error\";\n\nimport { BranchCreatedActionsService } from \"./branch-created-actions.service\";\nimport { cloneSkipToOutcomeAction } from \"./sync-outcome\";\n\nimport type { GitService } from \"./git.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { SyncOutcomeAccumulator } from \"./sync-outcome\";\nimport type { Config, RepositoryConfig } from \"../types\";\nimport type { GitProgressEmitter, GitProgressEvent } from \"../utils/git-progress\";\nimport type { SimpleGit, SimpleGitOptions } from \"simple-git\";\n\nconst ALL_REMOTE_BRANCHES_REFSPEC = \"+refs/heads/*:refs/remotes/origin/*\";\nconst SHALLOW_RELATION_DEEPEN_TARGETS = [50, 200, 1000] as const;\n\nexport type CloneSkipReason =\n | { kind: \"branch_mismatch\"; phase: \"init\" | \"sync\"; currentBranch: string; expectedBranch: string }\n | { kind: \"head_unreadable\"; phase: \"init\" | \"sync\"; error: string }\n | { kind: \"dirty_tree\" }\n | { kind: \"diverged\"; branch: string }\n | { kind: \"ahead_unpushed\"; branch: string }\n | { kind: \"missing_remote_ref\"; branch: string; source: \"fetch_error\" | \"post_fetch_verify\" }\n | { kind: \"indeterminate_shallow\"; branch: string; deepenedTo: number | null }\n | { kind: \"origin_mismatch\"; actual: string; expected: string };\n\nexport type CloneSkipListener = (reason: CloneSkipReason) => void;\n\nexport class CloneSyncService {\n private initialized = false;\n private resolvedBranch: string | null = null;\n private branchCreatedActions: BranchCreatedActionsService;\n private progressEmitter?: GitProgressEmitter;\n private onSkip?: CloneSkipListener;\n private outcomeAccumulator?: SyncOutcomeAccumulator;\n // One-shot suppression token. When init records a wrong-branch / unreadable-HEAD\n // skip for an existing clone, it sets this so the immediately following\n // runSyncAttempt (same sync operation) does not record the identical skip again.\n private pendingInitSkip: CloneSkipReason | null = null;\n\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger,\n options: {\n branchCreatedActions?: BranchCreatedActionsService;\n progressEmitter?: GitProgressEmitter;\n onSkip?: CloneSkipListener;\n } = {},\n ) {\n this.branchCreatedActions = options.branchCreatedActions ?? new BranchCreatedActionsService();\n this.progressEmitter = options.progressEmitter;\n this.onSkip = options.onSkip;\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n clearPendingInitSkip(): void {\n this.pendingInitSkip = null;\n }\n\n async getWorktrees(): Promise<Array<{ path: string; branch: string }>> {\n const worktreeDir = path.resolve(this.config.worktreeDir);\n if (!(await fileExists(path.join(worktreeDir, PATH_CONSTANTS.GIT_DIR)))) {\n return [];\n }\n\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n let branch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n\n if (!branch || branch === \"HEAD\") {\n const head = (await git.raw([\"rev-parse\", \"--short\", \"HEAD\"])).trim();\n branch = head ? `(detached ${head})` : \"(detached)\";\n }\n\n return [{ path: worktreeDir, branch }];\n }\n\n private get repoName(): string {\n return (this.config as RepositoryConfig).name ?? this.config.repoUrl;\n }\n\n private getCloneTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.cloneTimeoutMs ?? DEFAULT_CONFIG.CLONE_TIMEOUT_MS;\n }\n\n private getFetchTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.fetchTimeoutMs ?? DEFAULT_CONFIG.FETCH_TIMEOUT_MS;\n }\n\n private isLfsSkipEnabled(): boolean {\n return this.config.skipLfs === true;\n }\n\n private buildGitOptions(blockMs: number): Partial<SimpleGitOptions> {\n const options: Partial<SimpleGitOptions> = {\n progress: makeGitProgressHandler(this.logger, (event) => this.emitProgress(event)),\n };\n if (blockMs > 0) options.timeout = { block: blockMs };\n return options;\n }\n\n private emitProgress(event: GitProgressEvent): void {\n try {\n this.progressEmitter?.(event);\n } catch {\n // progress listeners must not break sync flow\n }\n }\n\n private async withOutcome<T>(outcome: SyncOutcomeAccumulator | undefined, operation: () => Promise<T>): Promise<T> {\n const previousOutcome = this.outcomeAccumulator;\n if (outcome) {\n this.outcomeAccumulator = outcome;\n }\n\n try {\n return await operation();\n } finally {\n if (outcome) {\n this.outcomeAccumulator = previousOutcome;\n }\n }\n }\n\n private recordSkip(\n reason: CloneSkipReason,\n logMessage: string,\n progressMessage?: string,\n logLevel: \"warn\" | \"info\" = \"warn\",\n ): void {\n if (logLevel === \"warn\") {\n this.logger.warn(logMessage);\n } else {\n this.logger.info(logMessage);\n }\n this.emitProgress({ phase: \"skip\", message: progressMessage ?? logMessage });\n try {\n this.onSkip?.(reason);\n } catch {\n // listeners must not break sync flow\n }\n this.outcomeAccumulator?.add(\n cloneSkipToOutcomeAction(reason, {\n branch: this.resolvedBranch ?? this.config.branch,\n path: this.config.worktreeDir,\n }),\n );\n }\n\n private clientFor(dir: string, blockMs: number): SimpleGit {\n return simpleGit(dir, this.buildGitOptions(blockMs)).env(this.buildGitEnv());\n }\n\n // Force a stable C locale so git's stderr is deterministic English. The\n // missing-remote-ref and LFS error classification matches on those strings\n // and would otherwise misfire under a non-English LANG/LC_ALL. simple-git's\n // .env() merges this object with process.env (PATH etc. preserved).\n private buildGitEnv(opts: { forceLfsSkip?: boolean } = {}): Record<string, string> {\n const env: Record<string, string> = { LC_ALL: \"C\", LANG: \"C\" };\n if (opts.forceLfsSkip || this.isLfsSkipEnabled()) {\n env[ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE] = \"1\";\n }\n return env;\n }\n\n private buildCloneArgs(branch: string): string[] {\n const args = [\"--branch\", branch, \"--progress\"];\n if (this.config.depth !== undefined) {\n args.push(\"--depth\", String(this.config.depth), \"--no-single-branch\");\n }\n return args;\n }\n\n private async buildFetchArgs(git: SimpleGit): Promise<string[]> {\n const args = [\"origin\", \"--prune\", \"--progress\"];\n if (this.config.depth !== undefined && (await this.isShallowRepository(git))) {\n args.push(\"--depth\", String(this.config.depth));\n }\n return args;\n }\n\n private async ensureAllRemoteBranchesRefspec(git: SimpleGit): Promise<void> {\n let fetchRefspecs: string[] = [];\n try {\n const output = await git.raw([\"config\", \"--get-all\", \"remote.origin.fetch\"]);\n fetchRefspecs = output\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean);\n } catch {\n fetchRefspecs = [];\n }\n\n if (fetchRefspecs.includes(ALL_REMOTE_BRANCHES_REFSPEC)) return;\n\n const customRefspecs = fetchRefspecs.filter((refspec) => !this.isOriginRemoteBranchTrackingRefspec(refspec));\n\n this.logger.info(`Configuring '${this.repoName}' to fetch all remote branches from origin.`);\n await git.raw([\"remote\", \"set-branches\", \"origin\", \"*\"]);\n for (const refspec of customRefspecs) {\n await git.raw([\"config\", \"--add\", \"remote.origin.fetch\", refspec]);\n }\n }\n\n private isOriginRemoteBranchTrackingRefspec(refspec: string): boolean {\n const withoutForce = refspec.startsWith(\"+\") ? refspec.slice(1) : refspec;\n if (withoutForce.startsWith(\"^\")) return false;\n\n const [source, destination] = withoutForce.split(\":\");\n return source.startsWith(\"refs/heads/\") && destination?.startsWith(\"refs/remotes/origin/\") === true;\n }\n\n private recordMissingRemoteRefSkip(branch: string): void {\n this.recordSkip(\n { kind: \"missing_remote_ref\", branch, source: \"fetch_error\" },\n `Tracked branch '${branch}' is missing on remote for '${this.repoName}'. Skipping sync.`,\n `Skipping '${this.repoName}': origin/${branch} is missing`,\n );\n }\n\n private async fetchWithRecovery(\n git: SimpleGit,\n fetchArgs: string[],\n worktreeDir: string,\n branch: string,\n ): Promise<{ skipped: boolean }> {\n try {\n await git.fetch(fetchArgs);\n return { skipped: false };\n } catch (fetchError) {\n const message = getErrorMessage(fetchError);\n if (isLfsError(message)) {\n this.logger.info(`\u26A0\uFE0F LFS error during fetch for '${this.repoName}'; retrying with LFS disabled.`);\n this.emitProgress({ phase: \"fetch\", message: `Retrying fetch for '${this.repoName}' with LFS disabled` });\n const lfsSkipGit = simpleGit(worktreeDir, this.buildGitOptions(this.getFetchTimeoutMs())).env(\n this.buildGitEnv({ forceLfsSkip: true }),\n );\n try {\n await lfsSkipGit.fetch(fetchArgs);\n return { skipped: false };\n } catch (retryError) {\n // The LFS-disabled retry can itself hit a deleted remote branch \u2014\n // classify it as a soft skip too, instead of letting it escape as a\n // hard failure.\n if (isMissingRemoteRefError(getErrorMessage(retryError))) {\n this.recordMissingRemoteRefSkip(branch);\n return { skipped: true };\n }\n // Otherwise propagate the retry error unchanged so the outer retry\n // policy's LFS handling still sees an accurate error.\n throw retryError;\n }\n }\n if (isMissingRemoteRefError(message)) {\n this.recordMissingRemoteRefSkip(branch);\n return { skipped: true };\n }\n throw fetchError;\n }\n }\n\n private async hasRemoteBranch(git: SimpleGit, branch: string): Promise<boolean> {\n try {\n // simple-git resolves `show-ref --quiet` even when git exits 1, so keep\n // stdout enabled (no --quiet) to get a real reject on a missing ref \u2014\n // otherwise the post-fetch missing_remote_ref skip would never fire.\n await git.raw([\"show-ref\", \"--verify\", `refs/remotes/origin/${branch}`]);\n return true;\n } catch {\n return false;\n }\n }\n\n private async isShallowRepository(git: SimpleGit): Promise<boolean> {\n try {\n const output = await git.raw([\"rev-parse\", \"--is-shallow-repository\"]);\n return output.trim() === \"true\";\n } catch {\n return false;\n }\n }\n\n private async unshallowIfDepthRemoved(git: SimpleGit): Promise<void> {\n if (this.config.depth !== undefined) return;\n\n if (!(await this.isShallowRepository(git))) return;\n\n this.logger.info(\n `[deepen] Existing shallow clone for '${this.repoName}' has no configured depth; fetching full history...`,\n );\n await git.fetch([\"--unshallow\"]);\n }\n\n private getDeepenTargets(): readonly number[] {\n const configuredDepth = this.config.depth;\n if (configuredDepth === undefined) return [];\n // `git fetch --depth N` can shorten a shallow repo if N is below current depth.\n // Skip targets at or below the configured depth \u2014 they would never widen history.\n return SHALLOW_RELATION_DEEPEN_TARGETS.filter((target) => target > configuredDepth);\n }\n\n private async deepenShallowHistoryToDepth(git: SimpleGit, branch: string, targetDepth: number): Promise<void> {\n this.logger.info(\n `[deepen] Shallow clone for '${this.repoName}' lacks enough history to classify origin/${branch}; ` +\n `refetching to depth ${targetDepth} before deciding.`,\n );\n this.emitProgress({\n phase: \"fetch\",\n message: `Deepening '${this.repoName}' to depth ${targetDepth} before classifying origin/${branch}`,\n });\n await git.fetch([\n \"origin\",\n \"--depth\",\n String(targetDepth),\n \"--prune\",\n \"--progress\",\n `+refs/heads/${branch}:refs/remotes/origin/${branch}`,\n ]);\n }\n\n async resolveBranch(): Promise<string> {\n if (this.resolvedBranch) return this.resolvedBranch;\n if (this.config.branch) {\n this.resolvedBranch = this.config.branch;\n this.emitProgress({ phase: \"branch\", message: `Using configured branch '${this.resolvedBranch}'` });\n return this.resolvedBranch;\n }\n this.logger.info(`No branch configured for '${this.repoName}', detecting remote default branch...`);\n this.emitProgress({ phase: \"branch\", message: `Resolving remote default branch for '${this.repoName}'` });\n this.resolvedBranch = await this.gitService.getRemoteDefaultBranch(this.config.repoUrl);\n this.logger.info(` \u21B3 resolved default branch: ${this.resolvedBranch}`);\n this.emitProgress({ phase: \"branch\", message: `Resolved default branch '${this.resolvedBranch}'` });\n return this.resolvedBranch;\n }\n\n async initialize(outcome?: SyncOutcomeAccumulator): Promise<void> {\n return this.withOutcome(outcome, () => this.initializeInternal());\n }\n\n private async initializeInternal(): Promise<void> {\n this.pendingInitSkip = null;\n const branch = await this.resolveBranch();\n const worktreeDir = this.config.worktreeDir;\n\n let entries: string[] | null = null;\n try {\n entries = await fs.readdir(worktreeDir);\n } catch {\n entries = null;\n }\n\n if (entries?.includes(PATH_CONSTANTS.GIT_DIR)) {\n this.emitProgress({ phase: \"clone\", message: `Validating existing clone for '${this.repoName}'` });\n const result = await this.validateExistingClone(branch);\n if (!result.valid) {\n this.recordSkip(result.skip, result.warnMessage, `Skipping '${this.repoName}': ${result.progressDetail}`);\n this.pendingInitSkip = result.skip;\n this.initialized = true;\n return;\n }\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n await this.ensureAllRemoteBranchesRefspec(git);\n this.initialized = true;\n this.emitProgress({ phase: \"clone\", message: `Existing clone validated for '${this.repoName}'` });\n return;\n }\n\n if (entries && entries.length > 0) {\n throw new ConfigError(\n `Cannot clone into '${worktreeDir}': directory exists and is not empty. ` +\n `Remove existing contents or point worktreeDir at an empty path.`,\n \"CLONE_DESTINATION_NOT_EMPTY\",\n );\n }\n\n const cloneCreatedDir = entries === null;\n await fs.mkdir(worktreeDir, { recursive: true });\n\n this.logger.info(`Cloning '${this.config.repoUrl}' (${branch}) into '${worktreeDir}'...`);\n this.emitProgress({ phase: \"clone\", message: `Cloning '${this.repoName}' (${branch})` });\n\n const cloneClient = simpleGit(this.buildGitOptions(this.getCloneTimeoutMs())).env(this.buildGitEnv());\n\n try {\n await cloneClient.clone(this.config.repoUrl, worktreeDir, this.buildCloneArgs(branch));\n } catch (error) {\n await this.maybeCleanupPartialClone(worktreeDir, cloneCreatedDir);\n this.outcomeAccumulator?.recordFailed(\"repo\", getErrorMessage(error), {\n reason: \"clone_failed\",\n branch,\n path: worktreeDir,\n });\n throw error;\n }\n\n const worktreeGit = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n await this.ensureAllRemoteBranchesRefspec(worktreeGit);\n\n this.logger.info(`\u2705 Clone successful.`);\n this.emitProgress({ phase: \"clone\", message: `Clone successful for '${this.repoName}'` });\n\n if (this.config.sparseCheckout) {\n this.logger.info(`Applying sparse-checkout patterns to '${worktreeDir}'...`);\n this.emitProgress({ phase: \"sparse_checkout\", message: `Applying sparse-checkout for '${this.repoName}'` });\n const sparseService = this.gitService.getSparseCheckoutService();\n await sparseService.applyToWorktree(worktreeDir, this.config.sparseCheckout);\n await worktreeGit.raw([\"checkout\", \"HEAD\"]);\n this.emitProgress({ phase: \"sparse_checkout\", message: `Sparse-checkout applied for '${this.repoName}'` });\n }\n\n this.emitProgress({ phase: \"lfs\", message: `Verifying LFS for '${this.repoName}'` });\n await this.gitService.verifyLfs(worktreeDir, branch);\n this.emitProgress({ phase: \"lfs\", message: `LFS verified for '${this.repoName}'` });\n\n await this.runInitialFileCopy(worktreeDir, branch);\n\n // Only record `created` once init is fully complete; otherwise an aborted\n // post-clone step would leave the outcome reporting both created and failed.\n this.outcomeAccumulator?.recordCreated(branch, worktreeDir);\n this.initialized = true;\n }\n\n // Detects an on-disk clone whose `origin` no longer matches the configured\n // repoUrl (e.g. repoUrl was repointed in config). Returns a skip descriptor so\n // we never fetch/ff-merge from the wrong remote; null when origin matches or\n // can't be read. Comparison is normalized so https/.git/trailing-slash\n // variants don't false-positive; the raw URLs are kept in the message.\n private async evaluateOriginMatch(\n git: SimpleGit,\n worktreeDir: string,\n ): Promise<{ skip: CloneSkipReason; warnMessage: string; progressDetail: string } | null> {\n let originUrl: string;\n try {\n originUrl = (await git.raw([\"remote\", \"get-url\", \"origin\"])).trim();\n } catch {\n this.logger.warn(`Could not read 'origin' remote URL from existing clone at '${worktreeDir}'.`);\n return null;\n }\n\n if (!originUrl || normalizeRepoUrlForComparison(originUrl) === normalizeRepoUrlForComparison(this.config.repoUrl)) {\n return null;\n }\n\n return {\n skip: { kind: \"origin_mismatch\", actual: originUrl, expected: this.config.repoUrl },\n warnMessage:\n `Existing clone at '${worktreeDir}' has origin '${originUrl}', expected '${this.config.repoUrl}'. ` +\n `Update the remote ('git remote set-url origin <url>') or point worktreeDir at a fresh path.`,\n progressDetail: `origin '${originUrl}' is not '${this.config.repoUrl}'`,\n };\n }\n\n private async validateExistingClone(\n expectedBranch: string,\n ): Promise<{ valid: true } | { valid: false; skip: CloneSkipReason; warnMessage: string; progressDetail: string }> {\n const worktreeDir = this.config.worktreeDir;\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n\n const originMismatch = await this.evaluateOriginMatch(git, worktreeDir);\n if (originMismatch) {\n return { valid: false, ...originMismatch };\n }\n\n let currentBranch: string;\n try {\n currentBranch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n return {\n valid: false,\n skip: { kind: \"head_unreadable\", phase: \"init\", error: errorMessage },\n warnMessage: `Existing clone at '${worktreeDir}' has a .git folder but reading HEAD failed: ${errorMessage}`,\n progressDetail: `could not read HEAD (${errorMessage})`,\n };\n }\n\n if (currentBranch !== expectedBranch) {\n return {\n valid: false,\n skip: {\n kind: \"branch_mismatch\",\n phase: \"init\",\n currentBranch,\n expectedBranch,\n },\n warnMessage:\n `Existing clone at '${worktreeDir}' is on branch '${currentBranch}', expected '${expectedBranch}'. ` +\n `Switch the working tree to '${expectedBranch}' or update the config.`,\n progressDetail: `current branch '${currentBranch}' is not '${expectedBranch}'`,\n };\n }\n\n return { valid: true };\n }\n\n private async maybeCleanupPartialClone(worktreeDir: string, cloneCreatedDir: boolean): Promise<void> {\n if (!cloneCreatedDir) {\n this.logger.warn(\n `Clone failed; leaving '${worktreeDir}' for manual inspection (directory existed before clone attempt).`,\n );\n return;\n }\n\n let entries: string[];\n try {\n entries = await fs.readdir(worktreeDir);\n } catch {\n return;\n }\n\n const looksIncomplete = entries.every((e) => e.startsWith(\".\"));\n const hasUsableGit =\n entries.includes(PATH_CONSTANTS.GIT_DIR) &&\n (await fileExists(path.join(worktreeDir, PATH_CONSTANTS.GIT_DIR, \"HEAD\")));\n\n if (looksIncomplete && !hasUsableGit) {\n try {\n await fs.rm(worktreeDir, { recursive: true, force: true });\n this.logger.info(`Cleaned up incomplete clone at '${worktreeDir}'.`);\n } catch (rmError) {\n this.logger.warn(`Failed to clean up incomplete clone at '${worktreeDir}': ${getErrorMessage(rmError)}`);\n }\n } else {\n this.logger.warn(\n `Clone failed; leaving '${worktreeDir}' for manual inspection (post-failure contents do not look like an empty incomplete clone).`,\n );\n }\n }\n\n private getInitMarkerPath(worktreeDir: string): string {\n return path.join(worktreeDir, PATH_CONSTANTS.GIT_DIR, PATH_CONSTANTS.CLONE_INIT_MARKER);\n }\n\n private async runInitialFileCopy(worktreeDir: string, branch: string): Promise<void> {\n const marker = this.getInitMarkerPath(worktreeDir);\n if (await fileExists(marker)) {\n return;\n }\n\n const sourceDir = this.config.__configFileDir ?? worktreeDir;\n\n await this.branchCreatedActions.copyFiles({\n config: this.config,\n branchName: branch,\n worktreePath: worktreeDir,\n sourceDir,\n logger: this.logger,\n });\n\n try {\n await fs.writeFile(marker, new Date().toISOString());\n } catch (error) {\n this.logger.warn(`Could not write clone-init marker: ${getErrorMessage(error)}`);\n }\n }\n\n async runSyncAttempt(outcome?: SyncOutcomeAccumulator): Promise<void> {\n return this.withOutcome(outcome, () => this.runSyncAttemptInternal());\n }\n\n private async runSyncAttemptInternal(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n // init ran here and recorded any skip itself; no duplicate to suppress.\n this.pendingInitSkip = null;\n return;\n }\n\n // If init already recorded a wrong-branch / unreadable-HEAD skip for the\n // current clone state during this same sync operation, don't record it a\n // second time. Consume the one-shot token; later ticks re-evaluate fresh.\n if (this.pendingInitSkip) {\n this.pendingInitSkip = null;\n return;\n }\n\n const branch = await this.resolveBranch();\n const worktreeDir = this.config.worktreeDir;\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n\n let currentBranch: string;\n try {\n currentBranch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n this.recordSkip(\n { kind: \"head_unreadable\", phase: \"sync\", error: errorMessage },\n `Could not read current branch from '${worktreeDir}': ${errorMessage}`,\n `Skipping '${this.repoName}': could not read current branch`,\n );\n return;\n }\n\n if (currentBranch !== branch) {\n this.recordSkip(\n { kind: \"branch_mismatch\", phase: \"sync\", currentBranch, expectedBranch: branch },\n `Clone at '${worktreeDir}' is on '${currentBranch}', expected '${branch}'. Skipping fetch+merge.`,\n `Skipping '${this.repoName}': current branch '${currentBranch}' is not '${branch}'`,\n );\n return;\n }\n\n // Re-check every tick (not just at init): the daemon reuses this service, so\n // a clone whose origin no longer matches repoUrl must keep being skipped\n // rather than fetching from the wrong remote.\n const originMismatch = await this.evaluateOriginMatch(git, worktreeDir);\n if (originMismatch) {\n this.recordSkip(\n originMismatch.skip,\n originMismatch.warnMessage,\n `Skipping '${this.repoName}': ${originMismatch.progressDetail}`,\n );\n return;\n }\n\n await this.unshallowIfDepthRemoved(git);\n\n await this.ensureAllRemoteBranchesRefspec(git);\n\n const fetchArgs = await this.buildFetchArgs(git);\n this.emitProgress({ phase: \"fetch\", message: `Fetching origin branches for '${this.repoName}'` });\n if ((await this.fetchWithRecovery(git, fetchArgs, worktreeDir, branch)).skipped) {\n return;\n }\n this.emitProgress({ phase: \"fetch\", message: `Fetched origin branches for '${this.repoName}'` });\n\n if (!(await this.hasRemoteBranch(git, branch))) {\n this.recordSkip(\n { kind: \"missing_remote_ref\", branch, source: \"post_fetch_verify\" },\n `Tracked branch '${branch}' is missing on remote for '${this.repoName}'. Skipping sync.`,\n `Skipping '${this.repoName}': origin/${branch} is missing`,\n );\n return;\n }\n\n if (this.config.sparseCheckout) {\n const sparseService = this.gitService.getSparseCheckoutService();\n try {\n if (await sparseService.needsUpdate(worktreeDir, this.config.sparseCheckout)) {\n this.emitProgress({ phase: \"sparse_checkout\", message: `Updating sparse-checkout for '${this.repoName}'` });\n await sparseService.applyToWorktree(worktreeDir, this.config.sparseCheckout);\n this.emitProgress({ phase: \"sparse_checkout\", message: `Sparse-checkout updated for '${this.repoName}'` });\n }\n } catch (error) {\n this.logger.warn(`Failed to reapply sparse-checkout for '${this.repoName}': ${getErrorMessage(error)}`);\n }\n }\n\n const isClean = await this.gitService.checkWorktreeStatus(worktreeDir);\n if (!isClean) {\n this.recordSkip(\n { kind: \"dirty_tree\" },\n `\u23ED\uFE0F Skipping ff-merge for '${this.repoName}' \u2014 working tree has local changes.`,\n `Skipping merge for '${this.repoName}': working tree has local changes`,\n \"info\",\n );\n return;\n }\n\n let relationship = await this.gitService.classifyRemoteRelationship(worktreeDir, branch);\n let lastDeepenedTo: number | null = null;\n if (relationship === \"indeterminate_shallow\") {\n for (const target of this.getDeepenTargets()) {\n await this.deepenShallowHistoryToDepth(git, branch, target);\n lastDeepenedTo = target;\n relationship = await this.gitService.classifyRemoteRelationship(worktreeDir, branch);\n if (relationship !== \"indeterminate_shallow\") break;\n }\n }\n\n if (relationship === \"up_to_date\") {\n this.logger.info(`'${this.repoName}' already up to date with origin/${branch}.`);\n this.emitProgress({\n phase: \"skip\",\n message: `'${this.repoName}' already up to date with origin/${branch}`,\n });\n this.outcomeAccumulator?.recordNoop(\"repo\", \"already_up_to_date\", {\n branch,\n path: worktreeDir,\n message: `Already up to date with origin/${branch}`,\n });\n return;\n }\n\n if (relationship !== \"fast_forward\") {\n if (relationship === \"local_ahead\") {\n this.recordSkip(\n { kind: \"ahead_unpushed\", branch },\n `\u23ED\uFE0F '${this.repoName}' has unpushed commits ahead of origin/${branch}. Skipping merge.`,\n `Skipping merge for '${this.repoName}': unpushed commits ahead of origin/${branch}`,\n \"info\",\n );\n } else if (relationship === \"indeterminate_shallow\") {\n const detail =\n lastDeepenedTo === null\n ? `no deepening attempted (configured depth already at or above all deepen targets)`\n : `deepening to ${lastDeepenedTo} commits`;\n const progressDetail =\n lastDeepenedTo === null\n ? `no deepening attempted (configured depth at/above limits)`\n : `shallow depth budget exhausted at ${lastDeepenedTo}`;\n this.recordSkip(\n { kind: \"indeterminate_shallow\", branch, deepenedTo: lastDeepenedTo },\n `\u23ED\uFE0F '${this.repoName}' could not classify origin/${branch} after ${detail}. ` +\n `Skipping merge \u2014 consider removing or raising 'depth' to unshallow.`,\n `Skipping merge for '${this.repoName}': ${progressDetail}`,\n \"info\",\n );\n } else {\n this.recordSkip(\n { kind: \"diverged\", branch },\n `\u23ED\uFE0F '${this.repoName}' has diverged from origin/${branch}. Skipping merge (no auto-reset).`,\n `Skipping merge for '${this.repoName}': diverged from origin/${branch}`,\n \"info\",\n );\n }\n return;\n }\n\n this.logger.info(`Fast-forwarding '${this.repoName}' to origin/${branch}...`);\n this.emitProgress({ phase: \"merge\", message: `Fast-forwarding '${this.repoName}' to origin/${branch}` });\n await git.merge([`origin/${branch}`, \"--ff-only\"]);\n this.logger.info(`\u2705 Updated '${this.repoName}' to origin/${branch}.`);\n this.emitProgress({ phase: \"merge\", message: `Updated '${this.repoName}' to origin/${branch}` });\n this.outcomeAccumulator?.recordUpdated(branch, worktreeDir, \"fast_forward\");\n }\n}\n", "import { GIT_CONSTANTS } from \"../constants\";\n\nimport type { Logger } from \"../services/logger.service\";\nimport type { SimpleGitProgressEvent } from \"simple-git\";\n\nexport interface GitProgressEvent {\n phase: string;\n message: string;\n progress?: number;\n processed?: number;\n total?: number;\n}\n\nexport type GitProgressEmitter = (event: GitProgressEvent) => void;\n\n/**\n * Build a progress callback for simple-git's `progress` option that:\n * - filters to clone/fetch/pull events only,\n * - emits at most one log per (method,stage) bucket of PROGRESS_BUCKET_PERCENT,\n * - always emits the 100% completion line,\n * - detects stage restarts (bucket regression on the same cached SimpleGit\n * instance, e.g. a second fetch) and resets the bucket so the new run\n * logs from scratch.\n *\n * State (the bucket map) is closure-local \u2014 pass one handler per SimpleGit\n * client. The contract is user-visible log output, so prefer this shared\n * factory over copies in each caller.\n */\nexport function makeGitProgressHandler(\n logger: Logger,\n emitProgress?: GitProgressEmitter,\n): (event: SimpleGitProgressEvent) => void {\n const lastBucket = new Map<string, number>();\n return (event: SimpleGitProgressEvent): void => {\n if (event.method !== \"fetch\" && event.method !== \"clone\" && event.method !== \"pull\") return;\n const key = `${event.method}:${event.stage}`;\n const bucket = Math.floor(event.progress / GIT_CONSTANTS.PROGRESS_BUCKET_PERCENT);\n let last = lastBucket.get(key) ?? -1;\n if (bucket < last) last = -1;\n if (bucket <= last && event.progress < 100) return;\n lastBucket.set(key, bucket);\n const total = event.total > 0 ? `${event.processed}/${event.total}` : `${event.processed}`;\n const message = `${event.method} ${event.stage}: ${event.progress}% (${total})`;\n logger.info(` \u21B3 ${message}`);\n emitProgress?.({\n phase: event.method,\n message,\n progress: event.progress,\n processed: event.processed,\n total: event.total,\n });\n };\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport { glob } from \"glob\";\n\nimport { fileExists } from \"../utils/file-exists\";\n\nconst DEFAULT_IGNORE_PATTERNS = [\n \"**/node_modules/**\",\n \"**/.git/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/.next/**\",\n \"**/coverage/**\",\n];\n\nexport interface FileCopyResult {\n copied: string[];\n skipped: string[];\n errors: Array<{ file: string; error: string }>;\n}\n\nexport class FileCopyService {\n /**\n * Copy files matching patterns from source to destination directory.\n * Skips files that already exist at destination.\n * Preserves directory structure relative to source.\n */\n async copyFiles(sourceDir: string, destDir: string, patterns: string[]): Promise<FileCopyResult> {\n const result: FileCopyResult = {\n copied: [],\n skipped: [],\n errors: [],\n };\n\n if (!patterns || patterns.length === 0) {\n return result;\n }\n\n const filesToCopy = await this.expandPatterns(sourceDir, patterns);\n\n for (const relativePath of filesToCopy) {\n const sourcePath = path.join(sourceDir, relativePath);\n const destPath = path.join(destDir, relativePath);\n\n try {\n const copied = await this.copyFile(sourcePath, destPath);\n if (copied) {\n result.copied.push(relativePath);\n } else {\n result.skipped.push(relativePath);\n }\n } catch (error) {\n result.errors.push({\n file: relativePath,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return result;\n }\n\n private async expandPatterns(sourceDir: string, patterns: string[]): Promise<string[]> {\n const allFiles = new Set<string>();\n\n for (const pattern of patterns) {\n try {\n const matches = await glob(pattern, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n ignore: DEFAULT_IGNORE_PATTERNS,\n });\n\n for (const match of matches) {\n allFiles.add(match);\n }\n } catch {\n // Pattern matching failed, skip silently\n }\n }\n\n return Array.from(allFiles);\n }\n\n private async copyFile(sourcePath: string, destPath: string): Promise<boolean> {\n if (await fileExists(destPath)) {\n return false;\n }\n\n const destDir = path.dirname(destPath);\n await fs.mkdir(destDir, { recursive: true });\n\n await fs.copyFile(sourcePath, destPath);\n return true;\n }\n}\n", "import { FileCopyService } from \"./file-copy.service\";\n\nimport type { HookExecutionService } from \"./hook-execution.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { Config, HookContext } from \"../types\";\n\nexport interface CopyFilesParams {\n config: Pick<Config, \"filesToCopyOnBranchCreate\">;\n branchName: string;\n worktreePath: string;\n sourceDir: string;\n logger: Logger;\n}\n\nexport interface RunHooksParams {\n config: Pick<Config, \"hooks\" | \"repoUrl\">;\n repoName: string;\n branchName: string;\n worktreePath: string;\n baseBranch: string;\n logger: Logger;\n hookExecutionService: HookExecutionService;\n}\n\nexport class BranchCreatedActionsService {\n private fileCopyService: FileCopyService;\n\n constructor(fileCopyService?: FileCopyService) {\n this.fileCopyService = fileCopyService ?? new FileCopyService();\n }\n\n async copyFiles(params: CopyFilesParams): Promise<void> {\n const { config, sourceDir, worktreePath, branchName, logger } = params;\n const patterns = config.filesToCopyOnBranchCreate;\n if (!patterns?.length) return;\n\n try {\n const result = await this.fileCopyService.copyFiles(sourceDir, worktreePath, patterns);\n\n if (result.copied.length > 0) {\n logger.info(`\uD83D\uDCCB Copied ${result.copied.length} file(s) to '${branchName}': ${result.copied.join(\", \")}`);\n }\n if (result.errors.length > 0) {\n logger.warn(`\u26A0\uFE0F Failed to copy ${result.errors.length} file(s) to '${branchName}':`);\n for (const err of result.errors) {\n logger.warn(` - ${err.file}: ${err.error}`);\n }\n }\n } catch (error) {\n logger.error(`Failed to copy files to '${branchName}': ${error}`);\n }\n }\n\n runHooks(params: RunHooksParams): void {\n const { config, branchName, worktreePath, repoName, baseBranch, logger, hookExecutionService } = params;\n if (!config.hooks?.onBranchCreated?.length) return;\n\n const context: HookContext = {\n branchName,\n worktreePath,\n repoName,\n baseBranch,\n repoUrl: config.repoUrl,\n };\n\n logger.info(`Running ${config.hooks.onBranchCreated.length} hook(s) for branch '${branchName}'...`);\n\n hookExecutionService.executeOnBranchCreated(config.hooks, context, {\n onStdout: (data) => logger.info(`[hook] ${data}`),\n onStderr: (data) => logger.warn(`[hook] ${data}`),\n onError: (command, error) => logger.error(`[hook] Failed to execute '${command}': ${error.message}`),\n onComplete: (command, exitCode) => {\n if (exitCode === 0) {\n logger.info(`[hook] Command completed successfully`);\n } else if (exitCode !== null) {\n logger.warn(`[hook] Command exited with code ${exitCode}`);\n }\n },\n });\n }\n}\n", "import type { CloneSkipReason } from \"../services/clone-sync.service\";\n\nexport function formatCloneSkipReason(reason: CloneSkipReason): string {\n switch (reason.kind) {\n case \"branch_mismatch\":\n return reason.phase === \"init\"\n ? `clone is on '${reason.currentBranch}', expected '${reason.expectedBranch}' (since process start)`\n : `clone is on '${reason.currentBranch}', expected '${reason.expectedBranch}'`;\n case \"head_unreadable\":\n return `could not read HEAD: ${reason.error}`;\n case \"dirty_tree\":\n return `working tree has local changes`;\n case \"diverged\":\n return `diverged from origin/${reason.branch}`;\n case \"ahead_unpushed\":\n return `unpushed commits ahead of origin/${reason.branch}`;\n case \"missing_remote_ref\":\n return reason.source === \"fetch_error\"\n ? `origin/${reason.branch} missing on remote (fetch error)`\n : `origin/${reason.branch} pruned after fetch`;\n case \"indeterminate_shallow\":\n return reason.deepenedTo === null\n ? `unable to classify origin/${reason.branch} (no deepening attempted \u2014 configured depth already at or above all deepen targets) \u2014 remove 'depth' to unshallow`\n : `unable to classify origin/${reason.branch} after deepening shallow history to ${reason.deepenedTo} commits \u2014 remove or raise 'depth' to unshallow`;\n case \"origin_mismatch\":\n return `clone origin is '${reason.actual}', expected '${reason.expected}'`;\n default: {\n const _exhaustive: never = reason;\n return _exhaustive;\n }\n }\n}\n", "import { formatCloneSkipReason } from \"../utils/clone-skip-format\";\n\nimport type { CloneSkipReason } from \"./clone-sync.service\";\nimport type { SyncOutcome, SyncOutcomeAction, SyncOutcomeCounts, SyncOutcomeMode, SyncOutcomeScope } from \"../types\";\n\nconst EMPTY_COUNTS: SyncOutcomeCounts = {\n created: 0,\n removed: 0,\n updated: 0,\n skipped: 0,\n preserved: 0,\n failed: 0,\n noop: 0,\n};\n\nfunction cloneCounts(counts: SyncOutcomeCounts): SyncOutcomeCounts {\n return { ...counts };\n}\n\nfunction cloneAction(action: SyncOutcomeAction): SyncOutcomeAction {\n return { ...action } as SyncOutcomeAction;\n}\n\nfunction countKeyFor(action: SyncOutcomeAction): keyof SyncOutcomeCounts {\n switch (action.kind) {\n case \"created\":\n return \"created\";\n case \"removed\":\n return \"removed\";\n case \"updated\":\n return \"updated\";\n case \"skipped\":\n return \"skipped\";\n case \"preserved-diverged\":\n return \"preserved\";\n case \"failed\":\n return \"failed\";\n case \"noop\":\n return \"noop\";\n default: {\n const _exhaustive: never = action;\n return _exhaustive;\n }\n }\n}\n\nexport class SyncOutcomeAccumulator {\n private counts: SyncOutcomeCounts = cloneCounts(EMPTY_COUNTS);\n private actions: SyncOutcomeAction[] = [];\n\n constructor(\n private readonly options: {\n mode: SyncOutcomeMode;\n repoName?: string;\n },\n ) {}\n\n add(action: SyncOutcomeAction): void {\n this.actions.push(action);\n this.counts[countKeyFor(action)]++;\n }\n\n recordCreated(branch: string, path: string): void {\n this.add({ kind: \"created\", branch, path });\n }\n\n recordRemoved(branch: string, path: string): void {\n this.add({ kind: \"removed\", branch, path });\n }\n\n recordUpdated(branch: string, path: string, reason?: string): void {\n this.add({ kind: \"updated\", branch, path, reason });\n }\n\n recordNoop(\n scope: SyncOutcomeScope,\n reason: string,\n details: { branch?: string; path?: string; message?: string },\n ): void {\n this.add({ kind: \"noop\", scope, reason, ...details });\n }\n\n recordSkipped(\n scope: SyncOutcomeScope,\n reason: string,\n details: { branch?: string; path?: string; message?: string },\n ): void {\n this.add({ kind: \"skipped\", scope, reason, ...details });\n }\n\n recordPreservedDiverged(branch: string, path: string, preservedPath: string): void {\n this.add({ kind: \"preserved-diverged\", branch, path, preservedPath });\n }\n\n recordFailed(\n scope: SyncOutcomeScope,\n error: string,\n details: { reason?: string; branch?: string; path?: string } = {},\n ): void {\n this.add({ kind: \"failed\", scope, error, ...details });\n }\n\n getCounts(): SyncOutcomeCounts {\n return cloneCounts(this.counts);\n }\n\n snapshot(): { counts: SyncOutcomeCounts; actions: SyncOutcomeAction[] } {\n return {\n counts: cloneCounts(this.counts),\n actions: this.actions.map(cloneAction),\n };\n }\n\n restore(snapshot: { counts: SyncOutcomeCounts; actions: SyncOutcomeAction[] }): void {\n this.counts = cloneCounts(snapshot.counts);\n this.actions = snapshot.actions.map(cloneAction);\n }\n\n toOutcome(durationMs?: number): SyncOutcome {\n return {\n repoName: this.options.repoName,\n mode: this.options.mode,\n started: true,\n counts: cloneCounts(this.counts),\n actions: this.actions.map(cloneAction),\n durationMs,\n };\n }\n}\n\nexport function createEmptySyncOutcome(mode: SyncOutcomeMode, repoName?: string, durationMs?: number): SyncOutcome {\n return {\n repoName,\n mode,\n started: true,\n counts: cloneCounts(EMPTY_COUNTS),\n actions: [],\n durationMs,\n };\n}\n\nexport function cloneSkipToOutcomeAction(\n reason: CloneSkipReason,\n details: { branch?: string; path?: string } = {},\n): SyncOutcomeAction {\n const message = formatCloneSkipReason(reason);\n const branch =\n \"branch\" in reason ? reason.branch : reason.kind === \"branch_mismatch\" ? reason.expectedBranch : details.branch;\n\n return {\n kind: \"skipped\",\n scope: \"repo\",\n reason: `clone_${reason.kind}`,\n branch,\n path: details.path,\n message,\n };\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { DEFAULT_CONFIG, ENV_CONSTANTS, GIT_CONSTANTS } from \"../constants\";\nimport { WorktreeError } from \"../errors\";\nimport { makeGitProgressHandler } from \"../utils/git-progress\";\nimport { getDefaultBareRepoDir } from \"../utils/git-url\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\nimport { parseWorktreeListPorcelain } from \"../utils/worktree-list-parser\";\n\nimport { Logger } from \"./logger.service\";\nimport { SparseCheckoutService } from \"./sparse-checkout.service\";\nimport { WorktreeMetadataService } from \"./worktree-metadata.service\";\nimport { WorktreeStatusService } from \"./worktree-status.service\";\n\nimport type { WorktreeStatusResult } from \"./worktree-status.service\";\nimport type { Config } from \"../types\";\nimport type { SyncMetadata } from \"../types/sync-metadata\";\nimport type { SimpleGit, SimpleGitOptions } from \"simple-git\";\n\nexport type RemoteRelationship = \"up_to_date\" | \"fast_forward\" | \"local_ahead\" | \"diverged\" | \"indeterminate_shallow\";\n\nexport type GitServiceOptions = Pick<\n Config,\n | \"repoUrl\"\n | \"worktreeDir\"\n | \"bareRepoDir\"\n | \"skipLfs\"\n | \"debug\"\n | \"sparseCheckout\"\n | \"fetchTimeoutMs\"\n | \"cloneTimeoutMs\"\n>;\n\n// simple-git blocks EDITOR / GIT_EDITOR / GIT_SEQUENCE_EDITOR unless allowUnsafeEditor is set;\n// strip them when forwarding process.env so a user's shell EDITOR doesn't break read-only commands.\nfunction sanitizeGitEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n const sanitized = { ...env };\n delete sanitized.EDITOR;\n delete sanitized.GIT_EDITOR;\n delete sanitized.GIT_SEQUENCE_EDITOR;\n return sanitized;\n}\n\nexport class GitService {\n private git: SimpleGit | null = null;\n private bareRepoPath: string;\n private mainWorktreePath: string;\n private defaultBranch: string = GIT_CONSTANTS.DEFAULT_BRANCH; // Will be updated after detection\n private metadataService: WorktreeMetadataService;\n private statusService: WorktreeStatusService;\n private sparseCheckoutService: SparseCheckoutService;\n private logger: Logger;\n private lfsSkipOverride = false;\n private gitInstances = new Map<string, SimpleGit>();\n\n constructor(\n private config: GitServiceOptions,\n logger?: Logger,\n ) {\n this.logger = logger ?? Logger.createDefault(undefined, config.debug);\n this.bareRepoPath = this.config.bareRepoDir || getDefaultBareRepoDir(this.config.repoUrl);\n this.mainWorktreePath = path.join(this.config.worktreeDir, GIT_CONSTANTS.DEFAULT_BRANCH); // Temporary, will be updated\n this.metadataService = new WorktreeMetadataService(this.logger);\n this.statusService = new WorktreeStatusService({ skipLfs: this.config.skipLfs }, this.logger);\n this.sparseCheckoutService = new SparseCheckoutService(this.logger);\n }\n\n getSparseCheckoutService(): SparseCheckoutService {\n return this.sparseCheckoutService;\n }\n\n private getFetchTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.fetchTimeoutMs ?? DEFAULT_CONFIG.FETCH_TIMEOUT_MS;\n }\n\n private getCloneTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.cloneTimeoutMs ?? DEFAULT_CONFIG.CLONE_TIMEOUT_MS;\n }\n\n private getCachedGit(dirPath: string, useLfsSkip = false): SimpleGit {\n const key = `${path.resolve(dirPath)}::${useLfsSkip ? \"1\" : \"0\"}`;\n let git = this.gitInstances.get(key);\n if (!git) {\n const base = simpleGit(dirPath, this.buildSimpleGitOptions(this.getFetchTimeoutMs()));\n git = useLfsSkip ? base.env({ [ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE]: \"1\" }) : base;\n this.gitInstances.set(key, git);\n }\n return git;\n }\n\n private buildSimpleGitOptions(blockMs: number): Partial<SimpleGitOptions> {\n const options: Partial<SimpleGitOptions> = { progress: makeGitProgressHandler(this.logger) };\n if (blockMs > 0) options.timeout = { block: blockMs };\n return options;\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n this.sparseCheckoutService.updateLogger(logger);\n }\n\n async initialize(): Promise<SimpleGit> {\n const { repoUrl } = this.config;\n\n try {\n // Check if bare repo already exists\n await fs.access(path.join(this.bareRepoPath, \"HEAD\"));\n } catch {\n // Clone as bare repository\n this.logger.info(`Cloning from \"${repoUrl}\" as bare repository into \"${this.bareRepoPath}\"...`);\n await fs.mkdir(path.dirname(this.bareRepoPath), { recursive: true });\n const cloneBase = simpleGit(this.buildSimpleGitOptions(this.getCloneTimeoutMs()));\n const cloneGit = this.isLfsSkipEnabled()\n ? cloneBase.env({ [ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE]: \"1\" })\n : cloneBase;\n await cloneGit.clone(repoUrl, this.bareRepoPath, [\"--bare\", \"--progress\"]);\n this.logger.info(\"\u2705 Clone successful.\");\n }\n\n // Configure bare repository for worktrees\n const bareGit = this.getCachedGit(this.bareRepoPath);\n\n // Check if fetch config already exists\n try {\n const existingConfig = await bareGit.raw([\"config\", \"--get-all\", \"remote.origin.fetch\"]);\n const targetConfig = \"+refs/heads/*:refs/remotes/origin/*\";\n\n if (!existingConfig.includes(targetConfig)) {\n await bareGit.addConfig(\"remote.origin.fetch\", targetConfig);\n }\n } catch {\n // Config doesn't exist, add it\n await bareGit.addConfig(\"remote.origin.fetch\", \"+refs/heads/*:refs/remotes/origin/*\");\n }\n\n // Always fetch to ensure remote refs are up-to-date\n // This is needed for branch creation UI even when repo already exists\n this.logger.info(\"Fetching remote branches...\");\n await bareGit.fetch([\"--all\", \"--progress\"]);\n\n // Detect the default branch (works from local refs even without fetch)\n this.defaultBranch = await this.detectDefaultBranch(bareGit);\n this.mainWorktreePath = path.join(this.config.worktreeDir, this.defaultBranch);\n\n // Check if main worktree exists\n let needsMainWorktree = true;\n try {\n const worktrees = await this.getWorktreesFromBare(bareGit);\n needsMainWorktree = !worktrees.some((w) => path.resolve(w.path) === path.resolve(this.mainWorktreePath));\n } catch {\n // If worktree list fails, assume we need main worktree\n }\n\n if (needsMainWorktree) {\n // Create main worktree if it doesn't exist\n this.logger.info(`Creating ${this.defaultBranch} worktree at \"${this.mainWorktreePath}\"...`);\n await fs.mkdir(this.config.worktreeDir, { recursive: true });\n // Use absolute path for worktree add to avoid relative path issues\n const absoluteWorktreePath = path.resolve(this.mainWorktreePath);\n\n // Check if local branch exists\n const branches = await bareGit.branch();\n const defaultBranchExists = branches.all.includes(this.defaultBranch);\n\n const useNoCheckoutMain = !!this.config.sparseCheckout;\n const noCheckoutFlagMain = useNoCheckoutMain ? [\"--no-checkout\"] : [];\n\n try {\n if (defaultBranchExists) {\n await bareGit.raw([\"worktree\", \"add\", ...noCheckoutFlagMain, absoluteWorktreePath, this.defaultBranch]);\n const worktreeGit = this.getCachedGit(absoluteWorktreePath, this.isLfsSkipEnabled());\n await worktreeGit.branch([\"--set-upstream-to\", `origin/${this.defaultBranch}`, this.defaultBranch]);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, this.defaultBranch, false);\n } else {\n await bareGit.raw([\n \"worktree\",\n \"add\",\n ...noCheckoutFlagMain,\n \"--track\",\n \"-b\",\n this.defaultBranch,\n absoluteWorktreePath,\n `origin/${this.defaultBranch}`,\n ]);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, this.defaultBranch, true);\n }\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes(\"already exists\")) {\n this.logger.info(\n `${this.defaultBranch} worktree directory already exists at '${absoluteWorktreePath}', skipping creation.`,\n );\n } else {\n throw error;\n }\n }\n\n // Ensure the worktree is registered by checking it exists in the list\n const updatedWorktrees = await this.getWorktreesFromBare(bareGit);\n const mainWorktreeRegistered = updatedWorktrees.some(\n (w) => path.resolve(w.path) === path.resolve(this.mainWorktreePath),\n );\n\n if (!mainWorktreeRegistered) {\n // Only warn in non-test environments as this is common in tests due to Git state\n if (process.env.NODE_ENV !== ENV_CONSTANTS.NODE_ENV_TEST) {\n this.logger.warn(`Main worktree was created but not found in worktree list. This may cause issues.`);\n }\n }\n }\n\n // Use the main worktree as our primary git instance\n this.git = this.getCachedGit(this.mainWorktreePath);\n return this.git;\n }\n\n getGit(): SimpleGit {\n if (!this.git) {\n throw new Error(\"Git service not initialized. Call initialize() first.\");\n }\n return this.git;\n }\n\n isInitialized(): boolean {\n return this.git !== null;\n }\n\n getDefaultBranch(): string {\n return this.defaultBranch;\n }\n\n getBareRepoPath(): string {\n return this.bareRepoPath;\n }\n\n async getRemoteDefaultBranch(repoUrl: string): Promise<string> {\n const git = simpleGit(this.buildSimpleGitOptions(this.getFetchTimeoutMs()));\n\n try {\n const out = await git.raw([\"ls-remote\", \"--symref\", repoUrl, \"HEAD\"]);\n const match = out.match(/^ref: refs\\/heads\\/(\\S+)\\s+HEAD/m);\n if (match && match[1]) {\n return match[1];\n }\n } catch {\n /* fall through to probe candidates */\n }\n\n // symref HEAD was unavailable/unparsed: probe common branch names, but only\n // auto-pick when the choice is unambiguous. Guessing by fixed priority when\n // several exist can silently track the wrong branch (e.g. 'main' when the\n // remote's real default is 'master').\n const existing: string[] = [];\n for (const candidate of GIT_CONSTANTS.COMMON_DEFAULT_BRANCHES) {\n try {\n const out = await git.raw([\"ls-remote\", \"--exit-code\", repoUrl, `refs/heads/${candidate}`]);\n if (out.trim().length > 0) {\n existing.push(candidate);\n }\n } catch {\n /* candidate missing \u2014 try next */\n }\n }\n\n if (existing.length === 1) {\n this.logger.warn(\n `Could not read symref HEAD for '${repoUrl}'; using the only common branch found ('${existing[0]}') as the default.`,\n );\n return existing[0];\n }\n\n if (existing.length > 1) {\n throw new Error(\n `Unable to detect default branch for '${repoUrl}': symref HEAD is unavailable and multiple common branches exist (${existing.join(\", \")}). ` +\n `Set 'branch' explicitly in the repository config.`,\n );\n }\n\n throw new Error(\n `Unable to detect default branch for '${repoUrl}'. ` +\n `Set 'branch' explicitly in the repository config or ensure the remote is reachable.`,\n );\n }\n\n async verifyLfs(worktreePath: string, label: string): Promise<void> {\n if (this.isLfsSkipEnabled()) return;\n await this.verifyLfsFilesDownloaded(worktreePath, label);\n }\n\n async fetchAll(): Promise<void> {\n this.assertInitialized();\n this.logger.info(\"Fetching latest data from remote...\");\n const git = this.getCachedGit(this.mainWorktreePath, this.isLfsSkipEnabled());\n await git.fetch([\"--all\", \"--prune\", \"--progress\"]);\n }\n\n async fetchBranch(branchName: string): Promise<void> {\n this.assertInitialized();\n const git = this.getCachedGit(this.mainWorktreePath, this.isLfsSkipEnabled());\n await git.fetch([\"origin\", branchName, \"--prune\", \"--progress\"]);\n }\n\n private assertInitialized(): void {\n if (!this.git) {\n throw new Error(\"Git service not initialized. Call initialize() first.\");\n }\n }\n\n async getRemoteBranches(): Promise<string[]> {\n const git = this.getGit();\n const branches = await git.branch([\"-r\"]);\n return branches.all\n .filter((b) => b.startsWith(\"origin/\") && !b.endsWith(\"/HEAD\"))\n .map((b) => b.replace(\"origin/\", \"\"))\n .filter((b) => b !== \"origin\" && b.length > 0);\n }\n\n async getRemoteBranchesWithActivity(): Promise<{ branch: string; lastActivity: Date }[]> {\n const git = this.getGit();\n // Use for-each-ref to get branch names with their last commit dates\n const result = await git.raw([\n \"for-each-ref\",\n \"--format=%(refname:short)|%(committerdate:iso8601)\",\n \"refs/remotes/origin\",\n ]);\n\n const branches: { branch: string; lastActivity: Date }[] = [];\n const lines = result\n .trim()\n .split(\"\\n\")\n .filter((line) => line);\n\n for (const line of lines) {\n const [ref, dateStr] = line.split(\"|\", 2);\n if (ref && dateStr && !ref.endsWith(\"/HEAD\")) {\n const branch = ref.replace(\"origin/\", \"\");\n // Skip invalid branch names\n if (branch === \"origin\" || branch.length === 0) {\n continue;\n }\n const lastActivity = new Date(dateStr);\n // Skip if the date is invalid\n if (!isNaN(lastActivity.getTime())) {\n branches.push({ branch, lastActivity });\n }\n }\n }\n\n return branches;\n }\n\n private async verifyLfsFilesDownloaded(worktreePath: string, branchName: string): Promise<void> {\n const worktreeGit = this.config.sparseCheckout\n ? simpleGit(worktreePath).env({ ...sanitizeGitEnv(process.env), [ENV_CONSTANTS.GIT_ATTR_SOURCE]: \"HEAD\" })\n : this.getCachedGit(worktreePath);\n\n try {\n const lfsFiles = await worktreeGit.raw([\"lfs\", \"ls-files\", \"--name-only\"]);\n let lfsFileList = lfsFiles\n .trim()\n .split(\"\\n\")\n .filter((f) => f.length > 0);\n\n if (lfsFileList.length === 0) {\n return;\n }\n\n // GIT_ATTR_SOURCE=HEAD lists every LFS file declared in HEAD's .gitattributes,\n // including ones outside the sparse-checkout cone that aren't on disk. Sampling\n // those would burn the 30s retry loop on guaranteed-missing files.\n if (this.config.sparseCheckout) {\n const existence = await Promise.all(\n lfsFileList.map(async (f) => {\n try {\n await fs.access(path.join(worktreePath, f));\n return f;\n } catch {\n return null;\n }\n }),\n );\n lfsFileList = existence.filter((f): f is string => f !== null);\n if (lfsFileList.length === 0) {\n return;\n }\n }\n\n if (this.config.debug) {\n this.logger.info(` - Verifying ${lfsFileList.length} LFS files are downloaded...`);\n }\n\n const sampleSize = Math.min(5, lfsFileList.length);\n const samplesToCheck = [];\n for (let i = 0; i < sampleSize; i++) {\n const randomIndex = Math.floor(Math.random() * lfsFileList.length);\n samplesToCheck.push(lfsFileList[randomIndex]);\n }\n\n let retries = 0;\n const maxRetries = 30;\n const retryDelay = 1000;\n\n while (retries < maxRetries) {\n let allDownloaded = true;\n const notDownloaded: string[] = [];\n\n for (const file of samplesToCheck) {\n const filePath = path.join(worktreePath, file);\n try {\n const handle = await fs.open(filePath, \"r\");\n try {\n const buffer = Buffer.alloc(200);\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);\n const header = buffer.subarray(0, bytesRead).toString(\"utf8\");\n if (header.startsWith(GIT_CONSTANTS.LFS_HEADER)) {\n allDownloaded = false;\n notDownloaded.push(file);\n }\n } finally {\n await handle.close();\n }\n } catch {\n allDownloaded = false;\n notDownloaded.push(file);\n }\n }\n\n if (allDownloaded) {\n if (this.config.debug) {\n this.logger.info(` - \u2705 LFS files verified (${samplesToCheck.length} samples checked)`);\n }\n return;\n }\n\n retries++;\n if (retries < maxRetries) {\n await new Promise((resolve) => setTimeout(resolve, retryDelay));\n }\n }\n\n this.logger.warn(\n ` - \u26A0\uFE0F Warning: Some LFS files may not be fully downloaded after ${maxRetries} seconds. ` +\n `This might cause issues if tools access the worktree immediately.`,\n );\n } catch (error) {\n this.logger.warn(` - \u26A0\uFE0F Warning: Could not verify LFS files for '${branchName}': ${error}`);\n }\n }\n\n async checkoutHead(worktreePath: string): Promise<void> {\n const git = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n await git.raw([\"checkout\", \"HEAD\"]);\n }\n\n private async applySparseAndCheckout(absoluteWorktreePath: string): Promise<void> {\n if (!this.config.sparseCheckout) return;\n await this.sparseCheckoutService.applyToWorktree(absoluteWorktreePath, this.config.sparseCheckout);\n const worktreeGit = this.getCachedGit(absoluteWorktreePath, this.isLfsSkipEnabled());\n await worktreeGit.raw([\"checkout\", \"HEAD\"]);\n }\n\n private async rollbackPartialWorktree(\n bareGit: SimpleGit,\n absoluteWorktreePath: string,\n branchName: string,\n createdNewBranch: boolean,\n failureContext?: string,\n ): Promise<{ worktreeRemoved: boolean }> {\n let worktreeRemoved = true;\n try {\n await bareGit.raw([\"worktree\", \"remove\", \"--force\", absoluteWorktreePath]);\n } catch (rollbackError) {\n worktreeRemoved = false;\n const ctx = failureContext ? ` after ${failureContext}` : \"\";\n this.logger.warn(\n ` - Rollback failed for '${branchName}' at '${absoluteWorktreePath}'${ctx}: ${getErrorMessage(rollbackError)}`,\n );\n }\n if (createdNewBranch) {\n try {\n await bareGit.raw([\"branch\", \"-D\", branchName]);\n } catch (branchRollbackError) {\n this.logger.warn(\n ` - Rollback (branch delete) failed for '${branchName}': ${getErrorMessage(branchRollbackError)}`,\n );\n }\n }\n return { worktreeRemoved };\n }\n\n private async createWorktreeMetadata(bareGit: SimpleGit, worktreePath: string, branchName: string): Promise<void> {\n try {\n const worktreeGit = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n const parentCommit = await bareGit.revparse([this.defaultBranch]);\n\n await this.metadataService.createInitialMetadataFromPath(\n this.bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n `origin/${branchName}`,\n this.defaultBranch,\n parentCommit.trim(),\n );\n } catch (metadataError) {\n this.logger.error(` - \u274C Failed to create metadata for '${branchName}': ${metadataError}`);\n throw new Error(`Metadata creation failed for ${branchName}. This worktree cannot be auto-managed.`);\n }\n }\n\n async addWorktree(branchName: string, worktreePath: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath, this.isLfsSkipEnabled());\n // Use absolute path for worktree add to avoid relative path issues\n const absoluteWorktreePath = path.resolve(worktreePath);\n // Ensure parent directory exists for nested branch paths\n await fs.mkdir(path.dirname(absoluteWorktreePath), { recursive: true });\n\n // Check if directory already exists (could be from a failed previous attempt)\n try {\n await fs.access(absoluteWorktreePath);\n // Directory exists - check if it's already a valid worktree\n const worktrees = await this.getWorktreesFromBare(bareGit);\n const isValidWorktree = worktrees.some((w) => path.resolve(w.path) === absoluteWorktreePath);\n\n if (isValidWorktree) {\n this.logger.info(` - Worktree for '${branchName}' already exists at '${absoluteWorktreePath}'`);\n return;\n } else {\n // Directory exists but is not a valid worktree - clean it up\n this.logger.info(` - Cleaning up orphaned directory at '${absoluteWorktreePath}'`);\n await fs.rm(absoluteWorktreePath, { recursive: true, force: true });\n }\n } catch {\n // Directory doesn't exist, which is expected - continue with creation\n }\n\n let createdNewBranch = false;\n try {\n const { local: localBranchExists, remote: remoteBranchExists } = await this.branchExists(branchName);\n\n createdNewBranch = await this.runWorktreeAddByMatrix(\n bareGit,\n branchName,\n absoluteWorktreePath,\n localBranchExists,\n remoteBranchExists,\n );\n\n if (localBranchExists && !remoteBranchExists) {\n this.logger.info(` - Created worktree for '${branchName}' (no remote yet \u2014 push to set upstream)`);\n } else {\n this.logger.info(` - Created worktree for '${branchName}' with tracking to origin/${branchName}`);\n }\n\n if (!this.isLfsSkipEnabled()) {\n await this.verifyLfsFilesDownloaded(absoluteWorktreePath, branchName);\n }\n\n try {\n await this.createWorktreeMetadata(bareGit, absoluteWorktreePath, branchName);\n } catch (metadataError) {\n this.logger.warn(` - Metadata creation failed for '${branchName}', removing worktree to prevent orphan`);\n await this.rollbackPartialWorktree(bareGit, absoluteWorktreePath, branchName, createdNewBranch);\n throw new Error(`Metadata creation failed for '${branchName}': ${getErrorMessage(metadataError)}`);\n }\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n // Upstream setup failures are already rolled back inside runWorktreeAddByMatrix.\n // Don't enter the tracking-error fallback (which would silently accept a partial worktree).\n if ((error as { isUpstreamSetupFailure?: boolean })?.isUpstreamSetupFailure) {\n throw error;\n }\n\n // Re-throw metadata creation errors - these are fatal and should not fall back\n if (errorMessage.includes(\"Metadata creation failed\")) {\n throw error;\n }\n\n // Check if this is an \"already registered\" error\n if (errorMessage.includes(\"already registered worktree\")) {\n // Check if worktree was actually created by a concurrent operation\n const worktrees = await this.getWorktreesFromBare(bareGit);\n const existingWorktree = worktrees.find((w) => path.resolve(w.path) === absoluteWorktreePath);\n\n if (existingWorktree && !existingWorktree.isPrunable) {\n this.logger.info(` - Worktree for '${branchName}' was created by concurrent operation`);\n return;\n }\n\n this.logger.warn(` - Worktree already registered but missing. Pruning and retrying...`);\n await bareGit.raw([\"worktree\", \"prune\"]);\n // Clean up directory if it exists\n try {\n await fs.rm(absoluteWorktreePath, { recursive: true, force: true });\n } catch {\n // Directory might not exist, ignore\n }\n let retryCreatedNewBranch = false;\n try {\n const { local: localBranchExists, remote: remoteBranchExists } = await this.branchExists(branchName);\n retryCreatedNewBranch = await this.runWorktreeAddByMatrix(\n bareGit,\n branchName,\n absoluteWorktreePath,\n localBranchExists,\n remoteBranchExists,\n );\n this.logger.info(` - Created worktree for '${branchName}' after pruning`);\n\n if (!this.isLfsSkipEnabled()) {\n await this.verifyLfsFilesDownloaded(absoluteWorktreePath, branchName);\n }\n\n try {\n await this.createWorktreeMetadata(bareGit, absoluteWorktreePath, branchName);\n } catch (metadataError) {\n this.logger.warn(` - Metadata creation failed for '${branchName}', removing worktree to prevent orphan`);\n await this.rollbackPartialWorktree(bareGit, absoluteWorktreePath, branchName, retryCreatedNewBranch);\n throw new Error(`Metadata creation failed for '${branchName}': ${getErrorMessage(metadataError)}`);\n }\n return;\n } catch (retryError) {\n this.logger.error(` - Failed to create worktree after pruning: ${retryError}`);\n throw retryError;\n }\n }\n\n // Only fall back to non-tracking version for tracking-related errors.\n // Re-throw real errors (disk full, permissions, etc.) immediately.\n const isTrackingError =\n errorMessage.includes(\"not a valid object name\") ||\n errorMessage.includes(\"not a commit\") ||\n errorMessage.includes(\"cannot set up tracking\") ||\n errorMessage.includes(\"does not track\") ||\n errorMessage.includes(\"remote tracking branch\") ||\n errorMessage.includes(\"no such remote ref\");\n\n if (!isTrackingError) {\n throw error;\n }\n\n this.logger.warn(` - Failed to create worktree with tracking, falling back to simple add: ${error}`);\n\n // Check again if directory exists before fallback attempt\n try {\n await fs.access(absoluteWorktreePath);\n // Directory exists - check if it's already a valid worktree\n const worktrees = await this.getWorktreesFromBare(bareGit);\n const isValidWorktree = worktrees.some((w) => path.resolve(w.path) === absoluteWorktreePath);\n\n if (isValidWorktree) {\n this.logger.info(` - Worktree for '${branchName}' already exists at '${absoluteWorktreePath}'`);\n return;\n } else {\n // Directory exists but is not a valid worktree - clean it up\n this.logger.info(` - Cleaning up orphaned directory at '${absoluteWorktreePath}' before fallback attempt`);\n await fs.rm(absoluteWorktreePath, { recursive: true, force: true });\n }\n } catch {\n // Directory doesn't exist, which is expected - continue with fallback\n }\n\n try {\n const useNoCheckout = !!this.config.sparseCheckout;\n const fallbackArgs = useNoCheckout\n ? [\"worktree\", \"add\", \"--no-checkout\", absoluteWorktreePath, branchName]\n : [\"worktree\", \"add\", absoluteWorktreePath, branchName];\n await bareGit.raw(fallbackArgs);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, branchName, false);\n this.logger.info(` - Created worktree for '${branchName}' (without tracking)`);\n\n if (!this.isLfsSkipEnabled()) {\n await this.verifyLfsFilesDownloaded(absoluteWorktreePath, branchName);\n }\n\n try {\n await this.createWorktreeMetadata(bareGit, absoluteWorktreePath, branchName);\n } catch (metadataError) {\n this.logger.warn(` - Metadata creation failed for '${branchName}', removing worktree to prevent orphan`);\n await this.rollbackPartialWorktree(bareGit, absoluteWorktreePath, branchName, false);\n throw new Error(`Metadata creation failed for '${branchName}': ${getErrorMessage(metadataError)}`);\n }\n } catch (fallbackError) {\n const fallbackErrorMessage = getErrorMessage(fallbackError);\n\n // If fallback also fails with \"already registered\", check if created by concurrent op\n if (fallbackErrorMessage.includes(\"already registered worktree\")) {\n const worktrees = await this.getWorktreesFromBare(bareGit);\n const existingWorktree = worktrees.find((w) => path.resolve(w.path) === absoluteWorktreePath);\n\n if (existingWorktree && !existingWorktree.isPrunable) {\n this.logger.info(` - Worktree for '${branchName}' was created by concurrent operation during fallback`);\n return;\n }\n }\n\n // If still failing, this is a real error\n throw fallbackError;\n }\n }\n }\n\n private async runWorktreeAddByMatrix(\n bareGit: SimpleGit,\n branchName: string,\n absoluteWorktreePath: string,\n localExists: boolean,\n remoteExists: boolean,\n ): Promise<boolean> {\n const useNoCheckout = !!this.config.sparseCheckout;\n const noCheckoutFlag = useNoCheckout ? [\"--no-checkout\"] : [];\n\n if (localExists && remoteExists) {\n await bareGit.raw([\"worktree\", \"add\", ...noCheckoutFlag, absoluteWorktreePath, branchName]);\n\n // branch --set-upstream-to is a config-only operation and works on a --no-checkout\n // worktree, so we run it before sparse setup and materialization.\n try {\n const worktreeGit = this.getCachedGit(absoluteWorktreePath, this.isLfsSkipEnabled());\n await worktreeGit.branch([\"--set-upstream-to\", `origin/${branchName}`, branchName]);\n } catch (error) {\n throw await this.wrapUpstreamFailure(bareGit, absoluteWorktreePath, branchName, false, error);\n }\n\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, branchName, false);\n return false;\n }\n\n if (localExists) {\n await bareGit.raw([\"worktree\", \"add\", ...noCheckoutFlag, absoluteWorktreePath, branchName]);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, branchName, false);\n return false;\n }\n\n if (remoteExists) {\n await bareGit.raw([\n \"worktree\",\n \"add\",\n ...noCheckoutFlag,\n \"--track\",\n \"-b\",\n branchName,\n absoluteWorktreePath,\n `origin/${branchName}`,\n ]);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, branchName, true);\n return true;\n }\n\n throw new WorktreeError(\n `Branch '${branchName}' does not exist locally or on origin; create it first`,\n \"BRANCH_NOT_FOUND\",\n );\n }\n\n private async runSparseStepWithRollback(\n bareGit: SimpleGit,\n absoluteWorktreePath: string,\n branchName: string,\n createdNewBranch: boolean,\n ): Promise<void> {\n try {\n await this.applySparseAndCheckout(absoluteWorktreePath);\n } catch (sparseError) {\n await this.rollbackPartialWorktree(bareGit, absoluteWorktreePath, branchName, createdNewBranch);\n throw new Error(`Sparse-checkout setup failed for '${branchName}': ${getErrorMessage(sparseError)}`);\n }\n }\n\n private async wrapUpstreamFailure(\n bareGit: SimpleGit,\n absoluteWorktreePath: string,\n branchName: string,\n createdNewBranch: boolean,\n error: unknown,\n ): Promise<Error> {\n const { worktreeRemoved } = await this.rollbackPartialWorktree(\n bareGit,\n absoluteWorktreePath,\n branchName,\n createdNewBranch,\n \"upstream setup error\",\n );\n const suffix = worktreeRemoved ? \"\" : \" (rollback failed; partial worktree may remain)\";\n const wrapped = new Error(`Failed to set upstream for '${branchName}': ${getErrorMessage(error)}${suffix}`);\n (wrapped as Error & { isUpstreamSetupFailure?: boolean }).isUpstreamSetupFailure = true;\n return wrapped;\n }\n\n async removeWorktree(worktreePath: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n\n await bareGit.raw([\"worktree\", \"remove\", worktreePath, \"--force\"]);\n this.logger.info(` - \u2705 Safely removed stale worktree at '${worktreePath}'.`);\n\n // Clean up metadata using the worktree path\n try {\n await this.metadataService.deleteMetadataFromPath(this.bareRepoPath, worktreePath);\n } catch (metadataError) {\n this.logger.warn(`Failed to delete metadata for worktree: ${metadataError}`);\n }\n }\n\n async pruneWorktrees(): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n await bareGit.raw([\"worktree\", \"prune\"]);\n this.logger.info(\"Pruned worktree metadata.\");\n }\n\n async checkWorktreeStatus(worktreePath: string): Promise<boolean> {\n return this.statusService.checkWorktreeStatus(worktreePath);\n }\n\n async hasUnpushedCommits(worktreePath: string): Promise<boolean> {\n const metadata = await this.metadataService.loadMetadataFromPath(this.bareRepoPath, worktreePath);\n return this.statusService.hasUnpushedCommits(worktreePath, metadata?.lastSyncCommit);\n }\n\n async hasUpstreamGone(worktreePath: string): Promise<boolean> {\n return this.statusService.hasUpstreamGone(worktreePath);\n }\n\n async hasStashedChanges(worktreePath: string): Promise<boolean> {\n return this.statusService.hasStashedChanges(worktreePath);\n }\n\n async getFullWorktreeStatus(worktreePath: string, includeDetails = false): Promise<WorktreeStatusResult> {\n const metadata = await this.metadataService.loadMetadataFromPath(this.bareRepoPath, worktreePath);\n return this.statusService.getFullWorktreeStatus(worktreePath, includeDetails, metadata?.lastSyncCommit);\n }\n\n async hasModifiedSubmodules(worktreePath: string): Promise<boolean> {\n return this.statusService.hasModifiedSubmodules(worktreePath);\n }\n\n async hasOperationInProgress(worktreePath: string): Promise<boolean> {\n return this.statusService.hasOperationInProgress(worktreePath);\n }\n\n async getCurrentBranch(): Promise<string> {\n const git = this.getGit();\n const branchSummary = await git.branch();\n return branchSummary.current;\n }\n\n private async detectDefaultBranch(bareGit: SimpleGit): Promise<string> {\n try {\n // Try to get the symbolic ref for origin/HEAD\n const headRef = await bareGit.raw([\"symbolic-ref\", \"refs/remotes/origin/HEAD\"]);\n // Extract branch name from refs/remotes/origin/main or refs/remotes/origin/master\n const branch = headRef.trim().split(\"/\").pop();\n if (branch) {\n return branch;\n }\n } catch {\n // If that fails, try to set HEAD automatically\n try {\n await bareGit.raw([\"remote\", \"set-head\", \"origin\", \"-a\"]);\n const headRef = await bareGit.raw([\"symbolic-ref\", \"refs/remotes/origin/HEAD\"]);\n const branch = headRef.trim().split(\"/\").pop();\n if (branch) {\n return branch;\n }\n } catch {\n // If all else fails, try to detect from remote branches\n try {\n const remoteBranches = await bareGit.branch([\"-r\"]);\n const commonDefaults = GIT_CONSTANTS.COMMON_DEFAULT_BRANCHES;\n for (const defaultName of commonDefaults) {\n if (remoteBranches.all.some((branch) => branch === `origin/${defaultName}`)) {\n return defaultName;\n }\n }\n } catch {\n // Ignore and fall through to default\n }\n }\n }\n // Final fallback\n return GIT_CONSTANTS.DEFAULT_BRANCH;\n }\n\n setLfsSkipEnabled(value: boolean): void {\n this.lfsSkipOverride = value;\n }\n\n private isLfsSkipEnabled(): boolean {\n return this.config.skipLfs || this.lfsSkipOverride;\n }\n\n async getWorktrees(): Promise<{ path: string; branch: string }[]> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n return this.getWorktreesFromBare(bareGit);\n }\n\n async isWorktreeBehind(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the current branch\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n // Check if the branch has an upstream\n const upstreamInfo = await worktreeGit.raw([\"rev-parse\", \"--abbrev-ref\", `${currentBranch}@{upstream}`]);\n if (!upstreamInfo.trim()) {\n return false; // No upstream, can't be behind\n }\n\n // Count commits behind upstream\n const behindCount = await worktreeGit.raw([\"rev-list\", \"--count\", `HEAD..${upstreamInfo.trim()}`]);\n return parseInt(behindCount.trim(), 10) > 0;\n } catch {\n // If any command fails, assume not behind\n return false;\n }\n }\n\n async updateWorktree(worktreePath: string): Promise<void> {\n const worktreeGit = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n\n // Perform a fast-forward merge\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n await worktreeGit.merge([`origin/${currentBranch}`, \"--ff-only\"]);\n\n // Update metadata after successful update (use path-based method)\n try {\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n await this.metadataService.updateLastSyncFromPath(\n this.bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n \"updated\",\n this.defaultBranch,\n );\n } catch (metadataError) {\n this.logger.warn(`Failed to update metadata for worktree: ${metadataError}`);\n }\n }\n\n async hasDivergedHistory(worktreePath: string, expectedBranch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n\n // Validate branch matches\n const branchInfo = await worktreeGit.branch();\n if (branchInfo.current !== expectedBranch) {\n this.logger.warn(`Branch mismatch in hasDivergedHistory: expected ${expectedBranch}, got ${branchInfo.current}`);\n return false; // Conservative: assume can fast-forward\n }\n\n try {\n // Check if HEAD is an ancestor of the remote branch (can fast-forward)\n await worktreeGit.raw([\"merge-base\", \"--is-ancestor\", \"HEAD\", `origin/${expectedBranch}`]);\n return false; // Can fast-forward\n } catch {\n return true; // Histories have diverged\n }\n }\n\n async canFastForward(worktreePath: string, branch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the merge base between HEAD and the remote branch\n const mergeBase = await worktreeGit.raw([\"merge-base\", \"HEAD\", `origin/${branch}`]);\n const mergeBaseSha = mergeBase.trim();\n\n // Get current HEAD SHA\n const headSha = await worktreeGit.revparse([\"HEAD\"]);\n const headShaTrimmed = headSha.trim();\n\n // If merge base equals HEAD, then HEAD is an ancestor of remote and can fast-forward\n return mergeBaseSha === headShaTrimmed;\n } catch {\n // If merge-base fails, branches have diverged\n return false;\n }\n }\n\n async isLocalAheadOfRemote(worktreePath: string, branch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the merge base between HEAD and the remote branch\n const mergeBase = await worktreeGit.raw([\"merge-base\", \"HEAD\", `origin/${branch}`]);\n const mergeBaseSha = mergeBase.trim();\n\n // Get remote branch SHA\n const remoteSha = await worktreeGit.revparse([`origin/${branch}`]);\n const remoteShaTrimmed = remoteSha.trim();\n\n // If merge base equals remote, local is ahead (remote is ancestor of local)\n return mergeBaseSha === remoteShaTrimmed;\n } catch {\n return false;\n }\n }\n\n async classifyRemoteRelationship(worktreePath: string, branch: string): Promise<RemoteRelationship> {\n const worktreeGit = this.getCachedGit(worktreePath);\n\n let headSha: string;\n let remoteSha: string;\n try {\n headSha = (await worktreeGit.revparse([\"HEAD\"])).trim();\n remoteSha = (await worktreeGit.revparse([`refs/remotes/origin/${branch}`])).trim();\n } catch {\n return \"diverged\";\n }\n\n if (headSha === remoteSha) return \"up_to_date\";\n\n let mergeBase = \"\";\n let mergeBaseFailed = false;\n try {\n mergeBase = (await worktreeGit.raw([\"merge-base\", \"HEAD\", `origin/${branch}`])).trim();\n } catch {\n mergeBaseFailed = true;\n }\n // simple-git swallows merge-base exit 1 and returns \"\" \u2014 treat empty output as failure too.\n if (mergeBaseFailed || !mergeBase) {\n if (await this.isShallowRepository(worktreeGit)) return \"indeterminate_shallow\";\n return \"diverged\";\n }\n if (mergeBase === headSha) return \"fast_forward\";\n if (mergeBase === remoteSha) return \"local_ahead\";\n return \"diverged\";\n }\n\n private async isShallowRepository(git: SimpleGit): Promise<boolean> {\n try {\n const output = await git.raw([\"rev-parse\", \"--is-shallow-repository\"]);\n return output.trim() === \"true\";\n } catch {\n return false;\n }\n }\n\n async getChangedPathsInRange(worktreePath: string, fromRef: string, toRef: string): Promise<string[] | null> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n const out = await worktreeGit.raw([\n \"-c\",\n \"core.quotePath=false\",\n \"diff\",\n \"--name-only\",\n \"--no-renames\",\n `${fromRef}..${toRef}`,\n ]);\n // Don't .trim() entries \u2014 leading/trailing whitespace is valid in POSIX\n // paths and `core.quotePath=false` only affects high-byte quoting, not\n // whitespace. Strip a trailing CR for Windows line endings only.\n return out\n .split(\"\\n\")\n .map((l) => l.replace(/\\r$/, \"\"))\n .filter((l) => l.length > 0);\n } catch (error) {\n this.logger.warn(`Failed to compute diff ${fromRef}..${toRef} in ${worktreePath}: ${getErrorMessage(error)}`);\n return null;\n }\n }\n\n async compareTreeContent(worktreePath: string, branch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the tree SHA for the current HEAD\n const localTree = await worktreeGit.raw([\"rev-parse\", \"HEAD^{tree}\"]);\n // Get the tree SHA for the remote branch\n const remoteTree = await worktreeGit.raw([\"rev-parse\", `origin/${branch}^{tree}`]);\n\n return localTree.trim() === remoteTree.trim();\n } catch (error) {\n this.logger.error(`Error comparing tree content: ${error}`);\n return false; // Assume trees are different if we can't compare\n }\n }\n\n async resetToUpstream(worktreePath: string, branch: string): Promise<void> {\n const worktreeGit = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n\n await worktreeGit.reset([\"--hard\", `origin/${branch}`]);\n\n // Update metadata after reset (use path-based method)\n try {\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n await this.metadataService.updateLastSyncFromPath(\n this.bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n \"updated\",\n this.defaultBranch,\n );\n } catch (metadataError) {\n this.logger.warn(`Failed to update metadata after reset: ${metadataError}`);\n }\n }\n\n async getCurrentCommit(worktreePath: string): Promise<string> {\n const worktreeGit = this.getCachedGit(worktreePath);\n const commit = await worktreeGit.revparse([\"HEAD\"]);\n return commit.trim();\n }\n\n async getRemoteCommit(ref: string): Promise<string> {\n // Use the bare repository to read remote commit to avoid dependency on main worktree path\n const git = this.getCachedGit(this.bareRepoPath);\n const commit = await git.revparse([ref]);\n return commit.trim();\n }\n\n async branchExists(branchName: string): Promise<{ local: boolean; remote: boolean }> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const checkRef = async (ref: string): Promise<boolean> => {\n try {\n // simple-git resolves `show-ref --quiet` when Git exits 1, so keep stdout enabled.\n await bareGit.raw([\"show-ref\", \"--verify\", ref]);\n return true;\n } catch {\n return false;\n }\n };\n\n const [local, remote] = await Promise.all([\n checkRef(`${GIT_CONSTANTS.REFS.HEADS}${branchName}`),\n checkRef(`${GIT_CONSTANTS.REFS.REMOTES}/${branchName}`),\n ]);\n\n return { local, remote };\n }\n\n async getLocalBranches(): Promise<string[]> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const branches = await bareGit.branch();\n return branches.all;\n }\n\n private async resolveCreateBranchBaseRef(bareGit: SimpleGit, baseBranch: string): Promise<string> {\n const candidates =\n baseBranch.startsWith(GIT_CONSTANTS.REMOTE_PREFIX) || baseBranch.startsWith(\"refs/\")\n ? [baseBranch]\n : [`${GIT_CONSTANTS.REMOTE_PREFIX}${baseBranch}`, baseBranch];\n\n for (const candidate of candidates) {\n try {\n await bareGit.revparse([\"--verify\", candidate]);\n return candidate;\n } catch {\n // Try the next candidate before letting git branch report the original failure.\n }\n }\n\n return candidates[0];\n }\n\n async createBranch(branchName: string, baseBranch: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const baseRef = await this.resolveCreateBranchBaseRef(bareGit, baseBranch);\n\n await bareGit.raw([\"branch\", \"--no-track\", branchName, baseRef]);\n this.logger.info(`Created branch '${branchName}' from '${baseRef}'`);\n }\n\n async pushBranch(branchName: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n\n await bareGit.push([\"origin\", `${branchName}:${branchName}`, \"-u\"]);\n this.logger.info(`Pushed branch '${branchName}' to remote`);\n }\n\n async getWorktreeMetadata(worktreePath: string): Promise<SyncMetadata | null> {\n return this.metadataService.loadMetadataFromPath(this.bareRepoPath, worktreePath);\n }\n\n private async getWorktreesFromBare(\n bareGit: SimpleGit,\n ): Promise<{ path: string; branch: string; isPrunable?: boolean }[]> {\n const result = await bareGit.raw([\"worktree\", \"list\", \"--porcelain\"]);\n return parseWorktreeListPorcelain(result)\n .filter((w) => !w.detached && w.branch !== null)\n .map((w) => ({\n path: w.path,\n branch: w.branch as string,\n isPrunable: w.prunable,\n }));\n }\n}\n", "export interface ParsedWorktree {\n path: string;\n branch: string | null;\n head: string | null;\n detached: boolean;\n prunable: boolean;\n locked: boolean;\n}\n\nexport function parseWorktreeListPorcelain(output: string): ParsedWorktree[] {\n const worktrees: ParsedWorktree[] = [];\n let current: Partial<ParsedWorktree> = {};\n\n const flush = (): void => {\n if (!current.path) {\n current = {};\n return;\n }\n worktrees.push({\n path: current.path,\n branch: current.branch ?? null,\n head: current.head ?? null,\n detached: current.detached ?? false,\n prunable: current.prunable ?? false,\n locked: current.locked ?? false,\n });\n current = {};\n };\n\n for (const line of output.split(\"\\n\")) {\n if (line.startsWith(\"worktree \")) {\n flush();\n current.path = line.substring(\"worktree \".length);\n } else if (line.startsWith(\"branch \")) {\n current.branch = line.substring(\"branch \".length).replace(\"refs/heads/\", \"\");\n } else if (line.startsWith(\"HEAD \")) {\n current.head = line.substring(\"HEAD \".length);\n } else if (line === \"detached\") {\n current.detached = true;\n } else if (line === \"prunable\" || line.startsWith(\"prunable \")) {\n current.prunable = true;\n } else if (line === \"locked\" || line.startsWith(\"locked \")) {\n current.locked = true;\n } else if (line.trim() === \"\") {\n flush();\n }\n }\n flush();\n return worktrees;\n}\n", "import * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { SparseCheckoutConfig, SparseCheckoutMode } from \"../types\";\nimport type { SimpleGit } from \"simple-git\";\n\nexport type GitFactory = (worktreePath: string) => SimpleGit;\n\ninterface SparseMatcher {\n mode: SparseCheckoutMode;\n patterns: string[];\n ancestorDirs: Set<string>;\n}\n\nexport class SparseCheckoutService {\n private logger: Logger;\n private gitFactory: GitFactory;\n private warnedConfigs = new WeakSet<SparseCheckoutConfig>();\n private matcherCache = new WeakMap<SparseCheckoutConfig, SparseMatcher>();\n\n constructor(logger?: Logger, gitFactory?: GitFactory) {\n this.logger = logger ?? Logger.createDefault();\n this.gitFactory = gitFactory ?? ((p: string): SimpleGit => simpleGit(p));\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n resolveMode(cfg: SparseCheckoutConfig): SparseCheckoutMode {\n const hasExclude = !!cfg.exclude && cfg.exclude.length > 0;\n const hasNegation = cfg.include.some((p) => p.trim().startsWith(\"!\"));\n\n if (cfg.mode === \"no-cone\") return \"no-cone\";\n if (hasExclude || hasNegation) {\n if (cfg.mode === \"cone\" && !this.warnedConfigs.has(cfg)) {\n this.logger.warn(\n \"sparseCheckout: mode 'cone' is incompatible with excludes or negation patterns; auto-promoting to 'no-cone'\",\n );\n this.warnedConfigs.add(cfg);\n }\n return \"no-cone\";\n }\n return cfg.mode ?? \"cone\";\n }\n\n buildPatterns(cfg: SparseCheckoutConfig): string[] {\n return this.buildPatternsForMode(cfg, this.resolveMode(cfg));\n }\n\n private buildPatternsForMode(cfg: SparseCheckoutConfig, mode: SparseCheckoutMode): string[] {\n const includes = cfg.include.map((p) => p.trim()).filter((p) => p.length > 0);\n\n if (mode === \"cone\") {\n return includes;\n }\n\n const excludes = (cfg.exclude ?? [])\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n .map((p) => (p.startsWith(\"!\") ? p : `!${p}`));\n\n return [...includes, ...excludes];\n }\n\n async applyToWorktree(worktreePath: string, cfg: SparseCheckoutConfig): Promise<void> {\n const mode = this.resolveMode(cfg);\n const patterns = this.buildPatternsForMode(cfg, mode);\n\n if (patterns.length === 0) {\n throw new Error(\"sparseCheckout produced no patterns; refusing to apply empty config\");\n }\n\n const git = this.gitFactory(worktreePath);\n await git.raw([\"sparse-checkout\", \"init\", mode === \"cone\" ? \"--cone\" : \"--no-cone\"]);\n await git.raw([\"sparse-checkout\", \"set\", mode === \"cone\" ? \"--cone\" : \"--no-cone\", ...patterns]);\n }\n\n async readCurrent(worktreePath: string): Promise<string[] | null> {\n const git = this.gitFactory(worktreePath);\n try {\n const out = await git.raw([\"sparse-checkout\", \"list\"]);\n const lines = out\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter((l) => l.length > 0 && !l.startsWith(\"#\"));\n return lines.length === 0 ? null : lines;\n } catch {\n return null;\n }\n }\n\n async readCurrentMode(worktreePath: string): Promise<SparseCheckoutMode | null> {\n const git = this.gitFactory(worktreePath);\n try {\n const out = await git.raw([\"config\", \"--bool\", \"--get\", \"core.sparseCheckoutCone\"]);\n const value = out.trim().toLowerCase();\n if (value === \"true\") return \"cone\";\n if (value === \"false\") return \"no-cone\";\n return null;\n } catch {\n return null;\n }\n }\n\n async needsUpdate(worktreePath: string, cfg: SparseCheckoutConfig): Promise<boolean> {\n const desiredMode = this.resolveMode(cfg);\n const currentMode = await this.readCurrentMode(worktreePath);\n if (currentMode !== desiredMode) return true;\n const current = await this.readCurrent(worktreePath);\n if (current === null) return true;\n return !this.patternsEqual(current, this.buildPatternsForMode(cfg, desiredMode));\n }\n\n isNarrowing(currentPatterns: string[] | null, nextPatterns: string[]): boolean {\n if (!currentPatterns || currentPatterns.length === 0) return false;\n\n const isNeg = (p: string): boolean => p.startsWith(\"!\");\n const trim = (xs: string[]): string[] => xs.map((p) => p.trim()).filter((p) => p.length > 0);\n\n const cur = trim(currentPatterns);\n const next = trim(nextPatterns);\n\n const positiveCurrent = new Set(cur.filter((p) => !isNeg(p)));\n const negativeCurrent = new Set(cur.filter(isNeg));\n const positiveNext = new Set(next.filter((p) => !isNeg(p)));\n const negativeNext = new Set(next.filter(isNeg));\n\n for (const p of positiveCurrent) {\n if (!positiveNext.has(p)) return true;\n }\n for (const p of negativeNext) {\n if (!negativeCurrent.has(p)) return true;\n }\n return false;\n }\n\n patternsEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n const at = a.map((x) => x.trim());\n const bt = b.map((x) => x.trim());\n return at.every((v, i) => v === bt[i]);\n }\n\n /**\n * Decide whether a list of changed file paths intersects the sparse-checkout\n * set defined by `cfg`. Used to skip fast-forward updates when upstream\n * commits only touch files outside the materialized worktree.\n *\n * Cone mode materializes:\n * - all files at the repository root,\n * - all files directly inside every ancestor of an included directory\n * (e.g. include `tools/build` keeps `tools/foo.txt` checked out too),\n * - everything inside an included directory.\n * We mirror those rules here. Missing the ancestor-files case would let\n * stale files linger when only those parent files change upstream.\n *\n * No-cone mode: gitignore-style matching with negation is non-trivial and\n * not implemented here yet. We return `true` so the caller falls back to\n * the safe behavior of always running the update.\n *\n * The matcher derived from `cfg` is cached on the cfg object identity\n * (WeakMap), so callers should reuse the same `cfg` reference across\n * invocations to benefit from the cache.\n */\n pathsTouchSparse(changedPaths: string[], cfg: SparseCheckoutConfig): boolean {\n if (changedPaths.length === 0) return false;\n\n const matcher = this.getMatcher(cfg);\n if (matcher.mode === \"no-cone\") return true;\n if (matcher.patterns.length === 0) return true;\n\n return changedPaths.some((p) => {\n if (!p.includes(\"/\")) return true;\n for (const pat of matcher.patterns) {\n if (p === pat || p.startsWith(pat + \"/\")) return true;\n }\n return matcher.ancestorDirs.has(path.posix.dirname(p));\n });\n }\n\n private getMatcher(cfg: SparseCheckoutConfig): SparseMatcher {\n const cached = this.matcherCache.get(cfg);\n if (cached) return cached;\n\n const mode = this.resolveMode(cfg);\n if (mode === \"no-cone\") {\n const matcher: SparseMatcher = { mode, patterns: [], ancestorDirs: new Set() };\n this.matcherCache.set(cfg, matcher);\n return matcher;\n }\n\n const patterns = cfg.include\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n .map((p) => (p.endsWith(\"/\") ? p.slice(0, -1) : p));\n\n const ancestorDirs = new Set<string>();\n for (const pat of patterns) {\n const parts = pat.split(\"/\");\n for (let i = 1; i < parts.length; i++) {\n ancestorDirs.add(parts.slice(0, i).join(\"/\"));\n }\n }\n\n const matcher: SparseMatcher = { mode, patterns, ancestorDirs };\n this.matcherCache.set(cfg, matcher);\n return matcher;\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { ERROR_MESSAGES, GIT_CONSTANTS, METADATA_CONSTANTS } from \"../constants\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { SyncMetadata } from \"../types/sync-metadata\";\n\nexport class WorktreeMetadataService {\n private logger: Logger;\n\n constructor(logger?: Logger) {\n this.logger = logger ?? Logger.createDefault();\n }\n\n /**\n * Gets the internal worktree directory name from a worktree path.\n * Git uses the basename of the worktree path as the internal directory name.\n * For example: /worktrees/fix/test-branch -> test-branch (not fix/test-branch)\n */\n private getWorktreeDirectoryName(worktreePath: string): string {\n return path.basename(worktreePath);\n }\n\n async getMetadataPath(bareRepoPath: string, worktreeName: string): Promise<string> {\n if (worktreeName.includes(\"/\") || worktreeName.includes(\"\\\\\")) {\n throw new Error(\n `getMetadataPath requires a filesystem-safe worktree directory name, got '${worktreeName}'. Use getMetadataPathFromWorktreePath when starting from a raw branch name.`,\n );\n }\n return path.join(\n bareRepoPath,\n METADATA_CONSTANTS.WORKTREE_METADATA_PATH,\n worktreeName,\n METADATA_CONSTANTS.METADATA_FILENAME,\n );\n }\n\n async getMetadataPathFromWorktreePath(bareRepoPath: string, worktreePath: string): Promise<string> {\n // Extract the worktree directory name (basename) that Git actually uses\n const worktreeDirName = this.getWorktreeDirectoryName(worktreePath);\n return this.getMetadataPath(bareRepoPath, worktreeDirName);\n }\n\n async saveMetadata(bareRepoPath: string, worktreeName: string, metadata: SyncMetadata): Promise<void> {\n const metadataPath = await this.getMetadataPath(bareRepoPath, worktreeName);\n await fs.mkdir(path.dirname(metadataPath), { recursive: true });\n\n // Write to temp file then rename for atomicity \u2014 prevents corruption on crash.\n // Unique suffix avoids collisions between concurrent writers for the same worktree.\n const tmpPath = `${metadataPath}.${process.pid}.${Date.now()}.tmp`;\n let renamed = false;\n try {\n await fs.writeFile(tmpPath, JSON.stringify(metadata, null, 2), \"utf-8\");\n try {\n await fs.rename(tmpPath, metadataPath);\n renamed = true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === ERROR_MESSAGES.EXDEV) {\n await fs.copyFile(tmpPath, metadataPath);\n } else {\n throw err;\n }\n }\n } finally {\n if (!renamed) {\n await fs.unlink(tmpPath).catch(() => undefined);\n }\n }\n }\n\n async loadMetadata(bareRepoPath: string, worktreeName: string): Promise<SyncMetadata | null> {\n const metadataPath = await this.getMetadataPath(bareRepoPath, worktreeName);\n\n try {\n const content = await fs.readFile(metadataPath, \"utf-8\");\n return JSON.parse(content) as SyncMetadata;\n } catch {\n // Return null if file doesn't exist or can't be parsed\n return null;\n }\n }\n\n async loadMetadataFromPath(bareRepoPath: string, worktreePath: string): Promise<SyncMetadata | null> {\n const metadataPath = await this.getMetadataPathFromWorktreePath(bareRepoPath, worktreePath);\n\n try {\n const content = await fs.readFile(metadataPath, \"utf-8\");\n const metadata = JSON.parse(content) as SyncMetadata;\n\n if (!(await this.validateMetadata(metadata))) {\n this.logger.warn(`Corrupted metadata for ${worktreePath}, treating as missing`);\n return null;\n }\n\n return metadata;\n } catch {\n return null;\n }\n }\n\n async deleteMetadata(bareRepoPath: string, worktreeName: string): Promise<void> {\n const metadataPath = await this.getMetadataPath(bareRepoPath, worktreeName);\n\n try {\n await fs.unlink(metadataPath);\n } catch (error) {\n // Ignore errors if file doesn't exist\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n }\n\n async deleteMetadataFromPath(bareRepoPath: string, worktreePath: string): Promise<void> {\n const metadataPath = await this.getMetadataPathFromWorktreePath(bareRepoPath, worktreePath);\n\n try {\n await fs.unlink(metadataPath);\n } catch (error) {\n // Ignore errors if file doesn't exist\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n }\n\n async updateLastSync(\n bareRepoPath: string,\n worktreeName: string,\n commit: string,\n action: \"created\" | \"updated\" | \"fetched\" = \"updated\",\n ): Promise<void> {\n const existing = await this.loadMetadata(bareRepoPath, worktreeName);\n\n if (!existing) {\n this.logger.warn(\n `No metadata found for worktree ${worktreeName}; skipping update because upstream/parent context is unavailable`,\n );\n return;\n }\n\n existing.lastSyncCommit = commit;\n existing.lastSyncDate = new Date().toISOString();\n\n existing.syncHistory.push({\n date: existing.lastSyncDate,\n commit,\n action,\n });\n\n if (existing.syncHistory.length > METADATA_CONSTANTS.MAX_HISTORY_ENTRIES) {\n existing.syncHistory = existing.syncHistory.slice(-METADATA_CONSTANTS.MAX_HISTORY_ENTRIES);\n }\n\n await this.saveMetadata(bareRepoPath, worktreeName, existing);\n }\n\n async updateLastSyncFromPath(\n bareRepoPath: string,\n worktreePath: string,\n commit: string,\n action: \"created\" | \"updated\" | \"fetched\" = \"updated\",\n defaultBranch?: string,\n ): Promise<void> {\n const worktreeDirName = this.getWorktreeDirectoryName(worktreePath);\n const existing = await this.loadMetadataFromPath(bareRepoPath, worktreePath);\n\n if (!existing) {\n this.logger.warn(`No metadata found for worktree ${worktreeDirName}`);\n this.logger.info(` Attempting to create initial metadata...`);\n\n try {\n const worktreeGit = simpleGit(worktreePath);\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n\n const branchSummary = await worktreeGit.branch();\n const actualBranchName = branchSummary.current;\n\n if (!actualBranchName) {\n throw new Error(\"Could not determine current branch name\");\n }\n\n let upstreamBranch = `origin/${actualBranchName}`;\n try {\n const configuredUpstream = await worktreeGit.raw([\n \"rev-parse\",\n \"--abbrev-ref\",\n `${actualBranchName}@{upstream}`,\n ]);\n if (configuredUpstream.trim()) {\n upstreamBranch = configuredUpstream.trim();\n }\n } catch {\n // No configured upstream, use constructed value\n }\n\n const parentBranch = defaultBranch || GIT_CONSTANTS.DEFAULT_BRANCH;\n\n await this.createInitialMetadataFromPath(\n bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n upstreamBranch,\n parentBranch,\n currentCommit.trim(),\n );\n this.logger.info(` \u2705 Created metadata for ${worktreeDirName}`);\n return;\n } catch (error) {\n this.logger.error(` \u274C Failed to create metadata`, error);\n throw error;\n }\n }\n\n // Update metadata\n existing.lastSyncCommit = commit;\n existing.lastSyncDate = new Date().toISOString();\n\n existing.syncHistory.push({\n date: existing.lastSyncDate,\n commit,\n action,\n });\n\n if (existing.syncHistory.length > METADATA_CONSTANTS.MAX_HISTORY_ENTRIES) {\n existing.syncHistory = existing.syncHistory.slice(-METADATA_CONSTANTS.MAX_HISTORY_ENTRIES);\n }\n\n // Save using the directory name\n await this.saveMetadata(bareRepoPath, worktreeDirName, existing);\n }\n\n async createInitialMetadata(\n bareRepoPath: string,\n worktreeName: string,\n commit: string,\n upstreamBranch: string,\n parentBranch: string,\n parentCommit: string,\n ): Promise<void> {\n const metadata: SyncMetadata = {\n lastSyncCommit: commit,\n lastSyncDate: new Date().toISOString(),\n upstreamBranch,\n createdFrom: {\n branch: parentBranch,\n commit: parentCommit,\n },\n syncHistory: [\n {\n date: new Date().toISOString(),\n commit,\n action: \"created\",\n },\n ],\n };\n\n await this.saveMetadata(bareRepoPath, worktreeName, metadata);\n }\n\n async createInitialMetadataFromPath(\n bareRepoPath: string,\n worktreePath: string,\n commit: string,\n upstreamBranch: string,\n parentBranch: string,\n parentCommit: string,\n ): Promise<void> {\n const worktreeDirName = this.getWorktreeDirectoryName(worktreePath);\n const metadata: SyncMetadata = {\n lastSyncCommit: commit,\n lastSyncDate: new Date().toISOString(),\n upstreamBranch,\n createdFrom: {\n branch: parentBranch,\n commit: parentCommit,\n },\n syncHistory: [\n {\n date: new Date().toISOString(),\n commit,\n action: \"created\",\n },\n ],\n };\n\n await this.saveMetadata(bareRepoPath, worktreeDirName, metadata);\n }\n\n async validateMetadata(metadata: SyncMetadata): Promise<boolean> {\n if (!metadata.lastSyncCommit || !metadata.lastSyncDate || !metadata.upstreamBranch) {\n return false;\n }\n\n if (!/^[0-9a-f]+$/i.test(metadata.lastSyncCommit)) {\n return false;\n }\n\n if (Number.isNaN(new Date(metadata.lastSyncDate).getTime())) {\n return false;\n }\n\n return true;\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { ENV_CONSTANTS, GIT_CONSTANTS, GIT_OPERATIONS, PATH_CONSTANTS } from \"../constants\";\nimport { GitOperationError, WorktreeNotCleanError } from \"../errors\";\nimport { fileExists } from \"../utils/file-exists\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { SimpleGit } from \"simple-git\";\n\nexport interface WorktreeStatusDetails {\n modifiedFiles: number;\n deletedFiles: number;\n renamedFiles: number;\n createdFiles: number;\n conflictedFiles: number;\n untrackedFiles: number;\n unpushedCommitCount?: number;\n stashCount?: number;\n operationType?: string;\n modifiedSubmodules?: string[];\n modifiedFilesList?: string[];\n deletedFilesList?: string[];\n renamedFilesList?: Array<{ from: string; to: string }>;\n createdFilesList?: string[];\n conflictedFilesList?: string[];\n untrackedFilesList?: string[];\n}\n\nexport interface WorktreeStatusResult {\n isClean: boolean;\n hasUnpushedCommits: boolean;\n hasStashedChanges: boolean;\n hasOperationInProgress: boolean;\n hasModifiedSubmodules: boolean;\n upstreamGone: boolean;\n canRemove: boolean;\n reasons: string[];\n details?: WorktreeStatusDetails;\n}\n\nconst OPERATION_FILES: ReadonlyArray<{ file: string; type: string }> = [\n { file: GIT_OPERATIONS.MERGE_HEAD, type: \"merge\" },\n { file: GIT_OPERATIONS.CHERRY_PICK_HEAD, type: \"cherry-pick\" },\n { file: GIT_OPERATIONS.REVERT_HEAD, type: \"revert\" },\n { file: GIT_OPERATIONS.BISECT_LOG, type: \"bisect\" },\n { file: GIT_OPERATIONS.REBASE_MERGE, type: \"rebase\" },\n { file: GIT_OPERATIONS.REBASE_APPLY, type: \"rebase (apply)\" },\n];\n\ninterface WorktreeSnapshot {\n exists: boolean;\n status: Awaited<ReturnType<SimpleGit[\"status\"]>> | null;\n currentBranch: string | null;\n detached: boolean;\n remoteBranches: string[];\n upstream: string | null;\n unpushedCount: number | null;\n stashTotal: number | null;\n submoduleStatus: string | null;\n operationFile: string | null;\n gitDir: string | null;\n untrackedNotIgnored: string[];\n}\n\nexport class WorktreeStatusService {\n private gitInstances = new Map<string, SimpleGit>();\n private logger: Logger;\n\n constructor(\n private readonly config: { skipLfs?: boolean } = {},\n logger?: Logger,\n ) {\n this.logger = logger ?? Logger.createDefault();\n }\n\n async checkWorktreeStatus(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n const status = await worktreeGit.status();\n\n const hasTrackedChanges =\n status.modified.length > 0 ||\n status.deleted.length > 0 ||\n status.renamed.length > 0 ||\n status.created.length > 0 ||\n status.conflicted.length > 0;\n\n if (hasTrackedChanges) {\n return false;\n }\n\n if (status.not_added.length > 0) {\n const untrackedFiles = status.not_added;\n const notIgnoredFiles = await this.filterUntrackedFiles(worktreePath, untrackedFiles);\n return notIgnoredFiles.length === 0;\n }\n\n return true;\n }\n\n async getFullWorktreeStatus(\n worktreePath: string,\n includeDetails = false,\n lastSyncCommit?: string,\n ): Promise<WorktreeStatusResult> {\n if (!(await fileExists(worktreePath))) {\n return {\n isClean: true,\n hasUnpushedCommits: false,\n hasStashedChanges: false,\n hasOperationInProgress: false,\n hasModifiedSubmodules: false,\n upstreamGone: false,\n canRemove: true,\n reasons: [],\n };\n }\n\n const snap = await this.collectSnapshot(worktreePath, lastSyncCommit);\n\n const isClean = this.deriveIsClean(snap);\n const hasUnpushedCommits = !snap.detached && (snap.unpushedCount ?? 1) > 0;\n const hasStashedChanges = snap.stashTotal === null ? true : snap.stashTotal > 0;\n const hasOperationInProgress = snap.gitDir === null ? true : snap.operationFile !== null;\n const hasModifiedSubmodules = this.deriveModifiedSubmodules(snap).length > 0 || snap.submoduleStatus === null;\n const upstreamGone =\n !snap.detached && snap.upstream !== null && snap.remoteBranches.length > 0\n ? !snap.remoteBranches.includes(snap.upstream)\n : false;\n\n const reasons: string[] = [];\n if (!isClean) reasons.push(\"uncommitted changes\");\n if (hasUnpushedCommits) reasons.push(\"unpushed commits\");\n if (hasStashedChanges) reasons.push(\"stashed changes\");\n if (hasOperationInProgress) reasons.push(\"operation in progress\");\n if (hasModifiedSubmodules) reasons.push(\"modified submodules\");\n if (upstreamGone) reasons.push(\"upstream gone\");\n\n const canRemove =\n isClean && !hasUnpushedCommits && !hasStashedChanges && !hasOperationInProgress && !hasModifiedSubmodules;\n\n const details: WorktreeStatusDetails | undefined = includeDetails ? this.buildStatusDetails(snap) : undefined;\n\n return {\n isClean,\n hasUnpushedCommits,\n hasStashedChanges,\n hasOperationInProgress,\n hasModifiedSubmodules,\n upstreamGone,\n canRemove,\n reasons,\n details,\n };\n }\n\n private async collectSnapshot(worktreePath: string, lastSyncCommit?: string): Promise<WorktreeSnapshot> {\n const git = this.createGitInstance(worktreePath);\n\n const [status, branchResult, remoteBranchesResult, stashResult, submoduleResult, gitDirResult] = await Promise.all([\n git.status().catch((e: unknown) => {\n this.logger.error(`Error reading status for ${worktreePath}`, e);\n return null;\n }),\n git.branch().catch(() => null),\n git.branch([\"-r\"]).catch(() => null),\n git.stashList().catch((e: unknown) => {\n this.logger.error(`Error checking stash`, e);\n return null;\n }),\n git.raw([\"submodule\", \"status\"]).catch((e: unknown) => {\n this.logger.error(`Error checking submodule status`, e);\n return null;\n }),\n this.resolveGitDir(worktreePath).catch((e: unknown) => {\n this.logger.error(`Error checking operation in progress for ${worktreePath}`, e);\n return null;\n }),\n ]);\n\n const currentBranch = branchResult?.current ?? null;\n const detached = !branchResult?.current || Boolean((branchResult as { detached?: boolean })?.detached);\n\n let upstream: string | null = null;\n let unpushedCount: number | null = null;\n if (!detached && currentBranch) {\n const revListArgs = lastSyncCommit\n ? [\"rev-list\", \"--count\", `${lastSyncCommit}..HEAD`]\n : [\"rev-list\", \"--count\", currentBranch, \"--not\", \"--remotes\"];\n\n const [upstreamResult, unpushedResult] = await Promise.all([\n git.raw([\"rev-parse\", \"--abbrev-ref\", `${currentBranch}@{upstream}`]).then(\n (raw) => ({ ok: true as const, value: raw }),\n (error: unknown) => ({ ok: false as const, error }),\n ),\n git.raw(revListArgs).then(\n (raw) => ({ ok: true as const, value: raw }),\n (error: unknown) => ({ ok: false as const, error }),\n ),\n ]);\n\n if (upstreamResult.ok) {\n upstream = upstreamResult.value.trim() || null;\n } else {\n const errorMessage = getErrorMessage(upstreamResult.error);\n if (\n !errorMessage.includes(\"fatal: no upstream configured\") &&\n !errorMessage.includes(\"no upstream configured for branch\") &&\n !errorMessage.includes(\"fatal: ambiguous argument\") &&\n !errorMessage.includes(\"unknown revision or path\")\n ) {\n this.logger.error(`Unexpected error checking upstream status for ${worktreePath}: ${errorMessage}`);\n }\n }\n\n if (unpushedResult.ok) {\n unpushedCount = parseInt(unpushedResult.value.trim(), 10);\n } else {\n this.logger.error(`Error checking unpushed commits`, unpushedResult.error);\n }\n }\n\n const operationFile = gitDirResult ? await this.detectOperationFile(gitDirResult) : null;\n\n let untrackedNotIgnored: string[] = [];\n if (status && status.not_added.length > 0) {\n try {\n untrackedNotIgnored = await this.filterUntrackedFiles(worktreePath, status.not_added);\n } catch {\n untrackedNotIgnored = status.not_added;\n }\n }\n\n return {\n exists: true,\n status,\n currentBranch,\n detached,\n remoteBranches: remoteBranchesResult?.all ?? [],\n upstream,\n unpushedCount,\n stashTotal: stashResult?.total ?? null,\n submoduleStatus: submoduleResult,\n operationFile,\n gitDir: gitDirResult,\n untrackedNotIgnored,\n };\n }\n\n private deriveIsClean(snap: WorktreeSnapshot): boolean {\n const status = snap.status;\n if (!status) return false;\n const hasTracked =\n status.modified.length > 0 ||\n status.deleted.length > 0 ||\n status.renamed.length > 0 ||\n status.created.length > 0 ||\n status.conflicted.length > 0;\n if (hasTracked) return false;\n return snap.untrackedNotIgnored.length === 0;\n }\n\n private deriveModifiedSubmodules(snap: WorktreeSnapshot): string[] {\n if (!snap.submoduleStatus) return [];\n const modified: string[] = [];\n for (const line of snap.submoduleStatus.split(\"\\n\").filter((l) => l.trim())) {\n const firstChar = line.charAt(0);\n if (firstChar === GIT_CONSTANTS.SUBMODULE_STATUS_ADDED || firstChar === GIT_CONSTANTS.SUBMODULE_STATUS_REMOVED) {\n const match = line.match(/^[+-]\\s*(\\S+)/);\n if (match) modified.push(match[1]);\n }\n }\n return modified;\n }\n\n private buildStatusDetails(snap: WorktreeSnapshot): WorktreeStatusDetails {\n const status = snap.status;\n const details: WorktreeStatusDetails = {\n modifiedFiles: status?.modified.length ?? 0,\n deletedFiles: status?.deleted.length ?? 0,\n renamedFiles: status?.renamed.length ?? 0,\n createdFiles: status?.created.length ?? 0,\n conflictedFiles: status?.conflicted.length ?? 0,\n untrackedFiles: snap.untrackedNotIgnored.length,\n };\n if (status) {\n if (status.modified.length > 0) details.modifiedFilesList = status.modified;\n if (status.deleted.length > 0) details.deletedFilesList = status.deleted;\n if (status.renamed.length > 0) {\n details.renamedFilesList = status.renamed.map((r) => ({ from: r.from, to: r.to }));\n }\n if (status.created.length > 0) details.createdFilesList = status.created;\n if (status.conflicted.length > 0) details.conflictedFilesList = status.conflicted;\n }\n if (snap.untrackedNotIgnored.length > 0) details.untrackedFilesList = snap.untrackedNotIgnored;\n if (!snap.detached && snap.unpushedCount !== null) details.unpushedCommitCount = snap.unpushedCount;\n if (snap.stashTotal !== null) details.stashCount = snap.stashTotal;\n const opType = this.operationTypeFromFile(snap.operationFile);\n if (opType) details.operationType = opType;\n const modSubs = this.deriveModifiedSubmodules(snap);\n if (modSubs.length > 0) details.modifiedSubmodules = modSubs;\n return details;\n }\n\n private operationTypeFromFile(file: string | null): string | undefined {\n if (!file) return undefined;\n return OPERATION_FILES.find((op) => op.file === file)?.type;\n }\n\n private async detectOperationFile(gitDir: string): Promise<string | null> {\n const results = await Promise.all(\n OPERATION_FILES.map(({ file }) =>\n fs.access(path.join(gitDir, file)).then(\n () => true,\n () => false,\n ),\n ),\n );\n const idx = results.findIndex(Boolean);\n return idx >= 0 ? OPERATION_FILES[idx].file : null;\n }\n\n async hasUnpushedCommits(worktreePath: string, lastSyncCommit?: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n if (await this.isDetachedHead(worktreeGit)) {\n return false;\n }\n\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n if (lastSyncCommit) {\n try {\n const newCommitsResult = await worktreeGit.raw([\"rev-list\", \"--count\", `${lastSyncCommit}..HEAD`]);\n const newCommitsCount = parseInt(newCommitsResult.trim(), 10);\n return newCommitsCount > 0;\n } catch {\n // Fall through to regular check\n }\n }\n\n const result = await worktreeGit.raw([\"rev-list\", \"--count\", currentBranch, \"--not\", \"--remotes\"]);\n const unpushedCount = parseInt(result.trim(), 10);\n return unpushedCount > 0;\n } catch (error) {\n this.logger.error(`Error checking unpushed commits`, error);\n return true;\n }\n }\n\n async hasUpstreamGone(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n if (await this.isDetachedHead(worktreeGit)) {\n return false;\n }\n\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n const upstream = await worktreeGit.raw([\"rev-parse\", \"--abbrev-ref\", `${currentBranch}@{upstream}`]);\n const remoteBranches = await worktreeGit.branch([\"-r\"]);\n\n return !remoteBranches.all.includes(upstream.trim());\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n if (\n errorMessage.includes(\"fatal: no upstream configured\") ||\n errorMessage.includes(\"no upstream configured for branch\") ||\n errorMessage.includes(\"fatal: ambiguous argument\") ||\n errorMessage.includes(\"unknown revision or path\")\n ) {\n return false;\n }\n\n this.logger.error(`Unexpected error checking upstream status for ${worktreePath}: ${errorMessage}`);\n return true;\n }\n }\n\n async hasStashedChanges(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n const stashList = await worktreeGit.stashList();\n return stashList.total > 0;\n } catch (error) {\n this.logger.error(`Error checking stash`, error);\n return true; // Conservative: assume unsafe to delete\n }\n }\n\n async hasModifiedSubmodules(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n const result = await worktreeGit.raw([\"submodule\", \"status\"]);\n const lines = result.split(\"\\n\").filter((line) => line.trim());\n\n for (const line of lines) {\n const firstChar = line.charAt(0);\n if (\n firstChar === GIT_CONSTANTS.SUBMODULE_STATUS_ADDED ||\n firstChar === GIT_CONSTANTS.SUBMODULE_STATUS_REMOVED\n ) {\n return true;\n }\n }\n return false;\n } catch (error) {\n this.logger.error(`Error checking submodule status`, error);\n return true;\n }\n }\n\n async hasOperationInProgress(worktreePath: string): Promise<boolean> {\n try {\n const gitDir = await this.resolveGitDir(worktreePath);\n return (await this.detectOperationFile(gitDir)) !== null;\n } catch (error) {\n this.logger.error(`Error checking operation in progress for ${worktreePath}`, error);\n return true;\n }\n }\n\n async validateWorktreeForRemoval(worktreePath: string, lastSyncCommit?: string): Promise<void> {\n const status = await this.getFullWorktreeStatus(worktreePath, false, lastSyncCommit);\n\n if (!status.canRemove) {\n throw new WorktreeNotCleanError(worktreePath, status.reasons);\n }\n }\n\n private async filterUntrackedFiles(worktreePath: string, files: string[]): Promise<string[]> {\n if (files.length === 0) return [];\n\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n const result = await worktreeGit.raw([\"check-ignore\", \"--\", ...files]);\n\n const ignoredFiles = new Set(\n result\n .trim()\n .split(\"\\n\")\n .filter((f) => f),\n );\n return files.filter((f) => !ignoredFiles.has(f));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n if (errorMessage.includes(GIT_CONSTANTS.GIT_CHECK_IGNORE_NO_MATCH)) {\n return files;\n }\n\n throw error;\n }\n }\n\n private async isDetachedHead(worktreeGit: SimpleGit): Promise<boolean> {\n try {\n const branchSummary = await worktreeGit.branch();\n return !branchSummary.current || branchSummary.detached;\n } catch {\n return true;\n }\n }\n\n private async resolveGitDir(worktreePath: string): Promise<string> {\n const gitPath = path.join(worktreePath, PATH_CONSTANTS.GIT_DIR);\n\n try {\n const stat = await fs.stat(gitPath);\n\n if (stat.isFile()) {\n const content = await fs.readFile(gitPath, \"utf-8\");\n const gitdirMatch = content.match(new RegExp(`^${GIT_CONSTANTS.GITDIR_PREFIX}\\\\s*(.+)$`, \"m\"));\n if (gitdirMatch) {\n return path.resolve(worktreePath, gitdirMatch[1].trim());\n }\n throw new GitOperationError(\"resolve-git-dir\", `Failed to parse gitdir from .git file at ${gitPath}`);\n }\n\n return gitPath;\n } catch (error) {\n throw new GitOperationError(\n \"resolve-git-dir\",\n `Failed to resolve .git directory for ${worktreePath}`,\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n private createGitInstance(worktreePath: string): SimpleGit {\n const key = `${path.resolve(worktreePath)}::${this.config.skipLfs ? \"1\" : \"0\"}`;\n let git = this.gitInstances.get(key);\n if (!git) {\n git = this.config.skipLfs\n ? simpleGit(worktreePath).env({ [ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE]: \"1\" })\n : simpleGit(worktreePath);\n this.gitInstances.set(key, git);\n }\n return git;\n }\n}\n", "export interface ProgressEvent {\n phase: string;\n message: string;\n progress?: number;\n processed?: number;\n total?: number;\n}\n\nexport type ProgressListener = (event: ProgressEvent) => void;\n\nexport class ProgressEmitter {\n private listeners = new Set<ProgressListener>();\n\n onProgress(listener: ProgressListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n emit(event: ProgressEvent): void {\n // Snapshot so a listener that unsubscribes a sibling during emit doesn't\n // skip that sibling's notification for this event.\n for (const listener of [...this.listeners]) {\n try {\n listener(event);\n } catch {\n // Progress listeners must not break sync flow.\n }\n }\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport * as lockfile from \"proper-lockfile\";\n\nimport { DEFAULT_CONFIG, ENV_CONSTANTS } from \"../constants\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\nimport { getCloneModeLockTarget } from \"../utils/lock-path\";\nimport { REPOSITORY_MODES, resolveMode } from \"../utils/repo-mode\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { Config } from \"../types\";\nimport type { GitService } from \"./git.service\";\n\nexport type RepoLockRelease = () => Promise<void>;\n\nexport class RepoOperationLock {\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger = Logger.createDefault(),\n ) {}\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n async acquire(): Promise<RepoLockRelease | null> {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) {\n return async () => {};\n }\n\n if (resolveMode(this.config) === REPOSITORY_MODES.CLONE) {\n return this.acquireCloneModeLock();\n }\n\n return this.acquireWorktreeModeLock();\n }\n\n private async acquireCloneModeLock(): Promise<RepoLockRelease | null> {\n const target = getCloneModeLockTarget(this.config);\n const lockTarget = path.join(target.dir, target.file);\n try {\n await fs.mkdir(target.dir, { recursive: true });\n await fs.writeFile(lockTarget, \"\", { flag: \"a\" });\n } catch {\n // Couldn't prepare the lock target (read-only FS, ENOSPC, EACCES).\n // Treat as 'unable to acquire' so the operation is skipped cleanly\n // instead of crashing the whole sync run.\n return null;\n }\n return this.lockPath(lockTarget);\n }\n\n private async acquireWorktreeModeLock(): Promise<RepoLockRelease | null> {\n const barePath = this.gitService.getBareRepoPath();\n try {\n await fs.mkdir(barePath, { recursive: true });\n } catch {\n return null;\n }\n return this.lockPath(barePath);\n }\n\n private async lockPath(lockTarget: string): Promise<RepoLockRelease | null> {\n try {\n return await lockfile.lock(lockTarget, {\n stale: DEFAULT_CONFIG.LOCK_STALE_MS,\n update: DEFAULT_CONFIG.LOCK_UPDATE_MS,\n retries: 0,\n realpath: false,\n });\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ELOCKED\") {\n return null;\n }\n // A lock we cannot acquire (read-only FS, EACCES/EROFS/EPERM surfaced at\n // lock time rather than during prep) must be a clean skip, never a fatal\n // error that crashes the whole multi-repo run. Surface it as a warning so\n // the cause is visible.\n this.logger.warn(\n `Could not acquire repo lock at '${lockTarget}' (${code ?? \"unknown\"}: ${getErrorMessage(error)}); skipping.`,\n );\n return null;\n }\n }\n}\n", "import { createHash } from \"crypto\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\nimport { sanitizeNameForPath } from \"./sanitize-name\";\n\nimport type { Config, RepositoryConfig } from \"../types\";\n\nexport interface RepoLockTarget {\n /** Absolute path to the directory that should contain the lock file. */\n dir: string;\n /** Lock filename (created lazily by proper-lockfile). */\n file: string;\n}\n\nexport function getCloneModeLockTarget(config: Config): RepoLockTarget {\n const name = (config as RepositoryConfig).name;\n const configDir = config.__configFileDir;\n\n const hash = createHash(\"sha256\").update(path.resolve(config.worktreeDir)).digest(\"hex\").slice(0, 16);\n\n if (configDir) {\n return {\n dir: path.join(configDir, \".sync-worktrees-state\"),\n file: `${sanitizeNameForPath(name ?? \"repo\", \"clone-mode lock name\")}-${hash}.lock`,\n };\n }\n\n const stateBase =\n process.env.XDG_STATE_HOME && process.env.XDG_STATE_HOME.length > 0\n ? process.env.XDG_STATE_HOME\n : path.join(os.homedir(), \".cache\");\n const dir = path.join(stateBase, \"sync-worktrees\", \"locks\");\n return { dir, file: `${hash}.lock` };\n}\n", "import { getErrorMessage } from \"../utils/lfs-error\";\n\nimport type { GitService } from \"./git.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { Config } from \"../types\";\nimport type { RetryOptions } from \"../utils/retry\";\n\nexport interface SyncRetryContext {\n lfsSkipEnabled: boolean;\n}\n\nexport class SyncRetryPolicy {\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger,\n ) {}\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n createContext(): SyncRetryContext {\n return { lfsSkipEnabled: false };\n }\n\n createOptions(syncContext: SyncRetryContext): RetryOptions {\n return {\n maxAttempts: this.config.retry?.maxAttempts ?? 3,\n maxLfsRetries: this.config.retry?.maxLfsRetries ?? 2,\n initialDelayMs: this.config.retry?.initialDelayMs ?? 1000,\n maxDelayMs: this.config.retry?.maxDelayMs ?? 30000,\n backoffMultiplier: this.config.retry?.backoffMultiplier ?? 2,\n jitterMs: this.config.retry?.jitterMs ?? 0,\n onRetry: (error, attempt, context): void => {\n const errorMessage = getErrorMessage(error);\n this.logger.info(`\\n\u26A0\uFE0F Sync attempt ${attempt} failed: ${errorMessage}`);\n\n if (context?.isLfsError && !this.config.skipLfs) {\n this.logger.info(`\uD83D\uDD04 LFS error detected. Will retry with LFS skipped...`);\n } else {\n this.logger.info(`\uD83D\uDD04 Retrying synchronization...\\n`);\n }\n },\n lfsRetryHandler: (): void => {\n if (!this.config.skipLfs && !syncContext.lfsSkipEnabled) {\n this.logger.info(\"\u26A0\uFE0F Temporarily disabling LFS downloads for this sync...\");\n this.gitService.setLfsSkipEnabled(true);\n syncContext.lfsSkipEnabled = true;\n }\n },\n };\n }\n\n resetLfsSkipIfNeeded(syncContext: SyncRetryContext): void {\n if (syncContext.lfsSkipEnabled && !this.config.skipLfs) {\n this.gitService.setLfsSkipEnabled(false);\n }\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport pLimit from \"p-limit\";\n\nimport { DEFAULT_CONFIG, ERROR_MESSAGES, GIT_CONSTANTS, METADATA_CONSTANTS } from \"../constants\";\nimport { filterBranchesByName } from \"../utils/branch-filter\";\nimport { filterBranchesByAge, formatDuration } from \"../utils/date-filter\";\nimport { getErrorMessage, isLfsError } from \"../utils/lfs-error\";\n\nimport { PathResolutionService } from \"./path-resolution.service\";\nimport { createWorktreeSyncPlan } from \"./worktree-sync-planner\";\n\nimport type { GitService } from \"./git.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { ProgressEmitter } from \"./progress-emitter\";\nimport type { SyncOutcomeAccumulator } from \"./sync-outcome\";\nimport type { SyncRetryContext } from \"./sync-retry-policy\";\nimport type { WorktreeStatusDetails } from \"./worktree-status.service\";\nimport type { CreateAction, PruneAction, SparseAction, SyncPlan, UpdateAction } from \"./worktree-sync-planner\";\nimport type { Config } from \"../types\";\nimport type { PhaseTimer } from \"../utils/timing\";\n\nexport class WorktreeModeSyncRunner {\n private pathResolution = new PathResolutionService();\n\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger,\n private progressEmitter: ProgressEmitter,\n ) {}\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n async runSyncAttempt(\n phaseTimer: PhaseTimer,\n syncContext: SyncRetryContext,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n await this.gitService.pruneWorktrees();\n await this.fetchLatestRemoteData(phaseTimer, syncContext);\n\n const { remoteBranches, defaultBranch } = await this.resolveSyncBranches();\n\n await fs.mkdir(this.config.worktreeDir, { recursive: true });\n\n const worktrees = await this.gitService.getWorktrees();\n this.logger.info(`Found ${worktrees.length} existing Git worktrees.`);\n\n await this.cleanupOrphanedDirectories(worktrees);\n const syncPlan = createWorktreeSyncPlan(\n {\n remoteBranches,\n defaultBranch,\n existingWorktrees: worktrees,\n worktreeDir: this.config.worktreeDir,\n },\n {\n pathResolution: this.pathResolution,\n updateExistingWorktrees: this.config.updateExistingWorktrees !== false,\n sparseCheckout: this.config.sparseCheckout,\n },\n );\n\n await this.createNewWorktreesWithTiming(syncPlan, phaseTimer, outcome);\n await this.pruneOldWorktreesWithTiming(syncPlan.prune, phaseTimer, outcome);\n\n if (this.config.updateExistingWorktrees !== false) {\n await this.updateExistingWorktreesWithTiming(syncPlan.update, phaseTimer, outcome);\n }\n\n if (this.config.sparseCheckout) {\n await this.reapplySparseCheckout(syncPlan.sparse, outcome);\n }\n\n await this.finalizeSyncAttempt(phaseTimer);\n }\n\n private async reapplySparseCheckout(actions: SparseAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n const sparseConfig = this.config.sparseCheckout;\n if (!sparseConfig) return;\n\n this.logger.info(\"Step 5: Reconciling sparse-checkout patterns on existing worktrees...\");\n const sparseService = this.gitService.getSparseCheckoutService();\n const desired = sparseService.buildPatterns(sparseConfig);\n\n const limit = pLimit(this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\n\n await Promise.all(\n actions.map((action) =>\n limit(async () => {\n if (action.kind !== \"check-sparse\") return;\n\n try {\n try {\n await fs.access(action.path);\n } catch {\n return;\n }\n\n const current = await sparseService.readCurrent(action.path);\n if (current !== null && sparseService.patternsEqual(current, desired)) return;\n\n if (sparseService.isNarrowing(current, desired)) {\n const status = await this.gitService.getFullWorktreeStatus(action.path, false);\n if (!status.canRemove) {\n this.logger.warn(\n ` - Skipping sparse-checkout narrowing for '${action.branch}': ${status.reasons.join(\", \")}.`,\n );\n outcome.recordSkipped(\"sparse-checkout\", \"sparse_narrowing_unsafe\", {\n branch: action.branch,\n path: action.path,\n message: status.reasons.join(\", \"),\n });\n return;\n }\n }\n\n await sparseService.applyToWorktree(action.path, sparseConfig);\n await this.gitService.checkoutHead(action.path);\n this.logger.info(` - \u2705 Sparse-checkout updated for '${action.branch}'`);\n outcome.recordUpdated(action.branch, action.path, \"sparse_checkout\");\n } catch (error) {\n this.logger.warn(\n ` - \u26A0\uFE0F Failed to update sparse-checkout for '${action.branch}': ${getErrorMessage(error)}`,\n );\n outcome.recordFailed(\"sparse-checkout\", getErrorMessage(error), {\n reason: \"sparse_checkout_failed\",\n branch: action.branch,\n path: action.path,\n });\n }\n }),\n ),\n );\n }\n\n private async fetchLatestRemoteData(phaseTimer: PhaseTimer, syncContext: SyncRetryContext): Promise<void> {\n this.logger.info(\"Step 1: Fetching latest data from remote...\");\n phaseTimer.startPhase(\"Phase 1: Fetch\");\n this.progressEmitter.emit({ phase: \"fetch\", message: \"Fetching latest data from remote\" });\n\n try {\n await this.gitService.fetchAll();\n } catch (fetchError) {\n const errorMessage = getErrorMessage(fetchError);\n\n if (isLfsError(errorMessage) && !syncContext.lfsSkipEnabled && !this.config.skipLfs) {\n this.logger.info(\"\u26A0\uFE0F Fetch all failed due to LFS error. Attempting branch-by-branch fetch...\");\n this.logger.info(\"\u26A0\uFE0F Temporarily disabling LFS downloads for branch-by-branch fetch...\");\n this.gitService.setLfsSkipEnabled(true);\n syncContext.lfsSkipEnabled = true;\n await this.fetchBranchByBranch();\n } else {\n throw fetchError;\n }\n } finally {\n phaseTimer.endPhase();\n }\n }\n\n private async resolveSyncBranches(): Promise<{ remoteBranches: string[]; defaultBranch: string }> {\n const remoteBranches = this.config.branchMaxAge\n ? await this.getRemoteBranchesFilteredByActivity()\n : await this.getRemoteBranchesFilteredByName();\n const defaultBranch = this.gitService.getDefaultBranch();\n\n if (!remoteBranches.includes(defaultBranch)) {\n remoteBranches.push(defaultBranch);\n this.logger.info(`Ensuring default branch '${defaultBranch}' is retained.`);\n }\n\n return { remoteBranches, defaultBranch };\n }\n\n private async getRemoteBranchesFilteredByActivity(): Promise<string[]> {\n const branchesWithActivity = await this.gitService.getRemoteBranchesWithActivity();\n this.logger.info(`Found ${branchesWithActivity.length} remote branches.`);\n\n const branchNames = filterBranchesByName(\n branchesWithActivity.map((b) => b.branch),\n this.config.branchInclude,\n this.config.branchExclude,\n );\n\n if (branchNames.length < branchesWithActivity.length) {\n this.logger.info(\n `After branch name filtering: ${branchNames.length} of ${branchesWithActivity.length} branches.`,\n );\n }\n\n const branchNameSet = new Set(branchNames);\n const filteredByName = branchesWithActivity.filter((b) => branchNameSet.has(b.branch));\n const filteredBranches = filterBranchesByAge(filteredByName, this.config.branchMaxAge!);\n const remoteBranches = filteredBranches.map((b) => b.branch);\n\n this.logger.info(\n `After filtering by age (${formatDuration(this.config.branchMaxAge!)}): ${remoteBranches.length} branches.`,\n );\n\n if (filteredByName.length > remoteBranches.length) {\n const excludedCount = filteredByName.length - remoteBranches.length;\n this.logger.info(` - Excluded ${excludedCount} stale branches.`);\n }\n\n return remoteBranches;\n }\n\n private async getRemoteBranchesFilteredByName(): Promise<string[]> {\n const allBranches = await this.gitService.getRemoteBranches();\n this.logger.info(`Found ${allBranches.length} remote branches.`);\n\n const remoteBranches = filterBranchesByName(allBranches, this.config.branchInclude, this.config.branchExclude);\n\n if (remoteBranches.length < allBranches.length) {\n this.logger.info(`After branch name filtering: ${remoteBranches.length} of ${allBranches.length} branches.`);\n }\n\n return remoteBranches;\n }\n\n private async finalizeSyncAttempt(phaseTimer: PhaseTimer): Promise<void> {\n phaseTimer.startPhase(\"Phase 5: Cleanup\");\n this.progressEmitter.emit({ phase: \"cleanup\", message: \"Pruning worktree metadata\" });\n await this.gitService.pruneWorktrees();\n this.logger.info(\"Step 5: Pruned worktree metadata.\");\n phaseTimer.endPhase();\n }\n\n private async createNewWorktreesWithTiming(\n syncPlan: SyncPlan,\n phaseTimer: PhaseTimer,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n const maxConcurrent =\n this.config.parallelism?.maxWorktreeCreation ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_CREATION;\n phaseTimer.startPhase(\"Phase 2: Create\", maxConcurrent);\n this.progressEmitter.emit({ phase: \"create\", message: \"Creating worktrees for new branches\" });\n\n await this.createNewWorktrees(syncPlan.create, outcome);\n\n phaseTimer.setPhaseCount(\"Phase 2: Create\", syncPlan.create.length);\n phaseTimer.endPhase();\n }\n\n private async createNewWorktrees(actions: CreateAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n if (actions.length === 0) {\n this.logger.info(\"Step 2: No new branches to create worktrees for.\");\n return;\n }\n\n const plan: Array<{ branchName: string; worktreePath: string }> = [];\n for (const action of actions) {\n if (action.kind === \"skip-create\") {\n this.logger.error(\n ` \u274C Skipping '${action.branch}': sanitized worktree path '${action.path}' collides with existing branch '${action.conflictingBranch}'.`,\n );\n outcome.recordSkipped(\"branch\", \"path_collision\", {\n branch: action.branch,\n path: action.path,\n message: `Path collides with existing branch '${action.conflictingBranch}'`,\n });\n continue;\n }\n\n plan.push({ branchName: action.branch, worktreePath: action.path });\n }\n\n this.logger.info(`Step 2: Creating ${plan.length} new worktrees...`);\n\n // Worktree creation has concurrency=1 by default because Git's worktree.lock\n // can cause race conditions when multiple operations run simultaneously.\n // If concurrent operations try to create the same worktree, we gracefully handle\n // the \"already registered\" error by checking if the worktree actually exists.\n const maxConcurrent =\n this.config.parallelism?.maxWorktreeCreation ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_CREATION;\n const limit = pLimit(maxConcurrent);\n\n const results = await Promise.allSettled(\n plan.map(({ branchName, worktreePath }) =>\n limit(async () => {\n try {\n await this.gitService.addWorktree(branchName, worktreePath);\n this.logger.info(` \u2705 Created worktree for '${branchName}'`);\n outcome.recordCreated(branchName, worktreePath);\n } catch (error) {\n this.logger.error(` \u274C Failed to create worktree for '${branchName}':`, getErrorMessage(error));\n outcome.recordFailed(\"worktree\", getErrorMessage(error), {\n reason: \"create_failed\",\n branch: branchName,\n path: worktreePath,\n });\n throw error;\n }\n }),\n ),\n );\n\n const successCount = results.filter((r) => r.status === \"fulfilled\").length;\n this.logger.info(` Created ${successCount}/${plan.length} worktrees successfully`);\n }\n\n private async pruneOldWorktreesWithTiming(\n actions: PruneAction[],\n phaseTimer: PhaseTimer,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n const maxConcurrent = this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n phaseTimer.startPhase(\"Phase 3: Prune\", maxConcurrent);\n this.progressEmitter.emit({ phase: \"prune\", message: \"Pruning stale worktrees\" });\n\n await this.pruneOldWorktrees(actions, outcome);\n\n phaseTimer.setPhaseCount(\"Phase 3: Prune\", actions.length);\n phaseTimer.endPhase();\n }\n\n private async pruneOldWorktrees(actions: PruneAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n if (actions.length > 0) {\n this.logger.info(`Step 3: Checking ${actions.length} stale worktrees to prune...`);\n\n // Two-phase approach: First check status in parallel (read-only, safe),\n // then remove worktrees in parallel (mutation, needs lower concurrency)\n const maxConcurrent = this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n const limit = pLimit(maxConcurrent);\n\n const statusResults = await Promise.allSettled(\n actions.map(({ branch: branchName, path: worktreePath }) =>\n limit(async () => {\n const status = await this.gitService.getFullWorktreeStatus(worktreePath, this.config.debug);\n return { branchName, worktreePath, status };\n }).catch((error) => {\n throw Object.assign(error instanceof Error ? error : new Error(String(error)), { branchName });\n }),\n ),\n );\n\n const toRemove: Array<{ branchName: string; worktreePath: string }> = [];\n const toSkip: Array<{\n branchName: string;\n worktreePath: string;\n status: Awaited<ReturnType<GitService[\"getFullWorktreeStatus\"]>>;\n }> = [];\n\n for (const result of statusResults) {\n if (result.status === \"fulfilled\") {\n const { branchName, worktreePath, status } = result.value;\n if (status.canRemove) {\n toRemove.push({ branchName, worktreePath });\n } else {\n toSkip.push({ branchName, worktreePath, status });\n }\n } else {\n const branchName = (result.reason as Error & { branchName?: string })?.branchName ?? \"unknown\";\n this.logger.error(` - Error checking worktree '${branchName}':`, result.reason);\n this.logger.warn(` - \u26A0\uFE0F Skipping removal of '${branchName}' due to status check failure (conservative)`);\n outcome.recordSkipped(\"worktree\", \"prune_status_check_failed\", {\n branch: branchName,\n message: getErrorMessage(result.reason),\n });\n }\n }\n\n if (toRemove.length > 0) {\n const removeLimit = pLimit(\n this.config.parallelism?.maxWorktreeRemoval ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_REMOVAL,\n );\n\n const removeResults = await Promise.allSettled(\n toRemove.map(({ branchName, worktreePath }) =>\n removeLimit(async () => {\n try {\n // Re-validate status immediately before removal to close TOCTOU window.\n const recheck = await this.gitService.getFullWorktreeStatus(worktreePath, false);\n if (!recheck.canRemove) {\n this.logger.warn(\n ` \u26A0\uFE0F Skipping removal of '${branchName}' - status changed since initial check: ${recheck.reasons.join(\", \")}`,\n );\n outcome.recordSkipped(\"worktree\", \"prune_status_changed\", {\n branch: branchName,\n path: worktreePath,\n message: recheck.reasons.join(\", \"),\n });\n return;\n }\n await this.gitService.removeWorktree(worktreePath);\n this.logger.info(` \u2705 Removed worktree for '${branchName}'`);\n outcome.recordRemoved(branchName, worktreePath);\n } catch (error) {\n this.logger.error(` \u274C Failed to remove worktree for '${branchName}':`, getErrorMessage(error));\n outcome.recordFailed(\"worktree\", getErrorMessage(error), {\n reason: \"remove_failed\",\n branch: branchName,\n path: worktreePath,\n });\n throw error;\n }\n }),\n ),\n );\n\n const removedCount = removeResults.filter((r) => r.status === \"fulfilled\").length;\n this.logger.info(` Removed ${removedCount}/${toRemove.length} worktrees successfully`);\n }\n\n if (toSkip.length > 0) {\n this.logger.info(` Skipped ${toSkip.length} worktree(s) with local changes or unpushed commits`);\n }\n\n for (const { branchName, worktreePath, status } of toSkip) {\n outcome.recordSkipped(\"worktree\", \"unsafe_to_remove\", {\n branch: branchName,\n path: worktreePath,\n message: status.reasons.join(\", \"),\n });\n\n if (status.upstreamGone && status.hasUnpushedCommits) {\n this.logger.warn(` - \u26A0\uFE0F Cannot automatically remove '${branchName}' - upstream branch was deleted.`);\n this.logger.info(` Please review manually: cd ${worktreePath} && git log`);\n this.logger.info(\n ` If changes were squash-merged, you can safely remove with: git worktree remove ${worktreePath}`,\n );\n } else {\n this.logger.info(` - \u26A0\uFE0F Skipping removal of '${branchName}' due to: ${status.reasons.join(\", \")}.`);\n }\n\n if (this.config.debug && status.details) {\n this.logDebugDetails(branchName, status.details);\n }\n }\n } else {\n this.logger.info(\"Step 3: No stale worktrees to prune.\");\n }\n }\n\n private logDebugDetails(branchName: string, details: WorktreeStatusDetails): void {\n this.logger.info(`\\n \uD83D\uDD0D Debug details for '${branchName}':`);\n\n if (details.modifiedFiles > 0 && details.modifiedFilesList) {\n this.logger.info(` - Modified files (${details.modifiedFiles}):`);\n details.modifiedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.deletedFiles > 0 && details.deletedFilesList) {\n this.logger.info(` - Deleted files (${details.deletedFiles}):`);\n details.deletedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.renamedFiles > 0 && details.renamedFilesList) {\n this.logger.info(` - Renamed files (${details.renamedFiles}):`);\n details.renamedFilesList.forEach((file) => this.logger.info(` \u2022 ${file.from} \u2192 ${file.to}`));\n }\n if (details.createdFiles > 0 && details.createdFilesList) {\n this.logger.info(` - Created files (${details.createdFiles}):`);\n details.createdFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.conflictedFiles > 0 && details.conflictedFilesList) {\n this.logger.info(` - Conflicted files (${details.conflictedFiles}):`);\n details.conflictedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.untrackedFiles > 0 && details.untrackedFilesList) {\n this.logger.info(` - Untracked files (not ignored) (${details.untrackedFiles}):`);\n details.untrackedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.unpushedCommitCount !== undefined && details.unpushedCommitCount > 0) {\n this.logger.info(` - Unpushed commits: ${details.unpushedCommitCount}`);\n }\n if (details.stashCount !== undefined && details.stashCount > 0) {\n this.logger.info(` - Stashed changes: ${details.stashCount}`);\n }\n if (details.operationType) {\n this.logger.info(` - Operation in progress: ${details.operationType}`);\n }\n if (details.modifiedSubmodules && details.modifiedSubmodules.length > 0) {\n this.logger.info(` - Modified submodules (${details.modifiedSubmodules.length}):`);\n details.modifiedSubmodules.forEach((submodule) => this.logger.info(` \u2022 ${submodule}`));\n }\n\n this.logger.info(\"\");\n }\n\n private async fetchBranchByBranch(): Promise<void> {\n this.logger.info(\"Fetching branches individually to isolate LFS errors...\");\n\n const remoteBranches = await this.gitService.getRemoteBranches();\n this.logger.info(`Found ${remoteBranches.length} remote branches to fetch.`);\n\n const fetchLimit = pLimit(\n this.config.parallelism?.maxBranchFetches ?? DEFAULT_CONFIG.PARALLELISM.MAX_BRANCH_FETCHES,\n );\n const failedBranches: string[] = [];\n let successCount = 0;\n\n const results = await Promise.allSettled(\n remoteBranches.map((branch) =>\n fetchLimit(async () => {\n await this.gitService.fetchBranch(branch);\n return branch;\n }),\n ),\n );\n\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n if (result.status === \"fulfilled\") {\n successCount++;\n } else {\n const errorMessage = getErrorMessage(result.reason);\n this.logger.info(` \u26A0\uFE0F Failed to fetch branch '${remoteBranches[i]}': ${errorMessage}`);\n failedBranches.push(remoteBranches[i]);\n }\n }\n\n this.logger.info(`Branch-by-branch fetch completed: ${successCount}/${remoteBranches.length} successful`);\n\n if (failedBranches.length > 0) {\n this.logger.info(`\u26A0\uFE0F Failed to fetch ${failedBranches.length} branches due to errors.`);\n this.logger.info(` These branches will be skipped: ${failedBranches.join(\", \")}`);\n }\n }\n\n private async updateExistingWorktreesWithTiming(\n actions: UpdateAction[],\n phaseTimer: PhaseTimer,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n const maxConcurrent =\n this.config.parallelism?.maxWorktreeUpdates ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_UPDATES;\n phaseTimer.startPhase(\"Phase 4: Update\", maxConcurrent);\n this.progressEmitter.emit({ phase: \"update\", message: \"Updating existing worktrees\" });\n\n await this.updateExistingWorktrees(actions, outcome);\n\n phaseTimer.setPhaseCount(\"Phase 4: Update\", actions.length);\n phaseTimer.endPhase();\n }\n\n private async updateExistingWorktrees(actions: UpdateAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n this.logger.info(\"Step 4: Checking for worktrees that need updates...\");\n\n const divergedDir = path.join(this.config.worktreeDir, GIT_CONSTANTS.DIVERGED_DIR_NAME);\n try {\n const diverged = await fs.readdir(divergedDir);\n if (diverged.length > 0) {\n this.logger.info(\n `\uD83D\uDCE6 Note: ${diverged.length} diverged worktree(s) in ${path.relative(process.cwd(), divergedDir)}`,\n );\n }\n } catch {\n // No diverged directory, that's fine.\n }\n\n type UpdateCheckResult =\n | { action: \"update\" | \"diverged\"; worktree: { path: string; branch: string } }\n | {\n action: \"skip\" | \"noop\";\n worktree: { path: string; branch: string };\n reason: string;\n message?: string;\n };\n\n // Phase 4a: Check which worktrees need updates (parallel, read-only, high concurrency)\n const maxConcurrent = this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n const limit = pLimit(maxConcurrent);\n\n const checkResults = await Promise.allSettled(\n actions.map((action) =>\n limit(async (): Promise<UpdateCheckResult> => {\n const worktree = { path: action.path, branch: action.branch };\n\n try {\n await fs.access(worktree.path);\n } catch {\n return { action: \"skip\", worktree, reason: \"missing_worktree_path\" };\n }\n\n const hasOp = await this.gitService.hasOperationInProgress(worktree.path);\n if (hasOp) return { action: \"skip\", worktree, reason: \"operation_in_progress\" };\n\n const isClean = await this.gitService.checkWorktreeStatus(worktree.path);\n if (!isClean) return { action: \"skip\", worktree, reason: \"dirty_worktree\" };\n\n const canFastForward = await this.gitService.canFastForward(worktree.path, worktree.branch);\n if (!canFastForward) {\n const isAhead = await this.gitService.isLocalAheadOfRemote(worktree.path, worktree.branch);\n if (isAhead) {\n this.logger.info(`\u23ED\uFE0F Skipping '${worktree.branch}' - has unpushed commits`);\n return { action: \"skip\", worktree, reason: \"local_ahead\" };\n }\n return { action: \"diverged\", worktree };\n }\n\n const isBehind = await this.gitService.isWorktreeBehind(worktree.path);\n if (!isBehind) return { action: \"noop\", worktree, reason: \"already_up_to_date\" };\n\n const sparseCfg = this.config.sparseCheckout;\n if (sparseCfg && sparseCfg.skipUpdateWhenOutsideSparse !== false) {\n const sparseService = this.gitService.getSparseCheckoutService();\n if (sparseService.resolveMode(sparseCfg) === \"cone\") {\n const diff = await this.gitService.getChangedPathsInRange(\n worktree.path,\n \"HEAD\",\n `origin/${worktree.branch}`,\n );\n // null = git diff failed; force update rather than treat the failure as \"no sparse paths affected\".\n if (diff !== null && !sparseService.pathsTouchSparse(diff, sparseCfg)) {\n this.logger.info(`\u23ED\uFE0F Skipping '${worktree.branch}' - upstream changes outside sparse paths`);\n return { action: \"skip\", worktree, reason: \"outside_sparse_checkout\" };\n }\n }\n }\n\n return { action: \"update\", worktree };\n }),\n ),\n );\n\n const worktreesToUpdate: { path: string; branch: string }[] = [];\n const divergedWorktrees: { path: string; branch: string }[] = [];\n\n for (const result of checkResults) {\n if (result.status === \"fulfilled\" && result.value) {\n switch (result.value.action) {\n case \"update\":\n worktreesToUpdate.push(result.value.worktree);\n break;\n case \"diverged\":\n divergedWorktrees.push(result.value.worktree);\n break;\n case \"noop\":\n outcome.recordNoop(\"worktree\", result.value.reason, result.value.worktree);\n break;\n case \"skip\":\n outcome.recordSkipped(\"worktree\", result.value.reason, result.value.worktree);\n break;\n }\n } else if (result.status === \"rejected\") {\n // Probe-only failure (status / fast-forward / divergence check threw). The\n // actual update is gated on success here, so a probe error means we never\n // touched the worktree \u2014 treat it as a skip, not a hard failure.\n this.logger.error(` - Error checking worktree:`, result.reason);\n outcome.recordSkipped(\"worktree\", \"update_check_failed\", {\n message: getErrorMessage(result.reason),\n });\n }\n }\n\n // Phase 4b: Perform mutations (updates + diverged handling) with lower concurrency\n const updateLimit = pLimit(\n this.config.parallelism?.maxWorktreeUpdates ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_UPDATES,\n );\n\n const mutationTasks: Promise<{ type: \"update\" | \"diverged\"; branch: string }>[] = [];\n\n for (const worktree of worktreesToUpdate) {\n mutationTasks.push(\n updateLimit(async () => {\n try {\n this.logger.info(` - Updating worktree '${worktree.branch}'...`);\n await this.gitService.updateWorktree(worktree.path);\n this.logger.info(` \u2705 Successfully updated '${worktree.branch}'.`);\n outcome.recordUpdated(worktree.branch, worktree.path, \"fast_forward\");\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n if (ERROR_MESSAGES.FAST_FORWARD_FAILED.some((msg) => errorMessage.includes(msg))) {\n this.logger.info(\n ` \u26A0\uFE0F Branch '${worktree.branch}' cannot be fast-forwarded. Checking for divergence...`,\n );\n try {\n await this.handleDivergedBranch(worktree, outcome);\n } catch (divergedError) {\n this.logger.error(` \u274C Failed to handle diverged branch '${worktree.branch}':`, divergedError);\n outcome.recordFailed(\"worktree\", getErrorMessage(divergedError), {\n reason: \"diverged_recovery_failed\",\n branch: worktree.branch,\n path: worktree.path,\n });\n throw divergedError;\n }\n } else {\n this.logger.error(` \u274C Failed to update '${worktree.branch}':`, error);\n outcome.recordFailed(\"worktree\", errorMessage, {\n reason: \"update_failed\",\n branch: worktree.branch,\n path: worktree.path,\n });\n throw error;\n }\n }\n return { type: \"update\" as const, branch: worktree.branch };\n }),\n );\n }\n\n for (const worktree of divergedWorktrees) {\n mutationTasks.push(\n updateLimit(async () => {\n try {\n await this.handleDivergedBranch(worktree, outcome);\n } catch (error) {\n this.logger.error(` \u274C Failed to handle diverged branch '${worktree.branch}':`, error);\n outcome.recordFailed(\"worktree\", getErrorMessage(error), {\n reason: \"diverged_recovery_failed\",\n branch: worktree.branch,\n path: worktree.path,\n });\n throw error;\n }\n return { type: \"diverged\" as const, branch: worktree.branch };\n }),\n );\n }\n\n if (mutationTasks.length > 0) {\n if (worktreesToUpdate.length > 0) {\n this.logger.info(` - Found ${worktreesToUpdate.length} worktrees behind their upstream branches.`);\n }\n if (divergedWorktrees.length > 0) {\n this.logger.info(` - Found ${divergedWorktrees.length} diverged worktrees to handle.`);\n }\n\n const mutationResults = await Promise.allSettled(mutationTasks);\n\n const successCount = mutationResults.filter((r) => r.status === \"fulfilled\").length;\n this.logger.info(` Processed ${successCount}/${mutationTasks.length} worktrees successfully`);\n } else {\n this.logger.info(\" - All worktrees are up to date.\");\n }\n }\n\n private async cleanupOrphanedDirectories(worktrees: { path: string; branch: string }[]): Promise<void> {\n try {\n const worktreeRelativePaths = worktrees.map((w) => path.relative(this.config.worktreeDir, w.path));\n const allDirs = await fs.readdir(this.config.worktreeDir);\n\n // Filter out special directories like .diverged.\n const regularDirs = allDirs.filter((dir) => !dir.startsWith(\".\"));\n\n const orphanedDirs: string[] = [];\n for (const dir of regularDirs) {\n const isPartOfWorktree = worktreeRelativePaths.some((worktreePath) => {\n return worktreePath === dir || worktreePath.startsWith(dir + path.sep);\n });\n\n if (!isPartOfWorktree) {\n orphanedDirs.push(dir);\n }\n }\n\n if (orphanedDirs.length > 0) {\n this.logger.info(`Found ${orphanedDirs.length} orphaned directories: ${orphanedDirs.join(\", \")}`);\n\n for (const dir of orphanedDirs) {\n const dirPath = path.join(this.config.worktreeDir, dir);\n try {\n const stat = await fs.stat(dirPath);\n if (stat.isDirectory()) {\n await fs.rm(dirPath, { recursive: true, force: true });\n this.logger.info(` - Removed orphaned directory: ${dir}`);\n }\n } catch (error) {\n this.logger.error(` - Failed to remove orphaned directory ${dir}:`, error);\n }\n }\n }\n } catch (error) {\n this.logger.error(\"Error during orphaned directory cleanup:\", error);\n }\n }\n\n private async handleDivergedBranch(\n worktree: { path: string; branch: string },\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n this.logger.info(`\u26A0\uFE0F Branch '${worktree.branch}' has diverged from upstream. Analyzing...`);\n\n const treesIdentical = await this.gitService.compareTreeContent(worktree.path, worktree.branch);\n\n if (treesIdentical) {\n this.logger.info(`\u2705 Branch '${worktree.branch}' was rebased but files are identical. Resetting to upstream...`);\n await this.gitService.resetToUpstream(worktree.path, worktree.branch);\n this.logger.info(` Successfully updated '${worktree.branch}' to match upstream.`);\n outcome.recordUpdated(worktree.branch, worktree.path, \"reset_identical_tree\");\n } else {\n const hasLocalChanges = await this.hasLocalChangesSinceLastSync(worktree.path);\n\n if (!hasLocalChanges) {\n this.logger.info(\n `\u2705 Branch '${worktree.branch}' has diverged but you made no local changes. Resetting to upstream...`,\n );\n await this.gitService.resetToUpstream(worktree.path, worktree.branch);\n this.logger.info(` Successfully updated '${worktree.branch}' to match upstream.`);\n outcome.recordUpdated(worktree.branch, worktree.path, \"reset_no_local_changes\");\n } else {\n this.logger.info(`\uD83D\uDD12 Branch '${worktree.branch}' has diverged with local changes. Moving to diverged...`);\n\n const divergedPath = await this.divergeWorktree(worktree.path, worktree.branch);\n const relativePath = path.relative(process.cwd(), divergedPath);\n outcome.recordPreservedDiverged(worktree.branch, worktree.path, divergedPath);\n\n this.logger.info(` Moved to: ${relativePath}`);\n this.logger.info(` Your local changes are preserved. To review:`);\n this.logger.info(` cd ${relativePath}`);\n this.logger.info(` git diff origin/${worktree.branch}`);\n\n await this.gitService.removeWorktree(worktree.path);\n await this.gitService.addWorktree(worktree.branch, worktree.path);\n this.logger.info(` Created fresh worktree from upstream at: ${worktree.path}`);\n }\n }\n }\n\n private async hasLocalChangesSinceLastSync(worktreePath: string): Promise<boolean> {\n try {\n const metadata = await this.gitService.getWorktreeMetadata(worktreePath);\n if (!metadata || !metadata.lastSyncCommit) {\n return true;\n }\n\n const currentCommit = await this.gitService.getCurrentCommit(worktreePath);\n return currentCommit !== metadata.lastSyncCommit;\n } catch {\n return true;\n }\n }\n\n private async divergeWorktree(worktreePath: string, branchName: string): Promise<string> {\n const divergedBaseDir = path.join(this.config.worktreeDir, GIT_CONSTANTS.DIVERGED_DIR_NAME);\n\n const timestamp = new Date().toISOString().split(\"T\")[0];\n const uniqueSuffix = Date.now().toString(36) + Math.random().toString(36).substring(2, 7);\n const safeBranchName = this.pathResolution.sanitizeBranchName(branchName);\n const divergedName = `${timestamp}-${safeBranchName}-${uniqueSuffix}`;\n const divergedPath = path.join(divergedBaseDir, divergedName);\n\n await fs.mkdir(divergedBaseDir, { recursive: true });\n\n try {\n await fs.rename(worktreePath, divergedPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === ERROR_MESSAGES.EXDEV) {\n await fs.cp(worktreePath, divergedPath, { recursive: true });\n await fs.rm(worktreePath, { recursive: true, force: true });\n } else {\n throw err;\n }\n }\n\n const metadata = {\n originalBranch: branchName,\n divergedAt: new Date().toISOString(),\n reason: METADATA_CONSTANTS.DIVERGED_REASON,\n originalPath: worktreePath,\n localCommit: await this.gitService.getCurrentCommit(divergedPath),\n remoteCommit: await this.gitService.getRemoteCommit(`origin/${branchName}`),\n instruction: `To preserve your changes:\n 1. Review: git diff origin/${branchName}\n 2. Keep changes: git push --force-with-lease origin ${branchName}\n 3. Discard changes: rm -rf this directory\n\n Original worktree location: ${worktreePath}`,\n };\n\n await fs.writeFile(\n path.join(divergedPath, METADATA_CONSTANTS.DIVERGED_INFO_FILE),\n JSON.stringify(metadata, null, 2),\n );\n\n return divergedPath;\n }\n}\n", "export function parseDuration(durationStr: string): number | null {\n const match = durationStr.match(/^(\\d+)([hdwmy])$/);\n if (!match) {\n return null;\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n const multipliers: Record<string, number> = {\n h: 60 * 60 * 1000, // hours\n d: 24 * 60 * 60 * 1000, // days\n w: 7 * 24 * 60 * 60 * 1000, // weeks\n m: 30 * 24 * 60 * 60 * 1000, // months (approximate)\n y: 365 * 24 * 60 * 60 * 1000, // years (approximate)\n };\n\n return value * multipliers[unit];\n}\n\nexport function filterBranchesByAge(\n branches: { branch: string; lastActivity: Date }[],\n maxAge: string,\n): { branch: string; lastActivity: Date }[] {\n const maxAgeMs = parseDuration(maxAge);\n if (maxAgeMs === null) {\n console.warn(`Invalid duration format: ${maxAge}. Using all branches.`);\n return branches;\n }\n\n const cutoffDate = new Date(Date.now() - maxAgeMs);\n\n return branches.filter(({ lastActivity }) => lastActivity >= cutoffDate);\n}\n\nexport function formatDuration(durationStr: string): string {\n const match = durationStr.match(/^(\\d+)([hdwmy])$/);\n if (!match) {\n return durationStr;\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n const unitNames: Record<string, string> = {\n h: value === 1 ? \"hour\" : \"hours\",\n d: value === 1 ? \"day\" : \"days\",\n w: value === 1 ? \"week\" : \"weeks\",\n m: value === 1 ? \"month\" : \"months\",\n y: value === 1 ? \"year\" : \"years\",\n };\n\n return `${value} ${unitNames[unit]}`;\n}\n", "import { createHash } from \"crypto\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\nimport { isCaseInsensitiveFs } from \"../utils/path-compare\";\n\nconst BRANCH_STEM_MAX = 80;\nconst BRANCH_HASH_LEN = 8;\n\nexport class PathResolutionService {\n sanitizeBranchName(branchName: string): string {\n const stem = branchName\n .replace(/\\//g, \"-\")\n .replace(/[^a-zA-Z0-9_-]/g, \"_\")\n .slice(0, BRANCH_STEM_MAX);\n const hash = createHash(\"sha256\").update(branchName).digest(\"hex\").slice(0, BRANCH_HASH_LEN);\n return `${stem}-${hash}`;\n }\n\n getBranchWorktreePath(worktreeDir: string, branchName: string): string {\n return path.join(worktreeDir, this.sanitizeBranchName(branchName));\n }\n\n private resolveRealPath(inputPath: string): string {\n const absolute = path.resolve(inputPath);\n const missing: string[] = [];\n let current = absolute;\n\n while (!fs.existsSync(current)) {\n const parent = path.dirname(current);\n if (parent === current) {\n return absolute;\n }\n missing.unshift(path.basename(current));\n current = parent;\n }\n\n try {\n return path.join(fs.realpathSync(current), ...missing);\n } catch {\n return absolute;\n }\n }\n\n private isResolvedPathInsideBase(resolved: string, resolvedBase: string): boolean {\n const fold = (p: string): string => (isCaseInsensitiveFs() ? p.toLowerCase() : p);\n const a = fold(resolved);\n const b = fold(resolvedBase);\n if (a === b) return true;\n return a.length > b.length && a.charAt(b.length) === path.sep && a.startsWith(b);\n }\n\n normalizeWorktreePath(worktreePath: string, worktreeBaseDir: string): string {\n const resolved = this.resolveRealPath(worktreePath);\n const resolvedBase = this.resolveRealPath(worktreeBaseDir);\n if (!this.isResolvedPathInsideBase(resolved, resolvedBase)) {\n throw new Error(`Worktree path '${worktreePath}' is outside base directory '${worktreeBaseDir}'`);\n }\n return path.relative(resolvedBase, resolved);\n }\n\n isPathInsideBaseDir(targetPath: string, baseDir: string): boolean {\n const resolved = this.resolveRealPath(targetPath);\n const resolvedBase = this.resolveRealPath(baseDir);\n return this.isResolvedPathInsideBase(resolved, resolvedBase);\n }\n\n extractBranchFromWorktreePath(worktreePath: string, worktreeBaseDir: string): string {\n return this.normalizeWorktreePath(worktreePath, worktreeBaseDir);\n }\n}\n", "import * as path from \"path\";\n\nimport { PathResolutionService } from \"./path-resolution.service\";\n\nimport type { SparseCheckoutConfig } from \"../types\";\n\nexport interface WorktreeInventory {\n remoteBranches: string[];\n defaultBranch: string;\n existingWorktrees: WorktreeEntry[];\n worktreeDir: string;\n}\n\nexport interface WorktreeEntry {\n path: string;\n branch: string;\n}\n\nexport type CreateAction =\n | { kind: \"create\"; branch: string; path: string }\n | { kind: \"skip-create\"; branch: string; path: string; reason: \"path-collision\"; conflictingBranch: string };\n\nexport type PruneAction = { kind: \"check-prune\"; branch: string; path: string };\n\nexport type UpdateAction = { kind: \"update-candidate\"; branch: string; path: string };\n\nexport type SparseAction =\n | { kind: \"check-sparse\"; branch: string; path: string }\n | { kind: \"skip-sparse\"; branch: string; path: string; reason: \"not-configured\" };\n\nexport type SyncAction = CreateAction | PruneAction | UpdateAction | SparseAction;\n\nexport interface SyncPlan {\n create: CreateAction[];\n prune: PruneAction[];\n update: UpdateAction[];\n sparse: SparseAction[];\n warnings: string[];\n}\n\nexport interface SyncPlanOptions {\n pathResolution?: PathResolutionService;\n updateExistingWorktrees?: boolean;\n sparseCheckout?: SparseCheckoutConfig;\n}\n\nexport function createWorktreeSyncPlan(inventory: WorktreeInventory, options: SyncPlanOptions = {}): SyncPlan {\n return {\n create: planCreateActions(inventory, options),\n prune: planPruneActions(inventory),\n update: options.updateExistingWorktrees === false ? [] : planUpdateActions(inventory),\n sparse: planSparseActions(inventory, options.sparseCheckout),\n warnings: [],\n };\n}\n\nexport function planCreateActions(inventory: WorktreeInventory, options: SyncPlanOptions = {}): CreateAction[] {\n const pathResolution = options.pathResolution ?? new PathResolutionService();\n const existingBranches = new Set(inventory.existingWorktrees.map((w) => w.branch));\n const newBranches = inventory.remoteBranches.filter(\n (branch) => !existingBranches.has(branch) && branch !== inventory.defaultBranch,\n );\n\n const reservedPaths = new Map<string, string>();\n for (const worktree of inventory.existingWorktrees) {\n reservedPaths.set(path.resolve(worktree.path), worktree.branch);\n }\n\n const actions: CreateAction[] = [];\n for (const branch of newBranches) {\n const worktreePath = pathResolution.getBranchWorktreePath(inventory.worktreeDir, branch);\n const resolved = path.resolve(worktreePath);\n const conflictingBranch = reservedPaths.get(resolved);\n\n if (conflictingBranch && conflictingBranch !== branch) {\n actions.push({\n kind: \"skip-create\",\n branch,\n path: worktreePath,\n reason: \"path-collision\",\n conflictingBranch,\n });\n continue;\n }\n\n reservedPaths.set(resolved, branch);\n actions.push({ kind: \"create\", branch, path: worktreePath });\n }\n\n return actions;\n}\n\nexport function planPruneActions(inventory: WorktreeInventory): PruneAction[] {\n const remoteBranches = new Set(inventory.remoteBranches);\n return inventory.existingWorktrees\n .filter((worktree) => !remoteBranches.has(worktree.branch))\n .map((worktree) => ({ kind: \"check-prune\", branch: worktree.branch, path: worktree.path }));\n}\n\nexport function planUpdateActions(inventory: WorktreeInventory): UpdateAction[] {\n const remoteBranches = new Set(inventory.remoteBranches);\n return inventory.existingWorktrees\n .filter((worktree) => remoteBranches.has(worktree.branch))\n .map((worktree) => ({ kind: \"update-candidate\", branch: worktree.branch, path: worktree.path }));\n}\n\nexport function planSparseActions(inventory: WorktreeInventory, sparseCheckout?: SparseCheckoutConfig): SparseAction[] {\n if (!sparseCheckout) {\n return [];\n }\n\n return inventory.existingWorktrees.map((worktree) => ({\n kind: \"check-sparse\",\n branch: worktree.branch,\n path: worktree.path,\n }));\n}\n", "import { getErrorMessage } from \"../utils/lfs-error\";\nimport { REPOSITORY_MODES, resolveMode } from \"../utils/repo-mode\";\nimport { retry } from \"../utils/retry\";\nimport { PhaseTimer, Timer, formatTimingTable } from \"../utils/timing\";\n\nimport { type CloneSkipReason, CloneSyncService } from \"./clone-sync.service\";\nimport { GitService } from \"./git.service\";\nimport { Logger } from \"./logger.service\";\nimport { ProgressEmitter } from \"./progress-emitter\";\nimport { RepoOperationLock } from \"./repo-operation-lock\";\nimport { SyncOutcomeAccumulator } from \"./sync-outcome\";\nimport { SyncRetryPolicy } from \"./sync-retry-policy\";\nimport { WorktreeModeSyncRunner } from \"./worktree-mode-sync-runner\";\n\nimport type { ProgressEvent, ProgressListener } from \"./progress-emitter\";\nimport type { RepoLockRelease } from \"./repo-operation-lock\";\nimport type { Config, SyncOutcome, SyncResult } from \"../types\";\nimport type { LfsErrorContext } from \"../utils/retry\";\n\nexport type { ProgressEvent, ProgressListener } from \"./progress-emitter\";\nexport type { SyncOutcome, SyncOutcomeAction, SyncOutcomeCounts, SyncResult } from \"../types\";\n\nexport type ExclusiveRepoOperationResult<T> =\n | { started: true; value: T }\n | { started: false; reason: \"in_progress\" | \"locked\" };\n\nexport class WorktreeSyncService {\n private gitService: GitService;\n private cloneSyncService: CloneSyncService | null = null;\n private logger: Logger;\n private syncInProgress: boolean = false;\n private progressEmitter = new ProgressEmitter();\n private repoOperationLock: RepoOperationLock;\n private retryPolicy: SyncRetryPolicy;\n private worktreeModeSyncRunner: WorktreeModeSyncRunner;\n private skipsAccumulator: CloneSkipReason[] = [];\n private lastOutcome: SyncOutcome | null = null;\n\n constructor(public readonly config: Config) {\n this.logger = config.logger ?? Logger.createDefault(undefined, config.debug);\n this.gitService = new GitService(config, this.logger);\n this.repoOperationLock = new RepoOperationLock(config, this.gitService, this.logger);\n this.retryPolicy = new SyncRetryPolicy(config, this.gitService, this.logger);\n this.worktreeModeSyncRunner = new WorktreeModeSyncRunner(\n config,\n this.gitService,\n this.logger,\n this.progressEmitter,\n );\n if (resolveMode(config) === REPOSITORY_MODES.CLONE) {\n this.cloneSyncService = new CloneSyncService(config, this.gitService, this.logger, {\n progressEmitter: (event): void => this.emitProgress(event),\n onSkip: (reason): void => {\n this.skipsAccumulator.push(reason);\n },\n });\n }\n }\n\n public getRecordedSkips(): readonly CloneSkipReason[] {\n return [...this.skipsAccumulator];\n }\n\n public clearRecordedSkips(): void {\n this.skipsAccumulator = [];\n }\n\n public clearPendingInitSkip(): void {\n this.cloneSyncService?.clearPendingInitSkip();\n }\n\n public getLastOutcome(): SyncOutcome | null {\n return this.lastOutcome;\n }\n\n isCloneMode(): boolean {\n return this.cloneSyncService !== null;\n }\n\n async getWorktrees(): Promise<Array<{ path: string; branch: string }>> {\n if (this.cloneSyncService) {\n return this.cloneSyncService.getWorktrees();\n }\n return this.gitService.getWorktrees();\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized()) return;\n const result = await this.runExclusiveRepoOperation(() => this.initializeUnlocked());\n if (!result.started) {\n const reason = result.reason === \"in_progress\" ? \"operation in progress\" : \"another process holds the lock\";\n this.logger.warn(`\u26A0\uFE0F Initialize skipped: ${reason}`);\n }\n }\n\n async initializeUnlocked(outcome?: SyncOutcomeAccumulator): Promise<void> {\n this.emitProgress({ phase: \"initialize\", message: \"Initializing repository\" });\n if (this.cloneSyncService) {\n await this.cloneSyncService.initialize(outcome);\n } else {\n await this.gitService.initialize();\n }\n this.emitProgress({ phase: \"initialize\", message: \"Repository initialized\" });\n }\n\n isInitialized(): boolean {\n if (this.cloneSyncService) {\n return this.cloneSyncService.isInitialized();\n }\n return this.gitService.isInitialized();\n }\n\n isSyncInProgress(): boolean {\n return this.syncInProgress;\n }\n\n getGitService(): GitService {\n return this.gitService;\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n this.gitService.updateLogger(logger);\n this.cloneSyncService?.updateLogger(logger);\n this.retryPolicy.updateLogger(logger);\n this.worktreeModeSyncRunner.updateLogger(logger);\n this.repoOperationLock.updateLogger(logger);\n }\n\n onProgress(listener: ProgressListener): () => void {\n return this.progressEmitter.onProgress(listener);\n }\n\n async runExclusiveRepoOperation<T>(operation: () => Promise<T>): Promise<ExclusiveRepoOperationResult<T>> {\n if (this.syncInProgress) {\n this.logger.warn(\"\u26A0\uFE0F Another repository operation is already in progress, skipping...\");\n return { started: false, reason: \"in_progress\" };\n }\n // Claim the in-process slot synchronously so a second caller arriving while\n // we await acquire() sees \"in_progress\" instead of also passing the check.\n this.syncInProgress = true;\n\n let release: RepoLockRelease | null;\n try {\n release = await this.repoOperationLock.acquire();\n } catch (error) {\n this.syncInProgress = false;\n throw error;\n }\n\n if (release === null) {\n this.syncInProgress = false;\n this.logger.warn(\"\u26A0\uFE0F Another process holds the sync lock for this repo, skipping...\");\n return { started: false, reason: \"locked\" };\n }\n\n try {\n return { started: true, value: await operation() };\n } finally {\n // Release the file lock first; only then clear the in-process flag so\n // another caller arriving in this window gets \"in_progress\" rather than\n // ELOCKED from proper-lockfile.\n try {\n await release();\n } catch (releaseError) {\n this.logger.warn(`Failed to release sync lock: ${getErrorMessage(releaseError)}`);\n }\n this.syncInProgress = false;\n }\n }\n\n private emitProgress(event: ProgressEvent): void {\n this.progressEmitter.emit(event);\n }\n\n async sync(): Promise<SyncResult> {\n const result = await this.runExclusiveRepoOperation<SyncOutcome>(async () => {\n const totalTimer = new Timer();\n const phaseTimer = new PhaseTimer();\n const outcome = new SyncOutcomeAccumulator({\n mode: this.cloneSyncService ? \"clone\" : \"worktree\",\n repoName: (this.config as { name?: string }).name,\n });\n const syncContext = this.retryPolicy.createContext();\n const retryOptions = this.retryPolicy.createOptions(syncContext);\n let durationMs: number | undefined;\n\n try {\n if (!this.isInitialized()) {\n await this.initializeUnlocked(outcome);\n }\n\n this.logger.info(`[${new Date().toISOString()}] Starting worktree synchronization...`);\n\n const retryOutcomeBaseline = outcome.snapshot();\n const retryOptionsWithOutcomeReset = {\n ...retryOptions,\n onRetry: (error: unknown, attempt: number, context?: LfsErrorContext): void => {\n outcome.restore(retryOutcomeBaseline);\n retryOptions.onRetry?.(error, attempt, context);\n },\n };\n\n const cloneSync = this.cloneSyncService;\n if (cloneSync) {\n await retry(() => cloneSync.runSyncAttempt(outcome), retryOptionsWithOutcomeReset);\n } else {\n await retry(\n () => this.worktreeModeSyncRunner.runSyncAttempt(phaseTimer, syncContext, outcome),\n retryOptionsWithOutcomeReset,\n );\n }\n } catch (error) {\n if (outcome.getCounts().failed === 0) {\n outcome.recordFailed(\"repo\", getErrorMessage(error), { reason: \"sync_failed\" });\n }\n this.logger.error(\"\\n\u274C Error during worktree synchronization after all retry attempts:\", error);\n throw error;\n } finally {\n this.retryPolicy.resetLfsSkipIfNeeded(syncContext);\n this.logger.info(`[${new Date().toISOString()}] Synchronization finished.\\n`);\n durationMs = totalTimer.stop();\n this.lastOutcome = outcome.toOutcome(durationMs);\n\n if (this.config.debug) {\n const phaseResults = phaseTimer.getResults();\n const repoName = (this.config as { name?: string }).name;\n this.logger.table(formatTimingTable(durationMs, phaseResults, repoName));\n }\n }\n\n return this.lastOutcome ?? outcome.toOutcome(durationMs);\n });\n\n return result.started ? { started: true, outcome: result.value } : result;\n }\n}\n", "import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n\nimport { buildUnsupportedContext } from \"./context\";\nimport {\n handleCreateWorktree,\n handleDetectContext,\n handleGetWorktreeStatus,\n handleInitialize,\n handleListWorktrees,\n handleLoadConfig,\n handleRemoveWorktree,\n handleSetCurrentRepository,\n handleSync,\n handleUpdateWorktree,\n} from \"./handlers\";\nimport { wrapHandler } from \"./utils\";\n\nimport type { DiscoveredRepoContext, RepositoryContext } from \"./context\";\n\nconst REPO_NAME_DESCRIBE =\n \"Repo name from loaded config. Omit to use current (set via set_current_repository) or the only loaded repo.\";\n\nconst PATH_DESCRIBE_SUFFIX = \"Absolute preferred; relative resolves from server CWD.\";\n\nconst SERVER_INSTRUCTIONS =\n \"Call `detect_context` for the project map and live worktree state; `configuredRepositories` in its response is the server-wide loaded-config inventory. Use `set_current_repository` to switch repos. Auto-loads sync-worktrees.config.{js,mjs,cjs,ts} via walk-up.\";\n\nexport interface ServerSnapshot {\n discovered: DiscoveredRepoContext | null;\n configuredRepoCount?: number;\n}\n\nexport function buildInstructions(snapshot?: ServerSnapshot): string {\n const d = snapshot?.discovered;\n\n if (!d || !d.isWorktree || d.kind !== \"managed\") {\n return SERVER_INSTRUCTIONS;\n }\n\n const fields: string[] = [];\n if (d.repoName) fields.push(`workspace=${d.repoName}`);\n if (d.currentWorktreePath) fields.push(`path=${d.currentWorktreePath}`);\n if (d.configPath) fields.push(`config=${d.configPath}`);\n if (typeof snapshot?.configuredRepoCount === \"number\") {\n fields.push(`configuredRepos=${snapshot.configuredRepoCount}`);\n }\n fields.push(`worktrees=${d.allWorktrees.length}`);\n\n return `${SERVER_INSTRUCTIONS} Connect-time: ${fields.join(\" \")}.`;\n}\n\nexport function createServer(context: RepositoryContext, snapshot?: ServerSnapshot): McpServer {\n const server = new McpServer(\n {\n name: \"sync-worktrees\",\n version: \"1.0.0\",\n },\n {\n instructions: buildInstructions(snapshot),\n },\n );\n\n server.registerResource(\n \"workspace\",\n \"sync-worktrees://workspace\",\n {\n title: \"Workspace context\",\n description:\n \"Workspace context: isWorktree, kind, currentWorktreePath, currentBranch, allWorktrees, siblingRepositories, configPath, capabilities {available,reason}, configuredRepositories (server-wide loaded-config inventory). {isWorktree:false} when outside any workspace.\",\n mimeType: \"application/json\",\n },\n async (uri) => {\n let payload: unknown;\n try {\n const discovered = await context.detectFromPath(process.cwd());\n const configuredRepositories = await context.getConfiguredRepositorySummaries();\n payload = { ...discovered, configuredRepositories };\n } catch (err) {\n payload = buildUnsupportedContext(process.cwd(), err instanceof Error ? err.message : String(err));\n }\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: \"application/json\",\n text: JSON.stringify(payload),\n },\n ],\n };\n },\n );\n\n server.registerTool(\n \"detect_context\",\n {\n description:\n \"Detect sync-worktrees structure from path (default: CWD). Reads .git, resolves bare repo, walks up to auto-load sync-worktrees.config.{js,mjs,cjs,ts}. Returns: configuredRepositories (server-wide loaded-config inventory; independent of params.path), bareRepoPath, allWorktrees, siblingRepositories, currentWorktreePath, configPath, capabilities {available,reason}, notes. Lean configuredRepositories entries are mode-discriminated: clone \u2192 {name, mode:'clone', checkoutPath, isCurrent}; worktree \u2192 {name, mode:'worktree', worktreeDir, isCurrent}. detailed=true adds repoUrl, branch?, sparseCheckout?, localReady, plus bareRepoDir for worktree mode. Use at session start or to bootstrap from unknown checkout.\",\n inputSchema: {\n path: z.string().optional().describe(\"Directory to inspect. Default: server CWD.\"),\n detailed: z\n .boolean()\n .optional()\n .default(false)\n .describe(\"Expand configuredRepositories with repoUrl, branch, sparseCheckout, localReady, bareRepoDir.\"),\n includeAllWorktrees: z\n .boolean()\n .optional()\n .describe(\"Include allWorktreesByRepo + allWorktreeErrorsByRepo for each configured repo. Default: false.\"),\n includeStatus: z\n .boolean()\n .optional()\n .describe(\n \"Enrich entries with label, divergence, staleHint. Adds 1 git status + rev-list per worktree. Default: false.\",\n ),\n },\n annotations: {\n title: \"Detect sync-worktrees context\",\n readOnlyHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n wrapHandler((params, extra) => handleDetectContext(context, params, extra)),\n );\n\n server.registerTool(\n \"list_worktrees\",\n {\n description:\n \"List worktrees with status. No repoName + config loaded = all configured repos grouped by repoName. With repoName = single repo. Entries: {path, branch, isCurrent, label (clean|dirty|stale|current|unknown), status, divergence, safeToRemove, lastSyncAt, sizeBytes}.\",\n inputSchema: {\n repoName: z.string().optional().describe(\"Repo name. Omit + config loaded = list all configured repos.\"),\n includeSize: z\n .boolean()\n .optional()\n .describe(\n \"Compute on-disk size per worktree (bytes). Slow on large worktrees. Default: false (sizeBytes=null).\",\n ),\n },\n annotations: {\n title: \"List worktrees with status\",\n readOnlyHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n wrapHandler((params, extra) => handleListWorktrees(context, params, extra)),\n );\n\n server.registerTool(\n \"get_worktree_status\",\n {\n description:\n \"Detailed status for one worktree: dirty files, unpushed commits, stashes, upstream gone, ops in progress. Returns: status + divergence {ahead,behind} + resolved path.\",\n inputSchema: {\n path: z.string().describe(`Worktree path. ${PATH_DESCRIBE_SUFFIX}`),\n repoName: z.string().optional().describe(REPO_NAME_DESCRIBE),\n includeDetails: z\n .boolean()\n .optional()\n .describe(\"Include file-level lists (modified, untracked, staged). Default: false (counts only).\"),\n },\n annotations: {\n title: \"Get worktree status\",\n readOnlyHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n wrapHandler((params, extra) => handleGetWorktreeStatus(context, params, extra)),\n );\n\n server.registerTool(\n \"create_worktree\",\n {\n description:\n \"Create worktree for a branch. Existing branch (local/remote) = checkout. New branch = create from baseBranch + push to origin (default). baseBranch required only for new branches \u2014 pass defensively if unsure. push=false opts out. Preconditions: repo initialized (auto-runs). Returns: {success, branchName, worktreePath, created, pushed}.\",\n inputSchema: {\n branchName: z.string().describe(\"Branch name. Slashes/special chars sanitized for dir name.\"),\n baseBranch: z\n .string()\n .optional()\n .describe(\n \"Base for new branch. Required if branchName doesn't exist locally or remotely; ignored otherwise.\",\n ),\n push: z.boolean().optional().describe(\"Push new branch to origin. Default: true. Ignored if branch existed.\"),\n repoName: z.string().optional().describe(REPO_NAME_DESCRIBE),\n },\n annotations: {\n title: \"Create worktree\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n wrapHandler((params, extra) => handleCreateWorktree(context, params, extra)),\n );\n\n server.registerTool(\n \"remove_worktree\",\n {\n description:\n \"Remove worktree. Safety checks reject if dirty, unpushed commits, stashes, or op in progress (merge/rebase/cherry-pick/revert/bisect). force=true: `git worktree remove --force` DELETES uncommitted/untracked files in dir; branch ref + stashes + remote preserved. Returns: {success, removedPath}.\",\n inputSchema: {\n path: z.string().describe(`Worktree path to remove. ${PATH_DESCRIBE_SUFFIX}`),\n force: z\n .boolean()\n .optional()\n .describe(\"Skip safety checks; deletes uncommitted/untracked files. Branch ref preserved. Default: false.\"),\n repoName: z.string().optional().describe(REPO_NAME_DESCRIBE),\n },\n annotations: {\n title: \"Remove worktree\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n wrapHandler((params, extra) => handleRemoveWorktree(context, params, extra)),\n );\n\n server.registerTool(\n \"sync\",\n {\n description:\n \"Repo-wide sync: fetch, create worktrees for new remote branches, remove pruned (clean only), fast-forward existing. Emits progress. Single worktree? Use update_worktree. Single create? Use create_worktree. Preconditions: config loaded + repo initialized (auto-runs). Returns: {success, duration, skips}.\",\n inputSchema: {\n repoName: z.string().optional().describe(REPO_NAME_DESCRIBE),\n },\n annotations: {\n title: \"Sync repository worktrees\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n wrapHandler((params, extra) => handleSync(context, params, extra)),\n );\n\n server.registerTool(\n \"update_worktree\",\n {\n description:\n \"Fast-forward one worktree to upstream. No merge, no rebase, aborts if not fast-forwardable. Whole repo? Use sync.\",\n inputSchema: {\n path: z.string().describe(`Worktree path to fast-forward. ${PATH_DESCRIBE_SUFFIX}`),\n repoName: z.string().optional().describe(REPO_NAME_DESCRIBE),\n },\n annotations: {\n title: \"Fast-forward one worktree\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n },\n wrapHandler((params, extra) => handleUpdateWorktree(context, params, extra)),\n );\n\n server.registerTool(\n \"initialize\",\n {\n description:\n \"Initialize repo: clone as bare if missing, create main worktree. Idempotent. Emits progress. Preconditions: config loaded. Returns: {success, defaultBranch, worktreeDir}.\",\n inputSchema: {\n repoName: z.string().optional().describe(REPO_NAME_DESCRIBE),\n },\n annotations: {\n title: \"Initialize repository\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n },\n wrapHandler((params, extra) => handleInitialize(context, params, extra)),\n );\n\n server.registerTool(\n \"load_config\",\n {\n description:\n \"Load/reload sync-worktrees JS config into session. Replaces previously loaded repos. Call before sync/initialize/create_worktree in config-driven workflow. Returns: {configPath, currentRepository, repositories: [{name, repoUrl, worktreeDir, source}]}.\",\n inputSchema: {\n configPath: z\n .string()\n .optional()\n .describe(\"Config file path. Falls back to SYNC_WORKTREES_CONFIG env var. Errors if neither set.\"),\n },\n annotations: {\n title: \"Load sync-worktrees config\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n wrapHandler((params, extra) => handleLoadConfig(context, params, extra)),\n );\n\n server.registerTool(\n \"set_current_repository\",\n {\n description:\n \"Set current repo for tool calls that omit repoName. Session-scoped. Preconditions: load_config called.\",\n inputSchema: {\n repoName: z.string().describe(\"Repo name from loaded config repositories[].name.\"),\n },\n annotations: {\n title: \"Set current repository\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n wrapHandler((params, extra) => handleSetCurrentRepository(context, params, extra)),\n );\n\n return server;\n}\n", "import * as path from \"path\";\n\nimport pLimit from \"p-limit\";\n\nimport { DEFAULT_CONFIG } from \"../constants\";\nimport { PathResolutionService } from \"../services/path-resolution.service\";\nimport { createEmptySyncOutcome } from \"../services/sync-outcome\";\nimport { WorktreeStatusService } from \"../services/worktree-status.service\";\nimport { formatCloneSkipReason } from \"../utils/clone-skip-format\";\nimport { calculateDirectorySize } from \"../utils/disk-space\";\nimport { isValidGitBranchName } from \"../utils/git-validation\";\nimport { pathsEqual } from \"../utils/path-compare\";\n\nimport { CapabilityUnavailableError, SyncInProgressError, formatToolResponse } from \"./utils\";\nimport { deriveLabel, deriveSafeToRemove, getDivergence } from \"./worktree-summary\";\n\nimport type { Capabilities, DiscoveredRepoContext, DiscoveredWorktree, RepositoryContext } from \"./context\";\nimport type { HandlerExtra } from \"./utils\";\nimport type { WorktreeLabel } from \"./worktree-summary\";\nimport type { ProgressEvent } from \"../services/worktree-sync.service\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\n\ntype CapabilityKey = keyof Capabilities;\ntype RepoScopedParams = { repoName?: string };\ntype WorktreePathParams = RepoScopedParams & { path: string };\ntype RepoService = Awaited<ReturnType<RepositoryContext[\"getService\"]>>;\ntype RepoGitService = ReturnType<RepoService[\"getGitService\"]>;\ntype Limit = ReturnType<typeof pLimit>;\ntype ListedWorktree = {\n path: string;\n branch: string;\n isCurrent: boolean;\n label: WorktreeLabel;\n status: Awaited<ReturnType<RepoGitService[\"getFullWorktreeStatus\"]>> | null;\n divergence: Awaited<ReturnType<typeof getDivergence>>;\n safeToRemove: ReturnType<typeof deriveSafeToRemove>;\n lastSyncAt: string | null;\n sizeBytes: number | null;\n};\n\nconst pathResolution = new PathResolutionService();\nconst CLONE_MODE_WORKTREE_MUTATION_REASON =\n \"clone-mode repositories have a single checkout; use sync for clone-mode updates\";\n\nfunction ensureCapability(discovered: DiscoveredRepoContext | null, key: CapabilityKey, toolName: string): void {\n if (!discovered) return;\n const cap = discovered.capabilities[key];\n if (!cap.available) {\n const reasons = cap.reason ? [cap.reason] : discovered.notes;\n throw new CapabilityUnavailableError(toolName, reasons);\n }\n}\n\nasync function getReadyService(\n ctx: RepositoryContext,\n repoName: string | undefined,\n options: {\n capability?: CapabilityKey;\n toolName?: string;\n ensureInitialized?: boolean;\n } = {},\n): Promise<{ discovered: DiscoveredRepoContext | null; service: RepoService; git: RepoGitService }> {\n if (!repoName) {\n ctx.autoSelectCurrentRepoIfSingleConfig();\n }\n const discovered = ctx.getDiscoveredContext(repoName);\n if (options.capability && options.toolName) {\n ensureCapability(discovered, options.capability, options.toolName);\n }\n\n const service = await ctx.getService(repoName);\n if (options.ensureInitialized && !service.isInitialized()) {\n await service.initialize();\n }\n\n return {\n discovered,\n service,\n git: service.getGitService(),\n };\n}\n\nasync function runExclusiveRepoOperation<T>(\n ctx: RepositoryContext,\n repoName: string | undefined,\n service: RepoService,\n operation: () => Promise<T>,\n): Promise<T> {\n const result = await service.runExclusiveRepoOperation(operation);\n if (!result.started) {\n const name = ctx.getEntry(repoName)?.name ?? repoName ?? \"unknown\";\n throw new SyncInProgressError(name);\n }\n return result.value;\n}\n\nasync function ensureRepoWorktreePath(\n ctx: RepositoryContext,\n params: WorktreePathParams,\n service: RepoService,\n git: RepoGitService,\n): Promise<string> {\n await ensurePathBelongsToRepo(ctx, params.path, params.repoName, service, git);\n return path.resolve(params.path);\n}\n\nasync function ensurePathBelongsToRepo(\n ctx: RepositoryContext,\n targetPath: string,\n repoName: string | undefined,\n service: RepoService,\n git: RepoGitService,\n): Promise<void> {\n const discovered = ctx.getDiscoveredContext(repoName);\n if (discovered?.allWorktrees.length) {\n const match = discovered.allWorktrees.some((w) => pathsEqual(w.path, targetPath));\n if (match) return;\n }\n\n try {\n const worktrees = await getWorktreesFromService(service, git);\n if (worktrees.some((w) => pathsEqual(w.path, targetPath))) return;\n } catch {\n // fall through to rejection\n }\n\n throw new Error(`Path '${targetPath}' is not a registered worktree of the current repository`);\n}\n\nfunction isCloneModeService(service: RepoService): boolean {\n const candidate = service as RepoService & { isCloneMode?: () => boolean };\n return typeof candidate.isCloneMode === \"function\" && candidate.isCloneMode();\n}\n\nfunction ensureWorktreeModeService(service: RepoService, toolName: string): void {\n if (isCloneModeService(service)) {\n throw new CapabilityUnavailableError(toolName, [CLONE_MODE_WORKTREE_MUTATION_REASON]);\n }\n}\n\nasync function getWorktreesFromService(\n service: RepoService,\n git: { getWorktrees: () => Promise<Array<{ path: string; branch: string }>> },\n): Promise<Array<{ path: string; branch: string }>> {\n const candidate = service as RepoService & {\n getWorktrees?: () => Promise<Array<{ path: string; branch: string }>>;\n };\n if (typeof candidate.getWorktrees === \"function\") {\n return candidate.getWorktrees();\n }\n return git.getWorktrees();\n}\n\nexport async function handleDetectContext(\n ctx: RepositoryContext,\n params: { path?: string; includeStatus?: boolean; includeAllWorktrees?: boolean; detailed?: boolean },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const target = params.path ?? process.cwd();\n const discovered = await ctx.detectFromPath(target);\n // configuredRepositories is server-wide loaded-config inventory, independent of params.path.\n const configuredRepositories = await ctx.getConfiguredRepositorySummaries({ detailed: params.detailed ?? false });\n let response = { ...discovered, configuredRepositories };\n\n if (params.includeAllWorktrees) {\n const details = await ctx.getAllConfiguredWorktreeDetails(discovered.currentWorktreePath);\n const errorsByRepo = Object.keys(details.errorsByRepo).length > 0 ? details.errorsByRepo : undefined;\n response = {\n ...response,\n allWorktreesByRepo: details.worktreesByRepo,\n allWorktreeErrorsByRepo: errorsByRepo,\n };\n }\n\n if (!params.includeStatus) {\n return formatToolResponse(response);\n }\n\n const statusService = new WorktreeStatusService();\n const statusLimit = pLimit(DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\n\n const enriched = await enrichDetectedWorktrees(response.allWorktrees, statusService, statusLimit);\n let allWorktreesByRepo = response.allWorktreesByRepo;\n\n if (allWorktreesByRepo) {\n const entries = await Promise.all(\n Object.entries(allWorktreesByRepo).map(async ([repoName, worktrees]) => [\n repoName,\n await enrichDetectedWorktrees(worktrees, statusService, statusLimit),\n ]),\n );\n allWorktreesByRepo = Object.fromEntries(entries);\n }\n\n return formatToolResponse({ ...response, allWorktrees: enriched, allWorktreesByRepo });\n}\n\nasync function enrichDetectedWorktrees(\n worktrees: DiscoveredWorktree[],\n statusService: WorktreeStatusService,\n limit: Limit,\n): Promise<DiscoveredWorktree[]> {\n if (worktrees.length === 0) return worktrees;\n\n return Promise.all(\n worktrees.map((wt) =>\n limit(async () => {\n const [status, divergence] = await Promise.all([\n statusService.getFullWorktreeStatus(wt.path, false).catch(() => null),\n getDivergence(wt.path),\n ]);\n return {\n ...wt,\n label: status\n ? deriveLabel(status, wt.isCurrent)\n : wt.isCurrent\n ? (\"current\" as const)\n : (\"unknown\" as const),\n divergence,\n staleHint: status?.upstreamGone ?? false,\n };\n }),\n ),\n );\n}\n\nexport async function handleListWorktrees(\n ctx: RepositoryContext,\n params: { repoName?: string; includeSize?: boolean },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const configuredRepoNames = params.repoName ? [] : ctx.getConfiguredRepositoryNames();\n if (configuredRepoNames.length > 0) {\n const limit = pLimit(DEFAULT_CONFIG.PARALLELISM.MAX_REPOSITORIES);\n const statusLimit = pLimit(DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\n const repositories = await Promise.all(\n configuredRepoNames.map((repoName) =>\n limit(async () => {\n try {\n return [\n repoName,\n {\n worktrees: await listWorktreesForRepo(ctx, repoName, params.includeSize, statusLimit),\n },\n ] as const;\n } catch (err) {\n return [\n repoName,\n {\n worktrees: [],\n error: err instanceof Error ? err.message : String(err),\n },\n ] as const;\n }\n }),\n ),\n );\n\n return formatToolResponse({ repositories: Object.fromEntries(repositories) });\n }\n\n const results = await listWorktreesForRepo(ctx, params.repoName, params.includeSize);\n return formatToolResponse({ worktrees: results });\n}\n\nasync function listWorktreesForRepo(\n ctx: RepositoryContext,\n repoName: string | undefined,\n includeSize: boolean | undefined,\n limit: Limit = pLimit(DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS),\n): Promise<ListedWorktree[]> {\n const { discovered, service, git } = await getReadyService(ctx, repoName, {\n capability: \"listWorktrees\",\n toolName: \"list_worktrees\",\n });\n\n let worktrees: Array<{ path: string; branch: string }>;\n try {\n worktrees = await getWorktreesFromService(service, git);\n } catch {\n if (discovered) {\n worktrees = discovered.allWorktrees.map((w) => ({ path: w.path, branch: w.branch }));\n } else {\n throw new Error(\"Cannot list worktrees - service not initialized and no detected context\");\n }\n }\n\n const currentPath = discovered?.currentWorktreePath ?? null;\n\n const results = await Promise.all(\n worktrees.map((wt) =>\n limit(async () => {\n const resolvedPath = path.resolve(wt.path);\n const isCurrent = currentPath !== null && pathsEqual(wt.path, currentPath);\n\n const [status, divergence, metadata, sizeBytes] = await Promise.all([\n git.getFullWorktreeStatus(wt.path, false).catch(() => null),\n getDivergence(wt.path),\n git.getWorktreeMetadata(wt.path).catch(() => null),\n includeSize ? calculateDirectorySize(wt.path).catch(() => null) : Promise.resolve(null),\n ]);\n\n return {\n path: resolvedPath,\n branch: wt.branch,\n isCurrent,\n label: status ? deriveLabel(status, isCurrent) : isCurrent ? \"current\" : \"unknown\",\n status,\n divergence,\n safeToRemove: status ? deriveSafeToRemove(status) : { safe: false, reason: \"status unavailable\" },\n lastSyncAt: metadata?.lastSyncDate ?? null,\n sizeBytes,\n };\n }),\n ),\n );\n\n return results;\n}\n\nexport async function handleGetWorktreeStatus(\n ctx: RepositoryContext,\n params: { path: string; repoName?: string; includeDetails?: boolean },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { service, git } = await getReadyService(ctx, params.repoName, {\n capability: \"getStatus\",\n toolName: \"get_worktree_status\",\n });\n const resolvedPath = await ensureRepoWorktreePath(ctx, params, service, git);\n const [status, divergence] = await Promise.all([\n git.getFullWorktreeStatus(params.path, params.includeDetails ?? false),\n getDivergence(params.path),\n ]);\n\n return formatToolResponse({\n path: resolvedPath,\n ...status,\n divergence,\n });\n}\n\nexport async function handleCreateWorktree(\n ctx: RepositoryContext,\n params: { branchName: string; baseBranch?: string; push?: boolean; repoName?: string },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { branchName, baseBranch } = params;\n const push = params.push ?? true;\n\n const validation = isValidGitBranchName(branchName);\n if (!validation.valid) {\n throw new Error(`Invalid branch name '${branchName}': ${validation.error}`);\n }\n\n const { service, git } = await getReadyService(ctx, params.repoName, {\n capability: \"createWorktree\",\n toolName: \"create_worktree\",\n });\n ensureWorktreeModeService(service, \"create_worktree\");\n\n return runExclusiveRepoOperation(ctx, params.repoName, service, async () => {\n if (!service.isInitialized()) {\n await service.initializeUnlocked();\n }\n\n const existence = await git.branchExists(branchName);\n\n let created = false;\n let pushed = false;\n\n if (!existence.local && !existence.remote) {\n if (!baseBranch) {\n throw new Error(`Branch '${branchName}' does not exist. Provide 'baseBranch' to create it.`);\n }\n await git.createBranch(branchName, baseBranch);\n created = true;\n }\n\n const worktreeDir = service.config.worktreeDir;\n const worktreePath = pathResolution.getBranchWorktreePath(worktreeDir, branchName);\n const existing = await git.getWorktrees();\n const collision = existing.find((w) => pathsEqual(w.path, worktreePath) && w.branch !== branchName);\n if (collision) {\n throw new Error(\n `Sanitized worktree path '${worktreePath}' collides with existing branch '${collision.branch}'. Rename or remove the conflicting branch first.`,\n );\n }\n await git.addWorktree(branchName, worktreePath);\n ctx.invalidateDiscovered();\n\n if (created && push) {\n await git.pushBranch(branchName);\n pushed = true;\n }\n\n return formatToolResponse({\n success: true,\n branchName,\n worktreePath: path.resolve(worktreePath),\n created,\n pushed,\n });\n });\n}\n\nexport async function handleRemoveWorktree(\n ctx: RepositoryContext,\n params: { path: string; force?: boolean; repoName?: string },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { service, git } = await getReadyService(ctx, params.repoName, {\n capability: \"removeWorktree\",\n toolName: \"remove_worktree\",\n });\n ensureWorktreeModeService(service, \"remove_worktree\");\n\n return runExclusiveRepoOperation(ctx, params.repoName, service, async () => {\n if (!service.isInitialized()) {\n await service.initializeUnlocked();\n }\n const removedPath = await ensureRepoWorktreePath(ctx, params, service, git);\n\n if (!params.force) {\n const status = await git.getFullWorktreeStatus(params.path, false);\n if (!status.canRemove) {\n throw new Error(`Cannot remove worktree: ${status.reasons.join(\", \")}. Use force=true to override.`);\n }\n }\n\n await git.removeWorktree(params.path);\n ctx.invalidateDiscovered();\n\n return formatToolResponse({\n success: true,\n removedPath,\n });\n });\n}\n\nexport async function handleSync(\n ctx: RepositoryContext,\n params: { repoName?: string },\n extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { service } = await getReadyService(ctx, params.repoName, {\n capability: \"sync\",\n toolName: \"sync\",\n });\n\n const dispose = attachProgressReporter(service, extra);\n try {\n const start = Date.now();\n service.clearRecordedSkips();\n const result = await service.sync();\n if (!result.started) {\n throw new SyncInProgressError(ctx.getEntry(params.repoName)?.name ?? params.repoName ?? \"unknown\");\n }\n const duration = Date.now() - start;\n ctx.invalidateDiscovered();\n const outcome =\n result.outcome ??\n createEmptySyncOutcome(\n isCloneModeService(service) ? \"clone\" : \"worktree\",\n ctx.getEntry(params.repoName)?.name ?? params.repoName,\n duration,\n );\n const skips = service.getRecordedSkips().map((reason) => ({\n ...reason,\n message: formatCloneSkipReason(reason),\n }));\n return formatToolResponse({\n success: true,\n duration,\n outcome: {\n ...outcome,\n durationMs: outcome.durationMs ?? duration,\n },\n skips,\n });\n } finally {\n dispose();\n }\n}\n\nexport async function handleUpdateWorktree(\n ctx: RepositoryContext,\n params: { path: string; repoName?: string },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { service, git } = await getReadyService(ctx, params.repoName, {\n capability: \"updateWorktree\",\n toolName: \"update_worktree\",\n });\n ensureWorktreeModeService(service, \"update_worktree\");\n\n return runExclusiveRepoOperation(ctx, params.repoName, service, async () => {\n if (!service.isInitialized()) {\n await service.initializeUnlocked();\n }\n const worktreePath = await ensureRepoWorktreePath(ctx, params, service, git);\n\n await git.updateWorktree(params.path);\n ctx.invalidateDiscovered();\n\n return formatToolResponse({\n success: true,\n worktreePath,\n });\n });\n}\n\nexport async function handleInitialize(\n ctx: RepositoryContext,\n params: { repoName?: string },\n extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { service } = await getReadyService(ctx, params.repoName, {\n capability: \"initialize\",\n toolName: \"initialize\",\n });\n const dispose = attachProgressReporter(service, extra);\n try {\n return await runExclusiveRepoOperation(ctx, params.repoName, service, async () => {\n await service.initializeUnlocked();\n // A standalone initialize does not surface skips in its response. Clear the\n // one-shot suppression token so a later independent `sync` re-detects and\n // reports a wrong-branch / unreadable-HEAD clone instead of swallowing it.\n service.clearPendingInitSkip();\n const git = service.getGitService();\n ctx.invalidateDiscovered();\n return formatToolResponse({\n success: true,\n defaultBranch: git.getDefaultBranch(),\n worktreeDir: service.config.worktreeDir,\n });\n });\n } finally {\n dispose();\n }\n}\n\nexport async function handleLoadConfig(\n ctx: RepositoryContext,\n params: { configPath?: string },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const configPath = params.configPath ?? process.env.SYNC_WORKTREES_CONFIG;\n if (!configPath) {\n throw new Error(\"configPath required (or set SYNC_WORKTREES_CONFIG env var)\");\n }\n await ctx.loadConfig(configPath);\n return formatToolResponse({\n configPath: path.resolve(configPath),\n currentRepository: ctx.getCurrentRepo(),\n repositories: ctx.getRepositoryList(),\n });\n}\n\nexport async function handleSetCurrentRepository(\n ctx: RepositoryContext,\n params: { repoName: string },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n ctx.setCurrentRepo(params.repoName);\n return formatToolResponse({\n currentRepository: ctx.getCurrentRepo(),\n repositories: ctx.getRepositoryList(),\n });\n}\n\nfunction attachProgressReporter(\n service: {\n onProgress?: (listener: (event: ProgressEvent) => void) => () => void;\n },\n extra: HandlerExtra | undefined,\n): () => void {\n const token = extra?._meta?.progressToken;\n if (token === undefined || !extra) return () => {};\n if (!service.onProgress) return () => {};\n\n let progressCounter = 0;\n const unsubscribe = service.onProgress((event) => {\n progressCounter++;\n void extra\n .sendNotification({\n method: \"notifications/progress\",\n params: {\n progressToken: token,\n progress: progressCounter,\n message: `[${event.phase}] ${event.message}`,\n },\n })\n .catch(() => {});\n });\n\n return unsubscribe;\n}\n", "import fastFolderSize from \"fast-folder-size\";\n\n/**\n * Calculates the total size of a directory in bytes using native OS utilities.\n * Uses the `du` command on Unix systems for optimal performance (10-100x faster than pure Node.js).\n * @param dirPath - The path to the directory\n * @returns The total size in bytes\n */\nexport async function calculateDirectorySize(dirPath: string): Promise<number> {\n return new Promise((resolve, reject) => {\n fastFolderSize(dirPath, (err, bytes) => {\n if (err) {\n reject(err);\n return;\n }\n if (bytes === undefined) {\n reject(new Error(`fast-folder-size returned no bytes for ${dirPath}`));\n return;\n }\n resolve(bytes);\n });\n });\n}\n\n/**\n * Formats bytes into a human-readable string.\n * @param bytes - The number of bytes\n * @returns Formatted string (e.g., \"1.2 GB\", \"345 MB\", \"12 KB\")\n */\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return \"0 B\";\n\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n const k = 1024;\n const decimals = 2;\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n const value = bytes / Math.pow(k, i);\n\n return `${value.toFixed(decimals)} ${units[i]}`;\n}\n\n/**\n * Calculates the total disk space used by sync-worktrees repositories.\n * This includes bare repository directories and all worktree directories.\n *\n * @param repoPaths - Array of bare repository directory paths (e.g., from config.bareRepoDir)\n * @param worktreeDirs - Array of worktree base directories\n * @returns Formatted disk space string (e.g., \"1.2 GB\") or \"N/A\" if calculation fails\n */\nexport async function calculateSyncDiskSpace(repoPaths: string[], worktreeDirs: string[]): Promise<string> {\n try {\n let totalBytes = 0;\n\n for (const repoPath of repoPaths) {\n try {\n totalBytes += await calculateDirectorySize(repoPath);\n } catch {\n /* skip unreadable bare repo */\n }\n }\n\n for (const worktreeDir of worktreeDirs) {\n try {\n totalBytes += await calculateDirectorySize(worktreeDir);\n } catch {\n /* skip unreadable worktree dir */\n }\n }\n\n return formatBytes(totalBytes);\n } catch (error) {\n console.error(\"Failed to calculate disk space:\", error);\n return \"N/A\";\n }\n}\n", "export function isValidGitBranchName(name: string): { valid: boolean; error?: string } {\n if (!name.trim()) {\n return { valid: false, error: \"Branch name cannot be empty\" };\n }\n if (name === \"@\") {\n return { valid: false, error: \"Branch name cannot be '@'\" };\n }\n if (name.startsWith(\"-\")) {\n return { valid: false, error: \"Branch name cannot start with '-'\" };\n }\n if (name.startsWith(\"/\") || name.endsWith(\"/\")) {\n return { valid: false, error: \"Branch name cannot start or end with '/'\" };\n }\n if (name.endsWith(\".lock\")) {\n return { valid: false, error: \"Branch name cannot end with '.lock'\" };\n }\n if (name.includes(\"..\")) {\n return { valid: false, error: \"Branch name cannot contain '..'\" };\n }\n if (name.includes(\"@{\")) {\n return { valid: false, error: \"Branch name cannot contain '@{'\" };\n }\n if (name.includes(\"/.\") || name.includes(\"./\")) {\n return { valid: false, error: \"Branch name cannot contain '/.' or './'\" };\n }\n if (name.startsWith(\".\") || name.endsWith(\".\")) {\n return { valid: false, error: \"Branch name cannot start or end with '.'\" };\n }\n if (name.includes(\"//\")) {\n return { valid: false, error: \"Branch name cannot contain consecutive slashes\" };\n }\n for (const component of name.split(\"/\")) {\n if (component === \"\") {\n return { valid: false, error: \"Branch name cannot contain empty path components\" };\n }\n if (component.startsWith(\".\") || component.endsWith(\".\")) {\n return { valid: false, error: \"Branch name path components cannot start or end with '.'\" };\n }\n if (component.endsWith(\".lock\")) {\n return { valid: false, error: \"Branch name path components cannot end with '.lock'\" };\n }\n }\n // eslint-disable-next-line no-control-regex\n if (/[\\x00-\\x20\\x7f~^:?*[\\\\]/.test(name)) {\n return { valid: false, error: \"Branch name contains invalid characters\" };\n }\n return { valid: true };\n}\n", "import { SyncWorktreesError } from \"../errors\";\n\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type { CallToolResult, ServerNotification, ServerRequest } from \"@modelcontextprotocol/sdk/types.js\";\n\nexport type HandlerExtra = RequestHandlerExtra<ServerRequest, ServerNotification>;\n\nexport function formatToolResponse(data: unknown): CallToolResult {\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(data),\n },\n ],\n };\n}\n\nexport function formatErrorResponse(error: unknown): CallToolResult {\n let code = \"UNKNOWN_ERROR\";\n let message = String(error);\n\n if (error instanceof SyncWorktreesError) {\n code = error.code;\n message = error.message;\n } else if (error instanceof Error) {\n code = \"INTERNAL_ERROR\";\n message = error.message;\n }\n\n const body: Record<string, unknown> = {\n error: true,\n code,\n message,\n };\n\n if (process.env.DEBUG && error instanceof Error && error.stack) {\n body.stack = error.stack;\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(body),\n },\n ],\n isError: true,\n };\n}\n\nexport class CapabilityUnavailableError extends SyncWorktreesError {\n constructor(capability: string, reasons: string[]) {\n super(`Capability '${capability}' unavailable: ${reasons.join(\", \")}`, \"CAPABILITY_UNAVAILABLE\");\n }\n}\n\nexport class SyncInProgressError extends SyncWorktreesError {\n constructor(repoName: string) {\n super(`Sync already in progress for '${repoName}'`, \"SYNC_IN_PROGRESS\");\n }\n}\n\nexport function wrapHandler<P>(\n fn: (params: P, extra: HandlerExtra) => Promise<CallToolResult>,\n): (params: P, extra: HandlerExtra) => Promise<CallToolResult> {\n return async (params, extra) => {\n try {\n return await fn(params, extra);\n } catch (error) {\n return formatErrorResponse(error);\n }\n };\n}\n", "import simpleGit from \"simple-git\";\n\nimport type { WorktreeStatusResult } from \"../services/worktree-status.service\";\n\nexport type WorktreeLabel = \"current\" | \"dirty\" | \"stale\" | \"clean\" | \"unknown\";\n\nexport interface Divergence {\n ahead: number;\n behind: number;\n}\n\nexport interface SafeToRemove {\n safe: boolean;\n reason: string;\n}\n\nexport function deriveLabel(status: WorktreeStatusResult, isCurrent: boolean): WorktreeLabel {\n if (isCurrent) return \"current\";\n if (!status.isClean || status.hasUnpushedCommits || status.hasStashedChanges) return \"dirty\";\n if (status.upstreamGone) return \"stale\";\n return \"clean\";\n}\n\nexport function deriveSafeToRemove(status: WorktreeStatusResult): SafeToRemove {\n if (status.canRemove && !status.upstreamGone) {\n return { safe: true, reason: \"clean tree, no unpushed commits\" };\n }\n\n if (status.canRemove && status.upstreamGone) {\n return { safe: false, reason: \"branch deleted upstream \u2014 verify no work is lost before removal\" };\n }\n\n if (status.reasons.length > 0) {\n return { safe: false, reason: status.reasons.join(\", \") };\n }\n\n return { safe: false, reason: \"not safe to remove\" };\n}\n\nexport async function getDivergence(worktreePath: string): Promise<Divergence | null> {\n try {\n const git = simpleGit(worktreePath);\n const output = await git.raw([\"rev-list\", \"--left-right\", \"--count\", \"HEAD...@{upstream}\"]);\n const [aheadStr, behindStr] = output.trim().split(/\\s+/);\n return { ahead: parseInt(aheadStr, 10), behind: parseInt(behindStr, 10) };\n } catch {\n return null;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\n\nimport { RepositoryContext } from \"./context\";\nimport { createServer } from \"./server\";\n\nimport type { DiscoveredRepoContext } from \"./context\";\n\nasync function main(): Promise<void> {\n const context = new RepositoryContext();\n\n const configPath = process.env.SYNC_WORKTREES_CONFIG;\n if (configPath) {\n try {\n await context.loadConfig(configPath);\n process.stderr.write(`[sync-worktrees-mcp] Loaded config: ${configPath}\\n`);\n } catch (err) {\n process.stderr.write(`[sync-worktrees-mcp] Failed to load SYNC_WORKTREES_CONFIG: ${(err as Error).message}\\n`);\n }\n }\n\n let discovered: DiscoveredRepoContext | null = null;\n try {\n discovered = await context.detectFromPath(process.cwd());\n if (discovered.isWorktree) {\n process.stderr.write(\n `[sync-worktrees-mcp] Auto-detected ${discovered.kind} worktree at ${discovered.currentWorktreePath} (branch: ${discovered.currentBranch})\\n`,\n );\n }\n } catch (err) {\n process.stderr.write(`[sync-worktrees-mcp] Auto-detect failed: ${(err as Error).message}\\n`);\n }\n\n const server = createServer(context, {\n discovered,\n configuredRepoCount: context.getConfiguredRepositoryNames().length,\n });\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n process.stderr.write(`[sync-worktrees-mcp] Fatal error: ${(err as Error).message}\\n`);\n process.exit(1);\n});\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport pLimit from \"p-limit\";\nimport simpleGit from \"simple-git\";\n\nimport { DEFAULT_CONFIG, GIT_CONSTANTS } from \"../constants\";\nimport { ConfigLoaderService } from \"../services/config-loader.service\";\nimport { Logger } from \"../services/logger.service\";\nimport { WorktreeSyncService } from \"../services/worktree-sync.service\";\nimport { normalizePathForCompare } from \"../utils/path-compare\";\nimport { REPOSITORY_MODES, resolveMode } from \"../utils/repo-mode\";\nimport { parseWorktreeListPorcelain } from \"../utils/worktree-list-parser\";\n\nimport type { Config, RepositoryConfig } from \"../types\";\nimport type { Divergence, WorktreeLabel } from \"./worktree-summary\";\n\nexport interface CapabilityState {\n available: boolean;\n reason?: string;\n}\n\nexport interface Capabilities {\n listWorktrees: CapabilityState;\n getStatus: CapabilityState;\n createWorktree: CapabilityState;\n removeWorktree: CapabilityState;\n updateWorktree: CapabilityState;\n sync: CapabilityState;\n initialize: CapabilityState;\n}\n\nexport interface DiscoveredWorktree {\n path: string;\n branch: string;\n isCurrent: boolean;\n label?: WorktreeLabel;\n divergence?: Divergence | null;\n staleHint?: boolean;\n}\n\nexport interface SiblingRepository {\n name: string;\n bareRepoPath: string;\n worktreeDir: string | null;\n repoUrl: string | null;\n sparseCheckout?: RepositoryConfig[\"sparseCheckout\"];\n present: boolean;\n configMatched: boolean;\n}\n\ninterface ConfiguredRepositorySummaryBase {\n name: string;\n isCurrent: boolean;\n repoUrl?: string;\n branch?: string;\n sparseCheckout?: RepositoryConfig[\"sparseCheckout\"];\n localReady?: boolean;\n}\n\nexport interface ConfiguredCloneRepositorySummary extends ConfiguredRepositorySummaryBase {\n mode: \"clone\";\n checkoutPath: string;\n}\n\nexport interface ConfiguredWorktreeRepositorySummary extends ConfiguredRepositorySummaryBase {\n mode: \"worktree\";\n worktreeDir: string;\n bareRepoDir?: string;\n}\n\nexport type ConfiguredRepositorySummary = ConfiguredCloneRepositorySummary | ConfiguredWorktreeRepositorySummary;\n\nexport interface DiscoveredRepoContext {\n isWorktree: boolean;\n kind: \"managed\" | \"unmanaged\" | \"unsupported\";\n currentBranch: string | null;\n currentWorktreePath: string | null;\n bareRepoPath: string | null;\n repoUrl: string | null;\n worktreeDir: string | null;\n allWorktrees: DiscoveredWorktree[];\n allWorktreesByRepo?: Record<string, DiscoveredWorktree[]>;\n allWorktreeErrorsByRepo?: Record<string, string>;\n siblingRepositories: SiblingRepository[];\n configPath: string | null;\n repoName: string | null;\n capabilities: Capabilities;\n notes: string[];\n}\n\ninterface RepoEntry {\n name: string;\n config: Config;\n source: \"config\" | \"detected\";\n service?: WorktreeSyncService;\n discovered?: DiscoveredRepoContext;\n}\n\ntype RepositorySelectionDecision =\n | { kind: \"selected\"; repoName: string; source: \"current\" | \"explicit\" | \"single-config\" }\n | { kind: \"ambiguous\"; configured: string[]; detected: string[]; reason: string }\n | { kind: \"missing\"; configured: string[]; detected: string[]; reason: string };\n\ninterface RepositorySelectionState {\n currentRepo: string | null;\n configured: string[];\n detected: string[];\n defaultDecision: RepositorySelectionDecision;\n}\n\ninterface CachedDiscovery {\n result: DiscoveredRepoContext;\n cachedAt: number;\n worktreeAdminDir: string | null;\n worktreeHeadMtimeMs: number | null;\n worktreesDirMtimeMs: number | null;\n}\n\nconst AUTO_DETECT_PREFIX = \"__auto_detected__:\";\nconst DISCOVERY_CACHE_TTL_MS = 5000;\n\nfunction emptyCapabilities(reason?: string): Capabilities {\n const state: CapabilityState = reason ? { available: false, reason } : { available: false };\n return {\n listWorktrees: { ...state },\n getStatus: { ...state },\n createWorktree: { ...state },\n removeWorktree: { ...state },\n updateWorktree: { ...state },\n sync: { ...state },\n initialize: { ...state },\n };\n}\n\nexport function buildUnsupportedContext(currentPath: string, reason: string): DiscoveredRepoContext {\n return {\n isWorktree: false,\n kind: \"unsupported\",\n currentBranch: null,\n currentWorktreePath: currentPath,\n bareRepoPath: null,\n repoUrl: null,\n worktreeDir: null,\n allWorktrees: [],\n siblingRepositories: [],\n configPath: null,\n repoName: null,\n capabilities: emptyCapabilities(reason),\n notes: [reason],\n };\n}\n\nfunction createStderrLogger(repoName?: string): Logger {\n return new Logger({\n repoName,\n outputFn: (msg: string): void => {\n process.stderr.write(msg + \"\\n\");\n },\n });\n}\n\nexport class RepositoryContext {\n private repos = new Map<string, RepoEntry>();\n private currentRepo: string | null = null;\n private configPath: string | null = null;\n private configLoader = new ConfigLoaderService();\n private discoveryCache = new Map<string, CachedDiscovery>();\n private readonly launchCwd: string;\n\n constructor(options: { launchCwd?: string } = {}) {\n this.launchCwd = path.resolve(options.launchCwd ?? process.cwd());\n }\n\n getLaunchCwd(): string {\n return this.launchCwd;\n }\n\n async loadConfig(configPath: string, options: { setDefaultCurrent?: boolean } = {}): Promise<RepositoryConfig[]> {\n const setDefaultCurrent = options.setDefaultCurrent ?? true;\n const absolutePath = path.resolve(configPath);\n const configFile = await this.configLoader.loadConfigFile(absolutePath);\n\n const configDir = path.dirname(absolutePath);\n const globalDefaults = configFile.defaults;\n\n const resolvedAll: RepositoryConfig[] = [];\n for (const repo of configFile.repositories) {\n const resolved = this.configLoader.resolveRepositoryConfig(\n repo,\n globalDefaults,\n configDir,\n configFile.retry,\n configFile.repositories,\n );\n resolvedAll.push(resolved);\n }\n this.configLoader.detectBareRepoDirCollisions(resolvedAll);\n\n for (const [name, entry] of this.repos) {\n if (entry.source === \"config\") {\n this.repos.delete(name);\n }\n }\n\n this.configPath = absolutePath;\n for (const resolved of resolvedAll) {\n this.repos.set(resolved.name, {\n name: resolved.name,\n config: resolved,\n source: \"config\",\n });\n }\n\n if (this.currentRepo && !this.repos.has(this.currentRepo)) {\n this.currentRepo = null;\n }\n\n if (setDefaultCurrent && !this.currentRepo && configFile.repositories.length > 0) {\n this.currentRepo = configFile.repositories[0].name;\n }\n\n this.discoveryCache.clear();\n\n return configFile.repositories;\n }\n\n async detectFromPath(dirPath: string): Promise<DiscoveredRepoContext> {\n const absolutePath = path.resolve(dirPath);\n\n const cached = this.discoveryCache.get(absolutePath);\n if (cached && (await this.isCacheFresh(cached))) {\n return cached.result;\n }\n\n if (this.configPath === null) {\n const found = await this.configLoader.findConfigUpward(absolutePath);\n if (found) {\n try {\n await this.loadConfig(found, { setDefaultCurrent: false });\n } catch (err) {\n process.stderr.write(`[sync-worktrees] auto-loaded config failed: ${(err as Error).message}\\n`);\n }\n }\n }\n\n const { result, adminDir } = await this.detectFromPathUncached(absolutePath);\n\n if (result.isWorktree && result.bareRepoPath && adminDir) {\n const [worktreeHeadMtimeMs, worktreesDirMtimeMs] = await Promise.all([\n safeMtimeMs(path.join(adminDir, \"HEAD\")),\n safeMtimeMs(path.join(result.bareRepoPath, \"worktrees\")),\n ]);\n this.discoveryCache.set(absolutePath, {\n result,\n cachedAt: Date.now(),\n worktreeAdminDir: adminDir,\n worktreeHeadMtimeMs,\n worktreesDirMtimeMs,\n });\n }\n\n return result;\n }\n\n invalidateDiscovered(): void {\n this.discoveryCache.clear();\n }\n\n /** @internal Test-only helper \u2014 registers a repo entry without going through config loading. */\n __registerForTest(name: string, entry: Omit<RepoEntry, \"name\">): void {\n this.repos.set(name, { ...entry, name });\n }\n\n /** @internal Test-only helper \u2014 sets the current repo pointer. */\n __setCurrentRepoForTest(name: string | null): void {\n this.currentRepo = name;\n }\n\n /** @internal Test-only helper \u2014 returns the size of the internal repo map. */\n __repoCountForTest(): number {\n return this.repos.size;\n }\n\n /** @internal Test-only helper \u2014 returns the size of the discovery cache. */\n __discoveryCacheSizeForTest(): number {\n return this.discoveryCache.size;\n }\n\n /** @internal Test-only helper \u2014 exposes the internal selection state. */\n __getRepositorySelectionStateForTest(): unknown {\n return this.getRepositorySelectionState();\n }\n\n private async discoverSiblingRepositories(currentBareRepoPath: string): Promise<SiblingRepository[]> {\n const currentBare = normalizePathForCompare(currentBareRepoPath);\n const results = new Map<string, SiblingRepository>();\n const byName = (a: SiblingRepository, b: SiblingRepository): number => a.name.localeCompare(b.name);\n\n const configCandidates = Array.from(this.repos.values())\n .filter((entry) => entry.source === \"config\" && !!entry.config.bareRepoDir)\n .map((entry) => {\n const bareRepoPath = path.resolve(entry.config.bareRepoDir as string);\n return { entry, bareRepoPath, foldedBare: normalizePathForCompare(bareRepoPath) };\n })\n .filter((c) => c.foldedBare !== currentBare);\n\n const configPresence = await Promise.all(configCandidates.map((c) => isDirectory(c.bareRepoPath)));\n configCandidates.forEach(({ entry, bareRepoPath, foldedBare }, i) => {\n const sibling: SiblingRepository = {\n name: entry.name,\n bareRepoPath,\n worktreeDir: path.resolve(entry.config.worktreeDir),\n repoUrl: entry.config.repoUrl,\n present: configPresence[i],\n configMatched: true,\n };\n if (entry.config.sparseCheckout) {\n sibling.sparseCheckout = entry.config.sparseCheckout;\n }\n results.set(foldedBare, sibling);\n });\n\n const repoDir = path.dirname(currentBareRepoPath);\n const workspaceRoot = path.dirname(repoDir);\n\n if (workspaceRoot === repoDir) {\n return Array.from(results.values()).sort(byName);\n }\n\n let entries: string[];\n try {\n entries = await fs.readdir(workspaceRoot);\n } catch {\n return Array.from(results.values()).sort(byName);\n }\n\n const configBares = new Map(configCandidates.map((c) => [c.foldedBare, c.entry.name]));\n\n await Promise.all(\n entries.map(async (entry) => {\n const candidate = path.join(workspaceRoot, entry);\n const bareCandidate = path.join(candidate, GIT_CONSTANTS.BARE_DIR_NAME);\n if (!(await isDirectory(bareCandidate))) return;\n\n const resolvedBare = path.resolve(bareCandidate);\n const foldedBare = normalizePathForCompare(resolvedBare);\n if (foldedBare === currentBare || results.has(foldedBare)) return;\n\n const matchedName = configBares.get(foldedBare);\n results.set(foldedBare, {\n name: matchedName ?? entry,\n bareRepoPath: resolvedBare,\n worktreeDir: null,\n repoUrl: null,\n present: true,\n configMatched: matchedName !== undefined,\n });\n }),\n );\n\n return Array.from(results.values()).sort(byName);\n }\n\n private bootstrapCurrentRepo(candidate: string, force = false): void {\n if (this.currentRepo !== null) return;\n if (!this.repos.has(candidate)) return;\n if (!force && this.repos.size !== 1) return;\n this.currentRepo = candidate;\n }\n\n private async isCacheFresh(cached: CachedDiscovery): Promise<boolean> {\n if (Date.now() - cached.cachedAt >= DISCOVERY_CACHE_TTL_MS) return false;\n if (!cached.worktreeAdminDir || !cached.result.bareRepoPath) return true;\n\n const [currentHeadMtime, currentWorktreesDirMtime] = await Promise.all([\n safeMtimeMs(path.join(cached.worktreeAdminDir, \"HEAD\")),\n safeMtimeMs(path.join(cached.result.bareRepoPath, \"worktrees\")),\n ]);\n\n return currentHeadMtime === cached.worktreeHeadMtimeMs && currentWorktreesDirMtime === cached.worktreesDirMtimeMs;\n }\n\n private async detectFromPathUncached(\n absolutePath: string,\n ): Promise<{ result: DiscoveredRepoContext; adminDir: string | null }> {\n const notes: string[] = [];\n\n const located = await findWorktreeRoot(absolutePath);\n const worktreeRoot = located?.worktreeRoot ?? absolutePath;\n\n const unsupported = (reason: string): { result: DiscoveredRepoContext; adminDir: string | null } => {\n notes.push(reason);\n return {\n result: {\n isWorktree: false,\n kind: \"unsupported\",\n currentBranch: null,\n currentWorktreePath: worktreeRoot,\n bareRepoPath: null,\n repoUrl: null,\n worktreeDir: null,\n allWorktrees: [],\n siblingRepositories: [],\n configPath: this.configPath,\n repoName: null,\n capabilities: emptyCapabilities(reason),\n notes,\n },\n adminDir: null,\n };\n };\n\n if (!located) {\n return unsupported(\"No .git file found in path or any parent directory\");\n }\n if (located.kind === \"regular-git-dir\") {\n const cloneEntry = this.findConfiguredCloneEntry(worktreeRoot);\n if (cloneEntry) {\n return {\n result: await this.buildCloneModeContext(cloneEntry, worktreeRoot, notes),\n adminDir: null,\n };\n }\n return unsupported(\"Directory has .git folder (regular repo, not a sync-worktrees worktree)\");\n }\n\n const gitFileContent = located.gitFileContent;\n\n const gitdirMatch = gitFileContent.match(/^gitdir:\\s*(.+)$/m);\n if (!gitdirMatch) {\n return unsupported(\"Invalid .git file format (missing gitdir line)\");\n }\n\n const gitdir = gitdirMatch[1].trim();\n const resolvedGitdir = path.isAbsolute(gitdir) ? gitdir : path.resolve(worktreeRoot, gitdir);\n const worktreesMatch = resolvedGitdir.match(/^(.+?)[/\\\\]worktrees[/\\\\][^/\\\\]+$/);\n if (!worktreesMatch) {\n return unsupported(\"gitdir does not follow worktree structure (missing /worktrees/<name>)\");\n }\n\n const bareRepoPath = path.resolve(worktreesMatch[1]);\n const adminDir = path.resolve(resolvedGitdir);\n\n let repoUrl: string | null = null;\n let worktrees: DiscoveredWorktree[] = [];\n let currentBranch: string | null = null;\n\n try {\n const bareGit = simpleGit(bareRepoPath);\n\n try {\n const remoteResult = await bareGit.remote([\"get-url\", \"origin\"]);\n const urlStr = typeof remoteResult === \"string\" ? remoteResult.trim() : \"\";\n repoUrl = urlStr || null;\n } catch {\n notes.push(\"Could not read remote origin URL\");\n }\n\n const listOutput = await bareGit.raw([\"worktree\", \"list\", \"--porcelain\"]);\n worktrees = parseWorktreeList(listOutput, worktreeRoot);\n const current = worktrees.find((w) => w.isCurrent);\n if (current) {\n currentBranch = current.branch;\n }\n } catch (err) {\n const reason = `Failed to read bare repo at ${bareRepoPath}: ${(err as Error).message}`;\n notes.push(reason);\n return {\n result: {\n isWorktree: true,\n kind: \"unsupported\",\n currentBranch: null,\n currentWorktreePath: worktreeRoot,\n bareRepoPath,\n repoUrl: null,\n worktreeDir: null,\n allWorktrees: [],\n siblingRepositories: [],\n configPath: this.configPath,\n repoName: null,\n capabilities: emptyCapabilities(reason),\n notes,\n },\n adminDir,\n };\n }\n\n const worktreeDir = path.dirname(worktreeRoot);\n\n const noUrlReason = \"no remote origin URL detected\";\n const capabilities: Capabilities = {\n listWorktrees: { available: true },\n getStatus: { available: true },\n createWorktree: repoUrl !== null ? { available: true } : { available: false, reason: noUrlReason },\n removeWorktree: { available: true },\n updateWorktree: { available: true },\n sync: { available: false, reason: \"no config and no remote URL\" },\n initialize: { available: false, reason: \"no config and no remote URL\" },\n };\n\n const foldedBare = normalizePathForCompare(bareRepoPath);\n let matchedConfig: RepoEntry | null = null;\n for (const entry of this.repos.values()) {\n if (entry.source === \"config\" && entry.config.bareRepoDir) {\n if (normalizePathForCompare(entry.config.bareRepoDir) === foldedBare) {\n matchedConfig = entry;\n break;\n }\n }\n }\n\n let repoName: string | null = null;\n let kind: DiscoveredRepoContext[\"kind\"] = \"unmanaged\";\n\n if (matchedConfig) {\n repoName = matchedConfig.name;\n kind = \"managed\";\n capabilities.sync = { available: true };\n capabilities.initialize = { available: true };\n } else if (repoUrl) {\n const syntheticConfig: Config = {\n repoUrl,\n worktreeDir,\n bareRepoDir: bareRepoPath,\n cronSchedule: DEFAULT_CONFIG.CRON_SCHEDULE,\n runOnce: true,\n };\n const detectedKey = `${AUTO_DETECT_PREFIX}${path.basename(bareRepoPath)}@${bareRepoPath}`;\n if (!this.repos.has(detectedKey)) {\n this.repos.set(detectedKey, {\n name: detectedKey,\n config: syntheticConfig,\n source: \"detected\",\n });\n }\n repoName = detectedKey;\n const autoReason = \"no config file loaded (running in auto-detect mode)\";\n capabilities.sync = { available: false, reason: autoReason };\n capabilities.initialize = { available: false, reason: autoReason };\n }\n\n if (repoName) {\n this.bootstrapCurrentRepo(repoName, matchedConfig !== null);\n }\n\n const siblingRepositories = await this.discoverSiblingRepositories(bareRepoPath);\n\n const discovered: DiscoveredRepoContext = {\n isWorktree: true,\n kind,\n currentBranch,\n currentWorktreePath: worktreeRoot,\n bareRepoPath,\n repoUrl,\n worktreeDir,\n allWorktrees: worktrees,\n siblingRepositories,\n configPath: this.configPath,\n repoName,\n capabilities,\n notes,\n };\n\n if (repoName) {\n const entry = this.repos.get(repoName);\n if (entry) {\n entry.discovered = discovered;\n }\n }\n\n return { result: discovered, adminDir };\n }\n\n async getService(repoName?: string): Promise<WorktreeSyncService> {\n if (repoName) {\n const explicit = this.selectExplicitRepository(repoName);\n if (explicit.kind !== \"selected\") {\n throw new Error(this.buildRepoNotFoundError(repoName));\n }\n }\n\n const name = repoName ?? this.currentRepo;\n if (!name) {\n throw new Error(this.buildNoRepoSelectedError());\n }\n const entry = this.repos.get(name);\n if (!entry) {\n throw new Error(this.buildRepoNotFoundError(name));\n }\n if (!entry.service) {\n const logger = createStderrLogger(entry.name);\n entry.service = new WorktreeSyncService({\n ...entry.config,\n logger,\n });\n }\n return entry.service;\n }\n\n private getRepositorySelectionState(): RepositorySelectionState {\n const configured = this.getConfiguredRepositoryNames();\n const detected = this.getDetectedRepositoryNames();\n return {\n currentRepo: this.currentRepo,\n configured,\n detected,\n defaultDecision: this.selectDefaultRepository(configured, detected),\n };\n }\n\n private selectExplicitRepository(repoName: string): RepositorySelectionDecision {\n if (this.repos.has(repoName)) {\n return { kind: \"selected\", repoName, source: \"explicit\" };\n }\n return {\n kind: \"missing\",\n configured: this.getConfiguredRepositoryNames(),\n detected: this.getDetectedRepositoryNames(),\n reason: `Repository '${repoName}' not found`,\n };\n }\n\n private selectDefaultRepository(\n configured = this.getConfiguredRepositoryNames(),\n detected = this.getDetectedRepositoryNames(),\n ): RepositorySelectionDecision {\n if (this.currentRepo !== null) {\n return { kind: \"selected\", repoName: this.currentRepo, source: \"current\" };\n }\n if (this.canAutoSelectSingleConfig(configured, detected)) {\n return { kind: \"selected\", repoName: configured[0], source: \"single-config\" };\n }\n if (configured.length === 0 && detected.length === 0) {\n return {\n kind: \"missing\",\n configured,\n detected,\n reason: \"no configured or detected repositories are registered\",\n };\n }\n return {\n kind: \"ambiguous\",\n configured,\n detected,\n reason: \"repository selection is ambiguous without currentRepo or explicit repoName\",\n };\n }\n\n private canAutoSelectSingleConfig(\n configured = this.getConfiguredRepositoryNames(),\n detected = this.getDetectedRepositoryNames(),\n ): boolean {\n return this.currentRepo === null && configured.length === 1 && detected.length === 0;\n }\n\n private getDetectedRepositoryNames(): string[] {\n return Array.from(this.repos.values())\n .filter((entry) => entry.source === \"detected\")\n .map((entry) => entry.name);\n }\n\n private formatDetectedRepositoryNames(): string[] {\n return Array.from(this.repos.values())\n .filter((e) => e.source === \"detected\")\n .map((e) => {\n const location = e.discovered?.currentWorktreePath ?? e.config.bareRepoDir ?? e.config.worktreeDir;\n return location ? `${e.name} (${location})` : e.name;\n });\n }\n\n private formatKnownRepositoryNames(names: string[]): string {\n return names.length === 0 ? \"[]\" : `[${names.join(\", \")}]`;\n }\n\n private buildNoRepoSelectedError(): string {\n const selection = this.getRepositorySelectionState();\n const detected = this.formatDetectedRepositoryNames();\n const parts = [\n \"No repository specified and no current repository set.\",\n `launchCwd=${this.launchCwd}`,\n `configPath=${this.configPath ?? \"none\"}`,\n `loadedRepos=${this.repos.size} (config: ${selection.configured.length}, detected: ${selection.detected.length})`,\n ];\n if (detected.length > 0) {\n parts.push(`Detected repos: ${this.formatKnownRepositoryNames(detected)}.`);\n }\n if (selection.configured.length > 0) {\n parts.push(`Configured repos: ${this.formatKnownRepositoryNames(selection.configured)}.`);\n }\n if (selection.configured.length > 0 || detected.length > 0) {\n parts.push(\"Recovery: call set_current_repository with one of the repo names above or pass repoName explicitly.\");\n } else {\n parts.push(\n \"Recovery: call detect_context {path: <workspace>}, load_config {configPath: <file>}, set SYNC_WORKTREES_CONFIG env var, or pass repoName explicitly.\",\n );\n }\n return parts.join(\" \");\n }\n\n private buildRepoNotFoundError(name: string): string {\n const known = Array.from(this.repos.keys());\n const knownStr = this.formatKnownRepositoryNames(known);\n return `Repository '${name}' not found. Known repos: ${knownStr}. Run load_config or detect_context to register it.`;\n }\n\n getEntry(repoName?: string): RepoEntry | null {\n const name = repoName ?? this.currentRepo;\n if (!name) return null;\n return this.repos.get(name) ?? null;\n }\n\n getDiscoveredContext(repoName?: string): DiscoveredRepoContext | null {\n const entry = this.getEntry(repoName);\n return entry?.discovered ?? null;\n }\n\n getCurrentRepo(): string | null {\n return this.currentRepo;\n }\n\n setCurrentRepo(repoName: string): void {\n if (!this.repos.has(repoName)) {\n throw new Error(`Repository '${repoName}' not found`);\n }\n this.currentRepo = repoName;\n }\n\n getRepositoryList(): Array<{ name: string; repoUrl: string; worktreeDir: string; source: \"config\" | \"detected\" }> {\n return Array.from(this.repos.values()).map((e) => ({\n name: e.name,\n repoUrl: e.config.repoUrl,\n worktreeDir: e.config.worktreeDir,\n source: e.source,\n }));\n }\n\n getConfiguredRepositoryNames(): string[] {\n return Array.from(this.repos.values())\n .filter((entry) => entry.source === \"config\")\n .map((entry) => entry.name);\n }\n\n async getConfiguredRepositorySummaries(options: { detailed?: boolean } = {}): Promise<ConfiguredRepositorySummary[]> {\n const entries = Array.from(this.repos.values()).filter((entry) => entry.source === \"config\");\n const currentRepo = this.currentRepo;\n\n const buildLean = (entry: RepoEntry): ConfiguredRepositorySummary => {\n const mode = resolveMode(entry.config);\n const isCurrent = entry.name === currentRepo;\n if (mode === REPOSITORY_MODES.CLONE) {\n return { name: entry.name, mode: \"clone\", checkoutPath: path.resolve(entry.config.worktreeDir), isCurrent };\n }\n return { name: entry.name, mode: \"worktree\", worktreeDir: path.resolve(entry.config.worktreeDir), isCurrent };\n };\n\n if (!options.detailed) {\n return entries.map(buildLean);\n }\n\n const limit = pLimit(DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\n return Promise.all(\n entries.map((entry) =>\n limit(async () => {\n const summary = buildLean(entry);\n summary.repoUrl = entry.config.repoUrl;\n if (entry.config.branch) summary.branch = entry.config.branch;\n if (entry.config.sparseCheckout) {\n const sc = entry.config.sparseCheckout;\n summary.sparseCheckout = {\n ...sc,\n include: [...sc.include],\n ...(sc.exclude ? { exclude: [...sc.exclude] } : {}),\n };\n }\n\n if (summary.mode === \"clone\") {\n summary.localReady = await isGitCheckout(summary.checkoutPath);\n return summary;\n }\n\n if (entry.config.bareRepoDir) {\n summary.bareRepoDir = path.resolve(entry.config.bareRepoDir);\n summary.localReady = await isDirectory(summary.bareRepoDir);\n } else {\n summary.localReady = false;\n }\n return summary;\n }),\n ),\n );\n }\n\n autoSelectCurrentRepoIfSingleConfig(): string | null {\n const decision = this.selectDefaultRepository();\n if (decision.kind !== \"selected\") return null;\n if (decision.source === \"single-config\") {\n this.currentRepo = decision.repoName;\n }\n return this.currentRepo;\n }\n\n async getAllConfiguredWorktreeDetails(\n currentWorktreePath: string | null = null,\n ): Promise<{ worktreesByRepo: Record<string, DiscoveredWorktree[]>; errorsByRepo: Record<string, string> }> {\n const entries = Array.from(this.repos.values()).filter((entry) => entry.source === \"config\");\n const results = await Promise.all(\n entries.map(async (entry) => ({\n name: entry.name,\n result: await this.readConfiguredWorktrees(entry, currentWorktreePath),\n })),\n );\n\n const worktreesByRepo: Record<string, DiscoveredWorktree[]> = {};\n const errorsByRepo: Record<string, string> = {};\n\n for (const entry of results) {\n worktreesByRepo[entry.name] = entry.result.worktrees;\n if (entry.result.error) {\n errorsByRepo[entry.name] = entry.result.error;\n }\n }\n\n return { worktreesByRepo, errorsByRepo };\n }\n\n getConfigPath(): string | null {\n return this.configPath;\n }\n\n private async readConfiguredWorktrees(\n entry: RepoEntry,\n currentWorktreePath: string | null,\n ): Promise<{ worktrees: DiscoveredWorktree[]; error?: string }> {\n if (entry.source === \"config\" && resolveMode(entry.config) === REPOSITORY_MODES.CLONE) {\n return this.readConfiguredCloneWorktree(entry, currentWorktreePath);\n }\n\n if (entry.source !== \"config\" || !entry.config.bareRepoDir) return { worktrees: [] };\n\n const bareRepoPath = path.resolve(entry.config.bareRepoDir);\n if (!(await isDirectory(bareRepoPath))) return { worktrees: [] };\n\n try {\n const output = await simpleGit(bareRepoPath).raw([\"worktree\", \"list\", \"--porcelain\"]);\n return { worktrees: parseWorktreeList(output, currentWorktreePath) };\n } catch (err) {\n return { worktrees: [], error: err instanceof Error ? err.message : String(err) };\n }\n }\n\n private findConfiguredCloneEntry(worktreeRoot: string): RepoEntry | null {\n const foldedRoot = normalizePathForCompare(path.resolve(worktreeRoot));\n for (const entry of this.repos.values()) {\n if (entry.source !== \"config\" || resolveMode(entry.config) !== REPOSITORY_MODES.CLONE) continue;\n if (normalizePathForCompare(path.resolve(entry.config.worktreeDir)) === foldedRoot) {\n return entry;\n }\n }\n return null;\n }\n\n private async buildCloneModeContext(\n entry: RepoEntry,\n worktreeRoot: string,\n notes: string[],\n ): Promise<DiscoveredRepoContext> {\n const resolvedRoot = path.resolve(worktreeRoot);\n let currentBranch: string | null = null;\n try {\n currentBranch = await readCurrentBranch(resolvedRoot);\n } catch (err) {\n notes.push(`Could not read clone-mode branch: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n const branch = currentBranch ?? \"unknown\";\n const cloneModeReason = \"clone-mode repositories have a single checkout; use sync for clone-mode updates\";\n const capabilities: Capabilities = {\n listWorktrees: { available: true },\n getStatus: { available: true },\n createWorktree: { available: false, reason: cloneModeReason },\n removeWorktree: { available: false, reason: cloneModeReason },\n updateWorktree: { available: false, reason: cloneModeReason },\n sync: { available: true },\n initialize: { available: true },\n };\n\n const discovered: DiscoveredRepoContext = {\n isWorktree: true,\n kind: \"managed\",\n currentBranch,\n currentWorktreePath: resolvedRoot,\n bareRepoPath: null,\n repoUrl: entry.config.repoUrl,\n worktreeDir: resolvedRoot,\n allWorktrees: [{ path: resolvedRoot, branch, isCurrent: true }],\n siblingRepositories: [],\n configPath: this.configPath,\n repoName: entry.name,\n capabilities,\n notes,\n };\n\n entry.discovered = discovered;\n this.bootstrapCurrentRepo(entry.name, true);\n return discovered;\n }\n\n private async readConfiguredCloneWorktree(\n entry: RepoEntry,\n currentWorktreePath: string | null,\n ): Promise<{ worktrees: DiscoveredWorktree[]; error?: string }> {\n const worktreePath = path.resolve(entry.config.worktreeDir);\n if (!(await isDirectory(worktreePath)) || !(await hasGitMetadata(worktreePath))) {\n return { worktrees: [] };\n }\n\n try {\n const branch = await readCurrentBranch(worktreePath);\n return {\n worktrees: [\n {\n path: worktreePath,\n branch,\n isCurrent:\n currentWorktreePath !== null &&\n normalizePathForCompare(worktreePath) === normalizePathForCompare(currentWorktreePath),\n },\n ],\n };\n } catch (err) {\n return { worktrees: [], error: err instanceof Error ? err.message : String(err) };\n }\n }\n}\n\nfunction parseWorktreeList(output: string, currentPath: string | null): DiscoveredWorktree[] {\n const foldedCurrent = currentPath ? normalizePathForCompare(currentPath) : null;\n const results: DiscoveredWorktree[] = [];\n for (const wt of parseWorktreeListPorcelain(output)) {\n const resolved = path.resolve(wt.path);\n const branch = wt.branch ?? (wt.detached ? `(detached ${(wt.head ?? \"\").slice(0, 7)})` : null);\n if (!branch) continue;\n results.push({\n path: resolved,\n branch,\n isCurrent: foldedCurrent !== null && normalizePathForCompare(resolved) === foldedCurrent,\n });\n }\n return results;\n}\n\ntype FindResult =\n | { kind: \"worktree-file\"; worktreeRoot: string; gitFileContent: string }\n | { kind: \"regular-git-dir\"; worktreeRoot: string };\n\nasync function safeMtimeMs(filePath: string): Promise<number | null> {\n try {\n const stat = await fs.stat(filePath);\n return stat.mtimeMs;\n } catch {\n return null;\n }\n}\n\nasync function isDirectory(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath);\n return stat.isDirectory();\n } catch {\n return false;\n }\n}\n\nasync function hasGitMetadata(worktreePath: string): Promise<boolean> {\n try {\n await fs.stat(path.join(worktreePath, \".git\"));\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isGitCheckout(checkoutPath: string): Promise<boolean> {\n if (!(await isDirectory(checkoutPath))) return false;\n try {\n const inside = (await simpleGit(checkoutPath).raw([\"rev-parse\", \"--is-inside-work-tree\"])).trim();\n return inside === \"true\";\n } catch {\n return false;\n }\n}\n\nasync function readCurrentBranch(worktreePath: string): Promise<string> {\n const git = simpleGit(worktreePath);\n const branch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n if (branch && branch !== \"HEAD\") {\n return branch;\n }\n\n const head = (await git.raw([\"rev-parse\", \"--short\", \"HEAD\"])).trim();\n return head ? `(detached ${head})` : \"(detached)\";\n}\n\nasync function findWorktreeRoot(startPath: string): Promise<FindResult | null> {\n let current = path.resolve(startPath);\n const root = path.parse(current).root;\n\n while (true) {\n const gitPath = path.join(current, \".git\");\n try {\n const content = await fs.readFile(gitPath, \"utf-8\");\n return { kind: \"worktree-file\", worktreeRoot: current, gitFileContent: content };\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === \"EISDIR\") {\n return { kind: \"regular-git-dir\", worktreeRoot: current };\n }\n if (code !== \"ENOENT\") {\n return null;\n }\n }\n if (current === root) return null;\n const parent = path.dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n}\n", "export const GIT_CONSTANTS = {\n REMOTE_PREFIX: \"origin/\",\n REMOTE_NAME: \"origin\",\n HEAD_REF: \"/HEAD\",\n DEFAULT_BRANCH: \"main\",\n COMMON_DEFAULT_BRANCHES: [\"main\", \"master\", \"develop\", \"trunk\"],\n BARE_DIR_NAME: \".bare\",\n DIVERGED_DIR_NAME: \".diverged\",\n LFS_HEADER: \"version https://git-lfs.github.com/spec/\",\n SUBMODULE_STATUS_ADDED: \"+\",\n SUBMODULE_STATUS_REMOVED: \"-\",\n GITDIR_PREFIX: \"gitdir:\",\n GIT_CHECK_IGNORE_NO_MATCH: \"exit code: 1\",\n REFS: {\n HEADS: \"refs/heads/\",\n REMOTES: \"refs/remotes/origin\",\n REMOTES_ORIGIN: \"refs/remotes/origin/*\",\n },\n FETCH_CONFIG: \"+refs/heads/*:refs/remotes/origin/*\",\n PROGRESS_BUCKET_PERCENT: 25,\n} as const;\n\nexport const GIT_OPERATIONS = {\n MERGE_HEAD: \"MERGE_HEAD\",\n CHERRY_PICK_HEAD: \"CHERRY_PICK_HEAD\",\n REVERT_HEAD: \"REVERT_HEAD\",\n BISECT_LOG: \"BISECT_LOG\",\n REBASE_MERGE: \"rebase-merge\",\n REBASE_APPLY: \"rebase-apply\",\n} as const;\n\nexport const DEFAULT_CONFIG = {\n CRON_SCHEDULE: \"0 * * * *\",\n RETRY: {\n MAX_ATTEMPTS: 3,\n MAX_LFS_RETRIES: 2,\n INITIAL_DELAY_MS: 1000,\n MAX_DELAY_MS: 30000,\n BACKOFF_MULTIPLIER: 2,\n JITTER_MS: 500,\n },\n PARALLELISM: {\n MAX_REPOSITORIES: 2,\n MAX_WORKTREE_CREATION: 1,\n MAX_WORKTREE_UPDATES: 3,\n MAX_WORKTREE_REMOVAL: 3,\n MAX_STATUS_CHECKS: 20,\n MAX_BRANCH_FETCHES: 3,\n MAX_SAFE_TOTAL_CONCURRENT_OPS: 100,\n },\n UPDATE_EXISTING_WORKTREES: true,\n HOOK_TIMEOUT_MS: 60_000,\n FETCH_TIMEOUT_MS: 300_000,\n CLONE_TIMEOUT_MS: 900_000,\n LOCK_STALE_MS: 600_000,\n LOCK_UPDATE_MS: 30_000,\n} as const;\n\nexport const ERROR_MESSAGES = {\n GIT_NOT_INITIALIZED: \"Git service not initialized. Call initialize() first.\",\n ALREADY_EXISTS: \"already exists\",\n ALREADY_REGISTERED: \"already registered worktree\",\n FAST_FORWARD_FAILED: [\n \"Not possible to fast-forward\",\n \"fatal: Not possible to fast-forward, aborting\",\n \"cannot fast-forward\",\n ],\n NO_UPSTREAM: [\n \"fatal: no upstream configured\",\n \"no upstream configured for branch\",\n \"fatal: ambiguous argument\",\n \"unknown revision or path\",\n ],\n LFS_ERROR: [\"smudge filter lfs failed\", \"git-lfs\", \"LFS\"],\n EXDEV: \"EXDEV\",\n} as const;\n\nexport const TEST_TIMEOUT = {\n DEFAULT: 10000,\n E2E: 60000,\n} as const;\n\nexport const ENV_CONSTANTS = {\n GIT_LFS_SKIP_SMUDGE: \"GIT_LFS_SKIP_SMUDGE\",\n GIT_ATTR_SOURCE: \"GIT_ATTR_SOURCE\",\n NODE_ENV_TEST: \"test\",\n} as const;\n\nexport const PATH_CONSTANTS = {\n GIT_DIR: \".git\",\n README: \"README\",\n CLONE_INIT_MARKER: \".sync-worktrees-clone-init\",\n} as const;\n\nexport const CONFIG_FILE_NAMES = [\n \"sync-worktrees.config.js\",\n \"sync-worktrees.config.mjs\",\n \"sync-worktrees.config.cjs\",\n] as const;\n\nexport const METADATA_CONSTANTS = {\n MAX_HISTORY_ENTRIES: 10,\n METADATA_FILENAME: \"sync-metadata.json\",\n WORKTREE_METADATA_PATH: \".git/worktrees\",\n DIVERGED_INFO_FILE: \".diverged-info.json\",\n DIVERGED_REASON: \"diverged-history-with-changes\",\n ACTION_CREATED: \"created\",\n ACTION_UPDATED: \"updated\",\n ACTION_FETCHED: \"fetched\",\n} as const;\n\nexport const TERMINAL_CONSTANTS = {\n ENV_OVERRIDE: \"SYNC_WORKTREES_TERMINAL\",\n ENV_FALLBACK: \"TERMINAL\",\n LINUX_CANDIDATES: [\"gnome-terminal\", \"konsole\", \"alacritty\", \"kitty\", \"xterm\"],\n} as const;\n\nexport const HOOK_CONSTANTS = {\n ENV_PREFIX: \"SYNC_WORKTREES_\",\n ENV_VARS: {\n BRANCH_NAME: \"SYNC_WORKTREES_BRANCH_NAME\",\n WORKTREE_PATH: \"SYNC_WORKTREES_WORKTREE_PATH\",\n REPO_NAME: \"SYNC_WORKTREES_REPO_NAME\",\n BASE_BRANCH: \"SYNC_WORKTREES_BASE_BRANCH\",\n REPO_URL: \"SYNC_WORKTREES_REPO_URL\",\n },\n PLACEHOLDERS: {\n BRANCH_NAME: \"{BRANCH_NAME}\",\n WORKTREE_PATH: \"{WORKTREE_PATH}\",\n REPO_NAME: \"{REPO_NAME}\",\n BASE_BRANCH: \"{BASE_BRANCH}\",\n REPO_URL: \"{REPO_URL}\",\n },\n} as const;\n", "import * as path from \"path\";\nimport { pathToFileURL } from \"url\";\n\nimport * as cron from \"node-cron\";\n\nimport { CONFIG_FILE_NAMES, DEFAULT_CONFIG } from \"../constants\";\nimport { ConfigFileNotFoundError, ConfigValidationError, SyncWorktreesError } from \"../errors\";\nimport { matchesPattern } from \"../utils/branch-filter\";\nimport { fileExists } from \"../utils/file-exists\";\nimport { getDefaultBareRepoDir } from \"../utils/git-url\";\nimport { normalizePathForCompare } from \"../utils/path-compare\";\nimport { REPOSITORY_MODES, isRepositoryMode } from \"../utils/repo-mode\";\nimport { sanitizeNameForPath } from \"../utils/sanitize-name\";\n\nimport type { Config, ConfigFile, RepositoryConfig, RepositoryMode } from \"../types\";\n\nconst CLONE_MODE_CONFLICTING_FIELDS = [\n \"branchInclude\",\n \"branchExclude\",\n \"branchMaxAge\",\n \"updateExistingWorktrees\",\n \"bareRepoDir\",\n] as const satisfies readonly (keyof RepositoryConfig)[];\n\nexport class ConfigLoaderService {\n async findConfigUpward(startDir: string): Promise<string | null> {\n let current = path.resolve(startDir);\n const root = path.parse(current).root;\n\n while (true) {\n for (const name of CONFIG_FILE_NAMES) {\n const candidate = path.join(current, name);\n if (await fileExists(candidate)) {\n return candidate;\n }\n }\n if (current === root) return null;\n const parent = path.dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n }\n\n async loadConfigFile(configPath: string): Promise<ConfigFile> {\n const absolutePath = path.resolve(configPath);\n\n if (!(await fileExists(absolutePath))) {\n throw new ConfigFileNotFoundError(absolutePath);\n }\n\n try {\n const fileUrl = pathToFileURL(absolutePath);\n fileUrl.searchParams.set(\"t\", Date.now().toString());\n const configModule = await import(fileUrl.href);\n const config = configModule.default;\n\n if (!config) {\n throw new Error(\"Config file must use 'export default' syntax\");\n }\n\n this.validateConfigFile(config);\n\n return config;\n } catch (error) {\n if (error instanceof SyncWorktreesError) {\n throw error;\n }\n throw new Error(`Failed to load config file: ${(error as Error).message}`);\n }\n }\n\n private validateConfigFile(config: unknown): asserts config is ConfigFile {\n if (!config || typeof config !== \"object\") {\n throw new Error(\"Config file must export an object\");\n }\n\n const configObj = config as Record<string, unknown>;\n\n if (!Array.isArray(configObj.repositories)) {\n throw new Error(\"Config file must have a 'repositories' array\");\n }\n\n if (configObj.repositories.length === 0) {\n throw new Error(\"Config file must have at least one repository\");\n }\n\n const seenNames = new Set<string>();\n\n configObj.repositories.forEach((repo: unknown, index: number) => {\n if (!repo || typeof repo !== \"object\") {\n throw new Error(`Repository at index ${index} must be an object`);\n }\n\n const repoObj = repo as Record<string, unknown>;\n\n if (!repoObj.name || typeof repoObj.name !== \"string\") {\n throw new Error(`Repository at index ${index} must have a 'name' property`);\n }\n\n if (seenNames.has(repoObj.name)) {\n throw new Error(`Duplicate repository name: ${repoObj.name}`);\n }\n seenNames.add(repoObj.name);\n\n if (!repoObj.repoUrl || typeof repoObj.repoUrl !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' must have a 'repoUrl' property`);\n }\n\n if (!this.isValidGitUrl(repoObj.repoUrl)) {\n throw new Error(\n `Repository '${repoObj.name}' has invalid 'repoUrl': '${repoObj.repoUrl}'. ` +\n `Expected an HTTP(S), SSH, Git protocol URL, or a local/file path (file://, absolute filesystem path)`,\n );\n }\n\n if (!repoObj.worktreeDir || typeof repoObj.worktreeDir !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' must have a 'worktreeDir' property`);\n }\n\n if (repoObj.bareRepoDir !== undefined && typeof repoObj.bareRepoDir !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'bareRepoDir' property`);\n }\n\n if (repoObj.cronSchedule !== undefined && typeof repoObj.cronSchedule !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'cronSchedule' property`);\n }\n\n if (typeof repoObj.cronSchedule === \"string\" && !cron.validate(repoObj.cronSchedule)) {\n throw new Error(`Repository '${repoObj.name}' has invalid cron expression: '${repoObj.cronSchedule}'`);\n }\n\n if (repoObj.runOnce !== undefined && typeof repoObj.runOnce !== \"boolean\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'runOnce' property`);\n }\n\n if (repoObj.debug !== undefined && typeof repoObj.debug !== \"boolean\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'debug' property`);\n }\n\n if (repoObj.retry !== undefined) {\n this.validateRetryConfig(repoObj.retry, `Repository '${repoObj.name}' retry config`);\n }\n\n if (repoObj.filesToCopyOnBranchCreate !== undefined) {\n this.validateFilesToCopyConfig(repoObj.filesToCopyOnBranchCreate, `Repository '${repoObj.name}'`);\n }\n\n if (repoObj.hooks !== undefined) {\n this.validateHooksConfig(repoObj.hooks, `Repository '${repoObj.name}'`);\n }\n\n if (repoObj.sparseCheckout !== undefined) {\n this.validateSparseCheckoutConfig(repoObj.sparseCheckout, `Repository '${repoObj.name}'`);\n }\n\n this.validateDepth(repoObj.depth, `Repository '${repoObj.name}' depth`);\n this.validateRepositoryMode(repoObj, configObj.defaults as Record<string, unknown> | undefined);\n });\n\n this.warnOnDuplicateRepoUrls(configObj.repositories as Array<Record<string, unknown>>);\n\n if (configObj.defaults) {\n if (typeof configObj.defaults !== \"object\") {\n throw new Error(\"'defaults' must be an object\");\n }\n\n const defaults = configObj.defaults as Record<string, unknown>;\n\n if (defaults.cronSchedule !== undefined && typeof defaults.cronSchedule !== \"string\") {\n throw new Error(\"Invalid 'cronSchedule' in defaults\");\n }\n if (typeof defaults.cronSchedule === \"string\" && !cron.validate(defaults.cronSchedule)) {\n throw new Error(`Invalid cron expression in defaults: '${defaults.cronSchedule}'`);\n }\n if (defaults.runOnce !== undefined && typeof defaults.runOnce !== \"boolean\") {\n throw new Error(\"Invalid 'runOnce' in defaults\");\n }\n if (defaults.debug !== undefined && typeof defaults.debug !== \"boolean\") {\n throw new Error(\"Invalid 'debug' in defaults\");\n }\n if (defaults.retry !== undefined && typeof defaults.retry !== \"object\") {\n throw new Error(\"Invalid 'retry' in defaults\");\n }\n if (defaults.retry !== undefined) {\n this.validateRetryConfig(defaults.retry, \"defaults retry config\");\n }\n if (defaults.filesToCopyOnBranchCreate !== undefined) {\n this.validateFilesToCopyConfig(defaults.filesToCopyOnBranchCreate, \"defaults\");\n }\n\n if (defaults.hooks !== undefined) {\n this.validateHooksConfig(defaults.hooks, \"defaults\");\n }\n\n if (defaults.sparseCheckout !== undefined) {\n this.validateSparseCheckoutConfig(defaults.sparseCheckout, \"defaults\");\n }\n\n this.validateDepth(defaults.depth, \"defaults.depth\");\n\n if (defaults.mode !== undefined && !isRepositoryMode(defaults.mode)) {\n throw new ConfigValidationError(\"defaults.mode\", \"must be 'clone' or 'worktree'\");\n }\n\n if (defaults.branch !== undefined && (typeof defaults.branch !== \"string\" || defaults.branch.trim() === \"\")) {\n throw new ConfigValidationError(\"defaults.branch\", \"must be a non-empty string\");\n }\n }\n\n if (configObj.retry !== undefined) {\n this.validateRetryConfig(configObj.retry, \"retry config\");\n }\n\n if (configObj.parallelism !== undefined) {\n this.validateParallelismConfig(configObj.parallelism, \"global\");\n }\n\n if (configObj.defaults && typeof configObj.defaults === \"object\") {\n const defaults = configObj.defaults as Record<string, unknown>;\n if (defaults.parallelism !== undefined) {\n this.validateParallelismConfig(defaults.parallelism, \"defaults\");\n }\n }\n }\n\n private validateDepth(value: unknown, field: string): void {\n if (value === undefined) return;\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value <= 0) {\n throw new ConfigValidationError(field, \"must be a positive safe integer\");\n }\n }\n\n private validateRetryConfig(value: unknown, context: string): void {\n if (typeof value !== \"object\" || value === null) {\n throw new Error(context === \"retry config\" ? \"'retry' must be an object\" : `Invalid 'retry' in ${context}`);\n }\n\n const retry = value as Record<string, unknown>;\n\n if (retry.maxAttempts !== undefined) {\n if (retry.maxAttempts !== \"unlimited\" && (typeof retry.maxAttempts !== \"number\" || retry.maxAttempts < 1)) {\n throw new Error(\"Invalid 'maxAttempts' in retry config. Must be 'unlimited' or a positive number\");\n }\n }\n\n if (retry.maxLfsRetries !== undefined) {\n if (typeof retry.maxLfsRetries !== \"number\" || retry.maxLfsRetries < 0) {\n throw new Error(\"Invalid 'maxLfsRetries' in retry config. Must be a non-negative number\");\n }\n }\n\n if (retry.initialDelayMs !== undefined && (typeof retry.initialDelayMs !== \"number\" || retry.initialDelayMs < 0)) {\n throw new Error(\"Invalid 'initialDelayMs' in retry config\");\n }\n\n if (retry.maxDelayMs !== undefined && (typeof retry.maxDelayMs !== \"number\" || retry.maxDelayMs < 0)) {\n throw new Error(\"Invalid 'maxDelayMs' in retry config\");\n }\n\n if (\n retry.backoffMultiplier !== undefined &&\n (typeof retry.backoffMultiplier !== \"number\" || retry.backoffMultiplier < 1)\n ) {\n throw new Error(\"Invalid 'backoffMultiplier' in retry config\");\n }\n\n if (retry.jitterMs !== undefined && (typeof retry.jitterMs !== \"number\" || retry.jitterMs < 0)) {\n throw new Error(\"Invalid 'jitterMs' in retry config\");\n }\n\n const initialDelay = (retry.initialDelayMs as number) ?? DEFAULT_CONFIG.RETRY.INITIAL_DELAY_MS;\n const maxDelay = (retry.maxDelayMs as number) ?? DEFAULT_CONFIG.RETRY.MAX_DELAY_MS;\n if (initialDelay > maxDelay) {\n throw new Error(\n `Invalid retry config: 'initialDelayMs' (${initialDelay}) must not exceed 'maxDelayMs' (${maxDelay})`,\n );\n }\n }\n\n private validateParallelismConfig(parallelism: unknown, context: string): void {\n if (typeof parallelism !== \"object\" || parallelism === null) {\n throw new Error(`'parallelism' in ${context} must be an object`);\n }\n\n const config = parallelism as Record<string, unknown>;\n\n const positiveIntFields = [\n \"maxRepositories\",\n \"maxWorktreeCreation\",\n \"maxWorktreeUpdates\",\n \"maxWorktreeRemoval\",\n \"maxStatusChecks\",\n \"maxBranchFetches\",\n ] as const;\n\n for (const field of positiveIntFields) {\n const value = config[field];\n if (value !== undefined && (typeof value !== \"number\" || value < 1)) {\n throw new Error(`Invalid '${field}' in ${context} parallelism config. Must be a positive number`);\n }\n }\n\n const maxRepos = (config.maxRepositories as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_REPOSITORIES;\n const maxCreation = (config.maxWorktreeCreation as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_CREATION;\n const maxUpdates = (config.maxWorktreeUpdates as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_UPDATES;\n const maxRemoval = (config.maxWorktreeRemoval as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_REMOVAL;\n const maxStatus = (config.maxStatusChecks as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n\n const maxPerRepoOps = maxCreation + maxUpdates + maxRemoval + maxStatus;\n const totalMaxConcurrent = maxRepos * maxPerRepoOps;\n\n if (totalMaxConcurrent > DEFAULT_CONFIG.PARALLELISM.MAX_SAFE_TOTAL_CONCURRENT_OPS) {\n const safeMaxRepos = Math.floor(DEFAULT_CONFIG.PARALLELISM.MAX_SAFE_TOTAL_CONCURRENT_OPS / maxPerRepoOps);\n throw new Error(\n `Total concurrent operations (${totalMaxConcurrent}) exceeds safe limit (${DEFAULT_CONFIG.PARALLELISM.MAX_SAFE_TOTAL_CONCURRENT_OPS}). ` +\n `With current per-repository limits (creation: ${maxCreation}, updates: ${maxUpdates}, removal: ${maxRemoval}, status: ${maxStatus}), ` +\n `maximum safe maxRepositories is ${safeMaxRepos}. ` +\n `Consider reducing maxRepositories or lowering per-operation limits.`,\n );\n }\n }\n\n private validateFilesToCopyConfig(filesToCopy: unknown, context: string): void {\n if (!Array.isArray(filesToCopy)) {\n throw new Error(`'filesToCopyOnBranchCreate' in ${context} must be an array`);\n }\n\n for (let i = 0; i < filesToCopy.length; i++) {\n const pattern = filesToCopy[i];\n if (typeof pattern !== \"string\" || pattern.trim() === \"\") {\n throw new Error(\n `'filesToCopyOnBranchCreate' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n }\n\n private validateSparseCheckoutConfig(value: unknown, context: string): void {\n if (typeof value !== \"object\" || value === null) {\n throw new Error(`'sparseCheckout' in ${context} must be an object`);\n }\n\n const cfg = value as Record<string, unknown>;\n\n if (!Array.isArray(cfg.include)) {\n throw new Error(`'sparseCheckout.include' in ${context} must be an array`);\n }\n if (cfg.include.length === 0) {\n throw new Error(`'sparseCheckout.include' in ${context} must contain at least one pattern`);\n }\n for (let i = 0; i < cfg.include.length; i++) {\n const p = cfg.include[i];\n if (typeof p !== \"string\" || p.trim() === \"\") {\n throw new Error(\n `'sparseCheckout.include' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n\n if (cfg.exclude !== undefined) {\n if (!Array.isArray(cfg.exclude)) {\n throw new Error(`'sparseCheckout.exclude' in ${context} must be an array`);\n }\n for (let i = 0; i < cfg.exclude.length; i++) {\n const p = cfg.exclude[i];\n if (typeof p !== \"string\" || p.trim() === \"\") {\n throw new Error(\n `'sparseCheckout.exclude' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n }\n\n if (cfg.mode !== undefined && cfg.mode !== \"cone\" && cfg.mode !== \"no-cone\") {\n throw new Error(`'sparseCheckout.mode' in ${context} must be 'cone' or 'no-cone'`);\n }\n }\n\n private warnOnDuplicateRepoUrls(repositories: Array<Record<string, unknown>>): void {\n const seen = new Map<string, string[]>();\n for (const repo of repositories) {\n const url = typeof repo.repoUrl === \"string\" ? repo.repoUrl : null;\n const name = typeof repo.name === \"string\" ? repo.name : null;\n if (!url || !name) continue;\n const list = seen.get(url) ?? [];\n list.push(name);\n seen.set(url, list);\n }\n for (const [url, names] of seen) {\n if (names.length > 1) {\n console.warn(\n `[sync-worktrees] repoUrl '${url}' appears in multiple entries (${names.join(\", \")}). ` +\n `Pin 'bareRepoDir' on duplicate entries to make config reorder-proof.`,\n );\n }\n }\n }\n\n private validateRepositoryMode(\n repoObj: Record<string, unknown>,\n defaults: Record<string, unknown> | undefined,\n ): void {\n const repoName = repoObj.name as string;\n const repoMode = repoObj.mode;\n\n if (repoMode !== undefined && !isRepositoryMode(repoMode)) {\n throw new ConfigValidationError(`Repository '${repoName}' mode`, \"must be 'clone' or 'worktree'\");\n }\n\n if (\n repoObj.branch !== undefined &&\n (typeof repoObj.branch !== \"string\" || (repoObj.branch as string).trim() === \"\")\n ) {\n throw new ConfigValidationError(`Repository '${repoName}' branch`, \"must be a non-empty string\");\n }\n\n const effectiveMode = (repoMode as RepositoryMode | undefined) ?? (defaults?.mode as RepositoryMode | undefined);\n if (effectiveMode !== REPOSITORY_MODES.CLONE) {\n const depthFromRepo = repoObj.depth;\n const depthFromDefaults = defaults?.depth;\n if (depthFromRepo !== undefined || depthFromDefaults !== undefined) {\n const source = depthFromRepo !== undefined ? \"repository\" : \"defaults\";\n throw new ConfigValidationError(\n `Repository '${repoName}' depth`,\n `only supported when mode is 'clone' (set on ${source})`,\n );\n }\n\n const branchFromRepo = repoObj.branch;\n const branchFromDefaults = defaults?.branch;\n if (branchFromRepo !== undefined || branchFromDefaults !== undefined) {\n const source = branchFromRepo !== undefined ? \"repository\" : \"defaults\";\n throw new ConfigValidationError(\n `Repository '${repoName}' branch`,\n `only supported when mode is 'clone' (set on ${source})`,\n );\n }\n\n return;\n }\n\n for (const field of CLONE_MODE_CONFLICTING_FIELDS) {\n const fromRepo = repoObj[field];\n const fromDefaults = defaults?.[field];\n const present = fromRepo !== undefined || fromDefaults !== undefined;\n if (present) {\n const source = fromRepo !== undefined ? \"repository\" : \"defaults\";\n throw new ConfigValidationError(\n `Repository '${repoName}' ${field}`,\n `not supported when mode is 'clone' (set on ${source})`,\n );\n }\n }\n }\n\n private validateHooksConfig(hooks: unknown, context: string): void {\n if (typeof hooks !== \"object\" || hooks === null) {\n throw new Error(`'hooks' in ${context} must be an object`);\n }\n\n const hooksObj = hooks as Record<string, unknown>;\n\n if (hooksObj.onBranchCreated !== undefined) {\n if (!Array.isArray(hooksObj.onBranchCreated)) {\n throw new Error(`'hooks.onBranchCreated' in ${context} must be an array`);\n }\n\n for (let i = 0; i < hooksObj.onBranchCreated.length; i++) {\n const command = hooksObj.onBranchCreated[i];\n if (typeof command !== \"string\" || command.trim() === \"\") {\n throw new Error(\n `'hooks.onBranchCreated' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n }\n }\n\n resolveRepositoryConfig(\n repo: RepositoryConfig,\n defaults?: Partial<Config>,\n configDir?: string,\n globalRetry?: Config[\"retry\"],\n allRepositories?: RepositoryConfig[],\n ): RepositoryConfig {\n const mode: RepositoryMode = repo.mode ?? defaults?.mode ?? REPOSITORY_MODES.WORKTREE;\n\n const resolved: RepositoryConfig = {\n name: repo.name,\n repoUrl: repo.repoUrl,\n worktreeDir: this.resolvePath(repo.worktreeDir, configDir),\n cronSchedule: repo.cronSchedule ?? defaults?.cronSchedule ?? DEFAULT_CONFIG.CRON_SCHEDULE,\n runOnce: repo.runOnce ?? defaults?.runOnce ?? false,\n debug: repo.debug ?? defaults?.debug,\n mode,\n };\n\n if (configDir) {\n resolved.__configFileDir = configDir;\n }\n\n if (mode === REPOSITORY_MODES.CLONE) {\n if (repo.branch ?? defaults?.branch) {\n resolved.branch = repo.branch ?? defaults?.branch;\n }\n if (repo.depth !== undefined || defaults?.depth !== undefined) {\n resolved.depth = repo.depth ?? defaults?.depth;\n }\n } else {\n if (repo.bareRepoDir) {\n resolved.bareRepoDir = this.resolvePath(repo.bareRepoDir, configDir);\n } else if (allRepositories && this.isDuplicateRepoUrl(repo, allRepositories, defaults)) {\n const sanitized = sanitizeNameForPath(repo.name, `Repository '${repo.name}' name`);\n resolved.bareRepoDir = this.resolvePath(`.bare/${sanitized}`, configDir);\n } else {\n resolved.bareRepoDir = this.resolvePath(getDefaultBareRepoDir(repo.repoUrl), configDir);\n }\n\n if (repo.branchMaxAge || defaults?.branchMaxAge) {\n resolved.branchMaxAge = repo.branchMaxAge ?? defaults?.branchMaxAge;\n }\n\n if (repo.branchInclude || defaults?.branchInclude) {\n resolved.branchInclude = repo.branchInclude ?? defaults?.branchInclude;\n }\n\n if (repo.branchExclude || defaults?.branchExclude) {\n resolved.branchExclude = repo.branchExclude ?? defaults?.branchExclude;\n }\n\n if (repo.updateExistingWorktrees !== undefined || defaults?.updateExistingWorktrees !== undefined) {\n resolved.updateExistingWorktrees = repo.updateExistingWorktrees ?? defaults?.updateExistingWorktrees ?? true;\n }\n }\n\n if (repo.skipLfs !== undefined || defaults?.skipLfs !== undefined) {\n resolved.skipLfs = repo.skipLfs ?? defaults?.skipLfs ?? false;\n }\n\n if (repo.retry || defaults?.retry || globalRetry) {\n resolved.retry = {\n ...(globalRetry || {}),\n ...(defaults?.retry || {}),\n ...(repo.retry || {}),\n };\n }\n\n if (repo.parallelism || defaults?.parallelism) {\n resolved.parallelism = {\n ...(defaults?.parallelism || {}),\n ...(repo.parallelism || {}),\n };\n }\n\n if (repo.filesToCopyOnBranchCreate || defaults?.filesToCopyOnBranchCreate) {\n const files = repo.filesToCopyOnBranchCreate ?? defaults?.filesToCopyOnBranchCreate;\n resolved.filesToCopyOnBranchCreate = files?.map((f) => this.resolvePath(f, configDir));\n }\n\n if (repo.hooks || defaults?.hooks) {\n resolved.hooks = {\n ...(defaults?.hooks || {}),\n ...(repo.hooks || {}),\n };\n }\n\n const sparse = repo.sparseCheckout ?? defaults?.sparseCheckout;\n if (sparse) {\n resolved.sparseCheckout = sparse;\n }\n\n return resolved;\n }\n\n private isDuplicateRepoUrl(repo: RepositoryConfig, all: RepositoryConfig[], defaults?: Partial<Config>): boolean {\n const firstIndex = all.findIndex((r) => {\n const mode = r.mode ?? defaults?.mode ?? REPOSITORY_MODES.WORKTREE;\n return r.repoUrl === repo.repoUrl && mode === REPOSITORY_MODES.WORKTREE;\n });\n const myIndex = all.indexOf(repo);\n return firstIndex !== -1 && myIndex !== -1 && myIndex !== firstIndex;\n }\n\n detectBareRepoDirCollisions(repositories: RepositoryConfig[]): void {\n const seen = new Map<string, { name: string; displayPath: string }>();\n for (const repo of repositories) {\n if (!repo.bareRepoDir) continue;\n const key = normalizePathForCompare(repo.bareRepoDir);\n const displayPath = path.resolve(repo.bareRepoDir);\n const existing = seen.get(key);\n if (existing && existing.name !== repo.name) {\n throw new Error(\n `Repositories '${existing.name}' and '${repo.name}' resolve to the same bareRepoDir '${displayPath}'. ` +\n `Set distinct 'bareRepoDir' values for duplicate repoUrl entries.`,\n );\n }\n seen.set(key, { name: repo.name, displayPath });\n }\n }\n\n private isValidGitUrl(url: string): boolean {\n // HTTP(S) URLs\n if (/^https?:\\/\\/.+/.test(url)) return true;\n // SSH URLs (git@host:path or ssh://...)\n if (/^(ssh:\\/\\/|git@).+/.test(url)) return true;\n // Git protocol\n if (/^git:\\/\\/.+/.test(url)) return true;\n // Local file paths (absolute)\n if (/^(file:\\/\\/|\\/|[A-Za-z]:\\\\)/.test(url)) return true;\n return false;\n }\n\n private resolvePath(inputPath: string, baseDir?: string): string {\n if (path.isAbsolute(inputPath)) {\n return inputPath;\n }\n\n return path.resolve(baseDir || process.cwd(), inputPath);\n }\n\n filterRepositories(repositories: RepositoryConfig[], filter?: string): RepositoryConfig[] {\n if (!filter) {\n return repositories;\n }\n\n const patterns = filter.split(\",\").map((p) => p.trim());\n\n return repositories.filter((repo) => {\n return patterns.some((pattern) => matchesPattern(repo.name, pattern));\n });\n }\n\n async buildRepositories(\n configPath: string,\n overrides?: { filter?: string },\n ): Promise<{ repositories: RepositoryConfig[]; configFile: ConfigFile; configDir: string }> {\n const configFile = await this.loadConfigFile(configPath);\n const configDir = path.dirname(path.resolve(configPath));\n\n let repositories = configFile.repositories.map((repo) =>\n this.resolveRepositoryConfig(repo, configFile.defaults, configDir, configFile.retry, configFile.repositories),\n );\n\n this.detectBareRepoDirCollisions(repositories);\n\n if (overrides?.filter) {\n repositories = this.filterRepositories(repositories, overrides.filter);\n }\n\n return { repositories, configFile, configDir };\n }\n}\n", "import { ERROR_MESSAGES } from \"../constants\";\n\nexport class SyncWorktreesError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly cause?: Error,\n ) {\n super(message);\n this.name = this.constructor.name;\n Object.setPrototypeOf(this, new.target.prototype);\n if (cause && cause.stack) {\n this.stack = `${this.stack}\\nCaused by: ${cause.stack}`;\n }\n }\n}\n\nexport class GitError extends SyncWorktreesError {\n constructor(message: string, code: string, cause?: Error) {\n super(message, `GIT_${code}`, cause);\n }\n}\n\nexport class GitNotInitializedError extends GitError {\n constructor() {\n super(ERROR_MESSAGES.GIT_NOT_INITIALIZED, \"NOT_INITIALIZED\");\n }\n}\n\nexport class GitOperationError extends GitError {\n constructor(operation: string, details: string, cause?: Error) {\n super(`Git operation '${operation}' failed: ${details}`, \"OPERATION_FAILED\", cause);\n }\n}\n\nexport class FastForwardError extends GitError {\n constructor(\n public readonly branchName: string,\n cause?: Error,\n ) {\n super(`Cannot fast-forward branch '${branchName}'`, \"FAST_FORWARD_FAILED\", cause);\n }\n}\n\nexport class WorktreeError extends SyncWorktreesError {\n constructor(message: string, code: string, cause?: Error) {\n super(message, `WORKTREE_${code}`, cause);\n }\n}\n\nexport class WorktreeAlreadyExistsError extends WorktreeError {\n constructor(\n public readonly path: string,\n public readonly branchName: string,\n ) {\n super(`Worktree already exists at '${path}' for branch '${branchName}'`, \"ALREADY_EXISTS\");\n }\n}\n\nexport class WorktreeNotCleanError extends WorktreeError {\n constructor(\n public readonly path: string,\n public readonly reasons: string[],\n ) {\n super(`Worktree at '${path}' is not clean: ${reasons.join(\", \")}`, \"NOT_CLEAN\");\n }\n}\n\nexport class ConfigError extends SyncWorktreesError {\n constructor(message: string, code: string, cause?: Error) {\n super(message, `CONFIG_${code}`, cause);\n }\n}\n\nexport class ConfigValidationError extends ConfigError {\n constructor(\n public readonly field: string,\n public readonly reason: string,\n ) {\n super(`Invalid configuration for '${field}': ${reason}`, \"VALIDATION_FAILED\");\n }\n}\n\nexport class ConfigFileNotFoundError extends ConfigError {\n constructor(public readonly configPath: string) {\n super(`Config file not found: ${configPath}`, \"FILE_NOT_FOUND\");\n }\n}\n\nexport class ConfigFileExistsError extends ConfigError {\n constructor(public readonly configPath: string) {\n super(`Config file already exists: ${configPath}`, \"FILE_EXISTS\");\n }\n}\n\nexport class PathResolutionError extends SyncWorktreesError {\n constructor(\n public readonly path: string,\n public readonly reason: string,\n ) {\n super(`Path resolution failed for '${path}': ${reason}`, \"PATH_RESOLUTION_FAILED\");\n }\n}\n\nexport class LfsError extends GitError {\n constructor(message: string, cause?: Error) {\n super(`LFS operation failed: ${message}`, \"LFS_ERROR\", cause);\n }\n}\n\nexport function isLfsError(error: Error | string): boolean {\n const message = typeof error === \"string\" ? error : error.message;\n return ERROR_MESSAGES.LFS_ERROR.some((pattern) => message.includes(pattern));\n}\n\nexport function isFastForwardError(error: Error | string): boolean {\n const message = typeof error === \"string\" ? error : error.message;\n return ERROR_MESSAGES.FAST_FORWARD_FAILED.some((pattern) => message.includes(pattern));\n}\n\nexport function isNoUpstreamError(error: Error | string): boolean {\n const message = typeof error === \"string\" ? error : error.message;\n return ERROR_MESSAGES.NO_UPSTREAM.some((pattern) => message.includes(pattern));\n}\n", "export function matchesPattern(name: string, pattern: string): boolean {\n if (pattern.includes(\"*\")) {\n const escapedPattern = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n const regex = new RegExp(\"^\" + escapedPattern + \"$\");\n return regex.test(name);\n }\n return name === pattern;\n}\n\nexport function filterBranchesByName(branches: string[], include?: string[], exclude?: string[]): string[] {\n let result = branches;\n\n if (include && include.length > 0) {\n result = result.filter((branch) => include.some((pattern) => matchesPattern(branch, pattern)));\n }\n\n if (exclude && exclude.length > 0) {\n result = result.filter((branch) => !exclude.some((pattern) => matchesPattern(branch, pattern)));\n }\n\n return result;\n}\n", "import * as fs from \"fs/promises\";\n\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await fs.access(path);\n return true;\n } catch {\n return false;\n }\n}\n", "/**\n * Extracts the repository name from a Git URL\n * @param gitUrl - The Git URL (HTTPS or SSH format)\n * @returns The repository name without .git extension\n * @throws Error if the URL format is invalid\n */\nexport function extractRepoNameFromUrl(gitUrl: string): string {\n // Remove trailing spaces\n const url = gitUrl.trim();\n\n // Handle SSH format: git@github.com:user/repo.git or ssh://git@domain/path/repo.git\n const sshMatch = url.match(/^git@[^:]+:(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (sshMatch) {\n return sshMatch[1];\n }\n\n // Handle SSH URL format: ssh://git@domain.com/path/repo.git\n const sshUrlMatch = url.match(/^ssh:\\/\\/[^/]+\\/(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (sshUrlMatch) {\n return sshUrlMatch[1];\n }\n\n // Handle HTTPS format: https://github.com/user/repo.git\n const httpsMatch = url.match(/^https?:\\/\\/[^/]+\\/(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (httpsMatch) {\n return httpsMatch[1];\n }\n\n // Handle file:// URLs for local repositories\n const fileMatch = url.match(/^file:\\/\\/(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (fileMatch) {\n return fileMatch[1];\n }\n\n throw new Error(`Invalid Git URL format: ${gitUrl}`);\n}\n\n/**\n * Generates the default bare repository directory path\n * @param repoUrl - The Git repository URL\n * @param baseDir - The base directory for bare repos (default: .bare)\n * @returns The path to the bare repository\n */\nexport function getDefaultBareRepoDir(repoUrl: string, baseDir: string = \".bare\"): string {\n const repoName = extractRepoNameFromUrl(repoUrl);\n return `${baseDir}/${repoName}`;\n}\n\n/**\n * Normalizes a Git remote URL for equivalence comparison only: trims, lowercases\n * a leading `scheme://host`, and strips a trailing slash and a single trailing\n * `.git`. Intentionally does NOT equate scp-style (git@host:path) with https://\n * forms \u2014 those are left distinct. Use only to decide whether two URLs point at\n * the same remote, never as a canonical URL for git operations.\n */\nexport function normalizeRepoUrlForComparison(url: string): string {\n let normalized = url.trim();\n // Only forge-style remotes (http(s)/ssh/git:// and scp git@host:path) treat a\n // trailing \".git\" as optional/equivalent. For file:// and bare local paths,\n // \"foo.git\" and \"foo\" can be genuinely different directories, so we must NOT\n // strip \".git\" there or we'd hide a real origin mismatch.\n const isForgeUrl = /^(https?|ssh|git):\\/\\//i.test(normalized) || /^[\\w.-]+@[^/]+:/.test(normalized);\n normalized = normalized.replace(/^[a-zA-Z][a-zA-Z0-9+.-]*:\\/\\/[^/]+/, (prefix) => prefix.toLowerCase());\n normalized = normalized.replace(/\\/+$/, \"\");\n if (isForgeUrl) {\n normalized = normalized.replace(/\\.git$/, \"\");\n }\n return normalized;\n}\n", "import * as path from \"path\";\n\n// darwin default filesystem (APFS default, HFS+) is case-insensitive.\n// Case-sensitive APFS volumes on macOS exist but are rare; those will see false-positive\n// matches for case-differing paths. Acceptable tradeoff vs breaking the common case.\nconst CASE_INSENSITIVE_PLATFORMS = new Set([\"darwin\"]);\n\nexport function isCaseInsensitiveFs(platform: NodeJS.Platform = process.platform): boolean {\n return CASE_INSENSITIVE_PLATFORMS.has(platform);\n}\n\n/**\n * Normalizes a path for equality comparison.\n *\n * The `platform` argument is a case-sensitivity hint only: it controls whether\n * the resolved path is lower-cased before comparison.\n */\nexport function normalizePathForCompare(p: string, platform: NodeJS.Platform = process.platform): string {\n const resolved = path.resolve(p);\n return isCaseInsensitiveFs(platform) ? resolved.toLowerCase() : resolved;\n}\n\n/**\n * Compares two paths for equality after host-path resolution and platform-aware case folding.\n *\n * The `platform` argument is a case-sensitivity hint only. See\n * {@link normalizePathForCompare} for the caveats about path.resolve semantics.\n */\nexport function pathsEqual(a: string, b: string, platform: NodeJS.Platform = process.platform): boolean {\n return normalizePathForCompare(a, platform) === normalizePathForCompare(b, platform);\n}\n", "import type { Config, RepositoryMode } from \"../types\";\n\nexport const REPOSITORY_MODES = {\n CLONE: \"clone\",\n WORKTREE: \"worktree\",\n} as const satisfies Record<string, RepositoryMode>;\n\nexport function isRepositoryMode(value: unknown): value is RepositoryMode {\n return value === REPOSITORY_MODES.CLONE || value === REPOSITORY_MODES.WORKTREE;\n}\n\nexport function resolveMode(cfg: Pick<Config, \"mode\">): RepositoryMode {\n return cfg.mode ?? REPOSITORY_MODES.WORKTREE;\n}\n", "import { ConfigValidationError } from \"../errors\";\n\nconst WINDOWS_RESERVED = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;\n// eslint-disable-next-line no-control-regex -- Windows reserves \\x00\u2013\\x1f for path validation; intentional\nconst ILLEGAL_CHARS = /[<>:\"|?*\\x00-\\x1f]/g;\n\nexport function sanitizeNameForPath(name: string, fieldContext = \"name\"): string {\n if (!name || typeof name !== \"string\") {\n throw new ConfigValidationError(fieldContext, \"must be a non-empty string\");\n }\n\n let cleaned = name.trim();\n cleaned = cleaned.replace(/[/\\\\]/g, \"-\");\n cleaned = cleaned.replace(/^\\.+/, \"\");\n cleaned = cleaned.replace(ILLEGAL_CHARS, \"_\");\n cleaned = cleaned.replace(/[. ]+$/, \"\");\n\n if (cleaned.length === 0) {\n throw new ConfigValidationError(fieldContext, `'${name}' produces an empty path segment after sanitization`);\n }\n\n if (WINDOWS_RESERVED.test(cleaned)) {\n throw new ConfigValidationError(fieldContext, `'${cleaned}' is a reserved name on Windows`);\n }\n\n return cleaned;\n}\n", "export type LogLevel = \"info\" | \"warn\" | \"error\" | \"debug\";\nexport type LogOutputFn = (message: string, level: LogLevel) => void;\n\nexport interface LoggerOptions {\n repoName?: string;\n debug?: boolean;\n disableColors?: boolean;\n outputFn?: LogOutputFn;\n}\n\nexport class Logger {\n private repoName?: string;\n private debugEnabled: boolean;\n private outputFn?: LogOutputFn;\n\n constructor(options: LoggerOptions = {}) {\n this.repoName = options.repoName;\n this.debugEnabled = options.debug ?? false;\n this.outputFn = options.outputFn;\n }\n\n private prefix(): string {\n return this.repoName ? `[${this.repoName}] ` : \"\";\n }\n\n debug(message: string, ...args: unknown[]): void {\n if (!this.debugEnabled) return;\n const formattedMessage = this.prefix() + this.formatMessage(message, args);\n if (this.outputFn) {\n this.outputFn(formattedMessage, \"debug\");\n } else {\n console.log(formattedMessage);\n }\n }\n\n info(message: string, ...args: unknown[]): void {\n const formattedMessage = this.prefix() + this.formatMessage(message, args);\n if (this.outputFn) {\n this.outputFn(formattedMessage, \"info\");\n } else {\n console.log(formattedMessage);\n }\n }\n\n warn(message: string, ...args: unknown[]): void {\n const formattedMessage = this.prefix() + this.formatMessage(message, args);\n if (this.outputFn) {\n this.outputFn(formattedMessage, \"warn\");\n } else {\n console.warn(formattedMessage);\n }\n }\n\n error(message: string, error?: Error | unknown): void {\n let formattedMessage = this.prefix() + message;\n if (error instanceof Error) {\n formattedMessage += ` ${error.message}`;\n } else if (error) {\n formattedMessage += ` ${String(error)}`;\n }\n if (this.outputFn) {\n this.outputFn(formattedMessage, \"error\");\n } else {\n if (error instanceof Error) {\n console.error(this.prefix() + message, error);\n } else if (error) {\n console.error(this.prefix() + message, error);\n } else {\n console.error(this.prefix() + message);\n }\n }\n }\n\n table(content: string): void {\n const formattedMessage = \"\\n\" + content + \"\\n\";\n if (this.outputFn) {\n this.outputFn(formattedMessage, \"info\");\n } else {\n console.log(formattedMessage);\n }\n }\n\n private formatMessage(message: string, args: unknown[]): string {\n if (args.length === 0) {\n return message;\n }\n\n return args.reduce((msg, arg) => (msg as string).replace(\"%s\", String(arg)), message) as string;\n }\n\n static createDefault(repoName?: string, debug?: boolean): Logger {\n return new Logger({ repoName, debug });\n }\n\n withPassthrough(passthrough: LogOutputFn): Logger {\n const upstream = this.outputFn;\n return new Logger({\n repoName: this.repoName,\n debug: this.debugEnabled,\n outputFn: (msg: string, level: LogLevel): void => {\n if (upstream) {\n upstream(msg, level);\n } else {\n defaultConsoleOutput(msg, level);\n }\n try {\n passthrough(msg, level);\n } catch {\n // swallow - passthrough must never break primary logging\n }\n },\n });\n }\n}\n\nfunction defaultConsoleOutput(msg: string, level: LogLevel): void {\n if (level === \"warn\") console.warn(msg);\n else if (level === \"error\") console.error(msg);\n else console.log(msg);\n}\n", "/**\n * Extracts error message from unknown error type\n * @param error The error to extract message from\n * @returns The error message string\n */\nexport function getErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (error && typeof error === \"object\" && \"message\" in error) {\n return String((error as { message: unknown }).message);\n }\n return String(error);\n}\n\n/**\n * Common LFS error patterns that indicate Git LFS-related failures\n */\nexport const LFS_ERROR_PATTERNS = Object.freeze([\n \"smudge filter lfs failed\",\n \"Object does not exist on the server\",\n \"external filter 'git-lfs filter-process' failed\",\n] as const);\n\n/**\n * Checks if an error message contains any known LFS error patterns\n * @param errorMessage The error message to check\n * @returns true if the error is related to Git LFS\n */\nexport function isLfsError(errorMessage: string): boolean {\n return LFS_ERROR_PATTERNS.some((pattern) => errorMessage.includes(pattern));\n}\n\n/**\n * Checks if an error object contains any known LFS error patterns\n * @param error The error object to check\n * @returns true if the error is related to Git LFS\n */\nexport function isLfsErrorFromError(error: unknown): boolean {\n return isLfsError(getErrorMessage(error));\n}\n\n/**\n * git stderr fragments that indicate the requested remote ref does not exist\n * (e.g. the tracked branch was deleted on the remote). Matched as substrings;\n * callers force LC_ALL=C so these stay deterministic English.\n */\nexport const MISSING_REMOTE_REF_PATTERNS = Object.freeze([\n \"couldn't find remote ref\",\n \"Couldn't find remote ref\",\n \"not our ref\",\n] as const);\n\n/**\n * Checks if an error message indicates a missing remote ref.\n * @param errorMessage The error message to check\n * @returns true if the message indicates the remote ref is gone\n */\nexport function isMissingRemoteRefError(errorMessage: string): boolean {\n return MISSING_REMOTE_REF_PATTERNS.some((pattern) => errorMessage.includes(pattern));\n}\n", "import { isLfsErrorFromError } from \"./lfs-error\";\n\ninterface ErrorWithCode {\n code?: string;\n message?: string;\n}\n\nexport interface LfsErrorContext {\n isLfsError: boolean;\n}\n\nexport interface RetryOptions {\n maxAttempts?: number | \"unlimited\";\n maxLfsRetries?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n backoffMultiplier?: number;\n /**\n * Add random jitter to retry delays to prevent thundering herd problem\n * in concurrent operations. Jitter is a random value between 0 and jitterMs\n * added to the calculated delay.\n *\n * Recommended for parallel operations to spread out retries.\n * Default: 0 (no jitter)\n */\n jitterMs?: number;\n shouldRetry?: (error: unknown, context?: LfsErrorContext) => boolean;\n onRetry?: (error: unknown, attempt: number, context?: LfsErrorContext) => void;\n lfsRetryHandler?: (context: LfsErrorContext) => void;\n}\n\nconst DEFAULT_OPTIONS: Required<Omit<RetryOptions, \"maxAttempts\">> & { maxAttempts: number | \"unlimited\" } = {\n maxAttempts: \"unlimited\",\n maxLfsRetries: 2,\n initialDelayMs: 1000,\n maxDelayMs: 600000, // 10 minutes\n backoffMultiplier: 2,\n jitterMs: 0,\n shouldRetry: (error, context) => {\n const err = error as ErrorWithCode;\n\n // Check for LFS errors\n if (isLfsErrorFromError(error)) {\n if (context) {\n context.isLfsError = true;\n }\n return true;\n }\n\n if (err.code === \"ENOTFOUND\" || err.code === \"ECONNREFUSED\" || err.code === \"ETIMEDOUT\") {\n return true;\n }\n\n if (err.code === \"EBUSY\" || err.code === \"ENOENT\" || err.code === \"EACCES\") {\n return true;\n }\n\n if (err.message?.includes(\"Could not read from remote repository\")) {\n return true;\n }\n\n if (err.message?.includes(\"fatal: unable to access\")) {\n return true;\n }\n\n return false;\n },\n onRetry: () => {},\n lfsRetryHandler: (_context) => {},\n};\n\nexport async function retry<T>(fn: () => Promise<T>, options: RetryOptions = {}): Promise<T> {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n let attempt = 1;\n let lfsAttempt = 0;\n const lfsContext: LfsErrorContext = { isLfsError: false };\n\n while (true) {\n try {\n return await fn();\n } catch (error) {\n // Reset LFS error flag for each attempt\n lfsContext.isLfsError = false;\n\n // Check if we should retry\n if (!opts.shouldRetry(error, lfsContext)) {\n throw error;\n }\n\n // Track LFS attempts separately\n if (lfsContext.isLfsError) {\n lfsAttempt++;\n\n // Check if we've exceeded LFS retry limit\n if (lfsAttempt > opts.maxLfsRetries) {\n const err = error as Error;\n throw new Error(\n `LFS error retry limit exceeded (${opts.maxLfsRetries} attempts). ` +\n `Consider using --skip-lfs option to bypass LFS downloads.`,\n { cause: err },\n );\n }\n }\n\n const isLastAttempt = opts.maxAttempts !== \"unlimited\" && attempt >= opts.maxAttempts;\n if (isLastAttempt) {\n throw error;\n }\n\n // Handle LFS errors specifically\n if (lfsContext.isLfsError && opts.lfsRetryHandler) {\n opts.lfsRetryHandler(lfsContext);\n }\n\n const baseDelay = Math.min(opts.initialDelayMs * Math.pow(opts.backoffMultiplier, attempt - 1), opts.maxDelayMs);\n\n // Add jitter to prevent thundering herd in concurrent operations\n // Jitter is a random value between 0 and jitterMs\n const jitter = opts.jitterMs > 0 ? Math.random() * opts.jitterMs : 0;\n const delay = baseDelay + jitter;\n\n opts.onRetry(error, attempt, lfsContext);\n\n await new Promise((resolve) => setTimeout(resolve, delay));\n attempt++;\n }\n }\n}\n", "import Table from \"cli-table3\";\n\nexport interface TimingResult {\n name: string;\n duration: number;\n count?: number;\n efficiency?: number;\n}\n\nexport class Timer {\n private startTime: number;\n private endTime?: number;\n\n constructor() {\n this.startTime = Date.now();\n }\n\n stop(): number {\n this.endTime = Date.now();\n return this.getDuration();\n }\n\n getDuration(): number {\n const end = this.endTime ?? Date.now();\n return end - this.startTime;\n }\n}\n\nexport class PhaseTimer {\n private phases: Map<string, { timer: Timer; count?: number; parallelism?: number }> = new Map();\n private currentPhase?: string;\n\n startPhase(name: string, parallelism?: number): void {\n if (this.currentPhase) {\n this.endPhase();\n }\n this.currentPhase = name;\n this.phases.set(name, { timer: new Timer(), parallelism });\n }\n\n endPhase(): void {\n if (this.currentPhase) {\n const phase = this.phases.get(this.currentPhase);\n if (phase) {\n phase.timer.stop();\n }\n this.currentPhase = undefined;\n }\n }\n\n setPhaseCount(name: string, count: number): void {\n const phase = this.phases.get(name);\n if (phase) {\n phase.count = count;\n }\n }\n\n getResults(): TimingResult[] {\n if (this.currentPhase) {\n this.endPhase();\n }\n\n const results: TimingResult[] = [];\n\n for (const [name, { timer, count, parallelism }] of this.phases.entries()) {\n const duration = timer.getDuration();\n const result: TimingResult = {\n name,\n duration,\n count,\n };\n\n if (count && count > 0 && parallelism && parallelism > 1) {\n const batches = Math.ceil(count / parallelism);\n const avgTimePerBatch = duration / batches;\n const theoreticalSequentialTime = count * avgTimePerBatch;\n result.efficiency =\n theoreticalSequentialTime > 0 ? Math.round((theoreticalSequentialTime / duration) * 100) : 100;\n }\n\n results.push(result);\n }\n\n return results;\n }\n}\n\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${minutes}m ${seconds}s`;\n}\n\nexport function formatTimingTable(totalDuration: number, phaseResults: TimingResult[], repoName?: string): string {\n const header = repoName ? `Performance Summary - [${repoName}]` : \"Performance Summary\";\n\n const table = new Table({\n head: [\"Operation\", \"Duration\", \"Efficiency\"],\n colWidths: [35, 12, 12],\n style: {\n head: [\"cyan\", \"bold\"],\n border: [\"gray\"],\n },\n });\n\n table.push([{ colSpan: 3, content: header, hAlign: \"center\" }]);\n\n table.push([\"Total Sync\", formatDuration(totalDuration), \"\"]);\n\n for (let i = 0; i < phaseResults.length; i++) {\n const result = phaseResults[i];\n const isLast = i === phaseResults.length - 1;\n const countStr = result.count ? ` (${result.count})` : \"\";\n const prefix = isLast ? \"\u2514\u2500\" : \"\u251C\u2500\";\n const name = ` ${prefix} ${result.name}${countStr}`;\n const efficiency = result.efficiency ? `${result.efficiency}%` : \"\";\n\n table.push([name, formatDuration(result.duration), efficiency]);\n }\n\n return table.toString();\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { DEFAULT_CONFIG, ENV_CONSTANTS, PATH_CONSTANTS } from \"../constants\";\nimport { ConfigError } from \"../errors\";\nimport { fileExists } from \"../utils/file-exists\";\nimport { makeGitProgressHandler } from \"../utils/git-progress\";\nimport { normalizeRepoUrlForComparison } from \"../utils/git-url\";\nimport { getErrorMessage, isLfsError, isMissingRemoteRefError } from \"../utils/lfs-error\";\n\nimport { BranchCreatedActionsService } from \"./branch-created-actions.service\";\nimport { cloneSkipToOutcomeAction } from \"./sync-outcome\";\n\nimport type { GitService } from \"./git.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { SyncOutcomeAccumulator } from \"./sync-outcome\";\nimport type { Config, RepositoryConfig } from \"../types\";\nimport type { GitProgressEmitter, GitProgressEvent } from \"../utils/git-progress\";\nimport type { SimpleGit, SimpleGitOptions } from \"simple-git\";\n\nconst ALL_REMOTE_BRANCHES_REFSPEC = \"+refs/heads/*:refs/remotes/origin/*\";\nconst SHALLOW_RELATION_DEEPEN_TARGETS = [50, 200, 1000] as const;\n\nexport type CloneSkipReason =\n | { kind: \"branch_mismatch\"; phase: \"init\" | \"sync\"; currentBranch: string; expectedBranch: string }\n | { kind: \"head_unreadable\"; phase: \"init\" | \"sync\"; error: string }\n | { kind: \"dirty_tree\" }\n | { kind: \"diverged\"; branch: string }\n | { kind: \"ahead_unpushed\"; branch: string }\n | { kind: \"missing_remote_ref\"; branch: string; source: \"fetch_error\" | \"post_fetch_verify\" }\n | { kind: \"indeterminate_shallow\"; branch: string; deepenedTo: number | null }\n | { kind: \"origin_mismatch\"; actual: string; expected: string };\n\nexport type CloneSkipListener = (reason: CloneSkipReason) => void;\n\nexport class CloneSyncService {\n private initialized = false;\n private resolvedBranch: string | null = null;\n private branchCreatedActions: BranchCreatedActionsService;\n private progressEmitter?: GitProgressEmitter;\n private onSkip?: CloneSkipListener;\n private outcomeAccumulator?: SyncOutcomeAccumulator;\n // One-shot suppression token. When init records a wrong-branch / unreadable-HEAD\n // skip for an existing clone, it sets this so the immediately following\n // runSyncAttempt (same sync operation) does not record the identical skip again.\n private pendingInitSkip: CloneSkipReason | null = null;\n\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger,\n options: {\n branchCreatedActions?: BranchCreatedActionsService;\n progressEmitter?: GitProgressEmitter;\n onSkip?: CloneSkipListener;\n } = {},\n ) {\n this.branchCreatedActions = options.branchCreatedActions ?? new BranchCreatedActionsService();\n this.progressEmitter = options.progressEmitter;\n this.onSkip = options.onSkip;\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n clearPendingInitSkip(): void {\n this.pendingInitSkip = null;\n }\n\n async getWorktrees(): Promise<Array<{ path: string; branch: string }>> {\n const worktreeDir = path.resolve(this.config.worktreeDir);\n if (!(await fileExists(path.join(worktreeDir, PATH_CONSTANTS.GIT_DIR)))) {\n return [];\n }\n\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n let branch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n\n if (!branch || branch === \"HEAD\") {\n const head = (await git.raw([\"rev-parse\", \"--short\", \"HEAD\"])).trim();\n branch = head ? `(detached ${head})` : \"(detached)\";\n }\n\n return [{ path: worktreeDir, branch }];\n }\n\n private get repoName(): string {\n return (this.config as RepositoryConfig).name ?? this.config.repoUrl;\n }\n\n private getCloneTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.cloneTimeoutMs ?? DEFAULT_CONFIG.CLONE_TIMEOUT_MS;\n }\n\n private getFetchTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.fetchTimeoutMs ?? DEFAULT_CONFIG.FETCH_TIMEOUT_MS;\n }\n\n private isLfsSkipEnabled(): boolean {\n return this.config.skipLfs === true;\n }\n\n private buildGitOptions(blockMs: number): Partial<SimpleGitOptions> {\n const options: Partial<SimpleGitOptions> = {\n progress: makeGitProgressHandler(this.logger, (event) => this.emitProgress(event)),\n };\n if (blockMs > 0) options.timeout = { block: blockMs };\n return options;\n }\n\n private emitProgress(event: GitProgressEvent): void {\n try {\n this.progressEmitter?.(event);\n } catch {\n // progress listeners must not break sync flow\n }\n }\n\n private async withOutcome<T>(outcome: SyncOutcomeAccumulator | undefined, operation: () => Promise<T>): Promise<T> {\n const previousOutcome = this.outcomeAccumulator;\n if (outcome) {\n this.outcomeAccumulator = outcome;\n }\n\n try {\n return await operation();\n } finally {\n if (outcome) {\n this.outcomeAccumulator = previousOutcome;\n }\n }\n }\n\n private recordSkip(\n reason: CloneSkipReason,\n logMessage: string,\n progressMessage?: string,\n logLevel: \"warn\" | \"info\" = \"warn\",\n ): void {\n if (logLevel === \"warn\") {\n this.logger.warn(logMessage);\n } else {\n this.logger.info(logMessage);\n }\n this.emitProgress({ phase: \"skip\", message: progressMessage ?? logMessage });\n try {\n this.onSkip?.(reason);\n } catch {\n // listeners must not break sync flow\n }\n this.outcomeAccumulator?.add(\n cloneSkipToOutcomeAction(reason, {\n branch: this.resolvedBranch ?? this.config.branch,\n path: this.config.worktreeDir,\n }),\n );\n }\n\n private clientFor(dir: string, blockMs: number): SimpleGit {\n return simpleGit(dir, this.buildGitOptions(blockMs)).env(this.buildGitEnv());\n }\n\n // Force a stable C locale so git's stderr is deterministic English. The\n // missing-remote-ref and LFS error classification matches on those strings\n // and would otherwise misfire under a non-English LANG/LC_ALL. simple-git's\n // .env() merges this object with process.env (PATH etc. preserved).\n private buildGitEnv(opts: { forceLfsSkip?: boolean } = {}): Record<string, string> {\n const env: Record<string, string> = { LC_ALL: \"C\", LANG: \"C\" };\n if (opts.forceLfsSkip || this.isLfsSkipEnabled()) {\n env[ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE] = \"1\";\n }\n return env;\n }\n\n private buildCloneArgs(branch: string): string[] {\n const args = [\"--branch\", branch, \"--progress\"];\n if (this.config.depth !== undefined) {\n args.push(\"--depth\", String(this.config.depth), \"--no-single-branch\");\n }\n return args;\n }\n\n private async buildFetchArgs(git: SimpleGit): Promise<string[]> {\n const args = [\"origin\", \"--prune\", \"--progress\"];\n if (this.config.depth !== undefined && (await this.isShallowRepository(git))) {\n args.push(\"--depth\", String(this.config.depth));\n }\n return args;\n }\n\n private async ensureAllRemoteBranchesRefspec(git: SimpleGit): Promise<void> {\n let fetchRefspecs: string[] = [];\n try {\n const output = await git.raw([\"config\", \"--get-all\", \"remote.origin.fetch\"]);\n fetchRefspecs = output\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean);\n } catch {\n fetchRefspecs = [];\n }\n\n if (fetchRefspecs.includes(ALL_REMOTE_BRANCHES_REFSPEC)) return;\n\n const customRefspecs = fetchRefspecs.filter((refspec) => !this.isOriginRemoteBranchTrackingRefspec(refspec));\n\n this.logger.info(`Configuring '${this.repoName}' to fetch all remote branches from origin.`);\n await git.raw([\"remote\", \"set-branches\", \"origin\", \"*\"]);\n for (const refspec of customRefspecs) {\n await git.raw([\"config\", \"--add\", \"remote.origin.fetch\", refspec]);\n }\n }\n\n private isOriginRemoteBranchTrackingRefspec(refspec: string): boolean {\n const withoutForce = refspec.startsWith(\"+\") ? refspec.slice(1) : refspec;\n if (withoutForce.startsWith(\"^\")) return false;\n\n const [source, destination] = withoutForce.split(\":\");\n return source.startsWith(\"refs/heads/\") && destination?.startsWith(\"refs/remotes/origin/\") === true;\n }\n\n private recordMissingRemoteRefSkip(branch: string): void {\n this.recordSkip(\n { kind: \"missing_remote_ref\", branch, source: \"fetch_error\" },\n `Tracked branch '${branch}' is missing on remote for '${this.repoName}'. Skipping sync.`,\n `Skipping '${this.repoName}': origin/${branch} is missing`,\n );\n }\n\n private async fetchWithRecovery(\n git: SimpleGit,\n fetchArgs: string[],\n worktreeDir: string,\n branch: string,\n ): Promise<{ skipped: boolean }> {\n try {\n await git.fetch(fetchArgs);\n return { skipped: false };\n } catch (fetchError) {\n const message = getErrorMessage(fetchError);\n if (isLfsError(message)) {\n this.logger.info(`\u26A0\uFE0F LFS error during fetch for '${this.repoName}'; retrying with LFS disabled.`);\n this.emitProgress({ phase: \"fetch\", message: `Retrying fetch for '${this.repoName}' with LFS disabled` });\n const lfsSkipGit = simpleGit(worktreeDir, this.buildGitOptions(this.getFetchTimeoutMs())).env(\n this.buildGitEnv({ forceLfsSkip: true }),\n );\n try {\n await lfsSkipGit.fetch(fetchArgs);\n return { skipped: false };\n } catch (retryError) {\n // The LFS-disabled retry can itself hit a deleted remote branch \u2014\n // classify it as a soft skip too, instead of letting it escape as a\n // hard failure.\n if (isMissingRemoteRefError(getErrorMessage(retryError))) {\n this.recordMissingRemoteRefSkip(branch);\n return { skipped: true };\n }\n // Otherwise propagate the retry error unchanged so the outer retry\n // policy's LFS handling still sees an accurate error.\n throw retryError;\n }\n }\n if (isMissingRemoteRefError(message)) {\n this.recordMissingRemoteRefSkip(branch);\n return { skipped: true };\n }\n throw fetchError;\n }\n }\n\n private async hasRemoteBranch(git: SimpleGit, branch: string): Promise<boolean> {\n try {\n // simple-git resolves `show-ref --quiet` even when git exits 1, so keep\n // stdout enabled (no --quiet) to get a real reject on a missing ref \u2014\n // otherwise the post-fetch missing_remote_ref skip would never fire.\n await git.raw([\"show-ref\", \"--verify\", `refs/remotes/origin/${branch}`]);\n return true;\n } catch {\n return false;\n }\n }\n\n private async isShallowRepository(git: SimpleGit): Promise<boolean> {\n try {\n const output = await git.raw([\"rev-parse\", \"--is-shallow-repository\"]);\n return output.trim() === \"true\";\n } catch {\n return false;\n }\n }\n\n private async unshallowIfDepthRemoved(git: SimpleGit): Promise<void> {\n if (this.config.depth !== undefined) return;\n\n if (!(await this.isShallowRepository(git))) return;\n\n this.logger.info(\n `[deepen] Existing shallow clone for '${this.repoName}' has no configured depth; fetching full history...`,\n );\n await git.fetch([\"--unshallow\"]);\n }\n\n private getDeepenTargets(): readonly number[] {\n const configuredDepth = this.config.depth;\n if (configuredDepth === undefined) return [];\n // `git fetch --depth N` can shorten a shallow repo if N is below current depth.\n // Skip targets at or below the configured depth \u2014 they would never widen history.\n return SHALLOW_RELATION_DEEPEN_TARGETS.filter((target) => target > configuredDepth);\n }\n\n private async deepenShallowHistoryToDepth(git: SimpleGit, branch: string, targetDepth: number): Promise<void> {\n this.logger.info(\n `[deepen] Shallow clone for '${this.repoName}' lacks enough history to classify origin/${branch}; ` +\n `refetching to depth ${targetDepth} before deciding.`,\n );\n this.emitProgress({\n phase: \"fetch\",\n message: `Deepening '${this.repoName}' to depth ${targetDepth} before classifying origin/${branch}`,\n });\n await git.fetch([\n \"origin\",\n \"--depth\",\n String(targetDepth),\n \"--prune\",\n \"--progress\",\n `+refs/heads/${branch}:refs/remotes/origin/${branch}`,\n ]);\n }\n\n async resolveBranch(): Promise<string> {\n if (this.resolvedBranch) return this.resolvedBranch;\n if (this.config.branch) {\n this.resolvedBranch = this.config.branch;\n this.emitProgress({ phase: \"branch\", message: `Using configured branch '${this.resolvedBranch}'` });\n return this.resolvedBranch;\n }\n this.logger.info(`No branch configured for '${this.repoName}', detecting remote default branch...`);\n this.emitProgress({ phase: \"branch\", message: `Resolving remote default branch for '${this.repoName}'` });\n this.resolvedBranch = await this.gitService.getRemoteDefaultBranch(this.config.repoUrl);\n this.logger.info(` \u21B3 resolved default branch: ${this.resolvedBranch}`);\n this.emitProgress({ phase: \"branch\", message: `Resolved default branch '${this.resolvedBranch}'` });\n return this.resolvedBranch;\n }\n\n async initialize(outcome?: SyncOutcomeAccumulator): Promise<void> {\n return this.withOutcome(outcome, () => this.initializeInternal());\n }\n\n private async initializeInternal(): Promise<void> {\n this.pendingInitSkip = null;\n const branch = await this.resolveBranch();\n const worktreeDir = this.config.worktreeDir;\n\n let entries: string[] | null = null;\n try {\n entries = await fs.readdir(worktreeDir);\n } catch {\n entries = null;\n }\n\n if (entries?.includes(PATH_CONSTANTS.GIT_DIR)) {\n this.emitProgress({ phase: \"clone\", message: `Validating existing clone for '${this.repoName}'` });\n const result = await this.validateExistingClone(branch);\n if (!result.valid) {\n this.recordSkip(result.skip, result.warnMessage, `Skipping '${this.repoName}': ${result.progressDetail}`);\n this.pendingInitSkip = result.skip;\n this.initialized = true;\n return;\n }\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n await this.ensureAllRemoteBranchesRefspec(git);\n this.initialized = true;\n this.emitProgress({ phase: \"clone\", message: `Existing clone validated for '${this.repoName}'` });\n return;\n }\n\n if (entries && entries.length > 0) {\n throw new ConfigError(\n `Cannot clone into '${worktreeDir}': directory exists and is not empty. ` +\n `Remove existing contents or point worktreeDir at an empty path.`,\n \"CLONE_DESTINATION_NOT_EMPTY\",\n );\n }\n\n const cloneCreatedDir = entries === null;\n await fs.mkdir(worktreeDir, { recursive: true });\n\n this.logger.info(`Cloning '${this.config.repoUrl}' (${branch}) into '${worktreeDir}'...`);\n this.emitProgress({ phase: \"clone\", message: `Cloning '${this.repoName}' (${branch})` });\n\n const cloneClient = simpleGit(this.buildGitOptions(this.getCloneTimeoutMs())).env(this.buildGitEnv());\n\n try {\n await cloneClient.clone(this.config.repoUrl, worktreeDir, this.buildCloneArgs(branch));\n } catch (error) {\n await this.maybeCleanupPartialClone(worktreeDir, cloneCreatedDir);\n this.outcomeAccumulator?.recordFailed(\"repo\", getErrorMessage(error), {\n reason: \"clone_failed\",\n branch,\n path: worktreeDir,\n });\n throw error;\n }\n\n const worktreeGit = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n await this.ensureAllRemoteBranchesRefspec(worktreeGit);\n\n this.logger.info(`\u2705 Clone successful.`);\n this.emitProgress({ phase: \"clone\", message: `Clone successful for '${this.repoName}'` });\n\n if (this.config.sparseCheckout) {\n this.logger.info(`Applying sparse-checkout patterns to '${worktreeDir}'...`);\n this.emitProgress({ phase: \"sparse_checkout\", message: `Applying sparse-checkout for '${this.repoName}'` });\n const sparseService = this.gitService.getSparseCheckoutService();\n await sparseService.applyToWorktree(worktreeDir, this.config.sparseCheckout);\n await worktreeGit.raw([\"checkout\", \"HEAD\"]);\n this.emitProgress({ phase: \"sparse_checkout\", message: `Sparse-checkout applied for '${this.repoName}'` });\n }\n\n this.emitProgress({ phase: \"lfs\", message: `Verifying LFS for '${this.repoName}'` });\n await this.gitService.verifyLfs(worktreeDir, branch);\n this.emitProgress({ phase: \"lfs\", message: `LFS verified for '${this.repoName}'` });\n\n await this.runInitialFileCopy(worktreeDir, branch);\n\n // Only record `created` once init is fully complete; otherwise an aborted\n // post-clone step would leave the outcome reporting both created and failed.\n this.outcomeAccumulator?.recordCreated(branch, worktreeDir);\n this.initialized = true;\n }\n\n // Detects an on-disk clone whose `origin` no longer matches the configured\n // repoUrl (e.g. repoUrl was repointed in config). Returns a skip descriptor so\n // we never fetch/ff-merge from the wrong remote; null when origin matches or\n // can't be read. Comparison is normalized so https/.git/trailing-slash\n // variants don't false-positive; the raw URLs are kept in the message.\n private async evaluateOriginMatch(\n git: SimpleGit,\n worktreeDir: string,\n ): Promise<{ skip: CloneSkipReason; warnMessage: string; progressDetail: string } | null> {\n let originUrl: string;\n try {\n originUrl = (await git.raw([\"remote\", \"get-url\", \"origin\"])).trim();\n } catch {\n this.logger.warn(`Could not read 'origin' remote URL from existing clone at '${worktreeDir}'.`);\n return null;\n }\n\n if (!originUrl || normalizeRepoUrlForComparison(originUrl) === normalizeRepoUrlForComparison(this.config.repoUrl)) {\n return null;\n }\n\n return {\n skip: { kind: \"origin_mismatch\", actual: originUrl, expected: this.config.repoUrl },\n warnMessage:\n `Existing clone at '${worktreeDir}' has origin '${originUrl}', expected '${this.config.repoUrl}'. ` +\n `Update the remote ('git remote set-url origin <url>') or point worktreeDir at a fresh path.`,\n progressDetail: `origin '${originUrl}' is not '${this.config.repoUrl}'`,\n };\n }\n\n private async validateExistingClone(\n expectedBranch: string,\n ): Promise<{ valid: true } | { valid: false; skip: CloneSkipReason; warnMessage: string; progressDetail: string }> {\n const worktreeDir = this.config.worktreeDir;\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n\n const originMismatch = await this.evaluateOriginMatch(git, worktreeDir);\n if (originMismatch) {\n return { valid: false, ...originMismatch };\n }\n\n let currentBranch: string;\n try {\n currentBranch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n return {\n valid: false,\n skip: { kind: \"head_unreadable\", phase: \"init\", error: errorMessage },\n warnMessage: `Existing clone at '${worktreeDir}' has a .git folder but reading HEAD failed: ${errorMessage}`,\n progressDetail: `could not read HEAD (${errorMessage})`,\n };\n }\n\n if (currentBranch !== expectedBranch) {\n return {\n valid: false,\n skip: {\n kind: \"branch_mismatch\",\n phase: \"init\",\n currentBranch,\n expectedBranch,\n },\n warnMessage:\n `Existing clone at '${worktreeDir}' is on branch '${currentBranch}', expected '${expectedBranch}'. ` +\n `Switch the working tree to '${expectedBranch}' or update the config.`,\n progressDetail: `current branch '${currentBranch}' is not '${expectedBranch}'`,\n };\n }\n\n return { valid: true };\n }\n\n private async maybeCleanupPartialClone(worktreeDir: string, cloneCreatedDir: boolean): Promise<void> {\n if (!cloneCreatedDir) {\n this.logger.warn(\n `Clone failed; leaving '${worktreeDir}' for manual inspection (directory existed before clone attempt).`,\n );\n return;\n }\n\n let entries: string[];\n try {\n entries = await fs.readdir(worktreeDir);\n } catch {\n return;\n }\n\n const looksIncomplete = entries.every((e) => e.startsWith(\".\"));\n const hasUsableGit =\n entries.includes(PATH_CONSTANTS.GIT_DIR) &&\n (await fileExists(path.join(worktreeDir, PATH_CONSTANTS.GIT_DIR, \"HEAD\")));\n\n if (looksIncomplete && !hasUsableGit) {\n try {\n await fs.rm(worktreeDir, { recursive: true, force: true });\n this.logger.info(`Cleaned up incomplete clone at '${worktreeDir}'.`);\n } catch (rmError) {\n this.logger.warn(`Failed to clean up incomplete clone at '${worktreeDir}': ${getErrorMessage(rmError)}`);\n }\n } else {\n this.logger.warn(\n `Clone failed; leaving '${worktreeDir}' for manual inspection (post-failure contents do not look like an empty incomplete clone).`,\n );\n }\n }\n\n private getInitMarkerPath(worktreeDir: string): string {\n return path.join(worktreeDir, PATH_CONSTANTS.GIT_DIR, PATH_CONSTANTS.CLONE_INIT_MARKER);\n }\n\n private async runInitialFileCopy(worktreeDir: string, branch: string): Promise<void> {\n const marker = this.getInitMarkerPath(worktreeDir);\n if (await fileExists(marker)) {\n return;\n }\n\n const sourceDir = this.config.__configFileDir ?? worktreeDir;\n\n await this.branchCreatedActions.copyFiles({\n config: this.config,\n branchName: branch,\n worktreePath: worktreeDir,\n sourceDir,\n logger: this.logger,\n });\n\n try {\n await fs.writeFile(marker, new Date().toISOString());\n } catch (error) {\n this.logger.warn(`Could not write clone-init marker: ${getErrorMessage(error)}`);\n }\n }\n\n async runSyncAttempt(outcome?: SyncOutcomeAccumulator): Promise<void> {\n return this.withOutcome(outcome, () => this.runSyncAttemptInternal());\n }\n\n private async runSyncAttemptInternal(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n // init ran here and recorded any skip itself; no duplicate to suppress.\n this.pendingInitSkip = null;\n return;\n }\n\n // If init already recorded a wrong-branch / unreadable-HEAD skip for the\n // current clone state during this same sync operation, don't record it a\n // second time. Consume the one-shot token; later ticks re-evaluate fresh.\n if (this.pendingInitSkip) {\n this.pendingInitSkip = null;\n return;\n }\n\n const branch = await this.resolveBranch();\n const worktreeDir = this.config.worktreeDir;\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n\n let currentBranch: string;\n try {\n currentBranch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n this.recordSkip(\n { kind: \"head_unreadable\", phase: \"sync\", error: errorMessage },\n `Could not read current branch from '${worktreeDir}': ${errorMessage}`,\n `Skipping '${this.repoName}': could not read current branch`,\n );\n return;\n }\n\n if (currentBranch !== branch) {\n this.recordSkip(\n { kind: \"branch_mismatch\", phase: \"sync\", currentBranch, expectedBranch: branch },\n `Clone at '${worktreeDir}' is on '${currentBranch}', expected '${branch}'. Skipping fetch+merge.`,\n `Skipping '${this.repoName}': current branch '${currentBranch}' is not '${branch}'`,\n );\n return;\n }\n\n // Re-check every tick (not just at init): the daemon reuses this service, so\n // a clone whose origin no longer matches repoUrl must keep being skipped\n // rather than fetching from the wrong remote.\n const originMismatch = await this.evaluateOriginMatch(git, worktreeDir);\n if (originMismatch) {\n this.recordSkip(\n originMismatch.skip,\n originMismatch.warnMessage,\n `Skipping '${this.repoName}': ${originMismatch.progressDetail}`,\n );\n return;\n }\n\n await this.unshallowIfDepthRemoved(git);\n\n await this.ensureAllRemoteBranchesRefspec(git);\n\n const fetchArgs = await this.buildFetchArgs(git);\n this.emitProgress({ phase: \"fetch\", message: `Fetching origin branches for '${this.repoName}'` });\n if ((await this.fetchWithRecovery(git, fetchArgs, worktreeDir, branch)).skipped) {\n return;\n }\n this.emitProgress({ phase: \"fetch\", message: `Fetched origin branches for '${this.repoName}'` });\n\n if (!(await this.hasRemoteBranch(git, branch))) {\n this.recordSkip(\n { kind: \"missing_remote_ref\", branch, source: \"post_fetch_verify\" },\n `Tracked branch '${branch}' is missing on remote for '${this.repoName}'. Skipping sync.`,\n `Skipping '${this.repoName}': origin/${branch} is missing`,\n );\n return;\n }\n\n if (this.config.sparseCheckout) {\n const sparseService = this.gitService.getSparseCheckoutService();\n try {\n if (await sparseService.needsUpdate(worktreeDir, this.config.sparseCheckout)) {\n this.emitProgress({ phase: \"sparse_checkout\", message: `Updating sparse-checkout for '${this.repoName}'` });\n await sparseService.applyToWorktree(worktreeDir, this.config.sparseCheckout);\n this.emitProgress({ phase: \"sparse_checkout\", message: `Sparse-checkout updated for '${this.repoName}'` });\n }\n } catch (error) {\n this.logger.warn(`Failed to reapply sparse-checkout for '${this.repoName}': ${getErrorMessage(error)}`);\n }\n }\n\n const isClean = await this.gitService.checkWorktreeStatus(worktreeDir);\n if (!isClean) {\n this.recordSkip(\n { kind: \"dirty_tree\" },\n `\u23ED\uFE0F Skipping ff-merge for '${this.repoName}' \u2014 working tree has local changes.`,\n `Skipping merge for '${this.repoName}': working tree has local changes`,\n \"info\",\n );\n return;\n }\n\n let relationship = await this.gitService.classifyRemoteRelationship(worktreeDir, branch);\n let lastDeepenedTo: number | null = null;\n if (relationship === \"indeterminate_shallow\") {\n for (const target of this.getDeepenTargets()) {\n await this.deepenShallowHistoryToDepth(git, branch, target);\n lastDeepenedTo = target;\n relationship = await this.gitService.classifyRemoteRelationship(worktreeDir, branch);\n if (relationship !== \"indeterminate_shallow\") break;\n }\n }\n\n if (relationship === \"up_to_date\") {\n this.logger.info(`'${this.repoName}' already up to date with origin/${branch}.`);\n this.emitProgress({\n phase: \"skip\",\n message: `'${this.repoName}' already up to date with origin/${branch}`,\n });\n this.outcomeAccumulator?.recordNoop(\"repo\", \"already_up_to_date\", {\n branch,\n path: worktreeDir,\n message: `Already up to date with origin/${branch}`,\n });\n return;\n }\n\n if (relationship !== \"fast_forward\") {\n if (relationship === \"local_ahead\") {\n this.recordSkip(\n { kind: \"ahead_unpushed\", branch },\n `\u23ED\uFE0F '${this.repoName}' has unpushed commits ahead of origin/${branch}. Skipping merge.`,\n `Skipping merge for '${this.repoName}': unpushed commits ahead of origin/${branch}`,\n \"info\",\n );\n } else if (relationship === \"indeterminate_shallow\") {\n const detail =\n lastDeepenedTo === null\n ? `no deepening attempted (configured depth already at or above all deepen targets)`\n : `deepening to ${lastDeepenedTo} commits`;\n const progressDetail =\n lastDeepenedTo === null\n ? `no deepening attempted (configured depth at/above limits)`\n : `shallow depth budget exhausted at ${lastDeepenedTo}`;\n this.recordSkip(\n { kind: \"indeterminate_shallow\", branch, deepenedTo: lastDeepenedTo },\n `\u23ED\uFE0F '${this.repoName}' could not classify origin/${branch} after ${detail}. ` +\n `Skipping merge \u2014 consider removing or raising 'depth' to unshallow.`,\n `Skipping merge for '${this.repoName}': ${progressDetail}`,\n \"info\",\n );\n } else {\n this.recordSkip(\n { kind: \"diverged\", branch },\n `\u23ED\uFE0F '${this.repoName}' has diverged from origin/${branch}. Skipping merge (no auto-reset).`,\n `Skipping merge for '${this.repoName}': diverged from origin/${branch}`,\n \"info\",\n );\n }\n return;\n }\n\n this.logger.info(`Fast-forwarding '${this.repoName}' to origin/${branch}...`);\n this.emitProgress({ phase: \"merge\", message: `Fast-forwarding '${this.repoName}' to origin/${branch}` });\n await git.merge([`origin/${branch}`, \"--ff-only\"]);\n this.logger.info(`\u2705 Updated '${this.repoName}' to origin/${branch}.`);\n this.emitProgress({ phase: \"merge\", message: `Updated '${this.repoName}' to origin/${branch}` });\n this.outcomeAccumulator?.recordUpdated(branch, worktreeDir, \"fast_forward\");\n }\n}\n", "import { GIT_CONSTANTS } from \"../constants\";\n\nimport type { Logger } from \"../services/logger.service\";\nimport type { SimpleGitProgressEvent } from \"simple-git\";\n\nexport interface GitProgressEvent {\n phase: string;\n message: string;\n progress?: number;\n processed?: number;\n total?: number;\n}\n\nexport type GitProgressEmitter = (event: GitProgressEvent) => void;\n\n/**\n * Build a progress callback for simple-git's `progress` option that:\n * - filters to clone/fetch/pull events only,\n * - emits at most one progress event per (method,stage) bucket of PROGRESS_BUCKET_PERCENT,\n * - always emits the 100% completion event,\n * - detects stage restarts (bucket regression on the same cached SimpleGit\n * instance, e.g. a second fetch) and resets the bucket so the new run\n * emits from scratch.\n *\n * State (the bucket map) is closure-local \u2014 pass one handler per SimpleGit\n * client. Keep progress logs at debug level so normal logs can stay readable\n * while interactive surfaces and MCP notifications consume structured events.\n */\nexport function makeGitProgressHandler(\n logger: Logger,\n emitProgress?: GitProgressEmitter,\n): (event: SimpleGitProgressEvent) => void {\n const lastBucket = new Map<string, number>();\n return (event: SimpleGitProgressEvent): void => {\n if (event.method !== \"fetch\" && event.method !== \"clone\" && event.method !== \"pull\") return;\n const key = `${event.method}:${event.stage}`;\n const bucket = Math.floor(event.progress / GIT_CONSTANTS.PROGRESS_BUCKET_PERCENT);\n let last = lastBucket.get(key) ?? -1;\n if (bucket < last) last = -1;\n if (bucket <= last && event.progress < 100) return;\n lastBucket.set(key, bucket);\n const total = event.total > 0 ? `${event.processed}/${event.total}` : `${event.processed}`;\n const message = `${event.method} ${event.stage}: ${event.progress}% (${total})`;\n logger.debug(` \u21B3 ${message}`);\n emitProgress?.({\n phase: event.method,\n message,\n progress: event.progress,\n processed: event.processed,\n total: event.total,\n });\n };\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport { glob } from \"glob\";\n\nimport { fileExists } from \"../utils/file-exists\";\n\nconst DEFAULT_IGNORE_PATTERNS = [\n \"**/node_modules/**\",\n \"**/.git/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/.next/**\",\n \"**/coverage/**\",\n];\n\nexport interface FileCopyResult {\n copied: string[];\n skipped: string[];\n errors: Array<{ file: string; error: string }>;\n}\n\nexport class FileCopyService {\n /**\n * Copy files matching patterns from source to destination directory.\n * Skips files that already exist at destination.\n * Preserves directory structure relative to source.\n */\n async copyFiles(sourceDir: string, destDir: string, patterns: string[]): Promise<FileCopyResult> {\n const result: FileCopyResult = {\n copied: [],\n skipped: [],\n errors: [],\n };\n\n if (!patterns || patterns.length === 0) {\n return result;\n }\n\n const filesToCopy = await this.expandPatterns(sourceDir, patterns);\n\n for (const relativePath of filesToCopy) {\n const sourcePath = path.join(sourceDir, relativePath);\n const destPath = path.join(destDir, relativePath);\n\n try {\n const copied = await this.copyFile(sourcePath, destPath);\n if (copied) {\n result.copied.push(relativePath);\n } else {\n result.skipped.push(relativePath);\n }\n } catch (error) {\n result.errors.push({\n file: relativePath,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return result;\n }\n\n private async expandPatterns(sourceDir: string, patterns: string[]): Promise<string[]> {\n const allFiles = new Set<string>();\n\n for (const pattern of patterns) {\n try {\n const matches = await glob(pattern, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n ignore: DEFAULT_IGNORE_PATTERNS,\n });\n\n for (const match of matches) {\n allFiles.add(match);\n }\n } catch {\n // Pattern matching failed, skip silently\n }\n }\n\n return Array.from(allFiles);\n }\n\n private async copyFile(sourcePath: string, destPath: string): Promise<boolean> {\n if (await fileExists(destPath)) {\n return false;\n }\n\n const destDir = path.dirname(destPath);\n await fs.mkdir(destDir, { recursive: true });\n\n await fs.copyFile(sourcePath, destPath);\n return true;\n }\n}\n", "import { FileCopyService } from \"./file-copy.service\";\n\nimport type { HookExecutionService } from \"./hook-execution.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { Config, HookContext } from \"../types\";\n\nexport interface CopyFilesParams {\n config: Pick<Config, \"filesToCopyOnBranchCreate\">;\n branchName: string;\n worktreePath: string;\n sourceDir: string;\n logger: Logger;\n}\n\nexport interface RunHooksParams {\n config: Pick<Config, \"hooks\" | \"repoUrl\">;\n repoName: string;\n branchName: string;\n worktreePath: string;\n baseBranch: string;\n logger: Logger;\n hookExecutionService: HookExecutionService;\n}\n\nexport class BranchCreatedActionsService {\n private fileCopyService: FileCopyService;\n\n constructor(fileCopyService?: FileCopyService) {\n this.fileCopyService = fileCopyService ?? new FileCopyService();\n }\n\n async copyFiles(params: CopyFilesParams): Promise<void> {\n const { config, sourceDir, worktreePath, branchName, logger } = params;\n const patterns = config.filesToCopyOnBranchCreate;\n if (!patterns?.length) return;\n\n try {\n const result = await this.fileCopyService.copyFiles(sourceDir, worktreePath, patterns);\n\n if (result.copied.length > 0) {\n logger.info(`\uD83D\uDCCB Copied ${result.copied.length} file(s) to '${branchName}': ${result.copied.join(\", \")}`);\n }\n if (result.errors.length > 0) {\n logger.warn(`\u26A0\uFE0F Failed to copy ${result.errors.length} file(s) to '${branchName}':`);\n for (const err of result.errors) {\n logger.warn(` - ${err.file}: ${err.error}`);\n }\n }\n } catch (error) {\n logger.error(`Failed to copy files to '${branchName}': ${error}`);\n }\n }\n\n runHooks(params: RunHooksParams): void {\n const { config, branchName, worktreePath, repoName, baseBranch, logger, hookExecutionService } = params;\n if (!config.hooks?.onBranchCreated?.length) return;\n\n const context: HookContext = {\n branchName,\n worktreePath,\n repoName,\n baseBranch,\n repoUrl: config.repoUrl,\n };\n\n logger.info(`Running ${config.hooks.onBranchCreated.length} hook(s) for branch '${branchName}'...`);\n\n hookExecutionService.executeOnBranchCreated(config.hooks, context, {\n onStdout: (data) => logger.info(`[hook] ${data}`),\n onStderr: (data) => logger.warn(`[hook] ${data}`),\n onError: (command, error) => logger.error(`[hook] Failed to execute '${command}': ${error.message}`),\n onComplete: (command, exitCode) => {\n if (exitCode === 0) {\n logger.info(`[hook] Command completed successfully`);\n } else if (exitCode !== null) {\n logger.warn(`[hook] Command exited with code ${exitCode}`);\n }\n },\n });\n }\n}\n", "import type { CloneSkipReason } from \"../services/clone-sync.service\";\n\nexport function formatCloneSkipReason(reason: CloneSkipReason): string {\n switch (reason.kind) {\n case \"branch_mismatch\":\n return reason.phase === \"init\"\n ? `clone is on '${reason.currentBranch}', expected '${reason.expectedBranch}' (since process start)`\n : `clone is on '${reason.currentBranch}', expected '${reason.expectedBranch}'`;\n case \"head_unreadable\":\n return `could not read HEAD: ${reason.error}`;\n case \"dirty_tree\":\n return `working tree has local changes`;\n case \"diverged\":\n return `diverged from origin/${reason.branch}`;\n case \"ahead_unpushed\":\n return `unpushed commits ahead of origin/${reason.branch}`;\n case \"missing_remote_ref\":\n return reason.source === \"fetch_error\"\n ? `origin/${reason.branch} missing on remote (fetch error)`\n : `origin/${reason.branch} pruned after fetch`;\n case \"indeterminate_shallow\":\n return reason.deepenedTo === null\n ? `unable to classify origin/${reason.branch} (no deepening attempted \u2014 configured depth already at or above all deepen targets) \u2014 remove 'depth' to unshallow`\n : `unable to classify origin/${reason.branch} after deepening shallow history to ${reason.deepenedTo} commits \u2014 remove or raise 'depth' to unshallow`;\n case \"origin_mismatch\":\n return `clone origin is '${reason.actual}', expected '${reason.expected}'`;\n default: {\n const _exhaustive: never = reason;\n return _exhaustive;\n }\n }\n}\n", "import { formatCloneSkipReason } from \"../utils/clone-skip-format\";\n\nimport type { CloneSkipReason } from \"./clone-sync.service\";\nimport type { SyncOutcome, SyncOutcomeAction, SyncOutcomeCounts, SyncOutcomeMode, SyncOutcomeScope } from \"../types\";\n\nconst EMPTY_COUNTS: SyncOutcomeCounts = {\n created: 0,\n removed: 0,\n updated: 0,\n skipped: 0,\n preserved: 0,\n failed: 0,\n noop: 0,\n};\n\nfunction cloneCounts(counts: SyncOutcomeCounts): SyncOutcomeCounts {\n return { ...counts };\n}\n\nfunction cloneAction(action: SyncOutcomeAction): SyncOutcomeAction {\n return { ...action } as SyncOutcomeAction;\n}\n\nfunction countKeyFor(action: SyncOutcomeAction): keyof SyncOutcomeCounts {\n switch (action.kind) {\n case \"created\":\n return \"created\";\n case \"removed\":\n return \"removed\";\n case \"updated\":\n return \"updated\";\n case \"skipped\":\n return \"skipped\";\n case \"preserved-diverged\":\n return \"preserved\";\n case \"failed\":\n return \"failed\";\n case \"noop\":\n return \"noop\";\n default: {\n const _exhaustive: never = action;\n return _exhaustive;\n }\n }\n}\n\nexport class SyncOutcomeAccumulator {\n private counts: SyncOutcomeCounts = cloneCounts(EMPTY_COUNTS);\n private actions: SyncOutcomeAction[] = [];\n\n constructor(\n private readonly options: {\n mode: SyncOutcomeMode;\n repoName?: string;\n },\n ) {}\n\n add(action: SyncOutcomeAction): void {\n this.actions.push(action);\n this.counts[countKeyFor(action)]++;\n }\n\n recordCreated(branch: string, path: string): void {\n this.add({ kind: \"created\", branch, path });\n }\n\n recordRemoved(branch: string, path: string): void {\n this.add({ kind: \"removed\", branch, path });\n }\n\n recordUpdated(branch: string, path: string, reason?: string): void {\n this.add({ kind: \"updated\", branch, path, reason });\n }\n\n recordNoop(\n scope: SyncOutcomeScope,\n reason: string,\n details: { branch?: string; path?: string; message?: string },\n ): void {\n this.add({ kind: \"noop\", scope, reason, ...details });\n }\n\n recordSkipped(\n scope: SyncOutcomeScope,\n reason: string,\n details: { branch?: string; path?: string; message?: string },\n ): void {\n this.add({ kind: \"skipped\", scope, reason, ...details });\n }\n\n recordPreservedDiverged(branch: string, path: string, preservedPath: string): void {\n this.add({ kind: \"preserved-diverged\", branch, path, preservedPath });\n }\n\n recordFailed(\n scope: SyncOutcomeScope,\n error: string,\n details: { reason?: string; branch?: string; path?: string } = {},\n ): void {\n this.add({ kind: \"failed\", scope, error, ...details });\n }\n\n getCounts(): SyncOutcomeCounts {\n return cloneCounts(this.counts);\n }\n\n snapshot(): { counts: SyncOutcomeCounts; actions: SyncOutcomeAction[] } {\n return {\n counts: cloneCounts(this.counts),\n actions: this.actions.map(cloneAction),\n };\n }\n\n restore(snapshot: { counts: SyncOutcomeCounts; actions: SyncOutcomeAction[] }): void {\n this.counts = cloneCounts(snapshot.counts);\n this.actions = snapshot.actions.map(cloneAction);\n }\n\n toOutcome(durationMs?: number): SyncOutcome {\n return {\n repoName: this.options.repoName,\n mode: this.options.mode,\n started: true,\n counts: cloneCounts(this.counts),\n actions: this.actions.map(cloneAction),\n durationMs,\n };\n }\n}\n\nexport function createEmptySyncOutcome(mode: SyncOutcomeMode, repoName?: string, durationMs?: number): SyncOutcome {\n return {\n repoName,\n mode,\n started: true,\n counts: cloneCounts(EMPTY_COUNTS),\n actions: [],\n durationMs,\n };\n}\n\nexport function cloneSkipToOutcomeAction(\n reason: CloneSkipReason,\n details: { branch?: string; path?: string } = {},\n): SyncOutcomeAction {\n const message = formatCloneSkipReason(reason);\n const branch =\n \"branch\" in reason ? reason.branch : reason.kind === \"branch_mismatch\" ? reason.expectedBranch : details.branch;\n\n return {\n kind: \"skipped\",\n scope: \"repo\",\n reason: `clone_${reason.kind}`,\n branch,\n path: details.path,\n message,\n };\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { DEFAULT_CONFIG, ENV_CONSTANTS, GIT_CONSTANTS } from \"../constants\";\nimport { WorktreeError } from \"../errors\";\nimport { makeGitProgressHandler } from \"../utils/git-progress\";\nimport { getDefaultBareRepoDir } from \"../utils/git-url\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\nimport { parseWorktreeListPorcelain } from \"../utils/worktree-list-parser\";\n\nimport { Logger } from \"./logger.service\";\nimport { SparseCheckoutService } from \"./sparse-checkout.service\";\nimport { WorktreeMetadataService } from \"./worktree-metadata.service\";\nimport { WorktreeStatusService } from \"./worktree-status.service\";\n\nimport type { WorktreeStatusResult } from \"./worktree-status.service\";\nimport type { Config } from \"../types\";\nimport type { SyncMetadata } from \"../types/sync-metadata\";\nimport type { GitProgressEmitter } from \"../utils/git-progress\";\nimport type { SimpleGit, SimpleGitOptions } from \"simple-git\";\n\nexport type RemoteRelationship = \"up_to_date\" | \"fast_forward\" | \"local_ahead\" | \"diverged\" | \"indeterminate_shallow\";\n\nexport type GitServiceOptions = Pick<\n Config,\n | \"repoUrl\"\n | \"worktreeDir\"\n | \"bareRepoDir\"\n | \"skipLfs\"\n | \"debug\"\n | \"sparseCheckout\"\n | \"fetchTimeoutMs\"\n | \"cloneTimeoutMs\"\n>;\n\n// simple-git blocks EDITOR / GIT_EDITOR / GIT_SEQUENCE_EDITOR unless allowUnsafeEditor is set;\n// strip them when forwarding process.env so a user's shell EDITOR doesn't break read-only commands.\nfunction sanitizeGitEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n const sanitized = { ...env };\n delete sanitized.EDITOR;\n delete sanitized.GIT_EDITOR;\n delete sanitized.GIT_SEQUENCE_EDITOR;\n return sanitized;\n}\n\nexport class GitService {\n private git: SimpleGit | null = null;\n private bareRepoPath: string;\n private mainWorktreePath: string;\n private defaultBranch: string = GIT_CONSTANTS.DEFAULT_BRANCH; // Will be updated after detection\n private metadataService: WorktreeMetadataService;\n private statusService: WorktreeStatusService;\n private sparseCheckoutService: SparseCheckoutService;\n private logger: Logger;\n private lfsSkipOverride = false;\n private gitInstances = new Map<string, SimpleGit>();\n\n constructor(\n private config: GitServiceOptions,\n logger?: Logger,\n private progressEmitter?: GitProgressEmitter,\n ) {\n this.logger = logger ?? Logger.createDefault(undefined, config.debug);\n this.bareRepoPath = this.config.bareRepoDir || getDefaultBareRepoDir(this.config.repoUrl);\n this.mainWorktreePath = path.join(this.config.worktreeDir, GIT_CONSTANTS.DEFAULT_BRANCH); // Temporary, will be updated\n this.metadataService = new WorktreeMetadataService(this.logger);\n this.statusService = new WorktreeStatusService({ skipLfs: this.config.skipLfs }, this.logger);\n this.sparseCheckoutService = new SparseCheckoutService(this.logger);\n }\n\n getSparseCheckoutService(): SparseCheckoutService {\n return this.sparseCheckoutService;\n }\n\n private getFetchTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.fetchTimeoutMs ?? DEFAULT_CONFIG.FETCH_TIMEOUT_MS;\n }\n\n private getCloneTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.cloneTimeoutMs ?? DEFAULT_CONFIG.CLONE_TIMEOUT_MS;\n }\n\n private getCachedGit(dirPath: string, useLfsSkip = false): SimpleGit {\n const key = `${path.resolve(dirPath)}::${useLfsSkip ? \"1\" : \"0\"}`;\n let git = this.gitInstances.get(key);\n if (!git) {\n const base = simpleGit(dirPath, this.buildSimpleGitOptions(this.getFetchTimeoutMs()));\n git = useLfsSkip ? base.env({ [ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE]: \"1\" }) : base;\n this.gitInstances.set(key, git);\n }\n return git;\n }\n\n private buildSimpleGitOptions(blockMs: number): Partial<SimpleGitOptions> {\n const options: Partial<SimpleGitOptions> = {\n progress: makeGitProgressHandler(this.logger, (event) => this.progressEmitter?.(event)),\n };\n if (blockMs > 0) options.timeout = { block: blockMs };\n return options;\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n this.sparseCheckoutService.updateLogger(logger);\n }\n\n async initialize(): Promise<SimpleGit> {\n const { repoUrl } = this.config;\n\n try {\n // Check if bare repo already exists\n await fs.access(path.join(this.bareRepoPath, \"HEAD\"));\n } catch {\n // Clone as bare repository\n this.logger.info(`Cloning from \"${repoUrl}\" as bare repository into \"${this.bareRepoPath}\"...`);\n await fs.mkdir(path.dirname(this.bareRepoPath), { recursive: true });\n const cloneBase = simpleGit(this.buildSimpleGitOptions(this.getCloneTimeoutMs()));\n const cloneGit = this.isLfsSkipEnabled()\n ? cloneBase.env({ [ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE]: \"1\" })\n : cloneBase;\n await cloneGit.clone(repoUrl, this.bareRepoPath, [\"--bare\", \"--progress\"]);\n this.logger.info(\"\u2705 Clone successful.\");\n }\n\n // Configure bare repository for worktrees\n const bareGit = this.getCachedGit(this.bareRepoPath);\n\n // Check if fetch config already exists\n try {\n const existingConfig = await bareGit.raw([\"config\", \"--get-all\", \"remote.origin.fetch\"]);\n const targetConfig = \"+refs/heads/*:refs/remotes/origin/*\";\n\n if (!existingConfig.includes(targetConfig)) {\n await bareGit.addConfig(\"remote.origin.fetch\", targetConfig);\n }\n } catch {\n // Config doesn't exist, add it\n await bareGit.addConfig(\"remote.origin.fetch\", \"+refs/heads/*:refs/remotes/origin/*\");\n }\n\n // Always fetch to ensure remote refs are up-to-date\n // This is needed for branch creation UI even when repo already exists\n this.logger.info(\"Fetching remote branches...\");\n await bareGit.fetch([\"--all\", \"--progress\"]);\n\n // Detect the default branch (works from local refs even without fetch)\n this.defaultBranch = await this.detectDefaultBranch(bareGit);\n this.mainWorktreePath = path.join(this.config.worktreeDir, this.defaultBranch);\n\n // Check if main worktree exists\n let needsMainWorktree = true;\n try {\n const worktrees = await this.getWorktreesFromBare(bareGit);\n needsMainWorktree = !worktrees.some((w) => path.resolve(w.path) === path.resolve(this.mainWorktreePath));\n } catch {\n // If worktree list fails, assume we need main worktree\n }\n\n if (needsMainWorktree) {\n // Create main worktree if it doesn't exist\n this.logger.info(`Creating ${this.defaultBranch} worktree at \"${this.mainWorktreePath}\"...`);\n await fs.mkdir(this.config.worktreeDir, { recursive: true });\n // Use absolute path for worktree add to avoid relative path issues\n const absoluteWorktreePath = path.resolve(this.mainWorktreePath);\n\n // Check if local branch exists\n const branches = await bareGit.branch();\n const defaultBranchExists = branches.all.includes(this.defaultBranch);\n\n const useNoCheckoutMain = !!this.config.sparseCheckout;\n const noCheckoutFlagMain = useNoCheckoutMain ? [\"--no-checkout\"] : [];\n\n try {\n if (defaultBranchExists) {\n await bareGit.raw([\"worktree\", \"add\", ...noCheckoutFlagMain, absoluteWorktreePath, this.defaultBranch]);\n const worktreeGit = this.getCachedGit(absoluteWorktreePath, this.isLfsSkipEnabled());\n await worktreeGit.branch([\"--set-upstream-to\", `origin/${this.defaultBranch}`, this.defaultBranch]);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, this.defaultBranch, false);\n } else {\n await bareGit.raw([\n \"worktree\",\n \"add\",\n ...noCheckoutFlagMain,\n \"--track\",\n \"-b\",\n this.defaultBranch,\n absoluteWorktreePath,\n `origin/${this.defaultBranch}`,\n ]);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, this.defaultBranch, true);\n }\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes(\"already exists\")) {\n this.logger.info(\n `${this.defaultBranch} worktree directory already exists at '${absoluteWorktreePath}', skipping creation.`,\n );\n } else {\n throw error;\n }\n }\n\n // Ensure the worktree is registered by checking it exists in the list\n const updatedWorktrees = await this.getWorktreesFromBare(bareGit);\n const mainWorktreeRegistered = updatedWorktrees.some(\n (w) => path.resolve(w.path) === path.resolve(this.mainWorktreePath),\n );\n\n if (!mainWorktreeRegistered) {\n // Only warn in non-test environments as this is common in tests due to Git state\n if (process.env.NODE_ENV !== ENV_CONSTANTS.NODE_ENV_TEST) {\n this.logger.warn(`Main worktree was created but not found in worktree list. This may cause issues.`);\n }\n }\n }\n\n // Use the main worktree as our primary git instance\n this.git = this.getCachedGit(this.mainWorktreePath);\n return this.git;\n }\n\n getGit(): SimpleGit {\n if (!this.git) {\n throw new Error(\"Git service not initialized. Call initialize() first.\");\n }\n return this.git;\n }\n\n isInitialized(): boolean {\n return this.git !== null;\n }\n\n getDefaultBranch(): string {\n return this.defaultBranch;\n }\n\n getBareRepoPath(): string {\n return this.bareRepoPath;\n }\n\n async getRemoteDefaultBranch(repoUrl: string): Promise<string> {\n const git = simpleGit(this.buildSimpleGitOptions(this.getFetchTimeoutMs()));\n\n try {\n const out = await git.raw([\"ls-remote\", \"--symref\", repoUrl, \"HEAD\"]);\n const match = out.match(/^ref: refs\\/heads\\/(\\S+)\\s+HEAD/m);\n if (match && match[1]) {\n return match[1];\n }\n } catch {\n /* fall through to probe candidates */\n }\n\n // symref HEAD was unavailable/unparsed: probe common branch names, but only\n // auto-pick when the choice is unambiguous. Guessing by fixed priority when\n // several exist can silently track the wrong branch (e.g. 'main' when the\n // remote's real default is 'master').\n const existing: string[] = [];\n for (const candidate of GIT_CONSTANTS.COMMON_DEFAULT_BRANCHES) {\n try {\n const out = await git.raw([\"ls-remote\", \"--exit-code\", repoUrl, `refs/heads/${candidate}`]);\n if (out.trim().length > 0) {\n existing.push(candidate);\n }\n } catch {\n /* candidate missing \u2014 try next */\n }\n }\n\n if (existing.length === 1) {\n this.logger.warn(\n `Could not read symref HEAD for '${repoUrl}'; using the only common branch found ('${existing[0]}') as the default.`,\n );\n return existing[0];\n }\n\n if (existing.length > 1) {\n throw new Error(\n `Unable to detect default branch for '${repoUrl}': symref HEAD is unavailable and multiple common branches exist (${existing.join(\", \")}). ` +\n `Set 'branch' explicitly in the repository config.`,\n );\n }\n\n throw new Error(\n `Unable to detect default branch for '${repoUrl}'. ` +\n `Set 'branch' explicitly in the repository config or ensure the remote is reachable.`,\n );\n }\n\n async verifyLfs(worktreePath: string, label: string): Promise<void> {\n if (this.isLfsSkipEnabled()) return;\n await this.verifyLfsFilesDownloaded(worktreePath, label);\n }\n\n async fetchAll(): Promise<void> {\n this.assertInitialized();\n this.logger.info(\"Fetching latest data from remote...\");\n const git = this.getCachedGit(this.mainWorktreePath, this.isLfsSkipEnabled());\n await git.fetch([\"--all\", \"--prune\", \"--progress\"]);\n }\n\n async fetchBranch(branchName: string): Promise<void> {\n this.assertInitialized();\n const git = this.getCachedGit(this.mainWorktreePath, this.isLfsSkipEnabled());\n await git.fetch([\"origin\", branchName, \"--prune\", \"--progress\"]);\n }\n\n private assertInitialized(): void {\n if (!this.git) {\n throw new Error(\"Git service not initialized. Call initialize() first.\");\n }\n }\n\n async getRemoteBranches(): Promise<string[]> {\n const git = this.getGit();\n const branches = await git.branch([\"-r\"]);\n return branches.all\n .filter((b) => b.startsWith(\"origin/\") && !b.endsWith(\"/HEAD\"))\n .map((b) => b.replace(\"origin/\", \"\"))\n .filter((b) => b !== \"origin\" && b.length > 0);\n }\n\n async getRemoteBranchesWithActivity(): Promise<{ branch: string; lastActivity: Date }[]> {\n const git = this.getGit();\n // Use for-each-ref to get branch names with their last commit dates\n const result = await git.raw([\n \"for-each-ref\",\n \"--format=%(refname:short)|%(committerdate:iso8601)\",\n \"refs/remotes/origin\",\n ]);\n\n const branches: { branch: string; lastActivity: Date }[] = [];\n const lines = result\n .trim()\n .split(\"\\n\")\n .filter((line) => line);\n\n for (const line of lines) {\n const [ref, dateStr] = line.split(\"|\", 2);\n if (ref && dateStr && !ref.endsWith(\"/HEAD\")) {\n const branch = ref.replace(\"origin/\", \"\");\n // Skip invalid branch names\n if (branch === \"origin\" || branch.length === 0) {\n continue;\n }\n const lastActivity = new Date(dateStr);\n // Skip if the date is invalid\n if (!isNaN(lastActivity.getTime())) {\n branches.push({ branch, lastActivity });\n }\n }\n }\n\n return branches;\n }\n\n private async verifyLfsFilesDownloaded(worktreePath: string, branchName: string): Promise<void> {\n const worktreeGit = this.config.sparseCheckout\n ? simpleGit(worktreePath).env({ ...sanitizeGitEnv(process.env), [ENV_CONSTANTS.GIT_ATTR_SOURCE]: \"HEAD\" })\n : this.getCachedGit(worktreePath);\n\n try {\n const lfsFiles = await worktreeGit.raw([\"lfs\", \"ls-files\", \"--name-only\"]);\n let lfsFileList = lfsFiles\n .trim()\n .split(\"\\n\")\n .filter((f) => f.length > 0);\n\n if (lfsFileList.length === 0) {\n return;\n }\n\n // GIT_ATTR_SOURCE=HEAD lists every LFS file declared in HEAD's .gitattributes,\n // including ones outside the sparse-checkout cone that aren't on disk. Sampling\n // those would burn the 30s retry loop on guaranteed-missing files.\n if (this.config.sparseCheckout) {\n const existence = await Promise.all(\n lfsFileList.map(async (f) => {\n try {\n await fs.access(path.join(worktreePath, f));\n return f;\n } catch {\n return null;\n }\n }),\n );\n lfsFileList = existence.filter((f): f is string => f !== null);\n if (lfsFileList.length === 0) {\n return;\n }\n }\n\n if (this.config.debug) {\n this.logger.info(` - Verifying ${lfsFileList.length} LFS files are downloaded...`);\n }\n\n const sampleSize = Math.min(5, lfsFileList.length);\n const samplesToCheck = [];\n for (let i = 0; i < sampleSize; i++) {\n const randomIndex = Math.floor(Math.random() * lfsFileList.length);\n samplesToCheck.push(lfsFileList[randomIndex]);\n }\n\n let retries = 0;\n const maxRetries = 30;\n const retryDelay = 1000;\n\n while (retries < maxRetries) {\n let allDownloaded = true;\n const notDownloaded: string[] = [];\n\n for (const file of samplesToCheck) {\n const filePath = path.join(worktreePath, file);\n try {\n const handle = await fs.open(filePath, \"r\");\n try {\n const buffer = Buffer.alloc(200);\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);\n const header = buffer.subarray(0, bytesRead).toString(\"utf8\");\n if (header.startsWith(GIT_CONSTANTS.LFS_HEADER)) {\n allDownloaded = false;\n notDownloaded.push(file);\n }\n } finally {\n await handle.close();\n }\n } catch {\n allDownloaded = false;\n notDownloaded.push(file);\n }\n }\n\n if (allDownloaded) {\n if (this.config.debug) {\n this.logger.info(` - \u2705 LFS files verified (${samplesToCheck.length} samples checked)`);\n }\n return;\n }\n\n retries++;\n if (retries < maxRetries) {\n await new Promise((resolve) => setTimeout(resolve, retryDelay));\n }\n }\n\n this.logger.warn(\n ` - \u26A0\uFE0F Warning: Some LFS files may not be fully downloaded after ${maxRetries} seconds. ` +\n `This might cause issues if tools access the worktree immediately.`,\n );\n } catch (error) {\n this.logger.warn(` - \u26A0\uFE0F Warning: Could not verify LFS files for '${branchName}': ${error}`);\n }\n }\n\n async checkoutHead(worktreePath: string): Promise<void> {\n const git = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n await git.raw([\"checkout\", \"HEAD\"]);\n }\n\n private async applySparseAndCheckout(absoluteWorktreePath: string): Promise<void> {\n if (!this.config.sparseCheckout) return;\n await this.sparseCheckoutService.applyToWorktree(absoluteWorktreePath, this.config.sparseCheckout);\n const worktreeGit = this.getCachedGit(absoluteWorktreePath, this.isLfsSkipEnabled());\n await worktreeGit.raw([\"checkout\", \"HEAD\"]);\n }\n\n private async rollbackPartialWorktree(\n bareGit: SimpleGit,\n absoluteWorktreePath: string,\n branchName: string,\n createdNewBranch: boolean,\n failureContext?: string,\n ): Promise<{ worktreeRemoved: boolean }> {\n let worktreeRemoved = true;\n try {\n await bareGit.raw([\"worktree\", \"remove\", \"--force\", absoluteWorktreePath]);\n } catch (rollbackError) {\n worktreeRemoved = false;\n const ctx = failureContext ? ` after ${failureContext}` : \"\";\n this.logger.warn(\n ` - Rollback failed for '${branchName}' at '${absoluteWorktreePath}'${ctx}: ${getErrorMessage(rollbackError)}`,\n );\n }\n if (createdNewBranch) {\n try {\n await bareGit.raw([\"branch\", \"-D\", branchName]);\n } catch (branchRollbackError) {\n this.logger.warn(\n ` - Rollback (branch delete) failed for '${branchName}': ${getErrorMessage(branchRollbackError)}`,\n );\n }\n }\n return { worktreeRemoved };\n }\n\n private async createWorktreeMetadata(bareGit: SimpleGit, worktreePath: string, branchName: string): Promise<void> {\n try {\n const worktreeGit = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n const parentCommit = await bareGit.revparse([this.defaultBranch]);\n\n await this.metadataService.createInitialMetadataFromPath(\n this.bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n `origin/${branchName}`,\n this.defaultBranch,\n parentCommit.trim(),\n );\n } catch (metadataError) {\n this.logger.error(` - \u274C Failed to create metadata for '${branchName}': ${metadataError}`);\n throw new Error(`Metadata creation failed for ${branchName}. This worktree cannot be auto-managed.`);\n }\n }\n\n async addWorktree(branchName: string, worktreePath: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath, this.isLfsSkipEnabled());\n // Use absolute path for worktree add to avoid relative path issues\n const absoluteWorktreePath = path.resolve(worktreePath);\n // Ensure parent directory exists for nested branch paths\n await fs.mkdir(path.dirname(absoluteWorktreePath), { recursive: true });\n\n // Check if directory already exists (could be from a failed previous attempt)\n try {\n await fs.access(absoluteWorktreePath);\n // Directory exists - check if it's already a valid worktree\n const worktrees = await this.getWorktreesFromBare(bareGit);\n const isValidWorktree = worktrees.some((w) => path.resolve(w.path) === absoluteWorktreePath);\n\n if (isValidWorktree) {\n this.logger.info(` - Worktree for '${branchName}' already exists at '${absoluteWorktreePath}'`);\n return;\n } else {\n // Directory exists but is not a valid worktree - clean it up\n this.logger.info(` - Cleaning up orphaned directory at '${absoluteWorktreePath}'`);\n await fs.rm(absoluteWorktreePath, { recursive: true, force: true });\n }\n } catch {\n // Directory doesn't exist, which is expected - continue with creation\n }\n\n let createdNewBranch = false;\n try {\n const { local: localBranchExists, remote: remoteBranchExists } = await this.branchExists(branchName);\n\n createdNewBranch = await this.runWorktreeAddByMatrix(\n bareGit,\n branchName,\n absoluteWorktreePath,\n localBranchExists,\n remoteBranchExists,\n );\n\n if (localBranchExists && !remoteBranchExists) {\n this.logger.info(` - Created worktree for '${branchName}' (no remote yet \u2014 push to set upstream)`);\n } else {\n this.logger.info(` - Created worktree for '${branchName}' with tracking to origin/${branchName}`);\n }\n\n if (!this.isLfsSkipEnabled()) {\n await this.verifyLfsFilesDownloaded(absoluteWorktreePath, branchName);\n }\n\n try {\n await this.createWorktreeMetadata(bareGit, absoluteWorktreePath, branchName);\n } catch (metadataError) {\n this.logger.warn(` - Metadata creation failed for '${branchName}', removing worktree to prevent orphan`);\n await this.rollbackPartialWorktree(bareGit, absoluteWorktreePath, branchName, createdNewBranch);\n throw new Error(`Metadata creation failed for '${branchName}': ${getErrorMessage(metadataError)}`);\n }\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n // Upstream setup failures are already rolled back inside runWorktreeAddByMatrix.\n // Don't enter the tracking-error fallback (which would silently accept a partial worktree).\n if ((error as { isUpstreamSetupFailure?: boolean })?.isUpstreamSetupFailure) {\n throw error;\n }\n\n // Re-throw metadata creation errors - these are fatal and should not fall back\n if (errorMessage.includes(\"Metadata creation failed\")) {\n throw error;\n }\n\n // Check if this is an \"already registered\" error\n if (errorMessage.includes(\"already registered worktree\")) {\n // Check if worktree was actually created by a concurrent operation\n const worktrees = await this.getWorktreesFromBare(bareGit);\n const existingWorktree = worktrees.find((w) => path.resolve(w.path) === absoluteWorktreePath);\n\n if (existingWorktree && !existingWorktree.isPrunable) {\n this.logger.info(` - Worktree for '${branchName}' was created by concurrent operation`);\n return;\n }\n\n this.logger.warn(` - Worktree already registered but missing. Pruning and retrying...`);\n await bareGit.raw([\"worktree\", \"prune\"]);\n // Clean up directory if it exists\n try {\n await fs.rm(absoluteWorktreePath, { recursive: true, force: true });\n } catch {\n // Directory might not exist, ignore\n }\n let retryCreatedNewBranch = false;\n try {\n const { local: localBranchExists, remote: remoteBranchExists } = await this.branchExists(branchName);\n retryCreatedNewBranch = await this.runWorktreeAddByMatrix(\n bareGit,\n branchName,\n absoluteWorktreePath,\n localBranchExists,\n remoteBranchExists,\n );\n this.logger.info(` - Created worktree for '${branchName}' after pruning`);\n\n if (!this.isLfsSkipEnabled()) {\n await this.verifyLfsFilesDownloaded(absoluteWorktreePath, branchName);\n }\n\n try {\n await this.createWorktreeMetadata(bareGit, absoluteWorktreePath, branchName);\n } catch (metadataError) {\n this.logger.warn(` - Metadata creation failed for '${branchName}', removing worktree to prevent orphan`);\n await this.rollbackPartialWorktree(bareGit, absoluteWorktreePath, branchName, retryCreatedNewBranch);\n throw new Error(`Metadata creation failed for '${branchName}': ${getErrorMessage(metadataError)}`);\n }\n return;\n } catch (retryError) {\n this.logger.error(` - Failed to create worktree after pruning: ${retryError}`);\n throw retryError;\n }\n }\n\n // Only fall back to non-tracking version for tracking-related errors.\n // Re-throw real errors (disk full, permissions, etc.) immediately.\n const isTrackingError =\n errorMessage.includes(\"not a valid object name\") ||\n errorMessage.includes(\"not a commit\") ||\n errorMessage.includes(\"cannot set up tracking\") ||\n errorMessage.includes(\"does not track\") ||\n errorMessage.includes(\"remote tracking branch\") ||\n errorMessage.includes(\"no such remote ref\");\n\n if (!isTrackingError) {\n throw error;\n }\n\n this.logger.warn(` - Failed to create worktree with tracking, falling back to simple add: ${error}`);\n\n // Check again if directory exists before fallback attempt\n try {\n await fs.access(absoluteWorktreePath);\n // Directory exists - check if it's already a valid worktree\n const worktrees = await this.getWorktreesFromBare(bareGit);\n const isValidWorktree = worktrees.some((w) => path.resolve(w.path) === absoluteWorktreePath);\n\n if (isValidWorktree) {\n this.logger.info(` - Worktree for '${branchName}' already exists at '${absoluteWorktreePath}'`);\n return;\n } else {\n // Directory exists but is not a valid worktree - clean it up\n this.logger.info(` - Cleaning up orphaned directory at '${absoluteWorktreePath}' before fallback attempt`);\n await fs.rm(absoluteWorktreePath, { recursive: true, force: true });\n }\n } catch {\n // Directory doesn't exist, which is expected - continue with fallback\n }\n\n try {\n const useNoCheckout = !!this.config.sparseCheckout;\n const fallbackArgs = useNoCheckout\n ? [\"worktree\", \"add\", \"--no-checkout\", absoluteWorktreePath, branchName]\n : [\"worktree\", \"add\", absoluteWorktreePath, branchName];\n await bareGit.raw(fallbackArgs);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, branchName, false);\n this.logger.info(` - Created worktree for '${branchName}' (without tracking)`);\n\n if (!this.isLfsSkipEnabled()) {\n await this.verifyLfsFilesDownloaded(absoluteWorktreePath, branchName);\n }\n\n try {\n await this.createWorktreeMetadata(bareGit, absoluteWorktreePath, branchName);\n } catch (metadataError) {\n this.logger.warn(` - Metadata creation failed for '${branchName}', removing worktree to prevent orphan`);\n await this.rollbackPartialWorktree(bareGit, absoluteWorktreePath, branchName, false);\n throw new Error(`Metadata creation failed for '${branchName}': ${getErrorMessage(metadataError)}`);\n }\n } catch (fallbackError) {\n const fallbackErrorMessage = getErrorMessage(fallbackError);\n\n // If fallback also fails with \"already registered\", check if created by concurrent op\n if (fallbackErrorMessage.includes(\"already registered worktree\")) {\n const worktrees = await this.getWorktreesFromBare(bareGit);\n const existingWorktree = worktrees.find((w) => path.resolve(w.path) === absoluteWorktreePath);\n\n if (existingWorktree && !existingWorktree.isPrunable) {\n this.logger.info(` - Worktree for '${branchName}' was created by concurrent operation during fallback`);\n return;\n }\n }\n\n // If still failing, this is a real error\n throw fallbackError;\n }\n }\n }\n\n private async runWorktreeAddByMatrix(\n bareGit: SimpleGit,\n branchName: string,\n absoluteWorktreePath: string,\n localExists: boolean,\n remoteExists: boolean,\n ): Promise<boolean> {\n const useNoCheckout = !!this.config.sparseCheckout;\n const noCheckoutFlag = useNoCheckout ? [\"--no-checkout\"] : [];\n\n if (localExists && remoteExists) {\n await bareGit.raw([\"worktree\", \"add\", ...noCheckoutFlag, absoluteWorktreePath, branchName]);\n\n // branch --set-upstream-to is a config-only operation and works on a --no-checkout\n // worktree, so we run it before sparse setup and materialization.\n try {\n const worktreeGit = this.getCachedGit(absoluteWorktreePath, this.isLfsSkipEnabled());\n await worktreeGit.branch([\"--set-upstream-to\", `origin/${branchName}`, branchName]);\n } catch (error) {\n throw await this.wrapUpstreamFailure(bareGit, absoluteWorktreePath, branchName, false, error);\n }\n\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, branchName, false);\n return false;\n }\n\n if (localExists) {\n await bareGit.raw([\"worktree\", \"add\", ...noCheckoutFlag, absoluteWorktreePath, branchName]);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, branchName, false);\n return false;\n }\n\n if (remoteExists) {\n await bareGit.raw([\n \"worktree\",\n \"add\",\n ...noCheckoutFlag,\n \"--track\",\n \"-b\",\n branchName,\n absoluteWorktreePath,\n `origin/${branchName}`,\n ]);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, branchName, true);\n return true;\n }\n\n throw new WorktreeError(\n `Branch '${branchName}' does not exist locally or on origin; create it first`,\n \"BRANCH_NOT_FOUND\",\n );\n }\n\n private async runSparseStepWithRollback(\n bareGit: SimpleGit,\n absoluteWorktreePath: string,\n branchName: string,\n createdNewBranch: boolean,\n ): Promise<void> {\n try {\n await this.applySparseAndCheckout(absoluteWorktreePath);\n } catch (sparseError) {\n await this.rollbackPartialWorktree(bareGit, absoluteWorktreePath, branchName, createdNewBranch);\n throw new Error(`Sparse-checkout setup failed for '${branchName}': ${getErrorMessage(sparseError)}`);\n }\n }\n\n private async wrapUpstreamFailure(\n bareGit: SimpleGit,\n absoluteWorktreePath: string,\n branchName: string,\n createdNewBranch: boolean,\n error: unknown,\n ): Promise<Error> {\n const { worktreeRemoved } = await this.rollbackPartialWorktree(\n bareGit,\n absoluteWorktreePath,\n branchName,\n createdNewBranch,\n \"upstream setup error\",\n );\n const suffix = worktreeRemoved ? \"\" : \" (rollback failed; partial worktree may remain)\";\n const wrapped = new Error(`Failed to set upstream for '${branchName}': ${getErrorMessage(error)}${suffix}`);\n (wrapped as Error & { isUpstreamSetupFailure?: boolean }).isUpstreamSetupFailure = true;\n return wrapped;\n }\n\n async removeWorktree(worktreePath: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n\n await bareGit.raw([\"worktree\", \"remove\", worktreePath, \"--force\"]);\n this.logger.info(` - \u2705 Safely removed stale worktree at '${worktreePath}'.`);\n\n // Clean up metadata using the worktree path\n try {\n await this.metadataService.deleteMetadataFromPath(this.bareRepoPath, worktreePath);\n } catch (metadataError) {\n this.logger.warn(`Failed to delete metadata for worktree: ${metadataError}`);\n }\n }\n\n async pruneWorktrees(): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n await bareGit.raw([\"worktree\", \"prune\"]);\n this.logger.info(\"Pruned worktree metadata.\");\n }\n\n async checkWorktreeStatus(worktreePath: string): Promise<boolean> {\n return this.statusService.checkWorktreeStatus(worktreePath);\n }\n\n async hasUnpushedCommits(worktreePath: string): Promise<boolean> {\n const metadata = await this.metadataService.loadMetadataFromPath(this.bareRepoPath, worktreePath);\n return this.statusService.hasUnpushedCommits(worktreePath, metadata?.lastSyncCommit);\n }\n\n async hasUpstreamGone(worktreePath: string): Promise<boolean> {\n return this.statusService.hasUpstreamGone(worktreePath);\n }\n\n async hasStashedChanges(worktreePath: string): Promise<boolean> {\n return this.statusService.hasStashedChanges(worktreePath);\n }\n\n async getFullWorktreeStatus(worktreePath: string, includeDetails = false): Promise<WorktreeStatusResult> {\n const metadata = await this.metadataService.loadMetadataFromPath(this.bareRepoPath, worktreePath);\n return this.statusService.getFullWorktreeStatus(worktreePath, includeDetails, metadata?.lastSyncCommit);\n }\n\n async hasModifiedSubmodules(worktreePath: string): Promise<boolean> {\n return this.statusService.hasModifiedSubmodules(worktreePath);\n }\n\n async hasOperationInProgress(worktreePath: string): Promise<boolean> {\n return this.statusService.hasOperationInProgress(worktreePath);\n }\n\n async getCurrentBranch(): Promise<string> {\n const git = this.getGit();\n const branchSummary = await git.branch();\n return branchSummary.current;\n }\n\n private async detectDefaultBranch(bareGit: SimpleGit): Promise<string> {\n try {\n // Try to get the symbolic ref for origin/HEAD\n const headRef = await bareGit.raw([\"symbolic-ref\", \"refs/remotes/origin/HEAD\"]);\n // Extract branch name from refs/remotes/origin/main or refs/remotes/origin/master\n const branch = headRef.trim().split(\"/\").pop();\n if (branch) {\n return branch;\n }\n } catch {\n // If that fails, try to set HEAD automatically\n try {\n await bareGit.raw([\"remote\", \"set-head\", \"origin\", \"-a\"]);\n const headRef = await bareGit.raw([\"symbolic-ref\", \"refs/remotes/origin/HEAD\"]);\n const branch = headRef.trim().split(\"/\").pop();\n if (branch) {\n return branch;\n }\n } catch {\n // If all else fails, try to detect from remote branches\n try {\n const remoteBranches = await bareGit.branch([\"-r\"]);\n const commonDefaults = GIT_CONSTANTS.COMMON_DEFAULT_BRANCHES;\n for (const defaultName of commonDefaults) {\n if (remoteBranches.all.some((branch) => branch === `origin/${defaultName}`)) {\n return defaultName;\n }\n }\n } catch {\n // Ignore and fall through to default\n }\n }\n }\n // Final fallback\n return GIT_CONSTANTS.DEFAULT_BRANCH;\n }\n\n setLfsSkipEnabled(value: boolean): void {\n this.lfsSkipOverride = value;\n }\n\n private isLfsSkipEnabled(): boolean {\n return this.config.skipLfs || this.lfsSkipOverride;\n }\n\n async getWorktrees(): Promise<{ path: string; branch: string }[]> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n return this.getWorktreesFromBare(bareGit);\n }\n\n async isWorktreeBehind(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the current branch\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n // Check if the branch has an upstream\n const upstreamInfo = await worktreeGit.raw([\"rev-parse\", \"--abbrev-ref\", `${currentBranch}@{upstream}`]);\n if (!upstreamInfo.trim()) {\n return false; // No upstream, can't be behind\n }\n\n // Count commits behind upstream\n const behindCount = await worktreeGit.raw([\"rev-list\", \"--count\", `HEAD..${upstreamInfo.trim()}`]);\n return parseInt(behindCount.trim(), 10) > 0;\n } catch {\n // If any command fails, assume not behind\n return false;\n }\n }\n\n async updateWorktree(worktreePath: string): Promise<void> {\n const worktreeGit = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n\n // Perform a fast-forward merge\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n await worktreeGit.merge([`origin/${currentBranch}`, \"--ff-only\"]);\n\n // Update metadata after successful update (use path-based method)\n try {\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n await this.metadataService.updateLastSyncFromPath(\n this.bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n \"updated\",\n this.defaultBranch,\n );\n } catch (metadataError) {\n this.logger.warn(`Failed to update metadata for worktree: ${metadataError}`);\n }\n }\n\n async hasDivergedHistory(worktreePath: string, expectedBranch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n\n // Validate branch matches\n const branchInfo = await worktreeGit.branch();\n if (branchInfo.current !== expectedBranch) {\n this.logger.warn(`Branch mismatch in hasDivergedHistory: expected ${expectedBranch}, got ${branchInfo.current}`);\n return false; // Conservative: assume can fast-forward\n }\n\n try {\n // Check if HEAD is an ancestor of the remote branch (can fast-forward)\n await worktreeGit.raw([\"merge-base\", \"--is-ancestor\", \"HEAD\", `origin/${expectedBranch}`]);\n return false; // Can fast-forward\n } catch {\n return true; // Histories have diverged\n }\n }\n\n async canFastForward(worktreePath: string, branch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the merge base between HEAD and the remote branch\n const mergeBase = await worktreeGit.raw([\"merge-base\", \"HEAD\", `origin/${branch}`]);\n const mergeBaseSha = mergeBase.trim();\n\n // Get current HEAD SHA\n const headSha = await worktreeGit.revparse([\"HEAD\"]);\n const headShaTrimmed = headSha.trim();\n\n // If merge base equals HEAD, then HEAD is an ancestor of remote and can fast-forward\n return mergeBaseSha === headShaTrimmed;\n } catch {\n // If merge-base fails, branches have diverged\n return false;\n }\n }\n\n async isLocalAheadOfRemote(worktreePath: string, branch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the merge base between HEAD and the remote branch\n const mergeBase = await worktreeGit.raw([\"merge-base\", \"HEAD\", `origin/${branch}`]);\n const mergeBaseSha = mergeBase.trim();\n\n // Get remote branch SHA\n const remoteSha = await worktreeGit.revparse([`origin/${branch}`]);\n const remoteShaTrimmed = remoteSha.trim();\n\n // If merge base equals remote, local is ahead (remote is ancestor of local)\n return mergeBaseSha === remoteShaTrimmed;\n } catch {\n return false;\n }\n }\n\n async classifyRemoteRelationship(worktreePath: string, branch: string): Promise<RemoteRelationship> {\n const worktreeGit = this.getCachedGit(worktreePath);\n\n let headSha: string;\n let remoteSha: string;\n try {\n headSha = (await worktreeGit.revparse([\"HEAD\"])).trim();\n remoteSha = (await worktreeGit.revparse([`refs/remotes/origin/${branch}`])).trim();\n } catch {\n return \"diverged\";\n }\n\n if (headSha === remoteSha) return \"up_to_date\";\n\n let mergeBase = \"\";\n let mergeBaseFailed = false;\n try {\n mergeBase = (await worktreeGit.raw([\"merge-base\", \"HEAD\", `origin/${branch}`])).trim();\n } catch {\n mergeBaseFailed = true;\n }\n // simple-git swallows merge-base exit 1 and returns \"\" \u2014 treat empty output as failure too.\n if (mergeBaseFailed || !mergeBase) {\n if (await this.isShallowRepository(worktreeGit)) return \"indeterminate_shallow\";\n return \"diverged\";\n }\n if (mergeBase === headSha) return \"fast_forward\";\n if (mergeBase === remoteSha) return \"local_ahead\";\n return \"diverged\";\n }\n\n private async isShallowRepository(git: SimpleGit): Promise<boolean> {\n try {\n const output = await git.raw([\"rev-parse\", \"--is-shallow-repository\"]);\n return output.trim() === \"true\";\n } catch {\n return false;\n }\n }\n\n async getChangedPathsInRange(worktreePath: string, fromRef: string, toRef: string): Promise<string[] | null> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n const out = await worktreeGit.raw([\n \"-c\",\n \"core.quotePath=false\",\n \"diff\",\n \"--name-only\",\n \"--no-renames\",\n `${fromRef}..${toRef}`,\n ]);\n // Don't .trim() entries \u2014 leading/trailing whitespace is valid in POSIX\n // paths and `core.quotePath=false` only affects high-byte quoting, not\n // whitespace. Strip a trailing CR for Windows line endings only.\n return out\n .split(\"\\n\")\n .map((l) => l.replace(/\\r$/, \"\"))\n .filter((l) => l.length > 0);\n } catch (error) {\n this.logger.warn(`Failed to compute diff ${fromRef}..${toRef} in ${worktreePath}: ${getErrorMessage(error)}`);\n return null;\n }\n }\n\n async compareTreeContent(worktreePath: string, branch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the tree SHA for the current HEAD\n const localTree = await worktreeGit.raw([\"rev-parse\", \"HEAD^{tree}\"]);\n // Get the tree SHA for the remote branch\n const remoteTree = await worktreeGit.raw([\"rev-parse\", `origin/${branch}^{tree}`]);\n\n return localTree.trim() === remoteTree.trim();\n } catch (error) {\n this.logger.error(`Error comparing tree content: ${error}`);\n return false; // Assume trees are different if we can't compare\n }\n }\n\n async resetToUpstream(worktreePath: string, branch: string): Promise<void> {\n const worktreeGit = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n\n await worktreeGit.reset([\"--hard\", `origin/${branch}`]);\n\n // Update metadata after reset (use path-based method)\n try {\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n await this.metadataService.updateLastSyncFromPath(\n this.bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n \"updated\",\n this.defaultBranch,\n );\n } catch (metadataError) {\n this.logger.warn(`Failed to update metadata after reset: ${metadataError}`);\n }\n }\n\n async getCurrentCommit(worktreePath: string): Promise<string> {\n const worktreeGit = this.getCachedGit(worktreePath);\n const commit = await worktreeGit.revparse([\"HEAD\"]);\n return commit.trim();\n }\n\n async getRemoteCommit(ref: string): Promise<string> {\n // Use the bare repository to read remote commit to avoid dependency on main worktree path\n const git = this.getCachedGit(this.bareRepoPath);\n const commit = await git.revparse([ref]);\n return commit.trim();\n }\n\n async branchExists(branchName: string): Promise<{ local: boolean; remote: boolean }> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const checkRef = async (ref: string): Promise<boolean> => {\n try {\n // simple-git resolves `show-ref --quiet` when Git exits 1, so keep stdout enabled.\n await bareGit.raw([\"show-ref\", \"--verify\", ref]);\n return true;\n } catch {\n return false;\n }\n };\n\n const [local, remote] = await Promise.all([\n checkRef(`${GIT_CONSTANTS.REFS.HEADS}${branchName}`),\n checkRef(`${GIT_CONSTANTS.REFS.REMOTES}/${branchName}`),\n ]);\n\n return { local, remote };\n }\n\n async getLocalBranches(): Promise<string[]> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const branches = await bareGit.branch();\n return branches.all;\n }\n\n private async resolveCreateBranchBaseRef(bareGit: SimpleGit, baseBranch: string): Promise<string> {\n const candidates =\n baseBranch.startsWith(GIT_CONSTANTS.REMOTE_PREFIX) || baseBranch.startsWith(\"refs/\")\n ? [baseBranch]\n : [`${GIT_CONSTANTS.REMOTE_PREFIX}${baseBranch}`, baseBranch];\n\n for (const candidate of candidates) {\n try {\n await bareGit.revparse([\"--verify\", candidate]);\n return candidate;\n } catch {\n // Try the next candidate before letting git branch report the original failure.\n }\n }\n\n return candidates[0];\n }\n\n async createBranch(branchName: string, baseBranch: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const baseRef = await this.resolveCreateBranchBaseRef(bareGit, baseBranch);\n\n await bareGit.raw([\"branch\", \"--no-track\", branchName, baseRef]);\n this.logger.info(`Created branch '${branchName}' from '${baseRef}'`);\n }\n\n async pushBranch(branchName: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n\n await bareGit.push([\"origin\", `${branchName}:${branchName}`, \"-u\"]);\n this.logger.info(`Pushed branch '${branchName}' to remote`);\n }\n\n async getWorktreeMetadata(worktreePath: string): Promise<SyncMetadata | null> {\n return this.metadataService.loadMetadataFromPath(this.bareRepoPath, worktreePath);\n }\n\n private async getWorktreesFromBare(\n bareGit: SimpleGit,\n ): Promise<{ path: string; branch: string; isPrunable?: boolean }[]> {\n const result = await bareGit.raw([\"worktree\", \"list\", \"--porcelain\"]);\n return parseWorktreeListPorcelain(result)\n .filter((w) => !w.detached && w.branch !== null)\n .map((w) => ({\n path: w.path,\n branch: w.branch as string,\n isPrunable: w.prunable,\n }));\n }\n}\n", "export interface ParsedWorktree {\n path: string;\n branch: string | null;\n head: string | null;\n detached: boolean;\n prunable: boolean;\n locked: boolean;\n}\n\nexport function parseWorktreeListPorcelain(output: string): ParsedWorktree[] {\n const worktrees: ParsedWorktree[] = [];\n let current: Partial<ParsedWorktree> = {};\n\n const flush = (): void => {\n if (!current.path) {\n current = {};\n return;\n }\n worktrees.push({\n path: current.path,\n branch: current.branch ?? null,\n head: current.head ?? null,\n detached: current.detached ?? false,\n prunable: current.prunable ?? false,\n locked: current.locked ?? false,\n });\n current = {};\n };\n\n for (const line of output.split(\"\\n\")) {\n if (line.startsWith(\"worktree \")) {\n flush();\n current.path = line.substring(\"worktree \".length);\n } else if (line.startsWith(\"branch \")) {\n current.branch = line.substring(\"branch \".length).replace(\"refs/heads/\", \"\");\n } else if (line.startsWith(\"HEAD \")) {\n current.head = line.substring(\"HEAD \".length);\n } else if (line === \"detached\") {\n current.detached = true;\n } else if (line === \"prunable\" || line.startsWith(\"prunable \")) {\n current.prunable = true;\n } else if (line === \"locked\" || line.startsWith(\"locked \")) {\n current.locked = true;\n } else if (line.trim() === \"\") {\n flush();\n }\n }\n flush();\n return worktrees;\n}\n", "import * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { SparseCheckoutConfig, SparseCheckoutMode } from \"../types\";\nimport type { SimpleGit } from \"simple-git\";\n\nexport type GitFactory = (worktreePath: string) => SimpleGit;\n\ninterface SparseMatcher {\n mode: SparseCheckoutMode;\n patterns: string[];\n ancestorDirs: Set<string>;\n}\n\nexport class SparseCheckoutService {\n private logger: Logger;\n private gitFactory: GitFactory;\n private warnedConfigs = new WeakSet<SparseCheckoutConfig>();\n private matcherCache = new WeakMap<SparseCheckoutConfig, SparseMatcher>();\n\n constructor(logger?: Logger, gitFactory?: GitFactory) {\n this.logger = logger ?? Logger.createDefault();\n this.gitFactory = gitFactory ?? ((p: string): SimpleGit => simpleGit(p));\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n resolveMode(cfg: SparseCheckoutConfig): SparseCheckoutMode {\n const hasExclude = !!cfg.exclude && cfg.exclude.length > 0;\n const hasNegation = cfg.include.some((p) => p.trim().startsWith(\"!\"));\n\n if (cfg.mode === \"no-cone\") return \"no-cone\";\n if (hasExclude || hasNegation) {\n if (cfg.mode === \"cone\" && !this.warnedConfigs.has(cfg)) {\n this.logger.warn(\n \"sparseCheckout: mode 'cone' is incompatible with excludes or negation patterns; auto-promoting to 'no-cone'\",\n );\n this.warnedConfigs.add(cfg);\n }\n return \"no-cone\";\n }\n return cfg.mode ?? \"cone\";\n }\n\n buildPatterns(cfg: SparseCheckoutConfig): string[] {\n return this.buildPatternsForMode(cfg, this.resolveMode(cfg));\n }\n\n private buildPatternsForMode(cfg: SparseCheckoutConfig, mode: SparseCheckoutMode): string[] {\n const includes = cfg.include.map((p) => p.trim()).filter((p) => p.length > 0);\n\n if (mode === \"cone\") {\n return includes;\n }\n\n const excludes = (cfg.exclude ?? [])\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n .map((p) => (p.startsWith(\"!\") ? p : `!${p}`));\n\n return [...includes, ...excludes];\n }\n\n async applyToWorktree(worktreePath: string, cfg: SparseCheckoutConfig): Promise<void> {\n const mode = this.resolveMode(cfg);\n const patterns = this.buildPatternsForMode(cfg, mode);\n\n if (patterns.length === 0) {\n throw new Error(\"sparseCheckout produced no patterns; refusing to apply empty config\");\n }\n\n const git = this.gitFactory(worktreePath);\n await git.raw([\"sparse-checkout\", \"init\", mode === \"cone\" ? \"--cone\" : \"--no-cone\"]);\n await git.raw([\"sparse-checkout\", \"set\", mode === \"cone\" ? \"--cone\" : \"--no-cone\", ...patterns]);\n }\n\n async readCurrent(worktreePath: string): Promise<string[] | null> {\n const git = this.gitFactory(worktreePath);\n try {\n const out = await git.raw([\"sparse-checkout\", \"list\"]);\n const lines = out\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter((l) => l.length > 0 && !l.startsWith(\"#\"));\n return lines.length === 0 ? null : lines;\n } catch {\n return null;\n }\n }\n\n async readCurrentMode(worktreePath: string): Promise<SparseCheckoutMode | null> {\n const git = this.gitFactory(worktreePath);\n try {\n const out = await git.raw([\"config\", \"--bool\", \"--get\", \"core.sparseCheckoutCone\"]);\n const value = out.trim().toLowerCase();\n if (value === \"true\") return \"cone\";\n if (value === \"false\") return \"no-cone\";\n return null;\n } catch {\n return null;\n }\n }\n\n async needsUpdate(worktreePath: string, cfg: SparseCheckoutConfig): Promise<boolean> {\n const desiredMode = this.resolveMode(cfg);\n const currentMode = await this.readCurrentMode(worktreePath);\n if (currentMode !== desiredMode) return true;\n const current = await this.readCurrent(worktreePath);\n if (current === null) return true;\n return !this.patternsEqual(current, this.buildPatternsForMode(cfg, desiredMode));\n }\n\n isNarrowing(currentPatterns: string[] | null, nextPatterns: string[]): boolean {\n if (!currentPatterns || currentPatterns.length === 0) return false;\n\n const isNeg = (p: string): boolean => p.startsWith(\"!\");\n const trim = (xs: string[]): string[] => xs.map((p) => p.trim()).filter((p) => p.length > 0);\n\n const cur = trim(currentPatterns);\n const next = trim(nextPatterns);\n\n const positiveCurrent = new Set(cur.filter((p) => !isNeg(p)));\n const negativeCurrent = new Set(cur.filter(isNeg));\n const positiveNext = new Set(next.filter((p) => !isNeg(p)));\n const negativeNext = new Set(next.filter(isNeg));\n\n for (const p of positiveCurrent) {\n if (!positiveNext.has(p)) return true;\n }\n for (const p of negativeNext) {\n if (!negativeCurrent.has(p)) return true;\n }\n return false;\n }\n\n patternsEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n const at = a.map((x) => x.trim());\n const bt = b.map((x) => x.trim());\n return at.every((v, i) => v === bt[i]);\n }\n\n /**\n * Decide whether a list of changed file paths intersects the sparse-checkout\n * set defined by `cfg`. Used to skip fast-forward updates when upstream\n * commits only touch files outside the materialized worktree.\n *\n * Cone mode materializes:\n * - all files at the repository root,\n * - all files directly inside every ancestor of an included directory\n * (e.g. include `tools/build` keeps `tools/foo.txt` checked out too),\n * - everything inside an included directory.\n * We mirror those rules here. Missing the ancestor-files case would let\n * stale files linger when only those parent files change upstream.\n *\n * No-cone mode: gitignore-style matching with negation is non-trivial and\n * not implemented here yet. We return `true` so the caller falls back to\n * the safe behavior of always running the update.\n *\n * The matcher derived from `cfg` is cached on the cfg object identity\n * (WeakMap), so callers should reuse the same `cfg` reference across\n * invocations to benefit from the cache.\n */\n pathsTouchSparse(changedPaths: string[], cfg: SparseCheckoutConfig): boolean {\n if (changedPaths.length === 0) return false;\n\n const matcher = this.getMatcher(cfg);\n if (matcher.mode === \"no-cone\") return true;\n if (matcher.patterns.length === 0) return true;\n\n return changedPaths.some((p) => {\n if (!p.includes(\"/\")) return true;\n for (const pat of matcher.patterns) {\n if (p === pat || p.startsWith(pat + \"/\")) return true;\n }\n return matcher.ancestorDirs.has(path.posix.dirname(p));\n });\n }\n\n private getMatcher(cfg: SparseCheckoutConfig): SparseMatcher {\n const cached = this.matcherCache.get(cfg);\n if (cached) return cached;\n\n const mode = this.resolveMode(cfg);\n if (mode === \"no-cone\") {\n const matcher: SparseMatcher = { mode, patterns: [], ancestorDirs: new Set() };\n this.matcherCache.set(cfg, matcher);\n return matcher;\n }\n\n const patterns = cfg.include\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n .map((p) => (p.endsWith(\"/\") ? p.slice(0, -1) : p));\n\n const ancestorDirs = new Set<string>();\n for (const pat of patterns) {\n const parts = pat.split(\"/\");\n for (let i = 1; i < parts.length; i++) {\n ancestorDirs.add(parts.slice(0, i).join(\"/\"));\n }\n }\n\n const matcher: SparseMatcher = { mode, patterns, ancestorDirs };\n this.matcherCache.set(cfg, matcher);\n return matcher;\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { ERROR_MESSAGES, GIT_CONSTANTS, METADATA_CONSTANTS } from \"../constants\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { SyncMetadata } from \"../types/sync-metadata\";\n\nexport class WorktreeMetadataService {\n private logger: Logger;\n\n constructor(logger?: Logger) {\n this.logger = logger ?? Logger.createDefault();\n }\n\n /**\n * Gets the internal worktree directory name from a worktree path.\n * Git uses the basename of the worktree path as the internal directory name.\n * For example: /worktrees/fix/test-branch -> test-branch (not fix/test-branch)\n */\n private getWorktreeDirectoryName(worktreePath: string): string {\n return path.basename(worktreePath);\n }\n\n async getMetadataPath(bareRepoPath: string, worktreeName: string): Promise<string> {\n if (worktreeName.includes(\"/\") || worktreeName.includes(\"\\\\\")) {\n throw new Error(\n `getMetadataPath requires a filesystem-safe worktree directory name, got '${worktreeName}'. Use getMetadataPathFromWorktreePath when starting from a raw branch name.`,\n );\n }\n return path.join(\n bareRepoPath,\n METADATA_CONSTANTS.WORKTREE_METADATA_PATH,\n worktreeName,\n METADATA_CONSTANTS.METADATA_FILENAME,\n );\n }\n\n async getMetadataPathFromWorktreePath(bareRepoPath: string, worktreePath: string): Promise<string> {\n // Extract the worktree directory name (basename) that Git actually uses\n const worktreeDirName = this.getWorktreeDirectoryName(worktreePath);\n return this.getMetadataPath(bareRepoPath, worktreeDirName);\n }\n\n async saveMetadata(bareRepoPath: string, worktreeName: string, metadata: SyncMetadata): Promise<void> {\n const metadataPath = await this.getMetadataPath(bareRepoPath, worktreeName);\n await fs.mkdir(path.dirname(metadataPath), { recursive: true });\n\n // Write to temp file then rename for atomicity \u2014 prevents corruption on crash.\n // Unique suffix avoids collisions between concurrent writers for the same worktree.\n const tmpPath = `${metadataPath}.${process.pid}.${Date.now()}.tmp`;\n let renamed = false;\n try {\n await fs.writeFile(tmpPath, JSON.stringify(metadata, null, 2), \"utf-8\");\n try {\n await fs.rename(tmpPath, metadataPath);\n renamed = true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === ERROR_MESSAGES.EXDEV) {\n await fs.copyFile(tmpPath, metadataPath);\n } else {\n throw err;\n }\n }\n } finally {\n if (!renamed) {\n await fs.unlink(tmpPath).catch(() => undefined);\n }\n }\n }\n\n async loadMetadata(bareRepoPath: string, worktreeName: string): Promise<SyncMetadata | null> {\n const metadataPath = await this.getMetadataPath(bareRepoPath, worktreeName);\n\n try {\n const content = await fs.readFile(metadataPath, \"utf-8\");\n return JSON.parse(content) as SyncMetadata;\n } catch {\n // Return null if file doesn't exist or can't be parsed\n return null;\n }\n }\n\n async loadMetadataFromPath(bareRepoPath: string, worktreePath: string): Promise<SyncMetadata | null> {\n const metadataPath = await this.getMetadataPathFromWorktreePath(bareRepoPath, worktreePath);\n\n try {\n const content = await fs.readFile(metadataPath, \"utf-8\");\n const metadata = JSON.parse(content) as SyncMetadata;\n\n if (!(await this.validateMetadata(metadata))) {\n this.logger.warn(`Corrupted metadata for ${worktreePath}, treating as missing`);\n return null;\n }\n\n return metadata;\n } catch {\n return null;\n }\n }\n\n async deleteMetadata(bareRepoPath: string, worktreeName: string): Promise<void> {\n const metadataPath = await this.getMetadataPath(bareRepoPath, worktreeName);\n\n try {\n await fs.unlink(metadataPath);\n } catch (error) {\n // Ignore errors if file doesn't exist\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n }\n\n async deleteMetadataFromPath(bareRepoPath: string, worktreePath: string): Promise<void> {\n const metadataPath = await this.getMetadataPathFromWorktreePath(bareRepoPath, worktreePath);\n\n try {\n await fs.unlink(metadataPath);\n } catch (error) {\n // Ignore errors if file doesn't exist\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n }\n\n async updateLastSync(\n bareRepoPath: string,\n worktreeName: string,\n commit: string,\n action: \"created\" | \"updated\" | \"fetched\" = \"updated\",\n ): Promise<void> {\n const existing = await this.loadMetadata(bareRepoPath, worktreeName);\n\n if (!existing) {\n this.logger.warn(\n `No metadata found for worktree ${worktreeName}; skipping update because upstream/parent context is unavailable`,\n );\n return;\n }\n\n existing.lastSyncCommit = commit;\n existing.lastSyncDate = new Date().toISOString();\n\n existing.syncHistory.push({\n date: existing.lastSyncDate,\n commit,\n action,\n });\n\n if (existing.syncHistory.length > METADATA_CONSTANTS.MAX_HISTORY_ENTRIES) {\n existing.syncHistory = existing.syncHistory.slice(-METADATA_CONSTANTS.MAX_HISTORY_ENTRIES);\n }\n\n await this.saveMetadata(bareRepoPath, worktreeName, existing);\n }\n\n async updateLastSyncFromPath(\n bareRepoPath: string,\n worktreePath: string,\n commit: string,\n action: \"created\" | \"updated\" | \"fetched\" = \"updated\",\n defaultBranch?: string,\n ): Promise<void> {\n const worktreeDirName = this.getWorktreeDirectoryName(worktreePath);\n const existing = await this.loadMetadataFromPath(bareRepoPath, worktreePath);\n\n if (!existing) {\n this.logger.warn(`No metadata found for worktree ${worktreeDirName}`);\n this.logger.info(` Attempting to create initial metadata...`);\n\n try {\n const worktreeGit = simpleGit(worktreePath);\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n\n const branchSummary = await worktreeGit.branch();\n const actualBranchName = branchSummary.current;\n\n if (!actualBranchName) {\n throw new Error(\"Could not determine current branch name\");\n }\n\n let upstreamBranch = `origin/${actualBranchName}`;\n try {\n const configuredUpstream = await worktreeGit.raw([\n \"rev-parse\",\n \"--abbrev-ref\",\n `${actualBranchName}@{upstream}`,\n ]);\n if (configuredUpstream.trim()) {\n upstreamBranch = configuredUpstream.trim();\n }\n } catch {\n // No configured upstream, use constructed value\n }\n\n const parentBranch = defaultBranch || GIT_CONSTANTS.DEFAULT_BRANCH;\n\n await this.createInitialMetadataFromPath(\n bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n upstreamBranch,\n parentBranch,\n currentCommit.trim(),\n );\n this.logger.info(` \u2705 Created metadata for ${worktreeDirName}`);\n return;\n } catch (error) {\n this.logger.error(` \u274C Failed to create metadata`, error);\n throw error;\n }\n }\n\n // Update metadata\n existing.lastSyncCommit = commit;\n existing.lastSyncDate = new Date().toISOString();\n\n existing.syncHistory.push({\n date: existing.lastSyncDate,\n commit,\n action,\n });\n\n if (existing.syncHistory.length > METADATA_CONSTANTS.MAX_HISTORY_ENTRIES) {\n existing.syncHistory = existing.syncHistory.slice(-METADATA_CONSTANTS.MAX_HISTORY_ENTRIES);\n }\n\n // Save using the directory name\n await this.saveMetadata(bareRepoPath, worktreeDirName, existing);\n }\n\n async createInitialMetadata(\n bareRepoPath: string,\n worktreeName: string,\n commit: string,\n upstreamBranch: string,\n parentBranch: string,\n parentCommit: string,\n ): Promise<void> {\n const metadata: SyncMetadata = {\n lastSyncCommit: commit,\n lastSyncDate: new Date().toISOString(),\n upstreamBranch,\n createdFrom: {\n branch: parentBranch,\n commit: parentCommit,\n },\n syncHistory: [\n {\n date: new Date().toISOString(),\n commit,\n action: \"created\",\n },\n ],\n };\n\n await this.saveMetadata(bareRepoPath, worktreeName, metadata);\n }\n\n async createInitialMetadataFromPath(\n bareRepoPath: string,\n worktreePath: string,\n commit: string,\n upstreamBranch: string,\n parentBranch: string,\n parentCommit: string,\n ): Promise<void> {\n const worktreeDirName = this.getWorktreeDirectoryName(worktreePath);\n const metadata: SyncMetadata = {\n lastSyncCommit: commit,\n lastSyncDate: new Date().toISOString(),\n upstreamBranch,\n createdFrom: {\n branch: parentBranch,\n commit: parentCommit,\n },\n syncHistory: [\n {\n date: new Date().toISOString(),\n commit,\n action: \"created\",\n },\n ],\n };\n\n await this.saveMetadata(bareRepoPath, worktreeDirName, metadata);\n }\n\n async validateMetadata(metadata: SyncMetadata): Promise<boolean> {\n if (!metadata.lastSyncCommit || !metadata.lastSyncDate || !metadata.upstreamBranch) {\n return false;\n }\n\n if (!/^[0-9a-f]+$/i.test(metadata.lastSyncCommit)) {\n return false;\n }\n\n if (Number.isNaN(new Date(metadata.lastSyncDate).getTime())) {\n return false;\n }\n\n return true;\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { ENV_CONSTANTS, GIT_CONSTANTS, GIT_OPERATIONS, PATH_CONSTANTS } from \"../constants\";\nimport { GitOperationError, WorktreeNotCleanError } from \"../errors\";\nimport { fileExists } from \"../utils/file-exists\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { SimpleGit } from \"simple-git\";\n\nexport interface WorktreeStatusDetails {\n modifiedFiles: number;\n deletedFiles: number;\n renamedFiles: number;\n createdFiles: number;\n conflictedFiles: number;\n untrackedFiles: number;\n unpushedCommitCount?: number;\n stashCount?: number;\n operationType?: string;\n modifiedSubmodules?: string[];\n modifiedFilesList?: string[];\n deletedFilesList?: string[];\n renamedFilesList?: Array<{ from: string; to: string }>;\n createdFilesList?: string[];\n conflictedFilesList?: string[];\n untrackedFilesList?: string[];\n}\n\nexport interface WorktreeStatusResult {\n isClean: boolean;\n hasUnpushedCommits: boolean;\n hasStashedChanges: boolean;\n hasOperationInProgress: boolean;\n hasModifiedSubmodules: boolean;\n upstreamGone: boolean;\n canRemove: boolean;\n reasons: string[];\n details?: WorktreeStatusDetails;\n}\n\nconst OPERATION_FILES: ReadonlyArray<{ file: string; type: string }> = [\n { file: GIT_OPERATIONS.MERGE_HEAD, type: \"merge\" },\n { file: GIT_OPERATIONS.CHERRY_PICK_HEAD, type: \"cherry-pick\" },\n { file: GIT_OPERATIONS.REVERT_HEAD, type: \"revert\" },\n { file: GIT_OPERATIONS.BISECT_LOG, type: \"bisect\" },\n { file: GIT_OPERATIONS.REBASE_MERGE, type: \"rebase\" },\n { file: GIT_OPERATIONS.REBASE_APPLY, type: \"rebase (apply)\" },\n];\n\ninterface WorktreeSnapshot {\n exists: boolean;\n status: Awaited<ReturnType<SimpleGit[\"status\"]>> | null;\n currentBranch: string | null;\n detached: boolean;\n remoteBranches: string[];\n upstream: string | null;\n unpushedCount: number | null;\n stashTotal: number | null;\n submoduleStatus: string | null;\n operationFile: string | null;\n gitDir: string | null;\n untrackedNotIgnored: string[];\n}\n\nexport class WorktreeStatusService {\n private gitInstances = new Map<string, SimpleGit>();\n private logger: Logger;\n\n constructor(\n private readonly config: { skipLfs?: boolean } = {},\n logger?: Logger,\n ) {\n this.logger = logger ?? Logger.createDefault();\n }\n\n async checkWorktreeStatus(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n const status = await worktreeGit.status();\n\n const hasTrackedChanges =\n status.modified.length > 0 ||\n status.deleted.length > 0 ||\n status.renamed.length > 0 ||\n status.created.length > 0 ||\n status.conflicted.length > 0;\n\n if (hasTrackedChanges) {\n return false;\n }\n\n if (status.not_added.length > 0) {\n const untrackedFiles = status.not_added;\n const notIgnoredFiles = await this.filterUntrackedFiles(worktreePath, untrackedFiles);\n return notIgnoredFiles.length === 0;\n }\n\n return true;\n }\n\n async getFullWorktreeStatus(\n worktreePath: string,\n includeDetails = false,\n lastSyncCommit?: string,\n ): Promise<WorktreeStatusResult> {\n if (!(await fileExists(worktreePath))) {\n return {\n isClean: true,\n hasUnpushedCommits: false,\n hasStashedChanges: false,\n hasOperationInProgress: false,\n hasModifiedSubmodules: false,\n upstreamGone: false,\n canRemove: true,\n reasons: [],\n };\n }\n\n const snap = await this.collectSnapshot(worktreePath, lastSyncCommit);\n\n const isClean = this.deriveIsClean(snap);\n const hasUnpushedCommits = !snap.detached && (snap.unpushedCount ?? 1) > 0;\n const hasStashedChanges = snap.stashTotal === null ? true : snap.stashTotal > 0;\n const hasOperationInProgress = snap.gitDir === null ? true : snap.operationFile !== null;\n const hasModifiedSubmodules = this.deriveModifiedSubmodules(snap).length > 0 || snap.submoduleStatus === null;\n const upstreamGone =\n !snap.detached && snap.upstream !== null && snap.remoteBranches.length > 0\n ? !snap.remoteBranches.includes(snap.upstream)\n : false;\n\n const reasons: string[] = [];\n if (!isClean) reasons.push(\"uncommitted changes\");\n if (hasUnpushedCommits) reasons.push(\"unpushed commits\");\n if (hasStashedChanges) reasons.push(\"stashed changes\");\n if (hasOperationInProgress) reasons.push(\"operation in progress\");\n if (hasModifiedSubmodules) reasons.push(\"modified submodules\");\n if (upstreamGone) reasons.push(\"upstream gone\");\n\n const canRemove =\n isClean && !hasUnpushedCommits && !hasStashedChanges && !hasOperationInProgress && !hasModifiedSubmodules;\n\n const details: WorktreeStatusDetails | undefined = includeDetails ? this.buildStatusDetails(snap) : undefined;\n\n return {\n isClean,\n hasUnpushedCommits,\n hasStashedChanges,\n hasOperationInProgress,\n hasModifiedSubmodules,\n upstreamGone,\n canRemove,\n reasons,\n details,\n };\n }\n\n private async collectSnapshot(worktreePath: string, lastSyncCommit?: string): Promise<WorktreeSnapshot> {\n const git = this.createGitInstance(worktreePath);\n\n const [status, branchResult, remoteBranchesResult, stashResult, submoduleResult, gitDirResult] = await Promise.all([\n git.status().catch((e: unknown) => {\n this.logger.error(`Error reading status for ${worktreePath}`, e);\n return null;\n }),\n git.branch().catch(() => null),\n git.branch([\"-r\"]).catch(() => null),\n git.stashList().catch((e: unknown) => {\n this.logger.error(`Error checking stash`, e);\n return null;\n }),\n git.raw([\"submodule\", \"status\"]).catch((e: unknown) => {\n this.logger.error(`Error checking submodule status`, e);\n return null;\n }),\n this.resolveGitDir(worktreePath).catch((e: unknown) => {\n this.logger.error(`Error checking operation in progress for ${worktreePath}`, e);\n return null;\n }),\n ]);\n\n const currentBranch = branchResult?.current ?? null;\n const detached = !branchResult?.current || Boolean((branchResult as { detached?: boolean })?.detached);\n\n let upstream: string | null = null;\n let unpushedCount: number | null = null;\n if (!detached && currentBranch) {\n const revListArgs = lastSyncCommit\n ? [\"rev-list\", \"--count\", `${lastSyncCommit}..HEAD`]\n : [\"rev-list\", \"--count\", currentBranch, \"--not\", \"--remotes\"];\n\n const [upstreamResult, unpushedResult] = await Promise.all([\n git.raw([\"rev-parse\", \"--abbrev-ref\", `${currentBranch}@{upstream}`]).then(\n (raw) => ({ ok: true as const, value: raw }),\n (error: unknown) => ({ ok: false as const, error }),\n ),\n git.raw(revListArgs).then(\n (raw) => ({ ok: true as const, value: raw }),\n (error: unknown) => ({ ok: false as const, error }),\n ),\n ]);\n\n if (upstreamResult.ok) {\n upstream = upstreamResult.value.trim() || null;\n } else {\n const errorMessage = getErrorMessage(upstreamResult.error);\n if (\n !errorMessage.includes(\"fatal: no upstream configured\") &&\n !errorMessage.includes(\"no upstream configured for branch\") &&\n !errorMessage.includes(\"fatal: ambiguous argument\") &&\n !errorMessage.includes(\"unknown revision or path\")\n ) {\n this.logger.error(`Unexpected error checking upstream status for ${worktreePath}: ${errorMessage}`);\n }\n }\n\n if (unpushedResult.ok) {\n unpushedCount = parseInt(unpushedResult.value.trim(), 10);\n } else {\n this.logger.error(`Error checking unpushed commits`, unpushedResult.error);\n }\n }\n\n const operationFile = gitDirResult ? await this.detectOperationFile(gitDirResult) : null;\n\n let untrackedNotIgnored: string[] = [];\n if (status && status.not_added.length > 0) {\n try {\n untrackedNotIgnored = await this.filterUntrackedFiles(worktreePath, status.not_added);\n } catch {\n untrackedNotIgnored = status.not_added;\n }\n }\n\n return {\n exists: true,\n status,\n currentBranch,\n detached,\n remoteBranches: remoteBranchesResult?.all ?? [],\n upstream,\n unpushedCount,\n stashTotal: stashResult?.total ?? null,\n submoduleStatus: submoduleResult,\n operationFile,\n gitDir: gitDirResult,\n untrackedNotIgnored,\n };\n }\n\n private deriveIsClean(snap: WorktreeSnapshot): boolean {\n const status = snap.status;\n if (!status) return false;\n const hasTracked =\n status.modified.length > 0 ||\n status.deleted.length > 0 ||\n status.renamed.length > 0 ||\n status.created.length > 0 ||\n status.conflicted.length > 0;\n if (hasTracked) return false;\n return snap.untrackedNotIgnored.length === 0;\n }\n\n private deriveModifiedSubmodules(snap: WorktreeSnapshot): string[] {\n if (!snap.submoduleStatus) return [];\n const modified: string[] = [];\n for (const line of snap.submoduleStatus.split(\"\\n\").filter((l) => l.trim())) {\n const firstChar = line.charAt(0);\n if (firstChar === GIT_CONSTANTS.SUBMODULE_STATUS_ADDED || firstChar === GIT_CONSTANTS.SUBMODULE_STATUS_REMOVED) {\n const match = line.match(/^[+-]\\s*(\\S+)/);\n if (match) modified.push(match[1]);\n }\n }\n return modified;\n }\n\n private buildStatusDetails(snap: WorktreeSnapshot): WorktreeStatusDetails {\n const status = snap.status;\n const details: WorktreeStatusDetails = {\n modifiedFiles: status?.modified.length ?? 0,\n deletedFiles: status?.deleted.length ?? 0,\n renamedFiles: status?.renamed.length ?? 0,\n createdFiles: status?.created.length ?? 0,\n conflictedFiles: status?.conflicted.length ?? 0,\n untrackedFiles: snap.untrackedNotIgnored.length,\n };\n if (status) {\n if (status.modified.length > 0) details.modifiedFilesList = status.modified;\n if (status.deleted.length > 0) details.deletedFilesList = status.deleted;\n if (status.renamed.length > 0) {\n details.renamedFilesList = status.renamed.map((r) => ({ from: r.from, to: r.to }));\n }\n if (status.created.length > 0) details.createdFilesList = status.created;\n if (status.conflicted.length > 0) details.conflictedFilesList = status.conflicted;\n }\n if (snap.untrackedNotIgnored.length > 0) details.untrackedFilesList = snap.untrackedNotIgnored;\n if (!snap.detached && snap.unpushedCount !== null) details.unpushedCommitCount = snap.unpushedCount;\n if (snap.stashTotal !== null) details.stashCount = snap.stashTotal;\n const opType = this.operationTypeFromFile(snap.operationFile);\n if (opType) details.operationType = opType;\n const modSubs = this.deriveModifiedSubmodules(snap);\n if (modSubs.length > 0) details.modifiedSubmodules = modSubs;\n return details;\n }\n\n private operationTypeFromFile(file: string | null): string | undefined {\n if (!file) return undefined;\n return OPERATION_FILES.find((op) => op.file === file)?.type;\n }\n\n private async detectOperationFile(gitDir: string): Promise<string | null> {\n const results = await Promise.all(\n OPERATION_FILES.map(({ file }) =>\n fs.access(path.join(gitDir, file)).then(\n () => true,\n () => false,\n ),\n ),\n );\n const idx = results.findIndex(Boolean);\n return idx >= 0 ? OPERATION_FILES[idx].file : null;\n }\n\n async hasUnpushedCommits(worktreePath: string, lastSyncCommit?: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n if (await this.isDetachedHead(worktreeGit)) {\n return false;\n }\n\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n if (lastSyncCommit) {\n try {\n const newCommitsResult = await worktreeGit.raw([\"rev-list\", \"--count\", `${lastSyncCommit}..HEAD`]);\n const newCommitsCount = parseInt(newCommitsResult.trim(), 10);\n return newCommitsCount > 0;\n } catch {\n // Fall through to regular check\n }\n }\n\n const result = await worktreeGit.raw([\"rev-list\", \"--count\", currentBranch, \"--not\", \"--remotes\"]);\n const unpushedCount = parseInt(result.trim(), 10);\n return unpushedCount > 0;\n } catch (error) {\n this.logger.error(`Error checking unpushed commits`, error);\n return true;\n }\n }\n\n async hasUpstreamGone(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n if (await this.isDetachedHead(worktreeGit)) {\n return false;\n }\n\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n const upstream = await worktreeGit.raw([\"rev-parse\", \"--abbrev-ref\", `${currentBranch}@{upstream}`]);\n const remoteBranches = await worktreeGit.branch([\"-r\"]);\n\n return !remoteBranches.all.includes(upstream.trim());\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n if (\n errorMessage.includes(\"fatal: no upstream configured\") ||\n errorMessage.includes(\"no upstream configured for branch\") ||\n errorMessage.includes(\"fatal: ambiguous argument\") ||\n errorMessage.includes(\"unknown revision or path\")\n ) {\n return false;\n }\n\n this.logger.error(`Unexpected error checking upstream status for ${worktreePath}: ${errorMessage}`);\n return true;\n }\n }\n\n async hasStashedChanges(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n const stashList = await worktreeGit.stashList();\n return stashList.total > 0;\n } catch (error) {\n this.logger.error(`Error checking stash`, error);\n return true; // Conservative: assume unsafe to delete\n }\n }\n\n async hasModifiedSubmodules(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n const result = await worktreeGit.raw([\"submodule\", \"status\"]);\n const lines = result.split(\"\\n\").filter((line) => line.trim());\n\n for (const line of lines) {\n const firstChar = line.charAt(0);\n if (\n firstChar === GIT_CONSTANTS.SUBMODULE_STATUS_ADDED ||\n firstChar === GIT_CONSTANTS.SUBMODULE_STATUS_REMOVED\n ) {\n return true;\n }\n }\n return false;\n } catch (error) {\n this.logger.error(`Error checking submodule status`, error);\n return true;\n }\n }\n\n async hasOperationInProgress(worktreePath: string): Promise<boolean> {\n try {\n const gitDir = await this.resolveGitDir(worktreePath);\n return (await this.detectOperationFile(gitDir)) !== null;\n } catch (error) {\n this.logger.error(`Error checking operation in progress for ${worktreePath}`, error);\n return true;\n }\n }\n\n async validateWorktreeForRemoval(worktreePath: string, lastSyncCommit?: string): Promise<void> {\n const status = await this.getFullWorktreeStatus(worktreePath, false, lastSyncCommit);\n\n if (!status.canRemove) {\n throw new WorktreeNotCleanError(worktreePath, status.reasons);\n }\n }\n\n private async filterUntrackedFiles(worktreePath: string, files: string[]): Promise<string[]> {\n if (files.length === 0) return [];\n\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n const result = await worktreeGit.raw([\"check-ignore\", \"--\", ...files]);\n\n const ignoredFiles = new Set(\n result\n .trim()\n .split(\"\\n\")\n .filter((f) => f),\n );\n return files.filter((f) => !ignoredFiles.has(f));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n if (errorMessage.includes(GIT_CONSTANTS.GIT_CHECK_IGNORE_NO_MATCH)) {\n return files;\n }\n\n throw error;\n }\n }\n\n private async isDetachedHead(worktreeGit: SimpleGit): Promise<boolean> {\n try {\n const branchSummary = await worktreeGit.branch();\n return !branchSummary.current || branchSummary.detached;\n } catch {\n return true;\n }\n }\n\n private async resolveGitDir(worktreePath: string): Promise<string> {\n const gitPath = path.join(worktreePath, PATH_CONSTANTS.GIT_DIR);\n\n try {\n const stat = await fs.stat(gitPath);\n\n if (stat.isFile()) {\n const content = await fs.readFile(gitPath, \"utf-8\");\n const gitdirMatch = content.match(new RegExp(`^${GIT_CONSTANTS.GITDIR_PREFIX}\\\\s*(.+)$`, \"m\"));\n if (gitdirMatch) {\n return path.resolve(worktreePath, gitdirMatch[1].trim());\n }\n throw new GitOperationError(\"resolve-git-dir\", `Failed to parse gitdir from .git file at ${gitPath}`);\n }\n\n return gitPath;\n } catch (error) {\n throw new GitOperationError(\n \"resolve-git-dir\",\n `Failed to resolve .git directory for ${worktreePath}`,\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n private createGitInstance(worktreePath: string): SimpleGit {\n const key = `${path.resolve(worktreePath)}::${this.config.skipLfs ? \"1\" : \"0\"}`;\n let git = this.gitInstances.get(key);\n if (!git) {\n git = this.config.skipLfs\n ? simpleGit(worktreePath).env({ [ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE]: \"1\" })\n : simpleGit(worktreePath);\n this.gitInstances.set(key, git);\n }\n return git;\n }\n}\n", "export interface ProgressEvent {\n phase: string;\n message: string;\n progress?: number;\n processed?: number;\n total?: number;\n}\n\nexport type ProgressListener = (event: ProgressEvent) => void;\n\nexport class ProgressEmitter {\n private listeners = new Set<ProgressListener>();\n\n onProgress(listener: ProgressListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n emit(event: ProgressEvent): void {\n // Snapshot so a listener that unsubscribes a sibling during emit doesn't\n // skip that sibling's notification for this event.\n for (const listener of [...this.listeners]) {\n try {\n listener(event);\n } catch {\n // Progress listeners must not break sync flow.\n }\n }\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport * as lockfile from \"proper-lockfile\";\n\nimport { DEFAULT_CONFIG, ENV_CONSTANTS } from \"../constants\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\nimport { getCloneModeLockTarget } from \"../utils/lock-path\";\nimport { REPOSITORY_MODES, resolveMode } from \"../utils/repo-mode\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { Config } from \"../types\";\nimport type { GitService } from \"./git.service\";\n\nexport type RepoLockRelease = () => Promise<void>;\n\nexport class RepoOperationLock {\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger = Logger.createDefault(),\n ) {}\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n async acquire(): Promise<RepoLockRelease | null> {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) {\n return async () => {};\n }\n\n if (resolveMode(this.config) === REPOSITORY_MODES.CLONE) {\n return this.acquireCloneModeLock();\n }\n\n return this.acquireWorktreeModeLock();\n }\n\n private async acquireCloneModeLock(): Promise<RepoLockRelease | null> {\n const target = getCloneModeLockTarget(this.config);\n const lockTarget = path.join(target.dir, target.file);\n try {\n await fs.mkdir(target.dir, { recursive: true });\n await fs.writeFile(lockTarget, \"\", { flag: \"a\" });\n } catch {\n // Couldn't prepare the lock target (read-only FS, ENOSPC, EACCES).\n // Treat as 'unable to acquire' so the operation is skipped cleanly\n // instead of crashing the whole sync run.\n return null;\n }\n return this.lockPath(lockTarget);\n }\n\n private async acquireWorktreeModeLock(): Promise<RepoLockRelease | null> {\n const barePath = this.gitService.getBareRepoPath();\n try {\n await fs.mkdir(barePath, { recursive: true });\n } catch {\n return null;\n }\n return this.lockPath(barePath);\n }\n\n private async lockPath(lockTarget: string): Promise<RepoLockRelease | null> {\n try {\n return await lockfile.lock(lockTarget, {\n stale: DEFAULT_CONFIG.LOCK_STALE_MS,\n update: DEFAULT_CONFIG.LOCK_UPDATE_MS,\n retries: 0,\n realpath: false,\n });\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ELOCKED\") {\n return null;\n }\n // A lock we cannot acquire (read-only FS, EACCES/EROFS/EPERM surfaced at\n // lock time rather than during prep) must be a clean skip, never a fatal\n // error that crashes the whole multi-repo run. Surface it as a warning so\n // the cause is visible.\n this.logger.warn(\n `Could not acquire repo lock at '${lockTarget}' (${code ?? \"unknown\"}: ${getErrorMessage(error)}); skipping.`,\n );\n return null;\n }\n }\n}\n", "import { createHash } from \"crypto\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\nimport { sanitizeNameForPath } from \"./sanitize-name\";\n\nimport type { Config, RepositoryConfig } from \"../types\";\n\nexport interface RepoLockTarget {\n /** Absolute path to the directory that should contain the lock file. */\n dir: string;\n /** Lock filename (created lazily by proper-lockfile). */\n file: string;\n}\n\nexport function getCloneModeLockTarget(config: Config): RepoLockTarget {\n const name = (config as RepositoryConfig).name;\n const configDir = config.__configFileDir;\n\n const hash = createHash(\"sha256\").update(path.resolve(config.worktreeDir)).digest(\"hex\").slice(0, 16);\n\n if (configDir) {\n return {\n dir: path.join(configDir, \".sync-worktrees-state\"),\n file: `${sanitizeNameForPath(name ?? \"repo\", \"clone-mode lock name\")}-${hash}.lock`,\n };\n }\n\n const stateBase =\n process.env.XDG_STATE_HOME && process.env.XDG_STATE_HOME.length > 0\n ? process.env.XDG_STATE_HOME\n : path.join(os.homedir(), \".cache\");\n const dir = path.join(stateBase, \"sync-worktrees\", \"locks\");\n return { dir, file: `${hash}.lock` };\n}\n", "import { getErrorMessage } from \"../utils/lfs-error\";\n\nimport type { GitService } from \"./git.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { Config } from \"../types\";\nimport type { RetryOptions } from \"../utils/retry\";\n\nexport interface SyncRetryContext {\n lfsSkipEnabled: boolean;\n}\n\nexport class SyncRetryPolicy {\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger,\n ) {}\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n createContext(): SyncRetryContext {\n return { lfsSkipEnabled: false };\n }\n\n createOptions(syncContext: SyncRetryContext): RetryOptions {\n return {\n maxAttempts: this.config.retry?.maxAttempts ?? 3,\n maxLfsRetries: this.config.retry?.maxLfsRetries ?? 2,\n initialDelayMs: this.config.retry?.initialDelayMs ?? 1000,\n maxDelayMs: this.config.retry?.maxDelayMs ?? 30000,\n backoffMultiplier: this.config.retry?.backoffMultiplier ?? 2,\n jitterMs: this.config.retry?.jitterMs ?? 0,\n onRetry: (error, attempt, context): void => {\n const errorMessage = getErrorMessage(error);\n this.logger.info(`\\n\u26A0\uFE0F Sync attempt ${attempt} failed: ${errorMessage}`);\n\n if (context?.isLfsError && !this.config.skipLfs) {\n this.logger.info(`\uD83D\uDD04 LFS error detected. Will retry with LFS skipped...`);\n } else {\n this.logger.info(`\uD83D\uDD04 Retrying synchronization...\\n`);\n }\n },\n lfsRetryHandler: (): void => {\n if (!this.config.skipLfs && !syncContext.lfsSkipEnabled) {\n this.logger.info(\"\u26A0\uFE0F Temporarily disabling LFS downloads for this sync...\");\n this.gitService.setLfsSkipEnabled(true);\n syncContext.lfsSkipEnabled = true;\n }\n },\n };\n }\n\n resetLfsSkipIfNeeded(syncContext: SyncRetryContext): void {\n if (syncContext.lfsSkipEnabled && !this.config.skipLfs) {\n this.gitService.setLfsSkipEnabled(false);\n }\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport pLimit from \"p-limit\";\n\nimport { DEFAULT_CONFIG, ERROR_MESSAGES, GIT_CONSTANTS, METADATA_CONSTANTS } from \"../constants\";\nimport { filterBranchesByName } from \"../utils/branch-filter\";\nimport { filterBranchesByAge, formatDuration } from \"../utils/date-filter\";\nimport { getErrorMessage, isLfsError } from \"../utils/lfs-error\";\n\nimport { PathResolutionService } from \"./path-resolution.service\";\nimport { createWorktreeSyncPlan } from \"./worktree-sync-planner\";\n\nimport type { GitService } from \"./git.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { ProgressEmitter } from \"./progress-emitter\";\nimport type { SyncOutcomeAccumulator } from \"./sync-outcome\";\nimport type { SyncRetryContext } from \"./sync-retry-policy\";\nimport type { WorktreeStatusDetails } from \"./worktree-status.service\";\nimport type { CreateAction, PruneAction, SparseAction, SyncPlan, UpdateAction } from \"./worktree-sync-planner\";\nimport type { Config } from \"../types\";\nimport type { PhaseTimer } from \"../utils/timing\";\n\nexport class WorktreeModeSyncRunner {\n private pathResolution = new PathResolutionService();\n\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger,\n private progressEmitter: ProgressEmitter,\n ) {}\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n async runSyncAttempt(\n phaseTimer: PhaseTimer,\n syncContext: SyncRetryContext,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n await this.gitService.pruneWorktrees();\n await this.fetchLatestRemoteData(phaseTimer, syncContext);\n\n const { remoteBranches, defaultBranch } = await this.resolveSyncBranches();\n\n await fs.mkdir(this.config.worktreeDir, { recursive: true });\n\n const worktrees = await this.gitService.getWorktrees();\n this.logger.info(`Found ${worktrees.length} existing Git worktrees.`);\n\n await this.cleanupOrphanedDirectories(worktrees);\n const syncPlan = createWorktreeSyncPlan(\n {\n remoteBranches,\n defaultBranch,\n existingWorktrees: worktrees,\n worktreeDir: this.config.worktreeDir,\n },\n {\n pathResolution: this.pathResolution,\n updateExistingWorktrees: this.config.updateExistingWorktrees !== false,\n sparseCheckout: this.config.sparseCheckout,\n },\n );\n\n await this.createNewWorktreesWithTiming(syncPlan, phaseTimer, outcome);\n await this.pruneOldWorktreesWithTiming(syncPlan.prune, phaseTimer, outcome);\n\n if (this.config.updateExistingWorktrees !== false) {\n await this.updateExistingWorktreesWithTiming(syncPlan.update, phaseTimer, outcome);\n }\n\n if (this.config.sparseCheckout) {\n await this.reapplySparseCheckout(syncPlan.sparse, outcome);\n }\n\n await this.finalizeSyncAttempt(phaseTimer);\n }\n\n private async reapplySparseCheckout(actions: SparseAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n const sparseConfig = this.config.sparseCheckout;\n if (!sparseConfig) return;\n\n this.logger.info(\"Step 5: Reconciling sparse-checkout patterns on existing worktrees...\");\n const sparseService = this.gitService.getSparseCheckoutService();\n const desired = sparseService.buildPatterns(sparseConfig);\n\n const limit = pLimit(this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\n\n await Promise.all(\n actions.map((action) =>\n limit(async () => {\n if (action.kind !== \"check-sparse\") return;\n\n try {\n try {\n await fs.access(action.path);\n } catch {\n return;\n }\n\n const current = await sparseService.readCurrent(action.path);\n if (current !== null && sparseService.patternsEqual(current, desired)) return;\n\n if (sparseService.isNarrowing(current, desired)) {\n const status = await this.gitService.getFullWorktreeStatus(action.path, false);\n if (!status.canRemove) {\n this.logger.warn(\n ` - Skipping sparse-checkout narrowing for '${action.branch}': ${status.reasons.join(\", \")}.`,\n );\n outcome.recordSkipped(\"sparse-checkout\", \"sparse_narrowing_unsafe\", {\n branch: action.branch,\n path: action.path,\n message: status.reasons.join(\", \"),\n });\n return;\n }\n }\n\n await sparseService.applyToWorktree(action.path, sparseConfig);\n await this.gitService.checkoutHead(action.path);\n this.logger.info(` - \u2705 Sparse-checkout updated for '${action.branch}'`);\n outcome.recordUpdated(action.branch, action.path, \"sparse_checkout\");\n } catch (error) {\n this.logger.warn(\n ` - \u26A0\uFE0F Failed to update sparse-checkout for '${action.branch}': ${getErrorMessage(error)}`,\n );\n outcome.recordFailed(\"sparse-checkout\", getErrorMessage(error), {\n reason: \"sparse_checkout_failed\",\n branch: action.branch,\n path: action.path,\n });\n }\n }),\n ),\n );\n }\n\n private async fetchLatestRemoteData(phaseTimer: PhaseTimer, syncContext: SyncRetryContext): Promise<void> {\n this.logger.info(\"Step 1: Fetching latest data from remote...\");\n phaseTimer.startPhase(\"Phase 1: Fetch\");\n this.progressEmitter.emit({ phase: \"fetch\", message: \"Fetching latest data from remote\" });\n\n try {\n await this.gitService.fetchAll();\n } catch (fetchError) {\n const errorMessage = getErrorMessage(fetchError);\n\n if (isLfsError(errorMessage) && !syncContext.lfsSkipEnabled && !this.config.skipLfs) {\n this.logger.info(\"\u26A0\uFE0F Fetch all failed due to LFS error. Attempting branch-by-branch fetch...\");\n this.logger.info(\"\u26A0\uFE0F Temporarily disabling LFS downloads for branch-by-branch fetch...\");\n this.gitService.setLfsSkipEnabled(true);\n syncContext.lfsSkipEnabled = true;\n await this.fetchBranchByBranch();\n } else {\n throw fetchError;\n }\n } finally {\n phaseTimer.endPhase();\n }\n }\n\n private async resolveSyncBranches(): Promise<{ remoteBranches: string[]; defaultBranch: string }> {\n const remoteBranches = this.config.branchMaxAge\n ? await this.getRemoteBranchesFilteredByActivity()\n : await this.getRemoteBranchesFilteredByName();\n const defaultBranch = this.gitService.getDefaultBranch();\n\n if (!remoteBranches.includes(defaultBranch)) {\n remoteBranches.push(defaultBranch);\n this.logger.info(`Ensuring default branch '${defaultBranch}' is retained.`);\n }\n\n return { remoteBranches, defaultBranch };\n }\n\n private async getRemoteBranchesFilteredByActivity(): Promise<string[]> {\n const branchesWithActivity = await this.gitService.getRemoteBranchesWithActivity();\n this.logger.info(`Found ${branchesWithActivity.length} remote branches.`);\n\n const branchNames = filterBranchesByName(\n branchesWithActivity.map((b) => b.branch),\n this.config.branchInclude,\n this.config.branchExclude,\n );\n\n if (branchNames.length < branchesWithActivity.length) {\n this.logger.info(\n `After branch name filtering: ${branchNames.length} of ${branchesWithActivity.length} branches.`,\n );\n }\n\n const branchNameSet = new Set(branchNames);\n const filteredByName = branchesWithActivity.filter((b) => branchNameSet.has(b.branch));\n const filteredBranches = filterBranchesByAge(filteredByName, this.config.branchMaxAge!);\n const remoteBranches = filteredBranches.map((b) => b.branch);\n\n this.logger.info(\n `After filtering by age (${formatDuration(this.config.branchMaxAge!)}): ${remoteBranches.length} branches.`,\n );\n\n if (filteredByName.length > remoteBranches.length) {\n const excludedCount = filteredByName.length - remoteBranches.length;\n this.logger.info(` - Excluded ${excludedCount} stale branches.`);\n }\n\n return remoteBranches;\n }\n\n private async getRemoteBranchesFilteredByName(): Promise<string[]> {\n const allBranches = await this.gitService.getRemoteBranches();\n this.logger.info(`Found ${allBranches.length} remote branches.`);\n\n const remoteBranches = filterBranchesByName(allBranches, this.config.branchInclude, this.config.branchExclude);\n\n if (remoteBranches.length < allBranches.length) {\n this.logger.info(`After branch name filtering: ${remoteBranches.length} of ${allBranches.length} branches.`);\n }\n\n return remoteBranches;\n }\n\n private async finalizeSyncAttempt(phaseTimer: PhaseTimer): Promise<void> {\n phaseTimer.startPhase(\"Phase 5: Cleanup\");\n this.progressEmitter.emit({ phase: \"cleanup\", message: \"Pruning worktree metadata\" });\n await this.gitService.pruneWorktrees();\n this.logger.info(\"Step 5: Pruned worktree metadata.\");\n phaseTimer.endPhase();\n }\n\n private async createNewWorktreesWithTiming(\n syncPlan: SyncPlan,\n phaseTimer: PhaseTimer,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n const maxConcurrent =\n this.config.parallelism?.maxWorktreeCreation ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_CREATION;\n phaseTimer.startPhase(\"Phase 2: Create\", maxConcurrent);\n this.progressEmitter.emit({ phase: \"create\", message: \"Creating worktrees for new branches\" });\n\n await this.createNewWorktrees(syncPlan.create, outcome);\n\n phaseTimer.setPhaseCount(\"Phase 2: Create\", syncPlan.create.length);\n phaseTimer.endPhase();\n }\n\n private async createNewWorktrees(actions: CreateAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n if (actions.length === 0) {\n this.logger.info(\"Step 2: No new branches to create worktrees for.\");\n return;\n }\n\n const plan: Array<{ branchName: string; worktreePath: string }> = [];\n for (const action of actions) {\n if (action.kind === \"skip-create\") {\n this.logger.error(\n ` \u274C Skipping '${action.branch}': sanitized worktree path '${action.path}' collides with existing branch '${action.conflictingBranch}'.`,\n );\n outcome.recordSkipped(\"branch\", \"path_collision\", {\n branch: action.branch,\n path: action.path,\n message: `Path collides with existing branch '${action.conflictingBranch}'`,\n });\n continue;\n }\n\n plan.push({ branchName: action.branch, worktreePath: action.path });\n }\n\n this.logger.info(`Step 2: Creating ${plan.length} new worktrees...`);\n\n // Worktree creation has concurrency=1 by default because Git's worktree.lock\n // can cause race conditions when multiple operations run simultaneously.\n // If concurrent operations try to create the same worktree, we gracefully handle\n // the \"already registered\" error by checking if the worktree actually exists.\n const maxConcurrent =\n this.config.parallelism?.maxWorktreeCreation ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_CREATION;\n const limit = pLimit(maxConcurrent);\n\n const results = await Promise.allSettled(\n plan.map(({ branchName, worktreePath }) =>\n limit(async () => {\n try {\n await this.gitService.addWorktree(branchName, worktreePath);\n this.logger.info(` \u2705 Created worktree for '${branchName}'`);\n outcome.recordCreated(branchName, worktreePath);\n } catch (error) {\n this.logger.error(` \u274C Failed to create worktree for '${branchName}':`, getErrorMessage(error));\n outcome.recordFailed(\"worktree\", getErrorMessage(error), {\n reason: \"create_failed\",\n branch: branchName,\n path: worktreePath,\n });\n throw error;\n }\n }),\n ),\n );\n\n const successCount = results.filter((r) => r.status === \"fulfilled\").length;\n this.logger.info(` Created ${successCount}/${plan.length} worktrees successfully`);\n }\n\n private async pruneOldWorktreesWithTiming(\n actions: PruneAction[],\n phaseTimer: PhaseTimer,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n const maxConcurrent = this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n phaseTimer.startPhase(\"Phase 3: Prune\", maxConcurrent);\n this.progressEmitter.emit({ phase: \"prune\", message: \"Pruning stale worktrees\" });\n\n await this.pruneOldWorktrees(actions, outcome);\n\n phaseTimer.setPhaseCount(\"Phase 3: Prune\", actions.length);\n phaseTimer.endPhase();\n }\n\n private async pruneOldWorktrees(actions: PruneAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n if (actions.length > 0) {\n this.logger.info(`Step 3: Checking ${actions.length} stale worktrees to prune...`);\n\n // Two-phase approach: First check status in parallel (read-only, safe),\n // then remove worktrees in parallel (mutation, needs lower concurrency)\n const maxConcurrent = this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n const limit = pLimit(maxConcurrent);\n\n const statusResults = await Promise.allSettled(\n actions.map(({ branch: branchName, path: worktreePath }) =>\n limit(async () => {\n const status = await this.gitService.getFullWorktreeStatus(worktreePath, this.config.debug);\n return { branchName, worktreePath, status };\n }).catch((error) => {\n throw Object.assign(error instanceof Error ? error : new Error(String(error)), { branchName });\n }),\n ),\n );\n\n const toRemove: Array<{ branchName: string; worktreePath: string }> = [];\n const toSkip: Array<{\n branchName: string;\n worktreePath: string;\n status: Awaited<ReturnType<GitService[\"getFullWorktreeStatus\"]>>;\n }> = [];\n\n for (const result of statusResults) {\n if (result.status === \"fulfilled\") {\n const { branchName, worktreePath, status } = result.value;\n if (status.canRemove) {\n toRemove.push({ branchName, worktreePath });\n } else {\n toSkip.push({ branchName, worktreePath, status });\n }\n } else {\n const branchName = (result.reason as Error & { branchName?: string })?.branchName ?? \"unknown\";\n this.logger.error(` - Error checking worktree '${branchName}':`, result.reason);\n this.logger.warn(` - \u26A0\uFE0F Skipping removal of '${branchName}' due to status check failure (conservative)`);\n outcome.recordSkipped(\"worktree\", \"prune_status_check_failed\", {\n branch: branchName,\n message: getErrorMessage(result.reason),\n });\n }\n }\n\n if (toRemove.length > 0) {\n const removeLimit = pLimit(\n this.config.parallelism?.maxWorktreeRemoval ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_REMOVAL,\n );\n\n const removeResults = await Promise.allSettled(\n toRemove.map(({ branchName, worktreePath }) =>\n removeLimit(async () => {\n try {\n // Re-validate status immediately before removal to close TOCTOU window.\n const recheck = await this.gitService.getFullWorktreeStatus(worktreePath, false);\n if (!recheck.canRemove) {\n this.logger.warn(\n ` \u26A0\uFE0F Skipping removal of '${branchName}' - status changed since initial check: ${recheck.reasons.join(\", \")}`,\n );\n outcome.recordSkipped(\"worktree\", \"prune_status_changed\", {\n branch: branchName,\n path: worktreePath,\n message: recheck.reasons.join(\", \"),\n });\n return;\n }\n await this.gitService.removeWorktree(worktreePath);\n this.logger.info(` \u2705 Removed worktree for '${branchName}'`);\n outcome.recordRemoved(branchName, worktreePath);\n } catch (error) {\n this.logger.error(` \u274C Failed to remove worktree for '${branchName}':`, getErrorMessage(error));\n outcome.recordFailed(\"worktree\", getErrorMessage(error), {\n reason: \"remove_failed\",\n branch: branchName,\n path: worktreePath,\n });\n throw error;\n }\n }),\n ),\n );\n\n const removedCount = removeResults.filter((r) => r.status === \"fulfilled\").length;\n this.logger.info(` Removed ${removedCount}/${toRemove.length} worktrees successfully`);\n }\n\n if (toSkip.length > 0) {\n this.logger.info(` Skipped ${toSkip.length} worktree(s) with local changes or unpushed commits`);\n }\n\n for (const { branchName, worktreePath, status } of toSkip) {\n outcome.recordSkipped(\"worktree\", \"unsafe_to_remove\", {\n branch: branchName,\n path: worktreePath,\n message: status.reasons.join(\", \"),\n });\n\n if (status.upstreamGone && status.hasUnpushedCommits) {\n this.logger.warn(` - \u26A0\uFE0F Cannot automatically remove '${branchName}' - upstream branch was deleted.`);\n this.logger.info(` Please review manually: cd ${worktreePath} && git log`);\n this.logger.info(\n ` If changes were squash-merged, you can safely remove with: git worktree remove ${worktreePath}`,\n );\n } else {\n this.logger.info(` - \u26A0\uFE0F Skipping removal of '${branchName}' due to: ${status.reasons.join(\", \")}.`);\n }\n\n if (this.config.debug && status.details) {\n this.logDebugDetails(branchName, status.details);\n }\n }\n } else {\n this.logger.info(\"Step 3: No stale worktrees to prune.\");\n }\n }\n\n private logDebugDetails(branchName: string, details: WorktreeStatusDetails): void {\n this.logger.info(`\\n \uD83D\uDD0D Debug details for '${branchName}':`);\n\n if (details.modifiedFiles > 0 && details.modifiedFilesList) {\n this.logger.info(` - Modified files (${details.modifiedFiles}):`);\n details.modifiedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.deletedFiles > 0 && details.deletedFilesList) {\n this.logger.info(` - Deleted files (${details.deletedFiles}):`);\n details.deletedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.renamedFiles > 0 && details.renamedFilesList) {\n this.logger.info(` - Renamed files (${details.renamedFiles}):`);\n details.renamedFilesList.forEach((file) => this.logger.info(` \u2022 ${file.from} \u2192 ${file.to}`));\n }\n if (details.createdFiles > 0 && details.createdFilesList) {\n this.logger.info(` - Created files (${details.createdFiles}):`);\n details.createdFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.conflictedFiles > 0 && details.conflictedFilesList) {\n this.logger.info(` - Conflicted files (${details.conflictedFiles}):`);\n details.conflictedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.untrackedFiles > 0 && details.untrackedFilesList) {\n this.logger.info(` - Untracked files (not ignored) (${details.untrackedFiles}):`);\n details.untrackedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.unpushedCommitCount !== undefined && details.unpushedCommitCount > 0) {\n this.logger.info(` - Unpushed commits: ${details.unpushedCommitCount}`);\n }\n if (details.stashCount !== undefined && details.stashCount > 0) {\n this.logger.info(` - Stashed changes: ${details.stashCount}`);\n }\n if (details.operationType) {\n this.logger.info(` - Operation in progress: ${details.operationType}`);\n }\n if (details.modifiedSubmodules && details.modifiedSubmodules.length > 0) {\n this.logger.info(` - Modified submodules (${details.modifiedSubmodules.length}):`);\n details.modifiedSubmodules.forEach((submodule) => this.logger.info(` \u2022 ${submodule}`));\n }\n\n this.logger.info(\"\");\n }\n\n private async fetchBranchByBranch(): Promise<void> {\n this.logger.info(\"Fetching branches individually to isolate LFS errors...\");\n\n const remoteBranches = await this.gitService.getRemoteBranches();\n this.logger.info(`Found ${remoteBranches.length} remote branches to fetch.`);\n\n const fetchLimit = pLimit(\n this.config.parallelism?.maxBranchFetches ?? DEFAULT_CONFIG.PARALLELISM.MAX_BRANCH_FETCHES,\n );\n const failedBranches: string[] = [];\n let successCount = 0;\n\n const results = await Promise.allSettled(\n remoteBranches.map((branch) =>\n fetchLimit(async () => {\n await this.gitService.fetchBranch(branch);\n return branch;\n }),\n ),\n );\n\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n if (result.status === \"fulfilled\") {\n successCount++;\n } else {\n const errorMessage = getErrorMessage(result.reason);\n this.logger.info(` \u26A0\uFE0F Failed to fetch branch '${remoteBranches[i]}': ${errorMessage}`);\n failedBranches.push(remoteBranches[i]);\n }\n }\n\n this.logger.info(`Branch-by-branch fetch completed: ${successCount}/${remoteBranches.length} successful`);\n\n if (failedBranches.length > 0) {\n this.logger.info(`\u26A0\uFE0F Failed to fetch ${failedBranches.length} branches due to errors.`);\n this.logger.info(` These branches will be skipped: ${failedBranches.join(\", \")}`);\n }\n }\n\n private async updateExistingWorktreesWithTiming(\n actions: UpdateAction[],\n phaseTimer: PhaseTimer,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n const maxConcurrent =\n this.config.parallelism?.maxWorktreeUpdates ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_UPDATES;\n phaseTimer.startPhase(\"Phase 4: Update\", maxConcurrent);\n this.progressEmitter.emit({ phase: \"update\", message: \"Updating existing worktrees\" });\n\n await this.updateExistingWorktrees(actions, outcome);\n\n phaseTimer.setPhaseCount(\"Phase 4: Update\", actions.length);\n phaseTimer.endPhase();\n }\n\n private async updateExistingWorktrees(actions: UpdateAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n this.logger.info(\"Step 4: Checking for worktrees that need updates...\");\n\n const divergedDir = path.join(this.config.worktreeDir, GIT_CONSTANTS.DIVERGED_DIR_NAME);\n try {\n const diverged = await fs.readdir(divergedDir);\n if (diverged.length > 0) {\n this.logger.info(\n `\uD83D\uDCE6 Note: ${diverged.length} diverged worktree(s) in ${path.relative(process.cwd(), divergedDir)}`,\n );\n }\n } catch {\n // No diverged directory, that's fine.\n }\n\n type UpdateCheckResult =\n | { action: \"update\" | \"diverged\"; worktree: { path: string; branch: string } }\n | {\n action: \"skip\" | \"noop\";\n worktree: { path: string; branch: string };\n reason: string;\n message?: string;\n };\n\n // Phase 4a: Check which worktrees need updates (parallel, read-only, high concurrency)\n const maxConcurrent = this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n const limit = pLimit(maxConcurrent);\n\n const checkResults = await Promise.allSettled(\n actions.map((action) =>\n limit(async (): Promise<UpdateCheckResult> => {\n const worktree = { path: action.path, branch: action.branch };\n\n try {\n await fs.access(worktree.path);\n } catch {\n return { action: \"skip\", worktree, reason: \"missing_worktree_path\" };\n }\n\n const hasOp = await this.gitService.hasOperationInProgress(worktree.path);\n if (hasOp) return { action: \"skip\", worktree, reason: \"operation_in_progress\" };\n\n const isClean = await this.gitService.checkWorktreeStatus(worktree.path);\n if (!isClean) return { action: \"skip\", worktree, reason: \"dirty_worktree\" };\n\n const canFastForward = await this.gitService.canFastForward(worktree.path, worktree.branch);\n if (!canFastForward) {\n const isAhead = await this.gitService.isLocalAheadOfRemote(worktree.path, worktree.branch);\n if (isAhead) {\n this.logger.info(`\u23ED\uFE0F Skipping '${worktree.branch}' - has unpushed commits`);\n return { action: \"skip\", worktree, reason: \"local_ahead\" };\n }\n return { action: \"diverged\", worktree };\n }\n\n const isBehind = await this.gitService.isWorktreeBehind(worktree.path);\n if (!isBehind) return { action: \"noop\", worktree, reason: \"already_up_to_date\" };\n\n const sparseCfg = this.config.sparseCheckout;\n if (sparseCfg && sparseCfg.skipUpdateWhenOutsideSparse !== false) {\n const sparseService = this.gitService.getSparseCheckoutService();\n if (sparseService.resolveMode(sparseCfg) === \"cone\") {\n const diff = await this.gitService.getChangedPathsInRange(\n worktree.path,\n \"HEAD\",\n `origin/${worktree.branch}`,\n );\n // null = git diff failed; force update rather than treat the failure as \"no sparse paths affected\".\n if (diff !== null && !sparseService.pathsTouchSparse(diff, sparseCfg)) {\n this.logger.info(`\u23ED\uFE0F Skipping '${worktree.branch}' - upstream changes outside sparse paths`);\n return { action: \"skip\", worktree, reason: \"outside_sparse_checkout\" };\n }\n }\n }\n\n return { action: \"update\", worktree };\n }),\n ),\n );\n\n const worktreesToUpdate: { path: string; branch: string }[] = [];\n const divergedWorktrees: { path: string; branch: string }[] = [];\n\n for (const result of checkResults) {\n if (result.status === \"fulfilled\" && result.value) {\n switch (result.value.action) {\n case \"update\":\n worktreesToUpdate.push(result.value.worktree);\n break;\n case \"diverged\":\n divergedWorktrees.push(result.value.worktree);\n break;\n case \"noop\":\n outcome.recordNoop(\"worktree\", result.value.reason, result.value.worktree);\n break;\n case \"skip\":\n outcome.recordSkipped(\"worktree\", result.value.reason, result.value.worktree);\n break;\n }\n } else if (result.status === \"rejected\") {\n // Probe-only failure (status / fast-forward / divergence check threw). The\n // actual update is gated on success here, so a probe error means we never\n // touched the worktree \u2014 treat it as a skip, not a hard failure.\n this.logger.error(` - Error checking worktree:`, result.reason);\n outcome.recordSkipped(\"worktree\", \"update_check_failed\", {\n message: getErrorMessage(result.reason),\n });\n }\n }\n\n // Phase 4b: Perform mutations (updates + diverged handling) with lower concurrency\n const updateLimit = pLimit(\n this.config.parallelism?.maxWorktreeUpdates ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_UPDATES,\n );\n\n const mutationTasks: Promise<{ type: \"update\" | \"diverged\"; branch: string }>[] = [];\n\n for (const worktree of worktreesToUpdate) {\n mutationTasks.push(\n updateLimit(async () => {\n try {\n this.logger.info(` - Updating worktree '${worktree.branch}'...`);\n await this.gitService.updateWorktree(worktree.path);\n this.logger.info(` \u2705 Successfully updated '${worktree.branch}'.`);\n outcome.recordUpdated(worktree.branch, worktree.path, \"fast_forward\");\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n if (ERROR_MESSAGES.FAST_FORWARD_FAILED.some((msg) => errorMessage.includes(msg))) {\n this.logger.info(\n ` \u26A0\uFE0F Branch '${worktree.branch}' cannot be fast-forwarded. Checking for divergence...`,\n );\n try {\n await this.handleDivergedBranch(worktree, outcome);\n } catch (divergedError) {\n this.logger.error(` \u274C Failed to handle diverged branch '${worktree.branch}':`, divergedError);\n outcome.recordFailed(\"worktree\", getErrorMessage(divergedError), {\n reason: \"diverged_recovery_failed\",\n branch: worktree.branch,\n path: worktree.path,\n });\n throw divergedError;\n }\n } else {\n this.logger.error(` \u274C Failed to update '${worktree.branch}':`, error);\n outcome.recordFailed(\"worktree\", errorMessage, {\n reason: \"update_failed\",\n branch: worktree.branch,\n path: worktree.path,\n });\n throw error;\n }\n }\n return { type: \"update\" as const, branch: worktree.branch };\n }),\n );\n }\n\n for (const worktree of divergedWorktrees) {\n mutationTasks.push(\n updateLimit(async () => {\n try {\n await this.handleDivergedBranch(worktree, outcome);\n } catch (error) {\n this.logger.error(` \u274C Failed to handle diverged branch '${worktree.branch}':`, error);\n outcome.recordFailed(\"worktree\", getErrorMessage(error), {\n reason: \"diverged_recovery_failed\",\n branch: worktree.branch,\n path: worktree.path,\n });\n throw error;\n }\n return { type: \"diverged\" as const, branch: worktree.branch };\n }),\n );\n }\n\n if (mutationTasks.length > 0) {\n if (worktreesToUpdate.length > 0) {\n this.logger.info(` - Found ${worktreesToUpdate.length} worktrees behind their upstream branches.`);\n }\n if (divergedWorktrees.length > 0) {\n this.logger.info(` - Found ${divergedWorktrees.length} diverged worktrees to handle.`);\n }\n\n const mutationResults = await Promise.allSettled(mutationTasks);\n\n const successCount = mutationResults.filter((r) => r.status === \"fulfilled\").length;\n this.logger.info(` Processed ${successCount}/${mutationTasks.length} worktrees successfully`);\n } else {\n this.logger.info(\" - All worktrees are up to date.\");\n }\n }\n\n private async cleanupOrphanedDirectories(worktrees: { path: string; branch: string }[]): Promise<void> {\n try {\n const worktreeRelativePaths = worktrees.map((w) => path.relative(this.config.worktreeDir, w.path));\n const allDirs = await fs.readdir(this.config.worktreeDir);\n\n // Filter out special directories like .diverged.\n const regularDirs = allDirs.filter((dir) => !dir.startsWith(\".\"));\n\n const orphanedDirs: string[] = [];\n for (const dir of regularDirs) {\n const isPartOfWorktree = worktreeRelativePaths.some((worktreePath) => {\n return worktreePath === dir || worktreePath.startsWith(dir + path.sep);\n });\n\n if (!isPartOfWorktree) {\n orphanedDirs.push(dir);\n }\n }\n\n if (orphanedDirs.length > 0) {\n this.logger.info(`Found ${orphanedDirs.length} orphaned directories: ${orphanedDirs.join(\", \")}`);\n\n for (const dir of orphanedDirs) {\n const dirPath = path.join(this.config.worktreeDir, dir);\n try {\n const stat = await fs.stat(dirPath);\n if (stat.isDirectory()) {\n await fs.rm(dirPath, { recursive: true, force: true });\n this.logger.info(` - Removed orphaned directory: ${dir}`);\n }\n } catch (error) {\n this.logger.error(` - Failed to remove orphaned directory ${dir}:`, error);\n }\n }\n }\n } catch (error) {\n this.logger.error(\"Error during orphaned directory cleanup:\", error);\n }\n }\n\n private async handleDivergedBranch(\n worktree: { path: string; branch: string },\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n this.logger.info(`\u26A0\uFE0F Branch '${worktree.branch}' has diverged from upstream. Analyzing...`);\n\n const treesIdentical = await this.gitService.compareTreeContent(worktree.path, worktree.branch);\n\n if (treesIdentical) {\n this.logger.info(`\u2705 Branch '${worktree.branch}' was rebased but files are identical. Resetting to upstream...`);\n await this.gitService.resetToUpstream(worktree.path, worktree.branch);\n this.logger.info(` Successfully updated '${worktree.branch}' to match upstream.`);\n outcome.recordUpdated(worktree.branch, worktree.path, \"reset_identical_tree\");\n } else {\n const hasLocalChanges = await this.hasLocalChangesSinceLastSync(worktree.path);\n\n if (!hasLocalChanges) {\n this.logger.info(\n `\u2705 Branch '${worktree.branch}' has diverged but you made no local changes. Resetting to upstream...`,\n );\n await this.gitService.resetToUpstream(worktree.path, worktree.branch);\n this.logger.info(` Successfully updated '${worktree.branch}' to match upstream.`);\n outcome.recordUpdated(worktree.branch, worktree.path, \"reset_no_local_changes\");\n } else {\n this.logger.info(`\uD83D\uDD12 Branch '${worktree.branch}' has diverged with local changes. Moving to diverged...`);\n\n const divergedPath = await this.divergeWorktree(worktree.path, worktree.branch);\n const relativePath = path.relative(process.cwd(), divergedPath);\n outcome.recordPreservedDiverged(worktree.branch, worktree.path, divergedPath);\n\n this.logger.info(` Moved to: ${relativePath}`);\n this.logger.info(` Your local changes are preserved. To review:`);\n this.logger.info(` cd ${relativePath}`);\n this.logger.info(` git diff origin/${worktree.branch}`);\n\n await this.gitService.removeWorktree(worktree.path);\n await this.gitService.addWorktree(worktree.branch, worktree.path);\n this.logger.info(` Created fresh worktree from upstream at: ${worktree.path}`);\n }\n }\n }\n\n private async hasLocalChangesSinceLastSync(worktreePath: string): Promise<boolean> {\n try {\n const metadata = await this.gitService.getWorktreeMetadata(worktreePath);\n if (!metadata || !metadata.lastSyncCommit) {\n return true;\n }\n\n const currentCommit = await this.gitService.getCurrentCommit(worktreePath);\n return currentCommit !== metadata.lastSyncCommit;\n } catch {\n return true;\n }\n }\n\n private async divergeWorktree(worktreePath: string, branchName: string): Promise<string> {\n const divergedBaseDir = path.join(this.config.worktreeDir, GIT_CONSTANTS.DIVERGED_DIR_NAME);\n\n const timestamp = new Date().toISOString().split(\"T\")[0];\n const uniqueSuffix = Date.now().toString(36) + Math.random().toString(36).substring(2, 7);\n const safeBranchName = this.pathResolution.sanitizeBranchName(branchName);\n const divergedName = `${timestamp}-${safeBranchName}-${uniqueSuffix}`;\n const divergedPath = path.join(divergedBaseDir, divergedName);\n\n await fs.mkdir(divergedBaseDir, { recursive: true });\n\n try {\n await fs.rename(worktreePath, divergedPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === ERROR_MESSAGES.EXDEV) {\n await fs.cp(worktreePath, divergedPath, { recursive: true });\n await fs.rm(worktreePath, { recursive: true, force: true });\n } else {\n throw err;\n }\n }\n\n const metadata = {\n originalBranch: branchName,\n divergedAt: new Date().toISOString(),\n reason: METADATA_CONSTANTS.DIVERGED_REASON,\n originalPath: worktreePath,\n localCommit: await this.gitService.getCurrentCommit(divergedPath),\n remoteCommit: await this.gitService.getRemoteCommit(`origin/${branchName}`),\n instruction: `To preserve your changes:\n 1. Review: git diff origin/${branchName}\n 2. Keep changes: git push --force-with-lease origin ${branchName}\n 3. Discard changes: rm -rf this directory\n\n Original worktree location: ${worktreePath}`,\n };\n\n await fs.writeFile(\n path.join(divergedPath, METADATA_CONSTANTS.DIVERGED_INFO_FILE),\n JSON.stringify(metadata, null, 2),\n );\n\n return divergedPath;\n }\n}\n", "export function parseDuration(durationStr: string): number | null {\n const match = durationStr.match(/^(\\d+)([hdwmy])$/);\n if (!match) {\n return null;\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n const multipliers: Record<string, number> = {\n h: 60 * 60 * 1000, // hours\n d: 24 * 60 * 60 * 1000, // days\n w: 7 * 24 * 60 * 60 * 1000, // weeks\n m: 30 * 24 * 60 * 60 * 1000, // months (approximate)\n y: 365 * 24 * 60 * 60 * 1000, // years (approximate)\n };\n\n return value * multipliers[unit];\n}\n\nexport function filterBranchesByAge(\n branches: { branch: string; lastActivity: Date }[],\n maxAge: string,\n): { branch: string; lastActivity: Date }[] {\n const maxAgeMs = parseDuration(maxAge);\n if (maxAgeMs === null) {\n console.warn(`Invalid duration format: ${maxAge}. Using all branches.`);\n return branches;\n }\n\n const cutoffDate = new Date(Date.now() - maxAgeMs);\n\n return branches.filter(({ lastActivity }) => lastActivity >= cutoffDate);\n}\n\nexport function formatDuration(durationStr: string): string {\n const match = durationStr.match(/^(\\d+)([hdwmy])$/);\n if (!match) {\n return durationStr;\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n const unitNames: Record<string, string> = {\n h: value === 1 ? \"hour\" : \"hours\",\n d: value === 1 ? \"day\" : \"days\",\n w: value === 1 ? \"week\" : \"weeks\",\n m: value === 1 ? \"month\" : \"months\",\n y: value === 1 ? \"year\" : \"years\",\n };\n\n return `${value} ${unitNames[unit]}`;\n}\n", "import { createHash } from \"crypto\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\nimport { isCaseInsensitiveFs } from \"../utils/path-compare\";\n\nconst BRANCH_STEM_MAX = 80;\nconst BRANCH_HASH_LEN = 8;\n\nexport class PathResolutionService {\n sanitizeBranchName(branchName: string): string {\n const stem = branchName\n .replace(/\\//g, \"-\")\n .replace(/[^a-zA-Z0-9_-]/g, \"_\")\n .slice(0, BRANCH_STEM_MAX);\n const hash = createHash(\"sha256\").update(branchName).digest(\"hex\").slice(0, BRANCH_HASH_LEN);\n return `${stem}-${hash}`;\n }\n\n getBranchWorktreePath(worktreeDir: string, branchName: string): string {\n return path.join(worktreeDir, this.sanitizeBranchName(branchName));\n }\n\n private resolveRealPath(inputPath: string): string {\n const absolute = path.resolve(inputPath);\n const missing: string[] = [];\n let current = absolute;\n\n while (!fs.existsSync(current)) {\n const parent = path.dirname(current);\n if (parent === current) {\n return absolute;\n }\n missing.unshift(path.basename(current));\n current = parent;\n }\n\n try {\n return path.join(fs.realpathSync(current), ...missing);\n } catch {\n return absolute;\n }\n }\n\n private isResolvedPathInsideBase(resolved: string, resolvedBase: string): boolean {\n const fold = (p: string): string => (isCaseInsensitiveFs() ? p.toLowerCase() : p);\n const a = fold(resolved);\n const b = fold(resolvedBase);\n if (a === b) return true;\n return a.length > b.length && a.charAt(b.length) === path.sep && a.startsWith(b);\n }\n\n normalizeWorktreePath(worktreePath: string, worktreeBaseDir: string): string {\n const resolved = this.resolveRealPath(worktreePath);\n const resolvedBase = this.resolveRealPath(worktreeBaseDir);\n if (!this.isResolvedPathInsideBase(resolved, resolvedBase)) {\n throw new Error(`Worktree path '${worktreePath}' is outside base directory '${worktreeBaseDir}'`);\n }\n return path.relative(resolvedBase, resolved);\n }\n\n isPathInsideBaseDir(targetPath: string, baseDir: string): boolean {\n const resolved = this.resolveRealPath(targetPath);\n const resolvedBase = this.resolveRealPath(baseDir);\n return this.isResolvedPathInsideBase(resolved, resolvedBase);\n }\n\n extractBranchFromWorktreePath(worktreePath: string, worktreeBaseDir: string): string {\n return this.normalizeWorktreePath(worktreePath, worktreeBaseDir);\n }\n}\n", "import * as path from \"path\";\n\nimport { PathResolutionService } from \"./path-resolution.service\";\n\nimport type { SparseCheckoutConfig } from \"../types\";\n\nexport interface WorktreeInventory {\n remoteBranches: string[];\n defaultBranch: string;\n existingWorktrees: WorktreeEntry[];\n worktreeDir: string;\n}\n\nexport interface WorktreeEntry {\n path: string;\n branch: string;\n}\n\nexport type CreateAction =\n | { kind: \"create\"; branch: string; path: string }\n | { kind: \"skip-create\"; branch: string; path: string; reason: \"path-collision\"; conflictingBranch: string };\n\nexport type PruneAction = { kind: \"check-prune\"; branch: string; path: string };\n\nexport type UpdateAction = { kind: \"update-candidate\"; branch: string; path: string };\n\nexport type SparseAction =\n | { kind: \"check-sparse\"; branch: string; path: string }\n | { kind: \"skip-sparse\"; branch: string; path: string; reason: \"not-configured\" };\n\nexport type SyncAction = CreateAction | PruneAction | UpdateAction | SparseAction;\n\nexport interface SyncPlan {\n create: CreateAction[];\n prune: PruneAction[];\n update: UpdateAction[];\n sparse: SparseAction[];\n warnings: string[];\n}\n\nexport interface SyncPlanOptions {\n pathResolution?: PathResolutionService;\n updateExistingWorktrees?: boolean;\n sparseCheckout?: SparseCheckoutConfig;\n}\n\nexport function createWorktreeSyncPlan(inventory: WorktreeInventory, options: SyncPlanOptions = {}): SyncPlan {\n return {\n create: planCreateActions(inventory, options),\n prune: planPruneActions(inventory),\n update: options.updateExistingWorktrees === false ? [] : planUpdateActions(inventory),\n sparse: planSparseActions(inventory, options.sparseCheckout),\n warnings: [],\n };\n}\n\nexport function planCreateActions(inventory: WorktreeInventory, options: SyncPlanOptions = {}): CreateAction[] {\n const pathResolution = options.pathResolution ?? new PathResolutionService();\n const existingBranches = new Set(inventory.existingWorktrees.map((w) => w.branch));\n const newBranches = inventory.remoteBranches.filter(\n (branch) => !existingBranches.has(branch) && branch !== inventory.defaultBranch,\n );\n\n const reservedPaths = new Map<string, string>();\n for (const worktree of inventory.existingWorktrees) {\n reservedPaths.set(path.resolve(worktree.path), worktree.branch);\n }\n\n const actions: CreateAction[] = [];\n for (const branch of newBranches) {\n const worktreePath = pathResolution.getBranchWorktreePath(inventory.worktreeDir, branch);\n const resolved = path.resolve(worktreePath);\n const conflictingBranch = reservedPaths.get(resolved);\n\n if (conflictingBranch && conflictingBranch !== branch) {\n actions.push({\n kind: \"skip-create\",\n branch,\n path: worktreePath,\n reason: \"path-collision\",\n conflictingBranch,\n });\n continue;\n }\n\n reservedPaths.set(resolved, branch);\n actions.push({ kind: \"create\", branch, path: worktreePath });\n }\n\n return actions;\n}\n\nexport function planPruneActions(inventory: WorktreeInventory): PruneAction[] {\n const remoteBranches = new Set(inventory.remoteBranches);\n return inventory.existingWorktrees\n .filter((worktree) => !remoteBranches.has(worktree.branch))\n .map((worktree) => ({ kind: \"check-prune\", branch: worktree.branch, path: worktree.path }));\n}\n\nexport function planUpdateActions(inventory: WorktreeInventory): UpdateAction[] {\n const remoteBranches = new Set(inventory.remoteBranches);\n return inventory.existingWorktrees\n .filter((worktree) => remoteBranches.has(worktree.branch))\n .map((worktree) => ({ kind: \"update-candidate\", branch: worktree.branch, path: worktree.path }));\n}\n\nexport function planSparseActions(inventory: WorktreeInventory, sparseCheckout?: SparseCheckoutConfig): SparseAction[] {\n if (!sparseCheckout) {\n return [];\n }\n\n return inventory.existingWorktrees.map((worktree) => ({\n kind: \"check-sparse\",\n branch: worktree.branch,\n path: worktree.path,\n }));\n}\n", "import { getErrorMessage } from \"../utils/lfs-error\";\nimport { REPOSITORY_MODES, resolveMode } from \"../utils/repo-mode\";\nimport { retry } from \"../utils/retry\";\nimport { PhaseTimer, Timer, formatTimingTable } from \"../utils/timing\";\n\nimport { type CloneSkipReason, CloneSyncService } from \"./clone-sync.service\";\nimport { GitService } from \"./git.service\";\nimport { Logger } from \"./logger.service\";\nimport { ProgressEmitter } from \"./progress-emitter\";\nimport { RepoOperationLock } from \"./repo-operation-lock\";\nimport { SyncOutcomeAccumulator } from \"./sync-outcome\";\nimport { SyncRetryPolicy } from \"./sync-retry-policy\";\nimport { WorktreeModeSyncRunner } from \"./worktree-mode-sync-runner\";\n\nimport type { ProgressEvent, ProgressListener } from \"./progress-emitter\";\nimport type { RepoLockRelease } from \"./repo-operation-lock\";\nimport type { Config, SyncOutcome, SyncResult } from \"../types\";\nimport type { LfsErrorContext } from \"../utils/retry\";\n\nexport type { ProgressEvent, ProgressListener } from \"./progress-emitter\";\nexport type { SyncOutcome, SyncOutcomeAction, SyncOutcomeCounts, SyncResult } from \"../types\";\n\nexport type ExclusiveRepoOperationResult<T> =\n | { started: true; value: T }\n | { started: false; reason: \"in_progress\" | \"locked\" };\n\nexport class WorktreeSyncService {\n private gitService: GitService;\n private cloneSyncService: CloneSyncService | null = null;\n private logger: Logger;\n private syncInProgress: boolean = false;\n private progressEmitter = new ProgressEmitter();\n private repoOperationLock: RepoOperationLock;\n private retryPolicy: SyncRetryPolicy;\n private worktreeModeSyncRunner: WorktreeModeSyncRunner;\n private skipsAccumulator: CloneSkipReason[] = [];\n private lastOutcome: SyncOutcome | null = null;\n\n constructor(public readonly config: Config) {\n this.logger = config.logger ?? Logger.createDefault(undefined, config.debug);\n this.gitService = new GitService(config, this.logger, (event): void => this.emitProgress(event));\n this.repoOperationLock = new RepoOperationLock(config, this.gitService, this.logger);\n this.retryPolicy = new SyncRetryPolicy(config, this.gitService, this.logger);\n this.worktreeModeSyncRunner = new WorktreeModeSyncRunner(\n config,\n this.gitService,\n this.logger,\n this.progressEmitter,\n );\n if (resolveMode(config) === REPOSITORY_MODES.CLONE) {\n this.cloneSyncService = new CloneSyncService(config, this.gitService, this.logger, {\n progressEmitter: (event): void => this.emitProgress(event),\n onSkip: (reason): void => {\n this.skipsAccumulator.push(reason);\n },\n });\n }\n }\n\n public getRecordedSkips(): readonly CloneSkipReason[] {\n return [...this.skipsAccumulator];\n }\n\n public clearRecordedSkips(): void {\n this.skipsAccumulator = [];\n }\n\n public clearPendingInitSkip(): void {\n this.cloneSyncService?.clearPendingInitSkip();\n }\n\n public getLastOutcome(): SyncOutcome | null {\n return this.lastOutcome;\n }\n\n isCloneMode(): boolean {\n return this.cloneSyncService !== null;\n }\n\n async getWorktrees(): Promise<Array<{ path: string; branch: string }>> {\n if (this.cloneSyncService) {\n return this.cloneSyncService.getWorktrees();\n }\n return this.gitService.getWorktrees();\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized()) return;\n const result = await this.runExclusiveRepoOperation(() => this.initializeUnlocked());\n if (!result.started) {\n const reason = result.reason === \"in_progress\" ? \"operation in progress\" : \"another process holds the lock\";\n this.logger.warn(`\u26A0\uFE0F Initialize skipped: ${reason}`);\n }\n }\n\n async initializeUnlocked(outcome?: SyncOutcomeAccumulator): Promise<void> {\n this.emitProgress({ phase: \"initialize\", message: \"Initializing repository\" });\n if (this.cloneSyncService) {\n await this.cloneSyncService.initialize(outcome);\n } else {\n await this.gitService.initialize();\n }\n this.emitProgress({ phase: \"initialize\", message: \"Repository initialized\" });\n }\n\n isInitialized(): boolean {\n if (this.cloneSyncService) {\n return this.cloneSyncService.isInitialized();\n }\n return this.gitService.isInitialized();\n }\n\n isSyncInProgress(): boolean {\n return this.syncInProgress;\n }\n\n getGitService(): GitService {\n return this.gitService;\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n this.gitService.updateLogger(logger);\n this.cloneSyncService?.updateLogger(logger);\n this.retryPolicy.updateLogger(logger);\n this.worktreeModeSyncRunner.updateLogger(logger);\n this.repoOperationLock.updateLogger(logger);\n }\n\n onProgress(listener: ProgressListener): () => void {\n return this.progressEmitter.onProgress(listener);\n }\n\n async runExclusiveRepoOperation<T>(operation: () => Promise<T>): Promise<ExclusiveRepoOperationResult<T>> {\n if (this.syncInProgress) {\n this.logger.warn(\"\u26A0\uFE0F Another repository operation is already in progress, skipping...\");\n return { started: false, reason: \"in_progress\" };\n }\n // Claim the in-process slot synchronously so a second caller arriving while\n // we await acquire() sees \"in_progress\" instead of also passing the check.\n this.syncInProgress = true;\n\n let release: RepoLockRelease | null;\n try {\n release = await this.repoOperationLock.acquire();\n } catch (error) {\n this.syncInProgress = false;\n throw error;\n }\n\n if (release === null) {\n this.syncInProgress = false;\n this.logger.warn(\"\u26A0\uFE0F Another process holds the sync lock for this repo, skipping...\");\n return { started: false, reason: \"locked\" };\n }\n\n try {\n return { started: true, value: await operation() };\n } finally {\n // Release the file lock first; only then clear the in-process flag so\n // another caller arriving in this window gets \"in_progress\" rather than\n // ELOCKED from proper-lockfile.\n try {\n await release();\n } catch (releaseError) {\n this.logger.warn(`Failed to release sync lock: ${getErrorMessage(releaseError)}`);\n }\n this.syncInProgress = false;\n }\n }\n\n private emitProgress(event: ProgressEvent): void {\n this.progressEmitter.emit(event);\n }\n\n async sync(): Promise<SyncResult> {\n const result = await this.runExclusiveRepoOperation<SyncOutcome>(async () => {\n const totalTimer = new Timer();\n const phaseTimer = new PhaseTimer();\n const outcome = new SyncOutcomeAccumulator({\n mode: this.cloneSyncService ? \"clone\" : \"worktree\",\n repoName: (this.config as { name?: string }).name,\n });\n const syncContext = this.retryPolicy.createContext();\n const retryOptions = this.retryPolicy.createOptions(syncContext);\n let durationMs: number | undefined;\n\n try {\n if (!this.isInitialized()) {\n await this.initializeUnlocked(outcome);\n }\n\n this.logger.info(`[${new Date().toISOString()}] Starting worktree synchronization...`);\n\n const retryOutcomeBaseline = outcome.snapshot();\n const retryOptionsWithOutcomeReset = {\n ...retryOptions,\n onRetry: (error: unknown, attempt: number, context?: LfsErrorContext): void => {\n outcome.restore(retryOutcomeBaseline);\n retryOptions.onRetry?.(error, attempt, context);\n },\n };\n\n const cloneSync = this.cloneSyncService;\n if (cloneSync) {\n await retry(() => cloneSync.runSyncAttempt(outcome), retryOptionsWithOutcomeReset);\n } else {\n await retry(\n () => this.worktreeModeSyncRunner.runSyncAttempt(phaseTimer, syncContext, outcome),\n retryOptionsWithOutcomeReset,\n );\n }\n } catch (error) {\n if (outcome.getCounts().failed === 0) {\n outcome.recordFailed(\"repo\", getErrorMessage(error), { reason: \"sync_failed\" });\n }\n this.logger.error(\"\\n\u274C Error during worktree synchronization after all retry attempts:\", error);\n throw error;\n } finally {\n this.retryPolicy.resetLfsSkipIfNeeded(syncContext);\n this.logger.info(`[${new Date().toISOString()}] Synchronization finished.\\n`);\n durationMs = totalTimer.stop();\n this.lastOutcome = outcome.toOutcome(durationMs);\n\n if (this.config.debug) {\n const phaseResults = phaseTimer.getResults();\n const repoName = (this.config as { name?: string }).name;\n this.logger.table(formatTimingTable(durationMs, phaseResults, repoName));\n }\n }\n\n return this.lastOutcome ?? outcome.toOutcome(durationMs);\n });\n\n return result.started ? { started: true, outcome: result.value } : result;\n }\n}\n", "import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n\nimport { buildUnsupportedContext } from \"./context\";\nimport {\n handleCreateWorktree,\n handleDetectContext,\n handleGetWorktreeStatus,\n handleInitialize,\n handleListWorktrees,\n handleLoadConfig,\n handleRemoveWorktree,\n handleSetCurrentRepository,\n handleSync,\n handleUpdateWorktree,\n} from \"./handlers\";\nimport { wrapHandler } from \"./utils\";\n\nimport type { DiscoveredRepoContext, RepositoryContext } from \"./context\";\n\nconst REPO_NAME_DESCRIBE =\n \"Repo name from loaded config. Omit to use current (set via set_current_repository) or the only loaded repo.\";\n\nconst PATH_DESCRIBE_SUFFIX = \"Absolute preferred; relative resolves from server CWD.\";\n\nconst SERVER_INSTRUCTIONS =\n \"Call `detect_context` for the project map and live worktree state; `configuredRepositories` in its response is the server-wide loaded-config inventory. Use `set_current_repository` to switch repos. Auto-loads sync-worktrees.config.{js,mjs,cjs,ts} via walk-up.\";\n\nexport interface ServerSnapshot {\n discovered: DiscoveredRepoContext | null;\n configuredRepoCount?: number;\n}\n\nexport function buildInstructions(snapshot?: ServerSnapshot): string {\n const d = snapshot?.discovered;\n\n if (!d || !d.isWorktree || d.kind !== \"managed\") {\n return SERVER_INSTRUCTIONS;\n }\n\n const fields: string[] = [];\n if (d.repoName) fields.push(`workspace=${d.repoName}`);\n if (d.currentWorktreePath) fields.push(`path=${d.currentWorktreePath}`);\n if (d.configPath) fields.push(`config=${d.configPath}`);\n if (typeof snapshot?.configuredRepoCount === \"number\") {\n fields.push(`configuredRepos=${snapshot.configuredRepoCount}`);\n }\n fields.push(`worktrees=${d.allWorktrees.length}`);\n\n return `${SERVER_INSTRUCTIONS} Connect-time: ${fields.join(\" \")}.`;\n}\n\nexport function createServer(context: RepositoryContext, snapshot?: ServerSnapshot): McpServer {\n const server = new McpServer(\n {\n name: \"sync-worktrees\",\n version: \"1.0.0\",\n },\n {\n instructions: buildInstructions(snapshot),\n },\n );\n\n server.registerResource(\n \"workspace\",\n \"sync-worktrees://workspace\",\n {\n title: \"Workspace context\",\n description:\n \"Workspace context: isWorktree, kind, currentWorktreePath, currentBranch, allWorktrees, siblingRepositories, configPath, capabilities {available,reason}, configuredRepositories (server-wide loaded-config inventory). {isWorktree:false} when outside any workspace.\",\n mimeType: \"application/json\",\n },\n async (uri) => {\n let payload: unknown;\n try {\n const discovered = await context.detectFromPath(process.cwd());\n const configuredRepositories = await context.getConfiguredRepositorySummaries();\n payload = { ...discovered, configuredRepositories };\n } catch (err) {\n payload = buildUnsupportedContext(process.cwd(), err instanceof Error ? err.message : String(err));\n }\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: \"application/json\",\n text: JSON.stringify(payload),\n },\n ],\n };\n },\n );\n\n server.registerTool(\n \"detect_context\",\n {\n description:\n \"Detect sync-worktrees structure from path (default: CWD). Reads .git, resolves bare repo, walks up to auto-load sync-worktrees.config.{js,mjs,cjs,ts}. Returns: configuredRepositories (server-wide loaded-config inventory; independent of params.path), bareRepoPath, allWorktrees, siblingRepositories, currentWorktreePath, configPath, capabilities {available,reason}, notes. Lean configuredRepositories entries are mode-discriminated: clone \u2192 {name, mode:'clone', checkoutPath, isCurrent}; worktree \u2192 {name, mode:'worktree', worktreeDir, isCurrent}. detailed=true adds repoUrl, branch?, sparseCheckout?, localReady, plus bareRepoDir for worktree mode. Use at session start or to bootstrap from unknown checkout.\",\n inputSchema: {\n path: z.string().optional().describe(\"Directory to inspect. Default: server CWD.\"),\n detailed: z\n .boolean()\n .optional()\n .default(false)\n .describe(\"Expand configuredRepositories with repoUrl, branch, sparseCheckout, localReady, bareRepoDir.\"),\n includeAllWorktrees: z\n .boolean()\n .optional()\n .describe(\"Include allWorktreesByRepo + allWorktreeErrorsByRepo for each configured repo. Default: false.\"),\n includeStatus: z\n .boolean()\n .optional()\n .describe(\n \"Enrich entries with label, divergence, staleHint. Adds 1 git status + rev-list per worktree. Default: false.\",\n ),\n },\n annotations: {\n title: \"Detect sync-worktrees context\",\n readOnlyHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n wrapHandler((params, extra) => handleDetectContext(context, params, extra)),\n );\n\n server.registerTool(\n \"list_worktrees\",\n {\n description:\n \"List worktrees with status. No repoName + config loaded = all configured repos grouped by repoName. With repoName = single repo. Entries: {path, branch, isCurrent, label (clean|dirty|stale|current|unknown), status, divergence, safeToRemove, lastSyncAt, sizeBytes}.\",\n inputSchema: {\n repoName: z.string().optional().describe(\"Repo name. Omit + config loaded = list all configured repos.\"),\n includeSize: z\n .boolean()\n .optional()\n .describe(\n \"Compute on-disk size per worktree (bytes). Slow on large worktrees. Default: false (sizeBytes=null).\",\n ),\n },\n annotations: {\n title: \"List worktrees with status\",\n readOnlyHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n wrapHandler((params, extra) => handleListWorktrees(context, params, extra)),\n );\n\n server.registerTool(\n \"get_worktree_status\",\n {\n description:\n \"Detailed status for one worktree: dirty files, unpushed commits, stashes, upstream gone, ops in progress. Returns: status + divergence {ahead,behind} + resolved path.\",\n inputSchema: {\n path: z.string().describe(`Worktree path. ${PATH_DESCRIBE_SUFFIX}`),\n repoName: z.string().optional().describe(REPO_NAME_DESCRIBE),\n includeDetails: z\n .boolean()\n .optional()\n .describe(\"Include file-level lists (modified, untracked, staged). Default: false (counts only).\"),\n },\n annotations: {\n title: \"Get worktree status\",\n readOnlyHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n wrapHandler((params, extra) => handleGetWorktreeStatus(context, params, extra)),\n );\n\n server.registerTool(\n \"create_worktree\",\n {\n description:\n \"Create worktree for a branch. Existing branch (local/remote) = checkout. New branch = create from baseBranch + push to origin (default). baseBranch required only for new branches \u2014 pass defensively if unsure. push=false opts out. Preconditions: repo initialized (auto-runs). Returns: {success, branchName, worktreePath, created, pushed}.\",\n inputSchema: {\n branchName: z.string().describe(\"Branch name. Slashes/special chars sanitized for dir name.\"),\n baseBranch: z\n .string()\n .optional()\n .describe(\n \"Base for new branch. Required if branchName doesn't exist locally or remotely; ignored otherwise.\",\n ),\n push: z.boolean().optional().describe(\"Push new branch to origin. Default: true. Ignored if branch existed.\"),\n repoName: z.string().optional().describe(REPO_NAME_DESCRIBE),\n },\n annotations: {\n title: \"Create worktree\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n wrapHandler((params, extra) => handleCreateWorktree(context, params, extra)),\n );\n\n server.registerTool(\n \"remove_worktree\",\n {\n description:\n \"Remove worktree. Safety checks reject if dirty, unpushed commits, stashes, or op in progress (merge/rebase/cherry-pick/revert/bisect). force=true: `git worktree remove --force` DELETES uncommitted/untracked files in dir; branch ref + stashes + remote preserved. Returns: {success, removedPath}.\",\n inputSchema: {\n path: z.string().describe(`Worktree path to remove. ${PATH_DESCRIBE_SUFFIX}`),\n force: z\n .boolean()\n .optional()\n .describe(\"Skip safety checks; deletes uncommitted/untracked files. Branch ref preserved. Default: false.\"),\n repoName: z.string().optional().describe(REPO_NAME_DESCRIBE),\n },\n annotations: {\n title: \"Remove worktree\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n wrapHandler((params, extra) => handleRemoveWorktree(context, params, extra)),\n );\n\n server.registerTool(\n \"sync\",\n {\n description:\n \"Repo-wide sync: fetch, create worktrees for new remote branches, remove pruned (clean only), fast-forward existing. Emits progress. Single worktree? Use update_worktree. Single create? Use create_worktree. Preconditions: config loaded + repo initialized (auto-runs). Returns: {success, duration, skips}.\",\n inputSchema: {\n repoName: z.string().optional().describe(REPO_NAME_DESCRIBE),\n },\n annotations: {\n title: \"Sync repository worktrees\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n wrapHandler((params, extra) => handleSync(context, params, extra)),\n );\n\n server.registerTool(\n \"update_worktree\",\n {\n description:\n \"Fast-forward one worktree to upstream. No merge, no rebase, aborts if not fast-forwardable. Whole repo? Use sync.\",\n inputSchema: {\n path: z.string().describe(`Worktree path to fast-forward. ${PATH_DESCRIBE_SUFFIX}`),\n repoName: z.string().optional().describe(REPO_NAME_DESCRIBE),\n },\n annotations: {\n title: \"Fast-forward one worktree\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n },\n wrapHandler((params, extra) => handleUpdateWorktree(context, params, extra)),\n );\n\n server.registerTool(\n \"initialize\",\n {\n description:\n \"Initialize repo: clone as bare if missing, create main worktree. Idempotent. Emits progress. Preconditions: config loaded. Returns: {success, defaultBranch, worktreeDir}.\",\n inputSchema: {\n repoName: z.string().optional().describe(REPO_NAME_DESCRIBE),\n },\n annotations: {\n title: \"Initialize repository\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n },\n wrapHandler((params, extra) => handleInitialize(context, params, extra)),\n );\n\n server.registerTool(\n \"load_config\",\n {\n description:\n \"Load/reload sync-worktrees JS config into session. Replaces previously loaded repos. Call before sync/initialize/create_worktree in config-driven workflow. Returns: {configPath, currentRepository, repositories: [{name, repoUrl, worktreeDir, source}]}.\",\n inputSchema: {\n configPath: z\n .string()\n .optional()\n .describe(\"Config file path. Falls back to SYNC_WORKTREES_CONFIG env var. Errors if neither set.\"),\n },\n annotations: {\n title: \"Load sync-worktrees config\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n wrapHandler((params, extra) => handleLoadConfig(context, params, extra)),\n );\n\n server.registerTool(\n \"set_current_repository\",\n {\n description:\n \"Set current repo for tool calls that omit repoName. Session-scoped. Preconditions: load_config called.\",\n inputSchema: {\n repoName: z.string().describe(\"Repo name from loaded config repositories[].name.\"),\n },\n annotations: {\n title: \"Set current repository\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n wrapHandler((params, extra) => handleSetCurrentRepository(context, params, extra)),\n );\n\n return server;\n}\n", "import * as path from \"path\";\n\nimport pLimit from \"p-limit\";\n\nimport { DEFAULT_CONFIG } from \"../constants\";\nimport { PathResolutionService } from \"../services/path-resolution.service\";\nimport { createEmptySyncOutcome } from \"../services/sync-outcome\";\nimport { WorktreeStatusService } from \"../services/worktree-status.service\";\nimport { formatCloneSkipReason } from \"../utils/clone-skip-format\";\nimport { calculateDirectorySize } from \"../utils/disk-space\";\nimport { isValidGitBranchName } from \"../utils/git-validation\";\nimport { pathsEqual } from \"../utils/path-compare\";\n\nimport { CapabilityUnavailableError, SyncInProgressError, formatToolResponse } from \"./utils\";\nimport { deriveLabel, deriveSafeToRemove, getDivergence } from \"./worktree-summary\";\n\nimport type { Capabilities, DiscoveredRepoContext, DiscoveredWorktree, RepositoryContext } from \"./context\";\nimport type { HandlerExtra } from \"./utils\";\nimport type { WorktreeLabel } from \"./worktree-summary\";\nimport type { ProgressEvent } from \"../services/worktree-sync.service\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\n\ntype CapabilityKey = keyof Capabilities;\ntype RepoScopedParams = { repoName?: string };\ntype WorktreePathParams = RepoScopedParams & { path: string };\ntype RepoService = Awaited<ReturnType<RepositoryContext[\"getService\"]>>;\ntype RepoGitService = ReturnType<RepoService[\"getGitService\"]>;\ntype Limit = ReturnType<typeof pLimit>;\ntype ListedWorktree = {\n path: string;\n branch: string;\n isCurrent: boolean;\n label: WorktreeLabel;\n status: Awaited<ReturnType<RepoGitService[\"getFullWorktreeStatus\"]>> | null;\n divergence: Awaited<ReturnType<typeof getDivergence>>;\n safeToRemove: ReturnType<typeof deriveSafeToRemove>;\n lastSyncAt: string | null;\n sizeBytes: number | null;\n};\n\nconst pathResolution = new PathResolutionService();\nconst CLONE_MODE_WORKTREE_MUTATION_REASON =\n \"clone-mode repositories have a single checkout; use sync for clone-mode updates\";\n\nfunction ensureCapability(discovered: DiscoveredRepoContext | null, key: CapabilityKey, toolName: string): void {\n if (!discovered) return;\n const cap = discovered.capabilities[key];\n if (!cap.available) {\n const reasons = cap.reason ? [cap.reason] : discovered.notes;\n throw new CapabilityUnavailableError(toolName, reasons);\n }\n}\n\nasync function getReadyService(\n ctx: RepositoryContext,\n repoName: string | undefined,\n options: {\n capability?: CapabilityKey;\n toolName?: string;\n ensureInitialized?: boolean;\n } = {},\n): Promise<{ discovered: DiscoveredRepoContext | null; service: RepoService; git: RepoGitService }> {\n if (!repoName) {\n ctx.autoSelectCurrentRepoIfSingleConfig();\n }\n const discovered = ctx.getDiscoveredContext(repoName);\n if (options.capability && options.toolName) {\n ensureCapability(discovered, options.capability, options.toolName);\n }\n\n const service = await ctx.getService(repoName);\n if (options.ensureInitialized && !service.isInitialized()) {\n await service.initialize();\n }\n\n return {\n discovered,\n service,\n git: service.getGitService(),\n };\n}\n\nasync function runExclusiveRepoOperation<T>(\n ctx: RepositoryContext,\n repoName: string | undefined,\n service: RepoService,\n operation: () => Promise<T>,\n): Promise<T> {\n const result = await service.runExclusiveRepoOperation(operation);\n if (!result.started) {\n const name = ctx.getEntry(repoName)?.name ?? repoName ?? \"unknown\";\n throw new SyncInProgressError(name);\n }\n return result.value;\n}\n\nasync function ensureRepoWorktreePath(\n ctx: RepositoryContext,\n params: WorktreePathParams,\n service: RepoService,\n git: RepoGitService,\n): Promise<string> {\n await ensurePathBelongsToRepo(ctx, params.path, params.repoName, service, git);\n return path.resolve(params.path);\n}\n\nasync function ensurePathBelongsToRepo(\n ctx: RepositoryContext,\n targetPath: string,\n repoName: string | undefined,\n service: RepoService,\n git: RepoGitService,\n): Promise<void> {\n const discovered = ctx.getDiscoveredContext(repoName);\n if (discovered?.allWorktrees.length) {\n const match = discovered.allWorktrees.some((w) => pathsEqual(w.path, targetPath));\n if (match) return;\n }\n\n try {\n const worktrees = await getWorktreesFromService(service, git);\n if (worktrees.some((w) => pathsEqual(w.path, targetPath))) return;\n } catch {\n // fall through to rejection\n }\n\n throw new Error(`Path '${targetPath}' is not a registered worktree of the current repository`);\n}\n\nfunction isCloneModeService(service: RepoService): boolean {\n const candidate = service as RepoService & { isCloneMode?: () => boolean };\n return typeof candidate.isCloneMode === \"function\" && candidate.isCloneMode();\n}\n\nfunction ensureWorktreeModeService(service: RepoService, toolName: string): void {\n if (isCloneModeService(service)) {\n throw new CapabilityUnavailableError(toolName, [CLONE_MODE_WORKTREE_MUTATION_REASON]);\n }\n}\n\nasync function getWorktreesFromService(\n service: RepoService,\n git: { getWorktrees: () => Promise<Array<{ path: string; branch: string }>> },\n): Promise<Array<{ path: string; branch: string }>> {\n const candidate = service as RepoService & {\n getWorktrees?: () => Promise<Array<{ path: string; branch: string }>>;\n };\n if (typeof candidate.getWorktrees === \"function\") {\n return candidate.getWorktrees();\n }\n return git.getWorktrees();\n}\n\nexport async function handleDetectContext(\n ctx: RepositoryContext,\n params: { path?: string; includeStatus?: boolean; includeAllWorktrees?: boolean; detailed?: boolean },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const target = params.path ?? process.cwd();\n const discovered = await ctx.detectFromPath(target);\n // configuredRepositories is server-wide loaded-config inventory, independent of params.path.\n const configuredRepositories = await ctx.getConfiguredRepositorySummaries({ detailed: params.detailed ?? false });\n let response = { ...discovered, configuredRepositories };\n\n if (params.includeAllWorktrees) {\n const details = await ctx.getAllConfiguredWorktreeDetails(discovered.currentWorktreePath);\n const errorsByRepo = Object.keys(details.errorsByRepo).length > 0 ? details.errorsByRepo : undefined;\n response = {\n ...response,\n allWorktreesByRepo: details.worktreesByRepo,\n allWorktreeErrorsByRepo: errorsByRepo,\n };\n }\n\n if (!params.includeStatus) {\n return formatToolResponse(response);\n }\n\n const statusService = new WorktreeStatusService();\n const statusLimit = pLimit(DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\n\n const enriched = await enrichDetectedWorktrees(response.allWorktrees, statusService, statusLimit);\n let allWorktreesByRepo = response.allWorktreesByRepo;\n\n if (allWorktreesByRepo) {\n const entries = await Promise.all(\n Object.entries(allWorktreesByRepo).map(async ([repoName, worktrees]) => [\n repoName,\n await enrichDetectedWorktrees(worktrees, statusService, statusLimit),\n ]),\n );\n allWorktreesByRepo = Object.fromEntries(entries);\n }\n\n return formatToolResponse({ ...response, allWorktrees: enriched, allWorktreesByRepo });\n}\n\nasync function enrichDetectedWorktrees(\n worktrees: DiscoveredWorktree[],\n statusService: WorktreeStatusService,\n limit: Limit,\n): Promise<DiscoveredWorktree[]> {\n if (worktrees.length === 0) return worktrees;\n\n return Promise.all(\n worktrees.map((wt) =>\n limit(async () => {\n const [status, divergence] = await Promise.all([\n statusService.getFullWorktreeStatus(wt.path, false).catch(() => null),\n getDivergence(wt.path),\n ]);\n return {\n ...wt,\n label: status\n ? deriveLabel(status, wt.isCurrent)\n : wt.isCurrent\n ? (\"current\" as const)\n : (\"unknown\" as const),\n divergence,\n staleHint: status?.upstreamGone ?? false,\n };\n }),\n ),\n );\n}\n\nexport async function handleListWorktrees(\n ctx: RepositoryContext,\n params: { repoName?: string; includeSize?: boolean },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const configuredRepoNames = params.repoName ? [] : ctx.getConfiguredRepositoryNames();\n if (configuredRepoNames.length > 0) {\n const limit = pLimit(DEFAULT_CONFIG.PARALLELISM.MAX_REPOSITORIES);\n const statusLimit = pLimit(DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\n const repositories = await Promise.all(\n configuredRepoNames.map((repoName) =>\n limit(async () => {\n try {\n return [\n repoName,\n {\n worktrees: await listWorktreesForRepo(ctx, repoName, params.includeSize, statusLimit),\n },\n ] as const;\n } catch (err) {\n return [\n repoName,\n {\n worktrees: [],\n error: err instanceof Error ? err.message : String(err),\n },\n ] as const;\n }\n }),\n ),\n );\n\n return formatToolResponse({ repositories: Object.fromEntries(repositories) });\n }\n\n const results = await listWorktreesForRepo(ctx, params.repoName, params.includeSize);\n return formatToolResponse({ worktrees: results });\n}\n\nasync function listWorktreesForRepo(\n ctx: RepositoryContext,\n repoName: string | undefined,\n includeSize: boolean | undefined,\n limit: Limit = pLimit(DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS),\n): Promise<ListedWorktree[]> {\n const { discovered, service, git } = await getReadyService(ctx, repoName, {\n capability: \"listWorktrees\",\n toolName: \"list_worktrees\",\n });\n\n let worktrees: Array<{ path: string; branch: string }>;\n try {\n worktrees = await getWorktreesFromService(service, git);\n } catch {\n if (discovered) {\n worktrees = discovered.allWorktrees.map((w) => ({ path: w.path, branch: w.branch }));\n } else {\n throw new Error(\"Cannot list worktrees - service not initialized and no detected context\");\n }\n }\n\n const currentPath = discovered?.currentWorktreePath ?? null;\n\n const results = await Promise.all(\n worktrees.map((wt) =>\n limit(async () => {\n const resolvedPath = path.resolve(wt.path);\n const isCurrent = currentPath !== null && pathsEqual(wt.path, currentPath);\n\n const [status, divergence, metadata, sizeBytes] = await Promise.all([\n git.getFullWorktreeStatus(wt.path, false).catch(() => null),\n getDivergence(wt.path),\n git.getWorktreeMetadata(wt.path).catch(() => null),\n includeSize ? calculateDirectorySize(wt.path).catch(() => null) : Promise.resolve(null),\n ]);\n\n return {\n path: resolvedPath,\n branch: wt.branch,\n isCurrent,\n label: status ? deriveLabel(status, isCurrent) : isCurrent ? \"current\" : \"unknown\",\n status,\n divergence,\n safeToRemove: status ? deriveSafeToRemove(status) : { safe: false, reason: \"status unavailable\" },\n lastSyncAt: metadata?.lastSyncDate ?? null,\n sizeBytes,\n };\n }),\n ),\n );\n\n return results;\n}\n\nexport async function handleGetWorktreeStatus(\n ctx: RepositoryContext,\n params: { path: string; repoName?: string; includeDetails?: boolean },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { service, git } = await getReadyService(ctx, params.repoName, {\n capability: \"getStatus\",\n toolName: \"get_worktree_status\",\n });\n const resolvedPath = await ensureRepoWorktreePath(ctx, params, service, git);\n const [status, divergence] = await Promise.all([\n git.getFullWorktreeStatus(params.path, params.includeDetails ?? false),\n getDivergence(params.path),\n ]);\n\n return formatToolResponse({\n path: resolvedPath,\n ...status,\n divergence,\n });\n}\n\nexport async function handleCreateWorktree(\n ctx: RepositoryContext,\n params: { branchName: string; baseBranch?: string; push?: boolean; repoName?: string },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { branchName, baseBranch } = params;\n const push = params.push ?? true;\n\n const validation = isValidGitBranchName(branchName);\n if (!validation.valid) {\n throw new Error(`Invalid branch name '${branchName}': ${validation.error}`);\n }\n\n const { service, git } = await getReadyService(ctx, params.repoName, {\n capability: \"createWorktree\",\n toolName: \"create_worktree\",\n });\n ensureWorktreeModeService(service, \"create_worktree\");\n\n return runExclusiveRepoOperation(ctx, params.repoName, service, async () => {\n if (!service.isInitialized()) {\n await service.initializeUnlocked();\n }\n\n const existence = await git.branchExists(branchName);\n\n let created = false;\n let pushed = false;\n\n if (!existence.local && !existence.remote) {\n if (!baseBranch) {\n throw new Error(`Branch '${branchName}' does not exist. Provide 'baseBranch' to create it.`);\n }\n await git.createBranch(branchName, baseBranch);\n created = true;\n }\n\n const worktreeDir = service.config.worktreeDir;\n const worktreePath = pathResolution.getBranchWorktreePath(worktreeDir, branchName);\n const existing = await git.getWorktrees();\n const collision = existing.find((w) => pathsEqual(w.path, worktreePath) && w.branch !== branchName);\n if (collision) {\n throw new Error(\n `Sanitized worktree path '${worktreePath}' collides with existing branch '${collision.branch}'. Rename or remove the conflicting branch first.`,\n );\n }\n await git.addWorktree(branchName, worktreePath);\n ctx.invalidateDiscovered();\n\n if (created && push) {\n await git.pushBranch(branchName);\n pushed = true;\n }\n\n return formatToolResponse({\n success: true,\n branchName,\n worktreePath: path.resolve(worktreePath),\n created,\n pushed,\n });\n });\n}\n\nexport async function handleRemoveWorktree(\n ctx: RepositoryContext,\n params: { path: string; force?: boolean; repoName?: string },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { service, git } = await getReadyService(ctx, params.repoName, {\n capability: \"removeWorktree\",\n toolName: \"remove_worktree\",\n });\n ensureWorktreeModeService(service, \"remove_worktree\");\n\n return runExclusiveRepoOperation(ctx, params.repoName, service, async () => {\n if (!service.isInitialized()) {\n await service.initializeUnlocked();\n }\n const removedPath = await ensureRepoWorktreePath(ctx, params, service, git);\n\n if (!params.force) {\n const status = await git.getFullWorktreeStatus(params.path, false);\n if (!status.canRemove) {\n throw new Error(`Cannot remove worktree: ${status.reasons.join(\", \")}. Use force=true to override.`);\n }\n }\n\n await git.removeWorktree(params.path);\n ctx.invalidateDiscovered();\n\n return formatToolResponse({\n success: true,\n removedPath,\n });\n });\n}\n\nexport async function handleSync(\n ctx: RepositoryContext,\n params: { repoName?: string },\n extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { service } = await getReadyService(ctx, params.repoName, {\n capability: \"sync\",\n toolName: \"sync\",\n });\n\n const dispose = attachProgressReporter(service, extra);\n try {\n const start = Date.now();\n service.clearRecordedSkips();\n const result = await service.sync();\n if (!result.started) {\n throw new SyncInProgressError(ctx.getEntry(params.repoName)?.name ?? params.repoName ?? \"unknown\");\n }\n const duration = Date.now() - start;\n ctx.invalidateDiscovered();\n const outcome =\n result.outcome ??\n createEmptySyncOutcome(\n isCloneModeService(service) ? \"clone\" : \"worktree\",\n ctx.getEntry(params.repoName)?.name ?? params.repoName,\n duration,\n );\n const skips = service.getRecordedSkips().map((reason) => ({\n ...reason,\n message: formatCloneSkipReason(reason),\n }));\n return formatToolResponse({\n success: true,\n duration,\n outcome: {\n ...outcome,\n durationMs: outcome.durationMs ?? duration,\n },\n skips,\n });\n } finally {\n dispose();\n }\n}\n\nexport async function handleUpdateWorktree(\n ctx: RepositoryContext,\n params: { path: string; repoName?: string },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { service, git } = await getReadyService(ctx, params.repoName, {\n capability: \"updateWorktree\",\n toolName: \"update_worktree\",\n });\n ensureWorktreeModeService(service, \"update_worktree\");\n\n return runExclusiveRepoOperation(ctx, params.repoName, service, async () => {\n if (!service.isInitialized()) {\n await service.initializeUnlocked();\n }\n const worktreePath = await ensureRepoWorktreePath(ctx, params, service, git);\n\n await git.updateWorktree(params.path);\n ctx.invalidateDiscovered();\n\n return formatToolResponse({\n success: true,\n worktreePath,\n });\n });\n}\n\nexport async function handleInitialize(\n ctx: RepositoryContext,\n params: { repoName?: string },\n extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { service } = await getReadyService(ctx, params.repoName, {\n capability: \"initialize\",\n toolName: \"initialize\",\n });\n const dispose = attachProgressReporter(service, extra);\n try {\n return await runExclusiveRepoOperation(ctx, params.repoName, service, async () => {\n await service.initializeUnlocked();\n // A standalone initialize does not surface skips in its response. Clear the\n // one-shot suppression token so a later independent `sync` re-detects and\n // reports a wrong-branch / unreadable-HEAD clone instead of swallowing it.\n service.clearPendingInitSkip();\n const git = service.getGitService();\n ctx.invalidateDiscovered();\n return formatToolResponse({\n success: true,\n defaultBranch: git.getDefaultBranch(),\n worktreeDir: service.config.worktreeDir,\n });\n });\n } finally {\n dispose();\n }\n}\n\nexport async function handleLoadConfig(\n ctx: RepositoryContext,\n params: { configPath?: string },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const configPath = params.configPath ?? process.env.SYNC_WORKTREES_CONFIG;\n if (!configPath) {\n throw new Error(\"configPath required (or set SYNC_WORKTREES_CONFIG env var)\");\n }\n await ctx.loadConfig(configPath);\n return formatToolResponse({\n configPath: path.resolve(configPath),\n currentRepository: ctx.getCurrentRepo(),\n repositories: ctx.getRepositoryList(),\n });\n}\n\nexport async function handleSetCurrentRepository(\n ctx: RepositoryContext,\n params: { repoName: string },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n ctx.setCurrentRepo(params.repoName);\n return formatToolResponse({\n currentRepository: ctx.getCurrentRepo(),\n repositories: ctx.getRepositoryList(),\n });\n}\n\nfunction attachProgressReporter(\n service: {\n onProgress?: (listener: (event: ProgressEvent) => void) => () => void;\n },\n extra: HandlerExtra | undefined,\n): () => void {\n const token = extra?._meta?.progressToken;\n if (token === undefined || !extra) return () => {};\n if (!service.onProgress) return () => {};\n\n let progressCounter = 0;\n const unsubscribe = service.onProgress((event) => {\n progressCounter++;\n void extra\n .sendNotification({\n method: \"notifications/progress\",\n params: {\n progressToken: token,\n progress: progressCounter,\n message: `[${event.phase}] ${event.message}`,\n },\n })\n .catch(() => {});\n });\n\n return unsubscribe;\n}\n", "import fastFolderSize from \"fast-folder-size\";\n\n/**\n * Calculates the total size of a directory in bytes using native OS utilities.\n * Uses the `du` command on Unix systems for optimal performance (10-100x faster than pure Node.js).\n * @param dirPath - The path to the directory\n * @returns The total size in bytes\n */\nexport async function calculateDirectorySize(dirPath: string): Promise<number> {\n return new Promise((resolve, reject) => {\n fastFolderSize(dirPath, (err, bytes) => {\n if (err) {\n reject(err);\n return;\n }\n if (bytes === undefined) {\n reject(new Error(`fast-folder-size returned no bytes for ${dirPath}`));\n return;\n }\n resolve(bytes);\n });\n });\n}\n\n/**\n * Formats bytes into a human-readable string.\n * @param bytes - The number of bytes\n * @returns Formatted string (e.g., \"1.2 GB\", \"345 MB\", \"12 KB\")\n */\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return \"0 B\";\n\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n const k = 1024;\n const decimals = 2;\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n const value = bytes / Math.pow(k, i);\n\n return `${value.toFixed(decimals)} ${units[i]}`;\n}\n\n/**\n * Calculates the total disk space used by sync-worktrees repositories.\n * This includes bare repository directories and all worktree directories.\n *\n * @param repoPaths - Array of bare repository directory paths (e.g., from config.bareRepoDir)\n * @param worktreeDirs - Array of worktree base directories\n * @returns Formatted disk space string (e.g., \"1.2 GB\") or \"N/A\" if calculation fails\n */\nexport async function calculateSyncDiskSpace(repoPaths: string[], worktreeDirs: string[]): Promise<string> {\n try {\n let totalBytes = 0;\n\n for (const repoPath of repoPaths) {\n try {\n totalBytes += await calculateDirectorySize(repoPath);\n } catch {\n /* skip unreadable bare repo */\n }\n }\n\n for (const worktreeDir of worktreeDirs) {\n try {\n totalBytes += await calculateDirectorySize(worktreeDir);\n } catch {\n /* skip unreadable worktree dir */\n }\n }\n\n return formatBytes(totalBytes);\n } catch (error) {\n console.error(\"Failed to calculate disk space:\", error);\n return \"N/A\";\n }\n}\n", "export function isValidGitBranchName(name: string): { valid: boolean; error?: string } {\n if (!name.trim()) {\n return { valid: false, error: \"Branch name cannot be empty\" };\n }\n if (name === \"@\") {\n return { valid: false, error: \"Branch name cannot be '@'\" };\n }\n if (name.startsWith(\"-\")) {\n return { valid: false, error: \"Branch name cannot start with '-'\" };\n }\n if (name.startsWith(\"/\") || name.endsWith(\"/\")) {\n return { valid: false, error: \"Branch name cannot start or end with '/'\" };\n }\n if (name.endsWith(\".lock\")) {\n return { valid: false, error: \"Branch name cannot end with '.lock'\" };\n }\n if (name.includes(\"..\")) {\n return { valid: false, error: \"Branch name cannot contain '..'\" };\n }\n if (name.includes(\"@{\")) {\n return { valid: false, error: \"Branch name cannot contain '@{'\" };\n }\n if (name.includes(\"/.\") || name.includes(\"./\")) {\n return { valid: false, error: \"Branch name cannot contain '/.' or './'\" };\n }\n if (name.startsWith(\".\") || name.endsWith(\".\")) {\n return { valid: false, error: \"Branch name cannot start or end with '.'\" };\n }\n if (name.includes(\"//\")) {\n return { valid: false, error: \"Branch name cannot contain consecutive slashes\" };\n }\n for (const component of name.split(\"/\")) {\n if (component === \"\") {\n return { valid: false, error: \"Branch name cannot contain empty path components\" };\n }\n if (component.startsWith(\".\") || component.endsWith(\".\")) {\n return { valid: false, error: \"Branch name path components cannot start or end with '.'\" };\n }\n if (component.endsWith(\".lock\")) {\n return { valid: false, error: \"Branch name path components cannot end with '.lock'\" };\n }\n }\n // eslint-disable-next-line no-control-regex\n if (/[\\x00-\\x20\\x7f~^:?*[\\\\]/.test(name)) {\n return { valid: false, error: \"Branch name contains invalid characters\" };\n }\n return { valid: true };\n}\n", "import { SyncWorktreesError } from \"../errors\";\n\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type { CallToolResult, ServerNotification, ServerRequest } from \"@modelcontextprotocol/sdk/types.js\";\n\nexport type HandlerExtra = RequestHandlerExtra<ServerRequest, ServerNotification>;\n\nexport function formatToolResponse(data: unknown): CallToolResult {\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(data),\n },\n ],\n };\n}\n\nexport function formatErrorResponse(error: unknown): CallToolResult {\n let code = \"UNKNOWN_ERROR\";\n let message = String(error);\n\n if (error instanceof SyncWorktreesError) {\n code = error.code;\n message = error.message;\n } else if (error instanceof Error) {\n code = \"INTERNAL_ERROR\";\n message = error.message;\n }\n\n const body: Record<string, unknown> = {\n error: true,\n code,\n message,\n };\n\n if (process.env.DEBUG && error instanceof Error && error.stack) {\n body.stack = error.stack;\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(body),\n },\n ],\n isError: true,\n };\n}\n\nexport class CapabilityUnavailableError extends SyncWorktreesError {\n constructor(capability: string, reasons: string[]) {\n super(`Capability '${capability}' unavailable: ${reasons.join(\", \")}`, \"CAPABILITY_UNAVAILABLE\");\n }\n}\n\nexport class SyncInProgressError extends SyncWorktreesError {\n constructor(repoName: string) {\n super(`Sync already in progress for '${repoName}'`, \"SYNC_IN_PROGRESS\");\n }\n}\n\nexport function wrapHandler<P>(\n fn: (params: P, extra: HandlerExtra) => Promise<CallToolResult>,\n): (params: P, extra: HandlerExtra) => Promise<CallToolResult> {\n return async (params, extra) => {\n try {\n return await fn(params, extra);\n } catch (error) {\n return formatErrorResponse(error);\n }\n };\n}\n", "import simpleGit from \"simple-git\";\n\nimport type { WorktreeStatusResult } from \"../services/worktree-status.service\";\n\nexport type WorktreeLabel = \"current\" | \"dirty\" | \"stale\" | \"clean\" | \"unknown\";\n\nexport interface Divergence {\n ahead: number;\n behind: number;\n}\n\nexport interface SafeToRemove {\n safe: boolean;\n reason: string;\n}\n\nexport function deriveLabel(status: WorktreeStatusResult, isCurrent: boolean): WorktreeLabel {\n if (isCurrent) return \"current\";\n if (!status.isClean || status.hasUnpushedCommits || status.hasStashedChanges) return \"dirty\";\n if (status.upstreamGone) return \"stale\";\n return \"clean\";\n}\n\nexport function deriveSafeToRemove(status: WorktreeStatusResult): SafeToRemove {\n if (status.canRemove && !status.upstreamGone) {\n return { safe: true, reason: \"clean tree, no unpushed commits\" };\n }\n\n if (status.canRemove && status.upstreamGone) {\n return { safe: false, reason: \"branch deleted upstream \u2014 verify no work is lost before removal\" };\n }\n\n if (status.reasons.length > 0) {\n return { safe: false, reason: status.reasons.join(\", \") };\n }\n\n return { safe: false, reason: \"not safe to remove\" };\n}\n\nexport async function getDivergence(worktreePath: string): Promise<Divergence | null> {\n try {\n const git = simpleGit(worktreePath);\n const output = await git.raw([\"rev-list\", \"--left-right\", \"--count\", \"HEAD...@{upstream}\"]);\n const [aheadStr, behindStr] = output.trim().split(/\\s+/);\n return { ahead: parseInt(aheadStr, 10), behind: parseInt(behindStr, 10) };\n } catch {\n return null;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["fs", "path", "pLimit", "simpleGit", "path", "path", "path", "retry", "resolve", "fs", "path", "fs", "path", "path", "fs", "path", "simpleGit", "path", "simpleGit", "simpleGit", "matcher", "fs", "path", "simpleGit", "simpleGit", "fs", "path", "simpleGit", "stat", "simpleGit", "simpleGit", "resolve", "fs", "path", "path", "fs", "path", "formatDuration", "createHash", "fs", "path", "createHash", "path", "pathResolution", "formatDuration", "stat", "simpleGit", "pLimit", "stat", "path", "pLimit", "resolve", "simpleGit", "pLimit"]
|
|
7
7
|
}
|