sync-worktrees 3.5.0 → 3.6.1

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.
@@ -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/utils/branch-filter.ts", "../src/utils/git-url.ts", "../src/utils/path-compare.ts", "../src/errors/index.ts", "../src/utils/sanitize-name.ts", "../src/services/logger.service.ts", "../src/services/worktree-sync.service.ts", "../src/utils/date-filter.ts", "../src/utils/lfs-error.ts", "../src/utils/retry.ts", "../src/utils/timing.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/path-resolution.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, { discovered });\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 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 { 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 configMatched: boolean;\n}\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 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\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\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 private async discoverSiblingRepositories(currentBareRepoPath: string): Promise<SiblingRepository[]> {\n const repoDir = path.dirname(currentBareRepoPath);\n const workspaceRoot = path.dirname(repoDir);\n\n if (workspaceRoot === repoDir) return [];\n\n let entries: string[];\n try {\n entries = await fs.readdir(workspaceRoot);\n } catch {\n return [];\n }\n\n const configBares = new Map<string, string>();\n for (const entry of this.repos.values()) {\n if (entry.source === \"config\" && entry.config.bareRepoDir) {\n configBares.set(normalizePathForCompare(entry.config.bareRepoDir), entry.name);\n }\n }\n\n const results: SiblingRepository[] = [];\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 try {\n const stat = await fs.stat(bareCandidate);\n if (!stat.isDirectory()) return;\n } catch {\n return;\n }\n\n const resolvedBare = path.resolve(bareCandidate);\n const matchedName = configBares.get(normalizePathForCompare(resolvedBare));\n results.push({\n name: matchedName ?? entry,\n bareRepoPath: resolvedBare,\n configMatched: matchedName !== undefined,\n });\n }),\n );\n\n results.sort((a, b) => a.name.localeCompare(b.name));\n return results;\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 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 const name = repoName ?? this.currentRepo;\n if (!name) {\n throw new Error(\"No repository specified and no current repository set\");\n }\n const entry = this.repos.get(name);\n if (!entry) {\n throw new Error(`Repository '${name}' not found. Load a config or run detect_context first.`);\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 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 getConfigPath(): string | null {\n return this.configPath;\n }\n}\n\nfunction parseWorktreeList(output: string, currentPath: string): DiscoveredWorktree[] {\n const foldedCurrent = normalizePathForCompare(currentPath);\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: 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 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} 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} 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 fs from \"fs/promises\";\nimport * 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 { matchesPattern } from \"../utils/branch-filter\";\nimport { getDefaultBareRepoDir } from \"../utils/git-url\";\nimport { normalizePathForCompare } from \"../utils/path-compare\";\nimport { sanitizeNameForPath } from \"../utils/sanitize-name\";\n\nimport type { Config, ConfigFile, RepositoryConfig } from \"../types\";\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 try {\n await fs.access(candidate);\n return candidate;\n } catch {\n /* try next */\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 try {\n await fs.access(absolutePath);\n } catch {\n throw new Error(`Config file not found: ${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 Error && error.message.includes(\"Config file not found\")) {\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.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\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.retry !== undefined && typeof defaults.retry !== \"object\") {\n throw new Error(\"Invalid 'retry' in defaults\");\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\n if (configObj.retry !== undefined) {\n if (typeof configObj.retry !== \"object\") {\n throw new Error(\"'retry' must be an object\");\n }\n\n const retry = configObj.retry 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 if (\n retry.initialDelayMs !== undefined &&\n (typeof retry.initialDelayMs !== \"number\" || retry.initialDelayMs < 0)\n ) {\n throw new Error(\"Invalid 'initialDelayMs' in retry config\");\n }\n if (retry.maxDelayMs !== undefined && (typeof retry.maxDelayMs !== \"number\" || retry.maxDelayMs < 0)) {\n throw new Error(\"Invalid 'maxDelayMs' in retry config\");\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 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 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 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 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 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 };\n\n if (repo.bareRepoDir) {\n resolved.bareRepoDir = this.resolvePath(repo.bareRepoDir, configDir);\n } else if (allRepositories && this.isDuplicateRepoUrl(repo, allRepositories)) {\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.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.updateExistingWorktrees !== undefined || defaults?.updateExistingWorktrees !== undefined) {\n resolved.updateExistingWorktrees = repo.updateExistingWorktrees ?? defaults?.updateExistingWorktrees ?? true;\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[]): boolean {\n const firstIndex = all.findIndex((r) => r.repoUrl === repo.repoUrl);\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; noUpdateExisting?: boolean; debug?: boolean },\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 if (overrides?.noUpdateExisting) {\n repositories = repositories.map((repo) => ({ ...repo, updateExistingWorktrees: false }));\n }\n\n if (overrides?.debug) {\n repositories = repositories.map((repo) => ({ ...repo, debug: true }));\n }\n\n return { repositories, configFile, configDir };\n }\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", "/**\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", "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 { 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 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", "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", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport pLimit from \"p-limit\";\nimport * as lockfile from \"proper-lockfile\";\n\nimport { DEFAULT_CONFIG, ENV_CONSTANTS, 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\";\nimport { retry } from \"../utils/retry\";\nimport { PhaseTimer, Timer, formatTimingTable } from \"../utils/timing\";\n\nimport { GitService } from \"./git.service\";\nimport { Logger } from \"./logger.service\";\nimport { PathResolutionService } from \"./path-resolution.service\";\n\nimport type { Config } from \"../types\";\nimport type { WorktreeStatusDetails } from \"./worktree-status.service\";\nimport type { RetryOptions } from \"../utils/retry\";\n\nexport type SyncResult =\n | { started: true }\n | { started: false; reason: \"in_progress\" }\n | { started: false; reason: \"locked\" };\n\nexport interface ProgressEvent {\n phase: string;\n message: string;\n}\n\nexport type ProgressListener = (event: ProgressEvent) => void;\n\nexport class WorktreeSyncService {\n private gitService: GitService;\n private logger: Logger;\n private syncInProgress: boolean = false;\n private pathResolution = new PathResolutionService();\n private progressListeners = new Set<ProgressListener>();\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 }\n\n async initialize(): Promise<void> {\n this.emitProgress({ phase: \"initialize\", message: \"Initializing repository\" });\n await this.gitService.initialize();\n this.emitProgress({ phase: \"initialize\", message: \"Repository initialized\" });\n }\n\n isInitialized(): boolean {\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 }\n\n onProgress(listener: ProgressListener): () => void {\n this.progressListeners.add(listener);\n return () => this.progressListeners.delete(listener);\n }\n\n private emitProgress(event: ProgressEvent): void {\n for (const listener of this.progressListeners) {\n try {\n listener(event);\n } catch {\n // listener must not break sync flow\n }\n }\n }\n\n async sync(): Promise<SyncResult> {\n if (this.syncInProgress) {\n this.logger.warn(\"\u26A0\uFE0F Sync already in progress, skipping...\");\n return { started: false, reason: \"in_progress\" };\n }\n\n const release = await this.acquireBareLock();\n if (release === null) {\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 this.syncInProgress = true;\n this.logger.info(`[${new Date().toISOString()}] Starting worktree synchronization...`);\n\n const totalTimer = new Timer();\n const phaseTimer = new PhaseTimer();\n const syncContext = { lfsSkipEnabled: false };\n const retryOptions = this.createRetryOptions(syncContext);\n\n try {\n await retry(() => this.runSyncAttempt(phaseTimer, syncContext), retryOptions);\n } catch (error) {\n this.logger.error(\"\\n\u274C Error during worktree synchronization after all retry attempts:\", error);\n throw error;\n } finally {\n if (syncContext.lfsSkipEnabled && !this.config.skipLfs) {\n this.gitService.setLfsSkipEnabled(false);\n }\n this.syncInProgress = false;\n try {\n await release();\n } catch (releaseError) {\n this.logger.warn(`Failed to release sync lock: ${getErrorMessage(releaseError)}`);\n }\n this.logger.info(`[${new Date().toISOString()}] Synchronization finished.\\n`);\n\n if (this.config.debug) {\n const totalDuration = totalTimer.stop();\n const phaseResults = phaseTimer.getResults();\n const repoName = (this.config as { name?: string }).name;\n this.logger.table(formatTimingTable(totalDuration, phaseResults, repoName));\n }\n }\n\n return { started: true };\n }\n\n private async acquireBareLock(): Promise<(() => Promise<void>) | null> {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) {\n return async () => {};\n }\n\n if (typeof this.gitService.getBareRepoPath !== \"function\") {\n return async () => {};\n }\n\n const barePath = this.gitService.getBareRepoPath();\n const lockTarget = path.join(barePath, \"HEAD\");\n\n try {\n await fs.access(lockTarget);\n } catch {\n return async () => {};\n }\n\n try {\n const release = 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 return release;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ELOCKED\") {\n return null;\n }\n throw error;\n }\n }\n\n private createRetryOptions(syncContext: { lfsSkipEnabled: boolean }): 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 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 private async runSyncAttempt(phaseTimer: PhaseTimer, syncContext: { lfsSkipEnabled: boolean }): 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 await this.createNewWorktreesWithTiming(remoteBranches, worktrees, defaultBranch, phaseTimer);\n await this.pruneOldWorktreesWithTiming(remoteBranches, worktrees, phaseTimer);\n\n if (this.config.updateExistingWorktrees !== false) {\n await this.updateExistingWorktreesWithTiming(worktrees, remoteBranches, phaseTimer);\n }\n\n if (this.config.sparseCheckout) {\n await this.reapplySparseCheckout(worktrees);\n }\n\n await this.finalizeSyncAttempt(phaseTimer);\n }\n\n private async reapplySparseCheckout(worktrees: { path: string; branch: string }[]): 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 worktrees.map((worktree) =>\n limit(async () => {\n try {\n try {\n await fs.access(worktree.path);\n } catch {\n return;\n }\n\n const current = await sparseService.readCurrent(worktree.path);\n if (current !== null && sparseService.patternsEqual(current, desired)) return;\n\n if (sparseService.isNarrowing(current, desired)) {\n const status = await this.gitService.getFullWorktreeStatus(worktree.path, false);\n if (!status.canRemove) {\n this.logger.warn(\n ` - Skipping sparse-checkout narrowing for '${worktree.branch}': ${status.reasons.join(\", \")}.`,\n );\n return;\n }\n }\n\n await sparseService.applyToWorktree(worktree.path, sparseConfig);\n await this.gitService.checkoutHead(worktree.path);\n this.logger.info(` - \u2705 Sparse-checkout updated for '${worktree.branch}'`);\n } catch (error) {\n this.logger.warn(\n ` - \u26A0\uFE0F Failed to update sparse-checkout for '${worktree.branch}': ${getErrorMessage(error)}`,\n );\n }\n }),\n ),\n );\n }\n\n private async fetchLatestRemoteData(phaseTimer: PhaseTimer, syncContext: { lfsSkipEnabled: boolean }): Promise<void> {\n this.logger.info(\"Step 1: Fetching latest data from remote...\");\n phaseTimer.startPhase(\"Phase 1: Fetch\");\n this.emitProgress({ 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.emitProgress({ 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 remoteBranches: string[],\n worktrees: Array<{ path: string; branch: string }>,\n defaultBranch: string,\n phaseTimer: PhaseTimer,\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.emitProgress({ phase: \"create\", message: \"Creating worktrees for new branches\" });\n\n await this.createNewWorktrees(remoteBranches, worktrees, defaultBranch);\n\n const existingBranches = new Set(worktrees.map((w) => w.branch));\n const newBranches = remoteBranches.filter((b) => !existingBranches.has(b) && b !== defaultBranch);\n phaseTimer.setPhaseCount(\"Phase 2: Create\", newBranches.length);\n phaseTimer.endPhase();\n }\n\n private async createNewWorktrees(\n remoteBranches: string[],\n worktrees: Array<{ path: string; branch: string }>,\n defaultBranch: string,\n ): Promise<void> {\n const existingBranches = new Set(worktrees.map((w) => w.branch));\n const newBranches = remoteBranches.filter((b) => !existingBranches.has(b) && b !== defaultBranch);\n\n if (newBranches.length === 0) {\n this.logger.info(\"Step 2: No new branches to create worktrees for.\");\n return;\n }\n\n const reservedPaths = new Map<string, string>();\n for (const w of worktrees) {\n reservedPaths.set(path.resolve(w.path), w.branch);\n }\n\n const plan: Array<{ branchName: string; worktreePath: string }> = [];\n for (const branchName of newBranches) {\n const worktreePath = this.pathResolution.getBranchWorktreePath(this.config.worktreeDir, branchName);\n const resolved = path.resolve(worktreePath);\n const conflict = reservedPaths.get(resolved);\n if (conflict && conflict !== branchName) {\n this.logger.error(\n ` \u274C Skipping '${branchName}': sanitized worktree path '${worktreePath}' collides with existing branch '${conflict}'.`,\n );\n continue;\n }\n reservedPaths.set(resolved, branchName);\n plan.push({ branchName, worktreePath });\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 } catch (error) {\n this.logger.error(` \u274C Failed to create worktree for '${branchName}':`, getErrorMessage(error));\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 remoteBranches: string[],\n worktrees: Array<{ path: string; branch: string }>,\n phaseTimer: PhaseTimer,\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.emitProgress({ phase: \"prune\", message: \"Pruning stale worktrees\" });\n\n await this.pruneOldWorktrees(remoteBranches, worktrees);\n\n const deletedWorktrees = worktrees.filter((w) => !remoteBranches.includes(w.branch));\n phaseTimer.setPhaseCount(\"Phase 3: Prune\", deletedWorktrees.length);\n phaseTimer.endPhase();\n }\n\n private async pruneOldWorktrees(\n remoteBranches: string[],\n worktrees: Array<{ path: string; branch: string }>,\n ): Promise<void> {\n const deletedWorktrees = worktrees.filter((w) => !remoteBranches.includes(w.branch));\n\n if (deletedWorktrees.length > 0) {\n this.logger.info(`Step 3: Checking ${deletedWorktrees.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 deletedWorktrees.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 }\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 return;\n }\n await this.gitService.removeWorktree(worktreePath);\n this.logger.info(` \u2705 Removed worktree for '${branchName}'`);\n } catch (error) {\n this.logger.error(` \u274C Failed to remove worktree for '${branchName}':`, getErrorMessage(error));\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 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 worktrees: { path: string; branch: string }[],\n remoteBranches: string[],\n phaseTimer: PhaseTimer,\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.emitProgress({ phase: \"update\", message: \"Updating existing worktrees\" });\n\n await this.updateExistingWorktrees(worktrees, remoteBranches);\n\n const activeWorktrees = worktrees.filter((w) => remoteBranches.includes(w.branch));\n phaseTimer.setPhaseCount(\"Phase 4: Update\", activeWorktrees.length);\n phaseTimer.endPhase();\n }\n\n private async updateExistingWorktrees(\n worktrees: { path: string; branch: string }[],\n remoteBranches: string[],\n ): 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 const activeWorktrees = worktrees.filter((w) => remoteBranches.includes(w.branch));\n\n type UpdateCheckResult = { action: \"update\" | \"diverged\"; worktree: { path: string; branch: string } } | null;\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 activeWorktrees.map((worktree) =>\n limit(async (): Promise<UpdateCheckResult> => {\n try {\n await fs.access(worktree.path);\n } catch {\n return null;\n }\n\n const hasOp = await this.gitService.hasOperationInProgress(worktree.path);\n if (hasOp) return null;\n\n const isClean = await this.gitService.checkWorktreeStatus(worktree.path);\n if (!isClean) return null;\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 null;\n }\n return { action: \"diverged\", worktree };\n }\n\n const isBehind = await this.gitService.isWorktreeBehind(worktree.path);\n if (!isBehind) return null;\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 null;\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 if (result.value.action === \"update\") {\n worktreesToUpdate.push(result.value.worktree);\n } else {\n divergedWorktrees.push(result.value.worktree);\n }\n } else if (result.status === \"rejected\") {\n this.logger.error(` - Error checking worktree:`, result.reason);\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 } 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);\n } catch (divergedError) {\n this.logger.error(` \u274C Failed to handle diverged branch '${worktree.branch}':`, divergedError);\n throw divergedError;\n }\n } else {\n this.logger.error(` \u274C Failed to update '${worktree.branch}':`, error);\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);\n } catch (error) {\n this.logger.error(` \u274C Failed to handle diverged branch '${worktree.branch}':`, error);\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 // For each directory, check if it's part of any worktree path\n const orphanedDirs: string[] = [];\n for (const dir of regularDirs) {\n // Check if this directory is part of any worktree path\n const isPartOfWorktree = worktreeRelativePaths.some((worktreePath) => {\n // Either the directory IS a worktree or it's a parent of a worktree\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(worktree: { path: string; branch: string }): 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 } 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 } 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\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 // Create .diverged directory inside worktreeDir\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 // Ensure diverged directory exists\n await fs.mkdir(divergedBaseDir, { recursive: true });\n\n // Move the worktree directory; on cross-device errors, fall back to copy+remove\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 // Save metadata about why it was moved\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", "/**\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", "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, GIT_CONSTANTS } from \"../constants\";\nimport { WorktreeError } from \"../errors\";\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 } from \"simple-git\";\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 block = this.getFetchTimeoutMs();\n const base = block > 0 ? simpleGit(dirPath, { timeout: { block } }) : simpleGit(dirPath);\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 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 cloneBlock = this.getCloneTimeoutMs();\n const cloneBase = cloneBlock > 0 ? simpleGit({ timeout: { block: cloneBlock } }) : simpleGit();\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\"]);\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\"]);\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 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\"]);\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\"]);\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 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 await bareGit.raw([\"show-ref\", \"--verify\", \"--quiet\", 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 async createBranch(branchName: string, baseBranch: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n\n await bareGit.raw([\"branch\", branchName, `origin/${baseBranch}`]);\n this.logger.info(`Created branch '${branchName}' from '${baseBranch}'`);\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 needsUpdate(worktreePath: string, cfg: SparseCheckoutConfig): Promise<boolean> {\n const current = await this.readCurrent(worktreePath);\n const desired = this.buildPatterns(cfg);\n if (current === null) return true;\n return !this.patternsEqual(current, desired);\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 { 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 try {\n await fs.access(worktreePath);\n } catch {\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 (hasOperationInProgress) reasons.push(\"operation in progress\");\n if (hasModifiedSubmodules) reasons.push(\"modified submodules\");\n if (upstreamGone) reasons.push(\"upstream gone\");\n\n const canRemove = isClean && !hasUnpushedCommits && !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", "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 { 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 \"Repository name from loaded config. If omitted, uses the current repository set via set_current_repository or the only loaded repo.\";\n\nconst PATH_DESCRIBE_SUFFIX = \"Absolute path preferred; relative paths resolve from the server's CWD.\";\n\nconst SERVER_INSTRUCTIONS =\n \"Before running git worktree operations, call `detect_context` to learn the current repo, current branch, sibling repositories under the workspace root, and which capabilities are available. \" +\n \"It walks up to auto-discover sync-worktrees.config.{js,mjs,cjs,ts}, lists sibling worktrees, and reports per-capability {available, reason} so you can tell which tool is gated and why.\";\n\nexport interface ServerSnapshot {\n discovered: DiscoveredRepoContext | null;\n}\n\nexport function buildInstructions(snapshot?: ServerSnapshot): string {\n const d = snapshot?.discovered;\n if (!d || !d.isWorktree || d.kind !== \"managed\") return SERVER_INSTRUCTIONS;\n\n const lines: string[] = [\"Connect-time context (call `detect_context` for live state):\"];\n if (d.kind) lines.push(`- kind: ${d.kind}`);\n if (d.currentWorktreePath) lines.push(`- currentWorktreePath: ${d.currentWorktreePath}`);\n if (d.currentBranch) lines.push(`- currentBranch: ${d.currentBranch}`);\n if (d.configPath) lines.push(`- configPath: ${d.configPath}`);\n\n return `${SERVER_INSTRUCTIONS}\\n\\n${lines.join(\"\\n\")}`;\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 \"Current sync-worktrees workspace context: whether CWD is inside a managed worktree, the current branch, sibling worktrees, sibling repositories, auto-discovered configPath, and per-capability {available, reason}. Returns { isWorktree: false } when CWD is outside any workspace.\",\n mimeType: \"application/json\",\n },\n async (uri) => {\n let discovered: unknown;\n try {\n discovered = await context.detectFromPath(process.cwd());\n } catch (err) {\n discovered = 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(discovered, null, 2),\n },\n ],\n };\n },\n );\n\n server.registerTool(\n \"detect_context\",\n {\n description:\n \"Detect sync-worktrees structure from a filesystem path. Reads .git file, resolves bare repo, discovers sibling worktrees, walks up for a sync-worktrees.config.{js,mjs,cjs,ts}, and lists sibling bare repos under the workspace root. Defaults to CWD. \" +\n \"Use when: bootstrapping from an unknown checkout. \" +\n \"Returns: discovered repo root, bare repo path, all sibling worktrees, sibling repositories, current worktree path, configPath (auto-found), per-capability {available, reason}, notes[].\",\n inputSchema: {\n path: z.string().optional().describe(\"Directory path to inspect. Defaults to the server's CWD.\"),\n includeStatus: z\n .boolean()\n .optional()\n .describe(\n \"If true, enriches each entry in allWorktrees with label, divergence, and staleHint. Adds one git status + rev-list per worktree. Default: false (cheap path).\",\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 all worktrees of a repository with enriched status. \" +\n \"Returns: array of { path, branch, isCurrent, label (clean|dirty|stale|current|unknown), status, divergence (ahead/behind), safeToRemove: { safe, reason }, lastSyncAt, sizeBytes }.\",\n inputSchema: {\n repoName: z.string().optional().describe(REPO_NAME_DESCRIBE),\n includeSize: z\n .boolean()\n .optional()\n .describe(\n \"If true, computes the on-disk size of each worktree (in bytes). Slow on large worktrees. Default: false (sizeBytes returned as 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 \"Get detailed status for one worktree (dirty files, unpushed commits, stashes, upstream gone, operations in progress). \" +\n \"Returns: full status object plus divergence { ahead, behind } and resolved absolute 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(\"If true, includes 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 a worktree for a branch. If the branch exists (local or remote), checks it out; otherwise creates it from baseBranch. Optionally pushes the new branch to origin. \" +\n \"Key params: baseBranch is required only when the branch does not yet exist \u2014 pass it defensively if unsure. push=true only affects newly created branches. \" +\n \"Preconditions: repository must be initialized (auto-runs on first call). \" +\n \"Returns: { success, branchName, worktreePath, created, pushed }.\",\n inputSchema: {\n branchName: z\n .string()\n .describe(\"Branch name. Slashes and special chars are sanitized for the worktree directory name.\"),\n baseBranch: z\n .string()\n .optional()\n .describe(\n \"Base branch for creating a new branch. Required if branchName does not exist locally or remotely; ignored otherwise.\",\n ),\n push: z\n .boolean()\n .optional()\n .describe(\"Push the newly created branch to origin. Ignored if the branch already 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 a worktree. Runs safety checks first: rejects if worktree is dirty, has unpushed commits, has stashes, or has an in-progress git operation (merge/rebase/cherry-pick/revert/bisect). \" +\n \"force=true: runs `git worktree remove --force`, which DELETES uncommitted and untracked files in the worktree directory. Branch ref, stashes, and remote state are preserved. \" +\n \"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(\n \"Skip safety checks and delete uncommitted/untracked files in the worktree directory. Branch ref is preserved. Default: false.\",\n ),\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 \"Full repo-wide synchronization: fetch all, create worktrees for new remote branches, remove worktrees for pruned remote branches (clean only), fast-forward existing worktrees. Emits progress notifications. \" +\n \"Do not use when: you only need to update one worktree \u2014 use update_worktree. Only need to create one \u2014 use create_worktree. \" +\n \"Preconditions: config must be loaded (load_config) and the repository initialized (auto-runs on first call). \" +\n \"Returns: { success, duration } after sync completes.\",\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 match its upstream. No merge commits, no rebasing, aborts if not fast-forwardable. \" +\n \"Do not use when: you want to update every worktree in the repo \u2014 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 a repository: clone as bare repo if missing, create main worktree. Safe to call on already-initialized repos (no-op-ish). Emits progress notifications. \" +\n \"Preconditions: config must be loaded (load_config) so the repo's URL and paths are known. \" +\n \"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 or reload a sync-worktrees JavaScript config file into the server's session. Replaces any previously loaded repositories. \" +\n \"Call this before sync/initialize/create_worktree when using a config-driven workflow. \" +\n \"Returns: { configPath, currentRepository, repositories: [{ name, repoPath, worktreeDir, ... }] }.\",\n inputSchema: {\n configPath: z\n .string()\n .optional()\n .describe(\n \"Path to the config file. If omitted, falls back to the SYNC_WORKTREES_CONFIG env var. Errors if neither is set.\",\n ),\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 the current repository for subsequent tool calls that omit repoName. Session-scoped; not persisted across server restarts. \" +\n \"Preconditions: load_config must have been called so the name is known.\",\n inputSchema: {\n repoName: z.string().describe(\"Repository name as listed in the loaded config's `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 { WorktreeStatusService } from \"../services/worktree-status.service\";\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 { 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\"]>;\n\nconst pathResolution = new PathResolutionService();\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 ensureNotSyncing(ctx: RepositoryContext, repoName?: string): Promise<void> {\n const entry = ctx.getEntry(repoName);\n if (!entry?.service) return;\n if (entry.service.isSyncInProgress()) {\n throw new SyncInProgressError(entry.name);\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 ensureNotSyncing?: boolean;\n } = {},\n): Promise<{ discovered: DiscoveredRepoContext | null; service: RepoService; git: RepoGitService }> {\n const discovered = ctx.getDiscoveredContext(repoName);\n if (options.capability && options.toolName) {\n ensureCapability(discovered, options.capability, options.toolName);\n }\n if (options.ensureNotSyncing) {\n await ensureNotSyncing(ctx, repoName);\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 ensureRepoWorktreePath(\n ctx: RepositoryContext,\n params: WorktreePathParams,\n git: RepoGitService,\n): Promise<string> {\n await ensurePathBelongsToRepo(ctx, params.path, params.repoName, git);\n return path.resolve(params.path);\n}\n\nasync function ensurePathBelongsToRepo(\n ctx: RepositoryContext,\n targetPath: string,\n repoName: string | undefined,\n git: { getWorktrees: () => Promise<Array<{ path: string }>> },\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 git.getWorktrees();\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\nexport async function handleDetectContext(\n ctx: RepositoryContext,\n params: { path?: string; includeStatus?: boolean },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const target = params.path ?? process.cwd();\n const discovered = await ctx.detectFromPath(target);\n\n if (!params.includeStatus || discovered.allWorktrees.length === 0) {\n return formatToolResponse(discovered);\n }\n\n const statusService = new WorktreeStatusService();\n const limit = pLimit(DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\n\n const enriched: DiscoveredWorktree[] = await Promise.all(\n discovered.allWorktrees.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 return formatToolResponse({ ...discovered, allWorktrees: enriched });\n}\n\nexport async function handleListWorktrees(\n ctx: RepositoryContext,\n params: { repoName?: string; includeSize?: boolean },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { discovered, git } = await getReadyService(ctx, params.repoName, {\n capability: \"listWorktrees\",\n toolName: \"list_worktrees\",\n });\n\n let worktrees: Array<{ path: string; branch: string }>;\n try {\n worktrees = await git.getWorktrees();\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 limit = pLimit(DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\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 params.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 formatToolResponse({ worktrees: 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 { git } = await getReadyService(ctx, params.repoName, {\n capability: \"getStatus\",\n toolName: \"get_worktree_status\",\n });\n const resolvedPath = await ensureRepoWorktreePath(ctx, params, 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, push } = params;\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 ensureInitialized: true,\n ensureNotSyncing: true,\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\nexport async function handleRemoveWorktree(\n ctx: RepositoryContext,\n params: { path: string; force?: boolean; repoName?: string },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { git } = await getReadyService(ctx, params.repoName, {\n capability: \"removeWorktree\",\n toolName: \"remove_worktree\",\n ensureInitialized: true,\n ensureNotSyncing: true,\n });\n const removedPath = await ensureRepoWorktreePath(ctx, params, 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\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 ensureInitialized: true,\n });\n\n const dispose = attachProgressReporter(service, extra);\n try {\n const start = Date.now();\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 return formatToolResponse({ success: true, duration });\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 { git } = await getReadyService(ctx, params.repoName, {\n capability: \"updateWorktree\",\n toolName: \"update_worktree\",\n ensureInitialized: true,\n ensureNotSyncing: true,\n });\n const worktreePath = await ensureRepoWorktreePath(ctx, params, git);\n\n await git.updateWorktree(params.path);\n ctx.invalidateDiscovered();\n\n return formatToolResponse({\n success: true,\n worktreePath,\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 ensureNotSyncing: true,\n });\n const dispose = attachProgressReporter(service, extra);\n try {\n await service.initialize();\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 } 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, null, 2),\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, null, 2),\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, { discovered });\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 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 { 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 configMatched: boolean;\n}\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 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\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\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 private async discoverSiblingRepositories(currentBareRepoPath: string): Promise<SiblingRepository[]> {\n const repoDir = path.dirname(currentBareRepoPath);\n const workspaceRoot = path.dirname(repoDir);\n\n if (workspaceRoot === repoDir) return [];\n\n let entries: string[];\n try {\n entries = await fs.readdir(workspaceRoot);\n } catch {\n return [];\n }\n\n const configBares = new Map<string, string>();\n for (const entry of this.repos.values()) {\n if (entry.source === \"config\" && entry.config.bareRepoDir) {\n configBares.set(normalizePathForCompare(entry.config.bareRepoDir), entry.name);\n }\n }\n\n const results: SiblingRepository[] = [];\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 try {\n const stat = await fs.stat(bareCandidate);\n if (!stat.isDirectory()) return;\n } catch {\n return;\n }\n\n const resolvedBare = path.resolve(bareCandidate);\n const matchedName = configBares.get(normalizePathForCompare(resolvedBare));\n results.push({\n name: matchedName ?? entry,\n bareRepoPath: resolvedBare,\n configMatched: matchedName !== undefined,\n });\n }),\n );\n\n results.sort((a, b) => a.name.localeCompare(b.name));\n return results;\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 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 const name = repoName ?? this.currentRepo;\n if (!name) {\n throw new Error(\"No repository specified and no current repository set\");\n }\n const entry = this.repos.get(name);\n if (!entry) {\n throw new Error(`Repository '${name}' not found. Load a config or run detect_context first.`);\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 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 getConfigPath(): string | null {\n return this.configPath;\n }\n}\n\nfunction parseWorktreeList(output: string, currentPath: string): DiscoveredWorktree[] {\n const foldedCurrent = normalizePathForCompare(currentPath);\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: 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 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} 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 fs from \"fs/promises\";\nimport * 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 { matchesPattern } from \"../utils/branch-filter\";\nimport { getDefaultBareRepoDir } from \"../utils/git-url\";\nimport { normalizePathForCompare } from \"../utils/path-compare\";\nimport { sanitizeNameForPath } from \"../utils/sanitize-name\";\n\nimport type { Config, ConfigFile, RepositoryConfig } from \"../types\";\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 try {\n await fs.access(candidate);\n return candidate;\n } catch {\n /* try next */\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 try {\n await fs.access(absolutePath);\n } catch {\n throw new Error(`Config file not found: ${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 Error && error.message.includes(\"Config file not found\")) {\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.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\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.retry !== undefined && typeof defaults.retry !== \"object\") {\n throw new Error(\"Invalid 'retry' in defaults\");\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\n if (configObj.retry !== undefined) {\n if (typeof configObj.retry !== \"object\") {\n throw new Error(\"'retry' must be an object\");\n }\n\n const retry = configObj.retry 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 if (\n retry.initialDelayMs !== undefined &&\n (typeof retry.initialDelayMs !== \"number\" || retry.initialDelayMs < 0)\n ) {\n throw new Error(\"Invalid 'initialDelayMs' in retry config\");\n }\n if (retry.maxDelayMs !== undefined && (typeof retry.maxDelayMs !== \"number\" || retry.maxDelayMs < 0)) {\n throw new Error(\"Invalid 'maxDelayMs' in retry config\");\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 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 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 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 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 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 };\n\n if (repo.bareRepoDir) {\n resolved.bareRepoDir = this.resolvePath(repo.bareRepoDir, configDir);\n } else if (allRepositories && this.isDuplicateRepoUrl(repo, allRepositories)) {\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.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.updateExistingWorktrees !== undefined || defaults?.updateExistingWorktrees !== undefined) {\n resolved.updateExistingWorktrees = repo.updateExistingWorktrees ?? defaults?.updateExistingWorktrees ?? true;\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[]): boolean {\n const firstIndex = all.findIndex((r) => r.repoUrl === repo.repoUrl);\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; noUpdateExisting?: boolean; debug?: boolean },\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 if (overrides?.noUpdateExisting) {\n repositories = repositories.map((repo) => ({ ...repo, updateExistingWorktrees: false }));\n }\n\n if (overrides?.debug) {\n repositories = repositories.map((repo) => ({ ...repo, debug: true }));\n }\n\n return { repositories, configFile, configDir };\n }\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", "/**\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", "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 { 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 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", "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", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport pLimit from \"p-limit\";\nimport * as lockfile from \"proper-lockfile\";\n\nimport { DEFAULT_CONFIG, ENV_CONSTANTS, 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\";\nimport { retry } from \"../utils/retry\";\nimport { PhaseTimer, Timer, formatTimingTable } from \"../utils/timing\";\n\nimport { GitService } from \"./git.service\";\nimport { Logger } from \"./logger.service\";\nimport { PathResolutionService } from \"./path-resolution.service\";\n\nimport type { Config } from \"../types\";\nimport type { WorktreeStatusDetails } from \"./worktree-status.service\";\nimport type { RetryOptions } from \"../utils/retry\";\n\nexport type SyncResult =\n | { started: true }\n | { started: false; reason: \"in_progress\" }\n | { started: false; reason: \"locked\" };\n\nexport interface ProgressEvent {\n phase: string;\n message: string;\n}\n\nexport type ProgressListener = (event: ProgressEvent) => void;\n\nexport class WorktreeSyncService {\n private gitService: GitService;\n private logger: Logger;\n private syncInProgress: boolean = false;\n private pathResolution = new PathResolutionService();\n private progressListeners = new Set<ProgressListener>();\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 }\n\n async initialize(): Promise<void> {\n this.emitProgress({ phase: \"initialize\", message: \"Initializing repository\" });\n await this.gitService.initialize();\n this.emitProgress({ phase: \"initialize\", message: \"Repository initialized\" });\n }\n\n isInitialized(): boolean {\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 }\n\n onProgress(listener: ProgressListener): () => void {\n this.progressListeners.add(listener);\n return () => this.progressListeners.delete(listener);\n }\n\n private emitProgress(event: ProgressEvent): void {\n for (const listener of this.progressListeners) {\n try {\n listener(event);\n } catch {\n // listener must not break sync flow\n }\n }\n }\n\n async sync(): Promise<SyncResult> {\n if (this.syncInProgress) {\n this.logger.warn(\"\u26A0\uFE0F Sync already in progress, skipping...\");\n return { started: false, reason: \"in_progress\" };\n }\n\n const release = await this.acquireBareLock();\n if (release === null) {\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 this.syncInProgress = true;\n this.logger.info(`[${new Date().toISOString()}] Starting worktree synchronization...`);\n\n const totalTimer = new Timer();\n const phaseTimer = new PhaseTimer();\n const syncContext = { lfsSkipEnabled: false };\n const retryOptions = this.createRetryOptions(syncContext);\n\n try {\n await retry(() => this.runSyncAttempt(phaseTimer, syncContext), retryOptions);\n } catch (error) {\n this.logger.error(\"\\n\u274C Error during worktree synchronization after all retry attempts:\", error);\n throw error;\n } finally {\n if (syncContext.lfsSkipEnabled && !this.config.skipLfs) {\n this.gitService.setLfsSkipEnabled(false);\n }\n this.syncInProgress = false;\n try {\n await release();\n } catch (releaseError) {\n this.logger.warn(`Failed to release sync lock: ${getErrorMessage(releaseError)}`);\n }\n this.logger.info(`[${new Date().toISOString()}] Synchronization finished.\\n`);\n\n if (this.config.debug) {\n const totalDuration = totalTimer.stop();\n const phaseResults = phaseTimer.getResults();\n const repoName = (this.config as { name?: string }).name;\n this.logger.table(formatTimingTable(totalDuration, phaseResults, repoName));\n }\n }\n\n return { started: true };\n }\n\n private async acquireBareLock(): Promise<(() => Promise<void>) | null> {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) {\n return async () => {};\n }\n\n if (typeof this.gitService.getBareRepoPath !== \"function\") {\n return async () => {};\n }\n\n const barePath = this.gitService.getBareRepoPath();\n const lockTarget = path.join(barePath, \"HEAD\");\n\n try {\n await fs.access(lockTarget);\n } catch {\n return async () => {};\n }\n\n try {\n const release = 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 return release;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ELOCKED\") {\n return null;\n }\n throw error;\n }\n }\n\n private createRetryOptions(syncContext: { lfsSkipEnabled: boolean }): 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 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 private async runSyncAttempt(phaseTimer: PhaseTimer, syncContext: { lfsSkipEnabled: boolean }): 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 await this.createNewWorktreesWithTiming(remoteBranches, worktrees, defaultBranch, phaseTimer);\n await this.pruneOldWorktreesWithTiming(remoteBranches, worktrees, phaseTimer);\n\n if (this.config.updateExistingWorktrees !== false) {\n await this.updateExistingWorktreesWithTiming(worktrees, remoteBranches, phaseTimer);\n }\n\n if (this.config.sparseCheckout) {\n await this.reapplySparseCheckout(worktrees);\n }\n\n await this.finalizeSyncAttempt(phaseTimer);\n }\n\n private async reapplySparseCheckout(worktrees: { path: string; branch: string }[]): 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 worktrees.map((worktree) =>\n limit(async () => {\n try {\n try {\n await fs.access(worktree.path);\n } catch {\n return;\n }\n\n const current = await sparseService.readCurrent(worktree.path);\n if (current !== null && sparseService.patternsEqual(current, desired)) return;\n\n if (sparseService.isNarrowing(current, desired)) {\n const status = await this.gitService.getFullWorktreeStatus(worktree.path, false);\n if (!status.canRemove) {\n this.logger.warn(\n ` - Skipping sparse-checkout narrowing for '${worktree.branch}': ${status.reasons.join(\", \")}.`,\n );\n return;\n }\n }\n\n await sparseService.applyToWorktree(worktree.path, sparseConfig);\n await this.gitService.checkoutHead(worktree.path);\n this.logger.info(` - \u2705 Sparse-checkout updated for '${worktree.branch}'`);\n } catch (error) {\n this.logger.warn(\n ` - \u26A0\uFE0F Failed to update sparse-checkout for '${worktree.branch}': ${getErrorMessage(error)}`,\n );\n }\n }),\n ),\n );\n }\n\n private async fetchLatestRemoteData(phaseTimer: PhaseTimer, syncContext: { lfsSkipEnabled: boolean }): Promise<void> {\n this.logger.info(\"Step 1: Fetching latest data from remote...\");\n phaseTimer.startPhase(\"Phase 1: Fetch\");\n this.emitProgress({ 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.emitProgress({ 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 remoteBranches: string[],\n worktrees: Array<{ path: string; branch: string }>,\n defaultBranch: string,\n phaseTimer: PhaseTimer,\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.emitProgress({ phase: \"create\", message: \"Creating worktrees for new branches\" });\n\n await this.createNewWorktrees(remoteBranches, worktrees, defaultBranch);\n\n const existingBranches = new Set(worktrees.map((w) => w.branch));\n const newBranches = remoteBranches.filter((b) => !existingBranches.has(b) && b !== defaultBranch);\n phaseTimer.setPhaseCount(\"Phase 2: Create\", newBranches.length);\n phaseTimer.endPhase();\n }\n\n private async createNewWorktrees(\n remoteBranches: string[],\n worktrees: Array<{ path: string; branch: string }>,\n defaultBranch: string,\n ): Promise<void> {\n const existingBranches = new Set(worktrees.map((w) => w.branch));\n const newBranches = remoteBranches.filter((b) => !existingBranches.has(b) && b !== defaultBranch);\n\n if (newBranches.length === 0) {\n this.logger.info(\"Step 2: No new branches to create worktrees for.\");\n return;\n }\n\n const reservedPaths = new Map<string, string>();\n for (const w of worktrees) {\n reservedPaths.set(path.resolve(w.path), w.branch);\n }\n\n const plan: Array<{ branchName: string; worktreePath: string }> = [];\n for (const branchName of newBranches) {\n const worktreePath = this.pathResolution.getBranchWorktreePath(this.config.worktreeDir, branchName);\n const resolved = path.resolve(worktreePath);\n const conflict = reservedPaths.get(resolved);\n if (conflict && conflict !== branchName) {\n this.logger.error(\n ` \u274C Skipping '${branchName}': sanitized worktree path '${worktreePath}' collides with existing branch '${conflict}'.`,\n );\n continue;\n }\n reservedPaths.set(resolved, branchName);\n plan.push({ branchName, worktreePath });\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 } catch (error) {\n this.logger.error(` \u274C Failed to create worktree for '${branchName}':`, getErrorMessage(error));\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 remoteBranches: string[],\n worktrees: Array<{ path: string; branch: string }>,\n phaseTimer: PhaseTimer,\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.emitProgress({ phase: \"prune\", message: \"Pruning stale worktrees\" });\n\n await this.pruneOldWorktrees(remoteBranches, worktrees);\n\n const deletedWorktrees = worktrees.filter((w) => !remoteBranches.includes(w.branch));\n phaseTimer.setPhaseCount(\"Phase 3: Prune\", deletedWorktrees.length);\n phaseTimer.endPhase();\n }\n\n private async pruneOldWorktrees(\n remoteBranches: string[],\n worktrees: Array<{ path: string; branch: string }>,\n ): Promise<void> {\n const deletedWorktrees = worktrees.filter((w) => !remoteBranches.includes(w.branch));\n\n if (deletedWorktrees.length > 0) {\n this.logger.info(`Step 3: Checking ${deletedWorktrees.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 deletedWorktrees.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 }\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 return;\n }\n await this.gitService.removeWorktree(worktreePath);\n this.logger.info(` \u2705 Removed worktree for '${branchName}'`);\n } catch (error) {\n this.logger.error(` \u274C Failed to remove worktree for '${branchName}':`, getErrorMessage(error));\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 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 worktrees: { path: string; branch: string }[],\n remoteBranches: string[],\n phaseTimer: PhaseTimer,\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.emitProgress({ phase: \"update\", message: \"Updating existing worktrees\" });\n\n await this.updateExistingWorktrees(worktrees, remoteBranches);\n\n const activeWorktrees = worktrees.filter((w) => remoteBranches.includes(w.branch));\n phaseTimer.setPhaseCount(\"Phase 4: Update\", activeWorktrees.length);\n phaseTimer.endPhase();\n }\n\n private async updateExistingWorktrees(\n worktrees: { path: string; branch: string }[],\n remoteBranches: string[],\n ): 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 const activeWorktrees = worktrees.filter((w) => remoteBranches.includes(w.branch));\n\n type UpdateCheckResult = { action: \"update\" | \"diverged\"; worktree: { path: string; branch: string } } | null;\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 activeWorktrees.map((worktree) =>\n limit(async (): Promise<UpdateCheckResult> => {\n try {\n await fs.access(worktree.path);\n } catch {\n return null;\n }\n\n const hasOp = await this.gitService.hasOperationInProgress(worktree.path);\n if (hasOp) return null;\n\n const isClean = await this.gitService.checkWorktreeStatus(worktree.path);\n if (!isClean) return null;\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 null;\n }\n return { action: \"diverged\", worktree };\n }\n\n const isBehind = await this.gitService.isWorktreeBehind(worktree.path);\n if (!isBehind) return null;\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 null;\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 if (result.value.action === \"update\") {\n worktreesToUpdate.push(result.value.worktree);\n } else {\n divergedWorktrees.push(result.value.worktree);\n }\n } else if (result.status === \"rejected\") {\n this.logger.error(` - Error checking worktree:`, result.reason);\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 } 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);\n } catch (divergedError) {\n this.logger.error(` \u274C Failed to handle diverged branch '${worktree.branch}':`, divergedError);\n throw divergedError;\n }\n } else {\n this.logger.error(` \u274C Failed to update '${worktree.branch}':`, error);\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);\n } catch (error) {\n this.logger.error(` \u274C Failed to handle diverged branch '${worktree.branch}':`, error);\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 // For each directory, check if it's part of any worktree path\n const orphanedDirs: string[] = [];\n for (const dir of regularDirs) {\n // Check if this directory is part of any worktree path\n const isPartOfWorktree = worktreeRelativePaths.some((worktreePath) => {\n // Either the directory IS a worktree or it's a parent of a worktree\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(worktree: { path: string; branch: string }): 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 } 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 } 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\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 // Create .diverged directory inside worktreeDir\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 // Ensure diverged directory exists\n await fs.mkdir(divergedBaseDir, { recursive: true });\n\n // Move the worktree directory; on cross-device errors, fall back to copy+remove\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 // Save metadata about why it was moved\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", "/**\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", "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, GIT_CONSTANTS } from \"../constants\";\nimport { WorktreeError } from \"../errors\";\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, SimpleGitProgressEvent } from \"simple-git\";\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: this.makeProgressHandler() };\n if (blockMs > 0) options.timeout = { block: blockMs };\n return options;\n }\n\n private makeProgressHandler(): (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 // Stage restart on a new operation (e.g. second fetch on the same cached SimpleGit\n // instance): bucket regresses below `last`. Reset so the new run logs from scratch.\n if (bucket < last) {\n last = -1;\n }\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 this.logger.info(` \u21B3 ${event.method} ${event.stage}: ${event.progress}% (${total})`);\n };\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 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 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 await bareGit.raw([\"show-ref\", \"--verify\", \"--quiet\", 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 async createBranch(branchName: string, baseBranch: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n\n await bareGit.raw([\"branch\", branchName, `origin/${baseBranch}`]);\n this.logger.info(`Created branch '${branchName}' from '${baseBranch}'`);\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 needsUpdate(worktreePath: string, cfg: SparseCheckoutConfig): Promise<boolean> {\n const current = await this.readCurrent(worktreePath);\n const desired = this.buildPatterns(cfg);\n if (current === null) return true;\n return !this.patternsEqual(current, desired);\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 { 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 try {\n await fs.access(worktreePath);\n } catch {\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", "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 { 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 \"Repository name from loaded config. If omitted, uses the current repository set via set_current_repository or the only loaded repo.\";\n\nconst PATH_DESCRIBE_SUFFIX = \"Absolute path preferred; relative paths resolve from the server's CWD.\";\n\nconst SERVER_INSTRUCTIONS =\n \"Before running git worktree operations, call `detect_context` to learn the current repo, current branch, sibling repositories under the workspace root, and which capabilities are available. \" +\n \"It walks up to auto-discover sync-worktrees.config.{js,mjs,cjs,ts}, lists sibling worktrees, and reports per-capability {available, reason} so you can tell which tool is gated and why.\";\n\nexport interface ServerSnapshot {\n discovered: DiscoveredRepoContext | null;\n}\n\nexport function buildInstructions(snapshot?: ServerSnapshot): string {\n const d = snapshot?.discovered;\n if (!d || !d.isWorktree || d.kind !== \"managed\") return SERVER_INSTRUCTIONS;\n\n const lines: string[] = [\"Connect-time context (call `detect_context` for live state):\"];\n if (d.kind) lines.push(`- kind: ${d.kind}`);\n if (d.currentWorktreePath) lines.push(`- currentWorktreePath: ${d.currentWorktreePath}`);\n if (d.currentBranch) lines.push(`- currentBranch: ${d.currentBranch}`);\n if (d.configPath) lines.push(`- configPath: ${d.configPath}`);\n\n return `${SERVER_INSTRUCTIONS}\\n\\n${lines.join(\"\\n\")}`;\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 \"Current sync-worktrees workspace context: whether CWD is inside a managed worktree, the current branch, sibling worktrees, sibling repositories, auto-discovered configPath, and per-capability {available, reason}. Returns { isWorktree: false } when CWD is outside any workspace.\",\n mimeType: \"application/json\",\n },\n async (uri) => {\n let discovered: unknown;\n try {\n discovered = await context.detectFromPath(process.cwd());\n } catch (err) {\n discovered = 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(discovered, null, 2),\n },\n ],\n };\n },\n );\n\n server.registerTool(\n \"detect_context\",\n {\n description:\n \"Detect sync-worktrees structure from a filesystem path. Reads .git file, resolves bare repo, discovers sibling worktrees, walks up for a sync-worktrees.config.{js,mjs,cjs,ts}, and lists sibling bare repos under the workspace root. Defaults to CWD. \" +\n \"Use when: bootstrapping from an unknown checkout. \" +\n \"Returns: discovered repo root, bare repo path, all sibling worktrees, sibling repositories, current worktree path, configPath (auto-found), per-capability {available, reason}, notes[].\",\n inputSchema: {\n path: z.string().optional().describe(\"Directory path to inspect. Defaults to the server's CWD.\"),\n includeStatus: z\n .boolean()\n .optional()\n .describe(\n \"If true, enriches each entry in allWorktrees with label, divergence, and staleHint. Adds one git status + rev-list per worktree. Default: false (cheap path).\",\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 all worktrees of a repository with enriched status. \" +\n \"Returns: array of { path, branch, isCurrent, label (clean|dirty|stale|current|unknown), status, divergence (ahead/behind), safeToRemove: { safe, reason }, lastSyncAt, sizeBytes }.\",\n inputSchema: {\n repoName: z.string().optional().describe(REPO_NAME_DESCRIBE),\n includeSize: z\n .boolean()\n .optional()\n .describe(\n \"If true, computes the on-disk size of each worktree (in bytes). Slow on large worktrees. Default: false (sizeBytes returned as 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 \"Get detailed status for one worktree (dirty files, unpushed commits, stashes, upstream gone, operations in progress). \" +\n \"Returns: full status object plus divergence { ahead, behind } and resolved absolute 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(\"If true, includes 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 a worktree for a branch. If the branch exists (local or remote), checks it out; otherwise creates it from baseBranch. Optionally pushes the new branch to origin. \" +\n \"Key params: baseBranch is required only when the branch does not yet exist \u2014 pass it defensively if unsure. push=true only affects newly created branches. \" +\n \"Preconditions: repository must be initialized (auto-runs on first call). \" +\n \"Returns: { success, branchName, worktreePath, created, pushed }.\",\n inputSchema: {\n branchName: z\n .string()\n .describe(\"Branch name. Slashes and special chars are sanitized for the worktree directory name.\"),\n baseBranch: z\n .string()\n .optional()\n .describe(\n \"Base branch for creating a new branch. Required if branchName does not exist locally or remotely; ignored otherwise.\",\n ),\n push: z\n .boolean()\n .optional()\n .describe(\"Push the newly created branch to origin. Ignored if the branch already 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 a worktree. Runs safety checks first: rejects if worktree is dirty, has unpushed commits, has stashes, or has an in-progress git operation (merge/rebase/cherry-pick/revert/bisect). \" +\n \"force=true: runs `git worktree remove --force`, which DELETES uncommitted and untracked files in the worktree directory. Branch ref, stashes, and remote state are preserved. \" +\n \"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(\n \"Skip safety checks and delete uncommitted/untracked files in the worktree directory. Branch ref is preserved. Default: false.\",\n ),\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 \"Full repo-wide synchronization: fetch all, create worktrees for new remote branches, remove worktrees for pruned remote branches (clean only), fast-forward existing worktrees. Emits progress notifications. \" +\n \"Do not use when: you only need to update one worktree \u2014 use update_worktree. Only need to create one \u2014 use create_worktree. \" +\n \"Preconditions: config must be loaded (load_config) and the repository initialized (auto-runs on first call). \" +\n \"Returns: { success, duration } after sync completes.\",\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 match its upstream. No merge commits, no rebasing, aborts if not fast-forwardable. \" +\n \"Do not use when: you want to update every worktree in the repo \u2014 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 a repository: clone as bare repo if missing, create main worktree. Safe to call on already-initialized repos (no-op-ish). Emits progress notifications. \" +\n \"Preconditions: config must be loaded (load_config) so the repo's URL and paths are known. \" +\n \"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 or reload a sync-worktrees JavaScript config file into the server's session. Replaces any previously loaded repositories. \" +\n \"Call this before sync/initialize/create_worktree when using a config-driven workflow. \" +\n \"Returns: { configPath, currentRepository, repositories: [{ name, repoPath, worktreeDir, ... }] }.\",\n inputSchema: {\n configPath: z\n .string()\n .optional()\n .describe(\n \"Path to the config file. If omitted, falls back to the SYNC_WORKTREES_CONFIG env var. Errors if neither is set.\",\n ),\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 the current repository for subsequent tool calls that omit repoName. Session-scoped; not persisted across server restarts. \" +\n \"Preconditions: load_config must have been called so the name is known.\",\n inputSchema: {\n repoName: z.string().describe(\"Repository name as listed in the loaded config's `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 { WorktreeStatusService } from \"../services/worktree-status.service\";\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 { 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\"]>;\n\nconst pathResolution = new PathResolutionService();\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 ensureNotSyncing(ctx: RepositoryContext, repoName?: string): Promise<void> {\n const entry = ctx.getEntry(repoName);\n if (!entry?.service) return;\n if (entry.service.isSyncInProgress()) {\n throw new SyncInProgressError(entry.name);\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 ensureNotSyncing?: boolean;\n } = {},\n): Promise<{ discovered: DiscoveredRepoContext | null; service: RepoService; git: RepoGitService }> {\n const discovered = ctx.getDiscoveredContext(repoName);\n if (options.capability && options.toolName) {\n ensureCapability(discovered, options.capability, options.toolName);\n }\n if (options.ensureNotSyncing) {\n await ensureNotSyncing(ctx, repoName);\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 ensureRepoWorktreePath(\n ctx: RepositoryContext,\n params: WorktreePathParams,\n git: RepoGitService,\n): Promise<string> {\n await ensurePathBelongsToRepo(ctx, params.path, params.repoName, git);\n return path.resolve(params.path);\n}\n\nasync function ensurePathBelongsToRepo(\n ctx: RepositoryContext,\n targetPath: string,\n repoName: string | undefined,\n git: { getWorktrees: () => Promise<Array<{ path: string }>> },\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 git.getWorktrees();\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\nexport async function handleDetectContext(\n ctx: RepositoryContext,\n params: { path?: string; includeStatus?: boolean },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const target = params.path ?? process.cwd();\n const discovered = await ctx.detectFromPath(target);\n\n if (!params.includeStatus || discovered.allWorktrees.length === 0) {\n return formatToolResponse(discovered);\n }\n\n const statusService = new WorktreeStatusService();\n const limit = pLimit(DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\n\n const enriched: DiscoveredWorktree[] = await Promise.all(\n discovered.allWorktrees.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 return formatToolResponse({ ...discovered, allWorktrees: enriched });\n}\n\nexport async function handleListWorktrees(\n ctx: RepositoryContext,\n params: { repoName?: string; includeSize?: boolean },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { discovered, git } = await getReadyService(ctx, params.repoName, {\n capability: \"listWorktrees\",\n toolName: \"list_worktrees\",\n });\n\n let worktrees: Array<{ path: string; branch: string }>;\n try {\n worktrees = await git.getWorktrees();\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 limit = pLimit(DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\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 params.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 formatToolResponse({ worktrees: 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 { git } = await getReadyService(ctx, params.repoName, {\n capability: \"getStatus\",\n toolName: \"get_worktree_status\",\n });\n const resolvedPath = await ensureRepoWorktreePath(ctx, params, 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, push } = params;\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 ensureInitialized: true,\n ensureNotSyncing: true,\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\nexport async function handleRemoveWorktree(\n ctx: RepositoryContext,\n params: { path: string; force?: boolean; repoName?: string },\n _extra?: HandlerExtra,\n): Promise<CallToolResult> {\n const { git } = await getReadyService(ctx, params.repoName, {\n capability: \"removeWorktree\",\n toolName: \"remove_worktree\",\n ensureInitialized: true,\n ensureNotSyncing: true,\n });\n const removedPath = await ensureRepoWorktreePath(ctx, params, 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\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 ensureInitialized: true,\n });\n\n const dispose = attachProgressReporter(service, extra);\n try {\n const start = Date.now();\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 return formatToolResponse({ success: true, duration });\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 { git } = await getReadyService(ctx, params.repoName, {\n capability: \"updateWorktree\",\n toolName: \"update_worktree\",\n ensureInitialized: true,\n ensureNotSyncing: true,\n });\n const worktreePath = await ensureRepoWorktreePath(ctx, params, git);\n\n await git.updateWorktree(params.path);\n ctx.invalidateDiscovered();\n\n return formatToolResponse({\n success: true,\n worktreePath,\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 ensureNotSyncing: true,\n });\n const dispose = attachProgressReporter(service, extra);\n try {\n await service.initialize();\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 } 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, null, 2),\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, null, 2),\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", "simpleGit", "path", "path", "retry", "fs", "path", "resolve", "formatDuration", "fs", "path", "simpleGit", "path", "matcher", "fs", "path", "simpleGit", "simpleGit", "fs", "path", "simpleGit", "stat", "simpleGit", "simpleGit", "resolve", "fs", "path", "stat", "stat", "simpleGit", "path", "pLimit", "resolve", "simpleGit", "pLimit"]
7
7
  }