{"version":3,"file":"sync.mjs","names":["isPlainObjectFromMerge"],"sources":["../../src/cli/sync.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { glob } from \"glob\";\nimport { loadResolvedConfig } from \"../config\";\nimport type { SyncOptions, SyncResult } from \"../contract\";\nimport {\n  isPlainObject as isPlainObjectFromMerge,\n  mergeBosConfigWithTemplate,\n  resolveExtendsRef,\n} from \"../merge\";\nimport { syncResolvedSharedDeps } from \"../shared-deps\";\nimport { writeGeneratedInfra } from \"./infra\";\nimport {\n  buildChildAgentsMd,\n  extractSkillsBlock,\n  personalizeConfig,\n  resolveSourceDir,\n  runBunInstall,\n  runTypesGen,\n} from \"./init\";\nimport { writeSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_OWNED_SYNC_FILES = new Set([\n  \".env.example\",\n  \".gitignore\",\n  \"biome.json\",\n  \"bos.config.json\",\n  \"bunfig.toml\",\n  \"package.json\",\n  \".changeset/config.json\",\n  \".changeset/README.md\",\n  \".github/workflows/ci.yml\",\n  \".github/workflows/deploy.yml\",\n  \".github/workflows/staging.yml\",\n  \".github/workflows/release.yml\",\n  \"railway.toml\",\n  \"ui/package.json\",\n  \"ui/postcss.config.mjs\",\n  \"ui/rsbuild.config.ts\",\n  \"ui/tsconfig.json\",\n  \"ui/src/app.ts\",\n  \"ui/src/globals.d.ts\",\n  \"ui/src/hydrate.tsx\",\n  \"ui/src/lib/api.ts\",\n  \"ui/src/lib/auth.ts\",\n  \"ui/src/router.server.tsx\",\n  \"ui/src/router.tsx\",\n  \"ui/src/routes/__root.tsx\",\n  \"api/package.json\",\n  \"api/plugin.dev.ts\",\n  \"api/rspack.config.js\",\n  \"api/tsconfig.contract.json\",\n  \"api/tsconfig.json\",\n  \"api/src/lib/auth.ts\",\n  \"api/src/lib/context.ts\",\n  \"api/drizzle.config.ts\",\n  \"api/src/db/index.ts\",\n  \"api/src/db/layer.ts\",\n  \"api/src/db/migrate.ts\",\n  \"api/src/global.d.ts\",\n  \"api/tests/types.d.ts\",\n]);\n\ntype PackageJson = Record<string, unknown>;\n\nfunction computeHash(content: string | Uint8Array): string {\n  return createHash(\"sha256\").update(content).digest(\"hex\").substring(0, 16);\n}\n\nexport function isFrameworkOwnedSyncFile(filePath: string): boolean {\n  if (FRAMEWORK_OWNED_SYNC_FILES.has(filePath)) return true;\n  if (/^plugins\\/[^/]+\\/src\\/lib\\/(auth|context)\\.ts$/.test(filePath)) return true;\n  if (/^plugins\\/[^/]+\\/src\\/db\\/(index|layer|migrate)\\.ts$/.test(filePath)) return true;\n  if (/^plugins\\/[^/]+\\/rspack\\.config\\.js$/.test(filePath)) return true;\n  if (/^plugins\\/[^/]+\\/drizzle\\.config\\.ts$/.test(filePath)) return true;\n  if (/^plugins\\/[^/]+\\/src\\/global\\.d\\.ts$/.test(filePath)) return true;\n  if (/^plugins\\/[^/]+\\/tests\\/types\\.d\\.ts$/.test(filePath)) return true;\n  if (/^plugins\\/[^/]+\\/tsconfig\\.json$/.test(filePath)) return true;\n  if (/^plugins\\/[^/]+\\/tsconfig\\.contract\\.json$/.test(filePath)) return true;\n  return false;\n}\n\nfunction computeLocalHash(projectDir: string, filePath: string): string | null {\n  const fullPath = join(projectDir, filePath);\n  if (!existsSync(fullPath)) return null;\n  try {\n    const content = readFileSync(fullPath);\n    return computeHash(content);\n  } catch {\n    return null;\n  }\n}\n\nfunction backupFiles(projectDir: string, filePaths: string[]): string | null {\n  const filesToBackup = filePaths.filter((f) => existsSync(join(projectDir, f)));\n  if (filesToBackup.length === 0) return null;\n\n  const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n  const backupDir = join(projectDir, \".bos\", \"sync-backup\", timestamp);\n\n  for (const filePath of filesToBackup) {\n    const src = join(projectDir, filePath);\n    const dest = join(backupDir, filePath);\n    mkdirSync(dirname(dest), { recursive: true });\n    copyFileSync(src, dest);\n  }\n\n  return backupDir;\n}\n\nfunction mergeStringMaps(\n  local: Record<string, string> | undefined,\n  template: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n  if (!local && !template) return undefined;\n\n  const merged: Record<string, string> = { ...(local ?? {}) };\n  for (const [name, value] of Object.entries(template ?? {})) {\n    merged[name] = value;\n  }\n\n  return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeWorkspacePackages(local: unknown, template: unknown): string[] | undefined {\n  const localPackages = Array.isArray(local) ? local : [];\n  const templatePackages = Array.isArray(template) ? template : [];\n  if (localPackages.length === 0 && templatePackages.length === 0) return undefined;\n\n  const ordered = new Set<string>();\n  for (const entry of templatePackages) {\n    if (typeof entry === \"string\" && entry.length > 0) ordered.add(entry);\n  }\n  for (const entry of localPackages) {\n    if (typeof entry === \"string\" && entry.length > 0) ordered.add(entry);\n  }\n\n  const hasPluginEntry = [...ordered].some((e) => e.startsWith(\"plugins/\") && e !== \"plugins/*\");\n  if (hasPluginEntry) {\n    for (const entry of [...ordered]) {\n      if (entry.startsWith(\"plugins/\") && entry !== \"plugins/*\") {\n        ordered.delete(entry);\n      }\n    }\n    ordered.add(\"plugins/*\");\n  }\n\n  return ordered.size > 0 ? [...ordered] : undefined;\n}\n\nexport function mergePackageJson(\n  filePath: string,\n  local: PackageJson,\n  template: PackageJson,\n): PackageJson {\n  const merged: PackageJson = { ...local, ...template };\n\n  if (filePath === \"package.json\") {\n    for (const key of [\"name\", \"private\", \"version\"] as const) {\n      if (key in local) {\n        merged[key] = local[key];\n      }\n    }\n  } else if (\"version\" in local) {\n    merged.version = local.version;\n  }\n\n  for (const depField of [\n    \"dependencies\",\n    \"devDependencies\",\n    \"peerDependencies\",\n    \"overrides\",\n  ] as const) {\n    const localDeps = local[depField] as Record<string, string> | undefined;\n    const templateDeps = template[depField] as Record<string, string> | undefined;\n\n    const mergedDeps = mergeStringMaps(localDeps, templateDeps);\n    if (mergedDeps) {\n      merged[depField] = mergedDeps;\n    } else {\n      delete merged[depField];\n    }\n  }\n\n  if (\n    (local.scripts && typeof local.scripts === \"object\") ||\n    (template.scripts && typeof template.scripts === \"object\")\n  ) {\n    const mergedScripts = mergeStringMaps(\n      local.scripts as Record<string, string> | undefined,\n      template.scripts as Record<string, string> | undefined,\n    );\n    if (mergedScripts) {\n      merged.scripts = mergedScripts;\n    } else {\n      delete merged.scripts;\n    }\n  }\n\n  if (\n    (local.workspaces && typeof local.workspaces === \"object\") ||\n    (template.workspaces && typeof template.workspaces === \"object\")\n  ) {\n    const localWorkspaces = (local.workspaces ?? {}) as {\n      packages?: string[];\n      catalog?: Record<string, string>;\n    };\n    const templateWorkspaces = (template.workspaces ?? {}) as {\n      packages?: string[];\n      catalog?: Record<string, string>;\n    };\n\n    const mergedWorkspaces: { packages?: string[]; catalog?: Record<string, string> } = {\n      ...localWorkspaces,\n      ...templateWorkspaces,\n    };\n\n    const mergedPackages = mergeWorkspacePackages(\n      localWorkspaces.packages,\n      templateWorkspaces.packages,\n    );\n    if (mergedPackages) {\n      mergedWorkspaces.packages = mergedPackages;\n    } else {\n      delete mergedWorkspaces.packages;\n    }\n\n    const mergedCatalog = mergeStringMaps(localWorkspaces.catalog, templateWorkspaces.catalog);\n    if (mergedCatalog) {\n      mergedWorkspaces.catalog = mergedCatalog;\n    } else {\n      delete mergedWorkspaces.catalog;\n    }\n\n    if (Object.keys(mergedWorkspaces).length > 0) {\n      merged.workspaces = mergedWorkspaces;\n    } else {\n      delete merged.workspaces;\n    }\n  }\n\n  return merged;\n}\n\nfunction toSourcePath(sourceDir: string, destPath: string): string | null {\n  if (destPath.startsWith(\".github/\")) {\n    const templatePath = destPath.replace(/^\\.github\\//, \".github/templates/\");\n    if (existsSync(join(sourceDir, templatePath))) {\n      return templatePath;\n    }\n  }\n\n  const directPath = join(sourceDir, destPath);\n  if (existsSync(directPath)) {\n    return destPath;\n  }\n\n  return null;\n}\n\nfunction buildSyncedFileContent(\n  sourceDir: string,\n  projectDir: string,\n  filePath: string,\n  explicitDestPath?: string,\n): string | Uint8Array {\n  const src = join(sourceDir, filePath);\n  const destPath =\n    explicitDestPath ??\n    (filePath.startsWith(\".github/templates/\")\n      ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n      : filePath);\n  const dest = join(projectDir, destPath);\n\n  if (filePath.endsWith(\"bos.config.json\")) {\n    const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n    const templateContent = readFileSync(src, \"utf-8\");\n\n    if (localContent) {\n      const local = JSON.parse(localContent) as Record<string, unknown>;\n      const template = JSON.parse(templateContent) as Record<string, unknown>;\n      const merged = mergeBosConfigWithTemplate(local, template);\n      return `${JSON.stringify(merged, null, 2)}\\n`;\n    }\n  }\n\n  if (filePath.endsWith(\"package.json\")) {\n    const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n    const templateContent = readFileSync(src, \"utf-8\");\n\n    if (localContent) {\n      const local = JSON.parse(localContent) as Record<string, unknown>;\n      const template = JSON.parse(templateContent) as Record<string, unknown>;\n      const merged = mergePackageJson(destPath, local, template);\n      return `${JSON.stringify(merged, null, 2)}\\n`;\n    }\n  }\n\n  return readFileSync(src);\n}\n\nfunction writeSyncedFile(\n  sourceDir: string,\n  projectDir: string,\n  filePath: string,\n  explicitDestPath?: string,\n): void {\n  const destPath =\n    explicitDestPath ??\n    (filePath.startsWith(\".github/templates/\")\n      ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n      : filePath);\n  const dest = join(projectDir, destPath);\n  mkdirSync(dirname(dest), { recursive: true });\n  writeFileSync(dest, buildSyncedFileContent(sourceDir, projectDir, filePath, destPath));\n}\n\nasync function getSelectedChildPlugins(\n  projectDir: string,\n  localConfig: Record<string, unknown>,\n): Promise<string[]> {\n  if (!localConfig.plugins || typeof localConfig.plugins !== \"object\") {\n    return [];\n  }\n\n  const pluginDirs = new Set(\n    (\n      await glob(\"plugins/*/package.json\", {\n        cwd: projectDir,\n        nodir: true,\n        dot: false,\n        absolute: false,\n      })\n    )\n      .map((file) => file.match(/^plugins\\/([^/]+)\\/package\\.json$/)?.[1])\n      .filter((key): key is string => Boolean(key)),\n  );\n\n  const selected: string[] = [];\n  for (const [pluginKey, rawEntry] of Object.entries(\n    localConfig.plugins as Record<string, unknown>,\n  )) {\n    if (typeof rawEntry === \"string\") {\n      if (!rawEntry.startsWith(\"local:\")) {\n        selected.push(pluginKey);\n        continue;\n      }\n\n      const localPath = join(projectDir, rawEntry.slice(\"local:\".length).trim());\n      if (existsSync(localPath) || pluginDirs.has(pluginKey)) {\n        selected.push(pluginKey);\n      }\n      continue;\n    }\n\n    if (!rawEntry || typeof rawEntry !== \"object\") {\n      selected.push(pluginKey);\n      continue;\n    }\n\n    const entry = rawEntry as Record<string, unknown>;\n    const development = typeof entry.development === \"string\" ? entry.development : undefined;\n    if (!development?.startsWith(\"local:\")) {\n      selected.push(pluginKey);\n      continue;\n    }\n\n    const localPath = join(projectDir, development.slice(\"local:\".length).trim());\n    if (existsSync(localPath) || pluginDirs.has(pluginKey)) {\n      selected.push(pluginKey);\n    }\n  }\n\n  return selected;\n}\n\nfunction hasPluginsWorkspace(projectDir: string): boolean {\n  const packageJsonPath = join(projectDir, \"package.json\");\n  if (!existsSync(packageJsonPath)) return false;\n\n  try {\n    const pkg = JSON.parse(readFileSync(packageJsonPath, \"utf-8\")) as {\n      workspaces?: { packages?: string[] } | string[];\n    };\n    const workspaces = pkg.workspaces;\n    const packages = Array.isArray(workspaces)\n      ? workspaces\n      : Array.isArray(workspaces?.packages)\n        ? workspaces.packages\n        : [];\n    return packages.includes(\"plugins/*\");\n  } catch {\n    return false;\n  }\n}\n\nexport async function syncTemplate(projectDir: string, options: SyncOptions): Promise<SyncResult> {\n  // Sync reads the raw bos.config.json (not the resolved config) because it needs\n  // the user's explicit local settings: their extends ref, selected plugins, etc.\n  // The resolved config is the merged result and would include inherited parent\n  // values that the user didn't explicitly choose, which would break sync filtering.\n  const localConfig = JSON.parse(\n    readFileSync(join(projectDir, \"bos.config.json\"), \"utf-8\"),\n  ) as Record<string, unknown>;\n\n  let extendsRef: string | undefined;\n  if (typeof localConfig.extends === \"string\") {\n    extendsRef = localConfig.extends;\n  } else if (isPlainObjectFromMerge(localConfig.extends)) {\n    extendsRef = resolveExtendsRef(localConfig.extends as Record<string, string>, \"production\");\n  }\n  if (!extendsRef?.startsWith(\"bos://\")) {\n    return {\n      status: \"error\",\n      updated: [],\n      skipped: [],\n      added: [],\n      error: \"No extends field found in bos.config.json — cannot determine parent\",\n    };\n  }\n\n  const extendsMatch = extendsRef.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n  if (!extendsMatch) {\n    return {\n      status: \"error\",\n      updated: [],\n      skipped: [],\n      added: [],\n      error: `Invalid extends reference: ${extendsRef}`,\n    };\n  }\n\n  const extendsAccount = extendsMatch[1];\n  const extendsGateway = extendsMatch[2];\n\n  const { sourceDir, cleanup } = await resolveSourceDir({\n    extendsAccount,\n    extendsGateway,\n  });\n\n  try {\n    const childPlugins = await getSelectedChildPlugins(projectDir, localConfig);\n    const withUi = existsSync(join(projectDir, \"ui\", \"package.json\"));\n    const withApi = existsSync(join(projectDir, \"api\", \"package.json\"));\n    const withHost = existsSync(join(projectDir, \"host\", \"package.json\"));\n    const withPlugins = childPlugins.length > 0 || hasPluginsWorkspace(projectDir);\n\n    const destToSource = new Map<string, string>();\n    for (const destPath of FRAMEWORK_OWNED_SYNC_FILES) {\n      if (destPath.startsWith(\"ui/\") && !withUi) continue;\n      if (destPath.startsWith(\"api/\") && !withApi) continue;\n      if (destPath.startsWith(\"host/\") && !withHost) continue;\n      const sourcePath = toSourcePath(sourceDir, destPath);\n      if (!sourcePath) continue;\n      destToSource.set(destPath, sourcePath);\n    }\n\n    // Sync api/src/lib/{auth,context}.ts into each plugin's src/lib/\n    for (const pluginKey of childPlugins) {\n      if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\"))) continue;\n      for (const libFile of [\"auth.ts\", \"context.ts\"]) {\n        const sourceFile = `api/src/lib/${libFile}`;\n        if (!existsSync(join(sourceDir, sourceFile))) continue;\n        destToSource.set(`plugins/${pluginKey}/src/lib/${libFile}`, sourceFile);\n      }\n    }\n\n    // Sync api/src/global.d.ts into each plugin's src/\n    for (const pluginKey of childPlugins) {\n      if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\"))) continue;\n      const sourceFile = \"api/src/global.d.ts\";\n      if (!existsSync(join(sourceDir, sourceFile))) continue;\n      destToSource.set(`plugins/${pluginKey}/src/global.d.ts`, sourceFile);\n    }\n\n    // Sync tests/types.d.ts into each plugin's tests/\n    for (const pluginKey of childPlugins) {\n      if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n      const sourceFile = \"plugins/_template/tests/types.d.ts\";\n      if (!existsSync(join(sourceDir, sourceFile))) continue;\n      destToSource.set(`plugins/${pluginKey}/tests/types.d.ts`, sourceFile);\n    }\n\n    // Sync api/src/db/{index,layer,migrate}.ts into each plugin's src/db/\n    for (const pluginKey of childPlugins) {\n      if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\", \"db\"))) continue;\n      for (const dbFile of [\"index.ts\", \"layer.ts\", \"migrate.ts\"]) {\n        const sourceFile = `api/src/db/${dbFile}`;\n        if (!existsSync(join(sourceDir, sourceFile))) continue;\n        destToSource.set(`plugins/${pluginKey}/src/db/${dbFile}`, sourceFile);\n      }\n    }\n\n    // Sync rspack.config.js from the template into each plugin\n    for (const pluginKey of childPlugins) {\n      if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n      const sourceFile = \"plugins/_template/rspack.config.js\";\n      if (!existsSync(join(sourceDir, sourceFile))) continue;\n      destToSource.set(`plugins/${pluginKey}/rspack.config.js`, sourceFile);\n    }\n\n    // Sync drizzle.config.ts from api into each DB-enabled plugin\n    for (const pluginKey of childPlugins) {\n      if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\", \"db\"))) continue;\n      const sourceFile = \"api/drizzle.config.ts\";\n      if (!existsSync(join(sourceDir, sourceFile))) continue;\n      destToSource.set(`plugins/${pluginKey}/drizzle.config.ts`, sourceFile);\n    }\n\n    // Sync tsconfig files from the template into each plugin\n    for (const pluginKey of childPlugins) {\n      if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n      for (const tsconfigFile of [\"tsconfig.json\", \"tsconfig.contract.json\"]) {\n        const sourceFile = `plugins/_template/${tsconfigFile}`;\n        if (!existsSync(join(sourceDir, sourceFile))) continue;\n        destToSource.set(`plugins/${pluginKey}/${tsconfigFile}`, sourceFile);\n      }\n    }\n\n    const updated: string[] = [];\n    const skipped: string[] = [];\n    const added: string[] = [];\n\n    for (const [destPath, filePath] of destToSource.entries()) {\n      const localHash = computeLocalHash(projectDir, destPath);\n      const sourceHash = computeHash(buildSyncedFileContent(sourceDir, projectDir, filePath));\n\n      if (localHash === null) {\n        added.push(destPath);\n        continue;\n      }\n\n      if (localHash !== sourceHash) {\n        updated.push(destPath);\n      }\n    }\n\n    const account = (localConfig.account as string) || extendsAccount;\n    const domain = (localConfig.domain as string) || extendsGateway;\n    const overrides: Array<\"ui\" | \"api\" | \"host\" | \"plugins\"> = [];\n    if (withUi) overrides.push(\"ui\");\n    if (withApi) overrides.push(\"api\");\n    if (withHost) overrides.push(\"host\");\n    if (withPlugins) overrides.push(\"plugins\");\n\n    if (options.dryRun) {\n      const agentsMdSourcePath = toSourcePath(sourceDir, \"AGENTS.md\");\n      if (agentsMdSourcePath) {\n        const agentsMdSourceContent = readFileSync(join(sourceDir, agentsMdSourcePath), \"utf-8\");\n        const skillsBlock = extractSkillsBlock(agentsMdSourceContent);\n        if (skillsBlock) {\n          const expectedContent = buildChildAgentsMd(skillsBlock, {\n            overrides,\n            plugins: childPlugins,\n          });\n          const expectedHash = computeHash(expectedContent);\n          const agentsMdLocalHash = computeLocalHash(projectDir, \"AGENTS.md\");\n          if (agentsMdLocalHash !== expectedHash) {\n            updated.push(\"AGENTS.md\");\n          }\n        }\n      }\n\n      return {\n        status: \"dry-run\",\n        updated,\n        skipped,\n        added,\n      };\n    }\n\n    const filesToWrite = [...updated, ...added];\n\n    if (filesToWrite.length > 0) {\n      backupFiles(projectDir, filesToWrite);\n\n      for (const destPath of filesToWrite) {\n        const sourcePath = destToSource.get(destPath) ?? destPath;\n        writeSyncedFile(sourceDir, projectDir, sourcePath, destPath);\n      }\n    }\n\n    await personalizeConfig(projectDir, {\n      extendsAccount,\n      extendsGateway,\n      account,\n      domain,\n      overrides,\n      plugins: childPlugins,\n      workspaceOpts: { sourceDir },\n      mode: \"sync\",\n      existingConfig: localConfig,\n    });\n\n    await syncResolvedSharedDeps({\n      configDir: projectDir,\n      hostMode: \"local\",\n    });\n\n    const syncedConfig = await loadResolvedConfig({ cwd: projectDir });\n    if (syncedConfig?.runtime) {\n      writeGeneratedInfra(projectDir, syncedConfig.runtime);\n    }\n\n    const newSnapshotFiles: Record<string, string> = {};\n    for (const destPath of destToSource.keys()) {\n      const hash = computeLocalHash(projectDir, destPath);\n      if (hash) {\n        newSnapshotFiles[destPath] = hash;\n      }\n    }\n\n    const agentsMdSourcePath = toSourcePath(sourceDir, \"AGENTS.md\");\n    if (agentsMdSourcePath) {\n      const agentsMdSourceContent = readFileSync(join(sourceDir, agentsMdSourcePath), \"utf-8\");\n      const skillsBlock = extractSkillsBlock(agentsMdSourceContent);\n      if (skillsBlock) {\n        const expectedContent = buildChildAgentsMd(skillsBlock, {\n          overrides,\n          plugins: childPlugins,\n        });\n        const expectedHash = computeHash(expectedContent);\n\n        const agentsMdLocalHash = computeLocalHash(projectDir, \"AGENTS.md\");\n        if (agentsMdLocalHash !== expectedHash) {\n          writeFileSync(join(projectDir, \"AGENTS.md\"), expectedContent);\n          updated.push(\"AGENTS.md\");\n        }\n\n        newSnapshotFiles[\"AGENTS.md\"] = expectedHash;\n      }\n    }\n\n    await writeSnapshot(projectDir, {\n      parentRef: `bos://${extendsAccount}/${extendsGateway}`,\n      files: newSnapshotFiles,\n    });\n\n    if (!options.noInstall) {\n      await runBunInstall(projectDir);\n      await runTypesGen(projectDir);\n    }\n\n    return {\n      status: \"synced\",\n      updated,\n      skipped,\n      added,\n    };\n  } finally {\n    await cleanup();\n  }\n}\n"],"mappings":"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"}