{"version":3,"sources":["../../../src/services/sync-service.ts"],"names":["path"],"mappings":"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","file":"sync-service.cjs","sourcesContent":["import { FileService } from './file-service.js';\nimport { IssueService } from './issue-service.js';\nimport { IntentService } from './intent-service.js';\nimport { PathnameService } from './pathname-service.js';\nimport { ResolvedConfig } from '../utils/config.js';\nimport path from 'path';\n\nexport interface SyncChange {\n  id: string;\n  from: string;\n  to: string;\n  reason: string;\n}\n\nexport interface SyncError {\n  id: string;\n  error: string;\n}\n\nexport interface SyncResult {\n  changes: SyncChange[];\n  errors?: SyncError[];\n}\n\n/**\n * Service for synchronizing file locations with their metadata.\n * This service is responsible for:\n * - Finding mismatched file locations\n * - Generating sync plans\n * - Executing file moves safely\n */\nexport class SyncService {\n  constructor(\n    private fileService: FileService,\n    private issueService: IssueService,\n    private intentService: IntentService,\n    private pathnameService: PathnameService,\n    private config: ResolvedConfig\n  ) {}\n\n  /**\n   * Analyze the current state and generate a sync plan without making changes.\n   */\n  async analyzeSyncNeeded(): Promise<SyncResult> {\n    const changes: SyncChange[] = [];\n    const errors: SyncError[] = [];\n\n    // Get all markdown files in all possible directories\n    const allDirs = this.pathnameService.getActivityDirectories();\n    const files = await this.fileService.findFiles(\n      (f) => f.endsWith('.md'),\n      allDirs\n    );\n\n    // Check each file\n    for (const file of files) {\n      try {\n        // Get current metadata\n        const metadata = await this.issueService.frontmatterMethods.getFrontmatterMetadata(file);\n        if (!metadata) {\n          errors.push({\n            id: path.basename(file),\n            error: 'No frontmatter found'\n          });\n          continue;\n        }\n\n        // Let intent service determine where it should be\n        const intent = this.intentService.interpretIntent({\n          pathname: file,\n          metadata\n        });\n\n        // Get the target path\n        const targetPath = path.join(\n          intent.targetLocation.dirname,\n          intent.targetLocation.basename\n        );\n\n        // If paths don't match, we need to move the file\n        if (path.normalize(file) !== path.normalize(targetPath)) {\n          changes.push({\n            id: metadata.id || path.basename(file),\n            from: file,\n            to: targetPath,\n            reason: intent.reason\n          });\n        }\n\n        // If metadata needs updating, add that as a change too\n        if (JSON.stringify(metadata) !== JSON.stringify(intent.targetMetadata)) {\n          changes.push({\n            id: metadata.id || path.basename(file),\n            from: file,\n            to: file, // Same file, just metadata update\n            reason: 'Metadata needs to be updated to match intent'\n          });\n        }\n      } catch (error: any) {\n        errors.push({\n          id: path.basename(file),\n          error: error.message\n        });\n      }\n    }\n\n    return {\n      changes,\n      errors: errors.length > 0 ? errors : undefined\n    };\n  }\n\n  /**\n   * Execute the sync plan, moving files to their correct locations.\n   */\n  async executeSync(dryRun: boolean = false): Promise<SyncResult> {\n    // First analyze what needs to be done\n    const plan = await this.analyzeSyncNeeded();\n\n    // If this is a dry run, just return the plan\n    if (dryRun) {\n      return plan;\n    }\n\n    const errors: SyncError[] = plan.errors || [];\n    const executedChanges: SyncChange[] = [];\n\n    // Execute each change\n    for (const change of plan.changes) {\n      try {\n        // Skip if we've already processed this file\n        if (executedChanges.some(ec => ec.id === change.id)) {\n          continue;\n        }\n\n        // Get current metadata\n        const metadata = await this.issueService.frontmatterMethods.getFrontmatterMetadata(change.from);\n        if (!metadata) {\n          throw new Error('No frontmatter found');\n        }\n\n        // Let intent service determine final state\n        const intent = this.intentService.interpretIntent({\n          pathname: change.from,\n          metadata\n        });\n\n        // Move file with updated metadata\n        await this.issueService.fileMethods.moveFileWithMetadata(\n          change.from,\n          change.to,\n          intent.targetMetadata\n        );\n\n        executedChanges.push(change);\n      } catch (error: any) {\n        errors.push({\n          id: change.id,\n          error: error.message\n        });\n      }\n    }\n\n    return {\n      changes: executedChanges,\n      errors: errors.length > 0 ? errors : undefined\n    };\n  }\n} "]}