sync-worktrees 4.1.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +135 -55
  2. package/dist/components/App.d.ts.map +1 -1
  3. package/dist/components/BranchCreationWizard.d.ts.map +1 -1
  4. package/dist/components/OpenEditorWizard.d.ts.map +1 -1
  5. package/dist/components/StatusBar.d.ts +1 -0
  6. package/dist/components/StatusBar.d.ts.map +1 -1
  7. package/dist/components/WorktreeStatusView.d.ts.map +1 -1
  8. package/dist/constants.d.ts +22 -0
  9. package/dist/constants.d.ts.map +1 -1
  10. package/dist/errors/index.d.ts +7 -0
  11. package/dist/errors/index.d.ts.map +1 -1
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +2201 -510
  15. package/dist/index.js.map +4 -4
  16. package/dist/mcp/context.d.ts +1 -1
  17. package/dist/mcp/context.d.ts.map +1 -1
  18. package/dist/mcp/handlers.d.ts +0 -5
  19. package/dist/mcp/handlers.d.ts.map +1 -1
  20. package/dist/mcp/server.d.ts.map +1 -1
  21. package/dist/mcp/worktree-summary.d.ts.map +1 -1
  22. package/dist/mcp-server.js +2117 -519
  23. package/dist/mcp-server.js.map +4 -4
  24. package/dist/services/InteractiveUIService.d.ts.map +1 -1
  25. package/dist/services/clone-sync.service.d.ts +13 -2
  26. package/dist/services/clone-sync.service.d.ts.map +1 -1
  27. package/dist/services/config-loader.service.d.ts +2 -0
  28. package/dist/services/config-loader.service.d.ts.map +1 -1
  29. package/dist/services/git-maintenance.service.d.ts +44 -0
  30. package/dist/services/git-maintenance.service.d.ts.map +1 -0
  31. package/dist/services/git.service.d.ts +19 -1
  32. package/dist/services/git.service.d.ts.map +1 -1
  33. package/dist/services/removal-audit.service.d.ts +19 -0
  34. package/dist/services/removal-audit.service.d.ts.map +1 -0
  35. package/dist/services/sync-outcome.d.ts +1 -1
  36. package/dist/services/sync-outcome.d.ts.map +1 -1
  37. package/dist/services/trash-migration.service.d.ts +18 -0
  38. package/dist/services/trash-migration.service.d.ts.map +1 -0
  39. package/dist/services/trash-reaper.service.d.ts +18 -0
  40. package/dist/services/trash-reaper.service.d.ts.map +1 -0
  41. package/dist/services/trash.service.d.ts +91 -0
  42. package/dist/services/trash.service.d.ts.map +1 -0
  43. package/dist/services/worktree-metadata.service.d.ts +7 -0
  44. package/dist/services/worktree-metadata.service.d.ts.map +1 -1
  45. package/dist/services/worktree-mode-sync-runner.d.ts +11 -1
  46. package/dist/services/worktree-mode-sync-runner.d.ts.map +1 -1
  47. package/dist/services/worktree-status.service.d.ts +5 -2
  48. package/dist/services/worktree-status.service.d.ts.map +1 -1
  49. package/dist/services/worktree-sync.service.d.ts +21 -2
  50. package/dist/services/worktree-sync.service.d.ts.map +1 -1
  51. package/dist/types/index.d.ts +60 -2
  52. package/dist/types/index.d.ts.map +1 -1
  53. package/dist/types/sync-metadata.d.ts +6 -0
  54. package/dist/types/sync-metadata.d.ts.map +1 -1
  55. package/dist/utils/atomic-write.d.ts +2 -0
  56. package/dist/utils/atomic-write.d.ts.map +1 -0
  57. package/dist/utils/file-exists.d.ts +2 -0
  58. package/dist/utils/file-exists.d.ts.map +1 -1
  59. package/dist/utils/filename-timestamp.d.ts +2 -0
  60. package/dist/utils/filename-timestamp.d.ts.map +1 -0
  61. package/dist/utils/lock-path.d.ts +1 -0
  62. package/dist/utils/lock-path.d.ts.map +1 -1
  63. package/dist/utils/quarantine.d.ts +2 -0
  64. package/dist/utils/quarantine.d.ts.map +1 -0
  65. package/package.json +28 -27
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts", "../src/constants.ts", "../src/errors/index.ts", "../src/services/config-loader.service.ts", "../src/utils/branch-filter.ts", "../src/utils/file-exists.ts", "../src/utils/git-url.ts", "../src/utils/path-compare.ts", "../src/utils/repo-mode.ts", "../src/utils/sanitize-name.ts", "../src/services/InteractiveUIService.tsx", "../src/components/App.tsx", "../src/components/StatusBar.tsx", "../src/components/HelpModal.tsx", "../src/components/BranchCreationWizard.tsx", "../src/utils/git-validation.ts", "../src/components/OpenEditorWizard.tsx", "../src/components/WorktreeStatusView.tsx", "../src/utils/lfs-error.ts", "../src/components/LogPanel.tsx", "../src/utils/retry.ts", "../src/utils/timing.ts", "../src/services/clone-sync.service.ts", "../src/utils/git-progress.ts", "../src/services/file-copy.service.ts", "../src/services/branch-created-actions.service.ts", "../src/utils/clone-skip-format.ts", "../src/services/sync-outcome.ts", "../src/services/git.service.ts", "../src/utils/worktree-list-parser.ts", "../src/services/logger.service.ts", "../src/services/sparse-checkout.service.ts", "../src/services/worktree-metadata.service.ts", "../src/services/worktree-status.service.ts", "../src/services/progress-emitter.ts", "../src/services/repo-operation-lock.ts", "../src/utils/lock-path.ts", "../src/services/sync-retry-policy.ts", "../src/services/worktree-mode-sync-runner.ts", "../src/utils/date-filter.ts", "../src/services/path-resolution.service.ts", "../src/services/worktree-sync-planner.ts", "../src/services/worktree-sync.service.ts", "../src/services/hook-execution.service.ts", "../src/utils/shell-escape.ts", "../src/utils/disk-space.ts", "../src/utils/app-events.ts", "../src/utils/cli.ts", "../src/utils/config-generator.ts", "../src/utils/interactive.ts", "../src/utils/signal-handlers.ts"],
4
- "sourcesContent": ["#!/usr/bin/env node\n\nimport { realpathSync } from \"fs\";\nimport * as path from \"path\";\nimport { fileURLToPath } from \"url\";\n\nimport pLimit from \"p-limit\";\n\nimport { DEFAULT_CONFIG } from \"./constants\";\nimport { ConfigFileExistsError, ConfigFileNotFoundError } from \"./errors\";\nimport { ConfigLoaderService } from \"./services/config-loader.service\";\nimport { InteractiveUIService } from \"./services/InteractiveUIService\";\nimport { Logger } from \"./services/logger.service\";\nimport { WorktreeSyncService } from \"./services/worktree-sync.service\";\nimport { CLI_COMMANDS, parseArguments } from \"./utils/cli\";\nimport { formatCloneSkipReason } from \"./utils/clone-skip-format\";\nimport { findConfigInCwd, generateConfigFile, getDefaultConfigPath } from \"./utils/config-generator\";\nimport { fileExists } from \"./utils/file-exists\";\nimport { promptForInitConfig } from \"./utils/interactive\";\nimport { setupSignalHandlers } from \"./utils/signal-handlers\";\n\nimport type { CloneSkipReason } from \"./services/clone-sync.service\";\nimport type { ConfigFile, RepositoryConfig } from \"./types\";\nimport type { CliOptions } from \"./utils/cli\";\n\nexport type {\n SyncWorktreesConfig,\n SyncWorktreesDefaults,\n SyncWorktreesHooksConfig,\n SyncWorktreesParallelismConfig,\n SyncWorktreesRepository,\n SyncWorktreesRepositoryMode,\n SyncWorktreesRetryConfig,\n SyncWorktreesSparseCheckoutConfig,\n SyncWorktreesSparseCheckoutMode,\n} from \"./types\";\n\nconst signalHandle = setupSignalHandlers();\n\nexport async function runMultipleRepositories(\n configFile: ConfigFile,\n repositories: RepositoryConfig[],\n configPath?: string,\n): Promise<void> {\n const services = new Map<string, WorktreeSyncService>();\n const globalLogger = Logger.createDefault();\n\n const runOnce = configFile.defaults?.runOnce ?? false;\n const maxParallel =\n configFile.parallelism?.maxRepositories ??\n configFile.defaults?.parallelism?.maxRepositories ??\n DEFAULT_CONFIG.PARALLELISM.MAX_REPOSITORIES;\n\n const limit = pLimit(maxParallel);\n\n if (runOnce) {\n globalLogger.info(`\\n\uD83D\uDD04 Syncing ${repositories.length} repositories...`);\n\n const initResults = await Promise.allSettled(\n repositories.map((repoConfig) =>\n limit(async () => {\n const repoLogger = Logger.createDefault(repoConfig.name, repoConfig.debug);\n\n repoLogger.info(`\\n\uD83D\uDCE6 Repository: ${repoConfig.name}`);\n repoLogger.info(` URL: ${repoConfig.repoUrl}`);\n repoLogger.info(` Worktrees: ${repoConfig.worktreeDir}`);\n if (repoConfig.bareRepoDir) {\n repoLogger.info(` Bare repo: ${repoConfig.bareRepoDir}`);\n }\n\n if (!repoConfig.logger) {\n repoConfig.logger = repoLogger;\n }\n\n const syncService = new WorktreeSyncService(repoConfig);\n await syncService.initialize();\n return { name: repoConfig.name, service: syncService };\n }),\n ),\n );\n\n const servicesToSync: Array<{ name: string; service: WorktreeSyncService }> = [];\n\n for (const result of initResults) {\n if (result.status === \"fulfilled\") {\n services.set(result.value.name, result.value.service);\n servicesToSync.push(result.value);\n } else {\n globalLogger.error(`\u274C Failed to initialize repository:`, result.reason);\n }\n }\n\n const syncResults = await Promise.allSettled(\n servicesToSync.map(({ name, service }) =>\n limit(async () => {\n try {\n return await service.sync();\n } catch (error) {\n globalLogger.error(`\u274C Error syncing repository '${name}':`, error);\n throw error;\n }\n }),\n ),\n );\n\n const skipsByRepo: Array<{ repo: string; reasons: readonly CloneSkipReason[] }> = [];\n const skippedNames = new Set<string>();\n const outcomeFailedNames = new Set<string>();\n const partialSkipNames = new Set<string>();\n for (let i = 0; i < servicesToSync.length; i++) {\n const { name, service } = servicesToSync[i];\n const reasons = service.getRecordedSkips();\n if (reasons.length > 0) {\n skipsByRepo.push({ repo: name, reasons });\n skippedNames.add(name);\n }\n\n const result = syncResults[i];\n if (result.status === \"fulfilled\") {\n if (!result.value.started) {\n skippedNames.add(name);\n continue;\n }\n\n const counts = result.value.outcome?.counts;\n if (counts) {\n if (counts.failed > 0) {\n outcomeFailedNames.add(name);\n }\n // Per-action skips are informational \u2014 they don't demote a repo that\n // otherwise completed its sync attempt out of `successCount`. A\n // failed repo's headline is its failure, so don't double-label it.\n if (counts.skipped > 0 && !skippedNames.has(name) && !outcomeFailedNames.has(name)) {\n partialSkipNames.add(name);\n }\n }\n }\n }\n\n if (skipsByRepo.length > 0) {\n const skipsRepoWord = skipsByRepo.length === 1 ? \"repo\" : \"repos\";\n globalLogger.warn(`\\n\u26A0\uFE0F Clone-mode skips (${skipsByRepo.length} ${skipsRepoWord}):`);\n for (const { repo, reasons } of skipsByRepo) {\n for (const reason of reasons) {\n globalLogger.warn(` \u2022 ${repo} \u2014 ${formatCloneSkipReason(reason)}`);\n }\n }\n }\n\n const initFailures = initResults.filter(\n (result, index) => result.status === \"rejected\" && !skippedNames.has(repositories[index].name),\n ).length;\n const syncFailures = syncResults.filter(\n (result, index) => result.status === \"rejected\" && !skippedNames.has(servicesToSync[index].name),\n ).length;\n const failedCount = initFailures + syncFailures + outcomeFailedNames.size;\n const skippedCount = skippedNames.size;\n const successCount = syncResults.filter((result, index) => {\n const repoName = servicesToSync[index].name;\n return (\n result.status === \"fulfilled\" &&\n result.value.started &&\n !skippedNames.has(repoName) &&\n !outcomeFailedNames.has(repoName)\n );\n }).length;\n const processedRepoWord = repositories.length === 1 ? \"repo\" : \"repos\";\n const skipSummaryLabel = skippedNames.size === skipsByRepo.length ? \"with clone-mode skips\" : \"skipped\";\n const partialSuffix = partialSkipNames.size > 0 ? ` (${partialSkipNames.size} with partial skips)` : \"\";\n globalLogger.info(\n `\\n\uD83D\uDCCA Processed ${repositories.length} ${processedRepoWord}: ${successCount} synced${partialSuffix}, ${skippedCount} ${skipSummaryLabel}, ${failedCount} failed`,\n );\n\n if (failedCount > 0) {\n process.exitCode = 1;\n }\n } else {\n for (const repoConfig of repositories) {\n const syncService = new WorktreeSyncService(repoConfig);\n services.set(repoConfig.name, syncService);\n }\n\n const uniqueSchedules = [...new Set(repositories.map((r) => r.cronSchedule))];\n const displaySchedule = uniqueSchedules.length === 1 ? uniqueSchedules[0] : undefined;\n const allServices = Array.from(services.values());\n const uiService = new InteractiveUIService(allServices, configPath, displaySchedule, maxParallel);\n signalHandle.register((fast) => uiService.destroy(fast));\n\n void uiService.calculateAndUpdateDiskSpace();\n\n uiService.setupCronJobs();\n\n uiService.addLog(`\uD83D\uDCCB ${repositories.length} repositories configured`);\n\n const cronSchedules = new Map<string, number>();\n for (const repo of repositories) {\n cronSchedules.set(repo.cronSchedule, (cronSchedules.get(repo.cronSchedule) || 0) + 1);\n }\n for (const [schedule, count] of cronSchedules) {\n uiService.addLog(`\u23F0 ${schedule}: ${count} repository(ies)`);\n }\n }\n}\n\nasync function runList(configPath: string, filter?: string): Promise<void> {\n const configLoader = new ConfigLoaderService();\n\n try {\n const { repositories } = await configLoader.buildRepositories(configPath, { filter });\n\n if (filter && repositories.length === 0) {\n console.error(`\u274C No repositories match filter: ${filter}`);\n process.exit(1);\n }\n\n console.log(\"\\n\uD83D\uDCCB Configured repositories:\\n\");\n\n repositories.forEach((repo, index) => {\n console.log(`${index + 1}. ${repo.name}`);\n console.log(` URL: ${repo.repoUrl}`);\n console.log(` Worktrees: ${repo.worktreeDir}`);\n console.log(` Schedule: ${repo.cronSchedule}`);\n console.log(` Run Once: ${repo.runOnce}`);\n if (repo.bareRepoDir) {\n console.log(` Bare repo: ${repo.bareRepoDir}`);\n }\n if (repo.skipLfs) {\n console.log(` Skip LFS: ${repo.skipLfs}`);\n }\n console.log(\"\");\n });\n } catch (error) {\n console.error(\"\u274C Error loading config file:\", (error as Error).message);\n process.exit(1);\n }\n}\n\nasync function runFromConfigFile(configPath: string, runOnceOverride = false): Promise<void> {\n const configLoader = new ConfigLoaderService();\n const { repositories, configFile } = await configLoader.buildRepositories(configPath);\n const effectiveConfigFile = runOnceOverride\n ? { ...configFile, defaults: { ...(configFile.defaults ?? {}), runOnce: true } }\n : configFile;\n await runMultipleRepositories(effectiveConfigFile, repositories, configPath);\n}\n\nasync function resolveConfigOrExit(cliPath: string | undefined): Promise<string> {\n const resolved = cliPath ? path.resolve(cliPath) : await findConfigInCwd();\n if (!resolved) {\n console.error(\n \"\u274C No config file found. Pass --config <path>, run `sync-worktrees init` to create one, or place a sync-worktrees.config.{js,mjs,cjs} in this directory.\",\n );\n process.exit(1);\n }\n return resolved;\n}\n\nfunction exitConfigExists(targetPath: string): never {\n console.error(`\\n\u274C Config file already exists: ${targetPath}`);\n console.error(`\uD83D\uDCA1 Re-run with --force to overwrite.`);\n process.exit(1);\n}\n\nasync function runInit(configPath: string | undefined, force: boolean): Promise<void> {\n const targetPath = configPath ? path.resolve(configPath) : getDefaultConfigPath();\n\n // Preflight before prompts so user isn't asked 5 questions just to fail at write.\n // The atomic `wx` write below is still the source of truth \u2014 it closes the TOCTOU\n // window between this check and the write.\n if (!force && (await fileExists(targetPath))) {\n exitConfigExists(targetPath);\n }\n\n const input = await promptForInitConfig();\n\n try {\n await generateConfigFile(input, targetPath, { overwrite: force });\n } catch (error) {\n if (error instanceof ConfigFileExistsError) {\n exitConfigExists(error.configPath);\n }\n throw error;\n }\n\n const displayPath = path.relative(process.cwd(), targetPath) || targetPath;\n console.log(`\\n\u2705 Configuration saved to: ${targetPath}`);\n console.log(`\\n\uD83D\uDCA1 Next: sync-worktrees --config ${displayPath}`);\n}\n\nasync function runSync(options: Extract<CliOptions, { command: typeof CLI_COMMANDS.RUN }>): Promise<void> {\n const configPath = await resolveConfigOrExit(options.config);\n const displayPath = path.relative(process.cwd(), configPath) || configPath;\n console.log(`\uD83D\uDCC4 Using config: ${displayPath}`);\n\n try {\n await runFromConfigFile(configPath, options.runOnce);\n } catch (error) {\n if (error instanceof ConfigFileNotFoundError) {\n console.error(`\\n\u274C Config file not found: ${error.configPath}`);\n console.error(`\uD83D\uDCA1 Run 'sync-worktrees init --config ${displayPath}' to create one.`);\n process.exit(1);\n }\n console.error(\"\u274C Error loading config file:\", (error as Error).message);\n process.exit(1);\n }\n}\n\nasync function main(): Promise<void> {\n const options = parseArguments();\n\n switch (options.command) {\n case CLI_COMMANDS.INIT:\n return runInit(options.config, options.force);\n case CLI_COMMANDS.LIST: {\n const configPath = await resolveConfigOrExit(options.config);\n return runList(configPath, options.filter);\n }\n case CLI_COMMANDS.RUN:\n return runSync(options);\n default: {\n const _exhaustive: never = options;\n throw new Error(`Unhandled command: ${JSON.stringify(_exhaustive)}`);\n }\n }\n}\n\nfunction isMainEntrypoint(): boolean {\n const entry = process.argv[1];\n if (!entry) return false;\n // realpathSync resolves symlinks on the argv side so the guard works for\n // npm/pnpm global-bin shims and macOS /tmp -> /private/tmp; import.meta.url\n // is already the resolved path by default.\n try {\n return realpathSync(entry) === fileURLToPath(import.meta.url);\n } catch {\n return false;\n }\n}\n\nif (isMainEntrypoint()) {\n main().catch((error) => {\n console.error(\"\u274C Unhandled error:\", error);\n process.exit(1);\n });\n}\n", "export const GIT_CONSTANTS = {\n REMOTE_PREFIX: \"origin/\",\n REMOTE_NAME: \"origin\",\n HEAD_REF: \"/HEAD\",\n DEFAULT_BRANCH: \"main\",\n COMMON_DEFAULT_BRANCHES: [\"main\", \"master\", \"develop\", \"trunk\"],\n BARE_DIR_NAME: \".bare\",\n DIVERGED_DIR_NAME: \".diverged\",\n LFS_HEADER: \"version https://git-lfs.github.com/spec/\",\n SUBMODULE_STATUS_ADDED: \"+\",\n SUBMODULE_STATUS_REMOVED: \"-\",\n GITDIR_PREFIX: \"gitdir:\",\n GIT_CHECK_IGNORE_NO_MATCH: \"exit code: 1\",\n REFS: {\n HEADS: \"refs/heads/\",\n REMOTES: \"refs/remotes/origin\",\n REMOTES_ORIGIN: \"refs/remotes/origin/*\",\n },\n FETCH_CONFIG: \"+refs/heads/*:refs/remotes/origin/*\",\n PROGRESS_BUCKET_PERCENT: 25,\n} as const;\n\nexport const GIT_OPERATIONS = {\n MERGE_HEAD: \"MERGE_HEAD\",\n CHERRY_PICK_HEAD: \"CHERRY_PICK_HEAD\",\n REVERT_HEAD: \"REVERT_HEAD\",\n BISECT_LOG: \"BISECT_LOG\",\n REBASE_MERGE: \"rebase-merge\",\n REBASE_APPLY: \"rebase-apply\",\n} as const;\n\nexport const DEFAULT_CONFIG = {\n CRON_SCHEDULE: \"0 * * * *\",\n RETRY: {\n MAX_ATTEMPTS: 3,\n MAX_LFS_RETRIES: 2,\n INITIAL_DELAY_MS: 1000,\n MAX_DELAY_MS: 30000,\n BACKOFF_MULTIPLIER: 2,\n JITTER_MS: 500,\n },\n PARALLELISM: {\n MAX_REPOSITORIES: 2,\n MAX_WORKTREE_CREATION: 1,\n MAX_WORKTREE_UPDATES: 3,\n MAX_WORKTREE_REMOVAL: 3,\n MAX_STATUS_CHECKS: 20,\n MAX_BRANCH_FETCHES: 3,\n MAX_SAFE_TOTAL_CONCURRENT_OPS: 100,\n },\n UPDATE_EXISTING_WORKTREES: true,\n HOOK_TIMEOUT_MS: 60_000,\n FETCH_TIMEOUT_MS: 300_000,\n CLONE_TIMEOUT_MS: 900_000,\n LOCK_STALE_MS: 600_000,\n LOCK_UPDATE_MS: 30_000,\n} as const;\n\nexport const ERROR_MESSAGES = {\n GIT_NOT_INITIALIZED: \"Git service not initialized. Call initialize() first.\",\n ALREADY_EXISTS: \"already exists\",\n ALREADY_REGISTERED: \"already registered worktree\",\n FAST_FORWARD_FAILED: [\n \"Not possible to fast-forward\",\n \"fatal: Not possible to fast-forward, aborting\",\n \"cannot fast-forward\",\n ],\n NO_UPSTREAM: [\n \"fatal: no upstream configured\",\n \"no upstream configured for branch\",\n \"fatal: ambiguous argument\",\n \"unknown revision or path\",\n ],\n LFS_ERROR: [\"smudge filter lfs failed\", \"git-lfs\", \"LFS\"],\n EXDEV: \"EXDEV\",\n} as const;\n\nexport const TEST_TIMEOUT = {\n DEFAULT: 10000,\n E2E: 60000,\n} as const;\n\nexport const ENV_CONSTANTS = {\n GIT_LFS_SKIP_SMUDGE: \"GIT_LFS_SKIP_SMUDGE\",\n GIT_ATTR_SOURCE: \"GIT_ATTR_SOURCE\",\n NODE_ENV_TEST: \"test\",\n} as const;\n\nexport const PATH_CONSTANTS = {\n GIT_DIR: \".git\",\n README: \"README\",\n CLONE_INIT_MARKER: \".sync-worktrees-clone-init\",\n} as const;\n\nexport const CONFIG_FILE_NAMES = [\n \"sync-worktrees.config.js\",\n \"sync-worktrees.config.mjs\",\n \"sync-worktrees.config.cjs\",\n] as const;\n\nexport const METADATA_CONSTANTS = {\n MAX_HISTORY_ENTRIES: 10,\n METADATA_FILENAME: \"sync-metadata.json\",\n WORKTREE_METADATA_PATH: \".git/worktrees\",\n DIVERGED_INFO_FILE: \".diverged-info.json\",\n DIVERGED_REASON: \"diverged-history-with-changes\",\n ACTION_CREATED: \"created\",\n ACTION_UPDATED: \"updated\",\n ACTION_FETCHED: \"fetched\",\n} as const;\n\nexport const TERMINAL_CONSTANTS = {\n ENV_OVERRIDE: \"SYNC_WORKTREES_TERMINAL\",\n ENV_FALLBACK: \"TERMINAL\",\n LINUX_CANDIDATES: [\"gnome-terminal\", \"konsole\", \"alacritty\", \"kitty\", \"xterm\"],\n} as const;\n\nexport const HOOK_CONSTANTS = {\n ENV_PREFIX: \"SYNC_WORKTREES_\",\n ENV_VARS: {\n BRANCH_NAME: \"SYNC_WORKTREES_BRANCH_NAME\",\n WORKTREE_PATH: \"SYNC_WORKTREES_WORKTREE_PATH\",\n REPO_NAME: \"SYNC_WORKTREES_REPO_NAME\",\n BASE_BRANCH: \"SYNC_WORKTREES_BASE_BRANCH\",\n REPO_URL: \"SYNC_WORKTREES_REPO_URL\",\n },\n PLACEHOLDERS: {\n BRANCH_NAME: \"{BRANCH_NAME}\",\n WORKTREE_PATH: \"{WORKTREE_PATH}\",\n REPO_NAME: \"{REPO_NAME}\",\n BASE_BRANCH: \"{BASE_BRANCH}\",\n REPO_URL: \"{REPO_URL}\",\n },\n} as const;\n", "import { ERROR_MESSAGES } from \"../constants\";\n\nexport class SyncWorktreesError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly cause?: Error,\n ) {\n super(message);\n this.name = this.constructor.name;\n Object.setPrototypeOf(this, new.target.prototype);\n if (cause && cause.stack) {\n this.stack = `${this.stack}\\nCaused by: ${cause.stack}`;\n }\n }\n}\n\nexport class GitError extends SyncWorktreesError {\n constructor(message: string, code: string, cause?: Error) {\n super(message, `GIT_${code}`, cause);\n }\n}\n\nexport class GitNotInitializedError extends GitError {\n constructor() {\n super(ERROR_MESSAGES.GIT_NOT_INITIALIZED, \"NOT_INITIALIZED\");\n }\n}\n\nexport class GitOperationError extends GitError {\n constructor(operation: string, details: string, cause?: Error) {\n super(`Git operation '${operation}' failed: ${details}`, \"OPERATION_FAILED\", cause);\n }\n}\n\nexport class FastForwardError extends GitError {\n constructor(\n public readonly branchName: string,\n cause?: Error,\n ) {\n super(`Cannot fast-forward branch '${branchName}'`, \"FAST_FORWARD_FAILED\", cause);\n }\n}\n\nexport class WorktreeError extends SyncWorktreesError {\n constructor(message: string, code: string, cause?: Error) {\n super(message, `WORKTREE_${code}`, cause);\n }\n}\n\nexport class WorktreeAlreadyExistsError extends WorktreeError {\n constructor(\n public readonly path: string,\n public readonly branchName: string,\n ) {\n super(`Worktree already exists at '${path}' for branch '${branchName}'`, \"ALREADY_EXISTS\");\n }\n}\n\nexport class WorktreeNotCleanError extends WorktreeError {\n constructor(\n public readonly path: string,\n public readonly reasons: string[],\n ) {\n super(`Worktree at '${path}' is not clean: ${reasons.join(\", \")}`, \"NOT_CLEAN\");\n }\n}\n\nexport class ConfigError extends SyncWorktreesError {\n constructor(message: string, code: string, cause?: Error) {\n super(message, `CONFIG_${code}`, cause);\n }\n}\n\nexport class ConfigValidationError extends ConfigError {\n constructor(\n public readonly field: string,\n public readonly reason: string,\n ) {\n super(`Invalid configuration for '${field}': ${reason}`, \"VALIDATION_FAILED\");\n }\n}\n\nexport class ConfigFileNotFoundError extends ConfigError {\n constructor(public readonly configPath: string) {\n super(`Config file not found: ${configPath}`, \"FILE_NOT_FOUND\");\n }\n}\n\nexport class ConfigFileExistsError extends ConfigError {\n constructor(public readonly configPath: string) {\n super(`Config file already exists: ${configPath}`, \"FILE_EXISTS\");\n }\n}\n\nexport class PathResolutionError extends SyncWorktreesError {\n constructor(\n public readonly path: string,\n public readonly reason: string,\n ) {\n super(`Path resolution failed for '${path}': ${reason}`, \"PATH_RESOLUTION_FAILED\");\n }\n}\n\nexport class LfsError extends GitError {\n constructor(message: string, cause?: Error) {\n super(`LFS operation failed: ${message}`, \"LFS_ERROR\", cause);\n }\n}\n\nexport function isLfsError(error: Error | string): boolean {\n const message = typeof error === \"string\" ? error : error.message;\n return ERROR_MESSAGES.LFS_ERROR.some((pattern) => message.includes(pattern));\n}\n\nexport function isFastForwardError(error: Error | string): boolean {\n const message = typeof error === \"string\" ? error : error.message;\n return ERROR_MESSAGES.FAST_FORWARD_FAILED.some((pattern) => message.includes(pattern));\n}\n\nexport function isNoUpstreamError(error: Error | string): boolean {\n const message = typeof error === \"string\" ? error : error.message;\n return ERROR_MESSAGES.NO_UPSTREAM.some((pattern) => message.includes(pattern));\n}\n", "import * as path from \"path\";\nimport { pathToFileURL } from \"url\";\n\nimport * as cron from \"node-cron\";\n\nimport { CONFIG_FILE_NAMES, DEFAULT_CONFIG } from \"../constants\";\nimport { ConfigFileNotFoundError, ConfigValidationError, SyncWorktreesError } from \"../errors\";\nimport { matchesPattern } from \"../utils/branch-filter\";\nimport { fileExists } from \"../utils/file-exists\";\nimport { getDefaultBareRepoDir } from \"../utils/git-url\";\nimport { normalizePathForCompare } from \"../utils/path-compare\";\nimport { REPOSITORY_MODES, isRepositoryMode } from \"../utils/repo-mode\";\nimport { sanitizeNameForPath } from \"../utils/sanitize-name\";\n\nimport type { Config, ConfigFile, RepositoryConfig, RepositoryMode } from \"../types\";\n\nconst CLONE_MODE_CONFLICTING_FIELDS = [\n \"branchInclude\",\n \"branchExclude\",\n \"branchMaxAge\",\n \"updateExistingWorktrees\",\n \"bareRepoDir\",\n] as const satisfies readonly (keyof RepositoryConfig)[];\n\nexport class ConfigLoaderService {\n async findConfigUpward(startDir: string): Promise<string | null> {\n let current = path.resolve(startDir);\n const root = path.parse(current).root;\n\n while (true) {\n for (const name of CONFIG_FILE_NAMES) {\n const candidate = path.join(current, name);\n if (await fileExists(candidate)) {\n return candidate;\n }\n }\n if (current === root) return null;\n const parent = path.dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n }\n\n async loadConfigFile(configPath: string): Promise<ConfigFile> {\n const absolutePath = path.resolve(configPath);\n\n if (!(await fileExists(absolutePath))) {\n throw new ConfigFileNotFoundError(absolutePath);\n }\n\n try {\n const fileUrl = pathToFileURL(absolutePath);\n fileUrl.searchParams.set(\"t\", Date.now().toString());\n const configModule = await import(fileUrl.href);\n const config = configModule.default;\n\n if (!config) {\n throw new Error(\"Config file must use 'export default' syntax\");\n }\n\n this.validateConfigFile(config);\n\n return config;\n } catch (error) {\n if (error instanceof SyncWorktreesError) {\n throw error;\n }\n throw new Error(`Failed to load config file: ${(error as Error).message}`);\n }\n }\n\n private validateConfigFile(config: unknown): asserts config is ConfigFile {\n if (!config || typeof config !== \"object\") {\n throw new Error(\"Config file must export an object\");\n }\n\n const configObj = config as Record<string, unknown>;\n\n if (!Array.isArray(configObj.repositories)) {\n throw new Error(\"Config file must have a 'repositories' array\");\n }\n\n if (configObj.repositories.length === 0) {\n throw new Error(\"Config file must have at least one repository\");\n }\n\n const seenNames = new Set<string>();\n\n configObj.repositories.forEach((repo: unknown, index: number) => {\n if (!repo || typeof repo !== \"object\") {\n throw new Error(`Repository at index ${index} must be an object`);\n }\n\n const repoObj = repo as Record<string, unknown>;\n\n if (!repoObj.name || typeof repoObj.name !== \"string\") {\n throw new Error(`Repository at index ${index} must have a 'name' property`);\n }\n\n if (seenNames.has(repoObj.name)) {\n throw new Error(`Duplicate repository name: ${repoObj.name}`);\n }\n seenNames.add(repoObj.name);\n\n if (!repoObj.repoUrl || typeof repoObj.repoUrl !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' must have a 'repoUrl' property`);\n }\n\n if (!this.isValidGitUrl(repoObj.repoUrl)) {\n throw new Error(\n `Repository '${repoObj.name}' has invalid 'repoUrl': '${repoObj.repoUrl}'. ` +\n `Expected an HTTP(S), SSH, Git protocol URL, or a local/file path (file://, absolute filesystem path)`,\n );\n }\n\n if (!repoObj.worktreeDir || typeof repoObj.worktreeDir !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' must have a 'worktreeDir' property`);\n }\n\n if (repoObj.bareRepoDir !== undefined && typeof repoObj.bareRepoDir !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'bareRepoDir' property`);\n }\n\n if (repoObj.cronSchedule !== undefined && typeof repoObj.cronSchedule !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'cronSchedule' property`);\n }\n\n if (typeof repoObj.cronSchedule === \"string\" && !cron.validate(repoObj.cronSchedule)) {\n throw new Error(`Repository '${repoObj.name}' has invalid cron expression: '${repoObj.cronSchedule}'`);\n }\n\n if (repoObj.runOnce !== undefined && typeof repoObj.runOnce !== \"boolean\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'runOnce' property`);\n }\n\n if (repoObj.debug !== undefined && typeof repoObj.debug !== \"boolean\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'debug' property`);\n }\n\n if (repoObj.retry !== undefined) {\n this.validateRetryConfig(repoObj.retry, `Repository '${repoObj.name}' retry config`);\n }\n\n if (repoObj.filesToCopyOnBranchCreate !== undefined) {\n this.validateFilesToCopyConfig(repoObj.filesToCopyOnBranchCreate, `Repository '${repoObj.name}'`);\n }\n\n if (repoObj.hooks !== undefined) {\n this.validateHooksConfig(repoObj.hooks, `Repository '${repoObj.name}'`);\n }\n\n if (repoObj.sparseCheckout !== undefined) {\n this.validateSparseCheckoutConfig(repoObj.sparseCheckout, `Repository '${repoObj.name}'`);\n }\n\n this.validateDepth(repoObj.depth, `Repository '${repoObj.name}' depth`);\n this.validateRepositoryMode(repoObj, configObj.defaults as Record<string, unknown> | undefined);\n });\n\n this.warnOnDuplicateRepoUrls(configObj.repositories as Array<Record<string, unknown>>);\n\n if (configObj.defaults) {\n if (typeof configObj.defaults !== \"object\") {\n throw new Error(\"'defaults' must be an object\");\n }\n\n const defaults = configObj.defaults as Record<string, unknown>;\n\n if (defaults.cronSchedule !== undefined && typeof defaults.cronSchedule !== \"string\") {\n throw new Error(\"Invalid 'cronSchedule' in defaults\");\n }\n if (typeof defaults.cronSchedule === \"string\" && !cron.validate(defaults.cronSchedule)) {\n throw new Error(`Invalid cron expression in defaults: '${defaults.cronSchedule}'`);\n }\n if (defaults.runOnce !== undefined && typeof defaults.runOnce !== \"boolean\") {\n throw new Error(\"Invalid 'runOnce' in defaults\");\n }\n if (defaults.debug !== undefined && typeof defaults.debug !== \"boolean\") {\n throw new Error(\"Invalid 'debug' in defaults\");\n }\n if (defaults.retry !== undefined && typeof defaults.retry !== \"object\") {\n throw new Error(\"Invalid 'retry' in defaults\");\n }\n if (defaults.retry !== undefined) {\n this.validateRetryConfig(defaults.retry, \"defaults retry config\");\n }\n if (defaults.filesToCopyOnBranchCreate !== undefined) {\n this.validateFilesToCopyConfig(defaults.filesToCopyOnBranchCreate, \"defaults\");\n }\n\n if (defaults.hooks !== undefined) {\n this.validateHooksConfig(defaults.hooks, \"defaults\");\n }\n\n if (defaults.sparseCheckout !== undefined) {\n this.validateSparseCheckoutConfig(defaults.sparseCheckout, \"defaults\");\n }\n\n this.validateDepth(defaults.depth, \"defaults.depth\");\n\n if (defaults.mode !== undefined && !isRepositoryMode(defaults.mode)) {\n throw new ConfigValidationError(\"defaults.mode\", \"must be 'clone' or 'worktree'\");\n }\n\n if (defaults.branch !== undefined && (typeof defaults.branch !== \"string\" || defaults.branch.trim() === \"\")) {\n throw new ConfigValidationError(\"defaults.branch\", \"must be a non-empty string\");\n }\n }\n\n if (configObj.retry !== undefined) {\n this.validateRetryConfig(configObj.retry, \"retry config\");\n }\n\n if (configObj.parallelism !== undefined) {\n this.validateParallelismConfig(configObj.parallelism, \"global\");\n }\n\n if (configObj.defaults && typeof configObj.defaults === \"object\") {\n const defaults = configObj.defaults as Record<string, unknown>;\n if (defaults.parallelism !== undefined) {\n this.validateParallelismConfig(defaults.parallelism, \"defaults\");\n }\n }\n }\n\n private validateDepth(value: unknown, field: string): void {\n if (value === undefined) return;\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value <= 0) {\n throw new ConfigValidationError(field, \"must be a positive safe integer\");\n }\n }\n\n private validateRetryConfig(value: unknown, context: string): void {\n if (typeof value !== \"object\" || value === null) {\n throw new Error(context === \"retry config\" ? \"'retry' must be an object\" : `Invalid 'retry' in ${context}`);\n }\n\n const retry = value as Record<string, unknown>;\n\n if (retry.maxAttempts !== undefined) {\n if (retry.maxAttempts !== \"unlimited\" && (typeof retry.maxAttempts !== \"number\" || retry.maxAttempts < 1)) {\n throw new Error(\"Invalid 'maxAttempts' in retry config. Must be 'unlimited' or a positive number\");\n }\n }\n\n if (retry.maxLfsRetries !== undefined) {\n if (typeof retry.maxLfsRetries !== \"number\" || retry.maxLfsRetries < 0) {\n throw new Error(\"Invalid 'maxLfsRetries' in retry config. Must be a non-negative number\");\n }\n }\n\n if (retry.initialDelayMs !== undefined && (typeof retry.initialDelayMs !== \"number\" || retry.initialDelayMs < 0)) {\n throw new Error(\"Invalid 'initialDelayMs' in retry config\");\n }\n\n if (retry.maxDelayMs !== undefined && (typeof retry.maxDelayMs !== \"number\" || retry.maxDelayMs < 0)) {\n throw new Error(\"Invalid 'maxDelayMs' in retry config\");\n }\n\n if (\n retry.backoffMultiplier !== undefined &&\n (typeof retry.backoffMultiplier !== \"number\" || retry.backoffMultiplier < 1)\n ) {\n throw new Error(\"Invalid 'backoffMultiplier' in retry config\");\n }\n\n if (retry.jitterMs !== undefined && (typeof retry.jitterMs !== \"number\" || retry.jitterMs < 0)) {\n throw new Error(\"Invalid 'jitterMs' in retry config\");\n }\n\n const initialDelay = (retry.initialDelayMs as number) ?? DEFAULT_CONFIG.RETRY.INITIAL_DELAY_MS;\n const maxDelay = (retry.maxDelayMs as number) ?? DEFAULT_CONFIG.RETRY.MAX_DELAY_MS;\n if (initialDelay > maxDelay) {\n throw new Error(\n `Invalid retry config: 'initialDelayMs' (${initialDelay}) must not exceed 'maxDelayMs' (${maxDelay})`,\n );\n }\n }\n\n private validateParallelismConfig(parallelism: unknown, context: string): void {\n if (typeof parallelism !== \"object\" || parallelism === null) {\n throw new Error(`'parallelism' in ${context} must be an object`);\n }\n\n const config = parallelism as Record<string, unknown>;\n\n const positiveIntFields = [\n \"maxRepositories\",\n \"maxWorktreeCreation\",\n \"maxWorktreeUpdates\",\n \"maxWorktreeRemoval\",\n \"maxStatusChecks\",\n \"maxBranchFetches\",\n ] as const;\n\n for (const field of positiveIntFields) {\n const value = config[field];\n if (value !== undefined && (typeof value !== \"number\" || value < 1)) {\n throw new Error(`Invalid '${field}' in ${context} parallelism config. Must be a positive number`);\n }\n }\n\n const maxRepos = (config.maxRepositories as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_REPOSITORIES;\n const maxCreation = (config.maxWorktreeCreation as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_CREATION;\n const maxUpdates = (config.maxWorktreeUpdates as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_UPDATES;\n const maxRemoval = (config.maxWorktreeRemoval as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_REMOVAL;\n const maxStatus = (config.maxStatusChecks as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n\n const maxPerRepoOps = maxCreation + maxUpdates + maxRemoval + maxStatus;\n const totalMaxConcurrent = maxRepos * maxPerRepoOps;\n\n if (totalMaxConcurrent > DEFAULT_CONFIG.PARALLELISM.MAX_SAFE_TOTAL_CONCURRENT_OPS) {\n const safeMaxRepos = Math.floor(DEFAULT_CONFIG.PARALLELISM.MAX_SAFE_TOTAL_CONCURRENT_OPS / maxPerRepoOps);\n throw new Error(\n `Total concurrent operations (${totalMaxConcurrent}) exceeds safe limit (${DEFAULT_CONFIG.PARALLELISM.MAX_SAFE_TOTAL_CONCURRENT_OPS}). ` +\n `With current per-repository limits (creation: ${maxCreation}, updates: ${maxUpdates}, removal: ${maxRemoval}, status: ${maxStatus}), ` +\n `maximum safe maxRepositories is ${safeMaxRepos}. ` +\n `Consider reducing maxRepositories or lowering per-operation limits.`,\n );\n }\n }\n\n private validateFilesToCopyConfig(filesToCopy: unknown, context: string): void {\n if (!Array.isArray(filesToCopy)) {\n throw new Error(`'filesToCopyOnBranchCreate' in ${context} must be an array`);\n }\n\n for (let i = 0; i < filesToCopy.length; i++) {\n const pattern = filesToCopy[i];\n if (typeof pattern !== \"string\" || pattern.trim() === \"\") {\n throw new Error(\n `'filesToCopyOnBranchCreate' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n }\n\n private validateSparseCheckoutConfig(value: unknown, context: string): void {\n if (typeof value !== \"object\" || value === null) {\n throw new Error(`'sparseCheckout' in ${context} must be an object`);\n }\n\n const cfg = value as Record<string, unknown>;\n\n if (!Array.isArray(cfg.include)) {\n throw new Error(`'sparseCheckout.include' in ${context} must be an array`);\n }\n if (cfg.include.length === 0) {\n throw new Error(`'sparseCheckout.include' in ${context} must contain at least one pattern`);\n }\n for (let i = 0; i < cfg.include.length; i++) {\n const p = cfg.include[i];\n if (typeof p !== \"string\" || p.trim() === \"\") {\n throw new Error(\n `'sparseCheckout.include' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n\n if (cfg.exclude !== undefined) {\n if (!Array.isArray(cfg.exclude)) {\n throw new Error(`'sparseCheckout.exclude' in ${context} must be an array`);\n }\n for (let i = 0; i < cfg.exclude.length; i++) {\n const p = cfg.exclude[i];\n if (typeof p !== \"string\" || p.trim() === \"\") {\n throw new Error(\n `'sparseCheckout.exclude' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n }\n\n if (cfg.mode !== undefined && cfg.mode !== \"cone\" && cfg.mode !== \"no-cone\") {\n throw new Error(`'sparseCheckout.mode' in ${context} must be 'cone' or 'no-cone'`);\n }\n }\n\n private warnOnDuplicateRepoUrls(repositories: Array<Record<string, unknown>>): void {\n const seen = new Map<string, string[]>();\n for (const repo of repositories) {\n const url = typeof repo.repoUrl === \"string\" ? repo.repoUrl : null;\n const name = typeof repo.name === \"string\" ? repo.name : null;\n if (!url || !name) continue;\n const list = seen.get(url) ?? [];\n list.push(name);\n seen.set(url, list);\n }\n for (const [url, names] of seen) {\n if (names.length > 1) {\n console.warn(\n `[sync-worktrees] repoUrl '${url}' appears in multiple entries (${names.join(\", \")}). ` +\n `Pin 'bareRepoDir' on duplicate entries to make config reorder-proof.`,\n );\n }\n }\n }\n\n private validateRepositoryMode(\n repoObj: Record<string, unknown>,\n defaults: Record<string, unknown> | undefined,\n ): void {\n const repoName = repoObj.name as string;\n const repoMode = repoObj.mode;\n\n if (repoMode !== undefined && !isRepositoryMode(repoMode)) {\n throw new ConfigValidationError(`Repository '${repoName}' mode`, \"must be 'clone' or 'worktree'\");\n }\n\n if (\n repoObj.branch !== undefined &&\n (typeof repoObj.branch !== \"string\" || (repoObj.branch as string).trim() === \"\")\n ) {\n throw new ConfigValidationError(`Repository '${repoName}' branch`, \"must be a non-empty string\");\n }\n\n const effectiveMode = (repoMode as RepositoryMode | undefined) ?? (defaults?.mode as RepositoryMode | undefined);\n if (effectiveMode !== REPOSITORY_MODES.CLONE) {\n const depthFromRepo = repoObj.depth;\n const depthFromDefaults = defaults?.depth;\n if (depthFromRepo !== undefined || depthFromDefaults !== undefined) {\n const source = depthFromRepo !== undefined ? \"repository\" : \"defaults\";\n throw new ConfigValidationError(\n `Repository '${repoName}' depth`,\n `only supported when mode is 'clone' (set on ${source})`,\n );\n }\n\n const branchFromRepo = repoObj.branch;\n const branchFromDefaults = defaults?.branch;\n if (branchFromRepo !== undefined || branchFromDefaults !== undefined) {\n const source = branchFromRepo !== undefined ? \"repository\" : \"defaults\";\n throw new ConfigValidationError(\n `Repository '${repoName}' branch`,\n `only supported when mode is 'clone' (set on ${source})`,\n );\n }\n\n return;\n }\n\n for (const field of CLONE_MODE_CONFLICTING_FIELDS) {\n const fromRepo = repoObj[field];\n const fromDefaults = defaults?.[field];\n const present = fromRepo !== undefined || fromDefaults !== undefined;\n if (present) {\n const source = fromRepo !== undefined ? \"repository\" : \"defaults\";\n throw new ConfigValidationError(\n `Repository '${repoName}' ${field}`,\n `not supported when mode is 'clone' (set on ${source})`,\n );\n }\n }\n }\n\n private validateHooksConfig(hooks: unknown, context: string): void {\n if (typeof hooks !== \"object\" || hooks === null) {\n throw new Error(`'hooks' in ${context} must be an object`);\n }\n\n const hooksObj = hooks as Record<string, unknown>;\n\n if (hooksObj.onBranchCreated !== undefined) {\n if (!Array.isArray(hooksObj.onBranchCreated)) {\n throw new Error(`'hooks.onBranchCreated' in ${context} must be an array`);\n }\n\n for (let i = 0; i < hooksObj.onBranchCreated.length; i++) {\n const command = hooksObj.onBranchCreated[i];\n if (typeof command !== \"string\" || command.trim() === \"\") {\n throw new Error(\n `'hooks.onBranchCreated' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n }\n }\n\n resolveRepositoryConfig(\n repo: RepositoryConfig,\n defaults?: Partial<Config>,\n configDir?: string,\n globalRetry?: Config[\"retry\"],\n allRepositories?: RepositoryConfig[],\n ): RepositoryConfig {\n const mode: RepositoryMode = repo.mode ?? defaults?.mode ?? REPOSITORY_MODES.WORKTREE;\n\n const resolved: RepositoryConfig = {\n name: repo.name,\n repoUrl: repo.repoUrl,\n worktreeDir: this.resolvePath(repo.worktreeDir, configDir),\n cronSchedule: repo.cronSchedule ?? defaults?.cronSchedule ?? DEFAULT_CONFIG.CRON_SCHEDULE,\n runOnce: repo.runOnce ?? defaults?.runOnce ?? false,\n debug: repo.debug ?? defaults?.debug,\n mode,\n };\n\n if (configDir) {\n resolved.__configFileDir = configDir;\n }\n\n if (mode === REPOSITORY_MODES.CLONE) {\n if (repo.branch ?? defaults?.branch) {\n resolved.branch = repo.branch ?? defaults?.branch;\n }\n if (repo.depth !== undefined || defaults?.depth !== undefined) {\n resolved.depth = repo.depth ?? defaults?.depth;\n }\n } else {\n if (repo.bareRepoDir) {\n resolved.bareRepoDir = this.resolvePath(repo.bareRepoDir, configDir);\n } else if (allRepositories && this.isDuplicateRepoUrl(repo, allRepositories, defaults)) {\n const sanitized = sanitizeNameForPath(repo.name, `Repository '${repo.name}' name`);\n resolved.bareRepoDir = this.resolvePath(`.bare/${sanitized}`, configDir);\n } else {\n resolved.bareRepoDir = this.resolvePath(getDefaultBareRepoDir(repo.repoUrl), configDir);\n }\n\n if (repo.branchMaxAge || defaults?.branchMaxAge) {\n resolved.branchMaxAge = repo.branchMaxAge ?? defaults?.branchMaxAge;\n }\n\n if (repo.branchInclude || defaults?.branchInclude) {\n resolved.branchInclude = repo.branchInclude ?? defaults?.branchInclude;\n }\n\n if (repo.branchExclude || defaults?.branchExclude) {\n resolved.branchExclude = repo.branchExclude ?? defaults?.branchExclude;\n }\n\n if (repo.updateExistingWorktrees !== undefined || defaults?.updateExistingWorktrees !== undefined) {\n resolved.updateExistingWorktrees = repo.updateExistingWorktrees ?? defaults?.updateExistingWorktrees ?? true;\n }\n }\n\n if (repo.skipLfs !== undefined || defaults?.skipLfs !== undefined) {\n resolved.skipLfs = repo.skipLfs ?? defaults?.skipLfs ?? false;\n }\n\n if (repo.retry || defaults?.retry || globalRetry) {\n resolved.retry = {\n ...(globalRetry || {}),\n ...(defaults?.retry || {}),\n ...(repo.retry || {}),\n };\n }\n\n if (repo.parallelism || defaults?.parallelism) {\n resolved.parallelism = {\n ...(defaults?.parallelism || {}),\n ...(repo.parallelism || {}),\n };\n }\n\n if (repo.filesToCopyOnBranchCreate || defaults?.filesToCopyOnBranchCreate) {\n const files = repo.filesToCopyOnBranchCreate ?? defaults?.filesToCopyOnBranchCreate;\n resolved.filesToCopyOnBranchCreate = files?.map((f) => this.resolvePath(f, configDir));\n }\n\n if (repo.hooks || defaults?.hooks) {\n resolved.hooks = {\n ...(defaults?.hooks || {}),\n ...(repo.hooks || {}),\n };\n }\n\n const sparse = repo.sparseCheckout ?? defaults?.sparseCheckout;\n if (sparse) {\n resolved.sparseCheckout = sparse;\n }\n\n return resolved;\n }\n\n private isDuplicateRepoUrl(repo: RepositoryConfig, all: RepositoryConfig[], defaults?: Partial<Config>): boolean {\n const firstIndex = all.findIndex((r) => {\n const mode = r.mode ?? defaults?.mode ?? REPOSITORY_MODES.WORKTREE;\n return r.repoUrl === repo.repoUrl && mode === REPOSITORY_MODES.WORKTREE;\n });\n const myIndex = all.indexOf(repo);\n return firstIndex !== -1 && myIndex !== -1 && myIndex !== firstIndex;\n }\n\n detectBareRepoDirCollisions(repositories: RepositoryConfig[]): void {\n const seen = new Map<string, { name: string; displayPath: string }>();\n for (const repo of repositories) {\n if (!repo.bareRepoDir) continue;\n const key = normalizePathForCompare(repo.bareRepoDir);\n const displayPath = path.resolve(repo.bareRepoDir);\n const existing = seen.get(key);\n if (existing && existing.name !== repo.name) {\n throw new Error(\n `Repositories '${existing.name}' and '${repo.name}' resolve to the same bareRepoDir '${displayPath}'. ` +\n `Set distinct 'bareRepoDir' values for duplicate repoUrl entries.`,\n );\n }\n seen.set(key, { name: repo.name, displayPath });\n }\n }\n\n private isValidGitUrl(url: string): boolean {\n // HTTP(S) URLs\n if (/^https?:\\/\\/.+/.test(url)) return true;\n // SSH URLs (git@host:path or ssh://...)\n if (/^(ssh:\\/\\/|git@).+/.test(url)) return true;\n // Git protocol\n if (/^git:\\/\\/.+/.test(url)) return true;\n // Local file paths (absolute)\n if (/^(file:\\/\\/|\\/|[A-Za-z]:\\\\)/.test(url)) return true;\n return false;\n }\n\n private resolvePath(inputPath: string, baseDir?: string): string {\n if (path.isAbsolute(inputPath)) {\n return inputPath;\n }\n\n return path.resolve(baseDir || process.cwd(), inputPath);\n }\n\n filterRepositories(repositories: RepositoryConfig[], filter?: string): RepositoryConfig[] {\n if (!filter) {\n return repositories;\n }\n\n const patterns = filter.split(\",\").map((p) => p.trim());\n\n return repositories.filter((repo) => {\n return patterns.some((pattern) => matchesPattern(repo.name, pattern));\n });\n }\n\n async buildRepositories(\n configPath: string,\n overrides?: { filter?: string },\n ): Promise<{ repositories: RepositoryConfig[]; configFile: ConfigFile; configDir: string }> {\n const configFile = await this.loadConfigFile(configPath);\n const configDir = path.dirname(path.resolve(configPath));\n\n let repositories = configFile.repositories.map((repo) =>\n this.resolveRepositoryConfig(repo, configFile.defaults, configDir, configFile.retry, configFile.repositories),\n );\n\n this.detectBareRepoDirCollisions(repositories);\n\n if (overrides?.filter) {\n repositories = this.filterRepositories(repositories, overrides.filter);\n }\n\n return { repositories, configFile, configDir };\n }\n}\n", "export function matchesPattern(name: string, pattern: string): boolean {\n if (pattern.includes(\"*\")) {\n const escapedPattern = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n const regex = new RegExp(\"^\" + escapedPattern + \"$\");\n return regex.test(name);\n }\n return name === pattern;\n}\n\nexport function filterBranchesByName(branches: string[], include?: string[], exclude?: string[]): string[] {\n let result = branches;\n\n if (include && include.length > 0) {\n result = result.filter((branch) => include.some((pattern) => matchesPattern(branch, pattern)));\n }\n\n if (exclude && exclude.length > 0) {\n result = result.filter((branch) => !exclude.some((pattern) => matchesPattern(branch, pattern)));\n }\n\n return result;\n}\n", "import * as fs from \"fs/promises\";\n\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await fs.access(path);\n return true;\n } catch {\n return false;\n }\n}\n", "/**\n * Extracts the repository name from a Git URL\n * @param gitUrl - The Git URL (HTTPS or SSH format)\n * @returns The repository name without .git extension\n * @throws Error if the URL format is invalid\n */\nexport function extractRepoNameFromUrl(gitUrl: string): string {\n // Remove trailing spaces\n const url = gitUrl.trim();\n\n // Handle SSH format: git@github.com:user/repo.git or ssh://git@domain/path/repo.git\n const sshMatch = url.match(/^git@[^:]+:(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (sshMatch) {\n return sshMatch[1];\n }\n\n // Handle SSH URL format: ssh://git@domain.com/path/repo.git\n const sshUrlMatch = url.match(/^ssh:\\/\\/[^/]+\\/(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (sshUrlMatch) {\n return sshUrlMatch[1];\n }\n\n // Handle HTTPS format: https://github.com/user/repo.git\n const httpsMatch = url.match(/^https?:\\/\\/[^/]+\\/(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (httpsMatch) {\n return httpsMatch[1];\n }\n\n // Handle file:// URLs for local repositories\n const fileMatch = url.match(/^file:\\/\\/(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (fileMatch) {\n return fileMatch[1];\n }\n\n throw new Error(`Invalid Git URL format: ${gitUrl}`);\n}\n\n/**\n * Generates the default bare repository directory path\n * @param repoUrl - The Git repository URL\n * @param baseDir - The base directory for bare repos (default: .bare)\n * @returns The path to the bare repository\n */\nexport function getDefaultBareRepoDir(repoUrl: string, baseDir: string = \".bare\"): string {\n const repoName = extractRepoNameFromUrl(repoUrl);\n return `${baseDir}/${repoName}`;\n}\n\n/**\n * Normalizes a Git remote URL for equivalence comparison only: trims, lowercases\n * a leading `scheme://host`, and strips a trailing slash and a single trailing\n * `.git`. Intentionally does NOT equate scp-style (git@host:path) with https://\n * forms \u2014 those are left distinct. Use only to decide whether two URLs point at\n * the same remote, never as a canonical URL for git operations.\n */\nexport function normalizeRepoUrlForComparison(url: string): string {\n let normalized = url.trim();\n // Only forge-style remotes (http(s)/ssh/git:// and scp git@host:path) treat a\n // trailing \".git\" as optional/equivalent. For file:// and bare local paths,\n // \"foo.git\" and \"foo\" can be genuinely different directories, so we must NOT\n // strip \".git\" there or we'd hide a real origin mismatch.\n const isForgeUrl = /^(https?|ssh|git):\\/\\//i.test(normalized) || /^[\\w.-]+@[^/]+:/.test(normalized);\n normalized = normalized.replace(/^[a-zA-Z][a-zA-Z0-9+.-]*:\\/\\/[^/]+/, (prefix) => prefix.toLowerCase());\n normalized = normalized.replace(/\\/+$/, \"\");\n if (isForgeUrl) {\n normalized = normalized.replace(/\\.git$/, \"\");\n }\n return normalized;\n}\n", "import * as path from \"path\";\n\n// darwin default filesystem (APFS default, HFS+) is case-insensitive.\n// Case-sensitive APFS volumes on macOS exist but are rare; those will see false-positive\n// matches for case-differing paths. Acceptable tradeoff vs breaking the common case.\nconst CASE_INSENSITIVE_PLATFORMS = new Set([\"darwin\"]);\n\nexport function isCaseInsensitiveFs(platform: NodeJS.Platform = process.platform): boolean {\n return CASE_INSENSITIVE_PLATFORMS.has(platform);\n}\n\n/**\n * Normalizes a path for equality comparison.\n *\n * The `platform` argument is a case-sensitivity hint only: it controls whether\n * the resolved path is lower-cased before comparison.\n */\nexport function normalizePathForCompare(p: string, platform: NodeJS.Platform = process.platform): string {\n const resolved = path.resolve(p);\n return isCaseInsensitiveFs(platform) ? resolved.toLowerCase() : resolved;\n}\n\n/**\n * Compares two paths for equality after host-path resolution and platform-aware case folding.\n *\n * The `platform` argument is a case-sensitivity hint only. See\n * {@link normalizePathForCompare} for the caveats about path.resolve semantics.\n */\nexport function pathsEqual(a: string, b: string, platform: NodeJS.Platform = process.platform): boolean {\n return normalizePathForCompare(a, platform) === normalizePathForCompare(b, platform);\n}\n", "import type { Config, RepositoryMode } from \"../types\";\n\nexport const REPOSITORY_MODES = {\n CLONE: \"clone\",\n WORKTREE: \"worktree\",\n} as const satisfies Record<string, RepositoryMode>;\n\nexport function isRepositoryMode(value: unknown): value is RepositoryMode {\n return value === REPOSITORY_MODES.CLONE || value === REPOSITORY_MODES.WORKTREE;\n}\n\nexport function resolveMode(cfg: Pick<Config, \"mode\">): RepositoryMode {\n return cfg.mode ?? REPOSITORY_MODES.WORKTREE;\n}\n", "import { ConfigValidationError } from \"../errors\";\n\nconst WINDOWS_RESERVED = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;\n// eslint-disable-next-line no-control-regex -- Windows reserves \\x00\u2013\\x1f for path validation; intentional\nconst ILLEGAL_CHARS = /[<>:\"|?*\\x00-\\x1f]/g;\n\nexport function sanitizeNameForPath(name: string, fieldContext = \"name\"): string {\n if (!name || typeof name !== \"string\") {\n throw new ConfigValidationError(fieldContext, \"must be a non-empty string\");\n }\n\n let cleaned = name.trim();\n cleaned = cleaned.replace(/[/\\\\]/g, \"-\");\n cleaned = cleaned.replace(/^\\.+/, \"\");\n cleaned = cleaned.replace(ILLEGAL_CHARS, \"_\");\n cleaned = cleaned.replace(/[. ]+$/, \"\");\n\n if (cleaned.length === 0) {\n throw new ConfigValidationError(fieldContext, `'${name}' produces an empty path segment after sanitization`);\n }\n\n if (WINDOWS_RESERVED.test(cleaned)) {\n throw new ConfigValidationError(fieldContext, `'${cleaned}' is a reserved name on Windows`);\n }\n\n return cleaned;\n}\n", "import React from \"react\";\nimport * as path from \"path\";\nimport { render, Instance } from \"ink\";\nimport * as cron from \"node-cron\";\nimport pLimit from \"p-limit\";\nimport { spawn, spawnSync } from \"child_process\";\nimport { existsSync } from \"fs\";\nimport App from \"../components/App\";\nimport { DEFAULT_CONFIG } from \"../constants\";\nimport { WorktreeSyncService } from \"./worktree-sync.service\";\nimport { ConfigLoaderService } from \"./config-loader.service\";\nimport { BranchCreatedActionsService } from \"./branch-created-actions.service\";\nimport { HookExecutionService } from \"./hook-execution.service\";\nimport { PathResolutionService } from \"./path-resolution.service\";\nimport { Logger, LogOutputFn, LogLevel } from \"./logger.service\";\nimport { formatCloneSkipReason } from \"../utils/clone-skip-format\";\nimport { calculateSyncDiskSpace } from \"../utils/disk-space\";\nimport { getDefaultBareRepoDir } from \"../utils/git-url\";\nimport { AppEventEmitter } from \"../utils/app-events\";\nimport { resolveMode } from \"../utils/repo-mode\";\nimport { shellEscape } from \"../utils/shell-escape\";\nimport * as fs from \"fs/promises\";\nimport { calculateDirectorySize, formatBytes } from \"../utils/disk-space\";\nimport { formatDuration } from \"../utils/timing\";\nimport { GIT_CONSTANTS, METADATA_CONSTANTS, TERMINAL_CONSTANTS } from \"../constants\";\nimport type {\n RepositoryConfig,\n HookContext,\n WorktreeStatusEntry,\n DivergedDirectoryInfo,\n RepositoryListEntry,\n RepositoryDiskUsage,\n} from \"../types\";\n\nconst WAIT_SYNC_FAST_TIMEOUT_MS = 2000;\nconst WAIT_SYNC_DEFAULT_TIMEOUT_MS = 30000;\n\nexport class InteractiveUIService {\n private app: Instance | null = null;\n private syncServices: WorktreeSyncService[];\n private configPath?: string;\n private cronSchedule?: string;\n private cronJobs: cron.ScheduledTask[] = [];\n private repositoryCount: number;\n private logBuffer: Array<{ message: string; level: \"info\" | \"warn\" | \"error\" }> = [];\n private uiReady = false;\n private hookExecutionService = new HookExecutionService();\n private branchCreatedActions = new BranchCreatedActionsService();\n private pathResolution = new PathResolutionService();\n private limit: ReturnType<typeof pLimit>;\n private maxProgressLines: number;\n private reloadInProgress = false;\n private isDestroyed = false;\n private events: AppEventEmitter;\n private ownsEvents: boolean;\n private unsubscribeCallbacks: Array<() => void> = [];\n private progressUnsubscribers: Array<() => void> = [];\n\n constructor(\n syncServices: WorktreeSyncService[],\n configPath?: string,\n cronSchedule?: string,\n maxParallel?: number,\n events?: AppEventEmitter,\n ) {\n this.ownsEvents = events === undefined;\n this.events = events ?? new AppEventEmitter();\n if (syncServices.length === 0) {\n throw new Error(\"InteractiveUIService requires at least one WorktreeSyncService\");\n }\n\n this.syncServices = syncServices;\n this.configPath = configPath;\n this.cronSchedule = cronSchedule;\n this.repositoryCount = syncServices.length;\n this.maxProgressLines = Math.max(1, maxParallel ?? DEFAULT_CONFIG.PARALLELISM.MAX_REPOSITORIES);\n this.limit = pLimit(this.maxProgressLines);\n\n this.startBufferFlushCheck();\n this.renderUI();\n this.subscribeToServiceProgress();\n this.injectLoggersIntoServices();\n\n // Add initial log after a short delay to verify the pipeline works\n setTimeout(() => {\n this.addLog(\"\uD83D\uDE80 sync-worktrees UI initialized\", \"info\");\n }, 100);\n }\n\n public getEvents(): AppEventEmitter {\n return this.events;\n }\n\n private startBufferFlushCheck(): void {\n const unsubscribe = this.events.on(\"uiReady\", () => {\n this.uiReady = true;\n this.flushLogBuffer();\n unsubscribe();\n const index = this.unsubscribeCallbacks.indexOf(unsubscribe);\n if (index !== -1) this.unsubscribeCallbacks.splice(index, 1);\n });\n this.unsubscribeCallbacks.push(unsubscribe);\n }\n\n private createOutputFn(): LogOutputFn {\n return (message: string, level: LogLevel) => {\n const uiLevel = level === \"debug\" ? \"info\" : level;\n this.addLog(message, uiLevel);\n };\n }\n\n private injectLoggersIntoServices(): void {\n const outputFn = this.createOutputFn();\n for (const service of this.syncServices) {\n const config = service.config as RepositoryConfig;\n service.updateLogger(\n new Logger({\n repoName: config.name,\n debug: config.debug,\n outputFn,\n }),\n );\n }\n }\n\n private subscribeToServiceProgress(): void {\n for (const unsubscribe of this.progressUnsubscribers) {\n unsubscribe();\n }\n this.progressUnsubscribers = this.syncServices.map((service, index) => {\n const repoName = this.getRepoName(index);\n if (!service.onProgress) return () => undefined;\n return service.onProgress((event) => {\n if (this.isDestroyed) return;\n this.events.emit(\"setSyncProgress\", {\n repo: repoName,\n phase: event.phase,\n message: event.message,\n progress: event.progress,\n processed: event.processed,\n total: event.total,\n });\n });\n });\n }\n\n public addLog(message: string, level: \"info\" | \"warn\" | \"error\" = \"info\"): void {\n if (this.isDestroyed) return;\n if (this.uiReady) {\n this.events.emit(\"addLog\", { message, level });\n } else {\n this.logBuffer.push({ message, level });\n }\n }\n\n private flushLogBuffer(): void {\n for (const log of this.logBuffer) {\n this.events.emit(\"addLog\", { message: log.message, level: log.level });\n }\n this.logBuffer = [];\n }\n\n public setupCronJobs(): void {\n const scheduleGroups = new Map<string, WorktreeSyncService[]>();\n\n for (const service of this.syncServices) {\n if (service.config.runOnce) continue;\n const schedule = service.config.cronSchedule || this.cronSchedule;\n if (!schedule) continue;\n\n if (!scheduleGroups.has(schedule)) {\n scheduleGroups.set(schedule, []);\n }\n scheduleGroups.get(schedule)!.push(service);\n }\n\n for (const [schedule, services] of scheduleGroups) {\n const task = cron.schedule(schedule, async () => {\n await this.runSyncCycle(services, { logErrors: false });\n });\n this.cronJobs.push(task);\n }\n }\n\n private cancelCronJobs(): void {\n for (const job of this.cronJobs) {\n job.stop();\n }\n this.cronJobs = [];\n }\n\n public registerCronJob(job: cron.ScheduledTask): void {\n this.cronJobs.push(job);\n }\n\n private renderUI(): void {\n if (this.app) {\n this.app.unmount();\n }\n\n this.app = render(\n <App\n events={this.events}\n repositoryCount={this.repositoryCount}\n cronSchedule={this.cronSchedule}\n maxProgressLines={this.maxProgressLines}\n onManualSync={() => this.handleManualSync()}\n onReload={() => this.handleReload()}\n onQuit={() => this.handleQuit()}\n getRepositoryList={() => this.getRepositoryList()}\n getBranchesForRepo={(index: number) => this.getBranchesForRepo(index)}\n getDefaultBranchForRepo={(index: number) => this.getDefaultBranchForRepo(index)}\n fetchForRepo={(index: number) => this.fetchForRepo(index)}\n createAndPushBranch={(repoIndex: number, baseBranch: string, branchName: string) =>\n this.createAndPushBranch(repoIndex, baseBranch, branchName)\n }\n getWorktreesForRepo={(index: number) => this.getWorktreesForRepo(index)}\n getWorktreeStatusForRepo={(index: number) => this.getWorktreeStatusForRepo(index)}\n getRepositoryDiskUsage={(index: number) => this.getRepositoryDiskUsage(index)}\n getDivergedDirectoriesForRepo={(index: number) => this.getDivergedDirectoriesForRepo(index)}\n deleteDivergedDirectory={(repoIndex: number, name: string) =>\n this.deleteDivergedDirectory(repoIndex, name)\n }\n openEditorInWorktree={(path: string) => this.openEditorInWorktree(path)}\n openTerminalInWorktree={(repoIndex: number, path: string, branchName: string) =>\n this.openTerminalInWorktree(repoIndex, path, branchName)\n }\n copyBranchFiles={(repoIndex: number, baseBranch: string, targetBranch: string) =>\n this.copyBranchFiles(repoIndex, baseBranch, targetBranch)\n }\n createWorktreeForBranch={(repoIndex: number, branchName: string) =>\n this.createWorktreeForBranch(repoIndex, branchName)\n }\n executeOnBranchCreatedHooks={(repoIndex: number, context: HookContext) =>\n this.executeOnBranchCreatedHooks(repoIndex, context)\n }\n />,\n );\n }\n\n private async handleManualSync(): Promise<void> {\n await this.triggerInitialSync();\n }\n\n public async triggerInitialSync(): Promise<void> {\n await this.runSyncCycle(this.syncServices, { logErrors: true });\n }\n\n private async handleReload(): Promise<void> {\n if (this.reloadInProgress) {\n return;\n }\n this.reloadInProgress = true;\n let cronJobsCancelled = false;\n try {\n if (!this.configPath) {\n this.setStatus(\"idle\");\n return;\n }\n\n await this.waitForInProgressSyncs();\n\n this.addLog(\"Reloading configuration...\");\n this.setStatus(\"syncing\");\n\n // Validate and load new config BEFORE canceling old cron jobs\n // to prevent a window with no cron running on validation failure\n const configLoader = new ConfigLoaderService();\n const { repositories } = await configLoader.buildRepositories(this.configPath);\n\n const initResults = await Promise.allSettled(\n repositories.map((repoConfig) =>\n this.limit(async () => {\n const service = new WorktreeSyncService(repoConfig);\n await service.initialize();\n return {\n service,\n clonePhaseSkips: service.getRecordedSkips().map((reason) => ({\n repo: repoConfig.name || repoConfig.repoUrl,\n reason: formatCloneSkipReason(reason),\n })),\n };\n }),\n ),\n );\n\n const newServices: WorktreeSyncService[] = [];\n const initClonePhaseSkips: Array<{ repo: string; reason: string }> = [];\n for (const result of initResults) {\n if (result.status === \"fulfilled\") {\n newServices.push(result.value.service);\n initClonePhaseSkips.push(...result.value.clonePhaseSkips);\n } else {\n this.addLog(`Failed to initialize repository: ${result.reason}`, \"error\");\n }\n }\n\n if (newServices.length === 0) {\n throw new Error(\"No repositories could be initialized from the configuration\");\n }\n\n // Cancel old cron jobs only after new config is validated and services initialized\n this.cancelCronJobs();\n cronJobsCancelled = true;\n\n this.syncServices = newServices;\n this.repositoryCount = this.syncServices.length;\n this.subscribeToServiceProgress();\n this.injectLoggersIntoServices();\n\n const uniqueSchedules = [...new Set(this.syncServices.map((s) => s.config.cronSchedule))];\n this.cronSchedule = uniqueSchedules.length === 1 ? uniqueSchedules[0] : undefined;\n\n this.setupCronJobs();\n\n this.events.emit(\"updateRepositoryCount\", this.repositoryCount);\n this.events.emit(\"updateCronSchedule\", this.cronSchedule);\n\n const {\n failures,\n skipped,\n clonePhaseSkips: syncClonePhaseSkips,\n attempted,\n } = await this.runSyncServices(this.syncServices);\n const clonePhaseSkips = [...initClonePhaseSkips, ...syncClonePhaseSkips];\n await this.recordSyncOutcome({ failures, skipped, attempted });\n this.setStatus(\"idle\");\n\n for (const skip of skipped) {\n this.addLog(`Sync skipped for '${skip.repo}': ${skip.reason}`, \"warn\");\n }\n for (const skip of clonePhaseSkips) {\n this.addLog(`Clone-mode skip for '${skip.repo}': ${skip.reason}`, \"warn\");\n }\n if (clonePhaseSkips.length > 0) {\n this.addLog(`\u26A0\uFE0F ${clonePhaseSkips.length} clone-mode skip(s) during reload`, \"warn\");\n }\n if (failures.length > 0) {\n for (const failure of failures) {\n this.addLog(`Failed to sync repository '${failure.repo}': ${failure.error}`, \"error\");\n }\n this.addLog(`Reload completed with ${failures.length} repository failure(s)`, \"warn\");\n }\n } catch (error) {\n this.addLog(`Reload failed: ${(error as Error).message}`, \"error\");\n if (cronJobsCancelled) {\n this.setupCronJobs();\n }\n this.setStatus(\"idle\");\n } finally {\n this.reloadInProgress = false;\n }\n }\n\n private async handleQuit(): Promise<void> {\n await this.destroy();\n process.exit(0);\n }\n\n private async waitForInProgressSyncs(timeoutMs: number = WAIT_SYNC_DEFAULT_TIMEOUT_MS): Promise<void> {\n const inProgressServices = this.syncServices.filter((s) => s.isSyncInProgress());\n\n if (inProgressServices.length === 0) {\n return;\n }\n\n this.addLog(`Waiting for ${inProgressServices.length} in-progress sync(s) to finish...`, \"info\");\n\n const syncChecks = inProgressServices.map(async (service) => {\n const checkInterval = 500;\n const startTime = Date.now();\n\n while (service.isSyncInProgress()) {\n if (Date.now() - startTime > timeoutMs) {\n throw new Error(\"Timeout waiting for sync operations to complete\");\n }\n await new Promise((resolve) => setTimeout(resolve, checkInterval));\n }\n });\n\n try {\n await Promise.all(syncChecks);\n } catch {\n this.addLog(\n `Warning: Timeout waiting for sync operations to complete after ${formatDuration(timeoutMs)}. Proceeding with potential data loss risk.`,\n \"warn\",\n );\n }\n }\n\n public updateLastSyncTime(): void {\n if (this.isDestroyed) return;\n this.events.emit(\"updateLastSyncTime\");\n }\n\n public setStatus(status: \"idle\" | \"syncing\"): void {\n if (this.isDestroyed) return;\n this.events.emit(\"setStatus\", status);\n if (status === \"idle\") {\n this.events.emit(\"setSyncProgress\", null);\n }\n }\n\n public setDiskSpace(diskSpace: string): void {\n if (this.isDestroyed) return;\n this.events.emit(\"setDiskSpace\", diskSpace);\n }\n\n public async calculateAndUpdateDiskSpace(): Promise<void> {\n try {\n const bareRepoDirs = this.syncServices.map(\n (service) => service.config.bareRepoDir || getDefaultBareRepoDir(service.config.repoUrl),\n );\n const worktreeDirs = this.syncServices.map((service) => service.config.worktreeDir);\n\n const diskSpace = await calculateSyncDiskSpace(bareRepoDirs, worktreeDirs);\n this.setDiskSpace(diskSpace);\n } catch (error) {\n this.addLog(`Failed to calculate disk space: ${error instanceof Error ? error.message : String(error)}`, \"error\");\n this.setDiskSpace(\"N/A\");\n }\n }\n\n public getRepositoryList(): RepositoryListEntry[] {\n return this.syncServices.map((service, index) => ({\n index,\n name: this.getRepoName(index),\n repoUrl: service.config.repoUrl,\n }));\n }\n\n private getRepoName(index: number): string {\n const service = this.syncServices[index];\n return (service.config as RepositoryConfig).name || `repo-${index}`;\n }\n\n public async getRepositoryDiskUsage(repoIndex: number): Promise<RepositoryDiskUsage> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n const config = service.config;\n const repoName = this.getRepoName(repoIndex);\n const mode = resolveMode(config);\n const sizeTargets: Array<{ kind: \"bare\" | \"worktree\"; path: string }> = [\n ...(mode === \"worktree\"\n ? [{ kind: \"bare\" as const, path: config.bareRepoDir || getDefaultBareRepoDir(config.repoUrl) }]\n : []),\n { kind: \"worktree\", path: config.worktreeDir },\n ];\n\n let bareSizeBytes = 0;\n let worktreeSizeBytes = 0;\n const errors: string[] = [];\n\n for (const target of sizeTargets) {\n try {\n const size = await calculateDirectorySize(target.path);\n if (target.kind === \"bare\") {\n bareSizeBytes = size;\n } else {\n worktreeSizeBytes = size;\n }\n } catch (error) {\n errors.push(`${target.path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n const sizeBytes = bareSizeBytes + worktreeSizeBytes;\n const failedAllPaths = errors.length === sizeTargets.length;\n\n return {\n repoIndex,\n repoName,\n sizeBytes: failedAllPaths ? null : sizeBytes,\n sizeFormatted: failedAllPaths ? \"N/A\" : formatBytes(sizeBytes),\n bareSizeBytes,\n worktreeSizeBytes,\n error: errors.length > 0 ? errors.join(\"; \") : undefined,\n };\n }\n\n public async getBranchesForRepo(repoIndex: number): Promise<string[]> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n if (!service.isInitialized()) {\n return [];\n }\n const gitService = service.getGitService();\n return gitService.getRemoteBranches();\n }\n\n public getDefaultBranchForRepo(repoIndex: number): string {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n const gitService = service.getGitService();\n return gitService.getDefaultBranch();\n }\n\n public async fetchForRepo(repoIndex: number): Promise<void> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n if (!service.isInitialized()) {\n await service.initialize();\n }\n const gitService = service.getGitService();\n await gitService.fetchAll();\n }\n\n public async createAndPushBranch(\n repoIndex: number,\n baseBranch: string,\n branchName: string,\n ): Promise<{ success: boolean; finalName: string; error?: string }> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n return { success: false, finalName: branchName, error: `Invalid repository index: ${repoIndex}` };\n }\n\n const service = this.syncServices[repoIndex];\n const gitService = service.getGitService();\n\n const maxAttempts = 10;\n let finalName = branchName;\n let suffix = 0;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n await gitService.createBranch(finalName, baseBranch);\n await gitService.pushBranch(finalName);\n return { success: true, finalName };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (errorMessage.includes(\"already exists\")) {\n suffix++;\n finalName = `${branchName}-${suffix}`;\n continue;\n }\n return { success: false, finalName: branchName, error: errorMessage };\n }\n }\n\n return { success: false, finalName: branchName, error: `Failed to create branch after ${maxAttempts} attempts` };\n }\n\n public async getWorktreesForRepo(repoIndex: number): Promise<Array<{ path: string; branch: string }>> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n return this.getWorktreesFromService(service);\n }\n\n public async getWorktreeStatusForRepo(repoIndex: number): Promise<WorktreeStatusEntry[]> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n const gitService = service.getGitService();\n const worktrees = await this.getWorktreesFromService(service);\n\n const results = await Promise.allSettled(\n worktrees.map(async (wt) => {\n const status = await gitService.getFullWorktreeStatus(wt.path, true);\n return { branch: wt.branch, path: wt.path, status };\n }),\n );\n\n return results\n .filter((r): r is PromiseFulfilledResult<WorktreeStatusEntry> => r.status === \"fulfilled\")\n .map((r) => r.value);\n }\n\n private async getWorktreesFromService(service: WorktreeSyncService): Promise<Array<{ path: string; branch: string }>> {\n const worktreeProvider = service as WorktreeSyncService & {\n getWorktrees?: () => Promise<Array<{ path: string; branch: string }>>;\n };\n if (typeof worktreeProvider.getWorktrees === \"function\") {\n return worktreeProvider.getWorktrees();\n }\n return service.getGitService().getWorktrees();\n }\n\n public async getDivergedDirectoriesForRepo(repoIndex: number): Promise<DivergedDirectoryInfo[]> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n return [];\n }\n\n const service = this.syncServices[repoIndex];\n const worktreeDir = service.config.worktreeDir;\n const divergedDir = path.join(worktreeDir, GIT_CONSTANTS.DIVERGED_DIR_NAME);\n\n let dirEntries: import(\"fs\").Dirent[];\n try {\n dirEntries = await fs.readdir(divergedDir, { withFileTypes: true, encoding: \"utf-8\" });\n } catch {\n return [];\n }\n\n const subdirs = dirEntries.filter((e) => e.isDirectory());\n\n const results = await Promise.allSettled(\n subdirs.map(async (entry) => {\n const fullPath = path.join(divergedDir, entry.name);\n const infoFilePath = path.join(fullPath, METADATA_CONSTANTS.DIVERGED_INFO_FILE);\n\n let originalBranch = entry.name;\n let divergedAt = \"\";\n\n try {\n const infoContent = await fs.readFile(infoFilePath, \"utf-8\");\n const info = JSON.parse(infoContent);\n if (typeof info.originalBranch === \"string\") originalBranch = info.originalBranch;\n if (typeof info.divergedAt === \"string\") divergedAt = info.divergedAt;\n } catch {\n // Extract date and branch from directory name pattern: YYYY-MM-DD-branch-suffix\n const match = entry.name.match(/^(\\d{4}-\\d{2}-\\d{2})-(.+?)(?:-[a-f0-9]+)?$/);\n if (match) {\n divergedAt = match[1];\n originalBranch = match[2];\n }\n }\n\n const sizeBytes = await calculateDirectorySize(fullPath).catch(() => 0);\n const sizeFormatted = formatBytes(sizeBytes);\n\n return {\n name: entry.name,\n path: fullPath,\n originalBranch,\n divergedAt,\n sizeBytes,\n sizeFormatted,\n };\n }),\n );\n\n return results\n .filter((r): r is PromiseFulfilledResult<DivergedDirectoryInfo> => r.status === \"fulfilled\")\n .map((r) => r.value)\n .sort((a, b) => b.divergedAt.localeCompare(a.divergedAt));\n }\n\n public async deleteDivergedDirectory(repoIndex: number, name: string): Promise<void> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n const worktreeDir = service.config.worktreeDir;\n const divergedBase = path.resolve(worktreeDir, GIT_CONSTANTS.DIVERGED_DIR_NAME);\n\n if (!name || name === \".\" || name === \"..\" || name.includes(\"/\") || name.includes(\"\\\\\")) {\n throw new Error(`Invalid diverged directory name: \"${name}\"`);\n }\n\n const targetPath = path.join(divergedBase, name);\n\n if (!this.pathResolution.isPathInsideBaseDir(targetPath, divergedBase)) {\n throw new Error(`Path traversal rejected: \"${name}\" resolves outside the diverged directory`);\n }\n\n await fs.rm(targetPath, { recursive: true, force: true });\n this.addLog(`\uD83D\uDDD1\uFE0F Deleted diverged directory: ${name}`, \"info\");\n }\n\n public async createWorktreeForBranch(repoIndex: number, branchName: string): Promise<void> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n const gitService = service.getGitService();\n const worktreeDir = service.config.worktreeDir;\n const worktreePath = this.pathResolution.getBranchWorktreePath(worktreeDir, branchName);\n\n await gitService.addWorktree(branchName, worktreePath);\n }\n\n public openEditorInWorktree(worktreePath: string): { success: boolean; error?: string } {\n const editor = process.env.EDITOR || process.env.VISUAL || \"code\";\n\n try {\n const child = spawn(editor, [worktreePath], {\n detached: true,\n stdio: \"ignore\",\n });\n\n child.on(\"error\", (err) => {\n this.addLog(`Failed to open editor '${editor}': ${err.message}`, \"error\");\n this.addLog(\"Set EDITOR or VISUAL environment variable to your preferred editor\", \"warn\");\n });\n\n child.unref();\n\n // Return success optimistically - spawn errors are async and will be logged\n // to the UI when they occur. For detached processes, we can't reliably\n // catch spawn errors synchronously.\n return { success: true };\n } catch (err) {\n // This catches synchronous errors like ENOENT when the command doesn't exist\n const errorMessage = err instanceof Error ? err.message : String(err);\n this.addLog(`Failed to open editor '${editor}': ${errorMessage}`, \"error\");\n return { success: false, error: errorMessage };\n }\n }\n\n public openTerminalInWorktree(\n repoIndex: number,\n worktreePath: string,\n branchName: string,\n ): { success: boolean; error?: string } {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n const message = `Invalid repository index: ${repoIndex}`;\n this.addLog(message, \"error\");\n return { success: false, error: message };\n }\n const repoName = this.getRepoName(repoIndex);\n const sanitizedBranch = this.pathResolution.sanitizeBranchName(branchName);\n const sessionName = `${repoName}-${sanitizedBranch}`;\n const tmuxCommand = `tmux new-session -A -s ${shellEscape(sessionName)} -c ${shellEscape(worktreePath)}`;\n\n const launcher = this.resolveTerminalLauncher(tmuxCommand);\n if (!launcher) {\n const message =\n \"No terminal launcher found. Set SYNC_WORKTREES_TERMINAL or $TERMINAL to a terminal emulator command.\";\n this.addLog(message, \"error\");\n return { success: false, error: message };\n }\n\n try {\n const child = spawn(launcher.command, launcher.args, {\n detached: true,\n stdio: \"ignore\",\n });\n\n child.on(\"error\", (err) => {\n this.addLog(`Failed to open terminal '${launcher.command}': ${err.message}`, \"error\");\n this.addLog(\"Set SYNC_WORKTREES_TERMINAL to your preferred terminal command\", \"warn\");\n });\n\n child.unref();\n\n return { success: true };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n this.addLog(`Failed to open terminal '${launcher.command}': ${errorMessage}`, \"error\");\n return { success: false, error: errorMessage };\n }\n }\n\n private resolveTerminalLauncher(tmuxCommand: string): { command: string; args: string[] } | null {\n const override = this.parseCommandString(process.env[TERMINAL_CONSTANTS.ENV_OVERRIDE]);\n if (override) {\n // Wrap the tmux command in `sh -c` so terminal emulators that exec their trailing\n // arg as a program name (e.g. `alacritty -e`, `kitty -e`) can run the composite command.\n return { command: override.command, args: [...override.args, \"sh\", \"-c\", tmuxCommand] };\n }\n\n switch (process.platform) {\n case \"darwin\": {\n // Ghostty cannot be launched directly from the CLI on macOS; use `open -na` instead.\n const ghosttyPaths = [\"/Applications/Ghostty.app\", `${process.env.HOME}/Applications/Ghostty.app`];\n if (ghosttyPaths.some((p) => existsSync(p))) {\n return {\n command: \"open\",\n args: [\"-na\", \"Ghostty.app\", \"--args\", \"-e\", \"sh\", \"-c\", tmuxCommand],\n };\n }\n const escapedTmuxCommand = tmuxCommand.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n const script = `tell application \"Terminal\" to do script \"${escapedTmuxCommand}\"`;\n return { command: \"osascript\", args: [\"-e\", script] };\n }\n case \"linux\": {\n const envTerminal = this.parseCommandString(process.env[TERMINAL_CONSTANTS.ENV_FALLBACK]);\n if (envTerminal) {\n return { command: envTerminal.command, args: [...envTerminal.args, \"-e\", \"sh\", \"-c\", tmuxCommand] };\n }\n for (const candidate of TERMINAL_CONSTANTS.LINUX_CANDIDATES) {\n if (this.commandExists(candidate)) {\n if (candidate === \"gnome-terminal\") {\n return { command: candidate, args: [\"--\", \"sh\", \"-c\", tmuxCommand] };\n }\n return { command: candidate, args: [\"-e\", \"sh\", \"-c\", tmuxCommand] };\n }\n }\n return null;\n }\n default:\n return null;\n }\n }\n\n private parseCommandString(raw: string | undefined): { command: string; args: string[] } | null {\n if (!raw || raw.trim().length === 0) return null;\n const parts = raw.trim().split(/\\s+/);\n return { command: parts[0], args: parts.slice(1) };\n }\n\n private commandExists(command: string): boolean {\n try {\n const result = spawnSync(\"which\", [command], { stdio: \"ignore\" });\n return result.status === 0;\n } catch {\n return false;\n }\n }\n\n private async runSyncCycle(\n services: WorktreeSyncService[],\n options: { logErrors: boolean },\n ): Promise<Array<{ repo: string; error: string }>> {\n this.setStatus(\"syncing\");\n\n try {\n const { failures, skipped, partialSkips, clonePhaseSkips, attempted } = await this.runSyncServices(services);\n\n if (options.logErrors) {\n for (const failure of failures) {\n this.addLog(`Failed to sync repository '${failure.repo}': ${failure.error}`, \"error\");\n }\n }\n for (const skip of skipped) {\n this.addLog(`Sync skipped for '${skip.repo}': ${skip.reason}`, \"warn\");\n }\n for (const skip of clonePhaseSkips) {\n this.addLog(`Clone-mode skip for '${skip.repo}': ${skip.reason}`, \"warn\");\n }\n if (clonePhaseSkips.length > 0) {\n this.addLog(`\u26A0\uFE0F ${clonePhaseSkips.length} clone-mode skip(s) this cycle`, \"warn\");\n }\n for (const partial of partialSkips) {\n this.addLog(`${partial.repo}: ${partial.reason}`, \"info\");\n }\n\n await this.recordSyncOutcome({ failures, skipped, attempted });\n return failures;\n } finally {\n this.setStatus(\"idle\");\n }\n }\n\n private async recordSyncOutcome(outcome: {\n failures: Array<{ repo: string; error: string }>;\n skipped: Array<{ repo: string; reason: string }>;\n attempted: number;\n }): Promise<void> {\n const allSkipped =\n outcome.attempted > 0 &&\n outcome.skipped.length === outcome.attempted &&\n outcome.failures.length === 0;\n if (allSkipped) return;\n this.updateLastSyncTime();\n await this.calculateAndUpdateDiskSpace();\n }\n\n private async runSyncServices(services: WorktreeSyncService[]): Promise<{\n failures: Array<{ repo: string; error: string }>;\n skipped: Array<{ repo: string; reason: string }>;\n partialSkips: Array<{ repo: string; reason: string }>;\n clonePhaseSkips: Array<{ repo: string; reason: string }>;\n attempted: number;\n }> {\n const syncResults = await Promise.allSettled(\n services.map((service) => {\n const repoName = (service.config as RepositoryConfig).name || service.config.repoUrl;\n return this.limit(async () => {\n service.clearRecordedSkips();\n try {\n if (!service.isInitialized()) {\n await service.initialize();\n }\n const result = await service.sync();\n return { service, result };\n } finally {\n this.events.emit(\"setSyncProgress\", {\n repo: repoName,\n phase: \"complete\",\n message: \"Finished\",\n completed: true,\n });\n }\n }).catch((error) => {\n throw Object.assign(error instanceof Error ? error : new Error(String(error)), { repoName });\n });\n }),\n );\n\n const failures: Array<{ repo: string; error: string }> = [];\n const skipped: Array<{ repo: string; reason: string }> = [];\n const partialSkips: Array<{ repo: string; reason: string }> = [];\n const clonePhaseSkips: Array<{ repo: string; reason: string }> = [];\n for (let i = 0; i < syncResults.length; i++) {\n const result = syncResults[i];\n const repoName = (services[i].config as RepositoryConfig).name || services[i].config.repoUrl;\n if (result.status === \"rejected\") {\n const fallbackName = (result.reason as { repoName?: string })?.repoName ?? repoName;\n const errorMessage = result.reason instanceof Error ? result.reason.message : String(result.reason);\n failures.push({ repo: fallbackName, error: errorMessage });\n } else if (result.value.result && result.value.result.started === false) {\n skipped.push({ repo: repoName, reason: `sync skipped: ${result.value.result.reason}` });\n } else if (result.status === \"fulfilled\" && result.value.result?.started === true) {\n const outcome = result.value.result.outcome;\n if (outcome?.counts.failed) {\n failures.push({ repo: repoName, error: `${outcome.counts.failed} sync action(s) failed` });\n }\n // Per-action skips are informational; the repo did complete its sync\n // attempt. Surface as a separate channel so updateLastSyncTime still\n // runs and the per-cycle log stays at info-level.\n if (outcome?.mode === \"worktree\" && outcome.counts.skipped > 0) {\n partialSkips.push({ repo: repoName, reason: `${outcome.counts.skipped} sync action(s) skipped` });\n }\n }\n for (const reason of services[i].getRecordedSkips()) {\n clonePhaseSkips.push({ repo: repoName, reason: formatCloneSkipReason(reason) });\n }\n }\n\n return { failures, skipped, partialSkips, clonePhaseSkips, attempted: services.length };\n }\n\n private buildUiLogger(): Logger {\n return new Logger({\n outputFn: (msg: string, level: LogLevel): void => {\n const uiLevel: \"info\" | \"warn\" | \"error\" =\n level === \"warn\" ? \"warn\" : level === \"error\" ? \"error\" : \"info\";\n this.addLog(msg, uiLevel);\n },\n });\n }\n\n public executeOnBranchCreatedHooks(repoIndex: number, context: HookContext): void {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n return;\n }\n\n const service = this.syncServices[repoIndex];\n const config = service.config;\n const repoName = (config as RepositoryConfig).name || config.repoUrl;\n\n this.branchCreatedActions.runHooks({\n config,\n repoName,\n branchName: context.branchName,\n worktreePath: context.worktreePath,\n baseBranch: context.baseBranch,\n logger: this.buildUiLogger(),\n hookExecutionService: this.hookExecutionService,\n });\n }\n\n public async copyBranchFiles(repoIndex: number, baseBranch: string, targetBranch: string): Promise<void> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n return;\n }\n\n const service = this.syncServices[repoIndex];\n const config = service.config;\n\n if (!config.filesToCopyOnBranchCreate?.length) {\n return;\n }\n\n const worktrees = await this.getWorktreesFromService(service);\n\n const sourceWorktree = worktrees.find((w) => w.branch === baseBranch);\n const targetWorktree = worktrees.find((w) => w.branch === targetBranch);\n\n if (!sourceWorktree || !targetWorktree) {\n this.addLog(`Could not find worktrees for file copy: source=${baseBranch}, target=${targetBranch}`, \"warn\");\n return;\n }\n\n await this.branchCreatedActions.copyFiles({\n config,\n branchName: targetBranch,\n worktreePath: targetWorktree.path,\n sourceDir: sourceWorktree.path,\n logger: this.buildUiLogger(),\n });\n }\n\n public async destroy(fast = false): Promise<void> {\n this.isDestroyed = true;\n this.cancelCronJobs();\n\n try {\n await this.waitForInProgressSyncs(fast ? WAIT_SYNC_FAST_TIMEOUT_MS : WAIT_SYNC_DEFAULT_TIMEOUT_MS);\n } catch {\n // Best effort - proceed with teardown even if syncs don't finish\n }\n\n this.hookExecutionService.cleanup();\n if (this.app) {\n this.app.unmount();\n this.app = null;\n }\n for (const unsubscribe of this.unsubscribeCallbacks) {\n unsubscribe();\n }\n this.unsubscribeCallbacks = [];\n for (const unsubscribe of this.progressUnsubscribers) {\n unsubscribe();\n }\n this.progressUnsubscribers = [];\n if (this.ownsEvents) {\n this.events.removeAllListeners();\n }\n this.uiReady = false;\n this.logBuffer = [];\n }\n}\n", "import React, { useState, useEffect, useCallback, useRef } from \"react\";\nimport { Box, useInput, useStdout } from \"ink\";\nimport StatusBar from \"./StatusBar\";\nimport HelpModal from \"./HelpModal\";\nimport BranchCreationWizard from \"./BranchCreationWizard\";\nimport OpenEditorWizard from \"./OpenEditorWizard\";\nimport WorktreeStatusView from \"./WorktreeStatusView\";\nimport LogPanel from \"./LogPanel\";\nimport type { AppEventEmitter } from \"../utils/app-events\";\nimport type { AppSyncProgress } from \"../utils/app-events\";\nimport type {\n HookContext,\n WorktreeStatusEntry,\n DivergedDirectoryInfo,\n RepositoryListEntry,\n RepositoryDiskUsage,\n} from \"../types\";\n\nexport type { HookContext, WorktreeStatusEntry };\n\nexport interface AppProps {\n events: AppEventEmitter;\n repositoryCount: number;\n cronSchedule?: string;\n onManualSync: () => void;\n onReload: () => void;\n onQuit: () => Promise<void>;\n maxProgressLines?: number;\n getRepositoryList: () => RepositoryListEntry[];\n getRepositoryDiskUsage?: (index: number) => Promise<RepositoryDiskUsage>;\n getBranchesForRepo: (index: number) => Promise<string[]>;\n getDefaultBranchForRepo: (index: number) => string;\n fetchForRepo?: (index: number) => Promise<void>;\n createAndPushBranch: (\n repoIndex: number,\n baseBranch: string,\n branchName: string,\n ) => Promise<{ success: boolean; finalName: string; error?: string }>;\n getWorktreesForRepo: (index: number) => Promise<Array<{ path: string; branch: string }>>;\n openEditorInWorktree: (worktreePath: string) => { success: boolean; error?: string };\n openTerminalInWorktree: (\n repoIndex: number,\n worktreePath: string,\n branchName: string,\n ) => { success: boolean; error?: string };\n copyBranchFiles?: (repoIndex: number, baseBranch: string, targetBranch: string) => Promise<void>;\n createWorktreeForBranch: (repoIndex: number, branchName: string) => Promise<void>;\n executeOnBranchCreatedHooks?: (repoIndex: number, context: HookContext) => void;\n getWorktreeStatusForRepo?: (index: number) => Promise<WorktreeStatusEntry[]>;\n getDivergedDirectoriesForRepo?: (index: number) => Promise<DivergedDirectoryInfo[]>;\n deleteDivergedDirectory?: (repoIndex: number, name: string) => Promise<void>;\n}\n\nexport interface LogEntry {\n id: string;\n message: string;\n level: \"info\" | \"warn\" | \"error\";\n timestamp: Date;\n}\n\nconst MAX_LOG_ENTRIES = 5000;\n\nconst App: React.FC<AppProps> = ({\n events,\n repositoryCount,\n cronSchedule,\n onManualSync,\n onReload,\n onQuit,\n maxProgressLines = 2,\n getRepositoryList,\n getRepositoryDiskUsage,\n getBranchesForRepo,\n getDefaultBranchForRepo,\n fetchForRepo,\n createAndPushBranch,\n getWorktreesForRepo,\n openEditorInWorktree,\n openTerminalInWorktree,\n copyBranchFiles,\n createWorktreeForBranch,\n executeOnBranchCreatedHooks,\n getWorktreeStatusForRepo,\n getDivergedDirectoriesForRepo,\n deleteDivergedDirectory,\n}) => {\n const [showHelp, setShowHelp] = useState(false);\n const [showBranchWizard, setShowBranchWizard] = useState(false);\n const [showOpenEditorWizard, setShowOpenEditorWizard] = useState(false);\n const [showWorktreeStatus, setShowWorktreeStatus] = useState(false);\n const [status, setStatus] = useState<\"idle\" | \"syncing\">(\"idle\");\n const [syncProgressEntries, setSyncProgressEntries] = useState<AppSyncProgress[]>([]);\n const [lastSyncTime, setLastSyncTime] = useState<Date | null>(null);\n const [diskSpaceUsed, setDiskSpaceUsed] = useState<string | null>(null);\n const [logs, setLogs] = useState<LogEntry[]>([]);\n const [repoCount, setRepoCount] = useState(repositoryCount);\n const [schedule, setSchedule] = useState(cronSchedule);\n\n const { stdout } = useStdout();\n\n const addLog = useCallback((message: string, level: LogEntry[\"level\"] = \"info\") => {\n setLogs((prev) => {\n const newLogs = [\n ...prev,\n {\n id: `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,\n message,\n level,\n timestamp: new Date(),\n },\n ];\n if (newLogs.length > MAX_LOG_ENTRIES) {\n return newLogs.slice(-MAX_LOG_ENTRIES);\n }\n return newLogs;\n });\n }, []);\n\n const addLogRef = useRef(addLog);\n addLogRef.current = addLog;\n\n useInput((input, key) => {\n if (showHelp) {\n if (input === \"?\" || input === \"h\" || key.escape) {\n setShowHelp(false);\n }\n return;\n }\n\n if (showBranchWizard || showOpenEditorWizard || showWorktreeStatus) {\n return;\n }\n\n if (input === \"q\") {\n onQuit().catch((err) => console.error(\"Quit failed:\", err));\n } else if (input === \"?\" || input === \"h\") {\n setShowHelp(true);\n } else if (input === \"c\" && status === \"idle\") {\n setShowBranchWizard(true);\n } else if (input === \"o\" && status === \"idle\") {\n setShowOpenEditorWizard(true);\n } else if (input === \"w\" && status === \"idle\" && getWorktreeStatusForRepo) {\n setShowWorktreeStatus(true);\n } else if (input === \"s\" && status !== \"syncing\") {\n setStatus(\"syncing\");\n (async () => {\n try {\n await onManualSync();\n } catch (error) {\n console.error(\"Manual sync failed:\", error);\n setStatus(\"idle\");\n }\n })().catch((err) => console.error(\"Manual sync unhandled error:\", err));\n } else if (input === \"r\" && status !== \"syncing\") {\n setStatus(\"syncing\");\n (async () => {\n try {\n await onReload();\n } catch (error) {\n console.error(\"Reload failed:\", error);\n setStatus(\"idle\");\n }\n })().catch((err) => console.error(\"Reload unhandled error:\", err));\n }\n });\n\n const updateLastSyncTime = useCallback(() => {\n setLastSyncTime(new Date());\n setStatus(\"idle\");\n setSyncProgressEntries([]);\n }, []);\n\n useEffect(() => {\n const unsubscribers = [\n events.on(\"updateLastSyncTime\", () => {\n setLastSyncTime(new Date());\n setStatus(\"idle\");\n setSyncProgressEntries([]);\n }),\n events.on(\"setStatus\", (newStatus: \"idle\" | \"syncing\") => {\n setStatus(newStatus);\n if (newStatus === \"idle\") {\n setSyncProgressEntries([]);\n }\n }),\n events.on(\"setSyncProgress\", (progress: AppSyncProgress | null) => {\n if (progress === null) {\n setSyncProgressEntries([]);\n return;\n }\n setSyncProgressEntries((prev) => {\n if (progress.completed) {\n return prev.filter((entry) => entry.repo !== progress.repo);\n }\n\n const existingIndex = prev.findIndex((entry) => entry.repo === progress.repo);\n if (existingIndex === -1) {\n return [...prev, progress];\n }\n\n return prev.map((entry, index) => (index === existingIndex ? progress : entry));\n });\n }),\n events.on(\"setDiskSpace\", (diskSpace: string) => {\n setDiskSpaceUsed(diskSpace);\n }),\n events.on(\"addLog\", ({ message, level }: { message: string; level: \"info\" | \"warn\" | \"error\" }) => {\n addLogRef.current(message, level);\n }),\n events.on(\"updateRepositoryCount\", (count: number) => {\n setRepoCount(count);\n }),\n events.on(\"updateCronSchedule\", (newSchedule: string | undefined) => {\n setSchedule(newSchedule);\n }),\n ];\n\n events.emit(\"uiReady\");\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const progressLineCount = status === \"syncing\" ? Math.max(1, maxProgressLines) : 0;\n const statusBarHeight = 5 + progressLineCount;\n const terminalRows = stdout.rows ?? 24;\n const logPanelHeight = Math.max(5, terminalRows - statusBarHeight);\n const showModal = showHelp || showBranchWizard || showOpenEditorWizard || showWorktreeStatus;\n\n return (\n <Box flexDirection=\"column\" minHeight={terminalRows}>\n {!showModal && <LogPanel logs={logs} height={logPanelHeight} isActive={!showModal} />}\n\n {showHelp && <HelpModal onClose={() => setShowHelp(false)} />}\n\n {showBranchWizard && (\n <BranchCreationWizard\n repositories={getRepositoryList()}\n getBranchesForRepo={getBranchesForRepo}\n getDefaultBranchForRepo={getDefaultBranchForRepo}\n fetchForRepo={fetchForRepo}\n createAndPushBranch={createAndPushBranch}\n onClose={() => setShowBranchWizard(false)}\n onBranchCreated={(context) => {\n setStatus(\"syncing\");\n (async () => {\n try {\n await createWorktreeForBranch(context.repoIndex, context.newBranch);\n if (copyBranchFiles) {\n await copyBranchFiles(context.repoIndex, context.baseBranch, context.newBranch);\n }\n\n if (executeOnBranchCreatedHooks) {\n const worktrees = await getWorktreesForRepo(context.repoIndex);\n const worktree = worktrees.find((w) => w.branch === context.newBranch);\n if (worktree) {\n const repos = getRepositoryList();\n const repo = repos.find((r) => r.index === context.repoIndex);\n executeOnBranchCreatedHooks(context.repoIndex, {\n branchName: context.newBranch,\n worktreePath: worktree.path,\n repoName: repo?.name || `repo-${context.repoIndex}`,\n baseBranch: context.baseBranch,\n repoUrl: repo?.repoUrl || \"\",\n });\n }\n }\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n events.emit(\"addLog\", {\n message: `Failed to create worktree: ${errorMsg}`,\n level: \"error\",\n });\n } finally {\n setStatus(\"idle\");\n }\n })().catch((err) => console.error(\"Branch creation unhandled error:\", err));\n }}\n onComplete={() => {\n setShowBranchWizard(false);\n }}\n />\n )}\n\n {showOpenEditorWizard && (\n <OpenEditorWizard\n repositories={getRepositoryList()}\n getWorktreesForRepo={getWorktreesForRepo}\n openEditorInWorktree={openEditorInWorktree}\n openTerminalInWorktree={openTerminalInWorktree}\n onClose={() => setShowOpenEditorWizard(false)}\n />\n )}\n\n {showWorktreeStatus && getWorktreeStatusForRepo && (\n <WorktreeStatusView\n repositories={getRepositoryList()}\n getWorktreeStatusForRepo={getWorktreeStatusForRepo}\n getRepositoryDiskUsage={getRepositoryDiskUsage}\n getDivergedDirectoriesForRepo={getDivergedDirectoriesForRepo}\n deleteDivergedDirectory={deleteDivergedDirectory}\n onClose={() => setShowWorktreeStatus(false)}\n />\n )}\n\n <StatusBar\n status={status}\n syncProgressEntries={syncProgressEntries}\n maxProgressLines={maxProgressLines}\n repositoryCount={repoCount}\n lastSyncTime={lastSyncTime}\n cronSchedule={schedule}\n diskSpaceUsed={diskSpaceUsed ?? undefined}\n />\n </Box>\n );\n};\n\nexport default App;\n", "import React, { useState, useEffect } from \"react\";\nimport { Box, Text } from \"ink\";\nimport { CronExpressionParser } from \"cron-parser\";\n\nimport type { AppSyncProgress } from \"../utils/app-events\";\n\nexport interface StatusBarProps {\n status: \"idle\" | \"syncing\";\n syncProgressEntries?: AppSyncProgress[];\n maxProgressLines?: number;\n repositoryCount: number;\n lastSyncTime: Date | null;\n cronSchedule?: string;\n diskSpaceUsed?: string;\n}\n\nconst StatusBar: React.FC<StatusBarProps> = ({\n status,\n syncProgressEntries = [],\n maxProgressLines = 2,\n repositoryCount,\n lastSyncTime,\n cronSchedule,\n diskSpaceUsed,\n}) => {\n const [nextSyncTime, setNextSyncTime] = useState<Date | null>(null);\n\n useEffect(() => {\n if (!cronSchedule) {\n setNextSyncTime(null);\n return undefined;\n }\n\n try {\n const interval = CronExpressionParser.parse(cronSchedule);\n setNextSyncTime(interval.next().toDate());\n\n const timer = setInterval(() => {\n const fresh = CronExpressionParser.parse(cronSchedule);\n setNextSyncTime(fresh.next().toDate());\n }, 60000);\n\n return () => clearInterval(timer);\n } catch (error) {\n setNextSyncTime(null);\n return undefined;\n }\n }, [cronSchedule]);\n\n const formatTime = (date: Date | null): string => {\n if (!date) return \"N/A\";\n return date.toLocaleTimeString();\n };\n\n const getStatusColor = (): \"green\" | \"yellow\" => {\n return status === \"syncing\" ? \"yellow\" : \"green\";\n };\n\n const getStatusIcon = (): string => {\n return status === \"syncing\" ? \"\u27F3\" : \"\u2713\";\n };\n\n const formatProgress = (syncProgress: AppSyncProgress): string => {\n const percent =\n syncProgress.progress === undefined || syncProgress.message.includes(`${syncProgress.progress}%`)\n ? \"\"\n : ` ${syncProgress.progress}%`;\n return `[${syncProgress.repo}] ${syncProgress.message}${percent}`;\n };\n\n const progressLineCount = Math.max(1, maxProgressLines);\n const visibleProgress = syncProgressEntries.slice(-progressLineCount);\n\n return (\n <Box borderStyle=\"single\" paddingX={1}>\n <Box flexDirection=\"column\" width=\"100%\">\n <Box justifyContent=\"space-between\">\n <Text bold>\n {getStatusIcon()} Status:{\" \"}\n <Text color={getStatusColor()}>{status === \"syncing\" ? \"Syncing...\" : \"Running\"}</Text>\n </Text>\n <Text>\n Repositories: <Text bold color=\"cyan\">{repositoryCount}</Text>\n </Text>\n </Box>\n <Box justifyContent=\"space-between\">\n <Text>\n Last Sync: <Text color=\"gray\">{formatTime(lastSyncTime)}</Text>\n </Text>\n {cronSchedule && (\n <Text>\n Next Sync: <Text color=\"gray\">{formatTime(nextSyncTime)}</Text>\n </Text>\n )}\n </Box>\n {status === \"syncing\" &&\n Array.from({ length: progressLineCount }).map((_, index) => {\n const entry = visibleProgress[index];\n const message = entry ? formatProgress(entry) : index === 0 ? \"waiting for progress events\" : \"\";\n return (\n <Box key={index}>\n <Text wrap=\"truncate\">\n {message ? \"Progress: \" : \" \"}\n {message && <Text color=\"cyan\">{message}</Text>}\n </Text>\n </Box>\n );\n })}\n <Box justifyContent=\"space-between\">\n <Text>\n Disk Space: <Text color=\"magenta\">{diskSpaceUsed || \"Calculating...\"}</Text>\n </Text>\n <Text dimColor>\n <Text color=\"yellow\">s</Text>ync{\" \"}\n <Text color=\"yellow\">c</Text>reate{\" \"}\n <Text color=\"yellow\">o</Text>pen{\" \"}\n <Text color=\"yellow\">w</Text>tree{\" \"}\n <Text color=\"yellow\">r</Text>eload{\" \"}\n <Text color=\"yellow\">?</Text>help{\" \"}\n <Text color=\"yellow\">q</Text>uit\n </Text>\n </Box>\n </Box>\n </Box>\n );\n};\n\nexport default StatusBar;\n", "import React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nexport interface HelpModalProps {\n onClose: () => void;\n}\n\nconst HelpModal: React.FC<HelpModalProps> = ({ onClose }) => {\n useInput((input, key) => {\n if (input === \"?\" || input === \"h\" || key.escape) {\n onClose();\n }\n });\n return (\n <Box justifyContent=\"center\" alignItems=\"center\" flexDirection=\"column\" marginTop={2} marginBottom={2}>\n <Box borderStyle=\"double\" borderColor=\"cyan\" paddingX={2} paddingY={1} flexDirection=\"column\" width={60}>\n <Box justifyContent=\"center\" marginBottom={1}>\n <Text bold color=\"cyan\">\n \uD83C\uDF33 sync-worktrees - Keyboard Shortcuts\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" gap={0}>\n <Text bold color=\"green\" dimColor>\n Navigation\n </Text>\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n j\n </Text>\n <Text> / </Text>\n <Text bold color=\"yellow\">\n \u2193\n </Text>\n </Box>\n <Text>Scroll down one line</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n k\n </Text>\n <Text> / </Text>\n <Text bold color=\"yellow\">\n \u2191\n </Text>\n </Box>\n <Text>Scroll up one line</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n gg\n </Text>\n </Box>\n <Text>Jump to top</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n G\n </Text>\n </Box>\n <Text>Jump to bottom (re-enables auto-scroll)</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text bold color=\"green\" dimColor>\n Actions\n </Text>\n </Box>\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n s\n </Text>\n </Box>\n <Text>Manually trigger sync for all repositories</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n c\n </Text>\n </Box>\n <Text>Create a new branch</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n o\n </Text>\n </Box>\n <Text>Open worktree in terminal or editor</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n w\n </Text>\n </Box>\n <Text>View worktree status</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n r\n </Text>\n </Box>\n <Text>Reload configuration and re-sync all repos</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n ?\n </Text>\n <Text> / </Text>\n <Text bold color=\"yellow\">\n h\n </Text>\n </Box>\n <Text>Toggle this help screen</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n q\n </Text>\n <Text> / </Text>\n <Text bold color=\"yellow\">\n Esc\n </Text>\n </Box>\n <Text>Gracefully quit</Text>\n </Box>\n </Box>\n\n <Box justifyContent=\"center\" marginTop={1}>\n <Text dimColor>Press ? / h / ESC to close</Text>\n </Box>\n </Box>\n </Box>\n );\n};\n\nexport default HelpModal;\n", "import React, { useState, useEffect, useCallback, useMemo, useRef } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nimport { isValidGitBranchName } from \"../utils/git-validation\";\n\ntype WizardStep = \"SELECT_PROJECT\" | \"SELECT_BRANCH\" | \"ENTER_NAME\" | \"CREATING\" | \"RESULT\";\n\nexport interface BranchCreationWizardProps {\n repositories: Array<{ index: number; name: string; repoUrl: string }>;\n getBranchesForRepo: (index: number) => Promise<string[]>;\n getDefaultBranchForRepo: (index: number) => string;\n fetchForRepo?: (index: number) => Promise<void>;\n createAndPushBranch: (\n repoIndex: number,\n baseBranch: string,\n branchName: string,\n ) => Promise<{ success: boolean; finalName: string; error?: string }>;\n onClose: () => void;\n onComplete: (success: boolean) => void;\n onBranchCreated?: (context: {\n repoIndex: number;\n baseBranch: string;\n newBranch: string;\n }) => void;\n}\n\nconst BranchCreationWizard: React.FC<BranchCreationWizardProps> = ({\n repositories,\n getBranchesForRepo,\n getDefaultBranchForRepo,\n fetchForRepo,\n createAndPushBranch,\n onClose,\n onComplete,\n onBranchCreated,\n}) => {\n const [step, setStep] = useState<WizardStep>(repositories.length > 1 ? \"SELECT_PROJECT\" : \"SELECT_BRANCH\");\n const [selectedProjectIndex, setSelectedProjectIndex] = useState(0);\n const [selectedRepoIndex, setSelectedRepoIndex] = useState(\n repositories.length === 1 ? repositories[0].index : -1,\n );\n const [projectFilter, setProjectFilter] = useState(\"\");\n const [branches, setBranches] = useState<string[]>([]);\n const [defaultBranch, setDefaultBranch] = useState<string>(\"\");\n const [selectedBranchIndex, setSelectedBranchIndex] = useState(0);\n const [branchFilter, setBranchFilter] = useState(\"\");\n const [branchName, setBranchName] = useState(\"\");\n const [existingSuffix, setExistingSuffix] = useState<number | null>(null);\n const [validationError, setValidationError] = useState<string | null>(null);\n const [result, setResult] = useState<{ success: boolean; finalName: string; error?: string } | null>(null);\n const [loading, setLoading] = useState(false);\n\n const branchesLoadedRef = useRef(false);\n const [isFetching, setIsFetching] = useState(false);\n\n const filteredProjects = useMemo(() => {\n if (!projectFilter) return repositories;\n const lowerFilter = projectFilter.toLowerCase();\n return repositories.filter((repo) => repo.name.toLowerCase().includes(lowerFilter));\n }, [repositories, projectFilter]);\n\n const filteredBranches = useMemo(() => {\n if (!branchFilter) return branches;\n const lowerFilter = branchFilter.toLowerCase();\n return branches.filter((branch) => branch.toLowerCase().includes(lowerFilter));\n }, [branches, branchFilter]);\n\n useEffect(() => {\n if (filteredProjects.length > 0) {\n setSelectedProjectIndex((prev) => Math.max(0, Math.min(prev, filteredProjects.length - 1)));\n }\n }, [filteredProjects.length]);\n\n useEffect(() => {\n if (filteredBranches.length > 0) {\n setSelectedBranchIndex((prev) => Math.max(0, Math.min(prev, filteredBranches.length - 1)));\n }\n }, [filteredBranches.length]);\n\n const loadBranches = useCallback(\n async (repoIndex: number) => {\n setLoading(true);\n setIsFetching(false);\n try {\n let branchList = await getBranchesForRepo(repoIndex);\n\n // If no branches found and we haven't tried fetching yet, fetch and retry\n if (branchList.length === 0 && fetchForRepo) {\n setIsFetching(true);\n await fetchForRepo(repoIndex);\n branchList = await getBranchesForRepo(repoIndex);\n }\n\n const defaultBr = getDefaultBranchForRepo(repoIndex);\n setBranches(branchList);\n setDefaultBranch(defaultBr);\n const defaultIndex = branchList.indexOf(defaultBr);\n setSelectedBranchIndex(defaultIndex >= 0 ? defaultIndex : 0);\n } catch {\n setBranches([]);\n }\n setLoading(false);\n setIsFetching(false);\n },\n [getBranchesForRepo, getDefaultBranchForRepo, fetchForRepo],\n );\n\n const checkBranchExists = useCallback(\n (name: string) => {\n if (!name.trim()) {\n setExistingSuffix(null);\n setValidationError(null);\n return;\n }\n\n const validation = isValidGitBranchName(name);\n if (!validation.valid) {\n setValidationError(validation.error ?? null);\n setExistingSuffix(null);\n return;\n }\n\n setValidationError(null);\n\n let suffix = 0;\n let testName = name;\n\n while (branches.includes(testName)) {\n suffix++;\n testName = `${name}-${suffix}`;\n }\n\n setExistingSuffix(suffix > 0 ? suffix : null);\n },\n [branches],\n );\n\n useEffect(() => {\n if (step === \"SELECT_BRANCH\" && !branchesLoadedRef.current && !loading && selectedRepoIndex >= 0) {\n branchesLoadedRef.current = true;\n loadBranches(selectedRepoIndex);\n }\n }, [step, selectedRepoIndex, loading, loadBranches]);\n\n useEffect(() => {\n if (step === \"ENTER_NAME\") {\n checkBranchExists(branchName);\n }\n }, [branchName, step, checkBranchExists]);\n\n const handleCreateBranch = async () => {\n const trimmedName = branchName.trim();\n if (!trimmedName) return;\n\n const validation = isValidGitBranchName(trimmedName);\n if (!validation.valid) {\n setValidationError(validation.error ?? null);\n return;\n }\n\n setStep(\"CREATING\");\n const baseBranch = filteredBranches[selectedBranchIndex];\n try {\n const createResult = await createAndPushBranch(selectedRepoIndex, baseBranch, trimmedName);\n setResult(createResult);\n if (createResult.success && onBranchCreated) {\n onBranchCreated({\n repoIndex: selectedRepoIndex,\n baseBranch,\n newBranch: createResult.finalName,\n });\n }\n } catch (err) {\n setResult({\n success: false,\n finalName: trimmedName,\n error: err instanceof Error ? err.message : String(err),\n });\n } finally {\n setStep(\"RESULT\");\n }\n };\n\n useInput((input, key) => {\n if (step === \"CREATING\") return;\n\n if (key.escape) {\n if (step === \"SELECT_PROJECT\") {\n onClose();\n } else if (step === \"SELECT_BRANCH\") {\n if (repositories.length > 1) {\n setBranches([]);\n setBranchFilter(\"\");\n branchesLoadedRef.current = false;\n setIsFetching(false);\n setStep(\"SELECT_PROJECT\");\n } else {\n onClose();\n }\n } else if (step === \"ENTER_NAME\") {\n setBranchName(\"\");\n setExistingSuffix(null);\n setStep(\"SELECT_BRANCH\");\n } else if (step === \"RESULT\") {\n onComplete(result?.success ?? false);\n }\n return;\n }\n\n if (step === \"SELECT_PROJECT\") {\n if (key.upArrow) {\n setSelectedProjectIndex((prev) => Math.max(0, prev - 1));\n } else if (key.downArrow) {\n if (filteredProjects.length > 0) {\n setSelectedProjectIndex((prev) => Math.min(filteredProjects.length - 1, prev + 1));\n }\n } else if (key.return && filteredProjects.length > 0) {\n const selectedRepo = filteredProjects[selectedProjectIndex];\n if (selectedRepo) {\n setSelectedRepoIndex(selectedRepo.index);\n branchesLoadedRef.current = true;\n setIsFetching(false);\n loadBranches(selectedRepo.index);\n setStep(\"SELECT_BRANCH\");\n }\n } else if (key.backspace || key.delete) {\n setProjectFilter((prev) => prev.slice(0, -1));\n setSelectedProjectIndex(0);\n } else if (input && !key.ctrl && !key.meta) {\n setProjectFilter((prev) => prev + input);\n setSelectedProjectIndex(0);\n }\n } else if (step === \"SELECT_BRANCH\") {\n if (key.upArrow) {\n setSelectedBranchIndex((prev) => Math.max(0, prev - 1));\n } else if (key.downArrow) {\n if (filteredBranches.length > 0) {\n setSelectedBranchIndex((prev) => Math.min(filteredBranches.length - 1, prev + 1));\n }\n } else if (key.return && filteredBranches.length > 0) {\n setStep(\"ENTER_NAME\");\n } else if (key.backspace || key.delete) {\n setBranchFilter((prev) => prev.slice(0, -1));\n setSelectedBranchIndex(0);\n } else if (input && !key.ctrl && !key.meta) {\n setBranchFilter((prev) => prev + input);\n setSelectedBranchIndex(0);\n }\n } else if (step === \"ENTER_NAME\") {\n if (key.return && branchName.trim()) {\n handleCreateBranch().catch((err) => console.error(\"Branch creation failed:\", err));\n } else if (key.backspace || key.delete) {\n setBranchName((prev) => prev.slice(0, -1));\n } else if (input && !key.ctrl && !key.meta) {\n const validChar = /^[a-zA-Z0-9/._-]$/.test(input);\n if (validChar) {\n setBranchName((prev) => prev + input);\n }\n }\n } else if (step === \"RESULT\") {\n onComplete(result?.success ?? false);\n }\n });\n\n const getStepNumber = () => {\n if (repositories.length === 1) {\n if (step === \"SELECT_BRANCH\") return 1;\n if (step === \"ENTER_NAME\") return 2;\n return 2;\n }\n if (step === \"SELECT_PROJECT\") return 1;\n if (step === \"SELECT_BRANCH\") return 2;\n if (step === \"ENTER_NAME\") return 3;\n return 3;\n };\n\n const getTotalSteps = () => (repositories.length === 1 ? 2 : 3);\n\n const renderProjectSelection = () => {\n const visibleCount = 8;\n const halfVisible = Math.floor(visibleCount / 2);\n let startIdx = Math.max(0, selectedProjectIndex - halfVisible);\n const endIdx = Math.min(filteredProjects.length, startIdx + visibleCount);\n if (endIdx - startIdx < visibleCount) {\n startIdx = Math.max(0, endIdx - visibleCount);\n }\n\n const visibleProjects = filteredProjects.slice(startIdx, endIdx);\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text>Select repository:</Text>\n <Box>\n <Text>Filter: </Text>\n <Text color=\"cyan\">{projectFilter || \"_\"}</Text>\n <Text dimColor>\n {\" \"}\n ({filteredProjects.length}/{repositories.length} matches)\n </Text>\n </Box>\n <Box flexDirection=\"column\">\n {filteredProjects.length === 0 ? (\n <Text color=\"yellow\">No matches</Text>\n ) : (\n <>\n {startIdx > 0 && <Text dimColor> ...</Text>}\n {visibleProjects.map((repo, idx) => {\n const actualIdx = startIdx + idx;\n const isSelected = actualIdx === selectedProjectIndex;\n return (\n <Box key={repo.index}>\n <Text color={isSelected ? \"cyan\" : undefined}>\n {isSelected ? \"> \" : \" \"}\n {repo.name}\n </Text>\n </Box>\n );\n })}\n {endIdx < filteredProjects.length && <Text dimColor> ...</Text>}\n </>\n )}\n </Box>\n </Box>\n );\n };\n\n const renderBranchSelection = () => {\n if (loading) {\n return <Text color=\"yellow\">Loading branches{isFetching ? \" (fetching from remote...)\" : \"...\"}</Text>;\n }\n\n if (branches.length === 0) {\n return <Text color=\"red\">No branches found</Text>;\n }\n\n const visibleCount = 8;\n const halfVisible = Math.floor(visibleCount / 2);\n let startIdx = Math.max(0, selectedBranchIndex - halfVisible);\n const endIdx = Math.min(filteredBranches.length, startIdx + visibleCount);\n if (endIdx - startIdx < visibleCount) {\n startIdx = Math.max(0, endIdx - visibleCount);\n }\n\n const visibleBranches = filteredBranches.slice(startIdx, endIdx);\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text>Select base branch:</Text>\n <Box>\n <Text>Filter: </Text>\n <Text color=\"cyan\">{branchFilter || \"_\"}</Text>\n <Text dimColor>\n {\" \"}\n ({filteredBranches.length}/{branches.length} matches)\n </Text>\n </Box>\n <Box flexDirection=\"column\">\n {filteredBranches.length === 0 ? (\n <Text color=\"yellow\">No matches</Text>\n ) : (\n <>\n {startIdx > 0 && <Text dimColor> ...</Text>}\n {visibleBranches.map((branch, idx) => {\n const actualIdx = startIdx + idx;\n const isSelected = actualIdx === selectedBranchIndex;\n const isDefault = branch === defaultBranch;\n return (\n <Box key={branch}>\n <Text color={isSelected ? \"cyan\" : undefined}>\n {isSelected ? \"> \" : \" \"}\n {branch}\n {isDefault && <Text color=\"green\"> (default)</Text>}\n </Text>\n </Box>\n );\n })}\n {endIdx < filteredBranches.length && <Text dimColor> ...</Text>}\n </>\n )}\n </Box>\n </Box>\n );\n };\n\n const renderNameInput = () => {\n const baseBranch = filteredBranches[selectedBranchIndex] || \"\";\n const finalName = existingSuffix !== null ? `${branchName}-${existingSuffix}` : branchName;\n const endsWithSlash = branchName.endsWith(\"/\");\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text>\n Base branch: <Text color=\"cyan\">{baseBranch}</Text>\n </Text>\n <Text>Enter new branch name:</Text>\n <Box>\n <Text color=\"cyan\">{\"> \"}</Text>\n <Text>{branchName}</Text>\n <Text color=\"gray\">|</Text>\n </Box>\n {validationError && (\n <Text color=\"red\">{validationError}</Text>\n )}\n {!validationError && endsWithSlash && (\n <Text color=\"yellow\" dimColor>\n Hint: consecutive slashes (//) are not allowed\n </Text>\n )}\n {!validationError && !endsWithSlash && existingSuffix !== null && branchName && (\n <Text color=\"yellow\">\n Name exists, will create: <Text color=\"cyan\">{finalName}</Text>\n </Text>\n )}\n </Box>\n );\n };\n\n const renderCreating = () => (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"yellow\">Creating branch...</Text>\n <Text dimColor>Please wait while the branch is created and pushed to remote.</Text>\n </Box>\n );\n\n const renderResult = () => {\n if (!result) return null;\n\n if (result.success) {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"green\">Branch created successfully!</Text>\n <Text>\n Created: <Text color=\"cyan\">{result.finalName}</Text>\n </Text>\n <Text>\n From: <Text color=\"cyan\">{filteredBranches[selectedBranchIndex]}</Text>\n </Text>\n <Text color=\"green\">Worktree sync started in background</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"red\">Failed to create branch</Text>\n <Text color=\"red\">{result.error}</Text>\n </Box>\n );\n };\n\n const renderContent = () => {\n switch (step) {\n case \"SELECT_PROJECT\":\n return renderProjectSelection();\n case \"SELECT_BRANCH\":\n return renderBranchSelection();\n case \"ENTER_NAME\":\n return renderNameInput();\n case \"CREATING\":\n return renderCreating();\n case \"RESULT\":\n return renderResult();\n }\n };\n\n const renderFooter = () => {\n if (step === \"CREATING\") return null;\n if (step === \"RESULT\") {\n return <Text dimColor>Press any key to close</Text>;\n }\n if (step === \"ENTER_NAME\") {\n return <Text dimColor>Enter to create \u2022 ESC to go back</Text>;\n }\n return <Text dimColor>\u2191/\u2193 navigate \u2022 Type to filter \u2022 Enter to select \u2022 ESC to cancel</Text>;\n };\n\n return (\n <Box flexDirection=\"column\" marginTop={1} marginBottom={1}>\n <Box borderStyle=\"round\" borderColor=\"green\" paddingX={2} paddingY={1} flexDirection=\"column\" width={60}>\n <Box marginBottom={1}>\n <Text bold color=\"green\">\n \uD83C\uDF3F Create New Branch{\" \"}\n {step !== \"CREATING\" && step !== \"RESULT\" && (\n <Text dimColor>\n (Step {getStepNumber()}/{getTotalSteps()})\n </Text>\n )}\n </Text>\n </Box>\n\n {repositories.length > 1 && step !== \"SELECT_PROJECT\" && step !== \"CREATING\" && step !== \"RESULT\" && (\n <Box marginBottom={1}>\n <Text>\n Repository: <Text color=\"cyan\">{repositories.find((r) => r.index === selectedRepoIndex)?.name}</Text>\n </Text>\n </Box>\n )}\n\n {renderContent()}\n\n <Box marginTop={1}>{renderFooter()}</Box>\n </Box>\n </Box>\n );\n};\n\nexport default BranchCreationWizard;\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 React, { useState, useEffect, useMemo, useCallback, useRef } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\ntype WizardStep = \"SELECT_PROJECT\" | \"SELECT_WORKTREE\" | \"OPENING\" | \"ERROR\";\n\nexport type OpenAction = \"terminal\" | \"editor\";\n\nexport interface OpenEditorWizardProps {\n repositories: Array<{ index: number; name: string; repoUrl: string }>;\n getWorktreesForRepo: (index: number) => Promise<Array<{ path: string; branch: string }>>;\n openEditorInWorktree: (worktreePath: string) => { success: boolean; error?: string };\n openTerminalInWorktree: (\n repoIndex: number,\n worktreePath: string,\n branchName: string,\n ) => { success: boolean; error?: string };\n onClose: () => void;\n}\n\nconst OpenEditorWizard: React.FC<OpenEditorWizardProps> = ({\n repositories,\n getWorktreesForRepo,\n openEditorInWorktree,\n openTerminalInWorktree,\n onClose,\n}) => {\n const [step, setStep] = useState<WizardStep>(repositories.length > 1 ? \"SELECT_PROJECT\" : \"SELECT_WORKTREE\");\n const [selectedProjectIndex, setSelectedProjectIndex] = useState(0);\n const [projectFilter, setProjectFilter] = useState(\"\");\n const selectedRepoIndexRef = useRef<number>(repositories.length === 1 ? 0 : -1);\n\n const [worktrees, setWorktrees] = useState<Array<{ path: string; branch: string }>>([]);\n const [selectedWorktreeIndex, setSelectedWorktreeIndex] = useState(0);\n const [worktreeFilter, setWorktreeFilter] = useState(\"\");\n const [loading, setLoading] = useState(false);\n const [openAction, setOpenAction] = useState<OpenAction>(\"terminal\");\n\n const [error, setError] = useState<string | null>(null);\n\n const filteredProjects = useMemo(() => {\n if (!projectFilter) return repositories;\n const lowerFilter = projectFilter.toLowerCase();\n return repositories.filter((repo) => repo.name.toLowerCase().includes(lowerFilter));\n }, [repositories, projectFilter]);\n\n const filteredWorktrees = useMemo(() => {\n if (!worktreeFilter) return worktrees;\n const lowerFilter = worktreeFilter.toLowerCase();\n return worktrees.filter((wt) => wt.branch.toLowerCase().includes(lowerFilter));\n }, [worktrees, worktreeFilter]);\n\n const loadWorktrees = useCallback(\n async (repoIndex: number) => {\n setLoading(true);\n try {\n const wts = await getWorktreesForRepo(repoIndex);\n setWorktrees(wts);\n setSelectedWorktreeIndex(0);\n } catch (err) {\n setError(`Failed to load worktrees: ${err}`);\n setStep(\"ERROR\");\n }\n setLoading(false);\n },\n [getWorktreesForRepo],\n );\n\n useEffect(() => {\n if (step === \"SELECT_WORKTREE\" && worktrees.length === 0 && !loading && selectedRepoIndexRef.current >= 0) {\n loadWorktrees(selectedRepoIndexRef.current);\n }\n }, [step, worktrees.length, loading, loadWorktrees]);\n\n const handleOpen = () => {\n const worktree = filteredWorktrees[selectedWorktreeIndex];\n if (!worktree) return;\n\n setStep(\"OPENING\");\n const result =\n openAction === \"terminal\"\n ? openTerminalInWorktree(selectedRepoIndexRef.current, worktree.path, worktree.branch)\n : openEditorInWorktree(worktree.path);\n if (result.success) {\n onClose();\n } else {\n setError(result.error || (openAction === \"terminal\" ? \"Failed to open terminal\" : \"Failed to open editor\"));\n setStep(\"ERROR\");\n }\n };\n\n useInput((input, key) => {\n if (step === \"OPENING\") return;\n\n if (key.escape) {\n if (step === \"SELECT_PROJECT\") {\n onClose();\n } else if (step === \"SELECT_WORKTREE\") {\n if (repositories.length > 1) {\n setWorktrees([]);\n setWorktreeFilter(\"\");\n selectedRepoIndexRef.current = -1;\n setStep(\"SELECT_PROJECT\");\n } else {\n onClose();\n }\n } else if (step === \"ERROR\") {\n onClose();\n }\n return;\n }\n\n if (step === \"SELECT_PROJECT\") {\n if (key.upArrow) {\n setSelectedProjectIndex((prev) => Math.max(0, prev - 1));\n } else if (key.downArrow) {\n setSelectedProjectIndex((prev) => Math.min(filteredProjects.length - 1, prev + 1));\n } else if (key.return && filteredProjects.length > 0) {\n const selectedRepo = filteredProjects[selectedProjectIndex];\n if (selectedRepo) {\n selectedRepoIndexRef.current = selectedRepo.index;\n setStep(\"SELECT_WORKTREE\");\n loadWorktrees(selectedRepo.index);\n }\n } else if (key.backspace || key.delete) {\n setProjectFilter((prev) => prev.slice(0, -1));\n setSelectedProjectIndex(0);\n } else if (input && !key.ctrl && !key.meta) {\n setProjectFilter((prev) => prev + input);\n setSelectedProjectIndex(0);\n }\n } else if (step === \"SELECT_WORKTREE\") {\n if (key.tab) {\n setOpenAction((prev) => (prev === \"terminal\" ? \"editor\" : \"terminal\"));\n } else if (key.upArrow) {\n setSelectedWorktreeIndex((prev) => Math.max(0, prev - 1));\n } else if (key.downArrow) {\n setSelectedWorktreeIndex((prev) => Math.min(filteredWorktrees.length - 1, prev + 1));\n } else if (key.return && filteredWorktrees.length > 0) {\n handleOpen();\n } else if (key.backspace || key.delete) {\n setWorktreeFilter((prev) => prev.slice(0, -1));\n setSelectedWorktreeIndex(0);\n } else if (input && !key.ctrl && !key.meta) {\n setWorktreeFilter((prev) => prev + input);\n setSelectedWorktreeIndex(0);\n }\n } else if (step === \"ERROR\") {\n onClose();\n }\n });\n\n const getStepNumber = () => {\n if (repositories.length === 1) {\n return 1;\n }\n return step === \"SELECT_PROJECT\" ? 1 : 2;\n };\n\n const getTotalSteps = () => (repositories.length === 1 ? 1 : 2);\n\n const renderProjectSelection = () => {\n const visibleCount = 8;\n const halfVisible = Math.floor(visibleCount / 2);\n let startIdx = Math.max(0, selectedProjectIndex - halfVisible);\n const endIdx = Math.min(filteredProjects.length, startIdx + visibleCount);\n if (endIdx - startIdx < visibleCount) {\n startIdx = Math.max(0, endIdx - visibleCount);\n }\n\n const visibleProjects = filteredProjects.slice(startIdx, endIdx);\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text>Select repository:</Text>\n <Box>\n <Text>Filter: </Text>\n <Text color=\"cyan\">{projectFilter || \"_\"}</Text>\n <Text dimColor>\n {\" \"}\n ({filteredProjects.length}/{repositories.length} matches)\n </Text>\n </Box>\n <Box flexDirection=\"column\">\n {filteredProjects.length === 0 ? (\n <Text color=\"yellow\">No matches</Text>\n ) : (\n <>\n {startIdx > 0 && <Text dimColor> ...</Text>}\n {visibleProjects.map((repo, idx) => {\n const actualIdx = startIdx + idx;\n const isSelected = actualIdx === selectedProjectIndex;\n return (\n <Box key={repo.index}>\n <Text color={isSelected ? \"cyan\" : undefined}>\n {isSelected ? \"> \" : \" \"}\n {repo.name}\n </Text>\n </Box>\n );\n })}\n {endIdx < filteredProjects.length && <Text dimColor> ...</Text>}\n </>\n )}\n </Box>\n </Box>\n );\n };\n\n const renderWorktreeSelection = () => {\n if (loading) {\n return <Text color=\"yellow\">Loading worktrees...</Text>;\n }\n\n if (worktrees.length === 0) {\n return <Text color=\"red\">No worktrees found</Text>;\n }\n\n const visibleCount = 8;\n const halfVisible = Math.floor(visibleCount / 2);\n let startIdx = Math.max(0, selectedWorktreeIndex - halfVisible);\n const endIdx = Math.min(filteredWorktrees.length, startIdx + visibleCount);\n if (endIdx - startIdx < visibleCount) {\n startIdx = Math.max(0, endIdx - visibleCount);\n }\n\n const visibleWorktrees = filteredWorktrees.slice(startIdx, endIdx);\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text>Mode: </Text>\n <Text color=\"cyan\" bold>\n {openAction === \"terminal\" ? \"Terminal (tmux)\" : \"Editor\"}\n </Text>\n <Text dimColor> (Tab to switch to {openAction === \"terminal\" ? \"Editor\" : \"Terminal\"})</Text>\n </Box>\n <Text>Select worktree:</Text>\n <Box>\n <Text>Filter: </Text>\n <Text color=\"cyan\">{worktreeFilter || \"_\"}</Text>\n <Text dimColor>\n {\" \"}\n ({filteredWorktrees.length}/{worktrees.length} matches)\n </Text>\n </Box>\n <Box flexDirection=\"column\">\n {filteredWorktrees.length === 0 ? (\n <Text color=\"yellow\">No matches</Text>\n ) : (\n <>\n {startIdx > 0 && <Text dimColor> ...</Text>}\n {visibleWorktrees.map((wt, idx) => {\n const actualIdx = startIdx + idx;\n const isSelected = actualIdx === selectedWorktreeIndex;\n return (\n <Box key={wt.path}>\n <Text color={isSelected ? \"cyan\" : undefined}>\n {isSelected ? \"> \" : \" \"}\n {wt.branch}\n </Text>\n </Box>\n );\n })}\n {endIdx < filteredWorktrees.length && <Text dimColor> ...</Text>}\n </>\n )}\n </Box>\n </Box>\n );\n };\n\n const renderOpening = () => (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"yellow\">{openAction === \"terminal\" ? \"Opening terminal...\" : \"Opening editor...\"}</Text>\n </Box>\n );\n\n const renderError = () => (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"red\">Error: {error}</Text>\n <Text dimColor>Press any key to close</Text>\n </Box>\n );\n\n const renderContent = () => {\n switch (step) {\n case \"SELECT_PROJECT\":\n return renderProjectSelection();\n case \"SELECT_WORKTREE\":\n return renderWorktreeSelection();\n case \"OPENING\":\n return renderOpening();\n case \"ERROR\":\n return renderError();\n }\n };\n\n const renderFooter = () => {\n if (step === \"OPENING\") return null;\n if (step === \"ERROR\") return null;\n if (step === \"SELECT_WORKTREE\") {\n return (\n <Text dimColor>\u2191/\u2193 navigate \u2022 Type to filter \u2022 Tab switch mode \u2022 Enter to select \u2022 ESC to cancel</Text>\n );\n }\n return <Text dimColor>\u2191/\u2193 navigate \u2022 Type to filter \u2022 Enter to select \u2022 ESC to cancel</Text>;\n };\n\n return (\n <Box flexDirection=\"column\" marginTop={1} marginBottom={1}>\n <Box borderStyle=\"round\" borderColor=\"blue\" paddingX={2} paddingY={1} flexDirection=\"column\" width={60}>\n <Box marginBottom={1}>\n <Text bold color=\"blue\">\n \uD83D\uDCC2 Open Worktree{\" \"}\n {step !== \"OPENING\" && step !== \"ERROR\" && (\n <Text dimColor>\n (Step {getStepNumber()}/{getTotalSteps()})\n </Text>\n )}\n </Text>\n </Box>\n\n {repositories.length > 1 && step === \"SELECT_WORKTREE\" && !loading && selectedRepoIndexRef.current >= 0 && (\n <Box marginBottom={1}>\n <Text>\n Repository: <Text color=\"cyan\">{repositories.find((r) => r.index === selectedRepoIndexRef.current)?.name}</Text>\n </Text>\n </Box>\n )}\n\n {renderContent()}\n\n <Box marginTop={1}>{renderFooter()}</Box>\n </Box>\n </Box>\n );\n};\n\nexport default OpenEditorWizard;\n", "import React, { useState, useEffect, useMemo, useCallback, useRef } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nimport type { WorktreeStatusResult } from \"../services/worktree-status.service\";\nimport type {\n WorktreeStatusEntry,\n DivergedDirectoryInfo,\n RepositoryListEntry,\n RepositoryDiskUsage,\n} from \"../types\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\n\nexport type { WorktreeStatusEntry };\n\ntype ViewStep = \"SELECT_PROJECT\" | \"VIEW_STATUS\" | \"ERROR\";\n\nexport interface WorktreeStatusViewProps {\n repositories: RepositoryListEntry[];\n getWorktreeStatusForRepo: (index: number) => Promise<WorktreeStatusEntry[]>;\n getRepositoryDiskUsage?: (index: number) => Promise<RepositoryDiskUsage>;\n getDivergedDirectoriesForRepo?: (index: number) => Promise<DivergedDirectoryInfo[]>;\n deleteDivergedDirectory?: (repoIndex: number, name: string) => Promise<void>;\n onClose: () => void;\n}\n\ntype RepositoryDiskUsageState =\n | { status: \"loading\" }\n | { status: \"ready\"; usage: RepositoryDiskUsage }\n | { status: \"error\" };\n\ntype ListItem =\n | { type: \"worktree\"; entry: WorktreeStatusEntry }\n | { type: \"separator\" }\n | { type: \"diverged\"; entry: DivergedDirectoryInfo };\n\nconst getStatusFlags = (status: WorktreeStatusResult): React.ReactNode => {\n const flags: React.ReactNode[] = [];\n\n if (\n status.isClean &&\n !status.hasUnpushedCommits &&\n !status.hasStashedChanges &&\n !status.hasOperationInProgress &&\n !status.hasModifiedSubmodules &&\n !status.upstreamGone\n ) {\n return <Text color=\"green\">\u2713</Text>;\n }\n\n if (!status.isClean) {\n flags.push(\n <Text key=\"modified\" color=\"yellow\">\n M\n </Text>,\n );\n }\n if (status.hasUnpushedCommits) {\n flags.push(\n <Text key=\"unpushed\" color=\"cyan\">\n \u2191\n </Text>,\n );\n }\n if (status.hasStashedChanges) {\n flags.push(\n <Text key=\"stash\" color=\"magenta\">\n S\n </Text>,\n );\n }\n if (status.hasOperationInProgress) {\n flags.push(\n <Text key=\"operation\" color=\"red\">\n \u26A0\n </Text>,\n );\n }\n if (status.hasModifiedSubmodules) {\n flags.push(\n <Text key=\"submodules\" color=\"yellow\">\n \u229E\n </Text>,\n );\n }\n if (status.upstreamGone) {\n flags.push(\n <Text key=\"upstream\" color=\"red\" dimColor>\n \u2717\n </Text>,\n );\n }\n\n return <>{flags}</>;\n};\n\nconst getStatusSummary = (status: WorktreeStatusResult): string => {\n const parts: string[] = [];\n const details = status.details;\n\n if (!status.isClean && details) {\n const fileCount =\n details.modifiedFiles + details.deletedFiles + details.renamedFiles + details.createdFiles + details.conflictedFiles + details.untrackedFiles;\n if (fileCount > 0) parts.push(`${fileCount} changed`);\n }\n if (status.hasUnpushedCommits && details?.unpushedCommitCount) {\n parts.push(`${details.unpushedCommitCount} unpushed`);\n }\n if (status.hasStashedChanges && details?.stashCount) {\n parts.push(`${details.stashCount} stash`);\n }\n if (status.hasOperationInProgress && details?.operationType) {\n parts.push(`${details.operationType} in progress`);\n }\n if (status.upstreamGone) {\n parts.push(\"upstream gone\");\n }\n\n return parts.length > 0 ? `(${parts.join(\", \")})` : \"\";\n};\n\nconst formatDivergedDate = (dateStr: string): string => {\n if (!dateStr) return \"unknown date\";\n if (dateStr.length === 10) return dateStr;\n try {\n return new Date(dateStr).toLocaleDateString(\"en-CA\");\n } catch {\n return dateStr;\n }\n};\n\nconst WorktreeStatusView: React.FC<WorktreeStatusViewProps> = ({\n repositories,\n getWorktreeStatusForRepo,\n getRepositoryDiskUsage,\n getDivergedDirectoriesForRepo,\n deleteDivergedDirectory,\n onClose,\n}) => {\n const [step, setStep] = useState<ViewStep>(repositories.length > 1 ? \"SELECT_PROJECT\" : \"VIEW_STATUS\");\n const [selectedProjectIndex, setSelectedProjectIndex] = useState(0);\n const [projectFilter, setProjectFilter] = useState(\"\");\n const selectedRepoIndexRef = useRef<number>(repositories.length === 1 ? 0 : -1);\n\n const [entries, setEntries] = useState<WorktreeStatusEntry[]>([]);\n const [divergedEntries, setDivergedEntries] = useState<DivergedDirectoryInfo[]>([]);\n const [selectedEntryIndex, setSelectedEntryIndex] = useState(0);\n const [entryFilter, setEntryFilter] = useState(\"\");\n const [expandedEntry, setExpandedEntry] = useState<number | null>(null);\n const [loading, setLoading] = useState(false);\n const [repoDiskUsage, setRepoDiskUsage] = useState<Record<number, RepositoryDiskUsageState>>({});\n const requestedDiskUsageRef = useRef<Set<number>>(new Set());\n\n const [confirmDelete, setConfirmDelete] = useState<number | null>(null);\n const [deleting, setDeleting] = useState(false);\n\n const [error, setError] = useState<string | null>(null);\n\n const filteredProjects = useMemo(() => {\n if (!projectFilter) return repositories;\n const lowerFilter = projectFilter.toLowerCase();\n return repositories.filter((repo) => repo.name.toLowerCase().includes(lowerFilter));\n }, [repositories, projectFilter]);\n\n const filteredEntries = useMemo(() => {\n if (!entryFilter) return entries;\n const lowerFilter = entryFilter.toLowerCase();\n return entries.filter((entry) => entry.branch.toLowerCase().includes(lowerFilter));\n }, [entries, entryFilter]);\n\n const filteredDiverged = useMemo(() => {\n if (!entryFilter) return divergedEntries;\n const lowerFilter = entryFilter.toLowerCase();\n return divergedEntries.filter((entry) => entry.originalBranch.toLowerCase().includes(lowerFilter));\n }, [divergedEntries, entryFilter]);\n\n const combinedList = useMemo((): ListItem[] => {\n const items: ListItem[] = filteredEntries.map((entry) => ({ type: \"worktree\" as const, entry }));\n if (filteredDiverged.length > 0) {\n items.push({ type: \"separator\" as const });\n for (const entry of filteredDiverged) {\n items.push({ type: \"diverged\" as const, entry });\n }\n }\n return items;\n }, [filteredEntries, filteredDiverged]);\n\n const selectableIndices = useMemo(() => {\n return combinedList.reduce<number[]>((acc, item, idx) => {\n if (item.type !== \"separator\") acc.push(idx);\n return acc;\n }, []);\n }, [combinedList]);\n\n const loadStatus = useCallback(\n async (repoIndex: number) => {\n setLoading(true);\n try {\n const [statusEntries, divergedDirs] = await Promise.all([\n getWorktreeStatusForRepo(repoIndex),\n getDivergedDirectoriesForRepo?.(repoIndex) ?? Promise.resolve([]),\n ]);\n setEntries(statusEntries);\n setDivergedEntries(divergedDirs);\n setSelectedEntryIndex(0);\n setExpandedEntry(null);\n setConfirmDelete(null);\n } catch (err) {\n setError(`Failed to load worktree status: ${err}`);\n setStep(\"ERROR\");\n }\n setLoading(false);\n },\n [getWorktreeStatusForRepo, getDivergedDirectoriesForRepo],\n );\n\n useEffect(() => {\n if (!getRepositoryDiskUsage) return undefined;\n\n let cancelled = false;\n const indexesToLoad = repositories\n .map((repo) => repo.index)\n .filter((repoIndex) => !requestedDiskUsageRef.current.has(repoIndex));\n\n if (indexesToLoad.length === 0) return undefined;\n\n for (const repoIndex of indexesToLoad) {\n requestedDiskUsageRef.current.add(repoIndex);\n setRepoDiskUsage((prev) => ({ ...prev, [repoIndex]: { status: \"loading\" } }));\n\n void getRepositoryDiskUsage(repoIndex)\n .then((usage) => {\n if (cancelled) return;\n setRepoDiskUsage((prev) => ({ ...prev, [repoIndex]: { status: \"ready\", usage } }));\n })\n .catch(() => {\n if (cancelled) return;\n setRepoDiskUsage((prev) => ({\n ...prev,\n [repoIndex]: { status: \"error\" },\n }));\n });\n }\n\n return () => {\n cancelled = true;\n };\n }, [repositories, getRepositoryDiskUsage]);\n\n useEffect(() => {\n if (step === \"VIEW_STATUS\" && entries.length === 0 && !loading && selectedRepoIndexRef.current >= 0) {\n loadStatus(selectedRepoIndexRef.current);\n }\n }, [step, entries.length, loading, loadStatus]);\n\n const navigateUp = useCallback(() => {\n setSelectedEntryIndex((prev) => {\n const currentSelectableIdx = selectableIndices.indexOf(prev);\n if (currentSelectableIdx <= 0) return selectableIndices[0] ?? 0;\n return selectableIndices[currentSelectableIdx - 1];\n });\n }, [selectableIndices]);\n\n const navigateDown = useCallback(() => {\n setSelectedEntryIndex((prev) => {\n const currentSelectableIdx = selectableIndices.indexOf(prev);\n if (currentSelectableIdx === -1) return selectableIndices[0] ?? 0;\n if (currentSelectableIdx >= selectableIndices.length - 1) return prev;\n return selectableIndices[currentSelectableIdx + 1];\n });\n }, [selectableIndices]);\n\n const selectedItem = combinedList[selectedEntryIndex];\n const isDivergedSelected = selectedItem?.type === \"diverged\";\n\n useInput((input, key) => {\n if (confirmDelete !== null) {\n if (input === \"y\" || input === \"Y\") {\n const item = combinedList[confirmDelete];\n if (item?.type === \"diverged\" && deleteDivergedDirectory && selectedRepoIndexRef.current >= 0) {\n setDeleting(true);\n deleteDivergedDirectory(selectedRepoIndexRef.current, item.entry.name)\n .then(() => {\n setDivergedEntries((prev) => prev.filter((d) => d.name !== item.entry.name));\n setConfirmDelete(null);\n setDeleting(false);\n setExpandedEntry(null);\n })\n .catch((err: unknown) => {\n setError(`Failed to delete: ${getErrorMessage(err)}`);\n setConfirmDelete(null);\n setDeleting(false);\n });\n }\n return;\n }\n if (input === \"n\" || input === \"N\" || key.escape) {\n setConfirmDelete(null);\n return;\n }\n return;\n }\n\n if (key.escape) {\n if (step === \"SELECT_PROJECT\") {\n onClose();\n } else if (step === \"VIEW_STATUS\") {\n if (repositories.length > 1) {\n setEntries([]);\n setDivergedEntries([]);\n setEntryFilter(\"\");\n setExpandedEntry(null);\n setConfirmDelete(null);\n selectedRepoIndexRef.current = -1;\n setStep(\"SELECT_PROJECT\");\n } else {\n onClose();\n }\n } else if (step === \"ERROR\") {\n onClose();\n }\n return;\n }\n\n if (step === \"SELECT_PROJECT\") {\n if (key.upArrow) {\n setSelectedProjectIndex((prev) => Math.max(0, prev - 1));\n } else if (key.downArrow) {\n setSelectedProjectIndex((prev) => Math.min(filteredProjects.length - 1, prev + 1));\n } else if (key.return && filteredProjects.length > 0) {\n const selectedRepo = filteredProjects[selectedProjectIndex];\n if (selectedRepo) {\n selectedRepoIndexRef.current = selectedRepo.index;\n setStep(\"VIEW_STATUS\");\n loadStatus(selectedRepo.index);\n }\n } else if (key.backspace || key.delete) {\n setProjectFilter((prev) => prev.slice(0, -1));\n setSelectedProjectIndex(0);\n } else if (input && !key.ctrl && !key.meta) {\n setProjectFilter((prev) => prev + input);\n setSelectedProjectIndex(0);\n }\n } else if (step === \"VIEW_STATUS\" && !loading) {\n if (key.upArrow) {\n navigateUp();\n } else if (key.downArrow) {\n navigateDown();\n } else if (key.return && combinedList.length > 0) {\n setExpandedEntry((prev) => (prev === selectedEntryIndex ? null : selectedEntryIndex));\n } else if (input === \"d\" && isDivergedSelected && deleteDivergedDirectory) {\n setConfirmDelete(selectedEntryIndex);\n } else if (key.backspace || key.delete) {\n setEntryFilter((prev) => prev.slice(0, -1));\n setSelectedEntryIndex(0);\n setExpandedEntry(null);\n } else if (input && !key.ctrl && !key.meta) {\n setEntryFilter((prev) => prev + input);\n setSelectedEntryIndex(0);\n setExpandedEntry(null);\n }\n } else if (step === \"ERROR\") {\n onClose();\n }\n });\n\n const getStepNumber = () => {\n if (repositories.length === 1) return 1;\n return step === \"SELECT_PROJECT\" ? 1 : 2;\n };\n\n const getTotalSteps = () => (repositories.length === 1 ? 1 : 2);\n\n const renderProjectSelection = () => {\n const visibleCount = 8;\n const halfVisible = Math.floor(visibleCount / 2);\n let startIdx = Math.max(0, selectedProjectIndex - halfVisible);\n const endIdx = Math.min(filteredProjects.length, startIdx + visibleCount);\n if (endIdx - startIdx < visibleCount) {\n startIdx = Math.max(0, endIdx - visibleCount);\n }\n\n const visibleProjects = filteredProjects.slice(startIdx, endIdx);\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text>Select repository:</Text>\n <Box>\n <Text>Filter: </Text>\n <Text color=\"cyan\">{projectFilter || \"_\"}</Text>\n <Text dimColor>\n {\" \"}\n ({filteredProjects.length}/{repositories.length} matches)\n </Text>\n </Box>\n <Box flexDirection=\"column\">\n {filteredProjects.length === 0 ? (\n <Text color=\"yellow\">No matches</Text>\n ) : (\n <>\n {startIdx > 0 && <Text dimColor> ...</Text>}\n {visibleProjects.map((repo, idx) => {\n const actualIdx = startIdx + idx;\n const isSelected = actualIdx === selectedProjectIndex;\n return (\n <Box key={repo.index}>\n <Text color={isSelected ? \"cyan\" : undefined}>{isSelected ? \"> \" : \" \"}</Text>\n <Box width={38}>\n <Text color={isSelected ? \"cyan\" : undefined}>{repo.name}</Text>\n </Box>\n {getRepositoryDiskUsage && <Text dimColor> </Text>}\n {renderRepositoryDiskUsage(repo.index)}\n </Box>\n );\n })}\n {endIdx < filteredProjects.length && <Text dimColor> ...</Text>}\n </>\n )}\n </Box>\n </Box>\n );\n };\n\n const renderDetailPanel = (entry: WorktreeStatusEntry) => {\n const { status } = entry;\n const details = status.details;\n\n return (\n <Box flexDirection=\"column\" marginLeft={4} marginTop={0} marginBottom={1}>\n <Text dimColor>Path: {entry.path}</Text>\n {details && (\n <>\n {details.modifiedFiles > 0 && <Text color=\"yellow\"> Modified: {details.modifiedFiles}</Text>}\n {details.deletedFiles > 0 && <Text color=\"red\"> Deleted: {details.deletedFiles}</Text>}\n {details.createdFiles > 0 && <Text color=\"green\"> Created: {details.createdFiles}</Text>}\n {details.renamedFiles > 0 && <Text color=\"blue\"> Renamed: {details.renamedFiles}</Text>}\n {details.untrackedFiles > 0 && <Text color=\"gray\"> Untracked: {details.untrackedFiles}</Text>}\n {details.conflictedFiles > 0 && <Text color=\"red\"> Conflicted: {details.conflictedFiles}</Text>}\n {(details.unpushedCommitCount ?? 0) > 0 && (\n <Text color=\"cyan\"> Unpushed commits: {details.unpushedCommitCount}</Text>\n )}\n {(details.stashCount ?? 0) > 0 && <Text color=\"magenta\"> Stashes: {details.stashCount}</Text>}\n {details.operationType && <Text color=\"red\"> Operation: {details.operationType}</Text>}\n {details.modifiedSubmodules && details.modifiedSubmodules.length > 0 && (\n <Text color=\"yellow\"> Modified submodules: {details.modifiedSubmodules.join(\", \")}</Text>\n )}\n </>\n )}\n {status.upstreamGone && <Text color=\"red\"> Remote branch has been deleted</Text>}\n {status.reasons.length > 0 && (\n <Text dimColor> Reasons: {status.reasons.join(\", \")}</Text>\n )}\n </Box>\n );\n };\n\n const renderDivergedDetailPanel = (entry: DivergedDirectoryInfo) => {\n return (\n <Box flexDirection=\"column\" marginLeft={4} marginTop={0} marginBottom={1}>\n <Text dimColor>Path: {entry.path}</Text>\n <Text dimColor> Original branch: {entry.originalBranch}</Text>\n {entry.divergedAt && <Text dimColor> Diverged: {entry.divergedAt}</Text>}\n <Text dimColor> Size: {entry.sizeFormatted}</Text>\n </Box>\n );\n };\n\n const renderRepositoryDiskUsage = (repoIndex: number) => {\n if (!getRepositoryDiskUsage) return null;\n\n const state = repoDiskUsage[repoIndex];\n if (!state || state.status === \"loading\") {\n return <Text dimColor>Size: calculating...</Text>;\n }\n if (state.status === \"error\") {\n return <Text color=\"red\">Size: N/A</Text>;\n }\n return (\n <Text>\n Size: <Text color=\"magenta\">{state.usage.sizeFormatted}</Text>\n </Text>\n );\n };\n\n const renderStatusList = () => {\n if (loading) {\n return <Text color=\"yellow\">Loading worktree status...</Text>;\n }\n\n if (entries.length === 0 && divergedEntries.length === 0) {\n return <Text color=\"red\">No worktrees found</Text>;\n }\n\n const visibleCount = 8;\n const halfVisible = Math.floor(visibleCount / 2);\n let startIdx = Math.max(0, selectedEntryIndex - halfVisible);\n const endIdx = Math.min(combinedList.length, startIdx + visibleCount);\n if (endIdx - startIdx < visibleCount) {\n startIdx = Math.max(0, endIdx - visibleCount);\n }\n\n const visibleItems = combinedList.slice(startIdx, endIdx);\n const filteredCount = filteredEntries.length + filteredDiverged.length;\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text>Filter: </Text>\n <Text color=\"cyan\">{entryFilter || \"_\"}</Text>\n <Text dimColor>\n {\" \"}\n ({filteredCount}/{entries.length + divergedEntries.length} matches)\n </Text>\n </Box>\n <Box flexDirection=\"column\">\n {filteredCount === 0 ? (\n <Text color=\"yellow\">No matches</Text>\n ) : (\n <>\n {startIdx > 0 && <Text dimColor> ...</Text>}\n {visibleItems.map((item, idx) => {\n const actualIdx = startIdx + idx;\n\n if (item.type === \"separator\") {\n return (\n <Box key=\"separator\" marginTop={1}>\n <Text dimColor>\u2500\u2500 Diverged Directories \u2500\u2500</Text>\n </Box>\n );\n }\n\n if (item.type === \"worktree\") {\n const isSelected = actualIdx === selectedEntryIndex;\n const isExpanded = expandedEntry === actualIdx;\n const summary = getStatusSummary(item.entry.status);\n\n return (\n <Box key={item.entry.path} flexDirection=\"column\">\n <Box>\n <Text color={isSelected ? \"cyan\" : undefined}>\n {isSelected ? \"> \" : \" \"}\n </Text>\n <Box width={24}>\n <Text color={isSelected ? \"cyan\" : undefined}>{item.entry.branch}</Text>\n </Box>\n <Text> </Text>\n {getStatusFlags(item.entry.status)}\n {summary && (\n <Text dimColor> {summary}</Text>\n )}\n </Box>\n {isExpanded && renderDetailPanel(item.entry)}\n </Box>\n );\n }\n\n const isSelected = actualIdx === selectedEntryIndex;\n const isExpanded = expandedEntry === actualIdx;\n const isConfirming = confirmDelete === actualIdx;\n const dateStr = formatDivergedDate(item.entry.divergedAt);\n\n return (\n <Box key={item.entry.path} flexDirection=\"column\">\n <Box>\n <Text color={isSelected ? \"cyan\" : undefined}>\n {isSelected ? \"> \" : \" \"}\n </Text>\n {isConfirming ? (\n deleting ? (\n <Text color=\"yellow\">Deleting...</Text>\n ) : (\n <Text color=\"red\">\n Delete {item.entry.name}? (y/n)\n </Text>\n )\n ) : (\n <>\n <Text color={isSelected ? \"cyan\" : \"yellow\"}>\uD83D\uDCE6 </Text>\n <Box width={24}>\n <Text color={isSelected ? \"cyan\" : undefined}>{item.entry.originalBranch}</Text>\n </Box>\n <Text dimColor> {item.entry.sizeFormatted.padStart(10)}</Text>\n <Text dimColor> (diverged {dateStr})</Text>\n </>\n )}\n </Box>\n {isExpanded && !isConfirming && renderDivergedDetailPanel(item.entry)}\n </Box>\n );\n })}\n {endIdx < combinedList.length && <Text dimColor> ...</Text>}\n </>\n )}\n </Box>\n </Box>\n );\n };\n\n const renderError = () => (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"red\">Error: {error}</Text>\n <Text dimColor>Press any key to close</Text>\n </Box>\n );\n\n const renderContent = () => {\n switch (step) {\n case \"SELECT_PROJECT\":\n return renderProjectSelection();\n case \"VIEW_STATUS\":\n return renderStatusList();\n case \"ERROR\":\n return renderError();\n }\n };\n\n const renderFooter = () => {\n if (step === \"ERROR\") return null;\n if (step === \"VIEW_STATUS\" && loading) return null;\n if (confirmDelete !== null) {\n return <Text dimColor>y to confirm \u2022 n or ESC to cancel</Text>;\n }\n return (\n <Text dimColor>\n {step === \"VIEW_STATUS\"\n ? isDivergedSelected\n ? \"\u2191/\u2193 navigate \u2022 Type to filter \u2022 Enter to expand \u2022 d to delete \u2022 ESC to close\"\n : \"\u2191/\u2193 navigate \u2022 Type to filter \u2022 Enter to expand \u2022 ESC to close\"\n : \"\u2191/\u2193 navigate \u2022 Type to filter \u2022 Enter to select \u2022 ESC to cancel\"}\n </Text>\n );\n };\n\n const selectedRepo =\n selectedRepoIndexRef.current >= 0\n ? repositories.find((repo) => repo.index === selectedRepoIndexRef.current)\n : undefined;\n\n return (\n <Box flexDirection=\"column\" marginTop={1} marginBottom={1}>\n <Box borderStyle=\"round\" borderColor=\"green\" paddingX={2} paddingY={1} flexDirection=\"column\" width={70}>\n <Box marginBottom={1}>\n <Text bold color=\"green\">\n \uD83D\uDCCA Worktree Status{\" \"}\n {step !== \"ERROR\" && (\n <Text dimColor>\n (Step {getStepNumber()}/{getTotalSteps()})\n </Text>\n )}\n </Text>\n </Box>\n\n {step === \"VIEW_STATUS\" && selectedRepo && (\n <Box marginBottom={1}>\n <Text>\n Repository: <Text color=\"cyan\">{selectedRepo.name}</Text>\n </Text>\n {getRepositoryDiskUsage && <Text dimColor> </Text>}\n {renderRepositoryDiskUsage(selectedRepo.index)}\n </Box>\n )}\n\n {renderContent()}\n\n <Box marginTop={1}>{renderFooter()}</Box>\n </Box>\n </Box>\n );\n};\n\nexport default WorktreeStatusView;\n", "/**\n * Extracts error message from unknown error type\n * @param error The error to extract message from\n * @returns The error message string\n */\nexport function getErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (error && typeof error === \"object\" && \"message\" in error) {\n return String((error as { message: unknown }).message);\n }\n return String(error);\n}\n\n/**\n * Common LFS error patterns that indicate Git LFS-related failures\n */\nexport const LFS_ERROR_PATTERNS = Object.freeze([\n \"smudge filter lfs failed\",\n \"Object does not exist on the server\",\n \"external filter 'git-lfs filter-process' failed\",\n] as const);\n\n/**\n * Checks if an error message contains any known LFS error patterns\n * @param errorMessage The error message to check\n * @returns true if the error is related to Git LFS\n */\nexport function isLfsError(errorMessage: string): boolean {\n return LFS_ERROR_PATTERNS.some((pattern) => errorMessage.includes(pattern));\n}\n\n/**\n * Checks if an error object contains any known LFS error patterns\n * @param error The error object to check\n * @returns true if the error is related to Git LFS\n */\nexport function isLfsErrorFromError(error: unknown): boolean {\n return isLfsError(getErrorMessage(error));\n}\n\n/**\n * git stderr fragments that indicate the requested remote ref does not exist\n * (e.g. the tracked branch was deleted on the remote). Matched as substrings;\n * callers force LC_ALL=C so these stay deterministic English.\n */\nexport const MISSING_REMOTE_REF_PATTERNS = Object.freeze([\n \"couldn't find remote ref\",\n \"Couldn't find remote ref\",\n \"not our ref\",\n] as const);\n\n/**\n * Checks if an error message indicates a missing remote ref.\n * @param errorMessage The error message to check\n * @returns true if the message indicates the remote ref is gone\n */\nexport function isMissingRemoteRefError(errorMessage: string): boolean {\n return MISSING_REMOTE_REF_PATTERNS.some((pattern) => errorMessage.includes(pattern));\n}\n", "import React, { useState, useEffect, useRef } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport type { LogEntry } from \"./App\";\n\nexport interface LogPanelProps {\n logs: LogEntry[];\n height: number;\n isActive: boolean;\n}\n\nconst LogPanel: React.FC<LogPanelProps> = ({ logs, height, isActive }) => {\n const [scrollOffset, setScrollOffset] = useState(0);\n const [autoScroll, setAutoScroll] = useState(true);\n const [pendingG, setPendingG] = useState(false);\n const gTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const borderLines = 2;\n const headerLine = 1;\n const visibleLines = Math.max(1, height - borderLines - headerLine);\n const maxOffset = Math.max(0, logs.length - visibleLines);\n\n useEffect(() => {\n if (autoScroll) {\n setScrollOffset(maxOffset);\n }\n }, [logs.length, maxOffset, autoScroll]);\n\n useEffect(() => {\n return () => {\n if (gTimeoutRef.current) {\n clearTimeout(gTimeoutRef.current);\n }\n };\n }, []);\n\n useInput(\n (input, key) => {\n if (!isActive) return;\n\n if (key.upArrow || input === \"k\") {\n setScrollOffset((prev) => Math.max(0, prev - 1));\n setAutoScroll(false);\n setPendingG(false);\n } else if (key.downArrow || input === \"j\") {\n setScrollOffset((prev) => {\n const newOffset = Math.min(maxOffset, prev + 1);\n if (newOffset >= maxOffset) {\n setAutoScroll(true);\n }\n return newOffset;\n });\n setPendingG(false);\n } else if (key.pageUp) {\n setScrollOffset((prev) => Math.max(0, prev - visibleLines));\n setAutoScroll(false);\n setPendingG(false);\n } else if (key.pageDown) {\n setScrollOffset((prev) => {\n const newOffset = Math.min(maxOffset, prev + visibleLines);\n if (newOffset >= maxOffset) {\n setAutoScroll(true);\n }\n return newOffset;\n });\n setPendingG(false);\n } else if (input === \"g\") {\n if (pendingG) {\n // gg - go to top\n setScrollOffset(0);\n setAutoScroll(false);\n setPendingG(false);\n if (gTimeoutRef.current) {\n clearTimeout(gTimeoutRef.current);\n gTimeoutRef.current = null;\n }\n } else {\n setPendingG(true);\n gTimeoutRef.current = setTimeout(() => {\n setPendingG(false);\n }, 500);\n }\n } else if (input === \"G\") {\n setScrollOffset(maxOffset);\n setAutoScroll(true);\n setPendingG(false);\n }\n },\n { isActive },\n );\n\n const getLogColor = (level: LogEntry[\"level\"]): \"red\" | \"yellow\" | undefined => {\n switch (level) {\n case \"error\":\n return \"red\";\n case \"warn\":\n return \"yellow\";\n default:\n return undefined;\n }\n };\n\n const visibleLogs = logs.slice(scrollOffset, scrollOffset + visibleLines);\n const hasMoreAbove = scrollOffset > 0;\n const hasMoreBelow = scrollOffset + visibleLines < logs.length;\n const aboveCount = scrollOffset;\n const belowCount = logs.length - scrollOffset - visibleLines;\n\n const emptyLines = Math.max(0, visibleLines - visibleLogs.length);\n\n return (\n <Box borderStyle=\"single\" flexDirection=\"column\" flexGrow={1} paddingX={1}>\n <Box justifyContent=\"space-between\">\n <Text bold>\n \uD83D\uDCCB Logs {logs.length > 0 && <Text dimColor>({logs.length} entries)</Text>}\n </Text>\n {isActive && (\n <Text dimColor>\n {hasMoreAbove || hasMoreBelow ? \"\u2191/\u2193 scroll\" : \"\"} {autoScroll ? \"(auto)\" : \"\"}\n </Text>\n )}\n </Box>\n\n {hasMoreAbove && (\n <Text dimColor>\n \u2191 {aboveCount} more above\n </Text>\n )}\n\n {visibleLogs.map((log) => (\n <Text key={log.id} color={getLogColor(log.level)} wrap=\"truncate\">\n {log.message}\n </Text>\n ))}\n\n {Array.from({ length: emptyLines }).map((_, i) => (\n <Text key={`empty-${i}`}> </Text>\n ))}\n\n {hasMoreBelow && (\n <Text dimColor>\n \u2193 {belowCount} more below\n </Text>\n )}\n </Box>\n );\n};\n\nexport default LogPanel;\n", "import { isLfsErrorFromError } from \"./lfs-error\";\n\ninterface ErrorWithCode {\n code?: string;\n message?: string;\n}\n\nexport interface LfsErrorContext {\n isLfsError: boolean;\n}\n\nexport interface RetryOptions {\n maxAttempts?: number | \"unlimited\";\n maxLfsRetries?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n backoffMultiplier?: number;\n /**\n * Add random jitter to retry delays to prevent thundering herd problem\n * in concurrent operations. Jitter is a random value between 0 and jitterMs\n * added to the calculated delay.\n *\n * Recommended for parallel operations to spread out retries.\n * Default: 0 (no jitter)\n */\n jitterMs?: number;\n shouldRetry?: (error: unknown, context?: LfsErrorContext) => boolean;\n onRetry?: (error: unknown, attempt: number, context?: LfsErrorContext) => void;\n lfsRetryHandler?: (context: LfsErrorContext) => void;\n}\n\nconst DEFAULT_OPTIONS: Required<Omit<RetryOptions, \"maxAttempts\">> & { maxAttempts: number | \"unlimited\" } = {\n maxAttempts: \"unlimited\",\n maxLfsRetries: 2,\n initialDelayMs: 1000,\n maxDelayMs: 600000, // 10 minutes\n backoffMultiplier: 2,\n jitterMs: 0,\n shouldRetry: (error, context) => {\n const err = error as ErrorWithCode;\n\n // Check for LFS errors\n if (isLfsErrorFromError(error)) {\n if (context) {\n context.isLfsError = true;\n }\n return true;\n }\n\n if (err.code === \"ENOTFOUND\" || err.code === \"ECONNREFUSED\" || err.code === \"ETIMEDOUT\") {\n return true;\n }\n\n if (err.code === \"EBUSY\" || err.code === \"ENOENT\" || err.code === \"EACCES\") {\n return true;\n }\n\n if (err.message?.includes(\"Could not read from remote repository\")) {\n return true;\n }\n\n if (err.message?.includes(\"fatal: unable to access\")) {\n return true;\n }\n\n return false;\n },\n onRetry: () => {},\n lfsRetryHandler: (_context) => {},\n};\n\nexport async function retry<T>(fn: () => Promise<T>, options: RetryOptions = {}): Promise<T> {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n let attempt = 1;\n let lfsAttempt = 0;\n const lfsContext: LfsErrorContext = { isLfsError: false };\n\n while (true) {\n try {\n return await fn();\n } catch (error) {\n // Reset LFS error flag for each attempt\n lfsContext.isLfsError = false;\n\n // Check if we should retry\n if (!opts.shouldRetry(error, lfsContext)) {\n throw error;\n }\n\n // Track LFS attempts separately\n if (lfsContext.isLfsError) {\n lfsAttempt++;\n\n // Check if we've exceeded LFS retry limit\n if (lfsAttempt > opts.maxLfsRetries) {\n const err = error as Error;\n throw new Error(\n `LFS error retry limit exceeded (${opts.maxLfsRetries} attempts). ` +\n `Consider using --skip-lfs option to bypass LFS downloads.`,\n { cause: err },\n );\n }\n }\n\n const isLastAttempt = opts.maxAttempts !== \"unlimited\" && attempt >= opts.maxAttempts;\n if (isLastAttempt) {\n throw error;\n }\n\n // Handle LFS errors specifically\n if (lfsContext.isLfsError && opts.lfsRetryHandler) {\n opts.lfsRetryHandler(lfsContext);\n }\n\n const baseDelay = Math.min(opts.initialDelayMs * Math.pow(opts.backoffMultiplier, attempt - 1), opts.maxDelayMs);\n\n // Add jitter to prevent thundering herd in concurrent operations\n // Jitter is a random value between 0 and jitterMs\n const jitter = opts.jitterMs > 0 ? Math.random() * opts.jitterMs : 0;\n const delay = baseDelay + jitter;\n\n opts.onRetry(error, attempt, lfsContext);\n\n await new Promise((resolve) => setTimeout(resolve, delay));\n attempt++;\n }\n }\n}\n", "import Table from \"cli-table3\";\n\nexport interface TimingResult {\n name: string;\n duration: number;\n count?: number;\n efficiency?: number;\n}\n\nexport class Timer {\n private startTime: number;\n private endTime?: number;\n\n constructor() {\n this.startTime = Date.now();\n }\n\n stop(): number {\n this.endTime = Date.now();\n return this.getDuration();\n }\n\n getDuration(): number {\n const end = this.endTime ?? Date.now();\n return end - this.startTime;\n }\n}\n\nexport class PhaseTimer {\n private phases: Map<string, { timer: Timer; count?: number; parallelism?: number }> = new Map();\n private currentPhase?: string;\n\n startPhase(name: string, parallelism?: number): void {\n if (this.currentPhase) {\n this.endPhase();\n }\n this.currentPhase = name;\n this.phases.set(name, { timer: new Timer(), parallelism });\n }\n\n endPhase(): void {\n if (this.currentPhase) {\n const phase = this.phases.get(this.currentPhase);\n if (phase) {\n phase.timer.stop();\n }\n this.currentPhase = undefined;\n }\n }\n\n setPhaseCount(name: string, count: number): void {\n const phase = this.phases.get(name);\n if (phase) {\n phase.count = count;\n }\n }\n\n getResults(): TimingResult[] {\n if (this.currentPhase) {\n this.endPhase();\n }\n\n const results: TimingResult[] = [];\n\n for (const [name, { timer, count, parallelism }] of this.phases.entries()) {\n const duration = timer.getDuration();\n const result: TimingResult = {\n name,\n duration,\n count,\n };\n\n if (count && count > 0 && parallelism && parallelism > 1) {\n const batches = Math.ceil(count / parallelism);\n const avgTimePerBatch = duration / batches;\n const theoreticalSequentialTime = count * avgTimePerBatch;\n result.efficiency =\n theoreticalSequentialTime > 0 ? Math.round((theoreticalSequentialTime / duration) * 100) : 100;\n }\n\n results.push(result);\n }\n\n return results;\n }\n}\n\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${minutes}m ${seconds}s`;\n}\n\nexport function formatTimingTable(totalDuration: number, phaseResults: TimingResult[], repoName?: string): string {\n const header = repoName ? `Performance Summary - [${repoName}]` : \"Performance Summary\";\n\n const table = new Table({\n head: [\"Operation\", \"Duration\", \"Efficiency\"],\n colWidths: [35, 12, 12],\n style: {\n head: [\"cyan\", \"bold\"],\n border: [\"gray\"],\n },\n });\n\n table.push([{ colSpan: 3, content: header, hAlign: \"center\" }]);\n\n table.push([\"Total Sync\", formatDuration(totalDuration), \"\"]);\n\n for (let i = 0; i < phaseResults.length; i++) {\n const result = phaseResults[i];\n const isLast = i === phaseResults.length - 1;\n const countStr = result.count ? ` (${result.count})` : \"\";\n const prefix = isLast ? \"\u2514\u2500\" : \"\u251C\u2500\";\n const name = ` ${prefix} ${result.name}${countStr}`;\n const efficiency = result.efficiency ? `${result.efficiency}%` : \"\";\n\n table.push([name, formatDuration(result.duration), efficiency]);\n }\n\n return table.toString();\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { DEFAULT_CONFIG, ENV_CONSTANTS, PATH_CONSTANTS } from \"../constants\";\nimport { ConfigError } from \"../errors\";\nimport { fileExists } from \"../utils/file-exists\";\nimport { makeGitProgressHandler } from \"../utils/git-progress\";\nimport { normalizeRepoUrlForComparison } from \"../utils/git-url\";\nimport { getErrorMessage, isLfsError, isMissingRemoteRefError } from \"../utils/lfs-error\";\n\nimport { BranchCreatedActionsService } from \"./branch-created-actions.service\";\nimport { cloneSkipToOutcomeAction } from \"./sync-outcome\";\n\nimport type { GitService } from \"./git.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { SyncOutcomeAccumulator } from \"./sync-outcome\";\nimport type { Config, RepositoryConfig } from \"../types\";\nimport type { GitProgressEmitter, GitProgressEvent } from \"../utils/git-progress\";\nimport type { SimpleGit, SimpleGitOptions } from \"simple-git\";\n\nconst ALL_REMOTE_BRANCHES_REFSPEC = \"+refs/heads/*:refs/remotes/origin/*\";\nconst SHALLOW_RELATION_DEEPEN_TARGETS = [50, 200, 1000] as const;\n\nexport type CloneSkipReason =\n | { kind: \"branch_mismatch\"; phase: \"init\" | \"sync\"; currentBranch: string; expectedBranch: string }\n | { kind: \"head_unreadable\"; phase: \"init\" | \"sync\"; error: string }\n | { kind: \"dirty_tree\" }\n | { kind: \"diverged\"; branch: string }\n | { kind: \"ahead_unpushed\"; branch: string }\n | { kind: \"missing_remote_ref\"; branch: string; source: \"fetch_error\" | \"post_fetch_verify\" }\n | { kind: \"indeterminate_shallow\"; branch: string; deepenedTo: number | null }\n | { kind: \"origin_mismatch\"; actual: string; expected: string };\n\nexport type CloneSkipListener = (reason: CloneSkipReason) => void;\n\nexport class CloneSyncService {\n private initialized = false;\n private resolvedBranch: string | null = null;\n private branchCreatedActions: BranchCreatedActionsService;\n private progressEmitter?: GitProgressEmitter;\n private onSkip?: CloneSkipListener;\n private outcomeAccumulator?: SyncOutcomeAccumulator;\n // One-shot suppression token. When init records a wrong-branch / unreadable-HEAD\n // skip for an existing clone, it sets this so the immediately following\n // runSyncAttempt (same sync operation) does not record the identical skip again.\n private pendingInitSkip: CloneSkipReason | null = null;\n\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger,\n options: {\n branchCreatedActions?: BranchCreatedActionsService;\n progressEmitter?: GitProgressEmitter;\n onSkip?: CloneSkipListener;\n } = {},\n ) {\n this.branchCreatedActions = options.branchCreatedActions ?? new BranchCreatedActionsService();\n this.progressEmitter = options.progressEmitter;\n this.onSkip = options.onSkip;\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n clearPendingInitSkip(): void {\n this.pendingInitSkip = null;\n }\n\n async getWorktrees(): Promise<Array<{ path: string; branch: string }>> {\n const worktreeDir = path.resolve(this.config.worktreeDir);\n if (!(await fileExists(path.join(worktreeDir, PATH_CONSTANTS.GIT_DIR)))) {\n return [];\n }\n\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n let branch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n\n if (!branch || branch === \"HEAD\") {\n const head = (await git.raw([\"rev-parse\", \"--short\", \"HEAD\"])).trim();\n branch = head ? `(detached ${head})` : \"(detached)\";\n }\n\n return [{ path: worktreeDir, branch }];\n }\n\n private get repoName(): string {\n return (this.config as RepositoryConfig).name ?? this.config.repoUrl;\n }\n\n private getCloneTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.cloneTimeoutMs ?? DEFAULT_CONFIG.CLONE_TIMEOUT_MS;\n }\n\n private getFetchTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.fetchTimeoutMs ?? DEFAULT_CONFIG.FETCH_TIMEOUT_MS;\n }\n\n private isLfsSkipEnabled(): boolean {\n return this.config.skipLfs === true;\n }\n\n private buildGitOptions(blockMs: number): Partial<SimpleGitOptions> {\n const options: Partial<SimpleGitOptions> = {\n progress: makeGitProgressHandler(this.logger, (event) => this.emitProgress(event)),\n };\n if (blockMs > 0) options.timeout = { block: blockMs };\n return options;\n }\n\n private emitProgress(event: GitProgressEvent): void {\n try {\n this.progressEmitter?.(event);\n } catch {\n // progress listeners must not break sync flow\n }\n }\n\n private async withOutcome<T>(outcome: SyncOutcomeAccumulator | undefined, operation: () => Promise<T>): Promise<T> {\n const previousOutcome = this.outcomeAccumulator;\n if (outcome) {\n this.outcomeAccumulator = outcome;\n }\n\n try {\n return await operation();\n } finally {\n if (outcome) {\n this.outcomeAccumulator = previousOutcome;\n }\n }\n }\n\n private recordSkip(\n reason: CloneSkipReason,\n logMessage: string,\n progressMessage?: string,\n logLevel: \"warn\" | \"info\" = \"warn\",\n ): void {\n if (logLevel === \"warn\") {\n this.logger.warn(logMessage);\n } else {\n this.logger.info(logMessage);\n }\n this.emitProgress({ phase: \"skip\", message: progressMessage ?? logMessage });\n try {\n this.onSkip?.(reason);\n } catch {\n // listeners must not break sync flow\n }\n this.outcomeAccumulator?.add(\n cloneSkipToOutcomeAction(reason, {\n branch: this.resolvedBranch ?? this.config.branch,\n path: this.config.worktreeDir,\n }),\n );\n }\n\n private clientFor(dir: string, blockMs: number): SimpleGit {\n return simpleGit(dir, this.buildGitOptions(blockMs)).env(this.buildGitEnv());\n }\n\n // Force a stable C locale so git's stderr is deterministic English. The\n // missing-remote-ref and LFS error classification matches on those strings\n // and would otherwise misfire under a non-English LANG/LC_ALL. simple-git's\n // .env() merges this object with process.env (PATH etc. preserved).\n private buildGitEnv(opts: { forceLfsSkip?: boolean } = {}): Record<string, string> {\n const env: Record<string, string> = { LC_ALL: \"C\", LANG: \"C\" };\n if (opts.forceLfsSkip || this.isLfsSkipEnabled()) {\n env[ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE] = \"1\";\n }\n return env;\n }\n\n private buildCloneArgs(branch: string): string[] {\n const args = [\"--branch\", branch, \"--progress\"];\n if (this.config.depth !== undefined) {\n args.push(\"--depth\", String(this.config.depth), \"--no-single-branch\");\n }\n return args;\n }\n\n private async buildFetchArgs(git: SimpleGit): Promise<string[]> {\n const args = [\"origin\", \"--prune\", \"--progress\"];\n if (this.config.depth !== undefined && (await this.isShallowRepository(git))) {\n args.push(\"--depth\", String(this.config.depth));\n }\n return args;\n }\n\n private async ensureAllRemoteBranchesRefspec(git: SimpleGit): Promise<void> {\n let fetchRefspecs: string[] = [];\n try {\n const output = await git.raw([\"config\", \"--get-all\", \"remote.origin.fetch\"]);\n fetchRefspecs = output\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean);\n } catch {\n fetchRefspecs = [];\n }\n\n if (fetchRefspecs.includes(ALL_REMOTE_BRANCHES_REFSPEC)) return;\n\n const customRefspecs = fetchRefspecs.filter((refspec) => !this.isOriginRemoteBranchTrackingRefspec(refspec));\n\n this.logger.info(`Configuring '${this.repoName}' to fetch all remote branches from origin.`);\n await git.raw([\"remote\", \"set-branches\", \"origin\", \"*\"]);\n for (const refspec of customRefspecs) {\n await git.raw([\"config\", \"--add\", \"remote.origin.fetch\", refspec]);\n }\n }\n\n private isOriginRemoteBranchTrackingRefspec(refspec: string): boolean {\n const withoutForce = refspec.startsWith(\"+\") ? refspec.slice(1) : refspec;\n if (withoutForce.startsWith(\"^\")) return false;\n\n const [source, destination] = withoutForce.split(\":\");\n return source.startsWith(\"refs/heads/\") && destination?.startsWith(\"refs/remotes/origin/\") === true;\n }\n\n private recordMissingRemoteRefSkip(branch: string): void {\n this.recordSkip(\n { kind: \"missing_remote_ref\", branch, source: \"fetch_error\" },\n `Tracked branch '${branch}' is missing on remote for '${this.repoName}'. Skipping sync.`,\n `Skipping '${this.repoName}': origin/${branch} is missing`,\n );\n }\n\n private async fetchWithRecovery(\n git: SimpleGit,\n fetchArgs: string[],\n worktreeDir: string,\n branch: string,\n ): Promise<{ skipped: boolean }> {\n try {\n await git.fetch(fetchArgs);\n return { skipped: false };\n } catch (fetchError) {\n const message = getErrorMessage(fetchError);\n if (isLfsError(message)) {\n this.logger.info(`\u26A0\uFE0F LFS error during fetch for '${this.repoName}'; retrying with LFS disabled.`);\n this.emitProgress({ phase: \"fetch\", message: `Retrying fetch for '${this.repoName}' with LFS disabled` });\n const lfsSkipGit = simpleGit(worktreeDir, this.buildGitOptions(this.getFetchTimeoutMs())).env(\n this.buildGitEnv({ forceLfsSkip: true }),\n );\n try {\n await lfsSkipGit.fetch(fetchArgs);\n return { skipped: false };\n } catch (retryError) {\n // The LFS-disabled retry can itself hit a deleted remote branch \u2014\n // classify it as a soft skip too, instead of letting it escape as a\n // hard failure.\n if (isMissingRemoteRefError(getErrorMessage(retryError))) {\n this.recordMissingRemoteRefSkip(branch);\n return { skipped: true };\n }\n // Otherwise propagate the retry error unchanged so the outer retry\n // policy's LFS handling still sees an accurate error.\n throw retryError;\n }\n }\n if (isMissingRemoteRefError(message)) {\n this.recordMissingRemoteRefSkip(branch);\n return { skipped: true };\n }\n throw fetchError;\n }\n }\n\n private async hasRemoteBranch(git: SimpleGit, branch: string): Promise<boolean> {\n try {\n // simple-git resolves `show-ref --quiet` even when git exits 1, so keep\n // stdout enabled (no --quiet) to get a real reject on a missing ref \u2014\n // otherwise the post-fetch missing_remote_ref skip would never fire.\n await git.raw([\"show-ref\", \"--verify\", `refs/remotes/origin/${branch}`]);\n return true;\n } catch {\n return false;\n }\n }\n\n private async isShallowRepository(git: SimpleGit): Promise<boolean> {\n try {\n const output = await git.raw([\"rev-parse\", \"--is-shallow-repository\"]);\n return output.trim() === \"true\";\n } catch {\n return false;\n }\n }\n\n private async unshallowIfDepthRemoved(git: SimpleGit): Promise<void> {\n if (this.config.depth !== undefined) return;\n\n if (!(await this.isShallowRepository(git))) return;\n\n this.logger.info(\n `[deepen] Existing shallow clone for '${this.repoName}' has no configured depth; fetching full history...`,\n );\n await git.fetch([\"--unshallow\"]);\n }\n\n private getDeepenTargets(): readonly number[] {\n const configuredDepth = this.config.depth;\n if (configuredDepth === undefined) return [];\n // `git fetch --depth N` can shorten a shallow repo if N is below current depth.\n // Skip targets at or below the configured depth \u2014 they would never widen history.\n return SHALLOW_RELATION_DEEPEN_TARGETS.filter((target) => target > configuredDepth);\n }\n\n private async deepenShallowHistoryToDepth(git: SimpleGit, branch: string, targetDepth: number): Promise<void> {\n this.logger.info(\n `[deepen] Shallow clone for '${this.repoName}' lacks enough history to classify origin/${branch}; ` +\n `refetching to depth ${targetDepth} before deciding.`,\n );\n this.emitProgress({\n phase: \"fetch\",\n message: `Deepening '${this.repoName}' to depth ${targetDepth} before classifying origin/${branch}`,\n });\n await git.fetch([\n \"origin\",\n \"--depth\",\n String(targetDepth),\n \"--prune\",\n \"--progress\",\n `+refs/heads/${branch}:refs/remotes/origin/${branch}`,\n ]);\n }\n\n async resolveBranch(): Promise<string> {\n if (this.resolvedBranch) return this.resolvedBranch;\n if (this.config.branch) {\n this.resolvedBranch = this.config.branch;\n this.emitProgress({ phase: \"branch\", message: `Using configured branch '${this.resolvedBranch}'` });\n return this.resolvedBranch;\n }\n this.logger.info(`No branch configured for '${this.repoName}', detecting remote default branch...`);\n this.emitProgress({ phase: \"branch\", message: `Resolving remote default branch for '${this.repoName}'` });\n this.resolvedBranch = await this.gitService.getRemoteDefaultBranch(this.config.repoUrl);\n this.logger.info(` \u21B3 resolved default branch: ${this.resolvedBranch}`);\n this.emitProgress({ phase: \"branch\", message: `Resolved default branch '${this.resolvedBranch}'` });\n return this.resolvedBranch;\n }\n\n async initialize(outcome?: SyncOutcomeAccumulator): Promise<void> {\n return this.withOutcome(outcome, () => this.initializeInternal());\n }\n\n private async initializeInternal(): Promise<void> {\n this.pendingInitSkip = null;\n const branch = await this.resolveBranch();\n const worktreeDir = this.config.worktreeDir;\n\n let entries: string[] | null = null;\n try {\n entries = await fs.readdir(worktreeDir);\n } catch {\n entries = null;\n }\n\n if (entries?.includes(PATH_CONSTANTS.GIT_DIR)) {\n this.emitProgress({ phase: \"clone\", message: `Validating existing clone for '${this.repoName}'` });\n const result = await this.validateExistingClone(branch);\n if (!result.valid) {\n this.recordSkip(result.skip, result.warnMessage, `Skipping '${this.repoName}': ${result.progressDetail}`);\n this.pendingInitSkip = result.skip;\n this.initialized = true;\n return;\n }\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n await this.ensureAllRemoteBranchesRefspec(git);\n this.initialized = true;\n this.emitProgress({ phase: \"clone\", message: `Existing clone validated for '${this.repoName}'` });\n return;\n }\n\n if (entries && entries.length > 0) {\n throw new ConfigError(\n `Cannot clone into '${worktreeDir}': directory exists and is not empty. ` +\n `Remove existing contents or point worktreeDir at an empty path.`,\n \"CLONE_DESTINATION_NOT_EMPTY\",\n );\n }\n\n const cloneCreatedDir = entries === null;\n await fs.mkdir(worktreeDir, { recursive: true });\n\n this.logger.info(`Cloning '${this.config.repoUrl}' (${branch}) into '${worktreeDir}'...`);\n this.emitProgress({ phase: \"clone\", message: `Cloning '${this.repoName}' (${branch})` });\n\n const cloneClient = simpleGit(this.buildGitOptions(this.getCloneTimeoutMs())).env(this.buildGitEnv());\n\n try {\n await cloneClient.clone(this.config.repoUrl, worktreeDir, this.buildCloneArgs(branch));\n } catch (error) {\n await this.maybeCleanupPartialClone(worktreeDir, cloneCreatedDir);\n this.outcomeAccumulator?.recordFailed(\"repo\", getErrorMessage(error), {\n reason: \"clone_failed\",\n branch,\n path: worktreeDir,\n });\n throw error;\n }\n\n const worktreeGit = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n await this.ensureAllRemoteBranchesRefspec(worktreeGit);\n\n this.logger.info(`\u2705 Clone successful.`);\n this.emitProgress({ phase: \"clone\", message: `Clone successful for '${this.repoName}'` });\n\n if (this.config.sparseCheckout) {\n this.logger.info(`Applying sparse-checkout patterns to '${worktreeDir}'...`);\n this.emitProgress({ phase: \"sparse_checkout\", message: `Applying sparse-checkout for '${this.repoName}'` });\n const sparseService = this.gitService.getSparseCheckoutService();\n await sparseService.applyToWorktree(worktreeDir, this.config.sparseCheckout);\n await worktreeGit.raw([\"checkout\", \"HEAD\"]);\n this.emitProgress({ phase: \"sparse_checkout\", message: `Sparse-checkout applied for '${this.repoName}'` });\n }\n\n this.emitProgress({ phase: \"lfs\", message: `Verifying LFS for '${this.repoName}'` });\n await this.gitService.verifyLfs(worktreeDir, branch);\n this.emitProgress({ phase: \"lfs\", message: `LFS verified for '${this.repoName}'` });\n\n await this.runInitialFileCopy(worktreeDir, branch);\n\n // Only record `created` once init is fully complete; otherwise an aborted\n // post-clone step would leave the outcome reporting both created and failed.\n this.outcomeAccumulator?.recordCreated(branch, worktreeDir);\n this.initialized = true;\n }\n\n // Detects an on-disk clone whose `origin` no longer matches the configured\n // repoUrl (e.g. repoUrl was repointed in config). Returns a skip descriptor so\n // we never fetch/ff-merge from the wrong remote; null when origin matches or\n // can't be read. Comparison is normalized so https/.git/trailing-slash\n // variants don't false-positive; the raw URLs are kept in the message.\n private async evaluateOriginMatch(\n git: SimpleGit,\n worktreeDir: string,\n ): Promise<{ skip: CloneSkipReason; warnMessage: string; progressDetail: string } | null> {\n let originUrl: string;\n try {\n originUrl = (await git.raw([\"remote\", \"get-url\", \"origin\"])).trim();\n } catch {\n this.logger.warn(`Could not read 'origin' remote URL from existing clone at '${worktreeDir}'.`);\n return null;\n }\n\n if (!originUrl || normalizeRepoUrlForComparison(originUrl) === normalizeRepoUrlForComparison(this.config.repoUrl)) {\n return null;\n }\n\n return {\n skip: { kind: \"origin_mismatch\", actual: originUrl, expected: this.config.repoUrl },\n warnMessage:\n `Existing clone at '${worktreeDir}' has origin '${originUrl}', expected '${this.config.repoUrl}'. ` +\n `Update the remote ('git remote set-url origin <url>') or point worktreeDir at a fresh path.`,\n progressDetail: `origin '${originUrl}' is not '${this.config.repoUrl}'`,\n };\n }\n\n private async validateExistingClone(\n expectedBranch: string,\n ): Promise<{ valid: true } | { valid: false; skip: CloneSkipReason; warnMessage: string; progressDetail: string }> {\n const worktreeDir = this.config.worktreeDir;\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n\n const originMismatch = await this.evaluateOriginMatch(git, worktreeDir);\n if (originMismatch) {\n return { valid: false, ...originMismatch };\n }\n\n let currentBranch: string;\n try {\n currentBranch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n return {\n valid: false,\n skip: { kind: \"head_unreadable\", phase: \"init\", error: errorMessage },\n warnMessage: `Existing clone at '${worktreeDir}' has a .git folder but reading HEAD failed: ${errorMessage}`,\n progressDetail: `could not read HEAD (${errorMessage})`,\n };\n }\n\n if (currentBranch !== expectedBranch) {\n return {\n valid: false,\n skip: {\n kind: \"branch_mismatch\",\n phase: \"init\",\n currentBranch,\n expectedBranch,\n },\n warnMessage:\n `Existing clone at '${worktreeDir}' is on branch '${currentBranch}', expected '${expectedBranch}'. ` +\n `Switch the working tree to '${expectedBranch}' or update the config.`,\n progressDetail: `current branch '${currentBranch}' is not '${expectedBranch}'`,\n };\n }\n\n return { valid: true };\n }\n\n private async maybeCleanupPartialClone(worktreeDir: string, cloneCreatedDir: boolean): Promise<void> {\n if (!cloneCreatedDir) {\n this.logger.warn(\n `Clone failed; leaving '${worktreeDir}' for manual inspection (directory existed before clone attempt).`,\n );\n return;\n }\n\n let entries: string[];\n try {\n entries = await fs.readdir(worktreeDir);\n } catch {\n return;\n }\n\n const looksIncomplete = entries.every((e) => e.startsWith(\".\"));\n const hasUsableGit =\n entries.includes(PATH_CONSTANTS.GIT_DIR) &&\n (await fileExists(path.join(worktreeDir, PATH_CONSTANTS.GIT_DIR, \"HEAD\")));\n\n if (looksIncomplete && !hasUsableGit) {\n try {\n await fs.rm(worktreeDir, { recursive: true, force: true });\n this.logger.info(`Cleaned up incomplete clone at '${worktreeDir}'.`);\n } catch (rmError) {\n this.logger.warn(`Failed to clean up incomplete clone at '${worktreeDir}': ${getErrorMessage(rmError)}`);\n }\n } else {\n this.logger.warn(\n `Clone failed; leaving '${worktreeDir}' for manual inspection (post-failure contents do not look like an empty incomplete clone).`,\n );\n }\n }\n\n private getInitMarkerPath(worktreeDir: string): string {\n return path.join(worktreeDir, PATH_CONSTANTS.GIT_DIR, PATH_CONSTANTS.CLONE_INIT_MARKER);\n }\n\n private async runInitialFileCopy(worktreeDir: string, branch: string): Promise<void> {\n const marker = this.getInitMarkerPath(worktreeDir);\n if (await fileExists(marker)) {\n return;\n }\n\n const sourceDir = this.config.__configFileDir ?? worktreeDir;\n\n await this.branchCreatedActions.copyFiles({\n config: this.config,\n branchName: branch,\n worktreePath: worktreeDir,\n sourceDir,\n logger: this.logger,\n });\n\n try {\n await fs.writeFile(marker, new Date().toISOString());\n } catch (error) {\n this.logger.warn(`Could not write clone-init marker: ${getErrorMessage(error)}`);\n }\n }\n\n async runSyncAttempt(outcome?: SyncOutcomeAccumulator): Promise<void> {\n return this.withOutcome(outcome, () => this.runSyncAttemptInternal());\n }\n\n private async runSyncAttemptInternal(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n // init ran here and recorded any skip itself; no duplicate to suppress.\n this.pendingInitSkip = null;\n return;\n }\n\n // If init already recorded a wrong-branch / unreadable-HEAD skip for the\n // current clone state during this same sync operation, don't record it a\n // second time. Consume the one-shot token; later ticks re-evaluate fresh.\n if (this.pendingInitSkip) {\n this.pendingInitSkip = null;\n return;\n }\n\n const branch = await this.resolveBranch();\n const worktreeDir = this.config.worktreeDir;\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n\n let currentBranch: string;\n try {\n currentBranch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n this.recordSkip(\n { kind: \"head_unreadable\", phase: \"sync\", error: errorMessage },\n `Could not read current branch from '${worktreeDir}': ${errorMessage}`,\n `Skipping '${this.repoName}': could not read current branch`,\n );\n return;\n }\n\n if (currentBranch !== branch) {\n this.recordSkip(\n { kind: \"branch_mismatch\", phase: \"sync\", currentBranch, expectedBranch: branch },\n `Clone at '${worktreeDir}' is on '${currentBranch}', expected '${branch}'. Skipping fetch+merge.`,\n `Skipping '${this.repoName}': current branch '${currentBranch}' is not '${branch}'`,\n );\n return;\n }\n\n // Re-check every tick (not just at init): the daemon reuses this service, so\n // a clone whose origin no longer matches repoUrl must keep being skipped\n // rather than fetching from the wrong remote.\n const originMismatch = await this.evaluateOriginMatch(git, worktreeDir);\n if (originMismatch) {\n this.recordSkip(\n originMismatch.skip,\n originMismatch.warnMessage,\n `Skipping '${this.repoName}': ${originMismatch.progressDetail}`,\n );\n return;\n }\n\n await this.unshallowIfDepthRemoved(git);\n\n await this.ensureAllRemoteBranchesRefspec(git);\n\n const fetchArgs = await this.buildFetchArgs(git);\n this.emitProgress({ phase: \"fetch\", message: `Fetching origin branches for '${this.repoName}'` });\n if ((await this.fetchWithRecovery(git, fetchArgs, worktreeDir, branch)).skipped) {\n return;\n }\n this.emitProgress({ phase: \"fetch\", message: `Fetched origin branches for '${this.repoName}'` });\n\n if (!(await this.hasRemoteBranch(git, branch))) {\n this.recordSkip(\n { kind: \"missing_remote_ref\", branch, source: \"post_fetch_verify\" },\n `Tracked branch '${branch}' is missing on remote for '${this.repoName}'. Skipping sync.`,\n `Skipping '${this.repoName}': origin/${branch} is missing`,\n );\n return;\n }\n\n if (this.config.sparseCheckout) {\n const sparseService = this.gitService.getSparseCheckoutService();\n try {\n if (await sparseService.needsUpdate(worktreeDir, this.config.sparseCheckout)) {\n this.emitProgress({ phase: \"sparse_checkout\", message: `Updating sparse-checkout for '${this.repoName}'` });\n await sparseService.applyToWorktree(worktreeDir, this.config.sparseCheckout);\n this.emitProgress({ phase: \"sparse_checkout\", message: `Sparse-checkout updated for '${this.repoName}'` });\n }\n } catch (error) {\n this.logger.warn(`Failed to reapply sparse-checkout for '${this.repoName}': ${getErrorMessage(error)}`);\n }\n }\n\n const isClean = await this.gitService.checkWorktreeStatus(worktreeDir);\n if (!isClean) {\n this.recordSkip(\n { kind: \"dirty_tree\" },\n `\u23ED\uFE0F Skipping ff-merge for '${this.repoName}' \u2014 working tree has local changes.`,\n `Skipping merge for '${this.repoName}': working tree has local changes`,\n \"info\",\n );\n return;\n }\n\n let relationship = await this.gitService.classifyRemoteRelationship(worktreeDir, branch);\n let lastDeepenedTo: number | null = null;\n if (relationship === \"indeterminate_shallow\") {\n for (const target of this.getDeepenTargets()) {\n await this.deepenShallowHistoryToDepth(git, branch, target);\n lastDeepenedTo = target;\n relationship = await this.gitService.classifyRemoteRelationship(worktreeDir, branch);\n if (relationship !== \"indeterminate_shallow\") break;\n }\n }\n\n if (relationship === \"up_to_date\") {\n this.logger.info(`'${this.repoName}' already up to date with origin/${branch}.`);\n this.emitProgress({\n phase: \"skip\",\n message: `'${this.repoName}' already up to date with origin/${branch}`,\n });\n this.outcomeAccumulator?.recordNoop(\"repo\", \"already_up_to_date\", {\n branch,\n path: worktreeDir,\n message: `Already up to date with origin/${branch}`,\n });\n return;\n }\n\n if (relationship !== \"fast_forward\") {\n if (relationship === \"local_ahead\") {\n this.recordSkip(\n { kind: \"ahead_unpushed\", branch },\n `\u23ED\uFE0F '${this.repoName}' has unpushed commits ahead of origin/${branch}. Skipping merge.`,\n `Skipping merge for '${this.repoName}': unpushed commits ahead of origin/${branch}`,\n \"info\",\n );\n } else if (relationship === \"indeterminate_shallow\") {\n const detail =\n lastDeepenedTo === null\n ? `no deepening attempted (configured depth already at or above all deepen targets)`\n : `deepening to ${lastDeepenedTo} commits`;\n const progressDetail =\n lastDeepenedTo === null\n ? `no deepening attempted (configured depth at/above limits)`\n : `shallow depth budget exhausted at ${lastDeepenedTo}`;\n this.recordSkip(\n { kind: \"indeterminate_shallow\", branch, deepenedTo: lastDeepenedTo },\n `\u23ED\uFE0F '${this.repoName}' could not classify origin/${branch} after ${detail}. ` +\n `Skipping merge \u2014 consider removing or raising 'depth' to unshallow.`,\n `Skipping merge for '${this.repoName}': ${progressDetail}`,\n \"info\",\n );\n } else {\n this.recordSkip(\n { kind: \"diverged\", branch },\n `\u23ED\uFE0F '${this.repoName}' has diverged from origin/${branch}. Skipping merge (no auto-reset).`,\n `Skipping merge for '${this.repoName}': diverged from origin/${branch}`,\n \"info\",\n );\n }\n return;\n }\n\n this.logger.info(`Fast-forwarding '${this.repoName}' to origin/${branch}...`);\n this.emitProgress({ phase: \"merge\", message: `Fast-forwarding '${this.repoName}' to origin/${branch}` });\n await git.merge([`origin/${branch}`, \"--ff-only\"]);\n this.logger.info(`\u2705 Updated '${this.repoName}' to origin/${branch}.`);\n this.emitProgress({ phase: \"merge\", message: `Updated '${this.repoName}' to origin/${branch}` });\n this.outcomeAccumulator?.recordUpdated(branch, worktreeDir, \"fast_forward\");\n }\n}\n", "import { GIT_CONSTANTS } from \"../constants\";\n\nimport type { Logger } from \"../services/logger.service\";\nimport type { SimpleGitProgressEvent } from \"simple-git\";\n\nexport interface GitProgressEvent {\n phase: string;\n message: string;\n progress?: number;\n processed?: number;\n total?: number;\n}\n\nexport type GitProgressEmitter = (event: GitProgressEvent) => void;\n\n/**\n * Build a progress callback for simple-git's `progress` option that:\n * - filters to clone/fetch/pull events only,\n * - emits at most one progress event per (method,stage) bucket of PROGRESS_BUCKET_PERCENT,\n * - always emits the 100% completion event,\n * - detects stage restarts (bucket regression on the same cached SimpleGit\n * instance, e.g. a second fetch) and resets the bucket so the new run\n * emits from scratch.\n *\n * State (the bucket map) is closure-local \u2014 pass one handler per SimpleGit\n * client. Keep progress logs at debug level so normal logs can stay readable\n * while interactive surfaces and MCP notifications consume structured events.\n */\nexport function makeGitProgressHandler(\n logger: Logger,\n emitProgress?: GitProgressEmitter,\n): (event: SimpleGitProgressEvent) => void {\n const lastBucket = new Map<string, number>();\n return (event: SimpleGitProgressEvent): void => {\n if (event.method !== \"fetch\" && event.method !== \"clone\" && event.method !== \"pull\") return;\n const key = `${event.method}:${event.stage}`;\n const bucket = Math.floor(event.progress / GIT_CONSTANTS.PROGRESS_BUCKET_PERCENT);\n let last = lastBucket.get(key) ?? -1;\n if (bucket < last) last = -1;\n if (bucket <= last && event.progress < 100) return;\n lastBucket.set(key, bucket);\n const total = event.total > 0 ? `${event.processed}/${event.total}` : `${event.processed}`;\n const message = `${event.method} ${event.stage}: ${event.progress}% (${total})`;\n logger.debug(` \u21B3 ${message}`);\n emitProgress?.({\n phase: event.method,\n message,\n progress: event.progress,\n processed: event.processed,\n total: event.total,\n });\n };\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport { glob } from \"glob\";\n\nimport { fileExists } from \"../utils/file-exists\";\n\nconst DEFAULT_IGNORE_PATTERNS = [\n \"**/node_modules/**\",\n \"**/.git/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/.next/**\",\n \"**/coverage/**\",\n];\n\nexport interface FileCopyResult {\n copied: string[];\n skipped: string[];\n errors: Array<{ file: string; error: string }>;\n}\n\nexport class FileCopyService {\n /**\n * Copy files matching patterns from source to destination directory.\n * Skips files that already exist at destination.\n * Preserves directory structure relative to source.\n */\n async copyFiles(sourceDir: string, destDir: string, patterns: string[]): Promise<FileCopyResult> {\n const result: FileCopyResult = {\n copied: [],\n skipped: [],\n errors: [],\n };\n\n if (!patterns || patterns.length === 0) {\n return result;\n }\n\n const filesToCopy = await this.expandPatterns(sourceDir, patterns);\n\n for (const relativePath of filesToCopy) {\n const sourcePath = path.join(sourceDir, relativePath);\n const destPath = path.join(destDir, relativePath);\n\n try {\n const copied = await this.copyFile(sourcePath, destPath);\n if (copied) {\n result.copied.push(relativePath);\n } else {\n result.skipped.push(relativePath);\n }\n } catch (error) {\n result.errors.push({\n file: relativePath,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return result;\n }\n\n private async expandPatterns(sourceDir: string, patterns: string[]): Promise<string[]> {\n const allFiles = new Set<string>();\n\n for (const pattern of patterns) {\n try {\n const matches = await glob(pattern, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n ignore: DEFAULT_IGNORE_PATTERNS,\n });\n\n for (const match of matches) {\n allFiles.add(match);\n }\n } catch {\n // Pattern matching failed, skip silently\n }\n }\n\n return Array.from(allFiles);\n }\n\n private async copyFile(sourcePath: string, destPath: string): Promise<boolean> {\n if (await fileExists(destPath)) {\n return false;\n }\n\n const destDir = path.dirname(destPath);\n await fs.mkdir(destDir, { recursive: true });\n\n await fs.copyFile(sourcePath, destPath);\n return true;\n }\n}\n", "import { FileCopyService } from \"./file-copy.service\";\n\nimport type { HookExecutionService } from \"./hook-execution.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { Config, HookContext } from \"../types\";\n\nexport interface CopyFilesParams {\n config: Pick<Config, \"filesToCopyOnBranchCreate\">;\n branchName: string;\n worktreePath: string;\n sourceDir: string;\n logger: Logger;\n}\n\nexport interface RunHooksParams {\n config: Pick<Config, \"hooks\" | \"repoUrl\">;\n repoName: string;\n branchName: string;\n worktreePath: string;\n baseBranch: string;\n logger: Logger;\n hookExecutionService: HookExecutionService;\n}\n\nexport class BranchCreatedActionsService {\n private fileCopyService: FileCopyService;\n\n constructor(fileCopyService?: FileCopyService) {\n this.fileCopyService = fileCopyService ?? new FileCopyService();\n }\n\n async copyFiles(params: CopyFilesParams): Promise<void> {\n const { config, sourceDir, worktreePath, branchName, logger } = params;\n const patterns = config.filesToCopyOnBranchCreate;\n if (!patterns?.length) return;\n\n try {\n const result = await this.fileCopyService.copyFiles(sourceDir, worktreePath, patterns);\n\n if (result.copied.length > 0) {\n logger.info(`\uD83D\uDCCB Copied ${result.copied.length} file(s) to '${branchName}': ${result.copied.join(\", \")}`);\n }\n if (result.errors.length > 0) {\n logger.warn(`\u26A0\uFE0F Failed to copy ${result.errors.length} file(s) to '${branchName}':`);\n for (const err of result.errors) {\n logger.warn(` - ${err.file}: ${err.error}`);\n }\n }\n } catch (error) {\n logger.error(`Failed to copy files to '${branchName}': ${error}`);\n }\n }\n\n runHooks(params: RunHooksParams): void {\n const { config, branchName, worktreePath, repoName, baseBranch, logger, hookExecutionService } = params;\n if (!config.hooks?.onBranchCreated?.length) return;\n\n const context: HookContext = {\n branchName,\n worktreePath,\n repoName,\n baseBranch,\n repoUrl: config.repoUrl,\n };\n\n logger.info(`Running ${config.hooks.onBranchCreated.length} hook(s) for branch '${branchName}'...`);\n\n hookExecutionService.executeOnBranchCreated(config.hooks, context, {\n onStdout: (data) => logger.info(`[hook] ${data}`),\n onStderr: (data) => logger.warn(`[hook] ${data}`),\n onError: (command, error) => logger.error(`[hook] Failed to execute '${command}': ${error.message}`),\n onComplete: (command, exitCode) => {\n if (exitCode === 0) {\n logger.info(`[hook] Command completed successfully`);\n } else if (exitCode !== null) {\n logger.warn(`[hook] Command exited with code ${exitCode}`);\n }\n },\n });\n }\n}\n", "import type { CloneSkipReason } from \"../services/clone-sync.service\";\n\nexport function formatCloneSkipReason(reason: CloneSkipReason): string {\n switch (reason.kind) {\n case \"branch_mismatch\":\n return reason.phase === \"init\"\n ? `clone is on '${reason.currentBranch}', expected '${reason.expectedBranch}' (since process start)`\n : `clone is on '${reason.currentBranch}', expected '${reason.expectedBranch}'`;\n case \"head_unreadable\":\n return `could not read HEAD: ${reason.error}`;\n case \"dirty_tree\":\n return `working tree has local changes`;\n case \"diverged\":\n return `diverged from origin/${reason.branch}`;\n case \"ahead_unpushed\":\n return `unpushed commits ahead of origin/${reason.branch}`;\n case \"missing_remote_ref\":\n return reason.source === \"fetch_error\"\n ? `origin/${reason.branch} missing on remote (fetch error)`\n : `origin/${reason.branch} pruned after fetch`;\n case \"indeterminate_shallow\":\n return reason.deepenedTo === null\n ? `unable to classify origin/${reason.branch} (no deepening attempted \u2014 configured depth already at or above all deepen targets) \u2014 remove 'depth' to unshallow`\n : `unable to classify origin/${reason.branch} after deepening shallow history to ${reason.deepenedTo} commits \u2014 remove or raise 'depth' to unshallow`;\n case \"origin_mismatch\":\n return `clone origin is '${reason.actual}', expected '${reason.expected}'`;\n default: {\n const _exhaustive: never = reason;\n return _exhaustive;\n }\n }\n}\n", "import { formatCloneSkipReason } from \"../utils/clone-skip-format\";\n\nimport type { CloneSkipReason } from \"./clone-sync.service\";\nimport type { SyncOutcome, SyncOutcomeAction, SyncOutcomeCounts, SyncOutcomeMode, SyncOutcomeScope } from \"../types\";\n\nconst EMPTY_COUNTS: SyncOutcomeCounts = {\n created: 0,\n removed: 0,\n updated: 0,\n skipped: 0,\n preserved: 0,\n failed: 0,\n noop: 0,\n};\n\nfunction cloneCounts(counts: SyncOutcomeCounts): SyncOutcomeCounts {\n return { ...counts };\n}\n\nfunction cloneAction(action: SyncOutcomeAction): SyncOutcomeAction {\n return { ...action } as SyncOutcomeAction;\n}\n\nfunction countKeyFor(action: SyncOutcomeAction): keyof SyncOutcomeCounts {\n switch (action.kind) {\n case \"created\":\n return \"created\";\n case \"removed\":\n return \"removed\";\n case \"updated\":\n return \"updated\";\n case \"skipped\":\n return \"skipped\";\n case \"preserved-diverged\":\n return \"preserved\";\n case \"failed\":\n return \"failed\";\n case \"noop\":\n return \"noop\";\n default: {\n const _exhaustive: never = action;\n return _exhaustive;\n }\n }\n}\n\nexport class SyncOutcomeAccumulator {\n private counts: SyncOutcomeCounts = cloneCounts(EMPTY_COUNTS);\n private actions: SyncOutcomeAction[] = [];\n\n constructor(\n private readonly options: {\n mode: SyncOutcomeMode;\n repoName?: string;\n },\n ) {}\n\n add(action: SyncOutcomeAction): void {\n this.actions.push(action);\n this.counts[countKeyFor(action)]++;\n }\n\n recordCreated(branch: string, path: string): void {\n this.add({ kind: \"created\", branch, path });\n }\n\n recordRemoved(branch: string, path: string): void {\n this.add({ kind: \"removed\", branch, path });\n }\n\n recordUpdated(branch: string, path: string, reason?: string): void {\n this.add({ kind: \"updated\", branch, path, reason });\n }\n\n recordNoop(\n scope: SyncOutcomeScope,\n reason: string,\n details: { branch?: string; path?: string; message?: string },\n ): void {\n this.add({ kind: \"noop\", scope, reason, ...details });\n }\n\n recordSkipped(\n scope: SyncOutcomeScope,\n reason: string,\n details: { branch?: string; path?: string; message?: string },\n ): void {\n this.add({ kind: \"skipped\", scope, reason, ...details });\n }\n\n recordPreservedDiverged(branch: string, path: string, preservedPath: string): void {\n this.add({ kind: \"preserved-diverged\", branch, path, preservedPath });\n }\n\n recordFailed(\n scope: SyncOutcomeScope,\n error: string,\n details: { reason?: string; branch?: string; path?: string } = {},\n ): void {\n this.add({ kind: \"failed\", scope, error, ...details });\n }\n\n getCounts(): SyncOutcomeCounts {\n return cloneCounts(this.counts);\n }\n\n snapshot(): { counts: SyncOutcomeCounts; actions: SyncOutcomeAction[] } {\n return {\n counts: cloneCounts(this.counts),\n actions: this.actions.map(cloneAction),\n };\n }\n\n restore(snapshot: { counts: SyncOutcomeCounts; actions: SyncOutcomeAction[] }): void {\n this.counts = cloneCounts(snapshot.counts);\n this.actions = snapshot.actions.map(cloneAction);\n }\n\n toOutcome(durationMs?: number): SyncOutcome {\n return {\n repoName: this.options.repoName,\n mode: this.options.mode,\n started: true,\n counts: cloneCounts(this.counts),\n actions: this.actions.map(cloneAction),\n durationMs,\n };\n }\n}\n\nexport function createEmptySyncOutcome(mode: SyncOutcomeMode, repoName?: string, durationMs?: number): SyncOutcome {\n return {\n repoName,\n mode,\n started: true,\n counts: cloneCounts(EMPTY_COUNTS),\n actions: [],\n durationMs,\n };\n}\n\nexport function cloneSkipToOutcomeAction(\n reason: CloneSkipReason,\n details: { branch?: string; path?: string } = {},\n): SyncOutcomeAction {\n const message = formatCloneSkipReason(reason);\n const branch =\n \"branch\" in reason ? reason.branch : reason.kind === \"branch_mismatch\" ? reason.expectedBranch : details.branch;\n\n return {\n kind: \"skipped\",\n scope: \"repo\",\n reason: `clone_${reason.kind}`,\n branch,\n path: details.path,\n message,\n };\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { DEFAULT_CONFIG, ENV_CONSTANTS, GIT_CONSTANTS } from \"../constants\";\nimport { WorktreeError } from \"../errors\";\nimport { makeGitProgressHandler } from \"../utils/git-progress\";\nimport { getDefaultBareRepoDir } from \"../utils/git-url\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\nimport { parseWorktreeListPorcelain } from \"../utils/worktree-list-parser\";\n\nimport { Logger } from \"./logger.service\";\nimport { SparseCheckoutService } from \"./sparse-checkout.service\";\nimport { WorktreeMetadataService } from \"./worktree-metadata.service\";\nimport { WorktreeStatusService } from \"./worktree-status.service\";\n\nimport type { WorktreeStatusResult } from \"./worktree-status.service\";\nimport type { Config } from \"../types\";\nimport type { SyncMetadata } from \"../types/sync-metadata\";\nimport type { GitProgressEmitter } from \"../utils/git-progress\";\nimport type { SimpleGit, SimpleGitOptions } from \"simple-git\";\n\nexport type RemoteRelationship = \"up_to_date\" | \"fast_forward\" | \"local_ahead\" | \"diverged\" | \"indeterminate_shallow\";\n\nexport type GitServiceOptions = Pick<\n Config,\n | \"repoUrl\"\n | \"worktreeDir\"\n | \"bareRepoDir\"\n | \"skipLfs\"\n | \"debug\"\n | \"sparseCheckout\"\n | \"fetchTimeoutMs\"\n | \"cloneTimeoutMs\"\n>;\n\n// simple-git blocks EDITOR / GIT_EDITOR / GIT_SEQUENCE_EDITOR unless allowUnsafeEditor is set;\n// strip them when forwarding process.env so a user's shell EDITOR doesn't break read-only commands.\nfunction sanitizeGitEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n const sanitized = { ...env };\n delete sanitized.EDITOR;\n delete sanitized.GIT_EDITOR;\n delete sanitized.GIT_SEQUENCE_EDITOR;\n return sanitized;\n}\n\nexport class GitService {\n private git: SimpleGit | null = null;\n private bareRepoPath: string;\n private mainWorktreePath: string;\n private defaultBranch: string = GIT_CONSTANTS.DEFAULT_BRANCH; // Will be updated after detection\n private metadataService: WorktreeMetadataService;\n private statusService: WorktreeStatusService;\n private sparseCheckoutService: SparseCheckoutService;\n private logger: Logger;\n private lfsSkipOverride = false;\n private gitInstances = new Map<string, SimpleGit>();\n\n constructor(\n private config: GitServiceOptions,\n logger?: Logger,\n private progressEmitter?: GitProgressEmitter,\n ) {\n this.logger = logger ?? Logger.createDefault(undefined, config.debug);\n this.bareRepoPath = this.config.bareRepoDir || getDefaultBareRepoDir(this.config.repoUrl);\n this.mainWorktreePath = path.join(this.config.worktreeDir, GIT_CONSTANTS.DEFAULT_BRANCH); // Temporary, will be updated\n this.metadataService = new WorktreeMetadataService(this.logger);\n this.statusService = new WorktreeStatusService({ skipLfs: this.config.skipLfs }, this.logger);\n this.sparseCheckoutService = new SparseCheckoutService(this.logger);\n }\n\n getSparseCheckoutService(): SparseCheckoutService {\n return this.sparseCheckoutService;\n }\n\n private getFetchTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.fetchTimeoutMs ?? DEFAULT_CONFIG.FETCH_TIMEOUT_MS;\n }\n\n private getCloneTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.cloneTimeoutMs ?? DEFAULT_CONFIG.CLONE_TIMEOUT_MS;\n }\n\n private getCachedGit(dirPath: string, useLfsSkip = false): SimpleGit {\n const key = `${path.resolve(dirPath)}::${useLfsSkip ? \"1\" : \"0\"}`;\n let git = this.gitInstances.get(key);\n if (!git) {\n const base = simpleGit(dirPath, this.buildSimpleGitOptions(this.getFetchTimeoutMs()));\n git = useLfsSkip ? base.env({ [ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE]: \"1\" }) : base;\n this.gitInstances.set(key, git);\n }\n return git;\n }\n\n private buildSimpleGitOptions(blockMs: number): Partial<SimpleGitOptions> {\n const options: Partial<SimpleGitOptions> = {\n progress: makeGitProgressHandler(this.logger, (event) => this.progressEmitter?.(event)),\n };\n if (blockMs > 0) options.timeout = { block: blockMs };\n return options;\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n this.sparseCheckoutService.updateLogger(logger);\n }\n\n async initialize(): Promise<SimpleGit> {\n const { repoUrl } = this.config;\n\n try {\n // Check if bare repo already exists\n await fs.access(path.join(this.bareRepoPath, \"HEAD\"));\n } catch {\n // Clone as bare repository\n this.logger.info(`Cloning from \"${repoUrl}\" as bare repository into \"${this.bareRepoPath}\"...`);\n await fs.mkdir(path.dirname(this.bareRepoPath), { recursive: true });\n const cloneBase = simpleGit(this.buildSimpleGitOptions(this.getCloneTimeoutMs()));\n const cloneGit = this.isLfsSkipEnabled()\n ? cloneBase.env({ [ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE]: \"1\" })\n : cloneBase;\n await cloneGit.clone(repoUrl, this.bareRepoPath, [\"--bare\", \"--progress\"]);\n this.logger.info(\"\u2705 Clone successful.\");\n }\n\n // Configure bare repository for worktrees\n const bareGit = this.getCachedGit(this.bareRepoPath);\n\n // Check if fetch config already exists\n try {\n const existingConfig = await bareGit.raw([\"config\", \"--get-all\", \"remote.origin.fetch\"]);\n const targetConfig = \"+refs/heads/*:refs/remotes/origin/*\";\n\n if (!existingConfig.includes(targetConfig)) {\n await bareGit.addConfig(\"remote.origin.fetch\", targetConfig);\n }\n } catch {\n // Config doesn't exist, add it\n await bareGit.addConfig(\"remote.origin.fetch\", \"+refs/heads/*:refs/remotes/origin/*\");\n }\n\n // Always fetch to ensure remote refs are up-to-date\n // This is needed for branch creation UI even when repo already exists\n this.logger.info(\"Fetching remote branches...\");\n await bareGit.fetch([\"--all\", \"--progress\"]);\n\n // Detect the default branch (works from local refs even without fetch)\n this.defaultBranch = await this.detectDefaultBranch(bareGit);\n this.mainWorktreePath = path.join(this.config.worktreeDir, this.defaultBranch);\n\n // Check if main worktree exists\n let needsMainWorktree = true;\n try {\n const worktrees = await this.getWorktreesFromBare(bareGit);\n needsMainWorktree = !worktrees.some((w) => path.resolve(w.path) === path.resolve(this.mainWorktreePath));\n } catch {\n // If worktree list fails, assume we need main worktree\n }\n\n if (needsMainWorktree) {\n // Create main worktree if it doesn't exist\n this.logger.info(`Creating ${this.defaultBranch} worktree at \"${this.mainWorktreePath}\"...`);\n await fs.mkdir(this.config.worktreeDir, { recursive: true });\n // Use absolute path for worktree add to avoid relative path issues\n const absoluteWorktreePath = path.resolve(this.mainWorktreePath);\n\n // Check if local branch exists\n const branches = await bareGit.branch();\n const defaultBranchExists = branches.all.includes(this.defaultBranch);\n\n const useNoCheckoutMain = !!this.config.sparseCheckout;\n const noCheckoutFlagMain = useNoCheckoutMain ? [\"--no-checkout\"] : [];\n\n try {\n if (defaultBranchExists) {\n await bareGit.raw([\"worktree\", \"add\", ...noCheckoutFlagMain, absoluteWorktreePath, this.defaultBranch]);\n const worktreeGit = this.getCachedGit(absoluteWorktreePath, this.isLfsSkipEnabled());\n await worktreeGit.branch([\"--set-upstream-to\", `origin/${this.defaultBranch}`, this.defaultBranch]);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, this.defaultBranch, false);\n } else {\n await bareGit.raw([\n \"worktree\",\n \"add\",\n ...noCheckoutFlagMain,\n \"--track\",\n \"-b\",\n this.defaultBranch,\n absoluteWorktreePath,\n `origin/${this.defaultBranch}`,\n ]);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, this.defaultBranch, true);\n }\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes(\"already exists\")) {\n this.logger.info(\n `${this.defaultBranch} worktree directory already exists at '${absoluteWorktreePath}', skipping creation.`,\n );\n } else {\n throw error;\n }\n }\n\n // Ensure the worktree is registered by checking it exists in the list\n const updatedWorktrees = await this.getWorktreesFromBare(bareGit);\n const mainWorktreeRegistered = updatedWorktrees.some(\n (w) => path.resolve(w.path) === path.resolve(this.mainWorktreePath),\n );\n\n if (!mainWorktreeRegistered) {\n // Only warn in non-test environments as this is common in tests due to Git state\n if (process.env.NODE_ENV !== ENV_CONSTANTS.NODE_ENV_TEST) {\n this.logger.warn(`Main worktree was created but not found in worktree list. This may cause issues.`);\n }\n }\n }\n\n // Use the main worktree as our primary git instance\n this.git = this.getCachedGit(this.mainWorktreePath);\n return this.git;\n }\n\n getGit(): SimpleGit {\n if (!this.git) {\n throw new Error(\"Git service not initialized. Call initialize() first.\");\n }\n return this.git;\n }\n\n isInitialized(): boolean {\n return this.git !== null;\n }\n\n getDefaultBranch(): string {\n return this.defaultBranch;\n }\n\n getBareRepoPath(): string {\n return this.bareRepoPath;\n }\n\n async getRemoteDefaultBranch(repoUrl: string): Promise<string> {\n const git = simpleGit(this.buildSimpleGitOptions(this.getFetchTimeoutMs()));\n\n try {\n const out = await git.raw([\"ls-remote\", \"--symref\", repoUrl, \"HEAD\"]);\n const match = out.match(/^ref: refs\\/heads\\/(\\S+)\\s+HEAD/m);\n if (match && match[1]) {\n return match[1];\n }\n } catch {\n /* fall through to probe candidates */\n }\n\n // symref HEAD was unavailable/unparsed: probe common branch names, but only\n // auto-pick when the choice is unambiguous. Guessing by fixed priority when\n // several exist can silently track the wrong branch (e.g. 'main' when the\n // remote's real default is 'master').\n const existing: string[] = [];\n for (const candidate of GIT_CONSTANTS.COMMON_DEFAULT_BRANCHES) {\n try {\n const out = await git.raw([\"ls-remote\", \"--exit-code\", repoUrl, `refs/heads/${candidate}`]);\n if (out.trim().length > 0) {\n existing.push(candidate);\n }\n } catch {\n /* candidate missing \u2014 try next */\n }\n }\n\n if (existing.length === 1) {\n this.logger.warn(\n `Could not read symref HEAD for '${repoUrl}'; using the only common branch found ('${existing[0]}') as the default.`,\n );\n return existing[0];\n }\n\n if (existing.length > 1) {\n throw new Error(\n `Unable to detect default branch for '${repoUrl}': symref HEAD is unavailable and multiple common branches exist (${existing.join(\", \")}). ` +\n `Set 'branch' explicitly in the repository config.`,\n );\n }\n\n throw new Error(\n `Unable to detect default branch for '${repoUrl}'. ` +\n `Set 'branch' explicitly in the repository config or ensure the remote is reachable.`,\n );\n }\n\n async verifyLfs(worktreePath: string, label: string): Promise<void> {\n if (this.isLfsSkipEnabled()) return;\n await this.verifyLfsFilesDownloaded(worktreePath, label);\n }\n\n async fetchAll(): Promise<void> {\n this.assertInitialized();\n this.logger.info(\"Fetching latest data from remote...\");\n const git = this.getCachedGit(this.mainWorktreePath, this.isLfsSkipEnabled());\n await git.fetch([\"--all\", \"--prune\", \"--progress\"]);\n }\n\n async fetchBranch(branchName: string): Promise<void> {\n this.assertInitialized();\n const git = this.getCachedGit(this.mainWorktreePath, this.isLfsSkipEnabled());\n await git.fetch([\"origin\", branchName, \"--prune\", \"--progress\"]);\n }\n\n private assertInitialized(): void {\n if (!this.git) {\n throw new Error(\"Git service not initialized. Call initialize() first.\");\n }\n }\n\n async getRemoteBranches(): Promise<string[]> {\n const git = this.getGit();\n const branches = await git.branch([\"-r\"]);\n return branches.all\n .filter((b) => b.startsWith(\"origin/\") && !b.endsWith(\"/HEAD\"))\n .map((b) => b.replace(\"origin/\", \"\"))\n .filter((b) => b !== \"origin\" && b.length > 0);\n }\n\n async getRemoteBranchesWithActivity(): Promise<{ branch: string; lastActivity: Date }[]> {\n const git = this.getGit();\n // Use for-each-ref to get branch names with their last commit dates\n const result = await git.raw([\n \"for-each-ref\",\n \"--format=%(refname:short)|%(committerdate:iso8601)\",\n \"refs/remotes/origin\",\n ]);\n\n const branches: { branch: string; lastActivity: Date }[] = [];\n const lines = result\n .trim()\n .split(\"\\n\")\n .filter((line) => line);\n\n for (const line of lines) {\n const [ref, dateStr] = line.split(\"|\", 2);\n if (ref && dateStr && !ref.endsWith(\"/HEAD\")) {\n const branch = ref.replace(\"origin/\", \"\");\n // Skip invalid branch names\n if (branch === \"origin\" || branch.length === 0) {\n continue;\n }\n const lastActivity = new Date(dateStr);\n // Skip if the date is invalid\n if (!isNaN(lastActivity.getTime())) {\n branches.push({ branch, lastActivity });\n }\n }\n }\n\n return branches;\n }\n\n private async verifyLfsFilesDownloaded(worktreePath: string, branchName: string): Promise<void> {\n const worktreeGit = this.config.sparseCheckout\n ? simpleGit(worktreePath).env({ ...sanitizeGitEnv(process.env), [ENV_CONSTANTS.GIT_ATTR_SOURCE]: \"HEAD\" })\n : this.getCachedGit(worktreePath);\n\n try {\n const lfsFiles = await worktreeGit.raw([\"lfs\", \"ls-files\", \"--name-only\"]);\n let lfsFileList = lfsFiles\n .trim()\n .split(\"\\n\")\n .filter((f) => f.length > 0);\n\n if (lfsFileList.length === 0) {\n return;\n }\n\n // GIT_ATTR_SOURCE=HEAD lists every LFS file declared in HEAD's .gitattributes,\n // including ones outside the sparse-checkout cone that aren't on disk. Sampling\n // those would burn the 30s retry loop on guaranteed-missing files.\n if (this.config.sparseCheckout) {\n const existence = await Promise.all(\n lfsFileList.map(async (f) => {\n try {\n await fs.access(path.join(worktreePath, f));\n return f;\n } catch {\n return null;\n }\n }),\n );\n lfsFileList = existence.filter((f): f is string => f !== null);\n if (lfsFileList.length === 0) {\n return;\n }\n }\n\n if (this.config.debug) {\n this.logger.info(` - Verifying ${lfsFileList.length} LFS files are downloaded...`);\n }\n\n const sampleSize = Math.min(5, lfsFileList.length);\n const samplesToCheck = [];\n for (let i = 0; i < sampleSize; i++) {\n const randomIndex = Math.floor(Math.random() * lfsFileList.length);\n samplesToCheck.push(lfsFileList[randomIndex]);\n }\n\n let retries = 0;\n const maxRetries = 30;\n const retryDelay = 1000;\n\n while (retries < maxRetries) {\n let allDownloaded = true;\n const notDownloaded: string[] = [];\n\n for (const file of samplesToCheck) {\n const filePath = path.join(worktreePath, file);\n try {\n const handle = await fs.open(filePath, \"r\");\n try {\n const buffer = Buffer.alloc(200);\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);\n const header = buffer.subarray(0, bytesRead).toString(\"utf8\");\n if (header.startsWith(GIT_CONSTANTS.LFS_HEADER)) {\n allDownloaded = false;\n notDownloaded.push(file);\n }\n } finally {\n await handle.close();\n }\n } catch {\n allDownloaded = false;\n notDownloaded.push(file);\n }\n }\n\n if (allDownloaded) {\n if (this.config.debug) {\n this.logger.info(` - \u2705 LFS files verified (${samplesToCheck.length} samples checked)`);\n }\n return;\n }\n\n retries++;\n if (retries < maxRetries) {\n await new Promise((resolve) => setTimeout(resolve, retryDelay));\n }\n }\n\n this.logger.warn(\n ` - \u26A0\uFE0F Warning: Some LFS files may not be fully downloaded after ${maxRetries} seconds. ` +\n `This might cause issues if tools access the worktree immediately.`,\n );\n } catch (error) {\n this.logger.warn(` - \u26A0\uFE0F Warning: Could not verify LFS files for '${branchName}': ${error}`);\n }\n }\n\n async checkoutHead(worktreePath: string): Promise<void> {\n const git = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n await git.raw([\"checkout\", \"HEAD\"]);\n }\n\n private async applySparseAndCheckout(absoluteWorktreePath: string): Promise<void> {\n if (!this.config.sparseCheckout) return;\n await this.sparseCheckoutService.applyToWorktree(absoluteWorktreePath, this.config.sparseCheckout);\n const worktreeGit = this.getCachedGit(absoluteWorktreePath, this.isLfsSkipEnabled());\n await worktreeGit.raw([\"checkout\", \"HEAD\"]);\n }\n\n private async rollbackPartialWorktree(\n bareGit: SimpleGit,\n absoluteWorktreePath: string,\n branchName: string,\n createdNewBranch: boolean,\n failureContext?: string,\n ): Promise<{ worktreeRemoved: boolean }> {\n let worktreeRemoved = true;\n try {\n await bareGit.raw([\"worktree\", \"remove\", \"--force\", absoluteWorktreePath]);\n } catch (rollbackError) {\n worktreeRemoved = false;\n const ctx = failureContext ? ` after ${failureContext}` : \"\";\n this.logger.warn(\n ` - Rollback failed for '${branchName}' at '${absoluteWorktreePath}'${ctx}: ${getErrorMessage(rollbackError)}`,\n );\n }\n if (createdNewBranch) {\n try {\n await bareGit.raw([\"branch\", \"-D\", branchName]);\n } catch (branchRollbackError) {\n this.logger.warn(\n ` - Rollback (branch delete) failed for '${branchName}': ${getErrorMessage(branchRollbackError)}`,\n );\n }\n }\n return { worktreeRemoved };\n }\n\n private async createWorktreeMetadata(bareGit: SimpleGit, worktreePath: string, branchName: string): Promise<void> {\n try {\n const worktreeGit = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n const parentCommit = await bareGit.revparse([this.defaultBranch]);\n\n await this.metadataService.createInitialMetadataFromPath(\n this.bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n `origin/${branchName}`,\n this.defaultBranch,\n parentCommit.trim(),\n );\n } catch (metadataError) {\n this.logger.error(` - \u274C Failed to create metadata for '${branchName}': ${metadataError}`);\n throw new Error(`Metadata creation failed for ${branchName}. This worktree cannot be auto-managed.`);\n }\n }\n\n async addWorktree(branchName: string, worktreePath: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath, this.isLfsSkipEnabled());\n // Use absolute path for worktree add to avoid relative path issues\n const absoluteWorktreePath = path.resolve(worktreePath);\n // Ensure parent directory exists for nested branch paths\n await fs.mkdir(path.dirname(absoluteWorktreePath), { recursive: true });\n\n // Check if directory already exists (could be from a failed previous attempt)\n try {\n await fs.access(absoluteWorktreePath);\n // Directory exists - check if it's already a valid worktree\n const worktrees = await this.getWorktreesFromBare(bareGit);\n const isValidWorktree = worktrees.some((w) => path.resolve(w.path) === absoluteWorktreePath);\n\n if (isValidWorktree) {\n this.logger.info(` - Worktree for '${branchName}' already exists at '${absoluteWorktreePath}'`);\n return;\n } else {\n // Directory exists but is not a valid worktree - clean it up\n this.logger.info(` - Cleaning up orphaned directory at '${absoluteWorktreePath}'`);\n await fs.rm(absoluteWorktreePath, { recursive: true, force: true });\n }\n } catch {\n // Directory doesn't exist, which is expected - continue with creation\n }\n\n let createdNewBranch = false;\n try {\n const { local: localBranchExists, remote: remoteBranchExists } = await this.branchExists(branchName);\n\n createdNewBranch = await this.runWorktreeAddByMatrix(\n bareGit,\n branchName,\n absoluteWorktreePath,\n localBranchExists,\n remoteBranchExists,\n );\n\n if (localBranchExists && !remoteBranchExists) {\n this.logger.info(` - Created worktree for '${branchName}' (no remote yet \u2014 push to set upstream)`);\n } else {\n this.logger.info(` - Created worktree for '${branchName}' with tracking to origin/${branchName}`);\n }\n\n if (!this.isLfsSkipEnabled()) {\n await this.verifyLfsFilesDownloaded(absoluteWorktreePath, branchName);\n }\n\n try {\n await this.createWorktreeMetadata(bareGit, absoluteWorktreePath, branchName);\n } catch (metadataError) {\n this.logger.warn(` - Metadata creation failed for '${branchName}', removing worktree to prevent orphan`);\n await this.rollbackPartialWorktree(bareGit, absoluteWorktreePath, branchName, createdNewBranch);\n throw new Error(`Metadata creation failed for '${branchName}': ${getErrorMessage(metadataError)}`);\n }\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n // Upstream setup failures are already rolled back inside runWorktreeAddByMatrix.\n // Don't enter the tracking-error fallback (which would silently accept a partial worktree).\n if ((error as { isUpstreamSetupFailure?: boolean })?.isUpstreamSetupFailure) {\n throw error;\n }\n\n // Re-throw metadata creation errors - these are fatal and should not fall back\n if (errorMessage.includes(\"Metadata creation failed\")) {\n throw error;\n }\n\n // Check if this is an \"already registered\" error\n if (errorMessage.includes(\"already registered worktree\")) {\n // Check if worktree was actually created by a concurrent operation\n const worktrees = await this.getWorktreesFromBare(bareGit);\n const existingWorktree = worktrees.find((w) => path.resolve(w.path) === absoluteWorktreePath);\n\n if (existingWorktree && !existingWorktree.isPrunable) {\n this.logger.info(` - Worktree for '${branchName}' was created by concurrent operation`);\n return;\n }\n\n this.logger.warn(` - Worktree already registered but missing. Pruning and retrying...`);\n await bareGit.raw([\"worktree\", \"prune\"]);\n // Clean up directory if it exists\n try {\n await fs.rm(absoluteWorktreePath, { recursive: true, force: true });\n } catch {\n // Directory might not exist, ignore\n }\n let retryCreatedNewBranch = false;\n try {\n const { local: localBranchExists, remote: remoteBranchExists } = await this.branchExists(branchName);\n retryCreatedNewBranch = await this.runWorktreeAddByMatrix(\n bareGit,\n branchName,\n absoluteWorktreePath,\n localBranchExists,\n remoteBranchExists,\n );\n this.logger.info(` - Created worktree for '${branchName}' after pruning`);\n\n if (!this.isLfsSkipEnabled()) {\n await this.verifyLfsFilesDownloaded(absoluteWorktreePath, branchName);\n }\n\n try {\n await this.createWorktreeMetadata(bareGit, absoluteWorktreePath, branchName);\n } catch (metadataError) {\n this.logger.warn(` - Metadata creation failed for '${branchName}', removing worktree to prevent orphan`);\n await this.rollbackPartialWorktree(bareGit, absoluteWorktreePath, branchName, retryCreatedNewBranch);\n throw new Error(`Metadata creation failed for '${branchName}': ${getErrorMessage(metadataError)}`);\n }\n return;\n } catch (retryError) {\n this.logger.error(` - Failed to create worktree after pruning: ${retryError}`);\n throw retryError;\n }\n }\n\n // Only fall back to non-tracking version for tracking-related errors.\n // Re-throw real errors (disk full, permissions, etc.) immediately.\n const isTrackingError =\n errorMessage.includes(\"not a valid object name\") ||\n errorMessage.includes(\"not a commit\") ||\n errorMessage.includes(\"cannot set up tracking\") ||\n errorMessage.includes(\"does not track\") ||\n errorMessage.includes(\"remote tracking branch\") ||\n errorMessage.includes(\"no such remote ref\");\n\n if (!isTrackingError) {\n throw error;\n }\n\n this.logger.warn(` - Failed to create worktree with tracking, falling back to simple add: ${error}`);\n\n // Check again if directory exists before fallback attempt\n try {\n await fs.access(absoluteWorktreePath);\n // Directory exists - check if it's already a valid worktree\n const worktrees = await this.getWorktreesFromBare(bareGit);\n const isValidWorktree = worktrees.some((w) => path.resolve(w.path) === absoluteWorktreePath);\n\n if (isValidWorktree) {\n this.logger.info(` - Worktree for '${branchName}' already exists at '${absoluteWorktreePath}'`);\n return;\n } else {\n // Directory exists but is not a valid worktree - clean it up\n this.logger.info(` - Cleaning up orphaned directory at '${absoluteWorktreePath}' before fallback attempt`);\n await fs.rm(absoluteWorktreePath, { recursive: true, force: true });\n }\n } catch {\n // Directory doesn't exist, which is expected - continue with fallback\n }\n\n try {\n const useNoCheckout = !!this.config.sparseCheckout;\n const fallbackArgs = useNoCheckout\n ? [\"worktree\", \"add\", \"--no-checkout\", absoluteWorktreePath, branchName]\n : [\"worktree\", \"add\", absoluteWorktreePath, branchName];\n await bareGit.raw(fallbackArgs);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, branchName, false);\n this.logger.info(` - Created worktree for '${branchName}' (without tracking)`);\n\n if (!this.isLfsSkipEnabled()) {\n await this.verifyLfsFilesDownloaded(absoluteWorktreePath, branchName);\n }\n\n try {\n await this.createWorktreeMetadata(bareGit, absoluteWorktreePath, branchName);\n } catch (metadataError) {\n this.logger.warn(` - Metadata creation failed for '${branchName}', removing worktree to prevent orphan`);\n await this.rollbackPartialWorktree(bareGit, absoluteWorktreePath, branchName, false);\n throw new Error(`Metadata creation failed for '${branchName}': ${getErrorMessage(metadataError)}`);\n }\n } catch (fallbackError) {\n const fallbackErrorMessage = getErrorMessage(fallbackError);\n\n // If fallback also fails with \"already registered\", check if created by concurrent op\n if (fallbackErrorMessage.includes(\"already registered worktree\")) {\n const worktrees = await this.getWorktreesFromBare(bareGit);\n const existingWorktree = worktrees.find((w) => path.resolve(w.path) === absoluteWorktreePath);\n\n if (existingWorktree && !existingWorktree.isPrunable) {\n this.logger.info(` - Worktree for '${branchName}' was created by concurrent operation during fallback`);\n return;\n }\n }\n\n // If still failing, this is a real error\n throw fallbackError;\n }\n }\n }\n\n private async runWorktreeAddByMatrix(\n bareGit: SimpleGit,\n branchName: string,\n absoluteWorktreePath: string,\n localExists: boolean,\n remoteExists: boolean,\n ): Promise<boolean> {\n const useNoCheckout = !!this.config.sparseCheckout;\n const noCheckoutFlag = useNoCheckout ? [\"--no-checkout\"] : [];\n\n if (localExists && remoteExists) {\n await bareGit.raw([\"worktree\", \"add\", ...noCheckoutFlag, absoluteWorktreePath, branchName]);\n\n // branch --set-upstream-to is a config-only operation and works on a --no-checkout\n // worktree, so we run it before sparse setup and materialization.\n try {\n const worktreeGit = this.getCachedGit(absoluteWorktreePath, this.isLfsSkipEnabled());\n await worktreeGit.branch([\"--set-upstream-to\", `origin/${branchName}`, branchName]);\n } catch (error) {\n throw await this.wrapUpstreamFailure(bareGit, absoluteWorktreePath, branchName, false, error);\n }\n\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, branchName, false);\n return false;\n }\n\n if (localExists) {\n await bareGit.raw([\"worktree\", \"add\", ...noCheckoutFlag, absoluteWorktreePath, branchName]);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, branchName, false);\n return false;\n }\n\n if (remoteExists) {\n await bareGit.raw([\n \"worktree\",\n \"add\",\n ...noCheckoutFlag,\n \"--track\",\n \"-b\",\n branchName,\n absoluteWorktreePath,\n `origin/${branchName}`,\n ]);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, branchName, true);\n return true;\n }\n\n throw new WorktreeError(\n `Branch '${branchName}' does not exist locally or on origin; create it first`,\n \"BRANCH_NOT_FOUND\",\n );\n }\n\n private async runSparseStepWithRollback(\n bareGit: SimpleGit,\n absoluteWorktreePath: string,\n branchName: string,\n createdNewBranch: boolean,\n ): Promise<void> {\n try {\n await this.applySparseAndCheckout(absoluteWorktreePath);\n } catch (sparseError) {\n await this.rollbackPartialWorktree(bareGit, absoluteWorktreePath, branchName, createdNewBranch);\n throw new Error(`Sparse-checkout setup failed for '${branchName}': ${getErrorMessage(sparseError)}`);\n }\n }\n\n private async wrapUpstreamFailure(\n bareGit: SimpleGit,\n absoluteWorktreePath: string,\n branchName: string,\n createdNewBranch: boolean,\n error: unknown,\n ): Promise<Error> {\n const { worktreeRemoved } = await this.rollbackPartialWorktree(\n bareGit,\n absoluteWorktreePath,\n branchName,\n createdNewBranch,\n \"upstream setup error\",\n );\n const suffix = worktreeRemoved ? \"\" : \" (rollback failed; partial worktree may remain)\";\n const wrapped = new Error(`Failed to set upstream for '${branchName}': ${getErrorMessage(error)}${suffix}`);\n (wrapped as Error & { isUpstreamSetupFailure?: boolean }).isUpstreamSetupFailure = true;\n return wrapped;\n }\n\n async removeWorktree(worktreePath: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n\n await bareGit.raw([\"worktree\", \"remove\", worktreePath, \"--force\"]);\n this.logger.info(` - \u2705 Safely removed stale worktree at '${worktreePath}'.`);\n\n // Clean up metadata using the worktree path\n try {\n await this.metadataService.deleteMetadataFromPath(this.bareRepoPath, worktreePath);\n } catch (metadataError) {\n this.logger.warn(`Failed to delete metadata for worktree: ${metadataError}`);\n }\n }\n\n async pruneWorktrees(): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n await bareGit.raw([\"worktree\", \"prune\"]);\n this.logger.info(\"Pruned worktree metadata.\");\n }\n\n async checkWorktreeStatus(worktreePath: string): Promise<boolean> {\n return this.statusService.checkWorktreeStatus(worktreePath);\n }\n\n async hasUnpushedCommits(worktreePath: string): Promise<boolean> {\n const metadata = await this.metadataService.loadMetadataFromPath(this.bareRepoPath, worktreePath);\n return this.statusService.hasUnpushedCommits(worktreePath, metadata?.lastSyncCommit);\n }\n\n async hasUpstreamGone(worktreePath: string): Promise<boolean> {\n return this.statusService.hasUpstreamGone(worktreePath);\n }\n\n async hasStashedChanges(worktreePath: string): Promise<boolean> {\n return this.statusService.hasStashedChanges(worktreePath);\n }\n\n async getFullWorktreeStatus(worktreePath: string, includeDetails = false): Promise<WorktreeStatusResult> {\n const metadata = await this.metadataService.loadMetadataFromPath(this.bareRepoPath, worktreePath);\n return this.statusService.getFullWorktreeStatus(worktreePath, includeDetails, metadata?.lastSyncCommit);\n }\n\n async hasModifiedSubmodules(worktreePath: string): Promise<boolean> {\n return this.statusService.hasModifiedSubmodules(worktreePath);\n }\n\n async hasOperationInProgress(worktreePath: string): Promise<boolean> {\n return this.statusService.hasOperationInProgress(worktreePath);\n }\n\n async getCurrentBranch(): Promise<string> {\n const git = this.getGit();\n const branchSummary = await git.branch();\n return branchSummary.current;\n }\n\n private async detectDefaultBranch(bareGit: SimpleGit): Promise<string> {\n try {\n // Try to get the symbolic ref for origin/HEAD\n const headRef = await bareGit.raw([\"symbolic-ref\", \"refs/remotes/origin/HEAD\"]);\n // Extract branch name from refs/remotes/origin/main or refs/remotes/origin/master\n const branch = headRef.trim().split(\"/\").pop();\n if (branch) {\n return branch;\n }\n } catch {\n // If that fails, try to set HEAD automatically\n try {\n await bareGit.raw([\"remote\", \"set-head\", \"origin\", \"-a\"]);\n const headRef = await bareGit.raw([\"symbolic-ref\", \"refs/remotes/origin/HEAD\"]);\n const branch = headRef.trim().split(\"/\").pop();\n if (branch) {\n return branch;\n }\n } catch {\n // If all else fails, try to detect from remote branches\n try {\n const remoteBranches = await bareGit.branch([\"-r\"]);\n const commonDefaults = GIT_CONSTANTS.COMMON_DEFAULT_BRANCHES;\n for (const defaultName of commonDefaults) {\n if (remoteBranches.all.some((branch) => branch === `origin/${defaultName}`)) {\n return defaultName;\n }\n }\n } catch {\n // Ignore and fall through to default\n }\n }\n }\n // Final fallback\n return GIT_CONSTANTS.DEFAULT_BRANCH;\n }\n\n setLfsSkipEnabled(value: boolean): void {\n this.lfsSkipOverride = value;\n }\n\n private isLfsSkipEnabled(): boolean {\n return this.config.skipLfs || this.lfsSkipOverride;\n }\n\n async getWorktrees(): Promise<{ path: string; branch: string }[]> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n return this.getWorktreesFromBare(bareGit);\n }\n\n async isWorktreeBehind(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the current branch\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n // Check if the branch has an upstream\n const upstreamInfo = await worktreeGit.raw([\"rev-parse\", \"--abbrev-ref\", `${currentBranch}@{upstream}`]);\n if (!upstreamInfo.trim()) {\n return false; // No upstream, can't be behind\n }\n\n // Count commits behind upstream\n const behindCount = await worktreeGit.raw([\"rev-list\", \"--count\", `HEAD..${upstreamInfo.trim()}`]);\n return parseInt(behindCount.trim(), 10) > 0;\n } catch {\n // If any command fails, assume not behind\n return false;\n }\n }\n\n async updateWorktree(worktreePath: string): Promise<void> {\n const worktreeGit = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n\n // Perform a fast-forward merge\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n await worktreeGit.merge([`origin/${currentBranch}`, \"--ff-only\"]);\n\n // Update metadata after successful update (use path-based method)\n try {\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n await this.metadataService.updateLastSyncFromPath(\n this.bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n \"updated\",\n this.defaultBranch,\n );\n } catch (metadataError) {\n this.logger.warn(`Failed to update metadata for worktree: ${metadataError}`);\n }\n }\n\n async hasDivergedHistory(worktreePath: string, expectedBranch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n\n // Validate branch matches\n const branchInfo = await worktreeGit.branch();\n if (branchInfo.current !== expectedBranch) {\n this.logger.warn(`Branch mismatch in hasDivergedHistory: expected ${expectedBranch}, got ${branchInfo.current}`);\n return false; // Conservative: assume can fast-forward\n }\n\n try {\n // Check if HEAD is an ancestor of the remote branch (can fast-forward)\n await worktreeGit.raw([\"merge-base\", \"--is-ancestor\", \"HEAD\", `origin/${expectedBranch}`]);\n return false; // Can fast-forward\n } catch {\n return true; // Histories have diverged\n }\n }\n\n async canFastForward(worktreePath: string, branch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the merge base between HEAD and the remote branch\n const mergeBase = await worktreeGit.raw([\"merge-base\", \"HEAD\", `origin/${branch}`]);\n const mergeBaseSha = mergeBase.trim();\n\n // Get current HEAD SHA\n const headSha = await worktreeGit.revparse([\"HEAD\"]);\n const headShaTrimmed = headSha.trim();\n\n // If merge base equals HEAD, then HEAD is an ancestor of remote and can fast-forward\n return mergeBaseSha === headShaTrimmed;\n } catch {\n // If merge-base fails, branches have diverged\n return false;\n }\n }\n\n async isLocalAheadOfRemote(worktreePath: string, branch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the merge base between HEAD and the remote branch\n const mergeBase = await worktreeGit.raw([\"merge-base\", \"HEAD\", `origin/${branch}`]);\n const mergeBaseSha = mergeBase.trim();\n\n // Get remote branch SHA\n const remoteSha = await worktreeGit.revparse([`origin/${branch}`]);\n const remoteShaTrimmed = remoteSha.trim();\n\n // If merge base equals remote, local is ahead (remote is ancestor of local)\n return mergeBaseSha === remoteShaTrimmed;\n } catch {\n return false;\n }\n }\n\n async classifyRemoteRelationship(worktreePath: string, branch: string): Promise<RemoteRelationship> {\n const worktreeGit = this.getCachedGit(worktreePath);\n\n let headSha: string;\n let remoteSha: string;\n try {\n headSha = (await worktreeGit.revparse([\"HEAD\"])).trim();\n remoteSha = (await worktreeGit.revparse([`refs/remotes/origin/${branch}`])).trim();\n } catch {\n return \"diverged\";\n }\n\n if (headSha === remoteSha) return \"up_to_date\";\n\n let mergeBase = \"\";\n let mergeBaseFailed = false;\n try {\n mergeBase = (await worktreeGit.raw([\"merge-base\", \"HEAD\", `origin/${branch}`])).trim();\n } catch {\n mergeBaseFailed = true;\n }\n // simple-git swallows merge-base exit 1 and returns \"\" \u2014 treat empty output as failure too.\n if (mergeBaseFailed || !mergeBase) {\n if (await this.isShallowRepository(worktreeGit)) return \"indeterminate_shallow\";\n return \"diverged\";\n }\n if (mergeBase === headSha) return \"fast_forward\";\n if (mergeBase === remoteSha) return \"local_ahead\";\n return \"diverged\";\n }\n\n private async isShallowRepository(git: SimpleGit): Promise<boolean> {\n try {\n const output = await git.raw([\"rev-parse\", \"--is-shallow-repository\"]);\n return output.trim() === \"true\";\n } catch {\n return false;\n }\n }\n\n async getChangedPathsInRange(worktreePath: string, fromRef: string, toRef: string): Promise<string[] | null> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n const out = await worktreeGit.raw([\n \"-c\",\n \"core.quotePath=false\",\n \"diff\",\n \"--name-only\",\n \"--no-renames\",\n `${fromRef}..${toRef}`,\n ]);\n // Don't .trim() entries \u2014 leading/trailing whitespace is valid in POSIX\n // paths and `core.quotePath=false` only affects high-byte quoting, not\n // whitespace. Strip a trailing CR for Windows line endings only.\n return out\n .split(\"\\n\")\n .map((l) => l.replace(/\\r$/, \"\"))\n .filter((l) => l.length > 0);\n } catch (error) {\n this.logger.warn(`Failed to compute diff ${fromRef}..${toRef} in ${worktreePath}: ${getErrorMessage(error)}`);\n return null;\n }\n }\n\n async compareTreeContent(worktreePath: string, branch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the tree SHA for the current HEAD\n const localTree = await worktreeGit.raw([\"rev-parse\", \"HEAD^{tree}\"]);\n // Get the tree SHA for the remote branch\n const remoteTree = await worktreeGit.raw([\"rev-parse\", `origin/${branch}^{tree}`]);\n\n return localTree.trim() === remoteTree.trim();\n } catch (error) {\n this.logger.error(`Error comparing tree content: ${error}`);\n return false; // Assume trees are different if we can't compare\n }\n }\n\n async resetToUpstream(worktreePath: string, branch: string): Promise<void> {\n const worktreeGit = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n\n await worktreeGit.reset([\"--hard\", `origin/${branch}`]);\n\n // Update metadata after reset (use path-based method)\n try {\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n await this.metadataService.updateLastSyncFromPath(\n this.bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n \"updated\",\n this.defaultBranch,\n );\n } catch (metadataError) {\n this.logger.warn(`Failed to update metadata after reset: ${metadataError}`);\n }\n }\n\n async getCurrentCommit(worktreePath: string): Promise<string> {\n const worktreeGit = this.getCachedGit(worktreePath);\n const commit = await worktreeGit.revparse([\"HEAD\"]);\n return commit.trim();\n }\n\n async getRemoteCommit(ref: string): Promise<string> {\n // Use the bare repository to read remote commit to avoid dependency on main worktree path\n const git = this.getCachedGit(this.bareRepoPath);\n const commit = await git.revparse([ref]);\n return commit.trim();\n }\n\n async branchExists(branchName: string): Promise<{ local: boolean; remote: boolean }> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const checkRef = async (ref: string): Promise<boolean> => {\n try {\n // simple-git resolves `show-ref --quiet` when Git exits 1, so keep stdout enabled.\n await bareGit.raw([\"show-ref\", \"--verify\", ref]);\n return true;\n } catch {\n return false;\n }\n };\n\n const [local, remote] = await Promise.all([\n checkRef(`${GIT_CONSTANTS.REFS.HEADS}${branchName}`),\n checkRef(`${GIT_CONSTANTS.REFS.REMOTES}/${branchName}`),\n ]);\n\n return { local, remote };\n }\n\n async getLocalBranches(): Promise<string[]> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const branches = await bareGit.branch();\n return branches.all;\n }\n\n private async resolveCreateBranchBaseRef(bareGit: SimpleGit, baseBranch: string): Promise<string> {\n const candidates =\n baseBranch.startsWith(GIT_CONSTANTS.REMOTE_PREFIX) || baseBranch.startsWith(\"refs/\")\n ? [baseBranch]\n : [`${GIT_CONSTANTS.REMOTE_PREFIX}${baseBranch}`, baseBranch];\n\n for (const candidate of candidates) {\n try {\n await bareGit.revparse([\"--verify\", candidate]);\n return candidate;\n } catch {\n // Try the next candidate before letting git branch report the original failure.\n }\n }\n\n return candidates[0];\n }\n\n async createBranch(branchName: string, baseBranch: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const baseRef = await this.resolveCreateBranchBaseRef(bareGit, baseBranch);\n\n await bareGit.raw([\"branch\", \"--no-track\", branchName, baseRef]);\n this.logger.info(`Created branch '${branchName}' from '${baseRef}'`);\n }\n\n async pushBranch(branchName: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n\n await bareGit.push([\"origin\", `${branchName}:${branchName}`, \"-u\"]);\n this.logger.info(`Pushed branch '${branchName}' to remote`);\n }\n\n async getWorktreeMetadata(worktreePath: string): Promise<SyncMetadata | null> {\n return this.metadataService.loadMetadataFromPath(this.bareRepoPath, worktreePath);\n }\n\n private async getWorktreesFromBare(\n bareGit: SimpleGit,\n ): Promise<{ path: string; branch: string; isPrunable?: boolean }[]> {\n const result = await bareGit.raw([\"worktree\", \"list\", \"--porcelain\"]);\n return parseWorktreeListPorcelain(result)\n .filter((w) => !w.detached && w.branch !== null)\n .map((w) => ({\n path: w.path,\n branch: w.branch as string,\n isPrunable: w.prunable,\n }));\n }\n}\n", "export interface ParsedWorktree {\n path: string;\n branch: string | null;\n head: string | null;\n detached: boolean;\n prunable: boolean;\n locked: boolean;\n}\n\nexport function parseWorktreeListPorcelain(output: string): ParsedWorktree[] {\n const worktrees: ParsedWorktree[] = [];\n let current: Partial<ParsedWorktree> = {};\n\n const flush = (): void => {\n if (!current.path) {\n current = {};\n return;\n }\n worktrees.push({\n path: current.path,\n branch: current.branch ?? null,\n head: current.head ?? null,\n detached: current.detached ?? false,\n prunable: current.prunable ?? false,\n locked: current.locked ?? false,\n });\n current = {};\n };\n\n for (const line of output.split(\"\\n\")) {\n if (line.startsWith(\"worktree \")) {\n flush();\n current.path = line.substring(\"worktree \".length);\n } else if (line.startsWith(\"branch \")) {\n current.branch = line.substring(\"branch \".length).replace(\"refs/heads/\", \"\");\n } else if (line.startsWith(\"HEAD \")) {\n current.head = line.substring(\"HEAD \".length);\n } else if (line === \"detached\") {\n current.detached = true;\n } else if (line === \"prunable\" || line.startsWith(\"prunable \")) {\n current.prunable = true;\n } else if (line === \"locked\" || line.startsWith(\"locked \")) {\n current.locked = true;\n } else if (line.trim() === \"\") {\n flush();\n }\n }\n flush();\n return worktrees;\n}\n", "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 path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { SparseCheckoutConfig, SparseCheckoutMode } from \"../types\";\nimport type { SimpleGit } from \"simple-git\";\n\nexport type GitFactory = (worktreePath: string) => SimpleGit;\n\ninterface SparseMatcher {\n mode: SparseCheckoutMode;\n patterns: string[];\n ancestorDirs: Set<string>;\n}\n\nexport class SparseCheckoutService {\n private logger: Logger;\n private gitFactory: GitFactory;\n private warnedConfigs = new WeakSet<SparseCheckoutConfig>();\n private matcherCache = new WeakMap<SparseCheckoutConfig, SparseMatcher>();\n\n constructor(logger?: Logger, gitFactory?: GitFactory) {\n this.logger = logger ?? Logger.createDefault();\n this.gitFactory = gitFactory ?? ((p: string): SimpleGit => simpleGit(p));\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n resolveMode(cfg: SparseCheckoutConfig): SparseCheckoutMode {\n const hasExclude = !!cfg.exclude && cfg.exclude.length > 0;\n const hasNegation = cfg.include.some((p) => p.trim().startsWith(\"!\"));\n\n if (cfg.mode === \"no-cone\") return \"no-cone\";\n if (hasExclude || hasNegation) {\n if (cfg.mode === \"cone\" && !this.warnedConfigs.has(cfg)) {\n this.logger.warn(\n \"sparseCheckout: mode 'cone' is incompatible with excludes or negation patterns; auto-promoting to 'no-cone'\",\n );\n this.warnedConfigs.add(cfg);\n }\n return \"no-cone\";\n }\n return cfg.mode ?? \"cone\";\n }\n\n buildPatterns(cfg: SparseCheckoutConfig): string[] {\n return this.buildPatternsForMode(cfg, this.resolveMode(cfg));\n }\n\n private buildPatternsForMode(cfg: SparseCheckoutConfig, mode: SparseCheckoutMode): string[] {\n const includes = cfg.include.map((p) => p.trim()).filter((p) => p.length > 0);\n\n if (mode === \"cone\") {\n return includes;\n }\n\n const excludes = (cfg.exclude ?? [])\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n .map((p) => (p.startsWith(\"!\") ? p : `!${p}`));\n\n return [...includes, ...excludes];\n }\n\n async applyToWorktree(worktreePath: string, cfg: SparseCheckoutConfig): Promise<void> {\n const mode = this.resolveMode(cfg);\n const patterns = this.buildPatternsForMode(cfg, mode);\n\n if (patterns.length === 0) {\n throw new Error(\"sparseCheckout produced no patterns; refusing to apply empty config\");\n }\n\n const git = this.gitFactory(worktreePath);\n await git.raw([\"sparse-checkout\", \"init\", mode === \"cone\" ? \"--cone\" : \"--no-cone\"]);\n await git.raw([\"sparse-checkout\", \"set\", mode === \"cone\" ? \"--cone\" : \"--no-cone\", ...patterns]);\n }\n\n async readCurrent(worktreePath: string): Promise<string[] | null> {\n const git = this.gitFactory(worktreePath);\n try {\n const out = await git.raw([\"sparse-checkout\", \"list\"]);\n const lines = out\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter((l) => l.length > 0 && !l.startsWith(\"#\"));\n return lines.length === 0 ? null : lines;\n } catch {\n return null;\n }\n }\n\n async readCurrentMode(worktreePath: string): Promise<SparseCheckoutMode | null> {\n const git = this.gitFactory(worktreePath);\n try {\n const out = await git.raw([\"config\", \"--bool\", \"--get\", \"core.sparseCheckoutCone\"]);\n const value = out.trim().toLowerCase();\n if (value === \"true\") return \"cone\";\n if (value === \"false\") return \"no-cone\";\n return null;\n } catch {\n return null;\n }\n }\n\n async needsUpdate(worktreePath: string, cfg: SparseCheckoutConfig): Promise<boolean> {\n const desiredMode = this.resolveMode(cfg);\n const currentMode = await this.readCurrentMode(worktreePath);\n if (currentMode !== desiredMode) return true;\n const current = await this.readCurrent(worktreePath);\n if (current === null) return true;\n return !this.patternsEqual(current, this.buildPatternsForMode(cfg, desiredMode));\n }\n\n isNarrowing(currentPatterns: string[] | null, nextPatterns: string[]): boolean {\n if (!currentPatterns || currentPatterns.length === 0) return false;\n\n const isNeg = (p: string): boolean => p.startsWith(\"!\");\n const trim = (xs: string[]): string[] => xs.map((p) => p.trim()).filter((p) => p.length > 0);\n\n const cur = trim(currentPatterns);\n const next = trim(nextPatterns);\n\n const positiveCurrent = new Set(cur.filter((p) => !isNeg(p)));\n const negativeCurrent = new Set(cur.filter(isNeg));\n const positiveNext = new Set(next.filter((p) => !isNeg(p)));\n const negativeNext = new Set(next.filter(isNeg));\n\n for (const p of positiveCurrent) {\n if (!positiveNext.has(p)) return true;\n }\n for (const p of negativeNext) {\n if (!negativeCurrent.has(p)) return true;\n }\n return false;\n }\n\n patternsEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n const at = a.map((x) => x.trim());\n const bt = b.map((x) => x.trim());\n return at.every((v, i) => v === bt[i]);\n }\n\n /**\n * Decide whether a list of changed file paths intersects the sparse-checkout\n * set defined by `cfg`. Used to skip fast-forward updates when upstream\n * commits only touch files outside the materialized worktree.\n *\n * Cone mode materializes:\n * - all files at the repository root,\n * - all files directly inside every ancestor of an included directory\n * (e.g. include `tools/build` keeps `tools/foo.txt` checked out too),\n * - everything inside an included directory.\n * We mirror those rules here. Missing the ancestor-files case would let\n * stale files linger when only those parent files change upstream.\n *\n * No-cone mode: gitignore-style matching with negation is non-trivial and\n * not implemented here yet. We return `true` so the caller falls back to\n * the safe behavior of always running the update.\n *\n * The matcher derived from `cfg` is cached on the cfg object identity\n * (WeakMap), so callers should reuse the same `cfg` reference across\n * invocations to benefit from the cache.\n */\n pathsTouchSparse(changedPaths: string[], cfg: SparseCheckoutConfig): boolean {\n if (changedPaths.length === 0) return false;\n\n const matcher = this.getMatcher(cfg);\n if (matcher.mode === \"no-cone\") return true;\n if (matcher.patterns.length === 0) return true;\n\n return changedPaths.some((p) => {\n if (!p.includes(\"/\")) return true;\n for (const pat of matcher.patterns) {\n if (p === pat || p.startsWith(pat + \"/\")) return true;\n }\n return matcher.ancestorDirs.has(path.posix.dirname(p));\n });\n }\n\n private getMatcher(cfg: SparseCheckoutConfig): SparseMatcher {\n const cached = this.matcherCache.get(cfg);\n if (cached) return cached;\n\n const mode = this.resolveMode(cfg);\n if (mode === \"no-cone\") {\n const matcher: SparseMatcher = { mode, patterns: [], ancestorDirs: new Set() };\n this.matcherCache.set(cfg, matcher);\n return matcher;\n }\n\n const patterns = cfg.include\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n .map((p) => (p.endsWith(\"/\") ? p.slice(0, -1) : p));\n\n const ancestorDirs = new Set<string>();\n for (const pat of patterns) {\n const parts = pat.split(\"/\");\n for (let i = 1; i < parts.length; i++) {\n ancestorDirs.add(parts.slice(0, i).join(\"/\"));\n }\n }\n\n const matcher: SparseMatcher = { mode, patterns, ancestorDirs };\n this.matcherCache.set(cfg, matcher);\n return matcher;\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { ERROR_MESSAGES, GIT_CONSTANTS, METADATA_CONSTANTS } from \"../constants\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { SyncMetadata } from \"../types/sync-metadata\";\n\nexport class WorktreeMetadataService {\n private logger: Logger;\n\n constructor(logger?: Logger) {\n this.logger = logger ?? Logger.createDefault();\n }\n\n /**\n * Gets the internal worktree directory name from a worktree path.\n * Git uses the basename of the worktree path as the internal directory name.\n * For example: /worktrees/fix/test-branch -> test-branch (not fix/test-branch)\n */\n private getWorktreeDirectoryName(worktreePath: string): string {\n return path.basename(worktreePath);\n }\n\n async getMetadataPath(bareRepoPath: string, worktreeName: string): Promise<string> {\n if (worktreeName.includes(\"/\") || worktreeName.includes(\"\\\\\")) {\n throw new Error(\n `getMetadataPath requires a filesystem-safe worktree directory name, got '${worktreeName}'. Use getMetadataPathFromWorktreePath when starting from a raw branch name.`,\n );\n }\n return path.join(\n bareRepoPath,\n METADATA_CONSTANTS.WORKTREE_METADATA_PATH,\n worktreeName,\n METADATA_CONSTANTS.METADATA_FILENAME,\n );\n }\n\n async getMetadataPathFromWorktreePath(bareRepoPath: string, worktreePath: string): Promise<string> {\n // Extract the worktree directory name (basename) that Git actually uses\n const worktreeDirName = this.getWorktreeDirectoryName(worktreePath);\n return this.getMetadataPath(bareRepoPath, worktreeDirName);\n }\n\n async saveMetadata(bareRepoPath: string, worktreeName: string, metadata: SyncMetadata): Promise<void> {\n const metadataPath = await this.getMetadataPath(bareRepoPath, worktreeName);\n await fs.mkdir(path.dirname(metadataPath), { recursive: true });\n\n // Write to temp file then rename for atomicity \u2014 prevents corruption on crash.\n // Unique suffix avoids collisions between concurrent writers for the same worktree.\n const tmpPath = `${metadataPath}.${process.pid}.${Date.now()}.tmp`;\n let renamed = false;\n try {\n await fs.writeFile(tmpPath, JSON.stringify(metadata, null, 2), \"utf-8\");\n try {\n await fs.rename(tmpPath, metadataPath);\n renamed = true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === ERROR_MESSAGES.EXDEV) {\n await fs.copyFile(tmpPath, metadataPath);\n } else {\n throw err;\n }\n }\n } finally {\n if (!renamed) {\n await fs.unlink(tmpPath).catch(() => undefined);\n }\n }\n }\n\n async loadMetadata(bareRepoPath: string, worktreeName: string): Promise<SyncMetadata | null> {\n const metadataPath = await this.getMetadataPath(bareRepoPath, worktreeName);\n\n try {\n const content = await fs.readFile(metadataPath, \"utf-8\");\n return JSON.parse(content) as SyncMetadata;\n } catch {\n // Return null if file doesn't exist or can't be parsed\n return null;\n }\n }\n\n async loadMetadataFromPath(bareRepoPath: string, worktreePath: string): Promise<SyncMetadata | null> {\n const metadataPath = await this.getMetadataPathFromWorktreePath(bareRepoPath, worktreePath);\n\n try {\n const content = await fs.readFile(metadataPath, \"utf-8\");\n const metadata = JSON.parse(content) as SyncMetadata;\n\n if (!(await this.validateMetadata(metadata))) {\n this.logger.warn(`Corrupted metadata for ${worktreePath}, treating as missing`);\n return null;\n }\n\n return metadata;\n } catch {\n return null;\n }\n }\n\n async deleteMetadata(bareRepoPath: string, worktreeName: string): Promise<void> {\n const metadataPath = await this.getMetadataPath(bareRepoPath, worktreeName);\n\n try {\n await fs.unlink(metadataPath);\n } catch (error) {\n // Ignore errors if file doesn't exist\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n }\n\n async deleteMetadataFromPath(bareRepoPath: string, worktreePath: string): Promise<void> {\n const metadataPath = await this.getMetadataPathFromWorktreePath(bareRepoPath, worktreePath);\n\n try {\n await fs.unlink(metadataPath);\n } catch (error) {\n // Ignore errors if file doesn't exist\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n }\n\n async updateLastSync(\n bareRepoPath: string,\n worktreeName: string,\n commit: string,\n action: \"created\" | \"updated\" | \"fetched\" = \"updated\",\n ): Promise<void> {\n const existing = await this.loadMetadata(bareRepoPath, worktreeName);\n\n if (!existing) {\n this.logger.warn(\n `No metadata found for worktree ${worktreeName}; skipping update because upstream/parent context is unavailable`,\n );\n return;\n }\n\n existing.lastSyncCommit = commit;\n existing.lastSyncDate = new Date().toISOString();\n\n existing.syncHistory.push({\n date: existing.lastSyncDate,\n commit,\n action,\n });\n\n if (existing.syncHistory.length > METADATA_CONSTANTS.MAX_HISTORY_ENTRIES) {\n existing.syncHistory = existing.syncHistory.slice(-METADATA_CONSTANTS.MAX_HISTORY_ENTRIES);\n }\n\n await this.saveMetadata(bareRepoPath, worktreeName, existing);\n }\n\n async updateLastSyncFromPath(\n bareRepoPath: string,\n worktreePath: string,\n commit: string,\n action: \"created\" | \"updated\" | \"fetched\" = \"updated\",\n defaultBranch?: string,\n ): Promise<void> {\n const worktreeDirName = this.getWorktreeDirectoryName(worktreePath);\n const existing = await this.loadMetadataFromPath(bareRepoPath, worktreePath);\n\n if (!existing) {\n this.logger.warn(`No metadata found for worktree ${worktreeDirName}`);\n this.logger.info(` Attempting to create initial metadata...`);\n\n try {\n const worktreeGit = simpleGit(worktreePath);\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n\n const branchSummary = await worktreeGit.branch();\n const actualBranchName = branchSummary.current;\n\n if (!actualBranchName) {\n throw new Error(\"Could not determine current branch name\");\n }\n\n let upstreamBranch = `origin/${actualBranchName}`;\n try {\n const configuredUpstream = await worktreeGit.raw([\n \"rev-parse\",\n \"--abbrev-ref\",\n `${actualBranchName}@{upstream}`,\n ]);\n if (configuredUpstream.trim()) {\n upstreamBranch = configuredUpstream.trim();\n }\n } catch {\n // No configured upstream, use constructed value\n }\n\n const parentBranch = defaultBranch || GIT_CONSTANTS.DEFAULT_BRANCH;\n\n await this.createInitialMetadataFromPath(\n bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n upstreamBranch,\n parentBranch,\n currentCommit.trim(),\n );\n this.logger.info(` \u2705 Created metadata for ${worktreeDirName}`);\n return;\n } catch (error) {\n this.logger.error(` \u274C Failed to create metadata`, error);\n throw error;\n }\n }\n\n // Update metadata\n existing.lastSyncCommit = commit;\n existing.lastSyncDate = new Date().toISOString();\n\n existing.syncHistory.push({\n date: existing.lastSyncDate,\n commit,\n action,\n });\n\n if (existing.syncHistory.length > METADATA_CONSTANTS.MAX_HISTORY_ENTRIES) {\n existing.syncHistory = existing.syncHistory.slice(-METADATA_CONSTANTS.MAX_HISTORY_ENTRIES);\n }\n\n // Save using the directory name\n await this.saveMetadata(bareRepoPath, worktreeDirName, existing);\n }\n\n async createInitialMetadata(\n bareRepoPath: string,\n worktreeName: string,\n commit: string,\n upstreamBranch: string,\n parentBranch: string,\n parentCommit: string,\n ): Promise<void> {\n const metadata: SyncMetadata = {\n lastSyncCommit: commit,\n lastSyncDate: new Date().toISOString(),\n upstreamBranch,\n createdFrom: {\n branch: parentBranch,\n commit: parentCommit,\n },\n syncHistory: [\n {\n date: new Date().toISOString(),\n commit,\n action: \"created\",\n },\n ],\n };\n\n await this.saveMetadata(bareRepoPath, worktreeName, metadata);\n }\n\n async createInitialMetadataFromPath(\n bareRepoPath: string,\n worktreePath: string,\n commit: string,\n upstreamBranch: string,\n parentBranch: string,\n parentCommit: string,\n ): Promise<void> {\n const worktreeDirName = this.getWorktreeDirectoryName(worktreePath);\n const metadata: SyncMetadata = {\n lastSyncCommit: commit,\n lastSyncDate: new Date().toISOString(),\n upstreamBranch,\n createdFrom: {\n branch: parentBranch,\n commit: parentCommit,\n },\n syncHistory: [\n {\n date: new Date().toISOString(),\n commit,\n action: \"created\",\n },\n ],\n };\n\n await this.saveMetadata(bareRepoPath, worktreeDirName, metadata);\n }\n\n async validateMetadata(metadata: SyncMetadata): Promise<boolean> {\n if (!metadata.lastSyncCommit || !metadata.lastSyncDate || !metadata.upstreamBranch) {\n return false;\n }\n\n if (!/^[0-9a-f]+$/i.test(metadata.lastSyncCommit)) {\n return false;\n }\n\n if (Number.isNaN(new Date(metadata.lastSyncDate).getTime())) {\n return false;\n }\n\n return true;\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { ENV_CONSTANTS, GIT_CONSTANTS, GIT_OPERATIONS, PATH_CONSTANTS } from \"../constants\";\nimport { GitOperationError, WorktreeNotCleanError } from \"../errors\";\nimport { fileExists } from \"../utils/file-exists\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { SimpleGit } from \"simple-git\";\n\nexport interface WorktreeStatusDetails {\n modifiedFiles: number;\n deletedFiles: number;\n renamedFiles: number;\n createdFiles: number;\n conflictedFiles: number;\n untrackedFiles: number;\n unpushedCommitCount?: number;\n stashCount?: number;\n operationType?: string;\n modifiedSubmodules?: string[];\n modifiedFilesList?: string[];\n deletedFilesList?: string[];\n renamedFilesList?: Array<{ from: string; to: string }>;\n createdFilesList?: string[];\n conflictedFilesList?: string[];\n untrackedFilesList?: string[];\n}\n\nexport interface WorktreeStatusResult {\n isClean: boolean;\n hasUnpushedCommits: boolean;\n hasStashedChanges: boolean;\n hasOperationInProgress: boolean;\n hasModifiedSubmodules: boolean;\n upstreamGone: boolean;\n canRemove: boolean;\n reasons: string[];\n details?: WorktreeStatusDetails;\n}\n\nconst OPERATION_FILES: ReadonlyArray<{ file: string; type: string }> = [\n { file: GIT_OPERATIONS.MERGE_HEAD, type: \"merge\" },\n { file: GIT_OPERATIONS.CHERRY_PICK_HEAD, type: \"cherry-pick\" },\n { file: GIT_OPERATIONS.REVERT_HEAD, type: \"revert\" },\n { file: GIT_OPERATIONS.BISECT_LOG, type: \"bisect\" },\n { file: GIT_OPERATIONS.REBASE_MERGE, type: \"rebase\" },\n { file: GIT_OPERATIONS.REBASE_APPLY, type: \"rebase (apply)\" },\n];\n\ninterface WorktreeSnapshot {\n exists: boolean;\n status: Awaited<ReturnType<SimpleGit[\"status\"]>> | null;\n currentBranch: string | null;\n detached: boolean;\n remoteBranches: string[];\n upstream: string | null;\n unpushedCount: number | null;\n stashTotal: number | null;\n submoduleStatus: string | null;\n operationFile: string | null;\n gitDir: string | null;\n untrackedNotIgnored: string[];\n}\n\nexport class WorktreeStatusService {\n private gitInstances = new Map<string, SimpleGit>();\n private logger: Logger;\n\n constructor(\n private readonly config: { skipLfs?: boolean } = {},\n logger?: Logger,\n ) {\n this.logger = logger ?? Logger.createDefault();\n }\n\n async checkWorktreeStatus(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n const status = await worktreeGit.status();\n\n const hasTrackedChanges =\n status.modified.length > 0 ||\n status.deleted.length > 0 ||\n status.renamed.length > 0 ||\n status.created.length > 0 ||\n status.conflicted.length > 0;\n\n if (hasTrackedChanges) {\n return false;\n }\n\n if (status.not_added.length > 0) {\n const untrackedFiles = status.not_added;\n const notIgnoredFiles = await this.filterUntrackedFiles(worktreePath, untrackedFiles);\n return notIgnoredFiles.length === 0;\n }\n\n return true;\n }\n\n async getFullWorktreeStatus(\n worktreePath: string,\n includeDetails = false,\n lastSyncCommit?: string,\n ): Promise<WorktreeStatusResult> {\n if (!(await fileExists(worktreePath))) {\n return {\n isClean: true,\n hasUnpushedCommits: false,\n hasStashedChanges: false,\n hasOperationInProgress: false,\n hasModifiedSubmodules: false,\n upstreamGone: false,\n canRemove: true,\n reasons: [],\n };\n }\n\n const snap = await this.collectSnapshot(worktreePath, lastSyncCommit);\n\n const isClean = this.deriveIsClean(snap);\n const hasUnpushedCommits = !snap.detached && (snap.unpushedCount ?? 1) > 0;\n const hasStashedChanges = snap.stashTotal === null ? true : snap.stashTotal > 0;\n const hasOperationInProgress = snap.gitDir === null ? true : snap.operationFile !== null;\n const hasModifiedSubmodules = this.deriveModifiedSubmodules(snap).length > 0 || snap.submoduleStatus === null;\n const upstreamGone =\n !snap.detached && snap.upstream !== null && snap.remoteBranches.length > 0\n ? !snap.remoteBranches.includes(snap.upstream)\n : false;\n\n const reasons: string[] = [];\n if (!isClean) reasons.push(\"uncommitted changes\");\n if (hasUnpushedCommits) reasons.push(\"unpushed commits\");\n if (hasStashedChanges) reasons.push(\"stashed changes\");\n if (hasOperationInProgress) reasons.push(\"operation in progress\");\n if (hasModifiedSubmodules) reasons.push(\"modified submodules\");\n if (upstreamGone) reasons.push(\"upstream gone\");\n\n const canRemove =\n isClean && !hasUnpushedCommits && !hasStashedChanges && !hasOperationInProgress && !hasModifiedSubmodules;\n\n const details: WorktreeStatusDetails | undefined = includeDetails ? this.buildStatusDetails(snap) : undefined;\n\n return {\n isClean,\n hasUnpushedCommits,\n hasStashedChanges,\n hasOperationInProgress,\n hasModifiedSubmodules,\n upstreamGone,\n canRemove,\n reasons,\n details,\n };\n }\n\n private async collectSnapshot(worktreePath: string, lastSyncCommit?: string): Promise<WorktreeSnapshot> {\n const git = this.createGitInstance(worktreePath);\n\n const [status, branchResult, remoteBranchesResult, stashResult, submoduleResult, gitDirResult] = await Promise.all([\n git.status().catch((e: unknown) => {\n this.logger.error(`Error reading status for ${worktreePath}`, e);\n return null;\n }),\n git.branch().catch(() => null),\n git.branch([\"-r\"]).catch(() => null),\n git.stashList().catch((e: unknown) => {\n this.logger.error(`Error checking stash`, e);\n return null;\n }),\n git.raw([\"submodule\", \"status\"]).catch((e: unknown) => {\n this.logger.error(`Error checking submodule status`, e);\n return null;\n }),\n this.resolveGitDir(worktreePath).catch((e: unknown) => {\n this.logger.error(`Error checking operation in progress for ${worktreePath}`, e);\n return null;\n }),\n ]);\n\n const currentBranch = branchResult?.current ?? null;\n const detached = !branchResult?.current || Boolean((branchResult as { detached?: boolean })?.detached);\n\n let upstream: string | null = null;\n let unpushedCount: number | null = null;\n if (!detached && currentBranch) {\n const revListArgs = lastSyncCommit\n ? [\"rev-list\", \"--count\", `${lastSyncCommit}..HEAD`]\n : [\"rev-list\", \"--count\", currentBranch, \"--not\", \"--remotes\"];\n\n const [upstreamResult, unpushedResult] = await Promise.all([\n git.raw([\"rev-parse\", \"--abbrev-ref\", `${currentBranch}@{upstream}`]).then(\n (raw) => ({ ok: true as const, value: raw }),\n (error: unknown) => ({ ok: false as const, error }),\n ),\n git.raw(revListArgs).then(\n (raw) => ({ ok: true as const, value: raw }),\n (error: unknown) => ({ ok: false as const, error }),\n ),\n ]);\n\n if (upstreamResult.ok) {\n upstream = upstreamResult.value.trim() || null;\n } else {\n const errorMessage = getErrorMessage(upstreamResult.error);\n if (\n !errorMessage.includes(\"fatal: no upstream configured\") &&\n !errorMessage.includes(\"no upstream configured for branch\") &&\n !errorMessage.includes(\"fatal: ambiguous argument\") &&\n !errorMessage.includes(\"unknown revision or path\")\n ) {\n this.logger.error(`Unexpected error checking upstream status for ${worktreePath}: ${errorMessage}`);\n }\n }\n\n if (unpushedResult.ok) {\n unpushedCount = parseInt(unpushedResult.value.trim(), 10);\n } else {\n this.logger.error(`Error checking unpushed commits`, unpushedResult.error);\n }\n }\n\n const operationFile = gitDirResult ? await this.detectOperationFile(gitDirResult) : null;\n\n let untrackedNotIgnored: string[] = [];\n if (status && status.not_added.length > 0) {\n try {\n untrackedNotIgnored = await this.filterUntrackedFiles(worktreePath, status.not_added);\n } catch {\n untrackedNotIgnored = status.not_added;\n }\n }\n\n return {\n exists: true,\n status,\n currentBranch,\n detached,\n remoteBranches: remoteBranchesResult?.all ?? [],\n upstream,\n unpushedCount,\n stashTotal: stashResult?.total ?? null,\n submoduleStatus: submoduleResult,\n operationFile,\n gitDir: gitDirResult,\n untrackedNotIgnored,\n };\n }\n\n private deriveIsClean(snap: WorktreeSnapshot): boolean {\n const status = snap.status;\n if (!status) return false;\n const hasTracked =\n status.modified.length > 0 ||\n status.deleted.length > 0 ||\n status.renamed.length > 0 ||\n status.created.length > 0 ||\n status.conflicted.length > 0;\n if (hasTracked) return false;\n return snap.untrackedNotIgnored.length === 0;\n }\n\n private deriveModifiedSubmodules(snap: WorktreeSnapshot): string[] {\n if (!snap.submoduleStatus) return [];\n const modified: string[] = [];\n for (const line of snap.submoduleStatus.split(\"\\n\").filter((l) => l.trim())) {\n const firstChar = line.charAt(0);\n if (firstChar === GIT_CONSTANTS.SUBMODULE_STATUS_ADDED || firstChar === GIT_CONSTANTS.SUBMODULE_STATUS_REMOVED) {\n const match = line.match(/^[+-]\\s*(\\S+)/);\n if (match) modified.push(match[1]);\n }\n }\n return modified;\n }\n\n private buildStatusDetails(snap: WorktreeSnapshot): WorktreeStatusDetails {\n const status = snap.status;\n const details: WorktreeStatusDetails = {\n modifiedFiles: status?.modified.length ?? 0,\n deletedFiles: status?.deleted.length ?? 0,\n renamedFiles: status?.renamed.length ?? 0,\n createdFiles: status?.created.length ?? 0,\n conflictedFiles: status?.conflicted.length ?? 0,\n untrackedFiles: snap.untrackedNotIgnored.length,\n };\n if (status) {\n if (status.modified.length > 0) details.modifiedFilesList = status.modified;\n if (status.deleted.length > 0) details.deletedFilesList = status.deleted;\n if (status.renamed.length > 0) {\n details.renamedFilesList = status.renamed.map((r) => ({ from: r.from, to: r.to }));\n }\n if (status.created.length > 0) details.createdFilesList = status.created;\n if (status.conflicted.length > 0) details.conflictedFilesList = status.conflicted;\n }\n if (snap.untrackedNotIgnored.length > 0) details.untrackedFilesList = snap.untrackedNotIgnored;\n if (!snap.detached && snap.unpushedCount !== null) details.unpushedCommitCount = snap.unpushedCount;\n if (snap.stashTotal !== null) details.stashCount = snap.stashTotal;\n const opType = this.operationTypeFromFile(snap.operationFile);\n if (opType) details.operationType = opType;\n const modSubs = this.deriveModifiedSubmodules(snap);\n if (modSubs.length > 0) details.modifiedSubmodules = modSubs;\n return details;\n }\n\n private operationTypeFromFile(file: string | null): string | undefined {\n if (!file) return undefined;\n return OPERATION_FILES.find((op) => op.file === file)?.type;\n }\n\n private async detectOperationFile(gitDir: string): Promise<string | null> {\n const results = await Promise.all(\n OPERATION_FILES.map(({ file }) =>\n fs.access(path.join(gitDir, file)).then(\n () => true,\n () => false,\n ),\n ),\n );\n const idx = results.findIndex(Boolean);\n return idx >= 0 ? OPERATION_FILES[idx].file : null;\n }\n\n async hasUnpushedCommits(worktreePath: string, lastSyncCommit?: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n if (await this.isDetachedHead(worktreeGit)) {\n return false;\n }\n\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n if (lastSyncCommit) {\n try {\n const newCommitsResult = await worktreeGit.raw([\"rev-list\", \"--count\", `${lastSyncCommit}..HEAD`]);\n const newCommitsCount = parseInt(newCommitsResult.trim(), 10);\n return newCommitsCount > 0;\n } catch {\n // Fall through to regular check\n }\n }\n\n const result = await worktreeGit.raw([\"rev-list\", \"--count\", currentBranch, \"--not\", \"--remotes\"]);\n const unpushedCount = parseInt(result.trim(), 10);\n return unpushedCount > 0;\n } catch (error) {\n this.logger.error(`Error checking unpushed commits`, error);\n return true;\n }\n }\n\n async hasUpstreamGone(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n if (await this.isDetachedHead(worktreeGit)) {\n return false;\n }\n\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n const upstream = await worktreeGit.raw([\"rev-parse\", \"--abbrev-ref\", `${currentBranch}@{upstream}`]);\n const remoteBranches = await worktreeGit.branch([\"-r\"]);\n\n return !remoteBranches.all.includes(upstream.trim());\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n if (\n errorMessage.includes(\"fatal: no upstream configured\") ||\n errorMessage.includes(\"no upstream configured for branch\") ||\n errorMessage.includes(\"fatal: ambiguous argument\") ||\n errorMessage.includes(\"unknown revision or path\")\n ) {\n return false;\n }\n\n this.logger.error(`Unexpected error checking upstream status for ${worktreePath}: ${errorMessage}`);\n return true;\n }\n }\n\n async hasStashedChanges(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n const stashList = await worktreeGit.stashList();\n return stashList.total > 0;\n } catch (error) {\n this.logger.error(`Error checking stash`, error);\n return true; // Conservative: assume unsafe to delete\n }\n }\n\n async hasModifiedSubmodules(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n const result = await worktreeGit.raw([\"submodule\", \"status\"]);\n const lines = result.split(\"\\n\").filter((line) => line.trim());\n\n for (const line of lines) {\n const firstChar = line.charAt(0);\n if (\n firstChar === GIT_CONSTANTS.SUBMODULE_STATUS_ADDED ||\n firstChar === GIT_CONSTANTS.SUBMODULE_STATUS_REMOVED\n ) {\n return true;\n }\n }\n return false;\n } catch (error) {\n this.logger.error(`Error checking submodule status`, error);\n return true;\n }\n }\n\n async hasOperationInProgress(worktreePath: string): Promise<boolean> {\n try {\n const gitDir = await this.resolveGitDir(worktreePath);\n return (await this.detectOperationFile(gitDir)) !== null;\n } catch (error) {\n this.logger.error(`Error checking operation in progress for ${worktreePath}`, error);\n return true;\n }\n }\n\n async validateWorktreeForRemoval(worktreePath: string, lastSyncCommit?: string): Promise<void> {\n const status = await this.getFullWorktreeStatus(worktreePath, false, lastSyncCommit);\n\n if (!status.canRemove) {\n throw new WorktreeNotCleanError(worktreePath, status.reasons);\n }\n }\n\n private async filterUntrackedFiles(worktreePath: string, files: string[]): Promise<string[]> {\n if (files.length === 0) return [];\n\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n const result = await worktreeGit.raw([\"check-ignore\", \"--\", ...files]);\n\n const ignoredFiles = new Set(\n result\n .trim()\n .split(\"\\n\")\n .filter((f) => f),\n );\n return files.filter((f) => !ignoredFiles.has(f));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n if (errorMessage.includes(GIT_CONSTANTS.GIT_CHECK_IGNORE_NO_MATCH)) {\n return files;\n }\n\n throw error;\n }\n }\n\n private async isDetachedHead(worktreeGit: SimpleGit): Promise<boolean> {\n try {\n const branchSummary = await worktreeGit.branch();\n return !branchSummary.current || branchSummary.detached;\n } catch {\n return true;\n }\n }\n\n private async resolveGitDir(worktreePath: string): Promise<string> {\n const gitPath = path.join(worktreePath, PATH_CONSTANTS.GIT_DIR);\n\n try {\n const stat = await fs.stat(gitPath);\n\n if (stat.isFile()) {\n const content = await fs.readFile(gitPath, \"utf-8\");\n const gitdirMatch = content.match(new RegExp(`^${GIT_CONSTANTS.GITDIR_PREFIX}\\\\s*(.+)$`, \"m\"));\n if (gitdirMatch) {\n return path.resolve(worktreePath, gitdirMatch[1].trim());\n }\n throw new GitOperationError(\"resolve-git-dir\", `Failed to parse gitdir from .git file at ${gitPath}`);\n }\n\n return gitPath;\n } catch (error) {\n throw new GitOperationError(\n \"resolve-git-dir\",\n `Failed to resolve .git directory for ${worktreePath}`,\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n private createGitInstance(worktreePath: string): SimpleGit {\n const key = `${path.resolve(worktreePath)}::${this.config.skipLfs ? \"1\" : \"0\"}`;\n let git = this.gitInstances.get(key);\n if (!git) {\n git = this.config.skipLfs\n ? simpleGit(worktreePath).env({ [ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE]: \"1\" })\n : simpleGit(worktreePath);\n this.gitInstances.set(key, git);\n }\n return git;\n }\n}\n", "export interface ProgressEvent {\n phase: string;\n message: string;\n progress?: number;\n processed?: number;\n total?: number;\n}\n\nexport type ProgressListener = (event: ProgressEvent) => void;\n\nexport class ProgressEmitter {\n private listeners = new Set<ProgressListener>();\n\n onProgress(listener: ProgressListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n emit(event: ProgressEvent): void {\n // Snapshot so a listener that unsubscribes a sibling during emit doesn't\n // skip that sibling's notification for this event.\n for (const listener of [...this.listeners]) {\n try {\n listener(event);\n } catch {\n // Progress listeners must not break sync flow.\n }\n }\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport * as lockfile from \"proper-lockfile\";\n\nimport { DEFAULT_CONFIG, ENV_CONSTANTS } from \"../constants\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\nimport { getCloneModeLockTarget } from \"../utils/lock-path\";\nimport { REPOSITORY_MODES, resolveMode } from \"../utils/repo-mode\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { Config } from \"../types\";\nimport type { GitService } from \"./git.service\";\n\nexport type RepoLockRelease = () => Promise<void>;\n\nexport class RepoOperationLock {\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger = Logger.createDefault(),\n ) {}\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n async acquire(): Promise<RepoLockRelease | null> {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) {\n return async () => {};\n }\n\n if (resolveMode(this.config) === REPOSITORY_MODES.CLONE) {\n return this.acquireCloneModeLock();\n }\n\n return this.acquireWorktreeModeLock();\n }\n\n private async acquireCloneModeLock(): Promise<RepoLockRelease | null> {\n const target = getCloneModeLockTarget(this.config);\n const lockTarget = path.join(target.dir, target.file);\n try {\n await fs.mkdir(target.dir, { recursive: true });\n await fs.writeFile(lockTarget, \"\", { flag: \"a\" });\n } catch {\n // Couldn't prepare the lock target (read-only FS, ENOSPC, EACCES).\n // Treat as 'unable to acquire' so the operation is skipped cleanly\n // instead of crashing the whole sync run.\n return null;\n }\n return this.lockPath(lockTarget);\n }\n\n private async acquireWorktreeModeLock(): Promise<RepoLockRelease | null> {\n const barePath = this.gitService.getBareRepoPath();\n try {\n await fs.mkdir(barePath, { recursive: true });\n } catch {\n return null;\n }\n return this.lockPath(barePath);\n }\n\n private async lockPath(lockTarget: string): Promise<RepoLockRelease | null> {\n try {\n return await lockfile.lock(lockTarget, {\n stale: DEFAULT_CONFIG.LOCK_STALE_MS,\n update: DEFAULT_CONFIG.LOCK_UPDATE_MS,\n retries: 0,\n realpath: false,\n });\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ELOCKED\") {\n return null;\n }\n // A lock we cannot acquire (read-only FS, EACCES/EROFS/EPERM surfaced at\n // lock time rather than during prep) must be a clean skip, never a fatal\n // error that crashes the whole multi-repo run. Surface it as a warning so\n // the cause is visible.\n this.logger.warn(\n `Could not acquire repo lock at '${lockTarget}' (${code ?? \"unknown\"}: ${getErrorMessage(error)}); skipping.`,\n );\n return null;\n }\n }\n}\n", "import { createHash } from \"crypto\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\nimport { sanitizeNameForPath } from \"./sanitize-name\";\n\nimport type { Config, RepositoryConfig } from \"../types\";\n\nexport interface RepoLockTarget {\n /** Absolute path to the directory that should contain the lock file. */\n dir: string;\n /** Lock filename (created lazily by proper-lockfile). */\n file: string;\n}\n\nexport function getCloneModeLockTarget(config: Config): RepoLockTarget {\n const name = (config as RepositoryConfig).name;\n const configDir = config.__configFileDir;\n\n const hash = createHash(\"sha256\").update(path.resolve(config.worktreeDir)).digest(\"hex\").slice(0, 16);\n\n if (configDir) {\n return {\n dir: path.join(configDir, \".sync-worktrees-state\"),\n file: `${sanitizeNameForPath(name ?? \"repo\", \"clone-mode lock name\")}-${hash}.lock`,\n };\n }\n\n const stateBase =\n process.env.XDG_STATE_HOME && process.env.XDG_STATE_HOME.length > 0\n ? process.env.XDG_STATE_HOME\n : path.join(os.homedir(), \".cache\");\n const dir = path.join(stateBase, \"sync-worktrees\", \"locks\");\n return { dir, file: `${hash}.lock` };\n}\n", "import { getErrorMessage } from \"../utils/lfs-error\";\n\nimport type { GitService } from \"./git.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { Config } from \"../types\";\nimport type { RetryOptions } from \"../utils/retry\";\n\nexport interface SyncRetryContext {\n lfsSkipEnabled: boolean;\n}\n\nexport class SyncRetryPolicy {\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger,\n ) {}\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n createContext(): SyncRetryContext {\n return { lfsSkipEnabled: false };\n }\n\n createOptions(syncContext: SyncRetryContext): RetryOptions {\n return {\n maxAttempts: this.config.retry?.maxAttempts ?? 3,\n maxLfsRetries: this.config.retry?.maxLfsRetries ?? 2,\n initialDelayMs: this.config.retry?.initialDelayMs ?? 1000,\n maxDelayMs: this.config.retry?.maxDelayMs ?? 30000,\n backoffMultiplier: this.config.retry?.backoffMultiplier ?? 2,\n jitterMs: this.config.retry?.jitterMs ?? 0,\n onRetry: (error, attempt, context): void => {\n const errorMessage = getErrorMessage(error);\n this.logger.info(`\\n\u26A0\uFE0F Sync attempt ${attempt} failed: ${errorMessage}`);\n\n if (context?.isLfsError && !this.config.skipLfs) {\n this.logger.info(`\uD83D\uDD04 LFS error detected. Will retry with LFS skipped...`);\n } else {\n this.logger.info(`\uD83D\uDD04 Retrying synchronization...\\n`);\n }\n },\n lfsRetryHandler: (): void => {\n if (!this.config.skipLfs && !syncContext.lfsSkipEnabled) {\n this.logger.info(\"\u26A0\uFE0F Temporarily disabling LFS downloads for this sync...\");\n this.gitService.setLfsSkipEnabled(true);\n syncContext.lfsSkipEnabled = true;\n }\n },\n };\n }\n\n resetLfsSkipIfNeeded(syncContext: SyncRetryContext): void {\n if (syncContext.lfsSkipEnabled && !this.config.skipLfs) {\n this.gitService.setLfsSkipEnabled(false);\n }\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport pLimit from \"p-limit\";\n\nimport { DEFAULT_CONFIG, ERROR_MESSAGES, GIT_CONSTANTS, METADATA_CONSTANTS } from \"../constants\";\nimport { filterBranchesByName } from \"../utils/branch-filter\";\nimport { filterBranchesByAge, formatDuration } from \"../utils/date-filter\";\nimport { getErrorMessage, isLfsError } from \"../utils/lfs-error\";\n\nimport { PathResolutionService } from \"./path-resolution.service\";\nimport { createWorktreeSyncPlan } from \"./worktree-sync-planner\";\n\nimport type { GitService } from \"./git.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { ProgressEmitter } from \"./progress-emitter\";\nimport type { SyncOutcomeAccumulator } from \"./sync-outcome\";\nimport type { SyncRetryContext } from \"./sync-retry-policy\";\nimport type { WorktreeStatusDetails } from \"./worktree-status.service\";\nimport type { CreateAction, PruneAction, SparseAction, SyncPlan, UpdateAction } from \"./worktree-sync-planner\";\nimport type { Config } from \"../types\";\nimport type { PhaseTimer } from \"../utils/timing\";\n\nexport class WorktreeModeSyncRunner {\n private pathResolution = new PathResolutionService();\n\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger,\n private progressEmitter: ProgressEmitter,\n ) {}\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n async runSyncAttempt(\n phaseTimer: PhaseTimer,\n syncContext: SyncRetryContext,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n await this.gitService.pruneWorktrees();\n await this.fetchLatestRemoteData(phaseTimer, syncContext);\n\n const { remoteBranches, defaultBranch } = await this.resolveSyncBranches();\n\n await fs.mkdir(this.config.worktreeDir, { recursive: true });\n\n const worktrees = await this.gitService.getWorktrees();\n this.logger.info(`Found ${worktrees.length} existing Git worktrees.`);\n\n await this.cleanupOrphanedDirectories(worktrees);\n const syncPlan = createWorktreeSyncPlan(\n {\n remoteBranches,\n defaultBranch,\n existingWorktrees: worktrees,\n worktreeDir: this.config.worktreeDir,\n },\n {\n pathResolution: this.pathResolution,\n updateExistingWorktrees: this.config.updateExistingWorktrees !== false,\n sparseCheckout: this.config.sparseCheckout,\n },\n );\n\n await this.createNewWorktreesWithTiming(syncPlan, phaseTimer, outcome);\n await this.pruneOldWorktreesWithTiming(syncPlan.prune, phaseTimer, outcome);\n\n if (this.config.updateExistingWorktrees !== false) {\n await this.updateExistingWorktreesWithTiming(syncPlan.update, phaseTimer, outcome);\n }\n\n if (this.config.sparseCheckout) {\n await this.reapplySparseCheckout(syncPlan.sparse, outcome);\n }\n\n await this.finalizeSyncAttempt(phaseTimer);\n }\n\n private async reapplySparseCheckout(actions: SparseAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n const sparseConfig = this.config.sparseCheckout;\n if (!sparseConfig) return;\n\n this.logger.info(\"Step 5: Reconciling sparse-checkout patterns on existing worktrees...\");\n const sparseService = this.gitService.getSparseCheckoutService();\n const desired = sparseService.buildPatterns(sparseConfig);\n\n const limit = pLimit(this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\n\n await Promise.all(\n actions.map((action) =>\n limit(async () => {\n if (action.kind !== \"check-sparse\") return;\n\n try {\n try {\n await fs.access(action.path);\n } catch {\n return;\n }\n\n const current = await sparseService.readCurrent(action.path);\n if (current !== null && sparseService.patternsEqual(current, desired)) return;\n\n if (sparseService.isNarrowing(current, desired)) {\n const status = await this.gitService.getFullWorktreeStatus(action.path, false);\n if (!status.canRemove) {\n this.logger.warn(\n ` - Skipping sparse-checkout narrowing for '${action.branch}': ${status.reasons.join(\", \")}.`,\n );\n outcome.recordSkipped(\"sparse-checkout\", \"sparse_narrowing_unsafe\", {\n branch: action.branch,\n path: action.path,\n message: status.reasons.join(\", \"),\n });\n return;\n }\n }\n\n await sparseService.applyToWorktree(action.path, sparseConfig);\n await this.gitService.checkoutHead(action.path);\n this.logger.info(` - \u2705 Sparse-checkout updated for '${action.branch}'`);\n outcome.recordUpdated(action.branch, action.path, \"sparse_checkout\");\n } catch (error) {\n this.logger.warn(\n ` - \u26A0\uFE0F Failed to update sparse-checkout for '${action.branch}': ${getErrorMessage(error)}`,\n );\n outcome.recordFailed(\"sparse-checkout\", getErrorMessage(error), {\n reason: \"sparse_checkout_failed\",\n branch: action.branch,\n path: action.path,\n });\n }\n }),\n ),\n );\n }\n\n private async fetchLatestRemoteData(phaseTimer: PhaseTimer, syncContext: SyncRetryContext): Promise<void> {\n this.logger.info(\"Step 1: Fetching latest data from remote...\");\n phaseTimer.startPhase(\"Phase 1: Fetch\");\n this.progressEmitter.emit({ phase: \"fetch\", message: \"Fetching latest data from remote\" });\n\n try {\n await this.gitService.fetchAll();\n } catch (fetchError) {\n const errorMessage = getErrorMessage(fetchError);\n\n if (isLfsError(errorMessage) && !syncContext.lfsSkipEnabled && !this.config.skipLfs) {\n this.logger.info(\"\u26A0\uFE0F Fetch all failed due to LFS error. Attempting branch-by-branch fetch...\");\n this.logger.info(\"\u26A0\uFE0F Temporarily disabling LFS downloads for branch-by-branch fetch...\");\n this.gitService.setLfsSkipEnabled(true);\n syncContext.lfsSkipEnabled = true;\n await this.fetchBranchByBranch();\n } else {\n throw fetchError;\n }\n } finally {\n phaseTimer.endPhase();\n }\n }\n\n private async resolveSyncBranches(): Promise<{ remoteBranches: string[]; defaultBranch: string }> {\n const remoteBranches = this.config.branchMaxAge\n ? await this.getRemoteBranchesFilteredByActivity()\n : await this.getRemoteBranchesFilteredByName();\n const defaultBranch = this.gitService.getDefaultBranch();\n\n if (!remoteBranches.includes(defaultBranch)) {\n remoteBranches.push(defaultBranch);\n this.logger.info(`Ensuring default branch '${defaultBranch}' is retained.`);\n }\n\n return { remoteBranches, defaultBranch };\n }\n\n private async getRemoteBranchesFilteredByActivity(): Promise<string[]> {\n const branchesWithActivity = await this.gitService.getRemoteBranchesWithActivity();\n this.logger.info(`Found ${branchesWithActivity.length} remote branches.`);\n\n const branchNames = filterBranchesByName(\n branchesWithActivity.map((b) => b.branch),\n this.config.branchInclude,\n this.config.branchExclude,\n );\n\n if (branchNames.length < branchesWithActivity.length) {\n this.logger.info(\n `After branch name filtering: ${branchNames.length} of ${branchesWithActivity.length} branches.`,\n );\n }\n\n const branchNameSet = new Set(branchNames);\n const filteredByName = branchesWithActivity.filter((b) => branchNameSet.has(b.branch));\n const filteredBranches = filterBranchesByAge(filteredByName, this.config.branchMaxAge!);\n const remoteBranches = filteredBranches.map((b) => b.branch);\n\n this.logger.info(\n `After filtering by age (${formatDuration(this.config.branchMaxAge!)}): ${remoteBranches.length} branches.`,\n );\n\n if (filteredByName.length > remoteBranches.length) {\n const excludedCount = filteredByName.length - remoteBranches.length;\n this.logger.info(` - Excluded ${excludedCount} stale branches.`);\n }\n\n return remoteBranches;\n }\n\n private async getRemoteBranchesFilteredByName(): Promise<string[]> {\n const allBranches = await this.gitService.getRemoteBranches();\n this.logger.info(`Found ${allBranches.length} remote branches.`);\n\n const remoteBranches = filterBranchesByName(allBranches, this.config.branchInclude, this.config.branchExclude);\n\n if (remoteBranches.length < allBranches.length) {\n this.logger.info(`After branch name filtering: ${remoteBranches.length} of ${allBranches.length} branches.`);\n }\n\n return remoteBranches;\n }\n\n private async finalizeSyncAttempt(phaseTimer: PhaseTimer): Promise<void> {\n phaseTimer.startPhase(\"Phase 5: Cleanup\");\n this.progressEmitter.emit({ phase: \"cleanup\", message: \"Pruning worktree metadata\" });\n await this.gitService.pruneWorktrees();\n this.logger.info(\"Step 5: Pruned worktree metadata.\");\n phaseTimer.endPhase();\n }\n\n private async createNewWorktreesWithTiming(\n syncPlan: SyncPlan,\n phaseTimer: PhaseTimer,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n const maxConcurrent =\n this.config.parallelism?.maxWorktreeCreation ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_CREATION;\n phaseTimer.startPhase(\"Phase 2: Create\", maxConcurrent);\n this.progressEmitter.emit({ phase: \"create\", message: \"Creating worktrees for new branches\" });\n\n await this.createNewWorktrees(syncPlan.create, outcome);\n\n phaseTimer.setPhaseCount(\"Phase 2: Create\", syncPlan.create.length);\n phaseTimer.endPhase();\n }\n\n private async createNewWorktrees(actions: CreateAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n if (actions.length === 0) {\n this.logger.info(\"Step 2: No new branches to create worktrees for.\");\n return;\n }\n\n const plan: Array<{ branchName: string; worktreePath: string }> = [];\n for (const action of actions) {\n if (action.kind === \"skip-create\") {\n this.logger.error(\n ` \u274C Skipping '${action.branch}': sanitized worktree path '${action.path}' collides with existing branch '${action.conflictingBranch}'.`,\n );\n outcome.recordSkipped(\"branch\", \"path_collision\", {\n branch: action.branch,\n path: action.path,\n message: `Path collides with existing branch '${action.conflictingBranch}'`,\n });\n continue;\n }\n\n plan.push({ branchName: action.branch, worktreePath: action.path });\n }\n\n this.logger.info(`Step 2: Creating ${plan.length} new worktrees...`);\n\n // Worktree creation has concurrency=1 by default because Git's worktree.lock\n // can cause race conditions when multiple operations run simultaneously.\n // If concurrent operations try to create the same worktree, we gracefully handle\n // the \"already registered\" error by checking if the worktree actually exists.\n const maxConcurrent =\n this.config.parallelism?.maxWorktreeCreation ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_CREATION;\n const limit = pLimit(maxConcurrent);\n\n const results = await Promise.allSettled(\n plan.map(({ branchName, worktreePath }) =>\n limit(async () => {\n try {\n await this.gitService.addWorktree(branchName, worktreePath);\n this.logger.info(` \u2705 Created worktree for '${branchName}'`);\n outcome.recordCreated(branchName, worktreePath);\n } catch (error) {\n this.logger.error(` \u274C Failed to create worktree for '${branchName}':`, getErrorMessage(error));\n outcome.recordFailed(\"worktree\", getErrorMessage(error), {\n reason: \"create_failed\",\n branch: branchName,\n path: worktreePath,\n });\n throw error;\n }\n }),\n ),\n );\n\n const successCount = results.filter((r) => r.status === \"fulfilled\").length;\n this.logger.info(` Created ${successCount}/${plan.length} worktrees successfully`);\n }\n\n private async pruneOldWorktreesWithTiming(\n actions: PruneAction[],\n phaseTimer: PhaseTimer,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n const maxConcurrent = this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n phaseTimer.startPhase(\"Phase 3: Prune\", maxConcurrent);\n this.progressEmitter.emit({ phase: \"prune\", message: \"Pruning stale worktrees\" });\n\n await this.pruneOldWorktrees(actions, outcome);\n\n phaseTimer.setPhaseCount(\"Phase 3: Prune\", actions.length);\n phaseTimer.endPhase();\n }\n\n private async pruneOldWorktrees(actions: PruneAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n if (actions.length > 0) {\n this.logger.info(`Step 3: Checking ${actions.length} stale worktrees to prune...`);\n\n // Two-phase approach: First check status in parallel (read-only, safe),\n // then remove worktrees in parallel (mutation, needs lower concurrency)\n const maxConcurrent = this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n const limit = pLimit(maxConcurrent);\n\n const statusResults = await Promise.allSettled(\n actions.map(({ branch: branchName, path: worktreePath }) =>\n limit(async () => {\n const status = await this.gitService.getFullWorktreeStatus(worktreePath, this.config.debug);\n return { branchName, worktreePath, status };\n }).catch((error) => {\n throw Object.assign(error instanceof Error ? error : new Error(String(error)), { branchName });\n }),\n ),\n );\n\n const toRemove: Array<{ branchName: string; worktreePath: string }> = [];\n const toSkip: Array<{\n branchName: string;\n worktreePath: string;\n status: Awaited<ReturnType<GitService[\"getFullWorktreeStatus\"]>>;\n }> = [];\n\n for (const result of statusResults) {\n if (result.status === \"fulfilled\") {\n const { branchName, worktreePath, status } = result.value;\n if (status.canRemove) {\n toRemove.push({ branchName, worktreePath });\n } else {\n toSkip.push({ branchName, worktreePath, status });\n }\n } else {\n const branchName = (result.reason as Error & { branchName?: string })?.branchName ?? \"unknown\";\n this.logger.error(` - Error checking worktree '${branchName}':`, result.reason);\n this.logger.warn(` - \u26A0\uFE0F Skipping removal of '${branchName}' due to status check failure (conservative)`);\n outcome.recordSkipped(\"worktree\", \"prune_status_check_failed\", {\n branch: branchName,\n message: getErrorMessage(result.reason),\n });\n }\n }\n\n if (toRemove.length > 0) {\n const removeLimit = pLimit(\n this.config.parallelism?.maxWorktreeRemoval ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_REMOVAL,\n );\n\n const removeResults = await Promise.allSettled(\n toRemove.map(({ branchName, worktreePath }) =>\n removeLimit(async () => {\n try {\n // Re-validate status immediately before removal to close TOCTOU window.\n const recheck = await this.gitService.getFullWorktreeStatus(worktreePath, false);\n if (!recheck.canRemove) {\n this.logger.warn(\n ` \u26A0\uFE0F Skipping removal of '${branchName}' - status changed since initial check: ${recheck.reasons.join(\", \")}`,\n );\n outcome.recordSkipped(\"worktree\", \"prune_status_changed\", {\n branch: branchName,\n path: worktreePath,\n message: recheck.reasons.join(\", \"),\n });\n return;\n }\n await this.gitService.removeWorktree(worktreePath);\n this.logger.info(` \u2705 Removed worktree for '${branchName}'`);\n outcome.recordRemoved(branchName, worktreePath);\n } catch (error) {\n this.logger.error(` \u274C Failed to remove worktree for '${branchName}':`, getErrorMessage(error));\n outcome.recordFailed(\"worktree\", getErrorMessage(error), {\n reason: \"remove_failed\",\n branch: branchName,\n path: worktreePath,\n });\n throw error;\n }\n }),\n ),\n );\n\n const removedCount = removeResults.filter((r) => r.status === \"fulfilled\").length;\n this.logger.info(` Removed ${removedCount}/${toRemove.length} worktrees successfully`);\n }\n\n if (toSkip.length > 0) {\n this.logger.info(` Skipped ${toSkip.length} worktree(s) with local changes or unpushed commits`);\n }\n\n for (const { branchName, worktreePath, status } of toSkip) {\n outcome.recordSkipped(\"worktree\", \"unsafe_to_remove\", {\n branch: branchName,\n path: worktreePath,\n message: status.reasons.join(\", \"),\n });\n\n if (status.upstreamGone && status.hasUnpushedCommits) {\n this.logger.warn(` - \u26A0\uFE0F Cannot automatically remove '${branchName}' - upstream branch was deleted.`);\n this.logger.info(` Please review manually: cd ${worktreePath} && git log`);\n this.logger.info(\n ` If changes were squash-merged, you can safely remove with: git worktree remove ${worktreePath}`,\n );\n } else {\n this.logger.info(` - \u26A0\uFE0F Skipping removal of '${branchName}' due to: ${status.reasons.join(\", \")}.`);\n }\n\n if (this.config.debug && status.details) {\n this.logDebugDetails(branchName, status.details);\n }\n }\n } else {\n this.logger.info(\"Step 3: No stale worktrees to prune.\");\n }\n }\n\n private logDebugDetails(branchName: string, details: WorktreeStatusDetails): void {\n this.logger.info(`\\n \uD83D\uDD0D Debug details for '${branchName}':`);\n\n if (details.modifiedFiles > 0 && details.modifiedFilesList) {\n this.logger.info(` - Modified files (${details.modifiedFiles}):`);\n details.modifiedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.deletedFiles > 0 && details.deletedFilesList) {\n this.logger.info(` - Deleted files (${details.deletedFiles}):`);\n details.deletedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.renamedFiles > 0 && details.renamedFilesList) {\n this.logger.info(` - Renamed files (${details.renamedFiles}):`);\n details.renamedFilesList.forEach((file) => this.logger.info(` \u2022 ${file.from} \u2192 ${file.to}`));\n }\n if (details.createdFiles > 0 && details.createdFilesList) {\n this.logger.info(` - Created files (${details.createdFiles}):`);\n details.createdFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.conflictedFiles > 0 && details.conflictedFilesList) {\n this.logger.info(` - Conflicted files (${details.conflictedFiles}):`);\n details.conflictedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.untrackedFiles > 0 && details.untrackedFilesList) {\n this.logger.info(` - Untracked files (not ignored) (${details.untrackedFiles}):`);\n details.untrackedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.unpushedCommitCount !== undefined && details.unpushedCommitCount > 0) {\n this.logger.info(` - Unpushed commits: ${details.unpushedCommitCount}`);\n }\n if (details.stashCount !== undefined && details.stashCount > 0) {\n this.logger.info(` - Stashed changes: ${details.stashCount}`);\n }\n if (details.operationType) {\n this.logger.info(` - Operation in progress: ${details.operationType}`);\n }\n if (details.modifiedSubmodules && details.modifiedSubmodules.length > 0) {\n this.logger.info(` - Modified submodules (${details.modifiedSubmodules.length}):`);\n details.modifiedSubmodules.forEach((submodule) => this.logger.info(` \u2022 ${submodule}`));\n }\n\n this.logger.info(\"\");\n }\n\n private async fetchBranchByBranch(): Promise<void> {\n this.logger.info(\"Fetching branches individually to isolate LFS errors...\");\n\n const remoteBranches = await this.gitService.getRemoteBranches();\n this.logger.info(`Found ${remoteBranches.length} remote branches to fetch.`);\n\n const fetchLimit = pLimit(\n this.config.parallelism?.maxBranchFetches ?? DEFAULT_CONFIG.PARALLELISM.MAX_BRANCH_FETCHES,\n );\n const failedBranches: string[] = [];\n let successCount = 0;\n\n const results = await Promise.allSettled(\n remoteBranches.map((branch) =>\n fetchLimit(async () => {\n await this.gitService.fetchBranch(branch);\n return branch;\n }),\n ),\n );\n\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n if (result.status === \"fulfilled\") {\n successCount++;\n } else {\n const errorMessage = getErrorMessage(result.reason);\n this.logger.info(` \u26A0\uFE0F Failed to fetch branch '${remoteBranches[i]}': ${errorMessage}`);\n failedBranches.push(remoteBranches[i]);\n }\n }\n\n this.logger.info(`Branch-by-branch fetch completed: ${successCount}/${remoteBranches.length} successful`);\n\n if (failedBranches.length > 0) {\n this.logger.info(`\u26A0\uFE0F Failed to fetch ${failedBranches.length} branches due to errors.`);\n this.logger.info(` These branches will be skipped: ${failedBranches.join(\", \")}`);\n }\n }\n\n private async updateExistingWorktreesWithTiming(\n actions: UpdateAction[],\n phaseTimer: PhaseTimer,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n const maxConcurrent =\n this.config.parallelism?.maxWorktreeUpdates ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_UPDATES;\n phaseTimer.startPhase(\"Phase 4: Update\", maxConcurrent);\n this.progressEmitter.emit({ phase: \"update\", message: \"Updating existing worktrees\" });\n\n await this.updateExistingWorktrees(actions, outcome);\n\n phaseTimer.setPhaseCount(\"Phase 4: Update\", actions.length);\n phaseTimer.endPhase();\n }\n\n private async updateExistingWorktrees(actions: UpdateAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n this.logger.info(\"Step 4: Checking for worktrees that need updates...\");\n\n const divergedDir = path.join(this.config.worktreeDir, GIT_CONSTANTS.DIVERGED_DIR_NAME);\n try {\n const diverged = await fs.readdir(divergedDir);\n if (diverged.length > 0) {\n this.logger.info(\n `\uD83D\uDCE6 Note: ${diverged.length} diverged worktree(s) in ${path.relative(process.cwd(), divergedDir)}`,\n );\n }\n } catch {\n // No diverged directory, that's fine.\n }\n\n type UpdateCheckResult =\n | { action: \"update\" | \"diverged\"; worktree: { path: string; branch: string } }\n | {\n action: \"skip\" | \"noop\";\n worktree: { path: string; branch: string };\n reason: string;\n message?: string;\n };\n\n // Phase 4a: Check which worktrees need updates (parallel, read-only, high concurrency)\n const maxConcurrent = this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n const limit = pLimit(maxConcurrent);\n\n const checkResults = await Promise.allSettled(\n actions.map((action) =>\n limit(async (): Promise<UpdateCheckResult> => {\n const worktree = { path: action.path, branch: action.branch };\n\n try {\n await fs.access(worktree.path);\n } catch {\n return { action: \"skip\", worktree, reason: \"missing_worktree_path\" };\n }\n\n const hasOp = await this.gitService.hasOperationInProgress(worktree.path);\n if (hasOp) return { action: \"skip\", worktree, reason: \"operation_in_progress\" };\n\n const isClean = await this.gitService.checkWorktreeStatus(worktree.path);\n if (!isClean) return { action: \"skip\", worktree, reason: \"dirty_worktree\" };\n\n const canFastForward = await this.gitService.canFastForward(worktree.path, worktree.branch);\n if (!canFastForward) {\n const isAhead = await this.gitService.isLocalAheadOfRemote(worktree.path, worktree.branch);\n if (isAhead) {\n this.logger.info(`\u23ED\uFE0F Skipping '${worktree.branch}' - has unpushed commits`);\n return { action: \"skip\", worktree, reason: \"local_ahead\" };\n }\n return { action: \"diverged\", worktree };\n }\n\n const isBehind = await this.gitService.isWorktreeBehind(worktree.path);\n if (!isBehind) return { action: \"noop\", worktree, reason: \"already_up_to_date\" };\n\n const sparseCfg = this.config.sparseCheckout;\n if (sparseCfg && sparseCfg.skipUpdateWhenOutsideSparse !== false) {\n const sparseService = this.gitService.getSparseCheckoutService();\n if (sparseService.resolveMode(sparseCfg) === \"cone\") {\n const diff = await this.gitService.getChangedPathsInRange(\n worktree.path,\n \"HEAD\",\n `origin/${worktree.branch}`,\n );\n // null = git diff failed; force update rather than treat the failure as \"no sparse paths affected\".\n if (diff !== null && !sparseService.pathsTouchSparse(diff, sparseCfg)) {\n this.logger.info(`\u23ED\uFE0F Skipping '${worktree.branch}' - upstream changes outside sparse paths`);\n return { action: \"skip\", worktree, reason: \"outside_sparse_checkout\" };\n }\n }\n }\n\n return { action: \"update\", worktree };\n }),\n ),\n );\n\n const worktreesToUpdate: { path: string; branch: string }[] = [];\n const divergedWorktrees: { path: string; branch: string }[] = [];\n\n for (const result of checkResults) {\n if (result.status === \"fulfilled\" && result.value) {\n switch (result.value.action) {\n case \"update\":\n worktreesToUpdate.push(result.value.worktree);\n break;\n case \"diverged\":\n divergedWorktrees.push(result.value.worktree);\n break;\n case \"noop\":\n outcome.recordNoop(\"worktree\", result.value.reason, result.value.worktree);\n break;\n case \"skip\":\n outcome.recordSkipped(\"worktree\", result.value.reason, result.value.worktree);\n break;\n }\n } else if (result.status === \"rejected\") {\n // Probe-only failure (status / fast-forward / divergence check threw). The\n // actual update is gated on success here, so a probe error means we never\n // touched the worktree \u2014 treat it as a skip, not a hard failure.\n this.logger.error(` - Error checking worktree:`, result.reason);\n outcome.recordSkipped(\"worktree\", \"update_check_failed\", {\n message: getErrorMessage(result.reason),\n });\n }\n }\n\n // Phase 4b: Perform mutations (updates + diverged handling) with lower concurrency\n const updateLimit = pLimit(\n this.config.parallelism?.maxWorktreeUpdates ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_UPDATES,\n );\n\n const mutationTasks: Promise<{ type: \"update\" | \"diverged\"; branch: string }>[] = [];\n\n for (const worktree of worktreesToUpdate) {\n mutationTasks.push(\n updateLimit(async () => {\n try {\n this.logger.info(` - Updating worktree '${worktree.branch}'...`);\n await this.gitService.updateWorktree(worktree.path);\n this.logger.info(` \u2705 Successfully updated '${worktree.branch}'.`);\n outcome.recordUpdated(worktree.branch, worktree.path, \"fast_forward\");\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n if (ERROR_MESSAGES.FAST_FORWARD_FAILED.some((msg) => errorMessage.includes(msg))) {\n this.logger.info(\n ` \u26A0\uFE0F Branch '${worktree.branch}' cannot be fast-forwarded. Checking for divergence...`,\n );\n try {\n await this.handleDivergedBranch(worktree, outcome);\n } catch (divergedError) {\n this.logger.error(` \u274C Failed to handle diverged branch '${worktree.branch}':`, divergedError);\n outcome.recordFailed(\"worktree\", getErrorMessage(divergedError), {\n reason: \"diverged_recovery_failed\",\n branch: worktree.branch,\n path: worktree.path,\n });\n throw divergedError;\n }\n } else {\n this.logger.error(` \u274C Failed to update '${worktree.branch}':`, error);\n outcome.recordFailed(\"worktree\", errorMessage, {\n reason: \"update_failed\",\n branch: worktree.branch,\n path: worktree.path,\n });\n throw error;\n }\n }\n return { type: \"update\" as const, branch: worktree.branch };\n }),\n );\n }\n\n for (const worktree of divergedWorktrees) {\n mutationTasks.push(\n updateLimit(async () => {\n try {\n await this.handleDivergedBranch(worktree, outcome);\n } catch (error) {\n this.logger.error(` \u274C Failed to handle diverged branch '${worktree.branch}':`, error);\n outcome.recordFailed(\"worktree\", getErrorMessage(error), {\n reason: \"diverged_recovery_failed\",\n branch: worktree.branch,\n path: worktree.path,\n });\n throw error;\n }\n return { type: \"diverged\" as const, branch: worktree.branch };\n }),\n );\n }\n\n if (mutationTasks.length > 0) {\n if (worktreesToUpdate.length > 0) {\n this.logger.info(` - Found ${worktreesToUpdate.length} worktrees behind their upstream branches.`);\n }\n if (divergedWorktrees.length > 0) {\n this.logger.info(` - Found ${divergedWorktrees.length} diverged worktrees to handle.`);\n }\n\n const mutationResults = await Promise.allSettled(mutationTasks);\n\n const successCount = mutationResults.filter((r) => r.status === \"fulfilled\").length;\n this.logger.info(` Processed ${successCount}/${mutationTasks.length} worktrees successfully`);\n } else {\n this.logger.info(\" - All worktrees are up to date.\");\n }\n }\n\n private async cleanupOrphanedDirectories(worktrees: { path: string; branch: string }[]): Promise<void> {\n try {\n const worktreeRelativePaths = worktrees.map((w) => path.relative(this.config.worktreeDir, w.path));\n const allDirs = await fs.readdir(this.config.worktreeDir);\n\n // Filter out special directories like .diverged.\n const regularDirs = allDirs.filter((dir) => !dir.startsWith(\".\"));\n\n const orphanedDirs: string[] = [];\n for (const dir of regularDirs) {\n const isPartOfWorktree = worktreeRelativePaths.some((worktreePath) => {\n return worktreePath === dir || worktreePath.startsWith(dir + path.sep);\n });\n\n if (!isPartOfWorktree) {\n orphanedDirs.push(dir);\n }\n }\n\n if (orphanedDirs.length > 0) {\n this.logger.info(`Found ${orphanedDirs.length} orphaned directories: ${orphanedDirs.join(\", \")}`);\n\n for (const dir of orphanedDirs) {\n const dirPath = path.join(this.config.worktreeDir, dir);\n try {\n const stat = await fs.stat(dirPath);\n if (stat.isDirectory()) {\n await fs.rm(dirPath, { recursive: true, force: true });\n this.logger.info(` - Removed orphaned directory: ${dir}`);\n }\n } catch (error) {\n this.logger.error(` - Failed to remove orphaned directory ${dir}:`, error);\n }\n }\n }\n } catch (error) {\n this.logger.error(\"Error during orphaned directory cleanup:\", error);\n }\n }\n\n private async handleDivergedBranch(\n worktree: { path: string; branch: string },\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n this.logger.info(`\u26A0\uFE0F Branch '${worktree.branch}' has diverged from upstream. Analyzing...`);\n\n const treesIdentical = await this.gitService.compareTreeContent(worktree.path, worktree.branch);\n\n if (treesIdentical) {\n this.logger.info(`\u2705 Branch '${worktree.branch}' was rebased but files are identical. Resetting to upstream...`);\n await this.gitService.resetToUpstream(worktree.path, worktree.branch);\n this.logger.info(` Successfully updated '${worktree.branch}' to match upstream.`);\n outcome.recordUpdated(worktree.branch, worktree.path, \"reset_identical_tree\");\n } else {\n const hasLocalChanges = await this.hasLocalChangesSinceLastSync(worktree.path);\n\n if (!hasLocalChanges) {\n this.logger.info(\n `\u2705 Branch '${worktree.branch}' has diverged but you made no local changes. Resetting to upstream...`,\n );\n await this.gitService.resetToUpstream(worktree.path, worktree.branch);\n this.logger.info(` Successfully updated '${worktree.branch}' to match upstream.`);\n outcome.recordUpdated(worktree.branch, worktree.path, \"reset_no_local_changes\");\n } else {\n this.logger.info(`\uD83D\uDD12 Branch '${worktree.branch}' has diverged with local changes. Moving to diverged...`);\n\n const divergedPath = await this.divergeWorktree(worktree.path, worktree.branch);\n const relativePath = path.relative(process.cwd(), divergedPath);\n outcome.recordPreservedDiverged(worktree.branch, worktree.path, divergedPath);\n\n this.logger.info(` Moved to: ${relativePath}`);\n this.logger.info(` Your local changes are preserved. To review:`);\n this.logger.info(` cd ${relativePath}`);\n this.logger.info(` git diff origin/${worktree.branch}`);\n\n await this.gitService.removeWorktree(worktree.path);\n await this.gitService.addWorktree(worktree.branch, worktree.path);\n this.logger.info(` Created fresh worktree from upstream at: ${worktree.path}`);\n }\n }\n }\n\n private async hasLocalChangesSinceLastSync(worktreePath: string): Promise<boolean> {\n try {\n const metadata = await this.gitService.getWorktreeMetadata(worktreePath);\n if (!metadata || !metadata.lastSyncCommit) {\n return true;\n }\n\n const currentCommit = await this.gitService.getCurrentCommit(worktreePath);\n return currentCommit !== metadata.lastSyncCommit;\n } catch {\n return true;\n }\n }\n\n private async divergeWorktree(worktreePath: string, branchName: string): Promise<string> {\n const divergedBaseDir = path.join(this.config.worktreeDir, GIT_CONSTANTS.DIVERGED_DIR_NAME);\n\n const timestamp = new Date().toISOString().split(\"T\")[0];\n const uniqueSuffix = Date.now().toString(36) + Math.random().toString(36).substring(2, 7);\n const safeBranchName = this.pathResolution.sanitizeBranchName(branchName);\n const divergedName = `${timestamp}-${safeBranchName}-${uniqueSuffix}`;\n const divergedPath = path.join(divergedBaseDir, divergedName);\n\n await fs.mkdir(divergedBaseDir, { recursive: true });\n\n try {\n await fs.rename(worktreePath, divergedPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === ERROR_MESSAGES.EXDEV) {\n await fs.cp(worktreePath, divergedPath, { recursive: true });\n await fs.rm(worktreePath, { recursive: true, force: true });\n } else {\n throw err;\n }\n }\n\n const metadata = {\n originalBranch: branchName,\n divergedAt: new Date().toISOString(),\n reason: METADATA_CONSTANTS.DIVERGED_REASON,\n originalPath: worktreePath,\n localCommit: await this.gitService.getCurrentCommit(divergedPath),\n remoteCommit: await this.gitService.getRemoteCommit(`origin/${branchName}`),\n instruction: `To preserve your changes:\n 1. Review: git diff origin/${branchName}\n 2. Keep changes: git push --force-with-lease origin ${branchName}\n 3. Discard changes: rm -rf this directory\n\n Original worktree location: ${worktreePath}`,\n };\n\n await fs.writeFile(\n path.join(divergedPath, METADATA_CONSTANTS.DIVERGED_INFO_FILE),\n JSON.stringify(metadata, null, 2),\n );\n\n return divergedPath;\n }\n}\n", "export function parseDuration(durationStr: string): number | null {\n const match = durationStr.match(/^(\\d+)([hdwmy])$/);\n if (!match) {\n return null;\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n const multipliers: Record<string, number> = {\n h: 60 * 60 * 1000, // hours\n d: 24 * 60 * 60 * 1000, // days\n w: 7 * 24 * 60 * 60 * 1000, // weeks\n m: 30 * 24 * 60 * 60 * 1000, // months (approximate)\n y: 365 * 24 * 60 * 60 * 1000, // years (approximate)\n };\n\n return value * multipliers[unit];\n}\n\nexport function filterBranchesByAge(\n branches: { branch: string; lastActivity: Date }[],\n maxAge: string,\n): { branch: string; lastActivity: Date }[] {\n const maxAgeMs = parseDuration(maxAge);\n if (maxAgeMs === null) {\n console.warn(`Invalid duration format: ${maxAge}. Using all branches.`);\n return branches;\n }\n\n const cutoffDate = new Date(Date.now() - maxAgeMs);\n\n return branches.filter(({ lastActivity }) => lastActivity >= cutoffDate);\n}\n\nexport function formatDuration(durationStr: string): string {\n const match = durationStr.match(/^(\\d+)([hdwmy])$/);\n if (!match) {\n return durationStr;\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n const unitNames: Record<string, string> = {\n h: value === 1 ? \"hour\" : \"hours\",\n d: value === 1 ? \"day\" : \"days\",\n w: value === 1 ? \"week\" : \"weeks\",\n m: value === 1 ? \"month\" : \"months\",\n y: value === 1 ? \"year\" : \"years\",\n };\n\n return `${value} ${unitNames[unit]}`;\n}\n", "import { createHash } from \"crypto\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\nimport { isCaseInsensitiveFs } from \"../utils/path-compare\";\n\nconst BRANCH_STEM_MAX = 80;\nconst BRANCH_HASH_LEN = 8;\n\nexport class PathResolutionService {\n sanitizeBranchName(branchName: string): string {\n const stem = branchName\n .replace(/\\//g, \"-\")\n .replace(/[^a-zA-Z0-9_-]/g, \"_\")\n .slice(0, BRANCH_STEM_MAX);\n const hash = createHash(\"sha256\").update(branchName).digest(\"hex\").slice(0, BRANCH_HASH_LEN);\n return `${stem}-${hash}`;\n }\n\n getBranchWorktreePath(worktreeDir: string, branchName: string): string {\n return path.join(worktreeDir, this.sanitizeBranchName(branchName));\n }\n\n private resolveRealPath(inputPath: string): string {\n const absolute = path.resolve(inputPath);\n const missing: string[] = [];\n let current = absolute;\n\n while (!fs.existsSync(current)) {\n const parent = path.dirname(current);\n if (parent === current) {\n return absolute;\n }\n missing.unshift(path.basename(current));\n current = parent;\n }\n\n try {\n return path.join(fs.realpathSync(current), ...missing);\n } catch {\n return absolute;\n }\n }\n\n private isResolvedPathInsideBase(resolved: string, resolvedBase: string): boolean {\n const fold = (p: string): string => (isCaseInsensitiveFs() ? p.toLowerCase() : p);\n const a = fold(resolved);\n const b = fold(resolvedBase);\n if (a === b) return true;\n return a.length > b.length && a.charAt(b.length) === path.sep && a.startsWith(b);\n }\n\n normalizeWorktreePath(worktreePath: string, worktreeBaseDir: string): string {\n const resolved = this.resolveRealPath(worktreePath);\n const resolvedBase = this.resolveRealPath(worktreeBaseDir);\n if (!this.isResolvedPathInsideBase(resolved, resolvedBase)) {\n throw new Error(`Worktree path '${worktreePath}' is outside base directory '${worktreeBaseDir}'`);\n }\n return path.relative(resolvedBase, resolved);\n }\n\n isPathInsideBaseDir(targetPath: string, baseDir: string): boolean {\n const resolved = this.resolveRealPath(targetPath);\n const resolvedBase = this.resolveRealPath(baseDir);\n return this.isResolvedPathInsideBase(resolved, resolvedBase);\n }\n\n extractBranchFromWorktreePath(worktreePath: string, worktreeBaseDir: string): string {\n return this.normalizeWorktreePath(worktreePath, worktreeBaseDir);\n }\n}\n", "import * as path from \"path\";\n\nimport { PathResolutionService } from \"./path-resolution.service\";\n\nimport type { SparseCheckoutConfig } from \"../types\";\n\nexport interface WorktreeInventory {\n remoteBranches: string[];\n defaultBranch: string;\n existingWorktrees: WorktreeEntry[];\n worktreeDir: string;\n}\n\nexport interface WorktreeEntry {\n path: string;\n branch: string;\n}\n\nexport type CreateAction =\n | { kind: \"create\"; branch: string; path: string }\n | { kind: \"skip-create\"; branch: string; path: string; reason: \"path-collision\"; conflictingBranch: string };\n\nexport type PruneAction = { kind: \"check-prune\"; branch: string; path: string };\n\nexport type UpdateAction = { kind: \"update-candidate\"; branch: string; path: string };\n\nexport type SparseAction =\n | { kind: \"check-sparse\"; branch: string; path: string }\n | { kind: \"skip-sparse\"; branch: string; path: string; reason: \"not-configured\" };\n\nexport type SyncAction = CreateAction | PruneAction | UpdateAction | SparseAction;\n\nexport interface SyncPlan {\n create: CreateAction[];\n prune: PruneAction[];\n update: UpdateAction[];\n sparse: SparseAction[];\n warnings: string[];\n}\n\nexport interface SyncPlanOptions {\n pathResolution?: PathResolutionService;\n updateExistingWorktrees?: boolean;\n sparseCheckout?: SparseCheckoutConfig;\n}\n\nexport function createWorktreeSyncPlan(inventory: WorktreeInventory, options: SyncPlanOptions = {}): SyncPlan {\n return {\n create: planCreateActions(inventory, options),\n prune: planPruneActions(inventory),\n update: options.updateExistingWorktrees === false ? [] : planUpdateActions(inventory),\n sparse: planSparseActions(inventory, options.sparseCheckout),\n warnings: [],\n };\n}\n\nexport function planCreateActions(inventory: WorktreeInventory, options: SyncPlanOptions = {}): CreateAction[] {\n const pathResolution = options.pathResolution ?? new PathResolutionService();\n const existingBranches = new Set(inventory.existingWorktrees.map((w) => w.branch));\n const newBranches = inventory.remoteBranches.filter(\n (branch) => !existingBranches.has(branch) && branch !== inventory.defaultBranch,\n );\n\n const reservedPaths = new Map<string, string>();\n for (const worktree of inventory.existingWorktrees) {\n reservedPaths.set(path.resolve(worktree.path), worktree.branch);\n }\n\n const actions: CreateAction[] = [];\n for (const branch of newBranches) {\n const worktreePath = pathResolution.getBranchWorktreePath(inventory.worktreeDir, branch);\n const resolved = path.resolve(worktreePath);\n const conflictingBranch = reservedPaths.get(resolved);\n\n if (conflictingBranch && conflictingBranch !== branch) {\n actions.push({\n kind: \"skip-create\",\n branch,\n path: worktreePath,\n reason: \"path-collision\",\n conflictingBranch,\n });\n continue;\n }\n\n reservedPaths.set(resolved, branch);\n actions.push({ kind: \"create\", branch, path: worktreePath });\n }\n\n return actions;\n}\n\nexport function planPruneActions(inventory: WorktreeInventory): PruneAction[] {\n const remoteBranches = new Set(inventory.remoteBranches);\n return inventory.existingWorktrees\n .filter((worktree) => !remoteBranches.has(worktree.branch))\n .map((worktree) => ({ kind: \"check-prune\", branch: worktree.branch, path: worktree.path }));\n}\n\nexport function planUpdateActions(inventory: WorktreeInventory): UpdateAction[] {\n const remoteBranches = new Set(inventory.remoteBranches);\n return inventory.existingWorktrees\n .filter((worktree) => remoteBranches.has(worktree.branch))\n .map((worktree) => ({ kind: \"update-candidate\", branch: worktree.branch, path: worktree.path }));\n}\n\nexport function planSparseActions(inventory: WorktreeInventory, sparseCheckout?: SparseCheckoutConfig): SparseAction[] {\n if (!sparseCheckout) {\n return [];\n }\n\n return inventory.existingWorktrees.map((worktree) => ({\n kind: \"check-sparse\",\n branch: worktree.branch,\n path: worktree.path,\n }));\n}\n", "import { getErrorMessage } from \"../utils/lfs-error\";\nimport { REPOSITORY_MODES, resolveMode } from \"../utils/repo-mode\";\nimport { retry } from \"../utils/retry\";\nimport { PhaseTimer, Timer, formatTimingTable } from \"../utils/timing\";\n\nimport { type CloneSkipReason, CloneSyncService } from \"./clone-sync.service\";\nimport { GitService } from \"./git.service\";\nimport { Logger } from \"./logger.service\";\nimport { ProgressEmitter } from \"./progress-emitter\";\nimport { RepoOperationLock } from \"./repo-operation-lock\";\nimport { SyncOutcomeAccumulator } from \"./sync-outcome\";\nimport { SyncRetryPolicy } from \"./sync-retry-policy\";\nimport { WorktreeModeSyncRunner } from \"./worktree-mode-sync-runner\";\n\nimport type { ProgressEvent, ProgressListener } from \"./progress-emitter\";\nimport type { RepoLockRelease } from \"./repo-operation-lock\";\nimport type { Config, SyncOutcome, SyncResult } from \"../types\";\nimport type { LfsErrorContext } from \"../utils/retry\";\n\nexport type { ProgressEvent, ProgressListener } from \"./progress-emitter\";\nexport type { SyncOutcome, SyncOutcomeAction, SyncOutcomeCounts, SyncResult } from \"../types\";\n\nexport type ExclusiveRepoOperationResult<T> =\n | { started: true; value: T }\n | { started: false; reason: \"in_progress\" | \"locked\" };\n\nexport class WorktreeSyncService {\n private gitService: GitService;\n private cloneSyncService: CloneSyncService | null = null;\n private logger: Logger;\n private syncInProgress: boolean = false;\n private progressEmitter = new ProgressEmitter();\n private repoOperationLock: RepoOperationLock;\n private retryPolicy: SyncRetryPolicy;\n private worktreeModeSyncRunner: WorktreeModeSyncRunner;\n private skipsAccumulator: CloneSkipReason[] = [];\n private lastOutcome: SyncOutcome | null = null;\n\n constructor(public readonly config: Config) {\n this.logger = config.logger ?? Logger.createDefault(undefined, config.debug);\n this.gitService = new GitService(config, this.logger, (event): void => this.emitProgress(event));\n this.repoOperationLock = new RepoOperationLock(config, this.gitService, this.logger);\n this.retryPolicy = new SyncRetryPolicy(config, this.gitService, this.logger);\n this.worktreeModeSyncRunner = new WorktreeModeSyncRunner(\n config,\n this.gitService,\n this.logger,\n this.progressEmitter,\n );\n if (resolveMode(config) === REPOSITORY_MODES.CLONE) {\n this.cloneSyncService = new CloneSyncService(config, this.gitService, this.logger, {\n progressEmitter: (event): void => this.emitProgress(event),\n onSkip: (reason): void => {\n this.skipsAccumulator.push(reason);\n },\n });\n }\n }\n\n public getRecordedSkips(): readonly CloneSkipReason[] {\n return [...this.skipsAccumulator];\n }\n\n public clearRecordedSkips(): void {\n this.skipsAccumulator = [];\n }\n\n public clearPendingInitSkip(): void {\n this.cloneSyncService?.clearPendingInitSkip();\n }\n\n public getLastOutcome(): SyncOutcome | null {\n return this.lastOutcome;\n }\n\n isCloneMode(): boolean {\n return this.cloneSyncService !== null;\n }\n\n async getWorktrees(): Promise<Array<{ path: string; branch: string }>> {\n if (this.cloneSyncService) {\n return this.cloneSyncService.getWorktrees();\n }\n return this.gitService.getWorktrees();\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized()) return;\n const result = await this.runExclusiveRepoOperation(() => this.initializeUnlocked());\n if (!result.started) {\n const reason = result.reason === \"in_progress\" ? \"operation in progress\" : \"another process holds the lock\";\n this.logger.warn(`\u26A0\uFE0F Initialize skipped: ${reason}`);\n }\n }\n\n async initializeUnlocked(outcome?: SyncOutcomeAccumulator): Promise<void> {\n this.emitProgress({ phase: \"initialize\", message: \"Initializing repository\" });\n if (this.cloneSyncService) {\n await this.cloneSyncService.initialize(outcome);\n } else {\n await this.gitService.initialize();\n }\n this.emitProgress({ phase: \"initialize\", message: \"Repository initialized\" });\n }\n\n isInitialized(): boolean {\n if (this.cloneSyncService) {\n return this.cloneSyncService.isInitialized();\n }\n return this.gitService.isInitialized();\n }\n\n isSyncInProgress(): boolean {\n return this.syncInProgress;\n }\n\n getGitService(): GitService {\n return this.gitService;\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n this.gitService.updateLogger(logger);\n this.cloneSyncService?.updateLogger(logger);\n this.retryPolicy.updateLogger(logger);\n this.worktreeModeSyncRunner.updateLogger(logger);\n this.repoOperationLock.updateLogger(logger);\n }\n\n onProgress(listener: ProgressListener): () => void {\n return this.progressEmitter.onProgress(listener);\n }\n\n async runExclusiveRepoOperation<T>(operation: () => Promise<T>): Promise<ExclusiveRepoOperationResult<T>> {\n if (this.syncInProgress) {\n this.logger.warn(\"\u26A0\uFE0F Another repository operation is already in progress, skipping...\");\n return { started: false, reason: \"in_progress\" };\n }\n // Claim the in-process slot synchronously so a second caller arriving while\n // we await acquire() sees \"in_progress\" instead of also passing the check.\n this.syncInProgress = true;\n\n let release: RepoLockRelease | null;\n try {\n release = await this.repoOperationLock.acquire();\n } catch (error) {\n this.syncInProgress = false;\n throw error;\n }\n\n if (release === null) {\n this.syncInProgress = false;\n this.logger.warn(\"\u26A0\uFE0F Another process holds the sync lock for this repo, skipping...\");\n return { started: false, reason: \"locked\" };\n }\n\n try {\n return { started: true, value: await operation() };\n } finally {\n // Release the file lock first; only then clear the in-process flag so\n // another caller arriving in this window gets \"in_progress\" rather than\n // ELOCKED from proper-lockfile.\n try {\n await release();\n } catch (releaseError) {\n this.logger.warn(`Failed to release sync lock: ${getErrorMessage(releaseError)}`);\n }\n this.syncInProgress = false;\n }\n }\n\n private emitProgress(event: ProgressEvent): void {\n this.progressEmitter.emit(event);\n }\n\n async sync(): Promise<SyncResult> {\n const result = await this.runExclusiveRepoOperation<SyncOutcome>(async () => {\n const totalTimer = new Timer();\n const phaseTimer = new PhaseTimer();\n const outcome = new SyncOutcomeAccumulator({\n mode: this.cloneSyncService ? \"clone\" : \"worktree\",\n repoName: (this.config as { name?: string }).name,\n });\n const syncContext = this.retryPolicy.createContext();\n const retryOptions = this.retryPolicy.createOptions(syncContext);\n let durationMs: number | undefined;\n\n try {\n if (!this.isInitialized()) {\n await this.initializeUnlocked(outcome);\n }\n\n this.logger.info(`[${new Date().toISOString()}] Starting worktree synchronization...`);\n\n const retryOutcomeBaseline = outcome.snapshot();\n const retryOptionsWithOutcomeReset = {\n ...retryOptions,\n onRetry: (error: unknown, attempt: number, context?: LfsErrorContext): void => {\n outcome.restore(retryOutcomeBaseline);\n retryOptions.onRetry?.(error, attempt, context);\n },\n };\n\n const cloneSync = this.cloneSyncService;\n if (cloneSync) {\n await retry(() => cloneSync.runSyncAttempt(outcome), retryOptionsWithOutcomeReset);\n } else {\n await retry(\n () => this.worktreeModeSyncRunner.runSyncAttempt(phaseTimer, syncContext, outcome),\n retryOptionsWithOutcomeReset,\n );\n }\n } catch (error) {\n if (outcome.getCounts().failed === 0) {\n outcome.recordFailed(\"repo\", getErrorMessage(error), { reason: \"sync_failed\" });\n }\n this.logger.error(\"\\n\u274C Error during worktree synchronization after all retry attempts:\", error);\n throw error;\n } finally {\n this.retryPolicy.resetLfsSkipIfNeeded(syncContext);\n this.logger.info(`[${new Date().toISOString()}] Synchronization finished.\\n`);\n durationMs = totalTimer.stop();\n this.lastOutcome = outcome.toOutcome(durationMs);\n\n if (this.config.debug) {\n const phaseResults = phaseTimer.getResults();\n const repoName = (this.config as { name?: string }).name;\n this.logger.table(formatTimingTable(durationMs, phaseResults, repoName));\n }\n }\n\n return this.lastOutcome ?? outcome.toOutcome(durationMs);\n });\n\n return result.started ? { started: true, outcome: result.value } : result;\n }\n}\n", "import { spawn } from \"child_process\";\n\nimport { DEFAULT_CONFIG, HOOK_CONSTANTS } from \"../constants\";\nimport { shellEscape } from \"../utils/shell-escape\";\n\nimport type { HookContext, HooksConfig } from \"../types\";\nimport type { ChildProcess } from \"child_process\";\n\nexport interface HookExecutionCallbacks {\n onStdout?: (data: string) => void;\n onStderr?: (data: string) => void;\n onError?: (command: string, error: Error) => void;\n onComplete?: (command: string, exitCode: number | null) => void;\n}\n\nexport class HookExecutionService {\n private activeProcesses = new Set<ChildProcess>();\n private killTimers = new Set<ReturnType<typeof setTimeout>>();\n private timeoutTimers = new Set<ReturnType<typeof setTimeout>>();\n private timeoutMs: number = DEFAULT_CONFIG.HOOK_TIMEOUT_MS;\n\n setTimeoutMs(ms: number): void {\n this.timeoutMs = ms;\n }\n\n executeOnBranchCreated(\n hooks: HooksConfig | undefined,\n context: HookContext,\n callbacks: HookExecutionCallbacks = {},\n ): void {\n if (!hooks?.onBranchCreated?.length) {\n return;\n }\n\n const env = this.buildEnvironment(context);\n\n for (const command of hooks.onBranchCreated) {\n const resolvedCommand = this.resolveCommandPlaceholders(command, context);\n this.executeCommandInBackground(resolvedCommand, env, callbacks, context.worktreePath);\n }\n }\n\n public cleanup(): void {\n for (const timer of this.timeoutTimers) {\n clearTimeout(timer);\n }\n this.timeoutTimers.clear();\n\n for (const timer of this.killTimers) {\n clearTimeout(timer);\n }\n this.killTimers.clear();\n\n for (const child of this.activeProcesses) {\n try {\n child.kill(\"SIGTERM\");\n } catch {\n // Process may have already exited\n }\n const killTimer = setTimeout(() => {\n try {\n child.kill(\"SIGKILL\");\n } catch {\n // Process may have already exited\n }\n this.killTimers.delete(killTimer);\n }, 5000);\n this.killTimers.add(killTimer);\n }\n this.activeProcesses.clear();\n }\n\n private buildEnvironment(context: HookContext): NodeJS.ProcessEnv {\n return {\n ...process.env,\n [HOOK_CONSTANTS.ENV_VARS.BRANCH_NAME]: context.branchName,\n [HOOK_CONSTANTS.ENV_VARS.WORKTREE_PATH]: context.worktreePath,\n [HOOK_CONSTANTS.ENV_VARS.REPO_NAME]: context.repoName,\n [HOOK_CONSTANTS.ENV_VARS.BASE_BRANCH]: context.baseBranch,\n [HOOK_CONSTANTS.ENV_VARS.REPO_URL]: context.repoUrl,\n };\n }\n\n private resolveCommandPlaceholders(command: string, context: HookContext): string {\n return command\n .replaceAll(HOOK_CONSTANTS.PLACEHOLDERS.BRANCH_NAME, shellEscape(context.branchName))\n .replaceAll(HOOK_CONSTANTS.PLACEHOLDERS.WORKTREE_PATH, shellEscape(context.worktreePath))\n .replaceAll(HOOK_CONSTANTS.PLACEHOLDERS.REPO_NAME, shellEscape(context.repoName))\n .replaceAll(HOOK_CONSTANTS.PLACEHOLDERS.BASE_BRANCH, shellEscape(context.baseBranch))\n .replaceAll(HOOK_CONSTANTS.PLACEHOLDERS.REPO_URL, shellEscape(context.repoUrl));\n }\n\n private executeCommandInBackground(\n command: string,\n env: NodeJS.ProcessEnv,\n callbacks: HookExecutionCallbacks,\n cwd?: string,\n ): void {\n const child = spawn(command, {\n shell: true,\n detached: false,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env,\n cwd,\n });\n\n this.activeProcesses.add(child);\n let timedOut = false;\n\n const timer = setTimeout(() => {\n timedOut = true;\n this.timeoutTimers.delete(timer);\n this.activeProcesses.delete(child);\n try {\n child.kill(\"SIGTERM\");\n } catch {\n // Process may have already exited\n }\n const killTimer = setTimeout(() => {\n try {\n child.kill(\"SIGKILL\");\n } catch {\n // Process may have already exited\n }\n this.killTimers.delete(killTimer);\n }, 5000);\n this.killTimers.add(killTimer);\n callbacks.onError?.(command, new Error(`Hook timed out after ${this.timeoutMs}ms`));\n }, this.timeoutMs);\n this.timeoutTimers.add(timer);\n\n if (child.stdout) {\n child.stdout.on(\"data\", (data: Buffer) => {\n const output = data.toString().trim();\n if (output) {\n callbacks.onStdout?.(output);\n }\n });\n }\n\n if (child.stderr) {\n child.stderr.on(\"data\", (data: Buffer) => {\n const output = data.toString().trim();\n if (output) {\n callbacks.onStderr?.(output);\n }\n });\n }\n\n child.on(\"error\", (error) => {\n clearTimeout(timer);\n this.timeoutTimers.delete(timer);\n this.activeProcesses.delete(child);\n callbacks.onError?.(command, error);\n });\n\n child.on(\"close\", (code) => {\n clearTimeout(timer);\n this.timeoutTimers.delete(timer);\n if (timedOut) return;\n this.activeProcesses.delete(child);\n callbacks.onComplete?.(command, code);\n });\n }\n}\n", "/**\n * Escapes a value for POSIX shell single-quoted contexts only.\n */\nexport function shellEscape(value: string): string {\n return \"'\" + value.replace(/'/g, \"'\\\\''\") + \"'\";\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 interface AppSyncProgress {\n repo: string;\n phase: string;\n message: string;\n progress?: number;\n processed?: number;\n total?: number;\n completed?: boolean;\n}\n\ntype AppEventMap = {\n updateLastSyncTime: void;\n setStatus: \"idle\" | \"syncing\";\n setSyncProgress: AppSyncProgress | null;\n setDiskSpace: string;\n addLog: { message: string; level: \"info\" | \"warn\" | \"error\" };\n uiReady: void;\n updateRepositoryCount: number;\n updateCronSchedule: string | undefined;\n};\n\ntype EventCallback<T> = T extends void ? () => void : (payload: T) => void;\n\ntype AnyEventCallback = EventCallback<AppEventMap[keyof AppEventMap]>;\n\nexport class AppEventEmitter {\n private listeners: Map<keyof AppEventMap, Set<AnyEventCallback>> = new Map();\n\n on<K extends keyof AppEventMap>(event: K, callback: EventCallback<AppEventMap[K]>): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(callback as AnyEventCallback);\n\n return () => {\n const set = this.listeners.get(event);\n if (set) {\n set.delete(callback as AnyEventCallback);\n if (set.size === 0) {\n this.listeners.delete(event);\n }\n }\n };\n }\n\n emit<K extends keyof AppEventMap>(event: K, ...args: AppEventMap[K] extends void ? [] : [AppEventMap[K]]): void {\n const callbacks = this.listeners.get(event);\n if (callbacks) {\n for (const callback of callbacks) {\n try {\n (callback as (payload?: AppEventMap[K]) => void)(args[0]);\n } catch (error) {\n console.error(`[app-events] Error in '${String(event)}' listener:`, error);\n }\n }\n }\n }\n\n removeAllListeners(): void {\n this.listeners.clear();\n }\n}\n", "import yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\n\nexport const CLI_COMMANDS = {\n RUN: \"run\",\n INIT: \"init\",\n LIST: \"list\",\n} as const;\n\nexport type CliCommand = (typeof CLI_COMMANDS)[keyof typeof CLI_COMMANDS];\n\nexport type CliOptions =\n | { command: typeof CLI_COMMANDS.RUN; config?: string; runOnce: boolean }\n | { command: typeof CLI_COMMANDS.INIT; config?: string; force: boolean }\n | { command: typeof CLI_COMMANDS.LIST; config?: string; filter?: string };\n\nexport function parseArguments(argv: string[] = hideBin(process.argv)): CliOptions {\n let parsed: CliOptions | undefined;\n\n yargs(argv)\n .scriptName(\"sync-worktrees\")\n .parserConfiguration({ \"camel-case-expansion\": false })\n .strict()\n .command(\n \"$0\",\n \"Sync git worktrees against a config file\",\n (y) =>\n y\n .option(\"config\", {\n alias: \"c\",\n type: \"string\",\n description: \"Path to JavaScript config file (auto-detected in CWD when omitted).\",\n })\n .option(\"runOnce\", {\n type: \"boolean\",\n description: \"Run a sync once and exit, overriding config runOnce settings for this invocation.\",\n default: false,\n }),\n (args) => {\n parsed = {\n command: CLI_COMMANDS.RUN,\n config: args.config,\n runOnce: args.runOnce,\n };\n },\n )\n .command(\n CLI_COMMANDS.INIT,\n \"Create a new config file interactively\",\n (y) =>\n y\n .option(\"config\", {\n alias: \"c\",\n type: \"string\",\n description: \"Target path for the generated config file (default: ./sync-worktrees.config.js).\",\n })\n .option(\"force\", {\n type: \"boolean\",\n description: \"Overwrite the target file if it already exists.\",\n default: false,\n }),\n (args) => {\n parsed = {\n command: CLI_COMMANDS.INIT,\n config: args.config,\n force: args.force,\n };\n },\n )\n .command(\n CLI_COMMANDS.LIST,\n \"List repositories configured in a config file and exit\",\n (y) =>\n y\n .option(\"config\", {\n alias: \"c\",\n type: \"string\",\n description: \"Path to JavaScript config file (auto-detected in CWD when omitted).\",\n })\n .option(\"filter\", {\n alias: \"f\",\n type: \"string\",\n description: \"Filter repositories by name (wildcards, comma-separated).\",\n }),\n (args) => {\n parsed = {\n command: CLI_COMMANDS.LIST,\n config: args.config,\n filter: args.filter,\n };\n },\n )\n .demandCommand(0, 0)\n .help()\n .alias(\"help\", \"h\")\n .version()\n .parseSync();\n\n if (!parsed) {\n throw new Error(\"Failed to parse CLI arguments\");\n }\n\n return parsed;\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport { CONFIG_FILE_NAMES } from \"../constants\";\nimport { ConfigFileExistsError } from \"../errors\";\n\nimport { fileExists } from \"./file-exists\";\nimport { extractRepoNameFromUrl } from \"./git-url\";\n\nimport type { InitConfigInput } from \"../types\";\n\nexport { ConfigFileExistsError };\n\ntype SerializableValue = string | number | boolean | null | undefined | SerializableObject | SerializableValue[];\ninterface SerializableObject {\n [key: string]: SerializableValue;\n}\n\nfunction serializeToESM(obj: SerializableValue, indent: number = 0): string {\n const spaces = \" \".repeat(indent);\n const innerSpaces = \" \".repeat(indent + 2);\n\n if (typeof obj === \"string\") {\n return JSON.stringify(obj);\n }\n\n if (typeof obj === \"number\" || typeof obj === \"boolean\") {\n return String(obj);\n }\n\n if (Array.isArray(obj)) {\n if (obj.length === 0) return \"[]\";\n const items = obj.map((item) => `${innerSpaces}${serializeToESM(item, indent + 2)}`).join(\",\\n\");\n return `[\\n${items}\\n${spaces}]`;\n }\n\n if (obj && typeof obj === \"object\") {\n const entries = Object.entries(obj)\n .filter(([_, value]) => value !== undefined)\n .map(([key, value]) => {\n const serializedValue = serializeToESM(value, indent + 2);\n return `${innerSpaces}${key}: ${serializedValue}`;\n });\n\n if (entries.length === 0) return \"{}\";\n return `{\\n${entries.join(\",\\n\")}\\n${spaces}}`;\n }\n\n return String(obj);\n}\n\nexport interface GenerateConfigFileOptions {\n overwrite?: boolean;\n}\n\nexport async function generateConfigFile(\n input: InitConfigInput,\n configPath: string,\n options: GenerateConfigFileOptions = {},\n): Promise<void> {\n const configDir = path.dirname(configPath);\n await fs.mkdir(configDir, { recursive: true });\n\n const worktreeDirRelative = path.relative(configDir, input.worktreeDir);\n const useRelativeWorktree = !worktreeDirRelative.startsWith(\"../../../\");\n\n const repoName = extractRepoNameFromUrl(input.repoUrl);\n\n const repository: SerializableObject = {\n name: repoName,\n repoUrl: input.repoUrl,\n worktreeDir: useRelativeWorktree ? `./${worktreeDirRelative}` : input.worktreeDir,\n };\n\n if (input.bareRepoDir) {\n const bareRepoDirRelative = path.relative(configDir, input.bareRepoDir);\n const useRelativeBare = !bareRepoDirRelative.startsWith(\"../../../\");\n repository.bareRepoDir = useRelativeBare ? `./${bareRepoDirRelative}` : input.bareRepoDir;\n }\n\n const defaults: SerializableObject = {\n cronSchedule: input.cronSchedule,\n };\n if (input.runOnce) {\n defaults.runOnce = input.runOnce;\n }\n\n const configObject: SerializableObject = {\n defaults,\n repositories: [repository],\n };\n\n const configContent = `// @ts-check\n\n/**\n * Sync-worktrees configuration file\n * Generated on ${new Date().toISOString()}\n */\n\n/** @satisfies {import(\"sync-worktrees\").SyncWorktreesConfig} */\nconst config = ${serializeToESM(configObject)};\n\nexport default config;\n`;\n\n try {\n await fs.writeFile(configPath, configContent, {\n encoding: \"utf-8\",\n flag: options.overwrite ? \"w\" : \"wx\",\n });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"EEXIST\") {\n throw new ConfigFileExistsError(configPath);\n }\n throw error;\n }\n}\n\nexport function getDefaultConfigPath(): string {\n return path.join(process.cwd(), \"sync-worktrees.config.js\");\n}\n\nexport async function findConfigInCwd(cwd: string = process.cwd()): Promise<string | null> {\n for (const name of CONFIG_FILE_NAMES) {\n const full = path.join(cwd, name);\n if (await fileExists(full)) {\n return full;\n }\n }\n return null;\n}\n", "import * as path from \"path\";\n\nimport { confirm, input, select } from \"@inquirer/prompts\";\n\nimport { extractRepoNameFromUrl } from \"./git-url\";\n\nimport type { InitConfigInput } from \"../types\";\n\nexport async function promptForInitConfig(): Promise<InitConfigInput> {\n console.log(\"\uD83D\uDD27 Welcome to sync-worktrees interactive setup!\\n\");\n\n const repoUrl = await input({\n message: \"Enter the Git repository URL (e.g., https://github.com/user/repo.git):\",\n validate: (value: string) => {\n if (!value.trim()) {\n return \"Repository URL is required\";\n }\n if (!value.match(/^(https?:\\/\\/|ssh:\\/\\/|git@|file:\\/\\/).*$/)) {\n return \"Please enter a valid Git URL (https://, ssh://, git@, or file://)\";\n }\n return true;\n },\n });\n\n const repoName = extractRepoNameFromUrl(repoUrl);\n const defaultWorktreeDir = repoName ? `./${repoName}` : \"\";\n\n let worktreeDir = await input({\n message: \"Enter the directory for storing worktrees:\",\n default: defaultWorktreeDir,\n validate: (value: string) => {\n if (!value.trim() && !defaultWorktreeDir) {\n return \"Worktree directory is required\";\n }\n return true;\n },\n });\n\n if (!worktreeDir.trim() && defaultWorktreeDir) {\n worktreeDir = defaultWorktreeDir;\n }\n\n if (!path.isAbsolute(worktreeDir)) {\n worktreeDir = path.resolve(worktreeDir);\n }\n\n let bareRepoDir: string | undefined;\n const askForBareDir = await confirm({\n message: \"Would you like to specify a custom location for the bare repository?\",\n default: false,\n });\n\n if (askForBareDir) {\n bareRepoDir = await input({\n message: \"Enter the directory for the bare repository:\",\n default: \"\",\n validate: (value: string) => {\n if (!value.trim()) {\n return \"Bare repository directory is required\";\n }\n return true;\n },\n });\n if (!path.isAbsolute(bareRepoDir)) {\n bareRepoDir = path.resolve(bareRepoDir);\n }\n }\n\n const runMode = await select({\n message: \"How would you like to run the sync?\",\n choices: [\n { name: \"Run once\", value: \"once\" },\n { name: \"Schedule with cron\", value: \"scheduled\" },\n ],\n });\n const runOnce = runMode === \"once\";\n\n let cronSchedule = \"0 * * * *\";\n if (!runOnce) {\n cronSchedule = await input({\n message: \"Enter the cron schedule (or press enter for default):\",\n default: \"0 * * * *\",\n validate: (value: string) => {\n if (!value.trim()) {\n return \"Cron schedule is required\";\n }\n const parts = value.trim().split(\" \");\n if (parts.length < 5) {\n return \"Invalid cron pattern. Expected format: '* * * * *'\";\n }\n return true;\n },\n });\n }\n\n return {\n repoUrl,\n worktreeDir,\n bareRepoDir,\n cronSchedule,\n runOnce,\n };\n}\n", "export type CleanupFn = (fast: boolean) => void | Promise<void>;\n\nexport interface SignalHandlerOptions {\n forceExitMs?: number;\n log?: (message: string) => void;\n exit?: (code: number) => void;\n process?: NodeJS.EventEmitter;\n}\n\nexport interface SignalHandlerHandle {\n register: (fn: CleanupFn) => void;\n dispose: () => void;\n}\n\nexport const DEFAULT_FORCE_EXIT_MS = 3000;\n\nexport function setupSignalHandlers(options: SignalHandlerOptions = {}): SignalHandlerHandle {\n const forceExitMs = options.forceExitMs ?? DEFAULT_FORCE_EXIT_MS;\n const log = options.log ?? ((msg: string): void => console.log(msg));\n const exit = options.exit ?? ((code: number): void => process.exit(code));\n const target = options.process ?? process;\n\n const cleanupFns: CleanupFn[] = [];\n let signalCount = 0;\n\n const handler = (signal: string): void => {\n signalCount += 1;\n if (signalCount >= 2) {\n log(`\\nReceived second ${signal}, forcing exit.`);\n exit(130);\n return;\n }\n log(`\\nReceived ${signal}, shutting down (Ctrl+C again to force exit)...`);\n\n const watchdog = setTimeout(() => {\n log(`\\nShutdown took longer than ${forceExitMs}ms, forcing exit.`);\n exit(130);\n }, forceExitMs);\n if (typeof watchdog.unref === \"function\") {\n watchdog.unref();\n }\n\n void Promise.allSettled(cleanupFns.map((fn) => Promise.resolve().then(() => fn(true)))).then(() => {\n clearTimeout(watchdog);\n exit(0);\n });\n };\n\n const sigintListener = (): void => handler(\"SIGINT\");\n const sigtermListener = (): void => handler(\"SIGTERM\");\n\n target.on(\"SIGINT\", sigintListener);\n target.on(\"SIGTERM\", sigtermListener);\n\n return {\n register: (fn: CleanupFn): void => {\n cleanupFns.push(fn);\n },\n dispose: (): void => {\n target.removeListener(\"SIGINT\", sigintListener);\n target.removeListener(\"SIGTERM\", sigtermListener);\n },\n };\n}\n"],
5
- "mappings": "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",
6
- "names": ["realpathSync", "path", "pLimit", "path", "path", "path", "retry", "React", "path", "cron", "pLimit", "spawn", "existsSync", "React", "useState", "useEffect", "useCallback", "useRef", "Box", "useInput", "React", "Box", "Text", "input", "React", "useState", "useEffect", "Box", "Text", "useInput", "useState", "useEffect", "useInput", "input", "React", "Box", "Text", "React", "useState", "useEffect", "useMemo", "useCallback", "useRef", "Box", "Text", "useInput", "input", "React", "useState", "useEffect", "useMemo", "useCallback", "useRef", "Box", "Text", "useInput", "React", "Text", "useState", "useRef", "useMemo", "useCallback", "useEffect", "useInput", "input", "selectedRepo", "Box", "isSelected", "isExpanded", "React", "useState", "useEffect", "useRef", "Box", "Text", "useInput", "input", "useState", "schedule", "useCallback", "useRef", "useInput", "input", "useEffect", "React", "Box", "resolve", "fs", "path", "fs", "path", "path", "fs", "path", "simpleGit", "path", "simpleGit", "simpleGit", "matcher", "fs", "path", "simpleGit", "simpleGit", "fs", "path", "simpleGit", "stat", "simpleGit", "simpleGit", "resolve", "fs", "path", "path", "fs", "path", "formatDuration", "createHash", "fs", "path", "createHash", "path", "formatDuration", "stat", "resolve", "fs", "pLimit", "schedule", "React", "path", "resolve", "spawn", "existsSync", "fs", "path", "input", "path", "pLimit", "schedule", "input", "realpathSync"]
3
+ "sources": ["../src/index.ts", "../src/constants.ts", "../src/errors/index.ts", "../src/services/config-loader.service.ts", "../src/utils/branch-filter.ts", "../src/utils/date-filter.ts", "../src/utils/file-exists.ts", "../src/utils/git-url.ts", "../src/utils/path-compare.ts", "../src/utils/repo-mode.ts", "../src/utils/sanitize-name.ts", "../src/services/InteractiveUIService.tsx", "../src/components/App.tsx", "../src/components/StatusBar.tsx", "../src/components/HelpModal.tsx", "../src/components/BranchCreationWizard.tsx", "../src/utils/git-validation.ts", "../src/components/OpenEditorWizard.tsx", "../src/components/WorktreeStatusView.tsx", "../src/utils/lfs-error.ts", "../src/components/LogPanel.tsx", "../src/services/worktree-sync.service.ts", "../src/utils/lock-path.ts", "../src/utils/retry.ts", "../src/utils/timing.ts", "../src/services/clone-sync.service.ts", "../src/utils/git-progress.ts", "../src/services/file-copy.service.ts", "../src/services/branch-created-actions.service.ts", "../src/utils/clone-skip-format.ts", "../src/services/sync-outcome.ts", "../src/services/git-maintenance.service.ts", "../src/utils/atomic-write.ts", "../src/services/logger.service.ts", "../src/services/git.service.ts", "../src/utils/quarantine.ts", "../src/utils/filename-timestamp.ts", "../src/utils/worktree-list-parser.ts", "../src/services/sparse-checkout.service.ts", "../src/services/worktree-metadata.service.ts", "../src/services/worktree-status.service.ts", "../src/services/progress-emitter.ts", "../src/services/removal-audit.service.ts", "../src/services/repo-operation-lock.ts", "../src/services/sync-retry-policy.ts", "../src/services/trash-migration.service.ts", "../src/services/trash-reaper.service.ts", "../src/utils/disk-space.ts", "../src/services/trash.service.ts", "../src/services/worktree-mode-sync-runner.ts", "../src/services/path-resolution.service.ts", "../src/services/worktree-sync-planner.ts", "../src/services/hook-execution.service.ts", "../src/utils/shell-escape.ts", "../src/utils/app-events.ts", "../src/utils/cli.ts", "../src/utils/config-generator.ts", "../src/utils/interactive.ts", "../src/utils/signal-handlers.ts"],
4
+ "sourcesContent": ["#!/usr/bin/env node\n\nimport { realpathSync } from \"fs\";\nimport * as path from \"path\";\nimport { fileURLToPath } from \"url\";\n\nimport pLimit from \"p-limit\";\n\nimport { DEFAULT_CONFIG } from \"./constants\";\nimport { ConfigFileExistsError, ConfigFileNotFoundError } from \"./errors\";\nimport { ConfigLoaderService } from \"./services/config-loader.service\";\nimport { InteractiveUIService } from \"./services/InteractiveUIService\";\nimport { Logger } from \"./services/logger.service\";\nimport { WorktreeSyncService } from \"./services/worktree-sync.service\";\nimport { CLI_COMMANDS, parseArguments } from \"./utils/cli\";\nimport { formatCloneSkipReason } from \"./utils/clone-skip-format\";\nimport { findConfigInCwd, generateConfigFile, getDefaultConfigPath } from \"./utils/config-generator\";\nimport { fileExists } from \"./utils/file-exists\";\nimport { promptForInitConfig } from \"./utils/interactive\";\nimport { setupSignalHandlers } from \"./utils/signal-handlers\";\n\nimport type { CloneSkipReason } from \"./services/clone-sync.service\";\nimport type { ConfigFile, RepositoryConfig } from \"./types\";\nimport type { CliOptions } from \"./utils/cli\";\n\nexport type {\n SyncWorktreesConfig,\n SyncWorktreesDefaults,\n SyncWorktreesHooksConfig,\n SyncWorktreesParallelismConfig,\n SyncWorktreesRepository,\n SyncWorktreesRepositoryMode,\n SyncWorktreesRetryConfig,\n SyncWorktreesSparseCheckoutConfig,\n SyncWorktreesSparseCheckoutMode,\n SyncWorktreesTrashConfig,\n} from \"./types\";\n\nconst signalHandle = setupSignalHandlers();\n\nexport async function runMultipleRepositories(\n configFile: ConfigFile,\n repositories: RepositoryConfig[],\n configPath?: string,\n): Promise<void> {\n const services = new Map<string, WorktreeSyncService>();\n const globalLogger = Logger.createDefault();\n\n const runOnce = configFile.defaults?.runOnce ?? false;\n const maxParallel =\n configFile.parallelism?.maxRepositories ??\n configFile.defaults?.parallelism?.maxRepositories ??\n DEFAULT_CONFIG.PARALLELISM.MAX_REPOSITORIES;\n\n const limit = pLimit(maxParallel);\n\n if (runOnce) {\n globalLogger.info(`\\n\uD83D\uDD04 Syncing ${repositories.length} repositories...`);\n\n const initResults = await Promise.allSettled(\n repositories.map((repoConfig) =>\n limit(async () => {\n const repoLogger = Logger.createDefault(repoConfig.name, repoConfig.debug);\n\n repoLogger.info(`\\n\uD83D\uDCE6 Repository: ${repoConfig.name}`);\n repoLogger.info(` URL: ${repoConfig.repoUrl}`);\n repoLogger.info(` Worktrees: ${repoConfig.worktreeDir}`);\n if (repoConfig.bareRepoDir) {\n repoLogger.info(` Bare repo: ${repoConfig.bareRepoDir}`);\n }\n\n if (!repoConfig.logger) {\n repoConfig.logger = repoLogger;\n }\n\n const syncService = new WorktreeSyncService(repoConfig);\n await syncService.initialize();\n return { name: repoConfig.name, service: syncService };\n }),\n ),\n );\n\n const servicesToSync: Array<{ name: string; service: WorktreeSyncService }> = [];\n\n for (const result of initResults) {\n if (result.status === \"fulfilled\") {\n services.set(result.value.name, result.value.service);\n servicesToSync.push(result.value);\n } else {\n globalLogger.error(`\u274C Failed to initialize repository:`, result.reason);\n }\n }\n\n const syncResults = await Promise.allSettled(\n servicesToSync.map(({ name, service }) =>\n limit(async () => {\n try {\n return await service.sync();\n } catch (error) {\n globalLogger.error(`\u274C Error syncing repository '${name}':`, error);\n throw error;\n }\n }),\n ),\n );\n\n const skipsByRepo: Array<{ repo: string; reasons: readonly CloneSkipReason[] }> = [];\n const skippedNames = new Set<string>();\n const outcomeFailedNames = new Set<string>();\n const partialSkipNames = new Set<string>();\n for (let i = 0; i < servicesToSync.length; i++) {\n const { name, service } = servicesToSync[i];\n const reasons = service.getRecordedSkips();\n if (reasons.length > 0) {\n skipsByRepo.push({ repo: name, reasons });\n skippedNames.add(name);\n }\n\n const result = syncResults[i];\n if (result.status === \"fulfilled\") {\n if (!result.value.started) {\n skippedNames.add(name);\n continue;\n }\n\n const counts = result.value.outcome?.counts;\n if (counts) {\n if (counts.failed > 0) {\n outcomeFailedNames.add(name);\n }\n // Per-action skips are informational \u2014 they don't demote a repo that\n // otherwise completed its sync attempt out of `successCount`. A\n // failed repo's headline is its failure, so don't double-label it.\n if (counts.skipped > 0 && !skippedNames.has(name) && !outcomeFailedNames.has(name)) {\n partialSkipNames.add(name);\n }\n }\n }\n }\n\n if (skipsByRepo.length > 0) {\n const skipsRepoWord = skipsByRepo.length === 1 ? \"repo\" : \"repos\";\n globalLogger.warn(`\\n\u26A0\uFE0F Clone-mode skips (${skipsByRepo.length} ${skipsRepoWord}):`);\n for (const { repo, reasons } of skipsByRepo) {\n for (const reason of reasons) {\n globalLogger.warn(` \u2022 ${repo} \u2014 ${formatCloneSkipReason(reason)}`);\n }\n }\n }\n\n const initFailures = initResults.filter(\n (result, index) => result.status === \"rejected\" && !skippedNames.has(repositories[index].name),\n ).length;\n const syncFailures = syncResults.filter(\n (result, index) => result.status === \"rejected\" && !skippedNames.has(servicesToSync[index].name),\n ).length;\n const failedCount = initFailures + syncFailures + outcomeFailedNames.size;\n const skippedCount = skippedNames.size;\n const successCount = syncResults.filter((result, index) => {\n const repoName = servicesToSync[index].name;\n return (\n result.status === \"fulfilled\" &&\n result.value.started &&\n !skippedNames.has(repoName) &&\n !outcomeFailedNames.has(repoName)\n );\n }).length;\n const processedRepoWord = repositories.length === 1 ? \"repo\" : \"repos\";\n const skipSummaryLabel = skippedNames.size === skipsByRepo.length ? \"with clone-mode skips\" : \"skipped\";\n const partialSuffix = partialSkipNames.size > 0 ? ` (${partialSkipNames.size} with partial skips)` : \"\";\n globalLogger.info(\n `\\n\uD83D\uDCCA Processed ${repositories.length} ${processedRepoWord}: ${successCount} synced${partialSuffix}, ${skippedCount} ${skipSummaryLabel}, ${failedCount} failed`,\n );\n\n if (failedCount > 0) {\n process.exitCode = 1;\n }\n } else {\n for (const repoConfig of repositories) {\n const syncService = new WorktreeSyncService(repoConfig);\n services.set(repoConfig.name, syncService);\n }\n\n const uniqueSchedules = [...new Set(repositories.map((r) => r.cronSchedule))];\n const displaySchedule = uniqueSchedules.length === 1 ? uniqueSchedules[0] : undefined;\n const allServices = Array.from(services.values());\n const uiService = new InteractiveUIService(allServices, configPath, displaySchedule, maxParallel);\n signalHandle.register((fast) => uiService.destroy(fast));\n\n void uiService.calculateAndUpdateDiskSpace();\n\n uiService.setupCronJobs();\n\n uiService.addLog(`\uD83D\uDCCB ${repositories.length} repositories configured`);\n\n const cronSchedules = new Map<string, number>();\n for (const repo of repositories) {\n cronSchedules.set(repo.cronSchedule, (cronSchedules.get(repo.cronSchedule) || 0) + 1);\n }\n for (const [schedule, count] of cronSchedules) {\n uiService.addLog(`\u23F0 ${schedule}: ${count} repository(ies)`);\n }\n }\n}\n\nasync function runList(configPath: string, filter?: string): Promise<void> {\n const configLoader = new ConfigLoaderService();\n\n try {\n const { repositories } = await configLoader.buildRepositories(configPath, { filter });\n\n if (filter && repositories.length === 0) {\n console.error(`\u274C No repositories match filter: ${filter}`);\n process.exit(1);\n }\n\n console.log(\"\\n\uD83D\uDCCB Configured repositories:\\n\");\n\n repositories.forEach((repo, index) => {\n console.log(`${index + 1}. ${repo.name}`);\n console.log(` URL: ${repo.repoUrl}`);\n console.log(` Worktrees: ${repo.worktreeDir}`);\n console.log(` Schedule: ${repo.cronSchedule}`);\n console.log(` Run Once: ${repo.runOnce}`);\n if (repo.bareRepoDir) {\n console.log(` Bare repo: ${repo.bareRepoDir}`);\n }\n if (repo.skipLfs) {\n console.log(` Skip LFS: ${repo.skipLfs}`);\n }\n console.log(\"\");\n });\n } catch (error) {\n console.error(\"\u274C Error loading config file:\", (error as Error).message);\n process.exit(1);\n }\n}\n\nasync function runFromConfigFile(configPath: string, runOnceOverride = false): Promise<void> {\n const configLoader = new ConfigLoaderService();\n const { repositories, configFile } = await configLoader.buildRepositories(configPath);\n const effectiveConfigFile = runOnceOverride\n ? { ...configFile, defaults: { ...(configFile.defaults ?? {}), runOnce: true } }\n : configFile;\n await runMultipleRepositories(effectiveConfigFile, repositories, configPath);\n}\n\nasync function resolveConfigOrExit(cliPath: string | undefined): Promise<string> {\n const resolved = cliPath ? path.resolve(cliPath) : await findConfigInCwd();\n if (!resolved) {\n console.error(\n \"\u274C No config file found. Pass --config <path>, run `sync-worktrees init` to create one, or place a sync-worktrees.config.{js,mjs,cjs} in this directory.\",\n );\n process.exit(1);\n }\n return resolved;\n}\n\nfunction exitConfigExists(targetPath: string): never {\n console.error(`\\n\u274C Config file already exists: ${targetPath}`);\n console.error(`\uD83D\uDCA1 Re-run with --force to overwrite.`);\n process.exit(1);\n}\n\nasync function runInit(configPath: string | undefined, force: boolean): Promise<void> {\n const targetPath = configPath ? path.resolve(configPath) : getDefaultConfigPath();\n\n // Preflight before prompts so user isn't asked 5 questions just to fail at write.\n // The atomic `wx` write below is still the source of truth \u2014 it closes the TOCTOU\n // window between this check and the write.\n if (!force && (await fileExists(targetPath))) {\n exitConfigExists(targetPath);\n }\n\n const input = await promptForInitConfig();\n\n try {\n await generateConfigFile(input, targetPath, { overwrite: force });\n } catch (error) {\n if (error instanceof ConfigFileExistsError) {\n exitConfigExists(error.configPath);\n }\n throw error;\n }\n\n const displayPath = path.relative(process.cwd(), targetPath) || targetPath;\n console.log(`\\n\u2705 Configuration saved to: ${targetPath}`);\n console.log(`\\n\uD83D\uDCA1 Next: sync-worktrees --config ${displayPath}`);\n}\n\nasync function runSync(options: Extract<CliOptions, { command: typeof CLI_COMMANDS.RUN }>): Promise<void> {\n const configPath = await resolveConfigOrExit(options.config);\n const displayPath = path.relative(process.cwd(), configPath) || configPath;\n console.log(`\uD83D\uDCC4 Using config: ${displayPath}`);\n\n try {\n await runFromConfigFile(configPath, options.runOnce);\n } catch (error) {\n if (error instanceof ConfigFileNotFoundError) {\n console.error(`\\n\u274C Config file not found: ${error.configPath}`);\n console.error(`\uD83D\uDCA1 Run 'sync-worktrees init --config ${displayPath}' to create one.`);\n process.exit(1);\n }\n console.error(\"\u274C Error loading config file:\", (error as Error).message);\n process.exit(1);\n }\n}\n\nasync function main(): Promise<void> {\n const options = parseArguments();\n\n switch (options.command) {\n case CLI_COMMANDS.INIT:\n return runInit(options.config, options.force);\n case CLI_COMMANDS.LIST: {\n const configPath = await resolveConfigOrExit(options.config);\n return runList(configPath, options.filter);\n }\n case CLI_COMMANDS.RUN:\n return runSync(options);\n default: {\n const _exhaustive: never = options;\n throw new Error(`Unhandled command: ${JSON.stringify(_exhaustive)}`);\n }\n }\n}\n\nfunction isMainEntrypoint(): boolean {\n const entry = process.argv[1];\n if (!entry) return false;\n // realpathSync resolves symlinks on the argv side so the guard works for\n // npm/pnpm global-bin shims and macOS /tmp -> /private/tmp; import.meta.url\n // is already the resolved path by default.\n try {\n return realpathSync(entry) === fileURLToPath(import.meta.url);\n } catch {\n return false;\n }\n}\n\nif (isMainEntrypoint()) {\n main().catch((error) => {\n console.error(\"\u274C Unhandled error:\", error);\n process.exit(1);\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 REMOVED_DIR_NAME: \".removed\",\n TRASH_DIR_NAME: \".trash\",\n TRASH_REF_PREFIX: \"refs/sync-worktrees/trash/\",\n KEEP_REF_PREFIX: \"refs/sync-worktrees/keep/\",\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 MAINTENANCE: {\n ENABLED: true,\n INTERVAL: \"7d\",\n },\n TRASH: {\n ENABLED: true,\n RETENTION_DAYS: 30,\n MIGRATE_LEGACY: true,\n },\n} as const;\n\nexport const ERROR_MESSAGES = {\n GIT_NOT_INITIALIZED: \"Git service not initialized. Call initialize() first.\",\n ALREADY_EXISTS: \"already exists\",\n ALREADY_REGISTERED: \"already registered worktree\",\n FAST_FORWARD_FAILED: [\n \"Not possible to fast-forward\",\n \"fatal: Not possible to fast-forward, aborting\",\n \"cannot fast-forward\",\n ],\n NO_UPSTREAM: [\n \"fatal: no upstream configured\",\n \"no upstream configured for branch\",\n \"fatal: ambiguous argument\",\n \"unknown revision or path\",\n ],\n LFS_ERROR: [\"smudge filter lfs failed\", \"git-lfs\", \"LFS\"],\n EXDEV: \"EXDEV\",\n} as const;\n\nexport const TEST_TIMEOUT = {\n DEFAULT: 10000,\n E2E: 60000,\n} as const;\n\nexport const ENV_CONSTANTS = {\n GIT_LFS_SKIP_SMUDGE: \"GIT_LFS_SKIP_SMUDGE\",\n GIT_ATTR_SOURCE: \"GIT_ATTR_SOURCE\",\n NODE_ENV_TEST: \"test\",\n} as const;\n\nexport const PATH_CONSTANTS = {\n GIT_DIR: \".git\",\n README: \"README\",\n CLONE_INIT_MARKER: \".sync-worktrees-clone-init\",\n} as const;\n\nexport const CONFIG_FILE_NAMES = [\n \"sync-worktrees.config.js\",\n \"sync-worktrees.config.mjs\",\n \"sync-worktrees.config.cjs\",\n] as const;\n\nexport const MAINTENANCE_CONSTANTS = {\n STATE_FILENAME: \"sync-worktrees-maintenance.json\",\n} as const;\n\nexport const TRASH_CONSTANTS = {\n MANIFEST_FILENAME: \"manifest.json\",\n PAYLOAD_DIRNAME: \"payload\",\n BUNDLE_FILENAME: \"commits.bundle\",\n SCHEMA_VERSION: 1,\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 { ERROR_MESSAGES } from \"../constants\";\n\nexport class SyncWorktreesError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly cause?: Error,\n ) {\n super(message);\n this.name = this.constructor.name;\n Object.setPrototypeOf(this, new.target.prototype);\n if (cause && cause.stack) {\n this.stack = `${this.stack}\\nCaused by: ${cause.stack}`;\n }\n }\n}\n\nexport class GitError extends SyncWorktreesError {\n constructor(message: string, code: string, cause?: Error) {\n super(message, `GIT_${code}`, cause);\n }\n}\n\nexport class GitNotInitializedError extends GitError {\n constructor() {\n super(ERROR_MESSAGES.GIT_NOT_INITIALIZED, \"NOT_INITIALIZED\");\n }\n}\n\nexport class GitOperationError extends GitError {\n constructor(operation: string, details: string, cause?: Error) {\n super(`Git operation '${operation}' failed: ${details}`, \"OPERATION_FAILED\", cause);\n }\n}\n\nexport class FastForwardError extends GitError {\n constructor(\n public readonly branchName: string,\n cause?: Error,\n ) {\n super(`Cannot fast-forward branch '${branchName}'`, \"FAST_FORWARD_FAILED\", cause);\n }\n}\n\nexport class WorktreeError extends SyncWorktreesError {\n constructor(message: string, code: string, cause?: Error) {\n super(message, `WORKTREE_${code}`, cause);\n }\n}\n\nexport class WorktreeAlreadyExistsError extends WorktreeError {\n constructor(\n public readonly path: string,\n public readonly branchName: string,\n ) {\n super(`Worktree already exists at '${path}' for branch '${branchName}'`, \"ALREADY_EXISTS\");\n }\n}\n\nexport class WorktreeNotCleanError extends WorktreeError {\n constructor(\n public readonly path: string,\n public readonly reasons: string[],\n ) {\n super(`Worktree at '${path}' is not clean: ${reasons.join(\", \")}`, \"NOT_CLEAN\");\n }\n}\n\nexport class ConfigError extends SyncWorktreesError {\n constructor(message: string, code: string, cause?: Error) {\n super(message, `CONFIG_${code}`, cause);\n }\n}\n\nexport class ConfigValidationError extends ConfigError {\n constructor(\n public readonly field: string,\n public readonly reason: string,\n ) {\n super(`Invalid configuration for '${field}': ${reason}`, \"VALIDATION_FAILED\");\n }\n}\n\nexport class ConfigFileNotFoundError extends ConfigError {\n constructor(public readonly configPath: string) {\n super(`Config file not found: ${configPath}`, \"FILE_NOT_FOUND\");\n }\n}\n\nexport class ConfigFileExistsError extends ConfigError {\n constructor(public readonly configPath: string) {\n super(`Config file already exists: ${configPath}`, \"FILE_EXISTS\");\n }\n}\n\nexport class PathResolutionError extends SyncWorktreesError {\n constructor(\n public readonly path: string,\n public readonly reason: string,\n ) {\n super(`Path resolution failed for '${path}': ${reason}`, \"PATH_RESOLUTION_FAILED\");\n }\n}\n\nexport class TrashError extends SyncWorktreesError {\n constructor(message: string, code: string, cause?: Error) {\n super(message, `TRASH_${code}`, cause);\n }\n}\n\nexport class TrashOperationError extends TrashError {\n constructor(\n public readonly operation: string,\n details: string,\n cause?: Error,\n ) {\n super(`Trash operation '${operation}' failed: ${details}`, \"OPERATION_FAILED\", cause);\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 * as path from \"path\";\nimport { pathToFileURL } from \"url\";\n\nimport * as cron from \"node-cron\";\n\nimport { CONFIG_FILE_NAMES, DEFAULT_CONFIG } from \"../constants\";\nimport { ConfigFileNotFoundError, ConfigValidationError, SyncWorktreesError } from \"../errors\";\nimport { matchesPattern } from \"../utils/branch-filter\";\nimport { parseDuration } from \"../utils/date-filter\";\nimport { fileExists } from \"../utils/file-exists\";\nimport { getDefaultBareRepoDir } from \"../utils/git-url\";\nimport { normalizePathForCompare } from \"../utils/path-compare\";\nimport { REPOSITORY_MODES, isRepositoryMode } from \"../utils/repo-mode\";\nimport { sanitizeNameForPath } from \"../utils/sanitize-name\";\n\nimport type { Config, ConfigFile, RepositoryConfig, RepositoryMode } from \"../types\";\n\nconst CLONE_MODE_CONFLICTING_FIELDS = [\n \"branchInclude\",\n \"branchExclude\",\n \"branchMaxAge\",\n \"updateExistingWorktrees\",\n \"bareRepoDir\",\n \"trash\",\n] as const satisfies readonly (keyof RepositoryConfig)[];\n\nexport class ConfigLoaderService {\n async findConfigUpward(startDir: string): Promise<string | null> {\n let current = path.resolve(startDir);\n const root = path.parse(current).root;\n\n while (true) {\n for (const name of CONFIG_FILE_NAMES) {\n const candidate = path.join(current, name);\n if (await fileExists(candidate)) {\n return candidate;\n }\n }\n if (current === root) return null;\n const parent = path.dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n }\n\n async loadConfigFile(configPath: string): Promise<ConfigFile> {\n const absolutePath = path.resolve(configPath);\n\n if (!(await fileExists(absolutePath))) {\n throw new ConfigFileNotFoundError(absolutePath);\n }\n\n try {\n const fileUrl = pathToFileURL(absolutePath);\n fileUrl.searchParams.set(\"t\", Date.now().toString());\n const configModule = await import(fileUrl.href);\n const config = configModule.default;\n\n if (!config) {\n throw new Error(\"Config file must use 'export default' syntax\");\n }\n\n this.validateConfigFile(config);\n\n return config;\n } catch (error) {\n if (error instanceof SyncWorktreesError) {\n throw error;\n }\n throw new Error(`Failed to load config file: ${(error as Error).message}`);\n }\n }\n\n private validateConfigFile(config: unknown): asserts config is ConfigFile {\n if (!config || typeof config !== \"object\") {\n throw new Error(\"Config file must export an object\");\n }\n\n const configObj = config as Record<string, unknown>;\n\n if (!Array.isArray(configObj.repositories)) {\n throw new Error(\"Config file must have a 'repositories' array\");\n }\n\n if (configObj.repositories.length === 0) {\n throw new Error(\"Config file must have at least one repository\");\n }\n\n const seenNames = new Set<string>();\n\n configObj.repositories.forEach((repo: unknown, index: number) => {\n if (!repo || typeof repo !== \"object\") {\n throw new Error(`Repository at index ${index} must be an object`);\n }\n\n const repoObj = repo as Record<string, unknown>;\n\n if (!repoObj.name || typeof repoObj.name !== \"string\") {\n throw new Error(`Repository at index ${index} must have a 'name' property`);\n }\n\n if (seenNames.has(repoObj.name)) {\n throw new Error(`Duplicate repository name: ${repoObj.name}`);\n }\n seenNames.add(repoObj.name);\n\n if (!repoObj.repoUrl || typeof repoObj.repoUrl !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' must have a 'repoUrl' property`);\n }\n\n if (!this.isValidGitUrl(repoObj.repoUrl)) {\n throw new Error(\n `Repository '${repoObj.name}' has invalid 'repoUrl': '${repoObj.repoUrl}'. ` +\n `Expected an HTTP(S), SSH, Git protocol URL, or a local/file path (file://, absolute filesystem path)`,\n );\n }\n\n if (!repoObj.worktreeDir || typeof repoObj.worktreeDir !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' must have a 'worktreeDir' property`);\n }\n\n if (repoObj.bareRepoDir !== undefined && typeof repoObj.bareRepoDir !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'bareRepoDir' property`);\n }\n\n if (repoObj.cronSchedule !== undefined && typeof repoObj.cronSchedule !== \"string\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'cronSchedule' property`);\n }\n\n if (typeof repoObj.cronSchedule === \"string\" && !cron.validate(repoObj.cronSchedule)) {\n throw new Error(`Repository '${repoObj.name}' has invalid cron expression: '${repoObj.cronSchedule}'`);\n }\n\n if (repoObj.runOnce !== undefined && typeof repoObj.runOnce !== \"boolean\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'runOnce' property`);\n }\n\n if (repoObj.debug !== undefined && typeof repoObj.debug !== \"boolean\") {\n throw new Error(`Repository '${repoObj.name}' has invalid 'debug' property`);\n }\n\n if (repoObj.retry !== undefined) {\n this.validateRetryConfig(repoObj.retry, `Repository '${repoObj.name}' retry config`);\n }\n\n if (repoObj.filesToCopyOnBranchCreate !== undefined) {\n this.validateFilesToCopyConfig(repoObj.filesToCopyOnBranchCreate, `Repository '${repoObj.name}'`);\n }\n\n if (repoObj.hooks !== undefined) {\n this.validateHooksConfig(repoObj.hooks, `Repository '${repoObj.name}'`);\n }\n\n if (repoObj.sparseCheckout !== undefined) {\n this.validateSparseCheckoutConfig(repoObj.sparseCheckout, `Repository '${repoObj.name}'`);\n }\n\n if (repoObj.maintenance !== undefined) {\n this.validateMaintenanceConfig(repoObj.maintenance, `Repository '${repoObj.name}'`);\n }\n\n if (repoObj.trash !== undefined) {\n this.validateTrashConfig(repoObj.trash, `Repository '${repoObj.name}'`);\n }\n\n this.validateDepth(repoObj.depth, `Repository '${repoObj.name}' depth`);\n this.validateRepositoryMode(repoObj, configObj.defaults as Record<string, unknown> | undefined);\n });\n\n this.warnOnDuplicateRepoUrls(configObj.repositories as Array<Record<string, unknown>>);\n\n if (configObj.defaults) {\n if (typeof configObj.defaults !== \"object\") {\n throw new Error(\"'defaults' must be an object\");\n }\n\n const defaults = configObj.defaults as Record<string, unknown>;\n\n if (defaults.cronSchedule !== undefined && typeof defaults.cronSchedule !== \"string\") {\n throw new Error(\"Invalid 'cronSchedule' in defaults\");\n }\n if (typeof defaults.cronSchedule === \"string\" && !cron.validate(defaults.cronSchedule)) {\n throw new Error(`Invalid cron expression in defaults: '${defaults.cronSchedule}'`);\n }\n if (defaults.runOnce !== undefined && typeof defaults.runOnce !== \"boolean\") {\n throw new Error(\"Invalid 'runOnce' in defaults\");\n }\n if (defaults.debug !== undefined && typeof defaults.debug !== \"boolean\") {\n throw new Error(\"Invalid 'debug' in defaults\");\n }\n if (defaults.retry !== undefined && typeof defaults.retry !== \"object\") {\n throw new Error(\"Invalid 'retry' in defaults\");\n }\n if (defaults.retry !== undefined) {\n this.validateRetryConfig(defaults.retry, \"defaults retry config\");\n }\n if (defaults.filesToCopyOnBranchCreate !== undefined) {\n this.validateFilesToCopyConfig(defaults.filesToCopyOnBranchCreate, \"defaults\");\n }\n\n if (defaults.hooks !== undefined) {\n this.validateHooksConfig(defaults.hooks, \"defaults\");\n }\n\n if (defaults.sparseCheckout !== undefined) {\n this.validateSparseCheckoutConfig(defaults.sparseCheckout, \"defaults\");\n }\n\n if (defaults.maintenance !== undefined) {\n this.validateMaintenanceConfig(defaults.maintenance, \"defaults\");\n }\n\n if (defaults.trash !== undefined) {\n this.validateTrashConfig(defaults.trash, \"defaults\");\n }\n\n this.validateDepth(defaults.depth, \"defaults.depth\");\n\n if (defaults.mode !== undefined && !isRepositoryMode(defaults.mode)) {\n throw new ConfigValidationError(\"defaults.mode\", \"must be 'clone' or 'worktree'\");\n }\n\n if (defaults.branch !== undefined && (typeof defaults.branch !== \"string\" || defaults.branch.trim() === \"\")) {\n throw new ConfigValidationError(\"defaults.branch\", \"must be a non-empty string\");\n }\n }\n\n if (configObj.retry !== undefined) {\n this.validateRetryConfig(configObj.retry, \"retry config\");\n }\n\n if (configObj.parallelism !== undefined) {\n this.validateParallelismConfig(configObj.parallelism, \"global\");\n }\n\n if (configObj.defaults && typeof configObj.defaults === \"object\") {\n const defaults = configObj.defaults as Record<string, unknown>;\n if (defaults.parallelism !== undefined) {\n this.validateParallelismConfig(defaults.parallelism, \"defaults\");\n }\n }\n }\n\n private validateDepth(value: unknown, field: string): void {\n if (value === undefined) return;\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value <= 0) {\n throw new ConfigValidationError(field, \"must be a positive safe integer\");\n }\n }\n\n private validateMaintenanceConfig(value: unknown, context: string): void {\n if (value === undefined) return;\n if (typeof value !== \"object\" || value === null) {\n throw new Error(`'maintenance' in ${context} must be an object`);\n }\n const maintenance = value as Record<string, unknown>;\n if (maintenance.enabled !== undefined && typeof maintenance.enabled !== \"boolean\") {\n throw new Error(`'maintenance.enabled' in ${context} must be a boolean`);\n }\n if (maintenance.aggressive !== undefined && typeof maintenance.aggressive !== \"boolean\") {\n throw new Error(`'maintenance.aggressive' in ${context} must be a boolean`);\n }\n if (maintenance.interval !== undefined) {\n const parsed = typeof maintenance.interval === \"string\" ? parseDuration(maintenance.interval) : null;\n // Zero parses fine but would disable throttling entirely (gc every tick).\n if (parsed === null || parsed <= 0) {\n throw new Error(\n `'maintenance.interval' in ${context} must be a positive duration string like '7d', '24h', or '2w'`,\n );\n }\n }\n }\n\n private validateTrashConfig(value: unknown, context: string): void {\n if (value === undefined) return;\n if (typeof value !== \"object\" || value === null) {\n throw new Error(`'trash' in ${context} must be an object`);\n }\n const trash = value as Record<string, unknown>;\n if (trash.enabled !== undefined && typeof trash.enabled !== \"boolean\") {\n throw new Error(`'trash.enabled' in ${context} must be a boolean`);\n }\n if (trash.migrateLegacy !== undefined && typeof trash.migrateLegacy !== \"boolean\") {\n throw new Error(`'trash.migrateLegacy' in ${context} must be a boolean`);\n }\n if (\n trash.retentionDays !== undefined &&\n (typeof trash.retentionDays !== \"number\" || !Number.isFinite(trash.retentionDays) || trash.retentionDays <= 0)\n ) {\n throw new Error(`'trash.retentionDays' in ${context} must be a positive number`);\n }\n if (\n trash.warnSizeBytes !== undefined &&\n (typeof trash.warnSizeBytes !== \"number\" || !Number.isFinite(trash.warnSizeBytes) || trash.warnSizeBytes <= 0)\n ) {\n throw new Error(`'trash.warnSizeBytes' in ${context} must be a positive number`);\n }\n }\n\n private validateRetryConfig(value: unknown, context: string): void {\n if (typeof value !== \"object\" || value === null) {\n throw new Error(context === \"retry config\" ? \"'retry' must be an object\" : `Invalid 'retry' in ${context}`);\n }\n\n const retry = value as Record<string, unknown>;\n\n if (retry.maxAttempts !== undefined) {\n if (retry.maxAttempts !== \"unlimited\" && (typeof retry.maxAttempts !== \"number\" || retry.maxAttempts < 1)) {\n throw new Error(\"Invalid 'maxAttempts' in retry config. Must be 'unlimited' or a positive number\");\n }\n }\n\n if (retry.maxLfsRetries !== undefined) {\n if (typeof retry.maxLfsRetries !== \"number\" || retry.maxLfsRetries < 0) {\n throw new Error(\"Invalid 'maxLfsRetries' in retry config. Must be a non-negative number\");\n }\n }\n\n if (retry.initialDelayMs !== undefined && (typeof retry.initialDelayMs !== \"number\" || retry.initialDelayMs < 0)) {\n throw new Error(\"Invalid 'initialDelayMs' in retry config\");\n }\n\n if (retry.maxDelayMs !== undefined && (typeof retry.maxDelayMs !== \"number\" || retry.maxDelayMs < 0)) {\n throw new Error(\"Invalid 'maxDelayMs' in retry config\");\n }\n\n if (\n retry.backoffMultiplier !== undefined &&\n (typeof retry.backoffMultiplier !== \"number\" || retry.backoffMultiplier < 1)\n ) {\n throw new Error(\"Invalid 'backoffMultiplier' in retry config\");\n }\n\n if (retry.jitterMs !== undefined && (typeof retry.jitterMs !== \"number\" || retry.jitterMs < 0)) {\n throw new Error(\"Invalid 'jitterMs' in retry config\");\n }\n\n const initialDelay = (retry.initialDelayMs as number) ?? DEFAULT_CONFIG.RETRY.INITIAL_DELAY_MS;\n const maxDelay = (retry.maxDelayMs as number) ?? DEFAULT_CONFIG.RETRY.MAX_DELAY_MS;\n if (initialDelay > maxDelay) {\n throw new Error(\n `Invalid retry config: 'initialDelayMs' (${initialDelay}) must not exceed 'maxDelayMs' (${maxDelay})`,\n );\n }\n }\n\n private validateParallelismConfig(parallelism: unknown, context: string): void {\n if (typeof parallelism !== \"object\" || parallelism === null) {\n throw new Error(`'parallelism' in ${context} must be an object`);\n }\n\n const config = parallelism as Record<string, unknown>;\n\n const positiveIntFields = [\n \"maxRepositories\",\n \"maxWorktreeCreation\",\n \"maxWorktreeUpdates\",\n \"maxWorktreeRemoval\",\n \"maxStatusChecks\",\n \"maxBranchFetches\",\n ] as const;\n\n for (const field of positiveIntFields) {\n const value = config[field];\n if (value !== undefined && (typeof value !== \"number\" || value < 1)) {\n throw new Error(`Invalid '${field}' in ${context} parallelism config. Must be a positive number`);\n }\n }\n\n const maxRepos = (config.maxRepositories as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_REPOSITORIES;\n const maxCreation = (config.maxWorktreeCreation as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_CREATION;\n const maxUpdates = (config.maxWorktreeUpdates as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_UPDATES;\n const maxRemoval = (config.maxWorktreeRemoval as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_REMOVAL;\n const maxStatus = (config.maxStatusChecks as number) ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n\n const maxPerRepoOps = maxCreation + maxUpdates + maxRemoval + maxStatus;\n const totalMaxConcurrent = maxRepos * maxPerRepoOps;\n\n if (totalMaxConcurrent > DEFAULT_CONFIG.PARALLELISM.MAX_SAFE_TOTAL_CONCURRENT_OPS) {\n const safeMaxRepos = Math.floor(DEFAULT_CONFIG.PARALLELISM.MAX_SAFE_TOTAL_CONCURRENT_OPS / maxPerRepoOps);\n throw new Error(\n `Total concurrent operations (${totalMaxConcurrent}) exceeds safe limit (${DEFAULT_CONFIG.PARALLELISM.MAX_SAFE_TOTAL_CONCURRENT_OPS}). ` +\n `With current per-repository limits (creation: ${maxCreation}, updates: ${maxUpdates}, removal: ${maxRemoval}, status: ${maxStatus}), ` +\n `maximum safe maxRepositories is ${safeMaxRepos}. ` +\n `Consider reducing maxRepositories or lowering per-operation limits.`,\n );\n }\n }\n\n private validateFilesToCopyConfig(filesToCopy: unknown, context: string): void {\n if (!Array.isArray(filesToCopy)) {\n throw new Error(`'filesToCopyOnBranchCreate' in ${context} must be an array`);\n }\n\n for (let i = 0; i < filesToCopy.length; i++) {\n const pattern = filesToCopy[i];\n if (typeof pattern !== \"string\" || pattern.trim() === \"\") {\n throw new Error(\n `'filesToCopyOnBranchCreate' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n }\n\n private validateSparseCheckoutConfig(value: unknown, context: string): void {\n if (typeof value !== \"object\" || value === null) {\n throw new Error(`'sparseCheckout' in ${context} must be an object`);\n }\n\n const cfg = value as Record<string, unknown>;\n\n if (!Array.isArray(cfg.include)) {\n throw new Error(`'sparseCheckout.include' in ${context} must be an array`);\n }\n if (cfg.include.length === 0) {\n throw new Error(`'sparseCheckout.include' in ${context} must contain at least one pattern`);\n }\n for (let i = 0; i < cfg.include.length; i++) {\n const p = cfg.include[i];\n if (typeof p !== \"string\" || p.trim() === \"\") {\n throw new Error(\n `'sparseCheckout.include' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n\n if (cfg.exclude !== undefined) {\n if (!Array.isArray(cfg.exclude)) {\n throw new Error(`'sparseCheckout.exclude' in ${context} must be an array`);\n }\n for (let i = 0; i < cfg.exclude.length; i++) {\n const p = cfg.exclude[i];\n if (typeof p !== \"string\" || p.trim() === \"\") {\n throw new Error(\n `'sparseCheckout.exclude' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n }\n\n if (cfg.mode !== undefined && cfg.mode !== \"cone\" && cfg.mode !== \"no-cone\") {\n throw new Error(`'sparseCheckout.mode' in ${context} must be 'cone' or 'no-cone'`);\n }\n }\n\n private warnOnDuplicateRepoUrls(repositories: Array<Record<string, unknown>>): void {\n const seen = new Map<string, string[]>();\n for (const repo of repositories) {\n const url = typeof repo.repoUrl === \"string\" ? repo.repoUrl : null;\n const name = typeof repo.name === \"string\" ? repo.name : null;\n if (!url || !name) continue;\n const list = seen.get(url) ?? [];\n list.push(name);\n seen.set(url, list);\n }\n for (const [url, names] of seen) {\n if (names.length > 1) {\n console.warn(\n `[sync-worktrees] repoUrl '${url}' appears in multiple entries (${names.join(\", \")}). ` +\n `Pin 'bareRepoDir' on duplicate entries to make config reorder-proof.`,\n );\n }\n }\n }\n\n private validateRepositoryMode(\n repoObj: Record<string, unknown>,\n defaults: Record<string, unknown> | undefined,\n ): void {\n const repoName = repoObj.name as string;\n const repoMode = repoObj.mode;\n\n if (repoMode !== undefined && !isRepositoryMode(repoMode)) {\n throw new ConfigValidationError(`Repository '${repoName}' mode`, \"must be 'clone' or 'worktree'\");\n }\n\n if (\n repoObj.branch !== undefined &&\n (typeof repoObj.branch !== \"string\" || (repoObj.branch as string).trim() === \"\")\n ) {\n throw new ConfigValidationError(`Repository '${repoName}' branch`, \"must be a non-empty string\");\n }\n\n const effectiveMode = (repoMode as RepositoryMode | undefined) ?? (defaults?.mode as RepositoryMode | undefined);\n if (effectiveMode !== REPOSITORY_MODES.CLONE) {\n const depthFromRepo = repoObj.depth;\n const depthFromDefaults = defaults?.depth;\n if (depthFromRepo !== undefined || depthFromDefaults !== undefined) {\n const source = depthFromRepo !== undefined ? \"repository\" : \"defaults\";\n throw new ConfigValidationError(\n `Repository '${repoName}' depth`,\n `only supported when mode is 'clone' (set on ${source})`,\n );\n }\n\n const branchFromRepo = repoObj.branch;\n const branchFromDefaults = defaults?.branch;\n if (branchFromRepo !== undefined || branchFromDefaults !== undefined) {\n const source = branchFromRepo !== undefined ? \"repository\" : \"defaults\";\n throw new ConfigValidationError(\n `Repository '${repoName}' branch`,\n `only supported when mode is 'clone' (set on ${source})`,\n );\n }\n\n return;\n }\n\n for (const field of CLONE_MODE_CONFLICTING_FIELDS) {\n const fromRepo = repoObj[field];\n const fromDefaults = defaults?.[field];\n const present = fromRepo !== undefined || fromDefaults !== undefined;\n if (present) {\n const source = fromRepo !== undefined ? \"repository\" : \"defaults\";\n throw new ConfigValidationError(\n `Repository '${repoName}' ${field}`,\n `not supported when mode is 'clone' (set on ${source})`,\n );\n }\n }\n }\n\n private validateHooksConfig(hooks: unknown, context: string): void {\n if (typeof hooks !== \"object\" || hooks === null) {\n throw new Error(`'hooks' in ${context} must be an object`);\n }\n\n const hooksObj = hooks as Record<string, unknown>;\n\n if (hooksObj.onBranchCreated !== undefined) {\n if (!Array.isArray(hooksObj.onBranchCreated)) {\n throw new Error(`'hooks.onBranchCreated' in ${context} must be an array`);\n }\n\n for (let i = 0; i < hooksObj.onBranchCreated.length; i++) {\n const command = hooksObj.onBranchCreated[i];\n if (typeof command !== \"string\" || command.trim() === \"\") {\n throw new Error(\n `'hooks.onBranchCreated' in ${context} must contain only non-empty strings (invalid at index ${i})`,\n );\n }\n }\n }\n }\n\n resolveRepositoryConfig(\n repo: RepositoryConfig,\n defaults?: Partial<Config>,\n configDir?: string,\n globalRetry?: Config[\"retry\"],\n allRepositories?: RepositoryConfig[],\n ): RepositoryConfig {\n const mode: RepositoryMode = repo.mode ?? defaults?.mode ?? REPOSITORY_MODES.WORKTREE;\n\n const resolved: RepositoryConfig = {\n name: repo.name,\n repoUrl: repo.repoUrl,\n worktreeDir: this.resolvePath(repo.worktreeDir, configDir),\n cronSchedule: repo.cronSchedule ?? defaults?.cronSchedule ?? DEFAULT_CONFIG.CRON_SCHEDULE,\n runOnce: repo.runOnce ?? defaults?.runOnce ?? false,\n debug: repo.debug ?? defaults?.debug,\n mode,\n };\n\n if (configDir) {\n resolved.__configFileDir = configDir;\n }\n\n if (mode === REPOSITORY_MODES.CLONE) {\n if (repo.branch ?? defaults?.branch) {\n resolved.branch = repo.branch ?? defaults?.branch;\n }\n if (repo.depth !== undefined || defaults?.depth !== undefined) {\n resolved.depth = repo.depth ?? defaults?.depth;\n }\n } else {\n if (repo.bareRepoDir) {\n resolved.bareRepoDir = this.resolvePath(repo.bareRepoDir, configDir);\n } else if (allRepositories && this.isDuplicateRepoUrl(repo, allRepositories, defaults)) {\n const sanitized = sanitizeNameForPath(repo.name, `Repository '${repo.name}' name`);\n resolved.bareRepoDir = this.resolvePath(`.bare/${sanitized}`, configDir);\n } else {\n resolved.bareRepoDir = this.resolvePath(getDefaultBareRepoDir(repo.repoUrl), configDir);\n }\n\n if (repo.branchMaxAge || defaults?.branchMaxAge) {\n resolved.branchMaxAge = repo.branchMaxAge ?? defaults?.branchMaxAge;\n }\n\n if (repo.branchInclude || defaults?.branchInclude) {\n resolved.branchInclude = repo.branchInclude ?? defaults?.branchInclude;\n }\n\n if (repo.branchExclude || defaults?.branchExclude) {\n resolved.branchExclude = repo.branchExclude ?? defaults?.branchExclude;\n }\n\n if (repo.updateExistingWorktrees !== undefined || defaults?.updateExistingWorktrees !== undefined) {\n resolved.updateExistingWorktrees = repo.updateExistingWorktrees ?? defaults?.updateExistingWorktrees ?? true;\n }\n }\n\n if (repo.skipLfs !== undefined || defaults?.skipLfs !== undefined) {\n resolved.skipLfs = repo.skipLfs ?? defaults?.skipLfs ?? false;\n }\n\n if (repo.retry || defaults?.retry || globalRetry) {\n resolved.retry = {\n ...(globalRetry || {}),\n ...(defaults?.retry || {}),\n ...(repo.retry || {}),\n };\n }\n\n if (repo.parallelism || defaults?.parallelism) {\n resolved.parallelism = {\n ...(defaults?.parallelism || {}),\n ...(repo.parallelism || {}),\n };\n }\n\n if (repo.filesToCopyOnBranchCreate || defaults?.filesToCopyOnBranchCreate) {\n const files = repo.filesToCopyOnBranchCreate ?? defaults?.filesToCopyOnBranchCreate;\n resolved.filesToCopyOnBranchCreate = files?.map((f) => this.resolvePath(f, configDir));\n }\n\n if (repo.hooks || defaults?.hooks) {\n resolved.hooks = {\n ...(defaults?.hooks || {}),\n ...(repo.hooks || {}),\n };\n }\n\n const sparse = repo.sparseCheckout ?? defaults?.sparseCheckout;\n if (sparse) {\n resolved.sparseCheckout = sparse;\n }\n\n if (repo.maintenance || defaults?.maintenance) {\n resolved.maintenance = {\n ...(defaults?.maintenance || {}),\n ...(repo.maintenance || {}),\n };\n }\n\n if (repo.trash || defaults?.trash) {\n resolved.trash = {\n ...(defaults?.trash || {}),\n ...(repo.trash || {}),\n };\n }\n\n return resolved;\n }\n\n private isDuplicateRepoUrl(repo: RepositoryConfig, all: RepositoryConfig[], defaults?: Partial<Config>): boolean {\n const firstIndex = all.findIndex((r) => {\n const mode = r.mode ?? defaults?.mode ?? REPOSITORY_MODES.WORKTREE;\n return r.repoUrl === repo.repoUrl && mode === REPOSITORY_MODES.WORKTREE;\n });\n const myIndex = all.indexOf(repo);\n return firstIndex !== -1 && myIndex !== -1 && myIndex !== firstIndex;\n }\n\n detectBareRepoDirCollisions(repositories: RepositoryConfig[]): void {\n const seen = new Map<string, { name: string; displayPath: string }>();\n for (const repo of repositories) {\n if (!repo.bareRepoDir) continue;\n const key = normalizePathForCompare(repo.bareRepoDir);\n const displayPath = path.resolve(repo.bareRepoDir);\n const existing = seen.get(key);\n if (existing && existing.name !== repo.name) {\n throw new Error(\n `Repositories '${existing.name}' and '${repo.name}' resolve to the same bareRepoDir '${displayPath}'. ` +\n `Set distinct 'bareRepoDir' values for duplicate repoUrl entries.`,\n );\n }\n seen.set(key, { name: repo.name, displayPath });\n }\n }\n\n private isValidGitUrl(url: string): boolean {\n // HTTP(S) URLs\n if (/^https?:\\/\\/.+/.test(url)) return true;\n // SSH URLs (git@host:path or ssh://...)\n if (/^(ssh:\\/\\/|git@).+/.test(url)) return true;\n // Git protocol\n if (/^git:\\/\\/.+/.test(url)) return true;\n // Local file paths (absolute)\n if (/^(file:\\/\\/|\\/|[A-Za-z]:\\\\)/.test(url)) return true;\n return false;\n }\n\n private resolvePath(inputPath: string, baseDir?: string): string {\n if (path.isAbsolute(inputPath)) {\n return inputPath;\n }\n\n return path.resolve(baseDir || process.cwd(), inputPath);\n }\n\n filterRepositories(repositories: RepositoryConfig[], filter?: string): RepositoryConfig[] {\n if (!filter) {\n return repositories;\n }\n\n const patterns = filter.split(\",\").map((p) => p.trim());\n\n return repositories.filter((repo) => {\n return patterns.some((pattern) => matchesPattern(repo.name, pattern));\n });\n }\n\n async buildRepositories(\n configPath: string,\n overrides?: { filter?: string },\n ): Promise<{ repositories: RepositoryConfig[]; configFile: ConfigFile; configDir: string }> {\n const configFile = await this.loadConfigFile(configPath);\n const configDir = path.dirname(path.resolve(configPath));\n\n let repositories = configFile.repositories.map((repo) =>\n this.resolveRepositoryConfig(repo, configFile.defaults, configDir, configFile.retry, configFile.repositories),\n );\n\n this.detectBareRepoDirCollisions(repositories);\n\n if (overrides?.filter) {\n repositories = this.filterRepositories(repositories, overrides.filter);\n }\n\n return { repositories, configFile, configDir };\n }\n}\n", "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", "export function parseDuration(durationStr: string): number | null {\n const match = durationStr.match(/^(\\d+)([hdwmy])$/);\n if (!match) {\n return null;\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n const multipliers: Record<string, number> = {\n h: 60 * 60 * 1000, // hours\n d: 24 * 60 * 60 * 1000, // days\n w: 7 * 24 * 60 * 60 * 1000, // weeks\n m: 30 * 24 * 60 * 60 * 1000, // months (approximate)\n y: 365 * 24 * 60 * 60 * 1000, // years (approximate)\n };\n\n return value * multipliers[unit];\n}\n\nexport function filterBranchesByAge(\n branches: { branch: string; lastActivity: Date }[],\n maxAge: string,\n): { branch: string; lastActivity: Date }[] {\n const maxAgeMs = parseDuration(maxAge);\n if (maxAgeMs === null) {\n console.warn(`Invalid duration format: ${maxAge}. Using all branches.`);\n return branches;\n }\n\n const cutoffDate = new Date(Date.now() - maxAgeMs);\n\n return branches.filter(({ lastActivity }) => lastActivity >= cutoffDate);\n}\n\nexport function formatDuration(durationStr: string): string {\n const match = durationStr.match(/^(\\d+)([hdwmy])$/);\n if (!match) {\n return durationStr;\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n const unitNames: Record<string, string> = {\n h: value === 1 ? \"hour\" : \"hours\",\n d: value === 1 ? \"day\" : \"days\",\n w: value === 1 ? \"week\" : \"weeks\",\n m: value === 1 ? \"month\" : \"months\",\n y: value === 1 ? \"year\" : \"years\",\n };\n\n return `${value} ${unitNames[unit]}`;\n}\n", "import * as fs from \"fs/promises\";\n\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await fs.access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport type PathProbeResult = \"exists\" | \"missing\" | \"unknown\";\n\n// Removal decisions must distinguish \"path is gone\" from \"probe failed\"\n// (EMFILE/EINTR under load): an unverifiable path must never read as deleted.\nexport async function probePathExists(path: string): Promise<PathProbeResult> {\n try {\n await fs.access(path);\n return \"exists\";\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n return code === \"ENOENT\" || code === \"ENOTDIR\" ? \"missing\" : \"unknown\";\n }\n}\n", "/**\n * Extracts the repository name from a Git URL\n * @param gitUrl - The Git URL (HTTPS or SSH format)\n * @returns The repository name without .git extension\n * @throws Error if the URL format is invalid\n */\nexport function extractRepoNameFromUrl(gitUrl: string): string {\n // Remove trailing spaces\n const url = gitUrl.trim();\n\n // Handle SSH format: git@github.com:user/repo.git or ssh://git@domain/path/repo.git\n const sshMatch = url.match(/^git@[^:]+:(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (sshMatch) {\n return sshMatch[1];\n }\n\n // Handle SSH URL format: ssh://git@domain.com/path/repo.git\n const sshUrlMatch = url.match(/^ssh:\\/\\/[^/]+\\/(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (sshUrlMatch) {\n return sshUrlMatch[1];\n }\n\n // Handle HTTPS format: https://github.com/user/repo.git\n const httpsMatch = url.match(/^https?:\\/\\/[^/]+\\/(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (httpsMatch) {\n return httpsMatch[1];\n }\n\n // Handle file:// URLs for local repositories\n const fileMatch = url.match(/^file:\\/\\/(?:.+\\/)?([^/]+?)(?:\\.git)?$/);\n if (fileMatch) {\n return fileMatch[1];\n }\n\n throw new Error(`Invalid Git URL format: ${gitUrl}`);\n}\n\n/**\n * Generates the default bare repository directory path\n * @param repoUrl - The Git repository URL\n * @param baseDir - The base directory for bare repos (default: .bare)\n * @returns The path to the bare repository\n */\nexport function getDefaultBareRepoDir(repoUrl: string, baseDir: string = \".bare\"): string {\n const repoName = extractRepoNameFromUrl(repoUrl);\n return `${baseDir}/${repoName}`;\n}\n\n/**\n * Normalizes a Git remote URL for equivalence comparison only: trims, lowercases\n * a leading `scheme://host`, and strips a trailing slash and a single trailing\n * `.git`. Intentionally does NOT equate scp-style (git@host:path) with https://\n * forms \u2014 those are left distinct. Use only to decide whether two URLs point at\n * the same remote, never as a canonical URL for git operations.\n */\nexport function normalizeRepoUrlForComparison(url: string): string {\n let normalized = url.trim();\n // Only forge-style remotes (http(s)/ssh/git:// and scp git@host:path) treat a\n // trailing \".git\" as optional/equivalent. For file:// and bare local paths,\n // \"foo.git\" and \"foo\" can be genuinely different directories, so we must NOT\n // strip \".git\" there or we'd hide a real origin mismatch.\n const isForgeUrl = /^(https?|ssh|git):\\/\\//i.test(normalized) || /^[\\w.-]+@[^/]+:/.test(normalized);\n normalized = normalized.replace(/^[a-zA-Z][a-zA-Z0-9+.-]*:\\/\\/[^/]+/, (prefix) => prefix.toLowerCase());\n normalized = normalized.replace(/\\/+$/, \"\");\n if (isForgeUrl) {\n normalized = normalized.replace(/\\.git$/, \"\");\n }\n return normalized;\n}\n", "import * as path from \"path\";\n\n// darwin default filesystem (APFS default, HFS+) is case-insensitive.\n// Case-sensitive APFS volumes on macOS exist but are rare; those will see false-positive\n// matches for case-differing paths. Acceptable tradeoff vs breaking the common case.\nconst CASE_INSENSITIVE_PLATFORMS = new Set([\"darwin\"]);\n\nexport function isCaseInsensitiveFs(platform: NodeJS.Platform = process.platform): boolean {\n return CASE_INSENSITIVE_PLATFORMS.has(platform);\n}\n\n/**\n * Normalizes a path for equality comparison.\n *\n * The `platform` argument is a case-sensitivity hint only: it controls whether\n * the resolved path is lower-cased before comparison.\n */\nexport function normalizePathForCompare(p: string, platform: NodeJS.Platform = process.platform): string {\n const resolved = path.resolve(p);\n return isCaseInsensitiveFs(platform) ? resolved.toLowerCase() : resolved;\n}\n\n/**\n * Compares two paths for equality after host-path resolution and platform-aware case folding.\n *\n * The `platform` argument is a case-sensitivity hint only. See\n * {@link normalizePathForCompare} for the caveats about path.resolve semantics.\n */\nexport function pathsEqual(a: string, b: string, platform: NodeJS.Platform = process.platform): boolean {\n return normalizePathForCompare(a, platform) === normalizePathForCompare(b, platform);\n}\n", "import type { Config, RepositoryMode } from \"../types\";\n\nexport const REPOSITORY_MODES = {\n CLONE: \"clone\",\n WORKTREE: \"worktree\",\n} as const satisfies Record<string, RepositoryMode>;\n\nexport function isRepositoryMode(value: unknown): value is RepositoryMode {\n return value === REPOSITORY_MODES.CLONE || value === REPOSITORY_MODES.WORKTREE;\n}\n\nexport function resolveMode(cfg: Pick<Config, \"mode\">): RepositoryMode {\n return cfg.mode ?? REPOSITORY_MODES.WORKTREE;\n}\n", "import { ConfigValidationError } from \"../errors\";\n\nconst WINDOWS_RESERVED = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;\n// eslint-disable-next-line no-control-regex -- Windows reserves \\x00\u2013\\x1f for path validation; intentional\nconst ILLEGAL_CHARS = /[<>:\"|?*\\x00-\\x1f]/g;\n\nexport function sanitizeNameForPath(name: string, fieldContext = \"name\"): string {\n if (!name || typeof name !== \"string\") {\n throw new ConfigValidationError(fieldContext, \"must be a non-empty string\");\n }\n\n let cleaned = name.trim();\n cleaned = cleaned.replace(/[/\\\\]/g, \"-\");\n cleaned = cleaned.replace(/^\\.+/, \"\");\n cleaned = cleaned.replace(ILLEGAL_CHARS, \"_\");\n cleaned = cleaned.replace(/[. ]+$/, \"\");\n\n if (cleaned.length === 0) {\n throw new ConfigValidationError(fieldContext, `'${name}' produces an empty path segment after sanitization`);\n }\n\n if (WINDOWS_RESERVED.test(cleaned)) {\n throw new ConfigValidationError(fieldContext, `'${cleaned}' is a reserved name on Windows`);\n }\n\n return cleaned;\n}\n", "import React from \"react\";\nimport * as path from \"path\";\nimport { render, Instance } from \"ink\";\nimport * as cron from \"node-cron\";\nimport pLimit from \"p-limit\";\nimport { spawn, spawnSync } from \"child_process\";\nimport { existsSync } from \"fs\";\nimport App from \"../components/App\";\nimport { DEFAULT_CONFIG } from \"../constants\";\nimport { WorktreeSyncService } from \"./worktree-sync.service\";\nimport { ConfigLoaderService } from \"./config-loader.service\";\nimport { BranchCreatedActionsService } from \"./branch-created-actions.service\";\nimport { HookExecutionService } from \"./hook-execution.service\";\nimport { PathResolutionService } from \"./path-resolution.service\";\nimport { Logger, LogOutputFn, LogLevel } from \"./logger.service\";\nimport { formatCloneSkipReason } from \"../utils/clone-skip-format\";\nimport { calculateSyncDiskSpace } from \"../utils/disk-space\";\nimport { getDefaultBareRepoDir } from \"../utils/git-url\";\nimport { AppEventEmitter } from \"../utils/app-events\";\nimport { resolveMode } from \"../utils/repo-mode\";\nimport { shellEscape } from \"../utils/shell-escape\";\nimport * as fs from \"fs/promises\";\nimport { calculateDirectorySize, formatBytes } from \"../utils/disk-space\";\nimport { formatDuration } from \"../utils/timing\";\nimport { GIT_CONSTANTS, METADATA_CONSTANTS, TERMINAL_CONSTANTS } from \"../constants\";\nimport type {\n RepositoryConfig,\n HookContext,\n WorktreeStatusEntry,\n DivergedDirectoryInfo,\n RepositoryListEntry,\n RepositoryDiskUsage,\n} from \"../types\";\n\nconst WAIT_SYNC_FAST_TIMEOUT_MS = 2000;\nconst WAIT_SYNC_DEFAULT_TIMEOUT_MS = 30000;\n\nexport class InteractiveUIService {\n private app: Instance | null = null;\n private syncServices: WorktreeSyncService[];\n private configPath?: string;\n private cronSchedule?: string;\n private cronJobs: cron.ScheduledTask[] = [];\n private repositoryCount: number;\n private logBuffer: Array<{ message: string; level: \"info\" | \"warn\" | \"error\" }> = [];\n private uiReady = false;\n private hookExecutionService = new HookExecutionService();\n private branchCreatedActions = new BranchCreatedActionsService();\n private pathResolution = new PathResolutionService();\n private limit: ReturnType<typeof pLimit>;\n private maxProgressLines: number;\n private reloadInProgress = false;\n private isDestroyed = false;\n private events: AppEventEmitter;\n private ownsEvents: boolean;\n private unsubscribeCallbacks: Array<() => void> = [];\n private progressUnsubscribers: Array<() => void> = [];\n\n constructor(\n syncServices: WorktreeSyncService[],\n configPath?: string,\n cronSchedule?: string,\n maxParallel?: number,\n events?: AppEventEmitter,\n ) {\n this.ownsEvents = events === undefined;\n this.events = events ?? new AppEventEmitter();\n if (syncServices.length === 0) {\n throw new Error(\"InteractiveUIService requires at least one WorktreeSyncService\");\n }\n\n this.syncServices = syncServices;\n this.configPath = configPath;\n this.cronSchedule = cronSchedule;\n this.repositoryCount = syncServices.length;\n this.maxProgressLines = Math.max(1, maxParallel ?? DEFAULT_CONFIG.PARALLELISM.MAX_REPOSITORIES);\n this.limit = pLimit(this.maxProgressLines);\n\n this.startBufferFlushCheck();\n this.renderUI();\n this.subscribeToServiceProgress();\n this.injectLoggersIntoServices();\n\n // Add initial log after a short delay to verify the pipeline works\n setTimeout(() => {\n this.addLog(\"\uD83D\uDE80 sync-worktrees UI initialized\", \"info\");\n }, 100);\n }\n\n public getEvents(): AppEventEmitter {\n return this.events;\n }\n\n private startBufferFlushCheck(): void {\n const unsubscribe = this.events.on(\"uiReady\", () => {\n this.uiReady = true;\n this.flushLogBuffer();\n unsubscribe();\n const index = this.unsubscribeCallbacks.indexOf(unsubscribe);\n if (index !== -1) this.unsubscribeCallbacks.splice(index, 1);\n });\n this.unsubscribeCallbacks.push(unsubscribe);\n }\n\n private createOutputFn(): LogOutputFn {\n return (message: string, level: LogLevel) => {\n const uiLevel = level === \"debug\" ? \"info\" : level;\n this.addLog(message, uiLevel);\n };\n }\n\n private injectLoggersIntoServices(): void {\n const outputFn = this.createOutputFn();\n for (const service of this.syncServices) {\n const config = service.config as RepositoryConfig;\n service.updateLogger(\n new Logger({\n repoName: config.name,\n debug: config.debug,\n outputFn,\n }),\n );\n }\n }\n\n private subscribeToServiceProgress(): void {\n for (const unsubscribe of this.progressUnsubscribers) {\n unsubscribe();\n }\n this.progressUnsubscribers = this.syncServices.map((service, index) => {\n const repoName = this.getRepoName(index);\n if (!service.onProgress) return () => undefined;\n return service.onProgress((event) => {\n if (this.isDestroyed) return;\n this.events.emit(\"setSyncProgress\", {\n repo: repoName,\n phase: event.phase,\n message: event.message,\n progress: event.progress,\n processed: event.processed,\n total: event.total,\n });\n });\n });\n }\n\n public addLog(message: string, level: \"info\" | \"warn\" | \"error\" = \"info\"): void {\n if (this.isDestroyed) return;\n if (this.uiReady) {\n this.events.emit(\"addLog\", { message, level });\n } else {\n this.logBuffer.push({ message, level });\n }\n }\n\n private flushLogBuffer(): void {\n for (const log of this.logBuffer) {\n this.events.emit(\"addLog\", { message: log.message, level: log.level });\n }\n this.logBuffer = [];\n }\n\n public setupCronJobs(): void {\n const scheduleGroups = new Map<string, WorktreeSyncService[]>();\n\n for (const service of this.syncServices) {\n if (service.config.runOnce) continue;\n const schedule = service.config.cronSchedule || this.cronSchedule;\n if (!schedule) continue;\n\n if (!scheduleGroups.has(schedule)) {\n scheduleGroups.set(schedule, []);\n }\n scheduleGroups.get(schedule)!.push(service);\n }\n\n for (const [schedule, services] of scheduleGroups) {\n const task = cron.schedule(schedule, async () => {\n await this.runSyncCycle(services, { logErrors: false });\n });\n this.cronJobs.push(task);\n }\n }\n\n private cancelCronJobs(): void {\n for (const job of this.cronJobs) {\n job.stop();\n }\n this.cronJobs = [];\n }\n\n public registerCronJob(job: cron.ScheduledTask): void {\n this.cronJobs.push(job);\n }\n\n private renderUI(): void {\n if (this.app) {\n this.app.unmount();\n }\n\n this.app = render(\n <App\n events={this.events}\n repositoryCount={this.repositoryCount}\n cronSchedule={this.cronSchedule}\n maxProgressLines={this.maxProgressLines}\n onManualSync={() => this.handleManualSync()}\n onReload={() => this.handleReload()}\n onQuit={() => this.handleQuit()}\n getRepositoryList={() => this.getRepositoryList()}\n getBranchesForRepo={(index: number) => this.getBranchesForRepo(index)}\n getDefaultBranchForRepo={(index: number) => this.getDefaultBranchForRepo(index)}\n fetchForRepo={(index: number) => this.fetchForRepo(index)}\n createAndPushBranch={(repoIndex: number, baseBranch: string, branchName: string) =>\n this.createAndPushBranch(repoIndex, baseBranch, branchName)\n }\n getWorktreesForRepo={(index: number) => this.getWorktreesForRepo(index)}\n getWorktreeStatusForRepo={(index: number) => this.getWorktreeStatusForRepo(index)}\n getRepositoryDiskUsage={(index: number) => this.getRepositoryDiskUsage(index)}\n getDivergedDirectoriesForRepo={(index: number) => this.getDivergedDirectoriesForRepo(index)}\n deleteDivergedDirectory={(repoIndex: number, name: string) =>\n this.deleteDivergedDirectory(repoIndex, name)\n }\n openEditorInWorktree={(path: string) => this.openEditorInWorktree(path)}\n openTerminalInWorktree={(repoIndex: number, path: string, branchName: string) =>\n this.openTerminalInWorktree(repoIndex, path, branchName)\n }\n copyBranchFiles={(repoIndex: number, baseBranch: string, targetBranch: string) =>\n this.copyBranchFiles(repoIndex, baseBranch, targetBranch)\n }\n createWorktreeForBranch={(repoIndex: number, branchName: string) =>\n this.createWorktreeForBranch(repoIndex, branchName)\n }\n executeOnBranchCreatedHooks={(repoIndex: number, context: HookContext) =>\n this.executeOnBranchCreatedHooks(repoIndex, context)\n }\n />,\n {\n alternateScreen: true,\n incrementalRendering: true,\n },\n );\n }\n\n private async handleManualSync(): Promise<void> {\n await this.triggerInitialSync();\n }\n\n public async triggerInitialSync(): Promise<void> {\n await this.runSyncCycle(this.syncServices, { logErrors: true });\n }\n\n private async handleReload(): Promise<void> {\n if (this.reloadInProgress) {\n return;\n }\n this.reloadInProgress = true;\n let cronJobsCancelled = false;\n try {\n if (!this.configPath) {\n this.setStatus(\"idle\");\n return;\n }\n\n await this.waitForInProgressSyncs();\n\n this.addLog(\"Reloading configuration...\");\n this.setStatus(\"syncing\");\n\n // Validate and load new config BEFORE canceling old cron jobs\n // to prevent a window with no cron running on validation failure\n const configLoader = new ConfigLoaderService();\n const { repositories } = await configLoader.buildRepositories(this.configPath);\n\n const initResults = await Promise.allSettled(\n repositories.map((repoConfig) =>\n this.limit(async () => {\n const service = new WorktreeSyncService(repoConfig);\n await service.initialize();\n return {\n service,\n clonePhaseSkips: service.getRecordedSkips().map((reason) => ({\n repo: repoConfig.name || repoConfig.repoUrl,\n reason: formatCloneSkipReason(reason),\n })),\n };\n }),\n ),\n );\n\n const newServices: WorktreeSyncService[] = [];\n const initClonePhaseSkips: Array<{ repo: string; reason: string }> = [];\n for (const result of initResults) {\n if (result.status === \"fulfilled\") {\n newServices.push(result.value.service);\n initClonePhaseSkips.push(...result.value.clonePhaseSkips);\n } else {\n this.addLog(`Failed to initialize repository: ${result.reason}`, \"error\");\n }\n }\n\n if (newServices.length === 0) {\n throw new Error(\"No repositories could be initialized from the configuration\");\n }\n\n // Cancel old cron jobs only after new config is validated and services initialized\n this.cancelCronJobs();\n cronJobsCancelled = true;\n\n this.syncServices = newServices;\n this.repositoryCount = this.syncServices.length;\n this.subscribeToServiceProgress();\n this.injectLoggersIntoServices();\n\n const uniqueSchedules = [...new Set(this.syncServices.map((s) => s.config.cronSchedule))];\n this.cronSchedule = uniqueSchedules.length === 1 ? uniqueSchedules[0] : undefined;\n\n this.setupCronJobs();\n\n this.events.emit(\"updateRepositoryCount\", this.repositoryCount);\n this.events.emit(\"updateCronSchedule\", this.cronSchedule);\n\n const {\n failures,\n skipped,\n clonePhaseSkips: syncClonePhaseSkips,\n attempted,\n } = await this.runSyncServices(this.syncServices);\n const clonePhaseSkips = [...initClonePhaseSkips, ...syncClonePhaseSkips];\n await this.recordSyncOutcome({ failures, skipped, attempted });\n this.setStatus(\"idle\");\n\n for (const skip of skipped) {\n this.addLog(`Sync skipped for '${skip.repo}': ${skip.reason}`, \"warn\");\n }\n for (const skip of clonePhaseSkips) {\n this.addLog(`Clone-mode skip for '${skip.repo}': ${skip.reason}`, \"warn\");\n }\n if (clonePhaseSkips.length > 0) {\n this.addLog(`\u26A0\uFE0F ${clonePhaseSkips.length} clone-mode skip(s) during reload`, \"warn\");\n }\n if (failures.length > 0) {\n for (const failure of failures) {\n this.addLog(`Failed to sync repository '${failure.repo}': ${failure.error}`, \"error\");\n }\n this.addLog(`Reload completed with ${failures.length} repository failure(s)`, \"warn\");\n }\n } catch (error) {\n this.addLog(`Reload failed: ${(error as Error).message}`, \"error\");\n if (cronJobsCancelled) {\n this.setupCronJobs();\n }\n this.setStatus(\"idle\");\n } finally {\n this.reloadInProgress = false;\n }\n }\n\n private async handleQuit(): Promise<void> {\n await this.destroy();\n process.exit(0);\n }\n\n private async waitForInProgressSyncs(timeoutMs: number = WAIT_SYNC_DEFAULT_TIMEOUT_MS): Promise<void> {\n const inProgressServices = this.syncServices.filter((s) => s.isSyncInProgress());\n\n if (inProgressServices.length === 0) {\n return;\n }\n\n this.addLog(`Waiting for ${inProgressServices.length} in-progress sync(s) to finish...`, \"info\");\n\n const syncChecks = inProgressServices.map(async (service) => {\n const checkInterval = 500;\n const startTime = Date.now();\n\n while (service.isSyncInProgress()) {\n if (Date.now() - startTime > timeoutMs) {\n throw new Error(\"Timeout waiting for sync operations to complete\");\n }\n await new Promise((resolve) => setTimeout(resolve, checkInterval));\n }\n });\n\n try {\n await Promise.all(syncChecks);\n } catch {\n this.addLog(\n `Warning: Timeout waiting for sync operations to complete after ${formatDuration(timeoutMs)}. Proceeding with potential data loss risk.`,\n \"warn\",\n );\n }\n }\n\n public updateLastSyncTime(): void {\n if (this.isDestroyed) return;\n this.events.emit(\"updateLastSyncTime\");\n }\n\n public setStatus(status: \"idle\" | \"syncing\"): void {\n if (this.isDestroyed) return;\n this.events.emit(\"setStatus\", status);\n if (status === \"idle\") {\n this.events.emit(\"setSyncProgress\", null);\n }\n }\n\n public setDiskSpace(diskSpace: string): void {\n if (this.isDestroyed) return;\n this.events.emit(\"setDiskSpace\", diskSpace);\n }\n\n public async calculateAndUpdateDiskSpace(): Promise<void> {\n try {\n const bareRepoDirs = this.syncServices.map(\n (service) => service.config.bareRepoDir || getDefaultBareRepoDir(service.config.repoUrl),\n );\n const worktreeDirs = this.syncServices.map((service) => service.config.worktreeDir);\n\n const diskSpace = await calculateSyncDiskSpace(bareRepoDirs, worktreeDirs);\n this.setDiskSpace(diskSpace);\n } catch (error) {\n this.addLog(`Failed to calculate disk space: ${error instanceof Error ? error.message : String(error)}`, \"error\");\n this.setDiskSpace(\"N/A\");\n }\n }\n\n public getRepositoryList(): RepositoryListEntry[] {\n return this.syncServices.map((service, index) => ({\n index,\n name: this.getRepoName(index),\n repoUrl: service.config.repoUrl,\n }));\n }\n\n private getRepoName(index: number): string {\n const service = this.syncServices[index];\n return (service.config as RepositoryConfig).name || `repo-${index}`;\n }\n\n public async getRepositoryDiskUsage(repoIndex: number): Promise<RepositoryDiskUsage> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n const config = service.config;\n const repoName = this.getRepoName(repoIndex);\n const mode = resolveMode(config);\n const sizeTargets: Array<{ kind: \"bare\" | \"worktree\"; path: string }> = [\n ...(mode === \"worktree\"\n ? [{ kind: \"bare\" as const, path: config.bareRepoDir || getDefaultBareRepoDir(config.repoUrl) }]\n : []),\n { kind: \"worktree\", path: config.worktreeDir },\n ];\n\n let bareSizeBytes = 0;\n let worktreeSizeBytes = 0;\n const errors: string[] = [];\n\n for (const target of sizeTargets) {\n try {\n const size = await calculateDirectorySize(target.path);\n if (target.kind === \"bare\") {\n bareSizeBytes = size;\n } else {\n worktreeSizeBytes = size;\n }\n } catch (error) {\n errors.push(`${target.path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n const sizeBytes = bareSizeBytes + worktreeSizeBytes;\n const failedAllPaths = errors.length === sizeTargets.length;\n const partialFailure = errors.length > 0 && !failedAllPaths;\n\n return {\n repoIndex,\n repoName,\n sizeBytes: failedAllPaths ? null : sizeBytes,\n sizeFormatted: failedAllPaths ? \"N/A\" : partialFailure ? `\u2265${formatBytes(sizeBytes)}` : formatBytes(sizeBytes),\n bareSizeBytes,\n worktreeSizeBytes,\n error: errors.length > 0 ? errors.join(\"; \") : undefined,\n };\n }\n\n public async getBranchesForRepo(repoIndex: number): Promise<string[]> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n if (!service.isInitialized() && !service.isCloneMode()) {\n return [];\n }\n // Clone-mode branch listing hits the network (ls-remote) whether or not\n // the clone is initialized \u2014 fail to an empty list in both cases so the\n // wizard's fetch-and-retry path handles it uniformly.\n try {\n return await service.getRemoteBranches();\n } catch {\n return [];\n }\n }\n\n public getDefaultBranchForRepo(repoIndex: number): string {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n const gitService = service.getGitService();\n return gitService.getDefaultBranch();\n }\n\n public async fetchForRepo(repoIndex: number): Promise<void> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n const result = await service.runQueuedRepoOperation(async () => {\n // Use the unlocked init path: initialize() re-enters the repo mutex and would\n // self-deadlock inside this queued operation.\n if (!service.isInitialized()) {\n await service.initializeUnlocked();\n }\n if (service.isCloneMode()) {\n // Clone-mode tracks a single branch; there is nothing to fetch-all here.\n // Branch discovery is a live `git ls-remote` performed when the picker opens.\n return;\n }\n await service.getGitService().fetchAll();\n });\n if (!result.started) {\n throw new Error(\"Another process holds the repository lock; fetch skipped. Try again.\");\n }\n }\n\n public async createAndPushBranch(\n repoIndex: number,\n baseBranch: string,\n branchName: string,\n ): Promise<{ success: boolean; finalName: string; error?: string }> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n return { success: false, finalName: branchName, error: `Invalid repository index: ${repoIndex}` };\n }\n\n const service = this.syncServices[repoIndex];\n const gitService = service.getGitService();\n\n // Serialize branch+push behind any in-flight sync so it can't race git's\n // index/refs. addWorktree (createWorktreeForBranch) is a separate queued op.\n const result = await service.runQueuedRepoOperation(async () => {\n const maxAttempts = 10;\n let finalName = branchName;\n let suffix = 0;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n await gitService.createBranch(finalName, baseBranch);\n await gitService.pushBranch(finalName);\n return { success: true, finalName };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (errorMessage.includes(\"already exists\")) {\n suffix++;\n finalName = `${branchName}-${suffix}`;\n continue;\n }\n return { success: false, finalName: branchName, error: errorMessage };\n }\n }\n\n return { success: false, finalName: branchName, error: `Failed to create branch after ${maxAttempts} attempts` };\n });\n\n if (!result.started) {\n return {\n success: false,\n finalName: branchName,\n error: \"Another process holds the repository lock; branch not created. Try again.\",\n };\n }\n return result.value;\n }\n\n public async getWorktreesForRepo(repoIndex: number): Promise<Array<{ path: string; branch: string }>> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n return this.getWorktreesFromService(service);\n }\n\n public async getWorktreeStatusForRepo(repoIndex: number): Promise<WorktreeStatusEntry[]> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n const gitService = service.getGitService();\n const worktrees = await this.getWorktreesFromService(service);\n\n const results = await Promise.allSettled(\n worktrees.map(async (wt) => {\n const status = await gitService.getFullWorktreeStatus(wt.path, true);\n return { branch: wt.branch, path: wt.path, status };\n }),\n );\n\n return results\n .filter((r): r is PromiseFulfilledResult<WorktreeStatusEntry> => r.status === \"fulfilled\")\n .map((r) => r.value);\n }\n\n private async getWorktreesFromService(service: WorktreeSyncService): Promise<Array<{ path: string; branch: string }>> {\n const worktreeProvider = service as WorktreeSyncService & {\n getWorktrees?: () => Promise<Array<{ path: string; branch: string }>>;\n };\n if (typeof worktreeProvider.getWorktrees === \"function\") {\n return worktreeProvider.getWorktrees();\n }\n return service.getGitService().getWorktrees();\n }\n\n public async getDivergedDirectoriesForRepo(repoIndex: number): Promise<DivergedDirectoryInfo[]> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n return [];\n }\n\n const service = this.syncServices[repoIndex];\n const worktreeDir = service.config.worktreeDir;\n const divergedDir = path.join(worktreeDir, GIT_CONSTANTS.DIVERGED_DIR_NAME);\n\n let dirEntries: import(\"fs\").Dirent[];\n try {\n dirEntries = await fs.readdir(divergedDir, { withFileTypes: true, encoding: \"utf-8\" });\n } catch {\n return [];\n }\n\n const subdirs = dirEntries.filter((e) => e.isDirectory());\n\n const results = await Promise.allSettled(\n subdirs.map(async (entry) => {\n const fullPath = path.join(divergedDir, entry.name);\n const infoFilePath = path.join(fullPath, METADATA_CONSTANTS.DIVERGED_INFO_FILE);\n\n let originalBranch = entry.name;\n let divergedAt = \"\";\n\n try {\n const infoContent = await fs.readFile(infoFilePath, \"utf-8\");\n const info = JSON.parse(infoContent);\n if (typeof info.originalBranch === \"string\") originalBranch = info.originalBranch;\n if (typeof info.divergedAt === \"string\") divergedAt = info.divergedAt;\n } catch {\n // Extract date and branch from directory name pattern: YYYY-MM-DD-branch-suffix\n const match = entry.name.match(/^(\\d{4}-\\d{2}-\\d{2})-(.+?)(?:-[a-f0-9]+)?$/);\n if (match) {\n divergedAt = match[1];\n originalBranch = match[2];\n }\n }\n\n const sizeBytes = await calculateDirectorySize(fullPath).catch(() => 0);\n const sizeFormatted = formatBytes(sizeBytes);\n\n return {\n name: entry.name,\n path: fullPath,\n originalBranch,\n divergedAt,\n sizeBytes,\n sizeFormatted,\n };\n }),\n );\n\n return results\n .filter((r): r is PromiseFulfilledResult<DivergedDirectoryInfo> => r.status === \"fulfilled\")\n .map((r) => r.value)\n .sort((a, b) => b.divergedAt.localeCompare(a.divergedAt));\n }\n\n public async deleteDivergedDirectory(repoIndex: number, name: string): Promise<void> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n const worktreeDir = service.config.worktreeDir;\n const divergedBase = path.resolve(worktreeDir, GIT_CONSTANTS.DIVERGED_DIR_NAME);\n\n if (!name || name === \".\" || name === \"..\" || name.includes(\"/\") || name.includes(\"\\\\\")) {\n throw new Error(`Invalid diverged directory name: \"${name}\"`);\n }\n\n const targetPath = path.join(divergedBase, name);\n\n if (!this.pathResolution.isPathInsideBaseDir(targetPath, divergedBase)) {\n throw new Error(`Path traversal rejected: \"${name}\" resolves outside the diverged directory`);\n }\n\n await fs.rm(targetPath, { recursive: true, force: true });\n this.addLog(`\uD83D\uDDD1\uFE0F Deleted diverged directory: ${name}`, \"info\");\n }\n\n public async createWorktreeForBranch(repoIndex: number, branchName: string): Promise<void> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n throw new Error(`Invalid repository index: ${repoIndex}`);\n }\n\n const service = this.syncServices[repoIndex];\n const gitService = service.getGitService();\n const worktreeDir = service.config.worktreeDir;\n const worktreePath = this.pathResolution.getBranchWorktreePath(worktreeDir, branchName);\n\n const result = await service.runQueuedRepoOperation(async () => {\n if (service.isCloneMode()) {\n // The wizard just created and pushed this branch \u2014 switching to it is\n // intentional config drift; checkoutBranch warns to update config.branch.\n await service.checkoutBranch(branchName, { allowConfigDrift: true });\n return;\n }\n await gitService.addWorktree(branchName, worktreePath);\n });\n if (!result.started) {\n throw new Error(\"Another process holds the repository lock; worktree not created. Try again.\");\n }\n }\n\n public openEditorInWorktree(worktreePath: string): { success: boolean; error?: string } {\n const editor = process.env.EDITOR || process.env.VISUAL || \"code\";\n\n try {\n const child = spawn(editor, [worktreePath], {\n detached: true,\n stdio: \"ignore\",\n });\n\n child.on(\"error\", (err) => {\n this.addLog(`Failed to open editor '${editor}': ${err.message}`, \"error\");\n this.addLog(\"Set EDITOR or VISUAL environment variable to your preferred editor\", \"warn\");\n });\n\n child.unref();\n\n // Return success optimistically - spawn errors are async and will be logged\n // to the UI when they occur. For detached processes, we can't reliably\n // catch spawn errors synchronously.\n return { success: true };\n } catch (err) {\n // This catches synchronous errors like ENOENT when the command doesn't exist\n const errorMessage = err instanceof Error ? err.message : String(err);\n this.addLog(`Failed to open editor '${editor}': ${errorMessage}`, \"error\");\n return { success: false, error: errorMessage };\n }\n }\n\n public openTerminalInWorktree(\n repoIndex: number,\n worktreePath: string,\n branchName: string,\n ): { success: boolean; error?: string } {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n const message = `Invalid repository index: ${repoIndex}`;\n this.addLog(message, \"error\");\n return { success: false, error: message };\n }\n const repoName = this.getRepoName(repoIndex);\n const sanitizedBranch = this.pathResolution.sanitizeBranchName(branchName);\n const sessionName = `${repoName}-${sanitizedBranch}`;\n const tmuxCommand = `tmux new-session -A -s ${shellEscape(sessionName)} -c ${shellEscape(worktreePath)}`;\n\n const launcher = this.resolveTerminalLauncher(tmuxCommand);\n if (!launcher) {\n const message =\n \"No terminal launcher found. Set SYNC_WORKTREES_TERMINAL or $TERMINAL to a terminal emulator command.\";\n this.addLog(message, \"error\");\n return { success: false, error: message };\n }\n\n try {\n const child = spawn(launcher.command, launcher.args, {\n detached: true,\n stdio: \"ignore\",\n });\n\n child.on(\"error\", (err) => {\n this.addLog(`Failed to open terminal '${launcher.command}': ${err.message}`, \"error\");\n this.addLog(\"Set SYNC_WORKTREES_TERMINAL to your preferred terminal command\", \"warn\");\n });\n\n child.unref();\n\n return { success: true };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n this.addLog(`Failed to open terminal '${launcher.command}': ${errorMessage}`, \"error\");\n return { success: false, error: errorMessage };\n }\n }\n\n private resolveTerminalLauncher(tmuxCommand: string): { command: string; args: string[] } | null {\n const override = this.parseCommandString(process.env[TERMINAL_CONSTANTS.ENV_OVERRIDE]);\n if (override) {\n // Wrap the tmux command in `sh -c` so terminal emulators that exec their trailing\n // arg as a program name (e.g. `alacritty -e`, `kitty -e`) can run the composite command.\n return { command: override.command, args: [...override.args, \"sh\", \"-c\", tmuxCommand] };\n }\n\n switch (process.platform) {\n case \"darwin\": {\n // Ghostty cannot be launched directly from the CLI on macOS; use `open -na` instead.\n const ghosttyPaths = [\"/Applications/Ghostty.app\", `${process.env.HOME}/Applications/Ghostty.app`];\n if (ghosttyPaths.some((p) => existsSync(p))) {\n return {\n command: \"open\",\n args: [\"-na\", \"Ghostty.app\", \"--args\", \"-e\", \"sh\", \"-c\", tmuxCommand],\n };\n }\n const escapedTmuxCommand = tmuxCommand.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n const script = `tell application \"Terminal\" to do script \"${escapedTmuxCommand}\"`;\n return { command: \"osascript\", args: [\"-e\", script] };\n }\n case \"linux\": {\n const envTerminal = this.parseCommandString(process.env[TERMINAL_CONSTANTS.ENV_FALLBACK]);\n if (envTerminal) {\n return { command: envTerminal.command, args: [...envTerminal.args, \"-e\", \"sh\", \"-c\", tmuxCommand] };\n }\n for (const candidate of TERMINAL_CONSTANTS.LINUX_CANDIDATES) {\n if (this.commandExists(candidate)) {\n if (candidate === \"gnome-terminal\") {\n return { command: candidate, args: [\"--\", \"sh\", \"-c\", tmuxCommand] };\n }\n return { command: candidate, args: [\"-e\", \"sh\", \"-c\", tmuxCommand] };\n }\n }\n return null;\n }\n default:\n return null;\n }\n }\n\n private parseCommandString(raw: string | undefined): { command: string; args: string[] } | null {\n if (!raw || raw.trim().length === 0) return null;\n const parts = raw.trim().split(/\\s+/);\n return { command: parts[0], args: parts.slice(1) };\n }\n\n private commandExists(command: string): boolean {\n try {\n const result = spawnSync(\"which\", [command], { stdio: \"ignore\" });\n return result.status === 0;\n } catch {\n return false;\n }\n }\n\n private async runSyncCycle(\n services: WorktreeSyncService[],\n options: { logErrors: boolean },\n ): Promise<Array<{ repo: string; error: string }>> {\n this.setStatus(\"syncing\");\n\n try {\n const { failures, skipped, partialSkips, clonePhaseSkips, attempted } = await this.runSyncServices(services);\n\n if (options.logErrors) {\n for (const failure of failures) {\n this.addLog(`Failed to sync repository '${failure.repo}': ${failure.error}`, \"error\");\n }\n }\n for (const skip of skipped) {\n this.addLog(`Sync skipped for '${skip.repo}': ${skip.reason}`, \"warn\");\n }\n for (const skip of clonePhaseSkips) {\n this.addLog(`Clone-mode skip for '${skip.repo}': ${skip.reason}`, \"warn\");\n }\n if (clonePhaseSkips.length > 0) {\n this.addLog(`\u26A0\uFE0F ${clonePhaseSkips.length} clone-mode skip(s) this cycle`, \"warn\");\n }\n for (const partial of partialSkips) {\n this.addLog(`${partial.repo}: ${partial.reason}`, \"info\");\n }\n\n await this.recordSyncOutcome({ failures, skipped, attempted });\n return failures;\n } finally {\n this.setStatus(\"idle\");\n }\n }\n\n private async recordSyncOutcome(outcome: {\n failures: Array<{ repo: string; error: string }>;\n skipped: Array<{ repo: string; reason: string }>;\n attempted: number;\n }): Promise<void> {\n const allSkipped =\n outcome.attempted > 0 &&\n outcome.skipped.length === outcome.attempted &&\n outcome.failures.length === 0;\n if (allSkipped) return;\n this.updateLastSyncTime();\n await this.calculateAndUpdateDiskSpace();\n }\n\n private async runSyncServices(services: WorktreeSyncService[]): Promise<{\n failures: Array<{ repo: string; error: string }>;\n skipped: Array<{ repo: string; reason: string }>;\n partialSkips: Array<{ repo: string; reason: string }>;\n clonePhaseSkips: Array<{ repo: string; reason: string }>;\n attempted: number;\n }> {\n const syncResults = await Promise.allSettled(\n services.map((service) => {\n const repoName = (service.config as RepositoryConfig).name || service.config.repoUrl;\n return this.limit(async () => {\n service.clearRecordedSkips();\n try {\n if (!service.isInitialized()) {\n await service.initialize();\n }\n const result = await service.sync();\n return { service, result };\n } finally {\n this.events.emit(\"setSyncProgress\", {\n repo: repoName,\n phase: \"complete\",\n message: \"Finished\",\n completed: true,\n });\n }\n }).catch((error) => {\n throw Object.assign(error instanceof Error ? error : new Error(String(error)), { repoName });\n });\n }),\n );\n\n const failures: Array<{ repo: string; error: string }> = [];\n const skipped: Array<{ repo: string; reason: string }> = [];\n const partialSkips: Array<{ repo: string; reason: string }> = [];\n const clonePhaseSkips: Array<{ repo: string; reason: string }> = [];\n for (let i = 0; i < syncResults.length; i++) {\n const result = syncResults[i];\n const repoName = (services[i].config as RepositoryConfig).name || services[i].config.repoUrl;\n if (result.status === \"rejected\") {\n const fallbackName = (result.reason as { repoName?: string })?.repoName ?? repoName;\n const errorMessage = result.reason instanceof Error ? result.reason.message : String(result.reason);\n failures.push({ repo: fallbackName, error: errorMessage });\n } else if (result.value.result && result.value.result.started === false) {\n skipped.push({ repo: repoName, reason: `sync skipped: ${result.value.result.reason}` });\n } else if (result.status === \"fulfilled\" && result.value.result?.started === true) {\n const outcome = result.value.result.outcome;\n if (outcome?.counts.failed) {\n failures.push({ repo: repoName, error: `${outcome.counts.failed} sync action(s) failed` });\n }\n // Per-action skips are informational; the repo did complete its sync\n // attempt. Surface as a separate channel so updateLastSyncTime still\n // runs and the per-cycle log stays at info-level.\n if (outcome?.mode === \"worktree\" && outcome.counts.skipped > 0) {\n partialSkips.push({ repo: repoName, reason: `${outcome.counts.skipped} sync action(s) skipped` });\n }\n }\n for (const reason of services[i].getRecordedSkips()) {\n clonePhaseSkips.push({ repo: repoName, reason: formatCloneSkipReason(reason) });\n }\n }\n\n return { failures, skipped, partialSkips, clonePhaseSkips, attempted: services.length };\n }\n\n private buildUiLogger(): Logger {\n return new Logger({\n outputFn: (msg: string, level: LogLevel): void => {\n const uiLevel: \"info\" | \"warn\" | \"error\" =\n level === \"warn\" ? \"warn\" : level === \"error\" ? \"error\" : \"info\";\n this.addLog(msg, uiLevel);\n },\n });\n }\n\n public executeOnBranchCreatedHooks(repoIndex: number, context: HookContext): void {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n return;\n }\n\n const service = this.syncServices[repoIndex];\n const config = service.config;\n const repoName = (config as RepositoryConfig).name || config.repoUrl;\n\n this.branchCreatedActions.runHooks({\n config,\n repoName,\n branchName: context.branchName,\n worktreePath: context.worktreePath,\n baseBranch: context.baseBranch,\n logger: this.buildUiLogger(),\n hookExecutionService: this.hookExecutionService,\n });\n }\n\n public async copyBranchFiles(repoIndex: number, baseBranch: string, targetBranch: string): Promise<void> {\n if (repoIndex < 0 || repoIndex >= this.syncServices.length) {\n return;\n }\n\n const service = this.syncServices[repoIndex];\n const config = service.config;\n\n if (!config.filesToCopyOnBranchCreate?.length) {\n return;\n }\n\n const worktrees = await this.getWorktreesFromService(service);\n\n const sourceWorktree = worktrees.find((w) => w.branch === baseBranch);\n const targetWorktree = worktrees.find((w) => w.branch === targetBranch);\n\n if (!sourceWorktree || !targetWorktree) {\n this.addLog(`Could not find worktrees for file copy: source=${baseBranch}, target=${targetBranch}`, \"warn\");\n return;\n }\n\n await this.branchCreatedActions.copyFiles({\n config,\n branchName: targetBranch,\n worktreePath: targetWorktree.path,\n sourceDir: sourceWorktree.path,\n logger: this.buildUiLogger(),\n });\n }\n\n public async destroy(fast = false): Promise<void> {\n this.isDestroyed = true;\n this.cancelCronJobs();\n\n try {\n await this.waitForInProgressSyncs(fast ? WAIT_SYNC_FAST_TIMEOUT_MS : WAIT_SYNC_DEFAULT_TIMEOUT_MS);\n } catch {\n // Best effort - proceed with teardown even if syncs don't finish\n }\n\n this.hookExecutionService.cleanup();\n if (this.app) {\n this.app.unmount();\n this.app = null;\n }\n for (const unsubscribe of this.unsubscribeCallbacks) {\n unsubscribe();\n }\n this.unsubscribeCallbacks = [];\n for (const unsubscribe of this.progressUnsubscribers) {\n unsubscribe();\n }\n this.progressUnsubscribers = [];\n if (this.ownsEvents) {\n this.events.removeAllListeners();\n }\n this.uiReady = false;\n this.logBuffer = [];\n }\n}\n", "import React, { useState, useEffect, useCallback, useRef } from \"react\";\nimport { Box, useInput, useWindowSize } from \"ink\";\nimport StatusBar from \"./StatusBar\";\nimport HelpModal from \"./HelpModal\";\nimport BranchCreationWizard from \"./BranchCreationWizard\";\nimport OpenEditorWizard from \"./OpenEditorWizard\";\nimport WorktreeStatusView from \"./WorktreeStatusView\";\nimport LogPanel from \"./LogPanel\";\nimport type { AppEventEmitter } from \"../utils/app-events\";\nimport type { AppSyncProgress } from \"../utils/app-events\";\nimport type {\n HookContext,\n WorktreeStatusEntry,\n DivergedDirectoryInfo,\n RepositoryListEntry,\n RepositoryDiskUsage,\n} from \"../types\";\n\nexport type { HookContext, WorktreeStatusEntry };\n\nexport interface AppProps {\n events: AppEventEmitter;\n repositoryCount: number;\n cronSchedule?: string;\n onManualSync: () => void;\n onReload: () => void;\n onQuit: () => Promise<void>;\n maxProgressLines?: number;\n getRepositoryList: () => RepositoryListEntry[];\n getRepositoryDiskUsage?: (index: number) => Promise<RepositoryDiskUsage>;\n getBranchesForRepo: (index: number) => Promise<string[]>;\n getDefaultBranchForRepo: (index: number) => string;\n fetchForRepo?: (index: number) => Promise<void>;\n createAndPushBranch: (\n repoIndex: number,\n baseBranch: string,\n branchName: string,\n ) => Promise<{ success: boolean; finalName: string; error?: string }>;\n getWorktreesForRepo: (index: number) => Promise<Array<{ path: string; branch: string }>>;\n openEditorInWorktree: (worktreePath: string) => { success: boolean; error?: string };\n openTerminalInWorktree: (\n repoIndex: number,\n worktreePath: string,\n branchName: string,\n ) => { success: boolean; error?: string };\n copyBranchFiles?: (repoIndex: number, baseBranch: string, targetBranch: string) => Promise<void>;\n createWorktreeForBranch: (repoIndex: number, branchName: string) => Promise<void>;\n executeOnBranchCreatedHooks?: (repoIndex: number, context: HookContext) => void;\n getWorktreeStatusForRepo?: (index: number) => Promise<WorktreeStatusEntry[]>;\n getDivergedDirectoriesForRepo?: (index: number) => Promise<DivergedDirectoryInfo[]>;\n deleteDivergedDirectory?: (repoIndex: number, name: string) => Promise<void>;\n}\n\nexport interface LogEntry {\n id: string;\n message: string;\n level: \"info\" | \"warn\" | \"error\";\n timestamp: Date;\n}\n\nconst MAX_LOG_ENTRIES = 5000;\n\nconst App: React.FC<AppProps> = ({\n events,\n repositoryCount,\n cronSchedule,\n onManualSync,\n onReload,\n onQuit,\n maxProgressLines = 2,\n getRepositoryList,\n getRepositoryDiskUsage,\n getBranchesForRepo,\n getDefaultBranchForRepo,\n fetchForRepo,\n createAndPushBranch,\n getWorktreesForRepo,\n openEditorInWorktree,\n openTerminalInWorktree,\n copyBranchFiles,\n createWorktreeForBranch,\n executeOnBranchCreatedHooks,\n getWorktreeStatusForRepo,\n getDivergedDirectoriesForRepo,\n deleteDivergedDirectory,\n}) => {\n const [showHelp, setShowHelp] = useState(false);\n const [showBranchWizard, setShowBranchWizard] = useState(false);\n const [showOpenEditorWizard, setShowOpenEditorWizard] = useState(false);\n const [showWorktreeStatus, setShowWorktreeStatus] = useState(false);\n const [status, setStatus] = useState<\"idle\" | \"syncing\">(\"idle\");\n // Interactive operations (branch/worktree creation) run independently of sync and\n // queue behind it. Tracked separately so they don't drive the sync `status` spinner.\n const [activeOps, setActiveOps] = useState<Array<{ id: number; label: string }>>([]);\n const opIdRef = useRef(0);\n const [syncProgressEntries, setSyncProgressEntries] = useState<AppSyncProgress[]>([]);\n const [lastSyncTime, setLastSyncTime] = useState<Date | null>(null);\n const [diskSpaceUsed, setDiskSpaceUsed] = useState<string | null>(null);\n const [logs, setLogs] = useState<LogEntry[]>([]);\n const [repoCount, setRepoCount] = useState(repositoryCount);\n const [schedule, setSchedule] = useState(cronSchedule);\n\n const { rows } = useWindowSize();\n\n const addLog = useCallback((message: string, level: LogEntry[\"level\"] = \"info\") => {\n setLogs((prev) => {\n const newLogs = [\n ...prev,\n {\n id: `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,\n message,\n level,\n timestamp: new Date(),\n },\n ];\n if (newLogs.length > MAX_LOG_ENTRIES) {\n return newLogs.slice(-MAX_LOG_ENTRIES);\n }\n return newLogs;\n });\n }, []);\n\n const addLogRef = useRef(addLog);\n addLogRef.current = addLog;\n\n useInput((input, key) => {\n if (showHelp) {\n if (input === \"?\" || input === \"h\" || key.escape) {\n setShowHelp(false);\n }\n return;\n }\n\n if (showBranchWizard || showOpenEditorWizard || showWorktreeStatus) {\n return;\n }\n\n if (input === \"q\") {\n onQuit().catch((err) => console.error(\"Quit failed:\", err));\n } else if (input === \"?\" || input === \"h\") {\n setShowHelp(true);\n } else if (input === \"c\") {\n setShowBranchWizard(true);\n } else if (input === \"o\") {\n setShowOpenEditorWizard(true);\n } else if (input === \"w\" && getWorktreeStatusForRepo) {\n setShowWorktreeStatus(true);\n } else if (input === \"s\" && status !== \"syncing\") {\n setStatus(\"syncing\");\n (async () => {\n try {\n await onManualSync();\n } catch (error) {\n console.error(\"Manual sync failed:\", error);\n setStatus(\"idle\");\n }\n })().catch((err) => console.error(\"Manual sync unhandled error:\", err));\n } else if (input === \"r\" && status !== \"syncing\") {\n setStatus(\"syncing\");\n (async () => {\n try {\n await onReload();\n } catch (error) {\n console.error(\"Reload failed:\", error);\n setStatus(\"idle\");\n }\n })().catch((err) => console.error(\"Reload unhandled error:\", err));\n }\n });\n\n const updateLastSyncTime = useCallback(() => {\n setLastSyncTime(new Date());\n setStatus(\"idle\");\n setSyncProgressEntries([]);\n }, []);\n\n useEffect(() => {\n const unsubscribers = [\n events.on(\"updateLastSyncTime\", () => {\n setLastSyncTime(new Date());\n setStatus(\"idle\");\n setSyncProgressEntries([]);\n }),\n events.on(\"setStatus\", (newStatus: \"idle\" | \"syncing\") => {\n setStatus(newStatus);\n if (newStatus === \"idle\") {\n setSyncProgressEntries([]);\n }\n }),\n events.on(\"setSyncProgress\", (progress: AppSyncProgress | null) => {\n if (progress === null) {\n setSyncProgressEntries([]);\n return;\n }\n setSyncProgressEntries((prev) => {\n if (progress.completed) {\n return prev.filter((entry) => entry.repo !== progress.repo);\n }\n\n const existingIndex = prev.findIndex((entry) => entry.repo === progress.repo);\n if (existingIndex === -1) {\n return [...prev, progress];\n }\n\n return prev.map((entry, index) => (index === existingIndex ? progress : entry));\n });\n }),\n events.on(\"setDiskSpace\", (diskSpace: string) => {\n setDiskSpaceUsed(diskSpace);\n }),\n events.on(\"addLog\", ({ message, level }: { message: string; level: \"info\" | \"warn\" | \"error\" }) => {\n addLogRef.current(message, level);\n }),\n events.on(\"updateRepositoryCount\", (count: number) => {\n setRepoCount(count);\n }),\n events.on(\"updateCronSchedule\", (newSchedule: string | undefined) => {\n setSchedule(newSchedule);\n }),\n ];\n\n events.emit(\"uiReady\");\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const progressLineCount = status === \"syncing\" ? Math.max(1, maxProgressLines) : 0;\n const statusBarHeight = 5 + progressLineCount + activeOps.length;\n const terminalRows = rows ?? 24;\n const logPanelHeight = Math.max(5, terminalRows - statusBarHeight);\n const showModal = showHelp || showBranchWizard || showOpenEditorWizard || showWorktreeStatus;\n\n return (\n <Box flexDirection=\"column\" minHeight={terminalRows}>\n {!showModal && <LogPanel logs={logs} height={logPanelHeight} isActive={!showModal} />}\n\n {showHelp && <HelpModal onClose={() => setShowHelp(false)} />}\n\n {showBranchWizard && (\n <BranchCreationWizard\n repositories={getRepositoryList()}\n getBranchesForRepo={getBranchesForRepo}\n getDefaultBranchForRepo={getDefaultBranchForRepo}\n fetchForRepo={fetchForRepo}\n createAndPushBranch={createAndPushBranch}\n onClose={() => setShowBranchWizard(false)}\n onBranchCreated={(context) => {\n const opId = ++opIdRef.current;\n setActiveOps((prev) => [...prev, { id: opId, label: `Creating worktree ${context.newBranch}` }]);\n (async () => {\n try {\n await createWorktreeForBranch(context.repoIndex, context.newBranch);\n if (copyBranchFiles) {\n await copyBranchFiles(context.repoIndex, context.baseBranch, context.newBranch);\n }\n\n if (executeOnBranchCreatedHooks) {\n const worktrees = await getWorktreesForRepo(context.repoIndex);\n const worktree = worktrees.find((w) => w.branch === context.newBranch);\n if (worktree) {\n const repos = getRepositoryList();\n const repo = repos.find((r) => r.index === context.repoIndex);\n executeOnBranchCreatedHooks(context.repoIndex, {\n branchName: context.newBranch,\n worktreePath: worktree.path,\n repoName: repo?.name || `repo-${context.repoIndex}`,\n baseBranch: context.baseBranch,\n repoUrl: repo?.repoUrl || \"\",\n });\n }\n }\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n events.emit(\"addLog\", {\n message: `Failed to create worktree: ${errorMsg}`,\n level: \"error\",\n });\n } finally {\n setActiveOps((prev) => prev.filter((op) => op.id !== opId));\n }\n })().catch((err) => console.error(\"Branch creation unhandled error:\", err));\n }}\n onComplete={() => {\n setShowBranchWizard(false);\n }}\n />\n )}\n\n {showOpenEditorWizard && (\n <OpenEditorWizard\n repositories={getRepositoryList()}\n getWorktreesForRepo={getWorktreesForRepo}\n openEditorInWorktree={openEditorInWorktree}\n openTerminalInWorktree={openTerminalInWorktree}\n onClose={() => setShowOpenEditorWizard(false)}\n />\n )}\n\n {showWorktreeStatus && getWorktreeStatusForRepo && (\n <WorktreeStatusView\n repositories={getRepositoryList()}\n getWorktreeStatusForRepo={getWorktreeStatusForRepo}\n getRepositoryDiskUsage={getRepositoryDiskUsage}\n getDivergedDirectoriesForRepo={getDivergedDirectoriesForRepo}\n deleteDivergedDirectory={deleteDivergedDirectory}\n onClose={() => setShowWorktreeStatus(false)}\n />\n )}\n\n <StatusBar\n status={status}\n syncProgressEntries={syncProgressEntries}\n activeOps={activeOps.map((op) => op.label)}\n maxProgressLines={maxProgressLines}\n repositoryCount={repoCount}\n lastSyncTime={lastSyncTime}\n cronSchedule={schedule}\n diskSpaceUsed={diskSpaceUsed ?? undefined}\n />\n </Box>\n );\n};\n\nexport default App;\n", "import React, { useState, useEffect } from \"react\";\nimport { Box, Text } from \"ink\";\nimport { CronExpressionParser } from \"cron-parser\";\n\nimport type { AppSyncProgress } from \"../utils/app-events\";\n\nexport interface StatusBarProps {\n status: \"idle\" | \"syncing\";\n syncProgressEntries?: AppSyncProgress[];\n activeOps?: string[];\n maxProgressLines?: number;\n repositoryCount: number;\n lastSyncTime: Date | null;\n cronSchedule?: string;\n diskSpaceUsed?: string;\n}\n\nconst StatusBar: React.FC<StatusBarProps> = ({\n status,\n syncProgressEntries = [],\n activeOps = [],\n maxProgressLines = 2,\n repositoryCount,\n lastSyncTime,\n cronSchedule,\n diskSpaceUsed,\n}) => {\n const [nextSyncTime, setNextSyncTime] = useState<Date | null>(null);\n\n useEffect(() => {\n if (!cronSchedule) {\n setNextSyncTime(null);\n return undefined;\n }\n\n try {\n const interval = CronExpressionParser.parse(cronSchedule);\n setNextSyncTime(interval.next().toDate());\n\n const timer = setInterval(() => {\n const fresh = CronExpressionParser.parse(cronSchedule);\n setNextSyncTime(fresh.next().toDate());\n }, 60000);\n\n return () => clearInterval(timer);\n } catch (error) {\n setNextSyncTime(null);\n return undefined;\n }\n }, [cronSchedule]);\n\n const formatTime = (date: Date | null): string => {\n if (!date) return \"N/A\";\n return date.toLocaleTimeString();\n };\n\n const getStatusColor = (): \"green\" | \"yellow\" => {\n return status === \"syncing\" ? \"yellow\" : \"green\";\n };\n\n const getStatusIcon = (): string => {\n return status === \"syncing\" ? \"\u27F3\" : \"\u2713\";\n };\n\n const formatProgress = (syncProgress: AppSyncProgress): string => `[${syncProgress.repo}] ${syncProgress.message}`;\n\n const progressLineCount = Math.max(1, maxProgressLines);\n const visibleProgress = syncProgressEntries.slice(-progressLineCount);\n\n return (\n <Box borderStyle=\"single\" paddingX={1}>\n <Box flexDirection=\"column\" width=\"100%\">\n <Box justifyContent=\"space-between\">\n <Text bold>\n {getStatusIcon()} Status:{\" \"}\n <Text color={getStatusColor()}>{status === \"syncing\" ? \"Syncing...\" : \"Running\"}</Text>\n </Text>\n <Text>\n Repositories: <Text bold color=\"cyan\">{repositoryCount}</Text>\n </Text>\n </Box>\n <Box justifyContent=\"space-between\">\n <Text>\n Last Sync: <Text color=\"gray\">{formatTime(lastSyncTime)}</Text>\n </Text>\n {cronSchedule && (\n <Text>\n Next Sync: <Text color=\"gray\">{formatTime(nextSyncTime)}</Text>\n </Text>\n )}\n </Box>\n {status === \"syncing\" &&\n Array.from({ length: progressLineCount }).map((_, index) => {\n const entry = visibleProgress[index];\n const message = entry ? formatProgress(entry) : index === 0 ? \"waiting for progress events\" : \"\";\n return (\n <Box key={index}>\n <Text wrap=\"truncate\">\n {message ? \"Progress: \" : \" \"}\n {message && <Text color=\"cyan\">{message}</Text>}\n </Text>\n </Box>\n );\n })}\n {activeOps.map((label, index) => (\n <Box key={`op-${index}`}>\n <Text wrap=\"truncate\">\n <Text color=\"yellow\">\u23F3 </Text>\n <Text color=\"yellow\">{label}</Text>\n </Text>\n </Box>\n ))}\n <Box justifyContent=\"space-between\">\n <Text>\n Disk Space: <Text color=\"magenta\">{diskSpaceUsed || \"Calculating...\"}</Text>\n </Text>\n <Text dimColor>\n <Text color=\"yellow\">s</Text>ync{\" \"}\n <Text color=\"yellow\">c</Text>reate{\" \"}\n <Text color=\"yellow\">o</Text>pen{\" \"}\n <Text color=\"yellow\">w</Text>tree{\" \"}\n <Text color=\"yellow\">r</Text>eload{\" \"}\n <Text color=\"yellow\">?</Text>help{\" \"}\n <Text color=\"yellow\">q</Text>uit\n </Text>\n </Box>\n </Box>\n </Box>\n );\n};\n\nexport default StatusBar;\n", "import React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nexport interface HelpModalProps {\n onClose: () => void;\n}\n\nconst HelpModal: React.FC<HelpModalProps> = ({ onClose }) => {\n useInput((input, key) => {\n if (input === \"?\" || input === \"h\" || key.escape) {\n onClose();\n }\n });\n return (\n <Box justifyContent=\"center\" alignItems=\"center\" flexDirection=\"column\" marginTop={2} marginBottom={2}>\n <Box borderStyle=\"double\" borderColor=\"cyan\" paddingX={2} paddingY={1} flexDirection=\"column\" width={60}>\n <Box justifyContent=\"center\" marginBottom={1}>\n <Text bold color=\"cyan\">\n \uD83C\uDF33 sync-worktrees - Keyboard Shortcuts\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" gap={0}>\n <Text bold color=\"green\" dimColor>\n Navigation\n </Text>\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n j\n </Text>\n <Text> / </Text>\n <Text bold color=\"yellow\">\n \u2193\n </Text>\n </Box>\n <Text>Scroll down one line</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n k\n </Text>\n <Text> / </Text>\n <Text bold color=\"yellow\">\n \u2191\n </Text>\n </Box>\n <Text>Scroll up one line</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n gg\n </Text>\n </Box>\n <Text>Jump to top</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n G\n </Text>\n </Box>\n <Text>Jump to bottom (re-enables auto-scroll)</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text bold color=\"green\" dimColor>\n Actions\n </Text>\n </Box>\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n s\n </Text>\n </Box>\n <Text>Manually trigger sync for all repositories</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n c\n </Text>\n </Box>\n <Text>Create a new branch</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n o\n </Text>\n </Box>\n <Text>Open worktree in terminal or editor</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n w\n </Text>\n </Box>\n <Text>View worktree status</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n r\n </Text>\n </Box>\n <Text>Reload configuration and re-sync all repos</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n ?\n </Text>\n <Text> / </Text>\n <Text bold color=\"yellow\">\n h\n </Text>\n </Box>\n <Text>Toggle this help screen</Text>\n </Box>\n\n <Box>\n <Box width={15}>\n <Text bold color=\"yellow\">\n q\n </Text>\n <Text> / </Text>\n <Text bold color=\"yellow\">\n Esc\n </Text>\n </Box>\n <Text>Gracefully quit</Text>\n </Box>\n </Box>\n\n <Box justifyContent=\"center\" marginTop={1}>\n <Text dimColor>Press ? / h / ESC to close</Text>\n </Box>\n </Box>\n </Box>\n );\n};\n\nexport default HelpModal;\n", "import React, { useState, useEffect, useCallback, useMemo, useRef } from \"react\";\nimport { Box, Text, useInput, usePaste } from \"ink\";\n\nimport { isValidGitBranchName } from \"../utils/git-validation\";\n\ntype WizardStep = \"SELECT_PROJECT\" | \"SELECT_BRANCH\" | \"ENTER_NAME\" | \"CREATING\" | \"RESULT\";\n\nexport interface BranchCreationWizardProps {\n repositories: Array<{ index: number; name: string; repoUrl: string }>;\n getBranchesForRepo: (index: number) => Promise<string[]>;\n getDefaultBranchForRepo: (index: number) => string;\n fetchForRepo?: (index: number) => Promise<void>;\n createAndPushBranch: (\n repoIndex: number,\n baseBranch: string,\n branchName: string,\n ) => Promise<{ success: boolean; finalName: string; error?: string }>;\n onClose: () => void;\n onComplete: (success: boolean) => void;\n onBranchCreated?: (context: {\n repoIndex: number;\n baseBranch: string;\n newBranch: string;\n }) => void;\n}\n\nconst BranchCreationWizard: React.FC<BranchCreationWizardProps> = ({\n repositories,\n getBranchesForRepo,\n getDefaultBranchForRepo,\n fetchForRepo,\n createAndPushBranch,\n onClose,\n onComplete,\n onBranchCreated,\n}) => {\n const [step, setStep] = useState<WizardStep>(repositories.length > 1 ? \"SELECT_PROJECT\" : \"SELECT_BRANCH\");\n const [selectedProjectIndex, setSelectedProjectIndex] = useState(0);\n const [selectedRepoIndex, setSelectedRepoIndex] = useState(\n repositories.length === 1 ? repositories[0].index : -1,\n );\n const [projectFilter, setProjectFilter] = useState(\"\");\n const [branches, setBranches] = useState<string[]>([]);\n const [defaultBranch, setDefaultBranch] = useState<string>(\"\");\n const [selectedBranchIndex, setSelectedBranchIndex] = useState(0);\n const [branchFilter, setBranchFilter] = useState(\"\");\n const [branchName, setBranchName] = useState(\"\");\n const [existingSuffix, setExistingSuffix] = useState<number | null>(null);\n const [validationError, setValidationError] = useState<string | null>(null);\n const [result, setResult] = useState<{ success: boolean; finalName: string; error?: string } | null>(null);\n const [loading, setLoading] = useState(false);\n\n const branchesLoadedRef = useRef(false);\n const [isFetching, setIsFetching] = useState(false);\n\n const filteredProjects = useMemo(() => {\n if (!projectFilter) return repositories;\n const lowerFilter = projectFilter.toLowerCase();\n return repositories.filter((repo) => repo.name.toLowerCase().includes(lowerFilter));\n }, [repositories, projectFilter]);\n\n const filteredBranches = useMemo(() => {\n if (!branchFilter) return branches;\n const lowerFilter = branchFilter.toLowerCase();\n return branches.filter((branch) => branch.toLowerCase().includes(lowerFilter));\n }, [branches, branchFilter]);\n\n useEffect(() => {\n if (filteredProjects.length > 0) {\n setSelectedProjectIndex((prev) => Math.max(0, Math.min(prev, filteredProjects.length - 1)));\n }\n }, [filteredProjects.length]);\n\n useEffect(() => {\n if (filteredBranches.length > 0) {\n setSelectedBranchIndex((prev) => Math.max(0, Math.min(prev, filteredBranches.length - 1)));\n }\n }, [filteredBranches.length]);\n\n const loadBranches = useCallback(\n async (repoIndex: number) => {\n setLoading(true);\n setIsFetching(false);\n try {\n let branchList = await getBranchesForRepo(repoIndex);\n\n // If no branches found and we haven't tried fetching yet, fetch and retry\n if (branchList.length === 0 && fetchForRepo) {\n setIsFetching(true);\n await fetchForRepo(repoIndex);\n branchList = await getBranchesForRepo(repoIndex);\n }\n\n const defaultBr = getDefaultBranchForRepo(repoIndex);\n setBranches(branchList);\n setDefaultBranch(defaultBr);\n const defaultIndex = branchList.indexOf(defaultBr);\n setSelectedBranchIndex(defaultIndex >= 0 ? defaultIndex : 0);\n } catch {\n setBranches([]);\n }\n setLoading(false);\n setIsFetching(false);\n },\n [getBranchesForRepo, getDefaultBranchForRepo, fetchForRepo],\n );\n\n const checkBranchExists = useCallback(\n (name: string) => {\n if (!name.trim()) {\n setExistingSuffix(null);\n setValidationError(null);\n return;\n }\n\n const validation = isValidGitBranchName(name);\n if (!validation.valid) {\n setValidationError(validation.error ?? null);\n setExistingSuffix(null);\n return;\n }\n\n setValidationError(null);\n\n let suffix = 0;\n let testName = name;\n\n while (branches.includes(testName)) {\n suffix++;\n testName = `${name}-${suffix}`;\n }\n\n setExistingSuffix(suffix > 0 ? suffix : null);\n },\n [branches],\n );\n\n useEffect(() => {\n if (step === \"SELECT_BRANCH\" && !branchesLoadedRef.current && !loading && selectedRepoIndex >= 0) {\n branchesLoadedRef.current = true;\n loadBranches(selectedRepoIndex);\n }\n }, [step, selectedRepoIndex, loading, loadBranches]);\n\n useEffect(() => {\n if (step === \"ENTER_NAME\") {\n checkBranchExists(branchName);\n }\n }, [branchName, step, checkBranchExists]);\n\n const handleCreateBranch = async () => {\n const trimmedName = branchName.trim();\n if (!trimmedName) return;\n\n const validation = isValidGitBranchName(trimmedName);\n if (!validation.valid) {\n setValidationError(validation.error ?? null);\n return;\n }\n\n setStep(\"CREATING\");\n const baseBranch = filteredBranches[selectedBranchIndex];\n try {\n const createResult = await createAndPushBranch(selectedRepoIndex, baseBranch, trimmedName);\n setResult(createResult);\n if (createResult.success && onBranchCreated) {\n onBranchCreated({\n repoIndex: selectedRepoIndex,\n baseBranch,\n newBranch: createResult.finalName,\n });\n }\n } catch (err) {\n setResult({\n success: false,\n finalName: trimmedName,\n error: err instanceof Error ? err.message : String(err),\n });\n } finally {\n setStep(\"RESULT\");\n }\n };\n\n useInput((input, key) => {\n if (step === \"CREATING\") return;\n\n if (key.escape) {\n if (step === \"SELECT_PROJECT\") {\n onClose();\n } else if (step === \"SELECT_BRANCH\") {\n if (repositories.length > 1) {\n setBranches([]);\n setBranchFilter(\"\");\n branchesLoadedRef.current = false;\n setIsFetching(false);\n setStep(\"SELECT_PROJECT\");\n } else {\n onClose();\n }\n } else if (step === \"ENTER_NAME\") {\n setBranchName(\"\");\n setExistingSuffix(null);\n setStep(\"SELECT_BRANCH\");\n } else if (step === \"RESULT\") {\n onComplete(result?.success ?? false);\n }\n return;\n }\n\n if (step === \"SELECT_PROJECT\") {\n if (key.upArrow) {\n setSelectedProjectIndex((prev) => Math.max(0, prev - 1));\n } else if (key.downArrow) {\n if (filteredProjects.length > 0) {\n setSelectedProjectIndex((prev) => Math.min(filteredProjects.length - 1, prev + 1));\n }\n } else if (key.return && filteredProjects.length > 0) {\n const selectedRepo = filteredProjects[selectedProjectIndex];\n if (selectedRepo) {\n setSelectedRepoIndex(selectedRepo.index);\n branchesLoadedRef.current = true;\n setIsFetching(false);\n loadBranches(selectedRepo.index);\n setStep(\"SELECT_BRANCH\");\n }\n } else if (key.backspace || key.delete) {\n setProjectFilter((prev) => prev.slice(0, -1));\n setSelectedProjectIndex(0);\n } else if (input && !key.ctrl && !key.meta) {\n setProjectFilter((prev) => prev + input);\n setSelectedProjectIndex(0);\n }\n } else if (step === \"SELECT_BRANCH\") {\n if (key.upArrow) {\n setSelectedBranchIndex((prev) => Math.max(0, prev - 1));\n } else if (key.downArrow) {\n if (filteredBranches.length > 0) {\n setSelectedBranchIndex((prev) => Math.min(filteredBranches.length - 1, prev + 1));\n }\n } else if (key.return && filteredBranches.length > 0) {\n setStep(\"ENTER_NAME\");\n } else if (key.backspace || key.delete) {\n setBranchFilter((prev) => prev.slice(0, -1));\n setSelectedBranchIndex(0);\n } else if (input && !key.ctrl && !key.meta) {\n setBranchFilter((prev) => prev + input);\n setSelectedBranchIndex(0);\n }\n } else if (step === \"ENTER_NAME\") {\n if (key.return && branchName.trim()) {\n handleCreateBranch().catch((err) => console.error(\"Branch creation failed:\", err));\n } else if (key.backspace || key.delete) {\n setBranchName((prev) => prev.slice(0, -1));\n } else if (input && !key.ctrl && !key.meta) {\n const validChar = /^[a-zA-Z0-9/._-]$/.test(input);\n if (validChar) {\n setBranchName((prev) => prev + input);\n }\n }\n } else if (step === \"RESULT\") {\n onComplete(result?.success ?? false);\n }\n });\n\n usePaste((text) => {\n if (step === \"SELECT_PROJECT\") {\n setProjectFilter((prev) => prev + text);\n setSelectedProjectIndex(0);\n } else if (step === \"SELECT_BRANCH\") {\n setBranchFilter((prev) => prev + text);\n setSelectedBranchIndex(0);\n } else if (step === \"ENTER_NAME\") {\n setBranchName((prev) => prev + text.replace(/[^a-zA-Z0-9/._-]/g, \"\"));\n }\n });\n\n const getStepNumber = () => {\n if (repositories.length === 1) {\n if (step === \"SELECT_BRANCH\") return 1;\n if (step === \"ENTER_NAME\") return 2;\n return 2;\n }\n if (step === \"SELECT_PROJECT\") return 1;\n if (step === \"SELECT_BRANCH\") return 2;\n if (step === \"ENTER_NAME\") return 3;\n return 3;\n };\n\n const getTotalSteps = () => (repositories.length === 1 ? 2 : 3);\n\n const renderProjectSelection = () => {\n const visibleCount = 8;\n const halfVisible = Math.floor(visibleCount / 2);\n let startIdx = Math.max(0, selectedProjectIndex - halfVisible);\n const endIdx = Math.min(filteredProjects.length, startIdx + visibleCount);\n if (endIdx - startIdx < visibleCount) {\n startIdx = Math.max(0, endIdx - visibleCount);\n }\n\n const visibleProjects = filteredProjects.slice(startIdx, endIdx);\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text>Select repository:</Text>\n <Box>\n <Text>Filter: </Text>\n <Text color=\"cyan\">{projectFilter || \"_\"}</Text>\n <Text dimColor>\n {\" \"}\n ({filteredProjects.length}/{repositories.length} matches)\n </Text>\n </Box>\n <Box flexDirection=\"column\">\n {filteredProjects.length === 0 ? (\n <Text color=\"yellow\">No matches</Text>\n ) : (\n <>\n {startIdx > 0 && <Text dimColor> ...</Text>}\n {visibleProjects.map((repo, idx) => {\n const actualIdx = startIdx + idx;\n const isSelected = actualIdx === selectedProjectIndex;\n return (\n <Box key={repo.index}>\n <Text color={isSelected ? \"cyan\" : undefined}>\n {isSelected ? \"> \" : \" \"}\n {repo.name}\n </Text>\n </Box>\n );\n })}\n {endIdx < filteredProjects.length && <Text dimColor> ...</Text>}\n </>\n )}\n </Box>\n </Box>\n );\n };\n\n const renderBranchSelection = () => {\n if (loading) {\n return <Text color=\"yellow\">Loading branches{isFetching ? \" (fetching from remote...)\" : \"...\"}</Text>;\n }\n\n if (branches.length === 0) {\n return <Text color=\"red\">No branches found</Text>;\n }\n\n const visibleCount = 8;\n const halfVisible = Math.floor(visibleCount / 2);\n let startIdx = Math.max(0, selectedBranchIndex - halfVisible);\n const endIdx = Math.min(filteredBranches.length, startIdx + visibleCount);\n if (endIdx - startIdx < visibleCount) {\n startIdx = Math.max(0, endIdx - visibleCount);\n }\n\n const visibleBranches = filteredBranches.slice(startIdx, endIdx);\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text>Select base branch:</Text>\n <Box>\n <Text>Filter: </Text>\n <Text color=\"cyan\">{branchFilter || \"_\"}</Text>\n <Text dimColor>\n {\" \"}\n ({filteredBranches.length}/{branches.length} matches)\n </Text>\n </Box>\n <Box flexDirection=\"column\">\n {filteredBranches.length === 0 ? (\n <Text color=\"yellow\">No matches</Text>\n ) : (\n <>\n {startIdx > 0 && <Text dimColor> ...</Text>}\n {visibleBranches.map((branch, idx) => {\n const actualIdx = startIdx + idx;\n const isSelected = actualIdx === selectedBranchIndex;\n const isDefault = branch === defaultBranch;\n return (\n <Box key={branch}>\n <Text color={isSelected ? \"cyan\" : undefined}>\n {isSelected ? \"> \" : \" \"}\n {branch}\n {isDefault && <Text color=\"green\"> (default)</Text>}\n </Text>\n </Box>\n );\n })}\n {endIdx < filteredBranches.length && <Text dimColor> ...</Text>}\n </>\n )}\n </Box>\n </Box>\n );\n };\n\n const renderNameInput = () => {\n const baseBranch = filteredBranches[selectedBranchIndex] || \"\";\n const finalName = existingSuffix !== null ? `${branchName}-${existingSuffix}` : branchName;\n const endsWithSlash = branchName.endsWith(\"/\");\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text>\n Base branch: <Text color=\"cyan\">{baseBranch}</Text>\n </Text>\n <Text>Enter new branch name:</Text>\n <Box>\n <Text color=\"cyan\">{\"> \"}</Text>\n <Text>{branchName}</Text>\n <Text color=\"gray\">|</Text>\n </Box>\n {validationError && (\n <Text color=\"red\">{validationError}</Text>\n )}\n {!validationError && endsWithSlash && (\n <Text color=\"yellow\" dimColor>\n Hint: consecutive slashes (//) are not allowed\n </Text>\n )}\n {!validationError && !endsWithSlash && existingSuffix !== null && branchName && (\n <Text color=\"yellow\">\n Name exists, will create: <Text color=\"cyan\">{finalName}</Text>\n </Text>\n )}\n </Box>\n );\n };\n\n const renderCreating = () => (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"yellow\">Creating branch...</Text>\n <Text dimColor>Please wait while the branch is created and pushed to remote.</Text>\n </Box>\n );\n\n const renderResult = () => {\n if (!result) return null;\n\n if (result.success) {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"green\">Branch created successfully!</Text>\n <Text>\n Created: <Text color=\"cyan\">{result.finalName}</Text>\n </Text>\n <Text>\n From: <Text color=\"cyan\">{filteredBranches[selectedBranchIndex]}</Text>\n </Text>\n <Text color=\"green\">Worktree sync started in background</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"red\">Failed to create branch</Text>\n <Text color=\"red\">{result.error}</Text>\n </Box>\n );\n };\n\n const renderContent = () => {\n switch (step) {\n case \"SELECT_PROJECT\":\n return renderProjectSelection();\n case \"SELECT_BRANCH\":\n return renderBranchSelection();\n case \"ENTER_NAME\":\n return renderNameInput();\n case \"CREATING\":\n return renderCreating();\n case \"RESULT\":\n return renderResult();\n }\n };\n\n const renderFooter = () => {\n if (step === \"CREATING\") return null;\n if (step === \"RESULT\") {\n return <Text dimColor>Press any key to close</Text>;\n }\n if (step === \"ENTER_NAME\") {\n return <Text dimColor>Enter to create \u2022 ESC to go back</Text>;\n }\n return <Text dimColor>\u2191/\u2193 navigate \u2022 Type to filter \u2022 Enter to select \u2022 ESC to cancel</Text>;\n };\n\n return (\n <Box flexDirection=\"column\" marginTop={1} marginBottom={1}>\n <Box borderStyle=\"round\" borderColor=\"green\" paddingX={2} paddingY={1} flexDirection=\"column\" width={60}>\n <Box marginBottom={1}>\n <Text bold color=\"green\">\n \uD83C\uDF3F Create New Branch{\" \"}\n {step !== \"CREATING\" && step !== \"RESULT\" && (\n <Text dimColor>\n (Step {getStepNumber()}/{getTotalSteps()})\n </Text>\n )}\n </Text>\n </Box>\n\n {repositories.length > 1 && step !== \"SELECT_PROJECT\" && step !== \"CREATING\" && step !== \"RESULT\" && (\n <Box marginBottom={1}>\n <Text>\n Repository: <Text color=\"cyan\">{repositories.find((r) => r.index === selectedRepoIndex)?.name}</Text>\n </Text>\n </Box>\n )}\n\n {renderContent()}\n\n <Box marginTop={1}>{renderFooter()}</Box>\n </Box>\n </Box>\n );\n};\n\nexport default BranchCreationWizard;\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 React, { useState, useEffect, useMemo, useCallback, useRef } from \"react\";\nimport { Box, Text, useInput, usePaste } from \"ink\";\n\ntype WizardStep = \"SELECT_PROJECT\" | \"SELECT_WORKTREE\" | \"OPENING\" | \"ERROR\";\n\nexport type OpenAction = \"terminal\" | \"editor\";\n\nexport interface OpenEditorWizardProps {\n repositories: Array<{ index: number; name: string; repoUrl: string }>;\n getWorktreesForRepo: (index: number) => Promise<Array<{ path: string; branch: string }>>;\n openEditorInWorktree: (worktreePath: string) => { success: boolean; error?: string };\n openTerminalInWorktree: (\n repoIndex: number,\n worktreePath: string,\n branchName: string,\n ) => { success: boolean; error?: string };\n onClose: () => void;\n}\n\nconst OpenEditorWizard: React.FC<OpenEditorWizardProps> = ({\n repositories,\n getWorktreesForRepo,\n openEditorInWorktree,\n openTerminalInWorktree,\n onClose,\n}) => {\n const [step, setStep] = useState<WizardStep>(repositories.length > 1 ? \"SELECT_PROJECT\" : \"SELECT_WORKTREE\");\n const [selectedProjectIndex, setSelectedProjectIndex] = useState(0);\n const [projectFilter, setProjectFilter] = useState(\"\");\n const selectedRepoIndexRef = useRef<number>(repositories.length === 1 ? 0 : -1);\n\n const [worktrees, setWorktrees] = useState<Array<{ path: string; branch: string }>>([]);\n const [selectedWorktreeIndex, setSelectedWorktreeIndex] = useState(0);\n const [worktreeFilter, setWorktreeFilter] = useState(\"\");\n const [loading, setLoading] = useState(false);\n const [openAction, setOpenAction] = useState<OpenAction>(\"terminal\");\n\n const [error, setError] = useState<string | null>(null);\n\n const filteredProjects = useMemo(() => {\n if (!projectFilter) return repositories;\n const lowerFilter = projectFilter.toLowerCase();\n return repositories.filter((repo) => repo.name.toLowerCase().includes(lowerFilter));\n }, [repositories, projectFilter]);\n\n const filteredWorktrees = useMemo(() => {\n if (!worktreeFilter) return worktrees;\n const lowerFilter = worktreeFilter.toLowerCase();\n return worktrees.filter((wt) => wt.branch.toLowerCase().includes(lowerFilter));\n }, [worktrees, worktreeFilter]);\n\n const loadWorktrees = useCallback(\n async (repoIndex: number) => {\n setLoading(true);\n try {\n const wts = await getWorktreesForRepo(repoIndex);\n setWorktrees(wts);\n setSelectedWorktreeIndex(0);\n } catch (err) {\n setError(`Failed to load worktrees: ${err}`);\n setStep(\"ERROR\");\n }\n setLoading(false);\n },\n [getWorktreesForRepo],\n );\n\n useEffect(() => {\n if (step === \"SELECT_WORKTREE\" && worktrees.length === 0 && !loading && selectedRepoIndexRef.current >= 0) {\n loadWorktrees(selectedRepoIndexRef.current);\n }\n }, [step, worktrees.length, loading, loadWorktrees]);\n\n const handleOpen = () => {\n const worktree = filteredWorktrees[selectedWorktreeIndex];\n if (!worktree) return;\n\n setStep(\"OPENING\");\n const result =\n openAction === \"terminal\"\n ? openTerminalInWorktree(selectedRepoIndexRef.current, worktree.path, worktree.branch)\n : openEditorInWorktree(worktree.path);\n if (result.success) {\n onClose();\n } else {\n setError(result.error || (openAction === \"terminal\" ? \"Failed to open terminal\" : \"Failed to open editor\"));\n setStep(\"ERROR\");\n }\n };\n\n useInput((input, key) => {\n if (step === \"OPENING\") return;\n\n if (key.escape) {\n if (step === \"SELECT_PROJECT\") {\n onClose();\n } else if (step === \"SELECT_WORKTREE\") {\n if (repositories.length > 1) {\n setWorktrees([]);\n setWorktreeFilter(\"\");\n selectedRepoIndexRef.current = -1;\n setStep(\"SELECT_PROJECT\");\n } else {\n onClose();\n }\n } else if (step === \"ERROR\") {\n onClose();\n }\n return;\n }\n\n if (step === \"SELECT_PROJECT\") {\n if (key.upArrow) {\n setSelectedProjectIndex((prev) => Math.max(0, prev - 1));\n } else if (key.downArrow) {\n setSelectedProjectIndex((prev) => Math.min(filteredProjects.length - 1, prev + 1));\n } else if (key.return && filteredProjects.length > 0) {\n const selectedRepo = filteredProjects[selectedProjectIndex];\n if (selectedRepo) {\n selectedRepoIndexRef.current = selectedRepo.index;\n setStep(\"SELECT_WORKTREE\");\n loadWorktrees(selectedRepo.index);\n }\n } else if (key.backspace || key.delete) {\n setProjectFilter((prev) => prev.slice(0, -1));\n setSelectedProjectIndex(0);\n } else if (input && !key.ctrl && !key.meta) {\n setProjectFilter((prev) => prev + input);\n setSelectedProjectIndex(0);\n }\n } else if (step === \"SELECT_WORKTREE\") {\n if (key.tab) {\n setOpenAction((prev) => (prev === \"terminal\" ? \"editor\" : \"terminal\"));\n } else if (key.upArrow) {\n setSelectedWorktreeIndex((prev) => Math.max(0, prev - 1));\n } else if (key.downArrow) {\n setSelectedWorktreeIndex((prev) => Math.min(filteredWorktrees.length - 1, prev + 1));\n } else if (key.return && filteredWorktrees.length > 0) {\n handleOpen();\n } else if (key.backspace || key.delete) {\n setWorktreeFilter((prev) => prev.slice(0, -1));\n setSelectedWorktreeIndex(0);\n } else if (input && !key.ctrl && !key.meta) {\n setWorktreeFilter((prev) => prev + input);\n setSelectedWorktreeIndex(0);\n }\n } else if (step === \"ERROR\") {\n onClose();\n }\n });\n\n usePaste((text) => {\n if (step === \"SELECT_PROJECT\") {\n setProjectFilter((prev) => prev + text);\n setSelectedProjectIndex(0);\n } else if (step === \"SELECT_WORKTREE\") {\n setWorktreeFilter((prev) => prev + text);\n setSelectedWorktreeIndex(0);\n }\n });\n\n const getStepNumber = () => {\n if (repositories.length === 1) {\n return 1;\n }\n return step === \"SELECT_PROJECT\" ? 1 : 2;\n };\n\n const getTotalSteps = () => (repositories.length === 1 ? 1 : 2);\n\n const renderProjectSelection = () => {\n const visibleCount = 8;\n const halfVisible = Math.floor(visibleCount / 2);\n let startIdx = Math.max(0, selectedProjectIndex - halfVisible);\n const endIdx = Math.min(filteredProjects.length, startIdx + visibleCount);\n if (endIdx - startIdx < visibleCount) {\n startIdx = Math.max(0, endIdx - visibleCount);\n }\n\n const visibleProjects = filteredProjects.slice(startIdx, endIdx);\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text>Select repository:</Text>\n <Box>\n <Text>Filter: </Text>\n <Text color=\"cyan\">{projectFilter || \"_\"}</Text>\n <Text dimColor>\n {\" \"}\n ({filteredProjects.length}/{repositories.length} matches)\n </Text>\n </Box>\n <Box flexDirection=\"column\">\n {filteredProjects.length === 0 ? (\n <Text color=\"yellow\">No matches</Text>\n ) : (\n <>\n {startIdx > 0 && <Text dimColor> ...</Text>}\n {visibleProjects.map((repo, idx) => {\n const actualIdx = startIdx + idx;\n const isSelected = actualIdx === selectedProjectIndex;\n return (\n <Box key={repo.index}>\n <Text color={isSelected ? \"cyan\" : undefined}>\n {isSelected ? \"> \" : \" \"}\n {repo.name}\n </Text>\n </Box>\n );\n })}\n {endIdx < filteredProjects.length && <Text dimColor> ...</Text>}\n </>\n )}\n </Box>\n </Box>\n );\n };\n\n const renderWorktreeSelection = () => {\n if (loading) {\n return <Text color=\"yellow\">Loading worktrees...</Text>;\n }\n\n if (worktrees.length === 0) {\n return <Text color=\"red\">No worktrees found</Text>;\n }\n\n const visibleCount = 8;\n const halfVisible = Math.floor(visibleCount / 2);\n let startIdx = Math.max(0, selectedWorktreeIndex - halfVisible);\n const endIdx = Math.min(filteredWorktrees.length, startIdx + visibleCount);\n if (endIdx - startIdx < visibleCount) {\n startIdx = Math.max(0, endIdx - visibleCount);\n }\n\n const visibleWorktrees = filteredWorktrees.slice(startIdx, endIdx);\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text>Mode: </Text>\n <Text color=\"cyan\" bold>\n {openAction === \"terminal\" ? \"Terminal (tmux)\" : \"Editor\"}\n </Text>\n <Text dimColor> (Tab to switch to {openAction === \"terminal\" ? \"Editor\" : \"Terminal\"})</Text>\n </Box>\n <Text>Select worktree:</Text>\n <Box>\n <Text>Filter: </Text>\n <Text color=\"cyan\">{worktreeFilter || \"_\"}</Text>\n <Text dimColor>\n {\" \"}\n ({filteredWorktrees.length}/{worktrees.length} matches)\n </Text>\n </Box>\n <Box flexDirection=\"column\">\n {filteredWorktrees.length === 0 ? (\n <Text color=\"yellow\">No matches</Text>\n ) : (\n <>\n {startIdx > 0 && <Text dimColor> ...</Text>}\n {visibleWorktrees.map((wt, idx) => {\n const actualIdx = startIdx + idx;\n const isSelected = actualIdx === selectedWorktreeIndex;\n return (\n <Box key={wt.path}>\n <Text color={isSelected ? \"cyan\" : undefined}>\n {isSelected ? \"> \" : \" \"}\n {wt.branch}\n </Text>\n </Box>\n );\n })}\n {endIdx < filteredWorktrees.length && <Text dimColor> ...</Text>}\n </>\n )}\n </Box>\n </Box>\n );\n };\n\n const renderOpening = () => (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"yellow\">{openAction === \"terminal\" ? \"Opening terminal...\" : \"Opening editor...\"}</Text>\n </Box>\n );\n\n const renderError = () => (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"red\">Error: {error}</Text>\n <Text dimColor>Press any key to close</Text>\n </Box>\n );\n\n const renderContent = () => {\n switch (step) {\n case \"SELECT_PROJECT\":\n return renderProjectSelection();\n case \"SELECT_WORKTREE\":\n return renderWorktreeSelection();\n case \"OPENING\":\n return renderOpening();\n case \"ERROR\":\n return renderError();\n }\n };\n\n const renderFooter = () => {\n if (step === \"OPENING\") return null;\n if (step === \"ERROR\") return null;\n if (step === \"SELECT_WORKTREE\") {\n return (\n <Text dimColor>\u2191/\u2193 navigate \u2022 Type to filter \u2022 Tab switch mode \u2022 Enter to select \u2022 ESC to cancel</Text>\n );\n }\n return <Text dimColor>\u2191/\u2193 navigate \u2022 Type to filter \u2022 Enter to select \u2022 ESC to cancel</Text>;\n };\n\n return (\n <Box flexDirection=\"column\" marginTop={1} marginBottom={1}>\n <Box borderStyle=\"round\" borderColor=\"blue\" paddingX={2} paddingY={1} flexDirection=\"column\" width={60}>\n <Box marginBottom={1}>\n <Text bold color=\"blue\">\n \uD83D\uDCC2 Open Worktree{\" \"}\n {step !== \"OPENING\" && step !== \"ERROR\" && (\n <Text dimColor>\n (Step {getStepNumber()}/{getTotalSteps()})\n </Text>\n )}\n </Text>\n </Box>\n\n {repositories.length > 1 && step === \"SELECT_WORKTREE\" && !loading && selectedRepoIndexRef.current >= 0 && (\n <Box marginBottom={1}>\n <Text>\n Repository: <Text color=\"cyan\">{repositories.find((r) => r.index === selectedRepoIndexRef.current)?.name}</Text>\n </Text>\n </Box>\n )}\n\n {renderContent()}\n\n <Box marginTop={1}>{renderFooter()}</Box>\n </Box>\n </Box>\n );\n};\n\nexport default OpenEditorWizard;\n", "import React, { useState, useEffect, useMemo, useCallback, useRef } from \"react\";\nimport { Box, Text, useInput, usePaste } from \"ink\";\n\nimport type { WorktreeStatusResult } from \"../services/worktree-status.service\";\nimport type {\n WorktreeStatusEntry,\n DivergedDirectoryInfo,\n RepositoryListEntry,\n RepositoryDiskUsage,\n} from \"../types\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\n\nexport type { WorktreeStatusEntry };\n\ntype ViewStep = \"SELECT_PROJECT\" | \"VIEW_STATUS\" | \"ERROR\";\n\nexport interface WorktreeStatusViewProps {\n repositories: RepositoryListEntry[];\n getWorktreeStatusForRepo: (index: number) => Promise<WorktreeStatusEntry[]>;\n getRepositoryDiskUsage?: (index: number) => Promise<RepositoryDiskUsage>;\n getDivergedDirectoriesForRepo?: (index: number) => Promise<DivergedDirectoryInfo[]>;\n deleteDivergedDirectory?: (repoIndex: number, name: string) => Promise<void>;\n onClose: () => void;\n}\n\ntype RepositoryDiskUsageState =\n | { status: \"loading\" }\n | { status: \"ready\"; usage: RepositoryDiskUsage }\n | { status: \"error\" };\n\ntype ListItem =\n | { type: \"worktree\"; entry: WorktreeStatusEntry }\n | { type: \"separator\" }\n | { type: \"diverged\"; entry: DivergedDirectoryInfo };\n\nconst getStatusFlags = (status: WorktreeStatusResult): React.ReactNode => {\n const flags: React.ReactNode[] = [];\n\n if (\n status.isClean &&\n !status.hasUnpushedCommits &&\n !status.hasStashedChanges &&\n !status.hasOperationInProgress &&\n !status.hasModifiedSubmodules &&\n !status.upstreamGone\n ) {\n return <Text color=\"green\">\u2713</Text>;\n }\n\n if (!status.isClean) {\n flags.push(\n <Text key=\"modified\" color=\"yellow\">\n M\n </Text>,\n );\n }\n if (status.hasUnpushedCommits) {\n flags.push(\n status.fullyPushedUpstreamDeleted ? (\n <Text key=\"unpushed\" color=\"green\">\n \u21E1\n </Text>\n ) : (\n <Text key=\"unpushed\" color=\"cyan\">\n \u2191\n </Text>\n ),\n );\n }\n if (status.hasStashedChanges) {\n flags.push(\n <Text key=\"stash\" color=\"magenta\">\n S\n </Text>,\n );\n }\n if (status.hasOperationInProgress) {\n flags.push(\n <Text key=\"operation\" color=\"red\">\n \u26A0\n </Text>,\n );\n }\n if (status.hasModifiedSubmodules) {\n flags.push(\n <Text key=\"submodules\" color=\"yellow\">\n \u229E\n </Text>,\n );\n }\n if (status.upstreamGone) {\n flags.push(\n <Text key=\"upstream\" color=\"red\" dimColor>\n \u2717\n </Text>,\n );\n }\n\n return <>{flags}</>;\n};\n\nconst getStatusSummary = (status: WorktreeStatusResult): string => {\n const parts: string[] = [];\n const details = status.details;\n\n if (!status.isClean && details) {\n const fileCount =\n details.modifiedFiles + details.deletedFiles + details.renamedFiles + details.createdFiles + details.conflictedFiles + details.untrackedFiles;\n if (fileCount > 0) parts.push(`${fileCount} changed`);\n }\n if (status.hasUnpushedCommits && details?.unpushedCommitCount) {\n parts.push(\n status.fullyPushedUpstreamDeleted\n ? \"pushed, remote branch deleted\"\n : `${details.unpushedCommitCount} unpushed`,\n );\n }\n if (status.hasStashedChanges && details?.stashCount) {\n parts.push(`${details.stashCount} stash`);\n }\n if (status.hasOperationInProgress && details?.operationType) {\n parts.push(`${details.operationType} in progress`);\n }\n if (status.upstreamGone) {\n parts.push(\"upstream gone\");\n }\n\n return parts.length > 0 ? `(${parts.join(\", \")})` : \"\";\n};\n\nconst formatDivergedDate = (dateStr: string): string => {\n if (!dateStr) return \"unknown date\";\n if (dateStr.length === 10) return dateStr;\n try {\n return new Date(dateStr).toLocaleDateString(\"en-CA\");\n } catch {\n return dateStr;\n }\n};\n\nconst WorktreeStatusView: React.FC<WorktreeStatusViewProps> = ({\n repositories,\n getWorktreeStatusForRepo,\n getRepositoryDiskUsage,\n getDivergedDirectoriesForRepo,\n deleteDivergedDirectory,\n onClose,\n}) => {\n const [step, setStep] = useState<ViewStep>(repositories.length > 1 ? \"SELECT_PROJECT\" : \"VIEW_STATUS\");\n const [selectedProjectIndex, setSelectedProjectIndex] = useState(0);\n const [projectFilter, setProjectFilter] = useState(\"\");\n const selectedRepoIndexRef = useRef<number>(repositories.length === 1 ? 0 : -1);\n\n const [entries, setEntries] = useState<WorktreeStatusEntry[]>([]);\n const [divergedEntries, setDivergedEntries] = useState<DivergedDirectoryInfo[]>([]);\n const [selectedEntryIndex, setSelectedEntryIndex] = useState(0);\n const [entryFilter, setEntryFilter] = useState(\"\");\n const [expandedEntry, setExpandedEntry] = useState<number | null>(null);\n const [loading, setLoading] = useState(false);\n const [repoDiskUsage, setRepoDiskUsage] = useState<Record<number, RepositoryDiskUsageState>>({});\n const requestedDiskUsageRef = useRef<Set<number>>(new Set());\n\n const [confirmDelete, setConfirmDelete] = useState<number | null>(null);\n const [deleting, setDeleting] = useState(false);\n\n const [error, setError] = useState<string | null>(null);\n\n const filteredProjects = useMemo(() => {\n if (!projectFilter) return repositories;\n const lowerFilter = projectFilter.toLowerCase();\n return repositories.filter((repo) => repo.name.toLowerCase().includes(lowerFilter));\n }, [repositories, projectFilter]);\n\n const filteredEntries = useMemo(() => {\n if (!entryFilter) return entries;\n const lowerFilter = entryFilter.toLowerCase();\n return entries.filter((entry) => entry.branch.toLowerCase().includes(lowerFilter));\n }, [entries, entryFilter]);\n\n const filteredDiverged = useMemo(() => {\n if (!entryFilter) return divergedEntries;\n const lowerFilter = entryFilter.toLowerCase();\n return divergedEntries.filter((entry) => entry.originalBranch.toLowerCase().includes(lowerFilter));\n }, [divergedEntries, entryFilter]);\n\n const combinedList = useMemo((): ListItem[] => {\n const items: ListItem[] = filteredEntries.map((entry) => ({ type: \"worktree\" as const, entry }));\n if (filteredDiverged.length > 0) {\n items.push({ type: \"separator\" as const });\n for (const entry of filteredDiverged) {\n items.push({ type: \"diverged\" as const, entry });\n }\n }\n return items;\n }, [filteredEntries, filteredDiverged]);\n\n const selectableIndices = useMemo(() => {\n return combinedList.reduce<number[]>((acc, item, idx) => {\n if (item.type !== \"separator\") acc.push(idx);\n return acc;\n }, []);\n }, [combinedList]);\n\n const loadStatus = useCallback(\n async (repoIndex: number) => {\n setLoading(true);\n try {\n const [statusEntries, divergedDirs] = await Promise.all([\n getWorktreeStatusForRepo(repoIndex),\n getDivergedDirectoriesForRepo?.(repoIndex) ?? Promise.resolve([]),\n ]);\n setEntries(statusEntries);\n setDivergedEntries(divergedDirs);\n setSelectedEntryIndex(0);\n setExpandedEntry(null);\n setConfirmDelete(null);\n } catch (err) {\n setError(`Failed to load worktree status: ${err}`);\n setStep(\"ERROR\");\n }\n setLoading(false);\n },\n [getWorktreeStatusForRepo, getDivergedDirectoriesForRepo],\n );\n\n useEffect(() => {\n if (!getRepositoryDiskUsage) return undefined;\n\n let cancelled = false;\n const indexesToLoad = repositories\n .map((repo) => repo.index)\n .filter((repoIndex) => !requestedDiskUsageRef.current.has(repoIndex));\n\n if (indexesToLoad.length === 0) return undefined;\n\n for (const repoIndex of indexesToLoad) {\n requestedDiskUsageRef.current.add(repoIndex);\n setRepoDiskUsage((prev) => ({ ...prev, [repoIndex]: { status: \"loading\" } }));\n\n void getRepositoryDiskUsage(repoIndex)\n .then((usage) => {\n if (cancelled) return;\n setRepoDiskUsage((prev) => ({ ...prev, [repoIndex]: { status: \"ready\", usage } }));\n })\n .catch(() => {\n if (cancelled) return;\n setRepoDiskUsage((prev) => ({\n ...prev,\n [repoIndex]: { status: \"error\" },\n }));\n });\n }\n\n return () => {\n cancelled = true;\n };\n }, [repositories, getRepositoryDiskUsage]);\n\n useEffect(() => {\n if (step === \"VIEW_STATUS\" && entries.length === 0 && !loading && selectedRepoIndexRef.current >= 0) {\n loadStatus(selectedRepoIndexRef.current);\n }\n }, [step, entries.length, loading, loadStatus]);\n\n const navigateUp = useCallback(() => {\n setSelectedEntryIndex((prev) => {\n const currentSelectableIdx = selectableIndices.indexOf(prev);\n if (currentSelectableIdx <= 0) return selectableIndices[0] ?? 0;\n return selectableIndices[currentSelectableIdx - 1];\n });\n }, [selectableIndices]);\n\n const navigateDown = useCallback(() => {\n setSelectedEntryIndex((prev) => {\n const currentSelectableIdx = selectableIndices.indexOf(prev);\n if (currentSelectableIdx === -1) return selectableIndices[0] ?? 0;\n if (currentSelectableIdx >= selectableIndices.length - 1) return prev;\n return selectableIndices[currentSelectableIdx + 1];\n });\n }, [selectableIndices]);\n\n const selectedItem = combinedList[selectedEntryIndex];\n const isDivergedSelected = selectedItem?.type === \"diverged\";\n\n useInput((input, key) => {\n if (confirmDelete !== null) {\n if (input === \"y\" || input === \"Y\") {\n const item = combinedList[confirmDelete];\n if (item?.type === \"diverged\" && deleteDivergedDirectory && selectedRepoIndexRef.current >= 0) {\n setDeleting(true);\n deleteDivergedDirectory(selectedRepoIndexRef.current, item.entry.name)\n .then(() => {\n setDivergedEntries((prev) => prev.filter((d) => d.name !== item.entry.name));\n setConfirmDelete(null);\n setDeleting(false);\n setExpandedEntry(null);\n })\n .catch((err: unknown) => {\n setError(`Failed to delete: ${getErrorMessage(err)}`);\n setConfirmDelete(null);\n setDeleting(false);\n });\n }\n return;\n }\n if (input === \"n\" || input === \"N\" || key.escape) {\n setConfirmDelete(null);\n return;\n }\n return;\n }\n\n if (key.escape) {\n if (step === \"SELECT_PROJECT\") {\n onClose();\n } else if (step === \"VIEW_STATUS\") {\n if (repositories.length > 1) {\n setEntries([]);\n setDivergedEntries([]);\n setEntryFilter(\"\");\n setExpandedEntry(null);\n setConfirmDelete(null);\n selectedRepoIndexRef.current = -1;\n setStep(\"SELECT_PROJECT\");\n } else {\n onClose();\n }\n } else if (step === \"ERROR\") {\n onClose();\n }\n return;\n }\n\n if (step === \"SELECT_PROJECT\") {\n if (key.upArrow) {\n setSelectedProjectIndex((prev) => Math.max(0, prev - 1));\n } else if (key.downArrow) {\n setSelectedProjectIndex((prev) => Math.min(filteredProjects.length - 1, prev + 1));\n } else if (key.return && filteredProjects.length > 0) {\n const selectedRepo = filteredProjects[selectedProjectIndex];\n if (selectedRepo) {\n selectedRepoIndexRef.current = selectedRepo.index;\n setStep(\"VIEW_STATUS\");\n loadStatus(selectedRepo.index);\n }\n } else if (key.backspace || key.delete) {\n setProjectFilter((prev) => prev.slice(0, -1));\n setSelectedProjectIndex(0);\n } else if (input && !key.ctrl && !key.meta) {\n setProjectFilter((prev) => prev + input);\n setSelectedProjectIndex(0);\n }\n } else if (step === \"VIEW_STATUS\" && !loading) {\n if (key.upArrow) {\n navigateUp();\n } else if (key.downArrow) {\n navigateDown();\n } else if (key.return && combinedList.length > 0) {\n setExpandedEntry((prev) => (prev === selectedEntryIndex ? null : selectedEntryIndex));\n } else if (input === \"d\" && isDivergedSelected && deleteDivergedDirectory) {\n setConfirmDelete(selectedEntryIndex);\n } else if (key.backspace || key.delete) {\n setEntryFilter((prev) => prev.slice(0, -1));\n setSelectedEntryIndex(0);\n setExpandedEntry(null);\n } else if (input && !key.ctrl && !key.meta) {\n setEntryFilter((prev) => prev + input);\n setSelectedEntryIndex(0);\n setExpandedEntry(null);\n }\n } else if (step === \"ERROR\") {\n onClose();\n }\n });\n\n usePaste((text) => {\n if (confirmDelete !== null) return;\n if (step === \"SELECT_PROJECT\") {\n setProjectFilter((prev) => prev + text);\n setSelectedProjectIndex(0);\n } else if (step === \"VIEW_STATUS\" && !loading) {\n setEntryFilter((prev) => prev + text);\n setSelectedEntryIndex(0);\n setExpandedEntry(null);\n }\n });\n\n const getStepNumber = () => {\n if (repositories.length === 1) return 1;\n return step === \"SELECT_PROJECT\" ? 1 : 2;\n };\n\n const getTotalSteps = () => (repositories.length === 1 ? 1 : 2);\n\n const renderProjectSelection = () => {\n const visibleCount = 8;\n const halfVisible = Math.floor(visibleCount / 2);\n let startIdx = Math.max(0, selectedProjectIndex - halfVisible);\n const endIdx = Math.min(filteredProjects.length, startIdx + visibleCount);\n if (endIdx - startIdx < visibleCount) {\n startIdx = Math.max(0, endIdx - visibleCount);\n }\n\n const visibleProjects = filteredProjects.slice(startIdx, endIdx);\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text>Select repository:</Text>\n <Box>\n <Text>Filter: </Text>\n <Text color=\"cyan\">{projectFilter || \"_\"}</Text>\n <Text dimColor>\n {\" \"}\n ({filteredProjects.length}/{repositories.length} matches)\n </Text>\n </Box>\n <Box flexDirection=\"column\">\n {filteredProjects.length === 0 ? (\n <Text color=\"yellow\">No matches</Text>\n ) : (\n <>\n {startIdx > 0 && <Text dimColor> ...</Text>}\n {visibleProjects.map((repo, idx) => {\n const actualIdx = startIdx + idx;\n const isSelected = actualIdx === selectedProjectIndex;\n return (\n <Box key={repo.index}>\n <Text color={isSelected ? \"cyan\" : undefined}>{isSelected ? \"> \" : \" \"}</Text>\n <Box width={38}>\n <Text color={isSelected ? \"cyan\" : undefined}>{repo.name}</Text>\n </Box>\n {getRepositoryDiskUsage && <Text dimColor> </Text>}\n {renderRepositoryDiskUsage(repo.index)}\n </Box>\n );\n })}\n {endIdx < filteredProjects.length && <Text dimColor> ...</Text>}\n </>\n )}\n </Box>\n </Box>\n );\n };\n\n const renderDetailPanel = (entry: WorktreeStatusEntry) => {\n const { status } = entry;\n const details = status.details;\n\n return (\n <Box flexDirection=\"column\" marginLeft={4} marginTop={0} marginBottom={1}>\n <Text dimColor>Path: {entry.path}</Text>\n {details && (\n <>\n {details.modifiedFiles > 0 && <Text color=\"yellow\"> Modified: {details.modifiedFiles}</Text>}\n {details.deletedFiles > 0 && <Text color=\"red\"> Deleted: {details.deletedFiles}</Text>}\n {details.createdFiles > 0 && <Text color=\"green\"> Created: {details.createdFiles}</Text>}\n {details.renamedFiles > 0 && <Text color=\"blue\"> Renamed: {details.renamedFiles}</Text>}\n {details.untrackedFiles > 0 && <Text color=\"gray\"> Untracked: {details.untrackedFiles}</Text>}\n {details.conflictedFiles > 0 && <Text color=\"red\"> Conflicted: {details.conflictedFiles}</Text>}\n {(details.unpushedCommitCount ?? 0) > 0 &&\n (status.fullyPushedUpstreamDeleted ? (\n <Text color=\"green\">\n {\" \"}\n Fully pushed before remote branch deletion ({details.unpushedCommitCount} commit\n {details.unpushedCommitCount === 1 ? \"\" : \"s\"} not on any remote \u2014 likely squash-merged)\n </Text>\n ) : (\n <Text color=\"cyan\"> Unpushed commits: {details.unpushedCommitCount}</Text>\n ))}\n {(details.stashCount ?? 0) > 0 && <Text color=\"magenta\"> Stashes: {details.stashCount}</Text>}\n {details.operationType && <Text color=\"red\"> Operation: {details.operationType}</Text>}\n {details.modifiedSubmodules && details.modifiedSubmodules.length > 0 && (\n <Text color=\"yellow\"> Modified submodules: {details.modifiedSubmodules.join(\", \")}</Text>\n )}\n </>\n )}\n {status.upstreamGone && <Text color=\"red\"> Remote branch has been deleted</Text>}\n {status.reasons.length > 0 && (\n <Text dimColor> Reasons: {status.reasons.join(\", \")}</Text>\n )}\n </Box>\n );\n };\n\n const renderDivergedDetailPanel = (entry: DivergedDirectoryInfo) => {\n return (\n <Box flexDirection=\"column\" marginLeft={4} marginTop={0} marginBottom={1}>\n <Text dimColor>Path: {entry.path}</Text>\n <Text dimColor> Original branch: {entry.originalBranch}</Text>\n {entry.divergedAt && <Text dimColor> Diverged: {entry.divergedAt}</Text>}\n <Text dimColor> Size: {entry.sizeFormatted}</Text>\n </Box>\n );\n };\n\n const renderRepositoryDiskUsage = (repoIndex: number) => {\n if (!getRepositoryDiskUsage) return null;\n\n const state = repoDiskUsage[repoIndex];\n if (!state || state.status === \"loading\") {\n return <Text dimColor>Size: calculating...</Text>;\n }\n if (state.status === \"error\") {\n return <Text color=\"red\">Size: N/A</Text>;\n }\n return (\n <Text>\n Size: <Text color=\"magenta\">{state.usage.sizeFormatted}</Text>\n </Text>\n );\n };\n\n const renderStatusList = () => {\n if (loading) {\n return <Text color=\"yellow\">Loading worktree status...</Text>;\n }\n\n if (entries.length === 0 && divergedEntries.length === 0) {\n return <Text color=\"red\">No worktrees found</Text>;\n }\n\n const visibleCount = 8;\n const halfVisible = Math.floor(visibleCount / 2);\n let startIdx = Math.max(0, selectedEntryIndex - halfVisible);\n const endIdx = Math.min(combinedList.length, startIdx + visibleCount);\n if (endIdx - startIdx < visibleCount) {\n startIdx = Math.max(0, endIdx - visibleCount);\n }\n\n const visibleItems = combinedList.slice(startIdx, endIdx);\n const filteredCount = filteredEntries.length + filteredDiverged.length;\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text>Filter: </Text>\n <Text color=\"cyan\">{entryFilter || \"_\"}</Text>\n <Text dimColor>\n {\" \"}\n ({filteredCount}/{entries.length + divergedEntries.length} matches)\n </Text>\n </Box>\n <Box flexDirection=\"column\">\n {filteredCount === 0 ? (\n <Text color=\"yellow\">No matches</Text>\n ) : (\n <>\n {startIdx > 0 && <Text dimColor> ...</Text>}\n {visibleItems.map((item, idx) => {\n const actualIdx = startIdx + idx;\n\n if (item.type === \"separator\") {\n return (\n <Box key=\"separator\" marginTop={1}>\n <Text dimColor>\u2500\u2500 Diverged Directories \u2500\u2500</Text>\n </Box>\n );\n }\n\n if (item.type === \"worktree\") {\n const isSelected = actualIdx === selectedEntryIndex;\n const isExpanded = expandedEntry === actualIdx;\n const summary = getStatusSummary(item.entry.status);\n\n return (\n <Box key={item.entry.path} flexDirection=\"column\">\n <Box>\n <Text color={isSelected ? \"cyan\" : undefined}>\n {isSelected ? \"> \" : \" \"}\n </Text>\n <Box width={24}>\n <Text color={isSelected ? \"cyan\" : undefined}>{item.entry.branch}</Text>\n </Box>\n <Text> </Text>\n {getStatusFlags(item.entry.status)}\n {summary && (\n <Text dimColor> {summary}</Text>\n )}\n </Box>\n {isExpanded && renderDetailPanel(item.entry)}\n </Box>\n );\n }\n\n const isSelected = actualIdx === selectedEntryIndex;\n const isExpanded = expandedEntry === actualIdx;\n const isConfirming = confirmDelete === actualIdx;\n const dateStr = formatDivergedDate(item.entry.divergedAt);\n\n return (\n <Box key={item.entry.path} flexDirection=\"column\">\n <Box>\n <Text color={isSelected ? \"cyan\" : undefined}>\n {isSelected ? \"> \" : \" \"}\n </Text>\n {isConfirming ? (\n deleting ? (\n <Text color=\"yellow\">Deleting...</Text>\n ) : (\n <Text color=\"red\">\n Delete {item.entry.name}? (y/n)\n </Text>\n )\n ) : (\n <>\n <Text color={isSelected ? \"cyan\" : \"yellow\"}>\uD83D\uDCE6 </Text>\n <Box width={24}>\n <Text color={isSelected ? \"cyan\" : undefined}>{item.entry.originalBranch}</Text>\n </Box>\n <Text dimColor> {item.entry.sizeFormatted.padStart(10)}</Text>\n <Text dimColor> (diverged {dateStr})</Text>\n </>\n )}\n </Box>\n {isExpanded && !isConfirming && renderDivergedDetailPanel(item.entry)}\n </Box>\n );\n })}\n {endIdx < combinedList.length && <Text dimColor> ...</Text>}\n </>\n )}\n </Box>\n </Box>\n );\n };\n\n const renderError = () => (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"red\">Error: {error}</Text>\n <Text dimColor>Press any key to close</Text>\n </Box>\n );\n\n const renderContent = () => {\n switch (step) {\n case \"SELECT_PROJECT\":\n return renderProjectSelection();\n case \"VIEW_STATUS\":\n return renderStatusList();\n case \"ERROR\":\n return renderError();\n }\n };\n\n const renderFooter = () => {\n if (step === \"ERROR\") return null;\n if (step === \"VIEW_STATUS\" && loading) return null;\n if (confirmDelete !== null) {\n return <Text dimColor>y to confirm \u2022 n or ESC to cancel</Text>;\n }\n return (\n <Text dimColor>\n {step === \"VIEW_STATUS\"\n ? isDivergedSelected\n ? \"\u2191/\u2193 navigate \u2022 Type to filter \u2022 Enter to expand \u2022 d to delete \u2022 ESC to close\"\n : \"\u2191/\u2193 navigate \u2022 Type to filter \u2022 Enter to expand \u2022 ESC to close\"\n : \"\u2191/\u2193 navigate \u2022 Type to filter \u2022 Enter to select \u2022 ESC to cancel\"}\n </Text>\n );\n };\n\n const selectedRepo =\n selectedRepoIndexRef.current >= 0\n ? repositories.find((repo) => repo.index === selectedRepoIndexRef.current)\n : undefined;\n\n return (\n <Box flexDirection=\"column\" marginTop={1} marginBottom={1}>\n <Box borderStyle=\"round\" borderColor=\"green\" paddingX={2} paddingY={1} flexDirection=\"column\" width={70}>\n <Box marginBottom={1}>\n <Text bold color=\"green\">\n \uD83D\uDCCA Worktree Status{\" \"}\n {step !== \"ERROR\" && (\n <Text dimColor>\n (Step {getStepNumber()}/{getTotalSteps()})\n </Text>\n )}\n </Text>\n </Box>\n\n {step === \"VIEW_STATUS\" && selectedRepo && (\n <Box marginBottom={1}>\n <Text>\n Repository: <Text color=\"cyan\">{selectedRepo.name}</Text>\n </Text>\n {getRepositoryDiskUsage && <Text dimColor> </Text>}\n {renderRepositoryDiskUsage(selectedRepo.index)}\n </Box>\n )}\n\n {renderContent()}\n\n <Box marginTop={1}>{renderFooter()}</Box>\n </Box>\n </Box>\n );\n};\n\nexport default WorktreeStatusView;\n", "/**\n * Extracts error message from unknown error type\n * @param error The error to extract message from\n * @returns The error message string\n */\nexport function getErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (error && typeof error === \"object\" && \"message\" in error) {\n return String((error as { message: unknown }).message);\n }\n return String(error);\n}\n\n/**\n * Common LFS error patterns that indicate Git LFS-related failures\n */\nexport const LFS_ERROR_PATTERNS = Object.freeze([\n \"smudge filter lfs failed\",\n \"Object does not exist on the server\",\n \"external filter 'git-lfs filter-process' failed\",\n] as const);\n\n/**\n * Checks if an error message contains any known LFS error patterns\n * @param errorMessage The error message to check\n * @returns true if the error is related to Git LFS\n */\nexport function isLfsError(errorMessage: string): boolean {\n return LFS_ERROR_PATTERNS.some((pattern) => errorMessage.includes(pattern));\n}\n\n/**\n * Checks if an error object contains any known LFS error patterns\n * @param error The error object to check\n * @returns true if the error is related to Git LFS\n */\nexport function isLfsErrorFromError(error: unknown): boolean {\n return isLfsError(getErrorMessage(error));\n}\n\n/**\n * git stderr fragments that indicate the requested remote ref does not exist\n * (e.g. the tracked branch was deleted on the remote). Matched as substrings;\n * callers force LC_ALL=C so these stay deterministic English.\n */\nexport const MISSING_REMOTE_REF_PATTERNS = Object.freeze([\n \"couldn't find remote ref\",\n \"Couldn't find remote ref\",\n \"not our ref\",\n] as const);\n\n/**\n * Checks if an error message indicates a missing remote ref.\n * @param errorMessage The error message to check\n * @returns true if the message indicates the remote ref is gone\n */\nexport function isMissingRemoteRefError(errorMessage: string): boolean {\n return MISSING_REMOTE_REF_PATTERNS.some((pattern) => errorMessage.includes(pattern));\n}\n", "import React, { useState, useEffect, useRef } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport type { LogEntry } from \"./App\";\n\nexport interface LogPanelProps {\n logs: LogEntry[];\n height: number;\n isActive: boolean;\n}\n\nconst LogPanel: React.FC<LogPanelProps> = ({ logs, height, isActive }) => {\n const [scrollOffset, setScrollOffset] = useState(0);\n const [autoScroll, setAutoScroll] = useState(true);\n const [pendingG, setPendingG] = useState(false);\n const gTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const borderLines = 2;\n const headerLine = 1;\n const visibleLines = Math.max(1, height - borderLines - headerLine);\n const maxOffset = Math.max(0, logs.length - visibleLines);\n\n useEffect(() => {\n if (autoScroll) {\n setScrollOffset(maxOffset);\n }\n }, [logs.length, maxOffset, autoScroll]);\n\n useEffect(() => {\n return () => {\n if (gTimeoutRef.current) {\n clearTimeout(gTimeoutRef.current);\n }\n };\n }, []);\n\n useInput(\n (input, key) => {\n if (!isActive) return;\n\n if (key.upArrow || input === \"k\") {\n setScrollOffset((prev) => Math.max(0, prev - 1));\n setAutoScroll(false);\n setPendingG(false);\n } else if (key.downArrow || input === \"j\") {\n setScrollOffset((prev) => {\n const newOffset = Math.min(maxOffset, prev + 1);\n if (newOffset >= maxOffset) {\n setAutoScroll(true);\n }\n return newOffset;\n });\n setPendingG(false);\n } else if (key.pageUp) {\n setScrollOffset((prev) => Math.max(0, prev - visibleLines));\n setAutoScroll(false);\n setPendingG(false);\n } else if (key.pageDown) {\n setScrollOffset((prev) => {\n const newOffset = Math.min(maxOffset, prev + visibleLines);\n if (newOffset >= maxOffset) {\n setAutoScroll(true);\n }\n return newOffset;\n });\n setPendingG(false);\n } else if (input === \"g\") {\n if (pendingG) {\n // gg - go to top\n setScrollOffset(0);\n setAutoScroll(false);\n setPendingG(false);\n if (gTimeoutRef.current) {\n clearTimeout(gTimeoutRef.current);\n gTimeoutRef.current = null;\n }\n } else {\n setPendingG(true);\n gTimeoutRef.current = setTimeout(() => {\n setPendingG(false);\n }, 500);\n }\n } else if (input === \"G\") {\n setScrollOffset(maxOffset);\n setAutoScroll(true);\n setPendingG(false);\n }\n },\n { isActive },\n );\n\n const getLogColor = (level: LogEntry[\"level\"]): \"red\" | \"yellow\" | undefined => {\n switch (level) {\n case \"error\":\n return \"red\";\n case \"warn\":\n return \"yellow\";\n default:\n return undefined;\n }\n };\n\n const visibleLogs = logs.slice(scrollOffset, scrollOffset + visibleLines);\n const hasMoreAbove = scrollOffset > 0;\n const hasMoreBelow = scrollOffset + visibleLines < logs.length;\n const aboveCount = scrollOffset;\n const belowCount = logs.length - scrollOffset - visibleLines;\n\n const emptyLines = Math.max(0, visibleLines - visibleLogs.length);\n\n return (\n <Box borderStyle=\"single\" flexDirection=\"column\" flexGrow={1} paddingX={1}>\n <Box justifyContent=\"space-between\">\n <Text bold>\n \uD83D\uDCCB Logs {logs.length > 0 && <Text dimColor>({logs.length} entries)</Text>}\n </Text>\n {isActive && (\n <Text dimColor>\n {hasMoreAbove || hasMoreBelow ? \"\u2191/\u2193 scroll\" : \"\"} {autoScroll ? \"(auto)\" : \"\"}\n </Text>\n )}\n </Box>\n\n {hasMoreAbove && (\n <Text dimColor>\n \u2191 {aboveCount} more above\n </Text>\n )}\n\n {visibleLogs.map((log) => (\n <Text key={log.id} color={getLogColor(log.level)} wrap=\"truncate\">\n {log.message}\n </Text>\n ))}\n\n {Array.from({ length: emptyLines }).map((_, i) => (\n <Text key={`empty-${i}`}> </Text>\n ))}\n\n {hasMoreBelow && (\n <Text dimColor>\n \u2193 {belowCount} more below\n </Text>\n )}\n </Box>\n );\n};\n\nexport default LogPanel;\n", "import pLimit from \"p-limit\";\n\nimport { ENV_CONSTANTS } from \"../constants\";\nimport { ConfigError, TrashOperationError } from \"../errors\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\nimport { getRemovalAuditLogPath } from \"../utils/lock-path\";\nimport { REPOSITORY_MODES, resolveMode } from \"../utils/repo-mode\";\nimport { retry } from \"../utils/retry\";\nimport { PhaseTimer, Timer, formatTimingTable } from \"../utils/timing\";\n\nimport { type CloneSkipReason, CloneSyncService } from \"./clone-sync.service\";\nimport { GitMaintenanceService } from \"./git-maintenance.service\";\nimport { GitService } from \"./git.service\";\nimport { Logger } from \"./logger.service\";\nimport { ProgressEmitter } from \"./progress-emitter\";\nimport { RemovalAuditService } from \"./removal-audit.service\";\nimport { RepoOperationLock } from \"./repo-operation-lock\";\nimport { SyncOutcomeAccumulator } from \"./sync-outcome\";\nimport { SyncRetryPolicy } from \"./sync-retry-policy\";\nimport { TrashMigrationService } from \"./trash-migration.service\";\nimport { TrashReaperService } from \"./trash-reaper.service\";\nimport { TrashService } from \"./trash.service\";\nimport { WorktreeModeSyncRunner } from \"./worktree-mode-sync-runner\";\n\nimport type { ProgressEvent, ProgressListener } from \"./progress-emitter\";\nimport type { RepoLockRelease } from \"./repo-operation-lock\";\nimport type { TrashEntry, TrashManifest } from \"./trash.service\";\nimport type { Config, SyncOutcome, SyncResult } from \"../types\";\nimport type { LfsErrorContext } from \"../utils/retry\";\n\nexport type { ProgressEvent, ProgressListener } from \"./progress-emitter\";\nexport type { SyncOutcome, SyncOutcomeAction, SyncOutcomeCounts, SyncResult } from \"../types\";\n\nexport type ExclusiveRepoOperationResult<T> =\n | { started: true; value: T }\n | { started: false; reason: \"in_progress\" | \"locked\" };\n\nexport class WorktreeSyncService {\n private gitService: GitService;\n private cloneSyncService: CloneSyncService | null = null;\n private logger: Logger;\n // In-process FIFO serializer for all bare-repo-mutating operations (sync, init,\n // interactive create). One per repo. wait:true callers queue behind an in-flight op;\n // wait:false callers fail fast. The cross-process file lock (RepoOperationLock) is\n // acquired inside the mutex body for multi-process safety.\n private repoMutex = pLimit(1);\n private progressEmitter = new ProgressEmitter();\n private repoOperationLock: RepoOperationLock;\n private maintenanceService: GitMaintenanceService;\n private retryPolicy: SyncRetryPolicy;\n private worktreeModeSyncRunner: WorktreeModeSyncRunner;\n private trashService: TrashService;\n private trashReaper: TrashReaperService;\n private trashMigration: TrashMigrationService;\n private skipsAccumulator: CloneSkipReason[] = [];\n private lastOutcome: SyncOutcome | null = null;\n\n constructor(public readonly config: Config) {\n this.logger = config.logger ?? Logger.createDefault(undefined, config.debug);\n this.gitService = new GitService(config, this.logger, (event): void => this.emitProgress(event));\n this.repoOperationLock = new RepoOperationLock(config, this.gitService, this.logger);\n this.maintenanceService = new GitMaintenanceService(config, this.gitService, this.logger);\n this.retryPolicy = new SyncRetryPolicy(config, this.gitService, this.logger);\n const removalAudit = new RemovalAuditService(getRemovalAuditLogPath(config));\n this.trashService = new TrashService(config, this.gitService, this.logger, removalAudit);\n this.trashReaper = new TrashReaperService(config, this.trashService, this.logger, removalAudit, this.gitService);\n this.trashMigration = new TrashMigrationService(config, this.trashService, this.logger);\n if (this.trashService.isEnabled()) {\n this.gitService.setStaleDirectoryTrasher(\n async (dirPath) => (await this.trashService.trashDirectory({ dirPath, reason: \"orphan\" })).payloadPath,\n );\n }\n this.worktreeModeSyncRunner = new WorktreeModeSyncRunner(\n config,\n this.gitService,\n this.logger,\n this.progressEmitter,\n {\n trashService: this.trashService,\n removalAudit,\n },\n );\n if (resolveMode(config) === REPOSITORY_MODES.CLONE) {\n this.cloneSyncService = new CloneSyncService(config, this.gitService, this.logger, {\n progressEmitter: (event): void => this.emitProgress(event),\n onSkip: (reason): void => {\n this.skipsAccumulator.push(reason);\n },\n });\n }\n }\n\n public getRecordedSkips(): readonly CloneSkipReason[] {\n return [...this.skipsAccumulator];\n }\n\n public clearRecordedSkips(): void {\n this.skipsAccumulator = [];\n }\n\n public clearPendingInitSkip(): void {\n this.cloneSyncService?.clearPendingInitSkip();\n }\n\n public getLastOutcome(): SyncOutcome | null {\n return this.lastOutcome;\n }\n\n isCloneMode(): boolean {\n return this.cloneSyncService !== null;\n }\n\n async getWorktrees(): Promise<Array<{ path: string; branch: string }>> {\n if (this.cloneSyncService) {\n return this.cloneSyncService.getWorktrees();\n }\n return this.gitService.getWorktrees();\n }\n\n async getRemoteBranches(): Promise<string[]> {\n if (this.cloneSyncService) {\n return this.cloneSyncService.getRemoteBranches();\n }\n return this.gitService.getRemoteBranches();\n }\n\n async checkoutBranch(branchName: string, options: { allowConfigDrift?: boolean } = {}): Promise<void> {\n if (!this.cloneSyncService) {\n throw new ConfigError(\"checkoutBranch is only available for clone-mode repositories\", \"CLONE_MODE_REQUIRED\");\n }\n await this.cloneSyncService.checkoutBranch(branchName, options);\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized()) return;\n const result = await this.runExclusiveRepoOperation(() => this.initializeUnlocked());\n if (!result.started) {\n const reason = result.reason === \"in_progress\" ? \"operation in progress\" : \"another process holds the lock\";\n this.logger.warn(`\u26A0\uFE0F Initialize skipped: ${reason}`);\n }\n }\n\n async initializeUnlocked(outcome?: SyncOutcomeAccumulator): Promise<void> {\n this.emitProgress({ phase: \"initialize\", message: \"Initializing repository\" });\n if (this.cloneSyncService) {\n await this.cloneSyncService.initialize(outcome);\n } else {\n await this.gitService.initialize();\n }\n this.emitProgress({ phase: \"initialize\", message: \"Repository initialized\" });\n }\n\n isInitialized(): boolean {\n if (this.cloneSyncService) {\n return this.cloneSyncService.isInitialized();\n }\n return this.gitService.isInitialized();\n }\n\n isSyncInProgress(): boolean {\n return this.repoMutex.activeCount + this.repoMutex.pendingCount > 0;\n }\n\n getGitService(): GitService {\n return this.gitService;\n }\n\n // Restore must hold the repo lock: the reaper, prune, and gc all mutate the\n // same trash entries and refs at the tail of a sync. wait:true queues behind\n // an in-flight sync instead of failing fast \u2014 restores are explicit user\n // actions, not periodic work.\n async restoreFromTrash(id: string): Promise<TrashManifest> {\n const result = await this.runExclusiveRepoOperation(() => this.trashService.restore(id), { wait: true });\n if (!result.started) {\n throw new TrashOperationError(\n \"restore\",\n `cannot restore trash entry '${id}': another process holds the repo lock`,\n );\n }\n return result.value;\n }\n\n async listTrashEntries(): Promise<{ entries: TrashEntry[]; invalid: string[] }> {\n return this.trashService.listEntries();\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n this.gitService.updateLogger(logger);\n this.cloneSyncService?.updateLogger(logger);\n this.retryPolicy.updateLogger(logger);\n this.worktreeModeSyncRunner.updateLogger(logger);\n this.repoOperationLock.updateLogger(logger);\n this.maintenanceService.updateLogger(logger);\n this.trashService.updateLogger(logger);\n this.trashReaper.updateLogger(logger);\n this.trashMigration.updateLogger(logger);\n }\n\n // Runs git gc when due, inside the already-held repo lock (mirrors\n // initializeUnlocked \u2014 must NOT re-acquire runExclusiveRepoOperation or it\n // would self-deadlock/skip). Skipped under NODE_ENV=test so unit suites don't\n // shell out to real git; GitMaintenanceService is covered by its own tests.\n private async runMaintenanceIfDueUnlocked(): Promise<void> {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) {\n return;\n }\n await this.maintenanceService.runIfDueUnlocked();\n }\n\n // Same contract as runMaintenanceIfDueUnlocked: tail of a successful sync,\n // inside the held lock, never fails the sync. Runs before gc so freshly\n // reaped pin refs can be collected in the same maintenance window.\n private async runTrashMaintenanceUnlocked(): Promise<void> {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) {\n return;\n }\n if (this.cloneSyncService) {\n return;\n }\n try {\n await this.trashMigration.migrateLegacyUnlocked();\n await this.trashReaper.reapExpiredUnlocked();\n } catch (error) {\n this.logger.warn(`\u26A0\uFE0F Trash maintenance failed: ${getErrorMessage(error)}`);\n }\n }\n\n onProgress(listener: ProgressListener): () => void {\n return this.progressEmitter.onProgress(listener);\n }\n\n async runExclusiveRepoOperation<T>(\n operation: () => Promise<T>,\n options: { wait?: boolean } = {},\n ): Promise<ExclusiveRepoOperationResult<T>> {\n // Fail-fast callers (sync, init, MCP) bail when any repo op is active or queued.\n // wait:true callers (interactive create) skip this check and queue on the mutex,\n // running once the in-flight op releases. The count check and the repoMutex()\n // enqueue below execute synchronously with no await between them, so on the\n // single JS thread a second fail-fast caller always observes the first.\n if (!options.wait && this.repoMutex.activeCount + this.repoMutex.pendingCount > 0) {\n this.logger.warn(\"\u26A0\uFE0F Another repository operation is already in progress, skipping...\");\n return { started: false, reason: \"in_progress\" };\n }\n\n return this.repoMutex(async (): Promise<ExclusiveRepoOperationResult<T>> => {\n const release: RepoLockRelease | null = await this.repoOperationLock.acquire();\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 try {\n return { started: true, value: await operation() };\n } finally {\n try {\n await release();\n } catch (releaseError) {\n this.logger.warn(`Failed to release sync lock: ${getErrorMessage(releaseError)}`);\n }\n }\n });\n }\n\n // Interactive variant: queues behind any in-flight sync/op instead of failing fast.\n async runQueuedRepoOperation<T>(operation: () => Promise<T>): Promise<ExclusiveRepoOperationResult<T>> {\n return this.runExclusiveRepoOperation(operation, { wait: true });\n }\n\n private emitProgress(event: ProgressEvent): void {\n this.progressEmitter.emit(event);\n }\n\n async sync(): Promise<SyncResult> {\n const result = await this.runExclusiveRepoOperation<SyncOutcome>(async () => {\n // Cleared here \u2014 once the sync actually starts \u2014 rather than by callers:\n // a losing concurrent caller clearing the shared accumulator would\n // silently truncate the winner's skips payload.\n this.clearRecordedSkips();\n const totalTimer = new Timer();\n const phaseTimer = new PhaseTimer();\n const outcome = new SyncOutcomeAccumulator({\n mode: this.cloneSyncService ? \"clone\" : \"worktree\",\n repoName: (this.config as { name?: string }).name,\n });\n const syncContext = this.retryPolicy.createContext();\n const retryOptions = this.retryPolicy.createOptions(syncContext);\n let durationMs: number | undefined;\n\n try {\n if (!this.isInitialized()) {\n await this.initializeUnlocked(outcome);\n }\n\n this.logger.info(`[${new Date().toISOString()}] Starting worktree synchronization...`);\n\n const retryOutcomeBaseline = outcome.snapshot();\n const retryOptionsWithOutcomeReset = {\n ...retryOptions,\n onRetry: (error: unknown, attempt: number, context?: LfsErrorContext): void => {\n outcome.restore(retryOutcomeBaseline);\n retryOptions.onRetry?.(error, attempt, context);\n },\n };\n\n const cloneSync = this.cloneSyncService;\n if (cloneSync) {\n await retry(() => cloneSync.runSyncAttempt(outcome), retryOptionsWithOutcomeReset);\n } else {\n await retry(\n () => this.worktreeModeSyncRunner.runSyncAttempt(phaseTimer, syncContext, outcome),\n retryOptionsWithOutcomeReset,\n );\n }\n } catch (error) {\n if (outcome.getCounts().failed === 0) {\n outcome.recordFailed(\"repo\", getErrorMessage(error), { reason: \"sync_failed\" });\n }\n this.logger.error(\"\\n\u274C Error during worktree synchronization after all retry attempts:\", error);\n throw error;\n } finally {\n this.retryPolicy.resetLfsSkipIfNeeded(syncContext);\n this.logger.info(`[${new Date().toISOString()}] Synchronization finished.\\n`);\n durationMs = totalTimer.stop();\n this.lastOutcome = outcome.toOutcome(durationMs);\n\n if (this.config.debug) {\n const phaseResults = phaseTimer.getResults();\n const repoName = (this.config as { name?: string }).name;\n this.logger.table(formatTimingTable(durationMs, phaseResults, repoName));\n }\n\n // Trash maintenance runs even when the sync failed: it only acts on\n // local expiry state, and a persistently failing fetch must not let\n // .trash/ grow without bound. gc stays success-only below.\n await this.runTrashMaintenanceUnlocked();\n }\n\n await this.runMaintenanceIfDueUnlocked();\n\n return this.lastOutcome ?? outcome.toOutcome(durationMs);\n });\n\n return result.started ? { started: true, outcome: result.value } : result;\n }\n}\n", "import { createHash } from \"crypto\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\nimport { sanitizeNameForPath } from \"./sanitize-name\";\n\nimport type { Config, RepositoryConfig } from \"../types\";\n\nexport interface RepoLockTarget {\n /** Absolute path to the directory that should contain the lock file. */\n dir: string;\n /** Lock filename (created lazily by proper-lockfile). */\n file: string;\n}\n\n// The lock is keyed ONLY by the canonical worktreeDir: two different config\n// files (or a config-mode daemon and a programmatic run) pointing at the same\n// checkout must contend for the same lock file, so it cannot live under a\n// per-config state dir the way the audit log does.\nexport function getCloneModeLockTarget(config: Config): RepoLockTarget {\n const hash = createHash(\"sha256\").update(path.resolve(config.worktreeDir)).digest(\"hex\").slice(0, 16);\n\n const stateBase =\n process.env.XDG_STATE_HOME && process.env.XDG_STATE_HOME.length > 0\n ? process.env.XDG_STATE_HOME\n : path.join(os.homedir(), \".cache\");\n const dir = path.join(stateBase, \"sync-worktrees\", \"locks\");\n return { dir, file: `${hash}.lock` };\n}\n\nexport function getRemovalAuditLogPath(config: Config): string {\n const name = (config as RepositoryConfig).name;\n const configDir = config.__configFileDir;\n\n const hash = createHash(\"sha256\").update(path.resolve(config.worktreeDir)).digest(\"hex\").slice(0, 16);\n\n if (configDir) {\n return path.join(\n configDir,\n \".sync-worktrees-state\",\n `${sanitizeNameForPath(name ?? \"repo\", \"removal audit log name\")}-${hash}-removals.jsonl`,\n );\n }\n\n const stateBase =\n process.env.XDG_STATE_HOME && process.env.XDG_STATE_HOME.length > 0\n ? process.env.XDG_STATE_HOME\n : path.join(os.homedir(), \".cache\");\n return path.join(stateBase, \"sync-worktrees\", \"removals\", `${hash}.jsonl`);\n}\n", "import { isLfsErrorFromError } from \"./lfs-error\";\n\ninterface ErrorWithCode {\n code?: string;\n message?: string;\n}\n\nexport interface LfsErrorContext {\n isLfsError: boolean;\n}\n\nexport interface RetryOptions {\n maxAttempts?: number | \"unlimited\";\n maxLfsRetries?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n backoffMultiplier?: number;\n /**\n * Add random jitter to retry delays to prevent thundering herd problem\n * in concurrent operations. Jitter is a random value between 0 and jitterMs\n * added to the calculated delay.\n *\n * Recommended for parallel operations to spread out retries.\n * Default: 0 (no jitter)\n */\n jitterMs?: number;\n shouldRetry?: (error: unknown, context?: LfsErrorContext) => boolean;\n onRetry?: (error: unknown, attempt: number, context?: LfsErrorContext) => void;\n lfsRetryHandler?: (context: LfsErrorContext) => void;\n}\n\nconst DEFAULT_OPTIONS: Required<Omit<RetryOptions, \"maxAttempts\">> & { maxAttempts: number | \"unlimited\" } = {\n maxAttempts: \"unlimited\",\n maxLfsRetries: 2,\n initialDelayMs: 1000,\n maxDelayMs: 600000, // 10 minutes\n backoffMultiplier: 2,\n jitterMs: 0,\n shouldRetry: (error, context) => {\n const err = error as ErrorWithCode;\n\n // Check for LFS errors\n if (isLfsErrorFromError(error)) {\n if (context) {\n context.isLfsError = true;\n }\n return true;\n }\n\n if (err.code === \"ENOTFOUND\" || err.code === \"ECONNREFUSED\" || err.code === \"ETIMEDOUT\") {\n return true;\n }\n\n if (err.code === \"EBUSY\" || err.code === \"ENOENT\" || err.code === \"EACCES\") {\n return true;\n }\n\n if (err.message?.includes(\"Could not read from remote repository\")) {\n return true;\n }\n\n if (err.message?.includes(\"fatal: unable to access\")) {\n return true;\n }\n\n return false;\n },\n onRetry: () => {},\n lfsRetryHandler: (_context) => {},\n};\n\nexport async function retry<T>(fn: () => Promise<T>, options: RetryOptions = {}): Promise<T> {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n let attempt = 1;\n let lfsAttempt = 0;\n const lfsContext: LfsErrorContext = { isLfsError: false };\n\n while (true) {\n try {\n return await fn();\n } catch (error) {\n // Reset LFS error flag for each attempt\n lfsContext.isLfsError = false;\n\n // Check if we should retry\n if (!opts.shouldRetry(error, lfsContext)) {\n throw error;\n }\n\n // Track LFS attempts separately\n if (lfsContext.isLfsError) {\n lfsAttempt++;\n\n // Check if we've exceeded LFS retry limit\n if (lfsAttempt > opts.maxLfsRetries) {\n const err = error as Error;\n throw new Error(\n `LFS error retry limit exceeded (${opts.maxLfsRetries} attempts). ` +\n `Consider using --skip-lfs option to bypass LFS downloads.`,\n { cause: err },\n );\n }\n }\n\n const isLastAttempt = opts.maxAttempts !== \"unlimited\" && attempt >= opts.maxAttempts;\n if (isLastAttempt) {\n throw error;\n }\n\n // Handle LFS errors specifically\n if (lfsContext.isLfsError && opts.lfsRetryHandler) {\n opts.lfsRetryHandler(lfsContext);\n }\n\n const baseDelay = Math.min(opts.initialDelayMs * Math.pow(opts.backoffMultiplier, attempt - 1), opts.maxDelayMs);\n\n // Add jitter to prevent thundering herd in concurrent operations\n // Jitter is a random value between 0 and jitterMs\n const jitter = opts.jitterMs > 0 ? Math.random() * opts.jitterMs : 0;\n const delay = baseDelay + jitter;\n\n opts.onRetry(error, attempt, lfsContext);\n\n await new Promise((resolve) => setTimeout(resolve, delay));\n attempt++;\n }\n }\n}\n", "import Table from \"cli-table3\";\n\nexport interface TimingResult {\n name: string;\n duration: number;\n count?: number;\n efficiency?: number;\n}\n\nexport class Timer {\n private startTime: number;\n private endTime?: number;\n\n constructor() {\n this.startTime = Date.now();\n }\n\n stop(): number {\n this.endTime = Date.now();\n return this.getDuration();\n }\n\n getDuration(): number {\n const end = this.endTime ?? Date.now();\n return end - this.startTime;\n }\n}\n\nexport class PhaseTimer {\n private phases: Map<string, { timer: Timer; count?: number; parallelism?: number }> = new Map();\n private currentPhase?: string;\n\n startPhase(name: string, parallelism?: number): void {\n if (this.currentPhase) {\n this.endPhase();\n }\n this.currentPhase = name;\n this.phases.set(name, { timer: new Timer(), parallelism });\n }\n\n endPhase(): void {\n if (this.currentPhase) {\n const phase = this.phases.get(this.currentPhase);\n if (phase) {\n phase.timer.stop();\n }\n this.currentPhase = undefined;\n }\n }\n\n setPhaseCount(name: string, count: number): void {\n const phase = this.phases.get(name);\n if (phase) {\n phase.count = count;\n }\n }\n\n getResults(): TimingResult[] {\n if (this.currentPhase) {\n this.endPhase();\n }\n\n const results: TimingResult[] = [];\n\n for (const [name, { timer, count, parallelism }] of this.phases.entries()) {\n const duration = timer.getDuration();\n const result: TimingResult = {\n name,\n duration,\n count,\n };\n\n if (count && count > 0 && parallelism && parallelism > 1) {\n const batches = Math.ceil(count / parallelism);\n const avgTimePerBatch = duration / batches;\n const theoreticalSequentialTime = count * avgTimePerBatch;\n result.efficiency =\n theoreticalSequentialTime > 0 ? Math.round((theoreticalSequentialTime / duration) * 100) : 100;\n }\n\n results.push(result);\n }\n\n return results;\n }\n}\n\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${minutes}m ${seconds}s`;\n}\n\nexport function formatTimingTable(totalDuration: number, phaseResults: TimingResult[], repoName?: string): string {\n const header = repoName ? `Performance Summary - [${repoName}]` : \"Performance Summary\";\n\n const table = new Table({\n head: [\"Operation\", \"Duration\", \"Efficiency\"],\n colWidths: [35, 12, 12],\n style: {\n head: [\"cyan\", \"bold\"],\n border: [\"gray\"],\n },\n });\n\n table.push([{ colSpan: 3, content: header, hAlign: \"center\" }]);\n\n table.push([\"Total Sync\", formatDuration(totalDuration), \"\"]);\n\n for (let i = 0; i < phaseResults.length; i++) {\n const result = phaseResults[i];\n const isLast = i === phaseResults.length - 1;\n const countStr = result.count ? ` (${result.count})` : \"\";\n const prefix = isLast ? \"\u2514\u2500\" : \"\u251C\u2500\";\n const name = ` ${prefix} ${result.name}${countStr}`;\n const efficiency = result.efficiency ? `${result.efficiency}%` : \"\";\n\n table.push([name, formatDuration(result.duration), efficiency]);\n }\n\n return table.toString();\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { DEFAULT_CONFIG, ENV_CONSTANTS, PATH_CONSTANTS } from \"../constants\";\nimport { ConfigError, FastForwardError, GitOperationError, WorktreeNotCleanError } from \"../errors\";\nimport { fileExists } from \"../utils/file-exists\";\nimport { makeGitProgressHandler } from \"../utils/git-progress\";\nimport { normalizeRepoUrlForComparison } from \"../utils/git-url\";\nimport { getErrorMessage, isLfsError, isMissingRemoteRefError } from \"../utils/lfs-error\";\n\nimport { BranchCreatedActionsService } from \"./branch-created-actions.service\";\nimport { cloneSkipToOutcomeAction } from \"./sync-outcome\";\n\nimport type { GitService } from \"./git.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { SyncOutcomeAccumulator } from \"./sync-outcome\";\nimport type { Config, RepositoryConfig } from \"../types\";\nimport type { GitProgressEmitter, GitProgressEvent } from \"../utils/git-progress\";\nimport type { SimpleGit, SimpleGitOptions } from \"simple-git\";\n\nconst SHALLOW_RELATION_DEEPEN_TARGETS = [50, 200, 1000] as const;\n\nexport type CloneSkipReason =\n | { kind: \"branch_mismatch\"; phase: \"init\" | \"sync\"; currentBranch: string; expectedBranch: string }\n | { kind: \"head_unreadable\"; phase: \"init\" | \"sync\"; error: string }\n | { kind: \"dirty_tree\" }\n | { kind: \"diverged\"; branch: string }\n | { kind: \"ahead_unpushed\"; branch: string }\n | { kind: \"missing_remote_ref\"; branch: string; source: \"fetch_error\" | \"post_fetch_verify\" }\n | { kind: \"indeterminate_shallow\"; branch: string; deepenedTo: number | null }\n | { kind: \"origin_mismatch\"; actual: string; expected: string };\n\nexport type CloneSkipListener = (reason: CloneSkipReason) => void;\n\nexport class CloneSyncService {\n private initialized = false;\n private resolvedBranch: string | null = null;\n private branchCreatedActions: BranchCreatedActionsService;\n private progressEmitter?: GitProgressEmitter;\n private onSkip?: CloneSkipListener;\n private outcomeAccumulator?: SyncOutcomeAccumulator;\n // One-shot suppression token. When init records a wrong-branch / unreadable-HEAD\n // skip for an existing clone, it sets this so the immediately following\n // runSyncAttempt (same sync operation) does not record the identical skip again.\n private pendingInitSkip: CloneSkipReason | null = null;\n\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger,\n options: {\n branchCreatedActions?: BranchCreatedActionsService;\n progressEmitter?: GitProgressEmitter;\n onSkip?: CloneSkipListener;\n } = {},\n ) {\n this.branchCreatedActions = options.branchCreatedActions ?? new BranchCreatedActionsService();\n this.progressEmitter = options.progressEmitter;\n this.onSkip = options.onSkip;\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n clearPendingInitSkip(): void {\n this.pendingInitSkip = null;\n }\n\n async getWorktrees(): Promise<Array<{ path: string; branch: string }>> {\n const worktreeDir = path.resolve(this.config.worktreeDir);\n if (!(await fileExists(path.join(worktreeDir, PATH_CONSTANTS.GIT_DIR)))) {\n return [];\n }\n\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n let branch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n\n if (!branch || branch === \"HEAD\") {\n const head = (await git.raw([\"rev-parse\", \"--short\", \"HEAD\"])).trim();\n branch = head ? `(detached ${head})` : \"(detached)\";\n }\n\n return [{ path: worktreeDir, branch }];\n }\n\n private get repoName(): string {\n return (this.config as RepositoryConfig).name ?? this.config.repoUrl;\n }\n\n private getCloneTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.cloneTimeoutMs ?? DEFAULT_CONFIG.CLONE_TIMEOUT_MS;\n }\n\n private getFetchTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.fetchTimeoutMs ?? DEFAULT_CONFIG.FETCH_TIMEOUT_MS;\n }\n\n private isLfsSkipEnabled(): boolean {\n return this.config.skipLfs === true;\n }\n\n private buildGitOptions(blockMs: number): Partial<SimpleGitOptions> {\n const options: Partial<SimpleGitOptions> = {\n progress: makeGitProgressHandler(this.logger, (event) => this.emitProgress(event)),\n };\n if (blockMs > 0) options.timeout = { block: blockMs };\n return options;\n }\n\n private emitProgress(event: GitProgressEvent): void {\n try {\n this.progressEmitter?.(event);\n } catch {\n // progress listeners must not break sync flow\n }\n }\n\n private async withOutcome<T>(outcome: SyncOutcomeAccumulator | undefined, operation: () => Promise<T>): Promise<T> {\n const previousOutcome = this.outcomeAccumulator;\n if (outcome) {\n this.outcomeAccumulator = outcome;\n }\n\n try {\n return await operation();\n } finally {\n if (outcome) {\n this.outcomeAccumulator = previousOutcome;\n }\n }\n }\n\n private recordSkip(\n reason: CloneSkipReason,\n logMessage: string,\n progressMessage?: string,\n logLevel: \"warn\" | \"info\" = \"warn\",\n ): void {\n if (logLevel === \"warn\") {\n this.logger.warn(logMessage);\n } else {\n this.logger.info(logMessage);\n }\n this.emitProgress({ phase: \"skip\", message: progressMessage ?? logMessage });\n try {\n this.onSkip?.(reason);\n } catch {\n // listeners must not break sync flow\n }\n this.outcomeAccumulator?.add(\n cloneSkipToOutcomeAction(reason, {\n branch: this.resolvedBranch ?? this.config.branch,\n path: this.config.worktreeDir,\n }),\n );\n }\n\n private clientFor(dir: string, blockMs: number): SimpleGit {\n return simpleGit(dir, this.buildGitOptions(blockMs)).env(this.buildGitEnv());\n }\n\n // Force a stable C locale so git's stderr is deterministic English. The\n // missing-remote-ref and LFS error classification matches on those strings\n // and would otherwise misfire under a non-English LANG/LC_ALL. simple-git's\n // .env() merges this object with process.env (PATH etc. preserved).\n private buildGitEnv(opts: { forceLfsSkip?: boolean } = {}): Record<string, string> {\n const env: Record<string, string> = { LC_ALL: \"C\", LANG: \"C\" };\n if (opts.forceLfsSkip || this.isLfsSkipEnabled()) {\n env[ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE] = \"1\";\n }\n return env;\n }\n\n private buildCloneArgs(branch: string): string[] {\n const args = [\"--branch\", branch, \"--single-branch\", \"--no-tags\", \"--progress\"];\n if (this.config.depth !== undefined) {\n args.push(\"--depth\", String(this.config.depth));\n }\n return args;\n }\n\n private getBranchRefspec(branch: string): string {\n return `+refs/heads/${branch}:refs/remotes/origin/${branch}`;\n }\n\n private async buildFetchArgs(git: SimpleGit, branch: string): Promise<string[]> {\n const args = [\"origin\", \"--prune\", \"--no-tags\", \"--progress\"];\n if (this.config.depth !== undefined && (await this.isShallowRepository(git))) {\n args.push(\"--depth\", String(this.config.depth));\n }\n args.push(this.getBranchRefspec(branch));\n return args;\n }\n\n private async configureSingleBranchRemote(git: SimpleGit, branch: string): Promise<void> {\n await git.raw([\"config\", \"--replace-all\", \"remote.origin.fetch\", this.getBranchRefspec(branch)]);\n await git.raw([\"config\", \"--replace-all\", \"remote.origin.tagOpt\", \"--no-tags\"]);\n await this.deleteStaleRemoteTrackingRefs(git, branch);\n }\n\n private recordMissingRemoteRefSkip(branch: string): void {\n this.recordSkip(\n { kind: \"missing_remote_ref\", branch, source: \"fetch_error\" },\n `Tracked branch '${branch}' is missing on remote for '${this.repoName}'. Skipping sync.`,\n `Skipping '${this.repoName}': origin/${branch} is missing`,\n );\n }\n\n private async fetchWithRecovery(\n git: SimpleGit,\n fetchArgs: string[],\n worktreeDir: string,\n branch: string,\n // checkoutBranch reports its own hard error \u2014 recording a \"Skipping sync\"\n // skip there would double-report a user-initiated action as a sync skip.\n recordSkip = true,\n ): Promise<{ skipped: boolean }> {\n const recordMissing = (): void => {\n if (recordSkip) this.recordMissingRemoteRefSkip(branch);\n };\n try {\n await git.fetch(fetchArgs);\n return { skipped: false };\n } catch (fetchError) {\n const message = getErrorMessage(fetchError);\n if (isLfsError(message)) {\n this.logger.info(`\u26A0\uFE0F LFS error during fetch for '${this.repoName}'; retrying with LFS disabled.`);\n this.emitProgress({ phase: \"fetch\", message: `Retrying fetch for '${this.repoName}' with LFS disabled` });\n const lfsSkipGit = simpleGit(worktreeDir, this.buildGitOptions(this.getFetchTimeoutMs())).env(\n this.buildGitEnv({ forceLfsSkip: true }),\n );\n try {\n await lfsSkipGit.fetch(fetchArgs);\n return { skipped: false };\n } catch (retryError) {\n // The LFS-disabled retry can itself hit a deleted remote branch \u2014\n // classify it as a soft skip too, instead of letting it escape as a\n // hard failure.\n if (isMissingRemoteRefError(getErrorMessage(retryError))) {\n recordMissing();\n return { skipped: true };\n }\n // Otherwise propagate the retry error unchanged so the outer retry\n // policy's LFS handling still sees an accurate error.\n throw retryError;\n }\n }\n if (isMissingRemoteRefError(message)) {\n recordMissing();\n return { skipped: true };\n }\n throw fetchError;\n }\n }\n\n private async hasRemoteBranch(git: SimpleGit, branch: string): Promise<boolean> {\n try {\n // simple-git resolves `show-ref --quiet` even when git exits 1, so keep\n // stdout enabled (no --quiet) to get a real reject on a missing ref \u2014\n // otherwise the post-fetch missing_remote_ref skip would never fire.\n await git.raw([\"show-ref\", \"--verify\", `refs/remotes/origin/${branch}`]);\n return true;\n } catch {\n return false;\n }\n }\n\n private async isShallowRepository(git: SimpleGit): Promise<boolean> {\n try {\n const output = await git.raw([\"rev-parse\", \"--is-shallow-repository\"]);\n return output.trim() === \"true\";\n } catch {\n return false;\n }\n }\n\n private async unshallowIfDepthRemoved(git: SimpleGit): Promise<void> {\n if (this.config.depth !== undefined) return;\n\n if (!(await this.isShallowRepository(git))) return;\n\n this.logger.info(\n `[deepen] Existing shallow clone for '${this.repoName}' has no configured depth; fetching full history...`,\n );\n await git.fetch([\"--unshallow\", \"--no-tags\"]);\n }\n\n private getDeepenTargets(): readonly number[] {\n const configuredDepth = this.config.depth;\n if (configuredDepth === undefined) return [];\n // `git fetch --depth N` can shorten a shallow repo if N is below current depth.\n // Skip targets at or below the configured depth \u2014 they would never widen history.\n return SHALLOW_RELATION_DEEPEN_TARGETS.filter((target) => target > configuredDepth);\n }\n\n private async deepenShallowHistoryToDepth(git: SimpleGit, branch: string, targetDepth: number): Promise<void> {\n this.logger.info(\n `[deepen] Shallow clone for '${this.repoName}' lacks enough history to classify origin/${branch}; ` +\n `refetching to depth ${targetDepth} before deciding.`,\n );\n this.emitProgress({\n phase: \"fetch\",\n message: `Deepening '${this.repoName}' to depth ${targetDepth} before classifying origin/${branch}`,\n });\n await git.fetch([\n \"origin\",\n \"--depth\",\n String(targetDepth),\n \"--prune\",\n \"--no-tags\",\n \"--progress\",\n this.getBranchRefspec(branch),\n ]);\n }\n\n async resolveBranch(): Promise<string> {\n if (this.resolvedBranch) return this.resolvedBranch;\n if (this.config.branch) {\n this.resolvedBranch = this.config.branch;\n this.emitProgress({ phase: \"branch\", message: `Using configured branch '${this.resolvedBranch}'` });\n return this.resolvedBranch;\n }\n this.logger.info(`No branch configured for '${this.repoName}', detecting remote default branch...`);\n this.emitProgress({ phase: \"branch\", message: `Resolving remote default branch for '${this.repoName}'` });\n this.resolvedBranch = await this.gitService.getRemoteDefaultBranch(this.config.repoUrl);\n this.logger.info(` \u21B3 resolved default branch: ${this.resolvedBranch}`);\n this.emitProgress({ phase: \"branch\", message: `Resolved default branch '${this.resolvedBranch}'` });\n return this.resolvedBranch;\n }\n\n private parseLsRemoteHeads(output: string): string[] {\n return output\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => line.split(/\\s+/)[1] ?? \"\")\n .filter((ref) => ref.startsWith(\"refs/heads/\"))\n .map((ref) => ref.slice(\"refs/heads/\".length))\n .filter((branch) => branch.length > 0);\n }\n\n async getRemoteBranches(): Promise<string[]> {\n const worktreeDir = path.resolve(this.config.worktreeDir);\n const repoArg = (await fileExists(path.join(worktreeDir, PATH_CONSTANTS.GIT_DIR))) ? \"origin\" : this.config.repoUrl;\n const git =\n repoArg === \"origin\"\n ? this.clientFor(worktreeDir, this.getFetchTimeoutMs())\n : simpleGit(this.buildGitOptions(this.getFetchTimeoutMs())).env(this.buildGitEnv());\n const output = await git.raw([\"ls-remote\", \"--heads\", repoArg]);\n return this.parseLsRemoteHeads(output);\n }\n\n private async localBranchExists(git: SimpleGit, branch: string): Promise<boolean> {\n try {\n await git.raw([\"show-ref\", \"--verify\", `refs/heads/${branch}`]);\n return true;\n } catch {\n return false;\n }\n }\n\n private async localBranchCanFastForward(git: SimpleGit, branch: string): Promise<boolean> {\n const localRef = `refs/heads/${branch}`;\n const remoteRef = `refs/remotes/origin/${branch}`;\n let localSha: string;\n let remoteSha: string;\n try {\n localSha = (await git.raw([\"rev-parse\", localRef])).trim();\n remoteSha = (await git.raw([\"rev-parse\", remoteRef])).trim();\n } catch {\n return false;\n }\n\n if (localSha === remoteSha) return true;\n\n try {\n const mergeBase = (await git.raw([\"merge-base\", localRef, remoteRef])).trim();\n return mergeBase === localSha;\n } catch {\n return false;\n }\n }\n\n private async deleteRemoteTrackingRef(git: SimpleGit, refName: string): Promise<void> {\n try {\n await git.raw([\"update-ref\", \"-d\", refName]);\n } catch {\n // Stale remote refs are best-effort cleanup; sync correctness comes from the narrowed refspec.\n }\n }\n\n private async deleteStaleRemoteTrackingRefs(git: SimpleGit, branch: string): Promise<void> {\n let refsOutput: string;\n try {\n refsOutput = await git.raw([\"for-each-ref\", \"--format=%(refname)\", \"refs/remotes/origin\"]);\n } catch {\n return;\n }\n\n const keepRef = `refs/remotes/origin/${branch}`;\n const refsToDelete = refsOutput\n .split(/\\r?\\n/)\n .map((ref) => ref.trim())\n .filter((ref) => ref && ref !== keepRef && ref !== \"refs/remotes/origin/HEAD\");\n\n for (const ref of refsToDelete) {\n await this.deleteRemoteTrackingRef(git, ref);\n }\n }\n\n private async restoreBranchAfterCheckoutFailure(\n git: SimpleGit,\n previousBranch: string,\n attemptedBranch: string,\n ): Promise<void> {\n if (!previousBranch || previousBranch === \"HEAD\" || previousBranch === attemptedBranch) return;\n\n try {\n await git.raw([\"switch\", previousBranch]);\n } catch (error) {\n this.logger.warn(\n `Failed to restore '${this.repoName}' to '${previousBranch}' after checkout failure: ${getErrorMessage(error)}`,\n );\n }\n }\n\n async checkoutBranch(branch: string, options: { allowConfigDrift?: boolean } = {}): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n\n // Checkout is a convergence action by default: it brings an existing clone\n // in line with the configured branch. Arbitrary targets would leave\n // config.branch stale, so every later sync (and every restart) soft-skips\n // with branch_mismatch after the refspec was already narrowed.\n // allowConfigDrift is the TUI's explicit opt-out for branches it just\n // created and pushed \u2014 the drift is then intentional and warned about.\n const targetBranch = await this.resolveBranch();\n if (branch !== targetBranch && !options.allowConfigDrift) {\n throw new ConfigError(\n this.config.branch\n ? `Cannot switch '${this.repoName}' to '${branch}': clone mode tracks the configured branch '${targetBranch}'. Update 'branch' in the config file first, then run checkout to converge.`\n : `Cannot switch '${this.repoName}' to '${branch}': no 'branch' is configured, so this clone tracks the remote default branch '${targetBranch}'. Set branch: \"${branch}\" in the config file first.`,\n \"CLONE_BRANCH_MISMATCH\",\n );\n }\n\n const worktreeDir = this.config.worktreeDir;\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n const originMismatch = await this.evaluateOriginMatch(git, worktreeDir);\n if (originMismatch) {\n throw new ConfigError(\n `Cannot switch '${this.repoName}' to '${branch}': ${originMismatch.progressDetail}.`,\n \"ORIGIN_MISMATCH\",\n );\n }\n\n const currentBranch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n // On a detached HEAD `git switch` only warns about leaving commits behind,\n // and the restore path below cannot return to \"HEAD\" \u2014 refuse instead of\n // stranding commits in the reflog.\n if (currentBranch === \"HEAD\") {\n throw new GitOperationError(\n \"checkout\",\n `'${this.repoName}' is on a detached HEAD; check out a branch manually (preserving any local commits) before switching the tracked branch`,\n );\n }\n if (currentBranch === branch) {\n await this.configureSingleBranchRemote(git, branch);\n this.resolvedBranch = branch;\n this.pendingInitSkip = null;\n this.warnConfigDriftAfterCheckout(branch, targetBranch);\n return;\n }\n\n const isClean = await this.gitService.checkWorktreeStatus(worktreeDir);\n if (!isClean) {\n throw new WorktreeNotCleanError(worktreeDir, [\"working tree has local changes\"]);\n }\n\n // Converge shallow state like runSyncAttempt does: with no configured depth an\n // existing shallow clone is unshallowed before the branch fetch, so switching\n // branches doesn't leave the new branch shallow while the rest is full.\n await this.unshallowIfDepthRemoved(git);\n\n const fetchArgs = await this.buildFetchArgs(git, branch);\n if ((await this.fetchWithRecovery(git, fetchArgs, worktreeDir, branch, false)).skipped) {\n throw new GitOperationError(\"checkout\", `origin/${branch} is missing for '${this.repoName}'`);\n }\n // Same post-fetch verify as runSyncAttempt: a fetch can succeed without\n // materializing the ref, which would otherwise surface downstream as a\n // misleading FastForwardError.\n if (!(await this.hasRemoteBranch(git, branch))) {\n throw new GitOperationError(\n \"checkout\",\n `origin/${branch} did not materialize after fetch for '${this.repoName}'`,\n );\n }\n\n if (await this.localBranchExists(git, branch)) {\n if (!(await this.localBranchCanFastForward(git, branch))) {\n throw new FastForwardError(branch);\n }\n\n let switched = false;\n try {\n await git.raw([\"switch\", branch]);\n switched = true;\n await git.merge([`origin/${branch}`, \"--ff-only\"]);\n } catch (error) {\n if (switched) {\n await this.restoreBranchAfterCheckoutFailure(git, currentBranch, branch);\n }\n throw error;\n }\n } else {\n await git.raw([\"switch\", \"-c\", branch, \"--track\", `origin/${branch}`]);\n }\n\n await this.configureSingleBranchRemote(git, branch);\n this.resolvedBranch = branch;\n this.pendingInitSkip = null;\n this.warnConfigDriftAfterCheckout(branch, targetBranch);\n }\n\n // resolvedBranch keeps in-session syncs on the new branch, but the config\n // file still names the old one: the next process start will soft-skip with\n // branch_mismatch on every tick until the config is updated.\n private warnConfigDriftAfterCheckout(branch: string, targetBranch: string): void {\n if (branch === targetBranch) return;\n this.logger.warn(\n `\u26A0\uFE0F '${this.repoName}' now tracks '${branch}', but the config ${\n this.config.branch ? `still says branch '${targetBranch}'` : `resolves the remote default '${targetBranch}'`\n }. Set branch: \"${branch}\" in the config file \u2014 after a restart every sync will soft-skip with branch_mismatch until it matches.`,\n );\n }\n\n async initialize(outcome?: SyncOutcomeAccumulator): Promise<void> {\n return this.withOutcome(outcome, () => this.initializeInternal());\n }\n\n private async initializeInternal(): Promise<void> {\n this.pendingInitSkip = null;\n const branch = await this.resolveBranch();\n const worktreeDir = this.config.worktreeDir;\n\n let entries: string[] | null = null;\n try {\n entries = await fs.readdir(worktreeDir);\n } catch {\n entries = null;\n }\n\n if (entries?.includes(PATH_CONSTANTS.GIT_DIR)) {\n this.emitProgress({ phase: \"clone\", message: `Validating existing clone for '${this.repoName}'` });\n const result = await this.validateExistingClone(branch);\n if (!result.valid) {\n this.recordSkip(result.skip, result.warnMessage, `Skipping '${this.repoName}': ${result.progressDetail}`);\n this.pendingInitSkip = result.skip;\n this.initialized = true;\n return;\n }\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n await this.configureSingleBranchRemote(git, branch);\n this.initialized = true;\n this.emitProgress({ phase: \"clone\", message: `Existing clone validated for '${this.repoName}'` });\n return;\n }\n\n if (entries && entries.length > 0) {\n throw new ConfigError(\n `Cannot clone into '${worktreeDir}': directory exists and is not empty. ` +\n `Remove existing contents or point worktreeDir at an empty path.`,\n \"CLONE_DESTINATION_NOT_EMPTY\",\n );\n }\n\n const cloneCreatedDir = entries === null;\n await fs.mkdir(worktreeDir, { recursive: true });\n\n this.logger.info(`Cloning '${this.config.repoUrl}' (${branch}) into '${worktreeDir}'...`);\n this.emitProgress({ phase: \"clone\", message: `Cloning '${this.repoName}' (${branch})` });\n\n const cloneClient = simpleGit(this.buildGitOptions(this.getCloneTimeoutMs())).env(this.buildGitEnv());\n\n try {\n await cloneClient.clone(this.config.repoUrl, worktreeDir, this.buildCloneArgs(branch));\n } catch (error) {\n await this.maybeCleanupPartialClone(worktreeDir, cloneCreatedDir);\n this.outcomeAccumulator?.recordFailed(\"repo\", getErrorMessage(error), {\n reason: \"clone_failed\",\n branch,\n path: worktreeDir,\n });\n throw error;\n }\n\n const worktreeGit = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n await this.configureSingleBranchRemote(worktreeGit, branch);\n\n this.logger.info(`\u2705 Clone successful.`);\n this.emitProgress({ phase: \"clone\", message: `Clone successful for '${this.repoName}'` });\n\n if (this.config.sparseCheckout) {\n this.logger.info(`Applying sparse-checkout patterns to '${worktreeDir}'...`);\n this.emitProgress({ phase: \"sparse_checkout\", message: `Applying sparse-checkout for '${this.repoName}'` });\n const sparseService = this.gitService.getSparseCheckoutService();\n await sparseService.applyToWorktree(worktreeDir, this.config.sparseCheckout);\n await worktreeGit.raw([\"checkout\", \"HEAD\"]);\n this.emitProgress({ phase: \"sparse_checkout\", message: `Sparse-checkout applied for '${this.repoName}'` });\n }\n\n this.emitProgress({ phase: \"lfs\", message: `Verifying LFS for '${this.repoName}'` });\n await this.gitService.verifyLfs(worktreeDir, branch);\n this.emitProgress({ phase: \"lfs\", message: `LFS verified for '${this.repoName}'` });\n\n await this.runInitialFileCopy(worktreeDir, branch);\n\n // Only record `created` once init is fully complete; otherwise an aborted\n // post-clone step would leave the outcome reporting both created and failed.\n this.outcomeAccumulator?.recordCreated(branch, worktreeDir);\n this.initialized = true;\n }\n\n // Detects an on-disk clone whose `origin` no longer matches the configured\n // repoUrl (e.g. repoUrl was repointed in config). Returns a skip descriptor so\n // we never fetch/ff-merge from the wrong remote; null when origin matches or\n // can't be read. Comparison is normalized so https/.git/trailing-slash\n // variants don't false-positive; the raw URLs are kept in the message.\n private async evaluateOriginMatch(\n git: SimpleGit,\n worktreeDir: string,\n ): Promise<{ skip: CloneSkipReason; warnMessage: string; progressDetail: string } | null> {\n let originUrl: string;\n try {\n originUrl = (await git.raw([\"remote\", \"get-url\", \"origin\"])).trim();\n } catch {\n this.logger.warn(`Could not read 'origin' remote URL from existing clone at '${worktreeDir}'.`);\n return null;\n }\n\n if (!originUrl || normalizeRepoUrlForComparison(originUrl) === normalizeRepoUrlForComparison(this.config.repoUrl)) {\n return null;\n }\n\n return {\n skip: { kind: \"origin_mismatch\", actual: originUrl, expected: this.config.repoUrl },\n warnMessage:\n `Existing clone at '${worktreeDir}' has origin '${originUrl}', expected '${this.config.repoUrl}'. ` +\n `Update the remote ('git remote set-url origin <url>') or point worktreeDir at a fresh path.`,\n progressDetail: `origin '${originUrl}' is not '${this.config.repoUrl}'`,\n };\n }\n\n private async validateExistingClone(\n expectedBranch: string,\n ): Promise<{ valid: true } | { valid: false; skip: CloneSkipReason; warnMessage: string; progressDetail: string }> {\n const worktreeDir = this.config.worktreeDir;\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n\n const originMismatch = await this.evaluateOriginMatch(git, worktreeDir);\n if (originMismatch) {\n return { valid: false, ...originMismatch };\n }\n\n let currentBranch: string;\n try {\n currentBranch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n return {\n valid: false,\n skip: { kind: \"head_unreadable\", phase: \"init\", error: errorMessage },\n warnMessage: `Existing clone at '${worktreeDir}' has a .git folder but reading HEAD failed: ${errorMessage}`,\n progressDetail: `could not read HEAD (${errorMessage})`,\n };\n }\n\n if (currentBranch !== expectedBranch) {\n return {\n valid: false,\n skip: {\n kind: \"branch_mismatch\",\n phase: \"init\",\n currentBranch,\n expectedBranch,\n },\n warnMessage:\n `Existing clone at '${worktreeDir}' is on branch '${currentBranch}', expected '${expectedBranch}'. ` +\n `Switch the working tree to '${expectedBranch}' or update the config.`,\n progressDetail: `current branch '${currentBranch}' is not '${expectedBranch}'`,\n };\n }\n\n return { valid: true };\n }\n\n private async maybeCleanupPartialClone(worktreeDir: string, cloneCreatedDir: boolean): Promise<void> {\n if (!cloneCreatedDir) {\n this.logger.warn(\n `Clone failed; leaving '${worktreeDir}' for manual inspection (directory existed before clone attempt).`,\n );\n return;\n }\n\n let entries: string[];\n try {\n entries = await fs.readdir(worktreeDir);\n } catch {\n return;\n }\n\n const looksIncomplete = entries.every((e) => e.startsWith(\".\"));\n const hasUsableGit =\n entries.includes(PATH_CONSTANTS.GIT_DIR) &&\n (await fileExists(path.join(worktreeDir, PATH_CONSTANTS.GIT_DIR, \"HEAD\")));\n\n if (looksIncomplete && !hasUsableGit) {\n try {\n await fs.rm(worktreeDir, { recursive: true, force: true });\n this.logger.info(`Cleaned up incomplete clone at '${worktreeDir}'.`);\n } catch (rmError) {\n this.logger.warn(`Failed to clean up incomplete clone at '${worktreeDir}': ${getErrorMessage(rmError)}`);\n }\n } else {\n this.logger.warn(\n `Clone failed; leaving '${worktreeDir}' for manual inspection (post-failure contents do not look like an empty incomplete clone).`,\n );\n }\n }\n\n private getInitMarkerPath(worktreeDir: string): string {\n return path.join(worktreeDir, PATH_CONSTANTS.GIT_DIR, PATH_CONSTANTS.CLONE_INIT_MARKER);\n }\n\n private async runInitialFileCopy(worktreeDir: string, branch: string): Promise<void> {\n const marker = this.getInitMarkerPath(worktreeDir);\n if (await fileExists(marker)) {\n return;\n }\n\n const sourceDir = this.config.__configFileDir ?? worktreeDir;\n\n await this.branchCreatedActions.copyFiles({\n config: this.config,\n branchName: branch,\n worktreePath: worktreeDir,\n sourceDir,\n logger: this.logger,\n });\n\n try {\n await fs.writeFile(marker, new Date().toISOString());\n } catch (error) {\n this.logger.warn(`Could not write clone-init marker: ${getErrorMessage(error)}`);\n }\n }\n\n async runSyncAttempt(outcome?: SyncOutcomeAccumulator): Promise<void> {\n return this.withOutcome(outcome, () => this.runSyncAttemptInternal());\n }\n\n private async runSyncAttemptInternal(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n // init ran here and recorded any skip itself; no duplicate to suppress.\n this.pendingInitSkip = null;\n return;\n }\n\n // If init already recorded a wrong-branch / unreadable-HEAD skip for the\n // current clone state during this same sync operation, don't record it a\n // second time. Consume the one-shot token; later ticks re-evaluate fresh.\n if (this.pendingInitSkip) {\n this.pendingInitSkip = null;\n return;\n }\n\n const branch = await this.resolveBranch();\n const worktreeDir = this.config.worktreeDir;\n const git = this.clientFor(worktreeDir, this.getFetchTimeoutMs());\n\n let currentBranch: string;\n try {\n currentBranch = (await git.raw([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n this.recordSkip(\n { kind: \"head_unreadable\", phase: \"sync\", error: errorMessage },\n `Could not read current branch from '${worktreeDir}': ${errorMessage}`,\n `Skipping '${this.repoName}': could not read current branch`,\n );\n return;\n }\n\n if (currentBranch !== branch) {\n this.recordSkip(\n { kind: \"branch_mismatch\", phase: \"sync\", currentBranch, expectedBranch: branch },\n `Clone at '${worktreeDir}' is on '${currentBranch}', expected '${branch}'. Skipping fetch+merge. ` +\n `Update 'branch' in the config or switch the clone back.`,\n `Skipping '${this.repoName}': current branch '${currentBranch}' is not '${branch}'`,\n );\n return;\n }\n\n // Re-check every tick (not just at init): the daemon reuses this service, so\n // a clone whose origin no longer matches repoUrl must keep being skipped\n // rather than fetching from the wrong remote.\n const originMismatch = await this.evaluateOriginMatch(git, worktreeDir);\n if (originMismatch) {\n this.recordSkip(\n originMismatch.skip,\n originMismatch.warnMessage,\n `Skipping '${this.repoName}': ${originMismatch.progressDetail}`,\n );\n return;\n }\n\n await this.unshallowIfDepthRemoved(git);\n\n await this.configureSingleBranchRemote(git, branch);\n\n const fetchArgs = await this.buildFetchArgs(git, branch);\n this.emitProgress({ phase: \"fetch\", message: `Fetching origin/${branch} for '${this.repoName}'` });\n if ((await this.fetchWithRecovery(git, fetchArgs, worktreeDir, branch)).skipped) {\n return;\n }\n this.emitProgress({ phase: \"fetch\", message: `Fetched origin/${branch} for '${this.repoName}'` });\n\n if (!(await this.hasRemoteBranch(git, branch))) {\n this.recordSkip(\n { kind: \"missing_remote_ref\", branch, source: \"post_fetch_verify\" },\n `Tracked branch '${branch}' is missing on remote for '${this.repoName}'. Skipping sync.`,\n `Skipping '${this.repoName}': origin/${branch} is missing`,\n );\n return;\n }\n\n if (this.config.sparseCheckout) {\n const sparseService = this.gitService.getSparseCheckoutService();\n try {\n if (await sparseService.needsUpdate(worktreeDir, this.config.sparseCheckout)) {\n this.emitProgress({ phase: \"sparse_checkout\", message: `Updating sparse-checkout for '${this.repoName}'` });\n await sparseService.applyToWorktree(worktreeDir, this.config.sparseCheckout);\n this.emitProgress({ phase: \"sparse_checkout\", message: `Sparse-checkout updated for '${this.repoName}'` });\n }\n } catch (error) {\n this.logger.warn(`Failed to reapply sparse-checkout for '${this.repoName}': ${getErrorMessage(error)}`);\n }\n }\n\n const isClean = await this.gitService.checkWorktreeStatus(worktreeDir);\n if (!isClean) {\n this.recordSkip(\n { kind: \"dirty_tree\" },\n `\u23ED\uFE0F Skipping ff-merge for '${this.repoName}' \u2014 working tree has local changes.`,\n `Skipping merge for '${this.repoName}': working tree has local changes`,\n \"info\",\n );\n return;\n }\n\n let relationship = await this.gitService.classifyRemoteRelationship(worktreeDir, branch);\n let lastDeepenedTo: number | null = null;\n if (relationship === \"indeterminate_shallow\") {\n for (const target of this.getDeepenTargets()) {\n await this.deepenShallowHistoryToDepth(git, branch, target);\n lastDeepenedTo = target;\n relationship = await this.gitService.classifyRemoteRelationship(worktreeDir, branch);\n if (relationship !== \"indeterminate_shallow\") break;\n }\n }\n\n if (relationship === \"up_to_date\") {\n this.logger.info(`'${this.repoName}' already up to date with origin/${branch}.`);\n this.emitProgress({\n phase: \"skip\",\n message: `'${this.repoName}' already up to date with origin/${branch}`,\n });\n this.outcomeAccumulator?.recordNoop(\"repo\", \"already_up_to_date\", {\n branch,\n path: worktreeDir,\n message: `Already up to date with origin/${branch}`,\n });\n return;\n }\n\n if (relationship !== \"fast_forward\") {\n if (relationship === \"local_ahead\") {\n this.recordSkip(\n { kind: \"ahead_unpushed\", branch },\n `\u23ED\uFE0F '${this.repoName}' has unpushed commits ahead of origin/${branch}. Skipping merge.`,\n `Skipping merge for '${this.repoName}': unpushed commits ahead of origin/${branch}`,\n \"info\",\n );\n } else if (relationship === \"indeterminate_shallow\") {\n const detail =\n lastDeepenedTo === null\n ? `no deepening attempted (configured depth already at or above all deepen targets)`\n : `deepening to ${lastDeepenedTo} commits`;\n const progressDetail =\n lastDeepenedTo === null\n ? `no deepening attempted (configured depth at/above limits)`\n : `shallow depth budget exhausted at ${lastDeepenedTo}`;\n this.recordSkip(\n { kind: \"indeterminate_shallow\", branch, deepenedTo: lastDeepenedTo },\n `\u23ED\uFE0F '${this.repoName}' could not classify origin/${branch} after ${detail}. ` +\n `Skipping merge \u2014 consider removing or raising 'depth' to unshallow.`,\n `Skipping merge for '${this.repoName}': ${progressDetail}`,\n \"info\",\n );\n } else {\n this.recordSkip(\n { kind: \"diverged\", branch },\n `\u23ED\uFE0F '${this.repoName}' has diverged from origin/${branch}. Skipping merge (no auto-reset).`,\n `Skipping merge for '${this.repoName}': diverged from origin/${branch}`,\n \"info\",\n );\n }\n return;\n }\n\n this.logger.info(`Fast-forwarding '${this.repoName}' to origin/${branch}...`);\n this.emitProgress({ phase: \"merge\", message: `Fast-forwarding '${this.repoName}' to origin/${branch}` });\n await git.merge([`origin/${branch}`, \"--ff-only\"]);\n this.logger.info(`\u2705 Updated '${this.repoName}' to origin/${branch}.`);\n this.emitProgress({ phase: \"merge\", message: `Updated '${this.repoName}' to origin/${branch}` });\n this.outcomeAccumulator?.recordUpdated(branch, worktreeDir, \"fast_forward\");\n }\n}\n", "import { GIT_CONSTANTS } from \"../constants\";\n\nimport type { Logger } from \"../services/logger.service\";\nimport type { SimpleGitProgressEvent } from \"simple-git\";\n\nexport interface GitProgressEvent {\n phase: string;\n message: string;\n progress?: number;\n processed?: number;\n total?: number;\n}\n\nexport type GitProgressEmitter = (event: GitProgressEvent) => void;\n\n/**\n * Build a progress callback for simple-git's `progress` option that:\n * - filters to clone/fetch/pull events only,\n * - emits at most one progress event per (method,stage) bucket of PROGRESS_BUCKET_PERCENT,\n * - always emits the 100% completion event,\n * - detects stage restarts (bucket regression on the same cached SimpleGit\n * instance, e.g. a second fetch) and resets the bucket so the new run\n * emits from scratch.\n *\n * State (the bucket map) is closure-local \u2014 pass one handler per SimpleGit\n * client. Keep progress logs at debug level so normal logs can stay readable\n * while interactive surfaces and MCP notifications consume structured events.\n */\nexport function makeGitProgressHandler(\n logger: Logger,\n emitProgress?: GitProgressEmitter,\n): (event: SimpleGitProgressEvent) => void {\n const lastBucket = new Map<string, number>();\n return (event: SimpleGitProgressEvent): void => {\n if (event.method !== \"fetch\" && event.method !== \"clone\" && event.method !== \"pull\") return;\n const key = `${event.method}:${event.stage}`;\n const bucket = Math.floor(event.progress / GIT_CONSTANTS.PROGRESS_BUCKET_PERCENT);\n let last = lastBucket.get(key) ?? -1;\n if (bucket < last) last = -1;\n if (bucket <= last && event.progress < 100) return;\n lastBucket.set(key, bucket);\n const total = event.total > 0 ? `${event.processed}/${event.total}` : `${event.processed}`;\n const message = `${event.method} ${event.stage}: ${event.progress}% (${total})`;\n logger.debug(` \u21B3 ${message}`);\n emitProgress?.({\n phase: event.method,\n message,\n progress: event.progress,\n processed: event.processed,\n total: event.total,\n });\n };\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport { glob } from \"glob\";\n\nimport { fileExists } from \"../utils/file-exists\";\n\nconst DEFAULT_IGNORE_PATTERNS = [\n \"**/node_modules/**\",\n \"**/.git/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/.next/**\",\n \"**/coverage/**\",\n];\n\nexport interface FileCopyResult {\n copied: string[];\n skipped: string[];\n errors: Array<{ file: string; error: string }>;\n}\n\nexport class FileCopyService {\n /**\n * Copy files matching patterns from source to destination directory.\n * Skips files that already exist at destination.\n * Preserves directory structure relative to source.\n */\n async copyFiles(sourceDir: string, destDir: string, patterns: string[]): Promise<FileCopyResult> {\n const result: FileCopyResult = {\n copied: [],\n skipped: [],\n errors: [],\n };\n\n if (!patterns || patterns.length === 0) {\n return result;\n }\n\n const filesToCopy = await this.expandPatterns(sourceDir, patterns);\n\n for (const relativePath of filesToCopy) {\n const sourcePath = path.join(sourceDir, relativePath);\n const destPath = path.join(destDir, relativePath);\n\n try {\n const copied = await this.copyFile(sourcePath, destPath);\n if (copied) {\n result.copied.push(relativePath);\n } else {\n result.skipped.push(relativePath);\n }\n } catch (error) {\n result.errors.push({\n file: relativePath,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return result;\n }\n\n private async expandPatterns(sourceDir: string, patterns: string[]): Promise<string[]> {\n const allFiles = new Set<string>();\n\n for (const pattern of patterns) {\n try {\n const matches = await glob(pattern, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n ignore: DEFAULT_IGNORE_PATTERNS,\n });\n\n for (const match of matches) {\n allFiles.add(match);\n }\n } catch {\n // Pattern matching failed, skip silently\n }\n }\n\n return Array.from(allFiles);\n }\n\n private async copyFile(sourcePath: string, destPath: string): Promise<boolean> {\n if (await fileExists(destPath)) {\n return false;\n }\n\n const destDir = path.dirname(destPath);\n await fs.mkdir(destDir, { recursive: true });\n\n await fs.copyFile(sourcePath, destPath);\n return true;\n }\n}\n", "import { FileCopyService } from \"./file-copy.service\";\n\nimport type { HookExecutionService } from \"./hook-execution.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { Config, HookContext } from \"../types\";\n\nexport interface CopyFilesParams {\n config: Pick<Config, \"filesToCopyOnBranchCreate\">;\n branchName: string;\n worktreePath: string;\n sourceDir: string;\n logger: Logger;\n}\n\nexport interface RunHooksParams {\n config: Pick<Config, \"hooks\" | \"repoUrl\">;\n repoName: string;\n branchName: string;\n worktreePath: string;\n baseBranch: string;\n logger: Logger;\n hookExecutionService: HookExecutionService;\n}\n\nexport class BranchCreatedActionsService {\n private fileCopyService: FileCopyService;\n\n constructor(fileCopyService?: FileCopyService) {\n this.fileCopyService = fileCopyService ?? new FileCopyService();\n }\n\n async copyFiles(params: CopyFilesParams): Promise<void> {\n const { config, sourceDir, worktreePath, branchName, logger } = params;\n const patterns = config.filesToCopyOnBranchCreate;\n if (!patterns?.length) return;\n\n try {\n const result = await this.fileCopyService.copyFiles(sourceDir, worktreePath, patterns);\n\n if (result.copied.length > 0) {\n logger.info(`\uD83D\uDCCB Copied ${result.copied.length} file(s) to '${branchName}': ${result.copied.join(\", \")}`);\n }\n if (result.errors.length > 0) {\n logger.warn(`\u26A0\uFE0F Failed to copy ${result.errors.length} file(s) to '${branchName}':`);\n for (const err of result.errors) {\n logger.warn(` - ${err.file}: ${err.error}`);\n }\n }\n } catch (error) {\n logger.error(`Failed to copy files to '${branchName}': ${error}`);\n }\n }\n\n runHooks(params: RunHooksParams): void {\n const { config, branchName, worktreePath, repoName, baseBranch, logger, hookExecutionService } = params;\n if (!config.hooks?.onBranchCreated?.length) return;\n\n const context: HookContext = {\n branchName,\n worktreePath,\n repoName,\n baseBranch,\n repoUrl: config.repoUrl,\n };\n\n logger.info(`Running ${config.hooks.onBranchCreated.length} hook(s) for branch '${branchName}'...`);\n\n hookExecutionService.executeOnBranchCreated(config.hooks, context, {\n onStdout: (data) => logger.info(`[hook] ${data}`),\n onStderr: (data) => logger.warn(`[hook] ${data}`),\n onError: (command, error) => logger.error(`[hook] Failed to execute '${command}': ${error.message}`),\n onComplete: (command, exitCode) => {\n if (exitCode === 0) {\n logger.info(`[hook] Command completed successfully`);\n } else if (exitCode !== null) {\n logger.warn(`[hook] Command exited with code ${exitCode}`);\n }\n },\n });\n }\n}\n", "import type { CloneSkipReason } from \"../services/clone-sync.service\";\n\nexport function formatCloneSkipReason(reason: CloneSkipReason): string {\n switch (reason.kind) {\n case \"branch_mismatch\":\n return reason.phase === \"init\"\n ? `clone is on '${reason.currentBranch}', expected '${reason.expectedBranch}' (since process start) \u2014 update 'branch' in the config or switch the clone back`\n : `clone is on '${reason.currentBranch}', expected '${reason.expectedBranch}' \u2014 update 'branch' in the config or switch the clone back`;\n case \"head_unreadable\":\n return `could not read HEAD: ${reason.error}`;\n case \"dirty_tree\":\n return `working tree has local changes`;\n case \"diverged\":\n return `diverged from origin/${reason.branch}`;\n case \"ahead_unpushed\":\n return `unpushed commits ahead of origin/${reason.branch}`;\n case \"missing_remote_ref\":\n return reason.source === \"fetch_error\"\n ? `origin/${reason.branch} missing on remote (fetch error)`\n : `origin/${reason.branch} pruned after fetch`;\n case \"indeterminate_shallow\":\n return reason.deepenedTo === null\n ? `unable to classify origin/${reason.branch} (no deepening attempted \u2014 configured depth already at or above all deepen targets) \u2014 remove 'depth' to unshallow`\n : `unable to classify origin/${reason.branch} after deepening shallow history to ${reason.deepenedTo} commits \u2014 remove or raise 'depth' to unshallow`;\n case \"origin_mismatch\":\n return `clone origin is '${reason.actual}', expected '${reason.expected}'`;\n default: {\n const _exhaustive: never = reason;\n return _exhaustive;\n }\n }\n}\n", "import { formatCloneSkipReason } from \"../utils/clone-skip-format\";\n\nimport type { CloneSkipReason } from \"./clone-sync.service\";\nimport type { SyncOutcome, SyncOutcomeAction, SyncOutcomeCounts, SyncOutcomeMode, SyncOutcomeScope } from \"../types\";\n\nconst EMPTY_COUNTS: SyncOutcomeCounts = {\n created: 0,\n removed: 0,\n updated: 0,\n skipped: 0,\n preserved: 0,\n failed: 0,\n noop: 0,\n};\n\nfunction cloneCounts(counts: SyncOutcomeCounts): SyncOutcomeCounts {\n return { ...counts };\n}\n\nfunction cloneAction(action: SyncOutcomeAction): SyncOutcomeAction {\n return { ...action } as SyncOutcomeAction;\n}\n\nfunction countKeyFor(action: SyncOutcomeAction): keyof SyncOutcomeCounts {\n switch (action.kind) {\n case \"created\":\n return \"created\";\n case \"removed\":\n return \"removed\";\n case \"updated\":\n return \"updated\";\n case \"skipped\":\n return \"skipped\";\n case \"preserved-diverged\":\n return \"preserved\";\n case \"failed\":\n return \"failed\";\n case \"noop\":\n return \"noop\";\n default: {\n const _exhaustive: never = action;\n return _exhaustive;\n }\n }\n}\n\nexport class SyncOutcomeAccumulator {\n private counts: SyncOutcomeCounts = cloneCounts(EMPTY_COUNTS);\n private actions: SyncOutcomeAction[] = [];\n\n constructor(\n private readonly options: {\n mode: SyncOutcomeMode;\n repoName?: string;\n },\n ) {}\n\n add(action: SyncOutcomeAction): void {\n this.actions.push(action);\n this.counts[countKeyFor(action)]++;\n }\n\n recordCreated(branch: string, path: string): void {\n this.add({ kind: \"created\", branch, path });\n }\n\n recordRemoved(branch: string, path: string, warning?: string): void {\n this.add({ kind: \"removed\", branch, path, ...(warning !== undefined && { warning }) });\n }\n\n recordUpdated(branch: string, path: string, reason?: string): void {\n this.add({ kind: \"updated\", branch, path, reason });\n }\n\n recordNoop(\n scope: SyncOutcomeScope,\n reason: string,\n details: { branch?: string; path?: string; message?: string },\n ): void {\n this.add({ kind: \"noop\", scope, reason, ...details });\n }\n\n recordSkipped(\n scope: SyncOutcomeScope,\n reason: string,\n details: { branch?: string; path?: string; message?: string },\n ): void {\n this.add({ kind: \"skipped\", scope, reason, ...details });\n }\n\n recordPreservedDiverged(branch: string, path: string, preservedPath: string): void {\n this.add({ kind: \"preserved-diverged\", branch, path, preservedPath });\n }\n\n recordFailed(\n scope: SyncOutcomeScope,\n error: string,\n details: { reason?: string; branch?: string; path?: string } = {},\n ): void {\n this.add({ kind: \"failed\", scope, error, ...details });\n }\n\n getCounts(): SyncOutcomeCounts {\n return cloneCounts(this.counts);\n }\n\n snapshot(): { counts: SyncOutcomeCounts; actions: SyncOutcomeAction[] } {\n return {\n counts: cloneCounts(this.counts),\n actions: this.actions.map(cloneAction),\n };\n }\n\n restore(snapshot: { counts: SyncOutcomeCounts; actions: SyncOutcomeAction[] }): void {\n this.counts = cloneCounts(snapshot.counts);\n this.actions = snapshot.actions.map(cloneAction);\n }\n\n toOutcome(durationMs?: number): SyncOutcome {\n return {\n repoName: this.options.repoName,\n mode: this.options.mode,\n started: true,\n counts: cloneCounts(this.counts),\n actions: this.actions.map(cloneAction),\n durationMs,\n };\n }\n}\n\nexport function createEmptySyncOutcome(mode: SyncOutcomeMode, repoName?: string, durationMs?: number): SyncOutcome {\n return {\n repoName,\n mode,\n started: true,\n counts: cloneCounts(EMPTY_COUNTS),\n actions: [],\n durationMs,\n };\n}\n\nexport function cloneSkipToOutcomeAction(\n reason: CloneSkipReason,\n details: { branch?: string; path?: string } = {},\n): SyncOutcomeAction {\n const message = formatCloneSkipReason(reason);\n const branch =\n \"branch\" in reason ? reason.branch : reason.kind === \"branch_mismatch\" ? reason.expectedBranch : details.branch;\n\n return {\n kind: \"skipped\",\n scope: \"repo\",\n reason: `clone_${reason.kind}`,\n branch,\n path: details.path,\n message,\n };\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { DEFAULT_CONFIG, MAINTENANCE_CONSTANTS, PATH_CONSTANTS } from \"../constants\";\nimport { atomicWriteFile } from \"../utils/atomic-write\";\nimport { parseDuration } from \"../utils/date-filter\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\nimport { REPOSITORY_MODES, resolveMode } from \"../utils/repo-mode\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { Config } from \"../types\";\nimport type { GitService } from \"./git.service\";\nimport type { SimpleGit } from \"simple-git\";\n\nexport interface MaintenanceState {\n lastAttemptAt?: string;\n lastSuccessAt?: string;\n lastFailureAt?: string;\n lastError?: string;\n}\n\ninterface MaintenanceTarget {\n /** Directory `git gc` runs in (the clone working dir, or the bare repo). */\n cwd: string;\n /** Git object-store dir that holds the persisted state file. */\n gitDir: string;\n}\n\nexport type GitFactory = (cwd: string) => SimpleGit;\n\n/**\n * Periodic `git gc` for the repository object store. Reclaims unreachable\n * objects (e.g. left by clone-mode single-branch ref narrowing and branch\n * churn) and consolidates pack files. Throttled by a persisted timestamp so a\n * daemon restart or repeated `runOnce` invocations don't re-run it every tick.\n *\n * Callers MUST already hold the repository operation lock \u2014 `runIfDueUnlocked`\n * mirrors `WorktreeSyncService.initializeUnlocked` and never re-acquires it.\n */\nexport class GitMaintenanceService {\n private logger: Logger;\n private gitFactory: GitFactory;\n\n constructor(\n private config: Config,\n private gitService: GitService,\n logger?: Logger,\n gitFactory: GitFactory = (cwd) => simpleGit(cwd),\n ) {\n this.logger = logger ?? Logger.createDefault();\n this.gitFactory = gitFactory;\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n isEnabled(): boolean {\n return this.config.maintenance?.enabled ?? DEFAULT_CONFIG.MAINTENANCE.ENABLED;\n }\n\n private getIntervalMs(): number {\n const fallback = parseDuration(DEFAULT_CONFIG.MAINTENANCE.INTERVAL)!;\n const raw = this.config.maintenance?.interval;\n if (raw === undefined) {\n return fallback;\n }\n const parsed = parseDuration(raw);\n // Zero would disable throttling entirely \u2014 treat it like any other invalid value.\n if (parsed === null || parsed <= 0) {\n this.logger.warn(`Invalid maintenance.interval '${raw}', using default ${DEFAULT_CONFIG.MAINTENANCE.INTERVAL}.`);\n return fallback;\n }\n return parsed;\n }\n\n private resolveTarget(): MaintenanceTarget {\n if (resolveMode(this.config) === REPOSITORY_MODES.CLONE) {\n const cwd = path.resolve(this.config.worktreeDir);\n return { cwd, gitDir: path.join(cwd, PATH_CONSTANTS.GIT_DIR) };\n }\n const bare = this.gitService.getBareRepoPath();\n return { cwd: bare, gitDir: bare };\n }\n\n private getStatePath(gitDir: string): string {\n return path.join(gitDir, MAINTENANCE_CONSTANTS.STATE_FILENAME);\n }\n\n private async readState(statePath: string): Promise<MaintenanceState> {\n try {\n const parsed: unknown = JSON.parse(await fs.readFile(statePath, \"utf-8\"));\n // Reject arrays and non-objects: spreading into a fresh plain object means a\n // corrupt file (e.g. `[]`) can't silently swallow the lastAttemptAt we set on\n // it, which would otherwise break throttling and re-run gc every sync.\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return {};\n }\n return { ...(parsed as MaintenanceState) };\n } catch {\n return {};\n }\n }\n\n private async writeState(statePath: string, state: MaintenanceState): Promise<void> {\n try {\n await atomicWriteFile(statePath, JSON.stringify(state, null, 2));\n } catch (error) {\n this.logger.warn(`Failed to persist maintenance state: ${getErrorMessage(error)}`);\n }\n }\n\n isDue(state: MaintenanceState, now: number): boolean {\n if (!state.lastAttemptAt) {\n return true;\n }\n const last = new Date(state.lastAttemptAt).getTime();\n if (Number.isNaN(last)) {\n return true;\n }\n return now - last >= this.getIntervalMs();\n }\n\n /**\n * Run `git gc` if maintenance is enabled and due. MUST be called while the\n * repository operation lock is already held. Never throws: a gc failure is\n * recorded and warned so it cannot fail the surrounding sync. The attempt\n * timestamp is persisted even on failure, so a perpetually-failing gc is\n * throttled instead of retried every tick.\n */\n async runIfDueUnlocked(now: number = Date.now()): Promise<void> {\n if (!this.isEnabled()) {\n return;\n }\n\n // Outer guard: maintenance is best-effort and runs at the tail of sync(). Any\n // failure here \u2014 target resolution, state IO, the gc itself \u2014 must be swallowed\n // so it can never fail an otherwise-successful sync.\n try {\n const { cwd, gitDir } = this.resolveTarget();\n\n try {\n await fs.access(gitDir);\n } catch {\n // Repo not initialized yet \u2014 nothing to maintain.\n return;\n }\n\n const statePath = this.getStatePath(gitDir);\n const state = await this.readState(statePath);\n if (!this.isDue(state, now)) {\n return;\n }\n\n const aggressive = this.config.maintenance?.aggressive ?? false;\n const args = aggressive ? [\"gc\", \"--prune=now\"] : [\"gc\"];\n const nowIso = new Date(now).toISOString();\n state.lastAttemptAt = nowIso;\n\n this.logger.info(`\uD83E\uDDF9 Running git ${args.join(\" \")} (maintenance)...`);\n try {\n await this.gitFactory(cwd).raw(args);\n state.lastSuccessAt = nowIso;\n delete state.lastError;\n this.logger.info(\"\uD83E\uDDF9 Maintenance complete.\");\n } catch (error) {\n state.lastFailureAt = nowIso;\n state.lastError = getErrorMessage(error);\n this.logger.warn(`\u26A0\uFE0F Maintenance (git ${args.join(\" \")}) failed: ${state.lastError}`);\n } finally {\n await this.writeState(statePath, state);\n }\n } catch (error) {\n this.logger.warn(`\u26A0\uFE0F Maintenance skipped due to an unexpected error: ${getErrorMessage(error)}`);\n }\n }\n}\n", "import * as fs from \"fs/promises\";\n\nimport { ERROR_MESSAGES } from \"../constants\";\n\n// Write to temp file then rename for atomicity \u2014 prevents corruption on crash.\n// Unique suffix avoids collisions between concurrent writers of the same file.\nexport async function atomicWriteFile(filePath: string, content: string): Promise<void> {\n const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;\n let renamed = false;\n try {\n // fsync before rename: without it a crash can leave the rename durable\n // but the content not, yielding a valid-looking empty/truncated file.\n const handle = await fs.open(tmpPath, \"w\");\n try {\n await handle.writeFile(content, \"utf-8\");\n await handle.sync();\n } finally {\n await handle.close();\n }\n try {\n await fs.rename(tmpPath, filePath);\n renamed = true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === ERROR_MESSAGES.EXDEV) {\n await fs.copyFile(tmpPath, filePath);\n } else {\n throw err;\n }\n }\n } finally {\n if (!renamed) {\n await fs.unlink(tmpPath).catch(() => undefined);\n }\n }\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 simpleGit from \"simple-git\";\n\nimport { DEFAULT_CONFIG, ENV_CONSTANTS, GIT_CONSTANTS, PATH_CONSTANTS } from \"../constants\";\nimport { GitOperationError, WorktreeError, WorktreeNotCleanError } from \"../errors\";\nimport { probePathExists } from \"../utils/file-exists\";\nimport { makeGitProgressHandler } from \"../utils/git-progress\";\nimport { getDefaultBareRepoDir } from \"../utils/git-url\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\nimport { quarantineDirectory } from \"../utils/quarantine\";\nimport { parseWorktreeListPorcelain } from \"../utils/worktree-list-parser\";\n\nimport { Logger } from \"./logger.service\";\nimport { SparseCheckoutService } from \"./sparse-checkout.service\";\nimport { WorktreeMetadataService } from \"./worktree-metadata.service\";\nimport { WorktreeStatusService } from \"./worktree-status.service\";\n\nimport type { WorktreeStatusResult } from \"./worktree-status.service\";\nimport type { Config } from \"../types\";\nimport type { SyncMetadata } from \"../types/sync-metadata\";\nimport type { GitProgressEmitter } from \"../utils/git-progress\";\nimport type { SimpleGit, SimpleGitOptions } from \"simple-git\";\n\nexport type RemoteRelationship = \"up_to_date\" | \"fast_forward\" | \"local_ahead\" | \"diverged\" | \"indeterminate_shallow\";\n\nexport type GitServiceOptions = Pick<\n Config,\n | \"repoUrl\"\n | \"worktreeDir\"\n | \"bareRepoDir\"\n | \"skipLfs\"\n | \"debug\"\n | \"sparseCheckout\"\n | \"fetchTimeoutMs\"\n | \"cloneTimeoutMs\"\n>;\n\n// simple-git blocks EDITOR / GIT_EDITOR / GIT_SEQUENCE_EDITOR unless allowUnsafeEditor is set;\n// strip them when forwarding process.env so a user's shell EDITOR doesn't break read-only commands.\nfunction sanitizeGitEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n const sanitized = { ...env };\n delete sanitized.EDITOR;\n delete sanitized.GIT_EDITOR;\n delete sanitized.GIT_SEQUENCE_EDITOR;\n return sanitized;\n}\n\nexport class GitService {\n private git: SimpleGit | null = null;\n private bareRepoPath: string;\n private mainWorktreePath: string;\n private defaultBranch: string = GIT_CONSTANTS.DEFAULT_BRANCH; // Will be updated after detection\n private metadataService: WorktreeMetadataService;\n private statusService: WorktreeStatusService;\n private sparseCheckoutService: SparseCheckoutService;\n private logger: Logger;\n private lfsSkipOverride = false;\n private gitInstances = new Map<string, SimpleGit>();\n\n constructor(\n private config: GitServiceOptions,\n logger?: Logger,\n private progressEmitter?: GitProgressEmitter,\n ) {\n this.logger = logger ?? Logger.createDefault(undefined, config.debug);\n this.bareRepoPath = this.config.bareRepoDir || getDefaultBareRepoDir(this.config.repoUrl);\n this.mainWorktreePath = path.join(this.config.worktreeDir, GIT_CONSTANTS.DEFAULT_BRANCH); // Temporary, will be updated\n this.metadataService = new WorktreeMetadataService(this.logger);\n this.statusService = new WorktreeStatusService({ skipLfs: this.config.skipLfs }, this.logger);\n this.sparseCheckoutService = new SparseCheckoutService(this.logger);\n }\n\n getSparseCheckoutService(): SparseCheckoutService {\n return this.sparseCheckoutService;\n }\n\n private getFetchTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.fetchTimeoutMs ?? DEFAULT_CONFIG.FETCH_TIMEOUT_MS;\n }\n\n private getCloneTimeoutMs(): number {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) return 0;\n return this.config.cloneTimeoutMs ?? DEFAULT_CONFIG.CLONE_TIMEOUT_MS;\n }\n\n private getCachedGit(dirPath: string, useLfsSkip = false): SimpleGit {\n const key = `${path.resolve(dirPath)}::${useLfsSkip ? \"1\" : \"0\"}`;\n let git = this.gitInstances.get(key);\n if (!git) {\n const base = simpleGit(dirPath, this.buildSimpleGitOptions(this.getFetchTimeoutMs()));\n git = useLfsSkip ? base.env({ [ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE]: \"1\" }) : base;\n this.gitInstances.set(key, git);\n }\n return git;\n }\n\n private buildSimpleGitOptions(blockMs: number): Partial<SimpleGitOptions> {\n const options: Partial<SimpleGitOptions> = {\n progress: makeGitProgressHandler(this.logger, (event) => this.progressEmitter?.(event)),\n };\n if (blockMs > 0) options.timeout = { block: blockMs };\n return options;\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n this.sparseCheckoutService.updateLogger(logger);\n }\n\n async initialize(): Promise<SimpleGit> {\n const { repoUrl } = this.config;\n\n try {\n // Check if bare repo already exists\n await fs.access(path.join(this.bareRepoPath, \"HEAD\"));\n } catch {\n // Clone as bare repository\n this.logger.info(`Cloning from \"${repoUrl}\" as bare repository into \"${this.bareRepoPath}\"...`);\n await fs.mkdir(path.dirname(this.bareRepoPath), { recursive: true });\n const cloneBase = simpleGit(this.buildSimpleGitOptions(this.getCloneTimeoutMs()));\n const cloneGit = this.isLfsSkipEnabled()\n ? cloneBase.env({ [ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE]: \"1\" })\n : cloneBase;\n await cloneGit.clone(repoUrl, this.bareRepoPath, [\"--bare\", \"--progress\"]);\n this.logger.info(\"\u2705 Clone successful.\");\n }\n\n // Configure bare repository for worktrees\n const bareGit = this.getCachedGit(this.bareRepoPath);\n\n // Check if fetch config already exists\n try {\n const existingConfig = await bareGit.raw([\"config\", \"--get-all\", \"remote.origin.fetch\"]);\n const targetConfig = \"+refs/heads/*:refs/remotes/origin/*\";\n\n if (!existingConfig.includes(targetConfig)) {\n await bareGit.addConfig(\"remote.origin.fetch\", targetConfig);\n }\n } catch {\n // Config doesn't exist, add it\n await bareGit.addConfig(\"remote.origin.fetch\", \"+refs/heads/*:refs/remotes/origin/*\");\n }\n\n // Always fetch to ensure remote refs are up-to-date\n // This is needed for branch creation UI even when repo already exists\n this.logger.info(\"Fetching remote branches...\");\n await bareGit.fetch([\"--all\", \"--progress\"]);\n\n // Detect the default branch (works from local refs even without fetch)\n this.defaultBranch = await this.detectDefaultBranch(bareGit);\n this.mainWorktreePath = path.join(this.config.worktreeDir, this.defaultBranch);\n\n // Check if main worktree exists\n let needsMainWorktree = true;\n try {\n const worktrees = await this.getWorktreesFromBare(bareGit);\n needsMainWorktree = !worktrees.some((w) => path.resolve(w.path) === path.resolve(this.mainWorktreePath));\n } catch {\n // If worktree list fails, assume we need main worktree\n }\n\n if (needsMainWorktree) {\n // Create main worktree if it doesn't exist\n this.logger.info(`Creating ${this.defaultBranch} worktree at \"${this.mainWorktreePath}\"...`);\n await fs.mkdir(this.config.worktreeDir, { recursive: true });\n // Use absolute path for worktree add to avoid relative path issues\n const absoluteWorktreePath = path.resolve(this.mainWorktreePath);\n\n // Check if local branch exists\n const branches = await bareGit.branch();\n const defaultBranchExists = branches.all.includes(this.defaultBranch);\n\n const useNoCheckoutMain = !!this.config.sparseCheckout;\n const noCheckoutFlagMain = useNoCheckoutMain ? [\"--no-checkout\"] : [];\n\n try {\n if (defaultBranchExists) {\n await bareGit.raw([\"worktree\", \"add\", ...noCheckoutFlagMain, absoluteWorktreePath, this.defaultBranch]);\n const worktreeGit = this.getCachedGit(absoluteWorktreePath, this.isLfsSkipEnabled());\n await worktreeGit.branch([\"--set-upstream-to\", `origin/${this.defaultBranch}`, this.defaultBranch]);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, this.defaultBranch, false);\n } else {\n await bareGit.raw([\n \"worktree\",\n \"add\",\n ...noCheckoutFlagMain,\n \"--track\",\n \"-b\",\n this.defaultBranch,\n absoluteWorktreePath,\n `origin/${this.defaultBranch}`,\n ]);\n await this.runSparseStepWithRollback(bareGit, absoluteWorktreePath, this.defaultBranch, true);\n }\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes(\"already exists\")) {\n this.logger.info(\n `${this.defaultBranch} worktree directory already exists at '${absoluteWorktreePath}', skipping creation.`,\n );\n } else {\n throw error;\n }\n }\n\n // Ensure the worktree is registered by checking it exists in the list\n const updatedWorktrees = await this.getWorktreesFromBare(bareGit);\n const mainWorktreeRegistered = updatedWorktrees.some(\n (w) => path.resolve(w.path) === path.resolve(this.mainWorktreePath),\n );\n\n if (!mainWorktreeRegistered) {\n // Only warn in non-test environments as this is common in tests due to Git state\n if (process.env.NODE_ENV !== ENV_CONSTANTS.NODE_ENV_TEST) {\n this.logger.warn(`Main worktree was created but not found in worktree list. This may cause issues.`);\n }\n }\n }\n\n // Use the main worktree as our primary git instance\n this.git = this.getCachedGit(this.mainWorktreePath);\n return this.git;\n }\n\n getGit(): SimpleGit {\n if (!this.git) {\n throw new Error(\"Git service not initialized. Call initialize() first.\");\n }\n return this.git;\n }\n\n isInitialized(): boolean {\n return this.git !== null;\n }\n\n getDefaultBranch(): string {\n return this.defaultBranch;\n }\n\n getBareRepoPath(): string {\n return this.bareRepoPath;\n }\n\n async getRemoteDefaultBranch(repoUrl: string): Promise<string> {\n const git = simpleGit(this.buildSimpleGitOptions(this.getFetchTimeoutMs()));\n\n try {\n const out = await git.raw([\"ls-remote\", \"--symref\", repoUrl, \"HEAD\"]);\n const match = out.match(/^ref: refs\\/heads\\/(\\S+)\\s+HEAD/m);\n if (match && match[1]) {\n return match[1];\n }\n } catch {\n /* fall through to probe candidates */\n }\n\n // symref HEAD was unavailable/unparsed: probe common branch names, but only\n // auto-pick when the choice is unambiguous. Guessing by fixed priority when\n // several exist can silently track the wrong branch (e.g. 'main' when the\n // remote's real default is 'master').\n const existing: string[] = [];\n for (const candidate of GIT_CONSTANTS.COMMON_DEFAULT_BRANCHES) {\n try {\n const out = await git.raw([\"ls-remote\", \"--exit-code\", repoUrl, `refs/heads/${candidate}`]);\n if (out.trim().length > 0) {\n existing.push(candidate);\n }\n } catch {\n /* candidate missing \u2014 try next */\n }\n }\n\n if (existing.length === 1) {\n this.logger.warn(\n `Could not read symref HEAD for '${repoUrl}'; using the only common branch found ('${existing[0]}') as the default.`,\n );\n return existing[0];\n }\n\n if (existing.length > 1) {\n throw new Error(\n `Unable to detect default branch for '${repoUrl}': symref HEAD is unavailable and multiple common branches exist (${existing.join(\", \")}). ` +\n `Set 'branch' explicitly in the repository config.`,\n );\n }\n\n throw new Error(\n `Unable to detect default branch for '${repoUrl}'. ` +\n `Set 'branch' explicitly in the repository config or ensure the remote is reachable.`,\n );\n }\n\n async verifyLfs(worktreePath: string, label: string): Promise<void> {\n if (this.isLfsSkipEnabled()) return;\n await this.verifyLfsFilesDownloaded(worktreePath, label);\n }\n\n async fetchAll(): Promise<void> {\n this.assertInitialized();\n this.logger.info(\"Fetching latest data from remote...\");\n const git = this.getCachedGit(this.mainWorktreePath, this.isLfsSkipEnabled());\n await git.fetch([\"--all\", \"--prune\", \"--progress\"]);\n }\n\n async fetchBranch(branchName: string): Promise<void> {\n this.assertInitialized();\n const git = this.getCachedGit(this.mainWorktreePath, this.isLfsSkipEnabled());\n await git.fetch([\"origin\", branchName, \"--prune\", \"--progress\"]);\n }\n\n private assertInitialized(): void {\n if (!this.git) {\n throw new Error(\"Git service not initialized. Call initialize() first.\");\n }\n }\n\n async getRemoteBranches(): Promise<string[]> {\n const git = this.getGit();\n const branches = await git.branch([\"-r\"]);\n return branches.all\n .filter((b) => b.startsWith(\"origin/\") && !b.endsWith(\"/HEAD\"))\n .map((b) => b.replace(\"origin/\", \"\"))\n .filter((b) => b !== \"origin\" && b.length > 0);\n }\n\n async getRemoteBranchesWithActivity(): Promise<{ branch: string; lastActivity: Date }[]> {\n const git = this.getGit();\n // Use for-each-ref to get branch names with their last commit dates\n const result = await git.raw([\n \"for-each-ref\",\n \"--format=%(refname:short)|%(committerdate:iso8601)\",\n \"refs/remotes/origin\",\n ]);\n\n const branches: { branch: string; lastActivity: Date }[] = [];\n const lines = result\n .trim()\n .split(\"\\n\")\n .filter((line) => line);\n\n for (const line of lines) {\n const [ref, dateStr] = line.split(\"|\", 2);\n if (ref && dateStr && !ref.endsWith(\"/HEAD\")) {\n const branch = ref.replace(\"origin/\", \"\");\n // Skip invalid branch names\n if (branch === \"origin\" || branch.length === 0) {\n continue;\n }\n const lastActivity = new Date(dateStr);\n // Skip if the date is invalid\n if (!isNaN(lastActivity.getTime())) {\n branches.push({ branch, lastActivity });\n }\n }\n }\n\n return branches;\n }\n\n private async verifyLfsFilesDownloaded(worktreePath: string, branchName: string): Promise<void> {\n const worktreeGit = this.config.sparseCheckout\n ? simpleGit(worktreePath).env({ ...sanitizeGitEnv(process.env), [ENV_CONSTANTS.GIT_ATTR_SOURCE]: \"HEAD\" })\n : this.getCachedGit(worktreePath);\n\n try {\n const lfsFiles = await worktreeGit.raw([\"lfs\", \"ls-files\", \"--name-only\"]);\n let lfsFileList = lfsFiles\n .trim()\n .split(\"\\n\")\n .filter((f) => f.length > 0);\n\n if (lfsFileList.length === 0) {\n return;\n }\n\n // GIT_ATTR_SOURCE=HEAD lists every LFS file declared in HEAD's .gitattributes,\n // including ones outside the sparse-checkout cone that aren't on disk. Sampling\n // those would burn the 30s retry loop on guaranteed-missing files.\n if (this.config.sparseCheckout) {\n const existence = await Promise.all(\n lfsFileList.map(async (f) => {\n try {\n await fs.access(path.join(worktreePath, f));\n return f;\n } catch {\n return null;\n }\n }),\n );\n lfsFileList = existence.filter((f): f is string => f !== null);\n if (lfsFileList.length === 0) {\n return;\n }\n }\n\n if (this.config.debug) {\n this.logger.info(` - Verifying ${lfsFileList.length} LFS files are downloaded...`);\n }\n\n const sampleSize = Math.min(5, lfsFileList.length);\n const samplesToCheck = [];\n for (let i = 0; i < sampleSize; i++) {\n const randomIndex = Math.floor(Math.random() * lfsFileList.length);\n samplesToCheck.push(lfsFileList[randomIndex]);\n }\n\n let retries = 0;\n const maxRetries = 30;\n const retryDelay = 1000;\n\n while (retries < maxRetries) {\n let allDownloaded = true;\n const notDownloaded: string[] = [];\n\n for (const file of samplesToCheck) {\n const filePath = path.join(worktreePath, file);\n try {\n const handle = await fs.open(filePath, \"r\");\n try {\n const buffer = Buffer.alloc(200);\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);\n const header = buffer.subarray(0, bytesRead).toString(\"utf8\");\n if (header.startsWith(GIT_CONSTANTS.LFS_HEADER)) {\n allDownloaded = false;\n notDownloaded.push(file);\n }\n } finally {\n await handle.close();\n }\n } catch {\n allDownloaded = false;\n notDownloaded.push(file);\n }\n }\n\n if (allDownloaded) {\n if (this.config.debug) {\n this.logger.info(` - \u2705 LFS files verified (${samplesToCheck.length} samples checked)`);\n }\n return;\n }\n\n retries++;\n if (retries < maxRetries) {\n await new Promise((resolve) => setTimeout(resolve, retryDelay));\n }\n }\n\n this.logger.warn(\n ` - \u26A0\uFE0F Warning: Some LFS files may not be fully downloaded after ${maxRetries} seconds. ` +\n `This might cause issues if tools access the worktree immediately.`,\n );\n } catch (error) {\n this.logger.warn(` - \u26A0\uFE0F Warning: Could not verify LFS files for '${branchName}': ${error}`);\n }\n }\n\n async checkoutHead(worktreePath: string): Promise<void> {\n const git = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n await git.raw([\"checkout\", \"HEAD\"]);\n }\n\n private async applySparseAndCheckout(absoluteWorktreePath: string): Promise<void> {\n if (!this.config.sparseCheckout) return;\n await this.sparseCheckoutService.applyToWorktree(absoluteWorktreePath, this.config.sparseCheckout);\n const worktreeGit = this.getCachedGit(absoluteWorktreePath, this.isLfsSkipEnabled());\n await worktreeGit.raw([\"checkout\", \"HEAD\"]);\n }\n\n private async rollbackPartialWorktree(\n bareGit: SimpleGit,\n absoluteWorktreePath: string,\n branchName: string,\n createdNewBranch: boolean,\n failureContext?: string,\n ): Promise<{ worktreeRemoved: boolean }> {\n let worktreeRemoved = true;\n try {\n await bareGit.raw([\"worktree\", \"remove\", \"--force\", absoluteWorktreePath]);\n } catch (rollbackError) {\n worktreeRemoved = false;\n const ctx = failureContext ? ` after ${failureContext}` : \"\";\n this.logger.warn(\n ` - Rollback failed for '${branchName}' at '${absoluteWorktreePath}'${ctx}: ${getErrorMessage(rollbackError)}`,\n );\n }\n if (createdNewBranch) {\n try {\n await bareGit.raw([\"branch\", \"-D\", branchName]);\n } catch (branchRollbackError) {\n this.logger.warn(\n ` - Rollback (branch delete) failed for '${branchName}': ${getErrorMessage(branchRollbackError)}`,\n );\n }\n }\n return { worktreeRemoved };\n }\n\n private async createWorktreeMetadata(bareGit: SimpleGit, worktreePath: string, branchName: string): Promise<void> {\n try {\n const worktreeGit = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n const parentCommit = await bareGit.revparse([this.defaultBranch]);\n\n await this.metadataService.createInitialMetadataFromPath(\n this.bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n `origin/${branchName}`,\n this.defaultBranch,\n parentCommit.trim(),\n );\n } catch (metadataError) {\n this.logger.error(` - \u274C Failed to create metadata for '${branchName}': ${metadataError}`);\n throw new Error(`Metadata creation failed for ${branchName}. This worktree cannot be auto-managed.`);\n }\n }\n\n async addWorktree(branchName: string, worktreePath: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath, this.isLfsSkipEnabled());\n // Use absolute path for worktree add to avoid relative path issues\n const absoluteWorktreePath = path.resolve(worktreePath);\n // Ensure parent directory exists for nested branch paths\n await fs.mkdir(path.dirname(absoluteWorktreePath), { recursive: true });\n\n // Check if directory already exists (could be from a failed previous attempt)\n try {\n await fs.access(absoluteWorktreePath);\n // Directory exists - check if it's already a valid worktree\n const worktrees = await this.getWorktreesFromBare(bareGit);\n const isValidWorktree = worktrees.some((w) => path.resolve(w.path) === absoluteWorktreePath);\n\n if (isValidWorktree) {\n this.logger.info(` - Worktree for '${branchName}' already exists at '${absoluteWorktreePath}'`);\n return;\n } else {\n // Directory exists but is not a valid worktree - clean it up\n this.logger.info(` - Cleaning up orphaned directory at '${absoluteWorktreePath}'`);\n await this.clearStaleWorktreeDirectory(absoluteWorktreePath);\n }\n } catch (error) {\n if (error instanceof GitOperationError || error instanceof WorktreeError) {\n throw error;\n }\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 await this.clearStaleWorktreeDirectory(absoluteWorktreePath);\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 this.clearStaleWorktreeDirectory(absoluteWorktreePath);\n }\n } catch (error) {\n if (error instanceof GitOperationError || error instanceof WorktreeError) {\n throw error;\n }\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, options?: { force?: boolean }): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n\n // Non-forced by default: git's own refusal to delete a dirty worktree is\n // the last line of defense when our status checks were wrong. --force is\n // reserved for callers that already preserved the data (diverged flow) or\n // explicit user override.\n const args = [\"worktree\", \"remove\", worktreePath];\n if (options?.force) args.push(\"--force\");\n\n try {\n await bareGit.raw(args);\n } catch (error) {\n const message = getErrorMessage(error);\n if (!options?.force && /contains modified or untracked files|use --force/i.test(message)) {\n throw new WorktreeNotCleanError(worktreePath, [`git refused removal: ${message}`]);\n }\n throw error;\n }\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 updateRef(refName: string, sha: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n await bareGit.raw([\"update-ref\", refName, sha]);\n }\n\n async deleteRef(refName: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n await bareGit.raw([\"update-ref\", \"-d\", refName]);\n }\n\n async listRefs(prefix: string): Promise<string[]> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const raw = await bareGit.raw([\"for-each-ref\", \"--format=%(refname)\", prefix]);\n return raw\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n }\n\n async localBranchExists(branchName: string): Promise<boolean> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n try {\n await bareGit.raw([\"show-ref\", \"--verify\", \"--quiet\", `${GIT_CONSTANTS.REFS.HEADS}${branchName}`]);\n return true;\n } catch {\n return false;\n }\n }\n\n async getLocalBranchCommit(branchName: string): Promise<string | null> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n try {\n return (await bareGit.raw([\"rev-parse\", `${GIT_CONSTANTS.REFS.HEADS}${branchName}^{commit}`])).trim();\n } catch {\n return null;\n }\n }\n\n async createBranchAt(branchName: string, sha: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n await bareGit.raw([\"branch\", branchName, sha]);\n }\n\n async deleteLocalBranch(branchName: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n await bareGit.raw([\"branch\", \"-D\", branchName]);\n }\n\n // Bundles only commits not reachable from any remote \u2014 for fully-pushed\n // refs that set is empty and `bundle create` would fail. Emptiness is\n // pre-checked with rev-list (locale-independent) instead of parsing git's\n // localized \"empty bundle\" stderr; after the pre-check, any bundle-create\n // error is a real failure the caller must treat as fail-closed.\n async createBundleFromRef(bundlePath: string, refName: string): Promise<boolean> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const count = (await bareGit.raw([\"rev-list\", \"--count\", refName, \"--not\", \"--remotes\"])).trim();\n if (count === \"0\") {\n return false;\n }\n await bareGit.raw([\"bundle\", \"create\", bundlePath, refName, \"--not\", \"--remotes\"]);\n return true;\n }\n\n // Registers the worktree and writes its .git link without populating files \u2014\n // restore overlays the preserved payload instead of a fresh checkout.\n async addWorktreeNoCheckout(branchName: string, worktreePath: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const absoluteWorktreePath = path.resolve(worktreePath);\n await fs.mkdir(path.dirname(absoluteWorktreePath), { recursive: true });\n await bareGit.raw([\"worktree\", \"add\", \"--no-checkout\", absoluteWorktreePath, branchName]);\n }\n\n // Mixed reset: points the index at HEAD without touching working files, so\n // overlaid payload content shows up as ordinary uncommitted changes.\n async resetWorktreeIndex(worktreePath: string): Promise<void> {\n const worktreeGit = this.getCachedGit(worktreePath);\n await worktreeGit.raw([\"reset\"]);\n }\n\n // Injected by WorktreeSyncService when trash is enabled, so stale-directory\n // cleanup follows the same reversible-removal pipeline as everything else.\n // GitService cannot own a TrashService directly (TrashService depends on it).\n private staleDirectoryTrasher: ((dirPath: string) => Promise<string>) | null = null;\n\n setStaleDirectoryTrasher(trasher: (dirPath: string) => Promise<string>): void {\n this.staleDirectoryTrasher = trasher;\n }\n\n // A stale directory that contains a .git may be a live checkout that git\n // failed to report; quarantine it instead of deleting.\n private async clearStaleWorktreeDirectory(absoluteWorktreePath: string): Promise<void> {\n const gitProbe = await probePathExists(path.join(absoluteWorktreePath, PATH_CONSTANTS.GIT_DIR));\n\n if (gitProbe === \"unknown\") {\n throw new GitOperationError(\n \"clear-stale-directory\",\n `Cannot verify whether '${absoluteWorktreePath}' is a live checkout; refusing to clear it`,\n );\n }\n\n if (this.staleDirectoryTrasher) {\n try {\n const trashPath = await this.staleDirectoryTrasher(absoluteWorktreePath);\n this.logger.info(` - Moved stale directory at '${absoluteWorktreePath}' to trash ('${trashPath}')`);\n return;\n } catch (error) {\n // Cannot preserve it -> refuse to clear it (the caller's worktree\n // creation fails rather than silently deleting unknown content).\n throw new GitOperationError(\n \"clear-stale-directory\",\n `Cannot move stale directory '${absoluteWorktreePath}' to trash: ${getErrorMessage(error)}`,\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n if (gitProbe === \"exists\") {\n const quarantinePath = await quarantineDirectory(absoluteWorktreePath);\n this.logger.warn(\n ` - \u26A0\uFE0F Directory at '${absoluteWorktreePath}' contains a .git; quarantined to '${quarantinePath}' instead of deleting.`,\n );\n return;\n }\n\n await fs.rm(absoluteWorktreePath, { recursive: true, force: true });\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(\n worktreePath,\n includeDetails,\n metadata?.lastSyncCommit,\n metadata?.lastKnownRemoteTip,\n );\n }\n\n /** Map of remote branch name (without \"origin/\") \u2192 tip oid, from the bare repo. */\n async getRemoteBranchTips(): Promise<Map<string, string>> {\n const git = this.getGit();\n const raw = await git.raw([\"for-each-ref\", \"--format=%(refname:short) %(objectname)\", GIT_CONSTANTS.REFS.REMOTES]);\n const tips = new Map<string, string>();\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const spaceIdx = trimmed.lastIndexOf(\" \");\n if (spaceIdx <= 0) continue;\n const ref = trimmed.slice(0, spaceIdx);\n const oid = trimmed.slice(spaceIdx + 1);\n if (!ref.startsWith(GIT_CONSTANTS.REMOTE_PREFIX) || ref === `${GIT_CONSTANTS.REMOTE_PREFIX}HEAD`) continue;\n tips.set(ref.slice(GIT_CONSTANTS.REMOTE_PREFIX.length), oid);\n }\n return tips;\n }\n\n async recordRemoteTip(worktreePath: string, branchName: string, oid: string): Promise<void> {\n await this.metadataService.recordRemoteTip(\n this.bareRepoPath,\n worktreePath,\n `${GIT_CONSTANTS.REMOTE_PREFIX}${branchName}`,\n oid,\n );\n }\n\n async hasModifiedSubmodules(worktreePath: string): Promise<boolean> {\n return this.statusService.hasModifiedSubmodules(worktreePath);\n }\n\n async hasOperationInProgress(worktreePath: string): Promise<boolean> {\n return this.statusService.hasOperationInProgress(worktreePath);\n }\n\n async getCurrentBranch(): Promise<string> {\n const git = this.getGit();\n const branchSummary = await git.branch();\n return branchSummary.current;\n }\n\n private async detectDefaultBranch(bareGit: SimpleGit): Promise<string> {\n try {\n // Try to get the symbolic ref for origin/HEAD\n const headRef = await bareGit.raw([\"symbolic-ref\", \"refs/remotes/origin/HEAD\"]);\n // Extract branch name from refs/remotes/origin/main or refs/remotes/origin/master\n const branch = headRef.trim().split(\"/\").pop();\n if (branch) {\n return branch;\n }\n } catch {\n // If that fails, try to set HEAD automatically\n try {\n await bareGit.raw([\"remote\", \"set-head\", \"origin\", \"-a\"]);\n const headRef = await bareGit.raw([\"symbolic-ref\", \"refs/remotes/origin/HEAD\"]);\n const branch = headRef.trim().split(\"/\").pop();\n if (branch) {\n return branch;\n }\n } catch {\n // If all else fails, try to detect from remote branches\n try {\n const remoteBranches = await bareGit.branch([\"-r\"]);\n const commonDefaults = GIT_CONSTANTS.COMMON_DEFAULT_BRANCHES;\n for (const defaultName of commonDefaults) {\n if (remoteBranches.all.some((branch) => branch === `origin/${defaultName}`)) {\n return defaultName;\n }\n }\n } catch {\n // Ignore and fall through to default\n }\n }\n }\n // Final fallback\n return GIT_CONSTANTS.DEFAULT_BRANCH;\n }\n\n setLfsSkipEnabled(value: boolean): void {\n this.lfsSkipOverride = value;\n }\n\n private isLfsSkipEnabled(): boolean {\n return this.config.skipLfs || this.lfsSkipOverride;\n }\n\n async getWorktrees(): Promise<{ path: string; branch: string }[]> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n return this.getWorktreesFromBare(bareGit);\n }\n\n async isWorktreeBehind(worktreePath: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the current branch\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n // Check if the branch has an upstream\n const upstreamInfo = await worktreeGit.raw([\"rev-parse\", \"--abbrev-ref\", `${currentBranch}@{upstream}`]);\n if (!upstreamInfo.trim()) {\n return false; // No upstream, can't be behind\n }\n\n // Count commits behind upstream\n const behindCount = await worktreeGit.raw([\"rev-list\", \"--count\", `HEAD..${upstreamInfo.trim()}`]);\n return parseInt(behindCount.trim(), 10) > 0;\n } catch {\n // If any command fails, assume not behind\n return false;\n }\n }\n\n async updateWorktree(worktreePath: string): Promise<void> {\n const worktreeGit = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n\n // Perform a fast-forward merge\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n await worktreeGit.merge([`origin/${currentBranch}`, \"--ff-only\"]);\n\n // Update metadata after successful update (use path-based method)\n try {\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n await this.metadataService.updateLastSyncFromPath(\n this.bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n \"updated\",\n this.defaultBranch,\n );\n } catch (metadataError) {\n this.logger.warn(`Failed to update metadata for worktree: ${metadataError}`);\n }\n }\n\n async hasDivergedHistory(worktreePath: string, expectedBranch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n\n // Validate branch matches\n const branchInfo = await worktreeGit.branch();\n if (branchInfo.current !== expectedBranch) {\n this.logger.warn(`Branch mismatch in hasDivergedHistory: expected ${expectedBranch}, got ${branchInfo.current}`);\n return false; // Conservative: assume can fast-forward\n }\n\n try {\n // Check if HEAD is an ancestor of the remote branch (can fast-forward)\n await worktreeGit.raw([\"merge-base\", \"--is-ancestor\", \"HEAD\", `origin/${expectedBranch}`]);\n return false; // Can fast-forward\n } catch {\n return true; // Histories have diverged\n }\n }\n\n async canFastForward(worktreePath: string, branch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the merge base between HEAD and the remote branch\n const mergeBase = await worktreeGit.raw([\"merge-base\", \"HEAD\", `origin/${branch}`]);\n const mergeBaseSha = mergeBase.trim();\n\n // Get current HEAD SHA\n const headSha = await worktreeGit.revparse([\"HEAD\"]);\n const headShaTrimmed = headSha.trim();\n\n // If merge base equals HEAD, then HEAD is an ancestor of remote and can fast-forward\n return mergeBaseSha === headShaTrimmed;\n } catch {\n // If merge-base fails, branches have diverged\n return false;\n }\n }\n\n async isLocalAheadOfRemote(worktreePath: string, branch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the merge base between HEAD and the remote branch\n const mergeBase = await worktreeGit.raw([\"merge-base\", \"HEAD\", `origin/${branch}`]);\n const mergeBaseSha = mergeBase.trim();\n\n // Get remote branch SHA\n const remoteSha = await worktreeGit.revparse([`origin/${branch}`]);\n const remoteShaTrimmed = remoteSha.trim();\n\n // If merge base equals remote, local is ahead (remote is ancestor of local)\n return mergeBaseSha === remoteShaTrimmed;\n } catch {\n return false;\n }\n }\n\n async classifyRemoteRelationship(worktreePath: string, branch: string): Promise<RemoteRelationship> {\n const worktreeGit = this.getCachedGit(worktreePath);\n\n let headSha: string;\n let remoteSha: string;\n try {\n headSha = (await worktreeGit.revparse([\"HEAD\"])).trim();\n remoteSha = (await worktreeGit.revparse([`refs/remotes/origin/${branch}`])).trim();\n } catch {\n return \"diverged\";\n }\n\n if (headSha === remoteSha) return \"up_to_date\";\n\n let mergeBase = \"\";\n let mergeBaseFailed = false;\n try {\n mergeBase = (await worktreeGit.raw([\"merge-base\", \"HEAD\", `origin/${branch}`])).trim();\n } catch {\n mergeBaseFailed = true;\n }\n // simple-git swallows merge-base exit 1 and returns \"\" \u2014 treat empty output as failure too.\n if (mergeBaseFailed || !mergeBase) {\n if (await this.isShallowRepository(worktreeGit)) return \"indeterminate_shallow\";\n return \"diverged\";\n }\n if (mergeBase === headSha) return \"fast_forward\";\n if (mergeBase === remoteSha) return \"local_ahead\";\n return \"diverged\";\n }\n\n private async isShallowRepository(git: SimpleGit): Promise<boolean> {\n try {\n const output = await git.raw([\"rev-parse\", \"--is-shallow-repository\"]);\n return output.trim() === \"true\";\n } catch {\n return false;\n }\n }\n\n async getChangedPathsInRange(worktreePath: string, fromRef: string, toRef: string): Promise<string[] | null> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n const out = await worktreeGit.raw([\n \"-c\",\n \"core.quotePath=false\",\n \"diff\",\n \"--name-only\",\n \"--no-renames\",\n `${fromRef}..${toRef}`,\n ]);\n // Don't .trim() entries \u2014 leading/trailing whitespace is valid in POSIX\n // paths and `core.quotePath=false` only affects high-byte quoting, not\n // whitespace. Strip a trailing CR for Windows line endings only.\n return out\n .split(\"\\n\")\n .map((l) => l.replace(/\\r$/, \"\"))\n .filter((l) => l.length > 0);\n } catch (error) {\n this.logger.warn(`Failed to compute diff ${fromRef}..${toRef} in ${worktreePath}: ${getErrorMessage(error)}`);\n return null;\n }\n }\n\n async compareTreeContent(worktreePath: string, branch: string): Promise<boolean> {\n const worktreeGit = this.getCachedGit(worktreePath);\n try {\n // Get the tree SHA for the current HEAD\n const localTree = await worktreeGit.raw([\"rev-parse\", \"HEAD^{tree}\"]);\n // Get the tree SHA for the remote branch\n const remoteTree = await worktreeGit.raw([\"rev-parse\", `origin/${branch}^{tree}`]);\n\n return localTree.trim() === remoteTree.trim();\n } catch (error) {\n this.logger.error(`Error comparing tree content: ${error}`);\n return false; // Assume trees are different if we can't compare\n }\n }\n\n async resetToUpstream(worktreePath: string, branch: string): Promise<void> {\n const worktreeGit = this.getCachedGit(worktreePath, this.isLfsSkipEnabled());\n\n await worktreeGit.reset([\"--hard\", `origin/${branch}`]);\n\n // Update metadata after reset (use path-based method)\n try {\n const currentCommit = await worktreeGit.revparse([\"HEAD\"]);\n await this.metadataService.updateLastSyncFromPath(\n this.bareRepoPath,\n worktreePath,\n currentCommit.trim(),\n \"updated\",\n this.defaultBranch,\n );\n } catch (metadataError) {\n this.logger.warn(`Failed to update metadata after reset: ${metadataError}`);\n }\n }\n\n async getCurrentCommit(worktreePath: string): Promise<string> {\n const worktreeGit = this.getCachedGit(worktreePath);\n const commit = await worktreeGit.revparse([\"HEAD\"]);\n return commit.trim();\n }\n\n async getRemoteCommit(ref: string): Promise<string> {\n // Use the bare repository to read remote commit to avoid dependency on main worktree path\n const git = this.getCachedGit(this.bareRepoPath);\n const commit = await git.revparse([ref]);\n return commit.trim();\n }\n\n async branchExists(branchName: string): Promise<{ local: boolean; remote: boolean }> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const checkRef = async (ref: string): Promise<boolean> => {\n try {\n // simple-git resolves `show-ref --quiet` when Git exits 1, so keep stdout enabled.\n await bareGit.raw([\"show-ref\", \"--verify\", ref]);\n return true;\n } catch {\n return false;\n }\n };\n\n const [local, remote] = await Promise.all([\n checkRef(`${GIT_CONSTANTS.REFS.HEADS}${branchName}`),\n checkRef(`${GIT_CONSTANTS.REFS.REMOTES}/${branchName}`),\n ]);\n\n return { local, remote };\n }\n\n async getLocalBranches(): Promise<string[]> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const branches = await bareGit.branch();\n return branches.all;\n }\n\n private async resolveCreateBranchBaseRef(bareGit: SimpleGit, baseBranch: string): Promise<string> {\n const candidates =\n baseBranch.startsWith(GIT_CONSTANTS.REMOTE_PREFIX) || baseBranch.startsWith(\"refs/\")\n ? [baseBranch]\n : [`${GIT_CONSTANTS.REMOTE_PREFIX}${baseBranch}`, baseBranch];\n\n for (const candidate of candidates) {\n try {\n await bareGit.revparse([\"--verify\", candidate]);\n return candidate;\n } catch {\n // Try the next candidate before letting git branch report the original failure.\n }\n }\n\n return candidates[0];\n }\n\n async createBranch(branchName: string, baseBranch: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n const baseRef = await this.resolveCreateBranchBaseRef(bareGit, baseBranch);\n\n await bareGit.raw([\"branch\", \"--no-track\", branchName, baseRef]);\n this.logger.info(`Created branch '${branchName}' from '${baseRef}'`);\n }\n\n async pushBranch(branchName: string): Promise<void> {\n const bareGit = this.getCachedGit(this.bareRepoPath);\n\n await bareGit.push([\"origin\", `${branchName}:${branchName}`, \"-u\"]);\n this.logger.info(`Pushed branch '${branchName}' to remote`);\n }\n\n async getWorktreeMetadata(worktreePath: string): Promise<SyncMetadata | null> {\n return this.metadataService.loadMetadataFromPath(this.bareRepoPath, worktreePath);\n }\n\n private async getWorktreesFromBare(\n bareGit: SimpleGit,\n ): Promise<{ path: string; branch: string; isPrunable?: boolean }[]> {\n const result = await bareGit.raw([\"worktree\", \"list\", \"--porcelain\"]);\n return parseWorktreeListPorcelain(result)\n .filter((w) => !w.detached && w.branch !== null)\n .map((w) => ({\n path: w.path,\n branch: w.branch as string,\n isPrunable: w.prunable,\n }));\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport { GIT_CONSTANTS } from \"../constants\";\n\nimport { filenameTimestamp } from \"./filename-timestamp\";\n\n// Reversible alternative to deletion for directories that may hold user data:\n// same-filesystem rename into a sibling .removed/ directory (mirrors .diverged/).\nexport async function quarantineDirectory(dirPath: string): Promise<string> {\n const baseDir = path.join(path.dirname(dirPath), GIT_CONSTANTS.REMOVED_DIR_NAME);\n await fs.mkdir(baseDir, { recursive: true });\n const timestamp = filenameTimestamp();\n const quarantinePath = path.join(baseDir, `${timestamp}-${path.basename(dirPath)}`);\n await fs.rename(dirPath, quarantinePath);\n return quarantinePath;\n}\n", "export function filenameTimestamp(date: Date = new Date()): string {\n return date.toISOString().replace(/[:.]/g, \"-\");\n}\n", "export interface ParsedWorktree {\n path: string;\n branch: string | null;\n head: string | null;\n detached: boolean;\n prunable: boolean;\n locked: boolean;\n}\n\nexport function parseWorktreeListPorcelain(output: string): ParsedWorktree[] {\n const worktrees: ParsedWorktree[] = [];\n let current: Partial<ParsedWorktree> = {};\n\n const flush = (): void => {\n if (!current.path) {\n current = {};\n return;\n }\n worktrees.push({\n path: current.path,\n branch: current.branch ?? null,\n head: current.head ?? null,\n detached: current.detached ?? false,\n prunable: current.prunable ?? false,\n locked: current.locked ?? false,\n });\n current = {};\n };\n\n for (const line of output.split(\"\\n\")) {\n if (line.startsWith(\"worktree \")) {\n flush();\n current.path = line.substring(\"worktree \".length);\n } else if (line.startsWith(\"branch \")) {\n current.branch = line.substring(\"branch \".length).replace(\"refs/heads/\", \"\");\n } else if (line.startsWith(\"HEAD \")) {\n current.head = line.substring(\"HEAD \".length);\n } else if (line === \"detached\") {\n current.detached = true;\n } else if (line === \"prunable\" || line.startsWith(\"prunable \")) {\n current.prunable = true;\n } else if (line === \"locked\" || line.startsWith(\"locked \")) {\n current.locked = true;\n } else if (line.trim() === \"\") {\n flush();\n }\n }\n flush();\n return worktrees;\n}\n", "import * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { SparseCheckoutConfig, SparseCheckoutMode } from \"../types\";\nimport type { SimpleGit } from \"simple-git\";\n\nexport type GitFactory = (worktreePath: string) => SimpleGit;\n\ninterface SparseMatcher {\n mode: SparseCheckoutMode;\n patterns: string[];\n ancestorDirs: Set<string>;\n}\n\nexport class SparseCheckoutService {\n private logger: Logger;\n private gitFactory: GitFactory;\n private warnedConfigs = new WeakSet<SparseCheckoutConfig>();\n private matcherCache = new WeakMap<SparseCheckoutConfig, SparseMatcher>();\n\n constructor(logger?: Logger, gitFactory?: GitFactory) {\n this.logger = logger ?? Logger.createDefault();\n this.gitFactory = gitFactory ?? ((p: string): SimpleGit => simpleGit(p));\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n resolveMode(cfg: SparseCheckoutConfig): SparseCheckoutMode {\n const hasExclude = !!cfg.exclude && cfg.exclude.length > 0;\n const hasNegation = cfg.include.some((p) => p.trim().startsWith(\"!\"));\n\n if (cfg.mode === \"no-cone\") return \"no-cone\";\n if (hasExclude || hasNegation) {\n if (cfg.mode === \"cone\" && !this.warnedConfigs.has(cfg)) {\n this.logger.warn(\n \"sparseCheckout: mode 'cone' is incompatible with excludes or negation patterns; auto-promoting to 'no-cone'\",\n );\n this.warnedConfigs.add(cfg);\n }\n return \"no-cone\";\n }\n return cfg.mode ?? \"cone\";\n }\n\n buildPatterns(cfg: SparseCheckoutConfig): string[] {\n return this.buildPatternsForMode(cfg, this.resolveMode(cfg));\n }\n\n private buildPatternsForMode(cfg: SparseCheckoutConfig, mode: SparseCheckoutMode): string[] {\n const includes = cfg.include.map((p) => p.trim()).filter((p) => p.length > 0);\n\n if (mode === \"cone\") {\n return includes;\n }\n\n const excludes = (cfg.exclude ?? [])\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n .map((p) => (p.startsWith(\"!\") ? p : `!${p}`));\n\n return [...includes, ...excludes];\n }\n\n async applyToWorktree(worktreePath: string, cfg: SparseCheckoutConfig): Promise<void> {\n const mode = this.resolveMode(cfg);\n const patterns = this.buildPatternsForMode(cfg, mode);\n\n if (patterns.length === 0) {\n throw new Error(\"sparseCheckout produced no patterns; refusing to apply empty config\");\n }\n\n const git = this.gitFactory(worktreePath);\n await git.raw([\"sparse-checkout\", \"init\", mode === \"cone\" ? \"--cone\" : \"--no-cone\"]);\n await git.raw([\"sparse-checkout\", \"set\", mode === \"cone\" ? \"--cone\" : \"--no-cone\", ...patterns]);\n }\n\n async readCurrent(worktreePath: string): Promise<string[] | null> {\n const git = this.gitFactory(worktreePath);\n try {\n const out = await git.raw([\"sparse-checkout\", \"list\"]);\n const lines = out\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter((l) => l.length > 0 && !l.startsWith(\"#\"));\n return lines.length === 0 ? null : lines;\n } catch {\n return null;\n }\n }\n\n async readCurrentMode(worktreePath: string): Promise<SparseCheckoutMode | null> {\n const git = this.gitFactory(worktreePath);\n try {\n const out = await git.raw([\"config\", \"--bool\", \"--get\", \"core.sparseCheckoutCone\"]);\n const value = out.trim().toLowerCase();\n if (value === \"true\") return \"cone\";\n if (value === \"false\") return \"no-cone\";\n return null;\n } catch {\n return null;\n }\n }\n\n async needsUpdate(worktreePath: string, cfg: SparseCheckoutConfig): Promise<boolean> {\n const desiredMode = this.resolveMode(cfg);\n const currentMode = await this.readCurrentMode(worktreePath);\n if (currentMode !== desiredMode) return true;\n const current = await this.readCurrent(worktreePath);\n if (current === null) return true;\n return !this.patternsEqual(current, this.buildPatternsForMode(cfg, desiredMode));\n }\n\n isNarrowing(currentPatterns: string[] | null, nextPatterns: string[]): boolean {\n if (!currentPatterns || currentPatterns.length === 0) return false;\n\n const isNeg = (p: string): boolean => p.startsWith(\"!\");\n const trim = (xs: string[]): string[] => xs.map((p) => p.trim()).filter((p) => p.length > 0);\n\n const cur = trim(currentPatterns);\n const next = trim(nextPatterns);\n\n const positiveCurrent = new Set(cur.filter((p) => !isNeg(p)));\n const negativeCurrent = new Set(cur.filter(isNeg));\n const positiveNext = new Set(next.filter((p) => !isNeg(p)));\n const negativeNext = new Set(next.filter(isNeg));\n\n for (const p of positiveCurrent) {\n if (!positiveNext.has(p)) return true;\n }\n for (const p of negativeNext) {\n if (!negativeCurrent.has(p)) return true;\n }\n return false;\n }\n\n patternsEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n const at = a.map((x) => x.trim());\n const bt = b.map((x) => x.trim());\n return at.every((v, i) => v === bt[i]);\n }\n\n /**\n * Decide whether a list of changed file paths intersects the sparse-checkout\n * set defined by `cfg`. Used to skip fast-forward updates when upstream\n * commits only touch files outside the materialized worktree.\n *\n * Cone mode materializes:\n * - all files at the repository root,\n * - all files directly inside every ancestor of an included directory\n * (e.g. include `tools/build` keeps `tools/foo.txt` checked out too),\n * - everything inside an included directory.\n * We mirror those rules here. Missing the ancestor-files case would let\n * stale files linger when only those parent files change upstream.\n *\n * No-cone mode: gitignore-style matching with negation is non-trivial and\n * not implemented here yet. We return `true` so the caller falls back to\n * the safe behavior of always running the update.\n *\n * The matcher derived from `cfg` is cached on the cfg object identity\n * (WeakMap), so callers should reuse the same `cfg` reference across\n * invocations to benefit from the cache.\n */\n pathsTouchSparse(changedPaths: string[], cfg: SparseCheckoutConfig): boolean {\n if (changedPaths.length === 0) return false;\n\n const matcher = this.getMatcher(cfg);\n if (matcher.mode === \"no-cone\") return true;\n if (matcher.patterns.length === 0) return true;\n\n return changedPaths.some((p) => {\n if (!p.includes(\"/\")) return true;\n for (const pat of matcher.patterns) {\n if (p === pat || p.startsWith(pat + \"/\")) return true;\n }\n return matcher.ancestorDirs.has(path.posix.dirname(p));\n });\n }\n\n private getMatcher(cfg: SparseCheckoutConfig): SparseMatcher {\n const cached = this.matcherCache.get(cfg);\n if (cached) return cached;\n\n const mode = this.resolveMode(cfg);\n if (mode === \"no-cone\") {\n const matcher: SparseMatcher = { mode, patterns: [], ancestorDirs: new Set() };\n this.matcherCache.set(cfg, matcher);\n return matcher;\n }\n\n const patterns = cfg.include\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n .map((p) => (p.endsWith(\"/\") ? p.slice(0, -1) : p));\n\n const ancestorDirs = new Set<string>();\n for (const pat of patterns) {\n const parts = pat.split(\"/\");\n for (let i = 1; i < parts.length; i++) {\n ancestorDirs.add(parts.slice(0, i).join(\"/\"));\n }\n }\n\n const matcher: SparseMatcher = { mode, patterns, ancestorDirs };\n this.matcherCache.set(cfg, matcher);\n return matcher;\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport simpleGit from \"simple-git\";\n\nimport { GIT_CONSTANTS, METADATA_CONSTANTS } from \"../constants\";\nimport { atomicWriteFile } from \"../utils/atomic-write\";\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 await atomicWriteFile(metadataPath, JSON.stringify(metadata, null, 2));\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 /**\n * Records the upstream tip observed during this sync. This is what later\n * proves \"HEAD was fully pushed\" after the remote branch is deleted, so it\n * must only ever be overwritten with a live observation \u2014 callers must not\n * invoke this once the upstream ref is gone.\n */\n async recordRemoteTip(bareRepoPath: string, worktreePath: string, ref: string, oid: string): Promise<void> {\n const worktreeDirName = this.getWorktreeDirectoryName(worktreePath);\n const existing = await this.loadMetadataFromPath(bareRepoPath, worktreePath);\n\n if (!existing) {\n // debug, not warn: this runs every sync tick for every worktree, and a\n // legacy worktree without metadata would otherwise spam the log forever.\n this.logger.debug(`No metadata found for worktree ${worktreeDirName}; skipping remote tip recording`);\n return;\n }\n\n if (existing.lastKnownRemoteTip?.ref === ref && existing.lastKnownRemoteTip.oid === oid) {\n return;\n }\n\n existing.lastKnownRemoteTip = { ref, oid, recordedAt: new Date().toISOString() };\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 { probePathExists } from \"../utils/file-exists\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { LastKnownRemoteTip } from \"../types/sync-metadata\";\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 // True when commits look unpushed only because the upstream ref was deleted\n // (squash-merge + branch deletion): metadata recorded the upstream tip while\n // it existed, that ref is now gone, and HEAD is an ancestor of (or equal to)\n // the recorded tip \u2014 so every local commit was on the remote at some point.\n fullyPushedUpstreamDeleted: 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 unpushedAnyRemoteCount: number | null;\n sinceSyncCount: number | null;\n sinceSyncChecked: boolean;\n // null = no recorded tip to check against; false also covers probe errors\n // (e.g. the recorded oid was gc'd away), which must read as \"not proven\".\n headPushedToRecordedTip: boolean | null;\n stashTotal: number | null;\n submoduleStatus: string | null;\n operationFile: string | null;\n operationProbeUnknown: boolean;\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 lastKnownRemoteTip?: LastKnownRemoteTip,\n ): Promise<WorktreeStatusResult> {\n const pathProbe = await probePathExists(worktreePath);\n if (pathProbe === \"missing\") {\n return {\n isClean: true,\n hasUnpushedCommits: false,\n hasStashedChanges: false,\n hasOperationInProgress: false,\n hasModifiedSubmodules: false,\n upstreamGone: false,\n fullyPushedUpstreamDeleted: false,\n canRemove: true,\n reasons: [],\n };\n }\n // A failed probe (EMFILE/EINTR under load) is indistinguishable from a live\n // worktree \u2014 never report it as removable.\n if (pathProbe === \"unknown\") {\n return {\n isClean: false,\n hasUnpushedCommits: true,\n hasStashedChanges: true,\n hasOperationInProgress: true,\n hasModifiedSubmodules: true,\n upstreamGone: false,\n fullyPushedUpstreamDeleted: false,\n canRemove: false,\n reasons: [\"cannot verify worktree path (filesystem probe failed)\"],\n };\n }\n\n const snap = await this.collectSnapshot(worktreePath, lastSyncCommit, lastKnownRemoteTip);\n\n const isClean = this.deriveIsClean(snap);\n // Removal requires BOTH unpushed checks to pass independently: commits\n // missing from every remote AND commits made since the last sync. Relying\n // on lastSyncCommit alone hides unpushed work when metadata records HEAD.\n const anyRemoteUnpushed = (snap.unpushedAnyRemoteCount ?? 1) > 0;\n const sinceSyncUnpushed = snap.sinceSyncChecked && (snap.sinceSyncCount ?? 1) > 0;\n const hasUnpushedCommits = !snap.detached && (anyRemoteUnpushed || sinceSyncUnpushed);\n // \"Unpushed\" override for squash-merge + branch deletion: only when the\n // recorded upstream ref is verifiably gone from a non-empty remote-branch\n // list (an empty list means the fetch may have failed \u2014 fail closed) AND\n // HEAD is an ancestor of the tip recorded while the ref still existed.\n const recordedRefGone =\n lastKnownRemoteTip !== undefined &&\n snap.remoteBranches.length > 0 &&\n !snap.remoteBranches.includes(lastKnownRemoteTip.ref);\n const fullyPushedUpstreamDeleted = hasUnpushedCommits && recordedRefGone && snap.headPushedToRecordedTip === true;\n const hasStashedChanges = snap.stashTotal === null ? true : snap.stashTotal > 0;\n const hasOperationInProgress =\n snap.gitDir === null ? true : snap.operationFile !== null || snap.operationProbeUnknown;\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 && !fullyPushedUpstreamDeleted) 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 // A detached HEAD may sit on commits unreachable from any ref; this tool\n // only manages branch-tracking worktrees, so never auto-remove one.\n if (snap.detached) reasons.push(\"detached HEAD\");\n\n const canRemove =\n isClean &&\n (!hasUnpushedCommits || fullyPushedUpstreamDeleted) &&\n !hasStashedChanges &&\n !hasOperationInProgress &&\n !hasModifiedSubmodules &&\n !snap.detached;\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 fullyPushedUpstreamDeleted,\n canRemove,\n reasons,\n details,\n };\n }\n\n private async collectSnapshot(\n worktreePath: string,\n lastSyncCommit?: string,\n lastKnownRemoteTip?: LastKnownRemoteTip,\n ): 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 unpushedAnyRemoteCount: number | null = null;\n let sinceSyncCount: number | null = null;\n let headPushedToRecordedTip: boolean | null = null;\n if (!detached && currentBranch) {\n const [upstreamResult, anyRemoteResult, sinceSyncResult, recordedTipResult] = 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([\"rev-list\", \"--count\", currentBranch, \"--not\", \"--remotes\"]).then(\n (raw) => ({ ok: true as const, value: raw }),\n (error: unknown) => ({ ok: false as const, error }),\n ),\n lastSyncCommit\n ? git.raw([\"rev-list\", \"--count\", `${lastSyncCommit}..HEAD`]).then(\n (raw) => ({ ok: true as const, value: raw }),\n (error: unknown) => ({ ok: false as const, error }),\n )\n : Promise.resolve(null),\n // Zero commits in <tip>..HEAD \u27FA HEAD is the recorded tip or behind it.\n // NOT merge-base --is-ancestor: simple-git resolves its silent exit-1\n // (\"not an ancestor\") as success because nothing is written to stderr.\n // Any failure (e.g. the recorded oid was gc'd) reads as \"not proven\".\n lastKnownRemoteTip\n ? git.raw([\"rev-list\", \"--count\", `${lastKnownRemoteTip.oid}..HEAD`]).then(\n (raw) => this.parseCount(raw) === 0,\n () => false,\n )\n : Promise.resolve(null),\n ]);\n\n headPushedToRecordedTip = recordedTipResult;\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 (anyRemoteResult.ok) {\n unpushedAnyRemoteCount = this.parseCount(anyRemoteResult.value);\n } else {\n this.logger.error(`Error checking unpushed commits`, anyRemoteResult.error);\n }\n\n if (sinceSyncResult) {\n if (sinceSyncResult.ok) {\n sinceSyncCount = this.parseCount(sinceSyncResult.value);\n } else {\n this.logger.error(`Error checking commits since last sync`, sinceSyncResult.error);\n }\n }\n }\n\n const operationProbe = gitDirResult ? await this.detectOperationFile(gitDirResult) : { file: null, unknown: false };\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 unpushedAnyRemoteCount,\n sinceSyncCount,\n sinceSyncChecked: lastSyncCommit !== undefined,\n headPushedToRecordedTip,\n stashTotal: stashResult?.total ?? null,\n submoduleStatus: submoduleResult,\n operationFile: operationProbe.file,\n operationProbeUnknown: operationProbe.unknown,\n gitDir: gitDirResult,\n untrackedNotIgnored,\n };\n }\n\n private parseCount(raw: string): number | null {\n const count = parseInt(raw.trim(), 10);\n return Number.isNaN(count) ? null : count;\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 const unpushedCount = snap.unpushedAnyRemoteCount ?? snap.sinceSyncCount;\n if (!snap.detached && unpushedCount !== null) details.unpushedCommitCount = 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<{ file: string | null; unknown: boolean }> {\n const results = await Promise.all(\n OPERATION_FILES.map(({ file }) =>\n fs.access(path.join(gitDir, file)).then(\n () => \"present\" as const,\n (error: unknown) =>\n (error as NodeJS.ErrnoException).code === \"ENOENT\" ? (\"absent\" as const) : (\"unknown\" as const),\n ),\n ),\n );\n const idx = results.findIndex((result) => result === \"present\");\n if (idx >= 0) return { file: OPERATION_FILES[idx].file, unknown: false };\n // An unreadable probe may be hiding MERGE_HEAD etc. \u2014 report it so the\n // caller treats the worktree as having an operation in progress.\n return { file: null, unknown: results.includes(\"unknown\") };\n }\n\n async hasUnpushedCommits(worktreePath: string, lastSyncCommit?: string): Promise<boolean> {\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n // A detached HEAD may sit on commits unreachable from any ref; this is a\n // safety predicate, so answer conservatively.\n if (await this.isDetachedHead(worktreeGit)) {\n return true;\n }\n\n const branchSummary = await worktreeGit.branch();\n const currentBranch = branchSummary.current;\n\n const anyRemoteResult = await worktreeGit.raw([\"rev-list\", \"--count\", currentBranch, \"--not\", \"--remotes\"]);\n const anyRemoteCount = this.parseCount(anyRemoteResult);\n if (anyRemoteCount === null || anyRemoteCount > 0) {\n return true;\n }\n\n if (lastSyncCommit) {\n const sinceSyncResult = await worktreeGit.raw([\"rev-list\", \"--count\", `${lastSyncCommit}..HEAD`]);\n const sinceSyncCount = this.parseCount(sinceSyncResult);\n if (sinceSyncCount === null || sinceSyncCount > 0) {\n return true;\n }\n }\n\n return false;\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 const probe = await this.detectOperationFile(gitDir);\n return probe.unknown || probe.file !== 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(\n worktreePath: string,\n lastSyncCommit?: string,\n lastKnownRemoteTip?: LastKnownRemoteTip,\n ): Promise<void> {\n const status = await this.getFullWorktreeStatus(worktreePath, false, lastSyncCommit, lastKnownRemoteTip);\n\n if (!status.canRemove) {\n throw new WorktreeNotCleanError(worktreePath, status.reasons);\n }\n }\n\n private async filterUntrackedFiles(worktreePath: string, files: string[]): Promise<string[]> {\n if (files.length === 0) return [];\n\n const worktreeGit = this.createGitInstance(worktreePath);\n\n try {\n const result = await worktreeGit.raw([\"check-ignore\", \"--\", ...files]);\n\n const ignoredFiles = new Set(\n result\n .trim()\n .split(\"\\n\")\n .filter((f) => f),\n );\n return files.filter((f) => !ignoredFiles.has(f));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n if (errorMessage.includes(GIT_CONSTANTS.GIT_CHECK_IGNORE_NO_MATCH)) {\n return files;\n }\n\n throw error;\n }\n }\n\n private async isDetachedHead(worktreeGit: SimpleGit): Promise<boolean> {\n try {\n const branchSummary = await worktreeGit.branch();\n return !branchSummary.current || branchSummary.detached;\n } catch {\n return true;\n }\n }\n\n private async resolveGitDir(worktreePath: string): Promise<string> {\n const gitPath = path.join(worktreePath, PATH_CONSTANTS.GIT_DIR);\n\n try {\n const stat = await fs.stat(gitPath);\n\n if (stat.isFile()) {\n const content = await fs.readFile(gitPath, \"utf-8\");\n const gitdirMatch = content.match(new RegExp(`^${GIT_CONSTANTS.GITDIR_PREFIX}\\\\s*(.+)$`, \"m\"));\n if (gitdirMatch) {\n return path.resolve(worktreePath, gitdirMatch[1].trim());\n }\n throw new GitOperationError(\"resolve-git-dir\", `Failed to parse gitdir from .git file at ${gitPath}`);\n }\n\n return gitPath;\n } catch (error) {\n throw new GitOperationError(\n \"resolve-git-dir\",\n `Failed to resolve .git directory for ${worktreePath}`,\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n private createGitInstance(worktreePath: string): SimpleGit {\n const key = `${path.resolve(worktreePath)}::${this.config.skipLfs ? \"1\" : \"0\"}`;\n let git = this.gitInstances.get(key);\n if (!git) {\n git = this.config.skipLfs\n ? simpleGit(worktreePath).env({ [ENV_CONSTANTS.GIT_LFS_SKIP_SMUDGE]: \"1\" })\n : simpleGit(worktreePath);\n this.gitInstances.set(key, git);\n }\n return git;\n }\n}\n", "export interface ProgressEvent {\n phase: string;\n message: string;\n progress?: number;\n processed?: number;\n total?: number;\n}\n\nexport type ProgressListener = (event: ProgressEvent) => void;\n\nexport class ProgressEmitter {\n private listeners = new Set<ProgressListener>();\n\n onProgress(listener: ProgressListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n emit(event: ProgressEvent): void {\n // Snapshot so a listener that unsubscribes a sibling during emit doesn't\n // skip that sibling's notification for this event.\n for (const listener of [...this.listeners]) {\n try {\n listener(event);\n } catch {\n // Progress listeners must not break sync flow.\n }\n }\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport type { WorktreeStatusResult } from \"./worktree-status.service\";\n\nexport type RemovalAuditAction =\n | \"prune_remove\"\n | \"orphan_delete\"\n | \"orphan_quarantine\"\n | \"diverged_replace\"\n | \"manual_remove\"\n | \"trash_create\"\n | \"trash_adopt\"\n | \"trash_restore\"\n | \"trash_reap\";\n\nexport interface RemovalAuditEntry {\n action: RemovalAuditAction;\n result: \"attempt\" | \"success\" | \"failure\";\n path: string;\n branch?: string;\n status?: WorktreeStatusResult;\n quarantinePath?: string;\n trashId?: string;\n trashPath?: string;\n error?: string;\n}\n\n// Append-only JSONL log of every destructive worktree operation. Console logs\n// die with the terminal; this record survives the process.\nexport class RemovalAuditService {\n constructor(private readonly logFilePath: string) {}\n\n async record(entry: RemovalAuditEntry): Promise<void> {\n await fs.mkdir(path.dirname(this.logFilePath), { recursive: true });\n const line = JSON.stringify({ timestamp: new Date().toISOString(), ...entry });\n // The audit line gates destructive operations (\"attempt\" must survive a\n // crash that happens mid-delete), so flush it to disk before returning.\n const handle = await fs.open(this.logFilePath, \"a\");\n try {\n await handle.appendFile(`${line}\\n`, \"utf-8\");\n await handle.sync();\n } finally {\n await handle.close();\n }\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport * as lockfile from \"proper-lockfile\";\n\nimport { DEFAULT_CONFIG, ENV_CONSTANTS } from \"../constants\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\nimport { getCloneModeLockTarget } from \"../utils/lock-path\";\nimport { REPOSITORY_MODES, resolveMode } from \"../utils/repo-mode\";\n\nimport { Logger } from \"./logger.service\";\n\nimport type { Config } from \"../types\";\nimport type { GitService } from \"./git.service\";\n\nexport type RepoLockRelease = () => Promise<void>;\n\nexport class RepoOperationLock {\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger = Logger.createDefault(),\n ) {}\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n async acquire(): Promise<RepoLockRelease | null> {\n if (process.env.NODE_ENV === ENV_CONSTANTS.NODE_ENV_TEST) {\n return async () => {};\n }\n\n if (resolveMode(this.config) === REPOSITORY_MODES.CLONE) {\n return this.acquireCloneModeLock();\n }\n\n return this.acquireWorktreeModeLock();\n }\n\n private async acquireCloneModeLock(): Promise<RepoLockRelease | null> {\n const target = getCloneModeLockTarget(this.config);\n const lockTarget = path.join(target.dir, target.file);\n try {\n await fs.mkdir(target.dir, { recursive: true });\n await fs.writeFile(lockTarget, \"\", { flag: \"a\" });\n } catch {\n // Couldn't prepare the lock target (read-only FS, ENOSPC, EACCES).\n // Treat as 'unable to acquire' so the operation is skipped cleanly\n // instead of crashing the whole sync run.\n return null;\n }\n return this.lockPath(lockTarget);\n }\n\n private async acquireWorktreeModeLock(): Promise<RepoLockRelease | null> {\n const barePath = this.gitService.getBareRepoPath();\n try {\n await fs.mkdir(barePath, { recursive: true });\n } catch {\n return null;\n }\n return this.lockPath(barePath);\n }\n\n private async lockPath(lockTarget: string): Promise<RepoLockRelease | null> {\n try {\n return await lockfile.lock(lockTarget, {\n stale: DEFAULT_CONFIG.LOCK_STALE_MS,\n update: DEFAULT_CONFIG.LOCK_UPDATE_MS,\n retries: 0,\n realpath: false,\n });\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ELOCKED\") {\n return null;\n }\n // A lock we cannot acquire (read-only FS, EACCES/EROFS/EPERM surfaced at\n // lock time rather than during prep) must be a clean skip, never a fatal\n // error that crashes the whole multi-repo run. Surface it as a warning so\n // the cause is visible.\n this.logger.warn(\n `Could not acquire repo lock at '${lockTarget}' (${code ?? \"unknown\"}: ${getErrorMessage(error)}); skipping.`,\n );\n return null;\n }\n }\n}\n", "import { getErrorMessage } from \"../utils/lfs-error\";\n\nimport type { GitService } from \"./git.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { Config } from \"../types\";\nimport type { RetryOptions } from \"../utils/retry\";\n\nexport interface SyncRetryContext {\n lfsSkipEnabled: boolean;\n}\n\nexport class SyncRetryPolicy {\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger,\n ) {}\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n createContext(): SyncRetryContext {\n return { lfsSkipEnabled: false };\n }\n\n createOptions(syncContext: SyncRetryContext): RetryOptions {\n return {\n maxAttempts: this.config.retry?.maxAttempts ?? 3,\n maxLfsRetries: this.config.retry?.maxLfsRetries ?? 2,\n initialDelayMs: this.config.retry?.initialDelayMs ?? 1000,\n maxDelayMs: this.config.retry?.maxDelayMs ?? 30000,\n backoffMultiplier: this.config.retry?.backoffMultiplier ?? 2,\n jitterMs: this.config.retry?.jitterMs ?? 0,\n onRetry: (error, attempt, context): void => {\n const errorMessage = getErrorMessage(error);\n this.logger.info(`\\n\u26A0\uFE0F Sync attempt ${attempt} failed: ${errorMessage}`);\n\n if (context?.isLfsError && !this.config.skipLfs) {\n this.logger.info(`\uD83D\uDD04 LFS error detected. Will retry with LFS skipped...`);\n } else {\n this.logger.info(`\uD83D\uDD04 Retrying synchronization...\\n`);\n }\n },\n lfsRetryHandler: (): void => {\n if (!this.config.skipLfs && !syncContext.lfsSkipEnabled) {\n this.logger.info(\"\u26A0\uFE0F Temporarily disabling LFS downloads for this sync...\");\n this.gitService.setLfsSkipEnabled(true);\n syncContext.lfsSkipEnabled = true;\n }\n },\n };\n }\n\n resetLfsSkipIfNeeded(syncContext: SyncRetryContext): void {\n if (syncContext.lfsSkipEnabled && !this.config.skipLfs) {\n this.gitService.setLfsSkipEnabled(false);\n }\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport { DEFAULT_CONFIG, GIT_CONSTANTS, METADATA_CONSTANTS } from \"../constants\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\n\nimport type { Logger } from \"./logger.service\";\nimport type { TrashService } from \"./trash.service\";\nimport type { Config } from \"../types\";\n\n// quarantineDirectory() wrote `<iso-timestamp-with-:.->-<original-name>`.\nconst REMOVED_ENTRY_RE = /^(\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-\\d{3}Z)-(.+)$/;\n\ninterface DivergedInfo {\n originalBranch?: string;\n divergedAt?: string;\n originalPath?: string;\n localCommit?: string;\n}\n\n// Adopts pre-trash `.removed/` quarantines and `.diverged/` backups into\n// `.trash/` so they age out under the same retention policy. Only entries in\n// the exact formats those flows wrote are adopted \u2014 anything else is warned\n// about and left alone (the reaper never touches unmanifested content).\nexport class TrashMigrationService {\n constructor(\n private readonly config: Config,\n private readonly trashService: TrashService,\n private logger: Logger,\n ) {}\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n isEnabled(): boolean {\n return this.trashService.isEnabled() && (this.config.trash?.migrateLegacy ?? DEFAULT_CONFIG.TRASH.MIGRATE_LEGACY);\n }\n\n async migrateLegacyUnlocked(): Promise<void> {\n if (!this.isEnabled()) return;\n await this.migrateRemovedDir();\n await this.migrateDivergedDir();\n }\n\n private async migrateRemovedDir(): Promise<void> {\n const removedDir = path.join(this.config.worktreeDir, GIT_CONSTANTS.REMOVED_DIR_NAME);\n const names = await this.listDirectories(removedDir);\n\n for (const name of names) {\n const match = REMOVED_ENTRY_RE.exec(name);\n const quarantinedAt = match ? this.parseQuarantineTimestamp(match[1]) : null;\n if (!match || !quarantinedAt) {\n this.logger.warn(`\u26A0\uFE0F Leaving unrecognized entry '${name}' in ${GIT_CONSTANTS.REMOVED_DIR_NAME}/ alone`);\n continue;\n }\n\n try {\n const entry = await this.trashService.trashDirectory({\n dirPath: path.join(removedDir, name),\n reason: \"legacy-adopt\",\n source: \".removed\",\n legacyOriginalName: name,\n legacyQuarantinedAt: quarantinedAt,\n headOid: null,\n originalPath: path.join(this.config.worktreeDir, match[2]),\n auditAction: \"trash_adopt\",\n });\n this.logger.info(\n `\u267B\uFE0F Adopted '${name}' from ${GIT_CONSTANTS.REMOVED_DIR_NAME}/ as trash entry '${entry.manifest.id}'`,\n );\n } catch (error) {\n this.logger.warn(`\u26A0\uFE0F Failed to adopt '${name}' into trash: ${getErrorMessage(error)}`);\n }\n }\n\n await fs.rmdir(removedDir).catch(() => undefined);\n }\n\n private async migrateDivergedDir(): Promise<void> {\n const divergedDir = path.join(this.config.worktreeDir, GIT_CONSTANTS.DIVERGED_DIR_NAME);\n const names = await this.listDirectories(divergedDir);\n\n for (const name of names) {\n const dirPath = path.join(divergedDir, name);\n const info = await this.readDivergedInfo(dirPath);\n const quarantinedAt = info?.divergedAt ? new Date(info.divergedAt) : null;\n const hasOriginalPath = typeof info?.originalPath === \"string\" && info.originalPath.length > 0;\n if (\n !info ||\n !info.originalBranch ||\n !hasOriginalPath ||\n !quarantinedAt ||\n Number.isNaN(quarantinedAt.getTime())\n ) {\n this.logger.warn(\n `\u26A0\uFE0F Leaving entry '${name}' in ${GIT_CONSTANTS.DIVERGED_DIR_NAME}/ alone (no parseable ${METADATA_CONSTANTS.DIVERGED_INFO_FILE})`,\n );\n continue;\n }\n\n try {\n // keepPinOnReap: a .diverged backup exists precisely because its\n // commits were never pushed \u2014 adoption must not weaken that to a\n // 30-day files-only entry. Entries whose commit can't be pinned\n // (missing localCommit, gc'd oid) fail adoption and stay in\n // .diverged/ forever, the pre-trash behavior.\n const entry = await this.trashService.trashDirectory({\n dirPath,\n reason: \"legacy-adopt\",\n source: \".diverged\",\n branch: info.originalBranch,\n legacyOriginalName: name,\n legacyQuarantinedAt: quarantinedAt,\n headOid: info.localCommit ?? null,\n originalPath: info.originalPath,\n auditAction: \"trash_adopt\",\n keepPinOnReap: true,\n });\n this.logger.info(\n `\u267B\uFE0F Adopted '${name}' from ${GIT_CONSTANTS.DIVERGED_DIR_NAME}/ as trash entry '${entry.manifest.id}'`,\n );\n } catch (error) {\n this.logger.warn(`\u26A0\uFE0F Failed to adopt '${name}' into trash: ${getErrorMessage(error)}`);\n }\n }\n\n await fs.rmdir(divergedDir).catch(() => undefined);\n }\n\n private async listDirectories(dirPath: string): Promise<string[]> {\n try {\n const dirents = await fs.readdir(dirPath, { withFileTypes: true });\n return dirents.filter((dirent) => dirent.isDirectory() && !dirent.isSymbolicLink()).map((dirent) => dirent.name);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n this.logger.warn(`\u26A0\uFE0F Cannot scan '${dirPath}' for legacy trash adoption: ${getErrorMessage(error)}`);\n }\n return [];\n }\n }\n\n private async readDivergedInfo(dirPath: string): Promise<DivergedInfo | null> {\n try {\n const raw = await fs.readFile(path.join(dirPath, METADATA_CONSTANTS.DIVERGED_INFO_FILE), \"utf-8\");\n return JSON.parse(raw) as DivergedInfo;\n } catch {\n return null;\n }\n }\n\n // quarantine timestamps replaced [:.] with \"-\": 2026-06-06T18-34-18-123Z\n private parseQuarantineTimestamp(raw: string): Date | null {\n const match = /^(\\d{4}-\\d{2}-\\d{2})T(\\d{2})-(\\d{2})-(\\d{2})-(\\d{3})Z$/.exec(raw);\n if (!match) return null;\n const date = new Date(`${match[1]}T${match[2]}:${match[3]}:${match[4]}.${match[5]}Z`);\n return Number.isNaN(date.getTime()) ? null : date;\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport { GIT_CONSTANTS } from \"../constants\";\nimport { formatBytes } from \"../utils/disk-space\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\n\nimport { summarizeTrashEntries } from \"./trash.service\";\n\nimport type { GitService } from \"./git.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { RemovalAuditService } from \"./removal-audit.service\";\nimport type { TrashEntry, TrashService } from \"./trash.service\";\nimport type { Config } from \"../types\";\n\n// Deletes expired trash entries at the tail of a successful sync, inside the\n// already-held repo lock. Same fail-closed discipline as the removal pipeline:\n// only manifested entries whose realpath stays under the trash root, and only\n// after the attempt is durably recorded in the audit log.\nexport class TrashReaperService {\n constructor(\n private readonly config: Config,\n private readonly trashService: TrashService,\n private logger: Logger,\n private readonly removalAudit: RemovalAuditService,\n private readonly gitService: GitService,\n ) {}\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n // Disabled trash means \"don't touch my trash\" \u2014 existing entries are left\n // alone rather than aged out behind the user's back.\n async reapExpiredUnlocked(now: Date = new Date()): Promise<void> {\n if (!this.trashService.isEnabled()) return;\n\n let realRoot: string;\n try {\n realRoot = await fs.realpath(this.trashService.getTrashRoot());\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n // A missing trash root is NOT proof the trash is empty \u2014 worktreeDir\n // may be an unmounted volume that sync just recreated empty. Sweeping\n // pins here would let gc collect objects whose manifests reappear on\n // remount. Pins from a manually deleted trash root linger only until\n // the next trashDirectory recreates the root and the sweep resumes.\n this.logger.debug(`Trash reaper: no trash root; skipping pin-ref sweep`);\n return;\n }\n this.logger.warn(`\u26A0\uFE0F Trash reaper skipped: cannot resolve trash root: ${getErrorMessage(error)}`);\n return;\n }\n\n const { entries, invalid } = await this.trashService.listEntries();\n for (const invalidPath of invalid) {\n this.logger.warn(`\u26A0\uFE0F Trash reaper: leaving unrecognized entry '${invalidPath}' alone (no valid manifest)`);\n }\n\n const reapedIds = new Set<string>();\n for (const entry of entries) {\n const expiresAt = new Date(entry.manifest.expiresAt);\n if (Number.isNaN(expiresAt.getTime())) {\n this.logger.warn(`\u26A0\uFE0F Trash reaper: entry '${entry.manifest.id}' has an unparseable expiry; skipping`);\n continue;\n }\n if (expiresAt.getTime() > now.getTime()) continue;\n\n try {\n const realEntry = await fs.realpath(entry.containerPath);\n if (!realEntry.startsWith(realRoot + path.sep)) {\n this.logger.warn(`\u26A0\uFE0F Trash reaper: entry '${entry.manifest.id}' resolves outside the trash root; skipping`);\n continue;\n }\n } catch (error) {\n this.logger.warn(\n `\u26A0\uFE0F Trash reaper: cannot verify path of entry '${entry.manifest.id}'; skipping: ${getErrorMessage(error)}`,\n );\n continue;\n }\n\n // \"Fully pushed before upstream deletion\" entries keep their commits\n // alive past payload expiry: move the pin to a permanent keep ref BEFORE\n // deleting anything. On failure defer the whole reap to the next run \u2014\n // these commits may be the only copy left anywhere.\n let keepRef: string | null = null;\n if (entry.manifest.keepPinOnReap && entry.manifest.headOid) {\n keepRef = `${GIT_CONSTANTS.KEEP_REF_PREFIX}${entry.manifest.id}`;\n try {\n await this.gitService.updateRef(keepRef, entry.manifest.headOid);\n } catch (error) {\n this.logger.warn(\n `\u26A0\uFE0F Trash reaper: cannot create keep ref '${keepRef}' for '${entry.manifest.id}'; deferring reap: ${getErrorMessage(error)}`,\n );\n continue;\n }\n }\n\n try {\n await this.removalAudit.record({\n action: \"trash_reap\",\n result: \"attempt\",\n path: entry.manifest.originalPath,\n branch: entry.manifest.branch ?? undefined,\n trashId: entry.manifest.id,\n trashPath: entry.payloadPath,\n });\n } catch (auditError) {\n this.logger.warn(\n `\u26A0\uFE0F Trash reaper: cannot write audit log; skipping '${entry.manifest.id}': ${getErrorMessage(auditError)}`,\n );\n continue;\n }\n\n try {\n await fs.rm(entry.containerPath, { recursive: true, force: true });\n } catch (error) {\n this.logger.warn(`\u26A0\uFE0F Trash reaper: failed to delete '${entry.manifest.id}': ${getErrorMessage(error)}`);\n await this.removalAudit\n .record({\n action: \"trash_reap\",\n result: \"failure\",\n path: entry.manifest.originalPath,\n trashId: entry.manifest.id,\n error: getErrorMessage(error),\n })\n .catch(() => undefined);\n continue;\n }\n\n if (entry.manifest.pinRef) {\n await this.gitService\n .deleteRef(entry.manifest.pinRef)\n .catch((error: unknown) =>\n this.logger.warn(\n `\u26A0\uFE0F Trash reaper: failed to delete pin ref '${entry.manifest.pinRef}': ${getErrorMessage(error)}`,\n ),\n );\n }\n\n reapedIds.add(entry.manifest.id);\n this.logger.info(\n `\uD83D\uDDD1\uFE0F Trash reaper: deleted expired entry '${entry.manifest.id}' (trashed ${entry.manifest.deletedAt})`,\n );\n if (keepRef) {\n this.logger.info(\n ` Commits remain recoverable at '${keepRef}' (${entry.manifest.headOid}) \u2014 recover with: git branch <name> ${entry.manifest.headOid}`,\n );\n }\n await this.removalAudit\n .record({\n action: \"trash_reap\",\n result: \"success\",\n path: entry.manifest.originalPath,\n trashId: entry.manifest.id,\n })\n .catch((auditError: unknown) =>\n this.logger.warn(`\u26A0\uFE0F Failed to write trash audit record: ${getErrorMessage(auditError)}`),\n );\n }\n\n let containerNames: Set<string> | null = null;\n try {\n containerNames = new Set(await fs.readdir(realRoot));\n } catch (error) {\n this.logger.warn(`\u26A0\uFE0F Trash reaper: cannot scan trash root for pin-ref sweep: ${getErrorMessage(error)}`);\n }\n if (containerNames !== null) {\n await this.reapOrphanedPinRefs(containerNames);\n }\n\n this.warnIfOverThreshold(entries.filter((entry) => !reapedIds.has(entry.manifest.id)));\n }\n\n // Pin refs whose trash container is gone would pin objects forever (failed\n // ref delete during restore, manually emptied trash). Keyed on container\n // existence, NOT manifest validity \u2014 an invalid-manifest entry still owns\n // its pin because the reaper refuses to delete its payload. Deliberately\n // any dirent name counts (files, symlinks): deleting a pin is irreversible\n // once gc runs, while a stray name collision merely keeps one ref alive.\n private async reapOrphanedPinRefs(containerNames: Set<string>): Promise<void> {\n let refs: string[];\n try {\n refs = await this.gitService.listRefs(GIT_CONSTANTS.TRASH_REF_PREFIX.replace(/\\/$/, \"\"));\n } catch (error) {\n this.logger.warn(`\u26A0\uFE0F Trash reaper: cannot list pin refs: ${getErrorMessage(error)}`);\n return;\n }\n\n for (const ref of refs) {\n if (!ref.startsWith(GIT_CONSTANTS.TRASH_REF_PREFIX)) continue;\n const id = ref.slice(GIT_CONSTANTS.TRASH_REF_PREFIX.length);\n if (id.length === 0 || id.includes(\"/\")) {\n this.logger.warn(`\u26A0\uFE0F Trash reaper: leaving unexpected ref '${ref}' alone`);\n continue;\n }\n if (containerNames.has(id)) continue;\n\n try {\n await this.gitService.deleteRef(ref);\n this.logger.info(`\uD83D\uDDD1\uFE0F Trash reaper: deleted orphaned pin ref '${ref}'`);\n } catch (error) {\n this.logger.warn(`\u26A0\uFE0F Trash reaper: failed to delete orphaned pin ref '${ref}': ${getErrorMessage(error)}`);\n }\n }\n }\n\n private warnIfOverThreshold(remaining: TrashEntry[]): void {\n const warnSizeBytes = this.config.trash?.warnSizeBytes;\n if (warnSizeBytes === undefined) return;\n\n const summary = summarizeTrashEntries(remaining);\n if (summary.totalSizeBytes > warnSizeBytes) {\n this.logger.warn(\n `\u26A0\uFE0F Trash holds ${formatBytes(summary.totalSizeBytes)} across ${summary.itemCount} entries ` +\n `(threshold ${formatBytes(warnSizeBytes)}). Entries expire ${this.trashService.getRetentionDays()} days after removal.`,\n );\n }\n }\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", "import { randomBytes } from \"crypto\";\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport { DEFAULT_CONFIG, GIT_CONSTANTS, PATH_CONSTANTS, TRASH_CONSTANTS } from \"../constants\";\nimport { TrashOperationError } from \"../errors\";\nimport { atomicWriteFile } from \"../utils/atomic-write\";\nimport { calculateDirectorySize } from \"../utils/disk-space\";\nimport { probePathExists } from \"../utils/file-exists\";\nimport { filenameTimestamp } from \"../utils/filename-timestamp\";\nimport { getErrorMessage } from \"../utils/lfs-error\";\n\nimport type { GitService } from \"./git.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { RemovalAuditService } from \"./removal-audit.service\";\nimport type { Config } from \"../types\";\n\nexport type TrashReason = \"prune\" | \"orphan\" | \"diverged-replace\" | \"manual\" | \"legacy-adopt\";\n\nexport interface TrashManifest {\n schemaVersion: number;\n id: string;\n deletedAt: string;\n expiresAt: string;\n originalPath: string;\n branch: string | null;\n reason: TrashReason;\n sizeBytes: number | null;\n headOid: string | null;\n pinRef: string | null;\n /** Bundle of the pinned commits not on any remote, relative to the container; null when nothing to bundle. */\n bundleFile?: string | null;\n source: \"worktree\" | \".removed\" | \".diverged\";\n legacyOriginalName: string | null;\n /** When the legacy quarantine flow originally preserved this entry; retention still counts from adoption. */\n legacyQuarantinedAt?: string | null;\n // When true the reaper moves the pin to a permanent keep ref instead of\n // unpinning. Set for removals authorized only by \"fully pushed before\n // upstream deletion\" proof \u2014 the remote may have deleted an unmerged\n // branch, so the commits must never become gc-eligible silently.\n keepPinOnReap?: boolean;\n}\n\nexport interface TrashEntry {\n manifest: TrashManifest;\n containerPath: string;\n payloadPath: string;\n}\n\nexport interface TrashSummary {\n itemCount: number;\n totalSizeBytes: number;\n unknownSizeCount: number;\n soonestExpiresAt: string | null;\n}\n\nexport function isWorktreeRestorable(manifest: Pick<TrashManifest, \"branch\" | \"headOid\" | \"pinRef\">): boolean {\n return manifest.branch !== null && manifest.headOid !== null && manifest.pinRef !== null;\n}\n\nexport function summarizeTrashEntries(entries: TrashEntry[]): TrashSummary {\n let totalSizeBytes = 0;\n let unknownSizeCount = 0;\n let soonest: string | null = null;\n\n for (const { manifest } of entries) {\n if (manifest.sizeBytes === null) {\n unknownSizeCount++;\n } else {\n totalSizeBytes += manifest.sizeBytes;\n }\n if (soonest === null || manifest.expiresAt < soonest) {\n soonest = manifest.expiresAt;\n }\n }\n\n return { itemCount: entries.length, totalSizeBytes, unknownSizeCount, soonestExpiresAt: soonest };\n}\n\nexport interface TrashDirectoryOptions {\n dirPath: string;\n reason: TrashReason;\n branch?: string | null;\n source?: TrashManifest[\"source\"];\n legacyOriginalName?: string | null;\n /** When the legacy flow originally quarantined the directory. Forensic only \u2014\n * retention always counts from adoption time so a just-adopted entry can\n * never be reaped in the same tick. */\n legacyQuarantinedAt?: Date;\n /** Explicit HEAD oid (legacy adoption); `undefined` resolves from dirPath when branch is set. */\n headOid?: string | null;\n /** Where restore should put the payload back; defaults to dirPath. */\n originalPath?: string;\n auditAction?: \"trash_create\" | \"trash_adopt\";\n keepPinOnReap?: boolean;\n}\n\n// Reversible removal: directories land in <worktreeDir>/.trash/<id>/payload\n// with a manifest sidecar and (when a commit is known) a pin ref that keeps\n// the trashed HEAD's objects alive through `git gc` until the reaper runs.\nexport class TrashService {\n constructor(\n private readonly config: Config,\n private readonly gitService: GitService,\n private logger: Logger,\n private readonly removalAudit: RemovalAuditService,\n ) {}\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n }\n\n isEnabled(): boolean {\n return this.config.trash?.enabled ?? DEFAULT_CONFIG.TRASH.ENABLED;\n }\n\n getTrashRoot(): string {\n return path.join(this.config.worktreeDir, GIT_CONSTANTS.TRASH_DIR_NAME);\n }\n\n getRetentionDays(): number {\n return this.config.trash?.retentionDays ?? DEFAULT_CONFIG.TRASH.RETENTION_DAYS;\n }\n\n async trashDirectory(options: TrashDirectoryOptions): Promise<TrashEntry> {\n const deletedAt = new Date();\n const expiresAt = new Date(deletedAt.getTime() + this.getRetentionDays() * 86_400_000);\n const keepPinOnReap = options.keepPinOnReap ?? false;\n\n const headOid = options.headOid !== undefined ? options.headOid : await this.resolveHeadOid(options);\n if (keepPinOnReap && !headOid) {\n throw new TrashOperationError(\n \"trash-directory\",\n `cannot create keep-on-reap trash entry for '${options.dirPath}': HEAD commit could not be resolved`,\n );\n }\n const sizeBytes = await calculateDirectorySize(options.dirPath).catch(() => null);\n\n // Non-recursive container mkdir + EEXIST retry: the undo path below may\n // rm -rf the container, so it must never adopt one it didn't create.\n await fs.mkdir(this.getTrashRoot(), { recursive: true });\n const { id, containerPath } = await this.createContainer(deletedAt, path.basename(options.dirPath));\n\n const manifest: TrashManifest = {\n schemaVersion: TRASH_CONSTANTS.SCHEMA_VERSION,\n id,\n deletedAt: deletedAt.toISOString(),\n expiresAt: expiresAt.toISOString(),\n originalPath: path.resolve(options.originalPath ?? options.dirPath),\n branch: options.branch ?? null,\n reason: options.reason,\n sizeBytes,\n headOid,\n pinRef: null,\n bundleFile: null,\n source: options.source ?? \"worktree\",\n legacyOriginalName: options.legacyOriginalName ?? null,\n legacyQuarantinedAt: options.legacyQuarantinedAt?.toISOString() ?? null,\n keepPinOnReap,\n };\n\n // Manifest goes down BEFORE the pin ref: a crash in between leaves a\n // valid (payload-less) entry that ages out normally, instead of an\n // unrecognized container the reaper warns about forever while its pin\n // keeps objects alive indefinitely.\n try {\n await this.writeManifest(containerPath, manifest);\n } catch (error) {\n await this.undoPartialTrash(containerPath, null);\n throw new TrashOperationError(\n \"trash-directory\",\n `cannot write trash manifest for '${options.dirPath}': ${getErrorMessage(error)}`,\n error instanceof Error ? error : undefined,\n );\n }\n\n const pinRef = headOid ? await this.createPinRef(id, headOid) : null;\n if (keepPinOnReap && !pinRef) {\n await this.undoPartialTrash(containerPath, pinRef);\n throw new TrashOperationError(\n \"trash-directory\",\n `cannot create keep-on-reap trash entry '${id}' for '${options.dirPath}': pin ref could not be created`,\n );\n }\n // Keep-on-reap entries may hold the only copy of their commits anywhere,\n // so a self-contained bundle backs up the pin ref; failure aborts the\n // removal (fail-closed) while the source directory is still untouched.\n let bundleFile: string | null = null;\n if (keepPinOnReap && pinRef) {\n try {\n const created = await this.gitService.createBundleFromRef(\n path.join(containerPath, TRASH_CONSTANTS.BUNDLE_FILENAME),\n pinRef,\n );\n bundleFile = created ? TRASH_CONSTANTS.BUNDLE_FILENAME : null;\n } catch (error) {\n await this.undoPartialTrash(containerPath, pinRef);\n throw new TrashOperationError(\n \"trash-directory\",\n `cannot bundle commits for keep-on-reap trash entry '${id}': ${getErrorMessage(error)}`,\n error instanceof Error ? error : undefined,\n );\n }\n }\n const payloadPath = path.join(containerPath, TRASH_CONSTANTS.PAYLOAD_DIRNAME);\n manifest.pinRef = pinRef;\n manifest.bundleFile = bundleFile;\n\n try {\n await this.writeManifest(containerPath, manifest);\n await fs.rename(options.dirPath, payloadPath);\n } catch (error) {\n await this.undoPartialTrash(containerPath, pinRef);\n const hint =\n (error as NodeJS.ErrnoException).code === \"EXDEV\"\n ? \" (trash lives inside worktreeDir; a cross-device rename means the directory is on a different filesystem \u2014 co-locate it or set trash.enabled=false)\"\n : \"\";\n throw new TrashOperationError(\n \"trash-directory\",\n `cannot move '${options.dirPath}' to trash${hint}: ${getErrorMessage(error)}`,\n error instanceof Error ? error : undefined,\n );\n }\n\n await this.removalAudit\n .record({\n action: options.auditAction ?? \"trash_create\",\n result: \"success\",\n path: manifest.originalPath,\n branch: manifest.branch ?? undefined,\n trashId: id,\n trashPath: payloadPath,\n })\n .catch((auditError: unknown) =>\n this.logger.warn(`\u26A0\uFE0F Failed to write trash audit record: ${getErrorMessage(auditError)}`),\n );\n\n return { manifest, containerPath, payloadPath };\n }\n\n async listEntries(): Promise<{ entries: TrashEntry[]; invalid: string[] }> {\n const root = this.getTrashRoot();\n const entries: TrashEntry[] = [];\n const invalid: string[] = [];\n\n let dirents;\n try {\n dirents = await fs.readdir(root, { withFileTypes: true });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return { entries, invalid };\n }\n throw error;\n }\n\n for (const dirent of dirents) {\n const containerPath = path.join(root, dirent.name);\n if (dirent.isSymbolicLink()) {\n invalid.push(containerPath);\n continue;\n }\n if (!dirent.isDirectory()) {\n continue;\n }\n const manifest = await this.readManifest(containerPath);\n if (manifest === null) {\n invalid.push(containerPath);\n continue;\n }\n entries.push({\n manifest,\n containerPath,\n payloadPath: path.join(containerPath, TRASH_CONSTANTS.PAYLOAD_DIRNAME),\n });\n }\n\n return { entries, invalid };\n }\n\n // The full reversible-removal sequence shared by prune and manual removal:\n // payload to trash, dangling registration cleared, branch ref deleted.\n // A ref-delete failure is a hygiene problem, not a failed removal \u2014 the\n // payload and pin ref already capture everything restore needs, and restore\n // tolerates a leftover ref at the trashed commit.\n async trashAndUnregisterWorktree(options: {\n dirPath: string;\n branch: string | null;\n reason: TrashReason;\n keepPinOnReap?: boolean;\n }): Promise<{ entry: TrashEntry; branchRefError?: string }> {\n const entry = await this.trashDirectory(options);\n // force is safe here: the directory was already moved to trash, so only\n // the dangling registration is being cleared.\n await this.gitService.removeWorktree(options.dirPath, { force: true });\n let branchRefError: string | undefined;\n try {\n await this.deleteTrashedBranchRef(entry.manifest);\n } catch (refError) {\n branchRefError = getErrorMessage(refError);\n this.logger.warn(\n `\u26A0\uFE0F Leftover branch ref '${entry.manifest.branch}' after trashing '${entry.manifest.id}': ${branchRefError}`,\n );\n }\n return { entry, branchRefError };\n }\n\n async restore(id: string): Promise<TrashManifest> {\n const { entries } = await this.listEntries();\n const entry = entries.find((candidate) => candidate.manifest.id === id);\n if (!entry) {\n throw new TrashOperationError(\"restore\", `no trash entry with id '${id}'`);\n }\n\n const { manifest, containerPath, payloadPath } = entry;\n\n if ((await probePathExists(payloadPath)) !== \"exists\") {\n throw new TrashOperationError(\"restore\", `payload missing or unverifiable for '${id}' at '${payloadPath}'`);\n }\n const destinationProbe = await probePathExists(manifest.originalPath);\n if (destinationProbe !== \"missing\") {\n const why = destinationProbe === \"exists\" ? \"already exists\" : \"cannot be verified\";\n const hint =\n manifest.reason === \"diverged-replace\" && destinationProbe === \"exists\"\n ? \" \u2014 a fresh worktree replaced this one when the branch diverged; remove that worktree first, or copy the files you need out of the trash payload manually\"\n : \"\";\n throw new TrashOperationError(\"restore\", `destination '${manifest.originalPath}' ${why}${hint}`);\n }\n\n // Worktree restore needs the pin: without it gc may already have collected\n // the trashed HEAD's objects, so promise only what is guaranteed \u2014 files.\n if (isWorktreeRestorable(manifest)) {\n await this.restoreAsWorktree(manifest, payloadPath);\n } else {\n if (manifest.branch) {\n this.logger.warn(\n `\u26A0\uFE0F Trash entry '${id}' has no pinned commit; restoring files only \u2014 the directory will not be a registered worktree.`,\n );\n }\n await fs.rename(payloadPath, manifest.originalPath);\n }\n\n // The payload is back in place \u2014 from here on, cleanup failures must not\n // fail the restore (a rejected retry would see \"payload missing\").\n await fs\n .rm(containerPath, { recursive: true, force: true })\n .catch((error: unknown) =>\n this.logger.warn(`\u26A0\uFE0F Failed to remove restored trash container '${containerPath}': ${getErrorMessage(error)}`),\n );\n if (manifest.pinRef) {\n await this.gitService\n .deleteRef(manifest.pinRef)\n .catch((error: unknown) =>\n this.logger.warn(`\u26A0\uFE0F Failed to delete pin ref '${manifest.pinRef}': ${getErrorMessage(error)}`),\n );\n }\n\n await this.removalAudit\n .record({\n action: \"trash_restore\",\n result: \"success\",\n path: manifest.originalPath,\n branch: manifest.branch ?? undefined,\n trashId: id,\n })\n .catch((auditError: unknown) =>\n this.logger.warn(`\u26A0\uFE0F Failed to write trash audit record: ${getErrorMessage(auditError)}`),\n );\n\n return manifest;\n }\n\n async deleteTrashedBranchRef(manifest: Pick<TrashManifest, \"branch\" | \"id\" | \"pinRef\">): Promise<void> {\n if (!manifest.branch) return;\n // Without a pin the branch ref may be the last thing keeping the trashed\n // commits out of gc \u2014 leave it as a hygiene problem rather than risk them.\n if (!manifest.pinRef) {\n this.logger.warn(\n `\u26A0\uFE0F Keeping branch ref '${manifest.branch}' after trashing '${manifest.id}': entry has no pin ref, so the ref is the only gc protection left`,\n );\n return;\n }\n\n try {\n await this.gitService.deleteLocalBranch(manifest.branch);\n } catch (error) {\n throw new TrashOperationError(\n \"trash-branch-ref\",\n `cannot delete branch ref '${manifest.branch}' after trashing '${manifest.id}': ${getErrorMessage(error)}`,\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n private async restoreAsWorktree(manifest: TrashManifest, payloadPath: string): Promise<void> {\n const branch = manifest.branch as string;\n const headOid = manifest.headOid as string;\n const existingBranchOid = await this.gitService.getLocalBranchCommit(branch);\n let createdBranch = false;\n\n if (existingBranchOid !== null && existingBranchOid !== headOid) {\n throw new TrashOperationError(\n \"restore\",\n `branch '${branch}' already exists at ${existingBranchOid}; expected trashed commit ${headOid}. Restore the files manually from '${payloadPath}' or move that branch first`,\n );\n }\n\n if (existingBranchOid === null) {\n await this.gitService.createBranchAt(branch, headOid);\n createdBranch = true;\n }\n\n try {\n await this.gitService.addWorktreeNoCheckout(branch, manifest.originalPath);\n await this.copyPayloadOver(payloadPath, manifest.originalPath);\n await this.gitService.resetWorktreeIndex(manifest.originalPath);\n // The payload was checked out under the sparse profile when it was\n // trashed; the fresh registration must carry the same sparse config or\n // git status would report every out-of-cone file as deleted.\n if (this.config.sparseCheckout) {\n await this.gitService\n .getSparseCheckoutService()\n .applyToWorktree(manifest.originalPath, this.config.sparseCheckout);\n }\n } catch (error) {\n await this.gitService\n .removeWorktree(manifest.originalPath, { force: true })\n .catch((rollbackError: unknown) =>\n this.logger.warn(`\u26A0\uFE0F Restore rollback (worktree) failed: ${getErrorMessage(rollbackError)}`),\n );\n if (createdBranch) {\n await this.gitService\n .deleteLocalBranch(branch)\n .catch((rollbackError: unknown) =>\n this.logger.warn(`\u26A0\uFE0F Restore rollback (branch) failed: ${getErrorMessage(rollbackError)}`),\n );\n }\n throw new TrashOperationError(\n \"restore\",\n `failed to recreate worktree for '${manifest.id}'; trash entry left intact: ${getErrorMessage(error)}`,\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n // The payload's top-level .git link points at a pruned admin dir; the fresh\n // one written by `worktree add --no-checkout` must survive the overlay.\n private async copyPayloadOver(payloadPath: string, destination: string): Promise<void> {\n await fs.cp(payloadPath, destination, {\n recursive: true,\n force: true,\n filter: (source) => !(path.dirname(source) === payloadPath && path.basename(source) === PATH_CONSTANTS.GIT_DIR),\n });\n }\n\n private async resolveHeadOid(options: TrashDirectoryOptions): Promise<string | null> {\n if (!options.branch) return null;\n try {\n return (await this.gitService.getCurrentCommit(options.dirPath)).trim();\n } catch (error) {\n this.logger.warn(\n `\u26A0\uFE0F Could not resolve HEAD for '${options.dirPath}'; trash entry will preserve files only: ${getErrorMessage(error)}`,\n );\n return null;\n }\n }\n\n // Pin failure degrades to a files-only trash entry rather than blocking the\n // removal \u2014 the payload itself is still fully preserved either way.\n private async createPinRef(id: string, headOid: string): Promise<string | null> {\n const refName = `${GIT_CONSTANTS.TRASH_REF_PREFIX}${id}`;\n try {\n await this.gitService.updateRef(refName, headOid);\n return refName;\n } catch (error) {\n this.logger.warn(\n `\u26A0\uFE0F Could not pin '${headOid}' for trash entry '${id}'; git gc may collect its objects: ${getErrorMessage(error)}`,\n );\n return null;\n }\n }\n\n private async writeManifest(containerPath: string, manifest: TrashManifest): Promise<void> {\n const manifestPath = path.join(containerPath, TRASH_CONSTANTS.MANIFEST_FILENAME);\n await atomicWriteFile(manifestPath, JSON.stringify(manifest, null, 2));\n }\n\n private async readManifest(containerPath: string): Promise<TrashManifest | null> {\n try {\n const raw = await fs.readFile(path.join(containerPath, TRASH_CONSTANTS.MANIFEST_FILENAME), \"utf-8\");\n const parsed = JSON.parse(raw) as TrashManifest;\n if (\n typeof parsed.id !== \"string\" ||\n typeof parsed.expiresAt !== \"string\" ||\n typeof parsed.originalPath !== \"string\"\n ) {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n }\n\n private async undoPartialTrash(containerPath: string, pinRef: string | null): Promise<void> {\n await fs.rm(containerPath, { recursive: true, force: true }).catch(() => undefined);\n if (pinRef) {\n await this.gitService.deleteRef(pinRef).catch(() => undefined);\n }\n }\n\n private async createContainer(deletedAt: Date, baseName: string): Promise<{ id: string; containerPath: string }> {\n let lastError: unknown;\n for (let attempt = 0; attempt < 3; attempt++) {\n const id = this.generateId(deletedAt, baseName);\n const containerPath = path.join(this.getTrashRoot(), id);\n try {\n await fs.mkdir(containerPath);\n return { id, containerPath };\n } catch (error) {\n lastError = error;\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") break;\n }\n }\n throw new TrashOperationError(\n \"trash-directory\",\n `cannot create trash container for '${baseName}': ${getErrorMessage(lastError)}`,\n lastError instanceof Error ? lastError : undefined,\n );\n }\n\n // The id doubles as a refname component (refs/sync-worktrees/trash/<id>).\n // The timestamp prefix and hex suffix rule out leading dots and \".lock\"\n // endings, but \"..\" inside the name would still make the ref invalid and\n // silently degrade the entry to files-only.\n private generateId(deletedAt: Date, baseName: string): string {\n const timestamp = filenameTimestamp(deletedAt);\n const safeName = baseName.replace(/[^A-Za-z0-9._-]/g, \"_\").replace(/\\.{2,}/g, \"_\");\n return `${timestamp}-${safeName}-${randomBytes(3).toString(\"hex\")}`;\n }\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport pLimit from \"p-limit\";\n\nimport { DEFAULT_CONFIG, ERROR_MESSAGES, GIT_CONSTANTS, METADATA_CONSTANTS, PATH_CONSTANTS } from \"../constants\";\nimport { TrashOperationError, WorktreeNotCleanError } from \"../errors\";\nimport { filterBranchesByName } from \"../utils/branch-filter\";\nimport { filterBranchesByAge, formatDuration } from \"../utils/date-filter\";\nimport { probePathExists } from \"../utils/file-exists\";\nimport { getErrorMessage, isLfsError } from \"../utils/lfs-error\";\nimport { getRemovalAuditLogPath } from \"../utils/lock-path\";\nimport { quarantineDirectory } from \"../utils/quarantine\";\n\nimport { PathResolutionService } from \"./path-resolution.service\";\nimport { RemovalAuditService } from \"./removal-audit.service\";\nimport { TrashService } from \"./trash.service\";\nimport { createWorktreeSyncPlan } from \"./worktree-sync-planner\";\n\nimport type { GitService } from \"./git.service\";\nimport type { Logger } from \"./logger.service\";\nimport type { ProgressEmitter } from \"./progress-emitter\";\nimport type { SyncOutcomeAccumulator } from \"./sync-outcome\";\nimport type { SyncRetryContext } from \"./sync-retry-policy\";\nimport type { TrashManifest } from \"./trash.service\";\nimport type { WorktreeStatusDetails, WorktreeStatusResult } from \"./worktree-status.service\";\nimport type { CreateAction, PruneAction, SparseAction, SyncPlan, UpdateAction } from \"./worktree-sync-planner\";\nimport type { Config } from \"../types\";\nimport type { PhaseTimer } from \"../utils/timing\";\n\nexport class WorktreeModeSyncRunner {\n private pathResolution = new PathResolutionService();\n private removalAudit: RemovalAuditService;\n private trashService: TrashService;\n\n constructor(\n private config: Config,\n private gitService: GitService,\n private logger: Logger,\n private progressEmitter: ProgressEmitter,\n services?: { trashService: TrashService; removalAudit: RemovalAuditService },\n ) {\n this.removalAudit = services?.removalAudit ?? new RemovalAuditService(getRemovalAuditLogPath(config));\n this.trashService = services?.trashService ?? new TrashService(config, gitService, logger, this.removalAudit);\n }\n\n updateLogger(logger: Logger): void {\n this.logger = logger;\n this.trashService.updateLogger(logger);\n }\n\n async runSyncAttempt(\n phaseTimer: PhaseTimer,\n syncContext: SyncRetryContext,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n await this.gitService.pruneWorktrees();\n await this.fetchLatestRemoteData(phaseTimer, syncContext);\n\n const { remoteBranches, defaultBranch } = await this.resolveSyncBranches();\n\n await fs.mkdir(this.config.worktreeDir, { recursive: true });\n\n const worktrees = await this.gitService.getWorktrees();\n this.logger.info(`Found ${worktrees.length} existing Git worktrees.`);\n\n await this.cleanupOrphanedDirectories(worktrees);\n const syncPlan = createWorktreeSyncPlan(\n {\n remoteBranches,\n defaultBranch,\n existingWorktrees: worktrees,\n worktreeDir: this.config.worktreeDir,\n },\n {\n pathResolution: this.pathResolution,\n updateExistingWorktrees: this.config.updateExistingWorktrees !== false,\n sparseCheckout: this.config.sparseCheckout,\n },\n );\n\n await this.createNewWorktreesWithTiming(syncPlan, phaseTimer, outcome);\n await this.recordRemoteBranchTips([...worktrees, ...syncPlan.create.filter((action) => action.kind === \"create\")]);\n await this.pruneOldWorktreesWithTiming(syncPlan.prune, phaseTimer, outcome);\n\n if (this.config.updateExistingWorktrees !== false) {\n await this.updateExistingWorktreesWithTiming(syncPlan.update, phaseTimer, outcome);\n }\n\n if (this.config.sparseCheckout) {\n await this.reapplySparseCheckout(syncPlan.sparse, outcome);\n }\n\n await this.finalizeSyncAttempt(phaseTimer);\n }\n\n private async reapplySparseCheckout(actions: SparseAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n const sparseConfig = this.config.sparseCheckout;\n if (!sparseConfig) return;\n\n this.logger.info(\"Step 5: Reconciling sparse-checkout patterns on existing worktrees...\");\n const sparseService = this.gitService.getSparseCheckoutService();\n const desired = sparseService.buildPatterns(sparseConfig);\n\n const limit = pLimit(this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\n\n await Promise.all(\n actions.map((action) =>\n limit(async () => {\n if (action.kind !== \"check-sparse\") return;\n\n try {\n try {\n await fs.access(action.path);\n } catch {\n return;\n }\n\n const current = await sparseService.readCurrent(action.path);\n if (current !== null && sparseService.patternsEqual(current, desired)) return;\n\n if (sparseService.isNarrowing(current, desired)) {\n const status = await this.gitService.getFullWorktreeStatus(action.path, false);\n if (!status.canRemove) {\n this.logger.warn(\n ` - Skipping sparse-checkout narrowing for '${action.branch}': ${status.reasons.join(\", \")}.`,\n );\n outcome.recordSkipped(\"sparse-checkout\", \"sparse_narrowing_unsafe\", {\n branch: action.branch,\n path: action.path,\n message: status.reasons.join(\", \"),\n });\n return;\n }\n }\n\n await sparseService.applyToWorktree(action.path, sparseConfig);\n await this.gitService.checkoutHead(action.path);\n this.logger.info(` - \u2705 Sparse-checkout updated for '${action.branch}'`);\n outcome.recordUpdated(action.branch, action.path, \"sparse_checkout\");\n } catch (error) {\n this.logger.warn(\n ` - \u26A0\uFE0F Failed to update sparse-checkout for '${action.branch}': ${getErrorMessage(error)}`,\n );\n outcome.recordFailed(\"sparse-checkout\", getErrorMessage(error), {\n reason: \"sparse_checkout_failed\",\n branch: action.branch,\n path: action.path,\n });\n }\n }),\n ),\n );\n }\n\n private async fetchLatestRemoteData(phaseTimer: PhaseTimer, syncContext: SyncRetryContext): Promise<void> {\n this.logger.info(\"Step 1: Fetching latest data from remote...\");\n phaseTimer.startPhase(\"Phase 1: Fetch\");\n this.progressEmitter.emit({ phase: \"fetch\", message: \"Fetching latest data from remote\" });\n\n try {\n await this.gitService.fetchAll();\n } catch (fetchError) {\n const errorMessage = getErrorMessage(fetchError);\n\n if (isLfsError(errorMessage) && !syncContext.lfsSkipEnabled && !this.config.skipLfs) {\n this.logger.info(\"\u26A0\uFE0F Fetch all failed due to LFS error. Attempting branch-by-branch fetch...\");\n this.logger.info(\"\u26A0\uFE0F Temporarily disabling LFS downloads for branch-by-branch fetch...\");\n this.gitService.setLfsSkipEnabled(true);\n syncContext.lfsSkipEnabled = true;\n await this.fetchBranchByBranch();\n } else {\n throw fetchError;\n }\n } finally {\n phaseTimer.endPhase();\n }\n }\n\n private async resolveSyncBranches(): Promise<{ remoteBranches: string[]; defaultBranch: string }> {\n const remoteBranches = this.config.branchMaxAge\n ? await this.getRemoteBranchesFilteredByActivity()\n : await this.getRemoteBranchesFilteredByName();\n const defaultBranch = this.gitService.getDefaultBranch();\n\n if (!remoteBranches.includes(defaultBranch)) {\n remoteBranches.push(defaultBranch);\n this.logger.info(`Ensuring default branch '${defaultBranch}' is retained.`);\n }\n\n return { remoteBranches, defaultBranch };\n }\n\n private async getRemoteBranchesFilteredByActivity(): Promise<string[]> {\n const branchesWithActivity = await this.gitService.getRemoteBranchesWithActivity();\n this.logger.info(`Found ${branchesWithActivity.length} remote branches.`);\n\n const branchNames = filterBranchesByName(\n branchesWithActivity.map((b) => b.branch),\n this.config.branchInclude,\n this.config.branchExclude,\n );\n\n if (branchNames.length < branchesWithActivity.length) {\n this.logger.info(\n `After branch name filtering: ${branchNames.length} of ${branchesWithActivity.length} branches.`,\n );\n }\n\n const branchNameSet = new Set(branchNames);\n const filteredByName = branchesWithActivity.filter((b) => branchNameSet.has(b.branch));\n const filteredBranches = filterBranchesByAge(filteredByName, this.config.branchMaxAge!);\n const remoteBranches = filteredBranches.map((b) => b.branch);\n\n this.logger.info(\n `After filtering by age (${formatDuration(this.config.branchMaxAge!)}): ${remoteBranches.length} branches.`,\n );\n\n if (filteredByName.length > remoteBranches.length) {\n const excludedCount = filteredByName.length - remoteBranches.length;\n this.logger.info(` - Excluded ${excludedCount} stale branches.`);\n }\n\n return remoteBranches;\n }\n\n private async getRemoteBranchesFilteredByName(): Promise<string[]> {\n const allBranches = await this.gitService.getRemoteBranches();\n this.logger.info(`Found ${allBranches.length} remote branches.`);\n\n const remoteBranches = filterBranchesByName(allBranches, this.config.branchInclude, this.config.branchExclude);\n\n if (remoteBranches.length < allBranches.length) {\n this.logger.info(`After branch name filtering: ${remoteBranches.length} of ${allBranches.length} branches.`);\n }\n\n return remoteBranches;\n }\n\n private async finalizeSyncAttempt(phaseTimer: PhaseTimer): Promise<void> {\n phaseTimer.startPhase(\"Phase 5: Cleanup\");\n this.progressEmitter.emit({ phase: \"cleanup\", message: \"Pruning worktree metadata\" });\n await this.gitService.pruneWorktrees();\n this.logger.info(\"Step 5: Pruned worktree metadata.\");\n phaseTimer.endPhase();\n }\n\n private async createNewWorktreesWithTiming(\n syncPlan: SyncPlan,\n phaseTimer: PhaseTimer,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n const maxConcurrent =\n this.config.parallelism?.maxWorktreeCreation ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_CREATION;\n phaseTimer.startPhase(\"Phase 2: Create\", maxConcurrent);\n this.progressEmitter.emit({ phase: \"create\", message: \"Creating worktrees for new branches\" });\n\n await this.createNewWorktrees(syncPlan.create, outcome);\n\n phaseTimer.setPhaseCount(\"Phase 2: Create\", syncPlan.create.length);\n phaseTimer.endPhase();\n }\n\n private async createNewWorktrees(actions: CreateAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n if (actions.length === 0) {\n this.logger.info(\"Step 2: No new branches to create worktrees for.\");\n return;\n }\n\n const plan: Array<{ branchName: string; worktreePath: string }> = [];\n for (const action of actions) {\n if (action.kind === \"skip-create\") {\n this.logger.error(\n ` \u274C Skipping '${action.branch}': sanitized worktree path '${action.path}' collides with existing branch '${action.conflictingBranch}'.`,\n );\n outcome.recordSkipped(\"branch\", \"path_collision\", {\n branch: action.branch,\n path: action.path,\n message: `Path collides with existing branch '${action.conflictingBranch}'`,\n });\n continue;\n }\n\n plan.push({ branchName: action.branch, worktreePath: action.path });\n }\n\n this.logger.info(`Step 2: Creating ${plan.length} new worktrees...`);\n\n // Worktree creation has concurrency=1 by default because Git's worktree.lock\n // can cause race conditions when multiple operations run simultaneously.\n // If concurrent operations try to create the same worktree, we gracefully handle\n // the \"already registered\" error by checking if the worktree actually exists.\n const maxConcurrent =\n this.config.parallelism?.maxWorktreeCreation ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_CREATION;\n const limit = pLimit(maxConcurrent);\n\n const results = await Promise.allSettled(\n plan.map(({ branchName, worktreePath }) =>\n limit(async () => {\n try {\n await this.gitService.addWorktree(branchName, worktreePath);\n this.logger.info(` \u2705 Created worktree for '${branchName}'`);\n outcome.recordCreated(branchName, worktreePath);\n } catch (error) {\n this.logger.error(` \u274C Failed to create worktree for '${branchName}':`, getErrorMessage(error));\n outcome.recordFailed(\"worktree\", getErrorMessage(error), {\n reason: \"create_failed\",\n branch: branchName,\n path: worktreePath,\n });\n throw error;\n }\n }),\n ),\n );\n\n const successCount = results.filter((r) => r.status === \"fulfilled\").length;\n this.logger.info(` Created ${successCount}/${plan.length} worktrees successfully`);\n }\n\n // Persist each worktree's upstream tip while the remote ref still exists.\n // This is the proof consulted after a squash-merge deletes the branch:\n // \"HEAD was on the remote before the deletion\" \u2014 without it every such\n // worktree reads as having unpushed commits forever. Best-effort: a failed\n // recording only means that worktree stays conservatively preserved.\n private async recordRemoteBranchTips(worktrees: Array<{ path: string; branch: string }>): Promise<void> {\n try {\n const tips = await this.gitService.getRemoteBranchTips();\n if (tips.size === 0) return;\n\n const limit = pLimit(this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS);\n\n await Promise.all(\n worktrees.map((wt) =>\n limit(async () => {\n const oid = tips.get(wt.branch);\n if (!oid) return;\n await this.gitService\n .recordRemoteTip(wt.path, wt.branch, oid)\n .catch((error: unknown) =>\n this.logger.warn(` - \u26A0\uFE0F Could not record remote tip for '${wt.branch}': ${getErrorMessage(error)}`),\n );\n }),\n ),\n );\n } catch (error) {\n this.logger.warn(`\u26A0\uFE0F Could not record remote branch tips: ${getErrorMessage(error)}`);\n }\n }\n\n // A removal authorized only by the fully-pushed proof must stay reversible:\n // without trash it would be a permanent delete of commits whose remote\n // branch may have been deleted unmerged.\n private blockedByDisabledTrash(status: WorktreeStatusResult): boolean {\n return status.fullyPushedUpstreamDeleted && !this.trashService.isEnabled();\n }\n\n private async pruneOldWorktreesWithTiming(\n actions: PruneAction[],\n phaseTimer: PhaseTimer,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n const maxConcurrent = this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n phaseTimer.startPhase(\"Phase 3: Prune\", maxConcurrent);\n this.progressEmitter.emit({ phase: \"prune\", message: \"Pruning stale worktrees\" });\n\n await this.pruneOldWorktrees(actions, outcome);\n\n phaseTimer.setPhaseCount(\"Phase 3: Prune\", actions.length);\n phaseTimer.endPhase();\n }\n\n private async pruneOldWorktrees(actions: PruneAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n if (actions.length > 0) {\n this.logger.info(`Step 3: Checking ${actions.length} stale worktrees to prune...`);\n\n // Two-phase approach: First check status in parallel (read-only, safe),\n // then remove worktrees in parallel (mutation, needs lower concurrency)\n const maxConcurrent = this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n const limit = pLimit(maxConcurrent);\n\n const statusResults = await Promise.allSettled(\n actions.map(({ branch: branchName, path: worktreePath }) =>\n limit(async () => {\n const status = await this.gitService.getFullWorktreeStatus(worktreePath, this.config.debug);\n return { branchName, worktreePath, status };\n }).catch((error) => {\n throw Object.assign(error instanceof Error ? error : new Error(String(error)), { branchName });\n }),\n ),\n );\n\n const toRemove: Array<{ branchName: string; worktreePath: string }> = [];\n const toSkip: Array<{\n branchName: string;\n worktreePath: string;\n status: Awaited<ReturnType<GitService[\"getFullWorktreeStatus\"]>>;\n }> = [];\n\n for (const result of statusResults) {\n if (result.status === \"fulfilled\") {\n const { branchName, worktreePath, status } = result.value;\n if (status.canRemove) {\n if (this.blockedByDisabledTrash(status)) {\n this.logger.warn(\n ` - \u26A0\uFE0F '${branchName}' was fully pushed before its remote branch was deleted, but trash is disabled \u2014 keeping worktree. Enable trash for reversible auto-removal, or remove manually.`,\n );\n outcome.recordSkipped(\"worktree\", \"fully_pushed_trash_disabled\", {\n branch: branchName,\n path: worktreePath,\n message: \"fully pushed before upstream deletion; trash disabled\",\n });\n } else {\n toRemove.push({ branchName, worktreePath });\n }\n } else {\n toSkip.push({ branchName, worktreePath, status });\n }\n } else {\n const branchName = (result.reason as Error & { branchName?: string })?.branchName ?? \"unknown\";\n this.logger.error(` - Error checking worktree '${branchName}':`, result.reason);\n this.logger.warn(` - \u26A0\uFE0F Skipping removal of '${branchName}' due to status check failure (conservative)`);\n outcome.recordSkipped(\"worktree\", \"prune_status_check_failed\", {\n branch: branchName,\n message: getErrorMessage(result.reason),\n });\n }\n }\n\n if (toRemove.length > 0) {\n const removeLimit = pLimit(\n this.config.parallelism?.maxWorktreeRemoval ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_REMOVAL,\n );\n\n const removeResults = await Promise.allSettled(\n toRemove.map(({ branchName, worktreePath }) =>\n removeLimit(async () => {\n try {\n // Re-validate status immediately before removal to close TOCTOU window.\n const recheck = await this.gitService.getFullWorktreeStatus(worktreePath, false);\n if (!recheck.canRemove || this.blockedByDisabledTrash(recheck)) {\n this.logger.warn(\n ` \u26A0\uFE0F Skipping removal of '${branchName}' - status changed since initial check: ${recheck.reasons.join(\", \")}`,\n );\n outcome.recordSkipped(\"worktree\", \"prune_status_changed\", {\n branch: branchName,\n path: worktreePath,\n message: recheck.reasons.join(\", \"),\n });\n return;\n }\n // The audit record must exist before the data is gone; an\n // unwritable audit log blocks removal (fail-closed).\n try {\n await this.removalAudit.record({\n action: \"prune_remove\",\n result: \"attempt\",\n path: worktreePath,\n branch: branchName,\n status: recheck,\n });\n } catch (auditError) {\n this.logger.warn(\n ` \u26A0\uFE0F Skipping removal of '${branchName}' - cannot write removal audit log: ${getErrorMessage(auditError)}`,\n );\n outcome.recordSkipped(\"worktree\", \"audit_log_unavailable\", {\n branch: branchName,\n path: worktreePath,\n message: getErrorMessage(auditError),\n });\n return;\n }\n // A previous removal may have moved the directory away and then\n // failed to clear the registration \u2014 re-trashing a missing path\n // would fail with ENOENT on every tick forever. There is nothing\n // left to preserve, so clear that one registration. Targeted\n // `worktree remove --force` (NOT global `worktree prune`): prune\n // would also drop unrelated unlocked registrations whose dirs sit\n // on a temporarily unavailable mount. A locked registration makes\n // single --force fail, which correctly preserves it.\n if ((await probePathExists(worktreePath)) === \"missing\") {\n await this.gitService.removeWorktree(worktreePath, { force: true });\n this.logger.info(` \u2705 Cleared dangling registration for '${branchName}' (directory already gone)`);\n outcome.recordRemoved(branchName, worktreePath);\n await this.removalAudit\n .record({ action: \"prune_remove\", result: \"success\", path: worktreePath, branch: branchName })\n .catch((auditError: unknown) =>\n this.logger.warn(` \u26A0\uFE0F Failed to write removal audit record: ${getErrorMessage(auditError)}`),\n );\n return;\n }\n let refWarning: string | undefined;\n if (this.trashService.isEnabled()) {\n const { entry, branchRefError } = await this.trashService.trashAndUnregisterWorktree({\n dirPath: worktreePath,\n branch: branchName,\n reason: \"prune\",\n keepPinOnReap: recheck.fullyPushedUpstreamDeleted,\n });\n if (branchRefError !== undefined) {\n refWarning = `leftover_branch_ref: could not delete branch ref '${branchName}': ${branchRefError}`;\n }\n const pushedNote = recheck.fullyPushedUpstreamDeleted\n ? \" \u2014 was fully pushed before its remote branch was deleted\"\n : \"\";\n this.logger.info(\n ` \u2705 Moved worktree for '${branchName}' to trash (id: ${entry.manifest.id})${pushedNote}`,\n );\n } else {\n await this.gitService.removeWorktree(worktreePath);\n this.logger.info(` \u2705 Removed worktree for '${branchName}'`);\n }\n outcome.recordRemoved(branchName, worktreePath, refWarning);\n await this.removalAudit\n .record({ action: \"prune_remove\", result: \"success\", path: worktreePath, branch: branchName })\n .catch((auditError: unknown) =>\n this.logger.warn(` \u26A0\uFE0F Failed to write removal audit record: ${getErrorMessage(auditError)}`),\n );\n } catch (error) {\n if (error instanceof WorktreeNotCleanError) {\n this.logger.warn(` \u26A0\uFE0F Skipping removal of '${branchName}' - git refused: ${getErrorMessage(error)}`);\n outcome.recordSkipped(\"worktree\", \"git_refused_removal\", {\n branch: branchName,\n path: worktreePath,\n message: getErrorMessage(error),\n });\n return;\n }\n if (error instanceof TrashOperationError) {\n this.logger.warn(` \u26A0\uFE0F Skipping removal of '${branchName}' - ${getErrorMessage(error)}`);\n outcome.recordSkipped(\"worktree\", \"trash_failed\", {\n branch: branchName,\n path: worktreePath,\n message: getErrorMessage(error),\n });\n return;\n }\n this.logger.error(` \u274C Failed to remove worktree for '${branchName}':`, getErrorMessage(error));\n outcome.recordFailed(\"worktree\", getErrorMessage(error), {\n reason: \"remove_failed\",\n branch: branchName,\n path: worktreePath,\n });\n throw error;\n }\n }),\n ),\n );\n\n const removedCount = removeResults.filter((r) => r.status === \"fulfilled\").length;\n this.logger.info(` Removed ${removedCount}/${toRemove.length} worktrees successfully`);\n }\n\n if (toSkip.length > 0) {\n this.logger.info(` Skipped ${toSkip.length} worktree(s) with local changes or unpushed commits`);\n }\n\n for (const { branchName, worktreePath, status } of toSkip) {\n outcome.recordSkipped(\"worktree\", \"unsafe_to_remove\", {\n branch: branchName,\n path: worktreePath,\n message: status.reasons.join(\", \"),\n });\n\n if (status.upstreamGone && status.hasUnpushedCommits) {\n this.logger.warn(` - \u26A0\uFE0F Cannot automatically remove '${branchName}' - upstream branch was deleted.`);\n this.logger.info(` Please review manually: cd ${worktreePath} && git log`);\n this.logger.info(\n ` If changes were squash-merged, you can safely remove with: git worktree remove ${worktreePath}`,\n );\n } else {\n this.logger.info(` - \u26A0\uFE0F Skipping removal of '${branchName}' due to: ${status.reasons.join(\", \")}.`);\n }\n\n if (this.config.debug && status.details) {\n this.logDebugDetails(branchName, status.details);\n }\n }\n } else {\n this.logger.info(\"Step 3: No stale worktrees to prune.\");\n }\n }\n\n private logDebugDetails(branchName: string, details: WorktreeStatusDetails): void {\n this.logger.info(`\\n \uD83D\uDD0D Debug details for '${branchName}':`);\n\n if (details.modifiedFiles > 0 && details.modifiedFilesList) {\n this.logger.info(` - Modified files (${details.modifiedFiles}):`);\n details.modifiedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.deletedFiles > 0 && details.deletedFilesList) {\n this.logger.info(` - Deleted files (${details.deletedFiles}):`);\n details.deletedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.renamedFiles > 0 && details.renamedFilesList) {\n this.logger.info(` - Renamed files (${details.renamedFiles}):`);\n details.renamedFilesList.forEach((file) => this.logger.info(` \u2022 ${file.from} \u2192 ${file.to}`));\n }\n if (details.createdFiles > 0 && details.createdFilesList) {\n this.logger.info(` - Created files (${details.createdFiles}):`);\n details.createdFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.conflictedFiles > 0 && details.conflictedFilesList) {\n this.logger.info(` - Conflicted files (${details.conflictedFiles}):`);\n details.conflictedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.untrackedFiles > 0 && details.untrackedFilesList) {\n this.logger.info(` - Untracked files (not ignored) (${details.untrackedFiles}):`);\n details.untrackedFilesList.forEach((file) => this.logger.info(` \u2022 ${file}`));\n }\n if (details.unpushedCommitCount !== undefined && details.unpushedCommitCount > 0) {\n this.logger.info(` - Unpushed commits: ${details.unpushedCommitCount}`);\n }\n if (details.stashCount !== undefined && details.stashCount > 0) {\n this.logger.info(` - Stashed changes: ${details.stashCount}`);\n }\n if (details.operationType) {\n this.logger.info(` - Operation in progress: ${details.operationType}`);\n }\n if (details.modifiedSubmodules && details.modifiedSubmodules.length > 0) {\n this.logger.info(` - Modified submodules (${details.modifiedSubmodules.length}):`);\n details.modifiedSubmodules.forEach((submodule) => this.logger.info(` \u2022 ${submodule}`));\n }\n\n this.logger.info(\"\");\n }\n\n private async fetchBranchByBranch(): Promise<void> {\n this.logger.info(\"Fetching branches individually to isolate LFS errors...\");\n\n const remoteBranches = await this.gitService.getRemoteBranches();\n this.logger.info(`Found ${remoteBranches.length} remote branches to fetch.`);\n\n const fetchLimit = pLimit(\n this.config.parallelism?.maxBranchFetches ?? DEFAULT_CONFIG.PARALLELISM.MAX_BRANCH_FETCHES,\n );\n const failedBranches: string[] = [];\n let successCount = 0;\n\n const results = await Promise.allSettled(\n remoteBranches.map((branch) =>\n fetchLimit(async () => {\n await this.gitService.fetchBranch(branch);\n return branch;\n }),\n ),\n );\n\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n if (result.status === \"fulfilled\") {\n successCount++;\n } else {\n const errorMessage = getErrorMessage(result.reason);\n this.logger.info(` \u26A0\uFE0F Failed to fetch branch '${remoteBranches[i]}': ${errorMessage}`);\n failedBranches.push(remoteBranches[i]);\n }\n }\n\n this.logger.info(`Branch-by-branch fetch completed: ${successCount}/${remoteBranches.length} successful`);\n\n if (failedBranches.length > 0) {\n this.logger.info(`\u26A0\uFE0F Failed to fetch ${failedBranches.length} branches due to errors.`);\n this.logger.info(` These branches will be skipped: ${failedBranches.join(\", \")}`);\n }\n }\n\n private async updateExistingWorktreesWithTiming(\n actions: UpdateAction[],\n phaseTimer: PhaseTimer,\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n const maxConcurrent =\n this.config.parallelism?.maxWorktreeUpdates ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_UPDATES;\n phaseTimer.startPhase(\"Phase 4: Update\", maxConcurrent);\n this.progressEmitter.emit({ phase: \"update\", message: \"Updating existing worktrees\" });\n\n await this.updateExistingWorktrees(actions, outcome);\n\n phaseTimer.setPhaseCount(\"Phase 4: Update\", actions.length);\n phaseTimer.endPhase();\n }\n\n private async updateExistingWorktrees(actions: UpdateAction[], outcome: SyncOutcomeAccumulator): Promise<void> {\n this.logger.info(\"Step 4: Checking for worktrees that need updates...\");\n\n const divergedDir = path.join(this.config.worktreeDir, GIT_CONSTANTS.DIVERGED_DIR_NAME);\n try {\n const diverged = await fs.readdir(divergedDir);\n if (diverged.length > 0) {\n this.logger.info(\n `\uD83D\uDCE6 Note: ${diverged.length} diverged worktree(s) in ${path.relative(process.cwd(), divergedDir)}`,\n );\n }\n } catch {\n // No diverged directory, that's fine.\n }\n\n type UpdateCheckResult =\n | { action: \"update\" | \"diverged\"; worktree: { path: string; branch: string } }\n | {\n action: \"skip\" | \"noop\";\n worktree: { path: string; branch: string };\n reason: string;\n message?: string;\n };\n\n // Phase 4a: Check which worktrees need updates (parallel, read-only, high concurrency)\n const maxConcurrent = this.config.parallelism?.maxStatusChecks ?? DEFAULT_CONFIG.PARALLELISM.MAX_STATUS_CHECKS;\n const limit = pLimit(maxConcurrent);\n\n const checkResults = await Promise.allSettled(\n actions.map((action) =>\n limit(async (): Promise<UpdateCheckResult> => {\n const worktree = { path: action.path, branch: action.branch };\n\n try {\n await fs.access(worktree.path);\n } catch {\n return { action: \"skip\", worktree, reason: \"missing_worktree_path\" };\n }\n\n const hasOp = await this.gitService.hasOperationInProgress(worktree.path);\n if (hasOp) return { action: \"skip\", worktree, reason: \"operation_in_progress\" };\n\n const isClean = await this.gitService.checkWorktreeStatus(worktree.path);\n if (!isClean) return { action: \"skip\", worktree, reason: \"dirty_worktree\" };\n\n const canFastForward = await this.gitService.canFastForward(worktree.path, worktree.branch);\n if (!canFastForward) {\n const isAhead = await this.gitService.isLocalAheadOfRemote(worktree.path, worktree.branch);\n if (isAhead) {\n this.logger.info(`\u23ED\uFE0F Skipping '${worktree.branch}' - has unpushed commits`);\n return { action: \"skip\", worktree, reason: \"local_ahead\" };\n }\n return { action: \"diverged\", worktree };\n }\n\n const isBehind = await this.gitService.isWorktreeBehind(worktree.path);\n if (!isBehind) return { action: \"noop\", worktree, reason: \"already_up_to_date\" };\n\n const sparseCfg = this.config.sparseCheckout;\n if (sparseCfg && sparseCfg.skipUpdateWhenOutsideSparse !== false) {\n const sparseService = this.gitService.getSparseCheckoutService();\n if (sparseService.resolveMode(sparseCfg) === \"cone\") {\n const diff = await this.gitService.getChangedPathsInRange(\n worktree.path,\n \"HEAD\",\n `origin/${worktree.branch}`,\n );\n // null = git diff failed; force update rather than treat the failure as \"no sparse paths affected\".\n if (diff !== null && !sparseService.pathsTouchSparse(diff, sparseCfg)) {\n this.logger.info(`\u23ED\uFE0F Skipping '${worktree.branch}' - upstream changes outside sparse paths`);\n return { action: \"skip\", worktree, reason: \"outside_sparse_checkout\" };\n }\n }\n }\n\n return { action: \"update\", worktree };\n }),\n ),\n );\n\n const worktreesToUpdate: { path: string; branch: string }[] = [];\n const divergedWorktrees: { path: string; branch: string }[] = [];\n\n for (const result of checkResults) {\n if (result.status === \"fulfilled\" && result.value) {\n switch (result.value.action) {\n case \"update\":\n worktreesToUpdate.push(result.value.worktree);\n break;\n case \"diverged\":\n divergedWorktrees.push(result.value.worktree);\n break;\n case \"noop\":\n outcome.recordNoop(\"worktree\", result.value.reason, result.value.worktree);\n break;\n case \"skip\":\n outcome.recordSkipped(\"worktree\", result.value.reason, result.value.worktree);\n break;\n }\n } else if (result.status === \"rejected\") {\n // Probe-only failure (status / fast-forward / divergence check threw). The\n // actual update is gated on success here, so a probe error means we never\n // touched the worktree \u2014 treat it as a skip, not a hard failure.\n this.logger.error(` - Error checking worktree:`, result.reason);\n outcome.recordSkipped(\"worktree\", \"update_check_failed\", {\n message: getErrorMessage(result.reason),\n });\n }\n }\n\n // Phase 4b: Perform mutations (updates + diverged handling) with lower concurrency\n const updateLimit = pLimit(\n this.config.parallelism?.maxWorktreeUpdates ?? DEFAULT_CONFIG.PARALLELISM.MAX_WORKTREE_UPDATES,\n );\n\n const mutationTasks: Promise<{ type: \"update\" | \"diverged\"; branch: string }>[] = [];\n\n for (const worktree of worktreesToUpdate) {\n mutationTasks.push(\n updateLimit(async () => {\n try {\n this.logger.info(` - Updating worktree '${worktree.branch}'...`);\n await this.gitService.updateWorktree(worktree.path);\n this.logger.info(` \u2705 Successfully updated '${worktree.branch}'.`);\n outcome.recordUpdated(worktree.branch, worktree.path, \"fast_forward\");\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n if (ERROR_MESSAGES.FAST_FORWARD_FAILED.some((msg) => errorMessage.includes(msg))) {\n this.logger.info(\n ` \u26A0\uFE0F Branch '${worktree.branch}' cannot be fast-forwarded. Checking for divergence...`,\n );\n try {\n await this.handleDivergedBranch(worktree, outcome);\n } catch (divergedError) {\n this.logger.error(` \u274C Failed to handle diverged branch '${worktree.branch}':`, divergedError);\n outcome.recordFailed(\"worktree\", getErrorMessage(divergedError), {\n reason: \"diverged_recovery_failed\",\n branch: worktree.branch,\n path: worktree.path,\n });\n throw divergedError;\n }\n } else {\n this.logger.error(` \u274C Failed to update '${worktree.branch}':`, error);\n outcome.recordFailed(\"worktree\", errorMessage, {\n reason: \"update_failed\",\n branch: worktree.branch,\n path: worktree.path,\n });\n throw error;\n }\n }\n return { type: \"update\" as const, branch: worktree.branch };\n }),\n );\n }\n\n for (const worktree of divergedWorktrees) {\n mutationTasks.push(\n updateLimit(async () => {\n try {\n await this.handleDivergedBranch(worktree, outcome);\n } catch (error) {\n this.logger.error(` \u274C Failed to handle diverged branch '${worktree.branch}':`, error);\n outcome.recordFailed(\"worktree\", getErrorMessage(error), {\n reason: \"diverged_recovery_failed\",\n branch: worktree.branch,\n path: worktree.path,\n });\n throw error;\n }\n return { type: \"diverged\" as const, branch: worktree.branch };\n }),\n );\n }\n\n if (mutationTasks.length > 0) {\n if (worktreesToUpdate.length > 0) {\n this.logger.info(` - Found ${worktreesToUpdate.length} worktrees behind their upstream branches.`);\n }\n if (divergedWorktrees.length > 0) {\n this.logger.info(` - Found ${divergedWorktrees.length} diverged worktrees to handle.`);\n }\n\n const mutationResults = await Promise.allSettled(mutationTasks);\n\n const successCount = mutationResults.filter((r) => r.status === \"fulfilled\").length;\n this.logger.info(` Processed ${successCount}/${mutationTasks.length} worktrees successfully`);\n } else {\n this.logger.info(\" - All worktrees are up to date.\");\n }\n }\n\n private async cleanupOrphanedDirectories(worktrees: { path: string; branch: string }[]): Promise<void> {\n try {\n const worktreeRelativePaths = worktrees.map((w) => path.relative(this.config.worktreeDir, w.path));\n const allDirs = await fs.readdir(this.config.worktreeDir);\n\n // Filter out special directories like .diverged.\n const regularDirs = allDirs.filter((dir) => !dir.startsWith(\".\"));\n\n const orphanedDirs: string[] = [];\n for (const dir of regularDirs) {\n const isPartOfWorktree = worktreeRelativePaths.some((worktreePath) => {\n return worktreePath === dir || worktreePath.startsWith(dir + path.sep);\n });\n\n if (!isPartOfWorktree) {\n orphanedDirs.push(dir);\n }\n }\n\n if (orphanedDirs.length > 0) {\n this.logger.info(`Found ${orphanedDirs.length} orphaned directories: ${orphanedDirs.join(\", \")}`);\n\n for (const dir of orphanedDirs) {\n const dirPath = path.join(this.config.worktreeDir, dir);\n try {\n const stat = await fs.stat(dirPath);\n if (!stat.isDirectory()) {\n continue;\n }\n\n // An \"orphan\" containing a .git may be a live checkout that git\n // failed to report (corrupt admin dir, transient list error) \u2014\n // quarantine it instead of deleting.\n const gitProbe = await probePathExists(path.join(dirPath, PATH_CONSTANTS.GIT_DIR));\n if (gitProbe === \"unknown\") {\n this.logger.warn(` - \u26A0\uFE0F Skipping orphaned directory ${dir}: cannot verify it is not a live checkout`);\n continue;\n }\n\n if (this.trashService.isEnabled()) {\n try {\n const entry = await this.trashService.trashDirectory({ dirPath, reason: \"orphan\" });\n this.logger.info(` - Moved orphaned directory '${dir}' to trash (id: ${entry.manifest.id})`);\n } catch (trashError) {\n this.logger.warn(` - \u26A0\uFE0F Skipping orphaned directory ${dir} - ${getErrorMessage(trashError)}`);\n }\n continue;\n }\n\n if (gitProbe === \"exists\") {\n const quarantinePath = await quarantineDirectory(dirPath);\n this.logger.warn(\n ` - \u26A0\uFE0F Orphaned directory ${dir} contains a .git; quarantined to '${quarantinePath}' instead of deleting.`,\n );\n await this.removalAudit\n .record({ action: \"orphan_quarantine\", result: \"success\", path: dirPath, quarantinePath })\n .catch((auditError: unknown) =>\n this.logger.warn(` \u26A0\uFE0F Failed to write removal audit record: ${getErrorMessage(auditError)}`),\n );\n continue;\n }\n\n try {\n await this.removalAudit.record({ action: \"orphan_delete\", result: \"attempt\", path: dirPath });\n } catch (auditError) {\n this.logger.warn(\n ` - \u26A0\uFE0F Skipping orphaned directory ${dir} - cannot write removal audit log: ${getErrorMessage(auditError)}`,\n );\n continue;\n }\n await fs.rm(dirPath, { recursive: true, force: true });\n this.logger.info(` - Removed orphaned directory: ${dir}`);\n } catch (error) {\n this.logger.error(` - Failed to remove orphaned directory ${dir}:`, error);\n }\n }\n }\n } catch (error) {\n this.logger.error(\"Error during orphaned directory cleanup:\", error);\n }\n }\n\n private async handleDivergedBranch(\n worktree: { path: string; branch: string },\n outcome: SyncOutcomeAccumulator,\n ): Promise<void> {\n this.logger.info(`\u26A0\uFE0F Branch '${worktree.branch}' has diverged from upstream. Analyzing...`);\n\n const treesIdentical = await this.gitService.compareTreeContent(worktree.path, worktree.branch);\n\n if (treesIdentical) {\n this.logger.info(`\u2705 Branch '${worktree.branch}' was rebased but files are identical. Resetting to upstream...`);\n await this.gitService.resetToUpstream(worktree.path, worktree.branch);\n this.logger.info(` Successfully updated '${worktree.branch}' to match upstream.`);\n outcome.recordUpdated(worktree.branch, worktree.path, \"reset_identical_tree\");\n } else {\n const hasLocalChanges = await this.hasLocalChangesSinceLastSync(worktree.path);\n\n if (!hasLocalChanges) {\n this.logger.info(\n `\u2705 Branch '${worktree.branch}' has diverged but you made no local changes. Resetting to upstream...`,\n );\n await this.gitService.resetToUpstream(worktree.path, worktree.branch);\n this.logger.info(` Successfully updated '${worktree.branch}' to match upstream.`);\n outcome.recordUpdated(worktree.branch, worktree.path, \"reset_no_local_changes\");\n } else {\n this.logger.info(`\uD83D\uDD12 Branch '${worktree.branch}' has diverged with local changes. Moving to diverged...`);\n\n // With trash disabled there is no pin ref, yet the local branch ref\n // must still be deleted below (or addWorktree would recreate the\n // worktree from the stale branch instead of upstream). A permanent\n // keep ref preserves the never-pushed commits first; failure aborts\n // while the worktree is still intact.\n let keepRef: string | null = null;\n if (!this.trashService.isEnabled()) {\n const localCommit = (await this.gitService.getCurrentCommit(worktree.path)).trim();\n keepRef = `${GIT_CONSTANTS.KEEP_REF_PREFIX}diverged-${Date.now().toString(36)}-${this.pathResolution.sanitizeBranchName(worktree.branch)}`;\n await this.gitService.updateRef(keepRef, localCommit);\n }\n\n const { divergedPath, manifest } = await this.divergeWorktree(worktree.path, worktree.branch);\n const relativePath = path.relative(process.cwd(), divergedPath);\n outcome.recordPreservedDiverged(worktree.branch, worktree.path, divergedPath);\n\n this.logger.info(` Moved to: ${relativePath}`);\n this.logger.info(` Your local changes are preserved. To review:`);\n this.logger.info(` cd ${relativePath}`);\n this.logger.info(` git diff origin/${worktree.branch}`);\n\n // force is safe here: the directory was already moved to .diverged/,\n // so only the stale registration is being cleared.\n await this.gitService.removeWorktree(worktree.path, { force: true });\n // Deliberately fatal on failure (unlike prune): addWorktree below\n // would silently recreate the worktree from the stale local branch\n // instead of upstream if the ref survived.\n if (manifest !== null) {\n await this.trashService.deleteTrashedBranchRef(manifest);\n } else {\n await this.gitService.deleteLocalBranch(worktree.branch);\n this.logger.info(\n ` Never-pushed commits remain recoverable at '${keepRef}' \u2014 recover with: git branch <name> ${keepRef}`,\n );\n }\n await this.removalAudit\n .record({\n action: \"diverged_replace\",\n result: \"success\",\n path: worktree.path,\n branch: worktree.branch,\n quarantinePath: divergedPath,\n })\n .catch((auditError: unknown) =>\n this.logger.warn(` \u26A0\uFE0F Failed to write removal audit record: ${getErrorMessage(auditError)}`),\n );\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(\n worktreePath: string,\n branchName: string,\n ): Promise<{ divergedPath: string; manifest: TrashManifest | null }> {\n if (this.trashService.isEnabled()) {\n // keepPinOnReap: diverged-replace trashes the only copy of never-pushed\n // commits, so pin/bundle failure must abort while the worktree is intact.\n const entry = await this.trashService.trashDirectory({\n dirPath: worktreePath,\n branch: branchName,\n reason: \"diverged-replace\",\n keepPinOnReap: true,\n });\n await this.writeDivergedInfoFile(entry.payloadPath, worktreePath, branchName, entry.manifest.headOid);\n return { divergedPath: entry.payloadPath, manifest: entry.manifest };\n }\n\n const divergedBaseDir = path.join(this.config.worktreeDir, GIT_CONSTANTS.DIVERGED_DIR_NAME);\n\n const timestamp = new Date().toISOString().split(\"T\")[0];\n const uniqueSuffix = Date.now().toString(36) + Math.random().toString(36).substring(2, 7);\n const safeBranchName = this.pathResolution.sanitizeBranchName(branchName);\n const divergedName = `${timestamp}-${safeBranchName}-${uniqueSuffix}`;\n const divergedPath = path.join(divergedBaseDir, divergedName);\n\n await fs.mkdir(divergedBaseDir, { recursive: true });\n\n try {\n await fs.rename(worktreePath, divergedPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === ERROR_MESSAGES.EXDEV) {\n await fs.cp(worktreePath, divergedPath, { recursive: true });\n await fs.rm(worktreePath, { recursive: true, force: true });\n } else {\n throw err;\n }\n }\n\n await this.writeDivergedInfoFile(divergedPath, worktreePath, branchName, null);\n\n return { divergedPath, manifest: null };\n }\n\n private async writeDivergedInfoFile(\n preservedPath: string,\n originalPath: string,\n branchName: string,\n knownLocalCommit: string | null,\n ): Promise<void> {\n const metadata = {\n originalBranch: branchName,\n divergedAt: new Date().toISOString(),\n reason: METADATA_CONSTANTS.DIVERGED_REASON,\n originalPath,\n localCommit: knownLocalCommit ?? (await this.gitService.getCurrentCommit(preservedPath)),\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: ${originalPath}`,\n };\n\n await fs.writeFile(\n path.join(preservedPath, METADATA_CONSTANTS.DIVERGED_INFO_FILE),\n JSON.stringify(metadata, null, 2),\n );\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 * as path from \"path\";\n\nimport { PathResolutionService } from \"./path-resolution.service\";\n\nimport type { SparseCheckoutConfig } from \"../types\";\n\nexport interface WorktreeInventory {\n remoteBranches: string[];\n defaultBranch: string;\n existingWorktrees: WorktreeEntry[];\n worktreeDir: string;\n}\n\nexport interface WorktreeEntry {\n path: string;\n branch: string;\n}\n\nexport type CreateAction =\n | { kind: \"create\"; branch: string; path: string }\n | { kind: \"skip-create\"; branch: string; path: string; reason: \"path-collision\"; conflictingBranch: string };\n\nexport type PruneAction = { kind: \"check-prune\"; branch: string; path: string };\n\nexport type UpdateAction = { kind: \"update-candidate\"; branch: string; path: string };\n\nexport type SparseAction =\n | { kind: \"check-sparse\"; branch: string; path: string }\n | { kind: \"skip-sparse\"; branch: string; path: string; reason: \"not-configured\" };\n\nexport type SyncAction = CreateAction | PruneAction | UpdateAction | SparseAction;\n\nexport interface SyncPlan {\n create: CreateAction[];\n prune: PruneAction[];\n update: UpdateAction[];\n sparse: SparseAction[];\n warnings: string[];\n}\n\nexport interface SyncPlanOptions {\n pathResolution?: PathResolutionService;\n updateExistingWorktrees?: boolean;\n sparseCheckout?: SparseCheckoutConfig;\n}\n\nexport function createWorktreeSyncPlan(inventory: WorktreeInventory, options: SyncPlanOptions = {}): SyncPlan {\n return {\n create: planCreateActions(inventory, options),\n prune: planPruneActions(inventory),\n update: options.updateExistingWorktrees === false ? [] : planUpdateActions(inventory),\n sparse: planSparseActions(inventory, options.sparseCheckout),\n warnings: [],\n };\n}\n\nexport function planCreateActions(inventory: WorktreeInventory, options: SyncPlanOptions = {}): CreateAction[] {\n const pathResolution = options.pathResolution ?? new PathResolutionService();\n const existingBranches = new Set(inventory.existingWorktrees.map((w) => w.branch));\n const newBranches = inventory.remoteBranches.filter(\n (branch) => !existingBranches.has(branch) && branch !== inventory.defaultBranch,\n );\n\n const reservedPaths = new Map<string, string>();\n for (const worktree of inventory.existingWorktrees) {\n reservedPaths.set(path.resolve(worktree.path), worktree.branch);\n }\n\n const actions: CreateAction[] = [];\n for (const branch of newBranches) {\n const worktreePath = pathResolution.getBranchWorktreePath(inventory.worktreeDir, branch);\n const resolved = path.resolve(worktreePath);\n const conflictingBranch = reservedPaths.get(resolved);\n\n if (conflictingBranch && conflictingBranch !== branch) {\n actions.push({\n kind: \"skip-create\",\n branch,\n path: worktreePath,\n reason: \"path-collision\",\n conflictingBranch,\n });\n continue;\n }\n\n reservedPaths.set(resolved, branch);\n actions.push({ kind: \"create\", branch, path: worktreePath });\n }\n\n return actions;\n}\n\nexport function planPruneActions(inventory: WorktreeInventory): PruneAction[] {\n const remoteBranches = new Set(inventory.remoteBranches);\n return inventory.existingWorktrees\n .filter((worktree) => !remoteBranches.has(worktree.branch))\n .map((worktree) => ({ kind: \"check-prune\", branch: worktree.branch, path: worktree.path }));\n}\n\nexport function planUpdateActions(inventory: WorktreeInventory): UpdateAction[] {\n const remoteBranches = new Set(inventory.remoteBranches);\n return inventory.existingWorktrees\n .filter((worktree) => remoteBranches.has(worktree.branch))\n .map((worktree) => ({ kind: \"update-candidate\", branch: worktree.branch, path: worktree.path }));\n}\n\nexport function planSparseActions(inventory: WorktreeInventory, sparseCheckout?: SparseCheckoutConfig): SparseAction[] {\n if (!sparseCheckout) {\n return [];\n }\n\n return inventory.existingWorktrees.map((worktree) => ({\n kind: \"check-sparse\",\n branch: worktree.branch,\n path: worktree.path,\n }));\n}\n", "import { spawn } from \"child_process\";\n\nimport { DEFAULT_CONFIG, HOOK_CONSTANTS } from \"../constants\";\nimport { shellEscape } from \"../utils/shell-escape\";\n\nimport type { HookContext, HooksConfig } from \"../types\";\nimport type { ChildProcess } from \"child_process\";\n\nexport interface HookExecutionCallbacks {\n onStdout?: (data: string) => void;\n onStderr?: (data: string) => void;\n onError?: (command: string, error: Error) => void;\n onComplete?: (command: string, exitCode: number | null) => void;\n}\n\nexport class HookExecutionService {\n private activeProcesses = new Set<ChildProcess>();\n private killTimers = new Set<ReturnType<typeof setTimeout>>();\n private timeoutTimers = new Set<ReturnType<typeof setTimeout>>();\n private timeoutMs: number = DEFAULT_CONFIG.HOOK_TIMEOUT_MS;\n\n setTimeoutMs(ms: number): void {\n this.timeoutMs = ms;\n }\n\n executeOnBranchCreated(\n hooks: HooksConfig | undefined,\n context: HookContext,\n callbacks: HookExecutionCallbacks = {},\n ): void {\n if (!hooks?.onBranchCreated?.length) {\n return;\n }\n\n const env = this.buildEnvironment(context);\n\n for (const command of hooks.onBranchCreated) {\n const resolvedCommand = this.resolveCommandPlaceholders(command, context);\n this.executeCommandInBackground(resolvedCommand, env, callbacks, context.worktreePath);\n }\n }\n\n public cleanup(): void {\n for (const timer of this.timeoutTimers) {\n clearTimeout(timer);\n }\n this.timeoutTimers.clear();\n\n for (const timer of this.killTimers) {\n clearTimeout(timer);\n }\n this.killTimers.clear();\n\n for (const child of this.activeProcesses) {\n try {\n child.kill(\"SIGTERM\");\n } catch {\n // Process may have already exited\n }\n const killTimer = setTimeout(() => {\n try {\n child.kill(\"SIGKILL\");\n } catch {\n // Process may have already exited\n }\n this.killTimers.delete(killTimer);\n }, 5000);\n this.killTimers.add(killTimer);\n }\n this.activeProcesses.clear();\n }\n\n private buildEnvironment(context: HookContext): NodeJS.ProcessEnv {\n return {\n ...process.env,\n [HOOK_CONSTANTS.ENV_VARS.BRANCH_NAME]: context.branchName,\n [HOOK_CONSTANTS.ENV_VARS.WORKTREE_PATH]: context.worktreePath,\n [HOOK_CONSTANTS.ENV_VARS.REPO_NAME]: context.repoName,\n [HOOK_CONSTANTS.ENV_VARS.BASE_BRANCH]: context.baseBranch,\n [HOOK_CONSTANTS.ENV_VARS.REPO_URL]: context.repoUrl,\n };\n }\n\n private resolveCommandPlaceholders(command: string, context: HookContext): string {\n return command\n .replaceAll(HOOK_CONSTANTS.PLACEHOLDERS.BRANCH_NAME, shellEscape(context.branchName))\n .replaceAll(HOOK_CONSTANTS.PLACEHOLDERS.WORKTREE_PATH, shellEscape(context.worktreePath))\n .replaceAll(HOOK_CONSTANTS.PLACEHOLDERS.REPO_NAME, shellEscape(context.repoName))\n .replaceAll(HOOK_CONSTANTS.PLACEHOLDERS.BASE_BRANCH, shellEscape(context.baseBranch))\n .replaceAll(HOOK_CONSTANTS.PLACEHOLDERS.REPO_URL, shellEscape(context.repoUrl));\n }\n\n private executeCommandInBackground(\n command: string,\n env: NodeJS.ProcessEnv,\n callbacks: HookExecutionCallbacks,\n cwd?: string,\n ): void {\n const child = spawn(command, {\n shell: true,\n detached: false,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env,\n cwd,\n });\n\n this.activeProcesses.add(child);\n let timedOut = false;\n\n const timer = setTimeout(() => {\n timedOut = true;\n this.timeoutTimers.delete(timer);\n this.activeProcesses.delete(child);\n try {\n child.kill(\"SIGTERM\");\n } catch {\n // Process may have already exited\n }\n const killTimer = setTimeout(() => {\n try {\n child.kill(\"SIGKILL\");\n } catch {\n // Process may have already exited\n }\n this.killTimers.delete(killTimer);\n }, 5000);\n this.killTimers.add(killTimer);\n callbacks.onError?.(command, new Error(`Hook timed out after ${this.timeoutMs}ms`));\n }, this.timeoutMs);\n this.timeoutTimers.add(timer);\n\n if (child.stdout) {\n child.stdout.on(\"data\", (data: Buffer) => {\n const output = data.toString().trim();\n if (output) {\n callbacks.onStdout?.(output);\n }\n });\n }\n\n if (child.stderr) {\n child.stderr.on(\"data\", (data: Buffer) => {\n const output = data.toString().trim();\n if (output) {\n callbacks.onStderr?.(output);\n }\n });\n }\n\n child.on(\"error\", (error) => {\n clearTimeout(timer);\n this.timeoutTimers.delete(timer);\n this.activeProcesses.delete(child);\n callbacks.onError?.(command, error);\n });\n\n child.on(\"close\", (code) => {\n clearTimeout(timer);\n this.timeoutTimers.delete(timer);\n if (timedOut) return;\n this.activeProcesses.delete(child);\n callbacks.onComplete?.(command, code);\n });\n }\n}\n", "/**\n * Escapes a value for POSIX shell single-quoted contexts only.\n */\nexport function shellEscape(value: string): string {\n return \"'\" + value.replace(/'/g, \"'\\\\''\") + \"'\";\n}\n", "export interface AppSyncProgress {\n repo: string;\n phase: string;\n message: string;\n progress?: number;\n processed?: number;\n total?: number;\n completed?: boolean;\n}\n\ntype AppEventMap = {\n updateLastSyncTime: void;\n setStatus: \"idle\" | \"syncing\";\n setSyncProgress: AppSyncProgress | null;\n setDiskSpace: string;\n addLog: { message: string; level: \"info\" | \"warn\" | \"error\" };\n uiReady: void;\n updateRepositoryCount: number;\n updateCronSchedule: string | undefined;\n};\n\ntype EventCallback<T> = T extends void ? () => void : (payload: T) => void;\n\ntype AnyEventCallback = EventCallback<AppEventMap[keyof AppEventMap]>;\n\nexport class AppEventEmitter {\n private listeners: Map<keyof AppEventMap, Set<AnyEventCallback>> = new Map();\n\n on<K extends keyof AppEventMap>(event: K, callback: EventCallback<AppEventMap[K]>): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(callback as AnyEventCallback);\n\n return () => {\n const set = this.listeners.get(event);\n if (set) {\n set.delete(callback as AnyEventCallback);\n if (set.size === 0) {\n this.listeners.delete(event);\n }\n }\n };\n }\n\n emit<K extends keyof AppEventMap>(event: K, ...args: AppEventMap[K] extends void ? [] : [AppEventMap[K]]): void {\n const callbacks = this.listeners.get(event);\n if (callbacks) {\n for (const callback of callbacks) {\n try {\n (callback as (payload?: AppEventMap[K]) => void)(args[0]);\n } catch (error) {\n console.error(`[app-events] Error in '${String(event)}' listener:`, error);\n }\n }\n }\n }\n\n removeAllListeners(): void {\n this.listeners.clear();\n }\n}\n", "import yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\n\nexport const CLI_COMMANDS = {\n RUN: \"run\",\n INIT: \"init\",\n LIST: \"list\",\n} as const;\n\nexport type CliCommand = (typeof CLI_COMMANDS)[keyof typeof CLI_COMMANDS];\n\nexport type CliOptions =\n | { command: typeof CLI_COMMANDS.RUN; config?: string; runOnce: boolean }\n | { command: typeof CLI_COMMANDS.INIT; config?: string; force: boolean }\n | { command: typeof CLI_COMMANDS.LIST; config?: string; filter?: string };\n\nexport function parseArguments(argv: string[] = hideBin(process.argv)): CliOptions {\n let parsed: CliOptions | undefined;\n\n yargs(argv)\n .scriptName(\"sync-worktrees\")\n .parserConfiguration({ \"camel-case-expansion\": false })\n .strict()\n .command(\n \"$0\",\n \"Sync git worktrees against a config file\",\n (y) =>\n y\n .option(\"config\", {\n alias: \"c\",\n type: \"string\",\n description: \"Path to JavaScript config file (auto-detected in CWD when omitted).\",\n })\n .option(\"runOnce\", {\n type: \"boolean\",\n description: \"Run a sync once and exit, overriding config runOnce settings for this invocation.\",\n default: false,\n }),\n (args) => {\n parsed = {\n command: CLI_COMMANDS.RUN,\n config: args.config,\n runOnce: args.runOnce,\n };\n },\n )\n .command(\n CLI_COMMANDS.INIT,\n \"Create a new config file interactively\",\n (y) =>\n y\n .option(\"config\", {\n alias: \"c\",\n type: \"string\",\n description: \"Target path for the generated config file (default: ./sync-worktrees.config.js).\",\n })\n .option(\"force\", {\n type: \"boolean\",\n description: \"Overwrite the target file if it already exists.\",\n default: false,\n }),\n (args) => {\n parsed = {\n command: CLI_COMMANDS.INIT,\n config: args.config,\n force: args.force,\n };\n },\n )\n .command(\n CLI_COMMANDS.LIST,\n \"List repositories configured in a config file and exit\",\n (y) =>\n y\n .option(\"config\", {\n alias: \"c\",\n type: \"string\",\n description: \"Path to JavaScript config file (auto-detected in CWD when omitted).\",\n })\n .option(\"filter\", {\n alias: \"f\",\n type: \"string\",\n description: \"Filter repositories by name (wildcards, comma-separated).\",\n }),\n (args) => {\n parsed = {\n command: CLI_COMMANDS.LIST,\n config: args.config,\n filter: args.filter,\n };\n },\n )\n .demandCommand(0, 0)\n .help()\n .alias(\"help\", \"h\")\n .version()\n .parseSync();\n\n if (!parsed) {\n throw new Error(\"Failed to parse CLI arguments\");\n }\n\n return parsed;\n}\n", "import * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nimport { CONFIG_FILE_NAMES } from \"../constants\";\nimport { ConfigFileExistsError } from \"../errors\";\n\nimport { fileExists } from \"./file-exists\";\nimport { extractRepoNameFromUrl } from \"./git-url\";\n\nimport type { InitConfigInput } from \"../types\";\n\nexport { ConfigFileExistsError };\n\ntype SerializableValue = string | number | boolean | null | undefined | SerializableObject | SerializableValue[];\ninterface SerializableObject {\n [key: string]: SerializableValue;\n}\n\nfunction serializeToESM(obj: SerializableValue, indent: number = 0): string {\n const spaces = \" \".repeat(indent);\n const innerSpaces = \" \".repeat(indent + 2);\n\n if (typeof obj === \"string\") {\n return JSON.stringify(obj);\n }\n\n if (typeof obj === \"number\" || typeof obj === \"boolean\") {\n return String(obj);\n }\n\n if (Array.isArray(obj)) {\n if (obj.length === 0) return \"[]\";\n const items = obj.map((item) => `${innerSpaces}${serializeToESM(item, indent + 2)}`).join(\",\\n\");\n return `[\\n${items}\\n${spaces}]`;\n }\n\n if (obj && typeof obj === \"object\") {\n const entries = Object.entries(obj)\n .filter(([_, value]) => value !== undefined)\n .map(([key, value]) => {\n const serializedValue = serializeToESM(value, indent + 2);\n return `${innerSpaces}${key}: ${serializedValue}`;\n });\n\n if (entries.length === 0) return \"{}\";\n return `{\\n${entries.join(\",\\n\")}\\n${spaces}}`;\n }\n\n return String(obj);\n}\n\nexport interface GenerateConfigFileOptions {\n overwrite?: boolean;\n}\n\nexport async function generateConfigFile(\n input: InitConfigInput,\n configPath: string,\n options: GenerateConfigFileOptions = {},\n): Promise<void> {\n const configDir = path.dirname(configPath);\n await fs.mkdir(configDir, { recursive: true });\n\n const worktreeDirRelative = path.relative(configDir, input.worktreeDir);\n const useRelativeWorktree = !worktreeDirRelative.startsWith(\"../../../\");\n\n const repoName = extractRepoNameFromUrl(input.repoUrl);\n\n const repository: SerializableObject = {\n name: repoName,\n repoUrl: input.repoUrl,\n worktreeDir: useRelativeWorktree ? `./${worktreeDirRelative}` : input.worktreeDir,\n };\n\n if (input.bareRepoDir) {\n const bareRepoDirRelative = path.relative(configDir, input.bareRepoDir);\n const useRelativeBare = !bareRepoDirRelative.startsWith(\"../../../\");\n repository.bareRepoDir = useRelativeBare ? `./${bareRepoDirRelative}` : input.bareRepoDir;\n }\n\n const defaults: SerializableObject = {\n cronSchedule: input.cronSchedule,\n };\n if (input.runOnce) {\n defaults.runOnce = input.runOnce;\n }\n\n const configObject: SerializableObject = {\n defaults,\n repositories: [repository],\n };\n\n const configContent = `// @ts-check\n\n/**\n * Sync-worktrees configuration file\n * Generated on ${new Date().toISOString()}\n */\n\n/** @satisfies {import(\"sync-worktrees\").SyncWorktreesConfig} */\nconst config = ${serializeToESM(configObject)};\n\nexport default config;\n`;\n\n try {\n await fs.writeFile(configPath, configContent, {\n encoding: \"utf-8\",\n flag: options.overwrite ? \"w\" : \"wx\",\n });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"EEXIST\") {\n throw new ConfigFileExistsError(configPath);\n }\n throw error;\n }\n}\n\nexport function getDefaultConfigPath(): string {\n return path.join(process.cwd(), \"sync-worktrees.config.js\");\n}\n\nexport async function findConfigInCwd(cwd: string = process.cwd()): Promise<string | null> {\n for (const name of CONFIG_FILE_NAMES) {\n const full = path.join(cwd, name);\n if (await fileExists(full)) {\n return full;\n }\n }\n return null;\n}\n", "import * as path from \"path\";\n\nimport { confirm, input, select } from \"@inquirer/prompts\";\n\nimport { extractRepoNameFromUrl } from \"./git-url\";\n\nimport type { InitConfigInput } from \"../types\";\n\nexport async function promptForInitConfig(): Promise<InitConfigInput> {\n console.log(\"\uD83D\uDD27 Welcome to sync-worktrees interactive setup!\\n\");\n\n const repoUrl = await input({\n message: \"Enter the Git repository URL (e.g., https://github.com/user/repo.git):\",\n validate: (value: string) => {\n if (!value.trim()) {\n return \"Repository URL is required\";\n }\n if (!value.match(/^(https?:\\/\\/|ssh:\\/\\/|git@|file:\\/\\/).*$/)) {\n return \"Please enter a valid Git URL (https://, ssh://, git@, or file://)\";\n }\n return true;\n },\n });\n\n const repoName = extractRepoNameFromUrl(repoUrl);\n const defaultWorktreeDir = repoName ? `./${repoName}` : \"\";\n\n let worktreeDir = await input({\n message: \"Enter the directory for storing worktrees:\",\n default: defaultWorktreeDir,\n validate: (value: string) => {\n if (!value.trim() && !defaultWorktreeDir) {\n return \"Worktree directory is required\";\n }\n return true;\n },\n });\n\n if (!worktreeDir.trim() && defaultWorktreeDir) {\n worktreeDir = defaultWorktreeDir;\n }\n\n if (!path.isAbsolute(worktreeDir)) {\n worktreeDir = path.resolve(worktreeDir);\n }\n\n let bareRepoDir: string | undefined;\n const askForBareDir = await confirm({\n message: \"Would you like to specify a custom location for the bare repository?\",\n default: false,\n });\n\n if (askForBareDir) {\n bareRepoDir = await input({\n message: \"Enter the directory for the bare repository:\",\n default: \"\",\n validate: (value: string) => {\n if (!value.trim()) {\n return \"Bare repository directory is required\";\n }\n return true;\n },\n });\n if (!path.isAbsolute(bareRepoDir)) {\n bareRepoDir = path.resolve(bareRepoDir);\n }\n }\n\n const runMode = await select({\n message: \"How would you like to run the sync?\",\n choices: [\n { name: \"Run once\", value: \"once\" },\n { name: \"Schedule with cron\", value: \"scheduled\" },\n ],\n });\n const runOnce = runMode === \"once\";\n\n let cronSchedule = \"0 * * * *\";\n if (!runOnce) {\n cronSchedule = await input({\n message: \"Enter the cron schedule (or press enter for default):\",\n default: \"0 * * * *\",\n validate: (value: string) => {\n if (!value.trim()) {\n return \"Cron schedule is required\";\n }\n const parts = value.trim().split(\" \");\n if (parts.length < 5) {\n return \"Invalid cron pattern. Expected format: '* * * * *'\";\n }\n return true;\n },\n });\n }\n\n return {\n repoUrl,\n worktreeDir,\n bareRepoDir,\n cronSchedule,\n runOnce,\n };\n}\n", "export type CleanupFn = (fast: boolean) => void | Promise<void>;\n\nexport interface SignalHandlerOptions {\n forceExitMs?: number;\n log?: (message: string) => void;\n exit?: (code: number) => void;\n process?: NodeJS.EventEmitter;\n}\n\nexport interface SignalHandlerHandle {\n register: (fn: CleanupFn) => void;\n dispose: () => void;\n}\n\nexport const DEFAULT_FORCE_EXIT_MS = 3000;\n\nexport function setupSignalHandlers(options: SignalHandlerOptions = {}): SignalHandlerHandle {\n const forceExitMs = options.forceExitMs ?? DEFAULT_FORCE_EXIT_MS;\n const log = options.log ?? ((msg: string): void => console.log(msg));\n const exit = options.exit ?? ((code: number): void => process.exit(code));\n const target = options.process ?? process;\n\n const cleanupFns: CleanupFn[] = [];\n let signalCount = 0;\n\n const handler = (signal: string): void => {\n signalCount += 1;\n if (signalCount >= 2) {\n log(`\\nReceived second ${signal}, forcing exit.`);\n exit(130);\n return;\n }\n log(`\\nReceived ${signal}, shutting down (Ctrl+C again to force exit)...`);\n\n const watchdog = setTimeout(() => {\n log(`\\nShutdown took longer than ${forceExitMs}ms, forcing exit.`);\n exit(130);\n }, forceExitMs);\n if (typeof watchdog.unref === \"function\") {\n watchdog.unref();\n }\n\n void Promise.allSettled(cleanupFns.map((fn) => Promise.resolve().then(() => fn(true)))).then(() => {\n clearTimeout(watchdog);\n exit(0);\n });\n };\n\n const sigintListener = (): void => handler(\"SIGINT\");\n const sigtermListener = (): void => handler(\"SIGTERM\");\n\n target.on(\"SIGINT\", sigintListener);\n target.on(\"SIGTERM\", sigtermListener);\n\n return {\n register: (fn: CleanupFn): void => {\n cleanupFns.push(fn);\n },\n dispose: (): void => {\n target.removeListener(\"SIGINT\", sigintListener);\n target.removeListener(\"SIGTERM\", sigtermListener);\n },\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["realpathSync", "path", "pLimit", "path", "path", "path", "retry", "React", "path", "cron", "pLimit", "spawn", "existsSync", "React", "useState", "useEffect", "useCallback", "useRef", "Box", "useInput", "React", "Box", "Text", "input", "React", "useState", "useEffect", "Box", "Text", "useInput", "useState", "useEffect", "useInput", "input", "React", "Box", "Text", "React", "useState", "useEffect", "useMemo", "useCallback", "useRef", "Box", "Text", "useInput", "usePaste", "input", "React", "useState", "useEffect", "useMemo", "useCallback", "useRef", "Box", "Text", "useInput", "usePaste", "React", "Text", "useState", "useRef", "useMemo", "useCallback", "useEffect", "useInput", "input", "selectedRepo", "usePaste", "Box", "isSelected", "isExpanded", "React", "useState", "useEffect", "useRef", "Box", "Text", "useInput", "input", "useState", "useRef", "schedule", "useCallback", "useInput", "input", "useEffect", "React", "Box", "pLimit", "path", "resolve", "formatDuration", "fs", "path", "fs", "path", "path", "fs", "path", "simpleGit", "fs", "simpleGit", "fs", "path", "simpleGit", "fs", "path", "path", "simpleGit", "simpleGit", "matcher", "fs", "path", "simpleGit", "simpleGit", "fs", "path", "simpleGit", "stat", "simpleGit", "simpleGit", "resolve", "error", "fs", "path", "fs", "path", "fs", "path", "fs", "path", "resolve", "fs", "path", "fs", "path", "createHash", "fs", "path", "createHash", "path", "stat", "pLimit", "fs", "pLimit", "schedule", "React", "path", "resolve", "formatDuration", "spawn", "existsSync", "fs", "path", "input", "path", "pLimit", "schedule", "input", "realpathSync"]
7
7
  }