UNPKG

everything-dev

Version:

A consolidated product package for building Module Federation apps with oRPC APIs.

1 lines • 39.4 kB
{"version":3,"file":"sync.mjs","names":["computeHash","parseYaml","isPlainObjectFromMerge"],"sources":["../../../src/services/scaffold/sync.ts"],"sourcesContent":["import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative } from \"node:path\";\nimport { glob } from \"glob\";\nimport { parse as parseYaml } from \"yaml\";\nimport type { SyncResult } from \"../../contract\";\nimport { materializeViaLayer } from \"../../infra/materializer\";\nimport { computeSnapshotHash as computeHash } from \"../../utils/snapshot-hash\";\nimport { resolvePlatformManifest } from \"../platform/manifest\";\nimport { loadInProcessDescriptor } from \"../resolution/load\";\nimport { isPlainObject as isPlainObjectFromMerge, resolveExtendsRef } from \"../resolution/merge\";\nimport { openResolution } from \"../resolution/session\";\nimport { readWorkspaceCatalog } from \"../workspace/catalog\";\nimport { syncResolvedSharedDeps } from \"../workspace/shared-deps\";\nimport { findWorkspaceRoot } from \"../workspace/workspace\";\nimport {\n buildChildAgentsMd,\n buildChildRootScripts,\n extractSkillsBlock,\n releaseRefCandidates,\n resolveSourceDir,\n runPnpmInstall,\n runTypesGen,\n} from \"./init\";\nimport {\n AGENT_SYNC_GLOBS,\n CHILD_OWNED_BLOCK_START,\n extractChildOwnedBlock,\n FRAMEWORK_OWNED_SYNC_FILES,\n spliceChildOwnedBlock,\n} from \"./ownership\";\nimport { readSnapshot, writeSnapshot } from \"./snapshot\";\n\nexport * from \"./ownership\";\n\n/**\n * Service-level sync options — deliberately narrower than the CLI contract's\n * SyncOptionsSchema: `json` is a terminal-rendering concern and never crosses\n * this seam.\n */\nexport interface TemplateSyncOptions {\n dryRun?: boolean;\n /** Overwrite conflicted files anyway (with a backup). Without it, anything\n * the three-way comparison cannot resolve aborts the whole run — nothing is\n * written, not even the clean updates. */\n force?: boolean;\n noInstall?: boolean;\n}\n\ntype PackageJson = Record<string, unknown>;\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 childScripts?: Record<string, string>,\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 childScripts\n ) {\n const mergedScripts = mergeStringMaps(\n local.scripts as Record<string, string> | undefined,\n filePath === \"package.json\" && childScripts\n ? childScripts\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\n/**\n * Child-shape normalization for every manifest sync writes (#521): the parent\n * repo's own root manifest uses `workspace:^` specifiers, which only resolve\n * where the framework packages are vendored workspace members. A child has no\n * such members — any `workspace:` specifier that lands in a child manifest\n * breaks the next `pnpm install --frozen-lockfile`. Runs on the merged (or\n * raw-template) object before the bytes are written, so both the `updated`\n * and `conflicted` outcomes land in child shape. A `workspace:` specifier\n * without a catalog entry is left alone — there is no version to pin.\n */\nexport function normalizeChildManifest(pkg: PackageJson, catalog: Record<string, string>): boolean {\n let modified = false;\n\n for (const fieldName of [\"dependencies\", \"devDependencies\", \"peerDependencies\"] as const) {\n const field = pkg[fieldName] as Record<string, string> | undefined;\n if (!field) continue;\n for (const [name, specifier] of Object.entries(field)) {\n if (specifier.startsWith(\"workspace:\") && catalog[name]) {\n field[name] = \"catalog:\";\n modified = true;\n }\n }\n }\n\n const dependencies = pkg.dependencies as Record<string, string> | undefined;\n const devDependencies = pkg.devDependencies as Record<string, string> | undefined;\n if (dependencies && devDependencies) {\n for (const name of Object.keys(devDependencies)) {\n if (name in dependencies) {\n delete devDependencies[name];\n modified = true;\n }\n }\n }\n\n return modified;\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\n/**\n * Release-scoped workflow refs (ADR 0034 pt 4): when a platform manifest\n * resolves, the child's *framework-owned* reusable-workflow wrappers pin the\n * framework's version tag instead of `@main`. Only refs into the framework\n * repo's own `.github/workflows/` repoint — third-party actions tracking\n * `@main` are nobody's release contract. Applied at content-build time so the\n * three-way hash comparison and the written bytes stay consistent.\n */\nexport function applyReleaseRefs(content: string, releaseTag: string): string {\n return content.replace(\n /(uses:\\s*\\S*everything-dev\\/\\.github\\/workflows\\/[^\\s@]+@)main\\b/g,\n `$1${releaseTag}`,\n );\n}\n\n/**\n * The workflow pin derives from what the release tarball actually resolved\n * from: the canonical `v<version>` tag when it resolved, otherwise the\n * resolved commit sha. No resolved ref/sha → the release tag itself.\n */\nexport function resolveWorkflowReleasePin(\n releaseTag: string,\n resolvedRef?: string,\n resolvedSha?: string,\n): string {\n if (resolvedRef?.startsWith(\"v\")) return resolvedRef;\n return resolvedSha ?? releaseTag;\n}\n\nfunction buildSyncedFileContent(\n sourceDir: string,\n projectDir: string,\n filePath: string,\n explicitDestPath?: string,\n childScripts?: Record<string, string>,\n release?: 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(\"package.json\")) {\n const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n const templateContent = readFileSync(src, \"utf-8\");\n const catalog = readWorkspaceCatalog(findWorkspaceRoot(projectDir)?.dir ?? projectDir);\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, childScripts);\n normalizeChildManifest(merged, catalog);\n return `${JSON.stringify(merged, null, 2)}\\n`;\n }\n\n const template = JSON.parse(templateContent) as Record<string, unknown>;\n normalizeChildManifest(template, catalog);\n return `${JSON.stringify(template, null, 2)}\\n`;\n }\n\n const raw = readFileSync(src);\n\n // The child-owned block protocol (#538): framework-owned files carrying the\n // markers get their marked span re-inserted from the child's local copy\n // before any hash is computed — the splice happens at content-build time,\n // so the side-by-side hash comparison and the written bytes agree. Files\n // synced before the markers existed lift their `variables` literal onto the\n // protocol on the first pass.\n const template = raw.toString(\"utf-8\");\n if (template.includes(CHILD_OWNED_BLOCK_START) && filePath.endsWith(\"plugin.dev.ts\")) {\n const destPathLocal = join(projectDir, destPath);\n if (existsSync(destPathLocal)) {\n const childBlock = extractChildOwnedBlock(readFileSync(destPathLocal, \"utf-8\"));\n if (childBlock) {\n return spliceChildOwnedBlock(template, childBlock);\n }\n }\n return template;\n }\n\n if (release && filePath.startsWith(\".github/templates/workflows/\")) {\n return applyReleaseRefs(raw.toString(\"utf-8\"), release);\n }\n return raw;\n}\n\nfunction writeSyncedFile(\n sourceDir: string,\n projectDir: string,\n filePath: string,\n explicitDestPath?: string,\n childScripts?: Record<string, string>,\n release?: 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(\n dest,\n buildSyncedFileContent(sourceDir, projectDir, filePath, destPath, childScripts, release),\n );\n}\n\n/**\n * The child AGENTS.md the parent template's skills block personalizes to —\n * shared by the dry-run preview and the write path so both agree on when\n * AGENTS.md counts as drifted.\n */\nfunction expectedChildAgentsMd(\n sourceDir: string,\n overrides: Array<\"ui\" | \"api\" | \"host\" | \"plugins\">,\n childPlugins: string[],\n): { content: string; hash: string } | null {\n const agentsMdSourcePath = toSourcePath(sourceDir, \"AGENTS.md\");\n if (!agentsMdSourcePath) return null;\n const skillsBlock = extractSkillsBlock(\n readFileSync(join(sourceDir, agentsMdSourcePath), \"utf-8\"),\n );\n if (!skillsBlock) return null;\n const content = buildChildAgentsMd(skillsBlock, { overrides, plugins: childPlugins });\n return { content, hash: computeHash(content) };\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 root = findWorkspaceRoot(projectDir);\n if (!root) return false;\n const rel = relative(root.dir, projectDir);\n const baseDir = rel.startsWith(\"..\") || rel === \"\" ? root.dir : projectDir;\n for (const manifest of [\"pnpm-workspace.yaml\", \"package.json\"]) {\n const manifestPath = join(baseDir, manifest);\n if (!existsSync(manifestPath)) continue;\n try {\n const content = readFileSync(manifestPath, \"utf-8\");\n const packages =\n manifest === \"pnpm-workspace.yaml\"\n ? (parseYaml(content) as { packages?: unknown } | null)?.packages\n : (\n JSON.parse(content) as {\n workspaces?: { packages?: string[] } | string[];\n }\n ).workspaces;\n const globs: string[] = Array.isArray(packages)\n ? packages\n : Array.isArray((packages as { packages?: string[] })?.packages)\n ? ((packages as { packages?: string[] }).packages ?? [])\n : [];\n if (globs.includes(\"plugins/*\")) return true;\n } catch {\n return false;\n }\n }\n return false;\n}\n\nexport async function syncTemplate(\n projectDir: string,\n options: TemplateSyncOptions = {},\n): Promise<SyncResult> {\n // Sync reads the user's authored config — the materialized bos.app.ts\n // descriptor, not the resolved config: it needs the user's explicit local\n // settings (their extends ref, selected plugins, etc.). The resolved config\n // is the merged result and would include inherited parent values that the\n // user didn't explicitly choose, which would break sync filtering.\n const configPath = join(projectDir, \"bos.app.ts\");\n if (!existsSync(configPath)) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n conflicted: [],\n error: \"No bos.app.ts found — template sync only applies to TS-form children\",\n };\n }\n const localConfig = (await loadInProcessDescriptor(\n readFileSync(configPath, \"utf-8\"),\n configPath,\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 conflicted: [],\n error: \"No extends field found in bos.app.ts — 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 conflicted: [],\n error: `Invalid extends reference: ${extendsRef}`,\n };\n }\n\n const extendsAccount = extendsMatch[1];\n const extendsGateway = extendsMatch[2];\n\n // ADR 0034 pt 4: release-scoped sync — the platform manifest is the chain's\n // release authority. An unresolved manifest means the child was never\n // pinned to a release; pulling main/moving HEAD on top of released bytes\n // would drift the snapshot, so this fails loud instead.\n const platform = await resolvePlatformManifest({ configDir: projectDir, localConfig });\n if (!platform) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n conflicted: [],\n error:\n \"No platform release manifest resolved (\" +\n `platform pin missing in ${join(projectDir, \"bos.app.ts\")} and its extends chain) — ` +\n \"run `bos upgrade` to pin a release, or `bos status` to inspect the chain\",\n };\n }\n const releaseTag = releaseRefCandidates(platform.manifest.frameworkVersion);\n\n const { sourceDir, cleanup, resolvedRef, resolvedSha } = await resolveSourceDir({\n extendsAccount,\n extendsGateway,\n ref: releaseTag,\n });\n const workflowPin = resolveWorkflowReleasePin(releaseTag, resolvedRef, resolvedSha);\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 childScripts = buildChildRootScripts({\n ui: withUi,\n api: withApi,\n host: withHost,\n plugins: withPlugins,\n });\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 for (const destPath of await glob(AGENT_SYNC_GLOBS, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n ignore: [\"**/node_modules/**\", \"**/.git/**\", \"**/dist/**\", \"**/.bos/**\"],\n })) {\n destToSource.set(destPath, destPath);\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 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 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/tsconfig.json\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/tsconfig.json`, sourceFile);\n }\n\n const updated: string[] = [];\n const skipped: string[] = [];\n const added: string[] = [];\n const conflicted: string[] = [];\n\n const snapshot = await readSnapshot(projectDir);\n const snapshotFiles = snapshot?.files ?? {};\n\n for (const [destPath, filePath] of destToSource.entries()) {\n if (!existsSync(join(sourceDir, filePath))) {\n // The template no longer ships this file — it was retired from the\n // scaffold. Leave the local copy untouched rather than crashing the\n // sync (the old-CLI + new-template transitional combo).\n skipped.push(destPath);\n continue;\n }\n const localHash = computeLocalHash(projectDir, destPath);\n const sourceHash = computeHash(\n buildSyncedFileContent(\n sourceDir,\n projectDir,\n filePath,\n undefined,\n childScripts,\n workflowPin,\n ),\n );\n\n if (localHash === null) {\n added.push(destPath);\n continue;\n }\n\n if (localHash === sourceHash) {\n skipped.push(destPath);\n continue;\n }\n\n const snapshotHash = snapshotFiles[destPath];\n if (!snapshotHash) {\n updated.push(destPath);\n continue;\n }\n\n if (localHash === snapshotHash) {\n updated.push(destPath);\n continue;\n }\n\n if (sourceHash === snapshotHash) {\n skipped.push(destPath);\n continue;\n }\n\n conflicted.push(destPath);\n }\n\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 // Conflicts never silently clobber: without --force a conflicted file\n // aborts the whole run before any write — the clean updates and additions\n // wait for a resolution, so a snapshot never half-advances.\n if (conflicted.length > 0 && !options.force && !options.dryRun) {\n return {\n status: \"conflicted\",\n updated: [],\n skipped,\n added: [],\n conflicted,\n error:\n \"Local edits conflict with the upstream template (run `bos upgrade --force` to \" +\n `overwrite — backups land in .bos/sync-backup/): ${conflicted.join(\", \")}`,\n };\n }\n\n if (options.dryRun) {\n const agentsMd = expectedChildAgentsMd(sourceDir, overrides, childPlugins);\n if (agentsMd && computeLocalHash(projectDir, \"AGENTS.md\") !== agentsMd.hash) {\n updated.push(\"AGENTS.md\");\n }\n\n return {\n status: \"dry-run\",\n updated,\n skipped,\n added,\n conflicted,\n };\n }\n\n const filesToWrite = [...updated, ...added, ...conflicted];\n\n let backupDir: string | undefined;\n if (filesToWrite.length > 0) {\n backupDir = backupFiles(projectDir, filesToWrite) ?? undefined;\n\n for (const destPath of filesToWrite) {\n const sourcePath = destToSource.get(destPath) ?? destPath;\n writeSyncedFile(sourceDir, projectDir, sourcePath, destPath, childScripts, workflowPin);\n }\n }\n\n // The authored config is never rewritten by sync: in sync mode\n // personalizeConfig only wrote back the child's own values while\n // re-serializing the whole file (dropping hand formatting, comments, and\n // remote-only attachments). The child's extends/account/domain come from\n // its own config read above, so there is nothing to personalize.\n\n await syncResolvedSharedDeps({\n configDir: projectDir,\n hostMode: \"local\",\n });\n\n const syncedConfig = await openResolution({ cwd: projectDir });\n if (syncedConfig?.runtime) {\n await materializeViaLayer(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 agentsMd = expectedChildAgentsMd(sourceDir, overrides, childPlugins);\n if (agentsMd) {\n if (computeLocalHash(projectDir, \"AGENTS.md\") !== agentsMd.hash) {\n writeFileSync(join(projectDir, \"AGENTS.md\"), agentsMd.content);\n updated.push(\"AGENTS.md\");\n }\n\n newSnapshotFiles[\"AGENTS.md\"] = agentsMd.hash;\n }\n\n await writeSnapshot(projectDir, {\n files: newSnapshotFiles,\n });\n\n if (!options.noInstall) {\n await runPnpmInstall(findWorkspaceRoot(projectDir)?.dir ?? projectDir);\n await runTypesGen(projectDir);\n }\n\n return {\n status: \"synced\",\n updated,\n skipped,\n added,\n conflicted,\n backupDir,\n };\n } finally {\n await cleanup();\n }\n}\n"],"mappings":"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"}